LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfc3Z4Lmh4eCIKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vCi8vIEdsb2JhbCBoZWFkZXIKLy8KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNpbmNsdWRlIDxsaW1pdHMuaD4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGRlcXVlPgojaW5jbHVkZSA8dm9zL211dGV4Lmh4eD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci91bm8vQW55Lmh4eD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci91bm8vUmVmZXJlbmNlLmh4eD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvd2Vha3JlZi5oeHg+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvYXd0L1BvaW50LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9hd3QvUmVjdGFuZ2xlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9sYW5nL0Rpc3Bvc2VkRXhjZXB0aW9uLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9hY2Nlc3NpYmlsaXR5L0FjY2Vzc2libGVFdmVudElkLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9hY2Nlc3NpYmlsaXR5L1hBY2Nlc3NpYmxlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9hY2Nlc3NpYmlsaXR5L1hBY2Nlc3NpYmxlQ29udGV4dC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvYWNjZXNzaWJpbGl0eS9YQWNjZXNzaWJsZUNvbXBvbmVudC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvYWNjZXNzaWJpbGl0eS9BY2Nlc3NpYmxlU3RhdGVUeXBlLmhwcD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvYWNjZXNzaWJsZWV2ZW50bm90aWZpZXIuaHh4PgojaW5jbHVkZSA8dW5vdG9vbHMvYWNjZXNzaWJsZXN0YXRlc2V0aGVscGVyLmh4eD4KI2luY2x1ZGUgPHZjbC91bm9oZWxwLmh4eD4KI2luY2x1ZGUgPHZjbC9zdmFwcC5oeHg+Ci8vYWRkIFRFWFRfU0VMRUNUSU9OX0NIQU5HRUQgZXZlbnQKI2lmbmRlZiBfVEVYVERBVEFfSFhYCiNpbmNsdWRlIDxzdnRvb2xzL3RleHRkYXRhLmh4eD4KI2VuZGlmCgojaW5jbHVkZSA8c2Z4Mi92aWV3ZnJtLmh4eD4KI2luY2x1ZGUgPHNmeDIvdmlld3NoLmh4eD4KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8KLy8gUHJvamVjdC1sb2NhbCBoZWFkZXIKLy8KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KI2luY2x1ZGUgIkFjY2Vzc2libGVUZXh0RXZlbnRRdWV1ZS5oeHgiCiNpbmNsdWRlIDxzdngvQWNjZXNzaWJsZVRleHRIZWxwZXIuaHh4PgojaW5jbHVkZSA8c3Z4L3Vub3NoYXBlLmh4eD4KI2luY2x1ZGUgImVkaXRlbmcvdW5vbGluZ3UuaHh4IgojaW5jbHVkZSA8ZWRpdGVuZy91bm90ZXh0Lmh4eD4KCiNpbmNsdWRlICJlZGl0ZW5nL3Vub2VkaGxwLmh4eCIKI2luY2x1ZGUgImVkaXRlbmcvdW5vcHJhY2MuaHh4IgojaW5jbHVkZSAiZWRpdGVuZy9BY2Nlc3NpYmxlUGFyYU1hbmFnZXIuaHh4IgojaW5jbHVkZSAiZWRpdGVuZy9BY2Nlc3NpYmxlRWRpdGFibGVUZXh0UGFyYS5oeHgiCiNpbmNsdWRlIDxzdngvc3ZkbW9kZWwuaHh4PgojaW5jbHVkZSA8c3Z4L3N2ZHBudHYuaHh4PgojaW5jbHVkZSAiLi4vdGFibGUvY2VsbC5oeHgiCiNpbmNsdWRlICIuLi90YWJsZS9hY2Nlc3NpYmxlY2VsbC5oeHgiCiNpbmNsdWRlIDxlZGl0ZW5nL2VkaXRkYXRhLmh4eD4KI2luY2x1ZGUgPGVkaXRlbmcvZWRpdGVuZy5oeHg+CiNpbmNsdWRlIDxlZGl0ZW5nL2VkaXR2aWV3Lmh4eD4KCnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6YWNjZXNzaWJpbGl0eTsKCm5hbWVzcGFjZSBhY2Nlc3NpYmlsaXR5CnsKCVdpbmRvdyogR2V0Q3VycmVudEVkaXRvclduZCgpCgl7CgkJV2luZG93KiBwV2luID0gTlVMTDsKCQlTZnhWaWV3RnJhbWUqIHBGcmFtZSA9IFNmeFZpZXdGcmFtZTo6Q3VycmVudCgpOwoJCWlmIChwRnJhbWUpCgkJewoJCQljb25zdCBTZnhWaWV3U2hlbGwgKiBwVmlld1NoZWxsID0gcEZyYW1lLT5HZXRWaWV3U2hlbGwoKTsKCQkJaWYocFZpZXdTaGVsbCkKCQkJewoJCQkJcFdpbiA9IHBWaWV3U2hlbGwtPkdldFdpbmRvdygpOwoJCQl9CgkJfQoJCXJldHVybiBwV2luOwoJfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8KLy8gQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCBkZWNsYXJhdGlvbgovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIERCR19OQU1FKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsICkKCiAgICB0ZW1wbGF0ZSA8IHR5cGVuYW1lIGZpcnN0X3R5cGUsIHR5cGVuYW1lIHNlY29uZF90eXBlID4KCSAgICA6OnN0ZDo6cGFpcjwgZmlyc3RfdHlwZSwgc2Vjb25kX3R5cGUgPiBtYWtlU29ydGVkUGFpciggZmlyc3RfdHlwZSAJZmlyc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZF90eXBlIAlzZWNvbmQJKQogICAgewogICAgICAgIGlmKCBmaXJzdCA+IHNlY29uZCApCiAgICAgICAgICAgIHJldHVybiA6OnN0ZDo6bWFrZV9wYWlyKCBzZWNvbmQsIGZpcnN0ICk7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gOjpzdGQ6Om1ha2VfcGFpciggZmlyc3QsIHNlY29uZCApOwogICAgfQoKICAgIGNsYXNzIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwgOiBwdWJsaWMgU2Z4TGlzdGVuZXIKICAgIHsKCiAgICBwdWJsaWM6CiAgICAgICAgdHlwZWRlZiA6OnN0ZDo6dmVjdG9yPCBzYWxfSW50MTYgPiBWZWN0b3JPZlN0YXRlczsKCiAgICAgICAgLy8gcmVjZWl2ZSBwb2ludGVyIHRvIG91ciBmcm9udGVuZCBjbGFzcyBhbmQgdmlldyB3aW5kb3cKICAgICAgICBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsKCk7CiAgICAgICAgfkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwoKTsKCiAgICAgICAgLy8gWEFjY2Vzc2libGVDb250ZXh0IGNoaWxkIGhhbmRsaW5nIG1ldGhvZHMKICAgICAgICBzYWxfSW50MzIgU0FMX0NBTEwgZ2V0QWNjZXNzaWJsZUNoaWxkQ291bnQoKSBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpOwogICAgICAgIHVubzo6UmVmZXJlbmNlPCBYQWNjZXNzaWJsZSA+IFNBTF9DQUxMIGdldEFjY2Vzc2libGVDaGlsZCggc2FsX0ludDMyIGkgKSBTQUxfVEhST1coKGxhbmc6OkluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24sIHVubzo6UnVudGltZUV4Y2VwdGlvbikpOwoKICAgICAgICAvLyBYQWNjZXNzaWJsZUV2ZW50QnJvYWRjYXN0ZXIgY2hpbGQgcmVsYXRlZCBtZXRob2RzCiAgICAgICAgdm9pZCBTQUxfQ0FMTCBhZGRFdmVudExpc3RlbmVyKCBjb25zdCB1bm86OlJlZmVyZW5jZTwgWEFjY2Vzc2libGVFdmVudExpc3RlbmVyID4mIHhMaXN0ZW5lciApIFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSk7CiAgICAgICAgdm9pZCBTQUxfQ0FMTCByZW1vdmVFdmVudExpc3RlbmVyKCBjb25zdCB1bm86OlJlZmVyZW5jZTwgWEFjY2Vzc2libGVFdmVudExpc3RlbmVyID4mIHhMaXN0ZW5lciApIFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSk7CgogICAgICAgIC8vIFhBY2Nlc3NpYmxlQ29tcG9uZW50IGNoaWxkIHJlbGF0ZWQgbWV0aG9kcwogICAgICAgIHVubzo6UmVmZXJlbmNlPCBYQWNjZXNzaWJsZSA+IFNBTF9DQUxMIGdldEFjY2Vzc2libGVBdFBvaW50KCBjb25zdCBhd3Q6OlBvaW50JiBhUG9pbnQgKSBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpOwoKICAgICAgICBTdnhFZGl0U291cmNlQWRhcHRlciYgR2V0RWRpdFNvdXJjZSgpIGNvbnN0IFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSk7CiAgICAgICAgdm9pZCBTZXRFZGl0U291cmNlKCA6OnN0ZDo6YXV0b19wdHI8IFN2eEVkaXRTb3VyY2UgPiBwRWRpdFNvdXJjZSApIFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSk7CgogICAgICAgIHZvaWQgU2V0RXZlbnRTb3VyY2UoIGNvbnN0IHVubzo6UmVmZXJlbmNlPCBYQWNjZXNzaWJsZSA+JiBySW50ZXJmYWNlICkKICAgICAgICB7CiAgICAgICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CiAgICAgICAgICAgIG14RnJvbnRFbmQgPSBySW50ZXJmYWNlOwogICAgICAgIH0KICAgICAgICB1bm86OlJlZmVyZW5jZTwgWEFjY2Vzc2libGUgPiBHZXRFdmVudFNvdXJjZSgpIGNvbnN0CiAgICAgICAgewogICAgICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwogICAgICAgICAgICByZXR1cm4gbXhGcm9udEVuZDsKICAgICAgICB9CgogICAgICAgIHZvaWQgU2V0T2Zmc2V0KCBjb25zdCBQb2ludCYgKTsKICAgICAgICBQb2ludCBHZXRPZmZzZXQoKSBjb25zdAogICAgICAgIHsKICAgICAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKICAgICAgICAgICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBtYU11dGV4ICk7IFBvaW50IGFQb2ludCggbWFPZmZzZXQgKTsKICAgICAgICAgICAgcmV0dXJuIGFQb2ludDsKICAgICAgICB9CgogICAgICAgIHZvaWQgU2V0U3RhcnRJbmRleCggc2FsX0ludDMyIG5PZmZzZXQgKTsKICAgICAgICBzYWxfSW50MzIgR2V0U3RhcnRJbmRleCgpIGNvbnN0CiAgICAgICAgewogICAgICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoJCQkvLyBTdHJpY3RseSBjb3JyZWN0IG9ubHkgd2l0aCBsb2NrZWQgc29sYXIgbXV0ZXgsIC8vIGJ1dAoJCQkvLyBoZXJlIHdlIHJlbHkgb24gdGhlIGZhY3QgdGhhdCBzYWxfSW50MzIgYWNjZXNzIGlzCgkJCS8vIGF0b21pYwogICAgICAgICAgICByZXR1cm4gbW5TdGFydEluZGV4OwogICAgICAgIH0KCiAgICAgICAgdm9pZCBTZXRBZGRpdGlvbmFsQ2hpbGRTdGF0ZXMoIGNvbnN0IFZlY3Rvck9mU3RhdGVzJiByQ2hpbGRTdGF0ZXMgKTsKICAgICAgICBjb25zdCBWZWN0b3JPZlN0YXRlcyYgR2V0QWRkaXRpb25hbENoaWxkU3RhdGVzKCkgY29uc3Q7CgogICAgICAgIHNhbF9Cb29sIElzU2VsZWN0ZWQoKSBjb25zdDsKCiAgICAgICAgdm9pZCBEaXNwb3NlKCk7CgogICAgICAgIC8vIGRvIE5PVCBob2xkIG9iamVjdCBtdXRleCB3aGVuIGNhbGxpbmcgdGhpcyEgRGFuZ2VyIG9mIGRlYWRsb2NrCiAgICAgICAgdm9pZCBGaXJlRXZlbnQoIGNvbnN0IHNhbF9JbnQxNiBuRXZlbnRJZCwgY29uc3QgdW5vOjpBbnkmIHJOZXdWYWx1ZSA9IHVubzo6QW55KCksIGNvbnN0IHVubzo6QW55JiByT2xkVmFsdWUgPSB1bm86OkFueSgpICkgY29uc3Q7CiAgICAgICAgdm9pZCBGaXJlRXZlbnQoIGNvbnN0IEFjY2Vzc2libGVFdmVudE9iamVjdCYgckV2ZW50ICkgY29uc3Q7CgogICAgICAgIHZvaWQgU2V0Rm9jdXMoIHNhbF9Cb29sIGJIYXZlRm9jdXMgKSBTQUxfVEhST1coKDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikpOwogICAgICAgIHNhbF9Cb29sIEhhdmVGb2N1cygpIFNBTF9USFJPVygoOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uKSk7CiAgICAgICAgdm9pZCBTZXRDaGlsZEZvY3VzKCBzYWxfSW50MzIgbkNoaWxkLCBzYWxfQm9vbCBiSGF2ZUZvY3VzICkgU0FMX1RIUk9XKCg6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJ1bnRpbWVFeGNlcHRpb24pKTsKICAgICAgICB2b2lkIFNldFNoYXBlRm9jdXMoIHNhbF9Cb29sIGJIYXZlRm9jdXMgKSBTQUxfVEhST1coKDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikpOwogICAgICAgIHZvaWQgQ2hhbmdlQ2hpbGRGb2N1cyggc2FsX0ludDMyIG5OZXdDaGlsZCApIFNBTF9USFJPVygoOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uKSk7CgojaWZkZWYgREJHX1VUSUwKICAgICAgICB2b2lkIENoZWNrSW52YXJpYW50cygpIGNvbnN0OwojZW5kaWYKCiAgICAgICAgLy8gY2hlY2tzIGFsbCBjaGlsZHJlbiBmb3IgdmlzaWJpbGl0eSwgdGhyb3dzIGF3YXkgaW52aXNpYmxlIG9uZXMKICAgICAgICB2b2lkIFVwZGF0ZVZpc2libGVDaGlsZHJlbiggYm9vbCBiQnJvYWRjYXN0RXZlbnRzPXRydWUgKTsKCiAgICAgICAgLy8gY2hlY2sgYWxsIGNoaWxkcmVuIGZvciBjaGFuZ2VzIGluIHBvc2l07W9uIGFuZCBzaXplCiAgICAgICAgdm9pZCBVcGRhdGVCb3VuZFJlY3QoKTsKCiAgICAgICAgLy8gY2FsbHMgU2V0U2VsZWN0aW9uIG9uIHRoZSBmb3J3YXJkZXIgYW5kIHVwZGF0ZXMgbWFMYXN0U2VsZWN0aW9uCiAgICAgICAgLy8gY2FjaGUuCiAgICAgICAgdm9pZCBVcGRhdGVTZWxlY3Rpb24oKTsKCiAgICBwcml2YXRlOgoKICAgICAgICAvLyBQcm9jZXNzIGV2ZW50IHF1ZXVlCiAgICAgICAgdm9pZCBQcm9jZXNzUXVldWUoKTsKCiAgICAgICAgLy8gc3ludGFjdGljIHN1Z2FyIGZvciBGaXJlRXZlbnQKICAgICAgICB2b2lkIEdvdFByb3BlcnR5RXZlbnQoIGNvbnN0IHVubzo6QW55JiByTmV3VmFsdWUsIGNvbnN0IHNhbF9JbnQxNiBuRXZlbnRJZCApIGNvbnN0IHsgRmlyZUV2ZW50KCBuRXZlbnRJZCwgck5ld1ZhbHVlICk7IH0KICAgICAgICB2b2lkIExvc3RQcm9wZXJ0eUV2ZW50KCBjb25zdCB1bm86OkFueSYgck9sZFZhbHVlLCBjb25zdCBzYWxfSW50MTYgbkV2ZW50SWQgKSBjb25zdCB7IEZpcmVFdmVudCggbkV2ZW50SWQsIHVubzo6QW55KCksIHJPbGRWYWx1ZSApOyB9CgogICAgICAgIC8vIHNodXRkb3duIHVzYWdlIG9mIGN1cnJlbnQgZWRpdCBzb3VyY2Ugb24gbXlzZWxmIGFuZCB0aGUgY2hpbGRyZW4uCiAgICAgICAgdm9pZCBTaHV0ZG93bkVkaXRTb3VyY2UoKSBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpOwoKICAgICAgICB2b2lkIFBhcmFncmFwaHNNb3ZlZCggc2FsX0ludDMyIG5GaXJzdCwgc2FsX0ludDMyIG5NaWRkbGUsIHNhbF9JbnQzMiBuTGFzdCApOwoKICAgICAgICB2aXJ0dWFsIHZvaWQgTm90aWZ5KCBTZnhCcm9hZGNhc3RlciYgckJDLCBjb25zdCBTZnhIaW50JiBySGludCApOwoKICAgICAgICBpbnQgZ2V0Tm90aWZpZXJDbGllbnRJZCgpIGNvbnN0IHsgcmV0dXJuIG1uTm90aWZpZXJDbGllbnRJZDsgfQoKICAgICAgICAvLyBsb2NrIHNvbGFyIG11dGV4IGJlZm9yZQogICAgICAgIFN2eFRleHRGb3J3YXJkZXImIEdldFRleHRGb3J3YXJkZXIoKSBjb25zdCBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpOwogICAgICAgIC8vIGxvY2sgc29sYXIgbXV0ZXggYmVmb3JlCiAgICAgICAgU3Z4Vmlld0ZvcndhcmRlciYgR2V0Vmlld0ZvcndhcmRlcigpIGNvbnN0IFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSk7CiAgICAgICAgLy8gbG9jayBzb2xhciBtdXRleCBiZWZvcmUKICAgICAgICBTdnhFZGl0Vmlld0ZvcndhcmRlciYgR2V0RWRpdFZpZXdGb3J3YXJkZXIoIHNhbF9Cb29sIGJDcmVhdGUgPSBzYWxfRmFsc2UgKSBjb25zdCBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpOwoKICAgICAgICAvLyBhcmUgd2UgaW4gZWRpdCBtb2RlPwogICAgICAgIHNhbF9Cb29sIElzQWN0aXZlKCkgY29uc3QgU0FMX1RIUk9XKCh1bm86OlJ1bnRpbWVFeGNlcHRpb24pKTsKCiAgICAgICAgLy8gb3VyIGZyb250ZW5kIGNsYXNzICh0aGUgb25lIGltcGxlbWVudGluZyB0aGUgYWN0dWFsCiAgICAgICAgLy8gaW50ZXJmYWNlKS4gVGhhdCdzIG5vdCBuZWNlc3NhcmlseSB0aGUgb25lIGNvbnRhaW5pbmcgdGhlIGltcGwKICAgICAgICAvLyBwb2ludGVyIQogICAgICAgIHVubzo6UmVmZXJlbmNlPCBYQWNjZXNzaWJsZSA+IG14RnJvbnRFbmQ7CgogICAgICAgIC8vIGEgd3JhcHBlciBmb3IgdGhlIHRleHQgZm9yd2FyZGVycyAoZ3VhcmRlZCBieSBzb2xhciBtdXRleCkKICAgICAgICBtdXRhYmxlIFN2eEVkaXRTb3VyY2VBZGFwdGVyIG1hRWRpdFNvdXJjZTsKCiAgICAgICAgLy8gc3RvcmUgbGFzdCBzZWxlY3Rpb24gKHRvIGNvcnJlY3RseSByZXBvcnQgc2VsZWN0aW9uIGNoYW5nZXMsIGd1YXJkZWQgYnkgc29sYXIgbXV0ZXgpCiAgICAgICAgRVNlbGVjdGlvbiBtYUxhc3RTZWxlY3Rpb247CgogICAgICAgIC8vIGNhY2hlIHJhbmdlIG9mIHZpc2libGUgY2hpbGRyZW4gKGd1YXJkZWQgYnkgc29sYXIgbXV0ZXgpCiAgICAgICAgc2FsX0ludDMyIG1uRmlyc3RWaXNpYmxlQ2hpbGQ7CiAgICAgICAgc2FsX0ludDMyIG1uTGFzdFZpc2libGVDaGlsZDsKCiAgICAgICAgLy8gb2Zmc2V0IHRvIGFkZCB0byBhbGwgb3VyIGNoaWxkcmVuICh1bmd1YXJkZWQsIHJlbHlpbmcgb24KICAgICAgICAvLyB0aGUgZmFjdCB0aGF0IHNhbF9JbnQzMiBhY2Nlc3MgaXMgYXRvbWljKQogICAgICAgIHNhbF9JbnQzMiBtblN0YXJ0SW5kZXg7CgogICAgICAgIC8vIHRoZSBvYmplY3QgaGFuZGxpbmcgb3VyIGNoaWxkcmVuIChndWFyZGVkIGJ5IHNvbGFyIG11dGV4KQogICAgICAgIDo6YWNjZXNzaWJpbGl0eTo6QWNjZXNzaWJsZVBhcmFNYW5hZ2VyIG1hUGFyYU1hbmFnZXI7CgogICAgICAgIC8vIG51bWJlciBvZiBub3QteWV0LWNsb3NlZCBldmVudCBmcmFtZXMgKEJFR0lOL0VORCBzZXF1ZW5jZXMpIChndWFyZGVkIGJ5IHNvbGFyIG11dGV4KQogICAgICAgIHNhbF9JbnQzMiBtYUV2ZW50T3BlbkZyYW1lczsKCiAgICAgICAgLy8gUXVldWVkIGV2ZW50cyBmcm9tIE5vdGlmeSgpIChndWFyZGVkIGJ5IHNvbGFyIG11dGV4KQogICAgICAgIEFjY2Vzc2libGVUZXh0RXZlbnRRdWV1ZSBtYUV2ZW50UXVldWU7CgogICAgICAgIC8vIHNwaW4gbG9jayB0byBwcmV2ZW50IG5vdGlmeSBpbiBub3RpZnkgKGd1YXJkZWQgYnkgc29sYXIgbXV0ZXgpCiAgICAgICAgc2FsX0Jvb2wgbWJJbk5vdGlmeTsKCiAgICAgICAgLy8gd2hldGhlciB0aGUgb2JqZWN0IG9yIGl0J3MgY2hpbGRyZW4gaGFzIHRoZSBmb2N1cyBzZXQgKGd1YXJkZWQgYnkgc29sYXIgbXV0ZXgpCiAgICAgICAgc2FsX0Jvb2wgbWJHcm91cEhhc0ZvY3VzOwoKICAgICAgICAvLyB3aGV0aGVyIHdlICh0aGlzIG9iamVjdCkgaGFzIHRoZSBmb2N1cyBzZXQgKGd1YXJkZWQgYnkgc29sYXIgbXV0ZXgpCiAgICAgICAgc2FsX0Jvb2wgbWJUaGlzSGFzRm9jdXM7CgogICAgICAgIG11dGFibGUgOjpvc2w6Ok11dGV4IG1hTXV0ZXg7CgogICAgICAgIC8vLyBvdXIgY3VycmVudCBvZmZzZXQgdG8gdGhlIGNvbnRhaW5pbmcgc2hhcGUvY2VsbCAoZ3VhcmRlZCBieSBtYU11dGV4KQogICAgICAgIFBvaW50IG1hT2Zmc2V0OwoKICAgICAgICAvLy8gY2xpZW50IElkIGZyb20gQWNjZXNzaWJsZUV2ZW50Tm90aWZpZXIKICAgICAgICBpbnQgbW5Ob3RpZmllckNsaWVudElkOwogICAgfTsKCgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJLy8KCS8vIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwgaW1wbGVtZW50YXRpb24KCS8vCgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwoKSA6CiAgICAgICAgbXhGcm9udEVuZCggTlVMTCApLAogICAgICAgIG1hTGFzdFNlbGVjdGlvbiggRUVfUEFSQV9OT1RfRk9VTkQsRUVfUEFSQV9OT1RfRk9VTkQsRUVfUEFSQV9OT1RfRk9VTkQsRUVfUEFSQV9OT1RfRk9VTkQgKSwKICAgICAgICBtbkZpcnN0VmlzaWJsZUNoaWxkKCAtMSApLAogICAgICAgIG1uTGFzdFZpc2libGVDaGlsZCggLTIgKSwKICAgICAgICBtblN0YXJ0SW5kZXgoIDAgKSwKICAgICAgICBtYUV2ZW50T3BlbkZyYW1lcyggMCApLAogICAgICAgIG1iSW5Ob3RpZnkoIHNhbF9GYWxzZSApLAogICAgICAgIG1iR3JvdXBIYXNGb2N1cyggc2FsX0ZhbHNlICksCiAgICAgICAgbWJUaGlzSGFzRm9jdXMoIHNhbF9GYWxzZSApLAogICAgICAgIG1hT2Zmc2V0KDAsMCksCiAgICAgICAgLy8gd2VsbCwgdGhhdCdzIHN0cmljdGx5IGV4Y2VwdGlvbiBzYWZlLCB0aG91Z2ggbm90IHJlYWxseQogICAgICAgIC8vIHJvYnVzdC4gV2UgcmVseSBvbiB0aGUgZmFjdCB0aGF0IHRoaXMgbWVtYmVyIGlzIGNvbnN0cnVjdGVkCiAgICAgICAgLy8gbGFzdCwgYW5kIHRoYXQgdGhlIGNvbnN0cnVjdG9yIGJvZHkgaXMgZW1wdHksIHRodXMgbm8KICAgICAgICAvLyBjaGFuY2UgZm9yIGV4Y2VwdGlvbnMgb25jZSB0aGUgSWQgaXMgZmV0Y2hlZC4gTmV2ZXJ0aGVsZXNzLAogICAgICAgIC8vIG5vcm1hbGx5IHNob3VsZCBlbXBsb3kgUkFJSSBoZXJlLi4uCiAgICAgICAgbW5Ob3RpZmllckNsaWVudElkKDo6Y29tcGhlbHBlcjo6QWNjZXNzaWJsZUV2ZW50Tm90aWZpZXI6OnJlZ2lzdGVyQ2xpZW50KCkpCiAgICB7CiAgICAgICAgREJHX0NUT1IoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiNpZmRlZiBEQkdfVVRJTAogICAgICAgIE9TTF9UUkFDRSggIkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwgcmVjZWl2ZWQgSUQ6ICVkIiwgbW5Ob3RpZmllckNsaWVudElkICk7CiNlbmRpZgogICAgfQoKICAgIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6On5BY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsKCkKICAgIHsKICAgICAgICBEQkdfRFRPUiggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICA6OnZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIGNhbGwgRGlzcG9zZSBoZXJlLCB0b28sIHNpbmNlIHdlJ3ZlIHNvbWUgcmVzb3VyY2VzIG5vdAogICAgICAgICAgICAvLyBhdXRvbWF0aWNhbGx5IGZyZWVkIG90aGVyd2lzZQogICAgICAgICAgICBEaXNwb3NlKCk7CiAgICAgICAgfQogICAgICAgIGNhdGNoKCBjb25zdCB1bm86OkV4Y2VwdGlvbiYgKSB7fQogICAgfQoKICAgIFN2eFRleHRGb3J3YXJkZXImIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OkdldFRleHRGb3J3YXJkZXIoKSBjb25zdCBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgaWYoICFtYUVkaXRTb3VyY2UuSXNWYWxpZCgpICkKICAgICAgICAgICAgdGhyb3cgdW5vOjpSdW50aW1lRXhjZXB0aW9uKDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIlVua25vd24gZWRpdCBzb3VyY2UiKSksIG14RnJvbnRFbmQpOwoKICAgICAgICBTdnhUZXh0Rm9yd2FyZGVyKiBwVGV4dEZvcndhcmRlciA9IG1hRWRpdFNvdXJjZS5HZXRUZXh0Rm9yd2FyZGVyKCk7CgogICAgICAgIGlmKCAhcFRleHRGb3J3YXJkZXIgKQogICAgICAgICAgICB0aHJvdyB1bm86OlJ1bnRpbWVFeGNlcHRpb24oOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiVW5hYmxlIHRvIGZldGNoIHRleHQgZm9yd2FyZGVyLCBtb2RlbCBtaWdodCBiZSBkZWFkIikpLCBteEZyb250RW5kKTsKCiAgICAgICAgaWYoIHBUZXh0Rm9yd2FyZGVyLT5Jc1ZhbGlkKCkgKQogICAgICAgICAgICByZXR1cm4gKnBUZXh0Rm9yd2FyZGVyOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdGhyb3cgdW5vOjpSdW50aW1lRXhjZXB0aW9uKDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIlRleHQgZm9yd2FyZGVyIGlzIGludmFsaWQsIG1vZGVsIG1pZ2h0IGJlIGRlYWQiKSksIG14RnJvbnRFbmQpOwogICAgfQoKICAgIFN2eFZpZXdGb3J3YXJkZXImIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OkdldFZpZXdGb3J3YXJkZXIoKSBjb25zdCBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgaWYoICFtYUVkaXRTb3VyY2UuSXNWYWxpZCgpICkKICAgICAgICAgICAgdGhyb3cgdW5vOjpSdW50aW1lRXhjZXB0aW9uKDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIlVua25vd24gZWRpdCBzb3VyY2UiKSksIG14RnJvbnRFbmQpOwoKICAgICAgICBTdnhWaWV3Rm9yd2FyZGVyKiBwVmlld0ZvcndhcmRlciA9IG1hRWRpdFNvdXJjZS5HZXRWaWV3Rm9yd2FyZGVyKCk7CgogICAgICAgIGlmKCAhcFZpZXdGb3J3YXJkZXIgKQogICAgICAgICAgICB0aHJvdyB1bm86OlJ1bnRpbWVFeGNlcHRpb24oOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiVW5hYmxlIHRvIGZldGNoIHZpZXcgZm9yd2FyZGVyLCBtb2RlbCBtaWdodCBiZSBkZWFkIikpLCBteEZyb250RW5kKTsKCiAgICAgICAgaWYoIHBWaWV3Rm9yd2FyZGVyLT5Jc1ZhbGlkKCkgKQogICAgICAgICAgICByZXR1cm4gKnBWaWV3Rm9yd2FyZGVyOwogICAgICAgIGVsc2UKICAgICAgICAgICAgdGhyb3cgdW5vOjpSdW50aW1lRXhjZXB0aW9uKDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIlZpZXcgZm9yd2FyZGVyIGlzIGludmFsaWQsIG1vZGVsIG1pZ2h0IGJlIGRlYWQiKSksIG14RnJvbnRFbmQpOwogICAgfQoKICAgIFN2eEVkaXRWaWV3Rm9yd2FyZGVyJiBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpHZXRFZGl0Vmlld0ZvcndhcmRlciggc2FsX0Jvb2wgYkNyZWF0ZSApIGNvbnN0IFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICBpZiggIW1hRWRpdFNvdXJjZS5Jc1ZhbGlkKCkgKQogICAgICAgICAgICB0aHJvdyB1bm86OlJ1bnRpbWVFeGNlcHRpb24oOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiVW5rbm93biBlZGl0IHNvdXJjZSIpKSwgbXhGcm9udEVuZCk7CgogICAgICAgIFN2eEVkaXRWaWV3Rm9yd2FyZGVyKiBwVmlld0ZvcndhcmRlciA9IG1hRWRpdFNvdXJjZS5HZXRFZGl0Vmlld0ZvcndhcmRlciggYkNyZWF0ZSApOwoKICAgICAgICBpZiggIXBWaWV3Rm9yd2FyZGVyICkKICAgICAgICB7CiAgICAgICAgICAgIGlmKCBiQ3JlYXRlICkKICAgICAgICAgICAgICAgIHRocm93IHVubzo6UnVudGltZUV4Y2VwdGlvbig6OnJ0bDo6T1VTdHJpbmcoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJVbmFibGUgdG8gZmV0Y2ggZWRpdCB2aWV3IGZvcndhcmRlciwgbW9kZWwgbWlnaHQgYmUgZGVhZCIpKSwgbXhGcm9udEVuZCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHRocm93IHVubzo6UnVudGltZUV4Y2VwdGlvbig6OnJ0bDo6T1VTdHJpbmcoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJObyBlZGl0IHZpZXcgZm9yd2FyZGVyLCBvYmplY3Qgbm90IGluIGVkaXQgbW9kZSIpKSwgbXhGcm9udEVuZCk7CiAgICAgICAgfQoKICAgICAgICBpZiggcFZpZXdGb3J3YXJkZXItPklzVmFsaWQoKSApCiAgICAgICAgICAgIHJldHVybiAqcFZpZXdGb3J3YXJkZXI7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYoIGJDcmVhdGUgKQogICAgICAgICAgICAgICAgdGhyb3cgdW5vOjpSdW50aW1lRXhjZXB0aW9uKDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIlZpZXcgZm9yd2FyZGVyIGlzIGludmFsaWQsIG1vZGVsIG1pZ2h0IGJlIGRlYWQiKSksIG14RnJvbnRFbmQpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0aHJvdyB1bm86OlJ1bnRpbWVFeGNlcHRpb24oOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiVmlldyBmb3J3YXJkZXIgaXMgaW52YWxpZCwgb2JqZWN0IG5vdCBpbiBlZGl0IG1vZGUiKSksIG14RnJvbnRFbmQpOwogICAgICAgIH0KICAgIH0KCiAgICBTdnhFZGl0U291cmNlQWRhcHRlciYgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6R2V0RWRpdFNvdXJjZSgpIGNvbnN0IFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICBpZiggbWFFZGl0U291cmNlLklzVmFsaWQoKSApCiAgICAgICAgICAgIHJldHVybiBtYUVkaXRTb3VyY2U7CiAgICAgICAgZWxzZQogICAgICAgICAgICB0aHJvdyB1bm86OlJ1bnRpbWVFeGNlcHRpb24oOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6R2V0RWRpdFNvdXJjZTogbm8gZWRpdCBzb3VyY2UiKSksIG14RnJvbnRFbmQgKTsKICAgIH0KCiAgICBzYWxfQm9vbCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpJc1NlbGVjdGVkKCkgY29uc3QKICAgIHsKICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICBzYWxfQm9vbCBiUmV0ID0gc2FsX0ZhbHNlOwoKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIEVTZWxlY3Rpb24gYVNlbGVjdGlvbjsKICAgICAgICAgICAgYlJldCA9IEdldEVkaXRWaWV3Rm9yd2FyZGVyKCkuR2V0U2VsZWN0aW9uKCBhU2VsZWN0aW9uICk7CiAgICAgICAgfQogICAgICAgIGNhdGNoKCBjb25zdCB1bm86OkV4Y2VwdGlvbiYgKSB7fQoKICAgICAgICByZXR1cm4gYlJldDsKICAgIH0KCgkvLyBmdW5jdG9yIGZvciBzZW5kaW5nIGNoaWxkIGV2ZW50cyAobm8gc3RhbmQtYWxvbmUgZnVuY3Rpb24sIHRoZXkgYXJlIG1heWJlIG5vdCBpbmxpbmVkKQogICAgY2xhc3MgQWNjZXNzaWJsZVRleHRIZWxwZXJfT2Zmc2V0Q2hpbGRJbmRleCA6IHB1YmxpYyA6OnN0ZDo6dW5hcnlfZnVuY3Rpb248IDo6YWNjZXNzaWJpbGl0eTo6QWNjZXNzaWJsZUVkaXRhYmxlVGV4dFBhcmEmLCB2b2lkID4KICAgIHsKICAgIHB1YmxpYzoKICAgICAgICBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9PZmZzZXRDaGlsZEluZGV4KCBzYWxfSW50MzIgbkRpZmZlcmVuY2UgKSA6IG1uRGlmZmVyZW5jZShuRGlmZmVyZW5jZSkge30KICAgICAgICB2b2lkIG9wZXJhdG9yKCkoIDo6YWNjZXNzaWJpbGl0eTo6QWNjZXNzaWJsZUVkaXRhYmxlVGV4dFBhcmEmIHJQYXJhICkKICAgICAgICB7CiAgICAgICAgICAgIHJQYXJhLlNldEluZGV4SW5QYXJlbnQoIHJQYXJhLkdldEluZGV4SW5QYXJlbnQoKSArIG1uRGlmZmVyZW5jZSApOwogICAgICAgIH0KCiAgICBwcml2YXRlOgogICAgICAgIGNvbnN0IHNhbF9JbnQzMiBtbkRpZmZlcmVuY2U7CiAgICB9OwoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6U2V0U3RhcnRJbmRleCggc2FsX0ludDMyIG5PZmZzZXQgKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIHNhbF9JbnQzMiBuT2xkT2Zmc2V0KCBtblN0YXJ0SW5kZXggKTsKCiAgICAgICAgbW5TdGFydEluZGV4ID0gbk9mZnNldDsKCiAgICAgICAgaWYoIG5PbGRPZmZzZXQgIT0gbk9mZnNldCApCiAgICAgICAgewogICAgICAgICAgICAvLyB1cGRhdGUgY2hpbGRyZW4KICAgICAgICAgICAgQWNjZXNzaWJsZVRleHRIZWxwZXJfT2Zmc2V0Q2hpbGRJbmRleCBhRnVuY3Rvciggbk9mZnNldCAtIG5PbGRPZmZzZXQgKTsKCiAgICAgICAgICAgIDo6c3RkOjpmb3JfZWFjaCggbWFQYXJhTWFuYWdlci5iZWdpbigpLCBtYVBhcmFNYW5hZ2VyLmVuZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc2libGVQYXJhTWFuYWdlcjo6V2Vha0NoaWxkQWRhcHRlcjwgQWNjZXNzaWJsZVRleHRIZWxwZXJfT2Zmc2V0Q2hpbGRJbmRleCA+IChhRnVuY3RvcikgKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpTZXRBZGRpdGlvbmFsQ2hpbGRTdGF0ZXMoIGNvbnN0IFZlY3Rvck9mU3RhdGVzJiByQ2hpbGRTdGF0ZXMgKQogICAgewogICAgICAgIG1hUGFyYU1hbmFnZXIuU2V0QWRkaXRpb25hbENoaWxkU3RhdGVzKCByQ2hpbGRTdGF0ZXMgKTsKICAgIH0KCiAgICBjb25zdCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpWZWN0b3JPZlN0YXRlcyYgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6R2V0QWRkaXRpb25hbENoaWxkU3RhdGVzKCkgY29uc3QKICAgIHsKICAgICAgICByZXR1cm4gbWFQYXJhTWFuYWdlci5HZXRBZGRpdGlvbmFsQ2hpbGRTdGF0ZXMoKTsKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OlNldENoaWxkRm9jdXMoIHNhbF9JbnQzMiBuQ2hpbGQsIHNhbF9Cb29sIGJIYXZlRm9jdXMgKSBTQUxfVEhST1coKDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgaWYoIGJIYXZlRm9jdXMgKQogICAgICAgIHsKICAgICAgICAgICAgaWYoIG1iVGhpc0hhc0ZvY3VzICkKICAgICAgICAgICAgICAgIFNldFNoYXBlRm9jdXMoIHNhbF9GYWxzZSApOwoKICAgICAgICAgICAgbWFQYXJhTWFuYWdlci5TZXRGb2N1cyggbkNoaWxkICk7CgogICAgICAgICAgICAvLyB3ZSBqdXN0IHJlY2VpdmVkIHRoZSBmb2N1cywgYWxzbyBzZW5kIGNhcmV0IGV2ZW50IHRoZW4KICAgICAgICAgICAgVXBkYXRlU2VsZWN0aW9uKCk7CgogICAgICAgICAgICBEQkdfVFJBQ0UxKCJBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpTZXRDaGlsZEZvY3VzKCk6IFBhcmFncmFwaCAlZCByZWNlaXZlZCBmb2N1cyIsIG5DaGlsZCApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLlNldEZvY3VzKCAtMSApOwoKICAgICAgICAgICAgREJHX1RSQUNFMSgiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6U2V0Q2hpbGRGb2N1cygpOiBQYXJhZ3JhcGggJWQgbG9zdCBmb2N1cyIsIG5DaGlsZCApOwoKICAgICAgICAgICAgaWYoIG1iR3JvdXBIYXNGb2N1cyApCiAgICAgICAgICAgICAgICBTZXRTaGFwZUZvY3VzKCBzYWxfVHJ1ZSApOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OkNoYW5nZUNoaWxkRm9jdXMoIHNhbF9JbnQzMiBuTmV3Q2hpbGQgKSBTQUxfVEhST1coKDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgaWYoIG1iVGhpc0hhc0ZvY3VzICkKICAgICAgICAgICAgU2V0U2hhcGVGb2N1cyggc2FsX0ZhbHNlICk7CgogICAgICAgIG1iR3JvdXBIYXNGb2N1cyA9IHNhbF9UcnVlOwogICAgICAgIG1hUGFyYU1hbmFnZXIuU2V0Rm9jdXMoIG5OZXdDaGlsZCApOwoKICAgICAgICBEQkdfVFJBQ0UxKCJBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpDaGFuZ2VDaGlsZEZvY3VzKCk6IFBhcmFncmFwaCAlZCByZWNlaXZlZCBmb2N1cyIsIG5OZXdDaGlsZCApOwogICAgfQoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6U2V0U2hhcGVGb2N1cyggc2FsX0Jvb2wgYkhhdmVGb2N1cyApIFNBTF9USFJPVygoOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICBzYWxfQm9vbCBiT2xkRm9jdXMoIG1iVGhpc0hhc0ZvY3VzICk7CgogICAgICAgIG1iVGhpc0hhc0ZvY3VzID0gYkhhdmVGb2N1czsKCiAgICAgICAgaWYoIGJPbGRGb2N1cyAhPSBiSGF2ZUZvY3VzICkKICAgICAgICB7CiAgICAgICAgICAgIGlmKCBiSGF2ZUZvY3VzICkKICAgICAgICAgICAgewoJCQkJaWYoIG14RnJvbnRFbmQuaXMoKSApCgkJCQl7CgkJCQkJQWNjZXNzaWJsZUNlbGwqIHBBY2Nlc3NpYmxlQ2VsbCA9IGR5bmFtaWNfY2FzdDwgQWNjZXNzaWJsZUNlbGwqID4gKCBteEZyb250RW5kLmdldCgpICk7CgkJCQkJaWYgKCAhcEFjY2Vzc2libGVDZWxsICkKCQkJCQkJR290UHJvcGVydHlFdmVudCggdW5vOjptYWtlQW55KEFjY2Vzc2libGVTdGF0ZVR5cGU6OkZPQ1VTRUQpLCBBY2Nlc3NpYmxlRXZlbnRJZDo6U1RBVEVfQ0hBTkdFRCApOwoJCQkJCWVsc2UJLy8gdGhlIGZvY3VzIGV2ZW50IG9uIGNlbGwgc2hvdWxkIGJlIGZpcmVkIG9uIHRhYmxlIGRpcmVjdGx5CgkJCQkJewoJCQkJCQlBY2Nlc3NpYmxlVGFibGVTaGFwZSogcEFjY1RhYmxlID0gcEFjY2Vzc2libGVDZWxsLT5HZXRQYXJlbnRUYWJsZSgpOwoJCQkJCQlpZiAocEFjY1RhYmxlKQoJCQkJCQkJcEFjY1RhYmxlLT5TZXRTdGF0ZURpcmVjdGx5KEFjY2Vzc2libGVTdGF0ZVR5cGU6OkZPQ1VTRUQpOwoJCQkJCX0KCQkJCX0KICAgICAgICAgICAgICAgIERCR19UUkFDRSgiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6U2V0U2hhcGVGb2N1cygpOiBQYXJlbnQgb2JqZWN0IHJlY2VpdmVkIGZvY3VzIiApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gVGhlIGZvY3VzIHN0YXRlIHNob3VsZCBiZSByZXNldCBkaXJlY3RseSBvbiB0YWJsZS4KICAgICAgICAgICAgICAgIC8vTG9zdFByb3BlcnR5RXZlbnQoIHVubzo6bWFrZUFueShBY2Nlc3NpYmxlU3RhdGVUeXBlOjpGT0NVU0VEKSwgQWNjZXNzaWJsZUV2ZW50SWQ6OlNUQVRFX0NIQU5HRUQgKTsKICAgICAgICAgICAgICAgIGlmKCBteEZyb250RW5kLmlzKCkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgCUFjY2Vzc2libGVDZWxsKiBwQWNjZXNzaWJsZUNlbGwgPSBkeW5hbWljX2Nhc3Q8IEFjY2Vzc2libGVDZWxsKiA+ICggbXhGcm9udEVuZC5nZXQoKSApOwogICAgICAgICAgICAgICAgCWlmICggIXBBY2Nlc3NpYmxlQ2VsbCApCiAgICAgICAgICAgICAgICAgICAgICAgIAlMb3N0UHJvcGVydHlFdmVudCggdW5vOjptYWtlQW55KEFjY2Vzc2libGVTdGF0ZVR5cGU6OkZPQ1VTRUQpLCBBY2Nlc3NpYmxlRXZlbnRJZDo6U1RBVEVfQ0hBTkdFRCApOwogICAgICAgICAgICAgICAgCWVsc2UKICAgICAgICAgICAgICAgIAl7CiAgICAgICAgICAgICAgICAgICAgICAgCQlBY2Nlc3NpYmxlVGFibGVTaGFwZSogcEFjY1RhYmxlID0gcEFjY2Vzc2libGVDZWxsLT5HZXRQYXJlbnRUYWJsZSgpOwogICAgICAgICAgICAgICAgICAgICAgIAkJaWYgKHBBY2NUYWJsZSkKICAgICAgICAgICAgICAgICAgICAgICAJCQlwQWNjVGFibGUtPlJlc2V0U3RhdGVEaXJlY3RseShBY2Nlc3NpYmxlU3RhdGVUeXBlOjpGT0NVU0VEKTsKICAgICAgICAgICAgICAgIAl9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBEQkdfVFJBQ0UoIkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OlNldFNoYXBlRm9jdXMoKTogUGFyZW50IG9iamVjdCBsb3N0IGZvY3VzIiApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6U2V0Rm9jdXMoIHNhbF9Cb29sIGJIYXZlRm9jdXMgKSBTQUxfVEhST1coKDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgc2FsX0Jvb2wgYk9sZEZvY3VzKCBtYkdyb3VwSGFzRm9jdXMgKTsKCiAgICAgICAgbWJHcm91cEhhc0ZvY3VzID0gYkhhdmVGb2N1czsKCiAgICAgICAgaWYoIElzQWN0aXZlKCkgKQogICAgICAgIHsKICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGZpbmQgdGhlIG9uZSB3aXRoIHRoZSBjdXJzb3IgYW5kIGdldC9zZXQgZm9jdXMgYWNjb3JkaW5nbHkKICAgICAgICAgICAgICAgIEVTZWxlY3Rpb24gYVNlbGVjdGlvbjsKICAgICAgICAgICAgICAgIGlmKCBHZXRFZGl0Vmlld0ZvcndhcmRlcigpLkdldFNlbGVjdGlvbiggYVNlbGVjdGlvbiApICkKICAgICAgICAgICAgICAgICAgICBTZXRDaGlsZEZvY3VzKCBhU2VsZWN0aW9uLm5FbmRQYXJhLCBiSGF2ZUZvY3VzICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2goIGNvbnN0IHVubzo6RXhjZXB0aW9uJiApIHt9CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoIGJPbGRGb2N1cyAhPSBiSGF2ZUZvY3VzICkKICAgICAgICB7CiAgICAgICAgICAgIFNldFNoYXBlRm9jdXMoIGJIYXZlRm9jdXMgKTsKICAgICAgICB9CgogICAgICAgIERCR19UUkFDRTIoIkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OlNldEZvY3VzOiBmb2N1cyBjaGFuZ2VkLCBPYmplY3QgJWQsIHN0YXRlOiAlcyIsIHRoaXMsIGJIYXZlRm9jdXMgPyAiZm9jdXNlZCIgOiAibm90IGZvY3VzZWQiKTsKICAgIH0KCiAgICBzYWxfQm9vbCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpIYXZlRm9jdXMoKSBTQUxfVEhST1coKDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgLy8gTm8gbG9ja2luZyBvZiBzb2xhciBtdXRleCBoZXJlLCBzaW5jZSB3ZSByZWx5IG9uIHRoZSBmYWN0CiAgICAgICAgLy8gdGhhdCBzYWxfQm9vbCBhY2Nlc3MgaXMgYXRvbWljCiAgICAgICAgcmV0dXJuIG1iVGhpc0hhc0ZvY3VzOwogICAgfQoKICAgIHNhbF9Cb29sIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OklzQWN0aXZlKCkgY29uc3QgU0FMX1RIUk9XKCh1bm86OlJ1bnRpbWVFeGNlcHRpb24pKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgU3Z4RWRpdFNvdXJjZSYgckVkaXRTb3VyY2UgPSBHZXRFZGl0U291cmNlKCk7CiAgICAgICAgICAgIFN2eEVkaXRWaWV3Rm9yd2FyZGVyKiBwVmlld0ZvcndhcmRlciA9IHJFZGl0U291cmNlLkdldEVkaXRWaWV3Rm9yd2FyZGVyKCk7CgogICAgICAgICAgICBpZiggIXBWaWV3Rm9yd2FyZGVyICkKICAgICAgICAgICAgICAgIHJldHVybiBzYWxfRmFsc2U7CgoJCQlpZiggbXhGcm9udEVuZC5pcygpICkKCQkJewoJCQkJQWNjZXNzaWJsZUNlbGwqIHBBY2Nlc3NpYmxlQ2VsbCA9IGR5bmFtaWNfY2FzdDwgQWNjZXNzaWJsZUNlbGwqID4gKCBteEZyb250RW5kLmdldCgpICk7CgkJCQlpZiAoIHBBY2Nlc3NpYmxlQ2VsbCApCgkJCQl7CgkJCQkJc2RyOjp0YWJsZTo6Q2VsbFJlZiB4Q2VsbCA9IHBBY2Nlc3NpYmxlQ2VsbC0+Z2V0Q2VsbFJlZigpOwoJCQkJCWlmICggeENlbGwuaXMoKSApCgkJCQkJCXJldHVybiB4Q2VsbC0+SXNUZXh0RWRpdEFjdGl2ZSgpOwoJCQkJfQoJCQl9CiAgICAgICAgICAgIGlmKCBwVmlld0ZvcndhcmRlci0+SXNWYWxpZCgpICkKICAgICAgICAgICAgICAgIHJldHVybiBzYWxfVHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKICAgICAgICB9CiAgICAgICAgY2F0Y2goIGNvbnN0IHVubzo6UnVudGltZUV4Y2VwdGlvbiYgKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpVcGRhdGVTZWxlY3Rpb24oKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgRVNlbGVjdGlvbiBhU2VsZWN0aW9uOwogICAgICAgICAgICBpZiggR2V0RWRpdFZpZXdGb3J3YXJkZXIoKS5HZXRTZWxlY3Rpb24oIGFTZWxlY3Rpb24gKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKCAhbWFMYXN0U2VsZWN0aW9uLklzRXF1YWwoIGFTZWxlY3Rpb24gKSAmJgogICAgICAgICAgICAgICAgICAgIGFTZWxlY3Rpb24ubkVuZFBhcmEgPCBtYVBhcmFNYW5hZ2VyLkdldE51bSgpICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyAjMTAzOTk4IyBOb3QgdGhhdCBpbXBvcnRhbnQsIGNoYW5nZWQgZnJvbSBhc3NlcnRpb24gdG8gdHJhY2UKICAgICAgICAgICAgICAgICAgICBpZiggbWJUaGlzSGFzRm9jdXMgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgREJHX1RSQUNFKCJBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpVcGRhdGVTZWxlY3Rpb24oKTogUGFyZW50IGhhcyBmb2N1cyEiKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHNhbF91SW50MTYgbk1heFZhbGlkUGFyYUluZGV4KCBzdGF0aWNfY2FzdDwgc2FsX3VJbnQxNiA+KCBHZXRUZXh0Rm9yd2FyZGVyKCkuR2V0UGFyYWdyYXBoQ291bnQoKSApIC0gMSApOwoKICAgICAgICAgICAgICAgICAgICAvLyBub3RpZnkgYWxsIGFmZmVjdGVkIHBhcmFncmFwaHMgKFRPRE86IG1heSBiZSBzdWJvcHRpbWFsLAogICAgICAgICAgICAgICAgICAgIC8vIHNpbmNlIHNvbWUgcGFyYWdyYXBocyBtaWdodCBzdGF5IHNlbGVjdGVkKQogICAgICAgICAgICAgICAgICAgIGlmKCBtYUxhc3RTZWxlY3Rpb24ublN0YXJ0UGFyYSAhPSBFRV9QQVJBX05PVF9GT1VORCApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBEaWQgdGhlIGNhcmV0IG1vdmUgZnJvbSBvbmUgcGFyYWdyYXBoIHRvIGFub3RoZXI/CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICMxMDA1MzAjIG5vIGNhcmV0IGV2ZW50cyBpZiBub3QgZm9jdXNlZC4KICAgICAgICAgICAgICAgICAgICAgICAgaWYoIG1iR3JvdXBIYXNGb2N1cyAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFMYXN0U2VsZWN0aW9uLm5FbmRQYXJhICE9IGFTZWxlY3Rpb24ubkVuZFBhcmEgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggbWFMYXN0U2VsZWN0aW9uLm5FbmRQYXJhIDwgbWFQYXJhTWFuYWdlci5HZXROdW0oKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CgkJCQkJCQkJbWFQYXJhTWFuYWdlci5GaXJlRXZlbnQoIDo6c3RkOjptaW4oIG1hTGFzdFNlbGVjdGlvbi5uRW5kUGFyYSwgbk1heFZhbGlkUGFyYUluZGV4ICksCgkJCQkJCQkJCQkJCQkJIDo6c3RkOjptaW4oIG1hTGFzdFNlbGVjdGlvbi5uRW5kUGFyYSwgbk1heFZhbGlkUGFyYUluZGV4ICkrMSwKCQkJCQkJCQkJCQkJCQkgQWNjZXNzaWJsZUV2ZW50SWQ6OkNBUkVUX0NIQU5HRUQsCgkJCQkJCQkJCQkJCQkJIHVubzo6bWFrZUFueShzdGF0aWNfY2FzdDxzYWxfSW50MzI+KC0xKSksCgkJCQkJCQkJCQkJCQkJIHVubzo6bWFrZUFueShzdGF0aWNfY2FzdDxzYWxfSW50MzI+KG1hTGFzdFNlbGVjdGlvbi5uRW5kUG9zKSkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFuZ2VDaGlsZEZvY3VzKCBhU2VsZWN0aW9uLm5FbmRQYXJhICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgREJHX1RSQUNFMygiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6VXBkYXRlU2VsZWN0aW9uKCk6IGZvY3VzIGNoYW5nZWQsIE9iamVjdDogJWQsIFBhcmFncmFwaDogJWQsIExhc3QgcGFyYWdyYXBoOiAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsIGFTZWxlY3Rpb24ubkVuZFBhcmEsIG1hTGFzdFNlbGVjdGlvbi5uRW5kUGFyYSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vICMxMDA1MzAjIG5vIGNhcmV0IGV2ZW50cyBpZiBub3QgZm9jdXNlZC4KICAgICAgICAgICAgICAgICAgICBpZiggbWJHcm91cEhhc0ZvY3VzICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVubzo6QW55IGFPbGRDdXJzb3I7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyAjaTEzNzA1IyBUaGUgb2xkIGN1cnNvciBjYW4gb25seSBjb250YWluIHZhbGlkCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZhbHVlcyBpZiBpdCdzIHRoZSBzYW1lIHBhcmFncmFwaCEKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIG1hTGFzdFNlbGVjdGlvbi5uU3RhcnRQYXJhICE9IEVFX1BBUkFfTk9UX0ZPVU5EICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYUxhc3RTZWxlY3Rpb24ubkVuZFBhcmEgPT0gYVNlbGVjdGlvbi5uRW5kUGFyYSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFPbGRDdXJzb3IgPDw9IHN0YXRpY19jYXN0PHNhbF9JbnQzMj4obWFMYXN0U2VsZWN0aW9uLm5FbmRQb3MpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYU9sZEN1cnNvciA8PD0gc3RhdGljX2Nhc3Q8c2FsX0ludDMyPigtMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIG1hUGFyYU1hbmFnZXIuRmlyZUV2ZW50KCBhU2VsZWN0aW9uLm5FbmRQYXJhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVNlbGVjdGlvbi5uRW5kUGFyYSsxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWNjZXNzaWJsZUV2ZW50SWQ6OkNBUkVUX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bm86Om1ha2VBbnkoc3RhdGljX2Nhc3Q8c2FsX0ludDMyPihhU2VsZWN0aW9uLm5FbmRQb3MpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFPbGRDdXJzb3IgKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIERCR19UUkFDRTUoIkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OlVwZGF0ZVNlbGVjdGlvbigpOiBjYXJldCBjaGFuZ2VkLCBPYmplY3Q6ICVkLCBOZXcgcG9zOiAlZCwgT2xkIHBvczogJWQsIE5ldyBwYXJhOiAlZCwgT2xkIHBhcmE6ICVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsIGFTZWxlY3Rpb24ubkVuZFBvcywgbWFMYXN0U2VsZWN0aW9uLm5FbmRQb3MsIGFTZWxlY3Rpb24ubkVuZFBhcmEsIG1hTGFzdFNlbGVjdGlvbi5uRW5kUGFyYSk7CgogICAgICAgICAgICAgICAgICAgIC8vICMxMDg5NDcjIFNvcnQgbmV3IHJhbmdlIGJlZm9yZSBjYWxsaW5nIEZpcmVFdmVudAogICAgICAgICAgICAgICAgICAgIDo6c3RkOjpwYWlyPCB4dWJfU3RyTGVuLCB4dWJfU3RyTGVuID4gc29ydGVkU2VsZWN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICBtYWtlU29ydGVkUGFpcig6OnN0ZDo6bWluKCBhU2VsZWN0aW9uLm5TdGFydFBhcmEsIG5NYXhWYWxpZFBhcmFJbmRleCApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnN0ZDo6bWluKCBhU2VsZWN0aW9uLm5FbmRQYXJhLCBuTWF4VmFsaWRQYXJhSW5kZXggKSApICk7CgogICAgICAgICAgICAgICAgICAgIC8vICMxMDg5NDcjIFNvcnQgbGFzdCByYW5nZSBiZWZvcmUgY2FsbGluZyBGaXJlRXZlbnQKICAgICAgICAgICAgICAgICAgICA6OnN0ZDo6cGFpcjwgeHViX1N0ckxlbiwgeHViX1N0ckxlbiA+IHNvcnRlZExhc3RTZWxlY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgIG1ha2VTb3J0ZWRQYWlyKDo6c3RkOjptaW4oIG1hTGFzdFNlbGVjdGlvbi5uU3RhcnRQYXJhLCBuTWF4VmFsaWRQYXJhSW5kZXggKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpzdGQ6Om1pbiggbWFMYXN0U2VsZWN0aW9uLm5FbmRQYXJhLCBuTWF4VmFsaWRQYXJhSW5kZXggKSApICk7CgogICAgICAgICAgICAgICAgICAgIC8vIC0tPiBPRCAyMDA1LTEyLTE1ICNpMjcyOTkjCiAgICAgICAgICAgICAgICAgICAgLy8gZXZlbnQgVEVYVF9TRUxFQ1RJT05fQ0hBTkdFRCBoYXMgdG8gYmUgc3VibWl0dGVkLgogICAgICAgICAgICAgICAgICAgIGNvbnN0IHNhbF9JbnQxNiBuVGV4dFNlbENoZ0V2ZW50SWQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY2Nlc3NpYmxlRXZlbnRJZDo6VEVYVF9TRUxFQ1RJT05fQ0hBTkdFRDsKICAgICAgICAgICAgICAgICAgICAvLyA8LS0KICAgICAgICAgICAgICAgICAgICAvLyAjMTA3MDM3IyBub3RpZnkgc2VsZWN0aW9uIGNoYW5nZQogICAgICAgICAgICAgICAgICAgIGlmKCBtYUxhc3RTZWxlY3Rpb24ublN0YXJ0UGFyYSA9PSBFRV9QQVJBX05PVF9GT1VORCApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBsYXN0IHNlbGVjdGlvbiBpcyB1bmRlZmluZWQKICAgICAgICAgICAgICAgICAgICAgICAgLy8gLS0+IE9EIDIwMDUtMTItMTUgI2kyNzI5OSMgLSB1c2UgbWV0aG9kIDxFU2VsZWN0aW9uOjpIYXNSYW5nZSgpPgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFTZWxlY3Rpb24uSGFzUmFuZ2UoKSApCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtLQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWxlY3Rpb24gd2FzIHVuZGVmaW5lZCwgbm93IGlzIG9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLkZpcmVFdmVudCggc29ydGVkU2VsZWN0aW9uLmZpcnN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRlZFNlbGVjdGlvbi5zZWNvbmQrMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuVGV4dFNlbENoZ0V2ZW50SWQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBsYXN0IHNlbGVjdGlvbiBpcyB2YWxpZAogICAgICAgICAgICAgICAgICAgICAgICAvLyAtLT4gT0QgMjAwNS0xMi0xNSAjaTI3Mjk5IyAtIHVzZSBtZXRob2QgPEVTZWxlY3Rpb246Okhhc1JhbmdlKCk+CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggbWFMYXN0U2VsZWN0aW9uLkhhc1JhbmdlKCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhYVNlbGVjdGlvbi5IYXNSYW5nZSgpICkKICAgICAgICAgICAgICAgICAgICAgICAgLy8gPC0tCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlbGVjdGlvbiB3YXMgb24sIG5vdyBpcyBlbXB0eQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFQYXJhTWFuYWdlci5GaXJlRXZlbnQoIHNvcnRlZExhc3RTZWxlY3Rpb24uZmlyc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc29ydGVkTGFzdFNlbGVjdGlvbi5zZWNvbmQrMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuVGV4dFNlbENoZ0V2ZW50SWQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvLyAtLT4gT0QgMjAwNS0xMi0xNSAjaTI3Mjk5IyAtIHVzZSBtZXRob2QgPEVTZWxlY3Rpb246Okhhc1JhbmdlKCk+CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoICFtYUxhc3RTZWxlY3Rpb24uSGFzUmFuZ2UoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhU2VsZWN0aW9uLkhhc1JhbmdlKCkgKQogICAgICAgICAgICAgICAgICAgICAgICAvLyA8LS0KICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VsZWN0aW9uIHdhcyBlbXB0eSwgbm93IGlzIG9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLkZpcmVFdmVudCggc29ydGVkU2VsZWN0aW9uLmZpcnN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRlZFNlbGVjdGlvbi5zZWNvbmQrMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuVGV4dFNlbENoZ0V2ZW50SWQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvLyAtLT4gT0QgMjAwNS0xMi0xNSAjaTI3Mjk5IwogICAgICAgICAgICAgICAgICAgICAgICAvLyAtIG5vIGV2ZW50IFRFWFRfU0VMRUNUSU9OX0NIQU5HRUQgZXZlbnQsIGlmIG5ldyBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBsYXN0IHNlbGVjdGlvbiBhcmUgZW1wdHkuCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCBtYUxhc3RTZWxlY3Rpb24uSGFzUmFuZ2UoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVNlbGVjdGlvbi5IYXNSYW5nZSgpICkKICAgICAgICAgICAgICAgICAgICAgICAgLy8gPC0tCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIC0tPiBPRCAyMDA1LTEyLTE2ICNpMjcyOTkjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAtIHNlbmQgZXZlbnQgVEVYVF9TRUxFQ1RJT05fQ0hBTkdFRCBmb3IgZGlmZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICBiZXR3ZWVuIGxhc3QgYW5kIG5ldyBzZWxlY3Rpb24uCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlbGVjdGlvbiB3YXMgb24sIG5vdyBpcyBkaWZmZXJlbnQ6IHRha2UgdW5pb24gb2YgcmFuZ2VzCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hUGFyYU1hbmFnZXIuRmlyZUV2ZW50KCA6OnN0ZDo6bWluKHNvcnRlZFNlbGVjdGlvbi5maXJzdCwKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRlZExhc3RTZWxlY3Rpb24uc2Vjb25kKSwKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6c3RkOjptYXgoc29ydGVkU2VsZWN0aW9uLmZpcnN0LAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc29ydGVkTGFzdFNlbGVjdGlvbi5zZWNvbmQpKzEsCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuVGV4dFNlbENoZ0V2ZW50SWQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZSBzb3J0ZWQgbGFzdCBhbmQgbmV3IHNlbGVjdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgRVNlbGVjdGlvbiBhVG1wTGFzdFNlbCggbWFMYXN0U2VsZWN0aW9uICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhVG1wTGFzdFNlbC5BZGp1c3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVTZWxlY3Rpb24gYVRtcFNlbCggYVNlbGVjdGlvbiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYVRtcFNlbC5BZGp1c3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpcnN0IHN1Ym1pdCBldmVudCBmb3IgbmV3IGFuZCBjaGFuZ2VkIHNlbGVjdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsX3VJbnQzMiBuUGFyYSA9IGFUbXBTZWwublN0YXJ0UGFyYTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoIDsgblBhcmEgPD0gYVRtcFNlbC5uRW5kUGFyYTsgKytuUGFyYSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBuUGFyYSA8IGFUbXBMYXN0U2VsLm5TdGFydFBhcmEgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5QYXJhID4gYVRtcExhc3RTZWwubkVuZFBhcmEgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmV3IHNlbGVjdGlvbiBvbiBwYXJhZ3JhcGggPG5QYXJhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLkZpcmVFdmVudCggblBhcmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuVGV4dFNlbENoZ0V2ZW50SWQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGNoYW5nZWQgc2VsZWN0aW9uIG9uIHBhcmFncmFwaCA8blBhcmE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHh1Yl9TdHJMZW4gblBhcmFTdGFydFBvcyA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgblBhcmEgPT0gYVRtcFNlbC5uU3RhcnRQYXJhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhVG1wU2VsLm5TdGFydFBvcyA6IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHh1Yl9TdHJMZW4gblBhcmFFbmRQb3MgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5QYXJhID09IGFUbXBTZWwubkVuZFBhcmEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFUbXBTZWwubkVuZFBvcyA6IFNUUklOR19MRU47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHh1Yl9TdHJMZW4gbkxhc3RQYXJhU3RhcnRQb3MgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5QYXJhID09IGFUbXBMYXN0U2VsLm5TdGFydFBhcmEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFUbXBMYXN0U2VsLm5TdGFydFBvcyA6IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHh1Yl9TdHJMZW4gbkxhc3RQYXJhRW5kUG9zID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuUGFyYSA9PSBhVG1wTGFzdFNlbC5uRW5kUGFyYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYVRtcExhc3RTZWwubkVuZFBvcyA6IFNUUklOR19MRU47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggblBhcmFTdGFydFBvcyAhPSBuTGFzdFBhcmFTdGFydFBvcyB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5QYXJhRW5kUG9zICE9IG5MYXN0UGFyYUVuZFBvcyApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hUGFyYU1hbmFnZXIuRmlyZUV2ZW50KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgblBhcmEsIG5UZXh0U2VsQ2hnRXZlbnRJZCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2Vjb25kIHN1Ym1pdCBldmVudCBmb3IgJ29sZCcgc2VsZWN0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgblBhcmEgPSBhVG1wTGFzdFNlbC5uU3RhcnRQYXJhOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICggOyBuUGFyYSA8PSBhVG1wTGFzdFNlbC5uRW5kUGFyYTsgKytuUGFyYSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBuUGFyYSA8IGFUbXBTZWwublN0YXJ0UGFyYSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgblBhcmEgPiBhVG1wU2VsLm5FbmRQYXJhICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hUGFyYU1hbmFnZXIuRmlyZUV2ZW50KCBuUGFyYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5UZXh0U2VsQ2hnRXZlbnRJZCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgbWFMYXN0U2VsZWN0aW9uID0gYVNlbGVjdGlvbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBubyBzZWxlY3Rpb24/IG5vIHVwZGF0ZSBhY3Rpb25zCiAgICAgICAgY2F0Y2goIGNvbnN0IHVubzo6UnVudGltZUV4Y2VwdGlvbiYgKSB7fQogICAgfQoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6U2h1dGRvd25FZGl0U291cmNlKCkgU0FMX1RIUk9XKCh1bm86OlJ1bnRpbWVFeGNlcHRpb24pKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIHdpdGggc29sYXIgbXV0ZXggbG9ja2VkLCBpLmUuIGZyb20gdGhlIG1haW4gb2ZmaWNlIHRocmVhZAoKICAgICAgICAvLyBUaGlzIGhlcmUgaXMgc29tZXdoYXQgY2x1bXN5OiBBcyBzb29uIGFzIG91ciBjaGlsZHJlbiBoYXZlCiAgICAgICAgLy8gYSBOVUxMIEVkaXRTb3VyY2UgKG1hUGFyYU1hbmFnZXIuU2V0RWRpdFNvdXJjZSgpKSwgdGhleQogICAgICAgIC8vIGVudGVyIHRoZSBkaXNwb3NlZCBzdGF0ZSBhbmQgY2Fubm90IGJlIHJlYW5pbWF0ZWQuIFRodXMsIGl0CiAgICAgICAgLy8gaXMgdW5hdm9pZGFibGUgYW5kIGEgaGFyZCByZXF1aXJlbWVudCB0byBsZXQgZ28gYW5kIGNyZWF0ZQogICAgICAgIC8vIGZyb20gc2NyYXRjaCBlYWNoIGFuZCBldmVyeSBjaGlsZC4KCiAgICAgICAgLy8gaW52YWxpZGF0ZSBjaGlsZHJlbgogICAgICAgIG1hUGFyYU1hbmFnZXIuRGlzcG9zZSgpOwogICAgICAgIG1hUGFyYU1hbmFnZXIuU2V0TnVtKDApOwoKICAgICAgICAvLyBsb3N0IGFsbCBjaGlsZHJlbgogICAgICAgIGlmKCBteEZyb250RW5kLmlzKCkgKQogICAgICAgICAgICBGaXJlRXZlbnQoQWNjZXNzaWJsZUV2ZW50SWQ6OklOVkFMSURBVEVfQUxMX0NISUxEUkVOKTsKCiAgICAgICAgLy8gcXVpdCBsaXN0ZW4gb24gc3RhbGUgZWRpdCBzb3VyY2UKICAgICAgICBpZiggbWFFZGl0U291cmNlLklzVmFsaWQoKSApCiAgICAgICAgICAgIEVuZExpc3RlbmluZyggbWFFZGl0U291cmNlLkdldEJyb2FkY2FzdGVyKCkgKTsKCiAgICAgICAgbWFFZGl0U291cmNlLlNldEVkaXRTb3VyY2UoIDo6c3RkOjphdXRvX3B0cjwgU3Z4RWRpdFNvdXJjZSA+KE5VTEwpICk7CiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpTZXRFZGl0U291cmNlKCA6OnN0ZDo6YXV0b19wdHI8IFN2eEVkaXRTb3VyY2UgPiBwRWRpdFNvdXJjZSApIFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICAvLyBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCB3aXRoIHNvbGFyIG11dGV4IGxvY2tlZCwgaS5lLiBmcm9tIHRoZSBtYWluIG9mZmljZSB0aHJlYWQKCiAgICAgICAgLy8gc2h1dGRvd24gb2xkIGVkaXQgc291cmNlCiAgICAgICAgU2h1dGRvd25FZGl0U291cmNlKCk7CgogICAgICAgIC8vIHNldCBuZXcgZWRpdCBzb3VyY2UKICAgICAgICBtYUVkaXRTb3VyY2UuU2V0RWRpdFNvdXJjZSggcEVkaXRTb3VyY2UgKTsKCiAgICAgICAgLy8gaW5pdCBjaGlsZCB2ZWN0b3IgdG8gdGhlIGN1cnJlbnQgY2hpbGQgY291bnQKICAgICAgICBpZiggbWFFZGl0U291cmNlLklzVmFsaWQoKSApCiAgICAgICAgewogICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLlNldE51bSggR2V0VGV4dEZvcndhcmRlcigpLkdldFBhcmFncmFwaENvdW50KCkgKTsKCiAgICAgICAgICAgIC8vIGxpc3RlbiBvbiBuZXcgZWRpdCBzb3VyY2UKICAgICAgICAgICAgU3RhcnRMaXN0ZW5pbmcoIG1hRWRpdFNvdXJjZS5HZXRCcm9hZGNhc3RlcigpICk7CgogICAgICAgICAgICBVcGRhdGVWaXNpYmxlQ2hpbGRyZW4oKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpTZXRPZmZzZXQoIGNvbnN0IFBvaW50JiByUG9pbnQgKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIC8vIGd1YXJkIGFnYWluc3Qgbm9uLWF0b21pYyBhY2Nlc3MgdG8gbWFPZmZzZXQgZGF0YSBzdHJ1Y3R1cmUKICAgICAgICB7CiAgICAgICAgICAgIDo6b3NsOjpNdXRleEd1YXJkIGFHdWFyZCggbWFNdXRleCApOwogICAgICAgICAgICBtYU9mZnNldCA9IHJQb2ludDsKICAgICAgICB9CgogICAgICAgIG1hUGFyYU1hbmFnZXIuU2V0RUVPZmZzZXQoIHJQb2ludCApOwoKICAgICAgICAvLyBpbiBhbGwgY2FzZXMsIGNoZWNrIHZpc2liaWxpdHkgYWZ0ZXJ3YXJkcy4KICAgICAgICBVcGRhdGVWaXNpYmxlQ2hpbGRyZW4oKTsKICAgICAgICBVcGRhdGVCb3VuZFJlY3QoKTsKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OlVwZGF0ZVZpc2libGVDaGlsZHJlbiggYm9vbCBiQnJvYWRjYXN0RXZlbnRzICkKICAgIHsKICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIFN2eFRleHRGb3J3YXJkZXImIHJDYWNoZVRGID0gR2V0VGV4dEZvcndhcmRlcigpOwogICAgICAgICAgICBTdnhWaWV3Rm9yd2FyZGVyJiByQ2FjaGVWRiA9IEdldFZpZXdGb3J3YXJkZXIoKTsKCiAgICAgICAgICAgIFJlY3RhbmdsZSBhVmlld0FyZWEgPSByQ2FjaGVWRi5HZXRWaXNBcmVhKCk7CgogICAgICAgICAgICBpZiggSXNBY3RpdmUoKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIG1heWJlIHRoZSBlZGl0IHZpZXcgc2Nyb2xscywgYWRhcHQgYVZpZXdBcmVhCiAgICAgICAgICAgICAgICBSZWN0YW5nbGUgYUVkaXRWaWV3QXJlYSA9IEdldEVkaXRWaWV3Rm9yd2FyZGVyKCkuR2V0VmlzQXJlYSgpOwogICAgICAgICAgICAgICAgYVZpZXdBcmVhICs9IGFFZGl0Vmlld0FyZWEuVG9wTGVmdCgpOwoKICAgICAgICAgICAgICAgIC8vIG5vdyBkZXRlcm1pbmUgaW50ZXJzZWN0aW9uCiAgICAgICAgICAgICAgICBhVmlld0FyZWEuSW50ZXJzZWN0aW9uKCBhRWRpdFZpZXdBcmVhICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFJlY3RhbmdsZSBhVG1wQkIsIGFQYXJhQkI7CiAgICAgICAgICAgIHNhbF9Cb29sIGJGaXJzdENoaWxkID0gc2FsX1RydWU7CiAgICAgICAgICAgIHNhbF9JbnQzMiBuQ3VyclBhcmE7CiAgICAgICAgICAgIHNhbF9JbnQzMiBuUGFyYXM9ckNhY2hlVEYuR2V0UGFyYWdyYXBoQ291bnQoKTsKCiAgICAgICAgICAgIG1uRmlyc3RWaXNpYmxlQ2hpbGQgPSAtMTsKICAgICAgICAgICAgbW5MYXN0VmlzaWJsZUNoaWxkID0gLTI7CgogICAgICAgICAgICBmb3IoIG5DdXJyUGFyYT0wOyBuQ3VyclBhcmE8blBhcmFzOyArK25DdXJyUGFyYSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERCR19BU1NFUlQobkN1cnJQYXJhID49IDAgJiYgbkN1cnJQYXJhIDw9IFVTSFJUX01BWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OlVwZGF0ZVZpc2libGVDaGlsZHJlbjogaW5kZXggdmFsdWUgb3ZlcmZsb3ciKTsKCiAgICAgICAgICAgICAgICBhVG1wQkIgPSByQ2FjaGVURi5HZXRQYXJhQm91bmRzKCBzdGF0aWNfY2FzdDwgc2FsX3VJbnQxNiA+KCBuQ3VyclBhcmEgKSApOwoKICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdG8gc2NyZWVuIGNvb3JkaW5hdGVzCiAgICAgICAgICAgICAgICBhUGFyYUJCID0gOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlRWRpdGFibGVUZXh0UGFyYTo6TG9naWNUb1BpeGVsKCBhVG1wQkIsIHJDYWNoZVRGLkdldE1hcE1vZGUoKSwgckNhY2hlVkYgKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gYXQgbGVhc3QgcGFydGlhbGx5IHZpc2libGUKICAgICAgICAgICAgICAgICAgICBpZiggYkZpcnN0Q2hpbGQgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYkZpcnN0Q2hpbGQgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIG1uRmlyc3RWaXNpYmxlQ2hpbGQgPSBuQ3VyclBhcmE7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBtbkxhc3RWaXNpYmxlQ2hpbGQgPSBuQ3VyclBhcmE7CgogICAgICAgICAgICAgICAgICAgIC8vIGNoaWxkIG5vdCB5ZXQgY3JlYXRlZD8KICAgICAgICAgICAgICAgICAgICA6OmFjY2Vzc2liaWxpdHk6OkFjY2Vzc2libGVQYXJhTWFuYWdlcjo6V2Vha0NoaWxkIGFDaGlsZCggbWFQYXJhTWFuYWdlci5HZXRDaGlsZChuQ3VyclBhcmEpICk7CiAgICAgICAgICAgICAgICAgICAgaWYoIGFDaGlsZC5zZWNvbmQuV2lkdGggPT0gMCAmJgogICAgICAgICAgICAgICAgICAgICAgICBhQ2hpbGQuc2Vjb25kLkhlaWdodCA9PSAwICYmCiAgICAgICAgICAgICAgICAgICAgICAgIG14RnJvbnRFbmQuaXMoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICBiQnJvYWRjYXN0RXZlbnRzICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEdvdFByb3BlcnR5RXZlbnQoIHVubzo6bWFrZUFueSggbWFQYXJhTWFuYWdlci5DcmVhdGVDaGlsZCggbkN1cnJQYXJhIC0gbW5GaXJzdFZpc2libGVDaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteEZyb250RW5kLCBHZXRFZGl0U291cmNlKCksIG5DdXJyUGFyYSApLmZpcnN0ICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc2libGVFdmVudElkOjpDSElMRCApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjYXRjaCggY29uc3QgdW5vOjpFeGNlcHRpb24mICkKICAgICAgICB7CiAgICAgICAgICAgIERCR19FUlJPUigiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6VXBkYXRlVmlzaWJsZUNoaWxkcmVuIGVycm9yIHdoaWxlIGRldGVybWluaW5nIHZpc2libGUgY2hpbGRyZW4iKTsKCiAgICAgICAgICAgIC8vIHNvbWV0aGluZyBmYWlsZWQgLSBjdXJyZW50bHkgbm8gY2hpbGRyZW4KICAgICAgICAgICAgbW5GaXJzdFZpc2libGVDaGlsZCA9IC0xOwogICAgICAgICAgICBtbkxhc3RWaXNpYmxlQ2hpbGQgPSAtMjsKICAgICAgICAgICAgbWFQYXJhTWFuYWdlci5TZXROdW0oMCk7CgogICAgICAgICAgICAvLyBsb3N0IGFsbCBjaGlsZHJlbgogICAgICAgICAgICBpZiggYkJyb2FkY2FzdEV2ZW50cyApCiAgICAgICAgICAgICAgICBGaXJlRXZlbnQoQWNjZXNzaWJsZUV2ZW50SWQ6OklOVkFMSURBVEVfQUxMX0NISUxEUkVOKTsKICAgICAgICB9CiAgICB9CgoJLy8gZnVuY3RvciBmb3IgY2hlY2tpbmcgY2hhbmdlcyBpbiBwYXJhZ3JhcGggYm91bmRpbmcgYm94ZXMgKG5vIHN0YW5kLWFsb25lIGZ1bmN0aW9uLCBtYXliZSBub3QgaW5saW5lZCkKICAgIGNsYXNzIEFjY2Vzc2libGVUZXh0SGVscGVyX1VwZGF0ZUNoaWxkQm91bmRzIDogcHVibGljIDo6c3RkOjp1bmFyeV9mdW5jdGlvbjwgY29uc3QgOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OldlYWtDaGlsZCYsCiAgICAgICAgOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OldlYWtDaGlsZCA+CiAgICB7CiAgICBwdWJsaWM6CiAgICAgICAgQWNjZXNzaWJsZVRleHRIZWxwZXJfVXBkYXRlQ2hpbGRCb3VuZHMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwmIHJJbXBsICkgOiBtckltcGwockltcGwpIHt9CiAgICAgICAgOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OldlYWtDaGlsZCBvcGVyYXRvcigpKCBjb25zdCA6OmFjY2Vzc2liaWxpdHk6OkFjY2Vzc2libGVQYXJhTWFuYWdlcjo6V2Vha0NoaWxkJiByQ2hpbGQgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gcmV0cmlldmUgaGFyZCByZWZlcmVuY2UgZnJvbSB3ZWFrIG9uZQogICAgICAgICAgICA6OmFjY2Vzc2liaWxpdHk6OkFjY2Vzc2libGVQYXJhTWFuYWdlcjo6V2Vha1BhcmE6OkhhcmRSZWZUeXBlIGFIYXJkUmVmKCByQ2hpbGQuZmlyc3QuZ2V0KCkgKTsKCiAgICAgICAgICAgIGlmKCBhSGFyZFJlZi5pcygpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXd0OjpSZWN0YW5nbGUgIAkJYU5ld1JlY3QgPSBhSGFyZFJlZi0+Z2V0Qm91bmRzKCk7CiAgICAgICAgICAgICAgICBjb25zdCBhd3Q6OlJlY3RhbmdsZSYgCWFPbGRSZWN0ID0gckNoaWxkLnNlY29uZDsKCiAgICAgICAgICAgICAgICBpZiggYU5ld1JlY3QuWCAhPSBhT2xkUmVjdC5YIHx8CiAgICAgICAgICAgICAgICAgICAgYU5ld1JlY3QuWSAhPSBhT2xkUmVjdC5ZIHx8CiAgICAgICAgICAgICAgICAgICAgYU5ld1JlY3QuV2lkdGggIT0gYU9sZFJlY3QuV2lkdGggfHwKICAgICAgICAgICAgICAgICAgICBhTmV3UmVjdC5IZWlnaHQgIT0gYU9sZFJlY3QuSGVpZ2h0ICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyB2aXNpYmxlIGRhdGEgY2hhbmdlZAogICAgICAgICAgICAgICAgICAgIGFIYXJkUmVmLT5GaXJlRXZlbnQoIEFjY2Vzc2libGVFdmVudElkOjpCT1VORFJFQ1RfQ0hBTkdFRCApOwoKICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgaW50ZXJuYWwgYm91bmRzCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDo6YWNjZXNzaWJpbGl0eTo6QWNjZXNzaWJsZVBhcmFNYW5hZ2VyOjpXZWFrQ2hpbGQoIHJDaGlsZC5maXJzdCwgYU5ld1JlY3QgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaWRlbnRpdHkgdHJhbnNmb3JtCiAgICAgICAgICAgIHJldHVybiByQ2hpbGQ7CiAgICAgICAgfQoKICAgIHByaXZhdGU6CiAgICAgICAgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCYJbXJJbXBsOwogICAgfTsKCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OlVwZGF0ZUJvdW5kUmVjdCgpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgLy8gc2VuZCBCT1VORFJFQ1RfQ0hBTkdFRCB0byBhZmZlY3RlZCBjaGlsZHJlbgogICAgICAgIEFjY2Vzc2libGVUZXh0SGVscGVyX1VwZGF0ZUNoaWxkQm91bmRzIGFGdW5jdG9yKCAqdGhpcyApOwogICAgICAgIDo6c3RkOjp0cmFuc2Zvcm0oIG1hUGFyYU1hbmFnZXIuYmVnaW4oKSwgbWFQYXJhTWFuYWdlci5lbmQoKSwgbWFQYXJhTWFuYWdlci5iZWdpbigpLCBhRnVuY3RvciApOwogICAgfQoKI2lmZGVmIERCR19VVElMCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OkNoZWNrSW52YXJpYW50cygpIGNvbnN0CiAgICB7CiAgICAgICAgaWYoIG1uRmlyc3RWaXNpYmxlQ2hpbGQgPj0gMCAmJgogICAgICAgICAgICBtbkZpcnN0VmlzaWJsZUNoaWxkID4gbW5MYXN0VmlzaWJsZUNoaWxkICkKICAgICAgICB7CiAgICAgICAgICAgIERCR19FUlJPUiggIkFjY2Vzc2libGVUZXh0SGVscGVyOiByYW5nZSBpbnZhbGlkIiApOwogICAgICAgIH0KICAgIH0KI2VuZGlmCgoJLy8gZnVuY3RvciBmb3Igc2VuZGluZyBjaGlsZCBldmVudHMgKG5vIHN0YW5kLWFsb25lIGZ1bmN0aW9uLCB0aGV5IGFyZSBtYXliZSBub3QgaW5saW5lZCkKICAgIGNsYXNzIEFjY2Vzc2libGVUZXh0SGVscGVyX0xvc3RDaGlsZEV2ZW50IDogcHVibGljIDo6c3RkOjp1bmFyeV9mdW5jdGlvbjwgY29uc3QgOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OldlYWtDaGlsZCYsIHZvaWQgPgogICAgewogICAgcHVibGljOgogICAgICAgIEFjY2Vzc2libGVUZXh0SGVscGVyX0xvc3RDaGlsZEV2ZW50KCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsJiBySW1wbCApIDogbXJJbXBsKHJJbXBsKSB7fQogICAgICAgIHZvaWQgb3BlcmF0b3IoKSggY29uc3QgOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OldlYWtDaGlsZCYgclBhcmEgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gcmV0cmlldmUgaGFyZCByZWZlcmVuY2UgZnJvbSB3ZWFrIG9uZQogICAgICAgICAgICA6OmFjY2Vzc2liaWxpdHk6OkFjY2Vzc2libGVQYXJhTWFuYWdlcjo6V2Vha1BhcmE6OkhhcmRSZWZUeXBlIGFIYXJkUmVmKCByUGFyYS5maXJzdC5nZXQoKSApOwoKICAgICAgICAgICAgaWYoIGFIYXJkUmVmLmlzKCkgKQogICAgICAgICAgICAgICAgbXJJbXBsLkZpcmVFdmVudChBY2Nlc3NpYmxlRXZlbnRJZDo6Q0hJTEQsIHVubzo6QW55KCksIHVubzo6bWFrZUFueSggYUhhcmRSZWYuZ2V0UmVmKCkgKSApOwogICAgICAgIH0KCiAgICBwcml2YXRlOgogICAgICAgIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwmCW1ySW1wbDsKICAgIH07CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpQYXJhZ3JhcGhzTW92ZWQoIHNhbF9JbnQzMiBuRmlyc3QsIHNhbF9JbnQzMiBuTWlkZGxlLCBzYWxfSW50MzIgbkxhc3QgKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIGNvbnN0IHNhbF9JbnQzMiBuUGFyYXMgPSBHZXRUZXh0Rm9yd2FyZGVyKCkuR2V0UGFyYWdyYXBoQ291bnQoKTsKCiAgICAgICAgLyogcm90YXRlIHBhcmFncmFwaHMKICAgICAgICAgKiA9PT09PT09PT09PT09PT09PQogICAgICAgICAqCiAgICAgICAgICogVGhyZWUgY2FzZXM6CiAgICAgICAgICoKICAgICAgICAgKiAxLgogICAgICAgICAqICAgLi4uIG5QYXJhZ3JhcGggLi4uIG5QYXJhbTEgLi4uIG5QYXJhbTIgLi4uCiAgICAgICAgICogICAgICAgfF9fX19fX19fX19fX19fW3h4eHh4eHh4eHh4XQogICAgICAgICAqICAgICAgICAgICAgICBiZWNvbWVzCiAgICAgICAgICogICAgICAgW3h4eHh4eHh4eHh4XXxfX19fX19fX19fX19fXwogICAgICAgICAqCiAgICAgICAgICogdGFpbCBpcyAwCiAgICAgICAgICoKICAgICAgICAgKiAyLgogICAgICAgICAqICAgLi4uIG5QYXJhbTEgLi4uIG5QYXJhZ3JhcGggLi4uIG5QYXJhbTIgLi4uCiAgICAgICAgICogICAgICAgW3h4eHh4eHh4eHh4fHh4eHh4eHh4eHh4eHh4XV9fX19fX19fX19fXwogICAgICAgICAqICAgICAgICAgICAgICBiZWNvbWVzCiAgICAgICAgICogICAgICAgX19fX19fX19fX19fW3h4eHh4eHh4eHh4fHh4eHh4eHh4eHh4eHh4XQogICAgICAgICAqCiAgICAgICAgICogdGFpbCBpcyBuUGFyYWdyYXBoIC0gblBhcmFtMQogICAgICAgICAqCiAgICAgICAgICogMy4KICAgICAgICAgKiAgIC4uLiBuUGFyYW0xIC4uLiBuUGFyYW0yIC4uLiBuUGFyYWdyYXBoIC4uLgogICAgICAgICAqICAgICAgIFt4eHh4eHh4eHh4eF1fX19fX19fX19fX3xfX19fX19fX19fX18KICAgICAgICAgKiAgICAgICAgICAgICAgYmVjb21lcwogICAgICAgICAqICAgICAgIF9fX19fX19fX19ffF9fX19fX19fX19fX1t4eHh4eHh4eHh4eF0KICAgICAgICAgKgogICAgICAgICAqIHRhaWwgaXMgblBhcmFtMiAtIG5QYXJhbTEKICAgICAgICAgKi8KCiAgICAgICAgLy8gc29ydCBuUGFyYWdyYXBoLCBuUGFyYW0xIGFuZCBuUGFyYW0yIGluIGFzY2VuZGluZyBvcmRlciwgY2FsYyByYW5nZQogICAgICAgIGlmKCBuTWlkZGxlIDwgbkZpcnN0ICkKICAgICAgICB7CiAgICAgICAgICAgIDo6c3RkOjpzd2FwKG5GaXJzdCwgbk1pZGRsZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoIG5NaWRkbGUgPCBuTGFzdCApCiAgICAgICAgewogICAgICAgICAgICBuTGFzdCA9IG5MYXN0ICsgbk1pZGRsZSAtIG5GaXJzdDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgOjpzdGQ6OnN3YXAobk1pZGRsZSwgbkxhc3QpOwogICAgICAgICAgICBuTGFzdCA9IG5MYXN0ICsgbk1pZGRsZSAtIG5GaXJzdDsKICAgICAgICB9CgogICAgICAgIGlmKCBuRmlyc3QgPCBuUGFyYXMgJiYgbk1pZGRsZSA8IG5QYXJhcyAmJiBuTGFzdCA8IG5QYXJhcyApCiAgICAgICAgewogICAgICAgICAgICAvLyBzaW5jZSB3ZSBoYXZlIG5vICJwYXJhZ3JhcGggaW5kZXgKICAgICAgICAgICAgLy8gY2hhbmdlZCIgZXZlbnQgb24gVUFBLCByZW1vdmUKICAgICAgICAgICAgLy8gW2ZpcnN0LGxhc3RdIGFuZCBpbnNlcnQgYWdhaW4gbGF0ZXIgKGluCiAgICAgICAgICAgIC8vIFVwZGF0ZVZpc2libGVDaGlsZHJlbikKCiAgICAgICAgICAgIC8vIG1hUGFyYU1hbmFnZXIuUm90YXRlKCBuRmlyc3QsIG5NaWRkbGUsIG5MYXN0ICk7CgogICAgICAgICAgICAvLyBzZW5kIENISUxEX0VWRU5UIHRvIGFmZmVjdGVkIGNoaWxkcmVuCiAgICAgICAgICAgIDo6YWNjZXNzaWJpbGl0eTo6QWNjZXNzaWJsZVBhcmFNYW5hZ2VyOjpWZWN0b3JPZkNoaWxkcmVuOjpjb25zdF9pdGVyYXRvciBiZWdpbiA9IG1hUGFyYU1hbmFnZXIuYmVnaW4oKTsKICAgICAgICAgICAgOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OlZlY3Rvck9mQ2hpbGRyZW46OmNvbnN0X2l0ZXJhdG9yIGVuZCA9IGJlZ2luOwoKICAgICAgICAgICAgOjpzdGQ6OmFkdmFuY2UoIGJlZ2luLCBuRmlyc3QgKTsKICAgICAgICAgICAgOjpzdGQ6OmFkdmFuY2UoIGVuZCwgbkxhc3QrMSApOwoKICAgICAgICAgICAgLy8gVE9ETzogbWF5YmUgb3B0aW1pemUgaGVyZSBpbiB0aGUgZm9sbG93aW5nIHdheS4gIElmIHRoZQogICAgICAgICAgICAvLyBudW1iZXIgb2YgcmVtb3ZlZCBjaGlsZHJlbiBleGNlZWRzIGEgY2VydGFpbiB0aHJlc2hvbGQsCiAgICAgICAgICAgIC8vIHVzZSBJTlZBTElEQVRFX0NISUxEUkVOCiAgICAgICAgICAgIEFjY2Vzc2libGVUZXh0SGVscGVyX0xvc3RDaGlsZEV2ZW50IGFGdW5jdG9yKCAqdGhpcyApOwoKICAgICAgICAgICAgOjpzdGQ6OmZvcl9lYWNoKCBiZWdpbiwgZW5kLCBhRnVuY3RvciApOwoKICAgICAgICAgICAgbWFQYXJhTWFuYWdlci5SZWxlYXNlKG5GaXJzdCwgbkxhc3QrMSk7CiAgICAgICAgICAgIC8vIHNob3VsZCBiZSBubyBuZWVkIGZvciBVcGRhdGVCb3VuZFJlY3QsIHNpbmNlIGFsbCBhZmZlY3RlZCBjaGlsZHJlbiBhcmUgY2xlYXJlZC4KICAgICAgICB9CiAgICB9CgoJLy8gZnVuY3RvciBmb3Igc2VuZGluZyBjaGlsZCBldmVudHMgKG5vIHN0YW5kLWFsb25lIGZ1bmN0aW9uLCB0aGV5IGFyZSBtYXliZSBub3QgaW5saW5lZCkKICAgIGNsYXNzIEFjY2Vzc2libGVUZXh0SGVscGVyX0NoaWxkcmVuVGV4dENoYW5nZWQgOiBwdWJsaWMgOjpzdGQ6OnVuYXJ5X2Z1bmN0aW9uPCA6OmFjY2Vzc2liaWxpdHk6OkFjY2Vzc2libGVFZGl0YWJsZVRleHRQYXJhJiwgdm9pZCA+CiAgICB7CiAgICBwdWJsaWM6CiAgICAgICAgdm9pZCBvcGVyYXRvcigpKCA6OmFjY2Vzc2liaWxpdHk6OkFjY2Vzc2libGVFZGl0YWJsZVRleHRQYXJhJiByUGFyYSApCiAgICAgICAgewogICAgICAgICAgICByUGFyYS5UZXh0Q2hhbmdlZCgpOwogICAgICAgIH0KICAgIH07CgoJLyoqIGZ1bmN0b3IgcHJvY2Vzc2luZyBxdWV1ZSBldmVudHMKCiAgICAJUmVhY3RzIG9uIFRFWFRfSElOVF9QQVJBSU5TRVJURUQvUkVNT1ZFRCBldmVudHMgYW5kIHN0b3JlcwogICAgCXRoZWlyIGNvbnRlbnQKICAgICAqLwogICAgY2xhc3MgQWNjZXNzaWJsZVRleHRIZWxwZXJfUXVldWVGdW5jdG9yIDogcHVibGljIDo6c3RkOjp1bmFyeV9mdW5jdGlvbjwgY29uc3QgU2Z4SGludCosIHZvaWQgPgogICAgewogICAgcHVibGljOgogICAgICAgIEFjY2Vzc2libGVUZXh0SGVscGVyX1F1ZXVlRnVuY3RvcigpIDoKICAgICAgICAgICAgbW5QYXJhc0NoYW5nZWQoIDAgKSwKICAgICAgICAgICAgbW5QYXJhSW5kZXgoLTEpLAogICAgICAgICAgICBtbkhpbnRJZCgtMSkKICAgICAgICB7fQogICAgICAgIHZvaWQgb3BlcmF0b3IoKSggY29uc3QgU2Z4SGludCogcEV2ZW50ICkKICAgICAgICB7CiAgICAgICAgICAgIGlmKCBwRXZlbnQgJiYKICAgICAgICAgICAgICAgIG1uUGFyYXNDaGFuZ2VkICE9IC0xICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIGhpbnQgdHlwZQogICAgICAgICAgICAgICAgY29uc3QgVGV4dEhpbnQqIHBUZXh0SGludCA9IFBUUl9DQVNUKCBUZXh0SGludCwgcEV2ZW50ICk7CiAgICAgICAgICAgICAgICBjb25zdCBTdnhFZGl0U291cmNlSGludCogcEVkaXRTb3VyY2VIaW50ID0gUFRSX0NBU1QoIFN2eEVkaXRTb3VyY2VIaW50LCBwRXZlbnQgKTsKCiAgICAgICAgICAgICAgICBpZiggIXBFZGl0U291cmNlSGludCAmJiBwVGV4dEhpbnQgJiYKICAgICAgICAgICAgICAgICAgICAocFRleHRIaW50LT5HZXRJZCgpID09IFRFWFRfSElOVF9QQVJBSU5TRVJURUQgfHwKICAgICAgICAgICAgICAgICAgICAgcFRleHRIaW50LT5HZXRJZCgpID09IFRFWFRfSElOVF9QQVJBUkVNT1ZFRCApICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiggcFRleHRIaW50LT5HZXRWYWx1ZSgpID09IEVFX1BBUkFfQUxMICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1uUGFyYXNDaGFuZ2VkID0gLTE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1uSGludElkID0gcFRleHRIaW50LT5HZXRJZCgpOwogICAgICAgICAgICAgICAgICAgICAgICBtblBhcmFJbmRleCA9IHBUZXh0SGludC0+R2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgKyttblBhcmFzQ2hhbmdlZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKiBRdWVyeSBudW1iZXIgb2YgcGFyYWdyYXBocyBjaGFuZ2VkIGR1cmluZyBxdWV1ZSBwcm9jZXNzaW5nLgoKICAgICAgICAJQHJldHVybiBudW1iZXIgb2YgY2hhbmdlZCBwYXJhZ3JhcGhzLCAtMSBmb3IKICAgICAgICAgICAgImV2ZXJ5IHBhcmFncmFwaCBjaGFuZ2VkIgogICAgICAgICovCiAgICAgICAgaW50IEdldE51bWJlck9mUGFyYXNDaGFuZ2VkKCkgeyByZXR1cm4gbW5QYXJhc0NoYW5nZWQ7IH0KICAgICAgICAvKiogUXVlcnkgaW5kZXggb2YgbGFzdCBhZGRlZC9yZW1vdmVkIHBhcmFncmFwaAoKICAgICAgICAJQHJldHVybiBpbmRleCBvZiBsYXN0bHkgYWRkZWQgcGFyYWdyYXBocywgLTEgZm9yIG5vbmUKICAgICAgICAJYWRkZWQgc28gZmFyLgogICAgICAgICovCiAgICAgICAgaW50IEdldFBhcmFJbmRleCgpIHsgcmV0dXJuIG1uUGFyYUluZGV4OyB9CiAgICAgICAgLyoqIFF1ZXJ5IGhpbnQgaWQgb2YgbGFzdCBpbnRlcmVzdGluZyBldmVudAoKICAgICAgICAJQHJldHVybiBoaW50IGlkIG9mIGxhc3QgaW50ZXJlc3RpbmcgZXZlbnQgKFJFTU9WRUQvSU5TRVJURUQpLgogICAgICAgICovCiAgICAgICAgaW50IEdldEhpbnRJZCgpIHsgcmV0dXJuIG1uSGludElkOyB9CgogICAgcHJpdmF0ZToKICAgICAgICAvKiogbnVtYmVyIG9mIHBhcmFncmFwaHMgY2hhbmdlZCBkdXJpbmcgcXVldWUgcHJvY2Vzc2luZy4gLTEgZm9yCiAgICAgICAgICAgICJldmVyeSBwYXJhZ3JhcGggY2hhbmdlZCIKICAgICAgICAqLwogICAgICAgIGludCBtblBhcmFzQ2hhbmdlZDsKICAgICAgICAvLy8gaW5kZXggb2YgcGFyYWdyYXBoIGFkZGVkL3JlbW92ZWQgbGFzdAogICAgICAgIGludCBtblBhcmFJbmRleDsKICAgICAgICAvLy8gVGV4dEhpbnQgSUQgKHJlbW92ZWQvaW5zZXJ0ZWQpIG9mIGxhc3QgaW50ZXJlc3RpbmcgZXZlbnQKICAgICAgICBpbnQgbW5IaW50SWQ7CiAgICB9OwoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6UHJvY2Vzc1F1ZXVlKCkKICAgIHsKICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICAvLyBpbnNwZWN0IHF1ZXVlIGZvciBwYXJhZ3JhcGggaW5zZXJ0L3JlbW92ZSBldmVudHMuIElmIHRoZXJlCiAgICAgICAgLy8gaXMgZXhhY3RseSBfb25lXyBvZiB0aG9zZSBpbiB0aGUgcXVldWUsIGFuZCB0aGUgbnVtYmVyIG9mCiAgICAgICAgLy8gcGFyYWdyYXBocyBoYXMgY2hhbmdlZCBieSBleGFjdGx5IG9uZSwgdXNlIHRoYXQgZXZlbnQgdG8KICAgICAgICAvLyBkZXRlcm1pbmUgYSBwcmlvcmkgd2hpY2ggcGFyYWdyYXBoIHdhcyBhZGRlZC9yZW1vdmVkLiBUaGlzCiAgICAgICAgLy8gaXMgbmVjZXNzYXJ5LCBzaW5jZSBJIG11c3Qgc3luYyByaWdodCBoZXJlIHdpdGggdGhlCiAgICAgICAgLy8gRWRpdEVuZ2luZSBzdGF0ZSAobnVtYmVyIG9mIHBhcmFncmFwaHMgZXRjLiksIHNpbmNlIEknbQogICAgICAgIC8vIHBvdGVudGlhbGx5IHNlbmRpbmcgbGlzdGVuZXIgZXZlbnRzIHJpZ2h0IGF3YXkuCiAgICAgICAgQWNjZXNzaWJsZVRleHRIZWxwZXJfUXVldWVGdW5jdG9yIGFGdW5jdG9yOwogICAgICAgIG1hRXZlbnRRdWV1ZS5Gb3JFYWNoKCBhRnVuY3RvciApOwoKICAgICAgICBjb25zdCBzYWxfSW50MzIgbk5ld1BhcmFzKCBHZXRUZXh0Rm9yd2FyZGVyKCkuR2V0UGFyYWdyYXBoQ291bnQoKSApOwogICAgICAgIGNvbnN0IHNhbF9JbnQzMiBuQ3VyclBhcmFzKCBtYVBhcmFNYW5hZ2VyLkdldE51bSgpICk7CgogICAgICAgIC8vIHdoZXRoZXIgZXZlcnkgcGFyYWdyYXBoIGFscmVhZHkgaXMgdXBkYXRlZCAobm8gbmVlZCB0bwogICAgICAgIC8vIHJlcGVhdCB0aGF0IGxhdGVyIG9uLCBlLmcuIGZvciBQQVJBX01PVkVEIGV2ZW50cykKICAgICAgICBib29sCQkJYkV2ZXJ5dGhpbmdVcGRhdGVkKCBmYWxzZSApOwoKICAgICAgICBpZiggbGFicyggbk5ld1BhcmFzIC0gbkN1cnJQYXJhcyApID09IDEgJiYKICAgICAgICAgICAgYUZ1bmN0b3IuR2V0TnVtYmVyT2ZQYXJhc0NoYW5nZWQoKSA9PSAxICkKICAgICAgICB7CiAgICAgICAgICAgIC8vICMxMDM0ODMjIEV4YWN0bHkgb25lIHBhcmFncmFwaCBhZGRlZC9yZW1vdmVkLiBUaGlzIGlzCiAgICAgICAgICAgIC8vIHRoZSBub3JtYWwgY2FzZSwgb3B0aW1pemUgZXZlbnQgaGFuZGxpbmcgaGVyZS4KCiAgICAgICAgICAgIGlmKCBhRnVuY3Rvci5HZXRIaW50SWQoKSA9PSBURVhUX0hJTlRfUEFSQUlOU0VSVEVEICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gdXBkYXRlIG51bSBvZiBwYXJhcwogICAgICAgICAgICAgICAgbWFQYXJhTWFuYWdlci5TZXROdW0oIG5OZXdQYXJhcyApOwoKICAgICAgICAgICAgICAgIC8vIHJlbGVhc2UgZXZlcnl0aGluZyBmcm9tIHRoZSBpbnNlcnRpb24gcG9zaXRpb24gdW50aWwgdGhlIGVuZAogICAgICAgICAgICAgICAgbWFQYXJhTWFuYWdlci5SZWxlYXNlKGFGdW5jdG9yLkdldFBhcmFJbmRleCgpLCBuQ3VyclBhcmFzKTsKCiAgICAgICAgICAgICAgICAvLyBUT0RPOiBDbGFyaWZ5IHdoZXRoZXIgdGhpcyBiZWhhdmlvdXIgX3JlYWxseV8gc2F2ZXMKICAgICAgICAgICAgICAgIC8vIGFueWJvZHkgYW55dGhpbmchCiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgY2hpbGRyZW4sIF9kb24ndF8gYnJvYWRjYXN0CiAgICAgICAgICAgICAgICBVcGRhdGVWaXNpYmxlQ2hpbGRyZW4oIGZhbHNlICk7CiAgICAgICAgICAgICAgICBVcGRhdGVCb3VuZFJlY3QoKTsKCiAgICAgICAgICAgICAgICAvLyBzZW5kIGluc2VydCBldmVudAogICAgICAgICAgICAgICAgLy8gIzEwOTg2NCMgRW5mb3JjZSBjcmVhdGlvbiBvZiB0aGlzIHBhcmFncmFwaAogICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgR290UHJvcGVydHlFdmVudCggdW5vOjptYWtlQW55KCBnZXRBY2Nlc3NpYmxlQ2hpbGQoIGFGdW5jdG9yLkdldFBhcmFJbmRleCgpIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW5GaXJzdFZpc2libGVDaGlsZCArIEdldFN0YXJ0SW5kZXgoKSApICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWNjZXNzaWJsZUV2ZW50SWQ6OkNISUxEICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCggY29uc3QgdW5vOjpFeGNlcHRpb24mICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBEQkdfRVJST1IoIkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OlByb2Nlc3NRdWV1ZTogY291bGQgbm90IGNyZWF0ZSBuZXcgcGFyYWdyYXBoIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiggYUZ1bmN0b3IuR2V0SGludElkKCkgPT0gVEVYVF9ISU5UX1BBUkFSRU1PVkVEICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OlZlY3Rvck9mQ2hpbGRyZW46OmNvbnN0X2l0ZXJhdG9yIGJlZ2luID0gbWFQYXJhTWFuYWdlci5iZWdpbigpOwogICAgICAgICAgICAgICAgOjpzdGQ6OmFkdmFuY2UoIGJlZ2luLCBhRnVuY3Rvci5HZXRQYXJhSW5kZXgoKSApOwogICAgICAgICAgICAgICAgOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OlZlY3Rvck9mQ2hpbGRyZW46OmNvbnN0X2l0ZXJhdG9yIGVuZCA9IGJlZ2luOwogICAgICAgICAgICAgICAgOjpzdGQ6OmFkdmFuY2UoIGVuZCwgMSApOwoKCQkJCS8vICNpNjE4MTIjIHJlbWVtYmVyIHBhcmEgdG8gYmUgcmVtb3ZlZCBmb3IgbGF0ZXIgbm90aWZpY2F0aW9uCgkJCQkvLyBBRlRFUiB0aGUgbmV3IHN0YXRlIGlzIGFwcGxpZWQgKHRoYXQgYWZ0ZXIgdGhlIHBhcmEgZ290IHJlbW92ZWQpCgkJCQk6OnVubzo6UmVmZXJlbmNlPCBYQWNjZXNzaWJsZSA+IHhQYXJhOwoJCQkJOjphY2Nlc3NpYmlsaXR5OjpBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OldlYWtQYXJhOjpIYXJkUmVmVHlwZSBhSGFyZFJlZiggYmVnaW4tPmZpcnN0LmdldCgpICk7CgkJCQlpZiggYUhhcmRSZWYuaXMoKSApCgkJCQkJeFBhcmEgPSA6OnVubzo6UmVmZXJlbmNlPCBYQWNjZXNzaWJsZSA+KCBhSGFyZFJlZi5nZXRSZWYoKSwgOjp1bm86OlVOT19RVUVSWSApOwoKICAgICAgICAgICAgICAgIC8vIHJlbGVhc2UgZXZlcnl0aGluZyBmcm9tIHRoZSByZW1vdmUgcG9zaXRpb24gdW50aWwgdGhlIGVuZAogICAgICAgICAgICAgICAgbWFQYXJhTWFuYWdlci5SZWxlYXNlKGFGdW5jdG9yLkdldFBhcmFJbmRleCgpLCBuQ3VyclBhcmFzKTsKCiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgbnVtIG9mIHBhcmFzCiAgICAgICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLlNldE51bSggbk5ld1BhcmFzICk7CgogICAgICAgICAgICAgICAgLy8gVE9ETzogQ2xhcmlmeSB3aGV0aGVyIHRoaXMgYmVoYXZpb3VyIF9yZWFsbHlfIHNhdmVzCiAgICAgICAgICAgICAgICAvLyBhbnlib2R5IGFueXRoaW5nIQogICAgICAgICAgICAgICAgLy8gdXBkYXRlIGNoaWxkcmVuLCBfZG9uJ3RfIGJyb2FkY2FzdAogICAgICAgICAgICAgICAgVXBkYXRlVmlzaWJsZUNoaWxkcmVuKCBmYWxzZSApOwogICAgICAgICAgICAgICAgVXBkYXRlQm91bmRSZWN0KCk7CgoJCQkJLy8gI2k2MTgxMiMgbm90aWZpY2F0aW9uIGZvciByZW1vdmVkIHBhcmEKCQkJCWlmICh4UGFyYS5pcygpKQoJICAgICAgICAgICAgCUZpcmVFdmVudChBY2Nlc3NpYmxlRXZlbnRJZDo6Q0hJTEQsIHVubzo6QW55KCksIHVubzo6bWFrZUFueSggeFBhcmEpICk7CiAgICAgICAgICAgIH0KI2lmZGVmIERCR19VVElMCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIERCR19FUlJPUigiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6UHJvY2Vzc1F1ZXVlKCkgaW52YWxpZCBoaW50IGlkIik7CiNlbmRpZgogICAgICAgIH0KICAgICAgICBlbHNlIGlmKCBuTmV3UGFyYXMgIT0gbkN1cnJQYXJhcyApCiAgICAgICAgewogICAgICAgICAgICAvLyByZWxlYXNlIGFsbCBwYXJhcwogICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLlJlbGVhc2UoMCwgbkN1cnJQYXJhcyk7CgogICAgICAgICAgICAvLyB1cGRhdGUgbnVtIG9mIHBhcmFzCiAgICAgICAgICAgIG1hUGFyYU1hbmFnZXIuU2V0TnVtKCBuTmV3UGFyYXMgKTsKCiAgICAgICAgICAgIC8vICMxMDk4NjQjIGNyZWF0ZSBmcm9tIHNjcmF0Y2gsIGRvbid0IGJyb2FkY2FzdAogICAgICAgICAgICBVcGRhdGVWaXNpYmxlQ2hpbGRyZW4oIGZhbHNlICk7CiAgICAgICAgICAgIFVwZGF0ZUJvdW5kUmVjdCgpOwoKICAgICAgICAgICAgLy8gbnVtYmVyIG9mIHBhcmFncmFwaHMgc29tZWhvdyBjaGFuZ2VkIC0gYnV0IHdlIGhhdmUgbm8KICAgICAgICAgICAgLy8gY2hhbmNlIGRldGVybWluaW5nIGhvdy4gVGh1cywgdGhyb3cgYXdheSBldmVyeXRoaW5nIGFuZAogICAgICAgICAgICAvLyBjcmVhdGUgZnJvbSBzY3JhdGNoLgoJCQkvLyAoY2hpbGQgZXZlbnRzIHNob3VsZCBiZSBicm9hZGNhc3QgYWZ0ZXIgdGhlIGNoYW5nZXMgYXJlIGRvbmUuLi4pCiAgICAgICAgICAgIEZpcmVFdmVudChBY2Nlc3NpYmxlRXZlbnRJZDo6SU5WQUxJREFURV9BTExfQ0hJTERSRU4pOwoKICAgICAgICAgICAgLy8gbm8gbmVlZCBmb3IgZnVydGhlciB1cGRhdGVzIGxhdGVyIG9uCiAgICAgICAgICAgIGJFdmVyeXRoaW5nVXBkYXRlZCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICB3aGlsZSggIW1hRXZlbnRRdWV1ZS5Jc0VtcHR5KCkgKQogICAgICAgIHsKICAgICAgICAgICAgOjpzdGQ6OmF1dG9fcHRyPCBTZnhIaW50ID4gcEhpbnQoIG1hRXZlbnRRdWV1ZS5Qb3BGcm9udCgpICk7CiAgICAgICAgICAgIGlmKCBwSGludC5nZXQoKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IFNmeEhpbnQmIHJIaW50ID0gKihwSGludC5nZXQoKSk7CgogICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5lIGhpbnQgdHlwZQogICAgICAgICAgICAgICAgY29uc3QgU2RySGludCogcFNkckhpbnQgPSBQVFJfQ0FTVCggU2RySGludCwgJnJIaW50ICk7CiAgICAgICAgICAgICAgICBjb25zdCBTZnhTaW1wbGVIaW50KiBwU2ltcGxlSGludCA9IFBUUl9DQVNUKCBTZnhTaW1wbGVIaW50LCAmckhpbnQgKTsKICAgICAgICAgICAgICAgIGNvbnN0IFRleHRIaW50KiBwVGV4dEhpbnQgPSBQVFJfQ0FTVCggVGV4dEhpbnQsICZySGludCApOwogICAgICAgICAgICAgICAgY29uc3QgU3Z4Vmlld0hpbnQqIHBWaWV3SGludCA9IFBUUl9DQVNUKCBTdnhWaWV3SGludCwgJnJIaW50ICk7CiAgICAgICAgICAgICAgICBjb25zdCBTdnhFZGl0U291cmNlSGludCogcEVkaXRTb3VyY2VIaW50ID0gUFRSX0NBU1QoIFN2eEVkaXRTb3VyY2VIaW50LCAmckhpbnQgKTsKCiAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBzYWxfSW50MzIgblBhcmFzID0gR2V0VGV4dEZvcndhcmRlcigpLkdldFBhcmFncmFwaENvdW50KCk7CgogICAgICAgICAgICAgICAgICAgIGlmKCBwRWRpdFNvdXJjZUhpbnQgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoKCBwRWRpdFNvdXJjZUhpbnQtPkdldElkKCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVESVRTT1VSQ0VfSElOVF9QQVJBU01PVkVEOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERCR19BU1NFUlQoIHBFZGl0U291cmNlSGludC0+R2V0U3RhcnRWYWx1ZSgpIDwgR2V0VGV4dEZvcndhcmRlcigpLkdldFBhcmFncmFwaENvdW50KCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRWRpdFNvdXJjZUhpbnQtPkdldEVuZFZhbHVlKCkgPCBHZXRUZXh0Rm9yd2FyZGVyKCkuR2V0UGFyYWdyYXBoQ291bnQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6Tm90aWZ5SGRsOiBJbnZhbGlkIG5vdGlmaWNhdGlvbiIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggIWJFdmVyeXRoaW5nVXBkYXRlZCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJhZ3JhcGhzTW92ZWQocEVkaXRTb3VyY2VIaW50LT5HZXRTdGFydFZhbHVlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRWRpdFNvdXJjZUhpbnQtPkdldFZhbHVlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRWRpdFNvdXJjZUhpbnQtPkdldEVuZFZhbHVlKCkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gYWxsIGNhc2VzLCBjaGVjayB2aXNpYmlsaXR5IGFmdGVyd2FyZHMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVwZGF0ZVZpc2libGVDaGlsZHJlbigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVESVRTT1VSQ0VfSElOVF9TRUxFQ1RJT05DSEFOR0VEOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdGlmeSBsaXN0ZW5lcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVwZGF0ZVNlbGVjdGlvbigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYXliZSB3ZSdyZSBub3QgaW4gZWRpdCBtb2RlICh0aGlzIGlzIG5vdCBhbiBlcnJvcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCggY29uc3QgdW5vOjpFeGNlcHRpb24mICkge30KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKCBwVGV4dEhpbnQgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoKCBwVGV4dEhpbnQtPkdldElkKCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRFWFRfSElOVF9NT0RJRklFRDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3RpZnkgbGlzdGVuZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsX0ludDMyIG5QYXJhKCBwVGV4dEhpbnQtPkdldFZhbHVlKCkgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIzEwODkwMCMgRGVsZWdhdGUgY2hhbmdlIGV2ZW50IHRvIGNoaWxkcmVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWNjZXNzaWJsZVRleHRIZWxwZXJfQ2hpbGRyZW5UZXh0Q2hhbmdlZCBhTm90aWZ5Q2hpbGRyZW5GdW5jdG9yOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggblBhcmEgPT0gc3RhdGljX2Nhc3Q8c2FsX0ludDMyPihFRV9QQVJBX0FMTCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIzEwODkwMCMgQ2FsbCBldmVyeSBjaGlsZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnN0ZDo6Zm9yX2VhY2goIG1hUGFyYU1hbmFnZXIuYmVnaW4oKSwgbWFQYXJhTWFuYWdlci5lbmQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY2Nlc3NpYmxlUGFyYU1hbmFnZXI6OldlYWtDaGlsZEFkYXB0ZXI8IEFjY2Vzc2libGVUZXh0SGVscGVyX0NoaWxkcmVuVGV4dENoYW5nZWQgPiAoYU5vdGlmeUNoaWxkcmVuRnVuY3RvcikgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggblBhcmEgPCBuUGFyYXMgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAjMTA4OTAwIyBDYWxsIGNoaWxkIGF0IGluZGV4IG5QYXJhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnN0ZDo6Zm9yX2VhY2goIG1hUGFyYU1hbmFnZXIuYmVnaW4oKStuUGFyYSwgbWFQYXJhTWFuYWdlci5iZWdpbigpK25QYXJhKzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjY2Vzc2libGVQYXJhTWFuYWdlcjo6V2Vha0NoaWxkQWRhcHRlcjwgQWNjZXNzaWJsZVRleHRIZWxwZXJfQ2hpbGRyZW5UZXh0Q2hhbmdlZCA+IChhTm90aWZ5Q2hpbGRyZW5GdW5jdG9yKSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBURVhUX0hJTlRfUEFSQUlOU0VSVEVEOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgaGFwcGVuZWQgYWJvdmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFRFWFRfSElOVF9QQVJBUkVNT1ZFRDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IGhhcHBlbmVkIGFib3ZlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBURVhUX0hJTlRfVEVYVEhFSUdIVENIQU5HRUQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmlzaWJpbGl0eSBjaGFuZ2VkLCBkb25lIGJlbG93CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBURVhUX0hJTlRfVklFV1NDUk9MTEVEOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHZpc2liaWxpdHkgY2hhbmdlZCwgZG9uZSBiZWxvdwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiBhbGwgY2FzZXMsIGNoZWNrIHZpc2liaWxpdHkgYWZ0ZXJ3YXJkcy4KICAgICAgICAgICAgICAgICAgICAgICAgVXBkYXRlVmlzaWJsZUNoaWxkcmVuKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFVwZGF0ZUJvdW5kUmVjdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKCBwVmlld0hpbnQgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoKCBwVmlld0hpbnQtPkdldEhpbnRUeXBlKCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFN2eFZpZXdIaW50OjpTVlhfSElOVF9WSUVXQ0hBTkdFRDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBqdXN0IGNoZWNrIHZpc2liaWxpdHkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVcGRhdGVWaXNpYmxlQ2hpbGRyZW4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVcGRhdGVCb3VuZFJlY3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKCBwU2RySGludCApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2goIHBTZHJIaW50LT5HZXRLaW5kKCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEhJTlRfQkVHRURJVDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKCQkJCQkJCQlpZighSXNBY3RpdmUoKSkKCQkJCQkJCQl7CgkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2UgY2hpbGRyZW4gc3RhdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLlNldEFjdGl2ZSgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwZXIgZGVmaW5pdGlvbiwgZWRpdCBtb2RlIHRleHQgaGFzIHRoZSBmb2N1cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldEZvY3VzKCBzYWxfVHJ1ZSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSElOVF9FTkRFRElUOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvY3VzZWQgY2hpbGQgbm93IGxvb3NlcyBmb2N1cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVTZWxlY3Rpb24gYVNlbGVjdGlvbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiggR2V0RWRpdFZpZXdGb3J3YXJkZXIoKS5HZXRTZWxlY3Rpb24oIGFTZWxlY3Rpb24gKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldENoaWxkRm9jdXMoIGFTZWxlY3Rpb24ubkVuZFBhcmEsIHNhbF9GYWxzZSApOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2UgY2hpbGRyZW4gc3RhdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYVBhcmFNYW5hZ2VyLlNldEFjdGl2ZSggc2FsX0ZhbHNlICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hTGFzdFNlbGVjdGlvbiA9IEVTZWxlY3Rpb24oIEVFX1BBUkFfTk9UX0ZPVU5ELCBFRV9QQVJBX05PVF9GT1VORCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFRV9QQVJBX05PVF9GT1VORCwgRUVfUEFSQV9OT1RfRk9VTkQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBpdCdzIFZJVEFMIHRvIGtlZXAgdGhlIFNmeFNpbXBsZUhpbnQgbGFzdCEgSXQncyB0aGUgYmFzZSBvZiBzb21lIGNsYXNzZXMgYWJvdmUhCiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiggcFNpbXBsZUhpbnQgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoKCBwU2ltcGxlSGludC0+R2V0SWQoKSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU0ZYX0hJTlRfRFlJTkc6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWRpdCBzb3VyY2UgaXMgZHlpbmcgdW5kZXIgdXMsIGJlY29tZSBkZWZ1bmMgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFrZSBlZGl0IHNvdXJjZSBpbmFjY2Vzc2libGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZTogY2Fubm90IGRlc3Ryb3kgaXQgaGVyZSwgc2luY2Ugd2UncmUgY2FsbGVkIGZyb20gdGhlcmUhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNodXRkb3duRWRpdFNvdXJjZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCggY29uc3QgdW5vOjpFeGNlcHRpb24mICkge30KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCggY29uc3QgdW5vOjpFeGNlcHRpb24mICkKICAgICAgICAgICAgICAgIHsKI2lmZGVmIERCR19VVElMCiAgICAgICAgICAgICAgICAgICAgT1NMX1RSQUNFKCJBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpQcm9jZXNzUXVldWU6IFVuaGFuZGxlZCBleGNlcHRpb24uIik7CiNlbmRpZgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6Tm90aWZ5KCBTZnhCcm9hZGNhc3RlciYgLypyQkMqLywgY29uc3QgU2Z4SGludCYgckhpbnQgKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIC8vIHByZWNvbmRpdGlvbjogc29sYXIgbXV0ZXggbG9ja2VkCiAgICAgICAgREJHX1RFU1RTT0xBUk1VVEVYKCk7CgogICAgICAgIC8vIHByZWNvbmRpdGlvbjogbm90IGluIGEgcmVjdXJzaW9uCiAgICAgICAgaWYoIG1iSW5Ob3RpZnkgKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIG1iSW5Ob3RpZnkgPSBzYWxfVHJ1ZTsKCiAgICAgICAgLy8gZGV0ZXJtaW5lIGhpbnQgdHlwZQogICAgICAgIGNvbnN0IFNkckhpbnQqIHBTZHJIaW50ID0gUFRSX0NBU1QoIFNkckhpbnQsICZySGludCApOwogICAgICAgIGNvbnN0IFNmeFNpbXBsZUhpbnQqIHBTaW1wbGVIaW50ID0gUFRSX0NBU1QoIFNmeFNpbXBsZUhpbnQsICZySGludCApOwogICAgICAgIGNvbnN0IFRleHRIaW50KiBwVGV4dEhpbnQgPSBQVFJfQ0FTVCggVGV4dEhpbnQsICZySGludCApOwogICAgICAgIGNvbnN0IFN2eFZpZXdIaW50KiBwVmlld0hpbnQgPSBQVFJfQ0FTVCggU3Z4Vmlld0hpbnQsICZySGludCApOwogICAgICAgIGNvbnN0IFN2eEVkaXRTb3VyY2VIaW50KiBwRWRpdFNvdXJjZUhpbnQgPSBQVFJfQ0FTVCggU3Z4RWRpdFNvdXJjZUhpbnQsICZySGludCApOwoKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFByb2Nlc3Mgbm90aWZpY2F0aW9uIGV2ZW50CiAgICAgICAgICAgIGlmKCBwRWRpdFNvdXJjZUhpbnQgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtYUV2ZW50UXVldWUuQXBwZW5kKCAqcEVkaXRTb3VyY2VIaW50ICk7CiAgICAgICAgICAgICAgICAvLyAtLT4gT0QgMjAwNS0xMi0xOSAjaTI3Mjk5IwogICAgICAgICAgICAgICAgaWYoIG1hRXZlbnRPcGVuRnJhbWVzID09IDAgKQogICAgICAgICAgICAgICAgICAgIFByb2Nlc3NRdWV1ZSgpOwogICAgICAgICAgICAgICAgLy8gPC0tCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiggcFRleHRIaW50ICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3dpdGNoKCBwVGV4dEhpbnQtPkdldElkKCkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhc2UgVEVYVF9ISU5UX0JMT0NLTk9USUZJQ0FUSU9OX0VORDoKICAgICAgICAgICAgICAgICAgICBjYXNlIFRFWFRfSElOVF9JTlBVVF9FTkQ6CiAgICAgICAgICAgICAgICAgICAgICAgIC0tbWFFdmVudE9wZW5GcmFtZXM7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiggbWFFdmVudE9wZW5GcmFtZXMgPT0gMCApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICMxMDM0ODMjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBBbGwgaW5mb3JtYXRpb24gc2hvdWxkIGhhdmUgYXJyaXZlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogbm93LCBwcm9jZXNzIHF1ZXVlLiBBcyBzdGF0ZWQgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBhYm92ZSBidWcsIHdlIGNhbiBvZnRlbiBhdm9pZCB0aHJvd2luZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogYXdheSBhbGwgcGFyYWdyYXBocyBieSBsb29raW5nIGZvcndhcmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGluIHRoZSBldmVudCBxdWV1ZSAoc2VhcmNoaW5nIGZvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogUEFSQUlOU0VSVC9SRU1PVkUgZXZlbnRzKS4gRnVydGhlcm1vcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBwcm9jZXNzaW5nIHRoZSBldmVudCBxdWV1ZSBvbmx5IGF0IHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogZW5kIG9mIGFuIGludGVyYWN0aW9uIGN5Y2xlLCBlbnN1cmVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB0aGF0IHRoZSBFZGl0RW5naW5lIHN0YXRlIGFuZCB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIEFjY2Vzc2libGVUZXh0IHN0YXRlIGFyZSB0aGUgc2FtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKHdlbGwsIG1vc3RseS4gSWYgdGhlcmUgYXJlIF9tdWx0aXBsZV8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGludGVyYWN0aW9uIGN5Y2xlcyBpbiB0aGUgRUUgcXVldWVzLCBpdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogY2FuIHN0aWxsIGhhcHBlbiB0aGF0IEVFIHN0YXRlIGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBkaWZmZXJlbnQuIFRoYXQncyBzbyB0byBzYXkgYnJva2VuIGJ5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBkZXNpZ24gd2l0aCB0aGF0IGRlbGF5ZWQgRUUgZXZlbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGNvbmNlcHQpLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9jZXNzUXVldWUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSBURVhUX0hJTlRfQkxPQ0tOT1RJRklDQVRJT05fU1RBUlQ6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBURVhUX0hJTlRfSU5QVVRfU1RBUlQ6CiAgICAgICAgICAgICAgICAgICAgICAgICsrbWFFdmVudE9wZW5GcmFtZXM7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC0tPiBPRCAyMDA1LTEyLTE5ICNpMjcyOTkjIC0gbm8gRkFMTFRST1VHSAogICAgICAgICAgICAgICAgICAgICAgICAvLyByZWFzb246IGV2ZW50IHdpbGwgbm90IGJlIHByb2Nlc3NlcywgdGh1cyBhcHBlbmRpbmcKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGV2ZW50IGlzbid0IG5lY2Vzc2FyeS4KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtLQogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIG1hRXZlbnRRdWV1ZS5BcHBlbmQoICpwVGV4dEhpbnQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gLS0+IE9EIDIwMDUtMTItMTkgI2kyNzI5OSMKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIG1hRXZlbnRPcGVuRnJhbWVzID09IDAgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvY2Vzc1F1ZXVlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtLQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKCBwVmlld0hpbnQgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtYUV2ZW50UXVldWUuQXBwZW5kKCAqcFZpZXdIaW50ICk7CgogICAgICAgICAgICAgICAgLy8gcHJvY2VzcyB2aXNpYmlsaXR5IHJpZ2h0IGF3YXksIGlmIG5vdCB3aXRoaW4gYW4KICAgICAgICAgICAgICAgIC8vIG9wZW4gRUUgbm90aWZpY2F0aW9uIGZyYW1lLiBPdGhlcndpc2UsIGV2ZW50CiAgICAgICAgICAgICAgICAvLyBwcm9jZXNzaW5nIHdvdWxkIGJlIGRlbGF5ZWQgdW50aWwgbmV4dCBFRQogICAgICAgICAgICAgICAgLy8gbm90aWZpY2F0aW9uIHNlcXVlbmNlLgogICAgICAgICAgICAgICAgaWYoIG1hRXZlbnRPcGVuRnJhbWVzID09IDAgKQogICAgICAgICAgICAgICAgICAgIFByb2Nlc3NRdWV1ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoIHBTZHJIaW50ICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbWFFdmVudFF1ZXVlLkFwcGVuZCggKnBTZHJIaW50ICk7CgogICAgICAgICAgICAgICAgLy8gcHJvY2VzcyBkcmF3aW5nIGxheWVyIGV2ZW50cyByaWdodCBhd2F5LCBpZiBub3QKICAgICAgICAgICAgICAgIC8vIHdpdGhpbiBhbiBvcGVuIEVFIG5vdGlmaWNhdGlvbiBmcmFtZS4gT3RoZXJ3aXNlLAogICAgICAgICAgICAgICAgLy8gZXZlbnQgcHJvY2Vzc2luZyB3b3VsZCBiZSBkZWxheWVkIHVudGlsIG5leHQgRUUKICAgICAgICAgICAgICAgIC8vIG5vdGlmaWNhdGlvbiBzZXF1ZW5jZS4KICAgICAgICAgICAgICAgIGlmKCBtYUV2ZW50T3BlbkZyYW1lcyA9PSAwICkKICAgICAgICAgICAgICAgICAgICBQcm9jZXNzUXVldWUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBpdCdzIFZJVEFMIHRvIGtlZXAgdGhlIFNmeFNpbXBsZUhpbnQgbGFzdCEgSXQncyB0aGUgYmFzZSBvZiBzb21lIGNsYXNzZXMgYWJvdmUhCiAgICAgICAgICAgIGVsc2UgaWYoIHBTaW1wbGVIaW50ICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gaGFuZGxlIHRoaXMgZXZlbnQgX2F0IG9uY2VfLCBiZWNhdXNlIGFmdGVyIHRoYXQsIG9iamVjdHMgYXJlIGludmFsaWQKICAgICAgICAgICAgICAgIHN3aXRjaCggcFNpbXBsZUhpbnQtPkdldElkKCkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhc2UgU0ZYX0hJTlRfRFlJTkc6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVkaXQgc291cmNlIGlzIGR5aW5nIHVuZGVyIHVzLCBiZWNvbWUgZGVmdW5jIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgbWFFdmVudFF1ZXVlLkNsZWFyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIGVkaXQgc291cmNlIGluYWNjZXNzaWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTm90ZTogY2Fubm90IGRlc3Ryb3kgaXQgaGVyZSwgc2luY2Ugd2UncmUgY2FsbGVkIGZyb20gdGhlcmUhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaHV0ZG93bkVkaXRTb3VyY2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCggY29uc3QgdW5vOjpFeGNlcHRpb24mICkge30KCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNhdGNoKCBjb25zdCB1bm86OkV4Y2VwdGlvbiYgKQogICAgICAgIHsKI2lmZGVmIERCR19VVElMCiAgICAgICAgICAgIE9TTF9UUkFDRSgiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6Tm90aWZ5OiBVbmhhbmRsZWQgZXhjZXB0aW9uLiIpOwojZW5kaWYKICAgICAgICAgICAgbWJJbk5vdGlmeSA9IHNhbF9GYWxzZTsKICAgICAgICB9CgogICAgICAgIG1iSW5Ob3RpZnkgPSBzYWxfRmFsc2U7CiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpEaXNwb3NlKCkKICAgIHsKICAgICAgICBEQkdfQ0hLVEhJUyggQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbCwgTlVMTCApOwoKICAgICAgICBpZiggZ2V0Tm90aWZpZXJDbGllbnRJZCgpICE9IC0xICkKICAgICAgICB7CiAgICAgICAgICAgIHRyeQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyAjMTA2MjM0IyBVbnJlZ2lzdGVyIGZyb20gRXZlbnROb3RpZmllcgogICAgICAgICAgICAgICAgOjpjb21waGVscGVyOjpBY2Nlc3NpYmxlRXZlbnROb3RpZmllcjo6cmV2b2tlQ2xpZW50KCBnZXROb3RpZmllckNsaWVudElkKCkgKTsKI2lmZGVmIERCR19VVElMCiAgICAgICAgICAgICAgICBPU0xfVFJBQ0UoICJBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsIGRpc3Bvc2VkIElEOiAlZCIsIG1uTm90aWZpZXJDbGllbnRJZCApOwojZW5kaWYKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCggY29uc3QgdW5vOjpFeGNlcHRpb24mICkge30KCiAgICAgICAgICAgIG1uTm90aWZpZXJDbGllbnRJZCA9IC0xOwogICAgICAgIH0KCiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICAvLyBkaXNwb3NlIGNoaWxkcmVuCiAgICAgICAgICAgIG1hUGFyYU1hbmFnZXIuRGlzcG9zZSgpOwogICAgICAgIH0KICAgICAgICBjYXRjaCggY29uc3QgdW5vOjpFeGNlcHRpb24mICkge30KCiAgICAgICAgLy8gcXVpdCBsaXN0ZW4gb24gc3RhbGUgZWRpdCBzb3VyY2UKICAgICAgICBpZiggbWFFZGl0U291cmNlLklzVmFsaWQoKSApCiAgICAgICAgICAgIEVuZExpc3RlbmluZyggbWFFZGl0U291cmNlLkdldEJyb2FkY2FzdGVyKCkgKTsKCiAgICAgICAgLy8gY2xlYXIgcmVmZXJlbmNlcwogICAgICAgIG1hRWRpdFNvdXJjZS5TZXRFZGl0U291cmNlKCA6OnN0ZDo6YXV0b19wdHI8IFN2eEVkaXRTb3VyY2UgPihOVUxMKSApOwogICAgICAgIG14RnJvbnRFbmQgPSBOVUxMOwogICAgfQoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6RmlyZUV2ZW50KCBjb25zdCBzYWxfSW50MTYgbkV2ZW50SWQsIGNvbnN0IHVubzo6QW55JiByTmV3VmFsdWUsIGNvbnN0IHVubzo6QW55JiByT2xkVmFsdWUgKSBjb25zdAogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgoJCS8vIC0tIG9iamVjdCBsb2NrZWQgLS0KICAgICAgICA6Om9zbDo6Q2xlYXJhYmxlTXV0ZXhHdWFyZCBhR3VhcmQoIG1hTXV0ZXggKTsKCiAgICAgICAgQWNjZXNzaWJsZUV2ZW50T2JqZWN0IGFFdmVudDsKCiAgICAgICAgREJHX0FTU0VSVChteEZyb250RW5kLmlzKCksICJBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6RmlyZUV2ZW50OiBubyBldmVudCBzb3VyY2Ugc2V0IiApOwoKICAgICAgICBpZiggbXhGcm9udEVuZC5pcygpICkKICAgICAgICAgICAgYUV2ZW50ID0gQWNjZXNzaWJsZUV2ZW50T2JqZWN0KG14RnJvbnRFbmQtPmdldEFjY2Vzc2libGVDb250ZXh0KCksIG5FdmVudElkLCByTmV3VmFsdWUsIHJPbGRWYWx1ZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBhRXZlbnQgPSBBY2Nlc3NpYmxlRXZlbnRPYmplY3QodW5vOjpSZWZlcmVuY2U8IHVubzo6WEludGVyZmFjZSA+KCksIG5FdmVudElkLCByTmV3VmFsdWUsIHJPbGRWYWx1ZSk7CgogICAgICAgIC8vIG5vIGxvY2tpbmcgbmVjZXNzYXJ5LCBGaXJlRXZlbnQgaW50ZXJuYWxseSBjb3BpZXMgbGlzdGVuZXJzCiAgICAgICAgLy8gaWYgc29tZW9uZSByZW1vdmVzL2FkZHMgaW4gYmV0d2VlbiBGdXJ0aGVyIGxvY2tpbmcsCiAgICAgICAgLy8gYWN0dWFsbHksIG1pZ2h0IGxlYWQgdG8gZGVhZGxvY2tzLCBzaW5jZSB3ZSdyZSBjYWxsaW5nIG91dAogICAgICAgIC8vIG9mIHRoaXMgb2JqZWN0CiAgICAgICAgYUd1YXJkLmNsZWFyKCk7CgkJLy8gLS0gdW50aWwgaGVyZSAtLQoKICAgICAgICBGaXJlRXZlbnQoYUV2ZW50KTsKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OkZpcmVFdmVudCggY29uc3QgQWNjZXNzaWJsZUV2ZW50T2JqZWN0JiByRXZlbnQgKSBjb25zdAogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIC8vICMxMDIyNjEjIENhbGwgZ2xvYmFsIHF1ZXVlIGZvciBmb2N1cyBldmVudHMKICAgICAgICBpZiggckV2ZW50LkV2ZW50SWQgPT0gQWNjZXNzaWJsZVN0YXRlVHlwZTo6Rk9DVVNFRCApCiAgICAgICAgICAgIHZjbDo6dW5vaGVscGVyOjpOb3RpZnlBY2Nlc3NpYmxlU3RhdGVFdmVudEdsb2JhbGx5KCByRXZlbnQgKTsKCiAgICAgICAgLy8gIzEwNjIzNCMgRGVsZWdhdGUgdG8gRXZlbnROb3RpZmllcgogICAgICAgIDo6Y29tcGhlbHBlcjo6QWNjZXNzaWJsZUV2ZW50Tm90aWZpZXI6OmFkZEV2ZW50KCBnZXROb3RpZmllckNsaWVudElkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJFdmVudCApOwogICAgfQoKCS8vIFhBY2Nlc3NpYmxlQ29udGV4dAogICAgc2FsX0ludDMyIFNBTF9DQUxMIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OmdldEFjY2Vzc2libGVDaGlsZENvdW50KCkgU0FMX1RIUk9XKCh1bm86OlJ1bnRpbWVFeGNlcHRpb24pKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIHJldHVybiBtbkxhc3RWaXNpYmxlQ2hpbGQgLSBtbkZpcnN0VmlzaWJsZUNoaWxkICsgMTsKICAgIH0KCiAgICB1bm86OlJlZmVyZW5jZTwgWEFjY2Vzc2libGUgPiBTQUxfQ0FMTCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpnZXRBY2Nlc3NpYmxlQ2hpbGQoIHNhbF9JbnQzMiBpICkgU0FMX1RIUk9XKChsYW5nOjpJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCB1bm86OlJ1bnRpbWVFeGNlcHRpb24pKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIGkgLT0gR2V0U3RhcnRJbmRleCgpOwoKICAgICAgICBpZiggMCA+IGkgfHwgaSA+PSBnZXRBY2Nlc3NpYmxlQ2hpbGRDb3VudCgpIHx8CiAgICAgICAgICAgIEdldFRleHRGb3J3YXJkZXIoKS5HZXRQYXJhZ3JhcGhDb3VudCgpIDw9IGkgKQogICAgICAgIHsKICAgICAgICAgICAgdGhyb3cgbGFuZzo6SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbig6OnJ0bDo6T1VTdHJpbmcoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJJbnZhbGlkIGNoaWxkIGluZGV4IikpLCBteEZyb250RW5kKTsKICAgICAgICB9CgogICAgICAgIERCR19BU1NFUlQobXhGcm9udEVuZC5pcygpLCAiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6VXBkYXRlVmlzaWJsZUNoaWxkcmVuOiBubyBmcm9udGVuZCBzZXQiKTsKCiAgICAgICAgaWYoIG14RnJvbnRFbmQuaXMoKSApCiAgICAgICAgICAgIHJldHVybiBtYVBhcmFNYW5hZ2VyLkNyZWF0ZUNoaWxkKCBpLCBteEZyb250RW5kLCBHZXRFZGl0U291cmNlKCksIG1uRmlyc3RWaXNpYmxlQ2hpbGQgKyBpICkuZmlyc3Q7CiAgICAgICAgZWxzZQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICB2b2lkIFNBTF9DQUxMIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OmFkZEV2ZW50TGlzdGVuZXIoIGNvbnN0IHVubzo6UmVmZXJlbmNlPCBYQWNjZXNzaWJsZUV2ZW50TGlzdGVuZXIgPiYgeExpc3RlbmVyICkgU0FMX1RIUk9XKCh1bm86OlJ1bnRpbWVFeGNlcHRpb24pKQogICAgewogICAgICAgIERCR19DSEtUSElTKCBBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsLCBOVUxMICk7CgogICAgICAgIGlmKCBnZXROb3RpZmllckNsaWVudElkKCkgIT0gLTEgKQogICAgICAgICAgICA6OmNvbXBoZWxwZXI6OkFjY2Vzc2libGVFdmVudE5vdGlmaWVyOjphZGRFdmVudExpc3RlbmVyKCBnZXROb3RpZmllckNsaWVudElkKCksIHhMaXN0ZW5lciApOwogICAgfQoKICAgIHZvaWQgU0FMX0NBTEwgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6cmVtb3ZlRXZlbnRMaXN0ZW5lciggY29uc3QgdW5vOjpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlRXZlbnRMaXN0ZW5lciA+JiB4TGlzdGVuZXIgKSBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgaWYoIGdldE5vdGlmaWVyQ2xpZW50SWQoKSAhPSAtMSApCiAgICAgICAgICAgIDo6Y29tcGhlbHBlcjo6QWNjZXNzaWJsZUV2ZW50Tm90aWZpZXI6OnJlbW92ZUV2ZW50TGlzdGVuZXIoIGdldE5vdGlmaWVyQ2xpZW50SWQoKSwgeExpc3RlbmVyICk7CiAgICB9CgogICAgdW5vOjpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlID4gU0FMX0NBTEwgQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6Z2V0QWNjZXNzaWJsZUF0UG9pbnQoIGNvbnN0IGF3dDo6UG9pbnQmIF9hUG9pbnQgKSBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgREJHX0NIS1RISVMoIEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwsIE5VTEwgKTsKCiAgICAgICAgLy8gbWFrZSBnaXZlbiBwb3NpdGlvbiByZWxhdGl2ZQogICAgICAgIGlmKCAhbXhGcm9udEVuZC5pcygpICkKICAgICAgICAgICAgdGhyb3cgdW5vOjpSdW50aW1lRXhjZXB0aW9uKDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OmdldEFjY2Vzc2libGVBdDogZnJvbnRlbmQgaW52YWxpZCIpKSwgbXhGcm9udEVuZCApOwoKICAgICAgICB1bm86OlJlZmVyZW5jZTwgWEFjY2Vzc2libGVDb250ZXh0ID4geEZyb250RW5kQ29udGV4dCA9IG14RnJvbnRFbmQtPmdldEFjY2Vzc2libGVDb250ZXh0KCk7CgogICAgICAgIGlmKCAheEZyb250RW5kQ29udGV4dC5pcygpICkKICAgICAgICAgICAgdGhyb3cgdW5vOjpSdW50aW1lRXhjZXB0aW9uKDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIkFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGw6OmdldEFjY2Vzc2libGVBdDogZnJvbnRlbmQgaW52YWxpZCIpKSwgbXhGcm9udEVuZCApOwoKICAgICAgICB1bm86OlJlZmVyZW5jZTwgWEFjY2Vzc2libGVDb21wb25lbnQgPiB4RnJvbnRFbmRDb21wb25lbnQoIHhGcm9udEVuZENvbnRleHQsIHVubzo6VU5PX1FVRVJZICk7CgogICAgICAgIGlmKCAheEZyb250RW5kQ29tcG9uZW50LmlzKCkgKQogICAgICAgICAgICB0aHJvdyB1bm86OlJ1bnRpbWVFeGNlcHRpb24oOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiQWNjZXNzaWJsZVRleHRIZWxwZXJfSW1wbDo6Z2V0QWNjZXNzaWJsZUF0OiBmcm9udGVuZCBpcyBubyBYQWNjZXNzaWJsZUNvbXBvbmVudCIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14RnJvbnRFbmQgKTsKCiAgICAgICAgLy8gIzEwMzg2MiMgTm8gbG9uZ2VyIG5lZWQgdG8gbWFrZSBnaXZlbiBwb3NpdGlvbiByZWxhdGl2ZQogICAgICAgIFBvaW50IGFQb2ludCggX2FQb2ludC5YLCBfYVBvaW50LlkgKTsKCiAgICAgICAgLy8gcmVzcGVjdCBFZGl0RW5naW5lIG9mZnNldCB0byBzdXJyb3VuZGluZyBzaGFwZS9jZWxsCiAgICAgICAgYVBvaW50IC09IEdldE9mZnNldCgpOwoKICAgICAgICAvLyBjb252ZXJ0IHRvIEVkaXRFbmdpbmUgY29vcmRpbmF0ZSBzeXN0ZW0KICAgICAgICBTdnhUZXh0Rm9yd2FyZGVyJiByQ2FjaGVURiA9IEdldFRleHRGb3J3YXJkZXIoKTsKICAgICAgICBQb2ludCBhTG9nUG9pbnQoIEdldFZpZXdGb3J3YXJkZXIoKS5QaXhlbFRvTG9naWMoIGFQb2ludCwgckNhY2hlVEYuR2V0TWFwTW9kZSgpICkgKTsKCiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIGFsbCB2aXNpYmxlIGNoaWxkcmVuIChpbmNsdWRpbmcgdGhvc2Ugbm90IHlldCBjcmVhdGVkKQogICAgICAgIHNhbF9JbnQzMiBuQ2hpbGQ7CiAgICAgICAgZm9yKCBuQ2hpbGQ9bW5GaXJzdFZpc2libGVDaGlsZDsgbkNoaWxkIDw9IG1uTGFzdFZpc2libGVDaGlsZDsgKytuQ2hpbGQgKQogICAgICAgIHsKICAgICAgICAgICAgREJHX0FTU0VSVChuQ2hpbGQgPj0gMCAmJiBuQ2hpbGQgPD0gVVNIUlRfTUFYLAogICAgICAgICAgICAgICAgICAgICAgICJBY2Nlc3NpYmxlVGV4dEhlbHBlcl9JbXBsOjpnZXRBY2Nlc3NpYmxlQXQ6IGluZGV4IHZhbHVlIG92ZXJmbG93Iik7CgogICAgICAgICAgICBSZWN0YW5nbGUgYVBhcmFCb3VuZHMoIHJDYWNoZVRGLkdldFBhcmFCb3VuZHMoIHN0YXRpY19jYXN0PCBzYWxfdUludDE2ID4gKG5DaGlsZCkgKSApOwoKICAgICAgICAgICAgaWYoIGFQYXJhQm91bmRzLklzSW5zaWRlKCBhTG9nUG9pbnQgKSApCiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0QWNjZXNzaWJsZUNoaWxkKCBuQ2hpbGQgLSBtbkZpcnN0VmlzaWJsZUNoaWxkICsgR2V0U3RhcnRJbmRleCgpICk7CiAgICAgICAgfQoKICAgICAgICAvLyBmb3VuZCBub25lCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCS8vCgkvLyBBY2Nlc3NpYmxlVGV4dEhlbHBlciBpbXBsZW1lbnRhdGlvbiAoc2ltcGx5IGZvcndhcmRzIHRvIGltcGwpCgkvLwoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6QWNjZXNzaWJsZVRleHRIZWxwZXIoIDo6c3RkOjphdXRvX3B0cjwgU3Z4RWRpdFNvdXJjZSA+IHBFZGl0U291cmNlICkgOgogICAgICAgIG1wSW1wbCggbmV3IEFjY2Vzc2libGVUZXh0SGVscGVyX0ltcGwoKSApCiAgICB7CiAgICAgICAgOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCiAgICAgICAgU2V0RWRpdFNvdXJjZSggcEVkaXRTb3VyY2UgKTsKICAgIH0KCiAgICBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6fkFjY2Vzc2libGVUZXh0SGVscGVyKCkKICAgIHsKICAgIH0KCiAgICBjb25zdCBTdnhFZGl0U291cmNlJiBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6R2V0RWRpdFNvdXJjZSgpIGNvbnN0IFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgY29uc3QgU3Z4RWRpdFNvdXJjZSYgYUVkaXRTb3VyY2UgPSBtcEltcGwtPkdldEVkaXRTb3VyY2UoKTsKCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgcmV0dXJuIGFFZGl0U291cmNlOwojZWxzZQogICAgICAgIHJldHVybiBtcEltcGwtPkdldEVkaXRTb3VyY2UoKTsKI2VuZGlmCiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6U2V0RWRpdFNvdXJjZSggOjpzdGQ6OmF1dG9fcHRyPCBTdnhFZGl0U291cmNlID4gcEVkaXRTb3VyY2UgKSBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiNpZmRlZiBEQkdfVVRJTAogICAgICAgIC8vIHByZWNvbmRpdGlvbjogc29sYXIgbXV0ZXggbG9ja2VkCiAgICAgICAgREJHX1RFU1RTT0xBUk1VVEVYKCk7CgogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CiNlbmRpZgoKICAgICAgICBtcEltcGwtPlNldEVkaXRTb3VyY2UoIHBFZGl0U291cmNlICk7CgojaWZkZWYgREJHX1VUSUwKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwojZW5kaWYKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyOjpTZXRFdmVudFNvdXJjZSggY29uc3QgdW5vOjpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlID4mIHJJbnRlcmZhY2UgKQogICAgewojaWZkZWYgREJHX1VUSUwKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwojZW5kaWYKCiAgICAgICAgbXBJbXBsLT5TZXRFdmVudFNvdXJjZSggckludGVyZmFjZSApOwoKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKI2VuZGlmCiAgICB9CgogICAgdW5vOjpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlID4gQWNjZXNzaWJsZVRleHRIZWxwZXI6OkdldEV2ZW50U291cmNlKCkgY29uc3QKICAgIHsKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgdW5vOjpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlID4geFJldCggbXBJbXBsLT5HZXRFdmVudFNvdXJjZSgpICk7CgogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CgogICAgICAgIHJldHVybiB4UmV0OwojZWxzZQogICAgICAgIHJldHVybiBtcEltcGwtPkdldEV2ZW50U291cmNlKCk7CiNlbmRpZgogICAgfQoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXI6OlNldEZvY3VzKCBzYWxfQm9vbCBiSGF2ZUZvY3VzICkgU0FMX1RIUk9XKCg6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJ1bnRpbWVFeGNlcHRpb24pKQogICAgewojaWZkZWYgREJHX1VUSUwKICAgICAgICAvLyBwcmVjb25kaXRpb246IHNvbGFyIG11dGV4IGxvY2tlZAogICAgICAgIERCR19URVNUU09MQVJNVVRFWCgpOwoKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwojZW5kaWYKCiAgICAgICAgbXBJbXBsLT5TZXRGb2N1cyggYkhhdmVGb2N1cyApOwoKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKI2VuZGlmCiAgICB9CgogICAgc2FsX0Jvb2wgQWNjZXNzaWJsZVRleHRIZWxwZXI6OkhhdmVGb2N1cygpIFNBTF9USFJPVygoOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgc2FsX0Jvb2wgYlJldCggbXBJbXBsLT5IYXZlRm9jdXMoKSApOwoKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwoKICAgICAgICByZXR1cm4gYlJldDsKI2Vsc2UKICAgICAgICByZXR1cm4gbXBJbXBsLT5IYXZlRm9jdXMoKTsKI2VuZGlmCiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6RmlyZUV2ZW50KCBjb25zdCBzYWxfSW50MTYgbkV2ZW50SWQsIGNvbnN0IHVubzo6QW55JiByTmV3VmFsdWUsIGNvbnN0IHVubzo6QW55JiByT2xkVmFsdWUgKSBjb25zdAogICAgewojaWZkZWYgREJHX1VUSUwKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwojZW5kaWYKCiAgICAgICAgbXBJbXBsLT5GaXJlRXZlbnQoIG5FdmVudElkLCByTmV3VmFsdWUsIHJPbGRWYWx1ZSApOwoKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKI2VuZGlmCiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6RmlyZUV2ZW50KCBjb25zdCBBY2Nlc3NpYmxlRXZlbnRPYmplY3QmIHJFdmVudCApIGNvbnN0CiAgICB7CiNpZmRlZiBEQkdfVVRJTAogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CiNlbmRpZgoKICAgICAgICBtcEltcGwtPkZpcmVFdmVudCggckV2ZW50ICk7CgojaWZkZWYgREJHX1VUSUwKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwojZW5kaWYKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyOjpTZXRPZmZzZXQoIGNvbnN0IFBvaW50JiByUG9pbnQgKQogICAgewojaWZkZWYgREJHX1VUSUwKICAgICAgICAvLyBwcmVjb25kaXRpb246IHNvbGFyIG11dGV4IGxvY2tlZAogICAgICAgIERCR19URVNUU09MQVJNVVRFWCgpOwoKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwojZW5kaWYKCiAgICAgICAgbXBJbXBsLT5TZXRPZmZzZXQoIHJQb2ludCApOwoKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKI2VuZGlmCiAgICB9CgogICAgUG9pbnQgQWNjZXNzaWJsZVRleHRIZWxwZXI6OkdldE9mZnNldCgpIGNvbnN0CiAgICB7CiNpZmRlZiBEQkdfVVRJTAogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CgogICAgICAgIFBvaW50IGFQb2ludCggbXBJbXBsLT5HZXRPZmZzZXQoKSApOwoKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwoKICAgICAgICByZXR1cm4gYVBvaW50OwojZWxzZQogICAgICAgIHJldHVybiBtcEltcGwtPkdldE9mZnNldCgpOwojZW5kaWYKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyOjpTZXRTdGFydEluZGV4KCBzYWxfSW50MzIgbk9mZnNldCApCiAgICB7CiNpZmRlZiBEQkdfVVRJTAogICAgICAgIC8vIHByZWNvbmRpdGlvbjogc29sYXIgbXV0ZXggbG9ja2VkCiAgICAgICAgREJHX1RFU1RTT0xBUk1VVEVYKCk7CgogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CiNlbmRpZgoKICAgICAgICBtcEltcGwtPlNldFN0YXJ0SW5kZXgoIG5PZmZzZXQgKTsKCiNpZmRlZiBEQkdfVVRJTAogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CiNlbmRpZgogICAgfQoKICAgIHNhbF9JbnQzMiBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6R2V0U3RhcnRJbmRleCgpIGNvbnN0CiAgICB7CiNpZmRlZiBEQkdfVVRJTAogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CgogICAgICAgIHNhbF9JbnQzMiBuT2Zmc2V0ID0gbXBJbXBsLT5HZXRTdGFydEluZGV4KCk7CgogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CgogICAgICAgIHJldHVybiBuT2Zmc2V0OwojZWxzZQogICAgICAgIHJldHVybiBtcEltcGwtPkdldFN0YXJ0SW5kZXgoKTsKI2VuZGlmCiAgICB9CgogICAgdm9pZCBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6U2V0QWRkaXRpb25hbENoaWxkU3RhdGVzKCBjb25zdCBWZWN0b3JPZlN0YXRlcyYgckNoaWxkU3RhdGVzICkKICAgIHsKICAgICAgICBtcEltcGwtPlNldEFkZGl0aW9uYWxDaGlsZFN0YXRlcyggckNoaWxkU3RhdGVzICk7CiAgICB9CgogICAgY29uc3QgQWNjZXNzaWJsZVRleHRIZWxwZXI6OlZlY3Rvck9mU3RhdGVzJiBBY2Nlc3NpYmxlVGV4dEhlbHBlcjo6R2V0QWRkaXRpb25hbENoaWxkU3RhdGVzKCkgY29uc3QKICAgIHsKICAgICAgICByZXR1cm4gbXBJbXBsLT5HZXRBZGRpdGlvbmFsQ2hpbGRTdGF0ZXMoKTsKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyOjpVcGRhdGVDaGlsZHJlbigpIFNBTF9USFJPVygoOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKI2lmZGVmIERCR19VVElMCiAgICAgICAgLy8gcHJlY29uZGl0aW9uOiBzb2xhciBtdXRleCBsb2NrZWQKICAgICAgICBEQkdfVEVTVFNPTEFSTVVURVgoKTsKCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKI2VuZGlmCgogICAgICAgIG1wSW1wbC0+VXBkYXRlVmlzaWJsZUNoaWxkcmVuKCk7CiAgICAgICAgbXBJbXBsLT5VcGRhdGVCb3VuZFJlY3QoKTsKCiAgICAgICAgbXBJbXBsLT5VcGRhdGVTZWxlY3Rpb24oKTsKCiNpZmRlZiBEQkdfVVRJTAogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CiNlbmRpZgogICAgfQoKICAgIHZvaWQgQWNjZXNzaWJsZVRleHRIZWxwZXI6OkRpc3Bvc2UoKQogICAgewogICAgICAgIC8vIEFzIERpc3Bvc2UgY2FsbHMgU2h1dGRvd25FZGl0U291cmNlLCB3aGljaCBpbiB0dXJuCiAgICAgICAgLy8gZGVyZWdpc3RlcnMgYXMgbGlzdGVuZXIgb24gdGhlIGVkaXQgc291cmNlLCBoYXZlIHRvIGxvY2sKICAgICAgICAvLyBoZXJlCiAgICAgICAgOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCiNpZmRlZiBEQkdfVVRJTAogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CiNlbmRpZgoKICAgICAgICBtcEltcGwtPkRpc3Bvc2UoKTsKCiNpZmRlZiBEQkdfVVRJTAogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CiNlbmRpZgogICAgfQoKICAgIHNhbF9Cb29sIEFjY2Vzc2libGVUZXh0SGVscGVyOjpJc1NlbGVjdGVkKCkgY29uc3QKICAgIHsKICAgICAgICA6OnZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgc2FsX0Jvb2wgYVJldCA9IG1wSW1wbC0+SXNTZWxlY3RlZCgpOwoKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwoKICAgICAgICByZXR1cm4gYVJldDsKI2Vsc2UKICAgICAgICByZXR1cm4gbXBJbXBsLT5Jc1NlbGVjdGVkKCk7CiNlbmRpZgogICAgfQoKCS8vIFhBY2Nlc3NpYmxlQ29udGV4dAogICAgc2FsX0ludDMyIEFjY2Vzc2libGVUZXh0SGVscGVyOjpHZXRDaGlsZENvdW50KCkgU0FMX1RIUk9XKCh1bm86OlJ1bnRpbWVFeGNlcHRpb24pKQogICAgewogICAgICAgIDo6dm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgojaWZkZWYgREJHX1VUSUwKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwoKICAgICAgICBzYWxfSW50MzIgblJldCA9IG1wSW1wbC0+Z2V0QWNjZXNzaWJsZUNoaWxkQ291bnQoKTsKCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgcmV0dXJuIG5SZXQ7CiNlbHNlCiAgICAgICAgcmV0dXJuIG1wSW1wbC0+Z2V0QWNjZXNzaWJsZUNoaWxkQ291bnQoKTsKI2VuZGlmCiAgICB9CgogICAgdW5vOjpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlID4gQWNjZXNzaWJsZVRleHRIZWxwZXI6OkdldENoaWxkKCBzYWxfSW50MzIgaSApIFNBTF9USFJPVygobGFuZzo6SW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbiwgdW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKICAgICAgICA6OnZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgdW5vOjpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlID4geFJldCA9IG1wSW1wbC0+Z2V0QWNjZXNzaWJsZUNoaWxkKCBpICk7CgogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CgogICAgICAgIHJldHVybiB4UmV0OwojZWxzZQogICAgICAgIHJldHVybiBtcEltcGwtPmdldEFjY2Vzc2libGVDaGlsZCggaSApOwojZW5kaWYKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyOjpBZGRFdmVudExpc3RlbmVyKCBjb25zdCB1bm86OlJlZmVyZW5jZTwgWEFjY2Vzc2libGVFdmVudExpc3RlbmVyID4mIHhMaXN0ZW5lciApIFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgbXBJbXBsLT5hZGRFdmVudExpc3RlbmVyKCB4TGlzdGVuZXIgKTsKCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKI2Vsc2UKICAgICAgICBtcEltcGwtPmFkZEV2ZW50TGlzdGVuZXIoIHhMaXN0ZW5lciApOwojZW5kaWYKICAgIH0KCiAgICB2b2lkIEFjY2Vzc2libGVUZXh0SGVscGVyOjpSZW1vdmVFdmVudExpc3RlbmVyKCBjb25zdCB1bm86OlJlZmVyZW5jZTwgWEFjY2Vzc2libGVFdmVudExpc3RlbmVyID4mIHhMaXN0ZW5lciApIFNBTF9USFJPVygodW5vOjpSdW50aW1lRXhjZXB0aW9uKSkKICAgIHsKI2lmZGVmIERCR19VVElMCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKCiAgICAgICAgbXBJbXBsLT5yZW1vdmVFdmVudExpc3RlbmVyKCB4TGlzdGVuZXIgKTsKCiAgICAgICAgbXBJbXBsLT5DaGVja0ludmFyaWFudHMoKTsKI2Vsc2UKICAgICAgICBtcEltcGwtPnJlbW92ZUV2ZW50TGlzdGVuZXIoIHhMaXN0ZW5lciApOwojZW5kaWYKICAgIH0KCgkvLyBYQWNjZXNzaWJsZUNvbXBvbmVudAogICAgdW5vOjpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlID4gQWNjZXNzaWJsZVRleHRIZWxwZXI6OkdldEF0KCBjb25zdCBhd3Q6OlBvaW50JiBhUG9pbnQgKSBTQUxfVEhST1coKHVubzo6UnVudGltZUV4Y2VwdGlvbikpCiAgICB7CiAgICAgICAgOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCiNpZmRlZiBEQkdfVVRJTAogICAgICAgIG1wSW1wbC0+Q2hlY2tJbnZhcmlhbnRzKCk7CgogICAgICAgIHVubzo6UmVmZXJlbmNlPCBYQWNjZXNzaWJsZSA+IHhDaGlsZCA9IG1wSW1wbC0+Z2V0QWNjZXNzaWJsZUF0UG9pbnQoIGFQb2ludCApOwoKICAgICAgICBtcEltcGwtPkNoZWNrSW52YXJpYW50cygpOwoKICAgICAgICByZXR1cm4geENoaWxkOwojZWxzZQogICAgICAgIHJldHVybiBtcEltcGwtPmdldEFjY2Vzc2libGVBdFBvaW50KCBhUG9pbnQgKTsKI2VuZGlmCiAgICB9Cgp9IC8vIGVuZCBvZiBuYW1lc3BhY2UgYWNjZXNzaWJpbGl0eQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K