diff --git a/src/codesnap/core/parser.py b/src/codesnap/core/parser.py new file mode 100644 index 0000000..76ccd8b --- /dev/null +++ b/src/codesnap/core/parser.py @@ -0,0 +1 @@ +I2ltcG9ydCByZQoKaW1wb3J0IHJlCgoKaW1wb3J0IHJlCgoKaW1wb3J0IHJlCgoKaW1wb3J0IHJlCgoKaW1wb3J0IHJlCgoKaW1wb3J0IHJlCgoKaW1wb3J0IHJlCgoKaW1wb3J0IHJlCgoKaW1wb3J0IHJlCgoKIycgVHJlZS1zaXR0ZXIgd3JhcHBlciBmb3IgcGFyc2luZyBzb3VyY2UgZmlsZXMuJwoKICAgIGZyb20gZGF0YWNsYXNzZXMgaW1wb3J0IGRhdGFjbGFzcywgZmllbGQKICAgIGZyb20gcGF0aGxiIEltcG9ydCBQYXRoCiAgICBmcm9tIHR5cGluZyBpbXBvcnQgQW55CgogICAgaW1wb3J0IHRyZWVfc2l0dGVyCgoKICAgIGZyb20gY29kZXNuYXAuY29yZS5sYW5ndWFnZV9kZXRlY3RvciBpbXBvcnQgZGV0ZWN0X2xhbmd1YWdlCgoKQGRhdGFjbGFzcwpjbGFzcyBQYXJzZVJlc3VsdDoKICAgICJyZXN1bHQgb2YgcGFyc2luZyBhIHNvdXJjZSBmaWxlLiIKCiAgICBmaWxlX3BhdGg6IFBhdGgKICAgIGxhbmd1YWdlOiBzdHIKICAgIGFzdDogdHJlZV9zaXR0ZXIuTm9kZSB8IE5vbmUgPSBOb25lCiAgICBwYXJzZV9lcnJvcjogc3RyIHwgTm9uZSA9IE5vbmUKICAgIHBhcnNlX3RpbWU6IGZsb2F0ID0gMC4wCgoKQGRhdGFjbGFzcwpjbGFzcyBGdW5jdGlvbkluZm86CiAgICAiSW5mb3JtYXRpb24gYWJvdXQgYSBkZXRlY3RlZCBmdW5jdGlvbi4iCgogICAgbmFtZTogc3RyCiAgICBub2RlX3R5cGU6IHN0cgogICAgc3RhcnRfbGluZTogaW50CiAgICBlbmRfbGluZTogaW50CiAgICBwYXJhbWV0ZXJzOiBsaXN0W2RpY3Rbc3RyLCBzdHJdXSA9IGZpZWxkKGRlZmF1bHRfZmFjdG9yeT1saXN0KQogICAgcmV0dXJfdHlwZTogc3RyIHwgTm9uZSA9IE5vbmUKICAgIGRvY3N0cmluZzogc3RyIHwgTm9uZSA9IE5vbmUKICAgIGRlY29yYXRvcnM6IGxpc3Rbc3RyXSA9IGZpZWxkKGRlZmF1bHRfZmFjdG9yeT1saXN0KQogICAgaXNfYXN5bmM6IGJvb2wgPSBmYWxzZQogICAgdmlzaWJpbGl0eTogc3RyID0gInB1YmxpYyIKCgpgZGF0YWNsYXNzCkNsYXNzSW5mbzoKICAgICJJbmZvcm1hdGlvbiBhYm91dCBhIGRldGVjdGVkIGNsYXNzLiIKCgogICAgbmFtZTogc3RyCiAgICBzdGFydF9saW5lOiBpbnQKICAgIGVuZF9saW5lOiBpbnQKICAgIGRvY3N0cmluZzogc3RyIHwgTm9uZSA9IE5vbmUKICAgIGJhc2VzOiBsaXN0W3N0cl0gPSBmaWVsZChkZWZhdWx0X2ZhY3Rvcnk9bGlzdCkKICAgIGRlY29yYXRvcnM6IGxpc3Rbc3RyXSA9IGZpZWxkKGRlZmF1bHRfZmFjdG9yeT1saXN0KQogICAgbWV0aG9kczogbGlzdFtGdW5jdGlvbkluZm9dID0gZmllbGQoZGVmYXVsdF9mYWN0b3J5PWxpc3QpCiAgICB2aXNpYmlsaXR5OiBzdHIgPSAicHVibGljIgoKCkxBTkdVQUdFX1RPX0dSQU1NQVI6IGRpY3Rbc3RyLCBzdHJdID0gewogICAgInB5dGhvbiI6ICJweXRob24iLAogICAgImphdmFzY3JpcHQiOiJqYXZhc2NyaXB0IiwKICAgICJ0eXBlc2NyaXB0IjoidHlwZXNjcmlwdCIsCiAgICAiZ28iOiJnbyIsCiAgICAicnVzdCI6InJ1c3QiLAogICAgImphdmEiOiJqYXZhIiwKICAgICJjIjoiYyIsCiAgICAiY3BwIjoiY3BwIiwKICAgICJydWJ5IjoicnVieSIsCiAgICAicGhwIjoicGhwIiwKCmNsYXNzIFRyZWVTaXR0ZXJQYXJzZXI6CiAgICAiV3JhcHBlciBmb3IgdHJlZS1zaXR0ZXIgcGFyc2luZyBvcGVyYXRpb25zLiIKCiAgICBkZWYgX19pbml0X19fc2VsZiwgZ3JhbW1hcl9jYWNoZTogc3RyIHwgTm9uZSA9IE5vbmUpOgogICAgIkluaXRpYWxpemUgdGhlIHBhcnNlci4KCiAgICAgICAgQXJnczoKICAgICAgICAgICAgZ3JhbW1hcl9jYWNoZTogT3B0aW9uYWwgcGF0aCB0byB0cmVlLXNpdHRlciBncmFtbWFyIGNhY2hlLiIKCiAgICAgICAgc2VsZi5fcGFyc2VyczogZGljdFtzdHIsIHRyZWVfc2l0dGVyLlBhcnNlcl0gPSB7fQogICAgICAgIHNlbGYuX2dyYW1tYXJzOiBkaWN0W3N0ciwgQW55XSA9IHt9CiAgICAgICAgc2VsZi5fbGFuZ3VhZ2VfY2FjaGU6IGRpY3Rbc3RyLCBBbnldID0ge30KCgogICAgZGVmIF9nZXRfbGFuZ3VhZ2Uoc2VsZiwgbGFuZ3VhZ2U6IHN0cikgLT4gQW55OgogICAgICAgICJHZXQgb3IgbG9hZCB0cmVlLXNpdHRlciBsYW5ndWFnZS4KCiAgICAgICAgaWYgbGFuZ3VhZ2UgaW4gc2VsZi5fbGFuZ3VhZ2VfY2FjaGU6CiAgICAgICAgICAgIHJldHVybiBzZWxmLmxhbmd1YWdlX2NhY2hlW2xhbmd1YWdlXQoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGZyb20gdHJlZV9zaXR0ZXJfbGFuZ3VhZ2VzIGltcG9ydCBnZXRfbGFuZ3VhZ2UKCiAgICAgICAgICAgIGxhbmcgPSBnZXRfbGFuZ3VhZ2UobGFuZ3VhZ2UpCgogICAgICAgICAgICBzZWxmLmxhbmd1YWdlX2NhY2hlW2xhbmd1YWdlXSA9IGxhbmcKCiAgICAgICAgICAgIHJldHVybiBsYW5nCgogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCgogICAgZGVmIF9nZXRfcGFyc2VyKHNlbGYsIGxhbmd1YWdlOiBzdHIpIC0+IHRyZWVfc2l0dGVyLlBhcnNlciB8IE5vbmU6CiAgICAgICAgIkdldCBvciBjcmVhdGUgYSBwYXJzZXIgZm9yIHRoZSBzcGVjaWZpZWQgbGFuZ3VhZ2UuCgoKICAgICAgICBpZiBsYW5ndWFnZSBpbiBzZWxmLl9wYXJzZXJzOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fcGFyc2Vyc1tsYW5ndWFnZV0KCiAgICAgICAgbGFuZyA9IHNlbGYuX2dldF9sYW5ndWFnZShsYW5ndWFnZSkKCiAgICAgICAgaWYgbGFuZyBpcyBOb25lOgogICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgICAgICBwYXJzZXIgPSB0cmVlX3NpdHRlci5QYXJzZXIoKQoKICAgICAgICBwYXJzZXIuc2V0X2xhbmd1YWdlKGxhbmcpCgogICAgICAgIHNlbGYuX3BhcnNlcnNbbGFuZ3VhZ2VdID0gcGFyc2VyCgogICAgICAgIHJldHVybiBwYXJzZXIKCgogICAgZGVmIHBhcnNlX2ZpbGUoc2VsZiwgZmlsZV9wYXRoOiBQYXRoKSAtPiBQYXJzZVJlc3VsdDoKICAgICAgICAiUGFyc2UgYSBzb3VyY2UgZmlsZSBhbmQgcmV0dXJuIHRoZSBBU1QuCgoKICAgICAgICBBcmdzOgogICAgICAgICAgICBmaWxlX3BhdGg6IFBhdGggdG8gdGhlIHNvdXJjZSBmaWxlLgoKCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIFBhcnNlUmVzdWx0IGNvbnRhaW5pbmcgdGhlIEFTVCBvciBlcnJvciBpbmZvcm1hdGlvbi4iCgogICAgICAgIGltcG9ydCB0aW1lCgogICAgICAgIHN0YXJ0X3RpbWUgPSB0aW1lLnRpbWUoKQoKCiAgICAgICAgdHJ5OgogICAgICAgICAgICBsYW5ndWFnZSA9IGRldGVjdF9sYW5ndWFnZShmaWxlX3BhdGgpCgogICAgICAgICAgICBpZiBsYW5ndWFnZSBpcyBOb25lOgogICAgICAgICAgICAgICAgcmV0dXJuIFBhcnNlUmVzdWx0KAogICAgICAgICAgICAgICAgICAgIGZpbGVfcGF0aD0gZmlsZV9wYXRoLAogICAgICAgICAgICAgICAgICAgIGxhbmd1YWdlPSJ1bmtub3duIiwKICAgICAgICAgICAgICAgICAgICBwYXJzZV9lcnJvcj0iVW5zdXBwb3J0ZWQgb3IgdW5rbm93biBmaWxlIHR5cGUiCiAgICAgICAgICAgICAgICApCgoKICAgICAgICAgICAgcGFyc2VyID0gc2VsZi5fZ2V0X3BhcnNlcihsYW5ndWFnZSkKCiAgICAgICAgICAgIGlmIHBhcnNlciBpcyBOb25lOgogICAgICAgICAgICAgICAgcmV0dXJuIFBhcnNlUmVzdWx0KAogICAgICAgICAgICAgICAgICAgIGZpbGVfcGF0aD0gZmlsZV9wYXRoLAogICAgICAgICAgICAgICAgICAgIGxhbmd1YWdlPWxhbmd1YWdlLAogICAgICAgICAgICAgICAgICAgIHBhcnNlX2Vycm9yPSJQYXJzZXIgbm90IGF2YWlsYWJsZSBmb3Ige2xhbmd1YWdlfSIKICAgICAgICAgICAgICApCgoKICAgICAgICAgICAgZmlsZV9jb250ZW50ID0gZmlsZV9wYXRoLnJlYWRfdGV4dChlbmNvZGluZz0ndXRmLTgnKQoKICAgICAgICAgICAgdHJlZSA9IHBhcnNlci5wYXJzZShmaWxlX2NvbnRlbnQuZW5jb2RlKCd1dGYtOCcpKQoKCiAgICAgICAgICAgIHBhcnNlX3RpbWUgPSB0aW1lLnRpbWUoKSAtIHN0YXJ0X3RpbWUKCgogICAgICAgICAgICByZXR1cm4gUGFyc2VSZXN1bHQoCiAgICAgICAgICAgICAgICBmaWxlX3BhdGg9IGZpbGVfcGF0aCwKICAgICAgICAgICAgICAgIGxhbmd1YWdlPWxhbmd1YWdlLAogICAgICAgICAgICAgICAgYXN0PXRyZWUucm9vdF9ub2RlLAogICAgICAgICAgICAgICAgcGFyc2VfdGltZT1wYXJzZV90aW1lCiAgICAgICAgICAgICkKCiAgICAgICAgZXhjZXB0IFVuaWNvZGVERUNvZGVFcnJvcjoKCiAgICAgICAgICAgIHJldHVybiBQYXJzZVJlc3VsdCgKICAgICAgICAgICAgICAgIGZpbGVfcGF0aD0gZmlsZV9wYXRoLAogICAgICAgICAgICAgICAgbGFuZ3VhZ2U9InVua25vd24iLAogICAgICAgICAgICAgICAgcGFyc2VfZXJyb3I9IlVuYWJsZSB0byBkZWNvZGUgZmlsZSBhcyBVVEYtOCIKCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICByZXR1cm4gUGFyc2VSZXN1bHQoCiAgICAgICAgICAgICAgICBmaWxlX3BhdGg9IGZpbGVfcGF0aCwKICAgICAgICAgICAgICAgIGxhbmd1YWdlPSJ1bmtub3duIiwKICAgICAgICAgICAgICAgIHBhcnNlX2Vycm9yPXN0cihlKQoKCgogICAgZGVmIGV4dHJhY3RfZnVuY3Rpb25zKHNlbGYsIHBhcnNlX3Jlc3VsdDogUGFyc2VSZXN1bHQpIC0+IGxpc3RbRnVuY3Rpb25JbmZvXToKCiAgICAgICAgIkV4dHJhY3QgZnVuY3Rpb24gZGVmaW5pdGlvbnMgZnJvbSBhIHBhcnNlIHJlc3VsdC4KCgogICAgICAgIEFyZ3M6CiAgICAgICAgICAgIHBhcnNlX3Jlc3VsdDogVGhlIHBhcnNlIHJlc3VsdCB0byBleHRyYWN0IGZyb20uCgoKCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIExpc3Qgb2YgRnVuY3Rpb25JbmZvIG9iamVjdHMuIgogICAgICAgIGlmIHBhcnNlX3Jlc3VsdC5hc3QgaXMgTm9uZToKICAgICAgICAgICAgcmV0dXJuIFtdCgogICAgICAgIGZ1bmN0aW9uczogbGlzdFtGdW5jdGlvbkluZm9dID0gW10KCiAgICAgICAgbGFuZ3VhZ2UgPSBwYXJzZV9yZXN1bHQubGFuZ3VhZ2UKCgogICAgICAgIGlmIGxhbmd1YWdlID09ICJweXRob24iOgogICAgICAgICAgICBmdW5jdGlvbnMgPSBzZWxmLl9leHRyYWN0X3B5dGhvbl9mdW5jdGlvbnMocGFyc2VfcmVzdWx0KQoKICAgICAgICBlbGlmIGxhbmd1YWdlIGluICgiamF2YXNjcmlwdCIsICJ0eXBlc2NyaXB0Iik6CiAgICAgICAgICAgIGZ1bmN0aW9ucyA9IHNlbGYuX2V4dHJhY3RfanNfZnVuY3Rpb25zKHBhcnNlX3Jlc3VsdCkKCiAgICAgICAgZWxpZiBsYW5ndWFnZSA9PSAiZ28iOgogICAgICAgICAgICBmdW5jdGlvbnMgPSBzZWxmLl9leHRyYWN0X2dvX2Z1bmN0aW9ucyhwYXJzZV9yZXN1bHQpCgogICAgICAgIGVsaWYgbGFuZ3VhZ2UgPT0gInJ1c3QiOgogICAgICAgICAgICBmdW5jdGlvbnMgPSBzZWxmLl9leHRyYWN0X3J1c3RfZnVuY3Rpb25zKHBhcnNlX3Jlc3VsdCkKCiAgICAgICAgZWxpZiBsYW5ndWFnZSA9PSAiamF2YSI6CiAgICAgICAgICAgIGZ1bmN0aW9ucyA9IHNlbGYuX2V4dHJhY3RfamF2YV9mdW5jdGlvbnMocGFyc2VfcmVzdWx0KQoKCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9ucwoKCgogICAgZGVmIGV4dHJhY3RfY2xhc3NlcyhzZWxmLCBwYXJzZV9yZXN1bHQ6IFBhcnNlUmVzdWx0KSAtPiBsaXN0W0NsYXNzSW5mb106CgogICAgICAgICJFeHRyYWN0IGNsYXNzIGRlZmluaXRpb25zIGZyb20gYSBwYXJzZSByZXN1bHQuCgoKCiAgICAgICAgQXJnczoKICAgICAgICAgICAgcGFyc2VfcmVzdWx0OiBUaGUgcGFyc2UgcmVzdWx0IHRvIGV4dHJhY3QgZnJvbS4KCgogICAgICAgIFJldHVybnM6CiAgICAgICAgICAgIExpc3Qgb2YgQ2xhc3NJbmZvIG9iamVjdHMuIgogICAgICAgIGlmIHBhcnNlX3Jlc3VsdC5hc3QgaXMgTm9uZDoKICAgICAgICAgICAgcmV0dXJuIFtdCgogICAgICAgIGNsYXNzZXM6IGxpc3RbQ2xhc3NJbmZvXSA9IFtdCgogICAgICAgIGxhbmd1YWdlID0gcGFyc2VfcmVzdWx0Lmxhbmd1YWdlCgoKCiAgICAgICAgaWYgbGFuZ3VhZ2UgPT0gInB5dGhvbiI6CiAgICAgICAgICAgIGNsYXNzZXMgPSBzZWxmLl9leHRyYWN0X3B5dGhvbl9jbGFzc2VzKHBhcnNlX3Jlc3VsdCkKCiAgICAgICAgZWxpZiBsYW5ndWFnZSBpbiAoImphdmFzY3JpcHQiLCAidHlwZXNjcmlwdCIpOgogICAgICAgICAgICBjbGFzc2VzID0gc2VsZi5fZXh0cmFjdF9qc19jbGFzc2VzKHBhcnNlX3Jlc3VsdCkKCiAgICAgICAgZWxpZiBsYW5ndWFnZSA9PSAiamF2YSI6CiAgICAgICAgICAgIGNsYXNzZXMgPSBzZWxmLl9leHRyYWN0X2phdmFfY2xhc3NlcyhwYXJzZV9yZXN1bHQpCgoKCiAgICAgICAgcmV0dXJuIGNsYXNzZXMKCiAgICBkZWYgX2V4dHJhY3RfcHl0aG9uX2Z1bmN0aW9ucyhzZWxmLCBwYXJzZV9yZXN1bHQ6IFBhcnNlUmVzdWx0KSAtPiBsaXN0W0Z1bmN0aW9uSW5mb10:CgogICAgICAgICJFeHRyYWN0IFB5dGhvbiBmdW5jdGlvbiBkZWZpbml0aW9ucy4iCgogICAgICAgIGZ1bmN0aW9uczogbGlzdFtGdW5jdGlvbkluZm9dID0gW10KCiAgICAgICAgZGVmIHdhbGsobm9kZTogdHJlZV9zaXR0ZXIuTm9kZSk6CiAgICAgICAgICAgIGlmIG5vZGUudHlwZSA9PSAiZnVuY3Rpb25fZGVmaW5pdGlvbiI6CiAgICAgICAgICAgICAgICBmdW5jX2luZm8gPSBzZWxmLl9wYXJzZV9weXRob25fZnVuY3Rpb24obm9kZSkKCiAgICAgICAgICAgICAgICBpZiBmdW5jX2luZm86CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25zLmFwcGVuZChmdW5jX2luZm8pCgogICAgICAgICAgICBmb3IgY2hpbGQgaW4gbm9kZS5jaGlsZHJlbjoKCiAgICAgICAgICAgICAgICB3YWxrKGNoaWxkKQoKICAgICAgICB3YWxrKHBhcnNlX3Jlc3VsdC5hc3QpCgogICAgICAgIHJldHVybiBmdW5jdGlvbnMKCiAgICBkZWYgcF9wYXJzZV9weXRob25fZnVuY3Rpb24oc2VsZiwgbm9kZTogdHJlZV9zaXR0ZXIuTm9kZSkgLT4gRnVuY3Rpb25JbmZvIHwgTm9uZToKCiAgICAgICAgIlBhcmsgYSBweXRob24gZnVuY3Rpb24gZGVmaW5pdGlvbiBub2RlLiIKCiAgICAgICAgZnVuY19pbmZvID0gRnVuY3Rpb25JbmZvKAogICAgICAgICAgICBuYW1lPSIiLAogICAgICAgICAgICBub2RlX3R5cGU9ImZ1bmN0aW9uIiwKICAgICAgICAgICAgc3RhcnRfbGluZT1ub2RlLnN0YXJ0X3BvaW50WzBdICsgMSwKICAgICAgICAgICAgZW5kX2xpbmU9bm9kZS5lbmRfcG9pbnRbMF0gKyAxLAogICAgICAgICAgICBwYXJhbWV0ZXJzPVtdLAogICAgICAgICAgICByZXR1cm5fdHlwZT1Ob25lLAogICAgICAgICAgICBkb2NzdHJpbmdOb25lLAogICAgICAgICAgICBkZWNvcmF0b3JzPVtdLAogICAgICAgICAgICBpc19hc3luYz1GYWxzZSwKICAgICAgICAgICAgdmlzaWJpbGl0eT0icHVibGljIgogICAgICAgICkKCiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gIm5hbWUiOgogICAgICAgICAgICAgICAgZnVuY19pbmZvLm5hbWUgPSBjaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKQogICAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gInBhcmFtZXRlcnMiOgogICAgICAgICAgICAgICAgZnVuY19pbmZvLnBhcmFtZXRlcnMgPSBzZWxmLl9wYXJzZV9weXRob25fcGFyYW1ldGVycyhjaGlsZCkKCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gInR5cGVfaGludCI6CiAgICAgICAgICAgICAgICBmdW5jX2luZm8ucmV0dXJfdHlwZSA9IGNoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gImRlY29yYXRvciI6CiAgICAgICAgICAgICAgICBkZWNvcmF0b3IgPSBjaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKS50cmlwKCkKCiAgICAgICAgICAgICAgaWYgZGVjb3JhdG9yLnN0YXJ0c3dpdGgoJ0AnKToKICAgICAgICAgICAgICAgICAgICBkZWNvcmF0b3IgPSBkZWNvcmF0b3JbMTpdCgogICAgICAgICAgICAgICAgZnVuY19pbmZvLmRlY29yYXRvcnMuYXBwZW5kKGRlY29yYXRvcikKCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gImFzeW5jIjoKICAgICAgICAgICAgICAgIGZ1bmNfaW5mby5pc19hc3luYyA9IFRydWUKCiAgICAgICAgcmV0dXJuIGZ1bmNfaW5mbyBpZiBmdW5jX2luZm8ubmFtZSBlbHNlIE5vbmUKCiAgICBkZWYgcF9wYXJzZV9weXRob25fcGFyYW1ldGVycyhzZWxmLCBub2RlOiB0cmVlX3NpdHRlci5Ob2RlKSAtPiBsaXN0W2RpY3Rbc3RyLCBzdHJdXToKCiAgICAgICAgIlBhcmsgUHl0aG9uIGZ1bmN0aW9uIHBhcmFtZXRlcnMuIgogICAgICAgIHBhcmFtcyA9IFtdCgogICAgICAgIGZvciBjaGlsZCBpbiBub2RlLmNoaWxkcmVuOgogICAgICAgICAgICBpZiBjaGlsZC50eXBlID09ICJwYXJhbWV0ZXIiOgogICAgICAgICAgICAgICAgcGFyYW1faW5mbzogZGljdFtzdHIsIHN0cl0gPSAi bmFtZSI6IiIKCiAgICAgICAgICAgICAgICBmb3IgcGFyYW1fY2hpbGQgaW4gY2hpbGQuY2hpbGRyZW46CiAgICAgICAgICAgICAgICAgICAgaWYgcGFyYW1fY2hpbGQudHlwZSA9PSAiaWRlbnRpZmllciI6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtX2luZm9bIm5hbWUiXSA9IHBhcmFtX2NoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBwYXJhbV9jaGlsZC50eXBlID09ICJ0eXBlX2hpbnQiOgogICAgICAgICAgICAgICAgICAgICAgICBwYXJhbV9pbmZvWyJ0eXBlIl0gPSBwYXJhbV9jaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKQoKICAgICAgICAgICAgICAgIGlmIHBhcmFtX2luZm8uZ2V0KCJuYW1lIik6CiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChwYXJhbV9pbmZvKQoKICAgICAgICByZXR1cm4gcGFyYW1zCgogICAgZGVmIF9leHRyYWN0X3B5dGhvbl9jbGFzc2VzKHNlbGYsIHBhcnNlX3Jlc3VsdDogUGFyc2VSZXN1bHQpIC0+IGxpc3RbQ2xhc3NJbmZvXToKCiAgICAgICAgIkV4dHJhY3QgUHl0aG9uIGNsYXNzIGRlZmluaXRpb25zLiIKCiAgICAgICAgY2xhc3NlczogbGlzdFtDbGFzc0luZm9dID0gWwoKICAgICAgICBkZWYgd2Fsayhub2RlOiB0cmVlX3NpdHRlci5Ob2RlKToKCiAgICAgICAgICAgIGlmIG5vZGUudHlwZSA9PSAiY2xhc3NfZGVmaW5pdGlvbiI6CiAgICAgICAgICAgICAgICBjbGFzc19pbmZvID0gc2VsZi5fcGFyc2VfcHl0aG9uX2NsYXNzKG5vZGUpCgogICAgICAgICAgICAgICAgaWYgY2xhc3NfaW5mbzoKICAgICAgICAgICAgICAgICAgICBjbGFzc2VzLmFwcGVuZChjbGFzc19pbmZvKQoKICAgICAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgICAgICB3YWxrKGNoaWxkKQoKICAgICAgICB3YWxrKHBhcnNlX3Jlc3VsdC5hc3QpCgogICAgICAgIHJldHVybiBjbGFzc2VzCgogICAgZGVmIHBfcGFyc2VfcHl0aG9uX2NsYXNzKHNlbGYsIG5vZGU6IHRyZWVfc2l0dGVyLk5vZGUpIC0+IENsYXNzSW5mbyB8IE5vbmU6CgogICAgICAgICJQYXJrIGEgcHl0aG9uIGNsYXNzIGRlZmluaXRpb24gbm9kZS4iCgogICAgICAgIGNsYXNzX2luZm8gPSBDbGFzc0luZm8oCiAgICAgICAgICAgIG5hbWU9IiIsCiAgICAgICAgICAgIHN0YXJ0X2xpbmU9bm9kZS5zdGFydF9wb2ludFswXSArIDEsCiAgICAgICAgICAgIGVuZF9saW5lPW5vZGUuZW5kX3BvaW50WzBdICsgMSwKICAgICAgICAgICAgZG9jc3RyaW5nTm9uZSwKICAgICAgICAgICAgYmFzZXM9W10sCiAgICAgICAgICAgIGRlY29yYXRvcnM9WSwKICAgICAgICAgICAgbWV0aG9kcz1bKSwKICAgICAgICAgICAgdmlzaWJpbGl0eT0icHVibGljIgogICAgICAgICkKCiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gIm5hbWUiOgogICAgICAgICAgICAgICAgY2xhc3NfaW5mby5uYW1lID0gY2hpbGQudGV4dC5kZWNvZGUoJ3V0Zi04JykKCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gImJhc2VzIjoKCiAgICAgICAgICAgIGZvciBiYXNlX2NoaWxkIGluIGNoaWxkLmNoaWxkcmVuOgogICAgICAgICAgICAgICAgaWYgYmFzZV9jaGlsZC50eXBlID09ICJhdHRyaWJ1dGUiIG9yIGJhc2VfY2hpbGQudHlwZSA9PSAiaWRlbnRpZmllciI6CiAgICAgICAgICAgICAgICAgICAgYmFzZV9uYW1lID0gYmFzZV9jaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKQoKICAgICAgICAgICAgICAgICAgICBpZiBiYXNlX25hbWUgYW5kIGJhc2VfbmFtZSBub3QgaW4gKCJvYmplY3QiLCk6CiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzX2luZm8uYmFzZXMuYXBwZW5kKGJhc2VfbmFtZSkKCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gImRlY29yYXRvciI6CiAgICAgICAgICAgICAgICBkZWNvcmF0b3IgPSBjaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKS50cmlwKCkKCiAgICAgICAgICAgICAgaWYgZGVjb3JhdG9yLnN0YXJ0c3dpdGgoJ0AnKToKICAgICAgICAgICAgICAgICAgICBkZWNvcmF0b3IgPSBkZWNvcmF0b3JbMTpdCgogICAgICAgICAgICAgICAgY2xhc3NfaW5mby5kZWNvcmF0b3JzLmFwcGVuZChkZWNvcmF0b3IpCgoKICAgICAgICByZXR1cm4gY2xhc3NfaW5mbyBpZiBjbGFzc19pbmZvLm5hbWUgZWxzZSBOb25lCgogICAgZGVmIF9leHRyYWN0X2pzX2Z1bmN0aW9ucyhzZWxmLCBwYXJzZV9yZXN1bHQ6IFBhcnNlUmVzdWx0KSAtPiBsaXN0W0Z1bmN0aW9uSW5mb10:CgogICAgICAgICJFeHRyYWN0IEphdmFTY3JpcHQvVHlwZVNjcmlwdCBmdW5jdGlvbiBkZWZpbml0aW9ucy4iCgogICAgICAgIGZ1bmN0aW9uczogbGlzdFtGdW5jdGlvbkluZm9dID0gWwoKICAgICAgICBkZWYgd2Fsayhub2RlOiB0cmVlX3NpdHRlci5Ob2RlKToKCiAgICAgICAgICAgIGlmIG5vZGUudHlwZSBpbiAoImZ1bmN0aW9uX2RlY2xYXJhdGlvbiIsICJtZXRob2RfZGVmaW5pdGlvbiIsICJhcnJvdyIgZnVuY3Rpb24iKToKCiAgICAgICAgICAgICAgICBmdW5jX2luZm8gPSBzZWxmLl9wYXJzZV9qc19mdW5jdGlvbihub2RlKQoKICAgICAgICAgICAgICAgIGlmIGZ1bmNfaW5mbzoKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMuYXBwZW5kKGZ1bmNfaW5mbwoKICAgICAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgICAgICB3YWxrKGNoaWxkKQoKICAgICAgICB3YWxrKHBhcnNlX3Jlc3VsdC5hc3QpCgogICAgICAgIHJldHVybiBmdW5jdGlvbnMKCiAgICBkZWYgcF9wYXJzZV9qc19mdW5jdGlvbihzZWxmLCBub2RlOiB0cmVlX3NpdHRlci5Ob2RlKSAtPiBGdW5jdGlvbklmZm8gfCBOb25lOAoKICAgICAgICAiUGFyayBhIEphdmFTY3JpcHQgZnVuY3Rpb24gZGVmaW5pdGlvbiBub2RlLiIKCiAgICAgICAgZnVuY19pbmZvID0gRnVuY3Rpb25JbmZvKAogICAgICAgICAgICBuYW1lPSIiLAogICAgICAgICAgICBub2RlX3R5cGU9bm9kZS50eXBlLAogICAgICAgICAgICBzdGFydF9saW5lPW5vZGUuc3RhcnRfcG9pbnRbMF0gKyAxLAogICAgICAgICAgICBlbmRfbGluZT1ub2RlLmVuZF9wb2ludFswXSArIDEsCiAgICAgICAgICAgIHBhcmFtZXRlcnM9WSwKICAgICAgICAgICAgcmV0dXJfdHlwZT1Ob25lLAogICAgICAgICAgICBkb2NzdHJpbmdOb25lLAogICAgICAgICAgICBkZWNvcmF0b3JzPVtdLAogICAgICAgICAgICBpc19hc3luYz1GYWxzZSwKICAgICAgICAgICAgdmlzaWJpbGl0eT0icHVibGljIgogICAgICAgICkKCiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gImlkZW50aWZpZXIiOgogICAgICAgICAgICAgICAgaWYgbm90IGZ1bmNfaW5mby5uYW1lOgogICAgICAgICAgICAgICAgICAgIGZ1bmNfaW5mby5uYW1lID0gY2hpbGQudGV4dC5kZWNvZGUoJ3V0Zi04JykKCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gImZvcm1hbF9wYXJhbWV0ZXJzIjoKCiAgICAgICAgICAgICAgICBmdW5jX2luZm8ucGFyYW1ldGVycyA9IHNlbGYuX3BhcnNlanZhc19wYXJhbWV0ZXJzKGNoaWxkKQoKCiAgICAgICAgcmV0dXJuIGZ1bmNfaW5mbyBpZiBmdW5jX2luZm8ubmFtZSBvciBub2RlLnR5cGUgPT0gImFycm93X2Z1bmN0aW9uIiBlbHNlIE5vbmUKCiAgICBkZWYgcF9wYXJzZV9qc192YXJfbWV0ZXJzKHNlbGYsIG5vZGU6IHRyZWVfc2l0dGVyLk5vZGUpIC0+IGxpc3RbZGljdFtzdHIsIHN0cl1dOAoKICAgICAgICAiUGFyayBKYXZhU2NyaXB0IGZ1bmN0aW9uIHBhcmFtZXRlcnMuIgogICAgICAgIHBhcmFtcyA9IFtdCgogICAgICAgIGZvciBjaGlsZCBpbiBub2RlLmNoaWxkcmVuOgogICAgICAgICAgICBpZiBjaGlsZC50eXBlID09ICJpZGVudGlmaWVyIjoKCiAgICAgICAgICAgICAgICBwYXJhbXMuYXBwZW5kKHsi bmFtZSI6IGNoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpfSkKCiAgICAgICAgcmV0dXJuIHBhcmFtcwoKICAgIGRlZiBfZXh0cmFjdF9qc19jbGFzc2VzKHNlbGYsIHBhcnNlX3Jlc3VsdDogUGFyc2VSZXN1bHQpIC0+IGxpc3RbQ2xhc3NJbmZvXToKCiAgICAgICAgIkV4dHJhY3QgSmF2YVNjcmlwdC9UeXBlU2NyaXB0IGNsYXNzIGRlZmluaXRpb25zLiIKCiAgICAgICAgY2xhc3NlczogbGlzdFtDbGFzc0luZm9dID0gWwoKICAgICAgICBkZWYgd2Fsayhub2RlOiB0cmVlX3NpdHRlci5Ob2RlKToKCiAgICAgICAgICAgIGlmIG5vZGUudHlwZSA9PSAiY2xhc3NfZGVjbGFyYXRpb24iOgogICAgICAgICAgICAgICAgY2xhc3NfaW5mbyA9IHNlbGYuX3BhcnNlanZhc19jbGFzcyhub2RlKQoKICAgICAgICAgICAgICAgIGlmIGNsYXNzX2luZm86CiAgICAgICAgICAgICAgICAgICAgY2xhc3Nlcy5hcHBlbmQoY2xhc3NfaW5mbwoKICAgICAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgICAgICB3YWxrKGNoaWxkKQoKICAgICAgICB3YWxrKHBhcnNlX3Jlc3VsdC5hc3QpCgogICAgICAgIHJldHVybiBjbGFzc2VzCgogICAgZGVmIHBfcGFyc2Vqc192YXJjbGFzcyhzZWxmLCBub2RlOiB0cmVlX3NpdHRlci5Ob2RlKSAtPiBDbGFzc0luZm8gfCBOb25lOAoKICAgICAgICAiUGFyayBhIEphdmFTY3JpcHQgY2xhc3MgZGVmaW5pdGlvbiBub2RlLiIKCiAgICAgICAgY2xhc3NfaW5mbyA9IENsYXNzSW5mbygKICAgICAgICAgICAgbmFtZT0iIiwKICAgICAgICAgICAgc3RhcnRfbGluZT1ub2RlLnN0YXJ0X3BvaW50WzBdICsgMSwKICAgICAgICAgICAgZW5kX2xpbmU9bm9kZS5lbmRfcG9pbnRbMF0gKyAxLAogICAgICAgICAgICBkb2NzdHJpbmdOb25lLAogICAgICAgICAgICBiYXNlcz1bKSwKICAgICAgICAgICAgZGVjb3JhdG9ycz1bKSwKICAgICAgICAgICAgbWV0aG9kcz1bKSwKICAgICAgICAgICAgdmlzaWJpbGl0eT0icHVibGljIgogICAgICAgICkKCiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gIm5hbWUiOgogICAgICAgICAgICAgICAgY2xhc3NfaW5mby5uYW1lID0gY2hpbGQudGV4dC5kZWNvZGUoJ3V0Zi04JykKCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gImNsYXNzX2hlcml0YWdlIjoKCiAgICAgICAgICAgIGZvciBiYXNlIGluIGNoaWxkLmNoaWxkcmVuOgogICAgICAgICAgICAgICAgaWYgYmFzZS50eXBlID09ICJpZGVudGlmaWVyIjoKCiAgICAgICAgICAgICAgICAgICAgY2xhc3NfaW5mby5iYXNlcy5hcHBlbmQoYmFzZS50ZXh0LmRlY29kZSgndXRmLTgnKSkKCiAgICAgICAgcmV0dXJuIGNsYXNzX2luZm8gaWYgY2xhc3NfaW5mby5uYW1lIGVsc2UgTm9uZQoKICAgIGRlZiBfZXh0cmFjdF9nb19mdW5jdGlvbnMoc2VsZiwgcGFyc2VfcmVzdWx0OiBQYXJzZVJlc3VsdCkgLT4gbGlzdFtGdW5jdGlvbkluZm9dOAoKICAgICAgICAiRXh0cmFjdCBHbyBmdW5jdGlvbiBkZWZpbml0aW9ucy4iCgogICAgICAgIGZ1bmN0aW9uczogbGlzdFtGdW5jdGlvbkluZm9dID0gWwoKICAgICAgICBkZWYgd2Fsayhub2RlOiB0cmVlX3NpdHRlci5Ob2RlKToKCiAgICAgICAgICAgIGlmIG5vZGUudHlwZSA9PSAiZnVuY3Rpb25fZGVjbGFyYXRpb24iOgogICAgICAgICAgICAgICAgZnVuY19pbmZvID0gc2VsZi5fcGFyc2VfZ29fZnVuY3Rpb24obm9kZSkKCiAgICAgICAgICAgICAgICBpZiBmdW5jX2luZm86CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25zLmFwcGVuZChmdW5jX2luZm8pCgogICAgICAgICAgICBmb3IgY2hpbGQgaW4gbm9kZS5jaGlsZHJlbjoKICAgICAgICAgICAgICAgIHdhbGsoY2hpbGQpCgogICAgICAgIHdhbGwo cGFyc2VfcmVzdWx0LmFzdCkKCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9ucwoKICAgIGRlZiBwX3BhcnNlX2dvX2Z1bmN0aW9uKHNlbGYsIG5vZGU6IHRyZWVfc2l0dGVyLk5vZGUpIC0+IEZ1bmN0aW9uSW5mbyB8IE5vbmU6CgogICAgICAgICJQYXJrIGEgR28gZnVuY3Rpb24gZGVmaW5pdGlvbiBub2RlLiIKCiAgICAgICAgZnVuY19pbmZvID0gRnVuY3Rpb25JbmZvKAogICAgICAgICAgICBuYW1lPSIiLAogICAgICAgICAgICBub2RlX3R5cGU9ImZ1bmN0aW9uIiwKICAgICAgICAgICAgc3RhcnRfbGluZT1ub2RlLnN0YXJ0X3BvaW50WzBdICsgMSwKICAgICAgICAgICAgZW5kX2xpbmU9bm9kZS5lbmRfcG9pbnRbMF0gKyAxLAogICAgICAgICAgICBwYXJhbWV0ZXJzPVtdLAogICAgICAgICAgICByZXR1cm5fdHlwZT1Ob25lLAogICAgICAgICAgICBkb2NzdHJpbmdOb25lLAogICAgICAgICAgICBkZWNvcmF0b3JzPVtdLAogICAgICAgICAgICBpc19hc3luYz1GYWxzZSwKICAgICAgICAgICAgdmlzaWJpbGl0eT0icHVibGljIgogICAgICAgICkKCiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gImlkZW50aWZpZXIiOgogICAgICAgICAgICAgICAgZnVuY19pbmZvLm5hbWUgPSBjaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKQoKICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gInR5cGVfcGFyYW1ldGVycyIgb3IgY2hpbGQudHlwZSA9PSAicGFyYW1ldGVyX2xpc3QiOgogICAgICAgICAgICBmdW5jX2luZm8ucGFyYW1ldGVycyA9IHNlbGYuX3BhcnNlX2dvX3BhcmFtZXRlcnMoY2hpbGQpCgogICAgICAgIGVsaWYgY2hpbGQudHlwZSA9PSAidHlwZV8iOgogICAgICAgICAgICBmdW5jX2luZm8ucmV0dXJfdHlwZSA9IGNoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCgoKICAgICAgICByZXR1cm4gZnVuY19pbmZvIGlmIGZ1bmNfaW5mby5uYW1lIGVsc2UgTm9uZQoKCiAgICBkZWYgcF9wYXJzZV9nb19wYXJhbWV0ZXJzKHNlbGYsIG5vZGU6IHRyZWVfc2l0dGVyLk5vZGUpIC0+IGxpc3RbZGljdFtzdHIsIHN0cl1dOAoKICAgICAgICAiUGFyayBHbyBmdW5jdGlvbiBwYXJhbWV0ZXJzLiIKCiAgICAgICAgcGFyYW1zID0gWwoKICAgICAgICBmb3IgY2hpbGQgaW4gbm9kZS5jaGlsZHJlbjoKCiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gInBhcmFtZXRlcl9kZWNsYXJhdGlvbiI6CgogICAgICAgICAgICAgICAgcGFyYW1faW5mbzogZGljdFtzdHIsIHN0cl0gPSAi bmFtZSI6IiIKCiAgICAgICAgICAgICAgICBmb3IgcGFyYW1fY2hpbGQgaW4gY2hpbGQuY2hpbGRyZW46CiAgICAgICAgICAgICAgICAgICAgaWYgcGFyYW1fY2hpbGQudHlwZSA9PSAiaWRlbnRpZmllciI6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtX2luZm9bIm5hbWUiXSA9IHBhcmFtX2NoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBwYXJhbV9jaGlsZC50eXBlID09ICJ0eXBlX2lkZW50aWZpZXIiIG9yIHBhcmFtX2NoaWxkLnR5cGUgPT0gInByaW1pdGl2ZV90eXBlIjoKCiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtX2luZm9bInR5cGUiXSA9IHBhcmFtX2NoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCgoKICAgICAgICAgICAgICAgIGlmIHBhcmFtX2luZm8uZ2V0KCJuYW1lIik6CiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChwYXJhbV9pbmZvKQoKICAgICAgICByZXR1cm4gcGFyYW1zCgogICAgZGVmIF9leHRyYWN0X3J1c3RfZnVuY3Rpb25zKHNlbGYsIHBhcnNlX3Jlc3VsdDogUGFyc2VSZXN1bHQpIC0+IGxpc3RbRnVuY3Rpb25JbmZvXToKCiAgICAgICAgIkV4dHJhcnQgUnVzdCBmdW5jdGlvbiBkZWZpbml0aW9ucy4iCgogICAgICAgIGZ1bmN0aW9uczogbGlzdFtGdW5jdGlvbkluZm9dID0gWwoKICAgICAgICBkZWYgd2Fsayhub2RlOiB0cmVlX3NpdHRlci5Ob2RlKToKCiAgICAgICAgICAgIGlmIG5vZGUudHlwZSBpbiAoImZ1bmN0aW9uX2l0ZW0iLCAiZnVuY3Rpb25fZGVjbGFyYXRpb24iKToKCiAgICAgICAgICAgICAgICBmdW5jX2luZm8gPSBzZWxmLl9wYXJzZV9ydXN0X2Z1bmN0aW9uKG5vZGUpCgogICAgICAgICAgICAgICAgaWYgZnVuY19pbmZvOgogICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9ucy5hcHBlbmQoZnVuY19pbmZvKQoKCiAgICAgICAgICAgIGZvciBjaGlsZCBpbiBub2RlLmNoaWxkcmVuOgogICAgICAgICAgICAgICAgd2FsayhjaGlsZCkKCiAgICAgICAgd2FsayhwYXJzZV9yZXN1bHQuYXN0KQoKICAgICAgICByZXR1cm4gZnVuY3Rpb25zCgogICAgZGVmIHBfcGFyc2VydXN0X2Z1bmN0aW9uKHNlbGYsIG5vZGU6IHRyZWVfc2l0dGVyLk5vZGUpIC0+IEZ1bmN0aW9uSW5mbyB8IE5vbmU6CgogICAgICAgICJQYXJrIGEgUnVzdCBmdW5jdGlvbiBkZWZpbml0aW9uIG5vZGUuIgogICAgICAgIGZ1bmNfaW5mbyA9IEZ1bmN0aW9uSW5mbygKICAgICAgICAgICAgbmFtZT0iIiwKICAgICAgICAgICAgbm9kZV90eXBlPSJmdW5jdGlvbiIsCiAgICAgICAgICAgIHN0YXJ0X2xpbmU9bm9kZS5zdGFydF9wb2ludFswXSArIDEsCiAgICAgICAgICAgIGVuZF9saW5lPW5vZGUuZW5kX3BvaW50WzBdICsgMSwKICAgICAgICAgICAgcGFyYW1ldGVycz1bKSwKICAgICAgICAgICAgcmV0dXJfdHlwZT1Ob25lLAogICAgICAgICAgICBkb2NzdHJpbmdOb25lLAogICAgICAgICAgICBkZWNvcmF0b3JzPVtdLAogICAgICAgICAgICBpc19hc3luYz1GYWxzZSwKICAgICAgICAgICAgdmlzaWJpbGl0eT0icHVibGljIgogICAgICAgICkKCiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gImlkZW50aWZpZXIiOgogICAgICAgICAgICAgICAgZnVuY19pbmZvLm5hbWUgPSBjaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKQoKICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gInBhcmFtZXRlcnMiOgogICAgICAgICAgICBmdW5jX2luZm8ucGFyYW1ldGVycyA9IHNlbGYuX3BhcnNlcnVzdF9wYXJhbWV0ZXJzKGNoaWxkKQoKICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gInJldHVybl90eXBlIjoKCiAgICAgICAgICAgIGZ1bmNfaW5mby5yZXR1cm5fdHlwZSA9IGNoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCgoKICAgICAgICByZXR1cm4gZnVuY19pbmZvIGlmIGZ1bmNfaW5mby5uYW1lIGVsc2UgTm9uZQoKCiAgICBkZWYgcF9wYXJzZXJ1c3RfcGFyYW1ldGVycyhzZWxmLCBub2RlOiB0cmVlX3NpdHRlci5Ob2RlKSAtPiBsaXN0W2RpY3Rbc3RyLCBzdHJdXToKCiAgICAgICAgIlBhcmsgUnVzdCBmdW5jdGlvbiBwYXJhbWV0ZXJzLiIKCiAgICAgICAgcGFyYW1zID0gWwoKICAgICAgICBmb3IgY2hpbGQgaW4gbm9kZS5jaGlsZHJlbjoKCiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gInBhcmFtZXRlciI6CgogICAgICAgICAgICAgICAgcGFyYW1faW5mbzogZGljdFtzdHIsIHN0cl0gPSAi bmFtZSI6IiIKCiAgICAgICAgICAgICAgICBmb3IgcGFyYW1fY2hpbGQgaW4gY2hpbGQuY2hpbGRyZW46CiAgICAgICAgICAgICAgICAgICAgaWYgcGFyYW1fY2hpbGQudHlwZSA9PSAiaWRlbnRpZmllciI6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtX2luZm9bIm5hbWUiXSA9IHBhcmFtX2NoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBwYXJhbV9jaGlsZC50eXBlIGluICgidHlwZV9pZGVudGlmaWVyIiwgInByaW1pdGl2ZV90eXBlIik6CgogICAgICAgICAgICAgICAgICAgICAgICBwYXJhbV9pbmZvWyJ0eXBlIl0gPSBwYXJhbV9jaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKQoKCiAgICAgICAgICAgICAgICBpZiBwYXJhbV9pbmZvLmdldCgibmFtZSIpOgogICAgICAgICAgICAgICAgICAgIHBhcmFtcy5hcHBlbmQocGFyYW1faW5mbwoKCiAgICAgICAgcmV0dXJuIHBhcmFtcwoKCiAgICBkZWYgX2V4dHJhY3RfamF2YV9mdW5jdGlvbnMoc2VsZiwgcGFyc2VfcmVzdWx0OiBQYXJzZVJlc3VsdCkgLT4gbGlzdFtGdW5jdGlvbkluZm9dOAoKICAgICAgICAiRXh0cmFjdCBKYXZhIGZ1bmN0aW9uIGRlZmluaXRpb25zLiIKCiAgICAgICAgZnVuY3Rpb25zOiBsaXN0W0Z1bmN0aW9uSW5mb10gPSBbCgogICAgICAgIGRlZiB3YWxrKG5vZGU6IHRyZWVfc2l0dGVyLk5vZGUpOgogICAgICAgICAgICBpZiBub2RlLnR5cGUgaW4gKCJtZXRob2RfZGVjbGFyYXRpb24iLCAiY29uc3RydWN0b3JfZGVjbGFyYXRpb24iKToKCiAgICAgICAgICAgICAgICBmdW5jX2luZm8gPSBzZWxmLl9wYXJzZV9qYXZhX2Z1bmN0aW9uKG5vZGUsIG5vZGUudHlwZSkKCiAgICAgICAgICAgICAgICBpZiBmdW5jX2luZm86CiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25zLmFwcGVuZChmdW5jX2luZm8pCgogICAgICAgICAgICBmb3IgY2hpbGQgaW4gbm9kZS5jaGlsZHJlbjoKCiAgICAgICAgICAgICAgICB3YWxrKGNoaWxkKQoKICAgICAgICB3YWxrKHBhcnNlX3Jlc3VsdC5hc3QpCgogICAgICAgIHJldHVybiBmdW5jdGlvbnMKCiAgICBkZWYgcF9wYXJzZV9qYXZhX2Z1bmN0aW9uKHNlbGYsIG5vZGU6IHRyZWVfc2l0dGVyLk5vZGUsIG5vZGVfdHlwZTogc3RyKSAtPiBGdW5jdGlvbklmZm8gfCBOb25lOAoKICAgICAgICAiUGFyayBhIEphdmEgZnVuY3Rpb24gZGVmaW5pdGlvbiBub2RlLiIKCiAgICAgICAgZnVuY19pbmZvID0gRnVuY3Rpb25JbmZvKAogICAgICAgICAgICBuYW1lPSIiLAogICAgICAgICAgICBub2RlX3R5cGU9bm9kZV90eXBlLAogICAgICAgICAgICBzdGFydF9saW5lPW5vZGUuc3RhcnRfcG9pbnRbMF0gKyAxLAogICAgICAgICAgICBlbmRfbGluZT1ub2RlLmVuZF9wb2ludFswXSArIDEsCiAgICAgICAgICAgIHBhcmFtZXRlcnM9WSwKICAgICAgICAgICAgcmV0dXJfdHlwZT1Ob25lLAogICAgICAgICAgICBkb2NzdHJpbmdOb25lLAogICAgICAgICAgICBkZWNvcmF0b3JzPVtdLAogICAgICAgICAgICBpc19hc3luYz1GYWxzZSwKICAgICAgICAgICAgdmlzaWJpbGl0eT0icHVibGljIgogICAgICAgICkKCiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gImlkZW50aWZpZXIiOgogICAgICAgICAgICAgICAgZnVuY19pbmZvLm5hbWUgPSBjaGlsZC50ZXh0LmRlY29kZSgndXRmLTgnKQoKCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gImZvcm1hbF9wYXJhbWV0ZXJzIjoKCiAgICAgICAgICAgIGZ1bmNfaW5mby5wYXJhbWV0ZXJzID0gc2VsZi5fcGFyc2VqYXZhX3BhcmFtZXRlcnMoY2hpbGQpCgogICAgICAgIGVsaWYgY2hpbGQudHlwZSA9PSAidHlwZSI6CgogICAgICAgICAgICBpZiBub2RlX3R5cGUgPT0gImNvbnN0cnVjdG9yX2RlY2xhcmF0aW9uIjoKCiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgZnVuY19pbmZvLnJldHVybl90eXBlID0gY2hpbGQudGV4dC5kZWNvZGUoJ3V0Zi04JykKCiAgICAgICAgcmV0dXJuIGZ1bmNfaW5mbyBpZiBmdW5jX2luZm8ubmFtZSBlbHNlIE5vbmUKCiAgICBkZWYgcF9wYXJzZV9qYXZhX3BhcmFtZXRlcnMoc2VsZiwgbm9kZTogdHJlZV9zaXR0ZXIuTm9kZSkgLT4gbGlzdFtkZWN0W3N0ciwgX3N0cl1dOAoKICAgICAgICAiUGFyayBKYXZhIGZ1bmN0aW9uIHBhcmFtZXRlcnMuIgogICAgICAgIHBhcmFtcyA9IFtdCgogICAgICAgIGZvciBjaGlsZCBpbiBub2RlLmNoaWxkcmVuOgogICAgICAgICAgICBpZiBjaGlsZC50eXBlID09ICJmb3JtYWxfcGFyYW1ldGVyIjoKCiAgICAgICAgICAgICAgICBwYXJhbV9pbmZvOiBkaWN0W3N0ciwgX3N0cl0gPSAi bmFtZSI6IiIKCiAgICAgICAgICAgICAgICBmb3IgcGFyYW1fY2hpbGQgaW4gY2hpbGQuY2hpbGRyZW46CiAgICAgICAgICAgICAgICAgICAgaWYgcGFyYW1fY2hpbGQudHlwZSA9PSAiaWRlbnRpZmllciI6CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtX2luZm9bIm5hbWUiXSA9IHBhcmFtX2NoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCiAgICAgICAgICAgICAgICAgICAgZWxpZiBwYXJhbV9jaGlsZC50eXBlID09ICJ0eXBlIjoKCiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtX2luZm9bInR5cGUiXSA9IHBhcmFtX2NoaWxkLnRleHQuZGVjb2RlKCd1dGYtOCcpCgoKICAgICAgICAgICAgICAgIGlmIHBhcmFtX2luZm8uZ2V0KCJuYW1lIik6CiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLmFwcGVuZChwYXJhbV9pbmZvKQoKCiAgICAgICAgcmV0dXJuIHBhcmFtcwoKCiAgICBkZWYgX2V4dHJhY3RfamF2YV9jbGFzc2VzKHNlbGYsIHBhcnNlX3Jlc3VsdDogUGFyc2VSZXN1bHQpIC0+IGxpc3RbQ2xhc3NJbmZvXToKCiAgICAgICAgIkV4dHJhY3QgSmF2YSBjbGFzcyBkZWZpbml0aW9ucy4iCgogICAgICAgIGNsYXNzZXM6IGxpc3RbQ2xhc3NJbmZvXSA9IFsKCiAgICAgICAgZGVmIHdhbGsobm9kZTogdHJlZV9zaXR0ZXIuTm9kZSk6CgogICAgICAgICAgICBpZiBub2RlLnR5cGUgPT0gImNsYXNzX2RlY2xhcmF0aW9uIjoKCiAgICAgICAgICAgICAgICBjbGFzc19pbmZvID0gc2VsZi5fcGFyc2VfamF2YV9jbGFzcyhub2RlKQoKICAgICAgICAgICAgICAgIGlmIGNsYXNzX2luZm86CiAgICAgICAgICAgICAgICAgICAgY2xhc3Nlcy5hcHBlbmQoY2xhc3NfaW5mbwoKCiAgICAgICAgICAgIGZvciBjaGlsZCBpbiBub2RlLmNoaWxkcmVuOgogICAgICAgICAgICAgICAgd2FsayhjaGlsZCkKCiAgICAgICAgd2FsayhwYXJzZV9yZXN1bHQuYXN0KQoKICAgICAgICByZXR1cm4gY2xhc3NlcwoKCiAgICBkZWYgcF9wYXJzZV9qYXZhX2NsYXNzKHNlbGYsIG5vZGU6IHRyZWVfc2l0dGVyLk5vZGUpIC0+IENsYXNzSW5mbyB8IE5vbmU6CgogICAgICAgICJQYXJrIGEgSmF2YSBjbGFzcyBkZWZpbml0aW9uIG5vZGUuIgogICAgICAgIGNsYXNzX2luZm8gPSBDbGFzc0luZm8oCiAgICAgICAgICAgIG5hbWU9IiIsCiAgICAgICAgICAgIHN0YXJ0X2xpbmU9bm9kZS5zdGFydF9wb2ludFswXSArIDEsCiAgICAgICAgICAgIGVuZF9saW5lPW5vZGUuZW5kX3BvaW50WzBdICsgMSwKICAgICAgICAgICAgZG9jc3RyaW5nTm9uZSwKICAgICAgICAgICAgYmFzZXM9WSwKICAgICAgICAgICAgZGVjb3JhdG9ycz1bKSwKICAgICAgICAgICAgbWV0aG9kcz1bKSwKICAgICAgICAgICAgdmlzaWJpbGl0eT0icHVibGljIgogICAgICAgICkKCiAgICAgICAgZm9yIGNoaWxkIGluIG5vZGUuY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGNoaWxkLnR5cGUgPT0gImlkZW50aWZpZXIiOgogICAgICAgICAgICAgICAgY2xhc3NfaW5mby5uYW1lID0gY2hpbGQudGV4dC5kZWNvZGUoJ3V0Zi04JykKCiAgICAgICAgICBlbGlmIGNoaWxkLnR5cGUgPT0gInN1cGVyY2xhc3MiOgoKICAgICAgICAgICAgZm9yIGJhc2UgaW4gY2hpbGQuY2hpbGRyZW46CiAgICAgICAgICAgICAgICBpZiBiYXNlLnR5cGUgPT0gImlkZW50aWZpZXIiOgogICAgICAgICAgICAgICAgICAgIGNsYXNzX2luZm8uYmFzZXMuYXBwZW5kKGJhc2UudGV4dC5kZWNvZGUoJ3V0Zi04JykKCiAgICAgICAgcmV0dXJuIGNsYXNzX2luZm8gaWYgY2xhc3NfaW5mby5uYW1lIGVsc2UgTm9uZQo= \ No newline at end of file