Iy0qLSBjb2Rpbmc6IGlzby04ODU5LTEgLSotCiMgcHlzcWxpdGUyL3Rlc3QvcmVncmVzc2lvbi5weTogcHlzcWxpdGUgcmVncmVzc2lvbiB0ZXN0cwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgR2VyaGFyZCBI5HJpbmcgPGdoQGdoYWVyaW5nLmRlPgojCiMgVGhpcyBmaWxlIGlzIHBhcnQgb2YgcHlzcWxpdGUuCiMKIyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZAojIHdhcnJhbnR5LiAgSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMKIyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLgojCiMgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiMgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAojIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKIwojIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90CiMgICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUKIyAgICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmUKIyAgICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLgojIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlCiMgICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLgojIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uCgppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IHVuaXR0ZXN0CmltcG9ydCBzcWxpdGUzIGFzIHNxbGl0ZQppbXBvcnQgd2Vha3JlZgppbXBvcnQgZnVuY3Rvb2xzCmZyb20gdGVzdCBpbXBvcnQgc3VwcG9ydAoKY2xhc3MgUmVncmVzc2lvblRlc3RzKHVuaXR0ZXN0LlRlc3RDYXNlKToKICAgIGRlZiBzZXRVcChzZWxmKToKICAgICAgICBzZWxmLmNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCgogICAgZGVmIHRlYXJEb3duKHNlbGYpOgogICAgICAgIHNlbGYuY29uLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tQcmFnbWFVc2VyVmVyc2lvbihzZWxmKToKICAgICAgICAjIFRoaXMgdXNlZCB0byBjcmFzaCBweXNxbGl0ZSBiZWNhdXNlIHRoaXMgcHJhZ21hIGNvbW1hbmQgcmV0dXJucyBOVUxMIGZvciB0aGUgY29sdW1uIG5hbWUKICAgICAgICBjdXIgPSBzZWxmLmNvbi5jdXJzb3IoKQogICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgdXNlcl92ZXJzaW9uIikKCiAgICBkZWYgQ2hlY2tQcmFnbWFTY2hlbWFWZXJzaW9uKHNlbGYpOgogICAgICAgICMgVGhpcyBzdGlsbCBjcmFzaGVkIHB5c3FsaXRlIDw9IDIuMi4xCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IiwgZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9DT0xOQU1FUykKICAgICAgICB0cnk6CiAgICAgICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJwcmFnbWEgc2NoZW1hX3ZlcnNpb24iKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIGN1ci5jbG9zZSgpCiAgICAgICAgICAgIGNvbi5jbG9zZSgpCgogICAgZGVmIENoZWNrU3RhdGVtZW50UmVzZXQoc2VsZik6CiAgICAgICAgIyBweXNxbGl0ZSAyLjEuMCB0byAyLjIuMCBoYXZlIHRoZSBwcm9ibGVtIHRoYXQgbm90IGFsbCBzdGF0ZW1lbnRzIGFyZQogICAgICAgICMgcmVzZXQgYmVmb3JlIGEgcm9sbGJhY2ssIGJ1dCBvbmx5IHRob3NlIHRoYXQgYXJlIHN0aWxsIGluIHRoZQogICAgICAgICMgc3RhdGVtZW50IGNhY2hlLiBUaGUgb3RoZXJzIGFyZSBub3QgYWNjZXNzaWJsZSBmcm9tIHRoZSBjb25uZWN0aW9uIG9iamVjdC4KICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBjYWNoZWRfc3RhdGVtZW50cz01KQogICAgICAgIGN1cnNvcnMgPSBbY29uLmN1cnNvcigpIGZvciB4IGluIHJhbmdlKDUpXQogICAgICAgIGN1cnNvcnNbMF0uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIHRlc3QoeCkiKQogICAgICAgIGZvciBpIGluIHJhbmdlKDEwKToKICAgICAgICAgICAgY3Vyc29yc1swXS5leGVjdXRlbWFueSgiaW5zZXJ0IGludG8gdGVzdCh4KSB2YWx1ZXMgKD8pIiwgWyh4LCkgZm9yIHggaW4gcmFuZ2UoMTApXSkKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoNSk6CiAgICAgICAgICAgIGN1cnNvcnNbaV0uZXhlY3V0ZSgiICIgKiBpICsgInNlbGVjdCB4IGZyb20gdGVzdCIpCgogICAgICAgIGNvbi5yb2xsYmFjaygpCgogICAgZGVmIENoZWNrQ29sdW1uTmFtZVdpdGhTcGFjZXMoc2VsZik6CiAgICAgICAgY3VyID0gc2VsZi5jb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgnc2VsZWN0IDEgYXMgImZvbyBiYXIgW2RhdGV0aW1lXSInKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoY3VyLmRlc2NyaXB0aW9uWzBdWzBdLCAiZm9vIGJhciBbZGF0ZXRpbWVdIikKCiAgICAgICAgY3VyLmV4ZWN1dGUoJ3NlbGVjdCAxIGFzICJmb28gYmF6IicpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjdXIuZGVzY3JpcHRpb25bMF1bMF0sICJmb28gYmF6IikKCiAgICBkZWYgQ2hlY2tTdGF0ZW1lbnRGaW5hbGl6YXRpb25PbkNsb3NlRGIoc2VsZik6CiAgICAgICAgIyBweXNxbGl0ZSB2ZXJzaW9ucyA8PSAyLjMuMyBvbmx5IGZpbmFsaXplZCBzdGF0ZW1lbnRzIGluIHRoZSBzdGF0ZW1lbnQKICAgICAgICAjIGNhY2hlIHdoZW4gY2xvc2luZyB0aGUgZGF0YWJhc2UuIHN0YXRlbWVudHMgdGhhdCB3ZXJlIHN0aWxsCiAgICAgICAgIyByZWZlcmVuY2VkIGluIGN1cnNvcnMgd2VyZW4ndCBjbG9zZWQgYW5kIGNvdWxkIHByb3Zva2UgIgogICAgICAgICMgIk9wZXJhdGlvbmFsRXJyb3I6IFVuYWJsZSB0byBjbG9zZSBkdWUgdG8gdW5maW5hbGlzZWQgc3RhdGVtZW50cyIuCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXJzb3JzID0gW10KICAgICAgICAjIGRlZmF1bHQgc3RhdGVtZW50IGNhY2hlIHNpemUgaXMgMTAwCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMTA1KToKICAgICAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgICAgIGN1cnNvcnMuYXBwZW5kKGN1cikKICAgICAgICAgICAgY3VyLmV4ZWN1dGUoInNlbGVjdCAxIHggdW5pb24gc2VsZWN0ICIgKyBzdHIoaSkpCiAgICAgICAgY29uLmNsb3NlKCkKCiAgICBAdW5pdHRlc3Quc2tpcElmKHNxbGl0ZS5zcWxpdGVfdmVyc2lvbl9pbmZvIDwgKDMsIDIsIDIpLCAnbmVlZHMgc3FsaXRlIDMuMi4yIG9yIG5ld2VyJykKICAgIGRlZiBDaGVja09uQ29uZmxpY3RSb2xsYmFjayhzZWxmKToKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGNvbi5leGVjdXRlKCJjcmVhdGUgdGFibGUgZm9vKHgsIHVuaXF1ZSh4KSBvbiBjb25mbGljdCByb2xsYmFjaykiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgxKSIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKHgpIHZhbHVlcyAoMSkiKQogICAgICAgIGV4Y2VwdCBzcWxpdGUuRGF0YWJhc2VFcnJvcjoKICAgICAgICAgICAgcGFzcwogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICgyKSIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICBjb24uY29tbWl0KCkKICAgICAgICBleGNlcHQgc3FsaXRlLk9wZXJhdGlvbmFsRXJyb3I6CiAgICAgICAgICAgIHNlbGYuZmFpbCgicHlzcWxpdGUga25ldyBub3RoaW5nIGFib3V0IHRoZSBpbXBsaWNpdCBST0xMQkFDSyIpCgogICAgZGVmIENoZWNrV29ya2Fyb3VuZEZvckJ1Z2d5U3FsaXRlVHJhbnNmZXJCaW5kaW5ncyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB3b3VsZCBjcmFzaCB3aXRoIG9sZGVyIFNRTGl0ZSB2ZXJzaW9ucyB1bmxlc3MKICAgICAgICBhIHdvcmthcm91bmQgaXMgaW1wbGVtZW50ZWQuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKICAgICAgICBzZWxmLmNvbi5leGVjdXRlKCJkcm9wIHRhYmxlIGZvbyIpCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyhiYXIpIikKCiAgICBkZWYgQ2hlY2tFbXB0eVN0YXRlbWVudChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBweXNxbGl0ZSB1c2VkIHRvIHNlZ2ZhdWx0IHdpdGggU1FMaXRlIHZlcnNpb25zIDMuNS54LiBUaGVzZSByZXR1cm4gTlVMTAogICAgICAgIGZvciAibm8tb3BlcmF0aW9uIiBzdGF0ZW1lbnRzCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgiIikKCiAgICBkZWYgQ2hlY2tUeXBlTWFwVXNhZ2Uoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgcHlzcWxpdGUgdW50aWwgMi40LjEgZGlkIG5vdCByZWJ1aWxkIHRoZSByb3dfY2FzdF9tYXAgd2hlbiByZWNvbXBpbGluZwogICAgICAgIGEgc3RhdGVtZW50LiBUaGlzIHRlc3QgZXhoaWJpdHMgdGhlIHByb2JsZW0uCiAgICAgICAgIiIiCiAgICAgICAgU0VMRUNUID0gInNlbGVjdCAqIGZyb20gZm9vIgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIsZGV0ZWN0X3R5cGVzPXNxbGl0ZS5QQVJTRV9ERUNMVFlQRVMpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyIHRpbWVzdGFtcCkiKQogICAgICAgIGNvbi5leGVjdXRlKCJpbnNlcnQgaW50byBmb28oYmFyKSB2YWx1ZXMgKD8pIiwgKGRhdGV0aW1lLmRhdGV0aW1lLm5vdygpLCkpCiAgICAgICAgY29uLmV4ZWN1dGUoU0VMRUNUKQogICAgICAgIGNvbi5leGVjdXRlKCJkcm9wIHRhYmxlIGZvbyIpCiAgICAgICAgY29uLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyIGludGVnZXIpIikKICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gZm9vKGJhcikgdmFsdWVzICg1KSIpCiAgICAgICAgY29uLmV4ZWN1dGUoU0VMRUNUKQoKICAgIGRlZiBDaGVja0Vycm9yTXNnRGVjb2RlRXJyb3Ioc2VsZik6CiAgICAgICAgIyBXaGVuIHBvcnRpbmcgdGhlIG1vZHVsZSB0byBQeXRob24gMy4wLCB0aGUgZXJyb3IgbWVzc2FnZSBhYm91dAogICAgICAgICMgZGVjb2RpbmcgZXJyb3JzIGRpc2FwcGVhcmVkLiBUaGlzIHZlcmlmaWVzIHRoZXkncmUgYmFjayBhZ2Fpbi4KICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5PcGVyYXRpb25hbEVycm9yKSBhcyBjbToKICAgICAgICAgICAgc2VsZi5jb24uZXhlY3V0ZSgic2VsZWN0ICd4eHgnIHx8ID8gfHwgJ3l5eScgY29sbmFtZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJ5dGVzKGJ5dGVhcnJheShbMjUwXSkpLCkpLmZldGNob25lKCkKICAgICAgICBtc2cgPSAiQ291bGQgbm90IGRlY29kZSB0byBVVEYtOCBjb2x1bW4gJ2NvbG5hbWUnIHdpdGggdGV4dCAneHh4IgogICAgICAgIHNlbGYuYXNzZXJ0SW4obXNnLCBzdHIoY20uZXhjZXB0aW9uKSkKCiAgICBkZWYgQ2hlY2tSZWdpc3RlckFkYXB0ZXIoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgU2VlIGlzc3VlIDMzMTIuCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoVHlwZUVycm9yLCBzcWxpdGUucmVnaXN0ZXJfYWRhcHRlciwge30sIE5vbmUpCgogICAgZGVmIENoZWNrU2V0SXNvbGF0aW9uTGV2ZWwoc2VsZik6CiAgICAgICAgIyBTZWUgaXNzdWUgMjc4ODEuCiAgICAgICAgY2xhc3MgQ3VzdG9tU3RyKHN0cik6CiAgICAgICAgICAgIGRlZiB1cHBlcihzZWxmKToKICAgICAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgICAgIGRlZiBfX2RlbF9fKHNlbGYpOgogICAgICAgICAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9ICIiCgogICAgICAgIGNvbiA9IHNxbGl0ZS5jb25uZWN0KCI6bWVtb3J5OiIpCiAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IE5vbmUKICAgICAgICBmb3IgbGV2ZWwgaW4gIiIsICJERUZFUlJFRCIsICJJTU1FRElBVEUiLCAiRVhDTFVTSVZFIjoKICAgICAgICAgICAgd2l0aCBzZWxmLnN1YlRlc3QobGV2ZWw9bGV2ZWwpOgogICAgICAgICAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IGxldmVsCiAgICAgICAgICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gbGV2ZWwubG93ZXIoKQogICAgICAgICAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IGxldmVsLmNhcGl0YWxpemUoKQogICAgICAgICAgICAgICAgY29uLmlzb2xhdGlvbl9sZXZlbCA9IEN1c3RvbVN0cihsZXZlbCkKCiAgICAgICAgIyBzZXR0aW5nIGlzb2xhdGlvbl9sZXZlbCBmYWlsdXJlIHNob3VsZCBub3QgYWx0ZXIgcHJldmlvdXMgc3RhdGUKICAgICAgICBjb24uaXNvbGF0aW9uX2xldmVsID0gTm9uZQogICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSAiREVGRVJSRUQiCiAgICAgICAgcGFpcnMgPSBbCiAgICAgICAgICAgICgxLCBUeXBlRXJyb3IpLCAoYicnLCBUeXBlRXJyb3IpLCAoImFiYyIsIFZhbHVlRXJyb3IpLAogICAgICAgICAgICAoIklNTUVESUFURVwwRVhDTFVTSVZFIiwgVmFsdWVFcnJvciksICgiXHhlOSIsIFZhbHVlRXJyb3IpLAogICAgICAgIF0KICAgICAgICBmb3IgdmFsdWUsIGV4YyBpbiBwYWlyczoKICAgICAgICAgICAgd2l0aCBzZWxmLnN1YlRlc3QobGV2ZWw9dmFsdWUpOgogICAgICAgICAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhleGMpOgogICAgICAgICAgICAgICAgICAgIGNvbi5pc29sYXRpb25fbGV2ZWwgPSB2YWx1ZQogICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChjb24uaXNvbGF0aW9uX2xldmVsLCAiREVGRVJSRUQiKQoKICAgIGRlZiBDaGVja0N1cnNvckNvbnN0cnVjdG9yQ2FsbENoZWNrKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgY3Vyc29yIG1ldGhvZHMgY2hlY2sgd2hldGhlciBiYXNlIGNsYXNzIF9faW5pdF9fIHdhcwogICAgICAgIGNhbGxlZC4KICAgICAgICAiIiIKICAgICAgICBjbGFzcyBDdXJzb3Ioc3FsaXRlLkN1cnNvcik6CiAgICAgICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBjb24pOgogICAgICAgICAgICAgICAgcGFzcwoKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIGN1ciA9IEN1cnNvcihjb24pCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvcik6CiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJzZWxlY3QgNCs1IikuZmV0Y2hhbGwoKQogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXNSZWdleChzcWxpdGUuUHJvZ3JhbW1pbmdFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcideQmFzZSBDdXJzb3JcLl9faW5pdF9fIG5vdCBjYWxsZWRcLiQnKToKICAgICAgICAgICAgY3VyLmNsb3NlKCkKCiAgICBkZWYgQ2hlY2tTdHJTdWJjbGFzcyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBUaGUgUHl0aG9uIDMuMCBwb3J0IG9mIHRoZSBtb2R1bGUgZGlkbid0IGNvcGUgd2l0aCB2YWx1ZXMgb2Ygc3ViY2xhc3NlcyBvZiBzdHIuCiAgICAgICAgIiIiCiAgICAgICAgY2xhc3MgTXlTdHIoc3RyKTogcGFzcwogICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoInNlbGVjdCA/IiwgKE15U3RyKCJhYmMiKSwpKQoKICAgIGRlZiBDaGVja0Nvbm5lY3Rpb25Db25zdHJ1Y3RvckNhbGxDaGVjayhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBWZXJpZmllcyB0aGF0IGNvbm5lY3Rpb24gbWV0aG9kcyBjaGVjayB3aGV0aGVyIGJhc2UgY2xhc3MgX19pbml0X18gd2FzCiAgICAgICAgY2FsbGVkLgogICAgICAgICIiIgogICAgICAgIGNsYXNzIENvbm5lY3Rpb24oc3FsaXRlLkNvbm5lY3Rpb24pOgogICAgICAgICAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSk6CiAgICAgICAgICAgICAgICBwYXNzCgogICAgICAgIGNvbiA9IENvbm5lY3Rpb24oIjptZW1vcnk6IikKICAgICAgICB3aXRoIHNlbGYuYXNzZXJ0UmFpc2VzKHNxbGl0ZS5Qcm9ncmFtbWluZ0Vycm9yKToKICAgICAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCgogICAgZGVmIENoZWNrQ3Vyc29yUmVnaXN0cmF0aW9uKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgc3ViY2xhc3NlZCBjdXJzb3IgY2xhc3NlcyBhcmUgY29ycmVjdGx5IHJlZ2lzdGVyZWQgd2l0aAogICAgICAgIHRoZSBjb25uZWN0aW9uIG9iamVjdCwgdG9vLiAgKGZldGNoLWFjcm9zcy1yb2xsYmFjayBwcm9ibGVtKQogICAgICAgICIiIgogICAgICAgIGNsYXNzIENvbm5lY3Rpb24oc3FsaXRlLkNvbm5lY3Rpb24pOgogICAgICAgICAgICBkZWYgY3Vyc29yKHNlbGYpOgogICAgICAgICAgICAgICAgcmV0dXJuIEN1cnNvcihzZWxmKQoKICAgICAgICBjbGFzcyBDdXJzb3Ioc3FsaXRlLkN1cnNvcik6CiAgICAgICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBjb24pOgogICAgICAgICAgICAgICAgc3FsaXRlLkN1cnNvci5fX2luaXRfXyhzZWxmLCBjb24pCgogICAgICAgIGNvbiA9IENvbm5lY3Rpb24oIjptZW1vcnk6IikKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGZvbyh4KSIpCiAgICAgICAgY3VyLmV4ZWN1dGVtYW55KCJpbnNlcnQgaW50byBmb28oeCkgdmFsdWVzICg/KSIsIFsoMywpLCAoNCwpLCAoNSwpXSkKICAgICAgICBjdXIuZXhlY3V0ZSgic2VsZWN0IHggZnJvbSBmb28iKQogICAgICAgIGNvbi5yb2xsYmFjaygpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhzcWxpdGUuSW50ZXJmYWNlRXJyb3IpOgogICAgICAgICAgICBjdXIuZmV0Y2hhbGwoKQoKICAgIGRlZiBDaGVja0F1dG9Db21taXQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgVmVyaWZpZXMgdGhhdCBjcmVhdGluZyBhIGNvbm5lY3Rpb24gaW4gYXV0b2NvbW1pdCBtb2RlIHdvcmtzLgogICAgICAgIDIuNS4zIGludHJvZHVjZWQgYSByZWdyZXNzaW9uIHNvIHRoYXQgdGhlc2UgY291bGQgbm8gbG9uZ2VyCiAgICAgICAgYmUgY3JlYXRlZC4KICAgICAgICAiIiIKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBpc29sYXRpb25fbGV2ZWw9Tm9uZSkKCiAgICBkZWYgQ2hlY2tQcmFnbWFBdXRvY29tbWl0KHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFZlcmlmaWVzIHRoYXQgcnVubmluZyBhIFBSQUdNQSBzdGF0ZW1lbnQgdGhhdCBkb2VzIGFuIGF1dG9jb21taXQgZG9lcwogICAgICAgIHdvcmsuIFRoaXMgZGlkIG5vdCB3b3JrIGluIDIuNS4zLzIuNS40LgogICAgICAgICIiIgogICAgICAgIGN1ciA9IHNlbGYuY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBmb28oYmFyKSIpCiAgICAgICAgY3VyLmV4ZWN1dGUoImluc2VydCBpbnRvIGZvbyhiYXIpIHZhbHVlcyAoNSkiKQoKICAgICAgICBjdXIuZXhlY3V0ZSgicHJhZ21hIHBhZ2Vfc2l6ZSIpCiAgICAgICAgcm93ID0gY3VyLmZldGNob25lKCkKCiAgICBkZWYgQ2hlY2tDb25uZWN0aW9uQ2FsbChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBDYWxsIGEgY29ubmVjdGlvbiB3aXRoIGEgbm9uLXN0cmluZyBTUUwgcmVxdWVzdDogY2hlY2sgZXJyb3IgaGFuZGxpbmcKICAgICAgICBvZiB0aGUgc3RhdGVtZW50IGNvbnN0cnVjdG9yLgogICAgICAgICIiIgogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFR5cGVFcnJvciwgc2VsZi5jb24sIDEpCgogICAgZGVmIENoZWNrQ29sbGF0aW9uKHNlbGYpOgogICAgICAgIGRlZiBjb2xsYXRpb25fY2IoYSwgYik6CiAgICAgICAgICAgIHJldHVybiAxCiAgICAgICAgc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IsIHNlbGYuY29uLmNyZWF0ZV9jb2xsYXRpb24sCiAgICAgICAgICAgICMgTG9uZSBzdXJyb2dhdGUgY2Fubm90IGJlIGVuY29kZWQgdG8gdGhlIGRlZmF1bHQgZW5jb2RpbmcgKHV0ZjgpCiAgICAgICAgICAgICJcdURDODAiLCBjb2xsYXRpb25fY2IpCgogICAgZGVmIENoZWNrUmVjdXJzaXZlQ3Vyc29yVXNlKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIGh0dHA6Ly9idWdzLnB5dGhvbi5vcmcvaXNzdWUxMDgxMQoKICAgICAgICBSZWN1cnNpdmVseSB1c2luZyBhIGN1cnNvciwgc3VjaCBhcyB3aGVuIHJldXNpbmcgaXQgZnJvbSBhIGdlbmVyYXRvciBsZWQgdG8gc2VnZmF1bHRzLgogICAgICAgIE5vdyB3ZSBjYXRjaCByZWN1cnNpdmUgY3Vyc29yIHVzYWdlIGFuZCByYWlzZSBhIFByb2dyYW1taW5nRXJyb3IuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKCiAgICAgICAgY3VyID0gY29uLmN1cnNvcigpCiAgICAgICAgY3VyLmV4ZWN1dGUoImNyZWF0ZSB0YWJsZSBhIChiYXIpIikKICAgICAgICBjdXIuZXhlY3V0ZSgiY3JlYXRlIHRhYmxlIGIgKGJheikiKQoKICAgICAgICBkZWYgZm9vKCk6CiAgICAgICAgICAgIGN1ci5leGVjdXRlKCJpbnNlcnQgaW50byBhIChiYXIpIHZhbHVlcyAoPykiLCAoMSwpKQogICAgICAgICAgICB5aWVsZCAxCgogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXMoc3FsaXRlLlByb2dyYW1taW5nRXJyb3IpOgogICAgICAgICAgICBjdXIuZXhlY3V0ZW1hbnkoImluc2VydCBpbnRvIGIgKGJheikgdmFsdWVzICg/KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGksKSBmb3IgaSBpbiBmb28oKSkpCgogICAgZGVmIENoZWNrQ29udmVydFRpbWVzdGFtcE1pY3Jvc2Vjb25kUGFkZGluZyhzZWxmKToKICAgICAgICAiIiIKICAgICAgICBodHRwOi8vYnVncy5weXRob24ub3JnL2lzc3VlMTQ3MjAKCiAgICAgICAgVGhlIG1pY3Jvc2Vjb25kIHBhcnNpbmcgb2YgY29udmVydF90aW1lc3RhbXAoKSBzaG91bGQgcGFkIHdpdGggemVyb3MsCiAgICAgICAgc2luY2UgdGhlIG1pY3Jvc2Vjb25kIHN0cmluZyAiNDU2IiBhY3R1YWxseSByZXByZXNlbnRzICI0NTYwMDAiLgogICAgICAgICIiIgoKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiLCBkZXRlY3RfdHlwZXM9c3FsaXRlLlBBUlNFX0RFQ0xUWVBFUykKICAgICAgICBjdXIgPSBjb24uY3Vyc29yKCkKICAgICAgICBjdXIuZXhlY3V0ZSgiQ1JFQVRFIFRBQkxFIHQgKHggVElNRVNUQU1QKSIpCgogICAgICAgICMgTWljcm9zZWNvbmRzIHNob3VsZCBiZSA0NTYwMDAKICAgICAgICBjdXIuZXhlY3V0ZSgiSU5TRVJUIElOVE8gdCAoeCkgVkFMVUVTICgnMjAxMi0wNC0wNCAxNTowNjowMC40NTYnKSIpCgogICAgICAgICMgTWljcm9zZWNvbmRzIHNob3VsZCBiZSB0cnVuY2F0ZWQgdG8gMTIzNDU2CiAgICAgICAgY3VyLmV4ZWN1dGUoIklOU0VSVCBJTlRPIHQgKHgpIFZBTFVFUyAoJzIwMTItMDQtMDQgMTU6MDY6MDAuMTIzNDU2Nzg5JykiKQoKICAgICAgICBjdXIuZXhlY3V0ZSgiU0VMRUNUICogRlJPTSB0IikKICAgICAgICB2YWx1ZXMgPSBbeFswXSBmb3IgeCBpbiBjdXIuZmV0Y2hhbGwoKV0KCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh2YWx1ZXMsIFsKICAgICAgICAgICAgZGF0ZXRpbWUuZGF0ZXRpbWUoMjAxMiwgNCwgNCwgMTUsIDYsIDAsIDQ1NjAwMCksCiAgICAgICAgICAgIGRhdGV0aW1lLmRhdGV0aW1lKDIwMTIsIDQsIDQsIDE1LCA2LCAwLCAxMjM0NTYpLAogICAgICAgIF0pCgogICAgZGVmIENoZWNrSW52YWxpZElzb2xhdGlvbkxldmVsVHlwZShzZWxmKToKICAgICAgICAjIGlzb2xhdGlvbiBsZXZlbCBpcyBhIHN0cmluZywgbm90IGFuIGludGVnZXIKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhUeXBlRXJyb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3FsaXRlLmNvbm5lY3QsICI6bWVtb3J5OiIsIGlzb2xhdGlvbl9sZXZlbD0xMjMpCgoKICAgIGRlZiBDaGVja051bGxDaGFyYWN0ZXIoc2VsZik6CiAgICAgICAgIyBJc3N1ZSAjMjExNDcKICAgICAgICBjb24gPSBzcWxpdGUuY29ubmVjdCgiOm1lbW9yeToiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGNvbiwgIlwwc2VsZWN0IDEiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGNvbiwgInNlbGVjdCAxXDAiKQogICAgICAgIGN1ciA9IGNvbi5jdXJzb3IoKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGN1ci5leGVjdXRlLCAiIFwwc2VsZWN0IDIiKQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFZhbHVlRXJyb3IsIGN1ci5leGVjdXRlLCAic2VsZWN0IDJcMCIpCgogICAgZGVmIENoZWNrQ29tbWl0Q3Vyc29yUmVzZXQoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgQ29ubmVjdGlvbi5jb21taXQoKSBkaWQgcmVzZXQgY3Vyc29ycywgd2hpY2ggbWFkZSBzcWxpdGUzCiAgICAgICAgdG8gcmV0dXJuIHJvd3MgbXVsdGlwbGUgdGltZXMgd2hlbiBmZXRjaGVkIGZyb20gY3Vyc29ycwogICAgICAgIGFmdGVyIGNvbW1pdC4gU2VlIGlzc3VlcyAxMDUxMyBhbmQgMjMxMjkgZm9yIGRldGFpbHMuCiAgICAgICAgIiIiCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjb24uZXhlY3V0ZXNjcmlwdCgiIiIKICAgICAgICBjcmVhdGUgdGFibGUgdChjKTsKICAgICAgICBjcmVhdGUgdGFibGUgdDIoYyk7CiAgICAgICAgaW5zZXJ0IGludG8gdCB2YWx1ZXMoMCk7CiAgICAgICAgaW5zZXJ0IGludG8gdCB2YWx1ZXMoMSk7CiAgICAgICAgaW5zZXJ0IGludG8gdCB2YWx1ZXMoMik7CiAgICAgICAgIiIiKQoKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvbi5pc29sYXRpb25fbGV2ZWwsICIiKQoKICAgICAgICBjb3VudGVyID0gMAogICAgICAgIGZvciBpLCByb3cgaW4gZW51bWVyYXRlKGNvbi5leGVjdXRlKCJzZWxlY3QgYyBmcm9tIHQiKSk6CiAgICAgICAgICAgIHdpdGggc2VsZi5zdWJUZXN0KGk9aSwgcm93PXJvdyk6CiAgICAgICAgICAgICAgICBjb24uZXhlY3V0ZSgiaW5zZXJ0IGludG8gdDIoYykgdmFsdWVzICg/KSIsIChpLCkpCiAgICAgICAgICAgICAgICBjb24uY29tbWl0KCkKICAgICAgICAgICAgICAgIGlmIGNvdW50ZXIgPT0gMDoKICAgICAgICAgICAgICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJvd1swXSwgMCkKICAgICAgICAgICAgICAgIGVsaWYgY291bnRlciA9PSAxOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwocm93WzBdLCAxKQogICAgICAgICAgICAgICAgZWxpZiBjb3VudGVyID09IDI6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChyb3dbMF0sIDIpCiAgICAgICAgICAgICAgICBjb3VudGVyICs9IDEKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKGNvdW50ZXIsIDMsICJzaG91bGQgaGF2ZSByZXR1cm5lZCBleGFjdGx5IHRocmVlIHJvd3MiKQoKICAgIGRlZiBDaGVja0JwbzMxNzcwKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFRoZSBpbnRlcnByZXRlciBzaG91bGRuJ3QgY3Jhc2ggaW4gY2FzZSBDdXJzb3IuX19pbml0X18oKSBpcyBjYWxsZWQKICAgICAgICBtb3JlIHRoYW4gb25jZS4KICAgICAgICAiIiIKICAgICAgICBkZWYgY2FsbGJhY2soKmFyZ3MpOgogICAgICAgICAgICBwYXNzCiAgICAgICAgY29uID0gc3FsaXRlLmNvbm5lY3QoIjptZW1vcnk6IikKICAgICAgICBjdXIgPSBzcWxpdGUuQ3Vyc29yKGNvbikKICAgICAgICByZWYgPSB3ZWFrcmVmLnJlZihjdXIsIGNhbGxiYWNrKQogICAgICAgIGN1ci5fX2luaXRfXyhjb24pCiAgICAgICAgZGVsIGN1cgogICAgICAgICMgVGhlIGludGVycHJldGVyIHNob3VsZG4ndCBjcmFzaCB3aGVuIHJlZiBpcyBjb2xsZWN0ZWQuCiAgICAgICAgZGVsIHJlZgogICAgICAgIHN1cHBvcnQuZ2NfY29sbGVjdCgpCgogICAgZGVmIENoZWNrRGVsSXNvbGF0aW9uX2xldmVsU2VnZmF1bHQoc2VsZik6CiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhBdHRyaWJ1dGVFcnJvcik6CiAgICAgICAgICAgIGRlbCBzZWxmLmNvbi5pc29sYXRpb25fbGV2ZWwKCiAgICBkZWYgQ2hlY2tCcG8zNzM0NyhzZWxmKToKICAgICAgICBjbGFzcyBQcmludGVyOgogICAgICAgICAgICBkZWYgbG9nKHNlbGYsICphcmdzKToKICAgICAgICAgICAgICAgIHJldHVybiBzcWxpdGUuU1FMSVRFX09LCgogICAgICAgIGZvciBtZXRob2QgaW4gW3NlbGYuY29uLnNldF90cmFjZV9jYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICBmdW5jdG9vbHMucGFydGlhbChzZWxmLmNvbi5zZXRfcHJvZ3Jlc3NfaGFuZGxlciwgbj0xKSwKICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbi5zZXRfYXV0aG9yaXplcl06CiAgICAgICAgICAgIHByaW50ZXJfaW5zdGFuY2UgPSBQcmludGVyKCkKICAgICAgICAgICAgbWV0aG9kKHByaW50ZXJfaW5zdGFuY2UubG9nKQogICAgICAgICAgICBtZXRob2QocHJpbnRlcl9pbnN0YW5jZS5sb2cpCiAgICAgICAgICAgIHNlbGYuY29uLmV4ZWN1dGUoInNlbGVjdCAxIikgICMgdHJpZ2dlciBzZWcgZmF1bHQKICAgICAgICAgICAgbWV0aG9kKE5vbmUpCgoKCmRlZiBzdWl0ZSgpOgogICAgcmVncmVzc2lvbl9zdWl0ZSA9IHVuaXR0ZXN0Lm1ha2VTdWl0ZShSZWdyZXNzaW9uVGVzdHMsICJDaGVjayIpCiAgICByZXR1cm4gdW5pdHRlc3QuVGVzdFN1aXRlKCgKICAgICAgICByZWdyZXNzaW9uX3N1aXRlLAogICAgKSkKCmRlZiB0ZXN0KCk6CiAgICBydW5uZXIgPSB1bml0dGVzdC5UZXh0VGVzdFJ1bm5lcigpCiAgICBydW5uZXIucnVuKHN1aXRlKCkpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgdGVzdCgpCg==