LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfZXh0ZW5zaW9ucy5oeHgiCgojaW5jbHVkZSAib2xlMnVuby5oeHgiCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8dG9vbHMvcHJlc3lzLmg+CiNpbmNsdWRlIDxvbGVjdGwuaD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDxoYXNoX21hcD4KI2luY2x1ZGUgImNvbWlmYWNlcy5oeHgiCiNpbmNsdWRlIDx0b29scy9wb3N0c3lzLmg+CgoKI2luY2x1ZGUgPHZvcy9kaWFnbm9zZS5oeHg+CiNpbmNsdWRlIDx2b3MvcmVmZXJuY2UuaHh4PgojaW5jbHVkZSA8dG9vbHMvZGVidWcuaHh4PgojaW5jbHVkZSA8cnRsL3VzdHJpbmcuaHh4PgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JlYW5zL01ldGhvZENvbmNlcHQuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JlYW5zL1Byb3BlcnR5Q29uY2VwdC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2NyaXB0L0ZhaWxSZWFzb24uaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3JlZmxlY3Rpb24vUGFyYW1JbmZvLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9iZWFucy9YRXhhY3ROYW1lLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jb250YWluZXIvTm9TdWNoRWxlbWVudEV4Y2VwdGlvbi5ocHA+CgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JlYW5zL1hNYXRlcmlhbEhvbGRlci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2NyaXB0L1hJbnZvY2F0aW9uMi5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2NyaXB0L01lbWJlclR5cGUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3JlZmxlY3Rpb24vWElkbFJlZmxlY3Rpb24uaHBwPgojaW5jbHVkZSA8b3NsL2ludGVybGNrLmg+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvdW5vL2dlbmZ1bmMuaD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvaW1wbGJhc2UxLmh4eD4KCiNpbmNsdWRlICJjb21pZmFjZXMuaHh4IgojaW5jbHVkZSAianNjcmlwdGNsYXNzZXMuaHh4IgojaW5jbHVkZSAidW5vdHlwZXdyYXBwZXIuaHh4IgojaW5jbHVkZSAib2xlb2Jqdy5oeHgiCiNpbmNsdWRlICJ1bm9vYmp3Lmh4eCIKI2luY2x1ZGUgInNlcnZwcm92Lmh4eCIKCnVzaW5nIG5hbWVzcGFjZSB2b3M7CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnVzaW5nIG5hbWVzcGFjZSBydGw7CnVzaW5nIG5hbWVzcGFjZSBvc2w7CnVzaW5nIG5hbWVzcGFjZSBjcHB1Owp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6OnVubzsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjpiZWFuczsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6c2NyaXB0Owp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6Omxhbmc7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6YnJpZGdlOjpNb2RlbERlcGVuZGVudDsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjpyZWZsZWN0aW9uOwoKCgojaWYgX01TQ19WRVIgPCAxMjAwCmV4dGVybiAiQyIgY29uc3QgR1VJRCBJSURfSURpc3BhdGNoRXg7CiNlbmRpZgoKbmFtZXNwYWNlIG9sZV9hZGFwdGVyCnsKaGFzaF9tYXA8c2FsX3VJbnQzMiwgV2Vha1JlZmVyZW5jZTxYSW50ZXJmYWNlPiA+IFVub09ialRvV3JhcHBlck1hcDsKc3RhdGljIHNhbF9Cb29sIHdyaXRlQmFja091dFBhcmFtZXRlcihWQVJJQU5UQVJHKiBwRGVzdCwgVkFSSUFOVCogcFNvdXJjZSk7CnN0YXRpYyBzYWxfQm9vbCB3cml0ZUJhY2tPdXRQYXJhbWV0ZXIyKCBWQVJJQU5UQVJHKiBwRGVzdCwgVkFSSUFOVCogcFNvdXJjZSk7CnN0YXRpYyBIUkVTVUxUIG1hcENhbm5vdENvbnZlcnRFeGNlcHRpb24oIENhbm5vdENvbnZlcnRFeGNlcHRpb24gZSwgdW5zaWduZWQgaW50ICogcHVBcmdFcnIpOwogICAgCgovKiBEb2VzIG5vdCB0aHJvdyBhbnkgZXhjZXB0aW9ucy4KICAgUGFyYW0gcEluZm8gY2FuIGJlIE5VTEwuCiAqLwpzdGF0aWMgdm9pZCB3cml0ZUV4Y2VwaW5mbyhFWENFUElORk8gKiBwSW5mbywgY29uc3QgT1VTdHJpbmcmIG1lc3NhZ2UpCnsKICAgIGlmIChwSW5mbyAhPSBOVUxMKQogICAgewogICAgICAgIHBJbmZvLT53Q29kZSA9IFVOT18yX09MRV9FWENFUFRJT05DT0RFOwogICAgICAgIHBJbmZvLT5ic3RyU291cmNlID0gU3lzQWxsb2NTdHJpbmcoTCJbYXV0b21hdGlvbiBicmlkZ2VdICIpOwogICAgICAgIHBJbmZvLT5ic3RyRGVzY3JpcHRpb24gPSBTeXNBbGxvY1N0cmluZyhyZWludGVycHJldF9jYXN0PExQQ09MRVNUUj4obWVzc2FnZS5nZXRTdHIoKSkpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCgljbGFzcyBpbXBsZW1lbnRhdGlvbjogSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsCgkKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6SW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsKCBSZWZlcmVuY2U8WE11bHRpU2VydmljZUZhY3Rvcnk+JiB4RmFjdG9yeSwKCQkJCQkJCQkJCQkJCXNhbF91SW50OCB1bm9XcmFwcGVyQ2xhc3MsIHNhbF91SW50OCBjb21XcmFwcGVyQ2xhc3MpOgoJCW1fZGVmYXVsdFZhbHVlVHlwZSggMCksCgkJVW5vQ29udmVyc2lvblV0aWxpdGllczxJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw+KCB4RmFjdG9yeSwgdW5vV3JhcHBlckNsYXNzLCBjb21XcmFwcGVyQ2xhc3MpCnsKfQoKSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjp+SW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsKCkKewogICAgTXV0ZXhHdWFyZCBndWFyZChnZXRCcmlkZ2VNdXRleCgpKTsKCS8vIHJlbW92ZSBlbnRyaWVzIGluIGdsb2JhbCBtYXAKICAgIElUX1VubyBpdD0gVW5vT2JqVG9XcmFwcGVyTWFwLmZpbmQoIChzYWxfdUludDMyKSBtX3hPcmlnaW4uZ2V0KCkpOwogICAgaWYoaXQgIT0gVW5vT2JqVG9XcmFwcGVyTWFwLmVuZCgpKQogICAgICAgIFVub09ialRvV3JhcHBlck1hcC5lcmFzZShpdCk7CiNpZiBPU0xfREVCVUdfTEVWRUwgPiAwCiAgICBmcHJpbnRmKHN0ZGVyciwiW2F1dG9tYXRpb24gYnJpZGdlXSBVbm9PYmpUb1dyYXBwZXJNYXAgIGNvbnRhaW5zOiAlaSBcbiIsCiAgICAgICAgICAgIFVub09ialRvV3JhcHBlck1hcC5zaXplKCkpOwojZW5kaWYgICAgIAogICAgCn0JCgpTVERNRVRIT0RJTVAgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpRdWVyeUludGVyZmFjZShSRUZJSUQgcmlpZCwgTFBWT0lEIEZBUiAqIHBwdikKewoJSFJFU1VMVCByZXQ9IFNfT0s7CgoJaWYoICFwcHYpCgkJcmV0dXJuIEVfUE9JTlRFUjsKCiAgICBpZihJc0VxdWFsSUlEKHJpaWQsIElJRF9JVW5rbm93bikpCgl7CgkJQWRkUmVmKCk7CgkJKnBwdiA9IChJVW5rbm93biopIChJRGlzcGF0Y2gqKSB0aGlzOwogICAgfSAKICAgIGVsc2UgaWYgKElzRXF1YWxJSUQocmlpZCwgSUlEX0lEaXNwYXRjaCkpCgl7CgkJQWRkUmVmKCk7CgkJKnBwdiA9IChJRGlzcGF0Y2gqKSB0aGlzOwoJfQoJZWxzZSBpZiggSXNFcXVhbElJRCggcmlpZCwgX191dWlkb2YoIElVbm9PYmplY3RXcmFwcGVyKSkpCgl7CgkJQWRkUmVmKCk7CgkJKnBwdj0gKElVbm9PYmplY3RXcmFwcGVyKikgdGhpczsKCX0KCWVsc2UKCQlyZXQ9IEVfTk9JTlRFUkZBQ0U7CglyZXR1cm4gcmV0Owp9CQoKU1RETUVUSE9ESU1QXyhVTE9ORykgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpBZGRSZWYoKQp7CiAgICBhY3F1aXJlKCk7CiAgICAvLyBkb2VzIG5vdCBuZWVkIHRvIGd1YXJkIGJlY2F1c2Ugb25lIHNob3VsZCBub3QgcmVseSBvbiB0aGUgcmV0dXJuIHZhbHVlIG9mCiAgICAvLyBBZGRSZWYgYW55d2F5CglyZXR1cm4gbV9yZWZDb3VudDsKfQkKClNURE1FVEhPRElNUF8oVUxPTkcpIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6UmVsZWFzZSgpCnsKICAgIFVMT05HIG49IG1fcmVmQ291bnQ7CiAgICByZWxlYXNlKCk7CiAgICByZXR1cm4gbiAtIDE7Cn0JCgovLyBJVW5vT2JqZWN0V3JhcHBlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTVERNRVRIT0RJTVAgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpnZXRXcmFwcGVyWEludGVyZmFjZSggUmVmZXJlbmNlPFhJbnRlcmZhY2U+KiBwWEludCkKewoJKnBYSW50PSBSZWZlcmVuY2U8WEludGVyZmFjZT4oIHN0YXRpY19jYXN0PFhXZWFrKj4oIHRoaXMpLCBVTk9fUVVFUlkpOwoJcmV0dXJuIHBYSW50LT5pcygpID8gU19PSyA6IEVfRkFJTDsKfQpTVERNRVRIT0RJTVAgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpnZXRPcmlnaW5hbFVub09iamVjdCggUmVmZXJlbmNlPFhJbnRlcmZhY2U+KiBwWEludCkKewoJKnBYSW50PSBtX3hPcmlnaW47CglyZXR1cm4gbV94T3JpZ2luLmlzKCkgPyBTX09LIDogRV9GQUlMOwp9ClNURE1FVEhPRElNUCAgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpnZXRPcmlnaW5hbFVub1N0cnVjdCggQW55ICogcFN0cnVjdCkKewoJSFJFU1VMVCByZXQ9IEVfRkFJTDsKCWlmKCAhbV94T3JpZ2luLmlzKCkpCgl7CgkJUmVmZXJlbmNlPFhNYXRlcmlhbEhvbGRlcj4geE1hdEhvbGRlciggbV94SW52b2NhdGlvbiwgVU5PX1FVRVJZKTsKCQlpZiggeE1hdEhvbGRlci5pcygpKQoJCXsKCQkJQW55IGFueSA9IHhNYXRIb2xkZXItPmdldE1hdGVyaWFsKCk7CgkJCWlmKCBhbnkuZ2V0VmFsdWVUeXBlQ2xhc3MoKSA9PSBUeXBlQ2xhc3NfU1RSVUNUKQoJCQl7CgkJCQkqcFN0cnVjdD0gYW55OwoJCQkJcmV0PSBTX09LOwoJCQl9CgkJfQoJfQoJcmV0dXJuIHJldDsKfQoKU1RETUVUSE9ESU1QIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6R2V0VHlwZUluZm9Db3VudCggdW5zaWduZWQgaW50ICogLypwY3RpbmZvKi8gKQp7CglyZXR1cm4gRV9OT1RJTVBMIDsKfQkKClNURE1FVEhPRElNUCBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OkdldFR5cGVJbmZvKHVuc2lnbmVkIGludCAvKml0aW5mbyovLCBMQ0lEIC8qbGNpZCovLCBJVHlwZUluZm8gKiogLypwcHRpbmZvKi8pCnsKCXJldHVybiBFX05PVElNUEw7Cn0JCgpTVERNRVRIT0RJTVAgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpHZXRJRHNPZk5hbWVzKFJFRklJRCAvKnJpaWQqLywgCgkJCQkJCQkJCQkJCQkgT0xFQ0hBUiAqKiByZ3N6TmFtZXMsIAoJCQkJCQkJCQkJCQkJIHVuc2lnbmVkIGludCBjTmFtZXMsCgkJCQkJCQkJCQkJCQkgTENJRCAvKmxjaWQqLywgCgkJCQkJCQkJCQkJCQkgRElTUElEICogcmdkaXNwaWQgKQp7CiAgICBIUkVTVUxUIHJldCA9IERJU1BfRV9VTktOT1dOTkFNRTsKICAgIHRyeQogICAgewogICAgICAgIE11dGV4R3VhcmQgZ3VhcmQoIGdldEJyaWRnZU11dGV4KCkpOwogICAgICAgIGlmKCAhIHJnZGlzcGlkKQogICAgICAgICAgICByZXR1cm4gRV9QT0lOVEVSOwoKICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgaWYoICEgX3djc2ljbXAoICpyZ3N6TmFtZXMsIEpTQ1JJUFRfVkFMVUVfRlVOQykgfHwgCiAgICAgICAgICAgICEgX3djc2ljbXAoICpyZ3N6TmFtZXMsIEJSSURHRV9WQUxVRV9GVU5DKSkKICAgICAgICB7CiAgICAgICAgICAgICpyZ2Rpc3BpZD0gRElTUElEX0pTQ1JJUFRfVkFMVUVfRlVOQzsKICAgICAgICAgICAgcmV0dXJuIFNfT0s7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoICEgX3djc2ljbXAoICpyZ3N6TmFtZXMsIEdFVF9TVFJVQ1RfRlVOQykgfHwKICAgICAgICAgICAgICAgICAhIF93Y3NpY21wKCAqcmdzek5hbWVzLCBCUklER0VfR0VUX1NUUlVDVF9GVU5DKSkKICAgICAgICB7CiAgICAgICAgICAgICpyZ2Rpc3BpZD0gRElTUElEX0dFVF9TVFJVQ1RfRlVOQzsKICAgICAgICAgICAgcmV0dXJuIFNfT0s7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoICEgX3djc2ljbXAoICpyZ3N6TmFtZXMsIEJSSURHRV9DUkVBVEVfVFlQRV9GVU5DKSkKICAgICAgICB7CiAgICAgICAgICAgICpyZ2Rpc3BpZD0gRElTUElEX0NSRUFURV9UWVBFX0ZVTkM7CiAgICAgICAgICAgIHJldHVybiBTX09LOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIGlmIChtX3hJbnZvY2F0aW9uLmlzKCkgJiYgKGNOYW1lcyA+IDApKQogICAgICAgIHsKICAgICAgICAgICAgT1VTdHJpbmcgbmFtZShyZWludGVycHJldF9jYXN0PGNvbnN0IHNhbF9Vbmljb2RlKj4ocmdzek5hbWVzWzBdKSk7CiAgICAgICAgICAgIE5hbWVUb0lkTWFwOjppdGVyYXRvciBpdGVyID0gbV9uYW1lVG9EaXNwSWRNYXAuZmluZChuYW1lKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChpdGVyID09IG1fbmFtZVRvRGlzcElkTWFwLmVuZCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBPVVN0cmluZyBleGFjdE5hbWU7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChtX3hFeGFjdE5hbWUuaXMoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBleGFjdE5hbWUgPSBtX3hFeGFjdE5hbWUtPmdldEV4YWN0TmFtZShuYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsgICAgCiAgICAgICAgICAgICAgICAgICAgZXhhY3ROYW1lID0gbmFtZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgTWVtYmVySW5mbyBkKDAsIGV4YWN0TmFtZSk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChtX3hJbnZvY2F0aW9uLT5oYXNQcm9wZXJ0eShleGFjdE5hbWUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGQuZmxhZ3MgfD0gRElTUEFUQ0hfUFJPUEVSVFlHRVQ7CQkJCiAgICAgICAgICAgICAgICAgICAgZC5mbGFncyB8PSBESVNQQVRDSF9QUk9QRVJUWVBVVDsKICAgICAgICAgICAgICAgICAgICBkLmZsYWdzIHw9IERJU1BBVENIX1BST1BFUlRZUFVUUkVGOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAobV94SW52b2NhdGlvbi0+aGFzTWV0aG9kKGV4YWN0TmFtZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZC5mbGFncyB8PSBESVNQQVRDSF9NRVRIT0Q7CQkJCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChkLmZsYWdzICE9IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbV9NZW1iZXJJbmZvcy5wdXNoX2JhY2soZCk7CiAgICAgICAgICAgICAgICAgICAgaXRlciA9IG1fbmFtZVRvRGlzcElkTWFwLmluc2VydChOYW1lVG9JZE1hcDo6dmFsdWVfdHlwZShleGFjdE5hbWUsIChESVNQSUQpbV9NZW1iZXJJbmZvcy5zaXplKCkpKS5maXJzdDsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoZXhhY3ROYW1lICE9IG5hbWUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpdGVyID0gbV9uYW1lVG9EaXNwSWRNYXAuaW5zZXJ0KE5hbWVUb0lkTWFwOjp2YWx1ZV90eXBlKG5hbWUsIChESVNQSUQpbV9NZW1iZXJJbmZvcy5zaXplKCkpKS5maXJzdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CQkKICAgICAgICAgICAgfQoJCQogICAgICAgICAgICBpZiAoaXRlciA9PSBtX25hbWVUb0Rpc3BJZE1hcC5lbmQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0ID0gRElTUF9FX1VOS05PV05OQU1FOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKnJnZGlzcGlkID0gKCppdGVyKS5zZWNvbmQ7CiAgICAgICAgICAgICAgICByZXQgPSBTX09LOwogICAgICAgICAgICB9CiAgICAgICAgfQkKICAgIH0KICAgIGNhdGNoKEJyaWRnZVJ1bnRpbWVFcnJvciYgKQogICAgewogICAgICAgIE9TTF9BU1NFUlQoMCk7CiAgICB9CiAgICBjYXRjaChFeGNlcHRpb24mICkKICAgIHsKICAgICAgICBPU0xfQVNTRVJUKDApOwogICAgfQoJY2F0Y2goLi4uKQoJewogICAgICAgIE9TTF9BU1NFUlQoMCk7Cgl9CgogICAgcmV0dXJuIHJldDsKfQkKICAgIAovLyAiY29udmVydERpc3BwYXJhbXNBcmdzIiBjb252ZXJ0cyBWQVJJQU5UUyB0byB0aGVpciByZXNwZWN0aW5nIEFueSBjb3VudGVycGFydHMKLy8gVGhlIHBhcmFtZXRlcnMgImlkIiwgIndGbGFncyIgYW5kICJwZGlzcHBhcmFtcyIgZXF1YWwgdGhvc2UgYXMgdXNlZCBpbiAKLy8gSURpc3BhdGNoOjpJbnZva2UuIFRoZSBmdW5jdGlvbiBoYW5kbGVzIHNwZWNpYWwgSmF2YVNjcmlwdCAKLy8gY2FzZXMgd2hlcmUgYSBWQVJJQU5UIG9mIHR5cGUgVlRfRElTUEFUQ0ggaXMgYW1iaWd1b3VzIGFuZCBjb3VsZCByZXByZXNlbnQgCi8vIGFuIG9iamVjdCwgYXJyYXkgKCBKYXZhU2NyaXB0IEFycmF5IG9iamVjdCksIG91dCBwYXJhbWV0ZXIgYW5kIGluL291dCAoIEphdmFTY3JpcHQgQXJyYXkgb2JqZWN0KQovLyAgcGFyYW1ldGVyIChKYXZhU2NyaXB0IEFycmF5IG9iamVjdCkKLy8gQmVjYXVzZSBhbGwgdGhvc2UgVlRfRElTUEFUQ0ggb2JqZWN0cyBuZWVkIGEgZGlmZmVyZW50IGNvbnZlcnNpb24KLy8gd2UgaGF2ZSB0byBmaW5kIG91dCB3aGF0IHRoZSBvYmplY3QgaXMgc3VwcG9zZWQgdG8gYmUuIFRoZSBmdW5jdGlvbiBkb2VzIHRoaXMKLy8gYnkgZWl0aGVyIHVzaW5nIHR5cGUgaW5mb3JtYXRpb24gb3IgYnkgaGVscCBvZiBhIHNwZWNpYWxpemVkIFZhbHVlT2JqZWN0IG9iamVjdC4KCi8vIEEuIFR5cGUgSW5mb3JtYXRpb24KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gV2l0aCB0aGUgaGVscCBvZiB0eXBlIGluZm9ybWF0aW9uIHRoZSBraW5kIG9mIHBhcmFtZXRlciBjYW4gYmUgZXhhY3RseSBkZXRlcm1pbmVkIAovLyBhbmQgYW4gYXBwcm9wcmlhdGUgY29udmVyc2lvbiBjYW4gYmUgY2hvb3Nlbi4gQSBwcm9ibGVtIGFyaXNlcyBpZiBhIG1ldGhvZCBleHBlY3RzIAovLyBhbiBBbnkuIFRoZW4gdGhlIHR5cGUgaW5mbyBkb2VzIG5vdCB0ZWxsIHdoYXQgdGhlIHR5cGUgb2YgdGhlIHZhbHVlLCB0aGF0IGlzIGtlcHQgCi8vIGJ5IHRoZSBhbnksIHNob3VsZCBiZS4gSW4gdGhpcyBzaXR1YXRpb24gdGhlIGRlY2lzaW9uIHdoZXRlciB0aGUgcGFyYW0gaXMgYSAKLy8gc2VxdWVuY2Ugb3IgYW4gb2JqZWN0IGlzIG1hZGUgdXBvbiB0aGUgZmFjdCBpZiB0aGUgb2JqZWN0IGhhcyBhIHByb3BlcnR5ICIwIgovLyAoIHNlZSBmdW5jdGlvbiAiaXNKU2NyaXB0QXJyYXkiKS4gU2luY2UgdGhpcyBpcyB1bnNhZmUgaXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlCi8vIHRoZSBKU2NyaXB0IHZhbHVlIG9iamVjdHMgd2l0aGluIGEgSlNjcmlwdCBzY3JpcHQgb24gc3VjaCBhbiBvY2Nhc2lvbi4KCi8vIEIuIEphdmFTY3JpcHQgVmFsdWUgT2JqZWN0ICggY2xhc3MgSlNjcmlwdFZhbHVlICkKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQSBKU2NyaXB0VmFsdWUgKFZhbHVlT2JqZWN0KSBvYmplY3QgaXMgYSBDT00gb2JqZWN0IGluIHRoYXQgaXQgaW1wbGVtZW50cyBJRGlzcGF0Y2ggYW5kIHRoZQovLyBJSlNjcmlwdFZhbHVlIG9iamVjdCBpbnRlcmZhY2UuIFN1Y2ggb2JqZWN0cyBhcmUgcHJvdmlkZWQgYnkgYWxsIFVOTyB3cmFwcGVyIAovLyBvYmplY3RzIHVzZWQgd2l0aGluIGEgSlNjcmlwdCBzY3JpcHQuIFRvIG9idGFpbiBhbiBpbnN0YW5jZSBvbmUgaGFzIHRvIGNhbGwKLy8gIl9HZXRWYWx1ZU9iamVjdCgpIG9yIEJyaWRnZV9HZXRWYWx1ZU9iamVjdCgpIiBvbiBhbiBVTk8gd3JhcHBlciBvYmplY3QgKGNsYXNzIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbCkuCi8vIEEgdmFsdWUgb2JqZWN0IGlzIGFwcHJvcHJpYXRlbHkgaW5pdGlhbGl6ZWQgd2l0aGluIHRoZSBzY3JpcHQgYW5kIHBhc3NlZCBhcyAKLy8gcGFyYW1ldGVyIHRvIGFuIFVOTyBvYmplY3QgbWV0aG9kIG9yIHByb3BlcnR5LiBUaGUgY29udmVydERpc3BwYXJhbXNBcmdzIGZ1bmN0aW9uCi8vIGNhbiBlYXNpbHkgZmluZCBvdXQgdGhhdCBhIHBhcmFtIGlzIHN1Y2ggYW4gb2JqZWN0IGJ5IHF1ZXJpaW5nIGZvciB0aGUgCi8vIElKU2NyaXB0VmFsdWUgaW50ZXJmYWNlLiBCeSB0aGlzIGludGVyZmFjZSBvbmUgdGhlIHR5cGUgYW5kIGtpbmQgKCBvdXQsIGluL291dCkKLy8gY2FuIGJlIGRldGVybWluZWQgYW5kIHRoZSByaWdodCBjb252ZXJzaW9uIGNhbiBiZSBhcHBsaWVkLiAKLy8gVXNpbmcgVmFsdWVPYmplY3RzIHdlIHNwYXJlIHVzIHRoZSBlZmZvcnQgb2YgYXF1aXJpbmcgYW5kIGV4YW1pbmluZyB0eXBlIGluZm9ybWF0aW9uCi8vIGluIG9yZGVyIHRvIGZpZ3VyZSBvdXQgd2hhdCB0aGUgYW4gSURpc3BhdGNoIHBhcmFtZXRlciBpcyBtZWFudCBmb3IuCgovLyBOb3JtYWwgSlNjcmlwdCBvYmplY3QgcGFyYW1ldGVyIGNhbiBiZSBtaXhlZCB3aXRoIEpTY3JpcHRWYWx1ZSBvYmplY3QuIElmIGFuIAovLyBWQVJJQU5UIGNvbnRhaW5zIGFuIFZUX0RJU1BBVENIIHRoYXQgaXMgbm8gSlNjcmlwdFZhbHVlIHRoYW4gdGhlIHR5cGUgaW5mb3JtYXRpb24KLy8gaXMgdXNlZCB0byBmaW5kIG91dCBhYm91dCB0aGUgcmVxaXJlZCB0eXBlLgp2b2lkIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6Y29udmVydERpc3BwYXJhbXNBcmdzKERJU1BJRCBpZCwKICAgIHVuc2lnbmVkIHNob3J0IC8qd0ZsYWdzKi8sIERJU1BQQVJBTVMqIHBkaXNwcGFyYW1zLCBTZXF1ZW5jZTxBbnk+JiByU2VxKQp7CglIUkVTVUxUIGhyPSBTX09LOwoJc2FsX0ludDMyIGNvdW50QXJncz0gcGRpc3BwYXJhbXMtPmNBcmdzOwoJaWYoIGNvdW50QXJncyA9PSAwKSAKCQlyZXR1cm47CgkKCXJTZXEucmVhbGxvYyggY291bnRBcmdzKTsKCUFueSoJcFBhcmFtcyA9IHJTZXEuZ2V0QXJyYXkoKTsKCglBbnkgYW55UGFyYW07CgogICAgLy9HZXQgdHlwZSBpbmZvcm1hdGlvbiBmb3IgdGhlIGN1cnJlbnQgY2FsbAogICAgSW52b2NhdGlvbkluZm8gaW5mbzsKICAgIGlmKCAhIGdldEludm9jYXRpb25JbmZvRm9yQ2FsbCggaWQsIGluZm8pKQogICAgICAgIHRocm93IEJyaWRnZVJ1bnRpbWVFcnJvcigKICAgICAgICAgICAgT1VTVFIoIlthdXRvbWF0aW9uIGJyaWRnZV1JbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OmNvbnZlcnREaXNwcGFyYW1zQXJncyBcbiIKICAgICAgICAgICAgICAgICAgIkNvdWxkIG5vdCBvYnRhaW4gdHlwZSBpbmZvcm1hdGlvbiBmb3IgY3VycmVudCBjYWxsLiIpKTsKICAgIAogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudEFyZ3M7IGkrKykKICAgIHsKICAgICAgICBpZiAoaW5mby5lTWVtYmVyVHlwZSA9PSBNZW1iZXJUeXBlX01FVEhPRCAmJgogICAgICAgICAgICBpbmZvLmFQYXJhbU1vZGVzWyBjb3VudEFyZ3MgLSBpIC0xIF0gID09IFBhcmFtTW9kZV9PVVQpCiAgICAgICAgICAgIGNvbnRpbnVlOwoKIAkJaWYoY29udmVydFZhbHVlT2JqZWN0KCAmIHBkaXNwcGFyYW1zLT5yZ3ZhcmdbaV0sIGFueVBhcmFtKSkgCiAJCXsgLy9hIHBhcmFtIGlzIGEgVmFsdWVPYmplY3QgYW5kIGNvdWxkIGJlIGNvbnZlcnRlZAogICAgICAgICAgICBwUGFyYW1zW2NvdW50QXJncyAtIChpICsgMSldID0gYW55UGFyYW07CiAJCQljb250aW51ZTsKIAkJfQoKICAgICAgICAvLyBJZiB0aGUgcGFyYW0gaXMgYW4gb3V0LCBpbi9vdXQgcGFyYW1ldGVyIGluCiAgICAgICAgLy8gSlNjcmlwdCAoQXJyYXkgb2JqZWN0LCB3aXRoIHZhbHVlIGF0IGluZGV4IDApIHRoZW4gd2UKICAgICAgICAvLyBleHRyYWN0IEFycmF5WzBdIGFuZCBwdXQgdGhlIHZhbHVlIGludG8gdmFyUGFyYW0uIEF0IHRoZSBlbmQgb2YgdGhlIGxvb3AgdmFyUGFyYW0KICAgICAgICAvLyBpcyBjb252ZXJ0ZWQgaWYgaXQgY29udGFpbnMgYSB2YWx1ZSBvdGhlcndpc2UgdGhlIFZBUklBTlQgZnJvbSAKICAgICAgICAvLyBESVNQUEFSQU1TIGlzIGNvbnZlcnRlZC4KICAgICAgICBDQ29tVmFyaWFudCB2YXJQYXJhbTsKCiAgICAgICAgLy8gQ2hlY2sgZm9yIEpTY3JpcHQgb3V0IGFuZCBpbi9vdXQgcGFyYW1zb2JqZWN0cyAoVlRfRElTUEFUQ0gpLgogICAgICAgIC8vIFRvIGZpbmQgdGhlbSBvdXQgd2UgdXNlIHR5cGVpbmZvcm1hdGlvbiBvZiB0aGUgZnVuY3Rpb24gYmVpbmcgY2FsbGVkLgogICAgICAgIGlmKCBwZGlzcHBhcmFtcy0+cmd2YXJnW2ldLnZ0ID09IFZUX0RJU1BBVENIICkJCQkKICAgICAgICB7CiAgICAgICAgICAgIGlmKCBpbmZvLmVNZW1iZXJUeXBlID09IE1lbWJlclR5cGVfTUVUSE9EICYmIGluZm8uYVBhcmFtTW9kZXNbIGNvdW50QXJncyAtIGkgLTEgXSAgPT0gUGFyYW1Nb2RlX0lOT1VUKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBJTk9VVC1wYXJhbQogICAgICAgICAgICAgICAgLy8gSW5kZXggKCBwcm9wZXJ0eSkgIjAiIGNvbnRhaW5zIHRoZSBhY3R1YWwgSU4tcGFyYW0uIFRoZSBvYmplY3QgaXMgYSBKU2NyaXB0CiAgICAgICAgICAgICAgICAvLyBBcnJheSBvYmplY3QuCiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIElOLXBhcmFtIGF0IGluZGV4ICIwIgogICAgICAgICAgICAgICAgSURpc3BhdGNoKiBwZGlzcD0gcGRpc3BwYXJhbXMtPnJndmFyZ1tpXS5wZGlzcFZhbDsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgT0xFQ0hBUiogc2luZGV4PSBMIjAiOwogICAgICAgICAgICAgICAgRElTUElEIGlkOwogICAgICAgICAgICAgICAgRElTUFBBUkFNUyBub1BhcmFtcz0gezAsMCwwLDB9OwogICAgICAgICAgICAgICAgaWYoU1VDQ0VFREVEKCBocj0gcGRpc3AtPkdldElEc09mTmFtZXMoIElJRF9OVUxMLCAmc2luZGV4LCAxLCBMT0NBTEVfVVNFUl9ERUZBVUxULCAmaWQpKSkKICAgICAgICAgICAgICAgICAgICBocj0gcGRpc3AtPkludm9rZSggaWQsIElJRF9OVUxMLCBMT0NBTEVfVVNFUl9ERUZBVUxULCBESVNQQVRDSF9QUk9QRVJUWUdFVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYgbm9QYXJhbXMsICYgdmFyUGFyYW0sIE5VTEwsIE5VTEwpOwogICAgICAgICAgICAgICAgaWYoIEZBSUxFRCggaHIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93IEJyaWRnZVJ1bnRpbWVFcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgT1VTVFIoIlthdXRvbWF0aW9uIGJyaWRnZV0gQ291bGQgbm90IGRldGVybWluZSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpZiB0aGUgb2JqZWN0IGhhcyBhIG1lbWJlciBcIjBcIi4gRXJyb3I6ICIpICsKICAgICAgICAgICAgICAgICAgICAgICAgT1VTdHJpbmc6OnZhbHVlT2YoaHIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYoIHZhclBhcmFtLnZ0ID09IFZUX0VNUFRZKSAvLyB0aGVuIGl0IHdhcyBubyBpbi9vdXQgcGFyYW1ldGVyCiAgICAgICAgICAgICAgICAgdmFyUGFyYW09IHBkaXNwcGFyYW1zLT5yZ3ZhcmdbaV07CgogICAgICAgIGlmKGluZm8uZU1lbWJlclR5cGUgPT0gTWVtYmVyVHlwZV9NRVRIT0QpCiAgICAgICAgICAgIHZhcmlhbnRUb0FueSggJiB2YXJQYXJhbSwgYW55UGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8uYVBhcmFtVHlwZXNbIGNvdW50QXJncyAtIGkgLSAxXSk7CiAgICAgICAgZWxzZSBpZihpbmZvLmVNZW1iZXJUeXBlID09IE1lbWJlclR5cGVfUFJPUEVSVFkpCiAgICAgICAgICAgIHZhcmlhbnRUb0FueSggJiB2YXJQYXJhbSwgYW55UGFyYW0sIGluZm8uYVR5cGUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgT1NMX0FTU0VSVCgwKTsKICAgICAgICAKICAgICAgICBwUGFyYW1zW2NvdW50QXJncyAtIChpICsgMSldPSBhbnlQYXJhbTsKICAgIH0vLyBlbmQgZm9yIC8gaXRlcmF0aW5nIG92ZXIgYWxsIHBhcmFtZXRlcnMKfQoKc2FsX0Jvb2wgIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6Z2V0SW52b2NhdGlvbkluZm9Gb3JDYWxsKCBESVNQSUQgaWQsIEludm9jYXRpb25JbmZvJiBpbmZvKQp7CiAgICBzYWxfQm9vbCBiVHlwZXNBdmFpbGFibGU9IHNhbF9GYWxzZTsgCgkKICAgIGlmKCAhbV94SW52b2NhdGlvbi5pcygpIClyZXR1cm4gZmFsc2U7CiAgICBSZWZlcmVuY2U8WEludm9jYXRpb24yPiBpbnYyKCBtX3hJbnZvY2F0aW9uLCBVTk9fUVVFUlkpOwogICAgaWYoIGludjIuaXMoKSkKICAgIHsKICAgICAgICAvLyBXZSBuZWVkIHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSBvciBtZXRob2QgdG8gZ2V0IGl0cyB0eXBlIGluZm9ybWF0aW9uLiAKICAgICAgICAvLyBUaGUgbmFtZSBjYW4gYmUgaWRlbnRpZmllZCB0aHJvdWdoIHRoZSBwYXJhbSAiaWQiCiAgICAgICAgLy8gdGhhdCBpcyBrZXB0IGFzIHZhbHVlIGluIHRoZSBtYXAgbV9uYW1lVG9EaXNwSWRNYXAuIAogICAgICAgIC8vIFByb3BsZW06IHRoZSBXaW5kb3dzIEpTY3JpcHQgZW5naW5lIHNvbWV0aW1lcyBjaGFuZ2VzIHNtYWxsIGxldHRlcnMgdG8gY2FwaXRhbCAKICAgICAgICAvLyBsZXR0ZXJzIGFzIGhhcHBlbnMgaW4geGlkbGNsYXNzX29iai5jcmVhdGVPYmplY3QoIHZhcikgLy8gaW4gSlNjcmlwdC4KICAgICAgICAvLyBJRGlzcGF0Y2g6OkdldElkc09mTmFtZXMgaXMgdGhlbiBjYWxsZWQgd2l0aCAiQ3JlYXRlT2JqZWN0IiAhISEKICAgICAgICAvLyBtX25hbWVUb0Rpc3BJZE1hcCBjYW4gY29udGFpbiBzZXZlcmFsIG5hbWVzIGZvciBvbmUgRElTUElEIGJ1dCBvbmx5IG9uZSBpcwogICAgICAgIC8vIHRoZSBleGFjdCBvbmUuIElmIHRoZXJlJ3Mgbm8gbV94RXhhY3ROYW1lIGFuZCB0aGVyZWZvcmUgbm8gZXhhY3QgbmFtZSB0aGVuIAogICAgICAgIC8vIHRoZXJlJ3Mgb25seSBvbmUgZW50cnkgaW4gdGhlIG1hcC4KICAgICAgICB0eXBlZGVmIE5hbWVUb0lkTWFwOjpjb25zdF9pdGVyYXRvciBjaXQ7CiAgICAgICAgT1VTdHJpbmcgc01lbWJlck5hbWU7CgogICAgICAgIGZvcihjaXQgY2kxPSBtX25hbWVUb0Rpc3BJZE1hcC5iZWdpbigpOyBjaTEgIT0gbV9uYW1lVG9EaXNwSWRNYXAuZW5kKCk7IGNpMSsrKQogICAgICAgIHsKICAgICAgICAgICAgaWYoICgqY2kxKS5zZWNvbmQgPT0gaWQpIC8vIGl0ZXJhdG9yIGlzIGEgcGFpcjwgT1VTdHJpbmcsIERJU1BJRD4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc01lbWJlck5hbWU9ICgqY2kxKS5maXJzdDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgLy8gR2V0IGluZm9ybWF0aW9uIGZvciB0aGUgY3VycmVudCBjYWxsICggcHJvcGVydHkgb3IgbWV0aG9kKS4KICAgICAgICAvLyBUaGVyZSBjb3VsZCBiZSBzaW1pbGFyIG5hbWVzIHdoaWNoIG9ubHkgZGlmZmVyIGluIHRoZSBjYXNlcwogICAgICAgIC8vIG9mIGxldHRlcnMuIEZpcnN0IHdlIGFzc3VtZSB0aGF0IHRoZSBuYW1lIHdoaWNoIHdhcyBwYXNzZWQgaW50bwogICAgICAgIC8vIEdldElEc09mTmFtZXMgaXMgY29ycmVjdC4gSWYgd2Ugd29uJ3QgZ2V0IGluZm9ybWF0aW9uIHdpdGggdGhhdAogICAgICAgIC8vIG5hbWUgdGhlbiB3ZSBoYXZlIHRoZSBpbnZvY2F0aW9uIHNlcnZpY2UgdXNlIHRoZSBYRXhhY3ROYW1lIGludGVyZmFjZS4KICAgICAgICBzYWxfQm9vbCB2YWxpZEluZm89IHNhbF9UcnVlOwogICAgICAgIEludm9jYXRpb25JbmZvIGludkluZm87CiAgICAgICAgdHJ5ewogICAgICAgICAgICBpbnZJbmZvPSBpbnYyLT5nZXRJbmZvRm9yTmFtZSggc01lbWJlck5hbWUsIHNhbF9GYWxzZSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoKCBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gKQogICAgICAgIHsKICAgICAgICAgICAgdmFsaWRJbmZvPSBzYWxfRmFsc2U7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmKCAhIHZhbGlkSW5mbykKICAgICAgICB7CiAgICAgICAgICAgIGludkluZm89IGludjItPmdldEluZm9Gb3JOYW1lKCBzTWVtYmVyTmFtZSwgc2FsX1RydWUpOwogICAgICAgIH0KICAgICAgICBpZiggaW52SW5mby5hTmFtZS5wRGF0YSkKICAgICAgICB7CiAgICAgICAgICAgIGJUeXBlc0F2YWlsYWJsZT0gc2FsX1RydWU7CiAgICAgICAgICAgIGluZm89IGludkluZm87CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGJUeXBlc0F2YWlsYWJsZTsKfQovLyBYQnJpZGdlU3VwcGxpZXIyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBvbmx5IGJyaWRnZXMgaXRzZWxmICggdGhpcyBpbnN0YW5jZSBvZiBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGwpZnJvbSBVTk8gdG8gSURpc3BhdGNoCi8vIElmIHNvdXJjZU1vZGVsVHlwZSBpcyBVTk8gdGhhbiBhbnkgVU5PIGludGVyZmFjZSBpbXBsZW1lbnRlZCBieSBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGwKLy8gY2FuIGJyaWRnZWQgdG8gSURpc3BhdGNoICggaWYgZGVzdE1vZGVsVHlwZSA9PSBPTEUpLiBUaGUgSURpc3BhdGNoIGlzCi8vIGltcGxlbWVudGVkIGJ5IHRoaXMgY2xhc3MuCkFueSBTQUxfQ0FMTCBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OmNyZWF0ZUJyaWRnZShjb25zdCBBbnkmIG1vZGVsRGVwT2JqZWN0LCAKCQkJCQkJCQljb25zdCBTZXF1ZW5jZTxzYWxfSW50OD4mIC8qUHJvY2Vzc0lkKi8sIAoJCQkJCQkJCXNhbF9JbnQxNiBzb3VyY2VNb2RlbFR5cGUsIAoJCQkJCQkJCXNhbF9JbnQxNiBkZXN0TW9kZWxUeXBlKSAKCQkJdGhyb3cgKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKewoKCUFueSByZXRBbnk7CglpZiggc291cmNlTW9kZWxUeXBlID09IFVOTyAmJiBkZXN0TW9kZWxUeXBlID09IE9MRSAmJiAKCQltb2RlbERlcE9iamVjdC5nZXRWYWx1ZVR5cGVDbGFzcygpID09IFR5cGVDbGFzc19JTlRFUkZBQ0UgKQoJewoJCVJlZmVyZW5jZTxYSW50ZXJmYWNlPiB4SW50OwoJCWlmKCBtb2RlbERlcE9iamVjdCA+Pj0geEludCApCgkJewkKCQkJaWYoIHhJbnQgPT0gUmVmZXJlbmNlPFhJbnRlcmZhY2U+KCBzdGF0aWNfY2FzdDxYV2Vhayo+KCB0aGlzKSwgVU5PX1FVRVJZKSkKCQkJewoJCQkJVkFSSUFOVCAqcFZhcj0gKFZBUklBTlQqKUNvVGFza01lbUFsbG9jKCBzaXplb2YoIFZBUklBTlQpKTsKCQkJCWlmKCBwVmFyKQoJCQkJewoJCQkJCXBWYXItPnZ0PSBWVF9ESVNQQVRDSDsKCQkJCQlwVmFyLT5wZGlzcFZhbD0gc3RhdGljX2Nhc3Q8SURpc3BhdGNoKj4oIHRoaXMpOwoJCQkJCUFkZFJlZigpOwoKCQkJCQlyZXRBbnk8PD0gcmVpbnRlcnByZXRfY2FzdDwgc2FsX3VJbnQzMiA+KCBwVmFyKTsKCQkJCX0KCQkJfQoJCX0KCX0KCglyZXR1cm4gcmV0QW55Owp9CgoKLy8gWEluaXRpYWxpemF0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjppbml0aWFsaXplKCBjb25zdCBTZXF1ZW5jZTwgQW55ID4mIGFBcmd1bWVudHMgKSAKCQl0aHJvdyhFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCnsKCXN3aXRjaCggYUFyZ3VtZW50cy5nZXRMZW5ndGgoKSApCgl7CgljYXNlIDI6IC8vIHRoZSBvYmplY3Qgd3JhcHMgYW4gVU5PIHN0cnVjdAoJCWFBcmd1bWVudHNbMF0gPj49IG1feEludm9jYXRpb247CgkJYUFyZ3VtZW50c1sxXSA+Pj0gbV9kZWZhdWx0VmFsdWVUeXBlOwoJCWJyZWFrOwoJY2FzZSAzOiAvLyB0aGUgb2JqZWN0IHdyYXBzIGFuIFVOTyBpbnRlcmZhY2UKCQlhQXJndW1lbnRzWzBdID4+PSBtX3hJbnZvY2F0aW9uOwoJCWFBcmd1bWVudHNbMV0gPj49IG1feE9yaWdpbjsKCQlhQXJndW1lbnRzWzJdID4+PSBtX2RlZmF1bHRWYWx1ZVR5cGU7CgkJYnJlYWs7Cgl9CgoJbV94RXhhY3ROYW1lPSBSZWZlcmVuY2U8WEV4YWN0TmFtZT4oIG1feEludm9jYXRpb24sIFVOT19RVUVSWSk7Cn0KClJlZmVyZW5jZTwgWEludGVyZmFjZSA+IEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6Y3JlYXRlVW5vV3JhcHBlckluc3RhbmNlKCkKewoJUmVmZXJlbmNlPFhXZWFrPiB4V2Vhaz0gc3RhdGljX2Nhc3Q8WFdlYWsqPiggbmV3IEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbCgKCQkJCQkJCW1fc21nciwgbV9uVW5vV3JhcHBlckNsYXNzLCBtX25Db21XcmFwcGVyQ2xhc3MpKTsKCXJldHVybiBSZWZlcmVuY2U8WEludGVyZmFjZT4oIHhXZWFrLCBVTk9fUVVFUlkpOwp9CgpSZWZlcmVuY2U8WEludGVyZmFjZT4gSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpjcmVhdGVDb21XcmFwcGVySW5zdGFuY2UoKQp7CglSZWZlcmVuY2U8WFdlYWs+IHhXZWFrPSBzdGF0aWNfY2FzdDxYV2Vhayo+KCBuZXcgSVVua25vd25XcmFwcGVyX0ltcGwoIAoJCQkJCQkJbV9zbWdyLCBtX25Vbm9XcmFwcGVyQ2xhc3MsIG1fbkNvbVdyYXBwZXJDbGFzcykpOwoJcmV0dXJuIFJlZmVyZW5jZTxYSW50ZXJmYWNlPiggeFdlYWssIFVOT19RVUVSWSk7Cn0KCgoKLy8gImdldFR5cGUiIGlzIHVzZWQgaW4gY29udmVydFZhbHVlT2JqZWN0IHRvIG1hcCB0aGUgc3RyaW5nIGRlbm90aW5nIHRoZSB0eXBlCi8vIHRvIGFuIGFjdHVhbCBUeXBlIG9iamVjdC4KYm9vbCBnZXRUeXBlKCBjb25zdCBCU1RSIG5hbWUsIFR5cGUgJiB0eXBlKQp7CglUeXBlIHJldFR5cGU7Cglib29sIHJldCA9IGZhbHNlOwoJdHlwZWxpYl9UeXBlRGVzY3JpcHRpb24JKiBwRGVzYz0gTlVMTDsKCU9VU3RyaW5nIHN0ciggcmVpbnRlcnByZXRfY2FzdDxjb25zdCBzYWxfVW5pY29kZSo+KG5hbWUpKTsKCXR5cGVsaWJfdHlwZWRlc2NyaXB0aW9uX2dldEJ5TmFtZSggJnBEZXNjLCBzdHIucERhdGEgKTsKCWlmKCBwRGVzYykKCXsKCQl0eXBlID0gVHlwZSggcERlc2MtPnBXZWFrUmVmICk7CgkJdHlwZWxpYl90eXBlZGVzY3JpcHRpb25fcmVsZWFzZSggcERlc2MpOwoJCXJldCA9IHRydWU7Cgl9CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgc2FsX0Jvb2wgd3JpdGVCYWNrT3V0UGFyYW1ldGVyMiggVkFSSUFOVEFSRyogcERlc3QsIFZBUklBTlQqIHBTb3VyY2UpCnsKCXNhbF9Cb29sIHJldCA9IHNhbF9GYWxzZTsJCglIUkVTVUxUIGhyOwoKCS8vIEhhbmRsZSBKU2NyaXB0VmFsdWUgb2JqZWN0cyBhbmQgSlNjcmlwdCBvdXQgcGFyYW1zICggQXJyYXkgb2JqZWN0ICkKCUNDb21WYXJpYW50IHZhckRlc3QoICpwRGVzdCk7CgkKCWlmKCBTVUNDRUVERUQoIHZhckRlc3QuQ2hhbmdlVHlwZShWVF9ESVNQQVRDSCkpKQoJewoJCUNDb21QdHI8SURpc3BhdGNoPiBzcERpc3BEZXN0KHZhckRlc3QucGRpc3BWYWwpOwoKCQkvLyBzcGVjaWFsIEhhbmRsaW5nIGZvciBhIEpTY3JpcHRWYWx1ZSBvYmplY3QKI2lmZGVmIF9fTUlOR1czMl9fCgkJQ0NvbVFJUHRyPElKU2NyaXB0VmFsdWVPYmplY3QsICZfX3V1aWRvZihJSlNjcmlwdFZhbHVlT2JqZWN0KT4gc3BWYWx1ZURlc3Qoc3BEaXNwRGVzdCk7CiNlbHNlCgkJQ0NvbVFJUHRyPElKU2NyaXB0VmFsdWVPYmplY3Q+IHNwVmFsdWVEZXN0KHNwRGlzcERlc3QpOwojZW5kaWYKCQlpZiAoc3BWYWx1ZURlc3QpCgkJewoJCQlWQVJJQU5UX0JPT0wgdmFyQm9vbD0gVkFSSUFOVF9GQUxTRTsKCQkJaWYoIFNVQ0NFRURFRCggaHI9IHNwVmFsdWVEZXN0LT5Jc091dFBhcmFtKCAmdmFyQm9vbCkgKSAKCQkJCSYmIHZhckJvb2wgPT0gVkFSSUFOVF9UUlVFICB8fCAKCQkJCVNVQ0NFRURFRChocj0gc3BWYWx1ZURlc3QtPklzSW5PdXRQYXJhbSggJnZhckJvb2wpICkgCgkJCQkmJiB2YXJCb29sID09IFZBUklBTlRfVFJVRSApCgkJCXsKCQkJCWlmKCBTVUNDRUVERUQoIHNwVmFsdWVEZXN0LT5TZXQoIENDb21WYXJpYW50KCksICpwU291cmNlKSkpCgkJCQkJcmV0PSBzYWxfVHJ1ZTsKCQkJfQoJCX0KCQllbHNlIGlmIChwRGVzdC0+dnQgPT0gVlRfRElTUEFUQ0gpLy8gVlRfRElTUEFUQ0ggLT4gSlNjcmlwdCBvdXQgcGFyYW0KCQl7CgkJCS8vIFdlIHVzZSBJRGlzcGF0Y2hFeCBiZWNhdXNlIGl0cyBHZXREaXNwSUQgZnVuY3Rpb24gY2F1c2VzIHRoZSBjcmVhdGlvbgoJCQkvLyBvZiBhIHByb3BlcnR5IGlmIGl0IGRvZXMgbm90IGV4aXN0IGFscmVhZHkuIFRoaXMgaXMgY29udmVuaWVudCBmb3IKCQkJLy8gb3V0IHBhcmFtZXRlcnMgaW4gSlNjcmlwdC4gVGhlbiB0aGUgdXNlciBtdXN0IG5vdCBzcGVjaWZ5IHByb3BlcnkgIjAiCgkJCS8vIGV4cGxpY2l0bHkKI2lmZGVmIF9fTUlOR1czMl9fCgkJCUNDb21RSVB0cjxJRGlzcGF0Y2hFeCwgJl9fdXVpZG9mKElEaXNwYXRjaEV4KT4gc3BEaXNwRXgoIHNwRGlzcERlc3QpOwojZWxzZQoJCQlDQ29tUUlQdHI8SURpc3BhdGNoRXg+IHNwRGlzcEV4KCBzcERpc3BEZXN0KTsKI2VuZGlmCgkJCWlmKCBzcERpc3BFeCkKCQkJewoJCQkJQ0NvbUJTVFIgbnVsbFByb3AoTCIwIik7CgkJCQlESVNQSUQgZHdEaXNwSUQ7CgkJCQlpZiggU1VDQ0VFREVEKCBzcERpc3BFeC0+R2V0RGlzcElEKCBudWxsUHJvcCwgZmRleE5hbWVFbnN1cmUsICZkd0Rpc3BJRCkpKQoJCQkJewoJCQkJCURJU1BQQVJBTVMgZGlzcHBhcmFtcyA9IHtOVUxMLCBOVUxMLCAxLCAxfTsKCQkJCQlkaXNwcGFyYW1zLnJndmFyZyA9IHBTb3VyY2U7CgkJCQkJRElTUElEIGRpc3BpZFB1dCA9IERJU1BJRF9QUk9QRVJUWVBVVDsKCQkJCQlkaXNwcGFyYW1zLnJnZGlzcGlkTmFtZWRBcmdzID0gJmRpc3BpZFB1dDsKCgkJCQkJaWYgKHBTb3VyY2UtPnZ0ID09IFZUX1VOS05PV04gfHwgcFNvdXJjZS0+dnQgPT0gVlRfRElTUEFUQ0ggfHwgCgkJCQkJCShwU291cmNlLT52dCAmIFZUX0FSUkFZKSB8fCAocFNvdXJjZS0+dnQgJiBWVF9CWVJFRikpCgkJCQkJCWhyID0gc3BEaXNwRXgtPkludm9rZUV4KGR3RGlzcElELCBMT0NBTEVfVVNFUl9ERUZBVUxULCBESVNQQVRDSF9QUk9QRVJUWVBVVFJFRiwKCQkJCQkJCQkJCQkJJmRpc3BwYXJhbXMsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCQkJCWVsc2UKCQkJCQkJaHI9IHNwRGlzcEV4LT5JbnZva2VFeChkd0Rpc3BJRCwgTE9DQUxFX1VTRVJfREVGQVVMVCwgRElTUEFUQ0hfUFJPUEVSVFlQVVQsCgkJCQkJCQkJCQkJICAgJmRpc3BwYXJhbXMsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCQkJCWlmKCBTVUNDRUVERUQoaHIpKQoJCQkJCQlyZXQ9IHNhbF9UcnVlOwoJCQkJfQoJCQl9CgkJfQoJCWVsc2UKCQkJcmV0PSB3cml0ZUJhY2tPdXRQYXJhbWV0ZXIoIHBEZXN0LCBwU291cmNlKTsKCX0KCWVsc2UgLy8gVGhlIHBhcmFtIGNhbid0IGJlIGEgSlNjcmlwdCBvdXQtcGFyYW1ldGVyICggYW4gQXJyYXkgb2JqZWN0KSwgaXQgY291bGQgYmUgYSBWQlNjcmlwdAoJewkvLyBwYXJhbS4gVGhlIGZ1bmN0aW9uIGNoZWNrcyBpdHNlbGYgZm9yIGNvcnJlY3QgVkJTY3JpcHQgcGFyYW1zCgkJcmV0PSB3cml0ZUJhY2tPdXRQYXJhbWV0ZXIoIHBEZXN0LCBwU291cmNlKTsKCX0KCXJldHVybiByZXQ7Cn0KLy8gVmlzdWFsQmFzaWMgU2NyaXB0IHBhc3NlcyBhcmd1bWVudHMgYXMgVlRfVkFSSUFOVCB8IFZUX0JZUkVGIGJlIGl0IGluIG9yIG91dCBwYXJhbWV0ZXIuCi8vIFRodXMgd2UgYXJlIGluIGNoYXJnZSBvZiBmcmVlaW5nIGFuIGV2ZW50dWFsIHZhbHVlIGNvbnRhaW5lZCBieSB0aGUgaW5uZXIgVkFSSUFOVAovLyBQbGVhc2Ugbm90ZTogVmFyaWFudENvcHkgZG9lc24ndCBmcmVlIGEgVlRfQllSRUYgdmFsdWUKLy8gVGhlIG91dCBwYXJhbWV0ZXJzIGFyZSBleHBlY3RlZCB0byBoYXZlIGFsd2F5cyBhIHZhbGlkIHR5cGUKc3RhdGljIHNhbF9Cb29sIHdyaXRlQmFja091dFBhcmFtZXRlcihWQVJJQU5UQVJHKiBwRGVzdCwgVkFSSUFOVCogcFNvdXJjZSkKewoJSFJFU1VMVCBocjsKCXNhbF9Cb29sIHJldCA9IEZBTFNFOwkKCS8vIE91dCBwYXJhbWV0ZXIgbXVzdCBiZSBWVF9CWVJFRgoJaWYgKChWX1ZUKHBEZXN0KSAmIFZUX0JZUkVGKSAhPSAwICkKCXsKCQlWQVJUWVBFIG9sZVR5cGVGbGFncyA9IFZfVlQocFNvdXJjZSk7CgoJCS8vIGlmIGNhbGxlciBhY2NlcHQgVkFSSUFOVCBhcyBvdXQgcGFyYW1ldGVyLCBhbnkgdmFsdWUgbXVzdCBiZSBjb252ZXJ0ZWQgCgkJaWYgKFZfVlQocERlc3QpID09IChWVF9WQVJJQU5UIHwgVlRfQllSRUYpKQoJCXsKCQkJLy8gV2hlbiB0aGUgdXNlciBwcm92aWRlcyBhIFZBUklBTlQgcmF0aGVyIHRoZW4gYSBjb25jcmV0ZSB0eXBlCgkJCS8vIHdlIGp1c3QgY29weSB0aGUgc291cmNlIHRvIHRoZSBvdXQsIGluL291dCBwYXJhbWV0ZXIKCQkJLy8gVlRfRElTUEFUQ0gsIFZUX1VOS05PV04sIFZUX0FSUkFZLCBWVF9CU1RSIGluIHRoZSBWQVJJQU5UIHRoYXQKCQkJLy8gaXMgY29udGFpbmVkIGluIHBEZXN0IGFyZSByZWxlYXNlZCBieSBWYXJpYW50Q29weQoJCQlWYXJpYW50Q29weShWX1ZBUklBTlRSRUYocERlc3QpLCBwU291cmNlKTsKCQkJcmV0CT0gc2FsX1RydWU7CgkJfQoJCWVsc2UgCgkJewoJCQkvLyB2YXJpYW50YXJnIGFuZCB2YXJpYW50IG11c3QgaGF2ZSBzYW1lIHR5cGUJCiAgCQkJaWYgKChWX1ZUKHBEZXN0KSAmIG9sZVR5cGVGbGFncykgPT0gb2xlVHlwZUZsYWdzKQoJCQl7CgkJCQlpZiAoKG9sZVR5cGVGbGFncyAmIFZUX0FSUkFZKSAhPSAwKQoJCQkJewoJCQkJCS8vIEluIC8gT3V0IFBhcmFtCgkJCQkJaWYoICpWX0FSUkFZUkVGKHBEZXN0KSAhPSBOVUxMKQoJCQkJCQlocj0gU2FmZUFycmF5Q29weURhdGEoIFZfQVJSQVkocFNvdXJjZSksICpWX0FSUkFZUkVGKHBEZXN0KSk7CgkJCQkJZWxzZQoJCQkJCQkvLyBPdXQgUGFyYW0KCQkJCQkJaHI9IFNhZmVBcnJheUNvcHkoVl9BUlJBWShwU291cmNlKSwgVl9BUlJBWVJFRihwRGVzdCkpID09IE5PRVJST1I7CgkJCQkJaWYoIFNVQ0NFRURFRCggaHIpKQoJCQkJCQlyZXQJPSBzYWxfVHJ1ZTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQkvLyBjb3B5IGJhc2UgdHlwZQoJCQkJCXN3aXRjaCAoVl9WVChwU291cmNlKSkKCQkJCQl7CgkJCQkJY2FzZSBWVF9JMjoKCQkJCQl7CgkJCQkJCSpWX0kyUkVGKHBEZXN0KSA9IFZfSTIocFNvdXJjZSk7CgkJCQkJCXJldAk9IHNhbF9UcnVlOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQkJY2FzZSBWVF9JNDoKCQkJCQkJKlZfSTRSRUYocERlc3QpID0gVl9JNChwU291cmNlKTsKCQkJCQkJcmV0CT0gc2FsX1RydWU7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgVlRfUjQ6CgkJCQkJCSpWX1I0UkVGKHBEZXN0KSA9IFZfUjQocFNvdXJjZSk7CgkJCQkJCXJldAk9IHNhbF9UcnVlOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFZUX1I4OgoJCQkJCQkqVl9SOFJFRihwRGVzdCkgPSBWX1I4KHBTb3VyY2UpOwoJCQkJCQlyZXQJPSBzYWxfVHJ1ZTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSBWVF9DWToKCQkJCQkJKlZfQ1lSRUYocERlc3QpID0gVl9DWShwU291cmNlKTsKCQkJCQkJcmV0CT0gc2FsX1RydWU7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgVlRfREFURToKCQkJCQkJKlZfREFURVJFRihwRGVzdCkgPSBWX0RBVEUocFNvdXJjZSk7CgkJCQkJCXJldAk9IHNhbF9UcnVlOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFZUX0JTVFI6CgkJCQkJCVN5c0ZyZWVTdHJpbmcoICpwRGVzdC0+cGJzdHJWYWwpOwoJCQkJCQoJCQkJCQkqVl9CU1RSUkVGKHBEZXN0KSA9IFN5c0FsbG9jU3RyaW5nKFZfQlNUUihwU291cmNlKSk7CgkJCQkJCXJldAk9IHNhbF9UcnVlOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFZUX0RJU1BBVENIOgoJCQkJCQlpZiAoKlZfRElTUEFUQ0hSRUYocERlc3QpICE9IE5VTEwpIAoJCQkJCQkJKCpWX0RJU1BBVENIUkVGKHBEZXN0KSktPlJlbGVhc2UoKTsKCQkJCQkKCQkJCQkJKlZfRElTUEFUQ0hSRUYocERlc3QpID0gVl9ESVNQQVRDSChwU291cmNlKTsKCQkJCQkKCQkJCQkJaWYgKCpWX0RJU1BBVENIUkVGKHBEZXN0KSAhPSBOVUxMKSAKCQkJCQkJCSgqVl9ESVNQQVRDSFJFRihwRGVzdCkpLT5BZGRSZWYoKTsKCQkJCQkKCQkJCQkJcmV0CT0gc2FsX1RydWU7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgVlRfRVJST1I6CgkJCQkJCSpWX0VSUk9SUkVGKHBEZXN0KSA9IFZfRVJST1IocFNvdXJjZSk7CgkJCQkJCXJldAk9IHNhbF9UcnVlOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFZUX0JPT0w6CgkJCQkJCSpWX0JPT0xSRUYocERlc3QpID0gVl9CT09MKHBTb3VyY2UpOwoJCQkJCQlyZXQJPSBzYWxfVHJ1ZTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSBWVF9VTktOT1dOOgoJCQkJCQlpZiAoKlZfVU5LTk9XTlJFRihwRGVzdCkgIT0gTlVMTCkgCgkJCQkJCQkoKlZfVU5LTk9XTlJFRihwRGVzdCkpLT5SZWxlYXNlKCk7CgkJCQkJCgkJCQkJCSpWX1VOS05PV05SRUYocERlc3QpID0gVl9VTktOT1dOKHBTb3VyY2UpOwoJCQkJCQoJCQkJCQlpZiAoKlZfVU5LTk9XTlJFRihwRGVzdCkgIT0gTlVMTCkgCgkJCQkJCQkoKlZfVU5LTk9XTlJFRihwRGVzdCkpLT5BZGRSZWYoKTsKCQkJCQkKCQkJCQkJcmV0CT0gc2FsX1RydWU7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgVlRfSTE6CgkJCQkJCSpWX0kxUkVGKHBEZXN0KSA9IFZfSTEocFNvdXJjZSk7CgkJCQkJCXJldAk9IHNhbF9UcnVlOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFZUX1VJMToKCQkJCQkJKlZfVUkxUkVGKHBEZXN0KSA9IFZfVUkxKHBTb3VyY2UpOwoJCQkJCQlyZXQJPSBzYWxfVHJ1ZTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSBWVF9VSTI6CgkJCQkJCSpWX1VJMlJFRihwRGVzdCkgPSBWX1VJMihwU291cmNlKTsKCQkJCQkJcmV0CT0gc2FsX1RydWU7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgVlRfVUk0OgoJCQkJCQkqVl9VSTRSRUYocERlc3QpID0gVl9VSTQocFNvdXJjZSk7CgkJCQkJCXJldAk9IHNhbF9UcnVlOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFZUX0lOVDoKCQkJCQkJKlZfSU5UUkVGKHBEZXN0KSA9IFZfSU5UKHBTb3VyY2UpOwoJCQkJCQlyZXQJPSBzYWxfVHJ1ZTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSBWVF9VSU5UOgoJCQkJCQkqVl9VSU5UUkVGKHBEZXN0KSA9IFZfVUlOVChwU291cmNlKTsKCQkJCQkJcmV0CT0gc2FsX1RydWU7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgVlRfREVDSU1BTDoKICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KHBEZXN0LT5wZGVjVmFsLCBwU291cmNlLCBzaXplb2YoREVDSU1BTCkpOwogICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UKCQkJewoJCQkJLy8gSGFuZGxpbmcgb2Ygc3BlY2lhbCBjYXNlcwoJCQkJLy8gRGVzdGluYXRpb24gYW5kIHNvdXJjZSB0eXBlcyBhcmUgZGlmZmVyZW50CgkJCQlpZiggcERlc3QtPnZ0ID09IChWVF9CU1RSIHwgVlRfQllSRUYpCgkJCQkJJiYgcFNvdXJjZS0+dnQgPT0gVlRfSTIpCgkJCQl7CgkJCQkJLy8gV2hlbiB0aGUgdXNlciBwcm92aWRlcyBhIFN0cmluZyBhcyBvdXQgb3VyIGluL291dCBwYXJhbWV0ZXIKCQkJCQkvLyBhbmQgdGhlIHR5cGUgaXMgY2hhciAoVHlwZUNsYXNzX0NIQVIpIHRoZW4gd2UgY29udmVydCB0byBhIEJTVFIKCQkJCQkvLyBpbnN0ZWFkIG9mIFZUX0kyIGFzIGlzIGRvbmUgb3RoZXJ3aXNlCgkJCQkJT0xFQ0hBUiBidWZmW109IHswLDB9OwoJCQkJCWJ1ZmZbMF09IHBTb3VyY2UtPmlWYWw7CgoJCQkJCVN5c0ZyZWVTdHJpbmcoICpwRGVzdC0+cGJzdHJWYWwpOwoJCQkJCSpwRGVzdC0+cGJzdHJWYWw9IFN5c0FsbG9jU3RyaW5nKCBidWZmKTsKCQkJCQlyZXQgPSBzYWxfVHJ1ZTsKCQkJCX0KCQkJfQoJCX0KCX0KCXJldHVybiByZXQ7Cn0JCQoKU1RETUVUSE9ESU1QIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6SW52b2tlKERJU1BJRCBkaXNwaWRNZW1iZXIsIAoJCQkJCQkJCQkJCSAgUkVGSUlEIC8qcmlpZCovLCAKCQkJCQkJCQkJCQkgIExDSUQgLypsY2lkKi8sIAoJCQkJCQkJCQkJCSAgdW5zaWduZWQgc2hvcnQgd0ZsYWdzLAogICAgICAgICAgICAgICAgICAgICAJCQkJCQkgIERJU1BQQVJBTVMgKiBwZGlzcHBhcmFtcywgCgkJCQkJCQkJCQkJICBWQVJJQU5UICogcHZhclJlc3VsdCwgCgkJCQkJCQkJCQkJICBFWENFUElORk8gKiBwZXhjZXBpbmZvLAogICAgICAgICAgICAgICAgICAgICAJCQkJCQkgIHVuc2lnbmVkIGludCAqIHB1QXJnRXJyICkKewoJSFJFU1VMVCByZXQgPSBTX09LOwoKICAgIHRyeQogICAgewogICAgICAgIHNhbF9Cb29sIGJIYW5kbGVkPSBzYWxfRmFsc2U7CiAgICAgICAgcmV0PSBJbnZva2VHZW5lcmFsKCBkaXNwaWRNZW1iZXIsICB3RmxhZ3MsIHBkaXNwcGFyYW1zLCBwdmFyUmVzdWx0LCAgcGV4Y2VwaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1QXJnRXJyLCBiSGFuZGxlZCk7CiAgICAgICAgaWYoIGJIYW5kbGVkKQogICAgICAgICAgICByZXR1cm4gcmV0OwoKICAgICAgICBpZiAoKGRpc3BpZE1lbWJlciA+IDApICYmICgoc2l6ZV90KWRpc3BpZE1lbWJlciA8PSBtX01lbWJlckluZm9zLnNpemUoKSkgJiYgbV94SW52b2NhdGlvbi5pcygpKQogICAgICAgIHsKICAgICAgICAgICAgTWVtYmVySW5mbyBkID0gbV9NZW1iZXJJbmZvc1tkaXNwaWRNZW1iZXIgLSAxXTsKICAgICAgICAgICAgRFdPUkQgZmxhZ3MgPSB3RmxhZ3MgJiBkLmZsYWdzOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGZsYWdzICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBESVNQQVRDSF9NRVRIT0QpICE9IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBkaXNwcGFyYW1zLT5jTmFtZWRBcmdzCT4gMCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gRElTUF9FX05PTkFNRURBUkdTOwkJCQkJCiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgU2VxdWVuY2U8QW55PiBwYXJhbXM7CgkJCQkJCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnREaXNwcGFyYW1zQXJncyhkaXNwaWRNZW1iZXIsIHdGbGFncywgcGRpc3BwYXJhbXMgLCBwYXJhbXMgKTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIHJldD0gZG9JbnZva2UocGRpc3BwYXJhbXMsIHB2YXJSZXN1bHQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBleGNlcGluZm8sIHB1QXJnRXJyLCBkLm5hbWUsIHBhcmFtcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoKGZsYWdzICYgRElTUEFUQ0hfUFJPUEVSVFlHRVQpICE9IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0PSAgZG9HZXRQcm9wZXJ0eSggcGRpc3BwYXJhbXMsIHB2YXJSZXN1bHQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBleGNlcGluZm8sIGQubmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICgoZmxhZ3MgJiBESVNQQVRDSF9QUk9QRVJUWVBVVCB8fCBmbGFncyAmIERJU1BBVENIX1BST1BFUlRZUFVUUkVGKSAhPSAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwZGlzcHBhcmFtcy0+Y0FyZ3MgIT0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gRElTUF9FX0JBRFBBUkFNQ09VTlQ7CiAgICAgICAgICAgICAgICAgICAgZWxzZQkJCQkJCQkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNlcXVlbmNlPEFueT4gcGFyYW1zOwogICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0RGlzcHBhcmFtc0FyZ3MoZGlzcGlkTWVtYmVyLCB3RmxhZ3MsIHBkaXNwcGFyYW1zLCBwYXJhbXMgKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYocGFyYW1zLmdldExlbmd0aCgpID4gMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldD0gZG9TZXRQcm9wZXJ0eSggcGRpc3BwYXJhbXMsIHB2YXJSZXN1bHQsIHBleGNlcGluZm8sIHB1QXJnRXJyLCBkLm5hbWUsIHBhcmFtcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IERJU1BfRV9CQURWQVJUWVBFOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXQ9IERJU1BfRV9NRU1CRVJOT1RGT1VORDsKICAgICAgICB9CQogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0ID0gRElTUF9FX01FTUJFUk5PVEZPVU5EOwogICAgfQogICAgY2F0Y2goQnJpZGdlUnVudGltZUVycm9yJiBlKQogICAgewogICAgICAgIHdyaXRlRXhjZXBpbmZvKHBleGNlcGluZm8sIGUubWVzc2FnZSk7CiAgICAgICAgcmV0ID0gRElTUF9FX0VYQ0VQVElPTjsKICAgIH0KICAgIGNhdGNoKEV4Y2VwdGlvbiYgZSkKICAgIHsKICAgICAgICBPVVN0cmluZyBtZXNzYWdlPSBPVVNUUigiSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpJbnZva2UgOiBcbiIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLk1lc3NhZ2U7CiAgICAgICAgd3JpdGVFeGNlcGluZm8ocGV4Y2VwaW5mbywgbWVzc2FnZSk7CgkJcmV0ID0gRElTUF9FX0VYQ0VQVElPTjsKICAgIH0KCWNhdGNoKC4uLikKCXsKICAgICAgICBPVVN0cmluZyBtZXNzYWdlPSBPVVNUUigiSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpJbnZva2UgOiBcbiIgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CiAgICAgICAgd3JpdGVFeGNlcGluZm8ocGV4Y2VwaW5mbywgbWVzc2FnZSk7CiAJCXJldCA9IERJU1BfRV9FWENFUFRJT047Cgl9CgoJcmV0dXJuIHJldDsKfQkJCQkJCQkJCQkJCSAgCgpIUkVTVUxUIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6ZG9JbnZva2UoIERJU1BQQVJBTVMgKiBwZGlzcHBhcmFtcywgVkFSSUFOVCAqIHB2YXJSZXN1bHQsIAoJCQkJCQkJICBFWENFUElORk8gKiBwZXhjZXBpbmZvLCB1bnNpZ25lZCBpbnQgKiBwdUFyZ0VyciwgT1VTdHJpbmcmIG5hbWUsIFNlcXVlbmNlPEFueT4mIHBhcmFtcykKewoKICAgIAoJSFJFU1VMVCByZXQ9IFNfT0s7CiAgICB0cnkKICAgIHsKICAgICAgICBTZXF1ZW5jZTxzYWxfSW50MTY+IAlvdXRJbmRleDsKICAgICAgICBTZXF1ZW5jZTxBbnk+IAlvdXRQYXJhbXM7CiAgICAgICAgQW55IAkJCQlyZXR1cm5WYWx1ZTsKICAgICAgICAKICAgICAgICBpZiAocGRpc3BwYXJhbXMtPmNOYW1lZEFyZ3MJPiAwKQogICAgICAgICAgICByZXR1cm4gRElTUF9FX05PTkFNRURBUkdTOwkJCQkJCgogICAgICAgIC8vIGludm9rZSBtZXRob2QgYW5kIHRha2UgY2FyZSBvZiBleGNlcHRpb25zCgkJcmV0dXJuVmFsdWUgPSBtX3hJbnZvY2F0aW9uLT5pbnZva2UobmFtZSwgCgkJCQkJCQkJCQkJcGFyYW1zLAoJCQkJCQkJCQkJCW91dEluZGV4LAoJCQkJCQkJCQkJCW91dFBhcmFtcyk7CQkJCQkJCQkJCgogICAgICAgIC8vIHRyeSB0byB3cml0ZSBiYWNrIG91dCBwYXJhbWV0ZXIJCQkJCQkKICAgICAgICBpZiAob3V0SW5kZXguZ2V0TGVuZ3RoKCkgPiAwKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3Qgc2FsX0ludDE2KiBwT3V0SW5kZXggPSBvdXRJbmRleC5nZXRDb25zdEFycmF5KCk7CiAgICAgICAgICAgIGNvbnN0IEFueSogcE91dFBhcmFtcyA9IG91dFBhcmFtcy5nZXRDb25zdEFycmF5KCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBmb3IgKHNhbF9JbnQzMiBpID0gMDsgaSA8IG91dEluZGV4LmdldExlbmd0aCgpOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENDb21WYXJpYW50IHZhcmlhbnQ7CiAgICAgICAgICAgICAgICAvLyBDdXJyZW50bHkgYSBTZXF1ZW5jZSBpcyBjb252ZXJ0ZWQgdG8gYW4gU2FmZUFycmF5IG9mIFZBUklBTlRzLgogICAgICAgICAgICAgICAgYW55VG9WYXJpYW50KCAmdmFyaWFudCwgcE91dFBhcmFtc1tpXSk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vIG91dCBwYXJhbWV0ZXIgbmVlZCBzcGVjaWFsIGhhbmRsaW5nIGlmIHRoZXkgYXJlIFZUX0RJU1BBVENICiAgICAgICAgICAgICAgICAvLyBhbmQgdXNlZCBpbiBKU2NyaXB0CiAgICAgICAgICAgICAgICBpbnQgb3V0aW5kZXg9IHBPdXRJbmRleFtpXTsKICAgICAgICAgICAgICAgIHdyaXRlQmFja091dFBhcmFtZXRlcjIoJihwZGlzcHBhcmFtcy0+cmd2YXJnW3BkaXNwcGFyYW1zLT5jQXJncyAtIDEgLSBvdXRpbmRleF0pLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZhcmlhbnQgKTsgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gd3JpdGUgYmFjayByZXR1cm4gdmFsdWUKICAgICAgICBpZiAocHZhclJlc3VsdCAhPSBOVUxMKSAgIAogICAgICAgICAgICBhbnlUb1ZhcmlhbnQocHZhclJlc3VsdCwgcmV0dXJuVmFsdWUpOyAgICAgICAgICAgIAogICAgfQoJY2F0Y2goSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uICYgZSkgLy9YSW52b2NhdGlvbjo6aW52b2tlCgl7CiAgICAgICAgd3JpdGVFeGNlcGluZm8ocGV4Y2VwaW5mbywgZS5NZXNzYWdlKTsKCQlyZXQgPSBESVNQX0VfVFlQRU1JU01BVENIOwoJfQoJY2F0Y2goQ2Fubm90Q29udmVydEV4Y2VwdGlvbiAmIGUpIC8vWEludm9jYXRpb246Omludm9rZQoJewogICAgICAgIHdyaXRlRXhjZXBpbmZvKHBleGNlcGluZm8sIGUuTWVzc2FnZSk7CgkJcmV0ID0gbWFwQ2Fubm90Q29udmVydEV4Y2VwdGlvbiggZSwgcHVBcmdFcnIpOwoJfQoJY2F0Y2goSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiAmICBlKSAvL1hJbnZvY2F0aW9uOjppbnZva2UKCXsKICAgICAgICBjb25zdCBBbnkmIG9yZyA9IGUuVGFyZ2V0RXhjZXB0aW9uOwogICAgICAgIEV4Y2VwdGlvbiBleGNUYXJnZXQ7CiAgICAgICAgb3JnID4+PSBleGNUYXJnZXQ7CiAgICAgICAgT1VTdHJpbmcgbWVzc2FnZT0gCiAgICAgICAgICAgIG9yZy5nZXRWYWx1ZVR5cGUoKS5nZXRUeXBlTmFtZSgpICsgT1VTVFIoIjogIikgKyBleGNUYXJnZXQuTWVzc2FnZTsKICAgICAgICB3cml0ZUV4Y2VwaW5mbyhwZXhjZXBpbmZvLCBtZXNzYWdlKTsKCQlyZXQgPSBESVNQX0VfRVhDRVBUSU9OOwoJfQoJY2F0Y2goTm9TdWNoTWV0aG9kRXhjZXB0aW9uICYgZSkgLy9YSW52b2NhdGlvbjo6aW52b2tlCgl7CiAgICAgICAgd3JpdGVFeGNlcGluZm8ocGV4Y2VwaW5mbywgZS5NZXNzYWdlKTsKCQlyZXQgPSBESVNQX0VfTUVNQkVSTk9URk9VTkQ7Cgl9CiAgICBjYXRjaChCcmlkZ2VSdW50aW1lRXJyb3IgJiBlKQogICAgewogICAgICAgIHdyaXRlRXhjZXBpbmZvKHBleGNlcGluZm8sIGUubWVzc2FnZSk7CiAgICAgICAgcmV0ID0gRElTUF9FX0VYQ0VQVElPTjsKICAgIH0KICAgIGNhdGNoKEV4Y2VwdGlvbiAmIGUpCiAgICB7CiAgICAgICAgT1VTdHJpbmcgbWVzc2FnZT0gT1VTVFIoIkludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6ZG9JbnZva2UgOiBcbiIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLk1lc3NhZ2U7CiAgICAgICAgd3JpdGVFeGNlcGluZm8ocGV4Y2VwaW5mbywgbWVzc2FnZSk7CiAgICAgICAgcmV0ID0gRElTUF9FX0VYQ0VQVElPTjsKICAgIH0KICAgIGNhdGNoKCAuLi4gKQogCXsKICAgICAgICBPVVN0cmluZyBtZXNzYWdlPSBPVVNUUigiSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpkb0ludm9rZSA6IFxuIiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5leHBlY3RlZCBleGNlcHRpb24iKTsKICAgICAgICB3cml0ZUV4Y2VwaW5mbyhwZXhjZXBpbmZvLCBtZXNzYWdlKTsKIAkJcmV0ID0gRElTUF9FX0VYQ0VQVElPTjsKIAl9CglyZXR1cm4gcmV0Owp9CgpIUkVTVUxUIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6ZG9HZXRQcm9wZXJ0eSggRElTUFBBUkFNUyAqIC8qcGRpc3BwYXJhbXMqLywgVkFSSUFOVCAqIHB2YXJSZXN1bHQsIAoJCQkJCQkJCQkJCQlFWENFUElORk8gKiBwZXhjZXBpbmZvLCBPVVN0cmluZyYgbmFtZSkKewoJSFJFU1VMVCByZXQ9IFNfT0s7CgoJQW55IHZhbHVlOwoJdHJ5Cgl7CgkJQW55IHJldHVyblZhbHVlID0gbV94SW52b2NhdGlvbi0+Z2V0VmFsdWUoIG5hbWUpOwoJCS8vIHdyaXRlIGJhY2sgcmV0dXJuIHZhbHVlCgkJaWYgKHB2YXJSZXN1bHQpCiAgICAgICAgICAgIGFueVRvVmFyaWFudChwdmFyUmVzdWx0LCByZXR1cm5WYWx1ZSk7Cgl9CgljYXRjaChVbmtub3duUHJvcGVydHlFeGNlcHRpb24gZSkgLy9YSW52b2NhdGlvbjo6Z2V0VmFsdWUKCXsKICAgICAgICB3cml0ZUV4Y2VwaW5mbyhwZXhjZXBpbmZvLCBlLk1lc3NhZ2UpOwoJCXJldCA9IERJU1BfRV9NRU1CRVJOT1RGT1VORDsKCX0KICAgIGNhdGNoKEJyaWRnZVJ1bnRpbWVFcnJvciYgZSkKICAgIHsKICAgICAgICB3cml0ZUV4Y2VwaW5mbyhwZXhjZXBpbmZvLCBlLm1lc3NhZ2UpOwogICAgICAgIHJldCA9IERJU1BfRV9FWENFUFRJT047CiAgICB9CiAgICBjYXRjaChFeGNlcHRpb24mIGUpCiAgICB7CiAgICAgICAgT1VTdHJpbmcgbWVzc2FnZT0gT1VTVFIoIkludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6ZG9HZXRQcm9wZXJ0eSA6IFxuIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuTWVzc2FnZTsKICAgICAgICB3cml0ZUV4Y2VwaW5mbyhwZXhjZXBpbmZvLCBtZXNzYWdlKTsKICAgIH0KCWNhdGNoKCAuLi4gKQoJewogICAgICAgIE9VU3RyaW5nIG1lc3NhZ2U9IE9VU1RSKCJJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OmRvSW52b2tlIDogXG4iIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIpOwogICAgICAgIHdyaXRlRXhjZXBpbmZvKHBleGNlcGluZm8sIG1lc3NhZ2UpOwogCQlyZXQgPSBESVNQX0VfRVhDRVBUSU9OOwoJfQoJcmV0dXJuICByZXQ7Cn0KCkhSRVNVTFQgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpkb1NldFByb3BlcnR5KCBESVNQUEFSQU1TICogLypwZGlzcHBhcmFtcyovLCBWQVJJQU5UICogLypwdmFyUmVzdWx0Ki8sIAoJCQkJCQkJCQkJRVhDRVBJTkZPICogcGV4Y2VwaW5mbywgdW5zaWduZWQgaW50ICogcHVBcmdFcnIsIE9VU3RyaW5nJiBuYW1lLCBTZXF1ZW5jZTxBbnk+IHBhcmFtcykKewoJSFJFU1VMVCByZXQ9IFNfT0s7CgkKCXRyeQoJewoJCW1feEludm9jYXRpb24tPnNldFZhbHVlKCBuYW1lLCBwYXJhbXMuZ2V0Q29uc3RBcnJheSgpWzBdKTsKCX0JCgljYXRjaChVbmtub3duUHJvcGVydHlFeGNlcHRpb24gKQoJewoJCXJldCA9IERJU1BfRV9NRU1CRVJOT1RGT1VORDsKCX0KCWNhdGNoKENhbm5vdENvbnZlcnRFeGNlcHRpb24gZSkKCXsKCQlyZXQ9IG1hcENhbm5vdENvbnZlcnRFeGNlcHRpb24oIGUsIHB1QXJnRXJyKTsKCX0KCWNhdGNoKEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24gZSkKCXsKCQlpZiAocGV4Y2VwaW5mbyAhPSBOVUxMKQoJCXsKCQkJQW55IG9yZyA9IGUuVGFyZ2V0RXhjZXB0aW9uOwoJCQkKCQkJcGV4Y2VwaW5mby0+d0NvZGUgPSBVTk9fMl9PTEVfRVhDRVBUSU9OQ09ERTsKCQkJcGV4Y2VwaW5mby0+YnN0clNvdXJjZSA9IFN5c0FsbG9jU3RyaW5nKEwiYW55IE9ORSBjb21wb25lbnQiKTsKCQkJcGV4Y2VwaW5mby0+YnN0ckRlc2NyaXB0aW9uID0gU3lzQWxsb2NTdHJpbmcoCgkJCQlyZWludGVycHJldF9jYXN0PExQQ09MRVNUUj4ob3JnLmdldFZhbHVlVHlwZSgpLmdldFR5cGVOYW1lKCkuZ2V0U3RyKCkpKTsKCQl9CgkJcmV0ID0gRElTUF9FX0VYQ0VQVElPTjsKCX0KCWNhdGNoKCAuLi4gKQoJewoJCXJldD0gRElTUF9FX0VYQ0VQVElPTjsKCX0KCXJldHVybiByZXQ7Cn0KCkhSRVNVTFQgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpJbnZva2VHZW5lcmFsKCBESVNQSUQgZGlzcGlkTWVtYmVyLCB1bnNpZ25lZCBzaG9ydCB3RmxhZ3MsCgkgICAgICAgICAgICAgICAgICAgICBESVNQUEFSQU1TICogcGRpc3BwYXJhbXMsIFZBUklBTlQgKiBwdmFyUmVzdWx0LCBFWENFUElORk8gKiBwZXhjZXBpbmZvLAoJICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50ICogLypwdUFyZ0VyciovLCBzYWxfQm9vbCYgYkhhbmRsZWQpCnsKCUhSRVNVTFQgcmV0PSBTX09LOwogICAgdHJ5CiAgICB7Ci8vIERJU1BJRF9WQUxVRSB8IFRoZSBERUZBVUxUIFZhbHVlIGlzIHJlcXVpcmVkIGluIEpTY3JpcHQgd2hlbiB0aGUgc2l0dWF0aW9uCi8vIGlzIHRoYXQgd2UgcHV0IGFuIG9iamVjdCBpbnRvIGFuIEFycmF5IG9iamVjdCAoIG91dCBwYXJhbWV0ZXIpLiBXZSBoYXZlIHRvIHJldHVybgovLyBJRGlzcGF0Y2ggb3RoZXJ3aXNlIHRoZSBvYmplY3QgY2Fubm90IGJlIGFjY2Vzc2VkIGZyb20gdGhlIFNjcmlwdC4KICAgICAgICBpZiggZGlzcGlkTWVtYmVyID09IERJU1BJRF9WQUxVRSAmJiB3RmxhZ3MgPT0gRElTUEFUQ0hfUFJPUEVSVFlHRVQKICAgICAgICAgICAgJiYgbV9kZWZhdWx0VmFsdWVUeXBlICE9IFZUX0VNUFRZICYmIHB2YXJSZXN1bHQgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIGJIYW5kbGVkPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgaWYoIG1fZGVmYXVsdFZhbHVlVHlwZSA9PSBWVF9ESVNQQVRDSCkJCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHB2YXJSZXN1bHQtPnZ0PSBWVF9ESVNQQVRDSDsKICAgICAgICAgICAgICAgIHB2YXJSZXN1bHQtPnBkaXNwVmFsPSBzdGF0aWNfY2FzdDxJRGlzcGF0Y2gqPiggdGhpcyk7CiAgICAgICAgICAgICAgICBBZGRSZWYoKTsKICAgICAgICAgICAgICAgIHJldD0gU19PSzsKICAgICAgICAgICAgfQogICAgICAgIH0KLy8gLS0tLS0tLS0tCiAgICAgICAgLy8gZnVuY3Rpb246IF9HZXRWYWx1ZU9iamVjdAogICAgICAgIGVsc2UgaWYoIGRpc3BpZE1lbWJlciA9PSBESVNQSURfSlNDUklQVF9WQUxVRV9GVU5DKQogICAgICAgIHsKICAgICAgICAgICAgYkhhbmRsZWQ9IHNhbF9UcnVlOwogICAgICAgICAgICBpZiggIXB2YXJSZXN1bHQpCiAgICAgICAgICAgICAgICByZXQ9IEVfUE9JTlRFUjsKICAgICAgICAgICAgQ0NvbU9iamVjdDwgSlNjcmlwdFZhbHVlPiogcFZhbHVlOwogICAgICAgICAgICBpZiggU1VDQ0VFREVEKCBDQ29tT2JqZWN0PEpTY3JpcHRWYWx1ZT46OkNyZWF0ZUluc3RhbmNlKCAmcFZhbHVlKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBWYWx1ZS0+QWRkUmVmKCk7CiAgICAgICAgICAgICAgICBwdmFyUmVzdWx0LT52dD0gVlRfRElTUEFUQ0g7CiNpZmRlZiBfX01JTkdXMzJfXwogICAgICAgICAgICAgICAgcHZhclJlc3VsdC0+cGRpc3BWYWw9IENDb21RSVB0cjxJRGlzcGF0Y2gsICZfX3V1aWRvZihJRGlzcGF0Y2gpPihwVmFsdWUtPkdldFVua25vd24oKSk7CiNlbHNlCiAgICAgICAgICAgICAgICBwdmFyUmVzdWx0LT5wZGlzcFZhbD0gQ0NvbVFJUHRyPElEaXNwYXRjaD4ocFZhbHVlLT5HZXRVbmtub3duKCkpOwojZW5kaWYKICAgICAgICAgICAgICAgIHJldD0gU19PSzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXQ9IERJU1BfRV9FWENFUFRJT047CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoIGRpc3BpZE1lbWJlciA9PSBESVNQSURfR0VUX1NUUlVDVF9GVU5DKQogICAgICAgIHsKICAgICAgICAgICAgYkhhbmRsZWQ9IHNhbF9UcnVlOwogICAgICAgICAgICBzYWxfQm9vbCBiU3RydWN0PSBzYWxfRmFsc2U7CiAgICAgICAgICAgIAogICAgICAgICAgICAKICAgICAgICAgICAgUmVmZXJlbmNlPFhJbnRlcmZhY2U+IHhJbnRDb3JlPQltX3NtZ3ItPmNyZWF0ZUluc3RhbmNlKCBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb20uc3VuLnN0YXIucmVmbGVjdGlvbi5Db3JlUmVmbGVjdGlvbiIpKTsKICAgICAgICAgICAgUmVmZXJlbmNlPFhJZGxSZWZsZWN0aW9uPiB4UmVmbCggeEludENvcmUsIFVOT19RVUVSWSk7CiAgICAgICAgICAgIGlmKCB4UmVmbC5pcygpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IHBhcmFtZXRlciBpcyBpbiBESVNQUEFSQU1TIHJndmFyZ3MgY29udGFpbnMgdGhlIG5hbWUgb2YgdGhlIHN0cnVjdC4KICAgICAgICAgICAgICAgIENDb21WYXJpYW50IGFyZzsKICAgICAgICAgICAgICAgIGlmKCBwZGlzcHBhcmFtcy0+Y0FyZ3MgPT0gMSAmJiBTVUNDRUVERUQoIGFyZy5DaGFuZ2VUeXBlKCBWVF9CU1RSLCAmcGRpc3BwYXJhbXMtPnJndmFyZ1swXSkpICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2U8WElkbENsYXNzPiBjbGFzc1N0cnVjdD0geFJlZmwtPmZvck5hbWUoIHJlaW50ZXJwcmV0X2Nhc3Q8Y29uc3Qgc2FsX1VuaWNvZGUqPihhcmcuYnN0clZhbCkpOwogICAgICAgICAgICAgICAgICAgIGlmKCBjbGFzc1N0cnVjdC5pcygpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgQW55IGFueVN0cnVjdDsKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NTdHJ1Y3QtPmNyZWF0ZU9iamVjdCggYW55U3RydWN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgQ0NvbVZhcmlhbnQgdmFyOwogICAgICAgICAgICAgICAgICAgICAgICBhbnlUb1ZhcmlhbnQoICZ2YXIsIGFueVN0cnVjdCApOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIHZhci52dCA9PSBWVF9ESVNQQVRDSCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFyaWFudENvcHkoIHB2YXJSZXN1bHQsICYgdmFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJTdHJ1Y3Q9IHNhbF9UcnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CQogICAgICAgICAgICByZXQ9IGJTdHJ1Y3QgPT0gc2FsX1RydWUgPyBTX09LIDogRElTUF9FX0VYQ0VQVElPTjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZGlzcGlkTWVtYmVyID09IERJU1BJRF9DUkVBVEVfVFlQRV9GVU5DKQogICAgICAgIHsKICAgICAgICAgICAgYkhhbmRsZWQ9IHNhbF9UcnVlOwogICAgICAgICAgICBpZiggIXB2YXJSZXN1bHQpCiAgICAgICAgICAgICAgICByZXQ9IEVfUE9JTlRFUjsKICAgICAgICAgICAgLy8gdGhlIGZpcnN0IHBhcmFtZXRlciBpcyBpbiBESVNQUEFSQU1TIHJndmFyZ3MgY29udGFpbnMgdGhlIG5hbWUgb2YgdGhlIHN0cnVjdC4KICAgICAgICAgICAgQ0NvbVZhcmlhbnQgYXJnOwogICAgICAgICAgICBpZiggcGRpc3BwYXJhbXMtPmNBcmdzICE9IDEpCiAgICAgICAgICAgICAgICByZXR1cm4gRElTUF9FX0JBRFBBUkFNQ09VTlQ7CiAgICAgICAgICAgIGlmIChGQUlMRUQoIGFyZy5DaGFuZ2VUeXBlKCBWVF9CU1RSLCAmcGRpc3BwYXJhbXMtPnJndmFyZ1swXSkpKQogICAgICAgICAgICAgICAgcmV0dXJuIERJU1BfRV9CQURWQVJUWVBFOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIC8vY2hlY2sgaWYgdGhlIHByb3ZpZGVkIG5hbWUgcmVwcmVzZW50cyBhIHZhbGlkIHR5cGUKICAgICAgICAgICAgVHlwZSB0eXBlOwogICAgICAgICAgICBpZiAoZ2V0VHlwZShhcmcuYnN0clZhbCwgdHlwZSkgPT0gZmFsc2UpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHdyaXRlRXhjZXBpbmZvKHBleGNlcGluZm8sT1VTdHJpbmcoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1VTVFIoIlthdXRvbWF0aW9uIGJyaWRnZV0gQSBVTk8gdHlwZSB3aXRoIHRoZSBuYW1lICIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPVVN0cmluZyhyZWludGVycHJldF9jYXN0PGNvbnN0IHNhbF9Vbmljb2RlKj4oYXJnLmJzdHJWYWwpKSArIE9VU1RSKCIgZG9lcyBub3QgZXhpc3QhIikpKTsKICAgICAgICAgICAgICAgIHJldHVybiBESVNQX0VfRVhDRVBUSU9OOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY3JlYXRlVW5vVHlwZVdyYXBwZXIoYXJnLmJzdHJWYWwsIHB2YXJSZXN1bHQpID09IGZhbHNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB3cml0ZUV4Y2VwaW5mbyhwZXhjZXBpbmZvLE9VU1RSKCJbYXV0b21hdGlvbiBicmlkZ2VdIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6SW52b2tlR2VuZXJhbFxuIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ291bGQgbm90IGluaXRpYWxpemUgVW5vVHlwZVdyYXBwZXIgb2JqZWN0ISIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBESVNQX0VfRVhDRVBUSU9OOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgY2F0Y2goQnJpZGdlUnVudGltZUVycm9yICYgZSkKICAgIHsKICAgICAgICB3cml0ZUV4Y2VwaW5mbyhwZXhjZXBpbmZvLCBlLm1lc3NhZ2UpOwogICAgICAgIHJldCA9IERJU1BfRV9FWENFUFRJT047CiAgICB9CiAgICBjYXRjaChFeGNlcHRpb24gJiBlKQogICAgewogICAgICAgIE9VU3RyaW5nIG1lc3NhZ2U9IE9VU1RSKCJJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6Okludm9rZUdlbmVyYWwgOiBcbiIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLk1lc3NhZ2U7CiAgICAgICAgd3JpdGVFeGNlcGluZm8ocGV4Y2VwaW5mbywgbWVzc2FnZSk7CiAgICAgICAgcmV0ID0gRElTUF9FX0VYQ0VQVElPTjsKICAgIH0KICAgIGNhdGNoKCAuLi4gKQogCXsKICAgICAgICBPVVN0cmluZyBtZXNzYWdlPSBPVVNUUigiSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpJbnZva2VHZW5lcmFsIDogXG4iIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIGV4Y2VwdGlvbiIpOwogICAgICAgIHdyaXRlRXhjZXBpbmZvKHBleGNlcGluZm8sIG1lc3NhZ2UpOwogCQlyZXQgPSBESVNQX0VfRVhDRVBUSU9OOwogCX0KCXJldHVybiByZXQ7Cn0KCgoKClNURE1FVEhPRElNUCBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OkdldERpc3BJRChCU1RSIC8qYnN0ck5hbWUqLywgRFdPUkQgLypncmZkZXgqLywgRElTUElEIF9fUlBDX0ZBUiogLypwaWQqLykKewoJSFJFU1VMVCByZXQgPSBSZXN1bHRGcm9tU2NvZGUoRV9OT1RJTVBMKTsJCgoJcmV0dXJuIHJldDsKfQoKU1RETUVUSE9ESU1QIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6SW52b2tlRXgoIAoJLyogW2luXSAqLyBESVNQSUQgLyppZCovLAoJLyogW2luXSAqLyBMQ0lEIC8qbGNpZCovLAoJLyogW2luXSAqLyBXT1JEIC8qd0ZsYWdzKi8sCgkvKiBbaW5dICovIERJU1BQQVJBTVMgX19SUENfRkFSKiAvKnBkcCovLAoJLyogW291dF0gKi8gVkFSSUFOVCBfX1JQQ19GQVIqIC8qcHZhclJlcyovLAoJLyogW291dF0gKi8gRVhDRVBJTkZPIF9fUlBDX0ZBUiogLypwZWkqLywKCS8qIFt1bmlxdWVdW2luXSAqLyBJU2VydmljZVByb3ZpZGVyIF9fUlBDX0ZBUiogLypwc3BDYWxsZXIqLykKewoJSFJFU1VMVCByZXQgPSBSZXN1bHRGcm9tU2NvZGUoRV9OT1RJTVBMKTsJCgoJcmV0dXJuIHJldDsKfQoKClNURE1FVEhPRElNUCBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OkRlbGV0ZU1lbWJlckJ5TmFtZSggCiAgICAvKiBbaW5dICovIEJTVFIgLypic3RyKi8sCiAgICAvKiBbaW5dICovIERXT1JEIC8qZ3JmZGV4Ki8pCnsKCUhSRVNVTFQgcmV0ID0gUmVzdWx0RnJvbVNjb2RlKEVfTk9USU1QTCk7CQoKCXJldHVybiByZXQ7Cn0KClNURE1FVEhPRElNUCBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OkRlbGV0ZU1lbWJlckJ5RGlzcElEKERJU1BJRCAvKmlkKi8pCnsKCUhSRVNVTFQgcmV0ID0gUmVzdWx0RnJvbVNjb2RlKEVfTk9USU1QTCk7CQoKCXJldHVybiByZXQ7Cn0KClNURE1FVEhPRElNUCBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OkdldE1lbWJlclByb3BlcnRpZXMoIAogICAgLyogW2luXSAqLyBESVNQSUQgLyppZCovLAogICAgLyogW2luXSAqLyBEV09SRCAvKmdyZmRleEZldGNoKi8sCiAgICAvKiBbb3V0XSAqLyBEV09SRCBfX1JQQ19GQVIqIC8qcGdyZmRleCovKQp7CglIUkVTVUxUIHJldCA9IFJlc3VsdEZyb21TY29kZShFX05PVElNUEwpOwkKCglyZXR1cm4gcmV0Owp9CgpTVERNRVRIT0RJTVAgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpHZXRNZW1iZXJOYW1lKCAKICAgIC8qIFtpbl0gKi8gRElTUElEIC8qaWQqLywKICAgIC8qIFtvdXRdICovIEJTVFIgX19SUENfRkFSKiAvKnBic3RyTmFtZSovKQp7CglIUkVTVUxUIHJldCA9IFJlc3VsdEZyb21TY29kZShFX05PVElNUEwpOwkKCglyZXR1cm4gcmV0Owp9CgpTVERNRVRIT0RJTVAgSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsOjpHZXROZXh0RGlzcElEKCAKICAgIC8qIFtpbl0gKi8gRFdPUkQgLypncmZkZXgqLywKICAgIC8qIFtpbl0gKi8gRElTUElEIC8qaWQqLywKICAgIC8qIFtvdXRdICovIERJU1BJRCBfX1JQQ19GQVIqIC8qcGlkKi8pCnsKCUhSRVNVTFQgcmV0ID0gUmVzdWx0RnJvbVNjb2RlKEVfTk9USU1QTCk7CQoKCXJldHVybiByZXQ7Cn0KClNURE1FVEhPRElNUCBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6OkdldE5hbWVTcGFjZVBhcmVudCggCiAgICAvKiBbb3V0XSAqLyBJVW5rbm93biBfX1JQQ19GQVIgKl9fUlBDX0ZBUiogLypwcHVuayovKQp7CglIUkVTVUxUIHJldCA9IFJlc3VsdEZyb21TY29kZShFX05PVElNUEwpOwkKCglyZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCglVbm9PYmplY3RXcmFwcGVyUmVtb3RlT3B0CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpVbm9PYmplY3RXcmFwcGVyUmVtb3RlT3B0OjpVbm9PYmplY3RXcmFwcGVyUmVtb3RlT3B0KCBSZWZlcmVuY2U8WE11bHRpU2VydmljZUZhY3Rvcnk+JiBhRmFjdG9yeSwKCQkJCQkJCQkJCQkJCSBzYWxfdUludDggdW5vV3JhcHBlckNsYXNzLCBzYWxfdUludDggY29tV3JhcHBlckNsYXNzKToKSW50ZXJmYWNlT2xlV3JhcHBlcl9JbXBsKCBhRmFjdG9yeSwgdW5vV3JhcHBlckNsYXNzLCBjb21XcmFwcGVyQ2xhc3MpLAptX2N1cnJlbnRJZCgxKQoKewp9ClVub09iamVjdFdyYXBwZXJSZW1vdGVPcHQ6On5Vbm9PYmplY3RXcmFwcGVyUmVtb3RlT3B0KCkKewp9CgovLyBVbm9Db252ZXJzaW9uVXRpbGl0aWVzClJlZmVyZW5jZTwgWEludGVyZmFjZSA+IFVub09iamVjdFdyYXBwZXJSZW1vdGVPcHQ6OmNyZWF0ZVVub1dyYXBwZXJJbnN0YW5jZSgpCnsKCVJlZmVyZW5jZTxYV2Vhaz4geFdlYWs9IHN0YXRpY19jYXN0PFhXZWFrKj4oIG5ldyBVbm9PYmplY3RXcmFwcGVyUmVtb3RlT3B0KAoJCQkJCQkJCQkJCQkgbV9zbWdyLCBtX25Vbm9XcmFwcGVyQ2xhc3MsIG1fbkNvbVdyYXBwZXJDbGFzcykpOwoJcmV0dXJuIFJlZmVyZW5jZTxYSW50ZXJmYWNlPiggeFdlYWssIFVOT19RVUVSWSk7Cn0KClNURE1FVEhPRElNUCAgVW5vT2JqZWN0V3JhcHBlclJlbW90ZU9wdDo6R2V0SURzT2ZOYW1lcyAoIFJFRklJRCAvKnJpaWQqLywgT0xFQ0hBUiAqKiByZ3N6TmFtZXMsIHVuc2lnbmVkIGludCBjTmFtZXMsCgkJCQkJCQkJTENJRCAvKmxjaWQqLywgRElTUElEICogcmdkaXNwaWQgKQp7CglNdXRleEd1YXJkIGd1YXJkKCBnZXRCcmlkZ2VNdXRleCgpKTsKCglpZiggISByZ2Rpc3BpZCkKCQlyZXR1cm4gRV9QT0lOVEVSOwoJSFJFU1VMVCByZXQgPSBFX1VORVhQRUNURUQ7CgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkvLyBfR2V0VmFsdWVPYmplY3QKCWlmKCAhIHdjc2NtcCggKnJnc3pOYW1lcywgSlNDUklQVF9WQUxVRV9GVU5DKSkKCXsKCQkqcmdkaXNwaWQ9IERJU1BJRF9KU0NSSVBUX1ZBTFVFX0ZVTkM7CgkJcmV0dXJuIFNfT0s7Cgl9CgllbHNlIGlmKCAhIHdjc2NtcCggKnJnc3pOYW1lcywgR0VUX1NUUlVDVF9GVU5DKSkKCXsKCQkqcmdkaXNwaWQ9IERJU1BJRF9HRVRfU1RSVUNUX0ZVTkM7CgkJcmV0dXJuIFNfT0s7Cgl9CgoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJaWYgKG1feEludm9jYXRpb24uaXMoKSAmJiAoY05hbWVzID4gMCkpCgl7CgkJT1VTdHJpbmcgbmFtZShyZWludGVycHJldF9jYXN0PGNvbnN0IHNhbF9Vbmljb2RlKj4ocmdzek5hbWVzWzBdKSk7CgkJLy8gaGFzIHRoaXMgbmFtZSBiZWVuIGRldGVybWluZWQgYXMgImJhZCIKCQlCYWROYW1lTWFwOjppdGVyYXRvciBiYWRJdGVyPSBtX2JhZE5hbWVNYXAuZmluZCggbmFtZSk7CgkJaWYoIGJhZEl0ZXIgPT0gbV9iYWROYW1lTWFwLmVuZCgpICkKCQl7CgkJCS8vIG5hbWUgaGFzIG5vdCBiZWVuIGJhZCBiZWZvcmUoIG1lbWJlciBleGlzdHMKCQkJdHlwZWRlZiBOYW1lVG9JZE1hcDo6aXRlcmF0b3IgSVRuYW1lczsKCQkJcGFpcjwgSVRuYW1lcywgYm9vbCA+IHBhaXJfaWQ9IG1fbmFtZVRvRGlzcElkTWFwLmluc2VydCggTmFtZVRvSWRNYXA6OnZhbHVlX3R5cGUobmFtZSwgbV9jdXJyZW50SWQrKykpOwoJCQkvLyBuZXcgSUQgaW5zZXJ0ZWQgPwoJCQlpZiggcGFpcl9pZC5zZWNvbmQgKQoJCQl7Ly8geWVzLCBub3cgY3JlYXRlIE1lbWJlckluZm8gYW5kIGFkIHRvIElkVG9NZW1iZXJJbmZvTWFwCgkJCQlNZW1iZXJJbmZvIGQoMCwgbmFtZSk7CgkJCQltX2lkVG9NZW1iZXJJbmZvTWFwLmluc2VydCggSWRUb01lbWJlckluZm9NYXA6OnZhbHVlX3R5cGUoIG1fY3VycmVudElkIC0gMSwgZCkpOwoJCQl9CgoJCQkqcmdkaXNwaWQgPSBwYWlyX2lkLmZpcnN0LT5zZWNvbmQ7CgkJCXJldCA9IFNfT0s7CgkJfQoJCWVsc2UKCQkJcmV0PSBESVNQX0VfVU5LTk9XTk5BTUU7Cgl9CglyZXR1cm4gcmV0Owp9CgpTVERNRVRIT0RJTVAgIFVub09iamVjdFdyYXBwZXJSZW1vdGVPcHQ6Okludm9rZSAoIERJU1BJRCBkaXNwaWRNZW1iZXIsIFJFRklJRCAvKnJpaWQqLywgTENJRCAvKmxjaWQqLywgdW5zaWduZWQgc2hvcnQgd0ZsYWdzLAoJICAgICAgICAgICAgICAgICAgICAgRElTUFBBUkFNUyAqIHBkaXNwcGFyYW1zLCBWQVJJQU5UICogcHZhclJlc3VsdCwgRVhDRVBJTkZPICogcGV4Y2VwaW5mbywKCSAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCAqIHB1QXJnRXJyICkKewoJSFJFU1VMVCByZXQgPSBTX09LOwogICAgdHJ5CiAgICB7CiAgICAgICAgc2FsX0Jvb2wgYkhhbmRsZWQ9IHNhbF9GYWxzZTsKICAgICAgICByZXQ9IEludm9rZUdlbmVyYWwoIGRpc3BpZE1lbWJlciwgIHdGbGFncywgcGRpc3BwYXJhbXMsIHB2YXJSZXN1bHQsICBwZXhjZXBpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVBcmdFcnIsIGJIYW5kbGVkKTsKICAgICAgICBpZiggYkhhbmRsZWQpCiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgCiAgICAgICAgaWYgKCBkaXNwaWRNZW1iZXIgPiAwICAmJiBtX3hJbnZvY2F0aW9uLmlzKCkpCiAgICAgICAgewogICAgICAgICAgICAKICAgICAgICAgICAgSWRUb01lbWJlckluZm9NYXA6Oml0ZXJhdG9yIGl0X01lbWJlckluZm89IG1faWRUb01lbWJlckluZm9NYXAuZmluZCggZGlzcGlkTWVtYmVyKTsKICAgICAgICAgICAgaWYoIGl0X01lbWJlckluZm8gIT0gbV9pZFRvTWVtYmVySW5mb01hcC5lbmQoKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE1lbWJlckluZm8mIGluZm89IGl0X01lbWJlckluZm8tPnNlY29uZDsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgU2VxdWVuY2U8QW55PiBwYXJhbXM7IC8vIGhvbGRzIGNvbnZlcnRlZCBhbnkgcwogICAgICAgICAgICAgICAgaWYoICEgaW5mby5mbGFncyApCiAgICAgICAgICAgICAgICB7IC8vIERJU1BJRCBjYWxsZWQgZm9yIHRoZSBmaXJzdCB0aW1lCiAgICAgICAgICAgICAgICAgICAgaWYoIHdGbGFncyA9PSBESVNQQVRDSF9NRVRIT0QgKQogICAgICAgICAgICAgICAgICAgIHsJCQkJCQogICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0RGlzcHBhcmFtc0FyZ3MoZGlzcGlkTWVtYmVyLCB3RmxhZ3MsIHBkaXNwcGFyYW1zLCBwYXJhbXMgKTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBGQUlMRUQoIHJldD0gZG9JbnZva2UoIHBkaXNwcGFyYW1zLCBwdmFyUmVzdWx0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGV4Y2VwaW5mbywgcHVBcmdFcnIsIGluZm8ubmFtZSwgcGFyYW1zKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHJldCA9PSBESVNQX0VfTUVNQkVSTk9URk9VTkQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0byBnZXQgdGhlIGV4YWN0IG5hbWUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPVVN0cmluZyBleGFjdE5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobV94RXhhY3ROYW1lLmlzKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhhY3ROYW1lID0gbV94RXhhY3ROYW1lLT5nZXRFeGFjdE5hbWUoIGluZm8ubmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW52b2tlIGFnYWluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIGV4YWN0TmFtZS5nZXRMZW5ndGgoKSAhPSAwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIFNVQ0NFRURFRCggcmV0PSBkb0ludm9rZSggcGRpc3BwYXJhbXMsIHB2YXJSZXN1bHQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXhjZXBpbmZvLCBwdUFyZ0VyciwgZXhhY3ROYW1lLCBwYXJhbXMpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubmFtZT0gZXhhY3ROYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0JCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBTVUNDRUVERUQoIHJldCApICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8uZmxhZ3M9IERJU1BBVENIX01FVEhPRDsKICAgICAgICAgICAgICAgICAgICB9IC8vaWYoIHdGbGFncyA9PSBESVNQQVRDSF9NRVRIT0QgKQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIHdGbGFncyA9PSBESVNQQVRDSF9QUk9QRVJUWVBVVCB8fCB3RmxhZ3MgPT0gRElTUEFUQ0hfUFJPUEVSVFlQVVRSRUYpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0RGlzcHBhcmFtc0FyZ3MoZGlzcGlkTWVtYmVyLCB3RmxhZ3MsIHBkaXNwcGFyYW1zLCBwYXJhbXMgKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIEZBSUxFRCggcmV0PSBkb1NldFByb3BlcnR5KCBwZGlzcHBhcmFtcywgcHZhclJlc3VsdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGV4Y2VwaW5mbywgcHVBcmdFcnIsIGluZm8ubmFtZSwgcGFyYW1zKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHJldCA9PSBESVNQX0VfTUVNQkVSTk9URk9VTkQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyeSB0byBnZXQgdGhlIGV4YWN0IG5hbWUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPVVN0cmluZyBleGFjdE5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobV94RXhhY3ROYW1lLmlzKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhhY3ROYW1lID0gbV94RXhhY3ROYW1lLT5nZXRFeGFjdE5hbWUoIGluZm8ubmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW52b2tlIGFnYWluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIGV4YWN0TmFtZS5nZXRMZW5ndGgoKSAhPSAwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIFNVQ0NFRURFRCggcmV0PSBkb1NldFByb3BlcnR5KCBwZGlzcHBhcmFtcywgcHZhclJlc3VsdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGV4Y2VwaW5mbywgcHVBcmdFcnIsIGV4YWN0TmFtZSwgcGFyYW1zKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5hbWU9IGV4YWN0TmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CQogICAgICAgICAgICAgICAgICAgICAgICBpZiggU1VDQ0VFREVEKCByZXQgKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmZsYWdzPSBESVNQQVRDSF9QUk9QRVJUWVBVVCB8IERJU1BBVENIX1BST1BFUlRZR0VUOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKCB3RmxhZ3MgPT0gRElTUEFUQ0hfUFJPUEVSVFlHRVQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiggRkFJTEVEKCByZXQ9IGRvR2V0UHJvcGVydHkoIHBkaXNwcGFyYW1zLCBwdmFyUmVzdWx0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXhjZXBpbmZvLCBpbmZvLm5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgcmV0ID09IERJU1BfRV9NRU1CRVJOT1RGT1VORCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJ5IHRvIGdldCB0aGUgZXhhY3QgbmFtZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9VU3RyaW5nIGV4YWN0TmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtX3hFeGFjdE5hbWUuaXMoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGFjdE5hbWUgPSBtX3hFeGFjdE5hbWUtPmdldEV4YWN0TmFtZSggaW5mby5uYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnZva2UgYWdhaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggZXhhY3ROYW1lLmdldExlbmd0aCgpICE9IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggU1VDQ0VFREVEKCByZXQ9IGRvR2V0UHJvcGVydHkoIHBkaXNwcGFyYW1zLCBwdmFyUmVzdWx0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXhjZXBpbmZvLCBleGFjdE5hbWUpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubmFtZT0gZXhhY3ROYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0JCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBTVUNDRUVERUQoIHJldCApICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8uZmxhZ3M9IERJU1BBVENIX1BST1BFUlRZR0VUIHwgRElTUEFUQ0hfUFJPUEVSVFlQVVQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIHdGbGFncyAmIERJU1BBVENIX01FVEhPRCAmJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAod0ZsYWdzICYgRElTUEFUQ0hfUFJPUEVSVFlQVVQgfHwgd0ZsYWdzICYgRElTUEFUQ0hfUFJPUEVSVFlQVVRSRUYpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIE9VU3RyaW5nIGV4YWN0TmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udmVydCBwYXJhbXMgZm9yIERJU1BBVENIX01FVEhPRCBvciBESVNQQVRDSF9QUk9QRVJUWVBVVAogICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0RGlzcHBhcmFtc0FyZ3MoZGlzcGlkTWVtYmVyLCB3RmxhZ3MsIHBkaXNwcGFyYW1zLCBwYXJhbXMgKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJ5IGZpcnN0IGFzIG1ldGhvZAogICAgICAgICAgICAgICAgICAgICAgICBpZiggRkFJTEVEKCByZXQ9IGRvSW52b2tlKCBwZGlzcHBhcmFtcywgcHZhclJlc3VsdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBleGNlcGluZm8sIHB1QXJnRXJyLCBpbmZvLm5hbWUsIHBhcmFtcykpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiByZXQgPT0gRElTUF9FX01FTUJFUk5PVEZPVU5EKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gZ2V0IHRoZSBleGFjdCBuYW1lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1feEV4YWN0TmFtZS5pcygpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0TmFtZSA9IG1feEV4YWN0TmFtZS0+Z2V0RXhhY3ROYW1lKCBpbmZvLm5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludm9rZSBhZ2FpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBleGFjdE5hbWUuZ2V0TGVuZ3RoKCkgIT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBTVUNDRUVERUQoIHJldD0gZG9JbnZva2UoIHBkaXNwcGFyYW1zLCBwdmFyUmVzdWx0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGV4Y2VwaW5mbywgcHVBcmdFcnIsIGV4YWN0TmFtZSwgcGFyYW1zKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5hbWU9IGV4YWN0TmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CQogICAgICAgICAgICAgICAgICAgICAgICBpZiggU1VDQ0VFREVEKCByZXQgKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmZsYWdzPSBESVNQQVRDSF9NRVRIT0Q7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAvLyB0cnkgYXMgcHJvcGVydHkKCQkJCQkJaWYoIEZBSUxFRCggcmV0KSAmJiBwZGlzcHBhcmFtcy0+Y0FyZ3MgPT0gMSkKCQkJCQkJewoJCQkJCQkJaWYoIEZBSUxFRCggcmV0PSBkb1NldFByb3BlcnR5KCBwZGlzcHBhcmFtcywgcHZhclJlc3VsdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBleGNlcGluZm8sIHB1QXJnRXJyLCBpbmZvLm5hbWUsIHBhcmFtcykpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgcmV0ID09IERJU1BfRV9NRU1CRVJOT1RGT1VORCkKCQkJCQkJCXsKCQkJCQkJCQkvLyB0cnkgdG8gZ2V0IHRoZSBleGFjdCBuYW1lIAoJCQkJCQkJCWlmKCBleGFjdE5hbWUuZ2V0TGVuZ3RoKCkgIT0gMCkKCQkJCQkJCQl7CgkJCQkJCQkJCWlmKCBTVUNDRUVERUQoIHJldD0gZG9TZXRQcm9wZXJ0eSggcGRpc3BwYXJhbXMsIHB2YXJSZXN1bHQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBleGNlcGluZm8sIHB1QXJnRXJyLCBleGFjdE5hbWUsIHBhcmFtcykpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mby5uYW1lPSBleGFjdE5hbWU7CgkJCQkJCQkJfSAKCQkJCQkJCX0JCgkJCQkJCQlpZiggU1VDQ0VFREVEKCByZXQgKSApCgkJCQkJCQkJaW5mby5mbGFncz0gRElTUEFUQ0hfUFJPUEVSVFlQVVQgfCBESVNQQVRDSF9QUk9QRVJUWUdFVDsJCQkJCQoJCQkJCQl9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIHdGbGFncyAmIERJU1BBVENIX01FVEhPRCAmJiB3RmxhZ3MgJiBESVNQQVRDSF9QUk9QRVJUWUdFVCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIE9VU3RyaW5nIGV4YWN0TmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydERpc3BwYXJhbXNBcmdzKGRpc3BpZE1lbWJlciwgd0ZsYWdzLCBwZGlzcHBhcmFtcywgcGFyYW1zICk7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpZiggRkFJTEVEKCByZXQ9IGRvSW52b2tlKCBwZGlzcHBhcmFtcywgcHZhclJlc3VsdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBleGNlcGluZm8sIHB1QXJnRXJyLCBpbmZvLm5hbWUsIHBhcmFtcykpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiByZXQgPT0gRElTUF9FX01FTUJFUk5PVEZPVU5EKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0cnkgdG8gZ2V0IHRoZSBleGFjdCBuYW1lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1feEV4YWN0TmFtZS5pcygpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4YWN0TmFtZSA9IG1feEV4YWN0TmFtZS0+Z2V0RXhhY3ROYW1lKCBpbmZvLm5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludm9rZSBhZ2FpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBleGFjdE5hbWUuZ2V0TGVuZ3RoKCkgIT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBTVUNDRUVERUQoIHJldD0gZG9JbnZva2UoIHBkaXNwcGFyYW1zLCBwdmFyUmVzdWx0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGV4Y2VwaW5mbywgcHVBcmdFcnIsIGV4YWN0TmFtZSwgcGFyYW1zKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLm5hbWU9IGV4YWN0TmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CQogICAgICAgICAgICAgICAgICAgICAgICBpZiggU1VDQ0VFREVEKCByZXQgKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmZsYWdzPSBESVNQQVRDSF9NRVRIT0Q7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAvLyB0cnkgYXMgcHJvcGVydHkKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIEZBSUxFRCggcmV0KSAmJiBwZGlzcHBhcmFtcy0+Y0FyZ3MgPT0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIEZBSUxFRCggcmV0PSBkb0dldFByb3BlcnR5KCBwZGlzcHBhcmFtcywgcHZhclJlc3VsdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBleGNlcGluZm8sIGluZm8ubmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgcmV0ID09IERJU1BfRV9NRU1CRVJOT1RGT1VORCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggZXhhY3ROYW1lLmdldExlbmd0aCgpICE9IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggU1VDQ0VFREVEKCByZXQ9IGRvU2V0UHJvcGVydHkoIHBkaXNwcGFyYW1zLCBwdmFyUmVzdWx0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXhjZXBpbmZvLCBwdUFyZ0VyciwgZXhhY3ROYW1lLCBwYXJhbXMpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubmFtZT0gZXhhY3ROYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIFNVQ0NFRURFRCggcmV0ICkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm8uZmxhZ3M9IERJU1BBVENIX1BST1BFUlRZR0VUOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSDtbmZvcm1hdGlvbiBhYm91dCB0aGlzIG1lbWJlciAKICAgICAgICAgICAgICAgICAgICBpZiggcmV0ID09IERJU1BfRV9NRU1CRVJOT1RGT1VORCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoZSBuYW1lIGFzIG5vdCBleGlzdGluZwogICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgcmVtb3ZlIHRoZSBNZW1iZXJJbmZvCiAgICAgICAgICAgICAgICAgICAgICAgIG1fYmFkTmFtZU1hcFtpbmZvLm5hbWVdPSBzYWxfRmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIG1faWRUb01lbWJlckluZm9NYXAuZXJhc2UoIGl0X01lbWJlckluZm8pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gLy8gaWYoICEgaW5mby5mbGFncyApCiAgICAgICAgICAgICAgICBlbHNlIC8vIElkVG9NZW1iZXJJbmZvTWFwIGNvbnRhaW5zIGEgTWVtYmVySW5mbwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmKCB3RmxhZ3MgJiBESVNQQVRDSF9NRVRIT0QgJiYgaW5mby5mbGFncyA9PSBESVNQQVRDSF9NRVRIT0QpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0RGlzcHBhcmFtc0FyZ3MoZGlzcGlkTWVtYmVyLCB3RmxhZ3MsIHBkaXNwcGFyYW1zLCBwYXJhbXMgKTsKCQkJCQkJcmV0PSBkb0ludm9rZSggcGRpc3BwYXJhbXMsIHB2YXJSZXN1bHQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXhjZXBpbmZvLCBwdUFyZ0VyciwgaW5mby5uYW1lLCBwYXJhbXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKCAod0ZsYWdzICYgRElTUEFUQ0hfUFJPUEVSVFlQVVQgfHwgd0ZsYWdzICYgRElTUEFUQ0hfUFJPUEVSVFlQVVRSRUYgKSAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmZsYWdzICYgRElTUEFUQ0hfUFJPUEVSVFlQVVQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0RGlzcHBhcmFtc0FyZ3MoZGlzcGlkTWVtYmVyLCB3RmxhZ3MsIHBkaXNwcGFyYW1zLCBwYXJhbXMgKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0PSBkb1NldFByb3BlcnR5KCBwZGlzcHBhcmFtcywgcHZhclJlc3VsdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGV4Y2VwaW5mbywgcHVBcmdFcnIsIGluZm8ubmFtZSwgcGFyYW1zKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiggKHdGbGFncyAmIERJU1BBVENIX1BST1BFUlRZR0VUKSAmJiAoIGluZm8uZmxhZ3MgJiBESVNQQVRDSF9QUk9QRVJUWUdFVCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXQ9IGRvR2V0UHJvcGVydHkoIHBkaXNwcGFyYW1zLCBwdmFyUmVzdWx0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXhjZXBpbmZvLCBpbmZvLm5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXQ9IERJU1BfRV9NRU1CRVJOT1RGT1VORDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0vLwkJaWYoIGl0X01lbWJlckluZm8gIT0gbV9pZFRvTWVtYmVySW5mb01hcC5lbmQoKSApCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldD0gRElTUF9FX01FTUJFUk5PVEZPVU5EOwogICAgICAgIH0KICAgIH0KICAgIGNhdGNoKEJyaWRnZVJ1bnRpbWVFcnJvciYgZSkKICAgIHsKICAgICAgICB3cml0ZUV4Y2VwaW5mbyhwZXhjZXBpbmZvLCBlLm1lc3NhZ2UpOwogICAgICAgIHJldCA9IERJU1BfRV9FWENFUFRJT047CiAgICB9CiAgICBjYXRjaChFeGNlcHRpb24mIGUpCiAgICB7CiAgICAgICAgT1VTdHJpbmcgbWVzc2FnZT0gT1VTVFIoIlVub09iamVjdFdyYXBwZXJSZW1vdGVPcHQ6Okludm9rZSA6IFxuIikgKwogICAgICAgICAgICBlLk1lc3NhZ2U7CiAgICAgICAgICAgIHdyaXRlRXhjZXBpbmZvKHBleGNlcGluZm8sIG1lc3NhZ2UpOwogICAgICAgICAgICByZXQgPSBESVNQX0VfRVhDRVBUSU9OOwogICAgfQogICAgY2F0Y2goLi4uKQogICAgewogICAgICAgIE9VU3RyaW5nIG1lc3NhZ2U9IE9VU1RSKCJVbm9PYmplY3RXcmFwcGVyUmVtb3RlT3B0OjpJbnZva2UgOiBcbiIgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIik7CiAgICAgICAgd3JpdGVFeGNlcGluZm8ocGV4Y2VwaW5mbywgbWVzc2FnZSk7CiAgICAgICAgcmV0ID0gRElTUF9FX0VYQ0VQVElPTjsKICAgIH0KICAgIAogICAgcmV0dXJuIHJldDsKfQoKSFJFU1VMVAlVbm9PYmplY3RXcmFwcGVyUmVtb3RlT3B0OjptZXRob2RJbnZva2UoIERJU1BJRCAvKmRpc3BpZE1lbWJlciovLCBESVNQUEFSQU1TICogLypwZGlzcHBhcmFtcyovLCBWQVJJQU5UICogLypwdmFyUmVzdWx0Ki8sIAoJCQkJCQkJICBFWENFUElORk8gKiAvKnBleGNlcGluZm8qLywgdW5zaWduZWQgaW50ICogLypwdUFyZ0VyciovLCBTZXF1ZW5jZTxBbnk+IHBhcmFtcykKewoJcmV0dXJuIFNfT0s7Cn0KCgovLyBUaGUgcmV0dXJuZWQgSFJFU1VMVCBpcyBvbmx5IGFwcHJvcHJpYXRlIGZvciBJRGlzcGF0Y2g6Okludm9rZQpzdGF0aWMgSFJFU1VMVCBtYXBDYW5ub3RDb252ZXJ0RXhjZXB0aW9uKCBDYW5ub3RDb252ZXJ0RXhjZXB0aW9uIGUsIHVuc2lnbmVkIGludCAqIHB1QXJnRXJyKQp7CglIUkVTVUxUIHJldDsKCXNhbF9Cb29sIGJXcml0ZUluZGV4PSBzYWxfVHJ1ZTsKCglzd2l0Y2ggKCBlLlJlYXNvbikKCXsKCQljYXNlIEZhaWxSZWFzb246Ok9VVF9PRl9SQU5HRToKCQkJcmV0ID0gRElTUF9FX09WRVJGTE9XOwoJCQlicmVhazsKCQljYXNlIEZhaWxSZWFzb246OklTX05PVF9OVU1CRVI6CgkJCXJldCA9IERJU1BfRV9UWVBFTUlTTUFUQ0g7CgkJCWJyZWFrOwoJCWNhc2UgRmFpbFJlYXNvbjo6SVNfTk9UX0VOVU06CgkJCXJldCA9IERJU1BfRV9UWVBFTUlTTUFUQ0g7CgkJCWJyZWFrOwoJCWNhc2UgRmFpbFJlYXNvbjo6SVNfTk9UX0JPT0w6CgkJCXJldCA9IERJU1BfRV9UWVBFTUlTTUFUQ0g7CgkJCWJyZWFrOwoJCWNhc2UgRmFpbFJlYXNvbjo6Tk9fU1VDSF9JTlRFUkZBQ0U6CgkJCXJldCA9IERJU1BfRV9UWVBFTUlTTUFUQ0g7CgkJCWJyZWFrOwoJCWNhc2UgRmFpbFJlYXNvbjo6U09VUkNFX0lTX05PX0RFUklWRURfVFlQRToKCQkJcmV0ID0gRElTUF9FX1RZUEVNSVNNQVRDSDsKCQkJYnJlYWs7CgkJY2FzZSBGYWlsUmVhc29uOjpUWVBFX05PVF9TVVBQT1JURUQ6CgkJCXJldCA9IERJU1BfRV9UWVBFTUlTTUFUQ0g7CgkJCWJyZWFrOwoJCWNhc2UgRmFpbFJlYXNvbjo6SU5WQUxJRDoKCQkJcmV0ID0gRElTUF9FX1RZUEVNSVNNQVRDSDsKCQkJYnJlYWs7CgkJY2FzZSBGYWlsUmVhc29uOjpOT19ERUZBVUxUX0FWQUlMQUJMRToKCQkJcmV0ID0gRElTUF9FX0JBRFBBUkFNQ09VTlQ7CgkJCWJyZWFrOwoJCWNhc2UgRmFpbFJlYXNvbjo6VU5LTk9XTjoKCQkJcmV0ID0gRV9VTkVYUEVDVEVEOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlyZXQgPSBFX1VORVhQRUNURUQ7CgkJCWJXcml0ZUluZGV4PSBzYWxfRmFsc2U7CgkJCWJyZWFrOwoJfQoKCWlmKCBiV3JpdGVJbmRleCAmJiAgcHVBcmdFcnIgIT0gTlVMTCkKCQkqcHVBcmdFcnIgPSBlLkFyZ3VtZW50SW5kZXg7CglyZXR1cm4gcmV0Owp9CgovLyBUaGUgZnVuY3Rpb24gbWFwcyB0aGUgVHlwZUNsYXNzIG9mIHRoZSBhbnkgdG8gVkFSVFlQRTogSWYgCi8vIHRoZSBBbnkgY29udGFpbnMgU1RSVUNUIG9yIElOVEVSRkFDRSB0aGVuIHRoZSByZXR1cm4gdmFsdWUKLy8gaXMgVlRfRElTUEFUQ0guIFRoZSBmdW5jdGlvbiBpcyB1c2VkIGZyb20gbzJ1X2NyZWF0ZVVub09iamVjdFdyYXBwZXIKLy8gYW5kIHRoZSByZXN1bHQgaXMgcHV0IGludG8gdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSB1bm8gLSB3cmFwcGVyCi8vIG9iamVjdC4gSWYgYSBjbGllbnQgYXNrcyB0aGUgb2JqZWN0IGZvciBESVNQSURfVkFMVUUgYW5kIHRoaXMKLy8gZnVudGlvbiByZXR1cm5lZCBWVF9ESVNQQVRDSCB0aGVuIHRoZSBJRGlzcGF0Y2ggb2YgdGhlIHNhbWUgCi8vIG9iamVjdCBpcyBiZWluZyByZXR1cm5lZC4KLy8gU2VlIEludGVyZmFjZU9sZVdyYXBwZXJfSW1wbDo6SW52b2tlLCBJbnRlcmZhY2VPbGVXcmFwcGVyX0ltcGw6Om1fZGVmYXVsdFZhbHVlVHlwZQpjb25zdCBWQVJUWVBFIGdldFZhclR5cGUoIGNvbnN0IEFueSYgdmFsdWUpCnsKCVZBUlRZUEUgcmV0PSBWVF9FTVBUWTsKCglzd2l0Y2ggKCB2YWx1ZS5nZXRWYWx1ZVR5cGVDbGFzcygpKQoJewoJY2FzZSBUeXBlQ2xhc3NfU1RSVUNUOiByZXQ9IFZUX0RJU1BBVENIOyBicmVhazsKCWNhc2UgVHlwZUNsYXNzX0lOVEVSRkFDRTogcmV0PSBWVF9ESVNQQVRDSDsgYnJlYWs7CglkZWZhdWx0OiBicmVhazsKCX0KCXJldHVybiByZXQ7Cn0KCgoKCn0gLy8gZW5kIG5hbWVzcGFjZQo=