Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvcmVncmVzc2lvbi5weTogcHlzcWxpdGUgcmVncmVzc2lvbiB0ZXN0cwojCiMgQ29weXJpZ2h0IChDKSAyMDA2IEdlcmhhcmQgSORyaW5nIDxnaEBnaGFlcmluZy5kZT4KIwojIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHB5c3FsaXRlLgojCiMgVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKIyB3YXJyYW50eS4gIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiMgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KIwojIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLAojIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQKIyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6CiMKIyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdAojICAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlCiMgICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlCiMgICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC4KIyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZQojICAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KIyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLgoKaW1wb3J0IGRhdGV0aW1lCmltcG9ydCB1bml0dGVzdAppbXBvcnQgc3FsaXRlMyBhcyBzcWxpdGUKCmNsYXNzIFJlZ3Jlc3Npb25UZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgc2V0VXAoc2VsZik6CiAgICAgICAgc2VsZi5jb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQoKICAgIGRlZiB0ZWFyRG93bihzZWxmKToKICAgICAgICBzZWxmLmNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrUHJhZ21hVXNlclZlcnNpb24oc2VsZik6CiAgICAgICAgIyBUaGlzIHVzZWQgdG8gY3Jhc2ggcHlzcWxpdGUgYmVjYXVzZSB0aGlzIHByYWdtYSBjb21tYW5kIHJldHVybnMgTlVMTCBmb3IgdGhlIGNvbHVtbiBuYW1lCiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgicHJhZ21hIHVzZXJfdmVyc2lvbiIpCgogICAgZGVmIENoZWNrUHJhZ21hU2NoZW1hVmVyc2lvbihzZWxmKToKICAgICAgICAjIFRoaXMgc3RpbGwgY3Jhc2hlZCBweXNxbGl0ZSA8PSAyLjIuMQogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsIGRldGVjdF90eXBlcz1zcWxpdGUuUEFSU0VfQ09MTkFNRVMpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgICAgICBjdXIuZXhlY3V0ZSgicHJhZ21hIHNjaGVtYV92ZXJzaW9uIikKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBjdXIuY2xvc2UoKQogICAgICAgICAgICBjb24uY2xvc2UoKQoKICAgIGRlZiBDaGVja1N0YXRlbWVudFJlc2V0KHNlbGYpOgogICAgICAgICMgcHlzcWxpdGUgMi4xLjAgdG8gMi4yLjAgaGF2ZSB0aGUgcHJvYmxlbSB0aGF0IG5vdCBhbGwgc3RhdGVtZW50cyBhcmUKICAgICAgICAjIHJlc2V0IGJlZm9yZSBhIHJvbGxiYWNrLCBidXQgb25seSB0aG9zZSB0aGF0IGFyZSBzdGlsbCBpbiB0aGUKICAgICAgICAjIHN0YXRlbWVudCBjYWNoZS4gVGhlIG90aGVycyBhcmUgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY29ubmVjdGlvbiBvYmplY3QuCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgY2FjaGVkX3N0YXRlbWVudHM9NSkKICAgICAgICBjdXJzb3JzID0gW2Nvbi5jdXJzb3IoKSBmb3IgeCBpbiByYW5nZSg1KV0KICAgICAgICBjdXJzb3JzWzBdLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KHgpIikKICAgICAgICBmb3IgaSBpbiByYW5nZSgxMCk6CiAgICAgICAgICAgIGN1cnNvcnNbMF0uZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIHRlc3QoeCkgdmFsdWVzICg/KSIsIFsoeCwpIGZvciB4IGluIHJhbmdlKDEwKV0pCgogICAgICAgIGZvciBpIGluIHJhbmdlKDUpOgogICAgICAgICAgICBjdXJzb3JzW2ldLmV4ZWN1dGUoIiAiICogaSArICJzZWxlY3QgeCBmcm9tIHRlc3QiKQoKICAgICAgICBjb24ucm9sbGJhY2soKQoKICAgIGRlZiBDaGVja0NvbHVtbk5hbWVXaXRoU3BhY2VzKHNlbGYpOgogICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoJ3NlbGVjdCAxIGFzICJmb28gYmFyIFtkYXRldGltZV0iJykKICAgICAgICBzZWxmLmZhaWxVbmxlc3NFcXVhbChjdXIuZGVzY3JpcHRpb25bMF1bMF0sICJmb28gYmFyIikKCiAgICAgICAgY3VyLmV4ZWN1dGUoJ3NlbGVjdCAxIGFzICJmb28gYmF6IicpCiAgICAgICAgc2VsZi5mYWlsVW5sZXNzRXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJheiIpCgogICAgZGVmIENoZWNrU3RhdGVtZW50QXZhaWxhYmxlKHNlbGYpOgogICAgICAgICMgcHlzcWxpdGUgdXAgdG8gMi4zLjIgY3Jhc2hlZCBvbiB0aGlzLCBiZWNhdXNlIHRoZSBhY3RpdmUgc3RhdGVtZW50IGhhbmRsZSB3YXMgbm90IGNoZWNrZWQKICAgICAgICAjIGJlZm9yZSB0cnlpbmcgdG8gZmV0Y2ggZGF0YSBmcm9tIGl0LiBjbG9zZSgpIGRlc3Ryb3lzIHRoZSBhY3RpdmUgc3RhdGVtZW50IC4uLgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsIGRldGVjdF90eXBlcz1zcWxpdGUuUEFSU0VfREVDTFRZUEVTKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgNCB1bmlvbiBzZWxlY3QgNSIpCiAgICAgICAgY3VyLmNsb3NlKCkKICAgICAgICBjdXIuZmV0Y2hvbmUoKQogICAgICAgIGN1ci5mZXRjaG9uZSgpCgogICAgZGVmIENoZWNrU3RhdGVtZW50RmluYWxpemF0aW9uT25DbG9zZURiKHNlbGYpOgogICAgICAgICMgcHlzcWxpdGUgdmVyc2lvbnMgPD0gMi4zLjMgb25seSBmaW5hbGl6ZWQgc3RhdGVtZW50cyBpbiB0aGUgc3RhdGVtZW50CiAgICAgICAgIyBjYWNoZSB3aGVuIGNsb3NpbmcgdGhlIGRhdGFiYXNlLiBzdGF0ZW1lbnRzIHRoYXQgd2VyZSBzdGlsbAogICAgICAgICMgcmVmZXJlbmNlZCBpbiBjdXJzb3JzIHdlcmVuJ3QgY2xvc2VkIGFuIGNvdWxkIHByb3Zva2UgIgogICAgICAgICMgIk9wZXJhdGlvbmFsRXJyb3I6IFVuYWJsZSB0byBjbG9zZSBkdWUgdG8gdW5maW5hbGlzZWQgc3RhdGVtZW50cyIuCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXJzb3JzID0gW10KICAgICAgICAjIGRlZmF1bHQgc3RhdGVtZW50IGNhY2hlIHNpemUgaXMgMTAwCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMTA1KToKICAgICAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1cnNvcnMuYXBwZW5kKGN1cikKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCAxIHggdW5pb24gc2VsZWN0ICIgKyBzdHIoaSkpCiAgICAgICAgY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tPbkNvbmZsaWN0Um9sbGJhY2soc2VsZik6CiAgICAgICAgaWYgc3FsaXRlLnNxbGl0ZV92ZXJzaW9uX2luZm8gPCAoMywgMiwgMik6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oeCwgdW5pcXVlKHgpIG9uIGNvbmZsaWN0IHJvbGxiYWNrKSIpCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKDEpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgxKSIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5EYXRhYmFzZUVycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKDIpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5jb21taXQoKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuT3BlcmF0aW9uYWxFcnJvcjoKICAgICAgICAgICAgc2VsZi5mYWlsKCJweXNxbGl0ZSBrbmV3IG5vdGhpbmcgYWJvdXQgdGhlIGltcGxpY2l0IFJPTExCQUNLIikKCiAgICBkZWYgQ2hlY2tXb3JrYXJvdW5kRm9yQnVnZ3lTcWxpdGVUcmFuc2ZlckJpbmRpbmdzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIHdvdWxkIGNyYXNoIHdpdGggb2xkZXIgU1FMaXRlIHZlcnNpb25zIHVubGVzcwogICAgICAgIGEgd29ya2Fyb3VuZCBpcyBpbXBsZW1lbnRlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhcikiKQogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoImRyb3AgdGFibGUgZm9vIikKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhcikiKQoKICAgIGRlZiBDaGVja0VtcHR5U3RhdGVtZW50KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIHVzZWQgdG8gc2VnZmF1bHQgd2l0aCBTUUxpdGUgdmVyc2lvbnMgMy41LnguIFRoZXNlIHJldHVybiBOVUxMCiAgICAgICAgZm9yICJuby1vcGVyYXRpb24iIHN0YXRlbWVudHMKICAgICAgICAiIiIKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCIiKQoKICAgIGRlZiBDaGVja1R5cGVNYXBVc2FnZShzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB1bnRpbCAyLjQuMSBkaWQgbm90IHJlYnVpbGQgdGhlIHJvd19jYXN0X21hcCB3aGVuIHJlY29tcGlsaW5nCiAgICAgICAgYSBzdGF0ZW1lbnQuIFRoaXMgdGVzdCBleGhpYml0cyB0aGUgcHJvYmxlbS4KICAgICAgICAiIiIKICAgICAgICBTRUxFQ1QgPSAic2VsZWN0ICogZnJvbSBmb28iCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IixkZXRlY3RfdHlwZXM9c3FsaXRlLlBBUlNFX0RFQ0xUWVBFUykKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIgdGltZXN0YW1wKSIpCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyhiYXIpIHZhbHVlcyAoPykiLCAoZGF0ZXRpbWUuZGF0ZXRpbWUubm93KCksKSkKICAgICAgICBjb24uZXhlY3V0ZShTRUxFQ1QpCiAgICAgICAgY29uLmV4ZWN1dGUoImRyb3AgdGFibGUgZm9vIikKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIgaW50ZWdlcikiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oYmFyKSB2YWx1ZXMgKDUpIikKICAgICAgICBjb24uZXhlY3V0ZShTRUxFQ1QpCgogICAgZGVmIENoZWNrRXJyb3JNc2dEZWNvZGVFcnJvcihzZWxmKToKICAgICAgICAjIFdoZW4gcG9ydGluZyB0aGUgbW9kdWxlIHRvIFB5dGhvbiAzLjAsIHRoZSBlcnJvciBtZXNzYWdlIGFib3V0CiAgICAgICAgIyBkZWNvZGluZyBlcnJvcnMgZGlzYXBwZWFyZWQuIFRoaXMgdmVyaWZpZXMgdGhleSdyZSBiYWNrIGFnYWluLgogICAgICAgIGZhaWx1cmUgPSBOb25lCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJzZWxlY3QgJ3h4eCcgfHwgPyB8fCAneXl5JyBjb2xuYW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZXMoYnl0ZWFycmF5KFsyNTBdKSksKSkuZmV0Y2hvbmUoKQogICAgICAgICAgICBmYWlsdXJlID0gInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIHdpdGggZGV0YWlsZWQgZGVzY3JpcHRpb24iCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yIGFzIGU6CiAgICAgICAgICAgIG1zZyA9IGUuYXJnc1swXQogICAgICAgICAgICBpZiBub3QgbXNnLnN0YXJ0c3dpdGgoIkNvdWxkIG5vdCBkZWNvZGUgdG8gVVRGLTggY29sdW1uICdjb2xuYW1lJyB3aXRoIHRleHQgJ3h4eCIpOgogICAgICAgICAgICAgICAgZmFpbHVyZSA9ICJPcGVyYXRpb25hbEVycm9yIGRpZCBub3QgaGF2ZSBleHBlY3RlZCBkZXNjcmlwdGlvbiB0ZXh0IgogICAgICAgIGlmIGZhaWx1cmU6CiAgICAgICAgICAgIHNlbGYuZmFpbChmYWlsdXJlKQoKICAgIGRlZiBDaGVja1JlZ2lzdGVyQWRhcHRlcihzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTZWUgaXNzdWUgMzMxMi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNxbGl0ZS5yZWdpc3Rlcl9hZGFwdGVyLCB7fSwgTm9uZSkKCiAgICBkZWYgQ2hlY2tTZXRJc29sYXRpb25MZXZlbChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTZWUgaXNzdWUgMzMxMi4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIHNldGF0dHIoY29uLCAiaXNvbGF0aW9uX2xldmVsIiwgIlx4ZTkiKQoKCmRlZiBzdWl0ZSgpOgogICAgcmVncmVzc2lvbl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShSZWdyZXNzaW9uVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKChyZWdyZXNzaW9uX3N1aXRlLCkpCgpkZWYgdGVzdCgpOgogICAgcnVubmVyID0gdW5pdHRlc3QuVGV4dFRlc3RSdW5uZXIoKQogICAgcnVubmVyLnJ1bihzdWl0ZSgpKQoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIHRlc3QoKQo=