Introduction

Metagenomic analysis was conducted on our oral biofilm model to assess the viability of the model as a proxy for dental calculus.

Materials

A total of 35 biofilm model samples were taken throughout the course of the experiment and includes saliva inoculate, media from the wells, and the biofilm end-product. DNA extraction was performed at the archaeogenetic facility at the Max Planck Institute for the Science of Human History (Jena, Germany).

Extractions were performed in duplicates. A total of DNA extracts.

DNeasy PowerSoil Kit from QIAGEN. C2 inhibitor removal step skipped, going directly to C3 step.

were paired-end sequenced on a NextSeq (2 color chemistry) to 150bp

Comparative samples

Methods

Preprocessing

Processing of the raw DNA reads was conducted using the nf-core/eager, v2.4.4 pipeline [@yatesEAGER2020]. Adapter removal and read merging was performed using AdapterRemoval, v2.3.2 [@AdapterRemovalv2]. Merged reads were mapped to the human reference genome, GRCh38, using BWA, v0.7.17-r1188 [@BWA] with default settings (-n 0.01; -l 32), and unmapped reads were extracted using Samtools, v1.12.

Metagenomic classification was conducted in kraken, v2.1.2 using the Standard database (https://benlangmead.github.io/aws-indexes/k2).

Kraken output reports were combined and converted to OTU tables, and only species-level assignments were selected for downstream analysis 02-scripts/00-comb-kraken-reports.R. The OTU tables were further filtered by removing species with relative abundance lower than 0.001%.

Authentication

SourceTracker [@knightsSourceTracker2011] was used to estimate source composition of the oral biofilm model samples using a Bayesian framework. Samples were compared with oral and environmental controls to detect potential external contamination.

Potential contaminants were identified using the frequency and prevalence method in the decontam v1.16.0 [@R-decontam] R package. 02-scripts/02-authentication.R. Samples from indoor_air, skin, and sediment were used as negative controls for the prevalence method with a probability threshold of 0.01. DNA concentrations were used for the ‘frequency’ method with a probability threshold of 0.99 and negative controls.

Putative contaminants were filtered out of the OTU tables for all downstream analyses.

See 06-reports/metagen-authentication.Rmd for more details.

Community composition

Genus- and species-level OTU tables were prepared from the decontaminated OTU table, and relative abundance of species in a sample was calculated as recommended for compositional data [@gloorMicrobiomeDatasets2017].

Information on the oxygen tolerance of bacterial species was downloaded from BacDive on 2022-05-27, 2022-06-29. A list of amylase-binding streptococci (ABS) was created based on [@nikitkovaStarchBiofilms2013].

Alpha-diversity, specifically the Shannon Index, was calculated to compare species richness and diversity across experimental and comparative oral samples. Shannon Index was calculated using the R package vegan v2.6.2 [@Rvegan].

Sparse principal components analysis (sPCA) was conducted on centered-log-ratio (CLR) transformed species-level counts using the R package mixOmics v6.20.0 [@RmixOmics]. The mixOmics implementation of sPCA uses a LASSO penalisation to eliminate unimportant variables. Two separate analyses were conducted: 1) on experiment samples to assess the difference in sample types and biofilm age; and 2) on oral comparative samples and biofilm model end-products to explore community differences between in vitro and in vivo biofilms.

Loadings obtained from the sPCA analyses were used in combination with CLR-transformed counts to create heatmaps of species- and genus-level counts within the experiment and across comparative samples.

Beta-diversity, Bray Curtis dissimilarity.

Differential abundance analysis

Results

Authentication

SourceTracker

Results from SourceTracker indicated a large portion of species from most samples are from an oral origin (plaque, saliva, or calculus). Some samples contained a large proportion of species from potential contaminants (indoor air) and of unknown origin. Potential contaminants were compared to a database of oral bacteria to see the proportion of known oral species were present in the samples. Many of the species assigned to indoor_air are known oral species (Figure @ref(fig:st-plot)).

Based on these results, samples SYN015.F0101, SYN015.G0101, SYN015.H0101, SYN017.F0101, SYN017.G0101, SYN018.H0101, SYN013.I0101, SYN016.I0101 were removed from further analysis. The removed samples were all sampled late in the experiment (day 18+).

decontam

A total of 5424 potential contaminants were removed. Remaining counts of species in the biofilm samples ranged between 88 and 284 with a mean of 181.59.

Community composition

Alpha-diversity. Days are grouped to increase sample sizes:

  • Inoculation (inoc) = days 0,3,5
  • Treatment (treatm) = days 7,9,12,15
  • End-product (final) = day 24

Alpha-diversity sees a slight decrease over the course of the experiment. The model calculus is less variable than the initial and middle biofilm samples. Compared to other oral samples, there is lower species diversity and richness in the medium and model calculus.

