Commit e0880027 authored by Bernd Klaus's avatar Bernd Klaus

fixed wrong code in the table combination section, changed highlighting to tango

parent 517b7002
......@@ -276,9 +276,9 @@ head(q_pcr, 5)
## ----add_rep_info--------------------------------------------------------
q_pcr <- q_pcr %>%
group_by(sample_name) %>%
{.$replicate = c("r_1", "r_2")
.} %>% ungroup
group_by(sample_name, target_Name) %>%
mutate(replicate = c("r_1", "r_2")) %>%
ungroup()
head(q_pcr)
......
......@@ -933,18 +933,15 @@ head(q_pcr, 5)
## Adding columns group--wise
As we have two replicates per sample, it is a natural to
add this annotation information to the table. Note that
we can actually perform complex operations in a single chaining
step by simply wrapping the code in curly brackets. Here, the
dot * . * refers to the current data. In the code below, we
add this annotation information to the table. In the code below, we
add a column *replicate* to each subgroup of the data frame
and the return the augmented data table.
```{r add_rep_info}
q_pcr <- q_pcr %>%
group_by(sample_name) %>%
{.$replicate = c("r_1", "r_2")
.} %>% ungroup
group_by(sample_name, target_Name) %>%
mutate(replicate = c("r_1", "r_2")) %>%
ungroup()
head(q_pcr)
```
......
......@@ -11,6 +11,7 @@
<meta name="author" content="Bernd Klaus" />
<meta name="date" content="2018-04-13" />
<title>Data handling for bioinformatics</title>
......@@ -138,7 +139,7 @@ $(document).ready(function () {
<h1 class="title toc-ignore">Data handling for bioinformatics</h1>
<p class="author-name">Bernd Klaus</p>
<h4 class="date"><em>23 Januar 2018</em></h4>
<h4 class="date"><em>13 April 2018</em></h4>
</div>
......@@ -189,7 +190,7 @@ rmarkdown::render('data_handling_bioinf.Rmd', output_format =
df_print = "paged", toc_depth = 2))
-->
<p><strong>LAST UPDATE AT</strong></p>
<pre><code> [1] &quot;Tue Jan 23 13:34:01 2018&quot;</code></pre>
<pre><code> [1] &quot;Fri Apr 13 15:53:20 2018&quot;</code></pre>
<div id="required-packages-and-other-preparations" class="section level1">
<h1><span class="header-section-number">1</span> Required packages and other preparations</h1>
<pre class="r"><code>library(&quot;readxl&quot;)
......@@ -250,8 +251,7 @@ z</code></pre>
<pre><code> [1] 10</code></pre>
<p>does the same calculation as above, storing the result in an object called <code>z</code>. We can look at the contents of the object by simply typing its name. At any time we can list the objects which we have created:</p>
<pre class="r"><code>ls()</code></pre>
<pre><code> [1] &quot;data_dir&quot; &quot;golden_ratio&quot; &quot;x&quot; &quot;y&quot;
[5] &quot;z&quot;</code></pre>
<pre><code> [1] &quot;data_dir&quot; &quot;golden_ratio&quot; &quot;x&quot; &quot;y&quot; &quot;z&quot;</code></pre>
<p>Notice that <code>ls</code> is actually an object itself. Typing <code>ls</code> ould result in a display of the contents of this object, in this case, the commands of the function. The use of parentheses, <code>ls()</code>, ensures that the function is executed and its result — in this case, a list of the objects in the current environment — displayed. More commonly, a function will operate on an object, for example</p>
<pre class="r"><code>sqrt(16)</code></pre>
<pre><code> [1] 4</code></pre>
......@@ -773,11 +773,11 @@ worst_cells </code></pre>
</div>
<div id="adding-columns-groupwise" class="section level2">
<h2><span class="header-section-number">10.1</span> Adding columns group–wise</h2>
<p>As we have two replicates per sample, it is a natural to add this annotation information to the table. Note that we can actually perform complex operations in a single chaining step by simply wrapping the code in curly brackets. Here, the dot * . * refers to the current data. In the code below, we add a column <em>replicate</em> to each subgroup of the data frame and the return the augmented data table.</p>
<p>As we have two replicates per sample, it is a natural to add this annotation information to the table. In the code below, we add a column <em>replicate</em> to each subgroup of the data frame and the return the augmented data table.</p>
<pre class="r"><code>q_pcr &lt;- q_pcr %&gt;%
group_by(sample_name) %&gt;%
{.$replicate = c(&quot;r_1&quot;, &quot;r_2&quot;)
.} %&gt;% ungroup
group_by(sample_name, target_Name) %&gt;%
mutate(replicate = c(&quot;r_1&quot;, &quot;r_2&quot;)) %&gt;%
ungroup()
head(q_pcr)</code></pre>
<div data-pagedtable="false">
......@@ -842,9 +842,9 @@ head(augmented_table_mutate, 5) </code></pre>
<div id="session-info" class="section level1">
<h1><span class="header-section-number">11</span> Session Info</h1>
<pre class="r"><code>sessionInfo()</code></pre>
<pre><code> R version 3.4.3 (2017-11-30)
<pre><code> R version 3.4.4 (2018-03-15)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.3 LTS
Running under: Ubuntu 16.04.4 LTS
Matrix products: default
BLAS: /usr/lib/libblas/libblas.so.3.6.0
......@@ -859,43 +859,101 @@ head(augmented_table_mutate, 5) </code></pre>
[11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
[1] stats4 parallel stats graphics grDevices utils datasets
[8] methods base
other attached packages:
[1] bindrcpp_0.2 dplyr_0.7.4 tidyr_0.7.2
[4] tibble_1.4.1 tidyverse_1.2.1 ggthemes_3.4.0
[7] limma_3.34.5 openxlsx_4.0.17 car_2.1-6
[10] corrplot_0.84 plotly_4.7.1 forcats_0.2.0
[13] entropy_1.2.1 magrittr_1.5 factoextra_1.0.5
[16] ggplot2_2.2.1 gtools_3.5.0 readr_1.1.1
[19] fdrtool_1.2.15 purrr_0.2.4 pheatmap_1.0.8
[22] stringr_1.2.0 RColorBrewer_1.1-2 matrixStats_0.52.2
[25] BiocStyle_2.6.1 readxl_1.0.0 knitr_1.18
[1] bibtex_0.4.2 knitcitations_1.0.8
[3] hexbin_1.27.2 devtools_1.13.5
[5] Rtsne_0.13 vsn_3.46.0
[7] psych_1.8.3.3 recount_1.4.6
[9] locfit_1.5-9.1 scran_1.6.9
[11] Single.mTEC.Transcriptomes_1.6.0 bindrcpp_0.2.2
[13] randomForest_4.6-14 crossval_1.0.3
[15] sda_1.3.7 clue_0.3-54
[17] clusterExperiment_1.4.0 zinbwave_1.0.0
[19] SingleCellExperiment_1.0.0 sva_3.26.0
[21] BiocParallel_1.12.0 genefilter_1.60.0
[23] mgcv_1.8-23 nlme_3.1-137
[25] corpcor_1.6.9 broom_0.4.4
[27] DESeq2_1.18.1 SummarizedExperiment_1.8.1
[29] DelayedArray_0.4.1 Biobase_2.38.0
[31] GenomicRanges_1.30.3 GenomeInfoDb_1.14.0
[33] IRanges_2.12.0 S4Vectors_0.16.0
[35] BiocGenerics_0.24.0 MASS_7.3-49
[37] dplyr_0.7.4 tidyr_0.8.0
[39] tibble_1.4.2 tidyverse_1.2.1
[41] ggthemes_3.4.2 limma_3.34.9
[43] openxlsx_4.0.17 car_3.0-0
[45] carData_3.0-1 corrplot_0.84
[47] plotly_4.7.1 forcats_0.3.0
[49] entropy_1.2.1 magrittr_1.5
[51] factoextra_1.0.5 ggplot2_2.2.1
[53] gtools_3.5.0 readr_1.1.1
[55] fdrtool_1.2.15 purrr_0.2.4
[57] pheatmap_1.0.8 stringr_1.3.0
[59] RColorBrewer_1.1-2 matrixStats_0.53.1
[61] readxl_1.0.0 knitr_1.20
[63] BiocStyle_2.6.1
loaded via a namespace (and not attached):
[1] nlme_3.1-131 pbkrtest_0.4-7 lubridate_1.7.1
[4] httr_1.3.1 rprojroot_1.3-2 tools_3.4.3
[7] backports_1.1.2 utf8_1.1.3 R6_2.2.2
[10] lazyeval_0.2.1 mgcv_1.8-23 colorspace_1.3-2
[13] nnet_7.3-12 tidyselect_0.2.3 mnormt_1.5-5
[16] curl_3.1 compiler_3.4.3 cli_1.0.0
[19] rvest_0.3.2 quantreg_5.34 SparseM_1.77
[22] xml2_1.1.1 bookdown_0.5 scales_0.5.0
[25] psych_1.7.8 digest_0.6.14 foreign_0.8-69
[28] minqa_1.2.4 rmarkdown_1.8 base64enc_0.1-3
[31] pkgconfig_2.0.1 htmltools_0.3.6 lme4_1.1-15
[34] htmlwidgets_1.0 rlang_0.1.6 rstudioapi_0.7
[37] bindr_0.1 jsonlite_1.5 Matrix_1.2-12
[40] Rcpp_0.12.15 munsell_0.4.3 stringi_1.1.6
[43] yaml_2.1.16 MASS_7.3-48 plyr_1.8.4
[46] grid_3.4.3 parallel_3.4.3 ggrepel_0.7.0
[49] crayon_1.3.4 lattice_0.20-35 haven_1.1.1
[52] splines_3.4.3 hms_0.4.0 pillar_1.1.0
[55] reshape2_1.4.3 codetools_0.2-15 glue_1.2.0
[58] evaluate_0.10.1 data.table_1.10.4-3 modelr_0.1.1
[61] nloptr_1.0.4 MatrixModels_0.4-1 cellranger_1.1.0
[64] gtable_0.2.0 assertthat_0.2.0 broom_0.4.3
[67] viridisLite_0.2.0</code></pre>
[1] Hmisc_4.1-1 class_7.3-14 Rsamtools_1.30.0
[4] foreach_1.4.4 rprojroot_1.3-2 glmnet_2.0-16
[7] crayon_1.3.4 backports_1.1.2 rlang_0.2.0
[10] XVector_0.18.0 phylobase_0.8.4 scater_1.6.3
[13] rjson_0.2.15 bit64_0.9-7 glue_1.2.0
[16] trimcluster_0.1-2 rngtools_1.2.4 vipor_0.4.5
[19] AnnotationDbi_1.40.0 shinydashboard_0.7.0 haven_1.1.1
[22] rio_0.5.10 XML_3.98-1.10 zoo_1.8-1
[25] GenomicAlignments_1.14.2 xtable_1.8-2 evaluate_0.10.1
[28] cli_1.0.0 zlibbioc_1.24.0 rstudioapi_0.7
[31] doRNG_1.6.6 whisker_0.3-2 rpart_4.1-13
[34] derfinderHelper_1.12.0 locfdr_1.1-8 shiny_1.0.5
[37] xfun_0.1 cluster_2.0.7 ggrepel_0.7.0
[40] ape_5.1 stabledist_0.7-1 dendextend_1.7.0
[43] Biostrings_2.46.0 reshape_0.8.7 withr_2.1.2
[46] bitops_1.0-6 plyr_1.8.4 cellranger_1.1.0
[49] pcaPP_1.9-73 pillar_1.2.1 bumphunter_1.20.0
[52] GenomicFeatures_1.30.3 flexmix_2.3-14 kernlab_0.9-25
[55] RMySQL_0.10.14 NMF_0.21.0 tools_3.4.4
[58] foreign_0.8-69 rncl_0.8.2 beeswarm_0.2.3
[61] munsell_0.4.3 compiler_3.4.4 abind_1.4-5
[64] httpuv_1.3.6.2 rtracklayer_1.38.3 pkgmaker_0.22
[67] GenomeInfoDbData_1.0.0 gridExtra_2.3 edgeR_3.20.9
[70] lattice_0.20-35 jsonlite_1.5 affy_1.56.0
[73] scales_0.5.0 lazyeval_0.2.1 taxize_0.9.3
[76] doParallel_1.0.11 latticeExtra_0.6-28 checkmate_1.8.5
[79] rmarkdown_1.9 statmod_1.4.30 downloader_0.4
[82] copula_0.999-18 softImpute_1.4 BSgenome_1.46.0
[85] igraph_1.2.1 survival_2.41-3 numDeriv_2016.8-1
[88] yaml_2.1.18 prabclus_2.2-6 htmltools_0.3.6
[91] memoise_1.1.0 VariantAnnotation_1.24.5 modeltools_0.2-21
[94] viridisLite_0.3.0 digest_0.6.15 assertthat_0.2.0
[97] mime_0.5 registry_0.5 RSQLite_2.1.0
[100] derfinder_1.12.6 data.table_1.10.4-3 blob_1.1.1
[103] RNeXML_2.0.8 preprocessCore_1.40.0 splines_3.4.4
[106] Formula_1.2-2 fpc_2.1-11 bold_0.5.0
[109] RCurl_1.95-4.10 hms_0.4.2 modelr_0.1.1
[112] rhdf5_2.22.0 colorspace_1.3-2 base64enc_0.1-3
[115] mnormt_1.5-5 ggbeeswarm_0.6.0 nnet_7.3-12
[118] tximport_1.6.0 GEOquery_2.46.15 Rcpp_0.12.16
[121] ADGofTest_0.3 mclust_5.4 bookdown_0.7
[124] mvtnorm_1.0-7 pspline_1.0-18 R6_2.2.2
[127] grid_3.4.4 crul_0.5.2 acepack_1.4.1
[130] BiocInstaller_1.28.0 curl_3.2 affyio_1.48.0
[133] robustbase_0.92-8 Matrix_1.2-13 howmany_0.3-1
[136] qvalue_2.10.0 iterators_1.0.9 RefManageR_0.14.20
[139] htmlwidgets_1.0 biomaRt_2.34.2 rvest_0.3.2
[142] htmlTable_1.11.2 codetools_0.2-15 lubridate_1.7.3
[145] FNN_1.1 prettyunits_1.0.2 gridBase_0.4-7
[148] RSpectra_0.12-0 gtable_0.2.0 DBI_0.8
[151] dynamicTreeCut_1.63-1 httr_1.3.1 stringi_1.1.7
[154] progress_1.1.2 reshape2_1.4.3 uuid_0.1-2
[157] diptest_0.75-7 annotate_1.56.2 viridis_0.5.1
[160] rentrez_1.2.1 DT_0.4 xml2_1.2.0
[163] ade4_1.7-11 geneplotter_1.56.0 DEoptimR_1.0-8
[166] bit_1.1-12 pkgconfig_2.0.1 gsl_1.9-10.3
[169] bindr_0.1.1 GenomicFiles_1.14.0</code></pre>
</div>
<div id="references" class="section level1 unnumbered">
<h1>References</h1>
......@@ -909,7 +967,7 @@ head(augmented_table_mutate, 5) </code></pre>
</div>
</div>
<div id="rmd-source-code">LS0tCnRpdGxlOiAiRGF0YSBoYW5kbGluZyBmb3IgYmlvaW5mb3JtYXRpY3MiCmF1dGhvcjogIkJlcm5kIEtsYXVzIgpkYXRlOiAiYHIgZG9jX2RhdGUoKWAiCm91dHB1dDogCiAgICBCaW9jU3R5bGU6Omh0bWxfZG9jdW1lbnQ6CiAgICAgICAgdG9jOiB0cnVlCiAgICAgICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgICAgICB0b2NfZmxvYXQ6IGZhbHNlCiAgICAgICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgICAgIGRmX3ByaW50OiBwYWdlZAogICAgICAgIHRvY19kZXB0aDogMgogICAgQmlvY1N0eWxlOjpwZGZfZG9jdW1lbnQ6CiAgICAgICAgdG9jOiB0cnVlCiAgICAgICAgdG9jX2RlcHRoOiAyCmJpYmxpb2dyYXBoeTogc3RhdF9tZXRob2RzX2Jpb2luZi5iaWIKLS0tCgo8IS0tCmdyYXBoaWNzLm9mZigpO3JtKGxpc3Q9bHMoKSk7cm1hcmtkb3duOjpyZW5kZXIoJ2RhdGFfaGFuZGxpbmdfYmlvaW5mLlJtZCcsIApvdXRwdXRfZm9ybWF0ID0gIkJpb2NTdHlsZTo6aHRtbF9kb2N1bWVudCIpO3B1cmwoJ2RhdGFfaGFuZGxpbmdfYmlvaW5mLlJtZCcpCgpybWFya2Rvd246OnJlbmRlcignZGF0YV9oYW5kbGluZ19iaW9pbmYuUm1kJywgb3V0cHV0X2Zvcm1hdCA9IAogICAgICAgICAgQmlvY1N0eWxlOjpwZGZfZG9jdW1lbnQodG9jID0gVFJVRSwgaGlnaGxpZ2h0ID0gInRhbmdvIiwgCiAgICAgICAgICBkZl9wcmludCA9ICJwYWdlZCIsIHRvY19kZXB0aCA9IDIpKQotLT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCm9wdGlvbnMoZGlnaXRzPTMsIHdpZHRoPTgwKQpnb2xkZW5fcmF0aW8gPC0gKDEgKyBzcXJ0KDUpKSAvIDIKb3B0c19jaHVuayRzZXQoZWNobz1UUlVFLHRpZHk9RkFMU0UsaW5jbHVkZT1UUlVFLAogICAgICAgICAgICAgICBkZXY9YygncG5nJywgJ3BkZicsICdzdmcnKSwgZmlnLmhlaWdodCA9IDUsIGZpZy53aWR0aCA9IDQgKiBnb2xkZW5fcmF0aW8sIGNvbW1lbnQgPSAnICAnLCBkcGkgPSAzMDAsCmNhY2hlID0gVFJVRSkKYGBgCgogKipMQVNUIFVQREFURSBBVCoqCgpgYGB7ciwgZWNobz1GQUxTRSwgY2FjaGU9RkFMU0V9CnByaW50KGRhdGUoKSkKYGBgCgoKCiMgUmVxdWlyZWQgcGFja2FnZXMgYW5kIG90aGVyIHByZXBhcmF0aW9ucwoKCmBgYHtyIHJlcXVpcmVkX3BhY2thZ2VzX2FuZF9kYXRhLCBlY2hvID0gVFJVRSwgY2FjaGU9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoInJlYWR4bCIpCmxpYnJhcnkoIkJpb2NTdHlsZSIpCmxpYnJhcnkoImtuaXRyIikKbGlicmFyeSgibWF0cml4U3RhdHMiKQpsaWJyYXJ5KCJSQ29sb3JCcmV3ZXIiKQpsaWJyYXJ5KCJzdHJpbmdyIikKbGlicmFyeSgicGhlYXRtYXAiKQpsaWJyYXJ5KCJwdXJyciIpCmxpYnJhcnkoImZkcnRvb2wiKQpsaWJyYXJ5KCJyZWFkciIpCmxpYnJhcnkoImd0b29scyIpCmxpYnJhcnkoImZhY3RvZXh0cmEiKQpsaWJyYXJ5KCJtYWdyaXR0ciIpCmxpYnJhcnkoImVudHJvcHkiKQpsaWJyYXJ5KCJmb3JjYXRzIikKbGlicmFyeSgicGxvdGx5IikKbGlicmFyeSgiY29ycnBsb3QiKQpsaWJyYXJ5KCJjYXIiKQpsaWJyYXJ5KCJmb3JjYXRzIikKbGlicmFyeSgib3Blbnhsc3giKQpsaWJyYXJ5KCJyZWFkeGwiKQpsaWJyYXJ5KCJsaW1tYSIpCmxpYnJhcnkoImdndGhlbWVzIikKbGlicmFyeSgidGlkeXZlcnNlIikKCnRoZW1lX3NldCh0aGVtZV9zb2xhcml6ZWQoYmFzZV9zaXplID0gMTgpKQoKCmRhdGFfZGlyIDwtIGZpbGUucGF0aCgiZGF0YS8iKQoKYGBgCgoKIyBJbnRyb2R1Y3Rpb24gdG8gKHNpbmdsZSBjZWxsKSBSTkEtLVNlcSBkYXRhICAKClRoZSBhZHZlbnQgb2YgbmV4dC1nZW5lcmF0aW9uIHNlcXVlbmNpbmcgb3ZlciBhIGRlY2FkZSBhZ28Kc3B1cnJlZCB0aGUgZGV2ZWxvcG1lbnQgb2YgYSBob3N0IG9mIHNlcXVlbmNpbmctYmFzZWQgdGVjaG5vbG9naWVzLiBPbmUKbWFqb3IgaW5ub3ZhdGlvbiwgUk5BLS1zZXF1ZW5jaW5nIChSTkEtLXNlcSkgZW5hYmxlZCB0cmFuc2NyaXB0b21pYyBwcm9maWxpbmcgYXQKdW5wcmVjZWRlbnRlZCBzZW5zaXRpdml0eSBhbmQgYnJlYWR0aCwgbGVhZGluZyB0byB0aGUgZGlzY292ZXJ5IG9mCm5ldyBSTkEgc3BlY2llcyBhbmQgZGVlcGVuaW5nIG91ciB1bmRlcnN0YW5kaW5nIG9mIHRyYW5zY3JpcHRvbWUKZHluYW1pY3MuIEluIHJlY2VudCB5ZWFycywgbG93LWlucHV0IFJOQS1zZXEgbWV0aG9kcyBoYXZlIGJlZW4KYWRhcHRlZCB0byB3b3JrIGluIHNpbmdsZSBjZWxscy4gVGhlc2Ugc2luZ2xlLWNlbGwgUk5BLXNlcSAoc2NSTkEtCnNlcSkgdGVjaG5vbG9naWVzIGNhbiBxdWFudGlmeSBpbnRyYS1wb3B1bGF0aW9uIGhldGVyb2dlbmVpdHkgYW5kCmVuYWJsZSBzdHVkeSBvZiBjZWxsIHN0YXRlcyBhbmQgdHJhbnNpdGlvbnMgYXQgdmVyeSBoaWdoIHJlc29sdXRpb24sCnBvdGVudGlhbGx5IHJldmVhbGluZyBjZWxsIHN1YnR5cGVzIG9yIGdlbmUgZXhwcmVzc2lvbiBkeW5hbWljcyB0aGF0CmFyZSBtYXNrZWQgaW4gYnVsaywgcG9wdWxhdGlvbi1hdmVyYWdlZCBtZWFzdXJlbWVudHMuCgoKSW4gUk5BLS1TZXEsIFJOQSBpcyBjYXB0dXJlZCBmb3IgcmV2ZXJzZSB0cmFuc2NyaXB0aW9uIGludG8gY0ROQS4gVGhpcwpjRE5BIGlzIHByZS1hbXBsaWZpZWQgYW5kIHRoZW4gdXNlZCB0byBwcmVwYXJlIGxpYnJhcmllcyBmb3IKc2VxdWVuY2luZyBhbmQgZG93bnN0cmVhbSBhbmFseXNpcy4gSW4gc2luZ2xlIGNlbGwgUk5BLS1TZXEgKHNjUk5BLS1TZXEpLCB0aGUgY2VsbHMKaGF2ZSB0byBiZSBseXNlZCBmaXJzdC4gVGhlIGNhcHR1cmUgZWZmZWNpZW5jeSBvZiBzY1JOQS0tU2VxIGlzIHF1aXRlCm9ubHkgYXJvdW5kIDEwJSwgc28gdGhlIGRhdGEgb2J0YWluZWQgaXMgb2Z0ZW4gcXVpdGUgc3BhcnNlOiBNYW55IGdlbmVzCmFyZSBzaW1wbHkgbm90IGNhcHR1cmVkLgoKIyBUaGUgQnJlbm5lY2tlIGV0LiBhbC4gbVRFQyBkYXRhCgoKVGhlIGFiaWxpdHkgb2YgdGhlIGltbXVuZSBzeXN0ZW0gdG8gZGlzdGluZ3Vpc2ggc2VsZiBmcm9tIGZvcmVpZ24gCigic2VsZi0tYW50aWdlbi0tdG9sZXJhbmNlIikgaXMgbGFyZ2VseSBlc3RhYmxpc2hlZCBpbiB0aGUgdGh5bXVzLAphIHByaW1hcnkgbHltcGhvaWQgb3JnYW4gd2hlcmUgVCBjZWxscyBkZXZlbG9wLiAKCkludHJpZ3VpbmdseSwgVC0tY2VsbHMgZW5jb3VudGVyIG1vc3QgdGlzc3VlLS1zcGVjaWZpYyAKY29uc3RpdHVlbnRzIGFscmVhZHkgdGhlcmUsIHRodXMgaW1wb3NpbmcgCmEgYnJvYWQgc2NvcGUgb2YgdG9sZXJhbmNlIGJlZm9yZSBUIGNlbGxzIGNpcmN1bGF0ZSB0aHJvdWdoIHRoZSBib2R5LiAKClRoaXMgInRyYWluaW5nIiBvZiB0aGUgVC0tY2VsbHMgaXMgbmVjY2Vzc2FyeSB0byBwcmV2ZW50IGF1dG9pbXVuaXR5LiBJdApoYXBwZW5zIGJ5IHRoZSAicHJvbWlzY3VvdXMiIGV4cHJlc3Npb24gb2YgbnVtZXJvdXMgdGlzc3VlLXNwZWNpZmljIGFudGlnZW5zIAooVFJBcykgaW4gbWVkdWxsYXJ5IHRoeW1pYyAgZXBpdGhlbGlhbCBjZWxscyAobVRFQ3MsIEBLeWV3c2tpXzIwMDYpLgoKSG93ZXZlciwgaXQgaXMgcG9vcmx5IHVuZGVyc3Rvb2QgaG93IHRoaXMgcHJvY2VzcyBpcyByZWd1bGF0ZWQgaW4Kc2luZ2xlIG1URUNzIGFuZCBpcyBjb29yZGluYXRlZCBhdCB0aGUgcG9wdWxhdGlvbiBsZXZlbC4gQEJyZW5uZWNrZV8yMDE1Cm9idGFpbmVkIHNjUk5BLS1TZXEgZGF0YSBvZiBtVEVDcyBhbmQgZmluZCBldmlkZW5jZSBvZiBudW1lcm91cyByZWN1cnJpbmcgClRSQS0tY28tLWV4cHJlc3Npb24gcGF0dGVybnMsIGVhY2ggcHJlc2VudCBpbiBvbmx5IGEgc3Vic2V0IG9mIG1URUNzLgpUaHVzLCB0aGV5IGNvdWxkIHNob3cgdGhhdCB0aGUgZ2VuZSBleHByZXNzaW9uIGluIG1URUMgY2VsbHMgcmF0aGVyICJtb3NhaWMiIAphbmQgY29vcmRpYW50ZWQgcmF0aGVyIHRoYW4gZW50aXJlbHkgc3RvY2hhc3RpYy4gCgpCZWZvcmUgd2UgIGRpdmUgbW9yZSBkZWVwbHkgaW50byB0aGUgZGF0YSwgd2UgcmV2aWV3IGltcG9ydGFudCBSIGJhc2ljcy4KCgojIEJhc2ljcyBvZiBhcml0aG1ldGljcyBhbmQgZGF0YSBoYW5kbGluZyBpbiBSCgoKIyMgRWxlbWVudGFyeSBkYXRhIHR5cGVzIGFuZCBhcml0aG1ldGljcwoKVGhlIGVsZW1lbnRhcnkgdW5pdCBpbiBSIGlzIGFuIG9iamVjdCBhbmQgdGhlIHNpbXBsZXN0IG9iamVjdHMgYXJlIHNjYWxhcnMsIAp2ZWN0b3JzIGFuZCBtYXRyaWNlcy4gUiBpcyBkZXNpZ25lZCB3aXRoIGludGVyYWN0aXZpdHkgaW4gbWluZCwgc28geW91IGNhbiBnZXQKc3RhcnRlZCBieSBzaW1wbHkgdHlwaW5nOgoKCmBgYHtyIHNpbXBsZV9leCwgZWNobyA9IFRSVUV9CjQgKyA2CmBgYAoKV2hhdCBkb2VzIFIgZG8/IEl0IHN1bXMgdXAgdGhlIHR3byBudW1iZXJzIGFuZCByZXR1cm5zIHRoZSBzY2FsYXIgdmFsdWUgMTAuIApJbiAgZmFjdCwgUiByZXR1cm5zIGEgdmVjdG9yIG9mIGxlbmd0aCAxIC0gaGVuY2UgdGhlIFsxXSBkZW5vdGluZyBmaXJzdCBlbGVtZW50IApvZiB0aGUgdmVjdG9yLgpXZSBjYW4gYXNzaWduIG9iamVjdHMgdmFsdWVzIGZvciBzdWJzZXF1ZW50IHVzZS4gRm9yIGV4YW1wbGU6CgoKYGBge3Igc2ltcGxlX2V4XzIsIGVjaG8gPSBUUlVFfQp4IDwtIDYKeSA8LSA0CnogPC0geCArIHkKegpgYGAKCmRvZXMgdGhlIHNhbWUgY2FsY3VsYXRpb24gYXMgYWJvdmUsIHN0b3JpbmcgdGhlIHJlc3VsdCBpbiBhbiBvYmplY3QgY2FsbGVkIGB6YC4gCldlIGNhbiBsb29rIGF0IHRoZSBjb250ZW50cyBvZiB0aGUgb2JqZWN0IGJ5IHNpbXBseSB0eXBpbmcgaXRzIG5hbWUuIEF0IGFueSAKdGltZSB3ZSBjYW4gCmxpc3QgdGhlIG9iamVjdHMgd2hpY2ggd2UgaGF2ZSBjcmVhdGVkOgoKYGBge3Igc2ltcGxlX2V4XzMsIGVjaG8gPSBUUlVFfQpscygpCmBgYAoKTm90aWNlIHRoYXQgYGxzYCBpcyBhY3R1YWxseSBhbiBvYmplY3QgaXRzZWxmLiBUeXBpbmcgYGxzYCAKb3VsZCByZXN1bHQgaW4gYSBkaXNwbGF5IG9mIHRoZSBjb250ZW50cyBvZgp0aGlzIG9iamVjdCwgaW4gdGhpcyBjYXNlLCB0aGUgY29tbWFuZHMgb2YgdGhlIGZ1bmN0aW9uLiBUaGUgdXNlIG9mIHBhcmVudGhlc2VzLCAKYGxzKClgLCBlbnN1cmVzIHRoYXQKdGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGFuZCBpdHMgcmVzdWx0IC0tLSBpbiB0aGlzIGNhc2UsIGEgbGlzdCBvZiB0aGUgb2JqZWN0cyAKaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgLS0tIGRpc3BsYXllZC4KTW9yZSBjb21tb25seSwgYSBmdW5jdGlvbiB3aWxsIG9wZXJhdGUgb24gYW4gb2JqZWN0LCBmb3IgZXhhbXBsZQoKYGBge3Igc2ltcGxlX2V4XzQsIGVjaG8gPSBUUlVFfQpzcXJ0KDE2KQpgYGAKCmNhbGN1bGF0ZXMgdGhlIHNxdWFyZSByb290IG9mIDE2LiBPYmplY3RzIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlIGN1cnJlbnQKd29ya3NwYWNlIHdpdGggdGhlIApmdW5jdGlvbiBgcm0oKWAuIFRoZXJlIGFyZSBtYW55IHN0YW5kYXJkIGZ1bmN0aW9ucyBhdmFpbGFibGUgaW4gUiwgCmFuZCBpdCBpcyBhbHNvIHBvc3NpYmxlIHRvIGNyZWF0ZSBuZXcgb25lcy4gVmVjdG9ycyBjYW4gYmUgY3JlYXRlZCBpbiBSIGluCmEgbnVtYmVyIG9mIHdheXMuCkZvciBleGFtcGxlLCB3ZSBjYW4gbGlzdCBhbGwgb2YgdGhlIGVsZW1lbnRzOgoKYGBge3Igc2ltcGxlX2V4XzUsIGVjaG8gPSBUUlVFfQp6IDwtIGMoNSwgOSwgMSwgMCkKYGBgCgoKTm90ZSB0aGUgdXNlIG9mIHRoZSBmdW5jdGlvbiBgY2AgdG8gY29uY2F0ZW5hdGUgb3IgImdsdWUgdG9nZXRoZXIiIGluZGl2aWR1YWwKZWxlbWVudHMuIFRoaXMgZnVuY3Rpb24KY2FuIGJlIHVzZWQgbXVjaCBtb3JlIHdpZGVseSwgZm9yIGV4YW1wbGUKCmBgYHtyIHNpbXBsZV9leF81YiwgZWNobyA9IFRSVUV9CnggPC0gYyg1LCA5KQp5IDwtIGMoMSwgMCkKeiA8LSBjKHgsIHkpCmBgYAoKCndvdWxkIGxlYWQgdG8gdGhlIHNhbWUgcmVzdWx0IGJ5IGdsdWluZyB0b2dldGhlciB0d28gdmVjdG9ycyB0byBjcmVhdGUgCmEgc2luZ2xlIHZlY3Rvci4KU2VxdWVuY2VzIGNhbiBiZSBnZW5lcmF0ZWQgYXMgZm9sbG93czoKCgpgYGB7ciBzaW1wbGVfZXhfNiwgZWNobyA9IFRSVUV9CnNlcSgxLCA5LCBieSA9IDIpCnNlcSg4LCAyMCwgbGVuZ3RoID0gNikKYGBgCgpUaGVzZSBleGFtcGxlcyBpbGx1c3RyYXRlIHRoYXQgbWFueSBmdW5jdGlvbnMgaW4gUiBoYXZlIG9wdGlvbmFsIGFyZ3VtZW50cywKaW4gdGhpcyBjYXNlLCBlaXRoZXIgdGhlIHN0ZXAgbGVuZ3RoIG9yIHRoZSB0b3RhbCBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIAooaXQgZG9lc24ndCBtYWtlIHNlbnNlICB0byB1c2UgYm90aCkuIElmIHlvdSBsZWF2ZQpvdXQgYm90aCBvZiB0aGVzZSBvcHRpb25zLCBSIHdpbGwgbWFrZSBpdHMgb3duIGRlZmF1bHQgY2hvaWNlLCBpbiB0aGlzIGNhc2UKYXNzdW1pbmcgYSBzdGVwIGxlbmd0aApvZiAxLiBTbywgZm9yIGV4YW1wbGUsCgoKYGBge3Igc2ltcGxlX2V4XzcsIGVjaG8gPSBUUlVFfQp4IDwtIHNlcSgxLCAxMCkKYGBgCgphbHNvIGdlbmVyYXRlcyBhIHZlY3RvciBvZiBpbnRlZ2VycyBmcm9tIDEgdG8gMTAuCkF0IHRoaXMgcG9pbnQgaXQncyB3b3J0aCBtZW50aW9uaW5nIHRoZSBoZWxwIGZhY2lsaXR5IGFnYWluLiAKSWYgeW91IGRvbid0IGtub3cgaG93IHRvIHVzZSBhIGZ1bmN0aW9uLApvciBkb24ndCBrbm93IHdoYXQgdGhlIG9wdGlvbnMgb3IgZGVmYXVsdCB2YWx1ZXMgYXJlLCAKdHlwZSBgaGVscChmdW5jdGlvbm5hbWUpYCAKb3IgIHNpbXBseSBgP2Z1bmN0aW9ubmFtZWAgd2hlcmUgCmBmdW5jdGlvbm5hbWVgIGlzIHRoZSBuYW1lIG9mIHRoZSBmdW5jdGlvbiB5b3UgYXJlIGludGVyZXN0ZWQgaW4uIApUaGlzIHdpbGwgdXN1YWxseSBoZWxwIGFuZCB3aWxsIG9mdGVuIGluY2x1ZGUKZXhhbXBsZXMgdG8gbWFrZSB0aGluZ3MgZXZlbiBjbGVhcmVyLgpBbm90aGVyIHVzZWZ1bCBmdW5jdGlvbiBmb3IgYnVpbGRpbmcgdmVjdG9ycyBpcyB0aGUgYHJlcGAgY29tbWFuZCBmb3IgCnJlcGVhdGluZyB0aGluZ3M6CnRoZSBmaXJzdCBjb21tYW5kIHdpbGwgcmVwZWF0IHRoZSB2ZWN0b3IgYHIgMTozYCBzaXggdGltZXMsIHdpbGwgdGhlIHNlY29uZApvbmUgd2lsbCByZXBlYXQgZWFjaCBlbGVtZW50IHNpeCB0aW1lcy4KCmBgYHtyIHNpbXBsZV9leF84LCBlY2hvID0gVFJVRX0KcmVwKDE6MywgNikKcmVwKDE6MywgdGltZXMgPSBjKDYsIDYsIDYpKQpgYGAKClIgd2lsbCBvZnRlbiBhZGFwdCB0byB0aGUgb2JqZWN0cyBpdCBpcyBhc2tlZCB0byB3b3JrIG9uLiBBbiBleGFtcGxlIGlzIHRoZSAKdmVjdG9yaXplZCBhcml0aG1ldGljIHVzZWQgaW4gUjoKCmBgYHtyIHZlY30KeCA8LSAxOjUKeSA8LSA1OjEKeCArIHkKeF4yCnggKiB5CmBgYAoKc2hvd2luZyB0aGF0IFIgdXNlcyBjb21wb25lbnQtd2lzZSBhcml0aG1ldGljIG9uIHZlY3RvcnMuIFIgd2lsbCBhbHNvIHRyeSB0byAKbWFrZSBzZW5zZSBvZiBhIHN0YXRlbWVudCBpZiBvYmplY3RzCmFyZSBtaXhlZC4gRm9yIGV4YW1wbGU6CgpgYGB7ciB2ZWMtMn0KeCA8LSBjKDYsIDggLCA5ICkKeCArIDIKYGBgICAKClR3byBwYXJ0aWN1bGFybHkgdXNlZnVsIGZ1bmN0aW9ucyB3b3J0aCByZW1lbWJlcmluZyBhcmUgYGxlbmd0aGAsIAp3aGljaCByZXR1cm5zIHRoZSBsZW5ndGggb2YgYSB2ZWN0b3IgKGkuZS4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpdCBjb250YWlucykgCmFuZCBgc3VtYCB3aGljaCBjYWxjdWxhdGVzIHRoZSBzdW0gb2YgdGhlIGVsZW1lbnRzCm9mIGEgdmVjdG9yLiBSIGFsc28gaGFzIGJhc2ljIGNhbGN1bGF0b3IgY2FwYWJpbGl0aWVzOgoKCiogYGErYmAsIGBhLWJgLCBgYVwqYmAsICBgYVwqXCpiYCAoYSB0byB0aGUgcG93ZXIgb2YgYikgCiogYWRkaXRpb25hbGx5OiBgc3FydChhKWAsIGBzaW4oYSlgIC4uLgoKYW5kIHNvbWUgc2ltcGxlIHN0YXRpc3RpY3M6IAoKKiAgYCBtZWFuKGEpYAoqICBgIHN1bW1hcnkoYSlgCiogIGAgdmFyKGEpYAoqICBgIG1pbihhLGIpYCwgYG1heChhLGIpYAoKCiMjIFN1YnNjcmlwdGluZyBhbmQgdXNlZnVsIHZlY3RvciBmdW5jdGlvbnMKCkxldCdzIHN1cHBvc2Ugd2UndmUgY29sbGVjdGVkIHNvbWUgZGF0YSBmcm9tIGFuIGV4cGVyaW1lbnQgYW5kIHN0b3JlZCB0aGVtIAppbiBhbiBvYmplY3QgYHhgLgpTb21lIHNpbXBsZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlc2UgZGF0YSBjYW4gYmUgcHJvZHVjZWQ6CgpgYGB7ciBzdW1tYXJ5XzEsICAgZWNobyA9IFRSVUV9CnggPC0gYyg3LjUsIDguMiwgMy4xLCA1LjYsIDguMiwgOS4zLCA2LjUsIDcuMCwgOS4zLCAxLjIsIDE0LjUsIDYuMikKbWVhbih4KQp2YXIoeCkKc3VtbWFyeSh4KQpgYGAKSXQgbWF5IGJlLCBob3dldmVyLCB0aGF0IHdlIHN1YnNlcXVlbnRseSBsZWFybiB0aGF0IHRoZSBmaXJzdAo2IGRhdGEgcG9pbnRzIGNvcnJlc3BvbmQgdG8gbWVhc3VyZW1lbnRzIG1hZGUgaW4gb25lIGV4cGVyaW1lbnQsIAphbmQgdGhlIHNlY29uZCBzaXggb24gYW5vdGhlciBleHBlcmltZW50LgpUaGlzIG1pZ2h0IHN1Z2dlc3Qgc3VtbWFyaXppbmcgdGhlIHR3byBzZXRzIG9mIGRhdGEgc2VwYXJhdGVseSwgCnNvIHdlIHdvdWxkIG5lZWQgdG8gZXh0cmFjdCBmcm9tCmB4YCB0aGUgdHdvIHJlbGV2YW50IHN1YnZlY3RvcnMuIFRoaXMgaXMgYWNoaWV2ZWQgYnkgc3Vic2NyaXB0aW5nOgoKYGBge3Igc3Vic2NyLCAgIGVjaG8gPSBUUlVFfQp4WzE6Nl0KeFs3OjEyXQpzdW1tYXJ5KHhbMTo2XSkKc3VtbWFyeSh4Wzc6MTJdKQpgYGAKCllvdSBzaW1wbHkgcHV0IHRoZSBpbmRleGVzIG9mIHRoZSBlbGVtZW50IHlvdSB3YW50IHRvIGFjY2VzcyBpbiBzcXVhcmUgYnJhY2tldHMuCk5vdGUgdGhhdCBSIHN0YXJ0cyBjb3VudGluZyBmcm9tIDEgb253YXJkcy4KT3RoZXIgc3Vic2V0cyBjYW4gYmUgY3JlYXRlZCBpbiB0aGUgb2J2aW91cyB3YXkuIFB1dHRpbmcgYSBtaW51cyBpbiAKZnJvbnQsIGV4Y2x1ZGVzCnRoZSBlbGVtZW50czoKCmBgYHtyIHN1YnNjcl8yLCAgIGVjaG8gPSBUUlVFfQp4W2MoMiwgNCwgOSldCnhbLSgxOjYpXQpoZWFkKHgpCmBgYAoKVGhlIGZ1bmN0aW9uIGBoZWFkYCBwcm92aWRlcyBhIHByZXZpZXcgb2YgdGhlIHZlY3Rvci4gVGhlcmUgYXJlIGFsc28gIAp1c2VmdWwgZnVuY3Rpb25zIHRvIG9yZGVyIGFuZCBzb3J0IHZlY3RvcnM6CgoqICBgc29ydGA6ICBzb3J0IGluIGluY3JlYXNpbmcgb3JkZXIKKiAgYG9yZGVyYDogb3JkZXJzIHRoZSBpbmRleGVzIGlzIHN1Y2ggYSB3YXkgdGhhdCB0aGUgZWxlbWVudHMKb2YgdGhlIHZlY3RvciBhcmUgc29ydGVkLCBpLmUgYHNvcnQodikgPSAgdltvcmRlcih2KV1gIAoKKiAgYHJhbmtgOiBnaXZlcyB0aGUgcmFua3Mgb2YgdGhlIGVsZW1lbnRzCm9mIGEgdmVjdG9yLCBkaWZmZXJlbnQgb3B0aW9ucyBmb3IgaGFuZGxpbmcgKnRpZXMqIGFyZQphdmFpbGFibGUuIAoKCmBgYHtyIHNvcnQtcmFuaywgICBlY2hvID0gVFJVRX0KeCA8LSBjKDEuMywgMy41LCAyLjcsIDYuMywgNi4zKQpzb3J0KHgpCm9yZGVyKHgpCnhbb3JkZXIoeCldCnJhbmsoeCkKYGBgCgoKCiMjIE1hdHJpY2VzCgpNYXRyaWNlcyBhcmUgdHdvLS1kaW1lbnNpb25hbCB2ZWN0b3JzIGFuZCAKY2FuIGJlIGNyZWF0ZWQgaW4gUiAgaW4gYSB2YXJpZXR5IG9mIHdheXMuIFBlcmhhcHMgdGhlIHNpbXBsZXN0IGlzIHRvIApjcmVhdGUgdGhlIGNvbHVtbnMKYW5kIHRoZW4gZ2x1ZSB0aGVtIHRvZ2V0aGVyIHdpdGggdGhlIGNvbW1hbmQgYGNiaW5kYC4gRm9yIGV4YW1wbGU6CgoKYGBge3IgY2JpbmQtZXgsICAgZWNobyA9IFRSVUV9CnggPC0gYyg1LCA3ICwgOSkKeSA8LSBjKDYsIDMgLCA0KQp6IDwtIGNiaW5kKHgsIHkpCnoKZGltKHopCmBgYAoKV2UgY2FuIGFsc28gdXNlIHRoZSBmdW5jdGlvbiBgbWF0cml4KClgIGRpcmVjdGx5IHRvIGNyZWF0ZSBhIG1hdHJpeC4KYGBge3IgbWF0cml4X2RpcmVjdCwgICBlY2hvID0gVFJVRX0KeiA8LSBtYXRyaXgoYyg1LCA3LCA5LCA2LCAzLCA0KSwgbnJvdyA9IDMpCmBgYAoKVGhlcmUgaXMgYSBzaW1pbGFyIGNvbW1hbmQsIGByYmluZGAsIGZvciBidWlsZGluZyBtYXRyaWNlcyBieQpnbHVpbmcgcm93cyB0b2dldGhlci4KVGhlIGZ1bmN0aW9ucyBgY2JpbmRgIGFuZCBgcmJpbmRgIGNhbiBhbHNvIGJlIGFwcGxpZWQgdG8gbWF0cmljZXMgdGhlbXNlbHZlcyAKKHByb3ZpZGVkIHRoZSBkaW1lbnNpb25zIG1hdGNoKSB0byBmb3JtIGxhcmdlciBtYXRyaWNlcy4KCk5vdGljZSB0aGF0IHRoZSBkaW1lbnNpb24gb2YgdGhlIG1hdHJpeCBpcyAgZGV0ZXJtaW5lZApieSB0aGUgc2l6ZSBvZiB0aGUgdmVjdG9yIGFuZCB0aGUgcmVxdWlyZW1lbnQgdGhhdCB0aGUgbnVtYmVyIG9mIApyb3dzIGlzIDMgaW4gdGhlIGV4YW1wbGUgYWJvdmUsIGFzIHNwZWNpZmllZCBieSB0aGUKYXJndW1lbnQgYG5yb3cgPSAzYC4gQXMgYW4gYWx0ZXJuYXRpdmUgd2UgY291bGQgaGF2ZSBzcGVjaWZpZWQgCnRoZSBudW1iZXIgb2YgY29sdW1ucyB3aXRoIHRoZSBhcmd1bWVudCBgbmNvbCA9IDJgIChvYnZpb3VzbHksIGl0IGlzIAp1bm5lY2Vzc2FyeSB0byBnaXZlIGJvdGgpLiBOb3RpY2UgdGhhdCB0aGUgbWF0cml4IGlzICJmaWxsZWQgdXAiCmNvbHVtbi13aXNlLiBJZiBpbnN0ZWFkIHlvdSB3aXNoIHRvIGZpbGwgdXAgcm93LXdpc2UsIGFkZCB0aGUgb3B0aW9uIApgYnlyb3c9VFJVRWAuIAogCgpgYGB7ciBNYXRyaXgtZXgsICAgZWNobyA9IFRSVUV9CnogPC0gbWF0cml4KGMoNSwgNyAsIDkgLCA2ICwgMyAsIDQpLCBucm93ID0gMywgYnlyb3cgPSBUUlVFKQp6CmBgYAoKUiB3aWxsIHRyeSB0byBpbnRlcnByZXQgb3BlcmF0aW9ucyBvbiBtYXRyaWNlcyBpbiBhIG5hdHVyYWwgd2F5LiAKRm9yIGV4YW1wbGUsIHdpdGggeiBhcyBhYm92ZSwgYW5kIHkgZGVmaW5lZCBiZWxvdyB3ZSBnZXQ6CgpgYGB7ciBNYXRyaXgtb3AsICAgZWNobyA9IFRSVUV9CnkgPC0gbWF0cml4KGMoMSwgMywgMCwgOSwgNSwgLTEpLCBucm93ID0gMywgYnlyb3cgPSBUUlVFKQp5CnkgKyB6CnkgKiB6CmBgYAoKTm90aWNlIHRoYXQgbXVsdGlwbGljYXRpb24gaGVyZSBpcyBjb21wb25lbnQtLXdpc2UuCkFzIHdpdGggdmVjdG9ycyBpdCBpcyB1c2VmdWwgdG8gYmUgYWJsZSB0byBleHRyYWN0IHN1Yi1jb21wb25lbnRzIG9mIG1hdHJpY2VzLiBJbiB0aGlzIGNhc2UsIHdlCm1heSB3aXNoIHRvIHBpY2sgb3V0IGluZGl2aWR1YWwgZWxlbWVudHMsIHJvd3Mgb3IgY29sdW1ucy4gQXMgYmVmb3JlLCB0aGUgYFsgXWAgCm5vdGF0aW9uIGlzIHVzZWQgdG8gc3Vic2NyaXB0LiBUaGUgZm9sbG93aW5nIGV4YW1wbGVzIGlsbHVzdHJhdGUgdGhpczoKCmBgYHtyIE1hdHJpeC1vcC00LCAgIGVjaG8gPSBUUlVFfQp6WzEsIDFdCnpbLCAyXQp6WzE6MiwgXQp6Wy0xLCBdCnpbLWMoMSwgMiksIF0KYGBgCgoKU28sIGluIHBhcnRpY3VsYXIsIGl0IGlzIG5lY2Vzc2FyeSB0byBzcGVjaWZ5IHdoaWNoIHJvd3MgYW5kIGNvbHVtbnMgYXJlIHJlcXVpcmVkLCAKd2hpbHN0IG9taXR0aW5nIHRoZSBpbmRleCBmb3IgZWl0aGVyIGRpbWVuc2lvbiBpbXBsaWVzIHRoYXQgZXZlcnkgZWxlbWVudCAKaW4gdGhhdCBkaW1lbnNpb24gaXMgc2VsZWN0ZWQuCgoKCiMjIERhdGEgZnJhbWVzICh0aWJibGVzKSBhbmQgbGlzdHMKCgpBIGRhdGEgZnJhbWUgaXMgIGEgbWF0cml4IHdoZXJlIHRoZSBjb2x1bW5zIGNhbiBoYXZlIGRpZmZlcmVudCBkYXRhIHR5cGVzLgpBcyBzdWNoLCBpdCBpcyB1c3VhbGx5IHVzZWQgdG8gcmVwcmVzZW50IGEgd2hvbGUgZGF0YSBzZXQsIHdoZXJlIHRoZSByb3dzCnJlcHJlc2VudCB0aGUgc2FtcGxlcyBhbmQgY29sdW1ucyB0aGUgdmFyaWFibGVzLiBFc3NlbnRpYWxseSwgeW91IGNhbiB0aGluawpvZiBhIGRhdGEgZnJhbWUgYXMgYW4gZXhjZWwgdGFibGUuCgpIZXJlLCB3ZSB3aWxsIG1lZXQgdGhlIGZpcnN0IHRpZHl2ZXJzZSBtZW1iZXIsIG5hbWVseSB0aGUgYHIgQ1JBTnBrZygidGliYmxlIikgYCAKcGFja2FnZSwgd2hpY2ggaW1wcm92ZXMgdGhlIGNvbnZlbnRpb25hbCBSIGBkYXRhLmZyYW1lYCBjbGFzcy4gQSB0aWJibGUKaXMgYSBgZGF0YS5mcmFtZWAgd2hpY2ggYSBsb3Qgb2YgdHdlYWtzIGFuZCBtb3JlIHNlbnNpYmxlIGRlZmF1bHRzIHRoYXQgbWFrZSB5b3VyCmxpZmUgZWFzaWVyLiBGb3IgZGV0YWlscyBvbiB0aGUgdHdlYWtzLCBzZWUgIHRoZSBoZWxwIG9uIHRpYmJsZTogYD90aWJibGVgCnNvIHRoYXQgeW91IG5ldmVyIGhhdmUgdG8gdXNlIGEgc3RhbmRhcmQgZGF0YSBmcmFtZSBhbnltb3JlLgoKTGV0J3MgaWxsdXN0cmF0ZSB0aGlzIGJ5IHRoZSBzbWFsbCBkYXRhIHNldApzYXZlZCBpbiBjb21tYS0tc2VwYXJhdGVkLWZvcm1hdCAoY3N2KSAtLS0KYHBhdGllbnRzYC4gV2UgbG9hZCBpdCBpbiBmcm9tIGEgd2Vic2l0ZSB1c2luZyB0aGUgZnVuY3Rpb24KYHJlYWRfY3N2YCwgd2hpY2ggaXMgdXNlZCB0byBpbXBvcnQgYSBkYXRhIGZpbGUgaW4gCipjb21tYSBzZXBhcmF0ZWQgZm9ybWF0IC0tLSBjc3YqIGludG8gUi4gSW4gYSAuY3N2LS1maWxlIHRoZSBkYXRhIAphcmUgc3RvcmVkIHJvdy0td2lzZSwgYW5kIHRoZSBlbnRyaWVzIGluIGVhY2ggcm93IGFyZSBzZXBhcmF0ZWQgYnkgY29tbWFzLiAKClRoZSBmdW5jdGlvbiBgcmVhZF9jc3ZgIGlzIGZyb20gdGhlIGByIENSQU5wa2coInJlYWRyIilgIHBhY2thZ2UgYW5kIHdpbGwKZ2l2ZSB1cyBhIHRpYmJsZSBhcyB0aGUgcmVzdWx0LiBUaGUgZnVuY3Rpb24gYGdsaW1wc2UoKWAgZ2l2ZXMgYSBuaWNlIHN1bW1hcnkKb2YgYSB0aWJibGUuCgpgYGB7ciBsb2FkLVBhdGllbnRzLCAgIGVjaG8gPSBUUlVFfQpwYXQgPC0gcmVhZF9jc3YoImh0dHA6Ly93d3ctaHViZXIuZW1ibC5kZS91c2Vycy9rbGF1cy9CYXNpY1IvUGF0aWVudHMuY3N2IikKcGF0CmdsaW1wc2UocGF0KQpgYGAKCgoKSXQgaGFzIHdlaWdodCwgaGVpZ2h0IGFuZCBnZW5kZXIgb2YgdGhyZWUgcGVvcGxlLiAKCgojIyBBY2Nlc3NpbmcgZGF0YSBpbiBkYXRhIGZyYW1lcwoKTm93IHRoYXQgd2UgaGF2ZSBpbXBvcnRlZCB0aGUgc21hbGwgZGF0YSBzZXQsIHlvdSBtaWdodCBiZSB3b25kZXJpbmcgaG93IHRvIAphY3R1YWxseSBhY2Nlc3MgdGhlIGRhdGEuIEZvciB0aGlzIHRoZSBmdW5jdGlvbnMgYGZpbHRlcmAgYW5kIGBzZWxlY3RgIGZyb20KdGhlIGByIENSQU5wa2coImRwbHlyIilgIHBhY2thZ2Ugb2YgdGhlIGByIENSQU5wa2coInRpZHl2ZXJzZSIpYCBhcmUgdXNlZnVsLiAKYGZpbHRlcmAgd2lsbCBzZWxlY3QgIGNlcnRhaW4gcm93cyAob2JzZXJ2YXRpb25zKSwKd2hpbGUgYHNlbGVjdGAgd2lsbCBzdWJzZXQgdGhlIGNvbHVtbnMgKHZhcmlhYmxlcyBvZiB0aGUgZGF0YSkuIEluIHRoZSBmb2xsb3dpbmcKY29tbWFuZCwgd2UgZ2V0IGFsbCB0aGUgcGF0aWVudHMgdGhhdCBhcmUgbGVzcyB0YWxsIHRoYW4gMS41IGFuZCBzZWxlY3QgdGhlaXIgSGVpZ2h0IGFuZApHZW5kZXIgYXMgd2VsbCBhcyB0aGVpciBJZDoKCmBgYHtyIHN1YnNldF9kYXRhfQpwYXRfdGlueSA8LSBmaWx0ZXIocGF0LCBIZWlnaHQgPCAxLjcpCnNlbGVjdChwYXRfdGlueSwgUGF0aWVudElkLCAgSGVpZ2h0LCBHZW5kZXIpCmBgYAoKVGhlcmUgYXJlIGEgY291cGxlIG9mIG9wZXJhdG9ycyB1c2VmdWwgZm9yIGNvbXBhcmlzb25zOgoKKiAgYFZhcmlhYmxlID09IHZhbHVlYDogZXF1YWwKKiAgYFZhcmlhYmxlICE9IHZhbHVlYDogdW4tLWVxdWFsCiogIGBWYXJpYWJsZSA8IHZhbHVlYDogbGVzcwoqICBgVmFyaWFibGUgPiB2YWx1ZWA6IGdyZWF0ZXIKKiAgYCY6IGFuZGAKKiAgYHxgIG9yCiogIGAhYDogbmVnYXRpb24KKiAgYCVpbiVgOiBpcyBlbGVtZW50PwoKVGhlIGZ1bmN0aW9uIGBmaWx0ZXJgIGFsbG93cyB1cyB0byBjb21iaW5lIG11bHRpcGxlIGNvbmRpdGlvbnMgZWFzaWx5LCAKaWYgeW91IHNwZWNpZnkgbXVsdGlwbGUgb2YgdGhlbSwgdGhleSB3aWxsIGF1dG9tYXRpY2FsbHkgY29uY2F0ZW5hdGVkIHZpYSBhIGAmYC4KRm9yIGV4YW1wbGUsIHdlIGNhbiBlYXNpbHkgZ2V0IGxpZ2h0IGFuZCBmZW1hbGUgcGF0aWVudHMgdmlhOgoKCmBgYHtyIGxpZ2h0X2FuZF9zbWFsbF9wYXRpZW50cywgICBlY2hvID0gVFJVRX0KZmlsdGVyKHBhdCwgSGVpZ2h0IDwgMS43LCBHZW5kZXIgPT0gImYiKQpgYGAKV2UgY2FuIGFsc28gcmV0cmlldmUgc21hbGwgT1IgZmVtYWxlIHBhdGllbnRzIHZpYQoKYGBge3IgbGlnaHRfb3Jfc21hbGxfcGF0aWVudHMsICAgZWNobyA9IFRSVUV9CmZpbHRlcihwYXQsIChIZWlnaHQgPCAxLjUpIHwgKEdlbmRlciA9PSAiZiIpKQpgYGAKCiMjIFZlY3RvcnMgd2l0aCBhcmJpdHJhcnkgY29udGVudHM6IExpc3RzCgpMaXN0cyBjYW4gYmUgdmlld2VkIGFzIHZlY3RvcnMgdGhhdCBjb250YWluIG5vdCBvbmx5IGVsZW1lbnRhcnkgb2JqZWN0cyBzdWNoIAphcyBudW1iZXIgb3Igc3RyaW5ncyBidXQgY2FuIHBvdGVudGlhbGx5IGFyYml0cmFyeSBvYmplY3RzLiBUaGUgZm9sbG93aW5nIGV4YW1wbGUKd2lsbCBtYWtlIHRoaXMgY2xlYXIuIFRoZSBsaXN0IHRoYXQgd2UgY3JlYXRlIGNvbnRhaW5zIGEgbnVtYmVyLCB0d28gdmVjdG9ycwphbmQgYSBzdHJpbmcgdGhhdCBpcyBpdHNlbGYgcGFydCBvZiBhIGxpc3QuCgoKYGBge3IgbGlzdF9leGFtcGxlLCAgIGVjaG8gPSBUUlVFfQpMIDwtIGxpc3Qob25lID0gMSwgdHdvID0gYygxLCAyKSwgZml2ZSA9IHNlcSgxLCA0LCBsZW5ndGggPSA1KSwgCiAgICAgICAgICBsaXN0KHN0cmluZyA9ICJIZWxsbyBXb3JsZCIpKQpMCmBgYAoKTGlzdHMgYXJlIHRoZSBtb3N0IGdlbmVyYWwgZGF0YSB0eXBlIGluIFIuIEluIGZhY3QsIGRhdGEgZnJhbWVzICh0aWJibGVzKSBhcmUKbGlzdHMgd2l0aCBlbGVtZW50cyBvZiBlcXVhbCBsZW5ndGhzLiBMaXN0IGVsZW1lbnRzIGNhbiBlaXRoZXIgYmUgYWNjZXNzZWQgYnkgCnRoZWlyIG5hbWUgdXNpbmcgdGhlIGRvbGxhciBzaWduIGAkYCBvciB2aWEgdGhlaXIgcG9zaXRpb24gdmlhIGEgZG91YmxlIApicmFja2V0IG9wZXJhdG9yIGBbW11dYC4KCmBgYHtyIGxpc3RfYWNjZXNzLCAgIGVjaG8gPSBUUlVFfQpuYW1lcyhMKQpMJGZpdmUgKyAxMApMW1szXV0gKyAxMApgYGAKClVzaW5nIG9ubHkgYSBzaW5nbGUgYnJhY2tldCAoYFtdYCkgd2lsbCBleHRyYWN0IGEgc3VibGlzdCwgc28gdGhlIHJlc3VsdCB3aWxsCmFsd2F5cyBiZSBhIGxpc3QsIHdoaWxlIHRoZSBkb2xsYXIgc2lnbiBgJGAgb3IgdGhlIGRvdWJsZSBicmFja2V0IG9wZXJhdG9yCmBbW11dYCByZW1vdmVzIGEgbGV2ZWwgb2YgdGhlIGxpc3QgaGllcmFyY2h5LiBUaHVzLCBpbiBvcmRlciB0byBhY2Nlc3MgdGhlIApzdHJpbmcsIHdlIHdvdWxkIGZpcnN0IGhhdmUgdG8gZXh0cmFjdCB0aGUgc3VibGlzdCBjb250YWluaW5nIHRoZSBzdHJpbmcgZnJvbSBgTGAKYW5kIHRoZW4gZ2V0IHRoZSBhY3R1YWwgc3RyaW5nIGZyb20gdGhlIHN1Ymxpc3QsIGBbW2AgZHJpbGxzIGRvd24gaW50byB0aGUgbGlzdCAKd2hpbGUgYFtgIHJldHVybnMgYSBuZXcsIHNtYWxsZXIgbGlzdC4gCgpgYGB7cn0KTFtbNF1dJHN0cmluZwpMWzJdCmBgYAoKU2luY2UgZGF0YSBmcmFtZXMgYXJlIGp1c3QgYSBzcGVjaWFsIGtpbmQgb2YgbGlzdHMsIAp0aGV5IGNhbiBhY3R1YWxseSBiZSBhY2Nlc3NlZCBpbiB0aGUgc2FtZSB3YXkuCgpgYGB7ciBsaXN0LWV4YW1wbGVfZGYsICAgZWNobyA9IFRSVUV9CnBhdCRIZWlnaHQKcGF0W1syXV0KcGF0W1siR2VuZGVyIl1dCmBgYAoKTW9yZSBvbiBsaXN0cyBjYW4gYmUgZm91bmQgaW4gdGhlIHJlc3BlY3RpdmUgY2hhcHRlciBvZiAiUiBmb3IgZGF0YSBzY2llbmNlIgpbaGVyZV0oaHR0cDovL3I0ZHMuaGFkLmNvLm56L3ZlY3RvcnMuaHRtbCNsaXN0cykuCgojIyBTdW1tYXJ5OiBkYXRhIGFjY2VzcyBpbiBSCgpXZSBwcmFwZSBhIHNpbXBsZSB2ZWN0b3IgdG8gaWxsdXN0cmF0ZSB0aGUgYWNjZXNzIG9wdGlvbnMgYWdhaW46CgpgYGB7ciBhY2Nlc19yZWNhcH0Kc2FtcGxlX3ZlY3RvciA8LSBjKCJBbGljZSIgPSA1LjQsICJCb2IiID0gMy43LCAiQ2xhaXJlIiA9IDguOCkKc2FtcGxlX3ZlY3RvcgpgYGAKCiMjIyBBY2Nlc3MgYnkgaW5kZXgKClRoZSBzaW1wbGVzdCB3YXkgdG8gYWNjZXNzIHRoZSBlbGVtZW50cyBpbiBhIHZlY3RvciBpcyB2aWEgdGhlaXIgaW5kaWNlcy4KU3BlY2lmaWNhbGx5LCB5b3UgcHJvdmlkZSBhIHZlY3RvciBvZiBpbmRpY2VzIHRvIHNheSB3aGljaAplbGVtZW50cyBmcm9tIHRoZSB2ZWN0b3IgeW91IHdhbnQgdG8gcmV0cmlldmUuIEEgbWludXMgc2lnbiBleGNsdWRlcyB0aGUgcmVzcGVjdGl2ZQpwb3NpdGlvbnMKCmBgYHtyICBhY2Nlc3NfaW5kZXgsIGRlcGVuZHNvbj0iYWNjZXNSZWNhcCJ9CnNhbXBsZV92ZWN0b3JbMToyXQpzYW1wbGVfdmVjdG9yWy0oMToyKV0KYGBgCgoKIyMjIEFjY2VzcyBieSBib29sZWFuCgpJZiB5b3UgZ2VuZXJhdGUgYSBib29sZWFuIHZlY3RvciB0aGUgc2FtZSBzaXplIGFzIHlvdXIgYWN0dWFsIHZlY3RvciB5b3UgY2FuIHVzZQp0aGUgcG9zaXRpb25zIG9mIHRoZSB0cnVlIHZhbHVlcyB0byBwdWxsIG91dCBjZXJ0YWluIHBvc2l0aW9ucyBmcm9tIHRoZSBmdWxsIHNldC4KWW91IGNhbiBhbHNvIHVzZSBzbWFsbGVyIGJvb2xlYW4gdmVjdG9ycyBhbmQgdGhleSB3aWxsIGJlIGNvbmNhdGVuYXRlZAp0byBtYXRjaCBhbGwgb2YgdGhlIHBvc2l0aW9ucyBpbiB0aGUgdmVjdG9yLCBidXQgdGhpcyBpcyBsZXNzIGNvbW1vbi4KCgpgYGB7ciAgYWNjZXNzX2Jvb2xlYW4sIGRlcGVuZHNvbj0iYWNjZXNfcmVjYXAifQpzYW1wbGVfdmVjdG9yW2MoVFJVRSwgRkFMU0UsIFRSVUUpXQpgYGAKCgpUaGlzIGNhbiBhbHNvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBsb2dpY2FsIHRlc3RzCndoaWNoIGdlbmVyYXRlIGEgYm9vbGVhbiByZXN1bHQuIEJvb2xlYW4gdmVjdG9ycyBjYW4gYmUgY29tYmluZWQgCndpdGggbG9naWNhbCBvcGVyYXRvcnMKIHRvIGNyZWF0ZSBtb3JlIGNvbXBsZXggZmlsdGVycy4KCmBgYHtyICBhY2Nlc3NfYm9vbGVhbjIsIGRlcGVuZHNvbj0iYWNjZXNfcmVjYXAifQpzYW1wbGVfdmVjdG9yW3NhbXBsZV92ZWN0b3IgPCA2XQpgYGAKCiMjIyBBY2Nlc3MgYnkgbmFtZQoKaWYgdGhlcmUgYXJlIG5hbWVzIHN1Y2ggYXMKY29sdW1uIG5hbWVzIHByZXNlbnQgKG5vdGUgdGhhdCByb3duYW1lIGFyZSBub3QgcHJlc2VydmVkIGluIHRoZSB0aWR5dmVyc2UpLCAKeW91IGNhbiBhY2Nlc3MgYnkgbmFtZSBhcyB3ZWxsOgoKYGBge3IgYWNjZXNzX25hbWV9CnNhbXBsZV92ZWN0b3JbYygiQWxpY2UiLCAiQ2xhaXJlIildCmBgYAoKCgojIG1URUMgcXVhbGl0eSBjb250cm9sIGRhdGEKCkZvciBlYWNoIHNpbmdsZS1jZWxsIHRyYW5zY3JpcHRvbWUgb2YgdGhlIG1URUMgZGF0YSwgdGhlIHNlcXVlbmNlZCAKZnJhZ21lbnRzIHdlcmUgbWFwcGVkIHRvIHRoZSBNb3VzZSAgcmVmZXJlbmNlIGdlbm9tZS4gRm9yIGVhY2ggc2FtcGxlIHRoZSByZWFkcyAKd2VyZSBjbGFzc2lmaWVkICBhcyBlaXRoZXI6CgoqIG1hcHBpbmcgdW5pcXVlbHkgdG8gdGhlIHJlZmVyZW5jZSBnZW5vbWUsIAoqIG1hcHBpbmcgbXVsdGlwbGUgdGltZXMgdG8gdGhlIHJlZmVyZW5jZSBnZW5vbWUKKiByZWFkcyB3aGljaCAgY291bGQgbm90ICBiZSBhc3NpZ25lZCB0byBhbnkgcG9zaXRpb24gb2YgdGhlIHJlZmVyZW5jZSBnZW5vbWUKKiBvdGhlcnMgKGUuZyByZWFkIHBhaXJzIHdlcmUgb25seSBvbmUgIHJlYWQgcGFpciBtYXRlIGNvdWxkIGJlIG1hcHBlZCkuIAoKV2UgbG9vayBhdCB0aGUgZGF0YSBhZnRlciBpbXBvcnRpbmcgaXQgdmlhIGEgYGxvYWRgIGNvbW1hbmQgZnJvbSBhbiBgUkRhdGFgIApmaWxlLgoKYGBge3IgbG9hZF9pbnNwZWN0X3FjX2RhdGF9CmxvYWQoZmlsZS5wYXRoKGRhdGFfZGlyLCAic2NfcWNfc3RhdHMuUkRhdGEiKSkKc2NfcWNfc3RhdHMKYGBgCgoKIyBJbnRyb2R1Y2luZyB0aWJibGVzOiBhIGRhdGEuZnJhbWUgcmVwbGFjZW1lbnQKCmBzY19xY19zdGF0c2AgaXMgYSBgciBDUkFOcGtnKCJ0aWJibGUiKWAuIEEgdGliYmxlCmlzIGEgZGF0YS5mcmFtZSB3aGljaCBhIGxvdCBvZiB0d2Vha3MgYW5kIG1vcmUgc2Vuc2libGUgZGVmYXVsdHMgdGhhdCBtYWtlIHlvdXIKbGlmZSBlYXNpZXIsIGFtb25nIG90aGVyIHRoaW5ncyBpdCAuLi4gCgoxLiBOZXZlciBjb2VyY2VzIGlucHV0cyAoaS5lLiBzdHJpbmdzIHN0YXkgYXMgc3RyaW5ncyEpCgoxLiBOZXZlciBhZGRzIHJvdy5uYW1lcwoKMS4gTmV2ZXIgbXVuZ2VzIGNvbHVtbiBuYW1lcyAodGhleSBzdGF5IGFzIHRoZXkgYXJlKQoKMS4gT25seSByZWN5Y2xlcyBsZW5ndGggMSBpbnB1dHMuCgoxLiBBdXRvbWF0aWNhbGx5IGFkZHMgY29sdW1uIG5hbWVzLgoKVGhlIGRhdGEgaXMgIGEgdHlwaWNhbCBkYXRhIHNldCBpbiBhIHRhYnVsYXIgZm9ybWF0LCB3aGVyZSBtdWx0aXBlIG1hcHBpbmcKc3RhdGlzdGljcyBhcmUgZ2l2ZW4gZm9yIGVhY2ggc2luZ2xlIGNlbGwuIFRoZSB0YWJsZSBpcyBpbiBhICJsb25nIiBmb3JtYXQsCm1lYW5pbmcgdGhhdCBlYWNoIHNpbmdsZSBjZWxsIGhhcyBkYXRhIGluIG11bHRpcGxlIHJvd3MuIAoKVGhlIGNvbHVtbnMgZ2l2ZSB0aGUgYW5ub3RhdGlvbiB2YXJpYWJsZXMgKGEuay5hLiAia2V5cyIpOiBgdHlwZWAsIGBjZWxsYCAKYW5kIGBiYXRjaGAgYXMgd2VsbCBhcyBvbiBtZWFzdXJlbW50IChgcGVyY2VudGApLgpBbiBpbXBvcnRhbnQgY29uY2VwdCBpbiBkYXRhIGhhbmRsaW5nIGlzICJ0aWR5IGRhdGEiIAphbmQgd2Ugd2lsbCBleHBsYWluIHdoYXQgdGhhdCBtZWFucyBuZXh0LgoKIyBUaGUgY29uY2VwdCBvZiB0aWR5IGRhdGEKCkluIGEgbnV0c2hlbGwsIGEgIGRhdGFzZXQgaXMgYSBjb2xsZWN0aW9uIG9mIHZhbHVlcywgdXN1YWxseSBlaXRoZXIgbnVtYmVycwooaWYgcXVhbnRpdGF0aXZlKSBvciBzdHJpbmdzIChpZiBxdWFsaXRhdGl2ZSkuIFZhbHVlcyBhcmUgb3JnYW5pemVkIGluIHR3byB3YXlzOgpFdmVyeSB2YWx1ZSBiZWxvbmdzIHRvIGEgdmFyaWFibGUgYW5kIGFuIG9ic2VydmF0aW9uLgoKQSB2YXJpYWJsZSBjb250YWlucyBhbGwgdmFsdWVzIHRoYXQgbWVhc3VyZSBhbiB1bmRlcmx5aW5nIGF0dHJpYnV0ZSAKKGxpa2UgaGVpZ2h0LCB0ZW1wZXJhdHVyZSwgZHVyYXRpb24sIG9yIGhlcmU6IHBlcmNlbnRhZ2Ugb2YgcmVhZHMpIGFjcm9zcyB1bml0cy4KQW4gb2JzZXJ2YXRpb24gY29udGFpbnMgYWxsIHZhbHVlcyBtZWFzdXJlZCBvbiB0aGUgc2FtZSB1bml0IChsaWtlIGEgcGVyc29uLCAKYSBkYXkgb3IgYSBzaW5nbGUgY2VsbCkgYWNyb3NzIGF0dHJpYnV0ZXMuCgpOb3csIGEgdGlkeSBkYXRhIGZyYW1lIGhhczoKCgoxLiBvbmUgcm93IHBlciBvYnNlcnZhdGlvbgoKMi4gb25lIGNvbHVtbiBwZXIgdmFyaWFibGUKCjMuIG9uIGNlbGwgcGVyIHZhbHVlCgoKVGlkeSBkYXRhIHdpbGwgcmVzdWx0IGluIGEgImxvbmciIGRhdGEgdGFibGUgYW5kIGlzICB0aGUgbW9zdCBhcHByb3ByaWF0ZSAKZm9ybWF0IGZvciAKZGF0YSBoYW5kbGluZy4gSXQgYWxsb3dzIHN0cmFpZ2hmb3J3YXJkIHN1YmVzdHRpbmcgYW5kIGdyb3VwLS13aXNlCmNvbXB1dGF0aW9ucy4gSG93ZXZlciwgYSAid2lkZSIgZGF0YSB0YWJsZSBpcyBiZXR0ZXIgZm9yIHZpZXdpbmcuICAKCkluIG91ciBxdWFsaXR5IGNvbnRyb2wgZGF0YSwgdGhlIHJlcXVpcmVtZW50cyBmb3IgdGlkeSBkYXRhIGFyZSBmdWxsZmlsbGVkLiAKSG93ZXZlciwgZm9yIHZpZXdpbmcsIGl0IHdvdWxkIGJlIG5pY2UgdG8gbWFrZSB0aGUgZGF0YSAid2lkZXIiIGJ5IHNwcmVhZGluZyAKdGhlIGNvbHVtbnMgYHR5cGVgIGFuZCBgcGVyY2VudCBhY3Jvc3MgbXVsdGlwbGUgY29sdW1ucywgc28gdGhhdCAKd2UgYWxsIGRhdGEgZm9yIG9uZSBzaW5nbGUgY2VsbCBpbiBvbmUgc2luZ2xlIHJvdy4KClRoZSBwYWNrYWdlIGByIENSQU5wa2coInRpZHlyIilgIGhhcyB0d28gbWFpbiBmdW5jdGlvbnMgdGhhdCBhbGxvd3MgCnVzIHRvIGdvIGJhY2sgYW5kIGZvcnRoOgoKKiBgZ2F0aGVyKClgIHRha2VzIG11bHRpcGxlIGNvbHVtbnMsIGFuZCBnYXRoZXJzIHRoZW0gCmludG8ga2V5LS12YWx1ZSBwYWlyczogaXQgIG1ha2VzICAid2lkZSIgZGF0YSBsb25nZXIuCgoqIGBzcHJlYWQoKWAgdGFrZXMgdHdvIGNvbHVtbnMgKGtleSAmIHZhbHVlKSBhbmQKc3ByZWFkcyBpbnRvIG11bHRpcGxlIGNvbHVtbnMsIGl0IG1ha2VzICJsb25nIiBkYXRhIHdpZGVyLgoKV2lkZW5pbmcgb3VyIGRhdGEgZnJhbWUgaXMgc2ltcGxlOiB3ZSBwcm92aWRlIGEgY29sdW1uIHRvIHNwcmVhZCAoYSBrZXkgY29sdW1uKQphbmQgYSBjb2x1bW4gY29udGFpbmluZyB0aGUgdmFsdWVzIHVzZSAoYSB2YWx1ZSBjb2x1bW4pLgpPdXIga2V5IGNvbHVtbiBpcyBgdHlwZWAgYW5kIG91ciB2YWx1ZSBjb2x1bW4gaXMgYHBlcmNlbnRgCgpgYGB7ciBzcHJlYWRfcWNfc3RhdHN9CnNjX3FjX3N0YXRzX3dpZGUgIDwtIHNwcmVhZChzY19xY19zdGF0cywga2V5ID0gdHlwZSwgdmFsdWUgPSBwZXJjZW50KQpzY19xY19zdGF0c193aWRlCmBgYAoKV2Ugbm93IGhhdmUgc2VwYXJhdGUgY29sdW1ucyBmb3IgZXZlcnkgbWFwcGluZyB0eXBlLCB3aGljaCBtYWtlcyBpdCBlYXNpZXIgdG8KdmlldyB0aGUgZGF0YS4gVGhpcyBkYXRhIGlzIG5vdCAidGlkeSIsIGFzIHRoZSBjb2x1bW5zIHdlIGNyZWF0ZWQgY29udGFpbiBib3RoIAp0aGVyIHBlY2VudCBhcyB3ZWxsIGFzIHRoZSB0eXBlIHZhcmlhYmxlIC0tLSBXZSBoYXZlIG11bHRpcGxlIHZhcmlhYmxlcyAKcGVyIGNvbHVtbi4KClRoZSBmdW5jdGlvbiBgZ2F0aGVyYCBjYW4gYmUgdXNlZCB0byBvYnRhaW4gdGhlIG9yaWdpbmFsCmZvcm1hdCBhZ2FpbjoKCmBgYHtyIGdhdGhlcl9xY19zdGF0c30Kc2NfcWNfc3RhdHNfb3JnIDwtIGdhdGhlcihzY19xY19zdGF0c193aWRlLCBrZXkgPSAidHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAicGVyY2VudCIsIGNvbmNvcmRhbnRNdWx0Om90aGVycykKYGBgCgpXZSBzcGVjaWZ5IHRvIGdhdGhlciB0aGUgcGVyY2VudGFnZXMgaW4gYSBjb2x1bW4gYHBlcmNlbnRgCmFuZCB0aGUgbWFwcGluZyB0eXBlIGluIGEgY29sdW1uIGB0eXBlYC4gVGhlIGB0eXBlYCBjb2x1bW4gYWxsb3dzCnRoZSBtYXRjaGluZyBvZiB0aGUgcGVyY2VudGFnZXMgdG8gdGhlIGNvcnJlc3BvbmRpbmcgY29sdW1uIGluIHRoZQp3aWRlIGRhdGEgZnJhbWUuIEhlbmNlIGl0IGlzIGNhbGxlZCBhIGtleSBjb2x1bW4uCgojIEJhc2ljIGRhdGEgbWFuaXB1bGF0aW9uIHdpdGggZHBseXIgdmVyYnMKClRoZSBwYWNrYWdlICBgciBDUkFOcGtnKCJkcGx5ciIpYCBwcm92aWRlcyBhICJncmFtbWFyIiBvZiBkYXRhIG1hbmlwdWxhdGlvbi4KV2Ugd2lsbCBhbHNvIHVzZSB0aGVtIGV4dGVuc2l2ZWx5IGxhdGVyIG9uIHdoZW4gZGlzY3Vzc2luZyB0aGUKInNwbGl0LS1hcHBseS0tY29tYmluZSIgc3RyYXRlZ3kgZm9yIGRhdGEgYW5hbHlzaXMuCgpTaW5jZSB0aGUgZmlyc3QgdGhpbmcgeW91IGRvIGluIGEgZGF0YSBtYW5pcHVsYXRpb24gdGFzayBpcyB0byBzdWJzZXQvdHJhbnNmb3JtCnlvdXIgZGF0YSwgaXQgaW5jbHVkZXMgInZlcmJzIiB0aGF0IHByb3ZpZGUgYmFzaWMgZnVuY3Rpb25hbGl0eS4gV2Ugd2lsbAppbnRyb2R1Y2UgdGhlc2UgaW4gdGhlIGZvbGxvd2luZy4gVGhlIGNvbW1hbmQgc3RydWN0dXJlIGZvciBhbGwgCmByIENSQU5wa2coImRwbHlyIilgIAp2ZXJicyBpcyA6CgogICogZmlyc3QgYXJndW1lbnQgaXMgYSBkYXRhIGZyYW1lCiAgKiByZXR1cm4gdmFsdWUgaXMgYSBkYXRhIGZyYW1lCiAgKiBub3RoaW5nIGlzIG1vZGlmaWVkIGluIHBsYWNlCgpOb3RlIHRoYXQgYHIgQ1JBTnBrZygiZHBseXIiKWAgZ2VuZXJhbGx5IGRvZXMgbm90IHByZXNlcnZlIHJvdyBuYW1lcy4KCgojIyBTZWxlY3Rpbmcgcm93cyAob2JzZXJ2YXRpb25zKSBieSB0aGVpciB2YWx1ZXMgd2l0aCBgZmlsdGVyKClgCgpUaGUgZnVuY3Rpb24gYGZpbHRlcigpYCBhbGxvd3MgeW91IHRvIHNlbGVjdCBhIHN1YnNldCBvZiB0aGUgcm93cyBvZgphIGRhdGEgZnJhbWUuIFRoZSBmaXJzdCBhcmd1bWVudCBpcyB0aGUgbmFtZSBvZiB0aGUgZGF0YSBmcmFtZSwgYW5kIHRoZQpzZWNvbmQgYW5kIHN1YnNlcXVlbnQgYXJlIGZpbHRlcmluZyBleHByZXNzaW9ucyBldmFsdWF0ZWQgaW4gdGhlIGNvbnRleHQgb2YKdGhhdCBkYXRhIGZyYW1lLiBJbiB0aGUgY29tbWFuZCBiZWxvdywgd2UgZ2V0IGFsbCBjZWxscyB3aXRoIGF0IGxlYXN0IDgwJQpvZiBjb25jb3JkYW50bHkgbWFwcGVkIHJlYWQgcGFpcnMuCgpgYGB7ciBtYXBwZWRfcmVhZHN9CmZpbHRlcihzY19xY19zdGF0c193aWRlLCBjb25jb3JkYW50VW5pcSA+IDgwICkKYGBgCgpgZmlsdGVyKClgICB3b3JrcyBzaW1pbGFybHkgdG8gYHN1YnNldCgpYCBleGNlcHQKdGhhdCB5b3UgY2FuIGdpdmUgaXQgYW55IG51bWJlciBvZiBmaWx0ZXJpbmcKY29uZGl0aW9ucyB3aGljaCBhcmUgam9pbmVkIHRvZ2V0aGVyIHdpdGggJiAobm90ICYmCndoaWNoIGlzIGVhc3kgdG8gZG8gYWNjaWRlbnRhbGx5IG90aGVyd2lzZSkuCgoKYGBge3IgZmlsdGVyX2RhdGFfYW5kfQpoZWFkKGZpbHRlcihzY19xY19zdGF0c193aWRlLCBjb25jb3JkYW50VW5pcSA+IDgwLCBvdGhlcnMgPCA1ICkpCmBgYAoKWW91IGNhbiB1c2Ugb3RoZXIgYm9vbGVhbiBvcGVyYXRvcnMgZXhwbGljaXRseSBhcyBpbjoKCmBgYHtyIGZpbHRlcl9kYXRhX29yfQpoZWFkKGZpbHRlcihzY19xY19zdGF0c193aWRlLCBjb25jb3JkYW50VW5pcSA+IDgwIHwgbm9tYXAgPCAxMCApKQpgYGAKCgojIyBBcnJhbmdlIHJvd3MgKHNhbXBsZXMpIHdpdGggYGFycmFuZ2UoKWAKCmBhcnJhbmdlKClgIHdvcmtzIHNpbWlsYXJseSB0byAgYGZpbHRlcigpYCBleGNlcHQgdGhhdAppbnN0ZWFkIG9mIGZpbHRlcmluZyBvciBzZWxlY3Rpbmcgcm93cywgaXQgcmVvcmRlcnMgdGhlbS4KSXQgdGFrZXMgYSBkYXRhIGZyYW1lLCBhbmQgYSBzZXQgb2YgY29sdW1uIG5hbWVzCihvciBtb3JlIGNvbXBsaWNhdGVkIGV4cHJlc3Npb25zKSB0byBvcmRlciBieS4KSWYgeW91IHByb3ZpZGUgbW9yZSB0aGFuIG9uZSBjb2x1bW4gbmFtZSwgZWFjaCBhZGRpdGlvbmFsIGNvbHVtbiB3aWxsIGJlCnVzZWQgdG8gYnJlYWsgdGllcyBpbiB0aGUgdmFsdWVzIG9mIHByZWNlZGluZyBjb2x1bW5zOgoKCmBgYHtyIGFyYW5nZV9hc2N9CmFycmFuZ2Uoc2NfcWNfc3RhdHNfd2lkZSwgY29uY29yZGFudFVuaXEsIG5vbWFwKSAKYGBgCgpVc2UgYGRlc2MoKWAgdG8gb3JkZXIgYSBjb2x1bW4gaW4gZGVzY2VuZGluZyBvcmRlcjoKCmBgYHtyIGFyYW5nZV9kZXNjfQphcnJhbmdlKHNjX3FjX3N0YXRzX3dpZGUsIGRlc2MoY29uY29yZGFudFVuaXEpLCBub21hcCkgCmBgYAoKCiMjIFNlbGVjdCBjb2x1bW5zICh2YXJpYWJsZXMpIGJ5IHRoZWlyIG5hbWVzIHdpdGggYHNlbGVjdCgpYAoKT2Z0ZW4geW91IHdvcmsgd2l0aCBsYXJnZSBkYXRhIHNldHMgd2l0aCBtYW55IGNvbHVtbnMgd2hlcmUgb25seSBhIGZldyBhcmUKYWN0dWFsbHkgb2YgaW50ZXJlc3QgdG8geW91LiBgc2VsZWN0KClgCmFsbG93cyB5b3UgdG8gcmFwaWRseSB6b29tIGluIG9uIGEgdXNlZnVsIHN1YnNldCB1c2luZyBvcGVyYXRpb25zIHRoYXQgdXN1YWxseQpvbmx5IHdvcmsgb24gbnVtZXJpYyB2YXJpYWJsZSBwb3NpdGlvbnMuIFRoaXMgd2F5LCB3ZSBjYW4gZS5nLiBzZWxlY3Qgb25seQp0aGUgY29sdW1uIGdpdmluZyB0aGUgcGVyY2VudGFnZSBvZiB1bmlxdWVseSBtYXBwaW5nIHJlYWRzLgoKYGBge3Igc2VsZWN0fQpzZWxlY3Qoc2NfcWNfc3RhdHNfd2lkZSwgY29uY29yZGFudFVuaXEpIApgYGAKClRoZSBgc2VsZWN0YCBpcyBzaW1pbGFyIHRvIHRoZSBiYXNpYyBSIGFjY2Nlc3Mgb3B0aW9ucyBmb3IgZGF0YQpmcmFtZTogdGhlIHNxdWFyZSBicmFja2V0IGZvciBpbmRleC9uYW1lIGJhc2VkIGFjY2Vzcy4KCmBgYHtyIGJhc2Vfcl9zZWxlY3R9CnNjX3FjX3N0YXRzX3dpZGVbLCAiY29uY29yZGFudFVuaXEiXQppZHggPC0gd2hpY2goY29sbmFtZXMoc2NfcWNfc3RhdHNfd2lkZSkgPT0gImNvbmNvcmRhbnRVbmlxIikKaWR4CnNjX3FjX3N0YXRzX3dpZGVbLCBpZHhdCmBgYAoKVGhlcmUgYXJlIHR3byBvcHRpb25zIGZvciBvYnRhaW5pbmcgYSB2ZWN0b3IgYXMgYSByZXR1cm4gdHlwZSwgdGhlIGRvdWJsZQpicmFja2V0IGBbW2AgYW5kIHRoZSBkb2xsYXIgc2lnbiBgJGAuCgpgYGB7ciBiYXNlX3Jfc2VsZWN0X3ZlY30KaGVhZChzY19xY19zdGF0c193aWRlJGNvbmNvcmRhbnRVbmlxLCA1KQpoZWFkKHNjX3FjX3N0YXRzX3dpZGVbW2lkeF1dLCA1KQpgYGAKCgojIyBDcmVhdGUgbmV3IHZhcmlhYmxlcyB1c2luZyBleGlzdGluZyBvbmVzIHdpdGggYG11dGF0ZSgpYAoKYGRwbHlyOjptdXRhdGUoKWAgYWxsb3dzIHRvIGFkZCBjb2x1bW5zIHVzaW5nIGV4aXN0aW5nIGNvbHVtbnMgYXMgaW5wdXQuCldlIGltcGxlbWVudCBhIGNvbHVtbiBob2xkaW5nIGEgc3VtIG9mIGFsbCBwZXJjZW50YWdlcyBhcyBzYW5pdHkgY2hlY2s6IAoKYGBge3IgbXV0YXRlLWV4YW1wbGV9CnNjX3FjX3N0YXRzX3dpZGUgPC0gbXV0YXRlKHNjX3FjX3N0YXRzX3dpZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1fcGVyYyA9IGNvbmNvcmRhbnRNdWx0ICsgY29uY29yZGFudFVuaXEgKyBub21hcAogICAgICAgICAgICAgICAgICAgICAgICAgICArIG90aGVycykKCmFsbChyb3VuZChzY19xY19zdGF0c193aWRlJHN1bV9wZXJjKSA9PSAxMDApCmBgYAoKSW5kZWVkLCBhbGwgb2YgdGhlIG1hcHBlZCByZWFkcyBhcmUgYXNzaWduZWQgdG8gYXQgbGVhc3Qgb25lIGNhdGVnb3J5IGZvcgpldmVyeSBzaW5nbGUgY2VsbC4KCgoKIyMgR3JvdXBlZCBzdW1tYXJpZXM6IGBncm91cF9ieSgpYCBhbmQgIGBzdW1tYXJpemUoKWAgCgpXaGlsZSB0aGUgYmFzaWMgYHIgQ1JBTnBrZygiZHBseXIiKWAgdmVyYnMgbWVyZWx5IHJlcGxpY2F0ZSBiYXNlIFIgZnVuY3Rpb25hbGl0eSwKdGhleSBiZWNvbWUgcmVhbGx5IHBvd2VyZnVsIHdoZW4gdXNlZCBpbiBjb25qdWN0aW9uIHdpdGggZ3JvdXBlZCBkYXRhIGZyYW1lcy4KClRoZSBmdW5jdGlvbiBgZ3JvdXBfYnkoKWAgY3JlYXRlcyBncm91cHMgaW4gYSBkYXRhIGZyYW1lIHRvIHdoaWNoIHlvdQpjYW4gdGhlbiBhcHBseSBhbnkgc2V0IG9mIGZ1bmN0aW9ucyBhbmQgZmluYWxseSBvYnRhaW4gYSBuZXcgZGF0YSBmcmFtZSAKd2l0aCB0aGUgcmVzdWx0cyB2aWEgYSBjYWxsIHRvICAgYHN1bW1hcml6ZSgpYC4KCkxldCdzIGxvb2sgYXQgdGhlIG1lYW4gYWxpZ25tZW50IHJhdGVzIHBlciBiYXRjaDoKCmBgYHtyIG1lYW5fcGVyX2JhdGNofQoKc2NfcWNfc3RhdHNfcGVyX2JhdGNoIDwtIGdyb3VwX2J5KHNjX3FjX3N0YXRzLCB0eXBlLCBiYXRjaCkKCnNjX3FjX21lYW5fYWxpZ25fcGVyX2JhdGNoIDwtIGZpbHRlcihzdW1tYXJpemUoc2NfcWNfc3RhdHNfcGVyX2JhdGNoLCAKICAgICAgICAgIG1lYW5fYWxpZ25fcmF0ZSA9IG1lYW4ocGVyY2VudCkpLAogICAgICAgICB0eXBlID09ICJjb25jb3JkYW50VW5pcSIpCgpzY19xY19tZWFuX2FsaWduX3Blcl9iYXRjaApgYGAKCkhlcmUsIHdlIGZpcnN0IGdyb3VwIHRoZSBkYXRhIGJ5ICB0eXBlIGFuZCBiYXRjaCwgdGhlbiBzdW1tYXJpemUKdGhlIHBlcmNlbnRhZ2VzIHBlciByZWFkIGNhdGVnb3J5IGFuZCBmaW5hbGx5IHN1YnNldCB0aGUgcmVzdWx0IHNvIHRoYXQKb25seSB0aGUgbWVhbiByYXRlIGZvciB0aGUgY29uY29yZGFudCByZWFkIHBhaXJzIGFyZSBnaXZlbi4KTm90ZSB0aGF0IGVhY2ggY2FsbCB0byBzdW1tYXJpemUgcGVlbHMgb2ZmIG9uZSBsZXZlbCBvZiBncm91cGluZy4KVGhlIGZ1bmN0aW9uIGB1bmdyb3VwKClgIGNhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgZ3JvdXBpbmcgYWdhaW4uCgojIFRoZSBwaXBpbmcgLyBjaGFpbmluZyBvcGVyYXRvcgoKT3VyIGNvZGUgaW4gdGhlIHByZXZpb3VzIGNvZGUgY2h1bmsgaXMgbmVpdGhlciB2ZXJ5IGVsZWdlbnQgbm9yIGNsZWFyOiAKd2UgY3JlYXRlIGFuIGludGVybWVkaWF0ZSBkYXRhIHRhYmxlIGZvciB0aGUgZ3JvdXBlZCBkYXRhIGFuZCB0aGVuIHVzZSB0aGlzCmluIGEgbGluZSBvZiBjb2RlIHRoYXQgaGFzIHRvIGJlIHJlYWQgZnJvbSB0aGUgaW5zaWRlIHRvIG91dHNpZGUuCgoKVG8gY2hhbmdlIHRoaXMsIHdlIHVzZSB0aGUgY2hhaW5pbmcgKG9yIHBpcGluZykgb3BlcmF0b3IgYCU+JWAuIAp4ICAlPiUgIGYoeSkgICBzaW1wbHkgbWVhbnMgZih4LCB5KS4gVGh1cywgdGhlIGN1cnJlbnQgZGF0YSBmcmFtZSBjYW4KYmUgcHV0IGludG8gYSBmdW5jdGlvbiAob3IgZXZlbiBtdWx0aXBsZSBwcm9jZXNzaW5nIHN0ZXBzKSwgd2hpY2ggaW4gdHVybgpyZXR1cm5zIGEgZGF0YSBmcmFtZS4KCgpUaGlzIGFsbG93cyB1cyB0byBjb2RlIG11bHRpcGxlIG9wZXJhdGlvbnMgaW4gc3VjaCBhIHdheSB0aGF0IHRoZXkgY2FuIGJlIHJlYWQKZnJvbSB5b3UgY2FuIHJlYWQgZnJvbSBsZWZ0LS10by0tcmlnaHQsCnRvcC0tdG8tLWJvdHRvbS4gCgpBIHNpbXBsZSBleGFtcGxlIHdpbGwgbWFrZSB0aGF0IGNsZWFyOiBXZSBjcmVhdGUgCnR3byB2ZWN0b3JzIGFuZCBjYWxjdWxhdGUgRXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gdGhlbS4gSW5zdGVhZCBvZgp0aGUgdXN1YWwgd2F5OgoKYGBge3IgY2hhaW5pbmdTaW1wbGVFeGFtcGxlXzF9CngxIDwtIDE6NTsgeDIgPC0gMjo2CnNxcnQoc3VtKCh4MSAtIHgyKV4yKSkKYGBgCgpXZSBjYW4gdXNlIHRoZSBwaXBpbmcgb3BlcmF0b3IKCmBgYHtyIGNoYWluaW5nU2ltcGxlRXhhbXBsZV8yfQooeDEgLSB4MileMiAlPiUKc3VtKCkgJT4lCnNxcnQoKQpgYGAKCldoaWNoIG1ha2VzIHRoZSBzZXQgb2Ygb3BlcmF0aW9ucyBtdWNoIGVhc2llciB0byBkaWdlc3QgYW5kIHVuZGVyc3RhbmQuCldlIGNhbiBzaW1wbGlmeSBvdXIgY29kZSBsaWtlIHRoaXM6CgpgYGB7ciBtZWFuX3Blcl9iYXRjaF9waXBlfQoKc2NfcWNfbWVhbl9hbGlnbl9wZXJfYmF0Y2ggPC0gZ3JvdXBfYnkoc2NfcWNfc3RhdHMsIGJhdGNoLCB0eXBlICkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpemUobWVhbl9hbGlnbl9yYXRlID0gbWVhbihwZXJjZW50KSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIodHlwZSA9PSAiY29uY29yZGFudFVuaXEiKQoKYGBgCgpJdCBpcyBub3cgY2xlYXIgdGhhdCB5b3UgZ3JvdXAgZmlyc3QsCnRoZW4geW91IHN1bW1hcml6ZSBhbmQgdGhlbiB5b3UgZmlsdGVyLgoKIyMgRmlsdGVyaW5nIHBlciBncm91cAoKRmlsdGVyaW5nIGFsc28gd29ya3Mgb24gZ3JvdXBlZCBkYXRhIGZyYW1lcywgd2UgY2FuIGlkZW50aWZ5IHRoZSBjZWxsIHdpdGgKdGhlIHdvcnN0IGFsaWdubWVudCByYXRlIGluIGVhY2ggYmF0Y2ggbGlrZSB0aGlzOgoKYGBge3Igd29yc3RfY2VsbH0KCndvcnN0X2NlbGxzIDwtICBncm91cF9ieShzY19xY19zdGF0cywgYmF0Y2gsIHR5cGUgKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihwZXJjZW50ID09IG1pbihwZXJjZW50KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9PSAiY29uY29yZGFudFVuaXEiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlKHBlcmNlbnQpICAKCndvcnN0X2NlbGxzIApgYGAKCgojIENvbWJpbmluZyB0YWJsZXMgd2l0aCByZWxhdGVkIGluZm9ybWF0aW9uCgpPZnRlbiwgb25lIHdhbnRzIHRvIGNvbWJpbmUgdHdvIChvciBtb3JlKSB0YWJsZXMgdGhhdCBjb250YWluIHJlbGF0ZWQgaW5mb3JtYXRpb24uClRoaXMgaXMgb2Z0ZW4gdGhlIGNhc2UgYWZ0ZXIgYSBzdW1tYXJpemF0aW9uIG9uIGdyb3VwZWQgIGRhdGEuIAoKQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBkYXRhIHRhYmxlIHNob3dpbmcgcVBDUiBkYXRhIGZvciAKdmFyaW91cyBnZW5lcyAoYHRhcmdldFxfTmFtZWApIGluIHZhcmlvdXMgY2VsbCBsaW5lcyAoYHNhbXBsZVxfbmFtZWApIAppbiB0d28gcmVwbGljYXRlcy4gSW4gcXVhbnRpdGF0aXZlIHJlYWwgdGltZSBQQ1IsIAp0aGUgY29tcGxldGUgUENSIGFtcGxpZmljYXRpb24gcHJvY2VzcyBpcyBtb25pdG9yZWQgYW5kIGEgZmxvcmVzY2VuY2UgaW50ZW5zaXR5IAppcyBvYnRhaW5lZCBmb3IgZWFjaCBjeWNsZS4gQSBjb21tb24gd2F5IHRvIHJlZHVjZSAgdGhlIGRhdGEgZm9yIHRoZSBjb21wbGV0ZSAKcHJvY2VzcyB0byBhIHNpbmdsZSBudW1iZXIsIGlzIHRvICBnaXZlIHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGZsdW9yZXNjZW5jZSAKaXMgaGlnaGVyIHRoYW4gYSBjZXJ0YWluIGJhY2tncm91bmQgdGhyZXNob2xkLiBUaGlzIHZhbHVlcyBpcyBjb21tb25seSByZWZlcnJlZAp0byBhcyAqQ19UKiB2YWx1ZS4KCgpgYGB7ciBkYXRhX3FfcGNyfQpxX3BjciA8LSByZWFkX2NzdihmaWxlLnBhdGgoZGF0YV9kaXIsICJxUENSLmNzdiIpKQpoZWFkKHFfcGNyLCA1KQpgYGAKCgojIyBBZGRpbmcgY29sdW1ucyBncm91cC0td2lzZSAKCkFzIHdlIGhhdmUgdHdvIHJlcGxpY2F0ZXMgcGVyIHNhbXBsZSwgaXQgaXMgYSBuYXR1cmFsIHRvCmFkZCB0aGlzIGFubm90YXRpb24gaW5mb3JtYXRpb24gdG8gdGhlIHRhYmxlLiBOb3RlIHRoYXQKd2UgIGNhbiBhY3R1YWxseSBwZXJmb3JtIGNvbXBsZXggb3BlcmF0aW9ucyBpbiBhIHNpbmdsZSBjaGFpbmluZyAKc3RlcCBieSBzaW1wbHkgd3JhcHBpbmcgdGhlIGNvZGUgaW4gY3VybHkgYnJhY2tldHMuIEhlcmUsIHRoZSAKZG90ICogLiAqIHJlZmVycyB0byB0aGUgY3VycmVudCBkYXRhLiBJbiB0aGUgY29kZSBiZWxvdywgd2UgCmFkZCBhIGNvbHVtbiAqcmVwbGljYXRlKiB0byBlYWNoIHN1Ymdyb3VwIG9mIHRoZSBkYXRhIGZyYW1lCmFuZCB0aGUgcmV0dXJuIHRoZSBhdWdtZW50ZWQgZGF0YSB0YWJsZS4KCmBgYHtyIGFkZF9yZXBfaW5mb30KcV9wY3IgPC0gcV9wY3IgJT4lIAogIGdyb3VwX2J5KHNhbXBsZV9uYW1lKSAlPiUKICB7LiRyZXBsaWNhdGUgPSAgYygicl8xIiwgInJfMiIpCiAgIC59ICU+JSB1bmdyb3VwCgpoZWFkKHFfcGNyKQpgYGAKCgojIyBQZXJmb3JtaW5nIGEgam9pbiBvcGVyYXRpb24KCkFzIGEgZmlyc3QgYW5hbHlzaXMgc3RlcCwgd2UgbWlnaHQgd2FudCB0byBpbmZlciB0aGUgbWVhbiAKYW5kIHRoZSB2YXJpYWJpbGl0eSBvZiB0aGUgKkNfVCogdmFsdWVzLCBpbiBvcmRlciB0byBhc3Nlc3MgYm90aCBnZW5lCmV4cHJlc3Npb24gYW5kIHJlcHJvZHVjaWJpbGl0eS4gV2UgYXNzZXNzIHJlcHJvZHVjaWJpbGl0eSBieSBhCnNwcmVhZCB2YWx1ZSwgd2hpY2ggaXMgc2ltcGx5IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byAKKkNfVCogdmFsdWVzIHBlciBleHBlcmltZW50YWwgc2FtcGxlLgoKYGBge3Igc3VtX2Fjcm9zc19yZXBzLCBkZXBlbmRzb249ImFkZF9yZXBfaW5mbyJ9CnN1bW1hcnlfYWNyb3NzX3JlcHMgPC0gZ3JvdXBfYnkocV9wY3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9uYW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRfTmFtZSkgJT4lCiAgIGRwbHlyOjpzdW1tYXJpemUobWVhbiA9IG1lYW4oQ19ULCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgIHNwcmVhZCA9IGFicyhkaWZmKENfVCkpKSAlPiUgCiAgICB1bmdyb3VwKCkKCmhlYWQoc3VtbWFyeV9hY3Jvc3NfcmVwcywgNSkKYGBgCgpXZSBub3cgbWlnaHQgd2FudCB0byBjb21iaW5lIHRoaXMgaW5mb3JtYXRpb24gdG8gdGhlIG9yaWdpbmFsIGRhdGEgdGFibGUsIHRoaXMKY2FuIGJlIGRvbmUgdXNlIHRoZSB2YXJpb3VzIGpvaW4gZnVuY3Rpb25zIGluIGByIENSQU5wa2coImRwbHlyIikgYC4gSm9pbiBvcGVyYXRpb25zCmNvbWJpbmUgdGFibGVzIGJhc2VkIG9uIGNvbW1vbiBjb2x1bW5zLiBJbiBvdXIgY2FzZSBhIGxlZnQgam9pbiBvcGVyYXRpb24gaXMgdXNlZnVsLCAKd2hpY2ggaW5jbHVkZXMgYWxsIG9ic2VydmF0aW9ucyBpbiB5b3VyIHByaW1hcnkgdGFibGUsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGV5IAptYXRjaCBvciBub3QuIFRoaXMgaXMgdGhlIG1vc3QgY29tbW9ubHkgdXNlZCBqb2luIGJlY2F1c2UgaXQgZW5zdXJlcyB0aGF0IHlvdSAKZG9uJ3QgbG9vc2Ugb2JzZXJ2YXRpb25zIGZyb20geW91ciBwcmltYXJ5IHRhYmxlLiBNb3JlIGluZm9ybWF0aW9uIG9uIHZhcmlvdXMKam9pbiB0eXBlcyBjYW4gYmUgZm91bmQgaGVyZTogPGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9kcGx5ci92aWduZXR0ZXMvdHdvLXRhYmxlLmh0bWw+LgoKYGBge3IgbGVmdF9qb2luX3N1bW0sIGRlcGVuZHNvbj0ic3VtX2Fjcm9zc19yZXBzIn0KYXVnbWVudGVkX3RhYmxlIDwtIGxlZnRfam9pbihxX3Bjciwgc3VtbWFyeV9hY3Jvc3NfcmVwcyApCmhlYWQoYXVnbWVudGVkX3RhYmxlLCA1KQpgYGAKCmByIENSQU5wa2coImRwbHlyIikgYCB3aWxsIGF1dG9tYXRpY2FsbHkgdHJ5IHRvIGlkZW50aWZ5IG1hdGNoaW5nIGNvbHVtbnMsIGFuZAp0ZWxsIHlvdSB3aGljaCBvbmVzIGl0IGhhcyB1c2VkLCAgYnV0IHlvdSBjYW4gYWx3YXlzIHNwZWNpZnkgdGhlbSBtYW51YWxseSAKdXNpbmcgdGhlIF9fYnlfXyBhcmd1bWVudC4KCiMjIEFsdGVybmF0aXZlOiBhIGdyb3VwZWQgbXV0YXRlCgpJbnN0ZWFkIG9mIGNyZWF0aW5nIGEgc3VtbWFyeSBvZiB0aGUgZGF0YSBhbmQgdGhlbiBqb2luaW5nIHRoZSBzdW1tYXJ5IHRvCnRoZSBvcmlnaW5hbCB0YWJsZSwgd2UgY2FuIGFsc28gZGlyZWN0bHkgdXNlIHRoZSBgbXV0YXRlYCBmdW5jdGlvbiBvbgphIGdyb3VwZWQgZGF0YSBzZXQ6CgpgYGB7ciBncm91cGVkX211dGF0ZX0KYXVnbWVudGVkX3RhYmxlX211dGF0ZSA8LSBncm91cF9ieShxX3Bjciwgc2FtcGxlX25hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldF9OYW1lKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKG1lYW4gPSBtZWFuKENfVCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByZWFkID0gYWJzKGRpZmYoQ19UKSkpCgpoZWFkKGF1Z21lbnRlZF90YWJsZV9tdXRhdGUsIDUpIApgYGAKCgoKIyMjIEV4ZXJjaXNlOiBIaWdoIHF1YWxpdHkgY2VsbHMKCjEuIEFzc3VtZSBhIHlvdSB3YW50IHRvIHJldGFpbiBvbmx5IGhpZ2ggcXVhbGl0eSBjZWxscyBkZWZpbmVkIGJ5IGFuIApwZXJjZW50YWdlIG9mIGdyZWF0ZXIgdGhhbiA2MCUgb2YgdW5pcXVlbHkgYW5kIGNvbmNvcmRhbnRseSBtYXBwaW5nIApyZWFkIHBhaXJzLiAKCldoaWNoIHByb3BvcnRpb24gb2YgY2VsbHMgYXJlIG9mIGhpZ2ggcXVhbGl0eT8gVXNlIGZpbHRlcmluZyAKYW5kIHRoZSBmdW5jdGlvbiBgY291bnQoKWAgdG8gYW5zd2VyIHRoaXMuIE1ha2Ugc3VyZSB0byB1bmdyb3VwIHRoZSAKZGF0YSBzZXQgYmVmb3JlIHVzaW5nIHRoZSBmdW5jdGlvbiBgY291bnQoKWAhCgoKYGBge3IgZXhfaGlnaF9xdWFsLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJoaWRlIn0KaHFfY2VsbHMgPC0gbXV0YXRlKHNjX3FjX3N0YXRzLCBoaWdoX3F1YWwgPSBwZXJjZW50ID4gNjApICU+JQogICAgICAgICAgICAgICAgZmlsdGVyKHR5cGUgPT0gImNvbmNvcmRhbnRVbmlxIikgCgpwcm9wX2hpZ2hfcXVhbCA8LSBkcGx5cjo6Y291bnQoaHFfY2VsbHMsIGhpZ2hfcXVhbCkgJT4lCiAgICAgICAgICAgICAgICAgICAgYXJyYW5nZShoaWdoX3F1YWwpICU+JQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShwZXJjX3F1YWwgPSBuIC8gc3VtKG4pKQoKYGBgCgoyLiBDb21wdXRlIHRoZSBwcm9wb3J0aW9uIG9mIGhpZ2ggcXVhbGl0eSBwZXIgYmF0Y2guCgoKYGBge3IgZXhfaGlnaF9xdWFsX2JhdGNoLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJoaWRlIn0KCmdyb3VwX2J5KGhxX2NlbGxzLCBiYXRjaCkgJT4lCiAgICAgICAgZHBseXI6OmNvdW50KGhpZ2hfcXVhbCkgJT4lCiAgICAgICAgbXV0YXRlKHBlcmNfcXVhbCA9IG4gLyBzdW0obikpICAlPiUKICAgICAgICBmaWx0ZXIoaGlnaF9xdWFsID09IFRSVUUpICU+JQogICAgICAgIGFycmFuZ2UocGVyY19xdWFsKQoKYGBgCgoKIyBTZXNzaW9uIEluZm8KCmBgYHtyIHNlc3Npb25JbmZvLCBjYWNoZSA9IEZBTFNFfQpzZXNzaW9uSW5mbygpCmBgYAoKIyBSZWZlcmVuY2VzCgoKCg==</div>
<div id="rmd-source-code">LS0tCnRpdGxlOiAiRGF0YSBoYW5kbGluZyBmb3IgYmlvaW5mb3JtYXRpY3MiCmF1dGhvcjogIkJlcm5kIEtsYXVzIgpkYXRlOiAiYHIgZG9jX2RhdGUoKWAiCm91dHB1dDogCiAgICBCaW9jU3R5bGU6Omh0bWxfZG9jdW1lbnQ6CiAgICAgICAgdG9jOiB0cnVlCiAgICAgICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgICAgICB0b2NfZmxvYXQ6IGZhbHNlCiAgICAgICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgICAgIGRmX3ByaW50OiBwYWdlZAogICAgICAgIHRvY19kZXB0aDogMgogICAgQmlvY1N0eWxlOjpwZGZfZG9jdW1lbnQ6CiAgICAgICAgdG9jOiB0cnVlCiAgICAgICAgdG9jX2RlcHRoOiAyCmJpYmxpb2dyYXBoeTogc3RhdF9tZXRob2RzX2Jpb2luZi5iaWIKLS0tCgo8IS0tCmdyYXBoaWNzLm9mZigpO3JtKGxpc3Q9bHMoKSk7cm1hcmtkb3duOjpyZW5kZXIoJ2RhdGFfaGFuZGxpbmdfYmlvaW5mLlJtZCcsIApvdXRwdXRfZm9ybWF0ID0gIkJpb2NTdHlsZTo6aHRtbF9kb2N1bWVudCIpO3B1cmwoJ2RhdGFfaGFuZGxpbmdfYmlvaW5mLlJtZCcpCgpybWFya2Rvd246OnJlbmRlcignZGF0YV9oYW5kbGluZ19iaW9pbmYuUm1kJywgb3V0cHV0X2Zvcm1hdCA9IAogICAgICAgICAgQmlvY1N0eWxlOjpwZGZfZG9jdW1lbnQodG9jID0gVFJVRSwgaGlnaGxpZ2h0ID0gInRhbmdvIiwgCiAgICAgICAgICBkZl9wcmludCA9ICJwYWdlZCIsIHRvY19kZXB0aCA9IDIpKQotLT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCm9wdGlvbnMoZGlnaXRzPTMsIHdpZHRoPTgwKQpnb2xkZW5fcmF0aW8gPC0gKDEgKyBzcXJ0KDUpKSAvIDIKb3B0c19jaHVuayRzZXQoZWNobz1UUlVFLHRpZHk9RkFMU0UsaW5jbHVkZT1UUlVFLAogICAgICAgICAgICAgICBkZXY9YygncG5nJywgJ3BkZicsICdzdmcnKSwgZmlnLmhlaWdodCA9IDUsIGZpZy53aWR0aCA9IDQgKiBnb2xkZW5fcmF0aW8sIGNvbW1lbnQgPSAnICAnLCBkcGkgPSAzMDAsCmNhY2hlID0gVFJVRSkKYGBgCgogKipMQVNUIFVQREFURSBBVCoqCgpgYGB7ciwgZWNobz1GQUxTRSwgY2FjaGU9RkFMU0V9CnByaW50KGRhdGUoKSkKYGBgCgoKCiMgUmVxdWlyZWQgcGFja2FnZXMgYW5kIG90aGVyIHByZXBhcmF0aW9ucwoKCmBgYHtyIHJlcXVpcmVkX3BhY2thZ2VzX2FuZF9kYXRhLCBlY2hvID0gVFJVRSwgY2FjaGU9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoInJlYWR4bCIpCmxpYnJhcnkoIkJpb2NTdHlsZSIpCmxpYnJhcnkoImtuaXRyIikKbGlicmFyeSgibWF0cml4U3RhdHMiKQpsaWJyYXJ5KCJSQ29sb3JCcmV3ZXIiKQpsaWJyYXJ5KCJzdHJpbmdyIikKbGlicmFyeSgicGhlYXRtYXAiKQpsaWJyYXJ5KCJwdXJyciIpCmxpYnJhcnkoImZkcnRvb2wiKQpsaWJyYXJ5KCJyZWFkciIpCmxpYnJhcnkoImd0b29scyIpCmxpYnJhcnkoImZhY3RvZXh0cmEiKQpsaWJyYXJ5KCJtYWdyaXR0ciIpCmxpYnJhcnkoImVudHJvcHkiKQpsaWJyYXJ5KCJmb3JjYXRzIikKbGlicmFyeSgicGxvdGx5IikKbGlicmFyeSgiY29ycnBsb3QiKQpsaWJyYXJ5KCJjYXIiKQpsaWJyYXJ5KCJmb3JjYXRzIikKbGlicmFyeSgib3Blbnhsc3giKQpsaWJyYXJ5KCJyZWFkeGwiKQpsaWJyYXJ5KCJsaW1tYSIpCmxpYnJhcnkoImdndGhlbWVzIikKbGlicmFyeSgidGlkeXZlcnNlIikKCnRoZW1lX3NldCh0aGVtZV9zb2xhcml6ZWQoYmFzZV9zaXplID0gMTgpKQoKCmRhdGFfZGlyIDwtIGZpbGUucGF0aCgiZGF0YS8iKQoKYGBgCgoKIyBJbnRyb2R1Y3Rpb24gdG8gKHNpbmdsZSBjZWxsKSBSTkEtLVNlcSBkYXRhICAKClRoZSBhZHZlbnQgb2YgbmV4dC1nZW5lcmF0aW9uIHNlcXVlbmNpbmcgb3ZlciBhIGRlY2FkZSBhZ28Kc3B1cnJlZCB0aGUgZGV2ZWxvcG1lbnQgb2YgYSBob3N0IG9mIHNlcXVlbmNpbmctYmFzZWQgdGVjaG5vbG9naWVzLiBPbmUKbWFqb3IgaW5ub3ZhdGlvbiwgUk5BLS1zZXF1ZW5jaW5nIChSTkEtLXNlcSkgZW5hYmxlZCB0cmFuc2NyaXB0b21pYyBwcm9maWxpbmcgYXQKdW5wcmVjZWRlbnRlZCBzZW5zaXRpdml0eSBhbmQgYnJlYWR0aCwgbGVhZGluZyB0byB0aGUgZGlzY292ZXJ5IG9mCm5ldyBSTkEgc3BlY2llcyBhbmQgZGVlcGVuaW5nIG91ciB1bmRlcnN0YW5kaW5nIG9mIHRyYW5zY3JpcHRvbWUKZHluYW1pY3MuIEluIHJlY2VudCB5ZWFycywgbG93LWlucHV0IFJOQS1zZXEgbWV0aG9kcyBoYXZlIGJlZW4KYWRhcHRlZCB0byB3b3JrIGluIHNpbmdsZSBjZWxscy4gVGhlc2Ugc2luZ2xlLWNlbGwgUk5BLXNlcSAoc2NSTkEtCnNlcSkgdGVjaG5vbG9naWVzIGNhbiBxdWFudGlmeSBpbnRyYS1wb3B1bGF0aW9uIGhldGVyb2dlbmVpdHkgYW5kCmVuYWJsZSBzdHVkeSBvZiBjZWxsIHN0YXRlcyBhbmQgdHJhbnNpdGlvbnMgYXQgdmVyeSBoaWdoIHJlc29sdXRpb24sCnBvdGVudGlhbGx5IHJldmVhbGluZyBjZWxsIHN1YnR5cGVzIG9yIGdlbmUgZXhwcmVzc2lvbiBkeW5hbWljcyB0aGF0CmFyZSBtYXNrZWQgaW4gYnVsaywgcG9wdWxhdGlvbi1hdmVyYWdlZCBtZWFzdXJlbWVudHMuCgoKSW4gUk5BLS1TZXEsIFJOQSBpcyBjYXB0dXJlZCBmb3IgcmV2ZXJzZSB0cmFuc2NyaXB0aW9uIGludG8gY0ROQS4gVGhpcwpjRE5BIGlzIHByZS1hbXBsaWZpZWQgYW5kIHRoZW4gdXNlZCB0byBwcmVwYXJlIGxpYnJhcmllcyBmb3IKc2VxdWVuY2luZyBhbmQgZG93bnN0cmVhbSBhbmFseXNpcy4gSW4gc2luZ2xlIGNlbGwgUk5BLS1TZXEgKHNjUk5BLS1TZXEpLCB0aGUgY2VsbHMKaGF2ZSB0byBiZSBseXNlZCBmaXJzdC4gVGhlIGNhcHR1cmUgZWZmZWNpZW5jeSBvZiBzY1JOQS0tU2VxIGlzIHF1aXRlCm9ubHkgYXJvdW5kIDEwJSwgc28gdGhlIGRhdGEgb2J0YWluZWQgaXMgb2Z0ZW4gcXVpdGUgc3BhcnNlOiBNYW55IGdlbmVzCmFyZSBzaW1wbHkgbm90IGNhcHR1cmVkLgoKIyBUaGUgQnJlbm5lY2tlIGV0LiBhbC4gbVRFQyBkYXRhCgoKVGhlIGFiaWxpdHkgb2YgdGhlIGltbXVuZSBzeXN0ZW0gdG8gZGlzdGluZ3Vpc2ggc2VsZiBmcm9tIGZvcmVpZ24gCigic2VsZi0tYW50aWdlbi0tdG9sZXJhbmNlIikgaXMgbGFyZ2VseSBlc3RhYmxpc2hlZCBpbiB0aGUgdGh5bXVzLAphIHByaW1hcnkgbHltcGhvaWQgb3JnYW4gd2hlcmUgVCBjZWxscyBkZXZlbG9wLiAKCkludHJpZ3VpbmdseSwgVC0tY2VsbHMgZW5jb3VudGVyIG1vc3QgdGlzc3VlLS1zcGVjaWZpYyAKY29uc3RpdHVlbnRzIGFscmVhZHkgdGhlcmUsIHRodXMgaW1wb3NpbmcgCmEgYnJvYWQgc2NvcGUgb2YgdG9sZXJhbmNlIGJlZm9yZSBUIGNlbGxzIGNpcmN1bGF0ZSB0aHJvdWdoIHRoZSBib2R5LiAKClRoaXMgInRyYWluaW5nIiBvZiB0aGUgVC0tY2VsbHMgaXMgbmVjY2Vzc2FyeSB0byBwcmV2ZW50IGF1dG9pbXVuaXR5LiBJdApoYXBwZW5zIGJ5IHRoZSAicHJvbWlzY3VvdXMiIGV4cHJlc3Npb24gb2YgbnVtZXJvdXMgdGlzc3VlLXNwZWNpZmljIGFudGlnZW5zIAooVFJBcykgaW4gbWVkdWxsYXJ5IHRoeW1pYyAgZXBpdGhlbGlhbCBjZWxscyAobVRFQ3MsIEBLeWV3c2tpXzIwMDYpLgoKSG93ZXZlciwgaXQgaXMgcG9vcmx5IHVuZGVyc3Rvb2QgaG93IHRoaXMgcHJvY2VzcyBpcyByZWd1bGF0ZWQgaW4Kc2luZ2xlIG1URUNzIGFuZCBpcyBjb29yZGluYXRlZCBhdCB0aGUgcG9wdWxhdGlvbiBsZXZlbC4gQEJyZW5uZWNrZV8yMDE1Cm9idGFpbmVkIHNjUk5BLS1TZXEgZGF0YSBvZiBtVEVDcyBhbmQgZmluZCBldmlkZW5jZSBvZiBudW1lcm91cyByZWN1cnJpbmcgClRSQS0tY28tLWV4cHJlc3Npb24gcGF0dGVybnMsIGVhY2ggcHJlc2VudCBpbiBvbmx5IGEgc3Vic2V0IG9mIG1URUNzLgpUaHVzLCB0aGV5IGNvdWxkIHNob3cgdGhhdCB0aGUgZ2VuZSBleHByZXNzaW9uIGluIG1URUMgY2VsbHMgcmF0aGVyICJtb3NhaWMiIAphbmQgY29vcmRpYW50ZWQgcmF0aGVyIHRoYW4gZW50aXJlbHkgc3RvY2hhc3RpYy4gCgpCZWZvcmUgd2UgIGRpdmUgbW9yZSBkZWVwbHkgaW50byB0aGUgZGF0YSwgd2UgcmV2aWV3IGltcG9ydGFudCBSIGJhc2ljcy4KCgojIEJhc2ljcyBvZiBhcml0aG1ldGljcyBhbmQgZGF0YSBoYW5kbGluZyBpbiBSCgoKIyMgRWxlbWVudGFyeSBkYXRhIHR5cGVzIGFuZCBhcml0aG1ldGljcwoKVGhlIGVsZW1lbnRhcnkgdW5pdCBpbiBSIGlzIGFuIG9iamVjdCBhbmQgdGhlIHNpbXBsZXN0IG9iamVjdHMgYXJlIHNjYWxhcnMsIAp2ZWN0b3JzIGFuZCBtYXRyaWNlcy4gUiBpcyBkZXNpZ25lZCB3aXRoIGludGVyYWN0aXZpdHkgaW4gbWluZCwgc28geW91IGNhbiBnZXQKc3RhcnRlZCBieSBzaW1wbHkgdHlwaW5nOgoKCmBgYHtyIHNpbXBsZV9leCwgZWNobyA9IFRSVUV9CjQgKyA2CmBgYAoKV2hhdCBkb2VzIFIgZG8/IEl0IHN1bXMgdXAgdGhlIHR3byBudW1iZXJzIGFuZCByZXR1cm5zIHRoZSBzY2FsYXIgdmFsdWUgMTAuIApJbiAgZmFjdCwgUiByZXR1cm5zIGEgdmVjdG9yIG9mIGxlbmd0aCAxIC0gaGVuY2UgdGhlIFsxXSBkZW5vdGluZyBmaXJzdCBlbGVtZW50IApvZiB0aGUgdmVjdG9yLgpXZSBjYW4gYXNzaWduIG9iamVjdHMgdmFsdWVzIGZvciBzdWJzZXF1ZW50IHVzZS4gRm9yIGV4YW1wbGU6CgoKYGBge3Igc2ltcGxlX2V4XzIsIGVjaG8gPSBUUlVFfQp4IDwtIDYKeSA8LSA0CnogPC0geCArIHkKegpgYGAKCmRvZXMgdGhlIHNhbWUgY2FsY3VsYXRpb24gYXMgYWJvdmUsIHN0b3JpbmcgdGhlIHJlc3VsdCBpbiBhbiBvYmplY3QgY2FsbGVkIGB6YC4gCldlIGNhbiBsb29rIGF0IHRoZSBjb250ZW50cyBvZiB0aGUgb2JqZWN0IGJ5IHNpbXBseSB0eXBpbmcgaXRzIG5hbWUuIEF0IGFueSAKdGltZSB3ZSBjYW4gCmxpc3QgdGhlIG9iamVjdHMgd2hpY2ggd2UgaGF2ZSBjcmVhdGVkOgoKYGBge3Igc2ltcGxlX2V4XzMsIGVjaG8gPSBUUlVFfQpscygpCmBgYAoKTm90aWNlIHRoYXQgYGxzYCBpcyBhY3R1YWxseSBhbiBvYmplY3QgaXRzZWxmLiBUeXBpbmcgYGxzYCAKb3VsZCByZXN1bHQgaW4gYSBkaXNwbGF5IG9mIHRoZSBjb250ZW50cyBvZgp0aGlzIG9iamVjdCwgaW4gdGhpcyBjYXNlLCB0aGUgY29tbWFuZHMgb2YgdGhlIGZ1bmN0aW9uLiBUaGUgdXNlIG9mIHBhcmVudGhlc2VzLCAKYGxzKClgLCBlbnN1cmVzIHRoYXQKdGhlIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIGFuZCBpdHMgcmVzdWx0IC0tLSBpbiB0aGlzIGNhc2UsIGEgbGlzdCBvZiB0aGUgb2JqZWN0cyAKaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgLS0tIGRpc3BsYXllZC4KTW9yZSBjb21tb25seSwgYSBmdW5jdGlvbiB3aWxsIG9wZXJhdGUgb24gYW4gb2JqZWN0LCBmb3IgZXhhbXBsZQoKYGBge3Igc2ltcGxlX2V4XzQsIGVjaG8gPSBUUlVFfQpzcXJ0KDE2KQpgYGAKCmNhbGN1bGF0ZXMgdGhlIHNxdWFyZSByb290IG9mIDE2LiBPYmplY3RzIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlIGN1cnJlbnQKd29ya3NwYWNlIHdpdGggdGhlIApmdW5jdGlvbiBgcm0oKWAuIFRoZXJlIGFyZSBtYW55IHN0YW5kYXJkIGZ1bmN0aW9ucyBhdmFpbGFibGUgaW4gUiwgCmFuZCBpdCBpcyBhbHNvIHBvc3NpYmxlIHRvIGNyZWF0ZSBuZXcgb25lcy4gVmVjdG9ycyBjYW4gYmUgY3JlYXRlZCBpbiBSIGluCmEgbnVtYmVyIG9mIHdheXMuCkZvciBleGFtcGxlLCB3ZSBjYW4gbGlzdCBhbGwgb2YgdGhlIGVsZW1lbnRzOgoKYGBge3Igc2ltcGxlX2V4XzUsIGVjaG8gPSBUUlVFfQp6IDwtIGMoNSwgOSwgMSwgMCkKYGBgCgoKTm90ZSB0aGUgdXNlIG9mIHRoZSBmdW5jdGlvbiBgY2AgdG8gY29uY2F0ZW5hdGUgb3IgImdsdWUgdG9nZXRoZXIiIGluZGl2aWR1YWwKZWxlbWVudHMuIFRoaXMgZnVuY3Rpb24KY2FuIGJlIHVzZWQgbXVjaCBtb3JlIHdpZGVseSwgZm9yIGV4YW1wbGUKCmBgYHtyIHNpbXBsZV9leF81YiwgZWNobyA9IFRSVUV9CnggPC0gYyg1LCA5KQp5IDwtIGMoMSwgMCkKeiA8LSBjKHgsIHkpCmBgYAoKCndvdWxkIGxlYWQgdG8gdGhlIHNhbWUgcmVzdWx0IGJ5IGdsdWluZyB0b2dldGhlciB0d28gdmVjdG9ycyB0byBjcmVhdGUgCmEgc2luZ2xlIHZlY3Rvci4KU2VxdWVuY2VzIGNhbiBiZSBnZW5lcmF0ZWQgYXMgZm9sbG93czoKCgpgYGB7ciBzaW1wbGVfZXhfNiwgZWNobyA9IFRSVUV9CnNlcSgxLCA5LCBieSA9IDIpCnNlcSg4LCAyMCwgbGVuZ3RoID0gNikKYGBgCgpUaGVzZSBleGFtcGxlcyBpbGx1c3RyYXRlIHRoYXQgbWFueSBmdW5jdGlvbnMgaW4gUiBoYXZlIG9wdGlvbmFsIGFyZ3VtZW50cywKaW4gdGhpcyBjYXNlLCBlaXRoZXIgdGhlIHN0ZXAgbGVuZ3RoIG9yIHRoZSB0b3RhbCBsZW5ndGggb2YgdGhlIHNlcXVlbmNlIAooaXQgZG9lc24ndCBtYWtlIHNlbnNlICB0byB1c2UgYm90aCkuIElmIHlvdSBsZWF2ZQpvdXQgYm90aCBvZiB0aGVzZSBvcHRpb25zLCBSIHdpbGwgbWFrZSBpdHMgb3duIGRlZmF1bHQgY2hvaWNlLCBpbiB0aGlzIGNhc2UKYXNzdW1pbmcgYSBzdGVwIGxlbmd0aApvZiAxLiBTbywgZm9yIGV4YW1wbGUsCgoKYGBge3Igc2ltcGxlX2V4XzcsIGVjaG8gPSBUUlVFfQp4IDwtIHNlcSgxLCAxMCkKYGBgCgphbHNvIGdlbmVyYXRlcyBhIHZlY3RvciBvZiBpbnRlZ2VycyBmcm9tIDEgdG8gMTAuCkF0IHRoaXMgcG9pbnQgaXQncyB3b3J0aCBtZW50aW9uaW5nIHRoZSBoZWxwIGZhY2lsaXR5IGFnYWluLiAKSWYgeW91IGRvbid0IGtub3cgaG93IHRvIHVzZSBhIGZ1bmN0aW9uLApvciBkb24ndCBrbm93IHdoYXQgdGhlIG9wdGlvbnMgb3IgZGVmYXVsdCB2YWx1ZXMgYXJlLCAKdHlwZSBgaGVscChmdW5jdGlvbm5hbWUpYCAKb3IgIHNpbXBseSBgP2Z1bmN0aW9ubmFtZWAgd2hlcmUgCmBmdW5jdGlvbm5hbWVgIGlzIHRoZSBuYW1lIG9mIHRoZSBmdW5jdGlvbiB5b3UgYXJlIGludGVyZXN0ZWQgaW4uIApUaGlzIHdpbGwgdXN1YWxseSBoZWxwIGFuZCB3aWxsIG9mdGVuIGluY2x1ZGUKZXhhbXBsZXMgdG8gbWFrZSB0aGluZ3MgZXZlbiBjbGVhcmVyLgpBbm90aGVyIHVzZWZ1bCBmdW5jdGlvbiBmb3IgYnVpbGRpbmcgdmVjdG9ycyBpcyB0aGUgYHJlcGAgY29tbWFuZCBmb3IgCnJlcGVhdGluZyB0aGluZ3M6CnRoZSBmaXJzdCBjb21tYW5kIHdpbGwgcmVwZWF0IHRoZSB2ZWN0b3IgYHIgMTozYCBzaXggdGltZXMsIHdpbGwgdGhlIHNlY29uZApvbmUgd2lsbCByZXBlYXQgZWFjaCBlbGVtZW50IHNpeCB0aW1lcy4KCmBgYHtyIHNpbXBsZV9leF84LCBlY2hvID0gVFJVRX0KcmVwKDE6MywgNikKcmVwKDE6MywgdGltZXMgPSBjKDYsIDYsIDYpKQpgYGAKClIgd2lsbCBvZnRlbiBhZGFwdCB0byB0aGUgb2JqZWN0cyBpdCBpcyBhc2tlZCB0byB3b3JrIG9uLiBBbiBleGFtcGxlIGlzIHRoZSAKdmVjdG9yaXplZCBhcml0aG1ldGljIHVzZWQgaW4gUjoKCmBgYHtyIHZlY30KeCA8LSAxOjUKeSA8LSA1OjEKeCArIHkKeF4yCnggKiB5CmBgYAoKc2hvd2luZyB0aGF0IFIgdXNlcyBjb21wb25lbnQtd2lzZSBhcml0aG1ldGljIG9uIHZlY3RvcnMuIFIgd2lsbCBhbHNvIHRyeSB0byAKbWFrZSBzZW5zZSBvZiBhIHN0YXRlbWVudCBpZiBvYmplY3RzCmFyZSBtaXhlZC4gRm9yIGV4YW1wbGU6CgpgYGB7ciB2ZWMtMn0KeCA8LSBjKDYsIDggLCA5ICkKeCArIDIKYGBgICAKClR3byBwYXJ0aWN1bGFybHkgdXNlZnVsIGZ1bmN0aW9ucyB3b3J0aCByZW1lbWJlcmluZyBhcmUgYGxlbmd0aGAsIAp3aGljaCByZXR1cm5zIHRoZSBsZW5ndGggb2YgYSB2ZWN0b3IgKGkuZS4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpdCBjb250YWlucykgCmFuZCBgc3VtYCB3aGljaCBjYWxjdWxhdGVzIHRoZSBzdW0gb2YgdGhlIGVsZW1lbnRzCm9mIGEgdmVjdG9yLiBSIGFsc28gaGFzIGJhc2ljIGNhbGN1bGF0b3IgY2FwYWJpbGl0aWVzOgoKCiogYGErYmAsIGBhLWJgLCBgYVwqYmAsICBgYVwqXCpiYCAoYSB0byB0aGUgcG93ZXIgb2YgYikgCiogYWRkaXRpb25hbGx5OiBgc3FydChhKWAsIGBzaW4oYSlgIC4uLgoKYW5kIHNvbWUgc2ltcGxlIHN0YXRpc3RpY3M6IAoKKiAgYCBtZWFuKGEpYAoqICBgIHN1bW1hcnkoYSlgCiogIGAgdmFyKGEpYAoqICBgIG1pbihhLGIpYCwgYG1heChhLGIpYAoKCiMjIFN1YnNjcmlwdGluZyBhbmQgdXNlZnVsIHZlY3RvciBmdW5jdGlvbnMKCkxldCdzIHN1cHBvc2Ugd2UndmUgY29sbGVjdGVkIHNvbWUgZGF0YSBmcm9tIGFuIGV4cGVyaW1lbnQgYW5kIHN0b3JlZCB0aGVtIAppbiBhbiBvYmplY3QgYHhgLgpTb21lIHNpbXBsZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlc2UgZGF0YSBjYW4gYmUgcHJvZHVjZWQ6CgpgYGB7ciBzdW1tYXJ5XzEsICAgZWNobyA9IFRSVUV9CnggPC0gYyg3LjUsIDguMiwgMy4xLCA1LjYsIDguMiwgOS4zLCA2LjUsIDcuMCwgOS4zLCAxLjIsIDE0LjUsIDYuMikKbWVhbih4KQp2YXIoeCkKc3VtbWFyeSh4KQpgYGAKSXQgbWF5IGJlLCBob3dldmVyLCB0aGF0IHdlIHN1YnNlcXVlbnRseSBsZWFybiB0aGF0IHRoZSBmaXJzdAo2IGRhdGEgcG9pbnRzIGNvcnJlc3BvbmQgdG8gbWVhc3VyZW1lbnRzIG1hZGUgaW4gb25lIGV4cGVyaW1lbnQsIAphbmQgdGhlIHNlY29uZCBzaXggb24gYW5vdGhlciBleHBlcmltZW50LgpUaGlzIG1pZ2h0IHN1Z2dlc3Qgc3VtbWFyaXppbmcgdGhlIHR3byBzZXRzIG9mIGRhdGEgc2VwYXJhdGVseSwgCnNvIHdlIHdvdWxkIG5lZWQgdG8gZXh0cmFjdCBmcm9tCmB4YCB0aGUgdHdvIHJlbGV2YW50IHN1YnZlY3RvcnMuIFRoaXMgaXMgYWNoaWV2ZWQgYnkgc3Vic2NyaXB0aW5nOgoKYGBge3Igc3Vic2NyLCAgIGVjaG8gPSBUUlVFfQp4WzE6Nl0KeFs3OjEyXQpzdW1tYXJ5KHhbMTo2XSkKc3VtbWFyeSh4Wzc6MTJdKQpgYGAKCllvdSBzaW1wbHkgcHV0IHRoZSBpbmRleGVzIG9mIHRoZSBlbGVtZW50IHlvdSB3YW50IHRvIGFjY2VzcyBpbiBzcXVhcmUgYnJhY2tldHMuCk5vdGUgdGhhdCBSIHN0YXJ0cyBjb3VudGluZyBmcm9tIDEgb253YXJkcy4KT3RoZXIgc3Vic2V0cyBjYW4gYmUgY3JlYXRlZCBpbiB0aGUgb2J2aW91cyB3YXkuIFB1dHRpbmcgYSBtaW51cyBpbiAKZnJvbnQsIGV4Y2x1ZGVzCnRoZSBlbGVtZW50czoKCmBgYHtyIHN1YnNjcl8yLCAgIGVjaG8gPSBUUlVFfQp4W2MoMiwgNCwgOSldCnhbLSgxOjYpXQpoZWFkKHgpCmBgYAoKVGhlIGZ1bmN0aW9uIGBoZWFkYCBwcm92aWRlcyBhIHByZXZpZXcgb2YgdGhlIHZlY3Rvci4gVGhlcmUgYXJlIGFsc28gIAp1c2VmdWwgZnVuY3Rpb25zIHRvIG9yZGVyIGFuZCBzb3J0IHZlY3RvcnM6CgoqICBgc29ydGA6ICBzb3J0IGluIGluY3JlYXNpbmcgb3JkZXIKKiAgYG9yZGVyYDogb3JkZXJzIHRoZSBpbmRleGVzIGlzIHN1Y2ggYSB3YXkgdGhhdCB0aGUgZWxlbWVudHMKb2YgdGhlIHZlY3RvciBhcmUgc29ydGVkLCBpLmUgYHNvcnQodikgPSAgdltvcmRlcih2KV1gIAoKKiAgYHJhbmtgOiBnaXZlcyB0aGUgcmFua3Mgb2YgdGhlIGVsZW1lbnRzCm9mIGEgdmVjdG9yLCBkaWZmZXJlbnQgb3B0aW9ucyBmb3IgaGFuZGxpbmcgKnRpZXMqIGFyZQphdmFpbGFibGUuIAoKCmBgYHtyIHNvcnQtcmFuaywgICBlY2hvID0gVFJVRX0KeCA8LSBjKDEuMywgMy41LCAyLjcsIDYuMywgNi4zKQpzb3J0KHgpCm9yZGVyKHgpCnhbb3JkZXIoeCldCnJhbmsoeCkKYGBgCgoKCiMjIE1hdHJpY2VzCgpNYXRyaWNlcyBhcmUgdHdvLS1kaW1lbnNpb25hbCB2ZWN0b3JzIGFuZCAKY2FuIGJlIGNyZWF0ZWQgaW4gUiAgaW4gYSB2YXJpZXR5IG9mIHdheXMuIFBlcmhhcHMgdGhlIHNpbXBsZXN0IGlzIHRvIApjcmVhdGUgdGhlIGNvbHVtbnMKYW5kIHRoZW4gZ2x1ZSB0aGVtIHRvZ2V0aGVyIHdpdGggdGhlIGNvbW1hbmQgYGNiaW5kYC4gRm9yIGV4YW1wbGU6CgoKYGBge3IgY2JpbmQtZXgsICAgZWNobyA9IFRSVUV9CnggPC0gYyg1LCA3ICwgOSkKeSA8LSBjKDYsIDMgLCA0KQp6IDwtIGNiaW5kKHgsIHkpCnoKZGltKHopCmBgYAoKV2UgY2FuIGFsc28gdXNlIHRoZSBmdW5jdGlvbiBgbWF0cml4KClgIGRpcmVjdGx5IHRvIGNyZWF0ZSBhIG1hdHJpeC4KYGBge3IgbWF0cml4X2RpcmVjdCwgICBlY2hvID0gVFJVRX0KeiA8LSBtYXRyaXgoYyg1LCA3LCA5LCA2LCAzLCA0KSwgbnJvdyA9IDMpCmBgYAoKVGhlcmUgaXMgYSBzaW1pbGFyIGNvbW1hbmQsIGByYmluZGAsIGZvciBidWlsZGluZyBtYXRyaWNlcyBieQpnbHVpbmcgcm93cyB0b2dldGhlci4KVGhlIGZ1bmN0aW9ucyBgY2JpbmRgIGFuZCBgcmJpbmRgIGNhbiBhbHNvIGJlIGFwcGxpZWQgdG8gbWF0cmljZXMgdGhlbXNlbHZlcyAKKHByb3ZpZGVkIHRoZSBkaW1lbnNpb25zIG1hdGNoKSB0byBmb3JtIGxhcmdlciBtYXRyaWNlcy4KCk5vdGljZSB0aGF0IHRoZSBkaW1lbnNpb24gb2YgdGhlIG1hdHJpeCBpcyAgZGV0ZXJtaW5lZApieSB0aGUgc2l6ZSBvZiB0aGUgdmVjdG9yIGFuZCB0aGUgcmVxdWlyZW1lbnQgdGhhdCB0aGUgbnVtYmVyIG9mIApyb3dzIGlzIDMgaW4gdGhlIGV4YW1wbGUgYWJvdmUsIGFzIHNwZWNpZmllZCBieSB0aGUKYXJndW1lbnQgYG5yb3cgPSAzYC4gQXMgYW4gYWx0ZXJuYXRpdmUgd2UgY291bGQgaGF2ZSBzcGVjaWZpZWQgCnRoZSBudW1iZXIgb2YgY29sdW1ucyB3aXRoIHRoZSBhcmd1bWVudCBgbmNvbCA9IDJgIChvYnZpb3VzbHksIGl0IGlzIAp1bm5lY2Vzc2FyeSB0byBnaXZlIGJvdGgpLiBOb3RpY2UgdGhhdCB0aGUgbWF0cml4IGlzICJmaWxsZWQgdXAiCmNvbHVtbi13aXNlLiBJZiBpbnN0ZWFkIHlvdSB3aXNoIHRvIGZpbGwgdXAgcm93LXdpc2UsIGFkZCB0aGUgb3B0aW9uIApgYnlyb3c9VFJVRWAuIAogCgpgYGB7ciBNYXRyaXgtZXgsICAgZWNobyA9IFRSVUV9CnogPC0gbWF0cml4KGMoNSwgNyAsIDkgLCA2ICwgMyAsIDQpLCBucm93ID0gMywgYnlyb3cgPSBUUlVFKQp6CmBgYAoKUiB3aWxsIHRyeSB0byBpbnRlcnByZXQgb3BlcmF0aW9ucyBvbiBtYXRyaWNlcyBpbiBhIG5hdHVyYWwgd2F5LiAKRm9yIGV4YW1wbGUsIHdpdGggeiBhcyBhYm92ZSwgYW5kIHkgZGVmaW5lZCBiZWxvdyB3ZSBnZXQ6CgpgYGB7ciBNYXRyaXgtb3AsICAgZWNobyA9IFRSVUV9CnkgPC0gbWF0cml4KGMoMSwgMywgMCwgOSwgNSwgLTEpLCBucm93ID0gMywgYnlyb3cgPSBUUlVFKQp5CnkgKyB6CnkgKiB6CmBgYAoKTm90aWNlIHRoYXQgbXVsdGlwbGljYXRpb24gaGVyZSBpcyBjb21wb25lbnQtLXdpc2UuCkFzIHdpdGggdmVjdG9ycyBpdCBpcyB1c2VmdWwgdG8gYmUgYWJsZSB0byBleHRyYWN0IHN1Yi1jb21wb25lbnRzIG9mIG1hdHJpY2VzLiBJbiB0aGlzIGNhc2UsIHdlCm1heSB3aXNoIHRvIHBpY2sgb3V0IGluZGl2aWR1YWwgZWxlbWVudHMsIHJvd3Mgb3IgY29sdW1ucy4gQXMgYmVmb3JlLCB0aGUgYFsgXWAgCm5vdGF0aW9uIGlzIHVzZWQgdG8gc3Vic2NyaXB0LiBUaGUgZm9sbG93aW5nIGV4YW1wbGVzIGlsbHVzdHJhdGUgdGhpczoKCmBgYHtyIE1hdHJpeC1vcC00LCAgIGVjaG8gPSBUUlVFfQp6WzEsIDFdCnpbLCAyXQp6WzE6MiwgXQp6Wy0xLCBdCnpbLWMoMSwgMiksIF0KYGBgCgoKU28sIGluIHBhcnRpY3VsYXIsIGl0IGlzIG5lY2Vzc2FyeSB0byBzcGVjaWZ5IHdoaWNoIHJvd3MgYW5kIGNvbHVtbnMgYXJlIHJlcXVpcmVkLCAKd2hpbHN0IG9taXR0aW5nIHRoZSBpbmRleCBmb3IgZWl0aGVyIGRpbWVuc2lvbiBpbXBsaWVzIHRoYXQgZXZlcnkgZWxlbWVudCAKaW4gdGhhdCBkaW1lbnNpb24gaXMgc2VsZWN0ZWQuCgoKCiMjIERhdGEgZnJhbWVzICh0aWJibGVzKSBhbmQgbGlzdHMKCgpBIGRhdGEgZnJhbWUgaXMgIGEgbWF0cml4IHdoZXJlIHRoZSBjb2x1bW5zIGNhbiBoYXZlIGRpZmZlcmVudCBkYXRhIHR5cGVzLgpBcyBzdWNoLCBpdCBpcyB1c3VhbGx5IHVzZWQgdG8gcmVwcmVzZW50IGEgd2hvbGUgZGF0YSBzZXQsIHdoZXJlIHRoZSByb3dzCnJlcHJlc2VudCB0aGUgc2FtcGxlcyBhbmQgY29sdW1ucyB0aGUgdmFyaWFibGVzLiBFc3NlbnRpYWxseSwgeW91IGNhbiB0aGluawpvZiBhIGRhdGEgZnJhbWUgYXMgYW4gZXhjZWwgdGFibGUuCgpIZXJlLCB3ZSB3aWxsIG1lZXQgdGhlIGZpcnN0IHRpZHl2ZXJzZSBtZW1iZXIsIG5hbWVseSB0aGUgYHIgQ1JBTnBrZygidGliYmxlIikgYCAKcGFja2FnZSwgd2hpY2ggaW1wcm92ZXMgdGhlIGNvbnZlbnRpb25hbCBSIGBkYXRhLmZyYW1lYCBjbGFzcy4gQSB0aWJibGUKaXMgYSBgZGF0YS5mcmFtZWAgd2hpY2ggYSBsb3Qgb2YgdHdlYWtzIGFuZCBtb3JlIHNlbnNpYmxlIGRlZmF1bHRzIHRoYXQgbWFrZSB5b3VyCmxpZmUgZWFzaWVyLiBGb3IgZGV0YWlscyBvbiB0aGUgdHdlYWtzLCBzZWUgIHRoZSBoZWxwIG9uIHRpYmJsZTogYD90aWJibGVgCnNvIHRoYXQgeW91IG5ldmVyIGhhdmUgdG8gdXNlIGEgc3RhbmRhcmQgZGF0YSBmcmFtZSBhbnltb3JlLgoKTGV0J3MgaWxsdXN0cmF0ZSB0aGlzIGJ5IHRoZSBzbWFsbCBkYXRhIHNldApzYXZlZCBpbiBjb21tYS0tc2VwYXJhdGVkLWZvcm1hdCAoY3N2KSAtLS0KYHBhdGllbnRzYC4gV2UgbG9hZCBpdCBpbiBmcm9tIGEgd2Vic2l0ZSB1c2luZyB0aGUgZnVuY3Rpb24KYHJlYWRfY3N2YCwgd2hpY2ggaXMgdXNlZCB0byBpbXBvcnQgYSBkYXRhIGZpbGUgaW4gCipjb21tYSBzZXBhcmF0ZWQgZm9ybWF0IC0tLSBjc3YqIGludG8gUi4gSW4gYSAuY3N2LS1maWxlIHRoZSBkYXRhIAphcmUgc3RvcmVkIHJvdy0td2lzZSwgYW5kIHRoZSBlbnRyaWVzIGluIGVhY2ggcm93IGFyZSBzZXBhcmF0ZWQgYnkgY29tbWFzLiAKClRoZSBmdW5jdGlvbiBgcmVhZF9jc3ZgIGlzIGZyb20gdGhlIGByIENSQU5wa2coInJlYWRyIilgIHBhY2thZ2UgYW5kIHdpbGwKZ2l2ZSB1cyBhIHRpYmJsZSBhcyB0aGUgcmVzdWx0LiBUaGUgZnVuY3Rpb24gYGdsaW1wc2UoKWAgZ2l2ZXMgYSBuaWNlIHN1bW1hcnkKb2YgYSB0aWJibGUuCgpgYGB7ciBsb2FkLVBhdGllbnRzLCAgIGVjaG8gPSBUUlVFfQpwYXQgPC0gcmVhZF9jc3YoImh0dHA6Ly93d3ctaHViZXIuZW1ibC5kZS91c2Vycy9rbGF1cy9CYXNpY1IvUGF0aWVudHMuY3N2IikKcGF0CmdsaW1wc2UocGF0KQpgYGAKCgoKSXQgaGFzIHdlaWdodCwgaGVpZ2h0IGFuZCBnZW5kZXIgb2YgdGhyZWUgcGVvcGxlLiAKCgojIyBBY2Nlc3NpbmcgZGF0YSBpbiBkYXRhIGZyYW1lcwoKTm93IHRoYXQgd2UgaGF2ZSBpbXBvcnRlZCB0aGUgc21hbGwgZGF0YSBzZXQsIHlvdSBtaWdodCBiZSB3b25kZXJpbmcgaG93IHRvIAphY3R1YWxseSBhY2Nlc3MgdGhlIGRhdGEuIEZvciB0aGlzIHRoZSBmdW5jdGlvbnMgYGZpbHRlcmAgYW5kIGBzZWxlY3RgIGZyb20KdGhlIGByIENSQU5wa2coImRwbHlyIilgIHBhY2thZ2Ugb2YgdGhlIGByIENSQU5wa2coInRpZHl2ZXJzZSIpYCBhcmUgdXNlZnVsLiAKYGZpbHRlcmAgd2lsbCBzZWxlY3QgIGNlcnRhaW4gcm93cyAob2JzZXJ2YXRpb25zKSwKd2hpbGUgYHNlbGVjdGAgd2lsbCBzdWJzZXQgdGhlIGNvbHVtbnMgKHZhcmlhYmxlcyBvZiB0aGUgZGF0YSkuIEluIHRoZSBmb2xsb3dpbmcKY29tbWFuZCwgd2UgZ2V0IGFsbCB0aGUgcGF0aWVudHMgdGhhdCBhcmUgbGVzcyB0YWxsIHRoYW4gMS41IGFuZCBzZWxlY3QgdGhlaXIgSGVpZ2h0IGFuZApHZW5kZXIgYXMgd2VsbCBhcyB0aGVpciBJZDoKCmBgYHtyIHN1YnNldF9kYXRhfQpwYXRfdGlueSA8LSBmaWx0ZXIocGF0LCBIZWlnaHQgPCAxLjcpCnNlbGVjdChwYXRfdGlueSwgUGF0aWVudElkLCAgSGVpZ2h0LCBHZW5kZXIpCmBgYAoKVGhlcmUgYXJlIGEgY291cGxlIG9mIG9wZXJhdG9ycyB1c2VmdWwgZm9yIGNvbXBhcmlzb25zOgoKKiAgYFZhcmlhYmxlID09IHZhbHVlYDogZXF1YWwKKiAgYFZhcmlhYmxlICE9IHZhbHVlYDogdW4tLWVxdWFsCiogIGBWYXJpYWJsZSA8IHZhbHVlYDogbGVzcwoqICBgVmFyaWFibGUgPiB2YWx1ZWA6IGdyZWF0ZXIKKiAgYCY6IGFuZGAKKiAgYHxgIG9yCiogIGAhYDogbmVnYXRpb24KKiAgYCVpbiVgOiBpcyBlbGVtZW50PwoKVGhlIGZ1bmN0aW9uIGBmaWx0ZXJgIGFsbG93cyB1cyB0byBjb21iaW5lIG11bHRpcGxlIGNvbmRpdGlvbnMgZWFzaWx5LCAKaWYgeW91IHNwZWNpZnkgbXVsdGlwbGUgb2YgdGhlbSwgdGhleSB3aWxsIGF1dG9tYXRpY2FsbHkgY29uY2F0ZW5hdGVkIHZpYSBhIGAmYC4KRm9yIGV4YW1wbGUsIHdlIGNhbiBlYXNpbHkgZ2V0IGxpZ2h0IGFuZCBmZW1hbGUgcGF0aWVudHMgdmlhOgoKCmBgYHtyIGxpZ2h0X2FuZF9zbWFsbF9wYXRpZW50cywgICBlY2hvID0gVFJVRX0KZmlsdGVyKHBhdCwgSGVpZ2h0IDwgMS43LCBHZW5kZXIgPT0gImYiKQpgYGAKV2UgY2FuIGFsc28gcmV0cmlldmUgc21hbGwgT1IgZmVtYWxlIHBhdGllbnRzIHZpYQoKYGBge3IgbGlnaHRfb3Jfc21hbGxfcGF0aWVudHMsICAgZWNobyA9IFRSVUV9CmZpbHRlcihwYXQsIChIZWlnaHQgPCAxLjUpIHwgKEdlbmRlciA9PSAiZiIpKQpgYGAKCiMjIFZlY3RvcnMgd2l0aCBhcmJpdHJhcnkgY29udGVudHM6IExpc3RzCgpMaXN0cyBjYW4gYmUgdmlld2VkIGFzIHZlY3RvcnMgdGhhdCBjb250YWluIG5vdCBvbmx5IGVsZW1lbnRhcnkgb2JqZWN0cyBzdWNoIAphcyBudW1iZXIgb3Igc3RyaW5ncyBidXQgY2FuIHBvdGVudGlhbGx5IGFyYml0cmFyeSBvYmplY3RzLiBUaGUgZm9sbG93aW5nIGV4YW1wbGUKd2lsbCBtYWtlIHRoaXMgY2xlYXIuIFRoZSBsaXN0IHRoYXQgd2UgY3JlYXRlIGNvbnRhaW5zIGEgbnVtYmVyLCB0d28gdmVjdG9ycwphbmQgYSBzdHJpbmcgdGhhdCBpcyBpdHNlbGYgcGFydCBvZiBhIGxpc3QuCgoKYGBge3IgbGlzdF9leGFtcGxlLCAgIGVjaG8gPSBUUlVFfQpMIDwtIGxpc3Qob25lID0gMSwgdHdvID0gYygxLCAyKSwgZml2ZSA9IHNlcSgxLCA0LCBsZW5ndGggPSA1KSwgCiAgICAgICAgICBsaXN0KHN0cmluZyA9ICJIZWxsbyBXb3JsZCIpKQpMCmBgYAoKTGlzdHMgYXJlIHRoZSBtb3N0IGdlbmVyYWwgZGF0YSB0eXBlIGluIFIuIEluIGZhY3QsIGRhdGEgZnJhbWVzICh0aWJibGVzKSBhcmUKbGlzdHMgd2l0aCBlbGVtZW50cyBvZiBlcXVhbCBsZW5ndGhzLiBMaXN0IGVsZW1lbnRzIGNhbiBlaXRoZXIgYmUgYWNjZXNzZWQgYnkgCnRoZWlyIG5hbWUgdXNpbmcgdGhlIGRvbGxhciBzaWduIGAkYCBvciB2aWEgdGhlaXIgcG9zaXRpb24gdmlhIGEgZG91YmxlIApicmFja2V0IG9wZXJhdG9yIGBbW11dYC4KCmBgYHtyIGxpc3RfYWNjZXNzLCAgIGVjaG8gPSBUUlVFfQpuYW1lcyhMKQpMJGZpdmUgKyAxMApMW1szXV0gKyAxMApgYGAKClVzaW5nIG9ubHkgYSBzaW5nbGUgYnJhY2tldCAoYFtdYCkgd2lsbCBleHRyYWN0IGEgc3VibGlzdCwgc28gdGhlIHJlc3VsdCB3aWxsCmFsd2F5cyBiZSBhIGxpc3QsIHdoaWxlIHRoZSBkb2xsYXIgc2lnbiBgJGAgb3IgdGhlIGRvdWJsZSBicmFja2V0IG9wZXJhdG9yCmBbW11dYCByZW1vdmVzIGEgbGV2ZWwgb2YgdGhlIGxpc3QgaGllcmFyY2h5LiBUaHVzLCBpbiBvcmRlciB0byBhY2Nlc3MgdGhlIApzdHJpbmcsIHdlIHdvdWxkIGZpcnN0IGhhdmUgdG8gZXh0cmFjdCB0aGUgc3VibGlzdCBjb250YWluaW5nIHRoZSBzdHJpbmcgZnJvbSBgTGAKYW5kIHRoZW4gZ2V0IHRoZSBhY3R1YWwgc3RyaW5nIGZyb20gdGhlIHN1Ymxpc3QsIGBbW2AgZHJpbGxzIGRvd24gaW50byB0aGUgbGlzdCAKd2hpbGUgYFtgIHJldHVybnMgYSBuZXcsIHNtYWxsZXIgbGlzdC4gCgpgYGB7cn0KTFtbNF1dJHN0cmluZwpMWzJdCmBgYAoKU2luY2UgZGF0YSBmcmFtZXMgYXJlIGp1c3QgYSBzcGVjaWFsIGtpbmQgb2YgbGlzdHMsIAp0aGV5IGNhbiBhY3R1YWxseSBiZSBhY2Nlc3NlZCBpbiB0aGUgc2FtZSB3YXkuCgpgYGB7ciBsaXN0LWV4YW1wbGVfZGYsICAgZWNobyA9IFRSVUV9CnBhdCRIZWlnaHQKcGF0W1syXV0KcGF0W1siR2VuZGVyIl1dCmBgYAoKTW9yZSBvbiBsaXN0cyBjYW4gYmUgZm91bmQgaW4gdGhlIHJlc3BlY3RpdmUgY2hhcHRlciBvZiAiUiBmb3IgZGF0YSBzY2llbmNlIgpbaGVyZV0oaHR0cDovL3I0ZHMuaGFkLmNvLm56L3ZlY3RvcnMuaHRtbCNsaXN0cykuCgojIyBTdW1tYXJ5OiBkYXRhIGFjY2VzcyBpbiBSCgpXZSBwcmFwZSBhIHNpbXBsZSB2ZWN0b3IgdG8gaWxsdXN0cmF0ZSB0aGUgYWNjZXNzIG9wdGlvbnMgYWdhaW46CgpgYGB7ciBhY2Nlc19yZWNhcH0Kc2FtcGxlX3ZlY3RvciA8LSBjKCJBbGljZSIgPSA1LjQsICJCb2IiID0gMy43LCAiQ2xhaXJlIiA9IDguOCkKc2FtcGxlX3ZlY3RvcgpgYGAKCiMjIyBBY2Nlc3MgYnkgaW5kZXgKClRoZSBzaW1wbGVzdCB3YXkgdG8gYWNjZXNzIHRoZSBlbGVtZW50cyBpbiBhIHZlY3RvciBpcyB2aWEgdGhlaXIgaW5kaWNlcy4KU3BlY2lmaWNhbGx5LCB5b3UgcHJvdmlkZSBhIHZlY3RvciBvZiBpbmRpY2VzIHRvIHNheSB3aGljaAplbGVtZW50cyBmcm9tIHRoZSB2ZWN0b3IgeW91IHdhbnQgdG8gcmV0cmlldmUuIEEgbWludXMgc2lnbiBleGNsdWRlcyB0aGUgcmVzcGVjdGl2ZQpwb3NpdGlvbnMKCmBgYHtyICBhY2Nlc3NfaW5kZXgsIGRlcGVuZHNvbj0iYWNjZXNSZWNhcCJ9CnNhbXBsZV92ZWN0b3JbMToyXQpzYW1wbGVfdmVjdG9yWy0oMToyKV0KYGBgCgoKIyMjIEFjY2VzcyBieSBib29sZWFuCgpJZiB5b3UgZ2VuZXJhdGUgYSBib29sZWFuIHZlY3RvciB0aGUgc2FtZSBzaXplIGFzIHlvdXIgYWN0dWFsIHZlY3RvciB5b3UgY2FuIHVzZQp0aGUgcG9zaXRpb25zIG9mIHRoZSB0cnVlIHZhbHVlcyB0byBwdWxsIG91dCBjZXJ0YWluIHBvc2l0aW9ucyBmcm9tIHRoZSBmdWxsIHNldC4KWW91IGNhbiBhbHNvIHVzZSBzbWFsbGVyIGJvb2xlYW4gdmVjdG9ycyBhbmQgdGhleSB3aWxsIGJlIGNvbmNhdGVuYXRlZAp0byBtYXRjaCBhbGwgb2YgdGhlIHBvc2l0aW9ucyBpbiB0aGUgdmVjdG9yLCBidXQgdGhpcyBpcyBsZXNzIGNvbW1vbi4KCgpgYGB7ciAgYWNjZXNzX2Jvb2xlYW4sIGRlcGVuZHNvbj0iYWNjZXNfcmVjYXAifQpzYW1wbGVfdmVjdG9yW2MoVFJVRSwgRkFMU0UsIFRSVUUpXQpgYGAKCgpUaGlzIGNhbiBhbHNvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBsb2dpY2FsIHRlc3RzCndoaWNoIGdlbmVyYXRlIGEgYm9vbGVhbiByZXN1bHQuIEJvb2xlYW4gdmVjdG9ycyBjYW4gYmUgY29tYmluZWQgCndpdGggbG9naWNhbCBvcGVyYXRvcnMKIHRvIGNyZWF0ZSBtb3JlIGNvbXBsZXggZmlsdGVycy4KCmBgYHtyICBhY2Nlc3NfYm9vbGVhbjIsIGRlcGVuZHNvbj0iYWNjZXNfcmVjYXAifQpzYW1wbGVfdmVjdG9yW3NhbXBsZV92ZWN0b3IgPCA2XQpgYGAKCiMjIyBBY2Nlc3MgYnkgbmFtZQoKaWYgdGhlcmUgYXJlIG5hbWVzIHN1Y2ggYXMKY29sdW1uIG5hbWVzIHByZXNlbnQgKG5vdGUgdGhhdCByb3duYW1lIGFyZSBub3QgcHJlc2VydmVkIGluIHRoZSB0aWR5dmVyc2UpLCAKeW91IGNhbiBhY2Nlc3MgYnkgbmFtZSBhcyB3ZWxsOgoKYGBge3IgYWNjZXNzX25hbWV9CnNhbXBsZV92ZWN0b3JbYygiQWxpY2UiLCAiQ2xhaXJlIildCmBgYAoKCgojIG1URUMgcXVhbGl0eSBjb250cm9sIGRhdGEKCkZvciBlYWNoIHNpbmdsZS1jZWxsIHRyYW5zY3JpcHRvbWUgb2YgdGhlIG1URUMgZGF0YSwgdGhlIHNlcXVlbmNlZCAKZnJhZ21lbnRzIHdlcmUgbWFwcGVkIHRvIHRoZSBNb3VzZSAgcmVmZXJlbmNlIGdlbm9tZS4gRm9yIGVhY2ggc2FtcGxlIHRoZSByZWFkcyAKd2VyZSBjbGFzc2lmaWVkICBhcyBlaXRoZXI6CgoqIG1hcHBpbmcgdW5pcXVlbHkgdG8gdGhlIHJlZmVyZW5jZSBnZW5vbWUsIAoqIG1hcHBpbmcgbXVsdGlwbGUgdGltZXMgdG8gdGhlIHJlZmVyZW5jZSBnZW5vbWUKKiByZWFkcyB3aGljaCAgY291bGQgbm90ICBiZSBhc3NpZ25lZCB0byBhbnkgcG9zaXRpb24gb2YgdGhlIHJlZmVyZW5jZSBnZW5vbWUKKiBvdGhlcnMgKGUuZyByZWFkIHBhaXJzIHdlcmUgb25seSBvbmUgIHJlYWQgcGFpciBtYXRlIGNvdWxkIGJlIG1hcHBlZCkuIAoKV2UgbG9vayBhdCB0aGUgZGF0YSBhZnRlciBpbXBvcnRpbmcgaXQgdmlhIGEgYGxvYWRgIGNvbW1hbmQgZnJvbSBhbiBgUkRhdGFgIApmaWxlLgoKYGBge3IgbG9hZF9pbnNwZWN0X3FjX2RhdGF9CmxvYWQoZmlsZS5wYXRoKGRhdGFfZGlyLCAic2NfcWNfc3RhdHMuUkRhdGEiKSkKc2NfcWNfc3RhdHMKYGBgCgoKIyBJbnRyb2R1Y2luZyB0aWJibGVzOiBhIGRhdGEuZnJhbWUgcmVwbGFjZW1lbnQKCmBzY19xY19zdGF0c2AgaXMgYSBgciBDUkFOcGtnKCJ0aWJibGUiKWAuIEEgdGliYmxlCmlzIGEgZGF0YS5mcmFtZSB3aGljaCBhIGxvdCBvZiB0d2Vha3MgYW5kIG1vcmUgc2Vuc2libGUgZGVmYXVsdHMgdGhhdCBtYWtlIHlvdXIKbGlmZSBlYXNpZXIsIGFtb25nIG90aGVyIHRoaW5ncyBpdCAuLi4gCgoxLiBOZXZlciBjb2VyY2VzIGlucHV0cyAoaS5lLiBzdHJpbmdzIHN0YXkgYXMgc3RyaW5ncyEpCgoxLiBOZXZlciBhZGRzIHJvdy5uYW1lcwoKMS4gTmV2ZXIgbXVuZ2VzIGNvbHVtbiBuYW1lcyAodGhleSBzdGF5IGFzIHRoZXkgYXJlKQoKMS4gT25seSByZWN5Y2xlcyBsZW5ndGggMSBpbnB1dHMuCgoxLiBBdXRvbWF0aWNhbGx5IGFkZHMgY29sdW1uIG5hbWVzLgoKVGhlIGRhdGEgaXMgIGEgdHlwaWNhbCBkYXRhIHNldCBpbiBhIHRhYnVsYXIgZm9ybWF0LCB3aGVyZSBtdWx0aXBlIG1hcHBpbmcKc3RhdGlzdGljcyBhcmUgZ2l2ZW4gZm9yIGVhY2ggc2luZ2xlIGNlbGwuIFRoZSB0YWJsZSBpcyBpbiBhICJsb25nIiBmb3JtYXQsCm1lYW5pbmcgdGhhdCBlYWNoIHNpbmdsZSBjZWxsIGhhcyBkYXRhIGluIG11bHRpcGxlIHJvd3MuIAoKVGhlIGNvbHVtbnMgZ2l2ZSB0aGUgYW5ub3RhdGlvbiB2YXJpYWJsZXMgKGEuay5hLiAia2V5cyIpOiBgdHlwZWAsIGBjZWxsYCAKYW5kIGBiYXRjaGAgYXMgd2VsbCBhcyBvbiBtZWFzdXJlbW50IChgcGVyY2VudGApLgpBbiBpbXBvcnRhbnQgY29uY2VwdCBpbiBkYXRhIGhhbmRsaW5nIGlzICJ0aWR5IGRhdGEiIAphbmQgd2Ugd2lsbCBleHBsYWluIHdoYXQgdGhhdCBtZWFucyBuZXh0LgoKIyBUaGUgY29uY2VwdCBvZiB0aWR5IGRhdGEKCkluIGEgbnV0c2hlbGwsIGEgIGRhdGFzZXQgaXMgYSBjb2xsZWN0aW9uIG9mIHZhbHVlcywgdXN1YWxseSBlaXRoZXIgbnVtYmVycwooaWYgcXVhbnRpdGF0aXZlKSBvciBzdHJpbmdzIChpZiBxdWFsaXRhdGl2ZSkuIFZhbHVlcyBhcmUgb3JnYW5pemVkIGluIHR3byB3YXlzOgpFdmVyeSB2YWx1ZSBiZWxvbmdzIHRvIGEgdmFyaWFibGUgYW5kIGFuIG9ic2VydmF0aW9uLgoKQSB2YXJpYWJsZSBjb250YWlucyBhbGwgdmFsdWVzIHRoYXQgbWVhc3VyZSBhbiB1bmRlcmx5aW5nIGF0dHJpYnV0ZSAKKGxpa2UgaGVpZ2h0LCB0ZW1wZXJhdHVyZSwgZHVyYXRpb24sIG9yIGhlcmU6IHBlcmNlbnRhZ2Ugb2YgcmVhZHMpIGFjcm9zcyB1bml0cy4KQW4gb2JzZXJ2YXRpb24gY29udGFpbnMgYWxsIHZhbHVlcyBtZWFzdXJlZCBvbiB0aGUgc2FtZSB1bml0IChsaWtlIGEgcGVyc29uLCAKYSBkYXkgb3IgYSBzaW5nbGUgY2VsbCkgYWNyb3NzIGF0dHJpYnV0ZXMuCgpOb3csIGEgdGlkeSBkYXRhIGZyYW1lIGhhczoKCgoxLiBvbmUgcm93IHBlciBvYnNlcnZhdGlvbgoKMi4gb25lIGNvbHVtbiBwZXIgdmFyaWFibGUKCjMuIG9uIGNlbGwgcGVyIHZhbHVlCgoKVGlkeSBkYXRhIHdpbGwgcmVzdWx0IGluIGEgImxvbmciIGRhdGEgdGFibGUgYW5kIGlzICB0aGUgbW9zdCBhcHByb3ByaWF0ZSAKZm9ybWF0IGZvciAKZGF0YSBoYW5kbGluZy4gSXQgYWxsb3dzIHN0cmFpZ2hmb3J3YXJkIHN1YmVzdHRpbmcgYW5kIGdyb3VwLS13aXNlCmNvbXB1dGF0aW9ucy4gSG93ZXZlciwgYSAid2lkZSIgZGF0YSB0YWJsZSBpcyBiZXR0ZXIgZm9yIHZpZXdpbmcuICAKCkluIG91ciBxdWFsaXR5IGNvbnRyb2wgZGF0YSwgdGhlIHJlcXVpcmVtZW50cyBmb3IgdGlkeSBkYXRhIGFyZSBmdWxsZmlsbGVkLiAKSG93ZXZlciwgZm9yIHZpZXdpbmcsIGl0IHdvdWxkIGJlIG5pY2UgdG8gbWFrZSB0aGUgZGF0YSAid2lkZXIiIGJ5IHNwcmVhZGluZyAKdGhlIGNvbHVtbnMgYHR5cGVgIGFuZCBgcGVyY2VudCBhY3Jvc3MgbXVsdGlwbGUgY29sdW1ucywgc28gdGhhdCAKd2UgYWxsIGRhdGEgZm9yIG9uZSBzaW5nbGUgY2VsbCBpbiBvbmUgc2luZ2xlIHJvdy4KClRoZSBwYWNrYWdlIGByIENSQU5wa2coInRpZHlyIilgIGhhcyB0d28gbWFpbiBmdW5jdGlvbnMgdGhhdCBhbGxvd3MgCnVzIHRvIGdvIGJhY2sgYW5kIGZvcnRoOgoKKiBgZ2F0aGVyKClgIHRha2VzIG11bHRpcGxlIGNvbHVtbnMsIGFuZCBnYXRoZXJzIHRoZW0gCmludG8ga2V5LS12YWx1ZSBwYWlyczogaXQgIG1ha2VzICAid2lkZSIgZGF0YSBsb25nZXIuCgoqIGBzcHJlYWQoKWAgdGFrZXMgdHdvIGNvbHVtbnMgKGtleSAmIHZhbHVlKSBhbmQKc3ByZWFkcyBpbnRvIG11bHRpcGxlIGNvbHVtbnMsIGl0IG1ha2VzICJsb25nIiBkYXRhIHdpZGVyLgoKV2lkZW5pbmcgb3VyIGRhdGEgZnJhbWUgaXMgc2ltcGxlOiB3ZSBwcm92aWRlIGEgY29sdW1uIHRvIHNwcmVhZCAoYSBrZXkgY29sdW1uKQphbmQgYSBjb2x1bW4gY29udGFpbmluZyB0aGUgdmFsdWVzIHVzZSAoYSB2YWx1ZSBjb2x1bW4pLgpPdXIga2V5IGNvbHVtbiBpcyBgdHlwZWAgYW5kIG91ciB2YWx1ZSBjb2x1bW4gaXMgYHBlcmNlbnRgCgpgYGB7ciBzcHJlYWRfcWNfc3RhdHN9CnNjX3FjX3N0YXRzX3dpZGUgIDwtIHNwcmVhZChzY19xY19zdGF0cywga2V5ID0gdHlwZSwgdmFsdWUgPSBwZXJjZW50KQpzY19xY19zdGF0c193aWRlCmBgYAoKV2Ugbm93IGhhdmUgc2VwYXJhdGUgY29sdW1ucyBmb3IgZXZlcnkgbWFwcGluZyB0eXBlLCB3aGljaCBtYWtlcyBpdCBlYXNpZXIgdG8KdmlldyB0aGUgZGF0YS4gVGhpcyBkYXRhIGlzIG5vdCAidGlkeSIsIGFzIHRoZSBjb2x1bW5zIHdlIGNyZWF0ZWQgY29udGFpbiBib3RoIAp0aGVyIHBlY2VudCBhcyB3ZWxsIGFzIHRoZSB0eXBlIHZhcmlhYmxlIC0tLSBXZSBoYXZlIG11bHRpcGxlIHZhcmlhYmxlcyAKcGVyIGNvbHVtbi4KClRoZSBmdW5jdGlvbiBgZ2F0aGVyYCBjYW4gYmUgdXNlZCB0byBvYnRhaW4gdGhlIG9yaWdpbmFsCmZvcm1hdCBhZ2FpbjoKCmBgYHtyIGdhdGhlcl9xY19zdGF0c30Kc2NfcWNfc3RhdHNfb3JnIDwtIGdhdGhlcihzY19xY19zdGF0c193aWRlLCBrZXkgPSAidHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAicGVyY2VudCIsIGNvbmNvcmRhbnRNdWx0Om90aGVycykKYGBgCgpXZSBzcGVjaWZ5IHRvIGdhdGhlciB0aGUgcGVyY2VudGFnZXMgaW4gYSBjb2x1bW4gYHBlcmNlbnRgCmFuZCB0aGUgbWFwcGluZyB0eXBlIGluIGEgY29sdW1uIGB0eXBlYC4gVGhlIGB0eXBlYCBjb2x1bW4gYWxsb3dzCnRoZSBtYXRjaGluZyBvZiB0aGUgcGVyY2VudGFnZXMgdG8gdGhlIGNvcnJlc3BvbmRpbmcgY29sdW1uIGluIHRoZQp3aWRlIGRhdGEgZnJhbWUuIEhlbmNlIGl0IGlzIGNhbGxlZCBhIGtleSBjb2x1bW4uCgojIEJhc2ljIGRhdGEgbWFuaXB1bGF0aW9uIHdpdGggZHBseXIgdmVyYnMKClRoZSBwYWNrYWdlICBgciBDUkFOcGtnKCJkcGx5ciIpYCBwcm92aWRlcyBhICJncmFtbWFyIiBvZiBkYXRhIG1hbmlwdWxhdGlvbi4KV2Ugd2lsbCBhbHNvIHVzZSB0aGVtIGV4dGVuc2l2ZWx5IGxhdGVyIG9uIHdoZW4gZGlzY3Vzc2luZyB0aGUKInNwbGl0LS1hcHBseS0tY29tYmluZSIgc3RyYXRlZ3kgZm9yIGRhdGEgYW5hbHlzaXMuCgpTaW5jZSB0aGUgZmlyc3QgdGhpbmcgeW91IGRvIGluIGEgZGF0YSBtYW5pcHVsYXRpb24gdGFzayBpcyB0byBzdWJzZXQvdHJhbnNmb3JtCnlvdXIgZGF0YSwgaXQgaW5jbHVkZXMgInZlcmJzIiB0aGF0IHByb3ZpZGUgYmFzaWMgZnVuY3Rpb25hbGl0eS4gV2Ugd2lsbAppbnRyb2R1Y2UgdGhlc2UgaW4gdGhlIGZvbGxvd2luZy4gVGhlIGNvbW1hbmQgc3RydWN0dXJlIGZvciBhbGwgCmByIENSQU5wa2coImRwbHlyIilgIAp2ZXJicyBpcyA6CgogICogZmlyc3QgYXJndW1lbnQgaXMgYSBkYXRhIGZyYW1lCiAgKiByZXR1cm4gdmFsdWUgaXMgYSBkYXRhIGZyYW1lCiAgKiBub3RoaW5nIGlzIG1vZGlmaWVkIGluIHBsYWNlCgpOb3RlIHRoYXQgYHIgQ1JBTnBrZygiZHBseXIiKWAgZ2VuZXJhbGx5IGRvZXMgbm90IHByZXNlcnZlIHJvdyBuYW1lcy4KCgojIyBTZWxlY3Rpbmcgcm93cyAob2JzZXJ2YXRpb25zKSBieSB0aGVpciB2YWx1ZXMgd2l0aCBgZmlsdGVyKClgCgpUaGUgZnVuY3Rpb24gYGZpbHRlcigpYCBhbGxvd3MgeW91IHRvIHNlbGVjdCBhIHN1YnNldCBvZiB0aGUgcm93cyBvZgphIGRhdGEgZnJhbWUuIFRoZSBmaXJzdCBhcmd1bWVudCBpcyB0aGUgbmFtZSBvZiB0aGUgZGF0YSBmcmFtZSwgYW5kIHRoZQpzZWNvbmQgYW5kIHN1YnNlcXVlbnQgYXJlIGZpbHRlcmluZyBleHByZXNzaW9ucyBldmFsdWF0ZWQgaW4gdGhlIGNvbnRleHQgb2YKdGhhdCBkYXRhIGZyYW1lLiBJbiB0aGUgY29tbWFuZCBiZWxvdywgd2UgZ2V0IGFsbCBjZWxscyB3aXRoIGF0IGxlYXN0IDgwJQpvZiBjb25jb3JkYW50bHkgbWFwcGVkIHJlYWQgcGFpcnMuCgpgYGB7ciBtYXBwZWRfcmVhZHN9CmZpbHRlcihzY19xY19zdGF0c193aWRlLCBjb25jb3JkYW50VW5pcSA+IDgwICkKYGBgCgpgZmlsdGVyKClgICB3b3JrcyBzaW1pbGFybHkgdG8gYHN1YnNldCgpYCBleGNlcHQKdGhhdCB5b3UgY2FuIGdpdmUgaXQgYW55IG51bWJlciBvZiBmaWx0ZXJpbmcKY29uZGl0aW9ucyB3aGljaCBhcmUgam9pbmVkIHRvZ2V0aGVyIHdpdGggJiAobm90ICYmCndoaWNoIGlzIGVhc3kgdG8gZG8gYWNjaWRlbnRhbGx5IG90aGVyd2lzZSkuCgoKYGBge3IgZmlsdGVyX2RhdGFfYW5kfQpoZWFkKGZpbHRlcihzY19xY19zdGF0c193aWRlLCBjb25jb3JkYW50VW5pcSA+IDgwLCBvdGhlcnMgPCA1ICkpCmBgYAoKWW91IGNhbiB1c2Ugb3RoZXIgYm9vbGVhbiBvcGVyYXRvcnMgZXhwbGljaXRseSBhcyBpbjoKCmBgYHtyIGZpbHRlcl9kYXRhX29yfQpoZWFkKGZpbHRlcihzY19xY19zdGF0c193aWRlLCBjb25jb3JkYW50VW5pcSA+IDgwIHwgbm9tYXAgPCAxMCApKQpgYGAKCgojIyBBcnJhbmdlIHJvd3MgKHNhbXBsZXMpIHdpdGggYGFycmFuZ2UoKWAKCmBhcnJhbmdlKClgIHdvcmtzIHNpbWlsYXJseSB0byAgYGZpbHRlcigpYCBleGNlcHQgdGhhdAppbnN0ZWFkIG9mIGZpbHRlcmluZyBvciBzZWxlY3Rpbmcgcm93cywgaXQgcmVvcmRlcnMgdGhlbS4KSXQgdGFrZXMgYSBkYXRhIGZyYW1lLCBhbmQgYSBzZXQgb2YgY29sdW1uIG5hbWVzCihvciBtb3JlIGNvbXBsaWNhdGVkIGV4cHJlc3Npb25zKSB0byBvcmRlciBieS4KSWYgeW91IHByb3ZpZGUgbW9yZSB0aGFuIG9uZSBjb2x1bW4gbmFtZSwgZWFjaCBhZGRpdGlvbmFsIGNvbHVtbiB3aWxsIGJlCnVzZWQgdG8gYnJlYWsgdGllcyBpbiB0aGUgdmFsdWVzIG9mIHByZWNlZGluZyBjb2x1bW5zOgoKCmBgYHtyIGFyYW5nZV9hc2N9CmFycmFuZ2Uoc2NfcWNfc3RhdHNfd2lkZSwgY29uY29yZGFudFVuaXEsIG5vbWFwKSAKYGBgCgpVc2UgYGRlc2MoKWAgdG8gb3JkZXIgYSBjb2x1bW4gaW4gZGVzY2VuZGluZyBvcmRlcjoKCmBgYHtyIGFyYW5nZV9kZXNjfQphcnJhbmdlKHNjX3FjX3N0YXRzX3dpZGUsIGRlc2MoY29uY29yZGFudFVuaXEpLCBub21hcCkgCmBgYAoKCiMjIFNlbGVjdCBjb2x1bW5zICh2YXJpYWJsZXMpIGJ5IHRoZWlyIG5hbWVzIHdpdGggYHNlbGVjdCgpYAoKT2Z0ZW4geW91IHdvcmsgd2l0aCBsYXJnZSBkYXRhIHNldHMgd2l0aCBtYW55IGNvbHVtbnMgd2hlcmUgb25seSBhIGZldyBhcmUKYWN0dWFsbHkgb2YgaW50ZXJlc3QgdG8geW91LiBgc2VsZWN0KClgCmFsbG93cyB5b3UgdG8gcmFwaWRseSB6b29tIGluIG9uIGEgdXNlZnVsIHN1YnNldCB1c2luZyBvcGVyYXRpb25zIHRoYXQgdXN1YWxseQpvbmx5IHdvcmsgb24gbnVtZXJpYyB2YXJpYWJsZSBwb3NpdGlvbnMuIFRoaXMgd2F5LCB3ZSBjYW4gZS5nLiBzZWxlY3Qgb25seQp0aGUgY29sdW1uIGdpdmluZyB0aGUgcGVyY2VudGFnZSBvZiB1bmlxdWVseSBtYXBwaW5nIHJlYWRzLgoKYGBge3Igc2VsZWN0fQpzZWxlY3Qoc2NfcWNfc3RhdHNfd2lkZSwgY29uY29yZGFudFVuaXEpIApgYGAKClRoZSBgc2VsZWN0YCBpcyBzaW1pbGFyIHRvIHRoZSBiYXNpYyBSIGFjY2Nlc3Mgb3B0aW9ucyBmb3IgZGF0YQpmcmFtZTogdGhlIHNxdWFyZSBicmFja2V0IGZvciBpbmRleC9uYW1lIGJhc2VkIGFjY2Vzcy4KCmBgYHtyIGJhc2Vfcl9zZWxlY3R9CnNjX3FjX3N0YXRzX3dpZGVbLCAiY29uY29yZGFudFVuaXEiXQppZHggPC0gd2hpY2goY29sbmFtZXMoc2NfcWNfc3RhdHNfd2lkZSkgPT0gImNvbmNvcmRhbnRVbmlxIikKaWR4CnNjX3FjX3N0YXRzX3dpZGVbLCBpZHhdCmBgYAoKVGhlcmUgYXJlIHR3byBvcHRpb25zIGZvciBvYnRhaW5pbmcgYSB2ZWN0b3IgYXMgYSByZXR1cm4gdHlwZSwgdGhlIGRvdWJsZQpicmFja2V0IGBbW2AgYW5kIHRoZSBkb2xsYXIgc2lnbiBgJGAuCgpgYGB7ciBiYXNlX3Jfc2VsZWN0X3ZlY30KaGVhZChzY19xY19zdGF0c193aWRlJGNvbmNvcmRhbnRVbmlxLCA1KQpoZWFkKHNjX3FjX3N0YXRzX3dpZGVbW2lkeF1dLCA1KQpgYGAKCgojIyBDcmVhdGUgbmV3IHZhcmlhYmxlcyB1c2luZyBleGlzdGluZyBvbmVzIHdpdGggYG11dGF0ZSgpYAoKYGRwbHlyOjptdXRhdGUoKWAgYWxsb3dzIHRvIGFkZCBjb2x1bW5zIHVzaW5nIGV4aXN0aW5nIGNvbHVtbnMgYXMgaW5wdXQuCldlIGltcGxlbWVudCBhIGNvbHVtbiBob2xkaW5nIGEgc3VtIG9mIGFsbCBwZXJjZW50YWdlcyBhcyBzYW5pdHkgY2hlY2s6IAoKYGBge3IgbXV0YXRlLWV4YW1wbGV9CnNjX3FjX3N0YXRzX3dpZGUgPC0gbXV0YXRlKHNjX3FjX3N0YXRzX3dpZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1fcGVyYyA9IGNvbmNvcmRhbnRNdWx0ICsgY29uY29yZGFudFVuaXEgKyBub21hcAogICAgICAgICAgICAgICAgICAgICAgICAgICArIG90aGVycykKCmFsbChyb3VuZChzY19xY19zdGF0c193aWRlJHN1bV9wZXJjKSA9PSAxMDApCmBgYAoKSW5kZWVkLCBhbGwgb2YgdGhlIG1hcHBlZCByZWFkcyBhcmUgYXNzaWduZWQgdG8gYXQgbGVhc3Qgb25lIGNhdGVnb3J5IGZvcgpldmVyeSBzaW5nbGUgY2VsbC4KCgoKIyMgR3JvdXBlZCBzdW1tYXJpZXM6IGBncm91cF9ieSgpYCBhbmQgIGBzdW1tYXJpemUoKWAgCgpXaGlsZSB0aGUgYmFzaWMgYHIgQ1JBTnBrZygiZHBseXIiKWAgdmVyYnMgbWVyZWx5IHJlcGxpY2F0ZSBiYXNlIFIgZnVuY3Rpb25hbGl0eSwKdGhleSBiZWNvbWUgcmVhbGx5IHBvd2VyZnVsIHdoZW4gdXNlZCBpbiBjb25qdWN0aW9uIHdpdGggZ3JvdXBlZCBkYXRhIGZyYW1lcy4KClRoZSBmdW5jdGlvbiBgZ3JvdXBfYnkoKWAgY3JlYXRlcyBncm91cHMgaW4gYSBkYXRhIGZyYW1lIHRvIHdoaWNoIHlvdQpjYW4gdGhlbiBhcHBseSBhbnkgc2V0IG9mIGZ1bmN0aW9ucyBhbmQgZmluYWxseSBvYnRhaW4gYSBuZXcgZGF0YSBmcmFtZSAKd2l0aCB0aGUgcmVzdWx0cyB2aWEgYSBjYWxsIHRvICAgYHN1bW1hcml6ZSgpYC4KCkxldCdzIGxvb2sgYXQgdGhlIG1lYW4gYWxpZ25tZW50IHJhdGVzIHBlciBiYXRjaDoKCmBgYHtyIG1lYW5fcGVyX2JhdGNofQoKc2NfcWNfc3RhdHNfcGVyX2JhdGNoIDwtIGdyb3VwX2J5KHNjX3FjX3N0YXRzLCB0eXBlLCBiYXRjaCkKCnNjX3FjX21lYW5fYWxpZ25fcGVyX2JhdGNoIDwtIGZpbHRlcihzdW1tYXJpemUoc2NfcWNfc3RhdHNfcGVyX2JhdGNoLCAKICAgICAgICAgIG1lYW5fYWxpZ25fcmF0ZSA9IG1lYW4ocGVyY2VudCkpLAogICAgICAgICB0eXBlID09ICJjb25jb3JkYW50VW5pcSIpCgpzY19xY19tZWFuX2FsaWduX3Blcl9iYXRjaApgYGAKCkhlcmUsIHdlIGZpcnN0IGdyb3VwIHRoZSBkYXRhIGJ5ICB0eXBlIGFuZCBiYXRjaCwgdGhlbiBzdW1tYXJpemUKdGhlIHBlcmNlbnRhZ2VzIHBlciByZWFkIGNhdGVnb3J5IGFuZCBmaW5hbGx5IHN1YnNldCB0aGUgcmVzdWx0IHNvIHRoYXQKb25seSB0aGUgbWVhbiByYXRlIGZvciB0aGUgY29uY29yZGFudCByZWFkIHBhaXJzIGFyZSBnaXZlbi4KTm90ZSB0aGF0IGVhY2ggY2FsbCB0byBzdW1tYXJpemUgcGVlbHMgb2ZmIG9uZSBsZXZlbCBvZiBncm91cGluZy4KVGhlIGZ1bmN0aW9uIGB1bmdyb3VwKClgIGNhbiBiZSB1c2VkIHRvIHJlbW92ZSB0aGUgZ3JvdXBpbmcgYWdhaW4uCgojIFRoZSBwaXBpbmcgLyBjaGFpbmluZyBvcGVyYXRvcgoKT3VyIGNvZGUgaW4gdGhlIHByZXZpb3VzIGNvZGUgY2h1bmsgaXMgbmVpdGhlciB2ZXJ5IGVsZWdlbnQgbm9yIGNsZWFyOiAKd2UgY3JlYXRlIGFuIGludGVybWVkaWF0ZSBkYXRhIHRhYmxlIGZvciB0aGUgZ3JvdXBlZCBkYXRhIGFuZCB0aGVuIHVzZSB0aGlzCmluIGEgbGluZSBvZiBjb2RlIHRoYXQgaGFzIHRvIGJlIHJlYWQgZnJvbSB0aGUgaW5zaWRlIHRvIG91dHNpZGUuCgoKVG8gY2hhbmdlIHRoaXMsIHdlIHVzZSB0aGUgY2hhaW5pbmcgKG9yIHBpcGluZykgb3BlcmF0b3IgYCU+JWAuIAp4ICAlPiUgIGYoeSkgICBzaW1wbHkgbWVhbnMgZih4LCB5KS4gVGh1cywgdGhlIGN1cnJlbnQgZGF0YSBmcmFtZSBjYW4KYmUgcHV0IGludG8gYSBmdW5jdGlvbiAob3IgZXZlbiBtdWx0aXBsZSBwcm9jZXNzaW5nIHN0ZXBzKSwgd2hpY2ggaW4gdHVybgpyZXR1cm5zIGEgZGF0YSBmcmFtZS4KCgpUaGlzIGFsbG93cyB1cyB0byBjb2RlIG11bHRpcGxlIG9wZXJhdGlvbnMgaW4gc3VjaCBhIHdheSB0aGF0IHRoZXkgY2FuIGJlIHJlYWQKZnJvbSB5b3UgY2FuIHJlYWQgZnJvbSBsZWZ0LS10by0tcmlnaHQsCnRvcC0tdG8tLWJvdHRvbS4gCgpBIHNpbXBsZSBleGFtcGxlIHdpbGwgbWFrZSB0aGF0IGNsZWFyOiBXZSBjcmVhdGUgCnR3byB2ZWN0b3JzIGFuZCBjYWxjdWxhdGUgRXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gdGhlbS4gSW5zdGVhZCBvZgp0aGUgdXN1YWwgd2F5OgoKYGBge3IgY2hhaW5pbmdTaW1wbGVFeGFtcGxlXzF9CngxIDwtIDE6NTsgeDIgPC0gMjo2CnNxcnQoc3VtKCh4MSAtIHgyKV4yKSkKYGBgCgpXZSBjYW4gdXNlIHRoZSBwaXBpbmcgb3BlcmF0b3IKCmBgYHtyIGNoYWluaW5nU2ltcGxlRXhhbXBsZV8yfQooeDEgLSB4MileMiAlPiUKc3VtKCkgJT4lCnNxcnQoKQpgYGAKCldoaWNoIG1ha2VzIHRoZSBzZXQgb2Ygb3BlcmF0aW9ucyBtdWNoIGVhc2llciB0byBkaWdlc3QgYW5kIHVuZGVyc3RhbmQuCldlIGNhbiBzaW1wbGlmeSBvdXIgY29kZSBsaWtlIHRoaXM6CgpgYGB7ciBtZWFuX3Blcl9iYXRjaF9waXBlfQoKc2NfcWNfbWVhbl9hbGlnbl9wZXJfYmF0Y2ggPC0gZ3JvdXBfYnkoc2NfcWNfc3RhdHMsIGJhdGNoLCB0eXBlICkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpemUobWVhbl9hbGlnbl9yYXRlID0gbWVhbihwZXJjZW50KSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIodHlwZSA9PSAiY29uY29yZGFudFVuaXEiKQoKYGBgCgpJdCBpcyBub3cgY2xlYXIgdGhhdCB5b3UgZ3JvdXAgZmlyc3QsCnRoZW4geW91IHN1bW1hcml6ZSBhbmQgdGhlbiB5b3UgZmlsdGVyLgoKIyMgRmlsdGVyaW5nIHBlciBncm91cAoKRmlsdGVyaW5nIGFsc28gd29ya3Mgb24gZ3JvdXBlZCBkYXRhIGZyYW1lcywgd2UgY2FuIGlkZW50aWZ5IHRoZSBjZWxsIHdpdGgKdGhlIHdvcnN0IGFsaWdubWVudCByYXRlIGluIGVhY2ggYmF0Y2ggbGlrZSB0aGlzOgoKYGBge3Igd29yc3RfY2VsbH0KCndvcnN0X2NlbGxzIDwtICBncm91cF9ieShzY19xY19zdGF0cywgYmF0Y2gsIHR5cGUgKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihwZXJjZW50ID09IG1pbihwZXJjZW50KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9PSAiY29uY29yZGFudFVuaXEiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlKHBlcmNlbnQpICAKCndvcnN0X2NlbGxzIApgYGAKCgojIENvbWJpbmluZyB0YWJsZXMgd2l0aCByZWxhdGVkIGluZm9ybWF0aW9uCgpPZnRlbiwgb25lIHdhbnRzIHRvIGNvbWJpbmUgdHdvIChvciBtb3JlKSB0YWJsZXMgdGhhdCBjb250YWluIHJlbGF0ZWQgaW5mb3JtYXRpb24uClRoaXMgaXMgb2Z0ZW4gdGhlIGNhc2UgYWZ0ZXIgYSBzdW1tYXJpemF0aW9uIG9uIGdyb3VwZWQgIGRhdGEuIAoKQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBkYXRhIHRhYmxlIHNob3dpbmcgcVBDUiBkYXRhIGZvciAKdmFyaW91cyBnZW5lcyAoYHRhcmdldFxfTmFtZWApIGluIHZhcmlvdXMgY2VsbCBsaW5lcyAoYHNhbXBsZVxfbmFtZWApIAppbiB0d28gcmVwbGljYXRlcy4gSW4gcXVhbnRpdGF0aXZlIHJlYWwgdGltZSBQQ1IsIAp0aGUgY29tcGxldGUgUENSIGFtcGxpZmljYXRpb24gcHJvY2VzcyBpcyBtb25pdG9yZWQgYW5kIGEgZmxvcmVzY2VuY2UgaW50ZW5zaXR5IAppcyBvYnRhaW5lZCBmb3IgZWFjaCBjeWNsZS4gQSBjb21tb24gd2F5IHRvIHJlZHVjZSAgdGhlIGRhdGEgZm9yIHRoZSBjb21wbGV0ZSAKcHJvY2VzcyB0byBhIHNpbmdsZSBudW1iZXIsIGlzIHRvICBnaXZlIHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGZsdW9yZXNjZW5jZSAKaXMgaGlnaGVyIHRoYW4gYSBjZXJ0YWluIGJhY2tncm91bmQgdGhyZXNob2xkLiBUaGlzIHZhbHVlcyBpcyBjb21tb25seSByZWZlcnJlZAp0byBhcyAqQ19UKiB2YWx1ZS4KCgpgYGB7ciBkYXRhX3FfcGNyfQpxX3BjciA8LSByZWFkX2NzdihmaWxlLnBhdGgoZGF0YV9kaXIsICJxUENSLmNzdiIpKQpoZWFkKHFfcGNyLCA1KQpgYGAKCgojIyBBZGRpbmcgY29sdW1ucyBncm91cC0td2lzZSAKCkFzIHdlIGhhdmUgdHdvIHJlcGxpY2F0ZXMgcGVyIHNhbXBsZSwgaXQgaXMgYSBuYXR1cmFsIHRvCmFkZCB0aGlzIGFubm90YXRpb24gaW5mb3JtYXRpb24gdG8gdGhlIHRhYmxlLiBJbiB0aGUgY29kZSBiZWxvdywgd2UgCmFkZCBhIGNvbHVtbiAqcmVwbGljYXRlKiB0byBlYWNoIHN1Ymdyb3VwIG9mIHRoZSBkYXRhIGZyYW1lCmFuZCB0aGUgcmV0dXJuIHRoZSBhdWdtZW50ZWQgZGF0YSB0YWJsZS4KCmBgYHtyIGFkZF9yZXBfaW5mb30KcV9wY3IgPC0gcV9wY3IgJT4lIAogIGdyb3VwX2J5KHNhbXBsZV9uYW1lLCB0YXJnZXRfTmFtZSkgJT4lCiAgbXV0YXRlKHJlcGxpY2F0ZSA9ICBjKCJyXzEiLCAicl8yIikpICU+JSAKICB1bmdyb3VwKCkKCmhlYWQocV9wY3IpCmBgYAoKCiMjIFBlcmZvcm1pbmcgYSBqb2luIG9wZXJhdGlvbgoKQXMgYSBmaXJzdCBhbmFseXNpcyBzdGVwLCB3ZSBtaWdodCB3YW50IHRvIGluZmVyIHRoZSBtZWFuIAphbmQgdGhlIHZhcmlhYmlsaXR5IG9mIHRoZSAqQ19UKiB2YWx1ZXMsIGluIG9yZGVyIHRvIGFzc2VzcyBib3RoIGdlbmUKZXhwcmVzc2lvbiBhbmQgcmVwcm9kdWNpYmlsaXR5LiBXZSBhc3Nlc3MgcmVwcm9kdWNpYmlsaXR5IGJ5IGEKc3ByZWFkIHZhbHVlLCB3aGljaCBpcyBzaW1wbHkgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIAoqQ19UKiB2YWx1ZXMgcGVyIGV4cGVyaW1lbnRhbCBzYW1wbGUuCgpgYGB7ciBzdW1fYWNyb3NzX3JlcHMsIGRlcGVuZHNvbj0iYWRkX3JlcF9pbmZvIn0Kc3VtbWFyeV9hY3Jvc3NfcmVwcyA8LSBncm91cF9ieShxX3BjciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlX25hbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldF9OYW1lKSAlPiUKICAgZHBseXI6OnN1bW1hcml6ZShtZWFuID0gbWVhbihDX1QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgc3ByZWFkID0gYWJzKGRpZmYoQ19UKSkpICU+JSAKICAgIHVuZ3JvdXAoKQoKaGVhZChzdW1tYXJ5X2Fjcm9zc19yZXBzLCA1KQpgYGAKCldlIG5vdyBtaWdodCB3YW50IHRvIGNvbWJpbmUgdGhpcyBpbmZvcm1hdGlvbiB0byB0aGUgb3JpZ2luYWwgZGF0YSB0YWJsZSwgdGhpcwpjYW4gYmUgZG9uZSB1c2UgdGhlIHZhcmlvdXMgam9pbiBmdW5jdGlvbnMgaW4gYHIgQ1JBTnBrZygiZHBseXIiKSBgLiBKb2luIG9wZXJhdGlvbnMKY29tYmluZSB0YWJsZXMgYmFzZWQgb24gY29tbW9uIGNvbHVtbnMuIEluIG91ciBjYXNlIGEgbGVmdCBqb2luIG9wZXJhdGlvbiBpcyB1c2VmdWwsIAp3aGljaCBpbmNsdWRlcyBhbGwgb2JzZXJ2YXRpb25zIGluIHlvdXIgcHJpbWFyeSB0YWJsZSwgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZXkgCm1hdGNoIG9yIG5vdC4gVGhpcyBpcyB0aGUgbW9zdCBjb21tb25seSB1c2VkIGpvaW4gYmVjYXVzZSBpdCBlbnN1cmVzIHRoYXQgeW91IApkb24ndCBsb29zZSBvYnNlcnZhdGlvbnMgZnJvbSB5b3VyIHByaW1hcnkgdGFibGUuIE1vcmUgaW5mb3JtYXRpb24gb24gdmFyaW91cwpqb2luIHR5cGVzIGNhbiBiZSBmb3VuZCBoZXJlOiA8aHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2RwbHlyL3ZpZ25ldHRlcy90d28tdGFibGUuaHRtbD4uCgpgYGB7ciBsZWZ0X2pvaW5fc3VtbSwgZGVwZW5kc29uPSJzdW1fYWNyb3NzX3JlcHMifQphdWdtZW50ZWRfdGFibGUgPC0gbGVmdF9qb2luKHFfcGNyLCBzdW1tYXJ5X2Fjcm9zc19yZXBzICkKaGVhZChhdWdtZW50ZWRfdGFibGUsIDUpCmBgYAoKYHIgQ1JBTnBrZygiZHBseXIiKSBgIHdpbGwgYXV0b21hdGljYWxseSB0cnkgdG8gaWRlbnRpZnkgbWF0Y2hpbmcgY29sdW1ucywgYW5kCnRlbGwgeW91IHdoaWNoIG9uZXMgaXQgaGFzIHVzZWQsICBidXQgeW91IGNhbiBhbHdheXMgc3BlY2lmeSB0aGVtIG1hbnVhbGx5IAp1c2luZyB0aGUgX19ieV9fIGFyZ3VtZW50LgoKIyMgQWx0ZXJuYXRpdmU6IGEgZ3JvdXBlZCBtdXRhdGUKCkluc3RlYWQgb2YgY3JlYXRpbmcgYSBzdW1tYXJ5IG9mIHRoZSBkYXRhIGFuZCB0aGVuIGpvaW5pbmcgdGhlIHN1bW1hcnkgdG8KdGhlIG9yaWdpbmFsIHRhYmxlLCB3ZSBjYW4gYWxzbyBkaXJlY3RseSB1c2UgdGhlIGBtdXRhdGVgIGZ1bmN0aW9uIG9uCmEgZ3JvdXBlZCBkYXRhIHNldDoKCmBgYHtyIGdyb3VwZWRfbXV0YXRlfQphdWdtZW50ZWRfdGFibGVfbXV0YXRlIDwtIGdyb3VwX2J5KHFfcGNyLCBzYW1wbGVfbmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0X05hbWUpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUobWVhbiA9IG1lYW4oQ19ULCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJlYWQgPSBhYnMoZGlmZihDX1QpKSkKCmhlYWQoYXVnbWVudGVkX3RhYmxlX211dGF0ZSwgNSkgCmBgYAoKCgojIyMgRXhlcmNpc2U6IEhpZ2ggcXVhbGl0eSBjZWxscwoKMS4gQXNzdW1lIGEgeW91IHdhbnQgdG8gcmV0YWluIG9ubHkgaGlnaCBxdWFsaXR5IGNlbGxzIGRlZmluZWQgYnkgYW4gCnBlcmNlbnRhZ2Ugb2YgZ3JlYXRlciB0aGFuIDYwJSBvZiB1bmlxdWVseSBhbmQgY29uY29yZGFudGx5IG1hcHBpbmcgCnJlYWQgcGFpcnMuIAoKV2hpY2ggcHJvcG9ydGlvbiBvZiBjZWxscyBhcmUgb2YgaGlnaCBxdWFsaXR5PyBVc2UgZmlsdGVyaW5nIAphbmQgdGhlIGZ1bmN0aW9uIGBjb3VudCgpYCB0byBhbnN3ZXIgdGhpcy4gTWFrZSBzdXJlIHRvIHVuZ3JvdXAgdGhlIApkYXRhIHNldCBiZWZvcmUgdXNpbmcgdGhlIGZ1bmN0aW9uIGBjb3VudCgpYCEKCgpgYGB7ciBleF9oaWdoX3F1YWwsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImhpZGUifQpocV9jZWxscyA8LSBtdXRhdGUoc2NfcWNfc3RhdHMsIGhpZ2hfcXVhbCA9IHBlcmNlbnQgPiA2MCkgJT4lCiAgICAgICAgICAgICAgICBmaWx0ZXIodHlwZSA9PSAiY29uY29yZGFudFVuaXEiKSAKCnByb3BfaGlnaF9xdWFsIDwtIGRwbHlyOjpjb3VudChocV9jZWxscywgaGlnaF9xdWFsKSAlPiUKICAgICAgICAgICAgICAgICAgICBhcnJhbmdlKGhpZ2hfcXVhbCkgJT4lCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHBlcmNfcXVhbCA9IG4gLyBzdW0obikpCgpgYGAKCjIuIENvbXB1dGUgdGhlIHByb3BvcnRpb24gb2YgaGlnaCBxdWFsaXR5IHBlciBiYXRjaC4KCgpgYGB7ciBleF9oaWdoX3F1YWxfYmF0Y2gsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImhpZGUifQoKZ3JvdXBfYnkoaHFfY2VsbHMsIGJhdGNoKSAlPiUKICAgICAgICBkcGx5cjo6Y291bnQoaGlnaF9xdWFsKSAlPiUKICAgICAgICBtdXRhdGUocGVyY19xdWFsID0gbiAvIHN1bShuKSkgICU+JQogICAgICAgIGZpbHRlcihoaWdoX3F1YWwgPT0gVFJVRSkgJT4lCiAgICAgICAgYXJyYW5nZShwZXJjX3F1YWwpCgpgYGAKCgojIFNlc3Npb24gSW5mbwoKYGBge3Igc2Vzc2lvbkluZm8sIGNhY2hlID0gRkFMU0V9CnNlc3Npb25JbmZvKCkKYGBgCgojIFJlZmVyZW5jZXMKCgoK</div>
No preview for this file type
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment