IyAtKi0gY29kaW5nOiBpc28tODg1OS0xNSAtKi0KCmltcG9ydCBzeXMKaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IFN0cmluZ0lPCmZyb20gaGFzaGxpYiBpbXBvcnQgbWQ1CmltcG9ydCBlcnJubwoKaW1wb3J0IHVuaXR0ZXN0CmltcG9ydCB0YXJmaWxlCgpmcm9tIHRlc3QgaW1wb3J0IHRlc3Rfc3VwcG9ydAoKIyBDaGVjayBmb3Igb3VyIGNvbXByZXNzaW9uIG1vZHVsZXMuCnRyeToKICAgIGltcG9ydCBnemlwCiAgICBnemlwLkd6aXBGaWxlCmV4Y2VwdCAoSW1wb3J0RXJyb3IsIEF0dHJpYnV0ZUVycm9yKToKICAgIGd6aXAgPSBOb25lCnRyeToKICAgIGltcG9ydCBiejIKZXhjZXB0IEltcG9ydEVycm9yOgogICAgYnoyID0gTm9uZQoKZGVmIG1kNXN1bShkYXRhKToKICAgIHJldHVybiBtZDUoZGF0YSkuaGV4ZGlnZXN0KCkKClRFTVBESVIgPSBvcy5wYXRoLmFic3BhdGgodGVzdF9zdXBwb3J0LlRFU1RGTikKdGFybmFtZSA9IHRlc3Rfc3VwcG9ydC5maW5kZmlsZSgidGVzdHRhci50YXIiKQpnemlwbmFtZSA9IG9zLnBhdGguam9pbihURU1QRElSLCAidGVzdHRhci50YXIuZ3oiKQpiejJuYW1lID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJ0ZXN0dGFyLnRhci5iejIiKQp0bXBuYW1lID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJ0bXAudGFyIikKCm1kNV9yZWd0eXBlID0gIjY1ZjQ3N2M4MThhZDllMTVmN2ZlYWIwYzZkMzc3NDJmIgptZDVfc3BhcnNlID0gImE1NGZiYzRjYTRmNDM5OWE5MGUxYjI3MTY0MDEyZmM2IgoKCmNsYXNzIFJlYWRUZXN0KHVuaXR0ZXN0LlRlc3RDYXNlKToKCiAgICB0YXJuYW1lID0gdGFybmFtZQogICAgbW9kZSA9ICJyOiIKCiAgICBkZWYgc2V0VXAoc2VsZik6CiAgICAgICAgc2VsZi50YXIgPSB0YXJmaWxlLm9wZW4oc2VsZi50YXJuYW1lLCBtb2RlPXNlbGYubW9kZSwgZW5jb2Rpbmc9Imlzbzg4NTktMSIpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYudGFyLmNsb3NlKCkKCgpjbGFzcyBVc3RhclJlYWRUZXN0KFJlYWRUZXN0KToKCiAgICBkZWYgdGVzdF9maWxlb2JqX3JlZ3VsYXJfZmlsZShzZWxmKToKICAgICAgICB0YXJpbmZvID0gc2VsZi50YXIuZ2V0bWVtYmVyKCJ1c3Rhci9yZWd0eXBlIikKICAgICAgICBmb2JqID0gc2VsZi50YXIuZXh0cmFjdGZpbGUodGFyaW5mbykKICAgICAgICBkYXRhID0gZm9iai5yZWFkKCkKICAgICAgICBzZWxmLmFzc2VydFRydWUoKGxlbihkYXRhKSwgbWQ1c3VtKGRhdGEpKSA9PSAodGFyaW5mby5zaXplLCBtZDVfcmVndHlwZSksCiAgICAgICAgICAgICAgICAicmVndWxhciBmaWxlIGV4dHJhY3Rpb24gZmFpbGVkIikKCiAgICBkZWYgdGVzdF9maWxlb2JqX3JlYWRsaW5lcyhzZWxmKToKICAgICAgICBzZWxmLnRhci5leHRyYWN0KCJ1c3Rhci9yZWd0eXBlIiwgVEVNUERJUikKICAgICAgICB0YXJpbmZvID0gc2VsZi50YXIuZ2V0bWVtYmVyKCJ1c3Rhci9yZWd0eXBlIikKICAgICAgICBmb2JqMSA9IG9wZW4ob3MucGF0aC5qb2luKFRFTVBESVIsICJ1c3Rhci9yZWd0eXBlIiksICJyVSIpCiAgICAgICAgZm9iajIgPSBzZWxmLnRhci5leHRyYWN0ZmlsZSh0YXJpbmZvKQoKICAgICAgICBsaW5lczEgPSBmb2JqMS5yZWFkbGluZXMoKQogICAgICAgIGxpbmVzMiA9IGZvYmoyLnJlYWRsaW5lcygpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGxpbmVzMSA9PSBsaW5lczIsCiAgICAgICAgICAgICAgICAiZmlsZW9iai5yZWFkbGluZXMoKSBmYWlsZWQiKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShsZW4obGluZXMyKSA9PSAxMTQsCiAgICAgICAgICAgICAgICAiZmlsZW9iai5yZWFkbGluZXMoKSBmYWlsZWQiKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShsaW5lczJbODNdID09CiAgICAgICAgICAgICAgICAiSSB3aWxsIGdsYWRseSBhZG1pdCB0aGF0IFB5dGhvbiBpcyBub3QgdGhlIGZhc3Rlc3QgcnVubmluZyBzY3JpcHRpbmcgbGFuZ3VhZ2UuXG4iLAogICAgICAgICAgICAgICAgImZpbGVvYmoucmVhZGxpbmVzKCkgZmFpbGVkIikKCiAgICBkZWYgdGVzdF9maWxlb2JqX2l0ZXIoc2VsZik6CiAgICAgICAgc2VsZi50YXIuZXh0cmFjdCgidXN0YXIvcmVndHlwZSIsIFRFTVBESVIpCiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcigidXN0YXIvcmVndHlwZSIpCiAgICAgICAgZm9iajEgPSBvcGVuKG9zLnBhdGguam9pbihURU1QRElSLCAidXN0YXIvcmVndHlwZSIpLCAiclUiKQogICAgICAgIGZvYmoyID0gc2VsZi50YXIuZXh0cmFjdGZpbGUodGFyaW5mbykKICAgICAgICBsaW5lczEgPSBmb2JqMS5yZWFkbGluZXMoKQogICAgICAgIGxpbmVzMiA9IFtsaW5lIGZvciBsaW5lIGluIGZvYmoyXQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShsaW5lczEgPT0gbGluZXMyLAogICAgICAgICAgICAgICAgICAgICAiZmlsZW9iai5fX2l0ZXJfXygpIGZhaWxlZCIpCgogICAgZGVmIHRlc3RfZmlsZW9ial9zZWVrKHNlbGYpOgogICAgICAgIHNlbGYudGFyLmV4dHJhY3QoInVzdGFyL3JlZ3R5cGUiLCBURU1QRElSKQogICAgICAgIGZvYmogPSBvcGVuKG9zLnBhdGguam9pbihURU1QRElSLCAidXN0YXIvcmVndHlwZSIpLCAicmIiKQogICAgICAgIGRhdGEgPSBmb2JqLnJlYWQoKQogICAgICAgIGZvYmouY2xvc2UoKQoKICAgICAgICB0YXJpbmZvID0gc2VsZi50YXIuZ2V0bWVtYmVyKCJ1c3Rhci9yZWd0eXBlIikKICAgICAgICBmb2JqID0gc2VsZi50YXIuZXh0cmFjdGZpbGUodGFyaW5mbykKCiAgICAgICAgdGV4dCA9IGZvYmoucmVhZCgpCiAgICAgICAgZm9iai5zZWVrKDApCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKDAgPT0gZm9iai50ZWxsKCksCiAgICAgICAgICAgICAgICAgICAgICJzZWVrKCkgdG8gZmlsZSdzIHN0YXJ0IGZhaWxlZCIpCiAgICAgICAgZm9iai5zZWVrKDIwNDgsIDApCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKDIwNDggPT0gZm9iai50ZWxsKCksCiAgICAgICAgICAgICAgICAgICAgICJzZWVrKCkgdG8gYWJzb2x1dGUgcG9zaXRpb24gZmFpbGVkIikKICAgICAgICBmb2JqLnNlZWsoLTEwMjQsIDEpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKDEwMjQgPT0gZm9iai50ZWxsKCksCiAgICAgICAgICAgICAgICAgICAgICJzZWVrKCkgdG8gbmVnYXRpdmUgcmVsYXRpdmUgcG9zaXRpb24gZmFpbGVkIikKICAgICAgICBmb2JqLnNlZWsoMTAyNCwgMSkKICAgICAgICBzZWxmLmFzc2VydFRydWUoMjA0OCA9PSBmb2JqLnRlbGwoKSwKICAgICAgICAgICAgICAgICAgICAgInNlZWsoKSB0byBwb3NpdGl2ZSByZWxhdGl2ZSBwb3NpdGlvbiBmYWlsZWQiKQogICAgICAgIHMgPSBmb2JqLnJlYWQoMTApCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHMgPT0gZGF0YVsyMDQ4OjIwNThdLAogICAgICAgICAgICAgICAgICAgICAicmVhZCgpIGFmdGVyIHNlZWsgZmFpbGVkIikKICAgICAgICBmb2JqLnNlZWsoMCwgMikKICAgICAgICBzZWxmLmFzc2VydFRydWUodGFyaW5mby5zaXplID09IGZvYmoudGVsbCgpLAogICAgICAgICAgICAgICAgICAgICAic2VlaygpIHRvIGZpbGUncyBlbmQgZmFpbGVkIikKICAgICAgICBzZWxmLmFzc2VydFRydWUoZm9iai5yZWFkKCkgPT0gIiIsCiAgICAgICAgICAgICAgICAgICAgICJyZWFkKCkgYXQgZmlsZSdzIGVuZCBkaWQgbm90IHJldHVybiBlbXB0eSBzdHJpbmciKQogICAgICAgIGZvYmouc2VlaygtdGFyaW5mby5zaXplLCAyKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSgwID09IGZvYmoudGVsbCgpLAogICAgICAgICAgICAgICAgICAgICAicmVsYXRpdmUgc2VlaygpIHRvIGZpbGUncyBzdGFydCBmYWlsZWQiKQogICAgICAgIGZvYmouc2Vlayg1MTIpCiAgICAgICAgczEgPSBmb2JqLnJlYWRsaW5lcygpCiAgICAgICAgZm9iai5zZWVrKDUxMikKICAgICAgICBzMiA9IGZvYmoucmVhZGxpbmVzKCkKICAgICAgICBzZWxmLmFzc2VydFRydWUoczEgPT0gczIsCiAgICAgICAgICAgICAgICAgICAgICJyZWFkbGluZXMoKSBhZnRlciBzZWVrIGZhaWxlZCIpCiAgICAgICAgZm9iai5zZWVrKDApCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGxlbihmb2JqLnJlYWRsaW5lKCkpID09IGZvYmoudGVsbCgpLAogICAgICAgICAgICAgICAgICAgICAidGVsbCgpIGFmdGVyIHJlYWRsaW5lKCkgZmFpbGVkIikKICAgICAgICBmb2JqLnNlZWsoNTEyKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShsZW4oZm9iai5yZWFkbGluZSgpKSArIDUxMiA9PSBmb2JqLnRlbGwoKSwKICAgICAgICAgICAgICAgICAgICAgInRlbGwoKSBhZnRlciBzZWVrKCkgYW5kIHJlYWRsaW5lKCkgZmFpbGVkIikKICAgICAgICBmb2JqLnNlZWsoMCkKICAgICAgICBsaW5lID0gZm9iai5yZWFkbGluZSgpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKGZvYmoucmVhZCgpID09IGRhdGFbbGVuKGxpbmUpOl0sCiAgICAgICAgICAgICAgICAgICAgICJyZWFkKCkgYWZ0ZXIgcmVhZGxpbmUoKSBmYWlsZWQiKQogICAgICAgIGZvYmouY2xvc2UoKQoKICAgICMgVGVzdCBpZiBzeW1ib2xpYyBhbmQgaGFyZCBsaW5rcyBhcmUgcmVzb2x2ZWQgYnkgZXh0cmFjdGZpbGUoKS4gIFRoZQogICAgIyB0ZXN0IGxpbmsgbWVtYmVycyBlYWNoIHBvaW50IHRvIGEgcmVndWxhciBtZW1iZXIgd2hvc2UgZGF0YSBpcwogICAgIyBzdXBwb3NlZCB0byBiZSBleHBvcnRlZC4KICAgIGRlZiBfdGVzdF9maWxlb2JqX2xpbmsoc2VsZiwgbG5rdHlwZSwgcmVndHlwZSk6CiAgICAgICAgYSA9IHNlbGYudGFyLmV4dHJhY3RmaWxlKGxua3R5cGUpCiAgICAgICAgYiA9IHNlbGYudGFyLmV4dHJhY3RmaWxlKHJlZ3R5cGUpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChhLm5hbWUsIGIubmFtZSkKCiAgICBkZWYgdGVzdF9maWxlb2JqX2xpbmsxKHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3RfZmlsZW9ial9saW5rKCJ1c3Rhci9sbmt0eXBlIiwgInVzdGFyL3JlZ3R5cGUiKQoKICAgIGRlZiB0ZXN0X2ZpbGVvYmpfbGluazIoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdF9maWxlb2JqX2xpbmsoIi4vdXN0YXIvbGlua3Rlc3QyL2xua3R5cGUiLCAidXN0YXIvbGlua3Rlc3QxL3JlZ3R5cGUiKQoKICAgIGRlZiB0ZXN0X2ZpbGVvYmpfc3ltbGluazEoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdF9maWxlb2JqX2xpbmsoInVzdGFyL3N5bXR5cGUiLCAidXN0YXIvcmVndHlwZSIpCgogICAgZGVmIHRlc3RfZmlsZW9ial9zeW1saW5rMihzZWxmKToKICAgICAgICBzZWxmLl90ZXN0X2ZpbGVvYmpfbGluaygiLi91c3Rhci9saW5rdGVzdDIvc3ltdHlwZSIsICJ1c3Rhci9saW5rdGVzdDEvcmVndHlwZSIpCgogICAgZGVmIHRlc3RfaXNzdWUxNDE2MChzZWxmKToKICAgICAgICBzZWxmLl90ZXN0X2ZpbGVvYmpfbGluaygic3ltdHlwZTIiLCAidXN0YXIvcmVndHlwZSIpCgoKY2xhc3MgTGlzdFRlc3QoUmVhZFRlc3QsIHVuaXR0ZXN0LlRlc3RDYXNlKToKCiAgICAjIE92ZXJyaWRlIHNldFVwIHRvIHVzZSBkZWZhdWx0IGVuY29kaW5nIChVVEYtOCkKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLnRhciA9IHRhcmZpbGUub3BlbihzZWxmLnRhcm5hbWUsIG1vZGU9c2VsZi5tb2RlKQoKICAgIGRlZiB0ZXN0X2xpc3Qoc2VsZik6CiAgICAgICAgd2l0aCB0ZXN0X3N1cHBvcnQuY2FwdHVyZWRfc3Rkb3V0KCkgYXMgdDoKICAgICAgICAgICAgc2VsZi50YXIubGlzdCh2ZXJib3NlPUZhbHNlKQogICAgICAgIG91dCA9IHQuZ2V0dmFsdWUoKQogICAgICAgIHNlbGYuYXNzZXJ0SW4oJ3VzdGFyL2NvbnR0eXBlJywgb3V0KQogICAgICAgIHNlbGYuYXNzZXJ0SW4oJ3VzdGFyL3JlZ3R5cGUnLCBvdXQpCiAgICAgICAgc2VsZi5hc3NlcnRJbigndXN0YXIvbG5rdHlwZScsIG91dCkKICAgICAgICBzZWxmLmFzc2VydEluKCd1c3RhcicgKyAoJy8xMjM0NScgKiA0MCkgKyAnNjcvbG9uZ25hbWUnLCBvdXQpCiAgICAgICAgc2VsZi5hc3NlcnRJbignLi91c3Rhci9saW5rdGVzdDIvc3ltdHlwZScsIG91dCkKICAgICAgICBzZWxmLmFzc2VydEluKCcuL3VzdGFyL2xpbmt0ZXN0Mi9sbmt0eXBlJywgb3V0KQogICAgICAgICMgTWFrZSBzdXJlIGl0IHB1dHMgdHJhaWxpbmcgc2xhc2ggZm9yIGRpcmVjdG9yeQogICAgICAgIHNlbGYuYXNzZXJ0SW4oJ3VzdGFyL2RpcnR5cGUvJywgb3V0KQogICAgICAgIHNlbGYuYXNzZXJ0SW4oJ3VzdGFyL2RpcnR5cGUtd2l0aC1zaXplLycsIG91dCkKICAgICAgICAjIE1ha2Ugc3VyZSBpdCBpcyBhYmxlIHRvIHByaW50IG5vbi1BU0NJSSBjaGFyYWN0ZXJzCiAgICAgICAgc2VsZi5hc3NlcnRJbigndXN0YXIvdW1sYXV0cy0nCiAgICAgICAgICAgICAgICAgICAgICAnXHhjNFx4ZDZceGRjXHhlNFx4ZjZceGZjXHhkZicsIG91dCkKICAgICAgICBzZWxmLmFzc2VydEluKCdtaXNjL3JlZ3R5cGUtaHB1eC1zaWduZWQtY2hrc3VtLScKICAgICAgICAgICAgICAgICAgICAgICdceGM0XHhkNlx4ZGNceGU0XHhmNlx4ZmNceGRmJywgb3V0KQogICAgICAgIHNlbGYuYXNzZXJ0SW4oJ21pc2MvcmVndHlwZS1vbGQtdjctc2lnbmVkLWNoa3N1bS0nCiAgICAgICAgICAgICAgICAgICAgICAnXHhjNFx4ZDZceGRjXHhlNFx4ZjZceGZjXHhkZicsIG91dCkKICAgICAgICAjIE1ha2Ugc3VyZSBpdCBwcmludHMgZmlsZXMgc2VwYXJhdGVkIGJ5IG9uZSBuZXdsaW5lIHdpdGhvdXQgYW55CiAgICAgICAgIyAnbHMgLWwnLWxpa2UgYWNjZXNzb3JpZXMgaWYgdmVyYm9zZSBmbGFnIGlzIG5vdCBiZWluZyB1c2VkCiAgICAgICAgIyAuLi4KICAgICAgICAjIHVzdGFyL2NvbnR0eXBlCiAgICAgICAgIyB1c3Rhci9yZWd0eXBlCiAgICAgICAgIyAuLi4KICAgICAgICBzZWxmLmFzc2VydFJlZ2V4cE1hdGNoZXMob3V0LCByJ3VzdGFyL2NvbnR0eXBlID9ccj9cbicKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJ3VzdGFyL3JlZ3R5cGUgP1xyP1xuJykKICAgICAgICAjIE1ha2Ugc3VyZSBpdCBkb2VzIG5vdCBwcmludCB0aGUgc291cmNlIG9mIGxpbmsgd2l0aG91dCB2ZXJib3NlIGZsYWcKICAgICAgICBzZWxmLmFzc2VydE5vdEluKCdsaW5rIHRvJywgb3V0KQogICAgICAgIHNlbGYuYXNzZXJ0Tm90SW4oJy0+Jywgb3V0KQoKICAgIGRlZiB0ZXN0X2xpc3RfdmVyYm9zZShzZWxmKToKICAgICAgICB3aXRoIHRlc3Rfc3VwcG9ydC5jYXB0dXJlZF9zdGRvdXQoKSBhcyB0OgogICAgICAgICAgICBzZWxmLnRhci5saXN0KHZlcmJvc2U9VHJ1ZSkKICAgICAgICBvdXQgPSB0LmdldHZhbHVlKCkKICAgICAgICAjIE1ha2Ugc3VyZSBpdCBwcmludHMgZmlsZXMgc2VwYXJhdGVkIGJ5IG9uZSBuZXdsaW5lIHdpdGggJ2xzIC1sJy1saWtlCiAgICAgICAgIyBhY2Nlc3NvcmllcyBpZiB2ZXJib3NlIGZsYWcgaXMgYmVpbmcgdXNlZAogICAgICAgICMgLi4uCiAgICAgICAgIyA/cnctci0tci0tIHRhcmZpbGUvdGFyZmlsZSAgICAgNzAxMSAyMDAzLTAxLTA2IDA3OjE5OjQzIHVzdGFyL2NvbnR0eXBlCiAgICAgICAgIyA/cnctci0tci0tIHRhcmZpbGUvdGFyZmlsZSAgICAgNzAxMSAyMDAzLTAxLTA2IDA3OjE5OjQzIHVzdGFyL3JlZ3R5cGUKICAgICAgICAjIC4uLgogICAgICAgIHNlbGYuYXNzZXJ0UmVnZXhwTWF0Y2hlcyhvdXQsIChyJy1ydy1yLS1yLS0gdGFyZmlsZS90YXJmaWxlXHMrNzAxMSAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHInXGR7NH0tXGRcZC1cZFxkXHMrXGRcZDpcZFxkOlxkXGQgJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJ3VzdGFyL1x3K3R5cGUgP1xyP1xuJykgKiAyKQogICAgICAgICMgTWFrZSBzdXJlIGl0IHByaW50cyB0aGUgc291cmNlIG9mIGxpbmsgd2l0aCB2ZXJib3NlIGZsYWcKICAgICAgICBzZWxmLmFzc2VydEluKCd1c3Rhci9zeW10eXBlIC0+IHJlZ3R5cGUnLCBvdXQpCiAgICAgICAgc2VsZi5hc3NlcnRJbignLi91c3Rhci9saW5rdGVzdDIvc3ltdHlwZSAtPiAuLi9saW5rdGVzdDEvcmVndHlwZScsIG91dCkKICAgICAgICBzZWxmLmFzc2VydEluKCcuL3VzdGFyL2xpbmt0ZXN0Mi9sbmt0eXBlIGxpbmsgdG8gJwogICAgICAgICAgICAgICAgICAgICAgJy4vdXN0YXIvbGlua3Rlc3QxL3JlZ3R5cGUnLCBvdXQpCiAgICAgICAgc2VsZi5hc3NlcnRJbignZ251JyArICgnLzEyMycgKiAxMjUpICsgJy9sb25nbGluayBsaW5rIHRvIGdudScgKwogICAgICAgICAgICAgICAgICAgICAgKCcvMTIzJyAqIDEyNSkgKyAnL2xvbmduYW1lJywgb3V0KQogICAgICAgIHNlbGYuYXNzZXJ0SW4oJ3BheCcgKyAoJy8xMjMnICogMTI1KSArICcvbG9uZ2xpbmsgbGluayB0byBwYXgnICsKICAgICAgICAgICAgICAgICAgICAgICgnLzEyMycgKiAxMjUpICsgJy9sb25nbmFtZScsIG91dCkKCgpjbGFzcyBHemlwTGlzdFRlc3QoTGlzdFRlc3QpOgogICAgdGFybmFtZSA9IGd6aXBuYW1lCiAgICBtb2RlID0gInI6Z3oiCiAgICB0YXJvcGVuID0gdGFyZmlsZS5UYXJGaWxlLmd6b3BlbgoKCmNsYXNzIEJ6Mkxpc3RUZXN0KExpc3RUZXN0KToKICAgIHRhcm5hbWUgPSBiejJuYW1lCiAgICBtb2RlID0gInI6YnoyIgogICAgdGFyb3BlbiA9IHRhcmZpbGUuVGFyRmlsZS5iejJvcGVuCgoKY2xhc3MgQ29tbW9uUmVhZFRlc3QoUmVhZFRlc3QpOgoKICAgIGRlZiB0ZXN0X2VtcHR5X3RhcmZpbGUoc2VsZik6CiAgICAgICAgIyBUZXN0IGZvciBpc3N1ZTYxMjM6IEFsbG93IG9wZW5pbmcgZW1wdHkgYXJjaGl2ZXMuCiAgICAgICAgIyBUaGlzIHRlc3QgY2hlY2tzIGlmIHRhcmZpbGUub3BlbigpIGlzIGFibGUgdG8gb3BlbiBhbiBlbXB0eSB0YXIKICAgICAgICAjIGFyY2hpdmUgc3VjY2Vzc2Z1bGx5LiBOb3RlIHRoYXQgYW4gZW1wdHkgdGFyIGFyY2hpdmUgaXMgbm90IHRoZQogICAgICAgICMgc2FtZSBhcyBhbiBlbXB0eSBmaWxlIQogICAgICAgIHRhcmZpbGUub3Blbih0bXBuYW1lLCBzZWxmLm1vZGUucmVwbGFjZSgiciIsICJ3IikpLmNsb3NlKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgICAgIHRhci5nZXRuYW1lcygpCiAgICAgICAgZXhjZXB0IHRhcmZpbGUuUmVhZEVycm9yOgogICAgICAgICAgICBzZWxmLmZhaWwoInRhcmZpbGUub3BlbigpIGZhaWxlZCBvbiBlbXB0eSBhcmNoaXZlIikKICAgICAgICBzZWxmLmFzc2VydExpc3RFcXVhbCh0YXIuZ2V0bWVtYmVycygpLCBbXSkKCiAgICBkZWYgdGVzdF9udWxsX3RhcmZpbGUoc2VsZik6CiAgICAgICAgIyBUZXN0IGZvciBpc3N1ZTYxMjM6IEFsbG93IG9wZW5pbmcgZW1wdHkgYXJjaGl2ZXMuCiAgICAgICAgIyBUaGlzIHRlc3QgZ3VhcmFudGVlcyB0aGF0IHRhcmZpbGUub3BlbigpIGRvZXMgbm90IHRyZWF0IGFuIGVtcHR5CiAgICAgICAgIyBmaWxlIGFzIGFuIGVtcHR5IHRhciBhcmNoaXZlLgogICAgICAgIG9wZW4odG1wbmFtZSwgIndiIikuY2xvc2UoKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRhcmZpbGUuUmVhZEVycm9yLCB0YXJmaWxlLm9wZW4sIHRtcG5hbWUsIHNlbGYubW9kZSkKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyh0YXJmaWxlLlJlYWRFcnJvciwgdGFyZmlsZS5vcGVuLCB0bXBuYW1lKQoKICAgIGRlZiB0ZXN0X25vbl9leGlzdGVudF90YXJmaWxlKHNlbGYpOgogICAgICAgICMgVGVzdCBmb3IgaXNzdWUxMTUxMzogcHJldmVudCBub24tZXhpc3RlbnQgZ3ppcHBlZCB0YXJmaWxlcyByYWlzaW5nCiAgICAgICAgIyBtdWx0aXBsZSBleGNlcHRpb25zLgogICAgICAgIGV4Y3R5cGUgPSBPU0Vycm9yIGlmICd8JyBpbiBzZWxmLm1vZGUgZWxzZSBJT0Vycm9yCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4cChleGN0eXBlLCAieHh4IikgYXMgZXg6CiAgICAgICAgICAgIHRhcmZpbGUub3BlbigieHh4Iiwgc2VsZi5tb2RlKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoZXguZXhjZXB0aW9uLmVycm5vLCBlcnJuby5FTk9FTlQpCgogICAgZGVmIHRlc3RfaWdub3JlX3plcm9zKHNlbGYpOgogICAgICAgICMgVGVzdCBUYXJGaWxlJ3MgaWdub3JlX3plcm9zIG9wdGlvbi4KICAgICAgICBpZiBzZWxmLm1vZGUuZW5kc3dpdGgoIjpneiIpOgogICAgICAgICAgICBfb3BlbiA9IGd6aXAuR3ppcEZpbGUKICAgICAgICBlbGlmIHNlbGYubW9kZS5lbmRzd2l0aCgiOmJ6MiIpOgogICAgICAgICAgICBfb3BlbiA9IGJ6Mi5CWjJGaWxlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgX29wZW4gPSBvcGVuCgogICAgICAgIGZvciBjaGFyIGluICgnXDAnLCAnYScpOgogICAgICAgICAgICAjIFRlc3QgaWYgRU9GSGVhZGVyRXJyb3IgKCdcMCcpIGFuZCBJbnZhbGlkSGVhZGVyRXJyb3IgKCdhJykKICAgICAgICAgICAgIyBhcmUgaWdub3JlZCBjb3JyZWN0bHkuCiAgICAgICAgICAgIGZvYmogPSBfb3Blbih0bXBuYW1lLCAid2IiKQogICAgICAgICAgICBmb2JqLndyaXRlKGNoYXIgKiAxMDI0KQogICAgICAgICAgICBmb2JqLndyaXRlKHRhcmZpbGUuVGFySW5mbygiZm9vIikudG9idWYoKSkKICAgICAgICAgICAgZm9iai5jbG9zZSgpCgogICAgICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odG1wbmFtZSwgbW9kZT0iciIsIGlnbm9yZV96ZXJvcz1UcnVlKQogICAgICAgICAgICBzZWxmLmFzc2VydExpc3RFcXVhbCh0YXIuZ2V0bmFtZXMoKSwgWyJmb28iXSwKICAgICAgICAgICAgICAgICAgICAiaWdub3JlX3plcm9zPVRydWUgc2hvdWxkIGhhdmUgc2tpcHBlZCB0aGUgJXItYmxvY2tzIiAlIGNoYXIpCiAgICAgICAgICAgIHRhci5jbG9zZSgpCgoKY2xhc3MgTWlzY1JlYWRUZXN0KENvbW1vblJlYWRUZXN0KToKICAgIHRhcm9wZW4gPSB0YXJmaWxlLlRhckZpbGUudGFyb3BlbgoKICAgIGRlZiB0ZXN0X25vX25hbWVfYXJndW1lbnQoc2VsZik6CiAgICAgICAgZm9iaiA9IG9wZW4oc2VsZi50YXJuYW1lLCAicmIiKQogICAgICAgIHRhciA9IHRhcmZpbGUub3BlbihmaWxlb2JqPWZvYmosIG1vZGU9c2VsZi5tb2RlKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyLm5hbWUsIG9zLnBhdGguYWJzcGF0aChmb2JqLm5hbWUpKQoKICAgIGRlZiB0ZXN0X25vX25hbWVfYXR0cmlidXRlKHNlbGYpOgogICAgICAgIGRhdGEgPSBvcGVuKHNlbGYudGFybmFtZSwgInJiIikucmVhZCgpCiAgICAgICAgZm9iaiA9IFN0cmluZ0lPLlN0cmluZ0lPKGRhdGEpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoQXR0cmlidXRlRXJyb3IsIGdldGF0dHIsIGZvYmosICJuYW1lIikKICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4oZmlsZW9iaj1mb2JqLCBtb2RlPXNlbGYubW9kZSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhci5uYW1lLCBOb25lKQoKICAgIGRlZiB0ZXN0X2VtcHR5X25hbWVfYXR0cmlidXRlKHNlbGYpOgogICAgICAgIGRhdGEgPSBvcGVuKHNlbGYudGFybmFtZSwgInJiIikucmVhZCgpCiAgICAgICAgZm9iaiA9IFN0cmluZ0lPLlN0cmluZ0lPKGRhdGEpCiAgICAgICAgZm9iai5uYW1lID0gIiIKICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4oZmlsZW9iaj1mb2JqLCBtb2RlPXNlbGYubW9kZSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhci5uYW1lLCBOb25lKQoKICAgIGRlZiB0ZXN0X2lsbGVnYWxfbW9kZV9hcmcoc2VsZik6CiAgICAgICAgd2l0aCBvcGVuKHRtcG5hbWUsICd3YicpOgogICAgICAgICAgICBwYXNzCiAgICAgICAgc2VsZi5hZGRDbGVhbnVwKG9zLnVubGluaywgdG1wbmFtZSkKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzUmVnZXhwKFZhbHVlRXJyb3IsICdtb2RlIG11c3QgYmUgJyk6CiAgICAgICAgICAgIHRhciA9IHNlbGYudGFyb3Blbih0bXBuYW1lLCAncScpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4cChWYWx1ZUVycm9yLCAnbW9kZSBtdXN0IGJlICcpOgogICAgICAgICAgICB0YXIgPSBzZWxmLnRhcm9wZW4odG1wbmFtZSwgJ3J3JykKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzUmVnZXhwKFZhbHVlRXJyb3IsICdtb2RlIG11c3QgYmUgJyk6CiAgICAgICAgICAgIHRhciA9IHNlbGYudGFyb3Blbih0bXBuYW1lLCAnJykKCiAgICBkZWYgdGVzdF9maWxlb2JqX3dpdGhfb2Zmc2V0KHNlbGYpOgogICAgICAgICMgU2tpcCB0aGUgZmlyc3QgbWVtYmVyIGFuZCBzdG9yZSB2YWx1ZXMgZnJvbSB0aGUgc2Vjb25kIG1lbWJlcgogICAgICAgICMgb2YgdGhlIHRlc3R0YXIuCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHNlbGYudGFybmFtZSwgbW9kZT1zZWxmLm1vZGUpCiAgICAgICAgdGFyLm5leHQoKQogICAgICAgIHQgPSB0YXIubmV4dCgpCiAgICAgICAgbmFtZSA9IHQubmFtZQogICAgICAgIG9mZnNldCA9IHQub2Zmc2V0CiAgICAgICAgZGF0YSA9IHRhci5leHRyYWN0ZmlsZSh0KS5yZWFkKCkKICAgICAgICB0YXIuY2xvc2UoKQoKICAgICAgICAjIE9wZW4gdGhlIHRlc3R0YXIgYW5kIHNlZWsgdG8gdGhlIG9mZnNldCBvZiB0aGUgc2Vjb25kIG1lbWJlci4KICAgICAgICBpZiBzZWxmLm1vZGUuZW5kc3dpdGgoIjpneiIpOgogICAgICAgICAgICBfb3BlbiA9IGd6aXAuR3ppcEZpbGUKICAgICAgICBlbGlmIHNlbGYubW9kZS5lbmRzd2l0aCgiOmJ6MiIpOgogICAgICAgICAgICBfb3BlbiA9IGJ6Mi5CWjJGaWxlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgX29wZW4gPSBvcGVuCiAgICAgICAgZm9iaiA9IF9vcGVuKHNlbGYudGFybmFtZSwgInJiIikKICAgICAgICBmb2JqLnNlZWsob2Zmc2V0KQoKICAgICAgICAjIFRlc3QgaWYgdGhlIHRhcmZpbGUgc3RhcnRzIHdpdGggdGhlIHNlY29uZCBtZW1iZXIuCiAgICAgICAgdGFyID0gdGFyLm9wZW4oc2VsZi50YXJuYW1lLCBtb2RlPSJyOiIsIGZpbGVvYmo9Zm9iaikKICAgICAgICB0ID0gdGFyLm5leHQoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodC5uYW1lLCBuYW1lKQogICAgICAgICMgUmVhZCB0byB0aGUgZW5kIG9mIGZpbGVvYmogYW5kIHRlc3QgaWYgc2Vla2luZyBiYWNrIHRvIHRoZQogICAgICAgICMgYmVnaW5uaW5nIHdvcmtzLgogICAgICAgIHRhci5nZXRtZW1iZXJzKCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhci5leHRyYWN0ZmlsZSh0KS5yZWFkKCksIGRhdGEsCiAgICAgICAgICAgICAgICAic2VlayBiYWNrIGRpZCBub3Qgd29yayIpCiAgICAgICAgdGFyLmNsb3NlKCkKCiAgICBkZWYgdGVzdF9mYWlsX2NvbXAoc2VsZik6CiAgICAgICAgIyBGb3IgR3ppcCBhbmQgQnoyIFRlc3RzOiBmYWlsIHdpdGggYSBSZWFkRXJyb3Igb24gYW4gdW5jb21wcmVzc2VkIGZpbGUuCiAgICAgICAgaWYgc2VsZi5tb2RlID09ICJyOiI6CiAgICAgICAgICAgIHNlbGYuc2tpcFRlc3QoJ25lZWRzIGEgZ3ogb3IgYnoyIG1vZGUnKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRhcmZpbGUuUmVhZEVycm9yLCB0YXJmaWxlLm9wZW4sIHRhcm5hbWUsIHNlbGYubW9kZSkKICAgICAgICBmb2JqID0gb3Blbih0YXJuYW1lLCAicmIiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRhcmZpbGUuUmVhZEVycm9yLCB0YXJmaWxlLm9wZW4sIGZpbGVvYmo9Zm9iaiwgbW9kZT1zZWxmLm1vZGUpCgogICAgZGVmIHRlc3RfdjdfZGlydHlwZShzZWxmKToKICAgICAgICAjIFRlc3Qgb2xkIHN0eWxlIGRpcnR5cGUgbWVtYmVyIChidWcgIzEzMzY2MjMpOgogICAgICAgICMgT2xkIFY3IHRhcnMgY3JlYXRlIGRpcmVjdG9yeSBtZW1iZXJzIHVzaW5nIGFuIEFSRUdUWVBFCiAgICAgICAgIyBoZWFkZXIgd2l0aCBhICIvIiBhcHBlbmRlZCB0byB0aGUgZmlsZW5hbWUgZmllbGQuCiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcigibWlzYy9kaXJ0eXBlLW9sZC12NyIpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHRhcmluZm8udHlwZSA9PSB0YXJmaWxlLkRJUlRZUEUsCiAgICAgICAgICAgICAgICAidjcgZGlydHlwZSBmYWlsZWQiKQoKICAgIGRlZiB0ZXN0X3hzdGFyX3R5cGUoc2VsZik6CiAgICAgICAgIyBUaGUgeHN0YXIgZm9ybWF0IHN0b3JlcyBleHRyYSBhdGltZSBhbmQgY3RpbWUgZmllbGRzIGluc2lkZSB0aGUKICAgICAgICAjIHNwYWNlIHJlc2VydmVkIGZvciB0aGUgcHJlZml4IGZpZWxkLiBUaGUgcHJlZml4IGZpZWxkIG11c3QgYmUKICAgICAgICAjIGlnbm9yZWQgaW4gdGhpcyBjYXNlLCBvdGhlcndpc2UgaXQgd2lsbCBtZXNzIHVwIHRoZSBuYW1lLgogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi50YXIuZ2V0bWVtYmVyKCJtaXNjL3JlZ3R5cGUteHN0YXIiKQogICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgc2VsZi5mYWlsKCJmYWlsZWQgdG8gZmluZCBtaXNjL3JlZ3R5cGUteHN0YXIgKG1hbmdsZWQgcHJlZml4PykiKQoKICAgIGRlZiB0ZXN0X2NoZWNrX21lbWJlcnMoc2VsZik6CiAgICAgICAgZm9yIHRhcmluZm8gaW4gc2VsZi50YXI6CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShpbnQodGFyaW5mby5tdGltZSkgPT0gMDc2MDYxMzY2MTcsCiAgICAgICAgICAgICAgICAgICAgIndyb25nIG10aW1lIGZvciAlcyIgJSB0YXJpbmZvLm5hbWUpCiAgICAgICAgICAgIGlmIG5vdCB0YXJpbmZvLm5hbWUuc3RhcnRzd2l0aCgidXN0YXIvIik6CiAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBzZWxmLmFzc2VydFRydWUodGFyaW5mby51bmFtZSA9PSAidGFyZmlsZSIsCiAgICAgICAgICAgICAgICAgICAgIndyb25nIHVuYW1lIGZvciAlcyIgJSB0YXJpbmZvLm5hbWUpCgogICAgZGVmIHRlc3RfZmluZF9tZW1iZXJzKHNlbGYpOgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShzZWxmLnRhci5nZXRtZW1iZXJzKClbLTFdLm5hbWUgPT0gIm1pc2MvZW9mIiwKICAgICAgICAgICAgICAgICJjb3VsZCBub3QgZmluZCBhbGwgbWVtYmVycyIpCgogICAgZGVmIHRlc3RfZXh0cmFjdF9oYXJkbGluayhzZWxmKToKICAgICAgICAjIFRlc3QgaGFyZGxpbmsgZXh0cmFjdGlvbiAoZS5nLiBidWcgIzg1NzI5NykuCiAgICAgICAgd2l0aCB0YXJmaWxlLm9wZW4odGFybmFtZSwgZXJyb3JsZXZlbD0xLCBlbmNvZGluZz0iaXNvODg1OS0xIikgYXMgdGFyOgogICAgICAgICAgICB0YXIuZXh0cmFjdCgidXN0YXIvcmVndHlwZSIsIFRFTVBESVIpCiAgICAgICAgICAgIHNlbGYuYWRkQ2xlYW51cChvcy5yZW1vdmUsIG9zLnBhdGguam9pbihURU1QRElSLCAidXN0YXIvcmVndHlwZSIpKQoKICAgICAgICAgICAgdGFyLmV4dHJhY3QoInVzdGFyL2xua3R5cGUiLCBURU1QRElSKQogICAgICAgICAgICBzZWxmLmFkZENsZWFudXAob3MucmVtb3ZlLCBvcy5wYXRoLmpvaW4oVEVNUERJUiwgInVzdGFyL2xua3R5cGUiKSkKICAgICAgICAgICAgd2l0aCBvcGVuKG9zLnBhdGguam9pbihURU1QRElSLCAidXN0YXIvbG5rdHlwZSIpLCAicmIiKSBhcyBmOgogICAgICAgICAgICAgICAgZGF0YSA9IGYucmVhZCgpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobWQ1c3VtKGRhdGEpLCBtZDVfcmVndHlwZSkKCiAgICAgICAgICAgIHRhci5leHRyYWN0KCJ1c3Rhci9zeW10eXBlIiwgVEVNUERJUikKICAgICAgICAgICAgc2VsZi5hZGRDbGVhbnVwKG9zLnJlbW92ZSwgb3MucGF0aC5qb2luKFRFTVBESVIsICJ1c3Rhci9zeW10eXBlIikpCiAgICAgICAgICAgIHdpdGggb3Blbihvcy5wYXRoLmpvaW4oVEVNUERJUiwgInVzdGFyL3N5bXR5cGUiKSwgInJiIikgYXMgZjoKICAgICAgICAgICAgICAgIGRhdGEgPSBmLnJlYWQoKQogICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG1kNXN1bShkYXRhKSwgbWQ1X3JlZ3R5cGUpCgogICAgZGVmIHRlc3RfZXh0cmFjdGFsbChzZWxmKToKICAgICAgICAjIFRlc3QgaWYgZXh0cmFjdGFsbCgpIGNvcnJlY3RseSByZXN0b3JlcyBkaXJlY3RvcnkgcGVybWlzc2lvbnMKICAgICAgICAjIGFuZCB0aW1lcyAoc2VlIGlzc3VlMTczNSkuCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRhcm5hbWUsIGVuY29kaW5nPSJpc284ODU5LTEiKQogICAgICAgIGRpcmVjdG9yaWVzID0gW3QgZm9yIHQgaW4gdGFyIGlmIHQuaXNkaXIoKV0KICAgICAgICB0YXIuZXh0cmFjdGFsbChURU1QRElSLCBkaXJlY3RvcmllcykKICAgICAgICBmb3IgdGFyaW5mbyBpbiBkaXJlY3RvcmllczoKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihURU1QRElSLCB0YXJpbmZvLm5hbWUpCiAgICAgICAgICAgIGlmIHN5cy5wbGF0Zm9ybSAhPSAid2luMzIiOgogICAgICAgICAgICAgICAgIyBXaW4zMiBoYXMgbm8gc3VwcG9ydCBmb3IgZmluZSBncmFpbmVkIHBlcm1pc3Npb25zLgogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXJpbmZvLm1vZGUgJiAwNzc3LCBvcy5zdGF0KHBhdGgpLnN0X21vZGUgJiAwNzc3KQogICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8ubXRpbWUsIG9zLnBhdGguZ2V0bXRpbWUocGF0aCkpCiAgICAgICAgdGFyLmNsb3NlKCkKCiAgICBkZWYgdGVzdF9pbml0X2Nsb3NlX2ZvYmooc2VsZik6CiAgICAgICAgIyBJc3N1ZSAjNzM0MTogQ2xvc2UgdGhlIGludGVybmFsIGZpbGUgb2JqZWN0IGluIHRoZSBUYXJGaWxlCiAgICAgICAgIyBjb25zdHJ1Y3RvciBpbiBjYXNlIG9mIGFuIGVycm9yLiBGb3IgdGhlIHRlc3Qgd2UgcmVseSBvbgogICAgICAgICMgdGhlIGZhY3QgdGhhdCBvcGVuaW5nIGFuIGVtcHR5IGZpbGUgcmFpc2VzIGEgUmVhZEVycm9yLgogICAgICAgIGVtcHR5ID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJlbXB0eSIpCiAgICAgICAgb3BlbihlbXB0eSwgIndiIikud3JpdGUoIiIpCgogICAgICAgIHRyeToKICAgICAgICAgICAgdGFyID0gb2JqZWN0Ll9fbmV3X18odGFyZmlsZS5UYXJGaWxlKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXIuX19pbml0X18oZW1wdHkpCiAgICAgICAgICAgIGV4Y2VwdCB0YXJmaWxlLlJlYWRFcnJvcjoKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0YXIuZmlsZW9iai5jbG9zZWQpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLmZhaWwoIlJlYWRFcnJvciBub3QgcmFpc2VkIikKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBvcy5yZW1vdmUoZW1wdHkpCgogICAgZGVmIHRlc3RfcGFyYWxsZWxfaXRlcmF0aW9uKHNlbGYpOgogICAgICAgICMgSXNzdWUgIzE2NjAxOiBSZXN0YXJ0aW5nIGl0ZXJhdGlvbiBvdmVyIHRhcmZpbGUgY29udGludWVkCiAgICAgICAgIyBmcm9tIHdoZXJlIGl0IGxlZnQgb2ZmLgogICAgICAgIHdpdGggdGFyZmlsZS5vcGVuKHNlbGYudGFybmFtZSkgYXMgdGFyOgogICAgICAgICAgICBmb3IgbTEsIG0yIGluIHppcCh0YXIsIHRhcik6CiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG0xLm9mZnNldCwgbTIub2Zmc2V0KQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChtMS5uYW1lLCBtMi5uYW1lKQoKCmNsYXNzIFN0cmVhbVJlYWRUZXN0KENvbW1vblJlYWRUZXN0KToKCiAgICBtb2RlPSJyfCIKCiAgICBkZWYgdGVzdF9maWxlb2JqX3JlZ3VsYXJfZmlsZShzZWxmKToKICAgICAgICB0YXJpbmZvID0gc2VsZi50YXIubmV4dCgpICMgZ2V0ICJyZWd0eXBlIiAoY2FuJ3QgdXNlIGdldG1lbWJlcikKICAgICAgICBmb2JqID0gc2VsZi50YXIuZXh0cmFjdGZpbGUodGFyaW5mbykKICAgICAgICBkYXRhID0gZm9iai5yZWFkKCkKICAgICAgICBzZWxmLmFzc2VydFRydWUoKGxlbihkYXRhKSwgbWQ1c3VtKGRhdGEpKSA9PSAodGFyaW5mby5zaXplLCBtZDVfcmVndHlwZSksCiAgICAgICAgICAgICAgICAicmVndWxhciBmaWxlIGV4dHJhY3Rpb24gZmFpbGVkIikKCiAgICBkZWYgdGVzdF9wcm92b2tlX3N0cmVhbV9lcnJvcihzZWxmKToKICAgICAgICB0YXJpbmZvcyA9IHNlbGYudGFyLmdldG1lbWJlcnMoKQogICAgICAgIGYgPSBzZWxmLnRhci5leHRyYWN0ZmlsZSh0YXJpbmZvc1swXSkgIyByZWFkIHRoZSBmaXJzdCBtZW1iZXIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyh0YXJmaWxlLlN0cmVhbUVycm9yLCBmLnJlYWQpCgogICAgZGVmIHRlc3RfY29tcGFyZV9tZW1iZXJzKHNlbGYpOgogICAgICAgIHRhcjEgPSB0YXJmaWxlLm9wZW4odGFybmFtZSwgZW5jb2Rpbmc9Imlzbzg4NTktMSIpCiAgICAgICAgdGFyMiA9IHNlbGYudGFyCgogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIHQxID0gdGFyMS5uZXh0KCkKICAgICAgICAgICAgdDIgPSB0YXIyLm5leHQoKQogICAgICAgICAgICBpZiB0MSBpcyBOb25lOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHQyIGlzIG5vdCBOb25lLCAic3RyZWFtLm5leHQoKSBmYWlsZWQuIikKCiAgICAgICAgICAgIGlmIHQyLmlzbG5rKCkgb3IgdDIuaXNzeW0oKToKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRhcmZpbGUuU3RyZWFtRXJyb3IsIHRhcjIuZXh0cmFjdGZpbGUsIHQyKQogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIHYxID0gdGFyMS5leHRyYWN0ZmlsZSh0MSkKICAgICAgICAgICAgdjIgPSB0YXIyLmV4dHJhY3RmaWxlKHQyKQogICAgICAgICAgICBpZiB2MSBpcyBOb25lOgogICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHYyIGlzIG5vdCBOb25lLCAic3RyZWFtLmV4dHJhY3RmaWxlKCkgZmFpbGVkIikKICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHYxLnJlYWQoKSA9PSB2Mi5yZWFkKCksICJzdHJlYW0gZXh0cmFjdGlvbiBmYWlsZWQiKQoKICAgICAgICB0YXIxLmNsb3NlKCkKCgpjbGFzcyBEZXRlY3RSZWFkVGVzdCh1bml0dGVzdC5UZXN0Q2FzZSk6CgogICAgZGVmIF90ZXN0ZnVuY19maWxlKHNlbGYsIG5hbWUsIG1vZGUpOgogICAgICAgIHRyeToKICAgICAgICAgICAgdGFyZmlsZS5vcGVuKG5hbWUsIG1vZGUpCiAgICAgICAgZXhjZXB0IHRhcmZpbGUuUmVhZEVycm9yOgogICAgICAgICAgICBzZWxmLmZhaWwoKQoKICAgIGRlZiBfdGVzdGZ1bmNfZmlsZW9iaihzZWxmLCBuYW1lLCBtb2RlKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHRhcmZpbGUub3BlbihuYW1lLCBtb2RlLCBmaWxlb2JqPW9wZW4obmFtZSwgInJiIikpCiAgICAgICAgZXhjZXB0IHRhcmZpbGUuUmVhZEVycm9yOgogICAgICAgICAgICBzZWxmLmZhaWwoKQoKICAgIGRlZiBfdGVzdF9tb2RlcyhzZWxmLCB0ZXN0ZnVuYyk6CiAgICAgICAgdGVzdGZ1bmModGFybmFtZSwgInIiKQogICAgICAgIHRlc3RmdW5jKHRhcm5hbWUsICJyOiIpCiAgICAgICAgdGVzdGZ1bmModGFybmFtZSwgInI6KiIpCiAgICAgICAgdGVzdGZ1bmModGFybmFtZSwgInJ8IikKICAgICAgICB0ZXN0ZnVuYyh0YXJuYW1lLCAicnwqIikKCiAgICAgICAgaWYgZ3ppcDoKICAgICAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXModGFyZmlsZS5SZWFkRXJyb3IsIHRhcmZpbGUub3BlbiwgdGFybmFtZSwgbW9kZT0icjpneiIpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRhcmZpbGUuUmVhZEVycm9yLCB0YXJmaWxlLm9wZW4sIHRhcm5hbWUsIG1vZGU9InJ8Z3oiKQogICAgICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyh0YXJmaWxlLlJlYWRFcnJvciwgdGFyZmlsZS5vcGVuLCBnemlwbmFtZSwgbW9kZT0icjoiKQogICAgICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyh0YXJmaWxlLlJlYWRFcnJvciwgdGFyZmlsZS5vcGVuLCBnemlwbmFtZSwgbW9kZT0icnwiKQoKICAgICAgICAgICAgdGVzdGZ1bmMoZ3ppcG5hbWUsICJyIikKICAgICAgICAgICAgdGVzdGZ1bmMoZ3ppcG5hbWUsICJyOioiKQogICAgICAgICAgICB0ZXN0ZnVuYyhnemlwbmFtZSwgInI6Z3oiKQogICAgICAgICAgICB0ZXN0ZnVuYyhnemlwbmFtZSwgInJ8KiIpCiAgICAgICAgICAgIHRlc3RmdW5jKGd6aXBuYW1lLCAicnxneiIpCgogICAgICAgIGlmIGJ6MjoKICAgICAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXModGFyZmlsZS5SZWFkRXJyb3IsIHRhcmZpbGUub3BlbiwgdGFybmFtZSwgbW9kZT0icjpiejIiKQogICAgICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyh0YXJmaWxlLlJlYWRFcnJvciwgdGFyZmlsZS5vcGVuLCB0YXJuYW1lLCBtb2RlPSJyfGJ6MiIpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRhcmZpbGUuUmVhZEVycm9yLCB0YXJmaWxlLm9wZW4sIGJ6Mm5hbWUsIG1vZGU9InI6IikKICAgICAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXModGFyZmlsZS5SZWFkRXJyb3IsIHRhcmZpbGUub3BlbiwgYnoybmFtZSwgbW9kZT0icnwiKQoKICAgICAgICAgICAgdGVzdGZ1bmMoYnoybmFtZSwgInIiKQogICAgICAgICAgICB0ZXN0ZnVuYyhiejJuYW1lLCAicjoqIikKICAgICAgICAgICAgdGVzdGZ1bmMoYnoybmFtZSwgInI6YnoyIikKICAgICAgICAgICAgdGVzdGZ1bmMoYnoybmFtZSwgInJ8KiIpCiAgICAgICAgICAgIHRlc3RmdW5jKGJ6Mm5hbWUsICJyfGJ6MiIpCgogICAgZGVmIHRlc3RfZGV0ZWN0X2ZpbGUoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdF9tb2RlcyhzZWxmLl90ZXN0ZnVuY19maWxlKQoKICAgIGRlZiB0ZXN0X2RldGVjdF9maWxlb2JqKHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3RfbW9kZXMoc2VsZi5fdGVzdGZ1bmNfZmlsZW9iaikKCiAgICBAdW5pdHRlc3Quc2tpcFVubGVzcyhiejIsICdyZXF1aXJlcyBiejInKQogICAgZGVmIHRlc3RfZGV0ZWN0X3N0cmVhbV9iejIoc2VsZik6CiAgICAgICAgIyBPcmlnaW5hbGx5LCB0YXJmaWxlJ3Mgc3RyZWFtIGRldGVjdGlvbiBsb29rZWQgZm9yIHRoZSBzdHJpbmcKICAgICAgICAjICJCWmg5MSIgYXQgdGhlIHN0YXJ0IG9mIHRoZSBmaWxlLiBUaGlzIGlzIGluY29ycmVjdCBiZWNhdXNlCiAgICAgICAgIyB0aGUgJzknIHJlcHJlc2VudHMgdGhlIGJsb2Nrc2l6ZSAoOTAwa0IpLiBJZiB0aGUgZmlsZSB3YXMKICAgICAgICAjIGNvbXByZXNzZWQgdXNpbmcgYW5vdGhlciBibG9ja3NpemUgYXV0b2RldGVjdGlvbiBmYWlscy4KICAgICAgICB3aXRoIG9wZW4odGFybmFtZSwgInJiIikgYXMgZm9iajoKICAgICAgICAgICAgZGF0YSA9IGZvYmoucmVhZCgpCgogICAgICAgICMgQ29tcHJlc3Mgd2l0aCBibG9ja3NpemUgMTAwa0IsIHRoZSBmaWxlIHN0YXJ0cyB3aXRoICJCWmgxMSIuCiAgICAgICAgd2l0aCBiejIuQloyRmlsZSh0bXBuYW1lLCAid2IiLCBjb21wcmVzc2xldmVsPTEpIGFzIGZvYmo6CiAgICAgICAgICAgIGZvYmoud3JpdGUoZGF0YSkKCiAgICAgICAgc2VsZi5fdGVzdGZ1bmNfZmlsZSh0bXBuYW1lLCAicnwqIikKCgpjbGFzcyBNZW1iZXJSZWFkVGVzdChSZWFkVGVzdCk6CgogICAgZGVmIF90ZXN0X21lbWJlcihzZWxmLCB0YXJpbmZvLCBjaGtzdW09Tm9uZSwgKiprd2FyZ3MpOgogICAgICAgIGlmIGNoa3N1bSBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKG1kNXN1bShzZWxmLnRhci5leHRyYWN0ZmlsZSh0YXJpbmZvKS5yZWFkKCkpID09IGNoa3N1bSwKICAgICAgICAgICAgICAgICAgICAid3JvbmcgbWQ1c3VtIGZvciAlcyIgJSB0YXJpbmZvLm5hbWUpCgogICAgICAgIGt3YXJnc1sibXRpbWUiXSA9IDA3NjA2MTM2NjE3CiAgICAgICAga3dhcmdzWyJ1aWQiXSA9IDEwMDAKICAgICAgICBrd2FyZ3NbImdpZCJdID0gMTAwCiAgICAgICAgaWYgIm9sZC12NyIgbm90IGluIHRhcmluZm8ubmFtZToKICAgICAgICAgICAgIyBWNyB0YXIgY2FuJ3QgaGFuZGxlIGFscGhhYmV0aWMgb3duZXJzLgogICAgICAgICAgICBrd2FyZ3NbInVuYW1lIl0gPSAidGFyZmlsZSIKICAgICAgICAgICAga3dhcmdzWyJnbmFtZSJdID0gInRhcmZpbGUiCiAgICAgICAgZm9yIGssIHYgaW4ga3dhcmdzLml0ZXJpdGVtcygpOgogICAgICAgICAgICBzZWxmLmFzc2VydFRydWUoZ2V0YXR0cih0YXJpbmZvLCBrKSA9PSB2LAogICAgICAgICAgICAgICAgICAgICJ3cm9uZyB2YWx1ZSBpbiAlcyBmaWVsZCBvZiAlcyIgJSAoaywgdGFyaW5mby5uYW1lKSkKCiAgICBkZWYgdGVzdF9maW5kX3JlZ3R5cGUoc2VsZik6CiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcigidXN0YXIvcmVndHlwZSIpCiAgICAgICAgc2VsZi5fdGVzdF9tZW1iZXIodGFyaW5mbywgc2l6ZT03MDExLCBjaGtzdW09bWQ1X3JlZ3R5cGUpCgogICAgZGVmIHRlc3RfZmluZF9jb250dHlwZShzZWxmKToKICAgICAgICB0YXJpbmZvID0gc2VsZi50YXIuZ2V0bWVtYmVyKCJ1c3Rhci9jb250dHlwZSIpCiAgICAgICAgc2VsZi5fdGVzdF9tZW1iZXIodGFyaW5mbywgc2l6ZT03MDExLCBjaGtzdW09bWQ1X3JlZ3R5cGUpCgogICAgZGVmIHRlc3RfZmluZF9kaXJ0eXBlKHNlbGYpOgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhci5nZXRtZW1iZXIoInVzdGFyL2RpcnR5cGUiKQogICAgICAgIHNlbGYuX3Rlc3RfbWVtYmVyKHRhcmluZm8sIHNpemU9MCkKCiAgICBkZWYgdGVzdF9maW5kX2RpcnR5cGVfd2l0aF9zaXplKHNlbGYpOgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhci5nZXRtZW1iZXIoInVzdGFyL2RpcnR5cGUtd2l0aC1zaXplIikKICAgICAgICBzZWxmLl90ZXN0X21lbWJlcih0YXJpbmZvLCBzaXplPTI1NSkKCiAgICBkZWYgdGVzdF9maW5kX2xua3R5cGUoc2VsZik6CiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcigidXN0YXIvbG5rdHlwZSIpCiAgICAgICAgc2VsZi5fdGVzdF9tZW1iZXIodGFyaW5mbywgc2l6ZT0wLCBsaW5rbmFtZT0idXN0YXIvcmVndHlwZSIpCgogICAgZGVmIHRlc3RfZmluZF9zeW10eXBlKHNlbGYpOgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhci5nZXRtZW1iZXIoInVzdGFyL3N5bXR5cGUiKQogICAgICAgIHNlbGYuX3Rlc3RfbWVtYmVyKHRhcmluZm8sIHNpemU9MCwgbGlua25hbWU9InJlZ3R5cGUiKQoKICAgIGRlZiB0ZXN0X2ZpbmRfYmxrdHlwZShzZWxmKToKICAgICAgICB0YXJpbmZvID0gc2VsZi50YXIuZ2V0bWVtYmVyKCJ1c3Rhci9ibGt0eXBlIikKICAgICAgICBzZWxmLl90ZXN0X21lbWJlcih0YXJpbmZvLCBzaXplPTAsIGRldm1ham9yPTMsIGRldm1pbm9yPTApCgogICAgZGVmIHRlc3RfZmluZF9jaHJ0eXBlKHNlbGYpOgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhci5nZXRtZW1iZXIoInVzdGFyL2NocnR5cGUiKQogICAgICAgIHNlbGYuX3Rlc3RfbWVtYmVyKHRhcmluZm8sIHNpemU9MCwgZGV2bWFqb3I9MSwgZGV2bWlub3I9MykKCiAgICBkZWYgdGVzdF9maW5kX2ZpZm90eXBlKHNlbGYpOgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhci5nZXRtZW1iZXIoInVzdGFyL2ZpZm90eXBlIikKICAgICAgICBzZWxmLl90ZXN0X21lbWJlcih0YXJpbmZvLCBzaXplPTApCgogICAgZGVmIHRlc3RfZmluZF9zcGFyc2Uoc2VsZik6CiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcigidXN0YXIvc3BhcnNlIikKICAgICAgICBzZWxmLl90ZXN0X21lbWJlcih0YXJpbmZvLCBzaXplPTg2MDE2LCBjaGtzdW09bWQ1X3NwYXJzZSkKCiAgICBkZWYgdGVzdF9maW5kX3VtbGF1dHMoc2VsZik6CiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcigidXN0YXIvdW1sYXV0cy3E1tzk9vzfIikKICAgICAgICBzZWxmLl90ZXN0X21lbWJlcih0YXJpbmZvLCBzaXplPTcwMTEsIGNoa3N1bT1tZDVfcmVndHlwZSkKCiAgICBkZWYgdGVzdF9maW5kX3VzdGFyX2xvbmduYW1lKHNlbGYpOgogICAgICAgIG5hbWUgPSAidXN0YXIvIiArICIxMjM0NS8iICogMzkgKyAiMTIzNDU2Ny9sb25nbmFtZSIKICAgICAgICBzZWxmLmFzc2VydEluKG5hbWUsIHNlbGYudGFyLmdldG5hbWVzKCkpCgogICAgZGVmIHRlc3RfZmluZF9yZWd0eXBlX29sZHY3KHNlbGYpOgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhci5nZXRtZW1iZXIoIm1pc2MvcmVndHlwZS1vbGQtdjciKQogICAgICAgIHNlbGYuX3Rlc3RfbWVtYmVyKHRhcmluZm8sIHNpemU9NzAxMSwgY2hrc3VtPW1kNV9yZWd0eXBlKQoKICAgIGRlZiB0ZXN0X2ZpbmRfcGF4X3VtbGF1dHMoc2VsZik6CiAgICAgICAgc2VsZi50YXIgPSB0YXJmaWxlLm9wZW4oc2VsZi50YXJuYW1lLCBtb2RlPXNlbGYubW9kZSwgZW5jb2Rpbmc9Imlzbzg4NTktMSIpCiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcigicGF4L3VtbGF1dHMtxNbc5Pb83yIpCiAgICAgICAgc2VsZi5fdGVzdF9tZW1iZXIodGFyaW5mbywgc2l6ZT03MDExLCBjaGtzdW09bWQ1X3JlZ3R5cGUpCgoKY2xhc3MgTG9uZ25hbWVUZXN0KFJlYWRUZXN0KToKCiAgICBkZWYgdGVzdF9yZWFkX2xvbmduYW1lKHNlbGYpOgogICAgICAgICMgVGVzdCByZWFkaW5nIG9mIGxvbmduYW1lIChidWcgIzE0NzE0MjcpLgogICAgICAgIGxvbmduYW1lID0gc2VsZi5zdWJkaXIgKyAiLyIgKyAiMTIzLyIgKiAxMjUgKyAibG9uZ25hbWUiCiAgICAgICAgdHJ5OgogICAgICAgICAgICB0YXJpbmZvID0gc2VsZi50YXIuZ2V0bWVtYmVyKGxvbmduYW1lKQogICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgc2VsZi5mYWlsKCJsb25nbmFtZSBub3QgZm91bmQiKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0YXJpbmZvLnR5cGUgIT0gdGFyZmlsZS5ESVJUWVBFLCAicmVhZCBsb25nbmFtZSBhcyBkaXJ0eXBlIikKCiAgICBkZWYgdGVzdF9yZWFkX2xvbmdsaW5rKHNlbGYpOgogICAgICAgIGxvbmduYW1lID0gc2VsZi5zdWJkaXIgKyAiLyIgKyAiMTIzLyIgKiAxMjUgKyAibG9uZ25hbWUiCiAgICAgICAgbG9uZ2xpbmsgPSBzZWxmLnN1YmRpciArICIvIiArICIxMjMvIiAqIDEyNSArICJsb25nbGluayIKICAgICAgICB0cnk6CiAgICAgICAgICAgIHRhcmluZm8gPSBzZWxmLnRhci5nZXRtZW1iZXIobG9uZ2xpbmspCiAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICBzZWxmLmZhaWwoImxvbmdsaW5rIG5vdCBmb3VuZCIpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHRhcmluZm8ubGlua25hbWUgPT0gbG9uZ25hbWUsICJsaW5rbmFtZSB3cm9uZyIpCgogICAgZGVmIHRlc3RfdHJ1bmNhdGVkX2xvbmduYW1lKHNlbGYpOgogICAgICAgIGxvbmduYW1lID0gc2VsZi5zdWJkaXIgKyAiLyIgKyAiMTIzLyIgKiAxMjUgKyAibG9uZ25hbWUiCiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldG1lbWJlcihsb25nbmFtZSkKICAgICAgICBvZmZzZXQgPSB0YXJpbmZvLm9mZnNldAogICAgICAgIHNlbGYudGFyLmZpbGVvYmouc2VlayhvZmZzZXQpCiAgICAgICAgZm9iaiA9IFN0cmluZ0lPLlN0cmluZ0lPKHNlbGYudGFyLmZpbGVvYmoucmVhZCgzICogNTEyKSkKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyh0YXJmaWxlLlJlYWRFcnJvciwgdGFyZmlsZS5vcGVuLCBuYW1lPSJmb28udGFyIiwgZmlsZW9iaj1mb2JqKQoKICAgIGRlZiB0ZXN0X2hlYWRlcl9vZmZzZXQoc2VsZik6CiAgICAgICAgIyBUZXN0IGlmIHRoZSBzdGFydCBvZmZzZXQgb2YgdGhlIFRhckluZm8gb2JqZWN0IGluY2x1ZGVzCiAgICAgICAgIyB0aGUgcHJlY2VkaW5nIGV4dGVuZGVkIGhlYWRlci4KICAgICAgICBsb25nbmFtZSA9IHNlbGYuc3ViZGlyICsgIi8iICsgIjEyMy8iICogMTI1ICsgImxvbmduYW1lIgogICAgICAgIG9mZnNldCA9IHNlbGYudGFyLmdldG1lbWJlcihsb25nbmFtZSkub2Zmc2V0CiAgICAgICAgZm9iaiA9IG9wZW4odGFybmFtZSkKICAgICAgICBmb2JqLnNlZWsob2Zmc2V0KQogICAgICAgIHRhcmluZm8gPSB0YXJmaWxlLlRhckluZm8uZnJvbWJ1Zihmb2JqLnJlYWQoNTEyKSkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8udHlwZSwgc2VsZi5sb25nbmFtZXR5cGUpCgoKY2xhc3MgR05VUmVhZFRlc3QoTG9uZ25hbWVUZXN0KToKCiAgICBzdWJkaXIgPSAiZ251IgogICAgbG9uZ25hbWV0eXBlID0gdGFyZmlsZS5HTlVUWVBFX0xPTkdOQU1FCgogICAgZGVmIHRlc3Rfc3BhcnNlX2ZpbGUoc2VsZik6CiAgICAgICAgdGFyaW5mbzEgPSBzZWxmLnRhci5nZXRtZW1iZXIoInVzdGFyL3NwYXJzZSIpCiAgICAgICAgZm9iajEgPSBzZWxmLnRhci5leHRyYWN0ZmlsZSh0YXJpbmZvMSkKICAgICAgICB0YXJpbmZvMiA9IHNlbGYudGFyLmdldG1lbWJlcigiZ251L3NwYXJzZSIpCiAgICAgICAgZm9iajIgPSBzZWxmLnRhci5leHRyYWN0ZmlsZSh0YXJpbmZvMikKICAgICAgICBzZWxmLmFzc2VydFRydWUoZm9iajEucmVhZCgpID09IGZvYmoyLnJlYWQoKSwKICAgICAgICAgICAgICAgICJzcGFyc2UgZmlsZSBleHRyYWN0aW9uIGZhaWxlZCIpCgoKY2xhc3MgUGF4UmVhZFRlc3QoTG9uZ25hbWVUZXN0KToKCiAgICBzdWJkaXIgPSAicGF4IgogICAgbG9uZ25hbWV0eXBlID0gdGFyZmlsZS5YSERUWVBFCgogICAgZGVmIHRlc3RfcGF4X2dsb2JhbF9oZWFkZXJzKHNlbGYpOgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0YXJuYW1lLCBlbmNvZGluZz0iaXNvODg1OS0xIikKCiAgICAgICAgdGFyaW5mbyA9IHRhci5nZXRtZW1iZXIoInBheC9yZWd0eXBlMSIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXJpbmZvLnVuYW1lLCAiZm9vIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8uZ25hbWUsICJiYXIiKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyaW5mby5wYXhfaGVhZGVycy5nZXQoIlZFTkRPUi51bWxhdXRzIiksIHUixNbc5Pb83yIpCgogICAgICAgIHRhcmluZm8gPSB0YXIuZ2V0bWVtYmVyKCJwYXgvcmVndHlwZTIiKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyaW5mby51bmFtZSwgIiIpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXJpbmZvLmduYW1lLCAiYmFyIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8ucGF4X2hlYWRlcnMuZ2V0KCJWRU5ET1IudW1sYXV0cyIpLCB1IsTW3OT2/N8iKQoKICAgICAgICB0YXJpbmZvID0gdGFyLmdldG1lbWJlcigicGF4L3JlZ3R5cGUzIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8udW5hbWUsICJ0YXJmaWxlIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8uZ25hbWUsICJ0YXJmaWxlIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8ucGF4X2hlYWRlcnMuZ2V0KCJWRU5ET1IudW1sYXV0cyIpLCB1IsTW3OT2/N8iKQoKICAgIGRlZiB0ZXN0X3BheF9udW1iZXJfZmllbGRzKHNlbGYpOgogICAgICAgICMgQWxsIGZvbGxvd2luZyBudW1iZXIgZmllbGRzIGFyZSByZWFkIGZyb20gdGhlIHBheCBoZWFkZXIuCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRhcm5hbWUsIGVuY29kaW5nPSJpc284ODU5LTEiKQogICAgICAgIHRhcmluZm8gPSB0YXIuZ2V0bWVtYmVyKCJwYXgvcmVndHlwZTQiKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyaW5mby5zaXplLCA3MDExKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyaW5mby51aWQsIDEyMykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8uZ2lkLCAxMjMpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXJpbmZvLm10aW1lLCAxMDQxODA4NzgzLjApCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0eXBlKHRhcmluZm8ubXRpbWUpLCBmbG9hdCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGZsb2F0KHRhcmluZm8ucGF4X2hlYWRlcnNbImF0aW1lIl0pLCAxMDQxODA4NzgzLjApCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChmbG9hdCh0YXJpbmZvLnBheF9oZWFkZXJzWyJjdGltZSJdKSwgMTA0MTgwODc4My4wKQoKCmNsYXNzIFdyaXRlVGVzdEJhc2UodW5pdHRlc3QuVGVzdENhc2UpOgogICAgIyBQdXQgYWxsIHdyaXRlIHRlc3RzIGluIGhlcmUgdGhhdCBhcmUgc3VwcG9zZWQgdG8gYmUgdGVzdGVkCiAgICAjIGluIGFsbCBwb3NzaWJsZSBtb2RlIGNvbWJpbmF0aW9ucy4KCiAgICBkZWYgdGVzdF9maWxlb2JqX25vX2Nsb3NlKHNlbGYpOgogICAgICAgIGZvYmogPSBTdHJpbmdJTy5TdHJpbmdJTygpCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKGZpbGVvYmo9Zm9iaiwgbW9kZT1zZWxmLm1vZGUpCiAgICAgICAgdGFyLmFkZGZpbGUodGFyZmlsZS5UYXJJbmZvKCJmb28iKSkKICAgICAgICB0YXIuY2xvc2UoKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShmb2JqLmNsb3NlZCBpcyBGYWxzZSwgImV4dGVybmFsIGZpbGVvYmpzIG11c3QgbmV2ZXIgY2xvc2VkIikKICAgICAgICAjIElzc3VlICMyMDIzODogSW5jb21wbGV0ZSBnemlwIG91dHB1dCB3aXRoIG1vZGU9Inc6Z3oiCiAgICAgICAgZGF0YSA9IGZvYmouZ2V0dmFsdWUoKQogICAgICAgIGRlbCB0YXIKICAgICAgICB0ZXN0X3N1cHBvcnQuZ2NfY29sbGVjdCgpCiAgICAgICAgc2VsZi5hc3NlcnRGYWxzZShmb2JqLmNsb3NlZCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGRhdGEsIGZvYmouZ2V0dmFsdWUoKSkKCgpjbGFzcyBXcml0ZVRlc3QoV3JpdGVUZXN0QmFzZSk6CgogICAgbW9kZSA9ICJ3OiIKCiAgICBkZWYgdGVzdF8xMDBfY2hhcl9uYW1lKHNlbGYpOgogICAgICAgICMgVGhlIG5hbWUgZmllbGQgaW4gYSB0YXIgaGVhZGVyIHN0b3JlcyBzdHJpbmdzIG9mIGF0IG1vc3QgMTAwIGNoYXJzLgogICAgICAgICMgSWYgYSBzdHJpbmcgaXMgc2hvcnRlciB0aGFuIDEwMCBjaGFycyBpdCBoYXMgdG8gYmUgcGFkZGVkIHdpdGggJ1wwJywKICAgICAgICAjIHdoaWNoIGltcGxpZXMgdGhhdCBhIHN0cmluZyBvZiBleGFjdGx5IDEwMCBjaGFycyBpcyBzdG9yZWQgd2l0aG91dAogICAgICAgICMgYSB0cmFpbGluZyAnXDAnLgogICAgICAgIG5hbWUgPSAiMDEyMzQ1Njc4OSIgKiAxMAogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgdCA9IHRhcmZpbGUuVGFySW5mbyhuYW1lKQogICAgICAgIHRhci5hZGRmaWxlKHQpCiAgICAgICAgdGFyLmNsb3NlKCkKCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHRhci5nZXRuYW1lcygpWzBdID09IG5hbWUsCiAgICAgICAgICAgICAgICAiZmFpbGVkIHRvIHN0b3JlIDEwMCBjaGFyIGZpbGVuYW1lIikKICAgICAgICB0YXIuY2xvc2UoKQoKICAgIGRlZiB0ZXN0X3Rhcl9zaXplKHNlbGYpOgogICAgICAgICMgVGVzdCBmb3IgYnVnICMxMDEzODgyLgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihURU1QRElSLCAiZmlsZSIpCiAgICAgICAgZm9iaiA9IG9wZW4ocGF0aCwgIndiIikKICAgICAgICBmb2JqLndyaXRlKCJhYWEiKQogICAgICAgIGZvYmouY2xvc2UoKQogICAgICAgIHRhci5hZGQocGF0aCkKICAgICAgICB0YXIuY2xvc2UoKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShvcy5wYXRoLmdldHNpemUodG1wbmFtZSkgPiAwLAogICAgICAgICAgICAgICAgInRhcmZpbGUgaXMgZW1wdHkiKQoKICAgICMgVGhlIHRlc3RfKl9zaXplIHRlc3RzIHRlc3QgZm9yIGJ1ZyAjMTE2NzEyOC4KICAgIGRlZiB0ZXN0X2ZpbGVfc2l6ZShzZWxmKToKICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odG1wbmFtZSwgc2VsZi5tb2RlKQoKICAgICAgICBwYXRoID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJmaWxlIikKICAgICAgICBmb2JqID0gb3BlbihwYXRoLCAid2IiKQogICAgICAgIGZvYmouY2xvc2UoKQogICAgICAgIHRhcmluZm8gPSB0YXIuZ2V0dGFyaW5mbyhwYXRoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyaW5mby5zaXplLCAwKQoKICAgICAgICBmb2JqID0gb3BlbihwYXRoLCAid2IiKQogICAgICAgIGZvYmoud3JpdGUoImFhYSIpCiAgICAgICAgZm9iai5jbG9zZSgpCiAgICAgICAgdGFyaW5mbyA9IHRhci5nZXR0YXJpbmZvKHBhdGgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXJpbmZvLnNpemUsIDMpCgogICAgICAgIHRhci5jbG9zZSgpCgogICAgZGVmIHRlc3RfZGlyZWN0b3J5X3NpemUoc2VsZik6CiAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihURU1QRElSLCAiZGlyZWN0b3J5IikKICAgICAgICBvcy5ta2RpcihwYXRoKQogICAgICAgIHRyeToKICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsIHNlbGYubW9kZSkKICAgICAgICAgICAgdGFyaW5mbyA9IHRhci5nZXR0YXJpbmZvKHBhdGgpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyaW5mby5zaXplLCAwKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIG9zLnJtZGlyKHBhdGgpCgogICAgZGVmIHRlc3RfbGlua19zaXplKHNlbGYpOgogICAgICAgIGlmIGhhc2F0dHIob3MsICJsaW5rIik6CiAgICAgICAgICAgIGxpbmsgPSBvcy5wYXRoLmpvaW4oVEVNUERJUiwgImxpbmsiKQogICAgICAgICAgICB0YXJnZXQgPSBvcy5wYXRoLmpvaW4oVEVNUERJUiwgImxpbmtfdGFyZ2V0IikKICAgICAgICAgICAgZm9iaiA9IG9wZW4odGFyZ2V0LCAid2IiKQogICAgICAgICAgICBmb2JqLndyaXRlKCJhYWEiKQogICAgICAgICAgICBmb2JqLmNsb3NlKCkKICAgICAgICAgICAgb3MubGluayh0YXJnZXQsIGxpbmspCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgICAgICAgICAjIFJlY29yZCB0aGUgbGluayB0YXJnZXQgaW4gdGhlIGlub2RlcyBsaXN0LgogICAgICAgICAgICAgICAgdGFyLmdldHRhcmluZm8odGFyZ2V0KQogICAgICAgICAgICAgICAgdGFyaW5mbyA9IHRhci5nZXR0YXJpbmZvKGxpbmspCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8uc2l6ZSwgMCkKICAgICAgICAgICAgZmluYWxseToKICAgICAgICAgICAgICAgIG9zLnJlbW92ZSh0YXJnZXQpCiAgICAgICAgICAgICAgICBvcy5yZW1vdmUobGluaykKCiAgICBkZWYgdGVzdF9zeW1saW5rX3NpemUoc2VsZik6CiAgICAgICAgaWYgaGFzYXR0cihvcywgInN5bWxpbmsiKToKICAgICAgICAgICAgcGF0aCA9IG9zLnBhdGguam9pbihURU1QRElSLCAic3ltbGluayIpCiAgICAgICAgICAgIG9zLnN5bWxpbmsoImxpbmtfdGFyZ2V0IiwgcGF0aCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsIHNlbGYubW9kZSkKICAgICAgICAgICAgICAgIHRhcmluZm8gPSB0YXIuZ2V0dGFyaW5mbyhwYXRoKQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXJpbmZvLnNpemUsIDApCiAgICAgICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgICAgICBvcy5yZW1vdmUocGF0aCkKCiAgICBkZWYgdGVzdF9hZGRfc2VsZihzZWxmKToKICAgICAgICAjIFRlc3QgZm9yICMxMjU3MjU1LgogICAgICAgIGRzdG5hbWUgPSBvcy5wYXRoLmFic3BhdGgodG1wbmFtZSkKCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsIHNlbGYubW9kZSkKICAgICAgICBzZWxmLmFzc2VydFRydWUodGFyLm5hbWUgPT0gZHN0bmFtZSwgImFyY2hpdmUgbmFtZSBtdXN0IGJlIGFic29sdXRlIikKCiAgICAgICAgdGFyLmFkZChkc3RuYW1lKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0YXIuZ2V0bmFtZXMoKSA9PSBbXSwgImFkZGVkIHRoZSBhcmNoaXZlIHRvIGl0c2VsZiIpCgogICAgICAgIGN3ZCA9IG9zLmdldGN3ZCgpCiAgICAgICAgb3MuY2hkaXIoVEVNUERJUikKICAgICAgICB0YXIuYWRkKGRzdG5hbWUpCiAgICAgICAgb3MuY2hkaXIoY3dkKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0YXIuZ2V0bmFtZXMoKSA9PSBbXSwgImFkZGVkIHRoZSBhcmNoaXZlIHRvIGl0c2VsZiIpCgogICAgZGVmIHRlc3RfZXhjbHVkZShzZWxmKToKICAgICAgICB0ZW1wZGlyID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJleGNsdWRlIikKICAgICAgICBvcy5ta2Rpcih0ZW1wZGlyKQogICAgICAgIHRyeToKICAgICAgICAgICAgZm9yIG5hbWUgaW4gKCJmb28iLCAiYmFyIiwgImJheiIpOgogICAgICAgICAgICAgICAgbmFtZSA9IG9zLnBhdGguam9pbih0ZW1wZGlyLCBuYW1lKQogICAgICAgICAgICAgICAgb3BlbihuYW1lLCAid2IiKS5jbG9zZSgpCgogICAgICAgICAgICBleGNsdWRlID0gb3MucGF0aC5pc2ZpbGUKCiAgICAgICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCBzZWxmLm1vZGUsIGVuY29kaW5nPSJpc284ODU5LTEiKQogICAgICAgICAgICB3aXRoIHRlc3Rfc3VwcG9ydC5jaGVja193YXJuaW5ncygoInVzZSB0aGUgZmlsdGVyIGFyZ3VtZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlcHJlY2F0aW9uV2FybmluZykpOgogICAgICAgICAgICAgICAgdGFyLmFkZCh0ZW1wZGlyLCBhcmNuYW1lPSJlbXB0eV9kaXIiLCBleGNsdWRlPWV4Y2x1ZGUpCiAgICAgICAgICAgIHRhci5jbG9zZSgpCgogICAgICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odG1wbmFtZSwgInIiKQogICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbih0YXIuZ2V0bWVtYmVycygpKSwgMSkKICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXIuZ2V0bmFtZXMoKVswXSwgImVtcHR5X2RpciIpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgc2h1dGlsLnJtdHJlZSh0ZW1wZGlyKQoKICAgIGRlZiB0ZXN0X2ZpbHRlcihzZWxmKToKICAgICAgICB0ZW1wZGlyID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJmaWx0ZXIiKQogICAgICAgIG9zLm1rZGlyKHRlbXBkaXIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBmb3IgbmFtZSBpbiAoImZvbyIsICJiYXIiLCAiYmF6Iik6CiAgICAgICAgICAgICAgICBuYW1lID0gb3MucGF0aC5qb2luKHRlbXBkaXIsIG5hbWUpCiAgICAgICAgICAgICAgICBvcGVuKG5hbWUsICJ3YiIpLmNsb3NlKCkKCiAgICAgICAgICAgIGRlZiBmaWx0ZXIodGFyaW5mbyk6CiAgICAgICAgICAgICAgICBpZiBvcy5wYXRoLmJhc2VuYW1lKHRhcmluZm8ubmFtZSkgPT0gImJhciI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgICAgICB0YXJpbmZvLnVpZCA9IDEyMwogICAgICAgICAgICAgICAgdGFyaW5mby51bmFtZSA9ICJmb28iCiAgICAgICAgICAgICAgICByZXR1cm4gdGFyaW5mbwoKICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsIHNlbGYubW9kZSwgZW5jb2Rpbmc9Imlzbzg4NTktMSIpCiAgICAgICAgICAgIHRhci5hZGQodGVtcGRpciwgYXJjbmFtZT0iZW1wdHlfZGlyIiwgZmlsdGVyPWZpbHRlcikKICAgICAgICAgICAgdGFyLmNsb3NlKCkKCiAgICAgICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCAiciIpCiAgICAgICAgICAgIGZvciB0YXJpbmZvIGluIHRhcjoKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyaW5mby51aWQsIDEyMykKICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodGFyaW5mby51bmFtZSwgImZvbyIpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHRhci5nZXRtZW1iZXJzKCkpLCAzKQogICAgICAgICAgICB0YXIuY2xvc2UoKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIHNodXRpbC5ybXRyZWUodGVtcGRpcikKCiAgICAjIEd1YXJhbnRlZSB0aGF0IHN0b3JlZCBwYXRobmFtZXMgYXJlIG5vdCBtb2RpZmllZC4gRG9uJ3QKICAgICMgcmVtb3ZlIC4vIG9yIC4uLyBvciBkb3VibGUgc2xhc2hlcy4gU3RpbGwgbWFrZSBhYnNvbHV0ZQogICAgIyBwYXRobmFtZXMgcmVsYXRpdmUuCiAgICAjIEZvciBkZXRhaWxzIHNlZSBidWcgIzYwNTQuCiAgICBkZWYgX3Rlc3RfcGF0aG5hbWUoc2VsZiwgcGF0aCwgY21wX3BhdGg9Tm9uZSwgZGlyPUZhbHNlKToKICAgICAgICAjIENyZWF0ZSBhIHRhcmZpbGUgd2l0aCBhbiBlbXB0eSBtZW1iZXIgbmFtZWQgcGF0aAogICAgICAgICMgYW5kIGNvbXBhcmUgdGhlIHN0b3JlZCBuYW1lIHdpdGggdGhlIG9yaWdpbmFsLgogICAgICAgIGZvbyA9IG9zLnBhdGguam9pbihURU1QRElSLCAiZm9vIikKICAgICAgICBpZiBub3QgZGlyOgogICAgICAgICAgICBvcGVuKGZvbywgInciKS5jbG9zZSgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgb3MubWtkaXIoZm9vKQoKICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odG1wbmFtZSwgc2VsZi5tb2RlKQogICAgICAgIHRhci5hZGQoZm9vLCBhcmNuYW1lPXBhdGgpCiAgICAgICAgdGFyLmNsb3NlKCkKCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsICJyIikKICAgICAgICB0ID0gdGFyLm5leHQoKQogICAgICAgIHRhci5jbG9zZSgpCgogICAgICAgIGlmIG5vdCBkaXI6CiAgICAgICAgICAgIG9zLnJlbW92ZShmb28pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgb3Mucm1kaXIoZm9vKQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHQubmFtZSwgY21wX3BhdGggb3IgcGF0aC5yZXBsYWNlKG9zLnNlcCwgIi8iKSkKCiAgICBkZWYgdGVzdF9wYXRobmFtZXMoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdF9wYXRobmFtZSgiZm9vIikKICAgICAgICBzZWxmLl90ZXN0X3BhdGhuYW1lKG9zLnBhdGguam9pbigiZm9vIiwgIi4iLCAiYmFyIikpCiAgICAgICAgc2VsZi5fdGVzdF9wYXRobmFtZShvcy5wYXRoLmpvaW4oImZvbyIsICIuLiIsICJiYXIiKSkKICAgICAgICBzZWxmLl90ZXN0X3BhdGhuYW1lKG9zLnBhdGguam9pbigiLiIsICJmb28iKSkKICAgICAgICBzZWxmLl90ZXN0X3BhdGhuYW1lKG9zLnBhdGguam9pbigiLiIsICJmb28iLCAiLiIpKQogICAgICAgIHNlbGYuX3Rlc3RfcGF0aG5hbWUob3MucGF0aC5qb2luKCIuIiwgImZvbyIsICIuIiwgImJhciIpKQogICAgICAgIHNlbGYuX3Rlc3RfcGF0aG5hbWUob3MucGF0aC5qb2luKCIuIiwgImZvbyIsICIuLiIsICJiYXIiKSkKICAgICAgICBzZWxmLl90ZXN0X3BhdGhuYW1lKG9zLnBhdGguam9pbigiLiIsICJmb28iLCAiLi4iLCAiYmFyIikpCiAgICAgICAgc2VsZi5fdGVzdF9wYXRobmFtZShvcy5wYXRoLmpvaW4oIi4uIiwgImZvbyIpKQogICAgICAgIHNlbGYuX3Rlc3RfcGF0aG5hbWUob3MucGF0aC5qb2luKCIuLiIsICJmb28iLCAiLi4iKSkKICAgICAgICBzZWxmLl90ZXN0X3BhdGhuYW1lKG9zLnBhdGguam9pbigiLi4iLCAiZm9vIiwgIi4iLCAiYmFyIikpCiAgICAgICAgc2VsZi5fdGVzdF9wYXRobmFtZShvcy5wYXRoLmpvaW4oIi4uIiwgImZvbyIsICIuLiIsICJiYXIiKSkKCiAgICAgICAgc2VsZi5fdGVzdF9wYXRobmFtZSgiZm9vIiArIG9zLnNlcCArIG9zLnNlcCArICJiYXIiKQogICAgICAgIHNlbGYuX3Rlc3RfcGF0aG5hbWUoImZvbyIgKyBvcy5zZXAgKyBvcy5zZXAsICJmb28iLCBkaXI9VHJ1ZSkKCiAgICBkZWYgdGVzdF9hYnNfcGF0aG5hbWVzKHNlbGYpOgogICAgICAgIGlmIHN5cy5wbGF0Zm9ybSA9PSAid2luMzIiOgogICAgICAgICAgICBzZWxmLl90ZXN0X3BhdGhuYW1lKCJDOlxcZm9vIiwgImZvbyIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fdGVzdF9wYXRobmFtZSgiL2ZvbyIsICJmb28iKQogICAgICAgICAgICBzZWxmLl90ZXN0X3BhdGhuYW1lKCIvLy9mb28iLCAiZm9vIikKCiAgICBkZWYgdGVzdF9jd2Qoc2VsZik6CiAgICAgICAgIyBUZXN0IGFkZGluZyB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS4KICAgICAgICBjd2QgPSBvcy5nZXRjd2QoKQogICAgICAgIG9zLmNoZGlyKFRFTVBESVIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBvcGVuKCJmb28iLCAidyIpLmNsb3NlKCkKCiAgICAgICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCBzZWxmLm1vZGUpCiAgICAgICAgICAgIHRhci5hZGQoIi4iKQogICAgICAgICAgICB0YXIuY2xvc2UoKQoKICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsICJyIikKICAgICAgICAgICAgZm9yIHQgaW4gdGFyOgogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHQubmFtZSA9PSAiLiIgb3IgdC5uYW1lLnN0YXJ0c3dpdGgoIi4vIikpCiAgICAgICAgICAgIHRhci5jbG9zZSgpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgb3MuY2hkaXIoY3dkKQoKICAgIEB1bml0dGVzdC5za2lwVW5sZXNzKGhhc2F0dHIob3MsICdzeW1saW5rJyksICJuZWVkcyBvcy5zeW1saW5rIikKICAgIGRlZiB0ZXN0X2V4dHJhY3RhbGxfc3ltbGlua3Moc2VsZik6CiAgICAgICAgIyBUZXN0IGlmIGV4dHJhY3RhbGwgd29ya3MgcHJvcGVybHkgd2hlbiB0YXJmaWxlIGNvbnRhaW5zIHN5bWxpbmtzCiAgICAgICAgdGVtcGRpciA9IG9zLnBhdGguam9pbihURU1QRElSLCAidGVzdHN5bWxpbmtzIikKICAgICAgICB0ZW1wYXJjaGl2ZSA9IG9zLnBhdGguam9pbihURU1QRElSLCAidGVzdHN5bWxpbmtzLnRhciIpCiAgICAgICAgb3MubWtkaXIodGVtcGRpcikKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNvdXJjZV9maWxlID0gb3MucGF0aC5qb2luKHRlbXBkaXIsJ3NvdXJjZScpCiAgICAgICAgICAgIHRhcmdldF9maWxlID0gb3MucGF0aC5qb2luKHRlbXBkaXIsJ3N5bWxpbmsnKQogICAgICAgICAgICB3aXRoIG9wZW4oc291cmNlX2ZpbGUsJ3cnKSBhcyBmOgogICAgICAgICAgICAgICAgZi53cml0ZSgnc29tZXRoaW5nXG4nKQogICAgICAgICAgICBvcy5zeW1saW5rKHNvdXJjZV9maWxlLCB0YXJnZXRfZmlsZSkKICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRlbXBhcmNoaXZlLCd3JykKICAgICAgICAgICAgdGFyLmFkZChzb3VyY2VfZmlsZSwgYXJjbmFtZT1vcy5wYXRoLmJhc2VuYW1lKHNvdXJjZV9maWxlKSkKICAgICAgICAgICAgdGFyLmFkZCh0YXJnZXRfZmlsZSwgYXJjbmFtZT1vcy5wYXRoLmJhc2VuYW1lKHRhcmdldF9maWxlKSkKICAgICAgICAgICAgdGFyLmNsb3NlKCkKICAgICAgICAgICAgIyBMZXQncyBleHRyYWN0IGl0IHRvIHRoZSBsb2NhdGlvbiB3aGljaCBjb250YWlucyB0aGUgc3ltbGluawogICAgICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odGVtcGFyY2hpdmUsJ3InKQogICAgICAgICAgICAjIHRoaXMgc2hvdWxkIG5vdCByYWlzZSBPU0Vycm9yOiBbRXJybm8gMTddIEZpbGUgZXhpc3RzCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhci5leHRyYWN0YWxsKHBhdGg9dGVtcGRpcikKICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgICAgICBzZWxmLmZhaWwoImV4dHJhY3RhbGwgZmFpbGVkIHdpdGggc3ltbGlua2VkIGZpbGVzIikKICAgICAgICAgICAgZmluYWxseToKICAgICAgICAgICAgICAgIHRhci5jbG9zZSgpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgb3MudW5saW5rKHRlbXBhcmNoaXZlKQogICAgICAgICAgICBzaHV0aWwucm10cmVlKHRlbXBkaXIpCgogICAgQHVuaXR0ZXN0LnNraXBVbmxlc3MoaGFzYXR0cihvcywgJ3N5bWxpbmsnKSwgIm5lZWRzIG9zLnN5bWxpbmsiKQogICAgZGVmIHRlc3RfZXh0cmFjdGFsbF9icm9rZW5fc3ltbGlua3Moc2VsZik6CiAgICAgICAgIyBUZXN0IGlmIGV4dHJhY3RhbGwgd29ya3MgcHJvcGVybHkgd2hlbiB0YXJmaWxlIGNvbnRhaW5zIGJyb2tlbgogICAgICAgICMgc3ltbGlua3MKICAgICAgICB0ZW1wZGlyID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJ0ZXN0c3ltbGlua3MiKQogICAgICAgIHRlbXBhcmNoaXZlID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJ0ZXN0c3ltbGlua3MudGFyIikKICAgICAgICBvcy5ta2Rpcih0ZW1wZGlyKQogICAgICAgIHRyeToKICAgICAgICAgICAgc291cmNlX2ZpbGUgPSBvcy5wYXRoLmpvaW4odGVtcGRpciwnc291cmNlJykKICAgICAgICAgICAgdGFyZ2V0X2ZpbGUgPSBvcy5wYXRoLmpvaW4odGVtcGRpciwnc3ltbGluaycpCiAgICAgICAgICAgIHdpdGggb3Blbihzb3VyY2VfZmlsZSwndycpIGFzIGY6CiAgICAgICAgICAgICAgICBmLndyaXRlKCdzb21ldGhpbmdcbicpCiAgICAgICAgICAgIG9zLnN5bWxpbmsoc291cmNlX2ZpbGUsIHRhcmdldF9maWxlKQogICAgICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odGVtcGFyY2hpdmUsJ3cnKQogICAgICAgICAgICB0YXIuYWRkKHRhcmdldF9maWxlLCBhcmNuYW1lPW9zLnBhdGguYmFzZW5hbWUodGFyZ2V0X2ZpbGUpKQogICAgICAgICAgICB0YXIuY2xvc2UoKQogICAgICAgICAgICAjIHJlbW92ZSB0aGUgcmVhbCBmaWxlCiAgICAgICAgICAgIG9zLnVubGluayhzb3VyY2VfZmlsZSkKICAgICAgICAgICAgIyBMZXQncyBleHRyYWN0IGl0IHRvIHRoZSBsb2NhdGlvbiB3aGljaCBjb250YWlucyB0aGUgc3ltbGluawogICAgICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odGVtcGFyY2hpdmUsJ3InKQogICAgICAgICAgICAjIHRoaXMgc2hvdWxkIG5vdCByYWlzZSBPU0Vycm9yOiBbRXJybm8gMTddIEZpbGUgZXhpc3RzCiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhci5leHRyYWN0YWxsKHBhdGg9dGVtcGRpcikKICAgICAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgICAgICBzZWxmLmZhaWwoImV4dHJhY3RhbGwgZmFpbGVkIHdpdGggYnJva2VuIHN5bWxpbmtlZCBmaWxlcyIpCiAgICAgICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgICAgICB0YXIuY2xvc2UoKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIG9zLnVubGluayh0ZW1wYXJjaGl2ZSkKICAgICAgICAgICAgc2h1dGlsLnJtdHJlZSh0ZW1wZGlyKQoKICAgIEB1bml0dGVzdC5za2lwVW5sZXNzKGhhc2F0dHIob3MsICdsaW5rJyksICJuZWVkcyBvcy5saW5rIikKICAgIGRlZiB0ZXN0X2V4dHJhY3RhbGxfaGFyZGxpbmtzKHNlbGYpOgogICAgICAgICMgVGVzdCBpZiBleHRyYWN0YWxsIHdvcmtzIHByb3Blcmx5IHdoZW4gdGFyZmlsZSBjb250YWlucyBzeW1saW5rcwogICAgICAgIHRlbXBkaXIgPSBvcy5wYXRoLmpvaW4oVEVNUERJUiwgInRlc3RzeW1saW5rcyIpCiAgICAgICAgdGVtcGFyY2hpdmUgPSBvcy5wYXRoLmpvaW4oVEVNUERJUiwgInRlc3RzeW1saW5rcy50YXIiKQogICAgICAgIG9zLm1rZGlyKHRlbXBkaXIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzb3VyY2VfZmlsZSA9IG9zLnBhdGguam9pbih0ZW1wZGlyLCdzb3VyY2UnKQogICAgICAgICAgICB0YXJnZXRfZmlsZSA9IG9zLnBhdGguam9pbih0ZW1wZGlyLCdzeW1saW5rJykKICAgICAgICAgICAgd2l0aCBvcGVuKHNvdXJjZV9maWxlLCd3JykgYXMgZjoKICAgICAgICAgICAgICAgIGYud3JpdGUoJ3NvbWV0aGluZ1xuJykKICAgICAgICAgICAgb3MubGluayhzb3VyY2VfZmlsZSwgdGFyZ2V0X2ZpbGUpCiAgICAgICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0ZW1wYXJjaGl2ZSwndycpCiAgICAgICAgICAgIHRhci5hZGQoc291cmNlX2ZpbGUsIGFyY25hbWU9b3MucGF0aC5iYXNlbmFtZShzb3VyY2VfZmlsZSkpCiAgICAgICAgICAgIHRhci5hZGQodGFyZ2V0X2ZpbGUsIGFyY25hbWU9b3MucGF0aC5iYXNlbmFtZSh0YXJnZXRfZmlsZSkpCiAgICAgICAgICAgIHRhci5jbG9zZSgpCiAgICAgICAgICAgICMgTGV0J3MgZXh0cmFjdCBpdCB0byB0aGUgbG9jYXRpb24gd2hpY2ggY29udGFpbnMgdGhlIHN5bWxpbmsKICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRlbXBhcmNoaXZlLCdyJykKICAgICAgICAgICAgIyB0aGlzIHNob3VsZCBub3QgcmFpc2UgT1NFcnJvcjogW0Vycm5vIDE3XSBGaWxlIGV4aXN0cwogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0YXIuZXh0cmFjdGFsbChwYXRoPXRlbXBkaXIpCiAgICAgICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICAgICAgc2VsZi5mYWlsKCJleHRyYWN0YWxsIGZhaWxlZCB3aXRoIGxpbmtlZCBmaWxlcyIpCiAgICAgICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgICAgICB0YXIuY2xvc2UoKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIG9zLnVubGluayh0ZW1wYXJjaGl2ZSkKICAgICAgICAgICAgc2h1dGlsLnJtdHJlZSh0ZW1wZGlyKQoKICAgIGRlZiB0ZXN0X29wZW5fbm9ud3JpdGFibGVfZmlsZW9iaihzZWxmKToKICAgICAgICBmb3IgZXhjdHlwZSBpbiBJT0Vycm9yLCBFT0ZFcnJvciwgUnVudGltZUVycm9yOgogICAgICAgICAgICBjbGFzcyBCYWRGaWxlKFN0cmluZ0lPLlN0cmluZ0lPKToKICAgICAgICAgICAgICAgIGZpcnN0ID0gVHJ1ZQogICAgICAgICAgICAgICAgZGVmIHdyaXRlKHNlbGYsIGRhdGEpOgogICAgICAgICAgICAgICAgICAgIGlmIHNlbGYuZmlyc3Q6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZmlyc3QgPSBGYWxzZQogICAgICAgICAgICAgICAgICAgICAgICByYWlzZSBleGN0eXBlCgogICAgICAgICAgICBmID0gQmFkRmlsZSgpCiAgICAgICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoZXhjdHlwZSk6CiAgICAgICAgICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odG1wbmFtZSwgc2VsZi5tb2RlLCBmaWxlb2JqPWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0PXRhcmZpbGUuUEFYX0ZPUk1BVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXhfaGVhZGVycz17J25vbic6ICdlbXB0eSd9KQogICAgICAgICAgICBzZWxmLmFzc2VydEZhbHNlKGYuY2xvc2VkKQoKY2xhc3MgU3RyZWFtV3JpdGVUZXN0KFdyaXRlVGVzdEJhc2UpOgoKICAgIG1vZGUgPSAid3wiCgogICAgZGVmIHRlc3Rfc3RyZWFtX3BhZGRpbmcoc2VsZik6CiAgICAgICAgIyBUZXN0IGZvciBidWcgIzE1NDMzMDMuCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsIHNlbGYubW9kZSkKICAgICAgICB0YXIuY2xvc2UoKQoKICAgICAgICBpZiBzZWxmLm1vZGUuZW5kc3dpdGgoImd6Iik6CiAgICAgICAgICAgIGZvYmogPSBnemlwLkd6aXBGaWxlKHRtcG5hbWUpCiAgICAgICAgICAgIGRhdGEgPSBmb2JqLnJlYWQoKQogICAgICAgICAgICBmb2JqLmNsb3NlKCkKICAgICAgICBlbGlmIHNlbGYubW9kZS5lbmRzd2l0aCgiYnoyIik6CiAgICAgICAgICAgIGRlYyA9IGJ6Mi5CWjJEZWNvbXByZXNzb3IoKQogICAgICAgICAgICBkYXRhID0gb3Blbih0bXBuYW1lLCAicmIiKS5yZWFkKCkKICAgICAgICAgICAgZGF0YSA9IGRlYy5kZWNvbXByZXNzKGRhdGEpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShsZW4oZGVjLnVudXNlZF9kYXRhKSA9PSAwLAogICAgICAgICAgICAgICAgICAgICJmb3VuZCB0cmFpbGluZyBkYXRhIikKICAgICAgICBlbHNlOgogICAgICAgICAgICBmb2JqID0gb3Blbih0bXBuYW1lLCAicmIiKQogICAgICAgICAgICBkYXRhID0gZm9iai5yZWFkKCkKICAgICAgICAgICAgZm9iai5jbG9zZSgpCgogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShkYXRhLmNvdW50KCJcMCIpID09IHRhcmZpbGUuUkVDT1JEU0laRSwKICAgICAgICAgICAgICAgICAgICAgICAgICJpbmNvcnJlY3QgemVybyBwYWRkaW5nIikKCiAgICBAdW5pdHRlc3Quc2tpcElmKHN5cy5wbGF0Zm9ybSA9PSAnd2luMzInLCAnbm90IGFwcHJvcHJpYXRlIGZvciBXaW5kb3dzJykKICAgIEB1bml0dGVzdC5za2lwVW5sZXNzKGhhc2F0dHIob3MsICd1bWFzaycpLCAncmVxdWlyZXMgb3MudW1hc2snKQogICAgZGVmIHRlc3RfZmlsZV9tb2RlKHNlbGYpOgogICAgICAgICMgVGVzdCBmb3IgaXNzdWUgIzg0NjQ6IENyZWF0ZSBmaWxlcyB3aXRoIGNvcnJlY3QKICAgICAgICAjIHBlcm1pc3Npb25zLgogICAgICAgIGlmIG9zLnBhdGguZXhpc3RzKHRtcG5hbWUpOgogICAgICAgICAgICBvcy5yZW1vdmUodG1wbmFtZSkKCiAgICAgICAgb3JpZ2luYWxfdW1hc2sgPSBvcy51bWFzaygwMDIyKQogICAgICAgIHRyeToKICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsIHNlbGYubW9kZSkKICAgICAgICAgICAgdGFyLmNsb3NlKCkKICAgICAgICAgICAgbW9kZSA9IG9zLnN0YXQodG1wbmFtZSkuc3RfbW9kZSAmIDA3NzcKICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChtb2RlLCAwNjQ0LCAid3JvbmcgZmlsZSBwZXJtaXNzaW9ucyIpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgb3MudW1hc2sob3JpZ2luYWxfdW1hc2spCgogICAgZGVmIHRlc3RfaXNzdWUxMzYzOShzZWxmKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHdpdGggdGFyZmlsZS5vcGVuKHVuaWNvZGUodG1wbmFtZSwgc3lzLmdldGZpbGVzeXN0ZW1lbmNvZGluZygpKSwgc2VsZi5tb2RlKToKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICBleGNlcHQgVW5pY29kZURlY29kZUVycm9yOgogICAgICAgICAgICBzZWxmLmZhaWwoIl9TdHJlYW0gZmFpbGVkIHRvIHdyaXRlIHVuaWNvZGUgZmlsZW5hbWUiKQoKCmNsYXNzIEdOVVdyaXRlVGVzdCh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICAjIFRoaXMgdGVzdGNhc2UgY2hlY2tzIGZvciBjb3JyZWN0IGNyZWF0aW9uIG9mIEdOVSBMb25nbmFtZQogICAgIyBhbmQgTG9uZ2xpbmsgZXh0ZW5kZWQgaGVhZGVycyAoY3AuIGJ1ZyAjODEyMzI1KS4KCiAgICBkZWYgX2xlbmd0aChzZWxmLCBzKToKICAgICAgICBibG9ja3MsIHJlbWFpbmRlciA9IGRpdm1vZChsZW4ocykgKyAxLCA1MTIpCiAgICAgICAgaWYgcmVtYWluZGVyOgogICAgICAgICAgICBibG9ja3MgKz0gMQogICAgICAgIHJldHVybiBibG9ja3MgKiA1MTIKCiAgICBkZWYgX2NhbGNfc2l6ZShzZWxmLCBuYW1lLCBsaW5rPU5vbmUpOgogICAgICAgICMgSW5pdGlhbCB0YXIgaGVhZGVyCiAgICAgICAgY291bnQgPSA1MTIKCiAgICAgICAgaWYgbGVuKG5hbWUpID4gdGFyZmlsZS5MRU5HVEhfTkFNRToKICAgICAgICAgICAgIyBHTlUgbG9uZ25hbWUgZXh0ZW5kZWQgaGVhZGVyICsgbG9uZ25hbWUKICAgICAgICAgICAgY291bnQgKz0gNTEyCiAgICAgICAgICAgIGNvdW50ICs9IHNlbGYuX2xlbmd0aChuYW1lKQogICAgICAgIGlmIGxpbmsgaXMgbm90IE5vbmUgYW5kIGxlbihsaW5rKSA+IHRhcmZpbGUuTEVOR1RIX0xJTks6CiAgICAgICAgICAgICMgR05VIGxvbmdsaW5rIGV4dGVuZGVkIGhlYWRlciArIGxvbmdsaW5rCiAgICAgICAgICAgIGNvdW50ICs9IDUxMgogICAgICAgICAgICBjb3VudCArPSBzZWxmLl9sZW5ndGgobGluaykKICAgICAgICByZXR1cm4gY291bnQKCiAgICBkZWYgX3Rlc3Qoc2VsZiwgbmFtZSwgbGluaz1Ob25lKToKICAgICAgICB0YXJpbmZvID0gdGFyZmlsZS5UYXJJbmZvKG5hbWUpCiAgICAgICAgaWYgbGluazoKICAgICAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9IGxpbmsKICAgICAgICAgICAgdGFyaW5mby50eXBlID0gdGFyZmlsZS5MTktUWVBFCgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCAidyIpCiAgICAgICAgdGFyLmZvcm1hdCA9IHRhcmZpbGUuR05VX0ZPUk1BVAogICAgICAgIHRhci5hZGRmaWxlKHRhcmluZm8pCgogICAgICAgIHYxID0gc2VsZi5fY2FsY19zaXplKG5hbWUsIGxpbmspCiAgICAgICAgdjIgPSB0YXIub2Zmc2V0CiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHYxID09IHYyLCAiR05VIGxvbmduYW1lL2xvbmdsaW5rIGNyZWF0aW9uIGZhaWxlZCIpCgogICAgICAgIHRhci5jbG9zZSgpCgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lKQogICAgICAgIG1lbWJlciA9IHRhci5uZXh0KCkKICAgICAgICBzZWxmLmFzc2VydElzTm90Tm9uZShtZW1iZXIsCiAgICAgICAgICAgICAgICAidW5hYmxlIHRvIHJlYWQgbG9uZ25hbWUgbWVtYmVyIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8ubmFtZSwgbWVtYmVyLm5hbWUsCiAgICAgICAgICAgICAgICAidW5hYmxlIHRvIHJlYWQgbG9uZ25hbWUgbWVtYmVyIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhcmluZm8ubGlua25hbWUsIG1lbWJlci5saW5rbmFtZSwKICAgICAgICAgICAgICAgICJ1bmFibGUgdG8gcmVhZCBsb25nbmFtZSBtZW1iZXIiKQoKICAgIGRlZiB0ZXN0X2xvbmduYW1lXzEwMjMoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdCgoImxvbmduYW0vIiAqIDEyNykgKyAibG9uZ25hbSIpCgogICAgZGVmIHRlc3RfbG9uZ25hbWVfMTAyNChzZWxmKToKICAgICAgICBzZWxmLl90ZXN0KCgibG9uZ25hbS8iICogMTI3KSArICJsb25nbmFtZSIpCgogICAgZGVmIHRlc3RfbG9uZ25hbWVfMTAyNShzZWxmKToKICAgICAgICBzZWxmLl90ZXN0KCgibG9uZ25hbS8iICogMTI3KSArICJsb25nbmFtZV8iKQoKICAgIGRlZiB0ZXN0X2xvbmdsaW5rXzEwMjMoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdCgibmFtZSIsICgibG9uZ2xuay8iICogMTI3KSArICJsb25nbG5rIikKCiAgICBkZWYgdGVzdF9sb25nbGlua18xMDI0KHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3QoIm5hbWUiLCAoImxvbmdsbmsvIiAqIDEyNykgKyAibG9uZ2xpbmsiKQoKICAgIGRlZiB0ZXN0X2xvbmdsaW5rXzEwMjUoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdCgibmFtZSIsICgibG9uZ2xuay8iICogMTI3KSArICJsb25nbGlua18iKQoKICAgIGRlZiB0ZXN0X2xvbmduYW1lbGlua18xMDIzKHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3QoKCJsb25nbmFtLyIgKiAxMjcpICsgImxvbmduYW0iLAogICAgICAgICAgICAgICAgICAgKCJsb25nbG5rLyIgKiAxMjcpICsgImxvbmdsbmsiKQoKICAgIGRlZiB0ZXN0X2xvbmduYW1lbGlua18xMDI0KHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3QoKCJsb25nbmFtLyIgKiAxMjcpICsgImxvbmduYW1lIiwKICAgICAgICAgICAgICAgICAgICgibG9uZ2xuay8iICogMTI3KSArICJsb25nbGluayIpCgogICAgZGVmIHRlc3RfbG9uZ25hbWVsaW5rXzEwMjUoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdCgoImxvbmduYW0vIiAqIDEyNykgKyAibG9uZ25hbWVfIiwKICAgICAgICAgICAgICAgICAgICgibG9uZ2xuay8iICogMTI3KSArICJsb25nbGlua18iKQoKCmNsYXNzIEhhcmRsaW5rVGVzdCh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICAjIFRlc3QgdGhlIGNyZWF0aW9uIG9mIExOS1RZUEUgKGhhcmRsaW5rKSBtZW1iZXJzIGluIGFuIGFyY2hpdmUuCgogICAgZGVmIHNldFVwKHNlbGYpOgogICAgICAgIHNlbGYuZm9vID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJmb28iKQogICAgICAgIHNlbGYuYmFyID0gb3MucGF0aC5qb2luKFRFTVBESVIsICJiYXIiKQoKICAgICAgICBmb2JqID0gb3BlbihzZWxmLmZvbywgIndiIikKICAgICAgICBmb2JqLndyaXRlKCJmb28iKQogICAgICAgIGZvYmouY2xvc2UoKQoKICAgICAgICBvcy5saW5rKHNlbGYuZm9vLCBzZWxmLmJhcikKCiAgICAgICAgc2VsZi50YXIgPSB0YXJmaWxlLm9wZW4odG1wbmFtZSwgInciKQogICAgICAgIHNlbGYudGFyLmFkZChzZWxmLmZvbykKCiAgICBkZWYgdGVhckRvd24oc2VsZik6CiAgICAgICAgc2VsZi50YXIuY2xvc2UoKQogICAgICAgIG9zLnJlbW92ZShzZWxmLmZvbykKICAgICAgICBvcy5yZW1vdmUoc2VsZi5iYXIpCgogICAgZGVmIHRlc3RfYWRkX3R3aWNlKHNlbGYpOgogICAgICAgICMgVGhlIHNhbWUgbmFtZSB3aWxsIGJlIGFkZGVkIGFzIGEgUkVHVFlQRSBldmVyeQogICAgICAgICMgdGltZSByZWdhcmRsZXNzIG9mIHN0X25saW5rLgogICAgICAgIHRhcmluZm8gPSBzZWxmLnRhci5nZXR0YXJpbmZvKHNlbGYuZm9vKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0YXJpbmZvLnR5cGUgPT0gdGFyZmlsZS5SRUdUWVBFLAogICAgICAgICAgICAgICAgImFkZCBmaWxlIGFzIHJlZ3VsYXIgZmFpbGVkIikKCiAgICBkZWYgdGVzdF9hZGRfaGFyZGxpbmsoc2VsZik6CiAgICAgICAgdGFyaW5mbyA9IHNlbGYudGFyLmdldHRhcmluZm8oc2VsZi5iYXIpCiAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHRhcmluZm8udHlwZSA9PSB0YXJmaWxlLkxOS1RZUEUsCiAgICAgICAgICAgICAgICAiYWRkIGZpbGUgYXMgaGFyZGxpbmsgZmFpbGVkIikKCiAgICBkZWYgdGVzdF9kZXJlZmVyZW5jZV9oYXJkbGluayhzZWxmKToKICAgICAgICBzZWxmLnRhci5kZXJlZmVyZW5jZSA9IFRydWUKICAgICAgICB0YXJpbmZvID0gc2VsZi50YXIuZ2V0dGFyaW5mbyhzZWxmLmJhcikKICAgICAgICBzZWxmLmFzc2VydFRydWUodGFyaW5mby50eXBlID09IHRhcmZpbGUuUkVHVFlQRSwKICAgICAgICAgICAgICAgICJkZXJlZmVyZW5jaW5nIGhhcmRsaW5rIGZhaWxlZCIpCgoKY2xhc3MgUGF4V3JpdGVUZXN0KEdOVVdyaXRlVGVzdCk6CgogICAgZGVmIF90ZXN0KHNlbGYsIG5hbWUsIGxpbms9Tm9uZSk6CiAgICAgICAgIyBTZWUgR05VV3JpdGVUZXN0LgogICAgICAgIHRhcmluZm8gPSB0YXJmaWxlLlRhckluZm8obmFtZSkKICAgICAgICBpZiBsaW5rOgogICAgICAgICAgICB0YXJpbmZvLmxpbmtuYW1lID0gbGluawogICAgICAgICAgICB0YXJpbmZvLnR5cGUgPSB0YXJmaWxlLkxOS1RZUEUKCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsICJ3IiwgZm9ybWF0PXRhcmZpbGUuUEFYX0ZPUk1BVCkKICAgICAgICB0YXIuYWRkZmlsZSh0YXJpbmZvKQogICAgICAgIHRhci5jbG9zZSgpCgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lKQogICAgICAgIGlmIGxpbms6CiAgICAgICAgICAgIGwgPSB0YXIuZ2V0bWVtYmVycygpWzBdLmxpbmtuYW1lCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShsaW5rID09IGwsICJQQVggbG9uZ2xpbmsgY3JlYXRpb24gZmFpbGVkIikKICAgICAgICBlbHNlOgogICAgICAgICAgICBuID0gdGFyLmdldG1lbWJlcnMoKVswXS5uYW1lCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZShuYW1lID09IG4sICJQQVggbG9uZ25hbWUgY3JlYXRpb24gZmFpbGVkIikKCiAgICBkZWYgdGVzdF9wYXhfZ2xvYmFsX2hlYWRlcihzZWxmKToKICAgICAgICBwYXhfaGVhZGVycyA9IHsKICAgICAgICAgICAgICAgIHUiZm9vIjogdSJiYXIiLAogICAgICAgICAgICAgICAgdSJ1aWQiOiB1IjAiLAogICAgICAgICAgICAgICAgdSJtdGltZSI6IHUiMS4yMyIsCiAgICAgICAgICAgICAgICB1InRlc3QiOiB1IuT2/CIsCiAgICAgICAgICAgICAgICB1IuT2/CI6IHUidGVzdCJ9CgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCAidyIsIGZvcm1hdD10YXJmaWxlLlBBWF9GT1JNQVQsCiAgICAgICAgICAgICAgICBwYXhfaGVhZGVycz1wYXhfaGVhZGVycykKICAgICAgICB0YXIuYWRkZmlsZSh0YXJmaWxlLlRhckluZm8oInRlc3QiKSkKICAgICAgICB0YXIuY2xvc2UoKQoKICAgICAgICAjIFRlc3QgaWYgdGhlIGdsb2JhbCBoZWFkZXIgd2FzIHdyaXR0ZW4gY29ycmVjdGx5LgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCBlbmNvZGluZz0iaXNvODg1OS0xIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhci5wYXhfaGVhZGVycywgcGF4X2hlYWRlcnMpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXIuZ2V0bWVtYmVycygpWzBdLnBheF9oZWFkZXJzLCBwYXhfaGVhZGVycykKCiAgICAgICAgIyBUZXN0IGlmIGFsbCB0aGUgZmllbGRzIGFyZSB1bmljb2RlLgogICAgICAgIGZvciBrZXksIHZhbCBpbiB0YXIucGF4X2hlYWRlcnMuaXRlcml0ZW1zKCk6CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0eXBlKGtleSkgaXMgdW5pY29kZSkKICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHR5cGUodmFsKSBpcyB1bmljb2RlKQogICAgICAgICAgICBpZiBrZXkgaW4gdGFyZmlsZS5QQVhfTlVNQkVSX0ZJRUxEUzoKICAgICAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgICAgICB0YXJmaWxlLlBBWF9OVU1CRVJfRklFTERTW2tleV0odmFsKQogICAgICAgICAgICAgICAgZXhjZXB0IChUeXBlRXJyb3IsIFZhbHVlRXJyb3IpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuZmFpbCgidW5hYmxlIHRvIGNvbnZlcnQgcGF4IGhlYWRlciBmaWVsZCIpCgogICAgZGVmIHRlc3RfcGF4X2V4dGVuZGVkX2hlYWRlcihzZWxmKToKICAgICAgICAjIFRoZSBmaWVsZHMgZnJvbSB0aGUgcGF4IGhlYWRlciBoYXZlIHByaW9yaXR5IG92ZXIgdGhlCiAgICAgICAgIyBUYXJJbmZvLgogICAgICAgIHBheF9oZWFkZXJzID0ge3UicGF0aCI6IHUiZm9vIiwgdSJ1aWQiOiB1IjEyMyJ9CgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCAidyIsIGZvcm1hdD10YXJmaWxlLlBBWF9GT1JNQVQsIGVuY29kaW5nPSJpc284ODU5LTEiKQogICAgICAgIHQgPSB0YXJmaWxlLlRhckluZm8oKQogICAgICAgIHQubmFtZSA9IHUi5Pb8IiAgICAgIyBub24tQVNDSUkKICAgICAgICB0LnVpZCA9IDgqKjggICAgICAgICMgdG9vIGxhcmdlCiAgICAgICAgdC5wYXhfaGVhZGVycyA9IHBheF9oZWFkZXJzCiAgICAgICAgdGFyLmFkZGZpbGUodCkKICAgICAgICB0YXIuY2xvc2UoKQoKICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odG1wbmFtZSwgZW5jb2Rpbmc9Imlzbzg4NTktMSIpCiAgICAgICAgdCA9IHRhci5nZXRtZW1iZXJzKClbMF0KICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHQucGF4X2hlYWRlcnMsIHBheF9oZWFkZXJzKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodC5uYW1lLCAiZm9vIikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHQudWlkLCAxMjMpCgoKY2xhc3MgVXN0YXJVbmljb2RlVGVzdCh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICAjIEFsbCAqVW5pY29kZVRlc3RzIEZJWE1FCgogICAgZm9ybWF0ID0gdGFyZmlsZS5VU1RBUl9GT1JNQVQKCiAgICBkZWYgdGVzdF9pc284ODU5XzFfZmlsZW5hbWUoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdF91bmljb2RlX2ZpbGVuYW1lKCJpc284ODU5LTEiKQoKICAgIGRlZiB0ZXN0X3V0ZjdfZmlsZW5hbWUoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdF91bmljb2RlX2ZpbGVuYW1lKCJ1dGY3IikKCiAgICBkZWYgdGVzdF91dGY4X2ZpbGVuYW1lKHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3RfdW5pY29kZV9maWxlbmFtZSgidXRmOCIpCgogICAgZGVmIF90ZXN0X3VuaWNvZGVfZmlsZW5hbWUoc2VsZiwgZW5jb2RpbmcpOgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCAidyIsIGZvcm1hdD1zZWxmLmZvcm1hdCwgZW5jb2Rpbmc9ZW5jb2RpbmcsIGVycm9ycz0ic3RyaWN0IikKICAgICAgICBuYW1lID0gdSLk9vwiCiAgICAgICAgdGFyLmFkZGZpbGUodGFyZmlsZS5UYXJJbmZvKG5hbWUpKQogICAgICAgIHRhci5jbG9zZSgpCgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCBlbmNvZGluZz1lbmNvZGluZykKICAgICAgICBzZWxmLmFzc2VydFRydWUodHlwZSh0YXIuZ2V0bmFtZXMoKVswXSkgaXMgbm90IHVuaWNvZGUpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXIuZ2V0bWVtYmVycygpWzBdLm5hbWUsIG5hbWUuZW5jb2RlKGVuY29kaW5nKSkKICAgICAgICB0YXIuY2xvc2UoKQoKICAgIGRlZiB0ZXN0X3VuaWNvZGVfZmlsZW5hbWVfZXJyb3Ioc2VsZik6CiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsICJ3IiwgZm9ybWF0PXNlbGYuZm9ybWF0LCBlbmNvZGluZz0iYXNjaWkiLCBlcnJvcnM9InN0cmljdCIpCiAgICAgICAgdGFyaW5mbyA9IHRhcmZpbGUuVGFySW5mbygpCgogICAgICAgIHRhcmluZm8ubmFtZSA9ICLk9vwiCiAgICAgICAgaWYgc2VsZi5mb3JtYXQgPT0gdGFyZmlsZS5QQVhfRk9STUFUOgogICAgICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhVbmljb2RlRXJyb3IsIHRhci5hZGRmaWxlLCB0YXJpbmZvKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHRhci5hZGRmaWxlKHRhcmluZm8pCgogICAgICAgIHRhcmluZm8ubmFtZSA9IHUi5Pb8IgogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFVuaWNvZGVFcnJvciwgdGFyLmFkZGZpbGUsIHRhcmluZm8pCgogICAgICAgIHRhcmluZm8ubmFtZSA9ICJmb28iCiAgICAgICAgdGFyaW5mby51bmFtZSA9IHUi5Pb8IgogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFVuaWNvZGVFcnJvciwgdGFyLmFkZGZpbGUsIHRhcmluZm8pCgogICAgZGVmIHRlc3RfdW5pY29kZV9hcmd1bWVudChzZWxmKToKICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4odGFybmFtZSwgInIiLCBlbmNvZGluZz0iaXNvODg1OS0xIiwgZXJyb3JzPSJzdHJpY3QiKQogICAgICAgIGZvciB0IGluIHRhcjoKICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHR5cGUodC5uYW1lKSBpcyBzdHIpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0eXBlKHQubGlua25hbWUpIGlzIHN0cikKICAgICAgICAgICAgc2VsZi5hc3NlcnRUcnVlKHR5cGUodC51bmFtZSkgaXMgc3RyKQogICAgICAgICAgICBzZWxmLmFzc2VydFRydWUodHlwZSh0LmduYW1lKSBpcyBzdHIpCiAgICAgICAgdGFyLmNsb3NlKCkKCiAgICBkZWYgdGVzdF91bmFtZV91bmljb2RlKHNlbGYpOgogICAgICAgIGZvciBuYW1lIGluICh1IuT2/CIsICLk9vwiKToKICAgICAgICAgICAgdCA9IHRhcmZpbGUuVGFySW5mbygiZm9vIikKICAgICAgICAgICAgdC51bmFtZSA9IG5hbWUKICAgICAgICAgICAgdC5nbmFtZSA9IG5hbWUKCiAgICAgICAgICAgIGZvYmogPSBTdHJpbmdJTy5TdHJpbmdJTygpCiAgICAgICAgICAgIHRhciA9IHRhcmZpbGUub3BlbigiZm9vLnRhciIsIG1vZGU9InciLCBmaWxlb2JqPWZvYmosIGZvcm1hdD1zZWxmLmZvcm1hdCwgZW5jb2Rpbmc9Imlzbzg4NTktMSIpCiAgICAgICAgICAgIHRhci5hZGRmaWxlKHQpCiAgICAgICAgICAgIHRhci5jbG9zZSgpCiAgICAgICAgICAgIGZvYmouc2VlaygwKQoKICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKCJmb28udGFyIiwgZmlsZW9iaj1mb2JqLCBlbmNvZGluZz0iaXNvODg1OS0xIikKICAgICAgICAgICAgdCA9IHRhci5nZXRtZW1iZXIoImZvbyIpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodC51bmFtZSwgIuT2/CIpCiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodC5nbmFtZSwgIuT2/CIpCgoKY2xhc3MgR05VVW5pY29kZVRlc3QoVXN0YXJVbmljb2RlVGVzdCk6CgogICAgZm9ybWF0ID0gdGFyZmlsZS5HTlVfRk9STUFUCgoKY2xhc3MgUGF4VW5pY29kZVRlc3QoVXN0YXJVbmljb2RlVGVzdCk6CgogICAgZm9ybWF0ID0gdGFyZmlsZS5QQVhfRk9STUFUCgogICAgZGVmIF9jcmVhdGVfdW5pY29kZV9uYW1lKHNlbGYsIG5hbWUpOgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0bXBuYW1lLCAidyIsIGZvcm1hdD1zZWxmLmZvcm1hdCkKICAgICAgICB0ID0gdGFyZmlsZS5UYXJJbmZvKCkKICAgICAgICB0LnBheF9oZWFkZXJzWyJwYXRoIl0gPSBuYW1lCiAgICAgICAgdGFyLmFkZGZpbGUodCkKICAgICAgICB0YXIuY2xvc2UoKQoKICAgIGRlZiB0ZXN0X2Vycm9yX2hhbmRsZXJzKHNlbGYpOgogICAgICAgICMgVGVzdCBpZiB0aGUgdW5pY29kZSBlcnJvciBoYW5kbGVycyB3b3JrIGNvcnJlY3RseSBmb3IgY2hhcmFjdGVycwogICAgICAgICMgdGhhdCBjYW5ub3QgYmUgZXhwcmVzc2VkIGluIGEgZ2l2ZW4gZW5jb2RpbmcuCiAgICAgICAgc2VsZi5fY3JlYXRlX3VuaWNvZGVfbmFtZSh1IuT2/CIpCgogICAgICAgIGZvciBoYW5kbGVyLCBuYW1lIGluICgoInV0Zi04IiwgdSLk9vwiLmVuY29kZSgidXRmOCIpKSwKICAgICAgICAgICAgICAgICAgICAoInJlcGxhY2UiLCAiPz8/IiksICgiaWdub3JlIiwgIiIpKToKICAgICAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsIGZvcm1hdD1zZWxmLmZvcm1hdCwgZW5jb2Rpbmc9ImFzY2lpIiwKICAgICAgICAgICAgICAgICAgICBlcnJvcnM9aGFuZGxlcikKICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXIuZ2V0bmFtZXMoKVswXSwgbmFtZSkKCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVW5pY29kZUVycm9yLCB0YXJmaWxlLm9wZW4sIHRtcG5hbWUsCiAgICAgICAgICAgICAgICBlbmNvZGluZz0iYXNjaWkiLCBlcnJvcnM9InN0cmljdCIpCgogICAgZGVmIHRlc3RfZXJyb3JfaGFuZGxlcl91dGY4KHNlbGYpOgogICAgICAgICMgQ3JlYXRlIGEgcGF0aG5hbWUgdGhhdCBoYXMgb25lIGNvbXBvbmVudCByZXByZXNlbnRhYmxlIHVzaW5nCiAgICAgICAgIyBpc284ODU5LTEgYW5kIHRoZSBvdGhlciBvbmx5IGluIGlzbzg4NTktMTUuCiAgICAgICAgc2VsZi5fY3JlYXRlX3VuaWNvZGVfbmFtZSh1IuT2/C+kIikKCiAgICAgICAgdGFyID0gdGFyZmlsZS5vcGVuKHRtcG5hbWUsIGZvcm1hdD1zZWxmLmZvcm1hdCwgZW5jb2Rpbmc9Imlzbzg4NTktMSIsCiAgICAgICAgICAgICAgICBlcnJvcnM9InV0Zi04IikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHRhci5nZXRuYW1lcygpWzBdLCAi5Pb8LyIgKyB1IqQiLmVuY29kZSgidXRmOCIpKQoKCmNsYXNzIEFwcGVuZFRlc3QodW5pdHRlc3QuVGVzdENhc2UpOgogICAgIyBUZXN0IGFwcGVuZCBtb2RlIChjcC4gcGF0Y2ggIzE2NTI2ODEpLgoKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLnRhcm5hbWUgPSB0bXBuYW1lCiAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoc2VsZi50YXJuYW1lKToKICAgICAgICAgICAgb3MucmVtb3ZlKHNlbGYudGFybmFtZSkKCiAgICBkZWYgX2FkZF90ZXN0ZmlsZShzZWxmLCBmaWxlb2JqPU5vbmUpOgogICAgICAgIHRhciA9IHRhcmZpbGUub3BlbihzZWxmLnRhcm5hbWUsICJhIiwgZmlsZW9iaj1maWxlb2JqKQogICAgICAgIHRhci5hZGRmaWxlKHRhcmZpbGUuVGFySW5mbygiYmFyIikpCiAgICAgICAgdGFyLmNsb3NlKCkKCiAgICBkZWYgX2NyZWF0ZV90ZXN0dGFyKHNlbGYsIG1vZGU9Inc6Iik6CiAgICAgICAgc3JjID0gdGFyZmlsZS5vcGVuKHRhcm5hbWUsIGVuY29kaW5nPSJpc284ODU5LTEiKQogICAgICAgIHQgPSBzcmMuZ2V0bWVtYmVyKCJ1c3Rhci9yZWd0eXBlIikKICAgICAgICB0Lm5hbWUgPSAiZm9vIgogICAgICAgIGYgPSBzcmMuZXh0cmFjdGZpbGUodCkKICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4oc2VsZi50YXJuYW1lLCBtb2RlKQogICAgICAgIHRhci5hZGRmaWxlKHQsIGYpCiAgICAgICAgdGFyLmNsb3NlKCkKCiAgICBkZWYgX3Rlc3Qoc2VsZiwgbmFtZXM9WyJiYXIiXSwgZmlsZW9iaj1Ob25lKToKICAgICAgICB0YXIgPSB0YXJmaWxlLm9wZW4oc2VsZi50YXJuYW1lLCBmaWxlb2JqPWZpbGVvYmopCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh0YXIuZ2V0bmFtZXMoKSwgbmFtZXMpCgogICAgZGVmIHRlc3Rfbm9uX2V4aXN0aW5nKHNlbGYpOgogICAgICAgIHNlbGYuX2FkZF90ZXN0ZmlsZSgpCiAgICAgICAgc2VsZi5fdGVzdCgpCgogICAgZGVmIHRlc3RfZW1wdHkoc2VsZik6CiAgICAgICAgdGFyZmlsZS5vcGVuKHNlbGYudGFybmFtZSwgInc6IikuY2xvc2UoKQogICAgICAgIHNlbGYuX2FkZF90ZXN0ZmlsZSgpCiAgICAgICAgc2VsZi5fdGVzdCgpCgogICAgZGVmIHRlc3RfZW1wdHlfZmlsZW9iaihzZWxmKToKICAgICAgICBmb2JqID0gU3RyaW5nSU8uU3RyaW5nSU8oIlwwIiAqIDEwMjQpCiAgICAgICAgc2VsZi5fYWRkX3Rlc3RmaWxlKGZvYmopCiAgICAgICAgZm9iai5zZWVrKDApCiAgICAgICAgc2VsZi5fdGVzdChmaWxlb2JqPWZvYmopCgogICAgZGVmIHRlc3RfZmlsZW9iaihzZWxmKToKICAgICAgICBzZWxmLl9jcmVhdGVfdGVzdHRhcigpCiAgICAgICAgZGF0YSA9IG9wZW4oc2VsZi50YXJuYW1lKS5yZWFkKCkKICAgICAgICBmb2JqID0gU3RyaW5nSU8uU3RyaW5nSU8oZGF0YSkKICAgICAgICBzZWxmLl9hZGRfdGVzdGZpbGUoZm9iaikKICAgICAgICBmb2JqLnNlZWsoMCkKICAgICAgICBzZWxmLl90ZXN0KG5hbWVzPVsiZm9vIiwgImJhciJdLCBmaWxlb2JqPWZvYmopCgogICAgZGVmIHRlc3RfZXhpc3Rpbmcoc2VsZik6CiAgICAgICAgc2VsZi5fY3JlYXRlX3Rlc3R0YXIoKQogICAgICAgIHNlbGYuX2FkZF90ZXN0ZmlsZSgpCiAgICAgICAgc2VsZi5fdGVzdChuYW1lcz1bImZvbyIsICJiYXIiXSkKCiAgICBAdW5pdHRlc3Quc2tpcFVubGVzcyhnemlwLCAncmVxdWlyZXMgZ3ppcCcpCiAgICBkZWYgdGVzdF9hcHBlbmRfZ3ooc2VsZik6CiAgICAgICAgc2VsZi5fY3JlYXRlX3Rlc3R0YXIoInc6Z3oiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRhcmZpbGUuUmVhZEVycm9yLCB0YXJmaWxlLm9wZW4sIHRtcG5hbWUsICJhIikKCiAgICBAdW5pdHRlc3Quc2tpcFVubGVzcyhiejIsICdyZXF1aXJlcyBiejInKQogICAgZGVmIHRlc3RfYXBwZW5kX2J6MihzZWxmKToKICAgICAgICBzZWxmLl9jcmVhdGVfdGVzdHRhcigidzpiejIiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHRhcmZpbGUuUmVhZEVycm9yLCB0YXJmaWxlLm9wZW4sIHRtcG5hbWUsICJhIikKCiAgICAjIEFwcGVuZCBtb2RlIGlzIHN1cHBvc2VkIHRvIGZhaWwgaWYgdGhlIHRhcmZpbGUgdG8gYXBwZW5kIHRvCiAgICAjIGRvZXMgbm90IGVuZCB3aXRoIGEgemVybyBibG9jay4KICAgIGRlZiBfdGVzdF9lcnJvcihzZWxmLCBkYXRhKToKICAgICAgICBvcGVuKHNlbGYudGFybmFtZSwgIndiIikud3JpdGUoZGF0YSkKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyh0YXJmaWxlLlJlYWRFcnJvciwgc2VsZi5fYWRkX3Rlc3RmaWxlKQoKICAgIGRlZiB0ZXN0X251bGwoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdF9lcnJvcigiIikKCiAgICBkZWYgdGVzdF9pbmNvbXBsZXRlKHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3RfZXJyb3IoIlwwIiAqIDEzKQoKICAgIGRlZiB0ZXN0X3ByZW1hdHVyZV9lb2Yoc2VsZik6CiAgICAgICAgZGF0YSA9IHRhcmZpbGUuVGFySW5mbygiZm9vIikudG9idWYoKQogICAgICAgIHNlbGYuX3Rlc3RfZXJyb3IoZGF0YSkKCiAgICBkZWYgdGVzdF90cmFpbGluZ19nYXJiYWdlKHNlbGYpOgogICAgICAgIGRhdGEgPSB0YXJmaWxlLlRhckluZm8oImZvbyIpLnRvYnVmKCkKICAgICAgICBzZWxmLl90ZXN0X2Vycm9yKGRhdGEgKyAiXDAiICogMTMpCgogICAgZGVmIHRlc3RfaW52YWxpZChzZWxmKToKICAgICAgICBzZWxmLl90ZXN0X2Vycm9yKCJhIiAqIDUxMikKCgpjbGFzcyBMaW1pdHNUZXN0KHVuaXR0ZXN0LlRlc3RDYXNlKToKCiAgICBkZWYgdGVzdF91c3Rhcl9saW1pdHMoc2VsZik6CiAgICAgICAgIyAxMDAgY2hhciBuYW1lCiAgICAgICAgdGFyaW5mbyA9IHRhcmZpbGUuVGFySW5mbygiMDEyMzQ1Njc4OSIgKiAxMCkKICAgICAgICB0YXJpbmZvLnRvYnVmKHRhcmZpbGUuVVNUQVJfRk9STUFUKQoKICAgICAgICAjIDEwMSBjaGFyIG5hbWUgdGhhdCBjYW5ub3QgYmUgc3RvcmVkCiAgICAgICAgdGFyaW5mbyA9IHRhcmZpbGUuVGFySW5mbygiMDEyMzQ1Njc4OSIgKiAxMCArICIwIikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCB0YXJpbmZvLnRvYnVmLCB0YXJmaWxlLlVTVEFSX0ZPUk1BVCkKCiAgICAgICAgIyAyNTYgY2hhciBuYW1lIHdpdGggYSBzbGFzaCBhdCBwb3MgMTU2CiAgICAgICAgdGFyaW5mbyA9IHRhcmZpbGUuVGFySW5mbygiMTIzLyIgKiA2MiArICJsb25nbmFtZSIpCiAgICAgICAgdGFyaW5mby50b2J1Zih0YXJmaWxlLlVTVEFSX0ZPUk1BVCkKCiAgICAgICAgIyAyNTYgY2hhciBuYW1lIHRoYXQgY2Fubm90IGJlIHN0b3JlZAogICAgICAgIHRhcmluZm8gPSB0YXJmaWxlLlRhckluZm8oIjEyMzQ1NjcvIiAqIDMxICsgImxvbmduYW1lIikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCB0YXJpbmZvLnRvYnVmLCB0YXJmaWxlLlVTVEFSX0ZPUk1BVCkKCiAgICAgICAgIyA1MTIgY2hhciBuYW1lCiAgICAgICAgdGFyaW5mbyA9IHRhcmZpbGUuVGFySW5mbygiMTIzLyIgKiAxMjYgKyAibG9uZ25hbWUiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIHRhcmluZm8udG9idWYsIHRhcmZpbGUuVVNUQVJfRk9STUFUKQoKICAgICAgICAjIDUxMiBjaGFyIGxpbmtuYW1lCiAgICAgICAgdGFyaW5mbyA9IHRhcmZpbGUuVGFySW5mbygibG9uZ2xpbmsiKQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSAiMTIzLyIgKiAxMjYgKyAibG9uZ25hbWUiCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVmFsdWVFcnJvciwgdGFyaW5mby50b2J1ZiwgdGFyZmlsZS5VU1RBUl9GT1JNQVQpCgogICAgICAgICMgdWlkID4gOCBkaWdpdHMKICAgICAgICB0YXJpbmZvID0gdGFyZmlsZS5UYXJJbmZvKCJuYW1lIikKICAgICAgICB0YXJpbmZvLnVpZCA9IDAxMDAwMDAwMAogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIHRhcmluZm8udG9idWYsIHRhcmZpbGUuVVNUQVJfRk9STUFUKQoKICAgIGRlZiB0ZXN0X2dudV9saW1pdHMoc2VsZik6CiAgICAgICAgdGFyaW5mbyA9IHRhcmZpbGUuVGFySW5mbygiMTIzLyIgKiAxMjYgKyAibG9uZ25hbWUiKQogICAgICAgIHRhcmluZm8udG9idWYodGFyZmlsZS5HTlVfRk9STUFUKQoKICAgICAgICB0YXJpbmZvID0gdGFyZmlsZS5UYXJJbmZvKCJsb25nbGluayIpCiAgICAgICAgdGFyaW5mby5saW5rbmFtZSA9ICIxMjMvIiAqIDEyNiArICJsb25nbmFtZSIKICAgICAgICB0YXJpbmZvLnRvYnVmKHRhcmZpbGUuR05VX0ZPUk1BVCkKCiAgICAgICAgIyB1aWQgPj0gMjU2ICoqIDcKICAgICAgICB0YXJpbmZvID0gdGFyZmlsZS5UYXJJbmZvKCJuYW1lIikKICAgICAgICB0YXJpbmZvLnVpZCA9IDA0MDAwMDAwMDAwMDAwMDAwMDAwTAogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIHRhcmluZm8udG9idWYsIHRhcmZpbGUuR05VX0ZPUk1BVCkKCiAgICBkZWYgdGVzdF9wYXhfbGltaXRzKHNlbGYpOgogICAgICAgIHRhcmluZm8gPSB0YXJmaWxlLlRhckluZm8oIjEyMy8iICogMTI2ICsgImxvbmduYW1lIikKICAgICAgICB0YXJpbmZvLnRvYnVmKHRhcmZpbGUuUEFYX0ZPUk1BVCkKCiAgICAgICAgdGFyaW5mbyA9IHRhcmZpbGUuVGFySW5mbygibG9uZ2xpbmsiKQogICAgICAgIHRhcmluZm8ubGlua25hbWUgPSAiMTIzLyIgKiAxMjYgKyAibG9uZ25hbWUiCiAgICAgICAgdGFyaW5mby50b2J1Zih0YXJmaWxlLlBBWF9GT1JNQVQpCgogICAgICAgIHRhcmluZm8gPSB0YXJmaWxlLlRhckluZm8oIm5hbWUiKQogICAgICAgIHRhcmluZm8udWlkID0gMDQwMDAwMDAwMDAwMDAwMDAwMDBMCiAgICAgICAgdGFyaW5mby50b2J1Zih0YXJmaWxlLlBBWF9GT1JNQVQpCgoKY2xhc3MgQ29udGV4dE1hbmFnZXJUZXN0KHVuaXR0ZXN0LlRlc3RDYXNlKToKCiAgICBkZWYgdGVzdF9iYXNpYyhzZWxmKToKICAgICAgICB3aXRoIHRhcmZpbGUub3Blbih0YXJuYW1lKSBhcyB0YXI6CiAgICAgICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UodGFyLmNsb3NlZCwgImNsb3NlZCBpbnNpZGUgcnVudGltZSBjb250ZXh0IikKICAgICAgICBzZWxmLmFzc2VydFRydWUodGFyLmNsb3NlZCwgImNvbnRleHQgbWFuYWdlciBmYWlsZWQiKQoKICAgIGRlZiB0ZXN0X2Nsb3NlZChzZWxmKToKICAgICAgICAjIFRoZSBfX2VudGVyX18oKSBtZXRob2QgaXMgc3VwcG9zZWQgdG8gcmFpc2UgSU9FcnJvcgogICAgICAgICMgaWYgdGhlIFRhckZpbGUgb2JqZWN0IGlzIGFscmVhZHkgY2xvc2VkLgogICAgICAgIHRhciA9IHRhcmZpbGUub3Blbih0YXJuYW1lKQogICAgICAgIHRhci5jbG9zZSgpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhJT0Vycm9yKToKICAgICAgICAgICAgd2l0aCB0YXI6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgZGVmIHRlc3RfZXhjZXB0aW9uKHNlbGYpOgogICAgICAgICMgVGVzdCBpZiB0aGUgSU9FcnJvciBleGNlcHRpb24gaXMgcGFzc2VkIHRocm91Z2ggcHJvcGVybHkuCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhFeGNlcHRpb24pIGFzIGV4YzoKICAgICAgICAgICAgd2l0aCB0YXJmaWxlLm9wZW4odGFybmFtZSkgYXMgdGFyOgogICAgICAgICAgICAgICAgcmFpc2UgSU9FcnJvcgogICAgICAgIHNlbGYuYXNzZXJ0SXNJbnN0YW5jZShleGMuZXhjZXB0aW9uLCBJT0Vycm9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid3JvbmcgZXhjZXB0aW9uIHJhaXNlZCBpbiBjb250ZXh0IG1hbmFnZXIiKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0YXIuY2xvc2VkLCAiY29udGV4dCBtYW5hZ2VyIGZhaWxlZCIpCgogICAgZGVmIHRlc3Rfbm9fZW9mKHNlbGYpOgogICAgICAgICMgX19leGl0X18oKSBtdXN0IG5vdCB3cml0ZSBlbmQtb2YtYXJjaGl2ZSBibG9ja3MgaWYgYW4KICAgICAgICAjIGV4Y2VwdGlvbiB3YXMgcmFpc2VkLgogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCB0YXJmaWxlLm9wZW4odG1wbmFtZSwgInciKSBhcyB0YXI6CiAgICAgICAgICAgICAgICByYWlzZSBFeGNlcHRpb24KICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKG9zLnBhdGguZ2V0c2l6ZSh0bXBuYW1lKSwgMCwKICAgICAgICAgICAgICAgICJjb250ZXh0IG1hbmFnZXIgd3JvdGUgYW4gZW5kLW9mLWFyY2hpdmUgYmxvY2siKQogICAgICAgIHNlbGYuYXNzZXJ0VHJ1ZSh0YXIuY2xvc2VkLCAiY29udGV4dCBtYW5hZ2VyIGZhaWxlZCIpCgogICAgZGVmIHRlc3RfZW9mKHNlbGYpOgogICAgICAgICMgX19leGl0X18oKSBtdXN0IHdyaXRlIGVuZC1vZi1hcmNoaXZlIGJsb2NrcywgaS5lLiBjYWxsCiAgICAgICAgIyBUYXJGaWxlLmNsb3NlKCkgaWYgdGhlcmUgd2FzIG5vIGVycm9yLgogICAgICAgIHdpdGggdGFyZmlsZS5vcGVuKHRtcG5hbWUsICJ3Iik6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBzZWxmLmFzc2VydE5vdEVxdWFsKG9zLnBhdGguZ2V0c2l6ZSh0bXBuYW1lKSwgMCwKICAgICAgICAgICAgICAgICJjb250ZXh0IG1hbmFnZXIgd3JvdGUgbm8gZW5kLW9mLWFyY2hpdmUgYmxvY2siKQoKICAgIGRlZiB0ZXN0X2ZpbGVvYmooc2VsZik6CiAgICAgICAgIyBUZXN0IHRoYXQgX19leGl0X18oKSBkaWQgbm90IGNsb3NlIHRoZSBleHRlcm5hbCBmaWxlCiAgICAgICAgIyBvYmplY3QuCiAgICAgICAgZm9iaiA9IG9wZW4odG1wbmFtZSwgIndiIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIHdpdGggdGFyZmlsZS5vcGVuKGZpbGVvYmo9Zm9iaiwgbW9kZT0idyIpIGFzIHRhcjoKICAgICAgICAgICAgICAgIHJhaXNlIEV4Y2VwdGlvbgogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgcGFzcwogICAgICAgIHNlbGYuYXNzZXJ0RmFsc2UoZm9iai5jbG9zZWQsICJleHRlcm5hbCBmaWxlIG9iamVjdCB3YXMgY2xvc2VkIikKICAgICAgICBzZWxmLmFzc2VydFRydWUodGFyLmNsb3NlZCwgImNvbnRleHQgbWFuYWdlciBmYWlsZWQiKQogICAgICAgIGZvYmouY2xvc2UoKQoKCmNsYXNzIExpbmtFbXVsYXRpb25UZXN0KFJlYWRUZXN0KToKCiAgICAjIFRlc3QgZm9yIGlzc3VlICM4NzQxIHJlZ3Jlc3Npb24uIE9uIHBsYXRmb3JtcyB0aGF0IGRvIG5vdCBzdXBwb3J0CiAgICAjIHN5bWJvbGljIG9yIGhhcmQgbGlua3MgdGFyZmlsZSB0cmllcyB0byBleHRyYWN0IHRoZXNlIHR5cGVzIG9mIG1lbWJlcnMgYXMKICAgICMgdGhlIHJlZ3VsYXIgZmlsZXMgdGhleSBwb2ludCB0by4KICAgIGRlZiBfdGVzdF9saW5rX2V4dHJhY3Rpb24oc2VsZiwgbmFtZSk6CiAgICAgICAgc2VsZi50YXIuZXh0cmFjdChuYW1lLCBURU1QRElSKQogICAgICAgIGRhdGEgPSBvcGVuKG9zLnBhdGguam9pbihURU1QRElSLCBuYW1lKSwgInJiIikucmVhZCgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChtZDVzdW0oZGF0YSksIG1kNV9yZWd0eXBlKQoKICAgIGRlZiB0ZXN0X2hhcmRsaW5rX2V4dHJhY3Rpb24xKHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3RfbGlua19leHRyYWN0aW9uKCJ1c3Rhci9sbmt0eXBlIikKCiAgICBkZWYgdGVzdF9oYXJkbGlua19leHRyYWN0aW9uMihzZWxmKToKICAgICAgICBzZWxmLl90ZXN0X2xpbmtfZXh0cmFjdGlvbigiLi91c3Rhci9saW5rdGVzdDIvbG5rdHlwZSIpCgogICAgZGVmIHRlc3Rfc3ltbGlua19leHRyYWN0aW9uMShzZWxmKToKICAgICAgICBzZWxmLl90ZXN0X2xpbmtfZXh0cmFjdGlvbigidXN0YXIvc3ltdHlwZSIpCgogICAgZGVmIHRlc3Rfc3ltbGlua19leHRyYWN0aW9uMihzZWxmKToKICAgICAgICBzZWxmLl90ZXN0X2xpbmtfZXh0cmFjdGlvbigiLi91c3Rhci9saW5rdGVzdDIvc3ltdHlwZSIpCgoKY2xhc3MgR3ppcE1pc2NSZWFkVGVzdChNaXNjUmVhZFRlc3QpOgogICAgdGFybmFtZSA9IGd6aXBuYW1lCiAgICBtb2RlID0gInI6Z3oiCiAgICB0YXJvcGVuID0gdGFyZmlsZS5UYXJGaWxlLmd6b3BlbgpjbGFzcyBHemlwVXN0YXJSZWFkVGVzdChVc3RhclJlYWRUZXN0KToKICAgIHRhcm5hbWUgPSBnemlwbmFtZQogICAgbW9kZSA9ICJyOmd6IgpjbGFzcyBHemlwU3RyZWFtUmVhZFRlc3QoU3RyZWFtUmVhZFRlc3QpOgogICAgdGFybmFtZSA9IGd6aXBuYW1lCiAgICBtb2RlID0gInJ8Z3oiCmNsYXNzIEd6aXBXcml0ZVRlc3QoV3JpdGVUZXN0KToKICAgIG1vZGUgPSAidzpneiIKY2xhc3MgR3ppcFN0cmVhbVdyaXRlVGVzdChTdHJlYW1Xcml0ZVRlc3QpOgogICAgbW9kZSA9ICJ3fGd6IgoKCmNsYXNzIEJ6Mk1pc2NSZWFkVGVzdChNaXNjUmVhZFRlc3QpOgogICAgdGFybmFtZSA9IGJ6Mm5hbWUKICAgIG1vZGUgPSAicjpiejIiCiAgICB0YXJvcGVuID0gdGFyZmlsZS5UYXJGaWxlLmJ6Mm9wZW4KY2xhc3MgQnoyVXN0YXJSZWFkVGVzdChVc3RhclJlYWRUZXN0KToKICAgIHRhcm5hbWUgPSBiejJuYW1lCiAgICBtb2RlID0gInI6YnoyIgpjbGFzcyBCejJTdHJlYW1SZWFkVGVzdChTdHJlYW1SZWFkVGVzdCk6CiAgICB0YXJuYW1lID0gYnoybmFtZQogICAgbW9kZSA9ICJyfGJ6MiIKY2xhc3MgQnoyV3JpdGVUZXN0KFdyaXRlVGVzdCk6CiAgICBtb2RlID0gInc6YnoyIgpjbGFzcyBCejJTdHJlYW1Xcml0ZVRlc3QoU3RyZWFtV3JpdGVUZXN0KToKICAgIG1vZGUgPSAid3xiejIiCgpjbGFzcyBCejJQYXJ0aWFsUmVhZFRlc3QodW5pdHRlc3QuVGVzdENhc2UpOgogICAgIyBJc3N1ZTUwNjg6IFRoZSBfQloyUHJveHkucmVhZCgpIG1ldGhvZCBsb29wcyBmb3JldmVyCiAgICAjIG9uIGFuIGVtcHR5IG9yIHBhcnRpYWwgYnppcHBlZCBmaWxlLgoKICAgIGRlZiBfdGVzdF9wYXJ0aWFsX2lucHV0KHNlbGYsIG1vZGUpOgogICAgICAgIGNsYXNzIE15U3RyaW5nSU8oU3RyaW5nSU8uU3RyaW5nSU8pOgogICAgICAgICAgICBoaXRfZW9mID0gRmFsc2UKICAgICAgICAgICAgZGVmIHJlYWQoc2VsZiwgbik6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmhpdF9lb2Y6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgQXNzZXJ0aW9uRXJyb3IoImluZmluaXRlIGxvb3AgZGV0ZWN0ZWQgaW4gdGFyZmlsZS5vcGVuKCkiKQogICAgICAgICAgICAgICAgc2VsZi5oaXRfZW9mID0gc2VsZi5wb3MgPT0gc2VsZi5sZW4KICAgICAgICAgICAgICAgIHJldHVybiBTdHJpbmdJTy5TdHJpbmdJTy5yZWFkKHNlbGYsIG4pCiAgICAgICAgICAgIGRlZiBzZWVrKHNlbGYsICphcmdzKToKICAgICAgICAgICAgICAgIHNlbGYuaGl0X2VvZiA9IEZhbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gU3RyaW5nSU8uU3RyaW5nSU8uc2VlayhzZWxmLCAqYXJncykKCiAgICAgICAgZGF0YSA9IGJ6Mi5jb21wcmVzcyh0YXJmaWxlLlRhckluZm8oImZvbyIpLnRvYnVmKCkpCiAgICAgICAgZm9yIHggaW4gcmFuZ2UobGVuKGRhdGEpICsgMSk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHRhcmZpbGUub3BlbihmaWxlb2JqPU15U3RyaW5nSU8oZGF0YVs6eF0pLCBtb2RlPW1vZGUpCiAgICAgICAgICAgIGV4Y2VwdCB0YXJmaWxlLlJlYWRFcnJvcjoKICAgICAgICAgICAgICAgIHBhc3MgIyB3ZSBoYXZlIG5vIGludGVyZXN0IGluIFJlYWRFcnJvcnMKCiAgICBkZWYgdGVzdF9wYXJ0aWFsX2lucHV0KHNlbGYpOgogICAgICAgIHNlbGYuX3Rlc3RfcGFydGlhbF9pbnB1dCgiciIpCgogICAgZGVmIHRlc3RfcGFydGlhbF9pbnB1dF9iejIoc2VsZik6CiAgICAgICAgc2VsZi5fdGVzdF9wYXJ0aWFsX2lucHV0KCJyOmJ6MiIpCgoKZGVmIHRlc3RfbWFpbigpOgogICAgb3MubWFrZWRpcnMoVEVNUERJUikKCiAgICB0ZXN0cyA9IFsKICAgICAgICBVc3RhclJlYWRUZXN0LAogICAgICAgIE1pc2NSZWFkVGVzdCwKICAgICAgICBTdHJlYW1SZWFkVGVzdCwKICAgICAgICBEZXRlY3RSZWFkVGVzdCwKICAgICAgICBNZW1iZXJSZWFkVGVzdCwKICAgICAgICBHTlVSZWFkVGVzdCwKICAgICAgICBQYXhSZWFkVGVzdCwKICAgICAgICBMaXN0VGVzdCwKICAgICAgICBXcml0ZVRlc3QsCiAgICAgICAgU3RyZWFtV3JpdGVUZXN0LAogICAgICAgIEdOVVdyaXRlVGVzdCwKICAgICAgICBQYXhXcml0ZVRlc3QsCiAgICAgICAgVXN0YXJVbmljb2RlVGVzdCwKICAgICAgICBHTlVVbmljb2RlVGVzdCwKICAgICAgICBQYXhVbmljb2RlVGVzdCwKICAgICAgICBBcHBlbmRUZXN0LAogICAgICAgIExpbWl0c1Rlc3QsCiAgICAgICAgQ29udGV4dE1hbmFnZXJUZXN0LAogICAgXQoKICAgIGlmIGhhc2F0dHIob3MsICJsaW5rIik6CiAgICAgICAgdGVzdHMuYXBwZW5kKEhhcmRsaW5rVGVzdCkKICAgIGVsc2U6CiAgICAgICAgdGVzdHMuYXBwZW5kKExpbmtFbXVsYXRpb25UZXN0KQoKICAgIGZvYmogPSBvcGVuKHRhcm5hbWUsICJyYiIpCiAgICBkYXRhID0gZm9iai5yZWFkKCkKICAgIGZvYmouY2xvc2UoKQoKICAgIGlmIGd6aXA6CiAgICAgICAgIyBDcmVhdGUgdGVzdHRhci50YXIuZ3ogYW5kIGFkZCBnemlwLXNwZWNpZmljIHRlc3RzLgogICAgICAgIHRhciA9IGd6aXAub3BlbihnemlwbmFtZSwgIndiIikKICAgICAgICB0YXIud3JpdGUoZGF0YSkKICAgICAgICB0YXIuY2xvc2UoKQoKICAgICAgICB0ZXN0cyArPSBbCiAgICAgICAgICAgIEd6aXBNaXNjUmVhZFRlc3QsCiAgICAgICAgICAgIEd6aXBVc3RhclJlYWRUZXN0LAogICAgICAgICAgICBHemlwU3RyZWFtUmVhZFRlc3QsCiAgICAgICAgICAgIEd6aXBMaXN0VGVzdCwKICAgICAgICAgICAgR3ppcFdyaXRlVGVzdCwKICAgICAgICAgICAgR3ppcFN0cmVhbVdyaXRlVGVzdCwKICAgICAgICBdCgogICAgaWYgYnoyOgogICAgICAgICMgQ3JlYXRlIHRlc3R0YXIudGFyLmJ6MiBhbmQgYWRkIGJ6Mi1zcGVjaWZpYyB0ZXN0cy4KICAgICAgICB0YXIgPSBiejIuQloyRmlsZShiejJuYW1lLCAid2IiKQogICAgICAgIHRhci53cml0ZShkYXRhKQogICAgICAgIHRhci5jbG9zZSgpCgogICAgICAgIHRlc3RzICs9IFsKICAgICAgICAgICAgQnoyTWlzY1JlYWRUZXN0LAogICAgICAgICAgICBCejJVc3RhclJlYWRUZXN0LAogICAgICAgICAgICBCejJTdHJlYW1SZWFkVGVzdCwKICAgICAgICAgICAgQnoyTGlzdFRlc3QsCiAgICAgICAgICAgIEJ6MldyaXRlVGVzdCwKICAgICAgICAgICAgQnoyU3RyZWFtV3JpdGVUZXN0LAogICAgICAgICAgICBCejJQYXJ0aWFsUmVhZFRlc3QsCiAgICAgICAgXQoKICAgIHRyeToKICAgICAgICB0ZXN0X3N1cHBvcnQucnVuX3VuaXR0ZXN0KCp0ZXN0cykKICAgIGZpbmFsbHk6CiAgICAgICAgaWYgb3MucGF0aC5leGlzdHMoVEVNUERJUik6CiAgICAgICAgICAgIHNodXRpbC5ybXRyZWUoVEVNUERJUikKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0ZXN0X21haW4oKQo=