LS0tCnRpdGxlOiAiU3VtbWFyeSBvZiBtZXRhZ2Vub21pYyBhbmFseXNpcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CiN8IGxhYmVsOiBzZXR1cAojfCBpbmNsdWRlOiBmYWxzZQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGN1cGVyZGVjKQpsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeShtaXhPbWljcykKIyBzZXQgZG9jdW1lbnQgY2h1bmsgb3B0aW9ucwprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IEZBTFNFLAogIHdhcm5pbmcgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UKKQojIG1ldGFkYXRhCm1ldGFkYXRhIDwtIHJlYWRfdHN2KGhlcmUoIjAxLWRvY3VtZW50YXRpb24vbWV0YWRhdGEudHN2IikpCmV4cGVyaW1lbnRfbWV0YWRhdGEgPC0gcmVhZF90c3YoaGVyZSgiMDEtZG9jdW1lbnRhdGlvbi9leHBlcmltZW50LW1ldGFkYXRhLnRzdiIpKQphbmFseXNpc19tZXRhZGF0YSA8LSByZWFkX3RzdihoZXJlKCIwMS1kb2N1bWVudGF0aW9uL2FuYWx5c2lzLW1ldGFkYXRhLnRzdiIpKQpzb2Z0d2FyZSA8LSByZWFkX3RzdihoZXJlKCIwMS1kb2N1bWVudGF0aW9uL3NvZnR3YXJlX3ZlcnNpb25zLmNzdiIpLCBjb2xfbmFtZXMgPSBjKCJzb2Z0d2FyZSIsICJ2ZXJzaW9uIikpCmNvbmRhX2VudiA8LSByZWFkX3RzdihoZXJlKCIwMS1kb2N1bWVudGF0aW9uL2NvbmRhX3ZlcnNpb25zLnRzdiIpLCBza2lwID0gMikKbGliX2NvbmMgPC0gcmVhZF90c3YoaGVyZSgiMDEtZG9jdW1lbnRhdGlvbi9TWU5fRE5BX2NvbmNlbnRyYXRpb25zLnRzdiIpKQojIGFuYWx5c2lzIHJlc3VsdHMKc291cmNldHJhY2tlcjIgPC0gcmVhZF90c3YoaGVyZSgiMDQtYW5hbHlzaXMvc291cmNldHJhY2tlci9zb3VyY2V0cmFja2VyMl9vdXRwdXQvbWl4aW5nX3Byb3BvcnRpb25zLnR4dCIpKQphbGxfZGF0YV9sb25nIDwtIHJlYWRfdHN2KGhlcmUoIjA0LWFuYWx5c2lzL3NvdXJjZXRyYWNrZXIvc291cmNlLWNvbWJfbG9uZy50c3YiKSkKbGlzdF9vZl9jb250YW1pbmFudHMgPC0gcmVhZF90c3YoaGVyZSgiMDQtYW5hbHlzaXMvZGVjb250YW0vbGlzdC1vZi1jb250YW1pbmFudHMudHh0IiksIGNvbF9uYW1lcyA9IEYpCm9yYWxfdGF4YSA8LSBjdXBlcmRlY19kYXRhYmFzZV9leCAlPiUKICBmaWx0ZXIoaXNvbGF0aW9uX3NvdXJjZSA9PSAib3JhbCIpCmJhY19wcm9wZXJ0aWVzIDwtIHJlYWRfdHN2KGhlcmUoIjAxLWRvY3VtZW50YXRpb24vc3BlY2llcy1wcm9wZXJ0aWVzLnRzdiIpKQpvdHVfdGFibGUgPC0gcmVhZF90c3YoaGVyZSgiMDUtcmVzdWx0cy9wb3N0LWRlY29udGFtX3RheGF0YWJsZS50c3YiKSkKYWxwaGFfZGl2IDwtIHJlYWRfdHN2KGhlcmUoIjA1LXJlc3VsdHMvYWxwaGEtZGl2ZXJzaXR5LnRzdiIpKQpsb2FkKGhlcmUoIjA1LXJlc3VsdHMvc3BjYV9ieW9jLnJkYSIpKQpsb2FkKGhlcmUoIjA1LXJlc3VsdHMvc3BjYV9zcGVjaWVzLnJkYSIpKQoKIyBjb252ZXJ0IHBvc3QtZGVjb250YW0gT1RVIHRhYmxlIHRvIGxvbmcgZm9ybWF0IGZvciBlYXNpZXIgd3JhbmdsaW5nCnNwZWNpZXNfY291bnRzX2xvbmcgPC0gb3R1X3RhYmxlICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gd2hlcmUoaXMubnVtZXJpYyksIG5hbWVzX3RvID0gInNhbXBsZSIsIHZhbHVlc190byA9ICJjb3VudCIpCgojIEhlbHBlciBvYmplY3RzCmRheV9vcmRlciA8LSBleHBlcmltZW50X21ldGFkYXRhICU+JQogIG11dGF0ZShFbnYgPSBmYWN0b3IoCiAgICBFbnYsIAogICAgbGV2ZWxzID0gYygic2FsaXZhIiwgIm1lZGl1bSIsICJieW9jX2NhbGN1bHVzIikgIyBmb3JjZSBsZXZlbCBvcmRlciBzbyBpdCBkb2Vzbid0IG9yZGVyIGFscGhhYmV0aWNhbGx5CiAgICApIAogICkgJT4lIAogIGdyb3VwX2J5KEVudikgJT4lCiAgYXJyYW5nZShkYXksIC5ieV9ncm91cCA9IFQpICU+JQogIGZpbHRlcihgI1NhbXBsZUlEYCAlaW4lIGNvbG5hbWVzKHNvdXJjZXRyYWNrZXIyKSkgJT4lCiAgbXV0YXRlKHJtID0gaWZfZWxzZShgI1NhbXBsZUlEYCAlaW4lIGFuYWx5c2lzX21ldGFkYXRhJGAjU2FtcGxlSURgLCBGLCBUKSwKICAgICAgICAgY29sID0gY2FzZV93aGVuKHJtID09IFQgfiAicmVkIiwgIyBleGNsdWRlZCBzYW1wbGVzIGNvbG91cmVkIHJlZAogICAgICAgICAgICAgICAgICAgICAgICAgcm0gPT0gRiB+ICJibGFjayIpKQp0cmVhdG1lbnRfY29sb3VycyA8LSB2aXJpZGlzTGl0ZTo6aW5mZXJubyhuID0gbGVuZ3RoKHVuaXF1ZShleHBlcmltZW50X21ldGFkYXRhJHRyZWF0bWVudCkpKSAjIGRlZmluZSBwYWxsZXR0ZSBhbmQgbnVtYmVyIG9mIGNvbG91cnMKZW52X2NvbG91cnMgPC0gdmlyaWRpc0xpdGU6Om1hZ21hKG4gPSBsZW5ndGgodW5pcXVlKGFuYWx5c2lzX21ldGFkYXRhJEVudikpKSAjIGRlZmluZSBwYWxsZXR0ZSBhbmQgbnVtYmVyIG9mIGNvbG91cnMKCmV4cGVyaW1lbnRfY29sb3VycyA8LSBleHBlcmltZW50X21ldGFkYXRhICU+JQogIGFycmFuZ2UoZGVzYyhkYXkpKSAlPiUgCiAgbXV0YXRlKHRyZWF0X2NvbCA9IGNhc2Vfd2hlbigKICAgICAgICAgICB0cmVhdG1lbnQgPT0gInBvdGF0byIgfiB0cmVhdG1lbnRfY29sb3Vyc1sxXSwKICAgICAgICAgICB0cmVhdG1lbnQgPT0gIndoZWF0IiB+IHRyZWF0bWVudF9jb2xvdXJzWzJdLAogICAgICAgICAgIHRyZWF0bWVudCA9PSAibWl4IiB+IHRyZWF0bWVudF9jb2xvdXJzWzNdLAogICAgICAgICAgIHRyZWF0bWVudCA9PSAiY29udHJvbCIgfiB0cmVhdG1lbnRfY29sb3Vyc1s0XSwKICAgICAgICAgICBpcy5uYSh0cmVhdG1lbnQpIH4gImdyZXkiKSwKICAgICAgICAgZW52X2NvbCA9IGNhc2Vfd2hlbigKICAgICAgICAgICBFbnYgPT0gInNhbGl2YSIgfiBlbnZfY29sb3Vyc1s1XSwKICAgICAgICAgICBFbnYgPT0gImJ5b2NfY2FsY3VsdXMiIH4gZW52X2NvbG91cnNbMV0sCiAgICAgICAgICAgRW52ID09ICJtZWRpdW0iIH4gZW52X2NvbG91cnNbOF0KICAgICAgICAgKSkKYW5hbHlzaXNfY29sb3VycyA8LSBhbmFseXNpc19tZXRhZGF0YSAlPiUKICBtdXRhdGUoZW52X2NvbCA9IGNhc2Vfd2hlbigKICAgIEVudiA9PSAic2FsaXZhIiB+IGVudl9jb2xvdXJzWzVdLAogICAgRW52ID09ICJieW9jX2NhbGN1bHVzIiB+IGVudl9jb2xvdXJzWzFdLAogICAgRW52ID09ICJtZWRpdW0iIH4gZW52X2NvbG91cnNbOF0sCiAgICBFbnYgPT0gImJ1Y2NhbF9tdWNvc2EiIH4gZW52X2NvbG91cnNbNl0sCiAgICBFbnYgPT0gInN1YmdpbmdpdmFsX3BsYXF1ZSIgfiBlbnZfY29sb3Vyc1syXSwKICAgIEVudiA9PSAic3VwcmFnaW5naXZhbF9wbGFxdWUiIH4gZW52X2NvbG91cnNbM10sCiAgICBFbnYgPT0gIm1vZGVybl9jYWxjdWx1cyIgfiBlbnZfY29sb3Vyc1s0XSwKICAgIEVudiA9PSAidml0cm9fYmlvZmlsbSIgfiBlbnZfY29sb3Vyc1s3XQogICAgICAgICApKQpgYGAKCgojIyBJbnRyb2R1Y3Rpb24KCk1ldGFnZW5vbWljIGFuYWx5c2lzIHdhcyBjb25kdWN0ZWQgb24gb3VyIG9yYWwgYmlvZmlsbSBtb2RlbCB0byBhc3Nlc3MgdGhlCnZpYWJpbGl0eSBvZiB0aGUgbW9kZWwgYXMgYSBwcm94eSBmb3IgZGVudGFsIGNhbGN1bHVzLgoKIyMgTWF0ZXJpYWxzCgpgYGB7cn0KbWV0YWRhdGEgJT4lCiAgZmlsdGVyKFN0dWR5ID09ICJ0aGlzX3N0dWR5IikKCmJ5b2Nfc2FtcGxlcyA8LSBtZXRhZGF0YSAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QoYCNTYW1wbGVJRGAsICJTWU4iKSkKYGBgCgpBIHRvdGFsIG9mIGByIG5yb3coYnlvY19zYW1wbGVzKWAgYmlvZmlsbSBtb2RlbCBzYW1wbGVzIHdlcmUgdGFrZW4gdGhyb3VnaG91dCB0aGUKY291cnNlIG9mIHRoZQpleHBlcmltZW50IGFuZCBpbmNsdWRlcyBzYWxpdmEgaW5vY3VsYXRlLCBtZWRpYSBmcm9tIHRoZSB3ZWxscywgYW5kIHRoZSBiaW9maWxtCmVuZC1wcm9kdWN0LiBETkEgZXh0cmFjdGlvbiB3YXMgcGVyZm9ybWVkIGF0IHRoZSBhcmNoYWVvZ2VuZXRpYyBmYWNpbGl0eSBhdCB0aGUKTWF4IFBsYW5jayBJbnN0aXR1dGUgZm9yIHRoZSBTY2llbmNlIG9mIEh1bWFuIEhpc3RvcnkgKEplbmEsIEdlcm1hbnkpLiAKCkV4dHJhY3Rpb25zIHdlcmUKcGVyZm9ybWVkIGluIGR1cGxpY2F0ZXM8IS0tID8/IC0tPi4gQSB0b3RhbCBvZiA8IS0tIHNhbXBsZSBzaXplIC0tPiBETkEgZXh0cmFjdHMuCgpETmVhc3kgUG93ZXJTb2lsIEtpdCBmcm9tIFFJQUdFTi4gQzIgaW5oaWJpdG9yIHJlbW92YWwgc3RlcCBza2lwcGVkLCBnb2luZyBkaXJlY3RseQp0byBDMyBzdGVwLgoKd2VyZSBwYWlyZWQtZW5kIHNlcXVlbmNlZCBvbiBhIE5leHRTZXEgKDIgY29sb3IgY2hlbWlzdHJ5KSB0byAxNTBicAoKIyMjIENvbXBhcmF0aXZlIHNhbXBsZXMKCmBgYHtyfQpjb21wX3NhbXBsZXMgPC0gbWV0YWRhdGEgJT4lCiAgZmlsdGVyKFByb2plY3QgIT0gInRoaXNfc3R1ZHkiKQoKY29tcF9zYW1wbGVzCmBgYAoKIyMgTWV0aG9kcwoKIyMjIFByZXByb2Nlc3NpbmcKClByb2Nlc3Npbmcgb2YgdGhlIHJhdyBETkEgcmVhZHMgd2FzIGNvbmR1Y3RlZCB1c2luZyB0aGUKYHIgcGFzdGUoZmlsdGVyKHNvZnR3YXJlLCBzdHJfZGV0ZWN0KHNvZnR3YXJlLCAiZWFnZXIiKSkpYApwaXBlbGluZSBbQHlhdGVzRUFHRVIyMDIwXS4KQWRhcHRlciByZW1vdmFsIGFuZCByZWFkIG1lcmdpbmcgd2FzIHBlcmZvcm1lZCB1c2luZwpgciBwYXN0ZShmaWx0ZXIoc29mdHdhcmUsIHN0cl9kZXRlY3Qoc29mdHdhcmUsIHJlZ2V4KCJhZGFwdGVycmVtb3ZhbCIsIGlnbm9yZV9jYXNlID0gVCkpKSlgCltAQWRhcHRlclJlbW92YWx2Ml0uIE1lcmdlZCByZWFkcyB3ZXJlIG1hcHBlZCB0byB0aGUgaHVtYW4gcmVmZXJlbmNlIGdlbm9tZSwKR1JDaDM4LCB1c2luZwpgciBwYXN0ZShmaWx0ZXIoc29mdHdhcmUsIHN0cl9kZXRlY3Qoc29mdHdhcmUsIHJlZ2V4KCJid2EiLCBpZ25vcmVfY2FzZSA9IFQpKSkpYApbQEJXQV0gd2l0aCBkZWZhdWx0IHNldHRpbmdzICgtbiAwLjAxOyAtbCAzMiksIGFuZCB1bm1hcHBlZCByZWFkcyB3ZXJlIGV4dHJhY3RlZAp1c2luZwpgciBwYXN0ZShmaWx0ZXIoc29mdHdhcmUsIHN0cl9kZXRlY3Qoc29mdHdhcmUsIHJlZ2V4KCJzYW10b29scyIsIGlnbm9yZV9jYXNlID0gVCkpKSlgLgoKTWV0YWdlbm9taWMgY2xhc3NpZmljYXRpb24gd2FzIGNvbmR1Y3RlZCBpbgpgciBwYXN0ZShmaWx0ZXIoc29mdHdhcmUsIHN0cl9kZXRlY3Qoc29mdHdhcmUsIHJlZ2V4KCJrcmFrZW4iLCBpZ25vcmVfY2FzZSA9IFQpKSkpYAp1c2luZyB0aGUgU3RhbmRhcmQgZGF0YWJhc2UgKGh0dHBzOi8vYmVubGFuZ21lYWQuZ2l0aHViLmlvL2F3cy1pbmRleGVzL2syKS4KCktyYWtlbiBvdXRwdXQgcmVwb3J0cyB3ZXJlIGNvbWJpbmVkIGFuZCBjb252ZXJ0ZWQgdG8gT1RVIHRhYmxlcywgYW5kIG9ubHkKc3BlY2llcy1sZXZlbCBhc3NpZ25tZW50cyB3ZXJlIHNlbGVjdGVkIGZvciBkb3duc3RyZWFtIGFuYWx5c2lzClswMi1zY3JpcHRzLzAwLWNvbWIta3Jha2VuLXJlcG9ydHMuUl0oMDItc2NyaXB0cy8wMC1jb21iLWtyYWtlbi1yZXBvcnRzLlIpLgpUaGUgT1RVIHRhYmxlcyB3ZXJlIGZ1cnRoZXIgZmlsdGVyZWQgYnkgcmVtb3Zpbmcgc3BlY2llcyB3aXRoIHJlbGF0aXZlIGFidW5kYW5jZQpsb3dlciB0aGFuIDAuMDAxJS4KCiMjIyBBdXRoZW50aWNhdGlvbgoKYGBge3J9CiN8IGxhYmVsOiBsaWItY29uYy10YWJsZQpsaWJfY29uYyAlPiUKICBrbml0cjo6a2FibGUoKQpgYGAKClNvdXJjZVRyYWNrZXIgW0BrbmlnaHRzU291cmNlVHJhY2tlcjIwMTFdIHdhcyB1c2VkIHRvIGVzdGltYXRlIHNvdXJjZSBjb21wb3NpdGlvbgpvZiB0aGUgb3JhbCBiaW9maWxtIG1vZGVsIHNhbXBsZXMgdXNpbmcgYSBCYXllc2lhbiBmcmFtZXdvcmsuIFNhbXBsZXMgd2VyZSBjb21wYXJlZAp3aXRoIG9yYWwgYW5kIGVudmlyb25tZW50YWwgY29udHJvbHMgdG8gZGV0ZWN0IHBvdGVudGlhbCBleHRlcm5hbCBjb250YW1pbmF0aW9uLgoKUG90ZW50aWFsIGNvbnRhbWluYW50cyB3ZXJlIGlkZW50aWZpZWQgdXNpbmcgdGhlIGZyZXF1ZW5jeSBhbmQgcHJldmFsZW5jZSBtZXRob2QKaW4gdGhlICoqZGVjb250YW0qKiB2YHIgcGFja2FnZVZlcnNpb24oImRlY29udGFtIilgIFtAUi1kZWNvbnRhbV0gUiBwYWNrYWdlLgpbMDItc2NyaXB0cy8wMi1hdXRoZW50aWNhdGlvbi5SXSguLi8wMi1zY3JpcHRzLzAyLWF1dGhlbnRpY2F0aW9uLlIpLiBTYW1wbGVzCmZyb20gKmluZG9vcl9haXIqLCAqc2tpbiosIGFuZCAqc2VkaW1lbnQqIHdlcmUgdXNlZCBhcyBuZWdhdGl2ZSBjb250cm9scyBmb3IKdGhlIHByZXZhbGVuY2UgbWV0aG9kIHdpdGggYSBwcm9iYWJpbGl0eSB0aHJlc2hvbGQgb2YgMC4wMS4gCltETkEgY29uY2VudHJhdGlvbnNdKC4uLzAxLWRvY3VtZW50YXRpb24vU1lOX0ROQV9jb25jZW50cmF0aW9ucy50c3YpIHdlcmUgdXNlZApmb3IgdGhlICdmcmVxdWVuY3knIG1ldGhvZCB3aXRoIGEgcHJvYmFiaWxpdHkgdGhyZXNob2xkIG9mIDAuOTkKYW5kIG5lZ2F0aXZlIGNvbnRyb2xzLiAKClB1dGF0aXZlIGNvbnRhbWluYW50cyB3ZXJlIGZpbHRlcmVkIG91dCBvZiB0aGUKW09UVSB0YWJsZXNdKC4uLzA1LXJlc3VsdHMvcG9zdC1kZWNvbnRhbV90YXhhdGFibGUudHN2KSBmb3IgYWxsIGRvd25zdHJlYW0gYW5hbHlzZXMuCgpTZWUgWzA2LXJlcG9ydHMvbWV0YWdlbi1hdXRoZW50aWNhdGlvbi5SbWRdKC4uLzA2LXJlcG9ydHMvbWV0YWdlbi1hdXRoZW50aWNhdGlvbi5SbWQpCmZvciBtb3JlIGRldGFpbHMuCjwhLS0gY3VwZXJkZWMgW0B5YXRlc09yYWxNaWNyb2Jpb21lMjAyMV0tLT4KCiMjIyBDb21tdW5pdHkgY29tcG9zaXRpb24KCkdlbnVzLSBhbmQgc3BlY2llcy1sZXZlbCBPVFUgdGFibGVzIHdlcmUgcHJlcGFyZWQgZnJvbSB0aGUgZGVjb250YW1pbmF0ZWQgT1RVCnRhYmxlLCBhbmQgcmVsYXRpdmUgYWJ1bmRhbmNlIG9mIHNwZWNpZXMgaW4gYSBzYW1wbGUgd2FzIGNhbGN1bGF0ZWQgYXMgcmVjb21tZW5kZWQKZm9yIGNvbXBvc2l0aW9uYWwgZGF0YSBbQGdsb29yTWljcm9iaW9tZURhdGFzZXRzMjAxN10uCgpJbmZvcm1hdGlvbiBvbiB0aGUgb3h5Z2VuIHRvbGVyYW5jZSBvZiBiYWN0ZXJpYWwgc3BlY2llcyB3YXMgZG93bmxvYWRlZCBmcm9tIApbQmFjRGl2ZV0oaHR0cHM6Ly9iYWNkaXZlLmRzbXouZGUpIG9uCmByIHN0cl9leHRyYWN0KGxpc3QuZmlsZXMoIi4uLzAzLWRhdGEvIiwgcGF0dGVybiA9ICJiYWNkaXZlIiksICJcXGR7NH0tXFxkezJ9LVxcZHsyfSIpYC4KQSBsaXN0IG9mIGFteWxhc2UtYmluZGluZyBzdHJlcHRvY29jY2kgKEFCUykgd2FzIGNyZWF0ZWQgYmFzZWQgb24KW0BuaWtpdGtvdmFTdGFyY2hCaW9maWxtczIwMTNdLgoKQWxwaGEtZGl2ZXJzaXR5LCBzcGVjaWZpY2FsbHkgdGhlIFNoYW5ub24gSW5kZXgsIHdhcyBjYWxjdWxhdGVkIHRvIGNvbXBhcmUgc3BlY2llcwpyaWNobmVzcyBhbmQgZGl2ZXJzaXR5IGFjcm9zcyBleHBlcmltZW50YWwgYW5kIGNvbXBhcmF0aXZlIG9yYWwgc2FtcGxlcy4gU2hhbm5vbgpJbmRleCB3YXMgY2FsY3VsYXRlZCB1c2luZyB0aGUgUiBwYWNrYWdlICoqdmVnYW4qKiB2YHIgcGFja2FnZVZlcnNpb24oInZlZ2FuIilgCltAUnZlZ2FuXS4KClNwYXJzZSBwcmluY2lwYWwgY29tcG9uZW50cyBhbmFseXNpcyAoc1BDQSkgd2FzIGNvbmR1Y3RlZCBvbiBjZW50ZXJlZC1sb2ctcmF0aW8KKENMUikgdHJhbnNmb3JtZWQgc3BlY2llcy1sZXZlbCBjb3VudHMgdXNpbmcgdGhlIFIgcGFja2FnZSAqKm1peE9taWNzKioKdmByIHBhY2thZ2VWZXJzaW9uKCJtaXhPbWljcyIpYCBbQFJtaXhPbWljc10uIFRoZSAqKm1peE9taWNzKiogaW1wbGVtZW50YXRpb24gb2YKc1BDQSB1c2VzIGEgTEFTU08gcGVuYWxpc2F0aW9uIHRvIGVsaW1pbmF0ZSB1bmltcG9ydGFudCB2YXJpYWJsZXMuClR3byBzZXBhcmF0ZSBhbmFseXNlcyB3ZXJlIGNvbmR1Y3RlZDogMSkgb24gZXhwZXJpbWVudCBzYW1wbGVzIHRvIGFzc2VzcyB0aGUKZGlmZmVyZW5jZSBpbiBzYW1wbGUgdHlwZXMgYW5kIGJpb2ZpbG0gYWdlOyBhbmQgMikgb24gb3JhbCBjb21wYXJhdGl2ZSBzYW1wbGVzCmFuZCBiaW9maWxtIG1vZGVsIGVuZC1wcm9kdWN0cyB0byBleHBsb3JlIGNvbW11bml0eSBkaWZmZXJlbmNlcyBiZXR3ZWVuICppbiB2aXRybyoKYW5kICppbiB2aXZvKiBiaW9maWxtcy4KCkxvYWRpbmdzIG9idGFpbmVkIGZyb20gdGhlIHNQQ0EgYW5hbHlzZXMgd2VyZSB1c2VkIGluIGNvbWJpbmF0aW9uIHdpdGgKQ0xSLXRyYW5zZm9ybWVkIGNvdW50cyB0byBjcmVhdGUgaGVhdG1hcHMgb2Ygc3BlY2llcy0gYW5kIGdlbnVzLWxldmVsIGNvdW50cwp3aXRoaW4gdGhlIGV4cGVyaW1lbnQgYW5kIGFjcm9zcyBjb21wYXJhdGl2ZSBzYW1wbGVzLgoKQmV0YS1kaXZlcnNpdHksIEJyYXkgQ3VydGlzIGRpc3NpbWlsYXJpdHkuCgojIyMgRGlmZmVyZW50aWFsIGFidW5kYW5jZSBhbmFseXNpcwoKIyMgUmVzdWx0cwoKYGBge3J9CiN8IGxhYmVsOiByZXN1bHRzLXNldHVwCnNvdXJjZXRyYWNrZXIyX2xvbmcgPC0gc291cmNldHJhY2tlcjIgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSB3aGVyZShpcy5udW1lcmljKSwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJwcm9wb3J0aW9uIiwgCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlNhbXBsZUlEIikgJT4lCiAgcmVuYW1lKHNvdXJjZSA9IC4uLjEpCgpyZW1vdmVkX3NhbXBsZXMgPC0gbWV0YWRhdGEgJT4lCiAgYW50aV9qb2luKGFuYWx5c2lzX21ldGFkYXRhKSAlPiUKICByZW5hbWUoc2FtcGxlcyA9IGAjU2FtcGxlSURgKQpgYGAKCiMjIyBBdXRoZW50aWNhdGlvbgoKIyMjIyBTb3VyY2VUcmFja2VyCgpSZXN1bHRzIGZyb20gU291cmNlVHJhY2tlciBpbmRpY2F0ZWQgYSBsYXJnZSBwb3J0aW9uIG9mIHNwZWNpZXMgZnJvbSBtb3N0IHNhbXBsZXMKYXJlIGZyb20gYW4gb3JhbCBvcmlnaW4gKHBsYXF1ZSwgc2FsaXZhLCBvciBjYWxjdWx1cykuIFNvbWUgc2FtcGxlcyBjb250YWluZWQgYQpsYXJnZSBwcm9wb3J0aW9uIG9mIHNwZWNpZXMgZnJvbSBwb3RlbnRpYWwgY29udGFtaW5hbnRzIChpbmRvb3IgYWlyKSBhbmQgb2YKdW5rbm93biBvcmlnaW4uIFBvdGVudGlhbCBjb250YW1pbmFudHMgd2VyZSBjb21wYXJlZCB0byBhIGRhdGFiYXNlIG9mIG9yYWwKYmFjdGVyaWEgdG8gc2VlIHRoZSBwcm9wb3J0aW9uIG9mIGtub3duIG9yYWwgc3BlY2llcyB3ZXJlIHByZXNlbnQgaW4gdGhlIHNhbXBsZXMuCk1hbnkgb2YgdGhlIHNwZWNpZXMgYXNzaWduZWQgdG8gYGluZG9vcl9haXJgIGFyZSBrbm93biBvcmFsIHNwZWNpZXMKKEZpZ3VyZSBcQHJlZihmaWc6c3QtcGxvdCkpLgoKYGBge3J9CiN8IGxhYmVsOiBzdC1wbG90CiN8IGZpZy1jYXA6ICJQbG90IG9mIGVzdGltYXRlZCBjb250cmlidXRpb25zIG9mIHZhcmlvdXMgc291cmNlcyB0byB0aGUgYXJ0aWZpY2lhbCBjYWxjdWx1cyBhbmQgYXJ0aWZpY2lhbCBzYWxpdmEgc2FtcGxlcy4gU2FtcGxlcyBhcmUgYXJyYW5nZWQgZnJvbSB0b3AgdG8gYm90dG9tIGJ5IGhvdyBsYXRlIGluIHRoZSBleHBlcmltZW50IHRoZXkgd2VyZSBzYW1wbGVkLCB3aXRoIGJvdHRvbSBiZWluZyB0aGUgZWFybGllc3Qgc2FtcGxlcy4gU2FtcGxlIG5hbWVzIGluIHJlZCBpbmRpY2F0ZSBzYW1wbGVzIHRoYXQgd2VyZSByZW1vdmVkIGZyb20gZnVydGhlciBhbmFseXNpcyBkdWUgdG8gY29udGFtaW5hdGlvbi4iCnN0X3Bsb3QgPC0gc291cmNldHJhY2tlcjJfbG9uZyAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gU2FtcGxlSUQsIHg9IHByb3BvcnRpb24sIGZpbGwgPSBzb3VyY2UpKSArCiAgICBnZW9tX2NvbCgpICsKICAgIHRoZW1lX21pbmltYWwoKSArCiAgICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IGRheV9vcmRlciRgI1NhbXBsZUlEYCkgKwogICAgc2NhbGVfZmlsbF92aXJpZGlzX2Qob3B0aW9uID0gIkMiKSArCiAgICB0aGVtZSgKICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDAuNSwgaGp1c3QgPSAwLjUsIGNvbG91ciA9IGRheV9vcmRlciRjb2wpLAogICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIgogICAgICApCgpvcmFsX3Bsb3QgPC0gYWxsX2RhdGFfbG9uZyAlPiUgCiAgZmlsdGVyKGNvdW50ID4gMCkgJT4lIAogIG11dGF0ZShvcmFsX3NvdXJjZSA9IGlmX2Vsc2UodGF4b24gJWluJSBvcmFsX3RheGEkc3BlY2llcywgIm9yYWwiLCAib3RoZXIiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gU2FtcGxlSUQsIHggPSBjb3VudCwgZmlsbCA9IG9yYWxfc291cmNlKSkgKwogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICAgIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gZGF5X29yZGVyJGAjU2FtcGxlSURgKSArICAKICAgIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG9wdGlvbiA9ICJDIikgKwogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIHRoZW1lKAogICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAjYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3VyID0gZGF5X29yZGVyJGNvbCksCiAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiCiAgICAgICkKCnN0X3Bsb3QgKyBvcmFsX3Bsb3QgKyBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJBIikKYGBgCgpCYXNlZCBvbiB0aGVzZSByZXN1bHRzLCBzYW1wbGVzCmByIHBhc3RlKHJlbW92ZWRfc2FtcGxlcyRzYW1wbGVzLCBjb2xsYXBzZSA9ICIsICIpYAp3ZXJlIHJlbW92ZWQgZnJvbSBmdXJ0aGVyIGFuYWx5c2lzLiBUaGUgcmVtb3ZlZCBzYW1wbGVzIHdlcmUgYWxsIHNhbXBsZWQgbGF0ZSBpbgp0aGUgZXhwZXJpbWVudCAoZGF5IDE4KykuCgpgYGB7cn0KcmVtb3ZlZF9zYW1wbGVzICU+JQogIGxlZnRfam9pbihleHBlcmltZW50X21ldGFkYXRhLCBieSA9IGMoInNhbXBsZXMiID0gIiNTYW1wbGVJRCIsICJFbnYiKSkgJT4lCiAgZHBseXI6OnNlbGVjdChzYW1wbGVzLCBFbnYsIGRheSkgJT4lCiAgYXJyYW5nZShkYXkpCmBgYAoKCiMjIyMgZGVjb250YW0KCmBgYHtyfQojfCBsYWJlbDogZGVjb250YW0tYnlvYy1zdW1tCiN8IGluY2x1ZGU6IGZhbHNlCmJ5b2Nfc3VtbSA8LSBzcGVjaWVzX2NvdW50c19sb25nICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KHNhbXBsZSwgIlNZTiIpLAogICAgICAgICBjb3VudCA+IDApICU+JQogIGdyb3VwX2J5KHNhbXBsZSkgJT4lCiAgY291bnQoYCNPVFUgSURgKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBzdW0obikpCmBgYAoKQSB0b3RhbCBvZiBgciBucm93KGxpc3Rfb2ZfY29udGFtaW5hbnRzKWAgcG90ZW50aWFsIGNvbnRhbWluYW50cyB3ZXJlIHJlbW92ZWQuClJlbWFpbmluZyBjb3VudHMgb2Ygc3BlY2llcyBpbiB0aGUgYmlvZmlsbSBzYW1wbGVzIHJhbmdlZCBiZXR3ZWVuCmByIHBhc3RlKHJhbmdlKGJ5b2Nfc3VtbSRjb3VudCksIGNvbGxhcHNlID0gIiBhbmQgIilgCndpdGggYSBtZWFuIG9mCmByIHBhc3RlKHJvdW5kKG1lYW4oYnlvY19zdW1tJGNvdW50KSwgMikpYC4KCmBgYHtyfQojfCBsYWJlbDogZGVjb250YW0tcGxvdAojfCBmaWctY2FwOiAiUmVtYWluaW5nIG51bWJlciBvZiBzcGVjaWVzIHBlciBzYW1wbGUgZm9sbG93aW5nIHJlbW92YWwgb2YgY29udGFtaW5hbnRzLiIKYnlvY19zdW1tICU+JQogIGdncGxvdChhZXMoeCA9IGNvdW50LCB5ID0gc2FtcGxlKSkgKwogICAgZ2VvbV9jb2woKSArCiAgICB0aGVtZV9taW5pbWFsKCkgKwogICAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiMjIyBDb21tdW5pdHkgY29tcG9zaXRpb24KCkFscGhhLWRpdmVyc2l0eS4gRGF5cyBhcmUgZ3JvdXBlZCB0byBpbmNyZWFzZSBzYW1wbGUgc2l6ZXM6CgotIElub2N1bGF0aW9uIChgaW5vY2ApID0gZGF5cyAwLDMsNQotIFRyZWF0bWVudCAoYHRyZWF0bWApID0gZGF5cyA3LDksMTIsMTUKLSBFbmQtcHJvZHVjdCAoYGZpbmFsYCkgPSBkYXkgMjQKCmBgYHtyfQojfCBsYWJlbDogY29tcC1zZXR1cAphbHBoYV9kaXZfbG9uZyA8LSBhbHBoYV9kaXYgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSB3aGVyZShpcy5udW1lcmljKSwgbmFtZXNfdG8gPSAiaW5kZXgiKSAlPiUKICBsZWZ0X2pvaW4obWV0YWRhdGEsIGJ5ID0gYygic2FtcGxlIiA9ICIjU2FtcGxlSUQiKSkgJT4lCiAgbGVmdF9qb2luKGV4cGVyaW1lbnRfbWV0YWRhdGEsIGJ5ID0gYygic2FtcGxlIiA9ICIjU2FtcGxlSUQiLCAiRW52IikpICU+JQogIG11dGF0ZShkYXlfZ3JvdXBlZCA9IGNhc2Vfd2hlbiggIyBncm91cCBkYXlzIHRvIGluY3JlYXNlIHNhbXBsZSBzaXplCiAgICBkYXkgPCA2IH4gImlub2MiLAogICAgZGF5ID4gNiAmIGRheSA8IDI0IH4gInRyZWF0bSIsCiAgICBkYXkgPT0gMjQgfiAiZmluYWwiKSwKICAgIGRheV9ncm91cGVkID0gZmFjdG9yKGRheV9ncm91cGVkLCBsZXZlbHMgPSBjKCJpbm9jIiwgInRyZWF0bSIsICJmaW5hbCIpKQogICAgKQpgYGAKICAKYGBge3J9CiN8IGxhYmVsOiBhbHBoYS1leHBlcmltZW50LXBsb3QKI3wgZmlnLWNhcDogIlBsb3Qgb2YgYWxwaGEtZGl2ZXJzaXR5IGluZGljZXMgYWNyb3NzIGV4cGVyaW1lbnQgc2FtcGxlcyBncm91cGVkIGJ5IHNhbXBsaW5nIHRpbWUuIgoKYWxwaGFfZGl2X2xvbmcgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3Qoc2FtcGxlLCAiU1lOIikpICU+JQogICNtdXRhdGUoZGF5ID0gYXMuZmFjdG9yKGRheSkpICU+JQogIGdncGxvdChhZXMoeCA9IGRheV9ncm91cGVkLCB5ID0gdmFsdWUpKSArCiAgICBnZW9tX3Zpb2xpbihhZXMoY29sID0gZGF5X2dyb3VwZWQpKSArCiAgICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjEyKSArCiAgICBmYWNldF93cmFwKH4gaW5kZXgsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgICB0aGVtZV9idygpICsKICAgIHRoZW1lKAogICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpCiAgICApCmBgYAoKYGBge3J9CiN8IGxhYmVsOiBhbHBoYS1jb21wYXItcGxvdAphbHBoYV9kaXZfbG9uZyAlPiUKICBmaWx0ZXIoRW52ICE9ICJza2luIiwKICAgICAgICAgRW52ICE9ICJzZWRpbWVudCIsCiAgICAgICAgIEVudiAhPSAic3Rvb2wiLAogICAgICAgICBFbnYgIT0gImluZG9vcl9haXIiKSAlPiUKICBtdXRhdGUoRW52ID0gY2FzZV93aGVuKHN0cl9kZXRlY3QoRW52LCAicGxhcXVlIikgfiAicGxhcXVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBFbnYpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBFbnYsIHkgPSB2YWx1ZSkpICsKICAgIGdlb21fdmlvbGluKGFlcyhjb2wgPSBFbnYpKSArCiAgICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjEpICsKICAgIGZhY2V0X3dyYXAofiBpbmRleCwgc2NhbGVzID0gImZyZWVfeSIpICsKICAgIHRoZW1lX2J3KCkgKwogICAgdGhlbWUoCiAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkKICAgICkKYGBgCgpgYGB7cn0KI3wgbGFiZWw6IGFscGhhLWRpdi10YmwKYWxwaGFfZGl2X2xvbmcgJT4lCiAgZmlsdGVyKAogICAgRW52ICE9ICJza2luIiwKICAgIEVudiAhPSAic2VkaW1lbnQiLAogICAgRW52ICE9ICJzdG9vbCIsCiAgICBFbnYgIT0gImluZG9vcl9haXIiKSAlPiUKICBncm91cF9ieShpbmRleCwgRW52KSAlPiUKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4odmFsdWUpLAogICAgICAgICAgICBzZCA9IHNkKHZhbHVlKSkgJT4lCiAga25pdHI6OmthYmxlKCkKYGBgCgoKQWxwaGEtZGl2ZXJzaXR5IHNlZXMgYSBzbGlnaHQgZGVjcmVhc2Ugb3ZlciB0aGUgY291cnNlIG9mIHRoZSBleHBlcmltZW50LiBUaGUKbW9kZWwgY2FsY3VsdXMgaXMgbGVzcyB2YXJpYWJsZSB0aGFuIHRoZSBpbml0aWFsIGFuZCBtaWRkbGUgYmlvZmlsbSBzYW1wbGVzLgpDb21wYXJlZCB0byBvdGhlciBvcmFsIHNhbXBsZXMsIHRoZXJlIGlzIGxvd2VyIHNwZWNpZXMgZGl2ZXJzaXR5IGFuZCByaWNobmVzcwppbiB0aGUgbWVkaXVtIGFuZCBtb2RlbCBjYWxjdWx1cy4KCmBgYHtyfQojfCBsYWJlbDogc3BjYS1zZXR1cAojfCBpbmNsdWRlOiBmYWxzZQojIGV4cGxhaW5lZCB2YXJpYW5jZQpieW9jX2V4cGxhaW5fdmFyIDwtIHNwY2FfYnlvYyRwcm9wX2V4cGxfdmFyJFgKIyBsb2FkaW5ncyBvZiBzYW1wbGVzCmJ5b2NfcHJpbmNvbXAgPC0gc3BjYV9ieW9jJHggJT4lCiAgYXNfdGliYmxlKHJvd25hbWVzID0gInNhbXBsZSIpICU+JQogIGxlZnRfam9pbihleHBlcmltZW50X21ldGFkYXRhLCBieSA9IGMoInNhbXBsZSIgPSAiI1NhbXBsZUlEIikpCiMgbG9hZGluZ3Mgb2Ygc3BlY2llcwpleHBfcGNhX2xvYWRpbmdzIDwtIHNwY2FfYnlvYyRsb2FkaW5ncyRYICU+JQogIGFzX3RpYmJsZShyb3duYW1lcyA9ICJzcGVjaWVzIikgJT4lCiAgbGVmdF9qb2luKGJhY19wcm9wZXJ0aWVzLCBieSA9ICJzcGVjaWVzIikgJT4lIAogIGRwbHlyOjpzZWxlY3Qoc3BlY2llcyxQQzEsUEMyLCBgT3h5Z2VuIHRvbGVyYW5jZWApICU+JQogIGFycmFuZ2UoZGVzYyhhYnMoUEMxKSkpCmV4cF9wY2FfbG9hZGluZ3MKIyBzZXQgY29tbW9uIGdncGxvdCB0aGVtZSBmb3IgbG9hZGluZyBwbG90cwpsb2FkaW5nX3RoZW1lIDwtICB0aGVtZV9taW5pbWFsKCkgKwogICAgdGhlbWUoCiAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGF4aXMudGlja3MueC5ib3R0b20gPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEpLAogICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCgpLAogICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0wLjIpLAogICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZSgpLAogICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIgogICAgICAgICAgKQpgYGAKCgpgYGB7cn0KI3wgbGFiZWw6IHNjcmVlLWJ5b2MKI3wgZmlnLWNhcDogIlNjcmVlIHBsb3Qgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgZnJvbSB0aGUgc1BDQSBvbiBleHBlcmltZW50IHNhbXBsZXMuIgpwbG90KHNwY2FfYnlvYywgdHlwZSA9ICJsIikKYGBgCgpgYGB7cn0KI3wgbGFiZWw6IGJ5b2Mtc3BjYS1wbG90CiN8IGZpZy1jYXA6ICJzUENBIG9uIHNwZWNpZXMtbGV2ZWwgY291bnRzIGZyb20gZXhwZXJpbWVudCBzYW1wbGVzIG9ubHkuIgpieW9jX3NwY2FfcGxvdCA8LSBieW9jX3ByaW5jb21wICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0gUEMxLCB5ID0gUEMyLCAKICAgIGNvbCA9IGFzX2ZhY3RvcihkYXkpLAogICAgc2hhcGUgPSBFbnYKICAgICkKICApICsKICAgIGdlb21fcG9pbnQoc2l6ZSA9IDQsIHN0cm9rZSA9IDEpICsKICAgIGxhYnMoCiAgICAgIHggPSBwYXN0ZSgKICAgICAgICAiUEMxIiwgCiAgICAgICAgc2NhbGVzOjpwZXJjZW50KGJ5b2NfZXhwbGFpbl92YXJbWzFdXSwgYWNjdXJhY3kgPSAwLjEpKSwKICAgICAgeSA9IHBhc3RlKAogICAgICAgICJQQzIiLCAKICAgICAgICBzY2FsZXM6OnBlcmNlbnQoYnlvY19leHBsYWluX3ZhcltbMl1dLCBhY2N1cmFjeSA9IDAuMSkpLAogICAgICBjb2wgPSAiU2FtcGxpbmcgZGF5IiwKICAgICAgc2hhcGUgPSAiU2FtcGxlIHR5cGUiCiAgICAgICkgKwogICAgdGhlbWVfYncoKSArCiAgICBzY2FsZV9zaGFwZV9kaXNjcmV0ZShzb2xpZCA9IEYpICsKICAgIHNjYWxlX2NvbG91cl92aXJpZGlzX2QoKQoKZXhwX3BjYV9sb2FkaW5ncyAlPiUKICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2MoYWJzKFBDMSkpKSkgJT4lCiAgc2xpY2VfaGVhZChuID0gMjApICU+JQogIGdncGxvdChhZXMoeCA9IFBDMSwgeSA9IHNwZWNpZXMsIGZpbGwgPSBgT3h5Z2VuIHRvbGVyYW5jZWApKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjgpICsKICAgIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0wLjIsMC4yKSkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICAgIHZhbHVlcyA9IHZpcmlkaXNMaXRlOjp0dXJibyhuID0gbGVuZ3RoKGxldmVscyhhcy5mYWN0b3IoYmFjX3Byb3BlcnRpZXMkYE94eWdlbiB0b2xlcmFuY2VgKSkpKSkgKwogICAgbGFicyh0aXRsZSA9ICJjb21wb25lbnQgMSIsIHggPSAiIikgKwogICAgbG9hZGluZ190aGVtZQoKZXhwX3BjYV9sb2FkaW5ncyAlPiUKICBhcnJhbmdlKGRlc2MoYWJzKFBDMikpKSAlPiUKICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2MoYWJzKFBDMikpKSkgJT4lCiAgc2xpY2VfaGVhZChuID0gMjApICU+JQogIGdncGxvdChhZXMoeCA9IFBDMiwgeSA9IHNwZWNpZXMsIGZpbGwgPSBgT3h5Z2VuIHRvbGVyYW5jZWApKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjgpICsKICAgIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0wLjE4LDAuMTgpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICAgIHZhbHVlcyA9IHZpcmlkaXNMaXRlOjp0dXJibygKICAgICAgICBuID0gbGVuZ3RoKGxldmVscyhhcy5mYWN0b3IoYmFjX3Byb3BlcnRpZXMkYE94eWdlbiB0b2xlcmFuY2VgKSkpCiAgICAgICAgKQogICAgICApICsKICAgIGxhYnModGl0bGUgPSAiY29tcG9uZW50IDIiLCB4ID0gIiIpICsKICAgIGxvYWRpbmdfdGhlbWUKYGBgCgoKCgoKCgoK