Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvcmVncmVzc2lvbi5weTogcHlzcWxpdGUgcmVncmVzc2lvbiB0ZXN0cwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQoKY2xhc3MgUmVncmVzc2lvblRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLmNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tQcmFnbWFVc2VyVmVyc2lvbihzZWxmKToKICAgICAgICAjIFRoaXMgdXNlZCB0byBjcmFzaCBweXNxbGl0ZSBiZWNhdXNlIHRoaXMgcHJhZ21hIGNvbW1hbmQgcmV0dXJucyBOVUxMIGZvciB0aGUgY29sdW1uIG5hbWUKICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgdXNlcl92ZXJzaW9uIikKCiAgICBkZWYgQ2hlY2tQcmFnbWFTY2hlbWFWZXJzaW9uKHNlbGYpOgogICAgICAgICMgVGhpcyBzdGlsbCBjcmFzaGVkIHB5c3FsaXRlIDw9IDIuMi4xCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9DT0xOQU1FUykKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgc2NoZW1hX3ZlcnNpb24iKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIGN1ci5jbG9zZSgpCiAgICAgICAgICAgIGNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrU3RhdGVtZW50UmVzZXQoc2VsZik6CiAgICAgICAgIyBweXNxbGl0ZSAyLjEuMCB0byAyLjIuMCBoYXZlIHRoZSBwcm9ibGVtIHRoYXQgbm90IGFsbCBzdGF0ZW1lbnRzIGFyZQogICAgICAgICMgcmVzZXQgYmVmb3JlIGEgcm9sbGJhY2ssIGJ1dCBvbmx5IHRob3NlIHRoYXQgYXJlIHN0aWxsIGluIHRoZQogICAgICAgICMgc3RhdGVtZW50IGNhY2hlLiBUaGUgb3RoZXJzIGFyZSBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjb25uZWN0aW9uIG9iamVjdC4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBjYWNoZWRfc3RhdGVtZW50cz01KQogICAgICAgIGN1cnNvcnMgPSBbY29uLmN1cnNvcigpIGZvciB4IGluIHJhbmdlKDUpXQogICAgICAgIGN1cnNvcnNbMF0uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoeCkiKQogICAgICAgIGZvciBpIGluIHJhbmdlKDEwKToKICAgICAgICAgICAgY3Vyc29yc1swXS5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gdGVzdCh4KSB2YWx1ZXMgKD8pIiwgWyh4LCkgZm9yIHggaW4gcmFuZ2UoMTApXSkKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoNSk6CiAgICAgICAgICAgIGN1cnNvcnNbaV0uZXhlY3V0ZSgiICIgKiBpICsgInNlbGVjdCB4IGZyb20gdGVzdCIpCgogICAgICAgIGNvbi5yb2xsYmFjaygpCgogICAgZGVmIENoZWNrQ29sdW1uTmFtZVdpdGhTcGFjZXMoc2VsZik6CiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgnc2VsZWN0IDEgYXMgImZvbyBiYXIgW2RhdGV0aW1lXSInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJhciIpCgogICAgICAgIGN1ci5leGVjdXRlKCdzZWxlY3QgMSBhcyAiZm9vIGJheiInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJheiIpCgogICAgZGVmIENoZWNrU3RhdGVtZW50RmluYWxpemF0aW9uT25DbG9zZURiKHNlbGYpOgogICAgICAgICMgcHlzcWxpdGUgdmVyc2lvbnMgPD0gMi4zLjMgb25seSBmaW5hbGl6ZWQgc3RhdGVtZW50cyBpbiB0aGUgc3RhdGVtZW50CiAgICAgICAgIyBjYWNoZSB3aGVuIGNsb3NpbmcgdGhlIGRhdGFiYXNlLiBzdGF0ZW1lbnRzIHRoYXQgd2VyZSBzdGlsbAogICAgICAgICMgcmVmZXJlbmNlZCBpbiBjdXJzb3JzIHdlcmVuJ3QgY2xvc2VkIGFuIGNvdWxkIHByb3Zva2UgIgogICAgICAgICMgIk9wZXJhdGlvbmFsRXJyb3I6IFVuYWJsZSB0byBjbG9zZSBkdWUgdG8gdW5maW5hbGlzZWQgc3RhdGVtZW50cyIuCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXJzb3JzID0gW10KICAgICAgICAjIGRlZmF1bHQgc3RhdGVtZW50IGNhY2hlIHNpemUgaXMgMTAwCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMTA1KToKICAgICAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1cnNvcnMuYXBwZW5kKGN1cikKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCAxIHggdW5pb24gc2VsZWN0ICIgKyBzdHIoaSkpCiAgICAgICAgY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tPbkNvbmZsaWN0Um9sbGJhY2soc2VsZik6CiAgICAgICAgaWYgc3FsaXRlLnNxbGl0ZV92ZXJzaW9uX2luZm8gPCAoMywgMiwgMik6CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oeCwgdW5pcXVlKHgpIG9uIGNvbmZsaWN0IHJvbGxiYWNrKSIpCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKDEpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgxKSIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5EYXRhYmFzZUVycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKDIpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5jb21taXQoKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuT3BlcmF0aW9uYWxFcnJvcjoKICAgICAgICAgICAgc2VsZi5mYWlsKCJweXNxbGl0ZSBrbmV3IG5vdGhpbmcgYWJvdXQgdGhlIGltcGxpY2l0IFJPTExCQUNLIikKCiAgICBkZWYgQ2hlY2tXb3JrYXJvdW5kRm9yQnVnZ3lTcWxpdGVUcmFuc2ZlckJpbmRpbmdzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIHdvdWxkIGNyYXNoIHdpdGggb2xkZXIgU1FMaXRlIHZlcnNpb25zIHVubGVzcwogICAgICAgIGEgd29ya2Fyb3VuZCBpcyBpbXBsZW1lbnRlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhcikiKQogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoImRyb3AgdGFibGUgZm9vIikKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhcikiKQoKICAgIGRlZiBDaGVja0VtcHR5U3RhdGVtZW50KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIHVzZWQgdG8gc2VnZmF1bHQgd2l0aCBTUUxpdGUgdmVyc2lvbnMgMy41LnguIFRoZXNlIHJldHVybiBOVUxMCiAgICAgICAgZm9yICJuby1vcGVyYXRpb24iIHN0YXRlbWVudHMKICAgICAgICAiIiIKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCIiKQoKICAgIGRlZiBDaGVja1R5cGVNYXBVc2FnZShzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB1bnRpbCAyLjQuMSBkaWQgbm90IHJlYnVpbGQgdGhlIHJvd19jYXN0X21hcCB3aGVuIHJlY29tcGlsaW5nCiAgICAgICAgYSBzdGF0ZW1lbnQuIFRoaXMgdGVzdCBleGhpYml0cyB0aGUgcHJvYmxlbS4KICAgICAgICAiIiIKICAgICAgICBTRUxFQ1QgPSAic2VsZWN0ICogZnJvbSBmb28iCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IixkZXRlY3RfdHlwZXM9c3FsaXRlLlBBUlNFX0RFQ0xUWVBFUykKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIgdGltZXN0YW1wKSIpCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyhiYXIpIHZhbHVlcyAoPykiLCAoZGF0ZXRpbWUuZGF0ZXRpbWUubm93KCksKSkKICAgICAgICBjb24uZXhlY3V0ZShTRUxFQ1QpCiAgICAgICAgY29uLmV4ZWN1dGUoImRyb3AgdGFibGUgZm9vIikKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIgaW50ZWdlcikiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oYmFyKSB2YWx1ZXMgKDUpIikKICAgICAgICBjb24uZXhlY3V0ZShTRUxFQ1QpCgogICAgZGVmIENoZWNrRXJyb3JNc2dEZWNvZGVFcnJvcihzZWxmKToKICAgICAgICAjIFdoZW4gcG9ydGluZyB0aGUgbW9kdWxlIHRvIFB5dGhvbiAzLjAsIHRoZSBlcnJvciBtZXNzYWdlIGFib3V0CiAgICAgICAgIyBkZWNvZGluZyBlcnJvcnMgZGlzYXBwZWFyZWQuIFRoaXMgdmVyaWZpZXMgdGhleSdyZSBiYWNrIGFnYWluLgogICAgICAgIGZhaWx1cmUgPSBOb25lCiAgICAgICAgdHJ5OgogICAgICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJzZWxlY3QgJ3h4eCcgfHwgPyB8fCAneXl5JyBjb2xuYW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZXMoYnl0ZWFycmF5KFsyNTBdKSksKSkuZmV0Y2hvbmUoKQogICAgICAgICAgICBmYWlsdXJlID0gInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIHdpdGggZGV0YWlsZWQgZGVzY3JpcHRpb24iCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yIGFzIGU6CiAgICAgICAgICAgIG1zZyA9IGUuYXJnc1swXQogICAgICAgICAgICBpZiBub3QgbXNnLnN0YXJ0c3dpdGgoIkNvdWxkIG5vdCBkZWNvZGUgdG8gVVRGLTggY29sdW1uICdjb2xuYW1lJyB3aXRoIHRleHQgJ3h4eCIpOgogICAgICAgICAgICAgICAgZmFpbHVyZSA9ICJPcGVyYXRpb25hbEVycm9yIGRpZCBub3QgaGF2ZSBleHBlY3RlZCBkZXNjcmlwdGlvbiB0ZXh0IgogICAgICAgIGlmIGZhaWx1cmU6CiAgICAgICAgICAgIHNlbGYuZmFpbChmYWlsdXJlKQoKICAgIGRlZiBDaGVja1JlZ2lzdGVyQWRhcHRlcihzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTZWUgaXNzdWUgMzMxMi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNxbGl0ZS5yZWdpc3Rlcl9hZGFwdGVyLCB7fSwgTm9uZSkKCiAgICBkZWYgQ2hlY2tTZXRJc29sYXRpb25MZXZlbChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTZWUgaXNzdWUgMzMxMi4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIHNldGF0dHIoY29uLCAiaXNvbGF0aW9uX2xldmVsIiwgIlx4ZTkiKQoKICAgIGRlZiBDaGVja0N1cnNvckNvbnN0cnVjdG9yQ2FsbENoZWNrKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgY3Vyc29yIG1ldGhvZHMgY2hlY2sgd2V0aGVyIGJhc2UgY2xhc3MgX19pbml0X18gd2FzIGNhbGxlZC4KICAgICAgICAiIiIKICAgICAgICBjbGFzcyBDdXJzb3Ioc3FsaXRlLkN1cnNvcik6CiAgICAgICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBjb24pOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IEN1cnNvcihjb24pCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IDQrNSIpLmZldGNoYWxsKCkKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBQcm9ncmFtbWluZ0Vycm9yIikKCgogICAgZGVmIENoZWNrU3RyU3ViY2xhc3Moc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGhlIFB5dGhvbiAzLjAgcG9ydCBvZiB0aGUgbW9kdWxlIGRpZG4ndCBjb3BlIHdpdGggdmFsdWVzIG9mIHN1YmNsYXNzZXMgb2Ygc3RyLgogICAgICAgICIiIgogICAgICAgIGNsYXNzIE15U3RyKHN0cik6IHBhc3MKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJzZWxlY3QgPyIsIChNeVN0cigiYWJjIiksKSkKCiAgICBkZWYgQ2hlY2tDb25uZWN0aW9uQ29uc3RydWN0b3JDYWxsQ2hlY2soc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBjb25uZWN0aW9uIG1ldGhvZHMgY2hlY2sgd2V0aGVyIGJhc2UgY2xhc3MgX19pbml0X18gd2FzIGNhbGxlZC4KICAgICAgICAiIiIKICAgICAgICBjbGFzcyBDb25uZWN0aW9uKHNxbGl0ZS5Db25uZWN0aW9uKToKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUpOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBjb24gPSBDb25uZWN0aW9uKCI6bWVtb3J5OiIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICAgICAgc2VsZi5mYWlsKCJzaG91bGQgaGF2ZSByYWlzZWQgUHJvZ3JhbW1pbmdFcnJvciIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBQcm9ncmFtbWluZ0Vycm9yIikKCiAgICBkZWYgQ2hlY2tDdXJzb3JSZWdpc3RyYXRpb24oc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBzdWJjbGFzc2VkIGN1cnNvciBjbGFzc2VzIGFyZSBjb3JyZWN0bHkgcmVnaXN0ZXJlZCB3aXRoCiAgICAgICAgdGhlIGNvbm5lY3Rpb24gb2JqZWN0LCB0b28uICAoZmV0Y2gtYWNyb3NzLXJvbGxiYWNrIHByb2JsZW0pCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgQ29ubmVjdGlvbihzcWxpdGUuQ29ubmVjdGlvbik6CiAgICAgICAgICAgIGRlZiBjdXJzb3Ioc2VsZik6CiAgICAgICAgICAgICAgICByZXR1cm4gQ3Vyc29yKHNlbGYpCgogICAgICAgIGNsYXNzIEN1cnNvcihzcWxpdGUuQ3Vyc29yKToKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGNvbik6CiAgICAgICAgICAgICAgICBzcWxpdGUuQ3Vyc29yLl9faW5pdF9fKHNlbGYsIGNvbikKCiAgICAgICAgY29uID0gQ29ubmVjdGlvbigiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKHgpIikKICAgICAgICBjdXIuZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKD8pIiwgWygzLCksICg0LCksICg1LCldKQogICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgeCBmcm9tIGZvbyIpCiAgICAgICAgY29uLnJvbGxiYWNrKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ci5mZXRjaGFsbCgpCiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIEludGVyZmFjZUVycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLkludGVyZmFjZUVycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBJbnRlcmZhY2VFcnJvciIpCgogICAgZGVmIENoZWNrQXV0b0NvbW1pdChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IGNyZWF0aW5nIGEgY29ubmVjdGlvbiBpbiBhdXRvY29tbWl0IG1vZGUgd29ya3MuCiAgICAgICAgMi41LjMgaW50cm9kdWNlZCBhIHJlZ3Jlc3Npb24gc28gdGhhdCB0aGVzZSBjb3VsZCBubyBsb25nZXIKICAgICAgICBiZSBjcmVhdGVkLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsIGlzb2xhdGlvbl9sZXZlbD1Ob25lKQoKICAgIGRlZiBDaGVja1ByYWdtYUF1dG9jb21taXQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBydW5uaW5nIGEgUFJBR01BIHN0YXRlbWVudCB0aGF0IGRvZXMgYW4gYXV0b2NvbW1pdCBkb2VzCiAgICAgICAgd29yay4gVGhpcyBkaWQgbm90IHdvcmsgaW4gMi41LjMvMi41LjQuCiAgICAgICAgIiIiCiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKICAgICAgICBjdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKGJhcikgdmFsdWVzICg1KSIpCgogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgcGFnZV9zaXplIikKICAgICAgICByb3cgPSBjdXIuZmV0Y2hvbmUoKQoKICAgIGRlZiBDaGVja1NldERpY3Qoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgU2VlIGh0dHA6Ly9idWdzLnB5dGhvbi5vcmcvaXNzdWU3NDc4CgogICAgICAgIEl0IHdhcyBwb3NzaWJsZSB0byBzdWNjZXNzZnVsbHkgcmVnaXN0ZXIgY2FsbGJhY2tzIHRoYXQgY291bGQgbm90IGJlCiAgICAgICAgaGFzaGVkLiBSZXR1cm4gY29kZXMgb2YgUHlEaWN0X1NldEl0ZW0gd2VyZSBub3QgY2hlY2tlZCBwcm9wZXJseS4KICAgICAgICAiIiIKICAgICAgICBjbGFzcyBOb3RIYXNoYWJsZToKICAgICAgICAgICAgZGVmIF9fY2FsbF9fKHNlbGYsICphcmdzLCAqKmt3KToKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgZGVmIF9faGFzaF9fKHNlbGYpOgogICAgICAgICAgICAgICAgcmFpc2UgVHlwZUVycm9yKCkKICAgICAgICB2YXIgPSBOb3RIYXNoYWJsZSgpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZWxmLmNvbi5jcmVhdGVfZnVuY3Rpb24sIHZhcikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNlbGYuY29uLmNyZWF0ZV9hZ2dyZWdhdGUsIHZhcikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNlbGYuY29uLnNldF9hdXRob3JpemVyLCB2YXIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZWxmLmNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlciwgdmFyKQoKICAgIGRlZiBDaGVja0Nvbm5lY3Rpb25DYWxsKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIENhbGwgYSBjb25uZWN0aW9uIHdpdGggYSBub24tc3RyaW5nIFNRTCByZXF1ZXN0OiBjaGVjayBlcnJvciBoYW5kbGluZwogICAgICAgIG9mIHRoZSBzdGF0ZW1lbnQgY29uc3RydWN0b3IuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLldhcm5pbmcsIHNlbGYuY29uLCAxKQoKICAgIGRlZiBDaGVja0NvbGxhdGlvbihzZWxmKToKICAgICAgICBkZWYgY29sbGF0aW9uX2NiKGEsIGIpOgogICAgICAgICAgICByZXR1cm4gMQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yLCBzZWxmLmNvbi5jcmVhdGVfY29sbGF0aW9uLAogICAgICAgICAgICAjIExvbmUgc3Vycm9nYXRlIGNhbm5vdCBiZSBlbmNvZGVkIHRvIHRoZSBkZWZhdWx0IGVuY29kaW5nICh1dGY4KQogICAgICAgICAgICAiXHVEQzgwIiwgY29sbGF0aW9uX2NiKQoKZGVmIHN1aXRlKCk6CiAgICByZWdyZXNzaW9uX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKFJlZ3Jlc3Npb25UZXN0cywgIkNoZWNrIikKICAgIHJldHVybiB1bml0dGVzdC5UZXN0U3VpdGUoKHJlZ3Jlc3Npb25fc3VpdGUsKSkKCmRlZiB0ZXN0KCk6CiAgICBydW5uZXIgPSB1bml0dGVzdC5UZXh0VGVzdFJ1bm5lcigpCiAgICBydW5uZXIucnVuKHN1aXRlKCkpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdGVzdCgpCg==