IyEgL3Vzci9iaW4vZW52IHB5dGhvbgojIC0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCiMgT3JpZ2luYWxseSB3cml0dGVuIGJ5IEJhcnJ5IFdhcnNhdyA8YmFycnlAem9wZS5jb20+CiMKIyBNaW5pbWFsbHkgcGF0Y2hlZCB0byBtYWtlIGl0IGV2ZW4gbW9yZSB4Z2V0dGV4dCBjb21wYXRpYmxlCiMgYnkgUGV0ZXIgRnVuayA8cGZAYXJ0Y29tLWdtYmguZGU+CiMKIyAyMDAyLTExLTIyIEr8cmdlbiBIZXJtYW5uIDxqaEB3ZWIuZGU+CiMgQWRkZWQgY2hlY2tzIHRoYXQgXygpIG9ubHkgY29udGFpbnMgc3RyaW5nIGxpdGVyYWxzLCBhbmQKIyBjb21tYW5kIGxpbmUgYXJncyBhcmUgcmVzb2x2ZWQgdG8gbW9kdWxlIGxpc3RzLCBpLmUuIHlvdQojIGNhbiBub3cgcGFzcyBhIGZpbGVuYW1lLCBhIG1vZHVsZSBvciBwYWNrYWdlIG5hbWUsIG9yIGEKIyBkaXJlY3RvcnkgKGluY2x1ZGluZyBnbG9iYmluZyBjaGFycywgaW1wb3J0YW50IGZvciBXaW4zMikuCiMgTWFkZSBkb2NzdHJpbmcgZml0IGluIDgwIGNoYXJzIHdpZGUgZGlzcGxheXMgdXNpbmcgcHlkb2MuCiMKCiMgZm9yIHNlbGZ0ZXN0aW5nCnRyeToKICAgIGltcG9ydCBmaW50bAogICAgXyA9IGZpbnRsLmdldHRleHQKZXhjZXB0IEltcG9ydEVycm9yOgogICAgXyA9IGxhbWJkYSBzOiBzCgpfX2RvY19fID0gXygiIiJweWdldHRleHQgLS0gUHl0aG9uIGVxdWl2YWxlbnQgb2YgeGdldHRleHQoMSkKCk1hbnkgc3lzdGVtcyAoU29sYXJpcywgTGludXgsIEdudSkgcHJvdmlkZSBleHRlbnNpdmUgdG9vbHMgdGhhdCBlYXNlIHRoZQppbnRlcm5hdGlvbmFsaXphdGlvbiBvZiBDIHByb2dyYW1zLiBNb3N0IG9mIHRoZXNlIHRvb2xzIGFyZSBpbmRlcGVuZGVudCBvZgp0aGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgYW5kIGNhbiBiZSB1c2VkIGZyb20gd2l0aGluIFB5dGhvbiBwcm9ncmFtcy4KTWFydGluIHZvbiBMb2V3aXMnIHdvcmtbMV0gaGVscHMgY29uc2lkZXJhYmx5IGluIHRoaXMgcmVnYXJkLgoKVGhlcmUncyBvbmUgcHJvYmxlbSB0aG91Z2g7IHhnZXR0ZXh0IGlzIHRoZSBwcm9ncmFtIHRoYXQgc2NhbnMgc291cmNlIGNvZGUKbG9va2luZyBmb3IgbWVzc2FnZSBzdHJpbmdzLCBidXQgaXQgZ3Jva3Mgb25seSBDIChvciBDKyspLiBQeXRob24KaW50cm9kdWNlcyBhIGZldyB3cmlua2xlcywgc3VjaCBhcyBkdWFsIHF1b3RpbmcgY2hhcmFjdGVycywgdHJpcGxlIHF1b3RlZApzdHJpbmdzLCBhbmQgcmF3IHN0cmluZ3MuIHhnZXR0ZXh0IHVuZGVyc3RhbmRzIG5vbmUgb2YgdGhpcy4KCkVudGVyIHB5Z2V0dGV4dCwgd2hpY2ggdXNlcyBQeXRob24ncyBzdGFuZGFyZCB0b2tlbml6ZSBtb2R1bGUgdG8gc2NhbgpQeXRob24gc291cmNlIGNvZGUsIGdlbmVyYXRpbmcgLnBvdCBmaWxlcyBpZGVudGljYWwgdG8gd2hhdCBHTlUgeGdldHRleHRbMl0KZ2VuZXJhdGVzIGZvciBDIGFuZCBDKysgY29kZS4gRnJvbSB0aGVyZSwgdGhlIHN0YW5kYXJkIEdOVSB0b29scyBjYW4gYmUKdXNlZC4KCkEgd29yZCBhYm91dCBtYXJraW5nIFB5dGhvbiBzdHJpbmdzIGFzIGNhbmRpZGF0ZXMgZm9yIHRyYW5zbGF0aW9uLiBHTlUKeGdldHRleHQgcmVjb2duaXplcyB0aGUgZm9sbG93aW5nIGtleXdvcmRzOiBnZXR0ZXh0LCBkZ2V0dGV4dCwgZGNnZXR0ZXh0LAphbmQgZ2V0dGV4dF9ub29wLiBCdXQgdGhvc2UgY2FuIGJlIGEgbG90IG9mIHRleHQgdG8gaW5jbHVkZSBhbGwgb3ZlciB5b3VyCmNvZGUuIEMgYW5kIEMrKyBoYXZlIGEgdHJpY2s6IHRoZXkgdXNlIHRoZSBDIHByZXByb2Nlc3Nvci4gTW9zdAppbnRlcm5hdGlvbmFsaXplZCBDIHNvdXJjZSBpbmNsdWRlcyBhICNkZWZpbmUgZm9yIGdldHRleHQoKSB0byBfKCkgc28gdGhhdAp3aGF0IGhhcyB0byBiZSB3cml0dGVuIGluIHRoZSBzb3VyY2UgaXMgbXVjaCBsZXNzLiBUaHVzIHRoZXNlIGFyZSBib3RoCnRyYW5zbGF0YWJsZSBzdHJpbmdzOgoKICAgIGdldHRleHQoIlRyYW5zbGF0YWJsZSBTdHJpbmciKQogICAgXygiVHJhbnNsYXRhYmxlIFN0cmluZyIpCgpQeXRob24gb2YgY291cnNlIGhhcyBubyBwcmVwcm9jZXNzb3Igc28gdGhpcyBkb2Vzbid0IHdvcmsgc28gd2VsbC4gIFRodXMsCnB5Z2V0dGV4dCBzZWFyY2hlcyBvbmx5IGZvciBfKCkgYnkgZGVmYXVsdCwgYnV0IHNlZSB0aGUgLWsvLS1rZXl3b3JkIGZsYWcKYmVsb3cgZm9yIGhvdyB0byBhdWdtZW50IHRoaXMuCgogWzFdIGh0dHA6Ly93d3cucHl0aG9uLm9yZy93b3Jrc2hvcHMvMTk5Ny0xMC9wcm9jZWVkaW5ncy9sb2V3aXMuaHRtbAogWzJdIGh0dHA6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9nZXR0ZXh0L2dldHRleHQuaHRtbAoKTk9URTogcHlnZXR0ZXh0IGF0dGVtcHRzIHRvIGJlIG9wdGlvbiBhbmQgZmVhdHVyZSBjb21wYXRpYmxlIHdpdGggR05VCnhnZXR0ZXh0IHdoZXJlIGV2ZXIgcG9zc2libGUuIEhvd2V2ZXIgc29tZSBvcHRpb25zIGFyZSBzdGlsbCBtaXNzaW5nIG9yIGFyZQpub3QgZnVsbHkgaW1wbGVtZW50ZWQuIEFsc28sIHhnZXR0ZXh0J3MgdXNlIG9mIGNvbW1hbmQgbGluZSBzd2l0Y2hlcyB3aXRoCm9wdGlvbiBhcmd1bWVudHMgaXMgYnJva2VuLCBhbmQgaW4gdGhlc2UgY2FzZXMsIHB5Z2V0dGV4dCBqdXN0IGRlZmluZXMKYWRkaXRpb25hbCBzd2l0Y2hlcy4KClVzYWdlOiBweWdldHRleHQgW29wdGlvbnNdIGlucHV0ZmlsZSAuLi4KCk9wdGlvbnM6CgogICAgLWEKICAgIC0tZXh0cmFjdC1hbGwKICAgICAgICBFeHRyYWN0IGFsbCBzdHJpbmdzLgoKICAgIC1kIG5hbWUKICAgIC0tZGVmYXVsdC1kb21haW49bmFtZQogICAgICAgIFJlbmFtZSB0aGUgZGVmYXVsdCBvdXRwdXQgZmlsZSBmcm9tIG1lc3NhZ2VzLnBvdCB0byBuYW1lLnBvdC4KCiAgICAtRQogICAgLS1lc2NhcGUKICAgICAgICBSZXBsYWNlIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIHdpdGggb2N0YWwgZXNjYXBlIHNlcXVlbmNlcy4KCiAgICAtRAogICAgLS1kb2NzdHJpbmdzCiAgICAgICAgRXh0cmFjdCBtb2R1bGUsIGNsYXNzLCBtZXRob2QsIGFuZCBmdW5jdGlvbiBkb2NzdHJpbmdzLiAgVGhlc2UgZG8KICAgICAgICBub3QgbmVlZCB0byBiZSB3cmFwcGVkIGluIF8oKSBtYXJrZXJzLCBhbmQgaW4gZmFjdCBjYW5ub3QgYmUgZm9yCiAgICAgICAgUHl0aG9uIHRvIGNvbnNpZGVyIHRoZW0gZG9jc3RyaW5ncy4gKFNlZSBhbHNvIHRoZSAtWCBvcHRpb24pLgoKICAgIC1oCiAgICAtLWhlbHAKICAgICAgICBQcmludCB0aGlzIGhlbHAgbWVzc2FnZSBhbmQgZXhpdC4KCiAgICAtayB3b3JkCiAgICAtLWtleXdvcmQ9d29yZAogICAgICAgIEtleXdvcmRzIHRvIGxvb2sgZm9yIGluIGFkZGl0aW9uIHRvIHRoZSBkZWZhdWx0IHNldCwgd2hpY2ggYXJlOgogICAgICAgICUoREVGQVVMVEtFWVdPUkRTKXMKCiAgICAgICAgWW91IGNhbiBoYXZlIG11bHRpcGxlIC1rIGZsYWdzIG9uIHRoZSBjb21tYW5kIGxpbmUuCgogICAgLUsKICAgIC0tbm8tZGVmYXVsdC1rZXl3b3JkcwogICAgICAgIERpc2FibGUgdGhlIGRlZmF1bHQgc2V0IG9mIGtleXdvcmRzIChzZWUgYWJvdmUpLiAgQW55IGtleXdvcmRzCiAgICAgICAgZXhwbGljaXRseSBhZGRlZCB3aXRoIHRoZSAtay8tLWtleXdvcmQgb3B0aW9uIGFyZSBzdGlsbCByZWNvZ25pemVkLgoKICAgIC0tbm8tbG9jYXRpb24KICAgICAgICBEbyBub3Qgd3JpdGUgZmlsZW5hbWUvbGluZW5vIGxvY2F0aW9uIGNvbW1lbnRzLgoKICAgIC1uCiAgICAtLWFkZC1sb2NhdGlvbgogICAgICAgIFdyaXRlIGZpbGVuYW1lL2xpbmVubyBsb2NhdGlvbiBjb21tZW50cyBpbmRpY2F0aW5nIHdoZXJlIGVhY2gKICAgICAgICBleHRyYWN0ZWQgc3RyaW5nIGlzIGZvdW5kIGluIHRoZSBzb3VyY2UuICBUaGVzZSBsaW5lcyBhcHBlYXIgYmVmb3JlCiAgICAgICAgZWFjaCBtc2dpZC4gIFRoZSBzdHlsZSBvZiBjb21tZW50cyBpcyBjb250cm9sbGVkIGJ5IHRoZSAtUy8tLXN0eWxlCiAgICAgICAgb3B0aW9uLiAgVGhpcyBpcyB0aGUgZGVmYXVsdC4KCiAgICAtbyBmaWxlbmFtZQogICAgLS1vdXRwdXQ9ZmlsZW5hbWUKICAgICAgICBSZW5hbWUgdGhlIGRlZmF1bHQgb3V0cHV0IGZpbGUgZnJvbSBtZXNzYWdlcy5wb3QgdG8gZmlsZW5hbWUuICBJZgogICAgICAgIGZpbGVuYW1lIGlzIGAtJyB0aGVuIHRoZSBvdXRwdXQgaXMgc2VudCB0byBzdGFuZGFyZCBvdXQuCgogICAgLXAgZGlyCiAgICAtLW91dHB1dC1kaXI9ZGlyCiAgICAgICAgT3V0cHV0IGZpbGVzIHdpbGwgYmUgcGxhY2VkIGluIGRpcmVjdG9yeSBkaXIuCgogICAgLVMgc3R5bGVuYW1lCiAgICAtLXN0eWxlIHN0eWxlbmFtZQogICAgICAgIFNwZWNpZnkgd2hpY2ggc3R5bGUgdG8gdXNlIGZvciBsb2NhdGlvbiBjb21tZW50cy4gIFR3byBzdHlsZXMgYXJlCiAgICAgICAgc3VwcG9ydGVkOgoKICAgICAgICBTb2xhcmlzICAjIEZpbGU6IGZpbGVuYW1lLCBsaW5lOiBsaW5lLW51bWJlcgogICAgICAgIEdOVSAgICAgICM6IGZpbGVuYW1lOmxpbmUKCiAgICAgICAgVGhlIHN0eWxlIG5hbWUgaXMgY2FzZSBpbnNlbnNpdGl2ZS4gIEdOVSBzdHlsZSBpcyB0aGUgZGVmYXVsdC4KCiAgICAtdgogICAgLS12ZXJib3NlCiAgICAgICAgUHJpbnQgdGhlIG5hbWVzIG9mIHRoZSBmaWxlcyBiZWluZyBwcm9jZXNzZWQuCgogICAgLVYKICAgIC0tdmVyc2lvbgogICAgICAgIFByaW50IHRoZSB2ZXJzaW9uIG9mIHB5Z2V0dGV4dCBhbmQgZXhpdC4KCiAgICAtdyBjb2x1bW5zCiAgICAtLXdpZHRoPWNvbHVtbnMKICAgICAgICBTZXQgd2lkdGggb2Ygb3V0cHV0IHRvIGNvbHVtbnMuCgogICAgLXggZmlsZW5hbWUKICAgIC0tZXhjbHVkZS1maWxlPWZpbGVuYW1lCiAgICAgICAgU3BlY2lmeSBhIGZpbGUgdGhhdCBjb250YWlucyBhIGxpc3Qgb2Ygc3RyaW5ncyB0aGF0IGFyZSBub3QgYmUKICAgICAgICBleHRyYWN0ZWQgZnJvbSB0aGUgaW5wdXQgZmlsZXMuICBFYWNoIHN0cmluZyB0byBiZSBleGNsdWRlZCBtdXN0CiAgICAgICAgYXBwZWFyIG9uIGEgbGluZSBieSBpdHNlbGYgaW4gdGhlIGZpbGUuCgogICAgLVggZmlsZW5hbWUKICAgIC0tbm8tZG9jc3RyaW5ncz1maWxlbmFtZQogICAgICAgIFNwZWNpZnkgYSBmaWxlIHRoYXQgY29udGFpbnMgYSBsaXN0IG9mIGZpbGVzIChvbmUgcGVyIGxpbmUpIHRoYXQKICAgICAgICBzaG91bGQgbm90IGhhdmUgdGhlaXIgZG9jc3RyaW5ncyBleHRyYWN0ZWQuICBUaGlzIGlzIG9ubHkgdXNlZnVsIGluCiAgICAgICAgY29uanVuY3Rpb24gd2l0aCB0aGUgLUQgb3B0aW9uIGFib3ZlLgoKSWYgYGlucHV0ZmlsZScgaXMgLSwgc3RhbmRhcmQgaW5wdXQgaXMgcmVhZC4KIiIiKQoKaW1wb3J0IG9zCmltcG9ydCBpbXAKaW1wb3J0IHN5cwppbXBvcnQgZ2xvYgppbXBvcnQgdGltZQppbXBvcnQgZ2V0b3B0CmltcG9ydCB0b2tlbgppbXBvcnQgdG9rZW5pemUKaW1wb3J0IG9wZXJhdG9yCgpfX3ZlcnNpb25fXyA9ICcxLjUnCgpkZWZhdWx0X2tleXdvcmRzID0gWydfJ10KREVGQVVMVEtFWVdPUkRTID0gJywgJy5qb2luKGRlZmF1bHRfa2V5d29yZHMpCgpFTVBUWVNUUklORyA9ICcnCgoKDAojIFRoZSBub3JtYWwgcG90LWZpbGUgaGVhZGVyLiBtc2dtZXJnZSBhbmQgRW1hY3MncyBwby1tb2RlIHdvcmsgYmV0dGVyIGlmIGl0J3MKIyB0aGVyZS4KcG90X2hlYWRlciA9IF8oJycnXAojIFNPTUUgREVTQ1JJUFRJVkUgVElUTEUuCiMgQ29weXJpZ2h0IChDKSBZRUFSIE9SR0FOSVpBVElPTgojIEZJUlNUIEFVVEhPUiA8RU1BSUxAQUREUkVTUz4sIFlFQVIuCiMKbXNnaWQgIiIKbXNnc3RyICIiCiJQcm9qZWN0LUlkLVZlcnNpb246IFBBQ0tBR0UgVkVSU0lPTlxcbiIKIlBPVC1DcmVhdGlvbi1EYXRlOiAlKHRpbWUpc1xcbiIKIlBPLVJldmlzaW9uLURhdGU6IFlFQVItTU8tREEgSE86TUkrWk9ORVxcbiIKIkxhc3QtVHJhbnNsYXRvcjogRlVMTCBOQU1FIDxFTUFJTEBBRERSRVNTPlxcbiIKIkxhbmd1YWdlLVRlYW06IExBTkdVQUdFIDxMTEBsaS5vcmc+XFxuIgoiTUlNRS1WZXJzaW9uOiAxLjBcXG4iCiJDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9Q0hBUlNFVFxcbiIKIkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IEVOQ09ESU5HXFxuIgoiR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgJSh2ZXJzaW9uKXNcXG4iCgonJycpCgoMCmRlZiB1c2FnZShjb2RlLCBtc2c9JycpOgogICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgX19kb2NfXyAlIGdsb2JhbHMoKQogICAgaWYgbXNnOgogICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIG1zZwogICAgc3lzLmV4aXQoY29kZSkKCgoMCmVzY2FwZXMgPSBbXQoKZGVmIG1ha2VfZXNjYXBlcyhwYXNzX2lzbzg4NTkpOgogICAgZ2xvYmFsIGVzY2FwZXMKICAgIGlmIHBhc3NfaXNvODg1OToKICAgICAgICAjIEFsbG93IGlzby04ODU5IGNoYXJhY3RlcnMgdG8gcGFzcyB0aHJvdWdoIHNvIHRoYXQgZS5nLiAnbXNnaWQKICAgICAgICAjICJI9mhlIicgd291bGQgcmVzdWx0IG5vdCByZXN1bHQgaW4gJ21zZ2lkICJIXDM2NmhlIicuICBPdGhlcndpc2Ugd2UKICAgICAgICAjIGVzY2FwZSBhbnkgY2hhcmFjdGVyIG91dHNpZGUgdGhlIDMyLi4xMjYgcmFuZ2UuCiAgICAgICAgbW9kID0gMTI4CiAgICBlbHNlOgogICAgICAgIG1vZCA9IDI1NgogICAgZm9yIGkgaW4gcmFuZ2UoMjU2KToKICAgICAgICBpZiAzMiA8PSAoaSAlIG1vZCkgPD0gMTI2OgogICAgICAgICAgICBlc2NhcGVzLmFwcGVuZChjaHIoaSkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZXNjYXBlcy5hcHBlbmQoIlxcJTAzbyIgJSBpKQogICAgZXNjYXBlc1tvcmQoJ1xcJyldID0gJ1xcXFwnCiAgICBlc2NhcGVzW29yZCgnXHQnKV0gPSAnXFx0JwogICAgZXNjYXBlc1tvcmQoJ1xyJyldID0gJ1xccicKICAgIGVzY2FwZXNbb3JkKCdcbicpXSA9ICdcXG4nCiAgICBlc2NhcGVzW29yZCgnXCInKV0gPSAnXFwiJwoKCmRlZiBlc2NhcGUocyk6CiAgICBnbG9iYWwgZXNjYXBlcwogICAgcyA9IGxpc3QocykKICAgIGZvciBpIGluIHJhbmdlKGxlbihzKSk6CiAgICAgICAgc1tpXSA9IGVzY2FwZXNbb3JkKHNbaV0pXQogICAgcmV0dXJuIEVNUFRZU1RSSU5HLmpvaW4ocykKCgpkZWYgc2FmZV9ldmFsKHMpOgogICAgIyB1bndyYXAgcXVvdGVzLCBzYWZlbHkKICAgIHJldHVybiBldmFsKHMsIHsnX19idWlsdGluc19fJzp7fX0sIHt9KQoKCmRlZiBub3JtYWxpemUocyk6CiAgICAjIFRoaXMgY29udmVydHMgdGhlIHZhcmlvdXMgUHl0aG9uIHN0cmluZyB0eXBlcyBpbnRvIGEgZm9ybWF0IHRoYXQgaXMKICAgICMgYXBwcm9wcmlhdGUgZm9yIC5wbyBmaWxlcywgbmFtZWx5IG11Y2ggY2xvc2VyIHRvIEMgc3R5bGUuCiAgICBsaW5lcyA9IHMuc3BsaXQoJ1xuJykKICAgIGlmIGxlbihsaW5lcykgPT0gMToKICAgICAgICBzID0gJyInICsgZXNjYXBlKHMpICsgJyInCiAgICBlbHNlOgogICAgICAgIGlmIG5vdCBsaW5lc1stMV06CiAgICAgICAgICAgIGRlbCBsaW5lc1stMV0KICAgICAgICAgICAgbGluZXNbLTFdID0gbGluZXNbLTFdICsgJ1xuJwogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihsaW5lcykpOgogICAgICAgICAgICBsaW5lc1tpXSA9IGVzY2FwZShsaW5lc1tpXSkKICAgICAgICBsaW5ldGVybSA9ICdcXG4iXG4iJwogICAgICAgIHMgPSAnIiJcbiInICsgbGluZXRlcm0uam9pbihsaW5lcykgKyAnIicKICAgIHJldHVybiBzCgoMCmRlZiBjb250YWluc0FueShzdHIsIHNldCk6CiAgICAiIiJDaGVjayB3aGV0aGVyICdzdHInIGNvbnRhaW5zIEFOWSBvZiB0aGUgY2hhcnMgaW4gJ3NldCciIiIKICAgIHJldHVybiAxIGluIFtjIGluIHN0ciBmb3IgYyBpbiBzZXRdCgoKZGVmIF92aXNpdF9weWZpbGVzKGxpc3QsIGRpcm5hbWUsIG5hbWVzKToKICAgICIiIkhlbHBlciBmb3IgZ2V0RmlsZXNGb3JOYW1lKCkuIiIiCiAgICAjIGdldCBleHRlbnNpb24gZm9yIHB5dGhvbiBzb3VyY2UgZmlsZXMKICAgIGlmIG5vdCBnbG9iYWxzKCkuaGFzX2tleSgnX3B5X2V4dCcpOgogICAgICAgIGdsb2JhbCBfcHlfZXh0CiAgICAgICAgX3B5X2V4dCA9IFt0cmlwbGVbMF0gZm9yIHRyaXBsZSBpbiBpbXAuZ2V0X3N1ZmZpeGVzKCkKICAgICAgICAgICAgICAgICAgIGlmIHRyaXBsZVsyXSA9PSBpbXAuUFlfU09VUkNFXVswXQoKICAgICMgZG9uJ3QgcmVjdXJzZSBpbnRvIENWUyBkaXJlY3RvcmllcwogICAgaWYgJ0NWUycgaW4gbmFtZXM6CiAgICAgICAgbmFtZXMucmVtb3ZlKCdDVlMnKQoKICAgICMgYWRkIGFsbCAqLnB5IGZpbGVzIHRvIGxpc3QKICAgIGxpc3QuZXh0ZW5kKAogICAgICAgIFtvcy5wYXRoLmpvaW4oZGlybmFtZSwgZmlsZSkgZm9yIGZpbGUgaW4gbmFtZXMKICAgICAgICAgaWYgb3MucGF0aC5zcGxpdGV4dChmaWxlKVsxXSA9PSBfcHlfZXh0XQogICAgICAgICkKCgpkZWYgX2dldF9tb2Rwa2dfcGF0aChkb3R0ZWRfbmFtZSwgcGF0aGxpc3Q9Tm9uZSk6CiAgICAiIiJHZXQgdGhlIGZpbGVzeXN0ZW0gcGF0aCBmb3IgYSBtb2R1bGUgb3IgYSBwYWNrYWdlLgoKICAgIFJldHVybiB0aGUgZmlsZSBzeXN0ZW0gcGF0aCB0byBhIGZpbGUgZm9yIGEgbW9kdWxlLCBhbmQgdG8gYSBkaXJlY3RvcnkgZm9yCiAgICBhIHBhY2thZ2UuIFJldHVybiBOb25lIGlmIHRoZSBuYW1lIGlzIG5vdCBmb3VuZCwgb3IgaXMgYSBidWlsdGluIG9yCiAgICBleHRlbnNpb24gbW9kdWxlLgogICAgIiIiCiAgICAjIHNwbGl0IG9mZiB0b3AtbW9zdCBuYW1lCiAgICBwYXJ0cyA9IGRvdHRlZF9uYW1lLnNwbGl0KCcuJywgMSkKCiAgICBpZiBsZW4ocGFydHMpID4gMToKICAgICAgICAjIHdlIGhhdmUgYSBkb3R0ZWQgcGF0aCwgaW1wb3J0IHRvcC1sZXZlbCBwYWNrYWdlCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmaWxlLCBwYXRobmFtZSwgZGVzY3JpcHRpb24gPSBpbXAuZmluZF9tb2R1bGUocGFydHNbMF0sIHBhdGhsaXN0KQogICAgICAgICAgICBpZiBmaWxlOiBmaWxlLmNsb3NlKCkKICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgICMgY2hlY2sgaWYgaXQncyBpbmRlZWQgYSBwYWNrYWdlCiAgICAgICAgaWYgZGVzY3JpcHRpb25bMl0gPT0gaW1wLlBLR19ESVJFQ1RPUlk6CiAgICAgICAgICAgICMgcmVjdXJzaXZlbHkgaGFuZGxlIHRoZSByZW1haW5pbmcgbmFtZSBwYXJ0cwogICAgICAgICAgICBwYXRobmFtZSA9IF9nZXRfbW9kcGtnX3BhdGgocGFydHNbMV0sIFtwYXRobmFtZV0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcGF0aG5hbWUgPSBOb25lCiAgICBlbHNlOgogICAgICAgICMgcGxhaW4gbmFtZQogICAgICAgIHRyeToKICAgICAgICAgICAgZmlsZSwgcGF0aG5hbWUsIGRlc2NyaXB0aW9uID0gaW1wLmZpbmRfbW9kdWxlKAogICAgICAgICAgICAgICAgZG90dGVkX25hbWUsIHBhdGhsaXN0KQogICAgICAgICAgICBpZiBmaWxlOgogICAgICAgICAgICAgICAgZmlsZS5jbG9zZSgpCiAgICAgICAgICAgIGlmIGRlc2NyaXB0aW9uWzJdIG5vdCBpbiBbaW1wLlBZX1NPVVJDRSwgaW1wLlBLR19ESVJFQ1RPUlldOgogICAgICAgICAgICAgICAgcGF0aG5hbWUgPSBOb25lCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICBwYXRobmFtZSA9IE5vbmUKCiAgICByZXR1cm4gcGF0aG5hbWUKCgpkZWYgZ2V0RmlsZXNGb3JOYW1lKG5hbWUpOgogICAgIiIiR2V0IGEgbGlzdCBvZiBtb2R1bGUgZmlsZXMgZm9yIGEgZmlsZW5hbWUsIGEgbW9kdWxlIG9yIHBhY2thZ2UgbmFtZSwKICAgIG9yIGEgZGlyZWN0b3J5LgogICAgIiIiCiAgICBpZiBub3Qgb3MucGF0aC5leGlzdHMobmFtZSk6CiAgICAgICAgIyBjaGVjayBmb3IgZ2xvYiBjaGFycwogICAgICAgIGlmIGNvbnRhaW5zQW55KG5hbWUsICIqP1tdIik6CiAgICAgICAgICAgIGZpbGVzID0gZ2xvYi5nbG9iKG5hbWUpCiAgICAgICAgICAgIGxpc3QgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgICAgIGxpc3QuZXh0ZW5kKGdldEZpbGVzRm9yTmFtZShmaWxlKSkKICAgICAgICAgICAgcmV0dXJuIGxpc3QKCiAgICAgICAgIyB0cnkgdG8gZmluZCBtb2R1bGUgb3IgcGFja2FnZQogICAgICAgIG5hbWUgPSBfZ2V0X21vZHBrZ19wYXRoKG5hbWUpCiAgICAgICAgaWYgbm90IG5hbWU6CiAgICAgICAgICAgIHJldHVybiBbXQoKICAgIGlmIG9zLnBhdGguaXNkaXIobmFtZSk6CiAgICAgICAgIyBmaW5kIGFsbCBweXRob24gZmlsZXMgaW4gZGlyZWN0b3J5CiAgICAgICAgbGlzdCA9IFtdCiAgICAgICAgb3MucGF0aC53YWxrKG5hbWUsIF92aXNpdF9weWZpbGVzLCBsaXN0KQogICAgICAgIHJldHVybiBsaXN0CiAgICBlbGlmIG9zLnBhdGguZXhpc3RzKG5hbWUpOgogICAgICAgICMgYSBzaW5nbGUgZmlsZQogICAgICAgIHJldHVybiBbbmFtZV0KCiAgICByZXR1cm4gW10KCgwKY2xhc3MgVG9rZW5FYXRlcjoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvcHRpb25zKToKICAgICAgICBzZWxmLl9fb3B0aW9ucyA9IG9wdGlvbnMKICAgICAgICBzZWxmLl9fbWVzc2FnZXMgPSB7fQogICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCiAgICAgICAgc2VsZi5fX2RhdGEgPSBbXQogICAgICAgIHNlbGYuX19saW5lbm8gPSAtMQogICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDEKICAgICAgICBzZWxmLl9fY3VyZmlsZSA9IE5vbmUKCiAgICBkZWYgX19jYWxsX18oc2VsZiwgdHR5cGUsIHRzdHJpbmcsIHN0dXAsIGV0dXAsIGxpbmUpOgogICAgICAgICMgZGlzcGF0Y2gKIyMgICAgICAgIGltcG9ydCB0b2tlbgojIyAgICAgICAgcHJpbnQgPj4gc3lzLnN0ZGVyciwgJ3R0eXBlOicsIHRva2VuLnRva19uYW1lW3R0eXBlXSwgXAojIyAgICAgICAgICAgICAgJ3RzdHJpbmc6JywgdHN0cmluZwogICAgICAgIHNlbGYuX19zdGF0ZSh0dHlwZSwgdHN0cmluZywgc3R1cFswXSkKCiAgICBkZWYgX193YWl0aW5nKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOgogICAgICAgIG9wdHMgPSBzZWxmLl9fb3B0aW9ucwogICAgICAgICMgRG8gZG9jc3RyaW5nIGV4dHJhY3Rpb25zLCBpZiBlbmFibGVkCiAgICAgICAgaWYgb3B0cy5kb2NzdHJpbmdzIGFuZCBub3Qgb3B0cy5ub2RvY3N0cmluZ3MuZ2V0KHNlbGYuX19jdXJmaWxlKToKICAgICAgICAgICAgIyBtb2R1bGUgZG9jc3RyaW5nPwogICAgICAgICAgICBpZiBzZWxmLl9fZnJlc2htb2R1bGU6CiAgICAgICAgICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5TVFJJTkc6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2FkZGVudHJ5KHNhZmVfZXZhbCh0c3RyaW5nKSwgbGluZW5vLCBpc2RvY3N0cmluZz0xKQogICAgICAgICAgICAgICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDAKICAgICAgICAgICAgICAgIGVsaWYgdHR5cGUgbm90IGluICh0b2tlbml6ZS5DT01NRU5ULCB0b2tlbml6ZS5OTCk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMAogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICMgY2xhc3MgZG9jc3RyaW5nPwogICAgICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5OQU1FIGFuZCB0c3RyaW5nIGluICgnY2xhc3MnLCAnZGVmJyk6CiAgICAgICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fc3VpdGVzZWVuCiAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5OQU1FIGFuZCB0c3RyaW5nIGluIG9wdHMua2V5d29yZHM6CiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX19rZXl3b3Jkc2VlbgoKICAgIGRlZiBfX3N1aXRlc2VlbihzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICAjIGlnbm9yZSBhbnl0aGluZyB1bnRpbCB3ZSBzZWUgdGhlIGNvbG9uCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuT1AgYW5kIHRzdHJpbmcgPT0gJzonOgogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fc3VpdGVkb2NzdHJpbmcKCiAgICBkZWYgX19zdWl0ZWRvY3N0cmluZyhzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICAjIGlnbm9yZSBhbnkgaW50ZXJ2ZW5pbmcgbm9pc2UKICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5TVFJJTkc6CiAgICAgICAgICAgIHNlbGYuX19hZGRlbnRyeShzYWZlX2V2YWwodHN0cmluZyksIGxpbmVubywgaXNkb2NzdHJpbmc9MSkKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKICAgICAgICBlbGlmIHR0eXBlIG5vdCBpbiAodG9rZW5pemUuTkVXTElORSwgdG9rZW5pemUuSU5ERU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbml6ZS5DT01NRU5UKToKICAgICAgICAgICAgIyB0aGVyZSB3YXMgbm8gY2xhc3MgZG9jc3RyaW5nCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCgogICAgZGVmIF9fa2V5d29yZHNlZW4oc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6CiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuT1AgYW5kIHRzdHJpbmcgPT0gJygnOgogICAgICAgICAgICBzZWxmLl9fZGF0YSA9IFtdCiAgICAgICAgICAgIHNlbGYuX19saW5lbm8gPSBsaW5lbm8KICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX29wZW5zZWVuCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKCiAgICBkZWYgX19vcGVuc2VlbihzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5PUCBhbmQgdHN0cmluZyA9PSAnKSc6CiAgICAgICAgICAgICMgV2UndmUgc2VlbiB0aGUgbGFzdCBvZiB0aGUgdHJhbnNsYXRhYmxlIHN0cmluZ3MuICBSZWNvcmQgdGhlCiAgICAgICAgICAgICMgbGluZSBudW1iZXIgb2YgdGhlIGZpcnN0IGxpbmUgb2YgdGhlIHN0cmluZ3MgYW5kIHVwZGF0ZSB0aGUgbGlzdAogICAgICAgICAgICAjIG9mIG1lc3NhZ2VzIHNlZW4uICBSZXNldCBzdGF0ZSBmb3IgdGhlIG5leHQgYmF0Y2guICBJZiB0aGVyZQogICAgICAgICAgICAjIHdlcmUgbm8gc3RyaW5ncyBpbnNpZGUgXygpLCB0aGVuIGp1c3QgaWdub3JlIHRoaXMgZW50cnkuCiAgICAgICAgICAgIGlmIHNlbGYuX19kYXRhOgogICAgICAgICAgICAgICAgc2VsZi5fX2FkZGVudHJ5KEVNUFRZU1RSSU5HLmpvaW4oc2VsZi5fX2RhdGEpKQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwogICAgICAgIGVsaWYgdHR5cGUgPT0gdG9rZW5pemUuU1RSSU5HOgogICAgICAgICAgICBzZWxmLl9fZGF0YS5hcHBlbmQoc2FmZV9ldmFsKHRzdHJpbmcpKQogICAgICAgIGVsaWYgdHR5cGUgbm90IGluIFt0b2tlbml6ZS5DT01NRU5ULCB0b2tlbi5JTkRFTlQsIHRva2VuLkRFREVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW4uTkVXTElORSwgdG9rZW5pemUuTkxdOgogICAgICAgICAgICAjIHdhcm4gaWYgd2Ugc2VlIGFueXRoaW5nIGVsc2UgdGhhbiBTVFJJTkcgb3Igd2hpdGVzcGFjZQogICAgICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCBfKAogICAgICAgICAgICAgICAgJyoqKiAlKGZpbGUpczolKGxpbmVubylzOiBTZWVuIHVuZXhwZWN0ZWQgdG9rZW4gIiUodG9rZW4pcyInCiAgICAgICAgICAgICAgICApICUgewogICAgICAgICAgICAgICAgJ3Rva2VuJzogdHN0cmluZywKICAgICAgICAgICAgICAgICdmaWxlJzogc2VsZi5fX2N1cmZpbGUsCiAgICAgICAgICAgICAgICAnbGluZW5vJzogc2VsZi5fX2xpbmVubwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwoKICAgIGRlZiBfX2FkZGVudHJ5KHNlbGYsIG1zZywgbGluZW5vPU5vbmUsIGlzZG9jc3RyaW5nPTApOgogICAgICAgIGlmIGxpbmVubyBpcyBOb25lOgogICAgICAgICAgICBsaW5lbm8gPSBzZWxmLl9fbGluZW5vCiAgICAgICAgaWYgbm90IG1zZyBpbiBzZWxmLl9fb3B0aW9ucy50b2V4Y2x1ZGU6CiAgICAgICAgICAgIGVudHJ5ID0gKHNlbGYuX19jdXJmaWxlLCBsaW5lbm8pCiAgICAgICAgICAgIHNlbGYuX19tZXNzYWdlcy5zZXRkZWZhdWx0KG1zZywge30pW2VudHJ5XSA9IGlzZG9jc3RyaW5nCgogICAgZGVmIHNldF9maWxlbmFtZShzZWxmLCBmaWxlbmFtZSk6CiAgICAgICAgc2VsZi5fX2N1cmZpbGUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDEKCiAgICBkZWYgd3JpdGUoc2VsZiwgZnApOgogICAgICAgIG9wdGlvbnMgPSBzZWxmLl9fb3B0aW9ucwogICAgICAgIHRpbWVzdGFtcCA9IHRpbWUuY3RpbWUodGltZS50aW1lKCkpCiAgICAgICAgIyBUaGUgdGltZSBzdGFtcCBpbiB0aGUgaGVhZGVyIGRvZXNuJ3QgaGF2ZSB0aGUgc2FtZSBmb3JtYXQgYXMgdGhhdAogICAgICAgICMgZ2VuZXJhdGVkIGJ5IHhnZXR0ZXh0Li4uCiAgICAgICAgcHJpbnQgPj4gZnAsIHBvdF9oZWFkZXIgJSB7J3RpbWUnOiB0aW1lc3RhbXAsICd2ZXJzaW9uJzogX192ZXJzaW9uX199CiAgICAgICAgIyBTb3J0IHRoZSBlbnRyaWVzLiAgRmlyc3Qgc29ydCBlYWNoIHBhcnRpY3VsYXIgZW50cnkncyBrZXlzLCB0aGVuCiAgICAgICAgIyBzb3J0IGFsbCB0aGUgZW50cmllcyBieSB0aGVpciBmaXJzdCBpdGVtLgogICAgICAgIHJldmVyc2UgPSB7fQogICAgICAgIGZvciBrLCB2IGluIHNlbGYuX19tZXNzYWdlcy5pdGVtcygpOgogICAgICAgICAgICBrZXlzID0gdi5rZXlzKCkKICAgICAgICAgICAga2V5cy5zb3J0KCkKICAgICAgICAgICAgcmV2ZXJzZS5zZXRkZWZhdWx0KHR1cGxlKGtleXMpLCBbXSkuYXBwZW5kKChrLCB2KSkKICAgICAgICBya2V5cyA9IHJldmVyc2Uua2V5cygpCiAgICAgICAgcmtleXMuc29ydCgpCiAgICAgICAgZm9yIHJrZXkgaW4gcmtleXM6CiAgICAgICAgICAgIHJlbnRyaWVzID0gcmV2ZXJzZVtya2V5XQogICAgICAgICAgICByZW50cmllcy5zb3J0KCkKICAgICAgICAgICAgZm9yIGssIHYgaW4gcmVudHJpZXM6CiAgICAgICAgICAgICAgICBpc2RvY3N0cmluZyA9IDAKICAgICAgICAgICAgICAgICMgSWYgdGhlIGVudHJ5IHdhcyBnbGVhbmVkIG91dCBvZiBhIGRvY3N0cmluZywgdGhlbiBhZGQgYQogICAgICAgICAgICAgICAgIyBjb21tZW50IHN0YXRpbmcgc28uICBUaGlzIGlzIHRvIGFpZCB0cmFuc2xhdG9ycyB3aG8gbWF5IHdpc2gKICAgICAgICAgICAgICAgICMgdG8gc2tpcCB0cmFuc2xhdGluZyBzb21lIHVuaW1wb3J0YW50IGRvY3N0cmluZ3MuCiAgICAgICAgICAgICAgICBpZiByZWR1Y2Uob3BlcmF0b3IuX19hZGRfXywgdi52YWx1ZXMoKSk6CiAgICAgICAgICAgICAgICAgICAgaXNkb2NzdHJpbmcgPSAxCiAgICAgICAgICAgICAgICAjIGsgaXMgdGhlIG1lc3NhZ2Ugc3RyaW5nLCB2IGlzIGEgZGljdGlvbmFyeS1zZXQgb2YgKGZpbGVuYW1lLAogICAgICAgICAgICAgICAgIyBsaW5lbm8pIHR1cGxlcy4gIFdlIHdhbnQgdG8gc29ydCB0aGUgZW50cmllcyBpbiB2IGZpcnN0IGJ5CiAgICAgICAgICAgICAgICAjIGZpbGUgbmFtZSBhbmQgdGhlbiBieSBsaW5lIG51bWJlci4KICAgICAgICAgICAgICAgIHYgPSB2LmtleXMoKQogICAgICAgICAgICAgICAgdi5zb3J0KCkKICAgICAgICAgICAgICAgIGlmIG5vdCBvcHRpb25zLndyaXRlbG9jYXRpb25zOgogICAgICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgICAgICMgbG9jYXRpb24gY29tbWVudHMgYXJlIGRpZmZlcmVudCBiL3cgU29sYXJpcyBhbmQgR05VOgogICAgICAgICAgICAgICAgZWxpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgPT0gb3B0aW9ucy5TT0xBUklTOgogICAgICAgICAgICAgICAgICAgIGZvciBmaWxlbmFtZSwgbGluZW5vIGluIHY6CiAgICAgICAgICAgICAgICAgICAgICAgIGQgPSB7J2ZpbGVuYW1lJzogZmlsZW5hbWUsICdsaW5lbm8nOiBsaW5lbm99CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ID4+ZnAsIF8oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIyBGaWxlOiAlKGZpbGVuYW1lKXMsIGxpbmU6ICUobGluZW5vKWQnKSAlIGQKICAgICAgICAgICAgICAgIGVsaWYgb3B0aW9ucy5sb2NhdGlvbnN0eWxlID09IG9wdGlvbnMuR05VOgogICAgICAgICAgICAgICAgICAgICMgZml0IGFzIG1hbnkgbG9jYXRpb25zIG9uIG9uZSBsaW5lLCBhcyBsb25nIGFzIHRoZQogICAgICAgICAgICAgICAgICAgICMgcmVzdWx0aW5nIGxpbmUgbGVuZ3RoIGRvZXNuJ3QgZXhjZWVkcyAnb3B0aW9ucy53aWR0aCcKICAgICAgICAgICAgICAgICAgICBsb2NsaW5lID0gJyM6JwogICAgICAgICAgICAgICAgICAgIGZvciBmaWxlbmFtZSwgbGluZW5vIGluIHY6CiAgICAgICAgICAgICAgICAgICAgICAgIGQgPSB7J2ZpbGVuYW1lJzogZmlsZW5hbWUsICdsaW5lbm8nOiBsaW5lbm99CiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBfKCcgJShmaWxlbmFtZSlzOiUobGluZW5vKWQnKSAlIGQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKGxvY2xpbmUpICsgbGVuKHMpIDw9IG9wdGlvbnMud2lkdGg6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NsaW5lID0gbG9jbGluZSArIHMKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ID4+IGZwLCBsb2NsaW5lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NsaW5lID0gIiM6IiArIHMKICAgICAgICAgICAgICAgICAgICBpZiBsZW4obG9jbGluZSkgPiAyOgogICAgICAgICAgICAgICAgICAgICAgICBwcmludCA+PiBmcCwgbG9jbGluZQogICAgICAgICAgICAgICAgaWYgaXNkb2NzdHJpbmc6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgPj4gZnAsICcjLCBkb2NzdHJpbmcnCiAgICAgICAgICAgICAgICBwcmludCA+PiBmcCwgJ21zZ2lkJywgbm9ybWFsaXplKGspCiAgICAgICAgICAgICAgICBwcmludCA+PiBmcCwgJ21zZ3N0ciAiIlxuJwoKCgwKZGVmIG1haW4oKToKICAgIGdsb2JhbCBkZWZhdWx0X2tleXdvcmRzCiAgICB0cnk6CiAgICAgICAgb3B0cywgYXJncyA9IGdldG9wdC5nZXRvcHQoCiAgICAgICAgICAgIHN5cy5hcmd2WzE6XSwKICAgICAgICAgICAgJ2FkOkRFaGs6S25vOnA6UzpWdnc6eDpYOicsCiAgICAgICAgICAgIFsnZXh0cmFjdC1hbGwnLCAnZGVmYXVsdC1kb21haW49JywgJ2VzY2FwZScsICdoZWxwJywKICAgICAgICAgICAgICdrZXl3b3JkPScsICduby1kZWZhdWx0LWtleXdvcmRzJywKICAgICAgICAgICAgICdhZGQtbG9jYXRpb24nLCAnbm8tbG9jYXRpb24nLCAnb3V0cHV0PScsICdvdXRwdXQtZGlyPScsCiAgICAgICAgICAgICAnc3R5bGU9JywgJ3ZlcmJvc2UnLCAndmVyc2lvbicsICd3aWR0aD0nLCAnZXhjbHVkZS1maWxlPScsCiAgICAgICAgICAgICAnZG9jc3RyaW5ncycsICduby1kb2NzdHJpbmdzJywKICAgICAgICAgICAgIF0pCiAgICBleGNlcHQgZ2V0b3B0LmVycm9yLCBtc2c6CiAgICAgICAgdXNhZ2UoMSwgbXNnKQoKICAgICMgZm9yIGhvbGRpbmcgb3B0aW9uIHZhbHVlcwogICAgY2xhc3MgT3B0aW9uczoKICAgICAgICAjIGNvbnN0YW50cwogICAgICAgIEdOVSA9IDEKICAgICAgICBTT0xBUklTID0gMgogICAgICAgICMgZGVmYXVsdHMKICAgICAgICBleHRyYWN0YWxsID0gMCAjIEZJWE1FOiBjdXJyZW50bHkgdGhpcyBvcHRpb24gaGFzIG5vIGVmZmVjdCBhdCBhbGwuCiAgICAgICAgZXNjYXBlID0gMAogICAgICAgIGtleXdvcmRzID0gW10KICAgICAgICBvdXRwYXRoID0gJycKICAgICAgICBvdXRmaWxlID0gJ21lc3NhZ2VzLnBvdCcKICAgICAgICB3cml0ZWxvY2F0aW9ucyA9IDEKICAgICAgICBsb2NhdGlvbnN0eWxlID0gR05VCiAgICAgICAgdmVyYm9zZSA9IDAKICAgICAgICB3aWR0aCA9IDc4CiAgICAgICAgZXhjbHVkZWZpbGVuYW1lID0gJycKICAgICAgICBkb2NzdHJpbmdzID0gMAogICAgICAgIG5vZG9jc3RyaW5ncyA9IHt9CgogICAgb3B0aW9ucyA9IE9wdGlvbnMoKQogICAgbG9jYXRpb25zID0geydnbnUnIDogb3B0aW9ucy5HTlUsCiAgICAgICAgICAgICAgICAgJ3NvbGFyaXMnIDogb3B0aW9ucy5TT0xBUklTLAogICAgICAgICAgICAgICAgIH0KCiAgICAjIHBhcnNlIG9wdGlvbnMKICAgIGZvciBvcHQsIGFyZyBpbiBvcHRzOgogICAgICAgIGlmIG9wdCBpbiAoJy1oJywgJy0taGVscCcpOgogICAgICAgICAgICB1c2FnZSgwKQogICAgICAgIGVsaWYgb3B0IGluICgnLWEnLCAnLS1leHRyYWN0LWFsbCcpOgogICAgICAgICAgICBvcHRpb25zLmV4dHJhY3RhbGwgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctZCcsICctLWRlZmF1bHQtZG9tYWluJyk6CiAgICAgICAgICAgIG9wdGlvbnMub3V0ZmlsZSA9IGFyZyArICcucG90JwogICAgICAgIGVsaWYgb3B0IGluICgnLUUnLCAnLS1lc2NhcGUnKToKICAgICAgICAgICAgb3B0aW9ucy5lc2NhcGUgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctRCcsICctLWRvY3N0cmluZ3MnKToKICAgICAgICAgICAgb3B0aW9ucy5kb2NzdHJpbmdzID0gMQogICAgICAgIGVsaWYgb3B0IGluICgnLWsnLCAnLS1rZXl3b3JkJyk6CiAgICAgICAgICAgIG9wdGlvbnMua2V5d29yZHMuYXBwZW5kKGFyZykKICAgICAgICBlbGlmIG9wdCBpbiAoJy1LJywgJy0tbm8tZGVmYXVsdC1rZXl3b3JkcycpOgogICAgICAgICAgICBkZWZhdWx0X2tleXdvcmRzID0gW10KICAgICAgICBlbGlmIG9wdCBpbiAoJy1uJywgJy0tYWRkLWxvY2F0aW9uJyk6CiAgICAgICAgICAgIG9wdGlvbnMud3JpdGVsb2NhdGlvbnMgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctLW5vLWxvY2F0aW9uJywpOgogICAgICAgICAgICBvcHRpb25zLndyaXRlbG9jYXRpb25zID0gMAogICAgICAgIGVsaWYgb3B0IGluICgnLVMnLCAnLS1zdHlsZScpOgogICAgICAgICAgICBvcHRpb25zLmxvY2F0aW9uc3R5bGUgPSBsb2NhdGlvbnMuZ2V0KGFyZy5sb3dlcigpKQogICAgICAgICAgICBpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgaXMgTm9uZToKICAgICAgICAgICAgICAgIHVzYWdlKDEsIF8oJ0ludmFsaWQgdmFsdWUgZm9yIC0tc3R5bGU6ICVzJykgJSBhcmcpCiAgICAgICAgZWxpZiBvcHQgaW4gKCctbycsICctLW91dHB1dCcpOgogICAgICAgICAgICBvcHRpb25zLm91dGZpbGUgPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy1wJywgJy0tb3V0cHV0LWRpcicpOgogICAgICAgICAgICBvcHRpb25zLm91dHBhdGggPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy12JywgJy0tdmVyYm9zZScpOgogICAgICAgICAgICBvcHRpb25zLnZlcmJvc2UgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctVicsICctLXZlcnNpb24nKToKICAgICAgICAgICAgcHJpbnQgXygncHlnZXR0ZXh0LnB5ICh4Z2V0dGV4dCBmb3IgUHl0aG9uKSAlcycpICUgX192ZXJzaW9uX18KICAgICAgICAgICAgc3lzLmV4aXQoMCkKICAgICAgICBlbGlmIG9wdCBpbiAoJy13JywgJy0td2lkdGgnKToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgb3B0aW9ucy53aWR0aCA9IGludChhcmcpCiAgICAgICAgICAgIGV4Y2VwdCBWYWx1ZUVycm9yOgogICAgICAgICAgICAgICAgdXNhZ2UoMSwgXygnLS13aWR0aCBhcmd1bWVudCBtdXN0IGJlIGFuIGludGVnZXI6ICVzJykgJSBhcmcpCiAgICAgICAgZWxpZiBvcHQgaW4gKCcteCcsICctLWV4Y2x1ZGUtZmlsZScpOgogICAgICAgICAgICBvcHRpb25zLmV4Y2x1ZGVmaWxlbmFtZSA9IGFyZwogICAgICAgIGVsaWYgb3B0IGluICgnLVgnLCAnLS1uby1kb2NzdHJpbmdzJyk6CiAgICAgICAgICAgIGZwID0gb3BlbihhcmcpCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHdoaWxlIDE6CiAgICAgICAgICAgICAgICAgICAgbGluZSA9IGZwLnJlYWRsaW5lKCkKICAgICAgICAgICAgICAgICAgICBpZiBub3QgbGluZToKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm5vZG9jc3RyaW5nc1tsaW5lWzotMV1dID0gMQogICAgICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICAgICAgZnAuY2xvc2UoKQoKICAgICMgY2FsY3VsYXRlIGVzY2FwZXMKICAgIG1ha2VfZXNjYXBlcyhvcHRpb25zLmVzY2FwZSkKCiAgICAjIGNhbGN1bGF0ZSBhbGwga2V5d29yZHMKICAgIG9wdGlvbnMua2V5d29yZHMuZXh0ZW5kKGRlZmF1bHRfa2V5d29yZHMpCgogICAgIyBpbml0aWFsaXplIGxpc3Qgb2Ygc3RyaW5ncyB0byBleGNsdWRlCiAgICBpZiBvcHRpb25zLmV4Y2x1ZGVmaWxlbmFtZToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZwID0gb3BlbihvcHRpb25zLmV4Y2x1ZGVmaWxlbmFtZSkKICAgICAgICAgICAgb3B0aW9ucy50b2V4Y2x1ZGUgPSBmcC5yZWFkbGluZXMoKQogICAgICAgICAgICBmcC5jbG9zZSgpCiAgICAgICAgZXhjZXB0IElPRXJyb3I6CiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIF8oCiAgICAgICAgICAgICAgICAiQ2FuJ3QgcmVhZCAtLWV4Y2x1ZGUtZmlsZTogJXMiKSAlIG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lCiAgICAgICAgICAgIHN5cy5leGl0KDEpCiAgICBlbHNlOgogICAgICAgIG9wdGlvbnMudG9leGNsdWRlID0gW10KCiAgICAjIHJlc29sdmUgYXJncyB0byBtb2R1bGUgbGlzdHMKICAgIGV4cGFuZGVkID0gW10KICAgIGZvciBhcmcgaW4gYXJnczoKICAgICAgICBpZiBhcmcgPT0gJy0nOgogICAgICAgICAgICBleHBhbmRlZC5hcHBlbmQoYXJnKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGV4cGFuZGVkLmV4dGVuZChnZXRGaWxlc0Zvck5hbWUoYXJnKSkKICAgIGFyZ3MgPSBleHBhbmRlZAoKICAgICMgc2x1cnAgdGhyb3VnaCBhbGwgdGhlIGZpbGVzCiAgICBlYXRlciA9IFRva2VuRWF0ZXIob3B0aW9ucykKICAgIGZvciBmaWxlbmFtZSBpbiBhcmdzOgogICAgICAgIGlmIGZpbGVuYW1lID09ICctJzoKICAgICAgICAgICAgaWYgb3B0aW9ucy52ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQgXygnUmVhZGluZyBzdGFuZGFyZCBpbnB1dCcpCiAgICAgICAgICAgIGZwID0gc3lzLnN0ZGluCiAgICAgICAgICAgIGNsb3NlcCA9IDAKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiBvcHRpb25zLnZlcmJvc2U6CiAgICAgICAgICAgICAgICBwcmludCBfKCdXb3JraW5nIG9uICVzJykgJSBmaWxlbmFtZQogICAgICAgICAgICBmcCA9IG9wZW4oZmlsZW5hbWUpCiAgICAgICAgICAgIGNsb3NlcCA9IDEKICAgICAgICB0cnk6CiAgICAgICAgICAgIGVhdGVyLnNldF9maWxlbmFtZShmaWxlbmFtZSkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdG9rZW5pemUudG9rZW5pemUoZnAucmVhZGxpbmUsIGVhdGVyKQogICAgICAgICAgICBleGNlcHQgdG9rZW5pemUuVG9rZW5FcnJvciwgZToKICAgICAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsICclczogJXMsIGxpbmUgJWQsIGNvbHVtbiAlZCcgJSAoCiAgICAgICAgICAgICAgICAgICAgZVswXSwgZmlsZW5hbWUsIGVbMV1bMF0sIGVbMV1bMV0pCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgaWYgY2xvc2VwOgogICAgICAgICAgICAgICAgZnAuY2xvc2UoKQoKICAgICMgd3JpdGUgdGhlIG91dHB1dAogICAgaWYgb3B0aW9ucy5vdXRmaWxlID09ICctJzoKICAgICAgICBmcCA9IHN5cy5zdGRvdXQKICAgICAgICBjbG9zZXAgPSAwCiAgICBlbHNlOgogICAgICAgIGlmIG9wdGlvbnMub3V0cGF0aDoKICAgICAgICAgICAgb3B0aW9ucy5vdXRmaWxlID0gb3MucGF0aC5qb2luKG9wdGlvbnMub3V0cGF0aCwgb3B0aW9ucy5vdXRmaWxlKQogICAgICAgIGZwID0gb3BlbihvcHRpb25zLm91dGZpbGUsICd3JykKICAgICAgICBjbG9zZXAgPSAxCiAgICB0cnk6CiAgICAgICAgZWF0ZXIud3JpdGUoZnApCiAgICBmaW5hbGx5OgogICAgICAgIGlmIGNsb3NlcDoKICAgICAgICAgICAgZnAuY2xvc2UoKQoKDAppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbWFpbigpCiAgICAjIHNvbWUgbW9yZSB0ZXN0IHN0cmluZ3MKICAgIF8odSdhIHVuaWNvZGUgc3RyaW5nJykKICAgICMgdGhpcyBvbmUgY3JlYXRlcyBhIHdhcm5pbmcKICAgIF8oJyoqKiBTZWVuIHVuZXhwZWN0ZWQgdG9rZW4gIiUodG9rZW4pcyInKSAlIHsndG9rZW4nOiAndGVzdCd9CiAgICBfKCdtb3JlJyAndGhhbicgJ29uZScgJ3N0cmluZycpCg==