Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvdHJhbnNhY3Rpb25zLnB5OiB0ZXN0cyB0cmFuc2FjdGlvbnMKIwojIENvcHlyaWdodCAoQykgMjAwNS0yMDA3IEdlcmhhcmQgSORyaW5nIDxnaEBnaGFlcmluZy5kZT4KIwojIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHB5c3FsaXRlLgojCiMgVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKIyB3YXJyYW50eS4gIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiMgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KIwojIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAojIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQKIyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiMKIyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdAojICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiMgICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiMgICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC4KIyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQojICAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KIyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLgoKaW1wb3J0IHN5cwppbXBvcnQgb3MsIHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQoKZGVmIGdldF9kYl9wYXRoKCk6CiAgICByZXR1cm4gInNxbGl0ZV90ZXN0ZGIiCgpjbGFzcyBUcmFuc2FjdGlvblRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIG9zLnJlbW92ZShnZXRfZGJfcGF0aCgpKQogICAgICAgIGV4Y2VwdCBPU0Vycm9yOgogICAgICAgICAgICBwYXNzCgogICAgICAgIHNlbGYuY29uMSA9IHNxbGl0ZS5jb25uZWN0KGdldF9kYl9wYXRoKCksIHRpbWVvdXQ9MC4xKQogICAgICAgIHNlbGYuY3VyMSA9IHNlbGYuY29uMS5jdXJzb3IoKQoKICAgICAgICBzZWxmLmNvbjIgPSBzcWxpdGUuY29ubmVjdChnZXRfZGJfcGF0aCgpLCB0aW1lb3V0PTAuMSkKICAgICAgICBzZWxmLmN1cjIgPSBzZWxmLmNvbjIuY3Vyc29yKCkKCiAgICBkZWYgdGVhckRvd24oc2VsZik6CiAgICAgICAgc2VsZi5jdXIxLmNsb3NlKCkKICAgICAgICBzZWxmLmNvbjEuY2xvc2UoKQoKICAgICAgICBzZWxmLmN1cjIuY2xvc2UoKQogICAgICAgIHNlbGYuY29uMi5jbG9zZSgpCgogICAgICAgIHRyeToKICAgICAgICAgICAgb3MudW5saW5rKGdldF9kYl9wYXRoKCkpCiAgICAgICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgICAgIHBhc3MKCiAgICBkZWYgQ2hlY2tETUxkb2VzQXV0b0NvbW1pdEJlZm9yZShzZWxmKToKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoaSkiKQogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGkpIHZhbHVlcyAoNSkiKQogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdDIoaikiKQogICAgICAgIHNlbGYuY3VyMi5leGVjdXRlKCJzZWxlY3QgaSBmcm9tIHRlc3QiKQogICAgICAgIHJlcyA9IHNlbGYuY3VyMi5mZXRjaGFsbCgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocmVzKSwgMSkKCiAgICBkZWYgQ2hlY2tJbnNlcnRTdGFydHNUcmFuc2FjdGlvbihzZWxmKToKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoaSkiKQogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGkpIHZhbHVlcyAoNSkiKQogICAgICAgIHNlbGYuY3VyMi5leGVjdXRlKCJzZWxlY3QgaSBmcm9tIHRlc3QiKQogICAgICAgIHJlcyA9IHNlbGYuY3VyMi5mZXRjaGFsbCgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocmVzKSwgMCkKCiAgICBkZWYgQ2hlY2tVcGRhdGVTdGFydHNUcmFuc2FjdGlvbihzZWxmKToKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoaSkiKQogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGkpIHZhbHVlcyAoNSkiKQogICAgICAgIHNlbGYuY29uMS5jb21taXQoKQogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJ1cGRhdGUgdGVzdCBzZXQgaT02IikKICAgICAgICBzZWxmLmN1cjIuZXhlY3V0ZSgic2VsZWN0IGkgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1cjIuZmV0Y2hvbmUoKVswXQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzLCA1KQoKICAgIGRlZiBDaGVja0RlbGV0ZVN0YXJ0c1RyYW5zYWN0aW9uKHNlbGYpOgogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QoaSkgdmFsdWVzICg1KSIpCiAgICAgICAgc2VsZi5jb24xLmNvbW1pdCgpCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImRlbGV0ZSBmcm9tIHRlc3QiKQogICAgICAgIHNlbGYuY3VyMi5leGVjdXRlKCJzZWxlY3QgaSBmcm9tIHRlc3QiKQogICAgICAgIHJlcyA9IHNlbGYuY3VyMi5mZXRjaGFsbCgpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4ocmVzKSwgMSkKCiAgICBkZWYgQ2hlY2tSZXBsYWNlU3RhcnRzVHJhbnNhY3Rpb24oc2VsZik6CiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KGkpIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmNvbjEuY29tbWl0KCkKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgicmVwbGFjZSBpbnRvIHRlc3QoaSkgdmFsdWVzICg2KSIpCiAgICAgICAgc2VsZi5jdXIyLmV4ZWN1dGUoInNlbGVjdCBpIGZyb20gdGVzdCIpCiAgICAgICAgcmVzID0gc2VsZi5jdXIyLmZldGNoYWxsKCkKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGxlbihyZXMpLCAxKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocmVzWzBdWzBdLCA1KQoKICAgIGRlZiBDaGVja1RvZ2dsZUF1dG9Db21taXQoc2VsZik6CiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KGkpIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmNvbjEuaXNvbGF0aW9uX2xldmVsID0gTm9uZQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoc2VsZi5jb24xLmlzb2xhdGlvbl9sZXZlbCwgTm9uZSkKICAgICAgICBzZWxmLmN1cjIuZXhlY3V0ZSgic2VsZWN0IGkgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1cjIuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlcyksIDEpCgogICAgICAgIHNlbGYuY29uMS5pc29sYXRpb25fbGV2ZWwgPSAiREVGRVJSRUQiCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzZWxmLmNvbjEuaXNvbGF0aW9uX2xldmVsICwgIkRFRkVSUkVEIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1cjIuZXhlY3V0ZSgic2VsZWN0IGkgZnJvbSB0ZXN0IikKICAgICAgICByZXMgPSBzZWxmLmN1cjIuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwobGVuKHJlcyksIDEpCgogICAgZGVmIENoZWNrUmFpc2VUaW1lb3V0KHNlbGYpOgogICAgICAgIGlmIHNxbGl0ZS5zcWxpdGVfdmVyc2lvbl9pbmZvIDwgKDMsIDIsIDIpOgogICAgICAgICAgICAjIFRoaXMgd2lsbCBmYWlsIChoYW5nKSBvbiBlYXJsaWVyIHZlcnNpb25zIG9mIHNxbGl0ZS4KICAgICAgICAgICAgIyBEZXRlcm1pbmUgZXhhY3QgdmVyc2lvbiBpdCB3YXMgZml4ZWQuIDMuMi4xIGhhbmdzLgogICAgICAgICAgICByZXR1cm4KICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoaSkiKQogICAgICAgIHNlbGYuY3VyMS5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGkpIHZhbHVlcyAoNSkiKQogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi5jdXIyLmV4ZWN1dGUoImluc2VydCBpbnRvIHRlc3QoaSkgdmFsdWVzICg1KSIpCiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIGFuIE9wZXJhdGlvbmFsRXJyb3IiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuT3BlcmF0aW9uYWxFcnJvcjoKICAgICAgICAgICAgcGFzcwogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgYW4gT3BlcmF0aW9uYWxFcnJvciIpCgogICAgZGVmIENoZWNrTG9ja2luZyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBUaGlzIHRlc3RzIHRoZSBpbXByb3ZlZCBjb25jdXJyZW5jeSB3aXRoIHB5c3FsaXRlIDIuMy40LiBZb3UgbmVlZGVkCiAgICAgICAgdG8gcm9sbCBiYWNrIGNvbjIgYmVmb3JlIHlvdSBjb3VsZCBjb21taXQgY29uMS4KICAgICAgICAiIiIKICAgICAgICBpZiBzcWxpdGUuc3FsaXRlX3ZlcnNpb25faW5mbyA8ICgzLCAyLCAyKToKICAgICAgICAgICAgIyBUaGlzIHdpbGwgZmFpbCAoaGFuZykgb24gZWFybGllciB2ZXJzaW9ucyBvZiBzcWxpdGUuCiAgICAgICAgICAgICMgRGV0ZXJtaW5lIGV4YWN0IHZlcnNpb24gaXQgd2FzIGZpeGVkLiAzLjIuMSBoYW5ncy4KICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgc2VsZi5jdXIxLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KGkpIikKICAgICAgICBzZWxmLmN1cjEuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYuY3VyMi5leGVjdXRlKCJpbnNlcnQgaW50byB0ZXN0KGkpIHZhbHVlcyAoNSkiKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3I6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIGFuIE9wZXJhdGlvbmFsRXJyb3IiKQogICAgICAgICMgTk8gc2VsZi5jb24yLnJvbGxiYWNrKCkgSEVSRSEhIQogICAgICAgIHNlbGYuY29uMS5jb21taXQoKQoKICAgIGRlZiBDaGVja1JvbGxiYWNrQ3Vyc29yQ29uc2lzdGVuY3koc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQ2hlY2tzIGlmIGN1cnNvcnMgb24gdGhlIGNvbm5lY3Rpb24gYXJlIHNldCBpbnRvIGEgInJlc2V0IiBzdGF0ZQogICAgICAgIHdoZW4gYSByb2xsYmFjayBpcyBkb25lIG9uIHRoZSBjb25uZWN0aW9uLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KHgpIikKICAgICAgICBjdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdCh4KSB2YWx1ZXMgKDUpIikKICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IDEgdW5pb24gc2VsZWN0IDIgdW5pb24gc2VsZWN0IDMiKQoKICAgICAgICBjb24ucm9sbGJhY2soKQogICAgICAgIHRyeToKICAgICAgICAgICAgY3VyLmZldGNoYWxsKCkKICAgICAgICAgICAgc2VsZi5mYWlsKCJJbnRlcmZhY2VFcnJvciBzaG91bGQgaGF2ZSBiZWVuIHJhaXNlZCIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5JbnRlcmZhY2VFcnJvciwgZToKICAgICAgICAgICAgcGFzcwogICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgc2VsZi5mYWlsKCJJbnRlcmZhY2VFcnJvciBzaG91bGQgaGF2ZSBiZWVuIHJhaXNlZCIpCgpjbGFzcyBTcGVjaWFsQ29tbWFuZFRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLmNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgc2VsZi5jdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQoKICAgIGRlZiBDaGVja1ZhY3V1bShzZWxmKToKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJ2YWN1dW0iKQoKICAgIGRlZiBDaGVja0Ryb3BUYWJsZShzZWxmKToKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJkcm9wIHRhYmxlIHRlc3QiKQoKICAgIGRlZiBDaGVja1ByYWdtYShzZWxmKToKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgdGVzdChpKSIpCiAgICAgICAgc2VsZi5jdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gdGVzdChpKSB2YWx1ZXMgKDUpIikKICAgICAgICBzZWxmLmN1ci5leGVjdXRlKCJwcmFnbWEgY291bnRfY2hhbmdlcz0xIikKCiAgICBkZWYgdGVhckRvd24oc2VsZik6CiAgICAgICAgc2VsZi5jdXIuY2xvc2UoKQogICAgICAgIHNlbGYuY29uLmNsb3NlKCkKCmRlZiBzdWl0ZSgpOgogICAgZGVmYXVsdF9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShUcmFuc2FjdGlvblRlc3RzLCAiQ2hlY2siKQogICAgc3BlY2lhbF9jb21tYW5kX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKFNwZWNpYWxDb21tYW5kVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKChkZWZhdWx0X3N1aXRlLCBzcGVjaWFsX2NvbW1hbmRfc3VpdGUpKQoKZGVmIHRlc3QoKToKICAgIHJ1bm5lciA9IHVuaXR0ZXN0LlRleHRUZXN0UnVubmVyKCkKICAgIHJ1bm5lci5ydW4oc3VpdGUoKSkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0ZXN0KCkK