Iy0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvcmVncmVzc2lvbi5weTogcHlzcWxpdGUgcmVncmVzc2lvbiB0ZXN0cwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQppbXBvcnQgd2Vha3JlZgpmcm9tIHRlc3QgaW1wb3J0IHN1cHBvcnQKCmNsYXNzIFJlZ3Jlc3Npb25UZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgc2V0VXAoc2VsZik6CiAgICAgICAgc2VsZi5jb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQoKICAgIGRlZiB0ZWFyRG93bihzZWxmKToKICAgICAgICBzZWxmLmNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrUHJhZ21hVXNlclZlcnNpb24oc2VsZik6CiAgICAgICAgIyBUaGlzIHVzZWQgdG8gY3Jhc2ggcHlzcWxpdGUgYmVjYXVzZSB0aGlzIHByYWdtYSBjb21tYW5kIHJldHVybnMgTlVMTCBmb3IgdGhlIGNvbHVtbiBuYW1lCiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgicHJhZ21hIHVzZXJfdmVyc2lvbiIpCgogICAgZGVmIENoZWNrUHJhZ21hU2NoZW1hVmVyc2lvbihzZWxmKToKICAgICAgICAjIFRoaXMgc3RpbGwgY3Jhc2hlZCBweXNxbGl0ZSA8PSAyLjIuMQogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsIGRldGVjdF90eXBlcz1zcWxpdGUuUEFSU0VfQ09MTkFNRVMpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgICAgICBjdXIuZXhlY3V0ZSgicHJhZ21hIHNjaGVtYV92ZXJzaW9uIikKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBjdXIuY2xvc2UoKQogICAgICAgICAgICBjb24uY2xvc2UoKQoKICAgIGRlZiBDaGVja1N0YXRlbWVudFJlc2V0KHNlbGYpOgogICAgICAgICMgcHlzcWxpdGUgMi4xLjAgdG8gMi4yLjAgaGF2ZSB0aGUgcHJvYmxlbSB0aGF0IG5vdCBhbGwgc3RhdGVtZW50cyBhcmUKICAgICAgICAjIHJlc2V0IGJlZm9yZSBhIHJvbGxiYWNrLCBidXQgb25seSB0aG9zZSB0aGF0IGFyZSBzdGlsbCBpbiB0aGUKICAgICAgICAjIHN0YXRlbWVudCBjYWNoZS4gVGhlIG90aGVycyBhcmUgbm90IGFjY2Vzc2libGUgZnJvbSB0aGUgY29ubmVjdGlvbiBvYmplY3QuCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgY2FjaGVkX3N0YXRlbWVudHM9NSkKICAgICAgICBjdXJzb3JzID0gW2Nvbi5jdXJzb3IoKSBmb3IgeCBpbiByYW5nZSg1KV0KICAgICAgICBjdXJzb3JzWzBdLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSB0ZXN0KHgpIikKICAgICAgICBmb3IgaSBpbiByYW5nZSgxMCk6CiAgICAgICAgICAgIGN1cnNvcnNbMF0uZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIHRlc3QoeCkgdmFsdWVzICg/KSIsIFsoeCwpIGZvciB4IGluIHJhbmdlKDEwKV0pCgogICAgICAgIGZvciBpIGluIHJhbmdlKDUpOgogICAgICAgICAgICBjdXJzb3JzW2ldLmV4ZWN1dGUoIiAiICogaSArICJzZWxlY3QgeCBmcm9tIHRlc3QiKQoKICAgICAgICBjb24ucm9sbGJhY2soKQoKICAgIGRlZiBDaGVja0NvbHVtbk5hbWVXaXRoU3BhY2VzKHNlbGYpOgogICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoJ3NlbGVjdCAxIGFzICJmb28gYmFyIFtkYXRldGltZV0iJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGN1ci5kZXNjcmlwdGlvblswXVswXSwgImZvbyBiYXIiKQoKICAgICAgICBjdXIuZXhlY3V0ZSgnc2VsZWN0IDEgYXMgImZvbyBiYXoiJykKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGN1ci5kZXNjcmlwdGlvblswXVswXSwgImZvbyBiYXoiKQoKICAgIGRlZiBDaGVja1N0YXRlbWVudEZpbmFsaXphdGlvbk9uQ2xvc2VEYihzZWxmKToKICAgICAgICAjIHB5c3FsaXRlIHZlcnNpb25zIDw9IDIuMy4zIG9ubHkgZmluYWxpemVkIHN0YXRlbWVudHMgaW4gdGhlIHN0YXRlbWVudAogICAgICAgICMgY2FjaGUgd2hlbiBjbG9zaW5nIHRoZSBkYXRhYmFzZS4gc3RhdGVtZW50cyB0aGF0IHdlcmUgc3RpbGwKICAgICAgICAjIHJlZmVyZW5jZWQgaW4gY3Vyc29ycyB3ZXJlbid0IGNsb3NlZCBhbmQgY291bGQgcHJvdm9rZSAiCiAgICAgICAgIyAiT3BlcmF0aW9uYWxFcnJvcjogVW5hYmxlIHRvIGNsb3NlIGR1ZSB0byB1bmZpbmFsaXNlZCBzdGF0ZW1lbnRzIi4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGN1cnNvcnMgPSBbXQogICAgICAgICMgZGVmYXVsdCBzdGF0ZW1lbnQgY2FjaGUgc2l6ZSBpcyAxMDAKICAgICAgICBmb3IgaSBpbiByYW5nZSgxMDUpOgogICAgICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICAgICAgY3Vyc29ycy5hcHBlbmQoY3VyKQogICAgICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IDEgeCB1bmlvbiBzZWxlY3QgIiArIHN0cihpKSkKICAgICAgICBjb24uY2xvc2UoKQoKICAgIEB1bml0dGVzdC5za2lwSWYoc3FsaXRlLnNxbGl0ZV92ZXJzaW9uX2luZm8gPCAoMywgMiwgMiksICduZWVkcyBzcWxpdGUgMy4yLjIgb3IgbmV3ZXInKQogICAgZGVmIENoZWNrT25Db25mbGljdFJvbGxiYWNrKHNlbGYpOgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oeCwgdW5pcXVlKHgpIG9uIGNvbmZsaWN0IHJvbGxiYWNrKSIpCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKDEpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgxKSIpCiAgICAgICAgZXhjZXB0IHNxbGl0ZS5EYXRhYmFzZUVycm9yOgogICAgICAgICAgICBwYXNzCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKDIpIikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5jb21taXQoKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuT3BlcmF0aW9uYWxFcnJvcjoKICAgICAgICAgICAgc2VsZi5mYWlsKCJweXNxbGl0ZSBrbmV3IG5vdGhpbmcgYWJvdXQgdGhlIGltcGxpY2l0IFJPTExCQUNLIikKCiAgICBkZWYgQ2hlY2tXb3JrYXJvdW5kRm9yQnVnZ3lTcWxpdGVUcmFuc2ZlckJpbmRpbmdzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIHdvdWxkIGNyYXNoIHdpdGggb2xkZXIgU1FMaXRlIHZlcnNpb25zIHVubGVzcwogICAgICAgIGEgd29ya2Fyb3VuZCBpcyBpbXBsZW1lbnRlZC4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhcikiKQogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoImRyb3AgdGFibGUgZm9vIikKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKGJhcikiKQoKICAgIGRlZiBDaGVja0VtcHR5U3RhdGVtZW50KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIHB5c3FsaXRlIHVzZWQgdG8gc2VnZmF1bHQgd2l0aCBTUUxpdGUgdmVyc2lvbnMgMy41LnguIFRoZXNlIHJldHVybiBOVUxMCiAgICAgICAgZm9yICJuby1vcGVyYXRpb24iIHN0YXRlbWVudHMKICAgICAgICAiIiIKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCIiKQoKICAgIGRlZiBDaGVja1R5cGVNYXBVc2FnZShzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB1bnRpbCAyLjQuMSBkaWQgbm90IHJlYnVpbGQgdGhlIHJvd19jYXN0X21hcCB3aGVuIHJlY29tcGlsaW5nCiAgICAgICAgYSBzdGF0ZW1lbnQuIFRoaXMgdGVzdCBleGhpYml0cyB0aGUgcHJvYmxlbS4KICAgICAgICAiIiIKICAgICAgICBTRUxFQ1QgPSAic2VsZWN0ICogZnJvbSBmb28iCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IixkZXRlY3RfdHlwZXM9c3FsaXRlLlBBUlNFX0RFQ0xUWVBFUykKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIgdGltZXN0YW1wKSIpCiAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyhiYXIpIHZhbHVlcyAoPykiLCAoZGF0ZXRpbWUuZGF0ZXRpbWUubm93KCksKSkKICAgICAgICBjb24uZXhlY3V0ZShTRUxFQ1QpCiAgICAgICAgY29uLmV4ZWN1dGUoImRyb3AgdGFibGUgZm9vIikKICAgICAgICBjb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIgaW50ZWdlcikiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oYmFyKSB2YWx1ZXMgKDUpIikKICAgICAgICBjb24uZXhlY3V0ZShTRUxFQ1QpCgogICAgZGVmIENoZWNrRXJyb3JNc2dEZWNvZGVFcnJvcihzZWxmKToKICAgICAgICAjIFdoZW4gcG9ydGluZyB0aGUgbW9kdWxlIHRvIFB5dGhvbiAzLjAsIHRoZSBlcnJvciBtZXNzYWdlIGFib3V0CiAgICAgICAgIyBkZWNvZGluZyBlcnJvcnMgZGlzYXBwZWFyZWQuIFRoaXMgdmVyaWZpZXMgdGhleSdyZSBiYWNrIGFnYWluLgogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3IpIGFzIGNtOgogICAgICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJzZWxlY3QgJ3h4eCcgfHwgPyB8fCAneXl5JyBjb2xuYW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYnl0ZXMoYnl0ZWFycmF5KFsyNTBdKSksKSkuZmV0Y2hvbmUoKQogICAgICAgIG1zZyA9ICJDb3VsZCBub3QgZGVjb2RlIHRvIFVURi04IGNvbHVtbiAnY29sbmFtZScgd2l0aCB0ZXh0ICd4eHgiCiAgICAgICAgc2VsZi5hc3NlcnRJbihtc2csIHN0cihjbS5leGNlcHRpb24pKQoKICAgIGRlZiBDaGVja1JlZ2lzdGVyQWRhcHRlcihzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTZWUgaXNzdWUgMzMxMi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNxbGl0ZS5yZWdpc3Rlcl9hZGFwdGVyLCB7fSwgTm9uZSkKCiAgICBkZWYgQ2hlY2tTZXRJc29sYXRpb25MZXZlbChzZWxmKToKICAgICAgICAjIFNlZSBpc3N1ZSAyNzg4MS4KICAgICAgICBjbGFzcyBDdXN0b21TdHIoc3RyKToKICAgICAgICAgICAgZGVmIHVwcGVyKHNlbGYpOgogICAgICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAgICAgZGVmIF9fZGVsX18oc2VsZik6CiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gIiIKCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gTm9uZQogICAgICAgIGZvciBsZXZlbCBpbiAiIiwgIkRFRkVSUkVEIiwgIklNTUVESUFURSIsICJFWENMVVNJVkUiOgogICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChsZXZlbD1sZXZlbCk6CiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gbGV2ZWwKICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBsZXZlbC5sb3dlcigpCiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gbGV2ZWwuY2FwaXRhbGl6ZSgpCiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gQ3VzdG9tU3RyKGxldmVsKQoKICAgICAgICAjIHNldHRpbmcgaXNvbGF0aW9uX2xldmVsIGZhaWx1cmUgc2hvdWxkIG5vdCBhbHRlciBwcmV2aW91cyBzdGF0ZQogICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSBOb25lCiAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9ICJERUZFUlJFRCIKICAgICAgICBwYWlycyA9IFsKICAgICAgICAgICAgKDEsIFR5cGVFcnJvciksIChiJycsIFR5cGVFcnJvciksICgiYWJjIiwgVmFsdWVFcnJvciksCiAgICAgICAgICAgICgiSU1NRURJQVRFXDBFWENMVVNJVkUiLCBWYWx1ZUVycm9yKSwgKCJceGU5IiwgVmFsdWVFcnJvciksCiAgICAgICAgXQogICAgICAgIGZvciB2YWx1ZSwgZXhjIGluIHBhaXJzOgogICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChsZXZlbD12YWx1ZSk6CiAgICAgICAgICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKGV4Yyk6CiAgICAgICAgICAgICAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IHZhbHVlCiAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvbi5pc29sYXRpb25fbGV2ZWwsICJERUZFUlJFRCIpCgogICAgZGVmIENoZWNrQ3Vyc29yQ29uc3RydWN0b3JDYWxsQ2hlY2soc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBjdXJzb3IgbWV0aG9kcyBjaGVjayB3aGV0aGVyIGJhc2UgY2xhc3MgX19pbml0X18gd2FzCiAgICAgICAgY2FsbGVkLgogICAgICAgICIiIgogICAgICAgIGNsYXNzIEN1cnNvcihzcWxpdGUuQ3Vyc29yKToKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGNvbik6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3VyID0gQ3Vyc29yKGNvbikKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yKToKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCA0KzUiKS5mZXRjaGFsbCgpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4KHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByJ15CYXNlIEN1cnNvclwuX19pbml0X18gbm90IGNhbGxlZFwuJCcpOgogICAgICAgICAgICBjdXIuY2xvc2UoKQoKICAgIGRlZiBDaGVja1N0clN1YmNsYXNzKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFRoZSBQeXRob24gMy4wIHBvcnQgb2YgdGhlIG1vZHVsZSBkaWRuJ3QgY29wZSB3aXRoIHZhbHVlcyBvZiBzdWJjbGFzc2VzIG9mIHN0ci4KICAgICAgICAiIiIKICAgICAgICBjbGFzcyBNeVN0cihzdHIpOiBwYXNzCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgic2VsZWN0ID8iLCAoTXlTdHIoImFiYyIpLCkpCgogICAgZGVmIENoZWNrQ29ubmVjdGlvbkNvbnN0cnVjdG9yQ2FsbENoZWNrKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgY29ubmVjdGlvbiBtZXRob2RzIGNoZWNrIHdoZXRoZXIgYmFzZSBjbGFzcyBfX2luaXRfXyB3YXMKICAgICAgICBjYWxsZWQuCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgQ29ubmVjdGlvbihzcWxpdGUuQ29ubmVjdGlvbik6CiAgICAgICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lKToKICAgICAgICAgICAgICAgIHBhc3MKCiAgICAgICAgY29uID0gQ29ubmVjdGlvbigiOm1lbW9yeToiKQogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IpOgogICAgICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKCiAgICBkZWYgQ2hlY2tDdXJzb3JSZWdpc3RyYXRpb24oc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBzdWJjbGFzc2VkIGN1cnNvciBjbGFzc2VzIGFyZSBjb3JyZWN0bHkgcmVnaXN0ZXJlZCB3aXRoCiAgICAgICAgdGhlIGNvbm5lY3Rpb24gb2JqZWN0LCB0b28uICAoZmV0Y2gtYWNyb3NzLXJvbGxiYWNrIHByb2JsZW0pCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgQ29ubmVjdGlvbihzcWxpdGUuQ29ubmVjdGlvbik6CiAgICAgICAgICAgIGRlZiBjdXJzb3Ioc2VsZik6CiAgICAgICAgICAgICAgICByZXR1cm4gQ3Vyc29yKHNlbGYpCgogICAgICAgIGNsYXNzIEN1cnNvcihzcWxpdGUuQ3Vyc29yKToKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIGNvbik6CiAgICAgICAgICAgICAgICBzcWxpdGUuQ3Vyc29yLl9faW5pdF9fKHNlbGYsIGNvbikKCiAgICAgICAgY29uID0gQ29ubmVjdGlvbigiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKHgpIikKICAgICAgICBjdXIuZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIGZvbyh4KSB2YWx1ZXMgKD8pIiwgWygzLCksICg0LCksICg1LCldKQogICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgeCBmcm9tIGZvbyIpCiAgICAgICAgY29uLnJvbGxiYWNrKCkKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5JbnRlcmZhY2VFcnJvcik6CiAgICAgICAgICAgIGN1ci5mZXRjaGFsbCgpCgogICAgZGVmIENoZWNrQXV0b0NvbW1pdChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IGNyZWF0aW5nIGEgY29ubmVjdGlvbiBpbiBhdXRvY29tbWl0IG1vZGUgd29ya3MuCiAgICAgICAgMi41LjMgaW50cm9kdWNlZCBhIHJlZ3Jlc3Npb24gc28gdGhhdCB0aGVzZSBjb3VsZCBubyBsb25nZXIKICAgICAgICBiZSBjcmVhdGVkLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsIGlzb2xhdGlvbl9sZXZlbD1Ob25lKQoKICAgIGRlZiBDaGVja1ByYWdtYUF1dG9jb21taXQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBydW5uaW5nIGEgUFJBR01BIHN0YXRlbWVudCB0aGF0IGRvZXMgYW4gYXV0b2NvbW1pdCBkb2VzCiAgICAgICAgd29yay4gVGhpcyBkaWQgbm90IHdvcmsgaW4gMi41LjMvMi41LjQuCiAgICAgICAgIiIiCiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKICAgICAgICBjdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKGJhcikgdmFsdWVzICg1KSIpCgogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgcGFnZV9zaXplIikKICAgICAgICByb3cgPSBjdXIuZmV0Y2hvbmUoKQoKICAgIGRlZiBDaGVja1NldERpY3Qoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgU2VlIGh0dHA6Ly9idWdzLnB5dGhvbi5vcmcvaXNzdWU3NDc4CgogICAgICAgIEl0IHdhcyBwb3NzaWJsZSB0byBzdWNjZXNzZnVsbHkgcmVnaXN0ZXIgY2FsbGJhY2tzIHRoYXQgY291bGQgbm90IGJlCiAgICAgICAgaGFzaGVkLiBSZXR1cm4gY29kZXMgb2YgUHlEaWN0X1NldEl0ZW0gd2VyZSBub3QgY2hlY2tlZCBwcm9wZXJseS4KICAgICAgICAiIiIKICAgICAgICBjbGFzcyBOb3RIYXNoYWJsZToKICAgICAgICAgICAgZGVmIF9fY2FsbF9fKHNlbGYsICphcmdzLCAqKmt3KToKICAgICAgICAgICAgICAgIHBhc3MKICAgICAgICAgICAgZGVmIF9faGFzaF9fKHNlbGYpOgogICAgICAgICAgICAgICAgcmFpc2UgVHlwZUVycm9yKCkKICAgICAgICB2YXIgPSBOb3RIYXNoYWJsZSgpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZWxmLmNvbi5jcmVhdGVfZnVuY3Rpb24sIHZhcikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNlbGYuY29uLmNyZWF0ZV9hZ2dyZWdhdGUsIHZhcikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsIHNlbGYuY29uLnNldF9hdXRob3JpemVyLCB2YXIpCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzZWxmLmNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlciwgdmFyKQoKICAgIGRlZiBDaGVja0Nvbm5lY3Rpb25DYWxsKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIENhbGwgYSBjb25uZWN0aW9uIHdpdGggYSBub24tc3RyaW5nIFNRTCByZXF1ZXN0OiBjaGVjayBlcnJvciBoYW5kbGluZwogICAgICAgIG9mIHRoZSBzdGF0ZW1lbnQgY29uc3RydWN0b3IuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLldhcm5pbmcsIHNlbGYuY29uLCAxKQoKICAgIGRlZiBDaGVja0NvbGxhdGlvbihzZWxmKToKICAgICAgICBkZWYgY29sbGF0aW9uX2NiKGEsIGIpOgogICAgICAgICAgICByZXR1cm4gMQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yLCBzZWxmLmNvbi5jcmVhdGVfY29sbGF0aW9uLAogICAgICAgICAgICAjIExvbmUgc3Vycm9nYXRlIGNhbm5vdCBiZSBlbmNvZGVkIHRvIHRoZSBkZWZhdWx0IGVuY29kaW5nICh1dGY4KQogICAgICAgICAgICAiXHVEQzgwIiwgY29sbGF0aW9uX2NiKQoKICAgIGRlZiBDaGVja1JlY3Vyc2l2ZUN1cnNvclVzZShzZWxmKToKICAgICAgICAiIiIKICAgICAgICBodHRwOi8vYnVncy5weXRob24ub3JnL2lzc3VlMTA4MTEKCiAgICAgICAgUmVjdXJzaXZlbHkgdXNpbmcgYSBjdXJzb3IsIHN1Y2ggYXMgd2hlbiByZXVzaW5nIGl0IGZyb20gYSBnZW5lcmF0b3IgbGVkIHRvIHNlZ2ZhdWx0cy4KICAgICAgICBOb3cgd2UgY2F0Y2ggcmVjdXJzaXZlIGN1cnNvciB1c2FnZSBhbmQgcmFpc2UgYSBQcm9ncmFtbWluZ0Vycm9yLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCgogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJjcmVhdGUgdGFibGUgYSAoYmFyKSIpCiAgICAgICAgY3VyLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBiIChiYXopIikKCiAgICAgICAgZGVmIGZvbygpOgogICAgICAgICAgICBjdXIuZXhlY3V0ZSgiaW5zZXJ0IGludG8gYSAoYmFyKSB2YWx1ZXMgKD8pIiwgKDEsKSkKICAgICAgICAgICAgeWllbGQgMQoKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yKToKICAgICAgICAgICAgY3VyLmV4ZWN1dGVtYW55KCJpbnNlcnQgaW50byBiIChiYXopIHZhbHVlcyAoPykiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChpLCkgZm9yIGkgaW4gZm9vKCkpKQoKICAgIGRlZiBDaGVja0NvbnZlcnRUaW1lc3RhbXBNaWNyb3NlY29uZFBhZGRpbmcoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgaHR0cDovL2J1Z3MucHl0aG9uLm9yZy9pc3N1ZTE0NzIwCgogICAgICAgIFRoZSBtaWNyb3NlY29uZCBwYXJzaW5nIG9mIGNvbnZlcnRfdGltZXN0YW1wKCkgc2hvdWxkIHBhZCB3aXRoIHplcm9zLAogICAgICAgIHNpbmNlIHRoZSBtaWNyb3NlY29uZCBzdHJpbmcgIjQ1NiIgYWN0dWFsbHkgcmVwcmVzZW50cyAiNDU2MDAwIi4KICAgICAgICAiIiIKCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9ERUNMVFlQRVMpCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoIkNSRUFURSBUQUJMRSB0ICh4IFRJTUVTVEFNUCkiKQoKICAgICAgICAjIE1pY3Jvc2Vjb25kcyBzaG91bGQgYmUgNDU2MDAwCiAgICAgICAgY3VyLmV4ZWN1dGUoIklOU0VSVCBJTlRPIHQgKHgpIFZBTFVFUyAoJzIwMTItMDQtMDQgMTU6MDY6MDAuNDU2JykiKQoKICAgICAgICAjIE1pY3Jvc2Vjb25kcyBzaG91bGQgYmUgdHJ1bmNhdGVkIHRvIDEyMzQ1NgogICAgICAgIGN1ci5leGVjdXRlKCJJTlNFUlQgSU5UTyB0ICh4KSBWQUxVRVMgKCcyMDEyLTA0LTA0IDE1OjA2OjAwLjEyMzQ1Njc4OScpIikKCiAgICAgICAgY3VyLmV4ZWN1dGUoIlNFTEVDVCAqIEZST00gdCIpCiAgICAgICAgdmFsdWVzID0gW3hbMF0gZm9yIHggaW4gY3VyLmZldGNoYWxsKCldCgogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwodmFsdWVzLCBbCiAgICAgICAgICAgIGRhdGV0aW1lLmRhdGV0aW1lKDIwMTIsIDQsIDQsIDE1LCA2LCAwLCA0NTYwMDApLAogICAgICAgICAgICBkYXRldGltZS5kYXRldGltZSgyMDEyLCA0LCA0LCAxNSwgNiwgMCwgMTIzNDU2KSwKICAgICAgICBdKQoKICAgIGRlZiBDaGVja0ludmFsaWRJc29sYXRpb25MZXZlbFR5cGUoc2VsZik6CiAgICAgICAgIyBpc29sYXRpb24gbGV2ZWwgaXMgYSBzdHJpbmcsIG5vdCBhbiBpbnRlZ2VyCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNxbGl0ZS5jb25uZWN0LCAiOm1lbW9yeToiLCBpc29sYXRpb25fbGV2ZWw9MTIzKQoKCiAgICBkZWYgQ2hlY2tOdWxsQ2hhcmFjdGVyKHNlbGYpOgogICAgICAgICMgSXNzdWUgIzIxMTQ3CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCBjb24sICJcMHNlbGVjdCAxIikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCBjb24sICJzZWxlY3QgMVwwIikKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCBjdXIuZXhlY3V0ZSwgIiBcMHNlbGVjdCAyIikKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhWYWx1ZUVycm9yLCBjdXIuZXhlY3V0ZSwgInNlbGVjdCAyXDAiKQoKICAgIGRlZiBDaGVja0NvbW1pdEN1cnNvclJlc2V0KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIENvbm5lY3Rpb24uY29tbWl0KCkgZGlkIHJlc2V0IGN1cnNvcnMsIHdoaWNoIG1hZGUgc3FsaXRlMwogICAgICAgIHRvIHJldHVybiByb3dzIG11bHRpcGxlIHRpbWVzIHdoZW4gZmV0Y2hlZCBmcm9tIGN1cnNvcnMKICAgICAgICBhZnRlciBjb21taXQuIFNlZSBpc3N1ZXMgMTA1MTMgYW5kIDIzMTI5IGZvciBkZXRhaWxzLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmV4ZWN1dGVzY3JpcHQoIiIiCiAgICAgICAgY3JlYXRlIHRhYmxlIHQoYyk7CiAgICAgICAgY3JlYXRlIHRhYmxlIHQyKGMpOwogICAgICAgIGluc2VydCBpbnRvIHQgdmFsdWVzKDApOwogICAgICAgIGluc2VydCBpbnRvIHQgdmFsdWVzKDEpOwogICAgICAgIGluc2VydCBpbnRvIHQgdmFsdWVzKDIpOwogICAgICAgICIiIikKCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjb24uaXNvbGF0aW9uX2xldmVsLCAiIikKCiAgICAgICAgY291bnRlciA9IDAKICAgICAgICBmb3IgaSwgcm93IGluIGVudW1lcmF0ZShjb24uZXhlY3V0ZSgic2VsZWN0IGMgZnJvbSB0IikpOgogICAgICAgICAgICB3aXRoIHNlbGYuc3ViVGVzdChpPWksIHJvdz1yb3cpOgogICAgICAgICAgICAgICAgY29uLmV4ZWN1dGUoImluc2VydCBpbnRvIHQyKGMpIHZhbHVlcyAoPykiLCAoaSwpKQogICAgICAgICAgICAgICAgY29uLmNvbW1pdCgpCiAgICAgICAgICAgICAgICBpZiBjb3VudGVyID09IDA6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sIDApCiAgICAgICAgICAgICAgICBlbGlmIGNvdW50ZXIgPT0gMToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJvd1swXSwgMSkKICAgICAgICAgICAgICAgIGVsaWYgY291bnRlciA9PSAyOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocm93WzBdLCAyKQogICAgICAgICAgICAgICAgY291bnRlciArPSAxCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjb3VudGVyLCAzLCAic2hvdWxkIGhhdmUgcmV0dXJuZWQgZXhhY3RseSB0aHJlZSByb3dzIikKCiAgICBkZWYgQ2hlY2tCcG8zMTc3MChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBUaGUgaW50ZXJwcmV0ZXIgc2hvdWxkbid0IGNyYXNoIGluIGNhc2UgQ3Vyc29yLl9faW5pdF9fKCkgaXMgY2FsbGVkCiAgICAgICAgbW9yZSB0aGFuIG9uY2UuCiAgICAgICAgIiIiCiAgICAgICAgZGVmIGNhbGxiYWNrKCphcmdzKToKICAgICAgICAgICAgcGFzcwogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY3VyID0gc3FsaXRlLkN1cnNvcihjb24pCiAgICAgICAgcmVmID0gd2Vha3JlZi5yZWYoY3VyLCBjYWxsYmFjaykKICAgICAgICBjdXIuX19pbml0X18oY29uKQogICAgICAgIGRlbCBjdXIKICAgICAgICAjIFRoZSBpbnRlcnByZXRlciBzaG91bGRuJ3QgY3Jhc2ggd2hlbiByZWYgaXMgY29sbGVjdGVkLgogICAgICAgIGRlbCByZWYKICAgICAgICBzdXBwb3J0LmdjX2NvbGxlY3QoKQoKCmRlZiBzdWl0ZSgpOgogICAgcmVncmVzc2lvbl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShSZWdyZXNzaW9uVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKChyZWdyZXNzaW9uX3N1aXRlLCkpCgpkZWYgdGVzdCgpOgogICAgcnVubmVyID0gdW5pdHRlc3QuVGV4dFRlc3RSdW5uZXIoKQogICAgcnVubmVyLnJ1bihzdWl0ZSgpKQoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIHRlc3QoKQo=