Iy0qLSBjb2Rpbmc6IElTTy04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvaG9va3MucHk6IHRlc3RzIGZvciB2YXJpb3VzIFNRTGl0ZS1zcGVjaWZpYyBob29rcwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMDcgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgdW5pdHRlc3QKaW1wb3J0IHNxbGl0ZTMgYXMgc3FsaXRlCgpjbGFzcyBDb2xsYXRpb25UZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAgICBkZWYgc2V0VXAoc2VsZik6CiAgICAgICAgcGFzcwoKICAgIGRlZiB0ZWFyRG93bihzZWxmKToKICAgICAgICBwYXNzCgogICAgZGVmIENoZWNrQ3JlYXRlQ29sbGF0aW9uTm90Q2FsbGFibGUoc2VsZik6CiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5jcmVhdGVfY29sbGF0aW9uKCJYIiwgNDIpCiAgICAgICAgICAgIHNlbGYuZmFpbCgic2hvdWxkIGhhdmUgcmFpc2VkIGEgVHlwZUVycm9yIikKICAgICAgICBleGNlcHQgVHlwZUVycm9yIGFzIGU6CiAgICAgICAgICAgIHNlbGYuZmFpbFVubGVzc0VxdWFsKGUuYXJnc1swXSwgInBhcmFtZXRlciBtdXN0IGJlIGNhbGxhYmxlIikKCiAgICBkZWYgQ2hlY2tDcmVhdGVDb2xsYXRpb25Ob3RBc2NpaShzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIHRyeToKICAgICAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oImNvbGzkIiwgY21wKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhIFByb2dyYW1taW5nRXJyb3IiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvciBhcyBlOgogICAgICAgICAgICBwYXNzCgogICAgZGVmIENoZWNrQ29sbGF0aW9uSXNVc2VkKHNlbGYpOgogICAgICAgIGlmIHNxbGl0ZS52ZXJzaW9uX2luZm8gPCAoMywgMiwgMSk6ICAjIG9sZCBTUUxpdGUgdmVyc2lvbnMgY3Jhc2ggb24gdGhpcyB0ZXN0CiAgICAgICAgICAgIHJldHVybgogICAgICAgIGRlZiBteWNvbGwoeCwgeSk6CiAgICAgICAgICAgICMgcmV2ZXJzZSBvcmRlcgogICAgICAgICAgICByZXR1cm4gLWNtcCh4LCB5KQoKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5jcmVhdGVfY29sbGF0aW9uKCJteWNvbGwiLCBteWNvbGwpCiAgICAgICAgc3FsID0gIiIiCiAgICAgICAgICAgIHNlbGVjdCB4IGZyb20gKAogICAgICAgICAgICBzZWxlY3QgJ2EnIGFzIHgKICAgICAgICAgICAgdW5pb24KICAgICAgICAgICAgc2VsZWN0ICdiJyBhcyB4CiAgICAgICAgICAgIHVuaW9uCiAgICAgICAgICAgIHNlbGVjdCAnYycgYXMgeAogICAgICAgICAgICApIG9yZGVyIGJ5IHggY29sbGF0ZSBteWNvbGwKICAgICAgICAgICAgIiIiCiAgICAgICAgcmVzdWx0ID0gY29uLmV4ZWN1dGUoc3FsKS5mZXRjaGFsbCgpCiAgICAgICAgaWYgcmVzdWx0WzBdWzBdICE9ICJjIiBvciByZXN1bHRbMV1bMF0gIT0gImIiIG9yIHJlc3VsdFsyXVswXSAhPSAiYSI6CiAgICAgICAgICAgIHNlbGYuZmFpbCgidGhlIGV4cGVjdGVkIG9yZGVyIHdhcyBub3QgcmV0dXJuZWQiKQoKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgTm9uZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJlc3VsdCA9IGNvbi5leGVjdXRlKHNxbCkuZmV0Y2hhbGwoKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3IgYXMgZToKICAgICAgICAgICAgc2VsZi5mYWlsVW5sZXNzRXF1YWwoZS5hcmdzWzBdLmxvd2VyKCksICJubyBzdWNoIGNvbGxhdGlvbiBzZXF1ZW5jZTogbXljb2xsIikKCiAgICBkZWYgQ2hlY2tDb2xsYXRpb25SZWdpc3RlclR3aWNlKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJlZ2lzdGVyIHR3byBkaWZmZXJlbnQgY29sbGF0aW9uIGZ1bmN0aW9ucyB1bmRlciB0aGUgc2FtZSBuYW1lLgogICAgICAgIFZlcmlmeSB0aGF0IHRoZSBsYXN0IG9uZSBpcyBhY3R1YWxseSB1c2VkLgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oIm15Y29sbCIsIGNtcCkKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgbGFtYmRhIHgsIHk6IC1jbXAoeCwgeSkpCiAgICAgICAgcmVzdWx0ID0gY29uLmV4ZWN1dGUoIiIiCiAgICAgICAgICAgIHNlbGVjdCB4IGZyb20gKHNlbGVjdCAnYScgYXMgeCB1bmlvbiBzZWxlY3QgJ2InIGFzIHgpIG9yZGVyIGJ5IHggY29sbGF0ZSBteWNvbGwKICAgICAgICAgICAgIiIiKS5mZXRjaGFsbCgpCiAgICAgICAgaWYgcmVzdWx0WzBdWzBdICE9ICdiJyBvciByZXN1bHRbMV1bMF0gIT0gJ2EnOgogICAgICAgICAgICBzZWxmLmZhaWwoIndyb25nIGNvbGxhdGlvbiBmdW5jdGlvbiBpcyB1c2VkIikKCiAgICBkZWYgQ2hlY2tEZXJlZ2lzdGVyQ29sbGF0aW9uKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJlZ2lzdGVyIGEgY29sbGF0aW9uLCB0aGVuIGRlcmVnaXN0ZXIgaXQuIE1ha2Ugc3VyZSBhbiBlcnJvciBpcyByYWlzZWQgaWYgd2UgdHJ5CiAgICAgICAgdG8gdXNlIGl0LgogICAgICAgICIiIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmNyZWF0ZV9jb2xsYXRpb24oIm15Y29sbCIsIGNtcCkKICAgICAgICBjb24uY3JlYXRlX2NvbGxhdGlvbigibXljb2xsIiwgTm9uZSkKICAgICAgICB0cnk6CiAgICAgICAgICAgIGNvbi5leGVjdXRlKCJzZWxlY3QgJ2EnIGFzIHggdW5pb24gc2VsZWN0ICdiJyBhcyB4IG9yZGVyIGJ5IHggY29sbGF0ZSBteWNvbGwiKQogICAgICAgICAgICBzZWxmLmZhaWwoInNob3VsZCBoYXZlIHJhaXNlZCBhbiBPcGVyYXRpb25hbEVycm9yIikKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3IgYXMgZToKICAgICAgICAgICAgaWYgbm90IGUuYXJnc1swXS5zdGFydHN3aXRoKCJubyBzdWNoIGNvbGxhdGlvbiBzZXF1ZW5jZSIpOgogICAgICAgICAgICAgICAgc2VsZi5mYWlsKCJ3cm9uZyBPcGVyYXRpb25hbEVycm9yIHJhaXNlZCIpCgpjbGFzcyBQcm9ncmVzc1Rlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBDaGVja1Byb2dyZXNzSGFuZGxlclVzZWQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGVzdCB0aGF0IHRoZSBwcm9ncmVzcyBoYW5kbGVyIGlzIGludm9rZWQgb25jZSBpdCBpcyBzZXQuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBwcm9ncmVzc19jYWxscyA9IFtdCiAgICAgICAgZGVmIHByb2dyZXNzKCk6CiAgICAgICAgICAgIHByb2dyZXNzX2NhbGxzLmFwcGVuZChOb25lKQogICAgICAgICAgICByZXR1cm4gMAogICAgICAgIGNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlcihwcm9ncmVzcywgMSkKICAgICAgICBjb24uZXhlY3V0ZSgiIiIKICAgICAgICAgICAgY3JlYXRlIHRhYmxlIGZvbyhhLCBiKQogICAgICAgICAgICAiIiIpCiAgICAgICAgc2VsZi5mYWlsVW5sZXNzKHByb2dyZXNzX2NhbGxzKQoKCiAgICBkZWYgQ2hlY2tPcGNvZGVDb3VudChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBUZXN0IHRoYXQgdGhlIG9wY29kZSBhcmd1bWVudCBpcyByZXNwZWN0ZWQuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBwcm9ncmVzc19jYWxscyA9IFtdCiAgICAgICAgZGVmIHByb2dyZXNzKCk6CiAgICAgICAgICAgIHByb2dyZXNzX2NhbGxzLmFwcGVuZChOb25lKQogICAgICAgICAgICByZXR1cm4gMAogICAgICAgIGNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlcihwcm9ncmVzcywgMSkKICAgICAgICBjdXJzID0gY29uLmN1cnNvcigpCiAgICAgICAgY3Vycy5leGVjdXRlKCIiIgogICAgICAgICAgICBjcmVhdGUgdGFibGUgZm9vIChhLCBiKQogICAgICAgICAgICAiIiIpCiAgICAgICAgZmlyc3RfY291bnQgPSBsZW4ocHJvZ3Jlc3NfY2FsbHMpCiAgICAgICAgcHJvZ3Jlc3NfY2FsbHMgPSBbXQogICAgICAgIGNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlcihwcm9ncmVzcywgMikKICAgICAgICBjdXJzLmV4ZWN1dGUoIiIiCiAgICAgICAgICAgIGNyZWF0ZSB0YWJsZSBiYXIgKGEsIGIpCiAgICAgICAgICAgICIiIikKICAgICAgICBzZWNvbmRfY291bnQgPSBsZW4ocHJvZ3Jlc3NfY2FsbHMpCiAgICAgICAgc2VsZi5mYWlsVW5sZXNzKGZpcnN0X2NvdW50ID4gc2Vjb25kX2NvdW50KQoKICAgIGRlZiBDaGVja0NhbmNlbE9wZXJhdGlvbihzZWxmKToKICAgICAgICAiIiIKICAgICAgICBUZXN0IHRoYXQgcmV0dXJuaW5nIGEgbm9uLXplcm8gdmFsdWUgc3RvcHMgdGhlIG9wZXJhdGlvbiBpbiBwcm9ncmVzcy4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIHByb2dyZXNzX2NhbGxzID0gW10KICAgICAgICBkZWYgcHJvZ3Jlc3MoKToKICAgICAgICAgICAgcHJvZ3Jlc3NfY2FsbHMuYXBwZW5kKE5vbmUpCiAgICAgICAgICAgIHJldHVybiAxCiAgICAgICAgY29uLnNldF9wcm9ncmVzc19oYW5kbGVyKHByb2dyZXNzLCAxKQogICAgICAgIGN1cnMgPSBjb24uY3Vyc29yKCkKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcygKICAgICAgICAgICAgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3IsCiAgICAgICAgICAgIGN1cnMuZXhlY3V0ZSwKICAgICAgICAgICAgImNyZWF0ZSB0YWJsZSBiYXIgKGEsIGIpIikKCiAgICBkZWYgQ2hlY2tDbGVhckhhbmRsZXIoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVGVzdCB0aGF0IHNldHRpbmcgdGhlIHByb2dyZXNzIGhhbmRsZXIgdG8gTm9uZSBjbGVhcnMgdGhlIHByZXZpb3VzbHkgc2V0IGhhbmRsZXIuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBhY3Rpb24gPSAwCiAgICAgICAgZGVmIHByb2dyZXNzKCk6CiAgICAgICAgICAgIGFjdGlvbiA9IDEKICAgICAgICAgICAgcmV0dXJuIDAKICAgICAgICBjb24uc2V0X3Byb2dyZXNzX2hhbmRsZXIocHJvZ3Jlc3MsIDEpCiAgICAgICAgY29uLnNldF9wcm9ncmVzc19oYW5kbGVyKE5vbmUsIDEpCiAgICAgICAgY29uLmV4ZWN1dGUoInNlbGVjdCAxIHVuaW9uIHNlbGVjdCAyIHVuaW9uIHNlbGVjdCAzIikuZmV0Y2hhbGwoKQogICAgICAgIHNlbGYuZmFpbFVubGVzc0VxdWFsKGFjdGlvbiwgMCwgInByb2dyZXNzIGhhbmRsZXIgd2FzIG5vdCBjbGVhcmVkIikKCmRlZiBzdWl0ZSgpOgogICAgY29sbGF0aW9uX3N1aXRlID0gdW5pdHRlc3QubWFrZVN1aXRlKENvbGxhdGlvblRlc3RzLCAiQ2hlY2siKQogICAgcHJvZ3Jlc3Nfc3VpdGUgPSB1bml0dGVzdC5tYWtlU3VpdGUoUHJvZ3Jlc3NUZXN0cywgIkNoZWNrIikKICAgIHJldHVybiB1bml0dGVzdC5UZXN0U3VpdGUoKGNvbGxhdGlvbl9zdWl0ZSwgcHJvZ3Jlc3Nfc3VpdGUpKQoKZGVmIHRlc3QoKToKICAgIHJ1bm5lciA9IHVuaXR0ZXN0LlRleHRUZXN0UnVubmVyKCkKICAgIHJ1bm5lci5ydW4oc3VpdGUoKSkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB0ZXN0KCkK