RotherOSS-CustomerMultitenancyOTRS
6.0.1
Rother OSS GmbH
https://rother-oss.com/
GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
Initial release.
Initial Version.
Group-based multitenancy for customer and customer user.
Gruppenbasierte Mandantenfähigkeit für Kunden und Kundenbenutzer.
6.0.x
2021-12-08 13:35:09
opms
IyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIxIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDIxIFpudW55IEdtYkgsIGh0dHBzOi8vem51bnkub3JnLwojIENvcHlyaWdodCAoQykgMjAyMSBSb3RoZXIgT1NTIEdtYkgsIGh0dHBzOi8vcm90aGVyLW9zcy5jb20vCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0zLjAudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6TW9kdWxlczo6QWRtaW5DdXN0b21lckNvbXBhbnk7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpMYW5ndWFnZSBxdyhUcmFuc2xhdGFibGUpOwoKb3VyICRPYmplY3RNYW5hZ2VyRGlzYWJsZWQgPSAxOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYXJpYWJsZUNoZWNrIHF3KDphbGwpOwoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7JVBhcmFtfTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlncyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKS0+RHluYW1pY0ZpZWxkTGlzdEdldCgKICAgICAgICBPYmplY3RUeXBlID0+ICdDdXN0b21lckNvbXBhbnknLAogICAgKTsKCiAgICAkU2VsZi0+e0R5bmFtaWNGaWVsZExvb2t1cH0gPSB7IG1hcCB7ICRfLT57TmFtZX0gPT4gJF8gfSBAeyREeW5hbWljRmllbGRDb25maWdzfSB9OwoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFJ1biB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRQYXJhbU9iamVjdCAgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6V2ViOjpSZXF1ZXN0Jyk7CiAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICBteSAkTmF2ICAgICAgICAgICAgICAgPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnTmF2JyApIHx8IDA7CiAgICBteSAkTmF2aWdhdGlvbkJhclR5cGUgPSAkTmF2IGVxICdBZ2VudCcgPyAnQ3VzdG9tZXJzJyA6ICdBZG1pbic7CiAgICBteSAkU2VhcmNoICAgICAgICAgICAgPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnU2VhcmNoJyApOwogICAgJFNlYXJjaAogICAgICAgIHx8PSAkQ29uZmlnT2JqZWN0LT5HZXQoJ0FkbWluQ3VzdG9tZXJDb21wYW55OjpSdW5Jbml0aWFsV2lsZGNhcmRTZWFyY2gnKSA/ICcqJyA6ICcnOwogICAgbXkgJExheW91dE9iamVjdCAgICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKICAgIG15ICRDdXN0b21lckNvbXBhbnlPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJDb21wYW55Jyk7CgogICAgbXkgJUdldFBhcmFtOwogICAgJEdldFBhcmFte1NvdXJjZX0gPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnU291cmNlJyApIHx8ICdDdXN0b21lckNvbXBhbnknOwoKICAgICMgLS0tCiAgICAjIFJvdGhlck9TUzoKICAgICMgLS0tCiAgICAjIENoZWNrIGlmIHRoZSB1c2VyIGhhcyBwZXJtaXNzaW9uIHRvIHNldCBtdWx0aXRlbmFuY3kuCiAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCgnTXVsdGl0ZW5hbmN5JykgKSB7CiAgICAgICAgbXkgJEdyb3VwT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Okdyb3VwJyk7CgogICAgICAgIG15ICRNdWx0aXRlbmFuY3lHcm91cElEID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Okdyb3VwJyktPkdyb3VwTG9va3VwKAogICAgICAgICAgICBHcm91cCA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ011bHRpdGVuYW5jeTo6UGVybWlzc2lvbkdyb3VwJyksCiAgICAgICAgKTsKCiAgICAgICAgbXkgJUdyb3VwcyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpHcm91cCcpLT5QZXJtaXNzaW9uVXNlckdldCgKICAgICAgICAgICAgVXNlcklEID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICAgICAgVHlwZSAgID0+ICdydycsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCAkR3JvdXBzeyRNdWx0aXRlbmFuY3lHcm91cElEfSApIHsKICAgICAgICAgICAgJFNlbGYtPntNdWx0aXRlbmFuY3lQZXJtaXNzaW9ufSA9IDE7CiAgICAgICAgfQogICAgfQogICAgIyAtLS0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIGNoYW5nZQogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgaWYgKCAkU2VsZi0+e1N1YmFjdGlvbn0gZXEgJ0NoYW5nZScgKSB7CiAgICAgICAgbXkgJEN1c3RvbWVySUQKICAgICAgICAgICAgPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnQ3VzdG9tZXJJRCcgKSB8fCAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnSUQnICkgfHwgJyc7CiAgICAgICAgbXkgJE5vdGlmaWNhdGlvbiA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdOb3RpZmljYXRpb24nICkgfHwgJyc7CiAgICAgICAgbXkgJURhdGEgICAgICAgICA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueUdldCgKICAgICAgICAgICAgQ3VzdG9tZXJJRCA9PiAkQ3VzdG9tZXJJRCwKICAgICAgICApOwogICAgICAgICREYXRhe0N1c3RvbWVyQ29tcGFueUlEfSA9ICRDdXN0b21lcklEOwogICAgICAgIG15ICRPdXRwdXQgPSAkTGF5b3V0T2JqZWN0LT5IZWFkZXIoKTsKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk5hdmlnYXRpb25CYXIoCiAgICAgICAgICAgIFR5cGUgPT4gJE5hdmlnYXRpb25CYXJUeXBlLAogICAgICAgICk7CiAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoIEluZm8gPT4gVHJhbnNsYXRhYmxlKCdDdXN0b21lciBjb21wYW55IHVwZGF0ZWQhJykgKQogICAgICAgICAgICBpZiAoICROb3RpZmljYXRpb24gJiYgJE5vdGlmaWNhdGlvbiBlcSAnVXBkYXRlJyApOwogICAgICAgICRTZWxmLT5fRWRpdCgKICAgICAgICAgICAgQWN0aW9uID0+ICdDaGFuZ2UnLAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgJURhdGEsCiAgICAgICAgKTsKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyQ29tcGFueScsCiAgICAgICAgICAgIERhdGEgICAgICAgICA9PiBcJVBhcmFtLAogICAgICAgICk7CiAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5Gb290ZXIoKTsKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIGNoYW5nZSBhY3Rpb24KICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgIGVsc2lmICggJFNlbGYtPntTdWJhY3Rpb259IGVxICdDaGFuZ2VBY3Rpb24nICkgewoKICAgICAgICAjIGNoYWxsZW5nZSB0b2tlbiBjaGVjayBmb3Igd3JpdGUgYWN0aW9uCiAgICAgICAgJExheW91dE9iamVjdC0+Q2hhbGxlbmdlVG9rZW5DaGVjaygpOwoKICAgICAgICBteSAkTm90ZSA9ICcnOwogICAgICAgIG15ICVFcnJvcnM7CiAgICAgICAgJEdldFBhcmFte0N1c3RvbWVyQ29tcGFueUlEfSA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdDdXN0b21lckNvbXBhbnlJRCcgKTsKCiAgICAgICAgIyBHZXQgZHluYW1pYyBmaWVsZCBiYWNrZW5kIG9iamVjdC4KICAgICAgICBteSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQnKTsKCiAgICAgICAgRU5UUlk6CiAgICAgICAgZm9yIG15ICRFbnRyeSAoIEB7ICRDb25maWdPYmplY3QtPkdldCggJEdldFBhcmFte1NvdXJjZX0gKS0+e01hcH0gfSApIHsKCiAgICAgICAgICAgICMgY2hlY2sgZHluYW1pYyBmaWVsZHMKICAgICAgICAgICAgaWYgKCAkRW50cnktPls1XSBlcSAnZHluYW1pY19maWVsZCcgKSB7CgogICAgICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZENvbmZpZyA9ICRTZWxmLT57RHluYW1pY0ZpZWxkTG9va3VwfS0+eyAkRW50cnktPlsyXSB9OwoKICAgICAgICAgICAgICAgIGlmICggIUlzSGFzaFJlZldpdGhEYXRhKCREeW5hbWljRmllbGRDb25maWcpICkgewogICAgICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiRHluYW1pY0ZpZWxkICRFbnRyeS0+WzJdIG5vdCBmb3VuZCEiLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBFTlRSWTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBteSAkVmFsaWRhdGlvblJlc3VsdCA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5FZGl0RmllbGRWYWx1ZVZhbGlkYXRlKAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLAogICAgICAgICAgICAgICAgICAgIFBhcmFtT2JqZWN0ICAgICAgICA9PiAkUGFyYW1PYmplY3QsCiAgICAgICAgICAgICAgICAgICAgTWFuZGF0b3J5ICAgICAgICAgID0+ICRFbnRyeS0+WzRdLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBpZiAoICRWYWxpZGF0aW9uUmVzdWx0LT57U2VydmVyRXJyb3J9ICkgewogICAgICAgICAgICAgICAgICAgICRFcnJvcnN7ICRFbnRyeS0+WzBdIH0gPSAkVmFsaWRhdGlvblJlc3VsdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewoKICAgICAgICAgICAgICAgICAgICAjIGdlbmVyYXRlIHN0b3JhYmxlIHZhbHVlIG9mIGR5bmFtaWMgZmllbGQgZWRpdCBmaWVsZAogICAgICAgICAgICAgICAgICAgICRHZXRQYXJhbXsgJEVudHJ5LT5bMF0gfSA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5FZGl0RmllbGRWYWx1ZUdldCgKICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgIFBhcmFtT2JqZWN0ICAgICAgICA9PiAkUGFyYW1PYmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgIExheW91dE9iamVjdCAgICAgICA9PiAkTGF5b3V0T2JqZWN0LAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgY2hlY2sgcmVtYWluaW5nIG5vbi1keW5hbWljLWZpZWxkIG1hbmRhdG9yeSBmaWVsZHMKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkR2V0UGFyYW17ICRFbnRyeS0+WzBdIH0gPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAkRW50cnktPlswXSApIC8vICcnOwogICAgICAgICAgICAgICAgaWYgKCAhJEdldFBhcmFteyAkRW50cnktPlswXSB9ICYmICRFbnRyeS0+WzRdICkgewogICAgICAgICAgICAgICAgICAgICRFcnJvcnN7ICRFbnRyeS0+WzBdIC4gJ0ludmFsaWQnIH0gPSAnU2VydmVyRXJyb3InOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoICFkZWZpbmVkICRHZXRQYXJhbXtDdXN0b21lcklEfSApIHsKICAgICAgICAgICAgJEdldFBhcmFte0N1c3RvbWVySUR9ID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ0N1c3RvbWVySUQnICkgfHwgJyc7CiAgICAgICAgfQoKICAgICAgICAjIGNoZWNrIGZvciBkdXBsaWNhdGUgZW50cmllcwogICAgICAgIGlmICggJEdldFBhcmFte0N1c3RvbWVyQ29tcGFueUlEfSBuZSAkR2V0UGFyYW17Q3VzdG9tZXJJRH0gKSB7CgogICAgICAgICAgICAjIGdldCBDdXN0b21lckNvbXBhbnkgbGlzdAogICAgICAgICAgICBteSAlTGlzdCA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueUxpc3QoCiAgICAgICAgICAgICAgICBTZWFyY2ggPT4gJFBhcmFte1NlYXJjaH0sCiAgICAgICAgICAgICAgICBWYWxpZCAgPT4gMCwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICMgY2hlY2sgZHVwbGljYXRlIGZpZWxkCiAgICAgICAgICAgIGlmICggJUxpc3QgJiYgJExpc3R7ICRHZXRQYXJhbXtDdXN0b21lcklEfSB9ICkgewogICAgICAgICAgICAgICAgJEVycm9yc3tEdXBsaWNhdGV9ID0gJ1NlcnZlckVycm9yJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBpZiBubyBlcnJvcnMgb2NjdXJyZWQKICAgICAgICBpZiAoICElRXJyb3JzICkgewoKICAgICAgICAgICAgIyB1cGRhdGUgZ3JvdXAKICAgICAgICAgICAgbXkgJFVwZGF0ZSA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueVVwZGF0ZSggJUdldFBhcmFtLCBVc2VySUQgPT4gJFNlbGYtPntVc2VySUR9ICk7CgogICAgICAgICAgICBpZiAoJFVwZGF0ZSkgewoKICAgICAgICAgICAgICAgIG15ICRTZXRERkVycm9yOwoKICAgICAgICAgICAgICAgICMgc2V0IGR5bmFtaWMgZmllbGQgdmFsdWVzCiAgICAgICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZCcpOwoKICAgICAgICAgICAgICAgIEVOVFJZOgogICAgICAgICAgICAgICAgZm9yIG15ICRFbnRyeSAoIEB7ICRDb25maWdPYmplY3QtPkdldCggJEdldFBhcmFte1NvdXJjZX0gKS0+e01hcH0gfSApIHsKICAgICAgICAgICAgICAgICAgICBuZXh0IEVOVFJZIGlmICRFbnRyeS0+WzVdIG5lICdkeW5hbWljX2ZpZWxkJzsKCiAgICAgICAgICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZENvbmZpZyA9ICRTZWxmLT57RHluYW1pY0ZpZWxkTG9va3VwfS0+eyAkRW50cnktPlsyXSB9OwoKICAgICAgICAgICAgICAgICAgICBpZiAoICFJc0hhc2hSZWZXaXRoRGF0YSgkRHluYW1pY0ZpZWxkQ29uZmlnKSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJFNldERGRXJyb3IgLj0gJExheW91dE9iamVjdC0+Tm90aWZ5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5mbyA9PiAkTGF5b3V0T2JqZWN0LT57TGFuZ3VhZ2VPYmplY3R9LT5UcmFuc2xhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0R5bmFtaWMgZmllbGQgJXMgbm90IGZvdW5kIScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJEVudHJ5LT5bMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgRU5UUlk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBteSAkVmFsdWVTZXQgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+VmFsdWVTZXQoCiAgICAgICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICBPYmplY3ROYW1lICAgICAgICAgPT4gJEdldFBhcmFte0N1c3RvbWVySUR9LAogICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSAgICAgICAgICAgICAgPT4gJEdldFBhcmFteyAkRW50cnktPlswXSB9LAogICAgICAgICAgICAgICAgICAgICAgICBVc2VySUQgICAgICAgICAgICAgPT4gJFNlbGYtPntVc2VySUR9LAogICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgIGlmICggISRWYWx1ZVNldCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJFNldERGRXJyb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZm8gPT4gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVbmFibGUgdG8gc2V0IHZhbHVlIGZvciBkeW5hbWljIGZpZWxkICVzIScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJEVudHJ5LT5bMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCBFTlRSWTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbXkgJENvbnRpbnVlQWZ0ZXJTYXZlID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ0NvbnRpbnVlQWZ0ZXJTYXZlJyApIHx8IDA7CgogICAgICAgICAgICAgICAgIyBpZiBzZXQgREYgZXJyb3IgZXhpc3RzLCBjcmVhdGUgbm90aWZpY2F0aW9uCiAgICAgICAgICAgICAgICBpZiAoJFNldERGRXJyb3IpIHsKCiAgICAgICAgICAgICAgICAgICAgIyBpZiB0aGUgdXNlciB3b3VsZCBsaWtlIHRvIGNvbnRpbnVlIGVkaXRpbmcgdGhlIGN1c3RvbWVyIGNvbXBhbnksIGp1c3QgcmVkaXJlY3QgdG8gdGhlIGVkaXQgc2NyZWVuCiAgICAgICAgICAgICAgICAgICAgaWYgKCAkQ29udGludWVBZnRlclNhdmUgZXEgJzEnICkgewogICAgICAgICAgICAgICAgICAgICAgICAkU2VsZi0+X0VkaXQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY3Rpb24gPT4gJ0NoYW5nZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVycm9ycyA9PiBcJUVycm9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICVHZXRQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRTZWxmLT5fT3ZlcnZpZXcoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlYXJjaCA9PiAkU2VhcmNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJUdldFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBteSAkT3V0cHV0ID0gJExheW91dE9iamVjdC0+SGVhZGVyKCk7CiAgICAgICAgICAgICAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5OYXZpZ2F0aW9uQmFyKAogICAgICAgICAgICAgICAgICAgICAgICBUeXBlID0+ICROYXZpZ2F0aW9uQmFyVHlwZSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Tm90aWZ5KCBJbmZvID0+IFRyYW5zbGF0YWJsZSgnQ3VzdG9tZXIgY29tcGFueSB1cGRhdGVkIScpICk7CiAgICAgICAgICAgICAgICAgICAgJE91dHB1dCAuPSAkU2V0REZFcnJvcjsKICAgICAgICAgICAgICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk91dHB1dCgKICAgICAgICAgICAgICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyQ29tcGFueScsCiAgICAgICAgICAgICAgICAgICAgICAgIERhdGEgICAgICAgICA9PiBcJVBhcmFtLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5Gb290ZXIoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAjIGlmIHRoZSB1c2VyIHdvdWxkIGxpa2UgdG8gY29udGludWUgZWRpdGluZyB0aGUgY3VzdG9tZXIgY29tcGFueSwganVzdCByZWRpcmVjdCB0byB0aGUgZWRpdCBzY3JlZW4KICAgICAgICAgICAgICAgIGlmICggJENvbnRpbnVlQWZ0ZXJTYXZlIGVxICcxJyApIHsKICAgICAgICAgICAgICAgICAgICBteSAkQ3VzdG9tZXJJRCA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdDdXN0b21lcklEJyApIHx8ICcnOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAkTGF5b3V0T2JqZWN0LT5SZWRpcmVjdCgKICAgICAgICAgICAgICAgICAgICAgICAgT1AgPT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBY3Rpb249JFNlbGYtPntBY3Rpb259O1N1YmFjdGlvbj1DaGFuZ2U7Q3VzdG9tZXJJRD0kQ3VzdG9tZXJJRDtOYXY9JE5hdjtOb3RpZmljYXRpb249VXBkYXRlIgogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKCiAgICAgICAgICAgICAgICAgICAgIyBvdGhlcndpc2UgcmV0dXJuIHRvIG92ZXJ2aWV3CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRMYXlvdXRPYmplY3QtPlJlZGlyZWN0KCBPUCA9PiAiQWN0aW9uPSRTZWxmLT57QWN0aW9ufTtOb3RpZmljYXRpb249VXBkYXRlIiApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjIHNvbWV0aGluZyB3ZW50IHdyb25nCiAgICAgICAgbXkgJE91dHB1dCA9ICRMYXlvdXRPYmplY3QtPkhlYWRlcigpOwogICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+TmF2aWdhdGlvbkJhcigKICAgICAgICAgICAgVHlwZSA9PiAkTmF2aWdhdGlvbkJhclR5cGUsCiAgICAgICAgKTsKCiAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoIFByaW9yaXR5ID0+ICdFcnJvcicgKTsKCiAgICAgICAgIyBzZXQgbm90aWZpY2F0aW9uIGZvciBkdXBsaWNhdGUgZW50cnkKICAgICAgICBpZiAoICRFcnJvcnN7RHVwbGljYXRlfSApIHsKICAgICAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnRXJyb3InLAogICAgICAgICAgICAgICAgSW5mbyAgICAgPT4gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAgICAgICAgICdDdXN0b21lciBDb21wYW55ICVzIGFscmVhZHkgZXhpc3RzIScsCiAgICAgICAgICAgICAgICAgICAgJEdldFBhcmFte0N1c3RvbWVySUR9LAogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRTZWxmLT5fRWRpdCgKICAgICAgICAgICAgQWN0aW9uID0+ICdDaGFuZ2UnLAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgRXJyb3JzID0+IFwlRXJyb3JzLAogICAgICAgICAgICAlR2V0UGFyYW0sCiAgICAgICAgKTsKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyQ29tcGFueScsCiAgICAgICAgICAgIERhdGEgICAgICAgICA9PiBcJVBhcmFtLAogICAgICAgICk7CiAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5Gb290ZXIoKTsKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIGFkZAogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgZWxzaWYgKCAkU2VsZi0+e1N1YmFjdGlvbn0gZXEgJ0FkZCcgKSB7CiAgICAgICAgJEdldFBhcmFte05hbWV9ID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ05hbWUnICk7CiAgICAgICAgbXkgJE91dHB1dCA9ICRMYXlvdXRPYmplY3QtPkhlYWRlcigpOwogICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+TmF2aWdhdGlvbkJhcigKICAgICAgICAgICAgVHlwZSA9PiAkTmF2aWdhdGlvbkJhclR5cGUsCiAgICAgICAgKTsKICAgICAgICAkU2VsZi0+X0VkaXQoCiAgICAgICAgICAgIEFjdGlvbiA9PiAnQWRkJywKICAgICAgICAgICAgTmF2ICAgID0+ICROYXYsCiAgICAgICAgICAgICVHZXRQYXJhbSwKICAgICAgICApOwogICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+T3V0cHV0KAogICAgICAgICAgICBUZW1wbGF0ZUZpbGUgPT4gJ0FkbWluQ3VzdG9tZXJDb21wYW55JywKICAgICAgICAgICAgRGF0YSAgICAgICAgID0+IFwlUGFyYW0sCiAgICAgICAgKTsKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPkZvb3RlcigpOwogICAgICAgIHJldHVybiAkT3V0cHV0OwogICAgfQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgICMgYWRkIGFjdGlvbgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgZWxzaWYgKCAkU2VsZi0+e1N1YmFjdGlvbn0gZXEgJ0FkZEFjdGlvbicgKSB7CgogICAgICAgICMgY2hhbGxlbmdlIHRva2VuIGNoZWNrIGZvciB3cml0ZSBhY3Rpb24KICAgICAgICAkTGF5b3V0T2JqZWN0LT5DaGFsbGVuZ2VUb2tlbkNoZWNrKCk7CgogICAgICAgIG15ICROb3RlID0gJyc7CiAgICAgICAgbXkgJUVycm9yczsKCiAgICAgICAgbXkgJEN1c3RvbWVyQ29tcGFueUtleSA9ICRDb25maWdPYmplY3QtPkdldCggJEdldFBhcmFte1NvdXJjZX0gKS0+e0N1c3RvbWVyQ29tcGFueUtleX07CiAgICAgICAgbXkgJEN1c3RvbWVyQ29tcGFueUlEOwoKICAgICAgICAjIEdldCBkeW5hbWljIGZpZWxkIGJhY2tlbmQgb2JqZWN0LgogICAgICAgIG15ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDo6QmFja2VuZCcpOwoKICAgICAgICBFTlRSWToKICAgICAgICBmb3IgbXkgJEVudHJ5ICggQHsgJENvbmZpZ09iamVjdC0+R2V0KCAkR2V0UGFyYW17U291cmNlfSApLT57TWFwfSB9ICkgewoKICAgICAgICAgICAgIyBjaGVjayBkeW5hbWljIGZpZWxkcwogICAgICAgICAgICBpZiAoICRFbnRyeS0+WzVdIGVxICdkeW5hbWljX2ZpZWxkJyApIHsKCiAgICAgICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlnID0gJFNlbGYtPntEeW5hbWljRmllbGRMb29rdXB9LT57ICRFbnRyeS0+WzJdIH07CgogICAgICAgICAgICAgICAgaWYgKCAhSXNIYXNoUmVmV2l0aERhdGEoJER5bmFtaWNGaWVsZENvbmZpZykgKSB7CiAgICAgICAgICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJEeW5hbWljRmllbGQgJEVudHJ5LT5bMl0gbm90IGZvdW5kISIsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICBuZXh0IEVOVFJZOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG15ICRWYWxpZGF0aW9uUmVzdWx0ID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPkVkaXRGaWVsZFZhbHVlVmFsaWRhdGUoCiAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICAgICAgUGFyYW1PYmplY3QgICAgICAgID0+ICRQYXJhbU9iamVjdCwKICAgICAgICAgICAgICAgICAgICBNYW5kYXRvcnkgICAgICAgICAgPT4gJEVudHJ5LT5bNF0sCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGlmICggJFZhbGlkYXRpb25SZXN1bHQtPntTZXJ2ZXJFcnJvcn0gKSB7CiAgICAgICAgICAgICAgICAgICAgJEVycm9yc3sgJEVudHJ5LT5bMF0gfSA9ICRWYWxpZGF0aW9uUmVzdWx0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CgogICAgICAgICAgICAgICAgICAgICMgZ2VuZXJhdGUgc3RvcmFibGUgdmFsdWUgb2YgZHluYW1pYyBmaWVsZCBlZGl0IGZpZWxkCiAgICAgICAgICAgICAgICAgICAgJEdldFBhcmFteyAkRW50cnktPlswXSB9ID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPkVkaXRGaWVsZFZhbHVlR2V0KAogICAgICAgICAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZENvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgUGFyYW1PYmplY3QgICAgICAgID0+ICRQYXJhbU9iamVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgTGF5b3V0T2JqZWN0ICAgICAgID0+ICRMYXlvdXRPYmplY3QsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgIyBjaGVjayByZW1haW5pbmcgbm9uLWR5bmFtaWMtZmllbGQgbWFuZGF0b3J5IGZpZWxkcwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRHZXRQYXJhbXsgJEVudHJ5LT5bMF0gfSA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICRFbnRyeS0+WzBdICkgLy8gJyc7CiAgICAgICAgICAgICAgICBpZiAoICEkR2V0UGFyYW17ICRFbnRyeS0+WzBdIH0gJiYgJEVudHJ5LT5bNF0gKSB7CiAgICAgICAgICAgICAgICAgICAgJEVycm9yc3sgJEVudHJ5LT5bMF0gLiAnSW52YWxpZCcgfSA9ICdTZXJ2ZXJFcnJvcic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgc2F2ZSBjdXN0b21lciBjb21wYW55IGtleSBmb3IgY2hlY2tpbmcgZHVwbGljYXRlCiAgICAgICAgICAgIGlmICggJEVudHJ5LT5bMl0gZXEgJEN1c3RvbWVyQ29tcGFueUtleSApIHsKICAgICAgICAgICAgICAgICRDdXN0b21lckNvbXBhbnlJRCA9ICRHZXRQYXJhbXsgJEVudHJ5LT5bMF0gfTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBnZXQgQ3VzdG9tZXJDb21wYW55IGxpc3QKICAgICAgICBteSAlTGlzdCA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueUxpc3QoCiAgICAgICAgICAgIFNlYXJjaCA9PiAkUGFyYW17U2VhcmNofSwKICAgICAgICAgICAgVmFsaWQgID0+IDAsCiAgICAgICAgKTsKCiAgICAgICAgIyBjaGVjayBkdXBsaWNhdGUgZmllbGQKICAgICAgICBpZiAoICVMaXN0ICYmICRMaXN0eyRDdXN0b21lckNvbXBhbnlJRH0gKSB7CiAgICAgICAgICAgICRFcnJvcnN7RHVwbGljYXRlfSA9ICdTZXJ2ZXJFcnJvcic7CiAgICAgICAgfQoKICAgICAgICAjIGlmIG5vIGVycm9ycyBvY2N1cnJlZAogICAgICAgIGlmICggISVFcnJvcnMgKSB7CgogICAgICAgICAgICAjIGFkZCBjb21wYW55CiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueUFkZCgKICAgICAgICAgICAgICAgICAgICAlR2V0UGFyYW0sCiAgICAgICAgICAgICAgICAgICAgVXNlcklEID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICRTZWxmLT5fT3ZlcnZpZXcoCiAgICAgICAgICAgICAgICAgICAgTmF2ICAgID0+ICROYXYsCiAgICAgICAgICAgICAgICAgICAgU2VhcmNoID0+ICRTZWFyY2gsCiAgICAgICAgICAgICAgICAgICAgJUdldFBhcmFtLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIG15ICRPdXRwdXQgPSAkTGF5b3V0T2JqZWN0LT5IZWFkZXIoKTsKICAgICAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+TmF2aWdhdGlvbkJhcigKICAgICAgICAgICAgICAgICAgICBUeXBlID0+ICROYXZpZ2F0aW9uQmFyVHlwZSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSgKICAgICAgICAgICAgICAgICAgICBJbmZvID0+IFRyYW5zbGF0YWJsZSgnQ3VzdG9tZXIgY29tcGFueSBhZGRlZCEnKSwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgIyBzZXQgZHluYW1pYyBmaWVsZCB2YWx1ZXMKICAgICAgICAgICAgICAgIG15ICREeW5hbWljRmllbGRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkJyk7CgogICAgICAgICAgICAgICAgRU5UUlk6CiAgICAgICAgICAgICAgICBmb3IgbXkgJEVudHJ5ICggQHsgJENvbmZpZ09iamVjdC0+R2V0KCAkR2V0UGFyYW17U291cmNlfSApLT57TWFwfSB9ICkgewogICAgICAgICAgICAgICAgICAgIG5leHQgRU5UUlkgaWYgJEVudHJ5LT5bNV0gbmUgJ2R5bmFtaWNfZmllbGQnOwoKICAgICAgICAgICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlnID0gJFNlbGYtPntEeW5hbWljRmllbGRMb29rdXB9LT57ICRFbnRyeS0+WzJdIH07CgogICAgICAgICAgICAgICAgICAgIGlmICggIUlzSGFzaFJlZldpdGhEYXRhKCREeW5hbWljRmllbGRDb25maWcpICkgewogICAgICAgICAgICAgICAgICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZm8gPT4gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdEeW5hbWljIGZpZWxkICVzIG5vdCBmb3VuZCEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRFbnRyeS0+WzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCBFTlRSWTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIG15ICRWYWx1ZVNldCA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5WYWx1ZVNldCgKICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdE5hbWUgICAgICAgICA9PiAkR2V0UGFyYW17Q3VzdG9tZXJJRH0sCiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlICAgICAgICAgICAgICA9PiAkR2V0UGFyYW17ICRFbnRyeS0+WzBdIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJJRCAgICAgICAgICAgICA9PiAkU2VsZi0+e1VzZXJJRH0sCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCAhJFZhbHVlU2V0ICkgewogICAgICAgICAgICAgICAgICAgICAgICAkT3V0cHV0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmZvID0+ICRMYXlvdXRPYmplY3QtPntMYW5ndWFnZU9iamVjdH0tPlRyYW5zbGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVW5hYmxlIHRvIHNldCB2YWx1ZSBmb3IgZHluYW1pYyBmaWVsZCAlcyEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRFbnRyeS0+WzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgRU5UUlk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+T3V0cHV0KAogICAgICAgICAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnQWRtaW5DdXN0b21lckNvbXBhbnknLAogICAgICAgICAgICAgICAgICAgIERhdGEgICAgICAgICA9PiBcJVBhcmFtLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBzb21ldGhpbmcgd2VudCB3cm9uZwogICAgICAgIG15ICRPdXRwdXQgPSAkTGF5b3V0T2JqZWN0LT5IZWFkZXIoKTsKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk5hdmlnYXRpb25CYXIoCiAgICAgICAgICAgIFR5cGUgPT4gJE5hdmlnYXRpb25CYXJUeXBlLAogICAgICAgICk7CgogICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Tm90aWZ5KCBQcmlvcml0eSA9PiAnRXJyb3InICk7CgogICAgICAgICMgc2V0IG5vdGlmaWNhdGlvbiBmb3IgZHVwbGljYXRlIGVudHJ5CiAgICAgICAgaWYgKCAkRXJyb3Jze0R1cGxpY2F0ZX0gKSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Tm90aWZ5KAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ0Vycm9yJywKICAgICAgICAgICAgICAgIEluZm8gICAgID0+ICRMYXlvdXRPYmplY3QtPntMYW5ndWFnZU9iamVjdH0tPlRyYW5zbGF0ZSgKICAgICAgICAgICAgICAgICAgICAnQ3VzdG9tZXIgQ29tcGFueSAlcyBhbHJlYWR5IGV4aXN0cyEnLAogICAgICAgICAgICAgICAgICAgICRDdXN0b21lckNvbXBhbnlJRCwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAkU2VsZi0+X0VkaXQoCiAgICAgICAgICAgIEFjdGlvbiA9PiAnQWRkJywKICAgICAgICAgICAgTmF2ICAgID0+ICROYXYsCiAgICAgICAgICAgIEVycm9ycyA9PiBcJUVycm9ycywKICAgICAgICAgICAgJUdldFBhcmFtLAogICAgICAgICk7CiAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5PdXRwdXQoCiAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnQWRtaW5DdXN0b21lckNvbXBhbnknLAogICAgICAgICAgICBEYXRhICAgICAgICAgPT4gXCVQYXJhbSwKICAgICAgICApOwogICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCk7CiAgICAgICAgcmV0dXJuICRPdXRwdXQ7CiAgICB9CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgb3ZlcnZpZXcKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBlbHNlIHsKICAgICAgICAkU2VsZi0+X092ZXJ2aWV3KAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgU2VhcmNoID0+ICRTZWFyY2gsCiAgICAgICAgICAgICVHZXRQYXJhbSwKICAgICAgICApOwogICAgICAgIG15ICRPdXRwdXQgICAgICAgPSAkTGF5b3V0T2JqZWN0LT5IZWFkZXIoKTsKICAgICAgICBteSAkTm90aWZpY2F0aW9uID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ05vdGlmaWNhdGlvbicgKSB8fCAnJzsKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk5hdmlnYXRpb25CYXIoCiAgICAgICAgICAgIFR5cGUgPT4gJE5hdmlnYXRpb25CYXJUeXBlLAogICAgICAgICk7CiAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoIEluZm8gPT4gVHJhbnNsYXRhYmxlKCdDdXN0b21lciBjb21wYW55IHVwZGF0ZWQhJykgKQogICAgICAgICAgICBpZiAoICROb3RpZmljYXRpb24gJiYgJE5vdGlmaWNhdGlvbiBlcSAnVXBkYXRlJyApOwoKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyQ29tcGFueScsCiAgICAgICAgICAgIERhdGEgICAgICAgICA9PiBcJVBhcmFtLAogICAgICAgICk7CgogICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCk7CiAgICAgICAgcmV0dXJuICRPdXRwdXQ7CiAgICB9Cn0KCnN1YiBfRWRpdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CgogICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXcnLAogICAgICAgIERhdGEgPT4gXCVQYXJhbSwKICAgICk7CgogICAgJExheW91dE9iamVjdC0+QmxvY2soIE5hbWUgPT4gJ0FjdGlvbkxpc3QnICk7CiAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICBOYW1lID0+ICdBY3Rpb25PdmVydmlldycsCiAgICAgICAgRGF0YSA9PiBcJVBhcmFtLAogICAgKTsKCiAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICBOYW1lID0+ICdPdmVydmlld1VwZGF0ZScsCiAgICAgICAgRGF0YSA9PiBcJVBhcmFtLAogICAgKTsKCiAgICAjIGdldCBjb25maWcgb2JqZWN0CiAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICAjIHNlbmQgcGFyYW1ldGVyIFJlYWRPbmx5IHRvIEpTIG9iamVjdAogICAgJExheW91dE9iamVjdC0+QWRkSlNEYXRhKAogICAgICAgIEtleSAgID0+ICdSZWFkT25seScsCiAgICAgICAgVmFsdWUgPT4gJENvbmZpZ09iamVjdC0+eyAkUGFyYW17U291cmNlfSB9LT57UmVhZE9ubHl9LAogICAgKTsKCiAgICAjIEdldCB2YWxpZCBvYmplY3QuCiAgICBteSAkVmFsaWRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6VmFsaWQnKTsKCiAgICAkUGFyYW17J1ZhbGlkT3B0aW9uJ30gPSAkTGF5b3V0T2JqZWN0LT5CdWlsZFNlbGVjdGlvbigKICAgICAgICBEYXRhICAgICAgID0+IHsgJFZhbGlkT2JqZWN0LT5WYWxpZExpc3QoKSwgfSwKICAgICAgICBOYW1lICAgICAgID0+ICdWYWxpZElEJywKICAgICAgICBDbGFzcyAgICAgID0+ICdNb2Rlcm5pemUnLAogICAgICAgIFNlbGVjdGVkSUQgPT4gJFBhcmFte1ZhbGlkSUR9LAogICAgKTsKCiAgICAjIEdldCBuZWVkZWQgb2JqZWN0cy4KICAgIG15ICRQYXJhbU9iamVjdCAgICAgICAgICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OldlYjo6UmVxdWVzdCcpOwogICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CgogICAgRU5UUlk6CiAgICBmb3IgbXkgJEVudHJ5ICggQHsgJENvbmZpZ09iamVjdC0+R2V0KCAkUGFyYW17U291cmNlfSApLT57TWFwfSB9ICkgewogICAgICAgIGlmICggJEVudHJ5LT5bMF0gKSB7CgogICAgICAgICAgICAjIEhhbmRsZSBkeW5hbWljIGZpZWxkcwogICAgICAgICAgICBpZiAoICRFbnRyeS0+WzVdIGVxICdkeW5hbWljX2ZpZWxkJyApIHsKCiAgICAgICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlnID0gJFNlbGYtPntEeW5hbWljRmllbGRMb29rdXB9LT57ICRFbnRyeS0+WzJdIH07CgogICAgICAgICAgICAgICAgbmV4dCBFTlRSWSBpZiAhSXNIYXNoUmVmV2l0aERhdGEoJER5bmFtaWNGaWVsZENvbmZpZyk7CgogICAgICAgICAgICAgICAgIyBHZXQgSFRNTCBmb3IgZHluYW1pYyBmaWVsZAogICAgICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZEhUTUwgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+RWRpdEZpZWxkUmVuZGVyKAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLAogICAgICAgICAgICAgICAgICAgIFZhbHVlICAgICAgICAgICAgICA9PiAkUGFyYW17ICRFbnRyeS0+WzBdIH0gPyAkUGFyYW17ICRFbnRyeS0+WzBdIH0gOiB1bmRlZiwKICAgICAgICAgICAgICAgICAgICBNYW5kYXRvcnkgICAgICAgICAgPT4gJEVudHJ5LT5bNF0sCiAgICAgICAgICAgICAgICAgICAgTGF5b3V0T2JqZWN0ICAgICAgID0+ICRMYXlvdXRPYmplY3QsCiAgICAgICAgICAgICAgICAgICAgUGFyYW1PYmplY3QgICAgICAgID0+ICRQYXJhbU9iamVjdCwKCiAgICAgICAgICAgICAgICAgICAgIyBTZXJ2ZXIgZXJyb3IsIGlmIGFueQogICAgICAgICAgICAgICAgICAgICV7ICRQYXJhbXtFcnJvcnN9LT57ICRFbnRyeS0+WzBdIH0gfSwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgIyBza2lwIGZpZWxkcyBmb3Igd2hpY2ggSFRNTCBjb3VsZCBub3QgYmUgcmV0cmlldmVkCiAgICAgICAgICAgICAgICBuZXh0IEVOVFJZIGlmICFJc0hhc2hSZWZXaXRoRGF0YSgkRHluYW1pY0ZpZWxkSFRNTCk7CgogICAgICAgICAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAnUHJlZmVyZW5jZXNHZW5lcmljJywKICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHt9LAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdEeW5hbWljRmllbGQnLAogICAgICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgICAgICBOYW1lICA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLT57TmFtZX0sCiAgICAgICAgICAgICAgICAgICAgICAgIExhYmVsID0+ICREeW5hbWljRmllbGRIVE1MLT57TGFiZWx9LAogICAgICAgICAgICAgICAgICAgICAgICBGaWVsZCA9PiAkRHluYW1pY0ZpZWxkSFRNTC0+e0ZpZWxkfSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBuZXh0IEVOVFJZOwogICAgICAgICAgICB9CgogICAgICAgICAgICBteSAkQmxvY2sgPSAnSW5wdXQnOwoKICAgICAgICAgICAgIyBidWlsZCBzZWxlY3Rpb25zIG9yIGlucHV0IGZpZWxkcwogICAgICAgICAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCggJFBhcmFte1NvdXJjZX0gKS0+e1NlbGVjdGlvbnN9LT57ICRFbnRyeS0+WzBdIH0gKSB7CiAgICAgICAgICAgICAgICBteSAkT3B0aW9uUmVxdWlyZWQgPSAnJzsKICAgICAgICAgICAgICAgIGlmICggJEVudHJ5LT5bNF0gKSB7CiAgICAgICAgICAgICAgICAgICAgJE9wdGlvblJlcXVpcmVkID0gJ1ZhbGlkYXRlX1JlcXVpcmVkJzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAjIGJ1aWxkIFZhbGlkSUQgc3RyaW5nCiAgICAgICAgICAgICAgICAkQmxvY2sgPSAnT3B0aW9uJzsKICAgICAgICAgICAgICAgICRQYXJhbXtPcHRpb259ID0gJExheW91dE9iamVjdC0+QnVpbGRTZWxlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9PgogICAgICAgICAgICAgICAgICAgICAgICAkQ29uZmlnT2JqZWN0LT5HZXQoICRQYXJhbXtTb3VyY2V9ICktPntTZWxlY3Rpb25zfQogICAgICAgICAgICAgICAgICAgICAgICAtPnsgJEVudHJ5LT5bMF0gfSwKICAgICAgICAgICAgICAgICAgICBOYW1lICA9PiAkRW50cnktPlswXSwKICAgICAgICAgICAgICAgICAgICBDbGFzcyA9PiAiJE9wdGlvblJlcXVpcmVkIE1vZGVybml6ZSAiIC4KICAgICAgICAgICAgICAgICAgICAgICAgKCAkUGFyYW17RXJyb3JzfS0+eyAkRW50cnktPlswXSAuICdJbnZhbGlkJyB9IHx8ICcnICksCiAgICAgICAgICAgICAgICAgICAgVHJhbnNsYXRpb24gPT4gMCwKICAgICAgICAgICAgICAgICAgICBTZWxlY3RlZElEICA9PiAkUGFyYW17ICRFbnRyeS0+WzBdIH0sCiAgICAgICAgICAgICAgICAgICAgTWF4ICAgICAgICAgPT4gMzUsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNpZiAoICRFbnRyeS0+WzBdID1+IC9eQ3VzdG9tZXJDb21wYW55Q291bnRyeS9pICkgewogICAgICAgICAgICAgICAgbXkgJE9wdGlvblJlcXVpcmVkID0gJyc7CiAgICAgICAgICAgICAgICBpZiAoICRFbnRyeS0+WzRdICkgewogICAgICAgICAgICAgICAgICAgICRPcHRpb25SZXF1aXJlZCA9ICdWYWxpZGF0ZV9SZXF1aXJlZCc7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyBidWlsZCBDb3VudHJ5IHN0cmluZwogICAgICAgICAgICAgICAgbXkgJENvdW50cnlMaXN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlJlZmVyZW5jZURhdGEnKS0+Q291bnRyeUxpc3QoKTsKCiAgICAgICAgICAgICAgICAkQmxvY2sgPSAnT3B0aW9uJzsKICAgICAgICAgICAgICAgICRQYXJhbXtPcHRpb259ID0gJExheW91dE9iamVjdC0+QnVpbGRTZWxlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgRGF0YSAgICAgICAgID0+ICRDb3VudHJ5TGlzdCwKICAgICAgICAgICAgICAgICAgICBQb3NzaWJsZU5vbmUgPT4gMSwKICAgICAgICAgICAgICAgICAgICBTb3J0ICAgICAgICAgPT4gJ0FscGhhbnVtZXJpY1ZhbHVlJywKICAgICAgICAgICAgICAgICAgICBOYW1lICAgICAgICAgPT4gJEVudHJ5LT5bMF0sCiAgICAgICAgICAgICAgICAgICAgQ2xhc3MgICAgICAgID0+ICIkT3B0aW9uUmVxdWlyZWQgTW9kZXJuaXplICIgLgogICAgICAgICAgICAgICAgICAgICAgICAoICRQYXJhbXtFcnJvcnN9LT57ICRFbnRyeS0+WzBdIC4gJ0ludmFsaWQnIH0gfHwgJycgKSwKICAgICAgICAgICAgICAgICAgICBTZWxlY3RlZElEID0+IGRlZmluZWQoICRQYXJhbXsgJEVudHJ5LT5bMF0gfSApID8gJFBhcmFteyAkRW50cnktPlswXSB9IDogMSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzaWYgKCAkRW50cnktPlswXSA9fiAvXlZhbGlkSUQvaSApIHsKICAgICAgICAgICAgICAgIG15ICRPcHRpb25SZXF1aXJlZCA9ICcnOwogICAgICAgICAgICAgICAgaWYgKCAkRW50cnktPls0XSApIHsKICAgICAgICAgICAgICAgICAgICAkT3B0aW9uUmVxdWlyZWQgPSAnVmFsaWRhdGVfUmVxdWlyZWQnOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICMgYnVpbGQgVmFsaWRJRCBzdHJpbmcKICAgICAgICAgICAgICAgICRCbG9jayA9ICdPcHRpb24nOwogICAgICAgICAgICAgICAgJFBhcmFte09wdGlvbn0gPSAkTGF5b3V0T2JqZWN0LT5CdWlsZFNlbGVjdGlvbigKICAgICAgICAgICAgICAgICAgICBEYXRhICA9PiB7ICRWYWxpZE9iamVjdC0+VmFsaWRMaXN0KCksIH0sCiAgICAgICAgICAgICAgICAgICAgTmFtZSAgPT4gJEVudHJ5LT5bMF0sCiAgICAgICAgICAgICAgICAgICAgQ2xhc3MgPT4gIiRPcHRpb25SZXF1aXJlZCBNb2Rlcm5pemUgIiAuCiAgICAgICAgICAgICAgICAgICAgICAgICggJFBhcmFte0Vycm9yc30tPnsgJEVudHJ5LT5bMF0gLiAnSW52YWxpZCcgfSB8fCAnJyApLAogICAgICAgICAgICAgICAgICAgIFNlbGVjdGVkSUQgPT4gZGVmaW5lZCggJFBhcmFteyAkRW50cnktPlswXSB9ICkgPyAkUGFyYW17ICRFbnRyeS0+WzBdIH0gOiAxLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAjIC0tLQogICAgICAgICAgICAjIFJvdGhlck9TUzogQnVpbGQgdGhlIGdyb3VwIGZpZWxkLgogICAgICAgICAgICAjIC0tLQogICAgICAgICAgICBlbHNpZiAoICRFbnRyeS0+WzBdID1+IC9eVXNlckdyb3VwSUQkL2kgKSB7CiAgICAgICAgICAgICAgICAjIENoZWNrIGlmIHRoZSB1c2VyIGhhcyB0aGUgcGVybWlzc2lvbiB0byBzZWUvY2hhbmdlIHRoZSBtdWx0aXRlbmFuY3kgZmllbGQuCiAgICAgICAgICAgICAgICBpZiAoICEkU2VsZi0+e011bHRpdGVuYW5jeVBlcm1pc3Npb259ICkgewogICAgICAgICAgICAgICAgICAgIG5leHQgRU5UUlk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICMgQnVpbGQgdGhlIGZpZWxkLgogICAgICAgICAgICAgICAgICAgICRCbG9jayA9ICdPcHRpb24nOwogICAgICAgICAgICAgICAgICAgICRQYXJhbXtPcHRpb259ID0gJExheW91dE9iamVjdC0+QnVpbGRTZWxlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Okdyb3VwJyktPkdyb3VwTGlzdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWxpZCA9PiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBOYW1lICAgICAgICAgPT4gJEVudHJ5LT5bMF0sCiAgICAgICAgICAgICAgICAgICAgICAgIFBvc3NpYmxlTm9uZSA9PiAxLAogICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyAgICAgICAgPT4gJ01vZGVybml6ZSAnIC4gKCAkUGFyYW17RXJyb3JzfS0+eyAkRW50cnktPlswXSAuICdJbnZhbGlkJyB9IHx8ICcnICksCiAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGVkSUQgICA9PiAkUGFyYW17ICRFbnRyeS0+WzBdIH0gfHwgJycsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAjIC0tLSAKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkUGFyYW17VmFsdWV9ID0gJFBhcmFteyAkRW50cnktPlswXSB9IHx8ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAjIHNob3cgcmVxdWlyZWQgZmxhZwogICAgICAgICAgICBpZiAoICRFbnRyeS0+WzRdICkgewogICAgICAgICAgICAgICAgJFBhcmFte01hbmRhdG9yeUNsYXNzfSA9ICdjbGFzcz0iTWFuZGF0b3J5Iic7CiAgICAgICAgICAgICAgICAkUGFyYW17U3RhckxhYmVsfSAgICAgID0gJzxzcGFuIGNsYXNzPSJNYXJrZXIiPio8L3NwYW4+JzsKICAgICAgICAgICAgICAgICRQYXJhbXtSZXF1aXJlZENsYXNzfSAgPSAnVmFsaWRhdGVfUmVxdWlyZWQnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJFBhcmFte01hbmRhdG9yeUNsYXNzfSA9ICcnOwogICAgICAgICAgICAgICAgJFBhcmFte1N0YXJMYWJlbH0gICAgICA9ICcnOwogICAgICAgICAgICAgICAgJFBhcmFte1JlcXVpcmVkQ2xhc3N9ICA9ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAjIHNob3cgcmVxdWlyZWQgZmxhZwogICAgICAgICAgICBpZiAoICRFbnRyeS0+WzddICkgewogICAgICAgICAgICAgICAgJFBhcmFte1JlYWRPbmx5VHlwZX0gPSAncmVhZG9ubHk9InJlYWRvbmx5Iic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkUGFyYW17UmVhZE9ubHlUeXBlfSA9ICcnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAjIGFkZCBmb3JtIG9wdGlvbgogICAgICAgICAgICBpZiAoICRQYXJhbXtUeXBlfSAmJiAkUGFyYW17VHlwZX0gZXEgJ2hpZGRlbicgKSB7CiAgICAgICAgICAgICAgICAkUGFyYW17UHJlZmVyZW5jZXN9IC49ICRQYXJhbXtWYWx1ZX07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdQcmVmZXJlbmNlc0dlbmVyaWMnLAogICAgICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgICAgICBJdGVtID0+ICRFbnRyeS0+WzFdLAogICAgICAgICAgICAgICAgICAgICAgICAlUGFyYW0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gIlByZWZlcmVuY2VzR2VuZXJpYyRCbG9jayIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgSXRlbSAgICAgICAgID0+ICRFbnRyeS0+WzFdLAogICAgICAgICAgICAgICAgICAgICAgICBOYW1lICAgICAgICAgPT4gJEVudHJ5LT5bMF0sCiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlICAgICAgICA9PiAkUGFyYW17ICRFbnRyeS0+WzBdIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIEludmFsaWRGaWVsZCA9PiAkUGFyYW17RXJyb3JzfS0+eyAkRW50cnktPlswXSAuICdJbnZhbGlkJyB9IHx8ICcnLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKCAkRW50cnktPls0XSApIHsKICAgICAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAiUHJlZmVyZW5jZXNHZW5lcmljJHtCbG9ja31SZXF1aXJlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAkRW50cnktPlswXSwKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAxOwp9CgpzdWIgX092ZXJ2aWV3IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKCiAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICBOYW1lID0+ICdPdmVydmlldycsCiAgICAgICAgRGF0YSA9PiBcJVBhcmFtLAogICAgKTsKCiAgICAkTGF5b3V0T2JqZWN0LT5CbG9jayggTmFtZSA9PiAnQWN0aW9uTGlzdCcgKTsKICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgIE5hbWUgPT4gJ0FjdGlvblNlYXJjaCcsCiAgICAgICAgRGF0YSA9PiBcJVBhcmFtLAogICAgKTsKCiAgICBteSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQ29tcGFueScpOwoKICAgICMgZ2V0IHdyaXRhYmxlIGRhdGEgc291cmNlcwogICAgbXkgJUN1c3RvbWVyQ29tcGFueVNvdXJjZSA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueVNvdXJjZUxpc3QoCiAgICAgICAgUmVhZE9ubHkgPT4gMCwKICAgICk7CgogICAgIyBvbmx5IHNob3cgQWRkIG9wdGlvbiBpZiB3ZSBoYXZlIGF0IGxlYXN0IG9uZSB3cml0YWJsZSBiYWNrZW5kCiAgICBpZiAoIHNjYWxhciBrZXlzICVDdXN0b21lckNvbXBhbnlTb3VyY2UgKSB7CiAgICAgICAgJFBhcmFte1NvdXJjZU9wdGlvbn0gPSAkTGF5b3V0T2JqZWN0LT5CdWlsZFNlbGVjdGlvbigKICAgICAgICAgICAgRGF0YSAgICAgICA9PiB7ICVDdXN0b21lckNvbXBhbnlTb3VyY2UsIH0sCiAgICAgICAgICAgIE5hbWUgICAgICAgPT4gJ1NvdXJjZScsCiAgICAgICAgICAgIFNlbGVjdGVkSUQgPT4gJFBhcmFte1NvdXJjZX0gfHwgJycsCiAgICAgICAgICAgIENsYXNzICAgICAgPT4gJ01vZGVybml6ZScsCiAgICAgICAgKTsKCiAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ0FjdGlvbkFkZCcsCiAgICAgICAgICAgIERhdGEgPT4gXCVQYXJhbSwKICAgICAgICApOwogICAgfQoKICAgICMgaWYgdGhlcmUgYXJlIGFueSByZWdpc3RyaWVzIHRvIHNlYXJjaCwgdGhlIHRhYmxlIGlzIGZpbGxlZCBhbmQgc2hvd24KICAgIGlmICggJFBhcmFte1NlYXJjaH0gKSB7CgogICAgICAgICMgZ2V0IGNvbmZpZyBvYmplY3QKICAgICAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICAgICAgIyBzYW1lIExpbWl0IGFzICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+eydDdXN0b21lckNvbXBhbnlTZWFyY2hMaXN0TGltaXQnfQogICAgICAgICMgc21hbGxlc3QgTGltaXQgZnJvbSBhbGwgc291cmNlcwogICAgICAgIG15ICRMaW1pdCA9IDQwMDsKICAgICAgICBTT1VSQ0U6CiAgICAgICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewogICAgICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lckNvbXBhbnkkQ291bnQiKTsKICAgICAgICAgICAgbXkgJEN1c3RvbWVyVXNlck1hcCA9ICRDb25maWdPYmplY3QtPkdldCgiQ3VzdG9tZXJDb21wYW55JENvdW50Iik7CiAgICAgICAgICAgIG5leHQgU09VUkNFIGlmICEkQ3VzdG9tZXJVc2VyTWFwLT57Q3VzdG9tZXJDb21wYW55U2VhcmNoTGlzdExpbWl0fTsKICAgICAgICAgICAgaWYgKCAkQ3VzdG9tZXJVc2VyTWFwLT57Q3VzdG9tZXJDb21wYW55U2VhcmNoTGlzdExpbWl0fSA8ICRMaW1pdCApIHsKICAgICAgICAgICAgICAgICRMaW1pdCA9ICRDdXN0b21lclVzZXJNYXAtPntDdXN0b21lckNvbXBhbnlTZWFyY2hMaXN0TGltaXR9OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBteSAlTGlzdEFsbEl0ZW1zID0gJEN1c3RvbWVyQ29tcGFueU9iamVjdC0+Q3VzdG9tZXJDb21wYW55TGlzdCgKICAgICAgICAgICAgU2VhcmNoID0+ICRQYXJhbXtTZWFyY2h9LAogICAgICAgICAgICBMaW1pdCAgPT4gJExpbWl0ICsgMSwKICAgICAgICAgICAgVmFsaWQgID0+IDAsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCBrZXlzICVMaXN0QWxsSXRlbXMgPD0gJExpbWl0ICkgewogICAgICAgICAgICBteSAkTGlzdEFsbEl0ZW1zID0ga2V5cyAlTGlzdEFsbEl0ZW1zOwogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ092ZXJ2aWV3SGVhZGVyJywKICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgIExpc3RBbGwgPT4gJExpc3RBbGxJdGVtcywKICAgICAgICAgICAgICAgICAgICBMaW1pdCAgID0+ICRMaW1pdCwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBteSAlTGlzdCA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueUxpc3QoCiAgICAgICAgICAgIFNlYXJjaCA9PiAkUGFyYW17U2VhcmNofSwKICAgICAgICAgICAgVmFsaWQgID0+IDAsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCBrZXlzICVMaXN0QWxsSXRlbXMgPiAkTGltaXQgKSB7CiAgICAgICAgICAgIG15ICRMaXN0QWxsSXRlbXMgICA9IGtleXMgJUxpc3RBbGxJdGVtczsKICAgICAgICAgICAgbXkgJFNlYXJjaExpc3RTaXplID0ga2V5cyAlTGlzdDsKCiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXdIZWFkZXInLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgU2VhcmNoTGlzdFNpemUgPT4gJFNlYXJjaExpc3RTaXplLAogICAgICAgICAgICAgICAgICAgIExpc3RBbGwgICAgICAgID0+ICRMaXN0QWxsSXRlbXMsCiAgICAgICAgICAgICAgICAgICAgTGltaXQgICAgICAgICAgPT4gJExpbWl0LAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICBOYW1lID0+ICdPdmVydmlld1Jlc3VsdCcsCiAgICAgICAgICAgIERhdGEgPT4gXCVQYXJhbSwKICAgICAgICApOwoKICAgICAgICAjIGdldCB2YWxpZCBsaXN0CiAgICAgICAgbXkgJVZhbGlkTGlzdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcpLT5WYWxpZExpc3QoKTsKCiAgICAgICAgaWYgKCAhJENvbmZpZ09iamVjdC0+R2V0KCAkUGFyYW17U291cmNlfSApLT57UGFyYW1zfS0+e0ZvcmVpZ25EQn0gKSB7CiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKCBOYW1lID0+ICdMb2NhbERCJyApOwogICAgICAgIH0KCiAgICAgICAgIyBpZiB0aGVyZSBhcmUgcmVzdWx0cyB0byBzaG93CiAgICAgICAgaWYgKCVMaXN0KSB7CiAgICAgICAgICAgIGZvciBteSAkTGlzdEtleSAoIHNvcnQgeyAkTGlzdHskYX0gY21wICRMaXN0eyRifSB9IGtleXMgJUxpc3QgKSB7CgogICAgICAgICAgICAgICAgbXkgJURhdGEgPSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0LT5DdXN0b21lckNvbXBhbnlHZXQoIEN1c3RvbWVySUQgPT4gJExpc3RLZXkgKTsKICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJ092ZXJ2aWV3UmVzdWx0Um93JywKICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgJURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIFNlYXJjaCA9PiAkUGFyYW17U2VhcmNofSwKICAgICAgICAgICAgICAgICAgICAgICAgTmF2ICAgID0+ICRQYXJhbXtOYXZ9LAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGlmICggISRDb25maWdPYmplY3QtPkdldCggJFBhcmFte1NvdXJjZX0gKS0+e1BhcmFtc30tPntGb3JlaWduREJ9ICkgewogICAgICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdMb2NhbERCUm93JywKICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWxpZCA9PiAkVmFsaWRMaXN0eyAkRGF0YXtWYWxpZElEfSB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgb3RoZXJ3aXNlIGl0IGRpc3BsYXlzIGEgbm8gZGF0YSBmb3VuZCBtZXNzYWdlCiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnTm9EYXRhRm91bmRNc2cnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7fSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgIyBpZiB0aGVyZSBpcyBub3RoaW5nIHRvIHNlYXJjaCBpdCBzaG93cyBhIG1lc3NhZ2UKICAgIGVsc2UKICAgIHsKICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnTm9TZWFyY2hUZXJtcycsCiAgICAgICAgICAgIERhdGEgPT4ge30sCiAgICAgICAgKTsKICAgIH0KICAgIHJldHVybiAxOwp9CgoxOwo=
IyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIxIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDIxIFpudW55IEdtYkgsIGh0dHBzOi8vem51bnkub3JnLwojIENvcHlyaWdodCAoQykgMjAyMSBSb3RoZXIgT1NTIEdtYkgsIGh0dHBzOi8vcm90aGVyLW9zcy5jb20vCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0zLjAudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6TW9kdWxlczo6QWRtaW5DdXN0b21lclVzZXI7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OkNoZWNrSXRlbTsKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYXJpYWJsZUNoZWNrIHF3KDphbGwpOwp1c2UgS2VybmVsOjpMYW5ndWFnZSBxdyhUcmFuc2xhdGFibGUpOwoKb3VyICRPYmplY3RNYW5hZ2VyRGlzYWJsZWQgPSAxOwoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7JVBhcmFtfTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlncyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKS0+RHluYW1pY0ZpZWxkTGlzdEdldCgKICAgICAgICBPYmplY3RUeXBlID0+ICdDdXN0b21lclVzZXInLAogICAgKTsKCiAgICAkU2VsZi0+e0R5bmFtaWNGaWVsZExvb2t1cH0gPSB7IG1hcCB7ICRfLT57TmFtZX0gPT4gJF8gfSBAeyREeW5hbWljRmllbGRDb25maWdzfSB9OwoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFJ1biB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRQYXJhbU9iamVjdCAgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6V2ViOjpSZXF1ZXN0Jyk7CiAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICBteSAkTmF2ICAgID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ05hdicgKSAgICB8fCAnJzsKICAgIG15ICRTb3VyY2UgPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnU291cmNlJyApIHx8ICdDdXN0b21lclVzZXInOwogICAgbXkgJFNlYXJjaCA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdTZWFyY2gnICk7CiAgICAkU2VhcmNoCiAgICAgICAgfHw9ICRDb25maWdPYmplY3QtPkdldCgnQWRtaW5DdXN0b21lclVzZXI6OlJ1bkluaXRpYWxXaWxkY2FyZFNlYXJjaCcpID8gJyonIDogJyc7CgogICAgIyBjcmVhdGUgbG9jYWwgb2JqZWN0CiAgICBteSAkQ2hlY2tJdGVtT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNoZWNrSXRlbScpOwoKICAgIG15ICROYXZCYXIgICAgICAgPSAnJzsKICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CiAgICBpZiAoICROYXYgZXEgJ05vbmUnICkgewogICAgICAgICROYXZCYXIgPSAkTGF5b3V0T2JqZWN0LT5IZWFkZXIoIFR5cGUgPT4gJ1NtYWxsJyApOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgJE5hdkJhciA9ICRMYXlvdXRPYmplY3QtPkhlYWRlcigpOwogICAgICAgICROYXZCYXIgLj0gJExheW91dE9iamVjdC0+TmF2aWdhdGlvbkJhcigKICAgICAgICAgICAgVHlwZSA9PiAkTmF2IGVxICdBZ2VudCcgPyAnQ3VzdG9tZXJzJyA6ICdBZG1pbicsCiAgICAgICAgKTsKICAgIH0KCiAgICAjIEdldCBsaXN0IG9mIHZhbGlkIElEcy4KICAgIG15IEBWYWxpZElETGlzdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcpLT5WYWxpZElEc0dldCgpOwoKICAgICMgY2hlY2sgdGhlIHBlcm1pc3Npb24gZm9yIHRoZSBTd2l0Y2hUb0N1c3RvbWVyIGZlYXR1cmUKICAgIGlmICggJENvbmZpZ09iamVjdC0+R2V0KCdTd2l0Y2hUb0N1c3RvbWVyJykgKSB7CgogICAgICAgIG15ICRHcm91cE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpHcm91cCcpOwoKICAgICAgICAjIGdldCB0aGUgZ3JvdXAgaWQgd2hpY2ggaXMgYWxsb3dlZCB0byB1c2UgdGhlIHN3aXRjaCB0byBjdXN0b21lciBmZWF0dXJlCiAgICAgICAgbXkgJFN3aXRjaFRvQ3VzdG9tZXJHcm91cElEID0gJEdyb3VwT2JqZWN0LT5Hcm91cExvb2t1cCgKICAgICAgICAgICAgR3JvdXAgPT4gJENvbmZpZ09iamVjdC0+R2V0KCdTd2l0Y2hUb0N1c3RvbWVyOjpQZXJtaXNzaW9uR3JvdXAnKSwKICAgICAgICApOwoKICAgICAgICAjIGdldCB1c2VyIGdyb3Vwcywgd2hlcmUgdGhlIHVzZXIgaGFzIHRoZSBydyBwcml2aWxlZ2UKICAgICAgICBteSAlR3JvdXBzID0gJEdyb3VwT2JqZWN0LT5QZXJtaXNzaW9uVXNlckdldCgKICAgICAgICAgICAgVXNlcklEID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICAgICAgVHlwZSAgID0+ICdydycsCiAgICAgICAgKTsKCiAgICAgICAgIyBpZiB0aGUgdXNlciBpcyBhIG1lbWJlciBpbiB0aGlzIGdyb3VwIGhlIGNhbiBhY2Nlc3MgdGhlIGZlYXR1cmUKICAgICAgICBpZiAoICRHcm91cHN7JFN3aXRjaFRvQ3VzdG9tZXJHcm91cElEfSApIHsKICAgICAgICAgICAgJFNlbGYtPntTd2l0Y2hUb0N1c3RvbWVyUGVybWlzc2lvbn0gPSAxOwogICAgICAgIH0KICAgIH0KCiAgICBteSAkQ3VzdG9tZXJVc2VyT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlcicpOwogICAgbXkgJE1haW5PYmplY3QgICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpNYWluJyk7CgogICAgIyAtLS0KICAgICMgUm90aGVyT1NTOgogICAgIyAtLS0KICAgICMgQ2hlY2sgaWYgdGhlIHVzZXIgaGFzIHBlcm1pc3Npb24gdG8gc2V0IG11bHRpdGVuYW5jeS4KICAgIGlmICggJENvbmZpZ09iamVjdC0+R2V0KCdNdWx0aXRlbmFuY3knKSApIHsKICAgICAgICBteSAkR3JvdXBPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnKTsKCiAgICAgICAgbXkgJE11bHRpdGVuYW5jeUdyb3VwSUQgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnKS0+R3JvdXBMb29rdXAoCiAgICAgICAgICAgIEdyb3VwID0+ICRDb25maWdPYmplY3QtPkdldCgnTXVsdGl0ZW5hbmN5OjpQZXJtaXNzaW9uR3JvdXAnKSwKICAgICAgICApOwoKICAgICAgICBteSAlR3JvdXBzID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Okdyb3VwJyktPlBlcm1pc3Npb25Vc2VyR2V0KAogICAgICAgICAgICBVc2VySUQgPT4gJFNlbGYtPntVc2VySUR9LAogICAgICAgICAgICBUeXBlICAgPT4gJ3J3JywKICAgICAgICApOwoKICAgICAgICBpZiAoICRHcm91cHN7JE11bHRpdGVuYW5jeUdyb3VwSUR9ICkgewogICAgICAgICAgICAkU2VsZi0+e011bHRpdGVuYW5jeVBlcm1pc3Npb259ID0gMTsKICAgICAgICB9CiAgICB9CiAgICAjIC0tLQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgICMgIHN3aXRjaCB0byBjdXN0b21lcgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgaWYgKAogICAgICAgICRTZWxmLT57U3ViYWN0aW9ufSBlcSAnU3dpdGNoJwogICAgICAgICYmICRDb25maWdPYmplY3QtPkdldCgnU3dpdGNoVG9DdXN0b21lcicpCiAgICAgICAgJiYgJFNlbGYtPntTd2l0Y2hUb0N1c3RvbWVyUGVybWlzc2lvbn0KICAgICAgICApCiAgICB7CgogICAgICAgICMgY2hhbGxlbmdlIHRva2VuIGNoZWNrIGZvciB3cml0ZSBhY3Rpb24KICAgICAgICAkTGF5b3V0T2JqZWN0LT5DaGFsbGVuZ2VUb2tlbkNoZWNrKCk7CgogICAgICAgICMgZ2V0IHVzZXIgZGF0YQogICAgICAgIG15ICRVc2VySUQgICA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdJRCcgKSB8fCAnJzsKICAgICAgICBteSAlVXNlckRhdGEgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KAogICAgICAgICAgICBVc2VyICA9PiAkVXNlcklELAogICAgICAgICAgICBWYWxpZCA9PiAxLAogICAgICAgICk7CgogICAgICAgICMgY3JlYXRlIG5ldyBzZXNzaW9uIGlkCiAgICAgICAgbXkgJE5ld1Nlc3Npb25JRCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpBdXRoU2Vzc2lvbicpLT5DcmVhdGVTZXNzaW9uSUQoCiAgICAgICAgICAgICVVc2VyRGF0YSwKICAgICAgICAgICAgVXNlckxhc3RSZXF1ZXN0ID0+ICRLZXJuZWw6Ok9NLT5DcmVhdGUoJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScpLT5Ub0Vwb2NoKCksCiAgICAgICAgICAgIFVzZXJUeXBlICAgICAgICA9PiAnQ3VzdG9tZXInLAogICAgICAgICAgICBTZXNzaW9uU291cmNlICAgPT4gJ0N1c3RvbWVySW50ZXJmYWNlJywKICAgICAgICApOwoKICAgICAgICAjIGdldCBjdXN0b21lciBpbnRlcmZhY2Ugc2Vzc2lvbiBuYW1lCiAgICAgICAgbXkgJFNlc3Npb25OYW1lID0gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsU2Vzc2lvbk5hbWUnKSB8fCAnQ1NJRCc7CgogICAgICAgICMgY3JlYXRlIGEgbmV3IExheW91dE9iamVjdCB3aXRoIFNlc3Npb25JRENvb2tpZQogICAgICAgIG15ICRFeHBpcmVzID0gJysnIC4gJENvbmZpZ09iamVjdC0+R2V0KCdTZXNzaW9uTWF4VGltZScpIC4gJ3MnOwogICAgICAgIGlmICggISRDb25maWdPYmplY3QtPkdldCgnU2Vzc2lvblVzZUNvb2tpZUFmdGVyQnJvd3NlckNsb3NlJykgKSB7CiAgICAgICAgICAgICRFeHBpcmVzID0gJyc7CiAgICAgICAgfQoKICAgICAgICBteSAkU2VjdXJlQXR0cmlidXRlOwogICAgICAgIGlmICggJENvbmZpZ09iamVjdC0+R2V0KCdIdHRwVHlwZScpIGVxICdodHRwcycgKSB7CgogICAgICAgICAgICAjIFJlc3RyaWN0IENvb2tpZSB0byBIVFRQUyBpZiBpdCBpcyB1c2VkLgogICAgICAgICAgICAkU2VjdXJlQXR0cmlidXRlID0gMTsKICAgICAgICB9CgogICAgICAgIG15ICRMYXlvdXRPYmplY3QgPSBLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0LT5uZXcoCiAgICAgICAgICAgICV7JFNlbGZ9LAogICAgICAgICAgICBTZXRDb29raWVzID0+IHsKICAgICAgICAgICAgICAgIFNlc3Npb25JRENvb2tpZSA9PiAkUGFyYW1PYmplY3QtPlNldENvb2tpZSgKICAgICAgICAgICAgICAgICAgICBLZXkgICAgICA9PiAkU2Vzc2lvbk5hbWUsCiAgICAgICAgICAgICAgICAgICAgVmFsdWUgICAgPT4gJE5ld1Nlc3Npb25JRCwKICAgICAgICAgICAgICAgICAgICBFeHBpcmVzICA9PiAkRXhwaXJlcywKICAgICAgICAgICAgICAgICAgICBQYXRoICAgICA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ1NjcmlwdEFsaWFzJyksCiAgICAgICAgICAgICAgICAgICAgU2VjdXJlICAgPT4gc2NhbGFyICRTZWN1cmVBdHRyaWJ1dGUsCiAgICAgICAgICAgICAgICAgICAgSFRUUE9ubHkgPT4gMSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIFNlc3Npb25JRCAgID0+ICROZXdTZXNzaW9uSUQsCiAgICAgICAgICAgIFNlc3Npb25OYW1lID0+ICRDb25maWdPYmplY3QtPkdldCgnU2Vzc2lvbk5hbWUnKSwKICAgICAgICApOwoKICAgICAgICAjIGxvZyBldmVudAogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnbm90aWNlJywKICAgICAgICAgICAgTWVzc2FnZSA9PgogICAgICAgICAgICAgICAgIlN3aXRjaGVkIGZyb20gQWdlbnQgdG8gQ3VzdG9tZXIgKCRTZWxmLT57VXNlckxvZ2lufSAtPT4gJFVzZXJEYXRhe1VzZXJMb2dpbn0pIiwKICAgICAgICApOwoKICAgICAgICAjIGJ1aWxkIFVSTCB0byBjdXN0b21lciBpbnRlcmZhY2UKICAgICAgICBteSAkVVJMID0gJENvbmZpZ09iamVjdC0+R2V0KCdIdHRwVHlwZScpCiAgICAgICAgICAgIC4gJzovLycKICAgICAgICAgICAgLiAkQ29uZmlnT2JqZWN0LT5HZXQoJ0ZRRE4nKQogICAgICAgICAgICAuICcvJwogICAgICAgICAgICAuICRDb25maWdPYmplY3QtPkdldCgnU2NyaXB0QWxpYXMnKQogICAgICAgICAgICAuICdjdXN0b21lci5wbCc7CgogICAgICAgICMgaWYgbm8gc2Vzc2lvbnMgYXJlIHVzZWQgd2UgYXR0YWNoIHRoZSBzZXNzaW9uIGFzIFVSTCBwYXJhbWV0ZXIKICAgICAgICBpZiAoICEkQ29uZmlnT2JqZWN0LT5HZXQoJ1Nlc3Npb25Vc2VDb29raWUnKSApIHsKICAgICAgICAgICAgJFVSTCAuPSAiPyRTZXNzaW9uTmFtZT0kTmV3U2Vzc2lvbklEIjsKICAgICAgICB9CgogICAgICAgICMgcmVkaXJlY3QgdG8gY3VzdG9tZXIgaW50ZXJmYWNlIHdpdGggbmV3IHNlc3Npb24gaWQKICAgICAgICByZXR1cm4gJExheW91dE9iamVjdC0+UmVkaXJlY3QoIEV4dFVSTCA9PiAkVVJMICk7CiAgICB9CgogICAgIyBzZWFyY2ggdXNlciBsaXN0CiAgICBpZiAoICRTZWxmLT57U3ViYWN0aW9ufSBlcSAnU2VhcmNoJyApIHsKICAgICAgICAkU2VsZi0+X092ZXJ2aWV3KAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgU2VhcmNoID0+ICRTZWFyY2gsCiAgICAgICAgKTsKICAgICAgICBteSAkT3V0cHV0ID0gJE5hdkJhcjsKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyVXNlcicsCiAgICAgICAgICAgIERhdGEgICAgICAgICA9PiBcJVBhcmFtLAogICAgICAgICk7CgogICAgICAgIGlmICggJE5hdiBlcSAnTm9uZScgKSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCBUeXBlID0+ICdTbWFsbCcgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIGRvd25sb2FkIGZpbGUgcHJlZmVyZW5jZXMKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgIGVsc2lmICggJFNlbGYtPntTdWJhY3Rpb259IGVxICdEb3dubG9hZCcgKSB7CiAgICAgICAgbXkgJEdyb3VwID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ0dyb3VwJyApIHx8ICcnOwogICAgICAgIG15ICRVc2VyICA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdJRCcgKSAgICB8fCAnJzsKICAgICAgICBteSAkRmlsZSAgPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnRmlsZScgKSAgfHwgJyc7CgogICAgICAgICMgZ2V0IHVzZXIgZGF0YQogICAgICAgIG15ICVVc2VyRGF0YSAgICA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlckRhdGFHZXQoIFVzZXIgPT4gJFVzZXIgKTsKICAgICAgICBteSAlUHJlZmVyZW5jZXMgPSAleyAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUHJlZmVyZW5jZXNHcm91cHMnKSB9OwogICAgICAgIG15ICRNb2R1bGUgICAgICA9ICRQcmVmZXJlbmNlc3skR3JvdXB9LT57TW9kdWxlfTsKICAgICAgICBpZiAoICEkTWFpbk9iamVjdC0+UmVxdWlyZSgkTW9kdWxlKSApIHsKICAgICAgICAgICAgcmV0dXJuICRMYXlvdXRPYmplY3QtPkZhdGFsRXJyb3IoKTsKICAgICAgICB9CiAgICAgICAgbXkgJE9iamVjdCA9ICRNb2R1bGUtPm5ldygKICAgICAgICAgICAgJXskU2VsZn0sCiAgICAgICAgICAgIENvbmZpZ0l0ZW0gPT4gJFByZWZlcmVuY2VzeyRHcm91cH0sCiAgICAgICAgICAgIFVzZXJPYmplY3QgPT4gJEN1c3RvbWVyVXNlck9iamVjdCwKICAgICAgICAgICAgRGVidWcgICAgICA9PiAkU2VsZi0+e0RlYnVnfSwKICAgICAgICApOwogICAgICAgIG15ICVGaWxlID0gJE9iamVjdC0+RG93bmxvYWQoIFVzZXJEYXRhID0+IFwlVXNlckRhdGEgKTsKCiAgICAgICAgcmV0dXJuICRMYXlvdXRPYmplY3QtPkF0dGFjaG1lbnQoJUZpbGUpOwogICAgfQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgICMgY2hhbmdlCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICBlbHNpZiAoICRTZWxmLT57U3ViYWN0aW9ufSBlcSAnQ2hhbmdlJyApIHsKICAgICAgICBteSAkVXNlciAgICAgICAgID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ0lEJyApICAgICAgICAgICB8fCAnJzsKICAgICAgICBteSAkTm90aWZpY2F0aW9uID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ05vdGlmaWNhdGlvbicgKSB8fCAnJzsKCiAgICAgICAgIyBnZXQgdXNlciBkYXRhCiAgICAgICAgbXkgJVVzZXJEYXRhID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJVc2VyRGF0YUdldCggVXNlciA9PiAkVXNlciApOwoKICAgICAgICBteSAkT3V0cHV0ID0gJE5hdkJhcjsKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSggSW5mbyA9PiBUcmFuc2xhdGFibGUoJ0N1c3RvbWVyIHVwZGF0ZWQhJykgKQogICAgICAgICAgICBpZiAoICROb3RpZmljYXRpb24gJiYgJE5vdGlmaWNhdGlvbiBlcSAnVXBkYXRlJyApOwogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPl9FZGl0KAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgQWN0aW9uID0+ICdDaGFuZ2UnLAogICAgICAgICAgICBTb3VyY2UgPT4gJFNvdXJjZSwKICAgICAgICAgICAgU2VhcmNoID0+ICRTZWFyY2gsCiAgICAgICAgICAgIElEICAgICA9PiAkVXNlciwKICAgICAgICAgICAgJVVzZXJEYXRhLAogICAgICAgICk7CgogICAgICAgIGlmICggJE5hdiBlcSAnTm9uZScgKSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCBUeXBlID0+ICdTbWFsbCcgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIGNoYW5nZSBhY3Rpb24KICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgIGVsc2lmICggJFNlbGYtPntTdWJhY3Rpb259IGVxICdDaGFuZ2VBY3Rpb24nICkgewoKICAgICAgICAjIGNoYWxsZW5nZSB0b2tlbiBjaGVjayBmb3Igd3JpdGUgYWN0aW9uCiAgICAgICAgJExheW91dE9iamVjdC0+Q2hhbGxlbmdlVG9rZW5DaGVjaygpOwoKICAgICAgICAjIHVwZGF0ZSBvbmx5IHRoZSBwcmVmZXJlbmNlcyBhbmQgZHluYW1pYyBmaWVsZHMsIGlmIHRoZSBzb3VyY2UgaXMgcmVhZG9ubHkgb3IgYSBsZGFwIGJhY2tlbmQKICAgICAgICBteSAkVXBkYXRlT25seVByZWZlcmVuY2VzOwoKICAgICAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCgkU291cmNlKS0+e1JlYWRPbmx5fSB8fCAkQ29uZmlnT2JqZWN0LT5HZXQoJFNvdXJjZSktPntNb2R1bGV9ID1+IC9MREFQL2kgKSB7CiAgICAgICAgICAgICRVcGRhdGVPbmx5UHJlZmVyZW5jZXMgPSAxOwogICAgICAgIH0KCiAgICAgICAgbXkgJE5vdGUgPSAnJzsKICAgICAgICBteSAoICVHZXRQYXJhbSwgJUVycm9ycyApOwoKICAgICAgICAjIEdldCBkeW5hbWljIGZpZWxkIGJhY2tlbmQgb2JqZWN0LgogICAgICAgIG15ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDo6QmFja2VuZCcpOwoKICAgICAgICBFTlRSWToKICAgICAgICBmb3IgbXkgJEVudHJ5ICggQHsgJENvbmZpZ09iamVjdC0+R2V0KCRTb3VyY2UpLT57TWFwfSB9ICkgewogICAgICAgICAgICAjIGNoZWNrIGR5bmFtaWMgZmllbGRzCiAgICAgICAgICAgIGlmICggJEVudHJ5LT5bNV0gZXEgJ2R5bmFtaWNfZmllbGQnICkgewoKICAgICAgICAgICAgICAgIG15ICREeW5hbWljRmllbGRDb25maWcgPSAkU2VsZi0+e0R5bmFtaWNGaWVsZExvb2t1cH0tPnsgJEVudHJ5LT5bMl0gfTsKCiAgICAgICAgICAgICAgICBpZiAoICFJc0hhc2hSZWZXaXRoRGF0YSgkRHluYW1pY0ZpZWxkQ29uZmlnKSApIHsKICAgICAgICAgICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIkR5bmFtaWNGaWVsZCAkRW50cnktPlsyXSBub3QgZm91bmQhIiwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIG5leHQgRU5UUlk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbXkgJFZhbGlkYXRpb25SZXN1bHQgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+RWRpdEZpZWxkVmFsdWVWYWxpZGF0ZSgKICAgICAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZENvbmZpZywKICAgICAgICAgICAgICAgICAgICBQYXJhbU9iamVjdCAgICAgICAgPT4gJFBhcmFtT2JqZWN0LAogICAgICAgICAgICAgICAgICAgIE1hbmRhdG9yeSAgICAgICAgICA9PiAkRW50cnktPls0XSwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgaWYgKCAkVmFsaWRhdGlvblJlc3VsdC0+e1NlcnZlckVycm9yfSApIHsKICAgICAgICAgICAgICAgICAgICAkRXJyb3JzeyAkRW50cnktPlswXSB9ID0gJFZhbGlkYXRpb25SZXN1bHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKCiAgICAgICAgICAgICAgICAgICAgIyBnZW5lcmF0ZSBzdG9yYWJsZSB2YWx1ZSBvZiBkeW5hbWljIGZpZWxkIGVkaXQgZmllbGQKICAgICAgICAgICAgICAgICAgICAkR2V0UGFyYW17ICRFbnRyeS0+WzBdIH0gPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+RWRpdEZpZWxkVmFsdWVHZXQoCiAgICAgICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICBQYXJhbU9iamVjdCAgICAgICAgPT4gJFBhcmFtT2JqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICBMYXlvdXRPYmplY3QgICAgICAgPT4gJExheW91dE9iamVjdCwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAjIGNoZWNrIHJlbWFpbmluZyBub24tZHluYW1pYy1maWVsZCBtYW5kYXRvcnkgZmllbGRzCiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJEdldFBhcmFteyAkRW50cnktPlswXSB9ID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJEVudHJ5LT5bMF0gKSB8fCAnJzsKCiAgICAgICAgICAgICAgICBuZXh0IEVOVFJZIGlmICRVcGRhdGVPbmx5UHJlZmVyZW5jZXM7CgogICAgICAgICAgICAgICAgaWYgKCAhJEdldFBhcmFteyAkRW50cnktPlswXSB9ICYmICRFbnRyeS0+WzRdICkgewogICAgICAgICAgICAgICAgICAgICRFcnJvcnN7ICRFbnRyeS0+WzBdIC4gJ0ludmFsaWQnIH0gPSAnU2VydmVyRXJyb3InOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRHZXRQYXJhbXtJRH0gPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnSUQnICkgfHwgJyc7CgogICAgICAgICMgY2hlY2sgZW1haWwgYWRkcmVzcwogICAgICAgIGlmICgKICAgICAgICAgICAgISRVcGRhdGVPbmx5UHJlZmVyZW5jZXMKICAgICAgICAgICAgJiYgJEdldFBhcmFte1VzZXJFbWFpbH0KICAgICAgICAgICAgJiYgISRDaGVja0l0ZW1PYmplY3QtPkNoZWNrRW1haWwoIEFkZHJlc3MgPT4gJEdldFBhcmFte1VzZXJFbWFpbH0gKQogICAgICAgICAgICAmJiBncmVwIHsgJF8gZXEgJEdldFBhcmFte1ZhbGlkSUR9IH0gQFZhbGlkSURMaXN0CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICRFcnJvcnN7VXNlckVtYWlsSW52YWxpZH0gPSAnU2VydmVyRXJyb3InOwogICAgICAgICAgICAkRXJyb3Jze0Vycm9yVHlwZX0gICAgICAgID0gJENoZWNrSXRlbU9iamVjdC0+Q2hlY2tFcnJvclR5cGUoKSAuICdTZXJ2ZXJFcnJvck1zZyc7CiAgICAgICAgfQoKICAgICAgICAjIEdldCB0aGUgY3VycmVudCB1c2VyIGRhdGEgZm9yIHNvbWUgY2hlY2tzLgogICAgICAgIG15ICVDdXJyZW50VXNlckRhdGEgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KAogICAgICAgICAgICBVc2VyID0+ICRHZXRQYXJhbXtJRH0sCiAgICAgICAgKTsKCiAgICAgICAgIyBDaGVjayBDdXN0b21lcklELCBpZiBDdXN0b21lckNvbXBhbnlTdXBwb3J0IGlzIGVuYWJsZWQgYW5kIHRoZSBVc2VyQ3VzdG9tZXJJRCB3YXMgY2hhbmdlZC4KICAgICAgICBpZiAoCiAgICAgICAgICAgICRDb25maWdPYmplY3QtPkdldCgkU291cmNlKS0+e0N1c3RvbWVyQ29tcGFueVN1cHBvcnR9CiAgICAgICAgICAgICYmICRHZXRQYXJhbXtVc2VyQ3VzdG9tZXJJRH0KICAgICAgICAgICAgJiYgJEN1cnJlbnRVc2VyRGF0YXtVc2VyQ3VzdG9tZXJJRH0gbmUgJEdldFBhcmFte1VzZXJDdXN0b21lcklEfQogICAgICAgICAgICApCiAgICAgICAgewoKICAgICAgICAgICAgbXkgJUNvbXBhbnkgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJDb21wYW55JyktPkN1c3RvbWVyQ29tcGFueUdldCgKICAgICAgICAgICAgICAgIEN1c3RvbWVySUQgPT4gJEdldFBhcmFte1VzZXJDdXN0b21lcklEfSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGlmICggISVDb21wYW55ICkgewogICAgICAgICAgICAgICAgJEVycm9yc3tVc2VyQ3VzdG9tZXJJREludmFsaWR9ID0gJ1NlcnZlckVycm9yJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBpZiBubyBlcnJvcnMgb2NjdXJyZWQKICAgICAgICBpZiAoICElRXJyb3JzICkgewoKICAgICAgICAgICAgbXkgJFVwZGF0ZVN1Y2Nlc3M7CiAgICAgICAgICAgIGlmICggISRVcGRhdGVPbmx5UHJlZmVyZW5jZXMgKSB7CiAgICAgICAgICAgICAgICAkVXBkYXRlU3VjY2VzcyA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlclVwZGF0ZSgKICAgICAgICAgICAgICAgICAgICAlR2V0UGFyYW0sCiAgICAgICAgICAgICAgICAgICAgVXNlcklEID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggJFVwZGF0ZVN1Y2Nlc3MgfHwgJFVwZGF0ZU9ubHlQcmVmZXJlbmNlcyApIHsKCiAgICAgICAgICAgICAgICAjIHNldCBkeW5hbWljIGZpZWxkIHZhbHVlcwogICAgICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKTsKCiAgICAgICAgICAgICAgICBFTlRSWToKICAgICAgICAgICAgICAgIGZvciBteSAkRW50cnkgKCBAeyAkQ29uZmlnT2JqZWN0LT5HZXQoJFNvdXJjZSktPntNYXB9IH0gKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBFTlRSWSBpZiAkRW50cnktPls1XSBuZSAnZHluYW1pY19maWVsZCc7CgogICAgICAgICAgICAgICAgICAgIG15ICREeW5hbWljRmllbGRDb25maWcgPSAkU2VsZi0+e0R5bmFtaWNGaWVsZExvb2t1cH0tPnsgJEVudHJ5LT5bMl0gfTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCAhSXNIYXNoUmVmV2l0aERhdGEoJER5bmFtaWNGaWVsZENvbmZpZykgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICROb3RlIC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZm8gPT4gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdEeW5hbWljIGZpZWxkICVzIG5vdCBmb3VuZCEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRFbnRyeS0+WzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCBFTlRSWTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIG15ICRWYWx1ZVNldCA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5WYWx1ZVNldCgKICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdE5hbWUgICAgICAgICA9PiAkR2V0UGFyYW17VXNlckxvZ2lufSwKICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICAgICAgID0+ICRHZXRQYXJhbXsgJEVudHJ5LT5bMF0gfSwKICAgICAgICAgICAgICAgICAgICAgICAgVXNlcklEICAgICAgICAgICAgID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICBpZiAoICEkVmFsdWVTZXQgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICROb3RlIC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZm8gPT4gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVbmFibGUgdG8gc2V0IHZhbHVlIGZvciBkeW5hbWljIGZpZWxkICVzIScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJEVudHJ5LT5bMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICBuZXh0IEVOVFJZOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAjIHVwZGF0ZSBwcmVmZXJlbmNlcwogICAgICAgICAgICAgICAgbXkgJVByZWZlcmVuY2VzID0gJXsgJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclByZWZlcmVuY2VzR3JvdXBzJykgfTsKICAgICAgICAgICAgICAgIEdST1VQOgogICAgICAgICAgICAgICAgZm9yIG15ICRHcm91cCAoIHNvcnQga2V5cyAlUHJlZmVyZW5jZXMgKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBHUk9VUCBpZiAkR3JvdXAgZXEgJ1Bhc3N3b3JkJzsKCiAgICAgICAgICAgICAgICAgICAgIyBnZXQgdXNlciBkYXRhCiAgICAgICAgICAgICAgICAgICAgbXkgJVVzZXJEYXRhID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJVc2VyRGF0YUdldCgKICAgICAgICAgICAgICAgICAgICAgICAgVXNlciA9PiAkR2V0UGFyYW17VXNlckxvZ2lufQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgbXkgJE1vZHVsZSA9ICRQcmVmZXJlbmNlc3skR3JvdXB9LT57TW9kdWxlfTsKICAgICAgICAgICAgICAgICAgICBpZiAoICEkTWFpbk9iamVjdC0+UmVxdWlyZSgkTW9kdWxlKSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRMYXlvdXRPYmplY3QtPkZhdGFsRXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbXkgJE9iamVjdCA9ICRNb2R1bGUtPm5ldygKICAgICAgICAgICAgICAgICAgICAgICAgJXskU2VsZn0sCiAgICAgICAgICAgICAgICAgICAgICAgIENvbmZpZ0l0ZW0gPT4gJFByZWZlcmVuY2VzeyRHcm91cH0sCiAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJPYmplY3QgPT4gJEN1c3RvbWVyVXNlck9iamVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgRGVidWcgICAgICA9PiAkU2VsZi0+e0RlYnVnfSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIG15IEBQYXJhbXMgPSAkT2JqZWN0LT5QYXJhbSggVXNlckRhdGEgPT4gXCVVc2VyRGF0YSApOwogICAgICAgICAgICAgICAgICAgIGlmIChAUGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG15ICVHZXRQYXJhbTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIG15ICRQYXJhbUl0ZW0gKEBQYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15IEBBcnJheSA9ICRQYXJhbU9iamVjdC0+R2V0QXJyYXkoIFBhcmFtID0+ICRQYXJhbUl0ZW0tPntOYW1lfSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJEdldFBhcmFteyAkUGFyYW1JdGVtLT57TmFtZX0gfSA9IFxAQXJyYXk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgISRPYmplY3QtPlJ1bigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRQYXJhbSA9PiBcJUdldFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJEYXRhID0+IFwlVXNlckRhdGEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJE5vdGUgLj0gJExheW91dE9iamVjdC0+Tm90aWZ5KCBJbmZvID0+ICRPYmplY3QtPkVycm9yKCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAjIGNsZWFyIGN1c3RvbWVyIHVzZXIgY2FjaGUKICAgICAgICAgICAgICAgICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlckNhY2hlQ2xlYXIoCiAgICAgICAgICAgICAgICAgICAgVXNlckxvZ2luID0+ICRHZXRQYXJhbXtVc2VyTG9naW59LAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAjIGdldCB1c2VyIGRhdGEgYW5kIHNob3cgc2NyZWVuIGFnYWluCiAgICAgICAgICAgICAgICBpZiAoICEkTm90ZSApIHsKCiAgICAgICAgICAgICAgICAgICAgIyBpZiB0aGUgdXNlciB3b3VsZCBsaWtlIHRvIGNvbnRpbnVlIGVkaXRpbmcgdGhlIHByaW9yaXR5LCBqdXN0IHJlZGlyZWN0IHRvIHRoZSBlZGl0IHNjcmVlbgogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgZGVmaW5lZCAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnQ29udGludWVBZnRlclNhdmUnICkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKCAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnQ29udGludWVBZnRlclNhdmUnICkgZXEgJzEnICkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbXkgJElEID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ0lEJyApIHx8ICcnOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJExheW91dE9iamVjdC0+UmVkaXJlY3QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUCA9PgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBY3Rpb249JFNlbGYtPntBY3Rpb259O1N1YmFjdGlvbj1DaGFuZ2U7SUQ9JElEO1NlYXJjaD0kU2VhcmNoO05hdj0kTmF2O05vdGlmaWNhdGlvbj1VcGRhdGUiCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewoKICAgICAgICAgICAgICAgICAgICAgICAgIyBvdGhlcndpc2UgcmV0dXJuIHRvIG92ZXJ2aWV3CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkTGF5b3V0T2JqZWN0LT5SZWRpcmVjdCggT1AgPT4gIkFjdGlvbj0kU2VsZi0+e0FjdGlvbn07Tm90aWZpY2F0aW9uPVVwZGF0ZSIgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkTm90ZSAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoIFByaW9yaXR5ID0+ICdFcnJvcicgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBzb21ldGhpbmcgaGFzIGdvbmUgd3JvbmcKICAgICAgICBteSAkT3V0cHV0ID0gJE5hdkJhcjsKICAgICAgICAkT3V0cHV0IC49ICROb3RlOwogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPl9FZGl0KAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgQWN0aW9uID0+ICdDaGFuZ2UnLAogICAgICAgICAgICBTb3VyY2UgPT4gJFNvdXJjZSwKICAgICAgICAgICAgU2VhcmNoID0+ICRTZWFyY2gsCiAgICAgICAgICAgIEVycm9ycyA9PiBcJUVycm9ycywKICAgICAgICAgICAgJUdldFBhcmFtLAogICAgICAgICk7CgogICAgICAgIGlmICggJE5hdiBlcSAnTm9uZScgKSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCBUeXBlID0+ICdTbWFsbCcgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIGFkZAogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgZWxzaWYgKCAkU2VsZi0+e1N1YmFjdGlvbn0gZXEgJ0FkZCcgKSB7CiAgICAgICAgbXkgJUdldFBhcmFtOwogICAgICAgICRHZXRQYXJhbXtVc2VyTG9naW59ICA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdVc2VyTG9naW4nICkgIHx8ICcnOwogICAgICAgICRHZXRQYXJhbXtDdXN0b21lcklEfSA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdDdXN0b21lcklEJyApIHx8ICcnOwogICAgICAgIG15ICRPdXRwdXQgPSAkTmF2QmFyOwogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPl9FZGl0KAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgQWN0aW9uID0+ICdBZGQnLAogICAgICAgICAgICBTb3VyY2UgPT4gJFNvdXJjZSwKICAgICAgICAgICAgU2VhcmNoID0+ICRTZWFyY2gsCiAgICAgICAgICAgICVHZXRQYXJhbSwKICAgICAgICApOwoKICAgICAgICBpZiAoICROYXYgZXEgJ05vbmUnICkgewogICAgICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPkZvb3RlciggVHlwZSA9PiAnU21hbGwnICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPkZvb3RlcigpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRPdXRwdXQ7CiAgICB9CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBhZGQgYWN0aW9uCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICBlbHNpZiAoICRTZWxmLT57U3ViYWN0aW9ufSBlcSAnQWRkQWN0aW9uJyApIHsKCiAgICAgICAgIyBjaGFsbGVuZ2UgdG9rZW4gY2hlY2sgZm9yIHdyaXRlIGFjdGlvbgogICAgICAgICRMYXlvdXRPYmplY3QtPkNoYWxsZW5nZVRva2VuQ2hlY2soKTsKCiAgICAgICAgbXkgJE5vdGUgPSAnJzsKICAgICAgICBteSAoICVHZXRQYXJhbSwgJUVycm9ycyApOwoKICAgICAgICBteSAkQXV0b0xvZ2luQ3JlYXRpb24gPSAkQ29uZmlnT2JqZWN0LT5HZXQoJFNvdXJjZSktPntBdXRvTG9naW5DcmVhdGlvbn07CgogICAgICAgICMgR2V0IGR5bmFtaWMgZmllbGQgYmFja2VuZCBvYmplY3QuCiAgICAgICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CgogICAgICAgIEVOVFJZOgogICAgICAgIGZvciBteSAkRW50cnkgKCBAeyAkQ29uZmlnT2JqZWN0LT5HZXQoJFNvdXJjZSktPntNYXB9IH0gKSB7CgogICAgICAgICAgICAjIGRvbid0IHZhbGlkYXRlIFVzZXJMb2dpbiBpZiBBdXRvTG9naW5DcmVhdGlvbiBpcyBjb25maWd1cmVkCiAgICAgICAgICAgIG5leHQgRU5UUlkgaWYgKCAkQXV0b0xvZ2luQ3JlYXRpb24gJiYgJEVudHJ5LT5bMF0gZXEgJ1VzZXJMb2dpbicgKTsKCiAgICAgICAgICAgICMgY2hlY2sgZHluYW1pYyBmaWVsZHMKICAgICAgICAgICAgaWYgKCAkRW50cnktPls1XSBlcSAnZHluYW1pY19maWVsZCcgKSB7CgogICAgICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZENvbmZpZyA9ICRTZWxmLT57RHluYW1pY0ZpZWxkTG9va3VwfS0+eyAkRW50cnktPlsyXSB9OwoKICAgICAgICAgICAgICAgIGlmICggIUlzSGFzaFJlZldpdGhEYXRhKCREeW5hbWljRmllbGRDb25maWcpICkgewogICAgICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiRHluYW1pY0ZpZWxkICRFbnRyeS0+WzJdIG5vdCBmb3VuZCEiLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBFTlRSWTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBteSAkVmFsaWRhdGlvblJlc3VsdCA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5FZGl0RmllbGRWYWx1ZVZhbGlkYXRlKAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLAogICAgICAgICAgICAgICAgICAgIFBhcmFtT2JqZWN0ICAgICAgICA9PiAkUGFyYW1PYmplY3QsCiAgICAgICAgICAgICAgICAgICAgTWFuZGF0b3J5ICAgICAgICAgID0+ICRFbnRyeS0+WzRdLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBpZiAoICRWYWxpZGF0aW9uUmVzdWx0LT57U2VydmVyRXJyb3J9ICkgewogICAgICAgICAgICAgICAgICAgICRFcnJvcnN7ICRFbnRyeS0+WzBdIH0gPSAkVmFsaWRhdGlvblJlc3VsdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewoKICAgICAgICAgICAgICAgICAgICAjIGdlbmVyYXRlIHN0b3JhYmxlIHZhbHVlIG9mIGR5bmFtaWMgZmllbGQgZWRpdCBmaWVsZAogICAgICAgICAgICAgICAgICAgICRHZXRQYXJhbXsgJEVudHJ5LT5bMF0gfSA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5FZGl0RmllbGRWYWx1ZUdldCgKICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgIFBhcmFtT2JqZWN0ICAgICAgICA9PiAkUGFyYW1PYmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgIExheW91dE9iamVjdCAgICAgICA9PiAkTGF5b3V0T2JqZWN0LAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgY2hlY2sgcmVtYWluaW5nIG5vbi1keW5hbWljLWZpZWxkIG1hbmRhdG9yeSBmaWVsZHMKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkR2V0UGFyYW17ICRFbnRyeS0+WzBdIH0gPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAkRW50cnktPlswXSApIHx8ICcnOwogICAgICAgICAgICAgICAgaWYgKCAhJEdldFBhcmFteyAkRW50cnktPlswXSB9ICYmICRFbnRyeS0+WzRdICkgewogICAgICAgICAgICAgICAgICAgICRFcnJvcnN7ICRFbnRyeS0+WzBdIC4gJ0ludmFsaWQnIH0gPSAnU2VydmVyRXJyb3InOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjIGNoZWNrIGVtYWlsIGFkZHJlc3MKICAgICAgICBpZiAoCiAgICAgICAgICAgICRHZXRQYXJhbXtVc2VyRW1haWx9CiAgICAgICAgICAgICYmICEkQ2hlY2tJdGVtT2JqZWN0LT5DaGVja0VtYWlsKCBBZGRyZXNzID0+ICRHZXRQYXJhbXtVc2VyRW1haWx9ICkKICAgICAgICAgICAgJiYgZ3JlcCB7ICRfIGVxICRHZXRQYXJhbXtWYWxpZElEfSB9IEBWYWxpZElETGlzdAogICAgICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICAkRXJyb3Jze1VzZXJFbWFpbEludmFsaWR9ID0gJ1NlcnZlckVycm9yJzsKICAgICAgICAgICAgJEVycm9yc3tFcnJvclR5cGV9ICAgICAgICA9ICRDaGVja0l0ZW1PYmplY3QtPkNoZWNrRXJyb3JUeXBlKCkgLiAnU2VydmVyRXJyb3JNc2cnOwogICAgICAgIH0KCiAgICAgICAgIyBDaGVjayBDdXN0b21lcklELCBpZiBDdXN0b21lckNvbXBhbnlTdXBwb3J0IGlzIGVuYWJsZWQuCiAgICAgICAgaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoJFNvdXJjZSktPntDdXN0b21lckNvbXBhbnlTdXBwb3J0fSAmJiAkR2V0UGFyYW17VXNlckN1c3RvbWVySUR9ICkgewoKICAgICAgICAgICAgbXkgJUNvbXBhbnkgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJDb21wYW55JyktPkN1c3RvbWVyQ29tcGFueUdldCgKICAgICAgICAgICAgICAgIEN1c3RvbWVySUQgPT4gJEdldFBhcmFte1VzZXJDdXN0b21lcklEfSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGlmICggISVDb21wYW55ICkgewogICAgICAgICAgICAgICAgJEVycm9yc3tVc2VyQ3VzdG9tZXJJREludmFsaWR9ID0gJ1NlcnZlckVycm9yJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBpZiBubyBlcnJvcnMgb2NjdXJyZWQKICAgICAgICBpZiAoICElRXJyb3JzICkgewoKICAgICAgICAgICAgIyBhZGQgdXNlcgogICAgICAgICAgICBteSAkVXNlciA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlckFkZCgKICAgICAgICAgICAgICAgICVHZXRQYXJhbSwKICAgICAgICAgICAgICAgIFVzZXJJRCA9PiAkU2VsZi0+e1VzZXJJRH0sCiAgICAgICAgICAgICAgICBTb3VyY2UgPT4gJFNvdXJjZQogICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoJFVzZXIpIHsKCiAgICAgICAgICAgICAgICAjIHNldCBkeW5hbWljIGZpZWxkIHZhbHVlcwogICAgICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKTsKCiAgICAgICAgICAgICAgICBFTlRSWToKICAgICAgICAgICAgICAgIGZvciBteSAkRW50cnkgKCBAeyAkQ29uZmlnT2JqZWN0LT5HZXQoJFNvdXJjZSktPntNYXB9IH0gKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBFTlRSWSBpZiAkRW50cnktPls1XSBuZSAnZHluYW1pY19maWVsZCc7CgogICAgICAgICAgICAgICAgICAgIG15ICREeW5hbWljRmllbGRDb25maWcgPSAkU2VsZi0+e0R5bmFtaWNGaWVsZExvb2t1cH0tPnsgJEVudHJ5LT5bMl0gfTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCAhSXNIYXNoUmVmV2l0aERhdGEoJER5bmFtaWNGaWVsZENvbmZpZykgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICROb3RlIC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZm8gPT4gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdEeW5hbWljIGZpZWxkICVzIG5vdCBmb3VuZCEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRFbnRyeS0+WzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCBFTlRSWTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIG15ICRWYWx1ZVNldCA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5WYWx1ZVNldCgKICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdE5hbWUgICAgICAgICA9PiAkVXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICAgICAgID0+ICRHZXRQYXJhbXsgJEVudHJ5LT5bMF0gfSwKICAgICAgICAgICAgICAgICAgICAgICAgVXNlcklEICAgICAgICAgICAgID0+ICRTZWxmLT57VXNlcklEfSwKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICBpZiAoICEkVmFsdWVTZXQgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICROb3RlIC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZm8gPT4gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVbmFibGUgdG8gc2V0IHZhbHVlIGZvciBkeW5hbWljIGZpZWxkICVzIScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJEVudHJ5LT5bMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICBuZXh0IEVOVFJZOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAjIHVwZGF0ZSBwcmVmZXJlbmNlcwogICAgICAgICAgICAgICAgbXkgJVByZWZlcmVuY2VzID0gJXsgJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclByZWZlcmVuY2VzR3JvdXBzJykgfTsKICAgICAgICAgICAgICAgIEdST1VQOgogICAgICAgICAgICAgICAgZm9yIG15ICRHcm91cCAoIHNvcnQga2V5cyAlUHJlZmVyZW5jZXMgKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBHUk9VUCBpZiAkR3JvdXAgZXEgJ1Bhc3N3b3JkJzsKCiAgICAgICAgICAgICAgICAgICAgIyBnZXQgdXNlciBkYXRhCiAgICAgICAgICAgICAgICAgICAgbXkgJVVzZXJEYXRhID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJVc2VyRGF0YUdldCgKICAgICAgICAgICAgICAgICAgICAgICAgVXNlciA9PiAkVXNlciwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIG15ICRNb2R1bGUgPSAkUHJlZmVyZW5jZXN7JEdyb3VwfS0+e01vZHVsZX07CiAgICAgICAgICAgICAgICAgICAgaWYgKCAhJE1haW5PYmplY3QtPlJlcXVpcmUoJE1vZHVsZSkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkTGF5b3V0T2JqZWN0LT5GYXRhbEVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG15ICRPYmplY3QgPSAkTW9kdWxlLT5uZXcoCiAgICAgICAgICAgICAgICAgICAgICAgICV7JFNlbGZ9LAogICAgICAgICAgICAgICAgICAgICAgICBDb25maWdJdGVtID0+ICRQcmVmZXJlbmNlc3skR3JvdXB9LAogICAgICAgICAgICAgICAgICAgICAgICBVc2VyT2JqZWN0ID0+ICRDdXN0b21lclVzZXJPYmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgIERlYnVnICAgICAgPT4gJFNlbGYtPntEZWJ1Z30sCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICBteSBAUGFyYW1zID0gJE9iamVjdC0+UGFyYW0oICV7ICRQcmVmZXJlbmNlc3skR3JvdXB9IH0sIFVzZXJEYXRhID0+IFwlVXNlckRhdGEgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoQFBhcmFtcykgewogICAgICAgICAgICAgICAgICAgICAgICBteSAlR2V0UGFyYW07CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciBteSAkUGFyYW1JdGVtIChAUGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBteSBAQXJyYXkgPSAkUGFyYW1PYmplY3QtPkdldEFycmF5KCBQYXJhbSA9PiAkUGFyYW1JdGVtLT57TmFtZX0gKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRHZXRQYXJhbXsgJFBhcmFtSXRlbS0+e05hbWV9IH0gPSBcQEFycmF5OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICEkT2JqZWN0LT5SdW4oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0UGFyYW0gPT4gXCVHZXRQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVc2VyRGF0YSA9PiBcJVVzZXJEYXRhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICROb3RlIC49ICRMYXlvdXRPYmplY3QtPk5vdGlmeSggSW5mbyA9PiAkT2JqZWN0LT5FcnJvcigpICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyBnZXQgdXNlciBkYXRhIGFuZCBzaG93IHNjcmVlbiBhZ2FpbgogICAgICAgICAgICAgICAgaWYgKCAhJE5vdGUgKSB7CgogICAgICAgICAgICAgICAgICAgICMgaW4gYm9ycm93ZWQgdmlldywgdGFrZSB0aGUgbmV3IGNyZWF0ZWQgY3VzdG9tZXIgb3ZlciBpbnRvIHRoZSBuZXcgdGlja2V0CiAgICAgICAgICAgICAgICAgICAgaWYgKCAkTmF2IGVxICdOb25lJyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbXkgJE91dHB1dCA9ICROYXZCYXI7CgogICAgICAgICAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5BZGRKU0RhdGEoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXkgICA9PiAnQ3VzdG9tZXInLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgPT4gJFVzZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkFkZEpTRGF0YSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtleSAgID0+ICdOYXYnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgPT4gJE5hdiwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+T3V0cHV0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyVXNlcicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhICAgICAgICAgPT4gXCVQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCBUeXBlID0+ICdTbWFsbCcgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkT3V0cHV0OwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJFNlbGYtPl9PdmVydmlldygKICAgICAgICAgICAgICAgICAgICAgICAgTmF2ICAgID0+ICROYXYsCiAgICAgICAgICAgICAgICAgICAgICAgIFNlYXJjaCA9PiAkU2VhcmNoLAogICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgIG15ICRPdXRwdXQgICAgICAgID0gJE5hdkJhciAuICROb3RlOwogICAgICAgICAgICAgICAgICAgIG15ICRVUkwgICAgICAgICAgID0gJyc7CiAgICAgICAgICAgICAgICAgICAgbXkgJFVzZXJIVE1MUXVvdGUgPSAkTGF5b3V0T2JqZWN0LT5MaW5rRW5jb2RlKCRVc2VyKTsKICAgICAgICAgICAgICAgICAgICBteSAkVXNlclF1b3RlICAgICA9ICRMYXlvdXRPYmplY3QtPkFzY2lpMkh0bWwoIFRleHQgPT4gJFVzZXIgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCgnRnJvbnRlbmQ6Ok1vZHVsZScpLT57QWdlbnRUaWNrZXRQaG9uZX0gKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRVUkwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC49ICI8YSBocmVmPVwiJExheW91dE9iamVjdC0+e0Jhc2VsaW5rfUFjdGlvbj1BZ2VudFRpY2tldFBob25lO1N1YmFjdGlvbj1TdG9yZU5ldztFeHBhbmRDdXN0b21lck5hbWU9MjtDdXN0b21lclVzZXI9JFVzZXJIVE1MUXVvdGU7JExheW91dE9iamVjdC0+e0NoYWxsZW5nZVRva2VuUGFyYW19XCI+IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLiAkTGF5b3V0T2JqZWN0LT57TGFuZ3VhZ2VPYmplY3R9LT5UcmFuc2xhdGUoJ05ldyBwaG9uZSB0aWNrZXQnKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLiAiPC9hPiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICggJENvbmZpZ09iamVjdC0+R2V0KCdGcm9udGVuZDo6TW9kdWxlJyktPntBZ2VudFRpY2tldEVtYWlsfSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRVUkwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRVUkwgLj0gIiAtICI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJFVSTAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLj0gIjxhIGhyZWY9XCIkTGF5b3V0T2JqZWN0LT57QmFzZWxpbmt9QWN0aW9uPUFnZW50VGlja2V0RW1haWw7U3ViYWN0aW9uPVN0b3JlTmV3O0V4cGFuZEN1c3RvbWVyTmFtZT0yO0N1c3RvbWVyVXNlcj0kVXNlckhUTUxRdW90ZTskTGF5b3V0T2JqZWN0LT57Q2hhbGxlbmdlVG9rZW5QYXJhbX1cIj4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICRMYXlvdXRPYmplY3QtPntMYW5ndWFnZU9iamVjdH0tPlRyYW5zbGF0ZSgnTmV3IGVtYWlsIHRpY2tldCcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICI8L2E+IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCRVUkwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJE91dHB1dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLj0gJExheW91dE9iamVjdC0+Tm90aWZ5KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiAkTGF5b3V0T2JqZWN0LT57TGFuZ3VhZ2VPYmplY3R9LT5UcmFuc2xhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0N1c3RvbWVyICVzIGFkZGVkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkVXNlclF1b3RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICIgKCAkVVJMICkhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkT3V0cHV0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhID0+ICRMYXlvdXRPYmplY3QtPntMYW5ndWFnZU9iamVjdH0tPlRyYW5zbGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ3VzdG9tZXIgJXMgYWRkZWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRVc2VyUXVvdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4gIiEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5PdXRwdXQoCiAgICAgICAgICAgICAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnQWRtaW5DdXN0b21lclVzZXInLAogICAgICAgICAgICAgICAgICAgICAgICBEYXRhICAgICAgICAgPT4gXCVQYXJhbSwKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICBpZiAoICROYXYgZXEgJ05vbmUnICkgewogICAgICAgICAgICAgICAgICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPkZvb3RlciggVHlwZSA9PiAnU21hbGwnICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPkZvb3RlcigpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRPdXRwdXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkTm90ZSAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoIFByaW9yaXR5ID0+ICdFcnJvcicgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBzb21ldGhpbmcgaGFzIGdvbmUgd3JvbmcKICAgICAgICBteSAkT3V0cHV0ID0gJE5hdkJhciAuICROb3RlOwogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPl9FZGl0KAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgQWN0aW9uID0+ICdBZGQnLAogICAgICAgICAgICBTb3VyY2UgPT4gJFNvdXJjZSwKICAgICAgICAgICAgU2VhcmNoID0+ICRTZWFyY2gsCiAgICAgICAgICAgIEVycm9ycyA9PiBcJUVycm9ycywKICAgICAgICAgICAgJUdldFBhcmFtLAogICAgICAgICk7CgogICAgICAgIGlmICggJE5hdiBlcSAnTm9uZScgKSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCBUeXBlID0+ICdTbWFsbCcgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIG92ZXJ2aWV3CiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICBlbHNlIHsKICAgICAgICAkU2VsZi0+X092ZXJ2aWV3KAogICAgICAgICAgICBOYXYgICAgPT4gJE5hdiwKICAgICAgICAgICAgU2VhcmNoID0+ICRTZWFyY2gsCiAgICAgICAgKTsKCiAgICAgICAgbXkgJE5vdGlmaWNhdGlvbiA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdOb3RpZmljYXRpb24nICkgfHwgJyc7CiAgICAgICAgbXkgJE91dHB1dCAgICAgICA9ICROYXZCYXI7CiAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5Ob3RpZnkoIEluZm8gPT4gVHJhbnNsYXRhYmxlKCdDdXN0b21lciB1c2VyIHVwZGF0ZWQhJykgKQogICAgICAgICAgICBpZiAoICROb3RpZmljYXRpb24gJiYgJE5vdGlmaWNhdGlvbiBlcSAnVXBkYXRlJyApOwoKICAgICAgICAkT3V0cHV0IC49ICRMYXlvdXRPYmplY3QtPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pbkN1c3RvbWVyVXNlcicsCiAgICAgICAgICAgIERhdGEgICAgICAgICA9PiBcJVBhcmFtLAogICAgICAgICk7CgogICAgICAgIGlmICggJE5hdiBlcSAnTm9uZScgKSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCBUeXBlID0+ICdTbWFsbCcgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Rm9vdGVyKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KfQoKc3ViIF9PdmVydmlldyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CgogICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXcnLAogICAgICAgIERhdGEgPT4gXCVQYXJhbSwKICAgICk7CgogICAgJExheW91dE9iamVjdC0+QmxvY2soIE5hbWUgPT4gJ0FjdGlvbkxpc3QnICk7CiAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICBOYW1lID0+ICdBY3Rpb25TZWFyY2gnLAogICAgICAgIERhdGEgPT4gXCVQYXJhbSwKICAgICk7CgogICAgbXkgJEN1c3RvbWVyVXNlck9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXInKTsKCiAgICAjIGdldCB3cml0YWJsZSBkYXRhIHNvdXJjZXMKICAgIG15ICVDdXN0b21lclNvdXJjZSA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyU291cmNlTGlzdCgKICAgICAgICBSZWFkT25seSA9PiAwLAogICAgKTsKCiAgICAjIG9ubHkgc2hvdyBBZGQgb3B0aW9uIGlmIHdlIGhhdmUgYXQgbGVhc3Qgb25lIHdyaXRhYmxlIGJhY2tlbmQKICAgIGlmICggc2NhbGFyIGtleXMgJUN1c3RvbWVyU291cmNlICkgewogICAgICAgICRQYXJhbXtTb3VyY2VPcHRpb259ID0gJExheW91dE9iamVjdC0+QnVpbGRTZWxlY3Rpb24oCiAgICAgICAgICAgIERhdGEgICAgICAgPT4geyAlQ3VzdG9tZXJTb3VyY2UsIH0sCiAgICAgICAgICAgIE5hbWUgICAgICAgPT4gJ1NvdXJjZScsCiAgICAgICAgICAgIFNlbGVjdGVkSUQgPT4gJFBhcmFte1NvdXJjZX0gfHwgJycsCiAgICAgICAgICAgIENsYXNzICAgICAgPT4gJ01vZGVybml6ZScsCiAgICAgICAgKTsKCiAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ0FjdGlvbkFkZCcsCiAgICAgICAgICAgIERhdGEgPT4gXCVQYXJhbSwKICAgICAgICApOwogICAgfQoKICAgIGlmICggJFBhcmFte1NlYXJjaH0gKSB7CgogICAgICAgICMgZ2V0IGNvbmZpZyBvYmplY3QKICAgICAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICAgICAgIyB3aGVuIHRoZXJlIGlzIG5vIGRhdGEgdG8gc2hvdywgYSBtZXNzYWdlIGlzIGRpc3BsYXllZCBvbiB0aGUgdGFibGUgd2l0aCB0aGlzIGNvbHNwYW4KICAgICAgICBteSAkQ29sU3BhbiA9IDY7CgogICAgICAgICMgc2FtZSBMaW1pdCBhcyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJTZWFyY2hMaXN0TGltaXR9CiAgICAgICAgIyBzbWFsbGVzdCBMaW1pdCBmcm9tIGFsbCBzb3VyY2VzCiAgICAgICAgbXkgJExpbWl0ID0gNDAwOwogICAgICAgIFNPVVJDRToKICAgICAgICBmb3IgbXkgJENvdW50ICggJycsIDEgLi4gMTAgKSB7CiAgICAgICAgICAgIG5leHQgU09VUkNFIGlmICEkQ29uZmlnT2JqZWN0LT5HZXQoIkN1c3RvbWVyVXNlciRDb3VudCIpOwogICAgICAgICAgICBteSAkQ3VzdG9tZXJVc2VyTWFwID0gJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lclVzZXIkQ291bnQiKTsKICAgICAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRDdXN0b21lclVzZXJNYXAtPntDdXN0b21lclVzZXJTZWFyY2hMaXN0TGltaXR9OwogICAgICAgICAgICBpZiAoICRDdXN0b21lclVzZXJNYXAtPntDdXN0b21lclVzZXJTZWFyY2hMaXN0TGltaXR9IDwgJExpbWl0ICkgewogICAgICAgICAgICAgICAgJExpbWl0ID0gJEN1c3RvbWVyVXNlck1hcC0+e0N1c3RvbWVyVXNlclNlYXJjaExpc3RMaW1pdH07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIG15ICVMaXN0QWxsSXRlbXMgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclNlYXJjaCgKICAgICAgICAgICAgU2VhcmNoID0+ICRQYXJhbXtTZWFyY2h9LAogICAgICAgICAgICBMaW1pdCAgPT4gJExpbWl0ICsgMSwKICAgICAgICAgICAgVmFsaWQgID0+IDAsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCBrZXlzICVMaXN0QWxsSXRlbXMgPD0gJExpbWl0ICkgewogICAgICAgICAgICBteSAkTGlzdEFsbEl0ZW1zID0ga2V5cyAlTGlzdEFsbEl0ZW1zOwogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ092ZXJ2aWV3SGVhZGVyJywKICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgIExpc3RBbGwgPT4gJExpc3RBbGxJdGVtcywKICAgICAgICAgICAgICAgICAgICBMaW1pdCAgID0+ICRMaW1pdCwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICBteSAlTGlzdCA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyU2VhcmNoKAogICAgICAgICAgICBTZWFyY2ggPT4gJFBhcmFte1NlYXJjaH0sCiAgICAgICAgICAgIFZhbGlkICA9PiAwLAogICAgICAgICk7CgogICAgICAgIGlmICgga2V5cyAlTGlzdEFsbEl0ZW1zID4gJExpbWl0ICkgewogICAgICAgICAgICBteSAkTGlzdEFsbEl0ZW1zICAgPSBrZXlzICVMaXN0QWxsSXRlbXM7CiAgICAgICAgICAgIG15ICRTZWFyY2hMaXN0U2l6ZSA9IGtleXMgJUxpc3Q7CgogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ092ZXJ2aWV3SGVhZGVyJywKICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgIFNlYXJjaExpc3RTaXplID0+ICRTZWFyY2hMaXN0U2l6ZSwKICAgICAgICAgICAgICAgICAgICBMaXN0QWxsICAgICAgICA9PiAkTGlzdEFsbEl0ZW1zLAogICAgICAgICAgICAgICAgICAgIExpbWl0ICAgICAgICAgID0+ICRMaW1pdCwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXdSZXN1bHQnLAogICAgICAgICAgICBEYXRhID0+IFwlUGFyYW0sCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoJ1N3aXRjaFRvQ3VzdG9tZXInKSAmJiAkU2VsZi0+e1N3aXRjaFRvQ3VzdG9tZXJQZXJtaXNzaW9ufSAmJiAkUGFyYW17TmF2fSBuZSAnTm9uZScgKQogICAgICAgIHsKICAgICAgICAgICAgJENvbFNwYW4gPSA3OwogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ092ZXJ2aWV3UmVzdWx0U3dpdGNoVG9DdXN0b21lcicsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICAjIGlmIHRoZXJlIGFyZSByZXN1bHRzIHRvIHNob3cKICAgICAgICBpZiAoJUxpc3QpIHsKCiAgICAgICAgICAgICMgZ2V0IHZhbGlkIGxpc3QKICAgICAgICAgICAgbXkgJVZhbGlkTGlzdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcpLT5WYWxpZExpc3QoKTsKICAgICAgICAgICAgZm9yIG15ICRMaXN0S2V5ICggc29ydCB7IGxjKCRhKSBjbXAgbGMoJGIpIH0ga2V5cyAlTGlzdCApIHsKCiAgICAgICAgICAgICAgICBteSAlVXNlckRhdGEgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KCBVc2VyID0+ICRMaXN0S2V5ICk7CiAgICAgICAgICAgICAgICAkVXNlckRhdGF7VXNlckZ1bGxuYW1lfSA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyTmFtZSgKICAgICAgICAgICAgICAgICAgICBVc2VyTG9naW4gPT4gJFVzZXJEYXRhe1VzZXJMb2dpbn0sCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJ092ZXJ2aWV3UmVzdWx0Um93JywKICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgVmFsaWQgICAgICAgPT4gJFZhbGlkTGlzdHsgJFVzZXJEYXRhe1ZhbGlkSUR9IHx8ICcnIH0gfHwgJy0nLAogICAgICAgICAgICAgICAgICAgICAgICBTZWFyY2ggICAgICA9PiAkUGFyYW17U2VhcmNofSwKICAgICAgICAgICAgICAgICAgICAgICAgQ3VzdG9tZXJLZXkgPT4gJExpc3RLZXksCiAgICAgICAgICAgICAgICAgICAgICAgICVVc2VyRGF0YSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICggJFBhcmFte05hdn0gZXEgJ05vbmUnICkgewogICAgICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdPdmVydmlld1Jlc3VsdFJvd0xpbmtOb25lJywKICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWFyY2ggICAgICA9PiAkUGFyYW17U2VhcmNofSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1c3RvbWVyS2V5ID0+ICRMaXN0S2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJVVzZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXdSZXN1bHRSb3dMaW5rJywKICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWFyY2ggICAgICA9PiAkUGFyYW17U2VhcmNofSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hdiAgICAgICAgID0+ICRQYXJhbXtOYXZ9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VzdG9tZXJLZXkgPT4gJExpc3RLZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAlVXNlckRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgJENvbmZpZ09iamVjdC0+R2V0KCdTd2l0Y2hUb0N1c3RvbWVyJykKICAgICAgICAgICAgICAgICAgICAmJiAkU2VsZi0+e1N3aXRjaFRvQ3VzdG9tZXJQZXJtaXNzaW9ufQogICAgICAgICAgICAgICAgICAgICYmICRQYXJhbXtOYXZ9IG5lICdOb25lJwogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXdSZXN1bHRSb3dTd2l0Y2hUb0N1c3RvbWVyJywKICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWFyY2ggPT4gJFBhcmFte1NlYXJjaH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAlVXNlckRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBvdGhlcndpc2UgaXQgZGlzcGxheXMgYSBubyBkYXRhIGZvdW5kIG1lc3NhZ2UKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICdOb0RhdGFGb3VuZE1zZycsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICBDb2xTcGFuID0+ICRDb2xTcGFuLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgIyBpZiB0aGVyZSBpcyBub3RoaW5nIHRvIHNlYXJjaCBpdCBzaG93cyBhIG1lc3NhZ2UKICAgIGVsc2UKICAgIHsKICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnTm9TZWFyY2hUZXJtcycsCiAgICAgICAgICAgIERhdGEgPT4ge30sCiAgICAgICAgKTsKICAgIH0KCiAgICAkTGF5b3V0T2JqZWN0LT5BZGRKU0RhdGEoCiAgICAgICAgS2V5ICAgPT4gJ05hdicsCiAgICAgICAgVmFsdWUgPT4gJFBhcmFte05hdn0sCiAgICApOwoKICAgIHJldHVybjsKfQoKc3ViIF9FZGl0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBHZXQgbGF5b3V0IG9iamVjdC4KICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CgogICAgbXkgJE91dHB1dCA9ICcnOwoKICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgIE5hbWUgPT4gJ092ZXJ2aWV3JywKICAgICAgICBEYXRhID0+IFwlUGFyYW0sCiAgICApOwoKICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKCBOYW1lID0+ICdBY3Rpb25MaXN0JyApOwogICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgTmFtZSA9PiAnQWN0aW9uT3ZlcnZpZXcnLAogICAgICAgIERhdGEgPT4gXCVQYXJhbSwKICAgICk7CgogICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXdVcGRhdGUnLAogICAgICAgIERhdGEgPT4gXCVQYXJhbSwKICAgICk7CgogICAgaWYgKCAkUGFyYW17QWN0aW9ufSBlcSAnQ2hhbmdlJyApIHsKCiAgICAgICAgIyBzaG93cyBlZGl0IGhlYWRlcgogICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKCBOYW1lID0+ICdIZWFkZXJFZGl0JyApOwoKICAgICAgICAjIHNob3dzIGVmZmVjdGl2ZSBwZXJtaXNzaW9ucyBtYXRyaXgKICAgICAgICAkU2VsZi0+X0VmZmVjdGl2ZVBlcm1pc3Npb25zKCVQYXJhbSk7CiAgICB9CgogICAgIyBzaG93cyBhZGQgaGVhZGVyCiAgICBlbHNlIHsKICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jayggTmFtZSA9PiAnSGVhZGVyQWRkJyApOwogICAgfQoKICAgIG15ICRVcGRhdGVPbmx5UHJlZmVyZW5jZXM7CgogICAgIyBHZXQgY29uZmlnIG9iamVjdAogICAgbXkgJENvbmZpZ09iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyk7CgogICAgIyB1cGRhdGUgdXNlcgogICAgaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoICRQYXJhbXtTb3VyY2V9ICktPntSZWFkT25seX0gfHwgJENvbmZpZ09iamVjdC0+R2V0KCAkUGFyYW17U291cmNlfSApLT57TW9kdWxlfSA9fiAvTERBUC9pICkKICAgIHsKICAgICAgICAkVXBkYXRlT25seVByZWZlcmVuY2VzID0gMTsKICAgIH0KCiAgICAjIEdldCBkeW5hbWljIGZpZWxkIGJhY2tlbmQgb2JqZWN0LgogICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CiAgICBteSAkUGFyYW1PYmplY3QgICAgICAgICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpXZWI6OlJlcXVlc3QnKTsKCiAgICBFTlRSWToKICAgIGZvciBteSAkRW50cnkgKCBAeyAkQ29uZmlnT2JqZWN0LT5HZXQoICRQYXJhbXtTb3VyY2V9ICktPntNYXB9IH0gKSB7CiAgICAgICAgbmV4dCBFTlRSWSBpZiAhJEVudHJ5LT5bMF07CgogICAgICAgICMgSGFuZGxlIGR5bmFtaWMgZmllbGRzCiAgICAgICAgaWYgKCAkRW50cnktPls1XSBlcSAnZHluYW1pY19maWVsZCcgKSB7CgogICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlnID0gJFNlbGYtPntEeW5hbWljRmllbGRMb29rdXB9LT57ICRFbnRyeS0+WzJdIH07CgogICAgICAgICAgICBuZXh0IEVOVFJZIGlmICFJc0hhc2hSZWZXaXRoRGF0YSgkRHluYW1pY0ZpZWxkQ29uZmlnKTsKCiAgICAgICAgICAgICMgR2V0IEhUTUwgZm9yIGR5bmFtaWMgZmllbGQKICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZEhUTUwgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+RWRpdEZpZWxkUmVuZGVyKAogICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICBWYWx1ZSAgICAgICAgICAgICAgPT4gJFBhcmFteyAkRW50cnktPlswXSB9ID8gJFBhcmFteyAkRW50cnktPlswXSB9IDogdW5kZWYsCiAgICAgICAgICAgICAgICBNYW5kYXRvcnkgICAgICAgICAgPT4gJEVudHJ5LT5bNF0sCiAgICAgICAgICAgICAgICBMYXlvdXRPYmplY3QgICAgICAgPT4gJExheW91dE9iamVjdCwKICAgICAgICAgICAgICAgIFBhcmFtT2JqZWN0ICAgICAgICA9PiAkUGFyYW1PYmplY3QsCgogICAgICAgICAgICAgICAgIyBTZXJ2ZXIgZXJyb3IsIGlmIGFueQogICAgICAgICAgICAgICAgJXsgJFBhcmFte0Vycm9yc30tPnsgJEVudHJ5LT5bMF0gfSB9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgIyBza2lwIGZpZWxkcyBmb3Igd2hpY2ggSFRNTCBjb3VsZCBub3QgYmUgcmV0cmlldmVkCiAgICAgICAgICAgIG5leHQgRU5UUlkgaWYgIUlzSGFzaFJlZldpdGhEYXRhKCREeW5hbWljRmllbGRIVE1MKTsKCiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnSXRlbScsCiAgICAgICAgICAgICAgICBEYXRhID0+IHt9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICdEeW5hbWljRmllbGQnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgTmFtZSAgPT4gJER5bmFtaWNGaWVsZENvbmZpZy0+e05hbWV9LAogICAgICAgICAgICAgICAgICAgIExhYmVsID0+ICREeW5hbWljRmllbGRIVE1MLT57TGFiZWx9LAogICAgICAgICAgICAgICAgICAgIEZpZWxkID0+ICREeW5hbWljRmllbGRIVE1MLT57RmllbGR9LAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIG5leHQgRU5UUlk7CiAgICAgICAgfQoKICAgICAgICBteSAkQmxvY2sgPSAnSW5wdXQnOwoKICAgICAgICAjIGNoZWNrIGlucHV0IHR5cGUKICAgICAgICBpZiAoICRFbnRyeS0+WzBdID1+IC9eVXNlclBhc3N3b3IvaSApIHsKICAgICAgICAgICAgJEJsb2NrID0gJ1Bhc3N3b3JkJzsKICAgICAgICB9CgogICAgICAgICMgY2hlY2sgaWYgbG9naW4gYXV0byBjcmVhdGlvbgogICAgICAgIGlmICggJENvbmZpZ09iamVjdC0+R2V0KCAkUGFyYW17U291cmNlfSApLT57QXV0b0xvZ2luQ3JlYXRpb259ICYmICRFbnRyeS0+WzBdIGVxICdVc2VyTG9naW4nICkgewogICAgICAgICAgICAkQmxvY2sgPSAnSW5wdXRIaWRkZW4nOwogICAgICAgIH0KCiAgICAgICAgaWYgKCAkRW50cnktPls3XSB8fCAkVXBkYXRlT25seVByZWZlcmVuY2VzICkgewogICAgICAgICAgICAkUGFyYW17UmVhZE9ubHl9ID0gMTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRQYXJhbXtSZWFkT25seX0gPSAwOwogICAgICAgIH0KCiAgICAgICAgIyBzaG93IHJlcXVpcmVkIGZsYWcKICAgICAgICBpZiAoICRFbnRyeS0+WzRdICkgewogICAgICAgICAgICAkUGFyYW17UmVxdWlyZWRDbGFzc30gICAgICAgICAgPSAnVmFsaWRhdGVfUmVxdWlyZWQnOwogICAgICAgICAgICAkUGFyYW17UmVxdWlyZWRMYWJlbENsYXNzfSAgICAgPSAnTWFuZGF0b3J5JzsKICAgICAgICAgICAgJFBhcmFte1JlcXVpcmVkTGFiZWxDaGFyYWN0ZXJ9ID0gJyonOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJFBhcmFte1JlcXVpcmVkQ2xhc3N9ICAgICAgICAgID0gJyc7CiAgICAgICAgICAgICRQYXJhbXtSZXF1aXJlZExhYmVsQ2xhc3N9ICAgICA9ICcnOwogICAgICAgICAgICAkUGFyYW17UmVxdWlyZWRMYWJlbENoYXJhY3Rlcn0gPSAnJzsKICAgICAgICB9CgogICAgICAgICMgc2V0IGVtcHR5IHN0cmluZwogICAgICAgICRQYXJhbXtFcnJvcnN9LT57ICRFbnRyeS0+WzBdIC4gJ0ludmFsaWQnIH0gfHw9ICcnOwoKICAgICAgICAjIGFkZCBjbGFzcyB0byB2YWxpZGF0ZSBlbWFpbHMKICAgICAgICBpZiAoICRFbnRyeS0+WzBdIGVxICdVc2VyRW1haWwnICkgewogICAgICAgICAgICAkUGFyYW17UmVxdWlyZWRDbGFzc30gLj0gJyBWYWxpZGF0ZV9FbWFpbCc7CiAgICAgICAgfQoKICAgICAgICAjIGJ1aWxkIHNlbGVjdGlvbnMgb3IgaW5wdXQgZmllbGRzCiAgICAgICAgaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoICRQYXJhbXtTb3VyY2V9ICktPntTZWxlY3Rpb25zfS0+eyAkRW50cnktPlswXSB9ICkgewogICAgICAgICAgICAkQmxvY2sgPSAnT3B0aW9uJzsKCiAgICAgICAgICAgICMgQ2hhbmdlIHRoZSB2YWxpZGF0aW9uIGNsYXNzCiAgICAgICAgICAgIGlmICggJFBhcmFte1JlcXVpcmVkQ2xhc3N9ICkgewogICAgICAgICAgICAgICAgJFBhcmFte1JlcXVpcmVkQ2xhc3N9ID0gJ1ZhbGlkYXRlX1JlcXVpcmVkJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgIyBnZXQgdGhlIGRhdGEgb2YgdGhlIGN1cnJlbnQgc2VsZWN0aW9uCiAgICAgICAgICAgIG15ICRTZWxlY3Rpb25zRGF0YSA9ICRDb25maWdPYmplY3QtPkdldCggJFBhcmFte1NvdXJjZX0gKS0+e1NlbGVjdGlvbnN9LT57ICRFbnRyeS0+WzBdIH07CgogICAgICAgICAgICAjIG1ha2Ugc3VyZSB0aGUgZW5jb2Rpbmcgc3RhbXAgaXMgc2V0CiAgICAgICAgICAgIGZvciBteSAkS2V5ICggc29ydCBrZXlzICV7JFNlbGVjdGlvbnNEYXRhfSApIHsKICAgICAgICAgICAgICAgICRTZWxlY3Rpb25zRGF0YS0+eyRLZXl9CiAgICAgICAgICAgICAgICAgICAgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RW5jb2RlJyktPkVuY29kZUlucHV0KCAkU2VsZWN0aW9uc0RhdGEtPnskS2V5fSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAjIGJ1aWxkIG9wdGlvbiBzdHJpbmcKICAgICAgICAgICAgJFBhcmFte09wdGlvbn0gPSAkTGF5b3V0T2JqZWN0LT5CdWlsZFNlbGVjdGlvbigKICAgICAgICAgICAgICAgIERhdGEgICAgICAgID0+ICRTZWxlY3Rpb25zRGF0YSwKICAgICAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICRFbnRyeS0+WzBdLAogICAgICAgICAgICAgICAgVHJhbnNsYXRpb24gPT4gMSwKICAgICAgICAgICAgICAgIFNlbGVjdGVkSUQgID0+ICRQYXJhbXsgJEVudHJ5LT5bMF0gfSwKICAgICAgICAgICAgICAgIENsYXNzICAgICAgID0+ICIkUGFyYW17UmVxdWlyZWRDbGFzc30gTW9kZXJuaXplICIgLiAkUGFyYW17RXJyb3JzfS0+eyAkRW50cnktPlswXSAuICdJbnZhbGlkJyB9LAogICAgICAgICAgICAgICAgRGlzYWJsZWQgICAgPT4gJFVwZGF0ZU9ubHlQcmVmZXJlbmNlcyA/IDEgOiAwLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBlbHNpZiAoICRFbnRyeS0+WzBdID1+IC9eVmFsaWRJRC9pICkgewoKICAgICAgICAgICAgIyBDaGFuZ2UgdGhlIHZhbGlkYXRpb24gY2xhc3MKICAgICAgICAgICAgaWYgKCAkUGFyYW17UmVxdWlyZWRDbGFzc30gKSB7CiAgICAgICAgICAgICAgICAkUGFyYW17UmVxdWlyZWRDbGFzc30gPSAnVmFsaWRhdGVfUmVxdWlyZWQnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAjIGJ1aWxkIFZhbGlkSUQgc3RyaW5nCiAgICAgICAgICAgICRCbG9jayA9ICdPcHRpb24nOwogICAgICAgICAgICAkUGFyYW17T3B0aW9ufSA9ICRMYXlvdXRPYmplY3QtPkJ1aWxkU2VsZWN0aW9uKAogICAgICAgICAgICAgICAgRGF0YSAgICAgICA9PiB7ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcpLT5WYWxpZExpc3QoKSwgfSwKICAgICAgICAgICAgICAgIE5hbWUgICAgICAgPT4gJEVudHJ5LT5bMF0sCiAgICAgICAgICAgICAgICBTZWxlY3RlZElEID0+IGRlZmluZWQoICRQYXJhbXsgJEVudHJ5LT5bMF0gfSApID8gJFBhcmFteyAkRW50cnktPlswXSB9IDogMSwKICAgICAgICAgICAgICAgIENsYXNzICAgICAgPT4gIiRQYXJhbXtSZXF1aXJlZENsYXNzfSBNb2Rlcm5pemUgIiAuICRQYXJhbXtFcnJvcnN9LT57ICRFbnRyeS0+WzBdIC4gJ0ludmFsaWQnIH0sCiAgICAgICAgICAgICAgICBEaXNhYmxlZCAgID0+ICRVcGRhdGVPbmx5UHJlZmVyZW5jZXMgPyAxIDogMCwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgZWxzaWYgKAogICAgICAgICAgICAkRW50cnktPlswXSA9fiAvXlVzZXJDdXN0b21lcklEJC9pCiAgICAgICAgICAgICYmICRDb25maWdPYmplY3QtPkdldCggJFBhcmFte1NvdXJjZX0gKS0+e0N1c3RvbWVyQ29tcGFueVN1cHBvcnR9CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIG15ICRDdXN0b21lckNvbXBhbnlPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJDb21wYW55Jyk7CiAgICAgICAgICAgIG15ICVDb21wYW55TGlzdCAgICAgICAgICAgPSAoCiAgICAgICAgICAgICAgICAkQ3VzdG9tZXJDb21wYW55T2JqZWN0LT5DdXN0b21lckNvbXBhbnlMaXN0KCBMaW1pdCA9PiAwICksCiAgICAgICAgICAgICAgICAnJyA9PiAnLScsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmICggJFBhcmFteyAkRW50cnktPlswXSB9ICkgewogICAgICAgICAgICAgICAgbXkgJUNvbXBhbnkgPSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0LT5DdXN0b21lckNvbXBhbnlHZXQoCiAgICAgICAgICAgICAgICAgICAgQ3VzdG9tZXJJRCA9PiAkUGFyYW17ICRFbnRyeS0+WzBdIH0sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKCAhJUNvbXBhbnkgKSB7CiAgICAgICAgICAgICAgICAgICAgJENvbXBhbnlMaXN0eyAkUGFyYW17ICRFbnRyeS0+WzBdIH0gfSA9ICRQYXJhbXsgJEVudHJ5LT5bMF0gfSAuICcgKC0pJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAkQmxvY2sgPSAnT3B0aW9uJzsKCiAgICAgICAgICAgICMgQ2hhbmdlIHRoZSB2YWxpZGF0aW9uIGNsYXNzCiAgICAgICAgICAgIGlmICggJFBhcmFte1JlcXVpcmVkQ2xhc3N9ICkgewogICAgICAgICAgICAgICAgJFBhcmFte1JlcXVpcmVkQ2xhc3N9ID0gJ1ZhbGlkYXRlX1JlcXVpcmVkJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbXkgJFVzZUF1dG9Db21wbGV0ZSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyktPkdldCgnQWRtaW5DdXN0b21lclVzZXI6OlVzZUF1dG9Db21wbGV0ZScpOwoKICAgICAgICAgICAgaWYgKCRVc2VBdXRvQ29tcGxldGUpIHsKCiAgICAgICAgICAgICAgICBteSAkVmFsdWUgPSAkUGFyYW17ICRFbnRyeS0+WzBdIH0gfHwgJFBhcmFte0N1c3RvbWVySUR9OwogICAgICAgICAgICAgICAgJFBhcmFte09wdGlvbn0gPSAnPGlucHV0IHR5cGU9InRleHQiIGlkPSJVc2VyQ3VzdG9tZXJJRCIgbmFtZT0iVXNlckN1c3RvbWVySUQiIHZhbHVlPSInIC4gJFZhbHVlIC4gJyIKICAgICAgICAgICAgICAgICAgICBjbGFzcz0iVzUwcGMgQ3VzdG9tZXJBdXRvQ29tcGxldGVTaW1wbGUgJwogICAgICAgICAgICAgICAgICAgIC4gJFBhcmFte1JlcXVpcmVkQ2xhc3N9IC4gJyAnCiAgICAgICAgICAgICAgICAgICAgLiAkUGFyYW17RXJyb3JzfS0+eyAkRW50cnktPlswXSAuICdJbnZhbGlkJyB9CiAgICAgICAgICAgICAgICAgICAgLiAnIiBkYXRhLWN1c3RvbWVyLXNlYXJjaC10eXBlPSJDdXN0b21lcklEIiAvPic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkUGFyYW17T3B0aW9ufSA9ICRMYXlvdXRPYmplY3QtPkJ1aWxkU2VsZWN0aW9uKAogICAgICAgICAgICAgICAgICAgIERhdGEgICAgICAgPT4gXCVDb21wYW55TGlzdCwKICAgICAgICAgICAgICAgICAgICBOYW1lICAgICAgID0+ICRFbnRyeS0+WzBdLAogICAgICAgICAgICAgICAgICAgIE1heCAgICAgICAgPT4gODAsCiAgICAgICAgICAgICAgICAgICAgU2VsZWN0ZWRJRCA9PiAkUGFyYW17ICRFbnRyeS0+WzBdIH0gfHwgJFBhcmFte0N1c3RvbWVySUR9LAogICAgICAgICAgICAgICAgICAgIENsYXNzICAgICAgPT4gIiRQYXJhbXtSZXF1aXJlZENsYXNzfSBNb2Rlcm5pemUgIiAuICRQYXJhbXtFcnJvcnN9LT57ICRFbnRyeS0+WzBdIC4gJ0ludmFsaWQnIH0sCiAgICAgICAgICAgICAgICAgICAgRGlzYWJsZWQgICA9PiAkVXBkYXRlT25seVByZWZlcmVuY2VzID8gMSA6IDAsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2lmICggJFBhcmFte0FjdGlvbn0gZXEgJ0FkZCcgJiYgJEVudHJ5LT5bMF0gPX4gL15Vc2VyQ3VzdG9tZXJJRCQvaSApIHsKCiAgICAgICAgICAgICMgVXNlIEN1c3RvbWVySUQgcGFyYW0gaWYgY2FsbGVkIGZyb20gQ0lDLgogICAgICAgICAgICAkUGFyYW17VmFsdWV9ID0gJFBhcmFteyAkRW50cnktPlswXSB9IHx8ICRQYXJhbXtDdXN0b21lcklEfSB8fCAnJzsKICAgICAgICB9CiAgICAgICAgIyAtLS0KICAgICAgICAjIFJvdGhlck9TUzogQnVpbGQgdGhlIGdyb3VwIGZpZWxkLgogICAgICAgICMgLS0tCiAgICAgICAgZWxzaWYgKCAkRW50cnktPlswXSA9fiAvXlVzZXJHcm91cElEJC9pICkgewogICAgICAgICAgICAjIENoZWNrIGlmIHRoZSB1c2VyIGhhcyB0aGUgcGVybWlzc2lvbiB0byBzZWUvY2hhbmdlIHRoZSBtdWx0aXRlbmFuY3kgZmllbGQuCiAgICAgICAgICAgIGlmICggISRTZWxmLT57TXVsdGl0ZW5hbmN5UGVybWlzc2lvbn0gKSB7CiAgICAgICAgICAgICAgICBuZXh0IEVOVFJZOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgIyBCdWlsZCB0aGUgZmllbGQuCiAgICAgICAgICAgICAgICAkQmxvY2sgPSAnT3B0aW9uJzsKICAgICAgICAgICAgICAgICRQYXJhbXtPcHRpb259ID0gJExheW91dE9iamVjdC0+QnVpbGRTZWxlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpHcm91cCcpLT5Hcm91cExpc3QoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWxpZCA9PiAxLAogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBOYW1lICAgICAgICAgPT4gJEVudHJ5LT5bMF0sCiAgICAgICAgICAgICAgICAgICAgUG9zc2libGVOb25lID0+IDEsCiAgICAgICAgICAgICAgICAgICAgQ2xhc3MgICAgICAgID0+ICdNb2Rlcm5pemUgJyAuICggJFBhcmFte0Vycm9yc30tPnsgJEVudHJ5LT5bMF0gLiAnSW52YWxpZCcgfSB8fCAnJyApLAogICAgICAgICAgICAgICAgICAgIFNlbGVjdGVkSUQgICA9PiAkUGFyYW17ICRFbnRyeS0+WzBdIH0gfHwgJycsCiAgICAgICAgICAgICAgICAgICAgRGlzYWJsZWQgICAgID0+ICRVcGRhdGVPbmx5UHJlZmVyZW5jZXMgPyAxIDogMCwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgIyAtLS0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJFBhcmFte1ZhbHVlfSA9ICRQYXJhbXsgJEVudHJ5LT5bMF0gfSB8fCAnJzsKICAgICAgICB9CgogICAgICAgICMgYWRkIGZvcm0gb3B0aW9uCiAgICAgICAgaWYgKCAkUGFyYW17VHlwZX0gJiYgJFBhcmFte1R5cGV9IGVxICdoaWRkZW4nICkgewogICAgICAgICAgICAkUGFyYW17UHJlZmVyZW5jZXN9IC49ICRQYXJhbXtWYWx1ZX07CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1ByZWZlcmVuY2VzR2VuZXJpYycsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICBJdGVtID0+ICRFbnRyeS0+WzFdLAogICAgICAgICAgICAgICAgICAgICVQYXJhbQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICJQcmVmZXJlbmNlc0dlbmVyaWMkQmxvY2siLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgSXRlbSAgICAgICAgID0+ICRFbnRyeS0+WzFdLAogICAgICAgICAgICAgICAgICAgIE5hbWUgICAgICAgICA9PiAkRW50cnktPlswXSwKICAgICAgICAgICAgICAgICAgICBJbnZhbGlkRmllbGQgPT4gJFBhcmFte0Vycm9yc30tPnsgJEVudHJ5LT5bMF0gLiAnSW52YWxpZCcgfSB8fCAnJywKICAgICAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgIyBhZGQgdGhlIGNvcnJlY3QgY2xpZW50IHNpZGUgZXJyb3IgbXNnCiAgICAgICAgICAgIGlmICggJEJsb2NrIGVxICdJbnB1dCcgJiYgJEVudHJ5LT5bMF0gZXEgJ1VzZXJFbWFpbCcgKSB7CiAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdQcmVmZXJlbmNlc1VzZXJFbWFpbEVycm9yTXNnJywKICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHsgTmFtZSA9PiAkRW50cnktPlswXSB9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gIlByZWZlcmVuY2VzR2VuZXJpY0Vycm9yTXNnIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHsgTmFtZSA9PiAkRW50cnktPlswXSB9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgIyBhZGQgdGhlIGNvcnJlY3Qgc2VydmVyIGVycm9yIG1zZwogICAgICAgICAgICBpZiAoICRCbG9jayBlcSAnSW5wdXQnICYmICRQYXJhbXtVc2VyRW1haWx9ICYmICRFbnRyeS0+WzBdIGVxICdVc2VyRW1haWwnICkgewoKICAgICAgICAgICAgICAgICMgZGlzcGxheSBzZXJ2ZXIgZXJyb3IgbXNnIGFjY29yZGluZyB3aXRoIHRoZSBvY2N1cnJlZCBlbWFpbCBlcnJvciB0eXBlCiAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdQcmVmZXJlbmNlc1VzZXJFbWFpbCcgLiAoICRQYXJhbXtFcnJvcnN9LT57RXJyb3JUeXBlfSB8fCAnJyApLAogICAgICAgICAgICAgICAgICAgIERhdGEgPT4geyBOYW1lID0+ICRFbnRyeS0+WzBdIH0sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAiUHJlZmVyZW5jZXNHZW5lcmljU2VydmVyRXJyb3JNc2ciLAogICAgICAgICAgICAgICAgICAgIERhdGEgPT4geyBOYW1lID0+ICRFbnRyeS0+WzBdIH0sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIG15ICRQcmVmZXJlbmNlc1VzZWQgPSAkQ29uZmlnT2JqZWN0LT5HZXQoICRQYXJhbXtTb3VyY2V9ICktPntBZG1pblNldFByZWZlcmVuY2VzfTsKICAgIGlmICggKCBkZWZpbmVkICRQcmVmZXJlbmNlc1VzZWQgJiYgJFByZWZlcmVuY2VzVXNlZCAhPSAwICkgfHwgIWRlZmluZWQgJFByZWZlcmVuY2VzVXNlZCApIHsKCiAgICAgICAgbXkgJURhdGE7CiAgICAgICAgbXkgJVByZWZlcmVuY2VzID0gJXsgJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclByZWZlcmVuY2VzR3JvdXBzJykgfTsKCiAgICAgICAgR1JPVVA6CiAgICAgICAgZm9yIG15ICRHcm91cCAoIHNvcnQga2V5cyAlUHJlZmVyZW5jZXMgKSB7CgogICAgICAgICAgICBuZXh0IEdST1VQIGlmICEkR3JvdXA7CgogICAgICAgICAgICBteSAkUHJlZmVyZW5jZXNHcm91cCA9ICRQcmVmZXJlbmNlc3skR3JvdXB9OwoKICAgICAgICAgICAgbmV4dCBHUk9VUCBpZiAhJFByZWZlcmVuY2VzR3JvdXA7CiAgICAgICAgICAgIG5leHQgR1JPVVAgaWYgcmVmICRQcmVmZXJlbmNlc0dyb3VwIG5lICdIQVNIJzsKCiAgICAgICAgICAgIGlmICggJERhdGF7ICRQcmVmZXJlbmNlc0dyb3VwLT57UHJpb30gfSApIHsKCiAgICAgICAgICAgICAgICBDT1VOVDoKICAgICAgICAgICAgICAgIGZvciBteSAkQ291bnQgKCAxIC4uIDE1MSApIHsKCiAgICAgICAgICAgICAgICAgICAgJFByZWZlcmVuY2VzR3JvdXAtPntQcmlvfSsrOwoKICAgICAgICAgICAgICAgICAgICBpZiAoICEkRGF0YXsgJFByZWZlcmVuY2VzR3JvdXAtPntQcmlvfSB9ICkgewogICAgICAgICAgICAgICAgICAgICAgICAkRGF0YXsgJFByZWZlcmVuY2VzR3JvdXAtPntQcmlvfSB9ID0gJEdyb3VwOwogICAgICAgICAgICAgICAgICAgICAgICBsYXN0IENPVU5UOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJERhdGF7ICRQcmVmZXJlbmNlc0dyb3VwLT57UHJpb30gfSA9ICRHcm91cDsKICAgICAgICB9CgogICAgICAgICMgc29ydAogICAgICAgIGZvciBteSAkS2V5ICggc29ydCBrZXlzICVEYXRhICkgewogICAgICAgICAgICAkRGF0YXsgc3ByaW50ZiAiJTA3ZCIsICRLZXkgfSA9ICREYXRheyRLZXl9OwogICAgICAgICAgICBkZWxldGUgJERhdGF7JEtleX07CiAgICAgICAgfQoKICAgICAgICAjIHNob3cgZWFjaCBwcmVmZXJlbmNlcyBzZXR0aW5nCiAgICAgICAgUFJJTzoKICAgICAgICBmb3IgbXkgJFByaW8gKCBzb3J0IGtleXMgJURhdGEgKSB7CgogICAgICAgICAgICBteSAkR3JvdXAgPSAkRGF0YXskUHJpb307CiAgICAgICAgICAgIGlmICggISRDb25maWdPYmplY3QtPntDdXN0b21lclByZWZlcmVuY2VzR3JvdXBzfS0+eyRHcm91cH0gKSB7CiAgICAgICAgICAgICAgICBuZXh0IFBSSU87CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG15ICVQcmVmZXJlbmNlID0gJXsgJENvbmZpZ09iamVjdC0+e0N1c3RvbWVyUHJlZmVyZW5jZXNHcm91cHN9LT57JEdyb3VwfSB9OwogICAgICAgICAgICBpZiAoICRHcm91cCBlcSAnUGFzc3dvcmQnICkgewogICAgICAgICAgICAgICAgbmV4dCBQUklPOwogICAgICAgICAgICB9CgogICAgICAgICAgICBteSAkTW9kdWxlID0gJFByZWZlcmVuY2V7TW9kdWxlfQogICAgICAgICAgICAgICAgfHwgJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpDdXN0b21lclByZWZlcmVuY2VzR2VuZXJpYyc7CgogICAgICAgICAgICAjIGxvYWQgbW9kdWxlCiAgICAgICAgICAgIGlmICggJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Ok1haW4nKS0+UmVxdWlyZSgkTW9kdWxlKSApIHsKICAgICAgICAgICAgICAgIG15ICRPYmplY3QgPSAkTW9kdWxlLT5uZXcoCiAgICAgICAgICAgICAgICAgICAgJXskU2VsZn0sCiAgICAgICAgICAgICAgICAgICAgQ29uZmlnSXRlbSA9PiBcJVByZWZlcmVuY2UsCiAgICAgICAgICAgICAgICAgICAgVXNlck9iamVjdCA9PiAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyJyksCiAgICAgICAgICAgICAgICAgICAgRGVidWcgICAgICA9PiAkU2VsZi0+e0RlYnVnfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBteSBAUGFyYW1zID0gJE9iamVjdC0+UGFyYW0oIFVzZXJEYXRhID0+IFwlUGFyYW0gKTsKICAgICAgICAgICAgICAgIGlmIChAUGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIG15ICRQYXJhbUl0ZW0gKEBQYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdJdGVtJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGEgPT4geyVQYXJhbX0sCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZiAkUGFyYW1JdGVtLT57RGF0YX0gZXEgJ0hBU0gnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCByZWYgJFByZWZlcmVuY2V7RGF0YX0gZXEgJ0hBU0gnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15ICVCdWlsZFNlbGVjdGlvblBhcmFtcyA9ICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlUHJlZmVyZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAleyRQYXJhbUl0ZW19LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRCdWlsZFNlbGVjdGlvblBhcmFtc3tDbGFzc30gPSBqb2luKCAnICcsICRCdWlsZFNlbGVjdGlvblBhcmFtc3tDbGFzc30gLy8gJycsICdNb2Rlcm5pemUnICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJFBhcmFtSXRlbS0+e09wdGlvbn0gPSAkTGF5b3V0T2JqZWN0LT5CdWlsZFNlbGVjdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlQnVpbGRTZWxlY3Rpb25QYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJFBhcmFtSXRlbS0+e0Jsb2NrfSB8fCAkUHJlZmVyZW5jZXtCbG9ja30gfHwgJ09wdGlvbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHcm91cCA9PiAkR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICVQcmVmZXJlbmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICV7JFBhcmFtSXRlbX0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAkTGF5b3V0T2JqZWN0LT5GYXRhbEVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgJExheW91dE9iamVjdC0+QWRkSlNEYXRhKAogICAgICAgIEtleSAgID0+ICdOYXYnLAogICAgICAgIFZhbHVlID0+ICRQYXJhbXtOYXZ9LAogICAgKTsKCiAgICByZXR1cm4gJExheW91dE9iamVjdC0+T3V0cHV0KAogICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnQWRtaW5DdXN0b21lclVzZXInLAogICAgICAgIERhdGEgICAgICAgICA9PiBcJVBhcmFtLAogICAgKTsKfQoKc3ViIF9FZmZlY3RpdmVQZXJtaXNzaW9ucyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgb25seSBpZiBjdXN0b21lciBncm91cCBmZWF0dXJlIGlzIGFjdGl2ZQogICAgaWYgKCAhJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKS0+R2V0KCdDdXN0b21lckdyb3VwU3VwcG9ydCcpICkgewogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgICMgZ2V0IG5lZWRlZCBvYmplY3RzCiAgICBteSAkQ29uZmlnT2JqZWN0ICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyk7CiAgICBteSAkTGF5b3V0T2JqZWN0ICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKICAgIG15ICRDdXN0b21lckdyb3VwT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyR3JvdXAnKTsKCiAgICAjIHNob3cgdGFibGVzCiAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICBOYW1lID0+ICdFZmZlY3RpdmVQZXJtaXNzaW9ucycsCiAgICApOwoKICAgIG15ICVHcm91cHM7CiAgICBteSAlUGVybWlzc2lvbnM7CgogICAgIyBnbyB0aHJvdWdoIHBlcm1pc3Npb24gdHlwZXMKICAgIG15IEBUeXBlcyA9IEB7ICRDb25maWdPYmplY3QtPkdldCgnU3lzdGVtOjpDdXN0b21lcjo6UGVybWlzc2lvbicpIH07CiAgICBmb3IgbXkgJFR5cGUgKEBUeXBlcykgewoKICAgICAgICAjIHNob3cgaGVhZGVyCiAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gIkhlYWRlckdyb3VwUGVybWlzc2lvblR5cGUiLAogICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgIFR5cGUgPT4gJFR5cGUsCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKCiAgICAgICAgIyBnZXQgZ3JvdXBzIG9mIHRoZSB1c2VyCiAgICAgICAgbXkgJVVzZXJHcm91cHMgPSAkQ3VzdG9tZXJHcm91cE9iamVjdC0+R3JvdXBNZW1iZXJMaXN0KAogICAgICAgICAgICBVc2VySUQgICAgICAgICA9PiAkUGFyYW17SUR9LAogICAgICAgICAgICBUeXBlICAgICAgICAgICA9PiAkVHlwZSwKICAgICAgICAgICAgUmVzdWx0ICAgICAgICAgPT4gJ0hBU0gnLAogICAgICAgICAgICBSYXdQZXJtaXNzaW9ucyA9PiAwLCAgICAgICAgICAgICMgZ2V0IGVmZmVjdGl2ZSBwZXJtaXNzaW9ucwogICAgICAgICk7CgogICAgICAgICMgc3RvcmUgZGF0YSBpbiBsb29rdXAgaGFzaGVzCiAgICAgICAgZm9yIG15ICRHcm91cElEICggc29ydCBrZXlzICVVc2VyR3JvdXBzICkgewogICAgICAgICAgICAkR3JvdXBzeyRHcm91cElEfSA9ICRVc2VyR3JvdXBzeyRHcm91cElEfTsKICAgICAgICAgICAgJFBlcm1pc3Npb25zeyRHcm91cElEfXskVHlwZX0gPSAxOwogICAgICAgIH0KICAgIH0KCiAgICAjIHNob3cgbWVzc2FnZSBpZiBubyBwZXJtaXNzaW9ucyBmb3VuZAogICAgaWYgKCAhJVBlcm1pc3Npb25zICkgewogICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICBOYW1lID0+ICdOb0dyb3VwUGVybWlzc2lvbnNGb3VuZE1zZycsCiAgICAgICAgKTsKICAgIH0KCiAgICAjIGdvIHRocm91Z2ggZ3JvdXBzLCBzb3J0IGJ5IG5hbWUKICAgIGVsc2UgewogICAgICAgIGZvciBteSAkR3JvdXBJRCAoIHNvcnQgeyB1YyggJEdyb3Vwc3skYX0gKSBjbXAgdWMoICRHcm91cHN7JGJ9ICkgfSBrZXlzICVHcm91cHMgKSB7CgogICAgICAgICAgICAjIHNob3cgdGFibGUgcm93cwogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ0dyb3VwUGVybWlzc2lvblRhYmxlUm93JywKICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgIElEICAgPT4gJEdyb3VwSUQsCiAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAkR3JvdXBzeyRHcm91cElEfSwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAjIHNob3cgcGVybWlzc2lvbiBtYXJrcwogICAgICAgICAgICBmb3IgbXkgJFR5cGUgKEBUeXBlcykgewogICAgICAgICAgICAgICAgbXkgJFBlcm1pc3Npb25NYXJrID0gJFBlcm1pc3Npb25zeyRHcm91cElEfXskVHlwZX0gPyAnT24nICAgICAgICA6ICdPZmYnOwogICAgICAgICAgICAgICAgbXkgJEhpZ2hsaWdodE1hcmsgID0gJFR5cGUgZXEgJ3J3JyAgICAgICAgICAgICAgICAgPyAnSGlnaGxpZ2h0JyA6ICcnOwogICAgICAgICAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAnR3JvdXBQZXJtaXNzaW9uTWFyaycsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAnR3JvdXBQZXJtaXNzaW9uTWFyaycgLiAkUGVybWlzc2lvbk1hcmssCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIEhpZ2hsaWdodCA9PiAkSGlnaGxpZ2h0TWFyaywKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjIGdldCBhbGwgYWNjZXNzaWJsZSBjdXN0b21lcnMgb2YgdGhlIHVzZXIKICAgIG15ICVDdXN0b21lcnMgPSAkQ3VzdG9tZXJHcm91cE9iamVjdC0+R3JvdXBDb250ZXh0Q3VzdG9tZXJzKAogICAgICAgIEN1c3RvbWVyVXNlcklEID0+ICRQYXJhbXtJRH0sCiAgICApOwoKICAgICMgc2hvdyBtZXNzYWdlIGlmIG5vIGN1c3RvbWVycyBmb3VuZAogICAgaWYgKCAhJUN1c3RvbWVycyApIHsKICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnTm9DdXN0b21lckFjY2Vzc0ZvdW5kTXNnJywKICAgICAgICApOwogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgICMgZ2V0IHBlcm1pc3Npb24gY29udGV4dHMKICAgIG15ICRDb250ZXh0Q29uZmlnICAgICAgICAgICAgPSAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyR3JvdXBQZXJtaXNzaW9uQ29udGV4dCcpOwogICAgbXkgJERpcmVjdEFjY2Vzc0NvbnRleHRLZXkgICA9ICcwMDEtQ3VzdG9tZXJJRC1zYW1lJzsKICAgIG15ICRJbmRpcmVjdEFjY2Vzc0NvbnRleHRLZXkgPSAnMTAwLUN1c3RvbWVySUQtb3RoZXInOwoKICAgICMgdXNlIGRlZmF1bHQgY29udGV4dCBpZiBub25lIGFyZSBmb3VuZAogICAgaWYgKCAhSXNIYXNoUmVmV2l0aERhdGEoJENvbnRleHRDb25maWcpICkgewogICAgICAgICRDb250ZXh0Q29uZmlnID0gewogICAgICAgICAgICAkRGlyZWN0QWNjZXNzQ29udGV4dEtleSA9PiB7CiAgICAgICAgICAgICAgICBOYW1lID0+IFRyYW5zbGF0YWJsZSgnU2FtZSBDdXN0b21lcicpLAogICAgICAgICAgICB9LAogICAgICAgIH07CiAgICB9CgogICAgIyBzaG93IGRlZmF1bHQgYW5kIGV4dHJhIGNvbnRleHQgaGVhZGVycyBpZiBhdmFpbGFibGUKICAgIGlmICggJENvbnRleHRDb25maWctPnskRGlyZWN0QWNjZXNzQ29udGV4dEtleX0gKSB7CiAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ0hlYWRlckN1c3RvbWVyQWNjZXNzQ29udGV4dCcsCiAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgTmFtZSA9PiBUcmFuc2xhdGFibGUoJ0RpcmVjdCcpLAogICAgICAgICAgICB9LAogICAgICAgICk7CiAgICB9CiAgICBpZiAoICRDb250ZXh0Q29uZmlnLT57JEluZGlyZWN0QWNjZXNzQ29udGV4dEtleX0gKSB7CiAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ0hlYWRlckN1c3RvbWVyQWNjZXNzQ29udGV4dCcsCiAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgTmFtZSA9PiBUcmFuc2xhdGFibGUoJ0luZGlyZWN0JyksCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKICAgIH0KCiAgICAjIGRldGVybWluZSBjdXN0b21lcnMgZm9yIGRpcmVjdCBhbmQgaW5kaXJlY3QgYWNjZXNzCiAgICBteSBAVXNlckN1c3RvbWVySURzID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlcicpLT5DdXN0b21lcklEcygKICAgICAgICBVc2VyID0+ICRQYXJhbXtJRH0sCiAgICApOwogICAgbXkgJUV4dHJhQ3VzdG9tZXJJRHM7CiAgICBpZiAoICRDb250ZXh0Q29uZmlnLT57JEluZGlyZWN0QWNjZXNzQ29udGV4dEtleX0gKSB7CiAgICAgICAgbXkgJEV4dHJhQ29udGV4dE5hbWUgPSAkQ3VzdG9tZXJHcm91cE9iamVjdC0+R3JvdXBDb250ZXh0TmFtZUdldCgKICAgICAgICAgICAgU3lzQ29uZmlnTmFtZSA9PiAkSW5kaXJlY3RBY2Nlc3NDb250ZXh0S2V5LAogICAgICAgICk7CgogICAgICAgICMgZm9yIGFsbCBDdXN0b21lcklEcyBnZXQgZ3JvdXBzIHdpdGggZXh0cmEgYWNjZXNzCiAgICAgICAgbXkgJUV4dHJhUGVybWlzc2lvbkdyb3VwczsKICAgICAgICBDVVNUT01FUklEOgogICAgICAgIGZvciBteSAkQ3VzdG9tZXJJRCAoQFVzZXJDdXN0b21lcklEcykgewogICAgICAgICAgICBteSAlR3JvdXBMaXN0ID0gJEN1c3RvbWVyR3JvdXBPYmplY3QtPkdyb3VwQ3VzdG9tZXJMaXN0KAogICAgICAgICAgICAgICAgQ3VzdG9tZXJJRCA9PiAkQ3VzdG9tZXJJRCwKICAgICAgICAgICAgICAgIFR5cGUgICAgICAgPT4gJ3JvJywKICAgICAgICAgICAgICAgIENvbnRleHQgICAgPT4gJEV4dHJhQ29udGV4dE5hbWUsCiAgICAgICAgICAgICAgICBSZXN1bHQgICAgID0+ICdIQVNIJywKICAgICAgICAgICAgKTsKICAgICAgICAgICAgbmV4dCBDVVNUT01FUklEIGlmICElR3JvdXBMaXN0OwoKICAgICAgICAgICAgIyBhZGQgdG8gZ3JvdXBzCiAgICAgICAgICAgICVFeHRyYVBlcm1pc3Npb25Hcm91cHMgPSAoCiAgICAgICAgICAgICAgICAlRXh0cmFQZXJtaXNzaW9uR3JvdXBzLAogICAgICAgICAgICAgICAgJUdyb3VwTGlzdCwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICMgYWRkIGFsbCB1bmlxdWUgYWNjZXNzaWJsZSBHcm91cDwtPkN1c3RvbWVyIGNvbWJpbmF0aW9ucwogICAgICAgIEdST1VQSUQ6CiAgICAgICAgZm9yIG15ICRHcm91cElEICggc29ydCBrZXlzICVFeHRyYVBlcm1pc3Npb25Hcm91cHMgKSB7CiAgICAgICAgICAgIG15IEBHcm91cEN1c3RvbWVySURzID0gJEN1c3RvbWVyR3JvdXBPYmplY3QtPkdyb3VwQ3VzdG9tZXJMaXN0KAogICAgICAgICAgICAgICAgR3JvdXBJRCA9PiAkR3JvdXBJRCwKICAgICAgICAgICAgICAgIFR5cGUgICAgPT4gJ3JvJywKICAgICAgICAgICAgICAgIFJlc3VsdCAgPT4gJ0lEJywKICAgICAgICAgICAgKTsKICAgICAgICAgICAgbmV4dCBHUk9VUElEIGlmICFAR3JvdXBDdXN0b21lcklEczsKCiAgICAgICAgICAgICMgYWRkIHRvIEV4dHJhQ3VzdG9tZXJJRHMKICAgICAgICAgICAgJUV4dHJhQ3VzdG9tZXJJRHMgPSAoCiAgICAgICAgICAgICAgICAlRXh0cmFDdXN0b21lcklEcywKICAgICAgICAgICAgICAgIG1hcCB7ICRfID0+IDEgfSBAR3JvdXBDdXN0b21lcklEcywKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgIyBnbyB0aHJvdWdoIGN1c3RvbWVycwogICAgQ1VTVE9NRVJJRDoKICAgIGZvciBteSAkQ3VzdG9tZXJJRCAoIHNvcnQga2V5cyAlQ3VzdG9tZXJzICkgewoKICAgICAgICAjIHNob3cgdGFibGUgcm93cwogICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICBOYW1lID0+ICdDdXN0b21lckFjY2Vzc1RhYmxlUm93JywKICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICBJRCAgID0+ICRDdXN0b21lcklELAogICAgICAgICAgICAgICAgTmFtZSA9PiAkQ3VzdG9tZXJzeyRDdXN0b21lcklEfSwKICAgICAgICAgICAgfSwKICAgICAgICApOwoKICAgICAgICAjICdTYW1lIEN1c3RvbWVyJwogICAgICAgIGlmICggJENvbnRleHRDb25maWctPnskRGlyZWN0QWNjZXNzQ29udGV4dEtleX0gKSB7CgogICAgICAgICAgICAjIGNoZWNrIGlmIHdlIHNob3VsZCBzaG93IGNoZWNrIG1hcmsgZm9yICdTYW1lIEN1c3RvbWVyJwogICAgICAgICAgICBteSAkQWNjZXNzTWFyayA9ICggZ3JlcCB7ICRfIGVxICRDdXN0b21lcklEIH0gQFVzZXJDdXN0b21lcklEcyApID8gJ09uJyA6ICdPZmYnOwoKICAgICAgICAgICAgIyBzaG93IGJsb2NrcwogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ0N1c3RvbWVyQWNjZXNzTWFyaycsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnQ3VzdG9tZXJBY2Nlc3NNYXJrJyAuICRBY2Nlc3NNYXJrLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyAnT3RoZXIgQ3VzdG9tZXJzJwogICAgICAgIG5leHQgQ1VTVE9NRVJJRCBpZiAhJENvbnRleHRDb25maWctPnskSW5kaXJlY3RBY2Nlc3NDb250ZXh0S2V5fTsKCiAgICAgICAgIyBjaGVjayBpZiB3ZSBzaG91bGQgc2hvdyBjaGVjayBtYXJrIGZvciAnT3RoZXIgQ3VzdG9tZXJzJwogICAgICAgIG15ICRBY2Nlc3NNYXJrID0gJEV4dHJhQ3VzdG9tZXJJRHN7JEN1c3RvbWVySUR9ID8gJ09uJyA6ICdPZmYnOwoKICAgICAgICAjIHNob3cgYmxvY2tzCiAgICAgICAgJExheW91dE9iamVjdC0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ0N1c3RvbWVyQWNjZXNzTWFyaycsCiAgICAgICAgKTsKICAgICAgICAkTGF5b3V0T2JqZWN0LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnQ3VzdG9tZXJBY2Nlc3NNYXJrJyAuICRBY2Nlc3NNYXJrLAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCjE7Cg==
IyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIxIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDIxIFpudW55IEdtYkgsIGh0dHBzOi8vem51bnkub3JnLwojIENvcHlyaWdodCAoQykgMjAyMSBSb3RoZXIgT1NTIEdtYkgsIGh0dHBzOi8vcm90aGVyLW9zcy5jb20vCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0zLjAudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpDdXN0b21lckNvbXBhbnk6OkRCOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYXJpYWJsZUNoZWNrIHF3KDphbGwpOwoKb3VyIEBPYmplY3REZXBlbmRlbmNpZXMgPSAoCiAgICAnS2VybmVsOjpTeXN0ZW06OkNhY2hlJywKICAgICdLZXJuZWw6OlN5c3RlbTo6REInLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpMb2cnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcsCik7CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgZ2V0IGN1c3RvbWVyIGNvbXBhbnkgbWFwCiAgICAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0gPSAkUGFyYW17Q3VzdG9tZXJDb21wYW55TWFwfSB8fCBkaWUgIkdvdCBubyBDdXN0b21lckNvbXBhbnlNYXAhIjsKCiAgICAjIGNvbmZpZyBvcHRpb25zCiAgICAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueVRhYmxlfSA9ICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e1BhcmFtc30tPntUYWJsZX0KICAgICAgICB8fCBkaWUgIk5lZWQgQ3VzdG9tZXJDb21wYW55LT5QYXJhbXMtPlRhYmxlIGluIEtlcm5lbC9Db25maWcucG0hIjsKICAgICRTZWxmLT57Q3VzdG9tZXJDb21wYW55S2V5fSA9ICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e0N1c3RvbWVyQ29tcGFueUtleX0KICAgICAgICB8fCBkaWUgIk5lZWQgQ3VzdG9tZXJDb21wYW55LT5DdXN0b21lckNvbXBhbnlLZXkgaW4gS2VybmVsL0NvbmZpZy5wbSEiOwogICAgJFNlbGYtPntDdXN0b21lckNvbXBhbnlWYWxpZH0gPSAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPnsnQ3VzdG9tZXJDb21wYW55VmFsaWQnfTsKICAgICRTZWxmLT57U2VhcmNoTGlzdExpbWl0fSAgICAgID0gJFNlbGYtPntDdXN0b21lckNvbXBhbnlNYXB9LT57J0N1c3RvbWVyQ29tcGFueVNlYXJjaExpc3RMaW1pdCd9IHx8IDUwMDAwOwogICAgJFNlbGYtPntTZWFyY2hQcmVmaXh9ICAgICAgICAgPSAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPnsnQ3VzdG9tZXJDb21wYW55U2VhcmNoUHJlZml4J307CgogICAgaWYgKCAhZGVmaW5lZCggJFNlbGYtPntTZWFyY2hQcmVmaXh9ICkgKSB7CiAgICAgICAgJFNlbGYtPntTZWFyY2hQcmVmaXh9ID0gJyc7CiAgICB9CiAgICAkU2VsZi0+e1NlYXJjaFN1ZmZpeH0gPSAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPnsnQ3VzdG9tZXJDb21wYW55U2VhcmNoU3VmZml4J307CiAgICBpZiAoICFkZWZpbmVkKCAkU2VsZi0+e1NlYXJjaFN1ZmZpeH0gKSApIHsKICAgICAgICAkU2VsZi0+e1NlYXJjaFN1ZmZpeH0gPSAnKic7CiAgICB9CgogICAgIyBjcmVhdGUgY2FjaGUgb2JqZWN0LCBidXQgb25seSBpZiBDYWNoZVRUTCBpcyBzZXQgaW4gY3VzdG9tZXIgY29uZmlnCiAgICBpZiAoICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e0NhY2hlVFRMfSApIHsKICAgICAgICAkU2VsZi0+e0NhY2hlT2JqZWN0fSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDYWNoZScpOwogICAgICAgICRTZWxmLT57Q2FjaGVUeXBlfSAgID0gJ0N1c3RvbWVyQ29tcGFueScgLiAkUGFyYW17Q291bnR9OwogICAgICAgICRTZWxmLT57Q2FjaGVUVEx9ICAgID0gJFNlbGYtPntDdXN0b21lckNvbXBhbnlNYXB9LT57Q2FjaGVUVEx9IHx8IDA7CiAgICB9CgogICAgIyBnZXQgZGF0YWJhc2Ugb2JqZWN0CiAgICAkU2VsZi0+e0RCT2JqZWN0fSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEQicpOwoKICAgICMgY3JlYXRlIG5ldyBkYiBjb25uZWN0IGlmIERTTiBpcyBnaXZlbgogICAgaWYgKCAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntQYXJhbXN9LT57RFNOfSApIHsKICAgICAgICAkU2VsZi0+e0RCT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpEQi0+bmV3KAogICAgICAgICAgICBEYXRhYmFzZURTTiAgPT4gJFNlbGYtPntDdXN0b21lckNvbXBhbnlNYXB9LT57UGFyYW1zfS0+e0RTTn0sCiAgICAgICAgICAgIERhdGFiYXNlVXNlciA9PiAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntQYXJhbXN9LT57VXNlcn0sCiAgICAgICAgICAgIERhdGFiYXNlUHcgICA9PiAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntQYXJhbXN9LT57UGFzc3dvcmR9LAogICAgICAgICAgICBUeXBlICAgICAgICAgPT4gJFNlbGYtPntDdXN0b21lckNvbXBhbnlNYXB9LT57UGFyYW1zfS0+e1R5cGV9IHx8ICcnLAogICAgICAgICkgfHwgZGllKCdDYW5cJ3QgY29ubmVjdCB0byBkYXRhYmFzZSEnKTsKCiAgICAgICAgIyByZW1lbWJlciB0aGF0IHdlIGhhdmUgdGhlIERCT2JqZWN0IG5vdCBmcm9tIHBhcmVudCBjYWxsCiAgICAgICAgJFNlbGYtPntOb3RQYXJlbnREQk9iamVjdH0gPSAxOwogICAgfQoKICAgICMgdGhpcyBzZXR0aW5nIHNwZWNpZmllcyBpZiB0aGUgdGFibGUgaGFzIHRoZSBjcmVhdGVfdGltZSwKICAgICMgY3JlYXRlX2J5LCBjaGFuZ2VfdGltZSBhbmQgY2hhbmdlX2J5IGZpZWxkcyBvZiBPVFJTCiAgICAkU2VsZi0+e0ZvcmVpZ25EQn0gPSAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntQYXJhbXN9LT57Rm9yZWlnbkRCfSA/IDEgOiAwOwoKICAgICMgZGVmaW5lcyBpZiB0aGUgZGF0YWJhc2Ugc2VhcmNoIHdpbGwgYmUgcGVyZm9ybWVuZCBjYXNlIHNlbnNpdGl2ZSAoMSkgb3Igbm90ICgwKQogICAgJFNlbGYtPntDYXNlU2Vuc2l0aXZlfSA9ICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e1BhcmFtc30tPntTZWFyY2hDYXNlU2Vuc2l0aXZlfQogICAgICAgIC8vICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e1BhcmFtc30tPntDYXNlU2Vuc2l0aXZlfSB8fCAwOwoKICAgICMgZmV0Y2ggbmFtZXMgb2YgY29uZmlndXJlZCBkeW5hbWljIGZpZWxkcwogICAgbXkgQER5bmFtaWNGaWVsZE1hcEVudHJpZXMgPSBncmVwIHsgJF8tPls1XSBlcSAnZHluYW1pY19maWVsZCcgfSBAeyAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntNYXB9IH07CiAgICAkU2VsZi0+e0NvbmZpZ3VyZWREeW5hbWljRmllbGROYW1lc30gPSB7IG1hcCB7ICRfLT5bMl0gPT4gMSB9IEBEeW5hbWljRmllbGRNYXBFbnRyaWVzIH07CgogICAgIyAtLS0KICAgICMgUm90aGVyT1NTOgogICAgIyAtLS0KICAgIG15ICRMYXlvdXRQYXJhbSA9ICRLZXJuZWw6Ok9NLT57UGFyYW19LT57J0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnfTsKICAgIG15ICRDb25maWdPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwoKICAgICMgQ2hlY2sgaWYgbXVsdGl0ZW5hbmN5IGlzIGVuYWJsZWQgYW5kIHRoZSByZXF1ZXN0IGlzIGNvbWluZyBmcm9tIGEgdXNlci4KICAgIGlmICggJExheW91dFBhcmFtLT57VXNlclR5cGV9ICYmICRMYXlvdXRQYXJhbS0+e1VzZXJUeXBlfSBlcSAnVXNlcicgJiYgJENvbmZpZ09iamVjdC0+R2V0KCdNdWx0aXRlbmFuY3knKSApIHsKCiAgICAgICAgIyBTYXZlIHRoZSBVc2VySUQgYW5kIGFsbCBncm91cHMgdGhlIHVzZXIgaGFzICdybycgcGVybWlzc2lvbiBvbi4KICAgICAgICBpZiAoICRMYXlvdXRQYXJhbS0+e1VzZXJJRH0gKSB7CiAgICAgICAgICAgICMgT25seSBnZXQgdGhlIGdyb3VwIGxpc3Qgb25jZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucy4KICAgICAgICAgICAgbXkgJUdyb3VwcyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpHcm91cCcpLT5QZXJtaXNzaW9uVXNlckdldCgKICAgICAgICAgICAgICAgIFVzZXJJRCA9PiAkTGF5b3V0UGFyYW0tPntVc2VySUR9LAogICAgICAgICAgICAgICAgVHlwZSAgID0+ICdybycsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAjIFRoZSBsaW1pdCBkb2VzIG5vdCBjb3VudCBmb3IgbWVtYmVycyBvZiBhIHNwZWNpZmljIGdyb3VwLgogICAgICAgICAgICBteSAkUGVybWlzc2lvbkdyb3VwID0gJENvbmZpZ09iamVjdC0+R2V0KCdNdWx0aXRlbmFuY3k6OlBlcm1pc3Npb25Hcm91cCcpIHx8ICcnOwogICAgICAgICAgICBteSAlR3JvdXBzUmV2ZXJzZSAgID0gcmV2ZXJzZSAlR3JvdXBzOwoKICAgICAgICAgICAgaWYgKCAhJEdyb3Vwc1JldmVyc2V7JFBlcm1pc3Npb25Hcm91cH0gKSB7CiAgICAgICAgICAgICAgICAkU2VsZi0+e011bHRpdGVuYW5jeX0gPSAkTGF5b3V0UGFyYW0tPntVc2VySUR9OwogICAgICAgICAgICAgICAgJFNlbGYtPntVc2VyR3JvdXBJRHN9ID0gWyBzb3J0IGtleXMgJUdyb3VwcyBdOwogICAgICAgICAgICAgICAgJFNlbGYtPntVc2VyR3JvdXBzfSAgID0gWyB2YWx1ZXMgJUdyb3VwcyBdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgIyAtLS0KCiAgICByZXR1cm4gJFNlbGY7Cn0KCnN1YiBDdXN0b21lckNvbXBhbnlMaXN0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIG15ICRWYWxpZCA9IDE7CiAgICBpZiAoICEkUGFyYW17VmFsaWR9ICYmIGRlZmluZWQoICRQYXJhbXtWYWxpZH0gKSApIHsKICAgICAgICAkVmFsaWQgPSAwOwogICAgfQoKICAgIG15ICRMaW1pdCA9ICRQYXJhbXtMaW1pdH0gLy8gJFNlbGYtPntTZWFyY2hMaXN0TGltaXR9OwoKICAgIG15ICRDYWNoZVR5cGU7CiAgICBteSAkQ2FjaGVLZXk7CgogICAgIyBjaGVjayBjYWNoZQogICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICAkQ2FjaGVUeXBlID0gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lckNvbXBhbnlMaXN0JzsKICAgICAgICAkQ2FjaGVLZXkgID0gIkN1c3RvbWVyQ29tcGFueUxpc3Q6OiR7VmFsaWR9Ojoke0xpbWl0fTo6IiAuICggJFBhcmFte1NlYXJjaH0gfHwgJycgKTsKICAgICAgICAjIC0tLQogICAgICAgICMgUm90aGVyT1NTOiBVc2UgY2FjaGUgZm9yIG11bHRpdGVuYW5jeS4KICAgICAgICAjIC0tLQogICAgICAgIGlmICggJFNlbGYtPntNdWx0aXRlbmFuY3l9ICkgewogICAgICAgICAgICAkQ2FjaGVLZXkgLj0gam9pbiAnJywgbWFwIHsgJzo6R3JvdXBJRD0nIC4gJF8gfSBAeyAkU2VsZi0+e1VzZXJHcm91cElEc30gfTsKICAgICAgICB9CiAgICAgICAgIyAtLS0KICAgICAgICBteSAkRGF0YSA9ICRTZWxmLT57Q2FjaGVPYmplY3R9LT5HZXQoCiAgICAgICAgICAgIFR5cGUgPT4gJENhY2hlVHlwZSwKICAgICAgICAgICAgS2V5ICA9PiAkQ2FjaGVLZXksCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gJXskRGF0YX0gaWYgcmVmICREYXRhIGVxICdIQVNIJzsKICAgIH0KCiAgICBteSAkQ3VzdG9tZXJDb21wYW55TGlzdEZpZWxkcyA9ICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e0N1c3RvbWVyQ29tcGFueUxpc3RGaWVsZHN9OwogICAgaWYgKCAhSXNBcnJheVJlZldpdGhEYXRhKCRDdXN0b21lckNvbXBhbnlMaXN0RmllbGRzKSApIHsKICAgICAgICAkQ3VzdG9tZXJDb21wYW55TGlzdEZpZWxkcyA9IFsgJ2N1c3RvbWVyX2lkJywgJ25hbWUnLCBdOwogICAgfQoKICAgICMgcmVtb3ZlIGR5bmFtaWMgZmllbGQgbmFtZXMgdGhhdCBhcmUgY29uZmlndXJlZCBpbiBDdXN0b21lckNvbXBhbnlMaXN0RmllbGRzCiAgICAjIGFzIHRoZXkgY2Fubm90IGJlIGhhbmRsZWQgaGVyZQogICAgbXkgQEN1c3RvbWVyQ29tcGFueUxpc3RGaWVsZHNXaXRob3V0RHluYW1pY0ZpZWxkcwogICAgICAgID0gZ3JlcCB7ICFleGlzdHMgJFNlbGYtPntDb25maWd1cmVkRHluYW1pY0ZpZWxkTmFtZXN9LT57JF99IH0gQHskQ3VzdG9tZXJDb21wYW55TGlzdEZpZWxkc307CgogICAgIyB3aGF0IGlzIHRoZSByZXN1bHQKICAgIG15ICRXaGF0ID0gam9pbigKICAgICAgICAnLCAnLAogICAgICAgIEBDdXN0b21lckNvbXBhbnlMaXN0RmllbGRzV2l0aG91dER5bmFtaWNGaWVsZHMKICAgICk7CgogICAgIyBhZGQgdmFsaWQgb3B0aW9uIGlmIHJlcXVpcmVkCiAgICBteSAkU1FMOwogICAgbXkgQEJpbmQ7CiAgICBteSBAQ29uZGl0aW9uczsKCiAgICBpZiAoICRWYWxpZCAmJiAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueVZhbGlkfSApIHsKCiAgICAgICAgIyBnZXQgdmFsaWQgb2JqZWN0CiAgICAgICAgbXkgJFZhbGlkT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlZhbGlkJyk7CgogICAgICAgIHB1c2ggQENvbmRpdGlvbnMsICIkU2VsZi0+e0N1c3RvbWVyQ29tcGFueVZhbGlkfSBJTiAoICR7XChqb2luICcsICcsICRWYWxpZE9iamVjdC0+VmFsaWRJRHNHZXQoKSl9ICkiOwogICAgfQoKICAgICMgd2hlcmUKICAgIGlmICggJFBhcmFte1NlYXJjaH0gKSB7CgogICAgICAgICMgcmVtb3ZlIGR5bmFtaWMgZmllbGQgbmFtZXMgdGhhdCBhcmUgY29uZmlndXJlZCBpbiBDdXN0b21lckNvbXBhbnlTZWFyY2hGaWVsZHMKICAgICAgICAjIGFzIHRoZXkgY2Fubm90IGJlIHJldHJpZXZlZCBoZXJlCiAgICAgICAgbXkgQEN1c3RvbWVyQ29tcGFueVNlYXJjaEZpZWxkcyA9IGdyZXAgeyAhZXhpc3RzICRTZWxmLT57Q29uZmlndXJlZER5bmFtaWNGaWVsZE5hbWVzfS0+eyRffSB9CiAgICAgICAgICAgIEB7ICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e0N1c3RvbWVyQ29tcGFueVNlYXJjaEZpZWxkc30gfTsKCiAgICAgICAgbXkgJVF1ZXJ5Q29uZGl0aW9uID0gJFNlbGYtPntEQk9iamVjdH0tPlF1ZXJ5Q29uZGl0aW9uKAogICAgICAgICAgICBLZXkgICAgICAgICAgID0+IFxAQ3VzdG9tZXJDb21wYW55U2VhcmNoRmllbGRzLAogICAgICAgICAgICBWYWx1ZSAgICAgICAgID0+ICRQYXJhbXtTZWFyY2h9LAogICAgICAgICAgICBTZWFyY2hQcmVmaXggID0+ICRTZWxmLT57U2VhcmNoUHJlZml4fSwKICAgICAgICAgICAgU2VhcmNoU3VmZml4ICA9PiAkU2VsZi0+e1NlYXJjaFN1ZmZpeH0sCiAgICAgICAgICAgIENhc2VTZW5zaXRpdmUgPT4gJFNlbGYtPntDYXNlU2Vuc2l0aXZlfSwKICAgICAgICAgICAgQmluZE1vZGUgICAgICA9PiAxLAogICAgICAgICk7CgogICAgICAgIGlmICggJFF1ZXJ5Q29uZGl0aW9ue1NRTH0gKSB7CiAgICAgICAgICAgIHB1c2ggQENvbmRpdGlvbnMsICIgJFF1ZXJ5Q29uZGl0aW9ue1NRTH0iOwogICAgICAgICAgICBwdXNoIEBCaW5kLCAgICAgICBAeyAkUXVlcnlDb25kaXRpb257VmFsdWVzfSB9OwogICAgICAgIH0KCiAgICAgICAgIyAtLS0KICAgICAgICAjIFJvdGhlck9TUzogRG9uJ3Qgc2VhcmNoIGZvciBjdXN0b21lciB3aXRob3V0IGdyb3VwIHBlcm1pc3Npb24uCiAgICAgICAgIyAtLS0KICAgICAgICBpZiAoICRTZWxmLT57TXVsdGl0ZW5hbmN5fSApIHsKICAgICAgICAgICAgIyBHZXQgdGhlIGNvbHVtbiBuYW1lIHdoZXJlIHRoZSBncm91cCBJRCBpcyBzdG9yZWQuCiAgICAgICAgICAgIG15ICRHcm91cElEQ29sOwogICAgICAgICAgICBmb3IgbXkgJE1hcCAoIEB7ICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e01hcH0gfSApIHsKICAgICAgICAgICAgICAgIGlmICggJE1hcC0+WzBdIGVxICdVc2VyR3JvdXBJRCcgKSB7CiAgICAgICAgICAgICAgICAgICAgJEdyb3VwSURDb2wgPSAkTWFwLT5bMl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgkR3JvdXBJRENvbCkgewogICAgICAgICAgICAgICAgbXkgQFVzZXJHcm91cElEcyA9IEB7ICRTZWxmLT57VXNlckdyb3VwSURzfSB9OyAgIyBOb3Qgc2F2aW5nIHRoaXMgaW4gYW4gYXJyYXkgY2FuIGNhdXNlIGFuIHVua293biBlcnJvciBpbiBhIGxhdGVyIGl0ZXJhdGlvbi4KICAgICAgICAgICAgICAgIG15ICRVc2VyR3JvdXBJRFN5bmMgPSAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntVc2VyR3JvdXBJRFN5bmN9OwogICAgICAgICAgICAgICAgaWYgKCAkVXNlckdyb3VwSURTeW5jLT57UmVtb3RlR3JvdXBUb0xvY2FsR3JvdXB9ICkgewoKICAgICAgICAgICAgICAgICAgICAjIENoZWNrIGlmIGdyb3VwIElEcyBvciBuYW1lcyBzaG91bGQgYmUgY2hlY2tlZC4KICAgICAgICAgICAgICAgICAgICBpZiAoICRVc2VyR3JvdXBJRFN5bmMtPntVc2VHcm91cE5hbWVzfSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIG15ICRVc2VyR3JvdXBJRCAoIEBVc2VyR3JvdXBJRHMgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBteSAkR3JvdXBOYW1lID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Okdyb3VwJyktPkdyb3VwTG9va3VwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdyb3VwSUQgPT4gJFVzZXJHcm91cElELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRVc2VyR3JvdXBJRCA9ICRHcm91cE5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyBSZXBsYWNlIHRoZSBsb2NhbCBncm91cCB3aXRoIHRoZSBhc3NvY2lhdGVkIHJlbW90ZSBncm91cC4KICAgICAgICAgICAgICAgIGZvciBteSAkUmVtb3RlR3JvdXAgKCBrZXlzICV7ICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH0gfSApIHsKICAgICAgICAgICAgICAgICAgICBteSAkTG9jYWxHcm91cCA9ICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH17JFJlbW90ZUdyb3VwfTsKCiAgICAgICAgICAgICAgICAgICAgZm9yIG15ICRVc2VyR3JvdXBJRCAoIEBVc2VyR3JvdXBJRHMgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggJFVzZXJHcm91cElEIGVxICRMb2NhbEdyb3VwICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJFVzZXJHcm91cElEID0gJFJlbW90ZUdyb3VwOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG15ICRJbkNvbmRpdGlvbiA9ICRTZWxmLT57REJPYmplY3R9LT5RdWVyeUluQ29uZGl0aW9uKAogICAgICAgICAgICAgICAgICAgIEtleSAgICAgID0+ICRHcm91cElEQ29sLAogICAgICAgICAgICAgICAgICAgIFZhbHVlcyAgID0+IFxAVXNlckdyb3VwSURzLAogICAgICAgICAgICAgICAgICAgIEJpbmRNb2RlID0+IDAsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICRJbkNvbmRpdGlvbiAuPSAiIE9SICgkR3JvdXBJRENvbCBJUyBOVUxMIE9SICRHcm91cElEQ29sID0gJycpIjsKICAgICAgICAgICAgICAgIHB1c2ggQENvbmRpdGlvbnMsICIgKCRJbkNvbmRpdGlvbikiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICMgLS0tCiAgICB9CgogICAgIyBkeW5hbWljIGZpZWxkIGhhbmRsaW5nCiAgICBteSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQnKTsKCiAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlncyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKS0+RHluYW1pY0ZpZWxkTGlzdEdldCgKICAgICAgICBPYmplY3RUeXBlID0+ICdDdXN0b21lckNvbXBhbnknLAogICAgICAgIFZhbGlkICAgICAgPT4gMSwKICAgICk7CiAgICBteSAlRHluYW1pY0ZpZWxkQ29uZmlnc0J5TmFtZSA9IG1hcCB7ICRfLT57TmFtZX0gPT4gJF8gfSBAeyREeW5hbWljRmllbGRDb25maWdzfTsKCiAgICBteSBAQ3VzdG9tZXJDb21wYW55TGlzdEZpZWxkc0R5bmFtaWNGaWVsZHMKICAgICAgICA9IGdyZXAgeyBleGlzdHMgJFNlbGYtPntDb25maWd1cmVkRHluYW1pY0ZpZWxkTmFtZXN9LT57JF99IH0gQHskQ3VzdG9tZXJDb21wYW55TGlzdEZpZWxkc307CgogICAgIyBzcWwKICAgIG15ICRDb21wbGV0ZVNRTCA9ICJTRUxFQ1QgJFNlbGYtPntDdXN0b21lckNvbXBhbnlLZXl9LCAkV2hhdCBGUk9NICRTZWxmLT57Q3VzdG9tZXJDb21wYW55VGFibGV9IjsKCiAgICBpZiAoQENvbmRpdGlvbnMpIHsKICAgICAgICAkU1FMID0gam9pbiggJyBBTkQgJywgQENvbmRpdGlvbnMgKTsKICAgICAgICAkQ29tcGxldGVTUUwgLj0gIiBXSEVSRSAkU1FMIjsKICAgIH0KCiAgICAjIGdldCBkYXRhIGZyb20gY3VzdG9tZXIgY29tcGFueSB0YWJsZQogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMICAgPT4gJENvbXBsZXRlU1FMLAogICAgICAgIEJpbmQgID0+IFxAQmluZCwKICAgICAgICBMaW1pdCA9PiAkTGltaXQsCiAgICApOwoKICAgIG15IEBDdXN0b21lckNvbXBhbnlEYXRhOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICBwdXNoIEBDdXN0b21lckNvbXBhbnlEYXRhLCBbQFJvd107CiAgICB9CgogICAgbXkgJUxpc3Q7CgogICAgQ1VTVE9NRVJDT01QQU5ZREFUQToKICAgIGZvciBteSAkQ3VzdG9tZXJDb21wYW55RGF0YSAoQEN1c3RvbWVyQ29tcGFueURhdGEpIHsKICAgICAgICBteSAkQ3VzdG9tZXJDb21wYW55SUQgPSBzaGlmdCBAeyRDdXN0b21lckNvbXBhbnlEYXRhfTsKICAgICAgICBuZXh0IENVU1RPTUVSQ09NUEFOWURBVEEgaWYgJExpc3R7JEN1c3RvbWVyQ29tcGFueUlEfTsKCiAgICAgICAgbXkgJUNvbXBhbnlTdHJpbmdQYXJ0czsKCiAgICAgICAgbXkgJEZpZWxkQ291bnRlciA9IDA7CiAgICAgICAgZm9yIG15ICRGaWVsZCAoIEB7JEN1c3RvbWVyQ29tcGFueURhdGF9ICkgewogICAgICAgICAgICAkQ29tcGFueVN0cmluZ1BhcnRzeyAkQ3VzdG9tZXJDb21wYW55TGlzdEZpZWxkc1dpdGhvdXREeW5hbWljRmllbGRzWyRGaWVsZENvdW50ZXJdIH0gPSAkRmllbGQ7CiAgICAgICAgICAgICRGaWVsZENvdW50ZXIrKzsKICAgICAgICB9CgogICAgICAgICMgZmV0Y2ggZHluYW1pYyBmaWVsZCB2YWx1ZXMsIGlmIGNvbmZpZ3VyZWQKICAgICAgICBpZiAoQEN1c3RvbWVyQ29tcGFueUxpc3RGaWVsZHNEeW5hbWljRmllbGRzKSB7CiAgICAgICAgICAgIERZTkFNSUNGSUVMRE5BTUU6CiAgICAgICAgICAgIGZvciBteSAkRHluYW1pY0ZpZWxkTmFtZSAoQEN1c3RvbWVyQ29tcGFueUxpc3RGaWVsZHNEeW5hbWljRmllbGRzKSB7CiAgICAgICAgICAgICAgICBuZXh0IERZTkFNSUNGSUVMRE5BTUUgaWYgIWV4aXN0cyAkRHluYW1pY0ZpZWxkQ29uZmlnc0J5TmFtZXskRHluYW1pY0ZpZWxkTmFtZX07CgogICAgICAgICAgICAgICAgbXkgJFZhbHVlID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlR2V0KAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnc0J5TmFtZXskRHluYW1pY0ZpZWxkTmFtZX0sCiAgICAgICAgICAgICAgICAgICAgT2JqZWN0TmFtZSAgICAgICAgID0+ICRDdXN0b21lckNvbXBhbnlJRCwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgbmV4dCBEWU5BTUlDRklFTEROQU1FIGlmICFkZWZpbmVkICRWYWx1ZTsKCiAgICAgICAgICAgICAgICBpZiAoICFJc0FycmF5UmVmV2l0aERhdGEoJFZhbHVlKSApIHsKICAgICAgICAgICAgICAgICAgICAkVmFsdWUgPSBbJFZhbHVlXTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBteSBAVmFsdWVzOwoKICAgICAgICAgICAgICAgIFZBTFVFOgogICAgICAgICAgICAgICAgZm9yIG15ICRDdXJyZW50VmFsdWUgKCBAeyRWYWx1ZX0gKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBWQUxVRSBpZiAhZGVmaW5lZCAkQ3VycmVudFZhbHVlIHx8ICFsZW5ndGggJEN1cnJlbnRWYWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgbXkgJFJlYWRhYmxlVmFsdWUgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+UmVhZGFibGVWYWx1ZVJlbmRlcigKICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWdzQnlOYW1leyREeW5hbWljRmllbGROYW1lfSwKICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICAgICAgID0+ICRDdXJyZW50VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgbmV4dCBWQUxVRSBpZiAhSXNIYXNoUmVmV2l0aERhdGEoJFJlYWRhYmxlVmFsdWUpIHx8ICFkZWZpbmVkICRSZWFkYWJsZVZhbHVlLT57VmFsdWV9OwoKICAgICAgICAgICAgICAgICAgICBteSAkSXNBQ0xSZWR1Y2libGUgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+SGFzQmVoYXZpb3IoCiAgICAgICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnc0J5TmFtZXskRHluYW1pY0ZpZWxkTmFtZX0sCiAgICAgICAgICAgICAgICAgICAgICAgIEJlaGF2aW9yICAgICAgICAgICA9PiAnSXNBQ0xSZWR1Y2libGUnLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRJc0FDTFJlZHVjaWJsZSkgewogICAgICAgICAgICAgICAgICAgICAgICBteSAkUG9zc2libGVWYWx1ZXMgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+UG9zc2libGVWYWx1ZXNHZXQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZENvbmZpZ3NCeU5hbWV7JER5bmFtaWNGaWVsZE5hbWV9LAogICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXNIYXNoUmVmV2l0aERhdGEoJFBvc3NpYmxlVmFsdWVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZGVmaW5lZCAkUG9zc2libGVWYWx1ZXMtPnsgJFJlYWRhYmxlVmFsdWUtPntWYWx1ZX0gfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkUmVhZGFibGVWYWx1ZS0+e1ZhbHVlfSA9ICRQb3NzaWJsZVZhbHVlcy0+eyAkUmVhZGFibGVWYWx1ZS0+e1ZhbHVlfSB9OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBwdXNoIEBWYWx1ZXMsICRSZWFkYWJsZVZhbHVlLT57VmFsdWV9OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRDb21wYW55U3RyaW5nUGFydHN7JER5bmFtaWNGaWVsZE5hbWV9ID0gam9pbiAnICcsIEBWYWx1ZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgYXNzZW1ibGUgY29tcGFueSBzdHJpbmcKICAgICAgICBteSBAQ29tcGFueVN0cmluZ1BhcnRzOwogICAgICAgIENVU1RPTUVSQ09NUEFOWUxJU1RGSUVMRDoKICAgICAgICBmb3IgbXkgJEN1c3RvbWVyQ29tcGFueUxpc3RGaWVsZCAoIEB7JEN1c3RvbWVyQ29tcGFueUxpc3RGaWVsZHN9ICkgewogICAgICAgICAgICBuZXh0IENVU1RPTUVSQ09NUEFOWUxJU1RGSUVMRAogICAgICAgICAgICAgICAgaWYgIWV4aXN0cyAkQ29tcGFueVN0cmluZ1BhcnRzeyRDdXN0b21lckNvbXBhbnlMaXN0RmllbGR9CiAgICAgICAgICAgICAgICB8fCAhZGVmaW5lZCAkQ29tcGFueVN0cmluZ1BhcnRzeyRDdXN0b21lckNvbXBhbnlMaXN0RmllbGR9CiAgICAgICAgICAgICAgICB8fCAhbGVuZ3RoICRDb21wYW55U3RyaW5nUGFydHN7JEN1c3RvbWVyQ29tcGFueUxpc3RGaWVsZH07CiAgICAgICAgICAgIHB1c2ggQENvbXBhbnlTdHJpbmdQYXJ0cywgJENvbXBhbnlTdHJpbmdQYXJ0c3skQ3VzdG9tZXJDb21wYW55TGlzdEZpZWxkfTsKICAgICAgICB9CgogICAgICAgICRMaXN0eyRDdXN0b21lckNvbXBhbnlJRH0gPSBqb2luICcgJywgQENvbXBhbnlTdHJpbmdQYXJ0czsKICAgIH0KCiAgICAjIGNhY2hlIHJlcXVlc3QKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgVHlwZSAgPT4gJENhY2hlVHlwZSwKICAgICAgICAgICAgS2V5ICAgPT4gJENhY2hlS2V5LAogICAgICAgICAgICBWYWx1ZSA9PiBcJUxpc3QsCiAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q2FjaGVUVEx9LAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuICVMaXN0Owp9CgpzdWIgQ3VzdG9tZXJDb21wYW55U2VhcmNoRGV0YWlsIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgaWYgKCByZWYgJFBhcmFte1NlYXJjaEZpZWxkc30gbmUgJ0FSUkFZJyApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIlNlYXJjaEZpZWxkcyBtdXN0IGJlIGFuIGFycmF5IHJlZmVyZW5jZSEiLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIG15ICRWYWxpZCA9IGRlZmluZWQgJFBhcmFte1ZhbGlkfSA/ICRQYXJhbXtWYWxpZH0gOiAxOwoKICAgICRQYXJhbXtMaW1pdH0gLy89ICcnOwoKICAgICMgU3BsaXQgdGhlIHNlYXJjaCBmaWVsZHMgaW4gc2NhbGFyIGFuZCBhcnJheSBmaWVsZHMuCiAgICBteSBAU2NhbGFyU2VhcmNoRmllbGRzID0gZ3JlcCB7ICdJbnB1dCcgZXEgJF8tPntUeXBlfSB9IEB7ICRQYXJhbXtTZWFyY2hGaWVsZHN9IH07CiAgICBteSBAQXJyYXlTZWFyY2hGaWVsZHMgID0gZ3JlcCB7ICdTZWxlY3Rpb24nIGVxICRfLT57VHlwZX0gfSBAeyAkUGFyYW17U2VhcmNoRmllbGRzfSB9OwoKICAgICMgVmVyaWZ5IHRoYXQgYWxsIHBhc3NlZCBhcnJheSBwYXJhbWV0ZXJzIGNvbnRhaW4gYW4gYXJyYXlyZWYuCiAgICBBUkdVTUVOVDoKICAgIGZvciBteSAkQXJndW1lbnQgKEBBcnJheVNlYXJjaEZpZWxkcykgewogICAgICAgIGlmICggIWRlZmluZWQgJFBhcmFteyAkQXJndW1lbnQtPntOYW1lfSB9ICkgewogICAgICAgICAgICAkUGFyYW17ICRBcmd1bWVudC0+e05hbWV9IH0gfHw9IFtdOwoKICAgICAgICAgICAgbmV4dCBBUkdVTUVOVDsKICAgICAgICB9CgogICAgICAgIGlmICggcmVmICRQYXJhbXsgJEFyZ3VtZW50LT57TmFtZX0gfSBuZSAnQVJSQVknICkgewogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiJEFyZ3VtZW50LT57TmFtZX0gbXVzdCBiZSBhbiBhcnJheSByZWZlcmVuY2UhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIFNldCB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgZm9yIHRoZSByZXR1cm4gdHlwZS4KICAgIG15ICRSZXN1bHQgPSAkUGFyYW17UmVzdWx0fSB8fCAnQVJSQVknOwoKICAgICMgU3BlY2lhbCBoYW5kbGluZyBpZiB0aGUgcmVzdWx0IHR5cGUgaXMgJ0NPVU5UJy4KICAgIGlmICggJFJlc3VsdCBlcSAnQ09VTlQnICkgewoKICAgICAgICAjIElnbm9yZSB0aGUgcGFyYW1ldGVyICdMaW1pdCcgd2hlbiByZXN1bHQgdHlwZSBpcyAnQ09VTlQnLgogICAgICAgICRQYXJhbXtMaW1pdH0gPSAnJzsKCiAgICAgICAgIyBEZWxldGUgdGhlIE9yZGVyQnkgcGFyYW1ldGVyIHdoZW4gdGhlIHJlc3VsdCB0eXBlIGlzICdDT1VOVCcuCiAgICAgICAgJFBhcmFte09yZGVyQnl9ID0gW107CiAgICB9CgogICAgIyBEZWZpbmUgb3JkZXIgdGFibGUgZnJvbSB0aGUgc2VhcmNoIGZpZWxkcy4KICAgIG15ICVPcmRlckJ5VGFibGUgPSBtYXAgeyAkXy0+e05hbWV9ID0+ICRfLT57RGF0YWJhc2VGaWVsZH0gfSBAeyAkUGFyYW17U2VhcmNoRmllbGRzfSB9OwoKICAgIGZvciBteSAkRmllbGQgKEBBcnJheVNlYXJjaEZpZWxkcykgewoKICAgICAgICBteSAkU2VsZWN0aW9uc0RhdGEgPSAkRmllbGQtPntTZWxlY3Rpb25zRGF0YX07CgogICAgICAgIGZvciBteSAkU2VsZWN0ZWRWYWx1ZSAoIEB7ICRQYXJhbXsgJEZpZWxkLT57TmFtZX0gfSB9ICkgewoKICAgICAgICAgICAgIyBDaGVjayBpZiB0aGUgc2VsZWN0ZWQgdmFsdWUgZm9yIHRoZSBjdXJyZW50IGZpZWxkIGlzIHZhbGlkLgogICAgICAgICAgICBpZiAoICEkU2VsZWN0aW9uc0RhdGEtPnskU2VsZWN0ZWRWYWx1ZX0gKSB7CiAgICAgICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJUaGUgc2VsZWN0ZWQgdmFsdWUgJEZpZWxkLT57TmFtZX0gaXMgbm90IHZhbGlkISIsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIG15ICREQk9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEQicpOwoKICAgICMgQXNzZW1ibGUgdGhlIGNvbmRpdGlvbnMgdXNlZCBpbiB0aGUgV0hFUkUgY2xhdXNlLgogICAgbXkgQFNRTFdoZXJlOwoKICAgIGZvciBteSAkRmllbGQgKEBTY2FsYXJTZWFyY2hGaWVsZHMpIHsKCiAgICAgICAgIyBTZWFyY2ggZm9yIHNjYWxhciBmaWVsZHMgKHdpbGRjYXJkcyBhcmUgYWxsb3dlZCkuCiAgICAgICAgaWYgKCAkUGFyYW17ICRGaWVsZC0+e05hbWV9IH0gKSB7CgogICAgICAgICAgICAjIEdldCBsaWtlIGVzY2FwZSBzdHJpbmcgbmVlZGVkIGZvciBzb21lIGRhdGFiYXNlcyAoZS5nLiBvcmFjbGUpLgogICAgICAgICAgICBteSAkTGlrZUVzY2FwZVN0cmluZyA9ICREQk9iamVjdC0+R2V0RGF0YWJhc2VGdW5jdGlvbignTGlrZUVzY2FwZVN0cmluZycpOwoKICAgICAgICAgICAgJFBhcmFteyAkRmllbGQtPntOYW1lfSB9ID0gJERCT2JqZWN0LT5RdW90ZSggJFBhcmFteyAkRmllbGQtPntOYW1lfSB9LCAnTGlrZScgKTsKCiAgICAgICAgICAgICRQYXJhbXsgJEZpZWxkLT57TmFtZX0gfSA9fiBzeyBcKisgfXslfXhtc2c7CgogICAgICAgICAgICAjIElmIHRoZSBmaWVsZCBjb250YWlucyBtb3JlIHRoYW4gb25seSAnJScuCiAgICAgICAgICAgIGlmICggJFBhcmFteyAkRmllbGQtPntOYW1lfSB9ICF+IG17IFxBICUqIFx6IH14bXMgKSB7CiAgICAgICAgICAgICAgICBwdXNoIEBTUUxXaGVyZSwKICAgICAgICAgICAgICAgICAgICAiTE9XRVIoJEZpZWxkLT57RGF0YWJhc2VGaWVsZH0pIExJS0UgTE9XRVIoJyRQYXJhbXsgJEZpZWxkLT57TmFtZX0gfScpICRMaWtlRXNjYXBlU3RyaW5nIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBteSAkRHluYW1pY0ZpZWxkT2JqZWN0ICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKTsKICAgIG15ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDo6QmFja2VuZCcpOwoKICAgICMgQ2hlY2sgYWxsIGNvbmZpZ3VyZWQgY2hhbmdlIGR5bmFtaWMgZmllbGRzLCBidWlsZCBsb29rdXAgaGFzaCBieSBuYW1lLgogICAgbXkgJUN1c3RvbWVyQ29tcGFueUR5bmFtaWNGaWVsZE5hbWUyQ29uZmlnOwogICAgbXkgJEN1c3RvbWVyQ29tcGFueUR5bmFtaWNGaWVsZHMgPSAkRHluYW1pY0ZpZWxkT2JqZWN0LT5EeW5hbWljRmllbGRMaXN0R2V0KAogICAgICAgIE9iamVjdFR5cGUgPT4gJ0N1c3RvbWVyQ29tcGFueScsCiAgICApOwogICAgZm9yIG15ICREeW5hbWljRmllbGQgKCBAeyRDdXN0b21lckNvbXBhbnlEeW5hbWljRmllbGRzfSApIHsKICAgICAgICAkQ3VzdG9tZXJDb21wYW55RHluYW1pY0ZpZWxkTmFtZTJDb25maWd7ICREeW5hbWljRmllbGQtPntOYW1lfSB9ID0gJER5bmFtaWNGaWVsZDsKICAgIH0KCiAgICBteSAkU1FMRHluYW1pY0ZpZWxkRnJvbSAgICAgPSAnJzsKICAgIG15ICRTUUxEeW5hbWljRmllbGRXaGVyZSAgICA9ICcnOwogICAgbXkgJER5bmFtaWNGaWVsZEpvaW5Db3VudGVyID0gMTsKCiAgICBEWU5BTUlDRklFTEQ6CiAgICBmb3IgbXkgJER5bmFtaWNGaWVsZCAoIEB7JEN1c3RvbWVyQ29tcGFueUR5bmFtaWNGaWVsZHN9ICkgewoKICAgICAgICBteSAkU2VhcmNoUGFyYW0gPSAkUGFyYW17ICJEeW5hbWljRmllbGRfIiAuICREeW5hbWljRmllbGQtPntOYW1lfSB9OwoKICAgICAgICBuZXh0IERZTkFNSUNGSUVMRCBpZiAoICEkU2VhcmNoUGFyYW0gKTsKICAgICAgICBuZXh0IERZTkFNSUNGSUVMRCBpZiAoIHJlZiAkU2VhcmNoUGFyYW0gbmUgJ0hBU0gnICk7CgogICAgICAgIG15ICROZWVkSm9pbjsKCiAgICAgICAgZm9yIG15ICRPcGVyYXRvciAoIHNvcnQga2V5cyAleyRTZWFyY2hQYXJhbX0gKSB7CgogICAgICAgICAgICBteSBAU2VhcmNoUGFyYW1zID0gKCByZWYgJFNlYXJjaFBhcmFtLT57JE9wZXJhdG9yfSBlcSAnQVJSQVknICkKICAgICAgICAgICAgICAgID8gQHsgJFNlYXJjaFBhcmFtLT57JE9wZXJhdG9yfSB9CiAgICAgICAgICAgICAgICA6ICggJFNlYXJjaFBhcmFtLT57JE9wZXJhdG9yfSApOwoKICAgICAgICAgICAgbXkgJFNRTER5bmFtaWNGaWVsZFdoZXJlU3ViID0gJyc7CiAgICAgICAgICAgIGlmICgkU1FMRHluYW1pY0ZpZWxkV2hlcmUpIHsKICAgICAgICAgICAgICAgICRTUUxEeW5hbWljRmllbGRXaGVyZVN1YiA9ICcgQU5EICgnOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZFdoZXJlU3ViID0gJyAoJzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbXkgJENvdW50ZXIgPSAwOwogICAgICAgICAgICBURVhUOgogICAgICAgICAgICBmb3IgbXkgJFRleHQgKEBTZWFyY2hQYXJhbXMpIHsKICAgICAgICAgICAgICAgIG5leHQgVEVYVCBpZiAoICFkZWZpbmVkICRUZXh0IHx8ICRUZXh0IGVxICcnICk7CgogICAgICAgICAgICAgICAgJFRleHQgPX4gcy9cKi8lL2dpOwoKICAgICAgICAgICAgICAgICMgQ2hlY2sgc2VhcmNoIGF0dHJpYnV0ZSwgd2UgZG8gbm90IG5lZWQgdG8gc2VhcmNoIGZvciAnKicuCiAgICAgICAgICAgICAgICBuZXh0IFRFWFQgaWYgJFRleHQgPX4gL15cJXsxLDN9JC87CgogICAgICAgICAgICAgICAgbXkgJFZhbGlkYXRlU3VjY2VzcyA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5WYWx1ZVZhbGlkYXRlKAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkLAogICAgICAgICAgICAgICAgICAgIFZhbHVlICAgICAgICAgICAgICA9PiAkVGV4dCwKICAgICAgICAgICAgICAgICAgICBVc2VySUQgICAgICAgICAgICAgPT4gJFBhcmFte1VzZXJJRH0gfHwgMSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBpZiAoICEkVmFsaWRhdGVTdWNjZXNzICkgewogICAgICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiU2VhcmNoIG5vdCBleGVjdXRlZCBkdWUgdG8gaW52YWxpZCB2YWx1ZSAnIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLiAkVGV4dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLiAiJyBvbiBmaWVsZCAnIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLiAkRHluYW1pY0ZpZWxkLT57TmFtZX0gLiAiJyEiLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICgkQ291bnRlcikgewogICAgICAgICAgICAgICAgICAgICRTUUxEeW5hbWljRmllbGRXaGVyZVN1YiAuPSAnIE9SICc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkU1FMRHluYW1pY0ZpZWxkV2hlcmVTdWIgLj0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlNlYXJjaFNRTEdldCgKICAgICAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZCwKICAgICAgICAgICAgICAgICAgICBUYWJsZUFsaWFzICAgICAgICAgPT4gImRmdiREeW5hbWljRmllbGRKb2luQ291bnRlciIsCiAgICAgICAgICAgICAgICAgICAgT3BlcmF0b3IgICAgICAgICAgID0+ICRPcGVyYXRvciwKICAgICAgICAgICAgICAgICAgICBTZWFyY2hUZXJtICAgICAgICAgPT4gJFRleHQsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICRDb3VudGVyKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZFdoZXJlU3ViIC49ICcpICc7CgogICAgICAgICAgICBpZiAoJENvdW50ZXIpIHsKICAgICAgICAgICAgICAgICRTUUxEeW5hbWljRmllbGRXaGVyZSAuPSAkU1FMRHluYW1pY0ZpZWxkV2hlcmVTdWI7CiAgICAgICAgICAgICAgICAkTmVlZEpvaW4gPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoJE5lZWRKb2luKSB7CiAgICAgICAgICAgICRTUUxEeW5hbWljRmllbGRGcm9tIC49ICIKICAgICAgICAgICAgICAgIElOTkVSIEpPSU4gZHluYW1pY19maWVsZF92YWx1ZSBkZnYkRHluYW1pY0ZpZWxkSm9pbkNvdW50ZXIKICAgICAgICAgICAgICAgICAgICBPTiAoZGZfb2JqX2lkX25hbWUub2JqZWN0X2lkID0gZGZ2JER5bmFtaWNGaWVsZEpvaW5Db3VudGVyLm9iamVjdF9pZAogICAgICAgICAgICAgICAgICAgICAgICBBTkQgZGZ2JER5bmFtaWNGaWVsZEpvaW5Db3VudGVyLmZpZWxkX2lkID0gIgogICAgICAgICAgICAgICAgLiAkREJPYmplY3QtPlF1b3RlKCAkRHluYW1pY0ZpZWxkLT57SUR9LCAnSW50ZWdlcicgKSAuICIpCiAgICAgICAgICAgICI7CgogICAgICAgICAgICAkRHluYW1pY0ZpZWxkSm9pbkNvdW50ZXIrKzsKICAgICAgICB9CiAgICB9CgogICAgIyBFeGVjdXRlIGEgZHluYW1pYyBmaWVsZCBzZWFyY2gsIGlmIGEgZHluYW1pYyBmaWVsZCB3aGVyZSBzdGF0ZW1lbnQgZXhpc3RzLgogICAgaWYgKCAkU1FMRHluYW1pY0ZpZWxkRnJvbSAmJiAkU1FMRHluYW1pY0ZpZWxkV2hlcmUgKSB7CgogICAgICAgIG15IEBEeW5hbWljRmllbGRDdXN0b21lcklEczsKCiAgICAgICAgIyBTcWwgdWVyeSBmb3IgdGhlIGR5bmFtaWMgZmllbGRzLgogICAgICAgIG15ICRTUUxEeW5hbWljRmllbGQKICAgICAgICAgICAgPSAiU0VMRUNUIERJU1RJTkNUKGRmX29ial9pZF9uYW1lLm9iamVjdF9uYW1lKSBGUk9NIGR5bmFtaWNfZmllbGRfb2JqX2lkX25hbWUgZGZfb2JqX2lkX25hbWUgIgogICAgICAgICAgICAuICRTUUxEeW5hbWljRmllbGRGcm9tCiAgICAgICAgICAgIC4gIiBXSEVSRSAiCiAgICAgICAgICAgIC4gJFNRTER5bmFtaWNGaWVsZFdoZXJlOwoKICAgICAgICBteSAkVXNlZENhY2hlOwoKICAgICAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewoKICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZFNlYXJjaENhY2hlRGF0YSA9ICRTZWxmLT57Q2FjaGVPYmplY3R9LT5HZXQoCiAgICAgICAgICAgICAgICBUeXBlID0+ICRTZWxmLT57Q2FjaGVUeXBlfSAuICdfQ3VzdG9tZXJTZWFyY2hEZXRhaWxEeW5hbWljRmllbGRzJywKICAgICAgICAgICAgICAgIEtleSAgPT4gJFNRTER5bmFtaWNGaWVsZCwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGlmICggZGVmaW5lZCAkRHluYW1pY0ZpZWxkU2VhcmNoQ2FjaGVEYXRhICkgewogICAgICAgICAgICAgICAgaWYgKCByZWYgJER5bmFtaWNGaWVsZFNlYXJjaENhY2hlRGF0YSBlcSAnQVJSQVknICkgewogICAgICAgICAgICAgICAgICAgIEBEeW5hbWljRmllbGRDdXN0b21lcklEcyA9IEB7JER5bmFtaWNGaWVsZFNlYXJjaENhY2hlRGF0YX07CgogICAgICAgICAgICAgICAgICAgICMgU2V0IHRoZSB1c2VkIGNhY2hlIGZsYWcuCiAgICAgICAgICAgICAgICAgICAgJFVzZWRDYWNoZSA9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0ludmFsaWQgcmVmICcgLiByZWYoJER5bmFtaWNGaWVsZFNlYXJjaENhY2hlRGF0YSkgLiAnIScKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBHZXQgdGhlIGRhdGEgb25seSBmcm9tIGRhdGFiYXNlLCBpZiBubyBjYWNoZSBlbnRyeSBleGlzdHMuCiAgICAgICAgaWYgKCAhJFVzZWRDYWNoZSApIHsKCiAgICAgICAgICAgIHJldHVybiBpZiAhJERCT2JqZWN0LT5QcmVwYXJlKAogICAgICAgICAgICAgICAgU1FMID0+ICRTUUxEeW5hbWljRmllbGQsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICB3aGlsZSAoIG15IEBSb3cgPSAkREJPYmplY3QtPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICAgICAgICAgIHB1c2ggQER5bmFtaWNGaWVsZEN1c3RvbWVySURzLCAkUm93WzBdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgICAgICAgICBUeXBlICA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyU2VhcmNoRGV0YWlsRHluYW1pY0ZpZWxkcycsCiAgICAgICAgICAgICAgICAgICAgS2V5ICAgPT4gJFNRTER5bmFtaWNGaWVsZCwKICAgICAgICAgICAgICAgICAgICBWYWx1ZSA9PiBcQER5bmFtaWNGaWVsZEN1c3RvbWVySURzLAogICAgICAgICAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e0NhY2hlVFRMfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgQWRkIHRoZSB1c2VyIGxvZ2lucyBmcm9tIHRoZSBkeW5hbWljIGZpZWxkcywgaWYgYSBzZWFyY2ggcmVzdWx0IGV4aXN0cyBmcm9tIHRoZSBkeW5hbWljIGZpZWxkIHNlYXJjaAogICAgICAgICMgICBvciBza2lwIHRoZSBzZWFyY2ggYW5kIHJldHVybiBhIGVtcHRyeSBhcnJheSByZWYgKG9yIHplcm8gZm9yIHRoZSByZXN1bHQgJ0NPVU5UJywgaWYgbm8gdXNlciBsb2dpbnMgZXhpc3RzCiAgICAgICAgIyAgIGZyb20gdGhlIGR5bmFtaWMgZmllbGQgc2VhcmNoLgogICAgICAgIGlmIChARHluYW1pY0ZpZWxkQ3VzdG9tZXJJRHMpIHsKCiAgICAgICAgICAgIG15ICRTUUxRdWVyeUluQ29uZGl0aW9uID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkRCJyktPlF1ZXJ5SW5Db25kaXRpb24oCiAgICAgICAgICAgICAgICBLZXkgICAgICA9PiAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueUtleX0sCiAgICAgICAgICAgICAgICBWYWx1ZXMgICA9PiBcQER5bmFtaWNGaWVsZEN1c3RvbWVySURzLAogICAgICAgICAgICAgICAgQmluZE1vZGUgPT4gMCwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHB1c2ggQFNRTFdoZXJlLCAkU1FMUXVlcnlJbkNvbmRpdGlvbjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAkUmVzdWx0IGVxICdDT1VOVCcgPyAwIDogW107CiAgICAgICAgfQogICAgfQoKICAgIEZJRUxEOgogICAgZm9yIG15ICRGaWVsZCAoQEFycmF5U2VhcmNoRmllbGRzKSB7CgogICAgICAgIG5leHQgRklFTEQgaWYgIUB7ICRQYXJhbXsgJEZpZWxkLT57TmFtZX0gfSB9OwoKICAgICAgICBteSAkU1FMUXVlcnlJbkNvbmRpdGlvbiA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEQicpLT5RdWVyeUluQ29uZGl0aW9uKAogICAgICAgICAgICBLZXkgICAgICA9PiAkRmllbGQtPntEYXRhYmFzZUZpZWxkfSwKICAgICAgICAgICAgVmFsdWVzICAgPT4gJFBhcmFteyAkRmllbGQtPntOYW1lfSB9LAogICAgICAgICAgICBCaW5kTW9kZSA9PiAwLAogICAgICAgICk7CgogICAgICAgIHB1c2ggQFNRTFdoZXJlLCAkU1FMUXVlcnlJbkNvbmRpdGlvbjsKICAgIH0KCiAgICAjIEFkZCB0aGUgdmFsaWQgb3B0aW9uIGlmIG5lZWRlZC4KICAgIGlmICggJFNlbGYtPntDdXN0b21lckNvbXBhbnlNYXB9LT57Q3VzdG9tZXJWYWxpZH0gJiYgJFZhbGlkICkgewoKICAgICAgICBteSAkVmFsaWRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6VmFsaWQnKTsKCiAgICAgICAgcHVzaCBAU1FMV2hlcmUsCiAgICAgICAgICAgICIkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntDdXN0b21lclZhbGlkfSBJTiAoIiAuIGpvaW4oICcsICcsICRWYWxpZE9iamVjdC0+VmFsaWRJRHNHZXQoKSApIC4gIikgIjsKICAgIH0KCiAgICAjIENoZWNrIGlmIE9yZGVyQnkgY29udGFpbnMgb25seSB1bmlxdWUgdmFsaWQgdmFsdWVzLgogICAgbXkgJU9yZGVyQnlTZWVuOwogICAgZm9yIG15ICRPcmRlckJ5ICggQHsgJFBhcmFte09yZGVyQnl9IH0gKSB7CgogICAgICAgIGlmICggISRPcmRlckJ5IHx8ICRPcmRlckJ5U2VlbnskT3JkZXJCeX0gKSB7CgogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiT3JkZXJCeSBjb250YWlucyBpbnZhbGlkIHZhbHVlICckT3JkZXJCeScgIgogICAgICAgICAgICAgICAgICAgIC4gJ29yIHRoZSB2YWx1ZSBpcyB1c2VkIG1vcmUgdGhhbiBvbmNlIScsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgUmVtZW1iZXIgdGhlIHZhbHVlIHRvIGNoZWNrIGlmIGl0IGFwcGVhcnMgbW9yZSB0aGFuIG9uY2UuCiAgICAgICAgJE9yZGVyQnlTZWVueyRPcmRlckJ5fSA9IDE7CiAgICB9CgogICAgIyBDaGVjayBpZiBPcmRlckJ5RGlyZWN0aW9uIGFycmF5IGNvbnRhaW5zIG9ubHkgJ1VwJyBvciAnRG93bicuCiAgICBESVJFQ1RJT046CiAgICBmb3IgbXkgJERpcmVjdGlvbiAoIEB7ICRQYXJhbXtPcmRlckJ5RGlyZWN0aW9ufSB9ICkgewoKICAgICAgICAjIE9ubHkgJ1VwJyBvciAnRG93bicgYWxsb3dlZC4KICAgICAgICBuZXh0IERJUkVDVElPTiBpZiAkRGlyZWN0aW9uIGVxICdVcCc7CiAgICAgICAgbmV4dCBESVJFQ1RJT04gaWYgJERpcmVjdGlvbiBlcSAnRG93bic7CgogICAgICAgICMgZm91bmQgYW4gZXJyb3IKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk9yZGVyQnlEaXJlY3Rpb24gY2FuIG9ubHkgY29udGFpbiAnVXAnIG9yICdEb3duJyEiLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgQnVpbGQgdGhlIHNxbCBzdGF0ZW1lbnQgZm9yIHRoZSBzZWFyY2guCiAgICBteSAkU1FMID0gIlNFTEVDVCBESVNUSU5DVCgkU2VsZi0+e0N1c3RvbWVyQ29tcGFueUtleX0pIjsKCiAgICAjIE1vZGlmeSBTUUwgd2hlbiB0aGUgcmVzdWx0IHR5cGUgaXMgJ0NPVU5UJy4KICAgIGlmICggJFJlc3VsdCBlcSAnQ09VTlQnICkgewogICAgICAgICRTUUwgPSAiU0VMRUNUIENPVU5UKERJU1RJTkNUKCRTZWxmLT57Q3VzdG9tZXJDb21wYW55S2V5fSkpIjsKICAgIH0KCiAgICBteSBAU1FMT3JkZXJCeTsKCiAgICAjIFRoZSBPcmRlciBieSBjbGF1c2UgaXMgbm90IG5lZWRlZCBmb3IgdGhlIHJlc3VsdCB0eXBlICdDT1VOVCcuCiAgICBpZiAoICRSZXN1bHQgbmUgJ0NPVU5UJyApIHsKCiAgICAgICAgbXkgJENvdW50ID0gMDsKCiAgICAgICAgT1JERVJCWToKICAgICAgICBmb3IgbXkgJE9yZGVyQnkgKCBAeyAkUGFyYW17T3JkZXJCeX0gfSApIHsKCiAgICAgICAgICAgICMgU2V0IHRoZSBkZWZhdWx0IG9yZGVyIGRpcmVjdGlvbi4KICAgICAgICAgICAgbXkgJERpcmVjdGlvbiA9ICdERVNDJzsKCiAgICAgICAgICAgICMgQWRkIHRoZSBnaXZlbiBvcmRlciBkaXJlY3Rpb24uCiAgICAgICAgICAgIGlmICggJFBhcmFte09yZGVyQnlEaXJlY3Rpb259LT5bJENvdW50XSApIHsKICAgICAgICAgICAgICAgIGlmICggJFBhcmFte09yZGVyQnlEaXJlY3Rpb259LT5bJENvdW50XSBlcSAnVXAnICkgewogICAgICAgICAgICAgICAgICAgICREaXJlY3Rpb24gPSAnQVNDJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2lmICggJFBhcmFte09yZGVyQnlEaXJlY3Rpb259LT5bJENvdW50XSBlcSAnRG93bicgKSB7CiAgICAgICAgICAgICAgICAgICAgJERpcmVjdGlvbiA9ICdERVNDJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgJENvdW50Kys7CgogICAgICAgICAgICBuZXh0IE9SREVSQlkgaWYgISRPcmRlckJ5VGFibGV7JE9yZGVyQnl9OwoKICAgICAgICAgICAgcHVzaCBAU1FMT3JkZXJCeSwgIiRPcmRlckJ5VGFibGV7JE9yZGVyQnl9ICREaXJlY3Rpb24iOwoKICAgICAgICAgICAgbmV4dCBPUkRFUkJZIGlmICRPcmRlckJ5IGVxICdDdXN0b21lcklEJzsKCiAgICAgICAgICAgICRTUUwgLj0gIiwgJE9yZGVyQnlUYWJsZXskT3JkZXJCeX0iOwogICAgICAgIH0KCiAgICAgICAgIyBJZiB0aGVyZSBpcyBhIHBvc3NpYmlsaXR5IHRoYXQgdGhlIG9yZGVyaW5nIGlzIG5vdCBkZXRlcm1pbmVkCiAgICAgICAgIyAgIHdlIGFkZCBhbiBkZXNjZW5kaW5nIG9yZGVyaW5nIGJ5IGlkLgogICAgICAgIGlmICggIWdyZXAgeyAkXyBlcSAnQ3VzdG9tZXJJRCcgfSAoIEB7ICRQYXJhbXtPcmRlckJ5fSB9ICkgKSB7CiAgICAgICAgICAgIHB1c2ggQFNRTE9yZGVyQnksICIkU2VsZi0+e0N1c3RvbWVyQ29tcGFueUtleX0gREVTQyI7CiAgICAgICAgfQogICAgfQoKICAgICMgQWRkIGZvcm0gdG8gdGhlIFNRTCBhZnRlciB0aGUgb3JkZXIgYnkgY3JlYXRpb24uCiAgICAkU1FMIC49ICIgRlJPTSAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueVRhYmxlfSAiOwoKICAgIGlmIChAU1FMV2hlcmUpIHsKICAgICAgICBteSAkU1FMV2hlcmVTdHJpbmcgPSBqb2luICcgQU5EICcsIG1hcCB7IiggJF8gKSJ9IEBTUUxXaGVyZTsKICAgICAgICAkU1FMIC49ICJXSEVSRSAkU1FMV2hlcmVTdHJpbmcgIjsKICAgIH0KCiAgICBpZiAoQFNRTE9yZGVyQnkpIHsKICAgICAgICBteSAkT3JkZXJCeVN0cmluZyA9IGpvaW4gJywgJywgQFNRTE9yZGVyQnk7CiAgICAgICAgJFNRTCAuPSAiT1JERVIgQlkgJE9yZGVyQnlTdHJpbmciOwogICAgfQoKICAgICMgQ2hlY2sgaWYgYSBjYWNoZSBleGlzdHMgYmVmb3JlIHdlIGFzayB0aGUgZGF0YWJhc2UuCiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewoKICAgICAgICBteSAkQ2FjaGVEYXRhID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNhY2hlJyktPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyQ29tcGFueVNlYXJjaERldGFpbCcsCiAgICAgICAgICAgIEtleSAgPT4gJFNRTCAuICRQYXJhbXtMaW1pdH0sCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCBkZWZpbmVkICRDYWNoZURhdGEgKSB7CiAgICAgICAgICAgIGlmICggcmVmICRDYWNoZURhdGEgZXEgJ0FSUkFZJyApIHsKICAgICAgICAgICAgICAgIHJldHVybiAkQ2FjaGVEYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2lmICggcmVmICRDYWNoZURhdGEgZXEgJycgKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJENhY2hlRGF0YTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAnSW52YWxpZCByZWYgJyAuIHJlZigkQ2FjaGVEYXRhKSAuICchJwogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBpZiAhJERCT2JqZWN0LT5QcmVwYXJlKAogICAgICAgIFNRTCAgID0+ICRTUUwsCiAgICAgICAgTGltaXQgPT4gJFBhcmFte0xpbWl0fSwKICAgICk7CgogICAgbXkgQElEczsKICAgIHdoaWxlICggbXkgQFJvdyA9ICREQk9iamVjdC0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgIHB1c2ggQElEcywgJFJvd1swXTsKICAgIH0KCiAgICAjIEhhbmRsZSB0aGUgZGlmZnJlbnQgcmVzdWx0IHR5cGVzLgogICAgaWYgKCAkUmVzdWx0IGVxICdDT1VOVCcgKSB7CgogICAgICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDYWNoZScpLT5TZXQoCiAgICAgICAgICAgICAgICBUeXBlICA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyQ29tcGFueVNlYXJjaERldGFpbCcsCiAgICAgICAgICAgICAgICBLZXkgICA9PiAkU1FMIC4gJFBhcmFte0xpbWl0fSwKICAgICAgICAgICAgICAgIFZhbHVlID0+ICRJRHNbMF0sCiAgICAgICAgICAgICAgICBUVEwgICA9PiAkU2VsZi0+e0NhY2hlVFRMfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkSURzWzBdOwogICAgfQoKICAgIGVsc2UgewoKICAgICAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q2FjaGUnKS0+U2V0KAogICAgICAgICAgICAgICAgVHlwZSAgPT4gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lckNvbXBhbnlTZWFyY2hEZXRhaWwnLAogICAgICAgICAgICAgICAgS2V5ICAgPT4gJFNRTCAuICRQYXJhbXtMaW1pdH0sCiAgICAgICAgICAgICAgICBWYWx1ZSA9PiBcQElEcywKICAgICAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q2FjaGVUVEx9LAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFxASURzOwogICAgfQp9CgpzdWIgQ3VzdG9tZXJDb21wYW55R2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtDdXN0b21lcklEfSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgQ3VzdG9tZXJJRCEnCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjaGVjayBjYWNoZQogICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICBteSAkRGF0YSA9ICRTZWxmLT57Q2FjaGVPYmplY3R9LT5HZXQoCiAgICAgICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgICAgICBLZXkgID0+ICJDdXN0b21lckNvbXBhbnlHZXQ6OiRQYXJhbXtDdXN0b21lcklEfSIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gJXskRGF0YX0gaWYgcmVmICREYXRhIGVxICdIQVNIJzsKICAgIH0KCiAgICAjIGJ1aWxkIHNlbGVjdAogICAgbXkgQEZpZWxkczsKICAgIG15ICVGaWVsZHNNYXA7CgogICAgRU5UUlk6CiAgICBmb3IgbXkgJEVudHJ5ICggQHsgJFNlbGYtPntDdXN0b21lckNvbXBhbnlNYXB9LT57TWFwfSB9ICkgewogICAgICAgIG5leHQgRU5UUlkgaWYgJEVudHJ5LT5bNV0gZXEgJ2R5bmFtaWNfZmllbGQnOwogICAgICAgIHB1c2ggQEZpZWxkcywgJEVudHJ5LT5bMl07CiAgICAgICAgJEZpZWxkc01hcHsgJEVudHJ5LT5bMl0gfSA9ICRFbnRyeS0+WzBdOwogICAgfQogICAgbXkgJFNRTCA9ICdTRUxFQ1QgJyAuIGpvaW4oICcsICcsIEBGaWVsZHMgKTsKCiAgICBpZiAoICEkU2VsZi0+e0ZvcmVpZ25EQn0gKSB7CiAgICAgICAgJFNRTCAuPSAiLCBjcmVhdGVfdGltZSwgY3JlYXRlX2J5LCBjaGFuZ2VfdGltZSwgY2hhbmdlX2J5IjsKICAgIH0KCiAgICAjIHRoaXMgc2VlbXMgdG8gYmUgbGVnYWN5LCBpZiBOYW1lIGlzIHBhc3NlZCBpdCBzaG91bGQgdGFrZSBwcmVjZWRlbmNlIG92ZXIgQ3VzdG9tZXJJRAogICAgbXkgJEN1c3RvbWVySUQgPSAkUGFyYW17TmFtZX0gfHwgJFBhcmFte0N1c3RvbWVySUR9OwoKICAgICRTUUwgLj0gIiBGUk9NICRTZWxmLT57Q3VzdG9tZXJDb21wYW55VGFibGV9IFdIRVJFICI7CgogICAgaWYgKCAkU2VsZi0+e0Nhc2VTZW5zaXRpdmV9ICkgewogICAgICAgICRTUUwgLj0gIiRTZWxmLT57Q3VzdG9tZXJDb21wYW55S2V5fSA9ID8iOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgJFNRTCAuPSAiTE9XRVIoJFNlbGYtPntDdXN0b21lckNvbXBhbnlLZXl9KSA9IExPV0VSKCA/ICkiOwogICAgfQoKICAgICMgZ2V0IGluaXRpYWwgZGF0YQogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICBTUUwgID0+ICRTUUwsCiAgICAgICAgQmluZCA9PiBbIFwkQ3VzdG9tZXJJRCBdCiAgICApOwoKICAgICMgZmV0Y2ggdGhlIHJlc3VsdAogICAgbXkgJURhdGE7CiAgICBST1c6CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewoKICAgICAgICBteSAkTWFwQ291bnRlciA9IDA7CgogICAgICAgIGZvciBteSAkRmllbGQgKEBGaWVsZHMpIHsKICAgICAgICAgICAgJERhdGF7ICRGaWVsZHNNYXB7JEZpZWxkfSB9ID0gJFJvd1skTWFwQ291bnRlcl07CiAgICAgICAgICAgICRNYXBDb3VudGVyKys7CiAgICAgICAgfQoKICAgICAgICBuZXh0IFJPVyBpZiAkU2VsZi0+e0ZvcmVpZ25EQn07CgogICAgICAgIGZvciBteSAkS2V5IChxdyhDcmVhdGVUaW1lIENyZWF0ZUJ5IENoYW5nZVRpbWUgQ2hhbmdlQnkpKSB7CiAgICAgICAgICAgICREYXRheyRLZXl9ID0gJFJvd1skTWFwQ291bnRlcl07CiAgICAgICAgICAgICRNYXBDb3VudGVyKys7CiAgICAgICAgfQogICAgfQoKICAgICMgY2FjaGUgcmVxdWVzdAogICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+U2V0KAogICAgICAgICAgICBUeXBlICA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgID0+ICJDdXN0b21lckNvbXBhbnlHZXQ6OiRQYXJhbXtDdXN0b21lcklEfSIsCiAgICAgICAgICAgIFZhbHVlID0+IFwlRGF0YSwKICAgICAgICAgICAgVFRMICAgPT4gJFNlbGYtPntDYWNoZVRUTH0sCiAgICAgICAgKTsKICAgIH0KCiAgICAjIHJldHVybiBkYXRhCiAgICByZXR1cm4gKCVEYXRhKTsKfQoKc3ViIEN1c3RvbWVyQ29tcGFueUFkZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgcm8vcncKICAgIGlmICggJFNlbGYtPntSZWFkT25seX0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdDdXN0b21lckNvbXBhbnkgYmFja2VuZCBpcyByZWFkIG9ubHkhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIG15IEBGaWVsZHM7CiAgICBteSBAUGxhY2Vob2xkZXJzOwogICAgbXkgQFZhbHVlczsKCiAgICBFTlRSWToKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntNYXB9IH0gKSB7CgogICAgICAgICMgaWdub3JlIGR5bmFtaWMgZmllbGRzIGhlcmUKICAgICAgICBuZXh0IEVOVFJZIGlmICRFbnRyeS0+WzVdIGVxICdkeW5hbWljX2ZpZWxkJzsKCiAgICAgICAgcHVzaCBARmllbGRzLCAgICAgICAkRW50cnktPlsyXTsKICAgICAgICBwdXNoIEBQbGFjZWhvbGRlcnMsICc/JzsKICAgICAgICBwdXNoIEBWYWx1ZXMsICAgICAgIFwkUGFyYW17ICRFbnRyeS0+WzBdIH07CiAgICB9CiAgICBpZiAoICEkU2VsZi0+e0ZvcmVpZ25EQn0gKSB7CiAgICAgICAgcHVzaCBARmllbGRzLCAgICAgICBxdyhjcmVhdGVfdGltZSBjcmVhdGVfYnkgY2hhbmdlX3RpbWUgY2hhbmdlX2J5KTsKICAgICAgICBwdXNoIEBQbGFjZWhvbGRlcnMsIHF3KGN1cnJlbnRfdGltZXN0YW1wID8gY3VycmVudF90aW1lc3RhbXAgPyk7CiAgICAgICAgcHVzaCBAVmFsdWVzLCAoIFwkUGFyYW17VXNlcklEfSwgXCRQYXJhbXtVc2VySUR9ICk7CiAgICB9CgogICAgIyBidWlsZCBpbnNlcnQKICAgIG15ICRTUUwgPSAiSU5TRVJUIElOVE8gJFNlbGYtPntDdXN0b21lckNvbXBhbnlUYWJsZX0gKCI7CiAgICAkU1FMIC49IGpvaW4oICcsICcsIEBGaWVsZHMgKSAuICIgKSBWQUxVRVMgKCAiIC4gam9pbiggJywgJywgQFBsYWNlaG9sZGVycyApIC4gIiApIjsKCiAgICByZXR1cm4gaWYgISRTZWxmLT57REJPYmplY3R9LT5EbygKICAgICAgICBTUUwgID0+ICRTUUwsCiAgICAgICAgQmluZCA9PiBcQFZhbHVlcywKICAgICk7CgogICAgIyBsb2cgbm90aWNlCiAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICBQcmlvcml0eSA9PiAnaW5mbycsCiAgICAgICAgTWVzc2FnZSA9PgogICAgICAgICAgICAiQ3VzdG9tZXJDb21wYW55OiAnJFBhcmFte0N1c3RvbWVyQ29tcGFueU5hbWV9LyRQYXJhbXtDdXN0b21lcklEfScgY3JlYXRlZCBzdWNjZXNzZnVsbHkgKCRQYXJhbXtVc2VySUR9KSEiLAogICAgKTsKCiAgICAkU2VsZi0+X0N1c3RvbWVyQ29tcGFueUNhY2hlQ2xlYXIoIEN1c3RvbWVySUQgPT4gJFBhcmFte0N1c3RvbWVySUR9ICk7CgogICAgcmV0dXJuICRQYXJhbXtDdXN0b21lcklEfTsKfQoKc3ViIEN1c3RvbWVyQ29tcGFueVVwZGF0ZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgcm8vcncKICAgIGlmICggJFNlbGYtPntSZWFkT25seX0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdDdXN0b21lciBiYWNrZW5kIGlzIHJlYWQgb25seSEnCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntNYXB9IH0gKSB7CiAgICAgICAgaWYgKAogICAgICAgICAgICAhJFBhcmFteyAkRW50cnktPlswXSB9CiAgICAgICAgICAgICYmICRFbnRyeS0+WzVdIG5lICdkeW5hbWljX2ZpZWxkJyAgICAjIGlnbm9yZSBkeW5hbWljIGZpZWxkcyBoZXJlCiAgICAgICAgICAgICYmICRFbnRyeS0+WzRdCiAgICAgICAgICAgICYmICRFbnRyeS0+WzBdIG5lICdVc2VyUGFzc3dvcmQnCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRFbnRyeS0+WzBdISIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBteSBARmllbGRzOwogICAgbXkgQFZhbHVlczsKCiAgICBGSUVMRDoKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntNYXB9IH0gKSB7CiAgICAgICAgbmV4dCBGSUVMRCBpZiAkRW50cnktPlswXSA9fiAvXlVzZXJQYXNzd29yZCQvaTsKICAgICAgICBuZXh0IEZJRUxEIGlmICRFbnRyeS0+WzVdIGVxICdkeW5hbWljX2ZpZWxkJzsgICAgICMgc2tpcCBkeW5hbWljIGZpZWxkcwogICAgICAgIHB1c2ggQEZpZWxkcywgJEVudHJ5LT5bMl0gLiAnID0gPyc7CiAgICAgICAgcHVzaCBAVmFsdWVzLCBcJFBhcmFteyAkRW50cnktPlswXSB9OwogICAgfQogICAgaWYgKCAhJFNlbGYtPntGb3JlaWduREJ9ICkgewogICAgICAgIHB1c2ggQEZpZWxkcywgKCAnY2hhbmdlX3RpbWUgPSBjdXJyZW50X3RpbWVzdGFtcCcsICdjaGFuZ2VfYnkgPSA/JyApOwogICAgICAgIHB1c2ggQFZhbHVlcywgXCRQYXJhbXtVc2VySUR9OwogICAgfQoKICAgICMgY3JlYXRlIFNRTCBzdGF0ZW1lbnQKICAgIG15ICRTUUwgPSAiVVBEQVRFICRTZWxmLT57Q3VzdG9tZXJDb21wYW55VGFibGV9IFNFVCAiOwogICAgJFNRTCAuPSBqb2luKCAnLCAnLCBARmllbGRzICk7CgogICAgaWYgKCAkU2VsZi0+e0Nhc2VTZW5zaXRpdmV9ICkgewogICAgICAgICRTUUwgLj0gIiBXSEVSRSAkU2VsZi0+e0N1c3RvbWVyQ29tcGFueUtleX0gPSA/IjsKICAgIH0KICAgIGVsc2UgewogICAgICAgICRTUUwgLj0gIiBXSEVSRSBMT1dFUigkU2VsZi0+e0N1c3RvbWVyQ29tcGFueUtleX0pID0gTE9XRVIoID8gKSI7CiAgICB9CiAgICBwdXNoIEBWYWx1ZXMsIFwkUGFyYW17Q3VzdG9tZXJDb21wYW55SUR9OwoKICAgIHJldHVybiBpZiAhJFNlbGYtPntEQk9iamVjdH0tPkRvKAogICAgICAgIFNRTCAgPT4gJFNRTCwKICAgICAgICBCaW5kID0+IFxAVmFsdWVzLAogICAgKTsKCiAgICAjIGxvZyBub3RpY2UKICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgIFByaW9yaXR5ID0+ICdpbmZvJywKICAgICAgICBNZXNzYWdlID0+CiAgICAgICAgICAgICJDdXN0b21lckNvbXBhbnk6ICckUGFyYW17Q3VzdG9tZXJDb21wYW55TmFtZX0vJFBhcmFte0N1c3RvbWVySUR9JyB1cGRhdGVkIHN1Y2Nlc3NmdWxseSAoJFBhcmFte1VzZXJJRH0pISIsCiAgICApOwoKICAgICRTZWxmLT5fQ3VzdG9tZXJDb21wYW55Q2FjaGVDbGVhciggQ3VzdG9tZXJJRCA9PiAkUGFyYW17Q3VzdG9tZXJJRH0gKTsKICAgIGlmICggJFBhcmFte0N1c3RvbWVyQ29tcGFueUlEfSBuZSAkUGFyYW17Q3VzdG9tZXJJRH0gKSB7CiAgICAgICAgJFNlbGYtPl9DdXN0b21lckNvbXBhbnlDYWNoZUNsZWFyKCBDdXN0b21lcklEID0+ICRQYXJhbXtDdXN0b21lckNvbXBhbnlJRH0gKTsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKc3ViIF9DdXN0b21lckNvbXBhbnlDYWNoZUNsZWFyIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0NhY2hlT2JqZWN0fTsKCiAgICBpZiAoICEkUGFyYW17Q3VzdG9tZXJJRH0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIEN1c3RvbWVySUQhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5EZWxldGUoCiAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgS2V5ICA9PiAiQ3VzdG9tZXJDb21wYW55R2V0OjokUGFyYW17Q3VzdG9tZXJJRH0iLAogICAgKTsKCiAgICAjIGRlbGV0ZSBhbGwgc2VhcmNoIGNhY2hlIGVudHJpZXMKICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5DbGVhblVwKAogICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lckNvbXBhbnlMaXN0JywKICAgICk7CgogICAgZm9yIG15ICRGdW5jdGlvbiAocXcoQ3VzdG9tZXJDb21wYW55TGlzdCkpIHsKICAgICAgICBmb3IgbXkgJFZhbGlkICggMCAuLiAxICkgewogICAgICAgICAgICAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+RGVsZXRlKAogICAgICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgICAgICBLZXkgID0+ICIke0Z1bmN0aW9ufTo6JHtWYWxpZH0iLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gMTsKfQoKc3ViIERFU1RST1kgewogICAgbXkgJFNlbGYgPSBzaGlmdDsKCiAgICAjIGRpc2Nvbm5lY3QgaWYgaXQncyBub3QgYSBwYXJlbnQgREJPYmplY3QKICAgIGlmICggJFNlbGYtPntOb3RQYXJlbnREQk9iamVjdH0gKSB7CiAgICAgICAgaWYgKCAkU2VsZi0+e0RCT2JqZWN0fSApIHsKICAgICAgICAgICAgJFNlbGYtPntEQk9iamVjdH0tPkRpc2Nvbm5lY3QoKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCjE7Cg==
IyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIxIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDIxIFpudW55IEdtYkgsIGh0dHBzOi8vem51bnkub3JnLwojIENvcHlyaWdodCAoQykgMjAyMSBSb3RoZXIgT1NTIEdtYkgsIGh0dHBzOi8vcm90aGVyLW9zcy5jb20vCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0zLjAudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXI6OkRCOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYXJpYWJsZUNoZWNrIHF3KDphbGwpOwoKdXNlIENyeXB0OjpQYXNzd2RNRDUgcXcodW5peF9tZDVfY3J5cHQgYXBhY2hlX21kNV9jcnlwdCk7CnVzZSBEaWdlc3Q6OlNIQTsKCm91ciBAT2JqZWN0RGVwZW5kZW5jaWVzID0gKAogICAgJ0tlcm5lbDo6Q29uZmlnJywKICAgICdLZXJuZWw6Okxhbmd1YWdlJywKICAgICdLZXJuZWw6OlN5c3RlbTo6Q2FjaGUnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpDaGVja0l0ZW0nLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScsCiAgICAnS2VybmVsOjpTeXN0ZW06OkRCJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RW5jb2RlJywKICAgICdLZXJuZWw6OlN5c3RlbTo6TG9nJywKICAgICdLZXJuZWw6OlN5c3RlbTo6TWFpbicsCiAgICAnS2VybmVsOjpTeXN0ZW06OlZhbGlkJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkVmFsdWVPYmplY3ROYW1lJywKKTsKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgZGF0YQogICAgZm9yIG15ICROZWVkZWQgKHF3KCBQcmVmZXJlbmNlc09iamVjdCBDdXN0b21lclVzZXJNYXAgKSkgewogICAgICAgICRTZWxmLT57JE5lZWRlZH0gPSAkUGFyYW17JE5lZWRlZH0gfHwgZGllICJHb3Qgbm8gJE5lZWRlZCEiOwogICAgfQoKICAgICMgZ2V0IGRhdGFiYXNlIG9iamVjdAogICAgJFNlbGYtPntEQk9iamVjdH0gPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6REInKTsKCiAgICAjIG1heCBzaG93biB1c2VyIHBlciBzZWFyY2ggbGlzdAogICAgJFNlbGYtPntVc2VyU2VhcmNoTGlzdExpbWl0fSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlclNlYXJjaExpc3RMaW1pdH0gfHwgMjUwOwoKICAgICMgY29uZmlnIG9wdGlvbnMKICAgICRTZWxmLT57Q3VzdG9tZXJUYWJsZX0gPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntQYXJhbXN9LT57VGFibGV9CiAgICAgICAgfHwgZGllICJOZWVkIEN1c3RvbWVyVXNlci0+UGFyYW1zLT5UYWJsZSBpbiBLZXJuZWwvQ29uZmlnLnBtISI7CiAgICAkU2VsZi0+e0N1c3RvbWVyS2V5fSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyS2V5fQogICAgICAgIHx8ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0tleX0KICAgICAgICB8fCBkaWUgIk5lZWQgQ3VzdG9tZXJVc2VyLT5DdXN0b21lcktleSBpbiBLZXJuZWwvQ29uZmlnLnBtISI7CiAgICAkU2VsZi0+e0N1c3RvbWVySUR9ID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJJRH0KICAgICAgICB8fCBkaWUgIk5lZWQgQ3VzdG9tZXJVc2VyLT5DdXN0b21lcklEIGluIEtlcm5lbC9Db25maWcucG0hIjsKICAgICRTZWxmLT57UmVhZE9ubHl9ICAgICAgICAgICAgICAgICA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e1JlYWRPbmx5fTsKICAgICRTZWxmLT57RXhjbHVkZVByaW1hcnlDdXN0b21lcklEfSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlckV4Y2x1ZGVQcmltYXJ5Q3VzdG9tZXJJRH0gfHwgMDsKICAgICRTZWxmLT57U2VhcmNoUHJlZml4fSAgICAgICAgICAgICA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlclNlYXJjaFByZWZpeH07CgogICAgaWYgKCAhZGVmaW5lZCAkU2VsZi0+e1NlYXJjaFByZWZpeH0gKSB7CiAgICAgICAgJFNlbGYtPntTZWFyY2hQcmVmaXh9ID0gJyc7CiAgICB9CiAgICAkU2VsZi0+e1NlYXJjaFN1ZmZpeH0gPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJTZWFyY2hTdWZmaXh9OwogICAgaWYgKCAhZGVmaW5lZCAkU2VsZi0+e1NlYXJjaFN1ZmZpeH0gKSB7CiAgICAgICAgJFNlbGYtPntTZWFyY2hTdWZmaXh9ID0gJyonOwogICAgfQoKICAgICMgY2hlY2sgaWYgQ3VzdG9tZXJLZXkgaXMgdmFyIG9yIGludAogICAgRU5UUlk6CiAgICBmb3IgbXkgJEVudHJ5ICggQHsgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57TWFwfSB9ICkgewogICAgICAgIGlmICggJEVudHJ5LT5bMF0gZXEgJ1VzZXJMb2dpbicgJiYgJEVudHJ5LT5bNV0gPX4gL15pbnQkL2kgKSB7CiAgICAgICAgICAgICRTZWxmLT57Q3VzdG9tZXJLZXlJbnRlZ2VyfSA9IDE7CiAgICAgICAgICAgIGxhc3QgRU5UUlk7CiAgICAgICAgfQogICAgfQoKICAgICMgc2V0IGNhY2hlIHR5cGUKICAgICRTZWxmLT57Q2FjaGVUeXBlfSA9ICdDdXN0b21lclVzZXInIC4gJFBhcmFte0NvdW50fTsKCiAgICAjIGNyZWF0ZSBjYWNoZSBvYmplY3QsIGJ1dCBvbmx5IGlmIENhY2hlVFRMIGlzIHNldCBpbiBjdXN0b21lciBjb25maWcKICAgIGlmICggJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q2FjaGVUVEx9ICkgewogICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNhY2hlJyk7CiAgICB9CgogICAgIyBjcmVhdGUgbmV3IGRiIGNvbm5lY3QgaWYgRFNOIGlzIGdpdmVuCiAgICBpZiAoICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e1BhcmFtc30tPntEU059ICkgewogICAgICAgICRTZWxmLT57REJPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OkRCLT5uZXcoCiAgICAgICAgICAgIERhdGFiYXNlRFNOICA9PiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntQYXJhbXN9LT57RFNOfSwKICAgICAgICAgICAgRGF0YWJhc2VVc2VyID0+ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e1BhcmFtc30tPntVc2VyfSwKICAgICAgICAgICAgRGF0YWJhc2VQdyAgID0+ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e1BhcmFtc30tPntQYXNzd29yZH0sCiAgICAgICAgICAgICV7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e1BhcmFtc30gfSwKICAgICAgICApIHx8IGRpZSgnQ2FuXCd0IGNvbm5lY3QgdG8gZGF0YWJhc2UhJyk7CgogICAgICAgICMgcmVtZW1iZXIgdGhhdCB3ZSBoYXZlIHRoZSBEQk9iamVjdCBub3QgZnJvbSBwYXJlbnQgY2FsbAogICAgICAgICRTZWxmLT57Tm90UGFyZW50REJPYmplY3R9ID0gMTsKICAgIH0KCiAgICAjIHRoaXMgc2V0dGluZyBzcGVjaWZpZXMgaWYgdGhlIHRhYmxlIGhhcyB0aGUgY3JlYXRlX3RpbWUsCiAgICAjIGNyZWF0ZV9ieSwgY2hhbmdlX3RpbWUgYW5kIGNoYW5nZV9ieSBmaWVsZHMgb2YgT1RSUwogICAgJFNlbGYtPntGb3JlaWduREJ9ID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e0ZvcmVpZ25EQn0gPyAxIDogMDsKCiAgICAjIGRlZmluZXMgaWYgdGhlIGRhdGFiYXNlIHNlYXJjaCB3aWxsIGJlIHBlcmZvcm1lbmQgY2FzZSBzZW5zaXRpdmUgKDEpIG9yIG5vdCAoMCkKICAgICRTZWxmLT57Q2FzZVNlbnNpdGl2ZX0gPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntQYXJhbXN9LT57U2VhcmNoQ2FzZVNlbnNpdGl2ZX0KICAgICAgICAvLyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntQYXJhbXN9LT57Q2FzZVNlbnNpdGl2ZX0gfHwgMDsKCiAgICAjIGZldGNoIG5hbWVzIG9mIGNvbmZpZ3VyZWQgZHluYW1pYyBmaWVsZHMKICAgIG15IEBEeW5hbWljRmllbGRNYXBFbnRyaWVzID0gZ3JlcCB7ICRfLT5bNV0gZXEgJ2R5bmFtaWNfZmllbGQnIH0gQHsgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57TWFwfSB9OwogICAgJFNlbGYtPntDb25maWd1cmVkRHluYW1pY0ZpZWxkTmFtZXN9ID0geyBtYXAgeyAkXy0+WzJdID0+IDEgfSBARHluYW1pY0ZpZWxkTWFwRW50cmllcyB9OwoKICAgICMgLS0tCiAgICAjIFJvdGhlck9TUzoKICAgICMgLS0tCiAgICBteSAkTGF5b3V0UGFyYW0gPSAkS2VybmVsOjpPTS0+e1BhcmFtfS0+eydLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0J307CiAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICAjIENoZWNrIGlmIG11bHRpdGVuYW5jeSBpcyBlbmFibGVkIGFuZCB0aGUgcmVxdWVzdCBpcyBjb21pbmcgZnJvbSBhIHVzZXIuCiAgICBpZiAoICRMYXlvdXRQYXJhbS0+e1VzZXJUeXBlfSAmJiAkTGF5b3V0UGFyYW0tPntVc2VyVHlwZX0gZXEgJ1VzZXInICYmICRDb25maWdPYmplY3QtPkdldCgnTXVsdGl0ZW5hbmN5JykgKSB7CgogICAgICAgICMgU2F2ZSB0aGUgVXNlcklEIGFuZCBhbGwgZ3JvdXBzIHRoZSB1c2VyIGhhcyAncm8nIHBlcm1pc3Npb24gb24uCiAgICAgICAgaWYgKCAkTGF5b3V0UGFyYW0tPntVc2VySUR9ICkgewogICAgICAgICAgICAjIE9ubHkgZ2V0IHRoZSBncm91cCBsaXN0IG9uY2UgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMuCiAgICAgICAgICAgIG15ICVHcm91cHMgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnKS0+UGVybWlzc2lvblVzZXJHZXQoCiAgICAgICAgICAgICAgICBVc2VySUQgPT4gJExheW91dFBhcmFtLT57VXNlcklEfSwKICAgICAgICAgICAgICAgIFR5cGUgICA9PiAncm8nLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgIyBUaGUgbGltaXQgZG9lcyBub3QgY291bnQgZm9yIG1lbWJlcnMgb2YgYSBzcGVjaWZpYyBncm91cC4KICAgICAgICAgICAgbXkgJFBlcm1pc3Npb25Hcm91cCA9ICRDb25maWdPYmplY3QtPkdldCgnTXVsdGl0ZW5hbmN5OjpQZXJtaXNzaW9uR3JvdXAnKSB8fCAnJzsKICAgICAgICAgICAgbXkgJUdyb3Vwc1JldmVyc2UgICA9IHJldmVyc2UgJUdyb3VwczsKCiAgICAgICAgICAgIGlmICggISRHcm91cHNSZXZlcnNleyRQZXJtaXNzaW9uR3JvdXB9ICkgewogICAgICAgICAgICAgICAgJFNlbGYtPntNdWx0aXRlbmFuY3l9ID0gJExheW91dFBhcmFtLT57VXNlcklEfTsKICAgICAgICAgICAgICAgICRTZWxmLT57VXNlckdyb3VwSURzfSA9IFsgc29ydCBrZXlzICVHcm91cHMgXTsKICAgICAgICAgICAgICAgICRTZWxmLT57VXNlckdyb3Vwc30gICA9IFsgdmFsdWVzICVHcm91cHMgXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgICMgLS0tCgogICAgcmV0dXJuICRTZWxmOwp9CgpzdWIgQ3VzdG9tZXJOYW1lIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtVc2VyTG9naW59ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBVc2VyTG9naW4hJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNoZWNrIGNhY2hlCiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgIG15ICROYW1lID0gJFNlbGYtPntDYWNoZU9iamVjdH0tPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gIkN1c3RvbWVyTmFtZTo6JFBhcmFte1VzZXJMb2dpbn0iLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuICROYW1lIGlmIGRlZmluZWQgJE5hbWU7CiAgICB9CgogICAgbXkgJEN1c3RvbWVyVXNlck5hbWVGaWVsZHMgPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJOYW1lRmllbGRzfTsKICAgIGlmICggIUlzQXJyYXlSZWZXaXRoRGF0YSgkQ3VzdG9tZXJVc2VyTmFtZUZpZWxkcykgKSB7CiAgICAgICAgJEN1c3RvbWVyVXNlck5hbWVGaWVsZHMgPSBbICdmaXJzdF9uYW1lJywgJ2xhc3RfbmFtZScsIF07CiAgICB9CgogICAgIyByZW1vdmUgZHluYW1pYyBmaWVsZCBuYW1lcyB0aGF0IGFyZSBjb25maWd1cmVkIGluIEN1c3RvbWVyVXNlck5hbWVGaWVsZHMKICAgICMgYXMgdGhleSBjYW5ub3QgYmUgaGFuZGxlZCBoZXJlCiAgICBteSBAQ3VzdG9tZXJVc2VyTmFtZUZpZWxkc1dpdGhvdXREeW5hbWljRmllbGRzCiAgICAgICAgPSBncmVwIHsgIWV4aXN0cyAkU2VsZi0+e0NvbmZpZ3VyZWREeW5hbWljRmllbGROYW1lc30tPnskX30gfSBAeyRDdXN0b21lclVzZXJOYW1lRmllbGRzfTsKCiAgICAjIGJ1aWxkIFNRTCBzdHJpbmcgMS8yCiAgICBteSAkU1FMID0gIlNFTEVDVCAiOwoKICAgICRTUUwgLj0gam9pbiggIiwgIiwgQEN1c3RvbWVyVXNlck5hbWVGaWVsZHNXaXRob3V0RHluYW1pY0ZpZWxkcyApOwogICAgJFNRTCAuPSAiIEZST00gJFNlbGYtPntDdXN0b21lclRhYmxlfSBXSEVSRSAiOwoKICAgICMgY2hlY2sgQ3VzdG9tZXJLZXkgdHlwZQogICAgbXkgJFVzZXJMb2dpbiA9ICRQYXJhbXtVc2VyTG9naW59OwogICAgaWYgKCAkU2VsZi0+e0Nhc2VTZW5zaXRpdmV9ICkgewogICAgICAgICRTUUwgLj0gIiRTZWxmLT57Q3VzdG9tZXJLZXl9ID0gPyI7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkU1FMIC49ICJMT1dFUigkU2VsZi0+e0N1c3RvbWVyS2V5fSkgPSBMT1dFUig/KSI7CiAgICB9CgogICAgbXkgJU5hbWVQYXJ0czsKCiAgICAjIGdldCBkYXRhIGZyb20gY3VzdG9tZXIgdXNlciB0YWJsZQogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICBTUUwgICA9PiAkU1FMLAogICAgICAgIEJpbmQgID0+IFsgXCRQYXJhbXtVc2VyTG9naW59IF0sCiAgICAgICAgTGltaXQgPT4gMSwKICAgICk7CgogICAgbXkgJEZpZWxkQ291bnRlciA9IDA7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgIGZvciBteSAkRmllbGQgKEBSb3cpIHsKICAgICAgICAgICAgJE5hbWVQYXJ0c3sgJEN1c3RvbWVyVXNlck5hbWVGaWVsZHNXaXRob3V0RHluYW1pY0ZpZWxkc1skRmllbGRDb3VudGVyXSB9ID0gJEZpZWxkOwogICAgICAgICAgICAkRmllbGRDb3VudGVyKys7CiAgICAgICAgfQogICAgfQoKICAgICMgZmV0Y2ggZHluYW1pYyBmaWVsZCB2YWx1ZXMsIGlmIGNvbmZpZ3VyZWQKICAgIG15IEBEeW5hbWljRmllbGRDdXN0b21lclVzZXJOYW1lRmllbGRzCiAgICAgICAgPSBncmVwIHsgZXhpc3RzICRTZWxmLT57Q29uZmlndXJlZER5bmFtaWNGaWVsZE5hbWVzfS0+eyRffSB9IEB7JEN1c3RvbWVyVXNlck5hbWVGaWVsZHN9OwogICAgaWYgKEBEeW5hbWljRmllbGRDdXN0b21lclVzZXJOYW1lRmllbGRzKSB7CiAgICAgICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CgogICAgICAgIERZTkFNSUNGSUVMRE5BTUU6CiAgICAgICAgZm9yIG15ICREeW5hbWljRmllbGROYW1lIChARHluYW1pY0ZpZWxkQ3VzdG9tZXJVc2VyTmFtZUZpZWxkcykgewogICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlnID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZCcpLT5EeW5hbWljRmllbGRHZXQoCiAgICAgICAgICAgICAgICBOYW1lID0+ICREeW5hbWljRmllbGROYW1lLAogICAgICAgICAgICApOwogICAgICAgICAgICBuZXh0IERZTkFNSUNGSUVMRE5BTUUgaWYgIUlzSGFzaFJlZldpdGhEYXRhKCREeW5hbWljRmllbGRDb25maWcpOwoKICAgICAgICAgICAgbXkgJFZhbHVlID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlR2V0KAogICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICBPYmplY3ROYW1lICAgICAgICAgPT4gJFBhcmFte1VzZXJMb2dpbn0sCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBuZXh0IERZTkFNSUNGSUVMRE5BTUUgaWYgIWRlZmluZWQgJFZhbHVlOwoKICAgICAgICAgICAgaWYgKCAhSXNBcnJheVJlZldpdGhEYXRhKCRWYWx1ZSkgKSB7CiAgICAgICAgICAgICAgICAkVmFsdWUgPSBbJFZhbHVlXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbXkgQFJlbmRlcmVkVmFsdWVzOwoKICAgICAgICAgICAgVkFMVUU6CiAgICAgICAgICAgIGZvciBteSAkQ3VycmVudFZhbHVlICggQHskVmFsdWV9ICkgewogICAgICAgICAgICAgICAgbmV4dCBWQUxVRSBpZiAhZGVmaW5lZCAkQ3VycmVudFZhbHVlIHx8ICFsZW5ndGggJEN1cnJlbnRWYWx1ZTsKCiAgICAgICAgICAgICAgICBteSAkUmVuZGVyZWRWYWx1ZSA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5SZWFkYWJsZVZhbHVlUmVuZGVyKAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLAogICAgICAgICAgICAgICAgICAgIFZhbHVlICAgICAgICAgICAgICA9PiAkQ3VycmVudFZhbHVlLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBuZXh0IFZBTFVFIGlmICFJc0hhc2hSZWZXaXRoRGF0YSgkUmVuZGVyZWRWYWx1ZSkgfHwgIWRlZmluZWQgJFJlbmRlcmVkVmFsdWUtPntWYWx1ZX07CgogICAgICAgICAgICAgICAgcHVzaCBAUmVuZGVyZWRWYWx1ZXMsICRSZW5kZXJlZFZhbHVlLT57VmFsdWV9OwogICAgICAgICAgICB9CgogICAgICAgICAgICAkTmFtZVBhcnRzeyREeW5hbWljRmllbGROYW1lfSA9IGpvaW4gJyAnLCBAUmVuZGVyZWRWYWx1ZXM7CiAgICAgICAgfQogICAgfQoKICAgICMgYXNzZW1ibGUgbmFtZQogICAgbXkgQE5hbWVQYXJ0czsKICAgIENVU1RPTUVSVVNFUk5BTUVGSUVMRDoKICAgIGZvciBteSAkQ3VzdG9tZXJVc2VyTmFtZUZpZWxkICggQHskQ3VzdG9tZXJVc2VyTmFtZUZpZWxkc30gKSB7CiAgICAgICAgbmV4dCBDVVNUT01FUlVTRVJOQU1FRklFTEQKICAgICAgICAgICAgaWYgIWV4aXN0cyAkTmFtZVBhcnRzeyRDdXN0b21lclVzZXJOYW1lRmllbGR9CiAgICAgICAgICAgIHx8ICFkZWZpbmVkICROYW1lUGFydHN7JEN1c3RvbWVyVXNlck5hbWVGaWVsZH0KICAgICAgICAgICAgfHwgIWxlbmd0aCAkTmFtZVBhcnRzeyRDdXN0b21lclVzZXJOYW1lRmllbGR9OwogICAgICAgIHB1c2ggQE5hbWVQYXJ0cywgJE5hbWVQYXJ0c3skQ3VzdG9tZXJVc2VyTmFtZUZpZWxkfTsKICAgIH0KCiAgICBteSAkSm9pbkNoYXJhY3RlciA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlck5hbWVGaWVsZHNKb2lufSAvLyAnICc7CiAgICBteSAkTmFtZSAgICAgICAgICA9IGpvaW4gJEpvaW5DaGFyYWN0ZXIsIEBOYW1lUGFydHM7CgogICAgIyBjYWNoZSByZXF1ZXN0CiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICAgICAgS2V5ICAgPT4gIkN1c3RvbWVyTmFtZTo6JFBhcmFte1VzZXJMb2dpbn0iLAogICAgICAgICAgICBWYWx1ZSA9PiAkTmFtZSwKICAgICAgICAgICAgVFRMICAgPT4gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q2FjaGVUVEx9LAogICAgICAgICk7CiAgICB9CiAgICByZXR1cm4gJE5hbWU7Cn0KCnN1YiBDdXN0b21lclNlYXJjaCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICVVc2VyczsKICAgIG15ICRWYWxpZCA9IGRlZmluZWQgJFBhcmFte1ZhbGlkfSA/ICRQYXJhbXtWYWxpZH0gOiAxOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoCiAgICAgICAgISRQYXJhbXtTZWFyY2h9CiAgICAgICAgJiYgISRQYXJhbXtVc2VyTG9naW59CiAgICAgICAgJiYgISRQYXJhbXtQb3N0TWFzdGVyU2VhcmNofQogICAgICAgICYmICEkUGFyYW17Q3VzdG9tZXJJRH0KICAgICAgICAmJiAhJFBhcmFte0N1c3RvbWVySURSYXd9CiAgICAgICAgKQogICAgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBTZWFyY2gsIFVzZXJMb2dpbiwgUG9zdE1hc3RlclNlYXJjaCwgQ3VzdG9tZXJJRFJhdyBvciBDdXN0b21lcklEIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjaGVjayBjYWNoZQogICAgbXkgJENhY2hlS2V5ID0gam9pbiAnOjonLCBtYXAgeyAkXyAuICc9JyAuICRQYXJhbXskX30gfSBzb3J0IGtleXMgJVBhcmFtOwogICAgIyAtLS0KICAgICMgUm90aGVyT1NTOiBVc2UgY2FjaGUgZm9yIG11bHRpdGVuYW5jeS4KICAgICMgLS0tCiAgICBpZiAoICRTZWxmLT57TXVsdGl0ZW5hbmN5fSApIHsKICAgICAgICAkQ2FjaGVLZXkgLj0gam9pbiAnJywgbWFwIHsgJzo6R3JvdXBJRD0nIC4gJF8gfSBAeyAkU2VsZi0+e1VzZXJHcm91cElEc30gfTsKICAgIH0KICAgICMgLS0tCiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgIG15ICRVc2VycyA9ICRTZWxmLT57Q2FjaGVPYmplY3R9LT5HZXQoCiAgICAgICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lclNlYXJjaCcsCiAgICAgICAgICAgIEtleSAgPT4gJENhY2hlS2V5LAogICAgICAgICk7CiAgICAgICAgcmV0dXJuICV7JFVzZXJzfSBpZiByZWYgJFVzZXJzIGVxICdIQVNIJzsKICAgIH0KCiAgICBteSAkQ3VzdG9tZXJVc2VyTGlzdEZpZWxkcyA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlckxpc3RGaWVsZHN9OwogICAgaWYgKCAhSXNBcnJheVJlZldpdGhEYXRhKCRDdXN0b21lclVzZXJMaXN0RmllbGRzKSApIHsKICAgICAgICAkQ3VzdG9tZXJVc2VyTGlzdEZpZWxkcyA9IFsgJ2ZpcnN0X25hbWUnLCAnbGFzdF9uYW1lJywgJ2VtYWlsJywgXTsKICAgIH0KCiAgICAjIHJlbW92ZSBkeW5hbWljIGZpZWxkIG5hbWVzIHRoYXQgYXJlIGNvbmZpZ3VyZWQgaW4gQ3VzdG9tZXJVc2VyTGlzdEZpZWxkcwogICAgIyBhcyB0aGV5IGNhbm5vdCBiZSBoYW5kbGVkIGhlcmUKICAgIG15IEBDdXN0b21lclVzZXJMaXN0RmllbGRzV2l0aG91dER5bmFtaWNGaWVsZHMKICAgICAgICA9IGdyZXAgeyAhZXhpc3RzICRTZWxmLT57Q29uZmlndXJlZER5bmFtaWNGaWVsZE5hbWVzfS0+eyRffSB9IEB7JEN1c3RvbWVyVXNlckxpc3RGaWVsZHN9OwoKICAgICMgYnVpbGQgU1FMIHN0cmluZyAxLzIKICAgIG15ICRTUUwgPSAiU0VMRUNUICRTZWxmLT57Q3VzdG9tZXJLZXl9ICI7CiAgICBteSBAQmluZDsKICAgICRTUUwgLj0gJywgJyAuICggam9pbiAnLCAnLCBAQ3VzdG9tZXJVc2VyTGlzdEZpZWxkc1dpdGhvdXREeW5hbWljRmllbGRzICk7CgogICAgIyBnZXQgbGlrZSBlc2NhcGUgc3RyaW5nIG5lZWRlZCBmb3Igc29tZSBkYXRhYmFzZXMgKGUuZy4gb3JhY2xlKQogICAgbXkgJExpa2VFc2NhcGVTdHJpbmcgPSAkU2VsZi0+e0RCT2JqZWN0fS0+R2V0RGF0YWJhc2VGdW5jdGlvbignTGlrZUVzY2FwZVN0cmluZycpOwoKICAgICMgYnVpbGQgU1FMIHN0cmluZyAyLzIKICAgICRTUUwgLj0gIiBGUk9NICRTZWxmLT57Q3VzdG9tZXJUYWJsZX0gV0hFUkUgIjsKICAgIGlmICggJFBhcmFte1NlYXJjaH0gKSB7CiAgICAgICAgaWYgKCAhJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJVc2VyU2VhcmNoRmllbGRzfSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSA9PgogICAgICAgICAgICAgICAgICAgICJOZWVkIEN1c3RvbWVyVXNlclNlYXJjaEZpZWxkcyBpbiBDdXN0b21lclVzZXIgY29uZmlnLCB1bmFibGUgdG8gc2VhcmNoIGZvciAnJFBhcmFte1NlYXJjaH0nISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIG15ICRTZWFyY2ggPSAkU2VsZi0+e0RCT2JqZWN0fS0+UXVlcnlTdHJpbmdFc2NhcGUoIFF1ZXJ5U3RyaW5nID0+ICRQYXJhbXtTZWFyY2h9ICk7CgogICAgICAgICMgcmVtb3ZlIGR5bmFtaWMgZmllbGQgbmFtZXMgdGhhdCBhcmUgY29uZmlndXJlZCBpbiBDdXN0b21lclVzZXJTZWFyY2hGaWVsZHMKICAgICAgICAjIGFzIHRoZXkgY2Fubm90IGJlIHJldHJpZXZlZCBoZXJlCiAgICAgICAgbXkgQEN1c3RvbWVyVXNlclNlYXJjaEZpZWxkcyA9IGdyZXAgeyAhZXhpc3RzICRTZWxmLT57Q29uZmlndXJlZER5bmFtaWNGaWVsZE5hbWVzfS0+eyRffSB9CiAgICAgICAgICAgIEB7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlclNlYXJjaEZpZWxkc30gfTsKCiAgICAgICAgaWYgKCAkUGFyYW17Q3VzdG9tZXJVc2VyT25seX0gKSB7CiAgICAgICAgICAgIEBDdXN0b21lclVzZXJTZWFyY2hGaWVsZHMgPSBncmVwIHsgJF8gbmUgJ2N1c3RvbWVyX2lkJyB9IEBDdXN0b21lclVzZXJTZWFyY2hGaWVsZHM7CiAgICAgICAgfQoKICAgICAgICBteSAlUXVlcnlDb25kaXRpb24gPSAkU2VsZi0+e0RCT2JqZWN0fS0+UXVlcnlDb25kaXRpb24oCiAgICAgICAgICAgIEtleSAgICAgICAgICAgPT4gXEBDdXN0b21lclVzZXJTZWFyY2hGaWVsZHMsICAgICMkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJTZWFyY2hGaWVsZHN9LAogICAgICAgICAgICBWYWx1ZSAgICAgICAgID0+ICRTZWFyY2gsCiAgICAgICAgICAgIFNlYXJjaFByZWZpeCAgPT4gJFNlbGYtPntTZWFyY2hQcmVmaXh9LAogICAgICAgICAgICBTZWFyY2hTdWZmaXggID0+ICRTZWxmLT57U2VhcmNoU3VmZml4fSwKICAgICAgICAgICAgQ2FzZVNlbnNpdGl2ZSA9PiAkU2VsZi0+e0Nhc2VTZW5zaXRpdmV9LAogICAgICAgICAgICBCaW5kTW9kZSAgICAgID0+IDEsCiAgICAgICAgKTsKCiAgICAgICAgJFNRTCAuPSAkUXVlcnlDb25kaXRpb257U1FMfTsKICAgICAgICBwdXNoIEBCaW5kLCBAeyAkUXVlcnlDb25kaXRpb257VmFsdWVzfSB9OwoKICAgICAgICAjIC0tLQogICAgICAgICMgUm90aGVyT1NTOiBEb24ndCBzZWFyY2ggZm9yIGN1c3RvbWVyIHVzZXJzIHdpdGhvdXQgZ3JvdXAgcGVybWlzc2lvbi4KICAgICAgICAjIC0tLQogICAgICAgIGlmICggJFNlbGYtPntNdWx0aXRlbmFuY3l9ICkgewogICAgICAgICAgICBpZiAoICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyQ29tcGFueVN1cHBvcnR9ICkgewogICAgICAgICAgICAgICAgIyBUT0RPOiBXb3JrYXJvdW5kIHVudGlsIHRoZSBzZWFyY2ggZ2V0cyBjaGFuZ2VkLgogICAgICAgICAgICAgICAgJFBhcmFte0xpbWl0fSA9IDEwMDAwMDsKICAgICAgICAgICAgICAgICMgTm9ybWFsbHksIHdlIHNob3VsZCBpbm5lciBqb2luIGFsbCBjdXN0b21lciBjb21wYW5pZXMgdG8gc2VlIGlmIHRoZSBhZ2VudCBoYXMgcGVybWlzc2lvbiB0byBzZWUgdGhlIGN1c3RvbWVyIChjdXJyZW50bHkgd29ya2luZykgb3IgdGhlIGN1c3RvbWVyIGNvbXBhbnkgKGl0ZXJhdGUgdGhyb3VnaCBhbGwgREIgYmFjay1lbmRzKS4KICAgICAgICAgICAgICAgICMgSWYgdGhlIGFnZW50IGRvZXMgbm90IGhhdmUgcGVybWlzc2lvbiBvbiB0aGUgY3VzdG9tZXIgY29tcGFueSBidXQgdGhlIGN1c3RvbWVyIHVzZXIsIHRoZSBxdWVyeSBzaG91bGRuJ3QgcmV0dXJuIHRoZSBjdXN0b21lciB1c2VyLgogICAgICAgICAgICAgICAgIyBDdXJyZW50bHksIHdlIGFyZSBsb29raW5nIGZvciBldmVyeXRoaW5nIGFuZCBmaWx0ZXJpbmcgdGhlIHJlc3VsdCwgd2hpY2ggaXMgbm90IG9wdGltYWwuIFRoZSByZWFsIGxpbWl0IHNob3VsZCBzdGlsbCBiZSBhcHBsaWVkIGluIHRoZSBTeXN0ZW0vQ3VzdG9tZXJVc2VyLnBtLgogICAgICAgICAgICAgICAgIyBUaGUgc2FtZSBhcHBsaWVzIGZvciB0aGUgQ3VzdG9tZXJVc2VyL0xEQVAucG0KICAgICAgICAgICAgICAgICMgU0VMRUNUICogRlJPTSBjdXN0b21lcl91c2VyIGN1CiAgICAgICAgICAgICAgICAjIEpPSU4gY3VzdG9tZXJfY29tcGFueSBjcCBPTiBjdS5jdXN0b21lcl9pZCA9IGNwLmN1c3RvbWVyX2lkCiAgICAgICAgICAgICAgICAjIFdIRVJFICgoY3AuZ3JvdXBfaWQgSU4gKDEpIE9SIGNwLmdyb3VwX2lkIElTIE5VTEwgT1IgY3AuZ3JvdXBfaWQgPSAnJykKICAgICAgICAgICAgICAgICMgICAgIEFORCAoY3UuZ3JvdXBfaWQgSVMgTlVMTCBPUiBjdS5ncm91cF9pZCA9ICcnKSkKICAgICAgICAgICAgICAgICMgT1IgKGN1Lmdyb3VwX2lkIElOICgxKSkKICAgICAgICAgICAgICAgICMgVU5JT04KICAgICAgICAgICAgICAgICMgU0VMRUNUICogRlJPTSBjdXN0b21lcl91c2VyIGN1CiAgICAgICAgICAgICAgICAjIEpPSU4gY3VzdG9tZXJfY29tcGFueV8yIGNwIE9OIGN1LmN1c3RvbWVyX2lkID0gY3AuY3VzdG9tZXJfaWQKICAgICAgICAgICAgICAgICMgV0hFUkUgKChjcC5ncm91cF9pZCBJTiAoMSkgT1IgY3AuZ3JvdXBfaWQgSVMgTlVMTCBPUiBjcC5ncm91cF9pZCA9ICcnKQogICAgICAgICAgICAgICAgIyAgICAgQU5EIChjdS5ncm91cF9pZCBJUyBOVUxMIE9SIGN1Lmdyb3VwX2lkID0gJycpKQogICAgICAgICAgICAgICAgIyBPUiAoY3UuZ3JvdXBfaWQgSU4gKDEpKQogICAgICAgICAgICB9CgogICAgICAgICAgICAjIEdldCB0aGUgY29sdW1uIG5hbWUgd2hlcmUgdGhlIGdyb3VwIElEIGlzIHN0b3JlZC4KICAgICAgICAgICAgbXkgJEdyb3VwSURDb2w7CiAgICAgICAgICAgIGZvciBteSAkTWFwICggQHsgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57TWFwfSB9ICkgewogICAgICAgICAgICAgICAgaWYgKCAkTWFwLT5bMF0gZXEgJ1VzZXJHcm91cElEJyApIHsKICAgICAgICAgICAgICAgICAgICAkR3JvdXBJRENvbCA9ICRNYXAtPlsyXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgIyBUaGUgc291cmNlIHN1cHBvcnRzIG11bHRpdGVuYW5jeS4KICAgICAgICAgICAgaWYgKCRHcm91cElEQ29sKSB7CiAgICAgICAgICAgICAgICBteSAkVXNlckdyb3VwSURTeW5jID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57VXNlckdyb3VwSURTeW5jfTsKICAgICAgICAgICAgICAgICMgQ2hlY2sgaWYgd2UgbWF0Y2ggZm9yIGdyb3VwIElEcyBvciBncm91cCBuYW1lcy4KICAgICAgICAgICAgICAgIG15IEBVc2VyR3JvdXBzID0gJFVzZXJHcm91cElEU3luYy0+e1VzZUdyb3VwTmFtZXN9ID8gQHsgJFNlbGYtPntVc2VyR3JvdXBzfSB9IDogQHsgJFNlbGYtPntVc2VyR3JvdXBJRHN9IH07CgogICAgICAgICAgICAgICAgIyBSZW1hcCBsb2NhbCBncm91cHMgdG8gcmVtb3RlIGdyb3Vwcy4KICAgICAgICAgICAgICAgIGZvciBteSAkUmVtb3RlR3JvdXAgKCBrZXlzICV7ICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH0gfSApIHsKICAgICAgICAgICAgICAgICAgICBteSAkTG9jYWxHcm91cCA9ICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH17JFJlbW90ZUdyb3VwfTsKCiAgICAgICAgICAgICAgICAgICAgQFVzZXJHcm91cHMgPSBtYXAgeyAkXyBlcSAkTG9jYWxHcm91cCA/ICRSZW1vdGVHcm91cCA6ICRfIH0gQFVzZXJHcm91cHM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbXkgJEluQ29uZGl0aW9uID0gJFNlbGYtPntEQk9iamVjdH0tPlF1ZXJ5SW5Db25kaXRpb24oCiAgICAgICAgICAgICAgICAgICAgS2V5ICAgICAgPT4gJEdyb3VwSURDb2wsCiAgICAgICAgICAgICAgICAgICAgVmFsdWVzICAgPT4gXEBVc2VyR3JvdXBzLAogICAgICAgICAgICAgICAgICAgIEJpbmRNb2RlID0+IDAsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICMgSWYgdGhlIGZpZWxkIGlzIGVtcHR5LCB3ZSBoYXZlIGFjY2VzcyBieSBkZWZhdWx0LgogICAgICAgICAgICAgICAgJEluQ29uZGl0aW9uIC49ICIgT1IgKCRHcm91cElEQ29sIElTIE5VTEwgT1IgJEdyb3VwSURDb2wgPSAnJykiOwogICAgICAgICAgICAgICAgJFNRTCAuPSAiIEFORCAoJEluQ29uZGl0aW9uKSI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgIyAtLS0KCiAgICAgICAgJFNRTCAuPSAnICc7CiAgICB9CiAgICBlbHNpZiAoICRQYXJhbXtQb3N0TWFzdGVyU2VhcmNofSApIHsKICAgICAgICBpZiAoICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlclBvc3RNYXN0ZXJTZWFyY2hGaWVsZHN9ICkgewoKICAgICAgICAgICAgIyByZW1vdmUgZHluYW1pYyBmaWVsZCBuYW1lcyB0aGF0IGFyZSBjb25maWd1cmVkIGluIEN1c3RvbWVyVXNlclBvc3RNYXN0ZXJTZWFyY2hGaWVsZHMKICAgICAgICAgICAgIyBhcyB0aGV5IGNhbm5vdCBiZSByZXRyaWV2ZWQgaGVyZQogICAgICAgICAgICBteSBAQ3VzdG9tZXJVc2VyUG9zdE1hc3RlclNlYXJjaEZpZWxkcyA9IGdyZXAgeyAhZXhpc3RzICRTZWxmLT57Q29uZmlndXJlZER5bmFtaWNGaWVsZE5hbWVzfS0+eyRffSB9CiAgICAgICAgICAgICAgICBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJQb3N0TWFzdGVyU2VhcmNoRmllbGRzfSB9OwoKICAgICAgICAgICAgbXkgJFNRTEV4dCA9ICcnOwoKICAgICAgICAgICAgIyBmb3IgbXkgJEZpZWxkICggQHsgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJVc2VyUG9zdE1hc3RlclNlYXJjaEZpZWxkc30gfSApIHsKICAgICAgICAgICAgZm9yIG15ICRGaWVsZCAoQEN1c3RvbWVyVXNlclBvc3RNYXN0ZXJTZWFyY2hGaWVsZHMpIHsKICAgICAgICAgICAgICAgIGlmICgkU1FMRXh0KSB7CiAgICAgICAgICAgICAgICAgICAgJFNRTEV4dCAuPSAnIE9SICc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBteSAkUG9zdE1hc3RlclNlYXJjaCA9ICRTZWxmLT57REJPYmplY3R9LT5RdW90ZSggJFBhcmFte1Bvc3RNYXN0ZXJTZWFyY2h9ICk7CiAgICAgICAgICAgICAgICBwdXNoIEBCaW5kLCBcJFBvc3RNYXN0ZXJTZWFyY2g7CgogICAgICAgICAgICAgICAgaWYgKCAkU2VsZi0+e0Nhc2VTZW5zaXRpdmV9ICkgewogICAgICAgICAgICAgICAgICAgICRTUUxFeHQgLj0gIiAkRmllbGQgPSA/ICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAkU1FMRXh0IC49ICIgTE9XRVIoJEZpZWxkKSA9IExPV0VSKD8pICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJFNRTCAuPSAkU1FMRXh0OwogICAgICAgIH0KICAgIH0KICAgIGVsc2lmICggJFBhcmFte1VzZXJMb2dpbn0gKSB7CgogICAgICAgIG15ICRVc2VyTG9naW4gPSAkUGFyYW17VXNlckxvZ2lufTsKCiAgICAgICAgIyBjaGVjayBDdXN0b21lcktleSB0eXBlCiAgICAgICAgaWYgKCAkU2VsZi0+e0N1c3RvbWVyS2V5SW50ZWdlcn0gKSB7CgogICAgICAgICAgICAjIHJldHVybiBpZiBsb2dpbiBpcyBubyBpbnRlZ2VyCiAgICAgICAgICAgIHJldHVybiBpZiAkUGFyYW17VXNlckxvZ2lufSAhfiAvXihcK3xcLXwpXGR7MSwxNn0kLzsKCiAgICAgICAgICAgICRTUUwgLj0gIiRTZWxmLT57Q3VzdG9tZXJLZXl9ID0gPyI7CiAgICAgICAgICAgIHB1c2ggQEJpbmQsIFwkVXNlckxvZ2luOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJFVzZXJMb2dpbiA9ICclJyAuICRTZWxmLT57REJPYmplY3R9LT5RdW90ZSggJFVzZXJMb2dpbiwgJ0xpa2UnICkgLiAnJSc7CiAgICAgICAgICAgICRVc2VyTG9naW4gPX4gcy9cKi8lL2c7CiAgICAgICAgICAgIHB1c2ggQEJpbmQsIFwkVXNlckxvZ2luOwogICAgICAgICAgICBpZiAoICRTZWxmLT57Q2FzZVNlbnNpdGl2ZX0gKSB7CiAgICAgICAgICAgICAgICAkU1FMIC49ICIkU2VsZi0+e0N1c3RvbWVyS2V5fSBMSUtFID8gJExpa2VFc2NhcGVTdHJpbmciOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJFNRTCAuPSAiTE9XRVIoJFNlbGYtPntDdXN0b21lcktleX0pIExJS0UgTE9XRVIoPykgJExpa2VFc2NhcGVTdHJpbmciOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZWxzaWYgKCAkUGFyYW17Q3VzdG9tZXJJRH0gKSB7CgogICAgICAgIG15ICRDdXN0b21lcklEID0gJFNlbGYtPntEQk9iamVjdH0tPlF1b3RlKCAkUGFyYW17Q3VzdG9tZXJJRH0sICdMaWtlJyApOwogICAgICAgICRDdXN0b21lcklEID1+IHMvXCovJS9nOwogICAgICAgIHB1c2ggQEJpbmQsIFwkQ3VzdG9tZXJJRDsKCiAgICAgICAgaWYgKCAkU2VsZi0+e0Nhc2VTZW5zaXRpdmV9ICkgewogICAgICAgICAgICAkU1FMIC49ICIkU2VsZi0+e0N1c3RvbWVySUR9IExJS0UgPyAkTGlrZUVzY2FwZVN0cmluZyI7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkU1FMIC49ICJMT1dFUigkU2VsZi0+e0N1c3RvbWVySUR9KSBMSUtFIExPV0VSKD8pICRMaWtlRXNjYXBlU3RyaW5nIjsKICAgICAgICB9CiAgICB9CiAgICBlbHNpZiAoICRQYXJhbXtDdXN0b21lcklEUmF3fSApIHsKCiAgICAgICAgcHVzaCBAQmluZCwgXCRQYXJhbXtDdXN0b21lcklEUmF3fTsKCiAgICAgICAgaWYgKCAkU2VsZi0+e0Nhc2VTZW5zaXRpdmV9ICkgewogICAgICAgICAgICAkU1FMIC49ICIkU2VsZi0+e0N1c3RvbWVySUR9ID0gPyAiOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJFNRTCAuPSAiTE9XRVIoJFNlbGYtPntDdXN0b21lcklEfSkgPSBMT1dFUig/KSAiOwogICAgICAgIH0KICAgIH0KCiAgICAjIGFkZCB2YWxpZCBvcHRpb24KICAgIGlmICggJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJWYWxpZH0gJiYgJFZhbGlkICkgewoKICAgICAgICAjIGdldCB2YWxpZCBvYmplY3QKICAgICAgICBteSAkVmFsaWRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6VmFsaWQnKTsKCiAgICAgICAgJFNRTCAuPSAnIEFORCAnCiAgICAgICAgICAgIC4gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJWYWxpZH0KICAgICAgICAgICAgLiAnIElOICgnIC4gam9pbiggJywgJywgJFZhbGlkT2JqZWN0LT5WYWxpZElEc0dldCgpICkgLiAnKSAnOwogICAgfQoKICAgICMgZHluYW1pYyBmaWVsZCBoYW5kbGluZwogICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CgogICAgbXkgJER5bmFtaWNGaWVsZENvbmZpZ3MgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkJyktPkR5bmFtaWNGaWVsZExpc3RHZXQoCiAgICAgICAgT2JqZWN0VHlwZSA9PiAnQ3VzdG9tZXJVc2VyJywKICAgICAgICBWYWxpZCAgICAgID0+IDEsCiAgICApOwogICAgbXkgJUR5bmFtaWNGaWVsZENvbmZpZ3NCeU5hbWUgPSBtYXAgeyAkXy0+e05hbWV9ID0+ICRfIH0gQHskRHluYW1pY0ZpZWxkQ29uZmlnc307CgogICAgbXkgQEN1c3RvbWVyVXNlckxpc3RGaWVsZHNEeW5hbWljRmllbGRzCiAgICAgICAgPSBncmVwIHsgZXhpc3RzICRTZWxmLT57Q29uZmlndXJlZER5bmFtaWNGaWVsZE5hbWVzfS0+eyRffSB9IEB7JEN1c3RvbWVyVXNlckxpc3RGaWVsZHN9OwoKICAgICMgZ2V0IGRhdGEgZnJvbSBjdXN0b21lciB1c2VyIHRhYmxlCiAgICByZXR1cm4gaWYgISRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKAogICAgICAgIFNRTCAgID0+ICRTUUwsCiAgICAgICAgQmluZCAgPT4gXEBCaW5kLAogICAgICAgIExpbWl0ID0+ICRQYXJhbXtMaW1pdH0gfHwgJFNlbGYtPntVc2VyU2VhcmNoTGlzdExpbWl0fSwKICAgICk7CgogICAgbXkgQEN1c3RvbWVyVXNlckRhdGE7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgIHB1c2ggQEN1c3RvbWVyVXNlckRhdGEsIFtAUm93XTsKICAgIH0KCiAgICBDVVNUT01FUlVTRVJEQVRBOgogICAgZm9yIG15ICRDdXN0b21lclVzZXJEYXRhIChAQ3VzdG9tZXJVc2VyRGF0YSkgewogICAgICAgIG15ICRDdXN0b21lcktleSA9IHNoaWZ0IEB7JEN1c3RvbWVyVXNlckRhdGF9OwogICAgICAgIG5leHQgQ1VTVE9NRVJVU0VSREFUQSBpZiAkVXNlcnN7JEN1c3RvbWVyS2V5fTsKCiAgICAgICAgbXkgJVVzZXJTdHJpbmdQYXJ0czsKCiAgICAgICAgbXkgJEZpZWxkQ291bnRlciA9IDA7CiAgICAgICAgZm9yIG15ICRGaWVsZCAoIEB7JEN1c3RvbWVyVXNlckRhdGF9ICkgewogICAgICAgICAgICAkVXNlclN0cmluZ1BhcnRzeyAkQ3VzdG9tZXJVc2VyTGlzdEZpZWxkc1dpdGhvdXREeW5hbWljRmllbGRzWyRGaWVsZENvdW50ZXJdIH0gPSAkRmllbGQ7CiAgICAgICAgICAgICRGaWVsZENvdW50ZXIrKzsKICAgICAgICB9CgogICAgICAgICMgZmV0Y2ggZHluYW1pYyBmaWVsZCB2YWx1ZXMsIGlmIGNvbmZpZ3VyZWQKICAgICAgICBpZiAoQEN1c3RvbWVyVXNlckxpc3RGaWVsZHNEeW5hbWljRmllbGRzKSB7CiAgICAgICAgICAgIERZTkFNSUNGSUVMRE5BTUU6CiAgICAgICAgICAgIGZvciBteSAkRHluYW1pY0ZpZWxkTmFtZSAoQEN1c3RvbWVyVXNlckxpc3RGaWVsZHNEeW5hbWljRmllbGRzKSB7CiAgICAgICAgICAgICAgICBuZXh0IERZTkFNSUNGSUVMRE5BTUUgaWYgIWV4aXN0cyAkRHluYW1pY0ZpZWxkQ29uZmlnc0J5TmFtZXskRHluYW1pY0ZpZWxkTmFtZX07CgogICAgICAgICAgICAgICAgbXkgJFZhbHVlID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlR2V0KAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnc0J5TmFtZXskRHluYW1pY0ZpZWxkTmFtZX0sCiAgICAgICAgICAgICAgICAgICAgT2JqZWN0TmFtZSAgICAgICAgID0+ICRDdXN0b21lcktleSwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgbmV4dCBEWU5BTUlDRklFTEROQU1FIGlmICFkZWZpbmVkICRWYWx1ZTsKCiAgICAgICAgICAgICAgICBpZiAoICFJc0FycmF5UmVmV2l0aERhdGEoJFZhbHVlKSApIHsKICAgICAgICAgICAgICAgICAgICAkVmFsdWUgPSBbJFZhbHVlXTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBteSBAVmFsdWVzOwoKICAgICAgICAgICAgICAgIFZBTFVFOgogICAgICAgICAgICAgICAgZm9yIG15ICRDdXJyZW50VmFsdWUgKCBAeyRWYWx1ZX0gKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBWQUxVRSBpZiAhZGVmaW5lZCAkQ3VycmVudFZhbHVlIHx8ICFsZW5ndGggJEN1cnJlbnRWYWx1ZTsKCiAgICAgICAgICAgICAgICAgICAgbXkgJFJlYWRhYmxlVmFsdWUgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+UmVhZGFibGVWYWx1ZVJlbmRlcigKICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWdzQnlOYW1leyREeW5hbWljRmllbGROYW1lfSwKICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICAgICAgID0+ICRDdXJyZW50VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgbmV4dCBWQUxVRSBpZiAhSXNIYXNoUmVmV2l0aERhdGEoJFJlYWRhYmxlVmFsdWUpIHx8ICFkZWZpbmVkICRSZWFkYWJsZVZhbHVlLT57VmFsdWV9OwoKICAgICAgICAgICAgICAgICAgICBteSAkSXNBQ0xSZWR1Y2libGUgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+SGFzQmVoYXZpb3IoCiAgICAgICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnc0J5TmFtZXskRHluYW1pY0ZpZWxkTmFtZX0sCiAgICAgICAgICAgICAgICAgICAgICAgIEJlaGF2aW9yICAgICAgICAgICA9PiAnSXNBQ0xSZWR1Y2libGUnLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRJc0FDTFJlZHVjaWJsZSkgewogICAgICAgICAgICAgICAgICAgICAgICBteSAkUG9zc2libGVWYWx1ZXMgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+UG9zc2libGVWYWx1ZXNHZXQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZENvbmZpZ3NCeU5hbWV7JER5bmFtaWNGaWVsZE5hbWV9LAogICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSXNIYXNoUmVmV2l0aERhdGEoJFBvc3NpYmxlVmFsdWVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZGVmaW5lZCAkUG9zc2libGVWYWx1ZXMtPnsgJFJlYWRhYmxlVmFsdWUtPntWYWx1ZX0gfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkUmVhZGFibGVWYWx1ZS0+e1ZhbHVlfSA9ICRQb3NzaWJsZVZhbHVlcy0+eyAkUmVhZGFibGVWYWx1ZS0+e1ZhbHVlfSB9OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBwdXNoIEBWYWx1ZXMsICRSZWFkYWJsZVZhbHVlLT57VmFsdWV9OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICRVc2VyU3RyaW5nUGFydHN7JER5bmFtaWNGaWVsZE5hbWV9ID0gam9pbiAnICcsIEBWYWx1ZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgYXNzZW1ibGUgdXNlciBzdHJpbmcKICAgICAgICBteSBAVXNlclN0cmluZ1BhcnRzOwogICAgICAgIENVU1RPTUVSVVNFUkxJU1RGSUVMRDoKICAgICAgICBmb3IgbXkgJEN1c3RvbWVyVXNlckxpc3RGaWVsZCAoIEB7JEN1c3RvbWVyVXNlckxpc3RGaWVsZHN9ICkgewogICAgICAgICAgICBuZXh0IENVU1RPTUVSVVNFUkxJU1RGSUVMRAogICAgICAgICAgICAgICAgaWYgIWV4aXN0cyAkVXNlclN0cmluZ1BhcnRzeyRDdXN0b21lclVzZXJMaXN0RmllbGR9CiAgICAgICAgICAgICAgICB8fCAhZGVmaW5lZCAkVXNlclN0cmluZ1BhcnRzeyRDdXN0b21lclVzZXJMaXN0RmllbGR9CiAgICAgICAgICAgICAgICB8fCAhbGVuZ3RoICRVc2VyU3RyaW5nUGFydHN7JEN1c3RvbWVyVXNlckxpc3RGaWVsZH07CiAgICAgICAgICAgIHB1c2ggQFVzZXJTdHJpbmdQYXJ0cywgJFVzZXJTdHJpbmdQYXJ0c3skQ3VzdG9tZXJVc2VyTGlzdEZpZWxkfTsKICAgICAgICB9CgogICAgICAgICRVc2Vyc3skQ3VzdG9tZXJLZXl9ID0gam9pbiAnICcsIEBVc2VyU3RyaW5nUGFydHM7CiAgICAgICAgJFVzZXJzeyRDdXN0b21lcktleX0gPX4gcy9eKC4qKVxzKC4rP1xALis/XC4uKz8pKFxzfCkkLyIkMSIgPCQyPi87CiAgICB9CgogICAgIyBjYWNoZSByZXF1ZXN0CiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSAuICdfQ3VzdG9tZXJTZWFyY2gnLAogICAgICAgICAgICBLZXkgICA9PiAkQ2FjaGVLZXksCiAgICAgICAgICAgIFZhbHVlID0+IFwlVXNlcnMsCiAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0NhY2hlVFRMfSwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAlVXNlcnM7Cn0KCnN1YiBDdXN0b21lclNlYXJjaERldGFpbCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIGlmICggcmVmICRQYXJhbXtTZWFyY2hGaWVsZHN9IG5lICdBUlJBWScgKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJTZWFyY2hGaWVsZHMgbXVzdCBiZSBhbiBhcnJheSByZWZlcmVuY2UhIiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBteSAkVmFsaWQgPSBkZWZpbmVkICRQYXJhbXtWYWxpZH0gPyAkUGFyYW17VmFsaWR9IDogMTsKCiAgICAkUGFyYW17TGltaXR9IC8vPSAnJzsKCiAgICAjIFNwbGl0IHRoZSBzZWFyY2ggZmllbGRzIGluIHNjYWxhciBhbmQgYXJyYXkgZmllbGRzLCBiZWZvcmUgdGhlIGRpZmZyZW50IGhhbmRsaW5nLgogICAgbXkgQFNjYWxhclNlYXJjaEZpZWxkcyA9IGdyZXAgeyAnSW5wdXQnIGVxICRfLT57VHlwZX0gfSBAeyAkUGFyYW17U2VhcmNoRmllbGRzfSB9OwogICAgbXkgQEFycmF5U2VhcmNoRmllbGRzICA9IGdyZXAgeyAnU2VsZWN0aW9uJyBlcSAkXy0+e1R5cGV9IH0gQHsgJFBhcmFte1NlYXJjaEZpZWxkc30gfTsKCiAgICAjIFZlcmlmeSB0aGF0IGFsbCBwYXNzZWQgYXJyYXkgcGFyYW1ldGVycyBjb250YWluIGFuIGFycmF5cmVmLgogICAgQVJHVU1FTlQ6CiAgICBmb3IgbXkgJEFyZ3VtZW50IChAQXJyYXlTZWFyY2hGaWVsZHMpIHsKICAgICAgICBpZiAoICFkZWZpbmVkICRQYXJhbXsgJEFyZ3VtZW50LT57TmFtZX0gfSApIHsKICAgICAgICAgICAgJFBhcmFteyAkQXJndW1lbnQtPntOYW1lfSB9IHx8PSBbXTsKCiAgICAgICAgICAgIG5leHQgQVJHVU1FTlQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoIHJlZiAkUGFyYW17ICRBcmd1bWVudC0+e05hbWV9IH0gbmUgJ0FSUkFZJyApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIiRBcmd1bWVudC0+e05hbWV9IG11c3QgYmUgYW4gYXJyYXkgcmVmZXJlbmNlISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBTZXQgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIGZvciB0aGUgcmV0dXJuIHR5cGUuCiAgICBteSAkUmVzdWx0ID0gJFBhcmFte1Jlc3VsdH0gfHwgJ0FSUkFZJzsKCiAgICAjIFNwZWNpYWwgaGFuZGxpbmcgaWYgdGhlIHJlc3VsdCB0eXBlIGlzICdDT1VOVCcuCiAgICBpZiAoICRSZXN1bHQgZXEgJ0NPVU5UJyApIHsKCiAgICAgICAgIyBJZ25vcmUgdGhlIHBhcmFtZXRlciAnTGltaXQnIHdoZW4gcmVzdWx0IHR5cGUgaXMgJ0NPVU5UJy4KICAgICAgICAkUGFyYW17TGltaXR9ID0gJyc7CgogICAgICAgICMgRGVsZXRlIHRoZSBPcmRlckJ5IHBhcmFtZXRlciB3aGVuIHRoZSByZXN1bHQgdHlwZSBpcyAnQ09VTlQnLgogICAgICAgICRQYXJhbXtPcmRlckJ5fSA9IFtdOwogICAgfQoKICAgICMgRGVmaW5lIG9yZGVyIHRhYmxlIGZyb20gdGhlIHNlYXJjaCBmaWVsZHMuCiAgICBteSAlT3JkZXJCeVRhYmxlID0gbWFwIHsgJF8tPntOYW1lfSA9PiAkXy0+e0RhdGFiYXNlRmllbGR9IH0gQHsgJFBhcmFte1NlYXJjaEZpZWxkc30gfTsKCiAgICBmb3IgbXkgJEZpZWxkIChAQXJyYXlTZWFyY2hGaWVsZHMpIHsKCiAgICAgICAgbXkgJFNlbGVjdGlvbnNEYXRhID0gJEZpZWxkLT57U2VsZWN0aW9uc0RhdGF9OwoKICAgICAgICBmb3IgbXkgJFNlbGVjdGVkVmFsdWUgKCBAeyAkUGFyYW17ICRGaWVsZC0+e05hbWV9IH0gfSApIHsKCiAgICAgICAgICAgICMgQ2hlY2sgaWYgdGhlIHNlbGVjdGVkIHZhbHVlIGZvciB0aGUgY3VycmVudCBmaWVsZCBpcyB2YWxpZC4KICAgICAgICAgICAgaWYgKCAhJFNlbGVjdGlvbnNEYXRhLT57JFNlbGVjdGVkVmFsdWV9ICkgewogICAgICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiVGhlIHNlbGVjdGVkIHZhbHVlICRGaWVsZC0+e05hbWV9IGlzIG5vdCB2YWxpZCEiLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBteSAkREJPYmplY3QgPSAkU2VsZi0+e0RCT2JqZWN0fTsKCiAgICAjIEFzc2VtYmxlIHRoZSBjb25kaXRpb25zIHVzZWQgaW4gdGhlIFdIRVJFIGNsYXVzZS4KICAgIG15IEBTUUxXaGVyZTsKCiAgICBmb3IgbXkgJEZpZWxkIChAU2NhbGFyU2VhcmNoRmllbGRzKSB7CgogICAgICAgICMgU2VhcmNoIGZvciBzY2FsYXIgZmllbGRzICh3aWxkY2FyZHMgYXJlIGFsbG93ZWQpLgogICAgICAgIGlmICggJFBhcmFteyAkRmllbGQtPntOYW1lfSB9ICkgewoKICAgICAgICAgICAgIyBHZXQgbGlrZSBlc2NhcGUgc3RyaW5nIG5lZWRlZCBmb3Igc29tZSBkYXRhYmFzZXMgKGUuZy4gb3JhY2xlKS4KICAgICAgICAgICAgbXkgJExpa2VFc2NhcGVTdHJpbmcgPSAkREJPYmplY3QtPkdldERhdGFiYXNlRnVuY3Rpb24oJ0xpa2VFc2NhcGVTdHJpbmcnKTsKCiAgICAgICAgICAgICRQYXJhbXsgJEZpZWxkLT57TmFtZX0gfSA9ICREQk9iamVjdC0+UXVvdGUoICRQYXJhbXsgJEZpZWxkLT57TmFtZX0gfSwgJ0xpa2UnICk7CgogICAgICAgICAgICAkUGFyYW17ICRGaWVsZC0+e05hbWV9IH0gPX4gc3sgXCorIH17JX14bXNnOwoKICAgICAgICAgICAgIyBJZiB0aGUgZmllbGQgY29udGFpbnMgbW9yZSB0aGFuIG9ubHkgJS4KICAgICAgICAgICAgaWYgKCAkUGFyYW17ICRGaWVsZC0+e05hbWV9IH0gIX4gbXsgXEEgJSogXHogfXhtcyApIHsKICAgICAgICAgICAgICAgIHB1c2ggQFNRTFdoZXJlLAogICAgICAgICAgICAgICAgICAgICJMT1dFUigkRmllbGQtPntEYXRhYmFzZUZpZWxkfSkgTElLRSBMT1dFUignJFBhcmFteyAkRmllbGQtPntOYW1lfSB9JykgJExpa2VFc2NhcGVTdHJpbmciOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIG15ICREeW5hbWljRmllbGRPYmplY3QgICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZCcpOwogICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CgogICAgIyBDaGVjayBhbGwgY29uZmlndXJlZCBjaGFuZ2UgZHluYW1pYyBmaWVsZHMsIGJ1aWxkIGxvb2t1cCBoYXNoIGJ5IG5hbWUuCiAgICBteSAlQ3VzdG9tZXJVc2VyRHluYW1pY0ZpZWxkTmFtZTJDb25maWc7CiAgICBteSAkQ3VzdG9tZXJVc2VyRHluYW1pY0ZpZWxkcyA9ICREeW5hbWljRmllbGRPYmplY3QtPkR5bmFtaWNGaWVsZExpc3RHZXQoCiAgICAgICAgT2JqZWN0VHlwZSA9PiAnQ3VzdG9tZXJVc2VyJywKICAgICk7CiAgICBmb3IgbXkgJER5bmFtaWNGaWVsZCAoIEB7JEN1c3RvbWVyVXNlckR5bmFtaWNGaWVsZHN9ICkgewogICAgICAgICRDdXN0b21lclVzZXJEeW5hbWljRmllbGROYW1lMkNvbmZpZ3sgJER5bmFtaWNGaWVsZC0+e05hbWV9IH0gPSAkRHluYW1pY0ZpZWxkOwogICAgfQoKICAgIG15ICRTUUxEeW5hbWljRmllbGRGcm9tICAgICA9ICcnOwogICAgbXkgJFNRTER5bmFtaWNGaWVsZFdoZXJlICAgID0gJyc7CiAgICBteSAkRHluYW1pY0ZpZWxkSm9pbkNvdW50ZXIgPSAxOwoKICAgIERZTkFNSUNGSUVMRDoKICAgIGZvciBteSAkRHluYW1pY0ZpZWxkICggQHskQ3VzdG9tZXJVc2VyRHluYW1pY0ZpZWxkc30gKSB7CgogICAgICAgIG15ICRTZWFyY2hQYXJhbSA9ICRQYXJhbXsgIkR5bmFtaWNGaWVsZF8iIC4gJER5bmFtaWNGaWVsZC0+e05hbWV9IH07CgogICAgICAgIG5leHQgRFlOQU1JQ0ZJRUxEIGlmICggISRTZWFyY2hQYXJhbSApOwogICAgICAgIG5leHQgRFlOQU1JQ0ZJRUxEIGlmICggcmVmICRTZWFyY2hQYXJhbSBuZSAnSEFTSCcgKTsKCiAgICAgICAgbXkgJE5lZWRKb2luOwoKICAgICAgICBmb3IgbXkgJE9wZXJhdG9yICggc29ydCBrZXlzICV7JFNlYXJjaFBhcmFtfSApIHsKCiAgICAgICAgICAgIG15IEBTZWFyY2hQYXJhbXMgPSAoIHJlZiAkU2VhcmNoUGFyYW0tPnskT3BlcmF0b3J9IGVxICdBUlJBWScgKQogICAgICAgICAgICAgICAgPyBAeyAkU2VhcmNoUGFyYW0tPnskT3BlcmF0b3J9IH0KICAgICAgICAgICAgICAgIDogKCAkU2VhcmNoUGFyYW0tPnskT3BlcmF0b3J9ICk7CgogICAgICAgICAgICBteSAkU1FMRHluYW1pY0ZpZWxkV2hlcmVTdWIgPSAnJzsKICAgICAgICAgICAgaWYgKCRTUUxEeW5hbWljRmllbGRXaGVyZSkgewogICAgICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZFdoZXJlU3ViID0gJyBBTkQgKCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkU1FMRHluYW1pY0ZpZWxkV2hlcmVTdWIgPSAnICgnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBteSAkQ291bnRlciA9IDA7CiAgICAgICAgICAgIFRFWFQ6CiAgICAgICAgICAgIGZvciBteSAkVGV4dCAoQFNlYXJjaFBhcmFtcykgewogICAgICAgICAgICAgICAgbmV4dCBURVhUIGlmICggIWRlZmluZWQgJFRleHQgfHwgJFRleHQgZXEgJycgKTsKCiAgICAgICAgICAgICAgICAkVGV4dCA9fiBzL1wqLyUvZ2k7CgogICAgICAgICAgICAgICAgIyBDaGVjayBzZWFyY2ggYXR0cmlidXRlLCB3ZSBkbyBub3QgbmVlZCB0byBzZWFyY2ggZm9yICcqJy4KICAgICAgICAgICAgICAgIG5leHQgVEVYVCBpZiAkVGV4dCA9fiAvXlwlezEsM30kLzsKCiAgICAgICAgICAgICAgICBteSAkVmFsaWRhdGVTdWNjZXNzID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlVmFsaWRhdGUoCiAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGQsCiAgICAgICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICAgICAgID0+ICRUZXh0LAogICAgICAgICAgICAgICAgICAgIFVzZXJJRCAgICAgICAgICAgICA9PiAkUGFyYW17VXNlcklEfSB8fCAxLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICggISRWYWxpZGF0ZVN1Y2Nlc3MgKSB7CiAgICAgICAgICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJTZWFyY2ggbm90IGV4ZWN1dGVkIGR1ZSB0byBpbnZhbGlkIHZhbHVlICciCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICRUZXh0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICInIG9uIGZpZWxkICciCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICREeW5hbWljRmllbGQtPntOYW1lfSAuICInISIsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRDb3VudGVyKSB7CiAgICAgICAgICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZFdoZXJlU3ViIC49ICcgT1IgJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRTUUxEeW5hbWljRmllbGRXaGVyZVN1YiAuPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+U2VhcmNoU1FMR2V0KAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkLAogICAgICAgICAgICAgICAgICAgIFRhYmxlQWxpYXMgICAgICAgICA9PiAiZGZ2JER5bmFtaWNGaWVsZEpvaW5Db3VudGVyIiwKICAgICAgICAgICAgICAgICAgICBPcGVyYXRvciAgICAgICAgICAgPT4gJE9wZXJhdG9yLAogICAgICAgICAgICAgICAgICAgIFNlYXJjaFRlcm0gICAgICAgICA9PiAkVGV4dCwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgJENvdW50ZXIrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkU1FMRHluYW1pY0ZpZWxkV2hlcmVTdWIgLj0gJykgJzsKCiAgICAgICAgICAgIGlmICgkQ291bnRlcikgewogICAgICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZFdoZXJlIC49ICRTUUxEeW5hbWljRmllbGRXaGVyZVN1YjsKICAgICAgICAgICAgICAgICROZWVkSm9pbiA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkTmVlZEpvaW4pIHsKICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZEZyb20gLj0gIgogICAgICAgICAgICAgICAgSU5ORVIgSk9JTiBkeW5hbWljX2ZpZWxkX3ZhbHVlIGRmdiREeW5hbWljRmllbGRKb2luQ291bnRlcgogICAgICAgICAgICAgICAgICAgIE9OIChkZl9vYmpfaWRfbmFtZS5vYmplY3RfaWQgPSBkZnYkRHluYW1pY0ZpZWxkSm9pbkNvdW50ZXIub2JqZWN0X2lkCiAgICAgICAgICAgICAgICAgICAgICAgIEFORCBkZnYkRHluYW1pY0ZpZWxkSm9pbkNvdW50ZXIuZmllbGRfaWQgPSAiCiAgICAgICAgICAgICAgICAuICREQk9iamVjdC0+UXVvdGUoICREeW5hbWljRmllbGQtPntJRH0sICdJbnRlZ2VyJyApIC4gIikKICAgICAgICAgICAgIjsKCiAgICAgICAgICAgICREeW5hbWljRmllbGRKb2luQ291bnRlcisrOwogICAgICAgIH0KICAgIH0KCiAgICAjIEV4ZWN1dGUgYSBkeW5hbWljIGZpZWxkIHNlYXJjaCwgaWYgYSBkeW5hbWljIGZpZWxkIHdoZXJlIHN0YXRlbWVudCBleGlzdHMuCiAgICBpZiAoJFNRTER5bmFtaWNGaWVsZFdoZXJlKSB7CgogICAgICAgIG15IEBEeW5hbWljRmllbGRVc2VyTG9naW5zOwoKICAgICAgICBteSAkU1FMRHluYW1pY0ZpZWxkCiAgICAgICAgICAgID0gIlNFTEVDVCBESVNUSU5DVChkZl9vYmpfaWRfbmFtZS5vYmplY3RfbmFtZSkgRlJPTSBkeW5hbWljX2ZpZWxkX29ial9pZF9uYW1lIGRmX29ial9pZF9uYW1lICIKICAgICAgICAgICAgLiAkU1FMRHluYW1pY0ZpZWxkRnJvbQogICAgICAgICAgICAuICIgV0hFUkUgIgogICAgICAgICAgICAuICRTUUxEeW5hbWljRmllbGRXaGVyZTsKCiAgICAgICAgbXkgJFVzZWRDYWNoZTsKCiAgICAgICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKCiAgICAgICAgICAgIG15ICREeW5hbWljRmllbGRTZWFyY2hDYWNoZURhdGEgPSAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+R2V0KAogICAgICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyU2VhcmNoRGV0YWlsRHluYW1pY0ZpZWxkcycsCiAgICAgICAgICAgICAgICBLZXkgID0+ICRTUUxEeW5hbWljRmllbGQsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoIGRlZmluZWQgJER5bmFtaWNGaWVsZFNlYXJjaENhY2hlRGF0YSApIHsKICAgICAgICAgICAgICAgIGlmICggcmVmICREeW5hbWljRmllbGRTZWFyY2hDYWNoZURhdGEgZXEgJ0FSUkFZJyApIHsKICAgICAgICAgICAgICAgICAgICBARHluYW1pY0ZpZWxkVXNlckxvZ2lucyA9IEB7JER5bmFtaWNGaWVsZFNlYXJjaENhY2hlRGF0YX07CgogICAgICAgICAgICAgICAgICAgICRVc2VkQ2FjaGUgPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdJbnZhbGlkIHJlZiAnIC4gcmVmKCREeW5hbWljRmllbGRTZWFyY2hDYWNoZURhdGEpIC4gJyEnCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgR2V0IHRoZSBkYXRhIG9ubHkgZnJvbSBkYXRhYmFzZSwgaWYgbm8gY2FjaGUgZW50cnkgZXhpc3RzLgogICAgICAgIGlmICggISRVc2VkQ2FjaGUgKSB7CgogICAgICAgICAgICByZXR1cm4gaWYgISREQk9iamVjdC0+UHJlcGFyZSgKICAgICAgICAgICAgICAgIFNRTCA9PiAkU1FMRHluYW1pY0ZpZWxkLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgd2hpbGUgKCBteSBAUm93ID0gJERCT2JqZWN0LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgICAgICAgICBwdXNoIEBEeW5hbWljRmllbGRVc2VyTG9naW5zLCAkUm93WzBdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgICAgICAgICBUeXBlICA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyU2VhcmNoRGV0YWlsRHluYW1pY0ZpZWxkcycsCiAgICAgICAgICAgICAgICAgICAgS2V5ICAgPT4gJFNRTER5bmFtaWNGaWVsZCwKICAgICAgICAgICAgICAgICAgICBWYWx1ZSA9PiBcQER5bmFtaWNGaWVsZFVzZXJMb2dpbnMsCiAgICAgICAgICAgICAgICAgICAgVFRMICAgPT4gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q2FjaGVUVEx9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBBZGQgdGhlIHVzZXIgbG9naW5zIGZyb20gdGhlIGR5bmFtaWMgZmllbGRzLCBpZiBhIHNlYXJjaCByZXN1bHQgZXhpc3RzIGZyb20gdGhlIGR5bmFtaWMgZmllbGQgc2VhcmNoCiAgICAgICAgIyAgIG9yIHNraXAgdGhlIHNlYXJjaCBhbmQgcmV0dXJuIGEgZW1wdHJ5IGFycmF5IHJlZiwgaWYgbm8gdXNlciBsb2dpbnMgZXhpc3RzIGZyb20gdGhlIGR5bmFtaWMgZmllbGQgc2VhcmNoLgogICAgICAgIGlmIChARHluYW1pY0ZpZWxkVXNlckxvZ2lucykgewoKICAgICAgICAgICAgbXkgJFNRTFF1ZXJ5SW5Db25kaXRpb24gPSAkREJPYmplY3QtPlF1ZXJ5SW5Db25kaXRpb24oCiAgICAgICAgICAgICAgICBLZXkgICAgICA9PiAkU2VsZi0+e0N1c3RvbWVyS2V5fSwKICAgICAgICAgICAgICAgIFZhbHVlcyAgID0+IFxARHluYW1pY0ZpZWxkVXNlckxvZ2lucywKICAgICAgICAgICAgICAgIEJpbmRNb2RlID0+IDAsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBwdXNoIEBTUUxXaGVyZSwgJFNRTFF1ZXJ5SW5Db25kaXRpb247CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICByZXR1cm4gJFJlc3VsdCBlcSAnQ09VTlQnID8gMCA6IFtdOwogICAgICAgIH0KICAgIH0KCiAgICBGSUVMRDoKICAgIGZvciBteSAkRmllbGQgKEBBcnJheVNlYXJjaEZpZWxkcykgewoKICAgICAgICBuZXh0IEZJRUxEIGlmICFAeyAkUGFyYW17ICRGaWVsZC0+e05hbWV9IH0gfTsKCiAgICAgICAgbXkgJFNRTFF1ZXJ5SW5Db25kaXRpb24gPSAkREJPYmplY3QtPlF1ZXJ5SW5Db25kaXRpb24oCiAgICAgICAgICAgIEtleSAgICAgID0+ICRGaWVsZC0+e0RhdGFiYXNlRmllbGR9LAogICAgICAgICAgICBWYWx1ZXMgICA9PiAkUGFyYW17ICRGaWVsZC0+e05hbWV9IH0sCiAgICAgICAgICAgIEJpbmRNb2RlID0+IDAsCiAgICAgICAgKTsKCiAgICAgICAgcHVzaCBAU1FMV2hlcmUsICRTUUxRdWVyeUluQ29uZGl0aW9uOwogICAgfQoKICAgICMgU3BlY2lhbCBwYXJhbWV0ZXIgZm9yIEN1c3RvbWVySURzIGZyb20gYSBjdXN0b21lciBjb21wYW55IHNlYXJjaCByZXN1bHQuCiAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSggJFBhcmFte0N1c3RvbWVyQ29tcGFueVNlYXJjaEN1c3RvbWVySURzfSApICkgewoKICAgICAgICBteSAkU1FMUXVlcnlJbkNvbmRpdGlvbiA9ICREQk9iamVjdC0+UXVlcnlJbkNvbmRpdGlvbigKICAgICAgICAgICAgS2V5ICAgICAgPT4gJFNlbGYtPntDdXN0b21lcklEfSwKICAgICAgICAgICAgVmFsdWVzICAgPT4gJFBhcmFte0N1c3RvbWVyQ29tcGFueVNlYXJjaEN1c3RvbWVySURzfSwKICAgICAgICAgICAgQmluZE1vZGUgPT4gMCwKICAgICAgICApOwoKICAgICAgICBwdXNoIEBTUUxXaGVyZSwgJFNRTFF1ZXJ5SW5Db25kaXRpb247CiAgICB9CgogICAgIyBTcGVjaWFsIHBhcmFtZXRlciB0byBleGNsdWRlIHNvbWUgdXNlciBsb2dpbnMgZnJvbSB0aGUgc2VhcmNoIHJlc3VsdC4KICAgIGlmICggSXNBcnJheVJlZldpdGhEYXRhKCAkUGFyYW17RXhjbHVkZVVzZXJMb2dpbnN9ICkgKSB7CgogICAgICAgIG15ICRTUUxRdWVyeUluQ29uZGl0aW9uID0gJERCT2JqZWN0LT5RdWVyeUluQ29uZGl0aW9uKAogICAgICAgICAgICBLZXkgICAgICA9PiAkU2VsZi0+e0N1c3RvbWVyS2V5fSwKICAgICAgICAgICAgVmFsdWVzICAgPT4gJFBhcmFte0V4Y2x1ZGVVc2VyTG9naW5zfSwKICAgICAgICAgICAgQmluZE1vZGUgPT4gMCwKICAgICAgICAgICAgTmVnYXRlICAgPT4gMSwKICAgICAgICApOwoKICAgICAgICBwdXNoIEBTUUxXaGVyZSwgJFNRTFF1ZXJ5SW5Db25kaXRpb247CiAgICB9CgogICAgIyBBZGQgdGhlIHZhbGlkIG9wdGlvbiBpZiBuZWVkZWQuCiAgICBpZiAoICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVmFsaWR9ICYmICRWYWxpZCApIHsKCiAgICAgICAgbXkgJFZhbGlkT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlZhbGlkJyk7CgogICAgICAgIHB1c2ggQFNRTFdoZXJlLAogICAgICAgICAgICAiJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJWYWxpZH0gSU4gKCIgLiBqb2luKCAnLCAnLCAkVmFsaWRPYmplY3QtPlZhbGlkSURzR2V0KCkgKSAuICIpICI7CiAgICB9CgogICAgIyBDaGVjayBpZiBPcmRlckJ5IGNvbnRhaW5zIG9ubHkgdW5pcXVlIHZhbGlkIHZhbHVlcy4KICAgIG15ICVPcmRlckJ5U2VlbjsKICAgIGZvciBteSAkT3JkZXJCeSAoIEB7ICRQYXJhbXtPcmRlckJ5fSB9ICkgewoKICAgICAgICBpZiAoICEkT3JkZXJCeSB8fCAkT3JkZXJCeVNlZW57JE9yZGVyQnl9ICkgewoKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk9yZGVyQnkgY29udGFpbnMgaW52YWxpZCB2YWx1ZSAnJE9yZGVyQnknIG9yIHRoZSB2YWx1ZSBpcyB1c2VkIG1vcmUgdGhhbiBvbmNlISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgUmVtZW1iZXIgdGhlIHZhbHVlIHRvIGNoZWNrIGlmIGl0IGFwcGVhcnMgbW9yZSB0aGFuIG9uY2UuCiAgICAgICAgJE9yZGVyQnlTZWVueyRPcmRlckJ5fSA9IDE7CiAgICB9CgogICAgIyBDaGVjayBpZiBPcmRlckJ5RGlyZWN0aW9uIGFycmF5IGNvbnRhaW5zIG9ubHkgJ1VwJyBvciAnRG93bicuCiAgICBESVJFQ1RJT046CiAgICBmb3IgbXkgJERpcmVjdGlvbiAoIEB7ICRQYXJhbXtPcmRlckJ5RGlyZWN0aW9ufSB9ICkgewoKICAgICAgICAjIE9ubHkgJ1VwJyBvciAnRG93bicgYWxsb3dlZC4KICAgICAgICBuZXh0IERJUkVDVElPTiBpZiAkRGlyZWN0aW9uIGVxICdVcCc7CiAgICAgICAgbmV4dCBESVJFQ1RJT04gaWYgJERpcmVjdGlvbiBlcSAnRG93bic7CgogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiT3JkZXJCeURpcmVjdGlvbiBjYW4gb25seSBjb250YWluICdVcCcgb3IgJ0Rvd24nISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBCdWlsZCB0aGUgc3FsIHN0YXRlbWVudCBmb3IgdGhlIHNlYXJjaC4KICAgIG15ICRTUUwgPSAiU0VMRUNUIERJU1RJTkNUKCRTZWxmLT57Q3VzdG9tZXJLZXl9KSI7CgogICAgIyBNb2RpZnkgU1FMIHdoZW4gdGhlIHJlc3VsdCB0eXBlIGlzICdDT1VOVCcuCiAgICBpZiAoICRSZXN1bHQgZXEgJ0NPVU5UJyApIHsKICAgICAgICAkU1FMID0gIlNFTEVDVCBDT1VOVChESVNUSU5DVCgkU2VsZi0+e0N1c3RvbWVyS2V5fSkpIjsKICAgIH0KCiAgICAjIEFzc2VtYmxlIHRoZSBPUkRFUiBCWSBjbGF1c2UuCiAgICBteSBAU1FMT3JkZXJCeTsKCiAgICAjIFRoZSBPcmRlciBieSBjbGF1c2UgaXMgbm90IG5lZWRlZCBmb3IgdGhlIHJlc3VsdCB0eXBlICdDT1VOVCcuCiAgICBpZiAoICRSZXN1bHQgbmUgJ0NPVU5UJyApIHsKCiAgICAgICAgbXkgJENvdW50ID0gMDsKCiAgICAgICAgT1JERVJCWToKICAgICAgICBmb3IgbXkgJE9yZGVyQnkgKCBAeyAkUGFyYW17T3JkZXJCeX0gfSApIHsKCiAgICAgICAgICAgIG15ICREaXJlY3Rpb24gPSAnREVTQyc7CgogICAgICAgICAgICBpZiAoICRQYXJhbXtPcmRlckJ5RGlyZWN0aW9ufS0+WyRDb3VudF0gKSB7CiAgICAgICAgICAgICAgICBpZiAoICRQYXJhbXtPcmRlckJ5RGlyZWN0aW9ufS0+WyRDb3VudF0gZXEgJ1VwJyApIHsKICAgICAgICAgICAgICAgICAgICAkRGlyZWN0aW9uID0gJ0FTQyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNpZiAoICRQYXJhbXtPcmRlckJ5RGlyZWN0aW9ufS0+WyRDb3VudF0gZXEgJ0Rvd24nICkgewogICAgICAgICAgICAgICAgICAgICREaXJlY3Rpb24gPSAnREVTQyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRDb3VudCsrOwoKICAgICAgICAgICAgbmV4dCBPUkRFUkJZIGlmICEkT3JkZXJCeVRhYmxleyRPcmRlckJ5fTsKCiAgICAgICAgICAgIHB1c2ggQFNRTE9yZGVyQnksICIkT3JkZXJCeVRhYmxleyRPcmRlckJ5fSAkRGlyZWN0aW9uIjsKCiAgICAgICAgICAgIG5leHQgT1JERVJCWSBpZiAkT3JkZXJCeSBlcSAnVXNlckxvZ2luJzsKCiAgICAgICAgICAgICRTUUwgLj0gIiwgJE9yZGVyQnlUYWJsZXskT3JkZXJCeX0iOwogICAgICAgIH0KCiAgICAgICAgIyBJZiB0aGVyZSBpcyBhIHBvc3NpYmlsaXR5IHRoYXQgdGhlIG9yZGVyaW5nIGlzIG5vdCBkZXRlcm1pbmVkCiAgICAgICAgIyAgIHdlIGFkZCBhbiBkZXNjZW5kaW5nIG9yZGVyaW5nIGJ5IGlkLgogICAgICAgIGlmICggIWdyZXAgeyAkXyBlcSAnVXNlckxvZ2luJyB9ICggQHsgJFBhcmFte09yZGVyQnl9IH0gKSApIHsKICAgICAgICAgICAgcHVzaCBAU1FMT3JkZXJCeSwgIiRTZWxmLT57Q3VzdG9tZXJLZXl9IERFU0MiOwogICAgICAgIH0KICAgIH0KCiAgICAkU1FMIC49ICIgRlJPTSAkU2VsZi0+e0N1c3RvbWVyVGFibGV9ICI7CgogICAgaWYgKEBTUUxXaGVyZSkgewogICAgICAgIG15ICRTUUxXaGVyZVN0cmluZyA9IGpvaW4gJyBBTkQgJywgbWFwIHsiKCAkXyApIn0gQFNRTFdoZXJlOwogICAgICAgICRTUUwgLj0gIldIRVJFICRTUUxXaGVyZVN0cmluZyAiOwogICAgfQogICAgaWYgKEBTUUxPcmRlckJ5KSB7CiAgICAgICAgbXkgJE9yZGVyQnlTdHJpbmcgPSBqb2luICcsICcsIEBTUUxPcmRlckJ5OwogICAgICAgICRTUUwgLj0gIk9SREVSIEJZICRPcmRlckJ5U3RyaW5nIjsKICAgIH0KCiAgICAjIENoZWNrIGlmIGEgY2FjaGUgZXhpc3RzIGJlZm9yZSB3ZSBhc2sgdGhlIGRhdGFiYXNlLgogICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKCiAgICAgICAgbXkgJENhY2hlRGF0YSA9ICRTZWxmLT57Q2FjaGVPYmplY3R9LT5HZXQoCiAgICAgICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lclNlYXJjaERldGFpbCcsCiAgICAgICAgICAgIEtleSAgPT4gJFNRTCAuICRQYXJhbXtMaW1pdH0sCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCBkZWZpbmVkICRDYWNoZURhdGEgKSB7CiAgICAgICAgICAgIGlmICggcmVmICRDYWNoZURhdGEgZXEgJ0FSUkFZJyApIHsKICAgICAgICAgICAgICAgIHJldHVybiAkQ2FjaGVEYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2lmICggcmVmICRDYWNoZURhdGEgZXEgJycgKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJENhY2hlRGF0YTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAnSW52YWxpZCByZWYgJyAuIHJlZigkQ2FjaGVEYXRhKSAuICchJwogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBpZiAhJERCT2JqZWN0LT5QcmVwYXJlKAogICAgICAgIFNRTCAgID0+ICRTUUwsCiAgICAgICAgTGltaXQgPT4gJFBhcmFte0xpbWl0fSwKICAgICk7CgogICAgbXkgQElEczsKICAgIHdoaWxlICggbXkgQFJvdyA9ICREQk9iamVjdC0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgIHB1c2ggQElEcywgJFJvd1swXTsKICAgIH0KCiAgICAjIEhhbmRsZSB0aGUgZGlmZnJlbnQgcmVzdWx0IHR5cGVzLgogICAgaWYgKCAkUmVzdWx0IGVxICdDT1VOVCcgKSB7CgogICAgICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgICAgICBUeXBlICA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyU2VhcmNoRGV0YWlsJywKICAgICAgICAgICAgICAgIEtleSAgID0+ICRTUUwgLiAkUGFyYW17TGltaXR9LAogICAgICAgICAgICAgICAgVmFsdWUgPT4gJElEc1swXSwKICAgICAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0NhY2hlVFRMfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAkSURzWzBdOwogICAgfQogICAgZWxzZSB7CgogICAgICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgICAgICBUeXBlICA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyU2VhcmNoRGV0YWlsJywKICAgICAgICAgICAgICAgIEtleSAgID0+ICRTUUwgLiAkUGFyYW17TGltaXR9LAogICAgICAgICAgICAgICAgVmFsdWUgPT4gXEBJRHMsCiAgICAgICAgICAgICAgICBUVEwgICA9PiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDYWNoZVRUTH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gXEBJRHM7CiAgICB9Cn0KCnN1YiBDdXN0b21lcklETGlzdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRWYWxpZCAgICAgID0gZGVmaW5lZCAkUGFyYW17VmFsaWR9ID8gJFBhcmFte1ZhbGlkfSA6IDE7CiAgICBteSAkU2VhcmNoVGVybSA9ICRQYXJhbXtTZWFyY2hUZXJtfSB8fCAnJzsKCiAgICBteSAkQ2FjaGVUeXBlID0gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lcklETGlzdCc7CiAgICBteSAkQ2FjaGVLZXkgID0gIkN1c3RvbWVySURMaXN0Ojoke1ZhbGlkfTo6JFNlYXJjaFRlcm0iOwoKICAgICMgY2hlY2sgY2FjaGUKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgbXkgJFJlc3VsdCA9ICRTZWxmLT57Q2FjaGVPYmplY3R9LT5HZXQoCiAgICAgICAgICAgIFR5cGUgPT4gJENhY2hlVHlwZSwKICAgICAgICAgICAgS2V5ICA9PiAkQ2FjaGVLZXksCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gQHskUmVzdWx0fSBpZiByZWYgJFJlc3VsdCBlcSAnQVJSQVknOwogICAgfQoKICAgIG15ICRTUUwgPSAiCiAgICAgICAgU0VMRUNUIERJU1RJTkNUKCRTZWxmLT57Q3VzdG9tZXJJRH0pCiAgICAgICAgRlJPTSAkU2VsZi0+e0N1c3RvbWVyVGFibGV9CiAgICAgICAgV0hFUkUgMSA9IDEgIjsKICAgIG15IEBCaW5kOwoKICAgICMgYWRkIHZhbGlkIG9wdGlvbgogICAgaWYgKCAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclZhbGlkfSAmJiAkVmFsaWQgKSB7CgogICAgICAgICMgZ2V0IHZhbGlkIG9iamVjdAogICAgICAgIG15ICRWYWxpZE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcpOwoKICAgICAgICBteSAkVmFsaWRJRHMgPSBqb2luKCAnLCAnLCAkVmFsaWRPYmplY3QtPlZhbGlkSURzR2V0KCkgKTsKICAgICAgICAkU1FMIC49ICIKICAgICAgICAgICAgQU5EICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVmFsaWR9IElOICgkVmFsaWRJRHMpICI7CiAgICB9CgogICAgIyBhZGQgc2VhcmNoIHRlcm0KICAgIGlmICgkU2VhcmNoVGVybSkgewogICAgICAgIG15ICRTZWFyY2hUZXJtRXNjYXBlZCA9ICRTZWxmLT57REJPYmplY3R9LT5RdWVyeVN0cmluZ0VzY2FwZSggUXVlcnlTdHJpbmcgPT4gJFNlYXJjaFRlcm0gKTsKCiAgICAgICAgJFNRTCAuPSAnIEFORCAnOwogICAgICAgIG15ICVRdWVyeUNvbmRpdGlvbiA9ICRTZWxmLT57REJPYmplY3R9LT5RdWVyeUNvbmRpdGlvbigKICAgICAgICAgICAgS2V5ICAgICAgICAgICA9PiAkU2VsZi0+e0N1c3RvbWVySUR9LAogICAgICAgICAgICBWYWx1ZSAgICAgICAgID0+ICRTZWFyY2hUZXJtRXNjYXBlZCwKICAgICAgICAgICAgU2VhcmNoUHJlZml4ICA9PiAkU2VsZi0+e1NlYXJjaFByZWZpeH0sCiAgICAgICAgICAgIFNlYXJjaFN1ZmZpeCAgPT4gJFNlbGYtPntTZWFyY2hTdWZmaXh9LAogICAgICAgICAgICBDYXNlU2Vuc2l0aXZlID0+ICRTZWxmLT57Q2FzZVNlbnNpdGl2ZX0sCiAgICAgICAgICAgIEJpbmRNb2RlICAgICAgPT4gMSwKICAgICAgICApOwogICAgICAgICRTUUwgLj0gJFF1ZXJ5Q29uZGl0aW9ue1NRTH07CiAgICAgICAgcHVzaCBAQmluZCwgQHsgJFF1ZXJ5Q29uZGl0aW9ue1ZhbHVlc30gfTsKCiAgICAgICAgJFNRTCAuPSAnICc7CiAgICB9CgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICBTUUwgID0+ICRTUUwsCiAgICAgICAgQmluZCA9PiBcQEJpbmQsCiAgICApOwoKICAgIG15IEBSZXN1bHQ7CgogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICBwdXNoIEBSZXN1bHQsICRSb3dbMF07CiAgICB9CgogICAgIyBjYWNoZSByZXF1ZXN0CiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgIFR5cGUgID0+ICRDYWNoZVR5cGUsCiAgICAgICAgICAgIEtleSAgID0+ICRDYWNoZUtleSwKICAgICAgICAgICAgVmFsdWUgPT4gXEBSZXN1bHQsCiAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0NhY2hlVFRMfSwKICAgICAgICApOwogICAgfQogICAgcmV0dXJuIEBSZXN1bHQ7Cn0KCnN1YiBDdXN0b21lcklEcyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VXNlcn0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXIhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY2hlY2sgY2FjaGUKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgbXkgJEN1c3RvbWVySURzID0gJFNlbGYtPntDYWNoZU9iamVjdH0tPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gIkN1c3RvbWVySURzOjokUGFyYW17VXNlcn0iLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIEB7JEN1c3RvbWVySURzfSBpZiByZWYgJEN1c3RvbWVySURzIGVxICdBUlJBWSc7CiAgICB9CgogICAgIyBnZXQgY3VzdG9tZXIgZGF0YQogICAgbXkgJURhdGEgPSAkU2VsZi0+Q3VzdG9tZXJVc2VyRGF0YUdldCgKICAgICAgICBVc2VyID0+ICRQYXJhbXtVc2VyfSwKICAgICk7CgogICAgIyB0aGVyZSBhcmUgbXVsdGkgY3VzdG9tZXIgaWRzCiAgICBteSBAQ3VzdG9tZXJJRHM7CiAgICBpZiAoICREYXRhe1VzZXJDdXN0b21lcklEc30gKSB7CgogICAgICAgICMgdXNlZCBzZXBhcmF0b3JzCiAgICAgICAgU0VQQVJBVE9SOgogICAgICAgIGZvciBteSAkU2VwYXJhdG9yICggJzsnLCAnLCcsICd8JyApIHsKCiAgICAgICAgICAgIG5leHQgU0VQQVJBVE9SIGlmICREYXRhe1VzZXJDdXN0b21lcklEc30gIX4gL1xRJFNlcGFyYXRvclxFLzsKCiAgICAgICAgICAgICMgc3BsaXQgaXQKICAgICAgICAgICAgbXkgQElEcyA9IHNwbGl0IC9cUSRTZXBhcmF0b3JcRS8sICREYXRhe1VzZXJDdXN0b21lcklEc307CgogICAgICAgICAgICBmb3IgbXkgJElEIChASURzKSB7CiAgICAgICAgICAgICAgICAkSUQgPX4gcy9eXHMrLy9nOwogICAgICAgICAgICAgICAgJElEID1+IHMvXHMrJC8vZzsKICAgICAgICAgICAgICAgIHB1c2ggQEN1c3RvbWVySURzLCAkSUQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxhc3QgU0VQQVJBVE9SOwogICAgICAgIH0KCiAgICAgICAgIyBmYWxsYmFjayBpZiBubyBzZXBhcmF0b3IgZ290IGZvdW5kCiAgICAgICAgaWYgKCAhQEN1c3RvbWVySURzICkgewogICAgICAgICAgICAkRGF0YXtVc2VyQ3VzdG9tZXJJRHN9ID1+IHMvXlxzKy8vZzsKICAgICAgICAgICAgJERhdGF7VXNlckN1c3RvbWVySURzfSA9fiBzL1xzKyQvL2c7CiAgICAgICAgICAgIHB1c2ggQEN1c3RvbWVySURzLCAkRGF0YXtVc2VyQ3VzdG9tZXJJRHN9OwogICAgICAgIH0KICAgIH0KCiAgICAjIHVzZSBhbHNvIHRoZSBwcmltYXJ5IGN1c3RvbWVyIGlkCiAgICBpZiAoICREYXRhe1VzZXJDdXN0b21lcklEfSAmJiAhJFNlbGYtPntFeGNsdWRlUHJpbWFyeUN1c3RvbWVySUR9ICkgewogICAgICAgIHB1c2ggQEN1c3RvbWVySURzLCAkRGF0YXtVc2VyQ3VzdG9tZXJJRH07CiAgICB9CgogICAgIyBjYWNoZSByZXF1ZXN0CiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICAgICAgS2V5ICAgPT4gJ0N1c3RvbWVySURzOjonIC4gJFBhcmFte1VzZXJ9LAogICAgICAgICAgICBWYWx1ZSA9PiBcQEN1c3RvbWVySURzLAogICAgICAgICAgICBUVEwgICA9PiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDYWNoZVRUTH0sCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gQEN1c3RvbWVySURzOwp9CgpzdWIgQ3VzdG9tZXJVc2VyRGF0YUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VXNlcn0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXIhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGJ1aWxkIHNlbGVjdAogICAgbXkgJFNRTCA9ICdTRUxFQ1QgJzsKICAgIEVOVFJZOgogICAgZm9yIG15ICRFbnRyeSAoIEB7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e01hcH0gfSApIHsKCiAgICAgICAgbmV4dCBFTlRSWSBpZiAkRW50cnktPls1XSBlcSAnZHluYW1pY19maWVsZCc7CgogICAgICAgICRTUUwgLj0gIiAkRW50cnktPlsyXSwgIjsKICAgIH0KCiAgICBpZiAoICEkU2VsZi0+e0ZvcmVpZ25EQn0gKSB7CiAgICAgICAgJFNRTCAuPSAiY3JlYXRlX3RpbWUsIGNyZWF0ZV9ieSwgY2hhbmdlX3RpbWUsIGNoYW5nZV9ieSwgIjsKICAgIH0KCiAgICAkU1FMIC49ICRTZWxmLT57Q3VzdG9tZXJLZXl9IC4gIiBGUk9NICRTZWxmLT57Q3VzdG9tZXJUYWJsZX0gV0hFUkUgIjsKCiAgICAjIGNoZWNrIGNhY2hlCiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgIG15ICREYXRhID0gJFNlbGYtPntDYWNoZU9iamVjdH0tPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gIkN1c3RvbWVyVXNlckRhdGFHZXQ6OiRQYXJhbXtVc2VyfSIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gJXskRGF0YX0gaWYgcmVmICREYXRhIGVxICdIQVNIJzsKICAgIH0KCiAgICAjIGNoZWNrIGN1c3RvbWVyIGtleSB0eXBlCiAgICBteSAkVXNlciA9ICRQYXJhbXtVc2VyfTsKCiAgICBpZiAoICRTZWxmLT57Q2FzZVNlbnNpdGl2ZX0gKSB7CiAgICAgICAgJFNRTCAuPSAiJFNlbGYtPntDdXN0b21lcktleX0gPSA/IjsKICAgIH0KICAgIGVsc2UgewogICAgICAgICRTUUwgLj0gIkxPV0VSKCRTZWxmLT57Q3VzdG9tZXJLZXl9KSA9IExPV0VSKD8pIjsKICAgIH0KCiAgICAjIGFzayB0aGUgZGF0YWJhc2UKICAgIHJldHVybiBpZiAhJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMICAgPT4gJFNRTCwKICAgICAgICBCaW5kICA9PiBbIFwkVXNlciBdLAogICAgICAgIExpbWl0ID0+IDEsCiAgICApOwoKICAgICMgZmV0Y2ggdGhlIHJlc3VsdAogICAgbXkgJURhdGE7CiAgICBST1c6CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewoKICAgICAgICBteSAkTWFwQ291bnRlciA9IDA7CgogICAgICAgIEVOVFJZOgogICAgICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9IH0gKSB7CgogICAgICAgICAgICBuZXh0IEVOVFJZIGlmICRFbnRyeS0+WzVdIGVxICdkeW5hbWljX2ZpZWxkJzsKCiAgICAgICAgICAgICREYXRheyAkRW50cnktPlswXSB9ID0gJFJvd1skTWFwQ291bnRlcl07CiAgICAgICAgICAgICRNYXBDb3VudGVyKys7CiAgICAgICAgfQoKICAgICAgICBuZXh0IFJPVyBpZiAkU2VsZi0+e0ZvcmVpZ25EQn07CgogICAgICAgIGZvciBteSAkS2V5IChxdyhDcmVhdGVUaW1lIENyZWF0ZUJ5IENoYW5nZVRpbWUgQ2hhbmdlQnkpKSB7CiAgICAgICAgICAgICREYXRheyRLZXl9ID0gJFJvd1skTWFwQ291bnRlcl07CiAgICAgICAgICAgICRNYXBDb3VudGVyKys7CiAgICAgICAgfQogICAgfQoKICAgICMgY2hlY2sgZGF0YQogICAgaWYgKCAhJERhdGF7VXNlckxvZ2lufSApIHsKCiAgICAgICAgIyBjYWNoZSByZXF1ZXN0CiAgICAgICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICAgICAgICAgIEtleSAgID0+ICJDdXN0b21lclVzZXJEYXRhR2V0OjokUGFyYW17VXNlcn0iLAogICAgICAgICAgICAgICAgVmFsdWUgPT4ge30sCiAgICAgICAgICAgICAgICBUVEwgICA9PiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDYWNoZVRUTH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBteSAkQ3VzdG9tZXJVc2VyTGlzdEZpZWxkc01hcCA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlckxpc3RGaWVsZHN9OwogICAgaWYgKCAhSXNBcnJheVJlZldpdGhEYXRhKCRDdXN0b21lclVzZXJMaXN0RmllbGRzTWFwKSApIHsKICAgICAgICAkQ3VzdG9tZXJVc2VyTGlzdEZpZWxkc01hcCA9IFsgJ2ZpcnN0X25hbWUnLCAnbGFzdF9uYW1lJywgJ2VtYWlsJywgXTsKICAgIH0KCiAgICAjIE9yZGVyIGZpZWxkcyBieSBDdXN0b21lclVzZXJMaXN0RmllbGRzIChzZWUgYnVnIzEzODIxKS4KICAgIG15IEBDdXN0b21lclVzZXJMaXN0RmllbGRzOwogICAgZm9yIG15ICRGaWVsZCAoIEB7JEN1c3RvbWVyVXNlckxpc3RGaWVsZHNNYXB9ICkgewogICAgICAgIG15IEBGaWVsZE5hbWVzID0gbWFwIHsgJF8tPlswXSB9IGdyZXAgeyAkXy0+WzJdIGVxICRGaWVsZCB9IEB7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e01hcH0gfTsKICAgICAgICBwdXNoIEBDdXN0b21lclVzZXJMaXN0RmllbGRzLCAkRmllbGROYW1lc1swXTsKICAgIH0KCiAgICBteSAkVXNlck1haWxTdHJpbmcgPSAnJzsKICAgIG15IEBVc2VyTWFpbFN0cmluZ1BhcnRzOwoKICAgIEZJRUxEOgogICAgZm9yIG15ICRGaWVsZCAoQEN1c3RvbWVyVXNlckxpc3RGaWVsZHMpIHsKICAgICAgICBuZXh0IEZJRUxEIGlmICEkRGF0YXskRmllbGR9OwoKICAgICAgICBwdXNoIEBVc2VyTWFpbFN0cmluZ1BhcnRzLCAkRGF0YXskRmllbGR9OwogICAgfQogICAgJFVzZXJNYWlsU3RyaW5nID0gam9pbiAnICcsIEBVc2VyTWFpbFN0cmluZ1BhcnRzOwogICAgJFVzZXJNYWlsU3RyaW5nID1+IHMvXiguKilccyguKz9cQC4rP1wuLis/KShcc3wpJC8iJDEiIDwkMj4vOwoKICAgICMgYWRkIHRoZSBVc2VyTWFpbFN0cmluZyB0byB0aGUgZGF0YSBoYXNoCiAgICAkRGF0YXtVc2VyTWFpbFN0cmluZ30gPSAkVXNlck1haWxTdHJpbmc7CgogICAgIyBjb21wYXQhCiAgICAkRGF0YXtVc2VySUR9ID0gJERhdGF7VXNlckxvZ2lufTsKCiAgICAjIGdldCBwcmVmZXJlbmNlcwogICAgbXkgJVByZWZlcmVuY2VzID0gJFNlbGYtPkdldFByZWZlcmVuY2VzKCBVc2VySUQgPT4gJERhdGF7VXNlcklEfSApOwoKICAgICMgYWRkIGxhc3QgbG9naW4gdGltZXN0YW1wCiAgICBpZiAoICRQcmVmZXJlbmNlc3tVc2VyTGFzdExvZ2lufSApIHsKCiAgICAgICAgbXkgJERhdGVUaW1lT2JqZWN0ID0gJEtlcm5lbDo6T00tPkNyZWF0ZSgKICAgICAgICAgICAgJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScsCiAgICAgICAgICAgIE9iamVjdFBhcmFtcyA9PiB7CiAgICAgICAgICAgICAgICBFcG9jaCA9PiAkUHJlZmVyZW5jZXN7VXNlckxhc3RMb2dpbn0sCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKCiAgICAgICAgJFByZWZlcmVuY2Vze1VzZXJMYXN0TG9naW5UaW1lc3RhbXB9ID0gJERhdGVUaW1lT2JqZWN0LT5Ub1N0cmluZygpOwoKICAgIH0KCiAgICAjIGNhY2hlIHJlcXVlc3QKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgVHlwZSAgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgICAgICBLZXkgICA9PiAiQ3VzdG9tZXJVc2VyRGF0YUdldDo6JFBhcmFte1VzZXJ9IiwKICAgICAgICAgICAgVmFsdWUgPT4geyAlRGF0YSwgJVByZWZlcmVuY2VzIH0sCiAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0NhY2hlVFRMfSwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAoICVEYXRhLCAlUHJlZmVyZW5jZXMgKTsKfQoKc3ViIEN1c3RvbWVyVXNlckFkZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgcm8vcncKICAgIGlmICggJFNlbGYtPntSZWFkT25seX0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdDdXN0b21lciBiYWNrZW5kIGlzIHJlYWQgb25seSEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBFTlRSWToKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9IH0gKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyAkRW50cnktPlswXSB9ICYmICRFbnRyeS0+WzRdICkgewoKICAgICAgICAgICAgIyBza2lwIFVzZXJMb2dpbiwgd2lsbCBiZSBjaGVja2VkIGxhdGVyCiAgICAgICAgICAgIG5leHQgRU5UUlkgaWYgKCAkRW50cnktPlswXSBlcSAnVXNlckxvZ2luJyApOwoKICAgICAgICAgICAgIyBpZ25vcmUgZHluYW1pYyBmaWVsZHMgaGVyZQogICAgICAgICAgICBuZXh0IEVOVFJZIGlmICRFbnRyeS0+WzVdIGVxICdkeW5hbWljX2ZpZWxkJzsKCiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRFbnRyeS0+WzBdISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICBpZiAoICEkUGFyYW17VXNlcklEfSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgVXNlcklEIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBpZiBubyBVc2VyTG9naW4gaXMgZ2l2ZW4KICAgIGlmICggISRQYXJhbXtVc2VyTG9naW59ICYmICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0F1dG9Mb2dpbkNyZWF0aW9ufSApIHsKCiAgICAgICAgIyBnZXQgdGltZSBvYmplY3QKICAgICAgICBteSAkRGF0ZVRpbWVPYmplY3QgPSAkS2VybmVsOjpPTS0+Q3JlYXRlKCdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnKTsKICAgICAgICBteSAkRGF0ZVRpbWVTdHJpbmcgPSAkRGF0ZVRpbWVPYmplY3QtPkZvcm1hdCggRm9ybWF0ID0+ICclWSVtJWQlSCVNJyApOwoKICAgICAgICBteSAkUHJlZml4ID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57QXV0b0xvZ2luQ3JlYXRpb25QcmVmaXh9IHx8ICdhdXRvJzsKICAgICAgICAkUGFyYW17VXNlckxvZ2lufSA9ICIkUHJlZml4LSREYXRlVGltZVN0cmluZyIgLiBpbnQoIHJhbmQoOTkpICk7CiAgICB9CgogICAgIyBjaGVjayBpZiB1c2VyIGxvZ2luIGV4aXN0cwogICAgaWYgKCAhJFBhcmFte1VzZXJMb2dpbn0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXJMb2dpbiEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY2hlY2sgZW1haWwgYWRkcmVzcyBpZiBhbHJlYWR5IGV4aXN0cwogICAgaWYgKCAkUGFyYW17VXNlckVtYWlsfSAmJiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJFbWFpbFVuaXFDaGVja30gKSB7CiAgICAgICAgbXkgJVJlc3VsdCA9ICRTZWxmLT5DdXN0b21lclNlYXJjaCgKICAgICAgICAgICAgVmFsaWQgICAgICAgICAgICA9PiAwLAogICAgICAgICAgICBQb3N0TWFzdGVyU2VhcmNoID0+ICRQYXJhbXtVc2VyRW1haWx9LAogICAgICAgICk7CiAgICAgICAgaWYgKCVSZXN1bHQpIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpMYW5ndWFnZScpCiAgICAgICAgICAgICAgICAgICAgLT5UcmFuc2xhdGUoJ1RoaXMgZW1haWwgYWRkcmVzcyBpcyBhbHJlYWR5IGluIHVzZSBmb3IgYW5vdGhlciBjdXN0b21lciB1c2VyLicpLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgZ2V0IGNoZWNrIGl0ZW0gb2JqZWN0CiAgICBteSAkQ2hlY2tJdGVtT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNoZWNrSXRlbScpOwoKICAgICMgY2hlY2sgZW1haWwgYWRkcmVzcyBteAogICAgaWYgKAogICAgICAgICRQYXJhbXtVc2VyRW1haWx9CiAgICAgICAgJiYgISRDaGVja0l0ZW1PYmplY3QtPkNoZWNrRW1haWwoIEFkZHJlc3MgPT4gJFBhcmFte1VzZXJFbWFpbH0gKQogICAgICAgICYmIGdyZXAgeyAkXyBlcSAkUGFyYW17VmFsaWRJRH0gfSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6VmFsaWQnKS0+VmFsaWRJRHNHZXQoKQogICAgICAgICkKICAgIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIkVtYWlsIGFkZHJlc3MgKCRQYXJhbXtVc2VyRW1haWx9KSBub3QgdmFsaWQgKCIKICAgICAgICAgICAgICAgIC4gJENoZWNrSXRlbU9iamVjdC0+Q2hlY2tFcnJvcigpIC4gIikhIiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIHF1b3RlIHZhbHVlcwogICAgbXkgJVZhbHVlOwogICAgZm9yIG15ICRFbnRyeSAoIEB7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e01hcH0gfSApIHsKICAgICAgICBpZiAoICRFbnRyeS0+WzVdID1+IC9eaW50JC9pICkgewogICAgICAgICAgICBpZiAoICRQYXJhbXsgJEVudHJ5LT5bMF0gfSApIHsKICAgICAgICAgICAgICAgICRWYWx1ZXsgJEVudHJ5LT5bMF0gfSA9ICRQYXJhbXsgJEVudHJ5LT5bMF0gfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRWYWx1ZXsgJEVudHJ5LT5bMF0gfSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGlmICggJFBhcmFteyAkRW50cnktPlswXSB9ICkgewogICAgICAgICAgICAgICAgJFZhbHVleyAkRW50cnktPlswXSB9ID0gJFBhcmFteyAkRW50cnktPlswXSB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJFZhbHVleyAkRW50cnktPlswXSB9ID0gJyc7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgIyBidWlsZCBpbnNlcnQKICAgIG15ICRTUUwgPSAiSU5TRVJUIElOVE8gJFNlbGYtPntDdXN0b21lclRhYmxlfSAoIjsKICAgIG15IEBCaW5kOwogICAgbXkgJVNlZW5LZXk7ICAgICMgSWYgdGhlIG1hcCBjb250YWlucyBkdXBsaWNhdGVkIGZpZWxkIG5hbWVzLCBpbnNlcnQgb25seSBvbmNlLgogICAgbXkgQENvbHVtbk5hbWVzOwoKICAgIE1BUEVOVFJZOgogICAgZm9yIG15ICRFbnRyeSAoIEB7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e01hcH0gfSApIHsKICAgICAgICBuZXh0IE1BUEVOVFJZIGlmICRFbnRyeS0+WzVdIGVxICdkeW5hbWljX2ZpZWxkJzsgICAgICAgICAgICAjIHNraXAgZHluYW1pYyBmaWVsZHMKICAgICAgICBuZXh0IE1BUEVOVFJZIGlmICggbGMoICRFbnRyeS0+WzBdICkgZXEgInVzZXJwYXNzd29yZCIgKTsKICAgICAgICBuZXh0IE1BUEVOVFJZIGlmICRTZWVuS2V5eyAkRW50cnktPlsyXSB9Kys7CiAgICAgICAgcHVzaCBAQ29sdW1uTmFtZXMsICRFbnRyeS0+WzJdOwogICAgfQoKICAgICRTUUwgLj0gam9pbiAnLCAnLCBAQ29sdW1uTmFtZXM7CgogICAgaWYgKCAhJFNlbGYtPntGb3JlaWduREJ9ICkgewogICAgICAgICRTUUwgLj0gJywgY3JlYXRlX3RpbWUsIGNyZWF0ZV9ieSwgY2hhbmdlX3RpbWUsIGNoYW5nZV9ieSc7CiAgICB9CgogICAgJFNRTCAuPSAnKSBWQUxVRVMgKCc7CgogICAgbXkgJVNlZW5WYWx1ZTsKICAgIG15ICRCaW5kQ29sdW1ucyA9IDA7CgogICAgRU5UUlk6CiAgICBmb3IgbXkgJEVudHJ5ICggQHsgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57TWFwfSB9ICkgewogICAgICAgIG5leHQgRU5UUlkgaWYgJEVudHJ5LT5bNV0gZXEgJ2R5bmFtaWNfZmllbGQnOyAgICAgICAgICAgICMgc2tpcCBkeW5hbWljIGZpZWxkcwogICAgICAgIG5leHQgRU5UUlkgaWYgKCBsYyggJEVudHJ5LT5bMF0gKSBlcSAidXNlcnBhc3N3b3JkIiApOwogICAgICAgIG5leHQgRU5UUlkgaWYgJFNlZW5WYWx1ZXsgJEVudHJ5LT5bMl0gfSsrOwogICAgICAgICRCaW5kQ29sdW1ucysrOwogICAgICAgIHB1c2ggQEJpbmQsIFwkVmFsdWV7ICRFbnRyeS0+WzBdIH07CiAgICB9CgogICAgJFNRTCAuPSBqb2luICcsICcsICgnPycpIHggJEJpbmRDb2x1bW5zOwoKICAgIGlmICggISRTZWxmLT57Rm9yZWlnbkRCfSApIHsKICAgICAgICAkU1FMIC49ICcsIGN1cnJlbnRfdGltZXN0YW1wLCA/LCBjdXJyZW50X3RpbWVzdGFtcCwgPyc7CiAgICAgICAgcHVzaCBAQmluZCwgXCRQYXJhbXtVc2VySUR9OwogICAgICAgIHB1c2ggQEJpbmQsIFwkUGFyYW17VXNlcklEfTsKICAgIH0KCiAgICAkU1FMIC49ICcpJzsKCiAgICByZXR1cm4gaWYgISRTZWxmLT57REJPYmplY3R9LT5EbygKICAgICAgICBTUUwgID0+ICRTUUwsCiAgICAgICAgQmluZCA9PiBcQEJpbmQKICAgICk7CgogICAgIyBsb2cgbm90aWNlCiAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICBQcmlvcml0eSA9PiAnaW5mbycsCiAgICAgICAgTWVzc2FnZSAgPT4gIkN1c3RvbWVyVXNlcjogJyRQYXJhbXtVc2VyTG9naW59JyBjcmVhdGVkIHN1Y2Nlc3NmdWxseSAoJFBhcmFte1VzZXJJRH0pISIsCiAgICApOwoKICAgICMgc2V0IHBhc3N3b3JkCiAgICBpZiAoICRQYXJhbXtVc2VyUGFzc3dvcmR9ICkgewogICAgICAgICRTZWxmLT5TZXRQYXNzd29yZCgKICAgICAgICAgICAgVXNlckxvZ2luID0+ICRQYXJhbXtVc2VyTG9naW59LAogICAgICAgICAgICBQVyAgICAgICAgPT4gJFBhcmFte1VzZXJQYXNzd29yZH0KICAgICAgICApOwogICAgfQoKICAgICRTZWxmLT5fQ3VzdG9tZXJVc2VyQ2FjaGVDbGVhciggVXNlckxvZ2luID0+ICRQYXJhbXtVc2VyTG9naW59ICk7CgogICAgcmV0dXJuICRQYXJhbXtVc2VyTG9naW59Owp9CgpzdWIgQ3VzdG9tZXJVc2VyVXBkYXRlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayByby9ydwogICAgaWYgKCAkU2VsZi0+e1JlYWRPbmx5fSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0N1c3RvbWVyIGJhY2tlbmQgaXMgcmVhZCBvbmx5IScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9IH0gKSB7CiAgICAgICAgaWYgKAogICAgICAgICAgICAhJFBhcmFteyAkRW50cnktPlswXSB9CiAgICAgICAgICAgICYmICRFbnRyeS0+WzVdIG5lICdkeW5hbWljX2ZpZWxkJyAgICAjIGlnbm9yZSBkeW5hbWljIGZpZWxkcyBoZXJlCiAgICAgICAgICAgICYmICRFbnRyeS0+WzRdICAgICAgICAgICAgICAgICAgICAgICAjIG9ubHkgY2hlY2sgcmVxdWlyZWQgZmllbGRzCiAgICAgICAgICAgICYmICRFbnRyeS0+WzBdIG5lICdVc2VyUGFzc3dvcmQnICAgICAjIGlnbm9yZSBVc2VyUGFzc3dvcmQgZmllbGQKICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEVudHJ5LT5bMF0hIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGdldCBjaGVjayBpdGVtIG9iamVjdAogICAgbXkgJENoZWNrSXRlbU9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDaGVja0l0ZW0nKTsKCiAgICAjIGNoZWNrIGVtYWlsIGFkZHJlc3MKICAgIGlmICgKICAgICAgICAkUGFyYW17VXNlckVtYWlsfQogICAgICAgICYmICEkQ2hlY2tJdGVtT2JqZWN0LT5DaGVja0VtYWlsKCBBZGRyZXNzID0+ICRQYXJhbXtVc2VyRW1haWx9ICkKICAgICAgICAmJiBncmVwIHsgJF8gZXEgJFBhcmFte1ZhbGlkSUR9IH0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlZhbGlkJyktPlZhbGlkSURzR2V0KCkKICAgICAgICApCiAgICB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJFbWFpbCBhZGRyZXNzICgkUGFyYW17VXNlckVtYWlsfSkgbm90IHZhbGlkICgiCiAgICAgICAgICAgICAgICAuICRDaGVja0l0ZW1PYmplY3QtPkNoZWNrRXJyb3IoKSAuICIpISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgb2xkIHVzZXIgZGF0YSAocHcpCiAgICBteSAlVXNlckRhdGEgPSAkU2VsZi0+Q3VzdG9tZXJVc2VyRGF0YUdldCggVXNlciA9PiAkUGFyYW17SUR9ICk7CgogICAgIyBpZiB3ZSB1cGRhdGUgdGhlIGVtYWlsIGFkZHJlc3MsIGNoZWNrIGlmIGl0IGFscmVhZHkgZXhpc3RzCiAgICBpZiAoCiAgICAgICAgJFBhcmFte1VzZXJFbWFpbH0KICAgICAgICAmJiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJFbWFpbFVuaXFDaGVja30KICAgICAgICAmJiBsYyAkUGFyYW17VXNlckVtYWlsfSBuZSBsYyAkVXNlckRhdGF7VXNlckVtYWlsfQogICAgICAgICkKICAgIHsKICAgICAgICBteSAlUmVzdWx0ID0gJFNlbGYtPkN1c3RvbWVyU2VhcmNoKAogICAgICAgICAgICBWYWxpZCAgICAgICAgICAgID0+IDAsCiAgICAgICAgICAgIFBvc3RNYXN0ZXJTZWFyY2ggPT4gJFBhcmFte1VzZXJFbWFpbH0sCiAgICAgICAgKTsKICAgICAgICBpZiAoJVJlc3VsdCkgewogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Okxhbmd1YWdlJykKICAgICAgICAgICAgICAgICAgICAtPlRyYW5zbGF0ZSgnVGhpcyBlbWFpbCBhZGRyZXNzIGlzIGFscmVhZHkgaW4gdXNlIGZvciBhbm90aGVyIGN1c3RvbWVyIHVzZXIuJyksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBxdW90ZSB2YWx1ZXMKICAgIG15ICVWYWx1ZTsKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9IH0gKSB7CiAgICAgICAgaWYgKCAkRW50cnktPls1XSA9fiAvXmludCQvaSApIHsKICAgICAgICAgICAgaWYgKCAkUGFyYW17ICRFbnRyeS0+WzBdIH0gKSB7CiAgICAgICAgICAgICAgICAkVmFsdWV7ICRFbnRyeS0+WzBdIH0gPSAkUGFyYW17ICRFbnRyeS0+WzBdIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkVmFsdWV7ICRFbnRyeS0+WzBdIH0gPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBpZiAoICRQYXJhbXsgJEVudHJ5LT5bMF0gfSApIHsKICAgICAgICAgICAgICAgICRWYWx1ZXsgJEVudHJ5LT5bMF0gfSA9ICRQYXJhbXsgJEVudHJ5LT5bMF0gfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRWYWx1ZXsgJEVudHJ5LT5bMF0gfSA9ICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICMgdXBkYXRlIGRiCiAgICBteSAkU1FMID0gIlVQREFURSAkU2VsZi0+e0N1c3RvbWVyVGFibGV9IFNFVCAiOwogICAgbXkgQEJpbmQ7CgogICAgbXkgJVNlZW5LZXk7ICAgICMgSWYgdGhlIG1hcCBjb250YWlucyBkdXBsaWNhdGVkIGZpZWxkIG5hbWVzLCBpbnNlcnQgb25seSBvbmNlLgogICAgRU5UUlk6CiAgICBmb3IgbXkgJEVudHJ5ICggQHsgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57TWFwfSB9ICkgewogICAgICAgIG5leHQgRU5UUlkgaWYgJEVudHJ5LT5bNV0gZXEgJ2R5bmFtaWNfZmllbGQnOyAgICAgICAgICAgICMgc2tpcCBkeW5hbWljIGZpZWxkcwogICAgICAgIG5leHQgRU5UUlkgaWYgJEVudHJ5LT5bN107ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2tpcCByZWFkb25seSBmaWVsZHMKICAgICAgICBuZXh0IEVOVFJZIGlmICggbGMoICRFbnRyeS0+WzBdICkgZXEgInVzZXJwYXNzd29yZCIgKTsKICAgICAgICBuZXh0IEVOVFJZIGlmICRTZWVuS2V5eyAkRW50cnktPlsyXSB9Kys7CiAgICAgICAgJFNRTCAuPSAiICRFbnRyeS0+WzJdID0gPywgIjsKICAgICAgICBwdXNoIEBCaW5kLCBcJFZhbHVleyAkRW50cnktPlswXSB9OwogICAgfQoKICAgIGlmICggISRTZWxmLT57Rm9yZWlnbkRCfSApIHsKICAgICAgICAkU1FMIC49ICdjaGFuZ2VfdGltZSA9IGN1cnJlbnRfdGltZXN0YW1wLCBjaGFuZ2VfYnkgPSA/JzsKICAgICAgICBwdXNoIEBCaW5kLCBcJFBhcmFte1VzZXJJRH07CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBjaG9wICRTUUw7CiAgICAgICAgY2hvcCAkU1FMOwogICAgfQoKICAgICRTUUwgLj0gJyBXSEVSRSAnOwoKICAgIGlmICggJFNlbGYtPntDYXNlU2Vuc2l0aXZlfSApIHsKICAgICAgICAkU1FMIC49ICIkU2VsZi0+e0N1c3RvbWVyS2V5fSA9ID8iOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgJFNRTCAuPSAiTE9XRVIoJFNlbGYtPntDdXN0b21lcktleX0pID0gTE9XRVIoPykiOwogICAgfQogICAgcHVzaCBAQmluZCwgXCRQYXJhbXtJRH07CgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgU1FMICA9PiAkU1FMLAogICAgICAgIEJpbmQgPT4gXEBCaW5kCiAgICApOwoKICAgICMgY2hlY2sgaWYgd2UgbmVlZCB0byB1cGRhdGUgQ3VzdG9tZXIgUHJlZmVyZW5jZXMKICAgIGlmICggJFBhcmFte1VzZXJMb2dpbn0gbmUgJFVzZXJEYXRhe1VzZXJMb2dpbn0gKSB7CgogICAgICAgICMgdXBkYXRlIHRoZSBwcmVmZXJlbmNlcwogICAgICAgICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9LT5SZW5hbWVQcmVmZXJlbmNlcygKICAgICAgICAgICAgTmV3VXNlcklEID0+ICRQYXJhbXtVc2VyTG9naW59LAogICAgICAgICAgICBPbGRVc2VySUQgPT4gJFVzZXJEYXRhe1VzZXJMb2dpbn0sCiAgICAgICAgKTsKICAgIH0KCiAgICAjIGxvZyBub3RpY2UKICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgIFByaW9yaXR5ID0+ICdpbmZvJywKICAgICAgICBNZXNzYWdlICA9PiAiQ3VzdG9tZXJVc2VyOiAnJFBhcmFte1VzZXJMb2dpbn0nIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5ICgkUGFyYW17VXNlcklEfSkhIiwKICAgICk7CgogICAgIyBjaGVjayBwdwogICAgaWYgKCAkUGFyYW17VXNlclBhc3N3b3JkfSApIHsKICAgICAgICAkU2VsZi0+U2V0UGFzc3dvcmQoCiAgICAgICAgICAgIFVzZXJMb2dpbiA9PiAkUGFyYW17VXNlckxvZ2lufSwKICAgICAgICAgICAgUFcgICAgICAgID0+ICRQYXJhbXtVc2VyUGFzc3dvcmR9CiAgICAgICAgKTsKICAgIH0KCiAgICAkU2VsZi0+X0N1c3RvbWVyVXNlckNhY2hlQ2xlYXIoIFVzZXJMb2dpbiA9PiAkUGFyYW17VXNlckxvZ2lufSApOwogICAgaWYgKCAkUGFyYW17VXNlckxvZ2lufSBuZSAkVXNlckRhdGF7VXNlckxvZ2lufSApIHsKICAgICAgICAkU2VsZi0+X0N1c3RvbWVyVXNlckNhY2hlQ2xlYXIoIFVzZXJMb2dpbiA9PiAkVXNlckRhdGF7VXNlckxvZ2lufSApOwogICAgfQoKICAgIHJldHVybiAxOwp9CgpzdWIgU2V0UGFzc3dvcmQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkTG9naW4gPSAkUGFyYW17VXNlckxvZ2lufTsKICAgIG15ICRQdyAgICA9ICRQYXJhbXtQV30gfHwgJyc7CgogICAgIyBjaGVjayByby9ydwogICAgaWYgKCAkU2VsZi0+e1JlYWRPbmx5fSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0N1c3RvbWVyIGJhY2tlbmQgaXMgcmVhZCBvbmx5IScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtVc2VyTG9naW59ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBVc2VyTG9naW4hJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIG15ICRDcnlwdGVkUHcgPSAnJzsKCiAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICBteSAkQ3J5cHRUeXBlID0gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lcjo6QXV0aE1vZHVsZTo6REI6OkNyeXB0VHlwZScpIHx8ICdzaGEyJzsKCiAgICAjIGdldCBlbmNvZGUgb2JqZWN0CiAgICBteSAkRW5jb2RlT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkVuY29kZScpOwoKICAgICMgY3J5cHQgcGxhaW4gKG5vIGNyeXB0IGF0IGFsbCkKICAgIGlmICggJENyeXB0VHlwZSBlcSAncGxhaW4nICkgewogICAgICAgICRDcnlwdGVkUHcgPSAkUHc7CiAgICB9CgogICAgIyBjcnlwdCB3aXRoIHVuaXggY3J5cHQKICAgIGVsc2lmICggJENyeXB0VHlwZSBlcSAnY3J5cHQnICkgewoKICAgICAgICAjIGVuY29kZSBvdXRwdXQsIG5lZWRlZCBieSBjcnlwdCgpIG9ubHkgbm9uIHV0Zjggc2lnbnMKICAgICAgICAkRW5jb2RlT2JqZWN0LT5FbmNvZGVPdXRwdXQoIFwkUHcgKTsKICAgICAgICAkRW5jb2RlT2JqZWN0LT5FbmNvZGVPdXRwdXQoIFwkTG9naW4gKTsKCiAgICAgICAgJENyeXB0ZWRQdyA9IGNyeXB0KCAkUHcsICRMb2dpbiApOwogICAgICAgICRFbmNvZGVPYmplY3QtPkVuY29kZUlucHV0KCBcJENyeXB0ZWRQdyApOwogICAgfQoKICAgICMgY3J5cHQgd2l0aCBtZDUgY3J5cHQKICAgIGVsc2lmICggJENyeXB0VHlwZSBlcSAnbWQ1JyB8fCAhJENyeXB0VHlwZSApIHsKCiAgICAgICAgIyBlbmNvZGUgb3V0cHV0LCBuZWVkZWQgYnkgdW5peF9tZDVfY3J5cHQoKSBvbmx5IG5vbiB1dGY4IHNpZ25zCiAgICAgICAgJEVuY29kZU9iamVjdC0+RW5jb2RlT3V0cHV0KCBcJFB3ICk7CiAgICAgICAgJEVuY29kZU9iamVjdC0+RW5jb2RlT3V0cHV0KCBcJExvZ2luICk7CgogICAgICAgICRDcnlwdGVkUHcgPSB1bml4X21kNV9jcnlwdCggJFB3LCAkTG9naW4gKTsKICAgICAgICAkRW5jb2RlT2JqZWN0LT5FbmNvZGVJbnB1dCggXCRDcnlwdGVkUHcgKTsKICAgIH0KCiAgICAjIGNyeXB0IHdpdGggbWQ1IGNyeXB0IChjb21wYXRpYmxlIHdpdGggQXBhY2hlJ3MgLmh0cGFzc3dkIGZpbGVzKQogICAgZWxzaWYgKCAkQ3J5cHRUeXBlIGVxICdhcHIxJyApIHsKCiAgICAgICAgIyBlbmNvZGUgb3V0cHV0LCBuZWVkZWQgYnkgYXBhY2hlX21kNV9jcnlwdCgpIG9ubHkgbm9uIHV0Zjggc2lnbnMKICAgICAgICAkRW5jb2RlT2JqZWN0LT5FbmNvZGVPdXRwdXQoIFwkUHcgKTsKICAgICAgICAkRW5jb2RlT2JqZWN0LT5FbmNvZGVPdXRwdXQoIFwkTG9naW4gKTsKCiAgICAgICAgJENyeXB0ZWRQdyA9IGFwYWNoZV9tZDVfY3J5cHQoICRQdywgJExvZ2luICk7CiAgICAgICAgJEVuY29kZU9iamVjdC0+RW5jb2RlSW5wdXQoIFwkQ3J5cHRlZFB3ICk7CiAgICB9CgogICAgIyBjcnlwdCB3aXRoIHNoYTEKICAgIGVsc2lmICggJENyeXB0VHlwZSBlcSAnc2hhMScgKSB7CgogICAgICAgIG15ICRTSEFPYmplY3QgPSBEaWdlc3Q6OlNIQS0+bmV3KCdzaGExJyk7CiAgICAgICAgJEVuY29kZU9iamVjdC0+RW5jb2RlT3V0cHV0KCBcJFB3ICk7CiAgICAgICAgJFNIQU9iamVjdC0+YWRkKCRQdyk7CiAgICAgICAgJENyeXB0ZWRQdyA9ICRTSEFPYmplY3QtPmhleGRpZ2VzdCgpOwogICAgfQoKICAgIGVsc2lmICggJENyeXB0VHlwZSBlcSAnc2hhNTEyJyApIHsKCiAgICAgICAgbXkgJFNIQU9iamVjdCA9IERpZ2VzdDo6U0hBLT5uZXcoJ3NoYTUxMicpOwogICAgICAgICRFbmNvZGVPYmplY3QtPkVuY29kZU91dHB1dCggXCRQdyApOwogICAgICAgICRTSEFPYmplY3QtPmFkZCgkUHcpOwogICAgICAgICRDcnlwdGVkUHcgPSAkU0hBT2JqZWN0LT5oZXhkaWdlc3QoKTsKICAgIH0KCiAgICAjIGJjcnlwdAogICAgZWxzaWYgKCAkQ3J5cHRUeXBlIGVxICdiY3J5cHQnICkgewoKICAgICAgICAjIGdldCBtYWluIG9iamVjdAogICAgICAgIG15ICRNYWluT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Ok1haW4nKTsKCiAgICAgICAgaWYgKCAhJE1haW5PYmplY3QtPlJlcXVpcmUoJ0NyeXB0OjpFa3NibG93ZmlzaDo6QmNyeXB0JykgKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgPT4KICAgICAgICAgICAgICAgICAgICAiQ3VzdG9tZXJVc2VyOiAnJExvZ2luJyB0cmllZCB0byBzdG9yZSBwYXNzd29yZCB3aXRoIGJjcnlwdCBidXQgJ0NyeXB0OjpFa3NibG93ZmlzaDo6QmNyeXB0JyBpcyBub3QgaW5zdGFsbGVkISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIG15ICRDb3N0ID0gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lcjo6QXV0aE1vZHVsZTo6REI6OmJjcnlwdENvc3QnKSAvLyAxMjsKCiAgICAgICAgIyBEb24ndCBhbGxvdyB2YWx1ZXMgc21hbGxlciB0aGFuIDkgZm9yIHNlY3VyaXR5LgogICAgICAgICRDb3N0ID0gOSBpZiAkQ29zdCA8IDk7CgogICAgICAgICMgQ3VycmVudCBDcnlwdDo6RWtzYmxvd2Zpc2g6OkJjcnlwdCBsaW1pdCBpcyAzMS4KICAgICAgICAkQ29zdCA9IDMxIGlmICRDb3N0ID4gMzE7CgogICAgICAgIG15ICRTYWx0ID0gJE1haW5PYmplY3QtPkdlbmVyYXRlUmFuZG9tU3RyaW5nKCBMZW5ndGggPT4gMTYgKTsKCiAgICAgICAgIyByZW1vdmUgVVRGOCBmbGFnLCByZXF1aXJlZCBieSBDcnlwdDo6RWtzYmxvd2Zpc2g6OkJjcnlwdAogICAgICAgICRFbmNvZGVPYmplY3QtPkVuY29kZU91dHB1dCggXCRQdyApOwoKICAgICAgICAjIGNhbGN1bGF0ZSBwYXNzd29yZCBoYXNoCiAgICAgICAgbXkgJE9jdGV0cyA9IENyeXB0OjpFa3NibG93ZmlzaDo6QmNyeXB0OjpiY3J5cHRfaGFzaCgKICAgICAgICAgICAgewogICAgICAgICAgICAgICAga2V5X251bCA9PiAxLAogICAgICAgICAgICAgICAgY29zdCAgICA9PiAkQ29zdCwKICAgICAgICAgICAgICAgIHNhbHQgICAgPT4gJFNhbHQsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICRQdwogICAgICAgICk7CgogICAgICAgICMgV2Ugd2lsbCBzdG9yZSBjb3N0IGFuZCBzYWx0IGluIHRoZSBwYXNzd29yZCBzdHJpbmcgc28gdGhhdCBpdCBjYW4gYmUgZGVjb2RlZAogICAgICAgICMgICBpbiBmdXR1cmUgZXZlbiBpZiB3ZSB1c2UgYSBoaWdoZXIgY29zdCBieSBkZWZhdWx0LgogICAgICAgICRDcnlwdGVkUHcgPSAiQkNSWVBUOiRDb3N0OiRTYWx0OiIgLiBDcnlwdDo6RWtzYmxvd2Zpc2g6OkJjcnlwdDo6ZW5fYmFzZTY0KCRPY3RldHMpOwogICAgfQoKICAgICMgY3J5cHQgd2l0aCBzaGEyIGFzIGZhbGxiYWNrCiAgICBlbHNlIHsKCiAgICAgICAgbXkgJFNIQU9iamVjdCA9IERpZ2VzdDo6U0hBLT5uZXcoJ3NoYTI1NicpOwoKICAgICAgICAjIGVuY29kZSBvdXRwdXQsIG5lZWRlZCBieSBzaGEyNTZfaGV4KCkgb25seSBub24gdXRmOCBzaWducwogICAgICAgICRFbmNvZGVPYmplY3QtPkVuY29kZU91dHB1dCggXCRQdyApOwoKICAgICAgICAkU0hBT2JqZWN0LT5hZGQoJFB3KTsKICAgICAgICAkQ3J5cHRlZFB3ID0gJFNIQU9iamVjdC0+aGV4ZGlnZXN0KCk7CiAgICB9CgogICAgIyB1cGRhdGUgZGIKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9IH0gKSB7CiAgICAgICAgaWYgKCAkRW50cnktPlswXSA9fiAvXlVzZXJQYXNzd29yZCQvaSApIHsKICAgICAgICAgICAgJFBhcmFte1Bhc3N3b3JkQ29sfSA9ICRFbnRyeS0+WzJdOwogICAgICAgIH0KICAgICAgICBpZiAoICRFbnRyeS0+WzBdID1+IC9eVXNlckxvZ2luJC9pICkgewogICAgICAgICAgICAkUGFyYW17TG9naW5Db2x9ID0gJEVudHJ5LT5bMl07CiAgICAgICAgfQogICAgfQoKICAgICMgY2hlY2sgaWYgbmVlZGVkIHB3IGNvbC4gZXhpc3RzIChlbHNlIHRoZXJlIGlzIG5vIHB3IGNvbC4pCiAgICBpZiAoICRQYXJhbXtQYXNzd29yZENvbH0gJiYgJFBhcmFte0xvZ2luQ29sfSApIHsKICAgICAgICBteSAkU1FMID0gIlVQREFURSAkU2VsZi0+e0N1c3RvbWVyVGFibGV9IFNFVCAiCiAgICAgICAgICAgIC4gIiAkUGFyYW17UGFzc3dvcmRDb2x9ID0gPyAiCiAgICAgICAgICAgIC4gIiBXSEVSRSAiOwoKICAgICAgICBpZiAoICRTZWxmLT57Q2FzZVNlbnNpdGl2ZX0gKSB7CiAgICAgICAgICAgICRTUUwgLj0gIiRQYXJhbXtMb2dpbkNvbH0gPSA/IjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRTUUwgLj0gIkxPV0VSKCRQYXJhbXtMb2dpbkNvbH0pID0gTE9XRVIoPykiOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgICAgIFNRTCAgPT4gJFNRTCwKICAgICAgICAgICAgQmluZCA9PiBbIFwkQ3J5cHRlZFB3LCBcJFBhcmFte1VzZXJMb2dpbn0gXSwKICAgICAgICApOwoKICAgICAgICAjIGxvZyBub3RpY2UKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ25vdGljZScsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDdXN0b21lclVzZXI6ICckUGFyYW17VXNlckxvZ2lufScgY2hhbmdlZCBwYXNzd29yZCBzdWNjZXNzZnVsbHkhIiwKICAgICAgICApOwoKICAgICAgICAkU2VsZi0+X0N1c3RvbWVyVXNlckNhY2hlQ2xlYXIoIFVzZXJMb2dpbiA9PiAkUGFyYW17VXNlckxvZ2lufSApOwoKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAjIG5lZWQgbm8gcHcgdG8gc2V0CiAgICByZXR1cm4gMTsKfQoKc3ViIEdlbmVyYXRlUmFuZG9tUGFzc3dvcmQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGdlbmVyYXRlZCBwYXNzd29yZHMgYXJlIGVpZ2h0IGNoYXJhY3RlcnMgbG9uZyBieSBkZWZhdWx0CiAgICBteSAkU2l6ZSA9ICRQYXJhbXtTaXplfSB8fCA4OwoKICAgIG15ICRQYXNzd29yZCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpNYWluJyktPkdlbmVyYXRlUmFuZG9tU3RyaW5nKAogICAgICAgIExlbmd0aCA9PiAkU2l6ZSwKICAgICk7CgogICAgcmV0dXJuICRQYXNzd29yZDsKfQoKc3ViIFNldFByZWZlcmVuY2VzIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgcGFyYW1zCiAgICBpZiAoICEkUGFyYW17VXNlcklEfSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgVXNlcklEIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgJFNlbGYtPl9DdXN0b21lclVzZXJDYWNoZUNsZWFyKCBVc2VyTG9naW4gPT4gJFBhcmFte1VzZXJJRH0gKTsKCiAgICByZXR1cm4gJFNlbGYtPntQcmVmZXJlbmNlc09iamVjdH0tPlNldFByZWZlcmVuY2VzKCVQYXJhbSk7Cn0KCnN1YiBHZXRQcmVmZXJlbmNlcyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHBhcmFtcwogICAgaWYgKCAhJFBhcmFte1VzZXJJRH0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXJJRCEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHJldHVybiAkU2VsZi0+e1ByZWZlcmVuY2VzT2JqZWN0fS0+R2V0UHJlZmVyZW5jZXMoJVBhcmFtKTsKfQoKc3ViIFNlYXJjaFByZWZlcmVuY2VzIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgcmV0dXJuICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9LT5TZWFyY2hQcmVmZXJlbmNlcyglUGFyYW0pOwp9CgpzdWIgX0N1c3RvbWVyVXNlckNhY2hlQ2xlYXIgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICByZXR1cm4gaWYgISRTZWxmLT57Q2FjaGVPYmplY3R9OwoKICAgIGlmICggISRQYXJhbXtVc2VyTG9naW59ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBVc2VyTG9naW4hJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+RGVsZXRlKAogICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgIEtleSAgPT4gIkN1c3RvbWVyVXNlckRhdGFHZXQ6OiRQYXJhbXtVc2VyTG9naW59IiwKICAgICk7CiAgICAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+RGVsZXRlKAogICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgIEtleSAgPT4gIkN1c3RvbWVyTmFtZTo6JFBhcmFte1VzZXJMb2dpbn0iLAogICAgKTsKICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5EZWxldGUoCiAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgS2V5ICA9PiAiQ3VzdG9tZXJJRHM6OiRQYXJhbXtVc2VyTG9naW59IiwKICAgICk7CgogICAgIyBkZWxldGUgYWxsIHNlYXJjaCBjYWNoZSBlbnRyaWVzCiAgICAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+Q2xlYW5VcCgKICAgICAgICBUeXBlID0+ICRTZWxmLT57Q2FjaGVUeXBlfSAuICdfQ3VzdG9tZXJJRExpc3QnLAogICAgKTsKICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5DbGVhblVwKAogICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lclNlYXJjaCcsCiAgICApOwogICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPkNsZWFuVXAoCiAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyU2VhcmNoRGV0YWlsJywKICAgICk7CiAgICAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+Q2xlYW5VcCgKICAgICAgICBUeXBlID0+ICRTZWxmLT57Q2FjaGVUeXBlfSAuICdfQ3VzdG9tZXJTZWFyY2hEZXRhaWxEeW5hbWljRmllbGRzJywKICAgICk7CgogICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPkNsZWFuVXAoCiAgICAgICAgVHlwZSA9PiAnQ3VzdG9tZXJHcm91cCcsCiAgICApOwoKICAgIGZvciBteSAkRnVuY3Rpb24gKHF3KEN1c3RvbWVyVXNlckxpc3QpKSB7CiAgICAgICAgZm9yIG15ICRWYWxpZCAoIDAgLi4gMSApIHsKICAgICAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPkRlbGV0ZSgKICAgICAgICAgICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgICAgICAgICAgS2V5ICA9PiAiJHtGdW5jdGlvbn06OiR7VmFsaWR9IiwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCnN1YiBERVNUUk9ZIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgIyBkaXNjb25uZWN0IGlmIGl0J3Mgbm90IGEgcGFyZW50IERCT2JqZWN0CiAgICBpZiAoICRTZWxmLT57Tm90UGFyZW50REJPYmplY3R9ICkgewogICAgICAgIGlmICggJFNlbGYtPntEQk9iamVjdH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57REJPYmplY3R9LT5EaXNjb25uZWN0KCk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAxOwp9CgoxOwo=
IyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIxIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDIxIFpudW55IEdtYkgsIGh0dHBzOi8vem51bnkub3JnLwojIENvcHlyaWdodCAoQykgMjAyMSBSb3RoZXIgT1NTIEdtYkgsIGh0dHBzOi8vcm90aGVyLW9zcy5jb20vCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0zLjAudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXI6OkxEQVA7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgTmV0OjpMREFQOwp1c2UgTmV0OjpMREFQOjpVdGlsIHF3KGVzY2FwZV9maWx0ZXJfdmFsdWUpOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYXJpYWJsZUNoZWNrIHF3KDphbGwpOwoKb3VyIEBPYmplY3REZXBlbmRlbmNpZXMgPSAoCiAgICAnS2VybmVsOjpDb25maWcnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpDYWNoZScsCiAgICAnS2VybmVsOjpTeXN0ZW06OkRhdGVUaW1lJywKICAgICdLZXJuZWw6OlN5c3RlbTo6REInLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpFbmNvZGUnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpMb2cnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpNYWluJywKKTsKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgZGF0YQogICAgZm9yIG15ICROZWVkZWQgKHF3KCBQcmVmZXJlbmNlc09iamVjdCBDdXN0b21lclVzZXJNYXAgKSkgewogICAgICAgICRTZWxmLT57JE5lZWRlZH0gPSAkUGFyYW17JE5lZWRlZH0gfHwgZGllICJHb3Qgbm8gJE5lZWRlZCEiOwogICAgfQoKICAgICMgbWF4IHNob3duIHVzZXIgYSBzZWFyY2ggbGlzdAogICAgJFNlbGYtPntVc2VyU2VhcmNoTGlzdExpbWl0fSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlclNlYXJjaExpc3RMaW1pdH0gfHwgMjAwOwoKICAgICMgZ2V0IGxkYXAgcHJlZmVyZW5jZXMKICAgICRTZWxmLT57RGllfSA9IDA7CiAgICBpZiAoIGRlZmluZWQgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e0RpZX0gKSB7CiAgICAgICAgJFNlbGYtPntEaWV9ID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e0RpZX07CiAgICB9CgogICAgIyBnZXQgY29uZmlnIG9iamVjdAogICAgbXkgJENvbmZpZ09iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyk7CgogICAgIyBwYXJhbXMKICAgIGlmICggJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e1BhcmFtc30gKSB7CiAgICAgICAgJFNlbGYtPntQYXJhbXN9ID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e1BhcmFtc307CiAgICB9CgogICAgIyBOZXQ6OkxEQVAgbmV3IHBhcmFtcwogICAgZWxzaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoICdBdXRoTW9kdWxlOjpMREFQOjpQYXJhbXMnIC4gJFBhcmFte0NvdW50fSApICkgewogICAgICAgICRTZWxmLT57UGFyYW1zfSA9ICRDb25maWdPYmplY3QtPkdldCggJ0F1dGhNb2R1bGU6OkxEQVA6OlBhcmFtcycgLiAkUGFyYW17Q291bnR9ICk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkU2VsZi0+e1BhcmFtc30gPSB7fTsKICAgIH0KCiAgICAjIGhvc3QKICAgIGlmICggJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e0hvc3R9ICkgewogICAgICAgICRTZWxmLT57SG9zdH0gPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntQYXJhbXN9LT57SG9zdH07CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgQ3VzdG9tZXJVc2VyLT5QYXJhbXMtPkhvc3QgaW4gS2VybmVsL0NvbmZpZy5wbScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBiYXNlIGRuCiAgICBpZiAoIGRlZmluZWQgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e0Jhc2VETn0gKSB7CiAgICAgICAgJFNlbGYtPntCYXNlRE59ID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e0Jhc2VETn07CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgQ3VzdG9tZXJVc2VyLT5QYXJhbXMtPkJhc2VETiBpbiBLZXJuZWwvQ29uZmlnLnBtJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIHNjb3BlCiAgICBpZiAoICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e1BhcmFtc30tPntTU0NPUEV9ICkgewogICAgICAgICRTZWxmLT57U1Njb3BlfSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e1BhcmFtc30tPntTU0NPUEV9OwogICAgfQogICAgZWxzZSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIEN1c3RvbWVyVXNlci0+UGFyYW1zLT5TU0NPUEUgaW4gS2VybmVsL0NvbmZpZy5wbScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBzZWFyY2ggdXNlcgogICAgJFNlbGYtPntTZWFyY2hVc2VyRE59ID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e1VzZXJETn0gfHwgJyc7CiAgICAkU2VsZi0+e1NlYXJjaFVzZXJQd30gPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntQYXJhbXN9LT57VXNlclB3fSB8fCAnJzsKCiAgICAjIGdyb3VwIGRuCiAgICAkU2VsZi0+e0dyb3VwRE59ID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57UGFyYW1zfS0+e0dyb3VwRE59IHx8ICcnOwoKICAgICMgY3VzdG9tZXIga2V5CiAgICBpZiAoICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyS2V5fSApIHsKICAgICAgICAkU2VsZi0+e0N1c3RvbWVyS2V5fSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyS2V5fTsKICAgIH0KICAgIGVsc2UgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBDdXN0b21lclVzZXItPkN1c3RvbWVyS2V5IGluIEtlcm5lbC9Db25maWcucG0nLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY3VzdG9tZXIgaWQKICAgIGlmICggJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJJRH0gKSB7CiAgICAgICAgJFNlbGYtPntDdXN0b21lcklEfSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVySUR9OwogICAgfQogICAgZWxzZSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIEN1c3RvbWVyVXNlci0+Q3VzdG9tZXJJRCBpbiBLZXJuZWwvQ29uZmlnLnBtJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGxkYXAgZmlsdGVyIGFsd2F5cyB1c2VkCiAgICAkU2VsZi0+e0Fsd2F5c0ZpbHRlcn0gPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntQYXJhbXN9LT57QWx3YXlzRmlsdGVyfSB8fCAnJzsKCiAgICAkU2VsZi0+e0V4Y2x1ZGVQcmltYXJ5Q3VzdG9tZXJJRH0gPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJFeGNsdWRlUHJpbWFyeUN1c3RvbWVySUR9IHx8IDA7CiAgICAkU2VsZi0+e1NlYXJjaFByZWZpeH0gICAgICAgICAgICAgPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJTZWFyY2hQcmVmaXh9OwogICAgaWYgKCAhZGVmaW5lZCAkU2VsZi0+e1NlYXJjaFByZWZpeH0gKSB7CiAgICAgICAgJFNlbGYtPntTZWFyY2hQcmVmaXh9ID0gJyc7CiAgICB9CiAgICAkU2VsZi0+e1NlYXJjaFN1ZmZpeH0gPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJTZWFyY2hTdWZmaXh9OwogICAgaWYgKCAhZGVmaW5lZCAkU2VsZi0+e1NlYXJjaFN1ZmZpeH0gKSB7CiAgICAgICAgJFNlbGYtPntTZWFyY2hTdWZmaXh9ID0gJyonOwogICAgfQoKICAgICMgY2hhcnNldCBzZXR0aW5ncwogICAgJFNlbGYtPntTb3VyY2VDaGFyc2V0fSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e1BhcmFtc30tPntTb3VyY2VDaGFyc2V0fSB8fCAnJzsKCiAgICAjIHNldCBjYWNoZSB0eXBlCiAgICAkU2VsZi0+e0NhY2hlVHlwZX0gPSAnQ3VzdG9tZXJVc2VyJyAuICRQYXJhbXtDb3VudH07CgogICAgIyBjcmVhdGUgY2FjaGUgb2JqZWN0LCBidXQgb25seSBpZiBDYWNoZVRUTCBpcyBzZXQgaW4gY3VzdG9tZXIgY29uZmlnCiAgICBpZiAoICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0NhY2hlVFRMfSApIHsKICAgICAgICAkU2VsZi0+e0NhY2hlT2JqZWN0fSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDYWNoZScpOwogICAgfQoKICAgICMgZ2V0IHZhbGlkIGZpbHRlciBpZiB1c2VkCiAgICAkU2VsZi0+e1ZhbGlkRmlsdGVyfSA9ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlclZhbGlkRmlsdGVyfSB8fCAnJzsKCiAgICAjIGNvbm5lY3QgZmlyc3QgaWYgRGllIGlzIGVuYWJsZWQsIG1ha2Ugc3VyZSB0aGF0IGNvbm5lY3Rpb24gaXMgcG9zc2libGUsIGVsc2UgZGllCiAgICBpZiAoICRTZWxmLT57RGllfSApIHsKICAgICAgICByZXR1cm4gaWYgISRTZWxmLT5fQ29ubmVjdCgpOwogICAgfQoKICAgICMgZmV0Y2ggbmFtZXMgb2YgY29uZmlndXJlZCBkeW5hbWljIGZpZWxkcwogICAgbXkgQER5bmFtaWNGaWVsZE1hcEVudHJpZXMgPSBncmVwIHsgJF8tPls1XSBlcSAnZHluYW1pY19maWVsZCcgfSBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9IH07CiAgICAkU2VsZi0+e0NvbmZpZ3VyZWREeW5hbWljRmllbGROYW1lc30gPSB7IG1hcCB7ICRfLT5bMl0gPT4gMSB9IEBEeW5hbWljRmllbGRNYXBFbnRyaWVzIH07CgoKICAgICMgLS0tCiAgICAjIFJvdGhlck9TUzoKICAgICMgLS0tCiAgICBteSAkTGF5b3V0UGFyYW0gPSAkS2VybmVsOjpPTS0+e1BhcmFtfS0+eydLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0J307CgogICAgIyBDaGVjayBpZiBtdWx0aXRlbmFuY3kgaXMgZW5hYmxlZCBhbmQgdGhlIHJlcXVlc3QgaXMgY29taW5nIGZyb20gYSB1c2VyLgogICAgaWYgKCAkTGF5b3V0UGFyYW0tPntVc2VyVHlwZX0gJiYgJExheW91dFBhcmFtLT57VXNlclR5cGV9IGVxICdVc2VyJyAmJiAkQ29uZmlnT2JqZWN0LT5HZXQoJ011bHRpdGVuYW5jeScpICkgewoKICAgICAgICAjIFNhdmUgdGhlIFVzZXJJRCBhbmQgYWxsIGdyb3VwcyB0aGUgdXNlciBoYXMgJ3JvJyBwZXJtaXNzaW9uIG9uLgogICAgICAgIGlmICggJExheW91dFBhcmFtLT57VXNlcklEfSApIHsKICAgICAgICAgICAgIyBPbmx5IGdldCB0aGUgZ3JvdXAgbGlzdCBvbmNlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zLgogICAgICAgICAgICBteSAlR3JvdXBzID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Okdyb3VwJyktPlBlcm1pc3Npb25Vc2VyR2V0KAogICAgICAgICAgICAgICAgVXNlcklEID0+ICRMYXlvdXRQYXJhbS0+e1VzZXJJRH0sCiAgICAgICAgICAgICAgICBUeXBlICAgPT4gJ3JvJywKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICMgVGhlIGxpbWl0IGRvZXMgbm90IGNvdW50IGZvciBtZW1iZXJzIG9mIGEgc3BlY2lmaWMgZ3JvdXAuCiAgICAgICAgICAgIG15ICRQZXJtaXNzaW9uR3JvdXAgPSAkQ29uZmlnT2JqZWN0LT5HZXQoJ011bHRpdGVuYW5jeTo6UGVybWlzc2lvbkdyb3VwJykgfHwgJyc7CiAgICAgICAgICAgIG15ICVHcm91cHNSZXZlcnNlICAgPSByZXZlcnNlICVHcm91cHM7CgogICAgICAgICAgICBpZiAoICEkR3JvdXBzUmV2ZXJzZXskUGVybWlzc2lvbkdyb3VwfSApIHsKICAgICAgICAgICAgICAgICRTZWxmLT57TXVsdGl0ZW5hbmN5fSA9ICRMYXlvdXRQYXJhbS0+e1VzZXJJRH07CiAgICAgICAgICAgICAgICAkU2VsZi0+e1VzZXJHcm91cElEc30gPSBbIHNvcnQga2V5cyAlR3JvdXBzIF07CiAgICAgICAgICAgICAgICAkU2VsZi0+e1VzZXJHcm91cHN9ICAgPSBbIHZhbHVlcyAlR3JvdXBzIF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAjIC0tLQoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIF9Db25uZWN0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyByZXR1cm4gaWYgY29ubmVjdGlvbiBpcyBhbHJlYWR5IG9wZW4KICAgIHJldHVybiAxIGlmICRTZWxmLT57TERBUH07CgogICAgIyBsZGFwIGNvbm5lY3QgYW5kIGJpbmQgKG1heWJlIHdpdGggU2VhcmNoVXNlckROIGFuZCBTZWFyY2hVc2VyUHcpCiAgICAkU2VsZi0+e0xEQVB9ID0gTmV0OjpMREFQLT5uZXcoICRTZWxmLT57SG9zdH0sICV7ICRTZWxmLT57UGFyYW1zfSB9ICk7CgogICAgaWYgKCAhJFNlbGYtPntMREFQfSApIHsKICAgICAgICBpZiAoICRTZWxmLT57RGllfSApIHsKICAgICAgICAgICAgZGllICJDYW4ndCBjb25uZWN0IHRvICRTZWxmLT57SG9zdH06ICRAIjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDYW4ndCBjb25uZWN0IHRvICRTZWxmLT57SG9zdH06ICRAIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBteSAkUmVzdWx0OwogICAgaWYgKCAkU2VsZi0+e1NlYXJjaFVzZXJETn0gJiYgJFNlbGYtPntTZWFyY2hVc2VyUHd9ICkgewogICAgICAgICRSZXN1bHQgPSAkU2VsZi0+e0xEQVB9LT5iaW5kKAogICAgICAgICAgICBkbiAgICAgICA9PiAkU2VsZi0+e1NlYXJjaFVzZXJETn0sCiAgICAgICAgICAgIHBhc3N3b3JkID0+ICRTZWxmLT57U2VhcmNoVXNlclB3fSwKICAgICAgICApOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgJFJlc3VsdCA9ICRTZWxmLT57TERBUH0tPmJpbmQoKTsKICAgIH0KCiAgICBpZiAoICRSZXN1bHQtPmNvZGUoKSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0ZpcnN0IGJpbmQgZmFpbGVkISAnIC4gJFJlc3VsdC0+ZXJyb3IoKSwKICAgICAgICApOwogICAgICAgICRTZWxmLT57TERBUH0tPmRpc2Nvbm5lY3QoKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCnN1YiBDdXN0b21lck5hbWUgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1VzZXJMb2dpbn0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXJMb2dpbiEnCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBidWlsZCBmaWx0ZXIKICAgIG15ICRGaWx0ZXIgPSAiKCRTZWxmLT57Q3VzdG9tZXJLZXl9PSIgLiBlc2NhcGVfZmlsdGVyX3ZhbHVlKCAkUGFyYW17VXNlckxvZ2lufSApIC4gJyknOwoKICAgICMgcHJlcGFyZSBmaWx0ZXIKICAgIGlmICggJFNlbGYtPntBbHdheXNGaWx0ZXJ9ICkgewogICAgICAgICRGaWx0ZXIgPSAiKCYkRmlsdGVyJFNlbGYtPntBbHdheXNGaWx0ZXJ9KSI7CiAgICB9CgogICAgIyBjaGVjayBjYWNoZQogICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICBteSAkTmFtZSA9ICRTZWxmLT57Q2FjaGVPYmplY3R9LT5HZXQoCiAgICAgICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgICAgICBLZXkgID0+ICdDdXN0b21lck5hbWU6OicgLiAkUGFyYW17VXNlckxvZ2lufSwKICAgICAgICApOwogICAgICAgIHJldHVybiAkTmFtZSBpZiBkZWZpbmVkICROYW1lOwogICAgfQoKICAgICMgY3JlYXRlIGxkYXAgY29ubmVjdAogICAgcmV0dXJuIGlmICEkU2VsZi0+X0Nvbm5lY3QoKTsKCiAgICAjIHBlcmZvcm0gdXNlciBzZWFyY2gKICAgIG15ICRSZXN1bHQgPSAkU2VsZi0+e0xEQVB9LT5zZWFyY2goCiAgICAgICAgYmFzZSAgICAgID0+ICRTZWxmLT57QmFzZUROfSwKICAgICAgICBzY29wZSAgICAgPT4gJFNlbGYtPntTU2NvcGV9LAogICAgICAgIGZpbHRlciAgICA9PiAkRmlsdGVyLAogICAgICAgIHNpemVsaW1pdCA9PiAkU2VsZi0+e1VzZXJTZWFyY2hMaXN0TGltaXR9LAogICAgICAgIGF0dHJzICAgICA9PiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJOYW1lRmllbGRzfSwKICAgICk7CgogICAgaWYgKCAkUmVzdWx0LT5jb2RlKCkgKSB7CiAgICAgICAgaWYgKCAkUmVzdWx0LT5jb2RlKCkgPT0gNCApIHsKCiAgICAgICAgICAgICMgUmVzdWx0IGNvZGUgNCAoTERBUF9TSVpFTElNSVRfRVhDRUVERUQpIGlzIG5vcm1hbCBpZiB0aGVyZQogICAgICAgICAgICAjIGFyZSBtb3JlIGl0ZW1zIGluIExEQVAgdGhhbiBzZWFyY2ggbGltaXQgZGVmaW5lZCBpbiBPVFJTIG9yCiAgICAgICAgICAgICMgaW4gTERBUCBzZXJ2ZXIuIEF2b2lkIHNwYW1taW5nIGxvZ3Mgd2l0aCBzdWNoIGVycm9ycy4KICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0xEQVAgc2l6ZSBsaW1pdCBleGNlZWRlZCAoJyAuICRSZXN1bHQtPmVycm9yKCkgLiAnKS4nLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ1NlYXJjaCBmYWlsZWQhICcgLiAkUmVzdWx0LT5lcnJvcigpLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICByZXR1cm47CiAgICB9CgogICAgbXkgJU5hbWVQYXJ0czsKCiAgICBmb3IgbXkgJEVudHJ5ICggJFJlc3VsdC0+YWxsX2VudHJpZXMoKSApIHsKCiAgICAgICAgZm9yIG15ICRGaWVsZCAoIEB7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlck5hbWVGaWVsZHN9IH0gKSB7CgogICAgICAgICAgICBpZiAoIGRlZmluZWQgJEVudHJ5LT5nZXRfdmFsdWUoJEZpZWxkKSApIHsKICAgICAgICAgICAgICAgICROYW1lUGFydHN7JEZpZWxkfSA9ICRTZWxmLT5fQ29udmVydEZyb20oICRFbnRyeS0+Z2V0X3ZhbHVlKCRGaWVsZCkgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjIGZldGNoIGR5bmFtaWMgZmllbGQgdmFsdWVzLCBpZiBjb25maWd1cmVkCiAgICBteSBARHluYW1pY0ZpZWxkQ3VzdG9tZXJVc2VyTmFtZUZpZWxkcyA9IGdyZXAgeyBleGlzdHMgJFNlbGYtPntDb25maWd1cmVkRHluYW1pY0ZpZWxkTmFtZXN9LT57JF99IH0KICAgICAgICBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJOYW1lRmllbGRzfSB9OwogICAgaWYgKEBEeW5hbWljRmllbGRDdXN0b21lclVzZXJOYW1lRmllbGRzKSB7CiAgICAgICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CgogICAgICAgIERZTkFNSUNGSUVMRE5BTUU6CiAgICAgICAgZm9yIG15ICREeW5hbWljRmllbGROYW1lIChARHluYW1pY0ZpZWxkQ3VzdG9tZXJVc2VyTmFtZUZpZWxkcykgewogICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlnID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZCcpLT5EeW5hbWljRmllbGRHZXQoCiAgICAgICAgICAgICAgICBOYW1lID0+ICREeW5hbWljRmllbGROYW1lLAogICAgICAgICAgICApOwogICAgICAgICAgICBuZXh0IERZTkFNSUNGSUVMRE5BTUUgaWYgIUlzSGFzaFJlZldpdGhEYXRhKCREeW5hbWljRmllbGRDb25maWcpOwoKICAgICAgICAgICAgbXkgJFZhbHVlID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlR2V0KAogICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICBPYmplY3ROYW1lICAgICAgICAgPT4gJFBhcmFte1VzZXJMb2dpbn0sCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBuZXh0IERZTkFNSUNGSUVMRE5BTUUgaWYgIWRlZmluZWQgJFZhbHVlOwoKICAgICAgICAgICAgaWYgKCAhSXNBcnJheVJlZldpdGhEYXRhKCRWYWx1ZSkgKSB7CiAgICAgICAgICAgICAgICAkVmFsdWUgPSBbJFZhbHVlXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbXkgQFJlbmRlcmVkVmFsdWVzOwoKICAgICAgICAgICAgVkFMVUU6CiAgICAgICAgICAgIGZvciBteSAkQ3VycmVudFZhbHVlICggQHskVmFsdWV9ICkgewogICAgICAgICAgICAgICAgbmV4dCBWQUxVRSBpZiAhZGVmaW5lZCAkQ3VycmVudFZhbHVlIHx8ICFsZW5ndGggJEN1cnJlbnRWYWx1ZTsKCiAgICAgICAgICAgICAgICBteSAkUmVuZGVyZWRWYWx1ZSA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5SZWFkYWJsZVZhbHVlUmVuZGVyKAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLAogICAgICAgICAgICAgICAgICAgIFZhbHVlICAgICAgICAgICAgICA9PiAkQ3VycmVudFZhbHVlLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBuZXh0IFZBTFVFIGlmICFJc0hhc2hSZWZXaXRoRGF0YSgkUmVuZGVyZWRWYWx1ZSkgfHwgIWRlZmluZWQgJFJlbmRlcmVkVmFsdWUtPntWYWx1ZX07CgogICAgICAgICAgICAgICAgcHVzaCBAUmVuZGVyZWRWYWx1ZXMsICRSZW5kZXJlZFZhbHVlLT57VmFsdWV9OwogICAgICAgICAgICB9CgogICAgICAgICAgICAkTmFtZVBhcnRzeyREeW5hbWljRmllbGROYW1lfSA9IGpvaW4gJyAnLCBAUmVuZGVyZWRWYWx1ZXM7CiAgICAgICAgfQogICAgfQoKICAgICMgYXNzZW1ibGUgbmFtZQogICAgbXkgQE5hbWVQYXJ0czsKICAgIENVU1RPTUVSVVNFUk5BTUVGSUVMRDoKICAgIGZvciBteSAkQ3VzdG9tZXJVc2VyTmFtZUZpZWxkICggQHsgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJVc2VyTmFtZUZpZWxkc30gfSApIHsKICAgICAgICBuZXh0IENVU1RPTUVSVVNFUk5BTUVGSUVMRAogICAgICAgICAgICBpZiAhZXhpc3RzICROYW1lUGFydHN7JEN1c3RvbWVyVXNlck5hbWVGaWVsZH0KICAgICAgICAgICAgfHwgIWRlZmluZWQgJE5hbWVQYXJ0c3skQ3VzdG9tZXJVc2VyTmFtZUZpZWxkfQogICAgICAgICAgICB8fCAhbGVuZ3RoICROYW1lUGFydHN7JEN1c3RvbWVyVXNlck5hbWVGaWVsZH07CiAgICAgICAgcHVzaCBATmFtZVBhcnRzLCAkTmFtZVBhcnRzeyRDdXN0b21lclVzZXJOYW1lRmllbGR9OwogICAgfQoKICAgIG15ICRKb2luQ2hhcmFjdGVyID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJVc2VyTmFtZUZpZWxkc0pvaW59IC8vICcgJzsKICAgIG15ICROYW1lICAgICAgICAgID0gam9pbiAkSm9pbkNoYXJhY3RlciwgQE5hbWVQYXJ0czsKCiAgICAjIGNhY2hlIHJlcXVlc3QKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgVHlwZSAgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgICAgICBLZXkgICA9PiAnQ3VzdG9tZXJOYW1lOjonIC4gJFBhcmFte1VzZXJMb2dpbn0sCiAgICAgICAgICAgIFZhbHVlID0+ICROYW1lLAogICAgICAgICAgICBUVEwgICA9PiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDYWNoZVRUTH0sCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gJE5hbWU7Cn0KCnN1YiBDdXN0b21lclNlYXJjaCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIGlmICggJFBhcmFte0N1c3RvbWVySURSYXd9ICkgewogICAgICAgICRQYXJhbXtDdXN0b21lcklEfSA9ICRQYXJhbXtDdXN0b21lcklEUmF3fTsKICAgIH0KCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1NlYXJjaH0gJiYgISRQYXJhbXtVc2VyTG9naW59ICYmICEkUGFyYW17UG9zdE1hc3RlclNlYXJjaH0gJiYgISRQYXJhbXtDdXN0b21lcklEfSApCiAgICB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFNlYXJjaCwgVXNlckxvZ2luLCBQb3N0TWFzdGVyU2VhcmNoIG9yIEN1c3RvbWVySUQhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgYnVpbGQgZmlsdGVyCiAgICBteSAkRmlsdGVyID0gJyc7CiAgICBpZiAoICRQYXJhbXtTZWFyY2h9ICkgewoKICAgICAgICBteSAkQ291bnQgPSAwOwogICAgICAgIG15IEBQYXJ0cyA9IHNwbGl0KCAvXCsvLCAkUGFyYW17U2VhcmNofSwgNiApOwogICAgICAgIGZvciBteSAkUGFydCAoQFBhcnRzKSB7CgogICAgICAgICAgICAkUGFydCA9ICRTZWxmLT57U2VhcmNoUHJlZml4fSAuICRQYXJ0IC4gJFNlbGYtPntTZWFyY2hTdWZmaXh9OwogICAgICAgICAgICAkUGFydCA9fiBzLyhcJSspL1wlL2c7CiAgICAgICAgICAgICRQYXJ0ID1+IHMvKFwqKylcKi8qL2c7CiAgICAgICAgICAgICRDb3VudCsrOwoKICAgICAgICAgICAgIyByZW1vdmUgZHluYW1pYyBmaWVsZCBuYW1lcyB0aGF0IGFyZSBjb25maWd1cmVkIGluIEN1c3RvbWVyVXNlclNlYXJjaEZpZWxkcwogICAgICAgICAgICAjIGFzIHRoZXkgY2Fubm90IGJlIHJldHJpZXZlZCBoZXJlCiAgICAgICAgICAgIG15IEBDdXN0b21lclVzZXJTZWFyY2hGaWVsZHMgPSBncmVwIHsgIWV4aXN0cyAkU2VsZi0+e0NvbmZpZ3VyZWREeW5hbWljRmllbGROYW1lc30tPnskX30gfQogICAgICAgICAgICAgICAgQHsgJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJVc2VyU2VhcmNoRmllbGRzfSB9OwoKICAgICAgICAgICAgaWYgKEBDdXN0b21lclVzZXJTZWFyY2hGaWVsZHMpIHsKCiAgICAgICAgICAgICAgICAjIHF1b3RlIExEQVAgZmlsdGVyIHZhbHVlIGJ1dCBrZWVwIGFzdGVyaXNrcyB1bmVzY2FwZWQgKHdpbGRjYXJkKQogICAgICAgICAgICAgICAgJFBhcnQgPX4gcy9cKi9lbmNvZGVkYXN0ZXJpc2syMDE2MDkzMC9nOwogICAgICAgICAgICAgICAgJFBhcnQgPSBlc2NhcGVfZmlsdGVyX3ZhbHVlKCAkU2VsZi0+X0NvbnZlcnRUbygkUGFydCkgKTsKICAgICAgICAgICAgICAgICRQYXJ0ID1+IHMvZW5jb2RlZGFzdGVyaXNrMjAxNjA5MzAvKi9nOwoKICAgICAgICAgICAgICAgICRGaWx0ZXIgLj0gJyh8JzsKICAgICAgICAgICAgICAgIGZvciBteSAkRmllbGQgKEBDdXN0b21lclVzZXJTZWFyY2hGaWVsZHMpIHsKICAgICAgICAgICAgICAgICAgICAkRmlsdGVyIC49ICIoJEZpZWxkPSIgLiAkUGFydCAuICcpJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRGaWx0ZXIgLj0gJyknOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewoKICAgICAgICAgICAgICAgICMgcXVvdGUgTERBUCBmaWx0ZXIgdmFsdWUgYnV0IGtlZXAgYXN0ZXJpc2tzIHVuZXNjYXBlZCAod2lsZGNhcmQpCiAgICAgICAgICAgICAgICAkUGFydCA9fiBzL1wqL2VuY29kZWRhc3RlcmlzazIwMTYwOTMwL2c7CiAgICAgICAgICAgICAgICAkUGFydCA9IGVzY2FwZV9maWx0ZXJfdmFsdWUoJFBhcnQpOwogICAgICAgICAgICAgICAgJFBhcnQgPX4gcy9lbmNvZGVkYXN0ZXJpc2syMDE2MDkzMC8qL2c7CgogICAgICAgICAgICAgICAgJEZpbHRlciAuPSAiKCRTZWxmLT57Q3VzdG9tZXJLZXl9PSIgLiAkUGFydCAuICcpJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCAkQ291bnQgPiAxICkgewogICAgICAgICAgICAkRmlsdGVyID0gIigmJEZpbHRlcikiOwogICAgICAgIH0KICAgIH0KICAgIGVsc2lmICggJFBhcmFte1Bvc3RNYXN0ZXJTZWFyY2h9ICkgewoKICAgICAgICAjIHJlbW92ZSBkeW5hbWljIGZpZWxkIG5hbWVzIHRoYXQgYXJlIGNvbmZpZ3VyZWQgaW4gQ3VzdG9tZXJVc2VyUG9zdE1hc3RlclNlYXJjaEZpZWxkcwogICAgICAgICMgYXMgdGhleSBjYW5ub3QgYmUgcmV0cmlldmVkIGhlcmUKICAgICAgICBteSBAQ3VzdG9tZXJVc2VyUG9zdE1hc3RlclNlYXJjaEZpZWxkcyA9IGdyZXAgeyAhZXhpc3RzICRTZWxmLT57Q29uZmlndXJlZER5bmFtaWNGaWVsZE5hbWVzfS0+eyRffSB9CiAgICAgICAgICAgIEB7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0N1c3RvbWVyVXNlclBvc3RNYXN0ZXJTZWFyY2hGaWVsZHN9IH07CgogICAgICAgIGlmIChAQ3VzdG9tZXJVc2VyUG9zdE1hc3RlclNlYXJjaEZpZWxkcykgewoKICAgICAgICAgICAgIyBxdW90ZSBMREFQIGZpbHRlciB2YWx1ZSBidXQga2VlcCBhc3Rlcmlza3MgdW5lc2NhcGVkICh3aWxkY2FyZCkKICAgICAgICAgICAgJFBhcmFte1Bvc3RNYXN0ZXJTZWFyY2h9ID1+IHMvXCovZW5jb2RlZGFzdGVyaXNrMjAxNjA5MzAvZzsKICAgICAgICAgICAgJFBhcmFte1Bvc3RNYXN0ZXJTZWFyY2h9ID0gZXNjYXBlX2ZpbHRlcl92YWx1ZSggJFBhcmFte1Bvc3RNYXN0ZXJTZWFyY2h9ICk7CiAgICAgICAgICAgICRQYXJhbXtQb3N0TWFzdGVyU2VhcmNofSA9fiBzL2VuY29kZWRhc3RlcmlzazIwMTYwOTMwLyovZzsKCiAgICAgICAgICAgICRGaWx0ZXIgPSAnKHwnOwogICAgICAgICAgICBmb3IgbXkgJEZpZWxkIChAQ3VzdG9tZXJVc2VyUG9zdE1hc3RlclNlYXJjaEZpZWxkcykgewogICAgICAgICAgICAgICAgJEZpbHRlciAuPSAiKCRGaWVsZD0kUGFyYW17UG9zdE1hc3RlclNlYXJjaH0pIjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkRmlsdGVyIC49ICcpJzsKICAgICAgICB9CiAgICB9CiAgICBlbHNpZiAoICRQYXJhbXtVc2VyTG9naW59ICkgewogICAgICAgICRGaWx0ZXIgPSAiKCRTZWxmLT57Q3VzdG9tZXJLZXl9PSIgLiBlc2NhcGVfZmlsdGVyX3ZhbHVlKCAkUGFyYW17VXNlckxvZ2lufSApIC4gJyknOwogICAgfQogICAgZWxzaWYgKCAkUGFyYW17Q3VzdG9tZXJJRH0gKSB7CiAgICAgICAgJEZpbHRlciA9ICIoJFNlbGYtPntDdXN0b21lcklEfT0iIC4gZXNjYXBlX2ZpbHRlcl92YWx1ZSggJFBhcmFte0N1c3RvbWVySUR9ICkgLiAnKSc7CiAgICB9CgogICAgIyBwcmVwYXJlIGZpbHRlcgogICAgaWYgKCAkU2VsZi0+e0Fsd2F5c0ZpbHRlcn0gKSB7CiAgICAgICAgJEZpbHRlciA9ICIoJiRGaWx0ZXIkU2VsZi0+e0Fsd2F5c0ZpbHRlcn0pIjsKICAgIH0KCiAgICAjIGFkZCB2YWxpZCBmaWx0ZXIKICAgIGlmICggJFNlbGYtPntWYWxpZEZpbHRlcn0gKSB7CiAgICAgICAgJEZpbHRlciA9ICIoJiRGaWx0ZXIkU2VsZi0+e1ZhbGlkRmlsdGVyfSkiOwogICAgfQoKICAgICMgY2hlY2sgY2FjaGUKICAgIG15ICRDYWNoZUtleSA9IGpvaW4gJzo6JywgbWFwIHsgJF8gLiAnPScgLiAkUGFyYW17JF99IH0gc29ydCBrZXlzICVQYXJhbTsKICAgICMgLS0tCiAgICAjIFJvdGhlck9TUzogVXNlIGNhY2hlIGZvciBtdWx0aXRlbmFuY3kuCiAgICAjIC0tLQogICAgaWYgKCAkU2VsZi0+e011bHRpdGVuYW5jeX0gKSB7CiAgICAgICAgJENhY2hlS2V5IC49IGpvaW4gJycsIG1hcCB7ICc6Okdyb3VwSUQ9JyAuICRfIH0gQHsgJFNlbGYtPntVc2VyR3JvdXBJRHN9IH07CiAgICB9CiAgICAjIC0tLQogICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICBteSAkVXNlcnMgPSAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+R2V0KAogICAgICAgICAgICBUeXBlID0+ICRTZWxmLT57Q2FjaGVUeXBlfSAuICdfQ3VzdG9tZXJTZWFyY2gnLAogICAgICAgICAgICBLZXkgID0+ICRDYWNoZUtleSwKICAgICAgICApOwogICAgICAgIHJldHVybiAleyRVc2Vyc30gaWYgcmVmICRVc2VycyBlcSAnSEFTSCc7CiAgICB9CgogICAgIyBjcmVhdGUgbGRhcCBjb25uZWN0CiAgICByZXR1cm4gaWYgISRTZWxmLT5fQ29ubmVjdCgpOwoKICAgIG15ICRDdXN0b21lclVzZXJMaXN0RmllbGRzID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJVc2VyTGlzdEZpZWxkc307CgogICAgIyByZW1vdmUgZHluYW1pYyBmaWVsZCBuYW1lcyB0aGF0IGFyZSBjb25maWd1cmVkIGluIEN1c3RvbWVyVXNlckxpc3RGaWVsZHMKICAgICMgYXMgdGhleSBjYW5ub3QgYmUgaGFuZGxlZCBoZXJlCiAgICBteSBAQ3VzdG9tZXJVc2VyTGlzdEZpZWxkc1dpdGhvdXREeW5hbWljRmllbGRzCiAgICAgICAgPSBncmVwIHsgIWV4aXN0cyAkU2VsZi0+e0NvbmZpZ3VyZWREeW5hbWljRmllbGROYW1lc30tPnskX30gfSBAeyRDdXN0b21lclVzZXJMaXN0RmllbGRzfTsKCiAgICAjIGNvbWJpbmUgbmVlZGVkIGF0dHJzCiAgICBteSBAQXR0cmlidXRlcyA9ICggQEN1c3RvbWVyVXNlckxpc3RGaWVsZHNXaXRob3V0RHluYW1pY0ZpZWxkcywgJFNlbGYtPntDdXN0b21lcktleX0gKTsKCiAgICAjIC0tLQogICAgIyBSb3RoZXJPU1M6IERvbid0IHNlYXJjaCBmb3IgY3VzdG9tZXIgdXNlcnMgd2l0aG91dCBncm91cCBwZXJtaXNzaW9uLgogICAgIyAtLS0KICAgIGlmICggJFNlbGYtPntNdWx0aXRlbmFuY3l9ICkgewogICAgICAgIG15ICRHcm91cElEQXR0cjsKICAgICAgICBmb3IgbXkgJE1hcCAoIEB7ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e01hcH0gfSApIHsKICAgICAgICAgICAgaWYgKCAkTWFwLT5bMF0gZXEgJ1VzZXJHcm91cElEJyApIHsKICAgICAgICAgICAgICAgICRHcm91cElEQXR0ciA9ICRNYXAtPlsyXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBUaGUgc291cmNlIHN1cHBvcnRzIG11bHRpdGVuYW5jeS4KICAgICAgICBpZiAoJEdyb3VwSURBdHRyKSB7CiAgICAgICAgICAgIGlmICggJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJDb21wYW55U3VwcG9ydH0gKSB7CiAgICAgICAgICAgICAgICAjIFRPRE86IFdvcmthcm91bmQgdW50aWwgdGhlIHNlYXJjaCBnZXRzIGNoYW5nZWQuIFNlZSBDdXN0b21lclVzZXIvTERBUC5wbSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICAgICAgICAgICAgICAgICRQYXJhbXtMaW1pdH0gPSAxMDAwMDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG15ICRVc2VyR3JvdXBJRFN5bmMgPSAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntVc2VyR3JvdXBJRFN5bmN9OwogICAgICAgICAgICAjIENoZWNrIGlmIHdlIG1hdGNoIGZvciBncm91cCBJRHMgb3IgZ3JvdXAgbmFtZXMuCiAgICAgICAgICAgIG15IEBVc2VyR3JvdXBzID0gJFVzZXJHcm91cElEU3luYy0+e1VzZUdyb3VwTmFtZXN9ID8gQHsgJFNlbGYtPntVc2VyR3JvdXBzfSB9IDogQHsgJFNlbGYtPntVc2VyR3JvdXBJRHN9IH07CgogICAgICAgICAgICAjIFJlbWFwIGxvY2FsIGdyb3VwcyB0byByZW1vdGUgZ3JvdXBzLgogICAgICAgICAgICBmb3IgbXkgJFJlbW90ZUdyb3VwICgga2V5cyAleyAkVXNlckdyb3VwSURTeW5jLT57UmVtb3RlR3JvdXBUb0xvY2FsR3JvdXB9IH0gKSB7CiAgICAgICAgICAgICAgICBteSAkTG9jYWxHcm91cCA9ICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH17JFJlbW90ZUdyb3VwfTsKCiAgICAgICAgICAgICAgICBAVXNlckdyb3VwcyA9IG1hcCB7ICRfIGVxICRMb2NhbEdyb3VwID8gJFJlbW90ZUdyb3VwIDogJF8gfSBAVXNlckdyb3VwczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgIyBCdWlsZCBmaWx0ZXIgc3RyaW5nLiBJZiB0aGUgZmllbGQgaXMgZW1wdHksIHdlIGhhdmUgYWNjZXNzIGJ5IGRlZmF1bHQuCiAgICAgICAgICAgIG15ICRBZGRpdGlvbmFsRmlsdGVyID0gIih8KCEoJEdyb3VwSURBdHRyPSopKSI7CiAgICAgICAgICAgIGZvciBteSAkVXNlckdyb3VwIChAVXNlckdyb3VwcykgewogICAgICAgICAgICAgICAgJEFkZGl0aW9uYWxGaWx0ZXIgLj0gIigkR3JvdXBJREF0dHI9JFVzZXJHcm91cCkiOwogICAgICAgICAgICB9IAogICAgICAgICAgICAkQWRkaXRpb25hbEZpbHRlciAuPSAnKSknOwoKICAgICAgICAgICAgIyBSZW1vdmUgdGhlIGxhc3QgY2xvc2luZyBwYXJlbnRoZXNpcyBhbmQgYWRkIHRoZSBjdXN0b20gZmlsdGVyIHRvIHRoZSBzZWFyY2guCiAgICAgICAgICAgICRGaWx0ZXIgPSBzdWJzdHIgJEZpbHRlciwgMCwgLTE7CiAgICAgICAgICAgICRGaWx0ZXIgLj0gJEFkZGl0aW9uYWxGaWx0ZXI7CiAgICAgICAgfQogICAgfQogICAgIyAtLS0KCiAgICAjIHBlcmZvcm0gdXNlciBzZWFyY2gKICAgIG15ICRSZXN1bHQgPSAkU2VsZi0+e0xEQVB9LT5zZWFyY2goCiAgICAgICAgYmFzZSAgICAgID0+ICRTZWxmLT57QmFzZUROfSwKICAgICAgICBzY29wZSAgICAgPT4gJFNlbGYtPntTU2NvcGV9LAogICAgICAgIGZpbHRlciAgICA9PiAkRmlsdGVyLAogICAgICAgIHNpemVsaW1pdCA9PiAkUGFyYW17TGltaXR9IHx8ICRTZWxmLT57VXNlclNlYXJjaExpc3RMaW1pdH0sCiAgICAgICAgYXR0cnMgICAgID0+IFxAQXR0cmlidXRlcywKICAgICk7CgogICAgIyBsb2cgbGRhcCBlcnJvcnMKICAgIGlmICggJFJlc3VsdC0+Y29kZSgpICkgewogICAgICAgIGlmICggJFJlc3VsdC0+Y29kZSgpID09IDQgKSB7CgogICAgICAgICAgICAjIFJlc3VsdCBjb2RlIDQgKExEQVBfU0laRUxJTUlUX0VYQ0VFREVEKSBpcyBub3JtYWwgaWYgdGhlcmUKICAgICAgICAgICAgIyBhcmUgbW9yZSBpdGVtcyBpbiBMREFQIHRoYW4gc2VhcmNoIGxpbWl0IGRlZmluZWQgaW4gT1RSUyBvcgogICAgICAgICAgICAjIGluIExEQVAgc2VydmVyLiBBdm9pZCBzcGFtbWluZyBsb2dzIHdpdGggc3VjaCBlcnJvcnMuCiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2RlYnVnJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdMREFQIHNpemUgbGltaXQgZXhjZWVkZWQgKCcgLiAkUmVzdWx0LT5lcnJvcigpIC4gJykuJywKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdTZWFyY2ggZmFpbGVkISAnIC4gJFJlc3VsdC0+ZXJyb3IoKSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgIyBkeW5hbWljIGZpZWxkIGhhbmRsaW5nCiAgICBteSBAQ3VzdG9tZXJVc2VyTGlzdEZpZWxkc0R5bmFtaWNGaWVsZHMKICAgICAgICA9IGdyZXAgeyBleGlzdHMgJFNlbGYtPntDb25maWd1cmVkRHluYW1pY0ZpZWxkTmFtZXN9LT57JF99IH0gQHskQ3VzdG9tZXJVc2VyTGlzdEZpZWxkc307CiAgICBteSAlQ3VzdG9tZXJVc2VyTGlzdEZpZWxkc0R5bmFtaWNGaWVsZHMgPSBtYXAgeyAkXyA9PiAxIH0gQEN1c3RvbWVyVXNlckxpc3RGaWVsZHNEeW5hbWljRmllbGRzOwoKICAgIG15ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDo6QmFja2VuZCcpOwoKICAgIG15ICREeW5hbWljRmllbGRDb25maWdzID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZCcpLT5EeW5hbWljRmllbGRMaXN0R2V0KAogICAgICAgIE9iamVjdFR5cGUgPT4gJ0N1c3RvbWVyVXNlcicsCiAgICAgICAgVmFsaWQgICAgICA9PiAxLAogICAgKTsKICAgIG15ICVEeW5hbWljRmllbGRDb25maWdzQnlOYW1lID0gbWFwIHsgJF8tPntOYW1lfSA9PiAkXyB9IEB7JER5bmFtaWNGaWVsZENvbmZpZ3N9OwoKICAgIG15ICVVc2VyczsKICAgIGZvciBteSAkRW50cnkgKCAkUmVzdWx0LT5hbGxfZW50cmllcygpICkgewoKICAgICAgICBteSAkQ3VzdG9tZXJTdHJpbmcgPSAnJzsKCiAgICAgICAgbXkgJEN1c3RvbWVyS2V5OwogICAgICAgIGlmICggZGVmaW5lZCAkRW50cnktPmdldF92YWx1ZSggJFNlbGYtPntDdXN0b21lcktleX0gKSApIHsKICAgICAgICAgICAgJEN1c3RvbWVyS2V5ID0gJFNlbGYtPl9Db252ZXJ0RnJvbSggJEVudHJ5LT5nZXRfdmFsdWUoICRTZWxmLT57Q3VzdG9tZXJLZXl9ICkgKTsKICAgICAgICB9CgogICAgICAgIEZJRUxEOgogICAgICAgIGZvciBteSAkRmllbGQgKCBAeyRDdXN0b21lclVzZXJMaXN0RmllbGRzfSApIHsKCiAgICAgICAgICAgICMgZHluYW1pYyBmaWVsZCB2YWx1ZQogICAgICAgICAgICBpZiAoICRDdXN0b21lclVzZXJMaXN0RmllbGRzRHluYW1pY0ZpZWxkc3skRmllbGR9ICkgewogICAgICAgICAgICAgICAgbmV4dCBGSUVMRCBpZiAhZGVmaW5lZCAkQ3VzdG9tZXJLZXk7CiAgICAgICAgICAgICAgICBuZXh0IEZJRUxEIGlmICFleGlzdHMgJER5bmFtaWNGaWVsZENvbmZpZ3NCeU5hbWV7JEZpZWxkfTsKCiAgICAgICAgICAgICAgICBteSAkVmFsdWUgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+VmFsdWVHZXQoCiAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWdzQnlOYW1leyRGaWVsZH0sCiAgICAgICAgICAgICAgICAgICAgT2JqZWN0TmFtZSAgICAgICAgID0+ICRDdXN0b21lcktleSwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgbmV4dCBGSUVMRCBpZiAhZGVmaW5lZCAkVmFsdWU7CgogICAgICAgICAgICAgICAgaWYgKCAhSXNBcnJheVJlZldpdGhEYXRhKCRWYWx1ZSkgKSB7CiAgICAgICAgICAgICAgICAgICAgJFZhbHVlID0gWyRWYWx1ZV07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbXkgQFZhbHVlczsKCiAgICAgICAgICAgICAgICBWQUxVRToKICAgICAgICAgICAgICAgIGZvciBteSAkQ3VycmVudFZhbHVlICggQHskVmFsdWV9ICkgewogICAgICAgICAgICAgICAgICAgIG5leHQgVkFMVUUgaWYgIWRlZmluZWQgJEN1cnJlbnRWYWx1ZSB8fCAhbGVuZ3RoICRDdXJyZW50VmFsdWU7CgogICAgICAgICAgICAgICAgICAgIG15ICRSZWFkYWJsZVZhbHVlID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlJlYWRhYmxlVmFsdWVSZW5kZXIoCiAgICAgICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnc0J5TmFtZXskRmllbGR9LAogICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSAgICAgICAgICAgICAgPT4gJEN1cnJlbnRWYWx1ZSwKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICBuZXh0IFZBTFVFIGlmICFJc0hhc2hSZWZXaXRoRGF0YSgkUmVhZGFibGVWYWx1ZSkgfHwgIWRlZmluZWQgJFJlYWRhYmxlVmFsdWUtPntWYWx1ZX07CgogICAgICAgICAgICAgICAgICAgIG15ICRJc0FDTFJlZHVjaWJsZSA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5IYXNCZWhhdmlvcigKICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWdzQnlOYW1leyRGaWVsZH0sCiAgICAgICAgICAgICAgICAgICAgICAgIEJlaGF2aW9yICAgICAgICAgICA9PiAnSXNBQ0xSZWR1Y2libGUnLAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCRJc0FDTFJlZHVjaWJsZSkgewogICAgICAgICAgICAgICAgICAgICAgICBteSAkUG9zc2libGVWYWx1ZXMgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+UG9zc2libGVWYWx1ZXNHZXQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZENvbmZpZ3NCeU5hbWV7JEZpZWxkfSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElzSGFzaFJlZldpdGhEYXRhKCRQb3NzaWJsZVZhbHVlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGRlZmluZWQgJFBvc3NpYmxlVmFsdWVzLT57ICRSZWFkYWJsZVZhbHVlLT57VmFsdWV9IH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJFJlYWRhYmxlVmFsdWUtPntWYWx1ZX0gPSAkUG9zc2libGVWYWx1ZXMtPnsgJFJlYWRhYmxlVmFsdWUtPntWYWx1ZX0gfTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcHVzaCBAVmFsdWVzLCAkUmVhZGFibGVWYWx1ZS0+e1ZhbHVlfTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkQ3VzdG9tZXJTdHJpbmcgLj0gKCBqb2luICcgJywgQFZhbHVlcyApIC4gJyAnOwoKICAgICAgICAgICAgICAgIG5leHQgRklFTEQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG15ICRWYWx1ZSA9ICRTZWxmLT5fQ29udmVydEZyb20oICRFbnRyeS0+Z2V0X3ZhbHVlKCRGaWVsZCkgKTsKCiAgICAgICAgICAgIGlmICgkVmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICggJEZpZWxkID1+IC9edGFyZ2V0YWRkcmVzcyQvaSApIHsKICAgICAgICAgICAgICAgICAgICAkVmFsdWUgPX4gcy9TTVRQOiguKikvJDEvOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJEN1c3RvbWVyU3RyaW5nIC49ICRWYWx1ZSAuICcgJzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJEN1c3RvbWVyU3RyaW5nID1+IHMvXiguKilccyguKz9cQC4rP1wuLis/KShcc3wpJC8iJDEiIDwkMj4vOwoKICAgICAgICBpZiAoIGRlZmluZWQgJEN1c3RvbWVyS2V5ICkgewogICAgICAgICAgICAkVXNlcnN7JEN1c3RvbWVyS2V5fSA9ICRDdXN0b21lclN0cmluZzsKICAgICAgICB9CiAgICB9CgogICAgIyBjaGVjayBpZiB1c2VyIG5lZWQgdG8gYmUgaW4gYSBncm91cCEKICAgIGlmICggJFNlbGYtPntHcm91cEROfSApIHsKCiAgICAgICAgZm9yIG15ICRGaWx0ZXIyICggc29ydCBrZXlzICVVc2VycyApIHsKCiAgICAgICAgICAgIG15ICRSZXN1bHQyID0gJFNlbGYtPntMREFQfS0+c2VhcmNoKAogICAgICAgICAgICAgICAgYmFzZSAgICAgID0+ICRTZWxmLT57R3JvdXBETn0sCiAgICAgICAgICAgICAgICBzY29wZSAgICAgPT4gJFNlbGYtPntTU2NvcGV9LAogICAgICAgICAgICAgICAgZmlsdGVyICAgID0+ICdtZW1iZXJVaWQ9JyAuIGVzY2FwZV9maWx0ZXJfdmFsdWUoJEZpbHRlcjIpLAogICAgICAgICAgICAgICAgc2l6ZWxpbWl0ID0+ICRQYXJhbXtMaW1pdH0gfHwgJFNlbGYtPntVc2VyU2VhcmNoTGlzdExpbWl0fSwKICAgICAgICAgICAgICAgIGF0dHJzICAgICA9PiBbJzEuMSddLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgaWYgKCAhJFJlc3VsdDItPmFsbF9lbnRyaWVzKCkgKSB7CiAgICAgICAgICAgICAgICBkZWxldGUgJFVzZXJzeyRGaWx0ZXIyfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjIGNhY2hlIHJlcXVlc3QKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgVHlwZSAgPT4gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lclNlYXJjaCcsCiAgICAgICAgICAgIEtleSAgID0+ICRDYWNoZUtleSwKICAgICAgICAgICAgVmFsdWUgPT4gXCVVc2VycywKICAgICAgICAgICAgVFRMICAgPT4gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q2FjaGVUVEx9LAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuICVVc2VyczsKfQoKc3ViIEN1c3RvbWVyU2VhcmNoRGV0YWlsIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgaWYgKCByZWYgJFBhcmFte1NlYXJjaEZpZWxkc30gbmUgJ0FSUkFZJyApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIlNlYXJjaEZpZWxkcyBtdXN0IGJlIGFuIGFycmF5IHJlZmVyZW5jZSEiLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIG15ICRWYWxpZCA9IGRlZmluZWQgJFBhcmFte1ZhbGlkfSA/ICRQYXJhbXtWYWxpZH0gOiAxOwoKICAgICRQYXJhbXtMaW1pdH0gLy89ICcnOwoKICAgICMgU3BsaXQgdGhlIHNlYXJjaCBmaWVsZHMgaW4gc2NhbGFyIGFuZCBhcnJheSBmaWVsZHMsIGJlZm9yZSB0aGUgZGlmZnJlbnQgaGFuZGxpbmcuCiAgICBteSBAU2NhbGFyU2VhcmNoRmllbGRzID0gZ3JlcCB7ICdJbnB1dCcgZXEgJF8tPntUeXBlfSB9IEB7ICRQYXJhbXtTZWFyY2hGaWVsZHN9IH07CiAgICBteSBAQXJyYXlTZWFyY2hGaWVsZHMgID0gZ3JlcCB7ICdTZWxlY3Rpb24nIGVxICRfLT57VHlwZX0gfSBAeyAkUGFyYW17U2VhcmNoRmllbGRzfSB9OwoKICAgICMgVmVyaWZ5IHRoYXQgYWxsIHBhc3NlZCBhcnJheSBwYXJhbWV0ZXJzIGNvbnRhaW4gYW4gYXJyYXlyZWYuCiAgICBBUkdVTUVOVDoKICAgIGZvciBteSAkQXJndW1lbnQgKEBBcnJheVNlYXJjaEZpZWxkcykgewogICAgICAgIGlmICggIWRlZmluZWQgJFBhcmFteyAkQXJndW1lbnQtPntOYW1lfSB9ICkgewogICAgICAgICAgICAkUGFyYW17ICRBcmd1bWVudC0+e05hbWV9IH0gfHw9IFtdOwoKICAgICAgICAgICAgbmV4dCBBUkdVTUVOVDsKICAgICAgICB9CgogICAgICAgIGlmICggcmVmICRQYXJhbXsgJEFyZ3VtZW50LT57TmFtZX0gfSBuZSAnQVJSQVknICkgewogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiJEFyZ3VtZW50LT57TmFtZX0gbXVzdCBiZSBhbiBhcnJheSByZWZlcmVuY2UhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIFNldCB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgZm9yIHRoZSByZXR1cm4gdHlwZS4KICAgIG15ICRSZXN1bHQgPSAkUGFyYW17UmVzdWx0fSB8fCAnQVJSQVknOwoKICAgICMgU3BlY2lhbCBoYW5kbGluZyBpZiB0aGUgcmVzdWx0IHR5cGUgaXMgJ0NPVU5UJy4KICAgIGlmICggJFJlc3VsdCBlcSAnQ09VTlQnICkgewoKICAgICAgICAjIElnbm9yZSB0aGUgcGFyYW1ldGVyICdMaW1pdCcgd2hlbiByZXN1bHQgdHlwZSBpcyAnQ09VTlQnLgogICAgICAgICRQYXJhbXtMaW1pdH0gPSAnJzsKCiAgICAgICAgIyBEZWxldGUgdGhlIE9yZGVyQnkgcGFyYW1ldGVyIHdoZW4gdGhlIHJlc3VsdCB0eXBlIGlzICdDT1VOVCcuCiAgICAgICAgJFBhcmFte09yZGVyQnl9ID0gW107CiAgICB9CgogICAgIyBEZWZpbmUgb3JkZXIgdGFibGUgZnJvbSB0aGUgc2VhcmNoIGZpZWxkcy4KICAgIG15ICVPcmRlckJ5VGFibGUgPSBtYXAgeyAkXy0+e05hbWV9ID0+ICRfLT57RGF0YWJhc2VGaWVsZH0gfSBAeyAkUGFyYW17U2VhcmNoRmllbGRzfSB9OwoKICAgIGZvciBteSAkRmllbGQgKEBBcnJheVNlYXJjaEZpZWxkcykgewoKICAgICAgICBteSAkU2VsZWN0aW9uc0RhdGEgPSAkRmllbGQtPntTZWxlY3Rpb25zRGF0YX07CgogICAgICAgIGZvciBteSAkU2VsZWN0ZWRWYWx1ZSAoIEB7ICRQYXJhbXsgJEZpZWxkLT57TmFtZX0gfSB9ICkgewoKICAgICAgICAgICAgIyBDaGVjayBpZiB0aGUgc2VsZWN0ZWQgdmFsdWUgZm9yIHRoZSBjdXJyZW50IGZpZWxkIGlzIHZhbGlkLgogICAgICAgICAgICBpZiAoICEkU2VsZWN0aW9uc0RhdGEtPnskU2VsZWN0ZWRWYWx1ZX0gKSB7CiAgICAgICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJUaGUgc2VsZWN0ZWQgdmFsdWUgJEZpZWxkLT57TmFtZX0gaXMgbm90IHZhbGlkISIsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICMgQnVpbGQgdGhlIGxkYXAgZmlsdGVyIGZvciB0aGUgZGlmZnJlbnQgc2VhcmNoIHBhcmFtcy4KICAgIG15ICRGaWx0ZXIgPSAnJzsKCiAgICBmb3IgbXkgJEZpZWxkIChAU2NhbGFyU2VhcmNoRmllbGRzKSB7CgogICAgICAgICMgU2VhcmNoIGZvciBzY2FsYXIgZmllbGRzICh3aWxkY2FyZHMgYXJlIGFsbG93ZWQpLgogICAgICAgIGlmICggJFBhcmFteyAkRmllbGQtPntOYW1lfSB9ICkgewoKICAgICAgICAgICAgJFBhcmFteyAkRmllbGQtPntOYW1lfSB9ID1+IHMvKFwlKykvXCUvZzsKICAgICAgICAgICAgJFBhcmFteyAkRmllbGQtPntOYW1lfSB9ID1+IHMvKFwqKylcKi8qL2c7CgogICAgICAgICAgICAkRmlsdGVyIC49ICIoJEZpZWxkLT57RGF0YWJhc2VGaWVsZH09IiAuICRTZWxmLT5fQ29udmVydFRvKCAkUGFyYW17ICRGaWVsZC0+e05hbWV9IH0gKSAuICIpIjsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCRGaWx0ZXIpIHsKICAgICAgICAkRmlsdGVyID0gIigmJEZpbHRlcikiOwogICAgfQoKICAgIG15ICRBcnJheUZpbHRlciA9ICcnOwoKICAgICMgU3BlY2lhbCBwYXJhbWV0ZXIgZm9yIEN1c3RvbWVySURzIGZyb20gYSBjdXN0b21lciBjb21wYW55IHNlYXJjaCByZXN1bHQuCiAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSggJFBhcmFte0N1c3RvbWVyQ29tcGFueVNlYXJjaEN1c3RvbWVySURzfSApICkgewogICAgICAgICRBcnJheUZpbHRlciAuPSAnKHwnOwogICAgICAgIGZvciBteSAkT25lUGFyYW0gKCBAeyAkUGFyYW17Q3VzdG9tZXJDb21wYW55U2VhcmNoQ3VzdG9tZXJJRHN9IH0gKSB7CiAgICAgICAgICAgICRBcnJheUZpbHRlciAuPSAiKCRTZWxmLT57Q3VzdG9tZXJJRH09IiAuICRTZWxmLT5fQ29udmVydFRvKCRPbmVQYXJhbSkgLiAiKSI7CiAgICAgICAgfQogICAgICAgICRBcnJheUZpbHRlciAuPSAnKSc7CiAgICB9CgogICAgRklFTEQ6CiAgICBmb3IgbXkgJEZpZWxkIChAQXJyYXlTZWFyY2hGaWVsZHMpIHsKCiAgICAgICAgIyBJZ25vcmUgZW1wdHkgbGlzdHMuCiAgICAgICAgbmV4dCBGSUVMRCBpZiAhQHsgJFBhcmFteyAkRmllbGQtPntOYW1lfSB9IH07CgogICAgICAgICRBcnJheUZpbHRlciAuPSAnKHwnOwogICAgICAgIGZvciBteSAkT25lUGFyYW0gKCBAeyAkUGFyYW17ICRGaWVsZC0+e05hbWV9IH0gfSApIHsKICAgICAgICAgICAgJEFycmF5RmlsdGVyIC49ICIoJEZpZWxkLT57RGF0YWJhc2VGaWVsZH09IiAuICRTZWxmLT5fQ29udmVydFRvKCRPbmVQYXJhbSkgLiAiKSI7CiAgICAgICAgfQogICAgICAgICRBcnJheUZpbHRlciAuPSAnKSc7CiAgICB9CgogICAgIyBBZGQgdGhlIGFycmF5IGZpbHRlciBmaWVsZHMgdG8gdGhlIGxkYXAgZmlsdGVyLgogICAgaWYgKCRBcnJheUZpbHRlcikgewogICAgICAgICRGaWx0ZXIgPSAiKCYkRmlsdGVyJEFycmF5RmlsdGVyKSI7CiAgICB9CgogICAgbXkgJERCT2JqZWN0ICAgICAgICAgICAgICAgICAgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6REInKTsKICAgIG15ICREeW5hbWljRmllbGRPYmplY3QgICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZCcpOwogICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CgogICAgIyBDaGVjayBhbGwgY29uZmlndXJlZCBjaGFuZ2UgZHluYW1pYyBmaWVsZHMsIGJ1aWxkIGxvb2t1cCBoYXNoIGJ5IG5hbWUuCiAgICBteSAlQ3VzdG9tZXJVc2VyRHluYW1pY0ZpZWxkTmFtZTJDb25maWc7CiAgICBteSAkQ3VzdG9tZXJVc2VyRHluYW1pY0ZpZWxkcyA9ICREeW5hbWljRmllbGRPYmplY3QtPkR5bmFtaWNGaWVsZExpc3RHZXQoCiAgICAgICAgT2JqZWN0VHlwZSA9PiAnQ3VzdG9tZXJVc2VyJywKICAgICk7CiAgICBmb3IgbXkgJER5bmFtaWNGaWVsZCAoIEB7JEN1c3RvbWVyVXNlckR5bmFtaWNGaWVsZHN9ICkgewogICAgICAgICRDdXN0b21lclVzZXJEeW5hbWljRmllbGROYW1lMkNvbmZpZ3sgJER5bmFtaWNGaWVsZC0+e05hbWV9IH0gPSAkRHluYW1pY0ZpZWxkOwogICAgfQoKICAgIG15ICRTUUxEeW5hbWljRmllbGRGcm9tICAgICA9ICcnOwogICAgbXkgJFNRTER5bmFtaWNGaWVsZFdoZXJlICAgID0gJyc7CiAgICBteSAkRHluYW1pY0ZpZWxkSm9pbkNvdW50ZXIgPSAxOwoKICAgIERZTkFNSUNGSUVMRDoKICAgIGZvciBteSAkRHluYW1pY0ZpZWxkICggQHskQ3VzdG9tZXJVc2VyRHluYW1pY0ZpZWxkc30gKSB7CgogICAgICAgIG15ICRTZWFyY2hQYXJhbSA9ICRQYXJhbXsgIkR5bmFtaWNGaWVsZF8iIC4gJER5bmFtaWNGaWVsZC0+e05hbWV9IH07CgogICAgICAgIG5leHQgRFlOQU1JQ0ZJRUxEIGlmICggISRTZWFyY2hQYXJhbSApOwogICAgICAgIG5leHQgRFlOQU1JQ0ZJRUxEIGlmICggcmVmICRTZWFyY2hQYXJhbSBuZSAnSEFTSCcgKTsKCiAgICAgICAgbXkgJE5lZWRKb2luOwoKICAgICAgICBmb3IgbXkgJE9wZXJhdG9yICggc29ydCBrZXlzICV7JFNlYXJjaFBhcmFtfSApIHsKCiAgICAgICAgICAgIG15IEBTZWFyY2hQYXJhbXMgPSAoIHJlZiAkU2VhcmNoUGFyYW0tPnskT3BlcmF0b3J9IGVxICdBUlJBWScgKQogICAgICAgICAgICAgICAgPyBAeyAkU2VhcmNoUGFyYW0tPnskT3BlcmF0b3J9IH0KICAgICAgICAgICAgICAgIDogKCAkU2VhcmNoUGFyYW0tPnskT3BlcmF0b3J9ICk7CgogICAgICAgICAgICBteSAkU1FMRHluYW1pY0ZpZWxkV2hlcmVTdWIgPSAnJzsKICAgICAgICAgICAgaWYgKCRTUUxEeW5hbWljRmllbGRXaGVyZSkgewogICAgICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZFdoZXJlU3ViID0gJyBBTkQgKCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkU1FMRHluYW1pY0ZpZWxkV2hlcmVTdWIgPSAnICgnOwogICAgICAgICAgICB9CgogICAgICAgICAgICBteSAkQ291bnRlciA9IDA7CiAgICAgICAgICAgIFRFWFQ6CiAgICAgICAgICAgIGZvciBteSAkVGV4dCAoQFNlYXJjaFBhcmFtcykgewogICAgICAgICAgICAgICAgbmV4dCBURVhUIGlmICggIWRlZmluZWQgJFRleHQgfHwgJFRleHQgZXEgJycgKTsKCiAgICAgICAgICAgICAgICAkVGV4dCA9fiBzL1wqLyUvZ2k7CgogICAgICAgICAgICAgICAgIyBDaGVjayBzZWFyY2ggYXR0cmlidXRlLCB3ZSBkbyBub3QgbmVlZCB0byBzZWFyY2ggZm9yICcqJy4KICAgICAgICAgICAgICAgIG5leHQgVEVYVCBpZiAkVGV4dCA9fiAvXlwlezEsM30kLzsKCiAgICAgICAgICAgICAgICBteSAkVmFsaWRhdGVTdWNjZXNzID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlVmFsaWRhdGUoCiAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGQsCiAgICAgICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICAgICAgID0+ICRUZXh0LAogICAgICAgICAgICAgICAgICAgIFVzZXJJRCAgICAgICAgICAgICA9PiAkUGFyYW17VXNlcklEfSB8fCAxLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmICggISRWYWxpZGF0ZVN1Y2Nlc3MgKSB7CiAgICAgICAgICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJTZWFyY2ggbm90IGV4ZWN1dGVkIGR1ZSB0byBpbnZhbGlkIHZhbHVlICciCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICRUZXh0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICInIG9uIGZpZWxkICciCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuICREeW5hbWljRmllbGQtPntOYW1lfSAuICInISIsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCRDb3VudGVyKSB7CiAgICAgICAgICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZFdoZXJlU3ViIC49ICcgT1IgJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRTUUxEeW5hbWljRmllbGRXaGVyZVN1YiAuPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+U2VhcmNoU1FMR2V0KAogICAgICAgICAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkLAogICAgICAgICAgICAgICAgICAgIFRhYmxlQWxpYXMgICAgICAgICA9PiAiZGZ2JER5bmFtaWNGaWVsZEpvaW5Db3VudGVyIiwKICAgICAgICAgICAgICAgICAgICBPcGVyYXRvciAgICAgICAgICAgPT4gJE9wZXJhdG9yLAogICAgICAgICAgICAgICAgICAgIFNlYXJjaFRlcm0gICAgICAgICA9PiAkVGV4dCwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgJENvdW50ZXIrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICAkU1FMRHluYW1pY0ZpZWxkV2hlcmVTdWIgLj0gJykgJzsKCiAgICAgICAgICAgIGlmICgkQ291bnRlcikgewogICAgICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZFdoZXJlIC49ICRTUUxEeW5hbWljRmllbGRXaGVyZVN1YjsKICAgICAgICAgICAgICAgICROZWVkSm9pbiA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkTmVlZEpvaW4pIHsKICAgICAgICAgICAgJFNRTER5bmFtaWNGaWVsZEZyb20gLj0gIgogICAgICAgICAgICAgICAgSU5ORVIgSk9JTiBkeW5hbWljX2ZpZWxkX3ZhbHVlIGRmdiREeW5hbWljRmllbGRKb2luQ291bnRlcgogICAgICAgICAgICAgICAgICAgIE9OIChkZl9vYmpfaWRfbmFtZS5vYmplY3RfaWQgPSBkZnYkRHluYW1pY0ZpZWxkSm9pbkNvdW50ZXIub2JqZWN0X2lkCiAgICAgICAgICAgICAgICAgICAgICAgIEFORCBkZnYkRHluYW1pY0ZpZWxkSm9pbkNvdW50ZXIuZmllbGRfaWQgPSAiCiAgICAgICAgICAgICAgICAuICREQk9iamVjdC0+UXVvdGUoICREeW5hbWljRmllbGQtPntJRH0sICdJbnRlZ2VyJyApIC4gIikKICAgICAgICAgICAgIjsKCiAgICAgICAgICAgICREeW5hbWljRmllbGRKb2luQ291bnRlcisrOwogICAgICAgIH0KICAgIH0KCiAgICAjIEV4ZWN1dGUgYSBkeW5hbWljIGZpZWxkIHNlYXJjaCwgaWYgYSBkeW5hbWljIGZpZWxkIHdoZXJlIHN0YXRlbWVudCBleGlzdHMuCiAgICBpZiAoJFNRTER5bmFtaWNGaWVsZFdoZXJlKSB7CgogICAgICAgIG15IEBEeW5hbWljRmllbGRVc2VyTG9naW5zOwoKICAgICAgICAjIHNxbCB1ZXJ5IGZvciB0aGUgZHluYW1pYyBmaWVsZHMKICAgICAgICBteSAkU1FMRHluYW1pY0ZpZWxkCiAgICAgICAgICAgID0gIlNFTEVDVCBESVNUSU5DVChkZl9vYmpfaWRfbmFtZS5vYmplY3RfbmFtZSkgRlJPTSBkeW5hbWljX2ZpZWxkX29ial9pZF9uYW1lIGRmX29ial9pZF9uYW1lICIKICAgICAgICAgICAgLiAkU1FMRHluYW1pY0ZpZWxkRnJvbQogICAgICAgICAgICAuICIgV0hFUkUgIgogICAgICAgICAgICAuICRTUUxEeW5hbWljRmllbGRXaGVyZTsKCiAgICAgICAgbXkgJFVzZWRDYWNoZTsKCiAgICAgICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKCiAgICAgICAgICAgIG15ICREeW5hbWljRmllbGRTZWFyY2hDYWNoZURhdGEgPSAkU2VsZi0+e0NhY2hlT2JqZWN0fS0+R2V0KAogICAgICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0gLiAnX0N1c3RvbWVyU2VhcmNoRGV0YWlsRHluYW1pY0ZpZWxkcycsCiAgICAgICAgICAgICAgICBLZXkgID0+ICRTUUxEeW5hbWljRmllbGQsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoIGRlZmluZWQgJER5bmFtaWNGaWVsZFNlYXJjaENhY2hlRGF0YSApIHsKICAgICAgICAgICAgICAgIGlmICggcmVmICREeW5hbWljRmllbGRTZWFyY2hDYWNoZURhdGEgZXEgJ0FSUkFZJyApIHsKICAgICAgICAgICAgICAgICAgICBARHluYW1pY0ZpZWxkVXNlckxvZ2lucyA9IEB7JER5bmFtaWNGaWVsZFNlYXJjaENhY2hlRGF0YX07CgogICAgICAgICAgICAgICAgICAgICMgc2V0IHRoZSB1c2VkIGNhY2hlIGZsYWcKICAgICAgICAgICAgICAgICAgICAkVXNlZENhY2hlID0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAnSW52YWxpZCByZWYgJyAuIHJlZigkRHluYW1pY0ZpZWxkU2VhcmNoQ2FjaGVEYXRhKSAuICchJwogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjIEdldCB0aGUgZGF0YSBvbmx5IGZyb20gZGF0YWJhc2UsIGlmIG5vIGNhY2hlIGVudHJ5IGV4aXN0cy4KICAgICAgICBpZiAoICEkVXNlZENhY2hlICkgewoKICAgICAgICAgICAgcmV0dXJuIGlmICEkREJPYmplY3QtPlByZXBhcmUoCiAgICAgICAgICAgICAgICBTUUwgPT4gJFNRTER5bmFtaWNGaWVsZCwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHdoaWxlICggbXkgQFJvdyA9ICREQk9iamVjdC0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICAgICAgICAgcHVzaCBARHluYW1pY0ZpZWxkVXNlckxvZ2lucywgJFJvd1swXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICAgICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgICAgICAgICAgVHlwZSAgPT4gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lclNlYXJjaERldGFpbER5bmFtaWNGaWVsZHMnLAogICAgICAgICAgICAgICAgICAgIEtleSAgID0+ICRTUUxEeW5hbWljRmllbGQsCiAgICAgICAgICAgICAgICAgICAgVmFsdWUgPT4gXEBEeW5hbWljRmllbGRVc2VyTG9naW5zLAogICAgICAgICAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0NhY2hlVFRMfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgQWRkIHRoZSB1c2VyIGxvZ2lucyBmcm9tIHRoZSBkeW5hbWljIGZpZWxkcywgaWYgYSBzZWFyY2ggcmVzdWx0IGV4aXN0cyBmcm9tIHRoZSBkeW5hbWljIGZpZWxkIHNlYXJjaAogICAgICAgICMgICBvciBza2lwIHRoZSBzZWFyY2ggYW5kIHJldHVybiBhIGVtcHRyeSBhcnJheSByZWYsIGlmIG5vIHVzZXIgbG9naW5zIGV4aXN0cyBmcm9tIHRoZSBkeW5hbWljIGZpZWxkIHNlYXJjaC4KICAgICAgICBpZiAoQER5bmFtaWNGaWVsZFVzZXJMb2dpbnMpIHsKCiAgICAgICAgICAgIG15ICREeW5hbWljRmllbGRVc2VyTG9naW5zRmlsdGVyID0gJyh8JzsKICAgICAgICAgICAgZm9yIG15ICRPbmVQYXJhbSAoQER5bmFtaWNGaWVsZFVzZXJMb2dpbnMpIHsKICAgICAgICAgICAgICAgICREeW5hbWljRmllbGRVc2VyTG9naW5zRmlsdGVyIC49ICIoJFNlbGYtPntDdXN0b21lcktleX09IiAuICRTZWxmLT5fQ29udmVydFRvKCRPbmVQYXJhbSkgLiAiKSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJER5bmFtaWNGaWVsZFVzZXJMb2dpbnNGaWx0ZXIgLj0gJyknOwoKICAgICAgICAgICAgIyBBZGQgdGhlIGR5bmFtaWMgZmllbGQgdXNlciBsb2dpbnMgZmlsdGVyIHRvIHRoZSBsZGFwIGZpbHRlci4KICAgICAgICAgICAgJEZpbHRlciA9ICIoJiRGaWx0ZXIkRHluYW1pY0ZpZWxkVXNlckxvZ2luc0ZpbHRlcikiOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuICRSZXN1bHQgZXEgJ0NPVU5UJyA/IDAgOiBbXTsKICAgICAgICB9CiAgICB9CgogICAgIyBTcGVjaWFsIHBhcmFtZXRlciB0byBleGNsdWRlIHNvbWUgdXNlciBsb2dpbnMgZnJvbSB0aGUgc2VhcmNoIHJlc3VsdC4KICAgIGlmICggSXNBcnJheVJlZldpdGhEYXRhKCAkUGFyYW17RXhjbHVkZVVzZXJMb2dpbnN9ICkgKSB7CiAgICAgICAgbXkgJEV4Y2x1ZGVVc2VyTG9naW5zRmlsdGVyID0gJygmJzsKICAgICAgICBmb3IgbXkgJE9uZVBhcmFtICggQHsgJFBhcmFte0V4Y2x1ZGVVc2VyTG9naW5zfSB9ICkgewogICAgICAgICAgICAkRXhjbHVkZVVzZXJMb2dpbnNGaWx0ZXIgLj0gIighKCRTZWxmLT57Q3VzdG9tZXJLZXl9PSIgLiAkU2VsZi0+X0NvbnZlcnRUbygkT25lUGFyYW0pIC4gIikpIjsKICAgICAgICB9CiAgICAgICAgJEV4Y2x1ZGVVc2VyTG9naW5zRmlsdGVyIC49ICcpJzsKCiAgICAgICAgIyBBZGQgdGhlIGV4Y2x1ZGUgdXNlciBsb2dpbnMgZmlsdGVyIHRvIHRoZSBsZGFwIGZpbHRlci4KICAgICAgICAkRmlsdGVyID0gIigmJEZpbHRlciRFeGNsdWRlVXNlckxvZ2luc0ZpbHRlcikiOwogICAgfQoKICAgIGlmICggJFNlbGYtPntBbHdheXNGaWx0ZXJ9ICkgewogICAgICAgICRGaWx0ZXIgPSAiKCYkRmlsdGVyJFNlbGYtPntBbHdheXNGaWx0ZXJ9KSI7CiAgICB9CgogICAgaWYgKCAkU2VsZi0+e1ZhbGlkRmlsdGVyfSAmJiAkVmFsaWQgKSB7CiAgICAgICAgJEZpbHRlciA9ICIoJiRGaWx0ZXIkU2VsZi0+e1ZhbGlkRmlsdGVyfSkiOwogICAgfQoKICAgICMgRGVmYXVsdCBmaWx0ZXIgZm9yIHRoZSBzZWFyY2gsIGlmIG5vIGZpbHRlciBleGlzdHMuCiAgICBpZiAoICEkRmlsdGVyICkgewogICAgICAgICRGaWx0ZXIgPSAiKCRTZWxmLT57Q3VzdG9tZXJLZXl9PSopIjsKICAgIH0KCiAgICAjIENoZWNrIGlmIE9yZGVyQnkgY29udGFpbnMgb25seSB1bmlxdWUgdmFsaWQgdmFsdWVzLgogICAgbXkgJU9yZGVyQnlTZWVuOwogICAgZm9yIG15ICRPcmRlckJ5ICggQHsgJFBhcmFte09yZGVyQnl9IH0gKSB7CgogICAgICAgIGlmICggISRPcmRlckJ5IHx8ICRPcmRlckJ5U2VlbnskT3JkZXJCeX0gKSB7CgogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiT3JkZXJCeSBjb250YWlucyBpbnZhbGlkIHZhbHVlICckT3JkZXJCeScgb3IgdGhlIHZhbHVlIGlzIHVzZWQgbW9yZSB0aGFuIG9uY2UhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgIyBSZW1lbWJlciB0aGUgdmFsdWUgdG8gY2hlY2sgaWYgaXQgYXBwZWFycyBtb3JlIHRoYW4gb25jZS4KICAgICAgICAkT3JkZXJCeVNlZW57JE9yZGVyQnl9ID0gMTsKICAgIH0KCiAgICAjIENoZWNrIGlmIE9yZGVyQnlEaXJlY3Rpb24gYXJyYXkgY29udGFpbnMgb25seSAnVXAnIG9yICdEb3duJy4KICAgIERJUkVDVElPTjoKICAgIGZvciBteSAkRGlyZWN0aW9uICggQHsgJFBhcmFte09yZGVyQnlEaXJlY3Rpb259IH0gKSB7CgogICAgICAgICMgT25seSAnVXAnIG9yICdEb3duJyBhbGxvd2VkLgogICAgICAgIG5leHQgRElSRUNUSU9OIGlmICREaXJlY3Rpb24gZXEgJ1VwJzsKICAgICAgICBuZXh0IERJUkVDVElPTiBpZiAkRGlyZWN0aW9uIGVxICdEb3duJzsKCiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJPcmRlckJ5RGlyZWN0aW9uIGNhbiBvbmx5IGNvbnRhaW4gJ1VwJyBvciAnRG93bichIiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIEFzc2VtYmxlIHRoZSBPUkRFUiBCWSBjbGF1c2UuCiAgICBteSBAT3JkZXJCeUZpZWxkczsKICAgIG15ICRPcmRlckJ5U3RyaW5nID0gJyc7CiAgICBteSAkQ291bnQgICAgICAgICA9IDA7CgogICAgT1JERVJCWToKICAgIGZvciBteSAkT3JkZXJCeSAoIEB7ICRQYXJhbXtPcmRlckJ5fSB9ICkgewogICAgICAgIG5leHQgT1JERVJCWSBpZiAhJE9yZGVyQnlUYWJsZXskT3JkZXJCeX07CgogICAgICAgIG15ICREaXJlY3Rpb24gPSAkUGFyYW17T3JkZXJCeURpcmVjdGlvbn0tPlskQ291bnRdIHx8ICdEb3duJzsKCiAgICAgICAgJE9yZGVyQnlTdHJpbmcgLj0gJE9yZGVyQnlUYWJsZXskT3JkZXJCeX0gLiAkRGlyZWN0aW9uOwoKICAgICAgICBwdXNoIEBPcmRlckJ5RmllbGRzLCB7CiAgICAgICAgICAgIE5hbWUgICAgICAgICAgPT4gJE9yZGVyQnksCiAgICAgICAgICAgIERhdGFiYXNlRmllbGQgPT4gJE9yZGVyQnlUYWJsZXskT3JkZXJCeX0sCiAgICAgICAgICAgIERpcmVjdGlvbiAgICAgPT4gJERpcmVjdGlvbiwKICAgICAgICB9OwogICAgfQogICAgY29udGludWUgewogICAgICAgICRDb3VudCsrOwogICAgfQoKICAgICMgSWYgdGhlcmUgaXMgYSBwb3NzaWJpbGl0eSB0aGF0IHRoZSBvcmRlcmluZyBpcyBub3QgZGV0ZXJtaW5lZAogICAgIyAgIHdlIGFkZCBhbiBkZXNjZW5kaW5nIG9yZGVyaW5nIGJ5IGlkLgogICAgaWYgKCAhZ3JlcCB7ICRfIGVxICdVc2VyTG9naW4nIH0gKCBAeyAkUGFyYW17T3JkZXJCeX0gfSApICkgewogICAgICAgIHB1c2ggQE9yZGVyQnlGaWVsZHMsIHsKICAgICAgICAgICAgTmFtZSAgICAgICAgICA9PiAnVXNlckxvZ2luJywKICAgICAgICAgICAgRGF0YWJhc2VGaWVsZCA9PiAiJFNlbGYtPntDdXN0b21lcktleX0iLAogICAgICAgICAgICBEaXJlY3Rpb24gICAgID0+ICdEb3duJywKICAgICAgICB9OwogICAgfQoKICAgIG15ICRDYWNoZUtleSA9ICdDdXN0b21lclNlYXJjaERldGFpbDo6JyAuICRSZXN1bHQgLiAkRmlsdGVyIC4gJFBhcmFte0xpbWl0fSAuICRPcmRlckJ5U3RyaW5nOwoKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgbXkgJENhY2hlRGF0YSA9ICRTZWxmLT57Q2FjaGVPYmplY3R9LT5HZXQoCiAgICAgICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgICAgICBLZXkgID0+ICRDYWNoZUtleSwKICAgICAgICApOwoKICAgICAgICBpZiAoIGRlZmluZWQgJENhY2hlRGF0YSApIHsKICAgICAgICAgICAgaWYgKCByZWYgJENhY2hlRGF0YSBlcSAnQVJSQVknICkgewogICAgICAgICAgICAgICAgcmV0dXJuICRDYWNoZURhdGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzaWYgKCByZWYgJENhY2hlRGF0YSBlcSAnJyApIHsKICAgICAgICAgICAgICAgIHJldHVybiAkQ2FjaGVEYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdJbnZhbGlkIHJlZiAnIC4gcmVmKCRDYWNoZURhdGEpIC4gJyEnCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGlmICEkU2VsZi0+X0Nvbm5lY3QoKTsKCiAgICAjIGNDbWJpbmUgbmVlZGVkIGF0dHJpYnV0ZXMuCiAgICBteSBAQXR0cmlidXRlcyA9IG1hcCB7ICRfLT57RGF0YWJhc2VGaWVsZH0gfSBAT3JkZXJCeUZpZWxkczsKCiAgICAjIFBlcmZvcm0gdGhlIGxkYXAgdXNlciBzZWFyY2guCiAgICBteSAkUmVzdWx0U2VhcmNoID0gJFNlbGYtPntMREFQfS0+c2VhcmNoKAogICAgICAgIGJhc2UgICAgICA9PiAkU2VsZi0+e0Jhc2VETn0sCiAgICAgICAgc2NvcGUgICAgID0+ICRTZWxmLT57U1Njb3BlfSwKICAgICAgICBmaWx0ZXIgICAgPT4gJEZpbHRlciwKICAgICAgICBzaXplbGltaXQgPT4gJFNlbGYtPntVc2VyU2VhcmNoTGlzdExpbWl0fSwKICAgICAgICBhdHRycyAgICAgPT4gXEBBdHRyaWJ1dGVzLAogICAgKTsKCiAgICBpZiAoICRSZXN1bHRTZWFyY2gtPmNvZGUoKSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJFJlc3VsdFNlYXJjaC0+ZXJyb3IoKSwKICAgICAgICApOwogICAgfQoKICAgIG15IEBUbXBDdXN0b21lclVzZXJzOwogICAgZm9yIG15ICRFbnRyeSAoICRSZXN1bHRTZWFyY2gtPmFsbF9lbnRyaWVzKCkgKSB7CgogICAgICAgIG15ICVEYXRhOwogICAgICAgIGZvciBteSAkT3JkZXJCeSAoQE9yZGVyQnlGaWVsZHMpIHsKCiAgICAgICAgICAgIG15ICRGaWVsZFZhbHVlID0gJEVudHJ5LT5nZXRfdmFsdWUoICRPcmRlckJ5LT57RGF0YWJhc2VGaWVsZH0gKTsKICAgICAgICAgICAgJEZpZWxkVmFsdWUgPSAkU2VsZi0+X0NvbnZlcnRGcm9tKCRGaWVsZFZhbHVlKTsKCiAgICAgICAgICAgICREYXRheyAkT3JkZXJCeS0+e05hbWV9IH0gPSAkRmllbGRWYWx1ZTsKICAgICAgICB9CgogICAgICAgIHB1c2ggQFRtcEN1c3RvbWVyVXNlcnMsIFwlRGF0YTsKICAgIH0KCiAgICAjIFNvcnQgdGhlIGN1c3RvbWVyIHVzZXJzLgogICAgQFRtcEN1c3RvbWVyVXNlcnMgPSBzb3J0IHsgJFNlbGYtPl9TZWFyY2hSZXN1bHRTb3J0KEBPcmRlckJ5RmllbGRzKSB9IEBUbXBDdXN0b21lclVzZXJzOwoKICAgIG15IEBJRHM7CgogICAgIyBDaGVjayBpZiB1c2VyIG5lZWQgdG8gYmUgaW4gYSBncm91cCEKICAgIGlmICggJFNlbGYtPntHcm91cEROfSApIHsKCiAgICAgICAgRklMVEVSSUQ6CiAgICAgICAgZm9yIG15ICREYXRhIChAVG1wQ3VzdG9tZXJVc2VycykgewoKICAgICAgICAgICAgbXkgJFJlc3VsdEdyb3VwRE4gPSAkU2VsZi0+e0xEQVB9LT5zZWFyY2goCiAgICAgICAgICAgICAgICBiYXNlICAgICAgPT4gJFNlbGYtPntHcm91cEROfSwKICAgICAgICAgICAgICAgIHNjb3BlICAgICA9PiAkU2VsZi0+e1NTY29wZX0sCiAgICAgICAgICAgICAgICBmaWx0ZXIgICAgPT4gJ21lbWJlclVpZD0nIC4gJERhdGEtPntVc2VyTG9naW59LAogICAgICAgICAgICAgICAgc2l6ZWxpbWl0ID0+ICRTZWxmLT57VXNlclNlYXJjaExpc3RMaW1pdH0sCiAgICAgICAgICAgICAgICBhdHRycyAgICAgPT4gWycxLjEnXSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIG5leHQgRklMVEVSSUQgaWYgISRSZXN1bHRHcm91cEROLT5hbGxfZW50cmllcygpOwoKICAgICAgICAgICAgcHVzaCBASURzLCAkRGF0YS0+e1VzZXJMb2dpbn07CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgQElEcyA9IG1hcCB7ICRfLT57VXNlckxvZ2lufSB9IEBUbXBDdXN0b21lclVzZXJzOwogICAgfQoKICAgIGlmICggJFBhcmFte0xpbWl0fSApIHsKICAgICAgICBzcGxpY2UgQElEcywgJFBhcmFte0xpbWl0fTsKICAgIH0KCiAgICBpZiAoICRSZXN1bHQgZXEgJ0NPVU5UJyApIHsKCiAgICAgICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICAgICAgICAgIEtleSAgID0+ICRDYWNoZUtleSwKICAgICAgICAgICAgICAgIFZhbHVlID0+IHNjYWxhciBASURzLAogICAgICAgICAgICAgICAgVFRMICAgPT4gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q2FjaGVUVEx9LAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2NhbGFyIEBJRHM7CiAgICB9CiAgICBlbHNlIHsKCiAgICAgICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICAgICAgICAgIEtleSAgID0+ICRDYWNoZUtleSwKICAgICAgICAgICAgICAgIFZhbHVlID0+IFxASURzLAogICAgICAgICAgICAgICAgVFRMICAgPT4gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q2FjaGVUVEx9LAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICByZXR1cm4gXEBJRHM7CiAgICB9Cn0KCnN1YiBDdXN0b21lcklETGlzdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRWYWxpZCAgICAgID0gZGVmaW5lZCAkUGFyYW17VmFsaWR9ID8gJFBhcmFte1ZhbGlkfSA6IDE7CiAgICBteSAkU2VhcmNoVGVybSA9ICRQYXJhbXtTZWFyY2hUZXJtfSB8fCAnJzsKCiAgICBteSAkQ2FjaGVLZXkgPSAiQ3VzdG9tZXJJRExpc3Q6OiR7VmFsaWR9OjokU2VhcmNoVGVybSI7CgogICAgIyBjaGVjayBjYWNoZQogICAgaWYgKCAkU2VsZi0+e0NhY2hlT2JqZWN0fSApIHsKICAgICAgICBteSAkUmVzdWx0ID0gJFNlbGYtPntDYWNoZU9iamVjdH0tPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gJENhY2hlS2V5LAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIEB7JFJlc3VsdH0gaWYgcmVmICRSZXN1bHQgZXEgJ0FSUkFZJzsKICAgIH0KCiAgICAjIHByZXBhcmUgZmlsdGVyCiAgICBteSAkRmlsdGVyID0gIigkU2VsZi0+e0N1c3RvbWVySUR9PSopIjsKICAgIGlmICgkU2VhcmNoVGVybSkgewoKICAgICAgICBteSAkU2VhcmNoRmlsdGVyID0gJFNlbGYtPntTZWFyY2hQcmVmaXh9IC4gJFNlYXJjaFRlcm0gLiAkU2VsZi0+e1NlYXJjaFN1ZmZpeH07CiAgICAgICAgJFNlYXJjaEZpbHRlciA9fiBzLyhcJSspL1wlL2c7CiAgICAgICAgJFNlYXJjaEZpbHRlciA9fiBzLyhcKispXCovKi9nOwoKICAgICAgICAjIHF1b3RlIExEQVAgZmlsdGVyIHZhbHVlIGJ1dCBrZWVwIGFzdGVyaXNrcyB1bmVzY2FwZWQgKHdpbGRjYXJkKQogICAgICAgICRTZWFyY2hGaWx0ZXIgPX4gcy9cKi9lbmNvZGVkYXN0ZXJpc2syMDE2MDkzMC9nOwogICAgICAgICRTZWFyY2hGaWx0ZXIgPSBlc2NhcGVfZmlsdGVyX3ZhbHVlKCRTZWFyY2hGaWx0ZXIpOwogICAgICAgICRTZWFyY2hGaWx0ZXIgPX4gcy9lbmNvZGVkYXN0ZXJpc2syMDE2MDkzMC8qL2c7CgogICAgICAgICRGaWx0ZXIgPSAiKCRTZWxmLT57Q3VzdG9tZXJJRH09JFNlYXJjaEZpbHRlcikiOwoKICAgIH0KCiAgICBpZiAoICRTZWxmLT57QWx3YXlzRmlsdGVyfSApIHsKICAgICAgICAkRmlsdGVyID0gIigmJEZpbHRlciRTZWxmLT57QWx3YXlzRmlsdGVyfSkiOwogICAgfQoKICAgICMgYWRkIHZhbGlkIGZpbHRlcgogICAgaWYgKCAkU2VsZi0+e1ZhbGlkRmlsdGVyfSAmJiAkVmFsaWQgKSB7CiAgICAgICAgJEZpbHRlciA9ICIoJiRGaWx0ZXIkU2VsZi0+e1ZhbGlkRmlsdGVyfSkiOwogICAgfQoKICAgICMgY3JlYXRlIGxkYXAgY29ubmVjdAogICAgcmV0dXJuIGlmICEkU2VsZi0+X0Nvbm5lY3QoKTsKCiAgICAjIGNvbWJpbmUgbmVlZGVkIGF0dHJzCiAgICBteSBAQXR0cmlidXRlcyA9ICggJFNlbGYtPntDdXN0b21lcktleX0sICRTZWxmLT57Q3VzdG9tZXJJRH0gKTsKCiAgICAjIHBlcmZvcm0gdXNlciBzZWFyY2gKICAgIG15ICRSZXN1bHQgPSAkU2VsZi0+e0xEQVB9LT5zZWFyY2goCiAgICAgICAgYmFzZSAgICAgID0+ICRTZWxmLT57QmFzZUROfSwKICAgICAgICBzY29wZSAgICAgPT4gJFNlbGYtPntTU2NvcGV9LAogICAgICAgIGZpbHRlciAgICA9PiAkRmlsdGVyLAogICAgICAgIHNpemVsaW1pdCA9PiAkU2VsZi0+e1VzZXJTZWFyY2hMaXN0TGltaXR9LAogICAgICAgIGF0dHJzICAgICA9PiBcQEF0dHJpYnV0ZXMsCiAgICApOwoKICAgICMgbG9nIGxkYXAgZXJyb3JzCiAgICBpZiAoICRSZXN1bHQtPmNvZGUoKSApIHsKCiAgICAgICAgaWYgKCAkUmVzdWx0LT5jb2RlKCkgPT0gNCApIHsKCiAgICAgICAgICAgICMgUmVzdWx0IGNvZGUgNCAoTERBUF9TSVpFTElNSVRfRVhDRUVERUQpIGlzIG5vcm1hbCBpZiB0aGVyZQogICAgICAgICAgICAjIGFyZSBtb3JlIGl0ZW1zIGluIExEQVAgdGhhbiBzZWFyY2ggbGltaXQgZGVmaW5lZCBpbiBPVFJTIG9yCiAgICAgICAgICAgICMgaW4gTERBUCBzZXJ2ZXIuIEF2b2lkIHNwYW1taW5nIGxvZ3Mgd2l0aCBzdWNoIGVycm9ycy4KICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0xEQVAgc2l6ZSBsaW1pdCBleGNlZWRlZCAoJyAuICRSZXN1bHQtPmVycm9yKCkgLiAnKS4nLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ1NlYXJjaCBmYWlsZWQhICcgLiAkUmVzdWx0LT5lcnJvcigpLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICBteSAlVXNlcnM7CiAgICBmb3IgbXkgJEVudHJ5ICggJFJlc3VsdC0+YWxsX2VudHJpZXMoKSApIHsKCiAgICAgICAgbXkgJEZpZWxkVmFsdWUgPSAkRW50cnktPmdldF92YWx1ZSggJFNlbGYtPntDdXN0b21lcklEfSApOwogICAgICAgICRGaWVsZFZhbHVlID0gZGVmaW5lZCAkRmllbGRWYWx1ZSA/ICRGaWVsZFZhbHVlIDogJyc7CgogICAgICAgIG15ICRLZXlWYWx1ZSA9ICRFbnRyeS0+Z2V0X3ZhbHVlKCAkU2VsZi0+e0N1c3RvbWVyS2V5fSApOwogICAgICAgICRLZXlWYWx1ZSA9IGRlZmluZWQgJEtleVZhbHVlID8gJEtleVZhbHVlIDogJyc7CiAgICAgICAgJFVzZXJzeyAkU2VsZi0+X0NvbnZlcnRGcm9tKCRLZXlWYWx1ZSkgfSA9ICRTZWxmLT5fQ29udmVydEZyb20oJEZpZWxkVmFsdWUpOwogICAgfQoKICAgICMgY2hlY2sgaWYgdXNlciBuZWVkIHRvIGJlIGluIGEgZ3JvdXAhCiAgICBpZiAoICRTZWxmLT57R3JvdXBETn0gKSB7CiAgICAgICAgZm9yIG15ICRGaWx0ZXIyICggc29ydCBrZXlzICVVc2VycyApIHsKICAgICAgICAgICAgbXkgJFJlc3VsdDIgPSAkU2VsZi0+e0xEQVB9LT5zZWFyY2goCiAgICAgICAgICAgICAgICBiYXNlICAgICAgPT4gJFNlbGYtPntHcm91cEROfSwKICAgICAgICAgICAgICAgIHNjb3BlICAgICA9PiAkU2VsZi0+e1NTY29wZX0sCiAgICAgICAgICAgICAgICBmaWx0ZXIgICAgPT4gJ21lbWJlclVpZD0nIC4gZXNjYXBlX2ZpbHRlcl92YWx1ZSgkRmlsdGVyMiksCiAgICAgICAgICAgICAgICBzaXplbGltaXQgPT4gJFNlbGYtPntVc2VyU2VhcmNoTGlzdExpbWl0fSwKICAgICAgICAgICAgICAgIGF0dHJzICAgICA9PiBbJzEuMSddLAogICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoICEkUmVzdWx0Mi0+YWxsX2VudHJpZXMoKSApIHsKICAgICAgICAgICAgICAgIGRlbGV0ZSAkVXNlcnN7JEZpbHRlcjJ9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICMgbWFrZSBDdXN0b21lcklEcyB1bmlxdWUKICAgIG15ICVUbXA7CiAgICBAVG1weyB2YWx1ZXMgJVVzZXJzIH0gPSB1bmRlZjsKICAgIG15IEBSZXN1bHQgPSBrZXlzICVUbXA7CgogICAgIyBjYWNoZSByZXF1ZXN0CiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICAgICAgS2V5ICAgPT4gJENhY2hlS2V5LAogICAgICAgICAgICBWYWx1ZSA9PiBcQFJlc3VsdCwKICAgICAgICAgICAgVFRMICAgPT4gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q2FjaGVUVEx9LAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuIEBSZXN1bHQ7Cn0KCnN1YiBDdXN0b21lcklEcyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VXNlcn0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXIhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY2hlY2sgY2FjaGUKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgbXkgJEN1c3RvbWVySURzID0gJFNlbGYtPntDYWNoZU9iamVjdH0tPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gIkN1c3RvbWVySURzOjokUGFyYW17VXNlcn0iLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIEB7JEN1c3RvbWVySURzfSBpZiByZWYgJEN1c3RvbWVySURzIGVxICdBUlJBWSc7CiAgICB9CgogICAgIyBnZXQgY3VzdG9tZXIgZGF0YQogICAgbXkgJURhdGEgPSAkU2VsZi0+Q3VzdG9tZXJVc2VyRGF0YUdldCgKICAgICAgICBVc2VyID0+ICRQYXJhbXtVc2VyfSwKICAgICk7CgogICAgIyB0aGVyZSBhcmUgbXVsdGkgY3VzdG9tZXIgaWRzCiAgICBteSBAQ3VzdG9tZXJJRHM7CiAgICBpZiAoICREYXRhe1VzZXJDdXN0b21lcklEc30gKSB7CgogICAgICAgICMgdXNlZCBzZXBhcmF0b3JzCiAgICAgICAgU0VQQVJBVE9SOgogICAgICAgIGZvciBteSAkU2VwYXJhdG9yICggJzsnLCAnLCcsICd8JyApIHsKCiAgICAgICAgICAgIG5leHQgU0VQQVJBVE9SIGlmICREYXRhe1VzZXJDdXN0b21lcklEc30gIX4gL1xRJFNlcGFyYXRvclxFLzsKCiAgICAgICAgICAgICMgc3BsaXQgaXQKICAgICAgICAgICAgbXkgQElEcyA9IHNwbGl0IC9cUSRTZXBhcmF0b3JcRS8sICREYXRhe1VzZXJDdXN0b21lcklEc307CgogICAgICAgICAgICBmb3IgbXkgJElEIChASURzKSB7CiAgICAgICAgICAgICAgICAkSUQgPX4gcy9eXHMrLy9nOwogICAgICAgICAgICAgICAgJElEID1+IHMvXHMrJC8vZzsKICAgICAgICAgICAgICAgIHB1c2ggQEN1c3RvbWVySURzLCAkSUQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxhc3QgU0VQQVJBVE9SOwogICAgICAgIH0KCiAgICAgICAgIyBmYWxsYmFjayBpZiBubyBzZXBhcmF0b3IgZ290IGZvdW5kCiAgICAgICAgaWYgKCAhQEN1c3RvbWVySURzICkgewogICAgICAgICAgICAkRGF0YXtVc2VyQ3VzdG9tZXJJRHN9ID1+IHMvXlxzKy8vZzsKICAgICAgICAgICAgJERhdGF7VXNlckN1c3RvbWVySURzfSA9fiBzL1xzKyQvL2c7CiAgICAgICAgICAgIHB1c2ggQEN1c3RvbWVySURzLCAkRGF0YXtVc2VyQ3VzdG9tZXJJRHN9OwogICAgICAgIH0KICAgIH0KCiAgICAjIHVzZSBhbHNvIHRoZSBwcmltYXJ5IGN1c3RvbWVyIGlkCiAgICBpZiAoICREYXRhe1VzZXJDdXN0b21lcklEfSAmJiAhJFNlbGYtPntFeGNsdWRlUHJpbWFyeUN1c3RvbWVySUR9ICkgewogICAgICAgIHB1c2ggQEN1c3RvbWVySURzLCAkRGF0YXtVc2VyQ3VzdG9tZXJJRH07CiAgICB9CgogICAgIyBjYWNoZSByZXF1ZXN0CiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5TZXQoCiAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICAgICAgS2V5ICAgPT4gJ0N1c3RvbWVySURzOjonIC4gJFBhcmFte1VzZXJ9LAogICAgICAgICAgICBWYWx1ZSA9PiBcQEN1c3RvbWVySURzLAogICAgICAgICAgICBUVEwgICA9PiAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntDYWNoZVRUTH0sCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gQEN1c3RvbWVySURzOwp9CgpzdWIgQ3VzdG9tZXJVc2VyRGF0YUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VXNlcn0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXIhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgcGVyZm9ybSB1c2VyIHNlYXJjaAogICAgbXkgQEF0dHJpYnV0ZXM7CiAgICBFTlRSWToKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9IH0gKSB7CiAgICAgICAgbmV4dCBFTlRSWSBpZiAkRW50cnktPls1XSBlcSAnZHluYW1pY19maWVsZCc7CiAgICAgICAgcHVzaCggQEF0dHJpYnV0ZXMsICRFbnRyeS0+WzJdICk7CiAgICB9CiAgICBteSAkRmlsdGVyID0gIigkU2VsZi0+e0N1c3RvbWVyS2V5fT0iIC4gZXNjYXBlX2ZpbHRlcl92YWx1ZSggJFBhcmFte1VzZXJ9ICkgLiAnKSc7CgogICAgIyBwcmVwYXJlIGZpbHRlcgogICAgaWYgKCAkU2VsZi0+e0Fsd2F5c0ZpbHRlcn0gKSB7CiAgICAgICAgJEZpbHRlciA9ICIoJiRGaWx0ZXIkU2VsZi0+e0Fsd2F5c0ZpbHRlcn0pIjsKICAgIH0KCiAgICAjIGNoZWNrIGNhY2hlCiAgICBpZiAoICRTZWxmLT57Q2FjaGVPYmplY3R9ICkgewogICAgICAgIG15ICREYXRhID0gJFNlbGYtPntDYWNoZU9iamVjdH0tPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gJ0N1c3RvbWVyVXNlckRhdGFHZXQ6OicgLiAkUGFyYW17VXNlcn0sCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gJXskRGF0YX0gaWYgcmVmICREYXRhIGVxICdIQVNIJzsKICAgIH0KCiAgICAjIGNyZWF0ZSBsZGFwIGNvbm5lY3QKICAgIHJldHVybiBpZiAhJFNlbGYtPl9Db25uZWN0KCk7CgogICAgIyBwZXJmb3JtIHNlYXJjaAogICAgbXkgJFJlc3VsdCA9ICRTZWxmLT57TERBUH0tPnNlYXJjaCgKICAgICAgICBiYXNlICAgPT4gJFNlbGYtPntCYXNlRE59LAogICAgICAgIHNjb3BlICA9PiAkU2VsZi0+e1NTY29wZX0sCiAgICAgICAgZmlsdGVyID0+ICRGaWx0ZXIsCiAgICAgICAgYXR0cnMgID0+IFxAQXR0cmlidXRlcywKICAgICk7CgogICAgIyBsb2cgbGRhcCBlcnJvcnMKICAgIGlmICggJFJlc3VsdC0+Y29kZSgpICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAkUmVzdWx0LT5lcnJvcigpLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgZ2V0IGZpcnN0IGVudHJ5CiAgICBteSAkUmVzdWx0MiA9ICRSZXN1bHQtPmVudHJ5KDApOwogICAgaWYgKCAhJFJlc3VsdDIgKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgZ2V0IGN1c3RvbWVyIHVzZXIgaW5mbwogICAgbXkgJURhdGE7CiAgICBFTlRSWToKICAgIGZvciBteSAkRW50cnkgKCBAeyAkU2VsZi0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9IH0gKSB7CiAgICAgICAgbmV4dCBFTlRSWSBpZiAkRW50cnktPls1XSBlcSAnZHluYW1pY19maWVsZCc7CgogICAgICAgIG15ICRWYWx1ZSA9ICRTZWxmLT5fQ29udmVydEZyb20oICRSZXN1bHQyLT5nZXRfdmFsdWUoICRFbnRyeS0+WzJdICkgKSB8fCAnJzsKCiAgICAgICAgaWYgKCAkVmFsdWUgJiYgJEVudHJ5LT5bMl0gPX4gL150YXJnZXRhZGRyZXNzJC9pICkgewogICAgICAgICAgICAkVmFsdWUgPX4gcy9TTVRQOiguKikvJDEvOwogICAgICAgIH0KCiAgICAgICAgJERhdGF7ICRFbnRyeS0+WzBdIH0gPSAkVmFsdWU7CiAgICB9CgogICAgcmV0dXJuIGlmICEkRGF0YXtVc2VyTG9naW59OwoKICAgICMgdG8gYnVpbGQgdGhlIFVzZXJNYWlsU3RyaW5nCiAgICBteSAkVXNlck1haWxTdHJpbmcgPSAnJzsKICAgIG15IEBVc2VyTWFpbFN0cmluZ1BhcnRzOwoKICAgIG15ICRDdXN0b21lclVzZXJMaXN0RmllbGRzTWFwID0gJFNlbGYtPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJVc2VyTGlzdEZpZWxkc307CiAgICBpZiAoICFJc0FycmF5UmVmV2l0aERhdGEoJEN1c3RvbWVyVXNlckxpc3RGaWVsZHNNYXApICkgewogICAgICAgICRDdXN0b21lclVzZXJMaXN0RmllbGRzTWFwID0gWyAnZmlyc3RfbmFtZScsICdsYXN0X25hbWUnLCAnZW1haWwnLCBdOwogICAgfQoKICAgIGZvciBteSAkRmllbGQgKCBAeyRDdXN0b21lclVzZXJMaXN0RmllbGRzTWFwfSApIHsKCiAgICAgICAgbXkgJFZhbHVlID0gJFNlbGYtPl9Db252ZXJ0RnJvbSggJFJlc3VsdDItPmdldF92YWx1ZSgkRmllbGQpICkgfHwgJyc7CgogICAgICAgIGlmICgkVmFsdWUpIHsKICAgICAgICAgICAgaWYgKCAkRmllbGQgPX4gL150YXJnZXRhZGRyZXNzJC9pICkgewogICAgICAgICAgICAgICAgJFZhbHVlID1+IHMvU01UUDooLiopLyQxLzsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdXNoIEBVc2VyTWFpbFN0cmluZ1BhcnRzLCAkVmFsdWU7CiAgICAgICAgfQogICAgfQogICAgJFVzZXJNYWlsU3RyaW5nID0gam9pbiAnICcsIEBVc2VyTWFpbFN0cmluZ1BhcnRzOwogICAgJFVzZXJNYWlsU3RyaW5nID1+IHMvXiguKilccyguKz9cQC4rP1wuLis/KShcc3wpJC8iJDEiIDwkMj4vOwoKICAgICMgYWRkIHRoZSBVc2VyTWFpbFN0cmluZyB0byB0aGUgZGF0YSBoYXNoCiAgICAkRGF0YXtVc2VyTWFpbFN0cmluZ30gPSAkVXNlck1haWxTdHJpbmc7CgogICAgIyBjb21wYXQhCiAgICAkRGF0YXtVc2VySUR9ID0gJERhdGF7VXNlckxvZ2lufTsKCiAgICAjIGdldCBwcmVmZXJlbmNlcwogICAgbXkgJVByZWZlcmVuY2VzID0gJFNlbGYtPkdldFByZWZlcmVuY2VzKCBVc2VySUQgPT4gJERhdGF7VXNlckxvZ2lufSApOwoKICAgICMgYWRkIGxhc3QgbG9naW4gdGltZXN0YW1wCiAgICBpZiAoICRQcmVmZXJlbmNlc3tVc2VyTGFzdExvZ2lufSApIHsKCiAgICAgICAgbXkgJERhdGVUaW1lT2JqZWN0ID0gJEtlcm5lbDo6T00tPkNyZWF0ZSgKICAgICAgICAgICAgJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScsCiAgICAgICAgICAgIE9iamVjdFBhcmFtcyA9PiB7CiAgICAgICAgICAgICAgICBFcG9jaCA9PiAkUHJlZmVyZW5jZXN7VXNlckxhc3RMb2dpbn0sCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKCiAgICAgICAgJFByZWZlcmVuY2Vze1VzZXJMYXN0TG9naW5UaW1lc3RhbXB9ID0gJERhdGVUaW1lT2JqZWN0LT5Ub1N0cmluZygpOwoKICAgIH0KCiAgICAjIGNhY2hlIHJlcXVlc3QKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPlNldCgKICAgICAgICAgICAgVHlwZSAgPT4gJFNlbGYtPntDYWNoZVR5cGV9LAogICAgICAgICAgICBLZXkgICA9PiAnQ3VzdG9tZXJVc2VyRGF0YUdldDo6JyAuICRQYXJhbXtVc2VyfSwKICAgICAgICAgICAgVmFsdWUgPT4geyAlRGF0YSwgJVByZWZlcmVuY2VzIH0sCiAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q3VzdG9tZXJVc2VyTWFwfS0+e0NhY2hlVFRMfSwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAoICVEYXRhLCAlUHJlZmVyZW5jZXMgKTsKfQoKc3ViIEN1c3RvbWVyVXNlckFkZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgcm8vcncKICAgIGlmICggJFNlbGYtPntSZWFkT25seX0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdDdXN0b21lciBiYWNrZW5kIGlzIHJlYWQgb25seSEnCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICBNZXNzYWdlICA9PiAnTm90IHN1cHBvcnRlZCBmb3IgdGhpcyBtb2R1bGUhJwogICAgKTsKCiAgICByZXR1cm47Cn0KCnN1YiBDdXN0b21lclVzZXJVcGRhdGUgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIHJvL3J3CiAgICBpZiAoICRTZWxmLT57UmVhZE9ubHl9ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnQ3VzdG9tZXIgYmFja2VuZCBpcyByZWFkIG9ubHkhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgTWVzc2FnZSAgPT4gJ05vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgbW9kdWxlIScKICAgICk7CgogICAgcmV0dXJuOwp9CgpzdWIgU2V0UGFzc3dvcmQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkUHcgPSAkUGFyYW17UFd9IHx8ICcnOwoKICAgICMgY2hlY2sgcm8vcncKICAgIGlmICggJFNlbGYtPntSZWFkT25seX0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdDdXN0b21lciBiYWNrZW5kIGlzIHJlYWQgb25seSEnCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICBNZXNzYWdlICA9PiAnTm90IHN1cHBvcnRlZCBmb3IgdGhpcyBtb2R1bGUhJwogICAgKTsKCiAgICByZXR1cm47Cn0KCnN1YiBHZW5lcmF0ZVJhbmRvbVBhc3N3b3JkIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgcmV0dXJuICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpNYWluJyktPkdlbmVyYXRlUmFuZG9tU3RyaW5nKAogICAgICAgIExlbmd0aCAgICAgPT4gJFBhcmFte1NpemV9IHx8IDgsCiAgICAgICAgRGljdGlvbmFyeSA9PiBbIDAgLi4gOSwgJ0EnIC4uICdaJywgJ2EnIC4uICd6JywgJy0nLCAnXycsICchJywgJ0AnLCAnIycsICckJywgJyUnLCAnXicsICcmJywgJyonIF0sCiAgICApOwp9CgpzdWIgU2V0UHJlZmVyZW5jZXMgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBwYXJhbXMKICAgIGlmICggISRQYXJhbXtVc2VySUR9ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBVc2VySUQhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY2FjaGUgcmVzZXQKICAgIGlmICggJFNlbGYtPntDYWNoZU9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntDYWNoZU9iamVjdH0tPkRlbGV0ZSgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gIkN1c3RvbWVyVXNlckRhdGFHZXQ6OiRQYXJhbXtVc2VySUR9IiwKICAgICAgICApOwogICAgfQogICAgcmV0dXJuICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9LT5TZXRQcmVmZXJlbmNlcyglUGFyYW0pOwp9CgpzdWIgR2V0UHJlZmVyZW5jZXMgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBwYXJhbXMKICAgIGlmICggISRQYXJhbXtVc2VySUR9ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBVc2VySUQhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHJldHVybiAkU2VsZi0+e1ByZWZlcmVuY2VzT2JqZWN0fS0+R2V0UHJlZmVyZW5jZXMoJVBhcmFtKTsKfQoKc3ViIFNlYXJjaFByZWZlcmVuY2VzIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgcmV0dXJuICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9LT5TZWFyY2hQcmVmZXJlbmNlcyglUGFyYW0pOwp9CgpzdWIgX0NvbnZlcnRGcm9tIHsKICAgIG15ICggJFNlbGYsICRUZXh0ICkgPSBAXzsKCiAgICByZXR1cm4gaWYgIWRlZmluZWQgJFRleHQ7CgogICAgaWYgKCAhJFNlbGYtPntTb3VyY2VDaGFyc2V0fSApIHsKICAgICAgICByZXR1cm4gJFRleHQ7CiAgICB9CgogICAgcmV0dXJuICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpFbmNvZGUnKS0+Q29udmVydCgKICAgICAgICBUZXh0ID0+ICRUZXh0LAogICAgICAgIEZyb20gPT4gJFNlbGYtPntTb3VyY2VDaGFyc2V0fSwKICAgICAgICBUbyAgID0+ICd1dGYtOCcsCiAgICApOwp9CgpzdWIgX0NvbnZlcnRUbyB7CiAgICBteSAoICRTZWxmLCAkVGV4dCApID0gQF87CgogICAgcmV0dXJuIGlmICFkZWZpbmVkICRUZXh0OwoKICAgICMgZ2V0IGVuY29kZSBvYmplY3QKICAgIG15ICRFbmNvZGVPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RW5jb2RlJyk7CgogICAgaWYgKCAhJFNlbGYtPntTb3VyY2VDaGFyc2V0fSApIHsKICAgICAgICAkRW5jb2RlT2JqZWN0LT5FbmNvZGVJbnB1dCggXCRUZXh0ICk7CiAgICAgICAgcmV0dXJuICRUZXh0OwogICAgfQoKICAgIHJldHVybiAkRW5jb2RlT2JqZWN0LT5Db252ZXJ0KAogICAgICAgIFRleHQgPT4gJFRleHQsCiAgICAgICAgVG8gICA9PiAkU2VsZi0+e1NvdXJjZUNoYXJzZXR9LAogICAgICAgIEZyb20gPT4gJ3V0Zi04JywKICAgICk7Cn0KCnN1YiBfQ3VzdG9tZXJVc2VyQ2FjaGVDbGVhciB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIHJldHVybiBpZiAhJFNlbGYtPntDYWNoZU9iamVjdH07CgogICAgaWYgKCAhJFBhcmFte1VzZXJMb2dpbn0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXJMb2dpbiEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5EZWxldGUoCiAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgS2V5ICA9PiAiQ3VzdG9tZXJVc2VyRGF0YUdldDo6JFBhcmFte1VzZXJMb2dpbn0iLAogICAgKTsKICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5EZWxldGUoCiAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgS2V5ICA9PiAiQ3VzdG9tZXJOYW1lOjokUGFyYW17VXNlckxvZ2lufSIsCiAgICApOwoKICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5DbGVhblVwKAogICAgICAgIFR5cGUgPT4gJFNlbGYtPntDYWNoZVR5cGV9IC4gJ19DdXN0b21lclNlYXJjaCcsCiAgICApOwoKICAgICRTZWxmLT57Q2FjaGVPYmplY3R9LT5DbGVhblVwKAogICAgICAgIFR5cGUgPT4gJ0N1c3RvbWVyR3JvdXAnLAogICAgKTsKCiAgICByZXR1cm4gMTsKfQoKc3ViIF9TZWFyY2hSZXN1bHRTb3J0IHsKICAgIG15ICggJFNlbGYsIEBPcmRlckJ5RmllbGRzICkgPSBAXzsKCiAgICBmb3IgbXkgJE9yZGVyQnkgKEBPcmRlckJ5RmllbGRzKSB7CiAgICAgICAgbXkgJENvbXBhcmU7CgogICAgICAgIGlmICggJE9yZGVyQnktPntEaXJlY3Rpb259ICYmICRPcmRlckJ5LT57RGlyZWN0aW9ufSBlcSAnVXAnICkgewogICAgICAgICAgICAkQ29tcGFyZSA9IGxjKCAkYS0+eyAkT3JkZXJCeS0+e05hbWV9IH0gKSBjbXAgbGMoICRiLT57ICRPcmRlckJ5LT57TmFtZX0gfSApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJENvbXBhcmUgPSBsYyggJGItPnsgJE9yZGVyQnktPntOYW1lfSB9ICkgY21wIGxjKCAkYS0+eyAkT3JkZXJCeS0+e05hbWV9IH0gKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRDb21wYXJlIGlmICRDb21wYXJlOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN1YiBERVNUUk9ZIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyB0YWtlIGRvd24gc2Vzc2lvbgogICAgaWYgKCAkU2VsZi0+e0xEQVB9ICkgewogICAgICAgICRTZWxmLT57TERBUH0tPnVuYmluZCgpOwogICAgfQoKICAgIHJldHVybiAxOwp9CgoxOwo=
IyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIxIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDIxIFpudW55IEdtYkgsIGh0dHBzOi8vem51bnkub3JnLwojIENvcHlyaWdodCAoQykgMjAyMSBSb3RoZXIgT1NTIEdtYkgsIGh0dHBzOi8vcm90aGVyLW9zcy5jb20vCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0zLjAudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpDdXN0b21lckNvbXBhbnk7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OlZhcmlhYmxlQ2hlY2sgcXcoOmFsbCk7Cgp1c2UgcGFyZW50IHF3KEtlcm5lbDo6U3lzdGVtOjpFdmVudEhhbmRsZXIpOwoKb3VyIEBPYmplY3REZXBlbmRlbmNpZXMgPSAoCiAgICAnS2VybmVsOjpDb25maWcnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpFbmNvZGUnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpHcm91cCcsICAjIFJvdGhlck9TUzoKICAgICdLZXJuZWw6OlN5c3RlbTo6TG9nJywKICAgICdLZXJuZWw6OlN5c3RlbTo6TWFpbicsCiAgICAnS2VybmVsOjpTeXN0ZW06OlJlZmVyZW5jZURhdGEnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcsCik7Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQ29tcGFueSAtIGN1c3RvbWVyIGNvbXBhbnkgbGliCgo9aGVhZDEgREVTQ1JJUFRJT04KCkFsbCBDdXN0b21lciBmdW5jdGlvbnMuIEUuZy4gdG8gYWRkIGFuZCB1cGRhdGUgY3VzdG9tZXIgY29tcGFuaWVzLgoKPWhlYWQxIFBVQkxJQyBJTlRFUkZBQ0UKCj1oZWFkMiBuZXcoKQoKRG9uJ3QgdXNlIHRoZSBjb25zdHJ1Y3RvciBkaXJlY3RseSwgdXNlIHRoZSBPYmplY3RNYW5hZ2VyIGluc3RlYWQ6CgogICAgbXkgJEN1c3RvbWVyQ29tcGFueU9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lckNvbXBhbnknKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBnZXQgbmVlZGVkIG9iamVjdHMKICAgIG15ICRDb25maWdPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwogICAgbXkgJE1haW5PYmplY3QgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpNYWluJyk7CgogICAgIyAtLS0KICAgICMgUm90aGVyT1NTOgogICAgIyAtLS0KICAgIG15ICRMYXlvdXRQYXJhbSA9ICRLZXJuZWw6Ok9NLT57UGFyYW19LT57J0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnfTsKCiAgICAjIENoZWNrIGlmIG11bHRpdGVuYW5jeSBpcyBlbmFibGVkIGFuZCB0aGUgcmVxdWVzdCBpcyBjb21pbmcgZnJvbSBhIHVzZXIuCiAgICBpZiAoICRMYXlvdXRQYXJhbS0+e1VzZXJUeXBlfSAmJiAkTGF5b3V0UGFyYW0tPntVc2VyVHlwZX0gZXEgJ1VzZXInICYmICRDb25maWdPYmplY3QtPkdldCgnTXVsdGl0ZW5hbmN5JykgKSB7CgogICAgICAgICMgU2F2ZSB0aGUgVXNlcklEIGFuZCBhbGwgZ3JvdXBzIHRoZSB1c2VyIGhhcyAncm8nIHBlcm1pc3Npb24gb24uCiAgICAgICAgaWYgKCAkTGF5b3V0UGFyYW0tPntVc2VySUR9ICkgewogICAgICAgICAgICAjIE9ubHkgZ2V0IHRoZSBncm91cCBsaXN0IG9uY2UgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMuCiAgICAgICAgICAgIG15ICVHcm91cHMgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnKS0+UGVybWlzc2lvblVzZXJHZXQoCiAgICAgICAgICAgICAgICBVc2VySUQgPT4gJExheW91dFBhcmFtLT57VXNlcklEfSwKICAgICAgICAgICAgICAgIFR5cGUgICA9PiAncm8nLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgIyBUaGUgbGltaXQgZG9lcyBub3QgY291bnQgZm9yIG1lbWJlcnMgb2YgYSBzcGVjaWZpYyBncm91cC4KICAgICAgICAgICAgbXkgJFBlcm1pc3Npb25Hcm91cCA9ICRDb25maWdPYmplY3QtPkdldCgnTXVsdGl0ZW5hbmN5OjpQZXJtaXNzaW9uR3JvdXAnKSB8fCAnJzsKICAgICAgICAgICAgbXkgJUdyb3Vwc1JldmVyc2UgICA9IHJldmVyc2UgJUdyb3VwczsKCiAgICAgICAgICAgIGlmICggISRHcm91cHNSZXZlcnNleyRQZXJtaXNzaW9uR3JvdXB9ICkgewogICAgICAgICAgICAgICAgJFNlbGYtPntNdWx0aXRlbmFuY3l9ID0gJExheW91dFBhcmFtLT57VXNlcklEfTsKICAgICAgICAgICAgICAgICRTZWxmLT57VXNlckdyb3VwSURzfSA9IFsga2V5cyAlR3JvdXBzIF07CiAgICAgICAgICAgICAgICAkU2VsZi0+e1VzZXJHcm91cHN9ICAgPSBbIHZhbHVlcyAlR3JvdXBzIF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAjIC0tLQoKICAgICMgbG9hZCBjdXN0b21lciBjb21wYW55IGJhY2tlbmQgbW9kdWxlcwogICAgU09VUkNFOgogICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewoKICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lckNvbXBhbnkkQ291bnQiKTsKICAgICAgICAjIC0tLQogICAgICAgICMgUm90aGVyT1NTOiBDaGVjayBpZiB0aGUgdXNlciBoYXMgcGVybWlzc2lvbiB0byBhY2Nlc3MgdGhlIHNvdXJjZS4KICAgICAgICAjIC0tLQogICAgICAgIG15ICRDdXN0b21lckNvbXBhbnlVc2VyR3JvdXAgPSAkQ29uZmlnT2JqZWN0LT5HZXQoIkN1c3RvbWVyQ29tcGFueSRDb3VudCIpLT57Q3VzdG9tZXJDb21wYW55VXNlckdyb3VwfTsKCiAgICAgICAgIyBUaGUgdXNlciBkb2VzIG5vdCBoYXZlIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGZyb20gdGhpcyBzb3VyY2UuCiAgICAgICAgaWYgKCAkU2VsZi0+e011bHRpdGVuYW5jeX0gJiYgJEN1c3RvbWVyQ29tcGFueVVzZXJHcm91cCApIHsKICAgICAgICAgICAgaWYgKCAhZ3JlcCggL14kQ3VzdG9tZXJDb21wYW55VXNlckdyb3VwJC8sIEB7ICRTZWxmLT57VXNlckdyb3Vwc30gfSApICkgewogICAgICAgICAgICAgICAgbmV4dCBTT1VSQ0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgIyAtLS0KCiAgICAgICAgbXkgJEdlbmVyaWNNb2R1bGUgPSAkQ29uZmlnT2JqZWN0LT5HZXQoIkN1c3RvbWVyQ29tcGFueSRDb3VudCIpLT57TW9kdWxlfQogICAgICAgICAgICB8fCAnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQ29tcGFueTo6REInOwogICAgICAgIGlmICggISRNYWluT2JqZWN0LT5SZXF1aXJlKCRHZW5lcmljTW9kdWxlKSApIHsKICAgICAgICAgICAgJE1haW5PYmplY3QtPkRpZSgiQ2FuJ3QgbG9hZCBiYWNrZW5kIG1vZHVsZSAkR2VuZXJpY01vZHVsZSEgJEAiKTsKICAgICAgICB9CiAgICAgICAgJFNlbGYtPnsiQ3VzdG9tZXJDb21wYW55JENvdW50In0gPSAkR2VuZXJpY01vZHVsZS0+bmV3KAogICAgICAgICAgICBDb3VudCAgICAgICAgICAgICAgPT4gJENvdW50LAogICAgICAgICAgICBDdXN0b21lckNvbXBhbnlNYXAgPT4gJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lckNvbXBhbnkkQ291bnQiKSwKICAgICAgICApOwogICAgfQoKICAgICMgaW5pdCBvZiBldmVudCBoYW5kbGVyCiAgICAkU2VsZi0+RXZlbnRIYW5kbGVySW5pdCgKICAgICAgICBDb25maWcgPT4gJ0N1c3RvbWVyQ29tcGFueTo6RXZlbnRNb2R1bGVQb3N0JywKICAgICk7CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aGVhZDIgQ3VzdG9tZXJDb21wYW55QWRkKCkKCmFkZCBhIG5ldyBjdXN0b21lciBjb21wYW55CgogICAgbXkgJElEID0gJEN1c3RvbWVyQ29tcGFueU9iamVjdC0+Q3VzdG9tZXJDb21wYW55QWRkKAogICAgICAgIEN1c3RvbWVySUQgICAgICAgICAgICAgID0+ICdleGFtcGxlLmNvbScsCiAgICAgICAgQ3VzdG9tZXJDb21wYW55TmFtZSAgICAgPT4gJ05ldyBDdXN0b21lciBJbmMuJywKICAgICAgICBDdXN0b21lckNvbXBhbnlTdHJlZXQgICA9PiAnNTIwMSBCbHVlIExhZ29vbiBEcml2ZScsCiAgICAgICAgQ3VzdG9tZXJDb21wYW55WklQICAgICAgPT4gJzMzMTI2JywKICAgICAgICBDdXN0b21lckNvbXBhbnlDaXR5ICAgICA9PiAnTWlhbWknLAogICAgICAgIEN1c3RvbWVyQ29tcGFueUNvdW50cnkgID0+ICdVU0EnLAogICAgICAgIEN1c3RvbWVyQ29tcGFueVVSTCAgICAgID0+ICdodHRwOi8vd3d3LmV4YW1wbGUub3JnJywKICAgICAgICBDdXN0b21lckNvbXBhbnlDb21tZW50ICA9PiAnc29tZSBjb21tZW50JywKICAgICAgICBWYWxpZElEICAgICAgICAgICAgICAgICA9PiAxLAogICAgICAgIFVzZXJJRCAgICAgICAgICAgICAgICAgID0+IDEyMywKICAgICk7CgpOT1RFOiBBY3R1YWwgZmllbGRzIGFjY2VwdGVkIGJ5IHRoaXMgQVBJIGNhbGwgbWF5IGRpZmZlciBiYXNlZCBvbgpDdXN0b21lckNvbXBhbnkgbWFwcGluZyBpbiB5b3VyIHN5c3RlbSBjb25maWd1cmF0aW9uLgoKPWN1dAoKc3ViIEN1c3RvbWVyQ29tcGFueUFkZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgZGF0YSBzb3VyY2UKICAgIGlmICggISRQYXJhbXtTb3VyY2V9ICkgewogICAgICAgICRQYXJhbXtTb3VyY2V9ID0gJ0N1c3RvbWVyQ29tcGFueSc7CiAgICB9CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkTmVlZGVkIChxdyhDdXN0b21lcklEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JE5lZWRlZH0gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICROZWVkZWQhIgogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgc3RvcmUgY3VzdG9tZXIgY29tcGFueSBkYXRhCiAgICBteSAkUmVzdWx0ID0gJFNlbGYtPnsgJFBhcmFte1NvdXJjZX0gfS0+Q3VzdG9tZXJDb21wYW55QWRkKCVQYXJhbSk7CiAgICByZXR1cm4gaWYgISRSZXN1bHQ7CgogICAgIyB0cmlnZ2VyIGV2ZW50CiAgICAkU2VsZi0+RXZlbnRIYW5kbGVyKAogICAgICAgIEV2ZW50ID0+ICdDdXN0b21lckNvbXBhbnlBZGQnLAogICAgICAgIERhdGEgID0+IHsKICAgICAgICAgICAgQ3VzdG9tZXJJRCA9PiAkUGFyYW17Q3VzdG9tZXJJRH0sCiAgICAgICAgICAgIE5ld0RhdGEgICAgPT4gXCVQYXJhbSwKICAgICAgICB9LAogICAgICAgIFVzZXJJRCA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgcmV0dXJuICRSZXN1bHQ7Cn0KCj1oZWFkMiBDdXN0b21lckNvbXBhbnlHZXQoKQoKZ2V0IGN1c3RvbWVyIGNvbXBhbnkgYXR0cmlidXRlcwoKICAgIG15ICVDdXN0b21lckNvbXBhbnkgPSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0LT5DdXN0b21lckNvbXBhbnlHZXQoCiAgICAgICAgQ3VzdG9tZXJJRCA9PiAxMjMsCiAgICApOwoKUmV0dXJuczoKCiAgICAlQ3VzdG9tZXJDb21wYW55ID0gKAogICAgICAgICdDdXN0b21lckNvbXBhbnlOYW1lJyAgICA9PiAnQ3VzdG9tZXIgSW5jLicsCiAgICAgICAgJ0N1c3RvbWVySUQnICAgICAgICAgICAgID0+ICdleGFtcGxlLmNvbScsCiAgICAgICAgJ0N1c3RvbWVyQ29tcGFueVN0cmVldCcgID0+ICc1MjAxIEJsdWUgTGFnb29uIERyaXZlJywKICAgICAgICAnQ3VzdG9tZXJDb21wYW55WklQJyAgICAgPT4gJzMzMTI2JywKICAgICAgICAnQ3VzdG9tZXJDb21wYW55Q2l0eScgICAgPT4gJ01pYW1pJywKICAgICAgICAnQ3VzdG9tZXJDb21wYW55Q291bnRyeScgPT4gJ1VuaXRlZCBTdGF0ZXMnLAogICAgICAgICdDdXN0b21lckNvbXBhbnlVUkwnICAgICA9PiAnaHR0cDovL2V4YW1wbGUuY29tJywKICAgICAgICAnQ3VzdG9tZXJDb21wYW55Q29tbWVudCcgPT4gJ1NvbWUgQ29tbWVudHMnLAogICAgICAgICdWYWxpZElEJyAgICAgICAgICAgICAgICA9PiAnMScsCiAgICAgICAgJ0NyZWF0ZVRpbWUnICAgICAgICAgICAgID0+ICcyMDEwLTEwLTA0IDE2OjM1OjQ5JywKICAgICAgICAnQ2hhbmdlVGltZScgICAgICAgICAgICAgPT4gJzIwMTAtMTAtMDQgMTY6MzY6MTInLAogICAgKTsKCk5PVEU6IEFjdHVhbCBmaWVsZHMgcmV0dXJuZWQgYnkgdGhpcyBBUEkgY2FsbCBtYXkgZGlmZmVyIGJhc2VkIG9uCkN1c3RvbWVyQ29tcGFueSBtYXBwaW5nIGluIHlvdXIgc3lzdGVtIGNvbmZpZ3VyYXRpb24uCgo9Y3V0CgpzdWIgQ3VzdG9tZXJDb21wYW55R2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtDdXN0b21lcklEfSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgQ3VzdG9tZXJJRCEiCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBGZXRjaCBkeW5hbWljIGZpZWxkIGNvbmZpZ3VyYXRpb25zIGZvciBDdXN0b21lckNvbXBhbnkuCiAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlncyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKS0+RHluYW1pY0ZpZWxkTGlzdEdldCgKICAgICAgICBPYmplY3RUeXBlID0+ICdDdXN0b21lckNvbXBhbnknLAogICAgICAgIFZhbGlkICAgICAgPT4gMSwKICAgICk7CgogICAgbXkgJUR5bmFtaWNGaWVsZExvb2t1cCA9IG1hcCB7ICRfLT57TmFtZX0gPT4gJF8gfSBAeyREeW5hbWljRmllbGRDb25maWdzfTsKCiAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgbXkgJENvbmZpZ09iamVjdCAgICAgICAgICAgICAgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwogICAgbXkgJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJyk7CgogICAgU09VUkNFOgogICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewoKICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJFNlbGYtPnsiQ3VzdG9tZXJDb21wYW55JENvdW50In07CgogICAgICAgIG15ICVDb21wYW55ID0gJFNlbGYtPnsiQ3VzdG9tZXJDb21wYW55JENvdW50In0tPkN1c3RvbWVyQ29tcGFueUdldCggJVBhcmFtLCApOwogICAgICAgIG5leHQgU09VUkNFIGlmICElQ29tcGFueTsKCiAgICAgICAgIyBmZXRjaCBkeW5hbWljIGZpZWxkIHZhbHVlcwogICAgICAgIGlmICggSXNBcnJheVJlZldpdGhEYXRhKCAkU2VsZi0+eyJDdXN0b21lckNvbXBhbnkkQ291bnQifS0+e0N1c3RvbWVyQ29tcGFueU1hcH0tPntNYXB9ICkgKSB7CiAgICAgICAgICAgIENVU1RPTUVSQ09NUEFOWUZJRUxEOgogICAgICAgICAgICBmb3IgbXkgJEN1c3RvbWVyQ29tcGFueUZpZWxkICggQHsgJFNlbGYtPnsiQ3VzdG9tZXJDb21wYW55JENvdW50In0tPntDdXN0b21lckNvbXBhbnlNYXB9LT57TWFwfSB9ICkgewogICAgICAgICAgICAgICAgbmV4dCBDVVNUT01FUkNPTVBBTllGSUVMRCBpZiAkQ3VzdG9tZXJDb21wYW55RmllbGQtPls1XSBuZSAnZHluYW1pY19maWVsZCc7CiAgICAgICAgICAgICAgICBuZXh0IENVU1RPTUVSQ09NUEFOWUZJRUxEIGlmICEkRHluYW1pY0ZpZWxkTG9va3VweyAkQ3VzdG9tZXJDb21wYW55RmllbGQtPlsyXSB9OwoKICAgICAgICAgICAgICAgIG15ICRWYWx1ZSA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5WYWx1ZUdldCgKICAgICAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZExvb2t1cHsgJEN1c3RvbWVyQ29tcGFueUZpZWxkLT5bMl0gfSwKICAgICAgICAgICAgICAgICAgICBPYmplY3ROYW1lICAgICAgICAgPT4gJENvbXBhbnl7Q3VzdG9tZXJJRH0sCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICRDb21wYW55eyAkQ3VzdG9tZXJDb21wYW55RmllbGQtPlswXSB9ID0gJFZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjIC0tLQogICAgICAgICMgUm90aGVyT1NTOiBDaGVjayBwZXJtaXNzaW9uLgogICAgICAgICMgLS0tCiAgICAgICAgbXkgJFVzZXJHcm91cElEU3luYyA9ICRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9LT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e1VzZXJHcm91cElEU3luY307CgogICAgICAgIGlmICggJENvbXBhbnl7VXNlckdyb3VwSUR9ICYmICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH0gKSB7CiAgICAgICAgICAgICMgUmVwbGFjZSB0aGUgcmVtb3RlIGdyb3VwIHdpdGggdGhlIGFzc29jaWF0ZWQgbG9jYWwgZ3JvdXAuCiAgICAgICAgICAgIGZvciBteSAkUmVtb3RlR3JvdXAgKCBrZXlzICV7ICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH0gfSApIHsKICAgICAgICAgICAgICAgIGlmICggJENvbXBhbnl7VXNlckdyb3VwSUR9IGVxICRSZW1vdGVHcm91cCApIHsKICAgICAgICAgICAgICAgICAgICBteSAkTG9jYWxHcm91cCA9ICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH17JFJlbW90ZUdyb3VwfTsKICAgICAgICAgICAgICAgICAgICAkQ29tcGFueXtVc2VyR3JvdXBJRH0gPSAkTG9jYWxHcm91cDsKCiAgICAgICAgICAgICAgICAgICAgIyBDaGVjayBpZiBncm91cCBJRCBvciBncm91cCBuYW1lcyBzaG91bGQgYmUgdXNlZC4KICAgICAgICAgICAgICAgICAgICBpZiAoICRVc2VyR3JvdXBJRFN5bmMtPntVc2VHcm91cE5hbWVzfSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbXkgJEdyb3VwSUQgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnKS0+R3JvdXBMb29rdXAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHcm91cCA9PiAkTG9jYWxHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICRDb21wYW55e1VzZXJHcm91cElEfSA9ICRHcm91cElEOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCAkU2VsZi0+e011bHRpdGVuYW5jeX0gJiYgJENvbXBhbnl7VXNlckdyb3VwSUR9ICkgewogICAgICAgICAgICAjIENoZWNrIGlmIHRoZSB1c2VyIGhhcyBwZXJtaXNzaW9uIHRvIGFjY2VzcyB0aGUgaW5mb3JtYXRpb24uCiAgICAgICAgICAgIGlmICggIWdyZXAoIC9eJENvbXBhbnl7VXNlckdyb3VwSUR9JC8sIEB7ICRTZWxmLT57VXNlckdyb3VwSURzfSB9ICkgKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgIyAtLS0KCiAgICAgICAgIyByZXR1cm4gY29tcGFueSBkYXRhCiAgICAgICAgcmV0dXJuICgKICAgICAgICAgICAgJUNvbXBhbnksCiAgICAgICAgICAgIFNvdXJjZSA9PiAiQ3VzdG9tZXJDb21wYW55JENvdW50IiwKICAgICAgICAgICAgQ29uZmlnID0+ICRDb25maWdPYmplY3QtPkdldCgiQ3VzdG9tZXJDb21wYW55JENvdW50IiksCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm47Cn0KCj1oZWFkMiBDdXN0b21lckNvbXBhbnlVcGRhdGUoKQoKdXBkYXRlIGN1c3RvbWVyIGNvbXBhbnkgYXR0cmlidXRlcwoKICAgICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueVVwZGF0ZSgKICAgICAgICBDdXN0b21lckNvbXBhbnlJRCAgICAgICA9PiAnb2xkZXhhbXBsZS5jb20nLCAjIHJlcXVpcmVkIGZvciBDdXN0b21lckNvbXBhbnlJRC11cGRhdGUKICAgICAgICBDdXN0b21lcklEICAgICAgICAgICAgICA9PiAnZXhhbXBsZS5jb20nLAogICAgICAgIEN1c3RvbWVyQ29tcGFueU5hbWUgICAgID0+ICdOZXcgQ3VzdG9tZXIgSW5jLicsCiAgICAgICAgQ3VzdG9tZXJDb21wYW55U3RyZWV0ICAgPT4gJzUyMDEgQmx1ZSBMYWdvb24gRHJpdmUnLAogICAgICAgIEN1c3RvbWVyQ29tcGFueVpJUCAgICAgID0+ICczMzEyNicsCiAgICAgICAgQ3VzdG9tZXJDb21wYW55TG9jYXRpb24gPT4gJ01pYW1pJywKICAgICAgICBDdXN0b21lckNvbXBhbnlDb3VudHJ5ICA9PiAnVVNBJywKICAgICAgICBDdXN0b21lckNvbXBhbnlVUkwgICAgICA9PiAnaHR0cDovL2V4YW1wbGUuY29tJywKICAgICAgICBDdXN0b21lckNvbXBhbnlDb21tZW50ICA9PiAnc29tZSBjb21tZW50JywKICAgICAgICBWYWxpZElEICAgICAgICAgICAgICAgICA9PiAxLAogICAgICAgIFVzZXJJRCAgICAgICAgICAgICAgICAgID0+IDEyMywKICAgICk7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJDb21wYW55VXBkYXRlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgJFBhcmFte0N1c3RvbWVyQ29tcGFueUlEfSB8fD0gJFBhcmFte0N1c3RvbWVySUR9OwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17Q3VzdG9tZXJDb21wYW55SUR9ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCBDdXN0b21lckNvbXBhbnlJRCBvciBDdXN0b21lcklEISIKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNoZWNrIGlmIGNvbXBhbnkgZXhpc3RzCiAgICBteSAlQ29tcGFueSA9ICRTZWxmLT5DdXN0b21lckNvbXBhbnlHZXQoIEN1c3RvbWVySUQgPT4gJFBhcmFte0N1c3RvbWVyQ29tcGFueUlEfSApOwogICAgaWYgKCAhJUNvbXBhbnkgKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJObyBzdWNoIGNvbXBhbnkgJyRQYXJhbXtDdXN0b21lckNvbXBhbnlJRH0nISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyAtLS0KICAgICMgUm90aGVyT1NTOiBDaGVjayBpZiB0aGUgdXNlciBoYXMgcGVybWlzc2lvbiB0byBjaGFuZ2UgdGhlIFVzZXJHcm91cElELgogICAgIyAtLS0KICAgIGlmICggJFNlbGYtPntNdWx0aXRlbmFuY3l9ICkgewogICAgICAgICMgU2V0IHRoZSBVc2VyR3JvdXBJRCB0byB0aGUgY3VycmVudCBVc2VyR3JvdXBJRC4KICAgICAgICBpZiAoICRDb21wYW55e1VzZXJHcm91cElEfSApIHsKICAgICAgICAgICAgJFBhcmFte1VzZXJHcm91cElEfSA9ICRDb21wYW55e1VzZXJHcm91cElEfTsKICAgICAgICB9CiAgICB9CgogICAgbXkgJFVzZXJHcm91cElEU3luYyA9ICRTZWxmLT57JENvbXBhbnl7U291cmNlfX0tPntDdXN0b21lckNvbXBhbnlNYXB9LT57VXNlckdyb3VwSURTeW5jfTsKICAgIGlmICggJFBhcmFte1VzZXJHcm91cElEfSApIHsKICAgICAgICAjIENoZWNrIGlmIGdyb3VwIElEIG9yIGdyb3VwIG5hbWVzIHNob3VsZCBiZSB1c2VkLgogICAgICAgIGlmICggJFVzZXJHcm91cElEU3luYy0+e1VzZUdyb3VwTmFtZXN9ICkgewogICAgICAgICAgICAkUGFyYW17VXNlckdyb3VwSUR9ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Okdyb3VwJyktPkdyb3VwTG9va3VwKAogICAgICAgICAgICAgICAgR3JvdXBJRCA9PiAkUGFyYW17VXNlckdyb3VwSUR9LAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyBSZXBsYWNlIHRoZSBsb2NhbCBncm91cCB3aXRoIHRoZSBhc3NvY2lhdGVkIHJlbW90ZSBncm91cC4KICAgICAgICBmb3IgbXkgJFJlbW90ZUdyb3VwICgga2V5cyAleyAkVXNlckdyb3VwSURTeW5jLT57UmVtb3RlR3JvdXBUb0xvY2FsR3JvdXB9IH0gKSB7CiAgICAgICAgICAgIGlmICggJFBhcmFte1VzZXJHcm91cElEfSBlcSAkVXNlckdyb3VwSURTeW5jLT57UmVtb3RlR3JvdXBUb0xvY2FsR3JvdXB9eyRSZW1vdGVHcm91cH0gKSB7CiAgICAgICAgICAgICAgICAkUGFyYW17VXNlckdyb3VwSUR9ID0gJFJlbW90ZUdyb3VwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgIyAtLS0KCiAgICBteSAkUmVzdWx0ID0gJFNlbGYtPnsgJENvbXBhbnl7U291cmNlfSB9LT5DdXN0b21lckNvbXBhbnlVcGRhdGUoJVBhcmFtKTsKICAgIHJldHVybiBpZiAhJFJlc3VsdDsKCiAgICAjIHRyaWdnZXIgZXZlbnQKICAgICRTZWxmLT5FdmVudEhhbmRsZXIoCiAgICAgICAgRXZlbnQgPT4gJ0N1c3RvbWVyQ29tcGFueVVwZGF0ZScsCiAgICAgICAgRGF0YSAgPT4gewogICAgICAgICAgICBDdXN0b21lcklEICAgID0+ICRQYXJhbXtDdXN0b21lcklEfSwKICAgICAgICAgICAgT2xkQ3VzdG9tZXJJRCA9PiAkUGFyYW17Q3VzdG9tZXJDb21wYW55SUR9LAogICAgICAgICAgICBOZXdEYXRhICAgICAgID0+IFwlUGFyYW0sCiAgICAgICAgICAgIE9sZERhdGEgICAgICAgPT4gXCVDb21wYW55LAogICAgICAgIH0sCiAgICAgICAgVXNlcklEID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKCiAgICByZXR1cm4gJFJlc3VsdDsKfQoKPWhlYWQyIEN1c3RvbWVyQ29tcGFueVNvdXJjZUxpc3QoKQoKcmV0dXJuIGN1c3RvbWVyIGNvbXBhbnkgc291cmNlIGxpc3QKCiAgICBteSAlTGlzdCA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueVNvdXJjZUxpc3QoCiAgICAgICAgUmVhZE9ubHkgPT4gMCAjIG9wdGlvbmFsLCAxIHJldHVybnMgb25seSBSTyBiYWNrZW5kcywgMCByZXR1cm5zIHdyaXRhYmxlLCBpZiBub3QgcGFzc2VkIHJldHVybnMgYWxsIGJhY2tlbmRzCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyQ29tcGFueVNvdXJjZUxpc3QgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGdldCBjb25maWcgb2JqZWN0CiAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICBteSAlRGF0YTsKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKCiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRDb25maWdPYmplY3QtPkdldCgiQ3VzdG9tZXJDb21wYW55JENvdW50Iik7CgogICAgICAgIGlmICggZGVmaW5lZCAkUGFyYW17UmVhZE9ubHl9ICkgewogICAgICAgICAgICBteSAkQmFja2VuZENvbmZpZyA9ICRDb25maWdPYmplY3QtPkdldCgiQ3VzdG9tZXJDb21wYW55JENvdW50Iik7CiAgICAgICAgICAgIGlmICggJFBhcmFte1JlYWRPbmx5fSApIHsKICAgICAgICAgICAgICAgIG5leHQgU09VUkNFIGlmICEkQmFja2VuZENvbmZpZy0+e1JlYWRPbmx5fTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIG5leHQgU09VUkNFIGlmICRCYWNrZW5kQ29uZmlnLT57UmVhZE9ubHl9OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAkRGF0YXsiQ3VzdG9tZXJDb21wYW55JENvdW50In0gPSAkQ29uZmlnT2JqZWN0LT5HZXQoIkN1c3RvbWVyQ29tcGFueSRDb3VudCIpLT57TmFtZX0KICAgICAgICAgICAgfHwgIk5vIE5hbWUgJENvdW50IjsKICAgIH0KCiAgICByZXR1cm4gJURhdGE7Cn0KCj1oZWFkMiBDdXN0b21lckNvbXBhbnlMaXN0KCkKCmdldCBsaXN0IG9mIGN1c3RvbWVyIGNvbXBhbmllcy4KCiAgICBteSAlTGlzdCA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueUxpc3QoKTsKCiAgICBteSAlTGlzdCA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkN1c3RvbWVyQ29tcGFueUxpc3QoCiAgICAgICAgVmFsaWQgPT4gMCwKICAgICAgICBMaW1pdCA9PiAwLCAgICAgIyBvcHRpb25hbCwgb3ZlcnJpZGUgY29uZmlndXJlZCBzZWFyY2ggcmVzdWx0IGxpbWl0ICgwIG1lYW5zIHVubGltaXRlZCkKICAgICk7CgogICAgbXkgJUxpc3QgPSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0LT5DdXN0b21lckNvbXBhbnlMaXN0KAogICAgICAgIFNlYXJjaCA9PiAnc29tZWNvbXBhbnknLAogICAgKTsKClJldHVybnM6CgogICAgJUxpc3QgPSB7CiAgICAgICAgJ2V4YW1wbGUuY29tJyA9PiAnZXhhbXBsZS5jb20gQ3VzdG9tZXIgSW5jLicsCiAgICAgICAgJ2FjbWUuY29tJyAgICA9PiAnYWNtZS5jb20gQWNtZSwgSW5jLicKICAgIH07Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJDb21wYW55TGlzdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgR2V0IGR5bmFtaWMgZmllbGQgb2JqZWN0LgogICAgbXkgJER5bmFtaWNGaWVsZE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKTsKCiAgICBteSAkRHluYW1pY0ZpZWxkQ29uZmlncyA9ICREeW5hbWljRmllbGRPYmplY3QtPkR5bmFtaWNGaWVsZExpc3RHZXQoCiAgICAgICAgT2JqZWN0VHlwZSA9PiAnQ3VzdG9tZXJDb21wYW55JywKICAgICAgICBWYWxpZCAgICAgID0+IDEsCiAgICApOwoKICAgIG15ICVEeW5hbWljRmllbGRMb29rdXAgPSBtYXAgeyAkXy0+e05hbWV9ID0+ICRfIH0gQHskRHluYW1pY0ZpZWxkQ29uZmlnc307CgogICAgIyBHZXQgZHluYW1pYyBmaWVsZCBiYWNrZW5kIG9iamVjdC4KICAgIG15ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDo6QmFja2VuZCcpOwoKICAgIG15ICVEYXRhOwogICAgU09VUkNFOgogICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewoKICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJFNlbGYtPnsiQ3VzdG9tZXJDb21wYW55JENvdW50In07CgogICAgICAgICMgc2VhcmNoIGR5bmFtaWMgZmllbGQgdmFsdWVzLCBpZiBjb25maWd1cmVkCiAgICAgICAgbXkgJE1hcCA9ICRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9LT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e01hcH07CiAgICAgICAgaWYgKCBJc0FycmF5UmVmV2l0aERhdGEoJE1hcCkgKSB7CgogICAgICAgICAgICAjIGZldGNoIGR5bmFtaWMgZmllbGQgbmFtZXMgdGhhdCBhcmUgY29uZmlndXJlZCBpbiBNYXAKICAgICAgICAgICAgIyBvbmx5IHRoZXNlIHdpbGwgYmUgY29uc2lkZXJlZCBmb3IgYW55IG90aGVyIHNlYXJjaCBjb25maWcKICAgICAgICAgICAgIyBbICdEeW5hbWljRmllbGRfTmFtZV9ZJywgdW5kZWYsICdOYW1lX1knLCAwLCAwLCAnZHluYW1pY19maWVsZCcsIHVuZGVmLCAwLF0sCiAgICAgICAgICAgIG15ICVEeW5hbWljRmllbGROYW1lcyA9IG1hcCB7ICRfLT5bMl0gPT4gMSB9IGdyZXAgeyAkXy0+WzVdIGVxICdkeW5hbWljX2ZpZWxkJyB9IEB7JE1hcH07CgogICAgICAgICAgICBpZiAoJUR5bmFtaWNGaWVsZE5hbWVzKSB7CiAgICAgICAgICAgICAgICBteSAkRm91bmREeW5hbWljRmllbGRPYmplY3RJRHM7CiAgICAgICAgICAgICAgICBteSAkU2VhcmNoRmllbGRzOwogICAgICAgICAgICAgICAgbXkgJFNlYXJjaFBhcmFtOwoKICAgICAgICAgICAgICAgICMgY2hlY2sgd2hpY2ggb2YgdGhlIGR5bmFtaWMgZmllbGRzIGNvbmZpZ3VyZWQgaW4gTWFwIGFyZSBhbHNvCiAgICAgICAgICAgICAgICAjIGNvbmZpZ3VyZWQgaW4gU2VhcmNoRmllbGRzCgogICAgICAgICAgICAgICAgIyBwYXJhbSBTZWFyY2gKICAgICAgICAgICAgICAgIGlmICggZGVmaW5lZCAkUGFyYW17U2VhcmNofSAmJiBsZW5ndGggJFBhcmFte1NlYXJjaH0gKSB7CiAgICAgICAgICAgICAgICAgICAgJFNlYXJjaEZpZWxkcwogICAgICAgICAgICAgICAgICAgICAgICA9ICRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9LT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e0N1c3RvbWVyQ29tcGFueVNlYXJjaEZpZWxkc307CiAgICAgICAgICAgICAgICAgICAgJFNlYXJjaFBhcmFtID0gJFBhcmFte1NlYXJjaH07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyBzZWFyY2ggZHluYW1pYyBmaWVsZCB2YWx1ZXMKICAgICAgICAgICAgICAgIGlmICggSXNBcnJheVJlZldpdGhEYXRhKCRTZWFyY2hGaWVsZHMpICkgewogICAgICAgICAgICAgICAgICAgIG15IEBTZWFyY2hEeW5hbWljRmllbGROYW1lcyA9IGdyZXAgeyBleGlzdHMgJER5bmFtaWNGaWVsZE5hbWVzeyRffSB9IEB7JFNlYXJjaEZpZWxkc307CgogICAgICAgICAgICAgICAgICAgIG15ICVGb3VuZER5bmFtaWNGaWVsZE9iamVjdElEczsKICAgICAgICAgICAgICAgICAgICBGSUVMRE5BTUU6CiAgICAgICAgICAgICAgICAgICAgZm9yIG15ICRGaWVsZE5hbWUgKEBTZWFyY2hEeW5hbWljRmllbGROYW1lcykgewoKICAgICAgICAgICAgICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZENvbmZpZyA9ICREeW5hbWljRmllbGRMb29rdXB7JEZpZWxkTmFtZX07CgogICAgICAgICAgICAgICAgICAgICAgICBuZXh0IEZJRUxETkFNRSBpZiAhSXNIYXNoUmVmV2l0aERhdGEoJER5bmFtaWNGaWVsZENvbmZpZyk7CgogICAgICAgICAgICAgICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkVmFsdWVzID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlU2VhcmNoKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWFyY2ggICAgICAgICAgICAgPT4gJFNlYXJjaFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBJc0FycmF5UmVmV2l0aERhdGEoJER5bmFtaWNGaWVsZFZhbHVlcykgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgbXkgJER5bmFtaWNGaWVsZFZhbHVlICggQHskRHluYW1pY0ZpZWxkVmFsdWVzfSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkRm91bmREeW5hbWljRmllbGRPYmplY3RJRHN7ICREeW5hbWljRmllbGRWYWx1ZS0+e09iamVjdElEfSB9ID0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJEZvdW5kRHluYW1pY0ZpZWxkT2JqZWN0SURzID0gWyBrZXlzICVGb3VuZER5bmFtaWNGaWVsZE9iamVjdElEcyBdOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICMgZXhlY3V0ZSBiYWNrZW5kIHNlYXJjaCBmb3IgZm91bmQgb2JqZWN0IElEcwogICAgICAgICAgICAgICAgIyB0aGlzIGRhdGEgaXMgYmVpbmcgbWVyZ2VkIHdpdGggdGhlIGZvbGxvd2luZyBDdXN0b21lckNvbXBhbnlMaXN0IGNhbGwKICAgICAgICAgICAgICAgIGlmICggSXNBcnJheVJlZldpdGhEYXRhKCRGb3VuZER5bmFtaWNGaWVsZE9iamVjdElEcykgKSB7CgogICAgICAgICAgICAgICAgICAgIG15ICRPYmplY3ROYW1lcyA9ICREeW5hbWljRmllbGRPYmplY3QtPk9iamVjdE1hcHBpbmdHZXQoCiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdElEICAgPT4gJEZvdW5kRHluYW1pY0ZpZWxkT2JqZWN0SURzLAogICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RUeXBlID0+ICdDdXN0b21lckNvbXBhbnknLAogICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgIG15ICVTZWFyY2hQYXJhbSA9ICVQYXJhbTsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgJFNlYXJjaFBhcmFte1NlYXJjaH07CiAgICAgICAgICAgICAgICAgICAgbXkgJUNvbXBhbnlMaXN0ID0gJFNlbGYtPnsiQ3VzdG9tZXJDb21wYW55JENvdW50In0tPkN1c3RvbWVyQ29tcGFueUxpc3QoJVNlYXJjaFBhcmFtKTsKCiAgICAgICAgICAgICAgICAgICAgT0JKRUNUTkFNRToKICAgICAgICAgICAgICAgICAgICBmb3IgbXkgJE9iamVjdE5hbWUgKCB2YWx1ZXMgJXskT2JqZWN0TmFtZXN9ICkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXh0IE9CSkVDVE5BTUUgaWYgZXhpc3RzICREYXRheyRPYmplY3ROYW1lfTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggSXNIYXNoUmVmV2l0aERhdGEoIFwlQ29tcGFueUxpc3QgKSAmJiBleGlzdHMgJENvbXBhbnlMaXN0eyRPYmplY3ROYW1lfSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICVEYXRhID0gKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRPYmplY3ROYW1lID0+ICRDb21wYW55TGlzdHskT2JqZWN0TmFtZX0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJURhdGEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgZ2V0IGNvbXBhbnkgbGlzdCByZXN1bHQgb2YgYmFja2VuZCBhbmQgbWVyZ2UgaXQKICAgICAgICBteSAlU3ViRGF0YSA9ICRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9LT5DdXN0b21lckNvbXBhbnlMaXN0KCVQYXJhbSk7CiAgICAgICAgJURhdGEgPSAoICVEYXRhLCAlU3ViRGF0YSApOwogICAgfQoKICAgICMgLS0tCiAgICAjIFJvdGhlck9TUzogQ2hlY2sgaWYgdGhlIHVzZXIgaGFzIHBlcm1pc3Npb24gdG8gc2VlIHRoZSBjdXN0b21lciB1c2VyIGRhdGEuCiAgICAjIEltcHJvdmU6IENoZWNrIGV2ZXJ5IGNvbXBhbnkgb25lIGJ5IG9uZSBhcyBDdXN0b21lckNvbXBhbnlMaXN0IGRvZXMgc29tZXRpbWVzIHJldHVybiBhIG5vbiBmaWx0ZXJlZCBsaXN0IChDdXN0b21lckNvbXBhbnkgYWRkKQogICAgIyAtLS0KICAgIGlmICggJFNlbGYtPntNdWx0aXRlbmFuY3l9ICkgewogICAgICAgIGZvciBteSAkQ3VzdG9tZXJJRCAoIGtleXMgJURhdGEgKSB7CiAgICAgICAgICAgIG15ICVDb21wYW55ID0gJFNlbGYtPkN1c3RvbWVyQ29tcGFueUdldCgKICAgICAgICAgICAgICAgIEN1c3RvbWVySUQgPT4gJEN1c3RvbWVySUQsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoICElQ29tcGFueSB8fCAhJENvbXBhbnl7Q3VzdG9tZXJJRH0gKSB7CiAgICAgICAgICAgICAgICBkZWxldGUgJERhdGF7JEN1c3RvbWVySUR9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgIyAtLS0KCiAgICByZXR1cm4gJURhdGE7Cn0KCj1oZWFkMiBDdXN0b21lckNvbXBhbnlTZWFyY2hEZXRhaWwoKQoKVG8gZmluZCBjdXN0b21lciBjb21wYW5pZXMgaW4gdGhlIHN5c3RlbS4KClRoZSBzZWFyY2ggY3JpdGVyaWEgYXJlIGxvZ2ljYWxseSBBTkQgY29ubmVjdGVkLgpXaGVuIGEgbGlzdCBpcyBwYXNzZWQgYXMgY3JpdGVyaWEsIHRoZSBpbmRpdmlkdWFsIG1lbWJlcnMgYXJlIE9SIGNvbm5lY3RlZC4KV2hlbiBhbiB1bmRlZiBvciBhIHJlZmVyZW5jZSB0byBhbiBlbXB0eSBhcnJheSBpcyBwYXNzZWQsIHRoZW4gdGhlIHNlYXJjaCBjcml0ZXJpYQppcyBpZ25vcmVkLgoKUmV0dXJucyBlaXRoZXIgYSBsaXN0LCBhcyBhbiBhcnJheXJlZiwgb3IgYSBjb3VudCBvZiBmb3VuZCBjdXN0b21lciBjb21wYW55IGlkcy4KVGhlIGNvdW50IG9mIHJlc3VsdHMgaXMgcmV0dXJuZWQgd2hlbiB0aGUgcGFyYW1ldGVyIEM8UmVzdWx0ID0gJ0NPVU5UJz4gaXMgcGFzc2VkLgoKICAgIG15ICRDdXN0b21lckNvbXBhbnlJRHNSZWYgPSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0LT5DdXN0b21lckNvbXBhbnlTZWFyY2hEZXRhaWwoCgogICAgICAgICMgYWxsIHNlYXJjaCBmaWVsZHMgcG9zc2libGUgd2hpY2ggYXJlIGRlZmluZWQgaW4gQ3VzdG9tZXJDb21wYW55OjpFbmhhbmNlZFNlYXJjaEZpZWxkcwogICAgICAgIEN1c3RvbWVySUQgICAgICAgICAgPT4gJ2V4YW1wbGUqJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAob3B0aW9uYWwpCiAgICAgICAgQ3VzdG9tZXJDb21wYW55TmFtZSA9PiAnTmFtZSonLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIChvcHRpb25hbCkKCiAgICAgICAgIyBhcnJheSBwYXJhbWV0ZXJzIGFyZSB1c2VkIHdpdGggbG9naWNhbCBPUiBvcGVyYXRvciAoYWxsIHZhbHVlcyBhcmUgcG9zc2libGUgd2hpY2gKICAgICAgICBhcmUgZGVmaW5lZCBpbiB0aGUgY29uZmlnIHNlbGVjdGlvbiBoYXNoIGZvciB0aGUgZmllbGQpCiAgICAgICAgQ3VzdG9tZXJDb21wYW55Q291bnRyeSA9PiBbICdBdXN0cmlhJywgJ0dlcm1hbnknLCBdLCAgICAgICAgICAgICAgICAjIChvcHRpb25hbCkKCiAgICAgICAgIyBEeW5hbWljRmllbGRzCiAgICAgICAgIyAgIEF0IGxlYXN0IG9uZSBvcGVyYXRvciBtdXN0IGJlIHNwZWNpZmllZC4gT3BlcmF0b3JzIHdpbGwgYmUgY29ubmVjdGVkIHdpdGggQU5ELAogICAgICAgICMgICAgICAgdmFsdWVzIGluIGFuIG9wZXJhdG9yIHdpdGggT1IuCiAgICAgICAgIyAgIFlvdSBjYW4gYWxzbyBwYXNzIG1vcmUgdGhhbiBvbmUgYXJndW1lbnQgdG8gYW4gb3BlcmF0b3I6IFsndmFsdWUxJywgJ3ZhbHVlMiddCiAgICAgICAgRHluYW1pY0ZpZWxkX0ZpZWxkTmFtZVggPT4gewogICAgICAgICAgICBFcXVhbHMgICAgICAgICAgICA9PiAxMjMsCiAgICAgICAgICAgIExpa2UgICAgICAgICAgICAgID0+ICd2YWx1ZSonLCAgICAgICAgICAgICAgICAjICJlcXVhbHMiIG9wZXJhdG9yIHdpdGggd2lsZGNhcmQgc3VwcG9ydAogICAgICAgICAgICBHcmVhdGVyVGhhbiAgICAgICA9PiAnMjAwMS0wMS0wMSAwMTowMTowMScsCiAgICAgICAgICAgIEdyZWF0ZXJUaGFuRXF1YWxzID0+ICcyMDAxLTAxLTAxIDAxOjAxOjAxJywKICAgICAgICAgICAgU21hbGxlclRoYW4gICAgICAgPT4gJzIwMDItMDItMDIgMDI6MDI6MDInLAogICAgICAgICAgICBTbWFsbGVyVGhhbkVxdWFscyA9PiAnMjAwMi0wMi0wMiAwMjowMjowMicsCiAgICAgICAgfQoKICAgICAgICBPcmRlckJ5ID0+IFsgJ0N1c3RvbWVySUQnLCAnQ3VzdG9tZXJDb21wYW55Q291bnRyeScgXSwgICAgICAgICAgICAgICMgKG9wdGlvbmFsKQogICAgICAgICMgaWdub3JlZCBpZiB0aGUgcmVzdWx0IHR5cGUgaXMgJ0NPVU5UJwogICAgICAgICMgZGVmYXVsdDogWyAnQ3VzdG9tZXJJRCcgXQogICAgICAgICMgKGFsbCBzZWFyY2ggZmllbGRzIHBvc3NpYmxlIHdoaWNoIGFyZSBkZWZpbmVkIGluCiAgICAgICAgQ3VzdG9tZXJDb21wYW55OjpFbmhhbmNlZFNlYXJjaEZpZWxkcykKCiAgICAgICAgIyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIGZvciBPcmRlckJ5OgogICAgICAgICMgVGhlIE9yZGVyQnlEaXJlY3Rpb24gY2FuIGJlIHNwZWNpZmllZCBmb3IgZWFjaCBPcmRlckJ5IGF0dHJpYnV0ZS4KICAgICAgICAjIFRoZSBwYWlyaW5nIGlzIG1hZGUgYnkgdGhlIGFycmF5IGluZGljZXMuCgogICAgICAgIE9yZGVyQnlEaXJlY3Rpb24gPT4gWyAnRG93bicsICdVcCcgXSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAob3B0aW9uYWwpCiAgICAgICAgIyBpZ25vcmVkIGlmIHRoZSByZXN1bHQgdHlwZSBpcyAnQ09VTlQnCiAgICAgICAgIyAoRG93biB8IFVwKSBEZWZhdWx0OiBbICdEb3duJyBdCgogICAgICAgIFJlc3VsdCA9PiAnQVJSQVknIHx8ICdDT1VOVCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAob3B0aW9uYWwpCiAgICAgICAgIyBkZWZhdWx0OiBBUlJBWSwgcmV0dXJucyBhbiBhcnJheSBvZiBjaGFuZ2UgaWRzCiAgICAgICAgIyBDT1VOVCByZXR1cm5zIGEgc2NhbGFyIHdpdGggdGhlIG51bWJlciBvZiBmb3VuZCBjaGFuZ2VzCgogICAgICAgIExpbWl0ID0+IDEwMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAob3B0aW9uYWwpCiAgICAgICAgIyBpZ25vcmVkIGlmIHRoZSByZXN1bHQgdHlwZSBpcyAnQ09VTlQnCiAgICApOwoKUmV0dXJuczoKClJlc3VsdDogJ0FSUkFZJwoKICAgIEBDdXN0b21lcklEcyA9ICggMSwgMiwgMyApOwoKUmVzdWx0OiAnQ09VTlQnCgogICAgJEN1c3RvbWVySURzID0gMTA7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJDb21wYW55U2VhcmNoRGV0YWlsIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBHZXQgYWxsIGdlbmVyYWwgc2VhcmNoIGZpZWxkcyAod2l0aG91dCBhIHJlc3RyaWN0aW9uIHRvIGEgc291cmNlKS4KICAgIG15IEBBbGxTZWFyY2hGaWVsZHMgPSAkU2VsZi0+Q3VzdG9tZXJDb21wYW55U2VhcmNoRmllbGRzKCk7CgogICAgIyBHZW5lcmF0ZSBhIGhhc2ggd2l0aCB0aGUgY3VzdG9tZXIgY29tcGFueSBzb3VyY2VzIHdoaWNoIG11c3QgYmUgc2VhcmNoZWQuCiAgICBteSAlU2VhcmNoQ3VzdG9tZXJDb21wYW55U291cmNlczsKCiAgICBTT1VSQ0U6CiAgICBmb3IgbXkgJENvdW50ICggJycsIDEgLi4gMTAgKSB7CiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9OwoKICAgICAgICAjIEdldCB0aGUgc2VhcmNoIGZpZWxkcyBmb3IgdGhlIGN1cnJlbnQgc291cmNlLgogICAgICAgIG15IEBTb3VyY2VTZWFyY2hGaWVsZHMgPSAkU2VsZi0+Q3VzdG9tZXJDb21wYW55U2VhcmNoRmllbGRzKAogICAgICAgICAgICBTb3VyY2UgPT4gIkN1c3RvbWVyQ29tcGFueSRDb3VudCIsCiAgICAgICAgKTsKICAgICAgICBteSAlTG9va3VwU291cmNlU2VhcmNoRmllbGRzID0gbWFwIHsgJF8tPntOYW1lfSA9PiAxIH0gQFNvdXJjZVNlYXJjaEZpZWxkczsKCiAgICAgICAgIyBDaGVjayBpZiBhbGwgc2VhcmNoIHBhcmFtIGV4aXN0cyBpbiB0aGUgc2VhcmNoIGZpZWxkcyBmcm9tIHRoZSBjdXJyZW50IHNvdXJjZS4KICAgICAgICBTRUFSQ0hGSUVMRDoKICAgICAgICBmb3IgbXkgJFNlYXJjaEZpZWxkIChAQWxsU2VhcmNoRmllbGRzKSB7CgogICAgICAgICAgICBuZXh0IFNFQVJDSEZJRUxEIGlmICEkUGFyYW17ICRTZWFyY2hGaWVsZC0+e05hbWV9IH07CgogICAgICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJExvb2t1cFNvdXJjZVNlYXJjaEZpZWxkc3sgJFNlYXJjaEZpZWxkLT57TmFtZX0gfTsKICAgICAgICB9CiAgICAgICAgJFNlYXJjaEN1c3RvbWVyQ29tcGFueVNvdXJjZXN7IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9ID0gXEBTb3VyY2VTZWFyY2hGaWVsZHM7CiAgICB9CgogICAgIyBTZXQgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIGZvciB0aGUgcmV0dXJuIHR5cGUuCiAgICAkUGFyYW17UmVzdWx0fSB8fD0gJ0FSUkFZJzsKCiAgICBpZiAoICRQYXJhbXtSZXN1bHR9IGVxICdDT1VOVCcgKSB7CgogICAgICAgIG15ICRJRHNDb3VudCA9IDA7CgogICAgICAgIFNPVVJDRToKICAgICAgICBmb3IgbXkgJFNvdXJjZSAoIHNvcnQga2V5cyAlU2VhcmNoQ3VzdG9tZXJDb21wYW55U291cmNlcyApIHsKICAgICAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57JFNvdXJjZX07CgogICAgICAgICAgICBteSAkU3ViSURzQ291bnQgPSAkU2VsZi0+eyRTb3VyY2V9LT5DdXN0b21lckNvbXBhbnlTZWFyY2hEZXRhaWwoCiAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICBTZWFyY2hGaWVsZHMgPT4gJFNlYXJjaEN1c3RvbWVyQ29tcGFueVNvdXJjZXN7JFNvdXJjZX0sCiAgICAgICAgICAgICk7CgogICAgICAgICAgICByZXR1cm4gaWYgIWRlZmluZWQgJFN1YklEc0NvdW50OwoKICAgICAgICAgICAgJElEc0NvdW50ICs9ICRTdWJJRHNDb3VudCB8fCAwOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJElEc0NvdW50OwogICAgfQogICAgZWxzZSB7CgogICAgICAgIG15IEBJRHM7CgogICAgICAgIG15ICRSZXN1bHRDb3VudCA9IDA7CgogICAgICAgIFNPVVJDRToKICAgICAgICBmb3IgbXkgJFNvdXJjZSAoIHNvcnQga2V5cyAlU2VhcmNoQ3VzdG9tZXJDb21wYW55U291cmNlcyApIHsKICAgICAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57JFNvdXJjZX07CgogICAgICAgICAgICBteSAkU3ViSURzID0gJFNlbGYtPnskU291cmNlfS0+Q3VzdG9tZXJDb21wYW55U2VhcmNoRGV0YWlsKAogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgU2VhcmNoRmllbGRzID0+ICRTZWFyY2hDdXN0b21lckNvbXBhbnlTb3VyY2VzeyRTb3VyY2V9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmV0dXJuIGlmICFkZWZpbmVkICRTdWJJRHM7CgogICAgICAgICAgICBuZXh0IFNPVVJDRSBpZiAhSXNBcnJheVJlZldpdGhEYXRhKCRTdWJJRHMpOwoKICAgICAgICAgICAgcHVzaCBASURzLCBAeyRTdWJJRHN9OwoKICAgICAgICAgICAgJFJlc3VsdENvdW50Kys7CiAgICAgICAgfQoKICAgICAgICAjIElmIHdlIGhhdmUgbW9yZSB0aGVuIG9uZSBzZWFyY2ggcmVzdWx0cyBmcm9tIGRpZmZyZW50IHNvdXJjZXMsIHdlIG5lZWQgYSByZXNvcnRpbmcKICAgICAgICAjICAgYW5kIHNwbGljZSAoZm9yIHRoZSBsaW1pdCkgYmVjYXVzZSBvZiB0aGUgbWVyZ2VkIHNpbmdsZSByZXN1bHRzLgogICAgICAgIGlmICggJFJlc3VsdENvdW50ID4gMSApIHsKCiAgICAgICAgICAgIG15IEBDdXN0b21lckNvbXBhbnlhdGFMaXN0OwoKICAgICAgICAgICAgZm9yIG15ICRJRCAoQElEcykgewoKICAgICAgICAgICAgICAgIG15ICVDdXN0b21lckNvbXBhbnlEYXRhID0gJFNlbGYtPkN1c3RvbWVyQ29tcGFueUdldCgKICAgICAgICAgICAgICAgICAgICBDdXN0b21lcklEID0+ICRJRCwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBwdXNoIEBDdXN0b21lckNvbXBhbnlhdGFMaXN0LCBcJUN1c3RvbWVyQ29tcGFueURhdGE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG15ICRPcmRlckJ5ID0gJ0N1c3RvbWVySUQnOwogICAgICAgICAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSggJFBhcmFte09yZGVyQnl9ICkgKSB7CiAgICAgICAgICAgICAgICAkT3JkZXJCeSA9ICRQYXJhbXtPcmRlckJ5fS0+WzBdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSggJFBhcmFte09yZGVyQnlEaXJlY3Rpb259ICkgJiYgJFBhcmFte09yZGVyQnlEaXJlY3Rpb259LT5bMF0gZXEgJ1VwJyApIHsKICAgICAgICAgICAgICAgIEBDdXN0b21lckNvbXBhbnlhdGFMaXN0CiAgICAgICAgICAgICAgICAgICAgPSBzb3J0IHsgbGMoICRhLT57JE9yZGVyQnl9ICkgY21wIGxjKCAkYi0+eyRPcmRlckJ5fSApIH0gQEN1c3RvbWVyQ29tcGFueWF0YUxpc3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBAQ3VzdG9tZXJDb21wYW55YXRhTGlzdAogICAgICAgICAgICAgICAgICAgID0gc29ydCB7IGxjKCAkYi0+eyRPcmRlckJ5fSApIGNtcCBsYyggJGEtPnskT3JkZXJCeX0gKSB9IEBDdXN0b21lckNvbXBhbnlhdGFMaXN0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoICRQYXJhbXtMaW1pdH0gJiYgc2NhbGFyIEBDdXN0b21lckNvbXBhbnlhdGFMaXN0ID4gJFBhcmFte0xpbWl0fSApIHsKICAgICAgICAgICAgICAgIHNwbGljZSBAQ3VzdG9tZXJDb21wYW55YXRhTGlzdCwgJFBhcmFte0xpbWl0fTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQElEcyA9IG1hcCB7ICRfLT57Q3VzdG9tZXJJRH0gfSBAQ3VzdG9tZXJDb21wYW55YXRhTGlzdDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBcQElEczsKICAgIH0KfQoKPWhlYWQyIEN1c3RvbWVyQ29tcGFueVNlYXJjaEZpZWxkcygpCgpHZXQgYSBsaXN0IG9mIGRlZmluZWQgc2VhcmNoIGZpZWxkcyAob3B0aW9uYWwgb25seSB0aGUgcmVsZXZhbnQgZmllbGRzIGZvciB0aGUgZ2l2ZW4gc291cmNlKS4KCiAgICBteSBAU2VhY2hGaWVsZHMgPSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0LT5DdXN0b21lckNvbXBhbnlTZWFyY2hGaWVsZHMoCiAgICAgICAgU291cmNlID0+ICdDdXN0b21lckNvbXBhbnknLCAjIG9wdGlvbmFsLCBidXQgaW1wb3J0YW50IGluIHRoZSBDdXN0b21lckNvbXBhbnlTZWFyY2hEZXRhaWwgdG8gZ2V0IHRoZSByaWdodCBkYXRhYmFzZSBmaWVsZHMKICAgICk7CgpSZXR1cm5zIGFuIGFycmF5IG9mIGhhc2ggcmVmZXJlbmNlcy4KCiAgICBAU2VhY2hGaWVsZHMgPSAoCiAgICAgICAgewogICAgICAgICAgICBOYW1lICA9PiAnQ3VzdG9tZXJJRCcsCiAgICAgICAgICAgIExhYmVsID0+ICdDdXN0b21lcklEJywKICAgICAgICAgICAgVHlwZSAgPT4gJ0lucHV0JywKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgTmFtZSAgICAgICAgICAgPT4gJ0N1c3RvbWVyQ29tcGFueUNvdW50cnknLAogICAgICAgICAgICBMYWJlbCAgICAgICAgICA9PiAnQ291bnRyeScsCiAgICAgICAgICAgIFR5cGUgICAgICAgICAgID0+ICdTZWxlY3Rpb24nLAogICAgICAgICAgICBTZWxlY3Rpb25zRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAnR2VybWFueScgICAgICAgID0+ICdHZXJtYW55JywKICAgICAgICAgICAgICAgICdVbml0ZWQgS2luZ2RvbScgPT4gJ1VuaXRlZCBLaW5nZG9tJywKICAgICAgICAgICAgICAgICdVbml0ZWQgU3RhdGVzJyAgPT4gJ1VuaXRlZCBTdGF0ZXMnLAogICAgICAgICAgICAgICAgLi4uCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIE5hbWUgICAgICAgICAgPT4gJ0R5bmFtaWNGaWVsZF9CcmFuY2gnLAogICAgICAgICAgICBMYWJlbCAgICAgICAgID0+ICcnLAogICAgICAgICAgICBUeXBlICAgICAgICAgID0+ICdEeW5hbWljRmllbGQnLAogICAgICAgICAgICBEYXRhYmFzZUZpZWxkID0+ICdCcmFuY2gnLAogICAgICAgIH0sCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyQ29tcGFueVNlYXJjaEZpZWxkcyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgR2V0IHRoZSBzZWFyY2ggZmllbGRzIGZyb20gYWxsIGN1c3RvbWVyIGNvbXBhbnkgbWFwcyAobWVyZ2UgZnJvbSBhbGwgbWFwcyB0b2dldGhlcikuCiAgICBteSBAU2VhcmNoRmllbGRzOwoKICAgIG15ICVTZWFyY2hGaWVsZHNFeGlzdHM7CgogICAgU09VUkNFOgogICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewogICAgICAgIG5leHQgU09VUkNFIGlmICEkU2VsZi0+eyJDdXN0b21lckNvbXBhbnkkQ291bnQifTsKICAgICAgICBuZXh0IFNPVVJDRSBpZiAkUGFyYW17U291cmNlfSAmJiAkUGFyYW17U291cmNlfSBuZSAiQ3VzdG9tZXJDb21wYW55JENvdW50IjsKCiAgICAgICAgRU5UUlk6CiAgICAgICAgZm9yIG15ICRFbnRyeSAoIEB7ICRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9LT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e01hcH0gfSApIHsKCiAgICAgICAgICAgIG15ICRTZWFyY2hGaWVsZE5hbWUgPSAkRW50cnktPlswXTsKCiAgICAgICAgICAgIG5leHQgRU5UUlkgaWYgJFNlYXJjaEZpZWxkc0V4aXN0c3skU2VhcmNoRmllbGROYW1lfTsKCiAgICAgICAgICAgICMgUmVtZWJlciB0aGUgYWxyZWFkeSBjb2xsZWN0ZWQgc2VhcmNoIGZpZWxkIG5hbWUuCiAgICAgICAgICAgICRTZWFyY2hGaWVsZHNFeGlzdHN7JFNlYXJjaEZpZWxkTmFtZX0gPSAxOwoKICAgICAgICAgICAgbXkgJUZpZWxkQ29uZmlnID0gJFNlbGYtPkdldEZpZWxkQ29uZmlnKAogICAgICAgICAgICAgICAgRmllbGROYW1lID0+ICRTZWFyY2hGaWVsZE5hbWUsCiAgICAgICAgICAgICAgICBTb3VyY2UgICAgPT4gJFBhcmFte1NvdXJjZX0sICAgICAjIHRvIGdldCB0aGUgcmlnaHQgZGF0YWJhc2UgZmllbGQgZm9yIHRoZSBnaXZlbiBzb3VyY2UKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIG5leHQgRU5UUlkgaWYgISVGaWVsZENvbmZpZzsKCiAgICAgICAgICAgIG15ICVTZWFyY2hGaWVsZERhdGEgPSAoCiAgICAgICAgICAgICAgICAlRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICBOYW1lID0+ICRTZWFyY2hGaWVsZE5hbWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBteSAlU2VsZWN0aW9uc0RhdGEgPSAkU2VsZi0+R2V0RmllbGRTZWxlY3Rpb25zKAogICAgICAgICAgICAgICAgRmllbGROYW1lID0+ICRTZWFyY2hGaWVsZE5hbWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoICRTZWFyY2hGaWVsZERhdGF7U3RvcmFnZVR5cGV9IGVxICdkeW5hbWljX2ZpZWxkJyApIHsKICAgICAgICAgICAgICAgICRTZWFyY2hGaWVsZERhdGF7VHlwZX0gPSAnRHluYW1pY0ZpZWxkJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNpZiAoJVNlbGVjdGlvbnNEYXRhKSB7CiAgICAgICAgICAgICAgICAkU2VhcmNoRmllbGREYXRhe1R5cGV9ICAgICAgICAgICA9ICdTZWxlY3Rpb24nOwogICAgICAgICAgICAgICAgJFNlYXJjaEZpZWxkRGF0YXtTZWxlY3Rpb25zRGF0YX0gPSBcJVNlbGVjdGlvbnNEYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJFNlYXJjaEZpZWxkRGF0YXtUeXBlfSA9ICdJbnB1dCc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1c2ggQFNlYXJjaEZpZWxkcywgXCVTZWFyY2hGaWVsZERhdGE7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBAU2VhcmNoRmllbGRzOwp9Cgo9aGVhZDIgR2V0RmllbGRDb25maWcoKQoKVGhpcyBmdW5jdGlvbiBjb2xsZWN0IHNvbWUgZmllbGQgY29uZmlnIGluZm9ybWF0aW9uIGZyb20gdGhlIGN1c3RvbWVyIHVzZXIgbWFwLgoKICAgIG15ICVGaWVsZENvbmZpZyA9ICRDdXN0b21lckNvbXBhbnlPYmplY3QtPkdldEZpZWxkQ29uZmlnKAogICAgICAgIEZpZWxkTmFtZSA9PiAnQ3VzdG9tZXJDb21wYW55TmFtZScsCiAgICAgICAgU291cmNlICAgID0+ICdDdXN0b21lckNvbXBhbnknLCAjIG9wdGlvbmFsCiAgICApOwoKUmV0dXJucyBzb21lIGZpZWxkIGNvbmZpZyBpbmZvcm1hdGlvbjoKCiAgICBteSAlRmllbGRDb25maWcgPSAoCiAgICAgICAgTGFiZWwgICAgICAgICA9PiAnTmFtZScsCiAgICAgICAgRGF0YWJhc2VGaWVsZCA9PiAnbmFtZScsCiAgICAgICAgU3RvcmFnZVR5cGUgICA9PiAndmFyJywKICAgICk7Cgo9Y3V0CgpzdWIgR2V0RmllbGRDb25maWcgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBpZiAoICEkUGFyYW17RmllbGROYW1lfSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgRmllbGROYW1lISIKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBTT1VSQ0U6CiAgICBmb3IgbXkgJENvdW50ICggJycsIDEgLi4gMTAgKSB7CiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9OwogICAgICAgIG5leHQgU09VUkNFIGlmICRQYXJhbXtTb3VyY2V9ICYmICRQYXJhbXtTb3VyY2V9IG5lICJDdXN0b21lckNvbXBhbnkkQ291bnQiOwoKICAgICAgICAjIFNlYXJjaCB0aGUgcmlnaHQgZmllbGQgYW5kIHJldHVybiB0aGUgbGFiZWwuCiAgICAgICAgRU5UUlk6CiAgICAgICAgZm9yIG15ICRFbnRyeSAoIEB7ICRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9LT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e01hcH0gfSApIHsKICAgICAgICAgICAgbmV4dCBFTlRSWSBpZiAkUGFyYW17RmllbGROYW1lfSBuZSAkRW50cnktPlswXTsKCiAgICAgICAgICAgIG15ICVGaWVsZENvbmZpZyA9ICgKICAgICAgICAgICAgICAgIExhYmVsICAgICAgICAgPT4gJEVudHJ5LT5bMV0sCiAgICAgICAgICAgICAgICBEYXRhYmFzZUZpZWxkID0+ICRFbnRyeS0+WzJdLAogICAgICAgICAgICAgICAgU3RvcmFnZVR5cGUgICA9PiAkRW50cnktPls1XSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHJldHVybiAlRmllbGRDb25maWc7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybjsKfQoKPWhlYWQyIEdldEZpZWxkU2VsZWN0aW9ucygpCgpUaGlzIGZ1bmN0aW9uIGNvbGxlY3QgdGhlIHNlbGVjdGlvbnMgZm9yIHRoZSBnaXZlbiBmaWVsZCBuYW1lLCBpZiB0aGUgZmllbGQgaGFzIHNvbWUgc2VsZWN0aW9ucy4KCiAgICBteSAlU2VsZWN0aW9uc0RhdGEgPSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0LT5HZXRGaWVsZFNlbGVjdGlvbnMoCiAgICAgICAgRmllbGROYW1lID0+ICdDdXN0b21lckNvbXBhbnlDb3VudHJ5JywKICAgICk7CgpSZXR1cm5zIHRoZSBzZWxlY3Rpb25zIGZvciB0aGUgZ2l2ZW4gZmllbGQgbmFtZSAobWVyZ2VkIGZyb20gYWxsIHNvdXJjZXMpIG9yIGEgZW1wdHkgaGFzaDoKCiAgICBteSAlU2VsZWN0aW9uRGF0YSA9ICgKICAgICAgICAnR2VybWFueScgICAgICAgID0+ICdHZXJtYW55JywKICAgICAgICAnVW5pdGVkIEtpbmdkb20nID0+ICdVbml0ZWQgS2luZ2RvbScsCiAgICAgICAgJ1VuaXRlZCBTdGF0ZXMnICA9PiAnVW5pdGVkIFN0YXRlcycsCiAgICApOwoKPWN1dAoKc3ViIEdldEZpZWxkU2VsZWN0aW9ucyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17RmllbGROYW1lfSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgRmllbGROYW1lISIKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBteSAlU2VsZWN0aW9uc0RhdGE7CgogICAgU09VUkNFOgogICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewogICAgICAgIG5leHQgU09VUkNFIGlmICEkU2VsZi0+eyJDdXN0b21lckNvbXBhbnkkQ291bnQifTsKICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJFNlbGYtPnsiQ3VzdG9tZXJDb21wYW55JENvdW50In0tPntDdXN0b21lckNvbXBhbnlNYXB9LT57U2VsZWN0aW9uc30tPnsgJFBhcmFte0ZpZWxkTmFtZX0gfTsKCiAgICAgICAgJVNlbGVjdGlvbnNEYXRhID0gKAogICAgICAgICAgICAlU2VsZWN0aW9uc0RhdGEsCiAgICAgICAgICAgICV7ICRTZWxmLT57IkN1c3RvbWVyQ29tcGFueSRDb3VudCJ9LT57Q3VzdG9tZXJDb21wYW55TWFwfS0+e1NlbGVjdGlvbnN9LT57ICRQYXJhbXtGaWVsZE5hbWV9IH0gfQogICAgICAgICk7CiAgICB9CgogICAgIyBNYWtlIHN1cmUgdGhlIGVuY29kaW5nIHN0YW1wIGlzIHNldC4KICAgIGZvciBteSAkS2V5ICggc29ydCBrZXlzICVTZWxlY3Rpb25zRGF0YSApIHsKICAgICAgICAkU2VsZWN0aW9uc0RhdGF7JEtleX0gPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RW5jb2RlJyktPkVuY29kZUlucHV0KCAkU2VsZWN0aW9uc0RhdGF7JEtleX0gKTsKICAgIH0KCiAgICAjIERlZmF1bHQgaGFuZGxpbmcgZm9yIGZpZWxkICdDdXN0b21lckNvbXBhbnlDb3VudHJ5Jy4KICAgIGlmICggISVTZWxlY3Rpb25zRGF0YSAmJiAkUGFyYW17RmllbGROYW1lfSA9fiAvXkN1c3RvbWVyQ29tcGFueUNvdW50cnkvaSApIHsKICAgICAgICAlU2VsZWN0aW9uc0RhdGEgPSAleyAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6UmVmZXJlbmNlRGF0YScpLT5Db3VudHJ5TGlzdCgpIH07CiAgICB9CgogICAgIyBEZWZhdWx0IGhhbmRsaW5nIGZvciBmaWVsZCAnVmFsaWRJRCcuCiAgICBlbHNpZiAoICElU2VsZWN0aW9uc0RhdGEgJiYgJFBhcmFte0ZpZWxkTmFtZX0gPX4gL15WYWxpZElEL2kgKSB7CiAgICAgICAgJVNlbGVjdGlvbnNEYXRhID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlZhbGlkJyktPlZhbGlkTGlzdCgpOwogICAgfQoKICAgIHJldHVybiAlU2VsZWN0aW9uc0RhdGE7Cn0KCnN1YiBERVNUUk9ZIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgIyBleGVjdXRlIGFsbCB0cmFuc2FjdGlvbiBldmVudHMKICAgICRTZWxmLT5FdmVudEhhbmRsZXJUcmFuc2FjdGlvbigpOwoKICAgIHJldHVybiAxOwp9CgoxOwoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoTDxodHRwczovL290cnMub3JnLz4pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBMPGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTMuMC50eHQ+LgoKPWN1dAo=
IyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIxIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDIxIFpudW55IEdtYkgsIGh0dHBzOi8vem51bnkub3JnLwojIENvcHlyaWdodCAoQykgMjAyMSBSb3RoZXIgT1NTIEdtYkgsIGh0dHBzOi8vcm90aGVyLW9zcy5jb20vCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0zLjAudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXI7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OlZhcmlhYmxlQ2hlY2sgcXcoOmFsbCk7Cgp1c2UgcGFyZW50IHF3KEtlcm5lbDo6U3lzdGVtOjpFdmVudEhhbmRsZXIpOwoKb3VyIEBPYmplY3REZXBlbmRlbmNpZXMgPSAoCiAgICAnS2VybmVsOjpDb25maWcnLAogICAgJ0tlcm5lbDo6TGFuZ3VhZ2UnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpDYWNoZScsCiAgICAnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQ29tcGFueScsCiAgICAnS2VybmVsOjpTeXN0ZW06OkRCJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RW5jb2RlJywKICAgICdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnLCAgIyBSb3RoZXJPU1M6CiAgICAnS2VybmVsOjpTeXN0ZW06OkxvZycsCiAgICAnS2VybmVsOjpTeXN0ZW06Ok1haW4nLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpVc2VyJywgICMgUm90aGVyT1NTOgogICAgJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcsCik7Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlciAtIGN1c3RvbWVyIHVzZXIgbGliCgo9aGVhZDEgREVTQ1JJUFRJT04KCkFsbCBjdXN0b21lciB1c2VyIGZ1bmN0aW9ucy4gRS4gZy4gdG8gYWRkIGFuZCB1cGRhdGUgY3VzdG9tZXIgdXNlcnMuCgo9aGVhZDEgUFVCTElDIElOVEVSRkFDRQoKPWhlYWQyIG5ldygpCgpEb24ndCB1c2UgdGhlIGNvbnN0cnVjdG9yIGRpcmVjdGx5LCB1c2UgdGhlIE9iamVjdE1hbmFnZXIgaW5zdGVhZDoKCiAgICBteSAkQ3VzdG9tZXJVc2VyT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlcicpOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAkU2VsZi0+e0NhY2hlVHlwZX0gPSAnQ3VzdG9tZXJVc2VyJzsKICAgICRTZWxmLT57Q2FjaGVUVEx9ICA9IDYwICogNjAgKiAyNCAqIDIwOwoKICAgICMgZ2V0IGNvbmZpZyBvYmplY3QKICAgIG15ICRDb25maWdPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwoKICAgICMgbG9hZCBnZW5lcmF0b3IgY3VzdG9tZXIgcHJlZmVyZW5jZXMgbW9kdWxlCiAgICBteSAkR2VuZXJhdG9yTW9kdWxlID0gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclByZWZlcmVuY2VzJyktPntNb2R1bGV9CiAgICAgICAgfHwgJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXI6OlByZWZlcmVuY2VzOjpEQic7CgogICAgIyBnZXQgbWFpbiBvYmplY3QKICAgIG15ICRNYWluT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Ok1haW4nKTsKCiAgICBpZiAoICRNYWluT2JqZWN0LT5SZXF1aXJlKCRHZW5lcmF0b3JNb2R1bGUpICkgewogICAgICAgICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9ID0gJEdlbmVyYXRvck1vZHVsZS0+bmV3KCk7CiAgICB9CgogICAgIyAtLS0KICAgICMgUm90aGVyT1NTOgogICAgIyAtLS0KICAgIG15ICRMYXlvdXRQYXJhbSA9ICRLZXJuZWw6Ok9NLT57UGFyYW19LT57J0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnfTsKCiAgICAjIENoZWNrIGlmIG11bHRpdGVuYW5jeSBpcyBlbmFibGVkIGFuZCB0aGUgcmVxdWVzdCBpcyBjb21pbmcgZnJvbSBhIHVzZXIuCiAgICBpZiAoICRMYXlvdXRQYXJhbS0+e1VzZXJUeXBlfSAmJiAkTGF5b3V0UGFyYW0tPntVc2VyVHlwZX0gZXEgJ1VzZXInICYmICRDb25maWdPYmplY3QtPkdldCgnTXVsdGl0ZW5hbmN5JykgKSB7CgogICAgICAgICMgU2F2ZSB0aGUgVXNlcklEIGFuZCBhbGwgZ3JvdXBzIHRoZSB1c2VyIGhhcyAncm8nIHBlcm1pc3Npb24gb24uCiAgICAgICAgaWYgKCAkTGF5b3V0UGFyYW0tPntVc2VySUR9ICkgewogICAgICAgICAgICAjIE9ubHkgZ2V0IHRoZSBncm91cCBsaXN0IG9uY2UgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMuCiAgICAgICAgICAgIG15ICVHcm91cHMgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnKS0+UGVybWlzc2lvblVzZXJHZXQoCiAgICAgICAgICAgICAgICBVc2VySUQgPT4gJExheW91dFBhcmFtLT57VXNlcklEfSwKICAgICAgICAgICAgICAgIFR5cGUgICA9PiAncm8nLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgIyBUaGUgbGltaXQgZG9lcyBub3QgY291bnQgZm9yIG1lbWJlcnMgb2YgYSBzcGVjaWZpYyBncm91cC4KICAgICAgICAgICAgbXkgJFBlcm1pc3Npb25Hcm91cCA9ICRDb25maWdPYmplY3QtPkdldCgnTXVsdGl0ZW5hbmN5OjpQZXJtaXNzaW9uR3JvdXAnKSB8fCAnJzsKICAgICAgICAgICAgbXkgJUdyb3Vwc1JldmVyc2UgICA9IHJldmVyc2UgJUdyb3VwczsKCiAgICAgICAgICAgIGlmICggISRHcm91cHNSZXZlcnNleyRQZXJtaXNzaW9uR3JvdXB9ICkgewogICAgICAgICAgICAgICAgJFNlbGYtPntNdWx0aXRlbmFuY3l9ID0gJExheW91dFBhcmFtLT57VXNlcklEfTsKICAgICAgICAgICAgICAgICRTZWxmLT57VXNlckdyb3VwSURzfSA9IFsga2V5cyAlR3JvdXBzIF07CiAgICAgICAgICAgICAgICAkU2VsZi0+e1VzZXJHcm91cHN9ICAgPSBbIHZhbHVlcyAlR3JvdXBzIF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAjIC0tLQoKICAgICMgbG9hZCBjdXN0b21lciB1c2VyIGJhY2tlbmQgbW9kdWxlCiAgICBTT1VSQ0U6CiAgICBmb3IgbXkgJENvdW50ICggJycsIDEgLi4gMTAgKSB7CgogICAgICAgIG5leHQgU09VUkNFIGlmICEkQ29uZmlnT2JqZWN0LT5HZXQoIkN1c3RvbWVyVXNlciRDb3VudCIpOwogICAgICAgICMgLS0tCiAgICAgICAgIyBSb3RoZXJPU1M6IENoZWNrIGlmIHRoZSB1c2VyIGhhcyBwZXJtaXNzaW9uIHRvIGFjY2VzcyB0aGUgc291cmNlLgogICAgICAgICMgLS0tCiAgICAgICAgbXkgJEN1c3RvbWVyVXNlckdyb3VwID0gJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lclVzZXIkQ291bnQiKS0+e0N1c3RvbWVyVXNlckdyb3VwfTsKCiAgICAgICAgIyBUaGUgdXNlciBkb2VzIG5vdCBoYXZlIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGZyb20gdGhpcyBzb3VyY2UuCiAgICAgICAgaWYgKCAkU2VsZi0+e011bHRpdGVuYW5jeX0gJiYgJEN1c3RvbWVyVXNlckdyb3VwICkgewogICAgICAgICAgICBpZiAoICFncmVwKCAvXiRDdXN0b21lclVzZXJHcm91cCQvLCBAeyAkU2VsZi0+e1VzZXJHcm91cHN9IH0gKSApIHsKICAgICAgICAgICAgICAgIG5leHQgU09VUkNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICMgLS0tCgogICAgICAgIG15ICRHZW5lcmljTW9kdWxlID0gJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lclVzZXIkQ291bnQiKS0+e01vZHVsZX07CiAgICAgICAgaWYgKCAhJE1haW5PYmplY3QtPlJlcXVpcmUoJEdlbmVyaWNNb2R1bGUpICkgewogICAgICAgICAgICAkTWFpbk9iamVjdC0+RGllKCJDYW4ndCBsb2FkIGJhY2tlbmQgbW9kdWxlICRHZW5lcmljTW9kdWxlISAkQCIpOwogICAgICAgIH0KCiAgICAgICAgJFNlbGYtPnsiQ3VzdG9tZXJVc2VyJENvdW50In0gPSAkR2VuZXJpY01vZHVsZS0+bmV3KAogICAgICAgICAgICBDb3VudCAgICAgICAgICAgICA9PiAkQ291bnQsCiAgICAgICAgICAgIFByZWZlcmVuY2VzT2JqZWN0ID0+ICRTZWxmLT57UHJlZmVyZW5jZXNPYmplY3R9LAogICAgICAgICAgICBDdXN0b21lclVzZXJNYXAgICA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoIkN1c3RvbWVyVXNlciRDb3VudCIpLAogICAgICAgICk7CiAgICB9CgogICAgIyBpbml0IG9mIGV2ZW50IGhhbmRsZXIKICAgICRTZWxmLT5FdmVudEhhbmRsZXJJbml0KAogICAgICAgIENvbmZpZyA9PiAnQ3VzdG9tZXJVc2VyOjpFdmVudE1vZHVsZVBvc3QnLAogICAgKTsKCiAgICByZXR1cm4gJFNlbGY7Cn0KCj1oZWFkMiBDdXN0b21lclNvdXJjZUxpc3QoKQoKcmV0dXJuIGN1c3RvbWVyIHNvdXJjZSBsaXN0CgogICAgbXkgJUxpc3QgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclNvdXJjZUxpc3QoCiAgICAgICAgUmVhZE9ubHkgPT4gMCAjIG9wdGlvbmFsLCAxIHJldHVybnMgb25seSBSTyBiYWNrZW5kcywgMCByZXR1cm5zIHdyaXRhYmxlLCBpZiBub3QgcGFzc2VkIHJldHVybnMgYWxsIGJhY2tlbmRzCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyU291cmNlTGlzdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgZ2V0IGNvbmZpZyBvYmplY3QKICAgIG15ICRDb25maWdPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwoKICAgIG15ICVEYXRhOwogICAgU09VUkNFOgogICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewoKICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lclVzZXIkQ291bnQiKTsKICAgICAgICBpZiAoIGRlZmluZWQgJFBhcmFte1JlYWRPbmx5fSApIHsKICAgICAgICAgICAgbXkgJEN1c3RvbWVyQmFja2VuZENvbmZpZyA9ICRDb25maWdPYmplY3QtPkdldCgiQ3VzdG9tZXJVc2VyJENvdW50Iik7CiAgICAgICAgICAgIGlmICggJFBhcmFte1JlYWRPbmx5fSApIHsKICAgICAgICAgICAgICAgIG5leHQgU09VUkNFIGlmICEkQ3VzdG9tZXJCYWNrZW5kQ29uZmlnLT57UmVhZE9ubHl9IHx8ICRDdXN0b21lckJhY2tlbmRDb25maWctPntNb2R1bGV9ICF+IC9MREFQL2k7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBuZXh0IFNPVVJDRSBpZiAkQ3VzdG9tZXJCYWNrZW5kQ29uZmlnLT57UmVhZE9ubHl9IHx8ICRDdXN0b21lckJhY2tlbmRDb25maWctPntNb2R1bGV9ID1+IC9MREFQL2k7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJERhdGF7IkN1c3RvbWVyVXNlciRDb3VudCJ9ID0gJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lclVzZXIkQ291bnQiKS0+e05hbWV9CiAgICAgICAgICAgIHx8ICJObyBOYW1lICRDb3VudCI7CiAgICB9CiAgICByZXR1cm4gJURhdGE7Cn0KCj1oZWFkMiBDdXN0b21lclNlYXJjaCgpCgp0byBzZWFyY2ggdXNlcnMKCiAgICAjIHRleHQgc2VhcmNoCiAgICBteSAlTGlzdCA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyU2VhcmNoKAogICAgICAgIFNlYXJjaCA9PiAnKnNvbWUqJywgIyBhbHNvICdoYW5zK2h1YmVyJyBwb3NzaWJsZQogICAgICAgIFZhbGlkICA9PiAxLCAgICAgICAgIyAob3B0aW9uYWwpIGRlZmF1bHQgMQogICAgICAgIExpbWl0ICA9PiAxMDAsICAgICAgIyAob3B0aW9uYWwpIG92ZXJyaWRlcyBsaW1pdCBvZiB0aGUgY29uZmlnCiAgICApOwoKICAgICMgdXNlcm5hbWUgc2VhcmNoCiAgICBteSAlTGlzdCA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyU2VhcmNoKAogICAgICAgIFVzZXJMb2dpbiA9PiAnKnNvbWUqJywKICAgICAgICBWYWxpZCAgICAgPT4gMSwgICAgICAgICAjIChvcHRpb25hbCkgZGVmYXVsdCAxCiAgICApOwoKICAgICMgZW1haWwgc2VhcmNoCiAgICBteSAlTGlzdCA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyU2VhcmNoKAogICAgICAgIFBvc3RNYXN0ZXJTZWFyY2ggPT4gJ2VtYWlsQGV4YW1wbGUuY29tJywKICAgICAgICBWYWxpZCAgICAgICAgICAgID0+IDEsICAgICAgICAgICAgICAgICAgICAjIChvcHRpb25hbCkgZGVmYXVsdCAxCiAgICApOwoKICAgICMgc2VhcmNoIGJ5IEN1c3RvbWVySUQKICAgIG15ICVMaXN0ID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJTZWFyY2goCiAgICAgICAgQ3VzdG9tZXJJRCAgICAgICA9PiAnQ3VzdG9tZXJJRDEyMycsCiAgICAgICAgVmFsaWQgICAgICAgICAgICA9PiAxLCAgICAgICAgICAgICAgICAjIChvcHRpb25hbCkgZGVmYXVsdCAxCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyU2VhcmNoIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyByZW1vdmUgbGVhZGluZyBhbmQgZW5kaW5nIHNwYWNlcwogICAgaWYgKCAkUGFyYW17U2VhcmNofSApIHsKICAgICAgICAkUGFyYW17U2VhcmNofSA9fiBzL15ccysvLzsKICAgICAgICAkUGFyYW17U2VhcmNofSA9fiBzL1xzKyQvLzsKICAgIH0KCiAgICAjIEdldCBkeW5hbWljIGZpZWtkIG9iamVjdC4KICAgIG15ICREeW5hbWljRmllbGRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkJyk7CgogICAgbXkgJER5bmFtaWNGaWVsZENvbmZpZ3MgPSAkRHluYW1pY0ZpZWxkT2JqZWN0LT5EeW5hbWljRmllbGRMaXN0R2V0KAogICAgICAgIE9iamVjdFR5cGUgPT4gJ0N1c3RvbWVyVXNlcicsCiAgICAgICAgVmFsaWQgICAgICA9PiAxLAogICAgKTsKCiAgICBteSAlRHluYW1pY0ZpZWxkTG9va3VwID0gbWFwIHsgJF8tPntOYW1lfSA9PiAkXyB9IEB7JER5bmFtaWNGaWVsZENvbmZpZ3N9OwoKICAgICMgR2V0IGR5bmFtaWMgZmllbGQgYmFja2VuZCBvYmplY3QuCiAgICBteSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQnKTsKCiAgICBteSAlRGF0YTsKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKCiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9OwoKICAgICAgICAjIHNlYXJjaCBkeW5hbWljIGZpZWxkIHZhbHVlcywgaWYgY29uZmlndXJlZAogICAgICAgIG15ICRNYXAgPSAkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifS0+e0N1c3RvbWVyVXNlck1hcH0tPntNYXB9OwogICAgICAgIGlmICggSXNBcnJheVJlZldpdGhEYXRhKCRNYXApICkgewoKICAgICAgICAgICAgIyBmZXRjaCBkeW5hbWljIGZpZWxkIG5hbWVzIHRoYXQgYXJlIGNvbmZpZ3VyZWQgaW4gTWFwCiAgICAgICAgICAgICMgb25seSB0aGVzZSB3aWxsIGJlIGNvbnNpZGVyZWQgZm9yIGFueSBvdGhlciBzZWFyY2ggY29uZmlnCiAgICAgICAgICAgICMgWyAnRHluYW1pY0ZpZWxkX05hbWVfWCcsIHVuZGVmLCAnTmFtZV9YJywgMCwgMCwgJ2R5bmFtaWNfZmllbGQnLCB1bmRlZiwgMCwgdW5kZWYsIHVuZGVmLCBdLAogICAgICAgICAgICBteSAlRHluYW1pY0ZpZWxkTmFtZXMgPSBtYXAgeyAkXy0+WzJdID0+IDEgfSBncmVwIHsgJF8tPls1XSBlcSAnZHluYW1pY19maWVsZCcgfSBAeyRNYXB9OwoKICAgICAgICAgICAgaWYgKCBJc0hhc2hSZWZXaXRoRGF0YSggXCVEeW5hbWljRmllbGROYW1lcyApICkgewogICAgICAgICAgICAgICAgbXkgJEZvdW5kRHluYW1pY0ZpZWxkT2JqZWN0SURzOwogICAgICAgICAgICAgICAgbXkgJFNlYXJjaEZpZWxkczsKICAgICAgICAgICAgICAgIG15ICRTZWFyY2hQYXJhbTsKCiAgICAgICAgICAgICAgICAjIGNoZWNrIHdoaWNoIG9mIHRoZSBkeW5hbWljIGZpZWxkcyBjb25maWd1cmVkIGluIE1hcCBhcmUgYWxzbwogICAgICAgICAgICAgICAgIyBjb25maWd1cmVkIGluIFNlYXJjaEZpZWxkcwoKICAgICAgICAgICAgICAgICMgcGFyYW0gU2VhcmNoCiAgICAgICAgICAgICAgICBpZiAoIGRlZmluZWQgJFBhcmFte1NlYXJjaH0gJiYgbGVuZ3RoICRQYXJhbXtTZWFyY2h9ICkgewogICAgICAgICAgICAgICAgICAgICRTZWFyY2hGaWVsZHMgPSAkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifS0+e0N1c3RvbWVyVXNlck1hcH0tPntDdXN0b21lclVzZXJTZWFyY2hGaWVsZHN9OwogICAgICAgICAgICAgICAgICAgICRTZWFyY2hQYXJhbSAgPSAkUGFyYW17U2VhcmNofTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAjIHBhcmFtIFBvc3RNYXN0ZXJTZWFyY2gKICAgICAgICAgICAgICAgIGVsc2lmICggZGVmaW5lZCAkUGFyYW17UG9zdE1hc3RlclNlYXJjaH0gJiYgbGVuZ3RoICRQYXJhbXtQb3N0TWFzdGVyU2VhcmNofSApIHsKICAgICAgICAgICAgICAgICAgICAkU2VhcmNoRmllbGRzCiAgICAgICAgICAgICAgICAgICAgICAgID0gJFNlbGYtPnsiQ3VzdG9tZXJVc2VyJENvdW50In0tPntDdXN0b21lclVzZXJNYXB9LT57Q3VzdG9tZXJVc2VyUG9zdE1hc3RlclNlYXJjaEZpZWxkc307CiAgICAgICAgICAgICAgICAgICAgJFNlYXJjaFBhcmFtID0gJFBhcmFte1Bvc3RNYXN0ZXJTZWFyY2h9OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICMgc2VhcmNoIGR5bmFtaWMgZmllbGQgdmFsdWVzCiAgICAgICAgICAgICAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSgkU2VhcmNoRmllbGRzKSApIHsKICAgICAgICAgICAgICAgICAgICBteSBAU2VhcmNoRHluYW1pY0ZpZWxkTmFtZXMgPSBncmVwIHsgZXhpc3RzICREeW5hbWljRmllbGROYW1lc3skX30gfSBAeyRTZWFyY2hGaWVsZHN9OwogICAgICAgICAgICAgICAgICAgIG15IEBTZWFyY2hEeW5hbWljRmllbGRJRHM7CgogICAgICAgICAgICAgICAgICAgIG15ICVGb3VuZER5bmFtaWNGaWVsZE9iamVjdElEczsKICAgICAgICAgICAgICAgICAgICBGSUVMRE5BTUU6CiAgICAgICAgICAgICAgICAgICAgZm9yIG15ICRGaWVsZE5hbWUgKEBTZWFyY2hEeW5hbWljRmllbGROYW1lcykgewoKICAgICAgICAgICAgICAgICAgICAgICAgbXkgJER5bmFtaWNGaWVsZENvbmZpZyA9ICREeW5hbWljRmllbGRMb29rdXB7JEZpZWxkTmFtZX07CgogICAgICAgICAgICAgICAgICAgICAgICBuZXh0IEZJRUxETkFNRSBpZiAhSXNIYXNoUmVmV2l0aERhdGEoJER5bmFtaWNGaWVsZENvbmZpZyk7CgogICAgICAgICAgICAgICAgICAgICAgICBteSAkRHluYW1pY0ZpZWxkVmFsdWVzID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlU2VhcmNoKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWFyY2ggICAgICAgICAgICAgPT4gJFNlYXJjaFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBJc0FycmF5UmVmV2l0aERhdGEoJER5bmFtaWNGaWVsZFZhbHVlcykgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgbXkgJER5bmFtaWNGaWVsZFZhbHVlICggQHskRHluYW1pY0ZpZWxkVmFsdWVzfSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkRm91bmREeW5hbWljRmllbGRPYmplY3RJRHN7ICREeW5hbWljRmllbGRWYWx1ZS0+e09iamVjdElEfSB9ID0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgJEZvdW5kRHluYW1pY0ZpZWxkT2JqZWN0SURzID0gWyBrZXlzICVGb3VuZER5bmFtaWNGaWVsZE9iamVjdElEcyBdOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICMgZXhlY3V0ZSBiYWNrZW5kIHNlYXJjaCBmb3IgZm91bmQgb2JqZWN0IElEcwogICAgICAgICAgICAgICAgIyB0aGlzIGRhdGEgaXMgYmVpbmcgbWVyZ2VkIHdpdGggdGhlIGZvbGxvd2luZyBDdXN0b21lclNlYXJjaCBjYWxsCiAgICAgICAgICAgICAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSgkRm91bmREeW5hbWljRmllbGRPYmplY3RJRHMpICkgewoKICAgICAgICAgICAgICAgICAgICBteSAkT2JqZWN0TmFtZXMgPSAkRHluYW1pY0ZpZWxkT2JqZWN0LT5PYmplY3RNYXBwaW5nR2V0KAogICAgICAgICAgICAgICAgICAgICAgICBPYmplY3RJRCAgID0+ICRGb3VuZER5bmFtaWNGaWVsZE9iamVjdElEcywKICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0VHlwZSA9PiAnQ3VzdG9tZXJVc2VyJywKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICAgICBPQkpFQ1ROQU1FOgogICAgICAgICAgICAgICAgICAgIGZvciBteSAkT2JqZWN0TmFtZSAoIHZhbHVlcyAleyRPYmplY3ROYW1lc30gKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgT0JKRUNUTkFNRSBpZiBleGlzdHMgJERhdGF7JE9iamVjdE5hbWV9OwoKICAgICAgICAgICAgICAgICAgICAgICAgbXkgJVNlYXJjaFBhcmFtID0gJVBhcmFtOwogICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgJFNlYXJjaFBhcmFte1NlYXJjaH07CiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSAkU2VhcmNoUGFyYW17UG9zdE1hc3RlclNlYXJjaH07CgogICAgICAgICAgICAgICAgICAgICAgICAkU2VhcmNoUGFyYW17VXNlckxvZ2lufSA9ICRPYmplY3ROYW1lOwoKICAgICAgICAgICAgICAgICAgICAgICAgbXkgJVN1YkRhdGEgPSAkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifS0+Q3VzdG9tZXJTZWFyY2goJVNlYXJjaFBhcmFtKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICMgVXNlckxvZ2luIHNlYXJjaCBkb2VzIGEgd2lsZC1jYXJkIHNlYXJjaCwgYnV0IGluIHRoaXMgY2FzZSBvbmx5IHRoZQogICAgICAgICAgICAgICAgICAgICAgICAjIGV4YWN0IG1hdGNoaW5nIHVzZXIgbG9naW4gaXMgcmVsZXZhbnQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBJc0hhc2hSZWZXaXRoRGF0YSggXCVTdWJEYXRhICkgJiYgZXhpc3RzICRTdWJEYXRheyRPYmplY3ROYW1lfSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICVEYXRhID0gKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRPYmplY3ROYW1lID0+ICRTdWJEYXRheyRPYmplY3ROYW1lfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAlRGF0YQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBnZXQgY3VzdG9tZXIgc2VhcmNoIHJlc3VsdCBvZiBiYWNrZW5kIGFuZCBtZXJnZSBpdAogICAgICAgIG15ICVTdWJEYXRhID0gJFNlbGYtPnsiQ3VzdG9tZXJVc2VyJENvdW50In0tPkN1c3RvbWVyU2VhcmNoKCVQYXJhbSk7CgogICAgICAgICVEYXRhID0gKCAlU3ViRGF0YSwgJURhdGEgKTsKICAgIH0KCiAgICAjIC0tLQogICAgIyBSb3RoZXJPU1M6IENoZWNrIGlmIHRoZSB1c2VyIGhhcyBwZXJtaXNzaW9uIHRvIHNlZSB0aGlzIGN1c3RvbWVyIHVzZXIuIAogICAgIyBUT0RPOiBSZW1vdmUgdGhpcyBpZiB0aGUgREIvTERBUCBmdW5jdGlvbiBDdXN0b21lclNlYXJjaCBpcyBmdWxseSBpbXBsZW1lbnRlZC4KICAgICMgLS0tCiAgICBpZiAoICRTZWxmLT57TXVsdGl0ZW5hbmN5fSApIHsKICAgICAgICBmb3IgbXkgJEN1c3RvbWVyVXNlckxvZ2luICgga2V5cyAlRGF0YSApIHsKICAgICAgICAgICAgbXkgJVVzZXJEYXRhID0gJFNlbGYtPkN1c3RvbWVyVXNlckRhdGFHZXQoCiAgICAgICAgICAgICAgICBVc2VyID0+ICRDdXN0b21lclVzZXJMb2dpbiwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGlmICggISVVc2VyRGF0YSApIHsKICAgICAgICAgICAgICAgIGRlbGV0ZSAkRGF0YXskQ3VzdG9tZXJVc2VyTG9naW59OwogICAgICAgICAgICAgICAgbmV4dDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgICMgLS0tCgogICAgcmV0dXJuICVEYXRhOwp9Cgo9aGVhZDIgQ3VzdG9tZXJTZWFyY2hEZXRhaWwoKQoKVG8gZmluZCBjdXN0b21lciB1c2VyIGluIHRoZSBzeXN0ZW0uCgpUaGUgc2VhcmNoIGNyaXRlcmlhIGFyZSBsb2dpY2FsbHkgQU5EIGNvbm5lY3RlZC4KV2hlbiBhIGxpc3QgaXMgcGFzc2VkIGFzIGNyaXRlcmlhLCB0aGUgaW5kaXZpZHVhbCBtZW1iZXJzIGFyZSBPUiBjb25uZWN0ZWQuCldoZW4gYW4gdW5kZWYgb3IgYSByZWZlcmVuY2UgdG8gYW4gZW1wdHkgYXJyYXkgaXMgcGFzc2VkLCB0aGVuIHRoZSBzZWFyY2ggY3JpdGVyaWEKaXMgaWdub3JlZC4KClJldHVybnMgZWl0aGVyIGEgbGlzdCwgYXMgYW4gYXJyYXlyZWYsIG9yIGEgY291bnQgb2YgZm91bmQgY3VzdG9tZXIgdXNlciBpZHMuClRoZSBjb3VudCBvZiByZXN1bHRzIGlzIHJldHVybmVkIHdoZW4gdGhlIHBhcmFtZXRlciBDPFJlc3VsdCA9ICdDT1VOVCc+IGlzIHBhc3NlZC4KCiAgICBteSAkQ3VzdG9tZXJVc2VySURzUmVmID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJTZWFyY2hEZXRhaWwoCgogICAgICAgICMgYWxsIHNlYXJjaCBmaWVsZHMgcG9zc2libGUgd2hpY2ggYXJlIGRlZmluZWQgaW4gQ3VzdG9tZXJVc2VyOjpFbmhhbmNlZFNlYXJjaEZpZWxkcwogICAgICAgIFVzZXJMb2dpbiAgICAgPT4gJ2V4YW1wbGUqJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIChvcHRpb25hbCkKICAgICAgICBVc2VyRmlyc3RuYW1lID0+ICdGaXJzdG4qJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAob3B0aW9uYWwpCgogICAgICAgICMgc3BlY2lhbCBwYXJhbWV0ZXJzCiAgICAgICAgQ3VzdG9tZXJDb21wYW55U2VhcmNoQ3VzdG9tZXJJRHMgPT4gWyAnZXhhbXBsZS5jb20nIF0sICAgICAgICAgICMgKG9wdGlvbmFsKQogICAgICAgIEV4Y2x1ZGVVc2VyTG9naW5zICAgICAgICAgICAgICAgID0+IFsgJ2V4YW1wbGUnLCAnZG9lam9obicgXSwgICAjIChvcHRpb25hbCkKCiAgICAgICAgIyBhcnJheSBwYXJhbWV0ZXJzIGFyZSB1c2VkIHdpdGggbG9naWNhbCBPUiBvcGVyYXRvciAoYWxsIHZhbHVlcyBhcmUgcG9zc2libGUgd2hpY2gKICAgICAgICBhcmUgZGVmaW5lZCBpbiB0aGUgY29uZmlnIHNlbGVjdGlvbiBoYXNoIGZvciB0aGUgZmllbGQpCiAgICAgICAgVXNlckNvdW50cnkgICAgICAgICAgICAgID0+IFsgJ0F1c3RyaWEnLCAnR2VybWFueScsIF0sICAgICAgICAgICMgKG9wdGlvbmFsKQoKICAgICAgICAjIER5bmFtaWNGaWVsZHMKICAgICAgICAjICAgQXQgbGVhc3Qgb25lIG9wZXJhdG9yIG11c3QgYmUgc3BlY2lmaWVkLiBPcGVyYXRvcnMgd2lsbCBiZSBjb25uZWN0ZWQgd2l0aCBBTkQsCiAgICAgICAgIyAgICAgICB2YWx1ZXMgaW4gYW4gb3BlcmF0b3Igd2l0aCBPUi4KICAgICAgICAjICAgWW91IGNhbiBhbHNvIHBhc3MgbW9yZSB0aGFuIG9uZSBhcmd1bWVudCB0byBhbiBvcGVyYXRvcjogWyd2YWx1ZTEnLCAndmFsdWUyJ10KICAgICAgICBEeW5hbWljRmllbGRfRmllbGROYW1lWCA9PiB7CiAgICAgICAgICAgIEVxdWFscyAgICAgICAgICAgID0+IDEyMywKICAgICAgICAgICAgTGlrZSAgICAgICAgICAgICAgPT4gJ3ZhbHVlKicsICAgICAgICAgICAgICAgICMgImVxdWFscyIgb3BlcmF0b3Igd2l0aCB3aWxkY2FyZCBzdXBwb3J0CiAgICAgICAgICAgIEdyZWF0ZXJUaGFuICAgICAgID0+ICcyMDAxLTAxLTAxIDAxOjAxOjAxJywKICAgICAgICAgICAgR3JlYXRlclRoYW5FcXVhbHMgPT4gJzIwMDEtMDEtMDEgMDE6MDE6MDEnLAogICAgICAgICAgICBTbWFsbGVyVGhhbiAgICAgICA9PiAnMjAwMi0wMi0wMiAwMjowMjowMicsCiAgICAgICAgICAgIFNtYWxsZXJUaGFuRXF1YWxzID0+ICcyMDAyLTAyLTAyIDAyOjAyOjAyJywKICAgICAgICB9CgogICAgICAgIE9yZGVyQnkgPT4gWyAnVXNlckxvZ2luJywgJ1VzZXJDdXN0b21lcklEJyBdLCAgICAgICAgICAgICAgICAgICAjIChvcHRpb25hbCkKICAgICAgICAjIGlnbm9yZWQgaWYgdGhlIHJlc3VsdCB0eXBlIGlzICdDT1VOVCcKICAgICAgICAjIGRlZmF1bHQ6IFsgJ1VzZXJMb2dpbicgXQogICAgICAgICMgKGFsbCBzZWFyY2ggZmllbGRzIHBvc3NpYmxlIHdoaWNoIGFyZSBkZWZpbmVkIGluCiAgICAgICAgQ3VzdG9tZXJVc2VyOjpFbmhhbmNlZFNlYXJjaEZpZWxkcykKCiAgICAgICAgIyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIGZvciBPcmRlckJ5OgogICAgICAgICMgVGhlIE9yZGVyQnlEaXJlY3Rpb24gY2FuIGJlIHNwZWNpZmllZCBmb3IgZWFjaCBPcmRlckJ5IGF0dHJpYnV0ZS4KICAgICAgICAjIFRoZSBwYWlyaW5nIGlzIG1hZGUgYnkgdGhlIGFycmF5IGluZGljZXMuCgogICAgICAgIE9yZGVyQnlEaXJlY3Rpb24gPT4gWyAnRG93bicsICdVcCcgXSwgICAgICAgICAgICAgICAgICAgICAgICAgICMgKG9wdGlvbmFsKQogICAgICAgICMgaWdub3JlZCBpZiB0aGUgcmVzdWx0IHR5cGUgaXMgJ0NPVU5UJwogICAgICAgICMgKERvd24gfCBVcCkgRGVmYXVsdDogWyAnRG93bicgXQoKICAgICAgICBSZXN1bHQgPT4gJ0FSUkFZJyB8fCAnQ09VTlQnLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIChvcHRpb25hbCkKICAgICAgICAjIGRlZmF1bHQ6IEFSUkFZLCByZXR1cm5zIGFuIGFycmF5IG9mIGNoYW5nZSBpZHMKICAgICAgICAjIENPVU5UIHJldHVybnMgYSBzY2FsYXIgd2l0aCB0aGUgbnVtYmVyIG9mIGZvdW5kIGNoYW5nZXMKCiAgICAgICAgTGltaXQgPT4gMTAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAob3B0aW9uYWwpCiAgICAgICAgIyBpZ25vcmVkIGlmIHRoZSByZXN1bHQgdHlwZSBpcyAnQ09VTlQnCiAgICApOwoKUmV0dXJuczoKClJlc3VsdDogJ0FSUkFZJwoKICAgIEBDdXN0b21lclVzZXJJRHMgPSAoIDEsIDIsIDMgKTsKClJlc3VsdDogJ0NPVU5UJwoKICAgICRDdXN0b21lclVzZXJJRHMgPSAxMDsKCj1jdXQKCnN1YiBDdXN0b21lclNlYXJjaERldGFpbCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgZ2V0IGFsbCBnZW5lcmFsIHNlYXJjaCBmaWVsZHMgKHdpdGhvdXQgYSByZXN0cmljdGlvbiB0byBhIHNvdXJjZSkKICAgIG15IEBBbGxTZWFyY2hGaWVsZHMgPSAkU2VsZi0+Q3VzdG9tZXJVc2VyU2VhcmNoRmllbGRzKCk7CgogICAgIyBnZW5lcmF0ZSBhIGhhc2ggd2l0aCB0aGUgY3VzdG9tZXIgdXNlciBzb3VyY2VzIHdoaWNoIG11c3QgYmUgc2VhcmNoZWQKICAgIG15ICVTZWFyY2hDdXN0b21lclVzZXJTb3VyY2VzOwoKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJFNlbGYtPnsiQ3VzdG9tZXJVc2VyJENvdW50In07CgogICAgICAgICMgZ2V0IHRoZSBzZWFyY2ggZmllbGRzIGZvciB0aGUgY3VycmVudCBzb3VyY2UKICAgICAgICBteSBAU291cmNlU2VhcmNoRmllbGRzID0gJFNlbGYtPkN1c3RvbWVyVXNlclNlYXJjaEZpZWxkcygKICAgICAgICAgICAgU291cmNlID0+ICJDdXN0b21lclVzZXIkQ291bnQiLAogICAgICAgICk7CiAgICAgICAgbXkgJUxvb2t1cFNvdXJjZVNlYXJjaEZpZWxkcyA9IG1hcCB7ICRfLT57TmFtZX0gPT4gMSB9IEBTb3VyY2VTZWFyY2hGaWVsZHM7CgogICAgICAgICMgY2hlY2sgaWYgYWxsIHNlYXJjaCBwYXJhbSBleGlzdHMgaW4gdGhlIHNlYXJjaCBmaWVsZHMgZnJvbSB0aGUgY3VycmVudCBzb3VyY2UKICAgICAgICBTRUFSQ0hGSUVMRDoKICAgICAgICBmb3IgbXkgJFNlYXJjaEZpZWxkIChAQWxsU2VhcmNoRmllbGRzKSB7CgogICAgICAgICAgICBuZXh0IFNFQVJDSEZJRUxEIGlmICEkUGFyYW17ICRTZWFyY2hGaWVsZC0+e05hbWV9IH07CgogICAgICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJExvb2t1cFNvdXJjZVNlYXJjaEZpZWxkc3sgJFNlYXJjaEZpZWxkLT57TmFtZX0gfTsKICAgICAgICB9CiAgICAgICAgJFNlYXJjaEN1c3RvbWVyVXNlclNvdXJjZXN7IkN1c3RvbWVyVXNlciRDb3VudCJ9ID0gXEBTb3VyY2VTZWFyY2hGaWVsZHM7CiAgICB9CgogICAgIyBzZXQgdGhlIGRlZmF1bHQgYmVoYXZpb3VyIGZvciB0aGUgcmV0dXJuIHR5cGUKICAgICRQYXJhbXtSZXN1bHR9IHx8PSAnQVJSQVknOwoKICAgIGlmICggJFBhcmFte1Jlc3VsdH0gZXEgJ0NPVU5UJyApIHsKCiAgICAgICAgbXkgJElEc0NvdW50ID0gMDsKCiAgICAgICAgU09VUkNFOgogICAgICAgIGZvciBteSAkU291cmNlICggc29ydCBrZXlzICVTZWFyY2hDdXN0b21lclVzZXJTb3VyY2VzICkgewogICAgICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJFNlbGYtPnskU291cmNlfTsKCiAgICAgICAgICAgIG15ICRTdWJJRHNDb3VudCA9ICRTZWxmLT57JFNvdXJjZX0tPkN1c3RvbWVyU2VhcmNoRGV0YWlsKAogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgU2VhcmNoRmllbGRzID0+ICRTZWFyY2hDdXN0b21lclVzZXJTb3VyY2VzeyRTb3VyY2V9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmV0dXJuIGlmICFkZWZpbmVkICRTdWJJRHNDb3VudDsKCiAgICAgICAgICAgICRJRHNDb3VudCArPSAkU3ViSURzQ291bnQgfHwgMDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRJRHNDb3VudDsKICAgIH0KICAgIGVsc2UgewoKICAgICAgICBteSBASURzOwoKICAgICAgICBteSAkUmVzdWx0Q291bnQgPSAwOwoKICAgICAgICBTT1VSQ0U6CiAgICAgICAgZm9yIG15ICRTb3VyY2UgKCBzb3J0IGtleXMgJVNlYXJjaEN1c3RvbWVyVXNlclNvdXJjZXMgKSB7CiAgICAgICAgICAgIG5leHQgU09VUkNFIGlmICEkU2VsZi0+eyRTb3VyY2V9OwoKICAgICAgICAgICAgbXkgJFN1YklEcyA9ICRTZWxmLT57JFNvdXJjZX0tPkN1c3RvbWVyU2VhcmNoRGV0YWlsKAogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgU2VhcmNoRmllbGRzID0+ICRTZWFyY2hDdXN0b21lclVzZXJTb3VyY2VzeyRTb3VyY2V9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmV0dXJuIGlmICFkZWZpbmVkICRTdWJJRHM7CgogICAgICAgICAgICBuZXh0IFNPVVJDRSBpZiAhSXNBcnJheVJlZldpdGhEYXRhKCRTdWJJRHMpOwoKICAgICAgICAgICAgcHVzaCBASURzLCBAeyRTdWJJRHN9OwoKICAgICAgICAgICAgJFJlc3VsdENvdW50Kys7CiAgICAgICAgfQoKICAgICAgICAjIGlmIHdlIGhhdmUgbW9yZSB0aGVuIG9uZSBzZWFyY2ggcmVzdWx0cyBmcm9tIGRpZmZyZW50IHNvdXJjZXMsIHdlIG5lZWQgYSByZXNvcnRpbmcKICAgICAgICAjIGJlY2F1c2Ugb2YgdGhlIG1lcmdlZCBzaW5nbGUgcmVzdWx0cwogICAgICAgIGlmICggJFJlc3VsdENvdW50ID4gMSApIHsKCiAgICAgICAgICAgIG15IEBVc2VyRGF0YUxpc3Q7CgogICAgICAgICAgICBmb3IgbXkgJElEIChASURzKSB7CgogICAgICAgICAgICAgICAgbXkgJVVzZXJEYXRhID0gJFNlbGYtPkN1c3RvbWVyVXNlckRhdGFHZXQoCiAgICAgICAgICAgICAgICAgICAgVXNlciA9PiAkSUQsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgcHVzaCBAVXNlckRhdGFMaXN0LCBcJVVzZXJEYXRhOwogICAgICAgICAgICB9CgogICAgICAgICAgICBteSAkT3JkZXJCeSA9ICdVc2VyTG9naW4nOwogICAgICAgICAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSggJFBhcmFte09yZGVyQnl9ICkgKSB7CiAgICAgICAgICAgICAgICAkT3JkZXJCeSA9ICRQYXJhbXtPcmRlckJ5fS0+WzBdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSggJFBhcmFte09yZGVyQnlEaXJlY3Rpb259ICkgJiYgJFBhcmFte09yZGVyQnlEaXJlY3Rpb259LT5bMF0gZXEgJ1VwJyApIHsKICAgICAgICAgICAgICAgIEBVc2VyRGF0YUxpc3QgPSBzb3J0IHsgbGMoICRhLT57JE9yZGVyQnl9ICkgY21wIGxjKCAkYi0+eyRPcmRlckJ5fSApIH0gQFVzZXJEYXRhTGlzdDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIEBVc2VyRGF0YUxpc3QgPSBzb3J0IHsgbGMoICRiLT57JE9yZGVyQnl9ICkgY21wIGxjKCAkYS0+eyRPcmRlckJ5fSApIH0gQFVzZXJEYXRhTGlzdDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCAkUGFyYW17TGltaXR9ICYmIHNjYWxhciBAVXNlckRhdGFMaXN0ID4gJFBhcmFte0xpbWl0fSApIHsKICAgICAgICAgICAgICAgIHNwbGljZSBAVXNlckRhdGFMaXN0LCAkUGFyYW17TGltaXR9OwogICAgICAgICAgICB9CgogICAgICAgICAgICBASURzID0gbWFwIHsgJF8tPntVc2VyTG9naW59IH0gQFVzZXJEYXRhTGlzdDsKICAgICAgICB9CgogICAgICAgICMgLS0tCiAgICAgICAgIyBSb3RoZXJPU1M6IENoZWNrIHBlcm1pc3Npb24gZm9yIGV2ZXJ5IHNpbmdsZSBjdXN0b21lciB1c2VyLgogICAgICAgICMgLS0tCiAgICAgICAgaWYgKCAkU2VsZi0+e011bHRpdGVuYW5jeX0gKSB7CiAgICAgICAgICAgIG15IEBOZXdJRFMgPSBASURzOwogICAgICAgICAgICBASURzID0gKCk7CgogICAgICAgICAgICBmb3IgbXkgJElEIChATmV3SURTKSB7CiAgICAgICAgICAgICAgICBteSAlVXNlckRhdGEgPSAkU2VsZi0+Q3VzdG9tZXJVc2VyRGF0YUdldCgKICAgICAgICAgICAgICAgICAgICBVc2VyID0+ICRJRCwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgaWYgKCVVc2VyRGF0YSkgewogICAgICAgICAgICAgICAgICAgIHB1c2ggQElEcywgJElEOyAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjIC0tLQoKICAgICAgICByZXR1cm4gXEBJRHM7CiAgICB9Cn0KCj1oZWFkMiBDdXN0b21lclVzZXJTZWFyY2hGaWVsZHMoKQoKR2V0IGEgbGlzdCBvZiB0aGUgZGVmaW5lZCBzZWFyY2ggZmllbGRzIChvcHRpb25hbCBvbmx5IHRoZSByZWxldmFudCBmaWVsZHMgZm9yIHRoZSBnaXZlbiBzb3VyY2UpLgoKICAgIG15IEBTZWFjaEZpZWxkcyA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlclNlYXJjaEZpZWxkcygKICAgICAgICBTb3VyY2UgPT4gJ0N1c3RvbWVyVXNlcicsICMgb3B0aW9uYWwsIGJ1dCBpbXBvcnRhbnQgaW4gdGhlIEN1c3RvbWVyU2VhcmNoRGV0YWlsIHRvIGdldCB0aGUgcmlnaHQgZGF0YWJhc2UgZmllbGRzCiAgICApOwoKUmV0dXJucyBhbiBhcnJheSBvZiBoYXNoIHJlZmVyZW5jZXMuCgogICAgQFNlYWNoRmllbGRzID0gKAogICAgICAgIHsKICAgICAgICAgICAgTmFtZSAgICAgICAgICA9PiAnVXNlckVtYWlsJywKICAgICAgICAgICAgTGFiZWwgICAgICAgICA9PiAnRW1haWwnLAogICAgICAgICAgICBUeXBlICAgICAgICAgID0+ICdJbnB1dCcsCiAgICAgICAgICAgIERhdGFiYXNlRmllbGQgPT4gJ21haWwnLAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICBOYW1lICAgICAgICAgICA9PiAnVXNlckNvdW50cnknLAogICAgICAgICAgICBMYWJlbCAgICAgICAgICA9PiAnQ291bnRyeScsCiAgICAgICAgICAgIFR5cGUgICAgICAgICAgID0+ICdTZWxlY3Rpb24nLAogICAgICAgICAgICBTZWxlY3Rpb25zRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAnR2VybWFueScgICAgICAgID0+ICdHZXJtYW55JywKICAgICAgICAgICAgICAgICdVbml0ZWQgS2luZ2RvbScgPT4gJ1VuaXRlZCBLaW5nZG9tJywKICAgICAgICAgICAgICAgICdVbml0ZWQgU3RhdGVzJyAgPT4gJ1VuaXRlZCBTdGF0ZXMnLAogICAgICAgICAgICAgICAgLi4uCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIERhdGFiYXNlRmllbGQgPT4gJ2NvdW50cnknLAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICBOYW1lICAgICAgICAgID0+ICdEeW5hbWljRmllbGRfU2t5cGVBY2NvdW50TmFtZScsCiAgICAgICAgICAgIExhYmVsICAgICAgICAgPT4gJycsCiAgICAgICAgICAgIFR5cGUgICAgICAgICAgPT4gJ0R5bmFtaWNGaWVsZCcsCiAgICAgICAgICAgIERhdGFiYXNlRmllbGQgPT4gJ1NreXBlQWNjb3VudE5hbWUnLAogICAgICAgIH0sCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyVXNlclNlYXJjaEZpZWxkcyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgR2V0IHRoZSBzZWFyY2ggZmllbGRzIGZyb20gYWxsIGN1c3RvbWVyIHVzZXIgbWFwcyAobWVyZ2UgZnJvbSBhbGwgbWFwcyB0b2dldGhlcikuCiAgICBteSBAU2VhcmNoRmllbGRzOwoKICAgIG15ICVTZWFyY2hGaWVsZHNFeGlzdHM7CgogICAgU09VUkNFOgogICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewogICAgICAgIG5leHQgU09VUkNFIGlmICEkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifTsKICAgICAgICBuZXh0IFNPVVJDRSBpZiAkUGFyYW17U291cmNlfSAmJiAkUGFyYW17U291cmNlfSBuZSAiQ3VzdG9tZXJVc2VyJENvdW50IjsKCiAgICAgICAgRU5UUlk6CiAgICAgICAgZm9yIG15ICRFbnRyeSAoIEB7ICRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9LT57Q3VzdG9tZXJVc2VyTWFwfS0+e01hcH0gfSApIHsKCiAgICAgICAgICAgIG15ICRTZWFyY2hGaWVsZE5hbWUgPSAkRW50cnktPlswXTsKCiAgICAgICAgICAgIG5leHQgRU5UUlkgaWYgJFNlYXJjaEZpZWxkc0V4aXN0c3skU2VhcmNoRmllbGROYW1lfTsKICAgICAgICAgICAgbmV4dCBFTlRSWSBpZiAkU2VhcmNoRmllbGROYW1lID1+IG17KFBhc3N3b3JkfFB3KVxkKiR9c214aTsKCiAgICAgICAgICAgICMgUmVtZWJlciB0aGUgYWxyZWFkeSBjb2xsZWN0ZWQgc2VhcmNoIGZpZWxkIG5hbWUuCiAgICAgICAgICAgICRTZWFyY2hGaWVsZHNFeGlzdHN7JFNlYXJjaEZpZWxkTmFtZX0gPSAxOwoKICAgICAgICAgICAgbXkgJUZpZWxkQ29uZmlnID0gJFNlbGYtPkdldEZpZWxkQ29uZmlnKAogICAgICAgICAgICAgICAgRmllbGROYW1lID0+ICRTZWFyY2hGaWVsZE5hbWUsCiAgICAgICAgICAgICAgICBTb3VyY2UgICAgPT4gJFBhcmFte1NvdXJjZX0sICAgICAjIHRvIGdldCB0aGUgcmlnaHQgZGF0YWJhc2UgZmllbGQgZm9yIHRoZSBnaXZlbiBzb3VyY2UKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIG5leHQgRU5UUlkgaWYgISVGaWVsZENvbmZpZzsKCiAgICAgICAgICAgIG15ICVTZWFyY2hGaWVsZERhdGEgPSAoCiAgICAgICAgICAgICAgICAlRmllbGRDb25maWcsCiAgICAgICAgICAgICAgICBOYW1lID0+ICRTZWFyY2hGaWVsZE5hbWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBteSAlU2VsZWN0aW9uc0RhdGEgPSAkU2VsZi0+R2V0RmllbGRTZWxlY3Rpb25zKAogICAgICAgICAgICAgICAgRmllbGROYW1lID0+ICRTZWFyY2hGaWVsZE5hbWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoICRTZWFyY2hGaWVsZERhdGF7U3RvcmFnZVR5cGV9IGVxICdkeW5hbWljX2ZpZWxkJyApIHsKICAgICAgICAgICAgICAgICRTZWFyY2hGaWVsZERhdGF7VHlwZX0gPSAnRHluYW1pY0ZpZWxkJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNpZiAoJVNlbGVjdGlvbnNEYXRhKSB7CiAgICAgICAgICAgICAgICAkU2VhcmNoRmllbGREYXRhe1R5cGV9ICAgICAgICAgICA9ICdTZWxlY3Rpb24nOwogICAgICAgICAgICAgICAgJFNlYXJjaEZpZWxkRGF0YXtTZWxlY3Rpb25zRGF0YX0gPSBcJVNlbGVjdGlvbnNEYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJFNlYXJjaEZpZWxkRGF0YXtUeXBlfSA9ICdJbnB1dCc7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHB1c2ggQFNlYXJjaEZpZWxkcywgXCVTZWFyY2hGaWVsZERhdGE7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBAU2VhcmNoRmllbGRzOwp9Cgo9aGVhZDIgR2V0RmllbGRDb25maWcoKQoKVGhpcyBmdW5jdGlvbiBjb2xsZWN0IHNvbWUgZmllbGQgY29uZmlnIGluZm9ybWF0aW9uIGZyb20gdGhlIGN1c3RvbWVyIHVzZXIgbWFwLgoKICAgIG15ICVGaWVsZENvbmZpZyA9ICRDdXN0b21lclVzZXJPYmplY3QtPkdldEZpZWxkQ29uZmlnKAogICAgICAgIEZpZWxkTmFtZSA9PiAnVXNlckVtYWlsJywKICAgICAgICBTb3VyY2UgICAgPT4gJ0N1c3RvbWVyVXNlcicsICMgb3B0aW9uYWwKICAgICk7CgpSZXR1cm5zIHNvbWUgZmllbGQgY29uZmlnIGluZm9ybWF0aW9uOgoKICAgIG15ICVGaWVsZENvbmZpZyA9ICgKICAgICAgICBMYWJlbCAgICAgICAgID0+ICdFbWFpbCcsCiAgICAgICAgRGF0YWJhc2VGaWVsZCA9PiAnZW1haWwnLAogICAgICAgIFN0b3JhZ2VUeXBlICAgPT4gJ3ZhcicsCiAgICApOwoKPWN1dAoKc3ViIEdldEZpZWxkQ29uZmlnIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgaWYgKCAhJFBhcmFte0ZpZWxkTmFtZX0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkIEZpZWxkTmFtZSEiCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgU09VUkNFOgogICAgZm9yIG15ICRDb3VudCAoICcnLCAxIC4uIDEwICkgewogICAgICAgIG5leHQgU09VUkNFIGlmICEkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifTsKICAgICAgICBuZXh0IFNPVVJDRSBpZiAkUGFyYW17U291cmNlfSAmJiAkUGFyYW17U291cmNlfSBuZSAiQ3VzdG9tZXJVc2VyJENvdW50IjsKCiAgICAgICAgIyBTZWFyY2ggdGhlIHJpZ2h0IGZpZWxkIGFuZCByZXR1cm4gc29tZSBjb25maWcgaW5mb3JtYXRpb24gZnJvbSB0aGUgZmllbGQuCiAgICAgICAgRU5UUlk6CiAgICAgICAgZm9yIG15ICRFbnRyeSAoIEB7ICRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9LT57Q3VzdG9tZXJVc2VyTWFwfS0+e01hcH0gfSApIHsKICAgICAgICAgICAgbmV4dCBFTlRSWSBpZiAkUGFyYW17RmllbGROYW1lfSBuZSAkRW50cnktPlswXTsKCiAgICAgICAgICAgIG15ICVGaWVsZENvbmZpZyA9ICgKICAgICAgICAgICAgICAgIExhYmVsICAgICAgICAgPT4gJEVudHJ5LT5bMV0sCiAgICAgICAgICAgICAgICBEYXRhYmFzZUZpZWxkID0+ICRFbnRyeS0+WzJdLAogICAgICAgICAgICAgICAgU3RvcmFnZVR5cGUgICA9PiAkRW50cnktPls1XSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHJldHVybiAlRmllbGRDb25maWc7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybjsKfQoKPWhlYWQyIEdldEZpZWxkU2VsZWN0aW9ucygpCgpUaGlzIGZ1bmN0aW9uIGNvbGxlY3QgdGhlIHNlbGVjdGlvbnMgZm9yIHRoZSBnaXZlbiBmaWVsZCBuYW1lLCBpZiB0aGUgZmllbGQgaGFzIHNvbWUgc2VsZWN0aW9ucy4KCiAgICBteSAlU2VsZWN0aW9uc0RhdGEgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5HZXRGaWVsZFNlbGVjdGlvbnMoCiAgICAgICAgRmllbGROYW1lID0+ICdVc2VyVGl0bGUnLAogICAgKTsKClJldHVybnMgdGhlIHNlbGVjdGlvbnMgZm9yIHRoZSBnaXZlbiBmaWVsZCBuYW1lIChtZXJnZWQgZnJvbSBhbGwgc291cmNlcykgb3IgYSBlbXB0eSBoYXNoOgoKICAgIG15ICVTZWxlY3Rpb25EYXRhID0gKAogICAgICAgICdNci4nICA9PiAnTXIuJywKICAgICAgICAnTXJzLicgPT4gJ01ycy4nLAogICAgKTsKCj1jdXQKCnN1YiBHZXRGaWVsZFNlbGVjdGlvbnMgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte0ZpZWxkTmFtZX0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkIEZpZWxkTmFtZSEiCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgbXkgJVNlbGVjdGlvbnNEYXRhOwoKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJFNlbGYtPnsiQ3VzdG9tZXJVc2VyJENvdW50In07CiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9LT57Q3VzdG9tZXJVc2VyTWFwfS0+e1NlbGVjdGlvbnN9LT57ICRQYXJhbXtGaWVsZE5hbWV9IH07CgogICAgICAgICVTZWxlY3Rpb25zRGF0YSA9ICgKICAgICAgICAgICAgJVNlbGVjdGlvbnNEYXRhLCAleyAkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifS0+e0N1c3RvbWVyVXNlck1hcH0tPntTZWxlY3Rpb25zfS0+eyAkUGFyYW17RmllbGROYW1lfSB9IH0KICAgICAgICApOwogICAgfQoKICAgICMgTWFrZSBzdXJlIHRoZSBlbmNvZGluZyBzdGFtcCBpcyBzZXQuCiAgICBmb3IgbXkgJEtleSAoIHNvcnQga2V5cyAlU2VsZWN0aW9uc0RhdGEgKSB7CiAgICAgICAgJFNlbGVjdGlvbnNEYXRheyRLZXl9ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkVuY29kZScpLT5FbmNvZGVJbnB1dCggJFNlbGVjdGlvbnNEYXRheyRLZXl9ICk7CiAgICB9CgogICAgIyBEZWZhdWx0IGhhbmRsaW5nIGZvciBmaWVsZCAnVmFsaWRJRCcuCiAgICBpZiAoICElU2VsZWN0aW9uc0RhdGEgJiYgJFBhcmFte0ZpZWxkTmFtZX0gPX4gL15WYWxpZElEL2kgKSB7CiAgICAgICAgJVNlbGVjdGlvbnNEYXRhID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlZhbGlkJyktPlZhbGlkTGlzdCgpOwogICAgfQoKICAgIHJldHVybiAlU2VsZWN0aW9uc0RhdGE7Cn0KCj1oZWFkMiBDdXN0b21lcklETGlzdCgpCgpyZXR1cm4gYSBsaXN0IG9mIHdpdGggYWxsIGtub3duIHVuaXF1ZSBDdXN0b21lcklEcyBvZiB0aGUgcmVnaXN0ZXJlZCBjdXN0b21lcnMgdXNlcnMgKG5vIFNlYXJjaFRlcm0pLApvciBhIGZpbHRlcmVkIGxpc3Qgd2hlcmUgdGhlIEN1c3RvbWVySURzIG11c3QgY29udGFpbiBhIHNlYXJjaCB0ZXJtLgoKICAgIG15IEBDdXN0b21lcklEcyA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVySURMaXN0KAogICAgICAgIFNlYXJjaFRlcm0gID0+ICdzb21lY3VzdG9tZXInLCAgICAjIG9wdGlvbmFsCiAgICAgICAgVmFsaWQgICAgICAgPT4gMSwgICAgICAgICAgICAgICAgICMgb3B0aW9uYWwKICAgICk7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJJRExpc3QgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSBARGF0YTsKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKCiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9OwoKICAgICAgICAjIGdldCBjdXN0b21lciBsaXN0IHJlc3VsdCBvZiBiYWNrZW5kIGFuZCBtZXJnZSBpdAogICAgICAgIHB1c2ggQERhdGEsICRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9LT5DdXN0b21lcklETGlzdCglUGFyYW0pOwogICAgfQoKICAgICMgbWFrZSBlbnRyaWVzIHVuaXF1ZQogICAgbXkgJVRtcDsKICAgIEBUbXB7QERhdGF9ID0gdW5kZWY7CiAgICBARGF0YSA9IHNvcnQgeyBsYyAkYSBjbXAgbGMgJGIgfSBrZXlzICVUbXA7CgogICAgIyAtLS0KICAgICMgUm90aGVyT1NTOiBEb24ndCByZXR1cm4gY3VzdG9tZXIgSURzIGlmIHRoZSBhZ2VudCBkb2VzIG5vdCBoYXZlIHBlcm1pc3Npb24gdG8gdmlldy4KICAgICMgLS0tCiAgICBpZiAoICRTZWxmLT57TXVsdGl0ZW5hbmN5fSApIHsKICAgICAgICBteSBAQ2xlYW5lZEN1c3RvbWVySURzOwoKICAgICAgICBmb3IgbXkgJEN1c3RvbWVySUQgKCBARGF0YSApIHsKICAgICAgICAgICAgbXkgJUNvbXBhbnkgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJDb21wYW55JyktPkN1c3RvbWVyQ29tcGFueUdldCgKICAgICAgICAgICAgICAgIEN1c3RvbWVySUQgPT4gJEN1c3RvbWVySUQsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoICVDb21wYW55ICYmICRDb21wYW55e0N1c3RvbWVySUR9ICkgewogICAgICAgICAgICAgICAgcHVzaCBAQ2xlYW5lZEN1c3RvbWVySURzLCAkQ3VzdG9tZXJJRDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQERhdGEgPSBAQ2xlYW5lZEN1c3RvbWVySURzOwogICAgfQogICAgIyAtLS0KCiAgICByZXR1cm4gQERhdGE7Cn0KCj1oZWFkMiBDdXN0b21lck5hbWUoKQoKZ2V0IGN1c3RvbWVyIHVzZXIgbmFtZQoKICAgIG15ICROYW1lID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJOYW1lKAogICAgICAgIFVzZXJMb2dpbiA9PiAnc29tZS1sb2dpbicsCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyTmFtZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKCiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9OwoKICAgICAgICAjIEdldCBjdXN0b21lciBuYW1lIGFuZCByZXR1cm4gaXQuCiAgICAgICAgbXkgJE5hbWUgPSAkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifS0+Q3VzdG9tZXJOYW1lKCVQYXJhbSk7CgogICAgICAgIGlmICgkTmFtZSkgewogICAgICAgICAgICByZXR1cm4gJE5hbWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuOwp9Cgo9aGVhZDIgQ3VzdG9tZXJJRHMoKQoKZ2V0IGN1c3RvbWVyIHVzZXIgY3VzdG9tZXIgaWRzCgogICAgbXkgQEN1c3RvbWVySURzID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJJRHMoCiAgICAgICAgVXNlciA9PiAnc29tZS1sb2dpbicsCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVySURzIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtVc2VyfSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgVXNlciEnCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgY3VzdG9tZXIgaWRzIChzdG9wIGFmdGVyIGZpcnN0IHNvdXJjZSB3aXRoIHJlc3VsdHMpCiAgICBteSBAQ3VzdG9tZXJJRHM7CiAgICBTT1VSQ0U6CiAgICBmb3IgbXkgJENvdW50ICggJycsIDEgLi4gMTAgKSB7CgogICAgICAgIG5leHQgU09VUkNFIGlmICEkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifTsKCiAgICAgICAgIyBnZXQgY3VzdG9tZXIgaWRzIGZyb20gc291cmNlCiAgICAgICAgbXkgQFNvdXJjZUN1c3RvbWVySURzID0gJFNlbGYtPnsiQ3VzdG9tZXJVc2VyJENvdW50In0tPkN1c3RvbWVySURzKCVQYXJhbSk7CiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgIUBTb3VyY2VDdXN0b21lcklEczsKCiAgICAgICAgQEN1c3RvbWVySURzID0gQFNvdXJjZUN1c3RvbWVySURzOwogICAgICAgIGxhc3QgU09VUkNFOwogICAgfQoKICAgICMgY3JlYXRlIGhhc2ggd2l0aCBleGlzdGluZyBjdXN0b21lciBpZHMKICAgIG15ICVDdXN0b21lcklEcyA9IG1hcCB7ICRfID0+IDEgfSBAQ3VzdG9tZXJJRHM7CgogICAgIyBnZXQgcmVsYXRlZCBjdXN0b21lciBpZHMKICAgIG15IEBSZWxhdGVkQ3VzdG9tZXJJRHMgPSAkU2VsZi0+Q3VzdG9tZXJVc2VyQ3VzdG9tZXJNZW1iZXJMaXN0KAogICAgICAgIEN1c3RvbWVyVXNlcklEID0+ICRQYXJhbXtVc2VyfSwKICAgICk7CgogICAgIyBhZGQgcmVsYXRlZCBjdXN0b21lciBpZHMgaWYgbm90IGZvdW5kIGluIHNvdXJjZQogICAgUkVMQVRFRENVU1RPTUVSSUQ6CiAgICBmb3IgbXkgJFJlbGF0ZWRDdXN0b21lcklEIChAUmVsYXRlZEN1c3RvbWVySURzKSB7CiAgICAgICAgbmV4dCBSRUxBVEVEQ1VTVE9NRVJJRCBpZiAkQ3VzdG9tZXJJRHN7JFJlbGF0ZWRDdXN0b21lcklEfTsKCiAgICAgICAgcHVzaCBAQ3VzdG9tZXJJRHMsICRSZWxhdGVkQ3VzdG9tZXJJRDsKICAgIH0KCiAgICAjIC0tLQogICAgIyBSb3RoZXJPU1M6IERvbid0IHJldHVybiBjdXN0b21lciBJRHMgaWYgdGhlIGFnZW50IGRvZXMgbm90IGhhdmUgcGVybWlzc2lvbiB0byB2aWV3LgogICAgIyAtLS0KICAgIGlmICggJFNlbGYtPntNdWx0aXRlbmFuY3l9ICkgewogICAgICAgIG15IEBDbGVhbmVkQ3VzdG9tZXJJRHM7CgogICAgICAgIGZvciBteSAkQ3VzdG9tZXJJRCAoIEBDdXN0b21lcklEcyApIHsKICAgICAgICAgICAgbXkgJUNvbXBhbnkgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJDb21wYW55JyktPkN1c3RvbWVyQ29tcGFueUdldCgKICAgICAgICAgICAgICAgIEN1c3RvbWVySUQgPT4gJEN1c3RvbWVySUQsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoICVDb21wYW55ICYmICRDb21wYW55e0N1c3RvbWVySUR9ICkgewogICAgICAgICAgICAgICAgcHVzaCBAQ2xlYW5lZEN1c3RvbWVySURzLCAkQ3VzdG9tZXJJRDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQEN1c3RvbWVySURzID0gQENsZWFuZWRDdXN0b21lcklEczsKICAgIH0KICAgICMgLS0tCgogICAgIyByZXR1cm4gY3VzdG9tZXIgaWRzCiAgICByZXR1cm4gQEN1c3RvbWVySURzOwp9Cgo9aGVhZDIgQ3VzdG9tZXJVc2VyRGF0YUdldCgpCgpnZXQgdXNlciBkYXRhIChVc2VyTG9naW4sIFVzZXJGaXJzdG5hbWUsIFVzZXJMYXN0bmFtZSwgVXNlckVtYWlsLCAuLi4pCgogICAgbXkgJVVzZXIgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KAogICAgICAgIFVzZXIgPT4gJ2ZyYW56JywKICAgICk7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJVc2VyRGF0YUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIHJldHVybiBpZiAhJFBhcmFte1VzZXJ9OwoKICAgICMgZmV0Y2ggZHluYW1pYyBmaWVsZCBjb25maWd1cmF0aW9ucyBmb3IgQ3VzdG9tZXJVc2VyLgogICAgbXkgJER5bmFtaWNGaWVsZENvbmZpZ3MgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkJyktPkR5bmFtaWNGaWVsZExpc3RHZXQoCiAgICAgICAgT2JqZWN0VHlwZSA9PiAnQ3VzdG9tZXJVc2VyJywKICAgICAgICBWYWxpZCAgICAgID0+IDEsCiAgICApOwoKICAgIG15ICVEeW5hbWljRmllbGRMb29rdXAgPSBtYXAgeyAkXy0+e05hbWV9ID0+ICRfIH0gQHskRHluYW1pY0ZpZWxkQ29uZmlnc307CgogICAgIyBHZXQgbmVlZGVkIG9iamVjdHMuCiAgICBteSAkQ29uZmlnT2JqZWN0ICAgICAgICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyk7CiAgICBteSAkQ3VzdG9tZXJDb21wYW55T2JqZWN0ICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lckNvbXBhbnknKTsKICAgIG15ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDo6QmFja2VuZCcpOwoKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKCiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9OwoKICAgICAgICBteSAlQ3VzdG9tZXIgPSAkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifS0+Q3VzdG9tZXJVc2VyRGF0YUdldCglUGFyYW0pOwogICAgICAgIG5leHQgU09VUkNFIGlmICElQ3VzdG9tZXI7CgogICAgICAgICMgZ2VuZXJhdGUgdGhlIGZ1bGwgbmFtZSBhbmQgc2F2ZSBpdCBpbiB0aGUgaGFzaAogICAgICAgIG15ICRVc2VyRnVsbG5hbWUgPSAkU2VsZi0+Q3VzdG9tZXJOYW1lKCVDdXN0b21lcik7CgogICAgICAgICMgc2F2ZSB0aGUgZ2VuZXJhdGVkIGZ1bGxuYW1lIGluIHRoZSBoYXNoLgogICAgICAgICRDdXN0b21lcntVc2VyRnVsbG5hbWV9ID0gJFVzZXJGdWxsbmFtZTsKCiAgICAgICAgIyBhZGQgcHJlZmVyZW5jZXMgZGVmYXVsdHMKICAgICAgICBteSAkQ29uZmlnID0gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclByZWZlcmVuY2VzR3JvdXBzJyk7CiAgICAgICAgaWYgKCRDb25maWcpIHsKICAgICAgICAgICAgS0VZOgogICAgICAgICAgICBmb3IgbXkgJEtleSAoIHNvcnQga2V5cyAleyRDb25maWd9ICkgewoKICAgICAgICAgICAgICAgIG5leHQgS0VZIGlmICFkZWZpbmVkICRDb25maWctPnskS2V5fS0+e0RhdGFTZWxlY3RlZH07CiAgICAgICAgICAgICAgICBuZXh0IEtFWSBpZiBkZWZpbmVkICRDdXN0b21lcnsgJENvbmZpZy0+eyRLZXl9LT57UHJlZktleX0gfTsKCiAgICAgICAgICAgICAgICAjIHNldCBkZWZhdWx0IGRhdGEKICAgICAgICAgICAgICAgICRDdXN0b21lcnsgJENvbmZpZy0+eyRLZXl9LT57UHJlZktleX0gfSA9ICRDb25maWctPnskS2V5fS0+e0RhdGFTZWxlY3RlZH07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgY2hlY2sgaWYgY3VzdG9tZXIgY29tcGFueSBzdXBwb3J0IGlzIGVuYWJsZWQgYW5kIGdldCBjb21wYW55IGRhdGEKICAgICAgICBteSAlQ29tcGFueTsKICAgICAgICBpZiAoCiAgICAgICAgICAgICRDb25maWdPYmplY3QtPkdldCgiQ3VzdG9tZXJDb21wYW55IikKICAgICAgICAgICAgJiYgJENvbmZpZ09iamVjdC0+R2V0KCJDdXN0b21lclVzZXIkQ291bnQiKS0+e0N1c3RvbWVyQ29tcGFueVN1cHBvcnR9CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICVDb21wYW55ID0gJEN1c3RvbWVyQ29tcGFueU9iamVjdC0+Q3VzdG9tZXJDb21wYW55R2V0KAogICAgICAgICAgICAgICAgQ3VzdG9tZXJJRCA9PiAkQ3VzdG9tZXJ7VXNlckN1c3RvbWVySUR9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJENvbXBhbnl7Q3VzdG9tZXJDb21wYW55VmFsaWRJRH0gPSAkQ29tcGFueXtWYWxpZElEfTsKICAgICAgICB9CgogICAgICAgICMgZmV0Y2ggZHluYW1pYyBmaWVsZCB2YWx1ZXMKICAgICAgICBpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSggJFNlbGYtPnsiQ3VzdG9tZXJVc2VyJENvdW50In0tPntDdXN0b21lclVzZXJNYXB9LT57TWFwfSApICkgewogICAgICAgICAgICBDVVNUT01FUlVTRVJGSUVMRDoKICAgICAgICAgICAgZm9yIG15ICRDdXN0b21lclVzZXJGaWVsZCAoIEB7ICRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9LT57Q3VzdG9tZXJVc2VyTWFwfS0+e01hcH0gfSApIHsKICAgICAgICAgICAgICAgIG5leHQgQ1VTVE9NRVJVU0VSRklFTEQgaWYgJEN1c3RvbWVyVXNlckZpZWxkLT5bNV0gbmUgJ2R5bmFtaWNfZmllbGQnOwogICAgICAgICAgICAgICAgbmV4dCBDVVNUT01FUlVTRVJGSUVMRCBpZiAhJER5bmFtaWNGaWVsZExvb2t1cHsgJEN1c3RvbWVyVXNlckZpZWxkLT5bMl0gfTsKCiAgICAgICAgICAgICAgICBteSAkVmFsdWUgPSAkRHluYW1pY0ZpZWxkQmFja2VuZE9iamVjdC0+VmFsdWVHZXQoCiAgICAgICAgICAgICAgICAgICAgRHluYW1pY0ZpZWxkQ29uZmlnID0+ICREeW5hbWljRmllbGRMb29rdXB7ICRDdXN0b21lclVzZXJGaWVsZC0+WzJdIH0sCiAgICAgICAgICAgICAgICAgICAgT2JqZWN0TmFtZSAgICAgICAgID0+ICRDdXN0b21lcntVc2VySUR9LAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAkQ3VzdG9tZXJ7ICRDdXN0b21lclVzZXJGaWVsZC0+WzBdIH0gPSAkVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgLS0tCiAgICAgICAgIyBSb3RoZXJPU1M6IENoZWNrIHBlcm1pc3Npb24uCiAgICAgICAgIyAtLS0KICAgICAgICBpZiAoICRDdXN0b21lcntVc2VyR3JvdXBJRH0gKSB7CiAgICAgICAgICAgIG15ICRVc2VyR3JvdXBJRFN5bmMgPSAkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifS0+e0N1c3RvbWVyVXNlck1hcH0tPntVc2VyR3JvdXBJRFN5bmN9OwoKICAgICAgICAgICAgIyBSZXBsYWNlIHRoZSByZW1vdGUgZ3JvdXAgd2l0aCB0aGUgYXNzb2NpYXRlZCBsb2NhbCBncm91cC4KICAgICAgICAgICAgaWYgKCAkVXNlckdyb3VwSURTeW5jLT57UmVtb3RlR3JvdXBUb0xvY2FsR3JvdXB9ICkgewogICAgICAgICAgICAgICAgZm9yIG15ICRSZW1vdGVHcm91cCAoIGtleXMgJXsgJFVzZXJHcm91cElEU3luYy0+e1JlbW90ZUdyb3VwVG9Mb2NhbEdyb3VwfSB9ICkgewogICAgICAgICAgICAgICAgICAgIGlmICggJEN1c3RvbWVye1VzZXJHcm91cElEfSBlcSAkUmVtb3RlR3JvdXAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRDdXN0b21lcntVc2VyR3JvdXBJRH0gPSAkVXNlckdyb3VwSURTeW5jLT57UmVtb3RlR3JvdXBUb0xvY2FsR3JvdXB9eyRSZW1vdGVHcm91cH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAjIENoZWNrIGlmIGdyb3VwIElEIG9yIGdyb3VwIG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkLgogICAgICAgICAgICBpZiAoICRVc2VyR3JvdXBJRFN5bmMtPntVc2VHcm91cE5hbWVzfSApIHsKICAgICAgICAgICAgICAgICRDdXN0b21lcntVc2VyR3JvdXBJRH0gPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnKS0+R3JvdXBMb29rdXAoCiAgICAgICAgICAgICAgICAgICAgR3JvdXAgPT4gJEN1c3RvbWVye1VzZXJHcm91cElEfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgQ2hlY2sgaWYgYW55IGxpbWl0cyBhcmUgc2V0LgogICAgICAgICAgICBpZiAoICRTZWxmLT57TXVsdGl0ZW5hbmN5fSAmJiAhZ3JlcCggL14kQ3VzdG9tZXJ7VXNlckdyb3VwSUR9JC8sIEB7ICRTZWxmLT57VXNlckdyb3VwSURzfSB9ICkgKSB7CiAgICAgICAgICAgICAgICAjIFRoZSB1c2VyIGRvZXMgbm90IGhhdmUgYWNjZXNzIHRvIHRoaXMgaW5mb3JtYXRpb24uCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9IAogICAgICAgICMgSWYgdGhlcmUgYXJlIG5vIGdyb3VwIHNldHRpbmdzLCBjaGVjayBpZiBwZXJtaXNzaW9uIG9uIGN1c3RvbWVyIGNvbXBhbnkgaXMgcGVybWl0dGVkLgogICAgICAgIGVsc2lmICggJFNlbGYtPntNdWx0aXRlbmFuY3l9ICYmICEkQ3VzdG9tZXJ7VXNlckdyb3VwSUR9ICYmICggISVDb21wYW55IHx8ICEkQ29tcGFueXtDdXN0b21lcklEfSApICkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICMgLS0tCgogICAgICAgICMgcmV0dXJuIGN1c3RvbWVyIGRhdGEKICAgICAgICByZXR1cm4gKAogICAgICAgICAgICAlQ29tcGFueSwKICAgICAgICAgICAgJUN1c3RvbWVyLAogICAgICAgICAgICBTb3VyY2UgICAgICAgID0+ICJDdXN0b21lclVzZXIkQ291bnQiLAogICAgICAgICAgICBDb25maWcgICAgICAgID0+ICRDb25maWdPYmplY3QtPkdldCgiQ3VzdG9tZXJVc2VyJENvdW50IiksCiAgICAgICAgICAgIENvbXBhbnlDb25maWcgPT4gJENvbmZpZ09iamVjdC0+R2V0KCAkQ29tcGFueXtTb3VyY2V9IC8vICdDdXN0b21lckNvbXBhbnknICksCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm47Cn0KCj1oZWFkMiBDdXN0b21lclVzZXJBZGQoKQoKdG8gYWRkIG5ldyBjdXN0b21lciB1c2VycwoKICAgIG15ICRVc2VyTG9naW4gPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJBZGQoCiAgICAgICAgU291cmNlICAgICAgICAgPT4gJ0N1c3RvbWVyVXNlcicsICMgQ3VzdG9tZXJVc2VyIHNvdXJjZSBjb25maWcKICAgICAgICBVc2VyRmlyc3RuYW1lICA9PiAnSHViZXInLAogICAgICAgIFVzZXJMYXN0bmFtZSAgID0+ICdNYW5mcmVkJywKICAgICAgICBVc2VyQ3VzdG9tZXJJRCA9PiAnQTEyNCcsCiAgICAgICAgVXNlckxvZ2luICAgICAgPT4gJ21odWJlcicsCiAgICAgICAgVXNlclBhc3N3b3JkICAgPT4gJ3NvbWUtcGFzcycsICMgbm90IHJlcXVpcmVkCiAgICAgICAgVXNlckVtYWlsICAgICAgPT4gJ2VtYWlsQGV4YW1wbGUuY29tJywKICAgICAgICBWYWxpZElEICAgICAgICA9PiAxLAogICAgICAgIFVzZXJJRCAgICAgICAgID0+IDEyMywKICAgICk7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJVc2VyQWRkIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBkYXRhIHNvdXJjZQogICAgaWYgKCAhJFBhcmFte1NvdXJjZX0gKSB7CiAgICAgICAgJFBhcmFte1NvdXJjZX0gPSAnQ3VzdG9tZXJVc2VyJzsKICAgIH0KCiAgICAjIGNoZWNrIGlmIHVzZXIgZXhpc3RzCiAgICBpZiAoICRQYXJhbXtVc2VyTG9naW59ICkgewogICAgICAgIG15ICVVc2VyID0gJFNlbGYtPkN1c3RvbWVyVXNlckRhdGFHZXQoIFVzZXIgPT4gJFBhcmFte1VzZXJMb2dpbn0gKTsKICAgICAgICBpZiAoJVVzZXIpIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpMYW5ndWFnZScpCiAgICAgICAgICAgICAgICAgICAgLT5UcmFuc2xhdGUoICdDdXN0b21lciB1c2VyICIlcyIgYWxyZWFkeSBleGlzdHMuJywgJFBhcmFte1VzZXJMb2dpbn0gKSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIC0tLQogICAgIyBSb3RoZXJPU1M6IENoZWNrIGlmIHRoZSB1c2VyIGhhcyBwZXJtaXNzaW9uIHRvIGFkZCB0aGUgVXNlckdyb3VwSUQuCiAgICAjIC0tLQogICAgaWYgKCAkU2VsZi0+e011bHRpdGVuYW5jeX0gKSB7CiAgICAgICAgZGVsZXRlICRQYXJhbXtVc2VyR3JvdXBJRH07CiAgICB9CgogICAgbXkgJFVzZXJHcm91cElEU3luYyA9ICRTZWxmLT57JFBhcmFte1NvdXJjZX19LT57Q3VzdG9tZXJVc2VyTWFwfS0+e1VzZXJHcm91cElEU3luY307CiAgICBpZiAoICRQYXJhbXtVc2VyR3JvdXBJRH0gKSB7CiAgICAgICAgIyBDaGVjayBpZiBncm91cCBJRCBvciBncm91cCBuYW1lcyBzaG91bGQgYmUgbWF0Y2hlZC4KICAgICAgICBpZiAoICRVc2VyR3JvdXBJRFN5bmMtPntVc2VHcm91cE5hbWVzfSApIHsKICAgICAgICAgICAgbXkgJEdyb3VwTmFtZSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpHcm91cCcpLT5Hcm91cExvb2t1cCgKICAgICAgICAgICAgICAgIEdyb3VwSUQgPT4gJFBhcmFte1VzZXJHcm91cElEfSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICRQYXJhbXtVc2VyR3JvdXBJRH0gPSAkR3JvdXBOYW1lOwogICAgICAgIH0KCiAgICAgICAgIyBSZXBsYWNlIHRoZSBsb2NhbCBncm91cCB3aXRoIHRoZSBhc3NvY2lhdGVkIHJlbW90ZSBncm91cC4KICAgICAgICBmb3IgbXkgJFJlbW90ZUdyb3VwICgga2V5cyAleyAkVXNlckdyb3VwSURTeW5jLT57UmVtb3RlR3JvdXBUb0xvY2FsR3JvdXB9IH0gKSB7CiAgICAgICAgICAgIGlmICggJFBhcmFte1VzZXJHcm91cElEfSBlcSAkVXNlckdyb3VwSURTeW5jLT57UmVtb3RlR3JvdXBUb0xvY2FsR3JvdXB9eyRSZW1vdGVHcm91cH0gKSB7CiAgICAgICAgICAgICAgICAkUGFyYW17VXNlckdyb3VwSUR9ID0gJFJlbW90ZUdyb3VwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgIyAtLS0KCiAgICAjIHN0b3JlIGN1c3RvbWVyIHVzZXIgZGF0YQogICAgbXkgJFJlc3VsdCA9ICRTZWxmLT57ICRQYXJhbXtTb3VyY2V9IH0tPkN1c3RvbWVyVXNlckFkZCglUGFyYW0pOwogICAgcmV0dXJuIGlmICEkUmVzdWx0OwoKICAgICMgdHJpZ2dlciBldmVudAogICAgJFNlbGYtPkV2ZW50SGFuZGxlcigKICAgICAgICBFdmVudCA9PiAnQ3VzdG9tZXJVc2VyQWRkJywKICAgICAgICBEYXRhICA9PiB7CiAgICAgICAgICAgIFVzZXJMb2dpbiA9PiAkUGFyYW17VXNlckxvZ2lufSwKICAgICAgICAgICAgTmV3RGF0YSAgID0+IFwlUGFyYW0sCiAgICAgICAgfSwKICAgICAgICBVc2VySUQgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgIHJldHVybiAkUmVzdWx0OwoKfQoKPWhlYWQyIEN1c3RvbWVyVXNlclVwZGF0ZSgpCgp0byB1cGRhdGUgY3VzdG9tZXIgdXNlcnMKCiAgICAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJVcGRhdGUoCiAgICAgICAgU291cmNlICAgICAgICA9PiAnQ3VzdG9tZXJVc2VyJywgIyBDdXN0b21lclVzZXIgc291cmNlIGNvbmZpZwogICAgICAgIElEICAgICAgICAgICAgPT4gJ21oJyAgICAgICAgICAgICMgY3VycmVudCB1c2VyIGxvZ2luCiAgICAgICAgVXNlckxvZ2luICAgICA9PiAnbWh1YmVyJywgICAgICAgIyBuZXcgdXNlciBsb2dpbgogICAgICAgIFVzZXJGaXJzdG5hbWUgPT4gJ0h1YmVyJywKICAgICAgICBVc2VyTGFzdG5hbWUgID0+ICdNYW5mcmVkJywKICAgICAgICBVc2VyUGFzc3dvcmQgID0+ICdzb21lLXBhc3MnLCAgICAjIG5vdCByZXF1aXJlZAogICAgICAgIFVzZXJFbWFpbCAgICAgPT4gJ2VtYWlsQGV4YW1wbGUuY29tJywKICAgICAgICBWYWxpZElEICAgICAgID0+IDEsCiAgICAgICAgVXNlcklEICAgICAgICA9PiAxMjMsCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyVXNlclVwZGF0ZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VXNlckxvZ2lufSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgVXNlckxvZ2luISIKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNoZWNrIGZvciBVc2VyTG9naW4tcmVuYW1pbmcgYW5kIGlmIG5ldyBVc2VyTG9naW4gYWxyZWFkeSBleGlzdHMuLi4KICAgIGlmICggJFBhcmFte0lEfSAmJiAoIGxjICRQYXJhbXtVc2VyTG9naW59IG5lIGxjICRQYXJhbXtJRH0gKSApIHsKICAgICAgICBteSAlVXNlciA9ICRTZWxmLT5DdXN0b21lclVzZXJEYXRhR2V0KCBVc2VyID0+ICRQYXJhbXtVc2VyTG9naW59ICk7CiAgICAgICAgaWYgKCVVc2VyKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6TGFuZ3VhZ2UnKQogICAgICAgICAgICAgICAgICAgIC0+VHJhbnNsYXRlKCAnQ3VzdG9tZXIgdXNlciAiJXMiIGFscmVhZHkgZXhpc3RzLicsICRQYXJhbXtVc2VyTG9naW59ICksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBjaGVjayBpZiB1c2VyIGV4aXN0cwogICAgbXkgJVVzZXIgPSAkU2VsZi0+Q3VzdG9tZXJVc2VyRGF0YUdldCggVXNlciA9PiAkUGFyYW17SUR9IHx8ICRQYXJhbXtVc2VyTG9naW59ICk7CiAgICBpZiAoICElVXNlciApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIHN1Y2ggdXNlciAnJFBhcmFte1VzZXJMb2dpbn0nISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyAtLS0KICAgICMgUm90aGVyT1NTOiBDaGVjayBpZiB0aGUgdXNlciBoYXMgcGVybWlzc2lvbiB0byBjaGFuZ2UgdGhlIFVzZXJHcm91cElELgogICAgIyAtLS0KICAgIGlmICggJFNlbGYtPntNdWx0aXRlbmFuY3l9ICkgewogICAgICAgICMgU2V0IHRoZSBVc2VyR3JvdXBJRCB0byB0aGUgY3VycmVudCBVc2VyR3JvdXBJRC4KICAgICAgICBpZiAoICRVc2Vye1VzZXJHcm91cElEfSApIHsKICAgICAgICAgICAgJFBhcmFte1VzZXJHcm91cElEfSA9ICRVc2Vye1VzZXJHcm91cElEfTsKICAgICAgICB9CiAgICB9CgogICAgbXkgJFVzZXJHcm91cElEU3luYyA9ICRTZWxmLT57JFVzZXJ7U291cmNlfX0tPntDdXN0b21lclVzZXJNYXB9LT57VXNlckdyb3VwSURTeW5jfTsKICAgIGlmICggJFBhcmFte1VzZXJHcm91cElEfSApIHsKICAgICAgICAjIENoZWNrIGlmIGdyb3VwIElEIG9yIGdyb3VwIG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkLgogICAgICAgIGlmICggJFVzZXJHcm91cElEU3luYy0+e1VzZUdyb3VwTmFtZXN9ICkgewogICAgICAgICAgICBteSAkR3JvdXBOYW1lID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Okdyb3VwJyktPkdyb3VwTG9va3VwKAogICAgICAgICAgICAgICAgR3JvdXBJRCA9PiAkUGFyYW17VXNlckdyb3VwSUR9LAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJFBhcmFte1VzZXJHcm91cElEfSA9ICRHcm91cE5hbWU7CiAgICAgICAgfQoKICAgICAgICAjIFJlcGxhY2UgdGhlIGxvY2FsIGdyb3VwIHdpdGggdGhlIGFzc29jaWF0ZWQgcmVtb3RlIGdyb3VwLgogICAgICAgIGZvciBteSAkUmVtb3RlR3JvdXAgKCBrZXlzICV7ICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH0gfSApIHsKICAgICAgICAgICAgaWYgKCAkUGFyYW17VXNlckdyb3VwSUR9IGVxICRVc2VyR3JvdXBJRFN5bmMtPntSZW1vdGVHcm91cFRvTG9jYWxHcm91cH17JFJlbW90ZUdyb3VwfSApIHsKICAgICAgICAgICAgICAgICRQYXJhbXtVc2VyR3JvdXBJRH0gPSAkUmVtb3RlR3JvdXA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAjIC0tLQoKICAgIG15ICRSZXN1bHQgPSAkU2VsZi0+eyAkVXNlcntTb3VyY2V9IH0tPkN1c3RvbWVyVXNlclVwZGF0ZSglUGFyYW0pOwogICAgcmV0dXJuIGlmICEkUmVzdWx0OwoKICAgICMgdHJpZ2dlciBldmVudAogICAgJFNlbGYtPkV2ZW50SGFuZGxlcigKICAgICAgICBFdmVudCA9PiAnQ3VzdG9tZXJVc2VyVXBkYXRlJywKICAgICAgICBEYXRhICA9PiB7CiAgICAgICAgICAgIFVzZXJMb2dpbiA9PiAkUGFyYW17SUR9IHx8ICRQYXJhbXtVc2VyTG9naW59LAogICAgICAgICAgICBOZXdEYXRhICAgPT4gXCVQYXJhbSwKICAgICAgICAgICAgT2xkRGF0YSAgID0+IFwlVXNlciwKICAgICAgICB9LAogICAgICAgIFVzZXJJRCA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgcmV0dXJuICRSZXN1bHQ7Cn0KCj1oZWFkMiBTZXRQYXNzd29yZCgpCgp0byBzZXQgY3VzdG9tZXIgdXNlcnMgcGFzc3dvcmRzCgogICAgJEN1c3RvbWVyVXNlck9iamVjdC0+U2V0UGFzc3dvcmQoCiAgICAgICAgVXNlckxvZ2luID0+ICdzb21lLWxvZ2luJywKICAgICAgICBQVyAgICAgICAgPT4gJ3NvbWUtbmV3LXBhc3N3b3JkJwogICAgKTsKCj1jdXQKCnN1YiBTZXRQYXNzd29yZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VXNlckxvZ2lufSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ1VzZXIgVXNlckxvZ2luIScKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNoZWNrIGlmIHVzZXIgZXhpc3RzCiAgICBteSAlVXNlciA9ICRTZWxmLT5DdXN0b21lclVzZXJEYXRhR2V0KCBVc2VyID0+ICRQYXJhbXtVc2VyTG9naW59ICk7CiAgICBpZiAoICElVXNlciApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIHN1Y2ggdXNlciAnJFBhcmFte1VzZXJMb2dpbn0nISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICByZXR1cm4gJFNlbGYtPnsgJFVzZXJ7U291cmNlfSB9LT5TZXRQYXNzd29yZCglUGFyYW0pOwp9Cgo9aGVhZDIgR2VuZXJhdGVSYW5kb21QYXNzd29yZCgpCgpnZW5lcmF0ZSBhIHJhbmRvbSBwYXNzd29yZAoKICAgIG15ICRQYXNzd29yZCA9ICRDdXN0b21lclVzZXJPYmplY3QtPkdlbmVyYXRlUmFuZG9tUGFzc3dvcmQoKTsKCiAgICBvcgoKICAgIG15ICRQYXNzd29yZCA9ICRDdXN0b21lclVzZXJPYmplY3QtPkdlbmVyYXRlUmFuZG9tUGFzc3dvcmQoCiAgICAgICAgU2l6ZSA9PiAxNiwKICAgICk7Cgo9Y3V0CgpzdWIgR2VuZXJhdGVSYW5kb21QYXNzd29yZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIHJldHVybiAkU2VsZi0+e0N1c3RvbWVyVXNlcn0tPkdlbmVyYXRlUmFuZG9tUGFzc3dvcmQoJVBhcmFtKTsKfQoKPWhlYWQyIFNldFByZWZlcmVuY2VzKCkKCnNldCBjdXN0b21lciB1c2VyIHByZWZlcmVuY2VzCgogICAgJEN1c3RvbWVyVXNlck9iamVjdC0+U2V0UHJlZmVyZW5jZXMoCiAgICAgICAgS2V5ICAgID0+ICdVc2VyQ29tbWVudCcsCiAgICAgICAgVmFsdWUgID0+ICdzb21lIGNvbW1lbnQnLAogICAgICAgIFVzZXJJRCA9PiAnc29tZS1sb2dpbicsCiAgICApOwoKPWN1dAoKc3ViIFNldFByZWZlcmVuY2VzIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtVc2VySUR9ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBVc2VySUQhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgRG9uJ3QgYWxsb3cgb3ZlcndyaXRpbmcgb2YgbmF0aXZlIHVzZXIgZGF0YS4KICAgIG15ICVCbGFja2xpc3RlZCA9ICgKICAgICAgICBVc2VySUQgICAgICAgICA9PiAxLAogICAgICAgIFVzZXJMb2dpbiAgICAgID0+IDEsCiAgICAgICAgVXNlclBhc3N3b3JkICAgPT4gMSwKICAgICAgICBVc2VyRmlyc3RuYW1lICA9PiAxLAogICAgICAgIFVzZXJMYXN0bmFtZSAgID0+IDEsCiAgICAgICAgVXNlckZ1bGxuYW1lICAgPT4gMSwKICAgICAgICBVc2VyU3RyZWV0ICAgICA9PiAxLAogICAgICAgIFVzZXJDaXR5ICAgICAgID0+IDEsCiAgICAgICAgVXNlclppcCAgICAgICAgPT4gMSwKICAgICAgICBVc2VyQ291bnRyeSAgICA9PiAxLAogICAgICAgIFVzZXJDb21tZW50ICAgID0+IDEsCiAgICAgICAgVXNlckN1c3RvbWVySUQgPT4gMSwKICAgICAgICBVc2VyVGl0bGUgICAgICA9PiAxLAogICAgICAgIFVzZXJFbWFpbCAgICAgID0+IDEsCiAgICAgICAgQ2hhbmdlVGltZSAgICAgPT4gMSwKICAgICAgICBDaGFuZ2VCeSAgICAgICA9PiAxLAogICAgICAgIENyZWF0ZVRpbWUgICAgID0+IDEsCiAgICAgICAgQ3JlYXRlQnkgICAgICAgPT4gMSwKICAgICAgICBVc2VyUGhvbmUgICAgICA9PiAxLAogICAgICAgIFVzZXJNb2JpbGUgICAgID0+IDEsCiAgICAgICAgVXNlckZheCAgICAgICAgPT4gMSwKICAgICAgICBVc2VyTWFpbFN0cmluZyA9PiAxLAogICAgICAgIFZhbGlkSUQgICAgICAgID0+IDEsCiAgICApOwoKICAgIHJldHVybiAwIGlmICRCbGFja2xpc3RlZHsgJFBhcmFte0tleX0gfTsKCiAgICAjIGNoZWNrIGlmIHVzZXIgZXhpc3RzCiAgICBteSAlVXNlciA9ICRTZWxmLT5DdXN0b21lclVzZXJEYXRhR2V0KCBVc2VyID0+ICRQYXJhbXtVc2VySUR9ICk7CiAgICBpZiAoICElVXNlciApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIHN1Y2ggdXNlciAnJFBhcmFte1VzZXJJRH0nISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjYWxsIG5ldyBhcGkgKDIuNC44IGFuZCBoaWdoZXIpCiAgICBpZiAoICRTZWxmLT57ICRVc2Vye1NvdXJjZX0gfS0+Y2FuKCdTZXRQcmVmZXJlbmNlcycpICkgewogICAgICAgIHJldHVybiAkU2VsZi0+eyAkVXNlcntTb3VyY2V9IH0tPlNldFByZWZlcmVuY2VzKCVQYXJhbSk7CiAgICB9CgogICAgIyBjYWxsIG9sZCBhcGkKICAgIHJldHVybiAkU2VsZi0+e1ByZWZlcmVuY2VzT2JqZWN0fS0+U2V0UHJlZmVyZW5jZXMoJVBhcmFtKTsKfQoKPWhlYWQyIEdldFByZWZlcmVuY2VzKCkKCmdldCBjdXN0b21lciB1c2VyIHByZWZlcmVuY2VzCgogICAgbXkgJVByZWZlcmVuY2VzID0gJEN1c3RvbWVyVXNlck9iamVjdC0+R2V0UHJlZmVyZW5jZXMoCiAgICAgICAgVXNlcklEID0+ICdzb21lLWxvZ2luJywKICAgICk7Cgo9Y3V0CgpzdWIgR2V0UHJlZmVyZW5jZXMgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1VzZXJJRH0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFVzZXJJRCEnCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjaGVjayBpZiB1c2VyIGV4aXN0cwogICAgbXkgJVVzZXIgPSAkU2VsZi0+Q3VzdG9tZXJVc2VyRGF0YUdldCggVXNlciA9PiAkUGFyYW17VXNlcklEfSApOwogICAgaWYgKCAhJVVzZXIgKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJObyBzdWNoIHVzZXIgJyRQYXJhbXtVc2VySUR9JyEiLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY2FsbCBuZXcgYXBpICgyLjQuOCBhbmQgaGlnaGVyKQogICAgaWYgKCAkU2VsZi0+eyAkVXNlcntTb3VyY2V9IH0tPmNhbignR2V0UHJlZmVyZW5jZXMnKSApIHsKICAgICAgICByZXR1cm4gJFNlbGYtPnsgJFVzZXJ7U291cmNlfSB9LT5HZXRQcmVmZXJlbmNlcyglUGFyYW0pOwogICAgfQoKICAgICMgY2FsbCBvbGQgYXBpCiAgICByZXR1cm4gJFNlbGYtPntQcmVmZXJlbmNlc09iamVjdH0tPkdldFByZWZlcmVuY2VzKCVQYXJhbSk7Cn0KCj1oZWFkMiBTZWFyY2hQcmVmZXJlbmNlcygpCgpzZWFyY2ggaW4gdXNlciBwcmVmZXJlbmNlcwoKICAgIG15ICVVc2VyTGlzdCA9ICRDdXN0b21lclVzZXJPYmplY3QtPlNlYXJjaFByZWZlcmVuY2VzKAogICAgICAgIEtleSAgID0+ICdVc2VyU29tZUtleScsCiAgICAgICAgVmFsdWUgPT4gJ1NvbWVWYWx1ZScsICAgIyBvcHRpb25hbCwgbGltaXQgdG8gYSBjZXJ0YWluIHZhbHVlL3BhdHRlcm4KICAgICk7Cgo9Y3V0CgpzdWIgU2VhcmNoUHJlZmVyZW5jZXMgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAlRGF0YTsKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKCiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9OwoKICAgICAgICAjIGdldCBjdXN0b21lciBzZWFyY2ggcmVzdWx0IG9mIGJhY2tlbmQgYW5kIG1lcmdlIGl0CiAgICAgICAgIyBjYWxsIG5ldyBhcGkgKDIuNC44IGFuZCBoaWdoZXIpCiAgICAgICAgbXkgJVN1YkRhdGE7CiAgICAgICAgaWYgKCAkU2VsZi0+eyJDdXN0b21lclVzZXIkQ291bnQifS0+Y2FuKCdTZWFyY2hQcmVmZXJlbmNlcycpICkgewogICAgICAgICAgICAlU3ViRGF0YSA9ICRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9LT5TZWFyY2hQcmVmZXJlbmNlcyglUGFyYW0pOwogICAgICAgIH0KCiAgICAgICAgIyBjYWxsIG9sZCBhcGkKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJVN1YkRhdGEgPSAkU2VsZi0+e1ByZWZlcmVuY2VzT2JqZWN0fS0+U2VhcmNoUHJlZmVyZW5jZXMoJVBhcmFtKTsKICAgICAgICB9CiAgICAgICAgJURhdGEgPSAoICVTdWJEYXRhLCAlRGF0YSApOwogICAgfQoKICAgIHJldHVybiAlRGF0YTsKfQoKPWhlYWQyIFRva2VuR2VuZXJhdGUoKQoKZ2VuZXJhdGUgYSByYW5kb20gdG9rZW4KCiAgICBteSAkVG9rZW4gPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5Ub2tlbkdlbmVyYXRlKAogICAgICAgIFVzZXJJRCA9PiAxMjMsCiAgICApOwoKPWN1dAoKc3ViIFRva2VuR2VuZXJhdGUgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1VzZXJJRH0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkIFVzZXJJRCEiCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgbXkgJFRva2VuID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Ok1haW4nKS0+R2VuZXJhdGVSYW5kb21TdHJpbmcoCiAgICAgICAgTGVuZ3RoID0+IDE0LAogICAgKTsKCiAgICAjIHNhdmUgdG9rZW4gaW4gcHJlZmVyZW5jZXMKICAgICRTZWxmLT5TZXRQcmVmZXJlbmNlcygKICAgICAgICBLZXkgICAgPT4gJ1VzZXJUb2tlbicsCiAgICAgICAgVmFsdWUgID0+ICRUb2tlbiwKICAgICAgICBVc2VySUQgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgIHJldHVybiAkVG9rZW47Cn0KCj1oZWFkMiBUb2tlbkNoZWNrKCkKCmNoZWNrIHBhc3N3b3JkIHRva2VuCgogICAgbXkgJFZhbGlkID0gJEN1c3RvbWVyVXNlck9iamVjdD5Ub2tlbkNoZWNrKAogICAgICAgIFRva2VuICA9PiAkVG9rZW4sCiAgICAgICAgVXNlcklEID0+IDEyMywKICAgICk7Cgo9Y3V0CgpzdWIgVG9rZW5DaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17VG9rZW59IHx8ICEkUGFyYW17VXNlcklEfSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgVG9rZW4gYW5kIFVzZXJJRCEiCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgcHJlZmVyZW5jZXMgdG9rZW4KICAgIG15ICVQcmVmZXJlbmNlcyA9ICRTZWxmLT5HZXRQcmVmZXJlbmNlcygKICAgICAgICBVc2VySUQgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgICMgY2hlY2sgcmVxdWVzdGVkIHZzLiBzdG9yZWQgdG9rZW4KICAgIHJldHVybiBpZiAhJFByZWZlcmVuY2Vze1VzZXJUb2tlbn07CiAgICByZXR1cm4gaWYgJFByZWZlcmVuY2Vze1VzZXJUb2tlbn0gbmUgJFBhcmFte1Rva2VufTsKCiAgICAjIHJlc2V0IHBhc3N3b3JkIHRva2VuCiAgICAkU2VsZi0+U2V0UHJlZmVyZW5jZXMoCiAgICAgICAgS2V5ICAgID0+ICdVc2VyVG9rZW4nLAogICAgICAgIFZhbHVlICA9PiAnJywKICAgICAgICBVc2VySUQgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgIHJldHVybiAxOwp9Cgo9aGVhZDIgQ3VzdG9tZXJVc2VyQ2FjaGVDbGVhcigpCgpjbGVhciBjYWNoZSBvZiBjdXN0b21lciB1c2VyIGRhdGEKCiAgICAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJDYWNoZUNsZWFyKAogICAgICAgIFVzZXJMb2dpbiA9PiAnbWh1YmVyJywKICAgICk7Cgo9Y3V0CgpzdWIgQ3VzdG9tZXJVc2VyQ2FjaGVDbGVhciB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKCiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9OwogICAgICAgICRTZWxmLT57IkN1c3RvbWVyVXNlciRDb3VudCJ9LT5fQ3VzdG9tZXJVc2VyQ2FjaGVDbGVhcigKICAgICAgICAgICAgVXNlckxvZ2luID0+ICRQYXJhbXtVc2VyTG9naW59LAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCj1oZWFkMiBDdXN0b21lclVzZXJDdXN0b21lck1lbWJlckFkZCgpCgp0byBhZGQgYSBjdXN0b21lciB1c2VyIHRvIGEgY3VzdG9tZXIKCiAgICBteSAkU3VjY2VzcyA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlckN1c3RvbWVyTWVtYmVyQWRkKAogICAgICAgIEN1c3RvbWVyVXNlcklEID0+IDEyMywKICAgICAgICBDdXN0b21lcklEICAgICA9PiAxMjMsCiAgICAgICAgQWN0aXZlICAgICAgICAgPT4gMSwgICAgICAgICMgb3B0aW9uYWwKICAgICAgICBVc2VySUQgICAgICAgICA9PiAxMjMsCiAgICApOwoKPWN1dAoKc3ViIEN1c3RvbWVyVXNlckN1c3RvbWVyTWVtYmVyQWRkIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkQXJndW1lbnQgKHF3KEN1c3RvbWVyVXNlcklEIEN1c3RvbWVySUQgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskQXJndW1lbnR9ICkgewogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkQXJndW1lbnQhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGRlbGV0ZSBhZmZlY3RlZCBjYWNoZXMKICAgIG15ICRDYWNoZUtleSA9ICdDYWNoZTo6Q3VzdG9tZXJVc2VyQ3VzdG9tZXJNZW1iZXJMaXN0OjonOwogICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNhY2hlJyktPkRlbGV0ZSgKICAgICAgICBUeXBlID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICBLZXkgID0+ICRDYWNoZUtleSAuICdDdXN0b21lclVzZXJJRDo6JyAuICRQYXJhbXtDdXN0b21lclVzZXJJRH0sCiAgICApOwogICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNhY2hlJyktPkRlbGV0ZSgKICAgICAgICBUeXBlID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICBLZXkgID0+ICRDYWNoZUtleSAuICdDdXN0b21lcklEOjonIC4gJFBhcmFte0N1c3RvbWVySUR9LAogICAgKTsKCiAgICAjIGdldCBkYXRhYmFzZSBvYmplY3QKICAgIG15ICREQk9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEQicpOwoKICAgICMgZGVsZXRlIGV4aXN0aW5nIHJlbGF0aW9uCiAgICByZXR1cm4gaWYgISREQk9iamVjdC0+RG8oCiAgICAgICAgU1FMID0+ICdERUxFVEUgRlJPTSBjdXN0b21lcl91c2VyX2N1c3RvbWVyCiAgICAgICAgICAgIFdIRVJFIHVzZXJfaWQgPSA/CiAgICAgICAgICAgIEFORCBjdXN0b21lcl9pZCA9ID8nLAogICAgICAgIEJpbmQgPT4gWyBcJFBhcmFte0N1c3RvbWVyVXNlcklEfSwgXCRQYXJhbXtDdXN0b21lcklEfSBdLAogICAgKTsKCiAgICAjIHJldHVybiBpZiByZWxhdGlvbiBpcyBub3QgYWN0aXZlCiAgICByZXR1cm4gMSBpZiAhJFBhcmFte0FjdGl2ZX07CgogICAgIyBpbnNlcnQgbmV3IHJlbGF0aW9uCiAgICByZXR1cm4gaWYgISREQk9iamVjdC0+RG8oCiAgICAgICAgU1FMID0+ICcKICAgICAgICAgICAgSU5TRVJUIElOVE8gY3VzdG9tZXJfdXNlcl9jdXN0b21lciAodXNlcl9pZCwgY3VzdG9tZXJfaWQsIGNyZWF0ZV90aW1lLCBjcmVhdGVfYnksCiAgICAgICAgICAgIGNoYW5nZV90aW1lLCBjaGFuZ2VfYnkpCiAgICAgICAgICAgIFZBTFVFUyAoPywgPywgY3VycmVudF90aW1lc3RhbXAsID8sIGN1cnJlbnRfdGltZXN0YW1wLCA/KScsCiAgICAgICAgQmluZCA9PiBbIFwkUGFyYW17Q3VzdG9tZXJVc2VySUR9LCBcJFBhcmFte0N1c3RvbWVySUR9LCBcJFBhcmFte1VzZXJJRH0sIFwkUGFyYW17VXNlcklEfSwgXSwKICAgICk7CgogICAgcmV0dXJuIDE7Cn0KCj1oZWFkMiBDdXN0b21lclVzZXJDdXN0b21lck1lbWJlckxpc3QoKQoKZ2V0IHJlbGF0ZWQgY3VzdG9tZXIgSURzIG9mIGEgY3VzdG9tZXIgdXNlcgoKICAgIG15IEBDdXN0b21lcklEcyA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlckN1c3RvbWVyTWVtYmVyTGlzdCgKICAgICAgICBDdXN0b21lclVzZXJJRCA9PiAxMjMsCiAgICApOwoKUmV0dXJuczoKICAgIEBDdXN0b21lcklEcyA9ICgKICAgICAgICAnMTIzJywKICAgICAgICAnNDU2JywKICAgICk7CgpnZXQgcmVsYXRlZCBjdXN0b21lciB1c2VycyBvZiBhIGN1c3RvbWVyIElECgogICAgbXkgQEN1c3RvbWVyVXNlcnMgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJDdXN0b21lck1lbWJlckxpc3QoCiAgICAgICAgQ3VzdG9tZXJJRCA9PiAxMjMsCiAgICApOwoKUmV0dXJuczoKICAgIEBDdXN0b21lclVzZXJzID0gKAogICAgICAgICcxMjMnLAogICAgICAgICc0NTYnLAogICAgKTsKCj1jdXQKCnN1YiBDdXN0b21lclVzZXJDdXN0b21lck1lbWJlckxpc3QgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte0N1c3RvbWVyVXNlcklEfSAmJiAhJFBhcmFte0N1c3RvbWVySUR9ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnR290IG5vIEN1c3RvbWVyVXNlcklEIG9yIEN1c3RvbWVySUQhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgbXkgJERCT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkRCJyk7CiAgICBteSAkQ2FjaGVLZXkgPSAnQ2FjaGU6OkN1c3RvbWVyVXNlckN1c3RvbWVyTWVtYmVyTGlzdDo6JzsKCiAgICBpZiAoICRQYXJhbXtDdXN0b21lclVzZXJJRH0gKSB7CgogICAgICAgICMgY2hlY2sgaWYgdGhpcyByZXN1bHQgaXMgcHJlc2VudCAoaW4gY2FjaGUpCiAgICAgICAgJENhY2hlS2V5IC49ICdDdXN0b21lclVzZXJJRDo6JyAuICRQYXJhbXtDdXN0b21lclVzZXJJRH07CiAgICAgICAgbXkgJENhY2hlID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNhY2hlJyktPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gJENhY2hlS2V5LAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIEB7JENhY2hlfSBpZiAkQ2FjaGU7CgogICAgICAgICMgZ2V0IGN1c3RvbWVyIGlkcwogICAgICAgIHJldHVybiBpZiAhJERCT2JqZWN0LT5QcmVwYXJlKAogICAgICAgICAgICBTUUwgPT4KICAgICAgICAgICAgICAgICdTRUxFQ1QgY3VzdG9tZXJfaWQKICAgICAgICAgICAgICAgIEZST00gY3VzdG9tZXJfdXNlcl9jdXN0b21lcgogICAgICAgICAgICAgICAgV0hFUkUgdXNlcl9pZCA9ID8KICAgICAgICAgICAgICAgIE9SREVSIEJZIGN1c3RvbWVyX2lkJywKICAgICAgICAgICAgQmluZCA9PiBbIFwkUGFyYW17Q3VzdG9tZXJVc2VySUR9LCBdLAogICAgICAgICk7CgogICAgICAgICMgZmV0Y2ggdGhlIHJlc3VsdAogICAgICAgIG15IEBDdXN0b21lcklEczsKICAgICAgICB3aGlsZSAoIG15IEBSb3cgPSAkREJPYmplY3QtPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICAgICAgcHVzaCBAQ3VzdG9tZXJJRHMsICRSb3dbMF07CiAgICAgICAgfQoKICAgICAgICAjIGNhY2hlIHRoZSByZXN1bHQKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q2FjaGUnKS0+U2V0KAogICAgICAgICAgICBUeXBlICA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIFRUTCAgID0+ICRTZWxmLT57Q2FjaGVUVEx9LAogICAgICAgICAgICBLZXkgICA9PiAkQ2FjaGVLZXksCiAgICAgICAgICAgIFZhbHVlID0+IFxAQ3VzdG9tZXJJRHMsCgogICAgICAgICk7CgogICAgICAgIHJldHVybiBAQ3VzdG9tZXJJRHM7CiAgICB9CiAgICBlbHNlIHsKCiAgICAgICAgIyBjaGVjayBpZiB0aGlzIHJlc3VsdCBpcyBwcmVzZW50IChpbiBjYWNoZSkKICAgICAgICAkQ2FjaGVLZXkgLj0gJ0N1c3RvbWVySUQ6OicgLiAkUGFyYW17Q3VzdG9tZXJJRH07CiAgICAgICAgbXkgJENhY2hlID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNhY2hlJyktPkdldCgKICAgICAgICAgICAgVHlwZSA9PiAkU2VsZi0+e0NhY2hlVHlwZX0sCiAgICAgICAgICAgIEtleSAgPT4gJENhY2hlS2V5LAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIEB7JENhY2hlfSBpZiAkQ2FjaGU7CgogICAgICAgICMgZ2V0IGN1c3RvbWVyIHVzZXJzCiAgICAgICAgcmV0dXJuIGlmICEkREJPYmplY3QtPlByZXBhcmUoCiAgICAgICAgICAgIFNRTCA9PgogICAgICAgICAgICAgICAgJ1NFTEVDVCB1c2VyX2lkCiAgICAgICAgICAgICAgICBGUk9NIGN1c3RvbWVyX3VzZXJfY3VzdG9tZXIgV0hFUkUKICAgICAgICAgICAgICAgIGN1c3RvbWVyX2lkID0gPwogICAgICAgICAgICAgICAgT1JERVIgQlkgdXNlcl9pZCcsCiAgICAgICAgICAgIEJpbmQgPT4gWyBcJFBhcmFte0N1c3RvbWVySUR9LCBdLAogICAgICAgICk7CgogICAgICAgICMgZmV0Y2ggdGhlIHJlc3VsdAogICAgICAgIG15IEBDdXN0b21lclVzZXJJRHM7CiAgICAgICAgd2hpbGUgKCBteSBAUm93ID0gJERCT2JqZWN0LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgICAgIHB1c2ggQEN1c3RvbWVyVXNlcklEcywgJFJvd1swXTsKICAgICAgICB9CgogICAgICAgICMgY2FjaGUgdGhlIHJlc3VsdAogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDYWNoZScpLT5TZXQoCiAgICAgICAgICAgIFR5cGUgID0+ICRTZWxmLT57Q2FjaGVUeXBlfSwKICAgICAgICAgICAgVFRMICAgPT4gJFNlbGYtPntDYWNoZVRUTH0sCiAgICAgICAgICAgIEtleSAgID0+ICRDYWNoZUtleSwKICAgICAgICAgICAgVmFsdWUgPT4gXEBDdXN0b21lclVzZXJJRHMsCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuIEBDdXN0b21lclVzZXJJRHM7CiAgICB9Cn0KCnN1YiBERVNUUk9ZIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgIyBleGVjdXRlIGFsbCB0cmFuc2FjdGlvbiBldmVudHMKICAgICRTZWxmLT5FdmVudEhhbmRsZXJUcmFuc2FjdGlvbigpOwoKICAgIHJldHVybiAxOwp9CgoxOwoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoTDxodHRwczovL290cnMub3JnLz4pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBMPGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTMuMC50eHQ+LgoKPWN1dAo=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxvdHJzX2NvbmZpZyB2ZXJzaW9uPSIyLjAiIGluaXQ9IkFwcGxpY2F0aW9uIj4KICAgIDxTZXR0aW5nIE5hbWU9Ik11bHRpdGVuYW5jeSIgUmVxdWlyZWQ9IjEiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gVHJhbnNsYXRhYmxlPSIxIj5FbmFibGVzIHRoZSBtdWx0aXRlbmFuY3kgZnVuY3Rpb24gZm9yIGN1c3RvbWVyIGFuZCBjdXN0b21lciB1c2VyLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPE5hdmlnYXRpb24+Q29yZTo6UGVybWlzc2lvbjwvTmF2aWdhdGlvbj4KICAgICAgICA8VmFsdWU+CiAgICAgICAgICAgIDxJdGVtIFZhbHVlVHlwZT0iQ2hlY2tib3giPjE8L0l0ZW0+CiAgICAgICAgPC9WYWx1ZT4KICAgIDwvU2V0dGluZz4KICAgIDxTZXR0aW5nIE5hbWU9Ik11bHRpdGVuYW5jeTo6UGVybWlzc2lvbkdyb3VwIiBSZXF1aXJlZD0iMSIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBUcmFuc2xhdGFibGU9IjEiPlNwZWNpZmllcyB0aGUgZ3JvdXAgdGhhdCBjYW4gc2V0IG11bHRpdGVuYW5jeSBmb3IgY3VzdG9tZXIuIE11bHRpdGVuYW5jeSBkb2VzIG5vdCBhcHBseSB0byBtZW1iZXJzIG9mIHRoaXMgZ3JvdXAuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8TmF2aWdhdGlvbj5Db3JlOjpQZXJtaXNzaW9uPC9OYXZpZ2F0aW9uPgogICAgICAgIDxWYWx1ZT4KICAgICAgICAgICAgPEl0ZW0gVmFsdWVUeXBlPSJTdHJpbmciIFZhbHVlUmVnZXg9IiI+YWRtaW48L0l0ZW0+CiAgICAgICAgPC9WYWx1ZT4KICAgIDwvU2V0dGluZz4KPC9vdHJzX2NvbmZpZz4K
IyAtLQojIENvcHlyaWdodCAoQykgMjAyMSBSb3RoZXIgT1NTIEdtYkgsIGh0dHBzOi8vcm90aGVyLW9zcy5jb20vCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0zLjAudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6TGFuZ3VhZ2U6OmRlX1JvdGhlck9TU0N1c3RvbWVyTXVsdGl0ZW5hbmN5OwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwp1c2UgdXRmODsKCnN1YiBEYXRhIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgIyBDb25maWcucG0KICAgICRTZWxmLT57VHJhbnNsYXRpb259LT57J1Zpc2libGUgdG8gYWdlbnRzIGluIGdyb3VwJ30gPSAnU2ljaHRiYXIgZsO8ciBBZ2VudGVuIGRlciBHcnVwcGUnOwogICAgJFNlbGYtPntUcmFuc2xhdGlvbn0tPnsnT25seSB2aXNpYmxlIHRvIGFnZW50cyBpbiBncm91cCd9ID0gJ051ciBzaWNodGJhciBmw7xyIEFnZW50ZW4gZGVyIEdydXBwZSc7CgogICAgIyBUZW1wbGF0ZTogQWRtaW5DdXN0b21lclVzZXIsIEFkbWluQ3VzdG9tZXJDb21wYW55CiAgICAkU2VsZi0+e1RyYW5zbGF0aW9ufS0+eydMaW1pdHMgdGhlIGFjY2VzcyBvZiBjdXN0b21lciBkYXRhIHRvIGNlcnRhaW4gZ3JvdXBzIChtdWx0aXRlbmFuY3kpLiBXaXRob3V0IHNlbGVjdGlvbiwgY3VzdG9tZXIgZGF0YSBpcyB2aXNpYmxlIHRvIGFsbCBhZ2VudHMuJ30gPSAnTGltaXRpZXJ0IGRlbiBadWdyaWZmIHZvbiBLdW5kZW5kYXRlbiBhdWYgYmVzdGltbXRlIEdydXBwZW4gKE1hbmRhbnRlbmZhzIhoaWdrZWl0KS4gT2huZSBBdXN3YWhsIHNpbmQgS3VuZGVuZGF0ZW4gZsO8ciBhbGxlIEFnZW50ZW4gc2ljaHRiYXIuJzsKCiAgICAjIFN5c2NvbmZpZzoKICAgICRTZWxmLT57VHJhbnNsYXRpb259LT57J1NwZWNpZmllcyB0aGUgZ3JvdXAgdGhhdCBjYW4gc2V0IG11bHRpdGVuYW5jeSBmb3IgY3VzdG9tZXIuIE11bHRpdGVuYW5jeSBkb2VzIG5vdCBhcHBseSB0byBtZW1iZXJzIG9mIHRoaXMgZ3JvdXAuJ30gPSAnR2lidCBkaWUgR3J1cHBlIGFuLCBkaWUgZGllIE1hbmRhbnRlbmbDpGhpZ2tlaXQgZsO8ciBLdW5kZW4gZmVzdGxlZ2VuIGthbm4uIERpZSBNYW5kYW50ZW5mw6RoaWdrZWl0IGdpbHQgbmljaHQgZsO8ciBNaXRnbGllZGVyIGRpZXNlciBHcnVwcGUuJzsKICAgICRTZWxmLT57VHJhbnNsYXRpb259LT57J0VuYWJsZXMgdGhlIG11bHRpdGVuYW5jeSBmdW5jdGlvbiBmb3IgY3VzdG9tZXIgYW5kIGN1c3RvbWVyIHVzZXIuJ30gPSAnQWt0aXZpZXJ0IGRpZSBNYW5kYW50ZW5mw6RoaWdrZWl0cy1GdW5rdGlvbiBmw7xyIEt1bmRlIHVuZCBLdW5kZW5iZW51dHplci4nOwp9CgoxOwo=