Skip to content

Instantly share code, notes, and snippets.

@rohanjoseph93
Created May 24, 2018 19:24
Show Gist options
  • Save rohanjoseph93/7d5f6f961f0d6e9ebf728889c072d129 to your computer and use it in GitHub Desktop.
Save rohanjoseph93/7d5f6f961f0d6e9ebf728889c072d129 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"#Import Libraries\n",
"#install.packages('tm')\n",
"library(tm)\n",
"#install.packages('wordcloud2')\n",
"library(wordcloud2)\n",
"library(IRdisplay)\n",
"\n",
"\n",
"#Set working directory\n",
"setwd(\"C:/Users/rohan/Documents/Analytics/Data\")"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"#Function to clean data and plot wordcloud\n",
"lyrics_word <- function(lyrics){\n",
" #join all the lines\n",
" lyrics <- paste(lyrics,collapse=\" \")\n",
" #convert the entire text to lower case\n",
" lyrics_lower <- tolower(lyrics)\n",
" #Extract the words and organize them into a list - using strsplit\n",
" #\\\\W is a 'regular expression' and matches any non-word character\n",
" lyrics_list <- strsplit(lyrics_lower,\"\\\\W\")\n",
" #Create a vector again instead of a list (We don't need a list in this problem)\n",
" lyrics_list <- unlist(lyrics_list)\n",
" #identify items which are not blank\n",
" not.blanks <-which(lyrics_list!=\"\")\n",
" #overwrite the data with the non-blank entries\n",
" lyrics_list <- lyrics_list[not.blanks]\n",
" #Remove stop words and words with one letter\n",
" lyrics_list <- lyrics_list[-which(lyrics_list %in% stopwords('en'))]\n",
" lyrics_list <- lyrics_list[-which(nchar(lyrics_list)==1)]\n",
" #How often does he use each of the words?\n",
" lyrics_freq <- table(lyrics_list)\n",
" a <- as.data.frame(sort(lyrics_freq, decreasing=TRUE))\n",
" #Plot it in a wordcloud\n",
" wordcloud2(a,color = \"random-dark\")\n",
" \n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<!DOCTYPE html>\r\n",
"<html>\r\n",
"<head>\r\n",
"<meta charset=\"utf-8\" />\r\n",
"<title>wordcloud2</title>\r\n",
"<script src=\"data:application/x-javascript;base64,KGZ1bmN0aW9uKCkgewogIC8vIElmIHdpbmRvdy5IVE1MV2lkZ2V0cyBpcyBhbHJlYWR5IGRlZmluZWQsIHRoZW4gdXNlIGl0OyBvdGhlcndpc2UgY3JlYXRlIGEKICAvLyBuZXcgb2JqZWN0LiBUaGlzIGFsbG93cyBwcmVjZWRpbmcgY29kZSB0byBzZXQgb3B0aW9ucyB0aGF0IGFmZmVjdCB0aGUKICAvLyBpbml0aWFsaXphdGlvbiBwcm9jZXNzICh0aG91Z2ggbm9uZSBjdXJyZW50bHkgZXhpc3QpLgogIHdpbmRvdy5IVE1MV2lkZ2V0cyA9IHdpbmRvdy5IVE1MV2lkZ2V0cyB8fCB7fTsKCiAgLy8gU2VlIGlmIHdlJ3JlIHJ1bm5pbmcgaW4gYSB2aWV3ZXIgcGFuZS4gSWYgbm90LCB3ZSdyZSBpbiBhIHdlYiBicm93c2VyLgogIHZhciB2aWV3ZXJNb2RlID0gd2luZG93LkhUTUxXaWRnZXRzLnZpZXdlck1vZGUgPQogICAgICAvXGJ2aWV3ZXJfcGFuZT0xXGIvLnRlc3Qod2luZG93LmxvY2F0aW9uKTsKCiAgLy8gU2VlIGlmIHdlJ3JlIHJ1bm5pbmcgaW4gU2hpbnkgbW9kZS4gSWYgbm90LCBpdCdzIGEgc3RhdGljIGRvY3VtZW50LgogIC8vIE5vdGUgdGhhdCBzdGF0aWMgd2lkZ2V0cyBjYW4gYXBwZWFyIGluIGJvdGggU2hpbnkgYW5kIHN0YXRpYyBtb2RlcywgYnV0CiAgLy8gb2J2aW91c2x5LCBTaGlueSB3aWRnZXRzIGNhbiBvbmx5IGFwcGVhciBpbiBTaGlueSBhcHBzL2RvY3VtZW50cy4KICB2YXIgc2hpbnlNb2RlID0gd2luZG93LkhUTUxXaWRnZXRzLnNoaW55TW9kZSA9CiAgICAgIHR5cGVvZih3aW5kb3cuU2hpbnkpICE9PSAidW5kZWZpbmVkIiAmJiAhIXdpbmRvdy5TaGlueS5vdXRwdXRCaW5kaW5nczsKCiAgLy8gV2UgY2FuJ3QgY291bnQgb24galF1ZXJ5IGJlaW5nIGF2YWlsYWJsZSwgc28gd2UgaW1wbGVtZW50IG91ciBvd24KICAvLyB2ZXJzaW9uIGlmIG5lY2Vzc2FyeS4KICBmdW5jdGlvbiBxdWVyeVNlbGVjdG9yQWxsKHNjb3BlLCBzZWxlY3RvcikgewogICAgaWYgKHR5cGVvZihqUXVlcnkpICE9PSAidW5kZWZpbmVkIiAmJiBzY29wZSBpbnN0YW5jZW9mIGpRdWVyeSkgewogICAgICByZXR1cm4gc2NvcGUuZmluZChzZWxlY3Rvcik7CiAgICB9CiAgICBpZiAoc2NvcGUucXVlcnlTZWxlY3RvckFsbCkgewogICAgICByZXR1cm4gc2NvcGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBhc0FycmF5KHZhbHVlKSB7CiAgICBpZiAodmFsdWUgPT09IG51bGwpCiAgICAgIHJldHVybiBbXTsKICAgIGlmICgkLmlzQXJyYXkodmFsdWUpKQogICAgICByZXR1cm4gdmFsdWU7CiAgICByZXR1cm4gW3ZhbHVlXTsKICB9CgogIC8vIEltcGxlbWVudCBqUXVlcnkncyBleHRlbmQKICBmdW5jdGlvbiBleHRlbmQodGFyZ2V0IC8qLCAuLi4gKi8pIHsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgcmV0dXJuIHRhcmdldDsKICAgIH0KICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07CiAgICAgIGZvciAodmFyIHByb3AgaW4gc291cmNlKSB7CiAgICAgICAgaWYgKHNvdXJjZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgewogICAgICAgICAgdGFyZ2V0W3Byb3BdID0gc291cmNlW3Byb3BdOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRhcmdldDsKICB9CgogIC8vIElFOCBkb2Vzbid0IHN1cHBvcnQgQXJyYXkuZm9yRWFjaC4KICBmdW5jdGlvbiBmb3JFYWNoKHZhbHVlcywgY2FsbGJhY2ssIHRoaXNBcmcpIHsKICAgIGlmICh2YWx1ZXMuZm9yRWFjaCkgewogICAgICB2YWx1ZXMuZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZyk7CiAgICB9IGVsc2UgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykgewogICAgICAgIGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdmFsdWVzW2ldLCBpLCB2YWx1ZXMpOwogICAgICB9CiAgICB9CiAgfQoKICAvLyBSZXBsYWNlcyB0aGUgc3BlY2lmaWVkIG1ldGhvZCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgZnVuY1NvdXJjZS4KICAvLwogIC8vIE5vdGUgdGhhdCBmdW5jU291cmNlIHNob3VsZCBub3QgQkUgdGhlIG5ldyBtZXRob2QsIGl0IHNob3VsZCBiZSBhIGZ1bmN0aW9uCiAgLy8gdGhhdCBSRVRVUk5TIHRoZSBuZXcgbWV0aG9kLiBmdW5jU291cmNlIHJlY2VpdmVzIGEgc2luZ2xlIGFyZ3VtZW50IHRoYXQgaXMKICAvLyB0aGUgb3ZlcnJpZGRlbiBtZXRob2QsIGl0IGNhbiBiZSBjYWxsZWQgZnJvbSB0aGUgbmV3IG1ldGhvZC4gVGhlIG92ZXJyaWRkZW4KICAvLyBtZXRob2QgY2FuIGJlIGNhbGxlZCBsaWtlIGEgcmVndWxhciBmdW5jdGlvbiwgaXQgaGFzIHRoZSB0YXJnZXQgcGVybWFuZW50bHkKICAvLyBib3VuZCB0byBpdCBzbyAidGhpcyIgd2lsbCB3b3JrIGNvcnJlY3RseS4KICBmdW5jdGlvbiBvdmVycmlkZU1ldGhvZCh0YXJnZXQsIG1ldGhvZE5hbWUsIGZ1bmNTb3VyY2UpIHsKICAgIHZhciBzdXBlckZ1bmMgPSB0YXJnZXRbbWV0aG9kTmFtZV0gfHwgZnVuY3Rpb24oKSB7fTsKICAgIHZhciBzdXBlckZ1bmNCb3VuZCA9IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gc3VwZXJGdW5jLmFwcGx5KHRhcmdldCwgYXJndW1lbnRzKTsKICAgIH07CiAgICB0YXJnZXRbbWV0aG9kTmFtZV0gPSBmdW5jU291cmNlKHN1cGVyRnVuY0JvdW5kKTsKICB9CgogIC8vIEFkZCBhIG1ldGhvZCB0byBkZWxlZ2F0b3IgdGhhdCwgd2hlbiBpbnZva2VkLCBjYWxscwogIC8vIGRlbGVnYXRlZS5tZXRob2ROYW1lLiBJZiB0aGVyZSBpcyBubyBzdWNoIG1ldGhvZCBvbgogIC8vIHRoZSBkZWxlZ2F0ZWUsIGJ1dCB0aGVyZSB3YXMgb25lIG9uIGRlbGVnYXRvciBiZWZvcmUKICAvLyBkZWxlZ2F0ZU1ldGhvZCB3YXMgY2FsbGVkLCB0aGVuIHRoZSBvcmlnaW5hbCB2ZXJzaW9uCiAgLy8gaXMgaW52b2tlZCBpbnN0ZWFkLgogIC8vIEZvciBleGFtcGxlOgogIC8vCiAgLy8gdmFyIGEgPSB7CiAgLy8gICBtZXRob2QxOiBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2ExJyk7IH0KICAvLyAgIG1ldGhvZDI6IGZ1bmN0aW9uKCkgeyBjb25zb2xlLmxvZygnYTInKTsgfQogIC8vIH07CiAgLy8gdmFyIGIgPSB7CiAgLy8gICBtZXRob2QxOiBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2IxJyk7IH0KICAvLyB9OwogIC8vIGRlbGVnYXRlTWV0aG9kKGEsIGIsICJtZXRob2QxIik7CiAgLy8gZGVsZWdhdGVNZXRob2QoYSwgYiwgIm1ldGhvZDIiKTsKICAvLyBhLm1ldGhvZDEoKTsKICAvLyBhLm1ldGhvZDIoKTsKICAvLwogIC8vIFRoZSBvdXRwdXQgd291bGQgYmUgImIxIiwgImEyIi4KICBmdW5jdGlvbiBkZWxlZ2F0ZU1ldGhvZChkZWxlZ2F0b3IsIGRlbGVnYXRlZSwgbWV0aG9kTmFtZSkgewogICAgdmFyIGluaGVyaXRlZCA9IGRlbGVnYXRvclttZXRob2ROYW1lXTsKICAgIGRlbGVnYXRvclttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKCkgewogICAgICB2YXIgdGFyZ2V0ID0gZGVsZWdhdGVlOwogICAgICB2YXIgbWV0aG9kID0gZGVsZWdhdGVlW21ldGhvZE5hbWVdOwoKICAgICAgLy8gVGhlIG1ldGhvZCBkb2Vzbid0IGV4aXN0IG9uIHRoZSBkZWxlZ2F0ZWUuIEluc3RlYWQsCiAgICAgIC8vIGNhbGwgdGhlIG1ldGhvZCBvbiB0aGUgZGVsZWdhdG9yLCBpZiBpdCBleGlzdHMuCiAgICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgdGFyZ2V0ID0gZGVsZWdhdG9yOwogICAgICAgIG1ldGhvZCA9IGluaGVyaXRlZDsKICAgICAgfQoKICAgICAgaWYgKG1ldGhvZCkgewogICAgICAgIHJldHVybiBtZXRob2QuYXBwbHkodGFyZ2V0LCBhcmd1bWVudHMpOwogICAgICB9CiAgICB9OwogIH0KCiAgLy8gSW1wbGVtZW50IGEgdmFndWUgZmFjc2ltaWxpZSBvZiBqUXVlcnkncyBkYXRhIG1ldGhvZAogIGZ1bmN0aW9uIGVsZW1lbnREYXRhKGVsLCBuYW1lLCB2YWx1ZSkgewogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMikgewogICAgICByZXR1cm4gZWxbImh0bWx3aWRnZXRfZGF0YV8iICsgbmFtZV07CiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMykgewogICAgICBlbFsiaHRtbHdpZGdldF9kYXRhXyIgKyBuYW1lXSA9IHZhbHVlOwogICAgICByZXR1cm4gZWw7CiAgICB9IGVsc2UgewogICAgICB0aHJvdyBuZXcgRXJyb3IoIldyb25nIG51bWJlciBvZiBhcmd1bWVudHMgZm9yIGVsZW1lbnREYXRhOiAiICsKICAgICAgICBhcmd1bWVudHMubGVuZ3RoKTsKICAgIH0KICB9CgogIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzQ0NjE3MC9lc2NhcGUtc3RyaW5nLWZvci11c2UtaW4tamF2YXNjcmlwdC1yZWdleAogIGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cChzdHIpIHsKICAgIHJldHVybiBzdHIucmVwbGFjZSgvW1wtXFtcXVwvXHtcfVwoXClcKlwrXD9cLlxcXF5cJFx8XS9nLCAiXFwkJiIpOwogIH0KCiAgZnVuY3Rpb24gaGFzQ2xhc3MoZWwsIGNsYXNzTmFtZSkgewogICAgdmFyIHJlID0gbmV3IFJlZ0V4cCgiXFxiIiArIGVzY2FwZVJlZ0V4cChjbGFzc05hbWUpICsgIlxcYiIpOwogICAgcmV0dXJuIHJlLnRlc3QoZWwuY2xhc3NOYW1lKTsKICB9CgogIC8vIGVsZW1lbnRzIC0gYXJyYXkgKG9yIGFycmF5LWxpa2Ugb2JqZWN0KSBvZiBIVE1MIGVsZW1lbnRzCiAgLy8gY2xhc3NOYW1lIC0gY2xhc3MgbmFtZSB0byB0ZXN0IGZvcgogIC8vIGluY2x1ZGUgLSBpZiB0cnVlLCBvbmx5IHJldHVybiBlbGVtZW50cyB3aXRoIGdpdmVuIGNsYXNzTmFtZTsKICAvLyAgIGlmIGZhbHNlLCBvbmx5IHJldHVybiBlbGVtZW50cyAqd2l0aG91dCogZ2l2ZW4gY2xhc3NOYW1lCiAgZnVuY3Rpb24gZmlsdGVyQnlDbGFzcyhlbGVtZW50cywgY2xhc3NOYW1lLCBpbmNsdWRlKSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykgewogICAgICBpZiAoaGFzQ2xhc3MoZWxlbWVudHNbaV0sIGNsYXNzTmFtZSkgPT0gaW5jbHVkZSkKICAgICAgICByZXN1bHRzLnB1c2goZWxlbWVudHNbaV0pOwogICAgfQogICAgcmV0dXJuIHJlc3VsdHM7CiAgfQoKICBmdW5jdGlvbiBvbihvYmosIGV2ZW50TmFtZSwgZnVuYykgewogICAgaWYgKG9iai5hZGRFdmVudExpc3RlbmVyKSB7CiAgICAgIG9iai5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZnVuYywgZmFsc2UpOwogICAgfSBlbHNlIGlmIChvYmouYXR0YWNoRXZlbnQpIHsKICAgICAgb2JqLmF0dGFjaEV2ZW50KGV2ZW50TmFtZSwgZnVuYyk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBvZmYob2JqLCBldmVudE5hbWUsIGZ1bmMpIHsKICAgIGlmIChvYmoucmVtb3ZlRXZlbnRMaXN0ZW5lcikKICAgICAgb2JqLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBmdW5jLCBmYWxzZSk7CiAgICBlbHNlIGlmIChvYmouZGV0YWNoRXZlbnQpIHsKICAgICAgb2JqLmRldGFjaEV2ZW50KGV2ZW50TmFtZSwgZnVuYyk7CiAgICB9CiAgfQoKICAvLyBUcmFuc2xhdGUgYXJyYXkgb2YgdmFsdWVzIHRvIHRvcC9yaWdodC9ib3R0b20vbGVmdCwgYXMgdXN1YWwgd2l0aAogIC8vIHRoZSAicGFkZGluZyIgQ1NTIHByb3BlcnR5CiAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL3BhZGRpbmcKICBmdW5jdGlvbiB1bnBhY2tQYWRkaW5nKHZhbHVlKSB7CiAgICBpZiAodHlwZW9mKHZhbHVlKSA9PT0gIm51bWJlciIpCiAgICAgIHZhbHVlID0gW3ZhbHVlXTsKICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDEpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMF0sIGJvdHRvbTogdmFsdWVbMF0sIGxlZnQ6IHZhbHVlWzBdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDIpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMF0sIGxlZnQ6IHZhbHVlWzFdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDMpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMl0sIGxlZnQ6IHZhbHVlWzFdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDQpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMl0sIGxlZnQ6IHZhbHVlWzNdfTsKICAgIH0KICB9CgogIC8vIENvbnZlcnQgYW4gdW5wYWNrZWQgcGFkZGluZyBvYmplY3QgdG8gYSBDU1MgdmFsdWUKICBmdW5jdGlvbiBwYWRkaW5nVG9Dc3MocGFkZGluZ09iaikgewogICAgcmV0dXJuIHBhZGRpbmdPYmoudG9wICsgInB4ICIgKyBwYWRkaW5nT2JqLnJpZ2h0ICsgInB4ICIgKyBwYWRkaW5nT2JqLmJvdHRvbSArICJweCAiICsgcGFkZGluZ09iai5sZWZ0ICsgInB4IjsKICB9CgogIC8vIE1ha2VzIGEgbnVtYmVyIHN1aXRhYmxlIGZvciBDU1MKICBmdW5jdGlvbiBweCh4KSB7CiAgICBpZiAodHlwZW9mKHgpID09PSAibnVtYmVyIikKICAgICAgcmV0dXJuIHggKyAicHgiOwogICAgZWxzZQogICAgICByZXR1cm4geDsKICB9CgogIC8vIFJldHJpZXZlcyBydW50aW1lIHdpZGdldCBzaXppbmcgaW5mb3JtYXRpb24gZm9yIGFuIGVsZW1lbnQuCiAgLy8gVGhlIHJldHVybiB2YWx1ZSBpcyBlaXRoZXIgbnVsbCwgb3IgYW4gb2JqZWN0IHdpdGggZmlsbCwgcGFkZGluZywKICAvLyBkZWZhdWx0V2lkdGgsIGRlZmF1bHRIZWlnaHQgZmllbGRzLgogIGZ1bmN0aW9uIHNpemluZ1BvbGljeShlbCkgewogICAgdmFyIHNpemluZ0VsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcigic2NyaXB0W2RhdGEtZm9yPSciICsgZWwuaWQgKyAiJ11bdHlwZT0nYXBwbGljYXRpb24vaHRtbHdpZGdldC1zaXppbmcnXSIpOwogICAgaWYgKCFzaXppbmdFbCkKICAgICAgcmV0dXJuIG51bGw7CiAgICB2YXIgc3AgPSBKU09OLnBhcnNlKHNpemluZ0VsLnRleHRDb250ZW50IHx8IHNpemluZ0VsLnRleHQgfHwgInt9Iik7CiAgICBpZiAodmlld2VyTW9kZSkgewogICAgICByZXR1cm4gc3Audmlld2VyOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIHNwLmJyb3dzZXI7CiAgICB9CiAgfQoKICAvLyBAcGFyYW0gdGFza3MgQXJyYXkgb2Ygc3RyaW5ncyAob3IgZmFsc3kgdmFsdWUsIGluIHdoaWNoIGNhc2Ugbm8tb3ApLgogIC8vICAgRWFjaCBlbGVtZW50IG11c3QgYmUgYSB2YWxpZCBKYXZhU2NyaXB0IGV4cHJlc3Npb24gdGhhdCB5aWVsZHMgYQogIC8vICAgZnVuY3Rpb24uIE9yLCBjYW4gYmUgYW4gYXJyYXkgb2Ygb2JqZWN0cyB3aXRoICJjb2RlIiBhbmQgImRhdGEiCiAgLy8gICBwcm9wZXJ0aWVzOyBpbiB0aGlzIGNhc2UsIHRoZSAiY29kZSIgcHJvcGVydHkgc2hvdWxkIGJlIGEgc3RyaW5nCiAgLy8gICBvZiBKUyB0aGF0J3MgYW4gZXhwciB0aGF0IHlpZWxkcyBhIGZ1bmN0aW9uLCBhbmQgImRhdGEiIHNob3VsZCBiZQogIC8vICAgYW4gb2JqZWN0IHRoYXQgd2lsbCBiZSBhZGRlZCBhcyBhbiBhZGRpdGlvbmFsIGFyZ3VtZW50IHdoZW4gdGhhdAogIC8vICAgZnVuY3Rpb24gaXMgY2FsbGVkLgogIC8vIEBwYXJhbSB0YXJnZXQgVGhlIG9iamVjdCB0aGF0IHdpbGwgYmUgInRoaXMiIGZvciBlYWNoIGZ1bmN0aW9uCiAgLy8gICBleGVjdXRpb24uCiAgLy8gQHBhcmFtIGFyZ3MgQXJyYXkgb2YgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb25zLiAoVGhlCiAgLy8gICBzYW1lIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBhbGwgZnVuY3Rpb25zLikKICBmdW5jdGlvbiBldmFsQW5kUnVuKHRhc2tzLCB0YXJnZXQsIGFyZ3MpIHsKICAgIGlmICh0YXNrcykgewogICAgICBmb3JFYWNoKHRhc2tzLCBmdW5jdGlvbih0YXNrKSB7CiAgICAgICAgdmFyIHRoZXNlQXJncyA9IGFyZ3M7CiAgICAgICAgaWYgKHR5cGVvZih0YXNrKSA9PT0gIm9iamVjdCIpIHsKICAgICAgICAgIHRoZXNlQXJncyA9IHRoZXNlQXJncy5jb25jYXQoW3Rhc2suZGF0YV0pOwogICAgICAgICAgdGFzayA9IHRhc2suY29kZTsKICAgICAgICB9CiAgICAgICAgdmFyIHRhc2tGdW5jID0gZXZhbCgiKCIgKyB0YXNrICsgIikiKTsKICAgICAgICBpZiAodHlwZW9mKHRhc2tGdW5jKSAhPT0gImZ1bmN0aW9uIikgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJUYXNrIG11c3QgYmUgYSBmdW5jdGlvbiEgU291cmNlOlxuIiArIHRhc2spOwogICAgICAgIH0KICAgICAgICB0YXNrRnVuYy5hcHBseSh0YXJnZXQsIHRoZXNlQXJncyk7CiAgICAgIH0pOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdFNpemluZyhlbCkgewogICAgdmFyIHNpemluZyA9IHNpemluZ1BvbGljeShlbCk7CiAgICBpZiAoIXNpemluZykKICAgICAgcmV0dXJuOwoKICAgIHZhciBjZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaHRtbHdpZGdldF9jb250YWluZXIiKTsKICAgIGlmICghY2VsKQogICAgICByZXR1cm47CgogICAgaWYgKHR5cGVvZihzaXppbmcucGFkZGluZykgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUubWFyZ2luID0gIjAiOwogICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmcgPSBwYWRkaW5nVG9Dc3ModW5wYWNrUGFkZGluZyhzaXppbmcucGFkZGluZykpOwogICAgfQoKICAgIGlmIChzaXppbmcuZmlsbCkgewogICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gImhpZGRlbiI7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuaGVpZ2h0ID0gIjEwMCUiOwogICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5oZWlnaHQgPSAiMTAwJSI7CiAgICAgIGlmIChjZWwpIHsKICAgICAgICBjZWwuc3R5bGUucG9zaXRpb24gPSAiYWJzb2x1dGUiOwogICAgICAgIHZhciBwYWQgPSB1bnBhY2tQYWRkaW5nKHNpemluZy5wYWRkaW5nKTsKICAgICAgICBjZWwuc3R5bGUudG9wID0gcGFkLnRvcCArICJweCI7CiAgICAgICAgY2VsLnN0eWxlLnJpZ2h0ID0gcGFkLnJpZ2h0ICsgInB4IjsKICAgICAgICBjZWwuc3R5bGUuYm90dG9tID0gcGFkLmJvdHRvbSArICJweCI7CiAgICAgICAgY2VsLnN0eWxlLmxlZnQgPSBwYWQubGVmdCArICJweCI7CiAgICAgICAgZWwuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gIjEwMCUiOwogICAgICB9CgogICAgICByZXR1cm4gewogICAgICAgIGdldFdpZHRoOiBmdW5jdGlvbigpIHsgcmV0dXJuIGNlbC5vZmZzZXRXaWR0aDsgfSwKICAgICAgICBnZXRIZWlnaHQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gY2VsLm9mZnNldEhlaWdodDsgfQogICAgICB9OwoKICAgIH0gZWxzZSB7CiAgICAgIGVsLnN0eWxlLndpZHRoID0gcHgoc2l6aW5nLndpZHRoKTsKICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gcHgoc2l6aW5nLmhlaWdodCk7CgogICAgICByZXR1cm4gewogICAgICAgIGdldFdpZHRoOiBmdW5jdGlvbigpIHsgcmV0dXJuIGVsLm9mZnNldFdpZHRoOyB9LAogICAgICAgIGdldEhlaWdodDogZnVuY3Rpb24oKSB7IHJldHVybiBlbC5vZmZzZXRIZWlnaHQ7IH0KICAgICAgfTsKICAgIH0KICB9CgogIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb25zIGZvciBtZXRob2RzCiAgdmFyIGRlZmF1bHRzID0gewogICAgZmluZDogZnVuY3Rpb24oc2NvcGUpIHsKICAgICAgcmV0dXJuIHF1ZXJ5U2VsZWN0b3JBbGwoc2NvcGUsICIuIiArIHRoaXMubmFtZSk7CiAgICB9LAogICAgcmVuZGVyRXJyb3I6IGZ1bmN0aW9uKGVsLCBlcnIpIHsKICAgICAgdmFyICRlbCA9ICQoZWwpOwoKICAgICAgdGhpcy5jbGVhckVycm9yKGVsKTsKCiAgICAgIC8vIEFkZCBhbGwgdGhlc2UgZXJyb3IgY2xhc3NlcywgYXMgU2hpbnkgZG9lcwogICAgICB2YXIgZXJyQ2xhc3MgPSAic2hpbnktb3V0cHV0LWVycm9yIjsKICAgICAgaWYgKGVyci50eXBlICE9PSBudWxsKSB7CiAgICAgICAgLy8gdXNlIHRoZSBjbGFzc2VzIG9mIHRoZSBlcnJvciBjb25kaXRpb24gYXMgQ1NTIGNsYXNzIG5hbWVzCiAgICAgICAgZXJyQ2xhc3MgPSBlcnJDbGFzcyArICIgIiArICQubWFwKGFzQXJyYXkoZXJyLnR5cGUpLCBmdW5jdGlvbih0eXBlKSB7CiAgICAgICAgICByZXR1cm4gZXJyQ2xhc3MgKyAiLSIgKyB0eXBlOwogICAgICAgIH0pLmpvaW4oIiAiKTsKICAgICAgfQogICAgICBlcnJDbGFzcyA9IGVyckNsYXNzICsgIiBodG1sd2lkZ2V0cy1lcnJvciI7CgogICAgICAvLyBJcyBlbCBpbmxpbmUgb3IgYmxvY2s/IElmIGlubGluZSBvciBpbmxpbmUtYmxvY2ssIGp1c3QgZGlzcGxheTpub25lIGl0CiAgICAgIC8vIGFuZCBhZGQgYW4gaW5saW5lIGVycm9yLgogICAgICB2YXIgZGlzcGxheSA9ICRlbC5jc3MoImRpc3BsYXkiKTsKICAgICAgJGVsLmRhdGEoInJlc3RvcmUtZGlzcGxheS1tb2RlIiwgZGlzcGxheSk7CgogICAgICBpZiAoZGlzcGxheSA9PT0gImlubGluZSIgfHwgZGlzcGxheSA9PT0gImlubGluZS1ibG9jayIpIHsKICAgICAgICAkZWwuaGlkZSgpOwogICAgICAgIGlmIChlcnIubWVzc2FnZSAhPT0gIiIpIHsKICAgICAgICAgIHZhciBlcnJvclNwYW4gPSAkKCI8c3Bhbj4iKS5hZGRDbGFzcyhlcnJDbGFzcyk7CiAgICAgICAgICBlcnJvclNwYW4udGV4dChlcnIubWVzc2FnZSk7CiAgICAgICAgICAkZWwuYWZ0ZXIoZXJyb3JTcGFuKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoZGlzcGxheSA9PT0gImJsb2NrIikgewogICAgICAgIC8vIElmIGJsb2NrLCBhZGQgYW4gZXJyb3IganVzdCBhZnRlciB0aGUgZWwsIHNldCB2aXNpYmlsaXR5Om5vbmUgb24gdGhlCiAgICAgICAgLy8gZWwsIGFuZCBwb3NpdGlvbiB0aGUgZXJyb3IgdG8gYmUgb24gdG9wIG9mIHRoZSBlbC4KICAgICAgICAvLyBNYXJrIGl0IHdpdGggYSB1bmlxdWUgSUQgYW5kIENTUyBjbGFzcyBzbyB3ZSBjYW4gcmVtb3ZlIGl0IGxhdGVyLgogICAgICAgICRlbC5jc3MoInZpc2liaWxpdHkiLCAiaGlkZGVuIik7CiAgICAgICAgaWYgKGVyci5tZXNzYWdlICE9PSAiIikgewogICAgICAgICAgdmFyIGVycm9yRGl2ID0gJCgiPGRpdj4iKS5hZGRDbGFzcyhlcnJDbGFzcykuY3NzKCJwb3NpdGlvbiIsICJhYnNvbHV0ZSIpCiAgICAgICAgICAgIC5jc3MoInRvcCIsIGVsLm9mZnNldFRvcCkKICAgICAgICAgICAgLmNzcygibGVmdCIsIGVsLm9mZnNldExlZnQpCiAgICAgICAgICAgIC8vIHNldHRpbmcgd2lkdGggY2FuIHB1c2ggb3V0IHRoZSBwYWdlIHNpemUsIGZvcmNpbmcgb3RoZXJ3aXNlCiAgICAgICAgICAgIC8vIHVubmVjZXNzYXJ5IHNjcm9sbGJhcnMgdG8gYXBwZWFyIGFuZCBtYWtpbmcgaXQgaW1wb3NzaWJsZSBmb3IKICAgICAgICAgICAgLy8gdGhlIGVsZW1lbnQgdG8gc2hyaW5rOyBzbyB1c2UgbWF4LXdpZHRoIGluc3RlYWQKICAgICAgICAgICAgLmNzcygibWF4V2lkdGgiLCBlbC5vZmZzZXRXaWR0aCkKICAgICAgICAgICAgLmNzcygiaGVpZ2h0IiwgZWwub2Zmc2V0SGVpZ2h0KTsKICAgICAgICAgIGVycm9yRGl2LnRleHQoZXJyLm1lc3NhZ2UpOwogICAgICAgICAgJGVsLmFmdGVyKGVycm9yRGl2KTsKCiAgICAgICAgICAvLyBSZWFsbHkgZHVtYiB3YXkgdG8ga2VlcCB0aGUgc2l6ZS9wb3NpdGlvbiBvZiB0aGUgZXJyb3IgaW4gc3luYyB3aXRoCiAgICAgICAgICAvLyB0aGUgcGFyZW50IGVsZW1lbnQgYXMgdGhlIHdpbmRvdyBpcyByZXNpemVkIG9yIHdoYXRldmVyLgogICAgICAgICAgdmFyIGludElkID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICghZXJyb3JEaXZbMF0ucGFyZW50RWxlbWVudCkgewogICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50SWQpOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlcnJvckRpdgogICAgICAgICAgICAgIC5jc3MoInRvcCIsIGVsLm9mZnNldFRvcCkKICAgICAgICAgICAgICAuY3NzKCJsZWZ0IiwgZWwub2Zmc2V0TGVmdCkKICAgICAgICAgICAgICAuY3NzKCJtYXhXaWR0aCIsIGVsLm9mZnNldFdpZHRoKQogICAgICAgICAgICAgIC5jc3MoImhlaWdodCIsIGVsLm9mZnNldEhlaWdodCk7CiAgICAgICAgICB9LCA1MDApOwogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgIGNsZWFyRXJyb3I6IGZ1bmN0aW9uKGVsKSB7CiAgICAgIHZhciAkZWwgPSAkKGVsKTsKICAgICAgdmFyIGRpc3BsYXkgPSAkZWwuZGF0YSgicmVzdG9yZS1kaXNwbGF5LW1vZGUiKTsKICAgICAgJGVsLmRhdGEoInJlc3RvcmUtZGlzcGxheS1tb2RlIiwgbnVsbCk7CgogICAgICBpZiAoZGlzcGxheSA9PT0gImlubGluZSIgfHwgZGlzcGxheSA9PT0gImlubGluZS1ibG9jayIpIHsKICAgICAgICBpZiAoZGlzcGxheSkKICAgICAgICAgICRlbC5jc3MoImRpc3BsYXkiLCBkaXNwbGF5KTsKICAgICAgICAkKGVsLm5leHRTaWJsaW5nKS5maWx0ZXIoIi5odG1sd2lkZ2V0cy1lcnJvciIpLnJlbW92ZSgpOwogICAgICB9IGVsc2UgaWYgKGRpc3BsYXkgPT09ICJibG9jayIpewogICAgICAgICRlbC5jc3MoInZpc2liaWxpdHkiLCAiaW5oZXJpdCIpOwogICAgICAgICQoZWwubmV4dFNpYmxpbmcpLmZpbHRlcigiLmh0bWx3aWRnZXRzLWVycm9yIikucmVtb3ZlKCk7CiAgICAgIH0KICAgIH0sCiAgICBzaXppbmc6IHt9CiAgfTsKCiAgLy8gQ2FsbGVkIGJ5IHdpZGdldCBiaW5kaW5ncyB0byByZWdpc3RlciBhIG5ldyB0eXBlIG9mIHdpZGdldC4gVGhlIGRlZmluaXRpb24KICAvLyBvYmplY3QgY2FuIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgogIC8vIC0gbmFtZSAocmVxdWlyZWQpIC0gQSBzdHJpbmcgaW5kaWNhdGluZyB0aGUgYmluZGluZyBuYW1lLCB3aGljaCB3aWxsIGJlCiAgLy8gICB1c2VkIGJ5IGRlZmF1bHQgYXMgdGhlIENTUyBjbGFzc25hbWUgdG8gbG9vayBmb3IuCiAgLy8gLSBpbml0aWFsaXplIChvcHRpb25hbCkgLSBBIGZ1bmN0aW9uKGVsKSB0aGF0IHdpbGwgYmUgY2FsbGVkIG9uY2UgcGVyCiAgLy8gICB3aWRnZXQgZWxlbWVudDsgaWYgYSB2YWx1ZSBpcyByZXR1cm5lZCwgaXQgd2lsbCBiZSBwYXNzZWQgYXMgdGhlIHRoaXJkCiAgLy8gICB2YWx1ZSB0byByZW5kZXJWYWx1ZS4KICAvLyAtIHJlbmRlclZhbHVlIChyZXF1aXJlZCkgLSBBIGZ1bmN0aW9uKGVsLCBkYXRhLCBpbml0VmFsdWUpIHRoYXQgd2lsbCBiZQogIC8vICAgY2FsbGVkIHdpdGggZGF0YS4gU3RhdGljIGNvbnRleHRzIHdpbGwgY2F1c2UgdGhpcyB0byBiZSBjYWxsZWQgb25jZSBwZXIKICAvLyAgIGVsZW1lbnQ7IFNoaW55IGFwcHMgd2lsbCBjYXVzZSB0aGlzIHRvIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyBwZXIKICAvLyAgIGVsZW1lbnQsIGFzIHRoZSBkYXRhIGNoYW5nZXMuCiAgd2luZG93LkhUTUxXaWRnZXRzLndpZGdldCA9IGZ1bmN0aW9uKGRlZmluaXRpb24pIHsKICAgIGlmICghZGVmaW5pdGlvbi5uYW1lKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIG5hbWUiKTsKICAgIH0KICAgIGlmICghZGVmaW5pdGlvbi50eXBlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIHR5cGUiKTsKICAgIH0KICAgIC8vIEN1cnJlbnRseSB3ZSBvbmx5IHN1cHBvcnQgb3V0cHV0IHdpZGdldHMKICAgIGlmIChkZWZpbml0aW9uLnR5cGUgIT09ICJvdXRwdXQiKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiVW5yZWNvZ25pemVkIHdpZGdldCB0eXBlICciICsgZGVmaW5pdGlvbi50eXBlICsgIiciKTsKICAgIH0KICAgIC8vIFRPRE86IFZlcmlmeSB0aGF0IC5uYW1lIGlzIGEgdmFsaWQgQ1NTIGNsYXNzbmFtZQoKICAgIC8vIFN1cHBvcnQgbmV3LXN0eWxlIGluc3RhbmNlLWJvdW5kIGRlZmluaXRpb25zLiBPbGQtc3R5bGUgY2xhc3MtYm91bmQKICAgIC8vIGRlZmluaXRpb25zIGhhdmUgb25lIHdpZGdldCAib2JqZWN0IiBwZXIgd2lkZ2V0IHBlciB0eXBlL2NsYXNzIG9mCiAgICAvLyB3aWRnZXQ7IHRoZSByZW5kZXJWYWx1ZSBhbmQgcmVzaXplIG1ldGhvZHMgb24gc3VjaCB3aWRnZXQgb2JqZWN0cwogICAgLy8gdGFrZSBlbCBhbmQgaW5zdGFuY2UgYXJndW1lbnRzLCBiZWNhdXNlIHRoZSB3aWRnZXQgb2JqZWN0IGNhbid0CiAgICAvLyBzdG9yZSB0aGVtLiBOZXctc3R5bGUgaW5zdGFuY2UtYm91bmQgZGVmaW5pdGlvbnMgaGF2ZSBvbmUgd2lkZ2V0CiAgICAvLyBvYmplY3QgcGVyIHdpZGdldCBpbnN0YW5jZTsgdGhlIGRlZmluaXRpb24gdGhhdCdzIHBhc3NlZCBpbiBkb2Vzbid0CiAgICAvLyBwcm92aWRlIHJlbmRlclZhbHVlIG9yIHJlc2l6ZSBtZXRob2RzIGF0IGFsbCwganVzdCB0aGUgc2luZ2xlIG1ldGhvZAogICAgLy8gICBmYWN0b3J5KGVsLCB3aWR0aCwgaGVpZ2h0KQogICAgLy8gd2hpY2ggcmV0dXJucyBhbiBvYmplY3QgdGhhdCBoYXMgcmVuZGVyVmFsdWUoeCkgYW5kIHJlc2l6ZSh3LCBoKS4KICAgIC8vIFRoaXMgZW5hYmxlcyBhIGZhciBtb3JlIG5hdHVyYWwgcHJvZ3JhbW1pbmcgc3R5bGUgZm9yIHRoZSB3aWRnZXQKICAgIC8vIGF1dGhvciwgd2hvIGNhbiBzdG9yZSBwZXItaW5zdGFuY2Ugc3RhdGUgdXNpbmcgZWl0aGVyIE9PLXN0eWxlCiAgICAvLyBpbnN0YW5jZSBmaWVsZHMgb3IgZnVuY3Rpb25hbC1zdHlsZSBjbG9zdXJlIHZhcmlhYmxlcyAoSSBndWVzcyB0aGlzCiAgICAvLyBpcyBpbiBjb250cmFzdCB0byB3aGF0IGNhbiBvbmx5IGJlIGNhbGxlZCBDLXN0eWxlIHBzZXVkby1PTyB3aGljaCBpcwogICAgLy8gd2hhdCB3ZSByZXF1aXJlZCBiZWZvcmUpLgogICAgaWYgKGRlZmluaXRpb24uZmFjdG9yeSkgewogICAgICBkZWZpbml0aW9uID0gY3JlYXRlTGVnYWN5RGVmaW5pdGlvbkFkYXB0ZXIoZGVmaW5pdGlvbik7CiAgICB9CgogICAgaWYgKCFkZWZpbml0aW9uLnJlbmRlclZhbHVlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIHJlbmRlclZhbHVlIGZ1bmN0aW9uIik7CiAgICB9CgogICAgLy8gRm9yIHN0YXRpYyByZW5kZXJpbmcgKG5vbi1TaGlueSksIHVzZSBhIHNpbXBsZSB3aWRnZXQgcmVnaXN0cmF0aW9uCiAgICAvLyBzY2hlbWUuIFdlIGFsc28gdXNlIHRoaXMgc2NoZW1lIGZvciBTaGlueSBhcHBzL2RvY3VtZW50cyB0aGF0IGFsc28KICAgIC8vIGNvbnRhaW4gc3RhdGljIHdpZGdldHMuCiAgICB3aW5kb3cuSFRNTFdpZGdldHMud2lkZ2V0cyA9IHdpbmRvdy5IVE1MV2lkZ2V0cy53aWRnZXRzIHx8IFtdOwogICAgLy8gTWVyZ2UgZGVmYXVsdHMgaW50byB0aGUgZGVmaW5pdGlvbjsgZG9uJ3QgbXV0YXRlIHRoZSBvcmlnaW5hbCBkZWZpbml0aW9uLgogICAgdmFyIHN0YXRpY0JpbmRpbmcgPSBleHRlbmQoe30sIGRlZmF1bHRzLCBkZWZpbml0aW9uKTsKICAgIG92ZXJyaWRlTWV0aG9kKHN0YXRpY0JpbmRpbmcsICJmaW5kIiwgZnVuY3Rpb24oc3VwZXJmdW5jKSB7CiAgICAgIHJldHVybiBmdW5jdGlvbihzY29wZSkgewogICAgICAgIHZhciByZXN1bHRzID0gc3VwZXJmdW5jKHNjb3BlKTsKICAgICAgICAvLyBGaWx0ZXIgb3V0IFNoaW55IG91dHB1dHMsIHdlIG9ubHkgd2FudCB0aGUgc3RhdGljIGtpbmQKICAgICAgICByZXR1cm4gZmlsdGVyQnlDbGFzcyhyZXN1bHRzLCAiaHRtbC13aWRnZXQtb3V0cHV0IiwgZmFsc2UpOwogICAgICB9OwogICAgfSk7CiAgICB3aW5kb3cuSFRNTFdpZGdldHMud2lkZ2V0cy5wdXNoKHN0YXRpY0JpbmRpbmcpOwoKICAgIGlmIChzaGlueU1vZGUpIHsKICAgICAgLy8gU2hpbnkgaXMgcnVubmluZy4gUmVnaXN0ZXIgdGhlIGRlZmluaXRpb24gd2l0aCBhbiBvdXRwdXQgYmluZGluZy4KICAgICAgLy8gVGhlIGRlZmluaXRpb24gaXRzZWxmIHdpbGwgbm90IGJlIHRoZSBvdXRwdXQgYmluZGluZywgaW5zdGVhZAogICAgICAvLyB3ZSB3aWxsIG1ha2UgYW4gb3V0cHV0IGJpbmRpbmcgb2JqZWN0IHRoYXQgZGVsZWdhdGVzIHRvIHRoZQogICAgICAvLyBkZWZpbml0aW9uLiBUaGlzIGlzIGJlY2F1c2Ugd2UgZm9vbGlzaGx5IHVzZWQgdGhlIHNhbWUgbWV0aG9kCiAgICAgIC8vIG5hbWUgKHJlbmRlclZhbHVlKSBmb3IgaHRtbHdpZGdldHMgZGVmaW5pdGlvbiBhbmQgU2hpbnkgYmluZGluZ3MKICAgICAgLy8gYnV0IHRoZXkgYWN0dWFsbHkgaGF2ZSBxdWl0ZSBkaWZmZXJlbnQgc2VtYW50aWNzICh0aGUgU2hpbnkKICAgICAgLy8gYmluZGluZ3MgcmVjZWl2ZSBkYXRhIHRoYXQgaW5jbHVkZXMgbG90cyBvZiBtZXRhZGF0YSB0aGF0IGl0CiAgICAgIC8vIHN0cmlwcyBvZmYgYmVmb3JlIGNhbGxpbmcgaHRtbHdpZGdldHMgcmVuZGVyVmFsdWUpLiBXZSBjYW4ndAogICAgICAvLyBqdXN0IGlnbm9yZSB0aGUgZGlmZmVyZW5jZSBiZWNhdXNlIGluIHNvbWUgd2lkZ2V0cyBpdCdzIGhlbHBmdWwKICAgICAgLy8gdG8gY2FsbCB0aGlzLnJlbmRlclZhbHVlKCkgZnJvbSBpbnNpZGUgb2YgcmVzaXplKCksIGFuZCBpZgogICAgICAvLyB3ZSdyZSBub3QgZGVsZWdhdGluZywgdGhlbiB0aGF0IGNhbGwgd2lsbCBnbyB0byB0aGUgU2hpbnkKICAgICAgLy8gdmVyc2lvbiBpbnN0ZWFkIG9mIHRoZSBodG1sd2lkZ2V0cyB2ZXJzaW9uLgoKICAgICAgLy8gTWVyZ2UgZGVmYXVsdHMgd2l0aCBkZWZpbml0aW9uLCB3aXRob3V0IG11dGF0aW5nIGVpdGhlci4KICAgICAgdmFyIGJpbmRpbmdEZWYgPSBleHRlbmQoe30sIGRlZmF1bHRzLCBkZWZpbml0aW9uKTsKCiAgICAgIC8vIFRoaXMgb2JqZWN0IHdpbGwgYmUgb3VyIGFjdHVhbCBTaGlueSBiaW5kaW5nLgogICAgICB2YXIgc2hpbnlCaW5kaW5nID0gbmV3IFNoaW55Lk91dHB1dEJpbmRpbmcoKTsKCiAgICAgIC8vIFdpdGggYSBmZXcgZXhjZXB0aW9ucywgd2UnbGwgd2FudCB0byBzaW1wbHkgdXNlIHRoZSBiaW5kaW5nRGVmJ3MKICAgICAgLy8gdmVyc2lvbiBvZiBtZXRob2RzIGlmIHRoZXkgYXJlIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGZhbGwgYmFjayB0bwogICAgICAvLyBTaGlueSdzIGRlZmF1bHRzLiBOT1RFOiBJZiBTaGlueSdzIG91dHB1dCBiaW5kaW5ncyBnYWluIGFkZGl0aW9uYWwKICAgICAgLy8gbWV0aG9kcyBpbiB0aGUgZnV0dXJlLCBhbmQgd2Ugd2FudCB0aGVtIHRvIGJlIG92ZXJyaWRlYWJsZSBieQogICAgICAvLyBIVE1MV2lkZ2V0IGJpbmRpbmcgZGVmaW5pdGlvbnMsIHRoZW4gd2UnbGwgbmVlZCB0byBhZGQgdGhlbSB0byB0aGlzCiAgICAgIC8vIGxpc3QuCiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgImdldElkIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgIm9uVmFsdWVDaGFuZ2UiKTsKICAgICAgZGVsZWdhdGVNZXRob2Qoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLCAib25WYWx1ZUVycm9yIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgInJlbmRlckVycm9yIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgImNsZWFyRXJyb3IiKTsKICAgICAgZGVsZWdhdGVNZXRob2Qoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLCAic2hvd1Byb2dyZXNzIik7CgogICAgICAvLyBUaGUgZmluZCwgcmVuZGVyVmFsdWUsIGFuZCByZXNpemUgYXJlIGhhbmRsZWQgZGlmZmVyZW50bHksIGJlY2F1c2Ugd2UKICAgICAgLy8gd2FudCB0byBhY3R1YWxseSBkZWNvcmF0ZSB0aGUgYmVoYXZpb3Igb2YgdGhlIGJpbmRpbmdEZWYgbWV0aG9kcy4KCiAgICAgIHNoaW55QmluZGluZy5maW5kID0gZnVuY3Rpb24oc2NvcGUpIHsKICAgICAgICB2YXIgcmVzdWx0cyA9IGJpbmRpbmdEZWYuZmluZChzY29wZSk7CgogICAgICAgIC8vIE9ubHkgcmV0dXJuIGVsZW1lbnRzIHRoYXQgYXJlIFNoaW55IG91dHB1dHMsIG5vdCBzdGF0aWMgb25lcwogICAgICAgIHZhciBkeW5hbWljUmVzdWx0cyA9IHJlc3VsdHMuZmlsdGVyKCIuaHRtbC13aWRnZXQtb3V0cHV0Iik7CgogICAgICAgIC8vIEl0J3MgcG9zc2libGUgdGhhdCB3aGF0ZXZlciBjYXVzZWQgU2hpbnkgdG8gdGhpbmsgdGhlcmUgbWlnaHQgYmUKICAgICAgICAvLyBuZXcgZHluYW1pYyBvdXRwdXRzLCBhbHNvIGNhdXNlZCB0aGVyZSB0byBiZSBuZXcgc3RhdGljIG91dHB1dHMuCiAgICAgICAgLy8gU2luY2UgdGhlcmUgbWlnaHQgYmUgbG90cyBvZiBkaWZmZXJlbnQgaHRtbHdpZGdldHMgYmluZGluZ3MsIHdlCiAgICAgICAgLy8gc2NoZWR1bGUgZXhlY3V0aW9uIGZvciBsYXRlci0tbm8gbmVlZCB0byBzdGF0aWNSZW5kZXIgbXVsdGlwbGUKICAgICAgICAvLyB0aW1lcy4KICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IGR5bmFtaWNSZXN1bHRzLmxlbmd0aCkKICAgICAgICAgIHNjaGVkdWxlU3RhdGljUmVuZGVyKCk7CgogICAgICAgIHJldHVybiBkeW5hbWljUmVzdWx0czsKICAgICAgfTsKCiAgICAgIC8vIFdyYXAgcmVuZGVyVmFsdWUgdG8gaGFuZGxlIGluaXRpYWxpemF0aW9uLCB3aGljaCB1bmZvcnR1bmF0ZWx5IGlzbid0CiAgICAgIC8vIHN1cHBvcnRlZCBuYXRpdmVseSBieSBTaGlueSBhdCB0aGUgdGltZSBvZiB0aGlzIHdyaXRpbmcuCgogICAgICBzaGlueUJpbmRpbmcucmVuZGVyVmFsdWUgPSBmdW5jdGlvbihlbCwgZGF0YSkgewogICAgICAgIFNoaW55LnJlbmRlckRlcGVuZGVuY2llcyhkYXRhLmRlcHMpOwogICAgICAgIC8vIFJlc29sdmUgc3RyaW5ncyBtYXJrZWQgYXMgamF2YXNjcmlwdCBsaXRlcmFscyB0byBvYmplY3RzCiAgICAgICAgaWYgKCEoZGF0YS5ldmFscyBpbnN0YW5jZW9mIEFycmF5KSkgZGF0YS5ldmFscyA9IFtkYXRhLmV2YWxzXTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgZGF0YS5ldmFscyAmJiBpIDwgZGF0YS5ldmFscy5sZW5ndGg7IGkrKykgewogICAgICAgICAgd2luZG93LkhUTUxXaWRnZXRzLmV2YWx1YXRlU3RyaW5nTWVtYmVyKGRhdGEueCwgZGF0YS5ldmFsc1tpXSk7CiAgICAgICAgfQogICAgICAgIGlmICghYmluZGluZ0RlZi5yZW5kZXJPbk51bGxWYWx1ZSkgewogICAgICAgICAgaWYgKGRhdGEueCA9PT0gbnVsbCkgewogICAgICAgICAgICBlbC5zdHlsZS52aXNpYmlsaXR5ID0gImhpZGRlbiI7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVsLnN0eWxlLnZpc2liaWxpdHkgPSAiaW5oZXJpdCI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghZWxlbWVudERhdGEoZWwsICJpbml0aWFsaXplZCIpKSB7CiAgICAgICAgICBpbml0U2l6aW5nKGVsKTsKCiAgICAgICAgICBlbGVtZW50RGF0YShlbCwgImluaXRpYWxpemVkIiwgdHJ1ZSk7CiAgICAgICAgICBpZiAoYmluZGluZ0RlZi5pbml0aWFsaXplKSB7CiAgICAgICAgICAgIHZhciByZXN1bHQgPSBiaW5kaW5nRGVmLmluaXRpYWxpemUoZWwsIGVsLm9mZnNldFdpZHRoLAogICAgICAgICAgICAgIGVsLm9mZnNldEhlaWdodCk7CiAgICAgICAgICAgIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiLCByZXN1bHQpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBiaW5kaW5nRGVmLnJlbmRlclZhbHVlKGVsLCBkYXRhLngsIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiKSk7CiAgICAgICAgZXZhbEFuZFJ1bihkYXRhLmpzSG9va3MucmVuZGVyLCBlbGVtZW50RGF0YShlbCwgImluaXRfcmVzdWx0IiksIFtlbCwgZGF0YS54XSk7CiAgICAgIH07CgogICAgICAvLyBPbmx5IG92ZXJyaWRlIHJlc2l6ZSBpZiBiaW5kaW5nRGVmIGltcGxlbWVudHMgaXQKICAgICAgaWYgKGJpbmRpbmdEZWYucmVzaXplKSB7CiAgICAgICAgc2hpbnlCaW5kaW5nLnJlc2l6ZSA9IGZ1bmN0aW9uKGVsLCB3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgICAvLyBTaGlueSBjYW4gY2FsbCByZXNpemUgYmVmb3JlIGluaXRpYWxpemUvcmVuZGVyVmFsdWUgaGF2ZSBiZWVuCiAgICAgICAgICAvLyBjYWxsZWQsIHdoaWNoIGRvZXNuJ3QgbWFrZSBzZW5zZSBmb3Igd2lkZ2V0cy4KICAgICAgICAgIGlmIChlbGVtZW50RGF0YShlbCwgImluaXRpYWxpemVkIikpIHsKICAgICAgICAgICAgYmluZGluZ0RlZi5yZXNpemUoZWwsIHdpZHRoLCBoZWlnaHQsIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiKSk7CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgfQoKICAgICAgU2hpbnkub3V0cHV0QmluZGluZ3MucmVnaXN0ZXIoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLm5hbWUpOwogICAgfQogIH07CgogIHZhciBzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQgPSBudWxsOwogIGZ1bmN0aW9uIHNjaGVkdWxlU3RhdGljUmVuZGVyKCkgewogICAgaWYgKCFzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQpIHsKICAgICAgc2NoZWR1bGVTdGF0aWNSZW5kZXJUaW1lcklkID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICBzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQgPSBudWxsOwogICAgICAgIHdpbmRvdy5IVE1MV2lkZ2V0cy5zdGF0aWNSZW5kZXIoKTsKICAgICAgfSwgMSk7CiAgICB9CiAgfQoKICAvLyBSZW5kZXIgc3RhdGljIHdpZGdldHMgYWZ0ZXIgdGhlIGRvY3VtZW50IGZpbmlzaGVzIGxvYWRpbmcKICAvLyBTdGF0aWNhbGx5IHJlbmRlciBhbGwgZWxlbWVudHMgdGhhdCBhcmUgb2YgdGhpcyB3aWRnZXQncyBjbGFzcwogIHdpbmRvdy5IVE1MV2lkZ2V0cy5zdGF0aWNSZW5kZXIgPSBmdW5jdGlvbigpIHsKICAgIHZhciBiaW5kaW5ncyA9IHdpbmRvdy5IVE1MV2lkZ2V0cy53aWRnZXRzIHx8IFtdOwogICAgZm9yRWFjaChiaW5kaW5ncywgZnVuY3Rpb24oYmluZGluZykgewogICAgICB2YXIgbWF0Y2hlcyA9IGJpbmRpbmcuZmluZChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpOwogICAgICBmb3JFYWNoKG1hdGNoZXMsIGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgdmFyIHNpemVPYmogPSBpbml0U2l6aW5nKGVsLCBiaW5kaW5nKTsKCiAgICAgICAgaWYgKGhhc0NsYXNzKGVsLCAiaHRtbC13aWRnZXQtc3RhdGljLWJvdW5kIikpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgZWwuY2xhc3NOYW1lID0gZWwuY2xhc3NOYW1lICsgIiBodG1sLXdpZGdldC1zdGF0aWMtYm91bmQiOwoKICAgICAgICB2YXIgaW5pdFJlc3VsdDsKICAgICAgICBpZiAoYmluZGluZy5pbml0aWFsaXplKSB7CiAgICAgICAgICBpbml0UmVzdWx0ID0gYmluZGluZy5pbml0aWFsaXplKGVsLAogICAgICAgICAgICBzaXplT2JqID8gc2l6ZU9iai5nZXRXaWR0aCgpIDogZWwub2Zmc2V0V2lkdGgsCiAgICAgICAgICAgIHNpemVPYmogPyBzaXplT2JqLmdldEhlaWdodCgpIDogZWwub2Zmc2V0SGVpZ2h0CiAgICAgICAgICApOwogICAgICAgICAgZWxlbWVudERhdGEoZWwsICJpbml0X3Jlc3VsdCIsIGluaXRSZXN1bHQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGJpbmRpbmcucmVzaXplKSB7CiAgICAgICAgICB2YXIgbGFzdFNpemUgPSB7fTsKICAgICAgICAgIHZhciByZXNpemVIYW5kbGVyID0gZnVuY3Rpb24oZSkgewogICAgICAgICAgICB2YXIgc2l6ZSA9IHsKICAgICAgICAgICAgICB3OiBzaXplT2JqID8gc2l6ZU9iai5nZXRXaWR0aCgpIDogZWwub2Zmc2V0V2lkdGgsCiAgICAgICAgICAgICAgaDogc2l6ZU9iaiA/IHNpemVPYmouZ2V0SGVpZ2h0KCkgOiBlbC5vZmZzZXRIZWlnaHQKICAgICAgICAgICAgfTsKICAgICAgICAgICAgaWYgKHNpemUudyA9PT0gMCAmJiBzaXplLmggPT09IDApCiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBpZiAoc2l6ZS53ID09PSBsYXN0U2l6ZS53ICYmIHNpemUuaCA9PT0gbGFzdFNpemUuaCkKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIGxhc3RTaXplID0gc2l6ZTsKICAgICAgICAgICAgYmluZGluZy5yZXNpemUoZWwsIHNpemUudywgc2l6ZS5oLCBpbml0UmVzdWx0KTsKICAgICAgICAgIH07CgogICAgICAgICAgb24od2luZG93LCAicmVzaXplIiwgcmVzaXplSGFuZGxlcik7CgogICAgICAgICAgLy8gVGhpcyBpcyBuZWVkZWQgZm9yIGNhc2VzIHdoZXJlIHdlJ3JlIHJ1bm5pbmcgaW4gYSBTaGlueQogICAgICAgICAgLy8gYXBwLCBidXQgdGhlIHdpZGdldCBpdHNlbGYgaXMgbm90IGEgU2hpbnkgb3V0cHV0LCBidXQKICAgICAgICAgIC8vIHJhdGhlciBhIHNpbXBsZSBzdGF0aWMgd2lkZ2V0LiBPbmUgZXhhbXBsZSBvZiB0aGlzIGlzCiAgICAgICAgICAvLyBhbiBybWFya2Rvd24gZG9jdW1lbnQgdGhhdCBoYXMgcnVudGltZTpzaGlueSBhbmQgd2lkZ2V0CiAgICAgICAgICAvLyB0aGF0IGlzbid0IGluIGEgcmVuZGVyIGZ1bmN0aW9uLiBTaGlueSBvbmx5IGtub3dzIHRvCiAgICAgICAgICAvLyBjYWxsIHJlc2l6ZSBoYW5kbGVycyBmb3IgU2hpbnkgb3V0cHV0cywgbm90IGZvciBzdGF0aWMKICAgICAgICAgIC8vIHdpZGdldHMsIHNvIHdlIGRvIGl0IG91cnNlbHZlcy4KICAgICAgICAgIGlmICh3aW5kb3cualF1ZXJ5KSB7CiAgICAgICAgICAgIHdpbmRvdy5qUXVlcnkoZG9jdW1lbnQpLm9uKAogICAgICAgICAgICAgICJzaG93bi5odG1sd2lkZ2V0cyBzaG93bi5icy50YWIuaHRtbHdpZGdldHMgc2hvd24uYnMuY29sbGFwc2UuaHRtbHdpZGdldHMiLAogICAgICAgICAgICAgIHJlc2l6ZUhhbmRsZXIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgd2luZG93LmpRdWVyeShkb2N1bWVudCkub24oCiAgICAgICAgICAgICAgImhpZGRlbi5odG1sd2lkZ2V0cyBoaWRkZW4uYnMudGFiLmh0bWx3aWRnZXRzIGhpZGRlbi5icy5jb2xsYXBzZS5odG1sd2lkZ2V0cyIsCiAgICAgICAgICAgICAgcmVzaXplSGFuZGxlcgogICAgICAgICAgICApOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIGZvciB0aGUgc3BlY2lmaWMgY2FzZSBvZiBpb3NsaWRlcywgd2hpY2gKICAgICAgICAgIC8vIGZsaXBzIHNsaWRlcyBiZXR3ZWVuIGRpc3BsYXk6bm9uZSBhbmQgZGlzcGxheTpibG9jay4KICAgICAgICAgIC8vIElkZWFsbHkgd2Ugd291bGQgbm90IGhhdmUgdG8gaGF2ZSBpb3NsaWRlLXNwZWNpZmljIGNvZGUKICAgICAgICAgIC8vIGhlcmUsIGJ1dCByYXRoZXIgaGF2ZSBpb3NsaWRlcyByYWlzZSBhIGdlbmVyaWMgZXZlbnQsCiAgICAgICAgICAvLyBidXQgdGhlIHJtYXJrZG93biBwYWNrYWdlIGp1c3Qgd2VudCB0byBDUkFOIHNvIHRoZQogICAgICAgICAgLy8gd2luZG93IHRvIGdldHRpbmcgdGhhdCBmaXhlZCBtYXkgYmUgbG9uZy4KICAgICAgICAgIGlmICh3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcikgewogICAgICAgICAgICAvLyBJdCdzIE9LIHRvIGxpbWl0IHRoaXMgdG8gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIKICAgICAgICAgICAgLy8gYnJvd3NlcnMgYmVjYXVzZSBpb3NsaWRlcyBpdHNlbGYgb25seSBzdXBwb3J0cwogICAgICAgICAgICAvLyBzdWNoIGJyb3dzZXJzLgogICAgICAgICAgICBvbihkb2N1bWVudCwgInNsaWRlZW50ZXIiLCByZXNpemVIYW5kbGVyKTsKICAgICAgICAgICAgb24oZG9jdW1lbnQsICJzbGlkZWxlYXZlIiwgcmVzaXplSGFuZGxlcik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2YXIgc2NyaXB0RGF0YSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInNjcmlwdFtkYXRhLWZvcj0nIiArIGVsLmlkICsgIiddW3R5cGU9J2FwcGxpY2F0aW9uL2pzb24nXSIpOwogICAgICAgIGlmIChzY3JpcHREYXRhKSB7CiAgICAgICAgICB2YXIgZGF0YSA9IEpTT04ucGFyc2Uoc2NyaXB0RGF0YS50ZXh0Q29udGVudCB8fCBzY3JpcHREYXRhLnRleHQpOwogICAgICAgICAgLy8gUmVzb2x2ZSBzdHJpbmdzIG1hcmtlZCBhcyBqYXZhc2NyaXB0IGxpdGVyYWxzIHRvIG9iamVjdHMKICAgICAgICAgIGlmICghKGRhdGEuZXZhbHMgaW5zdGFuY2VvZiBBcnJheSkpIGRhdGEuZXZhbHMgPSBbZGF0YS5ldmFsc107CiAgICAgICAgICBmb3IgKHZhciBrID0gMDsgZGF0YS5ldmFscyAmJiBrIDwgZGF0YS5ldmFscy5sZW5ndGg7IGsrKykgewogICAgICAgICAgICB3aW5kb3cuSFRNTFdpZGdldHMuZXZhbHVhdGVTdHJpbmdNZW1iZXIoZGF0YS54LCBkYXRhLmV2YWxzW2tdKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpbmRpbmcucmVuZGVyVmFsdWUoZWwsIGRhdGEueCwgaW5pdFJlc3VsdCk7CiAgICAgICAgICBldmFsQW5kUnVuKGRhdGEuanNIb29rcy5yZW5kZXIsIGluaXRSZXN1bHQsIFtlbCwgZGF0YS54XSk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH0pOwoKICAgIGludm9rZVBvc3RSZW5kZXJIYW5kbGVycygpOwogIH0KCiAgLy8gV2FpdCB1bnRpbCBhZnRlciB0aGUgZG9jdW1lbnQgaGFzIGxvYWRlZCB0byByZW5kZXIgdGhlIHdpZGdldHMuCiAgaWYgKGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLCBmdW5jdGlvbigpIHsKICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsIGFyZ3VtZW50cy5jYWxsZWUsIGZhbHNlKTsKICAgICAgd2luZG93LkhUTUxXaWRnZXRzLnN0YXRpY1JlbmRlcigpOwogICAgfSwgZmFsc2UpOwogIH0gZWxzZSBpZiAoZG9jdW1lbnQuYXR0YWNoRXZlbnQpIHsKICAgIGRvY3VtZW50LmF0dGFjaEV2ZW50KCJvbnJlYWR5c3RhdGVjaGFuZ2UiLCBmdW5jdGlvbigpIHsKICAgICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICJjb21wbGV0ZSIpIHsKICAgICAgICBkb2N1bWVudC5kZXRhY2hFdmVudCgib25yZWFkeXN0YXRlY2hhbmdlIiwgYXJndW1lbnRzLmNhbGxlZSk7CiAgICAgICAgd2luZG93LkhUTUxXaWRnZXRzLnN0YXRpY1JlbmRlcigpOwogICAgICB9CiAgICB9KTsKICB9CgoKICB3aW5kb3cuSFRNTFdpZGdldHMuZ2V0QXR0YWNobWVudFVybCA9IGZ1bmN0aW9uKGRlcG5hbWUsIGtleSkgewogICAgLy8gSWYgbm8ga2V5LCBkZWZhdWx0IHRvIHRoZSBmaXJzdCBpdGVtCiAgICBpZiAodHlwZW9mKGtleSkgPT09ICJ1bmRlZmluZWQiKQogICAgICBrZXkgPSAxOwoKICAgIHZhciBsaW5rID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZGVwbmFtZSArICItIiArIGtleSArICItYXR0YWNobWVudCIpOwogICAgaWYgKCFsaW5rKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiQXR0YWNobWVudCAiICsgZGVwbmFtZSArICIvIiArIGtleSArICIgbm90IGZvdW5kIGluIGRvY3VtZW50Iik7CiAgICB9CiAgICByZXR1cm4gbGluay5nZXRBdHRyaWJ1dGUoImhyZWYiKTsKICB9OwoKICB3aW5kb3cuSFRNTFdpZGdldHMuZGF0YWZyYW1lVG9EMyA9IGZ1bmN0aW9uKGRmKSB7CiAgICB2YXIgbmFtZXMgPSBbXTsKICAgIHZhciBsZW5ndGg7CiAgICBmb3IgKHZhciBuYW1lIGluIGRmKSB7CiAgICAgICAgaWYgKGRmLmhhc093blByb3BlcnR5KG5hbWUpKQogICAgICAgICAgICBuYW1lcy5wdXNoKG5hbWUpOwogICAgICAgIGlmICh0eXBlb2YoZGZbbmFtZV0pICE9PSAib2JqZWN0IiB8fCB0eXBlb2YoZGZbbmFtZV0ubGVuZ3RoKSA9PT0gInVuZGVmaW5lZCIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJBbGwgZmllbGRzIG11c3QgYmUgYXJyYXlzIik7CiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YobGVuZ3RoKSAhPT0gInVuZGVmaW5lZCIgJiYgbGVuZ3RoICE9PSBkZltuYW1lXS5sZW5ndGgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJBbGwgZmllbGRzIG11c3QgYmUgYXJyYXlzIG9mIHRoZSBzYW1lIGxlbmd0aCIpOwogICAgICAgIH0KICAgICAgICBsZW5ndGggPSBkZltuYW1lXS5sZW5ndGg7CiAgICB9CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgdmFyIGl0ZW07CiAgICBmb3IgKHZhciByb3cgPSAwOyByb3cgPCBsZW5ndGg7IHJvdysrKSB7CiAgICAgICAgaXRlbSA9IHt9OwogICAgICAgIGZvciAodmFyIGNvbCA9IDA7IGNvbCA8IG5hbWVzLmxlbmd0aDsgY29sKyspIHsKICAgICAgICAgICAgaXRlbVtuYW1lc1tjb2xdXSA9IGRmW25hbWVzW2NvbF1dW3Jvd107CiAgICAgICAgfQogICAgICAgIHJlc3VsdHMucHVzaChpdGVtKTsKICAgIH0KICAgIHJldHVybiByZXN1bHRzOwogIH07CgogIHdpbmRvdy5IVE1MV2lkZ2V0cy50cmFuc3Bvc2VBcnJheTJEID0gZnVuY3Rpb24oYXJyYXkpIHsKICAgICAgaWYgKGFycmF5Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIGFycmF5OwogICAgICB2YXIgbmV3QXJyYXkgPSBhcnJheVswXS5tYXAoZnVuY3Rpb24oY29sLCBpKSB7CiAgICAgICAgICByZXR1cm4gYXJyYXkubWFwKGZ1bmN0aW9uKHJvdykgewogICAgICAgICAgICAgIHJldHVybiByb3dbaV0KICAgICAgICAgIH0pCiAgICAgIH0pOwogICAgICByZXR1cm4gbmV3QXJyYXk7CiAgfTsKICAvLyBTcGxpdCB2YWx1ZSBhdCBzcGxpdENoYXIsIGJ1dCBhbGxvdyBzcGxpdENoYXIgdG8gYmUgZXNjYXBlZAogIC8vIHVzaW5nIGVzY2FwZUNoYXIuIEFueSBvdGhlciBjaGFyYWN0ZXJzIGVzY2FwZWQgYnkgZXNjYXBlQ2hhcgogIC8vIHdpbGwgYmUgaW5jbHVkZWQgYXMgdXN1YWwgKGluY2x1ZGluZyBlc2NhcGVDaGFyIGl0c2VsZikuCiAgZnVuY3Rpb24gc3BsaXRXaXRoRXNjYXBlKHZhbHVlLCBzcGxpdENoYXIsIGVzY2FwZUNoYXIpIHsKICAgIHZhciByZXN1bHRzID0gW107CiAgICB2YXIgZXNjYXBlTW9kZSA9IGZhbHNlOwogICAgdmFyIGN1cnJlbnRSZXN1bHQgPSAiIjsKICAgIGZvciAodmFyIHBvcyA9IDA7IHBvcyA8IHZhbHVlLmxlbmd0aDsgcG9zKyspIHsKICAgICAgaWYgKCFlc2NhcGVNb2RlKSB7CiAgICAgICAgaWYgKHZhbHVlW3Bvc10gPT09IHNwbGl0Q2hhcikgewogICAgICAgICAgcmVzdWx0cy5wdXNoKGN1cnJlbnRSZXN1bHQpOwogICAgICAgICAgY3VycmVudFJlc3VsdCA9ICIiOwogICAgICAgIH0gZWxzZSBpZiAodmFsdWVbcG9zXSA9PT0gZXNjYXBlQ2hhcikgewogICAgICAgICAgZXNjYXBlTW9kZSA9IHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGN1cnJlbnRSZXN1bHQgKz0gdmFsdWVbcG9zXTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY3VycmVudFJlc3VsdCArPSB2YWx1ZVtwb3NdOwogICAgICAgIGVzY2FwZU1vZGUgPSBmYWxzZTsKICAgICAgfQogICAgfQogICAgaWYgKGN1cnJlbnRSZXN1bHQgIT09ICIiKSB7CiAgICAgIHJlc3VsdHMucHVzaChjdXJyZW50UmVzdWx0KTsKICAgIH0KICAgIHJldHVybiByZXN1bHRzOwogIH0KICAvLyBGdW5jdGlvbiBhdXRob3JlZCBieSBZaWh1aS9KSiBBbGxhaXJlCiAgd2luZG93LkhUTUxXaWRnZXRzLmV2YWx1YXRlU3RyaW5nTWVtYmVyID0gZnVuY3Rpb24obywgbWVtYmVyKSB7CiAgICB2YXIgcGFydHMgPSBzcGxpdFdpdGhFc2NhcGUobWVtYmVyLCAnLicsICdcXCcpOwogICAgZm9yICh2YXIgaSA9IDAsIGwgPSBwYXJ0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgdmFyIHBhcnQgPSBwYXJ0c1tpXTsKICAgICAgLy8gcGFydCBtYXkgYmUgYSBjaGFyYWN0ZXIgb3IgJ251bWVyaWMnIG1lbWJlciBuYW1lCiAgICAgIGlmIChvICE9PSBudWxsICYmIHR5cGVvZiBvID09PSAib2JqZWN0IiAmJiBwYXJ0IGluIG8pIHsKICAgICAgICBpZiAoaSA9PSAobCAtIDEpKSB7IC8vIGlmIHdlIGFyZSBhdCB0aGUgZW5kIG9mIHRoZSBsaW5lIHRoZW4gZXZhbHVsYXRlCiAgICAgICAgICBpZiAodHlwZW9mIG9bcGFydF0gPT09ICJzdHJpbmciKQogICAgICAgICAgICBvW3BhcnRdID0gZXZhbCgiKCIgKyBvW3BhcnRdICsgIikiKTsKICAgICAgICB9IGVsc2UgeyAvLyBvdGhlcndpc2UgY29udGludWUgdG8gbmV4dCBlbWJlZGRlZCBvYmplY3QKICAgICAgICAgIG8gPSBvW3BhcnRdOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH07CgogIC8vIFJldHJpZXZlIHRoZSBIVE1MV2lkZ2V0IGluc3RhbmNlIChpLmUuIHRoZSByZXR1cm4gdmFsdWUgb2YgYW4KICAvLyBIVE1MV2lkZ2V0IGJpbmRpbmcncyBpbml0aWFsaXplKCkgb3IgZmFjdG9yeSgpIGZ1bmN0aW9uKQogIC8vIGFzc29jaWF0ZWQgd2l0aCBhbiBlbGVtZW50LCBvciBudWxsIGlmIG5vbmUuCiAgd2luZG93LkhUTUxXaWRnZXRzLmdldEluc3RhbmNlID0gZnVuY3Rpb24oZWwpIHsKICAgIHJldHVybiBlbGVtZW50RGF0YShlbCwgImluaXRfcmVzdWx0Iik7CiAgfTsKCiAgLy8gRmluZHMgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIHNjb3BlIHRoYXQgbWF0Y2hlcyB0aGUgc2VsZWN0b3IsCiAgLy8gYW5kIHJldHVybnMgdGhlIEhUTUxXaWRnZXQgaW5zdGFuY2UgKGkuZS4gdGhlIHJldHVybiB2YWx1ZSBvZgogIC8vIGFuIEhUTUxXaWRnZXQgYmluZGluZydzIGluaXRpYWxpemUoKSBvciBmYWN0b3J5KCkgZnVuY3Rpb24pCiAgLy8gYXNzb2NpYXRlZCB3aXRoIHRoYXQgZWxlbWVudCwgaWYgYW55LiBJZiBubyBlbGVtZW50IG1hdGNoZXMgdGhlCiAgLy8gc2VsZWN0b3IsIG9yIHRoZSBmaXJzdCBtYXRjaGluZyBlbGVtZW50IGhhcyBubyBIVE1MV2lkZ2V0CiAgLy8gaW5zdGFuY2UgYXNzb2NpYXRlZCB3aXRoIGl0LCB0aGVuIG51bGwgaXMgcmV0dXJuZWQuCiAgLy8KICAvLyBUaGUgc2NvcGUgYXJndW1lbnQgaXMgb3B0aW9uYWwsIGFuZCBkZWZhdWx0cyB0byB3aW5kb3cuZG9jdW1lbnQuCiAgd2luZG93LkhUTUxXaWRnZXRzLmZpbmQgPSBmdW5jdGlvbihzY29wZSwgc2VsZWN0b3IpIHsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgc2VsZWN0b3IgPSBzY29wZTsKICAgICAgc2NvcGUgPSBkb2N1bWVudDsKICAgIH0KCiAgICB2YXIgZWwgPSBzY29wZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTsKICAgIGlmIChlbCA9PT0gbnVsbCkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB3aW5kb3cuSFRNTFdpZGdldHMuZ2V0SW5zdGFuY2UoZWwpOwogICAgfQogIH07CgogIC8vIEZpbmRzIGFsbCBlbGVtZW50cyBpbiB0aGUgc2NvcGUgdGhhdCBtYXRjaCB0aGUgc2VsZWN0b3IsIGFuZAogIC8vIHJldHVybnMgdGhlIEhUTUxXaWRnZXQgaW5zdGFuY2VzIChpLmUuIHRoZSByZXR1cm4gdmFsdWVzIG9mCiAgLy8gYW4gSFRNTFdpZGdldCBiaW5kaW5nJ3MgaW5pdGlhbGl6ZSgpIG9yIGZhY3RvcnkoKSBmdW5jdGlvbikKICAvLyBhc3NvY2lhdGVkIHdpdGggdGhlIGVsZW1lbnRzLCBpbiBhbiBhcnJheS4gSWYgZWxlbWVudHMgdGhhdAogIC8vIG1hdGNoIHRoZSBzZWxlY3RvciBkb24ndCBoYXZlIGFuIGFzc29jaWF0ZWQgSFRNTFdpZGdldAogIC8vIGluc3RhbmNlLCB0aGUgcmV0dXJuZWQgYXJyYXkgd2lsbCBjb250YWluIG51bGxzLgogIC8vCiAgLy8gVGhlIHNjb3BlIGFyZ3VtZW50IGlzIG9wdGlvbmFsLCBhbmQgZGVmYXVsdHMgdG8gd2luZG93LmRvY3VtZW50LgogIHdpbmRvdy5IVE1MV2lkZ2V0cy5maW5kQWxsID0gZnVuY3Rpb24oc2NvcGUsIHNlbGVjdG9yKSB7CiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7CiAgICAgIHNlbGVjdG9yID0gc2NvcGU7CiAgICAgIHNjb3BlID0gZG9jdW1lbnQ7CiAgICB9CgogICAgdmFyIG5vZGVzID0gc2NvcGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykgewogICAgICByZXN1bHRzLnB1c2god2luZG93LkhUTUxXaWRnZXRzLmdldEluc3RhbmNlKG5vZGVzW2ldKSk7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0czsKICB9OwoKICB2YXIgcG9zdFJlbmRlckhhbmRsZXJzID0gW107CiAgZnVuY3Rpb24gaW52b2tlUG9zdFJlbmRlckhhbmRsZXJzKCkgewogICAgd2hpbGUgKHBvc3RSZW5kZXJIYW5kbGVycy5sZW5ndGgpIHsKICAgICAgdmFyIGhhbmRsZXIgPSBwb3N0UmVuZGVySGFuZGxlcnMuc2hpZnQoKTsKICAgICAgaWYgKGhhbmRsZXIpIHsKICAgICAgICBoYW5kbGVyKCk7CiAgICAgIH0KICAgIH0KICB9CgogIC8vIFJlZ2lzdGVyIHRoZSBnaXZlbiBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBpbnZva2VkIGFmdGVyIHRoZQogIC8vIG5leHQgdGltZSBzdGF0aWMgd2lkZ2V0cyBhcmUgcmVuZGVyZWQuCiAgd2luZG93LkhUTUxXaWRnZXRzLmFkZFBvc3RSZW5kZXJIYW5kbGVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgIHBvc3RSZW5kZXJIYW5kbGVycy5wdXNoKGNhbGxiYWNrKTsKICB9OwoKICAvLyBUYWtlcyBhIG5ldy1zdHlsZSBpbnN0YW5jZS1ib3VuZCBkZWZpbml0aW9uLCBhbmQgcmV0dXJucyBhbgogIC8vIG9sZC1zdHlsZSBjbGFzcy1ib3VuZCBkZWZpbml0aW9uLiBUaGlzIHNhdmVzIHVzIGZyb20gaGF2aW5nCiAgLy8gdG8gcmV3cml0ZSBhbGwgdGhlIGxvZ2ljIGluIHRoaXMgZmlsZSB0byBhY2NvbW9kYXRlIGJvdGgKICAvLyB0eXBlcyBvZiBkZWZpbml0aW9ucy4KICBmdW5jdGlvbiBjcmVhdGVMZWdhY3lEZWZpbml0aW9uQWRhcHRlcihkZWZuKSB7CiAgICB2YXIgcmVzdWx0ID0gewogICAgICBuYW1lOiBkZWZuLm5hbWUsCiAgICAgIHR5cGU6IGRlZm4udHlwZSwKICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWwsIHdpZHRoLCBoZWlnaHQpIHsKICAgICAgICByZXR1cm4gZGVmbi5mYWN0b3J5KGVsLCB3aWR0aCwgaGVpZ2h0KTsKICAgICAgfSwKICAgICAgcmVuZGVyVmFsdWU6IGZ1bmN0aW9uKGVsLCB4LCBpbnN0YW5jZSkgewogICAgICAgIHJldHVybiBpbnN0YW5jZS5yZW5kZXJWYWx1ZSh4KTsKICAgICAgfSwKICAgICAgcmVzaXplOiBmdW5jdGlvbihlbCwgd2lkdGgsIGhlaWdodCwgaW5zdGFuY2UpIHsKICAgICAgICByZXR1cm4gaW5zdGFuY2UucmVzaXplKHdpZHRoLCBoZWlnaHQpOwogICAgICB9CiAgICB9OwoKICAgIGlmIChkZWZuLmZpbmQpCiAgICAgIHJlc3VsdC5maW5kID0gZGVmbi5maW5kOwogICAgaWYgKGRlZm4ucmVuZGVyRXJyb3IpCiAgICAgIHJlc3VsdC5yZW5kZXJFcnJvciA9IGRlZm4ucmVuZGVyRXJyb3I7CiAgICBpZiAoZGVmbi5jbGVhckVycm9yKQogICAgICByZXN1bHQuY2xlYXJFcnJvciA9IGRlZm4uY2xlYXJFcnJvcjsKCiAgICByZXR1cm4gcmVzdWx0OwogIH0KfSkoKTsKCg==\"></script>\r\n",
"<link href=\"data:text/css;charset=utf-8,%0A%23wcLabel%20%7B%0Aposition%3A%20absolute%3B%0Aborder%3A%202px%20solid%20%23fff%3B%0Abox%2Dshadow%3A%200%200%204px%200%20%23008%3B%0Apadding%3A%202px%3B%0A%0Apointer%2Devents%3A%20none%3B%20%7D%0A%23wcSpan%20%7B%0Aposition%3A%20absolute%3B%0Atop%3A%20100%25%3B%0Aleft%3A%200%3B%0Abackground%2Dcolor%3A%20rgba%28255%2C%20255%2C%20255%2C%200%2E8%29%3B%0Acolor%3A%20%23333%3B%0Amargin%2Dtop%3A%206px%3B%0Apadding%3A%200%200%2E5em%3B%0Aborder%2Dradius%3A%200%2E5em%3B%0Awhite%2Dspace%3A%20nowrap%3B%20%7D%0A\" rel=\"stylesheet\" />\r\n",
"<script src=\"data:application/x-javascript;base64,LyohCiAqIHdvcmRjbG91ZDIuanMKICogaHR0cDovL3RpbWRyZWFtLm9yZy93b3JkY2xvdWQyLmpzLwogKgogKiBDb3B5cmlnaHQgMjAxMSAtIDIwMTMgVGltIENoaWVuCiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZQogKi8KCid1c2Ugc3RyaWN0JzsKCi8vIHNldEltbWVkaWF0ZQppZiAoIXdpbmRvdy5zZXRJbW1lZGlhdGUpIHsKICB3aW5kb3cuc2V0SW1tZWRpYXRlID0gKGZ1bmN0aW9uIHNldHVwU2V0SW1tZWRpYXRlKCkgewogICAgcmV0dXJuIHdpbmRvdy5tc1NldEltbWVkaWF0ZSB8fAogICAgd2luZG93LndlYmtpdFNldEltbWVkaWF0ZSB8fAogICAgd2luZG93Lm1velNldEltbWVkaWF0ZSB8fAogICAgd2luZG93Lm9TZXRJbW1lZGlhdGUgfHwKICAgIChmdW5jdGlvbiBzZXR1cFNldFplcm9UaW1lb3V0KCkgewogICAgICBpZiAoIXdpbmRvdy5wb3N0TWVzc2FnZSB8fCAhd2luZG93LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgfQoKICAgICAgdmFyIGNhbGxiYWNrcyA9IFt1bmRlZmluZWRdOwogICAgICB2YXIgbWVzc2FnZSA9ICd6ZXJvLXRpbWVvdXQtbWVzc2FnZSc7CgogICAgICAvLyBMaWtlIHNldFRpbWVvdXQsIGJ1dCBvbmx5IHRha2VzIGEgZnVuY3Rpb24gYXJndW1lbnQuICBUaGVyZSdzCiAgICAgIC8vIG5vIHRpbWUgYXJndW1lbnQgKGFsd2F5cyB6ZXJvKSBhbmQgbm8gYXJndW1lbnRzICh5b3UgaGF2ZSB0bwogICAgICAvLyB1c2UgYSBjbG9zdXJlKS4KICAgICAgdmFyIHNldFplcm9UaW1lb3V0ID0gZnVuY3Rpb24gc2V0WmVyb1RpbWVvdXQoY2FsbGJhY2spIHsKICAgICAgICB2YXIgaWQgPSBjYWxsYmFja3MubGVuZ3RoOwogICAgICAgIGNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTsKICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UobWVzc2FnZSArIGlkLnRvU3RyaW5nKDM2KSwgJyonKTsKCiAgICAgICAgcmV0dXJuIGlkOwogICAgICB9OwoKICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiBzZXRaZXJvVGltZW91dE1lc3NhZ2UoZXZ0KSB7CiAgICAgICAgLy8gU2tpcHBpbmcgY2hlY2tpbmcgZXZlbnQgc291cmNlLCByZXRhcmRlZCBJRSBjb25mdXNlZCB0aGlzIHdpbmRvdwogICAgICAgIC8vIG9iamVjdCB3aXRoIGFub3RoZXIgaW4gdGhlIHByZXNlbmNlIG9mIGlmcmFtZQogICAgICAgIGlmICh0eXBlb2YgZXZ0LmRhdGEgIT09ICdzdHJpbmcnIHx8CiAgICAgICAgICAgIGV2dC5kYXRhLnN1YnN0cigwLCBtZXNzYWdlLmxlbmd0aCkgIT09IG1lc3NhZ2UvKiB8fAogICAgICAgICAgICBldnQuc291cmNlICE9PSB3aW5kb3cgKi8pIHsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGV2dC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTsKCiAgICAgICAgdmFyIGlkID0gcGFyc2VJbnQoZXZ0LmRhdGEuc3Vic3RyKG1lc3NhZ2UubGVuZ3RoKSwgMzYpOwogICAgICAgIGlmICghY2FsbGJhY2tzW2lkXSkgewogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgY2FsbGJhY2tzW2lkXSgpOwogICAgICAgIGNhbGxiYWNrc1tpZF0gPSB1bmRlZmluZWQ7CiAgICAgIH0sIHRydWUpOwoKICAgICAgLyogc3BlY2lmeSBjbGVhckltbWVkaWF0ZSgpIGhlcmUgc2luY2Ugd2UgbmVlZCB0aGUgc2NvcGUgKi8KICAgICAgd2luZG93LmNsZWFySW1tZWRpYXRlID0gZnVuY3Rpb24gY2xlYXJaZXJvVGltZW91dChpZCkgewogICAgICAgIGlmICghY2FsbGJhY2tzW2lkXSkgewogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgY2FsbGJhY2tzW2lkXSA9IHVuZGVmaW5lZDsKICAgICAgfTsKCiAgICAgIHJldHVybiBzZXRaZXJvVGltZW91dDsKICAgIH0pKCkgfHwKICAgIC8vIGZhbGxiYWNrCiAgICBmdW5jdGlvbiBzZXRJbW1lZGlhdGVGYWxsYmFjayhmbikgewogICAgICB3aW5kb3cuc2V0VGltZW91dChmbiwgMCk7CiAgICB9OwogIH0pKCk7Cn0KCmlmICghd2luZG93LmNsZWFySW1tZWRpYXRlKSB7CiAgd2luZG93LmNsZWFySW1tZWRpYXRlID0gKGZ1bmN0aW9uIHNldHVwQ2xlYXJJbW1lZGlhdGUoKSB7CiAgICByZXR1cm4gd2luZG93Lm1zQ2xlYXJJbW1lZGlhdGUgfHwKICAgIHdpbmRvdy53ZWJraXRDbGVhckltbWVkaWF0ZSB8fAogICAgd2luZG93Lm1vekNsZWFySW1tZWRpYXRlIHx8CiAgICB3aW5kb3cub0NsZWFySW1tZWRpYXRlIHx8CiAgICAvLyAiY2xlYXJaZXJvVGltZW91dCIgaXMgaW1wbGVtZW50IG9uIHRoZSBwcmV2aW91cyBibG9jayB8fAogICAgLy8gZmFsbGJhY2sKICAgIGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlRmFsbGJhY2sodGltZXIpIHsKICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aW1lcik7CiAgICB9OwogIH0pKCk7Cn0KCihmdW5jdGlvbihnbG9iYWwpIHsKCiAgLy8gQ2hlY2sgaWYgV29yZENsb3VkIGNhbiBydW4gb24gdGhpcyBicm93c2VyCiAgdmFyIGlzU3VwcG9ydGVkID0gKGZ1bmN0aW9uIGlzU3VwcG9ydGVkKCkgewogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpOwogICAgaWYgKCFjYW52YXMgfHwgIWNhbnZhcy5nZXRDb250ZXh0KSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7CiAgICBpZiAoIWN0eC5nZXRJbWFnZURhdGEpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKCFjdHguZmlsbFRleHQpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGlmICghQXJyYXkucHJvdG90eXBlLnNvbWUpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKCFBcnJheS5wcm90b3R5cGUucHVzaCkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcmV0dXJuIHRydWU7CiAgfSgpKTsKCiAgLy8gRmluZCBvdXQgaWYgdGhlIGJyb3dzZXIgaW1wb3NlIG1pbml1bSBmb250IHNpemUgYnkKICAvLyBkcmF3aW5nIHNtYWxsIHRleHRzIG9uIGEgY2FudmFzIGFuZCBtZWFzdXJlIGl0J3Mgd2lkdGguCiAgdmFyIG1pbkZvbnRTaXplID0gKGZ1bmN0aW9uIGdldE1pbkZvbnRTaXplKCkgewogICAgaWYgKCFpc1N1cHBvcnRlZCkgewogICAgICByZXR1cm47CiAgICB9CgogICAgdmFyIGN0eCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyk7CgogICAgLy8gc3RhcnQgZnJvbSAyMAogICAgdmFyIHNpemUgPSAyMDsKCiAgICAvLyB0d28gc2l6ZXMgdG8gbWVhc3VyZQogICAgdmFyIGhhbldpZHRoLCBtV2lkdGg7CgogICAgd2hpbGUgKHNpemUpIHsKICAgICAgY3R4LmZvbnQgPSBzaXplLnRvU3RyaW5nKDEwKSArICdweCBzYW5zLXNlcmlmJzsKICAgICAgaWYgKChjdHgubWVhc3VyZVRleHQoJ1x1RkYzNycpLndpZHRoID09PSBoYW5XaWR0aCkgJiYKICAgICAgICAgIChjdHgubWVhc3VyZVRleHQoJ20nKS53aWR0aCkgPT09IG1XaWR0aCkgewogICAgICAgIHJldHVybiAoc2l6ZSArIDEpOwogICAgICB9CgogICAgICBoYW5XaWR0aCA9IGN0eC5tZWFzdXJlVGV4dCgnXHVGRjM3Jykud2lkdGg7CiAgICAgIG1XaWR0aCA9IGN0eC5tZWFzdXJlVGV4dCgnbScpLndpZHRoOwoKICAgICAgc2l6ZS0tOwogICAgfQoKICAgIHJldHVybiAwOwogIH0pKCk7CgogIC8vIEJhc2VkIG9uIGh0dHA6Ly9qc2Zyb21oZWxsLmNvbS9hcnJheS9zaHVmZmxlCiAgdmFyIHNodWZmbGVBcnJheSA9IGZ1bmN0aW9uIHNodWZmbGVBcnJheShhcnIpIHsKICAgIGZvciAodmFyIGosIHgsIGkgPSBhcnIubGVuZ3RoOyBpOwogICAgICBqID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogaSksCiAgICAgIHggPSBhcnJbLS1pXSwgYXJyW2ldID0gYXJyW2pdLAogICAgICBhcnJbal0gPSB4KSB7fQogICAgcmV0dXJuIGFycjsKICB9OwoKICB2YXIgV29yZENsb3VkID0gZnVuY3Rpb24gV29yZENsb3VkKGVsZW1lbnRzLCBvcHRpb25zKSB7CiAgICBpZiAoIWlzU3VwcG9ydGVkKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZWxlbWVudHMpKSB7CiAgICAgIGVsZW1lbnRzID0gW2VsZW1lbnRzXTsKICAgIH0KCiAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsLCBpKSB7CiAgICAgIGlmICh0eXBlb2YgZWwgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgZWxlbWVudHNbaV0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbCk7CiAgICAgICAgaWYgKCFlbGVtZW50c1tpXSkgewogICAgICAgICAgdGhyb3cgJ1RoZSBlbGVtZW50IGlkIHNwZWNpZmllZCBpcyBub3QgZm91bmQuJzsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoIWVsLnRhZ05hbWUgJiYgIWVsLmFwcGVuZENoaWxkKSB7CiAgICAgICAgdGhyb3cgJ1lvdSBtdXN0IHBhc3MgdmFsaWQgSFRNTCBlbGVtZW50cywgb3IgSUQgb2YgdGhlIGVsZW1lbnQuJzsKICAgICAgfQogICAgfSk7CgogICAgLyogRGVmYXVsdCB2YWx1ZXMgdG8gYmUgb3ZlcndyaXR0ZW4gYnkgb3B0aW9ucyBvYmplY3QgKi8KICAgIHZhciBzZXR0aW5ncyA9IHsKICAgICAgbGlzdDogW10sCiAgICAgIGZvbnRGYW1pbHk6ICciVHJlYnVjaGV0IE1TIiwgIkhlaXRpIFRDIiwgIuW+rui7n+ato+m7kemrlCIsICcgKwogICAgICAgICAgICAgICAgICAnIkFyaWFsIFVuaWNvZGUgTVMiLCAiRHJvaWQgRmFsbGJhY2sgU2FucyIsIHNhbnMtc2VyaWYnLAogICAgICBmb250V2VpZ2h0OiAnbm9ybWFsJywKICAgICAgY29sb3I6ICdyYW5kb20tZGFyaycsCiAgICAgIG1pblNpemU6IDAsIC8vIDAgdG8gZGlzYWJsZQogICAgICB3ZWlnaHRGYWN0b3I6IDEsCiAgICAgIGNsZWFyQ2FudmFzOiB0cnVlLAogICAgICBiYWNrZ3JvdW5kQ29sb3I6ICcjZmZmJywgIC8vIG9wYXF1ZSB3aGl0ZSA9IHJnYmEoMjU1LCAyNTUsIDI1NSwgMSkKCiAgICAgIGdyaWRTaXplOiA4LAogICAgICBvcmlnaW46IG51bGwsCgogICAgICBkcmF3TWFzazogZmFsc2UsCiAgICAgIG1hc2tDb2xvcjogJ3JnYmEoMjU1LDAsMCwwLjMpJywKICAgICAgbWFza0dhcFdpZHRoOiAwLjMsCgogICAgICB3YWl0OiAwLAogICAgICBhYm9ydFRocmVzaG9sZDogMCwgLy8gZGlzYWJsZWQKICAgICAgYWJvcnQ6IGZ1bmN0aW9uIG5vb3AoKSB7fSwKCiAgICAgIG1pblJvdGF0aW9uOiAtIE1hdGguUEkgLyAyLAogICAgICBtYXhSb3RhdGlvbjogTWF0aC5QSSAvIDIsCgogICAgICBzaHVmZmxlOiB0cnVlLAogICAgICByb3RhdGVSYXRpbzogMC4xLAoKICAgICAgc2hhcGU6ICdjaXJjbGUnLAogICAgICBlbGxpcHRpY2l0eTogMC42NSwKCiAgICAgIGNsYXNzZXM6IG51bGwsCgogICAgICBob3ZlcjogbnVsbCwKICAgICAgY2xpY2s6IG51bGwKICAgIH07CgogICAgaWYgKG9wdGlvbnMpIHsKICAgICAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMpIHsKICAgICAgICBpZiAoa2V5IGluIHNldHRpbmdzKSB7CiAgICAgICAgICBzZXR0aW5nc1trZXldID0gb3B0aW9uc1trZXldOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8qIENvbnZlcnQgd2VpZ2h0RmFjdG9yIGludG8gYSBmdW5jdGlvbiAqLwogICAgaWYgKHR5cGVvZiBzZXR0aW5ncy53ZWlnaHRGYWN0b3IgIT09ICdmdW5jdGlvbicpIHsKICAgICAgdmFyIGZhY3RvciA9IHNldHRpbmdzLndlaWdodEZhY3RvcjsKICAgICAgc2V0dGluZ3Mud2VpZ2h0RmFjdG9yID0gZnVuY3Rpb24gd2VpZ2h0RmFjdG9yKHB0KSB7CiAgICAgICAgcmV0dXJuIHB0ICogZmFjdG9yOyAvL2luIHB4CiAgICAgIH07CiAgICB9CgogICAgLyogQ29udmVydCBzaGFwZSBpbnRvIGEgZnVuY3Rpb24gKi8KICAgIGlmICh0eXBlb2Ygc2V0dGluZ3Muc2hhcGUgIT09ICdmdW5jdGlvbicpIHsKICAgICAgc3dpdGNoIChzZXR0aW5ncy5zaGFwZSkgewogICAgICAgIGNhc2UgJ2NpcmNsZSc6CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAvLyAnY2lyY2xlJyBpcyB0aGUgZGVmYXVsdCBhbmQgYSBzaG9ydGN1dCBpbiB0aGUgY29kZSBsb29wLgogICAgICAgICAgc2V0dGluZ3Muc2hhcGUgPSAnY2lyY2xlJzsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICdjYXJkaW9pZCc6CiAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlQ2FyZGlvaWQodGhldGEpIHsKICAgICAgICAgICAgcmV0dXJuIDEgLSBNYXRoLnNpbih0aGV0YSk7CiAgICAgICAgICB9OwogICAgICAgICAgYnJlYWs7CgogICAgICAgIC8qCgogICAgICAgIFRvIHdvcmsgb3V0IGFuIFgtZ29uLCBvbmUgaGFzIHRvIGNhbGN1bGF0ZSAibSIsCiAgICAgICAgd2hlcmUgMS8oY29zKDIqUEkvWCkrbSpzaW4oMipQSS9YKSkgPSAxLyhjb3MoMCkrbSpzaW4oMCkpCiAgICAgICAgaHR0cDovL3d3dy53b2xmcmFtYWxwaGEuY29tL2lucHV0Lz9pPTElMkYlMjhjb3MlMjgyKlBJJTJGWCUyOSUyQm0qc2luJTI4CiAgICAgICAgMipQSSUyRlglMjklMjkrJTNEKzElMkYlMjhjb3MlMjgwJTI5JTJCbSpzaW4lMjgwJTI5JTI5CgogICAgICAgIENvcHkgdGhlIHNvbHV0aW9uIGludG8gcG9sYXIgZXF1YXRpb24gciA9IDEvKGNvcyh0JykgKyBtKnNpbih0JykpCiAgICAgICAgd2hlcmUgdCcgZXF1YWxzIHRvIG1vZCh0LCAyUEkvWCk7CgogICAgICAgICovCgogICAgICAgIGNhc2UgJ2RpYW1vbmQnOgogICAgICAgIGNhc2UgJ3NxdWFyZSc6CiAgICAgICAgICAvLyBodHRwOi8vd3d3LndvbGZyYW1hbHBoYS5jb20vaW5wdXQvP2k9cGxvdCtyKyUzRCsxJTJGJTI4Y29zJTI4bW9kKwogICAgICAgICAgLy8gJTI4dCUyQytQSSUyRjIlMjklMjklMkJzaW4lMjhtb2QrJTI4dCUyQytQSSUyRjIlMjklMjklMjklMkMrdCslM0QKICAgICAgICAgIC8vICswKy4uKzIqUEkKICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVTcXVhcmUodGhldGEpIHsKICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSB0aGV0YSAlICgyICogTWF0aC5QSSAvIDQpOwogICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArIE1hdGguc2luKHRoZXRhUHJpbWUpKTsKICAgICAgICAgIH07CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAndHJpYW5nbGUtZm9yd2FyZCc6CiAgICAgICAgICAvLyBodHRwOi8vd3d3LndvbGZyYW1hbHBoYS5jb20vaW5wdXQvP2k9cGxvdCtyKyUzRCsxJTJGJTI4Y29zJTI4bW9kKwogICAgICAgICAgLy8gJTI4dCUyQysyKlBJJTJGMyUyOSUyOSUyQnNxcnQlMjgzJTI5c2luJTI4bW9kKyUyOHQlMkMrMipQSSUyRjMlMjkKICAgICAgICAgIC8vICUyOSUyOSUyQyt0KyUzRCswKy4uKzIqUEkKICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVUcmlhbmdsZSh0aGV0YSkgewogICAgICAgICAgICB2YXIgdGhldGFQcmltZSA9IHRoZXRhICUgKDIgKiBNYXRoLlBJIC8gMyk7CiAgICAgICAgICAgIHJldHVybiAxIC8gKE1hdGguY29zKHRoZXRhUHJpbWUpICsKICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5zcXJ0KDMpICogTWF0aC5zaW4odGhldGFQcmltZSkpOwogICAgICAgICAgfTsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICd0cmlhbmdsZSc6CiAgICAgICAgY2FzZSAndHJpYW5nbGUtdXByaWdodCc6CiAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlVHJpYW5nbGUodGhldGEpIHsKICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSAodGhldGEgKyBNYXRoLlBJICogMyAvIDIpICUgKDIgKiBNYXRoLlBJIC8gMyk7CiAgICAgICAgICAgIHJldHVybiAxIC8gKE1hdGguY29zKHRoZXRhUHJpbWUpICsKICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5zcXJ0KDMpICogTWF0aC5zaW4odGhldGFQcmltZSkpOwogICAgICAgICAgfTsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICdwZW50YWdvbic6CiAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlUGVudGFnb24odGhldGEpIHsKICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSAodGhldGEgKyAwLjk1NSkgJSAoMiAqIE1hdGguUEkgLyA1KTsKICAgICAgICAgICAgcmV0dXJuIDEgLyAoTWF0aC5jb3ModGhldGFQcmltZSkgKwogICAgICAgICAgICAgICAgICAgICAgICAwLjcyNjU0MyAqIE1hdGguc2luKHRoZXRhUHJpbWUpKTsKICAgICAgICAgIH07CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAnc3Rhcic6CiAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlU3Rhcih0aGV0YSkgewogICAgICAgICAgICB2YXIgdGhldGFQcmltZSA9ICh0aGV0YSArIDAuOTU1KSAlICgyICogTWF0aC5QSSAvIDEwKTsKICAgICAgICAgICAgaWYgKCh0aGV0YSArIDAuOTU1KSAlICgyICogTWF0aC5QSSAvIDUpIC0gKDIgKiBNYXRoLlBJIC8gMTApID49IDApIHsKICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcygoMiAqIE1hdGguUEkgLyAxMCkgLSB0aGV0YVByaW1lKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgMy4wNzc2OCAqIE1hdGguc2luKCgyICogTWF0aC5QSSAvIDEwKSAtIHRoZXRhUHJpbWUpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgMy4wNzc2OCAqIE1hdGguc2luKHRoZXRhUHJpbWUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CgogICAgLyogTWFrZSBzdXJlIGdyaWRTaXplIGlzIGEgd2hvbGUgbnVtYmVyIGFuZCBpcyBub3Qgc21hbGxlciB0aGFuIDRweCAqLwogICAgc2V0dGluZ3MuZ3JpZFNpemUgPSBNYXRoLm1heChNYXRoLmZsb29yKHNldHRpbmdzLmdyaWRTaXplKSwgNCk7CgogICAgLyogc2hvcnRoYW5kICovCiAgICB2YXIgZyA9IHNldHRpbmdzLmdyaWRTaXplOwogICAgdmFyIG1hc2tSZWN0V2lkdGggPSBnIC0gc2V0dGluZ3MubWFza0dhcFdpZHRoOwoKICAgIC8qIG5vcm1hbGl6ZSByb3RhdGlvbiBzZXR0aW5ncyAqLwogICAgdmFyIHJvdGF0aW9uUmFuZ2UgPSBNYXRoLmFicyhzZXR0aW5ncy5tYXhSb3RhdGlvbiAtIHNldHRpbmdzLm1pblJvdGF0aW9uKTsKICAgIHZhciBtaW5Sb3RhdGlvbiA9IE1hdGgubWluKHNldHRpbmdzLm1heFJvdGF0aW9uLCBzZXR0aW5ncy5taW5Sb3RhdGlvbik7CgogICAgLyogaW5mb3JtYXRpb24vb2JqZWN0IGF2YWlsYWJsZSB0byBhbGwgZnVuY3Rpb25zLCBzZXQgd2hlbiBzdGFydCgpICovCiAgICB2YXIgZ3JpZCwgLy8gMmQgYXJyYXkgY29udGFpbmluZyBmaWxsaW5nIGluZm9ybWF0aW9uCiAgICAgIG5neCwgbmd5LCAvLyB3aWR0aCBhbmQgaGVpZ2h0IG9mIHRoZSBncmlkCiAgICAgIGNlbnRlciwgLy8gcG9zaXRpb24gb2YgdGhlIGNlbnRlciBvZiB0aGUgY2xvdWQKICAgICAgbWF4UmFkaXVzOwoKICAgIC8qIHRpbWVzdGFtcCBmb3IgbWVhc3VyaW5nIGVhY2ggcHV0V29yZCgpIGFjdGlvbiAqLwogICAgdmFyIGVzY2FwZVRpbWU7CgogICAgLyogZnVuY3Rpb24gZm9yIGdldHRpbmcgdGhlIGNvbG9yIG9mIHRoZSB0ZXh0ICovCiAgICB2YXIgZ2V0VGV4dENvbG9yOwogICAgZnVuY3Rpb24gcmFuZG9tX2hzbF9jb2xvcihtaW4sIG1heCkgewogICAgICByZXR1cm4gJ2hzbCgnICsKICAgICAgICAoTWF0aC5yYW5kb20oKSAqIDM2MCkudG9GaXhlZCgpICsgJywnICsKICAgICAgICAoTWF0aC5yYW5kb20oKSAqIDMwICsgNzApLnRvRml4ZWQoKSArICclLCcgKwogICAgICAgIChNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbikgKyBtaW4pLnRvRml4ZWQoKSArICclKSc7CiAgICB9CiAgICBzd2l0Y2ggKHNldHRpbmdzLmNvbG9yKSB7CiAgICAgIGNhc2UgJ3JhbmRvbS1kYXJrJzoKICAgICAgICBnZXRUZXh0Q29sb3IgPSBmdW5jdGlvbiBnZXRSYW5kb21EYXJrQ29sb3IoKSB7CiAgICAgICAgICByZXR1cm4gcmFuZG9tX2hzbF9jb2xvcigxMCwgNTApOwogICAgICAgIH07CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlICdyYW5kb20tbGlnaHQnOgogICAgICAgIGdldFRleHRDb2xvciA9IGZ1bmN0aW9uIGdldFJhbmRvbUxpZ2h0Q29sb3IoKSB7CiAgICAgICAgICByZXR1cm4gcmFuZG9tX2hzbF9jb2xvcig1MCwgOTApOwogICAgICAgIH07CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIGlmICh0eXBlb2Ygc2V0dGluZ3MuY29sb3IgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgIGdldFRleHRDb2xvciA9IHNldHRpbmdzLmNvbG9yOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBmdW5jdGlvbiBmb3IgZ2V0dGluZyB0aGUgY2xhc3NlcyBvZiB0aGUgdGV4dCAqLwogICAgdmFyIGdldFRleHRDbGFzc2VzID0gbnVsbDsKICAgIGlmICh0eXBlb2Ygc2V0dGluZ3MuY2xhc3NlcyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICBnZXRUZXh0Q2xhc3NlcyA9IHNldHRpbmdzLmNsYXNzZXM7CiAgICB9CgogICAgLyogSW50ZXJhY3RpdmUgKi8KICAgIHZhciBpbnRlcmFjdGl2ZSA9IGZhbHNlOwogICAgdmFyIGluZm9HcmlkID0gW107CiAgICB2YXIgaG92ZXJlZDsKCiAgICB2YXIgZ2V0SW5mb0dyaWRGcm9tTW91c2VUb3VjaEV2ZW50ID0KICAgIGZ1bmN0aW9uIGdldEluZm9HcmlkRnJvbU1vdXNlVG91Y2hFdmVudChldnQpIHsKICAgICAgdmFyIGNhbnZhcyA9IGV2dC5jdXJyZW50VGFyZ2V0OwogICAgICB2YXIgcmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgdmFyIGNsaWVudFg7CiAgICAgIHZhciBjbGllbnRZOwogICAgICAvKiogRGV0ZWN0IGlmIHRvdWNoZXMgYXJlIGF2YWlsYWJsZSAqLwogICAgICBpZiAoZXZ0LnRvdWNoZXMpIHsKICAgICAgICBjbGllbnRYID0gZXZ0LnRvdWNoZXNbMF0uY2xpZW50WDsKICAgICAgICBjbGllbnRZID0gZXZ0LnRvdWNoZXNbMF0uY2xpZW50WTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjbGllbnRYID0gZXZ0LmNsaWVudFg7CiAgICAgICAgY2xpZW50WSA9IGV2dC5jbGllbnRZOwogICAgICB9CiAgICAgIHZhciBldmVudFggPSBjbGllbnRYIC0gcmVjdC5sZWZ0OwogICAgICB2YXIgZXZlbnRZID0gY2xpZW50WSAtIHJlY3QudG9wOwoKICAgICAgdmFyIHggPSBNYXRoLmZsb29yKGV2ZW50WCAqICgoY2FudmFzLndpZHRoIC8gcmVjdC53aWR0aCkgfHwgMSkgLyBnKTsKICAgICAgdmFyIHkgPSBNYXRoLmZsb29yKGV2ZW50WSAqICgoY2FudmFzLmhlaWdodCAvIHJlY3QuaGVpZ2h0KSB8fCAxKSAvIGcpOwoKICAgICAgcmV0dXJuIGluZm9HcmlkW3hdW3ldOwogICAgfTsKCiAgICB2YXIgd29yZGNsb3VkaG92ZXIgPSBmdW5jdGlvbiB3b3JkY2xvdWRob3ZlcihldnQpIHsKICAgICAgdmFyIGluZm8gPSBnZXRJbmZvR3JpZEZyb21Nb3VzZVRvdWNoRXZlbnQoZXZ0KTsKCiAgICAgIGlmIChob3ZlcmVkID09PSBpbmZvKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICBob3ZlcmVkID0gaW5mbzsKICAgICAgaWYgKCFpbmZvKSB7CiAgICAgICAgc2V0dGluZ3MuaG92ZXIodW5kZWZpbmVkLCB1bmRlZmluZWQsIGV2dCk7CgogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgc2V0dGluZ3MuaG92ZXIoaW5mby5pdGVtLCBpbmZvLmRpbWVuc2lvbiwgZXZ0KTsKCiAgICB9OwoKICAgIHZhciB3b3JkY2xvdWRjbGljayA9IGZ1bmN0aW9uIHdvcmRjbG91ZGNsaWNrKGV2dCkgewogICAgICB2YXIgaW5mbyA9IGdldEluZm9HcmlkRnJvbU1vdXNlVG91Y2hFdmVudChldnQpOwogICAgICBpZiAoIWluZm8pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIHNldHRpbmdzLmNsaWNrKGluZm8uaXRlbSwgaW5mby5kaW1lbnNpb24sIGV2dCk7CiAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpOwogICAgfTsKCiAgICAvKiBHZXQgcG9pbnRzIG9uIHRoZSBncmlkIGZvciBhIGdpdmVuIHJhZGl1cyBhd2F5IGZyb20gdGhlIGNlbnRlciAqLwogICAgdmFyIHBvaW50c0F0UmFkaXVzID0gW107CiAgICB2YXIgZ2V0UG9pbnRzQXRSYWRpdXMgPSBmdW5jdGlvbiBnZXRQb2ludHNBdFJhZGl1cyhyYWRpdXMpIHsKICAgICAgaWYgKHBvaW50c0F0UmFkaXVzW3JhZGl1c10pIHsKICAgICAgICByZXR1cm4gcG9pbnRzQXRSYWRpdXNbcmFkaXVzXTsKICAgICAgfQoKICAgICAgLy8gTG9vayBmb3IgdGhlc2UgbnVtYmVyIG9mIHBvaW50cyBvbiBlYWNoIHJhZGl1cwogICAgICB2YXIgVCA9IHJhZGl1cyAqIDg7CgogICAgICAvLyBHZXR0aW5nIGFsbCB0aGUgcG9pbnRzIGF0IHRoaXMgcmFkaXVzCiAgICAgIHZhciB0ID0gVDsKICAgICAgdmFyIHBvaW50cyA9IFtdOwoKICAgICAgaWYgKHJhZGl1cyA9PT0gMCkgewogICAgICAgIHBvaW50cy5wdXNoKFtjZW50ZXJbMF0sIGNlbnRlclsxXSwgMF0pOwogICAgICB9CgogICAgICB3aGlsZSAodC0tKSB7CiAgICAgICAgLy8gZGlzdG9ydCB0aGUgcmFkaXVzIHRvIHB1dCB0aGUgY2xvdWQgaW4gc2hhcGUKICAgICAgICB2YXIgcnggPSAxOwogICAgICAgIGlmIChzZXR0aW5ncy5zaGFwZSAhPT0gJ2NpcmNsZScpIHsKICAgICAgICAgIHJ4ID0gc2V0dGluZ3Muc2hhcGUodCAvIFQgKiAyICogTWF0aC5QSSk7IC8vIDAgdG8gMQogICAgICAgIH0KCiAgICAgICAgLy8gUHVzaCBbeCwgeSwgdF07IHQgaXMgdXNlZCBzb2xlbHkgZm9yIGdldFRleHRDb2xvcigpCiAgICAgICAgcG9pbnRzLnB1c2goWwogICAgICAgICAgY2VudGVyWzBdICsgcmFkaXVzICogcnggKiBNYXRoLmNvcygtdCAvIFQgKiAyICogTWF0aC5QSSksCiAgICAgICAgICBjZW50ZXJbMV0gKyByYWRpdXMgKiByeCAqIE1hdGguc2luKC10IC8gVCAqIDIgKiBNYXRoLlBJKSAqCiAgICAgICAgICAgIHNldHRpbmdzLmVsbGlwdGljaXR5LAogICAgICAgICAgdCAvIFQgKiAyICogTWF0aC5QSV0pOwogICAgICB9CgogICAgICBwb2ludHNBdFJhZGl1c1tyYWRpdXNdID0gcG9pbnRzOwogICAgICByZXR1cm4gcG9pbnRzOwogICAgfTsKCiAgICAvKiBSZXR1cm4gdHJ1ZSBpZiB3ZSBoYWQgc3BlbnQgdG9vIG11Y2ggdGltZSAqLwogICAgdmFyIGV4Y2VlZFRpbWUgPSBmdW5jdGlvbiBleGNlZWRUaW1lKCkgewogICAgICByZXR1cm4gKChzZXR0aW5ncy5hYm9ydFRocmVzaG9sZCA+IDApICYmCiAgICAgICAgKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLSBlc2NhcGVUaW1lID4gc2V0dGluZ3MuYWJvcnRUaHJlc2hvbGQpKTsKICAgIH07CgogICAgLyogR2V0IHRoZSBkZWcgb2Ygcm90YXRpb24gYWNjb3JkaW5nIHRvIHNldHRpbmdzLCBhbmQgbHVjay4gKi8KICAgIHZhciBnZXRSb3RhdGVEZWcgPSBmdW5jdGlvbiBnZXRSb3RhdGVEZWcoKSB7CiAgICAgIGlmIChzZXR0aW5ncy5yb3RhdGVSYXRpbyA9PT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgICB9CgogICAgICBpZiAoTWF0aC5yYW5kb20oKSA+IHNldHRpbmdzLnJvdGF0ZVJhdGlvKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KCiAgICAgIGlmIChyb3RhdGlvblJhbmdlID09PSAwKSB7CiAgICAgICAgcmV0dXJuIG1pblJvdGF0aW9uOwogICAgICB9CgogICAgICByZXR1cm4gbWluUm90YXRpb24gKyBNYXRoLnJhbmRvbSgpICogcm90YXRpb25SYW5nZTsKICAgIH07CgogICAgdmFyIGdldFRleHRJbmZvID0gZnVuY3Rpb24gZ2V0VGV4dEluZm8od29yZCwgd2VpZ2h0LCByb3RhdGVEZWcpIHsKICAgICAgLy8gY2FsY3VsYXRlIHRoZSBhY3V0YWwgZm9udCBzaXplCiAgICAgIC8vIGZvbnRTaXplID09PSAwIG1lYW5zIHdlaWdodEZhY3RvciBmdW5jdGlvbiB3YW50cyB0aGUgdGV4dCBza2lwcGVkLAogICAgICAvLyBhbmQgc2l6ZSA8IG1pblNpemUgbWVhbnMgd2UgY2Fubm90IGRyYXcgdGhlIHRleHQuCiAgICAgIHZhciBkZWJ1ZyA9IGZhbHNlOwogICAgICB2YXIgZm9udFNpemUgPSBzZXR0aW5ncy53ZWlnaHRGYWN0b3Iod2VpZ2h0KTsKICAgICAgaWYgKGZvbnRTaXplIDw9IHNldHRpbmdzLm1pblNpemUpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KCiAgICAgIC8vIFNjYWxlIGZhY3RvciBoZXJlIGlzIHRvIG1ha2Ugc3VyZSBmaWxsVGV4dCBpcyBub3QgbGltaXRlZCBieQogICAgICAvLyB0aGUgbWluaXVtIGZvbnQgc2l6ZSBzZXQgYnkgYnJvd3Nlci4KICAgICAgLy8gSXQgd2lsbCBhbHdheXMgYmUgMSBvciAybi4KICAgICAgdmFyIG11ID0gMTsKICAgICAgaWYgKGZvbnRTaXplIDwgbWluRm9udFNpemUpIHsKICAgICAgICBtdSA9IChmdW5jdGlvbiBjYWxjdWxhdGVTY2FsZUZhY3RvcigpIHsKICAgICAgICAgIHZhciBtdSA9IDI7CiAgICAgICAgICB3aGlsZSAobXUgKiBmb250U2l6ZSA8IG1pbkZvbnRTaXplKSB7CiAgICAgICAgICAgIG11ICs9IDI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gbXU7CiAgICAgICAgfSkoKTsKICAgICAgfQoKICAgICAgdmFyIGZjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTsKICAgICAgdmFyIGZjdHggPSBmY2FudmFzLmdldENvbnRleHQoJzJkJywgeyB3aWxsUmVhZEZyZXF1ZW50bHk6IHRydWUgfSk7CgogICAgICBmY3R4LmZvbnQgPSBzZXR0aW5ncy5mb250V2VpZ2h0ICsgJyAnICsKICAgICAgICAoZm9udFNpemUgKiBtdSkudG9TdHJpbmcoMTApICsgJ3B4ICcgKyBzZXR0aW5ncy5mb250RmFtaWx5OwoKICAgICAgLy8gRXN0aW1hdGUgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGV4dCB3aXRoIG1lYXN1cmVUZXh0KCkuCiAgICAgIHZhciBmdyA9IGZjdHgubWVhc3VyZVRleHQod29yZCkud2lkdGggLyBtdTsKICAgICAgdmFyIGZoID0gTWF0aC5tYXgoZm9udFNpemUgKiBtdSwKICAgICAgICAgICAgICAgICAgICAgICAgZmN0eC5tZWFzdXJlVGV4dCgnbScpLndpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICBmY3R4Lm1lYXN1cmVUZXh0KCdcdUZGMzcnKS53aWR0aCkgLyBtdTsKCiAgICAgIC8vIENyZWF0ZSBhIGJvdW5kYXJ5IGJveCB0aGF0IGlzIGxhcmdlciB0aGFuIG91ciBlc3RpbWF0ZXMsCiAgICAgIC8vIHNvIHRleHQgZG9uJ3QgZ2V0IGN1dCBvZiAoaXQgc2lsbCBtaWdodCkKICAgICAgdmFyIGJveFdpZHRoID0gZncgKyBmaCAqIDI7CiAgICAgIHZhciBib3hIZWlnaHQgPSBmaCAqIDM7CiAgICAgIHZhciBmZ3cgPSBNYXRoLmNlaWwoYm94V2lkdGggLyBnKTsKICAgICAgdmFyIGZnaCA9IE1hdGguY2VpbChib3hIZWlnaHQgLyBnKTsKICAgICAgYm94V2lkdGggPSBmZ3cgKiBnOwogICAgICBib3hIZWlnaHQgPSBmZ2ggKiBnOwoKICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBwcm9wZXIgb2Zmc2V0cyB0byBtYWtlIHRoZSB0ZXh0IGNlbnRlcmVkIGF0CiAgICAgIC8vIHRoZSBwcmVmZXJyZWQgcG9zaXRpb24uCgogICAgICAvLyBUaGlzIGlzIHNpbXBseSBoYWxmIG9mIHRoZSB3aWR0aC4KICAgICAgdmFyIGZpbGxUZXh0T2Zmc2V0WCA9IC0gZncgLyAyOwogICAgICAvLyBJbnN0ZWFkIG9mIG1vdmluZyB0aGUgYm94IHRvIHRoZSBleGFjdCBtaWRkbGUgb2YgdGhlIHByZWZlcnJlZAogICAgICAvLyBwb3NpdGlvbiwgZm9yIFktb2Zmc2V0IHdlIG1vdmUgMC40IGluc3RlYWQsIHNvIExhdGluIGFscGhhYmV0cyBsb29rCiAgICAgIC8vIHZlcnRpY2FsIGNlbnRlcmVkLgogICAgICB2YXIgZmlsbFRleHRPZmZzZXRZID0gLSBmaCAqIDAuNDsKCiAgICAgIC8vIENhbGN1bGF0ZSB0aGUgYWN0dWFsIGRpbWVuc2lvbiBvZiB0aGUgY2FudmFzLCBjb25zaWRlcmluZyB0aGUgcm90YXRpb24uCiAgICAgIHZhciBjZ2ggPSBNYXRoLmNlaWwoKGJveFdpZHRoICogTWF0aC5hYnMoTWF0aC5zaW4ocm90YXRlRGVnKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICBib3hIZWlnaHQgKiBNYXRoLmFicyhNYXRoLmNvcyhyb3RhdGVEZWcpKSkgLyBnKTsKICAgICAgdmFyIGNndyA9IE1hdGguY2VpbCgoYm94V2lkdGggKiBNYXRoLmFicyhNYXRoLmNvcyhyb3RhdGVEZWcpKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJveEhlaWdodCAqIE1hdGguYWJzKE1hdGguc2luKHJvdGF0ZURlZykpKSAvIGcpOwogICAgICB2YXIgd2lkdGggPSBjZ3cgKiBnOwogICAgICB2YXIgaGVpZ2h0ID0gY2doICogZzsKCiAgICAgIGZjYW52YXMuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHdpZHRoKTsKICAgICAgZmNhbnZhcy5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGhlaWdodCk7CgogICAgICBpZiAoZGVidWcpIHsKICAgICAgICAvLyBBdHRhY2ggZmNhbnZhcyB0byB0aGUgRE9NCiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmY2FudmFzKTsKICAgICAgICAvLyBTYXZlIGl0J3Mgc3RhdGUgc28gdGhhdCB3ZSBjb3VsZCByZXN0b3JlIGFuZCBkcmF3IHRoZSBncmlkIGNvcnJlY3RseS4KICAgICAgICBmY3R4LnNhdmUoKTsKICAgICAgfQoKICAgICAgLy8gU2NhbGUgdGhlIGNhbnZhcyB3aXRoIHxtdXwuCiAgICAgIGZjdHguc2NhbGUoMSAvIG11LCAxIC8gbXUpOwogICAgICBmY3R4LnRyYW5zbGF0ZSh3aWR0aCAqIG11IC8gMiwgaGVpZ2h0ICogbXUgLyAyKTsKICAgICAgZmN0eC5yb3RhdGUoLSByb3RhdGVEZWcpOwoKICAgICAgLy8gT25jZSB0aGUgd2lkdGgvaGVpZ2h0IGlzIHNldCwgY3R4IGluZm8gd2lsbCBiZSByZXNldC4KICAgICAgLy8gU2V0IGl0IGFnYWluIGhlcmUuCiAgICAgIGZjdHguZm9udCA9IHNldHRpbmdzLmZvbnRXZWlnaHQgKyAnICcgKwogICAgICAgIChmb250U2l6ZSAqIG11KS50b1N0cmluZygxMCkgKyAncHggJyArIHNldHRpbmdzLmZvbnRGYW1pbHk7CgogICAgICAvLyBGaWxsIHRoZSB0ZXh0IGludG8gdGhlIGZjYW52YXMuCiAgICAgIC8vIFhYWDogV2UgY2Fubm90IGJlY2F1c2UgdGV4dEJhc2VsaW5lID0gJ3RvcCcgaGVyZSBiZWNhdXNlCiAgICAgIC8vIEZpcmVmb3ggYW5kIENocm9tZSB1c2VzIGRpZmZlcmVudCBkZWZhdWx0IGxpbmUtaGVpZ2h0IGZvciBjYW52YXMuCiAgICAgIC8vIFBsZWFzZSByZWFkIGh0dHBzOi8vYnVnemlsLmxhLzczNzg1MiNjNi4KICAgICAgLy8gSGVyZSwgd2UgdXNlIHRleHRCYXNlbGluZSA9ICdtaWRkbGUnIGFuZCBkcmF3IHRoZSB0ZXh0IGF0IGV4YWN0bHkKICAgICAgLy8gMC41ICogZm9udFNpemUgbG93ZXIuCiAgICAgIGZjdHguZmlsbFN0eWxlID0gJyMwMDAnOwogICAgICBmY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnOwogICAgICBmY3R4LmZpbGxUZXh0KHdvcmQsIGZpbGxUZXh0T2Zmc2V0WCAqIG11LAogICAgICAgICAgICAgICAgICAgIChmaWxsVGV4dE9mZnNldFkgKyBmb250U2l6ZSAqIDAuNSkgKiBtdSk7CgogICAgICAvLyBHZXQgdGhlIHBpeGVscyBvZiB0aGUgdGV4dAogICAgICB2YXIgaW1hZ2VEYXRhID0gZmN0eC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCkuZGF0YTsKCiAgICAgIGlmIChleGNlZWRUaW1lKCkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KCiAgICAgIGlmIChkZWJ1ZykgewogICAgICAgIC8vIERyYXcgdGhlIGJveCBvZiB0aGUgb3JpZ2luYWwgZXN0aW1hdGlvbgogICAgICAgIGZjdHguc3Ryb2tlUmVjdChmaWxsVGV4dE9mZnNldFggKiBtdSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsbFRleHRPZmZzZXRZLCBmdyAqIG11LCBmaCAqIG11KTsKICAgICAgICBmY3R4LnJlc3RvcmUoKTsKICAgICAgfQoKICAgICAgLy8gUmVhZCB0aGUgcGl4ZWxzIGFuZCBzYXZlIHRoZSBpbmZvcm1hdGlvbiB0byB0aGUgb2NjdXBpZWQgYXJyYXkKICAgICAgdmFyIG9jY3VwaWVkID0gW107CiAgICAgIHZhciBneCA9IGNndywgZ3ksIHgsIHk7CiAgICAgIHZhciBib3VuZHMgPSBbY2doIC8gMiwgY2d3IC8gMiwgY2doIC8gMiwgY2d3IC8gMl07CiAgICAgIHdoaWxlIChneC0tKSB7CiAgICAgICAgZ3kgPSBjZ2g7CiAgICAgICAgd2hpbGUgKGd5LS0pIHsKICAgICAgICAgIHkgPSBnOwogICAgICAgICAgc2luZ2xlR3JpZExvb3A6IHsKICAgICAgICAgICAgd2hpbGUgKHktLSkgewogICAgICAgICAgICAgIHggPSBnOwogICAgICAgICAgICAgIHdoaWxlICh4LS0pIHsKICAgICAgICAgICAgICAgIGlmIChpbWFnZURhdGFbKChneSAqIGcgKyB5KSAqIHdpZHRoICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChneCAqIGcgKyB4KSkgKiA0ICsgM10pIHsKICAgICAgICAgICAgICAgICAgb2NjdXBpZWQucHVzaChbZ3gsIGd5XSk7CgogICAgICAgICAgICAgICAgICBpZiAoZ3ggPCBib3VuZHNbM10pIHsKICAgICAgICAgICAgICAgICAgICBib3VuZHNbM10gPSBneDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAoZ3ggPiBib3VuZHNbMV0pIHsKICAgICAgICAgICAgICAgICAgICBib3VuZHNbMV0gPSBneDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAoZ3kgPCBib3VuZHNbMF0pIHsKICAgICAgICAgICAgICAgICAgICBib3VuZHNbMF0gPSBneTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAoZ3kgPiBib3VuZHNbMl0pIHsKICAgICAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSBneTsKICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgaWYgKGRlYnVnKSB7CiAgICAgICAgICAgICAgICAgICAgZmN0eC5maWxsU3R5bGUgPSAncmdiYSgyNTUsIDAsIDAsIDAuNSknOwogICAgICAgICAgICAgICAgICAgIGZjdHguZmlsbFJlY3QoZ3ggKiBnLCBneSAqIGcsIGcgLSAwLjUsIGcgLSAwLjUpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrIHNpbmdsZUdyaWRMb29wOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZGVidWcpIHsKICAgICAgICAgICAgICBmY3R4LmZpbGxTdHlsZSA9ICdyZ2JhKDAsIDAsIDI1NSwgMC41KSc7CiAgICAgICAgICAgICAgZmN0eC5maWxsUmVjdChneCAqIGcsIGd5ICogZywgZyAtIDAuNSwgZyAtIDAuNSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmIChkZWJ1ZykgewogICAgICAgIGZjdHguZmlsbFN0eWxlID0gJ3JnYmEoMCwgMjU1LCAwLCAwLjUpJzsKICAgICAgICBmY3R4LmZpbGxSZWN0KGJvdW5kc1szXSAqIGcsCiAgICAgICAgICAgICAgICAgICAgICBib3VuZHNbMF0gKiBnLAogICAgICAgICAgICAgICAgICAgICAgKGJvdW5kc1sxXSAtIGJvdW5kc1szXSArIDEpICogZywKICAgICAgICAgICAgICAgICAgICAgIChib3VuZHNbMl0gLSBib3VuZHNbMF0gKyAxKSAqIGcpOwogICAgICB9CgogICAgICAvLyBSZXR1cm4gaW5mb3JtYXRpb24gbmVlZGVkIHRvIGNyZWF0ZSB0aGUgdGV4dCBvbiB0aGUgcmVhbCBjYW52YXMKICAgICAgcmV0dXJuIHsKICAgICAgICBtdTogbXUsCiAgICAgICAgb2NjdXBpZWQ6IG9jY3VwaWVkLAogICAgICAgIGJvdW5kczogYm91bmRzLAogICAgICAgIGd3OiBjZ3csCiAgICAgICAgZ2g6IGNnaCwKICAgICAgICBmaWxsVGV4dE9mZnNldFg6IGZpbGxUZXh0T2Zmc2V0WCwKICAgICAgICBmaWxsVGV4dE9mZnNldFk6IGZpbGxUZXh0T2Zmc2V0WSwKICAgICAgICBmaWxsVGV4dFdpZHRoOiBmdywKICAgICAgICBmaWxsVGV4dEhlaWdodDogZmgsCiAgICAgICAgZm9udFNpemU6IGZvbnRTaXplCiAgICAgIH07CiAgICB9OwoKICAgIC8qIERldGVybWluZSBpZiB0aGVyZSBpcyByb29tIGF2YWlsYWJsZSBpbiB0aGUgZ2l2ZW4gZGltZW5zaW9uICovCiAgICB2YXIgY2FuRml0VGV4dCA9IGZ1bmN0aW9uIGNhbkZpdFRleHQoZ3gsIGd5LCBndywgZ2gsIG9jY3VwaWVkKSB7CiAgICAgIC8vIEdvIHRocm91Z2ggdGhlIG9jY3VwaWVkIHBvaW50cywKICAgICAgLy8gcmV0dXJuIGZhbHNlIGlmIHRoZSBzcGFjZSBpcyBub3QgYXZhaWxhYmxlLgogICAgICB2YXIgaSA9IG9jY3VwaWVkLmxlbmd0aDsKICAgICAgd2hpbGUgKGktLSkgewogICAgICAgIHZhciBweCA9IGd4ICsgb2NjdXBpZWRbaV1bMF07CiAgICAgICAgdmFyIHB5ID0gZ3kgKyBvY2N1cGllZFtpXVsxXTsKCiAgICAgICAgaWYgKHB4ID49IG5neCB8fCBweSA+PSBuZ3kgfHwgcHggPCAwIHx8IHB5IDwgMCB8fCAhZ3JpZFtweF1bcHldKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB0cnVlOwogICAgfTsKCiAgICAvKiBBY3R1YWxseSBkcmF3IHRoZSB0ZXh0IG9uIHRoZSBncmlkICovCiAgICB2YXIgZHJhd1RleHQgPSBmdW5jdGlvbiBkcmF3VGV4dChneCwgZ3ksIGluZm8sIHdvcmQsIHdlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RhbmNlLCB0aGV0YSwgcm90YXRlRGVnLCBhdHRyaWJ1dGVzKSB7CgogICAgICB2YXIgZm9udFNpemUgPSBpbmZvLmZvbnRTaXplOwogICAgICB2YXIgY29sb3I7CiAgICAgIGlmIChnZXRUZXh0Q29sb3IpIHsKICAgICAgICBjb2xvciA9IGdldFRleHRDb2xvcih3b3JkLCB3ZWlnaHQsIGZvbnRTaXplLCBkaXN0YW5jZSwgdGhldGEpOwogICAgICB9IGVsc2UgaWYgKHNldHRpbmdzLmNvbG9yIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgICBjb2xvciA9IHNldHRpbmdzLmNvbG9yLnNoaWZ0KCkgfHwgJ2JsYWNrJzsgLy8gcGFzcyBhIGFycmF5IGluIHNldHRpbmcsIGRlZmF1bHQgJ2JsYWNrJwogICAgICB9IGVsc2UgewogICAgICAgIGNvbG9yID0gc2V0dGluZ3MuY29sb3I7CiAgICAgIH0KCiAgICAgIHZhciBjbGFzc2VzOwogICAgICBpZiAoZ2V0VGV4dENsYXNzZXMpIHsKICAgICAgICBjbGFzc2VzID0gZ2V0VGV4dENsYXNzZXMod29yZCwgd2VpZ2h0LCBmb250U2l6ZSwgZGlzdGFuY2UsIHRoZXRhKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjbGFzc2VzID0gc2V0dGluZ3MuY2xhc3NlczsKICAgICAgfQoKICAgICAgdmFyIGRpbWVuc2lvbjsKICAgICAgdmFyIGJvdW5kcyA9IGluZm8uYm91bmRzOwogICAgICBkaW1lbnNpb24gPSB7CiAgICAgICAgeDogKGd4ICsgYm91bmRzWzNdKSAqIGcsCiAgICAgICAgeTogKGd5ICsgYm91bmRzWzBdKSAqIGcsCiAgICAgICAgdzogKGJvdW5kc1sxXSAtIGJvdW5kc1szXSArIDEpICogZywKICAgICAgICBoOiAoYm91bmRzWzJdIC0gYm91bmRzWzBdICsgMSkgKiBnCiAgICAgIH07CgogICAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgaWYgKGVsLmdldENvbnRleHQpIHsKICAgICAgICAgIHZhciBjdHggPSBlbC5nZXRDb250ZXh0KCcyZCcpOwogICAgICAgICAgdmFyIG11ID0gaW5mby5tdTsKCiAgICAgICAgICAvLyBTYXZlIHRoZSBjdXJyZW50IHN0YXRlIGJlZm9yZSBtZXNzaW5nIGl0CiAgICAgICAgICBjdHguc2F2ZSgpOwogICAgICAgICAgY3R4LnNjYWxlKDEgLyBtdSwgMSAvIG11KTsKCiAgICAgICAgICBjdHguZm9udCA9IHNldHRpbmdzLmZvbnRXZWlnaHQgKyAnICcgKwogICAgICAgICAgICAgICAgICAgICAoZm9udFNpemUgKiBtdSkudG9TdHJpbmcoMTApICsgJ3B4ICcgKyBzZXR0aW5ncy5mb250RmFtaWx5OwogICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGNvbG9yOwoKICAgICAgICAgIC8vIFRyYW5zbGF0ZSB0aGUgY2FudmFzIHBvc2l0aW9uIHRvIHRoZSBvcmlnaW4gY29vcmRpbmF0ZSBvZiB3aGVyZQogICAgICAgICAgLy8gdGhlIHRleHQgc2hvdWxkIGJlIHB1dC4KICAgICAgICAgIGN0eC50cmFuc2xhdGUoKGd4ICsgaW5mby5ndyAvIDIpICogZyAqIG11LAogICAgICAgICAgICAgICAgICAgICAgICAoZ3kgKyBpbmZvLmdoIC8gMikgKiBnICogbXUpOwoKICAgICAgICAgIGlmIChyb3RhdGVEZWcgIT09IDApIHsKICAgICAgICAgICAgY3R4LnJvdGF0ZSgtIHJvdGF0ZURlZyk7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gRmluYWxseSwgZmlsbCB0aGUgdGV4dC4KCiAgICAgICAgICAvLyBYWFg6IFdlIGNhbm5vdCBiZWNhdXNlIHRleHRCYXNlbGluZSA9ICd0b3AnIGhlcmUgYmVjYXVzZQogICAgICAgICAgLy8gRmlyZWZveCBhbmQgQ2hyb21lIHVzZXMgZGlmZmVyZW50IGRlZmF1bHQgbGluZS1oZWlnaHQgZm9yIGNhbnZhcy4KICAgICAgICAgIC8vIFBsZWFzZSByZWFkIGh0dHBzOi8vYnVnemlsLmxhLzczNzg1MiNjNi4KICAgICAgICAgIC8vIEhlcmUsIHdlIHVzZSB0ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJyBhbmQgZHJhdyB0aGUgdGV4dCBhdCBleGFjdGx5CiAgICAgICAgICAvLyAwLjUgKiBmb250U2l6ZSBsb3dlci4KICAgICAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJzsKICAgICAgICAgIGN0eC5maWxsVGV4dCh3b3JkLCBpbmZvLmZpbGxUZXh0T2Zmc2V0WCAqIG11LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbmZvLmZpbGxUZXh0T2Zmc2V0WSArIGZvbnRTaXplICogMC41KSAqIG11KTsKCiAgICAgICAgICAvLyBUaGUgYmVsb3cgYm94IGlzIGFsd2F5cyBtYXRjaGVzIGhvdyA8c3Bhbj5zIGFyZSBwb3NpdGlvbmVkCiAgICAgICAgICAvKiBjdHguc3Ryb2tlUmVjdChpbmZvLmZpbGxUZXh0T2Zmc2V0WCwgaW5mby5maWxsVGV4dE9mZnNldFksCiAgICAgICAgICAgIGluZm8uZmlsbFRleHRXaWR0aCwgaW5mby5maWxsVGV4dEhlaWdodCk7ICovCgogICAgICAgICAgLy8gUmVzdG9yZSB0aGUgc3RhdGUuCiAgICAgICAgICBjdHgucmVzdG9yZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBkcmF3VGV4dCBvbiBESVYgZWxlbWVudAogICAgICAgICAgdmFyIHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7CiAgICAgICAgICB2YXIgdHJhbnNmb3JtUnVsZSA9ICcnOwogICAgICAgICAgdHJhbnNmb3JtUnVsZSA9ICdyb3RhdGUoJyArICgtIHJvdGF0ZURlZyAvIE1hdGguUEkgKiAxODApICsgJ2RlZykgJzsKICAgICAgICAgIGlmIChpbmZvLm11ICE9PSAxKSB7CiAgICAgICAgICAgIHRyYW5zZm9ybVJ1bGUgKz0KICAgICAgICAgICAgICAndHJhbnNsYXRlWCgtJyArIChpbmZvLmZpbGxUZXh0V2lkdGggLyA0KSArICdweCkgJyArCiAgICAgICAgICAgICAgJ3NjYWxlKCcgKyAoMSAvIGluZm8ubXUpICsgJyknOwogICAgICAgICAgfQogICAgICAgICAgdmFyIHN0eWxlUnVsZXMgPSB7CiAgICAgICAgICAgICdwb3NpdGlvbic6ICdhYnNvbHV0ZScsCiAgICAgICAgICAgICdkaXNwbGF5JzogJ2Jsb2NrJywKICAgICAgICAgICAgJ2ZvbnQnOiBzZXR0aW5ncy5mb250V2VpZ2h0ICsgJyAnICsKICAgICAgICAgICAgICAgICAgICAoZm9udFNpemUgKiBpbmZvLm11KSArICdweCAnICsgc2V0dGluZ3MuZm9udEZhbWlseSwKICAgICAgICAgICAgJ2xlZnQnOiAoKGd4ICsgaW5mby5ndyAvIDIpICogZyArIGluZm8uZmlsbFRleHRPZmZzZXRYKSArICdweCcsCiAgICAgICAgICAgICd0b3AnOiAoKGd5ICsgaW5mby5naCAvIDIpICogZyArIGluZm8uZmlsbFRleHRPZmZzZXRZKSArICdweCcsCiAgICAgICAgICAgICd3aWR0aCc6IGluZm8uZmlsbFRleHRXaWR0aCArICdweCcsCiAgICAgICAgICAgICdoZWlnaHQnOiBpbmZvLmZpbGxUZXh0SGVpZ2h0ICsgJ3B4JywKICAgICAgICAgICAgJ2xpbmVIZWlnaHQnOiBmb250U2l6ZSArICdweCcsCiAgICAgICAgICAgICd3aGl0ZVNwYWNlJzogJ25vd3JhcCcsCiAgICAgICAgICAgICd0cmFuc2Zvcm0nOiB0cmFuc2Zvcm1SdWxlLAogICAgICAgICAgICAnd2Via2l0VHJhbnNmb3JtJzogdHJhbnNmb3JtUnVsZSwKICAgICAgICAgICAgJ21zVHJhbnNmb3JtJzogdHJhbnNmb3JtUnVsZSwKICAgICAgICAgICAgJ3RyYW5zZm9ybU9yaWdpbic6ICc1MCUgNDAlJywKICAgICAgICAgICAgJ3dlYmtpdFRyYW5zZm9ybU9yaWdpbic6ICc1MCUgNDAlJywKICAgICAgICAgICAgJ21zVHJhbnNmb3JtT3JpZ2luJzogJzUwJSA0MCUnCiAgICAgICAgICB9OwogICAgICAgICAgaWYgKGNvbG9yKSB7CiAgICAgICAgICAgIHN0eWxlUnVsZXMuY29sb3IgPSBjb2xvcjsKICAgICAgICAgIH0KICAgICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSB3b3JkOwogICAgICAgICAgZm9yICh2YXIgY3NzUHJvcCBpbiBzdHlsZVJ1bGVzKSB7CiAgICAgICAgICAgIHNwYW4uc3R5bGVbY3NzUHJvcF0gPSBzdHlsZVJ1bGVzW2Nzc1Byb3BdOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUsIGF0dHJpYnV0ZXNbYXR0cmlidXRlXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmIChjbGFzc2VzKSB7CiAgICAgICAgICAgIHNwYW4uY2xhc3NOYW1lICs9IGNsYXNzZXM7CiAgICAgICAgICB9CiAgICAgICAgICBlbC5hcHBlbmRDaGlsZChzcGFuKTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfTsKCiAgICAvKiBIZWxwIGZ1bmN0aW9uIHRvIHVwZGF0ZUdyaWQgKi8KICAgIHZhciBmaWxsR3JpZEF0ID0gZnVuY3Rpb24gZmlsbEdyaWRBdCh4LCB5LCBkcmF3TWFzaywgZGltZW5zaW9uLCBpdGVtKSB7CiAgICAgIGlmICh4ID49IG5neCB8fCB5ID49IG5neSB8fCB4IDwgMCB8fCB5IDwgMCkgewogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgZ3JpZFt4XVt5XSA9IGZhbHNlOwoKICAgICAgaWYgKGRyYXdNYXNrKSB7CiAgICAgICAgdmFyIGN0eCA9IGVsZW1lbnRzWzBdLmdldENvbnRleHQoJzJkJyk7CiAgICAgICAgY3R4LmZpbGxSZWN0KHggKiBnLCB5ICogZywgbWFza1JlY3RXaWR0aCwgbWFza1JlY3RXaWR0aCk7CiAgICAgIH0KCiAgICAgIGlmIChpbnRlcmFjdGl2ZSkgewogICAgICAgIGluZm9HcmlkW3hdW3ldID0geyBpdGVtOiBpdGVtLCBkaW1lbnNpb246IGRpbWVuc2lvbiB9OwogICAgICB9CiAgICB9OwoKICAgIC8qIFVwZGF0ZSB0aGUgZmlsbGluZyBpbmZvcm1hdGlvbiBvZiB0aGUgZ2l2ZW4gc3BhY2Ugd2l0aCBvY2N1cGllZCBwb2ludHMuCiAgICAgICBEcmF3IHRoZSBtYXNrIG9uIHRoZSBjYW52YXMgaWYgbmVjZXNzYXJ5LiAqLwogICAgdmFyIHVwZGF0ZUdyaWQgPSBmdW5jdGlvbiB1cGRhdGVHcmlkKGd4LCBneSwgZ3csIGdoLCBpbmZvLCBpdGVtKSB7CiAgICAgIHZhciBvY2N1cGllZCA9IGluZm8ub2NjdXBpZWQ7CiAgICAgIHZhciBkcmF3TWFzayA9IHNldHRpbmdzLmRyYXdNYXNrOwogICAgICB2YXIgY3R4OwogICAgICBpZiAoZHJhd01hc2spIHsKICAgICAgICBjdHggPSBlbGVtZW50c1swXS5nZXRDb250ZXh0KCcyZCcpOwogICAgICAgIGN0eC5zYXZlKCk7CiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IHNldHRpbmdzLm1hc2tDb2xvcjsKICAgICAgfQoKICAgICAgdmFyIGRpbWVuc2lvbjsKICAgICAgaWYgKGludGVyYWN0aXZlKSB7CiAgICAgICAgdmFyIGJvdW5kcyA9IGluZm8uYm91bmRzOwogICAgICAgIGRpbWVuc2lvbiA9IHsKICAgICAgICAgIHg6IChneCArIGJvdW5kc1szXSkgKiBnLAogICAgICAgICAgeTogKGd5ICsgYm91bmRzWzBdKSAqIGcsCiAgICAgICAgICB3OiAoYm91bmRzWzFdIC0gYm91bmRzWzNdICsgMSkgKiBnLAogICAgICAgICAgaDogKGJvdW5kc1syXSAtIGJvdW5kc1swXSArIDEpICogZwogICAgICAgIH07CiAgICAgIH0KCiAgICAgIHZhciBpID0gb2NjdXBpZWQubGVuZ3RoOwogICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgZmlsbEdyaWRBdChneCArIG9jY3VwaWVkW2ldWzBdLCBneSArIG9jY3VwaWVkW2ldWzFdLAogICAgICAgICAgICAgICAgICAgZHJhd01hc2ssIGRpbWVuc2lvbiwgaXRlbSk7CiAgICAgIH0KCiAgICAgIGlmIChkcmF3TWFzaykgewogICAgICAgIGN0eC5yZXN0b3JlKCk7CiAgICAgIH0KICAgIH07CgogICAgLyogcHV0V29yZCgpIHByb2Nlc3NlcyBlYWNoIGl0ZW0gb24gdGhlIGxpc3QsCiAgICAgICBjYWxjdWxhdGUgaXQncyBzaXplIGFuZCBkZXRlcm1pbmUgaXQncyBwb3NpdGlvbiwgYW5kIGFjdHVhbGx5CiAgICAgICBwdXQgaXQgb24gdGhlIGNhbnZhcy4gKi8KICAgIHZhciBwdXRXb3JkID0gZnVuY3Rpb24gcHV0V29yZChpdGVtKSB7CiAgICAgIHZhciB3b3JkLCB3ZWlnaHQsIGF0dHJpYnV0ZXM7CiAgICAgIGlmIChBcnJheS5pc0FycmF5KGl0ZW0pKSB7CiAgICAgICAgd29yZCA9IGl0ZW1bMF07CiAgICAgICAgd2VpZ2h0ID0gaXRlbVsxXTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3b3JkID0gaXRlbS53b3JkOwogICAgICAgIHdlaWdodCA9IGl0ZW0ud2VpZ2h0OwogICAgICAgIGF0dHJpYnV0ZXMgPSBpdGVtLmF0dHJpYnV0ZXM7CiAgICAgIH0KICAgICAgdmFyIHJvdGF0ZURlZyA9IGdldFJvdGF0ZURlZygpOwoKICAgICAgLy8gZ2V0IGluZm8gbmVlZGVkIHRvIHB1dCB0aGUgdGV4dCBvbnRvIHRoZSBjYW52YXMKICAgICAgdmFyIGluZm8gPSBnZXRUZXh0SW5mbyh3b3JkLCB3ZWlnaHQsIHJvdGF0ZURlZyk7CgogICAgICAvLyBub3QgZ2V0dGluZyB0aGUgaW5mbyBtZWFucyB3ZSBzaG91bGRuJ3QgYmUgZHJhd2luZyB0aGlzIG9uZS4KICAgICAgaWYgKCFpbmZvKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CgogICAgICBpZiAoZXhjZWVkVGltZSgpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CgogICAgICAvLyBTa2lwIHRoZSBsb29wIGlmIHdlIGhhdmUgYWxyZWFkeSBrbm93IHRoZSBib3VuZGluZyBib3ggb2YKICAgICAgLy8gd29yZCBpcyBsYXJnZXIgdGhhbiB0aGUgY2FudmFzLgogICAgICB2YXIgYm91bmRzID0gaW5mby5ib3VuZHM7CiAgICAgIGlmICgoYm91bmRzWzFdIC0gYm91bmRzWzNdICsgMSkgPiBuZ3ggfHwKICAgICAgICAoYm91bmRzWzJdIC0gYm91bmRzWzBdICsgMSkgPiBuZ3kpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KCiAgICAgIC8vIERldGVybWluZSB0aGUgcG9zaXRpb24gdG8gcHV0IHRoZSB0ZXh0IGJ5CiAgICAgIC8vIHN0YXJ0IGxvb2tpbmcgZm9yIHRoZSBuZWFyZXN0IHBvaW50cwogICAgICB2YXIgciA9IG1heFJhZGl1cyArIDE7CgogICAgICB2YXIgdHJ5VG9QdXRXb3JkQXRQb2ludCA9IGZ1bmN0aW9uKGd4eSkgewogICAgICAgIHZhciBneCA9IE1hdGguZmxvb3IoZ3h5WzBdIC0gaW5mby5ndyAvIDIpOwogICAgICAgIHZhciBneSA9IE1hdGguZmxvb3IoZ3h5WzFdIC0gaW5mby5naCAvIDIpOwogICAgICAgIHZhciBndyA9IGluZm8uZ3c7CiAgICAgICAgdmFyIGdoID0gaW5mby5naDsKCiAgICAgICAgLy8gSWYgd2UgY2Fubm90IGZpdCB0aGUgdGV4dCBhdCB0aGlzIHBvc2l0aW9uLCByZXR1cm4gZmFsc2UKICAgICAgICAvLyBhbmQgZ28gdG8gdGhlIG5leHQgcG9zaXRpb24uCiAgICAgICAgaWYgKCFjYW5GaXRUZXh0KGd4LCBneSwgZ3csIGdoLCBpbmZvLm9jY3VwaWVkKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gQWN0dWFsbHkgcHV0IHRoZSB0ZXh0IG9uIHRoZSBjYW52YXMKICAgICAgICBkcmF3VGV4dChneCwgZ3ksIGluZm8sIHdvcmQsIHdlaWdodCwKICAgICAgICAgICAgICAgICAobWF4UmFkaXVzIC0gciksIGd4eVsyXSwgcm90YXRlRGVnLCBhdHRyaWJ1dGVzKTsKCiAgICAgICAgLy8gTWFyayB0aGUgc3BhY2VzIG9uIHRoZSBncmlkIGFzIGZpbGxlZAogICAgICAgIHVwZGF0ZUdyaWQoZ3gsIGd5LCBndywgZ2gsIGluZm8sIGl0ZW0pOwoKICAgICAgICAvLyBSZXR1cm4gdHJ1ZSBzbyBzb21lKCkgd2lsbCBzdG9wIGFuZCBhbHNvIHJldHVybiB0cnVlLgogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9OwoKICAgICAgd2hpbGUgKHItLSkgewogICAgICAgIHZhciBwb2ludHMgPSBnZXRQb2ludHNBdFJhZGl1cyhtYXhSYWRpdXMgLSByKTsKCiAgICAgICAgaWYgKHNldHRpbmdzLnNodWZmbGUpIHsKICAgICAgICAgIHBvaW50cyA9IFtdLmNvbmNhdChwb2ludHMpOwogICAgICAgICAgc2h1ZmZsZUFycmF5KHBvaW50cyk7CiAgICAgICAgfQoKICAgICAgICAvLyBUcnkgdG8gZml0IHRoZSB3b3JkcyBieSBsb29raW5nIGF0IGVhY2ggcG9pbnQuCiAgICAgICAgLy8gYXJyYXkuc29tZSgpIHdpbGwgc3RvcCBhbmQgcmV0dXJuIHRydWUKICAgICAgICAvLyB3aGVuIHB1dFdvcmRBdFBvaW50KCkgcmV0dXJucyB0cnVlLgogICAgICAgIC8vIElmIGFsbCB0aGUgcG9pbnRzIHJldHVybnMgZmFsc2UsIGFycmF5LnNvbWUoKSByZXR1cm5zIGZhbHNlLgogICAgICAgIHZhciBkcmF3biA9IHBvaW50cy5zb21lKHRyeVRvUHV0V29yZEF0UG9pbnQpOwoKICAgICAgICBpZiAoZHJhd24pIHsKICAgICAgICAgIC8vIGxlYXZlIHB1dFdvcmQoKSBhbmQgcmV0dXJuIHRydWUKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgfQogICAgICAvLyB3ZSB0cmllZCBhbGwgZGlzdGFuY2VzIGJ1dCB0ZXh0IHdvbid0IGZpdCwgcmV0dXJuIGZhbHNlCiAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgLyogU2VuZCBET00gZXZlbnQgdG8gYWxsIGVsZW1lbnRzLiBXaWxsIHN0b3Agc2VuZGluZyBldmVudCBhbmQgcmV0dXJuCiAgICAgICBpZiB0aGUgcHJldmlvdXMgb25lIGlzIGNhbmNlbGVkIChmb3IgY2FuY2VsYWJsZSBldmVudHMpLiAqLwogICAgdmFyIHNlbmRFdmVudCA9IGZ1bmN0aW9uIHNlbmRFdmVudCh0eXBlLCBjYW5jZWxhYmxlLCBkZXRhaWwpIHsKICAgICAgaWYgKGNhbmNlbGFibGUpIHsKICAgICAgICByZXR1cm4gIWVsZW1lbnRzLnNvbWUoZnVuY3Rpb24oZWwpIHsKICAgICAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTsKICAgICAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQodHlwZSwgdHJ1ZSwgY2FuY2VsYWJsZSwgZGV0YWlsIHx8IHt9KTsKICAgICAgICAgIHJldHVybiAhZWwuZGlzcGF0Y2hFdmVudChldnQpOwogICAgICAgIH0sIHRoaXMpOwogICAgICB9IGVsc2UgewogICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWwpIHsKICAgICAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTsKICAgICAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQodHlwZSwgdHJ1ZSwgY2FuY2VsYWJsZSwgZGV0YWlsIHx8IHt9KTsKICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQoZXZ0KTsKICAgICAgICB9LCB0aGlzKTsKICAgICAgfQogICAgfTsKCiAgICAvKiBTdGFydCBkcmF3aW5nIG9uIGEgY2FudmFzICovCiAgICB2YXIgc3RhcnQgPSBmdW5jdGlvbiBzdGFydCgpIHsKICAgICAgLy8gRm9yIGRpbWVuc2lvbnMsIGNsZWFyQ2FudmFzIGV0Yy4sCiAgICAgIC8vIHdlIG9ubHkgY2FyZSBhYm91dCB0aGUgZmlyc3QgZWxlbWVudC4KICAgICAgdmFyIGNhbnZhcyA9IGVsZW1lbnRzWzBdOwoKICAgICAgaWYgKGNhbnZhcy5nZXRDb250ZXh0KSB7CiAgICAgICAgbmd4ID0gTWF0aC5mbG9vcihjYW52YXMud2lkdGggLyBnKTsKICAgICAgICBuZ3kgPSBNYXRoLmZsb29yKGNhbnZhcy5oZWlnaHQgLyBnKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB2YXIgcmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgICBuZ3ggPSBNYXRoLmZsb29yKHJlY3Qud2lkdGggLyBnKTsKICAgICAgICBuZ3kgPSBNYXRoLmZsb29yKHJlY3QuaGVpZ2h0IC8gZyk7CiAgICAgIH0KCiAgICAgIC8vIFNlbmRpbmcgYSB3b3JkY2xvdWRzdGFydCBldmVudCB3aGljaCBjYXVzZSB0aGUgcHJldmlvdXMgbG9vcCB0byBzdG9wLgogICAgICAvLyBEbyBub3RoaW5nIGlmIHRoZSBldmVudCBpcyBjYW5jZWxlZC4KICAgICAgaWYgKCFzZW5kRXZlbnQoJ3dvcmRjbG91ZHN0YXJ0JywgdHJ1ZSkpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIC8vIERldGVybWluZSB0aGUgY2VudGVyIG9mIHRoZSB3b3JkIGNsb3VkCiAgICAgIGNlbnRlciA9IChzZXR0aW5ncy5vcmlnaW4pID8KICAgICAgICBbc2V0dGluZ3Mub3JpZ2luWzBdL2csIHNldHRpbmdzLm9yaWdpblsxXS9nXSA6CiAgICAgICAgW25neCAvIDIsIG5neSAvIDJdOwoKICAgICAgLy8gTWF4aXVtIHJhZGl1cyB0byBsb29rIGZvciBzcGFjZQogICAgICBtYXhSYWRpdXMgPSBNYXRoLmZsb29yKE1hdGguc3FydChuZ3ggKiBuZ3ggKyBuZ3kgKiBuZ3kpKTsKCiAgICAgIC8qIENsZWFyIHRoZSBjYW52YXMgb25seSBpZiB0aGUgY2xlYXJDYW52YXMgaXMgc2V0LAogICAgICAgICBpZiBub3QsIHVwZGF0ZSB0aGUgZ3JpZCB0byB0aGUgY3VycmVudCBjYW52YXMgc3RhdGUgKi8KICAgICAgZ3JpZCA9IFtdOwoKICAgICAgdmFyIGd4LCBneSwgaTsKICAgICAgaWYgKCFjYW52YXMuZ2V0Q29udGV4dCB8fCBzZXR0aW5ncy5jbGVhckNhbnZhcykgewogICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWwpIHsKICAgICAgICAgIGlmIChlbC5nZXRDb250ZXh0KSB7CiAgICAgICAgICAgIHZhciBjdHggPSBlbC5nZXRDb250ZXh0KCcyZCcpOwogICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gc2V0dGluZ3MuYmFja2dyb3VuZENvbG9yOwogICAgICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIG5neCAqIChnICsgMSksIG5neSAqIChnICsgMSkpOwogICAgICAgICAgICBjdHguZmlsbFJlY3QoMCwgMCwgbmd4ICogKGcgKyAxKSwgbmd5ICogKGcgKyAxKSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbC50ZXh0Q29udGVudCA9ICcnOwogICAgICAgICAgICBlbC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBzZXR0aW5ncy5iYWNrZ3JvdW5kQ29sb3I7CiAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIC8qIGZpbGwgdGhlIGdyaWQgd2l0aCBlbXB0eSBzdGF0ZSAqLwogICAgICAgIGd4ID0gbmd4OwogICAgICAgIHdoaWxlIChneC0tKSB7CiAgICAgICAgICBncmlkW2d4XSA9IFtdOwogICAgICAgICAgZ3kgPSBuZ3k7CiAgICAgICAgICB3aGlsZSAoZ3ktLSkgewogICAgICAgICAgICBncmlkW2d4XVtneV0gPSB0cnVlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBEZXRlcm1pbmUgYmdQaXhlbCBieSBjcmVhdGluZwogICAgICAgICAgIGFub3RoZXIgY2FudmFzIGFuZCBmaWxsIHRoZSBzcGVjaWZpZWQgYmFja2dyb3VuZCBjb2xvci4gKi8KICAgICAgICB2YXIgYmN0eCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyk7CgogICAgICAgIGJjdHguZmlsbFN0eWxlID0gc2V0dGluZ3MuYmFja2dyb3VuZENvbG9yOwogICAgICAgIGJjdHguZmlsbFJlY3QoMCwgMCwgMSwgMSk7CiAgICAgICAgdmFyIGJnUGl4ZWwgPSBiY3R4LmdldEltYWdlRGF0YSgwLCAwLCAxLCAxKS5kYXRhOwoKICAgICAgICAvKiBSZWFkIGJhY2sgdGhlIHBpeGVscyBvZiB0aGUgY2FudmFzIHdlIGdvdCB0byB0ZWxsIHdoaWNoIHBhcnQgb2YgdGhlCiAgICAgICAgICAgY2FudmFzIGlzIGVtcHR5LgogICAgICAgICAgIChubyBjbGVhckNhbnZhcyBvbmx5IHdvcmtzIHdpdGggYSBjYW52YXMsIG5vdCBkaXZzKSAqLwogICAgICAgIHZhciBpbWFnZURhdGEgPQogICAgICAgICAgY2FudmFzLmdldENvbnRleHQoJzJkJykuZ2V0SW1hZ2VEYXRhKDAsIDAsIG5neCAqIGcsIG5neSAqIGcpLmRhdGE7CgogICAgICAgIGd4ID0gbmd4OwogICAgICAgIHZhciB4LCB5OwogICAgICAgIHdoaWxlIChneC0tKSB7CiAgICAgICAgICBncmlkW2d4XSA9IFtdOwogICAgICAgICAgZ3kgPSBuZ3k7CiAgICAgICAgICB3aGlsZSAoZ3ktLSkgewogICAgICAgICAgICB5ID0gZzsKICAgICAgICAgICAgc2luZ2xlR3JpZExvb3A6IHdoaWxlICh5LS0pIHsKICAgICAgICAgICAgICB4ID0gZzsKICAgICAgICAgICAgICB3aGlsZSAoeC0tKSB7CiAgICAgICAgICAgICAgICBpID0gNDsKICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICAgICAgICAgICAgaWYgKGltYWdlRGF0YVsoKGd5ICogZyArIHkpICogbmd4ICogZyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChneCAqIGcgKyB4KSkgKiA0ICsgaV0gIT09IGJnUGl4ZWxbaV0pIHsKICAgICAgICAgICAgICAgICAgICBncmlkW2d4XVtneV0gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhayBzaW5nbGVHcmlkTG9vcDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZ3JpZFtneF1bZ3ldICE9PSBmYWxzZSkgewogICAgICAgICAgICAgIGdyaWRbZ3hdW2d5XSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGltYWdlRGF0YSA9IGJjdHggPSBiZ1BpeGVsID0gdW5kZWZpbmVkOwogICAgICB9CgogICAgICAvLyBmaWxsIHRoZSBpbmZvR3JpZCB3aXRoIGVtcHR5IHN0YXRlIGlmIHdlIG5lZWQgaXQKICAgICAgaWYgKHNldHRpbmdzLmhvdmVyIHx8IHNldHRpbmdzLmNsaWNrKSB7CgogICAgICAgIGludGVyYWN0aXZlID0gdHJ1ZTsKCiAgICAgICAgLyogZmlsbCB0aGUgZ3JpZCB3aXRoIGVtcHR5IHN0YXRlICovCiAgICAgICAgZ3ggPSBuZ3ggKyAxOwogICAgICAgIHdoaWxlIChneC0tKSB7CiAgICAgICAgICBpbmZvR3JpZFtneF0gPSBbXTsKICAgICAgICB9CgogICAgICAgIGlmIChzZXR0aW5ncy5ob3ZlcikgewogICAgICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHdvcmRjbG91ZGhvdmVyKTsKICAgICAgICB9CgogICAgICAgIGlmIChzZXR0aW5ncy5jbGljaykgewogICAgICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgd29yZGNsb3VkY2xpY2spOwogICAgICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB3b3JkY2xvdWRjbGljayk7CiAgICAgICAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICB9KTsKICAgICAgICAgIGNhbnZhcy5zdHlsZS53ZWJraXRUYXBIaWdobGlnaHRDb2xvciA9ICdyZ2JhKDAsIDAsIDAsIDApJzsKICAgICAgICB9CgogICAgICAgIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCd3b3JkY2xvdWRzdGFydCcsIGZ1bmN0aW9uIHN0b3BJbnRlcmFjdGlvbigpIHsKICAgICAgICAgIGNhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCd3b3JkY2xvdWRzdGFydCcsIHN0b3BJbnRlcmFjdGlvbik7CgogICAgICAgICAgY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHdvcmRjbG91ZGhvdmVyKTsKICAgICAgICAgIGNhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHdvcmRjbG91ZGNsaWNrKTsKICAgICAgICAgIGhvdmVyZWQgPSB1bmRlZmluZWQ7CiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIGkgPSAwOwogICAgICB2YXIgbG9vcGluZ0Z1bmN0aW9uLCBzdG9wcGluZ0Z1bmN0aW9uOwogICAgICBpZiAoc2V0dGluZ3Mud2FpdCAhPT0gMCkgewogICAgICAgIGxvb3BpbmdGdW5jdGlvbiA9IHdpbmRvdy5zZXRUaW1lb3V0OwogICAgICAgIHN0b3BwaW5nRnVuY3Rpb24gPSB3aW5kb3cuY2xlYXJUaW1lb3V0OwogICAgICB9IGVsc2UgewogICAgICAgIGxvb3BpbmdGdW5jdGlvbiA9IHdpbmRvdy5zZXRJbW1lZGlhdGU7CiAgICAgICAgc3RvcHBpbmdGdW5jdGlvbiA9IHdpbmRvdy5jbGVhckltbWVkaWF0ZTsKICAgICAgfQoKICAgICAgdmFyIGFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7CiAgICAgICAgZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbihlbCkgewogICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcik7CiAgICAgICAgfSwgdGhpcyk7CiAgICAgIH07CgogICAgICB2YXIgcmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHsKICAgICAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKTsKICAgICAgICB9LCB0aGlzKTsKICAgICAgfTsKCiAgICAgIHZhciBhbm90aGVyV29yZENsb3VkU3RhcnQgPSBmdW5jdGlvbiBhbm90aGVyV29yZENsb3VkU3RhcnQoKSB7CiAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpOwogICAgICAgIHN0b3BwaW5nRnVuY3Rpb24odGltZXIpOwogICAgICB9OwoKICAgICAgYWRkRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpOwoKICAgICAgdmFyIHRpbWVyID0gbG9vcGluZ0Z1bmN0aW9uKGZ1bmN0aW9uIGxvb3AoKSB7CiAgICAgICAgaWYgKGkgPj0gc2V0dGluZ3MubGlzdC5sZW5ndGgpIHsKICAgICAgICAgIHN0b3BwaW5nRnVuY3Rpb24odGltZXIpOwogICAgICAgICAgc2VuZEV2ZW50KCd3b3JkY2xvdWRzdG9wJywgZmFsc2UpOwogICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpOwoKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZXNjYXBlVGltZSA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7CiAgICAgICAgdmFyIGRyYXduID0gcHV0V29yZChzZXR0aW5ncy5saXN0W2ldKTsKICAgICAgICB2YXIgY2FuY2VsZWQgPSAhc2VuZEV2ZW50KCd3b3JkY2xvdWRkcmF3bicsIHRydWUsIHsKICAgICAgICAgIGl0ZW06IHNldHRpbmdzLmxpc3RbaV0sIGRyYXduOiBkcmF3biB9KTsKICAgICAgICBpZiAoZXhjZWVkVGltZSgpIHx8IGNhbmNlbGVkKSB7CiAgICAgICAgICBzdG9wcGluZ0Z1bmN0aW9uKHRpbWVyKTsKICAgICAgICAgIHNldHRpbmdzLmFib3J0KCk7CiAgICAgICAgICBzZW5kRXZlbnQoJ3dvcmRjbG91ZGFib3J0JywgZmFsc2UpOwogICAgICAgICAgc2VuZEV2ZW50KCd3b3JkY2xvdWRzdG9wJywgZmFsc2UpOwogICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICAgICAgdGltZXIgPSBsb29waW5nRnVuY3Rpb24obG9vcCwgc2V0dGluZ3Mud2FpdCk7CiAgICAgIH0sIHNldHRpbmdzLndhaXQpOwogICAgfTsKCiAgICAvLyBBbGwgc2V0LCBzdGFydCB0aGUgZHJhd2luZwogICAgc3RhcnQoKTsKICB9OwoKICBXb3JkQ2xvdWQuaXNTdXBwb3J0ZWQgPSBpc1N1cHBvcnRlZDsKICBXb3JkQ2xvdWQubWluRm9udFNpemUgPSBtaW5Gb250U2l6ZTsKCiAgLy8gRXhwb3NlIHRoZSBsaWJyYXJ5IGFzIGFuIEFNRCBtb2R1bGUKICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7CiAgICBkZWZpbmUoJ3dvcmRjbG91ZCcsIFtdLCBmdW5jdGlvbigpIHsgcmV0dXJuIFdvcmRDbG91ZDsgfSk7CiAgfSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgbW9kdWxlLmV4cG9ydHMgPSBXb3JkQ2xvdWQ7CiAgfSBlbHNlIHsKICAgIGdsb2JhbC5Xb3JkQ2xvdWQgPSBXb3JkQ2xvdWQ7CiAgfQoKfSkodGhpcyk7IC8vanNoaW50IGlnbm9yZTpsaW5lCg==\"></script>\r\n",
"<script src=\"data:application/x-javascript;base64,Ly8gY3JlYXRlIGVsZW1lbnQKZnVuY3Rpb24gbmV3bGFiZWwoZWwpewogIHZhciBuZXdEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICB2YXIgbmV3U3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsKICBuZXdEaXYuaWQgPSAnd2NMYWJlbCc7CiAgbmV3U3Bhbi5pZCA9ICJ3Y1NwYW4iOwogIGVsLmFwcGVuZENoaWxkKG5ld0Rpdik7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIndjTGFiZWwiKS5hcHBlbmRDaGlsZChuZXdTcGFuKTsKfQoKLy8gaG92ZXIgZnVuY3Rpb24KZnVuY3Rpb24gY3ZfaGFuZGxlSG92ZXIoaXRlbSwgZGltZW5zaW9uLCBldnQpIHsKICB2YXIgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgid2NMYWJlbCIpOwogIGlmICghaXRlbSkgewogICAgZWwuc2V0QXR0cmlidXRlKCdoaWRkZW4nLCB0cnVlKTsKCiAgICByZXR1cm47CiAgfQoKICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2hpZGRlbicpOwogIC8vIGNvbnNvbGUubG9nKGV2dC5zcmNFbGVtZW50Lm9mZnNldExlZnQpOwoKICBlbC5zdHlsZS5sZWZ0ID0gZGltZW5zaW9uLnggKyBldnQuc3JjRWxlbWVudC5vZmZzZXRMZWZ0ICsgJ3B4JzsKICBlbC5zdHlsZS50b3AgPSBkaW1lbnNpb24ueSArIGV2dC5zcmNFbGVtZW50Lm9mZnNldFRvcCArICdweCc7CiAgZWwuc3R5bGUud2lkdGggPSBkaW1lbnNpb24udyArICdweCc7CiAgZWwuc3R5bGUuaGVpZ2h0ID0gZGltZW5zaW9uLmggKyAncHgnOwoKICB0aGlzLmhvdmVyRGltZW5zaW9uID0gZGltZW5zaW9uOwoKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgid2NTcGFuIikuc2V0QXR0cmlidXRlKAogICAgJ2RhdGEtbDEwbi1hcmdzJywgSlNPTi5zdHJpbmdpZnkoeyB3b3JkOiBpdGVtWzBdLCBjb3VudDogaXRlbVsxXSB9KSk7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIndjU3BhbiIpLmlubmVySFRNTCA9aXRlbVswXSsiOiIgKyBpdGVtWzFdOwoKfQoKZnVuY3Rpb24gdXBkYXRlQ2FudmFzTWFzayhtYXNrQ2FudmFzKSB7CiAgICB2YXIgY3R4ID0gbWFza0NhbnZhcy5nZXRDb250ZXh0KCcyZCcpOwogICAgdmFyIGltYWdlRGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoCiAgICAgICAgMCwgMCwgbWFza0NhbnZhcy53aWR0aCwgbWFza0NhbnZhcy5oZWlnaHQpOwogICAgdmFyIG5ld0ltYWdlRGF0YSA9IGN0eC5jcmVhdGVJbWFnZURhdGEoaW1hZ2VEYXRhKTsKCiAgICB2YXIgdG9uZVN1bSA9IDA7CiAgICB2YXIgdG9uZUNudCA9IDA7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGltYWdlRGF0YS5kYXRhLmxlbmd0aDsgaSArPSA0KSB7CiAgICAgICAgdmFyIGFscGhhID0gaW1hZ2VEYXRhLmRhdGFbaSArIDNdOwogICAgICAgIGlmIChhbHBoYSA+IDEyOCkgewogICAgICAgICAgICB2YXIgdG9uZSA9IGltYWdlRGF0YS5kYXRhW2ldCiAgICAgICAgICAgICAgICArIGltYWdlRGF0YS5kYXRhW2kgKyAxXQogICAgICAgICAgICAgICAgKyBpbWFnZURhdGEuZGF0YVtpICsgMl07CiAgICAgICAgICAgIHRvbmVTdW0gKz0gdG9uZTsKICAgICAgICAgICAgKyt0b25lQ250OwogICAgICAgIH0KICAgIH0KICAgIHZhciB0aHJlc2hvbGQgPSB0b25lU3VtIC8gdG9uZUNudDsKCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGltYWdlRGF0YS5kYXRhLmxlbmd0aDsgaSArPSA0KSB7CiAgICAgICAgdmFyIHRvbmUgPSBpbWFnZURhdGEuZGF0YVtpXQogICAgICAgICAgICArIGltYWdlRGF0YS5kYXRhW2kgKyAxXQogICAgICAgICAgICArIGltYWdlRGF0YS5kYXRhW2kgKyAyXTsKICAgICAgICB2YXIgYWxwaGEgPSBpbWFnZURhdGEuZGF0YVtpICsgM107CgogICAgICAgIGlmIChhbHBoYSA8IDEyOCB8fCB0b25lID4gdGhyZXNob2xkKSB7CiAgICAgICAgICAgIC8vIEFyZWEgbm90IHRvIGRyYXcKICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaV0gPSAwOwogICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgMV0gPSAwOwogICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgMl0gPSAwOwogICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgM10gPSAwOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLy8gQXJlYSB0byBkcmF3CiAgICAgICAgICAgIC8vIFRoZSBjb2xvciBtdXN0IGJlIHNhbWUgd2l0aCBiYWNrZ3JvdW5kQ29sb3IKICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaV0gPSAyNTU7CiAgICAgICAgICAgIG5ld0ltYWdlRGF0YS5kYXRhW2kgKyAxXSA9IDI1NTsKICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaSArIDJdID0gMjU1OwogICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgM10gPSAyNTU7CiAgICAgICAgfQogICAgfQoKICAgIGN0eC5wdXRJbWFnZURhdGEobmV3SW1hZ2VEYXRhLCAwLCAwKTsKICAgIGNvbnNvbGUubG9nKG1hc2tDYW52YXMudG9EYXRhVVJMKCkpOwp9CgoKCi8vbWFzayBmdW5jdGlvbgpmdW5jdGlvbiBtYXNrSW5pdChlbCx4KXsKICBjb25zb2xlLmxvZygxKQogIHN0ciA9IHguZmlnQmFzZTY0OwogIC8vY29uc29sZS5sb2coc3RyKQogIHZhciBuZXdJbWcgPSBuZXcgSW1hZ2UoKTsKICBuZXdJbWcuc3JjID0gc3RyOwogIG5ld0ltZy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7CiAgbmV3SW1nLnN0eWxlLmxlZnQgPSAwOwogIC8vIGNvbnNvbGUubG9nKGVsLmNsaWVudEhlaWdodCk7CiAgbmV3SW1nLndpZHRoID0gZWwuY2xpZW50V2lkdGg7CiAgbmV3SW1nLmhlaWdodCA9IGVsLmNsaWVudEhlaWdodDsKICAvLyBtYXNrQ2FudmFzID0gaW5pdChlbCwgeCwgbmV3SW1nKTsKICB2dmFsdWUgPSAxMjgKCiAgY3R4ID0gZWwuZmlyc3RDaGlsZC5nZXRDb250ZXh0KCcyZCcpOwoKICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2UobmV3SW1nLCAwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpOwogICAgICAgICAgICAgICAgdXBkYXRlQ2FudmFzTWFzayhjdHgpOwoKCgoKCiAgICAgICAgICAgIFdvcmRDbG91ZChlbC5maXJzdENoaWxkLCB7IGxpc3Q6IGxpc3REYXRhLAogICAgICAgICAgICAgICAgICBmb250RmFtaWx5OiB4LmZvbnRGYW1pbHksCiAgICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IHguZm9udFdlaWdodCwKICAgICAgICAgICAgICAgICAgY29sb3I6IHguY29sb3IsCiAgICAgICAgICAgICAgICAgIG1pblNpemU6IHgubWluU2l6ZSwKICAgICAgICAgICAgICAgICAgd2VpZ2h0RmFjdG9yOiB4LndlaWdodEZhY3RvciwKICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB4LmJhY2tncm91bmRDb2xvciwKICAgICAgICAgICAgICAgICAgZ3JpZFNpemU6IHguZ3JpZFNpemUsCiAgICAgICAgICAgICAgICAgIG1pblJvdGF0aW9uOiB4Lm1pblJvdGF0aW9uLAogICAgICAgICAgICAgICAgICBtYXhSb3RhdGlvbjogeC5tYXhSb3RhdGlvbiwKICAgICAgICAgICAgICAgICAgc2h1ZmZsZTogeC5zaHVmZmxlLAogICAgICAgICAgICAgICAgICBzaGFwZTogeC5zaGFwZSwKICAgICAgICAgICAgICAgICAgcm90YXRlUmF0aW86IHgucm90YXRlUmF0aW8sCiAgICAgICAgICAgICAgICAgIGVsbGlwdGljaXR5OiB4LmVsbGlwdGljaXR5LAogICAgICAgICAgICAgICAgICBjbGVhckNhbnZhczogZmFsc2UsCiAgICAgICAgICAgICAgICAgIGRyYXdNYXNrOiB0cnVlLAogICAgICAgICAgICAgICAgICBob3ZlcjogeC5ob3ZlciB8fCBjdl9oYW5kbGVIb3ZlciwKICAgICAgICAgICAgICAgICAgYWJvcnRUaHJlc2hvbGQ6IDMwMDAKICAgICAgICAgICAgICAgICAgfSk7Cn0KCg==\"></script>\r\n",
"<script src=\"data:application/x-javascript;base64,SFRNTFdpZGdldHMud2lkZ2V0KHsKCiAgbmFtZTogJ3dvcmRjbG91ZDInLAoKICB0eXBlOiAnb3V0cHV0JywKCiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWwsIHdpZHRoLCBoZWlnaHQpIHsKICAgIHZhciBuZXdDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKTsKICAgIG5ld0NhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7CiAgICBuZXdDYW52YXMud2lkdGggPSB3aWR0aDsKICAgIG5ld0NhbnZhcy5pZCA9ICJjYW52YXMiOwoKICAgIGVsLmFwcGVuZENoaWxkKG5ld0NhbnZhcyk7CiAgICBuZXdsYWJlbChlbCk7CiAgICByZXR1cm4oZWwuZmlyc3RDaGlsZCk7CiAgfSwKICByZW5kZXJWYWx1ZTogZnVuY3Rpb24oZWwsIHgsIGluc3RhbmNlKSB7CiAgLy8gcGFyc2UgZ2V4ZiBkYXRhCiAgICAgICAgbGlzdERhdGE9W107CiAgICAgICAgZm9yKHZhciBpPTA7IGk8eC53b3JkLmxlbmd0aDsgaSsrKXsKICAgICAgICAgIGxpc3REYXRhLnB1c2goW3gud29yZFtpXSwgeC5mcmVxW2ldXSk7CiAgICAgICAgfQogICAgIGlmKHguZmlnQmFzZTY0KXsKCiAgICAgICAgbWFza0luaXQoZWwseCk7CiAgICAgICAgY29uc29sZS5sb2coMykKCiAgICAgIH1lbHNlewogICAgICAgIFdvcmRDbG91ZChlbC5maXJzdENoaWxkLCB7IGxpc3Q6IGxpc3REYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5OiB4LmZvbnRGYW1pbHksCiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IHguZm9udFdlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I6IHguY29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pblNpemU6IHgubWluU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgd2VpZ2h0RmFjdG9yOiB4LndlaWdodEZhY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB4LmJhY2tncm91bmRDb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgZ3JpZFNpemU6IHguZ3JpZFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pblJvdGF0aW9uOiB4Lm1pblJvdGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICBtYXhSb3RhdGlvbjogeC5tYXhSb3RhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgc2h1ZmZsZTogeC5zaHVmZmxlLAogICAgICAgICAgICAgICAgICAgICAgICBzaGFwZTogeC5zaGFwZSwKICAgICAgICAgICAgICAgICAgICAgICAgcm90YXRlUmF0aW86IHgucm90YXRlUmF0aW8sCiAgICAgICAgICAgICAgICAgICAgICAgIGVsbGlwdGljaXR5OiB4LmVsbGlwdGljaXR5LAogICAgICAgICAgICAgICAgICAgICAgICBkcmF3TWFzazogeC5kcmF3TWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgbWFza0NvbG9yOiB4Lm1hc2tDb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgbWFza0dhcFdpZHRoOiB4Lm1hc2tHYXBXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXI6IHguaG92ZXIgfHwgY3ZfaGFuZGxlSG92ZXIKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgIH0KICAgIH0sCiAgICAgIHJlc2l6ZTogZnVuY3Rpb24oZWwsIHdpZHRoLCBoZWlnaHQpIHsKICAgICAgfQoKfSk7Cg==\"></script>\r\n",
"</head>\r\n",
"<body style=\"background-color: white;\">\r\n",
"<div id=\"htmlwidget_container\">\r\n",
"<div id=\"htmlwidget-7819bbf000eff166a540\" class=\"wordcloud2 html-widget\" style=\"width:960px;height:500px;\">\r\n",
"\r\n",
"</div>\r\n",
"</div>\r\n",
"<script type=\"application/json\" data-for=\"htmlwidget-7819bbf000eff166a540\">{\"x\":{\"word\":[\"ooh\",\"makes\",\"wonder\",\"know\",\"will\",\"can\",\"lady\",\"stairway\",\"wind\",\"buying\",\"don\",\"get\",\"go\",\"gold\",\"heaven\",\"long\",\"one\",\"piper\",\"road\",\"sometimes\",\"stand\",\"still\",\"sure\",\"thoughts\",\"tune\",\"two\",\"wants\",\"alarmed\",\"blow\",\"brook\",\"bustle\",\"call\",\"calling\",\"came\",\"case\",\"cause\",\"change\",\"clean\",\"closed\",\"come\",\"crying\",\"dawn\",\"day\",\"dear\",\"echo\",\"everything\",\"feeling\",\"forests\",\"gets\",\"glitters\",\"hard\",\"head\",\"hear\",\"hedgerow\",\"humming\",\"join\",\"just\",\"knows\",\"last\",\"laughter\",\"lead\",\"leaving\",\"lies\",\"light\",\"listen\",\"look\",\"looking\",\"may\",\"meanings\",\"misgiven\",\"new\",\"now\",\"paths\",\"queen\",\"re\",\"really\",\"reason\",\"rings\",\"rock\",\"roll\",\"run\",\"seen\",\"shadows\",\"shines\",\"show\",\"sign\",\"sings\",\"smoke\",\"songbird\",\"soon\",\"soul\",\"spirit\",\"spring\",\"stores\",\"taller\",\"time\",\"tree\",\"trees\",\"turns\",\"us\",\"voices\",\"walks\",\"wall\",\"west\",\"whispered\",\"whispering\",\"white\",\"won\",\"word\",\"words\",\"yes\"],\"freq\":[6,5,5,4,4,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"fontFamily\":\"Segoe UI\",\"fontWeight\":\"bold\",\"color\":\"random-dark\",\"minSize\":0,\"weightFactor\":30,\"backgroundColor\":\"white\",\"gridSize\":0,\"minRotation\":-0.785398163397448,\"maxRotation\":0.785398163397448,\"shuffle\":true,\"rotateRatio\":0.4,\"shape\":\"circle\",\"ellipticity\":0.65,\"figBase64\":null,\"hover\":null},\"evals\":[],\"jsHooks\":{\"render\":[{\"code\":\"function(el,x){\\n console.log(123);\\n if(!iii){\\n window.location.reload();\\n iii = False;\\n\\n }\\n }\",\"data\":null}]}}</script>\r\n",
"<script type=\"application/htmlwidget-sizing\" data-for=\"htmlwidget-7819bbf000eff166a540\">{\"viewer\":{\"width\":450,\"height\":350,\"padding\":0,\"fill\":true},\"browser\":{\"width\":960,\"height\":500,\"padding\":0,\"fill\":true}}</script>\r\n",
"</body>\r\n",
"</html>\r\n"
],
"text/plain": [
"HTML widgets cannot be represented in plain text (need html)"
]
},
"metadata": {
"text/html": {
"isolated": true
}
},
"output_type": "display_data"
}
],
"source": [
"#import lyrics of 1st file\n",
"lyrics_word(scan(\"lyrics1.txt\",what=\"character\",sep=\"\\n\"))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<!DOCTYPE html>\r\n",
"<html>\r\n",
"<head>\r\n",
"<meta charset=\"utf-8\" />\r\n",
"<title>wordcloud2</title>\r\n",
"<script src=\"data:application/x-javascript;base64,KGZ1bmN0aW9uKCkgewogIC8vIElmIHdpbmRvdy5IVE1MV2lkZ2V0cyBpcyBhbHJlYWR5IGRlZmluZWQsIHRoZW4gdXNlIGl0OyBvdGhlcndpc2UgY3JlYXRlIGEKICAvLyBuZXcgb2JqZWN0LiBUaGlzIGFsbG93cyBwcmVjZWRpbmcgY29kZSB0byBzZXQgb3B0aW9ucyB0aGF0IGFmZmVjdCB0aGUKICAvLyBpbml0aWFsaXphdGlvbiBwcm9jZXNzICh0aG91Z2ggbm9uZSBjdXJyZW50bHkgZXhpc3QpLgogIHdpbmRvdy5IVE1MV2lkZ2V0cyA9IHdpbmRvdy5IVE1MV2lkZ2V0cyB8fCB7fTsKCiAgLy8gU2VlIGlmIHdlJ3JlIHJ1bm5pbmcgaW4gYSB2aWV3ZXIgcGFuZS4gSWYgbm90LCB3ZSdyZSBpbiBhIHdlYiBicm93c2VyLgogIHZhciB2aWV3ZXJNb2RlID0gd2luZG93LkhUTUxXaWRnZXRzLnZpZXdlck1vZGUgPQogICAgICAvXGJ2aWV3ZXJfcGFuZT0xXGIvLnRlc3Qod2luZG93LmxvY2F0aW9uKTsKCiAgLy8gU2VlIGlmIHdlJ3JlIHJ1bm5pbmcgaW4gU2hpbnkgbW9kZS4gSWYgbm90LCBpdCdzIGEgc3RhdGljIGRvY3VtZW50LgogIC8vIE5vdGUgdGhhdCBzdGF0aWMgd2lkZ2V0cyBjYW4gYXBwZWFyIGluIGJvdGggU2hpbnkgYW5kIHN0YXRpYyBtb2RlcywgYnV0CiAgLy8gb2J2aW91c2x5LCBTaGlueSB3aWRnZXRzIGNhbiBvbmx5IGFwcGVhciBpbiBTaGlueSBhcHBzL2RvY3VtZW50cy4KICB2YXIgc2hpbnlNb2RlID0gd2luZG93LkhUTUxXaWRnZXRzLnNoaW55TW9kZSA9CiAgICAgIHR5cGVvZih3aW5kb3cuU2hpbnkpICE9PSAidW5kZWZpbmVkIiAmJiAhIXdpbmRvdy5TaGlueS5vdXRwdXRCaW5kaW5nczsKCiAgLy8gV2UgY2FuJ3QgY291bnQgb24galF1ZXJ5IGJlaW5nIGF2YWlsYWJsZSwgc28gd2UgaW1wbGVtZW50IG91ciBvd24KICAvLyB2ZXJzaW9uIGlmIG5lY2Vzc2FyeS4KICBmdW5jdGlvbiBxdWVyeVNlbGVjdG9yQWxsKHNjb3BlLCBzZWxlY3RvcikgewogICAgaWYgKHR5cGVvZihqUXVlcnkpICE9PSAidW5kZWZpbmVkIiAmJiBzY29wZSBpbnN0YW5jZW9mIGpRdWVyeSkgewogICAgICByZXR1cm4gc2NvcGUuZmluZChzZWxlY3Rvcik7CiAgICB9CiAgICBpZiAoc2NvcGUucXVlcnlTZWxlY3RvckFsbCkgewogICAgICByZXR1cm4gc2NvcGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBhc0FycmF5KHZhbHVlKSB7CiAgICBpZiAodmFsdWUgPT09IG51bGwpCiAgICAgIHJldHVybiBbXTsKICAgIGlmICgkLmlzQXJyYXkodmFsdWUpKQogICAgICByZXR1cm4gdmFsdWU7CiAgICByZXR1cm4gW3ZhbHVlXTsKICB9CgogIC8vIEltcGxlbWVudCBqUXVlcnkncyBleHRlbmQKICBmdW5jdGlvbiBleHRlbmQodGFyZ2V0IC8qLCAuLi4gKi8pIHsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgcmV0dXJuIHRhcmdldDsKICAgIH0KICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07CiAgICAgIGZvciAodmFyIHByb3AgaW4gc291cmNlKSB7CiAgICAgICAgaWYgKHNvdXJjZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgewogICAgICAgICAgdGFyZ2V0W3Byb3BdID0gc291cmNlW3Byb3BdOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRhcmdldDsKICB9CgogIC8vIElFOCBkb2Vzbid0IHN1cHBvcnQgQXJyYXkuZm9yRWFjaC4KICBmdW5jdGlvbiBmb3JFYWNoKHZhbHVlcywgY2FsbGJhY2ssIHRoaXNBcmcpIHsKICAgIGlmICh2YWx1ZXMuZm9yRWFjaCkgewogICAgICB2YWx1ZXMuZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZyk7CiAgICB9IGVsc2UgewogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykgewogICAgICAgIGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdmFsdWVzW2ldLCBpLCB2YWx1ZXMpOwogICAgICB9CiAgICB9CiAgfQoKICAvLyBSZXBsYWNlcyB0aGUgc3BlY2lmaWVkIG1ldGhvZCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgZnVuY1NvdXJjZS4KICAvLwogIC8vIE5vdGUgdGhhdCBmdW5jU291cmNlIHNob3VsZCBub3QgQkUgdGhlIG5ldyBtZXRob2QsIGl0IHNob3VsZCBiZSBhIGZ1bmN0aW9uCiAgLy8gdGhhdCBSRVRVUk5TIHRoZSBuZXcgbWV0aG9kLiBmdW5jU291cmNlIHJlY2VpdmVzIGEgc2luZ2xlIGFyZ3VtZW50IHRoYXQgaXMKICAvLyB0aGUgb3ZlcnJpZGRlbiBtZXRob2QsIGl0IGNhbiBiZSBjYWxsZWQgZnJvbSB0aGUgbmV3IG1ldGhvZC4gVGhlIG92ZXJyaWRkZW4KICAvLyBtZXRob2QgY2FuIGJlIGNhbGxlZCBsaWtlIGEgcmVndWxhciBmdW5jdGlvbiwgaXQgaGFzIHRoZSB0YXJnZXQgcGVybWFuZW50bHkKICAvLyBib3VuZCB0byBpdCBzbyAidGhpcyIgd2lsbCB3b3JrIGNvcnJlY3RseS4KICBmdW5jdGlvbiBvdmVycmlkZU1ldGhvZCh0YXJnZXQsIG1ldGhvZE5hbWUsIGZ1bmNTb3VyY2UpIHsKICAgIHZhciBzdXBlckZ1bmMgPSB0YXJnZXRbbWV0aG9kTmFtZV0gfHwgZnVuY3Rpb24oKSB7fTsKICAgIHZhciBzdXBlckZ1bmNCb3VuZCA9IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gc3VwZXJGdW5jLmFwcGx5KHRhcmdldCwgYXJndW1lbnRzKTsKICAgIH07CiAgICB0YXJnZXRbbWV0aG9kTmFtZV0gPSBmdW5jU291cmNlKHN1cGVyRnVuY0JvdW5kKTsKICB9CgogIC8vIEFkZCBhIG1ldGhvZCB0byBkZWxlZ2F0b3IgdGhhdCwgd2hlbiBpbnZva2VkLCBjYWxscwogIC8vIGRlbGVnYXRlZS5tZXRob2ROYW1lLiBJZiB0aGVyZSBpcyBubyBzdWNoIG1ldGhvZCBvbgogIC8vIHRoZSBkZWxlZ2F0ZWUsIGJ1dCB0aGVyZSB3YXMgb25lIG9uIGRlbGVnYXRvciBiZWZvcmUKICAvLyBkZWxlZ2F0ZU1ldGhvZCB3YXMgY2FsbGVkLCB0aGVuIHRoZSBvcmlnaW5hbCB2ZXJzaW9uCiAgLy8gaXMgaW52b2tlZCBpbnN0ZWFkLgogIC8vIEZvciBleGFtcGxlOgogIC8vCiAgLy8gdmFyIGEgPSB7CiAgLy8gICBtZXRob2QxOiBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2ExJyk7IH0KICAvLyAgIG1ldGhvZDI6IGZ1bmN0aW9uKCkgeyBjb25zb2xlLmxvZygnYTInKTsgfQogIC8vIH07CiAgLy8gdmFyIGIgPSB7CiAgLy8gICBtZXRob2QxOiBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ2IxJyk7IH0KICAvLyB9OwogIC8vIGRlbGVnYXRlTWV0aG9kKGEsIGIsICJtZXRob2QxIik7CiAgLy8gZGVsZWdhdGVNZXRob2QoYSwgYiwgIm1ldGhvZDIiKTsKICAvLyBhLm1ldGhvZDEoKTsKICAvLyBhLm1ldGhvZDIoKTsKICAvLwogIC8vIFRoZSBvdXRwdXQgd291bGQgYmUgImIxIiwgImEyIi4KICBmdW5jdGlvbiBkZWxlZ2F0ZU1ldGhvZChkZWxlZ2F0b3IsIGRlbGVnYXRlZSwgbWV0aG9kTmFtZSkgewogICAgdmFyIGluaGVyaXRlZCA9IGRlbGVnYXRvclttZXRob2ROYW1lXTsKICAgIGRlbGVnYXRvclttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKCkgewogICAgICB2YXIgdGFyZ2V0ID0gZGVsZWdhdGVlOwogICAgICB2YXIgbWV0aG9kID0gZGVsZWdhdGVlW21ldGhvZE5hbWVdOwoKICAgICAgLy8gVGhlIG1ldGhvZCBkb2Vzbid0IGV4aXN0IG9uIHRoZSBkZWxlZ2F0ZWUuIEluc3RlYWQsCiAgICAgIC8vIGNhbGwgdGhlIG1ldGhvZCBvbiB0aGUgZGVsZWdhdG9yLCBpZiBpdCBleGlzdHMuCiAgICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgdGFyZ2V0ID0gZGVsZWdhdG9yOwogICAgICAgIG1ldGhvZCA9IGluaGVyaXRlZDsKICAgICAgfQoKICAgICAgaWYgKG1ldGhvZCkgewogICAgICAgIHJldHVybiBtZXRob2QuYXBwbHkodGFyZ2V0LCBhcmd1bWVudHMpOwogICAgICB9CiAgICB9OwogIH0KCiAgLy8gSW1wbGVtZW50IGEgdmFndWUgZmFjc2ltaWxpZSBvZiBqUXVlcnkncyBkYXRhIG1ldGhvZAogIGZ1bmN0aW9uIGVsZW1lbnREYXRhKGVsLCBuYW1lLCB2YWx1ZSkgewogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMikgewogICAgICByZXR1cm4gZWxbImh0bWx3aWRnZXRfZGF0YV8iICsgbmFtZV07CiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMykgewogICAgICBlbFsiaHRtbHdpZGdldF9kYXRhXyIgKyBuYW1lXSA9IHZhbHVlOwogICAgICByZXR1cm4gZWw7CiAgICB9IGVsc2UgewogICAgICB0aHJvdyBuZXcgRXJyb3IoIldyb25nIG51bWJlciBvZiBhcmd1bWVudHMgZm9yIGVsZW1lbnREYXRhOiAiICsKICAgICAgICBhcmd1bWVudHMubGVuZ3RoKTsKICAgIH0KICB9CgogIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzQ0NjE3MC9lc2NhcGUtc3RyaW5nLWZvci11c2UtaW4tamF2YXNjcmlwdC1yZWdleAogIGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cChzdHIpIHsKICAgIHJldHVybiBzdHIucmVwbGFjZSgvW1wtXFtcXVwvXHtcfVwoXClcKlwrXD9cLlxcXF5cJFx8XS9nLCAiXFwkJiIpOwogIH0KCiAgZnVuY3Rpb24gaGFzQ2xhc3MoZWwsIGNsYXNzTmFtZSkgewogICAgdmFyIHJlID0gbmV3IFJlZ0V4cCgiXFxiIiArIGVzY2FwZVJlZ0V4cChjbGFzc05hbWUpICsgIlxcYiIpOwogICAgcmV0dXJuIHJlLnRlc3QoZWwuY2xhc3NOYW1lKTsKICB9CgogIC8vIGVsZW1lbnRzIC0gYXJyYXkgKG9yIGFycmF5LWxpa2Ugb2JqZWN0KSBvZiBIVE1MIGVsZW1lbnRzCiAgLy8gY2xhc3NOYW1lIC0gY2xhc3MgbmFtZSB0byB0ZXN0IGZvcgogIC8vIGluY2x1ZGUgLSBpZiB0cnVlLCBvbmx5IHJldHVybiBlbGVtZW50cyB3aXRoIGdpdmVuIGNsYXNzTmFtZTsKICAvLyAgIGlmIGZhbHNlLCBvbmx5IHJldHVybiBlbGVtZW50cyAqd2l0aG91dCogZ2l2ZW4gY2xhc3NOYW1lCiAgZnVuY3Rpb24gZmlsdGVyQnlDbGFzcyhlbGVtZW50cywgY2xhc3NOYW1lLCBpbmNsdWRlKSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykgewogICAgICBpZiAoaGFzQ2xhc3MoZWxlbWVudHNbaV0sIGNsYXNzTmFtZSkgPT0gaW5jbHVkZSkKICAgICAgICByZXN1bHRzLnB1c2goZWxlbWVudHNbaV0pOwogICAgfQogICAgcmV0dXJuIHJlc3VsdHM7CiAgfQoKICBmdW5jdGlvbiBvbihvYmosIGV2ZW50TmFtZSwgZnVuYykgewogICAgaWYgKG9iai5hZGRFdmVudExpc3RlbmVyKSB7CiAgICAgIG9iai5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZnVuYywgZmFsc2UpOwogICAgfSBlbHNlIGlmIChvYmouYXR0YWNoRXZlbnQpIHsKICAgICAgb2JqLmF0dGFjaEV2ZW50KGV2ZW50TmFtZSwgZnVuYyk7CiAgICB9CiAgfQoKICBmdW5jdGlvbiBvZmYob2JqLCBldmVudE5hbWUsIGZ1bmMpIHsKICAgIGlmIChvYmoucmVtb3ZlRXZlbnRMaXN0ZW5lcikKICAgICAgb2JqLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBmdW5jLCBmYWxzZSk7CiAgICBlbHNlIGlmIChvYmouZGV0YWNoRXZlbnQpIHsKICAgICAgb2JqLmRldGFjaEV2ZW50KGV2ZW50TmFtZSwgZnVuYyk7CiAgICB9CiAgfQoKICAvLyBUcmFuc2xhdGUgYXJyYXkgb2YgdmFsdWVzIHRvIHRvcC9yaWdodC9ib3R0b20vbGVmdCwgYXMgdXN1YWwgd2l0aAogIC8vIHRoZSAicGFkZGluZyIgQ1NTIHByb3BlcnR5CiAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL3BhZGRpbmcKICBmdW5jdGlvbiB1bnBhY2tQYWRkaW5nKHZhbHVlKSB7CiAgICBpZiAodHlwZW9mKHZhbHVlKSA9PT0gIm51bWJlciIpCiAgICAgIHZhbHVlID0gW3ZhbHVlXTsKICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDEpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMF0sIGJvdHRvbTogdmFsdWVbMF0sIGxlZnQ6IHZhbHVlWzBdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDIpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMF0sIGxlZnQ6IHZhbHVlWzFdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDMpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMl0sIGxlZnQ6IHZhbHVlWzFdfTsKICAgIH0KICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDQpIHsKICAgICAgcmV0dXJuIHt0b3A6IHZhbHVlWzBdLCByaWdodDogdmFsdWVbMV0sIGJvdHRvbTogdmFsdWVbMl0sIGxlZnQ6IHZhbHVlWzNdfTsKICAgIH0KICB9CgogIC8vIENvbnZlcnQgYW4gdW5wYWNrZWQgcGFkZGluZyBvYmplY3QgdG8gYSBDU1MgdmFsdWUKICBmdW5jdGlvbiBwYWRkaW5nVG9Dc3MocGFkZGluZ09iaikgewogICAgcmV0dXJuIHBhZGRpbmdPYmoudG9wICsgInB4ICIgKyBwYWRkaW5nT2JqLnJpZ2h0ICsgInB4ICIgKyBwYWRkaW5nT2JqLmJvdHRvbSArICJweCAiICsgcGFkZGluZ09iai5sZWZ0ICsgInB4IjsKICB9CgogIC8vIE1ha2VzIGEgbnVtYmVyIHN1aXRhYmxlIGZvciBDU1MKICBmdW5jdGlvbiBweCh4KSB7CiAgICBpZiAodHlwZW9mKHgpID09PSAibnVtYmVyIikKICAgICAgcmV0dXJuIHggKyAicHgiOwogICAgZWxzZQogICAgICByZXR1cm4geDsKICB9CgogIC8vIFJldHJpZXZlcyBydW50aW1lIHdpZGdldCBzaXppbmcgaW5mb3JtYXRpb24gZm9yIGFuIGVsZW1lbnQuCiAgLy8gVGhlIHJldHVybiB2YWx1ZSBpcyBlaXRoZXIgbnVsbCwgb3IgYW4gb2JqZWN0IHdpdGggZmlsbCwgcGFkZGluZywKICAvLyBkZWZhdWx0V2lkdGgsIGRlZmF1bHRIZWlnaHQgZmllbGRzLgogIGZ1bmN0aW9uIHNpemluZ1BvbGljeShlbCkgewogICAgdmFyIHNpemluZ0VsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcigic2NyaXB0W2RhdGEtZm9yPSciICsgZWwuaWQgKyAiJ11bdHlwZT0nYXBwbGljYXRpb24vaHRtbHdpZGdldC1zaXppbmcnXSIpOwogICAgaWYgKCFzaXppbmdFbCkKICAgICAgcmV0dXJuIG51bGw7CiAgICB2YXIgc3AgPSBKU09OLnBhcnNlKHNpemluZ0VsLnRleHRDb250ZW50IHx8IHNpemluZ0VsLnRleHQgfHwgInt9Iik7CiAgICBpZiAodmlld2VyTW9kZSkgewogICAgICByZXR1cm4gc3Audmlld2VyOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIHNwLmJyb3dzZXI7CiAgICB9CiAgfQoKICAvLyBAcGFyYW0gdGFza3MgQXJyYXkgb2Ygc3RyaW5ncyAob3IgZmFsc3kgdmFsdWUsIGluIHdoaWNoIGNhc2Ugbm8tb3ApLgogIC8vICAgRWFjaCBlbGVtZW50IG11c3QgYmUgYSB2YWxpZCBKYXZhU2NyaXB0IGV4cHJlc3Npb24gdGhhdCB5aWVsZHMgYQogIC8vICAgZnVuY3Rpb24uIE9yLCBjYW4gYmUgYW4gYXJyYXkgb2Ygb2JqZWN0cyB3aXRoICJjb2RlIiBhbmQgImRhdGEiCiAgLy8gICBwcm9wZXJ0aWVzOyBpbiB0aGlzIGNhc2UsIHRoZSAiY29kZSIgcHJvcGVydHkgc2hvdWxkIGJlIGEgc3RyaW5nCiAgLy8gICBvZiBKUyB0aGF0J3MgYW4gZXhwciB0aGF0IHlpZWxkcyBhIGZ1bmN0aW9uLCBhbmQgImRhdGEiIHNob3VsZCBiZQogIC8vICAgYW4gb2JqZWN0IHRoYXQgd2lsbCBiZSBhZGRlZCBhcyBhbiBhZGRpdGlvbmFsIGFyZ3VtZW50IHdoZW4gdGhhdAogIC8vICAgZnVuY3Rpb24gaXMgY2FsbGVkLgogIC8vIEBwYXJhbSB0YXJnZXQgVGhlIG9iamVjdCB0aGF0IHdpbGwgYmUgInRoaXMiIGZvciBlYWNoIGZ1bmN0aW9uCiAgLy8gICBleGVjdXRpb24uCiAgLy8gQHBhcmFtIGFyZ3MgQXJyYXkgb2YgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb25zLiAoVGhlCiAgLy8gICBzYW1lIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBhbGwgZnVuY3Rpb25zLikKICBmdW5jdGlvbiBldmFsQW5kUnVuKHRhc2tzLCB0YXJnZXQsIGFyZ3MpIHsKICAgIGlmICh0YXNrcykgewogICAgICBmb3JFYWNoKHRhc2tzLCBmdW5jdGlvbih0YXNrKSB7CiAgICAgICAgdmFyIHRoZXNlQXJncyA9IGFyZ3M7CiAgICAgICAgaWYgKHR5cGVvZih0YXNrKSA9PT0gIm9iamVjdCIpIHsKICAgICAgICAgIHRoZXNlQXJncyA9IHRoZXNlQXJncy5jb25jYXQoW3Rhc2suZGF0YV0pOwogICAgICAgICAgdGFzayA9IHRhc2suY29kZTsKICAgICAgICB9CiAgICAgICAgdmFyIHRhc2tGdW5jID0gZXZhbCgiKCIgKyB0YXNrICsgIikiKTsKICAgICAgICBpZiAodHlwZW9mKHRhc2tGdW5jKSAhPT0gImZ1bmN0aW9uIikgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJUYXNrIG11c3QgYmUgYSBmdW5jdGlvbiEgU291cmNlOlxuIiArIHRhc2spOwogICAgICAgIH0KICAgICAgICB0YXNrRnVuYy5hcHBseSh0YXJnZXQsIHRoZXNlQXJncyk7CiAgICAgIH0pOwogICAgfQogIH0KCiAgZnVuY3Rpb24gaW5pdFNpemluZyhlbCkgewogICAgdmFyIHNpemluZyA9IHNpemluZ1BvbGljeShlbCk7CiAgICBpZiAoIXNpemluZykKICAgICAgcmV0dXJuOwoKICAgIHZhciBjZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaHRtbHdpZGdldF9jb250YWluZXIiKTsKICAgIGlmICghY2VsKQogICAgICByZXR1cm47CgogICAgaWYgKHR5cGVvZihzaXppbmcucGFkZGluZykgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUubWFyZ2luID0gIjAiOwogICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmcgPSBwYWRkaW5nVG9Dc3ModW5wYWNrUGFkZGluZyhzaXppbmcucGFkZGluZykpOwogICAgfQoKICAgIGlmIChzaXppbmcuZmlsbCkgewogICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gImhpZGRlbiI7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUuaGVpZ2h0ID0gIjEwMCUiOwogICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5oZWlnaHQgPSAiMTAwJSI7CiAgICAgIGlmIChjZWwpIHsKICAgICAgICBjZWwuc3R5bGUucG9zaXRpb24gPSAiYWJzb2x1dGUiOwogICAgICAgIHZhciBwYWQgPSB1bnBhY2tQYWRkaW5nKHNpemluZy5wYWRkaW5nKTsKICAgICAgICBjZWwuc3R5bGUudG9wID0gcGFkLnRvcCArICJweCI7CiAgICAgICAgY2VsLnN0eWxlLnJpZ2h0ID0gcGFkLnJpZ2h0ICsgInB4IjsKICAgICAgICBjZWwuc3R5bGUuYm90dG9tID0gcGFkLmJvdHRvbSArICJweCI7CiAgICAgICAgY2VsLnN0eWxlLmxlZnQgPSBwYWQubGVmdCArICJweCI7CiAgICAgICAgZWwuc3R5bGUud2lkdGggPSAiMTAwJSI7CiAgICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gIjEwMCUiOwogICAgICB9CgogICAgICByZXR1cm4gewogICAgICAgIGdldFdpZHRoOiBmdW5jdGlvbigpIHsgcmV0dXJuIGNlbC5vZmZzZXRXaWR0aDsgfSwKICAgICAgICBnZXRIZWlnaHQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gY2VsLm9mZnNldEhlaWdodDsgfQogICAgICB9OwoKICAgIH0gZWxzZSB7CiAgICAgIGVsLnN0eWxlLndpZHRoID0gcHgoc2l6aW5nLndpZHRoKTsKICAgICAgZWwuc3R5bGUuaGVpZ2h0ID0gcHgoc2l6aW5nLmhlaWdodCk7CgogICAgICByZXR1cm4gewogICAgICAgIGdldFdpZHRoOiBmdW5jdGlvbigpIHsgcmV0dXJuIGVsLm9mZnNldFdpZHRoOyB9LAogICAgICAgIGdldEhlaWdodDogZnVuY3Rpb24oKSB7IHJldHVybiBlbC5vZmZzZXRIZWlnaHQ7IH0KICAgICAgfTsKICAgIH0KICB9CgogIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb25zIGZvciBtZXRob2RzCiAgdmFyIGRlZmF1bHRzID0gewogICAgZmluZDogZnVuY3Rpb24oc2NvcGUpIHsKICAgICAgcmV0dXJuIHF1ZXJ5U2VsZWN0b3JBbGwoc2NvcGUsICIuIiArIHRoaXMubmFtZSk7CiAgICB9LAogICAgcmVuZGVyRXJyb3I6IGZ1bmN0aW9uKGVsLCBlcnIpIHsKICAgICAgdmFyICRlbCA9ICQoZWwpOwoKICAgICAgdGhpcy5jbGVhckVycm9yKGVsKTsKCiAgICAgIC8vIEFkZCBhbGwgdGhlc2UgZXJyb3IgY2xhc3NlcywgYXMgU2hpbnkgZG9lcwogICAgICB2YXIgZXJyQ2xhc3MgPSAic2hpbnktb3V0cHV0LWVycm9yIjsKICAgICAgaWYgKGVyci50eXBlICE9PSBudWxsKSB7CiAgICAgICAgLy8gdXNlIHRoZSBjbGFzc2VzIG9mIHRoZSBlcnJvciBjb25kaXRpb24gYXMgQ1NTIGNsYXNzIG5hbWVzCiAgICAgICAgZXJyQ2xhc3MgPSBlcnJDbGFzcyArICIgIiArICQubWFwKGFzQXJyYXkoZXJyLnR5cGUpLCBmdW5jdGlvbih0eXBlKSB7CiAgICAgICAgICByZXR1cm4gZXJyQ2xhc3MgKyAiLSIgKyB0eXBlOwogICAgICAgIH0pLmpvaW4oIiAiKTsKICAgICAgfQogICAgICBlcnJDbGFzcyA9IGVyckNsYXNzICsgIiBodG1sd2lkZ2V0cy1lcnJvciI7CgogICAgICAvLyBJcyBlbCBpbmxpbmUgb3IgYmxvY2s/IElmIGlubGluZSBvciBpbmxpbmUtYmxvY2ssIGp1c3QgZGlzcGxheTpub25lIGl0CiAgICAgIC8vIGFuZCBhZGQgYW4gaW5saW5lIGVycm9yLgogICAgICB2YXIgZGlzcGxheSA9ICRlbC5jc3MoImRpc3BsYXkiKTsKICAgICAgJGVsLmRhdGEoInJlc3RvcmUtZGlzcGxheS1tb2RlIiwgZGlzcGxheSk7CgogICAgICBpZiAoZGlzcGxheSA9PT0gImlubGluZSIgfHwgZGlzcGxheSA9PT0gImlubGluZS1ibG9jayIpIHsKICAgICAgICAkZWwuaGlkZSgpOwogICAgICAgIGlmIChlcnIubWVzc2FnZSAhPT0gIiIpIHsKICAgICAgICAgIHZhciBlcnJvclNwYW4gPSAkKCI8c3Bhbj4iKS5hZGRDbGFzcyhlcnJDbGFzcyk7CiAgICAgICAgICBlcnJvclNwYW4udGV4dChlcnIubWVzc2FnZSk7CiAgICAgICAgICAkZWwuYWZ0ZXIoZXJyb3JTcGFuKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoZGlzcGxheSA9PT0gImJsb2NrIikgewogICAgICAgIC8vIElmIGJsb2NrLCBhZGQgYW4gZXJyb3IganVzdCBhZnRlciB0aGUgZWwsIHNldCB2aXNpYmlsaXR5Om5vbmUgb24gdGhlCiAgICAgICAgLy8gZWwsIGFuZCBwb3NpdGlvbiB0aGUgZXJyb3IgdG8gYmUgb24gdG9wIG9mIHRoZSBlbC4KICAgICAgICAvLyBNYXJrIGl0IHdpdGggYSB1bmlxdWUgSUQgYW5kIENTUyBjbGFzcyBzbyB3ZSBjYW4gcmVtb3ZlIGl0IGxhdGVyLgogICAgICAgICRlbC5jc3MoInZpc2liaWxpdHkiLCAiaGlkZGVuIik7CiAgICAgICAgaWYgKGVyci5tZXNzYWdlICE9PSAiIikgewogICAgICAgICAgdmFyIGVycm9yRGl2ID0gJCgiPGRpdj4iKS5hZGRDbGFzcyhlcnJDbGFzcykuY3NzKCJwb3NpdGlvbiIsICJhYnNvbHV0ZSIpCiAgICAgICAgICAgIC5jc3MoInRvcCIsIGVsLm9mZnNldFRvcCkKICAgICAgICAgICAgLmNzcygibGVmdCIsIGVsLm9mZnNldExlZnQpCiAgICAgICAgICAgIC8vIHNldHRpbmcgd2lkdGggY2FuIHB1c2ggb3V0IHRoZSBwYWdlIHNpemUsIGZvcmNpbmcgb3RoZXJ3aXNlCiAgICAgICAgICAgIC8vIHVubmVjZXNzYXJ5IHNjcm9sbGJhcnMgdG8gYXBwZWFyIGFuZCBtYWtpbmcgaXQgaW1wb3NzaWJsZSBmb3IKICAgICAgICAgICAgLy8gdGhlIGVsZW1lbnQgdG8gc2hyaW5rOyBzbyB1c2UgbWF4LXdpZHRoIGluc3RlYWQKICAgICAgICAgICAgLmNzcygibWF4V2lkdGgiLCBlbC5vZmZzZXRXaWR0aCkKICAgICAgICAgICAgLmNzcygiaGVpZ2h0IiwgZWwub2Zmc2V0SGVpZ2h0KTsKICAgICAgICAgIGVycm9yRGl2LnRleHQoZXJyLm1lc3NhZ2UpOwogICAgICAgICAgJGVsLmFmdGVyKGVycm9yRGl2KTsKCiAgICAgICAgICAvLyBSZWFsbHkgZHVtYiB3YXkgdG8ga2VlcCB0aGUgc2l6ZS9wb3NpdGlvbiBvZiB0aGUgZXJyb3IgaW4gc3luYyB3aXRoCiAgICAgICAgICAvLyB0aGUgcGFyZW50IGVsZW1lbnQgYXMgdGhlIHdpbmRvdyBpcyByZXNpemVkIG9yIHdoYXRldmVyLgogICAgICAgICAgdmFyIGludElkID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICghZXJyb3JEaXZbMF0ucGFyZW50RWxlbWVudCkgewogICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50SWQpOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlcnJvckRpdgogICAgICAgICAgICAgIC5jc3MoInRvcCIsIGVsLm9mZnNldFRvcCkKICAgICAgICAgICAgICAuY3NzKCJsZWZ0IiwgZWwub2Zmc2V0TGVmdCkKICAgICAgICAgICAgICAuY3NzKCJtYXhXaWR0aCIsIGVsLm9mZnNldFdpZHRoKQogICAgICAgICAgICAgIC5jc3MoImhlaWdodCIsIGVsLm9mZnNldEhlaWdodCk7CiAgICAgICAgICB9LCA1MDApOwogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgIGNsZWFyRXJyb3I6IGZ1bmN0aW9uKGVsKSB7CiAgICAgIHZhciAkZWwgPSAkKGVsKTsKICAgICAgdmFyIGRpc3BsYXkgPSAkZWwuZGF0YSgicmVzdG9yZS1kaXNwbGF5LW1vZGUiKTsKICAgICAgJGVsLmRhdGEoInJlc3RvcmUtZGlzcGxheS1tb2RlIiwgbnVsbCk7CgogICAgICBpZiAoZGlzcGxheSA9PT0gImlubGluZSIgfHwgZGlzcGxheSA9PT0gImlubGluZS1ibG9jayIpIHsKICAgICAgICBpZiAoZGlzcGxheSkKICAgICAgICAgICRlbC5jc3MoImRpc3BsYXkiLCBkaXNwbGF5KTsKICAgICAgICAkKGVsLm5leHRTaWJsaW5nKS5maWx0ZXIoIi5odG1sd2lkZ2V0cy1lcnJvciIpLnJlbW92ZSgpOwogICAgICB9IGVsc2UgaWYgKGRpc3BsYXkgPT09ICJibG9jayIpewogICAgICAgICRlbC5jc3MoInZpc2liaWxpdHkiLCAiaW5oZXJpdCIpOwogICAgICAgICQoZWwubmV4dFNpYmxpbmcpLmZpbHRlcigiLmh0bWx3aWRnZXRzLWVycm9yIikucmVtb3ZlKCk7CiAgICAgIH0KICAgIH0sCiAgICBzaXppbmc6IHt9CiAgfTsKCiAgLy8gQ2FsbGVkIGJ5IHdpZGdldCBiaW5kaW5ncyB0byByZWdpc3RlciBhIG5ldyB0eXBlIG9mIHdpZGdldC4gVGhlIGRlZmluaXRpb24KICAvLyBvYmplY3QgY2FuIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOgogIC8vIC0gbmFtZSAocmVxdWlyZWQpIC0gQSBzdHJpbmcgaW5kaWNhdGluZyB0aGUgYmluZGluZyBuYW1lLCB3aGljaCB3aWxsIGJlCiAgLy8gICB1c2VkIGJ5IGRlZmF1bHQgYXMgdGhlIENTUyBjbGFzc25hbWUgdG8gbG9vayBmb3IuCiAgLy8gLSBpbml0aWFsaXplIChvcHRpb25hbCkgLSBBIGZ1bmN0aW9uKGVsKSB0aGF0IHdpbGwgYmUgY2FsbGVkIG9uY2UgcGVyCiAgLy8gICB3aWRnZXQgZWxlbWVudDsgaWYgYSB2YWx1ZSBpcyByZXR1cm5lZCwgaXQgd2lsbCBiZSBwYXNzZWQgYXMgdGhlIHRoaXJkCiAgLy8gICB2YWx1ZSB0byByZW5kZXJWYWx1ZS4KICAvLyAtIHJlbmRlclZhbHVlIChyZXF1aXJlZCkgLSBBIGZ1bmN0aW9uKGVsLCBkYXRhLCBpbml0VmFsdWUpIHRoYXQgd2lsbCBiZQogIC8vICAgY2FsbGVkIHdpdGggZGF0YS4gU3RhdGljIGNvbnRleHRzIHdpbGwgY2F1c2UgdGhpcyB0byBiZSBjYWxsZWQgb25jZSBwZXIKICAvLyAgIGVsZW1lbnQ7IFNoaW55IGFwcHMgd2lsbCBjYXVzZSB0aGlzIHRvIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyBwZXIKICAvLyAgIGVsZW1lbnQsIGFzIHRoZSBkYXRhIGNoYW5nZXMuCiAgd2luZG93LkhUTUxXaWRnZXRzLndpZGdldCA9IGZ1bmN0aW9uKGRlZmluaXRpb24pIHsKICAgIGlmICghZGVmaW5pdGlvbi5uYW1lKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIG5hbWUiKTsKICAgIH0KICAgIGlmICghZGVmaW5pdGlvbi50eXBlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIHR5cGUiKTsKICAgIH0KICAgIC8vIEN1cnJlbnRseSB3ZSBvbmx5IHN1cHBvcnQgb3V0cHV0IHdpZGdldHMKICAgIGlmIChkZWZpbml0aW9uLnR5cGUgIT09ICJvdXRwdXQiKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiVW5yZWNvZ25pemVkIHdpZGdldCB0eXBlICciICsgZGVmaW5pdGlvbi50eXBlICsgIiciKTsKICAgIH0KICAgIC8vIFRPRE86IFZlcmlmeSB0aGF0IC5uYW1lIGlzIGEgdmFsaWQgQ1NTIGNsYXNzbmFtZQoKICAgIC8vIFN1cHBvcnQgbmV3LXN0eWxlIGluc3RhbmNlLWJvdW5kIGRlZmluaXRpb25zLiBPbGQtc3R5bGUgY2xhc3MtYm91bmQKICAgIC8vIGRlZmluaXRpb25zIGhhdmUgb25lIHdpZGdldCAib2JqZWN0IiBwZXIgd2lkZ2V0IHBlciB0eXBlL2NsYXNzIG9mCiAgICAvLyB3aWRnZXQ7IHRoZSByZW5kZXJWYWx1ZSBhbmQgcmVzaXplIG1ldGhvZHMgb24gc3VjaCB3aWRnZXQgb2JqZWN0cwogICAgLy8gdGFrZSBlbCBhbmQgaW5zdGFuY2UgYXJndW1lbnRzLCBiZWNhdXNlIHRoZSB3aWRnZXQgb2JqZWN0IGNhbid0CiAgICAvLyBzdG9yZSB0aGVtLiBOZXctc3R5bGUgaW5zdGFuY2UtYm91bmQgZGVmaW5pdGlvbnMgaGF2ZSBvbmUgd2lkZ2V0CiAgICAvLyBvYmplY3QgcGVyIHdpZGdldCBpbnN0YW5jZTsgdGhlIGRlZmluaXRpb24gdGhhdCdzIHBhc3NlZCBpbiBkb2Vzbid0CiAgICAvLyBwcm92aWRlIHJlbmRlclZhbHVlIG9yIHJlc2l6ZSBtZXRob2RzIGF0IGFsbCwganVzdCB0aGUgc2luZ2xlIG1ldGhvZAogICAgLy8gICBmYWN0b3J5KGVsLCB3aWR0aCwgaGVpZ2h0KQogICAgLy8gd2hpY2ggcmV0dXJucyBhbiBvYmplY3QgdGhhdCBoYXMgcmVuZGVyVmFsdWUoeCkgYW5kIHJlc2l6ZSh3LCBoKS4KICAgIC8vIFRoaXMgZW5hYmxlcyBhIGZhciBtb3JlIG5hdHVyYWwgcHJvZ3JhbW1pbmcgc3R5bGUgZm9yIHRoZSB3aWRnZXQKICAgIC8vIGF1dGhvciwgd2hvIGNhbiBzdG9yZSBwZXItaW5zdGFuY2Ugc3RhdGUgdXNpbmcgZWl0aGVyIE9PLXN0eWxlCiAgICAvLyBpbnN0YW5jZSBmaWVsZHMgb3IgZnVuY3Rpb25hbC1zdHlsZSBjbG9zdXJlIHZhcmlhYmxlcyAoSSBndWVzcyB0aGlzCiAgICAvLyBpcyBpbiBjb250cmFzdCB0byB3aGF0IGNhbiBvbmx5IGJlIGNhbGxlZCBDLXN0eWxlIHBzZXVkby1PTyB3aGljaCBpcwogICAgLy8gd2hhdCB3ZSByZXF1aXJlZCBiZWZvcmUpLgogICAgaWYgKGRlZmluaXRpb24uZmFjdG9yeSkgewogICAgICBkZWZpbml0aW9uID0gY3JlYXRlTGVnYWN5RGVmaW5pdGlvbkFkYXB0ZXIoZGVmaW5pdGlvbik7CiAgICB9CgogICAgaWYgKCFkZWZpbml0aW9uLnJlbmRlclZhbHVlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiV2lkZ2V0IG11c3QgaGF2ZSBhIHJlbmRlclZhbHVlIGZ1bmN0aW9uIik7CiAgICB9CgogICAgLy8gRm9yIHN0YXRpYyByZW5kZXJpbmcgKG5vbi1TaGlueSksIHVzZSBhIHNpbXBsZSB3aWRnZXQgcmVnaXN0cmF0aW9uCiAgICAvLyBzY2hlbWUuIFdlIGFsc28gdXNlIHRoaXMgc2NoZW1lIGZvciBTaGlueSBhcHBzL2RvY3VtZW50cyB0aGF0IGFsc28KICAgIC8vIGNvbnRhaW4gc3RhdGljIHdpZGdldHMuCiAgICB3aW5kb3cuSFRNTFdpZGdldHMud2lkZ2V0cyA9IHdpbmRvdy5IVE1MV2lkZ2V0cy53aWRnZXRzIHx8IFtdOwogICAgLy8gTWVyZ2UgZGVmYXVsdHMgaW50byB0aGUgZGVmaW5pdGlvbjsgZG9uJ3QgbXV0YXRlIHRoZSBvcmlnaW5hbCBkZWZpbml0aW9uLgogICAgdmFyIHN0YXRpY0JpbmRpbmcgPSBleHRlbmQoe30sIGRlZmF1bHRzLCBkZWZpbml0aW9uKTsKICAgIG92ZXJyaWRlTWV0aG9kKHN0YXRpY0JpbmRpbmcsICJmaW5kIiwgZnVuY3Rpb24oc3VwZXJmdW5jKSB7CiAgICAgIHJldHVybiBmdW5jdGlvbihzY29wZSkgewogICAgICAgIHZhciByZXN1bHRzID0gc3VwZXJmdW5jKHNjb3BlKTsKICAgICAgICAvLyBGaWx0ZXIgb3V0IFNoaW55IG91dHB1dHMsIHdlIG9ubHkgd2FudCB0aGUgc3RhdGljIGtpbmQKICAgICAgICByZXR1cm4gZmlsdGVyQnlDbGFzcyhyZXN1bHRzLCAiaHRtbC13aWRnZXQtb3V0cHV0IiwgZmFsc2UpOwogICAgICB9OwogICAgfSk7CiAgICB3aW5kb3cuSFRNTFdpZGdldHMud2lkZ2V0cy5wdXNoKHN0YXRpY0JpbmRpbmcpOwoKICAgIGlmIChzaGlueU1vZGUpIHsKICAgICAgLy8gU2hpbnkgaXMgcnVubmluZy4gUmVnaXN0ZXIgdGhlIGRlZmluaXRpb24gd2l0aCBhbiBvdXRwdXQgYmluZGluZy4KICAgICAgLy8gVGhlIGRlZmluaXRpb24gaXRzZWxmIHdpbGwgbm90IGJlIHRoZSBvdXRwdXQgYmluZGluZywgaW5zdGVhZAogICAgICAvLyB3ZSB3aWxsIG1ha2UgYW4gb3V0cHV0IGJpbmRpbmcgb2JqZWN0IHRoYXQgZGVsZWdhdGVzIHRvIHRoZQogICAgICAvLyBkZWZpbml0aW9uLiBUaGlzIGlzIGJlY2F1c2Ugd2UgZm9vbGlzaGx5IHVzZWQgdGhlIHNhbWUgbWV0aG9kCiAgICAgIC8vIG5hbWUgKHJlbmRlclZhbHVlKSBmb3IgaHRtbHdpZGdldHMgZGVmaW5pdGlvbiBhbmQgU2hpbnkgYmluZGluZ3MKICAgICAgLy8gYnV0IHRoZXkgYWN0dWFsbHkgaGF2ZSBxdWl0ZSBkaWZmZXJlbnQgc2VtYW50aWNzICh0aGUgU2hpbnkKICAgICAgLy8gYmluZGluZ3MgcmVjZWl2ZSBkYXRhIHRoYXQgaW5jbHVkZXMgbG90cyBvZiBtZXRhZGF0YSB0aGF0IGl0CiAgICAgIC8vIHN0cmlwcyBvZmYgYmVmb3JlIGNhbGxpbmcgaHRtbHdpZGdldHMgcmVuZGVyVmFsdWUpLiBXZSBjYW4ndAogICAgICAvLyBqdXN0IGlnbm9yZSB0aGUgZGlmZmVyZW5jZSBiZWNhdXNlIGluIHNvbWUgd2lkZ2V0cyBpdCdzIGhlbHBmdWwKICAgICAgLy8gdG8gY2FsbCB0aGlzLnJlbmRlclZhbHVlKCkgZnJvbSBpbnNpZGUgb2YgcmVzaXplKCksIGFuZCBpZgogICAgICAvLyB3ZSdyZSBub3QgZGVsZWdhdGluZywgdGhlbiB0aGF0IGNhbGwgd2lsbCBnbyB0byB0aGUgU2hpbnkKICAgICAgLy8gdmVyc2lvbiBpbnN0ZWFkIG9mIHRoZSBodG1sd2lkZ2V0cyB2ZXJzaW9uLgoKICAgICAgLy8gTWVyZ2UgZGVmYXVsdHMgd2l0aCBkZWZpbml0aW9uLCB3aXRob3V0IG11dGF0aW5nIGVpdGhlci4KICAgICAgdmFyIGJpbmRpbmdEZWYgPSBleHRlbmQoe30sIGRlZmF1bHRzLCBkZWZpbml0aW9uKTsKCiAgICAgIC8vIFRoaXMgb2JqZWN0IHdpbGwgYmUgb3VyIGFjdHVhbCBTaGlueSBiaW5kaW5nLgogICAgICB2YXIgc2hpbnlCaW5kaW5nID0gbmV3IFNoaW55Lk91dHB1dEJpbmRpbmcoKTsKCiAgICAgIC8vIFdpdGggYSBmZXcgZXhjZXB0aW9ucywgd2UnbGwgd2FudCB0byBzaW1wbHkgdXNlIHRoZSBiaW5kaW5nRGVmJ3MKICAgICAgLy8gdmVyc2lvbiBvZiBtZXRob2RzIGlmIHRoZXkgYXJlIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGZhbGwgYmFjayB0bwogICAgICAvLyBTaGlueSdzIGRlZmF1bHRzLiBOT1RFOiBJZiBTaGlueSdzIG91dHB1dCBiaW5kaW5ncyBnYWluIGFkZGl0aW9uYWwKICAgICAgLy8gbWV0aG9kcyBpbiB0aGUgZnV0dXJlLCBhbmQgd2Ugd2FudCB0aGVtIHRvIGJlIG92ZXJyaWRlYWJsZSBieQogICAgICAvLyBIVE1MV2lkZ2V0IGJpbmRpbmcgZGVmaW5pdGlvbnMsIHRoZW4gd2UnbGwgbmVlZCB0byBhZGQgdGhlbSB0byB0aGlzCiAgICAgIC8vIGxpc3QuCiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgImdldElkIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgIm9uVmFsdWVDaGFuZ2UiKTsKICAgICAgZGVsZWdhdGVNZXRob2Qoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLCAib25WYWx1ZUVycm9yIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgInJlbmRlckVycm9yIik7CiAgICAgIGRlbGVnYXRlTWV0aG9kKHNoaW55QmluZGluZywgYmluZGluZ0RlZiwgImNsZWFyRXJyb3IiKTsKICAgICAgZGVsZWdhdGVNZXRob2Qoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLCAic2hvd1Byb2dyZXNzIik7CgogICAgICAvLyBUaGUgZmluZCwgcmVuZGVyVmFsdWUsIGFuZCByZXNpemUgYXJlIGhhbmRsZWQgZGlmZmVyZW50bHksIGJlY2F1c2Ugd2UKICAgICAgLy8gd2FudCB0byBhY3R1YWxseSBkZWNvcmF0ZSB0aGUgYmVoYXZpb3Igb2YgdGhlIGJpbmRpbmdEZWYgbWV0aG9kcy4KCiAgICAgIHNoaW55QmluZGluZy5maW5kID0gZnVuY3Rpb24oc2NvcGUpIHsKICAgICAgICB2YXIgcmVzdWx0cyA9IGJpbmRpbmdEZWYuZmluZChzY29wZSk7CgogICAgICAgIC8vIE9ubHkgcmV0dXJuIGVsZW1lbnRzIHRoYXQgYXJlIFNoaW55IG91dHB1dHMsIG5vdCBzdGF0aWMgb25lcwogICAgICAgIHZhciBkeW5hbWljUmVzdWx0cyA9IHJlc3VsdHMuZmlsdGVyKCIuaHRtbC13aWRnZXQtb3V0cHV0Iik7CgogICAgICAgIC8vIEl0J3MgcG9zc2libGUgdGhhdCB3aGF0ZXZlciBjYXVzZWQgU2hpbnkgdG8gdGhpbmsgdGhlcmUgbWlnaHQgYmUKICAgICAgICAvLyBuZXcgZHluYW1pYyBvdXRwdXRzLCBhbHNvIGNhdXNlZCB0aGVyZSB0byBiZSBuZXcgc3RhdGljIG91dHB1dHMuCiAgICAgICAgLy8gU2luY2UgdGhlcmUgbWlnaHQgYmUgbG90cyBvZiBkaWZmZXJlbnQgaHRtbHdpZGdldHMgYmluZGluZ3MsIHdlCiAgICAgICAgLy8gc2NoZWR1bGUgZXhlY3V0aW9uIGZvciBsYXRlci0tbm8gbmVlZCB0byBzdGF0aWNSZW5kZXIgbXVsdGlwbGUKICAgICAgICAvLyB0aW1lcy4KICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IGR5bmFtaWNSZXN1bHRzLmxlbmd0aCkKICAgICAgICAgIHNjaGVkdWxlU3RhdGljUmVuZGVyKCk7CgogICAgICAgIHJldHVybiBkeW5hbWljUmVzdWx0czsKICAgICAgfTsKCiAgICAgIC8vIFdyYXAgcmVuZGVyVmFsdWUgdG8gaGFuZGxlIGluaXRpYWxpemF0aW9uLCB3aGljaCB1bmZvcnR1bmF0ZWx5IGlzbid0CiAgICAgIC8vIHN1cHBvcnRlZCBuYXRpdmVseSBieSBTaGlueSBhdCB0aGUgdGltZSBvZiB0aGlzIHdyaXRpbmcuCgogICAgICBzaGlueUJpbmRpbmcucmVuZGVyVmFsdWUgPSBmdW5jdGlvbihlbCwgZGF0YSkgewogICAgICAgIFNoaW55LnJlbmRlckRlcGVuZGVuY2llcyhkYXRhLmRlcHMpOwogICAgICAgIC8vIFJlc29sdmUgc3RyaW5ncyBtYXJrZWQgYXMgamF2YXNjcmlwdCBsaXRlcmFscyB0byBvYmplY3RzCiAgICAgICAgaWYgKCEoZGF0YS5ldmFscyBpbnN0YW5jZW9mIEFycmF5KSkgZGF0YS5ldmFscyA9IFtkYXRhLmV2YWxzXTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgZGF0YS5ldmFscyAmJiBpIDwgZGF0YS5ldmFscy5sZW5ndGg7IGkrKykgewogICAgICAgICAgd2luZG93LkhUTUxXaWRnZXRzLmV2YWx1YXRlU3RyaW5nTWVtYmVyKGRhdGEueCwgZGF0YS5ldmFsc1tpXSk7CiAgICAgICAgfQogICAgICAgIGlmICghYmluZGluZ0RlZi5yZW5kZXJPbk51bGxWYWx1ZSkgewogICAgICAgICAgaWYgKGRhdGEueCA9PT0gbnVsbCkgewogICAgICAgICAgICBlbC5zdHlsZS52aXNpYmlsaXR5ID0gImhpZGRlbiI7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVsLnN0eWxlLnZpc2liaWxpdHkgPSAiaW5oZXJpdCI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghZWxlbWVudERhdGEoZWwsICJpbml0aWFsaXplZCIpKSB7CiAgICAgICAgICBpbml0U2l6aW5nKGVsKTsKCiAgICAgICAgICBlbGVtZW50RGF0YShlbCwgImluaXRpYWxpemVkIiwgdHJ1ZSk7CiAgICAgICAgICBpZiAoYmluZGluZ0RlZi5pbml0aWFsaXplKSB7CiAgICAgICAgICAgIHZhciByZXN1bHQgPSBiaW5kaW5nRGVmLmluaXRpYWxpemUoZWwsIGVsLm9mZnNldFdpZHRoLAogICAgICAgICAgICAgIGVsLm9mZnNldEhlaWdodCk7CiAgICAgICAgICAgIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiLCByZXN1bHQpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBiaW5kaW5nRGVmLnJlbmRlclZhbHVlKGVsLCBkYXRhLngsIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiKSk7CiAgICAgICAgZXZhbEFuZFJ1bihkYXRhLmpzSG9va3MucmVuZGVyLCBlbGVtZW50RGF0YShlbCwgImluaXRfcmVzdWx0IiksIFtlbCwgZGF0YS54XSk7CiAgICAgIH07CgogICAgICAvLyBPbmx5IG92ZXJyaWRlIHJlc2l6ZSBpZiBiaW5kaW5nRGVmIGltcGxlbWVudHMgaXQKICAgICAgaWYgKGJpbmRpbmdEZWYucmVzaXplKSB7CiAgICAgICAgc2hpbnlCaW5kaW5nLnJlc2l6ZSA9IGZ1bmN0aW9uKGVsLCB3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgICAvLyBTaGlueSBjYW4gY2FsbCByZXNpemUgYmVmb3JlIGluaXRpYWxpemUvcmVuZGVyVmFsdWUgaGF2ZSBiZWVuCiAgICAgICAgICAvLyBjYWxsZWQsIHdoaWNoIGRvZXNuJ3QgbWFrZSBzZW5zZSBmb3Igd2lkZ2V0cy4KICAgICAgICAgIGlmIChlbGVtZW50RGF0YShlbCwgImluaXRpYWxpemVkIikpIHsKICAgICAgICAgICAgYmluZGluZ0RlZi5yZXNpemUoZWwsIHdpZHRoLCBoZWlnaHQsIGVsZW1lbnREYXRhKGVsLCAiaW5pdF9yZXN1bHQiKSk7CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgfQoKICAgICAgU2hpbnkub3V0cHV0QmluZGluZ3MucmVnaXN0ZXIoc2hpbnlCaW5kaW5nLCBiaW5kaW5nRGVmLm5hbWUpOwogICAgfQogIH07CgogIHZhciBzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQgPSBudWxsOwogIGZ1bmN0aW9uIHNjaGVkdWxlU3RhdGljUmVuZGVyKCkgewogICAgaWYgKCFzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQpIHsKICAgICAgc2NoZWR1bGVTdGF0aWNSZW5kZXJUaW1lcklkID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgICAgICBzY2hlZHVsZVN0YXRpY1JlbmRlclRpbWVySWQgPSBudWxsOwogICAgICAgIHdpbmRvdy5IVE1MV2lkZ2V0cy5zdGF0aWNSZW5kZXIoKTsKICAgICAgfSwgMSk7CiAgICB9CiAgfQoKICAvLyBSZW5kZXIgc3RhdGljIHdpZGdldHMgYWZ0ZXIgdGhlIGRvY3VtZW50IGZpbmlzaGVzIGxvYWRpbmcKICAvLyBTdGF0aWNhbGx5IHJlbmRlciBhbGwgZWxlbWVudHMgdGhhdCBhcmUgb2YgdGhpcyB3aWRnZXQncyBjbGFzcwogIHdpbmRvdy5IVE1MV2lkZ2V0cy5zdGF0aWNSZW5kZXIgPSBmdW5jdGlvbigpIHsKICAgIHZhciBiaW5kaW5ncyA9IHdpbmRvdy5IVE1MV2lkZ2V0cy53aWRnZXRzIHx8IFtdOwogICAgZm9yRWFjaChiaW5kaW5ncywgZnVuY3Rpb24oYmluZGluZykgewogICAgICB2YXIgbWF0Y2hlcyA9IGJpbmRpbmcuZmluZChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpOwogICAgICBmb3JFYWNoKG1hdGNoZXMsIGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgdmFyIHNpemVPYmogPSBpbml0U2l6aW5nKGVsLCBiaW5kaW5nKTsKCiAgICAgICAgaWYgKGhhc0NsYXNzKGVsLCAiaHRtbC13aWRnZXQtc3RhdGljLWJvdW5kIikpCiAgICAgICAgICByZXR1cm47CiAgICAgICAgZWwuY2xhc3NOYW1lID0gZWwuY2xhc3NOYW1lICsgIiBodG1sLXdpZGdldC1zdGF0aWMtYm91bmQiOwoKICAgICAgICB2YXIgaW5pdFJlc3VsdDsKICAgICAgICBpZiAoYmluZGluZy5pbml0aWFsaXplKSB7CiAgICAgICAgICBpbml0UmVzdWx0ID0gYmluZGluZy5pbml0aWFsaXplKGVsLAogICAgICAgICAgICBzaXplT2JqID8gc2l6ZU9iai5nZXRXaWR0aCgpIDogZWwub2Zmc2V0V2lkdGgsCiAgICAgICAgICAgIHNpemVPYmogPyBzaXplT2JqLmdldEhlaWdodCgpIDogZWwub2Zmc2V0SGVpZ2h0CiAgICAgICAgICApOwogICAgICAgICAgZWxlbWVudERhdGEoZWwsICJpbml0X3Jlc3VsdCIsIGluaXRSZXN1bHQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGJpbmRpbmcucmVzaXplKSB7CiAgICAgICAgICB2YXIgbGFzdFNpemUgPSB7fTsKICAgICAgICAgIHZhciByZXNpemVIYW5kbGVyID0gZnVuY3Rpb24oZSkgewogICAgICAgICAgICB2YXIgc2l6ZSA9IHsKICAgICAgICAgICAgICB3OiBzaXplT2JqID8gc2l6ZU9iai5nZXRXaWR0aCgpIDogZWwub2Zmc2V0V2lkdGgsCiAgICAgICAgICAgICAgaDogc2l6ZU9iaiA/IHNpemVPYmouZ2V0SGVpZ2h0KCkgOiBlbC5vZmZzZXRIZWlnaHQKICAgICAgICAgICAgfTsKICAgICAgICAgICAgaWYgKHNpemUudyA9PT0gMCAmJiBzaXplLmggPT09IDApCiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBpZiAoc2l6ZS53ID09PSBsYXN0U2l6ZS53ICYmIHNpemUuaCA9PT0gbGFzdFNpemUuaCkKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIGxhc3RTaXplID0gc2l6ZTsKICAgICAgICAgICAgYmluZGluZy5yZXNpemUoZWwsIHNpemUudywgc2l6ZS5oLCBpbml0UmVzdWx0KTsKICAgICAgICAgIH07CgogICAgICAgICAgb24od2luZG93LCAicmVzaXplIiwgcmVzaXplSGFuZGxlcik7CgogICAgICAgICAgLy8gVGhpcyBpcyBuZWVkZWQgZm9yIGNhc2VzIHdoZXJlIHdlJ3JlIHJ1bm5pbmcgaW4gYSBTaGlueQogICAgICAgICAgLy8gYXBwLCBidXQgdGhlIHdpZGdldCBpdHNlbGYgaXMgbm90IGEgU2hpbnkgb3V0cHV0LCBidXQKICAgICAgICAgIC8vIHJhdGhlciBhIHNpbXBsZSBzdGF0aWMgd2lkZ2V0LiBPbmUgZXhhbXBsZSBvZiB0aGlzIGlzCiAgICAgICAgICAvLyBhbiBybWFya2Rvd24gZG9jdW1lbnQgdGhhdCBoYXMgcnVudGltZTpzaGlueSBhbmQgd2lkZ2V0CiAgICAgICAgICAvLyB0aGF0IGlzbid0IGluIGEgcmVuZGVyIGZ1bmN0aW9uLiBTaGlueSBvbmx5IGtub3dzIHRvCiAgICAgICAgICAvLyBjYWxsIHJlc2l6ZSBoYW5kbGVycyBmb3IgU2hpbnkgb3V0cHV0cywgbm90IGZvciBzdGF0aWMKICAgICAgICAgIC8vIHdpZGdldHMsIHNvIHdlIGRvIGl0IG91cnNlbHZlcy4KICAgICAgICAgIGlmICh3aW5kb3cualF1ZXJ5KSB7CiAgICAgICAgICAgIHdpbmRvdy5qUXVlcnkoZG9jdW1lbnQpLm9uKAogICAgICAgICAgICAgICJzaG93bi5odG1sd2lkZ2V0cyBzaG93bi5icy50YWIuaHRtbHdpZGdldHMgc2hvd24uYnMuY29sbGFwc2UuaHRtbHdpZGdldHMiLAogICAgICAgICAgICAgIHJlc2l6ZUhhbmRsZXIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgd2luZG93LmpRdWVyeShkb2N1bWVudCkub24oCiAgICAgICAgICAgICAgImhpZGRlbi5odG1sd2lkZ2V0cyBoaWRkZW4uYnMudGFiLmh0bWx3aWRnZXRzIGhpZGRlbi5icy5jb2xsYXBzZS5odG1sd2lkZ2V0cyIsCiAgICAgICAgICAgICAgcmVzaXplSGFuZGxlcgogICAgICAgICAgICApOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIGZvciB0aGUgc3BlY2lmaWMgY2FzZSBvZiBpb3NsaWRlcywgd2hpY2gKICAgICAgICAgIC8vIGZsaXBzIHNsaWRlcyBiZXR3ZWVuIGRpc3BsYXk6bm9uZSBhbmQgZGlzcGxheTpibG9jay4KICAgICAgICAgIC8vIElkZWFsbHkgd2Ugd291bGQgbm90IGhhdmUgdG8gaGF2ZSBpb3NsaWRlLXNwZWNpZmljIGNvZGUKICAgICAgICAgIC8vIGhlcmUsIGJ1dCByYXRoZXIgaGF2ZSBpb3NsaWRlcyByYWlzZSBhIGdlbmVyaWMgZXZlbnQsCiAgICAgICAgICAvLyBidXQgdGhlIHJtYXJrZG93biBwYWNrYWdlIGp1c3Qgd2VudCB0byBDUkFOIHNvIHRoZQogICAgICAgICAgLy8gd2luZG93IHRvIGdldHRpbmcgdGhhdCBmaXhlZCBtYXkgYmUgbG9uZy4KICAgICAgICAgIGlmICh3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcikgewogICAgICAgICAgICAvLyBJdCdzIE9LIHRvIGxpbWl0IHRoaXMgdG8gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIKICAgICAgICAgICAgLy8gYnJvd3NlcnMgYmVjYXVzZSBpb3NsaWRlcyBpdHNlbGYgb25seSBzdXBwb3J0cwogICAgICAgICAgICAvLyBzdWNoIGJyb3dzZXJzLgogICAgICAgICAgICBvbihkb2N1bWVudCwgInNsaWRlZW50ZXIiLCByZXNpemVIYW5kbGVyKTsKICAgICAgICAgICAgb24oZG9jdW1lbnQsICJzbGlkZWxlYXZlIiwgcmVzaXplSGFuZGxlcik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2YXIgc2NyaXB0RGF0YSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInNjcmlwdFtkYXRhLWZvcj0nIiArIGVsLmlkICsgIiddW3R5cGU9J2FwcGxpY2F0aW9uL2pzb24nXSIpOwogICAgICAgIGlmIChzY3JpcHREYXRhKSB7CiAgICAgICAgICB2YXIgZGF0YSA9IEpTT04ucGFyc2Uoc2NyaXB0RGF0YS50ZXh0Q29udGVudCB8fCBzY3JpcHREYXRhLnRleHQpOwogICAgICAgICAgLy8gUmVzb2x2ZSBzdHJpbmdzIG1hcmtlZCBhcyBqYXZhc2NyaXB0IGxpdGVyYWxzIHRvIG9iamVjdHMKICAgICAgICAgIGlmICghKGRhdGEuZXZhbHMgaW5zdGFuY2VvZiBBcnJheSkpIGRhdGEuZXZhbHMgPSBbZGF0YS5ldmFsc107CiAgICAgICAgICBmb3IgKHZhciBrID0gMDsgZGF0YS5ldmFscyAmJiBrIDwgZGF0YS5ldmFscy5sZW5ndGg7IGsrKykgewogICAgICAgICAgICB3aW5kb3cuSFRNTFdpZGdldHMuZXZhbHVhdGVTdHJpbmdNZW1iZXIoZGF0YS54LCBkYXRhLmV2YWxzW2tdKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpbmRpbmcucmVuZGVyVmFsdWUoZWwsIGRhdGEueCwgaW5pdFJlc3VsdCk7CiAgICAgICAgICBldmFsQW5kUnVuKGRhdGEuanNIb29rcy5yZW5kZXIsIGluaXRSZXN1bHQsIFtlbCwgZGF0YS54XSk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH0pOwoKICAgIGludm9rZVBvc3RSZW5kZXJIYW5kbGVycygpOwogIH0KCiAgLy8gV2FpdCB1bnRpbCBhZnRlciB0aGUgZG9jdW1lbnQgaGFzIGxvYWRlZCB0byByZW5kZXIgdGhlIHdpZGdldHMuCiAgaWYgKGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLCBmdW5jdGlvbigpIHsKICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsIGFyZ3VtZW50cy5jYWxsZWUsIGZhbHNlKTsKICAgICAgd2luZG93LkhUTUxXaWRnZXRzLnN0YXRpY1JlbmRlcigpOwogICAgfSwgZmFsc2UpOwogIH0gZWxzZSBpZiAoZG9jdW1lbnQuYXR0YWNoRXZlbnQpIHsKICAgIGRvY3VtZW50LmF0dGFjaEV2ZW50KCJvbnJlYWR5c3RhdGVjaGFuZ2UiLCBmdW5jdGlvbigpIHsKICAgICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICJjb21wbGV0ZSIpIHsKICAgICAgICBkb2N1bWVudC5kZXRhY2hFdmVudCgib25yZWFkeXN0YXRlY2hhbmdlIiwgYXJndW1lbnRzLmNhbGxlZSk7CiAgICAgICAgd2luZG93LkhUTUxXaWRnZXRzLnN0YXRpY1JlbmRlcigpOwogICAgICB9CiAgICB9KTsKICB9CgoKICB3aW5kb3cuSFRNTFdpZGdldHMuZ2V0QXR0YWNobWVudFVybCA9IGZ1bmN0aW9uKGRlcG5hbWUsIGtleSkgewogICAgLy8gSWYgbm8ga2V5LCBkZWZhdWx0IHRvIHRoZSBmaXJzdCBpdGVtCiAgICBpZiAodHlwZW9mKGtleSkgPT09ICJ1bmRlZmluZWQiKQogICAgICBrZXkgPSAxOwoKICAgIHZhciBsaW5rID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZGVwbmFtZSArICItIiArIGtleSArICItYXR0YWNobWVudCIpOwogICAgaWYgKCFsaW5rKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigiQXR0YWNobWVudCAiICsgZGVwbmFtZSArICIvIiArIGtleSArICIgbm90IGZvdW5kIGluIGRvY3VtZW50Iik7CiAgICB9CiAgICByZXR1cm4gbGluay5nZXRBdHRyaWJ1dGUoImhyZWYiKTsKICB9OwoKICB3aW5kb3cuSFRNTFdpZGdldHMuZGF0YWZyYW1lVG9EMyA9IGZ1bmN0aW9uKGRmKSB7CiAgICB2YXIgbmFtZXMgPSBbXTsKICAgIHZhciBsZW5ndGg7CiAgICBmb3IgKHZhciBuYW1lIGluIGRmKSB7CiAgICAgICAgaWYgKGRmLmhhc093blByb3BlcnR5KG5hbWUpKQogICAgICAgICAgICBuYW1lcy5wdXNoKG5hbWUpOwogICAgICAgIGlmICh0eXBlb2YoZGZbbmFtZV0pICE9PSAib2JqZWN0IiB8fCB0eXBlb2YoZGZbbmFtZV0ubGVuZ3RoKSA9PT0gInVuZGVmaW5lZCIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJBbGwgZmllbGRzIG11c3QgYmUgYXJyYXlzIik7CiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YobGVuZ3RoKSAhPT0gInVuZGVmaW5lZCIgJiYgbGVuZ3RoICE9PSBkZltuYW1lXS5sZW5ndGgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJBbGwgZmllbGRzIG11c3QgYmUgYXJyYXlzIG9mIHRoZSBzYW1lIGxlbmd0aCIpOwogICAgICAgIH0KICAgICAgICBsZW5ndGggPSBkZltuYW1lXS5sZW5ndGg7CiAgICB9CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgdmFyIGl0ZW07CiAgICBmb3IgKHZhciByb3cgPSAwOyByb3cgPCBsZW5ndGg7IHJvdysrKSB7CiAgICAgICAgaXRlbSA9IHt9OwogICAgICAgIGZvciAodmFyIGNvbCA9IDA7IGNvbCA8IG5hbWVzLmxlbmd0aDsgY29sKyspIHsKICAgICAgICAgICAgaXRlbVtuYW1lc1tjb2xdXSA9IGRmW25hbWVzW2NvbF1dW3Jvd107CiAgICAgICAgfQogICAgICAgIHJlc3VsdHMucHVzaChpdGVtKTsKICAgIH0KICAgIHJldHVybiByZXN1bHRzOwogIH07CgogIHdpbmRvdy5IVE1MV2lkZ2V0cy50cmFuc3Bvc2VBcnJheTJEID0gZnVuY3Rpb24oYXJyYXkpIHsKICAgICAgaWYgKGFycmF5Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIGFycmF5OwogICAgICB2YXIgbmV3QXJyYXkgPSBhcnJheVswXS5tYXAoZnVuY3Rpb24oY29sLCBpKSB7CiAgICAgICAgICByZXR1cm4gYXJyYXkubWFwKGZ1bmN0aW9uKHJvdykgewogICAgICAgICAgICAgIHJldHVybiByb3dbaV0KICAgICAgICAgIH0pCiAgICAgIH0pOwogICAgICByZXR1cm4gbmV3QXJyYXk7CiAgfTsKICAvLyBTcGxpdCB2YWx1ZSBhdCBzcGxpdENoYXIsIGJ1dCBhbGxvdyBzcGxpdENoYXIgdG8gYmUgZXNjYXBlZAogIC8vIHVzaW5nIGVzY2FwZUNoYXIuIEFueSBvdGhlciBjaGFyYWN0ZXJzIGVzY2FwZWQgYnkgZXNjYXBlQ2hhcgogIC8vIHdpbGwgYmUgaW5jbHVkZWQgYXMgdXN1YWwgKGluY2x1ZGluZyBlc2NhcGVDaGFyIGl0c2VsZikuCiAgZnVuY3Rpb24gc3BsaXRXaXRoRXNjYXBlKHZhbHVlLCBzcGxpdENoYXIsIGVzY2FwZUNoYXIpIHsKICAgIHZhciByZXN1bHRzID0gW107CiAgICB2YXIgZXNjYXBlTW9kZSA9IGZhbHNlOwogICAgdmFyIGN1cnJlbnRSZXN1bHQgPSAiIjsKICAgIGZvciAodmFyIHBvcyA9IDA7IHBvcyA8IHZhbHVlLmxlbmd0aDsgcG9zKyspIHsKICAgICAgaWYgKCFlc2NhcGVNb2RlKSB7CiAgICAgICAgaWYgKHZhbHVlW3Bvc10gPT09IHNwbGl0Q2hhcikgewogICAgICAgICAgcmVzdWx0cy5wdXNoKGN1cnJlbnRSZXN1bHQpOwogICAgICAgICAgY3VycmVudFJlc3VsdCA9ICIiOwogICAgICAgIH0gZWxzZSBpZiAodmFsdWVbcG9zXSA9PT0gZXNjYXBlQ2hhcikgewogICAgICAgICAgZXNjYXBlTW9kZSA9IHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGN1cnJlbnRSZXN1bHQgKz0gdmFsdWVbcG9zXTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY3VycmVudFJlc3VsdCArPSB2YWx1ZVtwb3NdOwogICAgICAgIGVzY2FwZU1vZGUgPSBmYWxzZTsKICAgICAgfQogICAgfQogICAgaWYgKGN1cnJlbnRSZXN1bHQgIT09ICIiKSB7CiAgICAgIHJlc3VsdHMucHVzaChjdXJyZW50UmVzdWx0KTsKICAgIH0KICAgIHJldHVybiByZXN1bHRzOwogIH0KICAvLyBGdW5jdGlvbiBhdXRob3JlZCBieSBZaWh1aS9KSiBBbGxhaXJlCiAgd2luZG93LkhUTUxXaWRnZXRzLmV2YWx1YXRlU3RyaW5nTWVtYmVyID0gZnVuY3Rpb24obywgbWVtYmVyKSB7CiAgICB2YXIgcGFydHMgPSBzcGxpdFdpdGhFc2NhcGUobWVtYmVyLCAnLicsICdcXCcpOwogICAgZm9yICh2YXIgaSA9IDAsIGwgPSBwYXJ0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHsKICAgICAgdmFyIHBhcnQgPSBwYXJ0c1tpXTsKICAgICAgLy8gcGFydCBtYXkgYmUgYSBjaGFyYWN0ZXIgb3IgJ251bWVyaWMnIG1lbWJlciBuYW1lCiAgICAgIGlmIChvICE9PSBudWxsICYmIHR5cGVvZiBvID09PSAib2JqZWN0IiAmJiBwYXJ0IGluIG8pIHsKICAgICAgICBpZiAoaSA9PSAobCAtIDEpKSB7IC8vIGlmIHdlIGFyZSBhdCB0aGUgZW5kIG9mIHRoZSBsaW5lIHRoZW4gZXZhbHVsYXRlCiAgICAgICAgICBpZiAodHlwZW9mIG9bcGFydF0gPT09ICJzdHJpbmciKQogICAgICAgICAgICBvW3BhcnRdID0gZXZhbCgiKCIgKyBvW3BhcnRdICsgIikiKTsKICAgICAgICB9IGVsc2UgeyAvLyBvdGhlcndpc2UgY29udGludWUgdG8gbmV4dCBlbWJlZGRlZCBvYmplY3QKICAgICAgICAgIG8gPSBvW3BhcnRdOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH07CgogIC8vIFJldHJpZXZlIHRoZSBIVE1MV2lkZ2V0IGluc3RhbmNlIChpLmUuIHRoZSByZXR1cm4gdmFsdWUgb2YgYW4KICAvLyBIVE1MV2lkZ2V0IGJpbmRpbmcncyBpbml0aWFsaXplKCkgb3IgZmFjdG9yeSgpIGZ1bmN0aW9uKQogIC8vIGFzc29jaWF0ZWQgd2l0aCBhbiBlbGVtZW50LCBvciBudWxsIGlmIG5vbmUuCiAgd2luZG93LkhUTUxXaWRnZXRzLmdldEluc3RhbmNlID0gZnVuY3Rpb24oZWwpIHsKICAgIHJldHVybiBlbGVtZW50RGF0YShlbCwgImluaXRfcmVzdWx0Iik7CiAgfTsKCiAgLy8gRmluZHMgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIHNjb3BlIHRoYXQgbWF0Y2hlcyB0aGUgc2VsZWN0b3IsCiAgLy8gYW5kIHJldHVybnMgdGhlIEhUTUxXaWRnZXQgaW5zdGFuY2UgKGkuZS4gdGhlIHJldHVybiB2YWx1ZSBvZgogIC8vIGFuIEhUTUxXaWRnZXQgYmluZGluZydzIGluaXRpYWxpemUoKSBvciBmYWN0b3J5KCkgZnVuY3Rpb24pCiAgLy8gYXNzb2NpYXRlZCB3aXRoIHRoYXQgZWxlbWVudCwgaWYgYW55LiBJZiBubyBlbGVtZW50IG1hdGNoZXMgdGhlCiAgLy8gc2VsZWN0b3IsIG9yIHRoZSBmaXJzdCBtYXRjaGluZyBlbGVtZW50IGhhcyBubyBIVE1MV2lkZ2V0CiAgLy8gaW5zdGFuY2UgYXNzb2NpYXRlZCB3aXRoIGl0LCB0aGVuIG51bGwgaXMgcmV0dXJuZWQuCiAgLy8KICAvLyBUaGUgc2NvcGUgYXJndW1lbnQgaXMgb3B0aW9uYWwsIGFuZCBkZWZhdWx0cyB0byB3aW5kb3cuZG9jdW1lbnQuCiAgd2luZG93LkhUTUxXaWRnZXRzLmZpbmQgPSBmdW5jdGlvbihzY29wZSwgc2VsZWN0b3IpIHsKICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgc2VsZWN0b3IgPSBzY29wZTsKICAgICAgc2NvcGUgPSBkb2N1bWVudDsKICAgIH0KCiAgICB2YXIgZWwgPSBzY29wZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTsKICAgIGlmIChlbCA9PT0gbnVsbCkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB3aW5kb3cuSFRNTFdpZGdldHMuZ2V0SW5zdGFuY2UoZWwpOwogICAgfQogIH07CgogIC8vIEZpbmRzIGFsbCBlbGVtZW50cyBpbiB0aGUgc2NvcGUgdGhhdCBtYXRjaCB0aGUgc2VsZWN0b3IsIGFuZAogIC8vIHJldHVybnMgdGhlIEhUTUxXaWRnZXQgaW5zdGFuY2VzIChpLmUuIHRoZSByZXR1cm4gdmFsdWVzIG9mCiAgLy8gYW4gSFRNTFdpZGdldCBiaW5kaW5nJ3MgaW5pdGlhbGl6ZSgpIG9yIGZhY3RvcnkoKSBmdW5jdGlvbikKICAvLyBhc3NvY2lhdGVkIHdpdGggdGhlIGVsZW1lbnRzLCBpbiBhbiBhcnJheS4gSWYgZWxlbWVudHMgdGhhdAogIC8vIG1hdGNoIHRoZSBzZWxlY3RvciBkb24ndCBoYXZlIGFuIGFzc29jaWF0ZWQgSFRNTFdpZGdldAogIC8vIGluc3RhbmNlLCB0aGUgcmV0dXJuZWQgYXJyYXkgd2lsbCBjb250YWluIG51bGxzLgogIC8vCiAgLy8gVGhlIHNjb3BlIGFyZ3VtZW50IGlzIG9wdGlvbmFsLCBhbmQgZGVmYXVsdHMgdG8gd2luZG93LmRvY3VtZW50LgogIHdpbmRvdy5IVE1MV2lkZ2V0cy5maW5kQWxsID0gZnVuY3Rpb24oc2NvcGUsIHNlbGVjdG9yKSB7CiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7CiAgICAgIHNlbGVjdG9yID0gc2NvcGU7CiAgICAgIHNjb3BlID0gZG9jdW1lbnQ7CiAgICB9CgogICAgdmFyIG5vZGVzID0gc2NvcGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykgewogICAgICByZXN1bHRzLnB1c2god2luZG93LkhUTUxXaWRnZXRzLmdldEluc3RhbmNlKG5vZGVzW2ldKSk7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0czsKICB9OwoKICB2YXIgcG9zdFJlbmRlckhhbmRsZXJzID0gW107CiAgZnVuY3Rpb24gaW52b2tlUG9zdFJlbmRlckhhbmRsZXJzKCkgewogICAgd2hpbGUgKHBvc3RSZW5kZXJIYW5kbGVycy5sZW5ndGgpIHsKICAgICAgdmFyIGhhbmRsZXIgPSBwb3N0UmVuZGVySGFuZGxlcnMuc2hpZnQoKTsKICAgICAgaWYgKGhhbmRsZXIpIHsKICAgICAgICBoYW5kbGVyKCk7CiAgICAgIH0KICAgIH0KICB9CgogIC8vIFJlZ2lzdGVyIHRoZSBnaXZlbiBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBpbnZva2VkIGFmdGVyIHRoZQogIC8vIG5leHQgdGltZSBzdGF0aWMgd2lkZ2V0cyBhcmUgcmVuZGVyZWQuCiAgd2luZG93LkhUTUxXaWRnZXRzLmFkZFBvc3RSZW5kZXJIYW5kbGVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgIHBvc3RSZW5kZXJIYW5kbGVycy5wdXNoKGNhbGxiYWNrKTsKICB9OwoKICAvLyBUYWtlcyBhIG5ldy1zdHlsZSBpbnN0YW5jZS1ib3VuZCBkZWZpbml0aW9uLCBhbmQgcmV0dXJucyBhbgogIC8vIG9sZC1zdHlsZSBjbGFzcy1ib3VuZCBkZWZpbml0aW9uLiBUaGlzIHNhdmVzIHVzIGZyb20gaGF2aW5nCiAgLy8gdG8gcmV3cml0ZSBhbGwgdGhlIGxvZ2ljIGluIHRoaXMgZmlsZSB0byBhY2NvbW9kYXRlIGJvdGgKICAvLyB0eXBlcyBvZiBkZWZpbml0aW9ucy4KICBmdW5jdGlvbiBjcmVhdGVMZWdhY3lEZWZpbml0aW9uQWRhcHRlcihkZWZuKSB7CiAgICB2YXIgcmVzdWx0ID0gewogICAgICBuYW1lOiBkZWZuLm5hbWUsCiAgICAgIHR5cGU6IGRlZm4udHlwZSwKICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWwsIHdpZHRoLCBoZWlnaHQpIHsKICAgICAgICByZXR1cm4gZGVmbi5mYWN0b3J5KGVsLCB3aWR0aCwgaGVpZ2h0KTsKICAgICAgfSwKICAgICAgcmVuZGVyVmFsdWU6IGZ1bmN0aW9uKGVsLCB4LCBpbnN0YW5jZSkgewogICAgICAgIHJldHVybiBpbnN0YW5jZS5yZW5kZXJWYWx1ZSh4KTsKICAgICAgfSwKICAgICAgcmVzaXplOiBmdW5jdGlvbihlbCwgd2lkdGgsIGhlaWdodCwgaW5zdGFuY2UpIHsKICAgICAgICByZXR1cm4gaW5zdGFuY2UucmVzaXplKHdpZHRoLCBoZWlnaHQpOwogICAgICB9CiAgICB9OwoKICAgIGlmIChkZWZuLmZpbmQpCiAgICAgIHJlc3VsdC5maW5kID0gZGVmbi5maW5kOwogICAgaWYgKGRlZm4ucmVuZGVyRXJyb3IpCiAgICAgIHJlc3VsdC5yZW5kZXJFcnJvciA9IGRlZm4ucmVuZGVyRXJyb3I7CiAgICBpZiAoZGVmbi5jbGVhckVycm9yKQogICAgICByZXN1bHQuY2xlYXJFcnJvciA9IGRlZm4uY2xlYXJFcnJvcjsKCiAgICByZXR1cm4gcmVzdWx0OwogIH0KfSkoKTsKCg==\"></script>\r\n",
"<link href=\"data:text/css;charset=utf-8,%0A%23wcLabel%20%7B%0Aposition%3A%20absolute%3B%0Aborder%3A%202px%20solid%20%23fff%3B%0Abox%2Dshadow%3A%200%200%204px%200%20%23008%3B%0Apadding%3A%202px%3B%0A%0Apointer%2Devents%3A%20none%3B%20%7D%0A%23wcSpan%20%7B%0Aposition%3A%20absolute%3B%0Atop%3A%20100%25%3B%0Aleft%3A%200%3B%0Abackground%2Dcolor%3A%20rgba%28255%2C%20255%2C%20255%2C%200%2E8%29%3B%0Acolor%3A%20%23333%3B%0Amargin%2Dtop%3A%206px%3B%0Apadding%3A%200%200%2E5em%3B%0Aborder%2Dradius%3A%200%2E5em%3B%0Awhite%2Dspace%3A%20nowrap%3B%20%7D%0A\" rel=\"stylesheet\" />\r\n",
"<script src=\"data:application/x-javascript;base64,LyohCiAqIHdvcmRjbG91ZDIuanMKICogaHR0cDovL3RpbWRyZWFtLm9yZy93b3JkY2xvdWQyLmpzLwogKgogKiBDb3B5cmlnaHQgMjAxMSAtIDIwMTMgVGltIENoaWVuCiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZQogKi8KCid1c2Ugc3RyaWN0JzsKCi8vIHNldEltbWVkaWF0ZQppZiAoIXdpbmRvdy5zZXRJbW1lZGlhdGUpIHsKICB3aW5kb3cuc2V0SW1tZWRpYXRlID0gKGZ1bmN0aW9uIHNldHVwU2V0SW1tZWRpYXRlKCkgewogICAgcmV0dXJuIHdpbmRvdy5tc1NldEltbWVkaWF0ZSB8fAogICAgd2luZG93LndlYmtpdFNldEltbWVkaWF0ZSB8fAogICAgd2luZG93Lm1velNldEltbWVkaWF0ZSB8fAogICAgd2luZG93Lm9TZXRJbW1lZGlhdGUgfHwKICAgIChmdW5jdGlvbiBzZXR1cFNldFplcm9UaW1lb3V0KCkgewogICAgICBpZiAoIXdpbmRvdy5wb3N0TWVzc2FnZSB8fCAhd2luZG93LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgfQoKICAgICAgdmFyIGNhbGxiYWNrcyA9IFt1bmRlZmluZWRdOwogICAgICB2YXIgbWVzc2FnZSA9ICd6ZXJvLXRpbWVvdXQtbWVzc2FnZSc7CgogICAgICAvLyBMaWtlIHNldFRpbWVvdXQsIGJ1dCBvbmx5IHRha2VzIGEgZnVuY3Rpb24gYXJndW1lbnQuICBUaGVyZSdzCiAgICAgIC8vIG5vIHRpbWUgYXJndW1lbnQgKGFsd2F5cyB6ZXJvKSBhbmQgbm8gYXJndW1lbnRzICh5b3UgaGF2ZSB0bwogICAgICAvLyB1c2UgYSBjbG9zdXJlKS4KICAgICAgdmFyIHNldFplcm9UaW1lb3V0ID0gZnVuY3Rpb24gc2V0WmVyb1RpbWVvdXQoY2FsbGJhY2spIHsKICAgICAgICB2YXIgaWQgPSBjYWxsYmFja3MubGVuZ3RoOwogICAgICAgIGNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTsKICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UobWVzc2FnZSArIGlkLnRvU3RyaW5nKDM2KSwgJyonKTsKCiAgICAgICAgcmV0dXJuIGlkOwogICAgICB9OwoKICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiBzZXRaZXJvVGltZW91dE1lc3NhZ2UoZXZ0KSB7CiAgICAgICAgLy8gU2tpcHBpbmcgY2hlY2tpbmcgZXZlbnQgc291cmNlLCByZXRhcmRlZCBJRSBjb25mdXNlZCB0aGlzIHdpbmRvdwogICAgICAgIC8vIG9iamVjdCB3aXRoIGFub3RoZXIgaW4gdGhlIHByZXNlbmNlIG9mIGlmcmFtZQogICAgICAgIGlmICh0eXBlb2YgZXZ0LmRhdGEgIT09ICdzdHJpbmcnIHx8CiAgICAgICAgICAgIGV2dC5kYXRhLnN1YnN0cigwLCBtZXNzYWdlLmxlbmd0aCkgIT09IG1lc3NhZ2UvKiB8fAogICAgICAgICAgICBldnQuc291cmNlICE9PSB3aW5kb3cgKi8pIHsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGV2dC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTsKCiAgICAgICAgdmFyIGlkID0gcGFyc2VJbnQoZXZ0LmRhdGEuc3Vic3RyKG1lc3NhZ2UubGVuZ3RoKSwgMzYpOwogICAgICAgIGlmICghY2FsbGJhY2tzW2lkXSkgewogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgY2FsbGJhY2tzW2lkXSgpOwogICAgICAgIGNhbGxiYWNrc1tpZF0gPSB1bmRlZmluZWQ7CiAgICAgIH0sIHRydWUpOwoKICAgICAgLyogc3BlY2lmeSBjbGVhckltbWVkaWF0ZSgpIGhlcmUgc2luY2Ugd2UgbmVlZCB0aGUgc2NvcGUgKi8KICAgICAgd2luZG93LmNsZWFySW1tZWRpYXRlID0gZnVuY3Rpb24gY2xlYXJaZXJvVGltZW91dChpZCkgewogICAgICAgIGlmICghY2FsbGJhY2tzW2lkXSkgewogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgY2FsbGJhY2tzW2lkXSA9IHVuZGVmaW5lZDsKICAgICAgfTsKCiAgICAgIHJldHVybiBzZXRaZXJvVGltZW91dDsKICAgIH0pKCkgfHwKICAgIC8vIGZhbGxiYWNrCiAgICBmdW5jdGlvbiBzZXRJbW1lZGlhdGVGYWxsYmFjayhmbikgewogICAgICB3aW5kb3cuc2V0VGltZW91dChmbiwgMCk7CiAgICB9OwogIH0pKCk7Cn0KCmlmICghd2luZG93LmNsZWFySW1tZWRpYXRlKSB7CiAgd2luZG93LmNsZWFySW1tZWRpYXRlID0gKGZ1bmN0aW9uIHNldHVwQ2xlYXJJbW1lZGlhdGUoKSB7CiAgICByZXR1cm4gd2luZG93Lm1zQ2xlYXJJbW1lZGlhdGUgfHwKICAgIHdpbmRvdy53ZWJraXRDbGVhckltbWVkaWF0ZSB8fAogICAgd2luZG93Lm1vekNsZWFySW1tZWRpYXRlIHx8CiAgICB3aW5kb3cub0NsZWFySW1tZWRpYXRlIHx8CiAgICAvLyAiY2xlYXJaZXJvVGltZW91dCIgaXMgaW1wbGVtZW50IG9uIHRoZSBwcmV2aW91cyBibG9jayB8fAogICAgLy8gZmFsbGJhY2sKICAgIGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlRmFsbGJhY2sodGltZXIpIHsKICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aW1lcik7CiAgICB9OwogIH0pKCk7Cn0KCihmdW5jdGlvbihnbG9iYWwpIHsKCiAgLy8gQ2hlY2sgaWYgV29yZENsb3VkIGNhbiBydW4gb24gdGhpcyBicm93c2VyCiAgdmFyIGlzU3VwcG9ydGVkID0gKGZ1bmN0aW9uIGlzU3VwcG9ydGVkKCkgewogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpOwogICAgaWYgKCFjYW52YXMgfHwgIWNhbnZhcy5nZXRDb250ZXh0KSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7CiAgICBpZiAoIWN0eC5nZXRJbWFnZURhdGEpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKCFjdHguZmlsbFRleHQpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGlmICghQXJyYXkucHJvdG90eXBlLnNvbWUpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKCFBcnJheS5wcm90b3R5cGUucHVzaCkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcmV0dXJuIHRydWU7CiAgfSgpKTsKCiAgLy8gRmluZCBvdXQgaWYgdGhlIGJyb3dzZXIgaW1wb3NlIG1pbml1bSBmb250IHNpemUgYnkKICAvLyBkcmF3aW5nIHNtYWxsIHRleHRzIG9uIGEgY2FudmFzIGFuZCBtZWFzdXJlIGl0J3Mgd2lkdGguCiAgdmFyIG1pbkZvbnRTaXplID0gKGZ1bmN0aW9uIGdldE1pbkZvbnRTaXplKCkgewogICAgaWYgKCFpc1N1cHBvcnRlZCkgewogICAgICByZXR1cm47CiAgICB9CgogICAgdmFyIGN0eCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyk7CgogICAgLy8gc3RhcnQgZnJvbSAyMAogICAgdmFyIHNpemUgPSAyMDsKCiAgICAvLyB0d28gc2l6ZXMgdG8gbWVhc3VyZQogICAgdmFyIGhhbldpZHRoLCBtV2lkdGg7CgogICAgd2hpbGUgKHNpemUpIHsKICAgICAgY3R4LmZvbnQgPSBzaXplLnRvU3RyaW5nKDEwKSArICdweCBzYW5zLXNlcmlmJzsKICAgICAgaWYgKChjdHgubWVhc3VyZVRleHQoJ1x1RkYzNycpLndpZHRoID09PSBoYW5XaWR0aCkgJiYKICAgICAgICAgIChjdHgubWVhc3VyZVRleHQoJ20nKS53aWR0aCkgPT09IG1XaWR0aCkgewogICAgICAgIHJldHVybiAoc2l6ZSArIDEpOwogICAgICB9CgogICAgICBoYW5XaWR0aCA9IGN0eC5tZWFzdXJlVGV4dCgnXHVGRjM3Jykud2lkdGg7CiAgICAgIG1XaWR0aCA9IGN0eC5tZWFzdXJlVGV4dCgnbScpLndpZHRoOwoKICAgICAgc2l6ZS0tOwogICAgfQoKICAgIHJldHVybiAwOwogIH0pKCk7CgogIC8vIEJhc2VkIG9uIGh0dHA6Ly9qc2Zyb21oZWxsLmNvbS9hcnJheS9zaHVmZmxlCiAgdmFyIHNodWZmbGVBcnJheSA9IGZ1bmN0aW9uIHNodWZmbGVBcnJheShhcnIpIHsKICAgIGZvciAodmFyIGosIHgsIGkgPSBhcnIubGVuZ3RoOyBpOwogICAgICBqID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogaSksCiAgICAgIHggPSBhcnJbLS1pXSwgYXJyW2ldID0gYXJyW2pdLAogICAgICBhcnJbal0gPSB4KSB7fQogICAgcmV0dXJuIGFycjsKICB9OwoKICB2YXIgV29yZENsb3VkID0gZnVuY3Rpb24gV29yZENsb3VkKGVsZW1lbnRzLCBvcHRpb25zKSB7CiAgICBpZiAoIWlzU3VwcG9ydGVkKSB7CiAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZWxlbWVudHMpKSB7CiAgICAgIGVsZW1lbnRzID0gW2VsZW1lbnRzXTsKICAgIH0KCiAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsLCBpKSB7CiAgICAgIGlmICh0eXBlb2YgZWwgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgZWxlbWVudHNbaV0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbCk7CiAgICAgICAgaWYgKCFlbGVtZW50c1tpXSkgewogICAgICAgICAgdGhyb3cgJ1RoZSBlbGVtZW50IGlkIHNwZWNpZmllZCBpcyBub3QgZm91bmQuJzsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoIWVsLnRhZ05hbWUgJiYgIWVsLmFwcGVuZENoaWxkKSB7CiAgICAgICAgdGhyb3cgJ1lvdSBtdXN0IHBhc3MgdmFsaWQgSFRNTCBlbGVtZW50cywgb3IgSUQgb2YgdGhlIGVsZW1lbnQuJzsKICAgICAgfQogICAgfSk7CgogICAgLyogRGVmYXVsdCB2YWx1ZXMgdG8gYmUgb3ZlcndyaXR0ZW4gYnkgb3B0aW9ucyBvYmplY3QgKi8KICAgIHZhciBzZXR0aW5ncyA9IHsKICAgICAgbGlzdDogW10sCiAgICAgIGZvbnRGYW1pbHk6ICciVHJlYnVjaGV0IE1TIiwgIkhlaXRpIFRDIiwgIuW+rui7n+ato+m7kemrlCIsICcgKwogICAgICAgICAgICAgICAgICAnIkFyaWFsIFVuaWNvZGUgTVMiLCAiRHJvaWQgRmFsbGJhY2sgU2FucyIsIHNhbnMtc2VyaWYnLAogICAgICBmb250V2VpZ2h0OiAnbm9ybWFsJywKICAgICAgY29sb3I6ICdyYW5kb20tZGFyaycsCiAgICAgIG1pblNpemU6IDAsIC8vIDAgdG8gZGlzYWJsZQogICAgICB3ZWlnaHRGYWN0b3I6IDEsCiAgICAgIGNsZWFyQ2FudmFzOiB0cnVlLAogICAgICBiYWNrZ3JvdW5kQ29sb3I6ICcjZmZmJywgIC8vIG9wYXF1ZSB3aGl0ZSA9IHJnYmEoMjU1LCAyNTUsIDI1NSwgMSkKCiAgICAgIGdyaWRTaXplOiA4LAogICAgICBvcmlnaW46IG51bGwsCgogICAgICBkcmF3TWFzazogZmFsc2UsCiAgICAgIG1hc2tDb2xvcjogJ3JnYmEoMjU1LDAsMCwwLjMpJywKICAgICAgbWFza0dhcFdpZHRoOiAwLjMsCgogICAgICB3YWl0OiAwLAogICAgICBhYm9ydFRocmVzaG9sZDogMCwgLy8gZGlzYWJsZWQKICAgICAgYWJvcnQ6IGZ1bmN0aW9uIG5vb3AoKSB7fSwKCiAgICAgIG1pblJvdGF0aW9uOiAtIE1hdGguUEkgLyAyLAogICAgICBtYXhSb3RhdGlvbjogTWF0aC5QSSAvIDIsCgogICAgICBzaHVmZmxlOiB0cnVlLAogICAgICByb3RhdGVSYXRpbzogMC4xLAoKICAgICAgc2hhcGU6ICdjaXJjbGUnLAogICAgICBlbGxpcHRpY2l0eTogMC42NSwKCiAgICAgIGNsYXNzZXM6IG51bGwsCgogICAgICBob3ZlcjogbnVsbCwKICAgICAgY2xpY2s6IG51bGwKICAgIH07CgogICAgaWYgKG9wdGlvbnMpIHsKICAgICAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMpIHsKICAgICAgICBpZiAoa2V5IGluIHNldHRpbmdzKSB7CiAgICAgICAgICBzZXR0aW5nc1trZXldID0gb3B0aW9uc1trZXldOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8qIENvbnZlcnQgd2VpZ2h0RmFjdG9yIGludG8gYSBmdW5jdGlvbiAqLwogICAgaWYgKHR5cGVvZiBzZXR0aW5ncy53ZWlnaHRGYWN0b3IgIT09ICdmdW5jdGlvbicpIHsKICAgICAgdmFyIGZhY3RvciA9IHNldHRpbmdzLndlaWdodEZhY3RvcjsKICAgICAgc2V0dGluZ3Mud2VpZ2h0RmFjdG9yID0gZnVuY3Rpb24gd2VpZ2h0RmFjdG9yKHB0KSB7CiAgICAgICAgcmV0dXJuIHB0ICogZmFjdG9yOyAvL2luIHB4CiAgICAgIH07CiAgICB9CgogICAgLyogQ29udmVydCBzaGFwZSBpbnRvIGEgZnVuY3Rpb24gKi8KICAgIGlmICh0eXBlb2Ygc2V0dGluZ3Muc2hhcGUgIT09ICdmdW5jdGlvbicpIHsKICAgICAgc3dpdGNoIChzZXR0aW5ncy5zaGFwZSkgewogICAgICAgIGNhc2UgJ2NpcmNsZSc6CiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqLwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAvLyAnY2lyY2xlJyBpcyB0aGUgZGVmYXVsdCBhbmQgYSBzaG9ydGN1dCBpbiB0aGUgY29kZSBsb29wLgogICAgICAgICAgc2V0dGluZ3Muc2hhcGUgPSAnY2lyY2xlJzsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICdjYXJkaW9pZCc6CiAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlQ2FyZGlvaWQodGhldGEpIHsKICAgICAgICAgICAgcmV0dXJuIDEgLSBNYXRoLnNpbih0aGV0YSk7CiAgICAgICAgICB9OwogICAgICAgICAgYnJlYWs7CgogICAgICAgIC8qCgogICAgICAgIFRvIHdvcmsgb3V0IGFuIFgtZ29uLCBvbmUgaGFzIHRvIGNhbGN1bGF0ZSAibSIsCiAgICAgICAgd2hlcmUgMS8oY29zKDIqUEkvWCkrbSpzaW4oMipQSS9YKSkgPSAxLyhjb3MoMCkrbSpzaW4oMCkpCiAgICAgICAgaHR0cDovL3d3dy53b2xmcmFtYWxwaGEuY29tL2lucHV0Lz9pPTElMkYlMjhjb3MlMjgyKlBJJTJGWCUyOSUyQm0qc2luJTI4CiAgICAgICAgMipQSSUyRlglMjklMjkrJTNEKzElMkYlMjhjb3MlMjgwJTI5JTJCbSpzaW4lMjgwJTI5JTI5CgogICAgICAgIENvcHkgdGhlIHNvbHV0aW9uIGludG8gcG9sYXIgZXF1YXRpb24gciA9IDEvKGNvcyh0JykgKyBtKnNpbih0JykpCiAgICAgICAgd2hlcmUgdCcgZXF1YWxzIHRvIG1vZCh0LCAyUEkvWCk7CgogICAgICAgICovCgogICAgICAgIGNhc2UgJ2RpYW1vbmQnOgogICAgICAgIGNhc2UgJ3NxdWFyZSc6CiAgICAgICAgICAvLyBodHRwOi8vd3d3LndvbGZyYW1hbHBoYS5jb20vaW5wdXQvP2k9cGxvdCtyKyUzRCsxJTJGJTI4Y29zJTI4bW9kKwogICAgICAgICAgLy8gJTI4dCUyQytQSSUyRjIlMjklMjklMkJzaW4lMjhtb2QrJTI4dCUyQytQSSUyRjIlMjklMjklMjklMkMrdCslM0QKICAgICAgICAgIC8vICswKy4uKzIqUEkKICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVTcXVhcmUodGhldGEpIHsKICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSB0aGV0YSAlICgyICogTWF0aC5QSSAvIDQpOwogICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArIE1hdGguc2luKHRoZXRhUHJpbWUpKTsKICAgICAgICAgIH07CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAndHJpYW5nbGUtZm9yd2FyZCc6CiAgICAgICAgICAvLyBodHRwOi8vd3d3LndvbGZyYW1hbHBoYS5jb20vaW5wdXQvP2k9cGxvdCtyKyUzRCsxJTJGJTI4Y29zJTI4bW9kKwogICAgICAgICAgLy8gJTI4dCUyQysyKlBJJTJGMyUyOSUyOSUyQnNxcnQlMjgzJTI5c2luJTI4bW9kKyUyOHQlMkMrMipQSSUyRjMlMjkKICAgICAgICAgIC8vICUyOSUyOSUyQyt0KyUzRCswKy4uKzIqUEkKICAgICAgICAgIHNldHRpbmdzLnNoYXBlID0gZnVuY3Rpb24gc2hhcGVUcmlhbmdsZSh0aGV0YSkgewogICAgICAgICAgICB2YXIgdGhldGFQcmltZSA9IHRoZXRhICUgKDIgKiBNYXRoLlBJIC8gMyk7CiAgICAgICAgICAgIHJldHVybiAxIC8gKE1hdGguY29zKHRoZXRhUHJpbWUpICsKICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5zcXJ0KDMpICogTWF0aC5zaW4odGhldGFQcmltZSkpOwogICAgICAgICAgfTsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICd0cmlhbmdsZSc6CiAgICAgICAgY2FzZSAndHJpYW5nbGUtdXByaWdodCc6CiAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlVHJpYW5nbGUodGhldGEpIHsKICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSAodGhldGEgKyBNYXRoLlBJICogMyAvIDIpICUgKDIgKiBNYXRoLlBJIC8gMyk7CiAgICAgICAgICAgIHJldHVybiAxIC8gKE1hdGguY29zKHRoZXRhUHJpbWUpICsKICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5zcXJ0KDMpICogTWF0aC5zaW4odGhldGFQcmltZSkpOwogICAgICAgICAgfTsKICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICdwZW50YWdvbic6CiAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlUGVudGFnb24odGhldGEpIHsKICAgICAgICAgICAgdmFyIHRoZXRhUHJpbWUgPSAodGhldGEgKyAwLjk1NSkgJSAoMiAqIE1hdGguUEkgLyA1KTsKICAgICAgICAgICAgcmV0dXJuIDEgLyAoTWF0aC5jb3ModGhldGFQcmltZSkgKwogICAgICAgICAgICAgICAgICAgICAgICAwLjcyNjU0MyAqIE1hdGguc2luKHRoZXRhUHJpbWUpKTsKICAgICAgICAgIH07CiAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAnc3Rhcic6CiAgICAgICAgICBzZXR0aW5ncy5zaGFwZSA9IGZ1bmN0aW9uIHNoYXBlU3Rhcih0aGV0YSkgewogICAgICAgICAgICB2YXIgdGhldGFQcmltZSA9ICh0aGV0YSArIDAuOTU1KSAlICgyICogTWF0aC5QSSAvIDEwKTsKICAgICAgICAgICAgaWYgKCh0aGV0YSArIDAuOTU1KSAlICgyICogTWF0aC5QSSAvIDUpIC0gKDIgKiBNYXRoLlBJIC8gMTApID49IDApIHsKICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcygoMiAqIE1hdGguUEkgLyAxMCkgLSB0aGV0YVByaW1lKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgMy4wNzc2OCAqIE1hdGguc2luKCgyICogTWF0aC5QSSAvIDEwKSAtIHRoZXRhUHJpbWUpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gMSAvIChNYXRoLmNvcyh0aGV0YVByaW1lKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgMy4wNzc2OCAqIE1hdGguc2luKHRoZXRhUHJpbWUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CgogICAgLyogTWFrZSBzdXJlIGdyaWRTaXplIGlzIGEgd2hvbGUgbnVtYmVyIGFuZCBpcyBub3Qgc21hbGxlciB0aGFuIDRweCAqLwogICAgc2V0dGluZ3MuZ3JpZFNpemUgPSBNYXRoLm1heChNYXRoLmZsb29yKHNldHRpbmdzLmdyaWRTaXplKSwgNCk7CgogICAgLyogc2hvcnRoYW5kICovCiAgICB2YXIgZyA9IHNldHRpbmdzLmdyaWRTaXplOwogICAgdmFyIG1hc2tSZWN0V2lkdGggPSBnIC0gc2V0dGluZ3MubWFza0dhcFdpZHRoOwoKICAgIC8qIG5vcm1hbGl6ZSByb3RhdGlvbiBzZXR0aW5ncyAqLwogICAgdmFyIHJvdGF0aW9uUmFuZ2UgPSBNYXRoLmFicyhzZXR0aW5ncy5tYXhSb3RhdGlvbiAtIHNldHRpbmdzLm1pblJvdGF0aW9uKTsKICAgIHZhciBtaW5Sb3RhdGlvbiA9IE1hdGgubWluKHNldHRpbmdzLm1heFJvdGF0aW9uLCBzZXR0aW5ncy5taW5Sb3RhdGlvbik7CgogICAgLyogaW5mb3JtYXRpb24vb2JqZWN0IGF2YWlsYWJsZSB0byBhbGwgZnVuY3Rpb25zLCBzZXQgd2hlbiBzdGFydCgpICovCiAgICB2YXIgZ3JpZCwgLy8gMmQgYXJyYXkgY29udGFpbmluZyBmaWxsaW5nIGluZm9ybWF0aW9uCiAgICAgIG5neCwgbmd5LCAvLyB3aWR0aCBhbmQgaGVpZ2h0IG9mIHRoZSBncmlkCiAgICAgIGNlbnRlciwgLy8gcG9zaXRpb24gb2YgdGhlIGNlbnRlciBvZiB0aGUgY2xvdWQKICAgICAgbWF4UmFkaXVzOwoKICAgIC8qIHRpbWVzdGFtcCBmb3IgbWVhc3VyaW5nIGVhY2ggcHV0V29yZCgpIGFjdGlvbiAqLwogICAgdmFyIGVzY2FwZVRpbWU7CgogICAgLyogZnVuY3Rpb24gZm9yIGdldHRpbmcgdGhlIGNvbG9yIG9mIHRoZSB0ZXh0ICovCiAgICB2YXIgZ2V0VGV4dENvbG9yOwogICAgZnVuY3Rpb24gcmFuZG9tX2hzbF9jb2xvcihtaW4sIG1heCkgewogICAgICByZXR1cm4gJ2hzbCgnICsKICAgICAgICAoTWF0aC5yYW5kb20oKSAqIDM2MCkudG9GaXhlZCgpICsgJywnICsKICAgICAgICAoTWF0aC5yYW5kb20oKSAqIDMwICsgNzApLnRvRml4ZWQoKSArICclLCcgKwogICAgICAgIChNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbikgKyBtaW4pLnRvRml4ZWQoKSArICclKSc7CiAgICB9CiAgICBzd2l0Y2ggKHNldHRpbmdzLmNvbG9yKSB7CiAgICAgIGNhc2UgJ3JhbmRvbS1kYXJrJzoKICAgICAgICBnZXRUZXh0Q29sb3IgPSBmdW5jdGlvbiBnZXRSYW5kb21EYXJrQ29sb3IoKSB7CiAgICAgICAgICByZXR1cm4gcmFuZG9tX2hzbF9jb2xvcigxMCwgNTApOwogICAgICAgIH07CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlICdyYW5kb20tbGlnaHQnOgogICAgICAgIGdldFRleHRDb2xvciA9IGZ1bmN0aW9uIGdldFJhbmRvbUxpZ2h0Q29sb3IoKSB7CiAgICAgICAgICByZXR1cm4gcmFuZG9tX2hzbF9jb2xvcig1MCwgOTApOwogICAgICAgIH07CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIGlmICh0eXBlb2Ygc2V0dGluZ3MuY29sb3IgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgIGdldFRleHRDb2xvciA9IHNldHRpbmdzLmNvbG9yOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBmdW5jdGlvbiBmb3IgZ2V0dGluZyB0aGUgY2xhc3NlcyBvZiB0aGUgdGV4dCAqLwogICAgdmFyIGdldFRleHRDbGFzc2VzID0gbnVsbDsKICAgIGlmICh0eXBlb2Ygc2V0dGluZ3MuY2xhc3NlcyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICBnZXRUZXh0Q2xhc3NlcyA9IHNldHRpbmdzLmNsYXNzZXM7CiAgICB9CgogICAgLyogSW50ZXJhY3RpdmUgKi8KICAgIHZhciBpbnRlcmFjdGl2ZSA9IGZhbHNlOwogICAgdmFyIGluZm9HcmlkID0gW107CiAgICB2YXIgaG92ZXJlZDsKCiAgICB2YXIgZ2V0SW5mb0dyaWRGcm9tTW91c2VUb3VjaEV2ZW50ID0KICAgIGZ1bmN0aW9uIGdldEluZm9HcmlkRnJvbU1vdXNlVG91Y2hFdmVudChldnQpIHsKICAgICAgdmFyIGNhbnZhcyA9IGV2dC5jdXJyZW50VGFyZ2V0OwogICAgICB2YXIgcmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgdmFyIGNsaWVudFg7CiAgICAgIHZhciBjbGllbnRZOwogICAgICAvKiogRGV0ZWN0IGlmIHRvdWNoZXMgYXJlIGF2YWlsYWJsZSAqLwogICAgICBpZiAoZXZ0LnRvdWNoZXMpIHsKICAgICAgICBjbGllbnRYID0gZXZ0LnRvdWNoZXNbMF0uY2xpZW50WDsKICAgICAgICBjbGllbnRZID0gZXZ0LnRvdWNoZXNbMF0uY2xpZW50WTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjbGllbnRYID0gZXZ0LmNsaWVudFg7CiAgICAgICAgY2xpZW50WSA9IGV2dC5jbGllbnRZOwogICAgICB9CiAgICAgIHZhciBldmVudFggPSBjbGllbnRYIC0gcmVjdC5sZWZ0OwogICAgICB2YXIgZXZlbnRZID0gY2xpZW50WSAtIHJlY3QudG9wOwoKICAgICAgdmFyIHggPSBNYXRoLmZsb29yKGV2ZW50WCAqICgoY2FudmFzLndpZHRoIC8gcmVjdC53aWR0aCkgfHwgMSkgLyBnKTsKICAgICAgdmFyIHkgPSBNYXRoLmZsb29yKGV2ZW50WSAqICgoY2FudmFzLmhlaWdodCAvIHJlY3QuaGVpZ2h0KSB8fCAxKSAvIGcpOwoKICAgICAgcmV0dXJuIGluZm9HcmlkW3hdW3ldOwogICAgfTsKCiAgICB2YXIgd29yZGNsb3VkaG92ZXIgPSBmdW5jdGlvbiB3b3JkY2xvdWRob3ZlcihldnQpIHsKICAgICAgdmFyIGluZm8gPSBnZXRJbmZvR3JpZEZyb21Nb3VzZVRvdWNoRXZlbnQoZXZ0KTsKCiAgICAgIGlmIChob3ZlcmVkID09PSBpbmZvKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICBob3ZlcmVkID0gaW5mbzsKICAgICAgaWYgKCFpbmZvKSB7CiAgICAgICAgc2V0dGluZ3MuaG92ZXIodW5kZWZpbmVkLCB1bmRlZmluZWQsIGV2dCk7CgogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgc2V0dGluZ3MuaG92ZXIoaW5mby5pdGVtLCBpbmZvLmRpbWVuc2lvbiwgZXZ0KTsKCiAgICB9OwoKICAgIHZhciB3b3JkY2xvdWRjbGljayA9IGZ1bmN0aW9uIHdvcmRjbG91ZGNsaWNrKGV2dCkgewogICAgICB2YXIgaW5mbyA9IGdldEluZm9HcmlkRnJvbU1vdXNlVG91Y2hFdmVudChldnQpOwogICAgICBpZiAoIWluZm8pIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIHNldHRpbmdzLmNsaWNrKGluZm8uaXRlbSwgaW5mby5kaW1lbnNpb24sIGV2dCk7CiAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpOwogICAgfTsKCiAgICAvKiBHZXQgcG9pbnRzIG9uIHRoZSBncmlkIGZvciBhIGdpdmVuIHJhZGl1cyBhd2F5IGZyb20gdGhlIGNlbnRlciAqLwogICAgdmFyIHBvaW50c0F0UmFkaXVzID0gW107CiAgICB2YXIgZ2V0UG9pbnRzQXRSYWRpdXMgPSBmdW5jdGlvbiBnZXRQb2ludHNBdFJhZGl1cyhyYWRpdXMpIHsKICAgICAgaWYgKHBvaW50c0F0UmFkaXVzW3JhZGl1c10pIHsKICAgICAgICByZXR1cm4gcG9pbnRzQXRSYWRpdXNbcmFkaXVzXTsKICAgICAgfQoKICAgICAgLy8gTG9vayBmb3IgdGhlc2UgbnVtYmVyIG9mIHBvaW50cyBvbiBlYWNoIHJhZGl1cwogICAgICB2YXIgVCA9IHJhZGl1cyAqIDg7CgogICAgICAvLyBHZXR0aW5nIGFsbCB0aGUgcG9pbnRzIGF0IHRoaXMgcmFkaXVzCiAgICAgIHZhciB0ID0gVDsKICAgICAgdmFyIHBvaW50cyA9IFtdOwoKICAgICAgaWYgKHJhZGl1cyA9PT0gMCkgewogICAgICAgIHBvaW50cy5wdXNoKFtjZW50ZXJbMF0sIGNlbnRlclsxXSwgMF0pOwogICAgICB9CgogICAgICB3aGlsZSAodC0tKSB7CiAgICAgICAgLy8gZGlzdG9ydCB0aGUgcmFkaXVzIHRvIHB1dCB0aGUgY2xvdWQgaW4gc2hhcGUKICAgICAgICB2YXIgcnggPSAxOwogICAgICAgIGlmIChzZXR0aW5ncy5zaGFwZSAhPT0gJ2NpcmNsZScpIHsKICAgICAgICAgIHJ4ID0gc2V0dGluZ3Muc2hhcGUodCAvIFQgKiAyICogTWF0aC5QSSk7IC8vIDAgdG8gMQogICAgICAgIH0KCiAgICAgICAgLy8gUHVzaCBbeCwgeSwgdF07IHQgaXMgdXNlZCBzb2xlbHkgZm9yIGdldFRleHRDb2xvcigpCiAgICAgICAgcG9pbnRzLnB1c2goWwogICAgICAgICAgY2VudGVyWzBdICsgcmFkaXVzICogcnggKiBNYXRoLmNvcygtdCAvIFQgKiAyICogTWF0aC5QSSksCiAgICAgICAgICBjZW50ZXJbMV0gKyByYWRpdXMgKiByeCAqIE1hdGguc2luKC10IC8gVCAqIDIgKiBNYXRoLlBJKSAqCiAgICAgICAgICAgIHNldHRpbmdzLmVsbGlwdGljaXR5LAogICAgICAgICAgdCAvIFQgKiAyICogTWF0aC5QSV0pOwogICAgICB9CgogICAgICBwb2ludHNBdFJhZGl1c1tyYWRpdXNdID0gcG9pbnRzOwogICAgICByZXR1cm4gcG9pbnRzOwogICAgfTsKCiAgICAvKiBSZXR1cm4gdHJ1ZSBpZiB3ZSBoYWQgc3BlbnQgdG9vIG11Y2ggdGltZSAqLwogICAgdmFyIGV4Y2VlZFRpbWUgPSBmdW5jdGlvbiBleGNlZWRUaW1lKCkgewogICAgICByZXR1cm4gKChzZXR0aW5ncy5hYm9ydFRocmVzaG9sZCA+IDApICYmCiAgICAgICAgKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLSBlc2NhcGVUaW1lID4gc2V0dGluZ3MuYWJvcnRUaHJlc2hvbGQpKTsKICAgIH07CgogICAgLyogR2V0IHRoZSBkZWcgb2Ygcm90YXRpb24gYWNjb3JkaW5nIHRvIHNldHRpbmdzLCBhbmQgbHVjay4gKi8KICAgIHZhciBnZXRSb3RhdGVEZWcgPSBmdW5jdGlvbiBnZXRSb3RhdGVEZWcoKSB7CiAgICAgIGlmIChzZXR0aW5ncy5yb3RhdGVSYXRpbyA9PT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgICB9CgogICAgICBpZiAoTWF0aC5yYW5kb20oKSA+IHNldHRpbmdzLnJvdGF0ZVJhdGlvKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KCiAgICAgIGlmIChyb3RhdGlvblJhbmdlID09PSAwKSB7CiAgICAgICAgcmV0dXJuIG1pblJvdGF0aW9uOwogICAgICB9CgogICAgICByZXR1cm4gbWluUm90YXRpb24gKyBNYXRoLnJhbmRvbSgpICogcm90YXRpb25SYW5nZTsKICAgIH07CgogICAgdmFyIGdldFRleHRJbmZvID0gZnVuY3Rpb24gZ2V0VGV4dEluZm8od29yZCwgd2VpZ2h0LCByb3RhdGVEZWcpIHsKICAgICAgLy8gY2FsY3VsYXRlIHRoZSBhY3V0YWwgZm9udCBzaXplCiAgICAgIC8vIGZvbnRTaXplID09PSAwIG1lYW5zIHdlaWdodEZhY3RvciBmdW5jdGlvbiB3YW50cyB0aGUgdGV4dCBza2lwcGVkLAogICAgICAvLyBhbmQgc2l6ZSA8IG1pblNpemUgbWVhbnMgd2UgY2Fubm90IGRyYXcgdGhlIHRleHQuCiAgICAgIHZhciBkZWJ1ZyA9IGZhbHNlOwogICAgICB2YXIgZm9udFNpemUgPSBzZXR0aW5ncy53ZWlnaHRGYWN0b3Iod2VpZ2h0KTsKICAgICAgaWYgKGZvbnRTaXplIDw9IHNldHRpbmdzLm1pblNpemUpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KCiAgICAgIC8vIFNjYWxlIGZhY3RvciBoZXJlIGlzIHRvIG1ha2Ugc3VyZSBmaWxsVGV4dCBpcyBub3QgbGltaXRlZCBieQogICAgICAvLyB0aGUgbWluaXVtIGZvbnQgc2l6ZSBzZXQgYnkgYnJvd3Nlci4KICAgICAgLy8gSXQgd2lsbCBhbHdheXMgYmUgMSBvciAybi4KICAgICAgdmFyIG11ID0gMTsKICAgICAgaWYgKGZvbnRTaXplIDwgbWluRm9udFNpemUpIHsKICAgICAgICBtdSA9IChmdW5jdGlvbiBjYWxjdWxhdGVTY2FsZUZhY3RvcigpIHsKICAgICAgICAgIHZhciBtdSA9IDI7CiAgICAgICAgICB3aGlsZSAobXUgKiBmb250U2l6ZSA8IG1pbkZvbnRTaXplKSB7CiAgICAgICAgICAgIG11ICs9IDI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gbXU7CiAgICAgICAgfSkoKTsKICAgICAgfQoKICAgICAgdmFyIGZjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTsKICAgICAgdmFyIGZjdHggPSBmY2FudmFzLmdldENvbnRleHQoJzJkJywgeyB3aWxsUmVhZEZyZXF1ZW50bHk6IHRydWUgfSk7CgogICAgICBmY3R4LmZvbnQgPSBzZXR0aW5ncy5mb250V2VpZ2h0ICsgJyAnICsKICAgICAgICAoZm9udFNpemUgKiBtdSkudG9TdHJpbmcoMTApICsgJ3B4ICcgKyBzZXR0aW5ncy5mb250RmFtaWx5OwoKICAgICAgLy8gRXN0aW1hdGUgdGhlIGRpbWVuc2lvbiBvZiB0aGUgdGV4dCB3aXRoIG1lYXN1cmVUZXh0KCkuCiAgICAgIHZhciBmdyA9IGZjdHgubWVhc3VyZVRleHQod29yZCkud2lkdGggLyBtdTsKICAgICAgdmFyIGZoID0gTWF0aC5tYXgoZm9udFNpemUgKiBtdSwKICAgICAgICAgICAgICAgICAgICAgICAgZmN0eC5tZWFzdXJlVGV4dCgnbScpLndpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICBmY3R4Lm1lYXN1cmVUZXh0KCdcdUZGMzcnKS53aWR0aCkgLyBtdTsKCiAgICAgIC8vIENyZWF0ZSBhIGJvdW5kYXJ5IGJveCB0aGF0IGlzIGxhcmdlciB0aGFuIG91ciBlc3RpbWF0ZXMsCiAgICAgIC8vIHNvIHRleHQgZG9uJ3QgZ2V0IGN1dCBvZiAoaXQgc2lsbCBtaWdodCkKICAgICAgdmFyIGJveFdpZHRoID0gZncgKyBmaCAqIDI7CiAgICAgIHZhciBib3hIZWlnaHQgPSBmaCAqIDM7CiAgICAgIHZhciBmZ3cgPSBNYXRoLmNlaWwoYm94V2lkdGggLyBnKTsKICAgICAgdmFyIGZnaCA9IE1hdGguY2VpbChib3hIZWlnaHQgLyBnKTsKICAgICAgYm94V2lkdGggPSBmZ3cgKiBnOwogICAgICBib3hIZWlnaHQgPSBmZ2ggKiBnOwoKICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBwcm9wZXIgb2Zmc2V0cyB0byBtYWtlIHRoZSB0ZXh0IGNlbnRlcmVkIGF0CiAgICAgIC8vIHRoZSBwcmVmZXJyZWQgcG9zaXRpb24uCgogICAgICAvLyBUaGlzIGlzIHNpbXBseSBoYWxmIG9mIHRoZSB3aWR0aC4KICAgICAgdmFyIGZpbGxUZXh0T2Zmc2V0WCA9IC0gZncgLyAyOwogICAgICAvLyBJbnN0ZWFkIG9mIG1vdmluZyB0aGUgYm94IHRvIHRoZSBleGFjdCBtaWRkbGUgb2YgdGhlIHByZWZlcnJlZAogICAgICAvLyBwb3NpdGlvbiwgZm9yIFktb2Zmc2V0IHdlIG1vdmUgMC40IGluc3RlYWQsIHNvIExhdGluIGFscGhhYmV0cyBsb29rCiAgICAgIC8vIHZlcnRpY2FsIGNlbnRlcmVkLgogICAgICB2YXIgZmlsbFRleHRPZmZzZXRZID0gLSBmaCAqIDAuNDsKCiAgICAgIC8vIENhbGN1bGF0ZSB0aGUgYWN0dWFsIGRpbWVuc2lvbiBvZiB0aGUgY2FudmFzLCBjb25zaWRlcmluZyB0aGUgcm90YXRpb24uCiAgICAgIHZhciBjZ2ggPSBNYXRoLmNlaWwoKGJveFdpZHRoICogTWF0aC5hYnMoTWF0aC5zaW4ocm90YXRlRGVnKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICBib3hIZWlnaHQgKiBNYXRoLmFicyhNYXRoLmNvcyhyb3RhdGVEZWcpKSkgLyBnKTsKICAgICAgdmFyIGNndyA9IE1hdGguY2VpbCgoYm94V2lkdGggKiBNYXRoLmFicyhNYXRoLmNvcyhyb3RhdGVEZWcpKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJveEhlaWdodCAqIE1hdGguYWJzKE1hdGguc2luKHJvdGF0ZURlZykpKSAvIGcpOwogICAgICB2YXIgd2lkdGggPSBjZ3cgKiBnOwogICAgICB2YXIgaGVpZ2h0ID0gY2doICogZzsKCiAgICAgIGZjYW52YXMuc2V0QXR0cmlidXRlKCd3aWR0aCcsIHdpZHRoKTsKICAgICAgZmNhbnZhcy5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGhlaWdodCk7CgogICAgICBpZiAoZGVidWcpIHsKICAgICAgICAvLyBBdHRhY2ggZmNhbnZhcyB0byB0aGUgRE9NCiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmY2FudmFzKTsKICAgICAgICAvLyBTYXZlIGl0J3Mgc3RhdGUgc28gdGhhdCB3ZSBjb3VsZCByZXN0b3JlIGFuZCBkcmF3IHRoZSBncmlkIGNvcnJlY3RseS4KICAgICAgICBmY3R4LnNhdmUoKTsKICAgICAgfQoKICAgICAgLy8gU2NhbGUgdGhlIGNhbnZhcyB3aXRoIHxtdXwuCiAgICAgIGZjdHguc2NhbGUoMSAvIG11LCAxIC8gbXUpOwogICAgICBmY3R4LnRyYW5zbGF0ZSh3aWR0aCAqIG11IC8gMiwgaGVpZ2h0ICogbXUgLyAyKTsKICAgICAgZmN0eC5yb3RhdGUoLSByb3RhdGVEZWcpOwoKICAgICAgLy8gT25jZSB0aGUgd2lkdGgvaGVpZ2h0IGlzIHNldCwgY3R4IGluZm8gd2lsbCBiZSByZXNldC4KICAgICAgLy8gU2V0IGl0IGFnYWluIGhlcmUuCiAgICAgIGZjdHguZm9udCA9IHNldHRpbmdzLmZvbnRXZWlnaHQgKyAnICcgKwogICAgICAgIChmb250U2l6ZSAqIG11KS50b1N0cmluZygxMCkgKyAncHggJyArIHNldHRpbmdzLmZvbnRGYW1pbHk7CgogICAgICAvLyBGaWxsIHRoZSB0ZXh0IGludG8gdGhlIGZjYW52YXMuCiAgICAgIC8vIFhYWDogV2UgY2Fubm90IGJlY2F1c2UgdGV4dEJhc2VsaW5lID0gJ3RvcCcgaGVyZSBiZWNhdXNlCiAgICAgIC8vIEZpcmVmb3ggYW5kIENocm9tZSB1c2VzIGRpZmZlcmVudCBkZWZhdWx0IGxpbmUtaGVpZ2h0IGZvciBjYW52YXMuCiAgICAgIC8vIFBsZWFzZSByZWFkIGh0dHBzOi8vYnVnemlsLmxhLzczNzg1MiNjNi4KICAgICAgLy8gSGVyZSwgd2UgdXNlIHRleHRCYXNlbGluZSA9ICdtaWRkbGUnIGFuZCBkcmF3IHRoZSB0ZXh0IGF0IGV4YWN0bHkKICAgICAgLy8gMC41ICogZm9udFNpemUgbG93ZXIuCiAgICAgIGZjdHguZmlsbFN0eWxlID0gJyMwMDAnOwogICAgICBmY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnOwogICAgICBmY3R4LmZpbGxUZXh0KHdvcmQsIGZpbGxUZXh0T2Zmc2V0WCAqIG11LAogICAgICAgICAgICAgICAgICAgIChmaWxsVGV4dE9mZnNldFkgKyBmb250U2l6ZSAqIDAuNSkgKiBtdSk7CgogICAgICAvLyBHZXQgdGhlIHBpeGVscyBvZiB0aGUgdGV4dAogICAgICB2YXIgaW1hZ2VEYXRhID0gZmN0eC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCkuZGF0YTsKCiAgICAgIGlmIChleGNlZWRUaW1lKCkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KCiAgICAgIGlmIChkZWJ1ZykgewogICAgICAgIC8vIERyYXcgdGhlIGJveCBvZiB0aGUgb3JpZ2luYWwgZXN0aW1hdGlvbgogICAgICAgIGZjdHguc3Ryb2tlUmVjdChmaWxsVGV4dE9mZnNldFggKiBtdSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsbFRleHRPZmZzZXRZLCBmdyAqIG11LCBmaCAqIG11KTsKICAgICAgICBmY3R4LnJlc3RvcmUoKTsKICAgICAgfQoKICAgICAgLy8gUmVhZCB0aGUgcGl4ZWxzIGFuZCBzYXZlIHRoZSBpbmZvcm1hdGlvbiB0byB0aGUgb2NjdXBpZWQgYXJyYXkKICAgICAgdmFyIG9jY3VwaWVkID0gW107CiAgICAgIHZhciBneCA9IGNndywgZ3ksIHgsIHk7CiAgICAgIHZhciBib3VuZHMgPSBbY2doIC8gMiwgY2d3IC8gMiwgY2doIC8gMiwgY2d3IC8gMl07CiAgICAgIHdoaWxlIChneC0tKSB7CiAgICAgICAgZ3kgPSBjZ2g7CiAgICAgICAgd2hpbGUgKGd5LS0pIHsKICAgICAgICAgIHkgPSBnOwogICAgICAgICAgc2luZ2xlR3JpZExvb3A6IHsKICAgICAgICAgICAgd2hpbGUgKHktLSkgewogICAgICAgICAgICAgIHggPSBnOwogICAgICAgICAgICAgIHdoaWxlICh4LS0pIHsKICAgICAgICAgICAgICAgIGlmIChpbWFnZURhdGFbKChneSAqIGcgKyB5KSAqIHdpZHRoICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChneCAqIGcgKyB4KSkgKiA0ICsgM10pIHsKICAgICAgICAgICAgICAgICAgb2NjdXBpZWQucHVzaChbZ3gsIGd5XSk7CgogICAgICAgICAgICAgICAgICBpZiAoZ3ggPCBib3VuZHNbM10pIHsKICAgICAgICAgICAgICAgICAgICBib3VuZHNbM10gPSBneDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAoZ3ggPiBib3VuZHNbMV0pIHsKICAgICAgICAgICAgICAgICAgICBib3VuZHNbMV0gPSBneDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAoZ3kgPCBib3VuZHNbMF0pIHsKICAgICAgICAgICAgICAgICAgICBib3VuZHNbMF0gPSBneTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAoZ3kgPiBib3VuZHNbMl0pIHsKICAgICAgICAgICAgICAgICAgICBib3VuZHNbMl0gPSBneTsKICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgaWYgKGRlYnVnKSB7CiAgICAgICAgICAgICAgICAgICAgZmN0eC5maWxsU3R5bGUgPSAncmdiYSgyNTUsIDAsIDAsIDAuNSknOwogICAgICAgICAgICAgICAgICAgIGZjdHguZmlsbFJlY3QoZ3ggKiBnLCBneSAqIGcsIGcgLSAwLjUsIGcgLSAwLjUpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrIHNpbmdsZUdyaWRMb29wOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZGVidWcpIHsKICAgICAgICAgICAgICBmY3R4LmZpbGxTdHlsZSA9ICdyZ2JhKDAsIDAsIDI1NSwgMC41KSc7CiAgICAgICAgICAgICAgZmN0eC5maWxsUmVjdChneCAqIGcsIGd5ICogZywgZyAtIDAuNSwgZyAtIDAuNSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmIChkZWJ1ZykgewogICAgICAgIGZjdHguZmlsbFN0eWxlID0gJ3JnYmEoMCwgMjU1LCAwLCAwLjUpJzsKICAgICAgICBmY3R4LmZpbGxSZWN0KGJvdW5kc1szXSAqIGcsCiAgICAgICAgICAgICAgICAgICAgICBib3VuZHNbMF0gKiBnLAogICAgICAgICAgICAgICAgICAgICAgKGJvdW5kc1sxXSAtIGJvdW5kc1szXSArIDEpICogZywKICAgICAgICAgICAgICAgICAgICAgIChib3VuZHNbMl0gLSBib3VuZHNbMF0gKyAxKSAqIGcpOwogICAgICB9CgogICAgICAvLyBSZXR1cm4gaW5mb3JtYXRpb24gbmVlZGVkIHRvIGNyZWF0ZSB0aGUgdGV4dCBvbiB0aGUgcmVhbCBjYW52YXMKICAgICAgcmV0dXJuIHsKICAgICAgICBtdTogbXUsCiAgICAgICAgb2NjdXBpZWQ6IG9jY3VwaWVkLAogICAgICAgIGJvdW5kczogYm91bmRzLAogICAgICAgIGd3OiBjZ3csCiAgICAgICAgZ2g6IGNnaCwKICAgICAgICBmaWxsVGV4dE9mZnNldFg6IGZpbGxUZXh0T2Zmc2V0WCwKICAgICAgICBmaWxsVGV4dE9mZnNldFk6IGZpbGxUZXh0T2Zmc2V0WSwKICAgICAgICBmaWxsVGV4dFdpZHRoOiBmdywKICAgICAgICBmaWxsVGV4dEhlaWdodDogZmgsCiAgICAgICAgZm9udFNpemU6IGZvbnRTaXplCiAgICAgIH07CiAgICB9OwoKICAgIC8qIERldGVybWluZSBpZiB0aGVyZSBpcyByb29tIGF2YWlsYWJsZSBpbiB0aGUgZ2l2ZW4gZGltZW5zaW9uICovCiAgICB2YXIgY2FuRml0VGV4dCA9IGZ1bmN0aW9uIGNhbkZpdFRleHQoZ3gsIGd5LCBndywgZ2gsIG9jY3VwaWVkKSB7CiAgICAgIC8vIEdvIHRocm91Z2ggdGhlIG9jY3VwaWVkIHBvaW50cywKICAgICAgLy8gcmV0dXJuIGZhbHNlIGlmIHRoZSBzcGFjZSBpcyBub3QgYXZhaWxhYmxlLgogICAgICB2YXIgaSA9IG9jY3VwaWVkLmxlbmd0aDsKICAgICAgd2hpbGUgKGktLSkgewogICAgICAgIHZhciBweCA9IGd4ICsgb2NjdXBpZWRbaV1bMF07CiAgICAgICAgdmFyIHB5ID0gZ3kgKyBvY2N1cGllZFtpXVsxXTsKCiAgICAgICAgaWYgKHB4ID49IG5neCB8fCBweSA+PSBuZ3kgfHwgcHggPCAwIHx8IHB5IDwgMCB8fCAhZ3JpZFtweF1bcHldKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB0cnVlOwogICAgfTsKCiAgICAvKiBBY3R1YWxseSBkcmF3IHRoZSB0ZXh0IG9uIHRoZSBncmlkICovCiAgICB2YXIgZHJhd1RleHQgPSBmdW5jdGlvbiBkcmF3VGV4dChneCwgZ3ksIGluZm8sIHdvcmQsIHdlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RhbmNlLCB0aGV0YSwgcm90YXRlRGVnLCBhdHRyaWJ1dGVzKSB7CgogICAgICB2YXIgZm9udFNpemUgPSBpbmZvLmZvbnRTaXplOwogICAgICB2YXIgY29sb3I7CiAgICAgIGlmIChnZXRUZXh0Q29sb3IpIHsKICAgICAgICBjb2xvciA9IGdldFRleHRDb2xvcih3b3JkLCB3ZWlnaHQsIGZvbnRTaXplLCBkaXN0YW5jZSwgdGhldGEpOwogICAgICB9IGVsc2UgaWYgKHNldHRpbmdzLmNvbG9yIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgICBjb2xvciA9IHNldHRpbmdzLmNvbG9yLnNoaWZ0KCkgfHwgJ2JsYWNrJzsgLy8gcGFzcyBhIGFycmF5IGluIHNldHRpbmcsIGRlZmF1bHQgJ2JsYWNrJwogICAgICB9IGVsc2UgewogICAgICAgIGNvbG9yID0gc2V0dGluZ3MuY29sb3I7CiAgICAgIH0KCiAgICAgIHZhciBjbGFzc2VzOwogICAgICBpZiAoZ2V0VGV4dENsYXNzZXMpIHsKICAgICAgICBjbGFzc2VzID0gZ2V0VGV4dENsYXNzZXMod29yZCwgd2VpZ2h0LCBmb250U2l6ZSwgZGlzdGFuY2UsIHRoZXRhKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjbGFzc2VzID0gc2V0dGluZ3MuY2xhc3NlczsKICAgICAgfQoKICAgICAgdmFyIGRpbWVuc2lvbjsKICAgICAgdmFyIGJvdW5kcyA9IGluZm8uYm91bmRzOwogICAgICBkaW1lbnNpb24gPSB7CiAgICAgICAgeDogKGd4ICsgYm91bmRzWzNdKSAqIGcsCiAgICAgICAgeTogKGd5ICsgYm91bmRzWzBdKSAqIGcsCiAgICAgICAgdzogKGJvdW5kc1sxXSAtIGJvdW5kc1szXSArIDEpICogZywKICAgICAgICBoOiAoYm91bmRzWzJdIC0gYm91bmRzWzBdICsgMSkgKiBnCiAgICAgIH07CgogICAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgaWYgKGVsLmdldENvbnRleHQpIHsKICAgICAgICAgIHZhciBjdHggPSBlbC5nZXRDb250ZXh0KCcyZCcpOwogICAgICAgICAgdmFyIG11ID0gaW5mby5tdTsKCiAgICAgICAgICAvLyBTYXZlIHRoZSBjdXJyZW50IHN0YXRlIGJlZm9yZSBtZXNzaW5nIGl0CiAgICAgICAgICBjdHguc2F2ZSgpOwogICAgICAgICAgY3R4LnNjYWxlKDEgLyBtdSwgMSAvIG11KTsKCiAgICAgICAgICBjdHguZm9udCA9IHNldHRpbmdzLmZvbnRXZWlnaHQgKyAnICcgKwogICAgICAgICAgICAgICAgICAgICAoZm9udFNpemUgKiBtdSkudG9TdHJpbmcoMTApICsgJ3B4ICcgKyBzZXR0aW5ncy5mb250RmFtaWx5OwogICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGNvbG9yOwoKICAgICAgICAgIC8vIFRyYW5zbGF0ZSB0aGUgY2FudmFzIHBvc2l0aW9uIHRvIHRoZSBvcmlnaW4gY29vcmRpbmF0ZSBvZiB3aGVyZQogICAgICAgICAgLy8gdGhlIHRleHQgc2hvdWxkIGJlIHB1dC4KICAgICAgICAgIGN0eC50cmFuc2xhdGUoKGd4ICsgaW5mby5ndyAvIDIpICogZyAqIG11LAogICAgICAgICAgICAgICAgICAgICAgICAoZ3kgKyBpbmZvLmdoIC8gMikgKiBnICogbXUpOwoKICAgICAgICAgIGlmIChyb3RhdGVEZWcgIT09IDApIHsKICAgICAgICAgICAgY3R4LnJvdGF0ZSgtIHJvdGF0ZURlZyk7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gRmluYWxseSwgZmlsbCB0aGUgdGV4dC4KCiAgICAgICAgICAvLyBYWFg6IFdlIGNhbm5vdCBiZWNhdXNlIHRleHRCYXNlbGluZSA9ICd0b3AnIGhlcmUgYmVjYXVzZQogICAgICAgICAgLy8gRmlyZWZveCBhbmQgQ2hyb21lIHVzZXMgZGlmZmVyZW50IGRlZmF1bHQgbGluZS1oZWlnaHQgZm9yIGNhbnZhcy4KICAgICAgICAgIC8vIFBsZWFzZSByZWFkIGh0dHBzOi8vYnVnemlsLmxhLzczNzg1MiNjNi4KICAgICAgICAgIC8vIEhlcmUsIHdlIHVzZSB0ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJyBhbmQgZHJhdyB0aGUgdGV4dCBhdCBleGFjdGx5CiAgICAgICAgICAvLyAwLjUgKiBmb250U2l6ZSBsb3dlci4KICAgICAgICAgIGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJzsKICAgICAgICAgIGN0eC5maWxsVGV4dCh3b3JkLCBpbmZvLmZpbGxUZXh0T2Zmc2V0WCAqIG11LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbmZvLmZpbGxUZXh0T2Zmc2V0WSArIGZvbnRTaXplICogMC41KSAqIG11KTsKCiAgICAgICAgICAvLyBUaGUgYmVsb3cgYm94IGlzIGFsd2F5cyBtYXRjaGVzIGhvdyA8c3Bhbj5zIGFyZSBwb3NpdGlvbmVkCiAgICAgICAgICAvKiBjdHguc3Ryb2tlUmVjdChpbmZvLmZpbGxUZXh0T2Zmc2V0WCwgaW5mby5maWxsVGV4dE9mZnNldFksCiAgICAgICAgICAgIGluZm8uZmlsbFRleHRXaWR0aCwgaW5mby5maWxsVGV4dEhlaWdodCk7ICovCgogICAgICAgICAgLy8gUmVzdG9yZSB0aGUgc3RhdGUuCiAgICAgICAgICBjdHgucmVzdG9yZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBkcmF3VGV4dCBvbiBESVYgZWxlbWVudAogICAgICAgICAgdmFyIHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7CiAgICAgICAgICB2YXIgdHJhbnNmb3JtUnVsZSA9ICcnOwogICAgICAgICAgdHJhbnNmb3JtUnVsZSA9ICdyb3RhdGUoJyArICgtIHJvdGF0ZURlZyAvIE1hdGguUEkgKiAxODApICsgJ2RlZykgJzsKICAgICAgICAgIGlmIChpbmZvLm11ICE9PSAxKSB7CiAgICAgICAgICAgIHRyYW5zZm9ybVJ1bGUgKz0KICAgICAgICAgICAgICAndHJhbnNsYXRlWCgtJyArIChpbmZvLmZpbGxUZXh0V2lkdGggLyA0KSArICdweCkgJyArCiAgICAgICAgICAgICAgJ3NjYWxlKCcgKyAoMSAvIGluZm8ubXUpICsgJyknOwogICAgICAgICAgfQogICAgICAgICAgdmFyIHN0eWxlUnVsZXMgPSB7CiAgICAgICAgICAgICdwb3NpdGlvbic6ICdhYnNvbHV0ZScsCiAgICAgICAgICAgICdkaXNwbGF5JzogJ2Jsb2NrJywKICAgICAgICAgICAgJ2ZvbnQnOiBzZXR0aW5ncy5mb250V2VpZ2h0ICsgJyAnICsKICAgICAgICAgICAgICAgICAgICAoZm9udFNpemUgKiBpbmZvLm11KSArICdweCAnICsgc2V0dGluZ3MuZm9udEZhbWlseSwKICAgICAgICAgICAgJ2xlZnQnOiAoKGd4ICsgaW5mby5ndyAvIDIpICogZyArIGluZm8uZmlsbFRleHRPZmZzZXRYKSArICdweCcsCiAgICAgICAgICAgICd0b3AnOiAoKGd5ICsgaW5mby5naCAvIDIpICogZyArIGluZm8uZmlsbFRleHRPZmZzZXRZKSArICdweCcsCiAgICAgICAgICAgICd3aWR0aCc6IGluZm8uZmlsbFRleHRXaWR0aCArICdweCcsCiAgICAgICAgICAgICdoZWlnaHQnOiBpbmZvLmZpbGxUZXh0SGVpZ2h0ICsgJ3B4JywKICAgICAgICAgICAgJ2xpbmVIZWlnaHQnOiBmb250U2l6ZSArICdweCcsCiAgICAgICAgICAgICd3aGl0ZVNwYWNlJzogJ25vd3JhcCcsCiAgICAgICAgICAgICd0cmFuc2Zvcm0nOiB0cmFuc2Zvcm1SdWxlLAogICAgICAgICAgICAnd2Via2l0VHJhbnNmb3JtJzogdHJhbnNmb3JtUnVsZSwKICAgICAgICAgICAgJ21zVHJhbnNmb3JtJzogdHJhbnNmb3JtUnVsZSwKICAgICAgICAgICAgJ3RyYW5zZm9ybU9yaWdpbic6ICc1MCUgNDAlJywKICAgICAgICAgICAgJ3dlYmtpdFRyYW5zZm9ybU9yaWdpbic6ICc1MCUgNDAlJywKICAgICAgICAgICAgJ21zVHJhbnNmb3JtT3JpZ2luJzogJzUwJSA0MCUnCiAgICAgICAgICB9OwogICAgICAgICAgaWYgKGNvbG9yKSB7CiAgICAgICAgICAgIHN0eWxlUnVsZXMuY29sb3IgPSBjb2xvcjsKICAgICAgICAgIH0KICAgICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSB3b3JkOwogICAgICAgICAgZm9yICh2YXIgY3NzUHJvcCBpbiBzdHlsZVJ1bGVzKSB7CiAgICAgICAgICAgIHNwYW4uc3R5bGVbY3NzUHJvcF0gPSBzdHlsZVJ1bGVzW2Nzc1Byb3BdOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUsIGF0dHJpYnV0ZXNbYXR0cmlidXRlXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmIChjbGFzc2VzKSB7CiAgICAgICAgICAgIHNwYW4uY2xhc3NOYW1lICs9IGNsYXNzZXM7CiAgICAgICAgICB9CiAgICAgICAgICBlbC5hcHBlbmRDaGlsZChzcGFuKTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfTsKCiAgICAvKiBIZWxwIGZ1bmN0aW9uIHRvIHVwZGF0ZUdyaWQgKi8KICAgIHZhciBmaWxsR3JpZEF0ID0gZnVuY3Rpb24gZmlsbEdyaWRBdCh4LCB5LCBkcmF3TWFzaywgZGltZW5zaW9uLCBpdGVtKSB7CiAgICAgIGlmICh4ID49IG5neCB8fCB5ID49IG5neSB8fCB4IDwgMCB8fCB5IDwgMCkgewogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgZ3JpZFt4XVt5XSA9IGZhbHNlOwoKICAgICAgaWYgKGRyYXdNYXNrKSB7CiAgICAgICAgdmFyIGN0eCA9IGVsZW1lbnRzWzBdLmdldENvbnRleHQoJzJkJyk7CiAgICAgICAgY3R4LmZpbGxSZWN0KHggKiBnLCB5ICogZywgbWFza1JlY3RXaWR0aCwgbWFza1JlY3RXaWR0aCk7CiAgICAgIH0KCiAgICAgIGlmIChpbnRlcmFjdGl2ZSkgewogICAgICAgIGluZm9HcmlkW3hdW3ldID0geyBpdGVtOiBpdGVtLCBkaW1lbnNpb246IGRpbWVuc2lvbiB9OwogICAgICB9CiAgICB9OwoKICAgIC8qIFVwZGF0ZSB0aGUgZmlsbGluZyBpbmZvcm1hdGlvbiBvZiB0aGUgZ2l2ZW4gc3BhY2Ugd2l0aCBvY2N1cGllZCBwb2ludHMuCiAgICAgICBEcmF3IHRoZSBtYXNrIG9uIHRoZSBjYW52YXMgaWYgbmVjZXNzYXJ5LiAqLwogICAgdmFyIHVwZGF0ZUdyaWQgPSBmdW5jdGlvbiB1cGRhdGVHcmlkKGd4LCBneSwgZ3csIGdoLCBpbmZvLCBpdGVtKSB7CiAgICAgIHZhciBvY2N1cGllZCA9IGluZm8ub2NjdXBpZWQ7CiAgICAgIHZhciBkcmF3TWFzayA9IHNldHRpbmdzLmRyYXdNYXNrOwogICAgICB2YXIgY3R4OwogICAgICBpZiAoZHJhd01hc2spIHsKICAgICAgICBjdHggPSBlbGVtZW50c1swXS5nZXRDb250ZXh0KCcyZCcpOwogICAgICAgIGN0eC5zYXZlKCk7CiAgICAgICAgY3R4LmZpbGxTdHlsZSA9IHNldHRpbmdzLm1hc2tDb2xvcjsKICAgICAgfQoKICAgICAgdmFyIGRpbWVuc2lvbjsKICAgICAgaWYgKGludGVyYWN0aXZlKSB7CiAgICAgICAgdmFyIGJvdW5kcyA9IGluZm8uYm91bmRzOwogICAgICAgIGRpbWVuc2lvbiA9IHsKICAgICAgICAgIHg6IChneCArIGJvdW5kc1szXSkgKiBnLAogICAgICAgICAgeTogKGd5ICsgYm91bmRzWzBdKSAqIGcsCiAgICAgICAgICB3OiAoYm91bmRzWzFdIC0gYm91bmRzWzNdICsgMSkgKiBnLAogICAgICAgICAgaDogKGJvdW5kc1syXSAtIGJvdW5kc1swXSArIDEpICogZwogICAgICAgIH07CiAgICAgIH0KCiAgICAgIHZhciBpID0gb2NjdXBpZWQubGVuZ3RoOwogICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgZmlsbEdyaWRBdChneCArIG9jY3VwaWVkW2ldWzBdLCBneSArIG9jY3VwaWVkW2ldWzFdLAogICAgICAgICAgICAgICAgICAgZHJhd01hc2ssIGRpbWVuc2lvbiwgaXRlbSk7CiAgICAgIH0KCiAgICAgIGlmIChkcmF3TWFzaykgewogICAgICAgIGN0eC5yZXN0b3JlKCk7CiAgICAgIH0KICAgIH07CgogICAgLyogcHV0V29yZCgpIHByb2Nlc3NlcyBlYWNoIGl0ZW0gb24gdGhlIGxpc3QsCiAgICAgICBjYWxjdWxhdGUgaXQncyBzaXplIGFuZCBkZXRlcm1pbmUgaXQncyBwb3NpdGlvbiwgYW5kIGFjdHVhbGx5CiAgICAgICBwdXQgaXQgb24gdGhlIGNhbnZhcy4gKi8KICAgIHZhciBwdXRXb3JkID0gZnVuY3Rpb24gcHV0V29yZChpdGVtKSB7CiAgICAgIHZhciB3b3JkLCB3ZWlnaHQsIGF0dHJpYnV0ZXM7CiAgICAgIGlmIChBcnJheS5pc0FycmF5KGl0ZW0pKSB7CiAgICAgICAgd29yZCA9IGl0ZW1bMF07CiAgICAgICAgd2VpZ2h0ID0gaXRlbVsxXTsKICAgICAgfSBlbHNlIHsKICAgICAgICB3b3JkID0gaXRlbS53b3JkOwogICAgICAgIHdlaWdodCA9IGl0ZW0ud2VpZ2h0OwogICAgICAgIGF0dHJpYnV0ZXMgPSBpdGVtLmF0dHJpYnV0ZXM7CiAgICAgIH0KICAgICAgdmFyIHJvdGF0ZURlZyA9IGdldFJvdGF0ZURlZygpOwoKICAgICAgLy8gZ2V0IGluZm8gbmVlZGVkIHRvIHB1dCB0aGUgdGV4dCBvbnRvIHRoZSBjYW52YXMKICAgICAgdmFyIGluZm8gPSBnZXRUZXh0SW5mbyh3b3JkLCB3ZWlnaHQsIHJvdGF0ZURlZyk7CgogICAgICAvLyBub3QgZ2V0dGluZyB0aGUgaW5mbyBtZWFucyB3ZSBzaG91bGRuJ3QgYmUgZHJhd2luZyB0aGlzIG9uZS4KICAgICAgaWYgKCFpbmZvKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CgogICAgICBpZiAoZXhjZWVkVGltZSgpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CgogICAgICAvLyBTa2lwIHRoZSBsb29wIGlmIHdlIGhhdmUgYWxyZWFkeSBrbm93IHRoZSBib3VuZGluZyBib3ggb2YKICAgICAgLy8gd29yZCBpcyBsYXJnZXIgdGhhbiB0aGUgY2FudmFzLgogICAgICB2YXIgYm91bmRzID0gaW5mby5ib3VuZHM7CiAgICAgIGlmICgoYm91bmRzWzFdIC0gYm91bmRzWzNdICsgMSkgPiBuZ3ggfHwKICAgICAgICAoYm91bmRzWzJdIC0gYm91bmRzWzBdICsgMSkgPiBuZ3kpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KCiAgICAgIC8vIERldGVybWluZSB0aGUgcG9zaXRpb24gdG8gcHV0IHRoZSB0ZXh0IGJ5CiAgICAgIC8vIHN0YXJ0IGxvb2tpbmcgZm9yIHRoZSBuZWFyZXN0IHBvaW50cwogICAgICB2YXIgciA9IG1heFJhZGl1cyArIDE7CgogICAgICB2YXIgdHJ5VG9QdXRXb3JkQXRQb2ludCA9IGZ1bmN0aW9uKGd4eSkgewogICAgICAgIHZhciBneCA9IE1hdGguZmxvb3IoZ3h5WzBdIC0gaW5mby5ndyAvIDIpOwogICAgICAgIHZhciBneSA9IE1hdGguZmxvb3IoZ3h5WzFdIC0gaW5mby5naCAvIDIpOwogICAgICAgIHZhciBndyA9IGluZm8uZ3c7CiAgICAgICAgdmFyIGdoID0gaW5mby5naDsKCiAgICAgICAgLy8gSWYgd2UgY2Fubm90IGZpdCB0aGUgdGV4dCBhdCB0aGlzIHBvc2l0aW9uLCByZXR1cm4gZmFsc2UKICAgICAgICAvLyBhbmQgZ28gdG8gdGhlIG5leHQgcG9zaXRpb24uCiAgICAgICAgaWYgKCFjYW5GaXRUZXh0KGd4LCBneSwgZ3csIGdoLCBpbmZvLm9jY3VwaWVkKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgLy8gQWN0dWFsbHkgcHV0IHRoZSB0ZXh0IG9uIHRoZSBjYW52YXMKICAgICAgICBkcmF3VGV4dChneCwgZ3ksIGluZm8sIHdvcmQsIHdlaWdodCwKICAgICAgICAgICAgICAgICAobWF4UmFkaXVzIC0gciksIGd4eVsyXSwgcm90YXRlRGVnLCBhdHRyaWJ1dGVzKTsKCiAgICAgICAgLy8gTWFyayB0aGUgc3BhY2VzIG9uIHRoZSBncmlkIGFzIGZpbGxlZAogICAgICAgIHVwZGF0ZUdyaWQoZ3gsIGd5LCBndywgZ2gsIGluZm8sIGl0ZW0pOwoKICAgICAgICAvLyBSZXR1cm4gdHJ1ZSBzbyBzb21lKCkgd2lsbCBzdG9wIGFuZCBhbHNvIHJldHVybiB0cnVlLgogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9OwoKICAgICAgd2hpbGUgKHItLSkgewogICAgICAgIHZhciBwb2ludHMgPSBnZXRQb2ludHNBdFJhZGl1cyhtYXhSYWRpdXMgLSByKTsKCiAgICAgICAgaWYgKHNldHRpbmdzLnNodWZmbGUpIHsKICAgICAgICAgIHBvaW50cyA9IFtdLmNvbmNhdChwb2ludHMpOwogICAgICAgICAgc2h1ZmZsZUFycmF5KHBvaW50cyk7CiAgICAgICAgfQoKICAgICAgICAvLyBUcnkgdG8gZml0IHRoZSB3b3JkcyBieSBsb29raW5nIGF0IGVhY2ggcG9pbnQuCiAgICAgICAgLy8gYXJyYXkuc29tZSgpIHdpbGwgc3RvcCBhbmQgcmV0dXJuIHRydWUKICAgICAgICAvLyB3aGVuIHB1dFdvcmRBdFBvaW50KCkgcmV0dXJucyB0cnVlLgogICAgICAgIC8vIElmIGFsbCB0aGUgcG9pbnRzIHJldHVybnMgZmFsc2UsIGFycmF5LnNvbWUoKSByZXR1cm5zIGZhbHNlLgogICAgICAgIHZhciBkcmF3biA9IHBvaW50cy5zb21lKHRyeVRvUHV0V29yZEF0UG9pbnQpOwoKICAgICAgICBpZiAoZHJhd24pIHsKICAgICAgICAgIC8vIGxlYXZlIHB1dFdvcmQoKSBhbmQgcmV0dXJuIHRydWUKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgfQogICAgICAvLyB3ZSB0cmllZCBhbGwgZGlzdGFuY2VzIGJ1dCB0ZXh0IHdvbid0IGZpdCwgcmV0dXJuIGZhbHNlCiAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgLyogU2VuZCBET00gZXZlbnQgdG8gYWxsIGVsZW1lbnRzLiBXaWxsIHN0b3Agc2VuZGluZyBldmVudCBhbmQgcmV0dXJuCiAgICAgICBpZiB0aGUgcHJldmlvdXMgb25lIGlzIGNhbmNlbGVkIChmb3IgY2FuY2VsYWJsZSBldmVudHMpLiAqLwogICAgdmFyIHNlbmRFdmVudCA9IGZ1bmN0aW9uIHNlbmRFdmVudCh0eXBlLCBjYW5jZWxhYmxlLCBkZXRhaWwpIHsKICAgICAgaWYgKGNhbmNlbGFibGUpIHsKICAgICAgICByZXR1cm4gIWVsZW1lbnRzLnNvbWUoZnVuY3Rpb24oZWwpIHsKICAgICAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTsKICAgICAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQodHlwZSwgdHJ1ZSwgY2FuY2VsYWJsZSwgZGV0YWlsIHx8IHt9KTsKICAgICAgICAgIHJldHVybiAhZWwuZGlzcGF0Y2hFdmVudChldnQpOwogICAgICAgIH0sIHRoaXMpOwogICAgICB9IGVsc2UgewogICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWwpIHsKICAgICAgICAgIHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTsKICAgICAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQodHlwZSwgdHJ1ZSwgY2FuY2VsYWJsZSwgZGV0YWlsIHx8IHt9KTsKICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQoZXZ0KTsKICAgICAgICB9LCB0aGlzKTsKICAgICAgfQogICAgfTsKCiAgICAvKiBTdGFydCBkcmF3aW5nIG9uIGEgY2FudmFzICovCiAgICB2YXIgc3RhcnQgPSBmdW5jdGlvbiBzdGFydCgpIHsKICAgICAgLy8gRm9yIGRpbWVuc2lvbnMsIGNsZWFyQ2FudmFzIGV0Yy4sCiAgICAgIC8vIHdlIG9ubHkgY2FyZSBhYm91dCB0aGUgZmlyc3QgZWxlbWVudC4KICAgICAgdmFyIGNhbnZhcyA9IGVsZW1lbnRzWzBdOwoKICAgICAgaWYgKGNhbnZhcy5nZXRDb250ZXh0KSB7CiAgICAgICAgbmd4ID0gTWF0aC5mbG9vcihjYW52YXMud2lkdGggLyBnKTsKICAgICAgICBuZ3kgPSBNYXRoLmZsb29yKGNhbnZhcy5oZWlnaHQgLyBnKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB2YXIgcmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgICBuZ3ggPSBNYXRoLmZsb29yKHJlY3Qud2lkdGggLyBnKTsKICAgICAgICBuZ3kgPSBNYXRoLmZsb29yKHJlY3QuaGVpZ2h0IC8gZyk7CiAgICAgIH0KCiAgICAgIC8vIFNlbmRpbmcgYSB3b3JkY2xvdWRzdGFydCBldmVudCB3aGljaCBjYXVzZSB0aGUgcHJldmlvdXMgbG9vcCB0byBzdG9wLgogICAgICAvLyBEbyBub3RoaW5nIGlmIHRoZSBldmVudCBpcyBjYW5jZWxlZC4KICAgICAgaWYgKCFzZW5kRXZlbnQoJ3dvcmRjbG91ZHN0YXJ0JywgdHJ1ZSkpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KCiAgICAgIC8vIERldGVybWluZSB0aGUgY2VudGVyIG9mIHRoZSB3b3JkIGNsb3VkCiAgICAgIGNlbnRlciA9IChzZXR0aW5ncy5vcmlnaW4pID8KICAgICAgICBbc2V0dGluZ3Mub3JpZ2luWzBdL2csIHNldHRpbmdzLm9yaWdpblsxXS9nXSA6CiAgICAgICAgW25neCAvIDIsIG5neSAvIDJdOwoKICAgICAgLy8gTWF4aXVtIHJhZGl1cyB0byBsb29rIGZvciBzcGFjZQogICAgICBtYXhSYWRpdXMgPSBNYXRoLmZsb29yKE1hdGguc3FydChuZ3ggKiBuZ3ggKyBuZ3kgKiBuZ3kpKTsKCiAgICAgIC8qIENsZWFyIHRoZSBjYW52YXMgb25seSBpZiB0aGUgY2xlYXJDYW52YXMgaXMgc2V0LAogICAgICAgICBpZiBub3QsIHVwZGF0ZSB0aGUgZ3JpZCB0byB0aGUgY3VycmVudCBjYW52YXMgc3RhdGUgKi8KICAgICAgZ3JpZCA9IFtdOwoKICAgICAgdmFyIGd4LCBneSwgaTsKICAgICAgaWYgKCFjYW52YXMuZ2V0Q29udGV4dCB8fCBzZXR0aW5ncy5jbGVhckNhbnZhcykgewogICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWwpIHsKICAgICAgICAgIGlmIChlbC5nZXRDb250ZXh0KSB7CiAgICAgICAgICAgIHZhciBjdHggPSBlbC5nZXRDb250ZXh0KCcyZCcpOwogICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gc2V0dGluZ3MuYmFja2dyb3VuZENvbG9yOwogICAgICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIG5neCAqIChnICsgMSksIG5neSAqIChnICsgMSkpOwogICAgICAgICAgICBjdHguZmlsbFJlY3QoMCwgMCwgbmd4ICogKGcgKyAxKSwgbmd5ICogKGcgKyAxKSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbC50ZXh0Q29udGVudCA9ICcnOwogICAgICAgICAgICBlbC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBzZXR0aW5ncy5iYWNrZ3JvdW5kQ29sb3I7CiAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIC8qIGZpbGwgdGhlIGdyaWQgd2l0aCBlbXB0eSBzdGF0ZSAqLwogICAgICAgIGd4ID0gbmd4OwogICAgICAgIHdoaWxlIChneC0tKSB7CiAgICAgICAgICBncmlkW2d4XSA9IFtdOwogICAgICAgICAgZ3kgPSBuZ3k7CiAgICAgICAgICB3aGlsZSAoZ3ktLSkgewogICAgICAgICAgICBncmlkW2d4XVtneV0gPSB0cnVlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBEZXRlcm1pbmUgYmdQaXhlbCBieSBjcmVhdGluZwogICAgICAgICAgIGFub3RoZXIgY2FudmFzIGFuZCBmaWxsIHRoZSBzcGVjaWZpZWQgYmFja2dyb3VuZCBjb2xvci4gKi8KICAgICAgICB2YXIgYmN0eCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyk7CgogICAgICAgIGJjdHguZmlsbFN0eWxlID0gc2V0dGluZ3MuYmFja2dyb3VuZENvbG9yOwogICAgICAgIGJjdHguZmlsbFJlY3QoMCwgMCwgMSwgMSk7CiAgICAgICAgdmFyIGJnUGl4ZWwgPSBiY3R4LmdldEltYWdlRGF0YSgwLCAwLCAxLCAxKS5kYXRhOwoKICAgICAgICAvKiBSZWFkIGJhY2sgdGhlIHBpeGVscyBvZiB0aGUgY2FudmFzIHdlIGdvdCB0byB0ZWxsIHdoaWNoIHBhcnQgb2YgdGhlCiAgICAgICAgICAgY2FudmFzIGlzIGVtcHR5LgogICAgICAgICAgIChubyBjbGVhckNhbnZhcyBvbmx5IHdvcmtzIHdpdGggYSBjYW52YXMsIG5vdCBkaXZzKSAqLwogICAgICAgIHZhciBpbWFnZURhdGEgPQogICAgICAgICAgY2FudmFzLmdldENvbnRleHQoJzJkJykuZ2V0SW1hZ2VEYXRhKDAsIDAsIG5neCAqIGcsIG5neSAqIGcpLmRhdGE7CgogICAgICAgIGd4ID0gbmd4OwogICAgICAgIHZhciB4LCB5OwogICAgICAgIHdoaWxlIChneC0tKSB7CiAgICAgICAgICBncmlkW2d4XSA9IFtdOwogICAgICAgICAgZ3kgPSBuZ3k7CiAgICAgICAgICB3aGlsZSAoZ3ktLSkgewogICAgICAgICAgICB5ID0gZzsKICAgICAgICAgICAgc2luZ2xlR3JpZExvb3A6IHdoaWxlICh5LS0pIHsKICAgICAgICAgICAgICB4ID0gZzsKICAgICAgICAgICAgICB3aGlsZSAoeC0tKSB7CiAgICAgICAgICAgICAgICBpID0gNDsKICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICAgICAgICAgICAgaWYgKGltYWdlRGF0YVsoKGd5ICogZyArIHkpICogbmd4ICogZyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChneCAqIGcgKyB4KSkgKiA0ICsgaV0gIT09IGJnUGl4ZWxbaV0pIHsKICAgICAgICAgICAgICAgICAgICBncmlkW2d4XVtneV0gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhayBzaW5nbGVHcmlkTG9vcDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZ3JpZFtneF1bZ3ldICE9PSBmYWxzZSkgewogICAgICAgICAgICAgIGdyaWRbZ3hdW2d5XSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGltYWdlRGF0YSA9IGJjdHggPSBiZ1BpeGVsID0gdW5kZWZpbmVkOwogICAgICB9CgogICAgICAvLyBmaWxsIHRoZSBpbmZvR3JpZCB3aXRoIGVtcHR5IHN0YXRlIGlmIHdlIG5lZWQgaXQKICAgICAgaWYgKHNldHRpbmdzLmhvdmVyIHx8IHNldHRpbmdzLmNsaWNrKSB7CgogICAgICAgIGludGVyYWN0aXZlID0gdHJ1ZTsKCiAgICAgICAgLyogZmlsbCB0aGUgZ3JpZCB3aXRoIGVtcHR5IHN0YXRlICovCiAgICAgICAgZ3ggPSBuZ3ggKyAxOwogICAgICAgIHdoaWxlIChneC0tKSB7CiAgICAgICAgICBpbmZvR3JpZFtneF0gPSBbXTsKICAgICAgICB9CgogICAgICAgIGlmIChzZXR0aW5ncy5ob3ZlcikgewogICAgICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHdvcmRjbG91ZGhvdmVyKTsKICAgICAgICB9CgogICAgICAgIGlmIChzZXR0aW5ncy5jbGljaykgewogICAgICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgd29yZGNsb3VkY2xpY2spOwogICAgICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB3b3JkY2xvdWRjbGljayk7CiAgICAgICAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICB9KTsKICAgICAgICAgIGNhbnZhcy5zdHlsZS53ZWJraXRUYXBIaWdobGlnaHRDb2xvciA9ICdyZ2JhKDAsIDAsIDAsIDApJzsKICAgICAgICB9CgogICAgICAgIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCd3b3JkY2xvdWRzdGFydCcsIGZ1bmN0aW9uIHN0b3BJbnRlcmFjdGlvbigpIHsKICAgICAgICAgIGNhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCd3b3JkY2xvdWRzdGFydCcsIHN0b3BJbnRlcmFjdGlvbik7CgogICAgICAgICAgY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHdvcmRjbG91ZGhvdmVyKTsKICAgICAgICAgIGNhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHdvcmRjbG91ZGNsaWNrKTsKICAgICAgICAgIGhvdmVyZWQgPSB1bmRlZmluZWQ7CiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIGkgPSAwOwogICAgICB2YXIgbG9vcGluZ0Z1bmN0aW9uLCBzdG9wcGluZ0Z1bmN0aW9uOwogICAgICBpZiAoc2V0dGluZ3Mud2FpdCAhPT0gMCkgewogICAgICAgIGxvb3BpbmdGdW5jdGlvbiA9IHdpbmRvdy5zZXRUaW1lb3V0OwogICAgICAgIHN0b3BwaW5nRnVuY3Rpb24gPSB3aW5kb3cuY2xlYXJUaW1lb3V0OwogICAgICB9IGVsc2UgewogICAgICAgIGxvb3BpbmdGdW5jdGlvbiA9IHdpbmRvdy5zZXRJbW1lZGlhdGU7CiAgICAgICAgc3RvcHBpbmdGdW5jdGlvbiA9IHdpbmRvdy5jbGVhckltbWVkaWF0ZTsKICAgICAgfQoKICAgICAgdmFyIGFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7CiAgICAgICAgZWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbihlbCkgewogICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcik7CiAgICAgICAgfSwgdGhpcyk7CiAgICAgIH07CgogICAgICB2YXIgcmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHsKICAgICAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsKSB7CiAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKTsKICAgICAgICB9LCB0aGlzKTsKICAgICAgfTsKCiAgICAgIHZhciBhbm90aGVyV29yZENsb3VkU3RhcnQgPSBmdW5jdGlvbiBhbm90aGVyV29yZENsb3VkU3RhcnQoKSB7CiAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpOwogICAgICAgIHN0b3BwaW5nRnVuY3Rpb24odGltZXIpOwogICAgICB9OwoKICAgICAgYWRkRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpOwoKICAgICAgdmFyIHRpbWVyID0gbG9vcGluZ0Z1bmN0aW9uKGZ1bmN0aW9uIGxvb3AoKSB7CiAgICAgICAgaWYgKGkgPj0gc2V0dGluZ3MubGlzdC5sZW5ndGgpIHsKICAgICAgICAgIHN0b3BwaW5nRnVuY3Rpb24odGltZXIpOwogICAgICAgICAgc2VuZEV2ZW50KCd3b3JkY2xvdWRzdG9wJywgZmFsc2UpOwogICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpOwoKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZXNjYXBlVGltZSA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7CiAgICAgICAgdmFyIGRyYXduID0gcHV0V29yZChzZXR0aW5ncy5saXN0W2ldKTsKICAgICAgICB2YXIgY2FuY2VsZWQgPSAhc2VuZEV2ZW50KCd3b3JkY2xvdWRkcmF3bicsIHRydWUsIHsKICAgICAgICAgIGl0ZW06IHNldHRpbmdzLmxpc3RbaV0sIGRyYXduOiBkcmF3biB9KTsKICAgICAgICBpZiAoZXhjZWVkVGltZSgpIHx8IGNhbmNlbGVkKSB7CiAgICAgICAgICBzdG9wcGluZ0Z1bmN0aW9uKHRpbWVyKTsKICAgICAgICAgIHNldHRpbmdzLmFib3J0KCk7CiAgICAgICAgICBzZW5kRXZlbnQoJ3dvcmRjbG91ZGFib3J0JywgZmFsc2UpOwogICAgICAgICAgc2VuZEV2ZW50KCd3b3JkY2xvdWRzdG9wJywgZmFsc2UpOwogICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcignd29yZGNsb3Vkc3RhcnQnLCBhbm90aGVyV29yZENsb3VkU3RhcnQpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICAgICAgdGltZXIgPSBsb29waW5nRnVuY3Rpb24obG9vcCwgc2V0dGluZ3Mud2FpdCk7CiAgICAgIH0sIHNldHRpbmdzLndhaXQpOwogICAgfTsKCiAgICAvLyBBbGwgc2V0LCBzdGFydCB0aGUgZHJhd2luZwogICAgc3RhcnQoKTsKICB9OwoKICBXb3JkQ2xvdWQuaXNTdXBwb3J0ZWQgPSBpc1N1cHBvcnRlZDsKICBXb3JkQ2xvdWQubWluRm9udFNpemUgPSBtaW5Gb250U2l6ZTsKCiAgLy8gRXhwb3NlIHRoZSBsaWJyYXJ5IGFzIGFuIEFNRCBtb2R1bGUKICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7CiAgICBkZWZpbmUoJ3dvcmRjbG91ZCcsIFtdLCBmdW5jdGlvbigpIHsgcmV0dXJuIFdvcmRDbG91ZDsgfSk7CiAgfSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgbW9kdWxlLmV4cG9ydHMgPSBXb3JkQ2xvdWQ7CiAgfSBlbHNlIHsKICAgIGdsb2JhbC5Xb3JkQ2xvdWQgPSBXb3JkQ2xvdWQ7CiAgfQoKfSkodGhpcyk7IC8vanNoaW50IGlnbm9yZTpsaW5lCg==\"></script>\r\n",
"<script src=\"data:application/x-javascript;base64,Ly8gY3JlYXRlIGVsZW1lbnQKZnVuY3Rpb24gbmV3bGFiZWwoZWwpewogIHZhciBuZXdEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICB2YXIgbmV3U3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsKICBuZXdEaXYuaWQgPSAnd2NMYWJlbCc7CiAgbmV3U3Bhbi5pZCA9ICJ3Y1NwYW4iOwogIGVsLmFwcGVuZENoaWxkKG5ld0Rpdik7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIndjTGFiZWwiKS5hcHBlbmRDaGlsZChuZXdTcGFuKTsKfQoKLy8gaG92ZXIgZnVuY3Rpb24KZnVuY3Rpb24gY3ZfaGFuZGxlSG92ZXIoaXRlbSwgZGltZW5zaW9uLCBldnQpIHsKICB2YXIgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgid2NMYWJlbCIpOwogIGlmICghaXRlbSkgewogICAgZWwuc2V0QXR0cmlidXRlKCdoaWRkZW4nLCB0cnVlKTsKCiAgICByZXR1cm47CiAgfQoKICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2hpZGRlbicpOwogIC8vIGNvbnNvbGUubG9nKGV2dC5zcmNFbGVtZW50Lm9mZnNldExlZnQpOwoKICBlbC5zdHlsZS5sZWZ0ID0gZGltZW5zaW9uLnggKyBldnQuc3JjRWxlbWVudC5vZmZzZXRMZWZ0ICsgJ3B4JzsKICBlbC5zdHlsZS50b3AgPSBkaW1lbnNpb24ueSArIGV2dC5zcmNFbGVtZW50Lm9mZnNldFRvcCArICdweCc7CiAgZWwuc3R5bGUud2lkdGggPSBkaW1lbnNpb24udyArICdweCc7CiAgZWwuc3R5bGUuaGVpZ2h0ID0gZGltZW5zaW9uLmggKyAncHgnOwoKICB0aGlzLmhvdmVyRGltZW5zaW9uID0gZGltZW5zaW9uOwoKICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgid2NTcGFuIikuc2V0QXR0cmlidXRlKAogICAgJ2RhdGEtbDEwbi1hcmdzJywgSlNPTi5zdHJpbmdpZnkoeyB3b3JkOiBpdGVtWzBdLCBjb3VudDogaXRlbVsxXSB9KSk7CiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIndjU3BhbiIpLmlubmVySFRNTCA9aXRlbVswXSsiOiIgKyBpdGVtWzFdOwoKfQoKZnVuY3Rpb24gdXBkYXRlQ2FudmFzTWFzayhtYXNrQ2FudmFzKSB7CiAgICB2YXIgY3R4ID0gbWFza0NhbnZhcy5nZXRDb250ZXh0KCcyZCcpOwogICAgdmFyIGltYWdlRGF0YSA9IGN0eC5nZXRJbWFnZURhdGEoCiAgICAgICAgMCwgMCwgbWFza0NhbnZhcy53aWR0aCwgbWFza0NhbnZhcy5oZWlnaHQpOwogICAgdmFyIG5ld0ltYWdlRGF0YSA9IGN0eC5jcmVhdGVJbWFnZURhdGEoaW1hZ2VEYXRhKTsKCiAgICB2YXIgdG9uZVN1bSA9IDA7CiAgICB2YXIgdG9uZUNudCA9IDA7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGltYWdlRGF0YS5kYXRhLmxlbmd0aDsgaSArPSA0KSB7CiAgICAgICAgdmFyIGFscGhhID0gaW1hZ2VEYXRhLmRhdGFbaSArIDNdOwogICAgICAgIGlmIChhbHBoYSA+IDEyOCkgewogICAgICAgICAgICB2YXIgdG9uZSA9IGltYWdlRGF0YS5kYXRhW2ldCiAgICAgICAgICAgICAgICArIGltYWdlRGF0YS5kYXRhW2kgKyAxXQogICAgICAgICAgICAgICAgKyBpbWFnZURhdGEuZGF0YVtpICsgMl07CiAgICAgICAgICAgIHRvbmVTdW0gKz0gdG9uZTsKICAgICAgICAgICAgKyt0b25lQ250OwogICAgICAgIH0KICAgIH0KICAgIHZhciB0aHJlc2hvbGQgPSB0b25lU3VtIC8gdG9uZUNudDsKCiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGltYWdlRGF0YS5kYXRhLmxlbmd0aDsgaSArPSA0KSB7CiAgICAgICAgdmFyIHRvbmUgPSBpbWFnZURhdGEuZGF0YVtpXQogICAgICAgICAgICArIGltYWdlRGF0YS5kYXRhW2kgKyAxXQogICAgICAgICAgICArIGltYWdlRGF0YS5kYXRhW2kgKyAyXTsKICAgICAgICB2YXIgYWxwaGEgPSBpbWFnZURhdGEuZGF0YVtpICsgM107CgogICAgICAgIGlmIChhbHBoYSA8IDEyOCB8fCB0b25lID4gdGhyZXNob2xkKSB7CiAgICAgICAgICAgIC8vIEFyZWEgbm90IHRvIGRyYXcKICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaV0gPSAwOwogICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgMV0gPSAwOwogICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgMl0gPSAwOwogICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgM10gPSAwOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLy8gQXJlYSB0byBkcmF3CiAgICAgICAgICAgIC8vIFRoZSBjb2xvciBtdXN0IGJlIHNhbWUgd2l0aCBiYWNrZ3JvdW5kQ29sb3IKICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaV0gPSAyNTU7CiAgICAgICAgICAgIG5ld0ltYWdlRGF0YS5kYXRhW2kgKyAxXSA9IDI1NTsKICAgICAgICAgICAgbmV3SW1hZ2VEYXRhLmRhdGFbaSArIDJdID0gMjU1OwogICAgICAgICAgICBuZXdJbWFnZURhdGEuZGF0YVtpICsgM10gPSAyNTU7CiAgICAgICAgfQogICAgfQoKICAgIGN0eC5wdXRJbWFnZURhdGEobmV3SW1hZ2VEYXRhLCAwLCAwKTsKICAgIGNvbnNvbGUubG9nKG1hc2tDYW52YXMudG9EYXRhVVJMKCkpOwp9CgoKCi8vbWFzayBmdW5jdGlvbgpmdW5jdGlvbiBtYXNrSW5pdChlbCx4KXsKICBjb25zb2xlLmxvZygxKQogIHN0ciA9IHguZmlnQmFzZTY0OwogIC8vY29uc29sZS5sb2coc3RyKQogIHZhciBuZXdJbWcgPSBuZXcgSW1hZ2UoKTsKICBuZXdJbWcuc3JjID0gc3RyOwogIG5ld0ltZy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7CiAgbmV3SW1nLnN0eWxlLmxlZnQgPSAwOwogIC8vIGNvbnNvbGUubG9nKGVsLmNsaWVudEhlaWdodCk7CiAgbmV3SW1nLndpZHRoID0gZWwuY2xpZW50V2lkdGg7CiAgbmV3SW1nLmhlaWdodCA9IGVsLmNsaWVudEhlaWdodDsKICAvLyBtYXNrQ2FudmFzID0gaW5pdChlbCwgeCwgbmV3SW1nKTsKICB2dmFsdWUgPSAxMjgKCiAgY3R4ID0gZWwuZmlyc3RDaGlsZC5nZXRDb250ZXh0KCcyZCcpOwoKICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2UobmV3SW1nLCAwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpOwogICAgICAgICAgICAgICAgdXBkYXRlQ2FudmFzTWFzayhjdHgpOwoKCgoKCiAgICAgICAgICAgIFdvcmRDbG91ZChlbC5maXJzdENoaWxkLCB7IGxpc3Q6IGxpc3REYXRhLAogICAgICAgICAgICAgICAgICBmb250RmFtaWx5OiB4LmZvbnRGYW1pbHksCiAgICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IHguZm9udFdlaWdodCwKICAgICAgICAgICAgICAgICAgY29sb3I6IHguY29sb3IsCiAgICAgICAgICAgICAgICAgIG1pblNpemU6IHgubWluU2l6ZSwKICAgICAgICAgICAgICAgICAgd2VpZ2h0RmFjdG9yOiB4LndlaWdodEZhY3RvciwKICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB4LmJhY2tncm91bmRDb2xvciwKICAgICAgICAgICAgICAgICAgZ3JpZFNpemU6IHguZ3JpZFNpemUsCiAgICAgICAgICAgICAgICAgIG1pblJvdGF0aW9uOiB4Lm1pblJvdGF0aW9uLAogICAgICAgICAgICAgICAgICBtYXhSb3RhdGlvbjogeC5tYXhSb3RhdGlvbiwKICAgICAgICAgICAgICAgICAgc2h1ZmZsZTogeC5zaHVmZmxlLAogICAgICAgICAgICAgICAgICBzaGFwZTogeC5zaGFwZSwKICAgICAgICAgICAgICAgICAgcm90YXRlUmF0aW86IHgucm90YXRlUmF0aW8sCiAgICAgICAgICAgICAgICAgIGVsbGlwdGljaXR5OiB4LmVsbGlwdGljaXR5LAogICAgICAgICAgICAgICAgICBjbGVhckNhbnZhczogZmFsc2UsCiAgICAgICAgICAgICAgICAgIGRyYXdNYXNrOiB0cnVlLAogICAgICAgICAgICAgICAgICBob3ZlcjogeC5ob3ZlciB8fCBjdl9oYW5kbGVIb3ZlciwKICAgICAgICAgICAgICAgICAgYWJvcnRUaHJlc2hvbGQ6IDMwMDAKICAgICAgICAgICAgICAgICAgfSk7Cn0KCg==\"></script>\r\n",
"<script src=\"data:application/x-javascript;base64,SFRNTFdpZGdldHMud2lkZ2V0KHsKCiAgbmFtZTogJ3dvcmRjbG91ZDInLAoKICB0eXBlOiAnb3V0cHV0JywKCiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWwsIHdpZHRoLCBoZWlnaHQpIHsKICAgIHZhciBuZXdDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJjYW52YXMiKTsKICAgIG5ld0NhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7CiAgICBuZXdDYW52YXMud2lkdGggPSB3aWR0aDsKICAgIG5ld0NhbnZhcy5pZCA9ICJjYW52YXMiOwoKICAgIGVsLmFwcGVuZENoaWxkKG5ld0NhbnZhcyk7CiAgICBuZXdsYWJlbChlbCk7CiAgICByZXR1cm4oZWwuZmlyc3RDaGlsZCk7CiAgfSwKICByZW5kZXJWYWx1ZTogZnVuY3Rpb24oZWwsIHgsIGluc3RhbmNlKSB7CiAgLy8gcGFyc2UgZ2V4ZiBkYXRhCiAgICAgICAgbGlzdERhdGE9W107CiAgICAgICAgZm9yKHZhciBpPTA7IGk8eC53b3JkLmxlbmd0aDsgaSsrKXsKICAgICAgICAgIGxpc3REYXRhLnB1c2goW3gud29yZFtpXSwgeC5mcmVxW2ldXSk7CiAgICAgICAgfQogICAgIGlmKHguZmlnQmFzZTY0KXsKCiAgICAgICAgbWFza0luaXQoZWwseCk7CiAgICAgICAgY29uc29sZS5sb2coMykKCiAgICAgIH1lbHNlewogICAgICAgIFdvcmRDbG91ZChlbC5maXJzdENoaWxkLCB7IGxpc3Q6IGxpc3REYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5OiB4LmZvbnRGYW1pbHksCiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IHguZm9udFdlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I6IHguY29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pblNpemU6IHgubWluU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgd2VpZ2h0RmFjdG9yOiB4LndlaWdodEZhY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiB4LmJhY2tncm91bmRDb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgZ3JpZFNpemU6IHguZ3JpZFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pblJvdGF0aW9uOiB4Lm1pblJvdGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICBtYXhSb3RhdGlvbjogeC5tYXhSb3RhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgc2h1ZmZsZTogeC5zaHVmZmxlLAogICAgICAgICAgICAgICAgICAgICAgICBzaGFwZTogeC5zaGFwZSwKICAgICAgICAgICAgICAgICAgICAgICAgcm90YXRlUmF0aW86IHgucm90YXRlUmF0aW8sCiAgICAgICAgICAgICAgICAgICAgICAgIGVsbGlwdGljaXR5OiB4LmVsbGlwdGljaXR5LAogICAgICAgICAgICAgICAgICAgICAgICBkcmF3TWFzazogeC5kcmF3TWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgbWFza0NvbG9yOiB4Lm1hc2tDb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgbWFza0dhcFdpZHRoOiB4Lm1hc2tHYXBXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXI6IHguaG92ZXIgfHwgY3ZfaGFuZGxlSG92ZXIKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgIH0KICAgIH0sCiAgICAgIHJlc2l6ZTogZnVuY3Rpb24oZWwsIHdpZHRoLCBoZWlnaHQpIHsKICAgICAgfQoKfSk7Cg==\"></script>\r\n",
"</head>\r\n",
"<body style=\"background-color: white;\">\r\n",
"<div id=\"htmlwidget_container\">\r\n",
"<div id=\"htmlwidget-df008a2f0e061d383ca4\" class=\"wordcloud2 html-widget\" style=\"width:960px;height:500px;\">\r\n",
"\r\n",
"</div>\r\n",
"</div>\r\n",
"<script type=\"application/json\" data-for=\"htmlwidget-df008a2f0e061d383ca4\">{\"x\":{\"word\":[\"work\",\"dirt\",\"learn\",\"tired\",\"see\",\"done\",\"something\",\"nah\",\"need\",\"rolling\",\"just\",\"never\",\"bout\",\"don\",\"get\",\"gon\",\"turn\",\"baby\",\"care\",\"duh\",\"hope\",\"mmmmm\",\"na\",\"nana\",\"oh\",\"time\",\"away\",\"come\",\"face\",\"gimme\",\"got\",\"heart\",\"know\",\"leave\",\"nobody\",\"please\",\"sorry\",\"took\",\"ve\",\"yeah\",\"another\",\"believed\",\"brought\",\"can\",\"chance\",\"choose\",\"crisis\",\"dealt\",\"decoration\",\"deserved\",\"distance\",\"dreams\",\"duration\",\"emotions\",\"end\",\"everything\",\"forward\",\"foundation\",\"friendly\",\"gets\",\"give\",\"gotta\",\"hold\",\"join\",\"keys\",\"less\",\"like\",\"ll\",\"long\",\"love\",\"lurking\",\"many\",\"mean\",\"might\",\"mistaken\",\"motion\",\"neglect\",\"nicest\",\"niggas\",\"now\",\"okay\",\"one\",\"past\",\"patience\",\"pick\",\"place\",\"potential\",\"re\",\"ready\",\"recognize\",\"right\",\"righteous\",\"rush\",\"say\",\"seen\",\"shots\",\"sleeve\",\"slow\",\"soon\",\"spent\",\"spilled\",\"still\",\"streets\",\"stuck\",\"table\",\"text\",\"tonight\",\"touch\",\"true\",\"trying\",\"tryna\",\"twin\",\"wake\",\"wanna\",\"wanted\",\"way\",\"will\",\"wrong\"],\"freq\":[79,24,18,18,12,8,8,6,6,6,5,5,4,4,4,4,4,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"fontFamily\":\"Segoe UI\",\"fontWeight\":\"bold\",\"color\":\"random-dark\",\"minSize\":0,\"weightFactor\":2.27848101265823,\"backgroundColor\":\"white\",\"gridSize\":0,\"minRotation\":-0.785398163397448,\"maxRotation\":0.785398163397448,\"shuffle\":true,\"rotateRatio\":0.4,\"shape\":\"circle\",\"ellipticity\":0.65,\"figBase64\":null,\"hover\":null},\"evals\":[],\"jsHooks\":{\"render\":[{\"code\":\"function(el,x){\\n console.log(123);\\n if(!iii){\\n window.location.reload();\\n iii = False;\\n\\n }\\n }\",\"data\":null}]}}</script>\r\n",
"<script type=\"application/htmlwidget-sizing\" data-for=\"htmlwidget-df008a2f0e061d383ca4\">{\"viewer\":{\"width\":450,\"height\":350,\"padding\":0,\"fill\":true},\"browser\":{\"width\":960,\"height\":500,\"padding\":0,\"fill\":true}}</script>\r\n",
"</body>\r\n",
"</html>\r\n"
],
"text/plain": [
"HTML widgets cannot be represented in plain text (need html)"
]
},
"metadata": {
"text/html": {
"isolated": true
}
},
"output_type": "display_data"
}
],
"source": [
"#import lyrics of 2nd file\n",
"lyrics_word(scan(\"lyrics2.txt\",what=\"character\",sep=\"\\n\"))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "R",
"language": "R",
"name": "ir"
},
"language_info": {
"codemirror_mode": "r",
"file_extension": ".r",
"mimetype": "text/x-r-source",
"name": "R",
"pygments_lexer": "r",
"version": "3.4.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment