IyEgL3Vzci9iaW4vZW52IHB5dGhvbjMKIyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQojIE9yaWdpbmFsbHkgd3JpdHRlbiBieSBCYXJyeSBXYXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+CiMKIyBNaW5pbWFsbHkgcGF0Y2hlZCB0byBtYWtlIGl0IGV2ZW4gbW9yZSB4Z2V0dGV4dCBjb21wYXRpYmxlCiMgYnkgUGV0ZXIgRnVuayA8cGZAYXJ0Y29tLWdtYmguZGU+CiMKIyAyMDAyLTExLTIyIEr8cmdlbiBIZXJtYW5uIDxqaEB3ZWIuZGU+CiMgQWRkZWQgY2hlY2tzIHRoYXQgXygpIG9ubHkgY29udGFpbnMgc3RyaW5nIGxpdGVyYWxzLCBhbmQKIyBjb21tYW5kIGxpbmUgYXJncyBhcmUgcmVzb2x2ZWQgdG8gbW9kdWxlIGxpc3RzLCBpLmUuIHlvdQojIGNhbiBub3cgcGFzcyBhIGZpbGVuYW1lLCBhIG1vZHVsZSBvciBwYWNrYWdlIG5hbWUsIG9yIGEKIyBkaXJlY3RvcnkgKGluY2x1ZGluZyBnbG9iYmluZyBjaGFycywgaW1wb3J0YW50IGZvciBXaW4zMikuCiMgTWFkZSBkb2NzdHJpbmcgZml0IGluIDgwIGNoYXJzIHdpZGUgZGlzcGxheXMgdXNpbmcgcHlkb2MuCiMKCiMgZm9yIHNlbGZ0ZXN0aW5nCnRyeToKICAgIGltcG9ydCBmaW50bAogICAgXyA9IGZpbnRsLmdldHRleHQKZXhjZXB0IEltcG9ydEVycm9yOgogICAgXyA9IGxhbWJkYSBzOiBzCgpfX2RvY19fID0gXygiIiJweWdldHRleHQgLS0gUHl0aG9uIGVxdWl2YWxlbnQgb2YgeGdldHRleHQoMSkKCk1hbnkgc3lzdGVtcyAoU29sYXJpcywgTGludXgsIEdudSkgcHJvdmlkZSBleHRlbnNpdmUgdG9vbHMgdGhhdCBlYXNlIHRoZQppbnRlcm5hdGlvbmFsaXphdGlvbiBvZiBDIHByb2dyYW1zLiBNb3N0IG9mIHRoZXNlIHRvb2xzIGFyZSBpbmRlcGVuZGVudCBvZgp0aGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgYW5kIGNhbiBiZSB1c2VkIGZyb20gd2l0aGluIFB5dGhvbiBwcm9ncmFtcy4KTWFydGluIHZvbiBMb2V3aXMnIHdvcmtbMV0gaGVscHMgY29uc2lkZXJhYmx5IGluIHRoaXMgcmVnYXJkLgoKVGhlcmUncyBvbmUgcHJvYmxlbSB0aG91Z2g7IHhnZXR0ZXh0IGlzIHRoZSBwcm9ncmFtIHRoYXQgc2NhbnMgc291cmNlIGNvZGUKbG9va2luZyBmb3IgbWVzc2FnZSBzdHJpbmdzLCBidXQgaXQgZ3Jva3Mgb25seSBDIChvciBDKyspLiBQeXRob24KaW50cm9kdWNlcyBhIGZldyB3cmlua2xlcywgc3VjaCBhcyBkdWFsIHF1b3RpbmcgY2hhcmFjdGVycywgdHJpcGxlIHF1b3RlZApzdHJpbmdzLCBhbmQgcmF3IHN0cmluZ3MuIHhnZXR0ZXh0IHVuZGVyc3RhbmRzIG5vbmUgb2YgdGhpcy4KCkVudGVyIHB5Z2V0dGV4dCwgd2hpY2ggdXNlcyBQeXRob24ncyBzdGFuZGFyZCB0b2tlbml6ZSBtb2R1bGUgdG8gc2NhbgpQeXRob24gc291cmNlIGNvZGUsIGdlbmVyYXRpbmcgLnBvdCBmaWxlcyBpZGVudGljYWwgdG8gd2hhdCBHTlUgeGdldHRleHRbMl0KZ2VuZXJhdGVzIGZvciBDIGFuZCBDKysgY29kZS4gRnJvbSB0aGVyZSwgdGhlIHN0YW5kYXJkIEdOVSB0b29scyBjYW4gYmUKdXNlZC4KCkEgd29yZCBhYm91dCBtYXJraW5nIFB5dGhvbiBzdHJpbmdzIGFzIGNhbmRpZGF0ZXMgZm9yIHRyYW5zbGF0aW9uLiBHTlUKeGdldHRleHQgcmVjb2duaXplcyB0aGUgZm9sbG93aW5nIGtleXdvcmRzOiBnZXR0ZXh0LCBkZ2V0dGV4dCwgZGNnZXR0ZXh0LAphbmQgZ2V0dGV4dF9ub29wLiBCdXQgdGhvc2UgY2FuIGJlIGEgbG90IG9mIHRleHQgdG8gaW5jbHVkZSBhbGwgb3ZlciB5b3VyCmNvZGUuIEMgYW5kIEMrKyBoYXZlIGEgdHJpY2s6IHRoZXkgdXNlIHRoZSBDIHByZXByb2Nlc3Nvci4gTW9zdAppbnRlcm5hdGlvbmFsaXplZCBDIHNvdXJjZSBpbmNsdWRlcyBhICNkZWZpbmUgZm9yIGdldHRleHQoKSB0byBfKCkgc28gdGhhdAp3aGF0IGhhcyB0byBiZSB3cml0dGVuIGluIHRoZSBzb3VyY2UgaXMgbXVjaCBsZXNzLiBUaHVzIHRoZXNlIGFyZSBib3RoCnRyYW5zbGF0YWJsZSBzdHJpbmdzOgoKICAgIGdldHRleHQoIlRyYW5zbGF0YWJsZSBTdHJpbmciKQogICAgXygiVHJhbnNsYXRhYmxlIFN0cmluZyIpCgpQeXRob24gb2YgY291cnNlIGhhcyBubyBwcmVwcm9jZXNzb3Igc28gdGhpcyBkb2Vzbid0IHdvcmsgc28gd2VsbC4gIFRodXMsCnB5Z2V0dGV4dCBzZWFyY2hlcyBvbmx5IGZvciBfKCkgYnkgZGVmYXVsdCwgYnV0IHNlZSB0aGUgLWsvLS1rZXl3b3JkIGZsYWcKYmVsb3cgZm9yIGhvdyB0byBhdWdtZW50IHRoaXMuCgogWzFdIGh0dHA6Ly93d3cucHl0aG9uLm9yZy93b3Jrc2hvcHMvMTk5Ny0xMC9wcm9jZWVkaW5ncy9sb2V3aXMuaHRtbAogWzJdIGh0dHA6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS9nZXR0ZXh0L2dldHRleHQuaHRtbAoKTk9URTogcHlnZXR0ZXh0IGF0dGVtcHRzIHRvIGJlIG9wdGlvbiBhbmQgZmVhdHVyZSBjb21wYXRpYmxlIHdpdGggR05VCnhnZXR0ZXh0IHdoZXJlIGV2ZXIgcG9zc2libGUuIEhvd2V2ZXIgc29tZSBvcHRpb25zIGFyZSBzdGlsbCBtaXNzaW5nIG9yIGFyZQpub3QgZnVsbHkgaW1wbGVtZW50ZWQuIEFsc28sIHhnZXR0ZXh0J3MgdXNlIG9mIGNvbW1hbmQgbGluZSBzd2l0Y2hlcyB3aXRoCm9wdGlvbiBhcmd1bWVudHMgaXMgYnJva2VuLCBhbmQgaW4gdGhlc2UgY2FzZXMsIHB5Z2V0dGV4dCBqdXN0IGRlZmluZXMKYWRkaXRpb25hbCBzd2l0Y2hlcy4KClVzYWdlOiBweWdldHRleHQgW29wdGlvbnNdIGlucHV0ZmlsZSAuLi4KCk9wdGlvbnM6CgogICAgLWEKICAgIC0tZXh0cmFjdC1hbGwKICAgICAgICBFeHRyYWN0IGFsbCBzdHJpbmdzLgoKICAgIC1kIG5hbWUKICAgIC0tZGVmYXVsdC1kb21haW49bmFtZQogICAgICAgIFJlbmFtZSB0aGUgZGVmYXVsdCBvdXRwdXQgZmlsZSBmcm9tIG1lc3NhZ2VzLnBvdCB0byBuYW1lLnBvdC4KCiAgICAtRQogICAgLS1lc2NhcGUKICAgICAgICBSZXBsYWNlIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIHdpdGggb2N0YWwgZXNjYXBlIHNlcXVlbmNlcy4KCiAgICAtRAogICAgLS1kb2NzdHJpbmdzCiAgICAgICAgRXh0cmFjdCBtb2R1bGUsIGNsYXNzLCBtZXRob2QsIGFuZCBmdW5jdGlvbiBkb2NzdHJpbmdzLiAgVGhlc2UgZG8KICAgICAgICBub3QgbmVlZCB0byBiZSB3cmFwcGVkIGluIF8oKSBtYXJrZXJzLCBhbmQgaW4gZmFjdCBjYW5ub3QgYmUgZm9yCiAgICAgICAgUHl0aG9uIHRvIGNvbnNpZGVyIHRoZW0gZG9jc3RyaW5ncy4gKFNlZSBhbHNvIHRoZSAtWCBvcHRpb24pLgoKICAgIC1oCiAgICAtLWhlbHAKICAgICAgICBQcmludCB0aGlzIGhlbHAgbWVzc2FnZSBhbmQgZXhpdC4KCiAgICAtayB3b3JkCiAgICAtLWtleXdvcmQ9d29yZAogICAgICAgIEtleXdvcmRzIHRvIGxvb2sgZm9yIGluIGFkZGl0aW9uIHRvIHRoZSBkZWZhdWx0IHNldCwgd2hpY2ggYXJlOgogICAgICAgICUoREVGQVVMVEtFWVdPUkRTKXMKCiAgICAgICAgWW91IGNhbiBoYXZlIG11bHRpcGxlIC1rIGZsYWdzIG9uIHRoZSBjb21tYW5kIGxpbmUuCgogICAgLUsKICAgIC0tbm8tZGVmYXVsdC1rZXl3b3JkcwogICAgICAgIERpc2FibGUgdGhlIGRlZmF1bHQgc2V0IG9mIGtleXdvcmRzIChzZWUgYWJvdmUpLiAgQW55IGtleXdvcmRzCiAgICAgICAgZXhwbGljaXRseSBhZGRlZCB3aXRoIHRoZSAtay8tLWtleXdvcmQgb3B0aW9uIGFyZSBzdGlsbCByZWNvZ25pemVkLgoKICAgIC0tbm8tbG9jYXRpb24KICAgICAgICBEbyBub3Qgd3JpdGUgZmlsZW5hbWUvbGluZW5vIGxvY2F0aW9uIGNvbW1lbnRzLgoKICAgIC1uCiAgICAtLWFkZC1sb2NhdGlvbgogICAgICAgIFdyaXRlIGZpbGVuYW1lL2xpbmVubyBsb2NhdGlvbiBjb21tZW50cyBpbmRpY2F0aW5nIHdoZXJlIGVhY2gKICAgICAgICBleHRyYWN0ZWQgc3RyaW5nIGlzIGZvdW5kIGluIHRoZSBzb3VyY2UuICBUaGVzZSBsaW5lcyBhcHBlYXIgYmVmb3JlCiAgICAgICAgZWFjaCBtc2dpZC4gIFRoZSBzdHlsZSBvZiBjb21tZW50cyBpcyBjb250cm9sbGVkIGJ5IHRoZSAtUy8tLXN0eWxlCiAgICAgICAgb3B0aW9uLiAgVGhpcyBpcyB0aGUgZGVmYXVsdC4KCiAgICAtbyBmaWxlbmFtZQogICAgLS1vdXRwdXQ9ZmlsZW5hbWUKICAgICAgICBSZW5hbWUgdGhlIGRlZmF1bHQgb3V0cHV0IGZpbGUgZnJvbSBtZXNzYWdlcy5wb3QgdG8gZmlsZW5hbWUuICBJZgogICAgICAgIGZpbGVuYW1lIGlzIGAtJyB0aGVuIHRoZSBvdXRwdXQgaXMgc2VudCB0byBzdGFuZGFyZCBvdXQuCgogICAgLXAgZGlyCiAgICAtLW91dHB1dC1kaXI9ZGlyCiAgICAgICAgT3V0cHV0IGZpbGVzIHdpbGwgYmUgcGxhY2VkIGluIGRpcmVjdG9yeSBkaXIuCgogICAgLVMgc3R5bGVuYW1lCiAgICAtLXN0eWxlIHN0eWxlbmFtZQogICAgICAgIFNwZWNpZnkgd2hpY2ggc3R5bGUgdG8gdXNlIGZvciBsb2NhdGlvbiBjb21tZW50cy4gIFR3byBzdHlsZXMgYXJlCiAgICAgICAgc3VwcG9ydGVkOgoKICAgICAgICBTb2xhcmlzICAjIEZpbGU6IGZpbGVuYW1lLCBsaW5lOiBsaW5lLW51bWJlcgogICAgICAgIEdOVSAgICAgICM6IGZpbGVuYW1lOmxpbmUKCiAgICAgICAgVGhlIHN0eWxlIG5hbWUgaXMgY2FzZSBpbnNlbnNpdGl2ZS4gIEdOVSBzdHlsZSBpcyB0aGUgZGVmYXVsdC4KCiAgICAtdgogICAgLS12ZXJib3NlCiAgICAgICAgUHJpbnQgdGhlIG5hbWVzIG9mIHRoZSBmaWxlcyBiZWluZyBwcm9jZXNzZWQuCgogICAgLVYKICAgIC0tdmVyc2lvbgogICAgICAgIFByaW50IHRoZSB2ZXJzaW9uIG9mIHB5Z2V0dGV4dCBhbmQgZXhpdC4KCiAgICAtdyBjb2x1bW5zCiAgICAtLXdpZHRoPWNvbHVtbnMKICAgICAgICBTZXQgd2lkdGggb2Ygb3V0cHV0IHRvIGNvbHVtbnMuCgogICAgLXggZmlsZW5hbWUKICAgIC0tZXhjbHVkZS1maWxlPWZpbGVuYW1lCiAgICAgICAgU3BlY2lmeSBhIGZpbGUgdGhhdCBjb250YWlucyBhIGxpc3Qgb2Ygc3RyaW5ncyB0aGF0IGFyZSBub3QgYmUKICAgICAgICBleHRyYWN0ZWQgZnJvbSB0aGUgaW5wdXQgZmlsZXMuICBFYWNoIHN0cmluZyB0byBiZSBleGNsdWRlZCBtdXN0CiAgICAgICAgYXBwZWFyIG9uIGEgbGluZSBieSBpdHNlbGYgaW4gdGhlIGZpbGUuCgogICAgLVggZmlsZW5hbWUKICAgIC0tbm8tZG9jc3RyaW5ncz1maWxlbmFtZQogICAgICAgIFNwZWNpZnkgYSBmaWxlIHRoYXQgY29udGFpbnMgYSBsaXN0IG9mIGZpbGVzIChvbmUgcGVyIGxpbmUpIHRoYXQKICAgICAgICBzaG91bGQgbm90IGhhdmUgdGhlaXIgZG9jc3RyaW5ncyBleHRyYWN0ZWQuICBUaGlzIGlzIG9ubHkgdXNlZnVsIGluCiAgICAgICAgY29uanVuY3Rpb24gd2l0aCB0aGUgLUQgb3B0aW9uIGFib3ZlLgoKSWYgYGlucHV0ZmlsZScgaXMgLSwgc3RhbmRhcmQgaW5wdXQgaXMgcmVhZC4KIiIiKQoKaW1wb3J0IG9zCmltcG9ydCBpbXBvcnRsaWIubWFjaGluZXJ5CmltcG9ydCBpbXBvcnRsaWIudXRpbAppbXBvcnQgc3lzCmltcG9ydCBnbG9iCmltcG9ydCB0aW1lCmltcG9ydCBnZXRvcHQKaW1wb3J0IHRva2VuCmltcG9ydCB0b2tlbml6ZQoKX192ZXJzaW9uX18gPSAnMS41JwoKZGVmYXVsdF9rZXl3b3JkcyA9IFsnXyddCkRFRkFVTFRLRVlXT1JEUyA9ICcsICcuam9pbihkZWZhdWx0X2tleXdvcmRzKQoKRU1QVFlTVFJJTkcgPSAnJwoKCgwKIyBUaGUgbm9ybWFsIHBvdC1maWxlIGhlYWRlci4gbXNnbWVyZ2UgYW5kIEVtYWNzJ3MgcG8tbW9kZSB3b3JrIGJldHRlciBpZiBpdCdzCiMgdGhlcmUuCnBvdF9oZWFkZXIgPSBfKCcnJ1wKIyBTT01FIERFU0NSSVBUSVZFIFRJVExFLgojIENvcHlyaWdodCAoQykgWUVBUiBPUkdBTklaQVRJT04KIyBGSVJTVCBBVVRIT1IgPEVNQUlMQEFERFJFU1M+LCBZRUFSLgojCm1zZ2lkICIiCm1zZ3N0ciAiIgoiUHJvamVjdC1JZC1WZXJzaW9uOiBQQUNLQUdFIFZFUlNJT05cXG4iCiJQT1QtQ3JlYXRpb24tRGF0ZTogJSh0aW1lKXNcXG4iCiJQTy1SZXZpc2lvbi1EYXRlOiBZRUFSLU1PLURBIEhPOk1JK1pPTkVcXG4iCiJMYXN0LVRyYW5zbGF0b3I6IEZVTEwgTkFNRSA8RU1BSUxAQUREUkVTUz5cXG4iCiJMYW5ndWFnZS1UZWFtOiBMQU5HVUFHRSA8TExAbGkub3JnPlxcbiIKIk1JTUUtVmVyc2lvbjogMS4wXFxuIgoiQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSUoY2hhcnNldClzXFxuIgoiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogJShlbmNvZGluZylzXFxuIgoiR2VuZXJhdGVkLUJ5OiBweWdldHRleHQucHkgJSh2ZXJzaW9uKXNcXG4iCgonJycpCgoMCmRlZiB1c2FnZShjb2RlLCBtc2c9JycpOgogICAgcHJpbnQoX19kb2NfXyAlIGdsb2JhbHMoKSwgZmlsZT1zeXMuc3RkZXJyKQogICAgaWYgbXNnOgogICAgICAgIHByaW50KG1zZywgZmlsZT1zeXMuc3RkZXJyKQogICAgc3lzLmV4aXQoY29kZSkKCgoMCmRlZiBtYWtlX2VzY2FwZXMocGFzc19ub25hc2NpaSk6CiAgICBnbG9iYWwgZXNjYXBlcywgZXNjYXBlCiAgICBpZiBwYXNzX25vbmFzY2lpOgogICAgICAgICMgQWxsb3cgbm9uLWFzY2lpIGNoYXJhY3RlcnMgdG8gcGFzcyB0aHJvdWdoIHNvIHRoYXQgZS5nLiAnbXNnaWQKICAgICAgICAjICJI9mhlIicgd291bGQgcmVzdWx0IG5vdCByZXN1bHQgaW4gJ21zZ2lkICJIXDM2NmhlIicuICBPdGhlcndpc2Ugd2UKICAgICAgICAjIGVzY2FwZSBhbnkgY2hhcmFjdGVyIG91dHNpZGUgdGhlIDMyLi4xMjYgcmFuZ2UuCiAgICAgICAgbW9kID0gMTI4CiAgICAgICAgZXNjYXBlID0gZXNjYXBlX2FzY2lpCiAgICBlbHNlOgogICAgICAgIG1vZCA9IDI1NgogICAgICAgIGVzY2FwZSA9IGVzY2FwZV9ub25hc2NpaQogICAgZXNjYXBlcyA9IFtyIlwlMDNvIiAlIGkgZm9yIGkgaW4gcmFuZ2UobW9kKV0KICAgIGZvciBpIGluIHJhbmdlKDMyLCAxMjcpOgogICAgICAgIGVzY2FwZXNbaV0gPSBjaHIoaSkKICAgIGVzY2FwZXNbb3JkKCdcXCcpXSA9IHInXFwnCiAgICBlc2NhcGVzW29yZCgnXHQnKV0gPSByJ1x0JwogICAgZXNjYXBlc1tvcmQoJ1xyJyldID0gcidccicKICAgIGVzY2FwZXNbb3JkKCdcbicpXSA9IHInXG4nCiAgICBlc2NhcGVzW29yZCgnXCInKV0gPSByJ1wiJwoKCmRlZiBlc2NhcGVfYXNjaWkocywgZW5jb2RpbmcpOgogICAgcmV0dXJuICcnLmpvaW4oZXNjYXBlc1tvcmQoYyldIGlmIG9yZChjKSA8IDEyOCBlbHNlIGMgZm9yIGMgaW4gcykKCmRlZiBlc2NhcGVfbm9uYXNjaWkocywgZW5jb2RpbmcpOgogICAgcmV0dXJuICcnLmpvaW4oZXNjYXBlc1tiXSBmb3IgYiBpbiBzLmVuY29kZShlbmNvZGluZykpCgoKZGVmIHNhZmVfZXZhbChzKToKICAgICMgdW53cmFwIHF1b3Rlcywgc2FmZWx5CiAgICByZXR1cm4gZXZhbChzLCB7J19fYnVpbHRpbnNfXyc6e319LCB7fSkKCgpkZWYgbm9ybWFsaXplKHMsIGVuY29kaW5nKToKICAgICMgVGhpcyBjb252ZXJ0cyB0aGUgdmFyaW91cyBQeXRob24gc3RyaW5nIHR5cGVzIGludG8gYSBmb3JtYXQgdGhhdCBpcwogICAgIyBhcHByb3ByaWF0ZSBmb3IgLnBvIGZpbGVzLCBuYW1lbHkgbXVjaCBjbG9zZXIgdG8gQyBzdHlsZS4KICAgIGxpbmVzID0gcy5zcGxpdCgnXG4nKQogICAgaWYgbGVuKGxpbmVzKSA9PSAxOgogICAgICAgIHMgPSAnIicgKyBlc2NhcGUocywgZW5jb2RpbmcpICsgJyInCiAgICBlbHNlOgogICAgICAgIGlmIG5vdCBsaW5lc1stMV06CiAgICAgICAgICAgIGRlbCBsaW5lc1stMV0KICAgICAgICAgICAgbGluZXNbLTFdID0gbGluZXNbLTFdICsgJ1xuJwogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihsaW5lcykpOgogICAgICAgICAgICBsaW5lc1tpXSA9IGVzY2FwZShsaW5lc1tpXSwgZW5jb2RpbmcpCiAgICAgICAgbGluZXRlcm0gPSAnXFxuIlxuIicKICAgICAgICBzID0gJyIiXG4iJyArIGxpbmV0ZXJtLmpvaW4obGluZXMpICsgJyInCiAgICByZXR1cm4gcwoKDApkZWYgY29udGFpbnNBbnkoc3RyLCBzZXQpOgogICAgIiIiQ2hlY2sgd2hldGhlciAnc3RyJyBjb250YWlucyBBTlkgb2YgdGhlIGNoYXJzIGluICdzZXQnIiIiCiAgICByZXR1cm4gMSBpbiBbYyBpbiBzdHIgZm9yIGMgaW4gc2V0XQoKCmRlZiBfdmlzaXRfcHlmaWxlcyhsaXN0LCBkaXJuYW1lLCBuYW1lcyk6CiAgICAiIiJIZWxwZXIgZm9yIGdldEZpbGVzRm9yTmFtZSgpLiIiIgogICAgIyBnZXQgZXh0ZW5zaW9uIGZvciBweXRob24gc291cmNlIGZpbGVzCiAgICBpZiAnX3B5X2V4dCcgbm90IGluIGdsb2JhbHMoKToKICAgICAgICBnbG9iYWwgX3B5X2V4dAogICAgICAgIF9weV9leHQgPSBpbXBvcnRsaWIubWFjaGluZXJ5LlNPVVJDRV9TVUZGSVhFU1swXQoKICAgICMgZG9uJ3QgcmVjdXJzZSBpbnRvIENWUyBkaXJlY3RvcmllcwogICAgaWYgJ0NWUycgaW4gbmFtZXM6CiAgICAgICAgbmFtZXMucmVtb3ZlKCdDVlMnKQoKICAgICMgYWRkIGFsbCAqLnB5IGZpbGVzIHRvIGxpc3QKICAgIGxpc3QuZXh0ZW5kKAogICAgICAgIFtvcy5wYXRoLmpvaW4oZGlybmFtZSwgZmlsZSkgZm9yIGZpbGUgaW4gbmFtZXMKICAgICAgICAgaWYgb3MucGF0aC5zcGxpdGV4dChmaWxlKVsxXSA9PSBfcHlfZXh0XQogICAgICAgICkKCgpkZWYgZ2V0RmlsZXNGb3JOYW1lKG5hbWUpOgogICAgIiIiR2V0IGEgbGlzdCBvZiBtb2R1bGUgZmlsZXMgZm9yIGEgZmlsZW5hbWUsIGEgbW9kdWxlIG9yIHBhY2thZ2UgbmFtZSwKICAgIG9yIGEgZGlyZWN0b3J5LgogICAgIiIiCiAgICBpZiBub3Qgb3MucGF0aC5leGlzdHMobmFtZSk6CiAgICAgICAgIyBjaGVjayBmb3IgZ2xvYiBjaGFycwogICAgICAgIGlmIGNvbnRhaW5zQW55KG5hbWUsICIqP1tdIik6CiAgICAgICAgICAgIGZpbGVzID0gZ2xvYi5nbG9iKG5hbWUpCiAgICAgICAgICAgIGxpc3QgPSBbXQogICAgICAgICAgICBmb3IgZmlsZSBpbiBmaWxlczoKICAgICAgICAgICAgICAgIGxpc3QuZXh0ZW5kKGdldEZpbGVzRm9yTmFtZShmaWxlKSkKICAgICAgICAgICAgcmV0dXJuIGxpc3QKCiAgICAgICAgIyB0cnkgdG8gZmluZCBtb2R1bGUgb3IgcGFja2FnZQogICAgICAgIHRyeToKICAgICAgICAgICAgc3BlYyA9IGltcG9ydGxpYi51dGlsLmZpbmRfc3BlYyhuYW1lKQogICAgICAgICAgICBuYW1lID0gc3BlYy5vcmlnaW4KICAgICAgICBleGNlcHQgSW1wb3J0RXJyb3I6CiAgICAgICAgICAgIG5hbWUgPSBOb25lCiAgICAgICAgaWYgbm90IG5hbWU6CiAgICAgICAgICAgIHJldHVybiBbXQoKICAgIGlmIG9zLnBhdGguaXNkaXIobmFtZSk6CiAgICAgICAgIyBmaW5kIGFsbCBweXRob24gZmlsZXMgaW4gZGlyZWN0b3J5CiAgICAgICAgbGlzdCA9IFtdCiAgICAgICAgb3Mud2FsayhuYW1lLCBfdmlzaXRfcHlmaWxlcywgbGlzdCkKICAgICAgICByZXR1cm4gbGlzdAogICAgZWxpZiBvcy5wYXRoLmV4aXN0cyhuYW1lKToKICAgICAgICAjIGEgc2luZ2xlIGZpbGUKICAgICAgICByZXR1cm4gW25hbWVdCgogICAgcmV0dXJuIFtdCgoMCmNsYXNzIFRva2VuRWF0ZXI6CiAgICBkZWYgX19pbml0X18oc2VsZiwgb3B0aW9ucyk6CiAgICAgICAgc2VsZi5fX29wdGlvbnMgPSBvcHRpb25zCiAgICAgICAgc2VsZi5fX21lc3NhZ2VzID0ge30KICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwogICAgICAgIHNlbGYuX19kYXRhID0gW10KICAgICAgICBzZWxmLl9fbGluZW5vID0gLTEKICAgICAgICBzZWxmLl9fZnJlc2htb2R1bGUgPSAxCiAgICAgICAgc2VsZi5fX2N1cmZpbGUgPSBOb25lCgogICAgZGVmIF9fY2FsbF9fKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBzdHVwLCBldHVwLCBsaW5lKToKICAgICAgICAjIGRpc3BhdGNoCiMjICAgICAgICBpbXBvcnQgdG9rZW4KIyMgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsICd0dHlwZTonLCB0b2tlbi50b2tfbmFtZVt0dHlwZV0sIFwKIyMgICAgICAgICAgICAgICd0c3RyaW5nOicsIHRzdHJpbmcKICAgICAgICBzZWxmLl9fc3RhdGUodHR5cGUsIHRzdHJpbmcsIHN0dXBbMF0pCgogICAgZGVmIF9fd2FpdGluZyhzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICBvcHRzID0gc2VsZi5fX29wdGlvbnMKICAgICAgICAjIERvIGRvY3N0cmluZyBleHRyYWN0aW9ucywgaWYgZW5hYmxlZAogICAgICAgIGlmIG9wdHMuZG9jc3RyaW5ncyBhbmQgbm90IG9wdHMubm9kb2NzdHJpbmdzLmdldChzZWxmLl9fY3VyZmlsZSk6CiAgICAgICAgICAgICMgbW9kdWxlIGRvY3N0cmluZz8KICAgICAgICAgICAgaWYgc2VsZi5fX2ZyZXNobW9kdWxlOgogICAgICAgICAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuU1RSSU5HOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX19hZGRlbnRyeShzYWZlX2V2YWwodHN0cmluZyksIGxpbmVubywgaXNkb2NzdHJpbmc9MSkKICAgICAgICAgICAgICAgICAgICBzZWxmLl9fZnJlc2htb2R1bGUgPSAwCiAgICAgICAgICAgICAgICBlbGlmIHR0eXBlIG5vdCBpbiAodG9rZW5pemUuQ09NTUVOVCwgdG9rZW5pemUuTkwpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDAKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAjIGNsYXNzIGRvY3N0cmluZz8KICAgICAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuTkFNRSBhbmQgdHN0cmluZyBpbiAoJ2NsYXNzJywgJ2RlZicpOgogICAgICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3N1aXRlc2VlbgogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuTkFNRSBhbmQgdHN0cmluZyBpbiBvcHRzLmtleXdvcmRzOgogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fa2V5d29yZHNlZW4KCiAgICBkZWYgX19zdWl0ZXNlZW4oc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6CiAgICAgICAgIyBpZ25vcmUgYW55dGhpbmcgdW50aWwgd2Ugc2VlIHRoZSBjb2xvbgogICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLk9QIGFuZCB0c3RyaW5nID09ICc6JzoKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3N1aXRlZG9jc3RyaW5nCgogICAgZGVmIF9fc3VpdGVkb2NzdHJpbmcoc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6CiAgICAgICAgIyBpZ25vcmUgYW55IGludGVydmVuaW5nIG5vaXNlCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuU1RSSU5HOgogICAgICAgICAgICBzZWxmLl9fYWRkZW50cnkoc2FmZV9ldmFsKHRzdHJpbmcpLCBsaW5lbm8sIGlzZG9jc3RyaW5nPTEpCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCiAgICAgICAgZWxpZiB0dHlwZSBub3QgaW4gKHRva2VuaXplLk5FV0xJTkUsIHRva2VuaXplLklOREVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW5pemUuQ09NTUVOVCk6CiAgICAgICAgICAgICMgdGhlcmUgd2FzIG5vIGNsYXNzIGRvY3N0cmluZwogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwoKICAgIGRlZiBfX2tleXdvcmRzZWVuKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOgogICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLk9QIGFuZCB0c3RyaW5nID09ICcoJzoKICAgICAgICAgICAgc2VsZi5fX2RhdGEgPSBbXQogICAgICAgICAgICBzZWxmLl9fbGluZW5vID0gbGluZW5vCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX19vcGVuc2VlbgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCgogICAgZGVmIF9fb3BlbnNlZW4oc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6CiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuT1AgYW5kIHRzdHJpbmcgPT0gJyknOgogICAgICAgICAgICAjIFdlJ3ZlIHNlZW4gdGhlIGxhc3Qgb2YgdGhlIHRyYW5zbGF0YWJsZSBzdHJpbmdzLiAgUmVjb3JkIHRoZQogICAgICAgICAgICAjIGxpbmUgbnVtYmVyIG9mIHRoZSBmaXJzdCBsaW5lIG9mIHRoZSBzdHJpbmdzIGFuZCB1cGRhdGUgdGhlIGxpc3QKICAgICAgICAgICAgIyBvZiBtZXNzYWdlcyBzZWVuLiAgUmVzZXQgc3RhdGUgZm9yIHRoZSBuZXh0IGJhdGNoLiAgSWYgdGhlcmUKICAgICAgICAgICAgIyB3ZXJlIG5vIHN0cmluZ3MgaW5zaWRlIF8oKSwgdGhlbiBqdXN0IGlnbm9yZSB0aGlzIGVudHJ5LgogICAgICAgICAgICBpZiBzZWxmLl9fZGF0YToKICAgICAgICAgICAgICAgIHNlbGYuX19hZGRlbnRyeShFTVBUWVNUUklORy5qb2luKHNlbGYuX19kYXRhKSkKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKICAgICAgICBlbGlmIHR0eXBlID09IHRva2VuaXplLlNUUklORzoKICAgICAgICAgICAgc2VsZi5fX2RhdGEuYXBwZW5kKHNhZmVfZXZhbCh0c3RyaW5nKSkKICAgICAgICBlbGlmIHR0eXBlIG5vdCBpbiBbdG9rZW5pemUuQ09NTUVOVCwgdG9rZW4uSU5ERU5ULCB0b2tlbi5ERURFTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuLk5FV0xJTkUsIHRva2VuaXplLk5MXToKICAgICAgICAgICAgIyB3YXJuIGlmIHdlIHNlZSBhbnl0aGluZyBlbHNlIHRoYW4gU1RSSU5HIG9yIHdoaXRlc3BhY2UKICAgICAgICAgICAgcHJpbnQoXygKICAgICAgICAgICAgICAgICcqKiogJShmaWxlKXM6JShsaW5lbm8pczogU2VlbiB1bmV4cGVjdGVkIHRva2VuICIlKHRva2VuKXMiJwogICAgICAgICAgICAgICAgKSAlIHsKICAgICAgICAgICAgICAgICd0b2tlbic6IHRzdHJpbmcsCiAgICAgICAgICAgICAgICAnZmlsZSc6IHNlbGYuX19jdXJmaWxlLAogICAgICAgICAgICAgICAgJ2xpbmVubyc6IHNlbGYuX19saW5lbm8KICAgICAgICAgICAgICAgIH0sIGZpbGU9c3lzLnN0ZGVycikKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKCiAgICBkZWYgX19hZGRlbnRyeShzZWxmLCBtc2csIGxpbmVubz1Ob25lLCBpc2RvY3N0cmluZz0wKToKICAgICAgICBpZiBsaW5lbm8gaXMgTm9uZToKICAgICAgICAgICAgbGluZW5vID0gc2VsZi5fX2xpbmVubwogICAgICAgIGlmIG5vdCBtc2cgaW4gc2VsZi5fX29wdGlvbnMudG9leGNsdWRlOgogICAgICAgICAgICBlbnRyeSA9IChzZWxmLl9fY3VyZmlsZSwgbGluZW5vKQogICAgICAgICAgICBzZWxmLl9fbWVzc2FnZXMuc2V0ZGVmYXVsdChtc2csIHt9KVtlbnRyeV0gPSBpc2RvY3N0cmluZwoKICAgIGRlZiBzZXRfZmlsZW5hbWUoc2VsZiwgZmlsZW5hbWUpOgogICAgICAgIHNlbGYuX19jdXJmaWxlID0gZmlsZW5hbWUKICAgICAgICBzZWxmLl9fZnJlc2htb2R1bGUgPSAxCgogICAgZGVmIHdyaXRlKHNlbGYsIGZwKToKICAgICAgICBvcHRpb25zID0gc2VsZi5fX29wdGlvbnMKICAgICAgICB0aW1lc3RhbXAgPSB0aW1lLnN0cmZ0aW1lKCclWS0lbS0lZCAlSDolTSV6JykKICAgICAgICBlbmNvZGluZyA9IGZwLmVuY29kaW5nIGlmIGZwLmVuY29kaW5nIGVsc2UgJ1VURi04JwogICAgICAgIHByaW50KHBvdF9oZWFkZXIgJSB7J3RpbWUnOiB0aW1lc3RhbXAsICd2ZXJzaW9uJzogX192ZXJzaW9uX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY2hhcnNldCc6IGVuY29kaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2VuY29kaW5nJzogJzhiaXQnfSwgZmlsZT1mcCkKICAgICAgICAjIFNvcnQgdGhlIGVudHJpZXMuICBGaXJzdCBzb3J0IGVhY2ggcGFydGljdWxhciBlbnRyeSdzIGtleXMsIHRoZW4KICAgICAgICAjIHNvcnQgYWxsIHRoZSBlbnRyaWVzIGJ5IHRoZWlyIGZpcnN0IGl0ZW0uCiAgICAgICAgcmV2ZXJzZSA9IHt9CiAgICAgICAgZm9yIGssIHYgaW4gc2VsZi5fX21lc3NhZ2VzLml0ZW1zKCk6CiAgICAgICAgICAgIGtleXMgPSBzb3J0ZWQodi5rZXlzKCkpCiAgICAgICAgICAgIHJldmVyc2Uuc2V0ZGVmYXVsdCh0dXBsZShrZXlzKSwgW10pLmFwcGVuZCgoaywgdikpCiAgICAgICAgcmtleXMgPSBzb3J0ZWQocmV2ZXJzZS5rZXlzKCkpCiAgICAgICAgZm9yIHJrZXkgaW4gcmtleXM6CiAgICAgICAgICAgIHJlbnRyaWVzID0gcmV2ZXJzZVtya2V5XQogICAgICAgICAgICByZW50cmllcy5zb3J0KCkKICAgICAgICAgICAgZm9yIGssIHYgaW4gcmVudHJpZXM6CiAgICAgICAgICAgICAgICAjIElmIHRoZSBlbnRyeSB3YXMgZ2xlYW5lZCBvdXQgb2YgYSBkb2NzdHJpbmcsIHRoZW4gYWRkIGEKICAgICAgICAgICAgICAgICMgY29tbWVudCBzdGF0aW5nIHNvLiAgVGhpcyBpcyB0byBhaWQgdHJhbnNsYXRvcnMgd2hvIG1heSB3aXNoCiAgICAgICAgICAgICAgICAjIHRvIHNraXAgdHJhbnNsYXRpbmcgc29tZSB1bmltcG9ydGFudCBkb2NzdHJpbmdzLgogICAgICAgICAgICAgICAgaXNkb2NzdHJpbmcgPSBhbnkodi52YWx1ZXMoKSkKICAgICAgICAgICAgICAgICMgayBpcyB0aGUgbWVzc2FnZSBzdHJpbmcsIHYgaXMgYSBkaWN0aW9uYXJ5LXNldCBvZiAoZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAjIGxpbmVubykgdHVwbGVzLiAgV2Ugd2FudCB0byBzb3J0IHRoZSBlbnRyaWVzIGluIHYgZmlyc3QgYnkKICAgICAgICAgICAgICAgICMgZmlsZSBuYW1lIGFuZCB0aGVuIGJ5IGxpbmUgbnVtYmVyLgogICAgICAgICAgICAgICAgdiA9IHNvcnRlZCh2LmtleXMoKSkKICAgICAgICAgICAgICAgIGlmIG5vdCBvcHRpb25zLndyaXRlbG9jYXRpb25zOgogICAgICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgICAgICMgbG9jYXRpb24gY29tbWVudHMgYXJlIGRpZmZlcmVudCBiL3cgU29sYXJpcyBhbmQgR05VOgogICAgICAgICAgICAgICAgZWxpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgPT0gb3B0aW9ucy5TT0xBUklTOgogICAgICAgICAgICAgICAgICAgIGZvciBmaWxlbmFtZSwgbGluZW5vIGluIHY6CiAgICAgICAgICAgICAgICAgICAgICAgIGQgPSB7J2ZpbGVuYW1lJzogZmlsZW5hbWUsICdsaW5lbm8nOiBsaW5lbm99CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KF8oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIyBGaWxlOiAlKGZpbGVuYW1lKXMsIGxpbmU6ICUobGluZW5vKWQnKSAlIGQsIGZpbGU9ZnApCiAgICAgICAgICAgICAgICBlbGlmIG9wdGlvbnMubG9jYXRpb25zdHlsZSA9PSBvcHRpb25zLkdOVToKICAgICAgICAgICAgICAgICAgICAjIGZpdCBhcyBtYW55IGxvY2F0aW9ucyBvbiBvbmUgbGluZSwgYXMgbG9uZyBhcyB0aGUKICAgICAgICAgICAgICAgICAgICAjIHJlc3VsdGluZyBsaW5lIGxlbmd0aCBkb2Vzbid0IGV4Y2VlZCAnb3B0aW9ucy53aWR0aCcKICAgICAgICAgICAgICAgICAgICBsb2NsaW5lID0gJyM6JwogICAgICAgICAgICAgICAgICAgIGZvciBmaWxlbmFtZSwgbGluZW5vIGluIHY6CiAgICAgICAgICAgICAgICAgICAgICAgIGQgPSB7J2ZpbGVuYW1lJzogZmlsZW5hbWUsICdsaW5lbm8nOiBsaW5lbm99CiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBfKCcgJShmaWxlbmFtZSlzOiUobGluZW5vKWQnKSAlIGQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKGxvY2xpbmUpICsgbGVuKHMpIDw9IG9wdGlvbnMud2lkdGg6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NsaW5lID0gbG9jbGluZSArIHMKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KGxvY2xpbmUsIGZpbGU9ZnApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NsaW5lID0gIiM6IiArIHMKICAgICAgICAgICAgICAgICAgICBpZiBsZW4obG9jbGluZSkgPiAyOgogICAgICAgICAgICAgICAgICAgICAgICBwcmludChsb2NsaW5lLCBmaWxlPWZwKQogICAgICAgICAgICAgICAgaWYgaXNkb2NzdHJpbmc6CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoJyMsIGRvY3N0cmluZycsIGZpbGU9ZnApCiAgICAgICAgICAgICAgICBwcmludCgnbXNnaWQnLCBub3JtYWxpemUoaywgZW5jb2RpbmcpLCBmaWxlPWZwKQogICAgICAgICAgICAgICAgcHJpbnQoJ21zZ3N0ciAiIlxuJywgZmlsZT1mcCkKCgoMCmRlZiBtYWluKCk6CiAgICBnbG9iYWwgZGVmYXVsdF9rZXl3b3JkcwogICAgdHJ5OgogICAgICAgIG9wdHMsIGFyZ3MgPSBnZXRvcHQuZ2V0b3B0KAogICAgICAgICAgICBzeXMuYXJndlsxOl0sCiAgICAgICAgICAgICdhZDpERWhrOktubzpwOlM6VnZ3Ong6WDonLAogICAgICAgICAgICBbJ2V4dHJhY3QtYWxsJywgJ2RlZmF1bHQtZG9tYWluPScsICdlc2NhcGUnLCAnaGVscCcsCiAgICAgICAgICAgICAna2V5d29yZD0nLCAnbm8tZGVmYXVsdC1rZXl3b3JkcycsCiAgICAgICAgICAgICAnYWRkLWxvY2F0aW9uJywgJ25vLWxvY2F0aW9uJywgJ291dHB1dD0nLCAnb3V0cHV0LWRpcj0nLAogICAgICAgICAgICAgJ3N0eWxlPScsICd2ZXJib3NlJywgJ3ZlcnNpb24nLCAnd2lkdGg9JywgJ2V4Y2x1ZGUtZmlsZT0nLAogICAgICAgICAgICAgJ2RvY3N0cmluZ3MnLCAnbm8tZG9jc3RyaW5ncycsCiAgICAgICAgICAgICBdKQogICAgZXhjZXB0IGdldG9wdC5lcnJvciBhcyBtc2c6CiAgICAgICAgdXNhZ2UoMSwgbXNnKQoKICAgICMgZm9yIGhvbGRpbmcgb3B0aW9uIHZhbHVlcwogICAgY2xhc3MgT3B0aW9uczoKICAgICAgICAjIGNvbnN0YW50cwogICAgICAgIEdOVSA9IDEKICAgICAgICBTT0xBUklTID0gMgogICAgICAgICMgZGVmYXVsdHMKICAgICAgICBleHRyYWN0YWxsID0gMCAjIEZJWE1FOiBjdXJyZW50bHkgdGhpcyBvcHRpb24gaGFzIG5vIGVmZmVjdCBhdCBhbGwuCiAgICAgICAgZXNjYXBlID0gMAogICAgICAgIGtleXdvcmRzID0gW10KICAgICAgICBvdXRwYXRoID0gJycKICAgICAgICBvdXRmaWxlID0gJ21lc3NhZ2VzLnBvdCcKICAgICAgICB3cml0ZWxvY2F0aW9ucyA9IDEKICAgICAgICBsb2NhdGlvbnN0eWxlID0gR05VCiAgICAgICAgdmVyYm9zZSA9IDAKICAgICAgICB3aWR0aCA9IDc4CiAgICAgICAgZXhjbHVkZWZpbGVuYW1lID0gJycKICAgICAgICBkb2NzdHJpbmdzID0gMAogICAgICAgIG5vZG9jc3RyaW5ncyA9IHt9CgogICAgb3B0aW9ucyA9IE9wdGlvbnMoKQogICAgbG9jYXRpb25zID0geydnbnUnIDogb3B0aW9ucy5HTlUsCiAgICAgICAgICAgICAgICAgJ3NvbGFyaXMnIDogb3B0aW9ucy5TT0xBUklTLAogICAgICAgICAgICAgICAgIH0KCiAgICAjIHBhcnNlIG9wdGlvbnMKICAgIGZvciBvcHQsIGFyZyBpbiBvcHRzOgogICAgICAgIGlmIG9wdCBpbiAoJy1oJywgJy0taGVscCcpOgogICAgICAgICAgICB1c2FnZSgwKQogICAgICAgIGVsaWYgb3B0IGluICgnLWEnLCAnLS1leHRyYWN0LWFsbCcpOgogICAgICAgICAgICBvcHRpb25zLmV4dHJhY3RhbGwgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctZCcsICctLWRlZmF1bHQtZG9tYWluJyk6CiAgICAgICAgICAgIG9wdGlvbnMub3V0ZmlsZSA9IGFyZyArICcucG90JwogICAgICAgIGVsaWYgb3B0IGluICgnLUUnLCAnLS1lc2NhcGUnKToKICAgICAgICAgICAgb3B0aW9ucy5lc2NhcGUgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctRCcsICctLWRvY3N0cmluZ3MnKToKICAgICAgICAgICAgb3B0aW9ucy5kb2NzdHJpbmdzID0gMQogICAgICAgIGVsaWYgb3B0IGluICgnLWsnLCAnLS1rZXl3b3JkJyk6CiAgICAgICAgICAgIG9wdGlvbnMua2V5d29yZHMuYXBwZW5kKGFyZykKICAgICAgICBlbGlmIG9wdCBpbiAoJy1LJywgJy0tbm8tZGVmYXVsdC1rZXl3b3JkcycpOgogICAgICAgICAgICBkZWZhdWx0X2tleXdvcmRzID0gW10KICAgICAgICBlbGlmIG9wdCBpbiAoJy1uJywgJy0tYWRkLWxvY2F0aW9uJyk6CiAgICAgICAgICAgIG9wdGlvbnMud3JpdGVsb2NhdGlvbnMgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctLW5vLWxvY2F0aW9uJywpOgogICAgICAgICAgICBvcHRpb25zLndyaXRlbG9jYXRpb25zID0gMAogICAgICAgIGVsaWYgb3B0IGluICgnLVMnLCAnLS1zdHlsZScpOgogICAgICAgICAgICBvcHRpb25zLmxvY2F0aW9uc3R5bGUgPSBsb2NhdGlvbnMuZ2V0KGFyZy5sb3dlcigpKQogICAgICAgICAgICBpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgaXMgTm9uZToKICAgICAgICAgICAgICAgIHVzYWdlKDEsIF8oJ0ludmFsaWQgdmFsdWUgZm9yIC0tc3R5bGU6ICVzJykgJSBhcmcpCiAgICAgICAgZWxpZiBvcHQgaW4gKCctbycsICctLW91dHB1dCcpOgogICAgICAgICAgICBvcHRpb25zLm91dGZpbGUgPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy1wJywgJy0tb3V0cHV0LWRpcicpOgogICAgICAgICAgICBvcHRpb25zLm91dHBhdGggPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy12JywgJy0tdmVyYm9zZScpOgogICAgICAgICAgICBvcHRpb25zLnZlcmJvc2UgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctVicsICctLXZlcnNpb24nKToKICAgICAgICAgICAgcHJpbnQoXygncHlnZXR0ZXh0LnB5ICh4Z2V0dGV4dCBmb3IgUHl0aG9uKSAlcycpICUgX192ZXJzaW9uX18pCiAgICAgICAgICAgIHN5cy5leGl0KDApCiAgICAgICAgZWxpZiBvcHQgaW4gKCctdycsICctLXdpZHRoJyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9wdGlvbnMud2lkdGggPSBpbnQoYXJnKQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIHVzYWdlKDEsIF8oJy0td2lkdGggYXJndW1lbnQgbXVzdCBiZSBhbiBpbnRlZ2VyOiAlcycpICUgYXJnKQogICAgICAgIGVsaWYgb3B0IGluICgnLXgnLCAnLS1leGNsdWRlLWZpbGUnKToKICAgICAgICAgICAgb3B0aW9ucy5leGNsdWRlZmlsZW5hbWUgPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy1YJywgJy0tbm8tZG9jc3RyaW5ncycpOgogICAgICAgICAgICBmcCA9IG9wZW4oYXJnKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICAgICAgICAgIGxpbmUgPSBmcC5yZWFkbGluZSgpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGxpbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5ub2RvY3N0cmluZ3NbbGluZVs6LTFdXSA9IDEKICAgICAgICAgICAgZmluYWxseToKICAgICAgICAgICAgICAgIGZwLmNsb3NlKCkKCiAgICAjIGNhbGN1bGF0ZSBlc2NhcGVzCiAgICBtYWtlX2VzY2FwZXMobm90IG9wdGlvbnMuZXNjYXBlKQoKICAgICMgY2FsY3VsYXRlIGFsbCBrZXl3b3JkcwogICAgb3B0aW9ucy5rZXl3b3Jkcy5leHRlbmQoZGVmYXVsdF9rZXl3b3JkcykKCiAgICAjIGluaXRpYWxpemUgbGlzdCBvZiBzdHJpbmdzIHRvIGV4Y2x1ZGUKICAgIGlmIG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lOgogICAgICAgIHRyeToKICAgICAgICAgICAgZnAgPSBvcGVuKG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lKQogICAgICAgICAgICBvcHRpb25zLnRvZXhjbHVkZSA9IGZwLnJlYWRsaW5lcygpCiAgICAgICAgICAgIGZwLmNsb3NlKCkKICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgcHJpbnQoXygKICAgICAgICAgICAgICAgICJDYW4ndCByZWFkIC0tZXhjbHVkZS1maWxlOiAlcyIpICUgb3B0aW9ucy5leGNsdWRlZmlsZW5hbWUsIGZpbGU9c3lzLnN0ZGVycikKICAgICAgICAgICAgc3lzLmV4aXQoMSkKICAgIGVsc2U6CiAgICAgICAgb3B0aW9ucy50b2V4Y2x1ZGUgPSBbXQoKICAgICMgcmVzb2x2ZSBhcmdzIHRvIG1vZHVsZSBsaXN0cwogICAgZXhwYW5kZWQgPSBbXQogICAgZm9yIGFyZyBpbiBhcmdzOgogICAgICAgIGlmIGFyZyA9PSAnLSc6CiAgICAgICAgICAgIGV4cGFuZGVkLmFwcGVuZChhcmcpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZXhwYW5kZWQuZXh0ZW5kKGdldEZpbGVzRm9yTmFtZShhcmcpKQogICAgYXJncyA9IGV4cGFuZGVkCgogICAgIyBzbHVycCB0aHJvdWdoIGFsbCB0aGUgZmlsZXMKICAgIGVhdGVyID0gVG9rZW5FYXRlcihvcHRpb25zKQogICAgZm9yIGZpbGVuYW1lIGluIGFyZ3M6CiAgICAgICAgaWYgZmlsZW5hbWUgPT0gJy0nOgogICAgICAgICAgICBpZiBvcHRpb25zLnZlcmJvc2U6CiAgICAgICAgICAgICAgICBwcmludChfKCdSZWFkaW5nIHN0YW5kYXJkIGlucHV0JykpCiAgICAgICAgICAgIGZwID0gc3lzLnN0ZGluLmJ1ZmZlcgogICAgICAgICAgICBjbG9zZXAgPSAwCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgb3B0aW9ucy52ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQoXygnV29ya2luZyBvbiAlcycpICUgZmlsZW5hbWUpCiAgICAgICAgICAgIGZwID0gb3BlbihmaWxlbmFtZSwgJ3JiJykKICAgICAgICAgICAgY2xvc2VwID0gMQogICAgICAgIHRyeToKICAgICAgICAgICAgZWF0ZXIuc2V0X2ZpbGVuYW1lKGZpbGVuYW1lKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0b2tlbnMgPSB0b2tlbml6ZS50b2tlbml6ZShmcC5yZWFkbGluZSkKICAgICAgICAgICAgICAgIGZvciBfdG9rZW4gaW4gdG9rZW5zOgogICAgICAgICAgICAgICAgICAgIGVhdGVyKCpfdG9rZW4pCiAgICAgICAgICAgIGV4Y2VwdCB0b2tlbml6ZS5Ub2tlbkVycm9yIGFzIGU6CiAgICAgICAgICAgICAgICBwcmludCgnJXM6ICVzLCBsaW5lICVkLCBjb2x1bW4gJWQnICUgKAogICAgICAgICAgICAgICAgICAgIGUuYXJnc1swXSwgZmlsZW5hbWUsIGUuYXJnc1sxXVswXSwgZS5hcmdzWzFdWzFdKSwKICAgICAgICAgICAgICAgICAgICBmaWxlPXN5cy5zdGRlcnIpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgaWYgY2xvc2VwOgogICAgICAgICAgICAgICAgZnAuY2xvc2UoKQoKICAgICMgd3JpdGUgdGhlIG91dHB1dAogICAgaWYgb3B0aW9ucy5vdXRmaWxlID09ICctJzoKICAgICAgICBmcCA9IHN5cy5zdGRvdXQKICAgICAgICBjbG9zZXAgPSAwCiAgICBlbHNlOgogICAgICAgIGlmIG9wdGlvbnMub3V0cGF0aDoKICAgICAgICAgICAgb3B0aW9ucy5vdXRmaWxlID0gb3MucGF0aC5qb2luKG9wdGlvbnMub3V0cGF0aCwgb3B0aW9ucy5vdXRmaWxlKQogICAgICAgIGZwID0gb3BlbihvcHRpb25zLm91dGZpbGUsICd3JykKICAgICAgICBjbG9zZXAgPSAxCiAgICB0cnk6CiAgICAgICAgZWF0ZXIud3JpdGUoZnApCiAgICBmaW5hbGx5OgogICAgICAgIGlmIGNsb3NlcDoKICAgICAgICAgICAgZnAuY2xvc2UoKQoKDAppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgbWFpbigpCiAgICAjIHNvbWUgbW9yZSB0ZXN0IHN0cmluZ3MKICAgICMgdGhpcyBvbmUgY3JlYXRlcyBhIHdhcm5pbmcKICAgIF8oJyoqKiBTZWVuIHVuZXhwZWN0ZWQgdG9rZW4gIiUodG9rZW4pcyInKSAlIHsndG9rZW4nOiAndGVzdCd9CiAgICBfKCdtb3JlJyAndGhhbicgJ29uZScgJ3N0cmluZycpCg==