IyEgL3Vzci9iaW4vZW52IHB5dGhvbgojIC0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCiMgT3JpZ2luYWxseSB3cml0dGVuIGJ5IEJhcnJ5IFdhcnNhdyA8YmFycnlAem9wZS5jb20+CiMKIyBNaW5pbWFsbHkgcGF0Y2hlZCB0byBtYWtlIGl0IGV2ZW4gbW9yZSB4Z2V0dGV4dCBjb21wYXRpYmxlCiMgYnkgUGV0ZXIgRnVuayA8cGZAYXJ0Y29tLWdtYmguZGU+CiMKIyAyMDAyLTExLTIyIEr8cmdlbiBIZXJtYW5uIDxqaEB3ZWIuZGU+CiMgQWRkZWQgY2hlY2tzIHRoYXQgXygpIG9ubHkgY29udGFpbnMgc3RyaW5nIGxpdGVyYWxzLCBhbmQKIyBjb21tYW5kIGxpbmUgYXJncyBhcmUgcmVzb2x2ZWQgdG8gbW9kdWxlIGxpc3RzLCBpLmUuIHlvdQojIGNhbiBub3cgcGFzcyBhIGZpbGVuYW1lLCBhIG1vZHVsZSBvciBwYWNrYWdlIG5hbWUsIG9yIGEKIyBkaXJlY3RvcnkgKGluY2x1ZGluZyBnbG9iYmluZyBjaGFycywgaW1wb3J0YW50IGZvciBXaW4zMikuCiMgTWFkZSBkb2NzdHJpbmcgZml0IGluIDgwIGNoYXJzIHdpZGUgZGlzcGxheXMgdXNpbmcgcHlkb2MuCiMKCiMgZm9yIHNlbGZ0ZXN0aW5nCnRyeToKICAgIGltcG9ydCBmaW50bAogICAgXyA9IGZpbnRsLmdldHRleHQKZXhjZXB0IEltcG9ydEVycm9yOgogICAgXyA9IGxhbWJkYSBzOiBzCgpfX2RvY19fID0gXygiIiJweWdldHRleHQgLS0gUHl0aG9uIGVxdWl2YWxlbnQgb2YgeGdldHRleHQoMSkKCk1hbnkgc3lzdGVtcyAoU29sYXJpcywgTGludXgsIEdudSkgcHJvdmlkZSBleHRlbnNpdmUgdG9vbHMgdGhhdCBlYXNlIHRoZQppbnRlcm5hdGlvbmFsaXphdGlvbiBvZiBDIHByb2dyYW1zLiBNb3N0IG9mIHRoZXNlIHRvb2xzIGFyZSBpbmRlcGVuZGVudCBvZgp0aGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgYW5kIGNhbiBiZSB1c2VkIGZyb20gd2l0aGluIFB5dGhvbiBwcm9ncmFtcy4KTWFydGluIHZvbiBMb2V3aXMnIHdvcmtbMV0gaGVscHMgY29uc2lkZXJhYmx5IGluIHRoaXMgcmVnYXJkLgoKVGhlcmUncyBvbmUgcHJvYmxlbSB0aG91Z2g7IHhnZXR0ZXh0IGlzIHRoZSBwcm9ncmFtIHRoYXQgc2NhbnMgc291cmNlIGNvZGUKbG9va2luZyBmb3IgbWVzc2FnZSBzdHJpbmdzLCBidXQgaXQgZ3Jva3Mgb25seSBDIChvciBDKyspLiBQeXRob24KaW50cm9kdWNlcyBhIGZldyB3cmlua2xlcywgc3VjaCBhcyBkdWFsIHF1b3RpbmcgY2hhcmFjdGVycywgdHJpcGxlIHF1b3RlZApzdHJpbmdzLCBhbmQgcmF3IHN0cmluZ3MuIHhnZXR0ZXh0IHVuZGVyc3RhbmRzIG5vbmUgb2YgdGhpcy4KCkVudGVyIHB5Z2V0dGV4dCwgd2hpY2ggdXNlcyBQeXRob24ncyBzdGFuZGFyZCB0b2tlbml6ZSBtb2R1bGUgdG8gc2NhbgpQeXRob24gc291cmNlIGNvZGUsIGdlbmVyYXRpbmcgLnBvdCBmaWxlcyBpZGVudGljYWwgdG8gd2hhdCBHTlUgeGdldHRleHRbMl0KZ2VuZXJhdGVzIGZvciBDIGFuZCBDKysgY29kZS4gRnJvbSB0aGVyZSwgdGhlIHN0YW5kYXJkIEdOVSB0b29scyBjYW4gYmUKdXNlZC4KCkEgd29yZCBhYm91dCBtYXJraW5nIFB5dGhvbiBzdHJpbmdzIGFzIGNhbmRpZGF0ZXMgZm9yIHRyYW5zbGF0aW9uLiBHTlUKeGdldHRleHQgcmVjb2duaXplcyB0aGUgZm9sbG93aW5nIGtleXdvcmRzOiBnZXR0ZXh0LCBkZ2V0dGV4dCwgZGNnZXR0ZXh0LAphbmQgZ2V0dGV4dF9ub29wLiBCdXQgdGhvc2UgY2FuIGJlIGEgbG90IG9mIHRleHQgdG8gaW5jbHVkZSBhbGwgb3ZlciB5b3VyCmNvZGUuIEMgYW5kIEMrKyBoYXZlIGEgdHJpY2s6IHRoZXkgdXNlIHRoZSBDIHByZXByb2Nlc3Nvci4gTW9zdAppbnRlcm5hdGlvbmFsaXplZCBDIHNvdXJjZSBpbmNsdWRlcyBhICNkZWZpbmUgZm9yIGdldHRleHQoKSB0byBfKCkgc28gdGhhdAp3aGF0IGhhcyB0byBiZSB3cml0dGVuIGluIHRoZSBzb3VyY2UgaXMgbXVjaCBsZXNzLiBUaHVzIHRoZXNlIGFyZSBib3RoCnRyYW5zbGF0YWJsZSBzdHJpbmdzOgoKICAgIGdldHRleHQoIlRyYW5zbGF0YWJsZSBTdHJpbmciKQogICAgXygiVHJhbnNsYXRhYmxlIFN0cmluZyIpCgpQeXRob24gb2YgY291cnNlIGhhcyBubyBwcmVwcm9jZXNzb3Igc28gdGhpcyBkb2Vzbid0IHdvcmsgc28gd2VsbC4gIFRodXMsCnB5Z2V0dGV4dCBzZWFyY2hlcyBvbmx5IGZvciBfKCkgYnkgZGVmYXVsdCwgYnV0IHNlZSB0aGUgLWsvLS1rZXl3b3JkIGZsYWcKYmVsb3cgZm9yIGhvdyB0byBhdWdtZW50IHRoaXMuCgogWzFdIGh0dHA6Ly93d3cucHl0aG9uLm9yZy93b3Jrc2hvcHMvMTk5Ny0xMC9wcm9jZWVkaW5ncy9sb2V3aXMuaHRtbAogWzJdIGh0dHA6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9nZXR0ZXh0L2dldHRleHQuaHRtbAoKTk9URTogcHlnZXR0ZXh0IGF0dGVtcHRzIHRvIGJlIG9wdGlvbiBhbmQgZmVhdHVyZSBjb21wYXRpYmxlIHdpdGggR05VCnhnZXR0ZXh0IHdoZXJlIGV2ZXIgcG9zc2libGUuIEhvd2V2ZXIgc29tZSBvcHRpb25zIGFyZSBzdGlsbCBtaXNzaW5nIG9yIGFyZQpub3QgZnVsbHkgaW1wbGVtZW50ZWQuIEFsc28sIHhnZXR0ZXh0J3MgdXNlIG9mIGNvbW1hbmQgbGluZSBzd2l0Y2hlcyB3aXRoCm9wdGlvbiBhcmd1bWVudHMgaXMgYnJva2VuLCBhbmQgaW4gdGhlc2UgY2FzZXMsIHB5Z2V0dGV4dCBqdXN0IGRlZmluZXMKYWRkaXRpb25hbCBzd2l0Y2hlcy4KClVzYWdlOiBweWdldHRleHQgW29wdGlvbnNdIGlucHV0ZmlsZSAuLi4KCk9wdGlvbnM6CgogICAgLWEKICAgIC0tZXh0cmFjdC1hbGwKICAgICAgICBFeHRyYWN0IGFsbCBzdHJpbmdzLgoKICAgIC1kIG5hbWUKICAgIC0tZGVmYXVsdC1kb21haW49bmFtZQogICAgICAgIFJlbmFtZSB0aGUgZGVmYXVsdCBvdXRwdXQgZmlsZSBmcm9tIG1lc3NhZ2VzLnBvdCB0byBuYW1lLnBvdC4KCiAgICAtRQogICAgLS1lc2NhcGUKICAgICAgICBSZXBsYWNlIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIHdpdGggb2N0YWwgZXNjYXBlIHNlcXVlbmNlcy4KCiAgICAtRAogICAgLS1kb2NzdHJpbmdzCiAgICAgICAgRXh0cmFjdCBtb2R1bGUsIGNsYXNzLCBtZXRob2QsIGFuZCBmdW5jdGlvbiBkb2NzdHJpbmdzLiAgVGhlc2UgZG8KICAgICAgICBub3QgbmVlZCB0byBiZSB3cmFwcGVkIGluIF8oKSBtYXJrZXJzLCBhbmQgaW4gZmFjdCBjYW5ub3QgYmUgZm9yCiAgICAgICAgUHl0aG9uIHRvIGNvbnNpZGVyIHRoZW0gZG9jc3RyaW5ncy4gKFNlZSBhbHNvIHRoZSAtWCBvcHRpb24pLgoKICAgIC1oCiAgICAtLWhlbHAKICAgICAgICBQcmludCB0aGlzIGhlbHAgbWVzc2FnZSBhbmQgZXhpdC4KCiAgICAtayB3b3JkCiAgICAtLWtleXdvcmQ9d29yZAogICAgICAgIEtleXdvcmRzIHRvIGxvb2sgZm9yIGluIGFkZGl0aW9uIHRvIHRoZSBkZWZhdWx0IHNldCwgd2hpY2ggYXJlOgogICAgICAgICUoREVGQVVMVEtFWVdPUkRTKXMKCiAgICAgICAgWW91IGNhbiBoYXZlIG11bHRpcGxlIC1rIGZsYWdzIG9uIHRoZSBjb21tYW5kIGxpbmUuCgogICAgLUsKICAgIC0tbm8tZGVmYXVsdC1rZXl3b3JkcwogICAgICAgIERpc2FibGUgdGhlIGRlZmF1bHQgc2V0IG9mIGtleXdvcmRzIChzZWUgYWJvdmUpLiAgQW55IGtleXdvcmRzCiAgICAgICAgZXhwbGljaXRseSBhZGRlZCB3aXRoIHRoZSAtay8tLWtleXdvcmQgb3B0aW9uIGFyZSBzdGlsbCByZWNvZ25pemVkLgoKICAgIC0tbm8tbG9jYXRpb24KICAgICAgICBEbyBub3Qgd3JpdGUgZmlsZW5hbWUvbGluZW5vIGxvY2F0aW9uIGNvbW1lbnRzLgoKICAgIC1uCiAgICAtLWFkZC1sb2NhdGlvbgogICAgICAgIFdyaXRlIGZpbGVuYW1lL2xpbmVubyBsb2NhdGlvbiBjb21tZW50cyBpbmRpY2F0aW5nIHdoZXJlIGVhY2gKICAgICAgICBleHRyYWN0ZWQgc3RyaW5nIGlzIGZvdW5kIGluIHRoZSBzb3VyY2UuICBUaGVzZSBsaW5lcyBhcHBlYXIgYmVmb3JlCiAgICAgICAgZWFjaCBtc2dpZC4gIFRoZSBzdHlsZSBvZiBjb21tZW50cyBpcyBjb250cm9sbGVkIGJ5IHRoZSAtUy8tLXN0eWxlCiAgICAgICAgb3B0aW9uLiAgVGhpcyBpcyB0aGUgZGVmYXVsdC4KCiAgICAtbyBmaWxlbmFtZQogICAgLS1vdXRwdXQ9ZmlsZW5hbWUKICAgICAgICBSZW5hbWUgdGhlIGRlZmF1bHQgb3V0cHV0IGZpbGUgZnJvbSBtZXNzYWdlcy5wb3QgdG8gZmlsZW5hbWUuICBJZgogICAgICAgIGZpbGVuYW1lIGlzIGAtJyB0aGVuIHRoZSBvdXRwdXQgaXMgc2VudCB0byBzdGFuZGFyZCBvdXQuCgogICAgLXAgZGlyCiAgICAtLW91dHB1dC1kaXI9ZGlyCiAgICAgICAgT3V0cHV0IGZpbGVzIHdpbGwgYmUgcGxhY2VkIGluIGRpcmVjdG9yeSBkaXIuCgogICAgLVMgc3R5bGVuYW1lCiAgICAtLXN0eWxlIHN0eWxlbmFtZQogICAgICAgIFNwZWNpZnkgd2hpY2ggc3R5bGUgdG8gdXNlIGZvciBsb2NhdGlvbiBjb21tZW50cy4gIFR3byBzdHlsZXMgYXJlCiAgICAgICAgc3VwcG9ydGVkOgoKICAgICAgICBTb2xhcmlzICAjIEZpbGU6IGZpbGVuYW1lLCBsaW5lOiBsaW5lLW51bWJlcgogICAgICAgIEdOVSAgICAgICM6IGZpbGVuYW1lOmxpbmUKCiAgICAgICAgVGhlIHN0eWxlIG5hbWUgaXMgY2FzZSBpbnNlbnNpdGl2ZS4gIEdOVSBzdHlsZSBpcyB0aGUgZGVmYXVsdC4KCiAgICAtdgogICAgLS12ZXJib3NlCiAgICAgICAgUHJpbnQgdGhlIG5hbWVzIG9mIHRoZSBmaWxlcyBiZWluZyBwcm9jZXNzZWQuCgogICAgLVYKICAgIC0tdmVyc2lvbgogICAgICAgIFByaW50IHRoZSB2ZXJzaW9uIG9mIHB5Z2V0dGV4dCBhbmQgZXhpdC4KCiAgICAtdyBjb2x1bW5zCiAgICAtLXdpZHRoPWNvbHVtbnMKICAgICAgICBTZXQgd2lkdGggb2Ygb3V0cHV0IHRvIGNvbHVtbnMuCgogICAgLXggZmlsZW5hbWUKICAgIC0tZXhjbHVkZS1maWxlPWZpbGVuYW1lCiAgICAgICAgU3BlY2lmeSBhIGZpbGUgdGhhdCBjb250YWlucyBhIGxpc3Qgb2Ygc3RyaW5ncyB0aGF0IGFyZSBub3QgYmUKICAgICAgICBleHRyYWN0ZWQgZnJvbSB0aGUgaW5wdXQgZmlsZXMuICBFYWNoIHN0cmluZyB0byBiZSBleGNsdWRlZCBtdXN0CiAgICAgICAgYXBwZWFyIG9uIGEgbGluZSBieSBpdHNlbGYgaW4gdGhlIGZpbGUuCgogICAgLVggZmlsZW5hbWUKICAgIC0tbm8tZG9jc3RyaW5ncz1maWxlbmFtZQogICAgICAgIFNwZWNpZnkgYSBmaWxlIHRoYXQgY29udGFpbnMgYSBsaXN0IG9mIGZpbGVzIChvbmUgcGVyIGxpbmUpIHRoYXQKICAgICAgICBzaG91bGQgbm90IGhhdmUgdGhlaXIgZG9jc3RyaW5ncyBleHRyYWN0ZWQuICBUaGlzIGlzIG9ubHkgdXNlZnVsIGluCiAgICAgICAgY29uanVuY3Rpb24gd2l0aCB0aGUgLUQgb3B0aW9uIGFib3ZlLgoKSWYgYGlucHV0ZmlsZScgaXMgLSwgc3RhbmRhcmQgaW5wdXQgaXMgcmVhZC4KIiIiKQoKaW1wb3J0IG9zCmltcG9ydCBpbXAKaW1wb3J0IHN5cwppbXBvcnQgZ2xvYgppbXBvcnQgdGltZQppbXBvcnQgZ2V0b3B0CmltcG9ydCB0b2tlbgppbXBvcnQgdG9rZW5pemUKaW1wb3J0IG9wZXJhdG9yCgpfX3ZlcnNpb25fXyA9ICcxLjUnCgpkZWZhdWx0X2tleXdvcmRzID0gWydfJ10KREVGQVVMVEtFWVdPUkRTID0gJywgJy5qb2luKGRlZmF1bHRfa2V5d29yZHMpCgpFTVBUWVNUUklORyA9ICcnCgoKDAojIFRoZSBub3JtYWwgcG90LWZpbGUgaGVhZGVyLiBtc2dtZXJnZSBhbmQgRW1hY3MncyBwby1tb2RlIHdvcmsgYmV0dGVyIGlmIGl0J3MKIyB0aGVyZS4KcG90X2hlYWRlciA9IF8oJycnXAojIFNPTUUgREVTQ1JJUFRJVkUgVElUTEUuCiMgQ29weXJpZ2h0IChDKSBZRUFSIE9SR0FOSVpBVElPTgojIEZJUlNUIEFVVEhPUiA8RU1BSUxAQUREUkVTUz4sIFlFQVIuCiMKbXNnaWQgIiIKbXNnc3RyICIiCiJQcm9qZWN0LUlkLVZlcnNpb246IFBBQ0tBR0UgVkVSU0lPTlxcbiIKIlBPVC1DcmVhdGlvbi1EYXRlOiAlKHRpbWUpc1xcbiIKIlBPLVJldmlzaW9uLURhdGU6IFlFQVItTU8tREEgSE86TUkrWk9ORVxcbiIKIkxhc3QtVHJhbnNsYXRvcjogRlVMTCBOQU1FIDxFTUFJTEBBRERSRVNTPlxcbiIKIkxhbmd1YWdlLVRlYW06IExBTkdVQUdFIDxMTEBsaS5vcmc+XFxuIgoiTUlNRS1WZXJzaW9uOiAxLjBcXG4iCiJDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9Q0hBUlNFVFxcbiIKIkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IEVOQ09ESU5HXFxuIgoiR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgJSh2ZXJzaW9uKXNcXG4iCgonJycpCgoMCmRlZiB1c2FnZShjb2RlLCBtc2c9JycpOgogICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgX19kb2NfXyAlIGdsb2JhbHMoKQogICAgaWYgbXNnOgogICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIG1zZwogICAgc3lzLmV4aXQoY29kZSkKCgoMCmVzY2FwZXMgPSBbXQoKZGVmIG1ha2VfZXNjYXBlcyhwYXNzX2lzbzg4NTkpOgogICAgZ2xvYmFsIGVzY2FwZXMKICAgIGVzY2FwZXMgPSBbY2hyKGkpIGZvciBpIGluIHJhbmdlKDI1NildCiAgICBpZiBwYXNzX2lzbzg4NTk6CiAgICAgICAgIyBBbGxvdyBpc28tODg1OSBjaGFyYWN0ZXJzIHRvIHBhc3MgdGhyb3VnaCBzbyB0aGF0IGUuZy4gJ21zZ2lkCiAgICAgICAgIyAiSPZoZSInIHdvdWxkIHJlc3VsdCBub3QgcmVzdWx0IGluICdtc2dpZCAiSFwzNjZoZSInLiAgT3RoZXJ3aXNlIHdlCiAgICAgICAgIyBlc2NhcGUgYW55IGNoYXJhY3RlciBvdXRzaWRlIHRoZSAzMi4uMTI2IHJhbmdlLgogICAgICAgIG1vZCA9IDEyOAogICAgZWxzZToKICAgICAgICBtb2QgPSAyNTYKICAgIGZvciBpIGluIHJhbmdlKG1vZCk6CiAgICAgICAgaWYgbm90KDMyIDw9IGkgPD0gMTI2KToKICAgICAgICAgICAgZXNjYXBlc1tpXSA9ICJcXCUwM28iICUgaQogICAgZXNjYXBlc1tvcmQoJ1xcJyldID0gJ1xcXFwnCiAgICBlc2NhcGVzW29yZCgnXHQnKV0gPSAnXFx0JwogICAgZXNjYXBlc1tvcmQoJ1xyJyldID0gJ1xccicKICAgIGVzY2FwZXNbb3JkKCdcbicpXSA9ICdcXG4nCiAgICBlc2NhcGVzW29yZCgnXCInKV0gPSAnXFwiJwoKCmRlZiBlc2NhcGUocyk6CiAgICBnbG9iYWwgZXNjYXBlcwogICAgcyA9IGxpc3QocykKICAgIGZvciBpIGluIHJhbmdlKGxlbihzKSk6CiAgICAgICAgc1tpXSA9IGVzY2FwZXNbb3JkKHNbaV0pXQogICAgcmV0dXJuIEVNUFRZU1RSSU5HLmpvaW4ocykKCgpkZWYgc2FmZV9ldmFsKHMpOgogICAgIyB1bndyYXAgcXVvdGVzLCBzYWZlbHkKICAgIHJldHVybiBldmFsKHMsIHsnX19idWlsdGluc19fJzp7fX0sIHt9KQoKCmRlZiBub3JtYWxpemUocyk6CiAgICAjIFRoaXMgY29udmVydHMgdGhlIHZhcmlvdXMgUHl0aG9uIHN0cmluZyB0eXBlcyBpbnRvIGEgZm9ybWF0IHRoYXQgaXMKICAgICMgYXBwcm9wcmlhdGUgZm9yIC5wbyBmaWxlcywgbmFtZWx5IG11Y2ggY2xvc2VyIHRvIEMgc3R5bGUuCiAgICBsaW5lcyA9IHMuc3BsaXQoJ1xuJykKICAgIGlmIGxlbihsaW5lcykgPT0gMToKICAgICAgICBzID0gJyInICsgZXNjYXBlKHMpICsgJyInCiAgICBlbHNlOgogICAgICAgIGlmIG5vdCBsaW5lc1stMV06CiAgICAgICAgICAgIGRlbCBsaW5lc1stMV0KICAgICAgICAgICAgbGluZXNbLTFdID0gbGluZXNbLTFdICsgJ1xuJwogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihsaW5lcykpOgogICAgICAgICAgICBsaW5lc1tpXSA9IGVzY2FwZShsaW5lc1tpXSkKICAgICAgICBsaW5ldGVybSA9ICdcXG4iXG4iJwogICAgICAgIHMgPSAnIiJcbiInICsgbGluZXRlcm0uam9pbihsaW5lcykgKyAnIicKICAgIHJldHVybiBzCgoMCmRlZiBjb250YWluc0FueShzdHIsIHNldCk6CiAgICAiIiJDaGVjayB3aGV0aGVyICdzdHInIGNvbnRhaW5zIEFOWSBvZiB0aGUgY2hhcnMgaW4gJ3NldCciIiIKICAgIHJldHVybiAxIGluIFtjIGluIHN0ciBmb3IgYyBpbiBzZXRdCgoKZGVmIF92aXNpdF9weWZpbGVzKGxpc3QsIGRpcm5hbWUsIG5hbWVzKToKICAgICIiIkhlbHBlciBmb3IgZ2V0RmlsZXNGb3JOYW1lKCkuIiIiCiAgICAjIGdldCBleHRlbnNpb24gZm9yIHB5dGhvbiBzb3VyY2UgZmlsZXMKICAgIGlmIG5vdCBnbG9iYWxzKCkuaGFzX2tleSgnX3B5X2V4dCcpOgogICAgICAgIGdsb2JhbCBfcHlfZXh0CiAgICAgICAgX3B5X2V4dCA9IFt0cmlwbGVbMF0gZm9yIHRyaXBsZSBpbiBpbXAuZ2V0X3N1ZmZpeGVzKCkKICAgICAgICAgICAgICAgICAgIGlmIHRyaXBsZVsyXSA9PSBpbXAuUFlfU09VUkNFXVswXQoKICAgICMgZG9uJ3QgcmVjdXJzZSBpbnRvIENWUyBkaXJlY3RvcmllcwogICAgaWYgJ0NWUycgaW4gbmFtZXM6CiAgICAgICAgbmFtZXMucmVtb3ZlKCdDVlMnKQoKICAgICMgYWRkIGFsbCAqLnB5IGZpbGVzIHRvIGxpc3QKICAgIGxpc3QuZXh0ZW5kKAogICAgICAgIFtvcy5wYXRoLmpvaW4oZGlybmFtZSwgZmlsZSkgZm9yIGZpbGUgaW4gbmFtZXMKICAgICAgICAgaWYgb3MucGF0aC5zcGxpdGV4dChmaWxlKVsxXSA9PSBfcHlfZXh0XQogICAgICAgICkKCgpkZWYgX2dldF9tb2Rwa2dfcGF0aChkb3R0ZWRfbmFtZSwgcGF0aGxpc3Q9Tm9uZSk6CiAgICAiIiJHZXQgdGhlIGZpbGVzeXN0ZW0gcGF0aCBmb3IgYSBtb2R1bGUgb3IgYSBwYWNrYWdlLgoKICAgIFJldHVybiB0aGUgZmlsZSBzeXN0ZW0gcGF0aCB0byBhIGZpbGUgZm9yIGEgbW9kdWxlLCBhbmQgdG8gYSBkaXJlY3RvcnkgZm9yCiAgICBhIHBhY2thZ2UuIFJldHVybiBOb25lIGlmIHRoZSBuYW1lIGlzIG5vdCBmb3VuZCwgb3IgaXMgYSBidWlsdGluIG9yCiAgICBleHRlbnNpb24gbW9kdWxlLgogICAgIiIiCiAgICAjIHNwbGl0IG9mZiB0b3AtbW9zdCBuYW1lCiAgICBwYXJ0cyA9IGRvdHRlZF9uYW1lLnNwbGl0KCcuJywgMSkKCiAgICBpZiBsZW4ocGFydHMpID4gMToKICAgICAgICAjIHdlIGhhdmUgYSBkb3R0ZWQgcGF0aCwgaW1wb3J0IHRvcC1sZXZlbCBwYWNrYWdlCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmaWxlLCBwYXRobmFtZSwgZGVzY3JpcHRpb24gPSBpbXAuZmluZF9tb2R1bGUocGFydHNbMF0sIHBhdGhsaXN0KQogICAgICAgICAgICBpZiBmaWxlOiBmaWxlLmNsb3NlKCkKICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgICMgY2hlY2sgaWYgaXQncyBpbmRlZWQgYSBwYWNrYWdlCiAgICAgICAgaWYgZGVzY3JpcHRpb25bMl0gPT0gaW1wLlBLR19ESVJFQ1RPUlk6CiAgICAgICAgICAgICMgcmVjdXJzaXZlbHkgaGFuZGxlIHRoZSByZW1haW5pbmcgbmFtZSBwYXJ0cwogICAgICAgICAgICBwYXRobmFtZSA9IF9nZXRfbW9kcGtnX3BhdGgocGFydHNbMV0sIFtwYXRobmFtZV0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcGF0aG5hbWUgPSBOb25lCiAgICBlbHNlOgogICAgICAgICMgcGxhaW4gbmFtZQogICAgICAgIHRyeToKICAgICAgICAgICAgZmlsZSwgcGF0aG5hbWUsIGRlc2NyaXB0aW9uID0gaW1wLmZpbmRfbW9kdWxlKAogICAgICAgICAgICAgICAgZG90dGVkX25hbWUsIHBhdGhsaXN0KQogICAgICAgICAgICBpZiBmaWxlOgogICAgICAgICAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgICAgIGlmIGRlc2NyaXB0aW9uWzJdIG5vdCBpbiBbaW1wLlBZX1NPVVJDRSwgaW1wLlBLR19ESVJFQ1RPUlldOgogICAgICAgICAgICAgICAgcGF0aG5hbWUgPSBOb25lCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICBwYXRobmFtZSA9IE5vbmUKCiAgICByZXR1cm4gcGF0aG5hbWUKCgpkZWYgZ2V0RmlsZXNGb3JOYW1lKG5hbWUpOgogICAgIiIiR2V0IGEgbGlzdCBvZiBtb2R1bGUgZmlsZXMgZm9yIGEgZmlsZW5hbWUsIGEgbW9kdWxlIG9yIHBhY2thZ2UgbmFtZSwKICAgIG9yIGEgZGlyZWN0b3J5LgogICAgIiIiCiAgICBpZiBub3Qgb3MucGF0aC5leGlzdHMobmFtZSk6CiAgICAgICAgIyBjaGVjayBmb3IgZ2xvYiBjaGFycwogICAgICAgIGlmIGNvbnRhaW5zQW55KG5hbWUsICIqP1tdIik6CiAgICAgICAgICAgIGZpbGVzID0gZ2xvYi5nbG9iKG5hbWUpCiAgICAgICAgICAgIGxpc3QgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgICAgIGxpc3QuZXh0ZW5kKGdldEZpbGVzRm9yTmFtZShmaWxlKSkKICAgICAgICAgICAgcmV0dXJuIGxpc3QKCiAgICAgICAgIyB0cnkgdG8gZmluZCBtb2R1bGUgb3IgcGFja2FnZQogICAgICAgIG5hbWUgPSBfZ2V0X21vZHBrZ19wYXRoKG5hbWUpCiAgICAgICAgaWYgbm90IG5hbWU6CiAgICAgICAgICAgIHJldHVybiBbXQoKICAgIGlmIG9zLnBhdGguaXNkaXIobmFtZSk6CiAgICAgICAgIyBmaW5kIGFsbCBweXRob24gZmlsZXMgaW4gZGlyZWN0b3J5CiAgICAgICAgbGlzdCA9IFtdCiAgICAgICAgb3MucGF0aC53YWxrKG5hbWUsIF92aXNpdF9weWZpbGVzLCBsaXN0KQogICAgICAgIHJldHVybiBsaXN0CiAgICBlbGlmIG9zLnBhdGguZXhpc3RzKG5hbWUpOgogICAgICAgICMgYSBzaW5nbGUgZmlsZQogICAgICAgIHJldHVybiBbbmFtZV0KCiAgICByZXR1cm4gW10KCgwKY2xhc3MgVG9rZW5FYXRlcjoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvcHRpb25zKToKICAgICAgICBzZWxmLl9fb3B0aW9ucyA9IG9wdGlvbnMKICAgICAgICBzZWxmLl9fbWVzc2FnZXMgPSB7fQogICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCiAgICAgICAgc2VsZi5fX2RhdGEgPSBbXQogICAgICAgIHNlbGYuX19saW5lbm8gPSAtMQogICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDEKICAgICAgICBzZWxmLl9fY3VyZmlsZSA9IE5vbmUKCiAgICBkZWYgX19jYWxsX18oc2VsZiwgdHR5cGUsIHRzdHJpbmcsIHN0dXAsIGV0dXAsIGxpbmUpOgogICAgICAgICMgZGlzcGF0Y2gKIyMgICAgICAgIGltcG9ydCB0b2tlbgojIyAgICAgICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgJ3R0eXBlOicsIHRva2VuLnRva19uYW1lW3R0eXBlXSwgXAojIyAgICAgICAgICAgICAgJ3RzdHJpbmc6JywgdHN0cmluZwogICAgICAgIHNlbGYuX19zdGF0ZSh0dHlwZSwgdHN0cmluZywgc3R1cFswXSkKCiAgICBkZWYgX193YWl0aW5nKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOgogICAgICAgIG9wdHMgPSBzZWxmLl9fb3B0aW9ucwogICAgICAgICMgRG8gZG9jc3RyaW5nIGV4dHJhY3Rpb25zLCBpZiBlbmFibGVkCiAgICAgICAgaWYgb3B0cy5kb2NzdHJpbmdzIGFuZCBub3Qgb3B0cy5ub2RvY3N0cmluZ3MuZ2V0KHNlbGYuX19jdXJmaWxlKToKICAgICAgICAgICAgIyBtb2R1bGUgZG9jc3RyaW5nPwogICAgICAgICAgICBpZiBzZWxmLl9fZnJlc2htb2R1bGU6CiAgICAgICAgICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5TVFJJTkc6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2FkZGVudHJ5KHNhZmVfZXZhbCh0c3RyaW5nKSwgbGluZW5vLCBpc2RvY3N0cmluZz0xKQogICAgICAgICAgICAgICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDAKICAgICAgICAgICAgICAgIGVsaWYgdHR5cGUgbm90IGluICh0b2tlbml6ZS5DT01NRU5ULCB0b2tlbml6ZS5OTCk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMAogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICMgY2xhc3MgZG9jc3RyaW5nPwogICAgICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5OQU1FIGFuZCB0c3RyaW5nIGluICgnY2xhc3MnLCAnZGVmJyk6CiAgICAgICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fc3VpdGVzZWVuCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5OQU1FIGFuZCB0c3RyaW5nIGluIG9wdHMua2V5d29yZHM6CiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX19rZXl3b3Jkc2VlbgoKICAgIGRlZiBfX3N1aXRlc2VlbihzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICAjIGlnbm9yZSBhbnl0aGluZyB1bnRpbCB3ZSBzZWUgdGhlIGNvbG9uCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuT1AgYW5kIHRzdHJpbmcgPT0gJzonOgogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fc3VpdGVkb2NzdHJpbmcKCiAgICBkZWYgX19zdWl0ZWRvY3N0cmluZyhzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICAjIGlnbm9yZSBhbnkgaW50ZXJ2ZW5pbmcgbm9pc2UKICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5TVFJJTkc6CiAgICAgICAgICAgIHNlbGYuX19hZGRlbnRyeShzYWZlX2V2YWwodHN0cmluZyksIGxpbmVubywgaXNkb2NzdHJpbmc9MSkKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKICAgICAgICBlbGlmIHR0eXBlIG5vdCBpbiAodG9rZW5pemUuTkVXTElORSwgdG9rZW5pemUuSU5ERU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbml6ZS5DT01NRU5UKToKICAgICAgICAgICAgIyB0aGVyZSB3YXMgbm8gY2xhc3MgZG9jc3RyaW5nCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCgogICAgZGVmIF9fa2V5d29yZHNlZW4oc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6CiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuT1AgYW5kIHRzdHJpbmcgPT0gJygnOgogICAgICAgICAgICBzZWxmLl9fZGF0YSA9IFtdCiAgICAgICAgICAgIHNlbGYuX19saW5lbm8gPSBsaW5lbm8KICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX29wZW5zZWVuCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKCiAgICBkZWYgX19vcGVuc2VlbihzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5PUCBhbmQgdHN0cmluZyA9PSAnKSc6CiAgICAgICAgICAgICMgV2UndmUgc2VlbiB0aGUgbGFzdCBvZiB0aGUgdHJhbnNsYXRhYmxlIHN0cmluZ3MuICBSZWNvcmQgdGhlCiAgICAgICAgICAgICMgbGluZSBudW1iZXIgb2YgdGhlIGZpcnN0IGxpbmUgb2YgdGhlIHN0cmluZ3MgYW5kIHVwZGF0ZSB0aGUgbGlzdAogICAgICAgICAgICAjIG9mIG1lc3NhZ2VzIHNlZW4uICBSZXNldCBzdGF0ZSBmb3IgdGhlIG5leHQgYmF0Y2guICBJZiB0aGVyZQogICAgICAgICAgICAjIHdlcmUgbm8gc3RyaW5ncyBpbnNpZGUgXygpLCB0aGVuIGp1c3QgaWdub3JlIHRoaXMgZW50cnkuCiAgICAgICAgICAgIGlmIHNlbGYuX19kYXRhOgogICAgICAgICAgICAgICAgc2VsZi5fX2FkZGVudHJ5KEVNUFRZU1RSSU5HLmpvaW4oc2VsZi5fX2RhdGEpKQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwogICAgICAgIGVsaWYgdHR5cGUgPT0gdG9rZW5pemUuU1RSSU5HOgogICAgICAgICAgICBzZWxmLl9fZGF0YS5hcHBlbmQoc2FmZV9ldmFsKHRzdHJpbmcpKQogICAgICAgIGVsaWYgdHR5cGUgbm90IGluIFt0b2tlbml6ZS5DT01NRU5ULCB0b2tlbi5JTkRFTlQsIHRva2VuLkRFREVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW4uTkVXTElORSwgdG9rZW5pemUuTkxdOgogICAgICAgICAgICAjIHdhcm4gaWYgd2Ugc2VlIGFueXRoaW5nIGVsc2UgdGhhbiBTVFJJTkcgb3Igd2hpdGVzcGFjZQogICAgICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCBfKAogICAgICAgICAgICAgICAgJyoqKiAlKGZpbGUpczolKGxpbmVubylzOiBTZWVuIHVuZXhwZWN0ZWQgdG9rZW4gIiUodG9rZW4pcyInCiAgICAgICAgICAgICAgICApICUgewogICAgICAgICAgICAgICAgJ3Rva2VuJzogdHN0cmluZywKICAgICAgICAgICAgICAgICdmaWxlJzogc2VsZi5fX2N1cmZpbGUsCiAgICAgICAgICAgICAgICAnbGluZW5vJzogc2VsZi5fX2xpbmVubwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwoKICAgIGRlZiBfX2FkZGVudHJ5KHNlbGYsIG1zZywgbGluZW5vPU5vbmUsIGlzZG9jc3RyaW5nPTApOgogICAgICAgIGlmIGxpbmVubyBpcyBOb25lOgogICAgICAgICAgICBsaW5lbm8gPSBzZWxmLl9fbGluZW5vCiAgICAgICAgaWYgbm90IG1zZyBpbiBzZWxmLl9fb3B0aW9ucy50b2V4Y2x1ZGU6CiAgICAgICAgICAgIGVudHJ5ID0gKHNlbGYuX19jdXJmaWxlLCBsaW5lbm8pCiAgICAgICAgICAgIHNlbGYuX19tZXNzYWdlcy5zZXRkZWZhdWx0KG1zZywge30pW2VudHJ5XSA9IGlzZG9jc3RyaW5nCgogICAgZGVmIHNldF9maWxlbmFtZShzZWxmLCBmaWxlbmFtZSk6CiAgICAgICAgc2VsZi5fX2N1cmZpbGUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDEKCiAgICBkZWYgd3JpdGUoc2VsZiwgZnApOgogICAgICAgIG9wdGlvbnMgPSBzZWxmLl9fb3B0aW9ucwogICAgICAgIHRpbWVzdGFtcCA9IHRpbWUuc3RyZnRpbWUoJyVZLSVtLSVkICVIOiVNKyVaJykKICAgICAgICAjIFRoZSB0aW1lIHN0YW1wIGluIHRoZSBoZWFkZXIgZG9lc24ndCBoYXZlIHRoZSBzYW1lIGZvcm1hdCBhcyB0aGF0CiAgICAgICAgIyBnZW5lcmF0ZWQgYnkgeGdldHRleHQuLi4KICAgICAgICBwcmludCA+PiBmcCwgcG90X2hlYWRlciAlIHsndGltZSc6IHRpbWVzdGFtcCwgJ3ZlcnNpb24nOiBfX3ZlcnNpb25fX30KICAgICAgICAjIFNvcnQgdGhlIGVudHJpZXMuICBGaXJzdCBzb3J0IGVhY2ggcGFydGljdWxhciBlbnRyeSdzIGtleXMsIHRoZW4KICAgICAgICAjIHNvcnQgYWxsIHRoZSBlbnRyaWVzIGJ5IHRoZWlyIGZpcnN0IGl0ZW0uCiAgICAgICAgcmV2ZXJzZSA9IHt9CiAgICAgICAgZm9yIGssIHYgaW4gc2VsZi5fX21lc3NhZ2VzLml0ZW1zKCk6CiAgICAgICAgICAgIGtleXMgPSB2LmtleXMoKQogICAgICAgICAgICBrZXlzLnNvcnQoKQogICAgICAgICAgICByZXZlcnNlLnNldGRlZmF1bHQodHVwbGUoa2V5cyksIFtdKS5hcHBlbmQoKGssIHYpKQogICAgICAgIHJrZXlzID0gcmV2ZXJzZS5rZXlzKCkKICAgICAgICBya2V5cy5zb3J0KCkKICAgICAgICBmb3IgcmtleSBpbiBya2V5czoKICAgICAgICAgICAgcmVudHJpZXMgPSByZXZlcnNlW3JrZXldCiAgICAgICAgICAgIHJlbnRyaWVzLnNvcnQoKQogICAgICAgICAgICBmb3IgaywgdiBpbiByZW50cmllczoKICAgICAgICAgICAgICAgIGlzZG9jc3RyaW5nID0gMAogICAgICAgICAgICAgICAgIyBJZiB0aGUgZW50cnkgd2FzIGdsZWFuZWQgb3V0IG9mIGEgZG9jc3RyaW5nLCB0aGVuIGFkZCBhCiAgICAgICAgICAgICAgICAjIGNvbW1lbnQgc3RhdGluZyBzby4gIFRoaXMgaXMgdG8gYWlkIHRyYW5zbGF0b3JzIHdobyBtYXkgd2lzaAogICAgICAgICAgICAgICAgIyB0byBza2lwIHRyYW5zbGF0aW5nIHNvbWUgdW5pbXBvcnRhbnQgZG9jc3RyaW5ncy4KICAgICAgICAgICAgICAgIGlmIHJlZHVjZShvcGVyYXRvci5fX2FkZF9fLCB2LnZhbHVlcygpKToKICAgICAgICAgICAgICAgICAgICBpc2RvY3N0cmluZyA9IDEKICAgICAgICAgICAgICAgICMgayBpcyB0aGUgbWVzc2FnZSBzdHJpbmcsIHYgaXMgYSBkaWN0aW9uYXJ5LXNldCBvZiAoZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAjIGxpbmVubykgdHVwbGVzLiAgV2Ugd2FudCB0byBzb3J0IHRoZSBlbnRyaWVzIGluIHYgZmlyc3QgYnkKICAgICAgICAgICAgICAgICMgZmlsZSBuYW1lIGFuZCB0aGVuIGJ5IGxpbmUgbnVtYmVyLgogICAgICAgICAgICAgICAgdiA9IHYua2V5cygpCiAgICAgICAgICAgICAgICB2LnNvcnQoKQogICAgICAgICAgICAgICAgaWYgbm90IG9wdGlvbnMud3JpdGVsb2NhdGlvbnM6CiAgICAgICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgICAgIyBsb2NhdGlvbiBjb21tZW50cyBhcmUgZGlmZmVyZW50IGIvdyBTb2xhcmlzIGFuZCBHTlU6CiAgICAgICAgICAgICAgICBlbGlmIG9wdGlvbnMubG9jYXRpb25zdHlsZSA9PSBvcHRpb25zLlNPTEFSSVM6CiAgICAgICAgICAgICAgICAgICAgZm9yIGZpbGVuYW1lLCBsaW5lbm8gaW4gdjoKICAgICAgICAgICAgICAgICAgICAgICAgZCA9IHsnZmlsZW5hbWUnOiBmaWxlbmFtZSwgJ2xpbmVubyc6IGxpbmVub30KICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgPj5mcCwgXygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICcjIEZpbGU6ICUoZmlsZW5hbWUpcywgbGluZTogJShsaW5lbm8pZCcpICUgZAogICAgICAgICAgICAgICAgZWxpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgPT0gb3B0aW9ucy5HTlU6CiAgICAgICAgICAgICAgICAgICAgIyBmaXQgYXMgbWFueSBsb2NhdGlvbnMgb24gb25lIGxpbmUsIGFzIGxvbmcgYXMgdGhlCiAgICAgICAgICAgICAgICAgICAgIyByZXN1bHRpbmcgbGluZSBsZW5ndGggZG9lc24ndCBleGNlZWRzICdvcHRpb25zLndpZHRoJwogICAgICAgICAgICAgICAgICAgIGxvY2xpbmUgPSAnIzonCiAgICAgICAgICAgICAgICAgICAgZm9yIGZpbGVuYW1lLCBsaW5lbm8gaW4gdjoKICAgICAgICAgICAgICAgICAgICAgICAgZCA9IHsnZmlsZW5hbWUnOiBmaWxlbmFtZSwgJ2xpbmVubyc6IGxpbmVub30KICAgICAgICAgICAgICAgICAgICAgICAgcyA9IF8oJyAlKGZpbGVuYW1lKXM6JShsaW5lbm8pZCcpICUgZAogICAgICAgICAgICAgICAgICAgICAgICBpZiBsZW4obG9jbGluZSkgKyBsZW4ocykgPD0gb3B0aW9ucy53aWR0aDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2xpbmUgPSBsb2NsaW5lICsgcwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgPj4gZnAsIGxvY2xpbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2xpbmUgPSAiIzoiICsgcwogICAgICAgICAgICAgICAgICAgIGlmIGxlbihsb2NsaW5lKSA+IDI6CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ID4+IGZwLCBsb2NsaW5lCiAgICAgICAgICAgICAgICBpZiBpc2RvY3N0cmluZzoKICAgICAgICAgICAgICAgICAgICBwcmludCA+PiBmcCwgJyMsIGRvY3N0cmluZycKICAgICAgICAgICAgICAgIHByaW50ID4+IGZwLCAnbXNnaWQnLCBub3JtYWxpemUoaykKICAgICAgICAgICAgICAgIHByaW50ID4+IGZwLCAnbXNnc3RyICIiXG4nCgoKDApkZWYgbWFpbigpOgogICAgZ2xvYmFsIGRlZmF1bHRfa2V5d29yZHMKICAgIHRyeToKICAgICAgICBvcHRzLCBhcmdzID0gZ2V0b3B0LmdldG9wdCgKICAgICAgICAgICAgc3lzLmFyZ3ZbMTpdLAogICAgICAgICAgICAnYWQ6REVoazpLbm86cDpTOlZ2dzp4Olg6JywKICAgICAgICAgICAgWydleHRyYWN0LWFsbCcsICdkZWZhdWx0LWRvbWFpbj0nLCAnZXNjYXBlJywgJ2hlbHAnLAogICAgICAgICAgICAgJ2tleXdvcmQ9JywgJ25vLWRlZmF1bHQta2V5d29yZHMnLAogICAgICAgICAgICAgJ2FkZC1sb2NhdGlvbicsICduby1sb2NhdGlvbicsICdvdXRwdXQ9JywgJ291dHB1dC1kaXI9JywKICAgICAgICAgICAgICdzdHlsZT0nLCAndmVyYm9zZScsICd2ZXJzaW9uJywgJ3dpZHRoPScsICdleGNsdWRlLWZpbGU9JywKICAgICAgICAgICAgICdkb2NzdHJpbmdzJywgJ25vLWRvY3N0cmluZ3MnLAogICAgICAgICAgICAgXSkKICAgIGV4Y2VwdCBnZXRvcHQuZXJyb3IsIG1zZzoKICAgICAgICB1c2FnZSgxLCBtc2cpCgogICAgIyBmb3IgaG9sZGluZyBvcHRpb24gdmFsdWVzCiAgICBjbGFzcyBPcHRpb25zOgogICAgICAgICMgY29uc3RhbnRzCiAgICAgICAgR05VID0gMQogICAgICAgIFNPTEFSSVMgPSAyCiAgICAgICAgIyBkZWZhdWx0cwogICAgICAgIGV4dHJhY3RhbGwgPSAwICMgRklYTUU6IGN1cnJlbnRseSB0aGlzIG9wdGlvbiBoYXMgbm8gZWZmZWN0IGF0IGFsbC4KICAgICAgICBlc2NhcGUgPSAwCiAgICAgICAga2V5d29yZHMgPSBbXQogICAgICAgIG91dHBhdGggPSAnJwogICAgICAgIG91dGZpbGUgPSAnbWVzc2FnZXMucG90JwogICAgICAgIHdyaXRlbG9jYXRpb25zID0gMQogICAgICAgIGxvY2F0aW9uc3R5bGUgPSBHTlUKICAgICAgICB2ZXJib3NlID0gMAogICAgICAgIHdpZHRoID0gNzgKICAgICAgICBleGNsdWRlZmlsZW5hbWUgPSAnJwogICAgICAgIGRvY3N0cmluZ3MgPSAwCiAgICAgICAgbm9kb2NzdHJpbmdzID0ge30KCiAgICBvcHRpb25zID0gT3B0aW9ucygpCiAgICBsb2NhdGlvbnMgPSB7J2dudScgOiBvcHRpb25zLkdOVSwKICAgICAgICAgICAgICAgICAnc29sYXJpcycgOiBvcHRpb25zLlNPTEFSSVMsCiAgICAgICAgICAgICAgICAgfQoKICAgICMgcGFyc2Ugb3B0aW9ucwogICAgZm9yIG9wdCwgYXJnIGluIG9wdHM6CiAgICAgICAgaWYgb3B0IGluICgnLWgnLCAnLS1oZWxwJyk6CiAgICAgICAgICAgIHVzYWdlKDApCiAgICAgICAgZWxpZiBvcHQgaW4gKCctYScsICctLWV4dHJhY3QtYWxsJyk6CiAgICAgICAgICAgIG9wdGlvbnMuZXh0cmFjdGFsbCA9IDEKICAgICAgICBlbGlmIG9wdCBpbiAoJy1kJywgJy0tZGVmYXVsdC1kb21haW4nKToKICAgICAgICAgICAgb3B0aW9ucy5vdXRmaWxlID0gYXJnICsgJy5wb3QnCiAgICAgICAgZWxpZiBvcHQgaW4gKCctRScsICctLWVzY2FwZScpOgogICAgICAgICAgICBvcHRpb25zLmVzY2FwZSA9IDEKICAgICAgICBlbGlmIG9wdCBpbiAoJy1EJywgJy0tZG9jc3RyaW5ncycpOgogICAgICAgICAgICBvcHRpb25zLmRvY3N0cmluZ3MgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctaycsICctLWtleXdvcmQnKToKICAgICAgICAgICAgb3B0aW9ucy5rZXl3b3Jkcy5hcHBlbmQoYXJnKQogICAgICAgIGVsaWYgb3B0IGluICgnLUsnLCAnLS1uby1kZWZhdWx0LWtleXdvcmRzJyk6CiAgICAgICAgICAgIGRlZmF1bHRfa2V5d29yZHMgPSBbXQogICAgICAgIGVsaWYgb3B0IGluICgnLW4nLCAnLS1hZGQtbG9jYXRpb24nKToKICAgICAgICAgICAgb3B0aW9ucy53cml0ZWxvY2F0aW9ucyA9IDEKICAgICAgICBlbGlmIG9wdCBpbiAoJy0tbm8tbG9jYXRpb24nLCk6CiAgICAgICAgICAgIG9wdGlvbnMud3JpdGVsb2NhdGlvbnMgPSAwCiAgICAgICAgZWxpZiBvcHQgaW4gKCctUycsICctLXN0eWxlJyk6CiAgICAgICAgICAgIG9wdGlvbnMubG9jYXRpb25zdHlsZSA9IGxvY2F0aW9ucy5nZXQoYXJnLmxvd2VyKCkpCiAgICAgICAgICAgIGlmIG9wdGlvbnMubG9jYXRpb25zdHlsZSBpcyBOb25lOgogICAgICAgICAgICAgICAgdXNhZ2UoMSwgXygnSW52YWxpZCB2YWx1ZSBmb3IgLS1zdHlsZTogJXMnKSAlIGFyZykKICAgICAgICBlbGlmIG9wdCBpbiAoJy1vJywgJy0tb3V0cHV0Jyk6CiAgICAgICAgICAgIG9wdGlvbnMub3V0ZmlsZSA9IGFyZwogICAgICAgIGVsaWYgb3B0IGluICgnLXAnLCAnLS1vdXRwdXQtZGlyJyk6CiAgICAgICAgICAgIG9wdGlvbnMub3V0cGF0aCA9IGFyZwogICAgICAgIGVsaWYgb3B0IGluICgnLXYnLCAnLS12ZXJib3NlJyk6CiAgICAgICAgICAgIG9wdGlvbnMudmVyYm9zZSA9IDEKICAgICAgICBlbGlmIG9wdCBpbiAoJy1WJywgJy0tdmVyc2lvbicpOgogICAgICAgICAgICBwcmludCBfKCdweWdldHRleHQucHkgKHhnZXR0ZXh0IGZvciBQeXRob24pICVzJykgJSBfX3ZlcnNpb25fXwogICAgICAgICAgICBzeXMuZXhpdCgwKQogICAgICAgIGVsaWYgb3B0IGluICgnLXcnLCAnLS13aWR0aCcpOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBvcHRpb25zLndpZHRoID0gaW50KGFyZykKICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgICAgICAgICB1c2FnZSgxLCBfKCctLXdpZHRoIGFyZ3VtZW50IG11c3QgYmUgYW4gaW50ZWdlcjogJXMnKSAlIGFyZykKICAgICAgICBlbGlmIG9wdCBpbiAoJy14JywgJy0tZXhjbHVkZS1maWxlJyk6CiAgICAgICAgICAgIG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lID0gYXJnCiAgICAgICAgZWxpZiBvcHQgaW4gKCctWCcsICctLW5vLWRvY3N0cmluZ3MnKToKICAgICAgICAgICAgZnAgPSBvcGVuKGFyZykKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgd2hpbGUgMToKICAgICAgICAgICAgICAgICAgICBsaW5lID0gZnAucmVhZGxpbmUoKQogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOgogICAgICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgICAgIG9wdGlvbnMubm9kb2NzdHJpbmdzW2xpbmVbOi0xXV0gPSAxCiAgICAgICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgICAgICBmcC5jbG9zZSgpCgogICAgIyBjYWxjdWxhdGUgZXNjYXBlcwogICAgbWFrZV9lc2NhcGVzKG5vdCBvcHRpb25zLmVzY2FwZSkKCiAgICAjIGNhbGN1bGF0ZSBhbGwga2V5d29yZHMKICAgIG9wdGlvbnMua2V5d29yZHMuZXh0ZW5kKGRlZmF1bHRfa2V5d29yZHMpCgogICAgIyBpbml0aWFsaXplIGxpc3Qgb2Ygc3RyaW5ncyB0byBleGNsdWRlCiAgICBpZiBvcHRpb25zLmV4Y2x1ZGVmaWxlbmFtZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZwID0gb3BlbihvcHRpb25zLmV4Y2x1ZGVmaWxlbmFtZSkKICAgICAgICAgICAgb3B0aW9ucy50b2V4Y2x1ZGUgPSBmcC5yZWFkbGluZXMoKQogICAgICAgICAgICBmcC5jbG9zZSgpCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIF8oCiAgICAgICAgICAgICAgICAiQ2FuJ3QgcmVhZCAtLWV4Y2x1ZGUtZmlsZTogJXMiKSAlIG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lCiAgICAgICAgICAgIHN5cy5leGl0KDEpCiAgICBlbHNlOgogICAgICAgIG9wdGlvbnMudG9leGNsdWRlID0gW10KCiAgICAjIHJlc29sdmUgYXJncyB0byBtb2R1bGUgbGlzdHMKICAgIGV4cGFuZGVkID0gW10KICAgIGZvciBhcmcgaW4gYXJnczoKICAgICAgICBpZiBhcmcgPT0gJy0nOgogICAgICAgICAgICBleHBhbmRlZC5hcHBlbmQoYXJnKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGV4cGFuZGVkLmV4dGVuZChnZXRGaWxlc0Zvck5hbWUoYXJnKSkKICAgIGFyZ3MgPSBleHBhbmRlZAoKICAgICMgc2x1cnAgdGhyb3VnaCBhbGwgdGhlIGZpbGVzCiAgICBlYXRlciA9IFRva2VuRWF0ZXIob3B0aW9ucykKICAgIGZvciBmaWxlbmFtZSBpbiBhcmdzOgogICAgICAgIGlmIGZpbGVuYW1lID09ICctJzoKICAgICAgICAgICAgaWYgb3B0aW9ucy52ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQgXygnUmVhZGluZyBzdGFuZGFyZCBpbnB1dCcpCiAgICAgICAgICAgIGZwID0gc3lzLnN0ZGluCiAgICAgICAgICAgIGNsb3NlcCA9IDAKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiBvcHRpb25zLnZlcmJvc2U6CiAgICAgICAgICAgICAgICBwcmludCBfKCdXb3JraW5nIG9uICVzJykgJSBmaWxlbmFtZQogICAgICAgICAgICBmcCA9IG9wZW4oZmlsZW5hbWUpCiAgICAgICAgICAgIGNsb3NlcCA9IDEKICAgICAgICB0cnk6CiAgICAgICAgICAgIGVhdGVyLnNldF9maWxlbmFtZShmaWxlbmFtZSkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdG9rZW5pemUudG9rZW5pemUoZnAucmVhZGxpbmUsIGVhdGVyKQogICAgICAgICAgICBleGNlcHQgdG9rZW5pemUuVG9rZW5FcnJvciwgZToKICAgICAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsICclczogJXMsIGxpbmUgJWQsIGNvbHVtbiAlZCcgJSAoCiAgICAgICAgICAgICAgICAgICAgZVswXSwgZmlsZW5hbWUsIGVbMV1bMF0sIGVbMV1bMV0pCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgaWYgY2xvc2VwOgogICAgICAgICAgICAgICAgZnAuY2xvc2UoKQoKICAgICMgd3JpdGUgdGhlIG91dHB1dAogICAgaWYgb3B0aW9ucy5vdXRmaWxlID09ICctJzoKICAgICAgICBmcCA9IHN5cy5zdGRvdXQKICAgICAgICBjbG9zZXAgPSAwCiAgICBlbHNlOgogICAgICAgIGlmIG9wdGlvbnMub3V0cGF0aDoKICAgICAgICAgICAgb3B0aW9ucy5vdXRmaWxlID0gb3MucGF0aC5qb2luKG9wdGlvbnMub3V0cGF0aCwgb3B0aW9ucy5vdXRmaWxlKQogICAgICAgIGZwID0gb3BlbihvcHRpb25zLm91dGZpbGUsICd3JykKICAgICAgICBjbG9zZXAgPSAxCiAgICB0cnk6CiAgICAgICAgZWF0ZXIud3JpdGUoZnApCiAgICBmaW5hbGx5OgogICAgICAgIGlmIGNsb3NlcDoKICAgICAgICAgICAgZnAuY2xvc2UoKQoKDAppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbWFpbigpCiAgICAjIHNvbWUgbW9yZSB0ZXN0IHN0cmluZ3MKICAgIF8odSdhIHVuaWNvZGUgc3RyaW5nJykKICAgICMgdGhpcyBvbmUgY3JlYXRlcyBhIHdhcm5pbmcKICAgIF8oJyoqKiBTZWVuIHVuZXhwZWN0ZWQgdG9rZW4gIiUodG9rZW4pcyInKSAlIHsndG9rZW4nOiAndGVzdCd9CiAgICBfKCdtb3JlJyAndGhhbicgJ29uZScgJ3N0cmluZycpCg==