LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfc3Z4Lmh4eCIKCiNpbmNsdWRlICJzdngvZm1ncmlkaWYuaHh4IgojaW5jbHVkZSAiZm1wcm9wLmhyYyIKI2luY2x1ZGUgImZtc2VydnMuaHh4IgojaW5jbHVkZSAic3Z4L2ZtdG9vbHMuaHh4IgojaW5jbHVkZSAiZm11cmwuaHh4IgojaW5jbHVkZSAiZm9ybWNvbnRyb2xmYWN0b3J5Lmh4eCIKI2luY2x1ZGUgImdyaWRjZWxsLmh4eCIKI2luY2x1ZGUgInNkYmRhdGFjb2x1bW4uaHh4IgojaW5jbHVkZSAic3Z4L2ZtZ3JpZGNsLmh4eCIKI2luY2x1ZGUgInN2eC9zdnhpZHMuaHJjIgojaW5jbHVkZSA8dG9vbHMvdXJsb2JqLmh4eD4KCi8qKiA9PT0gYmVnaW4gVU5PIGluY2x1ZGVzID09PSAqKi8KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9hd3QvUG9zU2l6ZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvYmVhbnMvUHJvcGVydHlBdHRyaWJ1dGUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2Zvcm0vRm9ybUNvbXBvbmVudFR5cGUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2Zvcm0vWEZvcm1Db21wb25lbnQuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2Zvcm0vWExvYWRhYmxlLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9sYW5nL0Rpc3Bvc2VkRXhjZXB0aW9uLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjL1Jlc3VsdFNldFR5cGUuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmN4L1hDb2x1bW5zU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3V0aWwvWFVSTFRyYW5zZm9ybWVyLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci92aWV3L1hTZWxlY3Rpb25TdXBwbGllci5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiY3gvWFJvd0xvY2F0ZS5ocHA+Ci8qKiA9PT0gZW5kIFVOTyBpbmNsdWRlcyA9PT0gKiovCgojaW5jbHVkZSA8Y29tcGhlbHBlci9jb250YWluZXIuaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9lbnVtaGVscGVyLmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvZXh0cmFjdC5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL3Byb2Nlc3NmYWN0b3J5Lmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvcHJvcGVydHkuaHh4PgojaW5jbHVkZSA8Y29tcGhlbHBlci9zZXF1ZW5jZS5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL3R5cGVzLmh4eD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvdHlwZXByb3ZpZGVyLmh4eD4KI2luY2x1ZGUgPHRvb2xraXQvaGVscGVyL3ZjbHVub2hlbHBlci5oeHg+CiNpbmNsdWRlIDx0b29scy9kaWFnbm9zZV9leC5oPgoKdXNpbmcgbmFtZXNwYWNlIDo6c3Z4Zm9ybTsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmNvbnRhaW5lcjsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnNkYjsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnNkYmM7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1bm87CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp2aWV3Owp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6YmVhbnM7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6Zm9ybTsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnV0aWw7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOwoKdXNpbmcgOjpjb206OnN1bjo6c3Rhcjo6c2RiY3g6OlhDb2x1bW5zU3VwcGxpZXI7CnVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yOwp1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXI7CnVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OmFjY2Vzc2liaWxpdHk6OlhBY2Nlc3NpYmxlOwp1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphY2Nlc3NpYmlsaXR5OjpYQWNjZXNzaWJsZUNvbnRleHQ7CnVzaW5nIDo6Y29tOjpzdW46OnN0YXI6OnNkYjo6WFJvd1NldFN1cHBsaWVyOwp1c2luZyA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhWY2xXaW5kb3dQZWVyOwoKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6Y29tOjpzdW46OnN0YXI6OmF3dDo6Rm9udERlc2NyaXB0b3IgSW1wbENyZWF0ZUZvbnREZXNjcmlwdG9yKCBjb25zdCBGb250JiByRm9udCApCnsKCTo6Y29tOjpzdW46OnN0YXI6OmF3dDo6Rm9udERlc2NyaXB0b3IgYUZEOwoJYUZELk5hbWUgPSByRm9udC5HZXROYW1lKCk7CglhRkQuU3R5bGVOYW1lID0gckZvbnQuR2V0U3R5bGVOYW1lKCk7CglhRkQuSGVpZ2h0ID0gKHNhbF9JbnQxNilyRm9udC5HZXRTaXplKCkuSGVpZ2h0KCk7CglhRkQuV2lkdGggPSAoc2FsX0ludDE2KXJGb250LkdldFNpemUoKS5XaWR0aCgpOwoJYUZELkZhbWlseSA9IChzYWxfSW50MTYpckZvbnQuR2V0RmFtaWx5KCk7CglhRkQuQ2hhclNldCA9IHJGb250LkdldENoYXJTZXQoKTsKCWFGRC5QaXRjaCA9IChzYWxfSW50MTYpckZvbnQuR2V0UGl0Y2goKTsKCWFGRC5DaGFyYWN0ZXJXaWR0aCA9IFZDTFVub0hlbHBlcjo6Q29udmVydEZvbnRXaWR0aCggckZvbnQuR2V0V2lkdGhUeXBlKCkgKTsKCWFGRC5XZWlnaHQ9IFZDTFVub0hlbHBlcjo6Q29udmVydEZvbnRXZWlnaHQoIHJGb250LkdldFdlaWdodCgpICk7CglhRkQuU2xhbnQgPSAoOjpjb206OnN1bjo6c3Rhcjo6YXd0OjpGb250U2xhbnQpckZvbnQuR2V0SXRhbGljKCk7CglhRkQuVW5kZXJsaW5lID0gKHNhbF9JbnQxNilyRm9udC5HZXRVbmRlcmxpbmUoKTsKCWFGRC5TdHJpa2VvdXQgPSAoc2FsX0ludDE2KXJGb250LkdldFN0cmlrZW91dCgpOwoJYUZELk9yaWVudGF0aW9uID0gckZvbnQuR2V0T3JpZW50YXRpb24oKTsKCWFGRC5LZXJuaW5nID0gckZvbnQuSXNLZXJuaW5nKCk7CglhRkQuV29yZExpbmVNb2RlID0gckZvbnQuSXNXb3JkTGluZU1vZGUoKTsKCWFGRC5UeXBlID0gMDsgICAvLyA/Pz8gPT4gTnVyIGFuIE1ldHJpYy4uLgoJcmV0dXJuIGFGRDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRm9udCBJbXBsQ3JlYXRlRm9udCggY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6YXd0OjpGb250RGVzY3JpcHRvciYgckRlc2NyICkKewoJRm9udCBhRm9udDsKCWFGb250LlNldE5hbWUoIHJEZXNjci5OYW1lICk7CglhRm9udC5TZXRTdHlsZU5hbWUoIHJEZXNjci5TdHlsZU5hbWUgKTsKCWFGb250LlNldFNpemUoIDo6U2l6ZSggckRlc2NyLldpZHRoLCByRGVzY3IuSGVpZ2h0ICkgKTsKCWFGb250LlNldEZhbWlseSggKEZvbnRGYW1pbHkpckRlc2NyLkZhbWlseSApOwoJYUZvbnQuU2V0Q2hhclNldCggKENoYXJTZXQpckRlc2NyLkNoYXJTZXQgKTsKCWFGb250LlNldFBpdGNoKCAoRm9udFBpdGNoKXJEZXNjci5QaXRjaCApOwoJYUZvbnQuU2V0V2lkdGhUeXBlKCBWQ0xVbm9IZWxwZXI6OkNvbnZlcnRGb250V2lkdGgoIHJEZXNjci5DaGFyYWN0ZXJXaWR0aCApICk7CglhRm9udC5TZXRXZWlnaHQoIFZDTFVub0hlbHBlcjo6Q29udmVydEZvbnRXZWlnaHQoIHJEZXNjci5XZWlnaHQgKSApOwoJYUZvbnQuU2V0SXRhbGljKCAoRm9udEl0YWxpYylyRGVzY3IuU2xhbnQgKTsKCWFGb250LlNldFVuZGVybGluZSggKDo6Rm9udFVuZGVybGluZSlyRGVzY3IuVW5kZXJsaW5lICk7CglhRm9udC5TZXRTdHJpa2VvdXQoICg6OkZvbnRTdHJpa2VvdXQpckRlc2NyLlN0cmlrZW91dCApOwoJYUZvbnQuU2V0T3JpZW50YXRpb24oIChzYWxfSW50MTYpckRlc2NyLk9yaWVudGF0aW9uICk7CglhRm9udC5TZXRLZXJuaW5nKCByRGVzY3IuS2VybmluZyApOwoJYUZvbnQuU2V0V29yZExpbmVNb2RlKCByRGVzY3IuV29yZExpbmVNb2RlICk7CglyZXR1cm4gYUZvbnQ7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vPSBGbVhNb2RpZnlNdWx0aXBsZXhlcgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGbVhNb2RpZnlNdWx0aXBsZXhlcjo6Rm1YTW9kaWZ5TXVsdGlwbGV4ZXIoIDo6Y3BwdTo6T1dlYWtPYmplY3QmIHJTb3VyY2UsIDo6b3NsOjpNdXRleCYgX3JNdXRleCApCgkJCQkJOk9XZWFrU3ViT2JqZWN0KCByU291cmNlICkKCQkJCQksT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciggX3JNdXRleCApCnsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KQW55CVNBTF9DQUxMIEZtWE1vZGlmeU11bHRpcGxleGVyOjpxdWVyeUludGVyZmFjZShjb25zdCBUeXBlJiBfclR5cGUpIHRocm93IChSdW50aW1lRXhjZXB0aW9uKQp7CglBbnkgYVJldHVybjsKCWFSZXR1cm4gPSA6OmNwcHU6OnF1ZXJ5SW50ZXJmYWNlKF9yVHlwZSwKCQlzdGF0aWNfY2FzdDwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6WE1vZGlmeUxpc3RlbmVyKj4odGhpcyksCgkJc3RhdGljX2Nhc3Q8IFhFdmVudExpc3RlbmVyKj4odGhpcykKCSk7CgoJaWYgKCFhUmV0dXJuLmhhc1ZhbHVlKCkpCgkJYVJldHVybiA9IE9XZWFrU3ViT2JqZWN0OjpxdWVyeUludGVyZmFjZSggX3JUeXBlICk7CgoJcmV0dXJuIGFSZXR1cm47Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YTW9kaWZ5TXVsdGlwbGV4ZXI6OmRpc3Bvc2luZyhjb25zdCBFdmVudE9iamVjdCYgKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhNb2RpZnlNdWx0aXBsZXhlcjo6bW9kaWZpZWQoY29uc3QgRXZlbnRPYmplY3QmIGUpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJRXZlbnRPYmplY3QgYU11bHRpKCBlKTsKCWFNdWx0aS5Tb3VyY2UgPSAmbV9yUGFyZW50OwogICAgbm90aWZ5RWFjaCggJlhNb2RpZnlMaXN0ZW5lcjo6bW9kaWZpZWQsIGFNdWx0aSApOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLz0gRm1YVXBkYXRlTXVsdGlwbGV4ZXIKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRm1YVXBkYXRlTXVsdGlwbGV4ZXI6OkZtWFVwZGF0ZU11bHRpcGxleGVyKCA6OmNwcHU6Ok9XZWFrT2JqZWN0JiByU291cmNlLCA6Om9zbDo6TXV0ZXgmIF9yTXV0ZXggKQoJCQkJCTpPV2Vha1N1Yk9iamVjdCggclNvdXJjZSApCgkJCQkJLE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIoIF9yTXV0ZXggKQp7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkFueQlTQUxfQ0FMTCBGbVhVcGRhdGVNdWx0aXBsZXhlcjo6cXVlcnlJbnRlcmZhY2UoY29uc3QgVHlwZSYgX3JUeXBlKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewoJQW55IGFSZXR1cm47CglhUmV0dXJuID0gOjpjcHB1OjpxdWVyeUludGVyZmFjZShfclR5cGUsCgkJc3RhdGljX2Nhc3Q8IFhVcGRhdGVMaXN0ZW5lcio+KHRoaXMpLAoJCXN0YXRpY19jYXN0PCBYRXZlbnRMaXN0ZW5lcio+KHRoaXMpCgkpOwoKCWlmICghYVJldHVybi5oYXNWYWx1ZSgpKQoJCWFSZXR1cm4gPSBPV2Vha1N1Yk9iamVjdDo6cXVlcnlJbnRlcmZhY2UoIF9yVHlwZSApOwoKCXJldHVybiBhUmV0dXJuOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWFVwZGF0ZU11bHRpcGxleGVyOjpkaXNwb3NpbmcoY29uc3QgRXZlbnRPYmplY3QmICkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIEZtWFVwZGF0ZU11bHRpcGxleGVyOjphcHByb3ZlVXBkYXRlKGNvbnN0IEV2ZW50T2JqZWN0ICZlKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCUV2ZW50T2JqZWN0IGFNdWx0aSggZSApOwoJYU11bHRpLlNvdXJjZSA9ICZtX3JQYXJlbnQ7CgoJc2FsX0Jvb2wgYlJlc3VsdCA9IHNhbF9UcnVlOwoJaWYgKGdldExlbmd0aCgpKQoJewoJCTo6Y3BwdTo6T0ludGVyZmFjZUl0ZXJhdG9ySGVscGVyIGFJdGVyKCp0aGlzKTsKCQl3aGlsZSAoIGJSZXN1bHQgJiYgYUl0ZXIuaGFzTW9yZUVsZW1lbnRzKCkgKQoJCQliUmVzdWx0ID0gc3RhdGljX2Nhc3Q8IFhVcGRhdGVMaXN0ZW5lciogPiggYUl0ZXIubmV4dCgpICktPmFwcHJvdmVVcGRhdGUoIGFNdWx0aSApOwoJfQoKCXJldHVybiBiUmVzdWx0Owp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWFVwZGF0ZU11bHRpcGxleGVyOjp1cGRhdGVkKGNvbnN0IEV2ZW50T2JqZWN0ICZlKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCUV2ZW50T2JqZWN0IGFNdWx0aSggZSApOwoJYU11bHRpLlNvdXJjZSA9ICZtX3JQYXJlbnQ7CiAgICBub3RpZnlFYWNoKCAmWFVwZGF0ZUxpc3RlbmVyOjp1cGRhdGVkLCBhTXVsdGkgKTsKfQoKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vPSBGbVhTZWxlY3Rpb25NdWx0aXBsZXhlcgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGbVhTZWxlY3Rpb25NdWx0aXBsZXhlcjo6Rm1YU2VsZWN0aW9uTXVsdGlwbGV4ZXIoIDo6Y3BwdTo6T1dlYWtPYmplY3QmIHJTb3VyY2UsIDo6b3NsOjpNdXRleCYgX3JNdXRleCApCgk6T1dlYWtTdWJPYmplY3QoIHJTb3VyY2UgKQoJLE9JbnRlcmZhY2VDb250YWluZXJIZWxwZXIoIF9yTXV0ZXggKQp7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkFueQlTQUxfQ0FMTCBGbVhTZWxlY3Rpb25NdWx0aXBsZXhlcjo6cXVlcnlJbnRlcmZhY2UoY29uc3QgVHlwZSYgX3JUeXBlKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewoJQW55IGFSZXR1cm47CglhUmV0dXJuID0gOjpjcHB1OjpxdWVyeUludGVyZmFjZShfclR5cGUsCgkJc3RhdGljX2Nhc3Q8IFhTZWxlY3Rpb25DaGFuZ2VMaXN0ZW5lcio+KHRoaXMpLAoJCXN0YXRpY19jYXN0PCBYRXZlbnRMaXN0ZW5lcio+KHRoaXMpCgkpOwoKCWlmICghYVJldHVybi5oYXNWYWx1ZSgpKQoJCWFSZXR1cm4gPSBPV2Vha1N1Yk9iamVjdDo6cXVlcnlJbnRlcmZhY2UoIF9yVHlwZSApOwoKCXJldHVybiBhUmV0dXJuOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWFNlbGVjdGlvbk11bHRpcGxleGVyOjpkaXNwb3NpbmcoY29uc3QgRXZlbnRPYmplY3QmICkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YU2VsZWN0aW9uTXVsdGlwbGV4ZXI6OnNlbGVjdGlvbkNoYW5nZWQoIGNvbnN0IEV2ZW50T2JqZWN0JiBfckV2ZW50ICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKCUV2ZW50T2JqZWN0IGFNdWx0aShfckV2ZW50KTsKCWFNdWx0aS5Tb3VyY2UgPSAmbV9yUGFyZW50OwogICAgbm90aWZ5RWFjaCggJlhTZWxlY3Rpb25DaGFuZ2VMaXN0ZW5lcjo6c2VsZWN0aW9uQ2hhbmdlZCwgYU11bHRpICk7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vPSBGbVhDb250YWluZXJNdWx0aXBsZXhlcgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGbVhDb250YWluZXJNdWx0aXBsZXhlcjo6Rm1YQ29udGFpbmVyTXVsdGlwbGV4ZXIoIDo6Y3BwdTo6T1dlYWtPYmplY3QmIHJTb3VyY2UsIDo6b3NsOjpNdXRleCYgX3JNdXRleCApCgkJCQkJCTpPV2Vha1N1Yk9iamVjdCggclNvdXJjZSApCgkJCQkJCSxPSW50ZXJmYWNlQ29udGFpbmVySGVscGVyKCBfck11dGV4ICkKewp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpBbnkJU0FMX0NBTEwgRm1YQ29udGFpbmVyTXVsdGlwbGV4ZXI6OnF1ZXJ5SW50ZXJmYWNlKGNvbnN0IFR5cGUmIF9yVHlwZSkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKCUFueSBhUmV0dXJuOwoJYVJldHVybiA9IDo6Y3BwdTo6cXVlcnlJbnRlcmZhY2UoX3JUeXBlLAoJCXN0YXRpY19jYXN0PCBYQ29udGFpbmVyTGlzdGVuZXIqPih0aGlzKSwKCQlzdGF0aWNfY2FzdDwgWEV2ZW50TGlzdGVuZXIqPih0aGlzKQoJKTsKCglpZiAoIWFSZXR1cm4uaGFzVmFsdWUoKSkKCQlhUmV0dXJuID0gT1dlYWtTdWJPYmplY3Q6OnF1ZXJ5SW50ZXJmYWNlKCBfclR5cGUgKTsKCglyZXR1cm4gYVJldHVybjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhDb250YWluZXJNdWx0aXBsZXhlcjo6ZGlzcG9zaW5nKGNvbnN0IEV2ZW50T2JqZWN0JiApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YQ29udGFpbmVyTXVsdGlwbGV4ZXI6OmVsZW1lbnRJbnNlcnRlZChjb25zdCBDb250YWluZXJFdmVudCYgZSkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglDb250YWluZXJFdmVudCBhTXVsdGkoIGUgKTsKCWFNdWx0aS5Tb3VyY2UgPSAmbV9yUGFyZW50OwogICAgbm90aWZ5RWFjaCggJlhDb250YWluZXJMaXN0ZW5lcjo6ZWxlbWVudEluc2VydGVkLCBhTXVsdGkgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhDb250YWluZXJNdWx0aXBsZXhlcjo6ZWxlbWVudFJlbW92ZWQoY29uc3QgQ29udGFpbmVyRXZlbnQmIGUpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJQ29udGFpbmVyRXZlbnQgYU11bHRpKCBlICk7CglhTXVsdGkuU291cmNlID0gJm1fclBhcmVudDsKICAgIG5vdGlmeUVhY2goICZYQ29udGFpbmVyTGlzdGVuZXI6OmVsZW1lbnRSZW1vdmVkLCBhTXVsdGkgKTsKfQoKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YQ29udGFpbmVyTXVsdGlwbGV4ZXI6OmVsZW1lbnRSZXBsYWNlZChjb25zdCBDb250YWluZXJFdmVudCYgZSkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglDb250YWluZXJFdmVudCBhTXVsdGkoIGUgKTsKCWFNdWx0aS5Tb3VyY2UgPSAmbV9yUGFyZW50OwogICAgbm90aWZ5RWFjaCggJlhDb250YWluZXJMaXN0ZW5lcjo6ZWxlbWVudFJlcGxhY2VkLCBhTXVsdGkgKTsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy89IEZtWEdyaWRDb250cm9sTXVsdGlwbGV4ZXIKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRm1YR3JpZENvbnRyb2xNdWx0aXBsZXhlcjo6Rm1YR3JpZENvbnRyb2xNdWx0aXBsZXhlciggOjpjcHB1OjpPV2Vha09iamVjdCYgclNvdXJjZSwgOjpvc2w6Ok11dGV4JiBfck11dGV4ICkKCTpPV2Vha1N1Yk9iamVjdCggclNvdXJjZSApCgksT0ludGVyZmFjZUNvbnRhaW5lckhlbHBlciggX3JNdXRleCApCnsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KQW55CVNBTF9DQUxMIEZtWEdyaWRDb250cm9sTXVsdGlwbGV4ZXI6OnF1ZXJ5SW50ZXJmYWNlKGNvbnN0IFR5cGUmIF9yVHlwZSkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKCUFueSBhUmV0dXJuOwoJYVJldHVybiA9IDo6Y3BwdTo6cXVlcnlJbnRlcmZhY2UoIF9yVHlwZSwKCQlzdGF0aWNfY2FzdDwgWEdyaWRDb250cm9sTGlzdGVuZXIqPih0aGlzKQoJKTsKCglpZiAoIWFSZXR1cm4uaGFzVmFsdWUoKSkKCQlhUmV0dXJuID0gT1dlYWtTdWJPYmplY3Q6OnF1ZXJ5SW50ZXJmYWNlKCBfclR5cGUgKTsKCglyZXR1cm4gYVJldHVybjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkQ29udHJvbE11bHRpcGxleGVyOjpkaXNwb3NpbmcoIGNvbnN0IEV2ZW50T2JqZWN0JiApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sTXVsdGlwbGV4ZXI6OmNvbHVtbkNoYW5nZWQoIGNvbnN0IEV2ZW50T2JqZWN0JiBfZXZlbnQgKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewoJRXZlbnRPYmplY3QgYUZvcndhcmRlZEV2ZW50KCBfZXZlbnQgKTsKCWFGb3J3YXJkZWRFdmVudC5Tb3VyY2UgPSAmbV9yUGFyZW50OwogICAgbm90aWZ5RWFjaCggJlhHcmlkQ29udHJvbExpc3RlbmVyOjpjb2x1bW5DaGFuZ2VkLCBhRm9yd2FyZGVkRXZlbnQgKTsKfQoKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy89IEZtWEdyaWRDb250cm9sCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbF9OZXdJbnN0YW5jZV9JbXBsKGNvbnN0IFJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3Rvcnk+JiBfcnhGYWN0b3J5KQp7CglyZXR1cm4gKihuZXcgRm1YR3JpZENvbnRyb2woX3J4RmFjdG9yeSkpOwp9CkRCR19OQU1FKEZtWEdyaWRDb250cm9sICkKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KRm1YR3JpZENvbnRyb2w6OkZtWEdyaWRDb250cm9sKGNvbnN0IFJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiYgX3J4RmFjdG9yeSkKCQkJICAgOlVub0NvbnRyb2woIF9yeEZhY3RvcnkpCiAgICAgICAgICAgICAgICxtX2FNb2RpZnlMaXN0ZW5lcnMoKnRoaXMsIEdldE11dGV4KCkpCgkJCSAgICxtX2FVcGRhdGVMaXN0ZW5lcnMoKnRoaXMsIEdldE11dGV4KCkpCgkJCSAgICxtX2FDb250YWluZXJMaXN0ZW5lcnMoKnRoaXMsIEdldE11dGV4KCkpCgkJCSAgICxtX2FTZWxlY3Rpb25MaXN0ZW5lcnMoKnRoaXMsIEdldE11dGV4KCkpCiAgICAgICAgICAgICAgICxtX2FHcmlkQ29udHJvbExpc3RlbmVycygqdGhpcywgR2V0TXV0ZXgoKSkKCQkJICAgLG1fblBlZXJDcmVhdGlvbkxldmVsKDApCgkJCSAgICxtX2JJbkRyYXcoc2FsX0ZhbHNlKQoJCQkgICAsbV94U2VydmljZUZhY3RvcnkoX3J4RmFjdG9yeSkKewoJREJHX0NUT1IoRm1YR3JpZENvbnRyb2wgLE5VTEwpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGbVhHcmlkQ29udHJvbDo6fkZtWEdyaWRDb250cm9sKCkKewoJREJHX0RUT1IoRm1YR3JpZENvbnRyb2wgLE5VTEwpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpBbnkJU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OnF1ZXJ5QWdncmVnYXRpb24oY29uc3QgVHlwZSYgX3JUeXBlKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewoJQW55IGFSZXR1cm4gPSBGbVhHcmlkQ29udHJvbF9CQVNFOjpxdWVyeUludGVyZmFjZShfclR5cGUpOwoKCWlmICghYVJldHVybi5oYXNWYWx1ZSgpKQoJCWFSZXR1cm4gPSBVbm9Db250cm9sOjpxdWVyeUFnZ3JlZ2F0aW9uKCBfclR5cGUgKTsKCXJldHVybiBhUmV0dXJuOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTZXF1ZW5jZTwgVHlwZT4gU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmdldFR5cGVzKCAgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CglyZXR1cm4gY29tcGhlbHBlcjo6Y29uY2F0U2VxdWVuY2VzKFVub0NvbnRyb2w6OmdldFR5cGVzKCksRm1YR3JpZENvbnRyb2xfQkFTRTo6Z2V0VHlwZXMoKSk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNlcXVlbmNlPHNhbF9JbnQ4PiBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6Z2V0SW1wbGVtZW50YXRpb25JZCggICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKewogICAgc3RhdGljIDo6Y3BwdTo6T0ltcGxlbWVudGF0aW9uSWQqIHBJZCA9IDA7CglpZiAoISBwSWQpCgl7CiAgICAgICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCA6Om9zbDo6TXV0ZXg6OmdldEdsb2JhbE11dGV4KCkgKTsKCQlpZiAoISBwSWQpCgkJewoJCQlzdGF0aWMgOjpjcHB1OjpPSW1wbGVtZW50YXRpb25JZCBhSWQ7CgkJCXBJZCA9ICZhSWQ7CgkJfQoJfQoJcmV0dXJuIHBJZC0+Z2V0SW1wbGVtZW50YXRpb25JZCgpOwp9CgovLyBYU2VydmljZUluZm8KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OnN1cHBvcnRzU2VydmljZShjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIFNlcnZpY2VOYW1lKSB0aHJvdygpCnsKCTo6Y29tcGhlbHBlcjo6U3RyaW5nU2VxdWVuY2UgYVN1cHBvcnRlZCA9IGdldFN1cHBvcnRlZFNlcnZpY2VOYW1lcygpOwoJY29uc3QgOjpydGw6Ok9VU3RyaW5nICogcEFycmF5ID0gYVN1cHBvcnRlZC5nZXRDb25zdEFycmF5KCk7Cglmb3IoIHNhbF9JbnQzMiBpID0gMDsgaSA8IGFTdXBwb3J0ZWQuZ2V0TGVuZ3RoKCk7IGkrKyApCgkJaWYoIHBBcnJheVtpXSA9PSBTZXJ2aWNlTmFtZSApCgkJCXJldHVybiBzYWxfVHJ1ZTsKCXJldHVybiBzYWxfRmFsc2U7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZwlTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6Z2V0SW1wbGVtZW50YXRpb25OYW1lKCkgdGhyb3coKQp7CglyZXR1cm4gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoImNvbS5zdW4uc3Rhci5mb3JtLkZtWEdyaWRDb250cm9sIik7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6Y29tcGhlbHBlcjo6U3RyaW5nU2VxdWVuY2UgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmdldFN1cHBvcnRlZFNlcnZpY2VOYW1lcygpIHRocm93KCkKewoJU2VxdWVuY2U8IDo6cnRsOjpPVVN0cmluZyA+IGFTZXJ2aWNlTmFtZXMoMik7CglhU2VydmljZU5hbWVzWzBdID0gRk1fU1VOX0NPTlRST0xfR1JJRENPTlRST0w7CglhU2VydmljZU5hbWVzWzFdID0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoImNvbS5zdW4uc3Rhci5hd3QuVW5vQ29udHJvbCIpOwoJcmV0dXJuIGFTZXJ2aWNlTmFtZXM7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmRpc3Bvc2UoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCTo6dm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJRXZlbnRPYmplY3QgYUV2dDsKCWFFdnQuU291cmNlID0gc3RhdGljX2Nhc3Q8IDo6Y3BwdTo6T1dlYWtPYmplY3QqID4odGhpcyk7CgltX2FNb2RpZnlMaXN0ZW5lcnMuZGlzcG9zZUFuZENsZWFyKGFFdnQpOwoJbV9hVXBkYXRlTGlzdGVuZXJzLmRpc3Bvc2VBbmRDbGVhcihhRXZ0KTsKCW1fYUNvbnRhaW5lckxpc3RlbmVycy5kaXNwb3NlQW5kQ2xlYXIoYUV2dCk7CgoJVW5vQ29udHJvbDo6ZGlzcG9zZSgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OnJ0bDo6T1VTdHJpbmcJRm1YR3JpZENvbnRyb2w6OkdldENvbXBvbmVudFNlcnZpY2VOYW1lKCkKewoJOjpydGw6Ok9VU3RyaW5nIGFOYW1lID0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIkRCR3JpZCIpOwoJcmV0dXJuIGFOYW1lOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6c2V0TW9kZWwoY29uc3QgUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhDb250cm9sTW9kZWwgPiYgck1vZGVsKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCTo6dm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJaWYgKCFVbm9Db250cm9sOjpzZXRNb2RlbChyTW9kZWwpKQoJCXJldHVybiBzYWxfRmFsc2U7CgoJUmVmZXJlbmNlPCBYR3JpZFBlZXIgPiB4R3JpZFBlZXIoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJaWYgKHhHcmlkUGVlci5pcygpKQoJewoJCVJlZmVyZW5jZTwgWEluZGV4Q29udGFpbmVyID4geENvbHMobXhNb2RlbCwgVU5PX1FVRVJZKTsKCQl4R3JpZFBlZXItPnNldENvbHVtbnMoeENvbHMpOwoJfQoJcmV0dXJuIHNhbF9UcnVlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGbVhHcmlkUGVlciogRm1YR3JpZENvbnRyb2w6OmltcF9DcmVhdGVQZWVyKFdpbmRvdyogcFBhcmVudCkKewoJRm1YR3JpZFBlZXIqIHBSZXR1cm4gPSBuZXcgRm1YR3JpZFBlZXIobV94U2VydmljZUZhY3RvcnkpOwoKCS8vIHRyYW5zbGF0ZSBwcm9wZXJ0aWVzIGludG8gV2luQml0cwoJV2luQml0cyBuU3R5bGUgPSBXQl9UQUJTVE9QOwoJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeE1vZGVsU2V0KGdldE1vZGVsKCksIFVOT19RVUVSWSk7CglpZiAoeE1vZGVsU2V0LmlzKCkpCgl7CgkJdHJ5CgkJewoJCQlpZiAoOjpjb21waGVscGVyOjpnZXRJTlQxNih4TW9kZWxTZXQtPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9CT1JERVIpKSkKCQkJCW5TdHlsZSB8PSBXQl9CT1JERVI7CgkJfQoJCWNhdGNoKGNvbnN0IEV4Y2VwdGlvbiYpCgkJewoJCQlPU0xfQVNTRVJUKCEiQ2FuIG5vdCBnZXQgc3R5bGUiKTsKCQl9Cgl9CgoJcFJldHVybi0+Q3JlYXRlKHBQYXJlbnQsIG5TdHlsZSk7CglyZXR1cm4gcFJldHVybjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6Y3JlYXRlUGVlcihjb25zdCBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WFRvb2xraXQgPiYgLypyVG9vbGtpdCovLCBjb25zdCBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WFdpbmRvd1BlZXIgPiYgclBhcmVudFBlZXIpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJaWYgKCAhbXhNb2RlbC5pcygpICkKICAgICAgICB0aHJvdyBEaXNwb3NlZEV4Y2VwdGlvbiggOjpydGw6Ok9VU3RyaW5nKCksICp0aGlzICk7CgoJREJHX0FTU0VSVCgvKigwID09IG1fblBlZXJDcmVhdGlvbkxldmVsKSAmJiAqLyFtYkNyZWF0aW5nUGVlciwgIkZtWEdyaWRDb250cm9sOjpjcmVhdGVQZWVyIDogcmVjdXJzaW9uISIpOwoJCS8vIEkgdGhpbmsgdGhpcyBzaG91bGQgbmV2ZXIgYXNzZXJ0LCBub3cgdGhhdCB3ZSdyZSB1c2luZyB0aGUgYmFzZSBjbGFzcycgbWJDcmVhdGluZ1BlZXIgaW4gYWRkaXRpb24gdG8KCQkvLyBvdXIgb3duIG1fblBlZXJDcmVhdGlvbkxldmVsCgkJLy8gQnV0IEknbSBub3Qgc3VyZSBhcyBJIGRvbid0IF9mdWxseV8gdW5kZXJzdGFuZCB0aGUgdW5kZXJseWluZyB0b29sa2l0IGltcGxlbWVudGF0aW9ucyAuLi4uCgkJLy8gKGlmIHRoaXMgYXNzZXJ0cywgd2Ugc3RpbGwgbmVlZCBtX25QZWVyQ3JlYXRpb25MZXZlbC4gSWYgbm90LCB3ZSBjb3VsZCBvbWl0IGl0IC4uLi4pCgkJLy8gMTQuMDUuMjAwMSAtIDg2ODM2IC0gZnJhbmsuc2Nob2VuaGVpdEBnZXJtYW55LnN1bi5jb20KCgkvLyBUT0RPOiB3aHkgdGhlIGhlbGwgdGhpcyB3aG9sZSBjbGFzcyBkb2VzIG5vdCB1c2UgYW55IG11dGV4PwoKCWlmICghZ2V0UGVlcigpLmlzKCkpCgl7CgkJbWJDcmVhdGluZ1BlZXIgPSBzYWxfVHJ1ZTsKCQkJLy8gbWJDcmVhdGluZ1BlZXIgaXMgdmlydHVhbGx5IHRoZSBzYW1lIGFzIG1fblBlZXJDcmVhdGlvbkxldmVsLCBidXQgaXQncyB0aGUgYmFzZSBjbGFzcycgbWV0aG9kCgkJCS8vIHRvIHByZXZlbnQgcmVjdXJzaW9uLgoKCQlXaW5kb3cqIHBQYXJlbnRXaW4gPSBOVUxMOwoJCWlmIChyUGFyZW50UGVlci5pcygpKQoJCXsKCQkJVkNMWFdpbmRvdyogcFBhcmVudCA9IFZDTFhXaW5kb3c6OkdldEltcGxlbWVudGF0aW9uKHJQYXJlbnRQZWVyKTsKCQkJaWYgKHBQYXJlbnQpCgkJCQlwUGFyZW50V2luID0gcFBhcmVudC0+R2V0V2luZG93KCk7CgkJfQoKCQlGbVhHcmlkUGVlciogcFBlZXIgPSBpbXBfQ3JlYXRlUGVlcihwUGFyZW50V2luKTsKCQlEQkdfQVNTRVJUKHBQZWVyICE9IE5VTEwsICJGbVhHcmlkQ29udHJvbDo6Y3JlYXRlUGVlciA6IGltcF9DcmVhdGVQZWVyIGRpZG4ndCByZXR1cm4gYSBwZWVyICEiKTsKCQlzZXRQZWVyKCBwUGVlciApOwoKCQkvLyBsZXNlbiBkZXIgcHJvcGVydGllcyBhdXMgZGVtIG1vZGVsCi8vCQkrK21fblBlZXJDcmVhdGlvbkxldmVsOwoJCXVwZGF0ZUZyb21Nb2RlbCgpOwoKCQkvLyBmb2xnZW5kZXMgdW5zY2hvZW5lIFN6ZW5hcmlvIDogdXBkYXRlRnJvbU1vZGVsIGZ1ZWhydCB6dSBlaW5lbSBwcm9wZXJ0aWVzQ2hhbmdlZCBhbSBDb250cm9sLAoJCS8vIGRhcyBzdGVsbHQgZmVzdCwgZGFzcyBzaWNoIGVpbmUgJ2tyaXRpc2NoZScgUHJvcGVydHkgZ2VhZW5kZXJ0IGhhdCAoenVtIEJlaXNwaWVsICJCb3JkZXIiKSB1bmQKCQkvLyBsZWd0IGRhcmF1ZmhpbiBlaW5lIG5ldWUgUGVlciBhbiwgd2FzIHdpZWRlciBoaWVyIGltIGNyZWF0ZVBlZXIgbGFuZGV0LCB3aXIgbGVnZW4gYWxzbyBlaW5lCgkJLy8gendlaXRlIEZtWEdyaWRQZWVyIGFuIHVuZCBpbml0aWFsaXNpZXJlbiBkaWUuIERhbm4ga29tbWVuIHdpciBpbiBkZXIgZXJzdGVuIElua2FybmF0aW9uIGF1cwoJCS8vIGRlbSB1cGRzYXRlRnJvbU1vZGVsIHJhdXMgdW5kIGFyYmVpdGVuIGRvcnQgd2VpdGVyIG1pdCBkZW0gcFBlZXIsIGRhcyBqZXR6dCBlaWdlbnRsaWNoIHNjaG9uCgkJLy8gdmVyYWx0ZXQgaXN0IChkYSBqYSBpbiBkZXIgendlaXRlbiBJbmthcm5hdGlvbiBlaW5lIGFuZGVyZSBQZWVyIGFuZ2VsZWd0IHd1cmRlKS4KCQkvLyBEZXN3ZWdlbiBhbHNvIGRlciBBdWZ3YW5kIG1pdCBkZW0gUGVlckNyZWF0aW9uTGV2ZWwsIGRhcyBzdGVsbHQgc2ljaGVyLCBkYXNzIHdpciBkaWUgaW4gZGVtCgkJLy8gdGllZnN0ZW4gTGV2ZWwgYW5nZWxlZ3RlIFBlZXIgd2lya2xpY2ggdmVyd2VuZGVuLCBzaWUgYWJlciBlcnN0IGltIHRvcC1sZXZlbAoJCS8vIGluaXRpYWxpc2llcmVuLgovLwkJaWYgKC0tbV9uUGVlckNyZWF0aW9uTGV2ZWwgPT0gMCkKCQl7CgkJCURCR19BU1NFUlQoZ2V0UGVlcigpLmlzKCksICJGbVhHcmlkQ29udHJvbDo6Y3JlYXRlUGVlciA6IHNvbWV0aGluZyB3ZW50IHdyb25nIC4uLiBubyB0b3AgbGV2ZWwgcGVlciAhIik7CgkJCXBQZWVyID0gRm1YR3JpZFBlZXI6OmdldEltcGxlbWVudGF0aW9uKGdldFBlZXIoKSk7CgoJICAgICAgICBzZXRQb3NTaXplKCBtYUNvbXBvbmVudEluZm9zLm5YLCBtYUNvbXBvbmVudEluZm9zLm5ZLCBtYUNvbXBvbmVudEluZm9zLm5XaWR0aCwgbWFDb21wb25lbnRJbmZvcy5uSGVpZ2h0LCA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlBvc1NpemU6OlBPU1NJWkUgKTsKCgkJCVJlZmVyZW5jZTwgWEluZGV4Q29udGFpbmVyID4gIHhDb2x1bW5zKGdldE1vZGVsKCksIFVOT19RVUVSWSk7CgkJCWlmICh4Q29sdW1ucy5pcygpKQoJCQkJcFBlZXItPnNldENvbHVtbnMoeENvbHVtbnMpOwoKCQkJaWYgKG1hQ29tcG9uZW50SW5mb3MuYlZpc2libGUpCgkJCQlwUGVlci0+c2V0VmlzaWJsZShzYWxfVHJ1ZSk7CgoJCQlpZiAoIW1hQ29tcG9uZW50SW5mb3MuYkVuYWJsZSkKCQkJCXBQZWVyLT5zZXRFbmFibGUoc2FsX0ZhbHNlKTsKCgkJCWlmIChtYVdpbmRvd0xpc3RlbmVycy5nZXRMZW5ndGgoKSkKCQkJCXBQZWVyLT5hZGRXaW5kb3dMaXN0ZW5lciggJm1hV2luZG93TGlzdGVuZXJzICk7CgoJCQlpZiAobWFGb2N1c0xpc3RlbmVycy5nZXRMZW5ndGgoKSkKCQkJCXBQZWVyLT5hZGRGb2N1c0xpc3RlbmVyKCAmbWFGb2N1c0xpc3RlbmVycyApOwoKCQkJaWYgKG1hS2V5TGlzdGVuZXJzLmdldExlbmd0aCgpKQoJCQkJcFBlZXItPmFkZEtleUxpc3RlbmVyKCAmbWFLZXlMaXN0ZW5lcnMgKTsKCgkJCWlmIChtYU1vdXNlTGlzdGVuZXJzLmdldExlbmd0aCgpKQoJCQkJcFBlZXItPmFkZE1vdXNlTGlzdGVuZXIoICZtYU1vdXNlTGlzdGVuZXJzICk7CgoJCQlpZiAobWFNb3VzZU1vdGlvbkxpc3RlbmVycy5nZXRMZW5ndGgoKSkKCQkJCXBQZWVyLT5hZGRNb3VzZU1vdGlvbkxpc3RlbmVyKCAmbWFNb3VzZU1vdGlvbkxpc3RlbmVycyApOwoKCQkJaWYgKG1hUGFpbnRMaXN0ZW5lcnMuZ2V0TGVuZ3RoKCkpCgkJCQlwUGVlci0+YWRkUGFpbnRMaXN0ZW5lciggJm1hUGFpbnRMaXN0ZW5lcnMgKTsKCgkJCWlmIChtX2FNb2RpZnlMaXN0ZW5lcnMuZ2V0TGVuZ3RoKCkpCgkJCQlwUGVlci0+YWRkTW9kaWZ5TGlzdGVuZXIoICZtX2FNb2RpZnlMaXN0ZW5lcnMgKTsKCgkJCWlmIChtX2FVcGRhdGVMaXN0ZW5lcnMuZ2V0TGVuZ3RoKCkpCgkJCQlwUGVlci0+YWRkVXBkYXRlTGlzdGVuZXIoICZtX2FVcGRhdGVMaXN0ZW5lcnMgKTsKCgkJCWlmIChtX2FDb250YWluZXJMaXN0ZW5lcnMuZ2V0TGVuZ3RoKCkpCgkJCQlwUGVlci0+YWRkQ29udGFpbmVyTGlzdGVuZXIoICZtX2FDb250YWluZXJMaXN0ZW5lcnMgKTsKCgkJCS8vIGZvcndhcmQgdGhlIGRlc2lnbiBtb2RlCgkJCXNhbF9Cb29sIGJGb3JjZUFsaXZlUGVlciA9IG1fYkluRHJhdyAmJiAhbWFDb21wb25lbnRJbmZvcy5iVmlzaWJsZTsKCQkJCS8vICh3ZSBmb3JjZSBhIGFsaXZlLW1vZGUgcGVlciBpZiB3ZSdyZSBpbiAiZHJhdyIsIGNhdXNlIGluIHRoaXMgY2FzZSB0aGUgcGVlciB3aWxsIGJlIHVzZWQgZm9yIGRyYXdpbmcgaW4KCQkJCS8vIGZvcmVpZ24gZGV2aWNlcy4gV2UgZW5zdXJlIHRoaXMgd2l0aCB0aGUgdmlzaWJpbGl0eSBjaGVjayBhcyBhbiBsaXZpbmcgcGVlciBpcyBhc3N1bWVkIHRvIGJlIG5vbmNyaXRpY2FsCgkJCQkvLyBvbmx5IGlmIGludmlzaWJsZSkKCQkJQW55IGFPbGRDdXJzb3JCb29rbWFyazsKCQkJaWYgKCFtYkRlc2lnbk1vZGUgfHwgYkZvcmNlQWxpdmVQZWVyKQoJCQl7CgkJCQlSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4gIHhDb21wKGdldE1vZGVsKCksIFVOT19RVUVSWSk7CgkJCQlpZiAoeENvbXAuaXMoKSkKCQkJCXsKCQkJCQlSZWZlcmVuY2U8IFhSb3dTZXQgPiAgeEZvcm0oeENvbXAtPmdldFBhcmVudCgpLCBVTk9fUVVFUlkpOwoJCQkJCS8vIGlzIHRoZSBmb3JtIGFsaXZlPwoJCQkJCS8vIHdlIGNhbiBzZWUgdGhhdCBpZiB0aGUgZm9ybSBjb250YWlucyBjb2x1bW5zCgkJCQkJUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpzZGJjeDo6WENvbHVtbnNTdXBwbGllciA+ICB4Q29sdW1uc1N1cHBsaWVyKHhGb3JtLCBVTk9fUVVFUlkpOwoJCQkJCWlmICh4Q29sdW1uc1N1cHBsaWVyLmlzKCkpCgkJCQkJewoJCQkJCQlpZiAoUmVmZXJlbmNlPCBYSW5kZXhBY2Nlc3MgPiAoeENvbHVtbnNTdXBwbGllci0+Z2V0Q29sdW1ucygpLFVOT19RVUVSWSktPmdldENvdW50KCkpCgkJCQkJCXsKCQkJCQkJCS8vIHdlIGdldCBvbmx5IGEgbmV3IGJvb2ttYXJrIGlmIHRoZSByZXN1bHRzZXQgaXMgbm90IGZvcndhcmRvbmx5CgkJCQkJCQlpZiAoOjpjb21waGVscGVyOjpnZXRJTlQzMihSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICh4Rm9ybSwgVU5PX1FVRVJZKS0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX1JFU1VMVFNFVF9UWVBFKSkgIT0gUmVzdWx0U2V0VHlwZTo6Rk9SV0FSRF9PTkxZKQoJCQkJCQkJewoJCQkJCQkJCS8vIGFzIHRoZSBGbUdyaWRDb250cm9sIHRvdWNoZXMgdGhlIGRhdGEgc291cmNlIGl0IGlzIGNvbm5lY3RlZCB0byB3ZSBoYXZlIHRvIHJlbWVtYmVyIHRoZSBjdXJyZW50CgkJCQkJCQkJLy8gY3Vyc29yIHBvc2l0aW9uIChhbmQgcmVzdG9yZSBhZnRlcndhcmRzKQoJCQkJCQkJCS8vIE9KOiBidXQgb25seSB3aGVuIHdlIHN0YW5kIG9uIGEgdmFsaWQgcm93CgkJCQkJCQkJUmVmZXJlbmNlPCBYUmVzdWx0U2V0ID4geFJlc3VsdFNldCh4Rm9ybSwgVU5PX1FVRVJZKTsKCQkJCQkJCQlpZiAoICF4UmVzdWx0U2V0LT5pc0JlZm9yZUZpcnN0KCkgJiYgIXhSZXN1bHRTZXQtPmlzQWZ0ZXJMYXN0KCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKCQkJCQkJCQkJICAgIGFPbGRDdXJzb3JCb29rbWFyayA9IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6c2RiY3g6OlhSb3dMb2NhdGUgPiAoeEZvcm0sIFVOT19RVUVSWSktPmdldEJvb2ttYXJrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgZSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCllOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCXBQZWVyLT5zZXRSb3dTZXQoeEZvcm0pOwoJCQkJfQoJCQl9CgkJCXBQZWVyLT5zZXREZXNpZ25Nb2RlKG1iRGVzaWduTW9kZSAmJiAhYkZvcmNlQWxpdmVQZWVyKTsKCiAgICAgICAgICAgIHRyeQogICAgICAgICAgICB7CgkJCSAgICBpZiAoYU9sZEN1cnNvckJvb2ttYXJrLmhhc1ZhbHVlKCkpCgkJCSAgICB7CS8vIHdlIGhhdmUgYSB2YWxpZCBib29rbWFyaywgc28gd2UgaGF2ZSB0byByZXN0b3JlIHRoZSBjdXJzb3IncyBwb3NpdGlvbgoJCQkJICAgIFJlZmVyZW5jZTwgWEZvcm1Db21wb25lbnQgPiAgeENvbXAoZ2V0TW9kZWwoKSwgVU5PX1FVRVJZKTsKCQkJCSAgICBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OnNkYmN4OjpYUm93TG9jYXRlID4gIHhMb2NhdGUoeENvbXAtPmdldFBhcmVudCgpLCBVTk9fUVVFUlkpOwoJCQkJICAgIHhMb2NhdGUtPm1vdmVUb0Jvb2ttYXJrKGFPbGRDdXJzb3JCb29rbWFyayk7CgkJCSAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2goIGNvbnN0IEV4Y2VwdGlvbiYgZSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CiAgICAgICAgICAgICAgICAodm9pZCllOwogICAgICAgICAgICB9CgoJCQlSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WFZpZXcgPiAgeFBlZXJWaWV3KGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCQkJeFBlZXJWaWV3LT5zZXRab29tKCBtYUNvbXBvbmVudEluZm9zLm5ab29tWCwgbWFDb21wb25lbnRJbmZvcy5uWm9vbVkgKTsKCQkJeFBlZXJWaWV3LT5zZXRHcmFwaGljcyggbXhHcmFwaGljcyApOwoJCX0KCQltYkNyZWF0aW5nUGVlciA9IHNhbF9GYWxzZTsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkQ29udHJvbDo6YWRkTW9kaWZ5TGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpYTW9kaWZ5TGlzdGVuZXIgPiYgbCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CgltX2FNb2RpZnlMaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKCBsICk7CglpZiggZ2V0UGVlcigpLmlzKCkgJiYgbV9hTW9kaWZ5TGlzdGVuZXJzLmdldExlbmd0aCgpID09IDEgKQoJewoJCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6WE1vZGlmeUJyb2FkY2FzdGVyID4gIHhHcmlkKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCQl4R3JpZC0+YWRkTW9kaWZ5TGlzdGVuZXIoICZtX2FNb2RpZnlMaXN0ZW5lcnMpOwoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6c2VsZWN0KCBjb25zdCBBbnkmIF9yU2VsZWN0aW9uICkgdGhyb3cgKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKewoJOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCVJlZmVyZW5jZTwgWFNlbGVjdGlvblN1cHBsaWVyID4geFBlZXIoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJcmV0dXJuIHhQZWVyLT5zZWxlY3QoX3JTZWxlY3Rpb24pOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpBbnkgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmdldFNlbGVjdGlvbiggICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKCTo6dm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CglSZWZlcmVuY2U8IFhTZWxlY3Rpb25TdXBwbGllciA+IHhQZWVyKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCXJldHVybiB4UGVlci0+Z2V0U2VsZWN0aW9uKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmFkZFNlbGVjdGlvbkNoYW5nZUxpc3RlbmVyKCBjb25zdCBSZWZlcmVuY2U8IFhTZWxlY3Rpb25DaGFuZ2VMaXN0ZW5lciA+JiBfcnhMaXN0ZW5lciApIHRocm93IChSdW50aW1lRXhjZXB0aW9uKQp7CgltX2FTZWxlY3Rpb25MaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKCBfcnhMaXN0ZW5lciApOwoJaWYoIGdldFBlZXIoKS5pcygpICYmIDEgPT0gbV9hU2VsZWN0aW9uTGlzdGVuZXJzLmdldExlbmd0aCgpICkKCXsKCQlSZWZlcmVuY2U8IFhTZWxlY3Rpb25TdXBwbGllciA+IHhHcmlkKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCQl4R3JpZC0+YWRkU2VsZWN0aW9uQ2hhbmdlTGlzdGVuZXIoICZtX2FTZWxlY3Rpb25MaXN0ZW5lcnMpOwoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpyZW1vdmVTZWxlY3Rpb25DaGFuZ2VMaXN0ZW5lciggY29uc3QgUmVmZXJlbmNlPCBYU2VsZWN0aW9uQ2hhbmdlTGlzdGVuZXIgPiYgX3J4TGlzdGVuZXIgKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewoJaWYoIGdldFBlZXIoKS5pcygpICYmIDEgPT0gbV9hU2VsZWN0aW9uTGlzdGVuZXJzLmdldExlbmd0aCgpICkKCXsKCQlSZWZlcmVuY2U8IFhTZWxlY3Rpb25TdXBwbGllciA+IHhHcmlkKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCQl4R3JpZC0+cmVtb3ZlU2VsZWN0aW9uQ2hhbmdlTGlzdGVuZXIoICZtX2FTZWxlY3Rpb25MaXN0ZW5lcnMpOwoJfQoJbV9hU2VsZWN0aW9uTGlzdGVuZXJzLnJlbW92ZUludGVyZmFjZSggX3J4TGlzdGVuZXIgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IHNhbF9Cb29sID4gU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OnF1ZXJ5RmllbGREYXRhVHlwZSggY29uc3QgVHlwZSYgeFR5cGUgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CglpZiAoZ2V0UGVlcigpLmlzKCkpCgl7CgkJUmVmZXJlbmNlPCBYR3JpZEZpZWxkRGF0YVN1cHBsaWVyID4gIHhQZWVyU3VwcGxpZXIoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJCWlmICh4UGVlclN1cHBsaWVyLmlzKCkpCgkJCXJldHVybiB4UGVlclN1cHBsaWVyLT5xdWVyeUZpZWxkRGF0YVR5cGUoeFR5cGUpOwoJfQoKCXJldHVybiBTZXF1ZW5jZTxzYWxfQm9vbD4oKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IEFueSA+IFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpxdWVyeUZpZWxkRGF0YSggc2FsX0ludDMyIG5Sb3csIGNvbnN0IFR5cGUmIHhUeXBlICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKewoJaWYgKGdldFBlZXIoKS5pcygpKQoJewoJCVJlZmVyZW5jZTwgWEdyaWRGaWVsZERhdGFTdXBwbGllciA+ICB4UGVlclN1cHBsaWVyKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCQlpZiAoeFBlZXJTdXBwbGllci5pcygpKQoJCQlyZXR1cm4geFBlZXJTdXBwbGllci0+cXVlcnlGaWVsZERhdGEoblJvdywgeFR5cGUpOwoJfQoKCXJldHVybiBTZXF1ZW5jZTwgQW55PigpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpyZW1vdmVNb2RpZnlMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlhNb2RpZnlMaXN0ZW5lciA+JiBsKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCWlmKCBnZXRQZWVyKCkuaXMoKSAmJiBtX2FNb2RpZnlMaXN0ZW5lcnMuZ2V0TGVuZ3RoKCkgPT0gMSApCgl7CgkJUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpYTW9kaWZ5QnJvYWRjYXN0ZXIgPiAgeEdyaWQoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJCXhHcmlkLT5yZW1vdmVNb2RpZnlMaXN0ZW5lciggJm1fYU1vZGlmeUxpc3RlbmVycyk7Cgl9CgltX2FNb2RpZnlMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKCBsICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmRyYXcoIHNhbF9JbnQzMiB4LCBzYWxfSW50MzIgeSApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCW1fYkluRHJhdyA9IHNhbF9UcnVlOwoJVW5vQ29udHJvbDo6ZHJhdyh4LCB5KTsKCW1fYkluRHJhdyA9IHNhbF9GYWxzZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6c2V0RGVzaWduTW9kZShzYWxfQm9vbCBiT24pIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6TW9kZUNoYW5nZUV2ZW50IGFNb2RlQ2hhbmdlRXZlbnQ7CgogICAgLy8gLS0tIDxtdXRleF9sb2NrPiAtLS0KICAgIHsKICAgIAk6OnZvczo6T0d1YXJkIGFHdWFyZCggQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSApOwoKCSAgICBSZWZlcmVuY2U8IFhSb3dTZXRTdXBwbGllciA+ICB4R3JpZChnZXRQZWVyKCksIFVOT19RVUVSWSk7CgoJICAgIGlmICh4R3JpZC5pcygpICYmIChiT24gIT0gbWJEZXNpZ25Nb2RlIHx8ICghYk9uICYmICF4R3JpZC0+Z2V0Um93U2V0KCkuaXMoKSkpKQoJICAgIHsKCQkgICAgaWYgKGJPbikKCQkgICAgewoJCQkgICAgeEdyaWQtPnNldFJvd1NldChSZWZlcmVuY2U8IFhSb3dTZXQgPiAoKSk7CgkJICAgIH0KCQkgICAgZWxzZQoJCSAgICB7CgkJCSAgICBSZWZlcmVuY2U8IFhGb3JtQ29tcG9uZW50ID4gIHhDb21wKGdldE1vZGVsKCksIFVOT19RVUVSWSk7CgkJCSAgICBpZiAoeENvbXAuaXMoKSkKCQkJICAgIHsKCQkJCSAgICBSZWZlcmVuY2U8IFhSb3dTZXQgPiAgeEZvcm0oeENvbXAtPmdldFBhcmVudCgpLCBVTk9fUVVFUlkpOwoJCQkJICAgIHhHcmlkLT5zZXRSb3dTZXQoeEZvcm0pOwoJCQkgICAgfQoJCSAgICB9CgoJCSAgICBtYkRlc2lnbk1vZGUgPSBiT247CgoJCSAgICBSZWZlcmVuY2U8IFhWY2xXaW5kb3dQZWVyID4gIHhWY2xXaW5kb3dQZWVyKCBnZXRQZWVyKCksIFVOT19RVUVSWSApOwoJCSAgICBpZiAoeFZjbFdpbmRvd1BlZXIuaXMoKSkKCQkJICAgIHhWY2xXaW5kb3dQZWVyLT5zZXREZXNpZ25Nb2RlKGJPbik7CiAgICAgICAgfQoJICAgIG1iRGVzaWduTW9kZSA9IGJPbjsKCgkJLy8gZGlzcG9zZSBvdXIgY3VycmVudCBBY2Nlc3NpYmxlQ29udGV4dCwgaWYgd2UgaGF2ZSBvbmUKCQkvLyAoY2hhbmdpbmcgdGhlIGRlc2lnbiBtb2RlIGltcGxpZXMgaGF2aW5nIGEgbmV3IGltcGxlbWVudGF0aW9uIGZvciB0aGlzIGNvbnRleHQsCgkJLy8gc28gdGhlIG9sZCBvbmUgbXVzdCBiZSBkZWNsYXJlZCBERUZVTkMpCgkJZGlzcG9zZUFjY2Vzc2libGVDb250ZXh0KCk7CgogICAgICAgIC8vIHByZXBhcmUgZmlyaW5nIGFuIGV2ZW50CiAgICAgICAgYU1vZGVDaGFuZ2VFdmVudC5Tb3VyY2UgPSAqdGhpczsKCQlhTW9kZUNoYW5nZUV2ZW50Lk5ld01vZGUgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSggbWJEZXNpZ25Nb2RlID8gImRlc2lnbiIgOiAiYWxpdmUiICk7CiAgICB9CgogICAgLy8gLS0tIDwvbXV0ZXhfbG9jaz4gLS0tCiAgICBtYU1vZGVDaGFuZ2VMaXN0ZW5lcnMubm90aWZ5RWFjaCggJlhNb2RlQ2hhbmdlTGlzdGVuZXI6Om1vZGVDaGFuZ2VkLCBhTW9kZUNoYW5nZUV2ZW50ICk7Cn0KCi8vIFhCb3VuZENvbXBvbmVudAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjphZGRVcGRhdGVMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IFhVcGRhdGVMaXN0ZW5lciA+JiBsKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCW1fYVVwZGF0ZUxpc3RlbmVycy5hZGRJbnRlcmZhY2UoIGwgKTsKCWlmKCBnZXRQZWVyKCkuaXMoKSAmJiBtX2FVcGRhdGVMaXN0ZW5lcnMuZ2V0TGVuZ3RoKCkgPT0gMSApCgl7CgkJUmVmZXJlbmNlPCBYQm91bmRDb21wb25lbnQgPiAgeEJvdW5kKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCQl4Qm91bmQtPmFkZFVwZGF0ZUxpc3RlbmVyKCAmbV9hVXBkYXRlTGlzdGVuZXJzKTsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6cmVtb3ZlVXBkYXRlTGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYVXBkYXRlTGlzdGVuZXIgPiYgbCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglpZiggZ2V0UGVlcigpLmlzKCkgJiYgbV9hVXBkYXRlTGlzdGVuZXJzLmdldExlbmd0aCgpID09IDEgKQoJewoJCVJlZmVyZW5jZTwgWEJvdW5kQ29tcG9uZW50ID4gIHhCb3VuZChnZXRQZWVyKCksIFVOT19RVUVSWSk7CgkJeEJvdW5kLT5yZW1vdmVVcGRhdGVMaXN0ZW5lciggJm1fYVVwZGF0ZUxpc3RlbmVycyk7Cgl9CgltX2FVcGRhdGVMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKCBsICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpjb21taXQoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVJlZmVyZW5jZTwgWEJvdW5kQ29tcG9uZW50ID4gIHhCb3VuZChnZXRQZWVyKCksIFVOT19RVUVSWSk7CglpZiAoeEJvdW5kLmlzKCkpCgkJcmV0dXJuIHhCb3VuZC0+Y29tbWl0KCk7CgllbHNlCgkJcmV0dXJuIHNhbF9UcnVlOwp9CgovLyBYQ29udGFpbmVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmFkZENvbnRhaW5lckxpc3RlbmVyKGNvbnN0IFJlZmVyZW5jZTwgWENvbnRhaW5lckxpc3RlbmVyID4mIGwpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJbV9hQ29udGFpbmVyTGlzdGVuZXJzLmFkZEludGVyZmFjZSggbCApOwoJaWYoIGdldFBlZXIoKS5pcygpICYmIG1fYUNvbnRhaW5lckxpc3RlbmVycy5nZXRMZW5ndGgoKSA9PSAxICkKCXsKCQlSZWZlcmVuY2U8IFhDb250YWluZXIgPiAgeENvbnRhaW5lcihnZXRQZWVyKCksIFVOT19RVUVSWSk7CgkJeENvbnRhaW5lci0+YWRkQ29udGFpbmVyTGlzdGVuZXIoICZtX2FDb250YWluZXJMaXN0ZW5lcnMpOwoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpyZW1vdmVDb250YWluZXJMaXN0ZW5lcihjb25zdCBSZWZlcmVuY2U8IFhDb250YWluZXJMaXN0ZW5lciA+JiBsKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCWlmKCBnZXRQZWVyKCkuaXMoKSAmJiBtX2FDb250YWluZXJMaXN0ZW5lcnMuZ2V0TGVuZ3RoKCkgPT0gMSApCgl7CgkJUmVmZXJlbmNlPCBYQ29udGFpbmVyID4gIHhDb250YWluZXIoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJCXhDb250YWluZXItPnJlbW92ZUNvbnRhaW5lckxpc3RlbmVyKCAmbV9hQ29udGFpbmVyTGlzdGVuZXJzKTsKCX0KCW1fYUNvbnRhaW5lckxpc3RlbmVycy5yZW1vdmVJbnRlcmZhY2UoIGwgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoID4gIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpxdWVyeURpc3BhdGNoKGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlVSTCYgYVVSTCwgY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBhVGFyZ2V0RnJhbWVOYW1lLCBzYWxfSW50MzIgblNlYXJjaEZsYWdzKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaFByb3ZpZGVyID4gIHhQZWVyUHJvdmlkZXIoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJaWYgKHhQZWVyUHJvdmlkZXIuaXMoKSkKCQlyZXR1cm4geFBlZXJQcm92aWRlci0+cXVlcnlEaXNwYXRjaChhVVJMLCBhVGFyZ2V0RnJhbWVOYW1lLCBuU2VhcmNoRmxhZ3MpOwoJZWxzZQoJCXJldHVybiBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2ggPiAoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaCA+ID4gU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OnF1ZXJ5RGlzcGF0Y2hlcyhjb25zdCBTZXF1ZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OkRpc3BhdGNoRGVzY3JpcHRvcj4mIGFEZXNjcmlwdHMpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXIgPiAgeFBlZXJQcm92aWRlcihnZXRQZWVyKCksIFVOT19RVUVSWSk7CglpZiAoeFBlZXJQcm92aWRlci5pcygpKQoJCXJldHVybiB4UGVlclByb3ZpZGVyLT5xdWVyeURpc3BhdGNoZXMoYURlc2NyaXB0cyk7CgllbHNlCgkJcmV0dXJuIFNlcXVlbmNlPCBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2ggPiA+KCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OnJlZ2lzdGVyRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yKGNvbnN0IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaFByb3ZpZGVySW50ZXJjZXB0b3IgPiYgX3hJbnRlcmNlcHRvcikgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdGlvbiA+ICB4UGVlckludGVyY2VwdGlvbihnZXRQZWVyKCksIFVOT19RVUVSWSk7CglpZiAoeFBlZXJJbnRlcmNlcHRpb24uaXMoKSkKCQl4UGVlckludGVyY2VwdGlvbi0+cmVnaXN0ZXJEaXNwYXRjaFByb3ZpZGVySW50ZXJjZXB0b3IoX3hJbnRlcmNlcHRvcik7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OnJlbGVhc2VEaXNwYXRjaFByb3ZpZGVySW50ZXJjZXB0b3IoY29uc3QgUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXJJbnRlcmNlcHRvciA+JiBfeEludGVyY2VwdG9yKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaFByb3ZpZGVySW50ZXJjZXB0aW9uID4gIHhQZWVySW50ZXJjZXB0aW9uKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCWlmICh4UGVlckludGVyY2VwdGlvbi5pcygpKQoJCXhQZWVySW50ZXJjZXB0aW9uLT5yZWxlYXNlRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yKF94SW50ZXJjZXB0b3IpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjphZGRHcmlkQ29udHJvbExpc3RlbmVyKCBjb25zdCBSZWZlcmVuY2U8IFhHcmlkQ29udHJvbExpc3RlbmVyID4mIF9saXN0ZW5lciApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCBHZXRNdXRleCgpICk7CgoJbV9hR3JpZENvbnRyb2xMaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKCBfbGlzdGVuZXIgKTsKCWlmICggZ2V0UGVlcigpLmlzKCkgJiYgMSA9PSBtX2FHcmlkQ29udHJvbExpc3RlbmVycy5nZXRMZW5ndGgoKSApCgl7CgkJUmVmZXJlbmNlPCBYR3JpZENvbnRyb2wgPiB4UGVlckdyaWQoIGdldFBlZXIoKSwgVU5PX1FVRVJZICk7CiAgICAgICAgaWYgKCB4UGVlckdyaWQuaXMoKSApCgkJICAgIHhQZWVyR3JpZC0+YWRkR3JpZENvbnRyb2xMaXN0ZW5lciggJm1fYUdyaWRDb250cm9sTGlzdGVuZXJzICk7Cgl9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OnJlbW92ZUdyaWRDb250cm9sTGlzdGVuZXIoIGNvbnN0IFJlZmVyZW5jZTwgWEdyaWRDb250cm9sTGlzdGVuZXIgPiYgX2xpc3RlbmVyICkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIEdldE11dGV4KCkgKTsKCglpZiggZ2V0UGVlcigpLmlzKCkgJiYgMSA9PSBtX2FHcmlkQ29udHJvbExpc3RlbmVycy5nZXRMZW5ndGgoKSApCgl7CgkJUmVmZXJlbmNlPCBYR3JpZENvbnRyb2wgPiB4UGVlckdyaWQoIGdldFBlZXIoKSwgVU5PX1FVRVJZICk7CiAgICAgICAgaWYgKCB4UGVlckdyaWQuaXMoKSApCgkJICAgIHhQZWVyR3JpZC0+cmVtb3ZlR3JpZENvbnRyb2xMaXN0ZW5lciggJm1fYUdyaWRDb250cm9sTGlzdGVuZXJzICk7Cgl9CgogICAgbV9hR3JpZENvbnRyb2xMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKCBfbGlzdGVuZXIgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0ludDE2IFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpnZXRDdXJyZW50Q29sdW1uUG9zaXRpb24oKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKICAgIFJlZmVyZW5jZTwgWEdyaWRDb250cm9sID4geEdyaWQoIGdldFBlZXIoKSwgVU5PX1FVRVJZICk7CglyZXR1cm4geEdyaWQuaXMoKSA/IHhHcmlkLT5nZXRDdXJyZW50Q29sdW1uUG9zaXRpb24oKSA6IC0xOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpzZXRDdXJyZW50Q29sdW1uUG9zaXRpb24oc2FsX0ludDE2IG5Qb3MpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgUmVmZXJlbmNlPCBYR3JpZENvbnRyb2wgPiB4R3JpZCggZ2V0UGVlcigpLCBVTk9fUVVFUlkgKTsKCWlmICggeEdyaWQuaXMoKSApCgl7CgkJOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCQl4R3JpZC0+c2V0Q3VycmVudENvbHVtblBvc2l0aW9uKCBuUG9zICk7Cgl9Cn0KCi8vIFhFbGVtZW50QWNjZXNzCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIFNBTF9DQUxMIEZtWEdyaWRDb250cm9sOjpoYXNFbGVtZW50cygpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJUmVmZXJlbmNlPCBYRWxlbWVudEFjY2VzcyA+ICB4UGVlcihnZXRQZWVyKCksIFVOT19RVUVSWSk7CglyZXR1cm4geFBlZXIuaXMoKSA/IHhQZWVyLT5oYXNFbGVtZW50cygpIDogMDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVHlwZSBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6Z2V0RWxlbWVudFR5cGUoICApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCnsKCXJldHVybiA6OmdldENwcHVUeXBlKChjb25zdCBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmF3dDo6WFRleHRDb21wb25lbnQgPiopTlVMTCk7Cn0KCi8vIFhFbnVtZXJhdGlvbkFjY2VzcwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhFbnVtZXJhdGlvbiA+ICBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6Y3JlYXRlRW51bWVyYXRpb24oKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVJlZmVyZW5jZTwgWEVudW1lcmF0aW9uQWNjZXNzID4gIHhQZWVyKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCWlmICh4UGVlci5pcygpKQoJCXJldHVybiB4UGVlci0+Y3JlYXRlRW51bWVyYXRpb24oKTsKCWVsc2UKCQlyZXR1cm4gbmV3IDo6Y29tcGhlbHBlcjo6T0VudW1lcmF0aW9uQnlJbmRleCh0aGlzKTsKfQoKLy8gWEluZGV4QWNjZXNzCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9JbnQzMiBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6Z2V0Q291bnQoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVJlZmVyZW5jZTwgWEluZGV4QWNjZXNzID4gIHhQZWVyKGdldFBlZXIoKSwgVU5PX1FVRVJZKTsKCXJldHVybiB4UGVlci5pcygpID8geFBlZXItPmdldENvdW50KCkgOiAwOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpBbnkgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmdldEJ5SW5kZXgoc2FsX0ludDMyIF9uSW5kZXgpIHRocm93KCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uICkKewoJUmVmZXJlbmNlPCBYSW5kZXhBY2Nlc3MgPiAgeFBlZXIoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJaWYgKCF4UGVlci5pcygpKQoJCXRocm93IEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oKTsKCglyZXR1cm4geFBlZXItPmdldEJ5SW5kZXgoX25JbmRleCk7Cn0KCi8vIDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlhNb2RlU2VsZWN0b3IKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6c2V0TW9kZShjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIE1vZGUpIHRocm93KCBOb1N1cHBvcnRFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlhNb2RlU2VsZWN0b3IgPiAgeFBlZXIoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJaWYgKCF4UGVlci5pcygpKQoJCXRocm93IE5vU3VwcG9ydEV4Y2VwdGlvbigpOwoKCXhQZWVyLT5zZXRNb2RlKE1vZGUpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo6OnJ0bDo6T1VTdHJpbmcgU0FMX0NBTEwgRm1YR3JpZENvbnRyb2w6OmdldE1vZGUoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6WE1vZGVTZWxlY3RvciA+ICB4UGVlcihnZXRQZWVyKCksIFVOT19RVUVSWSk7CglyZXR1cm4geFBlZXIuaXMoKSA/IHhQZWVyLT5nZXRNb2RlKCkgOiA6OnJ0bDo6T1VTdHJpbmcoKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpjb21waGVscGVyOjpTdHJpbmdTZXF1ZW5jZSBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6Z2V0U3VwcG9ydGVkTW9kZXMoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6WE1vZGVTZWxlY3RvciA+ICB4UGVlcihnZXRQZWVyKCksIFVOT19RVUVSWSk7CglyZXR1cm4geFBlZXIuaXMoKSA/IHhQZWVyLT5nZXRTdXBwb3J0ZWRNb2RlcygpIDogOjpjb21waGVscGVyOjpTdHJpbmdTZXF1ZW5jZSgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBTQUxfQ0FMTCBGbVhHcmlkQ29udHJvbDo6c3VwcG9ydHNNb2RlKGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgTW9kZSkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlhNb2RlU2VsZWN0b3IgPiAgeFBlZXIoZ2V0UGVlcigpLCBVTk9fUVVFUlkpOwoJcmV0dXJuIHhQZWVyLmlzKCkgPyB4UGVlci0+c3VwcG9ydHNNb2RlKE1vZGUpIDogc2FsX0ZhbHNlOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLz0gRm1YR3JpZFBlZXIKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gaGVscGVyIGNsYXNzIHdoaWNoIHByZXZlbnRzIHRoYXQgaW4gdGhlIHBlZXIncyBoZWFkZXIgdGhlIEZtR3JpZExpc3RlbmVyIG11c3QgYmUga25vd24KY2xhc3MgRm1YR3JpZFBlZXI6OkdyaWRMaXN0ZW5lckRlbGVnYXRvciA6IHB1YmxpYyBGbUdyaWRMaXN0ZW5lcgp7CnByb3RlY3RlZDoKCUZtWEdyaWRQZWVyKgkJbV9wUGVlcjsKCnB1YmxpYzoKCUdyaWRMaXN0ZW5lckRlbGVnYXRvciggRm1YR3JpZFBlZXIqIF9wUGVlciApOwoKcHJvdGVjdGVkOgoJdmlydHVhbCB2b2lkIHNlbGVjdGlvbkNoYW5nZWQoKTsKICAgIHZpcnR1YWwgdm9pZCBjb2x1bW5DaGFuZ2VkKCk7Cn07CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGbVhHcmlkUGVlcjo6R3JpZExpc3RlbmVyRGVsZWdhdG9yOjpHcmlkTGlzdGVuZXJEZWxlZ2F0b3IoRm1YR3JpZFBlZXIqIF9wUGVlcikKCTptX3BQZWVyKF9wUGVlcikKewoJREJHX0FTU0VSVChtX3BQZWVyLCAiR3JpZExpc3RlbmVyRGVsZWdhdG9yOjpHcmlkTGlzdGVuZXJEZWxlZ2F0b3IiKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6R3JpZExpc3RlbmVyRGVsZWdhdG9yOjpzZWxlY3Rpb25DaGFuZ2VkKCkKewoJbV9wUGVlci0+c2VsZWN0aW9uQ2hhbmdlZCgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpHcmlkTGlzdGVuZXJEZWxlZ2F0b3I6OmNvbHVtbkNoYW5nZWQoKQp7CgltX3BQZWVyLT5jb2x1bW5DaGFuZ2VkKCk7Cn0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWEludGVyZmFjZSA+ICBGbVhHcmlkUGVlcl9DcmVhdGVJbnN0YW5jZShjb25zdCBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5PiYgX3J4RmFjdG9yeSkKewoJRm1YR3JpZFBlZXIqIHBOZXdPYmplY3QgPSBuZXcgRm1YR3JpZFBlZXIoX3J4RmFjdG9yeSk7CglwTmV3T2JqZWN0LT5DcmVhdGUoTlVMTCwgV0JfVEFCU1RPUCk7CglyZXR1cm4gKnBOZXdPYmplY3Q7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNlcXVlbmNlPCBUeXBlPiBTQUxfQ0FMTCBGbVhHcmlkUGVlcjo6Z2V0VHlwZXMoICApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCnsKICAgIHJldHVybiBjb21waGVscGVyOjpjb25jYXRTZXF1ZW5jZXMoIFZDTFhXaW5kb3c6OmdldFR5cGVzKCksIEZtWEdyaWRQZWVyX0JBU0U6OmdldFR5cGVzKCkgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8c2FsX0ludDg+IFNBTF9DQUxMIEZtWEdyaWRQZWVyOjpnZXRJbXBsZW1lbnRhdGlvbklkKCAgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CiAgICBzdGF0aWMgOjpjcHB1OjpPSW1wbGVtZW50YXRpb25JZCogcElkID0gMDsKCWlmICghIHBJZCkKCXsKICAgICAgICA6Om9zbDo6TXV0ZXhHdWFyZCBhR3VhcmQoIDo6b3NsOjpNdXRleDo6Z2V0R2xvYmFsTXV0ZXgoKSApOwoJCWlmICghIHBJZCkKCQl7CgkJCXN0YXRpYyA6OmNwcHU6Ok9JbXBsZW1lbnRhdGlvbklkIGFJZDsKCQkJcElkID0gJmFJZDsKCQl9Cgl9CglyZXR1cm4gcElkLT5nZXRJbXBsZW1lbnRhdGlvbklkKCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkFueQlTQUxfQ0FMTCBGbVhHcmlkUGVlcjo6cXVlcnlJbnRlcmZhY2UoY29uc3QgVHlwZSYgX3JUeXBlKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewogICAgQW55IGFSZXR1cm4gPSBGbVhHcmlkUGVlcl9CQVNFOjpxdWVyeUludGVyZmFjZShfclR5cGUpOwoKCWlmICghYVJldHVybi5oYXNWYWx1ZSgpKQoJCWFSZXR1cm4gPSBWQ0xYV2luZG93OjpxdWVyeUludGVyZmFjZSggX3JUeXBlICk7CgoJcmV0dXJuIGFSZXR1cm47Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OnNlbGVjdGlvbkNoYW5nZWQoKQp7CglFdmVudE9iamVjdCBhU291cmNlOwoJYVNvdXJjZS5Tb3VyY2UgPSBzdGF0aWNfY2FzdDwgOjpjcHB1OjpPV2Vha09iamVjdCogPih0aGlzKTsKICAgIG1fYVNlbGVjdGlvbkxpc3RlbmVycy5ub3RpZnlFYWNoKCAmWFNlbGVjdGlvbkNoYW5nZUxpc3RlbmVyOjpzZWxlY3Rpb25DaGFuZ2VkLCBhU291cmNlKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6Y29sdW1uQ2hhbmdlZCgpCnsKCUV2ZW50T2JqZWN0IGFFdmVudCggKnRoaXMgKTsKICAgIG1fYUdyaWRDb250cm9sTGlzdGVuZXJzLm5vdGlmeUVhY2goICZYR3JpZENvbnRyb2xMaXN0ZW5lcjo6Y29sdW1uQ2hhbmdlZCwgYUV2ZW50ICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCm5hbWVzcGFjZSBmbWdyaWRpZgp7Cgljb25zdCA6OnJ0bDo6T1VTdHJpbmcgZ2V0RGF0YU1vZGVJZGVudGlmaWVyKCkKCXsKCQlzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIHNfc0RhdGFNb2RlSWRlbnRpZmllciA9IDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiRGF0YU1vZGUiICkgKTsKCQlyZXR1cm4gc19zRGF0YU1vZGVJZGVudGlmaWVyOwoJfQp9CnVzaW5nIG5hbWVzcGFjZSBmbWdyaWRpZjsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkZtWEdyaWRQZWVyOjpGbVhHcmlkUGVlcihjb25zdCBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4mIF9yeEZhY3RvcnkpCgkJCTptX2FNb2RpZnlMaXN0ZW5lcnMobV9hTXV0ZXgpCgkJCSxtX2FVcGRhdGVMaXN0ZW5lcnMobV9hTXV0ZXgpCgkJCSxtX2FDb250YWluZXJMaXN0ZW5lcnMobV9hTXV0ZXgpCgkJCSxtX2FTZWxlY3Rpb25MaXN0ZW5lcnMobV9hTXV0ZXgpCiAgICAgICAgICAgICxtX2FHcmlkQ29udHJvbExpc3RlbmVycyhtX2FNdXRleCkKICAgICAgICAgICAgLG1fYU1vZGUoIGdldERhdGFNb2RlSWRlbnRpZmllcigpICkKICAgICAgICAgICAgLG1fbkN1cnNvckxpc3RlbmluZygwKQogICAgICAgICAgICAsbV9iSW50ZXJjZXB0aW5nRGlzcGF0Y2goc2FsX0ZhbHNlKQoJCQksbV9wU3RhdGVDYWNoZShOVUxMKQoJCQksbV9wRGlzcGF0Y2hlcnMoTlVMTCkKICAgICAgICAgICAgLG1fcEdyaWRMaXN0ZW5lcihOVUxMKQoJCQksbV94U2VydmljZUZhY3RvcnkoX3J4RmFjdG9yeSkKewoJLy8gbmFjaCBkaWVzZW0gQ29uc3RydWN0b3IgbXVzcyBDcmVhdGUgZ2VydWZlbiB3ZXJkZW4gIQoJbV9wR3JpZExpc3RlbmVyID0gbmV3IEdyaWRMaXN0ZW5lckRlbGVnYXRvciggdGhpcyApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGbUdyaWRDb250cm9sKiBGbVhHcmlkUGVlcjo6aW1wX0NyZWF0ZUNvbnRyb2woV2luZG93KiBwUGFyZW50LCBXaW5CaXRzIG5TdHlsZSkKewoJcmV0dXJuIG5ldyBGbUdyaWRDb250cm9sKG1feFNlcnZpY2VGYWN0b3J5LCBwUGFyZW50LCB0aGlzLCBuU3R5bGUpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpDcmVhdGUoV2luZG93KiBwUGFyZW50LCBXaW5CaXRzIG5TdHlsZSkKewoJRm1HcmlkQ29udHJvbCogcFdpbiA9IGltcF9DcmVhdGVDb250cm9sKHBQYXJlbnQsIG5TdHlsZSk7CglEQkdfQVNTRVJUKHBXaW4gIT0gTlVMTCwgIkZtWEdyaWRQZWVyOjpDcmVhdGUgOiBpbXBfQ3JlYXRlQ29udHJvbCBkaWRuJ3QgcmV0dXJuIGEgY29udHJvbCAhIik7CgoJcFdpbi0+U2V0U3RhdGVQcm92aWRlcihMSU5LKHRoaXMsIEZtWEdyaWRQZWVyLCBPblF1ZXJ5R3JpZFNsb3RTdGF0ZSkpOwoJcFdpbi0+U2V0U2xvdEV4ZWN1dG9yKExJTksodGhpcywgRm1YR3JpZFBlZXIsIE9uRXhlY3V0ZUdyaWRTbG90KSk7CgoJLy8gd2FudCB0byBoZWFyIGFib3V0IHJvdyBzZWxlY3Rpb25zCglwV2luLT5zZXRHcmlkTGlzdGVuZXIoIG1fcEdyaWRMaXN0ZW5lciApOwoKCS8vIEluaXQgbXXfIGltbWVyIGF1ZmdlcnVmZW4gd2VyZGVuCglwV2luLT5Jbml0KCk7CglwV2luLT5TZXRDb21wb25lbnRJbnRlcmZhY2UodGhpcyk7CgoJZ2V0U3VwcG9ydGVkVVJMcygpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpGbVhHcmlkUGVlcjo6fkZtWEdyaWRQZWVyKCkKewoJc2V0Um93U2V0KFJlZmVyZW5jZTwgWFJvd1NldCA+ICgpKTsKCXNldENvbHVtbnMoUmVmZXJlbmNlPCBYSW5kZXhDb250YWluZXIgPiAoKSk7CgoJZGVsZXRlIG1fcEdyaWRMaXN0ZW5lcjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KY29uc3QgU2VxdWVuY2U8IHNhbF9JbnQ4ID4mCUZtWEdyaWRQZWVyOjpnZXRVbm9UdW5uZWxJbXBsZW1lbnRhdGlvbklkKCkgdGhyb3coKQp7CglzdGF0aWMgU2VxdWVuY2U8IHNhbF9JbnQ4ID4gKiBwU2VxID0gMDsKCWlmKCAhcFNlcSApCgl7CgkJOjpvc2w6Ok11dGV4R3VhcmQgYUd1YXJkKCA6Om9zbDo6TXV0ZXg6OmdldEdsb2JhbE11dGV4KCkgKTsKCQlpZiggIXBTZXEgKQoJCXsKCQkJc3RhdGljIFNlcXVlbmNlPCBzYWxfSW50OCA+IGFTZXEoIDE2ICk7CgkJCXJ0bF9jcmVhdGVVdWlkKCAoc2FsX3VJbnQ4KilhU2VxLmdldEFycmF5KCksIDAsIHNhbF9UcnVlICk7CgkJCXBTZXEgPSAmYVNlcTsKCQl9Cgl9CglyZXR1cm4gKnBTZXE7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkZtWEdyaWRQZWVyKiBGbVhHcmlkUGVlcjo6Z2V0SW1wbGVtZW50YXRpb24oIGNvbnN0IFJlZmVyZW5jZTwgWEludGVyZmFjZSA+JiBfcnhJRmFjZSApIHRocm93KCkKewoJRm1YR3JpZFBlZXIqIHBSZXR1cm4gPSBOVUxMOwoJUmVmZXJlbmNlPCBYVW5vVHVubmVsID4gIHhUdW5uZWwoX3J4SUZhY2UsIFVOT19RVUVSWSk7CglpZiAoeFR1bm5lbC5pcygpKQoJCXBSZXR1cm4gPSByZWludGVycHJldF9jYXN0PEZtWEdyaWRQZWVyKj4oeFR1bm5lbC0+Z2V0U29tZXRoaW5nKGdldFVub1R1bm5lbEltcGxlbWVudGF0aW9uSWQoKSkpOwoKCXJldHVybiBwUmV0dXJuOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfSW50NjQgU0FMX0NBTEwgRm1YR3JpZFBlZXI6OmdldFNvbWV0aGluZyggY29uc3QgU2VxdWVuY2U8IHNhbF9JbnQ4ID4mIF9ySWRlbnRpZmllciApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCnsKCXNhbF9JbnQ2NCBuUmV0dXJuKDApOwoKCWlmCSgJKF9ySWRlbnRpZmllci5nZXRMZW5ndGgoKSA9PSAxNikKCQkmJgkoMCA9PSBydGxfY29tcGFyZU1lbW9yeSggZ2V0VW5vVHVubmVsSW1wbGVtZW50YXRpb25JZCgpLmdldENvbnN0QXJyYXkoKSwgX3JJZGVudGlmaWVyLmdldENvbnN0QXJyYXkoKSwgMTYgKSkKCQkpCgl7CgkJblJldHVybiA9IHJlaW50ZXJwcmV0X2Nhc3Q8c2FsX0ludDY0Pih0aGlzKTsKCX0KCWVsc2UKCQluUmV0dXJuID0gVkNMWFdpbmRvdzo6Z2V0U29tZXRoaW5nKF9ySWRlbnRpZmllcik7CgoJcmV0dXJuIG5SZXR1cm47Cn0KCi8vIFhFdmVudExpc3RlbmVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OmRpc3Bvc2luZyhjb25zdCBFdmVudE9iamVjdCYgZSkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOwogICAgYm9vbCBiS25vd25TZW5kZXIgPSBmYWxzZTsKCiAgICBSZWZlcmVuY2U8IFhJbmRleENvbnRhaW5lciA+ICB4Q29scyggZS5Tb3VyY2UsIFVOT19RVUVSWSApOwoJaWYgKCB4Q29scy5pcygpICkKICAgIHsKCQlzZXRDb2x1bW5zKFJlZmVyZW5jZTwgWEluZGV4Q29udGFpbmVyID4gKCkpOwogICAgICAgIGJLbm93blNlbmRlciA9IHRydWU7CiAgICB9CgoJUmVmZXJlbmNlPCBYUm93U2V0ID4gIHhDdXJzb3IoZS5Tb3VyY2UsIFVOT19RVUVSWSk7CglpZiAoeEN1cnNvci5pcygpKQoJewoJCXNldFJvd1NldCggbV94Q3Vyc29yICk7CgkJbV94Q3Vyc29yID0gTlVMTDsKICAgICAgICBiS25vd25TZW5kZXIgPSB0cnVlOwoJfQoKCglpZiAoICFiS25vd25TZW5kZXIgJiYgbV9wRGlzcGF0Y2hlcnMgKQoJewoJCWNvbnN0IFNlcXVlbmNlPCBVUkw+JiBhU3VwcG9ydGVkVVJMcyA9IGdldFN1cHBvcnRlZFVSTHMoKTsKCQljb25zdCBVUkwqIHBTdXBwb3J0ZWRVUkxzID0gYVN1cHBvcnRlZFVSTHMuZ2V0Q29uc3RBcnJheSgpOwoJCWZvciAoIHNhbF91SW50MTYgaT0wOyBpIDwgKCBhU3VwcG9ydGVkVVJMcy5nZXRMZW5ndGgoKSApICYmICFiS25vd25TZW5kZXI7ICsraSwgKytwU3VwcG9ydGVkVVJMcyApCgkJewoJCQlpZiAoIG1fcERpc3BhdGNoZXJzW2ldID09IGUuU291cmNlICkKCQkJewoJCQkJbV9wRGlzcGF0Y2hlcnNbaV0tPnJlbW92ZVN0YXR1c0xpc3RlbmVyKCBzdGF0aWNfY2FzdDwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhTdGF0dXNMaXN0ZW5lciogPiggdGhpcyApLCAqcFN1cHBvcnRlZFVSTHMgKTsKCQkJCW1fcERpc3BhdGNoZXJzW2ldID0gTlVMTDsKCQkJCW1fcFN0YXRlQ2FjaGVbaV0gPSAwOwogICAgICAgICAgICAgICAgYktub3duU2VuZGVyID0gdHJ1ZTsKCQkJfQoJCX0KCX0KCiAgICBpZiAoICFiS25vd25TZW5kZXIgKQogICAgICAgIFZDTFhXaW5kb3c6OmRpc3Bvc2luZyhlKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6YWRkTW9kaWZ5TGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpYTW9kaWZ5TGlzdGVuZXIgPiYgbCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CgltX2FNb2RpZnlMaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKCBsICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OnJlbW92ZU1vZGlmeUxpc3RlbmVyKGNvbnN0IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6WE1vZGlmeUxpc3RlbmVyID4mIGwpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJbV9hTW9kaWZ5TGlzdGVuZXJzLnJlbW92ZUludGVyZmFjZSggbCApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojZGVmaW5lIExBU1RfS05PV05fVFlQRQkJRm9ybUNvbXBvbmVudFR5cGU6OlBBVFRFUk5GSUVMRApTZXF1ZW5jZTwgc2FsX0Jvb2wgPiBTQUxfQ0FMTCBGbVhHcmlkUGVlcjo6cXVlcnlGaWVsZERhdGFUeXBlKCBjb25zdCBUeXBlJiB4VHlwZSApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCnsKCS8vIGVpbmUgJ0tvbnZlcnRpZXJ1bmdzdGFiZWxsZScKCXN0YXRpYyBzYWxfQm9vbCBiQ2FuQ29udmVydFtMQVNUX0tOT1dOX1RZUEVdWzRdID0KCXsKCQl7IHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSB9LAkvLwlGb3JtQ29tcG9uZW50VHlwZTo6Q09OVFJPTAoJCXsgc2FsX0ZhbHNlLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlIH0sCS8vCUZvcm1Db21wb25lbnRUeXBlOjpDT01NQU5EQlVUVE9OCgkJeyBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgfSwJLy8JRm9ybUNvbXBvbmVudFR5cGU6OlJBRElPQlVUVE9OCgkJeyBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgfSwJLy8JRm9ybUNvbXBvbmVudFR5cGU6OklNQUdFQlVUVE9OCgkJeyBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfVHJ1ZSAgfSwJLy8JRm9ybUNvbXBvbmVudFR5cGU6OkNIRUNLQk9YCgkJeyBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgfSwJLy8JRm9ybUNvbXBvbmVudFR5cGU6OkxJU1RCT1gKCQl7IHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSB9LAkvLwlGb3JtQ29tcG9uZW50VHlwZTo6Q09NQk9CT1gKCQl7IHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSB9LAkvLwlGb3JtQ29tcG9uZW50VHlwZTo6R1JPVVBCT1gKCQl7IHNhbF9UcnVlICwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSB9LAkvLwlGb3JtQ29tcG9uZW50VHlwZTo6VEVYVEZJRUxECgkJeyBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgfSwJLy8JRm9ybUNvbXBvbmVudFR5cGU6OkZJWEVEVEVYVAoJCXsgc2FsX0ZhbHNlLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlIH0sCS8vCUZvcm1Db21wb25lbnRUeXBlOjpHUklEQ09OVFJPTAoJCXsgc2FsX0ZhbHNlLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlIH0sCS8vCUZvcm1Db21wb25lbnRUeXBlOjpGSUxFQ09OVFJPTAoJCXsgc2FsX0ZhbHNlLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlIH0sCS8vCUZvcm1Db21wb25lbnRUeXBlOjpISURERU5DT05UUk9MCgkJeyBzYWxfRmFsc2UsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgfSwJLy8JRm9ybUNvbXBvbmVudFR5cGU6OklNQUdFQ09OVFJPTAoJCXsgc2FsX1RydWUgLCBzYWxfVHJ1ZSAsIHNhbF9UcnVlICwgc2FsX0ZhbHNlIH0sCS8vCUZvcm1Db21wb25lbnRUeXBlOjpEQVRFRklFTEQKCQl7IHNhbF9UcnVlICwgc2FsX1RydWUgLCBzYWxfRmFsc2UsIHNhbF9GYWxzZSB9LAkvLwlGb3JtQ29tcG9uZW50VHlwZTo6VElNRUZJRUxECgkJeyBzYWxfVHJ1ZSAsIHNhbF9UcnVlICwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgfSwJLy8JRm9ybUNvbXBvbmVudFR5cGU6Ok5VTUVSSUNGSUVMRAoJCXsgc2FsX1RydWUgLCBzYWxfVHJ1ZSAsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlIH0sCS8vCUZvcm1Db21wb25lbnRUeXBlOjpDVVJSRU5DWUZJRUxECgkJeyBzYWxfVHJ1ZSAsIHNhbF9GYWxzZSwgc2FsX0ZhbHNlLCBzYWxfRmFsc2UgfSAJLy8JRm9ybUNvbXBvbmVudFR5cGU6OlBBVFRFUk5GSUVMRAoJfTsKCgoJc2FsX0ludDE2IG5NYXBDb2x1bW4gPSAtMTsKCXN3aXRjaCAoeFR5cGUuZ2V0VHlwZUNsYXNzKCkpCgl7CgkJY2FzZSBUeXBlQ2xhc3NfU1RSSU5HCQkJOiBuTWFwQ29sdW1uID0gMDsgYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfRkxPQVQ6CgkJY2FzZSBUeXBlQ2xhc3NfRE9VQkxFCQkJOiBuTWFwQ29sdW1uID0gMTsgYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfU0hPUlQ6CgkJY2FzZSBUeXBlQ2xhc3NfTE9ORzoKCQljYXNlIFR5cGVDbGFzc19VTlNJR05FRF9MT05HOgoJCWNhc2UgVHlwZUNsYXNzX1VOU0lHTkVEX1NIT1JUCTogbk1hcENvbHVtbiA9IDI7IGJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX0JPT0xFQU4JCQk6IG5NYXBDb2x1bW4gPSAzOyBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKCX0KCglSZWZlcmVuY2U8IFhJbmRleENvbnRhaW5lciA+ICB4Q29sdW1ucyA9IGdldENvbHVtbnMoKTsKCglGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKikgR2V0V2luZG93KCk7CglzYWxfSW50MzIgbkNvbHVtbnMgPSBwR3JpZC0+R2V0Vmlld0NvbENvdW50KCk7CgoJRGJHcmlkQ29sdW1ucyBhQ29sdW1ucyA9IHBHcmlkLT5HZXRDb2x1bW5zKCk7CgoJU2VxdWVuY2U8c2FsX0Jvb2w+IGFSZXR1cm5TZXF1ZW5jZShuQ29sdW1ucyk7CglzYWxfQm9vbCogcFJldHVybkFycmF5ID0gYVJldHVyblNlcXVlbmNlLmdldEFycmF5KCk7CgoJc2FsX0Jvb2wgYlJlcXVlc3RlZEFzQW55ID0gKHhUeXBlLmdldFR5cGVDbGFzcygpID09IFR5cGVDbGFzc19BTlkpOwoKCURiR3JpZENvbHVtbiogcENvbDsKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6c2RiOjpYQ29sdW1uID4gIHhGaWVsZENvbnRlbnQ7CglSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4Q3VycmVudENvbHVtbjsKCWZvciAoc2FsX0ludDMyIGk9MDsgaTxuQ29sdW1uczsgKytpKQoJewoJCWlmIChiUmVxdWVzdGVkQXNBbnkpCgkJewoJCQlwUmV0dXJuQXJyYXlbaV0gPSBzYWxfVHJ1ZTsKCQkJY29udGludWU7CgkJfQoKCQlwUmV0dXJuQXJyYXlbaV0gPSBzYWxfRmFsc2U7CgoJCXNhbF91SW50MTYgbk1vZGVsUG9zID0gcEdyaWQtPkdldE1vZGVsQ29sdW1uUG9zKHBHcmlkLT5HZXRDb2x1bW5JZEZyb21WaWV3UG9zKChzYWxfdUludDE2KWkpKTsKCQlEQkdfQVNTRVJUKG5Nb2RlbFBvcyAhPSAoc2FsX3VJbnQxNiktMSwgIkZtWEdyaWRQZWVyOjpxdWVyeUZpZWxkRGF0YVR5cGUgOiBubyBtb2RlbCBwb3MgISIpOwoKCQlwQ29sID0gYUNvbHVtbnMuR2V0T2JqZWN0KG5Nb2RlbFBvcyk7CgkJY29uc3QgRGJHcmlkUm93UmVmIHhSb3cgPSBwR3JpZC0+R2V0U2Vla1JvdygpOwoJCXhGaWVsZENvbnRlbnQgPSAoeFJvdy5JcygpICYmIHhSb3ctPkhhc0ZpZWxkKHBDb2wtPkdldEZpZWxkUG9zKCkpKSA/IHhSb3ctPkdldEZpZWxkKHBDb2wtPkdldEZpZWxkUG9zKCkpLmdldENvbHVtbigpIDogUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpzZGI6OlhDb2x1bW4gPiAoKTsKCQlpZiAoIXhGaWVsZENvbnRlbnQuaXMoKSkKCQkJLy8gY2FuJ3Qgc3VwcGx5IGFueXRoaW5nIHdpdGhvdXQgYSBmaWVsZCBjb250ZW50CgkJCS8vIEZTIC0gMDcuMTIuOTkgLSA1NDM5MQoJCQljb250aW51ZTsKCgkJeENvbHVtbnMtPmdldEJ5SW5kZXgobk1vZGVsUG9zKSA+Pj0geEN1cnJlbnRDb2x1bW47CgkJaWYgKCE6OmNvbXBoZWxwZXI6Omhhc1Byb3BlcnR5KEZNX1BST1BfQ0xBU1NJRCwgeEN1cnJlbnRDb2x1bW4pKQoJCQljb250aW51ZTsKCgkJc2FsX0ludDE2IG5DbGFzc0lkID0gc2FsX0ludDE2KCk7CgkJeEN1cnJlbnRDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9DTEFTU0lEKSA+Pj0gbkNsYXNzSWQ7CgkJaWYgKG5DbGFzc0lkPkxBU1RfS05PV05fVFlQRSkKCQkJY29udGludWU7CgkJREJHX0FTU0VSVChuQ2xhc3NJZD4wLCAiRm1YR3JpZFBlZXI6OnF1ZXJ5RmllbGREYXRhVHlwZSA6IHNvbWVib2R5IGNoYW5nZWQgdGhlIGRlZmluaXRpb24gb2YgdGhlIEZvcm1Db21wb25lbnRUeXBlIGVudW0gISIpOwoKCQlpZiAobk1hcENvbHVtbiAhPSAtMSkKCQkJcFJldHVybkFycmF5W2ldID0gYkNhbkNvbnZlcnRbbkNsYXNzSWQtMV1bbk1hcENvbHVtbl07Cgl9CgoJcmV0dXJuIGFSZXR1cm5TZXF1ZW5jZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IEFueSA+IFNBTF9DQUxMIEZtWEdyaWRQZWVyOjpxdWVyeUZpZWxkRGF0YSggc2FsX0ludDMyIG5Sb3csIGNvbnN0IFR5cGUmIHhUeXBlICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKewoJRm1HcmlkQ29udHJvbCogcEdyaWQgPSAoRm1HcmlkQ29udHJvbCopIEdldFdpbmRvdygpOwoJREJHX0FTU0VSVChwR3JpZCAmJiBwR3JpZC0+SXNPcGVuKCksICJGbVhHcmlkUGVlcjo6cXVlcnlGaWVsZERhdGEgOiBoYXZlIG5vIHZhbGlkIGdyaWQgd2luZG93ICEiKTsKCWlmICghcEdyaWQgfHwgIXBHcmlkLT5Jc09wZW4oKSkKCQlyZXR1cm4gU2VxdWVuY2U8IEFueT4oKTsKCgkvLyBkYXMgQ29udHJvbCB6dXIgYW5nZWdlYmVuZW4gUm93IGZhaHJlbgoJaWYgKCFwR3JpZC0+U2Vla1JvdyhuUm93KSkKCXsKCQl0aHJvdyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKCX0KCgkvLyBkb24ndCB1c2UgR2V0Q3VycmVudFJvdyBhcyB0aGlzIGlzbid0IGFmZmVjdGVkIGJ5IHRoZSBhYm92ZSBTZWVrUm93CgkvLyBGUyAtIDMwLjA5Ljk5IC0gNjg2NDQKCURiR3JpZFJvd1JlZiB4UGFpbnRSb3cgPSBwR3JpZC0+R2V0UGFpbnRSb3coKTsKICAgIEVOU1VSRV9PUl9USFJPVyggeFBhaW50Um93LklzKCksICJpbnZhbGlkIHBhaW50IHJvdyIgKTsKCgkvLyBkaWUgQ29sdW1ucyBkZXMgQ29udHJvbHMgYnJhdWNoZSBpY2ggZnVlciBHZXRGaWVsZFRleHQKCURiR3JpZENvbHVtbnMgYUNvbHVtbnMgPSBwR3JpZC0+R2V0Q29sdW1ucygpOwoKCS8vIHVuZCBkdXJjaCBhbGxlIFNwYWx0ZW4gZHVyY2gKCXNhbF9JbnQzMiBuQ29sdW1uQ291bnQgPSBwR3JpZC0+R2V0Vmlld0NvbENvdW50KCk7CgoJU2VxdWVuY2U8IEFueT4gYVJldHVyblNlcXVlbmNlKG5Db2x1bW5Db3VudCk7CglBbnkqIHBSZXR1cm5BcnJheSA9IGFSZXR1cm5TZXF1ZW5jZS5nZXRBcnJheSgpOwoKCXNhbF9Cb29sIGJSZXF1ZXN0ZWRBc0FueSA9ICh4VHlwZS5nZXRUeXBlQ2xhc3MoKSA9PSBUeXBlQ2xhc3NfQU5ZKTsKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6c2RiOjpYQ29sdW1uID4gIHhGaWVsZENvbnRlbnQ7CglEYkdyaWRDb2x1bW4qIHBDb2w7Cglmb3IgKHNhbF9JbnQzMiBpPTA7IGkgPCBuQ29sdW1uQ291bnQ7ICsraSkKCXsKCQlzYWxfdUludDE2IG5Nb2RlbFBvcyA9IHBHcmlkLT5HZXRNb2RlbENvbHVtblBvcyhwR3JpZC0+R2V0Q29sdW1uSWRGcm9tVmlld1Bvcygoc2FsX3VJbnQxNilpKSk7CgkJREJHX0FTU0VSVChuTW9kZWxQb3MgIT0gKHNhbF91SW50MTYpLTEsICJGbVhHcmlkUGVlcjo6cXVlcnlGaWVsZERhdGEgOiBpbnZhbGlkIG1vZGVsIHBvcyAhIik7CgoJCS8vIGRvbid0IHVzZSBHZXRDdXJyZW50RmllbGRWYWx1ZSB0byBkZXRlcm1pbmUgdGhlIGZpZWxkIGNvbnRlbnQgYXMgdGhpcyBpc24ndCBhZmZlY3RlZCBieSB0aGUgYWJvdmUgU2Vla1JvdwoJCS8vIEZTIC0gMzAuMDkuOTkgLSA2ODY0NAoJCXBDb2wgPSBhQ29sdW1ucy5HZXRPYmplY3Qobk1vZGVsUG9zKTsKCQl4RmllbGRDb250ZW50ID0geFBhaW50Um93LT5IYXNGaWVsZCggcENvbC0+R2V0RmllbGRQb3MoKSApCiAgICAgICAgICAgICAgICAgICAgPyAgIHhQYWludFJvdy0+R2V0RmllbGQoIHBDb2wtPkdldEZpZWxkUG9zKCkgKS5nZXRDb2x1bW4oKQogICAgICAgICAgICAgICAgICAgIDogICBSZWZlcmVuY2U8IFhDb2x1bW4gPiAoKTsKCgkJaWYgKCAheEZpZWxkQ29udGVudC5pcygpICkKICAgICAgICAgICAgY29udGludWU7CgoJCWlmIChiUmVxdWVzdGVkQXNBbnkpCgkJewoJCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4RmllbGRTZXQoeEZpZWxkQ29udGVudCwgVU5PX1FVRVJZKTsKCQkJcFJldHVybkFycmF5W2ldID0geEZpZWxkU2V0LT5nZXRQcm9wZXJ0eVZhbHVlKEZNX1BST1BfVkFMVUUpOwoJCX0KCQllbHNlCgkJewoJCQlzd2l0Y2ggKHhUeXBlLmdldFR5cGVDbGFzcygpKQoJCQl7CgkJCQkvLyBTdHJpbmdzIHdlcmRlbiBkaXJla3QgdWViZXIgZGFzIEdldEZpZWxkVGV4dCBhYmdlaGFuZGVsdAoJCQkJY2FzZSBUeXBlQ2xhc3NfU1RSSU5HCQkJOgoJCQkJewoJCQkJCVN0cmluZyBzVGV4dCA9IGFDb2x1bW5zLkdldE9iamVjdChuTW9kZWxQb3MpLT5HZXRDZWxsVGV4dCggeFBhaW50Um93LCBwR3JpZC0+Z2V0TnVtYmVyRm9ybWF0dGVyKCkgKTsKCQkJCQlwUmV0dXJuQXJyYXlbaV0gPDw9IDo6cnRsOjpPVVN0cmluZyhzVGV4dCk7CgkJCQl9CgkJCQlicmVhazsKCQkJCS8vIGFsbGVzIGFuZGVyZSB3aXJkIGFuIGRlciBEYXRhYmFzZVZhcmlhbnQgZXJmcmFndAoJCQkJY2FzZSBUeXBlQ2xhc3NfRkxPQVQJCQk6IHBSZXR1cm5BcnJheVtpXSA8PD0geEZpZWxkQ29udGVudC0+Z2V0RmxvYXQoKTsgYnJlYWs7CgkJCQljYXNlIFR5cGVDbGFzc19ET1VCTEUJCSAgICA6IHBSZXR1cm5BcnJheVtpXSA8PD0geEZpZWxkQ29udGVudC0+Z2V0RG91YmxlKCk7IGJyZWFrOwoJCQkJY2FzZSBUeXBlQ2xhc3NfU0hPUlQJCQk6IHBSZXR1cm5BcnJheVtpXSA8PD0gKHNhbF9JbnQxNil4RmllbGRDb250ZW50LT5nZXRTaG9ydCgpOyBicmVhazsKCQkJCWNhc2UgVHlwZUNsYXNzX0xPTkcJCQkgICAgOiBwUmV0dXJuQXJyYXlbaV0gPDw9IChzYWxfSW50MzIpeEZpZWxkQ29udGVudC0+Z2V0TG9uZygpOyBicmVhazsKCQkJCWNhc2UgVHlwZUNsYXNzX1VOU0lHTkVEX1NIT1JUICAgOiBwUmV0dXJuQXJyYXlbaV0gPDw9IChzYWxfdUludDE2KXhGaWVsZENvbnRlbnQtPmdldFNob3J0KCk7IGJyZWFrOwoJCQkJY2FzZSBUeXBlQ2xhc3NfVU5TSUdORURfTE9ORwk6IHBSZXR1cm5BcnJheVtpXSA8PD0gKHNhbF91SW50MzIpeEZpZWxkQ29udGVudC0+Z2V0TG9uZygpOyBicmVhazsKCQkJCWNhc2UgVHlwZUNsYXNzX0JPT0xFQU4JCSAgICA6IDo6Y29tcGhlbHBlcjo6c2V0Qk9PTChwUmV0dXJuQXJyYXlbaV0seEZpZWxkQ29udGVudC0+Z2V0Qm9vbGVhbigpKTsgYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJewoJCQkJCXRocm93IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoJCQkJfQoJCQl9CgkJfQoJfQoJcmV0dXJuIGFSZXR1cm5TZXF1ZW5jZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6Q2VsbE1vZGlmaWVkKCkKewoJRXZlbnRPYmplY3QgYUV2dDsKCWFFdnQuU291cmNlID0gc3RhdGljX2Nhc3Q8IDo6Y3BwdTo6T1dlYWtPYmplY3QqID4odGhpcyk7CiAgICBtX2FNb2RpZnlMaXN0ZW5lcnMubm90aWZ5RWFjaCggJlhNb2RpZnlMaXN0ZW5lcjo6bW9kaWZpZWQsIGFFdnQgKTsKfQoKLy8gWFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6cHJvcGVydHlDaGFuZ2UoY29uc3QgUHJvcGVydHlDaGFuZ2VFdmVudCYgZXZ0KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCTo6dm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgkJLy8gd2FudCB0byBkbyBhIGxvdCBvZiBWQ0wgc3R1ZmYgaGVyZSAuLi4KCQkvLyB0aGlzIHNob3VsZCBub3QgYmUgKGRlYWRsb2NrKSBjcml0aWNhbCwgYXMgYnkgZGVmaW5pdGlvbiwgZXZlcnkgY29tcG9uZW50IHNob3VsZCByZWxlYXNlCgkJLy8gYW55IG93biBtdXRleGVzIGJlZm9yZSBub3RpZnlpbmcKCglGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKikgR2V0V2luZG93KCk7CglpZiAoIXBHcmlkKQoJCXJldHVybjsKCgkvLyBEYXRlbmJhbmtFdmVudAoJUmVmZXJlbmNlPCBYUm93U2V0ID4gIHhDdXJzb3IoZXZ0LlNvdXJjZSwgVU5PX1FVRVJZKTsKCWlmIChldnQuUHJvcGVydHlOYW1lID09IEZNX1BST1BfVkFMVUUgfHwgbV94Q3Vyc29yID09IGV2dC5Tb3VyY2UpCgkJcEdyaWQtPnByb3BlcnR5Q2hhbmdlKGV2dCk7CgllbHNlIGlmIChwR3JpZCAmJiBtX3hDb2x1bW5zLmlzKCkgJiYgbV94Q29sdW1ucy0+aGFzRWxlbWVudHMoKSkKCXsKCQkvLyB6dW5hZWNoc3QgcmF1c3N1Y2hlbiB3ZWxjaGUgQ29sdW1uIHNpY2ggZ2VhZW5kZXJ0IGhhdAoJCTo6Y29tcGhlbHBlcjo6SW50ZXJmYWNlUmVmIHhDdXJyZW50OwoJCXNhbF9JbnQzMiBpOwoKCQlmb3IgKCBpID0gMDsgaSA8IG1feENvbHVtbnMtPmdldENvdW50KCk7IGkrKykKCQl7CgkJCTo6Y3BwdTo6ZXh0cmFjdEludGVyZmFjZSh4Q3VycmVudCwgbV94Q29sdW1ucy0+Z2V0QnlJbmRleChpKSk7CgkJCWlmIChldnQuU291cmNlID09IHhDdXJyZW50KQoJCQkJYnJlYWs7CgkJfQoKCQlpZiAoaSA+PSBtX3hDb2x1bW5zLT5nZXRDb3VudCgpKQoJCQkvLyB0aGlzIGlzIHZhbGlkIGJlY2F1c2Ugd2UgYXJlIGxpc3RlbmluZyBhdCB0aGUgY3Vyc29yLCB0b28gKFJlY29yZENvdW50LCAtc3RhdHVzLCBlZGl0IG1vZGUpCgkJCXJldHVybjsKCgkJc2FsX3VJbnQxNiBuSWQgPSBwR3JpZC0+R2V0Q29sdW1uSWRGcm9tTW9kZWxQb3MoKHNhbF91SW50MTYpaSk7CgkJc2FsX0Jvb2wgYkludmFsaWRhdGVDb2x1bW4gPSBzYWxfRmFsc2U7CgoJCWlmIChldnQuUHJvcGVydHlOYW1lID09IEZNX1BST1BfTEFCRUwpCgkJewoJCQlTdHJpbmcgYU5hbWUgPSA6OmNvbXBoZWxwZXI6OmdldFN0cmluZyhldnQuTmV3VmFsdWUpOwoJCQlpZiAoYU5hbWUgIT0gcEdyaWQtPkdldENvbHVtblRpdGxlKG5JZCkpCgkJCQlwR3JpZC0+U2V0Q29sdW1uVGl0bGUobklkLCBhTmFtZSk7CgkJfQoJCWVsc2UgaWYgKGV2dC5Qcm9wZXJ0eU5hbWUgPT0gRk1fUFJPUF9XSURUSCkKCQl7CgkJCXNhbF9JbnQzMiBuV2lkdGggPSAwOwoJCQlpZiAoZXZ0Lk5ld1ZhbHVlLmdldFZhbHVlVHlwZSgpLmdldFR5cGVDbGFzcygpID09IFR5cGVDbGFzc19WT0lEKQoJCQkJbldpZHRoID0gcEdyaWQtPkdldERlZmF1bHRDb2x1bW5XaWR0aChwR3JpZC0+R2V0Q29sdW1uVGl0bGUobklkKSk7CgkJCQkvLyBHZXREZWZhdWx0Q29sdW1uV2lkdGggYWxyZWFkeSBjb25zaWRlcmQgdGhlIHpvb20gZmFjdG9yCgkJCWVsc2UKCQkJewoJCQkJc2FsX0ludDMyIG5UZXN0ID0gMDsKCQkJCWlmIChldnQuTmV3VmFsdWUgPj49IG5UZXN0KQoJCQkJewoJCQkJCW5XaWR0aCA9IHBHcmlkLT5Mb2dpY1RvUGl4ZWwoUG9pbnQoblRlc3QsMCksTUFQXzEwVEhfTU0pLlgoKTsKCQkJCQkvLyB0YWtlIHRoZSB6b29tIGZhY3RvciBpbnRvIGFjY291bnQKCQkJCQluV2lkdGggPSBwR3JpZC0+Q2FsY1pvb20obldpZHRoKTsKCQkJCX0KCQkJfQoJCQlpZiAobldpZHRoICE9IChzYWxfSW50MzIocEdyaWQtPkdldENvbHVtbldpZHRoKG5JZCkpKSkKCQkJewoJCQkJaWYgKHBHcmlkLT5Jc0VkaXRpbmcoKSkKCQkJCXsKCQkJCQlwR3JpZC0+RGVhY3RpdmF0ZUNlbGwoKTsKCQkJCQlwR3JpZC0+QWN0aXZhdGVDZWxsKCk7CgkJCQl9CgkJCQlwR3JpZC0+U2V0Q29sdW1uV2lkdGgobklkLCBuV2lkdGgpOwoJCQl9CgkJfQoJCWVsc2UgaWYgKGV2dC5Qcm9wZXJ0eU5hbWUgPT0gRk1fUFJPUF9ISURERU4pCgkJewoJCQlEQkdfQVNTRVJUKGV2dC5OZXdWYWx1ZS5nZXRWYWx1ZVR5cGUoKS5nZXRUeXBlQ2xhc3MoKSA9PSBUeXBlQ2xhc3NfQk9PTEVBTiwKCQkJCSJGbVhHcmlkUGVlcjo6cHJvcGVydHlDaGFuZ2UgOiB0aGUgcHJvcGVydHkgJ2hpZGRlbicgc2hvdWxkIGJlIG9mIHR5cGUgYm9vbGVhbiAhIik7CgkJCWlmICg6OmNvbXBoZWxwZXI6OmdldEJPT0woZXZ0Lk5ld1ZhbHVlKSkKCQkJCXBHcmlkLT5IaWRlQ29sdW1uKG5JZCk7CgkJCWVsc2UKCQkJCXBHcmlkLT5TaG93Q29sdW1uKG5JZCk7CgkJfQoJCWVsc2UgaWYgKGV2dC5Qcm9wZXJ0eU5hbWUgPT0gRk1fUFJPUF9BTElHTikKCQl7CgkJCS8vIGl0IGRlc2lnbiBtb2RlIGl0IGRvZXNuJ3QgbWF0dGVyCgkJCWlmICghaXNEZXNpZ25Nb2RlKCkpCgkJCXsKCQkJCURiR3JpZENvbHVtbiogcENvbCA9IHBHcmlkLT5HZXRDb2x1bW5zKCkuR2V0T2JqZWN0KGkpOwoKCQkJCXBDb2wtPlNldEFsaWdubWVudEZyb21Nb2RlbCgtMSk7CgkJCQliSW52YWxpZGF0ZUNvbHVtbiA9IHNhbF9UcnVlOwoJCQl9CgkJfQoJCWVsc2UgaWYgKGV2dC5Qcm9wZXJ0eU5hbWUgPT0gRk1fUFJPUF9GT1JNQVRLRVkpCgkJewoJCQlpZiAoIWlzRGVzaWduTW9kZSgpKQoJCQkJYkludmFsaWRhdGVDb2x1bW4gPSBzYWxfVHJ1ZTsKCQl9CgoJCS8vIG5lZWQgdG8gaW52YWxpZGF0ZSB0aGUgYWZmZWN0ZWQgY29sdW1uID8KCQlpZiAoYkludmFsaWRhdGVDb2x1bW4pCgkJewoJCQlzYWxfQm9vbCBiV2FzRWRpdGluZyA9IHBHcmlkLT5Jc0VkaXRpbmcoKTsKCQkJaWYgKGJXYXNFZGl0aW5nKQoJCQkJcEdyaWQtPkRlYWN0aXZhdGVDZWxsKCk7CgoJCQk6OlJlY3RhbmdsZSBhQ29sUmVjdCA9IHBHcmlkLT5HZXRGaWVsZFJlY3QobklkKTsKCQkJYUNvbFJlY3QuVG9wKCkgPSAwOwoJCQlhQ29sUmVjdC5Cb3R0b20oKSA9IHBHcmlkLT5HZXRTaXplUGl4ZWwoKS5IZWlnaHQoKTsKCQkJcEdyaWQtPkludmFsaWRhdGUoYUNvbFJlY3QpOwoKCQkJaWYgKGJXYXNFZGl0aW5nKQoJCQkJcEdyaWQtPkFjdGl2YXRlQ2VsbCgpOwoJCX0KCX0KfQoKLy8gWEJvdW5kQ29tcG9uZW50Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OmFkZFVwZGF0ZUxpc3RlbmVyKGNvbnN0IFJlZmVyZW5jZTwgWFVwZGF0ZUxpc3RlbmVyID4mIGwpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJbV9hVXBkYXRlTGlzdGVuZXJzLmFkZEludGVyZmFjZShsKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6cmVtb3ZlVXBkYXRlTGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYVXBkYXRlTGlzdGVuZXIgPiYgbCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CgltX2FVcGRhdGVMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKGwpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBGbVhHcmlkUGVlcjo6Y29tbWl0KCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKikgR2V0V2luZG93KCk7CglpZiAoIW1feEN1cnNvci5pcygpIHx8ICFwR3JpZCkKCQlyZXR1cm4gc2FsX1RydWU7CgoJRXZlbnRPYmplY3QgYUV2dChzdGF0aWNfY2FzdDwgOjpjcHB1OjpPV2Vha09iamVjdCogPih0aGlzKSk7Cgk6OmNwcHU6Ok9JbnRlcmZhY2VJdGVyYXRvckhlbHBlciBhSXRlcihtX2FVcGRhdGVMaXN0ZW5lcnMpOwoJc2FsX0Jvb2wgYkNhbmNlbCA9IHNhbF9GYWxzZTsKCXdoaWxlIChhSXRlci5oYXNNb3JlRWxlbWVudHMoKSAmJiAhYkNhbmNlbCkKCQlpZiAoICFzdGF0aWNfY2FzdDwgWFVwZGF0ZUxpc3RlbmVyKiA+KCBhSXRlci5uZXh0KCkgKS0+YXBwcm92ZVVwZGF0ZSggYUV2dCApICkKCQkJYkNhbmNlbCA9IHNhbF9UcnVlOwoKCWlmICghYkNhbmNlbCkKCQliQ2FuY2VsID0gIXBHcmlkLT5jb21taXQoKTsKCglpZiAoIWJDYW5jZWwpCiAgICAgICAgbV9hVXBkYXRlTGlzdGVuZXJzLm5vdGlmeUVhY2goICZYVXBkYXRlTGlzdGVuZXI6OnVwZGF0ZWQsIGFFdnQgKTsKCXJldHVybiAhYkNhbmNlbDsKfQoKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OmN1cnNvck1vdmVkKGNvbnN0IEV2ZW50T2JqZWN0JiBfckV2ZW50KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCUZtR3JpZENvbnRyb2wqIHBHcmlkID0gKEZtR3JpZENvbnRyb2wqKSBHZXRXaW5kb3coKTsKCS8vIHdlIGFyZSBub3QgaW50ZXJlc3RlZCBpbiBtb3ZlIHRvIGluc2VydCByb3cgb25seSBpbiB0aGUgcmVzZXR0ZWQgZXZlbnQKCS8vIHdoaWNoIGlzIGZpcmVkIGFmdGVyIHBvc2l0aW9uaW5nIGFuIHRoZSBpbnNlcnQgcm93CglpZiAocEdyaWQgJiYgcEdyaWQtPklzT3BlbigpICYmICE6OmNvbXBoZWxwZXI6OmdldEJPT0woUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAoX3JFdmVudC5Tb3VyY2UsIFVOT19RVUVSWSktPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9JU05FVykpKQoJCXBHcmlkLT5wb3NpdGlvbmVkKF9yRXZlbnQpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpyb3dDaGFuZ2VkKGNvbnN0IEV2ZW50T2JqZWN0JiBfckV2ZW50KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCUZtR3JpZENvbnRyb2wqIHBHcmlkID0gKEZtR3JpZENvbnRyb2wqKSBHZXRXaW5kb3coKTsKCWlmIChwR3JpZCAmJiBwR3JpZC0+SXNPcGVuKCkpCgl7CgkJaWYgKG1feEN1cnNvci0+cm93VXBkYXRlZCgpICYmICFwR3JpZC0+SXNDdXJyZW50QXBwZW5kaW5nKCkpCgkJCXBHcmlkLT5Sb3dNb2RpZmllZChwR3JpZC0+R2V0Q3VycmVudFBvcygpKTsKCQllbHNlIGlmIChtX3hDdXJzb3ItPnJvd0luc2VydGVkKCkpCgkJCXBHcmlkLT5pbnNlcnRlZChfckV2ZW50KTsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6cm93U2V0Q2hhbmdlZChjb25zdCBFdmVudE9iamVjdCYgLypldmVudCovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCS8vIG5vdCBpbnRlcmVzdGVkIGluIC4uLgoJLy8gKG91ciBwYXJlbnQgaXMgYSBmb3JtIHdoaWNoIG1lYW5zIHdlIGdldCBhIGxvYWRlZCBvciByZWxvYWRlZCBhZnRlciB0aGlzIHJvd1NldENoYW5nZWQpCn0KCi8vIFhMb2FkTGlzdGVuZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6bG9hZGVkKGNvbnN0IEV2ZW50T2JqZWN0JiAvKnJFdmVudCovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCXVwZGF0ZUdyaWQobV94Q3Vyc29yKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6dW5sb2FkZWQoY29uc3QgRXZlbnRPYmplY3QmIC8qckV2ZW50Ki8pIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJdXBkYXRlR3JpZCggUmVmZXJlbmNlPCBYUm93U2V0ID4gKE5VTEwpICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OnJlbG9hZGluZyhjb25zdCBFdmVudE9iamVjdCYgLyphRXZlbnQqLykgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CgkvLyBlbXB0eSB0aGUgZ3JpZAoJdXBkYXRlR3JpZCggUmVmZXJlbmNlPCBYUm93U2V0ID4gKE5VTEwpICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OnVubG9hZGluZyhjb25zdCBFdmVudE9iamVjdCYgLyphRXZlbnQqLykgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CgkvLyBlbXB0eSB0aGUgZ3JpZAoJdXBkYXRlR3JpZCggUmVmZXJlbmNlPCBYUm93U2V0ID4gKE5VTEwpICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OnJlbG9hZGVkKGNvbnN0IEV2ZW50T2JqZWN0JiAvKmFFdmVudCovKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCXVwZGF0ZUdyaWQobV94Q3Vyc29yKTsKfQoKLy8gWEdyaWRQZWVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlZmVyZW5jZTwgWEluZGV4Q29udGFpbmVyID4gIEZtWEdyaWRQZWVyOjpnZXRDb2x1bW5zKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglyZXR1cm4gbV94Q29sdW1uczsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6YWRkQ29sdW1uTGlzdGVuZXJzKGNvbnN0IFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4mIHhDb2wpCnsKCXN0YXRpYyBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgYVByb3BzTGlzdGVuZWRUb1tdID0KCXsKCQlGTV9QUk9QX0xBQkVMLCBGTV9QUk9QX1dJRFRILCBGTV9QUk9QX0hJRERFTiwgRk1fUFJPUF9BTElHTiwgRk1fUFJPUF9GT1JNQVRLRVkKCX07CgoJLy8gYXMgbm90IGFsbCBwcm9wZXJ0aWVzIGhhdmUgdG8gYmUgc3VwcG9ydGVkIGJ5IGFsbCBjb2x1bW5zIHdlIGhhdmUgdG8gY2hlY2sgdGhpcwoJLy8gYmVmb3JlIGFkZGluZyBhIGxpc3RlbmVyCglSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiB4SW5mbyA9IHhDb2wtPmdldFByb3BlcnR5U2V0SW5mbygpOwoJUHJvcGVydHkgYVByb3BEZXNjOwoJY29uc3QgOjpydGw6Ok9VU3RyaW5nKiBwUHJvcHMgPSBhUHJvcHNMaXN0ZW5lZFRvOwoJY29uc3QgOjpydGw6Ok9VU3RyaW5nKiBwUHJvcHNFbmQgPSBwUHJvcHMgKyBzaXplb2YoIGFQcm9wc0xpc3RlbmVkVG8gKSAvIHNpemVvZiggYVByb3BzTGlzdGVuZWRUb1sgMCBdICk7Cglmb3IgKDsgcFByb3BzICE9IHBQcm9wc0VuZDsgKytwUHJvcHMpCgl7CgkJaWYgKCB4SW5mby0+aGFzUHJvcGVydHlCeU5hbWUoICpwUHJvcHMgKSApCgkJewoJCQlhUHJvcERlc2MgPSB4SW5mby0+Z2V0UHJvcGVydHlCeU5hbWUoICpwUHJvcHMgKTsKCQkJaWYgKCAwICE9ICggYVByb3BEZXNjLkF0dHJpYnV0ZXMgJiBQcm9wZXJ0eUF0dHJpYnV0ZTo6Qk9VTkQgKSApCgkJCQl4Q29sLT5hZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCAqcFByb3BzLCB0aGlzICk7CgkJfQoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpyZW1vdmVDb2x1bW5MaXN0ZW5lcnMoY29uc3QgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiYgeENvbCkKewoJLy8gdGhlIHNhbWUgcHJvcHMgYXMgaW4gYWRkQ29sdW1uTGlzdGVuZXJzIC4uLiBsaW51eCBoYXMgcHJvYmxlbXMgd2l0aCBnbG9iYWwgc3RhdGljIFVTdHJpbmdzLCBzbwoJLy8gd2UgaGF2ZSB0byBkbyBpdCB0aGlzIHdheSAuLi4uCglzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIGFQcm9wc0xpc3RlbmVkVG9bXSA9Cgl7CgkJRk1fUFJPUF9MQUJFTCwgRk1fUFJPUF9XSURUSCwgRk1fUFJPUF9ISURERU4sIEZNX1BST1BfQUxJR04sIEZNX1BST1BfRk9STUFUS0VZCgl9OwoKCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0SW5mbyA+ICB4SW5mbyA9IHhDb2wtPmdldFByb3BlcnR5U2V0SW5mbygpOwoJZm9yIChzYWxfdUludDE2IGk9MDsgaTxzaXplb2YoYVByb3BzTGlzdGVuZWRUbykvc2l6ZW9mKGFQcm9wc0xpc3RlbmVkVG9bMF0pOyArK2kpCgkJaWYgKHhJbmZvLT5oYXNQcm9wZXJ0eUJ5TmFtZShhUHJvcHNMaXN0ZW5lZFRvW2ldKSkKCQkJeENvbC0+cmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihhUHJvcHNMaXN0ZW5lZFRvW2ldLCB0aGlzKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6c2V0Q29sdW1ucyhjb25zdCBSZWZlcmVuY2U8IFhJbmRleENvbnRhaW5lciA+JiBDb2x1bW5zKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCTo6dm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJRm1HcmlkQ29udHJvbCogcEdyaWQgPSBzdGF0aWNfY2FzdDwgRm1HcmlkQ29udHJvbCogPiggR2V0V2luZG93KCkgKTsKCglpZiAobV94Q29sdW1ucy5pcygpKQoJewoJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbDsKCQlmb3IgKHNhbF9JbnQzMiBpID0gMDsgaSA8IG1feENvbHVtbnMtPmdldENvdW50KCk7IGkrKykKCQl7CgkJCTo6Y3BwdTo6ZXh0cmFjdEludGVyZmFjZSh4Q29sLCBtX3hDb2x1bW5zLT5nZXRCeUluZGV4KGkpKTsKCQkJcmVtb3ZlQ29sdW1uTGlzdGVuZXJzKHhDb2wpOwoJCX0KCQlSZWZlcmVuY2U8IFhDb250YWluZXIgPiAgeENvbnRhaW5lcihtX3hDb2x1bW5zLCBVTk9fUVVFUlkpOwoJCXhDb250YWluZXItPnJlbW92ZUNvbnRhaW5lckxpc3RlbmVyKHRoaXMpOwoKCQlSZWZlcmVuY2U8IFhTZWxlY3Rpb25TdXBwbGllciA+ICB4U2VsU3VwcGxpZXIobV94Q29sdW1ucywgVU5PX1FVRVJZKTsKCQl4U2VsU3VwcGxpZXItPnJlbW92ZVNlbGVjdGlvbkNoYW5nZUxpc3RlbmVyKHRoaXMpOwoKCQlSZWZlcmVuY2U8IFhSZXNldCA+ICB4Q29sdW1uUmVzZXQobV94Q29sdW1ucywgVU5PX1FVRVJZKTsKCQlpZiAoeENvbHVtblJlc2V0LmlzKCkpCgkJCXhDb2x1bW5SZXNldC0+cmVtb3ZlUmVzZXRMaXN0ZW5lcigoWFJlc2V0TGlzdGVuZXIqKXRoaXMpOwoJfQoJaWYgKENvbHVtbnMuaXMoKSkKCXsKCQlSZWZlcmVuY2U8IFhDb250YWluZXIgPiAgeENvbnRhaW5lcihDb2x1bW5zLCBVTk9fUVVFUlkpOwoJCXhDb250YWluZXItPmFkZENvbnRhaW5lckxpc3RlbmVyKHRoaXMpOwoKCQlSZWZlcmVuY2U8IFhTZWxlY3Rpb25TdXBwbGllciA+ICB4U2VsU3VwcGxpZXIoQ29sdW1ucywgVU5PX1FVRVJZKTsKCQl4U2VsU3VwcGxpZXItPmFkZFNlbGVjdGlvbkNoYW5nZUxpc3RlbmVyKHRoaXMpOwoKCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4Q29sOwoJCWZvciAoc2FsX0ludDMyIGkgPSAwOyBpIDwgQ29sdW1ucy0+Z2V0Q291bnQoKTsgaSsrKQoJCXsKCQkJOjpjcHB1OjpleHRyYWN0SW50ZXJmYWNlKHhDb2wsIENvbHVtbnMtPmdldEJ5SW5kZXgoaSkpOwoJCQlhZGRDb2x1bW5MaXN0ZW5lcnMoeENvbCk7CgkJfQoKCQlSZWZlcmVuY2U8IFhSZXNldCA+ICB4Q29sdW1uUmVzZXQoQ29sdW1ucywgVU5PX1FVRVJZKTsKCQlpZiAoeENvbHVtblJlc2V0LmlzKCkpCgkJCXhDb2x1bW5SZXNldC0+YWRkUmVzZXRMaXN0ZW5lcigoWFJlc2V0TGlzdGVuZXIqKXRoaXMpOwoJfQoJbV94Q29sdW1ucyA9IENvbHVtbnM7CglpZiAocEdyaWQpCgl7CgkJcEdyaWQtPkluaXRDb2x1bW5zQnlNb2RlbHMobV94Q29sdW1ucyk7CgoJCWlmIChtX3hDb2x1bW5zLmlzKCkpCgkJewoJCQlFdmVudE9iamVjdCBhRXZ0KG1feENvbHVtbnMpOwoJCQlzZWxlY3Rpb25DaGFuZ2VkKGFFdnQpOwoJCX0KCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6c2V0RGVzaWduTW9kZShzYWxfQm9vbCBiT24pIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJaWYgKGJPbiAhPSBpc0Rlc2lnbk1vZGUoKSkKCXsKCQlXaW5kb3cqIHBXaW4gPSBHZXRXaW5kb3coKTsKCQlpZiAocFdpbikKCQkJKChGbUdyaWRDb250cm9sKikgcFdpbiktPlNldERlc2lnbk1vZGUoYk9uKTsKCX0KCglpZiAoYk9uKQoJCURpc0Nvbm5lY3RGcm9tRGlzcGF0Y2hlcigpOwoJZWxzZQoJCVVwZGF0ZURpc3BhdGNoZXMoKTsJLy8gd2lsbCBjb25uZWN0IGlmIG5vdCBhbHJlYWR5IGNvbm5lY3RlZCBhbmQganVzdCB1cGRhdGUgZWxzZQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBGbVhHcmlkUGVlcjo6aXNEZXNpZ25Nb2RlKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglXaW5kb3cqIHBXaW4gPSBHZXRXaW5kb3coKTsKCWlmIChwV2luKQoJCXJldHVybiAoKEZtR3JpZENvbnRyb2wqKSBwV2luKS0+SXNEZXNpZ25Nb2RlKCk7CgllbHNlCgkJcmV0dXJuIHNhbF9GYWxzZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6ZWxlbWVudEluc2VydGVkKGNvbnN0IENvbnRhaW5lckV2ZW50JiBldnQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCglGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKikgR2V0V2luZG93KCk7CgkvLyBIYW5kbGUgQ29sdW1uIGJlcnVlY2tzaWNodGlnZW4KCWlmICghcEdyaWQgfHwgIW1feENvbHVtbnMuaXMoKSB8fCBwR3JpZC0+SXNJbkNvbHVtbk1vdmUoKSB8fCBtX3hDb2x1bW5zLT5nZXRDb3VudCgpID09ICgoc2FsX0ludDMyKXBHcmlkLT5HZXRNb2RlbENvbENvdW50KCkpKQoJCXJldHVybjsKCglSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4U2V0OwoJOjpjcHB1OjpleHRyYWN0SW50ZXJmYWNlKHhTZXQsIGV2dC5FbGVtZW50KTsKCWFkZENvbHVtbkxpc3RlbmVycyh4U2V0KTsKCglSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4TmV3Q29sdW1uKHhTZXQpOwoJU3RyaW5nIGFOYW1lID0gOjpjb21waGVscGVyOjpnZXRTdHJpbmcoeE5ld0NvbHVtbi0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX0xBQkVMKSk7CglBbnkgYVdpZHRoID0geE5ld0NvbHVtbi0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX1dJRFRIKTsKCXNhbF9JbnQzMiBuV2lkdGggPSAwOwoJaWYgKGFXaWR0aCA+Pj0gbldpZHRoKQoJCW5XaWR0aCA9IHBHcmlkLT5Mb2dpY1RvUGl4ZWwoUG9pbnQobldpZHRoLDApLE1BUF8xMFRIX01NKS5YKCk7CgoJcEdyaWQtPkFwcGVuZENvbHVtbihhTmFtZSwgKHNhbF91SW50MTYpbldpZHRoLCAoc2FsX0ludDE2KTo6Y29tcGhlbHBlcjo6Z2V0SU5UMzIoZXZ0LkFjY2Vzc29yKSk7CgoJLy8gamV0enQgZGllIFNwYWx0ZSBzZXR6ZW4KCURiR3JpZENvbHVtbiogcENvbCA9IHBHcmlkLT5HZXRDb2x1bW5zKCkuR2V0T2JqZWN0KDo6Y29tcGhlbHBlcjo6Z2V0SU5UMzIoZXZ0LkFjY2Vzc29yKSk7CglwQ29sLT5zZXRNb2RlbCh4TmV3Q29sdW1uKTsKCglBbnkgYUhpZGRlbiA9IHhOZXdDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9ISURERU4pOwoJaWYgKDo6Y29tcGhlbHBlcjo6Z2V0Qk9PTChhSGlkZGVuKSkKCQlwR3JpZC0+SGlkZUNvbHVtbihwQ29sLT5HZXRJZCgpKTsKCiAgICBGb3JtQ29udHJvbEZhY3RvcnkoIG1feFNlcnZpY2VGYWN0b3J5ICkuaW5pdGlhbGl6ZVRleHRGaWVsZExpbmVFbmRzKCB4TmV3Q29sdW1uICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OmVsZW1lbnRSZXBsYWNlZChjb25zdCBDb250YWluZXJFdmVudCYgZXZ0KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCTo6dm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJRm1HcmlkQ29udHJvbCogcEdyaWQgPSAoRm1HcmlkQ29udHJvbCopIEdldFdpbmRvdygpOwoKCS8vIEhhbmRsZSBDb2x1bW4gYmVydWVja3NpY2h0aWdlbgoJaWYgKCFwR3JpZCB8fCAhbV94Q29sdW1ucy5pcygpIHx8IHBHcmlkLT5Jc0luQ29sdW1uTW92ZSgpKQoJCXJldHVybjsKCglSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4TmV3Q29sdW1uOwoJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeE9sZENvbHVtbjsKCTo6Y3BwdTo6ZXh0cmFjdEludGVyZmFjZSh4TmV3Q29sdW1uLCBldnQuRWxlbWVudCk7Cgk6OmNwcHU6OmV4dHJhY3RJbnRlcmZhY2UoeE9sZENvbHVtbiwgZXZ0LlJlcGxhY2VkRWxlbWVudCk7CgoJc2FsX0Jvb2wgYldhc0VkaXRpbmcgPSBwR3JpZC0+SXNFZGl0aW5nKCk7CglpZiAoYldhc0VkaXRpbmcpCgkJcEdyaWQtPkRlYWN0aXZhdGVDZWxsKCk7CgoJcEdyaWQtPlJlbW92ZUNvbHVtbihwR3JpZC0+R2V0Q29sdW1uSWRGcm9tTW9kZWxQb3MoKHNhbF91SW50MTYpOjpjb21waGVscGVyOjpnZXRJTlQzMihldnQuQWNjZXNzb3IpKSk7CgoJcmVtb3ZlQ29sdW1uTGlzdGVuZXJzKHhPbGRDb2x1bW4pOwoJYWRkQ29sdW1uTGlzdGVuZXJzKHhOZXdDb2x1bW4pOwoKCVN0cmluZyBhTmFtZSA9IDo6Y29tcGhlbHBlcjo6Z2V0U3RyaW5nKHhOZXdDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9MQUJFTCkpOwoJQW55IGFXaWR0aCA9IHhOZXdDb2x1bW4tPmdldFByb3BlcnR5VmFsdWUoRk1fUFJPUF9XSURUSCk7CglzYWxfSW50MzIgbldpZHRoID0gMDsKCWlmIChhV2lkdGggPj49IG5XaWR0aCkKCQluV2lkdGggPSBwR3JpZC0+TG9naWNUb1BpeGVsKFBvaW50KG5XaWR0aCwwKSxNQVBfMTBUSF9NTSkuWCgpOwoJc2FsX3VJbnQxNiBuTmV3SWQgPSBwR3JpZC0+QXBwZW5kQ29sdW1uKGFOYW1lLCAoc2FsX3VJbnQxNiluV2lkdGgsIChzYWxfSW50MTYpOjpjb21waGVscGVyOjpnZXRJTlQzMihldnQuQWNjZXNzb3IpKTsKCXNhbF91SW50MTYgbk5ld1BvcyA9IHBHcmlkLT5HZXRNb2RlbENvbHVtblBvcyhuTmV3SWQpOwoKCS8vIHNldCB0aGUgbW9kZWwgb2YgdGhlIG5ldyBjb2x1bW4KCURiR3JpZENvbHVtbiogcENvbCA9IHBHcmlkLT5HZXRDb2x1bW5zKCkuR2V0T2JqZWN0KG5OZXdQb3MpOwoKCS8vIGZvciBpbml0aWFsaXpvbmcgdGhpcyBncmlkIGNvbHVtbiwgd2UgbmVlZCB0aGUgZmllbGRzIG9mIHRoZSBncmlkJ3MgZGF0YSBzb3VyY2UKCVJlZmVyZW5jZTwgWENvbHVtbnNTdXBwbGllciA+IHhTdXBwQ29sdW1uczsKCUN1cnNvcldyYXBwZXIqIHBHcmlkRGF0YVNvdXJjZSA9IHBHcmlkLT5nZXREYXRhU291cmNlKCk7CglpZiAoIHBHcmlkRGF0YVNvdXJjZSApCgkJeFN1cHBDb2x1bW5zID0geFN1cHBDb2x1bW5zLnF1ZXJ5KCAoUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4pKCAqcEdyaWREYXRhU291cmNlICkgKTsKCVJlZmVyZW5jZTwgWE5hbWVBY2Nlc3MgPiB4Q29sdW1uc0J5TmFtZTsKCWlmICggeFN1cHBDb2x1bW5zLmlzKCkgKQoJCXhDb2x1bW5zQnlOYW1lID0geFN1cHBDb2x1bW5zLT5nZXRDb2x1bW5zKCk7CglSZWZlcmVuY2U8IFhJbmRleEFjY2VzcyA+IHhDb2x1bW5zQnlJbmRleCggeENvbHVtbnNCeU5hbWUsIFVOT19RVUVSWSApOwoKCWlmICggeENvbHVtbnNCeUluZGV4LmlzKCkgKQoJCXBHcmlkLT5Jbml0Q29sdW1uQnlGaWVsZCggcENvbCwgeE5ld0NvbHVtbiwgeENvbHVtbnNCeU5hbWUsIHhDb2x1bW5zQnlJbmRleCApOwoJZWxzZQoJCS8vIHRoZSBzaW1wbGUgdmVyc2lvbiwgYXBwbGllcyB3aGVuIHRoZSBncmlkIGlzIG5vdCB5ZXQgY29ubmVjdGVkIHRvIGEgZGF0YSBzb3VyY2UKCQlwQ29sLT5zZXRNb2RlbCh4TmV3Q29sdW1uKTsKCglpZiAoYldhc0VkaXRpbmcpCgkJcEdyaWQtPkFjdGl2YXRlQ2VsbCgpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjplbGVtZW50UmVtb3ZlZChjb25zdCBDb250YWluZXJFdmVudCYgZXZ0KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCTo6dm9zOjpPR3VhcmQgYUd1YXJkKCBBcHBsaWNhdGlvbjo6R2V0U29sYXJNdXRleCgpICk7CgoJRm1HcmlkQ29udHJvbCogcEdyaWQgICAgPSAoRm1HcmlkQ29udHJvbCopIEdldFdpbmRvdygpOwoKCS8vIEhhbmRsZSBDb2x1bW4gYmVydWVja3NpY2h0aWdlbgoJaWYgKCFwR3JpZCB8fCAhbV94Q29sdW1ucy5pcygpIHx8IHBHcmlkLT5Jc0luQ29sdW1uTW92ZSgpIHx8IG1feENvbHVtbnMtPmdldENvdW50KCkgPT0gKChzYWxfSW50MzIpcEdyaWQtPkdldE1vZGVsQ29sQ291bnQoKSkpCgkJcmV0dXJuOwoKCXBHcmlkLT5SZW1vdmVDb2x1bW4ocEdyaWQtPkdldENvbHVtbklkRnJvbU1vZGVsUG9zKChzYWxfdUludDE2KTo6Y29tcGhlbHBlcjo6Z2V0SU5UMzIoZXZ0LkFjY2Vzc29yKSkpOwoKCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gIHhPbGRDb2x1bW47Cgk6OmNwcHU6OmV4dHJhY3RJbnRlcmZhY2UoeE9sZENvbHVtbiwgZXZ0LkVsZW1lbnQpOwoJcmVtb3ZlQ29sdW1uTGlzdGVuZXJzKHhPbGRDb2x1bW4pOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpzZXRQcm9wZXJ0eSggY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBQcm9wZXJ0eU5hbWUsIGNvbnN0IEFueSYgVmFsdWUpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCglGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKikgR2V0V2luZG93KCk7CgoJc2FsX0Jvb2wgYlZvaWQgPSAhVmFsdWUuaGFzVmFsdWUoKTsKCglpZiAoIDAgPT0gUHJvcGVydHlOYW1lLmNvbXBhcmVUbyggRk1fUFJPUF9URVhUTElORUNPTE9SICkgKQoJewogICAgICAgIDo6Q29sb3IgYVRleHRMaW5lQ29sb3IoIGJWb2lkID8gQ09MX1RSQU5TUEFSRU5UIDogOjpjb21waGVscGVyOjpnZXRJTlQzMiggVmFsdWUgKSApOwoJCWlmIChiVm9pZCkKCQl7CgkJCXBHcmlkLT5TZXRUZXh0TGluZUNvbG9yKCk7CgkJCXBHcmlkLT5HZXREYXRhV2luZG93KCkuU2V0VGV4dExpbmVDb2xvcigpOwoJCX0KCQllbHNlCgkJewoJCQlwR3JpZC0+U2V0VGV4dExpbmVDb2xvcihhVGV4dExpbmVDb2xvcik7CgkJCXBHcmlkLT5HZXREYXRhV2luZG93KCkuU2V0VGV4dExpbmVDb2xvcihhVGV4dExpbmVDb2xvcik7CgkJfQoKCQkvLyBuZWVkIHRvIGZvcndhcmQgdGhpcyB0byB0aGUgY29sdW1ucwoJCURiR3JpZENvbHVtbnMmIHJDb2x1bW5zID0gY29uc3RfY2FzdDxEYkdyaWRDb2x1bW5zJj4ocEdyaWQtPkdldENvbHVtbnMoKSk7CgkJRGJHcmlkQ29sdW1uKiBwTG9vcCA9IHJDb2x1bW5zLkZpcnN0KCk7CgkJd2hpbGUgKHBMb29wKQoJCXsKCQkJRm1YR3JpZENlbGwqIHBYQ2VsbCA9IHBMb29wLT5HZXRDZWxsKCk7CgkJCWlmIChwWENlbGwpCgkJCXsKCQkJCWlmIChiVm9pZCkKCQkJCQlwWENlbGwtPlNldFRleHRMaW5lQ29sb3IoKTsKCQkJCWVsc2UKCQkJCQlwWENlbGwtPlNldFRleHRMaW5lQ29sb3IoYVRleHRMaW5lQ29sb3IpOwoJCQl9CgoJCQlwTG9vcCA9IHJDb2x1bW5zLk5leHQoKTsKCQl9CgoJCWlmIChpc0Rlc2lnbk1vZGUoKSkKCQkJcEdyaWQtPkludmFsaWRhdGUoKTsKCX0KCWVsc2UgaWYgKCAwID09IFByb3BlcnR5TmFtZS5jb21wYXJlVG8oIEZNX1BST1BfRk9OVEVNUEhBU0lTTUFSSyApICkKCXsKCQlGb250IGFHcmlkRm9udCA9IHBHcmlkLT5HZXRDb250cm9sRm9udCgpOwoJCXNhbF9JbnQxNiBuVmFsdWUgPSA6OmNvbXBoZWxwZXI6OmdldElOVDE2KFZhbHVlKTsKICAgICAgICBhR3JpZEZvbnQuU2V0RW1waGFzaXNNYXJrKCBuVmFsdWUgKTsKCQlwR3JpZC0+U2V0Q29udHJvbEZvbnQoIGFHcmlkRm9udCApOwoJfQoJZWxzZSBpZiAoIDAgPT0gUHJvcGVydHlOYW1lLmNvbXBhcmVUbyggRk1fUFJPUF9GT05UUkVMSUVGICkgKQoJewoJCUZvbnQgYUdyaWRGb250ID0gcEdyaWQtPkdldENvbnRyb2xGb250KCk7CgkJc2FsX0ludDE2IG5WYWx1ZSA9IDo6Y29tcGhlbHBlcjo6Z2V0SU5UMTYoVmFsdWUpOwogICAgICAgIGFHcmlkRm9udC5TZXRSZWxpZWYoIChGb250UmVsaWVmKW5WYWx1ZSApOwoJCXBHcmlkLT5TZXRDb250cm9sRm9udCggYUdyaWRGb250ICk7Cgl9CgllbHNlIGlmICggMCA9PSBQcm9wZXJ0eU5hbWUuY29tcGFyZVRvKCBGTV9QUk9QX0hFTFBVUkwgKSApCgl7CiAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNIZWxwVVJMOwogICAgICAgIE9TTF9WRVJJRlkoIFZhbHVlID4+PSBzSGVscFVSTCApOwogICAgICAgIElOZXRVUkxPYmplY3QgYUhJRCggc0hlbHBVUkwgKTsKICAgICAgICBpZiAoIGFISUQuR2V0UHJvdG9jb2woKSA9PSBJTkVUX1BST1RfSElEICkKICAgICAgICAgICAgc0hlbHBVUkwgPSBhSElELkdldFVSTFBhdGgoKTsKICAgICAgICBwR3JpZC0+U2V0SGVscElkKCBydGw6Ok9VU3RyaW5nVG9PU3RyaW5nKCBzSGVscFVSTCwgUlRMX1RFWFRFTkNPRElOR19VVEY4ICkgKTsKCX0KCWVsc2UgaWYgKCAwID09IFByb3BlcnR5TmFtZS5jb21wYXJlVG8oIEZNX1BST1BfRElTUExBWVNZTkNIUk9OICkgKQoJewoJCXBHcmlkLT5zZXREaXNwbGF5U3luY2hyb24oOjpjb21waGVscGVyOjpnZXRCT09MKFZhbHVlKSk7Cgl9CgllbHNlIGlmICggMCA9PSBQcm9wZXJ0eU5hbWUuY29tcGFyZVRvKCBGTV9QUk9QX0NVUlNPUkNPTE9SICkgKQoJewoJCWlmIChiVm9pZCkKCQkJcEdyaWQtPlNldEN1cnNvckNvbG9yKENPTF9UUkFOU1BBUkVOVCk7CgkJZWxzZQogICAgICAgICAgICBwR3JpZC0+U2V0Q3Vyc29yQ29sb3IoIDo6Q29sb3IoOjpjb21waGVscGVyOjpnZXRJTlQzMihWYWx1ZSkpKTsKCQlpZiAoaXNEZXNpZ25Nb2RlKCkpCgkJCXBHcmlkLT5JbnZhbGlkYXRlKCk7Cgl9CgllbHNlIGlmICggMCA9PSBQcm9wZXJ0eU5hbWUuY29tcGFyZVRvKCBGTV9QUk9QX0FMV0FZU1NIT1dDVVJTT1IgKSApCgl7CgkJcEdyaWQtPkVuYWJsZVBlcm1hbmVudEN1cnNvcig6OmNvbXBoZWxwZXI6OmdldEJPT0woVmFsdWUpKTsKCQlpZiAoaXNEZXNpZ25Nb2RlKCkpCgkJCXBHcmlkLT5JbnZhbGlkYXRlKCk7Cgl9CgllbHNlIGlmICggMCA9PSBQcm9wZXJ0eU5hbWUuY29tcGFyZVRvKCBGTV9QUk9QX0ZPTlQgKSApCgl7CgkJaWYgKCBiVm9pZCApCgkJCXBHcmlkLT5TZXRDb250cm9sRm9udCggRm9udCgpICk7CgkJZWxzZQoJCXsKCQkJOjpjb206OnN1bjo6c3Rhcjo6YXd0OjpGb250RGVzY3JpcHRvciBhRm9udDsKCQkJaWYgKFZhbHVlID4+PSBhRm9udCkKCQkJewoJCQkJRm9udCBhTmV3VmNsRm9udDsKCQkJCWlmICg6OmNvbXBoZWxwZXI6Om9wZXJhdG9yIT0oYUZvbnQsIDo6Y29tcGhlbHBlcjo6Z2V0RGVmYXVsdEZvbnQoKSkpCS8vIGlzdCBkYXMgZGVyIERlZmF1bHQKCQkJCQlhTmV3VmNsRm9udCA9IEltcGxDcmVhdGVGb250KCBhRm9udCApOwoKCQkJCS8vIG5lZWQgdG8gYWRkIHJlbGllZiBhbmQgZW1waGFzaXMgKHRoZXkncmUgc3RvcmVkIGluIGEgVkNMLUZvbnQsIGJ1dCBub3QgaW4gYSBGb250RGVzY3JpcHRvcgoJCQkJRm9udCBhT2xkVmNsRm9udCA9IHBHcmlkLT5HZXRDb250cm9sRm9udCgpOwoJCQkJYU5ld1ZjbEZvbnQuU2V0UmVsaWVmKCBhT2xkVmNsRm9udC5HZXRSZWxpZWYoKSApOwoJCSAgICAgICAgYU5ld1ZjbEZvbnQuU2V0RW1waGFzaXNNYXJrKCBhT2xkVmNsRm9udC5HZXRFbXBoYXNpc01hcmsoKSApOwoKCQkJCS8vIG5vdyBzZXQgaXQgLi4uCgkJCQlwR3JpZC0+U2V0Q29udHJvbEZvbnQoIGFOZXdWY2xGb250ICk7CgoJCQkJLy8gaWYgb3VyIHJvdy1oZWlnaHQgcHJvcGVydHkgaXMgdm9pZCAod2hpY2ggbWVhbnMgImNhbGN1bGF0ZSBpdCBmb250LWRlcGVuZGVudCIpIHdlIGhhdmUKCQkJCS8vIHRvIGFkanVzdCB0aGUgY29udHJvbCdzIHJvdyBoZWlnaHQKCQkJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gIHhNb2RlbFNldChnZXRDb2x1bW5zKCksIFVOT19RVUVSWSk7CgkJCQlpZiAoeE1vZGVsU2V0LmlzKCkgJiYgOjpjb21waGVscGVyOjpoYXNQcm9wZXJ0eShGTV9QUk9QX1JPV0hFSUdIVCwgeE1vZGVsU2V0KSkKCQkJCXsKCQkJCQlBbnkgYUhlaWdodCA9IHhNb2RlbFNldC0+Z2V0UHJvcGVydHlWYWx1ZShGTV9QUk9QX1JPV0hFSUdIVCk7CgkJCQkJaWYgKCFhSGVpZ2h0Lmhhc1ZhbHVlKCkpCgkJCQkJCXBHcmlkLT5TZXREYXRhUm93SGVpZ2h0KDApOwoJCQkJfQoKCQkJfQoJCX0KCX0KCWVsc2UgaWYgKCAwID09IFByb3BlcnR5TmFtZS5jb21wYXJlVG8oIEZNX1BST1BfQkFDS0dST1VORENPTE9SICkgKQoJewoJCWlmICggYlZvaWQgKQoJCXsKCQkJcEdyaWQtPlNldENvbnRyb2xCYWNrZ3JvdW5kKCk7CgkJfQoJCWVsc2UKCQl7CiAgICAgICAgICAgIDo6Q29sb3IgYUNvbG9yKCA6OmNvbXBoZWxwZXI6OmdldElOVDMyKFZhbHVlKSApOwoJCQlwR3JpZC0+U2V0QmFja2dyb3VuZCggYUNvbG9yICk7CgkJCXBHcmlkLT5TZXRDb250cm9sQmFja2dyb3VuZCggYUNvbG9yICk7CgkJfQoJfQoJZWxzZSBpZiAoIDAgPT0gUHJvcGVydHlOYW1lLmNvbXBhcmVUbyggRk1fUFJPUF9URVhUQ09MT1IgKSApCgl7CgkJaWYgKCBiVm9pZCApCgkJewoJCQlwR3JpZC0+U2V0Q29udHJvbEZvcmVncm91bmQoKTsKCQl9CgkJZWxzZQoJCXsKICAgICAgICAgICAgOjpDb2xvciBhQ29sb3IoIDo6Y29tcGhlbHBlcjo6Z2V0SU5UMzIoVmFsdWUpICk7CgkJCXBHcmlkLT5TZXRUZXh0Q29sb3IoIGFDb2xvciApOwoJCQlwR3JpZC0+U2V0Q29udHJvbEZvcmVncm91bmQoIGFDb2xvciApOwoJCX0KCX0KCWVsc2UgaWYgKCAwID09IFByb3BlcnR5TmFtZS5jb21wYXJlVG8oIEZNX1BST1BfUk9XSEVJR0hUICkgKQoJewoJCXNhbF9JbnQzMiBuTG9nSGVpZ2h0KDApOwoJCWlmIChWYWx1ZSA+Pj0gbkxvZ0hlaWdodCkKCQl7CgkJCXNhbF9JbnQzMiBuSGVpZ2h0ID0gcEdyaWQtPkxvZ2ljVG9QaXhlbChQb2ludCgwLG5Mb2dIZWlnaHQpLE1BUF8xMFRIX01NKS5ZKCk7CgkJCS8vIHRha2UgdGhlIHpvb20gZmFjdG9yIGludG8gYWNjb3VudAoJCQluSGVpZ2h0ID0gcEdyaWQtPkNhbGNab29tKG5IZWlnaHQpOwoJCQlwR3JpZC0+U2V0RGF0YVJvd0hlaWdodChuSGVpZ2h0KTsKCQl9CgkJZWxzZSBpZiAoYlZvaWQpCgkJCXBHcmlkLT5TZXREYXRhUm93SGVpZ2h0KDApOwoJfQoJZWxzZSBpZiAoIDAgPT0gUHJvcGVydHlOYW1lLmNvbXBhcmVUbyggRk1fUFJPUF9IQVNOQVZJR0FUSU9OICkgKQoJewogICAgICAgIHNhbF9Cb29sIGJWYWx1ZSggc2FsX1RydWUgKTsKICAgICAgICBPU0xfVkVSSUZZKCBWYWx1ZSA+Pj0gYlZhbHVlICk7CgkJcEdyaWQtPkVuYWJsZU5hdmlnYXRpb25CYXIoIGJWYWx1ZSApOwoJfQoJZWxzZSBpZiAoIDAgPT0gUHJvcGVydHlOYW1lLmNvbXBhcmVUbyggRk1fUFJPUF9SRUNPUkRNQVJLRVIgKSApCgl7CiAgICAgICAgc2FsX0Jvb2wgYlZhbHVlKCBzYWxfVHJ1ZSApOwogICAgICAgIE9TTF9WRVJJRlkoIFZhbHVlID4+PSBiVmFsdWUgKTsKCQlwR3JpZC0+RW5hYmxlSGFuZGxlKCBiVmFsdWUgKTsKCX0KCWVsc2UgaWYgKCAwID09IFByb3BlcnR5TmFtZS5jb21wYXJlVG8oIEZNX1BST1BfRU5BQkxFRCApICkKCXsKICAgICAgICBzYWxfQm9vbCBiVmFsdWUoIHNhbF9UcnVlICk7CiAgICAgICAgT1NMX1ZFUklGWSggVmFsdWUgPj49IGJWYWx1ZSApOwoJCXBHcmlkLT5FbmFibGVIYW5kbGUoIGJWYWx1ZSApOwoKICAgICAgICAvLyBJbSBEZXNpZ25Nb2R1cyBudXIgZGFzIERhdGVuZmVuc3RlciBkaXNhYmxlbgoJCS8vIFNvbnN0IGthbm4gZGFzIENvbnRyb2wgbmljaHQgbWVociBrb25maWd1cmllcnQgd2VyZGVuCgkJaWYgKGlzRGVzaWduTW9kZSgpKQoJCQlwR3JpZC0+R2V0RGF0YVdpbmRvdygpLkVuYWJsZSggYlZhbHVlICk7CgkJZWxzZQoJCQlwR3JpZC0+RW5hYmxlKCBiVmFsdWUgKTsKCX0KCWVsc2UKCQlWQ0xYV2luZG93OjpzZXRQcm9wZXJ0eSggUHJvcGVydHlOYW1lLCBWYWx1ZSApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhBY2Nlc3NpYmxlQ29udGV4dCA+IEZtWEdyaWRQZWVyOjpDcmVhdGVBY2Nlc3NpYmxlQ29udGV4dCgpCnsKICAgIFJlZmVyZW5jZTwgWEFjY2Vzc2libGVDb250ZXh0ID4geENvbnRleHQ7CgogICAgLy8gdXNlIHRoZSBBY2Nlc3NpYmxlQ29udGV4dCBwcm92aWRlZCBieSB0aGUgVkNMIHdpbmRvdwogICAgV2luZG93KiBwR3JpZCA9IEdldFdpbmRvdygpOwogICAgaWYgKCBwR3JpZCApCiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYQWNjZXNzaWJsZSA+IHhBY2MoIHBHcmlkLT5HZXRBY2Nlc3NpYmxlKCBzYWxfVHJ1ZSApICk7CiAgICAgICAgaWYgKCB4QWNjLmlzKCkgKQogICAgICAgICAgICB4Q29udGV4dCA9IHhBY2MtPmdldEFjY2Vzc2libGVDb250ZXh0KCk7CiAgICAgICAgLy8gVE9ETzogdGhpcyBoYXMgYSBzbGlnaHQgY29uY2VwdHVhbCBwcm9ibGVtOgogICAgICAgIC8vCiAgICAgICAgLy8gV2Uga25vdyB0aGF0IHRoZSBYQWNjZXNzaWJsZSBhbmQgWEFjY2Vzc2libGVDb250ZXh0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBicm93c2UKICAgICAgICAvLyBib3ggaXMgdGhlIHNhbWUgKHRoZSBjbGFzcyBpbXBsZW1lbnRzIGJvdGggaW50ZXJmYWNlcyksIHdoaWNoLCBzcGVha2luZyBzdHJpY3RseSwKICAgICAgICAvLyBpcyBiYWQgaGVyZSAobWVhbnMgd2hlbiBhIGJyb3dzZSBib3ggYWN0cyBhcyBVbm9Db250cm9sKTogV2UgKHRoZSBGbVhHcmlkUGVlcikgYXJlCiAgICAgICAgLy8gdGhlIFhBY2Nlc3NpYmxlIGhlcmUsIGFuZCB0aGUgYnJvd3NlIGJveCBzaG91bGQgYmUgYWJsZSB0byBwcm92aWRlIHVzIGFuIFhBY2Nlc3NpYmxlQ29udGV4dCwKICAgICAgICAvLyBidXQgaXQgc2hvdWxkIF9ub3RfIGJlIHRoZSBYQWNjZXNzaWJsZSBpdHNlbGYuCiAgICAgICAgLy8gSG93ZXZlciwgYXMgbG9uZyBhcyBubyBjbGllbnQgaW1wbGVtZW50YXRpb24gdXNlcyBkaXJ0eSBoYWNrcyBzdWNoIGFzIHF1ZXJ5aW5nIGFuCiAgICAgICAgLy8gWEFjY2Vzc2libGVDb250ZXh0IGZvciBYQWNjZXNzaWJsZSwgdGhpcyBzaG91bGQgbm90IGJlIGEgcHJvYmxlbS4KICAgIH0KCiAgICBpZiAoICF4Q29udGV4dC5pcygpICkKICAgICAgICB4Q29udGV4dCA9IFZDTFhXaW5kb3c6OkNyZWF0ZUFjY2Vzc2libGVDb250ZXh0KCApOwoKICAgIHJldHVybiB4Q29udGV4dDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KQW55IEZtWEdyaWRQZWVyOjpnZXRQcm9wZXJ0eSggY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBfclByb3BlcnR5TmFtZSApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJQW55IGFQcm9wOwoJaWYgKEdldFdpbmRvdygpKQoJewoJCUZtR3JpZENvbnRyb2wqIHBHcmlkID0gKEZtR3JpZENvbnRyb2wqKSBHZXRXaW5kb3coKTsKCQlXaW5kb3cqIHBEYXRhV2luZG93ICA9ICZwR3JpZC0+R2V0RGF0YVdpbmRvdygpOwoKCQlpZiAoIDAgPT0gX3JQcm9wZXJ0eU5hbWUuY29tcGFyZVRvKCBGTV9QUk9QX05BTUUgKSApCgkJewoJCQlGb250IGFGb250ID0gcERhdGFXaW5kb3ctPkdldENvbnRyb2xGb250KCk7CgkJCWFQcm9wIDw8PSBJbXBsQ3JlYXRlRm9udERlc2NyaXB0b3IoIGFGb250ICk7CgkJfQoJCWVsc2UgaWYgKCAwID09IF9yUHJvcGVydHlOYW1lLmNvbXBhcmVUbyggRk1fUFJPUF9URVhUQ09MT1IgKSApCgkJewoJCQlhUHJvcCA8PD0gKHNhbF9JbnQzMilwRGF0YVdpbmRvdy0+R2V0Q29udHJvbEZvcmVncm91bmQoKS5HZXRDb2xvcigpOwoJCX0KCQllbHNlIGlmICggMCA9PSBfclByb3BlcnR5TmFtZS5jb21wYXJlVG8oIEZNX1BST1BfQkFDS0dST1VORENPTE9SICkgKQoJCXsKCQkJYVByb3AgPDw9IChzYWxfSW50MzIpcERhdGFXaW5kb3ctPkdldENvbnRyb2xCYWNrZ3JvdW5kKCkuR2V0Q29sb3IoKTsKCQl9CgkJZWxzZSBpZiAoIDAgPT0gX3JQcm9wZXJ0eU5hbWUuY29tcGFyZVRvKCBGTV9QUk9QX1JPV0hFSUdIVCApICkKCQl7CgkJCXNhbF9JbnQzMiBuUGl4ZWxIZWlnaHQgPSBwR3JpZC0+R2V0RGF0YVJvd0hlaWdodCgpOwoJCQkvLyB0YWtlIHRoZSB6b29tIGZhY3RvciBpbnRvIGFjY291bnQKCQkJblBpeGVsSGVpZ2h0ID0gcEdyaWQtPkNhbGNSZXZlcnNlWm9vbShuUGl4ZWxIZWlnaHQpOwoJCQlhUHJvcCA8PD0gKHNhbF9JbnQzMilwR3JpZC0+UGl4ZWxUb0xvZ2ljKFBvaW50KDAsblBpeGVsSGVpZ2h0KSxNQVBfMTBUSF9NTSkuWSgpOwoJCX0KCQllbHNlIGlmICggMCA9PSBfclByb3BlcnR5TmFtZS5jb21wYXJlVG8oIEZNX1BST1BfSEFTTkFWSUdBVElPTiApICkKCQl7CgkJCXNhbF9Cb29sIGJIYXNOYXZCYXIgPSBwR3JpZC0+SGFzTmF2aWdhdGlvbkJhcigpOwoJCQlhUHJvcCA8PD0gKHNhbF9Cb29sKWJIYXNOYXZCYXI7CgkJfQoJCWVsc2UgaWYgKCAwID09IF9yUHJvcGVydHlOYW1lLmNvbXBhcmVUbyggRk1fUFJPUF9SRUNPUkRNQVJLRVIgKSApCgkJewoJCQlzYWxfQm9vbCBiSGFzSGFuZGxlID0gcEdyaWQtPkhhc0hhbmRsZSgpOwoJCQlhUHJvcCA8PD0gKHNhbF9Cb29sKWJIYXNIYW5kbGU7CgkJfQoJCWVsc2UgaWYgKCAwID09IF9yUHJvcGVydHlOYW1lLmNvbXBhcmVUbyggRk1fUFJPUF9FTkFCTEVEICkgKQoJCXsKCQkJYVByb3AgPDw9IChzYWxfQm9vbClwRGF0YVdpbmRvdy0+SXNFbmFibGVkKCk7CgkJfQoJCWVsc2UKCQkJYVByb3AgPSBWQ0xYV2luZG93OjpnZXRQcm9wZXJ0eSggX3JQcm9wZXJ0eU5hbWUgKTsKCX0KCXJldHVybiBhUHJvcDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6ZGlzcG9zZSgpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJRXZlbnRPYmplY3QgYUV2dDsKCWFFdnQuU291cmNlID0gc3RhdGljX2Nhc3Q8IDo6Y3BwdTo6T1dlYWtPYmplY3QqID4odGhpcyk7CgltX2FNb2RpZnlMaXN0ZW5lcnMuZGlzcG9zZUFuZENsZWFyKGFFdnQpOwoJbV9hVXBkYXRlTGlzdGVuZXJzLmRpc3Bvc2VBbmRDbGVhcihhRXZ0KTsKCW1fYUNvbnRhaW5lckxpc3RlbmVycy5kaXNwb3NlQW5kQ2xlYXIoYUV2dCk7CglWQ0xYV2luZG93OjpkaXNwb3NlKCk7CgoJLy8gcmVsZWFzZSBhbGwgaW50ZXJjZXB0b3JzCgkvLyBkaXNjb3ZlcmVkIGR1cmluZyAjMTAwMzEyIyAtIDIwMDItMTAtMjMgLSBmc0BvcGVub2ZmaWNlLm9yZwoJUmVmZXJlbmNlPCBYRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yID4geEludGVyY2VwdG9yKCBtX3hGaXJzdERpc3BhdGNoSW50ZXJjZXB0b3IgKTsKCW1feEZpcnN0RGlzcGF0Y2hJbnRlcmNlcHRvci5jbGVhcigpOwoJd2hpbGUgKCB4SW50ZXJjZXB0b3IuaXMoKSApCgl7CgkJLy8gdGVsbCB0aGUgaW50ZXJjZXB0b3IgaXQgaGFzIGEgbmV3IChtZWFucyBubykgcHJlZGVjZXNzb3IKCQl4SW50ZXJjZXB0b3ItPnNldE1hc3RlckRpc3BhdGNoUHJvdmlkZXIoIE5VTEwgKTsKCgkJLy8gYXNrIGZvciBpdCdzIHN1Y2Nlc3NvcgoJCVJlZmVyZW5jZTwgWERpc3BhdGNoUHJvdmlkZXIgPiB4U2xhdmUgPSB4SW50ZXJjZXB0b3ItPmdldFNsYXZlRGlzcGF0Y2hQcm92aWRlcigpOwoJCS8vIGFuZCBnaXZlIGl0IHRoZSBuZXcgKG1lYW5zIG5vKSBzdWNjZXNzb2VydAoJCXhJbnRlcmNlcHRvci0+c2V0U2xhdmVEaXNwYXRjaFByb3ZpZGVyKCBOVUxMICk7CgoJCS8vIHN0YXJ0IG92ZXIgd2l0aCB0aGUgbmV4dCBjaGFpbiBlbGVtZW50CgkJeEludGVyY2VwdG9yID0geEludGVyY2VwdG9yLnF1ZXJ5KCB4U2xhdmUgKTsKCX0KCglEaXNDb25uZWN0RnJvbURpc3BhdGNoZXIoKTsKCXNldFJvd1NldChSZWZlcmVuY2U8IFhSb3dTZXQgPiAoKSk7Cn0KCi8vIFhDb250YWluZXIKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6YWRkQ29udGFpbmVyTGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYQ29udGFpbmVyTGlzdGVuZXIgPiYgbCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CgltX2FDb250YWluZXJMaXN0ZW5lcnMuYWRkSW50ZXJmYWNlKCBsICk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6cmVtb3ZlQ29udGFpbmVyTGlzdGVuZXIoY29uc3QgUmVmZXJlbmNlPCBYQ29udGFpbmVyTGlzdGVuZXIgPiYgbCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CgltX2FDb250YWluZXJMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKCBsICk7Cn0KCi8vIDo6Y29tOjpzdW46OnN0YXI6OmRhdGE6OlhEYXRhYmFzZUN1cnNvclN1cHBsaWVyCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OnN0YXJ0Q3Vyc29yTGlzdGVuaW5nKCkKewoJaWYgKCFtX25DdXJzb3JMaXN0ZW5pbmcpCgl7CgkJUmVmZXJlbmNlPCBYUm93U2V0ID4gIHhSb3dTZXQobV94Q3Vyc29yLCBVTk9fUVVFUlkpOwoJCWlmICh4Um93U2V0LmlzKCkpCgkJCXhSb3dTZXQtPmFkZFJvd1NldExpc3RlbmVyKHRoaXMpOwoKCQlSZWZlcmVuY2U8IFhSZXNldCA+ICB4UmVzZXQobV94Q3Vyc29yLCBVTk9fUVVFUlkpOwoJCWlmICh4UmVzZXQuaXMoKSkKCQkJeFJlc2V0LT5hZGRSZXNldExpc3RlbmVyKHRoaXMpOwoKCQkvLyBhbGxlIExpc3RlbmVyIGFubWVsZGVuCgkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiAgeFNldChtX3hDdXJzb3IsIFVOT19RVUVSWSk7CgkJaWYgKHhTZXQuaXMoKSkKCQl7CgkJCXhTZXQtPmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoRk1fUFJPUF9JU01PRElGSUVELCB0aGlzKTsKCQkJeFNldC0+YWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihGTV9QUk9QX1JPV0NPVU5ULCB0aGlzKTsKCQl9Cgl9CgltX25DdXJzb3JMaXN0ZW5pbmcrKzsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6c3RvcEN1cnNvckxpc3RlbmluZygpCnsKCWlmICghLS1tX25DdXJzb3JMaXN0ZW5pbmcpCgl7CgkJUmVmZXJlbmNlPCBYUm93U2V0ID4gIHhSb3dTZXQobV94Q3Vyc29yLCBVTk9fUVVFUlkpOwoJCWlmICh4Um93U2V0LmlzKCkpCgkJCXhSb3dTZXQtPnJlbW92ZVJvd1NldExpc3RlbmVyKHRoaXMpOwoKCQlSZWZlcmVuY2U8IFhSZXNldCA+ICB4UmVzZXQobV94Q3Vyc29yLCBVTk9fUVVFUlkpOwoJCWlmICh4UmVzZXQuaXMoKSkKCQkJeFJlc2V0LT5yZW1vdmVSZXNldExpc3RlbmVyKHRoaXMpOwoKCQlSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+ICB4U2V0KG1feEN1cnNvciwgVU5PX1FVRVJZKTsKCQlpZiAoeFNldC5pcygpKQoJCXsKCQkJeFNldC0+cmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihGTV9QUk9QX0lTTU9ESUZJRUQsIHRoaXMpOwoJCQl4U2V0LT5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKEZNX1BST1BfUk9XQ09VTlQsIHRoaXMpOwoJCX0KCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6dXBkYXRlR3JpZChjb25zdCBSZWZlcmVuY2U8IFhSb3dTZXQgPiYgX3J4Q3Vyc29yKQp7CglGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKilHZXRXaW5kb3coKTsKCWlmIChwR3JpZCkKCQlwR3JpZC0+c2V0RGF0YVNvdXJjZShfcnhDdXJzb3IpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpSZWZlcmVuY2U8IFhSb3dTZXQgPiAgRm1YR3JpZFBlZXI6OmdldFJvd1NldCgpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJcmV0dXJuIG1feEN1cnNvcjsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6c2V0Um93U2V0KGNvbnN0IFJlZmVyZW5jZTwgWFJvd1NldCA+JiBfckRhdGFiYXNlQ3Vyc29yKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCUZtR3JpZENvbnRyb2wqIHBHcmlkID0gKEZtR3JpZENvbnRyb2wqKSBHZXRXaW5kb3coKTsKCWlmICghcEdyaWQgfHwgIW1feENvbHVtbnMuaXMoKSB8fCAhbV94Q29sdW1ucy0+Z2V0Q291bnQoKSkKCQlyZXR1cm47CgkvLyBhbGxlIExpc3RlbmVyIGFibWVsZGVuCglpZiAobV94Q3Vyc29yLmlzKCkpCgl7CgkJUmVmZXJlbmNlPCBYTG9hZGFibGUgPiAgeExvYWRhYmxlKG1feEN1cnNvciwgVU5PX1FVRVJZKTsKCQkvLyBvbmx5IGlmIHRoZSBmb3JtIGlzIGxvYWRlZCB3ZSBzZXQgdGhlIHJvd3NldAoJCWlmICh4TG9hZGFibGUuaXMoKSkKCQl7CgkJCXN0b3BDdXJzb3JMaXN0ZW5pbmcoKTsKCQkJeExvYWRhYmxlLT5yZW1vdmVMb2FkTGlzdGVuZXIodGhpcyk7CgkJfQoJfQoKCW1feEN1cnNvciA9IF9yRGF0YWJhc2VDdXJzb3I7CgoJaWYgKHBHcmlkKQoJewoJCVJlZmVyZW5jZTwgWExvYWRhYmxlID4gIHhMb2FkYWJsZShtX3hDdXJzb3IsIFVOT19RVUVSWSk7CgkJLy8gb25seSBpZiB0aGUgZm9ybSBpcyBsb2FkZWQgd2Ugc2V0IHRoZSByb3dzZXQKCQlpZiAoeExvYWRhYmxlLmlzKCkgJiYgeExvYWRhYmxlLT5pc0xvYWRlZCgpKQoJCQlwR3JpZC0+c2V0RGF0YVNvdXJjZShtX3hDdXJzb3IpOwoJCWVsc2UKCQkJcEdyaWQtPnNldERhdGFTb3VyY2UoUmVmZXJlbmNlPCBYUm93U2V0ID4gKCkpOwoKCQlpZiAoeExvYWRhYmxlLmlzKCkpCgkJewoJCQlzdGFydEN1cnNvckxpc3RlbmluZygpOwoJCQl4TG9hZGFibGUtPmFkZExvYWRMaXN0ZW5lcih0aGlzKTsKCQl9Cgl9Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZFBlZXI6OmFkZEdyaWRDb250cm9sTGlzdGVuZXIoIGNvbnN0IFJlZmVyZW5jZTwgWEdyaWRDb250cm9sTGlzdGVuZXIgPiYgX2xpc3RlbmVyICkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CiAgICBtX2FHcmlkQ29udHJvbExpc3RlbmVycy5hZGRJbnRlcmZhY2UoIF9saXN0ZW5lciApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIFNBTF9DQUxMIEZtWEdyaWRQZWVyOjpyZW1vdmVHcmlkQ29udHJvbExpc3RlbmVyKCBjb25zdCBSZWZlcmVuY2U8IFhHcmlkQ29udHJvbExpc3RlbmVyID4mIF9saXN0ZW5lciApIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewogICAgbV9hR3JpZENvbnRyb2xMaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKCBfbGlzdGVuZXIgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0ludDE2IEZtWEdyaWRQZWVyOjpnZXRDdXJyZW50Q29sdW1uUG9zaXRpb24oKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCUZtR3JpZENvbnRyb2wqIHBHcmlkID0gKEZtR3JpZENvbnRyb2wqKSBHZXRXaW5kb3coKTsKCXJldHVybiBwR3JpZCA/IHBHcmlkLT5HZXRWaWV3Q29sdW1uUG9zKHBHcmlkLT5HZXRDdXJDb2x1bW5JZCgpKSA6IC0xOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpzZXRDdXJyZW50Q29sdW1uUG9zaXRpb24oc2FsX0ludDE2IG5Qb3MpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJRm1HcmlkQ29udHJvbCogcEdyaWQgPSAoRm1HcmlkQ29udHJvbCopIEdldFdpbmRvdygpOwoJaWYgKHBHcmlkKQoJCXBHcmlkLT5Hb1RvQ29sdW1uSWQocEdyaWQtPkdldENvbHVtbklkRnJvbVZpZXdQb3MoblBvcykpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpzZWxlY3Rpb25DaGFuZ2VkKGNvbnN0IEV2ZW50T2JqZWN0JiBldnQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjp2b3M6Ok9HdWFyZCBhR3VhcmQoQXBwbGljYXRpb246OkdldFNvbGFyTXV0ZXgoKSk7CgoJRm1HcmlkQ29udHJvbCogcEdyaWQgPSAoRm1HcmlkQ29udHJvbCopIEdldFdpbmRvdygpOwoJaWYgKHBHcmlkKQoJewoJCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dmlldzo6WFNlbGVjdGlvblN1cHBsaWVyID4gIHhTZWxTdXBwbGllcihldnQuU291cmNlLCBVTk9fUVVFUlkpOwoJCUFueSBhU2VsZWN0aW9uID0geFNlbFN1cHBsaWVyLT5nZXRTZWxlY3Rpb24oKTsKCQlEQkdfQVNTRVJUKGFTZWxlY3Rpb24uZ2V0VmFsdWVUeXBlKCkuZ2V0VHlwZUNsYXNzKCkgPT0gVHlwZUNsYXNzX0lOVEVSRkFDRSwgIkZtWEdyaWRQZWVyOjpzZWxlY3Rpb25DaGFuZ2VkIDogaW52YWxpZCBzZWxlY3Rpb24gISIpOwoJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4gIHhTZWxlY3Rpb247CgkJIGFTZWxlY3Rpb24gPj49IHhTZWxlY3Rpb247CgkJaWYgKHhTZWxlY3Rpb24uaXMoKSkKCQl7CgkJCVJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geENvbDsKCQkJc2FsX0ludDMyIGkgPSAwOwoJCQlzYWxfSW50MzIgbkNvbENvdW50ID0gbV94Q29sdW1ucy0+Z2V0Q291bnQoKTsKCgkJCWZvciAoOyBpIDwgbkNvbENvdW50OyArK2kpCgkJCXsKCQkJCW1feENvbHVtbnMtPmdldEJ5SW5kZXgoaSkgPj49IHhDb2w7CgkJCQlpZiAoIHhDb2wgPT0geFNlbGVjdGlvbiApCgkJCQl7CgkJCQkJcEdyaWQtPm1hcmtDb2x1bW4ocEdyaWQtPkdldENvbHVtbklkRnJvbU1vZGVsUG9zKChzYWxfdUludDE2KWkpKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQkvLyBmdWVyIGRhcyBWQ0wtQ29udHJvbCBtdWVzc2VuIGRpZSBDb2x1bW5zIDEtYmFzaWVydCBzZWluCgkJCS8vIGRpZSBTZWxla3Rpb24gYW4gZGFzIFZDTC1Db250cm9sIHdlaXRlcnJlaWNoZW4sIHdlbm4gbm9ldGlnCgkJCWlmICggaSAhPSBwR3JpZC0+R2V0U2VsZWN0ZWRDb2x1bW4oKSApCgkJCXsJLy8gKHdlbm4gZGFzIG5pY2h0IGdyZWlmdCwgd3VyZGUgZGFzIHNlbGVjdGlvbkNoYW5nZWQgaW1wbGl6aXQgdm9uIGRlbSBDb250cm9sIHNlbGJlciBhdXNnZWxvZXN0CgkJCQlpZiAoIGkgPCBuQ29sQ291bnQgKQoJCQkJewoJCQkJCXBHcmlkLT5TZWxlY3RDb2x1bW5Qb3MocEdyaWQtPkdldFZpZXdDb2x1bW5Qb3MocEdyaWQtPkdldENvbHVtbklkRnJvbU1vZGVsUG9zKCAoc2FsX3VJbnQxNilpICkpICsgMSwgc2FsX1RydWUpOwoJCQkJCS8vIFNlbGVjdENvbHVtblBvcyBoYXQgd2llZGVyIHp1IGVpbmVtIGltcGxpeml0ZW4gQWN0aXZhdGVDZWxsIGdlZnVlaHJ0CgkJCQkJaWYgKHBHcmlkLT5Jc0VkaXRpbmcoKSkKCQkJCQkJcEdyaWQtPkRlYWN0aXZhdGVDZWxsKCk7CgkJCQl9CgkJCQllbHNlCgkJCQkJcEdyaWQtPlNldE5vU2VsZWN0aW9uKCk7CgkJCX0KCQl9CgkJZWxzZQoJCQlwR3JpZC0+bWFya0NvbHVtbihVU0hSVF9NQVgpOwoJfQp9CgovLyBYRWxlbWVudEFjY2VzcwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBGbVhHcmlkUGVlcjo6aGFzRWxlbWVudHMoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCXJldHVybiBnZXRDb3VudCgpICE9IDA7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClR5cGUgU0FMX0NBTEwgRm1YR3JpZFBlZXI6OmdldEVsZW1lbnRUeXBlKCAgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CglyZXR1cm4gOjpnZXRDcHB1VHlwZSgoUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhDb250cm9sPiAqKU5VTEwpOwp9CgovLyBYRW51bWVyYXRpb25BY2Nlc3MKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCBYRW51bWVyYXRpb24gPiAgRm1YR3JpZFBlZXI6OmNyZWF0ZUVudW1lcmF0aW9uKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglyZXR1cm4gbmV3IDo6Y29tcGhlbHBlcjo6T0VudW1lcmF0aW9uQnlJbmRleCh0aGlzKTsKfQoKLy8gWEluZGV4QWNjZXNzCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9JbnQzMiBGbVhHcmlkUGVlcjo6Z2V0Q291bnQoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCUZtR3JpZENvbnRyb2wqIHBHcmlkID0gKEZtR3JpZENvbnRyb2wqKSBHZXRXaW5kb3coKTsKCWlmIChwR3JpZCkKCQlyZXR1cm4gcEdyaWQtPkdldFZpZXdDb2xDb3VudCgpOwoJZWxzZQoJCXJldHVybiAwOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpBbnkgRm1YR3JpZFBlZXI6OmdldEJ5SW5kZXgoc2FsX0ludDMyIF9uSW5kZXgpIHRocm93KCBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uICkKewoJRm1HcmlkQ29udHJvbCogcEdyaWQgPSAoRm1HcmlkQ29udHJvbCopIEdldFdpbmRvdygpOwoJaWYgKF9uSW5kZXggPCAwIHx8CgkJX25JbmRleCA+PSBnZXRDb3VudCgpIHx8ICFwR3JpZCkKCQl0aHJvdyBJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uKCk7CgoJQW55IGFFbGVtZW50OwoJLy8gZ2V0IHRoZSBjb2x1bW5pZAoJc2FsX3VJbnQxNiBuSWQgPSBwR3JpZC0+R2V0Q29sdW1uSWRGcm9tVmlld1Bvcygoc2FsX3VJbnQxNilfbkluZGV4KTsKCS8vIGdldCB0aGUgbGlzdCBwb3NpdGlvbgoJc2FsX3VJbnQxNiBuUG9zID0gcEdyaWQtPkdldE1vZGVsQ29sdW1uUG9zKG5JZCk7CgoJRGJHcmlkQ29sdW1uKiBwQ29sID0gcEdyaWQtPkdldENvbHVtbnMoKS5HZXRPYmplY3QoblBvcyk7Ci8vCURCR19BU1NFUlQocENvbCAmJiBwQ29sLT5HZXRDZWxsKCksICJGbVhHcmlkUGVlcjo6Z2V0QnlJbmRleCgpOiBJbnZhbGlkIGNlbGwiKTsKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6YXd0OjpYQ29udHJvbCA+ICB4Q29udHJvbChwQ29sLT5HZXRDZWxsKCkpOwoJYUVsZW1lbnQgPDw9IHhDb250cm9sOwoKCXJldHVybiBhRWxlbWVudDsKfQoKLy8gOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6WE1vZGVTZWxlY3RvcgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpzZXRNb2RlKGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgTW9kZSkgdGhyb3coIE5vU3VwcG9ydEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbiApCnsKCWlmICghc3VwcG9ydHNNb2RlKE1vZGUpKQoJCXRocm93IE5vU3VwcG9ydEV4Y2VwdGlvbigpOwoKCWlmIChNb2RlID09IG1fYU1vZGUpCgkJcmV0dXJuOwoKCW1fYU1vZGUgPSBNb2RlOwoKCUZtR3JpZENvbnRyb2wqIHBHcmlkID0gKEZtR3JpZENvbnRyb2wqKSBHZXRXaW5kb3coKTsKCWlmICggTW9kZSA9PSA6OnJ0bDo6T1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggIkZpbHRlck1vZGUiICkgKSApCgkJcEdyaWQtPlNldEZpbHRlck1vZGUoc2FsX1RydWUpOwoJZWxzZQoJewoJCXBHcmlkLT5TZXRGaWx0ZXJNb2RlKHNhbF9GYWxzZSk7CgkJcEdyaWQtPnNldERhdGFTb3VyY2UobV94Q3Vyc29yKTsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpydGw6Ok9VU3RyaW5nIEZtWEdyaWRQZWVyOjpnZXRNb2RlKCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglyZXR1cm4gbV9hTW9kZTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpjb21waGVscGVyOjpTdHJpbmdTZXF1ZW5jZSBGbVhHcmlkUGVlcjo6Z2V0U3VwcG9ydGVkTW9kZXMoKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCXN0YXRpYyA6OmNvbXBoZWxwZXI6OlN0cmluZ1NlcXVlbmNlIGFNb2RlczsKCWlmICghYU1vZGVzLmdldExlbmd0aCgpKQoJewoJCWFNb2Rlcy5yZWFsbG9jKDIpOwoJCTo6cnRsOjpPVVN0cmluZyogcE1vZGVzID0gYU1vZGVzLmdldEFycmF5KCk7CgkJcE1vZGVzWzBdID0gOjpydGw6Ok9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oICJEYXRhTW9kZSIgKSApOwoJCXBNb2Rlc1sxXSA9IDo6cnRsOjpPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCAiRmlsdGVyTW9kZSIgKSApOwoJfQoJcmV0dXJuIGFNb2RlczsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgRm1YR3JpZFBlZXI6OnN1cHBvcnRzTW9kZShjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIE1vZGUpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJOjpjb21waGVscGVyOjpTdHJpbmdTZXF1ZW5jZSBhTW9kZXMoZ2V0U3VwcG9ydGVkTW9kZXMoKSk7Cgljb25zdCA6OnJ0bDo6T1VTdHJpbmcqIHBNb2RlcyA9IGFNb2Rlcy5nZXRDb25zdEFycmF5KCk7Cglmb3IgKHNhbF9JbnQzMiBpID0gYU1vZGVzLmdldExlbmd0aCgpOyBpID4gMDsgKQoJewoJCWlmIChwTW9kZXNbLS1pXSA9PSBNb2RlKQoJCQlyZXR1cm4gc2FsX1RydWU7Cgl9CglyZXR1cm4gc2FsX0ZhbHNlOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpjb2x1bW5WaXNpYmxlKERiR3JpZENvbHVtbiogcENvbHVtbikKewoJRm1HcmlkQ29udHJvbCogcEdyaWQgPSAoRm1HcmlkQ29udHJvbCopIEdldFdpbmRvdygpOwoKCXNhbF9JbnQzMiBfbkluZGV4ID0gcEdyaWQtPkdldE1vZGVsQ29sdW1uUG9zKHBDb2x1bW4tPkdldElkKCkpOwoJUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhDb250cm9sID4gIHhDb250cm9sKHBDb2x1bW4tPkdldENlbGwoKSk7CglDb250YWluZXJFdmVudCBhRXZ0OwoJYUV2dC5Tb3VyY2UgICA9IChYQ29udGFpbmVyKil0aGlzOwoJYUV2dC5BY2Nlc3NvciA8PD0gX25JbmRleDsKCWFFdnQuRWxlbWVudCAgPDw9IHhDb250cm9sOwoKICAgIG1fYUNvbnRhaW5lckxpc3RlbmVycy5ub3RpZnlFYWNoKCAmWENvbnRhaW5lckxpc3RlbmVyOjplbGVtZW50SW5zZXJ0ZWQsIGFFdnQgKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBGbVhHcmlkUGVlcjo6Y29sdW1uSGlkZGVuKERiR3JpZENvbHVtbiogcENvbHVtbikKewoJRm1HcmlkQ29udHJvbCogcEdyaWQgPSAoRm1HcmlkQ29udHJvbCopIEdldFdpbmRvdygpOwoKCXNhbF9JbnQzMiBfbkluZGV4ID0gcEdyaWQtPkdldE1vZGVsQ29sdW1uUG9zKHBDb2x1bW4tPkdldElkKCkpOwoJUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjphd3Q6OlhDb250cm9sID4gIHhDb250cm9sKHBDb2x1bW4tPkdldENlbGwoKSk7CglDb250YWluZXJFdmVudCBhRXZ0OwoJYUV2dC5Tb3VyY2UgICA9IChYQ29udGFpbmVyKil0aGlzOwoJYUV2dC5BY2Nlc3NvciA8PD0gX25JbmRleDsKCWFFdnQuRWxlbWVudCAgPDw9IHhDb250cm9sOwoKICAgIG1fYUNvbnRhaW5lckxpc3RlbmVycy5ub3RpZnlFYWNoKCAmWENvbnRhaW5lckxpc3RlbmVyOjplbGVtZW50UmVtb3ZlZCwgYUV2dCApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpkcmF3KCBzYWxfSW50MzIgeCwgc2FsX0ludDMyIHkgKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCUZtR3JpZENvbnRyb2wqIHBHcmlkID0gKEZtR3JpZENvbnRyb2wqKSBHZXRXaW5kb3coKTsKCXNhbF9JbnQzMiBuT2xkRmxhZ3MgPSBwR3JpZC0+R2V0QnJvd3NlckZsYWdzKCk7CglwR3JpZC0+U2V0QnJvd3NlckZsYWdzKG5PbGRGbGFncyB8IEVCQkZfTk9ST1dQSUNUVVJFKTsKCglWQ0xYV2luZG93OjpkcmF3KHgsIHkpOwoKCXBHcmlkLT5TZXRCcm93c2VyRmxhZ3Mobk9sZEZsYWdzKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoID4gIEZtWEdyaWRQZWVyOjpxdWVyeURpc3BhdGNoKGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlVSTCYgYVVSTCwgY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBhVGFyZ2V0RnJhbWVOYW1lLCBzYWxfSW50MzIgblNlYXJjaEZsYWdzKSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaCA+ICB4UmVzdWx0OwoKCS8vIGZpcnN0IGFzayBvdXIgaW50ZXJjZXB0b3IgY2hhaW4KCWlmIChtX3hGaXJzdERpc3BhdGNoSW50ZXJjZXB0b3IuaXMoKSAmJiAhbV9iSW50ZXJjZXB0aW5nRGlzcGF0Y2gpCgl7CgkJbV9iSW50ZXJjZXB0aW5nRGlzcGF0Y2ggPSBzYWxfVHJ1ZTsKCQkJLy8gc2FmZXR5IGFnYWluc3QgcmVjdXJzaW9uIDogYXMgd2UgYXJlIG1hc3RlciBvZiB0aGUgZmlyc3QgY2hhaW4gZWxlbWVudCBhbmQgc2xhdmUgb2YgdGhlIGxhc3Qgb25lIHdlIHdvdWxkCgkJCS8vIGhhdmUgYW4gaW5maW5pdGUgbG9vcCB3aXRob3V0IHRoaXMgaWYgbm8gZGlzcGF0Y2hlciBjYW4gZnVsbGZpbGwgdGhlIHJld3Vlc3QpCgkJeFJlc3VsdCA9IG1feEZpcnN0RGlzcGF0Y2hJbnRlcmNlcHRvci0+cXVlcnlEaXNwYXRjaChhVVJMLCBhVGFyZ2V0RnJhbWVOYW1lLCBuU2VhcmNoRmxhZ3MpOwoJCW1fYkludGVyY2VwdGluZ0Rpc3BhdGNoID0gc2FsX0ZhbHNlOwoJfQoKCS8vIHRoZW4gYXNrIG91cnNlbGYgOiB3ZSBkb24ndCBoYXZlIGFueSBkaXNwYXRjaGVzCglyZXR1cm4geFJlc3VsdDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaCA+ID4gRm1YR3JpZFBlZXI6OnF1ZXJ5RGlzcGF0Y2hlcyhjb25zdCBTZXF1ZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OkRpc3BhdGNoRGVzY3JpcHRvcj4mIGFEZXNjcmlwdHMpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJaWYgKG1feEZpcnN0RGlzcGF0Y2hJbnRlcmNlcHRvci5pcygpKQoJCXJldHVybiBtX3hGaXJzdERpc3BhdGNoSW50ZXJjZXB0b3ItPnF1ZXJ5RGlzcGF0Y2hlcyhhRGVzY3JpcHRzKTsKCgkvLyB0aGVuIGFzayBvdXJzZWxmIDogd2UgZG9uJ3QgaGF2ZSBhbnkgZGlzcGF0Y2hlcwoJcmV0dXJuIFNlcXVlbmNlPCBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2ggPiA+KCk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OnJlZ2lzdGVyRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yKGNvbnN0IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaFByb3ZpZGVySW50ZXJjZXB0b3IgPiYgX3hJbnRlcmNlcHRvcikgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglpZiAoX3hJbnRlcmNlcHRvci5pcygpKQoJewoJCWlmIChtX3hGaXJzdERpc3BhdGNoSW50ZXJjZXB0b3IuaXMoKSkKCQl7CgkJCVJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaFByb3ZpZGVyID4geEZpcnN0UHJvdmlkZXIobV94Rmlyc3REaXNwYXRjaEludGVyY2VwdG9yLCBVTk9fUVVFUlkpOwoJCQkvLyB0aGVyZSBpcyBhbHJlYWR5IGFuIGludGVyY2VwdG9yOyB0aGUgbmV3IG9uZSB3aWxsIGJlY29tZSBpdHMgbWFzdGVyCgkJCV94SW50ZXJjZXB0b3ItPnNldFNsYXZlRGlzcGF0Y2hQcm92aWRlcih4Rmlyc3RQcm92aWRlcik7CgkJCW1feEZpcnN0RGlzcGF0Y2hJbnRlcmNlcHRvci0+c2V0TWFzdGVyRGlzcGF0Y2hQcm92aWRlcih4Rmlyc3RQcm92aWRlcik7CgkJfQoJCWVsc2UKCQl7CgkJCS8vIGl0IGlzIHRoZSBmaXJzdCBpbnRlcmNlcHRvcjsgc2V0IG91cnNlbGYgYXMgc2xhdmUKCQkJX3hJbnRlcmNlcHRvci0+c2V0U2xhdmVEaXNwYXRjaFByb3ZpZGVyKCg6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXIqKXRoaXMpOwoJCX0KCgkJLy8gd2UgYXJlIHRoZSBtYXN0ZXIgb2YgdGhlIGNoYWluJ3MgZmlyc3QgaW50ZXJjZXB0b3IKCQltX3hGaXJzdERpc3BhdGNoSW50ZXJjZXB0b3IgPSBfeEludGVyY2VwdG9yOwoJCW1feEZpcnN0RGlzcGF0Y2hJbnRlcmNlcHRvci0+c2V0TWFzdGVyRGlzcGF0Y2hQcm92aWRlcigoOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaFByb3ZpZGVyKil0aGlzKTsKCgkJLy8gd2UgaGF2ZSBhIG5ldyBpbnRlcmNlcHRvciBhbmQgd2UncmUgYWxpdmUgPwoJCWlmICghaXNEZXNpZ25Nb2RlKCkpCgkJCS8vIC0+IGNoZWNrIGZvciBuZXcgZGlzcGF0Y2hlcnMKCQkJVXBkYXRlRGlzcGF0Y2hlcygpOwoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpyZWxlYXNlRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yKGNvbnN0IFJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaFByb3ZpZGVySW50ZXJjZXB0b3IgPiYgX3hJbnRlcmNlcHRvcikgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglpZiAoIV94SW50ZXJjZXB0b3IuaXMoKSkKCQlyZXR1cm47CgoJUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXJJbnRlcmNlcHRvciA+ICB4Q2hhaW5XYWxrKG1feEZpcnN0RGlzcGF0Y2hJbnRlcmNlcHRvcik7CgoJaWYgKG1feEZpcnN0RGlzcGF0Y2hJbnRlcmNlcHRvciA9PSBfeEludGVyY2VwdG9yKQoJewkvLyBvdXIgY2hhaW4gd2lsbCBoYXZlIGEgbmV3IGZpcnN0IGVsZW1lbnQKCQlSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yID4gIHhTbGF2ZShtX3hGaXJzdERpc3BhdGNoSW50ZXJjZXB0b3ItPmdldFNsYXZlRGlzcGF0Y2hQcm92aWRlcigpLCBVTk9fUVVFUlkpOwoJCW1feEZpcnN0RGlzcGF0Y2hJbnRlcmNlcHRvciA9IHhTbGF2ZTsKCX0KCS8vIGRvIHRoaXMgYmVmb3JlIHJlbW92aW5nIHRoZSBpbnRlcmNlcHRvciBmcm9tIHRoZSBjaGFpbiBhcyB3ZSB3b24ndCBrbm93IGl0J3Mgc2xhdmUgYWZ0ZXJ3YXJkcykKCgl3aGlsZSAoeENoYWluV2Fsay5pcygpKQoJewoJCS8vIHdhbGsgYWxvbmcgdGhlIGNoYWluIG9mIGludGVyY2VwdG9ycyBhbmQgbG9vayBmb3IgdGhlIGludGVyY2VwdG9yIHRoYXQgaGFzIHRvIGJlIHJlbW92ZWQKCQlSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yID4gIHhTbGF2ZSh4Q2hhaW5XYWxrLT5nZXRTbGF2ZURpc3BhdGNoUHJvdmlkZXIoKSwgVU5PX1FVRVJZKTsKCgkJaWYgKHhDaGFpbldhbGsgPT0gX3hJbnRlcmNlcHRvcikKCQl7CgkJCS8vIG9sZCBtYXN0ZXIgbWF5IGJlIGFuIGludGVyY2VwdG9yIHRvbwoJCQlSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2hQcm92aWRlckludGVyY2VwdG9yID4gIHhNYXN0ZXIoeENoYWluV2Fsay0+Z2V0TWFzdGVyRGlzcGF0Y2hQcm92aWRlcigpLCBVTk9fUVVFUlkpOwoKCQkJLy8gdW5jaGFpbiB0aGUgaW50ZXJjZXB0b3IgdGhhdCBoYXMgdG8gYmUgcmVtb3ZlZAoJCQl4Q2hhaW5XYWxrLT5zZXRTbGF2ZURpc3BhdGNoUHJvdmlkZXIoUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXIgPiAoKSk7CgkJCXhDaGFpbldhbGstPnNldE1hc3RlckRpc3BhdGNoUHJvdmlkZXIoUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXIgPiAoKSk7CgoJCQkvLyByZWNvbm5lY3QgdGhlIGNoYWluCgkJCWlmICh4TWFzdGVyLmlzKCkpCgkJCXsKCQkJCWlmICh4U2xhdmUuaXMoKSkKCQkJCQl4TWFzdGVyLT5zZXRTbGF2ZURpc3BhdGNoUHJvdmlkZXIoUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoUHJvdmlkZXIgPjo6cXVlcnkoeFNsYXZlKSk7CgkJCQllbHNlCgkJCQkJLy8gaXQncyB0aGUgZmlyc3QgaW50ZXJjZXB0b3Igb2YgdGhlIGNoYWluLCBzZXQgb3Vyc2VsZiBhcyBzbGF2ZQoJCQkJCXhNYXN0ZXItPnNldFNsYXZlRGlzcGF0Y2hQcm92aWRlcigoOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhEaXNwYXRjaFByb3ZpZGVyKil0aGlzKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCS8vIHRoZSBjaGFpbidzIGZpcnN0IGVsZW1lbnQgd2FzIHJlbW92ZWQsIHNldCBvdXJzZWxmIGFzIG5ldyBtYXN0ZXIgb2YgdGhlIHNlY29uZCBvbmUKCQkJCWlmICh4U2xhdmUuaXMoKSkKCQkJCQl4U2xhdmUtPnNldE1hc3RlckRpc3BhdGNoUHJvdmlkZXIoKDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2hQcm92aWRlciopdGhpcyk7CgkJCX0KCQl9CgoJCXhDaGFpbldhbGsgPSB4U2xhdmU7Cgl9CgkvLyBvdXIgaW50ZXJjZXB0b3IgY2hhaW4gaGFzIGNoYW5nZWQgYW5kIHdlJ3JlIGFsaXZlID8KCWlmICghaXNEZXNpZ25Nb2RlKCkpCgkJLy8gLT4gY2hlY2sgdGhlIGRpc3BhdGNoZXJzCgkJVXBkYXRlRGlzcGF0Y2hlcygpOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpzdGF0dXNDaGFuZ2VkKGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpGZWF0dXJlU3RhdGVFdmVudCYgRXZlbnQpIHRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJREJHX0FTU0VSVChtX3BTdGF0ZUNhY2hlLCAiRm1YR3JpZFBlZXI6OnN0YXR1c0NoYW5nZWQgOiBpbnZhbGlkIGNhbGwgISIpOwoJREJHX0FTU0VSVChtX3BEaXNwYXRjaGVycywgIkZtWEdyaWRQZWVyOjpzdGF0dXNDaGFuZ2VkIDogaW52YWxpZCBjYWxsICEiKTsKCglTZXF1ZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6VVJMPiYgYVVybHMgPSBnZXRTdXBwb3J0ZWRVUkxzKCk7Cgljb25zdCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpVUkwqIHBVcmxzID0gYVVybHMuZ2V0Q29uc3RBcnJheSgpOwoKCVNlcXVlbmNlPHNhbF91SW50MTY+IGFTbG90cyA9IGdldFN1cHBvcnRlZEdyaWRTbG90cygpOwoJY29uc3Qgc2FsX3VJbnQxNiogcFNsb3RzID0gYVNsb3RzLmdldENvbnN0QXJyYXkoKTsKCiAgICBzYWxfdUludDE2IGk7Cglmb3IgKGk9MDsgaTxhVXJscy5nZXRMZW5ndGgoKTsgKytpLCArK3BVcmxzLCArK3BTbG90cykKCXsKCQlpZiAocFVybHMtPk1haW4gPT0gRXZlbnQuRmVhdHVyZVVSTC5NYWluKQoJCXsKCQkJREJHX0FTU0VSVChtX3BEaXNwYXRjaGVyc1tpXSA9PSBFdmVudC5Tb3VyY2UsICJGbVhHcmlkUGVlcjo6c3RhdHVzQ2hhbmdlZCA6IHRoZSBldmVudCBzb3VyY2UgaXMgYSBsaXR0bGUgYml0IHN1c3BlY3QgISIpOwoJCQltX3BTdGF0ZUNhY2hlW2ldID0gRXZlbnQuSXNFbmFibGVkOwoJCQlGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKikgR2V0V2luZG93KCk7CgkJCWlmICgqcFNsb3RzICE9IFNJRF9GTV9SRUNPUkRfVU5ETykKCQkJCXBHcmlkLT5HZXROYXZpZ2F0aW9uQmFyKCkuSW52YWxpZGF0ZVN0YXRlKCpwU2xvdHMpOwoJCQlicmVhazsKCQl9Cgl9CglEQkdfQVNTRVJUKGk8YVVybHMuZ2V0TGVuZ3RoKCksICJGbVhHcmlkUGVlcjo6c3RhdHVzQ2hhbmdlZCA6IGdvdCBhIGNhbGwgZm9yIGFuIHVua25vd24gdXJsICEiKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgRm1YR3JpZFBlZXI6OmFwcHJvdmVSZXNldChjb25zdCBFdmVudE9iamVjdCYgLypyRXZlbnQqLykgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKQp7CglyZXR1cm4gc2FsX1RydWU7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIFNBTF9DQUxMIEZtWEdyaWRQZWVyOjpzZWxlY3QoIGNvbnN0IEFueSYgX3JTZWxlY3Rpb24gKSB0aHJvdyAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQp7CglTZXF1ZW5jZTwgQW55ID4gYUJvb2ttYXJrczsKCWlmICggISggX3JTZWxlY3Rpb24gPj49IGFCb29rbWFya3MgKSApCgkJdGhyb3cgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CgoJRm1HcmlkQ29udHJvbCogcFZjbENvbnRyb2wgPSBzdGF0aWNfY2FzdDxGbUdyaWRDb250cm9sKj4oR2V0V2luZG93KCkpOwoJcmV0dXJuIHBWY2xDb250cm9sLT5zZWxlY3RCb29rbWFya3MoYUJvb2ttYXJrcyk7CgoJLy8gVE9ETzoKCS8vIHNwZWFraW5nIHN0cmljdGx5LCB3ZSB3b3VsZCBoYXZlIHRvIGFkanVzdCBvdXIgbW9kZWwsIGFzIG91ciBDb2x1bW5TZWxlY3Rpb24gbWF5IGhhdmUgY2hhbmdlZC4KCS8vIE91ciBtb2RlbCBpcyBhIFhTZWxlY3Rpb25TdXBwbGllciwgdG9vLCBpdCBoYW5kbGVzIHRoZSBzZWxlY3Rpb24gb2Ygc2luZ2xlIGNvbHVtbnMuCgkvLyBUaGlzIGlzIHNvbWV3aGF0IHN0cmFuZ2UsIGFzIHNlbGVjdGlvbiBzaG91bGQgYmUgYSB2aWV3IChub3QgYSBtb2RlbCkgYXNwZWN0LgoJLy8gU28gZm9yIGEgY2xlYW4gc29sdXRpb24sIHdlIHNob3VsZCBoYW5kbGUgY29sdW1uIHNlbGVjdGlvbiBvdXJzZWxmLCBhbmQgdGhlIG1vZGVsIHNob3VsZG4ndAoJLy8gZGVhbCB3aXRoIHNlbGVjdGlvbiBhdCBhbGwuCn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkFueSBTQUxfQ0FMTCBGbVhHcmlkUGVlcjo6Z2V0U2VsZWN0aW9uKCAgKSB0aHJvdyAoUnVudGltZUV4Y2VwdGlvbikKewoJRm1HcmlkQ29udHJvbCogcFZjbENvbnRyb2wgPSBzdGF0aWNfY2FzdDxGbUdyaWRDb250cm9sKj4oR2V0V2luZG93KCkpOwoJU2VxdWVuY2U8IEFueSA+IGFTZWxlY3Rpb25Cb29rbWFya3MgPSBwVmNsQ29udHJvbC0+Z2V0U2VsZWN0aW9uQm9va21hcmtzKCk7CglyZXR1cm4gbWFrZUFueShhU2VsZWN0aW9uQm9va21hcmtzKTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBTQUxfQ0FMTCBGbVhHcmlkUGVlcjo6YWRkU2VsZWN0aW9uQ2hhbmdlTGlzdGVuZXIoIGNvbnN0IFJlZmVyZW5jZTwgWFNlbGVjdGlvbkNoYW5nZUxpc3RlbmVyID4mIF9yeExpc3RlbmVyICkgdGhyb3cgKFJ1bnRpbWVFeGNlcHRpb24pCnsKCW1fYVNlbGVjdGlvbkxpc3RlbmVycy5hZGRJbnRlcmZhY2UoIF9yeExpc3RlbmVyICk7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgU0FMX0NBTEwgRm1YR3JpZFBlZXI6OnJlbW92ZVNlbGVjdGlvbkNoYW5nZUxpc3RlbmVyKCBjb25zdCBSZWZlcmVuY2U8IFhTZWxlY3Rpb25DaGFuZ2VMaXN0ZW5lciA+JiBfcnhMaXN0ZW5lciApIHRocm93IChSdW50aW1lRXhjZXB0aW9uKQp7CgltX2FTZWxlY3Rpb25MaXN0ZW5lcnMucmVtb3ZlSW50ZXJmYWNlKCBfcnhMaXN0ZW5lciApOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpyZXNldHRlZChjb25zdCBFdmVudE9iamVjdCYgckV2ZW50KSB0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCWlmIChtX3hDb2x1bW5zID09IHJFdmVudC5Tb3VyY2UpCgl7CS8vIG15IG1vZGVsIHdhcyByZXNldCAtPiByZWZyZXNoIHRoZSBncmlkIGNvbnRlbnQKCQlGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKilHZXRXaW5kb3coKTsKCQlpZiAoIXBHcmlkKQoJCQlyZXR1cm47CgkJOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCQlwR3JpZC0+cmVzZXRDdXJyZW50Um93KCk7Cgl9CgkvLyBpZiB0aGUgY3Vyc29yIGZpcmVkIGEgcmVzZXQgZXZlbnQgd2Ugc2VlbSB0byBiZSBvbiB0aGUgaW5zZXJ0IHJvdwoJZWxzZSBpZiAobV94Q3Vyc29yID09IHJFdmVudC5Tb3VyY2UpCgl7CgkJOjp2b3M6Ok9HdWFyZCBhR3VhcmQoIEFwcGxpY2F0aW9uOjpHZXRTb2xhck11dGV4KCkgKTsKCQlGbUdyaWRDb250cm9sKiBwR3JpZCA9IChGbUdyaWRDb250cm9sKikgR2V0V2luZG93KCk7CgkJaWYgKHBHcmlkICYmIHBHcmlkLT5Jc09wZW4oKSkKCQkJcEdyaWQtPnBvc2l0aW9uZWQockV2ZW50KTsKCX0KfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8c2FsX3VJbnQxNj4mIEZtWEdyaWRQZWVyOjpnZXRTdXBwb3J0ZWRHcmlkU2xvdHMoKQp7CglzdGF0aWMgU2VxdWVuY2U8c2FsX3VJbnQxNj4gYVN1cHBvcnRlZDsKCWlmIChhU3VwcG9ydGVkLmdldExlbmd0aCgpID09IDApCgl7CgkJc2FsX3VJbnQxNiBuU3VwcG9ydGVkW10gPSB7CgkJCURiR3JpZENvbnRyb2w6Ok5hdmlnYXRpb25CYXI6OlJFQ09SRF9GSVJTVCwKCQkJRGJHcmlkQ29udHJvbDo6TmF2aWdhdGlvbkJhcjo6UkVDT1JEX1BSRVYsCgkJCURiR3JpZENvbnRyb2w6Ok5hdmlnYXRpb25CYXI6OlJFQ09SRF9ORVhULAoJCQlEYkdyaWRDb250cm9sOjpOYXZpZ2F0aW9uQmFyOjpSRUNPUkRfTEFTVCwKCQkJRGJHcmlkQ29udHJvbDo6TmF2aWdhdGlvbkJhcjo6UkVDT1JEX05FVywKCQkJU0lEX0ZNX1JFQ09SRF9VTkRPCgkJfTsKCQlhU3VwcG9ydGVkLnJlYWxsb2Moc2l6ZW9mKG5TdXBwb3J0ZWQpL3NpemVvZihuU3VwcG9ydGVkWzBdKSk7CgkJc2FsX3VJbnQxNiogcFN1cHBvcnRlZCA9IGFTdXBwb3J0ZWQuZ2V0QXJyYXkoKTsKCQlmb3IgKHNhbF91SW50MTYgaT0wOyBpPGFTdXBwb3J0ZWQuZ2V0TGVuZ3RoKCk7ICsraSwgKytwU3VwcG9ydGVkKQoJCQkqcFN1cHBvcnRlZCA9IG5TdXBwb3J0ZWRbaV07Cgl9CglyZXR1cm4gYVN1cHBvcnRlZDsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU2VxdWVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlVSTD4mIEZtWEdyaWRQZWVyOjpnZXRTdXBwb3J0ZWRVUkxzKCkKewoJc3RhdGljIFNlcXVlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpVUkw+IGFTdXBwb3J0ZWQ7CglpZiAoYVN1cHBvcnRlZC5nZXRMZW5ndGgoKSA9PSAwKQoJewoJCXN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgc1N1cHBvcnRlZFtdID0gewoJCQlGTVVSTF9SRUNPUkRfTU9WRUZJUlNULAoJCQlGTVVSTF9SRUNPUkRfTU9WRVBSRVYsCgkJCUZNVVJMX1JFQ09SRF9NT1ZFTkVYVCwKCQkJRk1VUkxfUkVDT1JEX01PVkVMQVNULAoJCQlGTVVSTF9SRUNPUkRfTU9WRVRPTkVXLAoJCQlGTVVSTF9SRUNPUkRfVU5ETwoJCX07CgkJYVN1cHBvcnRlZC5yZWFsbG9jKHNpemVvZihzU3VwcG9ydGVkKS9zaXplb2Yoc1N1cHBvcnRlZFswXSkpOwoJCTo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlVSTCogcFN1cHBvcnRlZCA9IGFTdXBwb3J0ZWQuZ2V0QXJyYXkoKTsKCQlzYWxfdUludDE2IGk7CgoJCWZvciAoIGkgPSAwOyBpIDwgYVN1cHBvcnRlZC5nZXRMZW5ndGgoKTsgKytpLCArK3BTdXBwb3J0ZWQpCgkJCXBTdXBwb3J0ZWQtPkNvbXBsZXRlID0gc1N1cHBvcnRlZFtpXTsKCgkJLy8gbGV0IGFuIDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlVSTC10cmFuc2Zvcm1lciBub3JtYWxpemUgdGhlIFVSTHMKCQlSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlhVUkxUcmFuc2Zvcm1lciA+ICB4VHJhbnNmb3JtZXIoCgkJCTo6Y29tcGhlbHBlcjo6Z2V0UHJvY2Vzc1NlcnZpY2VGYWN0b3J5KCktPmNyZWF0ZUluc3RhbmNlKAoJCQkJOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoImNvbS5zdW4uc3Rhci51dGlsLlVSTFRyYW5zZm9ybWVyIikpLAoJCQlVTk9fUVVFUlkpOwoJCXBTdXBwb3J0ZWQgPSBhU3VwcG9ydGVkLmdldEFycmF5KCk7CgkJaWYgKHhUcmFuc2Zvcm1lci5pcygpKQoJCXsKCQkJZm9yIChpPTA7IGk8YVN1cHBvcnRlZC5nZXRMZW5ndGgoKTsgKytpKQoJCQkJeFRyYW5zZm9ybWVyLT5wYXJzZVN0cmljdChwU3VwcG9ydGVkW2ldKTsKCQl9Cgl9CgoJcmV0dXJuIGFTdXBwb3J0ZWQ7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgRm1YR3JpZFBlZXI6OlVwZGF0ZURpc3BhdGNoZXMoKQp7CglpZiAoIW1fcFN0YXRlQ2FjaGUpCgl7CS8vIHdlIGRvbid0IGhhdmUgYW55IGRpc3BhdGNoZXJzIHlldCAtPiBkbyB0aGUgaW5pdGlhbCBjb25uZWN0CgkJQ29ubmVjdFRvRGlzcGF0Y2hlcigpOwoJCXJldHVybjsKCX0KCglzYWxfdUludDE2IG5EaXNwYXRjaGVyc0dvdCA9IDA7Cgljb25zdCBTZXF1ZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6VVJMPiYgYVN1cHBvcnRlZFVSTHMgPSBnZXRTdXBwb3J0ZWRVUkxzKCk7Cgljb25zdCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpVUkwqIHBTdXBwb3J0ZWRVUkxzID0gYVN1cHBvcnRlZFVSTHMuZ2V0Q29uc3RBcnJheSgpOwoJUmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpmcmFtZTo6WERpc3BhdGNoID4gIHhOZXdEaXNwYXRjaDsKCWZvciAoc2FsX3VJbnQxNiBpPTA7IGk8YVN1cHBvcnRlZFVSTHMuZ2V0TGVuZ3RoKCk7ICsraSwgKytwU3VwcG9ydGVkVVJMcykKCXsKCQl4TmV3RGlzcGF0Y2ggPSBxdWVyeURpc3BhdGNoKCpwU3VwcG9ydGVkVVJMcywgcnRsOjpPVVN0cmluZygpLCAwKTsKCQlpZiAoeE5ld0Rpc3BhdGNoICE9IG1fcERpc3BhdGNoZXJzW2ldKQoJCXsKCQkJaWYgKG1fcERpc3BhdGNoZXJzW2ldLmlzKCkpCgkJCQltX3BEaXNwYXRjaGVyc1tpXS0+cmVtb3ZlU3RhdHVzTGlzdGVuZXIoKDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYU3RhdHVzTGlzdGVuZXIqKXRoaXMsICpwU3VwcG9ydGVkVVJMcyk7CgkJCW1fcERpc3BhdGNoZXJzW2ldID0geE5ld0Rpc3BhdGNoOwoJCQlpZiAobV9wRGlzcGF0Y2hlcnNbaV0uaXMoKSkKCQkJCW1fcERpc3BhdGNoZXJzW2ldLT5hZGRTdGF0dXNMaXN0ZW5lcigoOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhTdGF0dXNMaXN0ZW5lciopdGhpcywgKnBTdXBwb3J0ZWRVUkxzKTsKCQl9CgkJaWYgKG1fcERpc3BhdGNoZXJzW2ldLmlzKCkpCgkJCSsrbkRpc3BhdGNoZXJzR290OwoJfQoKCWlmICghbkRpc3BhdGNoZXJzR290KQoJewoJCWRlbGV0ZVtdIG1fcFN0YXRlQ2FjaGU7CgkJZGVsZXRlW10gbV9wRGlzcGF0Y2hlcnM7CgkJbV9wU3RhdGVDYWNoZSA9IE5VTEw7CgkJbV9wRGlzcGF0Y2hlcnMgPSBOVUxMOwoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpDb25uZWN0VG9EaXNwYXRjaGVyKCkKewoJREJHX0FTU0VSVCgobV9wU3RhdGVDYWNoZSAhPSBOVUxMKSA9PSAobV9wRGlzcGF0Y2hlcnMgIT0gTlVMTCksICJGbVhHcmlkUGVlcjo6Q29ubmVjdFRvRGlzcGF0Y2hlciA6IGluY29uc2lzdGVudCAhIik7CglpZiAobV9wU3RhdGVDYWNoZSkKCXsJLy8gYWxyZWFkeSBjb25uZWN0ZWQgLT4ganVzdCBkbyBhbiB1cGRhdGUKCQlVcGRhdGVEaXNwYXRjaGVzKCk7CgkJcmV0dXJuOwoJfQoKCWNvbnN0IFNlcXVlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpVUkw+JiBhU3VwcG9ydGVkVVJMcyA9IGdldFN1cHBvcnRlZFVSTHMoKTsKCgkvLyBfYmVmb3JlXyBhZGRpbmcgdGhlIHN0YXR1cyBsaXN0ZW5lcnMgKGFzIHRoZSBhZGQgc2hvdWxkIHJlc3VsdCBpbiBhIHN0YXR1c0NoYW5nZWQtY2FsbCkgIQoJbV9wU3RhdGVDYWNoZSA9IG5ldyBzYWxfQm9vbFthU3VwcG9ydGVkVVJMcy5nZXRMZW5ndGgoKV07CgltX3BEaXNwYXRjaGVycyA9IG5ldyBSZWZlcmVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYRGlzcGF0Y2ggPiBbYVN1cHBvcnRlZFVSTHMuZ2V0TGVuZ3RoKCldOwoKCXNhbF91SW50MTYgbkRpc3BhdGNoZXJzR290ID0gMDsKCWNvbnN0IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlVSTCogcFN1cHBvcnRlZFVSTHMgPSBhU3VwcG9ydGVkVVJMcy5nZXRDb25zdEFycmF5KCk7Cglmb3IgKHNhbF91SW50MTYgaT0wOyBpPGFTdXBwb3J0ZWRVUkxzLmdldExlbmd0aCgpOyArK2ksICsrcFN1cHBvcnRlZFVSTHMpCgl7CgkJbV9wU3RhdGVDYWNoZVtpXSA9IDA7CgkJbV9wRGlzcGF0Y2hlcnNbaV0gPSBxdWVyeURpc3BhdGNoKCpwU3VwcG9ydGVkVVJMcywgcnRsOjpPVVN0cmluZygpLCAwKTsKCQlpZiAobV9wRGlzcGF0Y2hlcnNbaV0uaXMoKSkKCQl7CgkJCW1fcERpc3BhdGNoZXJzW2ldLT5hZGRTdGF0dXNMaXN0ZW5lcigoOjpjb206OnN1bjo6c3Rhcjo6ZnJhbWU6OlhTdGF0dXNMaXN0ZW5lciopdGhpcywgKnBTdXBwb3J0ZWRVUkxzKTsKCQkJKytuRGlzcGF0Y2hlcnNHb3Q7CgkJfQoJfQoKCWlmICghbkRpc3BhdGNoZXJzR290KQoJewoJCWRlbGV0ZVtdIG1fcFN0YXRlQ2FjaGU7CgkJZGVsZXRlW10gbV9wRGlzcGF0Y2hlcnM7CgkJbV9wU3RhdGVDYWNoZSA9IE5VTEw7CgkJbV9wRGlzcGF0Y2hlcnMgPSBOVUxMOwoJfQp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIEZtWEdyaWRQZWVyOjpEaXNDb25uZWN0RnJvbURpc3BhdGNoZXIoKQp7CglpZiAoIW1fcFN0YXRlQ2FjaGUgfHwgIW1fcERpc3BhdGNoZXJzKQoJCXJldHVybjsKCS8vIHdlJ3JlIG5vdCBjb25uZWN0ZWQKCgljb25zdCBTZXF1ZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6VVJMPiYgYVN1cHBvcnRlZFVSTHMgPSBnZXRTdXBwb3J0ZWRVUkxzKCk7Cgljb25zdCA6OmNvbTo6c3VuOjpzdGFyOjp1dGlsOjpVUkwqIHBTdXBwb3J0ZWRVUkxzID0gYVN1cHBvcnRlZFVSTHMuZ2V0Q29uc3RBcnJheSgpOwoJZm9yIChzYWxfdUludDE2IGk9MDsgaTxhU3VwcG9ydGVkVVJMcy5nZXRMZW5ndGgoKTsgKytpLCArK3BTdXBwb3J0ZWRVUkxzKQoJewoJCWlmIChtX3BEaXNwYXRjaGVyc1tpXS5pcygpKQoJCQltX3BEaXNwYXRjaGVyc1tpXS0+cmVtb3ZlU3RhdHVzTGlzdGVuZXIoKDo6Y29tOjpzdW46OnN0YXI6OmZyYW1lOjpYU3RhdHVzTGlzdGVuZXIqKXRoaXMsICpwU3VwcG9ydGVkVVJMcyk7Cgl9CgoJZGVsZXRlW10gbV9wU3RhdGVDYWNoZTsKCWRlbGV0ZVtdIG1fcERpc3BhdGNoZXJzOwoJbV9wU3RhdGVDYWNoZSA9IE5VTEw7CgltX3BEaXNwYXRjaGVycyA9IE5VTEw7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCklNUExfTElOSyhGbVhHcmlkUGVlciwgT25RdWVyeUdyaWRTbG90U3RhdGUsIHZvaWQqLCBwU2xvdCkKewoJaWYgKCFtX3BTdGF0ZUNhY2hlKQoJCXJldHVybiAtMTsJLy8gdW5zcGVjaWZpZWQKCglzYWxfdUludDE2IG5TbG90ID0gKHNhbF91SW50MTYpKHNhbF91SW50UHRyKXBTbG90OwoKCS8vIHNlYXJjaCB0aGUgZ2l2ZW4gc2xvdCB3aXRoIG91ciBzdXBwb3J0ZWQgc2VxdWVuY2UKCVNlcXVlbmNlPHNhbF91SW50MTY+JiBhU3VwcG9ydGVkID0gZ2V0U3VwcG9ydGVkR3JpZFNsb3RzKCk7Cgljb25zdCBzYWxfdUludDE2KiBwU2xvdHMgPSBhU3VwcG9ydGVkLmdldENvbnN0QXJyYXkoKTsKCWZvciAoc2FsX3VJbnQxNiBpPTA7IGk8YVN1cHBvcnRlZC5nZXRMZW5ndGgoKTsgKytpKQoJewoJCWlmIChwU2xvdHNbaV0gPT0gblNsb3QpCgkJewoJCQlpZiAoIW1fcERpc3BhdGNoZXJzW2ldLmlzKCkpCgkJCQlyZXR1cm4gLTE7CS8vIG5vdGhpbmcga25vd24gYWJvdXQgdGhpcyBzbG90CgkJCWVsc2UKCQkJCXJldHVybiBtX3BTdGF0ZUNhY2hlW2ldOwoJCX0KCX0KCglyZXR1cm4gIC0xOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpJTVBMX0xJTksoRm1YR3JpZFBlZXIsIE9uRXhlY3V0ZUdyaWRTbG90LCB2b2lkKiwgcFNsb3QpCnsKCWlmICghbV9wRGlzcGF0Y2hlcnMpCgkJcmV0dXJuIDA7CS8vIG5vdCBoYW5kbGVkCgoJU2VxdWVuY2U8IDo6Y29tOjpzdW46OnN0YXI6OnV0aWw6OlVSTD4mIGFVcmxzID0gZ2V0U3VwcG9ydGVkVVJMcygpOwoJY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6dXRpbDo6VVJMKiBwVXJscyA9IGFVcmxzLmdldENvbnN0QXJyYXkoKTsKCglTZXF1ZW5jZTxzYWxfdUludDE2PiBhU2xvdHMgPSBnZXRTdXBwb3J0ZWRHcmlkU2xvdHMoKTsKCWNvbnN0IHNhbF91SW50MTYqIHBTbG90cyA9IGFTbG90cy5nZXRDb25zdEFycmF5KCk7CgoJREJHX0FTU0VSVChhU2xvdHMuZ2V0TGVuZ3RoKCkgPT0gYVVybHMuZ2V0TGVuZ3RoKCksICJGbVhHcmlkUGVlcjo6T25FeGVjdXRlR3JpZFNsb3QgOiBpbmNvbnN0ZW50IGRhdGEgcmV0dXJuZWQgYnkgZ2V0U3VwcG9ydGVkVVJMcy9nZXRTdXBwb3J0ZWRHcmlkU2xvdHMgISIpOwoKCXNhbF91SW50MTYgblNsb3QgPSAoc2FsX3VJbnQxNikoc2FsX3VJbnRQdHIpcFNsb3Q7Cglmb3IgKHNhbF91SW50MTYgaT0wOyBpPGFTbG90cy5nZXRMZW5ndGgoKTsgKytpLCArK3BVcmxzLCArK3BTbG90cykKCXsKCQlpZiAoKnBTbG90cyA9PSBuU2xvdCkKCQl7CgkJCWlmIChtX3BEaXNwYXRjaGVyc1tpXS5pcygpKQoJCQl7CgkJCQkvLyBjb21taXQgYW55IGNoYW5nZXMgZG9uZSBzbyBmYXIsIGlmIGl0J3Mgbm90IHRoZSB1bmRvUmVjb3JkIFVSTAoJCQkJaWYgKCAwID09IHBVcmxzLT5Db21wbGV0ZS5jb21wYXJlVG8oIEZNVVJMX1JFQ09SRF9VTkRPICkgfHwgY29tbWl0KCkgKQoJCQkJCW1fcERpc3BhdGNoZXJzW2ldLT5kaXNwYXRjaCgqcFVybHMsIFNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlPigpKTsKCgkJCQlyZXR1cm4gMTsJLy8gaGFuZGxlZAoJCQl9CgkJfQoJfQoKCXJldHVybiAwOwkvLyBub3QgaGFuZGxlZAp9Cgo=