ZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9DQkFfRm9udG1hcC5oIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NCQV9Gb250bWFwLmgKaW5kZXggNzYyNDU5Ni4uNTBmNTE2MCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NCQV9Gb250bWFwLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NCQV9Gb250bWFwLmgKQEAgLTEsNTEgKzEsNTEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1JBT19GT05UTUFQX0hfDQotI2RlZmluZSBfUkFPX0ZPTlRNQVBfSF8NCi0NCi0jaWYgX01TQ19WRVIgPiAxMDAwDQotI3ByYWdtYSBvbmNlDQotI2VuZGlmIC8vIF9NU0NfVkVSID4gMTAwMA0KLQ0KLWNsYXNzIENQREZTREtfQW5ub3Q7DQotDQotY2xhc3MgQ0JBX0ZvbnRNYXAgOiBwdWJsaWMgQ1BXTF9Gb250TWFwDQotew0KLXB1YmxpYzoNCi0JQ0JBX0ZvbnRNYXAoQ1BERlNES19Bbm5vdCogcEFubm90LCBJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIpOw0KLQlDQkFfRm9udE1hcChDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRGljdGlvbmFyeSogcEFubm90RGljdCwgSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyKTsNCi0NCi0JdmlydHVhbCB+Q0JBX0ZvbnRNYXAoKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCUluaXRpYWwoRlhfTFBDU1RSIGZvbnRuYW1lID0gTlVMTCk7DQotDQotcHVibGljOg0KLQl2b2lkCQkJCQkJU2V0RGVmYXVsdEZvbnQoQ1BERl9Gb250ICogcEZvbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nICYgc0ZvbnROYW1lKTsNCi0NCi0Jdm9pZAkJCQkJCVJlc2V0KCk7DQotCXZvaWQJCQkJCQlTZXRBUFR5cGUoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFR5cGUpOw0KLQ0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCBDUERGX0ZvbnQqCQkJRmluZEZvbnRTYW1lQ2hhcnNldChDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcywgRlhfSU5UMzIgbkNoYXJzZXQpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJQWRkZWRGb250KENQREZfRm9udCogcEZvbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzKTsNCi0JdmlydHVhbCBDUERGX0RvY3VtZW50KgkJR2V0RG9jdW1lbnQoKTsNCi1wcml2YXRlOg0KLQlDUERGX0ZvbnQqCQkJCQlGaW5kUmVzRm9udFNhbWVDaGFyc2V0KENQREZfRGljdGlvbmFyeSogcFJlc0RpY3QsIENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzLA0KLQkJCQkJCQkJCUZYX0lOVDMyIG5DaGFyc2V0KTsNCi0JQ1BERl9Gb250KgkJCQkJR2V0QW5ub3REZWZhdWx0Rm9udChDRlhfQnl0ZVN0cmluZyAmY3NOYW1lVGFnKTsNCi0Jdm9pZAkJCQkJCUFkZEZvbnRUb0Fubm90RGljdChDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FsaWFzKTsNCi0NCi1wcml2YXRlOg0KLQlDUERGX0RvY3VtZW50KgkJCQltX3BEb2N1bWVudDsNCi0JQ1BERl9EaWN0aW9uYXJ5KgkJCW1fcEFubm90RGljdDsNCi0JQ1BERl9Gb250KgkJCQkJbV9wRGVmYXVsdEZvbnQ7DQotCUNGWF9CeXRlU3RyaW5nCQkJCW1fc0RlZmF1bHRGb250TmFtZTsNCi0JDQotCUNGWF9CeXRlU3RyaW5nCQkJCW1fc0FQVHlwZTsNCi19Ow0KLQ0KLSNlbmRpZiAvLyBfUkFPX0ZPTlRNQVBfSF8NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9SQU9fRk9OVE1BUF9IXworI2RlZmluZSBfUkFPX0ZPTlRNQVBfSF8KKworI2lmIF9NU0NfVkVSID4gMTAwMAorI3ByYWdtYSBvbmNlCisjZW5kaWYgLy8gX01TQ19WRVIgPiAxMDAwCisKK2NsYXNzIENQREZTREtfQW5ub3Q7CisKK2NsYXNzIENCQV9Gb250TWFwIDogcHVibGljIENQV0xfRm9udE1hcAoreworcHVibGljOgorCUNCQV9Gb250TWFwKENQREZTREtfQW5ub3QqIHBBbm5vdCwgSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyKTsKKwlDQkFfRm9udE1hcChDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRGljdGlvbmFyeSogcEFubm90RGljdCwgSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyKTsKKworCXZpcnR1YWwgfkNCQV9Gb250TWFwKCk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJSW5pdGlhbChGWF9MUENTVFIgZm9udG5hbWUgPSBOVUxMKTsKKworcHVibGljOgorCXZvaWQJCQkJCQlTZXREZWZhdWx0Rm9udChDUERGX0ZvbnQgKiBwRm9udCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcgJiBzRm9udE5hbWUpOworCisJdm9pZAkJCQkJCVJlc2V0KCk7CisJdm9pZAkJCQkJCVNldEFQVHlwZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FQVHlwZSk7CisKK3Byb3RlY3RlZDoKKwl2aXJ0dWFsIENQREZfRm9udCoJCQlGaW5kRm9udFNhbWVDaGFyc2V0KENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzLCBGWF9JTlQzMiBuQ2hhcnNldCk7CisJdmlydHVhbCB2b2lkCQkJCUFkZGVkRm9udChDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcyk7CisJdmlydHVhbCBDUERGX0RvY3VtZW50KgkJR2V0RG9jdW1lbnQoKTsKK3ByaXZhdGU6CisJQ1BERl9Gb250KgkJCQkJRmluZFJlc0ZvbnRTYW1lQ2hhcnNldChDUERGX0RpY3Rpb25hcnkqIHBSZXNEaWN0LCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcywKKwkJCQkJCQkJCUZYX0lOVDMyIG5DaGFyc2V0KTsKKwlDUERGX0ZvbnQqCQkJCQlHZXRBbm5vdERlZmF1bHRGb250KENGWF9CeXRlU3RyaW5nICZjc05hbWVUYWcpOworCXZvaWQJCQkJCQlBZGRGb250VG9Bbm5vdERpY3QoQ1BERl9Gb250KiBwRm9udCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBbGlhcyk7CisKK3ByaXZhdGU6CisJQ1BERl9Eb2N1bWVudCoJCQkJbV9wRG9jdW1lbnQ7CisJQ1BERl9EaWN0aW9uYXJ5KgkJCW1fcEFubm90RGljdDsKKwlDUERGX0ZvbnQqCQkJCQltX3BEZWZhdWx0Rm9udDsKKwlDRlhfQnl0ZVN0cmluZwkJCQltX3NEZWZhdWx0Rm9udE5hbWU7CisJCisJQ0ZYX0J5dGVTdHJpbmcJCQkJbV9zQVBUeXBlOworfTsKKworI2VuZGlmIC8vIF9SQU9fRk9OVE1BUF9IXwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NoZWNrQm94LmggYi9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ2hlY2tCb3guaAppbmRleCBmOGVlMzcwLi45YWFmN2ZlIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ2hlY2tCb3guaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ2hlY2tCb3guaApAQCAtMSwyNyArMSwyNyBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfRkZMX0NIRUNLQk9YX0hfDQotI2RlZmluZSBfRkZMX0NIRUNLQk9YX0hfDQotDQotY2xhc3MgQ0ZGTF9DaGVja0JveCA6IHB1YmxpYyBDRkZMX0J1dHRvbg0KLXsNCi1wdWJsaWM6DQotCUNGRkxfQ2hlY2tCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpOw0KLQl2aXJ0dWFsIH5DRkZMX0NoZWNrQm94KCk7DQotDQotCXZpcnR1YWwgQ1BXTF9XbmQqCQkJTmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktleURvd24oQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5LZXlDb2RlLCBGWF9VSU5UIG5GbGFncyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCUlzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsNCi0JdmlydHVhbCB2b2lkCQkJCVNhdmVEYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotfTsNCi0NCi0jZW5kaWYgLy9fRkZMX0NIRUNLQk9YX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRkZMX0NIRUNLQk9YX0hfCisjZGVmaW5lIF9GRkxfQ0hFQ0tCT1hfSF8KKworY2xhc3MgQ0ZGTF9DaGVja0JveCA6IHB1YmxpYyBDRkZMX0J1dHRvbgoreworcHVibGljOgorCUNGRkxfQ2hlY2tCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpOworCXZpcnR1YWwgfkNGRkxfQ2hlY2tCb3goKTsKKworCXZpcnR1YWwgQ1BXTF9XbmQqCQkJTmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuS2V5Q29kZSwgRlhfVUlOVCBuRmxhZ3MpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncyk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCisJdmlydHVhbCBGWF9CT09MCQkJCUlzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKwl2aXJ0dWFsIHZvaWQJCQkJU2F2ZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKK307CisKKyNlbmRpZiAvL19GRkxfQ0hFQ0tCT1hfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NvbWJvQm94LmggYi9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ29tYm9Cb3guaAppbmRleCBmMTE2YWNmLi42ZGY4MzQ3IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ29tYm9Cb3guaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ29tYm9Cb3guaApAQCAtMSw2OSArMSw2OSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfRkZMX0NPTUJPQk9YX0hfDQotICNkZWZpbmUgX0ZGTF9DT01CT0JPWF9IXw0KLQ0KLXN0cnVjdCBGRkxfQ29tYm9Cb3hTdGF0ZQ0KLXsNCi0JaW50IG5JbmRleDsNCi0JaW50IG5TdGFydDsNCi0JaW50IG5FbmQ7DQotCUNGWF9XaWRlU3RyaW5nIHNWYWx1ZTsNCi19Ow0KLWNsYXNzIENCQV9Gb250TWFwOw0KLQ0KLWNsYXNzIENGRkxfQ29tYm9Cb3ggOiBwdWJsaWMgQ0ZGTF9Gb3JtRmlsbGVyLCBwdWJsaWMgSVBXTF9Gb2N1c0hhbmRsZXIsIHB1YmxpYyBJUFdMX0VkaXRfTm90aWZ5DQotew0KLXB1YmxpYzoNCi0JQ0ZGTF9Db21ib0JveChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwV2lkZ2V0KTsNCi0JdmlydHVhbCB+Q0ZGTF9Db21ib0JveCgpOw0KLQkNCi0JdmlydHVhbAlQV0xfQ1JFQVRFUEFSQU0JCUdldENyZWF0ZVBhcmFtKCk7DQotCXZpcnR1YWwgQ1BXTF9XbmQqCQkJTmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotDQotCQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuQ2hhciwgRlhfVUlOVCBuRmxhZ3MpOw0KLQkNCi0JdmlydHVhbCBGWF9CT09MCQkJCUlzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsNCi0JdmlydHVhbCB2b2lkCQkJCVNhdmVEYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotCQ0KLSAJdmlydHVhbCB2b2lkCQkJCUdldEFjdGlvbkRhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIFBERlNES19GaWVsZEFjdGlvbiYgZmEpOw0KLSAJdmlydHVhbCB2b2lkCQkJCVNldEFjdGlvbkRhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIGNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmEpOw0KLSAJdmlydHVhbCBGWF9CT09MCQkJCUlzQWN0aW9uRGF0YUNoYW5nZWQoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBjb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhT2xkLCBjb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhTmV3KTsNCi0JdmlydHVhbCB2b2lkCQkJCVNhdmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJUmVzdG9yZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotCQ0KLQl2aXJ0dWFsIENQV0xfV25kKgkJCVJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uS2V5U3Ryb2tlKEZYX0JPT0wgYktleURvd24sIEZYX1VJTlQgbkZsYWcpOw0KLQkNCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQlPblNldEZvY3VzKENQV0xfV25kKiBwV25kKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uS2lsbEZvY3VzKENQV0xfV25kKiBwV25kKTsNCi0JDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJT25BZGRVbmRvKENQV0xfRWRpdCogcEVkaXQpOw0KLQkNCi1wdWJsaWM6DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlDYW5Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgDQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJRG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQl2aXJ0dWFsIHZvaWQJCQkJRG9DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgDQotCXZpcnR1YWwgdm9pZAkJCQlEb1Bhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQkNCi1wcml2YXRlOg0KLQlDRlhfV2lkZVN0cmluZwkJCQlHZXRTZWxlY3RFeHBvcnRUZXh0KCk7DQotDQotcHJpdmF0ZToNCi0JQ0JBX0ZvbnRNYXAqCQkJCW1fcEZvbnRNYXA7DQotCUZGTF9Db21ib0JveFN0YXRlCQkJCW1fU3RhdGU7DQotCS8vQ0ZGTF9JTV9CT1gJCQkJCW1fSU1Cb3g7DQotfTsNCi0NCi0jZW5kaWYgLy9fRkZMX0NPTUJPQk9YX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRkZMX0NPTUJPQk9YX0hfCisgI2RlZmluZSBfRkZMX0NPTUJPQk9YX0hfCisKK3N0cnVjdCBGRkxfQ29tYm9Cb3hTdGF0ZQoreworCWludCBuSW5kZXg7CisJaW50IG5TdGFydDsKKwlpbnQgbkVuZDsKKwlDRlhfV2lkZVN0cmluZyBzVmFsdWU7Cit9OworY2xhc3MgQ0JBX0ZvbnRNYXA7CisKK2NsYXNzIENGRkxfQ29tYm9Cb3ggOiBwdWJsaWMgQ0ZGTF9Gb3JtRmlsbGVyLCBwdWJsaWMgSVBXTF9Gb2N1c0hhbmRsZXIsIHB1YmxpYyBJUFdMX0VkaXRfTm90aWZ5Cit7CitwdWJsaWM6CisJQ0ZGTF9Db21ib0JveChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwV2lkZ2V0KTsKKwl2aXJ0dWFsIH5DRkZMX0NvbWJvQm94KCk7CisJCisJdmlydHVhbAlQV0xfQ1JFQVRFUEFSQU0JCUdldENyZWF0ZVBhcmFtKCk7CisJdmlydHVhbCBDUFdMX1duZCoJCQlOZXdQREZXaW5kb3coY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKworCQorCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncyk7CisJCisJdmlydHVhbCBGWF9CT09MCQkJCUlzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKwl2aXJ0dWFsIHZvaWQJCQkJU2F2ZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKwkKKyAJdmlydHVhbCB2b2lkCQkJCUdldEFjdGlvbkRhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIFBERlNES19GaWVsZEFjdGlvbiYgZmEpOworIAl2aXJ0dWFsIHZvaWQJCQkJU2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSk7CisgCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0FjdGlvbkRhdGFDaGFuZ2VkKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU9sZCwgY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU5ldyk7CisJdmlydHVhbCB2b2lkCQkJCVNhdmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCXZpcnR1YWwgdm9pZAkJCQlSZXN0b3JlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKwkKKwl2aXJ0dWFsIENQV0xfV25kKgkJCVJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25LZXlTdHJva2UoRlhfQk9PTCBiS2V5RG93biwgRlhfVUlOVCBuRmxhZyk7CisJCitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCU9uU2V0Rm9jdXMoQ1BXTF9XbmQqIHBXbmQpOworCXZpcnR1YWwgdm9pZAkJCQlPbktpbGxGb2N1cyhDUFdMX1duZCogcFduZCk7CisJCitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCU9uQWRkVW5kbyhDUFdMX0VkaXQqIHBFZGl0KTsKKwkKK3B1YmxpYzoKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IAorCXZpcnR1YWwgRlhfQk9PTAkJCQlDYW5QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwkKKwl2aXJ0dWFsIHZvaWQJCQkJRG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IAorCXZpcnR1YWwgdm9pZAkJCQlEb0N1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwl2aXJ0dWFsIHZvaWQJCQkJRG9QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwkKK3ByaXZhdGU6CisJQ0ZYX1dpZGVTdHJpbmcJCQkJR2V0U2VsZWN0RXhwb3J0VGV4dCgpOworCitwcml2YXRlOgorCUNCQV9Gb250TWFwKgkJCQltX3BGb250TWFwOworCUZGTF9Db21ib0JveFN0YXRlCQkJCW1fU3RhdGU7CisJLy9DRkZMX0lNX0JPWAkJCQkJbV9JTUJveDsKK307CisKKyNlbmRpZiAvL19GRkxfQ09NQk9CT1hfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmgKaW5kZXggZWI4MTY3NS4uN2EzNDAyYSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oCkBAIC0xLDE3OCArMSwxNzggQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZGTF9GT1JNRklMTEVSX0hfDQotI2RlZmluZSBfRkZMX0ZPUk1GSUxMRVJfSF8NCi0NCi0jaW5jbHVkZSAiRkZMX0lGb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIkZGTF9DQkFfRm9udG1hcC5oIg0KLQ0KLWNsYXNzIENQREZTREtfQW5ub3Q7DQotY2xhc3MgQ0ZGTF9Gb3JtRmlsbGVyOw0KLWNsYXNzIENGRkxfTm90aWZ5Ow0KLWNsYXNzIENQREZEb2NfRW52aXJvbm1lbnQ7DQotY2xhc3MgQ1BERlNES19QYWdlVmlldzsNCi1jbGFzcyBDUERGU0RLX0RvY3VtZW50Ow0KLWNsYXNzIENQREZTREtfV2lkZ2V0Ow0KLQ0KLQ0KLSNkZWZpbmUgQ0ZGTF9QYWdlVmlldzJQREZXaW5kb3cJCUNGWF9NYXBQdHJUZW1wbGF0ZTxDUERGU0RLX1BhZ2VWaWV3KiwgQ1BXTF9XbmQqPg0KLQ0KLXN0cnVjdCBGRkxfS2V5U3Ryb2tlRGF0YQ0KLXsNCi0JQ0ZYX1dpZGVTdHJpbmcJCXN3VmFsdWU7DQotCUZYX0JPT0wJCQkJYkZ1bGw7DQotCWludAkJCQkJblNlbFN0YXJ0Ow0KLQlpbnQJCQkJCW5TZWxFbmQ7DQotfTsNCi0NCi0NCi0NCi1jbGFzcyBDRkZMX0Zvcm1GaWxsZXIgOiAvKnB1YmxpYyBJQkFfQW5ub3RGaWxsZXIsKi8gcHVibGljIElQV0xfUHJvdmlkZXIsIHB1YmxpYyBDUFdMX1RpbWVySGFuZGxlcg0KLXsNCi1wdWJsaWM6DQotCUNGRkxfRm9ybUZpbGxlcihDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQl2aXJ0dWFsIH5DRkZMX0Zvcm1GaWxsZXIoKTsNCi0NCi0JdmlydHVhbCBGWF9SRUNUCQkJCUdldFZpZXdCQm94KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIA0KLQkJCQkJCQkJCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csICovRlhfRFdPUkQgZHdGbGFncyk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRyYXdEZWFjdGl2ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIA0KLQkJCQkJCQkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCQkJCQkJCS8qY29uc3QgQ1JlY3QmIHJjV2luZG93LCAqL0ZYX0RXT1JEIGR3RmxhZ3MpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25DcmVhdGUoQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uTG9hZChDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25EZWxldGUoQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbk1vdXNlRXhpdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25EYmxDbGsoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbk1vdXNlTW92ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTW91c2VXaGVlbChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25SQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uUkJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25SQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuS2V5Q29kZSwgRlhfVUlOVCBuRmxhZ3MpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuQ2hhciwgRlhfVUlOVCBuRmxhZ3MpOw0KLQ0KLQl2aXJ0dWFsCXZvaWQJCQkJT25EZVNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotCXZpcnR1YWwJdm9pZAkJCQlPblNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPblNldEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktpbGxGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWcpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyANCi0JdmlydHVhbCBGWF9CT09MCQkJCUNhbkN1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyANCi0JdmlydHVhbCBGWF9CT09MCQkJCUNhblBhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJRG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQl2aXJ0dWFsIHZvaWQJCQkJRG9DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgDQotCXZpcnR1YWwgdm9pZAkJCQlEb1Bhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQ0KLXB1YmxpYzogLy9DUFdMX1RpbWVySGFuZGxlcg0KLQl2aXJ0dWFsIHZvaWQJCQkJVGltZXJQcm9jKCk7DQotCXZpcnR1YWwgSUZYX1N5c3RlbUhhbmRsZXIqCUdldFN5c3RlbUhhbmRsZXIoKSBjb25zdDsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgQ1BERl9NYXRyaXgJCQlHZXRXaW5kb3dNYXRyaXgodm9pZCogcEF0dGFjaGVkRGF0YSk7DQotCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCUxvYWRQb3B1cE1lbnVTdHJpbmcoaW50IG5JbmRleCk7DQotDQotIAl2aXJ0dWFsIHZvaWQJCQkJR2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwNCi0gCQkJCQkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSk7DQotIAl2aXJ0dWFsIHZvaWQJCQkJU2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgDQotIAkJCQkJCQkJCWNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmEpOw0KLSAJdmlydHVhbCBGWF9CT09MCQkJCUlzQWN0aW9uRGF0YUNoYW5nZWQoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBjb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhT2xkLCANCi0gCQkJCQkJCQkJY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU5ldyk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlTYXZlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsNCi0JdmlydHVhbCB2b2lkCQkJCVJlc3RvcmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQ0KLQl2aXJ0dWFsIENQV0xfV25kKiAJCQlSZXNldFBERldpbmRvdyhDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wgYlJlc3RvcmVWYWx1ZSk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbktleVN0cm9rZShGWF9CT09MIGJLZXlEb3duKTsNCi0NCi0JQ1BERl9NYXRyaXgJCQkJCUdldEN1ck1hdHJpeCgpOw0KLQ0KLQlDUERGX1JlY3QJCQkJCUZGTHRvUFdMKGNvbnN0IENQREZfUmVjdCYgcmVjdCk7DQotCUNQREZfUmVjdAkJCQkJUFdMdG9GRkwoY29uc3QgQ1BERl9SZWN0JiByZWN0KTsNCi0JQ1BERl9Qb2ludAkJCQkJRkZMdG9QV0woY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQlDUERGX1BvaW50CQkJCQlQV0x0b0ZGTChjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotDQotCUNQREZfUG9pbnQJCQkJCVduZHRvUFdMKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgY29uc3QgQ1BERl9Qb2ludCYgcHQpOw0KLQlDUERGX1JlY3QJCQkJCUZGTHRvV25kKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgY29uc3QgQ1BERl9SZWN0JiByZWN0KTsNCi0NCi0Jdm9pZAkJCQkJCVNldFdpbmRvd1JlY3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBjb25zdCBDUERGX1JlY3QmIHJjV2luZG93KTsNCi0JQ1BERl9SZWN0CQkJCQlHZXRXaW5kb3dSZWN0KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotDQotCXN0YXRpYyB2b2lkCQkJCQlGRkxfRnJlZURhdGEodm9pZCogcERhdGEpOw0KLQ0KLQlGWF9CT09MCQkJCQkJQ29tbWl0RGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX1VJTlQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNEYXRhQ2hhbmdlZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJU2F2ZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCUdldEtleVN0cm9rZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGRkxfS2V5U3Ryb2tlRGF0YSYgZGF0YSk7DQotDQotcHVibGljOg0KLQlDUFdMX1duZCoJCQkJCUdldFBERldpbmRvdyhDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wgYk5ldyk7DQotCXZvaWQJCQkJCQlEZXN0cm95UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotCXZvaWQJCQkJCQlFc2NhcGVGaWxsZXIoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MIGJEZXN0cm95UERGV2luZG93KTsNCi0NCi0JdmlydHVhbAlQV0xfQ1JFQVRFUEFSQU0JCUdldENyZWF0ZVBhcmFtKCk7DQotCXZpcnR1YWwgQ1BXTF9XbmQqCQkJTmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykgPSAwOw0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCUdldEZvY3VzQm94KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotDQotcHVibGljOg0KLQlGWF9CT09MCQkJCQkJSXNWYWxpZCgpIGNvbnN0Ow0KLQlDUERGX1JlY3QJCQkJCUdldFBERldpbmRvd1JlY3QoKSBjb25zdDsNCi0NCi0JQ1BERlNES19QYWdlVmlldyoJCQlHZXRDdXJQYWdlVmlldygpOw0KLQl2b2lkCQkJCQkJU2V0Q2hhbmdlTWFyaygpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJSW52YWxpZGF0ZVJlY3QoZG91YmxlIGxlZnQsIGRvdWJsZSB0b3AsIGRvdWJsZSByaWdodCwgZG91YmxlIGJvdHRvbSk7DQotCUNQREZEb2NfRW52aXJvbm1lbnQqCQlHZXRBcHAoKXtyZXR1cm4gbV9wQXBwO30NCi0JQ1BERlNES19Bbm5vdCoJCQkJR2V0U0RLQW5ub3QoKSB7cmV0dXJuIG1fcEFubm90O30JDQotcHJvdGVjdGVkOg0KLQlDUERGRG9jX0Vudmlyb25tZW50KgkJbV9wQXBwOw0KLQlDUERGU0RLX1dpZGdldCoJCQkJbV9wV2lkZ2V0Ow0KLQlDUERGU0RLX0Fubm90KgkJCQltX3BBbm5vdDsNCi0NCi0JRlhfQk9PTAkJCQkJCW1fYlZhbGlkOw0KLQlDRkZMX1BhZ2VWaWV3MlBERldpbmRvdwkJbV9NYXBzOw0KLQlDUERGX1BvaW50CQkJCQltX3B0T2xkUG9zOw0KLX07DQotDQotY2xhc3MgQ0ZGTF9CdXR0b24gOiBwdWJsaWMgQ0ZGTF9Gb3JtRmlsbGVyDQotew0KLXB1YmxpYzoNCi0JQ0ZGTF9CdXR0b24oQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19Bbm5vdCogcFdpZGdldCk7DQotCXZpcnR1YWwgfkNGRkxfQnV0dG9uKCk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbk1vdXNlRW50ZXIoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25Nb3VzZUV4aXQoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25Nb3VzZU1vdmUoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRyYXcoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LyosIEhEQyBoREMqLywgQ1BERlNES19Bbm5vdCogcEFubm90LCANCi0JCQkJCQkJCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQkvKmNvbnN0IENSZWN0JiByY1dpbmRvdywqLyBGWF9EV09SRCBkd0ZsYWdzKTsNCi0NCi0JdmlydHVhbAl2b2lkCQkJCU9uRHJhd0RlYWN0aXZlKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgLypIREMgaERDLCovIENQREZTREtfQW5ub3QqIHBBbm5vdCwgDQotCQkJCQkJCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csICovRlhfRFdPUkQgZHdGbGFncyk7DQotcHJvdGVjdGVkOg0KLQlGWF9CT09MCQkJCQkJbV9iTW91c2VJbjsNCi0JRlhfQk9PTAkJCQkJCW1fYk1vdXNlRG93bjsNCi19Ow0KLQ0KLS8vI2RlZmluZSBDRkZMX0lNX0JPWAkJCQlDRlhfQXJyYXlUZW1wbGF0ZTxDQkFfRWRpdElucHV0Kj4NCi0NCi0jZW5kaWYNCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GRkxfRk9STUZJTExFUl9IXworI2RlZmluZSBfRkZMX0ZPUk1GSUxMRVJfSF8KKworI2luY2x1ZGUgIkZGTF9JRm9ybUZpbGxlci5oIgorI2luY2x1ZGUgIkZGTF9DQkFfRm9udG1hcC5oIgorCitjbGFzcyBDUERGU0RLX0Fubm90OworY2xhc3MgQ0ZGTF9Gb3JtRmlsbGVyOworY2xhc3MgQ0ZGTF9Ob3RpZnk7CitjbGFzcyBDUERGRG9jX0Vudmlyb25tZW50OworY2xhc3MgQ1BERlNES19QYWdlVmlldzsKK2NsYXNzIENQREZTREtfRG9jdW1lbnQ7CitjbGFzcyBDUERGU0RLX1dpZGdldDsKKworCisjZGVmaW5lIENGRkxfUGFnZVZpZXcyUERGV2luZG93CQlDRlhfTWFwUHRyVGVtcGxhdGU8Q1BERlNES19QYWdlVmlldyosIENQV0xfV25kKj4KKworc3RydWN0IEZGTF9LZXlTdHJva2VEYXRhCit7CisJQ0ZYX1dpZGVTdHJpbmcJCXN3VmFsdWU7CisJRlhfQk9PTAkJCQliRnVsbDsKKwlpbnQJCQkJCW5TZWxTdGFydDsKKwlpbnQJCQkJCW5TZWxFbmQ7Cit9OworCisKKworY2xhc3MgQ0ZGTF9Gb3JtRmlsbGVyIDogLypwdWJsaWMgSUJBX0Fubm90RmlsbGVyLCovIHB1YmxpYyBJUFdMX1Byb3ZpZGVyLCBwdWJsaWMgQ1BXTF9UaW1lckhhbmRsZXIKK3sKK3B1YmxpYzoKKwlDRkZMX0Zvcm1GaWxsZXIoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19Bbm5vdCogcEFubm90KTsKKwl2aXJ0dWFsIH5DRkZMX0Zvcm1GaWxsZXIoKTsKKworCXZpcnR1YWwgRlhfUkVDVAkJCQlHZXRWaWV3QkJveChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisJdmlydHVhbCB2b2lkCQkJCU9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIAorCQkJCQkJCQkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQkJCS8qY29uc3QgQ1JlY3QmIHJjV2luZG93LCAqL0ZYX0RXT1JEIGR3RmxhZ3MpOworCXZpcnR1YWwgdm9pZAkJCQlPbkRyYXdEZWFjdGl2ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIAorCQkJCQkJCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQkJCQkJCQkvKmNvbnN0IENSZWN0JiByY1dpbmRvdywgKi9GWF9EV09SRCBkd0ZsYWdzKTsKKworCXZpcnR1YWwgdm9pZAkJCQlPbkNyZWF0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCXZpcnR1YWwgdm9pZAkJCQlPbkxvYWQoQ1BERlNES19Bbm5vdCogcEFubm90KTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25EZWxldGUoQ1BERlNES19Bbm5vdCogcEFubm90KTsKKworCXZpcnR1YWwgdm9pZAkJCQlPbk1vdXNlRW50ZXIoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCXZpcnR1YWwgdm9pZAkJCQlPbk1vdXNlRXhpdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25Nb3VzZU1vdmUoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTW91c2VXaGVlbChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25SQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCisJdmlydHVhbCBGWF9CT09MCQkJCU9uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbktleUNvZGUsIEZYX1VJTlQgbkZsYWdzKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuQ2hhciwgRlhfVUlOVCBuRmxhZ3MpOworCisJdmlydHVhbAl2b2lkCQkJCU9uRGVTZWxlY3RlZChDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCXZpcnR1YWwJdm9pZAkJCQlPblNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25TZXRGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktpbGxGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWcpOworCisJdmlydHVhbCBGWF9CT09MCQkJCUNhbkNvcHkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgCisJdmlydHVhbCBGWF9CT09MCQkJCUNhbkN1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgCisKKwl2aXJ0dWFsIHZvaWQJCQkJRG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IAorCXZpcnR1YWwgdm9pZAkJCQlEb0N1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwl2aXJ0dWFsIHZvaWQJCQkJRG9QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKworcHVibGljOiAvL0NQV0xfVGltZXJIYW5kbGVyCisJdmlydHVhbCB2b2lkCQkJCVRpbWVyUHJvYygpOworCXZpcnR1YWwgSUZYX1N5c3RlbUhhbmRsZXIqCUdldFN5c3RlbUhhbmRsZXIoKSBjb25zdDsKKworcHVibGljOgorCXZpcnR1YWwgQ1BERl9NYXRyaXgJCQlHZXRXaW5kb3dNYXRyaXgodm9pZCogcEF0dGFjaGVkRGF0YSk7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJTG9hZFBvcHVwTWVudVN0cmluZyhpbnQgbkluZGV4KTsKKworIAl2aXJ0dWFsIHZvaWQJCQkJR2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwKKyAJCQkJCQkJCQlQREZTREtfRmllbGRBY3Rpb24mIGZhKTsKKyAJdmlydHVhbCB2b2lkCQkJCVNldEFjdGlvbkRhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIAorIAkJCQkJCQkJCWNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmEpOworIAl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNBY3Rpb25EYXRhQ2hhbmdlZChDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIGNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmFPbGQsIAorIAkJCQkJCQkJCWNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmFOZXcpOworCisJdmlydHVhbCB2b2lkCQkJCVNhdmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCXZpcnR1YWwgdm9pZAkJCQlSZXN0b3JlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKworCXZpcnR1YWwgQ1BXTF9XbmQqIAkJCVJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKTsKKworCXZpcnR1YWwgdm9pZAkJCQlPbktleVN0cm9rZShGWF9CT09MIGJLZXlEb3duKTsKKworCUNQREZfTWF0cml4CQkJCQlHZXRDdXJNYXRyaXgoKTsKKworCUNQREZfUmVjdAkJCQkJRkZMdG9QV0woY29uc3QgQ1BERl9SZWN0JiByZWN0KTsKKwlDUERGX1JlY3QJCQkJCVBXTHRvRkZMKGNvbnN0IENQREZfUmVjdCYgcmVjdCk7CisJQ1BERl9Qb2ludAkJCQkJRkZMdG9QV0woY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCUNQREZfUG9pbnQJCQkJCVBXTHRvRkZMKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKworCUNQREZfUG9pbnQJCQkJCVduZHRvUFdMKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgY29uc3QgQ1BERl9Qb2ludCYgcHQpOworCUNQREZfUmVjdAkJCQkJRkZMdG9XbmQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBjb25zdCBDUERGX1JlY3QmIHJlY3QpOworCisJdm9pZAkJCQkJCVNldFdpbmRvd1JlY3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBjb25zdCBDUERGX1JlY3QmIHJjV2luZG93KTsKKwlDUERGX1JlY3QJCQkJCUdldFdpbmRvd1JlY3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKworCXN0YXRpYyB2b2lkCQkJCQlGRkxfRnJlZURhdGEodm9pZCogcERhdGEpOworCisJRlhfQk9PTAkJCQkJCUNvbW1pdERhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9VSU5UIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNEYXRhQ2hhbmdlZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCXZpcnR1YWwgdm9pZAkJCQlTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCisJdmlydHVhbCB2b2lkCQkJCUdldEtleVN0cm9rZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGRkxfS2V5U3Ryb2tlRGF0YSYgZGF0YSk7CisKK3B1YmxpYzoKKwlDUFdMX1duZCoJCQkJCUdldFBERldpbmRvdyhDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wgYk5ldyk7CisJdm9pZAkJCQkJCURlc3Ryb3lQREZXaW5kb3coQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKwl2b2lkCQkJCQkJRXNjYXBlRmlsbGVyKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiRGVzdHJveVBERldpbmRvdyk7CisKKwl2aXJ0dWFsCVBXTF9DUkVBVEVQQVJBTQkJR2V0Q3JlYXRlUGFyYW0oKTsKKwl2aXJ0dWFsIENQV0xfV25kKgkJCU5ld1BERldpbmRvdyhjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpID0gMDsKKwl2aXJ0dWFsIENQREZfUmVjdAkJCUdldEZvY3VzQm94KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisKK3B1YmxpYzoKKwlGWF9CT09MCQkJCQkJSXNWYWxpZCgpIGNvbnN0OworCUNQREZfUmVjdAkJCQkJR2V0UERGV2luZG93UmVjdCgpIGNvbnN0OworCisJQ1BERlNES19QYWdlVmlldyoJCQlHZXRDdXJQYWdlVmlldygpOworCXZvaWQJCQkJCQlTZXRDaGFuZ2VNYXJrKCk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJSW52YWxpZGF0ZVJlY3QoZG91YmxlIGxlZnQsIGRvdWJsZSB0b3AsIGRvdWJsZSByaWdodCwgZG91YmxlIGJvdHRvbSk7CisJQ1BERkRvY19FbnZpcm9ubWVudCoJCUdldEFwcCgpe3JldHVybiBtX3BBcHA7fQorCUNQREZTREtfQW5ub3QqCQkJCUdldFNES0Fubm90KCkge3JldHVybiBtX3BBbm5vdDt9CQorcHJvdGVjdGVkOgorCUNQREZEb2NfRW52aXJvbm1lbnQqCQltX3BBcHA7CisJQ1BERlNES19XaWRnZXQqCQkJCW1fcFdpZGdldDsKKwlDUERGU0RLX0Fubm90KgkJCQltX3BBbm5vdDsKKworCUZYX0JPT0wJCQkJCQltX2JWYWxpZDsKKwlDRkZMX1BhZ2VWaWV3MlBERldpbmRvdwkJbV9NYXBzOworCUNQREZfUG9pbnQJCQkJCW1fcHRPbGRQb3M7Cit9OworCitjbGFzcyBDRkZMX0J1dHRvbiA6IHB1YmxpYyBDRkZMX0Zvcm1GaWxsZXIKK3sKK3B1YmxpYzoKKwlDRkZMX0J1dHRvbihDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwV2lkZ2V0KTsKKwl2aXJ0dWFsIH5DRkZMX0J1dHRvbigpOworCisJdmlydHVhbCB2b2lkCQkJCU9uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisJdmlydHVhbCB2b2lkCQkJCU9uTW91c2VFeGl0KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTW91c2VNb3ZlKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZpcnR1YWwgdm9pZAkJCQlPbkRyYXcoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LyosIEhEQyBoREMqLywgQ1BERlNES19Bbm5vdCogcEFubm90LCAKKwkJCQkJCQkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csKi8gRlhfRFdPUkQgZHdGbGFncyk7CisKKwl2aXJ0dWFsCXZvaWQJCQkJT25EcmF3RGVhY3RpdmUoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCAvKkhEQyBoREMsKi8gQ1BERlNES19Bbm5vdCogcEFubm90LCAKKwkJCQkJCQkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csICovRlhfRFdPUkQgZHdGbGFncyk7Citwcm90ZWN0ZWQ6CisJRlhfQk9PTAkJCQkJCW1fYk1vdXNlSW47CisJRlhfQk9PTAkJCQkJCW1fYk1vdXNlRG93bjsKK307CisKKy8vI2RlZmluZSBDRkZMX0lNX0JPWAkJCQlDRlhfQXJyYXlUZW1wbGF0ZTxDQkFfRWRpdElucHV0Kj4KKworI2VuZGlmCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfSUZvcm1GaWxsZXIuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9JRm9ybUZpbGxlci5oCmluZGV4IDc5YjRiOGUuLjM5M2YwYmUgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9JRm9ybUZpbGxlci5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9JRm9ybUZpbGxlci5oCkBAIC0xLDE0NCArMSwxNDQgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZGTF9JRk9STUZJTExFUl9IXw0KLSNkZWZpbmUgX0ZGTF9JRk9STUZJTExFUl9IXw0KLQ0KLSNpbmNsdWRlICJGb3JtRmlsbGVyLmgiDQotY2xhc3MgQ0ZGTF9Gb3JtRmlsbGVyOw0KLWNsYXNzIENGRkxfUHJpdmF0ZURhdGE7DQotDQotI2RlZmluZSBDRkZMX1dpZGdldDJGaWxsZXIJCUNGWF9NYXBQdHJUZW1wbGF0ZTxDUERGU0RLX0Fubm90KiwgQ0ZGTF9Gb3JtRmlsbGVyKj4NCi0NCi0vLyAjZGVmaW5lIElzQUxUcHJlc3NlZCgpCQkJKEdldEtleVN0YXRlKFZLX01FTlUpIDwgMCkNCi0vLyAjZGVmaW5lIElzQ1RSTHByZXNzZWQoKQkJCShHZXRLZXlTdGF0ZShWS19DT05UUk9MKSA8IDApDQotLy8gI2RlZmluZSBJc1NISUZUcHJlc3NlZCgpCQkoR2V0S2V5U3RhdGUoVktfU0hJRlQpJjB4ODAwMCkNCi0vLyAjZGVmaW5lIElzSU5TRVJUcHJlc3NlZCgpCQkoR2V0S2V5U3RhdGUoVktfSU5TRVJUKSAmIDB4MDEpCQ0KLS8vICNkZWZpbmUgVktfU0hJRlQgICAgICAgICAgMHgxMA0KLS8vICNkZWZpbmUgVktfQ09OVFJPTCAgICAgICAgMHgxMQ0KLS8vICNkZWZpbmUgVktfTUVOVSAgICAgICAgICAgMHgxMg0KLS8vICNkZWZpbmUgVktfUkVUVVJOICAgICAgICAgMHgwRA0KLS8vICNkZWZpbmUgVktfU1BBQ0UgICAgICAgICAgMHgyMA0KLS8vICNkZWZpbmUgVktfRVNDQVBFICAgICAgICAgMHgxQg0KLQ0KLQ0KLQ0KLWNsYXNzIENGRkxfSUZvcm1GaWxsZXIgOi8qIHB1YmxpYyBJQkFfQW5ub3RGaWxsZXIsICovcHVibGljIElQV0xfRmlsbGVyX05vdGlmeS8vLCANCi0vLwlwdWJsaWMgSVVuZG9fRXZlbnRIYW5kbGVyLCBwdWJsaWMgSUNsaXBib2FyZF9IYW5kbGVyDQotew0KLXB1YmxpYzoNCi0JQ0ZGTF9JRm9ybUZpbGxlcihDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwKTsNCi0JdmlydHVhbCB+Q0ZGTF9JRm9ybUZpbGxlcigpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfSGl0VGVzdChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsQ1BERlNES19Bbm5vdCogcEFubm90LCBDUERGX1BvaW50IHBvaW50KTsNCi0JdmlydHVhbCBGWF9SRUNUCQkJCUdldFZpZXdCQm94KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIA0KLQkJCQkJCQkJCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csKi8gRlhfRFdPUkQgZHdGbGFncyk7DQotDQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbkNyZWF0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25Mb2FkKENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRlbGV0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25Nb3VzZUVudGVyKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uTW91c2VFeGl0KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnKTsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTW91c2VNb3ZlKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25Nb3VzZVdoZWVsKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25SQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25EYmxDbGsoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktleURvd24oQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5LZXlDb2RlLCBGWF9VSU5UIG5GbGFncyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncyk7DQotDQotCXZpcnR1YWwJdm9pZAkJCQlPbkRlU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0JdmlydHVhbAl2b2lkCQkJCU9uU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uU2V0Rm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LEZYX1VJTlQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25LaWxsRm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnKTsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQlRdWVyeVdoZXJlUG9wdXAodm9pZCogcFByaXZhdGVEYXRhLCBGWF9GTE9BVCBmUG9wdXBNaW4sRlhfRkxPQVQgZlBvcHVwTWF4LCBGWF9JTlQzMiAmIG5SZXQsIEZYX0ZMT0FUICYgZlBvcHVwUmV0KTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uQmVmb3JlS2V5U3Ryb2tlKEZYX0JPT0wgYkVkaXRPckxpc3QsIHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfSU5UMzIgbktleUNvZGUsDQotCQkJCQkJCQkJCUNGWF9XaWRlU3RyaW5nICYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIA0KLQkJCQkJCQkJCQlpbnQgblNlbFN0YXJ0LCBpbnQgblNlbEVuZCwNCi0JCQkJCQkJCQkJRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCAmIGJSQywgRlhfQk9PTCAmIGJFeGl0LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkFmdGVyS2V5U3Ryb2tlKEZYX0JPT0wgYkVkaXRPckxpc3QsIHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfQk9PTCAmIGJFeGl0LCBGWF9EV09SRCBuRmxhZykgOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TZXRXaW5kb3dSZWN0KHZvaWQqIHBQcml2YXRlRGF0YSwgY29uc3QgQ1BERl9SZWN0ICYgcmNXaW5kb3cpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25LZXlTdHJva2UoRlhfQk9PTCBiRWRpdE9yTGlzdCwgdm9pZCogcFByaXZhdGVEYXRhLCBGWF9JTlQzMiBuS2V5Q29kZSwgQ0ZYX1dpZGVTdHJpbmcgJiBzdHJDaGFuZ2UsIA0KLQkJCQkJCQkJCWNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwgRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCAmIGJSQywgRlhfQk9PTCAmIGJFeGl0KTsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQlCZWZvcmVVbmRvKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7DQotCXZpcnR1YWwgdm9pZAkJCQlCZWZvcmVSZWRvKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7DQotCXZpcnR1YWwgdm9pZAkJCQlBZnRlclVuZG8oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsNCi0JdmlydHVhbCB2b2lkCQkJCUFmdGVyUmVkbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOw0KLQ0KLXB1YmxpYzoNCi0JdmlydHVhbCBGWF9CT09MCQkJCUNhbkNvcHkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlDYW5DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlDYW5QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyANCi0NCi0JdmlydHVhbCB2b2lkCQkJCURvQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyANCi0JdmlydHVhbCB2b2lkCQkJCURvQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQl2aXJ0dWFsIHZvaWQJCQkJRG9QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyANCi0NCi1wdWJsaWM6DQotCUNGRkxfRm9ybUZpbGxlcioJCQlHZXRGb3JtRmlsbGVyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfQk9PTCBiUmVnaXN0ZXIpOw0KLQl2b2lkCQkJCQkJUmVtb3ZlRm9ybUZpbGxlcihDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQ0KLQlzdGF0aWMgRlhfQk9PTAkJCQlJc1Zpc2libGUoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpOw0KLQlzdGF0aWMgRlhfQk9PTAkJCQlJc1JlYWRPbmx5KENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0KTsNCi0Jc3RhdGljIEZYX0JPT0wJCQkJSXNGaWxsaW5nQWxsb3dlZChDUERGU0RLX1dpZGdldCogcFdpZGdldCk7DQotIAlzdGF0aWMgRlhfQk9PTAkJCQlJc1ZhbGlkQW5ub3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQ0KLQl2b2lkCQkJCQkJT25LZXlTdHJva2VDb21taXQoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYlJDLCBGWF9CT09MJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2b2lkCQkJCQkJT25WYWxpZGF0ZShDUERGU0RLX1dpZGdldCogcFdpZGdldCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MJiBiUkMsIEZYX0JPT0wmIGJFeGl0LCBGWF9EV09SRCBuRmxhZyk7DQotDQotCXZvaWQJCQkJCQlPbkNhbGN1bGF0ZShDUERGU0RLX1dpZGdldCogcFdpZGdldCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2b2lkCQkJCQkJT25Gb3JtYXQoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKTsNCi0Jdm9pZAkJCQkJCU9uQnV0dG9uVXAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYlJlc2V0LCBGWF9CT09MJiBiRXhpdCxGWF9VSU5UIG5GbGFnKTsNCi0vLyAJc3RhdGljIExSRVNVTFQgQ0FMTEJBQ0sJCUZGTF9XbmRQcm9jKA0KLS8vIAkJCQkJCQkJCSAgaW50IGNvZGUsICAgICAgIC8vIGhvb2sgY29kZQ0KLS8vIAkJCQkJCQkJCSAgV1BBUkFNIHdQYXJhbSwgIC8vIHZpcnR1YWwta2V5IGNvZGUNCi0vLyAJCQkJCQkJCQkgIExQQVJBTSBsUGFyYW0gICAvLyBrZXlzdHJva2UtbWVzc2FnZSBpbmZvcm1hdGlvbg0KLS8vIAkJCQkJCQkJCQkpOw0KLS8vIAlzdGF0aWMgTVNHCQkJCQlHZXRMYXN0TWVzc2FnZSgpOw0KLQlzdGF0aWMgaW50CQkJCQlHZXRDb21taXRLZXkoKTsNCi0Jc3RhdGljIEZYX0JPT0wJCQkJR2V0S2V5RG93bigpOw0KLQ0KLQ0KLXB1YmxpYzoNCi0vLyAJc3RhdGljIE1TRwkJCQkJZ19Nc2c7DQotLy8gCXN0YXRpYyBISE9PSwkJCQltX2hvb2tTaGVldDsNCi0NCi1wcml2YXRlOg0KLQl2b2lkCQkJCQkJVW5SZWdpc3RlckZvcm1GaWxsZXIoQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0Jdm9pZAkJCQkJCVNldEZvY3VzQW5ub3RUYWIoQ1BERlNES19Bbm5vdCogcFdpZGdldCwgRlhfQk9PTCBiU2FtZUZpZWxkLCBGWF9CT09MIGJOZXh0KTsNCi0NCi1wcml2YXRlOg0KLQlDUERGRG9jX0Vudmlyb25tZW50KgkJCQltX3BBcHA7DQotCUNGRkxfV2lkZ2V0MkZpbGxlcgkJCW1fTWFwczsNCi0JRlhfQk9PTAkJCQkJCW1fYk5vdGlmeWluZzsNCi19Ow0KLQ0KLWNsYXNzIENGRkxfUHJpdmF0ZURhdGENCi17DQotcHVibGljOg0KLQlDUERGU0RLX1dpZGdldCoJCQlwV2lkZ2V0Ow0KLQlDUERGU0RLX1BhZ2VWaWV3KglwUGFnZVZpZXc7DQotCWludAkJCQkJbldpZGdldEFnZTsNCi0JaW50CQkJCQluVmFsdWVBZ2U7DQotfTsNCi0NCi0jZW5kaWYgLy9fRkZMX0lGT1JNRklMTEVSX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRkZMX0lGT1JNRklMTEVSX0hfCisjZGVmaW5lIF9GRkxfSUZPUk1GSUxMRVJfSF8KKworI2luY2x1ZGUgIkZvcm1GaWxsZXIuaCIKK2NsYXNzIENGRkxfRm9ybUZpbGxlcjsKK2NsYXNzIENGRkxfUHJpdmF0ZURhdGE7CisKKyNkZWZpbmUgQ0ZGTF9XaWRnZXQyRmlsbGVyCQlDRlhfTWFwUHRyVGVtcGxhdGU8Q1BERlNES19Bbm5vdCosIENGRkxfRm9ybUZpbGxlcio+CisKKy8vICNkZWZpbmUgSXNBTFRwcmVzc2VkKCkJCQkoR2V0S2V5U3RhdGUoVktfTUVOVSkgPCAwKQorLy8gI2RlZmluZSBJc0NUUkxwcmVzc2VkKCkJCQkoR2V0S2V5U3RhdGUoVktfQ09OVFJPTCkgPCAwKQorLy8gI2RlZmluZSBJc1NISUZUcHJlc3NlZCgpCQkoR2V0S2V5U3RhdGUoVktfU0hJRlQpJjB4ODAwMCkKKy8vICNkZWZpbmUgSXNJTlNFUlRwcmVzc2VkKCkJCShHZXRLZXlTdGF0ZShWS19JTlNFUlQpICYgMHgwMSkJCisvLyAjZGVmaW5lIFZLX1NISUZUICAgICAgICAgIDB4MTAKKy8vICNkZWZpbmUgVktfQ09OVFJPTCAgICAgICAgMHgxMQorLy8gI2RlZmluZSBWS19NRU5VICAgICAgICAgICAweDEyCisvLyAjZGVmaW5lIFZLX1JFVFVSTiAgICAgICAgIDB4MEQKKy8vICNkZWZpbmUgVktfU1BBQ0UgICAgICAgICAgMHgyMAorLy8gI2RlZmluZSBWS19FU0NBUEUgICAgICAgICAweDFCCisKKworCitjbGFzcyBDRkZMX0lGb3JtRmlsbGVyIDovKiBwdWJsaWMgSUJBX0Fubm90RmlsbGVyLCAqL3B1YmxpYyBJUFdMX0ZpbGxlcl9Ob3RpZnkvLywgCisvLwlwdWJsaWMgSVVuZG9fRXZlbnRIYW5kbGVyLCBwdWJsaWMgSUNsaXBib2FyZF9IYW5kbGVyCit7CitwdWJsaWM6CisJQ0ZGTF9JRm9ybUZpbGxlcihDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwKTsKKwl2aXJ0dWFsIH5DRkZMX0lGb3JtRmlsbGVyKCk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfSGl0VGVzdChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsQ1BERlNES19Bbm5vdCogcEFubm90LCBDUERGX1BvaW50IHBvaW50KTsKKwl2aXJ0dWFsIEZYX1JFQ1QJCQkJR2V0Vmlld0JCb3goQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCXZpcnR1YWwgdm9pZAkJCQlPbkRyYXcoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCAvKkhEQyBoREMsKi8gQ1BERlNES19Bbm5vdCogcEFubm90LCAKKwkJCQkJCQkJCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkJCQkvKmNvbnN0IENSZWN0JiByY1dpbmRvdywqLyBGWF9EV09SRCBkd0ZsYWdzKTsKKworCisJdmlydHVhbCB2b2lkCQkJCU9uQ3JlYXRlKENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisJdmlydHVhbCB2b2lkCQkJCU9uTG9hZChDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCXZpcnR1YWwgdm9pZAkJCQlPbkRlbGV0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCisJdmlydHVhbCB2b2lkCQkJCU9uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZyk7CisJdmlydHVhbCB2b2lkCQkJCU9uTW91c2VFeGl0KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnKTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbk1vdXNlTW92ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25Nb3VzZVdoZWVsKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uUkJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uUkJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25EYmxDbGsoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuS2V5Q29kZSwgRlhfVUlOVCBuRmxhZ3MpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncyk7CisKKwl2aXJ0dWFsCXZvaWQJCQkJT25EZVNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisJdmlydHVhbAl2b2lkCQkJCU9uU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlPblNldEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCxGWF9VSU5UIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25LaWxsRm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnKTsKKworcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQlRdWVyeVdoZXJlUG9wdXAodm9pZCogcFByaXZhdGVEYXRhLCBGWF9GTE9BVCBmUG9wdXBNaW4sRlhfRkxPQVQgZlBvcHVwTWF4LCBGWF9JTlQzMiAmIG5SZXQsIEZYX0ZMT0FUICYgZlBvcHVwUmV0KTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25CZWZvcmVLZXlTdHJva2UoRlhfQk9PTCBiRWRpdE9yTGlzdCwgdm9pZCogcFByaXZhdGVEYXRhLCBGWF9JTlQzMiBuS2V5Q29kZSwKKwkJCQkJCQkJCQlDRlhfV2lkZVN0cmluZyAmIHN0ckNoYW5nZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LCAKKwkJCQkJCQkJCQlpbnQgblNlbFN0YXJ0LCBpbnQgblNlbEVuZCwKKwkJCQkJCQkJCQlGWF9CT09MIGJLZXlEb3duLCBGWF9CT09MICYgYlJDLCBGWF9CT09MICYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25BZnRlcktleVN0cm9rZShGWF9CT09MIGJFZGl0T3JMaXN0LCB2b2lkKiBwUHJpdmF0ZURhdGEsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpIDsKKworCXZpcnR1YWwgdm9pZAkJCQlPblNldFdpbmRvd1JlY3Qodm9pZCogcFByaXZhdGVEYXRhLCBjb25zdCBDUERGX1JlY3QgJiByY1dpbmRvdyk7CisJdmlydHVhbCB2b2lkCQkJCU9uS2V5U3Ryb2tlKEZYX0JPT0wgYkVkaXRPckxpc3QsIHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfSU5UMzIgbktleUNvZGUsIENGWF9XaWRlU3RyaW5nICYgc3RyQ2hhbmdlLCAKKwkJCQkJCQkJCWNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwgRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCAmIGJSQywgRlhfQk9PTCAmIGJFeGl0KTsKKworcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQlCZWZvcmVVbmRvKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7CisJdmlydHVhbCB2b2lkCQkJCUJlZm9yZVJlZG8oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsKKwl2aXJ0dWFsIHZvaWQJCQkJQWZ0ZXJVbmRvKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7CisJdmlydHVhbCB2b2lkCQkJCUFmdGVyUmVkbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOworCitwdWJsaWM6CisJdmlydHVhbCBGWF9CT09MCQkJCUNhbkNvcHkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgCisJdmlydHVhbCBGWF9CT09MCQkJCUNhbkN1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgCisKKwl2aXJ0dWFsIHZvaWQJCQkJRG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IAorCXZpcnR1YWwgdm9pZAkJCQlEb0N1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwl2aXJ0dWFsIHZvaWQJCQkJRG9QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKworcHVibGljOgorCUNGRkxfRm9ybUZpbGxlcioJCQlHZXRGb3JtRmlsbGVyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfQk9PTCBiUmVnaXN0ZXIpOworCXZvaWQJCQkJCQlSZW1vdmVGb3JtRmlsbGVyKENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisKKwlzdGF0aWMgRlhfQk9PTAkJCQlJc1Zpc2libGUoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpOworCXN0YXRpYyBGWF9CT09MCQkJCUlzUmVhZE9ubHkoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpOworCXN0YXRpYyBGWF9CT09MCQkJCUlzRmlsbGluZ0FsbG93ZWQoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpOworIAlzdGF0aWMgRlhfQk9PTAkJCQlJc1ZhbGlkQW5ub3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCisJdm9pZAkJCQkJCU9uS2V5U3Ryb2tlQ29tbWl0KENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wmIGJSQywgRlhfQk9PTCYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2b2lkCQkJCQkJT25WYWxpZGF0ZShDUERGU0RLX1dpZGdldCogcFdpZGdldCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MJiBiUkMsIEZYX0JPT0wmIGJFeGl0LCBGWF9EV09SRCBuRmxhZyk7CisKKwl2b2lkCQkJCQkJT25DYWxjdWxhdGUoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2b2lkCQkJCQkJT25Gb3JtYXQoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2b2lkCQkJCQkJT25CdXR0b25VcChDUERGU0RLX1dpZGdldCogcFdpZGdldCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MJiBiUmVzZXQsIEZYX0JPT0wmIGJFeGl0LEZYX1VJTlQgbkZsYWcpOworLy8gCXN0YXRpYyBMUkVTVUxUIENBTExCQUNLCQlGRkxfV25kUHJvYygKKy8vIAkJCQkJCQkJCSAgaW50IGNvZGUsICAgICAgIC8vIGhvb2sgY29kZQorLy8gCQkJCQkJCQkJICBXUEFSQU0gd1BhcmFtLCAgLy8gdmlydHVhbC1rZXkgY29kZQorLy8gCQkJCQkJCQkJICBMUEFSQU0gbFBhcmFtICAgLy8ga2V5c3Ryb2tlLW1lc3NhZ2UgaW5mb3JtYXRpb24KKy8vIAkJCQkJCQkJCQkpOworLy8gCXN0YXRpYyBNU0cJCQkJCUdldExhc3RNZXNzYWdlKCk7CisJc3RhdGljIGludAkJCQkJR2V0Q29tbWl0S2V5KCk7CisJc3RhdGljIEZYX0JPT0wJCQkJR2V0S2V5RG93bigpOworCisKK3B1YmxpYzoKKy8vIAlzdGF0aWMgTVNHCQkJCQlnX01zZzsKKy8vIAlzdGF0aWMgSEhPT0sJCQkJbV9ob29rU2hlZXQ7CisKK3ByaXZhdGU6CisJdm9pZAkJCQkJCVVuUmVnaXN0ZXJGb3JtRmlsbGVyKENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisJdm9pZAkJCQkJCVNldEZvY3VzQW5ub3RUYWIoQ1BERlNES19Bbm5vdCogcFdpZGdldCwgRlhfQk9PTCBiU2FtZUZpZWxkLCBGWF9CT09MIGJOZXh0KTsKKworcHJpdmF0ZToKKwlDUERGRG9jX0Vudmlyb25tZW50KgkJCQltX3BBcHA7CisJQ0ZGTF9XaWRnZXQyRmlsbGVyCQkJbV9NYXBzOworCUZYX0JPT0wJCQkJCQltX2JOb3RpZnlpbmc7Cit9OworCitjbGFzcyBDRkZMX1ByaXZhdGVEYXRhCit7CitwdWJsaWM6CisJQ1BERlNES19XaWRnZXQqCQkJcFdpZGdldDsKKwlDUERGU0RLX1BhZ2VWaWV3KglwUGFnZVZpZXc7CisJaW50CQkJCQluV2lkZ2V0QWdlOworCWludAkJCQkJblZhbHVlQWdlOworfTsKKworI2VuZGlmIC8vX0ZGTF9JRk9STUZJTExFUl9IXworCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTGlzdEJveC5oIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0xpc3RCb3guaAppbmRleCA4OTljNDRkLi40M2Y1ZmNlIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTGlzdEJveC5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9MaXN0Qm94LmgKQEAgLTEsNDQgKzEsNDQgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZGTF9MSVNUQk9YX0hfDQotI2RlZmluZSBfRkZMX0xJU1RCT1hfSF8NCi0NCi1jbGFzcyAgQ0JBX0ZvbnRNYXA7DQotY2xhc3MgQ0ZGTF9MaXN0Qm94IDogcHVibGljIENGRkxfRm9ybUZpbGxlcg0KLXsNCi1wdWJsaWM6DQotCUNGRkxfTGlzdEJveChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwV2lkZ2V0KTsNCi0JdmlydHVhbCB+Q0ZGTF9MaXN0Qm94KCk7DQotDQotCXZpcnR1YWwJUFdMX0NSRUFURVBBUkFNCQlHZXRDcmVhdGVQYXJhbSgpOw0KLQl2aXJ0dWFsIENQV0xfV25kKgkJCU5ld1BERldpbmRvdyhjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuQ2hhciwgRlhfVUlOVCBuRmxhZ3MpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNEYXRhQ2hhbmdlZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJU2F2ZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsNCi0NCi0gCXZpcnR1YWwgdm9pZAkJCQlHZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLA0KLSAJCQkJCQkJCQlQREZTREtfRmllbGRBY3Rpb24mIGZhKTsNCi0gCXZpcnR1YWwgdm9pZAkJCQlTZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCANCi0gCQkJCQkJCQkJY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlTYXZlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsNCi0JdmlydHVhbCB2b2lkCQkJCVJlc3RvcmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQ0KLQl2aXJ0dWFsIENQV0xfV25kKgkJCVJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uS2V5U3Ryb2tlKEZYX0JPT0wgYktleURvd24sIEZYX0RXT1JEIG5GbGFnKTsNCi0NCi1wcml2YXRlOg0KLQlDQkFfRm9udE1hcCoJCQkJCW1fcEZvbnRNYXA7DQotCUNGWF9NYXBQdHJUZW1wbGF0ZTxpbnQsIHZvaWQqPgltX09yaWdpblNlbGVjdGlvbnM7DQotCUNGWF9BcnJheVRlbXBsYXRlPGludD4JCQltX1N0YXRlOw0KLX07DQotDQotDQotI2VuZGlmIC8vX0ZGTF9MSVNUQk9YX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRkZMX0xJU1RCT1hfSF8KKyNkZWZpbmUgX0ZGTF9MSVNUQk9YX0hfCisKK2NsYXNzICBDQkFfRm9udE1hcDsKK2NsYXNzIENGRkxfTGlzdEJveCA6IHB1YmxpYyBDRkZMX0Zvcm1GaWxsZXIKK3sKK3B1YmxpYzoKKwlDRkZMX0xpc3RCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19Bbm5vdCogcFdpZGdldCk7CisJdmlydHVhbCB+Q0ZGTF9MaXN0Qm94KCk7CisKKwl2aXJ0dWFsCVBXTF9DUkVBVEVQQVJBTQkJR2V0Q3JlYXRlUGFyYW0oKTsKKwl2aXJ0dWFsIENQV0xfV25kKgkJCU5ld1BERldpbmRvdyhjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCisJdmlydHVhbCBGWF9CT09MCQkJCU9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0RhdGFDaGFuZ2VkKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisJdmlydHVhbCB2b2lkCQkJCVNhdmVEYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisKKyAJdmlydHVhbCB2b2lkCQkJCUdldEFjdGlvbkRhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsCisgCQkJCQkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSk7CisgCXZpcnR1YWwgdm9pZAkJCQlTZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCAKKyAJCQkJCQkJCQljb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhKTsKKworCXZpcnR1YWwgdm9pZAkJCQlTYXZlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKwl2aXJ0dWFsIHZvaWQJCQkJUmVzdG9yZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisKKwl2aXJ0dWFsIENQV0xfV25kKgkJCVJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25LZXlTdHJva2UoRlhfQk9PTCBiS2V5RG93biwgRlhfRFdPUkQgbkZsYWcpOworCitwcml2YXRlOgorCUNCQV9Gb250TWFwKgkJCQkJbV9wRm9udE1hcDsKKwlDRlhfTWFwUHRyVGVtcGxhdGU8aW50LCB2b2lkKj4JbV9PcmlnaW5TZWxlY3Rpb25zOworCUNGWF9BcnJheVRlbXBsYXRlPGludD4JCQltX1N0YXRlOworfTsKKworCisjZW5kaWYgLy9fRkZMX0xJU1RCT1hfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX05vdGlmeS5oIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX05vdGlmeS5oCmluZGV4IDhhMGI3YTMuLmM3MjliNzQgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Ob3RpZnkuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTm90aWZ5LmgKQEAgLTEsNTQgKzEsNTQgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZiAhZGVmaW5lZChfRkZMX05PVElGWV9IXykNCi0jZGVmaW5lIF9GRkxfTk9USUZZX0hfDQotDQotY2xhc3MgQ0ZGTF9Gb3JtRmlsbGVyOw0KLQ0KLWNsYXNzIENGRkxfTm90aWZ5DQotew0KLXB1YmxpYzoNCi0JQ0ZGTF9Ob3RpZnkoQ0ZGTF9Gb3JtRmlsbGVyICogcEZvcm1GaWxsZXIpOwkNCi0JdmlydHVhbCB+Q0ZGTF9Ob3RpZnkoKTsNCi0NCi1wdWJsaWM6DQotCUZYX0JPT0wJCQkJCQkJCQlPblNldEZvY3VzKEZYX0JPT0wgJiBiRXhpdCk7DQotCUZYX0JPT0wJCQkJCQkJCQlPbk1vdXNlRW50ZXIoRlhfQk9PTCAmIGJFeGl0KTsNCi0JRlhfQk9PTAkJCQkJCQkJCU9uTW91c2VEb3duKEZYX0JPT0wgJiBiRXhpdCk7DQotCUZYX0JPT0wJCQkJCQkJCQlPbk1vdXNlVXAoRlhfQk9PTCAmIGJFeGl0KTsJDQotCUZYX0JPT0wJCQkJCQkJCQlPbk1vdXNlRXhpdChGWF9CT09MICYgYkV4aXQpOwkNCi0JRlhfQk9PTAkJCQkJCQkJCU9uS2lsbEZvY3VzKEZYX0JPT0wgJiBiRXhpdCk7DQotDQotCUZYX0JPT0wJCQkJCQkJCQlPbkNhbGN1bGF0ZSgpOw0KLQlGWF9CT09MCQkJCQkJCQkJT25Gb3JtYXQoaW50IGlDb21taXRLZXkpOw0KLQlGWF9CT09MCQkJCQkJCQkJT25WYWxpZGF0ZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIHN0clZhbHVlLCBDRlhfV2lkZVN0cmluZyAmIHN0ckNoYW5nZSwgDQotCQkJCQkJCQkJCQkgICBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIEZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLA0KLQkJCQkJCQkJCQkJICAgRlhfQk9PTCBiU2hpZnQsIEZYX0JPT0wgJiBiUkMpOw0KLQlGWF9CT09MCQkJCQkJCQkJT25LZXlTdHJva2UoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIGludCBuQ29tbWl0S2V5LCBDRlhfV2lkZVN0cmluZyYgc3RyVmFsdWUsIENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsIA0KLQkJCQkJCQkJCQkJICAgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LCBGWF9CT09MIGJLZXlEb3duLCBGWF9CT09MIGJNb2RpZmllciwNCi0JCQkJCQkJCQkJCSAgIEZYX0JPT0wgYlNoaWZ0LCBGWF9CT09MIGJXaWxsQ29tbWl0LCBGWF9CT09MIGJGaWVsZEZ1bGwsIA0KLQkJCQkJCQkJCQkJICAgaW50JiBuU2VsU3RhcnQsIGludCYgblNlbEVuZCwgRlhfQk9PTCYgYlJDKTsNCi0NCi0Jdm9pZAkJCQkJCQkJCUJlZm9yZU5vdGlmeSgpOw0KLQl2b2lkCQkJCQkJCQkJQWZ0ZXJOb3RpZnkoKTsNCi0JRlhfQk9PTAkJCQkJCQkJCUlzTm90aWZ5aW5nKCkgY29uc3Qge3JldHVybiBtX25Ob3RpZnlGbGFnID4gMDt9DQotDQotcHJpdmF0ZToNCi0vLwlDUmVhZGVyX0ludGVyRm9ybSAqCQkJCQkJR2V0UmVhZGVySW50ZXJGb3JtKCk7DQotIAlGWF9CT09MCQkJCQkJCQkJRG9BQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCwgRlhfQk9PTCAmIGJFeGl0KTsNCi0gCUZYX0JPT0wJCQkJCQkJCQlGaW5kQUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQsQ1BERl9BY3Rpb24gJiBhY3Rpb24pOw0KLSAJRlhfQk9PTAkJCQkJCQkJCUZpbmRBQWN0aW9uKENQREZfQUFjdGlvbiBhYWN0aW9uLENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCxDUERGX0FjdGlvbiAmIGFjdGlvbik7DQotIAlGWF9CT09MCQkJCQkJCQkJRXhlY3V0ZUFjdGlvblRyZWUoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlQUFULCBDUERGX0FjdGlvbiAmIGFjdGlvbiwgRlhfQk9PTCYgYkV4aXQpOw0KLSAJRlhfQk9PTAkJCQkJCQkJCUV4ZWN1dGVBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlQUFULENQREZfQWN0aW9uICYgYWN0aW9uLEZYX0JPT0wmIGJFeGl0KTsNCi0NCi0JQ0ZGTF9Gb3JtRmlsbGVyICoJCQkJCQltX3BGb3JtRmlsbGVyOw0KLQlGWF9CT09MCQkJCQkJCQkJbV9iRG9BY3Rpb25pbmc7DQotCUZYX0lOVDMyCQkJCQkJCQltX25Ob3RpZnlGbGFnOw0KLX07DQotDQotI2VuZGlmDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmICFkZWZpbmVkKF9GRkxfTk9USUZZX0hfKQorI2RlZmluZSBfRkZMX05PVElGWV9IXworCitjbGFzcyBDRkZMX0Zvcm1GaWxsZXI7CisKK2NsYXNzIENGRkxfTm90aWZ5Cit7CitwdWJsaWM6CisJQ0ZGTF9Ob3RpZnkoQ0ZGTF9Gb3JtRmlsbGVyICogcEZvcm1GaWxsZXIpOwkKKwl2aXJ0dWFsIH5DRkZMX05vdGlmeSgpOworCitwdWJsaWM6CisJRlhfQk9PTAkJCQkJCQkJCU9uU2V0Rm9jdXMoRlhfQk9PTCAmIGJFeGl0KTsKKwlGWF9CT09MCQkJCQkJCQkJT25Nb3VzZUVudGVyKEZYX0JPT0wgJiBiRXhpdCk7CisJRlhfQk9PTAkJCQkJCQkJCU9uTW91c2VEb3duKEZYX0JPT0wgJiBiRXhpdCk7CisJRlhfQk9PTAkJCQkJCQkJCU9uTW91c2VVcChGWF9CT09MICYgYkV4aXQpOwkKKwlGWF9CT09MCQkJCQkJCQkJT25Nb3VzZUV4aXQoRlhfQk9PTCAmIGJFeGl0KTsJCisJRlhfQk9PTAkJCQkJCQkJCU9uS2lsbEZvY3VzKEZYX0JPT0wgJiBiRXhpdCk7CisKKwlGWF9CT09MCQkJCQkJCQkJT25DYWxjdWxhdGUoKTsKKwlGWF9CT09MCQkJCQkJCQkJT25Gb3JtYXQoaW50IGlDb21taXRLZXkpOworCUZYX0JPT0wJCQkJCQkJCQlPblZhbGlkYXRlKENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCBDRlhfV2lkZVN0cmluZyYgc3RyVmFsdWUsIENGWF9XaWRlU3RyaW5nICYgc3RyQ2hhbmdlLCAKKwkJCQkJCQkJCQkJICAgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LCBGWF9CT09MIGJLZXlEb3duLCBGWF9CT09MIGJNb2RpZmllciwKKwkJCQkJCQkJCQkJICAgRlhfQk9PTCBiU2hpZnQsIEZYX0JPT0wgJiBiUkMpOworCUZYX0JPT0wJCQkJCQkJCQlPbktleVN0cm9rZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgaW50IG5Db21taXRLZXksIENGWF9XaWRlU3RyaW5nJiBzdHJWYWx1ZSwgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZSwgCisJCQkJCQkJCQkJCSAgIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwgRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCBiTW9kaWZpZXIsCisJCQkJCQkJCQkJCSAgIEZYX0JPT0wgYlNoaWZ0LCBGWF9CT09MIGJXaWxsQ29tbWl0LCBGWF9CT09MIGJGaWVsZEZ1bGwsIAorCQkJCQkJCQkJCQkgICBpbnQmIG5TZWxTdGFydCwgaW50JiBuU2VsRW5kLCBGWF9CT09MJiBiUkMpOworCisJdm9pZAkJCQkJCQkJCUJlZm9yZU5vdGlmeSgpOworCXZvaWQJCQkJCQkJCQlBZnRlck5vdGlmeSgpOworCUZYX0JPT0wJCQkJCQkJCQlJc05vdGlmeWluZygpIGNvbnN0IHtyZXR1cm4gbV9uTm90aWZ5RmxhZyA+IDA7fQorCitwcml2YXRlOgorLy8JQ1JlYWRlcl9JbnRlckZvcm0gKgkJCQkJCUdldFJlYWRlckludGVyRm9ybSgpOworIAlGWF9CT09MCQkJCQkJCQkJRG9BQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCwgRlhfQk9PTCAmIGJFeGl0KTsKKyAJRlhfQk9PTAkJCQkJCQkJCUZpbmRBQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCxDUERGX0FjdGlvbiAmIGFjdGlvbik7CisgCUZYX0JPT0wJCQkJCQkJCQlGaW5kQUFjdGlvbihDUERGX0FBY3Rpb24gYWFjdGlvbixDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQsQ1BERl9BY3Rpb24gJiBhY3Rpb24pOworIAlGWF9CT09MCQkJCQkJCQkJRXhlY3V0ZUFjdGlvblRyZWUoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlQUFULCBDUERGX0FjdGlvbiAmIGFjdGlvbiwgRlhfQk9PTCYgYkV4aXQpOworIAlGWF9CT09MCQkJCQkJCQkJRXhlY3V0ZUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQsQ1BERl9BY3Rpb24gJiBhY3Rpb24sRlhfQk9PTCYgYkV4aXQpOworCisJQ0ZGTF9Gb3JtRmlsbGVyICoJCQkJCQltX3BGb3JtRmlsbGVyOworCUZYX0JPT0wJCQkJCQkJCQltX2JEb0FjdGlvbmluZzsKKwlGWF9JTlQzMgkJCQkJCQkJbV9uTm90aWZ5RmxhZzsKK307CisKKyNlbmRpZgorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfUHVzaEJ1dHRvbi5oIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1B1c2hCdXR0b24uaAppbmRleCA0ZGNmZjE0Li5iZTVlNzM1IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfUHVzaEJ1dHRvbi5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9QdXNoQnV0dG9uLmgKQEAgLTEsMjUgKzEsMjUgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZGTF9QVVNIQlVUVE9OX0hfDQotI2RlZmluZSBfRkZMX1BVU0hCVVRUT05fSF8NCi0NCi1jbGFzcyBDRkZMX1B1c2hCdXR0b24gOiBwdWJsaWMgQ0ZGTF9CdXR0b24NCi17DQotcHVibGljOg0KLQlDRkZMX1B1c2hCdXR0b24oQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0JdmlydHVhbCB+Q0ZGTF9QdXNoQnV0dG9uKCk7DQotDQotCXZpcnR1YWwgQ1BXTF9XbmQqCQkJTmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncyk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRyYXcoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCAgQ1BERlNES19Bbm5vdCogcEFubm90LCANCi0JCQkJCQkJCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJCQkJCQkJCUZYX0RXT1JEIGR3RmxhZ3MpOw0KLX07DQotDQotI2VuZGlmIC8vX0ZGTF9QVVNIQlVUVE9OX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRkZMX1BVU0hCVVRUT05fSF8KKyNkZWZpbmUgX0ZGTF9QVVNIQlVUVE9OX0hfCisKK2NsYXNzIENGRkxfUHVzaEJ1dHRvbiA6IHB1YmxpYyBDRkZMX0J1dHRvbgoreworcHVibGljOgorCUNGRkxfUHVzaEJ1dHRvbihDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCXZpcnR1YWwgfkNGRkxfUHVzaEJ1dHRvbigpOworCisJdmlydHVhbCBDUFdMX1duZCoJCQlOZXdQREZXaW5kb3coY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncyk7CisJdmlydHVhbCB2b2lkCQkJCU9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsICBDUERGU0RLX0Fubm90KiBwQW5ub3QsIAorCQkJCQkJCQkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQkJCUZYX0RXT1JEIGR3RmxhZ3MpOworfTsKKworI2VuZGlmIC8vX0ZGTF9QVVNIQlVUVE9OX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9SYWRpb0J1dHRvbi5oIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1JhZGlvQnV0dG9uLmgKaW5kZXggYmFiODU4NC4uMDM3ZTU2MyAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1JhZGlvQnV0dG9uLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1JhZGlvQnV0dG9uLmgKQEAgLTEsMjUgKzEsMjUgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZGTF9SQURJT0JVVFRPTl9IXw0KLSNkZWZpbmUgX0ZGTF9SQURJT0JVVFRPTl9IXw0KLQ0KLWNsYXNzIENGRkxfUmFkaW9CdXR0b24gOiBwdWJsaWMgQ0ZGTF9CdXR0b24NCi17DQotcHVibGljOg0KLQlDRkZMX1JhZGlvQnV0dG9uKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotCXZpcnR1YWwgfkNGRkxfUmFkaW9CdXR0b24oKTsNCi0JDQotCXZpcnR1YWwgQ1BXTF9XbmQqCQkJTmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotICAJdmlydHVhbCBGWF9CT09MCQkJCU9uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbktleUNvZGUsIEZYX1VJTlQgbkZsYWdzKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNEYXRhQ2hhbmdlZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJU2F2ZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsNCi19Ow0KLQ0KLSNlbmRpZiAvL19GRkxfUkFESU9CVVRUT05fSF8NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GRkxfUkFESU9CVVRUT05fSF8KKyNkZWZpbmUgX0ZGTF9SQURJT0JVVFRPTl9IXworCitjbGFzcyBDRkZMX1JhZGlvQnV0dG9uIDogcHVibGljIENGRkxfQnV0dG9uCit7CitwdWJsaWM6CisJQ0ZGTF9SYWRpb0J1dHRvbihDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCXZpcnR1YWwgfkNGRkxfUmFkaW9CdXR0b24oKTsKKwkKKwl2aXJ0dWFsIENQV0xfV25kKgkJCU5ld1BERldpbmRvdyhjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworICAJdmlydHVhbCBGWF9CT09MCQkJCU9uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbktleUNvZGUsIEZYX1VJTlQgbkZsYWdzKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuQ2hhciwgRlhfVUlOVCBuRmxhZ3MpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNEYXRhQ2hhbmdlZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCXZpcnR1YWwgdm9pZAkJCQlTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworfTsKKworI2VuZGlmIC8vX0ZGTF9SQURJT0JVVFRPTl9IXworCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfVGV4dEZpZWxkLmggYi9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfVGV4dEZpZWxkLmgKaW5kZXggMmI2ZjA2OS4uZDI4MDhlOSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1RleHRGaWVsZC5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9UZXh0RmllbGQuaApAQCAtMSw4OSArMSw4OSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmICFkZWZpbmVkKEFGWF9GRkxfRURJVF9IX184RTBDOTQ1Nl9DQkEyXzRFRkJfOUYzMV81M0M2RDhDMUE4QUNfX0lOQ0xVREVEXykNCi0jZGVmaW5lIEFGWF9GRkxfRURJVF9IX184RTBDOTQ1Nl9DQkEyXzRFRkJfOUYzMV81M0M2RDhDMUE4QUNfX0lOQ0xVREVEXw0KLQ0KLSNpbmNsdWRlICJGRkxfRm9ybUZpbGxlci5oIg0KLQ0KLSNkZWZpbmUgQkZfQUxJR05fTEVGVAkJCTANCi0jZGVmaW5lIEJGX0FMSUdOX01JRERMRQkJCTENCi0jZGVmaW5lIEJGX0FMSUdOX1JJR0hUCQkJMg0KLQ0KLWNsYXNzIENCQV9Gb250TWFwOw0KLQ0KLWNsYXNzIENGRkxfRWRpdFVuZG9JdGVtIC8vOiBwdWJsaWMgSVVuZG9JdGVtDQotew0KLXB1YmxpYzoNCi0JQ0ZGTF9FZGl0VW5kb0l0ZW0oQ1BXTF9FZGl0KiBwRWRpdCk7DQotCXZpcnR1YWwgfkNGRkxfRWRpdFVuZG9JdGVtKCk7DQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCVVuZG8oKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlSZWRvKCk7DQotCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCQlHZXREZXNjcigpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVJlbGVhc2UoKTsNCi0JDQotcHJpdmF0ZToNCi0JQ1BXTF9FZGl0KgkJCQkJCW1fcEVkaXQ7DQotfTsNCi0NCi1zdHJ1Y3QgRkZMX1RleHRGaWVsZFN0YXRlDQotew0KLQlpbnQgblN0YXJ0Ow0KLQlpbnQgbkVuZDsNCi0JQ0ZYX1dpZGVTdHJpbmcgc1ZhbHVlOw0KLX07DQotDQotY2xhc3MgQ0ZGTF9UZXh0RmllbGQgOiBwdWJsaWMgQ0ZGTF9Gb3JtRmlsbGVyLCBwdWJsaWMgSVBXTF9Gb2N1c0hhbmRsZXIsIHB1YmxpYyBJUFdMX0VkaXRfTm90aWZ5DQotew0KLXB1YmxpYzoNCi0JQ0ZGTF9UZXh0RmllbGQoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0JdmlydHVhbCB+Q0ZGTF9UZXh0RmllbGQoKTsNCi0JDQotCXZpcnR1YWwJUFdMX0NSRUFURVBBUkFNCQlHZXRDcmVhdGVQYXJhbSgpOw0KLQl2aXJ0dWFsIENQV0xfV25kKgkJCU5ld1BERldpbmRvdyhjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQ0KLQkNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKTsNCi0JDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0RhdGFDaGFuZ2VkKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotCXZpcnR1YWwgdm9pZAkJCQlTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQkNCi0gCXZpcnR1YWwgdm9pZAkJCQlHZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLA0KLSAJCQkJCQkJCQkJCQlQREZTREtfRmllbGRBY3Rpb24mIGZhKTsNCi0gCXZpcnR1YWwgdm9pZAkJCQlTZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCANCi0JCQkJCQkJCQljb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhKTsNCi0gCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0FjdGlvbkRhdGFDaGFuZ2VkKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU9sZCwgDQotIAkJCQkJCQkJCQkJCWNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmFOZXcpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJU2F2ZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotCXZpcnR1YWwgdm9pZAkJCQlSZXN0b3JlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsNCi0JDQotCXZpcnR1YWwgQ1BXTF9XbmQqCQkJUmVzZXRQREZXaW5kb3coQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MIGJSZXN0b3JlVmFsdWUpOw0KLQkNCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQlPblNldEZvY3VzKENQV0xfV25kKiBwV25kKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uS2lsbEZvY3VzKENQV0xfV25kKiBwV25kKTsNCi0JDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJT25BZGRVbmRvKENQV0xfRWRpdCogcEVkaXQpOw0KLQkNCi1wdWJsaWM6DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlDYW5Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgDQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJRG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQl2aXJ0dWFsIHZvaWQJCQkJRG9DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgDQotCXZpcnR1YWwgdm9pZAkJCQlEb1Bhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7IA0KLQkNCi1wcml2YXRlOg0KLQlDQkFfRm9udE1hcCoJCQkJbV9wRm9udE1hcDsNCi0vLwlDQkFfU3BlbGxDaGVjayoJCQkJbV9wU3BlbGxDaGVjazsNCi0JRkZMX1RleHRGaWVsZFN0YXRlCQkJbV9TdGF0ZTsNCi0vLwlDRkZMX0lNX0JPWAkJCQkJbV9JTUJveDsNCi19Ow0KLQ0KLSNlbmRpZiAvLyAhZGVmaW5lZChBRlhfRkZMX0VESVRfSF9fOEUwQzk0NTZfQ0JBMl80RUZCXzlGMzFfNTNDNkQ4QzFBOEFDX19JTkNMVURFRF8pDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmICFkZWZpbmVkKEFGWF9GRkxfRURJVF9IX184RTBDOTQ1Nl9DQkEyXzRFRkJfOUYzMV81M0M2RDhDMUE4QUNfX0lOQ0xVREVEXykKKyNkZWZpbmUgQUZYX0ZGTF9FRElUX0hfXzhFMEM5NDU2X0NCQTJfNEVGQl85RjMxXzUzQzZEOEMxQThBQ19fSU5DTFVERURfCisKKyNpbmNsdWRlICJGRkxfRm9ybUZpbGxlci5oIgorCisjZGVmaW5lIEJGX0FMSUdOX0xFRlQJCQkwCisjZGVmaW5lIEJGX0FMSUdOX01JRERMRQkJCTEKKyNkZWZpbmUgQkZfQUxJR05fUklHSFQJCQkyCisKK2NsYXNzIENCQV9Gb250TWFwOworCitjbGFzcyBDRkZMX0VkaXRVbmRvSXRlbSAvLzogcHVibGljIElVbmRvSXRlbQoreworcHVibGljOgorCUNGRkxfRWRpdFVuZG9JdGVtKENQV0xfRWRpdCogcEVkaXQpOworCXZpcnR1YWwgfkNGRkxfRWRpdFVuZG9JdGVtKCk7CisJCisJdmlydHVhbCB2b2lkCQkJCQlVbmRvKCk7CisJdmlydHVhbCB2b2lkCQkJCQlSZWRvKCk7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCUdldERlc2NyKCk7CisJdmlydHVhbCB2b2lkCQkJCQlSZWxlYXNlKCk7CisJCitwcml2YXRlOgorCUNQV0xfRWRpdCoJCQkJCQltX3BFZGl0OworfTsKKworc3RydWN0IEZGTF9UZXh0RmllbGRTdGF0ZQoreworCWludCBuU3RhcnQ7CisJaW50IG5FbmQ7CisJQ0ZYX1dpZGVTdHJpbmcgc1ZhbHVlOworfTsKKworY2xhc3MgQ0ZGTF9UZXh0RmllbGQgOiBwdWJsaWMgQ0ZGTF9Gb3JtRmlsbGVyLCBwdWJsaWMgSVBXTF9Gb2N1c0hhbmRsZXIsIHB1YmxpYyBJUFdMX0VkaXRfTm90aWZ5Cit7CitwdWJsaWM6CisJQ0ZGTF9UZXh0RmllbGQoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19Bbm5vdCogcEFubm90KTsKKwl2aXJ0dWFsIH5DRkZMX1RleHRGaWVsZCgpOworCQorCXZpcnR1YWwJUFdMX0NSRUFURVBBUkFNCQlHZXRDcmVhdGVQYXJhbSgpOworCXZpcnR1YWwgQ1BXTF9XbmQqCQkJTmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisKKwkKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuQ2hhciwgRlhfVUlOVCBuRmxhZ3MpOworCQorCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0RhdGFDaGFuZ2VkKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisJdmlydHVhbCB2b2lkCQkJCVNhdmVEYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisJCisgCXZpcnR1YWwgdm9pZAkJCQlHZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLAorIAkJCQkJCQkJCQkJCVBERlNES19GaWVsZEFjdGlvbiYgZmEpOworIAl2aXJ0dWFsIHZvaWQJCQkJU2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgCisJCQkJCQkJCQljb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhKTsKKyAJdmlydHVhbCBGWF9CT09MCQkJCUlzQWN0aW9uRGF0YUNoYW5nZWQoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBjb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhT2xkLCAKKyAJCQkJCQkJCQkJCQljb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhTmV3KTsKKwl2aXJ0dWFsIHZvaWQJCQkJU2F2ZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisJdmlydHVhbCB2b2lkCQkJCVJlc3RvcmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCQorCXZpcnR1YWwgQ1BXTF9XbmQqCQkJUmVzZXRQREZXaW5kb3coQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MIGJSZXN0b3JlVmFsdWUpOworCQorcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQlPblNldEZvY3VzKENQV0xfV25kKiBwV25kKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25LaWxsRm9jdXMoQ1BXTF9XbmQqIHBXbmQpOworCQorcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQlPbkFkZFVuZG8oQ1BXTF9FZGl0KiBwRWRpdCk7CisJCitwdWJsaWM6CisJdmlydHVhbCBGWF9CT09MCQkJCUNhbkNvcHkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgCisJdmlydHVhbCBGWF9CT09MCQkJCUNhbkN1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgCisJCisJdmlydHVhbCB2b2lkCQkJCURvQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOyAKKwl2aXJ0dWFsIHZvaWQJCQkJRG9DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgCisJdmlydHVhbCB2b2lkCQkJCURvUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsgCisJCitwcml2YXRlOgorCUNCQV9Gb250TWFwKgkJCQltX3BGb250TWFwOworLy8JQ0JBX1NwZWxsQ2hlY2sqCQkJCW1fcFNwZWxsQ2hlY2s7CisJRkZMX1RleHRGaWVsZFN0YXRlCQkJbV9TdGF0ZTsKKy8vCUNGRkxfSU1fQk9YCQkJCQltX0lNQm94OworfTsKKworI2VuZGlmIC8vICFkZWZpbmVkKEFGWF9GRkxfRURJVF9IX184RTBDOTQ1Nl9DQkEyXzRFRkJfOUYzMV81M0M2RDhDMUE4QUNfX0lOQ0xVREVEXykKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9VdGlscy5oIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1V0aWxzLmgKaW5kZXggMDdmMmJlZS4uMmZkYzdiMSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1V0aWxzLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1V0aWxzLmgKQEAgLTEsMjAgKzEsMjAgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNkZWZpbmUgRkZMX0JBU0VfVVNFUlVOSVQJCQkxLjBmIC8gNzIuMGYNCi0NCi10ZW1wbGF0ZTxjbGFzcyBUPiBUIEZGTF9NSU4gKGNvbnN0IFQgJiBpLCBjb25zdCBUICYgaikgeyByZXR1cm4gKChpIDwgaikgPyBpIDogaik7IH0NCi10ZW1wbGF0ZTxjbGFzcyBUPiBUIEZGTF9NQVggKGNvbnN0IFQgJiBpLCBjb25zdCBUICYgaikgeyByZXR1cm4gKChpID4gaikgPyBpIDogaik7IH0NCi0NCi1jbGFzcyBDRkZMX1V0aWxzDQotew0KLXB1YmxpYzoNCi0Jc3RhdGljIENQREZfUmVjdAkJCQlNYXhSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QxLGNvbnN0IENQREZfUmVjdCAmIHJlY3QyKTsNCi0Jc3RhdGljIENQREZfUmVjdAkJCQlJbmZsYXRlUmVjdChjb25zdCBDUERGX1JlY3QgJiBjclJlY3QsIGNvbnN0IEZYX0ZMT0FUICYgZlNpemUpOw0KLQlzdGF0aWMgQ1BERl9SZWN0CQkJCURlZmxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIGNyUmVjdCwgY29uc3QgRlhfRkxPQVQgJiBmU2l6ZSk7DQotCXN0YXRpYyBGWF9CT09MCQkJCQlUcmFjZU9iamVjdChDUERGX09iamVjdCogcE9iaik7DQotfTsNCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjZGVmaW5lIEZGTF9CQVNFX1VTRVJVTklUCQkJMS4wZiAvIDcyLjBmCisKK3RlbXBsYXRlPGNsYXNzIFQ+IFQgRkZMX01JTiAoY29uc3QgVCAmIGksIGNvbnN0IFQgJiBqKSB7IHJldHVybiAoKGkgPCBqKSA/IGkgOiBqKTsgfQordGVtcGxhdGU8Y2xhc3MgVD4gVCBGRkxfTUFYIChjb25zdCBUICYgaSwgY29uc3QgVCAmIGopIHsgcmV0dXJuICgoaSA+IGopID8gaSA6IGopOyB9CisKK2NsYXNzIENGRkxfVXRpbHMKK3sKK3B1YmxpYzoKKwlzdGF0aWMgQ1BERl9SZWN0CQkJCU1heFJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdDEsY29uc3QgQ1BERl9SZWN0ICYgcmVjdDIpOworCXN0YXRpYyBDUERGX1JlY3QJCQkJSW5mbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgY3JSZWN0LCBjb25zdCBGWF9GTE9BVCAmIGZTaXplKTsKKwlzdGF0aWMgQ1BERl9SZWN0CQkJCURlZmxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIGNyUmVjdCwgY29uc3QgRlhfRkxPQVQgJiBmU2l6ZSk7CisJc3RhdGljIEZYX0JPT0wJCQkJCVRyYWNlT2JqZWN0KENQREZfT2JqZWN0KiBwT2JqKTsKK307CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaAppbmRleCBlN2EyMmEwLi44ZTQ1ZDVlIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZm9ybWZpbGxlci9Gb3JtRmlsbGVyLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2Zvcm1maWxsZXIvRm9ybUZpbGxlci5oCkBAIC0xLDMwICsxLDMwIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GT1JNRklMTEVSX0hfDQotI2RlZmluZSBfRk9STUZJTExFUl9IXw0KLQ0KLQ0KLQ0KLSNpZm5kZWYgX0lOQ19QREZBUEkNCi0JI2RlZmluZSBfSU5DX1BERkFQSQ0KLQ0KLQkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9tb2R1bGUuaCIgDQotCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmRvYy9mcGRmX2RvYy5oIiANCi0JI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmZG9jL2ZwZGZfdnQuaCIgDQotCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnhjcnQvZnhfeG1sLmgiIA0KLQ0KLSNlbmRpZg0KLQ0KLSNpbmNsdWRlICIuLi9mc2RrX21nci5oIg0KLQ0KLSNpbmNsdWRlICIuLi9meGVkaXQvZnhfZWRpdC5oIg0KLSNpbmNsdWRlICIuLi9wZGZ3aW5kb3cvSVBERldpbmRvdy5oIg0KLQ0KLQ0KLQ0KLSNlbmRpZiAvL19GT1JNRklMTEVSX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRk9STUZJTExFUl9IXworI2RlZmluZSBfRk9STUZJTExFUl9IXworCisKKworI2lmbmRlZiBfSU5DX1BERkFQSQorCSNkZWZpbmUgX0lOQ19QREZBUEkKKworCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX21vZHVsZS5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl9kb2MuaCIgCisJI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmZG9jL2ZwZGZfdnQuaCIgCisJI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9meGNydC9meF94bWwuaCIgCisKKyNlbmRpZgorCisjaW5jbHVkZSAiLi4vZnNka19tZ3IuaCIKKworI2luY2x1ZGUgIi4uL2Z4ZWRpdC9meF9lZGl0LmgiCisjaW5jbHVkZSAiLi4vcGRmd2luZG93L0lQREZXaW5kb3cuaCIKKworCisKKyNlbmRpZiAvL19GT1JNRklMTEVSX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmX2RhdGFhdmFpbC5oIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZGF0YWF2YWlsLmgKaW5kZXggOWQzNzNmYy4uOTcxYWIyNSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZGF0YWF2YWlsLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZGF0YWF2YWlsLmgKQEAgLTEsMjIyICsxLDIyMiBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfRlBERl9EQVRBQVZBSUxfSF8NCi0jZGVmaW5lIF9GUERGX0RBVEFBVkFJTF9IXw0KLQ0KLSNpZm5kZWYgX0ZQREZWSUVXX0hfDQotI2luY2x1ZGUgImZwZGZ2aWV3LmgiDQotI2VuZGlmDQotDQotDQotLyoqIFRoZSByZXN1bHQgb2YgdGhlIHByb2Nlc3Mgd2hpY2ggY2hlY2sgbGluZWFyaXplZCBQREYuICovDQotI2RlZmluZSBGU0RLX0lTX0xJTkVBUklaRUQJCQkxDQotI2RlZmluZSBGU0RLX05PVF9MSU5FQVJJWkVECQkJMA0KLSNkZWZpbmUgRlNES19VTktOT1dfTElORUFSSVpFRAkJLTENCi0NCi0NCi0jaWZkZWYgX19jcGx1c3BsdXMNCi1leHRlcm4gIkMiIHsNCi0jZW5kaWYNCi0NCi0vKioNCi0gKiBJbnRlcmZhY2U6IEZYX0ZJTEVBVkFJTA0KLSAqCQkJSW50ZXJmYWNlIGZvciBjaGVja2luZyB3aGV0aGVyIHRoZSBzZWN0aW9uIG9mIHRoZSBmaWxlIGlzIGF2YWlsYWJsZS4gDQotICovDQotdHlwZWRlZiBzdHJ1Y3QgX0ZYX0ZJTEVBVkFJTCB7DQotCS8qKg0KLQkgKiBWZXJzaW9uIG51bWJlciBvZiB0aGUgaW50ZXJmYWNlLiBDdXJyZW50bHkgbXVzdCBiZSAxLg0KLQkgKi8NCi0JaW50IHZlcnNpb247DQotDQotCS8qKg0KLQkgKiBNZXRob2Q6IElzRGF0YUF2YWlsDQotCSAqCQlSZXBvcnQgd2hldGhlciB0aGUgc3BlY2lmaWVkIGRhdGEgc2VjdGlvbiBpcyBhdmFpbGFibGUuIEEgc2VjdGlvbiBpcyBhdmFpbGFibGUgb25seSBpZiBhbGwgYnl0ZXMgaW4gdGhlIHNlY3Rpb24gaXMgYXZhaWxhYmxlLiANCi0JICogSW50ZXJmYWNlIFZlcnNpb246DQotCSAqCQkxDQotCSAqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOg0KLQkgKgkJWWVzDQotCSAqIFBhcmFtZXRlcnM6DQotCSAqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4NCi0JICoJCW9mZnNldAkJLQlUaGUgb2Zmc2V0IG9mIHRoZSBkYXRhIHNlY3Rpb24gaW4gdGhlIGZpbGUuDQotCSAqCQlzaXplCQktCVRoZSBzaXplIG9mIHRoZSBkYXRhIHNlY3Rpb24NCi0JICogUmV0dXJuIFZhbHVlOg0KLQkgKgkJdHJ1ZSBtZWFucyB0aGUgc3BlY2lmaWVkIGRhdGEgc2VjdGlvbiBpcyBhdmFpbGFibGUuDQotCSAqIENvbW1lbnRzOg0KLQkgKgkJQ2FsbGVkIGJ5IEZveGl0IFNESyB0byBjaGVjayB3aGV0aGVyIHRoZSBkYXRhIHNlY3Rpb24gaXMgcmVhZHkuDQotCSAqLw0KLQlib29sICgqSXNEYXRhQXZhaWwpKHN0cnVjdCBfRlhfRklMRUFWQUlMKiBwVGhpcywgc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpOw0KLX0gRlhfRklMRUFWQUlMOw0KLQ0KLXR5cGVkZWYgdm9pZCogRlBERl9BVkFJTDsNCi0NCi0vKioNCi0qIEZ1bmN0aW9uOiBGUERGQXZhaWxfQ3JlYXRlDQotKgkJCUNyZWF0ZSBhIGRvY3VtZW50IGF2YWlsYWJpbGl0eSBwcm92aWRlci4NCi0qDQotKiBQYXJhbWV0ZXJzOiANCi0qCQkJZmlsZV9hdmFpbAktCVBvaW50ZXIgdG8gZmlsZSBhdmFpbGFiaWxpdHkgaW50ZXJmYWNlIHRvIGNoZWNrIGF2YWlsYWJpbGl0eSBvZiBmaWxlIGRhdGEuDQotKgkJCWZpbGUJCS0JUG9pbnRlciB0byBhIGZpbGUgYWNjZXNzIGludGVyZmFjZSBmb3IgcmVhZGluZyBkYXRhIGZyb20gZmlsZS4NCi0qIFJldHVybiB2YWx1ZToNCi0qCQkJQSBoYW5kbGUgdG8gdGhlIGRvY3VtZW50IGF2YWlsYWJpbGl0eSBwcm92aWRlci4gTlVMTCBmb3IgZXJyb3IuDQotKiBDb21tZW50czoNCi0qCQkJQXBwbGljYXRpb24gbXVzdCBjYWxsIEZQREZBdmFpbF9EZXN0cm95IHdoZW4gZG9uZSB3aXRoIHRoZSBhdmFpbGFiaWxpdHkgcHJvdmlkZXIuDQotKi8NCi1ETExFWFBPUlQgRlBERl9BVkFJTCBTVERDQUxMIEZQREZBdmFpbF9DcmVhdGUoRlhfRklMRUFWQUlMKiBmaWxlX2F2YWlsLCBGUERGX0ZJTEVBQ0NFU1MqIGZpbGUpOw0KLQ0KLS8qKg0KLSogRnVuY3Rpb246IEZQREZBdmFpbF9EZXN0cm95DQotKgkJCURlc3Ryb3kgYSBkb2N1bWVudCBhdmFpbGliaXR5IHByb3ZpZGVyLg0KLSoNCi0qIFBhcmFtZXRlcnM6IA0KLSoJCQlhdmFpbAkJLQlIYW5kbGUgdG8gZG9jdW1lbnQgYXZhaWxhYmlsaXR5IHByb3ZpZGVyIHJldHVybmVkIGJ5IEZQREZBdmFpbF9DcmVhdGUNCi0qIFJldHVybiBWYWx1ZToNCi0qCQkJTm9uZS4NCi0qLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkF2YWlsX0Rlc3Ryb3koRlBERl9BVkFJTCBhdmFpbCk7DQotDQotLyoqDQotICogSW50ZXJmYWNlOiBGWF9ET1dOTE9BREhJTlRTDQotICoJCQlEb3dubG9hZCBoaW50cyBpbnRlcmZhY2UuIFVzZWQgdG8gcmVjZWl2ZSBoaW50cyBmb3IgZnVydGhlciBkb3dubG9hZGluZy4NCi0gKi8NCi10eXBlZGVmIHN0cnVjdCBfRlhfRE9XTkxPQURISU5UUyB7DQotCS8qKg0KLQkgKiBWZXJzaW9uIG51bWJlciBvZiB0aGUgaW50ZXJmYWNlLiBDdXJyZW50bHkgbXVzdCBiZSAxLg0KLQkgKi8NCi0JaW50IHZlcnNpb247DQotDQotCS8qKg0KLQkgKiBNZXRob2Q6IEFkZFNlZ21lbnQNCi0JICoJCUFkZCBhIHNlY3Rpb24gdG8gYmUgZG93bmxvYWRlZC4NCi0JICogSW50ZXJmYWNlIFZlcnNpb246DQotCSAqCQkxDQotCSAqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOg0KLQkgKgkJWWVzDQotCSAqIFBhcmFtZXRlcnM6DQotCSAqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4NCi0JICoJCW9mZnNldAkJLQlUaGUgb2Zmc2V0IG9mIHRoZSBoaW50IHJlcG9ydGVkIHRvIGJlIGRvd25sb2FkZWQuDQotCSAqCQlzaXplCQktCVRoZSBzaXplIG9mIHRoZSBoaW50IHJlcG9ydGVkIHRvIGJlIGRvd25sb2FkZWQuDQotCSAqIFJldHVybiBWYWx1ZToNCi0JICoJCU5vbmUuDQotCSAqIENvbW1lbnRzOg0KLQkgKgkJQ2FsbGVkIGJ5IEZveGl0IFNESyB0byByZXBvcnQgc29tZSBkb3dubG9hZGluZyBoaW50cyBmb3IgZG93bmxvYWQgbWFuYWdlci4NCi0JICoJCVRoZSBwb3NpdGlvbiBhbmQgc2l6ZSBvZiBzZWN0aW9uIG1heSBiZSBub3QgYWNjdXJhdGUsIHBhcnQgb2YgdGhlIHNlY3Rpb24gbWlnaHQgYmUgYWxyZWFkeSBhdmFpbGFibGUuIA0KLQkgKgkJVGhlIGRvd25sb2FkIG1hbmFnZXIgbXVzdCBkZWFsIHdpdGggdGhhdCB0byBtYXhpbWl6ZSBkb3dubG9hZCBlZmZpY2llbmN5Lg0KLQkgKi8NCi0Jdm9pZCAoKkFkZFNlZ21lbnQpKHN0cnVjdCBfRlhfRE9XTkxPQURISU5UUyogcFRoaXMsIHNpemVfdCBvZmZzZXQsIHNpemVfdCBzaXplKTsNCi19IEZYX0RPV05MT0FESElOVFM7DQotDQotLyoqDQotKiBGdW5jdGlvbjogRlBERkF2YWlsX0lzRG9jQXZhaWwNCi0qCQkJQ2hlY2sgd2hldGhlciB0aGUgZG9jdW1lbnQgaXMgcmVhZHkgZm9yIGxvYWRpbmcsIGlmIG5vdCwgZ2V0IGRvd25sb2FkIGhpbnRzLg0KLSoNCi0qIFBhcmFtZXRlcnM6IA0KLSoJCQlhdmFpbAkJLQlIYW5kbGUgdG8gZG9jdW1lbnQgYXZhaWxhYmlsaXR5IHByb3ZpZGVyIHJldHVybmVkIGJ5IEZQREZBdmFpbF9DcmVhdGUNCi0qCQkJaGludHMJCS0JUG9pbnRlciB0byBhIGRvd25sb2FkIGhpbnRzIGludGVyZmFjZSwgcmVjZWl2aW5nIGdlbmVyYXRlZCBoaW50cw0KLSogUmV0dXJuIHZhbHVlOg0KLSoJCQlOb24temVybyBmb3IgcGFnZSBpcyBmdWxseSBhdmFpbGFibGUsIDAgZm9yIHBhZ2Ugbm90IHlldCBhdmFpbGFibGUuDQotKiBDb21tZW50czoNCi0qCQkJVGhlIGFwcGxpY2F0aW9uIHNob3VsZCBjYWxsIHRoaXMgZnVuY3Rpb24gd2hlbmV2ZXIgbmV3IGRhdGEgYXJyaXZlZCwgYW5kIHByb2Nlc3MgYWxsIHRoZQ0KLSoJCQlnZW5lcmF0ZWQgZG93bmxvYWQgaGludHMgaWYgYW55LCB1bnRpbCB0aGUgZnVuY3Rpb24gcmV0dXJucyBub24temVybyB2YWx1ZS4gVGhlbiB0aGUgDQotKgkJCWFwcGxpY2F0aW9uIGNhbiBjYWxsIEZQREZBdmFpbF9HZXREb2N1bWVudCgpIHRvIGdldCBhIGRvY3VtZW50IGhhbmRsZS4NCi0qLw0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQXZhaWxfSXNEb2NBdmFpbChGUERGX0FWQUlMIGF2YWlsLCBGWF9ET1dOTE9BREhJTlRTKiBoaW50cyk7DQotDQotLyoqDQotKiBGdW5jdGlvbjogRlBERkF2YWlsX0dldERvY3VtZW50DQotKgkJCUdldCBkb2N1bWVudCBmcm9tIHRoZSBhdmFpbGFiaWxpdHkgcHJvdmlkZXIuDQotKg0KLSogUGFyYW1ldGVyczoNCi0qCQkJYXZhaWwJCS0JSGFuZGxlIHRvIGRvY3VtZW50IGF2YWlsYWJpbGl0eSBwcm92aWRlciByZXR1cm5lZCBieSBGUERGQXZhaWxfQ3JlYXRlDQotKiAgICAgcGFzc3dvcmQJLQlPcHRpb25hbCBwYXNzd29yZCBmb3IgZGVjcnlwdGluZyB0aGUgUERGIGZpbGUuDQotKiBSZXR1cm4gdmFsdWU6DQotKgkJCUhhbmRsZSB0byB0aGUgZG9jdW1lbnQuDQotKiBDb21tZW50czoNCi0qCQkJQWZ0ZXIgRlBERkF2YWlsX0lzRG9jQXZhaWwoKSByZXR1cm5zIFRSVUUsIHRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIGZ1bmN0aW9uIHRvDQotKgkJCWdldCB0aGUgZG9jdW1lbnQgaGFuZGxlLiBUbyBjbG9zZSB0aGUgZG9jdW1lbnQsIHVzZSBGUERGX0Nsb3NlRG9jdW1lbnQgZnVuY3Rpb24uDQotKi8NCi1ETExFWFBPUlQgRlBERl9ET0NVTUVOVCBTVERDQUxMIEZQREZBdmFpbF9HZXREb2N1bWVudChGUERGX0FWQUlMIGF2YWlsLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZQREZfQllURVNUUklORyBwYXNzd29yZCk7DQotDQotLyoqDQotKiBGdW5jdGlvbjogRlBERkF2YWlsX0dldEZpcnN0UGFnZU51bQ0KLSoJCQlHZXQgcGFnZSBudW1iZXIgZm9yIHRoZSBmaXJzdCBhdmFpbGFibGUgcGFnZSBpbiBhIGxpbmVhcml6ZWQgUERGDQotKg0KLSogUGFyYW1ldGVyczoNCi0qCQkJZG9jCQkJLQlBIGRvY3VtZW50IGhhbmRsZSByZXR1cm5lZCBieSBGUERGQXZhaWxfR2V0RG9jdW1lbnQNCi0qIFJldHVybiBWYWx1ZToNCi0qCQkJWmVyby1iYXNlZCBpbmRleCBmb3IgdGhlIGZpcnN0IGF2YWlsYWJsZSBwYWdlLg0KLSogQ29tbWVudHM6DQotKgkJCUZvciBtb3N0IGxpbmVhcml6ZWQgUERGcywgdGhlIGZpcnN0IGF2YWlsYWJsZSBwYWdlIHdvdWxkIGJlIGp1c3QgdGhlIGZpcnN0IHBhZ2UsIGhvd2V2ZXIsDQotKgkJCXNvbWUgUERGcyBtaWdodCBtYWtlIG90aGVyIHBhZ2UgdG8gYmUgdGhlIGZpcnN0IGF2YWlsYWJsZSBwYWdlLg0KLSoJCQlGb3Igbm9uLWxpbmVhcml6ZWQgUERGLCB0aGlzIGZ1bmN0aW9uIHdpbGwgYWx3YXlzIHJldHVybiB6ZXJvLg0KLSovDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZBdmFpbF9HZXRGaXJzdFBhZ2VOdW0oRlBERl9ET0NVTUVOVCBkb2MpOw0KLQ0KLS8qKg0KLSogRnVuY3Rpb246IEZQREZBdmFpbF9Jc1BhZ2VBdmFpbA0KLSoJCQlDaGVjayB3aGV0aGVyIGEgcGFnZSBpcyByZWFkeSBmb3IgbG9hZGluZywgaWYgbm90LCBnZXQgZG93bmxvYWQgaGludHMuDQotKg0KLSogUGFyYW1ldGVyczogDQotKgkJCWF2YWlsCQktCUhhbmRsZSB0byBkb2N1bWVudCBhdmFpbGFiaWxpdHkgcHJvdmlkZXIgcmV0dXJuZWQgYnkgRlBERkF2YWlsX0NyZWF0ZQ0KLSoJCQlwYWdlX2luZGV4CS0JSW5kZXggbnVtYmVyIG9mIHRoZSBwYWdlLiAwIGZvciB0aGUgZmlyc3QgcGFnZS4NCi0qCQkJaGludHMJCS0JUG9pbnRlciB0byBhIGRvd25sb2FkIGhpbnRzIGludGVyZmFjZSwgcmVjZWl2aW5nIGdlbmVyYXRlZCBoaW50cw0KLSogUmV0dXJuIHZhbHVlOg0KLSoJCQlOb24temVybyBmb3IgcGFnZSBpcyBmdWxseSBhdmFpbGFibGUsIDAgZm9yIHBhZ2Ugbm90IHlldCBhdmFpbGFibGUuDQotKiBDb21tZW50czoNCi0qCQkJVGhpcyBmdW5jdGlvbiBjYWxsIGJlIGNhbGxlZCBvbmx5IGFmdGVyIEZQREZBdmFpbF9HZXREb2N1bWVudCBpZiBjYWxsZWQuDQotKgkJCVRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIGZ1bmN0aW9uIHdoZW5ldmVyIG5ldyBkYXRhIGFycml2ZWQsIGFuZCBwcm9jZXNzIGFsbCB0aGUNCi0qCQkJZ2VuZXJhdGVkIGRvd25sb2FkIGhpbnRzIGlmIGFueSwgdW50aWwgdGhlIGZ1bmN0aW9uIHJldHVybnMgbm9uLXplcm8gdmFsdWUuIFRoZW4gdGhlIA0KLSoJCQlhcHBsaWNhdGlvbiBjYW4gcGVyZm9ybSBwYWdlIGxvYWRpbmcuDQotKi8NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERkF2YWlsX0lzUGFnZUF2YWlsKEZQREZfQVZBSUwgYXZhaWwsIGludCBwYWdlX2luZGV4LCBGWF9ET1dOTE9BREhJTlRTKiBoaW50cyk7DQotDQotLyoqDQotKiBGdW5jdGlvbjogRlBERkF2YWlsX0lTRm9ybUF2YWlsDQotKgkJCUNoZWNrIHdoZXRoZXIgRm9ybSBkYXRhIGlzIHJlYWR5IGZvciBpbml0LCBpZiBub3QsIGdldCBkb3dubG9hZCBoaW50cy4NCi0qDQotKiBQYXJhbWV0ZXJzOiANCi0qCQkJYXZhaWwJCS0JSGFuZGxlIHRvIGRvY3VtZW50IGF2YWlsYWJpbGl0eSBwcm92aWRlciByZXR1cm5lZCBieSBGUERGQXZhaWxfQ3JlYXRlDQotKgkJCWhpbnRzCQktCVBvaW50ZXIgdG8gYSBkb3dubG9hZCBoaW50cyBpbnRlcmZhY2UsIHJlY2VpdmluZyBnZW5lcmF0ZWQgaGludHMNCi0qIFJldHVybiB2YWx1ZToNCi0qCQkJTm9uLXplcm8gZm9yIEZvcm0gZGF0YSBpcyBmdWxseSBhdmFpbGFibGUsIDAgZm9yIEZvcm0gZGF0YSBub3QgeWV0IGF2YWlsYWJsZS4NCi0qCQkJRGV0YWlsczogLTEgLSBlcnJvciwgdGhlIGlucHV0IHBhcmFtZXRlciBub3QgY29ycmVjdCwgc3VjaCBhcyBoaW50cyBpcyBudWxsLg0KLSoJCQkJCSAwICAtIGRhdGEgbm90IGF2YWlsYWJsZQ0KLSoJCQkJCSAxICAtIGRhdGEgYXZhaWxhYmxlDQotKgkJCQkJIDIgIC0gbm8gZm9ybSBkYXRhLgkJCQkNCi0qIENvbW1lbnRzOg0KLSoJCQlUaGlzIGZ1bmN0aW9uIGNhbGwgYmUgY2FsbGVkIG9ubHkgYWZ0ZXIgRlBERkF2YWlsX0dldERvY3VtZW50IGlmIGNhbGxlZC4gDQotKgkJCVRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIGZ1bmN0aW9uIHdoZW5ldmVyIG5ldyBkYXRhIGFycml2ZWQsIGFuZCBwcm9jZXNzIGFsbCB0aGUNCi0qCQkJZ2VuZXJhdGVkIGRvd25sb2FkIGhpbnRzIGlmIGFueSwgdW50aWwgdGhlIGZ1bmN0aW9uIHJldHVybnMgbm9uLXplcm8gdmFsdWUuIFRoZW4gdGhlIA0KLSoJCQlhcHBsaWNhdGlvbiBjYW4gcGVyZm9ybSBwYWdlIGxvYWRpbmcuIFJlY29tbWVuZCB0byBjYWxsIEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQNCi0qCQkJYWZ0ZXIgdGhlIGZ1bmN0aW9uIHJldHVybnMgbm9uLXplcm8gdmFsdWUuDQotKi8NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERkF2YWlsX0lzRm9ybUF2YWlsKEZQREZfQVZBSUwgYXZhaWwsIEZYX0RPV05MT0FESElOVFMqIGhpbnRzKTsNCi0NCi0vKioNCi0qIEZ1bmN0aW9uOiBGUERGQXZhaWxfSXNMaW5lYXJpemVkDQotKgkJCVRvIGNoZWNrIHdoZXRoZXIgYSBkb2N1bWVudCBpcyBMaW5lYXJpemVkIFBERiBmaWxlLg0KLSoNCi0qIFBhcmFtZXRlcnM6DQotKgkJCWF2YWlsCQktCUhhbmRsZSB0byBkb2N1bWVudCBhdmFpbGFiaWxpdHkgcHJvdmlkZXIgcmV0dXJuZWQgYnkgRlBERkF2YWlsX0NyZWF0ZQ0KLSogUmV0dXJuIHZhbHVlOg0KLSoJCQlyZXR1cm4gVFJVRSBtZWFucyB0aGUgZG9jdW1lbnQgaXMgbGluZWFyaXplZCBQREYgZWxzZSBub3QuDQotKgkJCUZTREtfSVNfTElORUFSSVpFRCBpcyBhIGxpbmVhcml6ZSBmaWxlLg0KLSoJCQlGU0RLX05PVF9MSU5FQVJJWkVEIGlzIG5vdCBhIGxpbmVhcml6ZSBmaWxlLg0KLSoJCQlGU0RLX1VOS05PV19MSU5FQVJJWkVEIGRvbid0IGtub3cgd2hldGhlciB0aGUgZmlsZSBpcyBhIGxpbmVhcml6ZSBmaWxlLg0KLSogQ29tbWVudHM6DQotKgkJCUl0IHJldHVybiBUUlVFL0ZBTFNFIGFzIHNvb24gYXMgd2UgaGF2ZSBmaXJzdCAxSyBkYXRhLiAJSWYgdGhlIGZpbGUncyBzaXplIGxlc3MgdGhhbg0KLSoJCQkxSyx3ZSBkb24ndCBrbm93biB3aGV0aGVyIHRoZSBQREYgaXMgYSBsaW5lYXJpemVkIGZpbGUuDQotKg0KLSovDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZBdmFpbF9Jc0xpbmVhcml6ZWQoRlBERl9BVkFJTCBhdmFpbCk7DQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfTsNCi0jZW5kaWYNCi0NCi0jZW5kaWYNCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GUERGX0RBVEFBVkFJTF9IXworI2RlZmluZSBfRlBERl9EQVRBQVZBSUxfSF8KKworI2lmbmRlZiBfRlBERlZJRVdfSF8KKyNpbmNsdWRlICJmcGRmdmlldy5oIgorI2VuZGlmCisKKworLyoqIFRoZSByZXN1bHQgb2YgdGhlIHByb2Nlc3Mgd2hpY2ggY2hlY2sgbGluZWFyaXplZCBQREYuICovCisjZGVmaW5lIEZTREtfSVNfTElORUFSSVpFRAkJCTEKKyNkZWZpbmUgRlNES19OT1RfTElORUFSSVpFRAkJCTAKKyNkZWZpbmUgRlNES19VTktOT1dfTElORUFSSVpFRAkJLTEKKworCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qKgorICogSW50ZXJmYWNlOiBGWF9GSUxFQVZBSUwKKyAqCQkJSW50ZXJmYWNlIGZvciBjaGVja2luZyB3aGV0aGVyIHRoZSBzZWN0aW9uIG9mIHRoZSBmaWxlIGlzIGF2YWlsYWJsZS4gCisgKi8KK3R5cGVkZWYgc3RydWN0IF9GWF9GSUxFQVZBSUwgeworCS8qKgorCSAqIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcmZhY2UuIEN1cnJlbnRseSBtdXN0IGJlIDEuCisJICovCisJaW50IHZlcnNpb247CisKKwkvKioKKwkgKiBNZXRob2Q6IElzRGF0YUF2YWlsCisJICoJCVJlcG9ydCB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgZGF0YSBzZWN0aW9uIGlzIGF2YWlsYWJsZS4gQSBzZWN0aW9uIGlzIGF2YWlsYWJsZSBvbmx5IGlmIGFsbCBieXRlcyBpbiB0aGUgc2VjdGlvbiBpcyBhdmFpbGFibGUuIAorCSAqIEludGVyZmFjZSBWZXJzaW9uOgorCSAqCQkxCisJICogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJICoJCVllcworCSAqIFBhcmFtZXRlcnM6CisJICoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLgorCSAqCQlvZmZzZXQJCS0JVGhlIG9mZnNldCBvZiB0aGUgZGF0YSBzZWN0aW9uIGluIHRoZSBmaWxlLgorCSAqCQlzaXplCQktCVRoZSBzaXplIG9mIHRoZSBkYXRhIHNlY3Rpb24KKwkgKiBSZXR1cm4gVmFsdWU6CisJICoJCXRydWUgbWVhbnMgdGhlIHNwZWNpZmllZCBkYXRhIHNlY3Rpb24gaXMgYXZhaWxhYmxlLgorCSAqIENvbW1lbnRzOgorCSAqCQlDYWxsZWQgYnkgRm94aXQgU0RLIHRvIGNoZWNrIHdoZXRoZXIgdGhlIGRhdGEgc2VjdGlvbiBpcyByZWFkeS4KKwkgKi8KKwlib29sICgqSXNEYXRhQXZhaWwpKHN0cnVjdCBfRlhfRklMRUFWQUlMKiBwVGhpcywgc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpOworfSBGWF9GSUxFQVZBSUw7CisKK3R5cGVkZWYgdm9pZCogRlBERl9BVkFJTDsKKworLyoqCisqIEZ1bmN0aW9uOiBGUERGQXZhaWxfQ3JlYXRlCisqCQkJQ3JlYXRlIGEgZG9jdW1lbnQgYXZhaWxhYmlsaXR5IHByb3ZpZGVyLgorKgorKiBQYXJhbWV0ZXJzOiAKKyoJCQlmaWxlX2F2YWlsCS0JUG9pbnRlciB0byBmaWxlIGF2YWlsYWJpbGl0eSBpbnRlcmZhY2UgdG8gY2hlY2sgYXZhaWxhYmlsaXR5IG9mIGZpbGUgZGF0YS4KKyoJCQlmaWxlCQktCVBvaW50ZXIgdG8gYSBmaWxlIGFjY2VzcyBpbnRlcmZhY2UgZm9yIHJlYWRpbmcgZGF0YSBmcm9tIGZpbGUuCisqIFJldHVybiB2YWx1ZToKKyoJCQlBIGhhbmRsZSB0byB0aGUgZG9jdW1lbnQgYXZhaWxhYmlsaXR5IHByb3ZpZGVyLiBOVUxMIGZvciBlcnJvci4KKyogQ29tbWVudHM6CisqCQkJQXBwbGljYXRpb24gbXVzdCBjYWxsIEZQREZBdmFpbF9EZXN0cm95IHdoZW4gZG9uZSB3aXRoIHRoZSBhdmFpbGFiaWxpdHkgcHJvdmlkZXIuCisqLworRExMRVhQT1JUIEZQREZfQVZBSUwgU1REQ0FMTCBGUERGQXZhaWxfQ3JlYXRlKEZYX0ZJTEVBVkFJTCogZmlsZV9hdmFpbCwgRlBERl9GSUxFQUNDRVNTKiBmaWxlKTsKKworLyoqCisqIEZ1bmN0aW9uOiBGUERGQXZhaWxfRGVzdHJveQorKgkJCURlc3Ryb3kgYSBkb2N1bWVudCBhdmFpbGliaXR5IHByb3ZpZGVyLgorKgorKiBQYXJhbWV0ZXJzOiAKKyoJCQlhdmFpbAkJLQlIYW5kbGUgdG8gZG9jdW1lbnQgYXZhaWxhYmlsaXR5IHByb3ZpZGVyIHJldHVybmVkIGJ5IEZQREZBdmFpbF9DcmVhdGUKKyogUmV0dXJuIFZhbHVlOgorKgkJCU5vbmUuCisqLworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGQXZhaWxfRGVzdHJveShGUERGX0FWQUlMIGF2YWlsKTsKKworLyoqCisgKiBJbnRlcmZhY2U6IEZYX0RPV05MT0FESElOVFMKKyAqCQkJRG93bmxvYWQgaGludHMgaW50ZXJmYWNlLiBVc2VkIHRvIHJlY2VpdmUgaGludHMgZm9yIGZ1cnRoZXIgZG93bmxvYWRpbmcuCisgKi8KK3R5cGVkZWYgc3RydWN0IF9GWF9ET1dOTE9BREhJTlRTIHsKKwkvKioKKwkgKiBWZXJzaW9uIG51bWJlciBvZiB0aGUgaW50ZXJmYWNlLiBDdXJyZW50bHkgbXVzdCBiZSAxLgorCSAqLworCWludCB2ZXJzaW9uOworCisJLyoqCisJICogTWV0aG9kOiBBZGRTZWdtZW50CisJICoJCUFkZCBhIHNlY3Rpb24gdG8gYmUgZG93bmxvYWRlZC4KKwkgKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkgKgkJMQorCSAqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSAqCQlZZXMKKwkgKiBQYXJhbWV0ZXJzOgorCSAqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4KKwkgKgkJb2Zmc2V0CQktCVRoZSBvZmZzZXQgb2YgdGhlIGhpbnQgcmVwb3J0ZWQgdG8gYmUgZG93bmxvYWRlZC4KKwkgKgkJc2l6ZQkJLQlUaGUgc2l6ZSBvZiB0aGUgaGludCByZXBvcnRlZCB0byBiZSBkb3dubG9hZGVkLgorCSAqIFJldHVybiBWYWx1ZToKKwkgKgkJTm9uZS4KKwkgKiBDb21tZW50czoKKwkgKgkJQ2FsbGVkIGJ5IEZveGl0IFNESyB0byByZXBvcnQgc29tZSBkb3dubG9hZGluZyBoaW50cyBmb3IgZG93bmxvYWQgbWFuYWdlci4KKwkgKgkJVGhlIHBvc2l0aW9uIGFuZCBzaXplIG9mIHNlY3Rpb24gbWF5IGJlIG5vdCBhY2N1cmF0ZSwgcGFydCBvZiB0aGUgc2VjdGlvbiBtaWdodCBiZSBhbHJlYWR5IGF2YWlsYWJsZS4gCisJICoJCVRoZSBkb3dubG9hZCBtYW5hZ2VyIG11c3QgZGVhbCB3aXRoIHRoYXQgdG8gbWF4aW1pemUgZG93bmxvYWQgZWZmaWNpZW5jeS4KKwkgKi8KKwl2b2lkICgqQWRkU2VnbWVudCkoc3RydWN0IF9GWF9ET1dOTE9BREhJTlRTKiBwVGhpcywgc2l6ZV90IG9mZnNldCwgc2l6ZV90IHNpemUpOworfSBGWF9ET1dOTE9BREhJTlRTOworCisvKioKKyogRnVuY3Rpb246IEZQREZBdmFpbF9Jc0RvY0F2YWlsCisqCQkJQ2hlY2sgd2hldGhlciB0aGUgZG9jdW1lbnQgaXMgcmVhZHkgZm9yIGxvYWRpbmcsIGlmIG5vdCwgZ2V0IGRvd25sb2FkIGhpbnRzLgorKgorKiBQYXJhbWV0ZXJzOiAKKyoJCQlhdmFpbAkJLQlIYW5kbGUgdG8gZG9jdW1lbnQgYXZhaWxhYmlsaXR5IHByb3ZpZGVyIHJldHVybmVkIGJ5IEZQREZBdmFpbF9DcmVhdGUKKyoJCQloaW50cwkJLQlQb2ludGVyIHRvIGEgZG93bmxvYWQgaGludHMgaW50ZXJmYWNlLCByZWNlaXZpbmcgZ2VuZXJhdGVkIGhpbnRzCisqIFJldHVybiB2YWx1ZToKKyoJCQlOb24temVybyBmb3IgcGFnZSBpcyBmdWxseSBhdmFpbGFibGUsIDAgZm9yIHBhZ2Ugbm90IHlldCBhdmFpbGFibGUuCisqIENvbW1lbnRzOgorKgkJCVRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIGZ1bmN0aW9uIHdoZW5ldmVyIG5ldyBkYXRhIGFycml2ZWQsIGFuZCBwcm9jZXNzIGFsbCB0aGUKKyoJCQlnZW5lcmF0ZWQgZG93bmxvYWQgaGludHMgaWYgYW55LCB1bnRpbCB0aGUgZnVuY3Rpb24gcmV0dXJucyBub24temVybyB2YWx1ZS4gVGhlbiB0aGUgCisqCQkJYXBwbGljYXRpb24gY2FuIGNhbGwgRlBERkF2YWlsX0dldERvY3VtZW50KCkgdG8gZ2V0IGEgZG9jdW1lbnQgaGFuZGxlLgorKi8KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQXZhaWxfSXNEb2NBdmFpbChGUERGX0FWQUlMIGF2YWlsLCBGWF9ET1dOTE9BREhJTlRTKiBoaW50cyk7CisKKy8qKgorKiBGdW5jdGlvbjogRlBERkF2YWlsX0dldERvY3VtZW50CisqCQkJR2V0IGRvY3VtZW50IGZyb20gdGhlIGF2YWlsYWJpbGl0eSBwcm92aWRlci4KKyoKKyogUGFyYW1ldGVyczoKKyoJCQlhdmFpbAkJLQlIYW5kbGUgdG8gZG9jdW1lbnQgYXZhaWxhYmlsaXR5IHByb3ZpZGVyIHJldHVybmVkIGJ5IEZQREZBdmFpbF9DcmVhdGUKKyogICAgIHBhc3N3b3JkCS0JT3B0aW9uYWwgcGFzc3dvcmQgZm9yIGRlY3J5cHRpbmcgdGhlIFBERiBmaWxlLgorKiBSZXR1cm4gdmFsdWU6CisqCQkJSGFuZGxlIHRvIHRoZSBkb2N1bWVudC4KKyogQ29tbWVudHM6CisqCQkJQWZ0ZXIgRlBERkF2YWlsX0lzRG9jQXZhaWwoKSByZXR1cm5zIFRSVUUsIHRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIGZ1bmN0aW9uIHRvCisqCQkJZ2V0IHRoZSBkb2N1bWVudCBoYW5kbGUuIFRvIGNsb3NlIHRoZSBkb2N1bWVudCwgdXNlIEZQREZfQ2xvc2VEb2N1bWVudCBmdW5jdGlvbi4KKyovCitETExFWFBPUlQgRlBERl9ET0NVTUVOVCBTVERDQUxMIEZQREZBdmFpbF9HZXREb2N1bWVudChGUERGX0FWQUlMIGF2YWlsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlBERl9CWVRFU1RSSU5HIHBhc3N3b3JkKTsKKworLyoqCisqIEZ1bmN0aW9uOiBGUERGQXZhaWxfR2V0Rmlyc3RQYWdlTnVtCisqCQkJR2V0IHBhZ2UgbnVtYmVyIGZvciB0aGUgZmlyc3QgYXZhaWxhYmxlIHBhZ2UgaW4gYSBsaW5lYXJpemVkIFBERgorKgorKiBQYXJhbWV0ZXJzOgorKgkJCWRvYwkJCS0JQSBkb2N1bWVudCBoYW5kbGUgcmV0dXJuZWQgYnkgRlBERkF2YWlsX0dldERvY3VtZW50CisqIFJldHVybiBWYWx1ZToKKyoJCQlaZXJvLWJhc2VkIGluZGV4IGZvciB0aGUgZmlyc3QgYXZhaWxhYmxlIHBhZ2UuCisqIENvbW1lbnRzOgorKgkJCUZvciBtb3N0IGxpbmVhcml6ZWQgUERGcywgdGhlIGZpcnN0IGF2YWlsYWJsZSBwYWdlIHdvdWxkIGJlIGp1c3QgdGhlIGZpcnN0IHBhZ2UsIGhvd2V2ZXIsCisqCQkJc29tZSBQREZzIG1pZ2h0IG1ha2Ugb3RoZXIgcGFnZSB0byBiZSB0aGUgZmlyc3QgYXZhaWxhYmxlIHBhZ2UuCisqCQkJRm9yIG5vbi1saW5lYXJpemVkIFBERiwgdGhpcyBmdW5jdGlvbiB3aWxsIGFsd2F5cyByZXR1cm4gemVyby4KKyovCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkF2YWlsX0dldEZpcnN0UGFnZU51bShGUERGX0RPQ1VNRU5UIGRvYyk7CisKKy8qKgorKiBGdW5jdGlvbjogRlBERkF2YWlsX0lzUGFnZUF2YWlsCisqCQkJQ2hlY2sgd2hldGhlciBhIHBhZ2UgaXMgcmVhZHkgZm9yIGxvYWRpbmcsIGlmIG5vdCwgZ2V0IGRvd25sb2FkIGhpbnRzLgorKgorKiBQYXJhbWV0ZXJzOiAKKyoJCQlhdmFpbAkJLQlIYW5kbGUgdG8gZG9jdW1lbnQgYXZhaWxhYmlsaXR5IHByb3ZpZGVyIHJldHVybmVkIGJ5IEZQREZBdmFpbF9DcmVhdGUKKyoJCQlwYWdlX2luZGV4CS0JSW5kZXggbnVtYmVyIG9mIHRoZSBwYWdlLiAwIGZvciB0aGUgZmlyc3QgcGFnZS4KKyoJCQloaW50cwkJLQlQb2ludGVyIHRvIGEgZG93bmxvYWQgaGludHMgaW50ZXJmYWNlLCByZWNlaXZpbmcgZ2VuZXJhdGVkIGhpbnRzCisqIFJldHVybiB2YWx1ZToKKyoJCQlOb24temVybyBmb3IgcGFnZSBpcyBmdWxseSBhdmFpbGFibGUsIDAgZm9yIHBhZ2Ugbm90IHlldCBhdmFpbGFibGUuCisqIENvbW1lbnRzOgorKgkJCVRoaXMgZnVuY3Rpb24gY2FsbCBiZSBjYWxsZWQgb25seSBhZnRlciBGUERGQXZhaWxfR2V0RG9jdW1lbnQgaWYgY2FsbGVkLgorKgkJCVRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIGZ1bmN0aW9uIHdoZW5ldmVyIG5ldyBkYXRhIGFycml2ZWQsIGFuZCBwcm9jZXNzIGFsbCB0aGUKKyoJCQlnZW5lcmF0ZWQgZG93bmxvYWQgaGludHMgaWYgYW55LCB1bnRpbCB0aGUgZnVuY3Rpb24gcmV0dXJucyBub24temVybyB2YWx1ZS4gVGhlbiB0aGUgCisqCQkJYXBwbGljYXRpb24gY2FuIHBlcmZvcm0gcGFnZSBsb2FkaW5nLgorKi8KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQXZhaWxfSXNQYWdlQXZhaWwoRlBERl9BVkFJTCBhdmFpbCwgaW50IHBhZ2VfaW5kZXgsIEZYX0RPV05MT0FESElOVFMqIGhpbnRzKTsKKworLyoqCisqIEZ1bmN0aW9uOiBGUERGQXZhaWxfSVNGb3JtQXZhaWwKKyoJCQlDaGVjayB3aGV0aGVyIEZvcm0gZGF0YSBpcyByZWFkeSBmb3IgaW5pdCwgaWYgbm90LCBnZXQgZG93bmxvYWQgaGludHMuCisqCisqIFBhcmFtZXRlcnM6IAorKgkJCWF2YWlsCQktCUhhbmRsZSB0byBkb2N1bWVudCBhdmFpbGFiaWxpdHkgcHJvdmlkZXIgcmV0dXJuZWQgYnkgRlBERkF2YWlsX0NyZWF0ZQorKgkJCWhpbnRzCQktCVBvaW50ZXIgdG8gYSBkb3dubG9hZCBoaW50cyBpbnRlcmZhY2UsIHJlY2VpdmluZyBnZW5lcmF0ZWQgaGludHMKKyogUmV0dXJuIHZhbHVlOgorKgkJCU5vbi16ZXJvIGZvciBGb3JtIGRhdGEgaXMgZnVsbHkgYXZhaWxhYmxlLCAwIGZvciBGb3JtIGRhdGEgbm90IHlldCBhdmFpbGFibGUuCisqCQkJRGV0YWlsczogLTEgLSBlcnJvciwgdGhlIGlucHV0IHBhcmFtZXRlciBub3QgY29ycmVjdCwgc3VjaCBhcyBoaW50cyBpcyBudWxsLgorKgkJCQkJIDAgIC0gZGF0YSBub3QgYXZhaWxhYmxlCisqCQkJCQkgMSAgLSBkYXRhIGF2YWlsYWJsZQorKgkJCQkJIDIgIC0gbm8gZm9ybSBkYXRhLgkJCQkKKyogQ29tbWVudHM6CisqCQkJVGhpcyBmdW5jdGlvbiBjYWxsIGJlIGNhbGxlZCBvbmx5IGFmdGVyIEZQREZBdmFpbF9HZXREb2N1bWVudCBpZiBjYWxsZWQuIAorKgkJCVRoZSBhcHBsaWNhdGlvbiBzaG91bGQgY2FsbCB0aGlzIGZ1bmN0aW9uIHdoZW5ldmVyIG5ldyBkYXRhIGFycml2ZWQsIGFuZCBwcm9jZXNzIGFsbCB0aGUKKyoJCQlnZW5lcmF0ZWQgZG93bmxvYWQgaGludHMgaWYgYW55LCB1bnRpbCB0aGUgZnVuY3Rpb24gcmV0dXJucyBub24temVybyB2YWx1ZS4gVGhlbiB0aGUgCisqCQkJYXBwbGljYXRpb24gY2FuIHBlcmZvcm0gcGFnZSBsb2FkaW5nLiBSZWNvbW1lbmQgdG8gY2FsbCBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50CisqCQkJYWZ0ZXIgdGhlIGZ1bmN0aW9uIHJldHVybnMgbm9uLXplcm8gdmFsdWUuCisqLworRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZBdmFpbF9Jc0Zvcm1BdmFpbChGUERGX0FWQUlMIGF2YWlsLCBGWF9ET1dOTE9BREhJTlRTKiBoaW50cyk7CisKKy8qKgorKiBGdW5jdGlvbjogRlBERkF2YWlsX0lzTGluZWFyaXplZAorKgkJCVRvIGNoZWNrIHdoZXRoZXIgYSBkb2N1bWVudCBpcyBMaW5lYXJpemVkIFBERiBmaWxlLgorKgorKiBQYXJhbWV0ZXJzOgorKgkJCWF2YWlsCQktCUhhbmRsZSB0byBkb2N1bWVudCBhdmFpbGFiaWxpdHkgcHJvdmlkZXIgcmV0dXJuZWQgYnkgRlBERkF2YWlsX0NyZWF0ZQorKiBSZXR1cm4gdmFsdWU6CisqCQkJcmV0dXJuIFRSVUUgbWVhbnMgdGhlIGRvY3VtZW50IGlzIGxpbmVhcml6ZWQgUERGIGVsc2Ugbm90LgorKgkJCUZTREtfSVNfTElORUFSSVpFRCBpcyBhIGxpbmVhcml6ZSBmaWxlLgorKgkJCUZTREtfTk9UX0xJTkVBUklaRUQgaXMgbm90IGEgbGluZWFyaXplIGZpbGUuCisqCQkJRlNES19VTktOT1dfTElORUFSSVpFRCBkb24ndCBrbm93IHdoZXRoZXIgdGhlIGZpbGUgaXMgYSBsaW5lYXJpemUgZmlsZS4KKyogQ29tbWVudHM6CisqCQkJSXQgcmV0dXJuIFRSVUUvRkFMU0UgYXMgc29vbiBhcyB3ZSBoYXZlIGZpcnN0IDFLIGRhdGEuIAlJZiB0aGUgZmlsZSdzIHNpemUgbGVzcyB0aGFuCisqCQkJMUssd2UgZG9uJ3Qga25vd24gd2hldGhlciB0aGUgUERGIGlzIGEgbGluZWFyaXplZCBmaWxlLgorKgorKi8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGQXZhaWxfSXNMaW5lYXJpemVkKEZQREZfQVZBSUwgYXZhaWwpOworCisjaWZkZWYgX19jcGx1c3BsdXMKK307CisjZW5kaWYKKworI2VuZGlmCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmX2V4dC5oIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZXh0LmgKaW5kZXggYThmMjY4YS4uNWVmZTBlNiAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZXh0LmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZXh0LmgKQEAgLTEsMTA4ICsxLDEwOCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfRlBERl9FWFRfSF8NCi0jZGVmaW5lIF9GUERGX0VYVF9IXw0KLQ0KLSNpZm5kZWYgX0ZQREZWSUVXX0hfDQotI2luY2x1ZGUgImZwZGZ2aWV3LmgiDQotI2VuZGlmDQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotZXh0ZXJuICJDIiB7DQotI2VuZGlmDQotDQotLy9mbGFncyBmb3IgdHlwZSBvZiB1bnN1cHBvcnQgb2JqZWN0Lg0KLSNkZWZpbmUgRlBERl9VTlNQX0RPQ19YRkFGT1JNCQkJCTENCi0jZGVmaW5lIEZQREZfVU5TUF9ET0NfUE9SVEFCTEVDT0xMRUNUSU9OCTINCi0jZGVmaW5lIEZQREZfVU5TUF9ET0NfQVRUQUNITUVOVAkJCTMNCi0jZGVmaW5lIEZQREZfVU5TUF9ET0NfU0VDVVJJVFkJCQkJNA0KLSNkZWZpbmUgRlBERl9VTlNQX0RPQ19TSEFSRURSRVZJRVcJCQk1DQotI2RlZmluZSBGUERGX1VOU1BfRE9DX1NIQVJFREZPUk1fQUNST0JBVAk2DQotI2RlZmluZSBGUERGX1VOU1BfRE9DX1NIQVJFREZPUk1fRklMRVNZU1RFTQk3DQotI2RlZmluZSBGUERGX1VOU1BfRE9DX1NIQVJFREZPUk1fRU1BSUwJCTgNCi0jZGVmaW5lIEZQREZfVU5TUF9BTk5PVF8zREFOTk9UCQkJCTExDQotI2RlZmluZSBGUERGX1VOU1BfQU5OT1RfTU9WSUUJCQkJMTINCi0jZGVmaW5lIEZQREZfVU5TUF9BTk5PVF9TT1VORAkJCQkxMw0KLSNkZWZpbmUgRlBERl9VTlNQX0FOTk9UX1NDUkVFTl9NRURJQQkJMTQNCi0jZGVmaW5lIEZQREZfVU5TUF9BTk5PVF9TQ1JFRU5fUklDSE1FRElBCTE1DQotI2RlZmluZSBGUERGX1VOU1BfQU5OT1RfQVRUQUNITUVOVAkJCTE2DQotI2RlZmluZSBGUERGX1VOU1BfQU5OT1RfU0lHCQkJCQkxNw0KLQ0KLXR5cGVkZWYJc3RydWN0IF9VTlNVUFBPUlRfSU5GTw0KLXsNCi0JLyoqDQotCSogVmVyc2lvbiBudW1iZXIgb2YgdGhlIGludGVyZmFjZS4gQ3VycmVudGx5IG11c3QgYmUgMS4NCi0JKiovDQotCWludCB2ZXJzaW9uOw0KLQkNCi0JLyoqIA0KLQkqIE1ldGhvZDogRlNES19VblN1cHBvcnRfSGFuZGxlcg0KLQkqCQkJIFVuU3VwcG9ydCBPYmplY3QgcHJvY2VzcyBoYW5kbGluZyBmdW5jdGlvbi4NCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCVllcw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLg0KLQkqCQluVHlwZQkJLQlUaGUgdHlwZSBvZiB1bnN1cHBvcnRPYmplY3QNCi0JKiAJUmV0dXJuIHZhbHVlOg0KLQkqIAkJTm9uZS4NCi0JKiAqLw0KLQ0KLQl2b2lkKCpGU0RLX1VuU3VwcG9ydF9IYW5kbGVyKShfVU5TVVBQT1JUX0lORk8qIHBUaGlzLGludCBuVHlwZSk7DQotfVVOU1VQUE9SVF9JTkZPOw0KLQ0KLQ0KLS8qKg0KLSAqIEZ1bmN0aW9uOiBGU0RLX1NldFVuU3BPYmpQcm9jZXNzSGFuZGxlcg0KLSAqCQkJIFNldHVwIEEgVW5TdXBwb3J0IE9iamVjdCBwcm9jZXNzIGhhbmRsZXIgZm9yIGZveGl0IHNkay4gDQotICogUGFyYW1ldGVyczoNCi0gKgkJCXVuc3BfaW5mbwkJLQlQb2ludGVyIHRvIGEgVU5TVVBQT1JUX0lORk8gc3RydWN0dXJlLg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCVRSVUUgbWVhbnMgc3VjY2Vzc2Z1bC4gRkFMU0UgbWVhbnMgZmFpbHMuIA0KLSAqKi8NCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlNES19TZXRVblNwT2JqUHJvY2Vzc0hhbmRsZXIoVU5TVVBQT1JUX0lORk8qIHVuc3BfaW5mbyk7DQotDQotLy9mbGFncyBmb3IgcGFnZSBtb2RlLiANCi0NCi0vL1Vua25vd24gdmFsdWUNCi0jZGVmaW5lIFBBR0VNT0RFX1VOS09OT1dOCQktMQ0KLQ0KLS8vTmVpdGhlciBkb2N1bWVudCBvdXRsaW5lIG5vciB0aHVtYm5haWwgaW1hZ2VzIHZpc2libGUNCi0jZGVmaW5lIFBBR0VNT0RFX1VTRU5PTkUJCTANCi0NCi0vL0RvY3VtZW50IG91dGxpbmUgdmlzaWJsZQ0KLSNkZWZpbmUgUEFHRU1PREVfVVNFT1VUTElORVMJMQ0KLQ0KLS8vVGh1bWJuaWFsIGltYWdlcyB2aXNpYmxlDQotI2RlZmluZSBQQUdFTU9ERV9VU0VUSFVNQlMJCTINCi0NCi0vL0Z1bGwtc2NyZWVuIG1vZGUsIHdpdGggbm8gbWVudSBiYXIsIHdpbmRvdyBjb250cm9scywgb3IgYW55IG90aGVyIHdpbmRvdyB2aXNpYmxlDQotI2RlZmluZSBQQUdFTU9ERV9GVUxMU0NSRUVOCQkzDQotDQotLy9PcHRpb25hbCBjb250ZW50IGdyb3VwIHBhbmVsIHZpc2libGUNCi0jZGVmaW5lIFBBR0VNT0RFX1VTRU9DCQkJNA0KLQ0KLS8vQXR0YWNobWVudHMgcGFuZWwgdmlzaWJsZQ0KLSNkZWZpbmUgUEFHRU1PREVfVVNFQVRUQUNITUVOVFMJNQ0KLQ0KLQ0KLS8qKg0KLSAqIEZ1bmN0aW9uOiBGUERGRG9jX0dldFBhZ2VNb2RlDQotICoJCQkgR2V0IHRoZSBkb2N1bWVudCdzIFBhZ2VNb2RlKEhvdyB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlIGRpc3BsYXllZCB3aGVuIG9wZW5lZCkgDQotICogUGFyYW1ldGVyczoNCi0gKgkJCWRvYwkJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCVRoZSBmbGFncyBmb3IgcGFnZSBtb2RlLg0KLSAqKi8NCi1ETExFWFBPUlQgaW50IEZQREZEb2NfR2V0UGFnZU1vZGUoRlBERl9ET0NVTUVOVCBkb2N1bWVudCk7DQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfTsNCi0jZW5kaWYNCi0jZW5kaWYNCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GUERGX0VYVF9IXworI2RlZmluZSBfRlBERl9FWFRfSF8KKworI2lmbmRlZiBfRlBERlZJRVdfSF8KKyNpbmNsdWRlICJmcGRmdmlldy5oIgorI2VuZGlmCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLy9mbGFncyBmb3IgdHlwZSBvZiB1bnN1cHBvcnQgb2JqZWN0LgorI2RlZmluZSBGUERGX1VOU1BfRE9DX1hGQUZPUk0JCQkJMQorI2RlZmluZSBGUERGX1VOU1BfRE9DX1BPUlRBQkxFQ09MTEVDVElPTgkyCisjZGVmaW5lIEZQREZfVU5TUF9ET0NfQVRUQUNITUVOVAkJCTMKKyNkZWZpbmUgRlBERl9VTlNQX0RPQ19TRUNVUklUWQkJCQk0CisjZGVmaW5lIEZQREZfVU5TUF9ET0NfU0hBUkVEUkVWSUVXCQkJNQorI2RlZmluZSBGUERGX1VOU1BfRE9DX1NIQVJFREZPUk1fQUNST0JBVAk2CisjZGVmaW5lIEZQREZfVU5TUF9ET0NfU0hBUkVERk9STV9GSUxFU1lTVEVNCTcKKyNkZWZpbmUgRlBERl9VTlNQX0RPQ19TSEFSRURGT1JNX0VNQUlMCQk4CisjZGVmaW5lIEZQREZfVU5TUF9BTk5PVF8zREFOTk9UCQkJCTExCisjZGVmaW5lIEZQREZfVU5TUF9BTk5PVF9NT1ZJRQkJCQkxMgorI2RlZmluZSBGUERGX1VOU1BfQU5OT1RfU09VTkQJCQkJMTMKKyNkZWZpbmUgRlBERl9VTlNQX0FOTk9UX1NDUkVFTl9NRURJQQkJMTQKKyNkZWZpbmUgRlBERl9VTlNQX0FOTk9UX1NDUkVFTl9SSUNITUVESUEJMTUKKyNkZWZpbmUgRlBERl9VTlNQX0FOTk9UX0FUVEFDSE1FTlQJCQkxNgorI2RlZmluZSBGUERGX1VOU1BfQU5OT1RfU0lHCQkJCQkxNworCit0eXBlZGVmCXN0cnVjdCBfVU5TVVBQT1JUX0lORk8KK3sKKwkvKioKKwkqIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcmZhY2UuIEN1cnJlbnRseSBtdXN0IGJlIDEuCisJKiovCisJaW50IHZlcnNpb247CisJCisJLyoqIAorCSogTWV0aG9kOiBGU0RLX1VuU3VwcG9ydF9IYW5kbGVyCisJKgkJCSBVblN1cHBvcnQgT2JqZWN0IHByb2Nlc3MgaGFuZGxpbmcgZnVuY3Rpb24uCisJKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkqCQkJMQorCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJKgkJCVllcworCSogUGFyYW1ldGVyczoKKwkqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4KKwkqCQluVHlwZQkJLQlUaGUgdHlwZSBvZiB1bnN1cHBvcnRPYmplY3QKKwkqIAlSZXR1cm4gdmFsdWU6CisJKiAJCU5vbmUuCisJKiAqLworCisJdm9pZCgqRlNES19VblN1cHBvcnRfSGFuZGxlcikoX1VOU1VQUE9SVF9JTkZPKiBwVGhpcyxpbnQgblR5cGUpOworfVVOU1VQUE9SVF9JTkZPOworCisKKy8qKgorICogRnVuY3Rpb246IEZTREtfU2V0VW5TcE9ialByb2Nlc3NIYW5kbGVyCisgKgkJCSBTZXR1cCBBIFVuU3VwcG9ydCBPYmplY3QgcHJvY2VzcyBoYW5kbGVyIGZvciBmb3hpdCBzZGsuIAorICogUGFyYW1ldGVyczoKKyAqCQkJdW5zcF9pbmZvCQktCVBvaW50ZXIgdG8gYSBVTlNVUFBPUlRfSU5GTyBzdHJ1Y3R1cmUuCisgKiBSZXR1cm4gVmFsdWU6CisgKgkJCVRSVUUgbWVhbnMgc3VjY2Vzc2Z1bC4gRkFMU0UgbWVhbnMgZmFpbHMuIAorICoqLworCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlNES19TZXRVblNwT2JqUHJvY2Vzc0hhbmRsZXIoVU5TVVBQT1JUX0lORk8qIHVuc3BfaW5mbyk7CisKKy8vZmxhZ3MgZm9yIHBhZ2UgbW9kZS4gCisKKy8vVW5rbm93biB2YWx1ZQorI2RlZmluZSBQQUdFTU9ERV9VTktPTk9XTgkJLTEKKworLy9OZWl0aGVyIGRvY3VtZW50IG91dGxpbmUgbm9yIHRodW1ibmFpbCBpbWFnZXMgdmlzaWJsZQorI2RlZmluZSBQQUdFTU9ERV9VU0VOT05FCQkwCisKKy8vRG9jdW1lbnQgb3V0bGluZSB2aXNpYmxlCisjZGVmaW5lIFBBR0VNT0RFX1VTRU9VVExJTkVTCTEKKworLy9UaHVtYm5pYWwgaW1hZ2VzIHZpc2libGUKKyNkZWZpbmUgUEFHRU1PREVfVVNFVEhVTUJTCQkyCisKKy8vRnVsbC1zY3JlZW4gbW9kZSwgd2l0aCBubyBtZW51IGJhciwgd2luZG93IGNvbnRyb2xzLCBvciBhbnkgb3RoZXIgd2luZG93IHZpc2libGUKKyNkZWZpbmUgUEFHRU1PREVfRlVMTFNDUkVFTgkJMworCisvL09wdGlvbmFsIGNvbnRlbnQgZ3JvdXAgcGFuZWwgdmlzaWJsZQorI2RlZmluZSBQQUdFTU9ERV9VU0VPQwkJCTQKKworLy9BdHRhY2htZW50cyBwYW5lbCB2aXNpYmxlCisjZGVmaW5lIFBBR0VNT0RFX1VTRUFUVEFDSE1FTlRTCTUKKworCisvKioKKyAqIEZ1bmN0aW9uOiBGUERGRG9jX0dldFBhZ2VNb2RlCisgKgkJCSBHZXQgdGhlIGRvY3VtZW50J3MgUGFnZU1vZGUoSG93IHRoZSBkb2N1bWVudCBzaG91bGQgYmUgZGlzcGxheWVkIHdoZW4gb3BlbmVkKSAKKyAqIFBhcmFtZXRlcnM6CisgKgkJCWRvYwkJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLgorICogUmV0dXJuIFZhbHVlOgorICoJCQlUaGUgZmxhZ3MgZm9yIHBhZ2UgbW9kZS4KKyAqKi8KK0RMTEVYUE9SVCBpbnQgRlBERkRvY19HZXRQYWdlTW9kZShGUERGX0RPQ1VNRU5UIGRvY3VtZW50KTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9OworI2VuZGlmCisjZW5kaWYKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmX2ZsYXR0ZW4uaCBiL2ZwZGZzZGsvaW5jbHVkZS9mcGRmX2ZsYXR0ZW4uaAppbmRleCAyNmUzMjRkLi4yZTllNTA5IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnBkZl9mbGF0dGVuLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZmxhdHRlbi5oCkBAIC0xLDQyICsxLDQyIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GUERGX0ZMQVRURU5fSF8NCi0jZGVmaW5lIF9GUERGX0ZMQVRURU5fSF8NCi0JDQotI2luY2x1ZGUgImZwZGZ2aWV3LmgiDQotDQotI2RlZmluZSBGTEFUVEVOX0ZBSUwJCQkwCS8vIEZsYXR0ZW4gb3BlcmF0aW9uIGZhaWxlZC4NCi0jZGVmaW5lIEZMQVRURU5fU1VDQ0VTUwkJCTEJLy8gRmxhdHRlbiBvcGVyYXRpb24gc3VjY2VlZC4NCi0jZGVmaW5lIEZMQVRURU5fTk9USU5HVE9ETwkJMgkvLyBUaGVyZSBpcyBub3RoaW5nIGNhbiBiZSBmbGF0dGVuLg0KLQkNCi0jaWZkZWYgX19jcGx1c3BsdXMNCi1leHRlcm4gIkMiIHsNCi0jZW5kaWYNCi0NCi0jZGVmaW5lIEZMQVRfTk9STUFMRElTUExBWSAgICAgMA0KLSNkZWZpbmUgRkxBVF9QUklOVCAgICAgICAgICAgICAxICAgIA0KLQkvL0Z1bmN0aW9uOiBGUERGUGFnZV9GbGF0dGVuDQotDQotCS8vCQkJRmxhdCBhIHBkZiBwYWdlLGFubm90YXRpb25zIG9yIGZvcm0gZmllbGRzIHdpbGwgYmVjb21lIHBhcnQgb2YgdGhlIHBhZ2UgY29udGVudHMuDQotCS8vUGFyYW1ldGVyczoNCi0NCi0JLy8JCQlwYWdlICAtIEhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0JLy8JCQluRmxhZyAtIHRoZSBmbGFnIGZvciB0aGUgdXNlIG9mIGZsYXR0ZW4gcmVzdWx0LiBaZXJvIGZvciBub3JtYWwgZGlzcGxheSwgMSBmb3IgcHJpbnQuDQotCS8vUmV0dXJuIHZhbHVlOg0KLQkvLwkJCVRoZSByZXN1bHQgZmxhZyBvZiB0aGUgZnVuY3Rpb24sIFNlZSBmbGFncyBhYm92ZSAoIEZMQVRURU5fRkFJTCwgRkxBVFRFTl9TVUNDRVNTLCBGTEFUVEVOX05PVElOR1RPRE8gKS4NCi0JLy8NCi0JLy8gQ29tbWVudHM6IEN1cnJlbnQgdmVyc2lvbiBhbGwgZmFpbHMgcmV0dXJuIHplcm8uIElmIG5lY2Vzc2FyeSB3ZSB3aWxsIGFzc2lnbiBkaWZmZXJlbnQgdmFsdWUNCi0JLy8JCQl0byBpbmRpY2F0ZSBkaWZmZXJlbnQgZmFpbCByZWFzb24uDQotCS8vIA0KLQlETExFWFBPUlQgaW50IFNURENBTEwgRlBERlBhZ2VfRmxhdHRlbiggRlBERl9QQUdFIHBhZ2UsIGludCBuRmxhZyk7DQotCQkNCi0JCQ0KLSNpZmRlZiBfX2NwbHVzcGx1cw0KLX07DQotI2VuZGlmDQotDQotI2VuZGlmIC8vX0ZQREZfRkxBVFRFTl9IXw0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0ZQREZfRkxBVFRFTl9IXworI2RlZmluZSBfRlBERl9GTEFUVEVOX0hfCisJCisjaW5jbHVkZSAiZnBkZnZpZXcuaCIKKworI2RlZmluZSBGTEFUVEVOX0ZBSUwJCQkwCS8vIEZsYXR0ZW4gb3BlcmF0aW9uIGZhaWxlZC4KKyNkZWZpbmUgRkxBVFRFTl9TVUNDRVNTCQkJMQkvLyBGbGF0dGVuIG9wZXJhdGlvbiBzdWNjZWVkLgorI2RlZmluZSBGTEFUVEVOX05PVElOR1RPRE8JCTIJLy8gVGhlcmUgaXMgbm90aGluZyBjYW4gYmUgZmxhdHRlbi4KKwkKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworI2RlZmluZSBGTEFUX05PUk1BTERJU1BMQVkgICAgIDAKKyNkZWZpbmUgRkxBVF9QUklOVCAgICAgICAgICAgICAxICAgIAorCS8vRnVuY3Rpb246IEZQREZQYWdlX0ZsYXR0ZW4KKworCS8vCQkJRmxhdCBhIHBkZiBwYWdlLGFubm90YXRpb25zIG9yIGZvcm0gZmllbGRzIHdpbGwgYmVjb21lIHBhcnQgb2YgdGhlIHBhZ2UgY29udGVudHMuCisJLy9QYXJhbWV0ZXJzOgorCisJLy8JCQlwYWdlICAtIEhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4KKwkvLwkJCW5GbGFnIC0gdGhlIGZsYWcgZm9yIHRoZSB1c2Ugb2YgZmxhdHRlbiByZXN1bHQuIFplcm8gZm9yIG5vcm1hbCBkaXNwbGF5LCAxIGZvciBwcmludC4KKwkvL1JldHVybiB2YWx1ZToKKwkvLwkJCVRoZSByZXN1bHQgZmxhZyBvZiB0aGUgZnVuY3Rpb24sIFNlZSBmbGFncyBhYm92ZSAoIEZMQVRURU5fRkFJTCwgRkxBVFRFTl9TVUNDRVNTLCBGTEFUVEVOX05PVElOR1RPRE8gKS4KKwkvLworCS8vIENvbW1lbnRzOiBDdXJyZW50IHZlcnNpb24gYWxsIGZhaWxzIHJldHVybiB6ZXJvLiBJZiBuZWNlc3Nhcnkgd2Ugd2lsbCBhc3NpZ24gZGlmZmVyZW50IHZhbHVlCisJLy8JCQl0byBpbmRpY2F0ZSBkaWZmZXJlbnQgZmFpbCByZWFzb24uCisJLy8gCisJRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZQYWdlX0ZsYXR0ZW4oIEZQREZfUEFHRSBwYWdlLCBpbnQgbkZsYWcpOworCQkKKwkJCisjaWZkZWYgX19jcGx1c3BsdXMKK307CisjZW5kaWYKKworI2VuZGlmIC8vX0ZQREZfRkxBVFRFTl9IXwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZndsZXZlbnQuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mcGRmX2Z3bGV2ZW50LmgKaW5kZXggY2YzNGMyMS4uZjc3ZTdlMyAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfZndsZXZlbnQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnBkZl9md2xldmVudC5oCkBAIC0xLDI4NiArMSwyODYgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZXTF9FVkVOVF9IDQotI2RlZmluZSBfRldMX0VWRU5UX0gNCi0NCi0jaW5jbHVkZSAiZnBkZnZpZXcuaCINCi0NCi10eXBlZGVmIGludAkJCUZQREZfSU5UMzI7DQotdHlwZWRlZiB1bnNpZ25lZCBpbnQgRlBERl9VSU5UMzI7DQotdHlwZWRlZiBmbG9hdAkJRlBERl9GTE9BVDsNCi0vL2V2ZW50IHR5cGUNCi10eXBlZGVmIGVudW0NCi17DQotCUZXTF9FVkVOVFRZUEVfTW91c2UgPSAwCSwNCi0JRldMX0VWRU5UVFlQRV9Nb3VzZVdoZWVsLAkNCi0JRldMX0VWRU5UVFlQRV9LZXkJCSwNCi19IEZXTF9FVkVOVFRZUEU7DQotDQotLy9rZXkgZmxhZw0KLXR5cGVkZWYgZW51bQ0KLXsgICAgDQotCUZXTF9FVkVOVEZMQUdfU2hpZnRLZXkJCQk9IDEgPDwgMCwgICAgDQotCUZXTF9FVkVOVEZMQUdfQ29udHJvbEtleQkJPSAxIDw8IDEsDQotICAgIEZXTF9FVkVOVEZMQUdfQWx0S2V5CQkJPSAxIDw8IDIsDQotICAgIEZXTF9FVkVOVEZMQUdfTWV0YUtleQkJCT0gMSA8PCAzLA0KLSAgICBGV0xfRVZFTlRGTEFHX0tleVBhZAkJCT0gMSA8PCA0LA0KLSAgICBGV0xfRVZFTlRGTEFHX0F1dG9SZXBlYXQJCT0gMSA8PCA1LA0KLSAgICBGV0xfRVZFTlRGTEFHX0xlZnRCdXR0b25Eb3duCT0gMSA8PCA2LA0KLSAgICBGV0xfRVZFTlRGTEFHX01pZGRsZUJ1dHRvbkRvd24JPSAxIDw8IDcsDQotICAgIEZXTF9FVkVOVEZMQUdfUmlnaHRCdXR0b25Eb3duCT0gMSA8PCA4LCANCi19IEZXTF9FVkVOVEZMQUc7ICANCi0NCi0vLyBNb3VzZSBtZXNzYWdlIGNvbW1hbmQNCi10eXBlZGVmIGVudW0NCi17DQotCUZXTF9FVkVOVE1PVVNFQ01EX0xCdXR0b25Eb3duID0JMQksCQ0KLQlGV0xfRVZFTlRNT1VTRUNNRF9MQnV0dG9uVXAJCQksDQotCUZXTF9FVkVOVE1PVVNFQ01EX0xCdXR0b25EYmxDbGsJCSwNCi0JRldMX0VWRU5UTU9VU0VDTURfUkJ1dHRvbkRvd24JCSwNCi0JRldMX0VWRU5UTU9VU0VDTURfUkJ1dHRvblVwCQkJLA0KLQlGV0xfRVZFTlRNT1VTRUNNRF9SQnV0dG9uRGJsQ2xrCQksDQotCUZXTF9FVkVOVE1PVVNFQ01EX01CdXR0b25Eb3duCQksDQotCUZXTF9FVkVOVE1PVVNFQ01EX01CdXR0b25VcAkJCSwNCi0JRldMX0VWRU5UTU9VU0VDTURfTUJ1dHRvbkRibENsawkJLA0KLQlGV0xfRVZFTlRNT1VTRUNNRF9Nb3VzZU1vdmUJCQksDQotCUZXTF9FVkVOVE1PVVNFQ01EX01vdXNlRW50ZXIJCSwNCi0JRldMX0VWRU5UTU9VU0VDTURfTW91c2VIb3ZlcgkJLA0KLQlGV0xfRVZFTlRNT1VTRUNNRF9Nb3VzZUxlYXZlCQksDQotfSBGV0xfRVZFTlRfTU9VU0VDTUQ7DQotDQotLy9tb3VzZSBldmVudA0KLXN0cnVjdCBGV0xfRVZFTlRfTU9VU0UgDQotew0KLQlGUERGX1VJTlQzMiBjb21tYW5kOw0KLQlGUERGX0RXT1JEIGZsYWc7DQotCUZQREZfRkxPQVQgeDsNCi0JRlBERl9GTE9BVCB5Ow0KLX07DQotDQotLy9tb3VzZSB3aGVlbA0KLXN0cnVjdCBGV0xfRVZFTlRfTU9VU0VXSEVFTCANCi17CQ0KLQlGUERGX0RXT1JEIGZsYWc7DQotCUZQREZfRkxPQVQgeDsNCi0JRlBERl9GTE9BVCB5Ow0KLQlGUERGX0ZMT0FUIGRlbHRhWDsNCi0gICAgRlBERl9GTE9BVCBkZWx0YVk7ICANCi19Ow0KLQ0KLS8vdmlydHVhbCBrZXljb2RlDQotdHlwZWRlZiBlbnVtIA0KLXsNCi0gIEZXTF9WS0VZX0JhY2sJCT0gMHgwOCwNCi0gIEZXTF9WS0VZX1RhYgkJPSAweDA5LA0KLSAgRldMX1ZLRVlfQ2xlYXIJPSAweDBDLA0KLSAgRldMX1ZLRVlfUmV0dXJuCT0gMHgwRCwNCi0gIEZXTF9WS0VZX1NoaWZ0CT0gMHgxMCwNCi0gIEZXTF9WS0VZX0NvbnRyb2wJPSAweDExLA0KLSAgRldMX1ZLRVlfTWVudQkJPSAweDEyLA0KLSAgRldMX1ZLRVlfUGF1c2UJPSAweDEzLA0KLSAgRldMX1ZLRVlfQ2FwaXRhbAk9IDB4MTQsDQotICBGV0xfVktFWV9LYW5hCQk9IDB4MTUsDQotICBGV0xfVktFWV9IYW5ndWwJPSAweDE1LA0KLSAgRldMX1ZLRVlfSnVuamEJPSAweDE3LA0KLSAgRldMX1ZLRVlfRmluYWwJPSAweDE4LA0KLSAgRldMX1ZLRVlfSGFuamEJPSAweDE5LA0KLSAgRldMX1ZLRVlfS2FuamkJPSAweDE5LA0KLSAgRldMX1ZLRVlfRXNjYXBlCT0gMHgxQiwNCi0gIEZXTF9WS0VZX0NvbnZlcnQJPSAweDFDLA0KLSAgRldMX1ZLRVlfTm9uQ29udmVydCA9IDB4MUQsDQotICBGV0xfVktFWV9BY2NlcHQJID0gMHgxRSwNCi0gIEZXTF9WS0VZX01vZGVDaGFuZ2UgPSAweDFGLA0KLSAgRldMX1ZLRVlfU3BhY2UgPSAweDIwLA0KLSAgRldMX1ZLRVlfUHJpb3IgPSAweDIxLA0KLSAgRldMX1ZLRVlfTmV4dCA9IDB4MjIsDQotICBGV0xfVktFWV9FbmQgPSAweDIzLA0KLSAgRldMX1ZLRVlfSG9tZSA9IDB4MjQsDQotICBGV0xfVktFWV9MZWZ0ID0gMHgyNSwNCi0gIEZXTF9WS0VZX1VwID0gMHgyNiwNCi0gIEZXTF9WS0VZX1JpZ2h0ID0gMHgyNywNCi0gIEZXTF9WS0VZX0Rvd24gPSAweDI4LA0KLSAgRldMX1ZLRVlfU2VsZWN0ID0gMHgyOSwNCi0gIEZXTF9WS0VZX1ByaW50ID0gMHgyQSwNCi0gIEZXTF9WS0VZX0V4ZWN1dGUgPSAweDJCLA0KLSAgRldMX1ZLRVlfU25hcHNob3QgPSAweDJDLA0KLSAgRldMX1ZLRVlfSW5zZXJ0ID0gMHgyRCwNCi0gIEZXTF9WS0VZX0RlbGV0ZSA9IDB4MkUsDQotICBGV0xfVktFWV9IZWxwID0gMHgyRiwNCi0gIEZXTF9WS0VZXzAgPSAweDMwLA0KLSAgRldMX1ZLRVlfMSA9IDB4MzEsDQotICBGV0xfVktFWV8yID0gMHgzMiwNCi0gIEZXTF9WS0VZXzMgPSAweDMzLA0KLSAgRldMX1ZLRVlfNCA9IDB4MzQsDQotICBGV0xfVktFWV81ID0gMHgzNSwNCi0gIEZXTF9WS0VZXzYgPSAweDM2LA0KLSAgRldMX1ZLRVlfNyA9IDB4MzcsDQotICBGV0xfVktFWV84ID0gMHgzOCwNCi0gIEZXTF9WS0VZXzkgPSAweDM5LA0KLSAgRldMX1ZLRVlfQSA9IDB4NDEsDQotICBGV0xfVktFWV9CID0gMHg0MiwNCi0gIEZXTF9WS0VZX0MgPSAweDQzLA0KLSAgRldMX1ZLRVlfRCA9IDB4NDQsDQotICBGV0xfVktFWV9FID0gMHg0NSwNCi0gIEZXTF9WS0VZX0YgPSAweDQ2LA0KLSAgRldMX1ZLRVlfRyA9IDB4NDcsDQotICBGV0xfVktFWV9IID0gMHg0OCwNCi0gIEZXTF9WS0VZX0kgPSAweDQ5LA0KLSAgRldMX1ZLRVlfSiA9IDB4NEEsDQotICBGV0xfVktFWV9LID0gMHg0QiwNCi0gIEZXTF9WS0VZX0wgPSAweDRDLA0KLSAgRldMX1ZLRVlfTSA9IDB4NEQsDQotICBGV0xfVktFWV9OID0gMHg0RSwNCi0gIEZXTF9WS0VZX08gPSAweDRGLA0KLSAgRldMX1ZLRVlfUCA9IDB4NTAsDQotICBGV0xfVktFWV9RID0gMHg1MSwNCi0gIEZXTF9WS0VZX1IgPSAweDUyLA0KLSAgRldMX1ZLRVlfUyA9IDB4NTMsDQotICBGV0xfVktFWV9UID0gMHg1NCwNCi0gIEZXTF9WS0VZX1UgPSAweDU1LA0KLSAgRldMX1ZLRVlfViA9IDB4NTYsDQotICBGV0xfVktFWV9XID0gMHg1NywNCi0gIEZXTF9WS0VZX1ggPSAweDU4LA0KLSAgRldMX1ZLRVlfWSA9IDB4NTksDQotICBGV0xfVktFWV9aID0gMHg1QSwNCi0gIEZXTF9WS0VZX0xXaW4gPSAweDVCLA0KLSAgRldMX1ZLRVlfQ29tbWFuZCA9IDB4NUIsDQotICBGV0xfVktFWV9SV2luID0gMHg1QywNCi0gIEZXTF9WS0VZX0FwcHMgPSAweDVELA0KLSAgRldMX1ZLRVlfU2xlZXAgPSAweDVGLA0KLSAgRldMX1ZLRVlfTnVtUGFkMCA9IDB4NjAsDQotICBGV0xfVktFWV9OdW1QYWQxID0gMHg2MSwNCi0gIEZXTF9WS0VZX051bVBhZDIgPSAweDYyLA0KLSAgRldMX1ZLRVlfTnVtUGFkMyA9IDB4NjMsDQotICBGV0xfVktFWV9OdW1QYWQ0ID0gMHg2NCwNCi0gIEZXTF9WS0VZX051bVBhZDUgPSAweDY1LA0KLSAgRldMX1ZLRVlfTnVtUGFkNiA9IDB4NjYsDQotICBGV0xfVktFWV9OdW1QYWQ3ID0gMHg2NywNCi0gIEZXTF9WS0VZX051bVBhZDggPSAweDY4LA0KLSAgRldMX1ZLRVlfTnVtUGFkOSA9IDB4NjksDQotICBGV0xfVktFWV9NdWx0aXBseSA9IDB4NkEsDQotICBGV0xfVktFWV9BZGQgPSAweDZCLA0KLSAgRldMX1ZLRVlfU2VwYXJhdG9yID0gMHg2QywNCi0gIEZXTF9WS0VZX1N1YnRyYWN0ID0gMHg2RCwNCi0gIEZXTF9WS0VZX0RlY2ltYWwgPSAweDZFLA0KLSAgRldMX1ZLRVlfRGl2aWRlID0gMHg2RiwNCi0gIEZXTF9WS0VZX0YxID0gMHg3MCwNCi0gIEZXTF9WS0VZX0YyID0gMHg3MSwNCi0gIEZXTF9WS0VZX0YzID0gMHg3MiwNCi0gIEZXTF9WS0VZX0Y0ID0gMHg3MywNCi0gIEZXTF9WS0VZX0Y1ID0gMHg3NCwNCi0gIEZXTF9WS0VZX0Y2ID0gMHg3NSwNCi0gIEZXTF9WS0VZX0Y3ID0gMHg3NiwNCi0gIEZXTF9WS0VZX0Y4ID0gMHg3NywNCi0gIEZXTF9WS0VZX0Y5ID0gMHg3OCwNCi0gIEZXTF9WS0VZX0YxMCA9IDB4NzksDQotICBGV0xfVktFWV9GMTEgPSAweDdBLA0KLSAgRldMX1ZLRVlfRjEyID0gMHg3QiwNCi0gIEZXTF9WS0VZX0YxMyA9IDB4N0MsDQotICBGV0xfVktFWV9GMTQgPSAweDdELA0KLSAgRldMX1ZLRVlfRjE1ID0gMHg3RSwNCi0gIEZXTF9WS0VZX0YxNiA9IDB4N0YsDQotICBGV0xfVktFWV9GMTcgPSAweDgwLA0KLSAgRldMX1ZLRVlfRjE4ID0gMHg4MSwNCi0gIEZXTF9WS0VZX0YxOSA9IDB4ODIsDQotICBGV0xfVktFWV9GMjAgPSAweDgzLA0KLSAgRldMX1ZLRVlfRjIxID0gMHg4NCwNCi0gIEZXTF9WS0VZX0YyMiA9IDB4ODUsDQotICBGV0xfVktFWV9GMjMgPSAweDg2LA0KLSAgRldMX1ZLRVlfRjI0ID0gMHg4NywNCi0gIEZXTF9WS0VZX051bkxvY2sgPSAweDkwLA0KLSAgRldMX1ZLRVlfU2Nyb2xsID0gMHg5MSwNCi0gIEZXTF9WS0VZX0xTaGlmdCA9IDB4QTAsDQotICBGV0xfVktFWV9SU2hpZnQgPSAweEExLA0KLSAgRldMX1ZLRVlfTENvbnRyb2wgPSAweEEyLA0KLSAgRldMX1ZLRVlfUkNvbnRyb2wgPSAweEEzLA0KLSAgRldMX1ZLRVlfTE1lbnUgPSAweEE0LA0KLSAgRldMX1ZLRVlfUk1lbnUgPSAweEE1LA0KLSAgRldMX1ZLRVlfQlJPV1NFUl9CYWNrID0gMHhBNiwNCi0gIEZXTF9WS0VZX0JST1dTRVJfRm9yd2FyZCA9IDB4QTcsDQotICBGV0xfVktFWV9CUk9XU0VSX1JlZnJlc2ggPSAweEE4LA0KLSAgRldMX1ZLRVlfQlJPV1NFUl9TdG9wID0gMHhBOSwNCi0gIEZXTF9WS0VZX0JST1dTRVJfU2VhcmNoID0gMHhBQSwNCi0gIEZXTF9WS0VZX0JST1dTRVJfRmF2b3JpdGVzID0gMHhBQiwNCi0gIEZXTF9WS0VZX0JST1dTRVJfSG9tZSA9IDB4QUMsDQotICBGV0xfVktFWV9WT0xVTUVfTXV0ZSA9IDB4QUQsDQotICBGV0xfVktFWV9WT0xVTUVfRG93biA9IDB4QUUsDQotICBGV0xfVktFWV9WT0xVTUVfVXAgPSAweEFGLA0KLSAgRldMX1ZLRVlfTUVESUFfTkVYVF9UcmFjayA9IDB4QjAsDQotICBGV0xfVktFWV9NRURJQV9QUkVWX1RyYWNrID0gMHhCMSwNCi0gIEZXTF9WS0VZX01FRElBX1N0b3AgPSAweEIyLA0KLSAgRldMX1ZLRVlfTUVESUFfUExBWV9QYXVzZSA9IDB4QjMsDQotICBGV0xfVktFWV9NRURJQV9MQVVOQ0hfTWFpbCA9IDB4QjQsDQotICBGV0xfVktFWV9NRURJQV9MQVVOQ0hfTUVESUFfU2VsZWN0ID0gMHhCNSwNCi0gIEZXTF9WS0VZX01FRElBX0xBVU5DSF9BUFAxID0gMHhCNiwNCi0gIEZXTF9WS0VZX01FRElBX0xBVU5DSF9BUFAyID0gMHhCNywNCi0gIEZXTF9WS0VZX09FTV8xID0gMHhCQSwNCi0gIEZXTF9WS0VZX09FTV9QbHVzID0gMHhCQiwNCi0gIEZXTF9WS0VZX09FTV9Db21tYSA9IDB4QkMsDQotICBGV0xfVktFWV9PRU1fTWludXMgPSAweEJELA0KLSAgRldMX1ZLRVlfT0VNX1BlcmlvZCA9IDB4QkUsDQotICBGV0xfVktFWV9PRU1fMiA9IDB4QkYsDQotICBGV0xfVktFWV9PRU1fMyA9IDB4QzAsDQotICBGV0xfVktFWV9PRU1fNCA9IDB4REIsDQotICBGV0xfVktFWV9PRU1fNSA9IDB4REMsDQotICBGV0xfVktFWV9PRU1fNiA9IDB4REQsDQotICBGV0xfVktFWV9PRU1fNyA9IDB4REUsDQotICBGV0xfVktFWV9PRU1fOCA9IDB4REYsDQotICBGV0xfVktFWV9PRU1fMTAyID0gMHhFMiwNCi0gIEZXTF9WS0VZX1Byb2Nlc3NLZXkgPSAweEU1LA0KLSAgRldMX1ZLRVlfUGFja2V0ID0gMHhFNywNCi0gIEZXTF9WS0VZX0F0dG4gPSAweEY2LA0KLSAgRldMX1ZLRVlfQ3JzZWwgPSAweEY3LA0KLSAgRldMX1ZLRVlfRXhzZWwgPSAweEY4LA0KLSAgRldMX1ZLRVlfRXJlb2YgPSAweEY5LA0KLSAgRldMX1ZLRVlfUGxheSA9IDB4RkEsDQotICBGV0xfVktFWV9ab29tID0gMHhGQiwNCi0gIEZXTF9WS0VZX05vTmFtZSA9IDB4RkMsDQotICBGV0xfVktFWV9QQTEgPSAweEZELA0KLSAgRldMX1ZLRVlfT0VNX0NsZWFyID0gMHhGRSwNCi0gIEZXTF9WS0VZX1Vua25vd24gPSAwLA0KLX0gRldMX1ZLRVlDT0RFOw0KLQ0KLS8va2V5IGV2ZW50IGNvbW1hbmQNCi10eXBlZGVmIGVudW0NCi17DQotCUZXTF9FVkVOVEtFWUNNRF9LZXlEb3duID0gMQksDQotCUZXTF9FVkVOVEtFWUNNRF9LZXlVcAkJLA0KLQlGV0xfRVZFTlRLRVlDTURfQ2hhcgkJLA0KLX0gRldMX0VWRU5US0VZQ01EOw0KLQ0KLS8va2V5IGV2ZW50DQotc3RydWN0IEZXTF9FVkVOVF9LRVkNCi17DQotCUZQREZfVUlOVDMyIGNvbW1hbmQ7DQotCUZQREZfRFdPUkQgZmxhZzsNCi0JdW5pb24NCi0Jew0KLQkJLy9WaXJ0dWFsIGtleSBjb2RlLg0KLQkJRlBERl9VSU5UMzIgdmtjb2RlOw0KLQkJLy9DaGFyYWN0ZXIgY29kZS4NCi0JCUZQREZfRFdPUkQgY2hhcmNvZGU7DQotCX1jb2RlOw0KLX07DQotDQotLy9ldmVudCB0eXBlDQotc3RydWN0IEZXTF9FVkVOVCANCi17DQotCS8vc3RydWN0dXJlIHNpemUuDQotCUZQREZfVUlOVDMyIHNpemU7DQotCS8vRldMX0VWRU5UVFlQRS4NCi0gICAgRlBERl9VSU5UMzIgdHlwZTsNCi0JdW5pb24NCi0Jew0KLQkJc3RydWN0IEZXTF9FVkVOVF9NT1VTRSBtb3VzZTsNCi0JCXN0cnVjdCBGV0xfRVZFTlRfTU9VU0VXSEVFTCB3aGVlbDsNCi0JCXN0cnVjdCBGV0xfRVZFTlRfS0VZIGtleTsNCi0JfXM7DQotfTsgIA0KLQ0KLSNlbmRpZiAvL19GV0xfRVZFTlRfSA0KLQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0ZXTF9FVkVOVF9ICisjZGVmaW5lIF9GV0xfRVZFTlRfSAorCisjaW5jbHVkZSAiZnBkZnZpZXcuaCIKKwordHlwZWRlZiBpbnQJCQlGUERGX0lOVDMyOwordHlwZWRlZiB1bnNpZ25lZCBpbnQgRlBERl9VSU5UMzI7Cit0eXBlZGVmIGZsb2F0CQlGUERGX0ZMT0FUOworLy9ldmVudCB0eXBlCit0eXBlZGVmIGVudW0KK3sKKwlGV0xfRVZFTlRUWVBFX01vdXNlID0gMAksCisJRldMX0VWRU5UVFlQRV9Nb3VzZVdoZWVsLAkKKwlGV0xfRVZFTlRUWVBFX0tleQkJLAorfSBGV0xfRVZFTlRUWVBFOworCisvL2tleSBmbGFnCit0eXBlZGVmIGVudW0KK3sgICAgCisJRldMX0VWRU5URkxBR19TaGlmdEtleQkJCT0gMSA8PCAwLCAgICAKKwlGV0xfRVZFTlRGTEFHX0NvbnRyb2xLZXkJCT0gMSA8PCAxLAorICAgIEZXTF9FVkVOVEZMQUdfQWx0S2V5CQkJPSAxIDw8IDIsCisgICAgRldMX0VWRU5URkxBR19NZXRhS2V5CQkJPSAxIDw8IDMsCisgICAgRldMX0VWRU5URkxBR19LZXlQYWQJCQk9IDEgPDwgNCwKKyAgICBGV0xfRVZFTlRGTEFHX0F1dG9SZXBlYXQJCT0gMSA8PCA1LAorICAgIEZXTF9FVkVOVEZMQUdfTGVmdEJ1dHRvbkRvd24JPSAxIDw8IDYsCisgICAgRldMX0VWRU5URkxBR19NaWRkbGVCdXR0b25Eb3duCT0gMSA8PCA3LAorICAgIEZXTF9FVkVOVEZMQUdfUmlnaHRCdXR0b25Eb3duCT0gMSA8PCA4LCAKK30gRldMX0VWRU5URkxBRzsgIAorCisvLyBNb3VzZSBtZXNzYWdlIGNvbW1hbmQKK3R5cGVkZWYgZW51bQoreworCUZXTF9FVkVOVE1PVVNFQ01EX0xCdXR0b25Eb3duID0JMQksCQorCUZXTF9FVkVOVE1PVVNFQ01EX0xCdXR0b25VcAkJCSwKKwlGV0xfRVZFTlRNT1VTRUNNRF9MQnV0dG9uRGJsQ2xrCQksCisJRldMX0VWRU5UTU9VU0VDTURfUkJ1dHRvbkRvd24JCSwKKwlGV0xfRVZFTlRNT1VTRUNNRF9SQnV0dG9uVXAJCQksCisJRldMX0VWRU5UTU9VU0VDTURfUkJ1dHRvbkRibENsawkJLAorCUZXTF9FVkVOVE1PVVNFQ01EX01CdXR0b25Eb3duCQksCisJRldMX0VWRU5UTU9VU0VDTURfTUJ1dHRvblVwCQkJLAorCUZXTF9FVkVOVE1PVVNFQ01EX01CdXR0b25EYmxDbGsJCSwKKwlGV0xfRVZFTlRNT1VTRUNNRF9Nb3VzZU1vdmUJCQksCisJRldMX0VWRU5UTU9VU0VDTURfTW91c2VFbnRlcgkJLAorCUZXTF9FVkVOVE1PVVNFQ01EX01vdXNlSG92ZXIJCSwKKwlGV0xfRVZFTlRNT1VTRUNNRF9Nb3VzZUxlYXZlCQksCit9IEZXTF9FVkVOVF9NT1VTRUNNRDsKKworLy9tb3VzZSBldmVudAorc3RydWN0IEZXTF9FVkVOVF9NT1VTRSAKK3sKKwlGUERGX1VJTlQzMiBjb21tYW5kOworCUZQREZfRFdPUkQgZmxhZzsKKwlGUERGX0ZMT0FUIHg7CisJRlBERl9GTE9BVCB5OworfTsKKworLy9tb3VzZSB3aGVlbAorc3RydWN0IEZXTF9FVkVOVF9NT1VTRVdIRUVMIAorewkKKwlGUERGX0RXT1JEIGZsYWc7CisJRlBERl9GTE9BVCB4OworCUZQREZfRkxPQVQgeTsKKwlGUERGX0ZMT0FUIGRlbHRhWDsKKyAgICBGUERGX0ZMT0FUIGRlbHRhWTsgIAorfTsKKworLy92aXJ0dWFsIGtleWNvZGUKK3R5cGVkZWYgZW51bSAKK3sKKyAgRldMX1ZLRVlfQmFjawkJPSAweDA4LAorICBGV0xfVktFWV9UYWIJCT0gMHgwOSwKKyAgRldMX1ZLRVlfQ2xlYXIJPSAweDBDLAorICBGV0xfVktFWV9SZXR1cm4JPSAweDBELAorICBGV0xfVktFWV9TaGlmdAk9IDB4MTAsCisgIEZXTF9WS0VZX0NvbnRyb2wJPSAweDExLAorICBGV0xfVktFWV9NZW51CQk9IDB4MTIsCisgIEZXTF9WS0VZX1BhdXNlCT0gMHgxMywKKyAgRldMX1ZLRVlfQ2FwaXRhbAk9IDB4MTQsCisgIEZXTF9WS0VZX0thbmEJCT0gMHgxNSwKKyAgRldMX1ZLRVlfSGFuZ3VsCT0gMHgxNSwKKyAgRldMX1ZLRVlfSnVuamEJPSAweDE3LAorICBGV0xfVktFWV9GaW5hbAk9IDB4MTgsCisgIEZXTF9WS0VZX0hhbmphCT0gMHgxOSwKKyAgRldMX1ZLRVlfS2FuamkJPSAweDE5LAorICBGV0xfVktFWV9Fc2NhcGUJPSAweDFCLAorICBGV0xfVktFWV9Db252ZXJ0CT0gMHgxQywKKyAgRldMX1ZLRVlfTm9uQ29udmVydCA9IDB4MUQsCisgIEZXTF9WS0VZX0FjY2VwdAkgPSAweDFFLAorICBGV0xfVktFWV9Nb2RlQ2hhbmdlID0gMHgxRiwKKyAgRldMX1ZLRVlfU3BhY2UgPSAweDIwLAorICBGV0xfVktFWV9QcmlvciA9IDB4MjEsCisgIEZXTF9WS0VZX05leHQgPSAweDIyLAorICBGV0xfVktFWV9FbmQgPSAweDIzLAorICBGV0xfVktFWV9Ib21lID0gMHgyNCwKKyAgRldMX1ZLRVlfTGVmdCA9IDB4MjUsCisgIEZXTF9WS0VZX1VwID0gMHgyNiwKKyAgRldMX1ZLRVlfUmlnaHQgPSAweDI3LAorICBGV0xfVktFWV9Eb3duID0gMHgyOCwKKyAgRldMX1ZLRVlfU2VsZWN0ID0gMHgyOSwKKyAgRldMX1ZLRVlfUHJpbnQgPSAweDJBLAorICBGV0xfVktFWV9FeGVjdXRlID0gMHgyQiwKKyAgRldMX1ZLRVlfU25hcHNob3QgPSAweDJDLAorICBGV0xfVktFWV9JbnNlcnQgPSAweDJELAorICBGV0xfVktFWV9EZWxldGUgPSAweDJFLAorICBGV0xfVktFWV9IZWxwID0gMHgyRiwKKyAgRldMX1ZLRVlfMCA9IDB4MzAsCisgIEZXTF9WS0VZXzEgPSAweDMxLAorICBGV0xfVktFWV8yID0gMHgzMiwKKyAgRldMX1ZLRVlfMyA9IDB4MzMsCisgIEZXTF9WS0VZXzQgPSAweDM0LAorICBGV0xfVktFWV81ID0gMHgzNSwKKyAgRldMX1ZLRVlfNiA9IDB4MzYsCisgIEZXTF9WS0VZXzcgPSAweDM3LAorICBGV0xfVktFWV84ID0gMHgzOCwKKyAgRldMX1ZLRVlfOSA9IDB4MzksCisgIEZXTF9WS0VZX0EgPSAweDQxLAorICBGV0xfVktFWV9CID0gMHg0MiwKKyAgRldMX1ZLRVlfQyA9IDB4NDMsCisgIEZXTF9WS0VZX0QgPSAweDQ0LAorICBGV0xfVktFWV9FID0gMHg0NSwKKyAgRldMX1ZLRVlfRiA9IDB4NDYsCisgIEZXTF9WS0VZX0cgPSAweDQ3LAorICBGV0xfVktFWV9IID0gMHg0OCwKKyAgRldMX1ZLRVlfSSA9IDB4NDksCisgIEZXTF9WS0VZX0ogPSAweDRBLAorICBGV0xfVktFWV9LID0gMHg0QiwKKyAgRldMX1ZLRVlfTCA9IDB4NEMsCisgIEZXTF9WS0VZX00gPSAweDRELAorICBGV0xfVktFWV9OID0gMHg0RSwKKyAgRldMX1ZLRVlfTyA9IDB4NEYsCisgIEZXTF9WS0VZX1AgPSAweDUwLAorICBGV0xfVktFWV9RID0gMHg1MSwKKyAgRldMX1ZLRVlfUiA9IDB4NTIsCisgIEZXTF9WS0VZX1MgPSAweDUzLAorICBGV0xfVktFWV9UID0gMHg1NCwKKyAgRldMX1ZLRVlfVSA9IDB4NTUsCisgIEZXTF9WS0VZX1YgPSAweDU2LAorICBGV0xfVktFWV9XID0gMHg1NywKKyAgRldMX1ZLRVlfWCA9IDB4NTgsCisgIEZXTF9WS0VZX1kgPSAweDU5LAorICBGV0xfVktFWV9aID0gMHg1QSwKKyAgRldMX1ZLRVlfTFdpbiA9IDB4NUIsCisgIEZXTF9WS0VZX0NvbW1hbmQgPSAweDVCLAorICBGV0xfVktFWV9SV2luID0gMHg1QywKKyAgRldMX1ZLRVlfQXBwcyA9IDB4NUQsCisgIEZXTF9WS0VZX1NsZWVwID0gMHg1RiwKKyAgRldMX1ZLRVlfTnVtUGFkMCA9IDB4NjAsCisgIEZXTF9WS0VZX051bVBhZDEgPSAweDYxLAorICBGV0xfVktFWV9OdW1QYWQyID0gMHg2MiwKKyAgRldMX1ZLRVlfTnVtUGFkMyA9IDB4NjMsCisgIEZXTF9WS0VZX051bVBhZDQgPSAweDY0LAorICBGV0xfVktFWV9OdW1QYWQ1ID0gMHg2NSwKKyAgRldMX1ZLRVlfTnVtUGFkNiA9IDB4NjYsCisgIEZXTF9WS0VZX051bVBhZDcgPSAweDY3LAorICBGV0xfVktFWV9OdW1QYWQ4ID0gMHg2OCwKKyAgRldMX1ZLRVlfTnVtUGFkOSA9IDB4NjksCisgIEZXTF9WS0VZX011bHRpcGx5ID0gMHg2QSwKKyAgRldMX1ZLRVlfQWRkID0gMHg2QiwKKyAgRldMX1ZLRVlfU2VwYXJhdG9yID0gMHg2QywKKyAgRldMX1ZLRVlfU3VidHJhY3QgPSAweDZELAorICBGV0xfVktFWV9EZWNpbWFsID0gMHg2RSwKKyAgRldMX1ZLRVlfRGl2aWRlID0gMHg2RiwKKyAgRldMX1ZLRVlfRjEgPSAweDcwLAorICBGV0xfVktFWV9GMiA9IDB4NzEsCisgIEZXTF9WS0VZX0YzID0gMHg3MiwKKyAgRldMX1ZLRVlfRjQgPSAweDczLAorICBGV0xfVktFWV9GNSA9IDB4NzQsCisgIEZXTF9WS0VZX0Y2ID0gMHg3NSwKKyAgRldMX1ZLRVlfRjcgPSAweDc2LAorICBGV0xfVktFWV9GOCA9IDB4NzcsCisgIEZXTF9WS0VZX0Y5ID0gMHg3OCwKKyAgRldMX1ZLRVlfRjEwID0gMHg3OSwKKyAgRldMX1ZLRVlfRjExID0gMHg3QSwKKyAgRldMX1ZLRVlfRjEyID0gMHg3QiwKKyAgRldMX1ZLRVlfRjEzID0gMHg3QywKKyAgRldMX1ZLRVlfRjE0ID0gMHg3RCwKKyAgRldMX1ZLRVlfRjE1ID0gMHg3RSwKKyAgRldMX1ZLRVlfRjE2ID0gMHg3RiwKKyAgRldMX1ZLRVlfRjE3ID0gMHg4MCwKKyAgRldMX1ZLRVlfRjE4ID0gMHg4MSwKKyAgRldMX1ZLRVlfRjE5ID0gMHg4MiwKKyAgRldMX1ZLRVlfRjIwID0gMHg4MywKKyAgRldMX1ZLRVlfRjIxID0gMHg4NCwKKyAgRldMX1ZLRVlfRjIyID0gMHg4NSwKKyAgRldMX1ZLRVlfRjIzID0gMHg4NiwKKyAgRldMX1ZLRVlfRjI0ID0gMHg4NywKKyAgRldMX1ZLRVlfTnVuTG9jayA9IDB4OTAsCisgIEZXTF9WS0VZX1Njcm9sbCA9IDB4OTEsCisgIEZXTF9WS0VZX0xTaGlmdCA9IDB4QTAsCisgIEZXTF9WS0VZX1JTaGlmdCA9IDB4QTEsCisgIEZXTF9WS0VZX0xDb250cm9sID0gMHhBMiwKKyAgRldMX1ZLRVlfUkNvbnRyb2wgPSAweEEzLAorICBGV0xfVktFWV9MTWVudSA9IDB4QTQsCisgIEZXTF9WS0VZX1JNZW51ID0gMHhBNSwKKyAgRldMX1ZLRVlfQlJPV1NFUl9CYWNrID0gMHhBNiwKKyAgRldMX1ZLRVlfQlJPV1NFUl9Gb3J3YXJkID0gMHhBNywKKyAgRldMX1ZLRVlfQlJPV1NFUl9SZWZyZXNoID0gMHhBOCwKKyAgRldMX1ZLRVlfQlJPV1NFUl9TdG9wID0gMHhBOSwKKyAgRldMX1ZLRVlfQlJPV1NFUl9TZWFyY2ggPSAweEFBLAorICBGV0xfVktFWV9CUk9XU0VSX0Zhdm9yaXRlcyA9IDB4QUIsCisgIEZXTF9WS0VZX0JST1dTRVJfSG9tZSA9IDB4QUMsCisgIEZXTF9WS0VZX1ZPTFVNRV9NdXRlID0gMHhBRCwKKyAgRldMX1ZLRVlfVk9MVU1FX0Rvd24gPSAweEFFLAorICBGV0xfVktFWV9WT0xVTUVfVXAgPSAweEFGLAorICBGV0xfVktFWV9NRURJQV9ORVhUX1RyYWNrID0gMHhCMCwKKyAgRldMX1ZLRVlfTUVESUFfUFJFVl9UcmFjayA9IDB4QjEsCisgIEZXTF9WS0VZX01FRElBX1N0b3AgPSAweEIyLAorICBGV0xfVktFWV9NRURJQV9QTEFZX1BhdXNlID0gMHhCMywKKyAgRldMX1ZLRVlfTUVESUFfTEFVTkNIX01haWwgPSAweEI0LAorICBGV0xfVktFWV9NRURJQV9MQVVOQ0hfTUVESUFfU2VsZWN0ID0gMHhCNSwKKyAgRldMX1ZLRVlfTUVESUFfTEFVTkNIX0FQUDEgPSAweEI2LAorICBGV0xfVktFWV9NRURJQV9MQVVOQ0hfQVBQMiA9IDB4QjcsCisgIEZXTF9WS0VZX09FTV8xID0gMHhCQSwKKyAgRldMX1ZLRVlfT0VNX1BsdXMgPSAweEJCLAorICBGV0xfVktFWV9PRU1fQ29tbWEgPSAweEJDLAorICBGV0xfVktFWV9PRU1fTWludXMgPSAweEJELAorICBGV0xfVktFWV9PRU1fUGVyaW9kID0gMHhCRSwKKyAgRldMX1ZLRVlfT0VNXzIgPSAweEJGLAorICBGV0xfVktFWV9PRU1fMyA9IDB4QzAsCisgIEZXTF9WS0VZX09FTV80ID0gMHhEQiwKKyAgRldMX1ZLRVlfT0VNXzUgPSAweERDLAorICBGV0xfVktFWV9PRU1fNiA9IDB4REQsCisgIEZXTF9WS0VZX09FTV83ID0gMHhERSwKKyAgRldMX1ZLRVlfT0VNXzggPSAweERGLAorICBGV0xfVktFWV9PRU1fMTAyID0gMHhFMiwKKyAgRldMX1ZLRVlfUHJvY2Vzc0tleSA9IDB4RTUsCisgIEZXTF9WS0VZX1BhY2tldCA9IDB4RTcsCisgIEZXTF9WS0VZX0F0dG4gPSAweEY2LAorICBGV0xfVktFWV9DcnNlbCA9IDB4RjcsCisgIEZXTF9WS0VZX0V4c2VsID0gMHhGOCwKKyAgRldMX1ZLRVlfRXJlb2YgPSAweEY5LAorICBGV0xfVktFWV9QbGF5ID0gMHhGQSwKKyAgRldMX1ZLRVlfWm9vbSA9IDB4RkIsCisgIEZXTF9WS0VZX05vTmFtZSA9IDB4RkMsCisgIEZXTF9WS0VZX1BBMSA9IDB4RkQsCisgIEZXTF9WS0VZX09FTV9DbGVhciA9IDB4RkUsCisgIEZXTF9WS0VZX1Vua25vd24gPSAwLAorfSBGV0xfVktFWUNPREU7CisKKy8va2V5IGV2ZW50IGNvbW1hbmQKK3R5cGVkZWYgZW51bQoreworCUZXTF9FVkVOVEtFWUNNRF9LZXlEb3duID0gMQksCisJRldMX0VWRU5US0VZQ01EX0tleVVwCQksCisJRldMX0VWRU5US0VZQ01EX0NoYXIJCSwKK30gRldMX0VWRU5US0VZQ01EOworCisvL2tleSBldmVudAorc3RydWN0IEZXTF9FVkVOVF9LRVkKK3sKKwlGUERGX1VJTlQzMiBjb21tYW5kOworCUZQREZfRFdPUkQgZmxhZzsKKwl1bmlvbgorCXsKKwkJLy9WaXJ0dWFsIGtleSBjb2RlLgorCQlGUERGX1VJTlQzMiB2a2NvZGU7CisJCS8vQ2hhcmFjdGVyIGNvZGUuCisJCUZQREZfRFdPUkQgY2hhcmNvZGU7CisJfWNvZGU7Cit9OworCisvL2V2ZW50IHR5cGUKK3N0cnVjdCBGV0xfRVZFTlQgCit7CisJLy9zdHJ1Y3R1cmUgc2l6ZS4KKwlGUERGX1VJTlQzMiBzaXplOworCS8vRldMX0VWRU5UVFlQRS4KKyAgICBGUERGX1VJTlQzMiB0eXBlOworCXVuaW9uCisJeworCQlzdHJ1Y3QgRldMX0VWRU5UX01PVVNFIG1vdXNlOworCQlzdHJ1Y3QgRldMX0VWRU5UX01PVVNFV0hFRUwgd2hlZWw7CisJCXN0cnVjdCBGV0xfRVZFTlRfS0VZIGtleTsKKwl9czsKK307ICAKKworI2VuZGlmIC8vX0ZXTF9FVkVOVF9ICisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfcHJvZ3Jlc3NpdmUuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mcGRmX3Byb2dyZXNzaXZlLmgKaW5kZXggZDU5MGY3OC4uMDI5MjY0ZSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfcHJvZ3Jlc3NpdmUuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnBkZl9wcm9ncmVzc2l2ZS5oCkBAIC0xLDk0ICsxLDk0IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GUERGX1BST0dSRVNTSVZFX0hfDQotI2RlZmluZSBfRlBERl9QUk9HUkVTU0lWRV9IXw0KLQ0KLSNpbmNsdWRlICJmcGRmdmlldy5oIg0KLQ0KLS8vRmxhZ3MgZm9yIHByb2dyZXNzaXZlIHByb2Nlc3Mgc3RhdHVzLg0KLSNkZWZpbmUgRlBERl9SRU5ERVJfUkVBREVSCQkJMA0KLSNkZWZpbmUgRlBERl9SRU5ERVJfVE9CRUNPVU5USU5VRUQJMQ0KLSNkZWZpbmUgRlBERl9SRU5ERVJfRE9ORQkJCTINCi0jZGVmaW5lIEZQREZfUkVOREVSX0ZBSUxFRAkJCTMNCi0NCi0NCi0jaWZkZWYgX19jcGx1c3BsdXMNCi1leHRlcm4gIkMiIHsNCi0jZW5kaWYNCi0NCi0NCi0vL0lGUERGX1JFTkRFUklORk8gaW50ZXJmYWNlLg0KLXR5cGVkZWYgc3RydWN0IF9JRlNES19QQVVTRQ0KLXsNCi0JLyoqDQotCSogVmVyc2lvbiBudW1iZXIgb2YgdGhlIGludGVyZmFjZS4gQ3VycmVudGx5IG11c3QgYmUgMS4NCi0JKiovDQotCWludCB2ZXJzaW9uOw0KLQ0KLQkvKg0KLQkqIE1ldGhvZDogTmVlZFRvUGF1c2VOb3cNCi0JKgkJCUNoZWNrIGlmIHdlIG5lZWQgdG8gcGF1c2UgYSBwcm9ncmVzc2l2ZSBwcm9jZXNzIG5vdy4NCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCXllcw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZg0KLQkqIFJldHVybiBWYWx1ZToNCi0JKgkJCSBOb24temVybyBmb3IgcGF1c2Ugbm93LCAwIGZvciBjb250aW51ZS4NCi0JKg0KLQkqLw0KLQlGUERGX0JPT0wgKCpOZWVkVG9QYXVzZU5vdykgKHN0cnVjdCBfSUZTREtfUEFVU0UqIHBUaGlzKTsNCi0JDQotCS8vQSB1c2VyIGRlZmluZWQgZGF0YSBwb2ludGVyLCB1c2VkIGJ5IHVzZXIncyBhcHBsaWNhdGlvbi4gQ2FuIGJlIE5VTEwuDQotCXZvaWQqCQl1c2VyOw0KLX0gSUZTREtfUEFVU0U7DQotDQotLy8gRnVuY3Rpb246IEZQREZfUmVuZGVyUGFnZUJpdG1hcF9TdGFydA0KLS8vCQkJU3RhcnQgdG8gcmVuZGVyIHBhZ2UgY29udGVudHMgdG8gYSBkZXZpY2UgaW5kZXBlbmRlbnQgYml0bWFwIHByb2dyZXNzaXZlbHkuDQotLy8gUGFyYW1ldGVyczogDQotLy8JCQliaXRtYXAJCS0JSGFuZGxlIHRvIHRoZSBkZXZpY2UgaW5kZXBlbmRlbnQgYml0bWFwIChhcyB0aGUgb3V0cHV0IGJ1ZmZlcikuDQotLy8JCQkJCQkJQml0bWFwIGhhbmRsZSBjYW4gYmUgY3JlYXRlZCBieSBGUERGQml0bWFwX0NyZWF0ZSBmdW5jdGlvbi4NCi0vLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vCQkJc3RhcnRfeAkJLQlMZWZ0IHBpeGVsIHBvc2l0aW9uIG9mIHRoZSBkaXNwbGF5IGFyZWEgaW4gdGhlIGJpdG1hcCBjb29yZGluYXRlLg0KLS8vCQkJc3RhcnRfeQkJLQlUb3AgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgYml0bWFwIGNvb3JkaW5hdGUuDQotLy8JCQlzaXplX3gJCS0JSG9yaXpvbnRhbCBzaXplIChpbiBwaXhlbHMpIGZvciBkaXNwbGF5aW5nIHRoZSBwYWdlLg0KLS8vCQkJc2l6ZV95CQktCVZlcnRpY2FsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuDQotLy8JCQlyb3RhdGUJCS0JUGFnZSBvcmllbnRhdGlvbjogMCAobm9ybWFsKSwgMSAocm90YXRlZCA5MCBkZWdyZWVzIGNsb2Nrd2lzZSksDQotLy8JCQkJCQkJCTIgKHJvdGF0ZWQgMTgwIGRlZ3JlZXMpLCAzIChyb3RhdGVkIDkwIGRlZ3JlZXMgY291bnRlci1jbG9ja3dpc2UpLg0KLS8vCQkJZmxhZ3MJCS0JMCBmb3Igbm9ybWFsIGRpc3BsYXksIG9yIGNvbWJpbmF0aW9uIG9mIGZsYWdzIGRlZmluZWQgYWJvdmUuDQotLy8JCQlwYXVzZQkJLQlUaGUgSUZTREtfUEFVU0UgaW50ZXJmYWNlLkEgY2FsbGJhY2sgbWVjaGFuaXNtIGFsbG93aW5nIHRoZSBwYWdlIHJlbmRlcmluZyBwcm9jZXNzDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJUmVuZGVyaW5nIFN0YXR1cy4gU2VlIGZsYWdzIGZvciBwcm9ncmVzc2l2ZSBwcm9jZXNzIHN0YXR1cyBmb3IgdGhlIGRldGFpbHMuDQotLy8NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERl9SZW5kZXJQYWdlQml0bWFwX1N0YXJ0KEZQREZfQklUTUFQIGJpdG1hcCwgRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwNCi0JCQkJCQkJCQkJCQkgICBpbnQgc2l6ZV95LCBpbnQgcm90YXRlLCBpbnQgZmxhZ3MsSUZTREtfUEFVU0UgKiBwYXVzZSk7DQotDQotLy8gRnVuY3Rpb246IEZQREZfUmVuZGVyUGFnZV9Db250aW51ZQ0KLS8vCQkJQ29udGludWUgcmVuZGVyaW5nIGEgUERGIHBhZ2UuDQotLy8gUGFyYW1ldGVyczogDQotLy8JCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0vLwkJCXBhdXNlCQktCVRoZSBJRlNES19QQVVTRSBpbnRlcmZhY2UuQSBjYWxsYmFjayBtZWNoYW5pc20gYWxsb3dpbmcgdGhlIHBhZ2UgcmVuZGVyaW5nIHByb2Nlc3MNCi0vLwkJCQkJCQl0byBiZSBwYXVzZWQgYmVmb3JlIGl0J3MgZmluaXNoZWQuIFRoaXMgY2FuIGJlIE5VTEwgaWYgeW91IGRvbid0IHdhbnQgdG8gcGF1c2UuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVGhlIHJlbmRlcmluZyBzdGF0dXMuIFNlZSBmbGFncyBmb3IgcHJvZ3Jlc3NpdmUgcHJvY2VzcyBzdGF0dXMgZm9yIHRoZSBkZXRhaWxzLg0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2VfQ29udGludWUoRlBERl9QQUdFIHBhZ2UsSUZTREtfUEFVU0UgKiBwYXVzZSk7DQotDQotLy8gRnVuY3Rpb246IEZQREZfUmVuZGVyUGFnZV9DbG9zZQ0KLS8vCQkJUmVsZWFzZSB0aGUgcmVzb3VyY2UgYWxsb2NhdGUgZHVyaW5nIHBhZ2UgcmVuZGVyaW5nLiBOZWVkIHRvIGJlIGNhbGxlZCBhZnRlciBmaW5pc2hpbmcgcmVuZGVyaW5nIG9yDQotLy8JCQljYW5jZWwgdGhlIHJlbmRlcmluZy4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCU5VTEwNCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfUmVuZGVyUGFnZV9DbG9zZShGUERGX1BBR0UgcGFnZSk7DQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfQ0KLSNlbmRpZg0KLQ0KLSNlbmRpZgkvL19GUERGX1BST0dSRVNTSVZFX0hfDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRlBERl9QUk9HUkVTU0lWRV9IXworI2RlZmluZSBfRlBERl9QUk9HUkVTU0lWRV9IXworCisjaW5jbHVkZSAiZnBkZnZpZXcuaCIKKworLy9GbGFncyBmb3IgcHJvZ3Jlc3NpdmUgcHJvY2VzcyBzdGF0dXMuCisjZGVmaW5lIEZQREZfUkVOREVSX1JFQURFUgkJCTAKKyNkZWZpbmUgRlBERl9SRU5ERVJfVE9CRUNPVU5USU5VRUQJMQorI2RlZmluZSBGUERGX1JFTkRFUl9ET05FCQkJMgorI2RlZmluZSBGUERGX1JFTkRFUl9GQUlMRUQJCQkzCisKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisKKy8vSUZQREZfUkVOREVSSU5GTyBpbnRlcmZhY2UuCit0eXBlZGVmIHN0cnVjdCBfSUZTREtfUEFVU0UKK3sKKwkvKioKKwkqIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcmZhY2UuIEN1cnJlbnRseSBtdXN0IGJlIDEuCisJKiovCisJaW50IHZlcnNpb247CisKKwkvKgorCSogTWV0aG9kOiBOZWVkVG9QYXVzZU5vdworCSoJCQlDaGVjayBpZiB3ZSBuZWVkIHRvIHBhdXNlIGEgcHJvZ3Jlc3NpdmUgcHJvY2VzcyBub3cuCisJKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkqCQkJMQorCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJKgkJCXllcworCSogUGFyYW1ldGVyczoKKwkqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYKKwkqIFJldHVybiBWYWx1ZToKKwkqCQkJIE5vbi16ZXJvIGZvciBwYXVzZSBub3csIDAgZm9yIGNvbnRpbnVlLgorCSoKKwkqLworCUZQREZfQk9PTCAoKk5lZWRUb1BhdXNlTm93KSAoc3RydWN0IF9JRlNES19QQVVTRSogcFRoaXMpOworCQorCS8vQSB1c2VyIGRlZmluZWQgZGF0YSBwb2ludGVyLCB1c2VkIGJ5IHVzZXIncyBhcHBsaWNhdGlvbi4gQ2FuIGJlIE5VTEwuCisJdm9pZCoJCXVzZXI7Cit9IElGU0RLX1BBVVNFOworCisvLyBGdW5jdGlvbjogRlBERl9SZW5kZXJQYWdlQml0bWFwX1N0YXJ0CisvLwkJCVN0YXJ0IHRvIHJlbmRlciBwYWdlIGNvbnRlbnRzIHRvIGEgZGV2aWNlIGluZGVwZW5kZW50IGJpdG1hcCBwcm9ncmVzc2l2ZWx5LgorLy8gUGFyYW1ldGVyczogCisvLwkJCWJpdG1hcAkJLQlIYW5kbGUgdG8gdGhlIGRldmljZSBpbmRlcGVuZGVudCBiaXRtYXAgKGFzIHRoZSBvdXRwdXQgYnVmZmVyKS4KKy8vCQkJCQkJCUJpdG1hcCBoYW5kbGUgY2FuIGJlIGNyZWF0ZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uCisvLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8JCQlzdGFydF94CQktCUxlZnQgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgYml0bWFwIGNvb3JkaW5hdGUuCisvLwkJCXN0YXJ0X3kJCS0JVG9wIHBpeGVsIHBvc2l0aW9uIG9mIHRoZSBkaXNwbGF5IGFyZWEgaW4gdGhlIGJpdG1hcCBjb29yZGluYXRlLgorLy8JCQlzaXplX3gJCS0JSG9yaXpvbnRhbCBzaXplIChpbiBwaXhlbHMpIGZvciBkaXNwbGF5aW5nIHRoZSBwYWdlLgorLy8JCQlzaXplX3kJCS0JVmVydGljYWwgc2l6ZSAoaW4gcGl4ZWxzKSBmb3IgZGlzcGxheWluZyB0aGUgcGFnZS4KKy8vCQkJcm90YXRlCQktCVBhZ2Ugb3JpZW50YXRpb246IDAgKG5vcm1hbCksIDEgKHJvdGF0ZWQgOTAgZGVncmVlcyBjbG9ja3dpc2UpLAorLy8JCQkJCQkJCTIgKHJvdGF0ZWQgMTgwIGRlZ3JlZXMpLCAzIChyb3RhdGVkIDkwIGRlZ3JlZXMgY291bnRlci1jbG9ja3dpc2UpLgorLy8JCQlmbGFncwkJLQkwIGZvciBub3JtYWwgZGlzcGxheSwgb3IgY29tYmluYXRpb24gb2YgZmxhZ3MgZGVmaW5lZCBhYm92ZS4KKy8vCQkJcGF1c2UJCS0JVGhlIElGU0RLX1BBVVNFIGludGVyZmFjZS5BIGNhbGxiYWNrIG1lY2hhbmlzbSBhbGxvd2luZyB0aGUgcGFnZSByZW5kZXJpbmcgcHJvY2VzcworLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlSZW5kZXJpbmcgU3RhdHVzLiBTZWUgZmxhZ3MgZm9yIHByb2dyZXNzaXZlIHByb2Nlc3Mgc3RhdHVzIGZvciB0aGUgZGV0YWlscy4KKy8vCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERl9SZW5kZXJQYWdlQml0bWFwX1N0YXJ0KEZQREZfQklUTUFQIGJpdG1hcCwgRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwKKwkJCQkJCQkJCQkJCSAgIGludCBzaXplX3ksIGludCByb3RhdGUsIGludCBmbGFncyxJRlNES19QQVVTRSAqIHBhdXNlKTsKKworLy8gRnVuY3Rpb246IEZQREZfUmVuZGVyUGFnZV9Db250aW51ZQorLy8JCQlDb250aW51ZSByZW5kZXJpbmcgYSBQREYgcGFnZS4KKy8vIFBhcmFtZXRlcnM6IAorLy8JCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4KKy8vCQkJcGF1c2UJCS0JVGhlIElGU0RLX1BBVVNFIGludGVyZmFjZS5BIGNhbGxiYWNrIG1lY2hhbmlzbSBhbGxvd2luZyB0aGUgcGFnZSByZW5kZXJpbmcgcHJvY2VzcworLy8JCQkJCQkJdG8gYmUgcGF1c2VkIGJlZm9yZSBpdCdzIGZpbmlzaGVkLiBUaGlzIGNhbiBiZSBOVUxMIGlmIHlvdSBkb24ndCB3YW50IHRvIHBhdXNlLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUaGUgcmVuZGVyaW5nIHN0YXR1cy4gU2VlIGZsYWdzIGZvciBwcm9ncmVzc2l2ZSBwcm9jZXNzIHN0YXR1cyBmb3IgdGhlIGRldGFpbHMuCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERl9SZW5kZXJQYWdlX0NvbnRpbnVlKEZQREZfUEFHRSBwYWdlLElGU0RLX1BBVVNFICogcGF1c2UpOworCisvLyBGdW5jdGlvbjogRlBERl9SZW5kZXJQYWdlX0Nsb3NlCisvLwkJCVJlbGVhc2UgdGhlIHJlc291cmNlIGFsbG9jYXRlIGR1cmluZyBwYWdlIHJlbmRlcmluZy4gTmVlZCB0byBiZSBjYWxsZWQgYWZ0ZXIgZmluaXNoaW5nIHJlbmRlcmluZyBvcgorLy8JCQljYW5jZWwgdGhlIHJlbmRlcmluZy4KKy8vIFBhcmFtZXRlcnM6IAorLy8JCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTlVMTAorRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2VfQ2xvc2UoRlBERl9QQUdFIHBhZ2UpOworCisjaWZkZWYgX19jcGx1c3BsdXMKK30KKyNlbmRpZgorCisjZW5kaWYJLy9fRlBERl9QUk9HUkVTU0lWRV9IXwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfc2VhcmNoZXguaCBiL2ZwZGZzZGsvaW5jbHVkZS9mcGRmX3NlYXJjaGV4LmgKaW5kZXggYzI5MWMwYy4uZDcwZGRkYyAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfc2VhcmNoZXguaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnBkZl9zZWFyY2hleC5oCkBAIC0xLDMzICsxLDMzIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GUERGX1NFQVJDSF9FWF9IDQotI2RlZmluZSBfRlBERl9TRUFSQ0hfRVhfSA0KLQkNCi0jaWZuZGVmIF9GUERGVklFV19IXw0KLSNpbmNsdWRlICJmcGRmdmlldy5oIg0KLSNlbmRpZg0KLQ0KLSNpZmRlZiBfX2NwbHVzcGx1cw0KLWV4dGVybiAiQyIgew0KLSNlbmRpZg0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGVGV4dF9HZXRDaGFySW5kZXhGcm9tVGV4dEluZGV4DQotLy8JCUdldCB0aGUgYWN0dWFsbHkgY2hhciBpbmRleCBpbiB0ZXh0X3BhZ2UncyBpbnRlcm5hbCBjaGFyIGxpc3QuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCXRleHRfcGFnZQktIAlIYW5kbGUgdG8gYSB0ZXh0IHBhZ2UgaW5mb3JtYXRpb24gc3RydWN0dXJlLiBSZXR1cm5lZCBieSBGUERGVGV4dF9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0vLwkJCW5UZXh0SW5kZXgJLQlUaGUgaW5kZXggb2YgdGhlIHRleHQgaW4gdGhlIHN0cmluZyBnZXQgZnJvbSBGUERGVGV4dF9HZXRUZXh0Lg0KLS8vCVJldHVybiB2YWx1ZToNCi0vLwkJCVRoZSBpbmRleCBvZiB0aGUgY2hhcmFjdGVyIGluIGludGVybmFsIGNoYXJsaXN0LiAtMSBmb3IgZXJyb3IuDQotRExMRVhQT1JUIGludCBTVERDQUxMICBGUERGVGV4dF9HZXRDaGFySW5kZXhGcm9tVGV4dEluZGV4KEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLCBpbnQgblRleHRJbmRleCk7DQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfTsNCi0jZW5kaWYNCi0NCi0NCi0jZW5kaWYNCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GUERGX1NFQVJDSF9FWF9ICisjZGVmaW5lIF9GUERGX1NFQVJDSF9FWF9ICisJCisjaWZuZGVmIF9GUERGVklFV19IXworI2luY2x1ZGUgImZwZGZ2aWV3LmgiCisjZW5kaWYKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvLyBGdW5jdGlvbjogRlBERlRleHRfR2V0Q2hhckluZGV4RnJvbVRleHRJbmRleAorLy8JCUdldCB0aGUgYWN0dWFsbHkgY2hhciBpbmRleCBpbiB0ZXh0X3BhZ2UncyBpbnRlcm5hbCBjaGFyIGxpc3QuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQl0ZXh0X3BhZ2UJLSAJSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLwkJCW5UZXh0SW5kZXgJLQlUaGUgaW5kZXggb2YgdGhlIHRleHQgaW4gdGhlIHN0cmluZyBnZXQgZnJvbSBGUERGVGV4dF9HZXRUZXh0LgorLy8JUmV0dXJuIHZhbHVlOgorLy8JCQlUaGUgaW5kZXggb2YgdGhlIGNoYXJhY3RlciBpbiBpbnRlcm5hbCBjaGFybGlzdC4gLTEgZm9yIGVycm9yLgorRExMRVhQT1JUIGludCBTVERDQUxMICBGUERGVGV4dF9HZXRDaGFySW5kZXhGcm9tVGV4dEluZGV4KEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLCBpbnQgblRleHRJbmRleCk7CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfTsKKyNlbmRpZgorCisKKyNlbmRpZgorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZnBkZl90cmFuc2Zvcm1wYWdlLmggYi9mcGRmc2RrL2luY2x1ZGUvZnBkZl90cmFuc2Zvcm1wYWdlLmgKaW5kZXggY2FhZmVkYS4uNjlmZmUyNCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZfdHJhbnNmb3JtcGFnZS5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9mcGRmX3RyYW5zZm9ybXBhZ2UuaApAQCAtMSwxMTMgKzEsMTEzIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9UUkFOU0ZPUk1QQUdFX0hfDQotI2RlZmluZSBfVFJBTlNGT1JNUEFHRV9IXw0KLQ0KLSNpZm5kZWYgX0ZQREZWSUVXX0hfDQotI2luY2x1ZGUgImZwZGZ2aWV3LmgiDQotI2VuZGlmDQotDQotdHlwZWRlZiB2b2lkKiBGUERGX1BBR0VBUkNTQVZFUjsNCi10eXBlZGVmIHZvaWQqIEZQREZfUEFHRUFSQ0xPQURFUjsNCi0vKioNCi0qICBTZXQgIk1lZGlhQm94IiBlbnRyeSB0byB0aGUgcGFnZSBkaWN0aW9uYXJ5LgkJCQkJCSAgIA0KLSogQHBhcmFtW2luXSBwYWdlCS0gSGFuZGxlIHRvIGEgcGFnZS4NCi0qIEBwYXJhbVtpbl0gbGVmdAktIFRoZSBsZWZ0IG9mIHRoZSByZWN0YW5nbGUuDQotKiBAcGFyYW1baW5dIGJvdHRvbQktIFRoZSBib3R0b20gb2YgdGhlIHJlY3RhbmdsZS4NCi0qIEBwYXJhbVtpbl0gcmlnaHQJLSBUaGUgcmlnaHQgb2YgdGhlIHJlY3RhbmdsZS4NCi0qIEBwYXJhbVtpbl0gdG9wCS0gVGhlIHRvcCBvZiB0aGUgcmVjdGFuZ2xlLg0KLSogQHJldHZhbCBOb25lLg0KLSovDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGUGFnZV9TZXRNZWRpYUJveChGUERGX1BBR0UgcGFnZSwgZmxvYXQgbGVmdCwgZmxvYXQgYm90dG9tLCBmbG9hdCByaWdodCwgZmxvYXQgdG9wKTsNCi0NCi0vKioNCi0qICBTZXQgIkNyb3BCb3giIGVudHJ5IHRvIHRoZSBwYWdlIGRpY3Rpb25hcnkuCQkJCQkJICAgDQotKiBAcGFyYW1baW5dIHBhZ2UJLSBIYW5kbGUgdG8gYSBwYWdlLg0KLSogQHBhcmFtW2luXSBsZWZ0CS0gVGhlIGxlZnQgb2YgdGhlIHJlY3RhbmdsZS4NCi0qIEBwYXJhbVtpbl0gYm90dG9tCS0gVGhlIGJvdHRvbSBvZiB0aGUgcmVjdGFuZ2xlLg0KLSogQHBhcmFtW2luXSByaWdodAktIFRoZSByaWdodCBvZiB0aGUgcmVjdGFuZ2xlLg0KLSogQHBhcmFtW2luXSB0b3AJLSBUaGUgdG9wIG9mIHRoZSByZWN0YW5nbGUuDQotKiBAcmV0dmFsIE5vbmUuDQotKi8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX1NldENyb3BCb3goRlBERl9QQUdFIHBhZ2UsIGZsb2F0IGxlZnQsIGZsb2F0IGJvdHRvbSwgZmxvYXQgcmlnaHQsIGZsb2F0IHRvcCk7DQotDQotDQotLyoqICBHZXQgIk1lZGlhQm94IiBlbnRyeSBmcm9tIHRoZSBwYWdlIGRpY3Rpb25hcnkuCQkJCQkJICAgDQotKiBAcGFyYW1baW5dIHBhZ2UJLSBIYW5kbGUgdG8gYSBwYWdlLg0KLSogQHBhcmFtW2luXSBsZWZ0CS0gUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIGxlZnQgb2YgdGhlIHJlY3RhbmdsZS4NCi0qIEBwYXJhbVtpbl0gYm90dG9tCS0gUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIGJvdHRvbSBvZiB0aGUgcmVjdGFuZ2xlLg0KLSogQHBhcmFtW2luXSByaWdodAktIFBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSByaWdodCBvZiB0aGUgcmVjdGFuZ2xlLg0KLSogQHBhcmFtW2luXSB0b3AJLSBQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgdG9wIG9mIHRoZSByZWN0YW5nbGUuDQotKiBAcmV0dmFsIFRydWUgaWYgc3VjY2VzcyxlbHNlIGZhaWwuDQotKi8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VfR2V0TWVkaWFCb3goRlBERl9QQUdFIHBhZ2UsIGZsb2F0KiBsZWZ0LCBmbG9hdCogYm90dG9tLCBmbG9hdCogcmlnaHQsIGZsb2F0KiB0b3ApOw0KLQ0KLS8qKiAgR2V0ICJDcm9wQm94IiBlbnRyeSBmcm9tIHRoZSBwYWdlIGRpY3Rpb25hcnkuCQkJCQkJICAgDQotKiBAcGFyYW1baW5dIHBhZ2UJLSBIYW5kbGUgdG8gYSBwYWdlLg0KLSogQHBhcmFtW2luXSBsZWZ0CS0gUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIGxlZnQgb2YgdGhlIHJlY3RhbmdsZS4NCi0qIEBwYXJhbVtpbl0gYm90dG9tCS0gUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIGJvdHRvbSBvZiB0aGUgcmVjdGFuZ2xlLg0KLSogQHBhcmFtW2luXSByaWdodAktIFBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSByaWdodCBvZiB0aGUgcmVjdGFuZ2xlLg0KLSogQHBhcmFtW2luXSB0b3AJLSBQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgdG9wIG9mIHRoZSByZWN0YW5nbGUuDQotKiBAcmV0dmFsIFRydWUgaWYgc3VjY2VzcyxlbHNlIGZhaWwuDQotKi8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VfR2V0Q3JvcEJveChGUERGX1BBR0UgcGFnZSwgZmxvYXQqIGxlZnQsIGZsb2F0KiBib3R0b20sIGZsb2F0KiByaWdodCwgZmxvYXQqIHRvcCk7DQotDQotLyoqDQotKiBUcmFuc2Zvcm0gdGhlIHdob2xlIHBhZ2Ugd2l0aCBhIHNwZWNpZmllZCBtYXRyaXgsIHRoZW4gY2xpcCB0aGUgcGFnZSBjb250ZW50IHJlZ2lvbi4NCi0qDQotKiBAcGFyYW1baW5dIHBhZ2UJCSAtIEEgcGFnZSBoYW5kbGUuDQotKiBAcGFyYW1baW5dIG1hdHJpeAkJIC0gVGhlIHRyYW5zZm9ybSBtYXRyaXguDQotKiBAcGFyYW1baW5dIGNsaXBSZWN0CSAtIEEgcmVjdGFuZ2xlIHBhZ2UgYXJlYSB0byBiZSBjbGlwcGVkLg0KLSogQE5vdGUuIFRoaXMgZnVuY3Rpb24gd2lsbCB0cmFuc2Zvcm0gdGhlIHdob2xlIHBhZ2UsIGFuZCB3b3VsZCB0YWtlIGVmZmVjdCB0byBhbGwgdGhlIG9iamVjdHMgaW4gdGhlIHBhZ2UuDQotKi8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VfVHJhbnNGb3JtV2l0aENsaXAoRlBERl9QQUdFIHBhZ2UsIEZTX01BVFJJWCogbWF0cml4LCBGU19SRUNURiogY2xpcFJlY3QpOw0KLQ0KLS8qKg0KLSogVHJhbnNmb3JtIChzY2FsZSwgcm90YXRlLCBzaGVhciwgbW92ZSkgdGhlIGNsaXAgcGF0aCBvZiBwYWdlIG9iamVjdC4NCi0qIEBwYXJhbVtpbl0gcGFnZV9vYmplY3QgLSBIYW5kbGUgdG8gYSBwYWdlIG9iamVjdC4gUmV0dXJuZWQgYnkgRlBERlBhZ2VPYmpfTmV3SW1hZ2VPYmouDQotKiBAcGFyYW1baW5dIGEJLSBUaGUgY29lZmZpY2llbnQgImEiIG9mIHRoZSBtYXRyaXguDQotKiBAcGFyYW1baW5dIGIJLSBUaGUgY29lZmZpY2llbnQgImIiIG9mIHRoZSBtYXRyaXguDQotKiBAcGFyYW1baW5dIGMJLSBUaGUgY29lZmZpY2llbnQgImMiIG9mIHRoZSBtYXRyaXguDQotKiBAcGFyYW1baW5dIGQJLSBUaGUgY29lZmZpY2llbnQgImQiIG9mIHRoZSBtYXRyaXguDQotKiBAcGFyYW1baW5dIGUJLSBUaGUgY29lZmZpY2llbnQgImUiIG9mIHRoZSBtYXRyaXguDQotKiBAcGFyYW1baW5dIGYJLSBUaGUgY29lZmZpY2llbnQgImYiIG9mIHRoZSBtYXRyaXguDQotKiBAcmV0dmFsIE5vbmUuDQotKi8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlT2JqX1RyYW5zZm9ybUNsaXBQYXRoKEZQREZfUEFHRU9CSkVDVCBwYWdlX29iamVjdCxkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKTsNCi0NCi0vKioNCi0qIENyZWF0ZSBhIG5ldyBjbGlwIHBhdGgsIHdpdGggYSByZWN0YW5nbGUgaW5zZXJ0ZWQuDQotKiANCi0qIEBwYXJhbVtpbl0gbGVmdAktIFRoZSBsZWZ0IG9mIHRoZSBjbGlwIGJveC4NCi0qIEBwYXJhbVtpbl0gYm90dG9tIC0gVGhlIGJvdHRvbSBvZiB0aGUgY2xpcCBib3guDQotKiBAcGFyYW1baW5dIHJpZ2h0CS0gVGhlIHJpZ2h0IG9mIHRoZSBjbGlwIGJveC4NCi0qIEBwYXJhbVtpbl0gdG9wCS0gVGhlIHRvcCBvZiB0aGUgY2xpcCBib3guDQotKiBAcmV0dmFsIGEgaGFuZGxlIHRvIHRoZSBjbGlwIHBhdGguDQotKi8NCi1ETExFWFBPUlQgRlBERl9DTElQUEFUSCBTVERDQUxMIEZQREZfQ3JlYXRlQ2xpcFBhdGgoZmxvYXQgbGVmdCwgZmxvYXQgYm90dG9tLCBmbG9hdCByaWdodCwgZmxvYXQgdG9wKTsNCi0NCi0vKioNCi0qIERlc3Ryb3kgdGhlIGNsaXAgcGF0aC4NCi0qDQotKiBAcGFyYW1baW5dIGNsaXBQYXRoIC0gQSBoYW5kbGUgdG8gdGhlIGNsaXAgcGF0aC4NCi0qIERlc3Ryb3kgdGhlIGNsaXAgcGF0aC4NCi0qIEByZXR2YWwgTm9uZS4NCi0qLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9EZXN0cm95Q2xpcFBhdGgoRlBERl9DTElQUEFUSCBjbGlwUGF0aCk7DQotDQotLyoqDQotKiBDbGlwIHRoZSBwYWdlIGNvbnRlbnQsIHRoZSBwYWdlIGNvbnRlbnQgdGhhdCBvdXRzaWRlIHRoZSBjbGlwcGluZyByZWdpb24gYmVjb21lIGludmlzaWJsZS4NCi0qDQotKiBAcGFyYW1baW5dIHBhZ2UJCSAtIEEgcGFnZSBoYW5kbGUuDQotKiBAcGFyYW1baW5dIGNsaXBQYXRoCSAtIEEgaGFuZGxlIHRvIHRoZSBjbGlwIHBhdGguDQotKiBATm90ZS4gQSBjbGlwIHBhdGggd2lsbCBiZSBpbnNlcnRlZCBiZWZvcmUgdGhlIHBhZ2UgY29udGVudCBzdHJlYW0gb3IgY29udGVudCBhcnJheS4gSW4gdGhpcyB3YXksIHRoZSBwYWdlIGNvbnRlbnQgd2lsbCBiZSBjbGlwcGVkDQotKiBieSB0aGlzIGNsaXAgcGF0aC4gDQotKi8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX0luc2VydENsaXBQYXRoKEZQREZfUEFHRSBwYWdlLEZQREZfQ0xJUFBBVEggY2xpcFBhdGgpOw0KLQ0KLSNlbmRpZg0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1RSQU5TRk9STVBBR0VfSF8KKyNkZWZpbmUgX1RSQU5TRk9STVBBR0VfSF8KKworI2lmbmRlZiBfRlBERlZJRVdfSF8KKyNpbmNsdWRlICJmcGRmdmlldy5oIgorI2VuZGlmCisKK3R5cGVkZWYgdm9pZCogRlBERl9QQUdFQVJDU0FWRVI7Cit0eXBlZGVmIHZvaWQqIEZQREZfUEFHRUFSQ0xPQURFUjsKKy8qKgorKiAgU2V0ICJNZWRpYUJveCIgZW50cnkgdG8gdGhlIHBhZ2UgZGljdGlvbmFyeS4JCQkJCQkgICAKKyogQHBhcmFtW2luXSBwYWdlCS0gSGFuZGxlIHRvIGEgcGFnZS4KKyogQHBhcmFtW2luXSBsZWZ0CS0gVGhlIGxlZnQgb2YgdGhlIHJlY3RhbmdsZS4KKyogQHBhcmFtW2luXSBib3R0b20JLSBUaGUgYm90dG9tIG9mIHRoZSByZWN0YW5nbGUuCisqIEBwYXJhbVtpbl0gcmlnaHQJLSBUaGUgcmlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyogQHBhcmFtW2luXSB0b3AJLSBUaGUgdG9wIG9mIHRoZSByZWN0YW5nbGUuCisqIEByZXR2YWwgTm9uZS4KKyovCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX1NldE1lZGlhQm94KEZQREZfUEFHRSBwYWdlLCBmbG9hdCBsZWZ0LCBmbG9hdCBib3R0b20sIGZsb2F0IHJpZ2h0LCBmbG9hdCB0b3ApOworCisvKioKKyogIFNldCAiQ3JvcEJveCIgZW50cnkgdG8gdGhlIHBhZ2UgZGljdGlvbmFyeS4JCQkJCQkgICAKKyogQHBhcmFtW2luXSBwYWdlCS0gSGFuZGxlIHRvIGEgcGFnZS4KKyogQHBhcmFtW2luXSBsZWZ0CS0gVGhlIGxlZnQgb2YgdGhlIHJlY3RhbmdsZS4KKyogQHBhcmFtW2luXSBib3R0b20JLSBUaGUgYm90dG9tIG9mIHRoZSByZWN0YW5nbGUuCisqIEBwYXJhbVtpbl0gcmlnaHQJLSBUaGUgcmlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyogQHBhcmFtW2luXSB0b3AJLSBUaGUgdG9wIG9mIHRoZSByZWN0YW5nbGUuCisqIEByZXR2YWwgTm9uZS4KKyovCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX1NldENyb3BCb3goRlBERl9QQUdFIHBhZ2UsIGZsb2F0IGxlZnQsIGZsb2F0IGJvdHRvbSwgZmxvYXQgcmlnaHQsIGZsb2F0IHRvcCk7CisKKworLyoqICBHZXQgIk1lZGlhQm94IiBlbnRyeSBmcm9tIHRoZSBwYWdlIGRpY3Rpb25hcnkuCQkJCQkJICAgCisqIEBwYXJhbVtpbl0gcGFnZQktIEhhbmRsZSB0byBhIHBhZ2UuCisqIEBwYXJhbVtpbl0gbGVmdAktIFBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSBsZWZ0IG9mIHRoZSByZWN0YW5nbGUuCisqIEBwYXJhbVtpbl0gYm90dG9tCS0gUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIGJvdHRvbSBvZiB0aGUgcmVjdGFuZ2xlLgorKiBAcGFyYW1baW5dIHJpZ2h0CS0gUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHJpZ2h0IG9mIHRoZSByZWN0YW5nbGUuCisqIEBwYXJhbVtpbl0gdG9wCS0gUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHRvcCBvZiB0aGUgcmVjdGFuZ2xlLgorKiBAcmV0dmFsIFRydWUgaWYgc3VjY2VzcyxlbHNlIGZhaWwuCisqLworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlX0dldE1lZGlhQm94KEZQREZfUEFHRSBwYWdlLCBmbG9hdCogbGVmdCwgZmxvYXQqIGJvdHRvbSwgZmxvYXQqIHJpZ2h0LCBmbG9hdCogdG9wKTsKKworLyoqICBHZXQgIkNyb3BCb3giIGVudHJ5IGZyb20gdGhlIHBhZ2UgZGljdGlvbmFyeS4JCQkJCQkgICAKKyogQHBhcmFtW2luXSBwYWdlCS0gSGFuZGxlIHRvIGEgcGFnZS4KKyogQHBhcmFtW2luXSBsZWZ0CS0gUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIGxlZnQgb2YgdGhlIHJlY3RhbmdsZS4KKyogQHBhcmFtW2luXSBib3R0b20JLSBQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgYm90dG9tIG9mIHRoZSByZWN0YW5nbGUuCisqIEBwYXJhbVtpbl0gcmlnaHQJLSBQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgcmlnaHQgb2YgdGhlIHJlY3RhbmdsZS4KKyogQHBhcmFtW2luXSB0b3AJLSBQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgdG9wIG9mIHRoZSByZWN0YW5nbGUuCisqIEByZXR2YWwgVHJ1ZSBpZiBzdWNjZXNzLGVsc2UgZmFpbC4KKyovCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VfR2V0Q3JvcEJveChGUERGX1BBR0UgcGFnZSwgZmxvYXQqIGxlZnQsIGZsb2F0KiBib3R0b20sIGZsb2F0KiByaWdodCwgZmxvYXQqIHRvcCk7CisKKy8qKgorKiBUcmFuc2Zvcm0gdGhlIHdob2xlIHBhZ2Ugd2l0aCBhIHNwZWNpZmllZCBtYXRyaXgsIHRoZW4gY2xpcCB0aGUgcGFnZSBjb250ZW50IHJlZ2lvbi4KKyoKKyogQHBhcmFtW2luXSBwYWdlCQkgLSBBIHBhZ2UgaGFuZGxlLgorKiBAcGFyYW1baW5dIG1hdHJpeAkJIC0gVGhlIHRyYW5zZm9ybSBtYXRyaXguCisqIEBwYXJhbVtpbl0gY2xpcFJlY3QJIC0gQSByZWN0YW5nbGUgcGFnZSBhcmVhIHRvIGJlIGNsaXBwZWQuCisqIEBOb3RlLiBUaGlzIGZ1bmN0aW9uIHdpbGwgdHJhbnNmb3JtIHRoZSB3aG9sZSBwYWdlLCBhbmQgd291bGQgdGFrZSBlZmZlY3QgdG8gYWxsIHRoZSBvYmplY3RzIGluIHRoZSBwYWdlLgorKi8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGUGFnZV9UcmFuc0Zvcm1XaXRoQ2xpcChGUERGX1BBR0UgcGFnZSwgRlNfTUFUUklYKiBtYXRyaXgsIEZTX1JFQ1RGKiBjbGlwUmVjdCk7CisKKy8qKgorKiBUcmFuc2Zvcm0gKHNjYWxlLCByb3RhdGUsIHNoZWFyLCBtb3ZlKSB0aGUgY2xpcCBwYXRoIG9mIHBhZ2Ugb2JqZWN0LgorKiBAcGFyYW1baW5dIHBhZ2Vfb2JqZWN0IC0gSGFuZGxlIHRvIGEgcGFnZSBvYmplY3QuIFJldHVybmVkIGJ5IEZQREZQYWdlT2JqX05ld0ltYWdlT2JqLgorKiBAcGFyYW1baW5dIGEJLSBUaGUgY29lZmZpY2llbnQgImEiIG9mIHRoZSBtYXRyaXguCisqIEBwYXJhbVtpbl0gYgktIFRoZSBjb2VmZmljaWVudCAiYiIgb2YgdGhlIG1hdHJpeC4KKyogQHBhcmFtW2luXSBjCS0gVGhlIGNvZWZmaWNpZW50ICJjIiBvZiB0aGUgbWF0cml4LgorKiBAcGFyYW1baW5dIGQJLSBUaGUgY29lZmZpY2llbnQgImQiIG9mIHRoZSBtYXRyaXguCisqIEBwYXJhbVtpbl0gZQktIFRoZSBjb2VmZmljaWVudCAiZSIgb2YgdGhlIG1hdHJpeC4KKyogQHBhcmFtW2luXSBmCS0gVGhlIGNvZWZmaWNpZW50ICJmIiBvZiB0aGUgbWF0cml4LgorKiBAcmV0dmFsIE5vbmUuCisqLworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGUGFnZU9ial9UcmFuc2Zvcm1DbGlwUGF0aChGUERGX1BBR0VPQkpFQ1QgcGFnZV9vYmplY3QsZG91YmxlIGEsIGRvdWJsZSBiLCBkb3VibGUgYywgZG91YmxlIGQsIGRvdWJsZSBlLCBkb3VibGUgZik7CisKKy8qKgorKiBDcmVhdGUgYSBuZXcgY2xpcCBwYXRoLCB3aXRoIGEgcmVjdGFuZ2xlIGluc2VydGVkLgorKiAKKyogQHBhcmFtW2luXSBsZWZ0CS0gVGhlIGxlZnQgb2YgdGhlIGNsaXAgYm94LgorKiBAcGFyYW1baW5dIGJvdHRvbSAtIFRoZSBib3R0b20gb2YgdGhlIGNsaXAgYm94LgorKiBAcGFyYW1baW5dIHJpZ2h0CS0gVGhlIHJpZ2h0IG9mIHRoZSBjbGlwIGJveC4KKyogQHBhcmFtW2luXSB0b3AJLSBUaGUgdG9wIG9mIHRoZSBjbGlwIGJveC4KKyogQHJldHZhbCBhIGhhbmRsZSB0byB0aGUgY2xpcCBwYXRoLgorKi8KK0RMTEVYUE9SVCBGUERGX0NMSVBQQVRIIFNURENBTEwgRlBERl9DcmVhdGVDbGlwUGF0aChmbG9hdCBsZWZ0LCBmbG9hdCBib3R0b20sIGZsb2F0IHJpZ2h0LCBmbG9hdCB0b3ApOworCisvKioKKyogRGVzdHJveSB0aGUgY2xpcCBwYXRoLgorKgorKiBAcGFyYW1baW5dIGNsaXBQYXRoIC0gQSBoYW5kbGUgdG8gdGhlIGNsaXAgcGF0aC4KKyogRGVzdHJveSB0aGUgY2xpcCBwYXRoLgorKiBAcmV0dmFsIE5vbmUuCisqLworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX0Rlc3Ryb3lDbGlwUGF0aChGUERGX0NMSVBQQVRIIGNsaXBQYXRoKTsKKworLyoqCisqIENsaXAgdGhlIHBhZ2UgY29udGVudCwgdGhlIHBhZ2UgY29udGVudCB0aGF0IG91dHNpZGUgdGhlIGNsaXBwaW5nIHJlZ2lvbiBiZWNvbWUgaW52aXNpYmxlLgorKgorKiBAcGFyYW1baW5dIHBhZ2UJCSAtIEEgcGFnZSBoYW5kbGUuCisqIEBwYXJhbVtpbl0gY2xpcFBhdGgJIC0gQSBoYW5kbGUgdG8gdGhlIGNsaXAgcGF0aC4KKyogQE5vdGUuIEEgY2xpcCBwYXRoIHdpbGwgYmUgaW5zZXJ0ZWQgYmVmb3JlIHRoZSBwYWdlIGNvbnRlbnQgc3RyZWFtIG9yIGNvbnRlbnQgYXJyYXkuIEluIHRoaXMgd2F5LCB0aGUgcGFnZSBjb250ZW50IHdpbGwgYmUgY2xpcHBlZAorKiBieSB0aGlzIGNsaXAgcGF0aC4gCisqLworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGUGFnZV9JbnNlcnRDbGlwUGF0aChGUERGX1BBR0UgcGFnZSxGUERGX0NMSVBQQVRIIGNsaXBQYXRoKTsKKworI2VuZGlmCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmZG9jLmggYi9mcGRmc2RrL2luY2x1ZGUvZnBkZmRvYy5oCmluZGV4IDM1YzJjOTYuLjU0ZWRlNDAgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmZG9jLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZkb2MuaApAQCAtMSwyMzAgKzEsMjMwIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GUERGRE9DX0hfDQotI2RlZmluZSBfRlBERkRPQ19IXw0KLQ0KLSNpbmNsdWRlICJmcGRmdmlldy5oIg0KLQ0KLS8vIEV4cG9ydGVkIEZ1bmN0aW9ucw0KLSNpZmRlZiBfX2NwbHVzcGx1cw0KLWV4dGVybiAiQyIgew0KLSNlbmRpZg0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGQm9va21hcmtfRmluZA0KLS8vCQkJRmluZCBhIGJvb2ttYXJrIGluIHRoZSBkb2N1bWVudCwgdXNpbmcgdGhlIGJvb2ttYXJrIHRpdGxlLg0KLS8vIFBhcmFtZXRlcnM6IA0KLS8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBvciBGUERGX0xvYWRNZW1Eb2N1bWVudC4NCi0vLwkJCXRpdGxlCQktCVRoZSBVVEYtMTZMRSBlbmNvZGVkIFVuaWNvZGUgc3RyaW5nIGZvciB0aGUgYm9va21hcmsgdGl0bGUgdG8gYmUgc2VhcmNoZWQuIENhbid0IGJlIE5VTEwuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJSGFuZGxlIHRvIHRoZSBmb3VuZCBib29rbWFyayBpdGVtLiBOVUxMIGlmIHRoZSB0aXRsZSBjYW4ndCBiZSBmb3VuZC4NCi0vLyBDb21tZW50czoNCi0vLwkJCUl0IGFsd2F5cyByZXR1cm5zIHRoZSBmaXJzdCBmb3VuZCBib29rbWFyayBpZiBtb3JlIHRoYW4gb25lIGJvb2ttYXJrcyBoYXZlIHRoZSBzYW1lIHRpdGxlLg0KLS8vDQotRExMRVhQT1JUIEZQREZfQk9PS01BUksgU1REQ0FMTCBGUERGQm9va21hcmtfRmluZChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBGUERGX1dJREVTVFJJTkcgdGl0bGUpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGQm9va21hcmtfR2V0RGVzdA0KLS8vCQkJR2V0IHRoZSBkZXN0aW5hdGlvbiBhc3NvY2lhdGVkIHdpdGggYSBib29rbWFyayBpdGVtLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byB0aGUgZG9jdW1lbnQuDQotLy8JCQlib29rbWFyawktCUhhbmRsZSB0byB0aGUgYm9va21hcmsuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJSGFuZGxlIHRvIHRoZSBkZXN0aW5hdGlvbiBkYXRhLiBOVUxMIGlmIG5vIGRlc3RpbmF0aW9uIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGJvb2ttYXJrLg0KLS8vDQotRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZCb29rbWFya19HZXREZXN0KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfQk9PS01BUksgYm9va21hcmspOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGQm9va21hcmtfR2V0QWN0aW9uDQotLy8JCQlHZXQgdGhlIGFjdGlvbiBhc3NvY2lhdGVkIHdpdGggYSBib29rbWFyayBpdGVtLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQlib29rbWFyawktCUhhbmRsZSB0byB0aGUgYm9va21hcmsuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJSGFuZGxlIHRvIHRoZSBhY3Rpb24gZGF0YS4gTlVMTCBpZiBubyBhY3Rpb24gaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYm9va21hcmsuIEluIHRoaXMgY2FzZSwgdGhlIA0KLS8vCQkJYXBwbGljYXRpb24gc2hvdWxkIHRyeSBGUERGQm9va21hcmtfR2V0RGVzdC4NCi0vLw0KLURMTEVYUE9SVCBGUERGX0FDVElPTiBTVERDQUxMIEZQREZCb29rbWFya19HZXRBY3Rpb24oRlBERl9CT09LTUFSSyBib29rbWFyayk7DQotDQotI2RlZmluZSBQREZBQ1RJT05fVU5TVVBQT1JURUQJCTAJCS8vIFVuc3VwcG9ydGVkIGFjdGlvbiB0eXBlLg0KLSNkZWZpbmUgUERGQUNUSU9OX0dPVE8JCQkJMQkJLy8gR28gdG8gYSBkZXN0aW5hdGlvbiB3aXRoaW4gY3VycmVudCBkb2N1bWVudC4NCi0jZGVmaW5lIFBERkFDVElPTl9SRU1PVEVHT1RPCQkyCQkvLyBHbyB0byBhIGRlc3RpbmF0aW9uIHdpdGhpbiBhbm90aGVyIGRvY3VtZW50Lg0KLSNkZWZpbmUgUERGQUNUSU9OX1VSSQkJCQkzCQkvLyBVbml2ZXJzYWwgUmVzb3VyY2UgSWRlbnRpZmllciwgaW5jbHVkaW5nIHdlYiBwYWdlcyBhbmQgDQotCQkJCQkJCQkJCQkvLyBvdGhlciBJbnRlcm5ldCBiYXNlZCByZXNvdXJjZXMuDQotI2RlZmluZSBQREZBQ1RJT05fTEFVTkNICQkJNAkJLy8gTGF1bmNoIGFuIGFwcGxpY2F0aW9uIG9yIG9wZW4gYSBmaWxlLg0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGQWN0aW9uX0dldFR5cGUNCi0vLwkJCUdldCB0eXBlIG9mIGFuIGFjdGlvbi4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJYWN0aW9uCQktCUhhbmRsZSB0byB0aGUgYWN0aW9uLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCUEgdHlwZSBudW1iZXIgYXMgZGVmaW5lZCBhYm92ZS4NCi0vLw0KLURMTEVYUE9SVCB1bnNpZ25lZCBsb25nIFNURENBTEwgRlBERkFjdGlvbl9HZXRUeXBlKEZQREZfQUNUSU9OIGFjdGlvbik7DQotDQotLy8gRnVuY3Rpb246IEZQREZBY3Rpb25fR2V0RGVzdA0KLS8vCQkJR2V0IGRlc3RpbmF0aW9uIG9mIGFuIGFjdGlvbi4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50Lg0KLS8vCQkJYWN0aW9uCQktCUhhbmRsZSB0byB0aGUgYWN0aW9uLiBJdCBtdXN0IGJlIGEgR09UTyBvciBSRU1PVEVHT1RPIGFjdGlvbi4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlIYW5kbGUgdG8gdGhlIGRlc3RpbmF0aW9uIGRhdGEuDQotLy8gQ29tbWVudHM6DQotLy8JCQlJbiBjYXNlIG9mIHJlbW90ZSBnb3RvIGFjdGlvbiwgdGhlIGFwcGxpY2F0aW9uIHNob3VsZCBmaXJzdCB1c2UgRlBERkFjdGlvbl9HZXRGaWxlUGF0aCB0bw0KLS8vCQkJZ2V0IGZpbGUgcGF0aCwgdGhlbiBsb2FkIHRoYXQgcGFydGljdWxhciBkb2N1bWVudCwgYW5kIHVzZSBpdHMgZG9jdW1lbnQgaGFuZGxlIHRvIGNhbGwgdGhpcw0KLS8vCQkJZnVuY3Rpb24uDQotLy8NCi1ETExFWFBPUlQgRlBERl9ERVNUIFNURENBTEwgRlBERkFjdGlvbl9HZXREZXN0KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfQUNUSU9OIGFjdGlvbik7DQotDQotLy8gRnVuY3Rpb246IEZQREZBY3Rpb25fR2V0VVJJUGF0aA0KLS8vCQkJR2V0IFVSSSBwYXRoIG9mIGEgVVJJIGFjdGlvbi4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50Lg0KLS8vCQkJYWN0aW9uCQktCUhhbmRsZSB0byB0aGUgYWN0aW9uLiBNdXN0IGJlIGEgVVJJIGFjdGlvbi4NCi0vLwkJCWJ1ZmZlcgkJLQlBIGJ1ZmZlciBmb3Igb3V0cHV0IHRoZSBwYXRoIHN0cmluZy4gQ2FuIGJlIE5VTEwuDQotLy8JCQlidWZsZW4JCS0JVGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyLCBudW1iZXIgb2YgYnl0ZXMuIENhbiBiZSAwLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCU51bWJlciBvZiBieXRlcyB0aGUgVVJJIHBhdGggY29uc3VtZXMsIGluY2x1ZGluZyB0cmFpbGluZyB6ZXJvcy4NCi0vLyBDb21tZW50czoNCi0vLwkJCVRoZSBVUkkgcGF0aCBpcyBhbHdheXMgZW5jb2RlZCBpbiA3LWJpdCBBU0NJSS4NCi0vLyANCi0vLwkJCVRoZSByZXR1cm4gdmFsdWUgYWx3YXlzIGluZGljYXRlZCBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgZm9yIHRoZSBidWZmZXIsIGV2ZW4gd2hlbiB0aGVyZSBpcw0KLS8vCQkJbm8gYnVmZmVyIHNwZWNpZmllZCwgb3IgdGhlIGJ1ZmZlciBzaXplIGlzIGxlc3MgdGhlbiByZXF1aXJlZC4gSW4gdGhpcyBjYXNlLCB0aGUgYnVmZmVyIHdpbGwgbm90DQotLy8JCQliZSBtb2RpZmllZC4NCi0vLw0KLURMTEVYUE9SVCB1bnNpZ25lZCBsb25nIFNURENBTEwgRlBERkFjdGlvbl9HZXRVUklQYXRoKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfQUNUSU9OIGFjdGlvbiwgDQotCQkJCQkJCQkJCQkJCSAgdm9pZCogYnVmZmVyLCB1bnNpZ25lZCBsb25nIGJ1Zmxlbik7DQotDQotLy8gRnVuY3Rpb246IEZQREZEZXN0X0dldFBhZ2VJbmRleA0KLS8vCQkJR2V0IHBhZ2UgaW5kZXggb2YgYSBkZXN0aW5hdGlvbi4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50Lg0KLS8vCQkJZGVzdAkJLQlIYW5kbGUgdG8gdGhlIGRlc3RpbmF0aW9uLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRoZSBwYWdlIGluZGV4LiBTdGFydGluZyBmcm9tIDAgZm9yIHRoZSBmaXJzdCBwYWdlLg0KLS8vDQotRExMRVhQT1JUIHVuc2lnbmVkIGxvbmcgU1REQ0FMTCBGUERGRGVzdF9HZXRQYWdlSW5kZXgoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9ERVNUIGRlc3QpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGTGlua19HZXRMaW5rQXRQb2ludA0KLS8vCQkJRmluZCBhIGxpbmsgYXQgc3BlY2lmaWVkIHBvaW50IG9uIGEgZG9jdW1lbnQgcGFnZS4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50IHBhZ2UuDQotLy8JCQl4CQkJLQlUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludCwgc3BlY2lmaWVkIGluIHBhZ2UgY29vcmRpbmF0ZSBzeXN0ZW0uDQotLy8JCQl5CQkJLQlUaGUgeSBjb29yZGluYXRlIG9mIHRoZSBwb2ludCwgc3BlY2lmaWVkIGluIHBhZ2UgY29vcmRpbmF0ZSBzeXN0ZW0uDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJSGFuZGxlIHRvIHRoZSBsaW5rLiBOVUxMIGlmIG5vIGxpbmsgZm91bmQgYXQgdGhhdCBwb2ludC4NCi0vLyBDb21tZW50czoNCi0vLwkJCVRoZSBwb2ludCBjb29yZGluYXRlcyBhcmUgc3BlY2lmaWVkIGluIHBhZ2UgY29vcmRpbmF0ZSBzeXN0ZW0uIFlvdSBjYW4gY29udmVydCBjb29yZGluYXRlcyANCi0vLwkJCWZyb20gc2NyZWVuIHN5c3RlbSB0byBwYWdlIHN5c3RlbSB1c2luZyBGUERGX0RldmljZVRvUGFnZSBmdW5jdGlvbnMuDQotLy8NCi1ETExFWFBPUlQgRlBERl9MSU5LIFNURENBTEwgRlBERkxpbmtfR2V0TGlua0F0UG9pbnQoRlBERl9QQUdFIHBhZ2UsIGRvdWJsZSB4LCBkb3VibGUgeSk7DQotDQotLy8gRnVuY3Rpb246IEZQREZMaW5rX0dldERlc3QNCi0vLwkJCUdldCBkZXN0aW5hdGlvbiBpbmZvIG9mIGEgbGluay4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50Lg0KLS8vCQkJbGluawkJLQlIYW5kbGUgdG8gdGhlIGxpbmsuIFJldHVybmVkIGJ5IEZQREZMaW5rX0dldExpbmtBdFBvaW50Lg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCUhhbmRsZSB0byB0aGUgZGVzdGluYXRpb24uIE5VTEwgaWYgdGhlcmUgaXMgbm8gZGVzdGluYXRpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBsaW5rLCBpbiB0aGlzIGNhc2UNCi0vLwkJCXRoZSBhcHBsaWNhdGlvbiBzaG91bGQgdHJ5IEZQREZMaW5rX0dldEFjdGlvbi4NCi0vLw0KLURMTEVYUE9SVCBGUERGX0RFU1QgU1REQ0FMTCBGUERGTGlua19HZXREZXN0KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfTElOSyBsaW5rKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkxpbmtfR2V0QWN0aW9uDQotLy8JCQlHZXQgYWN0aW9uIGluZm8gb2YgYSBsaW5rLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQlsaW5rCQktCUhhbmRsZSB0byB0aGUgbGluay4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlIYW5kbGUgdG8gdGhlIGFjdGlvbi4gTlVMTCBpZiB0aGVyZSBpcyBubyBhY3Rpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBsaW5rLg0KLS8vDQotRExMRVhQT1JUIEZQREZfQUNUSU9OIFNURENBTEwgRlBERkxpbmtfR2V0QWN0aW9uKEZQREZfTElOSyBsaW5rKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkxpbmtfRW51bWVyYXRlDQotLy8JCQlUaGlzIGZ1bmN0aW9uIHdvdWxkIGVudW1lcmF0ZSBhbGwgdGhlIGxpbmsgYW5ub3RhdGlvbnMgaW4gYSBzaW5nbGUgUERGIHBhZ2UuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCXBhZ2VbaW5dCQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuDQotLy8JCQlzdGFydFBvc1tpbixvdXRdCS0JVGhlIHN0YXJ0IHBvc2l0aW9uIHRvIGVudW1lcmF0ZSB0aGUgbGluayBhbm5vdGF0aW9ucywgd2hpY2ggc2hvdWxkIGJlIHNwZWNpZmllZCB0byBzdGFydCBmcm9tIA0KLS8vCQkJCQkJCQktCTAgZm9yIHRoZSBmaXJzdCBjYWxsLCBhbmQgd291bGQgcmVjZWl2ZSB0aGUgbmV4dCBwb3NpdGlvbiBmb3IgZW51bWVyYXRpbmcgdG8gc3RhcnQgZnJvbS4NCi0vLwkJCWxpbmtBbm5vdFtvdXRdCQktCVJlY2VpdmUgdGhlIGxpbmsgaGFuZGxlLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRSVUUgaWYgc3VjY2NlZWQsIGVsc2UgRmFsc2U7DQotLy8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkxpbmtfRW51bWVyYXRlKEZQREZfUEFHRSBwYWdlLCBpbnQqIHN0YXJ0UG9zLCBGUERGX0xJTksqIGxpbmtBbm5vdCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZMaW5rX0dldEFubm90UmVjdA0KLS8vCQkJR2V0IHRoZSBhbm5vdGF0aW9uIHJlY3RhbmdsZS4gKFNwZWNpZmllZCBieSB0aGUgobBSZWN0obEgZW50cnkgb2YgYW5ub3RhdGlvbiBkaWN0aW9uYXJ5KS4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJbGlua0Fubm90W2luXQkJLQlIYW5kbGUgdG8gdGhlIGxpbmsgYW5ub3RhdGlvbi4NCi0vLwkJCXJlY3Rbb3V0XQkJCS0JVGhlIGFubm90YXRpb24gcmVjdC4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUUlVFIGlmIHN1Y2NjZWVkLCBlbHNlIEZhbHNlOw0KLS8vDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZMaW5rX0dldEFubm90UmVjdChGUERGX0xJTksgbGlua0Fubm90LCBGU19SRUNURiogcmVjdCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZMaW5rX0NvdW50UXVhZFBvaW50cw0KLS8vCQkJR2V0IHRoZSBjb3VudCBvZiBxdWFkcmlsYXRlcmFsIHBvaW50cyB0byB0aGUgbGluayBhbm5vdGF0aW9uLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQlsaW5rQW5ub3RbaW5dCQktCUhhbmRsZSB0byB0aGUgbGluayBhbm5vdGF0aW9uLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRoZSBjb3VudCBvZiBxdWFkcmlsYXRlcmFsIHBvaW50cy4NCi0vLw0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGTGlua19Db3VudFF1YWRQb2ludHMoRlBERl9MSU5LIGxpbmtBbm5vdCk7DQotDQotLyogX0ZTX0RFRl9TVFJVQ1RVUkVfUVVBRFBPSU5UU0ZfICovDQotI2lmbmRlZiBfRlNfREVGX1NUUlVDVFVSRV9RVUFEUE9JTlRTRl8NCi0jZGVmaW5lIF9GU19ERUZfU1RSVUNUVVJFX1FVQURQT0lOVFNGXw0KLXR5cGVkZWYgc3RydWN0IF9GU19RVUFEUE9JTlRTRg0KLXsNCi0JRlNfRkxPQVQgIHgxOw0KLQlGU19GTE9BVCAgeTE7DQotCUZTX0ZMT0FUICB4MjsNCi0JRlNfRkxPQVQgIHkyOw0KLQlGU19GTE9BVCAgeDM7DQotCUZTX0ZMT0FUICB5MzsNCi0JRlNfRkxPQVQgIHg0Ow0KLQlGU19GTE9BVCAgeTQ7DQotfSBGU19RVUFEUE9JTlRTRjsNCi0jZW5kaWYgLyogX0ZTX0RFRl9TVFJVQ1RVUkVfUVVBRFBPSU5UU0ZfICovDQotDQotLy8gRnVuY3Rpb246IEZQREZMaW5rX0dldFF1YWRQb2ludHMNCi0vLwkJCUdldCB0aGUgcXVhZHJpbGF0ZXJhbCBwb2ludHMgZm9yIHRoZSBzcGVjaWZpZWQgaW5kZXggaW4gdGhlIGxpbmsgYW5ub3RhdGlvbi4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJbGlua0Fubm90W2luXQkJLQlIYW5kbGUgdG8gdGhlIGxpbmsgYW5ub3RhdGlvbi4NCi0vLwkJCXF1YWRJbmRleFtpbl0JCS0JVGhlIHNwZWNpZmllZCBxdWFkIHBvaW50cyBpbmRleC4NCi0vLwkJCXF1YWRQb2ludHNbb3V0XQkJLQlSZWNlaXZlIHRoZSBxdWFkcmlsYXRlcmFsIHBvaW50cy4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUcnVlIGlmIHN1Y2NlZWQsIGVsc2UgRmFsc2UuDQotLy8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkxpbmtfR2V0UXVhZFBvaW50cyhGUERGX0xJTksgbGlua0Fubm90LCBpbnQgcXVhZEluZGV4LCBGU19RVUFEUE9JTlRTRiogcXVhZFBvaW50cyk7DQotDQotLy8gRnVuY3Rpb246IEZQREZfR2V0TWV0YVRleHQNCi0vLwkJCUdldCBhIHRleHQgZnJvbSBtZXRhIGRhdGEgb2YgdGhlIGRvY3VtZW50LiBSZXN1bHQgaXMgZW5jb2RlZCBpbiBVVEYtMTZMRS4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJZG9jCQkJLQlIYW5kbGUgdG8gYSBkb2N1bWVudA0KLS8vCQkJdGFnCQkJLQlUaGUgdGFnIGZvciB0aGUgbWV0YSBkYXRhLiBDdXJyZW50bHksIEl0IGNhbiBiZSAiVGl0bGUiLCAiQXV0aG9yIiwgDQotLy8JCQkJCQkJIlN1YmplY3QiLCAiS2V5d29yZHMiLCAiQ3JlYXRvciIsICJQcm9kdWNlciIsICJDcmVhdGlvbkRhdGUiLCBvciAiTW9kRGF0ZSIuDQotLy8JCQkJCQkJRm9yIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIHRoZXNlIHRhZ3MgYW5kIHRoZWlyIHJlc3BlY3RpdmUgdmFsdWVzLA0KLS8vCQkJCQkJCXBsZWFzZSByZWZlciB0byBQREYgUmVmZXJlbmNlIDEuNiwgc2VjdGlvbiAxMC4yLjEsICJEb2N1bWVudCBJbmZvcm1hdGlvbiBEaWN0aW9uYXJ5Ii4NCi0vLwkJCWJ1ZmZlcgkJLQlBIGJ1ZmZlciBmb3Igb3V0cHV0IHRoZSB0aXRsZS4gQ2FuIGJlIE5VTEwuDQotLy8JCQlidWZsZW4JCS0JVGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyLCBudW1iZXIgb2YgYnl0ZXMuIENhbiBiZSAwLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCU51bWJlciBvZiBieXRlcyB0aGUgdGl0bGUgY29uc3VtZXMsIGluY2x1ZGluZyB0cmFpbGluZyB6ZXJvcy4NCi0vLyBDb21tZW50czoNCi0vLwkJCU5vIG1hdHRlciBvbiB3aGF0IHBsYXRmb3JtLCB0aGUgdGl0bGUgaXMgYWx3YXlzIG91dHB1dCBpbiBVVEYtMTZMRSBlbmNvZGluZywgd2hpY2ggbWVhbnMgdGhlIGJ1ZmZlciANCi0vLwkJCWNhbiBiZSByZWdhcmRlZCBhcyBhbiBhcnJheSBvZiBXT1JEIChvbiBJbnRlbCBhbmQgY29tcGF0aWJsZSBDUFVzKSwgZWFjaCBXT1JEIHJlcHJlc2VudCB0aGUgVW5pY29kZSBvZiANCi0vLwkJCWEgY2hhcmFjdGVyIChzb21lIHNwZWNpYWwgVW5pY29kZSBtYXkgdGFrZSAyIFdPUkRzKS4gVGhlIHN0cmluZyBpcyBmb2xsb3dlZCBieSB0d28gYnl0ZXMgb2YgemVybyANCi0vLwkJCWluZGljYXRpbmcgZW5kIG9mIHRoZSBzdHJpbmcuDQotLy8NCi0vLwkJCVRoZSByZXR1cm4gdmFsdWUgYWx3YXlzIGluZGljYXRlZCBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgZm9yIHRoZSBidWZmZXIsIGV2ZW4gd2hlbiB0aGVyZSBpcw0KLS8vCQkJbm8gYnVmZmVyIHNwZWNpZmllZCwgb3IgdGhlIGJ1ZmZlciBzaXplIGlzIGxlc3MgdGhlbiByZXF1aXJlZC4gSW4gdGhpcyBjYXNlLCB0aGUgYnVmZmVyIHdpbGwgbm90DQotLy8JCQliZSBtb2RpZmllZC4NCi0vLw0KLURMTEVYUE9SVCB1bnNpZ25lZCBsb25nIFNURENBTEwgRlBERl9HZXRNZXRhVGV4dChGUERGX0RPQ1VNRU5UIGRvYywgRlBERl9CWVRFU1RSSU5HIHRhZywNCi0JCQkJCQkJCQkJCQkgdm9pZCogYnVmZmVyLCB1bnNpZ25lZCBsb25nIGJ1Zmxlbik7DQotDQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfTsNCi0jZW5kaWYNCi0NCi0jZW5kaWYJLy8gX0ZQREZET0NfSF8NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GUERGRE9DX0hfCisjZGVmaW5lIF9GUERGRE9DX0hfCisKKyNpbmNsdWRlICJmcGRmdmlldy5oIgorCisvLyBFeHBvcnRlZCBGdW5jdGlvbnMKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworLy8gRnVuY3Rpb246IEZQREZCb29rbWFya19GaW5kCisvLwkJCUZpbmQgYSBib29rbWFyayBpbiB0aGUgZG9jdW1lbnQsIHVzaW5nIHRoZSBib29rbWFyayB0aXRsZS4KKy8vIFBhcmFtZXRlcnM6IAorLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byB0aGUgZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IG9yIEZQREZfTG9hZE1lbURvY3VtZW50LgorLy8JCQl0aXRsZQkJLQlUaGUgVVRGLTE2TEUgZW5jb2RlZCBVbmljb2RlIHN0cmluZyBmb3IgdGhlIGJvb2ttYXJrIHRpdGxlIHRvIGJlIHNlYXJjaGVkLiBDYW4ndCBiZSBOVUxMLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlIYW5kbGUgdG8gdGhlIGZvdW5kIGJvb2ttYXJrIGl0ZW0uIE5VTEwgaWYgdGhlIHRpdGxlIGNhbid0IGJlIGZvdW5kLgorLy8gQ29tbWVudHM6CisvLwkJCUl0IGFsd2F5cyByZXR1cm5zIHRoZSBmaXJzdCBmb3VuZCBib29rbWFyayBpZiBtb3JlIHRoYW4gb25lIGJvb2ttYXJrcyBoYXZlIHRoZSBzYW1lIHRpdGxlLgorLy8KK0RMTEVYUE9SVCBGUERGX0JPT0tNQVJLIFNURENBTEwgRlBERkJvb2ttYXJrX0ZpbmQoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9XSURFU1RSSU5HIHRpdGxlKTsKKworLy8gRnVuY3Rpb246IEZQREZCb29rbWFya19HZXREZXN0CisvLwkJCUdldCB0aGUgZGVzdGluYXRpb24gYXNzb2NpYXRlZCB3aXRoIGEgYm9va21hcmsgaXRlbS4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIHRoZSBkb2N1bWVudC4KKy8vCQkJYm9va21hcmsJLQlIYW5kbGUgdG8gdGhlIGJvb2ttYXJrLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlIYW5kbGUgdG8gdGhlIGRlc3RpbmF0aW9uIGRhdGEuIE5VTEwgaWYgbm8gZGVzdGluYXRpb24gaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYm9va21hcmsuCisvLworRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZCb29rbWFya19HZXREZXN0KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfQk9PS01BUksgYm9va21hcmspOworCisvLyBGdW5jdGlvbjogRlBERkJvb2ttYXJrX0dldEFjdGlvbgorLy8JCQlHZXQgdGhlIGFjdGlvbiBhc3NvY2lhdGVkIHdpdGggYSBib29rbWFyayBpdGVtLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJYm9va21hcmsJLQlIYW5kbGUgdG8gdGhlIGJvb2ttYXJrLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlIYW5kbGUgdG8gdGhlIGFjdGlvbiBkYXRhLiBOVUxMIGlmIG5vIGFjdGlvbiBpcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBib29rbWFyay4gSW4gdGhpcyBjYXNlLCB0aGUgCisvLwkJCWFwcGxpY2F0aW9uIHNob3VsZCB0cnkgRlBERkJvb2ttYXJrX0dldERlc3QuCisvLworRExMRVhQT1JUIEZQREZfQUNUSU9OIFNURENBTEwgRlBERkJvb2ttYXJrX0dldEFjdGlvbihGUERGX0JPT0tNQVJLIGJvb2ttYXJrKTsKKworI2RlZmluZSBQREZBQ1RJT05fVU5TVVBQT1JURUQJCTAJCS8vIFVuc3VwcG9ydGVkIGFjdGlvbiB0eXBlLgorI2RlZmluZSBQREZBQ1RJT05fR09UTwkJCQkxCQkvLyBHbyB0byBhIGRlc3RpbmF0aW9uIHdpdGhpbiBjdXJyZW50IGRvY3VtZW50LgorI2RlZmluZSBQREZBQ1RJT05fUkVNT1RFR09UTwkJMgkJLy8gR28gdG8gYSBkZXN0aW5hdGlvbiB3aXRoaW4gYW5vdGhlciBkb2N1bWVudC4KKyNkZWZpbmUgUERGQUNUSU9OX1VSSQkJCQkzCQkvLyBVbml2ZXJzYWwgUmVzb3VyY2UgSWRlbnRpZmllciwgaW5jbHVkaW5nIHdlYiBwYWdlcyBhbmQgCisJCQkJCQkJCQkJCS8vIG90aGVyIEludGVybmV0IGJhc2VkIHJlc291cmNlcy4KKyNkZWZpbmUgUERGQUNUSU9OX0xBVU5DSAkJCTQJCS8vIExhdW5jaCBhbiBhcHBsaWNhdGlvbiBvciBvcGVuIGEgZmlsZS4KKworLy8gRnVuY3Rpb246IEZQREZBY3Rpb25fR2V0VHlwZQorLy8JCQlHZXQgdHlwZSBvZiBhbiBhY3Rpb24uCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlhY3Rpb24JCS0JSGFuZGxlIHRvIHRoZSBhY3Rpb24uCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCUEgdHlwZSBudW1iZXIgYXMgZGVmaW5lZCBhYm92ZS4KKy8vCitETExFWFBPUlQgdW5zaWduZWQgbG9uZyBTVERDQUxMIEZQREZBY3Rpb25fR2V0VHlwZShGUERGX0FDVElPTiBhY3Rpb24pOworCisvLyBGdW5jdGlvbjogRlBERkFjdGlvbl9HZXREZXN0CisvLwkJCUdldCBkZXN0aW5hdGlvbiBvZiBhbiBhY3Rpb24uCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byB0aGUgZG9jdW1lbnQuCisvLwkJCWFjdGlvbgkJLQlIYW5kbGUgdG8gdGhlIGFjdGlvbi4gSXQgbXVzdCBiZSBhIEdPVE8gb3IgUkVNT1RFR09UTyBhY3Rpb24uCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCUhhbmRsZSB0byB0aGUgZGVzdGluYXRpb24gZGF0YS4KKy8vIENvbW1lbnRzOgorLy8JCQlJbiBjYXNlIG9mIHJlbW90ZSBnb3RvIGFjdGlvbiwgdGhlIGFwcGxpY2F0aW9uIHNob3VsZCBmaXJzdCB1c2UgRlBERkFjdGlvbl9HZXRGaWxlUGF0aCB0bworLy8JCQlnZXQgZmlsZSBwYXRoLCB0aGVuIGxvYWQgdGhhdCBwYXJ0aWN1bGFyIGRvY3VtZW50LCBhbmQgdXNlIGl0cyBkb2N1bWVudCBoYW5kbGUgdG8gY2FsbCB0aGlzCisvLwkJCWZ1bmN0aW9uLgorLy8KK0RMTEVYUE9SVCBGUERGX0RFU1QgU1REQ0FMTCBGUERGQWN0aW9uX0dldERlc3QoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9BQ1RJT04gYWN0aW9uKTsKKworLy8gRnVuY3Rpb246IEZQREZBY3Rpb25fR2V0VVJJUGF0aAorLy8JCQlHZXQgVVJJIHBhdGggb2YgYSBVUkkgYWN0aW9uLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50LgorLy8JCQlhY3Rpb24JCS0JSGFuZGxlIHRvIHRoZSBhY3Rpb24uIE11c3QgYmUgYSBVUkkgYWN0aW9uLgorLy8JCQlidWZmZXIJCS0JQSBidWZmZXIgZm9yIG91dHB1dCB0aGUgcGF0aCBzdHJpbmcuIENhbiBiZSBOVUxMLgorLy8JCQlidWZsZW4JCS0JVGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyLCBudW1iZXIgb2YgYnl0ZXMuIENhbiBiZSAwLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOdW1iZXIgb2YgYnl0ZXMgdGhlIFVSSSBwYXRoIGNvbnN1bWVzLCBpbmNsdWRpbmcgdHJhaWxpbmcgemVyb3MuCisvLyBDb21tZW50czoKKy8vCQkJVGhlIFVSSSBwYXRoIGlzIGFsd2F5cyBlbmNvZGVkIGluIDctYml0IEFTQ0lJLgorLy8gCisvLwkJCVRoZSByZXR1cm4gdmFsdWUgYWx3YXlzIGluZGljYXRlZCBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgZm9yIHRoZSBidWZmZXIsIGV2ZW4gd2hlbiB0aGVyZSBpcworLy8JCQlubyBidWZmZXIgc3BlY2lmaWVkLCBvciB0aGUgYnVmZmVyIHNpemUgaXMgbGVzcyB0aGVuIHJlcXVpcmVkLiBJbiB0aGlzIGNhc2UsIHRoZSBidWZmZXIgd2lsbCBub3QKKy8vCQkJYmUgbW9kaWZpZWQuCisvLworRExMRVhQT1JUIHVuc2lnbmVkIGxvbmcgU1REQ0FMTCBGUERGQWN0aW9uX0dldFVSSVBhdGgoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9BQ1RJT04gYWN0aW9uLCAKKwkJCQkJCQkJCQkJCQkgIHZvaWQqIGJ1ZmZlciwgdW5zaWduZWQgbG9uZyBidWZsZW4pOworCisvLyBGdW5jdGlvbjogRlBERkRlc3RfR2V0UGFnZUluZGV4CisvLwkJCUdldCBwYWdlIGluZGV4IG9mIGEgZGVzdGluYXRpb24uCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byB0aGUgZG9jdW1lbnQuCisvLwkJCWRlc3QJCS0JSGFuZGxlIHRvIHRoZSBkZXN0aW5hdGlvbi4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJVGhlIHBhZ2UgaW5kZXguIFN0YXJ0aW5nIGZyb20gMCBmb3IgdGhlIGZpcnN0IHBhZ2UuCisvLworRExMRVhQT1JUIHVuc2lnbmVkIGxvbmcgU1REQ0FMTCBGUERGRGVzdF9HZXRQYWdlSW5kZXgoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9ERVNUIGRlc3QpOworCisvLyBGdW5jdGlvbjogRlBERkxpbmtfR2V0TGlua0F0UG9pbnQKKy8vCQkJRmluZCBhIGxpbmsgYXQgc3BlY2lmaWVkIHBvaW50IG9uIGEgZG9jdW1lbnQgcGFnZS4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBkb2N1bWVudCBwYWdlLgorLy8JCQl4CQkJLQlUaGUgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludCwgc3BlY2lmaWVkIGluIHBhZ2UgY29vcmRpbmF0ZSBzeXN0ZW0uCisvLwkJCXkJCQktCVRoZSB5IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50LCBzcGVjaWZpZWQgaW4gcGFnZSBjb29yZGluYXRlIHN5c3RlbS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJSGFuZGxlIHRvIHRoZSBsaW5rLiBOVUxMIGlmIG5vIGxpbmsgZm91bmQgYXQgdGhhdCBwb2ludC4KKy8vIENvbW1lbnRzOgorLy8JCQlUaGUgcG9pbnQgY29vcmRpbmF0ZXMgYXJlIHNwZWNpZmllZCBpbiBwYWdlIGNvb3JkaW5hdGUgc3lzdGVtLiBZb3UgY2FuIGNvbnZlcnQgY29vcmRpbmF0ZXMgCisvLwkJCWZyb20gc2NyZWVuIHN5c3RlbSB0byBwYWdlIHN5c3RlbSB1c2luZyBGUERGX0RldmljZVRvUGFnZSBmdW5jdGlvbnMuCisvLworRExMRVhQT1JUIEZQREZfTElOSyBTVERDQUxMIEZQREZMaW5rX0dldExpbmtBdFBvaW50KEZQREZfUEFHRSBwYWdlLCBkb3VibGUgeCwgZG91YmxlIHkpOworCisvLyBGdW5jdGlvbjogRlBERkxpbmtfR2V0RGVzdAorLy8JCQlHZXQgZGVzdGluYXRpb24gaW5mbyBvZiBhIGxpbmsuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byB0aGUgZG9jdW1lbnQuCisvLwkJCWxpbmsJCS0JSGFuZGxlIHRvIHRoZSBsaW5rLiBSZXR1cm5lZCBieSBGUERGTGlua19HZXRMaW5rQXRQb2ludC4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJSGFuZGxlIHRvIHRoZSBkZXN0aW5hdGlvbi4gTlVMTCBpZiB0aGVyZSBpcyBubyBkZXN0aW5hdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIGxpbmssIGluIHRoaXMgY2FzZQorLy8JCQl0aGUgYXBwbGljYXRpb24gc2hvdWxkIHRyeSBGUERGTGlua19HZXRBY3Rpb24uCisvLworRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZMaW5rX0dldERlc3QoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9MSU5LIGxpbmspOworCisvLyBGdW5jdGlvbjogRlBERkxpbmtfR2V0QWN0aW9uCisvLwkJCUdldCBhY3Rpb24gaW5mbyBvZiBhIGxpbmsuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlsaW5rCQktCUhhbmRsZSB0byB0aGUgbGluay4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJSGFuZGxlIHRvIHRoZSBhY3Rpb24uIE5VTEwgaWYgdGhlcmUgaXMgbm8gYWN0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGluay4KKy8vCitETExFWFBPUlQgRlBERl9BQ1RJT04gU1REQ0FMTCBGUERGTGlua19HZXRBY3Rpb24oRlBERl9MSU5LIGxpbmspOworCisvLyBGdW5jdGlvbjogRlBERkxpbmtfRW51bWVyYXRlCisvLwkJCVRoaXMgZnVuY3Rpb24gd291bGQgZW51bWVyYXRlIGFsbCB0aGUgbGluayBhbm5vdGF0aW9ucyBpbiBhIHNpbmdsZSBQREYgcGFnZS4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCXBhZ2VbaW5dCQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuCisvLwkJCXN0YXJ0UG9zW2luLG91dF0JLQlUaGUgc3RhcnQgcG9zaXRpb24gdG8gZW51bWVyYXRlIHRoZSBsaW5rIGFubm90YXRpb25zLCB3aGljaCBzaG91bGQgYmUgc3BlY2lmaWVkIHRvIHN0YXJ0IGZyb20gCisvLwkJCQkJCQkJLQkwIGZvciB0aGUgZmlyc3QgY2FsbCwgYW5kIHdvdWxkIHJlY2VpdmUgdGhlIG5leHQgcG9zaXRpb24gZm9yIGVudW1lcmF0aW5nIHRvIHN0YXJ0IGZyb20uCisvLwkJCWxpbmtBbm5vdFtvdXRdCQktCVJlY2VpdmUgdGhlIGxpbmsgaGFuZGxlLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGlmIHN1Y2NjZWVkLCBlbHNlIEZhbHNlOworLy8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGTGlua19FbnVtZXJhdGUoRlBERl9QQUdFIHBhZ2UsIGludCogc3RhcnRQb3MsIEZQREZfTElOSyogbGlua0Fubm90KTsKKworLy8gRnVuY3Rpb246IEZQREZMaW5rX0dldEFubm90UmVjdAorLy8JCQlHZXQgdGhlIGFubm90YXRpb24gcmVjdGFuZ2xlLiAoU3BlY2lmaWVkIGJ5IHRoZSChsFJlY3ShsSBlbnRyeSBvZiBhbm5vdGF0aW9uIGRpY3Rpb25hcnkpLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJbGlua0Fubm90W2luXQkJLQlIYW5kbGUgdG8gdGhlIGxpbmsgYW5ub3RhdGlvbi4KKy8vCQkJcmVjdFtvdXRdCQkJLQlUaGUgYW5ub3RhdGlvbiByZWN0LgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGlmIHN1Y2NjZWVkLCBlbHNlIEZhbHNlOworLy8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGTGlua19HZXRBbm5vdFJlY3QoRlBERl9MSU5LIGxpbmtBbm5vdCwgRlNfUkVDVEYqIHJlY3QpOworCisvLyBGdW5jdGlvbjogRlBERkxpbmtfQ291bnRRdWFkUG9pbnRzCisvLwkJCUdldCB0aGUgY291bnQgb2YgcXVhZHJpbGF0ZXJhbCBwb2ludHMgdG8gdGhlIGxpbmsgYW5ub3RhdGlvbi4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWxpbmtBbm5vdFtpbl0JCS0JSGFuZGxlIHRvIHRoZSBsaW5rIGFubm90YXRpb24uCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRoZSBjb3VudCBvZiBxdWFkcmlsYXRlcmFsIHBvaW50cy4KKy8vCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkxpbmtfQ291bnRRdWFkUG9pbnRzKEZQREZfTElOSyBsaW5rQW5ub3QpOworCisvKiBfRlNfREVGX1NUUlVDVFVSRV9RVUFEUE9JTlRTRl8gKi8KKyNpZm5kZWYgX0ZTX0RFRl9TVFJVQ1RVUkVfUVVBRFBPSU5UU0ZfCisjZGVmaW5lIF9GU19ERUZfU1RSVUNUVVJFX1FVQURQT0lOVFNGXwordHlwZWRlZiBzdHJ1Y3QgX0ZTX1FVQURQT0lOVFNGCit7CisJRlNfRkxPQVQgIHgxOworCUZTX0ZMT0FUICB5MTsKKwlGU19GTE9BVCAgeDI7CisJRlNfRkxPQVQgIHkyOworCUZTX0ZMT0FUICB4MzsKKwlGU19GTE9BVCAgeTM7CisJRlNfRkxPQVQgIHg0OworCUZTX0ZMT0FUICB5NDsKK30gRlNfUVVBRFBPSU5UU0Y7CisjZW5kaWYgLyogX0ZTX0RFRl9TVFJVQ1RVUkVfUVVBRFBPSU5UU0ZfICovCisKKy8vIEZ1bmN0aW9uOiBGUERGTGlua19HZXRRdWFkUG9pbnRzCisvLwkJCUdldCB0aGUgcXVhZHJpbGF0ZXJhbCBwb2ludHMgZm9yIHRoZSBzcGVjaWZpZWQgaW5kZXggaW4gdGhlIGxpbmsgYW5ub3RhdGlvbi4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWxpbmtBbm5vdFtpbl0JCS0JSGFuZGxlIHRvIHRoZSBsaW5rIGFubm90YXRpb24uCisvLwkJCXF1YWRJbmRleFtpbl0JCS0JVGhlIHNwZWNpZmllZCBxdWFkIHBvaW50cyBpbmRleC4KKy8vCQkJcXVhZFBvaW50c1tvdXRdCQktCVJlY2VpdmUgdGhlIHF1YWRyaWxhdGVyYWwgcG9pbnRzLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUcnVlIGlmIHN1Y2NlZWQsIGVsc2UgRmFsc2UuCisvLworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZMaW5rX0dldFF1YWRQb2ludHMoRlBERl9MSU5LIGxpbmtBbm5vdCwgaW50IHF1YWRJbmRleCwgRlNfUVVBRFBPSU5UU0YqIHF1YWRQb2ludHMpOworCisvLyBGdW5jdGlvbjogRlBERl9HZXRNZXRhVGV4dAorLy8JCQlHZXQgYSB0ZXh0IGZyb20gbWV0YSBkYXRhIG9mIHRoZSBkb2N1bWVudC4gUmVzdWx0IGlzIGVuY29kZWQgaW4gVVRGLTE2TEUuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlkb2MJCQktCUhhbmRsZSB0byBhIGRvY3VtZW50CisvLwkJCXRhZwkJCS0JVGhlIHRhZyBmb3IgdGhlIG1ldGEgZGF0YS4gQ3VycmVudGx5LCBJdCBjYW4gYmUgIlRpdGxlIiwgIkF1dGhvciIsIAorLy8JCQkJCQkJIlN1YmplY3QiLCAiS2V5d29yZHMiLCAiQ3JlYXRvciIsICJQcm9kdWNlciIsICJDcmVhdGlvbkRhdGUiLCBvciAiTW9kRGF0ZSIuCisvLwkJCQkJCQlGb3IgZGV0YWlsZWQgZXhwbGFuYXRpb24gb2YgdGhlc2UgdGFncyBhbmQgdGhlaXIgcmVzcGVjdGl2ZSB2YWx1ZXMsCisvLwkJCQkJCQlwbGVhc2UgcmVmZXIgdG8gUERGIFJlZmVyZW5jZSAxLjYsIHNlY3Rpb24gMTAuMi4xLCAiRG9jdW1lbnQgSW5mb3JtYXRpb24gRGljdGlvbmFyeSIuCisvLwkJCWJ1ZmZlcgkJLQlBIGJ1ZmZlciBmb3Igb3V0cHV0IHRoZSB0aXRsZS4gQ2FuIGJlIE5VTEwuCisvLwkJCWJ1ZmxlbgkJLQlUaGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIsIG51bWJlciBvZiBieXRlcy4gQ2FuIGJlIDAuCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCU51bWJlciBvZiBieXRlcyB0aGUgdGl0bGUgY29uc3VtZXMsIGluY2x1ZGluZyB0cmFpbGluZyB6ZXJvcy4KKy8vIENvbW1lbnRzOgorLy8JCQlObyBtYXR0ZXIgb24gd2hhdCBwbGF0Zm9ybSwgdGhlIHRpdGxlIGlzIGFsd2F5cyBvdXRwdXQgaW4gVVRGLTE2TEUgZW5jb2RpbmcsIHdoaWNoIG1lYW5zIHRoZSBidWZmZXIgCisvLwkJCWNhbiBiZSByZWdhcmRlZCBhcyBhbiBhcnJheSBvZiBXT1JEIChvbiBJbnRlbCBhbmQgY29tcGF0aWJsZSBDUFVzKSwgZWFjaCBXT1JEIHJlcHJlc2VudCB0aGUgVW5pY29kZSBvZiAKKy8vCQkJYSBjaGFyYWN0ZXIgKHNvbWUgc3BlY2lhbCBVbmljb2RlIG1heSB0YWtlIDIgV09SRHMpLiBUaGUgc3RyaW5nIGlzIGZvbGxvd2VkIGJ5IHR3byBieXRlcyBvZiB6ZXJvIAorLy8JCQlpbmRpY2F0aW5nIGVuZCBvZiB0aGUgc3RyaW5nLgorLy8KKy8vCQkJVGhlIHJldHVybiB2YWx1ZSBhbHdheXMgaW5kaWNhdGVkIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCBmb3IgdGhlIGJ1ZmZlciwgZXZlbiB3aGVuIHRoZXJlIGlzCisvLwkJCW5vIGJ1ZmZlciBzcGVjaWZpZWQsIG9yIHRoZSBidWZmZXIgc2l6ZSBpcyBsZXNzIHRoZW4gcmVxdWlyZWQuIEluIHRoaXMgY2FzZSwgdGhlIGJ1ZmZlciB3aWxsIG5vdAorLy8JCQliZSBtb2RpZmllZC4KKy8vCitETExFWFBPUlQgdW5zaWduZWQgbG9uZyBTVERDQUxMIEZQREZfR2V0TWV0YVRleHQoRlBERl9ET0NVTUVOVCBkb2MsIEZQREZfQllURVNUUklORyB0YWcsCisJCQkJCQkJCQkJCQkgdm9pZCogYnVmZmVyLCB1bnNpZ25lZCBsb25nIGJ1Zmxlbik7CisKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9OworI2VuZGlmCisKKyNlbmRpZgkvLyBfRlBERkRPQ19IXwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZlZGl0LmggYi9mcGRmc2RrL2luY2x1ZGUvZnBkZmVkaXQuaAppbmRleCA1MmZiMTQ4Li5jN2Q4YjAxIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnBkZmVkaXQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnBkZmVkaXQuaApAQCAtMSwyMzUgKzEsMjM1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmCV9GUERGRURJVF9IXw0KLSNkZWZpbmUJX0ZQREZFRElUX0hfDQotDQotI2luY2x1ZGUgImZwZGZ2aWV3LmgiDQotDQotLy8gRGVmaW5lIGFsbCB0eXBlcyB1c2VkIGluIHRoZSBTREsuIE5vdGUgdGhleSBjYW4gYmUgc2ltcGx5IHJlZ2FyZGVkIGFzIG9wYXF1ZSBwb2ludGVycw0KLS8vIG9yIGxvbmcgaW50ZWdlciBudW1iZXJzLg0KLQ0KLSNkZWZpbmUgRlBERl9BUkdCKGEscixnLGIpCQkoKCgoRlhfRFdPUkQpKCgoRlhfQllURSkoYil8KChGWF9XT1JEKSgoRlhfQllURSkoZykpPDw4KSl8KCgoRlhfRFdPUkQpKEZYX0JZVEUpKHIpKTw8MTYpKSkpIHwgKCgoRlhfRFdPUkQpKEZYX0JZVEUpKGEpKTw8MjQpKQ0KLSNkZWZpbmUgRlBERl9HZXRCVmFsdWUoYXJnYikgICAgKChGWF9CWVRFKShhcmdiKSkNCi0jZGVmaW5lIEZQREZfR2V0R1ZhbHVlKGFyZ2IpICAgICgoRlhfQllURSkoKChGWF9XT1JEKShhcmdiKSkgPj4gOCkpDQotI2RlZmluZSBGUERGX0dldFJWYWx1ZShhcmdiKSAgICAoKEZYX0JZVEUpKChhcmdiKT4+MTYpKQ0KLSNkZWZpbmUgRlBERl9HZXRBVmFsdWUoYXJnYikgICAgKChGWF9CWVRFKSgoYXJnYik+PjI0KSkNCi0NCi0jaWZkZWYgX19jcGx1c3BsdXMNCi1leHRlcm4gIkMiIHsNCi0jZW5kaWYNCi0NCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotLy8NCi0vLyBEb2N1bWVudCBmdW5jdGlvbnMNCi0vLw0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0NCi0vLyBGdW5jdGlvbjogRlBERl9DcmVhdGVOZXdEb2N1bWVudA0KLS8vCQkJQ3JlYXRlIGEgbmV3IFBERiBkb2N1bWVudC4NCi0vLyBQYXJhbWV0ZXJzOgkNCi0vLwkJCU5vbmUuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJQSBoYW5kbGUgdG8gYSBkb2N1bWVudC4gSWYgZmFpbGVkLCBOVUxMIGlzIHJldHVybmVkLg0KLURMTEVYUE9SVCBGUERGX0RPQ1VNRU5UIFNURENBTEwgRlBERl9DcmVhdGVOZXdEb2N1bWVudCgpOw0KLQ0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0vLw0KLS8vIFBhZ2UgZnVuY3Rpb25zDQotLy8NCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotDQotLy8gRnVuY3Rpb246IEZQREZQYWdlX05ldw0KLS8vCQkJQ29uc3RydWN0IGFuIGVtcHR5IHBhZ2UuDQotLy8gUGFyYW1ldGVyczoJDQotLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byBkb2N1bWVudC4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkRG9jdW1lbnQgYW5kIEZQREZfQ3JlYXRlTmV3RG9jdW1lbnQuDQotLy8JCQlwYWdlX2luZGV4CS0JVGhlIGluZGV4IG9mIGEgcGFnZS4NCi0vLwkJCXdpZHRoCQktCVRoZSBwYWdlIHdpZHRoLg0KLS8vCQkJaGVpZ2h0CQktCVRoZSBwYWdlIGhlaWdodC4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUaGUgaGFuZGxlIHRvIHRoZSBwYWdlLg0KLS8vIENvbW1lbnRzOg0KLS8vCQkJTG9hZGVkIHBhZ2UgY2FuIGJlIGRlbGV0ZWQgYnkgRlBERlBhZ2VfRGVsZXRlLg0KLURMTEVYUE9SVCBGUERGX1BBR0UgU1REQ0FMTCBGUERGUGFnZV9OZXcoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgaW50IHBhZ2VfaW5kZXgsIGRvdWJsZSB3aWR0aCwgZG91YmxlIGhlaWdodCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZQYWdlX0RlbGV0ZQ0KLS8vCQkJRGVsZXRlIGEgUERGIHBhZ2UuDQotLy8gUGFyYW1ldGVyczoJDQotLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byBkb2N1bWVudC4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkRG9jdW1lbnQgYW5kIEZQREZfQ3JlYXRlTmV3RG9jdW1lbnQuDQotLy8JCQlwYWdlX2luZGV4CS0JVGhlIGluZGV4IG9mIGEgcGFnZS4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlOb25lLg0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VfRGVsZXRlKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIGludCBwYWdlX2luZGV4KTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlBhZ2VfR2V0Um90YXRpb24NCi0vLwkJCUdldCB0aGUgcGFnZSByb3RhdGlvbi4gT25lIG9mIGZvbGxvd2luZyB2YWx1ZXMgd2lsbCBiZSByZXR1cm5lZDogMCgwKSwgMSg5MCksIDIoMTgwKSwgMygyNzApLg0KLS8vIFBhcmFtZXRlcnM6CQ0KLS8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gYSBwYWdlLiBSZXR1cm5lZCBieSBGUERGUGFnZV9OZXcuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVGhlIFBERiBwYWdlIHJvdGF0aW9uLg0KLS8vIENvbW1lbnQ6DQotLy8JCQlUaGUgUERGIHBhZ2Ugcm90YXRpb24gaXMgcm90YXRlZCBjbG9ja3dpc2UuDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZQYWdlX0dldFJvdGF0aW9uKEZQREZfUEFHRSBwYWdlKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlBhZ2VfSW5zZXJ0T2JqZWN0DQotLy8JCQlJbnNlcnQgYW4gb2JqZWN0IHRvIHRoZSBwYWdlLiBUaGUgcGFnZSBvYmplY3QgaXMgYXV0b21hdGljYWxseSBmcmVlZC4NCi0vLyBQYXJhbWV0ZXJzOgkNCi0vLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIGEgcGFnZS4gUmV0dXJuZWQgYnkgRlBERlBhZ2VfTmV3Lg0KLS8vCQkJcGFnZV9vYmoJLQlIYW5kbGUgdG8gYSBwYWdlIG9iamVjdC4gUmV0dXJuZWQgYnkgRlBERlBhZ2VPYmpfTmV3VGV4dE9iaixGUERGUGFnZU9ial9OZXdUZXh0T2JqRXggYW5kDQotLy8JCQkJCQkJRlBERlBhZ2VPYmpfTmV3UGF0aE9iai4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlOb25lLg0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VfSW5zZXJ0T2JqZWN0KEZQREZfUEFHRSBwYWdlLCBGUERGX1BBR0VPQkpFQ1QgcGFnZV9vYmopOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGUGFnZV9Db3VudE9iamVjdA0KLS8vCQkJR2V0IG51bWJlciBvZiBwYWdlIG9iamVjdHMgaW5zaWRlIHRoZSBwYWdlLg0KLS8vIFBhcmFtZXRlcnM6CQ0KLS8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gYSBwYWdlLiBSZXR1cm5lZCBieSBGUERGUGFnZV9OZXcuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVGhlIG51bWJlciBvZiB0aGUgcGFnZSBvYmplY3QuDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZQYWdlX0NvdW50T2JqZWN0KEZQREZfUEFHRSBwYWdlKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlBhZ2VfR2V0T2JqZWN0DQotLy8JCQlHZXQgcGFnZSBvYmplY3QgYnkgaW5kZXguDQotLy8gUGFyYW1ldGVyczoJDQotLy8JCQlwYWdlCQktCUhhbmRsZSB0byBhIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZQYWdlX05ldy4NCi0vLwkJCWluZGV4CQktCVRoZSBpbmRleCBvZiBhIHBhZ2Ugb2JqZWN0Lg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRoZSBoYW5kbGUgb2YgdGhlIHBhZ2Ugb2JqZWN0LiBOdWxsIGZvciBmYWlsZWQuDQotRExMRVhQT1JUIEZQREZfUEFHRU9CSkVDVCBTVERDQUxMIEZQREZQYWdlX0dldE9iamVjdChGUERGX1BBR0UgcGFnZSwgaW50IGluZGV4KTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlBhZ2VfSGFzVHJhbnNwYXJlbmN5DQotLy8JCQlDaGVjayB0aGF0IHdoZXRoZXIgdGhlIGNvbnRlbnQgb2Ygc3BlY2lmaWVkIFBERiBwYWdlIGNvbnRhaW5zIHRyYW5zcGFyZW5jeS4NCi0vLyBQYXJhbWV0ZXJzOgkNCi0vLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIGEgcGFnZS4gUmV0dXJuZWQgYnkgRlBERlBhZ2VfTmV3IG9yIEZQREZfTG9hZFBhZ2UuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVFJVRSBtZWFucyB0aGF0IHRoZSBQREYgcGFnZSBkb2VzIGNvbnRhaW5zIHRyYW5zcGFyZW5jeS4NCi0vLwkJCU90aGVyd2lzZSwgcmV0dXJucyBGQUxTRS4NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VfSGFzVHJhbnNwYXJlbmN5KEZQREZfUEFHRSBwYWdlKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlBhZ2VfR2VuZXJhdGVDb250ZW50DQotLy8JCQlHZW5lcmF0ZSBQREYgUGFnZSBjb250ZW50Lg0KLS8vIFBhcmFtZXRlcnM6CQ0KLS8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gYSBwYWdlLiBSZXR1cm5lZCBieSBGUERGUGFnZV9OZXcuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVHJ1ZSBpZiBzdWNjZXNzZnVsLCBmYWxzZSBvdGhlcndpc2UuDQotLy8gQ29tbWVudDoNCi0vLwkJCUJlZm9yZSB5b3Ugc2F2ZSB0aGUgcGFnZSB0byBhIGZpbGUsIG9yIHJlbG9hZCB0aGUgcGFnZSwgeW91IG11c3QgY2FsbCB0aGUgRlBERlBhZ2VfR2VuZXJhdGVDb250ZW50IGZ1bmN0aW9uLg0KLS8vCQkJT3IgdGhlIGNoYW5nZWQgaW5mb3JtYXRpb24gd2lsbCBiZSBsb3N0Lg0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGUGFnZV9HZW5lcmF0ZUNvbnRlbnQoRlBERl9QQUdFIHBhZ2UpOw0KLQ0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0vLw0KLS8vIFBhZ2UgT2JqZWN0IGZ1bmN0aW9ucw0KLS8vDQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGUGFnZU9ial9IYXNUcmFuc3BhcmVuY3kNCi0vLwkJCUNoZWNrIHRoYXQgd2hldGhlciB0aGUgc3BlY2lmaWVkIFBERiBwYWdlIG9iamVjdCBjb250YWlucyB0cmFuc3BhcmVuY3kuDQotLy8gUGFyYW1ldGVyczoJDQotLy8JCQlwYWdlT2JqZWN0CS0JSGFuZGxlIHRvIGEgcGFnZSBvYmplY3QuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVFJVRSBtZWFucyB0aGF0IHRoZSBQREYgcGFnZSBvYmplY3QgZG9lcyBjb250YWlucyB0cmFuc3BhcmVuY3kuDQotLy8JCQlPdGhlcndpc2UsIHJldHVybnMgRkFMU0UuDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlT2JqX0hhc1RyYW5zcGFyZW5jeShGUERGX1BBR0VPQkpFQ1QgcGFnZU9iamVjdCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZQYWdlT2JqX1RyYW5zZm9ybQ0KLS8vCQkJVHJhbnNmb3JtIChzY2FsZSwgcm90YXRlLCBzaGVhciwgbW92ZSkgcGFnZSBvYmplY3QuDQotLy8gUGFyYW1ldGVyczoJDQotLy8JCQlwYWdlX29iamVjdAktCUhhbmRsZSB0byBhIHBhZ2Ugb2JqZWN0LiBSZXR1cm5lZCBieSBGUERGUGFnZU9ial9OZXdJbWFnZU9iai4NCi0vLwkJCWEJCQktCVRoZSBjb2VmZmljaWVudCAiYSIgb2YgdGhlIG1hdHJpeC4NCi0vLwkJCWIJCQktCVRoZQljb2VmZmljaWVudCAiYiIgb2YgdGhlIG1hdHJpeC4NCi0vLwkJCWMJCQktCVRoZSBjb2VmZmljaWVudCAiYyIgb2YgdGhlIG1hdHJpeC4NCi0vLwkJCWQJCQktCVRoZSBjb2VmZmljaWVudCAiZCIgb2YgdGhlIG1hdHJpeC4NCi0vLwkJCWUJCQktCVRoZSBjb2VmZmljaWVudCAiZSIgb2YgdGhlIG1hdHJpeC4NCi0vLwkJCWYJCQktCVRoZSBjb2VmZmljaWVudCAiZiIgb2YgdGhlIG1hdHJpeC4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlOb25lLg0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VPYmpfVHJhbnNmb3JtKEZQREZfUEFHRU9CSkVDVCBwYWdlX29iamVjdCwNCi0JCQkJCQkJZG91YmxlIGEsIGRvdWJsZSBiLCBkb3VibGUgYywgZG91YmxlIGQsIGRvdWJsZSBlLCBkb3VibGUgZik7DQotDQotLy8gRnVuY3Rpb246IEZQREZQYWdlX1RyYW5zZm9ybUFubm90cw0KLS8vCQkJVHJhbnNmb3JtIChzY2FsZSwgcm90YXRlLCBzaGVhciwgbW92ZSkgYWxsIGFubm90cyBpbiBhIHBhZ2UuDQotLy8gUGFyYW1ldGVyczoJDQotLy8JCQlwYWdlCQktCUhhbmRsZSB0byBhIHBhZ2UuDQotLy8JCQlhCQkJLQlUaGUgY29lZmZpY2llbnQgImEiIG9mIHRoZSBtYXRyaXguDQotLy8JCQliCQkJLQlUaGUJY29lZmZpY2llbnQgImIiIG9mIHRoZSBtYXRyaXguDQotLy8JCQljCQkJLQlUaGUgY29lZmZpY2llbnQgImMiIG9mIHRoZSBtYXRyaXguDQotLy8JCQlkCQkJLQlUaGUgY29lZmZpY2llbnQgImQiIG9mIHRoZSBtYXRyaXguDQotLy8JCQllCQkJLQlUaGUgY29lZmZpY2llbnQgImUiIG9mIHRoZSBtYXRyaXguDQotLy8JCQlmCQkJLQlUaGUgY29lZmZpY2llbnQgImYiIG9mIHRoZSBtYXRyaXguDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJTm9uZS4NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX1RyYW5zZm9ybUFubm90cyhGUERGX1BBR0UgcGFnZSwNCi0JCQkJCQkJCQkJCSBkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKTsNCi0NCi0vLyBUaGUgcGFnZSBvYmplY3QgY29uc3RhbnRzLg0KLSNkZWZpbmUgRlBERl9QQUdFT0JKX1RFWFQJCTENCi0jZGVmaW5lIEZQREZfUEFHRU9CSl9QQVRICQkyDQotI2RlZmluZSBGUERGX1BBR0VPQkpfSU1BR0UJCTMNCi0jZGVmaW5lIEZQREZfUEFHRU9CSl9TSEFESU5HCTQNCi0jZGVmaW5lIEZQREZfUEFHRU9CSl9GT1JNCQk1DQotDQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KLS8vDQotLy8gSW1hZ2UgZnVuY3Rpb25zDQotLy8NCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotDQotLy8gRnVuY3Rpb246IEZQREZQYWdlT2JqX05ld0ltZ2VPYmoNCi0vLwkJCUNyZWF0ZSBhIG5ldyBJbWFnZSBPYmplY3QuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWRvY3VtZW50CQktCUhhbmRsZSB0byBkb2N1bWVudC4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkRG9jdW1lbnQgb3IgRlBERl9DcmVhdGVOZXdEb2N1bWVudCBmdW5jdGlvbi4NCi0vLyBSZXR1cm4gVmFsdWU6DQotLy8JCQlIYW5kbGUgb2YgaW1hZ2Ugb2JqZWN0Lg0KLURMTEVYUE9SVCBGUERGX1BBR0VPQkpFQ1QgU1REQ0FMTCBGUERGUGFnZU9ial9OZXdJbWdlT2JqKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpOw0KLQ0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGSW1hZ2VPYmpfTG9hZEpwZWdGaWxlDQotLy8JCQlMb2FkIEltYWdlIGZyb20gYSBKUEVHIGltYWdlIGZpbGUgYW5kIHRoZW4gc2V0IGl0IHRvIGFuIGltYWdlIG9iamVjdC4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJcGFnZXMJCQktCVBvaW50ZXJzIHRvIHRoZSBzdGFydCBvZiBhbGwgbG9hZGVkIHBhZ2VzLCBjb3VsZCBiZSBOVUxMLg0KLS8vCQkJbkNvdW50CQkJLQlOdW1iZXIgb2YgcGFnZXMsIGNvdWxkIGJlIDAuDQotLy8JCQlpbWFnZV9vYmplY3QJLQlIYW5kbGUgb2YgaW1hZ2Ugb2JqZWN0IHJldHVybmVkIGJ5IEZQREZQYWdlT2JqX05ld0ltZ2VPYmouDQotLy8JCQlmaWxlQWNjZXNzCQktCVRoZSBjdXN0b20gZmlsZSBhY2Nlc3MgaGFuZGxlciwgd2hpY2ggc3BlY2lmaWVzIHRoZSBKUEVHIGltYWdlIGZpbGUuDQotLy8JUmV0dXJuIFZhbHVlOg0KLS8vCQkJVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuDQotLy8gIE5vdGU6IA0KLS8vCQkJVGhlIGltYWdlIG9iamVjdCBtaWdodCBhbHJlYWR5IGhhcyBhbiBhc3NvY2lhdGVkIGltYWdlLCB3aGljaCBpcyBzaGFyZWQgYW5kIGNhY2hlZCBieSB0aGUgbG9hZGVkIHBhZ2VzLCBJbiB0aGlzIGNhc2UsIHdlIG5lZWQgdG8gY2xlYXIgdGhlIGNhY2hlIG9mIGltYWdlIGZvciBhbGwgdGhlIGxvYWRlZCBwYWdlcy4NCi0vLwkJCVBhc3MgcGFnZXMgYW5kIGNvdW50IHRvIHRoaXMgQVBJIHRvIGNsZWFyIHRoZSBpbWFnZSBjYWNoZS4gDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZJbWFnZU9ial9Mb2FkSnBlZ0ZpbGUoRlBERl9QQUdFKiBwYWdlcywgaW50IG5Db3VudCxGUERGX1BBR0VPQkpFQ1QgaW1hZ2Vfb2JqZWN0LCBGUERGX0ZJTEVBQ0NFU1MqIGZpbGVBY2Nlc3MpOw0KLQ0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGSW1hZ2VPYmpfU2V0TWF0cml4DQotLy8JCQlTZXQgdGhlIG1hdHJpeCBvZiBhbiBpbWFnZSBvYmplY3QuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWltYWdlX29iamVjdAktCUhhbmRsZSBvZiBpbWFnZSBvYmplY3QgcmV0dXJuZWQgYnkgRlBERlBhZ2VPYmpfTmV3SW1nZU9iai4NCi0vLwkJCWEJCQkJLQlUaGUgY29lZmZpY2llbnQgImEiIG9mIHRoZSBtYXRyaXguDQotLy8JCQliCQkJCS0JVGhlIGNvZWZmaWNpZW50ICJiIiBvZiB0aGUgbWF0cml4Lg0KLS8vCQkJYwkJCQktCVRoZSBjb2VmZmljaWVudCAiYyIgb2YgdGhlIG1hdHJpeC4NCi0vLwkJCWQJCQkJLQlUaGUgY29lZmZpY2llbnQgImQiIG9mIHRoZSBtYXRyaXguDQotLy8JCQllCQkJCS0JVGhlIGNvZWZmaWNpZW50ICJlIiBvZiB0aGUgbWF0cml4Lg0KLS8vCQkJZgkJCQktCVRoZSBjb2VmZmljaWVudCAiZiIgb2YgdGhlIG1hdHJpeC4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZJbWFnZU9ial9TZXRNYXRyaXgoRlBERl9QQUdFT0JKRUNUIGltYWdlX29iamVjdCwNCi0JCQkJCQkJCQkJCSBkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkltYWdlT2JqX1NldEJpdG1hcA0KLS8vCQkJU2V0IHRoZSBiaXRtYXAgdG8gYW4gaW1hZ2Ugb2JqZWN0Lg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQlwYWdlcwkJCS0JUG9pbnRlcidzIHRvIHRoZSBzdGFydCBvZiBhbGwgbG9hZGVkIHBhZ2VzLg0KLS8vCQkJbkNvdW50CQkJLQlOdW1iZXIgb2YgcGFnZXMuDQotLy8JCQlpbWFnZV9vYmplY3QJLQlIYW5kbGUgb2YgaW1hZ2Ugb2JqZWN0IHJldHVybmVkIGJ5IEZQREZQYWdlT2JqX05ld0ltZ2VPYmouDQotLy8JCQliaXRtYXAJCQktCVRoZSBoYW5kbGUgb2YgdGhlIGJpdG1hcCB3aGljaCB5b3Ugd2FudCB0byBzZXQgaXQgdG8gdGhlIGltYWdlIG9iamVjdC4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZJbWFnZU9ial9TZXRCaXRtYXAoRlBERl9QQUdFKiBwYWdlcyxpbnQgbkNvdW50LEZQREZfUEFHRU9CSkVDVCBpbWFnZV9vYmplY3QsIEZQREZfQklUTUFQIGJpdG1hcCk7DQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfQ0KLSNlbmRpZg0KLSNlbmRpZiAvLyBfRlBERkVESVRfSF8NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmCV9GUERGRURJVF9IXworI2RlZmluZQlfRlBERkVESVRfSF8KKworI2luY2x1ZGUgImZwZGZ2aWV3LmgiCisKKy8vIERlZmluZSBhbGwgdHlwZXMgdXNlZCBpbiB0aGUgU0RLLiBOb3RlIHRoZXkgY2FuIGJlIHNpbXBseSByZWdhcmRlZCBhcyBvcGFxdWUgcG9pbnRlcnMKKy8vIG9yIGxvbmcgaW50ZWdlciBudW1iZXJzLgorCisjZGVmaW5lIEZQREZfQVJHQihhLHIsZyxiKQkJKCgoKEZYX0RXT1JEKSgoKEZYX0JZVEUpKGIpfCgoRlhfV09SRCkoKEZYX0JZVEUpKGcpKTw8OCkpfCgoKEZYX0RXT1JEKShGWF9CWVRFKShyKSk8PDE2KSkpKSB8ICgoKEZYX0RXT1JEKShGWF9CWVRFKShhKSk8PDI0KSkKKyNkZWZpbmUgRlBERl9HZXRCVmFsdWUoYXJnYikgICAgKChGWF9CWVRFKShhcmdiKSkKKyNkZWZpbmUgRlBERl9HZXRHVmFsdWUoYXJnYikgICAgKChGWF9CWVRFKSgoKEZYX1dPUkQpKGFyZ2IpKSA+PiA4KSkKKyNkZWZpbmUgRlBERl9HZXRSVmFsdWUoYXJnYikgICAgKChGWF9CWVRFKSgoYXJnYik+PjE2KSkKKyNkZWZpbmUgRlBERl9HZXRBVmFsdWUoYXJnYikgICAgKChGWF9CWVRFKSgoYXJnYik+PjI0KSkKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisvLworLy8gRG9jdW1lbnQgZnVuY3Rpb25zCisvLworLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisvLyBGdW5jdGlvbjogRlBERl9DcmVhdGVOZXdEb2N1bWVudAorLy8JCQlDcmVhdGUgYSBuZXcgUERGIGRvY3VtZW50LgorLy8gUGFyYW1ldGVyczoJCisvLwkJCU5vbmUuCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCUEgaGFuZGxlIHRvIGEgZG9jdW1lbnQuIElmIGZhaWxlZCwgTlVMTCBpcyByZXR1cm5lZC4KK0RMTEVYUE9SVCBGUERGX0RPQ1VNRU5UIFNURENBTEwgRlBERl9DcmVhdGVOZXdEb2N1bWVudCgpOworCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisvLworLy8gUGFnZSBmdW5jdGlvbnMKKy8vCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKy8vIEZ1bmN0aW9uOiBGUERGUGFnZV9OZXcKKy8vCQkJQ29uc3RydWN0IGFuIGVtcHR5IHBhZ2UuCisvLyBQYXJhbWV0ZXJzOgkKKy8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGFuZCBGUERGX0NyZWF0ZU5ld0RvY3VtZW50LgorLy8JCQlwYWdlX2luZGV4CS0JVGhlIGluZGV4IG9mIGEgcGFnZS4KKy8vCQkJd2lkdGgJCS0JVGhlIHBhZ2Ugd2lkdGguCisvLwkJCWhlaWdodAkJLQlUaGUgcGFnZSBoZWlnaHQuCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRoZSBoYW5kbGUgdG8gdGhlIHBhZ2UuCisvLyBDb21tZW50czoKKy8vCQkJTG9hZGVkIHBhZ2UgY2FuIGJlIGRlbGV0ZWQgYnkgRlBERlBhZ2VfRGVsZXRlLgorRExMRVhQT1JUIEZQREZfUEFHRSBTVERDQUxMIEZQREZQYWdlX05ldyhGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBpbnQgcGFnZV9pbmRleCwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0KTsKKworLy8gRnVuY3Rpb246IEZQREZQYWdlX0RlbGV0ZQorLy8JCQlEZWxldGUgYSBQREYgcGFnZS4KKy8vIFBhcmFtZXRlcnM6CQorLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byBkb2N1bWVudC4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkRG9jdW1lbnQgYW5kIEZQREZfQ3JlYXRlTmV3RG9jdW1lbnQuCisvLwkJCXBhZ2VfaW5kZXgJLQlUaGUgaW5kZXggb2YgYSBwYWdlLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOb25lLgorRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGUGFnZV9EZWxldGUoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgaW50IHBhZ2VfaW5kZXgpOworCisvLyBGdW5jdGlvbjogRlBERlBhZ2VfR2V0Um90YXRpb24KKy8vCQkJR2V0IHRoZSBwYWdlIHJvdGF0aW9uLiBPbmUgb2YgZm9sbG93aW5nIHZhbHVlcyB3aWxsIGJlIHJldHVybmVkOiAwKDApLCAxKDkwKSwgMigxODApLCAzKDI3MCkuCisvLyBQYXJhbWV0ZXJzOgkKKy8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gYSBwYWdlLiBSZXR1cm5lZCBieSBGUERGUGFnZV9OZXcuCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRoZSBQREYgcGFnZSByb3RhdGlvbi4KKy8vIENvbW1lbnQ6CisvLwkJCVRoZSBQREYgcGFnZSByb3RhdGlvbiBpcyByb3RhdGVkIGNsb2Nrd2lzZS4KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGUGFnZV9HZXRSb3RhdGlvbihGUERGX1BBR0UgcGFnZSk7CisKKy8vIEZ1bmN0aW9uOiBGUERGUGFnZV9JbnNlcnRPYmplY3QKKy8vCQkJSW5zZXJ0IGFuIG9iamVjdCB0byB0aGUgcGFnZS4gVGhlIHBhZ2Ugb2JqZWN0IGlzIGF1dG9tYXRpY2FsbHkgZnJlZWQuCisvLyBQYXJhbWV0ZXJzOgkKKy8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gYSBwYWdlLiBSZXR1cm5lZCBieSBGUERGUGFnZV9OZXcuCisvLwkJCXBhZ2Vfb2JqCS0JSGFuZGxlIHRvIGEgcGFnZSBvYmplY3QuIFJldHVybmVkIGJ5IEZQREZQYWdlT2JqX05ld1RleHRPYmosRlBERlBhZ2VPYmpfTmV3VGV4dE9iakV4IGFuZAorLy8JCQkJCQkJRlBERlBhZ2VPYmpfTmV3UGF0aE9iai4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTm9uZS4KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VfSW5zZXJ0T2JqZWN0KEZQREZfUEFHRSBwYWdlLCBGUERGX1BBR0VPQkpFQ1QgcGFnZV9vYmopOworCisvLyBGdW5jdGlvbjogRlBERlBhZ2VfQ291bnRPYmplY3QKKy8vCQkJR2V0IG51bWJlciBvZiBwYWdlIG9iamVjdHMgaW5zaWRlIHRoZSBwYWdlLgorLy8gUGFyYW1ldGVyczoJCisvLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIGEgcGFnZS4gUmV0dXJuZWQgYnkgRlBERlBhZ2VfTmV3LgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUaGUgbnVtYmVyIG9mIHRoZSBwYWdlIG9iamVjdC4KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGUGFnZV9Db3VudE9iamVjdChGUERGX1BBR0UgcGFnZSk7CisKKy8vIEZ1bmN0aW9uOiBGUERGUGFnZV9HZXRPYmplY3QKKy8vCQkJR2V0IHBhZ2Ugb2JqZWN0IGJ5IGluZGV4LgorLy8gUGFyYW1ldGVyczoJCisvLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIGEgcGFnZS4gUmV0dXJuZWQgYnkgRlBERlBhZ2VfTmV3LgorLy8JCQlpbmRleAkJLQlUaGUgaW5kZXggb2YgYSBwYWdlIG9iamVjdC4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJVGhlIGhhbmRsZSBvZiB0aGUgcGFnZSBvYmplY3QuIE51bGwgZm9yIGZhaWxlZC4KK0RMTEVYUE9SVCBGUERGX1BBR0VPQkpFQ1QgU1REQ0FMTCBGUERGUGFnZV9HZXRPYmplY3QoRlBERl9QQUdFIHBhZ2UsIGludCBpbmRleCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGUGFnZV9IYXNUcmFuc3BhcmVuY3kKKy8vCQkJQ2hlY2sgdGhhdCB3aGV0aGVyIHRoZSBjb250ZW50IG9mIHNwZWNpZmllZCBQREYgcGFnZSBjb250YWlucyB0cmFuc3BhcmVuY3kuCisvLyBQYXJhbWV0ZXJzOgkKKy8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gYSBwYWdlLiBSZXR1cm5lZCBieSBGUERGUGFnZV9OZXcgb3IgRlBERl9Mb2FkUGFnZS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJVFJVRSBtZWFucyB0aGF0IHRoZSBQREYgcGFnZSBkb2VzIGNvbnRhaW5zIHRyYW5zcGFyZW5jeS4KKy8vCQkJT3RoZXJ3aXNlLCByZXR1cm5zIEZBTFNFLgorRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlX0hhc1RyYW5zcGFyZW5jeShGUERGX1BBR0UgcGFnZSk7CisKKy8vIEZ1bmN0aW9uOiBGUERGUGFnZV9HZW5lcmF0ZUNvbnRlbnQKKy8vCQkJR2VuZXJhdGUgUERGIFBhZ2UgY29udGVudC4KKy8vIFBhcmFtZXRlcnM6CQorLy8JCQlwYWdlCQktCUhhbmRsZSB0byBhIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZQYWdlX05ldy4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJVHJ1ZSBpZiBzdWNjZXNzZnVsLCBmYWxzZSBvdGhlcndpc2UuCisvLyBDb21tZW50OgorLy8JCQlCZWZvcmUgeW91IHNhdmUgdGhlIHBhZ2UgdG8gYSBmaWxlLCBvciByZWxvYWQgdGhlIHBhZ2UsIHlvdSBtdXN0IGNhbGwgdGhlIEZQREZQYWdlX0dlbmVyYXRlQ29udGVudCBmdW5jdGlvbi4KKy8vCQkJT3IgdGhlIGNoYW5nZWQgaW5mb3JtYXRpb24gd2lsbCBiZSBsb3N0LgorRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlX0dlbmVyYXRlQ29udGVudChGUERGX1BBR0UgcGFnZSk7CisKKy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKy8vCisvLyBQYWdlIE9iamVjdCBmdW5jdGlvbnMKKy8vCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKy8vIEZ1bmN0aW9uOiBGUERGUGFnZU9ial9IYXNUcmFuc3BhcmVuY3kKKy8vCQkJQ2hlY2sgdGhhdCB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgUERGIHBhZ2Ugb2JqZWN0IGNvbnRhaW5zIHRyYW5zcGFyZW5jeS4KKy8vIFBhcmFtZXRlcnM6CQorLy8JCQlwYWdlT2JqZWN0CS0JSGFuZGxlIHRvIGEgcGFnZSBvYmplY3QuCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRSVUUgbWVhbnMgdGhhdCB0aGUgUERGIHBhZ2Ugb2JqZWN0IGRvZXMgY29udGFpbnMgdHJhbnNwYXJlbmN5LgorLy8JCQlPdGhlcndpc2UsIHJldHVybnMgRkFMU0UuCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VPYmpfSGFzVHJhbnNwYXJlbmN5KEZQREZfUEFHRU9CSkVDVCBwYWdlT2JqZWN0KTsKKworLy8gRnVuY3Rpb246IEZQREZQYWdlT2JqX1RyYW5zZm9ybQorLy8JCQlUcmFuc2Zvcm0gKHNjYWxlLCByb3RhdGUsIHNoZWFyLCBtb3ZlKSBwYWdlIG9iamVjdC4KKy8vIFBhcmFtZXRlcnM6CQorLy8JCQlwYWdlX29iamVjdAktCUhhbmRsZSB0byBhIHBhZ2Ugb2JqZWN0LiBSZXR1cm5lZCBieSBGUERGUGFnZU9ial9OZXdJbWFnZU9iai4KKy8vCQkJYQkJCS0JVGhlIGNvZWZmaWNpZW50ICJhIiBvZiB0aGUgbWF0cml4LgorLy8JCQliCQkJLQlUaGUJY29lZmZpY2llbnQgImIiIG9mIHRoZSBtYXRyaXguCisvLwkJCWMJCQktCVRoZSBjb2VmZmljaWVudCAiYyIgb2YgdGhlIG1hdHJpeC4KKy8vCQkJZAkJCS0JVGhlIGNvZWZmaWNpZW50ICJkIiBvZiB0aGUgbWF0cml4LgorLy8JCQllCQkJLQlUaGUgY29lZmZpY2llbnQgImUiIG9mIHRoZSBtYXRyaXguCisvLwkJCWYJCQktCVRoZSBjb2VmZmljaWVudCAiZiIgb2YgdGhlIG1hdHJpeC4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTm9uZS4KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VPYmpfVHJhbnNmb3JtKEZQREZfUEFHRU9CSkVDVCBwYWdlX29iamVjdCwKKwkJCQkJCQlkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKTsKKworLy8gRnVuY3Rpb246IEZQREZQYWdlX1RyYW5zZm9ybUFubm90cworLy8JCQlUcmFuc2Zvcm0gKHNjYWxlLCByb3RhdGUsIHNoZWFyLCBtb3ZlKSBhbGwgYW5ub3RzIGluIGEgcGFnZS4KKy8vIFBhcmFtZXRlcnM6CQorLy8JCQlwYWdlCQktCUhhbmRsZSB0byBhIHBhZ2UuCisvLwkJCWEJCQktCVRoZSBjb2VmZmljaWVudCAiYSIgb2YgdGhlIG1hdHJpeC4KKy8vCQkJYgkJCS0JVGhlCWNvZWZmaWNpZW50ICJiIiBvZiB0aGUgbWF0cml4LgorLy8JCQljCQkJLQlUaGUgY29lZmZpY2llbnQgImMiIG9mIHRoZSBtYXRyaXguCisvLwkJCWQJCQktCVRoZSBjb2VmZmljaWVudCAiZCIgb2YgdGhlIG1hdHJpeC4KKy8vCQkJZQkJCS0JVGhlIGNvZWZmaWNpZW50ICJlIiBvZiB0aGUgbWF0cml4LgorLy8JCQlmCQkJLQlUaGUgY29lZmZpY2llbnQgImYiIG9mIHRoZSBtYXRyaXguCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCU5vbmUuCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX1RyYW5zZm9ybUFubm90cyhGUERGX1BBR0UgcGFnZSwKKwkJCQkJCQkJCQkJIGRvdWJsZSBhLCBkb3VibGUgYiwgZG91YmxlIGMsIGRvdWJsZSBkLCBkb3VibGUgZSwgZG91YmxlIGYpOworCisvLyBUaGUgcGFnZSBvYmplY3QgY29uc3RhbnRzLgorI2RlZmluZSBGUERGX1BBR0VPQkpfVEVYVAkJMQorI2RlZmluZSBGUERGX1BBR0VPQkpfUEFUSAkJMgorI2RlZmluZSBGUERGX1BBR0VPQkpfSU1BR0UJCTMKKyNkZWZpbmUgRlBERl9QQUdFT0JKX1NIQURJTkcJNAorI2RlZmluZSBGUERGX1BBR0VPQkpfRk9STQkJNQorCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisvLworLy8gSW1hZ2UgZnVuY3Rpb25zCisvLworLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCisvLyBGdW5jdGlvbjogRlBERlBhZ2VPYmpfTmV3SW1nZU9iagorLy8JCQlDcmVhdGUgYSBuZXcgSW1hZ2UgT2JqZWN0LgorLy8gUGFyYW1ldGVyczoKKy8vCQkJZG9jdW1lbnQJCS0JSGFuZGxlIHRvIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBvciBGUERGX0NyZWF0ZU5ld0RvY3VtZW50IGZ1bmN0aW9uLgorLy8gUmV0dXJuIFZhbHVlOgorLy8JCQlIYW5kbGUgb2YgaW1hZ2Ugb2JqZWN0LgorRExMRVhQT1JUIEZQREZfUEFHRU9CSkVDVCBTVERDQUxMIEZQREZQYWdlT2JqX05ld0ltZ2VPYmooRlBERl9ET0NVTUVOVCBkb2N1bWVudCk7CisKKworLy8gRnVuY3Rpb246IEZQREZJbWFnZU9ial9Mb2FkSnBlZ0ZpbGUKKy8vCQkJTG9hZCBJbWFnZSBmcm9tIGEgSlBFRyBpbWFnZSBmaWxlIGFuZCB0aGVuIHNldCBpdCB0byBhbiBpbWFnZSBvYmplY3QuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlwYWdlcwkJCS0JUG9pbnRlcnMgdG8gdGhlIHN0YXJ0IG9mIGFsbCBsb2FkZWQgcGFnZXMsIGNvdWxkIGJlIE5VTEwuCisvLwkJCW5Db3VudAkJCS0JTnVtYmVyIG9mIHBhZ2VzLCBjb3VsZCBiZSAwLgorLy8JCQlpbWFnZV9vYmplY3QJLQlIYW5kbGUgb2YgaW1hZ2Ugb2JqZWN0IHJldHVybmVkIGJ5IEZQREZQYWdlT2JqX05ld0ltZ2VPYmouCisvLwkJCWZpbGVBY2Nlc3MJCS0JVGhlIGN1c3RvbSBmaWxlIGFjY2VzcyBoYW5kbGVyLCB3aGljaCBzcGVjaWZpZXMgdGhlIEpQRUcgaW1hZ2UgZmlsZS4KKy8vCVJldHVybiBWYWx1ZToKKy8vCQkJVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCisvLyAgTm90ZTogCisvLwkJCVRoZSBpbWFnZSBvYmplY3QgbWlnaHQgYWxyZWFkeSBoYXMgYW4gYXNzb2NpYXRlZCBpbWFnZSwgd2hpY2ggaXMgc2hhcmVkIGFuZCBjYWNoZWQgYnkgdGhlIGxvYWRlZCBwYWdlcywgSW4gdGhpcyBjYXNlLCB3ZSBuZWVkIHRvIGNsZWFyIHRoZSBjYWNoZSBvZiBpbWFnZSBmb3IgYWxsIHRoZSBsb2FkZWQgcGFnZXMuCisvLwkJCVBhc3MgcGFnZXMgYW5kIGNvdW50IHRvIHRoaXMgQVBJIHRvIGNsZWFyIHRoZSBpbWFnZSBjYWNoZS4gCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkltYWdlT2JqX0xvYWRKcGVnRmlsZShGUERGX1BBR0UqIHBhZ2VzLCBpbnQgbkNvdW50LEZQREZfUEFHRU9CSkVDVCBpbWFnZV9vYmplY3QsIEZQREZfRklMRUFDQ0VTUyogZmlsZUFjY2Vzcyk7CisKKworLy8gRnVuY3Rpb246IEZQREZJbWFnZU9ial9TZXRNYXRyaXgKKy8vCQkJU2V0IHRoZSBtYXRyaXggb2YgYW4gaW1hZ2Ugb2JqZWN0LgorLy8gUGFyYW1ldGVyczoKKy8vCQkJaW1hZ2Vfb2JqZWN0CS0JSGFuZGxlIG9mIGltYWdlIG9iamVjdCByZXR1cm5lZCBieSBGUERGUGFnZU9ial9OZXdJbWdlT2JqLgorLy8JCQlhCQkJCS0JVGhlIGNvZWZmaWNpZW50ICJhIiBvZiB0aGUgbWF0cml4LgorLy8JCQliCQkJCS0JVGhlIGNvZWZmaWNpZW50ICJiIiBvZiB0aGUgbWF0cml4LgorLy8JCQljCQkJCS0JVGhlIGNvZWZmaWNpZW50ICJjIiBvZiB0aGUgbWF0cml4LgorLy8JCQlkCQkJCS0JVGhlIGNvZWZmaWNpZW50ICJkIiBvZiB0aGUgbWF0cml4LgorLy8JCQllCQkJCS0JVGhlIGNvZWZmaWNpZW50ICJlIiBvZiB0aGUgbWF0cml4LgorLy8JCQlmCQkJCS0JVGhlIGNvZWZmaWNpZW50ICJmIiBvZiB0aGUgbWF0cml4LgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkltYWdlT2JqX1NldE1hdHJpeChGUERGX1BBR0VPQkpFQ1QgaW1hZ2Vfb2JqZWN0LAorCQkJCQkJCQkJCQkgZG91YmxlIGEsIGRvdWJsZSBiLCBkb3VibGUgYywgZG91YmxlIGQsIGRvdWJsZSBlLCBkb3VibGUgZik7CisKKy8vIEZ1bmN0aW9uOiBGUERGSW1hZ2VPYmpfU2V0Qml0bWFwCisvLwkJCVNldCB0aGUgYml0bWFwIHRvIGFuIGltYWdlIG9iamVjdC4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCXBhZ2VzCQkJLQlQb2ludGVyJ3MgdG8gdGhlIHN0YXJ0IG9mIGFsbCBsb2FkZWQgcGFnZXMuCisvLwkJCW5Db3VudAkJCS0JTnVtYmVyIG9mIHBhZ2VzLgorLy8JCQlpbWFnZV9vYmplY3QJLQlIYW5kbGUgb2YgaW1hZ2Ugb2JqZWN0IHJldHVybmVkIGJ5IEZQREZQYWdlT2JqX05ld0ltZ2VPYmouCisvLwkJCWJpdG1hcAkJCS0JVGhlIGhhbmRsZSBvZiB0aGUgYml0bWFwIHdoaWNoIHlvdSB3YW50IHRvIHNldCBpdCB0byB0aGUgaW1hZ2Ugb2JqZWN0LgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4gCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkltYWdlT2JqX1NldEJpdG1hcChGUERGX1BBR0UqIHBhZ2VzLGludCBuQ291bnQsRlBERl9QQUdFT0JKRUNUIGltYWdlX29iamVjdCwgRlBERl9CSVRNQVAgYml0bWFwKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKKyNlbmRpZiAvLyBfRlBERkVESVRfSF8KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmZm9ybWZpbGwuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mcGRmZm9ybWZpbGwuaAppbmRleCAwZTc1NTZlLi41MGEyZGZmIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnBkZmZvcm1maWxsLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZmb3JtZmlsbC5oCkBAIC0xLDg0MSArMSw4NDEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLQ0KLSNpZm5kZWYgX0ZQREZPUk1GSUxMX0gNCi0jZGVmaW5lIF9GUERGT1JNRklMTF9IDQotI2luY2x1ZGUgImZwZGZ2aWV3LmgiDQotDQotdHlwZWRlZiB2b2lkKiBGUERGX0ZPUk1IQU5ETEU7DQotDQotLy8gRXhwb3J0ZWQgRnVuY3Rpb25zDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotZXh0ZXJuICJDIiB7DQotI2VuZGlmDQotDQotdHlwZWRlZiBzdHJ1Y3QgX0lQREZfSnNQbGF0Zm9ybQ0KLXsNCi0vKioNCi0qIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcmZhY2UuIEN1cnJlbnRseSBtdXN0IGJlIDEuDQotCSoqLw0KLQlpbnQgdmVyc2lvbjsNCi0JDQotCS8qKiANCi0JKiBNZXRob2Q6IGFwcF9hbGVydA0KLQkqCQkJcG9wIHVwIGEgZGlhbG9nIHRvIHNob3cgd2FybmluZyBvciBoaW50Lg0KLQkqIEludGVyZmFjZSBWZXJzaW9uOg0KLQkqCQkJMQ0KLQkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOg0KLQkqCQkJeWVzDQotCSogUGFyYW1ldGVyczoNCi0JKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmDQotCSoJCQlNc2cJCQktCUEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkLg0KLQkqCQkJVGl0bGUJCS0gICBUaGUgdGl0bGUgb2YgdGhlIGRpYWxvZy4NCi0JKgkJCVR5cGUJCS0JVGhlIHN0eXBlIG9mIGJ1dHRvbiBncm91cC4gDQotCSoJCQkJCQkJMC1PSyhkZWZhdWx0KTsNCi0JKgkJCQkJCQkxLU9LLENhbmNlbDsNCi0JKgkJCQkJCQkyLVllcyxOTzsgDQotCSoJCQkJCQkJMy1ZZXMsIE5PLCBDYW5jZWwuDQotCSogICAgICAgICAgIG5JY29uCQktICAgVGhlIEljb24gdHlwZS4gDQotCSoJCQkJCQkJMC1FcnJvcihkZWZhdWx0KTsNCi0JKgkJCQkJCQkxLVdhcm5pbmc7DQotCSoJCQkJCQkJMi1RdWVzdGlvbjsNCi0JKgkJCQkJCQkzLVN0YXR1cy4NCi0JKiBSZXR1cm4gVmFsdWU6DQotCSoJCQlUaGUgcmV0dXJuIHZhbHVlIGNvdWxkIGJlIHRoZSBmb2xvd2luZyB0eXBlOg0KLQkqCQkJCQkJCTEtT0s7DQotCSoJCQkJCQkJMi1DYW5jZWw7IA0KLQkqCQkJCQkJCTMtTk87DQotCSoJCQkJCQkJNC1ZZXM7DQotCSovDQotCWludCAoKmFwcF9hbGVydCkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLCBGUERGX1dJREVTVFJJTkcgTXNnLCBGUERGX1dJREVTVFJJTkcgVGl0bGUsIGludCBUeXBlLCBpbnQgSWNvbik7DQotCQ0KLQkvKiogDQotCSogTWV0aG9kOiBhcHBfYmVlcA0KLQkqCQkJQ2F1c2VzIHRoZSBzeXN0ZW0gdG8gcGxheSBhIHNvdW5kLiANCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCXllcw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZg0KLQkqCQkJblR5cGUJCS0JVGhlIHNvdW5kIHR5cGUuDQotCSoJCQkJCQkJMCAtIEVycm9yDQotCSoJCQkJCQkJMSAtIFdhcm5pbmcNCi0JKgkJCQkJCQkyIC0gUXVlc3Rpb24NCi0JKgkJCQkJCQkzIC0gU3RhdHVzDQotCSoJCQkJCQkJNCAtIERlZmF1bHQgKGRlZmF1bHQgdmFsdWUpDQotCSogUmV0dXJuIFZhbHVlOg0KLQkqCQkJTm9uZQ0KLQkqLw0KLQl2b2lkICgqYXBwX2JlZXApKHN0cnVjdCBfSVBERl9Kc1BsYXRmb3JtKiBwVGhpcywgIGludCBuVHlwZSk7DQotCQ0KLQkNCi0JLyoqIA0KLQkqIE1ldGhvZDogYXBwX3Jlc3BvbnNlDQotCSoJCQlEaXNwbGF5cyBhIGRpYWxvZyBib3ggY29udGFpbmluZyBhIHF1ZXN0aW9uIGFuZCBhbiBlbnRyeSBmaWVsZCBmb3IgdGhlIHVzZXIgdG8gcmVwbHkgdG8gdGhlIHF1ZXN0aW9uLiAgDQotCSogSW50ZXJmYWNlIFZlcnNpb246DQotCSoJCQkxDQotCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCSoJCQl5ZXMNCi0JKiBQYXJhbWV0ZXJzOg0KLQkqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYNCi0JKgkJCVF1ZXN0aW9uCS0JVGhlIHF1ZXN0aW9uIHRvIGJlIHBvc2VkIHRvIHRoZSB1c2VyLg0KLQkqCQkJVGl0bGUJCS0JVGhlIHRpdGxlIG9mIHRoZSBkaWFsb2cgYm94Lg0KLQkqCQkJRGVmYXVsdAkJLQlBIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSBhbnN3ZXIgdG8gdGhlIHF1ZXN0aW9uLiBJZiBub3Qgc3BlY2lmaWVkLCBubyBkZWZhdWx0IHZhbHVlIGlzIHByZXNlbnRlZC4NCi0JKgkJCWNMYWJlbAkJLQlBIHNob3J0IHN0cmluZyB0byBhcHBlYXIgaW4gZnJvbnQgb2YgYW5kIG9uIHRoZSBzYW1lIGxpbmUgYXMgdGhlIGVkaXQgdGV4dCBmaWVsZC4gDQotCSoJCQliUGFzc3dvcmQJLQlJZiB0cnVlLCBpbmRpY2F0ZXMgdGhhdCB0aGUgdXNlcidzIHJlc3BvbnNlIHNob3VsZCBzaG93IGFzIGFzdGVyaXNrcyAoKikgb3IgYnVsbGV0cyAoPykgdG8gbWFzayB0aGUgcmVzcG9uc2UsIHdoaWNoIG1pZ2h0IGJlIHNlbnNpdGl2ZSBpbmZvcm1hdGlvbi4gVGhlIGRlZmF1bHQgaXMgZmFsc2UuCQkNCi0JKgkJCXJlc3BvbnNlCS0JQSBzdHJpbmcgYnVmZmVyIGFsbG9jYXRlZCBieSBTREssIHRvIHJlY2VpdmUgdGhlIHVzZXIncyByZXNwb25zZS4gDQotCSoJCQlsZW5ndGgJCS0gICBUaGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIsIG51bWJlciBvZiBieXRlcy4gQ3VycmVudGx5LCBJdCdzIGFsd2F5cyBiZSAyMDQ4Lg0KLQkqIFJldHVybiBWYWx1ZToNCi0JKgkJCU51bWJlciBvZiBieXRlcyB0aGUgdXNlciBpbnB1dCB0ZXh0IGNvbnN1bWVzLCBub3QgaW5jbHVkaW5nIHRyYWlsaW5nIHplcm9zLiBJZiB0aGUgdGV4dCBleGNlZWQgMjA0OCBieXRlcywNCi0JKgkJCXRoZSBleGNlZWRlZCBwYXJ0IHdpbGwgYmUgaWdub3JlZC4NCi0JKiBDb21tZW50czoNCi0JKgkJCU5vIG1hdHRlciBvbiB3aGF0IHBsYXRmb3JtLCB0aGUgcmVzcG9uc2Ugc2hvdWxkIGJlIGFsd2F5cyBpbnB1dCBpbiBVVEYtMTZMRSBlbmNvZGluZy4NCi0JKgkJCVRoZSByZXR1cm4gdmFsdWUgYWx3YXlzIGluZGljYXRlZCBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgZm9yIHRoZSBidWZmZXIsIGV2ZW4gd2hlbiB0aGVyZSBpcw0KLQkqCQkJbm8gYnVmZmVyIHNwZWNpZmllZCwgb3IgdGhlIGJ1ZmZlciBzaXplIGlzIGxlc3MgdGhlbiByZXF1aXJlZC4gSW4gdGhpcyBjYXNlLCB0aGUgYnVmZmVyIHdpbGwgbm90DQotCSoJCQliZSBtb2RpZmllZC4NCi0JKi8NCi0JaW50ICgqYXBwX3Jlc3BvbnNlKShzdHJ1Y3QgX0lQREZfSnNQbGF0Zm9ybSogcFRoaXMsIEZQREZfV0lERVNUUklORyBRdWVzdGlvbiwgRlBERl9XSURFU1RSSU5HIFRpdGxlLCBGUERGX1dJREVTVFJJTkcgRGVmYXVsdCwgRlBERl9XSURFU1RSSU5HIGNMYWJlbCwgRlBERl9CT09MIGJQYXNzd29yZCwgdm9pZCogcmVzcG9uc2UsIGludCBsZW5ndGgpOw0KLQkNCi0JDQotCQ0KLQkvKg0KLQkqIE1ldGhvZDogRG9jX2dldEZpbGVQYXRoDQotCSoJCQlHZXQgdGhlIGZpbGUgcGF0aCBvZiB0aGUgY3VycmVudCBkb2N1bWVudC4gDQotCSogSW50ZXJmYWNlIFZlcnNpb246DQotCSoJCQkxDQotCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCSoJCQl5ZXMNCi0JKiBQYXJhbWV0ZXJzOg0KLQkqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYNCi0JKgkJCWZpbGVQYXRoCS0JVGhlIHN0cmluZyBidWZmZXIgdG8gcmVjZWl2ZSB0aGUgZmlsZSBwYXRoLiBDYW4gYmUgTlVMTC4NCi0JKgkJCWxlbmd0aAkJLSAgIFRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlciwgbnVtYmVyIG9mIGJ5dGVzLiBDYW4gYmUgMC4NCi0JKiBSZXR1cm4gVmFsdWU6DQotCSoJCU51bWJlciBvZiBieXRlcyB0aGUgZmlsZVBhdGggY29uc3VtZXMsIGluY2x1ZGluZyB0cmFpbGluZyB6ZXJvcy4NCi0JKiBDb21tZW50czoNCi0JKgkJVGhlIGZpbGVQYXRoIHNob3VsZCBiZSBhbHdheXMgaW5wdXQgaW4gbG9jYWwgZW5jb2RpbmcuDQotCSoNCi0JKgkJVGhlIHJldHVybiB2YWx1ZSBhbHdheXMgaW5kaWNhdGVkIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCBmb3IgdGhlIGJ1ZmZlciwgZXZlbiB3aGVuIHRoZXJlIGlzDQotCSoJCW5vIGJ1ZmZlciBzcGVjaWZpZWQsIG9yIHRoZSBidWZmZXIgc2l6ZSBpcyBsZXNzIHRoZW4gcmVxdWlyZWQuIEluIHRoaXMgY2FzZSwgdGhlIGJ1ZmZlciB3aWxsIG5vdA0KLQkqCQliZSBtb2RpZmllZC4NCi0JKi8NCi0JaW50ICgqRG9jX2dldEZpbGVQYXRoKShzdHJ1Y3QgX0lQREZfSnNQbGF0Zm9ybSogcFRoaXMsIHZvaWQqIGZpbGVQYXRoLCBpbnQgbGVuZ3RoKTsNCi0JDQotCQ0KLQkvKg0KLQkqIE1ldGhvZDogRG9jX21haWwNCi0JKgkJCU1haWxzIHRoZSBkYXRhIGJ1ZmZlciBhcyBhbiBhdHRhY2htZW50IHRvIGFsbCByZWNpcGllbnRzLCB3aXRoIG9yIHdpdGhvdXQgdXNlciBpbnRlcmFjdGlvbi4gDQotCSogSW50ZXJmYWNlIFZlcnNpb246DQotCSoJCQkxDQotCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCSoJCQl5ZXMNCi0JKiBQYXJhbWV0ZXJzOg0KLQkqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYNCi0JKgkJCW1haWxEYXRhCS0JUG9pbnRlciB0byB0aGUgZGF0YSBidWZmZXIgdG8gYmUgc2VudC5DYW4gYmUgTlVMTC4NCi0JKgkJCWxlbmd0aAkJLQlUaGUgc2l6ZSxpbiBieXRlcywgb2YgdGhlIGJ1ZmZlciBwb2ludGVkIGJ5IG1haWxEYXRhIHBhcmFtZXRlci5DYW4gYmUgMC4NCi0JKgkJCWJVSQkJCS0gICBJZiB0cnVlLCB0aGUgcmVzdCBvZiB0aGUgcGFyYW1ldGVycyBhcmUgdXNlZCBpbiBhIGNvbXBvc2UtbmV3LW1lc3NhZ2Ugd2luZG93IHRoYXQgaXMgZGlzcGxheWVkIHRvIHRoZSB1c2VyLiBJZiBmYWxzZSwgdGhlIGNUbyBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQgYW5kIGFsbCBvdGhlcnMgYXJlIG9wdGlvbmFsLg0KLQkqCQkJVG8JCQktCUEgc2VtaWNvbG9uLWRlbGltaXRlZCBsaXN0IG9mIHJlY2lwaWVudHMgZm9yIHRoZSBtZXNzYWdlLg0KLQkqCQkJU3ViamVjdAkJLSAgIFRoZSBzdWJqZWN0IG9mIHRoZSBtZXNzYWdlLiBUaGUgbGVuZ3RoIGxpbWl0IGlzIDY0IEtCLg0KLQkqCQkJQ0MJCQktCUEgc2VtaWNvbG9uLWRlbGltaXRlZCBsaXN0IG9mIENDIHJlY2lwaWVudHMgZm9yIHRoZSBtZXNzYWdlLiANCi0JKgkJCUJDQwkJCS0gICBBIHNlbWljb2xvbi1kZWxpbWl0ZWQgbGlzdCBvZiBCQ0MgcmVjaXBpZW50cyBmb3IgdGhlIG1lc3NhZ2UuIA0KLQkqCQkJTXNnCQkJLSAgIFRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlLiBUaGUgbGVuZ3RoIGxpbWl0IGlzIDY0IEtCLg0KLQkqIFJldHVybiBWYWx1ZToNCi0JKgkJCU5vbmUuDQotCSogQ29tbWVudHM6DQotCSoJCQlJZiB0aGUgcGFyYW1ldGVyIG1haWxEYXRhIGlzIE5VTEwgb3IgbGVuZ3RoIGlzIDAsIHRoZSBjdXJyZW50IGRvY3VtZW50IHdpbGwgYmUgbWFpbGVkIGFzIGFuIGF0dGFjaG1lbnQgdG8gYWxsIHJlY2lwaWVudHMuDQotCSovDQotCXZvaWQgKCpEb2NfbWFpbCkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLHZvaWQqIG1haWxEYXRhLCBpbnQgbGVuZ3RoLEZQREZfQk9PTCBiVUksIEZQREZfV0lERVNUUklORyBUbywgRlBERl9XSURFU1RSSU5HIFN1YmplY3QsIEZQREZfV0lERVNUUklORyBDQywgRlBERl9XSURFU1RSSU5HIEJDQywgRlBERl9XSURFU1RSSU5HIE1zZyk7IA0KLQkNCi0NCi0JLyoNCi0JKiBNZXRob2Q6IERvY19wcmludA0KLQkqCQkJUHJpbnRzIGFsbCBvciBhIHNwZWNpZmljIG51bWJlciBvZiBwYWdlcyBvZiB0aGUgZG9jdW1lbnQuDQotCSogSW50ZXJmYWNlIFZlcnNpb246DQotCSoJCQkxDQotCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCSoJCQl5ZXMNCi0JKiBQYXJhbWV0ZXJzOg0KLQkqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuDQotCSoJCQliVUkJCQktCUlmIHRydWUsIHdpbGwgY2F1c2UgYSBVSSB0byBiZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIgdG8gb2J0YWluIHByaW50aW5nIGluZm9ybWF0aW9uIGFuZCBjb25maXJtIHRoZSBhY3Rpb24uDQotCSoJCQluU3RhcnQJCS0JQSAwLWJhc2VkIGluZGV4IHRoYXQgZGVmaW5lcyB0aGUgc3RhcnQgb2YgYW4gaW5jbHVzaXZlIHJhbmdlIG9mIHBhZ2VzLg0KLQkqCQkJbkVuZAkJLSAgIEEgMC1iYXNlZCBpbmRleCB0aGF0IGRlZmluZXMgdGhlIGVuZCBvZiBhbiBpbmNsdXNpdmUgcGFnZSByYW5nZS4NCi0JKgkJCWJTaWxlbnQJCS0gICBJZiB0cnVlLCBzdXBwcmVzc2VzIHRoZSBjYW5jZWwgZGlhbG9nIGJveCB3aGlsZSB0aGUgZG9jdW1lbnQgaXMgcHJpbnRpbmcuIFRoZSBkZWZhdWx0IGlzIGZhbHNlLg0KLQkqCQkJYlNocmlua1RvRml0CS0JSWYgdHJ1ZSwgdGhlIHBhZ2UgaXMgc2hydW5rIChpZiBuZWNlc3NhcnkpIHRvIGZpdCB3aXRoaW4gdGhlIGltYWdlYWJsZSBhcmVhIG9mIHRoZSBwcmludGVkIHBhZ2UuDQotCSoJCQliUHJpbnRBc0ltYWdlCS0JSWYgdHJ1ZSwgcHJpbnQgcGFnZXMgYXMgYW4gaW1hZ2UuDQotCSoJCQliUmV2ZXJzZQktCUlmIHRydWUsIHByaW50IGZyb20gbkVuZCB0byBuU3RhcnQuDQotCSoJCQliQW5ub3RhdGlvbnMJLQlJZiB0cnVlICh0aGUgZGVmYXVsdCksIGFubm90YXRpb25zIGFyZSBwcmludGVkLg0KLQkqLw0KLQl2b2lkICgqRG9jX3ByaW50KShzdHJ1Y3QgX0lQREZfSnNQbGF0Zm9ybSogcFRoaXMsIEZQREZfQk9PTCBiVUksIGludCBuU3RhcnQsIGludCBuRW5kLCBGUERGX0JPT0wgYlNpbGVudCAsRlBERl9CT09MIGJTaHJpbmtUb0ZpdCxGUERGX0JPT0wgYlByaW50QXNJbWFnZSAsRlBERl9CT09MIGJSZXZlcnNlICxGUERGX0JPT0wgYkFubm90YXRpb25zKTsNCi0NCi0JLyoNCi0JKiBNZXRob2Q6IERvY19zdWJtaXRGb3JtDQotCSoJCQlTZW5kIHRoZSBmb3JtIGRhdGEgdG8gYSBzcGVjaWZpZWQgVVJMLg0KLQkqIEludGVyZmFjZSBWZXJzaW9uOg0KLQkqCQkJMQ0KLQkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOg0KLQkqCQkJeWVzDQotCSogUGFyYW1ldGVyczoNCi0JKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmDQotCSoJCQlmb3JtRGF0YQktCVBvaW50ZXIgdG8gdGhlIGRhdGEgYnVmZmVyIHRvIGJlIHNlbnQuDQotCSoJCQlsZW5ndGgJCS0JVGhlIHNpemUsaW4gYnl0ZXMsIG9mIHRoZSBidWZmZXIgcG9pbnRlZCBieSBmb3JtRGF0YSBwYXJhbWV0ZXIuDQotCSoJCQlVUkwJCQktCVRoZSBVUkwgdG8gc2VuZCB0by4NCi0JKiBSZXR1cm4gVmFsdWU6DQotCSoJCQlOb25lLg0KLQkqDQotCSovDQotCXZvaWQgKCpEb2Nfc3VibWl0Rm9ybSkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLHZvaWQqIGZvcm1EYXRhLCBpbnQgbGVuZ3RoLCBGUERGX1dJREVTVFJJTkcgVVJMKTsNCi0JDQotCS8qDQotCSogTWV0aG9kOiBEb2NfZ290b1BhZ2UNCi0JKgkJCUp1bXAgdG8gYSBzcGVjaWZpZWQgcGFnZS4NCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCXllcw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZg0KLQkqCQkJblBhZ2VOdW0JLQlUaGUgc3BlY2lmaWVkIHBhZ2UgbnVtYmVyLCB6ZXJvIGZvciB0aGUgZmlyc3QgcGFnZS4NCi0JKiBSZXR1cm4gVmFsdWU6DQotCSoJCQlOb25lLg0KLQkqDQotCSovDQotCXZvaWQgKCpEb2NfZ290b1BhZ2UpKHN0cnVjdCBfSVBERl9Kc1BsYXRmb3JtKiBwVGhpcywgaW50IG5QYWdlTnVtKTsNCi0JLyoNCi0JKiBNZXRob2Q6IEZpZWxkX2Jyb3dzZQ0KLQkqCQkJU2hvdyBhIGZpbGUgc2VsZWN0aW9uIGRpYWxvZywgYW5kIHJldHVybiB0aGUgc2VsZWN0ZWQgZmlsZSBwYXRoLg0KLQkqIEludGVyZmFjZSBWZXJzaW9uOg0KLQkqCQkJMQ0KLQkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOg0KLQkqCQkJeWVzDQotCSogUGFyYW1ldGVyczoNCi0JKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLg0KLQkqCQkJZmlsZVBhdGgJLQlQb2ludGVyIHRvIHRoZSBkYXRhIGJ1ZmZlciB0byByZWNlaXZlIHRoZSBmaWxlIHBhdGguQ2FuIGJlIE5VTEwuDQotCSoJCQlsZW5ndGgJCS0gICBUaGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIsIG51bWJlciBvZiBieXRlcy4gQ2FuIGJlIDAuDQotCSogUmV0dXJuIFZhbHVlOg0KLQkqCQlOdW1iZXIgb2YgYnl0ZXMgdGhlIGZpbGVQYXRoIGNvbnN1bWVzLCBpbmNsdWRpbmcgdHJhaWxpbmcgemVyb3MuDQotCSogQ29tbWVudHM6DQotCSoJCVRoZSBmaWxlUGF0aCBzaG91bGUgYmUgYWx3YXlzIGlucHV0IGluIGxvY2FsIGVuY29kaW5nLg0KLQkqLw0KLQlpbnQgICgqRmllbGRfYnJvd3NlKShzdHJ1Y3QgX0lQREZfSnNQbGF0Zm9ybSogcFRoaXMsdm9pZCogZmlsZVBhdGgsIGludCBsZW5ndGgpOw0KLQ0KLQkvKioNCi0JKglwb2ludGVyIHRvIEZQREZfRk9STUZJTExJTkZPIGludGVyZmFjZS4NCi0JKiovDQotCXZvaWQqCW1fcEZvcm1maWxsaW5mbzsNCi19IElQREZfSlNQTEFURk9STTsNCi0NCi0vLyBGbGFncyBmb3IgQ3Vyc29yIHR5cGUNCi0jZGVmaW5lIEZYQ1RfQVJST1cJMA0KLSNkZWZpbmUgRlhDVF9ORVNXCTEJCQ0KLSNkZWZpbmUgRlhDVF9OV1NFCTIJCQ0KLSNkZWZpbmUgRlhDVF9WQkVBTQkzCQkNCi0jZGVmaW5lIEZYQ1RfSEJFQU0JNAkNCi0jZGVmaW5lIEZYQ1RfSEFORAk1DQotDQotLyoqDQotICogRGVjbGFyZXMgb2YgYSBwb2ludGVyIHR5cGUgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGZvciB0aGUgRkZJX1NldFRpbWVyIG1ldGhvZC4NCi0gKiBQYXJhbWV0ZXJzOg0KLSAqCQkJaWRFdmVudAkJLQlJZGVudGlmaWVyIG9mIHRoZSB0aW1lci4gDQotICogUmV0dXJuIHZhbHVlOg0KLSAqCQkJTm9uZS4gDQotICoqLwkNCi10eXBlZGVmIHZvaWQJKCpUaW1lckNhbGxiYWNrKShpbnQgaWRFdmVudCk7DQotDQotLyoqDQotICogRGVjbGFyZXMgb2YgYSBzdHJ1Y3QgdHlwZSB0byB0aGUgbG9jYWwgc3lzdGVtIHRpbWUuDQotKiovDQotdHlwZWRlZiBzdHJ1Y3QgX0ZQREZfU1lTVEVNVElNRSANCi17DQotICAgIHVuc2lnbmVkIHNob3J0IHdZZWFyOwkJCS8qIHllYXJzIHNpbmNlIDE5MDAgKi8NCi0gICAgdW5zaWduZWQgc2hvcnQgd01vbnRoOwkJCS8qIG1vbnRocyBzaW5jZSBKYW51YXJ5IC0gWzAsMTFdICovDQotICAgIHVuc2lnbmVkIHNob3J0IHdEYXlPZldlZWs7CQkvKiBkYXlzIHNpbmNlIFN1bmRheSAtIFswLDZdICovDQotICAgIHVuc2lnbmVkIHNob3J0IHdEYXk7CQkJLyogZGF5IG9mIHRoZSBtb250aCAtIFsxLDMxXSAqLw0KLSAgICB1bnNpZ25lZCBzaG9ydCB3SG91cjsJCQkvKiBob3VycyBzaW5jZSBtaWRuaWdodCAtIFswLDIzXSAqLw0KLSAgICB1bnNpZ25lZCBzaG9ydCB3TWludXRlOwkJCS8qIG1pbnV0ZXMgYWZ0ZXIgdGhlIGhvdXIgLSBbMCw1OV0gKi8NCi0gICAgdW5zaWduZWQgc2hvcnQgd1NlY29uZDsJCQkvKiBzZWNvbmRzIGFmdGVyIHRoZSBtaW51dGUgLSBbMCw1OV0gKi8NCi0gICAgdW5zaWduZWQgc2hvcnQgd01pbGxpc2Vjb25kczsJLyogbWlsbGlzZWNvbmRzIGFmdGVyIHRoZSBzZWNvbmQgLSBbMCw5OTldICovDQotfUZQREZfU1lTVEVNVElNRTsNCi0NCi0NCi10eXBlZGVmIHN0cnVjdCAgX0ZQREZfRk9STUZJTExJTkZPDQotew0KLQkvKioNCi0JICogVmVyc2lvbiBudW1iZXIgb2YgdGhlIGludGVyZmFjZS4gQ3VycmVudGx5IG11c3QgYmUgMS4NCi0JICoqLw0KLQlpbnQJdmVyc2lvbjsNCi0NCi0JCS8qKiANCi0JICogTWV0aG9kOiBSZWxlYXNlDQotCSAqCQkJR2l2ZSBpbXBsZW1lbnRhdGlvbiBhIGNoYW5jZSB0byByZWxlYXNlIGFueSBkYXRhIGFmdGVyIHRoZSBpbnRlcmZhY2UgaXMgbm8gbG9uZ2VyIHVzZWQNCi0JICogSW50ZXJmYWNlIFZlcnNpb246DQotCSAqCQkJMQ0KLQkgKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JICoJCQlObw0KLQkgKiBDb21tZW50czoNCi0JICoJCQlDYWxsZWQgYnkgRm94aXQgU0RLIGR1cmluZyB0aGUgZmluYWwgY2xlYW51cCBwcm9jZXNzLg0KLQkgKiBQYXJhbWV0ZXJzOg0KLQkgKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmDQotCSAqIFJldHVybiBWYWx1ZToNCi0JICoJCQlOb25lDQotCSAqLw0KLQ0KLQl2b2lkICgqUmVsZWFzZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMpOw0KLQ0KLQkvKiogDQotCSAqIE1ldGhvZDogRkZJX0ludmFsaWRhdGUNCi0JICoJCQlJbnZhbGlkYXRlIHRoZSBjbGllbnQgYXJlYSB3aXRoaW4gdGhlIHNwZWNpZmllZCByZWN0YW5nbGUuDQotCSAqIEludGVyZmFjZSBWZXJzaW9uOg0KLQkgKgkJCTENCi0JICogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCQkqCQkJeWVzDQotCSAqIFBhcmFtZXRlcnM6DQotCSAqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuDQotCSAqCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uDQotCSAqCQkJbGVmdAkJLQlMZWZ0IHBvc2l0aW9uIG9mIHRoZSBjbGllbnQgYXJlYSBpbiBQREYgcGFnZSBjb29yZGluYXRlLg0KLQkgKgkJCXRvcAkJCS0JVG9wICBwb3NpdGlvbiBvZiB0aGUgY2xpZW50IGFyZWEgaW4gUERGIHBhZ2UgY29vcmRpbmF0ZS4NCi0JICoJCQlyaWdodAkJLQlSaWdodCBwb3NpdGlvbiBvZiB0aGUgY2xpZW50IGFyZWEgaW4gUERGIHBhZ2UgIGNvb3JkaW5hdGUuDQotCSAqCQkJYm90dG9tCQktCUJvdHRvbSBwb3NpdGlvbiBvZiB0aGUgY2xpZW50IGFyZWEgaW4gUERGIHBhZ2UgY29vcmRpbmF0ZS4NCi0JICogUmV0dXJuIFZhbHVlOg0KLQkgKgkJCU5vbmUuDQotCSAqDQotCSAqY29tbWVudHM6DQotCSAqCQkJQWxsIHBvc2l0aW9ucyBhcmUgbWVhc3VyZWQgaW4gUERGICJ1c2VyIHNwYWNlIi4NCi0JICoJCQlJbXBsZW1lbnRhdGlvbiBzaG91bGQgY2FsbCBGUERGX1JlbmRlclBhZ2VCaXRtYXAoKSBmdW5jdGlvbiBmb3IgcmVwYWludGluZyBhIHNwZWNpZmllZCBwYWdlIGFyZWEuDQotCSovDQotCXZvaWQgKCpGRklfSW52YWxpZGF0ZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsRlBERl9QQUdFIHBhZ2UsIGRvdWJsZSBsZWZ0LCBkb3VibGUgdG9wLCBkb3VibGUgcmlnaHQsIGRvdWJsZSBib3R0b20pOw0KLQkNCi0JLyoqIA0KLQkgKiBNZXRob2Q6IEZGSV9PdXRwdXRTZWxlY3RlZFJlY3QNCi0JICoJCQlXaGVuIHVzZXIgaXMgdGFraW5nIHRoZSBtb3VzZSB0byBzZWxlY3QgdGV4dHMgb24gYSBmb3JtIGZpZWxkLCB0aGlzIGNhbGxiYWNrIGZ1bmN0aW9uIHdpbGwga2VlcCANCi0JICoJCQlyZXR1cm5pbmcgdGhlIHNlbGVjdGVkIGFyZWFzIHRvIHRoZSBpbXBsZW1lbnRhdGlvbi4NCi0JICoNCi0JICogSW50ZXJmYWNlIFZlcnNpb246DQotCSAqCQkJMQ0KLQkgKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JICoJCQlObw0KLQkgKiBQYXJhbWV0ZXJzOg0KLQkgKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLg0KLQkgKgkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLQkgKgkJCWxlZnQJCS0JTGVmdCBwb3NpdGlvbiBvZiB0aGUgY2xpZW50IGFyZWEgaW4gUERGIHBhZ2UgY29vcmRpbmF0ZS4NCi0JICoJCQl0b3AJCQktCVRvcCAgcG9zaXRpb24gb2YgdGhlIGNsaWVudCBhcmVhIGluIFBERiBwYWdlIGNvb3JkaW5hdGUuDQotCSAqCQkJcmlnaHQJCS0JUmlnaHQgcG9zaXRpb24gb2YgdGhlIGNsaWVudCBhcmVhIGluIFBERiBwYWdlICBjb29yZGluYXRlLg0KLQkgKgkJCWJvdHRvbQkJLQlCb3R0b20gcG9zaXRpb24gb2YgdGhlIGNsaWVudCBhcmVhIGluIFBERiBwYWdlIGNvb3JkaW5hdGUuDQotCSAqIFJldHVybiBWYWx1ZToNCi0JICoJCQlOb25lLg0KLQkgKg0KLQkgKiBjb21tZW50czoNCi0JICoJCQlUaGlzIENBTExCQUNLIGZ1bmN0aW9uIGlzIHVzZWZ1bCBmb3IgaW1wbGVtZW50aW5nIHNwZWNpYWwgdGV4dCBzZWxlY3Rpb24gZWZmZWN0LiBJbXBsZW1lbnRhdGlvbiBzaG91bGQNCi0JICoJCQlmaXJzdCByZWNvcmRzIHRoZSByZXR1cm5lZCByZWN0YW5nbGVzLCB0aGVuIGRyYXcgdGhlbSBvbmUgYnkgb25lIGF0IHRoZSBwYWludGluZyBwZXJpb2QsIGxhc3QscmVtb3ZlIGFsbCANCi0JICoJCQl0aGUgcmVjb3JkZWQgcmVjdGFuZ2xlcyB3aGVuIGZpbmlzaCBwYWludGluZy4NCi0JKi8NCi0Jdm9pZCAoKkZGSV9PdXRwdXRTZWxlY3RlZFJlY3QpKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLEZQREZfUEFHRSBwYWdlLCBkb3VibGUgbGVmdCwgZG91YmxlIHRvcCwgZG91YmxlIHJpZ2h0LCBkb3VibGUgYm90dG9tKTsNCi0NCi0JLyoqIA0KLQkqIE1ldGhvZDogRkZJX1NldEN1cnNvcg0KLQkqCQkJU2V0IHRoZSBDdXJzb3Igc2hhcGUuDQotCSogSW50ZXJmYWNlIFZlcnNpb246DQotCSoJCQkxDQotCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCSoJCQl5ZXMNCi0JKiBQYXJhbWV0ZXJzOg0KLQkqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4NCi0JKiAJCW5DdXJzb3JUeXBlCS0JQ3Vyc29yIHR5cGUuIHNlZSBGbGFncyBmb3IgQ3Vyc29yIHR5cGUgZm9yIHRoZSBkZXRhaWxzLg0KLQkqIAlSZXR1cm4gdmFsdWU6DQotCSogCQlOb25lLg0KLQkqICovDQotCXZvaWQgKCpGRklfU2V0Q3Vyc29yKShzdHJ1Y3QgX0ZQREZfRk9STUZJTExJTkZPKiBwVGhpcywgaW50IG5DdXJzb3JUeXBlKTsNCi0NCi0JLyoqIA0KLQkqIE1ldGhvZDogRkZJX1NldFRpbWVyDQotCSoJCQlUaGlzIG1ldGhvZCBpbnN0YWxscyBhIHN5c3RlbSB0aW1lci4gQSB0aW1lLW91dCB2YWx1ZSBpcyBzcGVjaWZpZWQsIA0KLQkqCQkJYW5kIGV2ZXJ5IHRpbWUgYSB0aW1lLW91dCBvY2N1cnMsIHRoZSBzeXN0ZW0gcGFzc2VzIGEgbWVzc2FnZSB0bw0KLQkqCQkJdGhlIFRpbWVyUHJvYyBjYWxsYmFjayBmdW5jdGlvbi4gDQotCSogSW50ZXJmYWNlIFZlcnNpb246DQotCSoJCQkxDQotCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCSoJCQl5ZXMNCi0JKiBQYXJhbWV0ZXJzOg0KLQkqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4NCi0JKiAJCXVFbGFwc2UJCS0JU3BlY2lmaWVzIHRoZSB0aW1lLW91dCB2YWx1ZSwgaW4gbWlsbGlzZWNvbmRzLg0KLQkqIAkJbHBUaW1lckZ1bmMJLQlBIHBvaW50ZXIgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLVRpbWVyQ2FsbGJhY2suDQotCSogCVJldHVybiB2YWx1ZToNCi0JKiAJCVRoZSB0aW1lciBpZGVudGlmaWVyIG9mIHRoZSBuZXcgdGltZXIgaWYgdGhlIGZ1bmN0aW9uIGlzIHN1Y2Nlc3NmdWwuDQotCSoJCUFuIGFwcGxpY2F0aW9uIHBhc3NlcyB0aGlzIHZhbHVlIHRvIHRoZSBGRklfS2lsbFRpbWVyIG1ldGhvZCB0byBraWxsIA0KLQkqCQl0aGUgdGltZXIuIE5vbnplcm8gaWYgaXQgaXMgc3VjY2Vzc2Z1bDsgb3RoZXJ3aXNlLCBpdCBpcyB6ZXJvLg0KLQkqICovDQotCWludCAgKCpGRklfU2V0VGltZXIpKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLCBpbnQgdUVsYXBzZSwgVGltZXJDYWxsYmFjayBscFRpbWVyRnVuYyk7DQotDQotCS8qKiANCi0JKiBNZXRob2Q6IEZGSV9LaWxsVGltZXINCi0JKgkJCVRoaXMgbWV0aG9kIGtpbGxzIHRoZSB0aW1lciBldmVudCBpZGVudGlmaWVkIGJ5IG5JREV2ZW50LCBzZXQgYnkgYW4gZWFybGllciBjYWxsIHRvIEZGSV9TZXRUaW1lci4gDQotCSogSW50ZXJmYWNlIFZlcnNpb246DQotCSoJCQkxDQotCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCSoJCQl5ZXMNCi0JKiBQYXJhbWV0ZXJzOg0KLQkqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4NCi0JKiAJCW5UaW1lcklECS0JVGhlIHRpbWVyIElEIHJldHVybiBieSBGRklfU2V0VGltZXIgZnVuY3Rpb24uDQotCSogCVJldHVybiB2YWx1ZToNCi0JKiAJCU5vbmUuDQotCSogKi8NCi0Jdm9pZCAoKkZGSV9LaWxsVGltZXIpKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLCBpbnQgblRpbWVySUQpOw0KLQ0KLQ0KLQkvKiogDQotCSogTWV0aG9kOiBGRklfR2V0TG9jYWxUaW1lDQotCSoJCQlUaGlzIG1ldGhvZCByZWNlaXZlcyB0aGUgY3VycmVudCBsb2NhbCB0aW1lIG9uIHRoZSBzeXN0ZW0uIA0KLQkqIEludGVyZmFjZSBWZXJzaW9uOg0KLQkqCQkJMQ0KLQkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOg0KLQkqCQkJeWVzDQotCSogUGFyYW1ldGVyczoNCi0JKgkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuDQotCSogCVJldHVybiB2YWx1ZToNCi0JKiAJCU5vbmUuDQotCSogKi8NCi0JRlBERl9TWVNURU1USU1FICgqRkZJX0dldExvY2FsVGltZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMpOw0KLQ0KLQkvKiogDQotCSogTWV0aG9kOiBGRklfT25DaGFuZ2UNCi0JKgkJCVRoaXMgbWV0aG9kIHdpbGwgYmUgaW52b2tlZCB0byBub3RpZnkgaW1wbGVtZW50YXRpb24gd2hlbiB0aGUgdmFsdWUgb2YgYW55IEZvcm1GaWVsZCBvbiB0aGUgZG9jdW1lbnQgaGFkIGJlZW4gY2hhbmdlZC4NCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCW5vDQotCSogUGFyYW1ldGVyczoNCi0JKgkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuDQotCSogCVJldHVybiB2YWx1ZToNCi0JKiAJCU5vbmUuDQotCSogKi8NCi0Jdm9pZCAoKkZGSV9PbkNoYW5nZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMpOw0KLQ0KLQkvKiogDQotCSogTWV0aG9kOiBGRklfR2V0UGFnZQ0KLQkqCQkJVGhpcyBtZXRob2QgcmVjZWl2ZXMgdGhlIHBhZ2UgcG9pbnRlciBhc3NvY2lhdGVkIHdpdGggYSBzcGVjaWZpZWQgcGFnZSBpbmRleC4NCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCXllcw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLg0KLQkqCQlkb2N1bWVudAktCUhhbmRsZSB0byBkb2N1bWVudC4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkRG9jdW1lbnQgZnVuY3Rpb24uDQotCSoJCW5QYWdlSW5kZXggIC0JSW5kZXggbnVtYmVyIG9mIHRoZSBwYWdlLiAwIGZvciB0aGUgZmlyc3QgcGFnZS4NCi0JKiBSZXR1cm4gdmFsdWU6DQotCSogCQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uDQotCSogQ29tbWVudHM6DQotCSoJCUluIHNvbWUgY2FzZXMsIHRoZSBkb2N1bWVudC1sZXZlbCBKYXZhU2NyaXB0IGFjdGlvbiBtYXkgcmVmZXIgdG8gYSBwYWdlIHdoaWNoIGhhZG4ndCBiZWVuIGxvYWRlZCB5ZXQuDQotCSoJCVRvIHN1Y2Nlc3NmdWxseSBydW4gdGhlIGphdmFzY3JpcHQgYWN0aW9uLCBpbXBsZW1lbnRhdGlvbiBuZWVkIHRvIGxvYWQgdGhlIHBhZ2UgZm9yIFNESy4NCi0JKiAqLw0KLQlGUERGX1BBR0UJKCpGRklfR2V0UGFnZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIGludCBuUGFnZUluZGV4KTsNCi0NCi0JLyoqIA0KLQkqIE1ldGhvZDogRkZJX0dldEN1cnJlbnRQYWdlDQotCSoJCVRoaXMgbWV0aG9kIHJlY2VpdmVzIHRoZSBjdXJyZW50IHBhZ2UgcG9pbnRlci4NCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCXllcw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLg0KLQkqCQlkb2N1bWVudAktCUhhbmRsZSB0byBkb2N1bWVudC4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkRG9jdW1lbnQgZnVuY3Rpb24uDQotCSogUmV0dXJuIHZhbHVlOg0KLQkqIAkJSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLQkqICovDQotCUZQREZfUEFHRQkoKkZGSV9HZXRDdXJyZW50UGFnZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpOw0KLQ0KLQkvKiogDQotCSogTWV0aG9kOiBGRklfR2V0Um90YXRpb24NCi0JKgkJCVRoaXMgbWV0aG9kIHJlY2VpdmVzIGN1cnJlbnRseSByb3RhdGlvbiBvZiB0aGUgcGFnZSB2aWV3Lg0KLQkqIEludGVyZmFjZSBWZXJzaW9uOg0KLQkqCQkJMQ0KLQkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOg0KLQkqCQkJeWVzDQotCSogUGFyYW1ldGVyczoNCi0JKgkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuDQotCSoJCXBhZ2UJCS0JSGFuZGxlIHRvIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uDQotCSogUmV0dXJuIHZhbHVlOg0KLQkqIAkJVGhlIHBhZ2Ugcm90YXRpb24uIFNob3VsZCBiZSAwKDAgZGVncmVlKSwxKDkwIGRlZ3JlZSksMigxODAgZGVncmVlKSwzKDI3MCBkZWdyZWUpLCBpbiBhIGNsb2Nrd2lzZSBkaXJlY3Rpb24uDQotCSogKi8NCi0JaW50IAkoKkZGSV9HZXRSb3RhdGlvbikoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfUEFHRSBwYWdlKTsNCi0NCi0JLyoqIA0KLQkqIE1ldGhvZDogRkZJX0V4ZWN1dGVOYW1lZEFjdGlvbg0KLQkqCQkJVGhpcyBtZXRob2Qgd2lsbCBleGVjdXRlIGFuIG5hbWVkIGFjdGlvbi4NCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCXllcw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCXBUaGlzCQkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4NCi0JKgkJbmFtZWRBY3Rpb24JCS0JQSBieXRlIHN0cmluZyB3aGljaCBpbmRpY2F0ZXMgdGhlIG5hbWVkIGFjdGlvbiwgdGVybWluYXRlZCBieSAwLg0KLQkqIFJldHVybiB2YWx1ZToNCi0JKiAJCU5vbmUuDQotCSogQ29tbWVudHM6DQotCSoJCVNlZSB0aGUgbmFtZWQgYWN0aW9ucyBkZXNjcmlwdGlvbiBvZiA8PFBERiBSZWZlcmVuY2UsIHZlcnNpb24gMS43Pj4gZm9yIG1vcmUgZGV0YWlscy4gIA0KLQkqICovDQotCXZvaWQgCSgqRkZJX0V4ZWN1dGVOYW1lZEFjdGlvbikoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfQllURVNUUklORyBuYW1lZEFjdGlvbik7DQotCS8qKiANCi0JKiBAYnJpZWYgVGhpcyBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHRleHQgZmllbGQgaXMgZ2V0dGluZyBvciBsb3NpbmcgYSBmb2N1cy4NCi0JKg0KLQkqIEBwYXJhbVtpbl0gcFRoaXMJCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLg0KLQkqIEBwYXJhbVtpbl0gdmFsdWUJCVRoZSBzdHJpbmcgdmFsdWUgb2YgdGhlIGZvcm0gZmllbGQsIGluIFVURi0xNkxFIGZvcm1hdC4NCi0JKiBAcGFyYW1baW5dIHZhbHVlTGVuCVRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyB2YWx1ZSwgbnVtYmVyIG9mIGNoYXJhY3RlcnMgKG5vdCBieXRlcykuDQotCSogQHBhcmFtW2luXSBpc19mb2N1cwlUcnVlIGlmIHRoZSBmb3JtIGZpZWxkIGlzIGdldHRpbmcgYSBmb2N1cywgRmFsc2UgZm9yIGxvc2luZyBhIGZvY3VzLg0KLQkqDQotCSogQHJldHVybiBOb25lLg0KLQkqDQotCSogQG5vdGUgQ3VycmVudGx5LG9ubHkgc3VwcG9ydCB0ZXh0IGZpZWxkIGFuZCBjb21ib2JveCBmaWVsZC4NCi0JKiAqLw0KLQl2b2lkCSgqRkZJX1NldFRleHRGaWVsZEZvY3VzKShzdHJ1Y3QgX0ZQREZfRk9STUZJTExJTkZPKiBwVGhpcywgRlBERl9XSURFU1RSSU5HIHZhbHVlLCBGUERGX0RXT1JEIHZhbHVlTGVuLCBGUERGX0JPT0wgaXNfZm9jdXMpOw0KLQ0KLQkNCi0JLyoqIA0KLQkqIE1ldGhvZDogRkZJX0RvVVJJQWN0aW9uDQotCSoJCQlUaGlzIGFjdGlvbiByZXNvbHZlcyB0byBhIHVuaWZvcm0gcmVzb3VyY2UgaWRlbnRpZmllci4gDQotCSogSW50ZXJmYWNlIFZlcnNpb246DQotCSoJCQkxDQotCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCSoJCQlObw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCXBUaGlzCQkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4NCi0JKgkJYnNVUkkJCQktCUEgYnl0ZSBzdHJpbmcgd2hpY2ggaW5kaWNhdGVzIHRoZSB1bmlmb3JtIHJlc291cmNlIGlkZW50aWZpZXIsIHRlcm1pbmF0ZWQgYnkgMC4NCi0JKiBSZXR1cm4gdmFsdWU6DQotCSogCQlOb25lLg0KLQkqIENvbW1lbnRzOg0KLQkqCQlTZWUgdGhlIFVSSSBhY3Rpb25zIGRlc2NyaXB0aW9uIG9mIDw8UERGIFJlZmVyZW5jZSwgdmVyc2lvbiAxLjc+PiBmb3IgbW9yZSBkZXRhaWxzLiAgDQotCSogKi8NCi0Jdm9pZAkoKkZGSV9Eb1VSSUFjdGlvbikoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfQllURVNUUklORyBic1VSSSk7DQotCQ0KLQkvKiogDQotCSogTWV0aG9kOiBGRklfRG9Hb1RvQWN0aW9uDQotCSoJCQlUaGlzIGFjdGlvbiBjaGFuZ2VzIHRoZSB2aWV3IHRvIGEgc3BlY2lmaWVkIGRlc3RpbmF0aW9uLg0KLQkqIEludGVyZmFjZSBWZXJzaW9uOg0KLQkqCQkJMQ0KLQkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOg0KLQkqCQkJTm8NCi0JKiBQYXJhbWV0ZXJzOg0KLQkqCQlwVGhpcwkJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuDQotCSoJCW5QYWdlSW5kZXgJCS0JVGhlIGluZGV4IG9mIHRoZSBQREYgcGFnZS4NCi0JKgkJem9vbU1vZGUJCS0JVGhlIHpvb20gbW9kZSBmb3Igdmlld2luZyBwYWdlLlNlZSBNYWNyb3MgIlBERlpPT01fWFhYIiBkZWZpbmVkIGluICJmcGRmZG9jLmgiLiANCi0JKgkJZlBvc0FycmF5CQktCVRoZSBmbG9hdCBhcnJheSB3aGljaCBjYXJyaWVzIHRoZSBwb3NpdGlvbiBpbmZvLg0KLQkqCQlzaXplb2ZBcnJheQkJLQlUaGUgc2l6ZSBvZiBmbG9hdCBhcnJheS4NCi0JKiBSZXR1cm4gdmFsdWU6DQotCSogCQlOb25lLg0KLQkqIENvbW1lbnRzOg0KLQkqCQlTZWUgdGhlIERlc3RpbmF0aW9ucyBkZXNjcmlwdGlvbiBvZiA8PFBERiBSZWZlcmVuY2UsIHZlcnNpb24gMS43Pj4gaW4gOC4yLjEgZm9yIG1vcmUgZGV0YWlscy4gIA0KLQkqKi8NCi0Jdm9pZAkoKkZGSV9Eb0dvVG9BY3Rpb24pKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLCBpbnQgblBhZ2VJbmRleCwgaW50IHpvb21Nb2RlLCBmbG9hdCogZlBvc0FycmF5LCBpbnQgc2l6ZW9mQXJyYXkpOw0KLQkvKioNCi0JKglwb2ludGVyIHRvIElQREZfSlNQTEFURk9STSBpbnRlcmZhY2UNCi0JKiovDQotCUlQREZfSlNQTEFURk9STSoJbV9wSnNQbGF0Zm9ybTsNCi0NCi19IEZQREZfRk9STUZJTExJTkZPOw0KLQ0KLQ0KLQ0KLS8qKg0KLSAqIEZ1bmN0aW9uOiBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50DQotICoJCQlJbml0IGZvcm0gZmlsbCBlbnZpcm9ubWVudC4gDQotICogQ29tbWVudHM6DQotICoJCQlUaGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQgYmVmb3JlIGFueSBmb3JtIGZpbGwgb3BlcmF0aW9uLg0KLSAqIFBhcmFtZXRlcnM6DQotICoJCQlkb2N1bWVudAkJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLg0KLSAqCQkJcEZvcm1GaWxsSW5mbwktCVBvaW50ZXIgdG8gYSBGUERGX0ZPUk1GSUxMSU5GTyBzdHJ1Y3R1cmUuDQotICogUmV0dXJuIFZhbHVlOg0KLSAqCQkJUmV0dXJuIGhhbmRsZXIgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIE5VTEwgbWVhbnMgZmFpbHMuIA0KLSAqKi8NCi1ETExFWFBPUlQgRlBERl9GT1JNSEFORExFIFNURENBTEwgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBGUERGX0ZPUk1GSUxMSU5GTyogZm9ybUluZm8pOw0KLQ0KLS8qKg0KLSAqIEZ1bmN0aW9uOiBGUERGRE9DX0V4aXRGb3JtRmlsbEVudmlyb3VtZW50DQotICoJCQlFeGl0IGZvcm0gZmlsbCBlbnZpcm9ubWVudC4gDQotICogUGFyYW1ldGVyczoNCi0gKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCU5VTEwuDQotICoqLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkRPQ19FeGl0Rm9ybUZpbGxFbnZpcm91bWVudChGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSk7DQotDQotLyoqDQotICogRnVuY3Rpb246IEZPUk1fT25BZnRlckxvYWRQYWdlDQotICoJCQlUaGlzIG1ldGhvZCBpcyByZXF1aXJlZCBmb3IgaW1wbGVtZW50aW5nIGFsbCB0aGUgZm9ybSByZWxhdGVkIGZ1bmN0aW9ucy4gU2hvdWxkIGJlIGludm9rZWQgYWZ0ZXIgdXNlciANCi0gKgkJCXN1Y2Nlc3NmdWxseSBsb2FkZWQgYSBQREYgcGFnZSwgYW5kIG1ldGhvZCBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50IGhhZCBiZWVuIGludm9rZWQuDQotICogUGFyYW1ldGVyczoNCi0gKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCU5PTkUuDQotICoqLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9PbkFmdGVyTG9hZFBhZ2UoRlBERl9QQUdFIHBhZ2UsIEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKTsNCi0NCi0vKioNCi0gKiBGdW5jdGlvbjogRk9STV9PbkJlZm9yZUNsb3NlUGFnZQ0KLSAqCQkJVGhpcyBtZXRob2QgaXMgcmVxdWlyZWQgZm9yIGltcGxlbWVudGluZyBhbGwgdGhlIGZvcm0gcmVsYXRlZCBmdW5jdGlvbnMuIFNob3VsZCBiZSBpbnZva2VkIGJlZm9yZSB1c2VyIA0KLSAqCQkJY2xvc2UgdGhlIFBERiBwYWdlLg0KLSAqIFBhcmFtZXRlcnM6DQotICoJCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0gKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCU5PTkUuDQotICoqLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9PbkJlZm9yZUNsb3NlUGFnZShGUERGX1BBR0UgcGFnZSwgRlBERl9GT1JNSEFORExFIGhIYW5kbGUpOw0KLQ0KLS8qKg0KLSogRnVuY3Rpb246IEZPUk1fRG9Eb2N1bWVudEpTQWN0aW9uDQotKgkJCVRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIGZvciBwZXJmb3JtaW5nIERvY3VtZW50LWxldmVsIEphdmFTY3JpcHQgYWN0aW9uLiBJdCBzaG91bGQgYmUgaW52b2tlZCBhZnRlciB0aGUgUERGIGRvY3VtZW50DQotKgkJCWhhZCBiZWVuIGxvYWRlZC4NCi0qIFBhcmFtZXRlcnM6DQotKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSogUmV0dXJuIFZhbHVlOg0KLSoJCQlOT05FDQotKiBDb21tZW50czoNCi0qCQkJSWYgdGhlcmUgaXMgRG9jdW1lbnQtbGV2ZWwgSmF2YVNjcmlwdCBhY3Rpb24gZW1iZWRkZWQgaW4gdGhlIGRvY3VtZW50LCB0aGlzIG1ldGhvZCB3aWxsIGV4ZWN1dGUgdGhlIGphdmFzY3JpcHQgYWN0aW9uOw0KLSoJCQlvdGhlcndpc2UsIHRoZSBtZXRob2Qgd2lsbCBkbyBub3RoaW5nLg0KLSoqLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9Eb0RvY3VtZW50SlNBY3Rpb24oRlBERl9GT1JNSEFORExFIGhIYW5kbGUpOw0KLQ0KLQ0KLS8qKg0KLSogRnVuY3Rpb246IEZPUk1fRG9Eb2N1bWVudE9wZW5BY3Rpb24NCi0qCQkJVGhpcyBtZXRob2QgaXMgcmVxdWlyZWQgZm9yIHBlcmZvcm1pbmcgb3Blbi1hY3Rpb24gd2hlbiB0aGUgZG9jdW1lbnQgaXMgb3BlbmVkLg0KLSogUGFyYW1ldGVyczoNCi0qCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuDQotKiBSZXR1cm4gVmFsdWU6DQotKgkJCU5PTkUNCi0qIENvbW1lbnRzOg0KLSoJCQlUaGlzIG1ldGhvZCB3aWxsIGRvIG5vdGhpbmcgaWYgdGhlcmUgaXMgbm8gb3Blbi1hY3Rpb25zIGVtYmVkZGVkIGluIHRoZSBkb2N1bWVudC4gDQotKiovDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGT1JNX0RvRG9jdW1lbnRPcGVuQWN0aW9uKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKTsNCi0NCi0NCi0vLyBhZGRpdGlvbmFsIGFjdGlvbnMgdHlwZSBvZiBkb2N1bWVudC4NCi0jZGVmaW5lIEZQREZET0NfQUFDVElPTl9XQwkJMHgxMAkJLy9XQywgYmVmb3JlIGNsb3NpbmcgZG9jdW1lbnQsIEphdmFTY3JpcHQgYWN0aW9uLg0KLSNkZWZpbmUgRlBERkRPQ19BQUNUSU9OX1dTCQkweDExCQkvL1dTLCBiZWZvcmUgc2F2aW5nIGRvY3VtZW50LCBKYXZhU2NyaXB0IGFjdGlvbi4NCi0jZGVmaW5lIEZQREZET0NfQUFDVElPTl9EUwkJMHgxMgkJLy9EUywgYWZ0ZXIgc2F2aW5nIGRvY3VtZW50LCBKYXZhU2NyaXB0IGFjdGlvbi4NCi0jZGVmaW5lIEZQREZET0NfQUFDVElPTl9XUAkJMHgxMwkJLy9XUCwgYmVmb3JlIHByaW50aW5nIGRvY3VtZW50LCBKYXZhU2NyaXB0IGFjdGlvbi4NCi0jZGVmaW5lIEZQREZET0NfQUFDVElPTl9EUAkJMHgxNAkJLy9EUCwgYWZ0ZXIgcHJpbnRpbmcgZG9jdW1lbnQsIEphdmFTY3JpcHQgYWN0aW9uLiANCi0vKioNCi0qIEZ1bmN0aW9uOiBGT1JNX0RvRG9jdW1lbnRBQWN0aW9uDQotKgkJCVRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIGZvciBwZXJmb3JtaW5nIHRoZSBkb2N1bWVudCdzIGFkZGl0aW9uYWwtYWN0aW9uLg0KLSogUGFyYW1ldGVyczoNCi0qCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuDQotKgkJCWFhVHlwZQkgICAgLSAgIFRoZSB0eXBlIG9mIHRoZSBhZGRpdGlvbmFsLWFjdGlvbnMgd2hpY2ggZGVmaW5lZCBhYm92ZS4NCi0qIFJldHVybiBWYWx1ZToNCi0qCQkJTk9ORQ0KLSogQ29tbWVudHM6DQotKgkJCVRoaXMgbWV0aG9kIHdpbGwgZG8gbm90aGluZyBpZiB0aGVyZSBpcyBubyBkb2N1bWVudCBhZGRpdGlvbmFsLWFjdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSBzcGVjaWZpZWQgYWFUeXBlLg0KLSoqLw0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9Eb0RvY3VtZW50QUFjdGlvbihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgaW50IGFhVHlwZSk7DQotDQotLy8gQWRkaXRpb25hbC1hY3Rpb24gdHlwZXMgb2YgcGFnZSBvYmplY3QNCi0jZGVmaW5lIEZQREZQQUdFX0FBQ1RJT05fT1BFTgkJMAkJLy8gL08gLS0gQW4gYWN0aW9uIHRvIGJlIHBlcmZvcm1lZCB3aGVuIHRoZSBwYWdlIGlzIG9wZW5lZA0KLSNkZWZpbmUgRlBERlBBR0VfQUFDVElPTl9DTE9TRQkJMQkJLy8gL0MgLS0gQW4gYWN0aW9uIHRvIGJlIHBlcmZvcm1lZCB3aGVuIHRoZSBwYWdlIGlzIGNsb3NlZA0KLQ0KLS8qKg0KLSogRnVuY3Rpb246IEZPUk1fRG9QYWdlQUFjdGlvbg0KLSoJCQlUaGlzIG1ldGhvZCBpcyByZXF1aXJlZCBmb3IgcGVyZm9ybWluZyB0aGUgcGFnZSBvYmplY3QncyBhZGRpdGlvbmFsLWFjdGlvbiB3aGVuIG9wZW5lZCBvciBjbG9zZWQuDQotKiBQYXJhbWV0ZXJzOg0KLSoJCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0qCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuDQotKgkJCWFhVHlwZQkgICAgLSAgIFRoZSB0eXBlIG9mIHRoZSBwYWdlIG9iamVjdCdzIGFkZGl0aW9uYWwtYWN0aW9ucyB3aGljaCBkZWZpbmVkIGFib3ZlLg0KLSogUmV0dXJuIFZhbHVlOg0KLSoJCQlOT05FDQotKiBDb21tZW50czoNCi0qCQkJVGhpcyBtZXRob2Qgd2lsbCBkbyBub3RoaW5nIGlmIG5vIGFkZGl0aW9uYWwtYWN0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZCBhYVR5cGUgZXhpc3RzLg0KLSoqLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9Eb1BhZ2VBQWN0aW9uKEZQREZfUEFHRSBwYWdlLCBGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgaW50IGFhVHlwZSk7DQotDQotLyoqDQotICogRnVuY3Rpb246IEZPUk1fT25Nb3VzZU1vdmUNCi0gKgkJCVlvdSBjYW4gY2FsbCB0aGlzIG1lbWJlciBmdW5jdGlvbiB3aGVuIHRoZSBtb3VzZSBjdXJzb3IgbW92ZXMuIA0KLSAqIFBhcmFtZXRlcnM6DQotICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4NCi0gKgkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLSAqCQkJbW9kaWZpZXIJCS0JSW5kaWNhdGVzIHdoZXRoZXIgdmFyaW91cyB2aXJ0dWFsIGtleXMgYXJlIGRvd24uIA0KLSAqCQkJcGFnZV94CQktCVNwZWNpZmllcyB0aGUgeC1jb29yZGluYXRlIG9mIHRoZSBjdXJzb3IgaW4gUERGIHVzZXIgc3BhY2UuIA0KLSAqCQkJcGFnZV95CQktCVNwZWNpZmllcyB0aGUgeS1jb29yZGluYXRlIG9mIHRoZSBjdXJzb3IgaW4gUERGIHVzZXIgc3BhY2UuDQotICogUmV0dXJuIFZhbHVlOg0KLSAqCQkJVFJVRSBpbmRpY2F0ZXMgc3VjY2Vzczsgb3RoZXJ3aXNlIGZhbHNlLg0KLSAqKi8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRk9STV9Pbk1vdXNlTW92ZShGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSxGUERGX1BBR0UgcGFnZSwgaW50IG1vZGlmaWVyLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95KTsNCi0NCi0vKioNCi0gKiBGdW5jdGlvbjogRk9STV9PbkxCdXR0b25Eb3duDQotICoJCQlZb3UgY2FuIGNhbGwgdGhpcyBtZW1iZXIgZnVuY3Rpb24gd2hlbiB0aGUgdXNlciBwcmVzc2VzIHRoZSBsZWZ0IG1vdXNlIGJ1dHRvbi4NCi0gKiBQYXJhbWV0ZXJzOg0KLSAqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuDQotICoJCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0gKgkJCW1vZGlmaWVyCQktCUluZGljYXRlcyB3aGV0aGVyIHZhcmlvdXMgdmlydHVhbCBrZXlzIGFyZSBkb3duLiANCi0gKgkJCXBhZ2VfeAkJLQlTcGVjaWZpZXMgdGhlIHgtY29vcmRpbmF0ZSBvZiB0aGUgY3Vyc29yIGluIFBERiB1c2VyIHNwYWNlLiANCi0gKgkJCXBhZ2VfeQkJLQlTcGVjaWZpZXMgdGhlIHktY29vcmRpbmF0ZSBvZiB0aGUgY3Vyc29yIGluIFBERiB1c2VyIHNwYWNlLg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCVRSVUUgaW5kaWNhdGVzIHN1Y2Nlc3M7IG90aGVyd2lzZSBmYWxzZS4NCi0gKiovDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25MQnV0dG9uRG93bihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSxGUERGX1BBR0UgcGFnZSwgaW50IG1vZGlmaWVyLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95KTsNCi0NCi0vKioNCi0gKiBGdW5jdGlvbjogRk9STV9PbkxCdXR0b25VcA0KLSAqCQkJWW91IGNhbiBjYWxsIHRoaXMgbWVtYmVyIGZ1bmN0aW9uIHdoZW4gdGhlIHVzZXIgcmVsZWFzZXMgdGhlIGxlZnQgbW91c2UgYnV0dG9uLg0KLSAqIFBhcmFtZXRlcnM6DQotICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4NCi0gKgkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLSAqCQkJbW9kaWZpZXIJLQlJbmRpY2F0ZXMgd2hldGhlciB2YXJpb3VzIHZpcnR1YWwga2V5cyBhcmUgZG93bi4gDQotICoJCQlwYWdlX3gJCS0JU3BlY2lmaWVzIHRoZSB4LWNvb3JkaW5hdGUgb2YgdGhlIGN1cnNvciBpbiBkZXZpY2UuIA0KLSAqCQkJcGFnZV95CQktCVNwZWNpZmllcyB0aGUgeS1jb29yZGluYXRlIG9mIHRoZSBjdXJzb3IgaW4gZGV2aWNlLg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCVRSVUUgaW5kaWNhdGVzIHN1Y2Nlc3M7IG90aGVyd2lzZSBmYWxzZS4NCi0gKiovDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25MQnV0dG9uVXAoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsRlBERl9QQUdFIHBhZ2UsIGludCBtb2RpZmllciwgZG91YmxlIHBhZ2VfeCwgZG91YmxlIHBhZ2VfeSk7DQotDQotLyoqDQotICogRnVuY3Rpb246IEZPUk1fT25LZXlEb3duDQotICoJCQlZb3UgY2FuIGNhbGwgdGhpcyBtZW1iZXIgZnVuY3Rpb24gd2hlbiBhIG5vbnN5c3RlbSBrZXkgaXMgcHJlc3NlZC4gDQotICogUGFyYW1ldGVyczoNCi0gKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSAqCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uDQotICoJCQluS2V5Q29kZQktCUluZGljYXRlcyB3aGV0aGVyIHZhcmlvdXMgdmlydHVhbCBrZXlzIGFyZSBkb3duLiANCi0gKgkJCW1vZGlmaWVyCS0JQ29udGFpbnMgdGhlIHNjYW4gY29kZSwga2V5LXRyYW5zaXRpb24gY29kZSwgcHJldmlvdXMga2V5IHN0YXRlLCBhbmQgY29udGV4dCBjb2RlLg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCVRSVUUgaW5kaWNhdGVzIHN1Y2Nlc3M7IG90aGVyd2lzZSBmYWxzZS4NCi0gKiovDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25LZXlEb3duKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLEZQREZfUEFHRSBwYWdlLCBpbnQgbktleUNvZGUsIGludCBtb2RpZmllcik7DQotDQotLyoqDQotICogRnVuY3Rpb246IEZPUk1fT25LZXlVcA0KLSAqCQkJWW91IGNhbiBjYWxsIHRoaXMgbWVtYmVyIGZ1bmN0aW9uIHdoZW4gYSBub25zeXN0ZW0ga2V5IGlzIHJlbGVhc2VkLiANCi0gKiBQYXJhbWV0ZXJzOg0KLSAqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuDQotICoJCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0gKgkJCW5LZXlDb2RlCS0JVGhlIHZpcnR1YWwta2V5IGNvZGUgb2YgdGhlIGdpdmVuIGtleS4NCi0gKgkJCW1vZGlmaWVyCS0JQ29udGFpbnMgdGhlIHNjYW4gY29kZSwga2V5LXRyYW5zaXRpb24gY29kZSwgcHJldmlvdXMga2V5IHN0YXRlLCBhbmQgY29udGV4dCBjb2RlLg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCVRSVUUgaW5kaWNhdGVzIHN1Y2Nlc3M7IG90aGVyd2lzZSBmYWxzZS4NCi0gKiovDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25LZXlVcChGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSxGUERGX1BBR0UgcGFnZSwgaW50IG5LZXlDb2RlLCBpbnQgbW9kaWZpZXIpOw0KLQ0KLS8qKg0KLSAqIEZ1bmN0aW9uOiBGT1JNX09uQ2hhcg0KLSAqCQkJWW91IGNhbiBjYWxsIHRoaXMgbWVtYmVyIGZ1bmN0aW9uIHdoZW4gYSBrZXlzdHJva2UgdHJhbnNsYXRlcyB0byBhIG5vbnN5c3RlbSBjaGFyYWN0ZXIuDQotICogUGFyYW1ldGVyczoNCi0gKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSAqCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uDQotICoJCQluQ2hhcgkJLQlUaGUgY2hhcmFjdGVyIGNvZGUgdmFsdWUgb2YgdGhlIGtleS4gIA0KLSAqCQkJbW9kaWZpZXIJLQlDb250YWlucyB0aGUgc2NhbiBjb2RlLCBrZXktdHJhbnNpdGlvbiBjb2RlLCBwcmV2aW91cyBrZXkgc3RhdGUsIGFuZCBjb250ZXh0IGNvZGUuDQotICogUmV0dXJuIFZhbHVlOg0KLSAqCQkJVFJVRSBpbmRpY2F0ZXMgc3VjY2Vzczsgb3RoZXJ3aXNlIGZhbHNlLg0KLSAqKi8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRk9STV9PbkNoYXIoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsRlBERl9QQUdFIHBhZ2UsIGludCBuQ2hhciwgaW50IG1vZGlmaWVyKTsNCi0NCi0vKioNCi0gKiBGdW5jdGlvbjogRk9STV9Gb3JjZVRvS2lsbEZvY3VzLg0KLSAqCQkJWW91IGNhbiBjYWxsIHRoaXMgbWVtYmVyIGZ1bmN0aW9uIHRvIGZvcmNlIHRvIGtpbGwgdGhlIGZvY3VzIG9mIHRoZSBmb3JtIGZpZWxkIHdoaWNoIGdvdCBmb2N1cy4NCi0gKgkJCUl0IHdvdWxkIGtpbGwgdGhlIGZvY3VzIG9uIHRoZSBmb3JtIGZpZWxkLCBzYXZlIHRoZSB2YWx1ZSBvZiBmb3JtIGZpZWxkIGlmIGl0J3MgY2hhbmdlZCBieSB1c2VyLg0KLSAqIFBhcmFtZXRlcnM6DQotICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4NCi0gKiBSZXR1cm4gVmFsdWU6DQotICoJCQlUUlVFIGluZGljYXRlcyBzdWNjZXNzOyBvdGhlcndpc2UgZmFsc2UuDQotICoqLw0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX0ZvcmNlVG9LaWxsRm9jdXMoRlBERl9GT1JNSEFORExFIGhIYW5kbGUpOw0KLQ0KLS8vIEZpZWxkIFR5cGVzDQotI2RlZmluZSBGUERGX0ZPUk1GSUVMRF9VTktOT1dOCQkwCQkvLyBVbmtub3duLg0KLSNkZWZpbmUgRlBERl9GT1JNRklFTERfUFVTSEJVVFRPTgkxCQkvLyBwdXNoIGJ1dHRvbiB0eXBlLg0KLSNkZWZpbmUgRlBERl9GT1JNRklFTERfQ0hFQ0tCT1gJCTIJCS8vIGNoZWNrIGJveCB0eXBlLg0KLSNkZWZpbmUgRlBERl9GT1JNRklFTERfUkFESU9CVVRUT04JMwkJLy8gcmFkaW8gYnV0dG9uIHR5cGUuDQotI2RlZmluZSBGUERGX0ZPUk1GSUVMRF9DT01CT0JPWAkJNAkJLy8gY29tYm8gYm94IHR5cGUuDQotI2RlZmluZSBGUERGX0ZPUk1GSUVMRF9MSVNUQk9YCQk1CQkvLyBsaXN0IGJveCB0eXBlLg0KLSNkZWZpbmUgRlBERl9GT1JNRklFTERfVEVYVEZJRUxECTYJCS8vIHRleHQgZmllbGQgdHlwZS4NCi0NCi0vKioNCi0gKiBGdW5jdGlvbjogRlBEUGFnZV9IYXNGb3JtRmllbGRBdFBvaW50DQotICoJCQlDaGVjayB0aGUgZm9ybSBmaWxlZCBwb3NpdGlvbiBieSBwb2ludC4NCi0gKiBQYXJhbWV0ZXJzOg0KLSAqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuDQotICoJCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0gKgkJCXBhZ2VfeAkJLQlYIHBvc2l0aW9uIGluIFBERiAidXNlciBzcGFjZSIuDQotICoJCQlwYWdlX3kJCS0JWSBwb3NpdGlvbiBpbiBQREYgInVzZXIgc3BhY2UiLg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCVJldHVybiB0aGUgdHlwZSBvZiB0aGUgZm9ybWZpbGVkOyAtMSBpbmRpY2F0ZXMgbm8gZmllbGRzLg0KLSAqKi8NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBEUGFnZV9IYXNGb3JtRmllbGRBdFBvaW50KEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLEZQREZfUEFHRSBwYWdlLGRvdWJsZSBwYWdlX3gsIGRvdWJsZSBwYWdlX3kpOw0KLQ0KLS8qKg0KLSAqIEZ1bmN0aW9uOiBGUERGX1NldEZvcm1GaWVsZEhpZ2hsaWdodENvbG9yDQotICoJCQlTZXQgdGhlIGhpZ2hsaWdodCBjb2xvciBvZiBzcGVjaWZpZWQgb3IgYWxsIHRoZSBmb3JtIGZpZWxkcyBpbiB0aGUgZG9jdW1lbnQuDQotICogUGFyYW1ldGVyczoNCi0gKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSAqCQkJZG9jCQkJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBmdW5jdGlvbi4NCi0gKgkJCWZpZWxkVHlwZQktCUEgMzItYml0IGludGVnZXIgaW5kaWNhdGluZyB0aGUgdHlwZSBvZiBhIGZvcm0gZmllbGQoZGVmaW5lZCBhYm92ZSkuDQotICoJCQljb2xvcgkJLQlUaGUgaGlnaGxpZ2h0IGNvbG9yIG9mIHRoZSBmb3JtIGZpZWxkLkNvbnN0cnVjdGVkIGJ5IDB4eHhycmdnYmIuDQotICogUmV0dXJuIFZhbHVlOg0KLSAqCQkJTk9ORS4NCi0gKiBDb21tZW50czoNCi0gKgkJCVdoZW4gdGhlIHBhcmFtZXRlciBmaWVsZFR5cGUgaXMgc2V0IHRvIHplcm8sIHRoZSBoaWdobGlnaHQgY29sb3Igd2lsbCBiZSBhcHBsaWVkIHRvIGFsbCB0aGUgZm9ybSBmaWVsZHMgaW4gdGhlIA0KLSAqCQkJZG9jdW1lbnQuDQotICoJCQlQbGVhc2UgcmVmcmVzaCB0aGUgY2xpZW50IHdpbmRvdyB0byBzaG93IHRoZSBoaWdobGlnaHQgaW1tZWRpYXRlbHkgaWYgbmVjZXNzYXJ5Lg0KLSAqKi8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfU2V0Rm9ybUZpZWxkSGlnaGxpZ2h0Q29sb3IoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIGludCBmaWVsZFR5cGUsIHVuc2lnbmVkIGxvbmcgY29sb3IpOw0KLQ0KLS8qKg0KLSAqIEZ1bmN0aW9uOiBGUERGX1NldEZvcm1GaWVsZEhpZ2hsaWdodEFscGhhDQotICoJCQlTZXQgdGhlIHRyYW5zcGFyZW5jeSBvZiB0aGUgZm9ybSBmaWVsZCBoaWdobGlnaHQgY29sb3IgaW4gdGhlIGRvY3VtZW50Lg0KLSAqIFBhcmFtZXRlcnM6DQotICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4NCi0gKgkJCWRvYwkJCS0JSGFuZGxlIHRvIHRoZSBkb2N1bWVudC4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkRG9jdW1lbnQgZnVuY3Rpb24uDQotICoJCQlhbHBoYQkJLQlUaGUgdHJhbnNwYXJlbmN5IG9mIHRoZSBmb3JtIGZpZWxkIGhpZ2hsaWdodCBjb2xvci4gYmV0d2VlbiAwLTI1NS4NCi0gKiBSZXR1cm4gVmFsdWU6DQotICoJCQlOT05FLg0KLSAqKi8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfU2V0Rm9ybUZpZWxkSGlnaGxpZ2h0QWxwaGEoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIHVuc2lnbmVkIGNoYXIgYWxwaGEpOw0KLQ0KLQ0KLS8qKg0KLSAqIEZ1bmN0aW9uOiBGUERGX1JlbW92ZUZvcm1GaWVsZEhpZ2hsaWdodA0KLSAqCQkJUmVtb3ZlIHRoZSBmb3JtIGZpZWxkIGhpZ2hsaWdodCBjb2xvciBpbiB0aGUgZG9jdW1lbnQuDQotICogUGFyYW1ldGVyczoNCi0gKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSAqIFJldHVybiBWYWx1ZToNCi0gKgkJCU5PTkUuDQotICogQ29tbWVudHM6DQotICoJCQlQbGVhc2UgcmVmcmVzaCB0aGUgY2xpZW50IHdpbmRvdyB0byByZW1vdmUgdGhlIGhpZ2hsaWdodCBpbW1lZGlhdGVseSBpZiBuZWNlc3NhcnkuDQotICoqLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9SZW1vdmVGb3JtRmllbGRIaWdobGlnaHQoRlBERl9GT1JNSEFORExFIGhIYW5kbGUpOw0KLQ0KLS8qKg0KLSogRnVuY3Rpb246IEZQREZfRkZMRHJhdw0KLSoJCQlSZW5kZXIgRm9ybUZlaWxkcyBvbiBhIHBhZ2UgdG8gYSBkZXZpY2UgaW5kZXBlbmRlbnQgYml0bWFwLiAJCQkNCi0qIFBhcmFtZXRlcnM6DQotKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50Lg0KLSoJCQliaXRtYXAJCS0JSGFuZGxlIHRvIHRoZSBkZXZpY2UgaW5kZXBlbmRlbnQgYml0bWFwIChhcyB0aGUgb3V0cHV0IGJ1ZmZlcikuDQotKgkJCQkJCQlCaXRtYXAgaGFuZGxlIGNhbiBiZSBjcmVhdGVkIGJ5IEZQREZCaXRtYXBfQ3JlYXRlIGZ1bmN0aW9uLg0KLSoJCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0qCQkJc3RhcnRfeAkJLQlMZWZ0IHBpeGVsIHBvc2l0aW9uIG9mIHRoZSBkaXNwbGF5IGFyZWEgaW4gdGhlIGRldmljZSBjb29yZGluYXRlLg0KLSoJCQlzdGFydF95CQktCVRvcCBwaXhlbCBwb3NpdGlvbiBvZiB0aGUgZGlzcGxheSBhcmVhIGluIHRoZSBkZXZpY2UgY29vcmRpbmF0ZS4NCi0qCQkJc2l6ZV94CQktCUhvcml6b250YWwgc2l6ZSAoaW4gcGl4ZWxzKSBmb3IgZGlzcGxheWluZyB0aGUgcGFnZS4NCi0qCQkJc2l6ZV95CQktCVZlcnRpY2FsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuDQotKgkJCXJvdGF0ZQkJLQlQYWdlIG9yaWVudGF0aW9uOiAwIChub3JtYWwpLCAxIChyb3RhdGVkIDkwIGRlZ3JlZXMgY2xvY2t3aXNlKSwNCi0qCQkJCQkJCQkyIChyb3RhdGVkIDE4MCBkZWdyZWVzKSwgMyAocm90YXRlZCA5MCBkZWdyZWVzIGNvdW50ZXItY2xvY2t3aXNlKS4NCi0qCQkJZmxhZ3MJCS0JMCBmb3Igbm9ybWFsIGRpc3BsYXksIG9yIGNvbWJpbmF0aW9uIG9mIGZsYWdzIGRlZmluZWQgYWJvdmUuIA0KLSogUmV0dXJuIFZhbHVlOg0KLSoJCQlOb25lLg0KLSogQ29tbWVudHM6IA0KLSoJCQlUaGlzIG1ldGhvZCBpcyBkZXNpZ25lZCB0byBvbmx5IHJlbmRlciBhbm5vdGF0aW9ucyBhbmQgRm9ybUZpZWxkcyBvbiB0aGUgcGFnZS4gDQotKgkJCVdpdGhvdXQgRlBERl9BTk5PVCBzcGVjaWZpZWQgZm9yIGZsYWdzLCBSZW5kZXJpbmcgZnVuY3Rpb25zIHN1Y2ggYXMgRlBERl9SZW5kZXJQYWdlQml0bWFwIG9yIEZQREZfUmVuZGVyUGFnZUJpdG1hcF9TdGFydCB3aWxsIG9ubHkgcmVuZGVyIHBhZ2UgY29udGVudHMod2l0aG91dCBhbm5vdGF0aW9ucykgdG8gYSBiaXRtYXAuDQotKgkJCUluIG9yZGVyIHRvIGltcGxlbWVudCB0aGUgRm9ybUZpbGwgZnVuY3Rpb25zLEltcGxlbWVudGF0aW9uIHNob3VsZCBjYWxsIHRoaXMgbWV0aG9kIGFmdGVyIHJlbmRlcmluZyBmdW5jdGlvbnMgZmluaXNoIHJlbmRlcmluZyB0aGUgcGFnZSBjb250ZW50cy4NCi0qKi8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfRkZMRHJhdyhGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSxGUERGX0JJVE1BUCBiaXRtYXAsIEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIA0KLQkJCQkJCWludCBzaXplX3gsIGludCBzaXplX3ksIGludCByb3RhdGUsIGludCBmbGFncyk7DQotDQotDQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfTsNCi0jZW5kaWYNCi0NCi0jZW5kaWYgLy9fRlBERk9STUZJTExfSA0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKworI2lmbmRlZiBfRlBERk9STUZJTExfSAorI2RlZmluZSBfRlBERk9STUZJTExfSAorI2luY2x1ZGUgImZwZGZ2aWV3LmgiCisKK3R5cGVkZWYgdm9pZCogRlBERl9GT1JNSEFORExFOworCisvLyBFeHBvcnRlZCBGdW5jdGlvbnMKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKwordHlwZWRlZiBzdHJ1Y3QgX0lQREZfSnNQbGF0Zm9ybQoreworLyoqCisqIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcmZhY2UuIEN1cnJlbnRseSBtdXN0IGJlIDEuCisJKiovCisJaW50IHZlcnNpb247CisJCisJLyoqIAorCSogTWV0aG9kOiBhcHBfYWxlcnQKKwkqCQkJcG9wIHVwIGEgZGlhbG9nIHRvIHNob3cgd2FybmluZyBvciBoaW50LgorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQl5ZXMKKwkqIFBhcmFtZXRlcnM6CisJKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmCisJKgkJCU1zZwkJCS0JQSBzdHJpbmcgY29udGFpbmluZyB0aGUgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQuCisJKgkJCVRpdGxlCQktICAgVGhlIHRpdGxlIG9mIHRoZSBkaWFsb2cuCisJKgkJCVR5cGUJCS0JVGhlIHN0eXBlIG9mIGJ1dHRvbiBncm91cC4gCisJKgkJCQkJCQkwLU9LKGRlZmF1bHQpOworCSoJCQkJCQkJMS1PSyxDYW5jZWw7CisJKgkJCQkJCQkyLVllcyxOTzsgCisJKgkJCQkJCQkzLVllcywgTk8sIENhbmNlbC4KKwkqICAgICAgICAgICBuSWNvbgkJLSAgIFRoZSBJY29uIHR5cGUuIAorCSoJCQkJCQkJMC1FcnJvcihkZWZhdWx0KTsKKwkqCQkJCQkJCTEtV2FybmluZzsKKwkqCQkJCQkJCTItUXVlc3Rpb247CisJKgkJCQkJCQkzLVN0YXR1cy4KKwkqIFJldHVybiBWYWx1ZToKKwkqCQkJVGhlIHJldHVybiB2YWx1ZSBjb3VsZCBiZSB0aGUgZm9sb3dpbmcgdHlwZToKKwkqCQkJCQkJCTEtT0s7CisJKgkJCQkJCQkyLUNhbmNlbDsgCisJKgkJCQkJCQkzLU5POworCSoJCQkJCQkJNC1ZZXM7CisJKi8KKwlpbnQgKCphcHBfYWxlcnQpKHN0cnVjdCBfSVBERl9Kc1BsYXRmb3JtKiBwVGhpcywgRlBERl9XSURFU1RSSU5HIE1zZywgRlBERl9XSURFU1RSSU5HIFRpdGxlLCBpbnQgVHlwZSwgaW50IEljb24pOworCQorCS8qKiAKKwkqIE1ldGhvZDogYXBwX2JlZXAKKwkqCQkJQ2F1c2VzIHRoZSBzeXN0ZW0gdG8gcGxheSBhIHNvdW5kLiAKKwkqIEludGVyZmFjZSBWZXJzaW9uOgorCSoJCQkxCisJKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoKKwkqCQkJeWVzCisJKiBQYXJhbWV0ZXJzOgorCSoJCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZgorCSoJCQluVHlwZQkJLQlUaGUgc291bmQgdHlwZS4KKwkqCQkJCQkJCTAgLSBFcnJvcgorCSoJCQkJCQkJMSAtIFdhcm5pbmcKKwkqCQkJCQkJCTIgLSBRdWVzdGlvbgorCSoJCQkJCQkJMyAtIFN0YXR1cworCSoJCQkJCQkJNCAtIERlZmF1bHQgKGRlZmF1bHQgdmFsdWUpCisJKiBSZXR1cm4gVmFsdWU6CisJKgkJCU5vbmUKKwkqLworCXZvaWQgKCphcHBfYmVlcCkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLCAgaW50IG5UeXBlKTsKKwkKKwkKKwkvKiogCisJKiBNZXRob2Q6IGFwcF9yZXNwb25zZQorCSoJCQlEaXNwbGF5cyBhIGRpYWxvZyBib3ggY29udGFpbmluZyBhIHF1ZXN0aW9uIGFuZCBhbiBlbnRyeSBmaWVsZCBmb3IgdGhlIHVzZXIgdG8gcmVwbHkgdG8gdGhlIHF1ZXN0aW9uLiAgCisJKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkqCQkJMQorCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJKgkJCXllcworCSogUGFyYW1ldGVyczoKKwkqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYKKwkqCQkJUXVlc3Rpb24JLQlUaGUgcXVlc3Rpb24gdG8gYmUgcG9zZWQgdG8gdGhlIHVzZXIuCisJKgkJCVRpdGxlCQktCVRoZSB0aXRsZSBvZiB0aGUgZGlhbG9nIGJveC4KKwkqCQkJRGVmYXVsdAkJLQlBIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSBhbnN3ZXIgdG8gdGhlIHF1ZXN0aW9uLiBJZiBub3Qgc3BlY2lmaWVkLCBubyBkZWZhdWx0IHZhbHVlIGlzIHByZXNlbnRlZC4KKwkqCQkJY0xhYmVsCQktCUEgc2hvcnQgc3RyaW5nIHRvIGFwcGVhciBpbiBmcm9udCBvZiBhbmQgb24gdGhlIHNhbWUgbGluZSBhcyB0aGUgZWRpdCB0ZXh0IGZpZWxkLiAKKwkqCQkJYlBhc3N3b3JkCS0JSWYgdHJ1ZSwgaW5kaWNhdGVzIHRoYXQgdGhlIHVzZXIncyByZXNwb25zZSBzaG91bGQgc2hvdyBhcyBhc3Rlcmlza3MgKCopIG9yIGJ1bGxldHMgKD8pIHRvIG1hc2sgdGhlIHJlc3BvbnNlLCB3aGljaCBtaWdodCBiZSBzZW5zaXRpdmUgaW5mb3JtYXRpb24uIFRoZSBkZWZhdWx0IGlzIGZhbHNlLgkJCisJKgkJCXJlc3BvbnNlCS0JQSBzdHJpbmcgYnVmZmVyIGFsbG9jYXRlZCBieSBTREssIHRvIHJlY2VpdmUgdGhlIHVzZXIncyByZXNwb25zZS4gCisJKgkJCWxlbmd0aAkJLSAgIFRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlciwgbnVtYmVyIG9mIGJ5dGVzLiBDdXJyZW50bHksIEl0J3MgYWx3YXlzIGJlIDIwNDguCisJKiBSZXR1cm4gVmFsdWU6CisJKgkJCU51bWJlciBvZiBieXRlcyB0aGUgdXNlciBpbnB1dCB0ZXh0IGNvbnN1bWVzLCBub3QgaW5jbHVkaW5nIHRyYWlsaW5nIHplcm9zLiBJZiB0aGUgdGV4dCBleGNlZWQgMjA0OCBieXRlcywKKwkqCQkJdGhlIGV4Y2VlZGVkIHBhcnQgd2lsbCBiZSBpZ25vcmVkLgorCSogQ29tbWVudHM6CisJKgkJCU5vIG1hdHRlciBvbiB3aGF0IHBsYXRmb3JtLCB0aGUgcmVzcG9uc2Ugc2hvdWxkIGJlIGFsd2F5cyBpbnB1dCBpbiBVVEYtMTZMRSBlbmNvZGluZy4KKwkqCQkJVGhlIHJldHVybiB2YWx1ZSBhbHdheXMgaW5kaWNhdGVkIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCBmb3IgdGhlIGJ1ZmZlciwgZXZlbiB3aGVuIHRoZXJlIGlzCisJKgkJCW5vIGJ1ZmZlciBzcGVjaWZpZWQsIG9yIHRoZSBidWZmZXIgc2l6ZSBpcyBsZXNzIHRoZW4gcmVxdWlyZWQuIEluIHRoaXMgY2FzZSwgdGhlIGJ1ZmZlciB3aWxsIG5vdAorCSoJCQliZSBtb2RpZmllZC4KKwkqLworCWludCAoKmFwcF9yZXNwb25zZSkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLCBGUERGX1dJREVTVFJJTkcgUXVlc3Rpb24sIEZQREZfV0lERVNUUklORyBUaXRsZSwgRlBERl9XSURFU1RSSU5HIERlZmF1bHQsIEZQREZfV0lERVNUUklORyBjTGFiZWwsIEZQREZfQk9PTCBiUGFzc3dvcmQsIHZvaWQqIHJlc3BvbnNlLCBpbnQgbGVuZ3RoKTsKKwkKKwkKKwkKKwkvKgorCSogTWV0aG9kOiBEb2NfZ2V0RmlsZVBhdGgKKwkqCQkJR2V0IHRoZSBmaWxlIHBhdGggb2YgdGhlIGN1cnJlbnQgZG9jdW1lbnQuIAorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQl5ZXMKKwkqIFBhcmFtZXRlcnM6CisJKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmCisJKgkJCWZpbGVQYXRoCS0JVGhlIHN0cmluZyBidWZmZXIgdG8gcmVjZWl2ZSB0aGUgZmlsZSBwYXRoLiBDYW4gYmUgTlVMTC4KKwkqCQkJbGVuZ3RoCQktICAgVGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyLCBudW1iZXIgb2YgYnl0ZXMuIENhbiBiZSAwLgorCSogUmV0dXJuIFZhbHVlOgorCSoJCU51bWJlciBvZiBieXRlcyB0aGUgZmlsZVBhdGggY29uc3VtZXMsIGluY2x1ZGluZyB0cmFpbGluZyB6ZXJvcy4KKwkqIENvbW1lbnRzOgorCSoJCVRoZSBmaWxlUGF0aCBzaG91bGQgYmUgYWx3YXlzIGlucHV0IGluIGxvY2FsIGVuY29kaW5nLgorCSoKKwkqCQlUaGUgcmV0dXJuIHZhbHVlIGFsd2F5cyBpbmRpY2F0ZWQgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIGZvciB0aGUgYnVmZmVyLCBldmVuIHdoZW4gdGhlcmUgaXMKKwkqCQlubyBidWZmZXIgc3BlY2lmaWVkLCBvciB0aGUgYnVmZmVyIHNpemUgaXMgbGVzcyB0aGVuIHJlcXVpcmVkLiBJbiB0aGlzIGNhc2UsIHRoZSBidWZmZXIgd2lsbCBub3QKKwkqCQliZSBtb2RpZmllZC4KKwkqLworCWludCAoKkRvY19nZXRGaWxlUGF0aCkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLCB2b2lkKiBmaWxlUGF0aCwgaW50IGxlbmd0aCk7CisJCisJCisJLyoKKwkqIE1ldGhvZDogRG9jX21haWwKKwkqCQkJTWFpbHMgdGhlIGRhdGEgYnVmZmVyIGFzIGFuIGF0dGFjaG1lbnQgdG8gYWxsIHJlY2lwaWVudHMsIHdpdGggb3Igd2l0aG91dCB1c2VyIGludGVyYWN0aW9uLiAKKwkqIEludGVyZmFjZSBWZXJzaW9uOgorCSoJCQkxCisJKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoKKwkqCQkJeWVzCisJKiBQYXJhbWV0ZXJzOgorCSoJCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZgorCSoJCQltYWlsRGF0YQktCVBvaW50ZXIgdG8gdGhlIGRhdGEgYnVmZmVyIHRvIGJlIHNlbnQuQ2FuIGJlIE5VTEwuCisJKgkJCWxlbmd0aAkJLQlUaGUgc2l6ZSxpbiBieXRlcywgb2YgdGhlIGJ1ZmZlciBwb2ludGVkIGJ5IG1haWxEYXRhIHBhcmFtZXRlci5DYW4gYmUgMC4KKwkqCQkJYlVJCQkJLSAgIElmIHRydWUsIHRoZSByZXN0IG9mIHRoZSBwYXJhbWV0ZXJzIGFyZSB1c2VkIGluIGEgY29tcG9zZS1uZXctbWVzc2FnZSB3aW5kb3cgdGhhdCBpcyBkaXNwbGF5ZWQgdG8gdGhlIHVzZXIuIElmIGZhbHNlLCB0aGUgY1RvIHBhcmFtZXRlciBpcyByZXF1aXJlZCBhbmQgYWxsIG90aGVycyBhcmUgb3B0aW9uYWwuCisJKgkJCVRvCQkJLQlBIHNlbWljb2xvbi1kZWxpbWl0ZWQgbGlzdCBvZiByZWNpcGllbnRzIGZvciB0aGUgbWVzc2FnZS4KKwkqCQkJU3ViamVjdAkJLSAgIFRoZSBzdWJqZWN0IG9mIHRoZSBtZXNzYWdlLiBUaGUgbGVuZ3RoIGxpbWl0IGlzIDY0IEtCLgorCSoJCQlDQwkJCS0JQSBzZW1pY29sb24tZGVsaW1pdGVkIGxpc3Qgb2YgQ0MgcmVjaXBpZW50cyBmb3IgdGhlIG1lc3NhZ2UuIAorCSoJCQlCQ0MJCQktICAgQSBzZW1pY29sb24tZGVsaW1pdGVkIGxpc3Qgb2YgQkNDIHJlY2lwaWVudHMgZm9yIHRoZSBtZXNzYWdlLiAKKwkqCQkJTXNnCQkJLSAgIFRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlLiBUaGUgbGVuZ3RoIGxpbWl0IGlzIDY0IEtCLgorCSogUmV0dXJuIFZhbHVlOgorCSoJCQlOb25lLgorCSogQ29tbWVudHM6CisJKgkJCUlmIHRoZSBwYXJhbWV0ZXIgbWFpbERhdGEgaXMgTlVMTCBvciBsZW5ndGggaXMgMCwgdGhlIGN1cnJlbnQgZG9jdW1lbnQgd2lsbCBiZSBtYWlsZWQgYXMgYW4gYXR0YWNobWVudCB0byBhbGwgcmVjaXBpZW50cy4KKwkqLworCXZvaWQgKCpEb2NfbWFpbCkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLHZvaWQqIG1haWxEYXRhLCBpbnQgbGVuZ3RoLEZQREZfQk9PTCBiVUksIEZQREZfV0lERVNUUklORyBUbywgRlBERl9XSURFU1RSSU5HIFN1YmplY3QsIEZQREZfV0lERVNUUklORyBDQywgRlBERl9XSURFU1RSSU5HIEJDQywgRlBERl9XSURFU1RSSU5HIE1zZyk7IAorCQorCisJLyoKKwkqIE1ldGhvZDogRG9jX3ByaW50CisJKgkJCVByaW50cyBhbGwgb3IgYSBzcGVjaWZpYyBudW1iZXIgb2YgcGFnZXMgb2YgdGhlIGRvY3VtZW50LgorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQl5ZXMKKwkqIFBhcmFtZXRlcnM6CisJKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLgorCSoJCQliVUkJCQktCUlmIHRydWUsIHdpbGwgY2F1c2UgYSBVSSB0byBiZSBwcmVzZW50ZWQgdG8gdGhlIHVzZXIgdG8gb2J0YWluIHByaW50aW5nIGluZm9ybWF0aW9uIGFuZCBjb25maXJtIHRoZSBhY3Rpb24uCisJKgkJCW5TdGFydAkJLQlBIDAtYmFzZWQgaW5kZXggdGhhdCBkZWZpbmVzIHRoZSBzdGFydCBvZiBhbiBpbmNsdXNpdmUgcmFuZ2Ugb2YgcGFnZXMuCisJKgkJCW5FbmQJCS0gICBBIDAtYmFzZWQgaW5kZXggdGhhdCBkZWZpbmVzIHRoZSBlbmQgb2YgYW4gaW5jbHVzaXZlIHBhZ2UgcmFuZ2UuCisJKgkJCWJTaWxlbnQJCS0gICBJZiB0cnVlLCBzdXBwcmVzc2VzIHRoZSBjYW5jZWwgZGlhbG9nIGJveCB3aGlsZSB0aGUgZG9jdW1lbnQgaXMgcHJpbnRpbmcuIFRoZSBkZWZhdWx0IGlzIGZhbHNlLgorCSoJCQliU2hyaW5rVG9GaXQJLQlJZiB0cnVlLCB0aGUgcGFnZSBpcyBzaHJ1bmsgKGlmIG5lY2Vzc2FyeSkgdG8gZml0IHdpdGhpbiB0aGUgaW1hZ2VhYmxlIGFyZWEgb2YgdGhlIHByaW50ZWQgcGFnZS4KKwkqCQkJYlByaW50QXNJbWFnZQktCUlmIHRydWUsIHByaW50IHBhZ2VzIGFzIGFuIGltYWdlLgorCSoJCQliUmV2ZXJzZQktCUlmIHRydWUsIHByaW50IGZyb20gbkVuZCB0byBuU3RhcnQuCisJKgkJCWJBbm5vdGF0aW9ucwktCUlmIHRydWUgKHRoZSBkZWZhdWx0KSwgYW5ub3RhdGlvbnMgYXJlIHByaW50ZWQuCisJKi8KKwl2b2lkICgqRG9jX3ByaW50KShzdHJ1Y3QgX0lQREZfSnNQbGF0Zm9ybSogcFRoaXMsIEZQREZfQk9PTCBiVUksIGludCBuU3RhcnQsIGludCBuRW5kLCBGUERGX0JPT0wgYlNpbGVudCAsRlBERl9CT09MIGJTaHJpbmtUb0ZpdCxGUERGX0JPT0wgYlByaW50QXNJbWFnZSAsRlBERl9CT09MIGJSZXZlcnNlICxGUERGX0JPT0wgYkFubm90YXRpb25zKTsKKworCS8qCisJKiBNZXRob2Q6IERvY19zdWJtaXRGb3JtCisJKgkJCVNlbmQgdGhlIGZvcm0gZGF0YSB0byBhIHNwZWNpZmllZCBVUkwuCisJKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkqCQkJMQorCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJKgkJCXllcworCSogUGFyYW1ldGVyczoKKwkqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYKKwkqCQkJZm9ybURhdGEJLQlQb2ludGVyIHRvIHRoZSBkYXRhIGJ1ZmZlciB0byBiZSBzZW50LgorCSoJCQlsZW5ndGgJCS0JVGhlIHNpemUsaW4gYnl0ZXMsIG9mIHRoZSBidWZmZXIgcG9pbnRlZCBieSBmb3JtRGF0YSBwYXJhbWV0ZXIuCisJKgkJCVVSTAkJCS0JVGhlIFVSTCB0byBzZW5kIHRvLgorCSogUmV0dXJuIFZhbHVlOgorCSoJCQlOb25lLgorCSoKKwkqLworCXZvaWQgKCpEb2Nfc3VibWl0Rm9ybSkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLHZvaWQqIGZvcm1EYXRhLCBpbnQgbGVuZ3RoLCBGUERGX1dJREVTVFJJTkcgVVJMKTsKKwkKKwkvKgorCSogTWV0aG9kOiBEb2NfZ290b1BhZ2UKKwkqCQkJSnVtcCB0byBhIHNwZWNpZmllZCBwYWdlLgorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQl5ZXMKKwkqIFBhcmFtZXRlcnM6CisJKgkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmCisJKgkJCW5QYWdlTnVtCS0JVGhlIHNwZWNpZmllZCBwYWdlIG51bWJlciwgemVybyBmb3IgdGhlIGZpcnN0IHBhZ2UuCisJKiBSZXR1cm4gVmFsdWU6CisJKgkJCU5vbmUuCisJKgorCSovCisJdm9pZCAoKkRvY19nb3RvUGFnZSkoc3RydWN0IF9JUERGX0pzUGxhdGZvcm0qIHBUaGlzLCBpbnQgblBhZ2VOdW0pOworCS8qCisJKiBNZXRob2Q6IEZpZWxkX2Jyb3dzZQorCSoJCQlTaG93IGEgZmlsZSBzZWxlY3Rpb24gZGlhbG9nLCBhbmQgcmV0dXJuIHRoZSBzZWxlY3RlZCBmaWxlIHBhdGguCisJKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkqCQkJMQorCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJKgkJCXllcworCSogUGFyYW1ldGVyczoKKwkqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuCisJKgkJCWZpbGVQYXRoCS0JUG9pbnRlciB0byB0aGUgZGF0YSBidWZmZXIgdG8gcmVjZWl2ZSB0aGUgZmlsZSBwYXRoLkNhbiBiZSBOVUxMLgorCSoJCQlsZW5ndGgJCS0gICBUaGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIsIG51bWJlciBvZiBieXRlcy4gQ2FuIGJlIDAuCisJKiBSZXR1cm4gVmFsdWU6CisJKgkJTnVtYmVyIG9mIGJ5dGVzIHRoZSBmaWxlUGF0aCBjb25zdW1lcywgaW5jbHVkaW5nIHRyYWlsaW5nIHplcm9zLgorCSogQ29tbWVudHM6CisJKgkJVGhlIGZpbGVQYXRoIHNob3VsZSBiZSBhbHdheXMgaW5wdXQgaW4gbG9jYWwgZW5jb2RpbmcuCisJKi8KKwlpbnQgICgqRmllbGRfYnJvd3NlKShzdHJ1Y3QgX0lQREZfSnNQbGF0Zm9ybSogcFRoaXMsdm9pZCogZmlsZVBhdGgsIGludCBsZW5ndGgpOworCisJLyoqCisJKglwb2ludGVyIHRvIEZQREZfRk9STUZJTExJTkZPIGludGVyZmFjZS4KKwkqKi8KKwl2b2lkKgltX3BGb3JtZmlsbGluZm87Cit9IElQREZfSlNQTEFURk9STTsKKworLy8gRmxhZ3MgZm9yIEN1cnNvciB0eXBlCisjZGVmaW5lIEZYQ1RfQVJST1cJMAorI2RlZmluZSBGWENUX05FU1cJMQkJCisjZGVmaW5lIEZYQ1RfTldTRQkyCQkKKyNkZWZpbmUgRlhDVF9WQkVBTQkzCQkKKyNkZWZpbmUgRlhDVF9IQkVBTQk0CQorI2RlZmluZSBGWENUX0hBTkQJNQorCisvKioKKyAqIERlY2xhcmVzIG9mIGEgcG9pbnRlciB0eXBlIHRvIHRoZSBjYWxsYmFjayBmdW5jdGlvbiBmb3IgdGhlIEZGSV9TZXRUaW1lciBtZXRob2QuCisgKiBQYXJhbWV0ZXJzOgorICoJCQlpZEV2ZW50CQktCUlkZW50aWZpZXIgb2YgdGhlIHRpbWVyLiAKKyAqIFJldHVybiB2YWx1ZToKKyAqCQkJTm9uZS4gCisgKiovCQordHlwZWRlZiB2b2lkCSgqVGltZXJDYWxsYmFjaykoaW50IGlkRXZlbnQpOworCisvKioKKyAqIERlY2xhcmVzIG9mIGEgc3RydWN0IHR5cGUgdG8gdGhlIGxvY2FsIHN5c3RlbSB0aW1lLgorKiovCit0eXBlZGVmIHN0cnVjdCBfRlBERl9TWVNURU1USU1FIAoreworICAgIHVuc2lnbmVkIHNob3J0IHdZZWFyOwkJCS8qIHllYXJzIHNpbmNlIDE5MDAgKi8KKyAgICB1bnNpZ25lZCBzaG9ydCB3TW9udGg7CQkJLyogbW9udGhzIHNpbmNlIEphbnVhcnkgLSBbMCwxMV0gKi8KKyAgICB1bnNpZ25lZCBzaG9ydCB3RGF5T2ZXZWVrOwkJLyogZGF5cyBzaW5jZSBTdW5kYXkgLSBbMCw2XSAqLworICAgIHVuc2lnbmVkIHNob3J0IHdEYXk7CQkJLyogZGF5IG9mIHRoZSBtb250aCAtIFsxLDMxXSAqLworICAgIHVuc2lnbmVkIHNob3J0IHdIb3VyOwkJCS8qIGhvdXJzIHNpbmNlIG1pZG5pZ2h0IC0gWzAsMjNdICovCisgICAgdW5zaWduZWQgc2hvcnQgd01pbnV0ZTsJCQkvKiBtaW51dGVzIGFmdGVyIHRoZSBob3VyIC0gWzAsNTldICovCisgICAgdW5zaWduZWQgc2hvcnQgd1NlY29uZDsJCQkvKiBzZWNvbmRzIGFmdGVyIHRoZSBtaW51dGUgLSBbMCw1OV0gKi8KKyAgICB1bnNpZ25lZCBzaG9ydCB3TWlsbGlzZWNvbmRzOwkvKiBtaWxsaXNlY29uZHMgYWZ0ZXIgdGhlIHNlY29uZCAtIFswLDk5OV0gKi8KK31GUERGX1NZU1RFTVRJTUU7CisKKwordHlwZWRlZiBzdHJ1Y3QgIF9GUERGX0ZPUk1GSUxMSU5GTworeworCS8qKgorCSAqIFZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcmZhY2UuIEN1cnJlbnRseSBtdXN0IGJlIDEuCisJICoqLworCWludAl2ZXJzaW9uOworCisJCS8qKiAKKwkgKiBNZXRob2Q6IFJlbGVhc2UKKwkgKgkJCUdpdmUgaW1wbGVtZW50YXRpb24gYSBjaGFuY2UgdG8gcmVsZWFzZSBhbnkgZGF0YSBhZnRlciB0aGUgaW50ZXJmYWNlIGlzIG5vIGxvbmdlciB1c2VkCisJICogSW50ZXJmYWNlIFZlcnNpb246CisJICoJCQkxCisJICogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJICoJCQlObworCSAqIENvbW1lbnRzOgorCSAqCQkJQ2FsbGVkIGJ5IEZveGl0IFNESyBkdXJpbmcgdGhlIGZpbmFsIGNsZWFudXAgcHJvY2Vzcy4KKwkgKiBQYXJhbWV0ZXJzOgorCSAqCQkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYKKwkgKiBSZXR1cm4gVmFsdWU6CisJICoJCQlOb25lCisJICovCisKKwl2b2lkICgqUmVsZWFzZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMpOworCisJLyoqIAorCSAqIE1ldGhvZDogRkZJX0ludmFsaWRhdGUKKwkgKgkJCUludmFsaWRhdGUgdGhlIGNsaWVudCBhcmVhIHdpdGhpbiB0aGUgc3BlY2lmaWVkIHJlY3RhbmdsZS4KKwkgKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkgKgkJCTEKKwkgKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoKKwkJKgkJCXllcworCSAqIFBhcmFtZXRlcnM6CisJICoJCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4KKwkgKgkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorCSAqCQkJbGVmdAkJLQlMZWZ0IHBvc2l0aW9uIG9mIHRoZSBjbGllbnQgYXJlYSBpbiBQREYgcGFnZSBjb29yZGluYXRlLgorCSAqCQkJdG9wCQkJLQlUb3AgIHBvc2l0aW9uIG9mIHRoZSBjbGllbnQgYXJlYSBpbiBQREYgcGFnZSBjb29yZGluYXRlLgorCSAqCQkJcmlnaHQJCS0JUmlnaHQgcG9zaXRpb24gb2YgdGhlIGNsaWVudCBhcmVhIGluIFBERiBwYWdlICBjb29yZGluYXRlLgorCSAqCQkJYm90dG9tCQktCUJvdHRvbSBwb3NpdGlvbiBvZiB0aGUgY2xpZW50IGFyZWEgaW4gUERGIHBhZ2UgY29vcmRpbmF0ZS4KKwkgKiBSZXR1cm4gVmFsdWU6CisJICoJCQlOb25lLgorCSAqCisJICpjb21tZW50czoKKwkgKgkJCUFsbCBwb3NpdGlvbnMgYXJlIG1lYXN1cmVkIGluIFBERiAidXNlciBzcGFjZSIuCisJICoJCQlJbXBsZW1lbnRhdGlvbiBzaG91bGQgY2FsbCBGUERGX1JlbmRlclBhZ2VCaXRtYXAoKSBmdW5jdGlvbiBmb3IgcmVwYWludGluZyBhIHNwZWNpZmllZCBwYWdlIGFyZWEuCisJKi8KKwl2b2lkICgqRkZJX0ludmFsaWRhdGUpKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLEZQREZfUEFHRSBwYWdlLCBkb3VibGUgbGVmdCwgZG91YmxlIHRvcCwgZG91YmxlIHJpZ2h0LCBkb3VibGUgYm90dG9tKTsKKwkKKwkvKiogCisJICogTWV0aG9kOiBGRklfT3V0cHV0U2VsZWN0ZWRSZWN0CisJICoJCQlXaGVuIHVzZXIgaXMgdGFraW5nIHRoZSBtb3VzZSB0byBzZWxlY3QgdGV4dHMgb24gYSBmb3JtIGZpZWxkLCB0aGlzIGNhbGxiYWNrIGZ1bmN0aW9uIHdpbGwga2VlcCAKKwkgKgkJCXJldHVybmluZyB0aGUgc2VsZWN0ZWQgYXJlYXMgdG8gdGhlIGltcGxlbWVudGF0aW9uLgorCSAqCisJICogSW50ZXJmYWNlIFZlcnNpb246CisJICoJCQkxCisJICogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJICoJCQlObworCSAqIFBhcmFtZXRlcnM6CisJICoJCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4KKwkgKgkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorCSAqCQkJbGVmdAkJLQlMZWZ0IHBvc2l0aW9uIG9mIHRoZSBjbGllbnQgYXJlYSBpbiBQREYgcGFnZSBjb29yZGluYXRlLgorCSAqCQkJdG9wCQkJLQlUb3AgIHBvc2l0aW9uIG9mIHRoZSBjbGllbnQgYXJlYSBpbiBQREYgcGFnZSBjb29yZGluYXRlLgorCSAqCQkJcmlnaHQJCS0JUmlnaHQgcG9zaXRpb24gb2YgdGhlIGNsaWVudCBhcmVhIGluIFBERiBwYWdlICBjb29yZGluYXRlLgorCSAqCQkJYm90dG9tCQktCUJvdHRvbSBwb3NpdGlvbiBvZiB0aGUgY2xpZW50IGFyZWEgaW4gUERGIHBhZ2UgY29vcmRpbmF0ZS4KKwkgKiBSZXR1cm4gVmFsdWU6CisJICoJCQlOb25lLgorCSAqCisJICogY29tbWVudHM6CisJICoJCQlUaGlzIENBTExCQUNLIGZ1bmN0aW9uIGlzIHVzZWZ1bCBmb3IgaW1wbGVtZW50aW5nIHNwZWNpYWwgdGV4dCBzZWxlY3Rpb24gZWZmZWN0LiBJbXBsZW1lbnRhdGlvbiBzaG91bGQKKwkgKgkJCWZpcnN0IHJlY29yZHMgdGhlIHJldHVybmVkIHJlY3RhbmdsZXMsIHRoZW4gZHJhdyB0aGVtIG9uZSBieSBvbmUgYXQgdGhlIHBhaW50aW5nIHBlcmlvZCwgbGFzdCxyZW1vdmUgYWxsIAorCSAqCQkJdGhlIHJlY29yZGVkIHJlY3RhbmdsZXMgd2hlbiBmaW5pc2ggcGFpbnRpbmcuCisJKi8KKwl2b2lkICgqRkZJX091dHB1dFNlbGVjdGVkUmVjdCkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsRlBERl9QQUdFIHBhZ2UsIGRvdWJsZSBsZWZ0LCBkb3VibGUgdG9wLCBkb3VibGUgcmlnaHQsIGRvdWJsZSBib3R0b20pOworCisJLyoqIAorCSogTWV0aG9kOiBGRklfU2V0Q3Vyc29yCisJKgkJCVNldCB0aGUgQ3Vyc29yIHNoYXBlLgorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQl5ZXMKKwkqIFBhcmFtZXRlcnM6CisJKgkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuCisJKiAJCW5DdXJzb3JUeXBlCS0JQ3Vyc29yIHR5cGUuIHNlZSBGbGFncyBmb3IgQ3Vyc29yIHR5cGUgZm9yIHRoZSBkZXRhaWxzLgorCSogCVJldHVybiB2YWx1ZToKKwkqIAkJTm9uZS4KKwkqICovCisJdm9pZCAoKkZGSV9TZXRDdXJzb3IpKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLCBpbnQgbkN1cnNvclR5cGUpOworCisJLyoqIAorCSogTWV0aG9kOiBGRklfU2V0VGltZXIKKwkqCQkJVGhpcyBtZXRob2QgaW5zdGFsbHMgYSBzeXN0ZW0gdGltZXIuIEEgdGltZS1vdXQgdmFsdWUgaXMgc3BlY2lmaWVkLCAKKwkqCQkJYW5kIGV2ZXJ5IHRpbWUgYSB0aW1lLW91dCBvY2N1cnMsIHRoZSBzeXN0ZW0gcGFzc2VzIGEgbWVzc2FnZSB0bworCSoJCQl0aGUgVGltZXJQcm9jIGNhbGxiYWNrIGZ1bmN0aW9uLiAKKwkqIEludGVyZmFjZSBWZXJzaW9uOgorCSoJCQkxCisJKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoKKwkqCQkJeWVzCisJKiBQYXJhbWV0ZXJzOgorCSoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLgorCSogCQl1RWxhcHNlCQktCVNwZWNpZmllcyB0aGUgdGltZS1vdXQgdmFsdWUsIGluIG1pbGxpc2Vjb25kcy4KKwkqIAkJbHBUaW1lckZ1bmMJLQlBIHBvaW50ZXIgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLVRpbWVyQ2FsbGJhY2suCisJKiAJUmV0dXJuIHZhbHVlOgorCSogCQlUaGUgdGltZXIgaWRlbnRpZmllciBvZiB0aGUgbmV3IHRpbWVyIGlmIHRoZSBmdW5jdGlvbiBpcyBzdWNjZXNzZnVsLgorCSoJCUFuIGFwcGxpY2F0aW9uIHBhc3NlcyB0aGlzIHZhbHVlIHRvIHRoZSBGRklfS2lsbFRpbWVyIG1ldGhvZCB0byBraWxsIAorCSoJCXRoZSB0aW1lci4gTm9uemVybyBpZiBpdCBpcyBzdWNjZXNzZnVsOyBvdGhlcndpc2UsIGl0IGlzIHplcm8uCisJKiAqLworCWludCAgKCpGRklfU2V0VGltZXIpKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLCBpbnQgdUVsYXBzZSwgVGltZXJDYWxsYmFjayBscFRpbWVyRnVuYyk7CisKKwkvKiogCisJKiBNZXRob2Q6IEZGSV9LaWxsVGltZXIKKwkqCQkJVGhpcyBtZXRob2Qga2lsbHMgdGhlIHRpbWVyIGV2ZW50IGlkZW50aWZpZWQgYnkgbklERXZlbnQsIHNldCBieSBhbiBlYXJsaWVyIGNhbGwgdG8gRkZJX1NldFRpbWVyLiAKKwkqIEludGVyZmFjZSBWZXJzaW9uOgorCSoJCQkxCisJKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoKKwkqCQkJeWVzCisJKiBQYXJhbWV0ZXJzOgorCSoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLgorCSogCQluVGltZXJJRAktCVRoZSB0aW1lciBJRCByZXR1cm4gYnkgRkZJX1NldFRpbWVyIGZ1bmN0aW9uLgorCSogCVJldHVybiB2YWx1ZToKKwkqIAkJTm9uZS4KKwkqICovCisJdm9pZCAoKkZGSV9LaWxsVGltZXIpKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLCBpbnQgblRpbWVySUQpOworCisKKwkvKiogCisJKiBNZXRob2Q6IEZGSV9HZXRMb2NhbFRpbWUKKwkqCQkJVGhpcyBtZXRob2QgcmVjZWl2ZXMgdGhlIGN1cnJlbnQgbG9jYWwgdGltZSBvbiB0aGUgc3lzdGVtLiAKKwkqIEludGVyZmFjZSBWZXJzaW9uOgorCSoJCQkxCisJKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoKKwkqCQkJeWVzCisJKiBQYXJhbWV0ZXJzOgorCSoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLgorCSogCVJldHVybiB2YWx1ZToKKwkqIAkJTm9uZS4KKwkqICovCisJRlBERl9TWVNURU1USU1FICgqRkZJX0dldExvY2FsVGltZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMpOworCisJLyoqIAorCSogTWV0aG9kOiBGRklfT25DaGFuZ2UKKwkqCQkJVGhpcyBtZXRob2Qgd2lsbCBiZSBpbnZva2VkIHRvIG5vdGlmeSBpbXBsZW1lbnRhdGlvbiB3aGVuIHRoZSB2YWx1ZSBvZiBhbnkgRm9ybUZpZWxkIG9uIHRoZSBkb2N1bWVudCBoYWQgYmVlbiBjaGFuZ2VkLgorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQlubworCSogUGFyYW1ldGVyczoKKwkqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4KKwkqIAlSZXR1cm4gdmFsdWU6CisJKiAJCU5vbmUuCisJKiAqLworCXZvaWQgKCpGRklfT25DaGFuZ2UpKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzKTsKKworCS8qKiAKKwkqIE1ldGhvZDogRkZJX0dldFBhZ2UKKwkqCQkJVGhpcyBtZXRob2QgcmVjZWl2ZXMgdGhlIHBhZ2UgcG9pbnRlciBhc3NvY2lhdGVkIHdpdGggYSBzcGVjaWZpZWQgcGFnZSBpbmRleC4KKwkqIEludGVyZmFjZSBWZXJzaW9uOgorCSoJCQkxCisJKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoKKwkqCQkJeWVzCisJKiBQYXJhbWV0ZXJzOgorCSoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLgorCSoJCWRvY3VtZW50CS0JSGFuZGxlIHRvIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBmdW5jdGlvbi4KKwkqCQluUGFnZUluZGV4ICAtCUluZGV4IG51bWJlciBvZiB0aGUgcGFnZS4gMCBmb3IgdGhlIGZpcnN0IHBhZ2UuCisJKiBSZXR1cm4gdmFsdWU6CisJKiAJCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4KKwkqIENvbW1lbnRzOgorCSoJCUluIHNvbWUgY2FzZXMsIHRoZSBkb2N1bWVudC1sZXZlbCBKYXZhU2NyaXB0IGFjdGlvbiBtYXkgcmVmZXIgdG8gYSBwYWdlIHdoaWNoIGhhZG4ndCBiZWVuIGxvYWRlZCB5ZXQuCisJKgkJVG8gc3VjY2Vzc2Z1bGx5IHJ1biB0aGUgamF2YXNjcmlwdCBhY3Rpb24sIGltcGxlbWVudGF0aW9uIG5lZWQgdG8gbG9hZCB0aGUgcGFnZSBmb3IgU0RLLgorCSogKi8KKwlGUERGX1BBR0UJKCpGRklfR2V0UGFnZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIGludCBuUGFnZUluZGV4KTsKKworCS8qKiAKKwkqIE1ldGhvZDogRkZJX0dldEN1cnJlbnRQYWdlCisJKgkJVGhpcyBtZXRob2QgcmVjZWl2ZXMgdGhlIGN1cnJlbnQgcGFnZSBwb2ludGVyLgorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQl5ZXMKKwkqIFBhcmFtZXRlcnM6CisJKgkJcFRoaXMJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuCisJKgkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLgorCSogUmV0dXJuIHZhbHVlOgorCSogCQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisJKiAqLworCUZQREZfUEFHRQkoKkZGSV9HZXRDdXJyZW50UGFnZSkoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpOworCisJLyoqIAorCSogTWV0aG9kOiBGRklfR2V0Um90YXRpb24KKwkqCQkJVGhpcyBtZXRob2QgcmVjZWl2ZXMgY3VycmVudGx5IHJvdGF0aW9uIG9mIHRoZSBwYWdlIHZpZXcuCisJKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkqCQkJMQorCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJKgkJCXllcworCSogUGFyYW1ldGVyczoKKwkqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4KKwkqCQlwYWdlCQktCUhhbmRsZSB0byBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorCSogUmV0dXJuIHZhbHVlOgorCSogCQlUaGUgcGFnZSByb3RhdGlvbi4gU2hvdWxkIGJlIDAoMCBkZWdyZWUpLDEoOTAgZGVncmVlKSwyKDE4MCBkZWdyZWUpLDMoMjcwIGRlZ3JlZSksIGluIGEgY2xvY2t3aXNlIGRpcmVjdGlvbi4KKwkqICovCisJaW50IAkoKkZGSV9HZXRSb3RhdGlvbikoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfUEFHRSBwYWdlKTsKKworCS8qKiAKKwkqIE1ldGhvZDogRkZJX0V4ZWN1dGVOYW1lZEFjdGlvbgorCSoJCQlUaGlzIG1ldGhvZCB3aWxsIGV4ZWN1dGUgYW4gbmFtZWQgYWN0aW9uLgorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQl5ZXMKKwkqIFBhcmFtZXRlcnM6CisJKgkJcFRoaXMJCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLgorCSoJCW5hbWVkQWN0aW9uCQktCUEgYnl0ZSBzdHJpbmcgd2hpY2ggaW5kaWNhdGVzIHRoZSBuYW1lZCBhY3Rpb24sIHRlcm1pbmF0ZWQgYnkgMC4KKwkqIFJldHVybiB2YWx1ZToKKwkqIAkJTm9uZS4KKwkqIENvbW1lbnRzOgorCSoJCVNlZSB0aGUgbmFtZWQgYWN0aW9ucyBkZXNjcmlwdGlvbiBvZiA8PFBERiBSZWZlcmVuY2UsIHZlcnNpb24gMS43Pj4gZm9yIG1vcmUgZGV0YWlscy4gIAorCSogKi8KKwl2b2lkIAkoKkZGSV9FeGVjdXRlTmFtZWRBY3Rpb24pKHN0cnVjdCBfRlBERl9GT1JNRklMTElORk8qIHBUaGlzLCBGUERGX0JZVEVTVFJJTkcgbmFtZWRBY3Rpb24pOworCS8qKiAKKwkqIEBicmllZiBUaGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCB3aGVuIGEgdGV4dCBmaWVsZCBpcyBnZXR0aW5nIG9yIGxvc2luZyBhIGZvY3VzLgorCSoKKwkqIEBwYXJhbVtpbl0gcFRoaXMJCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLgorCSogQHBhcmFtW2luXSB2YWx1ZQkJVGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgZm9ybSBmaWVsZCwgaW4gVVRGLTE2TEUgZm9ybWF0LgorCSogQHBhcmFtW2luXSB2YWx1ZUxlbglUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdmFsdWUsIG51bWJlciBvZiBjaGFyYWN0ZXJzIChub3QgYnl0ZXMpLgorCSogQHBhcmFtW2luXSBpc19mb2N1cwlUcnVlIGlmIHRoZSBmb3JtIGZpZWxkIGlzIGdldHRpbmcgYSBmb2N1cywgRmFsc2UgZm9yIGxvc2luZyBhIGZvY3VzLgorCSoKKwkqIEByZXR1cm4gTm9uZS4KKwkqCisJKiBAbm90ZSBDdXJyZW50bHksb25seSBzdXBwb3J0IHRleHQgZmllbGQgYW5kIGNvbWJvYm94IGZpZWxkLgorCSogKi8KKwl2b2lkCSgqRkZJX1NldFRleHRGaWVsZEZvY3VzKShzdHJ1Y3QgX0ZQREZfRk9STUZJTExJTkZPKiBwVGhpcywgRlBERl9XSURFU1RSSU5HIHZhbHVlLCBGUERGX0RXT1JEIHZhbHVlTGVuLCBGUERGX0JPT0wgaXNfZm9jdXMpOworCisJCisJLyoqIAorCSogTWV0aG9kOiBGRklfRG9VUklBY3Rpb24KKwkqCQkJVGhpcyBhY3Rpb24gcmVzb2x2ZXMgdG8gYSB1bmlmb3JtIHJlc291cmNlIGlkZW50aWZpZXIuIAorCSogSW50ZXJmYWNlIFZlcnNpb246CisJKgkJCTEKKwkqIEltcGxlbWVudGF0aW9uIFJlcXVpcmVkOgorCSoJCQlObworCSogUGFyYW1ldGVyczoKKwkqCQlwVGhpcwkJCS0JUG9pbnRlciB0byB0aGUgaW50ZXJmYWNlIHN0cnVjdHVyZSBpdHNlbGYuCisJKgkJYnNVUkkJCQktCUEgYnl0ZSBzdHJpbmcgd2hpY2ggaW5kaWNhdGVzIHRoZSB1bmlmb3JtIHJlc291cmNlIGlkZW50aWZpZXIsIHRlcm1pbmF0ZWQgYnkgMC4KKwkqIFJldHVybiB2YWx1ZToKKwkqIAkJTm9uZS4KKwkqIENvbW1lbnRzOgorCSoJCVNlZSB0aGUgVVJJIGFjdGlvbnMgZGVzY3JpcHRpb24gb2YgPDxQREYgUmVmZXJlbmNlLCB2ZXJzaW9uIDEuNz4+IGZvciBtb3JlIGRldGFpbHMuICAKKwkqICovCisJdm9pZAkoKkZGSV9Eb1VSSUFjdGlvbikoc3RydWN0IF9GUERGX0ZPUk1GSUxMSU5GTyogcFRoaXMsIEZQREZfQllURVNUUklORyBic1VSSSk7CisJCisJLyoqIAorCSogTWV0aG9kOiBGRklfRG9Hb1RvQWN0aW9uCisJKgkJCVRoaXMgYWN0aW9uIGNoYW5nZXMgdGhlIHZpZXcgdG8gYSBzcGVjaWZpZWQgZGVzdGluYXRpb24uCisJKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkqCQkJMQorCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJKgkJCU5vCisJKiBQYXJhbWV0ZXJzOgorCSoJCXBUaGlzCQkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4KKwkqCQluUGFnZUluZGV4CQktCVRoZSBpbmRleCBvZiB0aGUgUERGIHBhZ2UuCisJKgkJem9vbU1vZGUJCS0JVGhlIHpvb20gbW9kZSBmb3Igdmlld2luZyBwYWdlLlNlZSBNYWNyb3MgIlBERlpPT01fWFhYIiBkZWZpbmVkIGluICJmcGRmZG9jLmgiLiAKKwkqCQlmUG9zQXJyYXkJCS0JVGhlIGZsb2F0IGFycmF5IHdoaWNoIGNhcnJpZXMgdGhlIHBvc2l0aW9uIGluZm8uCisJKgkJc2l6ZW9mQXJyYXkJCS0JVGhlIHNpemUgb2YgZmxvYXQgYXJyYXkuCisJKiBSZXR1cm4gdmFsdWU6CisJKiAJCU5vbmUuCisJKiBDb21tZW50czoKKwkqCQlTZWUgdGhlIERlc3RpbmF0aW9ucyBkZXNjcmlwdGlvbiBvZiA8PFBERiBSZWZlcmVuY2UsIHZlcnNpb24gMS43Pj4gaW4gOC4yLjEgZm9yIG1vcmUgZGV0YWlscy4gIAorCSoqLworCXZvaWQJKCpGRklfRG9Hb1RvQWN0aW9uKShzdHJ1Y3QgX0ZQREZfRk9STUZJTExJTkZPKiBwVGhpcywgaW50IG5QYWdlSW5kZXgsIGludCB6b29tTW9kZSwgZmxvYXQqIGZQb3NBcnJheSwgaW50IHNpemVvZkFycmF5KTsKKwkvKioKKwkqCXBvaW50ZXIgdG8gSVBERl9KU1BMQVRGT1JNIGludGVyZmFjZQorCSoqLworCUlQREZfSlNQTEFURk9STSoJbV9wSnNQbGF0Zm9ybTsKKworfSBGUERGX0ZPUk1GSUxMSU5GTzsKKworCisKKy8qKgorICogRnVuY3Rpb246IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQKKyAqCQkJSW5pdCBmb3JtIGZpbGwgZW52aXJvbm1lbnQuIAorICogQ29tbWVudHM6CisgKgkJCVRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUgYW55IGZvcm0gZmlsbCBvcGVyYXRpb24uCisgKiBQYXJhbWV0ZXJzOgorICoJCQlkb2N1bWVudAkJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLgorICoJCQlwRm9ybUZpbGxJbmZvCS0JUG9pbnRlciB0byBhIEZQREZfRk9STUZJTExJTkZPIHN0cnVjdHVyZS4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJUmV0dXJuIGhhbmRsZXIgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIE5VTEwgbWVhbnMgZmFpbHMuIAorICoqLworRExMRVhQT1JUIEZQREZfRk9STUhBTkRMRSBTVERDQUxMIEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9GT1JNRklMTElORk8qIGZvcm1JbmZvKTsKKworLyoqCisgKiBGdW5jdGlvbjogRlBERkRPQ19FeGl0Rm9ybUZpbGxFbnZpcm91bWVudAorICoJCQlFeGl0IGZvcm0gZmlsbCBlbnZpcm9ubWVudC4gCisgKiBQYXJhbWV0ZXJzOgorICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJTlVMTC4KKyAqKi8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkRPQ19FeGl0Rm9ybUZpbGxFbnZpcm91bWVudChGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSk7CisKKy8qKgorICogRnVuY3Rpb246IEZPUk1fT25BZnRlckxvYWRQYWdlCisgKgkJCVRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIGZvciBpbXBsZW1lbnRpbmcgYWxsIHRoZSBmb3JtIHJlbGF0ZWQgZnVuY3Rpb25zLiBTaG91bGQgYmUgaW52b2tlZCBhZnRlciB1c2VyIAorICoJCQlzdWNjZXNzZnVsbHkgbG9hZGVkIGEgUERGIHBhZ2UsIGFuZCBtZXRob2QgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudCBoYWQgYmVlbiBpbnZva2VkLgorICogUGFyYW1ldGVyczoKKyAqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuCisgKiBSZXR1cm4gVmFsdWU6CisgKgkJCU5PTkUuCisgKiovCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fT25BZnRlckxvYWRQYWdlKEZQREZfUEFHRSBwYWdlLCBGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSk7CisKKy8qKgorICogRnVuY3Rpb246IEZPUk1fT25CZWZvcmVDbG9zZVBhZ2UKKyAqCQkJVGhpcyBtZXRob2QgaXMgcmVxdWlyZWQgZm9yIGltcGxlbWVudGluZyBhbGwgdGhlIGZvcm0gcmVsYXRlZCBmdW5jdGlvbnMuIFNob3VsZCBiZSBpbnZva2VkIGJlZm9yZSB1c2VyIAorICoJCQljbG9zZSB0aGUgUERGIHBhZ2UuCisgKiBQYXJhbWV0ZXJzOgorICoJCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4KKyAqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuCisgKiBSZXR1cm4gVmFsdWU6CisgKgkJCU5PTkUuCisgKiovCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fT25CZWZvcmVDbG9zZVBhZ2UoRlBERl9QQUdFIHBhZ2UsIEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKTsKKworLyoqCisqIEZ1bmN0aW9uOiBGT1JNX0RvRG9jdW1lbnRKU0FjdGlvbgorKgkJCVRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIGZvciBwZXJmb3JtaW5nIERvY3VtZW50LWxldmVsIEphdmFTY3JpcHQgYWN0aW9uLiBJdCBzaG91bGQgYmUgaW52b2tlZCBhZnRlciB0aGUgUERGIGRvY3VtZW50CisqCQkJaGFkIGJlZW4gbG9hZGVkLgorKiBQYXJhbWV0ZXJzOgorKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50LgorKiBSZXR1cm4gVmFsdWU6CisqCQkJTk9ORQorKiBDb21tZW50czoKKyoJCQlJZiB0aGVyZSBpcyBEb2N1bWVudC1sZXZlbCBKYXZhU2NyaXB0IGFjdGlvbiBlbWJlZGRlZCBpbiB0aGUgZG9jdW1lbnQsIHRoaXMgbWV0aG9kIHdpbGwgZXhlY3V0ZSB0aGUgamF2YXNjcmlwdCBhY3Rpb247CisqCQkJb3RoZXJ3aXNlLCB0aGUgbWV0aG9kIHdpbGwgZG8gbm90aGluZy4KKyoqLworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGT1JNX0RvRG9jdW1lbnRKU0FjdGlvbihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSk7CisKKworLyoqCisqIEZ1bmN0aW9uOiBGT1JNX0RvRG9jdW1lbnRPcGVuQWN0aW9uCisqCQkJVGhpcyBtZXRob2QgaXMgcmVxdWlyZWQgZm9yIHBlcmZvcm1pbmcgb3Blbi1hY3Rpb24gd2hlbiB0aGUgZG9jdW1lbnQgaXMgb3BlbmVkLgorKiBQYXJhbWV0ZXJzOgorKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50LgorKiBSZXR1cm4gVmFsdWU6CisqCQkJTk9ORQorKiBDb21tZW50czoKKyoJCQlUaGlzIG1ldGhvZCB3aWxsIGRvIG5vdGhpbmcgaWYgdGhlcmUgaXMgbm8gb3Blbi1hY3Rpb25zIGVtYmVkZGVkIGluIHRoZSBkb2N1bWVudC4gCisqKi8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9Eb0RvY3VtZW50T3BlbkFjdGlvbihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSk7CisKKworLy8gYWRkaXRpb25hbCBhY3Rpb25zIHR5cGUgb2YgZG9jdW1lbnQuCisjZGVmaW5lIEZQREZET0NfQUFDVElPTl9XQwkJMHgxMAkJLy9XQywgYmVmb3JlIGNsb3NpbmcgZG9jdW1lbnQsIEphdmFTY3JpcHQgYWN0aW9uLgorI2RlZmluZSBGUERGRE9DX0FBQ1RJT05fV1MJCTB4MTEJCS8vV1MsIGJlZm9yZSBzYXZpbmcgZG9jdW1lbnQsIEphdmFTY3JpcHQgYWN0aW9uLgorI2RlZmluZSBGUERGRE9DX0FBQ1RJT05fRFMJCTB4MTIJCS8vRFMsIGFmdGVyIHNhdmluZyBkb2N1bWVudCwgSmF2YVNjcmlwdCBhY3Rpb24uCisjZGVmaW5lIEZQREZET0NfQUFDVElPTl9XUAkJMHgxMwkJLy9XUCwgYmVmb3JlIHByaW50aW5nIGRvY3VtZW50LCBKYXZhU2NyaXB0IGFjdGlvbi4KKyNkZWZpbmUgRlBERkRPQ19BQUNUSU9OX0RQCQkweDE0CQkvL0RQLCBhZnRlciBwcmludGluZyBkb2N1bWVudCwgSmF2YVNjcmlwdCBhY3Rpb24uIAorLyoqCisqIEZ1bmN0aW9uOiBGT1JNX0RvRG9jdW1lbnRBQWN0aW9uCisqCQkJVGhpcyBtZXRob2QgaXMgcmVxdWlyZWQgZm9yIHBlcmZvcm1pbmcgdGhlIGRvY3VtZW50J3MgYWRkaXRpb25hbC1hY3Rpb24uCisqIFBhcmFtZXRlcnM6CisqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuCisqCQkJYWFUeXBlCSAgICAtICAgVGhlIHR5cGUgb2YgdGhlIGFkZGl0aW9uYWwtYWN0aW9ucyB3aGljaCBkZWZpbmVkIGFib3ZlLgorKiBSZXR1cm4gVmFsdWU6CisqCQkJTk9ORQorKiBDb21tZW50czoKKyoJCQlUaGlzIG1ldGhvZCB3aWxsIGRvIG5vdGhpbmcgaWYgdGhlcmUgaXMgbm8gZG9jdW1lbnQgYWRkaXRpb25hbC1hY3Rpb24gY29ycmVzcG9uZGluZyB0byB0aGUgc3BlY2lmaWVkIGFhVHlwZS4KKyoqLworCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fRG9Eb2N1bWVudEFBY3Rpb24oRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIGludCBhYVR5cGUpOworCisvLyBBZGRpdGlvbmFsLWFjdGlvbiB0eXBlcyBvZiBwYWdlIG9iamVjdAorI2RlZmluZSBGUERGUEFHRV9BQUNUSU9OX09QRU4JCTAJCS8vIC9PIC0tIEFuIGFjdGlvbiB0byBiZSBwZXJmb3JtZWQgd2hlbiB0aGUgcGFnZSBpcyBvcGVuZWQKKyNkZWZpbmUgRlBERlBBR0VfQUFDVElPTl9DTE9TRQkJMQkJLy8gL0MgLS0gQW4gYWN0aW9uIHRvIGJlIHBlcmZvcm1lZCB3aGVuIHRoZSBwYWdlIGlzIGNsb3NlZAorCisvKioKKyogRnVuY3Rpb246IEZPUk1fRG9QYWdlQUFjdGlvbgorKgkJCVRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIGZvciBwZXJmb3JtaW5nIHRoZSBwYWdlIG9iamVjdCdzIGFkZGl0aW9uYWwtYWN0aW9uIHdoZW4gb3BlbmVkIG9yIGNsb3NlZC4KKyogUGFyYW1ldGVyczoKKyoJCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4KKyoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyoJCQlhYVR5cGUJICAgIC0gICBUaGUgdHlwZSBvZiB0aGUgcGFnZSBvYmplY3QncyBhZGRpdGlvbmFsLWFjdGlvbnMgd2hpY2ggZGVmaW5lZCBhYm92ZS4KKyogUmV0dXJuIFZhbHVlOgorKgkJCU5PTkUKKyogQ29tbWVudHM6CisqCQkJVGhpcyBtZXRob2Qgd2lsbCBkbyBub3RoaW5nIGlmIG5vIGFkZGl0aW9uYWwtYWN0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZCBhYVR5cGUgZXhpc3RzLgorKiovCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fRG9QYWdlQUFjdGlvbihGUERGX1BBR0UgcGFnZSwgRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIGludCBhYVR5cGUpOworCisvKioKKyAqIEZ1bmN0aW9uOiBGT1JNX09uTW91c2VNb3ZlCisgKgkJCVlvdSBjYW4gY2FsbCB0aGlzIG1lbWJlciBmdW5jdGlvbiB3aGVuIHRoZSBtb3VzZSBjdXJzb3IgbW92ZXMuIAorICogUGFyYW1ldGVyczoKKyAqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuCisgKgkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorICoJCQltb2RpZmllcgkJLQlJbmRpY2F0ZXMgd2hldGhlciB2YXJpb3VzIHZpcnR1YWwga2V5cyBhcmUgZG93bi4gCisgKgkJCXBhZ2VfeAkJLQlTcGVjaWZpZXMgdGhlIHgtY29vcmRpbmF0ZSBvZiB0aGUgY3Vyc29yIGluIFBERiB1c2VyIHNwYWNlLiAKKyAqCQkJcGFnZV95CQktCVNwZWNpZmllcyB0aGUgeS1jb29yZGluYXRlIG9mIHRoZSBjdXJzb3IgaW4gUERGIHVzZXIgc3BhY2UuCisgKiBSZXR1cm4gVmFsdWU6CisgKgkJCVRSVUUgaW5kaWNhdGVzIHN1Y2Nlc3M7IG90aGVyd2lzZSBmYWxzZS4KKyAqKi8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX09uTW91c2VNb3ZlKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLEZQREZfUEFHRSBwYWdlLCBpbnQgbW9kaWZpZXIsIGRvdWJsZSBwYWdlX3gsIGRvdWJsZSBwYWdlX3kpOworCisvKioKKyAqIEZ1bmN0aW9uOiBGT1JNX09uTEJ1dHRvbkRvd24KKyAqCQkJWW91IGNhbiBjYWxsIHRoaXMgbWVtYmVyIGZ1bmN0aW9uIHdoZW4gdGhlIHVzZXIgcHJlc3NlcyB0aGUgbGVmdCBtb3VzZSBidXR0b24uCisgKiBQYXJhbWV0ZXJzOgorICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyAqCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisgKgkJCW1vZGlmaWVyCQktCUluZGljYXRlcyB3aGV0aGVyIHZhcmlvdXMgdmlydHVhbCBrZXlzIGFyZSBkb3duLiAKKyAqCQkJcGFnZV94CQktCVNwZWNpZmllcyB0aGUgeC1jb29yZGluYXRlIG9mIHRoZSBjdXJzb3IgaW4gUERGIHVzZXIgc3BhY2UuIAorICoJCQlwYWdlX3kJCS0JU3BlY2lmaWVzIHRoZSB5LWNvb3JkaW5hdGUgb2YgdGhlIGN1cnNvciBpbiBQREYgdXNlciBzcGFjZS4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJVFJVRSBpbmRpY2F0ZXMgc3VjY2Vzczsgb3RoZXJ3aXNlIGZhbHNlLgorICoqLworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25MQnV0dG9uRG93bihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSxGUERGX1BBR0UgcGFnZSwgaW50IG1vZGlmaWVyLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95KTsKKworLyoqCisgKiBGdW5jdGlvbjogRk9STV9PbkxCdXR0b25VcAorICoJCQlZb3UgY2FuIGNhbGwgdGhpcyBtZW1iZXIgZnVuY3Rpb24gd2hlbiB0aGUgdXNlciByZWxlYXNlcyB0aGUgbGVmdCBtb3VzZSBidXR0b24uCisgKiBQYXJhbWV0ZXJzOgorICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyAqCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisgKgkJCW1vZGlmaWVyCS0JSW5kaWNhdGVzIHdoZXRoZXIgdmFyaW91cyB2aXJ0dWFsIGtleXMgYXJlIGRvd24uIAorICoJCQlwYWdlX3gJCS0JU3BlY2lmaWVzIHRoZSB4LWNvb3JkaW5hdGUgb2YgdGhlIGN1cnNvciBpbiBkZXZpY2UuIAorICoJCQlwYWdlX3kJCS0JU3BlY2lmaWVzIHRoZSB5LWNvb3JkaW5hdGUgb2YgdGhlIGN1cnNvciBpbiBkZXZpY2UuCisgKiBSZXR1cm4gVmFsdWU6CisgKgkJCVRSVUUgaW5kaWNhdGVzIHN1Y2Nlc3M7IG90aGVyd2lzZSBmYWxzZS4KKyAqKi8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX09uTEJ1dHRvblVwKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLEZQREZfUEFHRSBwYWdlLCBpbnQgbW9kaWZpZXIsIGRvdWJsZSBwYWdlX3gsIGRvdWJsZSBwYWdlX3kpOworCisvKioKKyAqIEZ1bmN0aW9uOiBGT1JNX09uS2V5RG93bgorICoJCQlZb3UgY2FuIGNhbGwgdGhpcyBtZW1iZXIgZnVuY3Rpb24gd2hlbiBhIG5vbnN5c3RlbSBrZXkgaXMgcHJlc3NlZC4gCisgKiBQYXJhbWV0ZXJzOgorICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyAqCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisgKgkJCW5LZXlDb2RlCS0JSW5kaWNhdGVzIHdoZXRoZXIgdmFyaW91cyB2aXJ0dWFsIGtleXMgYXJlIGRvd24uIAorICoJCQltb2RpZmllcgktCUNvbnRhaW5zIHRoZSBzY2FuIGNvZGUsIGtleS10cmFuc2l0aW9uIGNvZGUsIHByZXZpb3VzIGtleSBzdGF0ZSwgYW5kIGNvbnRleHQgY29kZS4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJVFJVRSBpbmRpY2F0ZXMgc3VjY2Vzczsgb3RoZXJ3aXNlIGZhbHNlLgorICoqLworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25LZXlEb3duKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLEZQREZfUEFHRSBwYWdlLCBpbnQgbktleUNvZGUsIGludCBtb2RpZmllcik7CisKKy8qKgorICogRnVuY3Rpb246IEZPUk1fT25LZXlVcAorICoJCQlZb3UgY2FuIGNhbGwgdGhpcyBtZW1iZXIgZnVuY3Rpb24gd2hlbiBhIG5vbnN5c3RlbSBrZXkgaXMgcmVsZWFzZWQuIAorICogUGFyYW1ldGVyczoKKyAqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuCisgKgkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorICoJCQluS2V5Q29kZQktCVRoZSB2aXJ0dWFsLWtleSBjb2RlIG9mIHRoZSBnaXZlbiBrZXkuCisgKgkJCW1vZGlmaWVyCS0JQ29udGFpbnMgdGhlIHNjYW4gY29kZSwga2V5LXRyYW5zaXRpb24gY29kZSwgcHJldmlvdXMga2V5IHN0YXRlLCBhbmQgY29udGV4dCBjb2RlLgorICogUmV0dXJuIFZhbHVlOgorICoJCQlUUlVFIGluZGljYXRlcyBzdWNjZXNzOyBvdGhlcndpc2UgZmFsc2UuCisgKiovCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRk9STV9PbktleVVwKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLEZQREZfUEFHRSBwYWdlLCBpbnQgbktleUNvZGUsIGludCBtb2RpZmllcik7CisKKy8qKgorICogRnVuY3Rpb246IEZPUk1fT25DaGFyCisgKgkJCVlvdSBjYW4gY2FsbCB0aGlzIG1lbWJlciBmdW5jdGlvbiB3aGVuIGEga2V5c3Ryb2tlIHRyYW5zbGF0ZXMgdG8gYSBub25zeXN0ZW0gY2hhcmFjdGVyLgorICogUGFyYW1ldGVyczoKKyAqCQkJaEhhbmRsZQkJLQlIYW5kbGUgdG8gdGhlIGZvcm0gZmlsbCBtb2R1bGUuIFJldHVybmVkIGJ5IEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQuCisgKgkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorICoJCQluQ2hhcgkJLQlUaGUgY2hhcmFjdGVyIGNvZGUgdmFsdWUgb2YgdGhlIGtleS4gIAorICoJCQltb2RpZmllcgktCUNvbnRhaW5zIHRoZSBzY2FuIGNvZGUsIGtleS10cmFuc2l0aW9uIGNvZGUsIHByZXZpb3VzIGtleSBzdGF0ZSwgYW5kIGNvbnRleHQgY29kZS4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJVFJVRSBpbmRpY2F0ZXMgc3VjY2Vzczsgb3RoZXJ3aXNlIGZhbHNlLgorICoqLworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25DaGFyKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLEZQREZfUEFHRSBwYWdlLCBpbnQgbkNoYXIsIGludCBtb2RpZmllcik7CisKKy8qKgorICogRnVuY3Rpb246IEZPUk1fRm9yY2VUb0tpbGxGb2N1cy4KKyAqCQkJWW91IGNhbiBjYWxsIHRoaXMgbWVtYmVyIGZ1bmN0aW9uIHRvIGZvcmNlIHRvIGtpbGwgdGhlIGZvY3VzIG9mIHRoZSBmb3JtIGZpZWxkIHdoaWNoIGdvdCBmb2N1cy4KKyAqCQkJSXQgd291bGQga2lsbCB0aGUgZm9jdXMgb24gdGhlIGZvcm0gZmllbGQsIHNhdmUgdGhlIHZhbHVlIG9mIGZvcm0gZmllbGQgaWYgaXQncyBjaGFuZ2VkIGJ5IHVzZXIuCisgKiBQYXJhbWV0ZXJzOgorICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJVFJVRSBpbmRpY2F0ZXMgc3VjY2Vzczsgb3RoZXJ3aXNlIGZhbHNlLgorICoqLworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fRm9yY2VUb0tpbGxGb2N1cyhGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSk7CisKKy8vIEZpZWxkIFR5cGVzCisjZGVmaW5lIEZQREZfRk9STUZJRUxEX1VOS05PV04JCTAJCS8vIFVua25vd24uCisjZGVmaW5lIEZQREZfRk9STUZJRUxEX1BVU0hCVVRUT04JMQkJLy8gcHVzaCBidXR0b24gdHlwZS4KKyNkZWZpbmUgRlBERl9GT1JNRklFTERfQ0hFQ0tCT1gJCTIJCS8vIGNoZWNrIGJveCB0eXBlLgorI2RlZmluZSBGUERGX0ZPUk1GSUVMRF9SQURJT0JVVFRPTgkzCQkvLyByYWRpbyBidXR0b24gdHlwZS4KKyNkZWZpbmUgRlBERl9GT1JNRklFTERfQ09NQk9CT1gJCTQJCS8vIGNvbWJvIGJveCB0eXBlLgorI2RlZmluZSBGUERGX0ZPUk1GSUVMRF9MSVNUQk9YCQk1CQkvLyBsaXN0IGJveCB0eXBlLgorI2RlZmluZSBGUERGX0ZPUk1GSUVMRF9URVhURklFTEQJNgkJLy8gdGV4dCBmaWVsZCB0eXBlLgorCisvKioKKyAqIEZ1bmN0aW9uOiBGUERQYWdlX0hhc0Zvcm1GaWVsZEF0UG9pbnQKKyAqCQkJQ2hlY2sgdGhlIGZvcm0gZmlsZWQgcG9zaXRpb24gYnkgcG9pbnQuCisgKiBQYXJhbWV0ZXJzOgorICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyAqCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisgKgkJCXBhZ2VfeAkJLQlYIHBvc2l0aW9uIGluIFBERiAidXNlciBzcGFjZSIuCisgKgkJCXBhZ2VfeQkJLQlZIHBvc2l0aW9uIGluIFBERiAidXNlciBzcGFjZSIuCisgKiBSZXR1cm4gVmFsdWU6CisgKgkJCVJldHVybiB0aGUgdHlwZSBvZiB0aGUgZm9ybWZpbGVkOyAtMSBpbmRpY2F0ZXMgbm8gZmllbGRzLgorICoqLworRExMRVhQT1JUIGludCBTVERDQUxMIEZQRFBhZ2VfSGFzRm9ybUZpZWxkQXRQb2ludChGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSxGUERGX1BBR0UgcGFnZSxkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95KTsKKworLyoqCisgKiBGdW5jdGlvbjogRlBERl9TZXRGb3JtRmllbGRIaWdobGlnaHRDb2xvcgorICoJCQlTZXQgdGhlIGhpZ2hsaWdodCBjb2xvciBvZiBzcGVjaWZpZWQgb3IgYWxsIHRoZSBmb3JtIGZpZWxkcyBpbiB0aGUgZG9jdW1lbnQuCisgKiBQYXJhbWV0ZXJzOgorICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyAqCQkJZG9jCQkJLQlIYW5kbGUgdG8gdGhlIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBmdW5jdGlvbi4KKyAqCQkJZmllbGRUeXBlCS0JQSAzMi1iaXQgaW50ZWdlciBpbmRpY2F0aW5nIHRoZSB0eXBlIG9mIGEgZm9ybSBmaWVsZChkZWZpbmVkIGFib3ZlKS4KKyAqCQkJY29sb3IJCS0JVGhlIGhpZ2hsaWdodCBjb2xvciBvZiB0aGUgZm9ybSBmaWVsZC5Db25zdHJ1Y3RlZCBieSAweHh4cnJnZ2JiLgorICogUmV0dXJuIFZhbHVlOgorICoJCQlOT05FLgorICogQ29tbWVudHM6CisgKgkJCVdoZW4gdGhlIHBhcmFtZXRlciBmaWVsZFR5cGUgaXMgc2V0IHRvIHplcm8sIHRoZSBoaWdobGlnaHQgY29sb3Igd2lsbCBiZSBhcHBsaWVkIHRvIGFsbCB0aGUgZm9ybSBmaWVsZHMgaW4gdGhlIAorICoJCQlkb2N1bWVudC4KKyAqCQkJUGxlYXNlIHJlZnJlc2ggdGhlIGNsaWVudCB3aW5kb3cgdG8gc2hvdyB0aGUgaGlnaGxpZ2h0IGltbWVkaWF0ZWx5IGlmIG5lY2Vzc2FyeS4KKyAqKi8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9TZXRGb3JtRmllbGRIaWdobGlnaHRDb2xvcihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgaW50IGZpZWxkVHlwZSwgdW5zaWduZWQgbG9uZyBjb2xvcik7CisKKy8qKgorICogRnVuY3Rpb246IEZQREZfU2V0Rm9ybUZpZWxkSGlnaGxpZ2h0QWxwaGEKKyAqCQkJU2V0IHRoZSB0cmFuc3BhcmVuY3kgb2YgdGhlIGZvcm0gZmllbGQgaGlnaGxpZ2h0IGNvbG9yIGluIHRoZSBkb2N1bWVudC4KKyAqIFBhcmFtZXRlcnM6CisgKgkJCWhIYW5kbGUJCS0JSGFuZGxlIHRvIHRoZSBmb3JtIGZpbGwgbW9kdWxlLiBSZXR1cm5lZCBieSBGUERGRE9DX0luaXRGb3JtRmlsbEVudmlyb3VtZW50LgorICoJCQlkb2MJCQktCUhhbmRsZSB0byB0aGUgZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLgorICoJCQlhbHBoYQkJLQlUaGUgdHJhbnNwYXJlbmN5IG9mIHRoZSBmb3JtIGZpZWxkIGhpZ2hsaWdodCBjb2xvci4gYmV0d2VlbiAwLTI1NS4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJTk9ORS4KKyAqKi8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9TZXRGb3JtRmllbGRIaWdobGlnaHRBbHBoYShGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgdW5zaWduZWQgY2hhciBhbHBoYSk7CisKKworLyoqCisgKiBGdW5jdGlvbjogRlBERl9SZW1vdmVGb3JtRmllbGRIaWdobGlnaHQKKyAqCQkJUmVtb3ZlIHRoZSBmb3JtIGZpZWxkIGhpZ2hsaWdodCBjb2xvciBpbiB0aGUgZG9jdW1lbnQuCisgKiBQYXJhbWV0ZXJzOgorICoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJTk9ORS4KKyAqIENvbW1lbnRzOgorICoJCQlQbGVhc2UgcmVmcmVzaCB0aGUgY2xpZW50IHdpbmRvdyB0byByZW1vdmUgdGhlIGhpZ2hsaWdodCBpbW1lZGlhdGVseSBpZiBuZWNlc3NhcnkuCisgKiovCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfUmVtb3ZlRm9ybUZpZWxkSGlnaGxpZ2h0KEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKTsKKworLyoqCisqIEZ1bmN0aW9uOiBGUERGX0ZGTERyYXcKKyoJCQlSZW5kZXIgRm9ybUZlaWxkcyBvbiBhIHBhZ2UgdG8gYSBkZXZpY2UgaW5kZXBlbmRlbnQgYml0bWFwLiAJCQkKKyogUGFyYW1ldGVyczoKKyoJCQloSGFuZGxlCQktCUhhbmRsZSB0byB0aGUgZm9ybSBmaWxsIG1vZHVsZS4gUmV0dXJuZWQgYnkgRlBERkRPQ19Jbml0Rm9ybUZpbGxFbnZpcm91bWVudC4KKyoJCQliaXRtYXAJCS0JSGFuZGxlIHRvIHRoZSBkZXZpY2UgaW5kZXBlbmRlbnQgYml0bWFwIChhcyB0aGUgb3V0cHV0IGJ1ZmZlcikuCisqCQkJCQkJCUJpdG1hcCBoYW5kbGUgY2FuIGJlIGNyZWF0ZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uCisqCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisqCQkJc3RhcnRfeAkJLQlMZWZ0IHBpeGVsIHBvc2l0aW9uIG9mIHRoZSBkaXNwbGF5IGFyZWEgaW4gdGhlIGRldmljZSBjb29yZGluYXRlLgorKgkJCXN0YXJ0X3kJCS0JVG9wIHBpeGVsIHBvc2l0aW9uIG9mIHRoZSBkaXNwbGF5IGFyZWEgaW4gdGhlIGRldmljZSBjb29yZGluYXRlLgorKgkJCXNpemVfeAkJLQlIb3Jpem9udGFsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuCisqCQkJc2l6ZV95CQktCVZlcnRpY2FsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuCisqCQkJcm90YXRlCQktCVBhZ2Ugb3JpZW50YXRpb246IDAgKG5vcm1hbCksIDEgKHJvdGF0ZWQgOTAgZGVncmVlcyBjbG9ja3dpc2UpLAorKgkJCQkJCQkJMiAocm90YXRlZCAxODAgZGVncmVlcyksIDMgKHJvdGF0ZWQgOTAgZGVncmVlcyBjb3VudGVyLWNsb2Nrd2lzZSkuCisqCQkJZmxhZ3MJCS0JMCBmb3Igbm9ybWFsIGRpc3BsYXksIG9yIGNvbWJpbmF0aW9uIG9mIGZsYWdzIGRlZmluZWQgYWJvdmUuIAorKiBSZXR1cm4gVmFsdWU6CisqCQkJTm9uZS4KKyogQ29tbWVudHM6IAorKgkJCVRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIHRvIG9ubHkgcmVuZGVyIGFubm90YXRpb25zIGFuZCBGb3JtRmllbGRzIG9uIHRoZSBwYWdlLiAKKyoJCQlXaXRob3V0IEZQREZfQU5OT1Qgc3BlY2lmaWVkIGZvciBmbGFncywgUmVuZGVyaW5nIGZ1bmN0aW9ucyBzdWNoIGFzIEZQREZfUmVuZGVyUGFnZUJpdG1hcCBvciBGUERGX1JlbmRlclBhZ2VCaXRtYXBfU3RhcnQgd2lsbCBvbmx5IHJlbmRlciBwYWdlIGNvbnRlbnRzKHdpdGhvdXQgYW5ub3RhdGlvbnMpIHRvIGEgYml0bWFwLgorKgkJCUluIG9yZGVyIHRvIGltcGxlbWVudCB0aGUgRm9ybUZpbGwgZnVuY3Rpb25zLEltcGxlbWVudGF0aW9uIHNob3VsZCBjYWxsIHRoaXMgbWV0aG9kIGFmdGVyIHJlbmRlcmluZyBmdW5jdGlvbnMgZmluaXNoIHJlbmRlcmluZyB0aGUgcGFnZSBjb250ZW50cy4KKyoqLworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX0ZGTERyYXcoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsRlBERl9CSVRNQVAgYml0bWFwLCBGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCAKKwkJCQkJCWludCBzaXplX3gsIGludCBzaXplX3ksIGludCByb3RhdGUsIGludCBmbGFncyk7CisKKworCisjaWZkZWYgX19jcGx1c3BsdXMKK307CisjZW5kaWYKKworI2VuZGlmIC8vX0ZQREZPUk1GSUxMX0gKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZvb20uaCBiL2ZwZGZzZGsvaW5jbHVkZS9mcGRmb29tLmgKaW5kZXggNjM4YjAxMi4uZGQxNGI3NCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZvb20uaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnBkZm9vbS5oCkBAIC0xLDYxICsxLDYxIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GUERGT09NX0hfDQotI2RlZmluZSBfRlBERk9PTV9IXw0KLQ0KLSNpZm5kZWYgX0ZQREZWSUVXX0hfDQotI2luY2x1ZGUgImZwZGZ2aWV3LmgiDQotI2VuZGlmDQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotZXh0ZXJuICJDIiB7DQotI2VuZGlmDQotDQotdHlwZWRlZglzdHJ1Y3QgX09PTV9JTkZPDQotew0KLQkvKioNCi0JKiBWZXJzaW9uIG51bWJlciBvZiB0aGUgaW50ZXJmYWNlLiBDdXJyZW50bHkgbXVzdCBiZSAxLg0KLQkqKi8NCi0JaW50IHZlcnNpb247DQotCQ0KLQkvKiogDQotCSogTWV0aG9kOiBGU0RLX09PTV9IYW5kbGVyDQotCSoJCQkgT3V0LU9mLU1lbW9yeSBoYW5kbGluZyBmdW5jdGlvbi4NCi0JKiBJbnRlcmZhY2UgVmVyc2lvbjoNCi0JKgkJCTENCi0JKiBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoNCi0JKgkJCVllcw0KLQkqIFBhcmFtZXRlcnM6DQotCSoJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIGludGVyZmFjZSBzdHJ1Y3R1cmUgaXRzZWxmLg0KLQkqIAlSZXR1cm4gdmFsdWU6DQotCSogCQlOb25lLg0KLQkqICovDQotDQotCXZvaWQoKkZTREtfT09NX0hhbmRsZXIpKF9PT01fSU5GTyogcFRoaXMpOw0KLX1PT01fSU5GTzsNCi0NCi0NCi0vKioNCi0gKiBGdW5jdGlvbjogRlNES19TZXRPT01IYW5kbGVyDQotICoJCQkgU2V0dXAgQSBPdXQtT2YtTWVtb3J5IGhhbmRsZXIgZm9yIGZveGl0IHNkay4gDQotICogUGFyYW1ldGVyczoNCi0gKgkJCW9vbUluZm8JCS0JUG9pbnRlciB0byBhIE9PTV9JTkZPIHN0cnVjdHVyZS4NCi0gKiBSZXR1cm4gVmFsdWU6DQotICoJCQlUUlVFIG1lYW5zIHN1Y2Nlc3NmdWwuIEZBTFNFIG1lYW5zIGZhaWxzLiANCi0gKiovDQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZTREtfU2V0T09NSGFuZGxlcihPT01fSU5GTyogb29tSW5mbyk7DQotDQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfTsNCi0jZW5kaWYNCi0NCi0NCi0NCi0NCi0jZW5kaWYNCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GUERGT09NX0hfCisjZGVmaW5lIF9GUERGT09NX0hfCisKKyNpZm5kZWYgX0ZQREZWSUVXX0hfCisjaW5jbHVkZSAiZnBkZnZpZXcuaCIKKyNlbmRpZgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKK3R5cGVkZWYJc3RydWN0IF9PT01fSU5GTworeworCS8qKgorCSogVmVyc2lvbiBudW1iZXIgb2YgdGhlIGludGVyZmFjZS4gQ3VycmVudGx5IG11c3QgYmUgMS4KKwkqKi8KKwlpbnQgdmVyc2lvbjsKKwkKKwkvKiogCisJKiBNZXRob2Q6IEZTREtfT09NX0hhbmRsZXIKKwkqCQkJIE91dC1PZi1NZW1vcnkgaGFuZGxpbmcgZnVuY3Rpb24uCisJKiBJbnRlcmZhY2UgVmVyc2lvbjoKKwkqCQkJMQorCSogSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6CisJKgkJCVllcworCSogUGFyYW1ldGVyczoKKwkqCQlwVGhpcwkJLQlQb2ludGVyIHRvIHRoZSBpbnRlcmZhY2Ugc3RydWN0dXJlIGl0c2VsZi4KKwkqIAlSZXR1cm4gdmFsdWU6CisJKiAJCU5vbmUuCisJKiAqLworCisJdm9pZCgqRlNES19PT01fSGFuZGxlcikoX09PTV9JTkZPKiBwVGhpcyk7Cit9T09NX0lORk87CisKKworLyoqCisgKiBGdW5jdGlvbjogRlNES19TZXRPT01IYW5kbGVyCisgKgkJCSBTZXR1cCBBIE91dC1PZi1NZW1vcnkgaGFuZGxlciBmb3IgZm94aXQgc2RrLiAKKyAqIFBhcmFtZXRlcnM6CisgKgkJCW9vbUluZm8JCS0JUG9pbnRlciB0byBhIE9PTV9JTkZPIHN0cnVjdHVyZS4KKyAqIFJldHVybiBWYWx1ZToKKyAqCQkJVFJVRSBtZWFucyBzdWNjZXNzZnVsLiBGQUxTRSBtZWFucyBmYWlscy4gCisgKiovCisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGU0RLX1NldE9PTUhhbmRsZXIoT09NX0lORk8qIG9vbUluZm8pOworCisKKyNpZmRlZiBfX2NwbHVzcGx1cworfTsKKyNlbmRpZgorCisKKworCisjZW5kaWYKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmcHBvLmggYi9mcGRmc2RrL2luY2x1ZGUvZnBkZnBwby5oCmluZGV4IDVmNzdiNWIuLjU3ZmQ2MzggMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmcHBvLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZwcG8uaApAQCAtMSwzNCArMSwzNCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfRlBERlBQT19IXw0KLSNkZWZpbmUgX0ZQREZQUE9fSF8NCi0NCi0jaW5jbHVkZSAiZnBkZnZpZXcuaCINCi0NCi0vLyBGdW5jdGlvbjogRlBERl9JbXBvcnRQYWdlcw0KLS8vCQkJSW1wb3J0IHNvbWUgcGFnZXMgdG8gYSBQREYgZG9jdW1lbnQuDQotLy8gUGFyYW1ldGVyczoJDQotLy8JCQlkZXN0X2RvYwktCVRoZSBkZXN0aW5hdGlvbiBkb2N1bWVudCB3aGljaCBhZGQgdGhlIHBhZ2VzLg0KLS8vCQkJc3JjX2RvYwkJLQlBIGRvY3VtZW50IHRvIGJlIGltcG9ydGVkLg0KLS8vCQkJcGFnZXJhbmdlCS0JQSBwYWdlIHJhbmdlIHN0cmluZywgU3VjaCBhcyAiMSwzLDUtNyIuIA0KLS8vCQkJCQkJCUlmIHRoaXMgcGFyYW1ldGVyIGlzIE5VTEwsIGl0IHdvdWxkIGltcG9ydCBhbGwgcGFnZXMgaW4gc3JjX2RvYy4NCi0vLwkJCWluZGV4CQktCVRoZSBwYWdlIGluZGV4IHdhbnRlZCB0byBpbnNlcnQgZnJvbS4JDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVFJVRSBmb3Igc3VjY2VlZCwgRkFMU0UgZm9yIEZhaWxlZC4JDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZfSW1wb3J0UGFnZXMoRlBERl9ET0NVTUVOVCBkZXN0X2RvYyxGUERGX0RPQ1VNRU5UIHNyY19kb2MsIEZQREZfQllURVNUUklORyBwYWdlcmFuZ2UsIGludCBpbmRleCk7DQotDQotDQotLy8gRnVuY3Rpb246IEZQREZfQ29weVZpZXdlclByZWZlcmVuY2VzDQotLy8JCQlDb3B5IHRoZSB2aWV3ZXIgcHJlZmVyZW5jZXMgZnJvbSBvbmUgUERGIGRvY3VtZW50IHRvIGFub3RoZXIuI2VuZGlmDQotLy8gUGFyYW1ldGVyczoJDQotLy8JCQlkZXN0X2RvYwktCUhhbmRsZSB0byBkb2N1bWVudCB0byB3cml0ZSB0aGUgdmlld2VyIHByZWZlcmVuY2VzIHRvLg0KLS8vCQkJc3JjX2RvYwkJLQlIYW5kbGUgdG8gZG9jdW1lbnQgd2l0aCB0aGUgdmlld2VyIHByZWZlcmVuY2VzLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRSVUUgZm9yIHN1Y2Nlc3MsIEZBTFNFIGZvciBmYWlsdXJlLg0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX0NvcHlWaWV3ZXJQcmVmZXJlbmNlcyhGUERGX0RPQ1VNRU5UIGRlc3RfZG9jLCBGUERGX0RPQ1VNRU5UIHNyY19kb2MpOw0KLSNlbmRpZg0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0ZQREZQUE9fSF8KKyNkZWZpbmUgX0ZQREZQUE9fSF8KKworI2luY2x1ZGUgImZwZGZ2aWV3LmgiCisKKy8vIEZ1bmN0aW9uOiBGUERGX0ltcG9ydFBhZ2VzCisvLwkJCUltcG9ydCBzb21lIHBhZ2VzIHRvIGEgUERGIGRvY3VtZW50LgorLy8gUGFyYW1ldGVyczoJCisvLwkJCWRlc3RfZG9jCS0JVGhlIGRlc3RpbmF0aW9uIGRvY3VtZW50IHdoaWNoIGFkZCB0aGUgcGFnZXMuCisvLwkJCXNyY19kb2MJCS0JQSBkb2N1bWVudCB0byBiZSBpbXBvcnRlZC4KKy8vCQkJcGFnZXJhbmdlCS0JQSBwYWdlIHJhbmdlIHN0cmluZywgU3VjaCBhcyAiMSwzLDUtNyIuIAorLy8JCQkJCQkJSWYgdGhpcyBwYXJhbWV0ZXIgaXMgTlVMTCwgaXQgd291bGQgaW1wb3J0IGFsbCBwYWdlcyBpbiBzcmNfZG9jLgorLy8JCQlpbmRleAkJLQlUaGUgcGFnZSBpbmRleCB3YW50ZWQgdG8gaW5zZXJ0IGZyb20uCQorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGZvciBzdWNjZWVkLCBGQUxTRSBmb3IgRmFpbGVkLgkKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX0ltcG9ydFBhZ2VzKEZQREZfRE9DVU1FTlQgZGVzdF9kb2MsRlBERl9ET0NVTUVOVCBzcmNfZG9jLCBGUERGX0JZVEVTVFJJTkcgcGFnZXJhbmdlLCBpbnQgaW5kZXgpOworCisKKy8vIEZ1bmN0aW9uOiBGUERGX0NvcHlWaWV3ZXJQcmVmZXJlbmNlcworLy8JCQlDb3B5IHRoZSB2aWV3ZXIgcHJlZmVyZW5jZXMgZnJvbSBvbmUgUERGIGRvY3VtZW50IHRvIGFub3RoZXIuI2VuZGlmCisvLyBQYXJhbWV0ZXJzOgkKKy8vCQkJZGVzdF9kb2MJLQlIYW5kbGUgdG8gZG9jdW1lbnQgdG8gd3JpdGUgdGhlIHZpZXdlciBwcmVmZXJlbmNlcyB0by4KKy8vCQkJc3JjX2RvYwkJLQlIYW5kbGUgdG8gZG9jdW1lbnQgd2l0aCB0aGUgdmlld2VyIHByZWZlcmVuY2VzLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGZvciBzdWNjZXNzLCBGQUxTRSBmb3IgZmFpbHVyZS4KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX0NvcHlWaWV3ZXJQcmVmZXJlbmNlcyhGUERGX0RPQ1VNRU5UIGRlc3RfZG9jLCBGUERGX0RPQ1VNRU5UIHNyY19kb2MpOworI2VuZGlmCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmc2F2ZS5oIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZzYXZlLmgKaW5kZXggYmUzNDBmNC4uYTY5NDU2MCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZzYXZlLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZzYXZlLmgKQEAgLTEsODEgKzEsODEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZQREZTQVZFX0hfDQotI2RlZmluZSBfRlBERlNBVkVfSF8NCi0NCi0jaW5jbHVkZSAiZnBkZnZpZXcuaCINCi0NCi0jaWZkZWYgX19jcGx1c3BsdXMNCi1leHRlcm4gIkMiIHsNCi0jZW5kaWYNCi0NCi0NCi0vLyBTdHJ1Y3R1cmUgZm9yIGN1c3RvbSBmaWxlIHdyaXRlDQotc3RydWN0IEZQREZfRklMRVdSSVRFew0KLQ0KLQkvLw0KLQkvL1ZlcnNpb24gbnVtYmVyIG9mIHRoZSBpbnRlcmZhY2UuIEN1cnJlbnRseSBtdXN0IGJlIDEuDQotCS8vDQotCWludCB2ZXJzaW9uOw0KLQ0KLQkvLyANCi0JLy8gTWV0aG9kOiBXcml0ZUJsb2NrDQotCS8vCQkJT3V0cHV0IGEgYmxvY2sgb2YgZGF0YSBpbiB5b3VyIGN1c3RvbSB3YXkuDQotCS8vIEludGVyZmFjZSBWZXJzaW9uOg0KLQkvLwkJCTENCi0JLy8gSW1wbGVtZW50YXRpb24gUmVxdWlyZWQ6DQotCS8vCQkJWWVzDQotCS8vIENvbW1lbnRzOg0KLQkvLwkJCUNhbGxlZCBieSBmdW5jdGlvbiBGUERGX1NhdmVEb2N1bWVudA0KLQkvLyBQYXJhbWV0ZXJzOg0KLQkvLwkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIHN0cnVjdHVyZSBpdHNlbGYNCi0JLy8JCQlwRGF0YQkJLQlQb2ludGVyIHRvIGEgYnVmZmVyIHRvIG91dHB1dA0KLQkvLwkJCXNpemUJCS0JVGhlIHNpemUgb2YgdGhlIGJ1ZmZlci4NCi0JLy8gUmV0dXJuIHZhbHVlOg0KLQkvLwkJCVNob3VsZCBiZSBub24temVybyBpZiBzdWNjZXNzZnVsLCB6ZXJvIGZvciBlcnJvci4NCi0JLy8NCi0JaW50CQkoKldyaXRlQmxvY2spKCBGUERGX0ZJTEVXUklURSogcFRoaXMsIGNvbnN0IHZvaWQqIHBEYXRhLCB1bnNpZ25lZCBsb25nIHNpemUpOw0KLQ0KLX07DQotDQotDQotLyoqIEBicmllZiBJbmNyZW1lbnRhbC4gKi8NCi0jZGVmaW5lIEZQREZfSU5DUkVNRU5UQUwJCTENCi0vKiogQGJyaWVmIE5vIEluY3JlbWVudGFsLiAqLw0KLSNkZWZpbmUgRlBERl9OT19JTkNSRU1FTlRBTAkJMg0KLQ0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX1NhdmVBc0NvcHkNCi0vLwkJCVNhdmVzIHRoZSBjb3B5IG9mIHNwZWNpZmllZCBkb2N1bWVudCBpbiBjdXN0b20gd2F5Lg0KLS8vIFBhcmFtZXRlcnM6CQ0KLS8vCQkJZG9jdW1lbnQJCS0JSGFuZGxlIHRvIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBhbmQgRlBERl9DcmVhdGVOZXdEb2N1bWVudC4NCi0vLwkJCXBGaWxlV3JpdGUJCS0JQSBwb2ludGVyIHRvIGEgY3VzdG9tIGZpbGUgd3JpdGUgc3RydWN0dXJlLg0KLS8vCQkJZmxhZ3MJCQktCVRoZSBjcmVhdGluZyBmbGFncy4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUUlVFIGZvciBzdWNjZWVkLCBGQUxTRSBmb3IgZmFpbGVkLg0KLS8vDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZfU2F2ZUFzQ29weSgJRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGUsDQotCQkJCQkJCQkJCQkJRlBERl9EV09SRCBmbGFncyApOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX1NhdmVXaXRoVmVyc2lvbg0KLS8vCQkJU2FtZSBhcyBmdW5jdGlvbiA6OkZQREZfU2F2ZUFzQ29weSwgZXhjZXB0IHRoZSBmaWxlIHZlcnNpb24gb2YgdGhlIHNhdmVkIGRvY3VtZW50IGNvdWxkIGJlIHNwZWNpZmllZCBieSB1c2VyLg0KLS8vIFBhcmFtZXRlcnM6CQ0KLS8vCQkJZG9jdW1lbnQJCS0JSGFuZGxlIHRvIGRvY3VtZW50Lg0KLS8vCQkJcEZpbGVXcml0ZQkJLQlBIHBvaW50ZXIgdG8gYSBjdXN0b20gZmlsZSB3cml0ZSBzdHJ1Y3R1cmUuDQotLy8JCQlmbGFncwkJCS0JVGhlIGNyZWF0aW5nIGZsYWdzLg0KLS8vCQkJZmlsZVZlcnNpb24JCS0JVGhlIFBERiBmaWxlIHZlcnNpb24uIEZpbGUgdmVyc2lvbjogMTQgZm9yIDEuNCwgMTUgZm9yIDEuNSwgLi4uDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVFJVRSBpZiBzdWNjZWVkLCBGQUxTRSBpZiBmYWlsZWQuDQotLy8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERl9TYXZlV2l0aFZlcnNpb24oRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGUsDQotCUZQREZfRFdPUkQgZmxhZ3MsIGludCBmaWxlVmVyc2lvbik7DQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfTsNCi0jZW5kaWYNCi0NCi0jZW5kaWYgLy9fRlBERlNBVkVfSF8NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GUERGU0FWRV9IXworI2RlZmluZSBfRlBERlNBVkVfSF8KKworI2luY2x1ZGUgImZwZGZ2aWV3LmgiCisKKyNpZmRlZiBfX2NwbHVzcGx1cworZXh0ZXJuICJDIiB7CisjZW5kaWYKKworCisvLyBTdHJ1Y3R1cmUgZm9yIGN1c3RvbSBmaWxlIHdyaXRlCitzdHJ1Y3QgRlBERl9GSUxFV1JJVEV7CisKKwkvLworCS8vVmVyc2lvbiBudW1iZXIgb2YgdGhlIGludGVyZmFjZS4gQ3VycmVudGx5IG11c3QgYmUgMS4KKwkvLworCWludCB2ZXJzaW9uOworCisJLy8gCisJLy8gTWV0aG9kOiBXcml0ZUJsb2NrCisJLy8JCQlPdXRwdXQgYSBibG9jayBvZiBkYXRhIGluIHlvdXIgY3VzdG9tIHdheS4KKwkvLyBJbnRlcmZhY2UgVmVyc2lvbjoKKwkvLwkJCTEKKwkvLyBJbXBsZW1lbnRhdGlvbiBSZXF1aXJlZDoKKwkvLwkJCVllcworCS8vIENvbW1lbnRzOgorCS8vCQkJQ2FsbGVkIGJ5IGZ1bmN0aW9uIEZQREZfU2F2ZURvY3VtZW50CisJLy8gUGFyYW1ldGVyczoKKwkvLwkJCXBUaGlzCQktCVBvaW50ZXIgdG8gdGhlIHN0cnVjdHVyZSBpdHNlbGYKKwkvLwkJCXBEYXRhCQktCVBvaW50ZXIgdG8gYSBidWZmZXIgdG8gb3V0cHV0CisJLy8JCQlzaXplCQktCVRoZSBzaXplIG9mIHRoZSBidWZmZXIuCisJLy8gUmV0dXJuIHZhbHVlOgorCS8vCQkJU2hvdWxkIGJlIG5vbi16ZXJvIGlmIHN1Y2Nlc3NmdWwsIHplcm8gZm9yIGVycm9yLgorCS8vCisJaW50CQkoKldyaXRlQmxvY2spKCBGUERGX0ZJTEVXUklURSogcFRoaXMsIGNvbnN0IHZvaWQqIHBEYXRhLCB1bnNpZ25lZCBsb25nIHNpemUpOworCit9OworCisKKy8qKiBAYnJpZWYgSW5jcmVtZW50YWwuICovCisjZGVmaW5lIEZQREZfSU5DUkVNRU5UQUwJCTEKKy8qKiBAYnJpZWYgTm8gSW5jcmVtZW50YWwuICovCisjZGVmaW5lIEZQREZfTk9fSU5DUkVNRU5UQUwJCTIKKworCisvLyBGdW5jdGlvbjogRlBERl9TYXZlQXNDb3B5CisvLwkJCVNhdmVzIHRoZSBjb3B5IG9mIHNwZWNpZmllZCBkb2N1bWVudCBpbiBjdXN0b20gd2F5LgorLy8gUGFyYW1ldGVyczoJCisvLwkJCWRvY3VtZW50CQktCUhhbmRsZSB0byBkb2N1bWVudC4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkRG9jdW1lbnQgYW5kIEZQREZfQ3JlYXRlTmV3RG9jdW1lbnQuCisvLwkJCXBGaWxlV3JpdGUJCS0JQSBwb2ludGVyIHRvIGEgY3VzdG9tIGZpbGUgd3JpdGUgc3RydWN0dXJlLgorLy8JCQlmbGFncwkJCS0JVGhlIGNyZWF0aW5nIGZsYWdzLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGZvciBzdWNjZWVkLCBGQUxTRSBmb3IgZmFpbGVkLgorLy8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX1NhdmVBc0NvcHkoCUZQREZfRE9DVU1FTlQgZG9jdW1lbnQsRlBERl9GSUxFV1JJVEUgKiBwRmlsZVdyaXRlLAorCQkJCQkJCQkJCQkJRlBERl9EV09SRCBmbGFncyApOworCisvLyBGdW5jdGlvbjogRlBERl9TYXZlV2l0aFZlcnNpb24KKy8vCQkJU2FtZSBhcyBmdW5jdGlvbiA6OkZQREZfU2F2ZUFzQ29weSwgZXhjZXB0IHRoZSBmaWxlIHZlcnNpb24gb2YgdGhlIHNhdmVkIGRvY3VtZW50IGNvdWxkIGJlIHNwZWNpZmllZCBieSB1c2VyLgorLy8gUGFyYW1ldGVyczoJCisvLwkJCWRvY3VtZW50CQktCUhhbmRsZSB0byBkb2N1bWVudC4KKy8vCQkJcEZpbGVXcml0ZQkJLQlBIHBvaW50ZXIgdG8gYSBjdXN0b20gZmlsZSB3cml0ZSBzdHJ1Y3R1cmUuCisvLwkJCWZsYWdzCQkJLQlUaGUgY3JlYXRpbmcgZmxhZ3MuCisvLwkJCWZpbGVWZXJzaW9uCQktCVRoZSBQREYgZmlsZSB2ZXJzaW9uLiBGaWxlIHZlcnNpb246IDE0IGZvciAxLjQsIDE1IGZvciAxLjUsIC4uLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGlmIHN1Y2NlZWQsIEZBTFNFIGlmIGZhaWxlZC4KKy8vCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERl9TYXZlV2l0aFZlcnNpb24oRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGUsCisJRlBERl9EV09SRCBmbGFncywgaW50IGZpbGVWZXJzaW9uKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9OworI2VuZGlmCisKKyNlbmRpZiAvL19GUERGU0FWRV9IXwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZ0ZXh0LmggYi9mcGRmc2RrL2luY2x1ZGUvZnBkZnRleHQuaAppbmRleCBmODYyZGI0Li44Yjg5Nzc5IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnBkZnRleHQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnBkZnRleHQuaApAQCAtMSwzMTYgKzEsMzE2IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GUERGVEVYVF9IXw0KLSNkZWZpbmUgX0ZQREZURVhUX0hfDQotDQotI2luY2x1ZGUgImZwZGZ2aWV3LmgiDQotDQotLy8gRXhwb3J0ZWQgRnVuY3Rpb25zDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotZXh0ZXJuICJDIiB7DQotI2VuZGlmDQotDQotLy8gRnVuY3Rpb246IEZQREZUZXh0X0xvYWRQYWdlDQotLy8JCQlQcmVwYXJlIGluZm9ybWF0aW9uIGFib3V0IGFsbCBjaGFyYWN0ZXJzIGluIGEgcGFnZS4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCXBhZ2UJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24gKGluIEZQREZWSUVXIG1vZHVsZSkuCQ0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCUEgaGFuZGxlIHRvIHRoZSB0ZXh0IHBhZ2UgaW5mb3JtYXRpb24gc3RydWN0dXJlLg0KLS8vCQkJTlVMTCBpZiBzb21ldGhpbmcgZ29lcyB3cm9uZy4NCi0vLyBDb21tZW50czoNCi0vLwkJCUFwcGxpY2F0aW9uIG11c3QgY2FsbCBGUERGVGV4dF9DbG9zZVBhZ2UgdG8gcmVsZWFzZSB0aGUgdGV4dCBwYWdlIGluZm9ybWF0aW9uLg0KLS8vCQkJSWYgeW91IGRvbid0IHB1cmNoYXNlIFRleHQgTW9kdWxlICwgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiBOVUxMLg0KLS8vCQ0KLURMTEVYUE9SVCBGUERGX1RFWFRQQUdFCVNURENBTEwgRlBERlRleHRfTG9hZFBhZ2UoRlBERl9QQUdFIHBhZ2UpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGVGV4dF9DbG9zZVBhZ2UNCi0vLwkJCVJlbGVhc2UgYWxsIHJlc291cmNlcyBhbGxvY2F0ZWQgZm9yIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vIFJldHVybiBWYWx1ZToNCi0vLwkJCU5vbmUuDQotLy8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0Nsb3NlUGFnZShGUERGX1RFWFRQQUdFIHRleHRfcGFnZSk7DQotCQ0KLS8vIEZ1bmN0aW9uOiBGUERGVGV4dF9Db3VudENoYXJzDQotLy8JCQlHZXQgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gYSBwYWdlLg0KLS8vIFBhcmFtZXRlcnM6IA0KLS8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJTnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gdGhlIHBhZ2UuIFJldHVybiAtMSBmb3IgZXJyb3IuIA0KLS8vCQkJR2VuZXJhdGVkIGNoYXJhY3RlcnMsIGxpa2UgYWRkaXRpb25hbCBzcGFjZSBjaGFyYWN0ZXJzLCBuZXcgbGluZSBjaGFyYWN0ZXJzLCBhcmUgYWxzbyBjb3VudGVkLg0KLS8vIENvbW1lbnRzOg0KLS8vCQkJQ2hhcmFjdGVycyBpbiBhIHBhZ2UgZm9ybSBhICJzdHJlYW0iLCBpbnNpZGUgdGhlIHN0cmVhbSwgZWFjaCBjaGFyYWN0ZXIgaGFzIGFuIGluZGV4Lg0KLS8vCQkJV2Ugd2lsbCB1c2UgdGhlIGluZGV4IHBhcmFtZXRlcnMgaW4gbWFueSBvZiBGUERGVEVYVCBmdW5jdGlvbnMuIFRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlIHBhZ2UNCi0vLwkJCWhhcyBhbiBpbmRleCB2YWx1ZSBvZiB6ZXJvLg0KLS8vDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0NvdW50Q2hhcnMoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGVGV4dF9HZXRVbmljb2RlDQotLy8JCQlHZXQgVW5pY29kZSBvZiBhIGNoYXJhY3RlciBpbiBhIHBhZ2UuDQotLy8gUGFyYW1ldGVyczogDQotLy8JCQl0ZXh0X3BhZ2UJLQlIYW5kbGUgdG8gYSB0ZXh0IHBhZ2UgaW5mb3JtYXRpb24gc3RydWN0dXJlLiBSZXR1cm5lZCBieSBGUERGVGV4dF9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0vLwkJCWluZGV4CQktCVplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGNoYXJhY3Rlci4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUaGUgVW5pY29kZSBvZiB0aGUgcGFydGljdWxhciBjaGFyYWN0ZXIuDQotLy8JCQlJZiBhIGNoYXJhY3RlciBpcyBub3QgZW5jb2RlZCBpbiBVbmljb2RlIGFuZCBGb3hpdCBlbmdpbmUgY2FuJ3QgY29udmVydCB0byBVbmljb2RlLA0KLS8vCQkJdGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIHplcm8uDQotLy8NCi1ETExFWFBPUlQgdW5zaWduZWQgaW50IFNURENBTEwgRlBERlRleHRfR2V0VW5pY29kZShGUERGX1RFWFRQQUdFIHRleHRfcGFnZSwgaW50IGluZGV4KTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlRleHRfR2V0Rm9udFNpemUNCi0vLwkJCUdldCB0aGUgZm9udCBzaXplIG9mIGEgcGFydGljdWxhciBjaGFyYWN0ZXIuDQotLy8gUGFyYW1ldGVyczogDQotLy8JCQl0ZXh0X3BhZ2UJLQlIYW5kbGUgdG8gYSB0ZXh0IHBhZ2UgaW5mb3JtYXRpb24gc3RydWN0dXJlLiBSZXR1cm5lZCBieSBGUERGVGV4dF9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0vLwkJCWluZGV4CQktCVplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGNoYXJhY3Rlci4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUaGUgZm9udCBzaXplIG9mIHRoZSBwYXJ0aWN1bGFyIGNoYXJhY3RlciwgbWVhc3VyZWQgaW4gcG9pbnRzIChhYm91dCAxLzcyIGluY2gpLg0KLS8vCQkJVGhpcyBpcyB0aGUgdHlwb2dyYXBoaWMgc2l6ZSBvZiB0aGUgZm9udCAoc28gY2FsbGVkICJlbSBzaXplIikuDQotLy8NCi1ETExFWFBPUlQgZG91YmxlIFNURENBTEwgRlBERlRleHRfR2V0Rm9udFNpemUoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCBpbmRleCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldENoYXJCb3gNCi0vLwkJCUdldCBib3VuZGluZyBib3ggb2YgYSBwYXJ0aWN1bGFyIGNoYXJhY3Rlci4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vCQkJaW5kZXgJCS0JWmVyby1iYXNlZCBpbmRleCBvZiB0aGUgY2hhcmFjdGVyLg0KLS8vCQkJbGVmdAkJLQlQb2ludGVyIHRvIGEgZG91YmxlIG51bWJlciByZWNlaXZpbmcgbGVmdCBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGJveC4NCi0vLwkJCXJpZ2h0CQktCVBvaW50ZXIgdG8gYSBkb3VibGUgbnVtYmVyIHJlY2VpdmluZyByaWdodCBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGJveC4NCi0vLwkJCWJvdHRvbQkJLQlQb2ludGVyIHRvIGEgZG91YmxlIG51bWJlciByZWNlaXZpbmcgYm90dG9tIHBvc2l0aW9uIG9mIHRoZSBjaGFyYWN0ZXIgYm94Lg0KLS8vCQkJdG9wCQkJLQlQb2ludGVyIHRvIGEgZG91YmxlIG51bWJlciByZWNlaXZpbmcgdG9wIHBvc2l0aW9uIG9mIHRoZSBjaGFyYWN0ZXIgYm94Lg0KLS8vIFJldHVybiBWYWx1ZToNCi0vLwkJCU5vbmUuDQotLy8gQ29tbWVudHM6DQotLy8JCQlBbGwgcG9zaXRpb25zIGFyZSBtZWFzdXJlZCBpbiBQREYgInVzZXIgc3BhY2UiLg0KLS8vDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGVGV4dF9HZXRDaGFyQm94KEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLCBpbnQgaW5kZXgsIGRvdWJsZSogbGVmdCwNCi0JCQkJCQkJCQkJCQkJZG91YmxlKiByaWdodCwgZG91YmxlKiBib3R0b20sIGRvdWJsZSogdG9wKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlRleHRfR2V0Q2hhckluZGV4QXRQb3MNCi0vLwkJCUdldCB0aGUgaW5kZXggb2YgYSBjaGFyYWN0ZXIgYXQgb3IgbmVhcmJ5IGEgY2VydGFpbiBwb3NpdGlvbiBvbiB0aGUgcGFnZS4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uDQotLy8JCQl4CQkJLQlYIHBvc2l0aW9uIGluIFBERiAidXNlciBzcGFjZSIuDQotLy8JCQl5CQkJLQlZIHBvc2l0aW9uIGluIFBERiAidXNlciBzcGFjZSIuDQotLy8JCQl4VG9sZXJhbmNlCS0JQW4geC1heGlzIHRvbGVyYW5jZSB2YWx1ZSBmb3IgY2hhcmFjdGVyIGhpdCBkZXRlY3Rpb24sIGluIHBvaW50IHVuaXQuDQotLy8JCQl5VG9sZXJhbmNlCS0JQSB5LWF4aXMgdG9sZXJhbmNlIHZhbHVlIGZvciBjaGFyYWN0ZXIgaGl0IGRldGVjdGlvbiwgaW4gcG9pbnQgdW5pdC4NCi0vLyBSZXR1cm4gVmFsdWU6DQotLy8JCQlUaGUgemVyby1iYXNlZCBpbmRleCBvZiB0aGUgY2hhcmFjdGVyIGF0LCBvciBuZWFyYnkgdGhlIHBvaW50ICh4LHkpLg0KLS8vCQkJSWYgdGhlcmUgaXMgbm8gY2hhcmFjdGVyIGF0IG9yIG5lYXJieSB0aGUgcG9pbnQsIHJldHVybiB2YWx1ZSB3aWxsIGJlIC0xLg0KLS8vCQkJSWYgYW4gZXJyb3Igb2NjdXJzLCAtMyB3aWxsIGJlIHJldHVybmVkLg0KLS8vDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0dldENoYXJJbmRleEF0UG9zKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLA0KLQkJCQkJCQkJCQkJCSBkb3VibGUgeCwgZG91YmxlIHksIGRvdWJsZSB4VG9yZWxhbmNlLCBkb3VibGUgeVRvbGVyYW5jZSk7DQotDQotLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldFRleHQNCi0vLwkJCUV4dHJhY3QgdW5pY29kZSB0ZXh0IHN0cmluZyBmcm9tIHRoZSBwYWdlLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQl0ZXh0X3BhZ2UJLQlIYW5kbGUgdG8gYSB0ZXh0IHBhZ2UgaW5mb3JtYXRpb24gc3RydWN0dXJlLiBSZXR1cm5lZCBieSBGUERGVGV4dF9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0vLwkJCXN0YXJ0X2luZGV4CS0JSW5kZXggZm9yIHRoZSBzdGFydCBjaGFyYWN0ZXJzLg0KLS8vCQkJY291bnQJCS0JTnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gYmUgZXh0cmFjdGVkLg0KLS8vCQkJcmVzdWx0CQktCUEgYnVmZmVyIChhbGxvY2F0ZWQgYnkgYXBwbGljYXRpb24pIHJlY2VpdmluZyB0aGUgZXh0cmFjdGVkIHVuaWNvZGVzLg0KLS8vCQkJCQkJCVRoZSBzaXplIG9mIHRoZSBidWZmZXIgbXVzdCBiZSBhYmxlIHRvIGhvbGQgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHBsdXMgYSB0ZXJtaW5hdG9yLg0KLS8vIFJldHVybiBWYWx1ZToNCi0vLwkJCU51bWJlciBvZiBjaGFyYWN0ZXJzIHdyaXR0ZW4gaW50byB0aGUgcmVzdWx0IGJ1ZmZlciwgaW5jbHVkaW5nIHRoZSB0cmFpbGluZyB0ZXJtaW5hdG9yLg0KLS8vIENvbW1lbnRzOg0KLS8vCQkJVGhpcyBmdW5jdGlvbiBpZ25vcmVzIGNoYXJhY3RlcnMgd2l0aG91dCB1bmljb2RlIGluZm9ybWF0aW9uLg0KLS8vCQkJDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0dldFRleHQoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCBzdGFydF9pbmRleCwgaW50IGNvdW50LCB1bnNpZ25lZCBzaG9ydCogcmVzdWx0KTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlRleHRfQ291bnRSZWN0cw0KLS8vCQkJQ291bnQgbnVtYmVyIG9mIHJlY3Rhbmd1bGFyIGFyZWFzIG9jY3VwaWVkIGJ5IGEgc2VnbWVudCBvZiB0ZXh0cy4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uDQotLy8JCQlzdGFydF9pbmRleAktCUluZGV4IGZvciB0aGUgc3RhcnQgY2hhcmFjdGVycy4NCi0vLwkJCWNvdW50CQktCU51bWJlciBvZiBjaGFyYWN0ZXJzLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCU51bWJlciBvZiByZWN0YW5nbGVzLiBaZXJvIGZvciBlcnJvci4NCi0vLyBDb21tZW50czoNCi0vLwkJCVRoaXMgZnVuY3Rpb24sIGFsb25nIHdpdGggRlBERlRleHRfR2V0UmVjdCBjYW4gYmUgdXNlZCBieSBhcHBsaWNhdGlvbnMgdG8gZGV0ZWN0IHRoZSBwb3NpdGlvbg0KLS8vCQkJb24gdGhlIHBhZ2UgZm9yIGEgdGV4dCBzZWdtZW50LCBzbyBwcm9wZXIgYXJlYXMgY2FuIGJlIGhpZ2hsaWdodGVkIG9yIHNvbWV0aGluZy4NCi0vLwkJCUZQREZURVhUIHdpbGwgYXV0b21hdGljYWxseSBtZXJnZSBzbWFsbCBjaGFyYWN0ZXIgYm94ZXMgaW50byBiaWdnZXIgb25lIGlmIHRob3NlIGNoYXJhY3RlcnMNCi0vLwkJCWFyZSBvbiB0aGUgc2FtZSBsaW5lIGFuZCB1c2Ugc2FtZSBmb250IHNldHRpbmdzLg0KLS8vDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0NvdW50UmVjdHMoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCBzdGFydF9pbmRleCwgaW50IGNvdW50KTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlRleHRfR2V0UmVjdA0KLS8vCQkJR2V0IGEgcmVjdGFuZ3VsYXIgYXJlYSBmcm9tIHRoZSByZXN1bHQgZ2VuZXJhdGVkIGJ5IEZQREZUZXh0X0NvdW50UmVjdHMuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vCQkJcmVjdF9pbmRleAktCVplcm8tYmFzZWQgaW5kZXggZm9yIHRoZSByZWN0YW5nbGUuDQotLy8JCQlsZWZ0CQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSByZWN0YW5nbGUgbGVmdCBib3VuZGFyeS4NCi0vLwkJCXRvcAkJCS0JUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHJlY3RhbmdsZSB0b3AgYm91bmRhcnkuDQotLy8JCQlyaWdodAkJLQlQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgcmVjdGFuZ2xlIHJpZ2h0IGJvdW5kYXJ5Lg0KLS8vCQkJYm90dG9tCQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSByZWN0YW5nbGUgYm90dG9tIGJvdW5kYXJ5Lg0KLS8vIFJldHVybiBWYWx1ZToNCi0vLwkJCU5vbmUuDQotLy8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0dldFJlY3QoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCByZWN0X2luZGV4LCBkb3VibGUqIGxlZnQsIGRvdWJsZSogdG9wLA0KLQkJCQkJCQkJCQkJZG91YmxlKiByaWdodCwgZG91YmxlKiBib3R0b20pOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGVGV4dF9HZXRCb3VuZGVkVGV4dA0KLS8vCQkJRXh0cmFjdCB1bmljb2RlIHRleHQgd2l0aGluIGEgcmVjdGFuZ3VsYXIgYm91bmRhcnkgb24gdGhlIHBhZ2UuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vCQkJbGVmdAkJLQlMZWZ0IGJvdW5kYXJ5Lg0KLS8vCQkJdG9wCQkJLQlUb3AgYm91bmRhcnkuDQotLy8JCQlyaWdodAkJLQlSaWdodCBib3VuZGFyeS4NCi0vLwkJCWJvdHRvbQkJLQlCb3R0b20gYm91bmRhcnkuDQotLy8JCQlidWZmZXIJCS0JQSB1bmljb2RlIGJ1ZmZlci4NCi0vLwkJCWJ1ZmxlbgkJLQlOdW1iZXIgb2YgY2hhcmFjdGVycyAobm90IGJ5dGVzKSBmb3IgdGhlIGJ1ZmZlciwgZXhjbHVkaW5nIGFuIGFkZGl0aW9uYWwgdGVybWluYXRvci4NCi0vLyBSZXR1cm4gVmFsdWU6DQotLy8JCQlJZiBidWZmZXIgaXMgTlVMTCBvciBidWZsZW4gaXMgemVybywgcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXJzIChub3QgYnl0ZXMpIG5lZWRlZCwNCi0vLwkJCW90aGVyd2lzZSwgcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXJzIGNvcGllZCBpbnRvIHRoZSBidWZmZXIuDQotLy8NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0Qm91bmRlZFRleHQoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsZG91YmxlIGxlZnQsIGRvdWJsZSB0b3AsIA0KLQkJCQkJCQkJCQkJICBkb3VibGUgcmlnaHQsIGRvdWJsZSBib3R0b20sdW5zaWduZWQgc2hvcnQqIGJ1ZmZlcixpbnQgYnVmbGVuKTsNCi0NCi0NCi0vLyBGbGFncyB1c2VkIGJ5IEZQREZUZXh0X0ZpbmRTdGFydCBmdW5jdGlvbi4NCi0jZGVmaW5lIEZQREZfTUFUQ0hDQVNFICAgICAgMHgwMDAwMDAwMQkJLy9JZiBub3Qgc2V0LCBpdCB3aWxsIG5vdCBtYXRjaCBjYXNlIGJ5IGRlZmF1bHQuDQotI2RlZmluZSBGUERGX01BVENIV0hPTEVXT1JEIDB4MDAwMDAwMDIJCS8vSWYgbm90IHNldCwgaXQgd2lsbCBub3QgbWF0Y2ggdGhlIHdob2xlIHdvcmQgYnkgZGVmYXVsdC4NCi0NCi0vLyBGdW5jdGlvbjogRlBERlRleHRfRmluZFN0YXJ0DQotLy8JCQlTdGFydCBhIHNlYXJjaC4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uDQotLy8JCQlmaW5kd2hhdAktCUEgdW5pY29kZSBtYXRjaCBwYXR0ZXJuLg0KLS8vCQkJZmxhZ3MJCS0JT3B0aW9uIGZsYWdzLg0KLS8vCQkJc3RhcnRfaW5kZXgJLQlTdGFydCBmcm9tIHRoaXMgY2hhcmFjdGVyLiAtMSBmb3IgZW5kIG9mIHRoZSBwYWdlLg0KLS8vIFJldHVybiBWYWx1ZToNCi0vLwkJCUEgaGFuZGxlIGZvciB0aGUgc2VhcmNoIGNvbnRleHQuIEZQREZUZXh0X0ZpbmRDbG9zZSBtdXN0IGJlIGNhbGxlZCB0byByZWxlYXNlIHRoaXMgaGFuZGxlLg0KLS8vDQotRExMRVhQT1JUIEZQREZfU0NISEFORExFIFNURENBTEwgRlBERlRleHRfRmluZFN0YXJ0KEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLCBGUERGX1dJREVTVFJJTkcgZmluZHdoYXQsDQotCQkJCQkJCQkJCQkJCXVuc2lnbmVkIGxvbmcgZmxhZ3MsIGludCBzdGFydF9pbmRleCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZUZXh0X0ZpbmROZXh0DQotLy8JCQlTZWFyY2ggaW4gdGhlIGRpcmVjdGlvbiBmcm9tIHBhZ2Ugc3RhcnQgdG8gZW5kLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQloYW5kbGUJCS0JQSBzZWFyY2ggY29udGV4dCBoYW5kbGUgcmV0dXJuZWQgYnkgRlBERlRleHRfRmluZFN0YXJ0Lg0KLS8vIFJldHVybiBWYWx1ZToNCi0vLwkJCVdoZXRoZXIgYSBtYXRjaCBpcyBmb3VuZC4NCi0vLw0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGVGV4dF9GaW5kTmV4dChGUERGX1NDSEhBTkRMRSBoYW5kbGUpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGVGV4dF9GaW5kUHJldg0KLS8vCQkJU2VhcmNoIGluIHRoZSBkaXJlY3Rpb24gZnJvbSBwYWdlIGVuZCB0byBzdGFydC4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJaGFuZGxlCQktCUEgc2VhcmNoIGNvbnRleHQgaGFuZGxlIHJldHVybmVkIGJ5IEZQREZUZXh0X0ZpbmRTdGFydC4NCi0vLyBSZXR1cm4gVmFsdWU6DQotLy8JCQlXaGV0aGVyIGEgbWF0Y2ggaXMgZm91bmQuDQotLy8NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlRleHRfRmluZFByZXYoRlBERl9TQ0hIQU5ETEUgaGFuZGxlKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERlRleHRfR2V0U2NoUmVzdWx0SW5kZXgNCi0vLwkJCUdldCB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIGluZGV4IG9mIHRoZSBzZWFyY2ggcmVzdWx0Lg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQloYW5kbGUJCS0JQSBzZWFyY2ggY29udGV4dCBoYW5kbGUgcmV0dXJuZWQgYnkgRlBERlRleHRfRmluZFN0YXJ0Lg0KLS8vIFJldHVybiBWYWx1ZToNCi0vLwkJCUluZGV4IGZvciB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyLg0KLS8vDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0dldFNjaFJlc3VsdEluZGV4KEZQREZfU0NISEFORExFIGhhbmRsZSk7DQotDQotLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldFNjaENvdW50DQotLy8JCQlHZXQgdGhlIG51bWJlciBvZiBtYXRjaGVkIGNoYXJhY3RlcnMgaW4gdGhlIHNlYXJjaCByZXN1bHQuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWhhbmRsZQkJLQlBIHNlYXJjaCBjb250ZXh0IGhhbmRsZSByZXR1cm5lZCBieSBGUERGVGV4dF9GaW5kU3RhcnQuDQotLy8gUmV0dXJuIFZhbHVlOg0KLS8vCQkJTnVtYmVyIG9mIG1hdGNoZWQgY2hhcmFjdGVycy4NCi0vLw0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGVGV4dF9HZXRTY2hDb3VudChGUERGX1NDSEhBTkRMRSBoYW5kbGUpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGVGV4dF9GaW5kQ2xvc2UNCi0vLwkJCVJlbGVhc2UgYSBzZWFyY2ggY29udGV4dC4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJaGFuZGxlCQktCUEgc2VhcmNoIGNvbnRleHQgaGFuZGxlIHJldHVybmVkIGJ5IEZQREZUZXh0X0ZpbmRTdGFydC4NCi0vLyBSZXR1cm4gVmFsdWU6DQotLy8JCQlOb25lLg0KLS8vDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGVGV4dF9GaW5kQ2xvc2UoRlBERl9TQ0hIQU5ETEUgaGFuZGxlKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkxpbmtfTG9hZFdlYkxpbmtzDQotLy8JCQlQcmVwYXJlIGluZm9ybWF0aW9uIGFib3V0IHdlYmxpbmtzIGluIGEgcGFnZS4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uDQotLy8gUmV0dXJuIFZhbHVlOgkNCi0vLwkJCUEgaGFuZGxlIHRvIHRoZSBwYWdlJ3MgbGlua3MgaW5mb3JtYXRpb24gc3RydWN0dXJlLg0KLS8vCQkJTlVMTCBpZiBzb21ldGhpbmcgZ29lcyB3cm9uZy4NCi0vLyBDb21tZW50czoNCi0vLwkJCVdlYmxpbmtzIGFyZSB0aG9zZSBsaW5rcyBpbXBsaWNpdGx5IGVtYmVkZGVkIGluIFBERiBwYWdlcy4gUERGIGFsc28gaGFzIGEgdHlwZSBvZg0KLS8vCQkJYW5ub3RhdGlvbiBjYWxsZWQgImxpbmsiLCBGUERGVEVYVCBkb2Vzbid0IGRlYWwgd2l0aCB0aGF0IGtpbmQgb2YgbGluay4NCi0vLwkJCUZQREZURVhUIHdlYmxpbmsgZmVhdHVyZSBpcyB1c2VmdWwgZm9yIGF1dG9tYXRpY2FsbHkgZGV0ZWN0aW5nIGxpbmtzIGluIHRoZSBwYWdlDQotLy8JCQljb250ZW50cy4gRm9yIGV4YW1wbGUsIHRoaW5ncyBsaWtlICJodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tIiB3aWxsIGJlIGRldGVjdGVkLA0KLS8vCQkJc28gYXBwbGljYXRpb25zIGNhbiBhbGxvdyB1c2VyIHRvIGNsaWNrIG9uIHRob3NlIGNoYXJhY3RlcnMgdG8gYWN0aXZhdGUgdGhlIGxpbmssDQotLy8JCQlldmVuIHRoZSBQREYgZG9lc24ndCBjb21lIHdpdGggbGluayBhbm5vdGF0aW9ucy4NCi0vLw0KLS8vCQkJRlBERkxpbmtfQ2xvc2VXZWJMaW5rcyBtdXN0IGJlIGNhbGxlZCB0byByZWxlYXNlIHJlc291cmNlcy4NCi0vLw0KLURMTEVYUE9SVCBGUERGX1BBR0VMSU5LIFNURENBTEwgRlBERkxpbmtfTG9hZFdlYkxpbmtzKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkxpbmtfQ291bnRXZWJMaW5rcw0KLS8vCQkJQ291bnQgbnVtYmVyIG9mIGRldGVjdGVkIHdlYiBsaW5rcy4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJbGlua19wYWdlCS0JSGFuZGxlIHJldHVybmVkIGJ5IEZQREZMaW5rX0xvYWRXZWJMaW5rcy4NCi0vLyBSZXR1cm4gVmFsdWU6DQotLy8JCQlOdW1iZXIgb2YgZGV0ZWN0ZWQgd2ViIGxpbmtzLg0KLS8vDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZMaW5rX0NvdW50V2ViTGlua3MoRlBERl9QQUdFTElOSyBsaW5rX3BhZ2UpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGTGlua19HZXRVUkwNCi0vLwkJCUZldGNoIHRoZSBVUkwgaW5mb3JtYXRpb24gZm9yIGEgZGV0ZWN0ZWQgd2ViIGxpbmsuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWxpbmtfcGFnZQktCUhhbmRsZSByZXR1cm5lZCBieSBGUERGTGlua19Mb2FkV2ViTGlua3MuDQotLy8JCQlsaW5rX2luZGV4CS0JWmVyby1iYXNlZCBpbmRleCBmb3IgdGhlIGxpbmsuDQotLy8JCQlidWZmZXIJCS0JQSB1bmljb2RlIGJ1ZmZlci4NCi0vLwkJCWJ1ZmxlbgkJLQlOdW1iZXIgb2YgY2hhcmFjdGVycyAobm90IGJ5dGVzKSBmb3IgdGhlIGJ1ZmZlciwgaW5jbHVkaW5nIGFuIGFkZGl0aW9uYWwgdGVybWluYXRvci4NCi0vLyBSZXR1cm4gVmFsdWU6DQotLy8JCQlJZiBidWZmZXIgaXMgTlVMTCBvciBidWZsZW4gaXMgemVybywgcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXJzIChub3QgYnl0ZXMgYW5kIGFuIGFkZGl0aW9uYWwgdGVybWluYXRvciBpcyBhbHNvIGNvdW50ZWQpIG5lZWRlZCwNCi0vLwkJCW90aGVyd2lzZSwgcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXJzIGNvcGllZCBpbnRvIHRoZSBidWZmZXIuDQotLy8NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERkxpbmtfR2V0VVJMKEZQREZfUEFHRUxJTksgbGlua19wYWdlLCBpbnQgbGlua19pbmRleCwgdW5zaWduZWQgc2hvcnQqIGJ1ZmZlcixpbnQgYnVmbGVuKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkxpbmtfQ291bnRSZWN0cw0KLS8vCQkJQ291bnQgbnVtYmVyIG9mIHJlY3Rhbmd1bGFyIGFyZWFzIGZvciB0aGUgbGluay4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJbGlua19wYWdlCS0JSGFuZGxlIHJldHVybmVkIGJ5IEZQREZMaW5rX0xvYWRXZWJMaW5rcy4NCi0vLwkJCWxpbmtfaW5kZXgJLQlaZXJvLWJhc2VkIGluZGV4IGZvciB0aGUgbGluay4NCi0vLyBSZXR1cm4gVmFsdWU6DQotLy8JCQlOdW1iZXIgb2YgcmVjdGFuZ3VsYXIgYXJlYXMgZm9yIHRoZSBsaW5rLg0KLS8vDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZMaW5rX0NvdW50UmVjdHMoRlBERl9QQUdFTElOSyBsaW5rX3BhZ2UsIGludCBsaW5rX2luZGV4KTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkxpbmtfR2V0UmVjdA0KLS8vCQkJRmV0Y2ggdGhlIGJvdW5kYXJpZXMgb2YgYSByZWN0YW5nbGUgZm9yIGEgbGluay4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJbGlua19wYWdlCS0JSGFuZGxlIHJldHVybmVkIGJ5IEZQREZMaW5rX0xvYWRXZWJMaW5rcy4NCi0vLwkJCWxpbmtfaW5kZXgJLQlaZXJvLWJhc2VkIGluZGV4IGZvciB0aGUgbGluay4NCi0vLwkJCXJlY3RfaW5kZXgJLQlaZXJvLWJhc2VkIGluZGV4IGZvciBhIHJlY3RhbmdsZS4NCi0vLwkJCWxlZnQJCS0JUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHJlY3RhbmdsZSBsZWZ0IGJvdW5kYXJ5Lg0KLS8vCQkJdG9wCQkJLQlQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgcmVjdGFuZ2xlIHRvcCBib3VuZGFyeS4NCi0vLwkJCXJpZ2h0CQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSByZWN0YW5nbGUgcmlnaHQgYm91bmRhcnkuDQotLy8JCQlib3R0b20JCS0JUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHJlY3RhbmdsZSBib3R0b20gYm91bmRhcnkuDQotLy8gUmV0dXJuIFZhbHVlOg0KLS8vCQkJTm9uZS4NCi0vLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkxpbmtfR2V0UmVjdChGUERGX1BBR0VMSU5LIGxpbmtfcGFnZSwgaW50IGxpbmtfaW5kZXgsIGludCByZWN0X2luZGV4LCANCi0JCQkJCQkJCQkJZG91YmxlKiBsZWZ0LCBkb3VibGUqIHRvcCxkb3VibGUqIHJpZ2h0LCBkb3VibGUqIGJvdHRvbSk7DQotDQotLy8gRnVuY3Rpb246IEZQREZMaW5rX0Nsb3NlV2ViTGlua3MNCi0vLwkJCVJlbGVhc2UgcmVzb3VyY2VzIHVzZWQgYnkgd2VibGluayBmZWF0dXJlLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQlsaW5rX3BhZ2UJLQlIYW5kbGUgcmV0dXJuZWQgYnkgRlBERkxpbmtfTG9hZFdlYkxpbmtzLg0KLS8vIFJldHVybiBWYWx1ZToNCi0vLwkJCU5vbmUuDQotLy8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZMaW5rX0Nsb3NlV2ViTGlua3MoRlBERl9QQUdFTElOSyBsaW5rX3BhZ2UpOw0KLQ0KLQ0KLSNpZmRlZiBfX2NwbHVzcGx1cw0KLX07DQotI2VuZGlmDQotDQotI2VuZGlmLy9fRlBERlRFWFRfSF8NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GUERGVEVYVF9IXworI2RlZmluZSBfRlBERlRFWFRfSF8KKworI2luY2x1ZGUgImZwZGZ2aWV3LmgiCisKKy8vIEV4cG9ydGVkIEZ1bmN0aW9ucworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvLyBGdW5jdGlvbjogRlBERlRleHRfTG9hZFBhZ2UKKy8vCQkJUHJlcGFyZSBpbmZvcm1hdGlvbiBhYm91dCBhbGwgY2hhcmFjdGVycyBpbiBhIHBhZ2UuCisvLyBQYXJhbWV0ZXJzOiAKKy8vCQkJcGFnZQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbiAoaW4gRlBERlZJRVcgbW9kdWxlKS4JCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCUEgaGFuZGxlIHRvIHRoZSB0ZXh0IHBhZ2UgaW5mb3JtYXRpb24gc3RydWN0dXJlLgorLy8JCQlOVUxMIGlmIHNvbWV0aGluZyBnb2VzIHdyb25nLgorLy8gQ29tbWVudHM6CisvLwkJCUFwcGxpY2F0aW9uIG11c3QgY2FsbCBGUERGVGV4dF9DbG9zZVBhZ2UgdG8gcmVsZWFzZSB0aGUgdGV4dCBwYWdlIGluZm9ybWF0aW9uLgorLy8JCQlJZiB5b3UgZG9uJ3QgcHVyY2hhc2UgVGV4dCBNb2R1bGUgLCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIE5VTEwuCisvLwkKK0RMTEVYUE9SVCBGUERGX1RFWFRQQUdFCVNURENBTEwgRlBERlRleHRfTG9hZFBhZ2UoRlBERl9QQUdFIHBhZ2UpOworCisvLyBGdW5jdGlvbjogRlBERlRleHRfQ2xvc2VQYWdlCisvLwkJCVJlbGVhc2UgYWxsIHJlc291cmNlcyBhbGxvY2F0ZWQgZm9yIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4KKy8vIFBhcmFtZXRlcnM6IAorLy8JCQl0ZXh0X3BhZ2UJLQlIYW5kbGUgdG8gYSB0ZXh0IHBhZ2UgaW5mb3JtYXRpb24gc3RydWN0dXJlLiBSZXR1cm5lZCBieSBGUERGVGV4dF9Mb2FkUGFnZSBmdW5jdGlvbi4KKy8vIFJldHVybiBWYWx1ZToKKy8vCQkJTm9uZS4KKy8vCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0Nsb3NlUGFnZShGUERGX1RFWFRQQUdFIHRleHRfcGFnZSk7CisJCisvLyBGdW5jdGlvbjogRlBERlRleHRfQ291bnRDaGFycworLy8JCQlHZXQgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gYSBwYWdlLgorLy8gUGFyYW1ldGVyczogCisvLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOdW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgcGFnZS4gUmV0dXJuIC0xIGZvciBlcnJvci4gCisvLwkJCUdlbmVyYXRlZCBjaGFyYWN0ZXJzLCBsaWtlIGFkZGl0aW9uYWwgc3BhY2UgY2hhcmFjdGVycywgbmV3IGxpbmUgY2hhcmFjdGVycywgYXJlIGFsc28gY291bnRlZC4KKy8vIENvbW1lbnRzOgorLy8JCQlDaGFyYWN0ZXJzIGluIGEgcGFnZSBmb3JtIGEgInN0cmVhbSIsIGluc2lkZSB0aGUgc3RyZWFtLCBlYWNoIGNoYXJhY3RlciBoYXMgYW4gaW5kZXguCisvLwkJCVdlIHdpbGwgdXNlIHRoZSBpbmRleCBwYXJhbWV0ZXJzIGluIG1hbnkgb2YgRlBERlRFWFQgZnVuY3Rpb25zLiBUaGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBwYWdlCisvLwkJCWhhcyBhbiBpbmRleCB2YWx1ZSBvZiB6ZXJvLgorLy8KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGVGV4dF9Db3VudENoYXJzKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlKTsKKworLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldFVuaWNvZGUKKy8vCQkJR2V0IFVuaWNvZGUgb2YgYSBjaGFyYWN0ZXIgaW4gYSBwYWdlLgorLy8gUGFyYW1ldGVyczogCisvLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8JCQlpbmRleAkJLQlaZXJvLWJhc2VkIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIuCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRoZSBVbmljb2RlIG9mIHRoZSBwYXJ0aWN1bGFyIGNoYXJhY3Rlci4KKy8vCQkJSWYgYSBjaGFyYWN0ZXIgaXMgbm90IGVuY29kZWQgaW4gVW5pY29kZSBhbmQgRm94aXQgZW5naW5lIGNhbid0IGNvbnZlcnQgdG8gVW5pY29kZSwKKy8vCQkJdGhlIHJldHVybiB2YWx1ZSB3aWxsIGJlIHplcm8uCisvLworRExMRVhQT1JUIHVuc2lnbmVkIGludCBTVERDQUxMIEZQREZUZXh0X0dldFVuaWNvZGUoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCBpbmRleCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGVGV4dF9HZXRGb250U2l6ZQorLy8JCQlHZXQgdGhlIGZvbnQgc2l6ZSBvZiBhIHBhcnRpY3VsYXIgY2hhcmFjdGVyLgorLy8gUGFyYW1ldGVyczogCisvLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8JCQlpbmRleAkJLQlaZXJvLWJhc2VkIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIuCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRoZSBmb250IHNpemUgb2YgdGhlIHBhcnRpY3VsYXIgY2hhcmFjdGVyLCBtZWFzdXJlZCBpbiBwb2ludHMgKGFib3V0IDEvNzIgaW5jaCkuCisvLwkJCVRoaXMgaXMgdGhlIHR5cG9ncmFwaGljIHNpemUgb2YgdGhlIGZvbnQgKHNvIGNhbGxlZCAiZW0gc2l6ZSIpLgorLy8KK0RMTEVYUE9SVCBkb3VibGUgU1REQ0FMTCBGUERGVGV4dF9HZXRGb250U2l6ZShGUERGX1RFWFRQQUdFIHRleHRfcGFnZSwgaW50IGluZGV4KTsKKworLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldENoYXJCb3gKKy8vCQkJR2V0IGJvdW5kaW5nIGJveCBvZiBhIHBhcnRpY3VsYXIgY2hhcmFjdGVyLgorLy8gUGFyYW1ldGVyczogCisvLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8JCQlpbmRleAkJLQlaZXJvLWJhc2VkIGluZGV4IG9mIHRoZSBjaGFyYWN0ZXIuCisvLwkJCWxlZnQJCS0JUG9pbnRlciB0byBhIGRvdWJsZSBudW1iZXIgcmVjZWl2aW5nIGxlZnQgcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciBib3guCisvLwkJCXJpZ2h0CQktCVBvaW50ZXIgdG8gYSBkb3VibGUgbnVtYmVyIHJlY2VpdmluZyByaWdodCBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGJveC4KKy8vCQkJYm90dG9tCQktCVBvaW50ZXIgdG8gYSBkb3VibGUgbnVtYmVyIHJlY2VpdmluZyBib3R0b20gcG9zaXRpb24gb2YgdGhlIGNoYXJhY3RlciBib3guCisvLwkJCXRvcAkJCS0JUG9pbnRlciB0byBhIGRvdWJsZSBudW1iZXIgcmVjZWl2aW5nIHRvcCBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGJveC4KKy8vIFJldHVybiBWYWx1ZToKKy8vCQkJTm9uZS4KKy8vIENvbW1lbnRzOgorLy8JCQlBbGwgcG9zaXRpb25zIGFyZSBtZWFzdXJlZCBpbiBQREYgInVzZXIgc3BhY2UiLgorLy8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlRleHRfR2V0Q2hhckJveChGUERGX1RFWFRQQUdFIHRleHRfcGFnZSwgaW50IGluZGV4LCBkb3VibGUqIGxlZnQsCisJCQkJCQkJCQkJCQkJZG91YmxlKiByaWdodCwgZG91YmxlKiBib3R0b20sIGRvdWJsZSogdG9wKTsKKworLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldENoYXJJbmRleEF0UG9zCisvLwkJCUdldCB0aGUgaW5kZXggb2YgYSBjaGFyYWN0ZXIgYXQgb3IgbmVhcmJ5IGEgY2VydGFpbiBwb3NpdGlvbiBvbiB0aGUgcGFnZS4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8JCQl4CQkJLQlYIHBvc2l0aW9uIGluIFBERiAidXNlciBzcGFjZSIuCisvLwkJCXkJCQktCVkgcG9zaXRpb24gaW4gUERGICJ1c2VyIHNwYWNlIi4KKy8vCQkJeFRvbGVyYW5jZQktCUFuIHgtYXhpcyB0b2xlcmFuY2UgdmFsdWUgZm9yIGNoYXJhY3RlciBoaXQgZGV0ZWN0aW9uLCBpbiBwb2ludCB1bml0LgorLy8JCQl5VG9sZXJhbmNlCS0JQSB5LWF4aXMgdG9sZXJhbmNlIHZhbHVlIGZvciBjaGFyYWN0ZXIgaGl0IGRldGVjdGlvbiwgaW4gcG9pbnQgdW5pdC4KKy8vIFJldHVybiBWYWx1ZToKKy8vCQkJVGhlIHplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGNoYXJhY3RlciBhdCwgb3IgbmVhcmJ5IHRoZSBwb2ludCAoeCx5KS4KKy8vCQkJSWYgdGhlcmUgaXMgbm8gY2hhcmFjdGVyIGF0IG9yIG5lYXJieSB0aGUgcG9pbnQsIHJldHVybiB2YWx1ZSB3aWxsIGJlIC0xLgorLy8JCQlJZiBhbiBlcnJvciBvY2N1cnMsIC0zIHdpbGwgYmUgcmV0dXJuZWQuCisvLworRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0dldENoYXJJbmRleEF0UG9zKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLAorCQkJCQkJCQkJCQkJIGRvdWJsZSB4LCBkb3VibGUgeSwgZG91YmxlIHhUb3JlbGFuY2UsIGRvdWJsZSB5VG9sZXJhbmNlKTsKKworLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldFRleHQKKy8vCQkJRXh0cmFjdCB1bmljb2RlIHRleHQgc3RyaW5nIGZyb20gdGhlIHBhZ2UuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQl0ZXh0X3BhZ2UJLQlIYW5kbGUgdG8gYSB0ZXh0IHBhZ2UgaW5mb3JtYXRpb24gc3RydWN0dXJlLiBSZXR1cm5lZCBieSBGUERGVGV4dF9Mb2FkUGFnZSBmdW5jdGlvbi4KKy8vCQkJc3RhcnRfaW5kZXgJLQlJbmRleCBmb3IgdGhlIHN0YXJ0IGNoYXJhY3RlcnMuCisvLwkJCWNvdW50CQktCU51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIGJlIGV4dHJhY3RlZC4KKy8vCQkJcmVzdWx0CQktCUEgYnVmZmVyIChhbGxvY2F0ZWQgYnkgYXBwbGljYXRpb24pIHJlY2VpdmluZyB0aGUgZXh0cmFjdGVkIHVuaWNvZGVzLgorLy8JCQkJCQkJVGhlIHNpemUgb2YgdGhlIGJ1ZmZlciBtdXN0IGJlIGFibGUgdG8gaG9sZCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgcGx1cyBhIHRlcm1pbmF0b3IuCisvLyBSZXR1cm4gVmFsdWU6CisvLwkJCU51bWJlciBvZiBjaGFyYWN0ZXJzIHdyaXR0ZW4gaW50byB0aGUgcmVzdWx0IGJ1ZmZlciwgaW5jbHVkaW5nIHRoZSB0cmFpbGluZyB0ZXJtaW5hdG9yLgorLy8gQ29tbWVudHM6CisvLwkJCVRoaXMgZnVuY3Rpb24gaWdub3JlcyBjaGFyYWN0ZXJzIHdpdGhvdXQgdW5pY29kZSBpbmZvcm1hdGlvbi4KKy8vCQkJCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0VGV4dChGUERGX1RFWFRQQUdFIHRleHRfcGFnZSwgaW50IHN0YXJ0X2luZGV4LCBpbnQgY291bnQsIHVuc2lnbmVkIHNob3J0KiByZXN1bHQpOworCisvLyBGdW5jdGlvbjogRlBERlRleHRfQ291bnRSZWN0cworLy8JCQlDb3VudCBudW1iZXIgb2YgcmVjdGFuZ3VsYXIgYXJlYXMgb2NjdXBpZWQgYnkgYSBzZWdtZW50IG9mIHRleHRzLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLwkJCXN0YXJ0X2luZGV4CS0JSW5kZXggZm9yIHRoZSBzdGFydCBjaGFyYWN0ZXJzLgorLy8JCQljb3VudAkJLQlOdW1iZXIgb2YgY2hhcmFjdGVycy4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTnVtYmVyIG9mIHJlY3RhbmdsZXMuIFplcm8gZm9yIGVycm9yLgorLy8gQ29tbWVudHM6CisvLwkJCVRoaXMgZnVuY3Rpb24sIGFsb25nIHdpdGggRlBERlRleHRfR2V0UmVjdCBjYW4gYmUgdXNlZCBieSBhcHBsaWNhdGlvbnMgdG8gZGV0ZWN0IHRoZSBwb3NpdGlvbgorLy8JCQlvbiB0aGUgcGFnZSBmb3IgYSB0ZXh0IHNlZ21lbnQsIHNvIHByb3BlciBhcmVhcyBjYW4gYmUgaGlnaGxpZ2h0ZWQgb3Igc29tZXRoaW5nLgorLy8JCQlGUERGVEVYVCB3aWxsIGF1dG9tYXRpY2FsbHkgbWVyZ2Ugc21hbGwgY2hhcmFjdGVyIGJveGVzIGludG8gYmlnZ2VyIG9uZSBpZiB0aG9zZSBjaGFyYWN0ZXJzCisvLwkJCWFyZSBvbiB0aGUgc2FtZSBsaW5lIGFuZCB1c2Ugc2FtZSBmb250IHNldHRpbmdzLgorLy8KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGVGV4dF9Db3VudFJlY3RzKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLCBpbnQgc3RhcnRfaW5kZXgsIGludCBjb3VudCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGVGV4dF9HZXRSZWN0CisvLwkJCUdldCBhIHJlY3Rhbmd1bGFyIGFyZWEgZnJvbSB0aGUgcmVzdWx0IGdlbmVyYXRlZCBieSBGUERGVGV4dF9Db3VudFJlY3RzLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLwkJCXJlY3RfaW5kZXgJLQlaZXJvLWJhc2VkIGluZGV4IGZvciB0aGUgcmVjdGFuZ2xlLgorLy8JCQlsZWZ0CQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSByZWN0YW5nbGUgbGVmdCBib3VuZGFyeS4KKy8vCQkJdG9wCQkJLQlQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgcmVjdGFuZ2xlIHRvcCBib3VuZGFyeS4KKy8vCQkJcmlnaHQJCS0JUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHJlY3RhbmdsZSByaWdodCBib3VuZGFyeS4KKy8vCQkJYm90dG9tCQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSByZWN0YW5nbGUgYm90dG9tIGJvdW5kYXJ5LgorLy8gUmV0dXJuIFZhbHVlOgorLy8JCQlOb25lLgorLy8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlRleHRfR2V0UmVjdChGUERGX1RFWFRQQUdFIHRleHRfcGFnZSwgaW50IHJlY3RfaW5kZXgsIGRvdWJsZSogbGVmdCwgZG91YmxlKiB0b3AsCisJCQkJCQkJCQkJCWRvdWJsZSogcmlnaHQsIGRvdWJsZSogYm90dG9tKTsKKworLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldEJvdW5kZWRUZXh0CisvLwkJCUV4dHJhY3QgdW5pY29kZSB0ZXh0IHdpdGhpbiBhIHJlY3Rhbmd1bGFyIGJvdW5kYXJ5IG9uIHRoZSBwYWdlLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLwkJCWxlZnQJCS0JTGVmdCBib3VuZGFyeS4KKy8vCQkJdG9wCQkJLQlUb3AgYm91bmRhcnkuCisvLwkJCXJpZ2h0CQktCVJpZ2h0IGJvdW5kYXJ5LgorLy8JCQlib3R0b20JCS0JQm90dG9tIGJvdW5kYXJ5LgorLy8JCQlidWZmZXIJCS0JQSB1bmljb2RlIGJ1ZmZlci4KKy8vCQkJYnVmbGVuCQktCU51bWJlciBvZiBjaGFyYWN0ZXJzIChub3QgYnl0ZXMpIGZvciB0aGUgYnVmZmVyLCBleGNsdWRpbmcgYW4gYWRkaXRpb25hbCB0ZXJtaW5hdG9yLgorLy8gUmV0dXJuIFZhbHVlOgorLy8JCQlJZiBidWZmZXIgaXMgTlVMTCBvciBidWZsZW4gaXMgemVybywgcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXJzIChub3QgYnl0ZXMpIG5lZWRlZCwKKy8vCQkJb3RoZXJ3aXNlLCByZXR1cm4gbnVtYmVyIG9mIGNoYXJhY3RlcnMgY29waWVkIGludG8gdGhlIGJ1ZmZlci4KKy8vCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0Qm91bmRlZFRleHQoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsZG91YmxlIGxlZnQsIGRvdWJsZSB0b3AsIAorCQkJCQkJCQkJCQkgIGRvdWJsZSByaWdodCwgZG91YmxlIGJvdHRvbSx1bnNpZ25lZCBzaG9ydCogYnVmZmVyLGludCBidWZsZW4pOworCisKKy8vIEZsYWdzIHVzZWQgYnkgRlBERlRleHRfRmluZFN0YXJ0IGZ1bmN0aW9uLgorI2RlZmluZSBGUERGX01BVENIQ0FTRSAgICAgIDB4MDAwMDAwMDEJCS8vSWYgbm90IHNldCwgaXQgd2lsbCBub3QgbWF0Y2ggY2FzZSBieSBkZWZhdWx0LgorI2RlZmluZSBGUERGX01BVENIV0hPTEVXT1JEIDB4MDAwMDAwMDIJCS8vSWYgbm90IHNldCwgaXQgd2lsbCBub3QgbWF0Y2ggdGhlIHdob2xlIHdvcmQgYnkgZGVmYXVsdC4KKworLy8gRnVuY3Rpb246IEZQREZUZXh0X0ZpbmRTdGFydAorLy8JCQlTdGFydCBhIHNlYXJjaC4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCXRleHRfcGFnZQktCUhhbmRsZSB0byBhIHRleHQgcGFnZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUuIFJldHVybmVkIGJ5IEZQREZUZXh0X0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8JCQlmaW5kd2hhdAktCUEgdW5pY29kZSBtYXRjaCBwYXR0ZXJuLgorLy8JCQlmbGFncwkJLQlPcHRpb24gZmxhZ3MuCisvLwkJCXN0YXJ0X2luZGV4CS0JU3RhcnQgZnJvbSB0aGlzIGNoYXJhY3Rlci4gLTEgZm9yIGVuZCBvZiB0aGUgcGFnZS4KKy8vIFJldHVybiBWYWx1ZToKKy8vCQkJQSBoYW5kbGUgZm9yIHRoZSBzZWFyY2ggY29udGV4dC4gRlBERlRleHRfRmluZENsb3NlIG11c3QgYmUgY2FsbGVkIHRvIHJlbGVhc2UgdGhpcyBoYW5kbGUuCisvLworRExMRVhQT1JUIEZQREZfU0NISEFORExFIFNURENBTEwgRlBERlRleHRfRmluZFN0YXJ0KEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLCBGUERGX1dJREVTVFJJTkcgZmluZHdoYXQsCisJCQkJCQkJCQkJCQkJdW5zaWduZWQgbG9uZyBmbGFncywgaW50IHN0YXJ0X2luZGV4KTsKKworLy8gRnVuY3Rpb246IEZQREZUZXh0X0ZpbmROZXh0CisvLwkJCVNlYXJjaCBpbiB0aGUgZGlyZWN0aW9uIGZyb20gcGFnZSBzdGFydCB0byBlbmQuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQloYW5kbGUJCS0JQSBzZWFyY2ggY29udGV4dCBoYW5kbGUgcmV0dXJuZWQgYnkgRlBERlRleHRfRmluZFN0YXJ0LgorLy8gUmV0dXJuIFZhbHVlOgorLy8JCQlXaGV0aGVyIGEgbWF0Y2ggaXMgZm91bmQuCisvLworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZUZXh0X0ZpbmROZXh0KEZQREZfU0NISEFORExFIGhhbmRsZSk7CisKKy8vIEZ1bmN0aW9uOiBGUERGVGV4dF9GaW5kUHJldgorLy8JCQlTZWFyY2ggaW4gdGhlIGRpcmVjdGlvbiBmcm9tIHBhZ2UgZW5kIHRvIHN0YXJ0LgorLy8gUGFyYW1ldGVyczoKKy8vCQkJaGFuZGxlCQktCUEgc2VhcmNoIGNvbnRleHQgaGFuZGxlIHJldHVybmVkIGJ5IEZQREZUZXh0X0ZpbmRTdGFydC4KKy8vIFJldHVybiBWYWx1ZToKKy8vCQkJV2hldGhlciBhIG1hdGNoIGlzIGZvdW5kLgorLy8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGVGV4dF9GaW5kUHJldihGUERGX1NDSEhBTkRMRSBoYW5kbGUpOworCisvLyBGdW5jdGlvbjogRlBERlRleHRfR2V0U2NoUmVzdWx0SW5kZXgKKy8vCQkJR2V0IHRoZSBzdGFydGluZyBjaGFyYWN0ZXIgaW5kZXggb2YgdGhlIHNlYXJjaCByZXN1bHQuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQloYW5kbGUJCS0JQSBzZWFyY2ggY29udGV4dCBoYW5kbGUgcmV0dXJuZWQgYnkgRlBERlRleHRfRmluZFN0YXJ0LgorLy8gUmV0dXJuIFZhbHVlOgorLy8JCQlJbmRleCBmb3IgdGhlIHN0YXJ0aW5nIGNoYXJhY3Rlci4KKy8vCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0U2NoUmVzdWx0SW5kZXgoRlBERl9TQ0hIQU5ETEUgaGFuZGxlKTsKKworLy8gRnVuY3Rpb246IEZQREZUZXh0X0dldFNjaENvdW50CisvLwkJCUdldCB0aGUgbnVtYmVyIG9mIG1hdGNoZWQgY2hhcmFjdGVycyBpbiB0aGUgc2VhcmNoIHJlc3VsdC4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWhhbmRsZQkJLQlBIHNlYXJjaCBjb250ZXh0IGhhbmRsZSByZXR1cm5lZCBieSBGUERGVGV4dF9GaW5kU3RhcnQuCisvLyBSZXR1cm4gVmFsdWU6CisvLwkJCU51bWJlciBvZiBtYXRjaGVkIGNoYXJhY3RlcnMuCisvLworRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0dldFNjaENvdW50KEZQREZfU0NISEFORExFIGhhbmRsZSk7CisKKy8vIEZ1bmN0aW9uOiBGUERGVGV4dF9GaW5kQ2xvc2UKKy8vCQkJUmVsZWFzZSBhIHNlYXJjaCBjb250ZXh0LgorLy8gUGFyYW1ldGVyczoKKy8vCQkJaGFuZGxlCQktCUEgc2VhcmNoIGNvbnRleHQgaGFuZGxlIHJldHVybmVkIGJ5IEZQREZUZXh0X0ZpbmRTdGFydC4KKy8vIFJldHVybiBWYWx1ZToKKy8vCQkJTm9uZS4KKy8vCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0ZpbmRDbG9zZShGUERGX1NDSEhBTkRMRSBoYW5kbGUpOworCisvLyBGdW5jdGlvbjogRlBERkxpbmtfTG9hZFdlYkxpbmtzCisvLwkJCVByZXBhcmUgaW5mb3JtYXRpb24gYWJvdXQgd2VibGlua3MgaW4gYSBwYWdlLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJdGV4dF9wYWdlCS0JSGFuZGxlIHRvIGEgdGV4dCBwYWdlIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4gUmV0dXJuZWQgYnkgRlBERlRleHRfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLyBSZXR1cm4gVmFsdWU6CQorLy8JCQlBIGhhbmRsZSB0byB0aGUgcGFnZSdzIGxpbmtzIGluZm9ybWF0aW9uIHN0cnVjdHVyZS4KKy8vCQkJTlVMTCBpZiBzb21ldGhpbmcgZ29lcyB3cm9uZy4KKy8vIENvbW1lbnRzOgorLy8JCQlXZWJsaW5rcyBhcmUgdGhvc2UgbGlua3MgaW1wbGljaXRseSBlbWJlZGRlZCBpbiBQREYgcGFnZXMuIFBERiBhbHNvIGhhcyBhIHR5cGUgb2YKKy8vCQkJYW5ub3RhdGlvbiBjYWxsZWQgImxpbmsiLCBGUERGVEVYVCBkb2Vzbid0IGRlYWwgd2l0aCB0aGF0IGtpbmQgb2YgbGluay4KKy8vCQkJRlBERlRFWFQgd2VibGluayBmZWF0dXJlIGlzIHVzZWZ1bCBmb3IgYXV0b21hdGljYWxseSBkZXRlY3RpbmcgbGlua3MgaW4gdGhlIHBhZ2UKKy8vCQkJY29udGVudHMuIEZvciBleGFtcGxlLCB0aGluZ3MgbGlrZSAiaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbSIgd2lsbCBiZSBkZXRlY3RlZCwKKy8vCQkJc28gYXBwbGljYXRpb25zIGNhbiBhbGxvdyB1c2VyIHRvIGNsaWNrIG9uIHRob3NlIGNoYXJhY3RlcnMgdG8gYWN0aXZhdGUgdGhlIGxpbmssCisvLwkJCWV2ZW4gdGhlIFBERiBkb2Vzbid0IGNvbWUgd2l0aCBsaW5rIGFubm90YXRpb25zLgorLy8KKy8vCQkJRlBERkxpbmtfQ2xvc2VXZWJMaW5rcyBtdXN0IGJlIGNhbGxlZCB0byByZWxlYXNlIHJlc291cmNlcy4KKy8vCitETExFWFBPUlQgRlBERl9QQUdFTElOSyBTVERDQUxMIEZQREZMaW5rX0xvYWRXZWJMaW5rcyhGUERGX1RFWFRQQUdFIHRleHRfcGFnZSk7CisKKy8vIEZ1bmN0aW9uOiBGUERGTGlua19Db3VudFdlYkxpbmtzCisvLwkJCUNvdW50IG51bWJlciBvZiBkZXRlY3RlZCB3ZWIgbGlua3MuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlsaW5rX3BhZ2UJLQlIYW5kbGUgcmV0dXJuZWQgYnkgRlBERkxpbmtfTG9hZFdlYkxpbmtzLgorLy8gUmV0dXJuIFZhbHVlOgorLy8JCQlOdW1iZXIgb2YgZGV0ZWN0ZWQgd2ViIGxpbmtzLgorLy8KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGTGlua19Db3VudFdlYkxpbmtzKEZQREZfUEFHRUxJTksgbGlua19wYWdlKTsKKworLy8gRnVuY3Rpb246IEZQREZMaW5rX0dldFVSTAorLy8JCQlGZXRjaCB0aGUgVVJMIGluZm9ybWF0aW9uIGZvciBhIGRldGVjdGVkIHdlYiBsaW5rLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJbGlua19wYWdlCS0JSGFuZGxlIHJldHVybmVkIGJ5IEZQREZMaW5rX0xvYWRXZWJMaW5rcy4KKy8vCQkJbGlua19pbmRleAktCVplcm8tYmFzZWQgaW5kZXggZm9yIHRoZSBsaW5rLgorLy8JCQlidWZmZXIJCS0JQSB1bmljb2RlIGJ1ZmZlci4KKy8vCQkJYnVmbGVuCQktCU51bWJlciBvZiBjaGFyYWN0ZXJzIChub3QgYnl0ZXMpIGZvciB0aGUgYnVmZmVyLCBpbmNsdWRpbmcgYW4gYWRkaXRpb25hbCB0ZXJtaW5hdG9yLgorLy8gUmV0dXJuIFZhbHVlOgorLy8JCQlJZiBidWZmZXIgaXMgTlVMTCBvciBidWZsZW4gaXMgemVybywgcmV0dXJuIG51bWJlciBvZiBjaGFyYWN0ZXJzIChub3QgYnl0ZXMgYW5kIGFuIGFkZGl0aW9uYWwgdGVybWluYXRvciBpcyBhbHNvIGNvdW50ZWQpIG5lZWRlZCwKKy8vCQkJb3RoZXJ3aXNlLCByZXR1cm4gbnVtYmVyIG9mIGNoYXJhY3RlcnMgY29waWVkIGludG8gdGhlIGJ1ZmZlci4KKy8vCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkxpbmtfR2V0VVJMKEZQREZfUEFHRUxJTksgbGlua19wYWdlLCBpbnQgbGlua19pbmRleCwgdW5zaWduZWQgc2hvcnQqIGJ1ZmZlcixpbnQgYnVmbGVuKTsKKworLy8gRnVuY3Rpb246IEZQREZMaW5rX0NvdW50UmVjdHMKKy8vCQkJQ291bnQgbnVtYmVyIG9mIHJlY3Rhbmd1bGFyIGFyZWFzIGZvciB0aGUgbGluay4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWxpbmtfcGFnZQktCUhhbmRsZSByZXR1cm5lZCBieSBGUERGTGlua19Mb2FkV2ViTGlua3MuCisvLwkJCWxpbmtfaW5kZXgJLQlaZXJvLWJhc2VkIGluZGV4IGZvciB0aGUgbGluay4KKy8vIFJldHVybiBWYWx1ZToKKy8vCQkJTnVtYmVyIG9mIHJlY3Rhbmd1bGFyIGFyZWFzIGZvciB0aGUgbGluay4KKy8vCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkxpbmtfQ291bnRSZWN0cyhGUERGX1BBR0VMSU5LIGxpbmtfcGFnZSwgaW50IGxpbmtfaW5kZXgpOworCisvLyBGdW5jdGlvbjogRlBERkxpbmtfR2V0UmVjdAorLy8JCQlGZXRjaCB0aGUgYm91bmRhcmllcyBvZiBhIHJlY3RhbmdsZSBmb3IgYSBsaW5rLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJbGlua19wYWdlCS0JSGFuZGxlIHJldHVybmVkIGJ5IEZQREZMaW5rX0xvYWRXZWJMaW5rcy4KKy8vCQkJbGlua19pbmRleAktCVplcm8tYmFzZWQgaW5kZXggZm9yIHRoZSBsaW5rLgorLy8JCQlyZWN0X2luZGV4CS0JWmVyby1iYXNlZCBpbmRleCBmb3IgYSByZWN0YW5nbGUuCisvLwkJCWxlZnQJCS0JUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHJlY3RhbmdsZSBsZWZ0IGJvdW5kYXJ5LgorLy8JCQl0b3AJCQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSByZWN0YW5nbGUgdG9wIGJvdW5kYXJ5LgorLy8JCQlyaWdodAkJLQlQb2ludGVyIHRvIGEgZG91YmxlIHZhbHVlIHJlY2VpdmluZyB0aGUgcmVjdGFuZ2xlIHJpZ2h0IGJvdW5kYXJ5LgorLy8JCQlib3R0b20JCS0JUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHJlY3RhbmdsZSBib3R0b20gYm91bmRhcnkuCisvLyBSZXR1cm4gVmFsdWU6CisvLwkJCU5vbmUuCisvLworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGTGlua19HZXRSZWN0KEZQREZfUEFHRUxJTksgbGlua19wYWdlLCBpbnQgbGlua19pbmRleCwgaW50IHJlY3RfaW5kZXgsIAorCQkJCQkJCQkJCWRvdWJsZSogbGVmdCwgZG91YmxlKiB0b3AsZG91YmxlKiByaWdodCwgZG91YmxlKiBib3R0b20pOworCisvLyBGdW5jdGlvbjogRlBERkxpbmtfQ2xvc2VXZWJMaW5rcworLy8JCQlSZWxlYXNlIHJlc291cmNlcyB1c2VkIGJ5IHdlYmxpbmsgZmVhdHVyZS4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWxpbmtfcGFnZQktCUhhbmRsZSByZXR1cm5lZCBieSBGUERGTGlua19Mb2FkV2ViTGlua3MuCisvLyBSZXR1cm4gVmFsdWU6CisvLwkJCU5vbmUuCisvLworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGTGlua19DbG9zZVdlYkxpbmtzKEZQREZfUEFHRUxJTksgbGlua19wYWdlKTsKKworCisjaWZkZWYgX19jcGx1c3BsdXMKK307CisjZW5kaWYKKworI2VuZGlmLy9fRlBERlRFWFRfSF8KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mcGRmdmlldy5oIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZ2aWV3LmgKaW5kZXggMTgyZDNjZi4uYTU2Mzc2MiAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZwZGZ2aWV3LmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZwZGZ2aWV3LmgKQEAgLTEsNTc4ICsxLDU3OCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotDQotI2lmbmRlZiBfRlBERlZJRVdfSF8NCi0jZGVmaW5lIF9GUERGVklFV19IXw0KLQ0KLSNpZiBkZWZpbmVkKF9XSU4zMikgJiYgIWRlZmluZWQoX19XSU5ET1dTX18pDQotI2luY2x1ZGUgPHdpbmRvd3MuaD4NCi0jZW5kaWYNCi0NCi0vLyBEYXRhIHR5cGVzDQotdHlwZWRlZiB2b2lkKglGUERGX01PRFVMRU1HUjsNCi0NCi0vLyBQREYgdHlwZXMNCi10eXBlZGVmIHZvaWQqCUZQREZfRE9DVU1FTlQ7CQkNCi10eXBlZGVmIHZvaWQqCUZQREZfUEFHRTsJCQkNCi10eXBlZGVmIHZvaWQqCUZQREZfUEFHRU9CSkVDVDsJLy8gUGFnZSBvYmplY3QodGV4dCwgcGF0aCwgZXRjKQ0KLXR5cGVkZWYgdm9pZCoJRlBERl9QQVRIOw0KLXR5cGVkZWYgdm9pZCoJRlBERl9DTElQUEFUSDsJDQotdHlwZWRlZiB2b2lkKglGUERGX0JJVE1BUDsJDQotdHlwZWRlZiB2b2lkKglGUERGX0ZPTlQ7CQkJDQotDQotdHlwZWRlZiB2b2lkKglGUERGX1RFWFRQQUdFOw0KLXR5cGVkZWYgdm9pZCoJRlBERl9TQ0hIQU5ETEU7DQotdHlwZWRlZiB2b2lkKglGUERGX1BBR0VMSU5LOw0KLXR5cGVkZWYgdm9pZCoJRlBERl9ITU9EVUxFOw0KLXR5cGVkZWYgdm9pZCoJRlBERl9ET0NTQ0hIQU5ETEU7DQotDQotdHlwZWRlZiB2b2lkKglGUERGX0JPT0tNQVJLOw0KLXR5cGVkZWYgdm9pZCoJRlBERl9ERVNUOw0KLXR5cGVkZWYgdm9pZCoJRlBERl9BQ1RJT047DQotdHlwZWRlZiB2b2lkKglGUERGX0xJTks7DQotDQotLy8gQmFzaWMgZGF0YSB0eXBlcw0KLXR5cGVkZWYgaW50CQkJCUZQREZfQk9PTDsNCi10eXBlZGVmIGludAkJCQlGUERGX0VSUk9SOwkNCi10eXBlZGVmIHVuc2lnbmVkIGxvbmcJRlBERl9EV09SRDsNCi0NCi10eXBlZGVmCWZsb2F0CQkJRlNfRkxPQVQ7DQotDQotLy8gU3RyaW5nIHR5cGVzDQotdHlwZWRlZiB1bnNpZ25lZCBzaG9ydAkJCUZQREZfV0NIQVI7DQotdHlwZWRlZiB1bnNpZ25lZCBjaGFyIGNvbnN0KglGUERGX0xQQ0JZVEU7DQotDQotLy8gRlBERlNESyBtYXkgdXNlIHRocmVlIHR5cGVzIG9mIHN0cmluZ3M6IGJ5dGUgc3RyaW5nLCB3aWRlIHN0cmluZyAoVVRGLTE2TEUgZW5jb2RlZCksIGFuZCBwbGF0Zm9ybSBkZXBlbmRlbnQgc3RyaW5nDQotdHlwZWRlZiBjb25zdCBjaGFyKgkJCQlGUERGX0JZVEVTVFJJTkc7DQotDQotdHlwZWRlZiBjb25zdCB1bnNpZ25lZCBzaG9ydCoJRlBERl9XSURFU1RSSU5HOwkJLy8gRm94aXQgUERGIFNESyBhbHdheXMgdXNlIFVURi0xNkxFIGVuY29kaW5nIHdpZGUgc3RyaW5nLA0KLQkJCQkJCQkJCQkJCQkJLy8gZWFjaCBjaGFyYWN0ZXIgdXNlIDIgYnl0ZXMgKGV4Y2VwdCBzdXJyb2dhdGlvbiksIHdpdGggbG93IGJ5dGUgZmlyc3QuDQotDQotLy8gRm9yIFdpbmRvd3MgcHJvZ3JhbW1lcnM6IGZvciBtb3N0IGNhc2UgaXQncyBPSyB0byB0cmVhdCBGUERGX1dJREVTVFJJTkcgYXMgV2luZG93cyB1bmljb2RlIHN0cmluZywNCi0vLwkJIGhvd2V2ZXIsIHNwZWNpYWwgY2FyZSBuZWVkcyB0byBiZSB0YWtlbiBpZiB5b3UgZXhwZWN0IHRvIHByb2Nlc3MgVW5pY29kZSBsYXJnZXIgdGhhbiAweGZmZmYuDQotLy8gRm9yIExpbnV4L1VuaXggcHJvZ3JhbW1lcnM6IG1vc3QgY29tcGlsZXIvbGlicmFyeSBlbnZpcm9ubWVudCB1c2VzIDQgYnl0ZXMgZm9yIGEgVW5pY29kZSBjaGFyYWN0ZXIsDQotLy8JCXlvdSBoYXZlIHRvIGNvbnZlcnQgYmV0d2VlbiBGUERGX1dJREVTVFJJTkcgYW5kIHN5c3RlbSB3aWRlIHN0cmluZyBieSB5b3Vyc2VsZi4NCi0NCi0jaWZkZWYgX1dJTjMyX1dDRQ0KLXR5cGVkZWYgY29uc3QgdW5zaWduZWQgc2hvcnQqIEZQREZfU1RSSU5HOw0KLSNlbHNlDQotdHlwZWRlZiBjb25zdCBjaGFyKiBGUERGX1NUUklORzsNCi0jZW5kaWYNCi0NCi0jaWZuZGVmIF9GU19ERUZfTUFUUklYXw0KLSNkZWZpbmUgX0ZTX0RFRl9NQVRSSVhfDQotLyoqIEBicmllZiBNYXRyaXggZm9yIHRyYW5zZm9ybWF0aW9uLiAqLw0KLXR5cGVkZWYgc3RydWN0IF9GU19NQVRSSVhfDQotew0KLQlmbG9hdAlhOwkvKio8IEBicmllZiBDb2VmZmljaWVudCBhLiovDQotCWZsb2F0CWI7CS8qKjwgQGJyaWVmIENvZWZmaWNpZW50IGIuKi8NCi0JZmxvYXQJYzsJLyoqPCBAYnJpZWYgQ29lZmZpY2llbnQgYy4qLw0KLQlmbG9hdAlkOwkvKio8IEBicmllZiBDb2VmZmljaWVudCBkLiovDQotCWZsb2F0CWU7CS8qKjwgQGJyaWVmIENvZWZmaWNpZW50IGUuKi8NCi0JZmxvYXQJZjsJLyoqPCBAYnJpZWYgQ29lZmZpY2llbnQgZi4qLw0KLX0gRlNfTUFUUklYOw0KLSNlbmRpZg0KLQ0KLSNpZm5kZWYgX0ZTX0RFRl9SRUNURl8NCi0jZGVmaW5lIF9GU19ERUZfUkVDVEZfDQotLyoqIEBicmllZiBSZWN0YW5nbGUgYXJlYShmbG9hdCkgaW4gZGV2aWNlIG9yIHBhZ2UgY29vcmRpbmF0aW9uIHN5c3RlbS4gKi8NCi10eXBlZGVmIHN0cnVjdCBfRlNfUkVDVEZfDQotew0KLQkvKipAeyovDQotCS8qKiBAYnJpZWYgVGhlIHgtY29vcmRpbmF0ZSBvZiB0aGUgbGVmdC10b3AgY29ybmVyLiAqLw0KLQlmbG9hdAlsZWZ0Ow0KLQkvKiogQGJyaWVmIFRoZSB5LWNvb3JkaW5hdGUgb2YgdGhlIGxlZnQtdG9wIGNvcm5lci4gKi8NCi0JZmxvYXQJdG9wOw0KLQkvKiogQGJyaWVmIFRoZSB4LWNvb3JkaW5hdGUgb2YgdGhlIHJpZ2h0LWJvdHRvbSBjb3JuZXIuICovDQotCWZsb2F0CXJpZ2h0Ow0KLQkvKiogQGJyaWVmIFRoZSB5LWNvb3JkaW5hdGUgb2YgdGhlIHJpZ2h0LWJvdHRvbSBjb3JuZXIuICovDQotCWZsb2F0CWJvdHRvbTsNCi0JLyoqQH0qLw0KLX0qIEZTX0xQUkVDVEYsIEZTX1JFQ1RGOw0KLS8qKiBAYnJpZWYgQ29uc3QgUG9pbnRlciB0byA6OkZTX1JFQ1RGIHN0cnVjdHVyZS4qLw0KLXR5cGVkZWYgY29uc3QgRlNfUkVDVEYqCUZTX0xQQ1JFQ1RGOw0KLSNlbmRpZg0KLQ0KLSNpZiBkZWZpbmVkKF9XSU4zMikgJiYgZGVmaW5lZChGUERGU0RLX0VYUE9SVFMpDQotLy8gT24gV2luZG93cyBzeXN0ZW0sIGZ1bmN0aW9ucyBhcmUgZXhwb3J0ZWQgaW4gYSBETEwNCi0jZGVmaW5lIERMTEVYUE9SVCBfX2RlY2xzcGVjKCBkbGxleHBvcnQgKQ0KLSNkZWZpbmUgU1REQ0FMTCBfX3N0ZGNhbGwNCi0jZWxzZQ0KLSNkZWZpbmUgRExMRVhQT1JUDQotI2RlZmluZSBTVERDQUxMDQotI2VuZGlmDQotDQotZXh0ZXJuIGNvbnN0IGNoYXIgZ19FeHBpcmVEYXRlW107DQotZXh0ZXJuIGNvbnN0IGNoYXIgZ19Nb2R1bGVDb2Rlc1tdOw0KLQ0KLS8vIEV4cG9ydGVkIEZ1bmN0aW9ucw0KLSNpZmRlZiBfX2NwbHVzcGx1cw0KLWV4dGVybiAiQyIgew0KLSNlbmRpZg0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX0luaXRMaWJyYXJ5DQotLy8JCQlJbml0aWFsaXplIHRoZSBGUERGU0RLIGxpYnJhcnkgDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWhJbnN0YW5jZQktCUZvciBXSU4zMiBzeXN0ZW0gb25seTogdGhlIGluc3RhbmNlIG9mIHRoZSBleGVjdXRhYmxlIG9yIERMTCBtb2R1bGUuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJTm9uZS4NCi0vLyBDb21tZW50czoNCi0vLwkJCVlvdSBoYXZlIHRvIGNhbGwgdGhpcyBmdW5jdGlvbiBiZWZvcmUgeW91IGNhbiBjYWxsIGFueSBQREYgcHJvY2Vzc2luZyBmdW5jdGlvbnMuDQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX0luaXRMaWJyYXJ5KHZvaWQqIGhJbnN0YW5jZSk7DQotDQotDQotLy8gRnVuY3Rpb246IEZQREZfRGVzdHJveUxpYmFyeQ0KLS8vCQkJUmVsZWFzZSBhbGwgcmVzb3VyY2VzIGFsbG9jYXRlZCBieSB0aGUgRlBERlNESyBsaWJyYXJ5Lg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQlOb25lLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCU5vbmUuDQotLy8gQ29tbWVudHM6DQotLy8JCQlZb3UgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbiB0byByZWxlYXNlIGFsbCBtZW1vcnkgYmxvY2tzIGFsbG9jYXRlZCBieSB0aGUgbGlicmFyeS4gDQotLy8JCQlBZnRlciB0aGlzIGZ1bmN0aW9uIGNhbGxlZCwgeW91IHNob3VsZCBub3QgY2FsbCBhbnkgUERGIHByb2Nlc3NpbmcgZnVuY3Rpb25zLg0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9EZXN0cm95TGlicmFyeSgpOw0KLQ0KLS8vUG9saWN5IGZvciBhY2Nlc3NpbmcgdGhlIGxvY2FsIG1hY2hpbmUgdGltZS4NCi0jZGVmaW5lIEZQREZfUE9MSUNZX01BQ0hJTkVUSU1FX0FDQ0VTUwkwDQotDQotLy8gRnVuY3Rpb246IEZQREZfU2V0U2FuZEJveFBvbGljeQ0KLS8vCQkJU2V0IHRoZSBwb2xpY3kgZm9yIHRoZSBzYW5kYm94IGVudmlyb25tZW50Lg0KLS8vIFBhcmFtZXRlcnM6CQ0KLS8vCQkJcG9saWN5CQktCVRoZSBzcGVjaWZpZWQgcG9saWN5IGZvciBzZXR0aW5nLCBmb3IgZXhhbXBsZTpGUERGX1BPTElDWV9NQUNISU5FVElNRV9BQ0NFU1MuDQotLy8JCQllbmFibGUJCS0JVHJ1ZSBmb3IgZW5hYmxlLCBGYWxzZSBmb3IgZGlzYWJsZSB0aGUgcG9saWN5Lg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCU5vbmUuDQotRExMRVhQT1JUIHZvaWQJU1REQ0FMTCBGUERGX1NldFNhbmRCb3hQb2xpY3koRlBERl9EV09SRCBwb2xpY3ksIEZQREZfQk9PTCBlbmFibGUpOw0KLQ0KLS8qKg0KLSogT3BlbiBhbmQgbG9hZCBhIFBERiBkb2N1bWVudC4NCi0qIEBwYXJhbVtpbl0gZmlsZV9wYXRoCS0JUGF0aCB0byB0aGUgUERGIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pLg0KLSogQHBhcmFtW2luXSBwYXNzd29yZAktCUEgc3RyaW5nIHVzZWQgYXMgdGhlIHBhc3N3b3JkIGZvciBQREYgZmlsZS4gDQotKgkJCQkJCQlJZiBubyBwYXNzd29yZCBuZWVkZWQsIGVtcHR5IG9yIE5VTEwgY2FuIGJlIHVzZWQuDQotKiBAbm90ZQkJTG9hZGVkIGRvY3VtZW50IGNhbiBiZSBjbG9zZWQgYnkgRlBERl9DbG9zZURvY3VtZW50Lg0KLSoJCQlJZiB0aGlzIGZ1bmN0aW9uIGZhaWxzLCB5b3UgY2FuIHVzZSBGUERGX0dldExhc3RFcnJvcigpIHRvIHJldHJpZXZlDQotKgkJCXRoZSByZWFzb24gd2h5IGl0IGZhaWxzLg0KLSogQHJldHZhbAlBIGhhbmRsZSB0byB0aGUgbG9hZGVkIGRvY3VtZW50LiBJZiBmYWlsZWQsIE5VTEwgaXMgcmV0dXJuZWQuDQotKi8NCi1ETExFWFBPUlQgRlBERl9ET0NVTUVOVAlTVERDQUxMIEZQREZfTG9hZERvY3VtZW50KEZQREZfU1RSSU5HIGZpbGVfcGF0aCwgDQotCUZQREZfQllURVNUUklORyBwYXNzd29yZCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZfTG9hZE1lbURvY3VtZW50DQotLy8JCQlPcGVuIGFuZCBsb2FkIGEgUERGIGRvY3VtZW50IGZyb20gbWVtb3J5Lg0KLS8vIFBhcmFtZXRlcnM6IA0KLS8vCQkJZGF0YV9idWYJLQlQb2ludGVyIHRvIGEgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIFBERiBkb2N1bWVudC4NCi0vLwkJCXNpemUJCS0JTnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBQREYgZG9jdW1lbnQuDQotLy8JCQlwYXNzd29yZAktCUEgc3RyaW5nIHVzZWQgYXMgdGhlIHBhc3N3b3JkIGZvciBQREYgZmlsZS4gDQotLy8JCQkJCQkJSWYgbm8gcGFzc3dvcmQgbmVlZGVkLCBlbXB0eSBvciBOVUxMIGNhbiBiZSB1c2VkLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCUEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgZG9jdW1lbnQuIElmIGZhaWxlZCwgTlVMTCBpcyByZXR1cm5lZC4NCi0vLyBDb21tZW50czoNCi0vLwkJCVRoZSBtZW1vcnkgYnVmZmVyIG11c3QgcmVtYWluIHZhbGlkIHdoZW4gdGhlIGRvY3VtZW50IGlzIG9wZW4uDQotLy8JCQlMb2FkZWQgZG9jdW1lbnQgY2FuIGJlIGNsb3NlZCBieSBGUERGX0Nsb3NlRG9jdW1lbnQuDQotLy8JCQlJZiB0aGlzIGZ1bmN0aW9uIGZhaWxzLCB5b3UgY2FuIHVzZSBGUERGX0dldExhc3RFcnJvcigpIHRvIHJldHJpZXZlDQotLy8JCQl0aGUgcmVhc29uIHdoeSBpdCBmYWlscy4NCi0vLw0KLURMTEVYUE9SVCBGUERGX0RPQ1VNRU5UCVNURENBTEwgRlBERl9Mb2FkTWVtRG9jdW1lbnQoY29uc3Qgdm9pZCogZGF0YV9idWYsIA0KLQkJCQkJCQkJCQkJaW50IHNpemUsIEZQREZfQllURVNUUklORyBwYXNzd29yZCk7DQotDQotLy8gU3RydWN0dXJlIGZvciBjdXN0b20gZmlsZSBhY2Nlc3MuDQotdHlwZWRlZiBzdHJ1Y3Qgew0KLQkvLyBGaWxlIGxlbmd0aCwgaW4gYnl0ZXMuDQotCXVuc2lnbmVkIGxvbmcJbV9GaWxlTGVuOw0KLQ0KLQkvLyBBIGZ1bmN0aW9uIHBvaW50ZXIgZm9yIGdldHRpbmcgYSBibG9jayBvZiBkYXRhIGZyb20gc3BlY2lmaWMgcG9zaXRpb24uDQotCS8vIFBvc2l0aW9uIGlzIHNwZWNpZmllZCBieSBieXRlIG9mZnNldCBmcm9tIGJlZ2lubmluZyBvZiB0aGUgZmlsZS4NCi0JLy8gVGhlIHBvc2l0aW9uIGFuZCBzaXplIHdpbGwgbmV2ZXIgZ28gb3V0IHJhbmdlIG9mIGZpbGUgbGVuZ3RoLg0KLQkvLyBJdCBtYXkgYmUgcG9zc2libGUgZm9yIEZQREZTREsgdG8gY2FsbCB0aGlzIGZ1bmN0aW9uIG11bHRpcGxlIHRpbWVzIGZvciBzYW1lIHBvc2l0aW9uLg0KLQkvLyBSZXR1cm4gdmFsdWU6IHNob3VsZCBiZSBub24temVybyBpZiBzdWNjZXNzZnVsLCB6ZXJvIGZvciBlcnJvci4NCi0JaW50CQkJCSgqbV9HZXRCbG9jaykodm9pZCogcGFyYW0sIHVuc2lnbmVkIGxvbmcgcG9zaXRpb24sIHVuc2lnbmVkIGNoYXIqIHBCdWYsIHVuc2lnbmVkIGxvbmcgc2l6ZSk7DQotDQotCS8vIEEgY3VzdG9tIHBvaW50ZXIgZm9yIGFsbCBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyBkYXRhLg0KLQkvLyBUaGlzIHBvaW50ZXIgd2lsbCBiZSB1c2VkIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIgdG8gbV9HZXRCbG9jayBjYWxsYmFjay4NCi0Jdm9pZCoJCQltX1BhcmFtOw0KLX0gRlBERl9GSUxFQUNDRVNTOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX0xvYWRDdXN0b21Eb2N1bWVudA0KLS8vCQkJTG9hZCBQREYgZG9jdW1lbnQgZnJvbSBhIGN1c3RvbSBhY2Nlc3MgZGVzY3JpcHRvci4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJcEZpbGVBY2Nlc3MJLQlBIHN0cnVjdHVyZSBmb3IgYWNjZXNzIHRoZSBmaWxlLg0KLS8vCQkJcGFzc3dvcmQJLQlPcHRpb25hbCBwYXNzd29yZCBmb3IgZGVjcnlwdGluZyB0aGUgUERGIGZpbGUuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJQSBoYW5kbGUgdG8gdGhlIGxvYWRlZCBkb2N1bWVudC4gSWYgZmFpbGVkLCBOVUxMIGlzIHJldHVybmVkLg0KLS8vIENvbW1lbnRzOg0KLS8vCQkJVGhlIGFwcGxpY2F0aW9uIHNob3VsZCBtYWludGFpbiB0aGUgZmlsZSByZXNvdXJjZXMgYmVpbmcgdmFsaWQgdW50aWwgdGhlIFBERiBkb2N1bWVudCBjbG9zZS4NCi0vLwkJCUxvYWRlZCBkb2N1bWVudCBjYW4gYmUgY2xvc2VkIGJ5IEZQREZfQ2xvc2VEb2N1bWVudC4NCi1ETExFWFBPUlQgRlBERl9ET0NVTUVOVCBTVERDQUxMIEZQREZfTG9hZEN1c3RvbURvY3VtZW50KEZQREZfRklMRUFDQ0VTUyogcEZpbGVBY2Nlc3MsIA0KLQkJCQkJCQkJCQkJCQkJRlBERl9CWVRFU1RSSU5HIHBhc3N3b3JkKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERl9HZXRGaWxlVmVyc2lvbg0KLS8vCQkJR2V0IHRoZSBmaWxlIHZlcnNpb24gb2YgdGhlIHNwZWNpZmljIFBERiBkb2N1bWVudC4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJZG9jCQkJLQlIYW5kbGUgdG8gZG9jdW1lbnQuDQotLy8JCQlmaWxlVmVyc2lvbgktCVRoZSBQREYgZmlsZSB2ZXJzaW9uLiBGaWxlIHZlcnNpb246IDE0IGZvciAxLjQsIDE1IGZvciAxLjUsIC4uLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRSVUUgaWYgdGhpcyBjYWxsIHN1Y2NlZWQsIElmIGZhaWxlZCwgRkFMU0UgaXMgcmV0dXJuZWQuDQotLy8gQ29tbWVudHM6DQotLy8JCQlJZiB0aGUgZG9jdW1lbnQgaXMgY3JlYXRlZCBieSBmdW5jdGlvbiA6OkZQREZfQ3JlYXRlTmV3RG9jdW1lbnQsIHRoZW4gdGhpcyBmdW5jdGlvbiB3b3VsZCBhbHdheXMgZmFpbC4NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERl9HZXRGaWxlVmVyc2lvbihGUERGX0RPQ1VNRU5UIGRvYywgaW50KiBmaWxlVmVyc2lvbik7DQotDQotI2RlZmluZSBGUERGX0VSUl9TVUNDRVNTCQkwCQkvLyBObyBlcnJvci4NCi0jZGVmaW5lIEZQREZfRVJSX1VOS05PV04JCTEJCS8vIFVua25vd24gZXJyb3IuDQotI2RlZmluZSBGUERGX0VSUl9GSUxFCQkJMgkJLy8gRmlsZSBub3QgZm91bmQgb3IgY291bGQgbm90IGJlIG9wZW5lZC4NCi0jZGVmaW5lIEZQREZfRVJSX0ZPUk1BVAkJCTMJCS8vIEZpbGUgbm90IGluIFBERiBmb3JtYXQgb3IgY29ycnVwdGVkLg0KLSNkZWZpbmUgRlBERl9FUlJfUEFTU1dPUkQJCTQJCS8vIFBhc3N3b3JkIHJlcXVpcmVkIG9yIGluY29ycmVjdCBwYXNzd29yZC4NCi0jZGVmaW5lIEZQREZfRVJSX1NFQ1VSSVRZCQk1CQkvLyBVbnN1cHBvcnRlZCBzZWN1cml0eSBzY2hlbWUuDQotI2RlZmluZSBGUERGX0VSUl9QQUdFCQkJNgkJLy8gUGFnZSBub3QgZm91bmQgb3IgY29udGVudCBlcnJvci4NCi0NCi0vLyBGdW5jdGlvbjogRlBERl9HZXRMYXN0RXJyb3INCi0vLwkJCUdldCBsYXN0IGVycm9yIGNvZGUgd2hlbiBhbiBTREsgZnVuY3Rpb24gZmFpbGVkLg0KLS8vIFBhcmFtZXRlcnM6IA0KLS8vCQkJTm9uZS4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlBIDMyLWJpdCBpbnRlZ2VyIGluZGljYXRpbmcgZXJyb3IgY29kZXMgKGRlZmluZWQgYWJvdmUpLg0KLS8vIENvbW1lbnRzOg0KLS8vCQkJSWYgdGhlIHByZXZpb3VzIFNESyBjYWxsIHN1Y2NlZWRlZCwgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGlzIGZ1bmN0aW9uDQotLy8JCQlpcyBub3QgZGVmaW5lZC4NCi0vLw0KLURMTEVYUE9SVCB1bnNpZ25lZCBsb25nCVNURENBTEwgRlBERl9HZXRMYXN0RXJyb3IoKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERl9HZXREb2NQZXJtaXNzaW9uDQotLy8JCQlHZXQgZmlsZSBwZXJtaXNzaW9uIGZsYWdzIG9mIHRoZSBkb2N1bWVudC4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBmdW5jdGlvbi4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlBIDMyLWJpdCBpbnRlZ2VyIGluZGljYXRpbmcgcGVybWlzc2lvbiBmbGFncy4gUGxlYXNlIHJlZmVyIHRvIFBERiBSZWZlcmVuY2UgZm9yDQotLy8JCQlkZXRhaWxlZCBkZXNjcmlwdGlvbi4gSWYgdGhlIGRvY3VtZW50IGlzIG5vdCBwcm90ZWN0ZWQsIDB4ZmZmZmZmZmYgd2lsbCBiZSByZXR1cm5lZC4NCi0vLw0KLURMTEVYUE9SVCB1bnNpZ25lZCBsb25nCVNURENBTEwgRlBERl9HZXREb2NQZXJtaXNzaW9ucyhGUERGX0RPQ1VNRU5UIGRvY3VtZW50KTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERl9HZXRQYWdlQ291bnQNCi0vLwkJCUdldCB0b3RhbCBudW1iZXIgb2YgcGFnZXMgaW4gYSBkb2N1bWVudC4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBmdW5jdGlvbi4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUb3RhbCBudW1iZXIgb2YgcGFnZXMgaW4gdGhlIGRvY3VtZW50Lg0KLS8vDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZfR2V0UGFnZUNvdW50KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX0xvYWRQYWdlDQotLy8JCQlMb2FkIGEgcGFnZSBpbnNpZGUgYSBkb2N1bWVudC4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBmdW5jdGlvbi4NCi0vLwkJCXBhZ2VfaW5kZXgJLQlJbmRleCBudW1iZXIgb2YgdGhlIHBhZ2UuIDAgZm9yIHRoZSBmaXJzdCBwYWdlLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCUEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgcGFnZS4gSWYgZmFpbGVkLCBOVUxMIGlzIHJldHVybmVkLg0KLS8vIENvbW1lbnRzOg0KLS8vCQkJTG9hZGVkIHBhZ2UgY2FuIGJlIHJlbmRlcmVkIHRvIGRldmljZXMgdXNpbmcgRlBERl9SZW5kZXJQYWdlIGZ1bmN0aW9uLg0KLS8vCQkJTG9hZGVkIHBhZ2UgY2FuIGJlIGNsb3NlZCBieSBGUERGX0Nsb3NlUGFnZS4NCi0vLw0KLURMTEVYUE9SVCBGUERGX1BBR0UJU1REQ0FMTCBGUERGX0xvYWRQYWdlKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIGludCBwYWdlX2luZGV4KTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERl9HZXRQYWdlV2lkdGgNCi0vLwkJCUdldCBwYWdlIHdpZHRoLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgcGFnZS4gUmV0dXJuZWQgYnkgRlBERl9Mb2FkUGFnZSBmdW5jdGlvbi4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlQYWdlIHdpZHRoIChleGNsdWRpbmcgbm9uLWRpc3BsYXlhYmxlIGFyZWEpIG1lYXN1cmVkIGluIHBvaW50cy4NCi0vLwkJCU9uZSBwb2ludCBpcyAxLzcyIGluY2ggKGFyb3VuZCAwLjM1MjggbW0pLg0KLS8vDQotRExMRVhQT1JUIGRvdWJsZSBTVERDQUxMIEZQREZfR2V0UGFnZVdpZHRoKEZQREZfUEFHRSBwYWdlKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERl9HZXRQYWdlSGVpZ2h0DQotLy8JCQlHZXQgcGFnZSBoZWlnaHQuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVBhZ2UgaGVpZ2h0IChleGNsdWRpbmcgbm9uLWRpc3BsYXlhYmxlIGFyZWEpIG1lYXN1cmVkIGluIHBvaW50cy4NCi0vLwkJCU9uZSBwb2ludCBpcyAxLzcyIGluY2ggKGFyb3VuZCAwLjM1MjggbW0pDQotLy8NCi1ETExFWFBPUlQgZG91YmxlIFNURENBTEwgRlBERl9HZXRQYWdlSGVpZ2h0KEZQREZfUEFHRSBwYWdlKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERl9HZXRQYWdlU2l6ZUJ5SW5kZXgNCi0vLwkJCUdldCB0aGUgc2l6ZSBvZiBhIHBhZ2UgYnkgaW5kZXguDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBmdW5jdGlvbi4NCi0vLwkJCXBhZ2VfaW5kZXgJLQlQYWdlIGluZGV4LCB6ZXJvIGZvciB0aGUgZmlyc3QgcGFnZS4NCi0vLwkJCXdpZHRoCQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSBwYWdlIHdpZHRoIChpbiBwb2ludHMpLg0KLS8vCQkJaGVpZ2h0CQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSBwYWdlIGhlaWdodCAoaW4gcG9pbnRzKS4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlOb24temVybyBmb3Igc3VjY2Vzcy4gMCBmb3IgZXJyb3IgKGRvY3VtZW50IG9yIHBhZ2Ugbm90IGZvdW5kKS4NCi0vLw0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX0dldFBhZ2VTaXplQnlJbmRleChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBpbnQgcGFnZV9pbmRleCwgZG91YmxlKiB3aWR0aCwgZG91YmxlKiBoZWlnaHQpOw0KLQ0KLQ0KLS8vIFBhZ2UgcmVuZGVyaW5nIGZsYWdzLiBUaGV5IGNhbiBiZSBjb21iaW5lZCB3aXRoIGJpdCBPUi4NCi0jZGVmaW5lIEZQREZfQU5OT1QJCQkweDAxCQkvLyBTZXQgaWYgYW5ub3RhdGlvbnMgYXJlIHRvIGJlIHJlbmRlcmVkLg0KLSNkZWZpbmUgRlBERl9MQ0RfVEVYVAkJMHgwMgkJLy8gU2V0IGlmIHVzaW5nIHRleHQgcmVuZGVyaW5nIG9wdGltaXplZCBmb3IgTENEIGRpc3BsYXkuDQotI2RlZmluZSBGUERGX05PX05BVElWRVRFWFQJMHgwNAkJLy8gRG9uJ3QgdXNlIHRoZSBuYXRpdmUgdGV4dCBvdXRwdXQgYXZhaWxhYmxlIG9uIHNvbWUgcGxhdGZvcm1zDQotI2RlZmluZSBGUERGX0dSQVlTQ0FMRQkJMHgwOAkJLy8gR3JheXNjYWxlIG91dHB1dC4NCi0jZGVmaW5lIEZQREZfREVCVUdfSU5GTwkJMHg4MAkJLy8gU2V0IGlmIHlvdSB3YW50IHRvIGdldCBzb21lIGRlYnVnIGluZm8uIA0KLQkJCQkJCQkJCQkvLyBQbGVhc2UgZGlzY3VzcyB3aXRoIEZveGl0IGZpcnN0IGlmIHlvdSBuZWVkIHRvIGNvbGxlY3QgZGVidWcgaW5mby4NCi0jZGVmaW5lIEZQREZfTk9fQ0FUQ0gJCTB4MTAwCQkvLyBTZXQgaWYgeW91IGRvbid0IHdhbnQgdG8gY2F0Y2ggZXhjZXB0aW9uLg0KLSNkZWZpbmUgRlBERl9SRU5ERVJfTElNSVRFRElNQUdFQ0FDSEUJMHgyMDAJLy8gTGltaXQgaW1hZ2UgY2FjaGUgc2l6ZS4gDQotI2RlZmluZSBGUERGX1JFTkRFUl9GT1JDRUhBTEZUT05FCQkweDQwMAkvLyBBbHdheXMgdXNlIGhhbGZ0b25lIGZvciBpbWFnZSBzdHJldGNoaW5nLg0KLSNkZWZpbmUgRlBERl9QUklOVElORwkJMHg4MDAJLy8gUmVuZGVyIGZvciBwcmludGluZy4NCi0jZGVmaW5lIEZQREZfUkVWRVJTRV9CWVRFX09SREVSCQkweDEwCQkvL3NldCB3aGV0aGVyIHJlbmRlciBpbiBhIHJldmVyc2UgQnl0ZSBvcmRlciwgdGhpcyBmbGFnIG9ubHkgDQotCQkJCQkJCQkJCQkJLy9lbmFibGUgd2hlbiByZW5kZXIgdG8gYSBiaXRtYXAuDQotI2lmZGVmIF9XSU4zMg0KLS8vIEZ1bmN0aW9uOiBGUERGX1JlbmRlclBhZ2UNCi0vLwkJCVJlbmRlciBjb250ZW50cyBpbiBhIHBhZ2UgdG8gYSBkZXZpY2UgKHNjcmVlbiwgYml0bWFwLCBvciBwcmludGVyKS4NCi0vLwkJCVRoaXMgZnVuY3Rpb24gaXMgb25seSBzdXBwb3J0ZWQgb24gV2luZG93cyBzeXN0ZW0uDQotLy8gUGFyYW1ldGVyczogDQotLy8JCQlkYwkJCS0JSGFuZGxlIHRvIGRldmljZSBjb250ZXh0Lg0KLS8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uDQotLy8JCQlzdGFydF94CQktCUxlZnQgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgZGV2aWNlIGNvb3JkaW5hdGUuDQotLy8JCQlzdGFydF95CQktCVRvcCBwaXhlbCBwb3NpdGlvbiBvZiB0aGUgZGlzcGxheSBhcmVhIGluIHRoZSBkZXZpY2UgY29vcmRpbmF0ZS4NCi0vLwkJCXNpemVfeAkJLQlIb3Jpem9udGFsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuDQotLy8JCQlzaXplX3kJCS0JVmVydGljYWwgc2l6ZSAoaW4gcGl4ZWxzKSBmb3IgZGlzcGxheWluZyB0aGUgcGFnZS4NCi0vLwkJCXJvdGF0ZQkJLQlQYWdlIG9yaWVudGF0aW9uOiAwIChub3JtYWwpLCAxIChyb3RhdGVkIDkwIGRlZ3JlZXMgY2xvY2t3aXNlKSwNCi0vLwkJCQkJCQkJMiAocm90YXRlZCAxODAgZGVncmVlcyksIDMgKHJvdGF0ZWQgOTAgZGVncmVlcyBjb3VudGVyLWNsb2Nrd2lzZSkuDQotLy8JCQlmbGFncwkJLQkwIGZvciBub3JtYWwgZGlzcGxheSwgb3IgY29tYmluYXRpb24gb2YgZmxhZ3MgZGVmaW5lZCBhYm92ZS4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlOb25lLg0KLS8vDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2UoSERDIGRjLCBGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCBpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LA0KLQkJCQkJCWludCByb3RhdGUsIGludCBmbGFncyk7DQotI2VuZGlmDQotDQotLy8gRnVuY3Rpb246IEZQREZfUmVuZGVyUGFnZUJpdG1hcA0KLS8vCQkJUmVuZGVyIGNvbnRlbnRzIGluIGEgcGFnZSB0byBhIGRldmljZSBpbmRlcGVuZGVudCBiaXRtYXANCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCWJpdG1hcAkJLQlIYW5kbGUgdG8gdGhlIGRldmljZSBpbmRlcGVuZGVudCBiaXRtYXAgKGFzIHRoZSBvdXRwdXQgYnVmZmVyKS4NCi0vLwkJCQkJCQlCaXRtYXAgaGFuZGxlIGNhbiBiZSBjcmVhdGVkIGJ5IEZQREZCaXRtYXBfQ3JlYXRlIGZ1bmN0aW9uLg0KLS8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uDQotLy8JCQlzdGFydF94CQktCUxlZnQgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgYml0bWFwIGNvb3JkaW5hdGUuDQotLy8JCQlzdGFydF95CQktCVRvcCBwaXhlbCBwb3NpdGlvbiBvZiB0aGUgZGlzcGxheSBhcmVhIGluIHRoZSBiaXRtYXAgY29vcmRpbmF0ZS4NCi0vLwkJCXNpemVfeAkJLQlIb3Jpem9udGFsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuDQotLy8JCQlzaXplX3kJCS0JVmVydGljYWwgc2l6ZSAoaW4gcGl4ZWxzKSBmb3IgZGlzcGxheWluZyB0aGUgcGFnZS4NCi0vLwkJCXJvdGF0ZQkJLQlQYWdlIG9yaWVudGF0aW9uOiAwIChub3JtYWwpLCAxIChyb3RhdGVkIDkwIGRlZ3JlZXMgY2xvY2t3aXNlKSwNCi0vLwkJCQkJCQkJMiAocm90YXRlZCAxODAgZGVncmVlcyksIDMgKHJvdGF0ZWQgOTAgZGVncmVlcyBjb3VudGVyLWNsb2Nrd2lzZSkuDQotLy8JCQlmbGFncwkJLQkwIGZvciBub3JtYWwgZGlzcGxheSwgb3IgY29tYmluYXRpb24gb2YgZmxhZ3MgZGVmaW5lZCBhYm92ZS4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlOb25lLg0KLS8vDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2VCaXRtYXAoRlBERl9CSVRNQVAgYml0bWFwLCBGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCANCi0JCQkJCQlpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LCBpbnQgcm90YXRlLCBpbnQgZmxhZ3MpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX0Nsb3NlUGFnZQ0KLS8vCQkJQ2xvc2UgYSBsb2FkZWQgUERGIHBhZ2UuDQotLy8gUGFyYW1ldGVyczogDQotLy8JCQlwYWdlCQktCUhhbmRsZSB0byB0aGUgbG9hZGVkIHBhZ2UuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJTm9uZS4NCi0vLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9DbG9zZVBhZ2UoRlBERl9QQUdFIHBhZ2UpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX0Nsb3NlRG9jdW1lbnQNCi0vLwkJCUNsb3NlIGEgbG9hZGVkIFBERiBkb2N1bWVudC4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIHRoZSBsb2FkZWQgZG9jdW1lbnQuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJTm9uZS4NCi0vLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9DbG9zZURvY3VtZW50KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX0RldmljZVRvUGFnZQ0KLS8vCQkJQ29udmVydCB0aGUgc2NyZWVuIGNvb3JkaW5hdGUgb2YgYSBwb2ludCB0byBwYWdlIGNvb3JkaW5hdGUuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vCQkJc3RhcnRfeAkJLQlMZWZ0IHBpeGVsIHBvc2l0aW9uIG9mIHRoZSBkaXNwbGF5IGFyZWEgaW4gdGhlIGRldmljZSBjb29yZGluYXRlLg0KLS8vCQkJc3RhcnRfeQkJLQlUb3AgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgZGV2aWNlIGNvb3JkaW5hdGUuDQotLy8JCQlzaXplX3gJCS0JSG9yaXpvbnRhbCBzaXplIChpbiBwaXhlbHMpIGZvciBkaXNwbGF5aW5nIHRoZSBwYWdlLg0KLS8vCQkJc2l6ZV95CQktCVZlcnRpY2FsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuDQotLy8JCQlyb3RhdGUJCS0JUGFnZSBvcmllbnRhdGlvbjogMCAobm9ybWFsKSwgMSAocm90YXRlZCA5MCBkZWdyZWVzIGNsb2Nrd2lzZSksDQotLy8JCQkJCQkJCTIgKHJvdGF0ZWQgMTgwIGRlZ3JlZXMpLCAzIChyb3RhdGVkIDkwIGRlZ3JlZXMgY291bnRlci1jbG9ja3dpc2UpLg0KLS8vCQkJZGV2aWNlX3gJLQlYIHZhbHVlIGluIGRldmljZSBjb29yZGluYXRlLCBmb3IgdGhlIHBvaW50IHRvIGJlIGNvbnZlcnRlZC4NCi0vLwkJCWRldmljZV95CS0JWSB2YWx1ZSBpbiBkZXZpY2UgY29vcmRpbmF0ZSwgZm9yIHRoZSBwb2ludCB0byBiZSBjb252ZXJ0ZWQuDQotLy8JCQlwYWdlX3gJCS0JQSBQb2ludGVyIHRvIGEgZG91YmxlIHJlY2VpdmluZyB0aGUgY29udmVydGVkIFggdmFsdWUgaW4gcGFnZSBjb29yZGluYXRlLg0KLS8vCQkJcGFnZV95CQktCUEgUG9pbnRlciB0byBhIGRvdWJsZSByZWNlaXZpbmcgdGhlIGNvbnZlcnRlZCBZIHZhbHVlIGluIHBhZ2UgY29vcmRpbmF0ZS4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlOb25lLg0KLS8vIENvbW1lbnRzOg0KLS8vCQkJVGhlIHBhZ2UgY29vcmRpbmF0ZSBzeXN0ZW0gaGFzIGl0cyBvcmlnaW4gYXQgbGVmdC1ib3R0b20gY29ybmVyIG9mIHRoZSBwYWdlLCB3aXRoIFggYXhpcyBnb2VzIGFsb25nDQotLy8JCQl0aGUgYm90dG9tIHNpZGUgdG8gdGhlIHJpZ2h0LCBhbmQgWSBheGlzIGdvZXMgYWxvbmcgdGhlIGxlZnQgc2lkZSB1cHdhcmQuIE5PVEU6IHRoaXMgY29vcmRpbmF0ZSBzeXN0ZW0gDQotLy8JCQljYW4gYmUgYWx0ZXJlZCB3aGVuIHlvdSB6b29tLCBzY3JvbGwsIG9yIHJvdGF0ZSBhIHBhZ2UsIGhvd2V2ZXIsIGEgcG9pbnQgb24gdGhlIHBhZ2Ugc2hvdWxkIGFsd2F5cyBoYXZlIA0KLS8vCQkJdGhlIHNhbWUgY29vcmRpbmF0ZSB2YWx1ZXMgaW4gdGhlIHBhZ2UgY29vcmRpbmF0ZSBzeXN0ZW0uIA0KLS8vDQotLy8JCQlUaGUgZGV2aWNlIGNvb3JkaW5hdGUgc3lzdGVtIGlzIGRldmljZSBkZXBlbmRlbnQuIEZvciBzY3JlZW4gZGV2aWNlLCBpdHMgb3JpZ2luIGlzIGF0IGxlZnQtdG9wDQotLy8JCQljb3JuZXIgb2YgdGhlIHdpbmRvdy4gSG93ZXZlciB0aGlzIG9yaWdpbiBjYW4gYmUgYWx0ZXJlZCBieSBXaW5kb3dzIGNvb3JkaW5hdGUgdHJhbnNmb3JtYXRpb24NCi0vLwkJCXV0aWxpdGllcy4gWW91IG11c3QgbWFrZSBzdXJlIHRoZSBzdGFydF94LCBzdGFydF95LCBzaXplX3gsIHNpemVfeSBhbmQgcm90YXRlIHBhcmFtZXRlcnMgaGF2ZSBleGFjdGx5DQotLy8JCQlzYW1lIHZhbHVlcyBhcyB5b3UgdXNlZCBpbiBGUERGX1JlbmRlclBhZ2UoKSBmdW5jdGlvbiBjYWxsLg0KLS8vDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX0RldmljZVRvUGFnZShGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCBpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LA0KLQkJCQkJCWludCByb3RhdGUsIGludCBkZXZpY2VfeCwgaW50IGRldmljZV95LCBkb3VibGUqIHBhZ2VfeCwgZG91YmxlKiBwYWdlX3kpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGX1BhZ2VUb0RldmljZQ0KLS8vCQkJQ29udmVydCB0aGUgcGFnZSBjb29yZGluYXRlIG9mIGEgcG9pbnQgdG8gc2NyZWVuIGNvb3JkaW5hdGUuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLg0KLS8vCQkJc3RhcnRfeAkJLQlMZWZ0IHBpeGVsIHBvc2l0aW9uIG9mIHRoZSBkaXNwbGF5IGFyZWEgaW4gdGhlIGRldmljZSBjb29yZGluYXRlLg0KLS8vCQkJc3RhcnRfeQkJLQlUb3AgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgZGV2aWNlIGNvb3JkaW5hdGUuDQotLy8JCQlzaXplX3gJCS0JSG9yaXpvbnRhbCBzaXplIChpbiBwaXhlbHMpIGZvciBkaXNwbGF5aW5nIHRoZSBwYWdlLg0KLS8vCQkJc2l6ZV95CQktCVZlcnRpY2FsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuDQotLy8JCQlyb3RhdGUJCS0JUGFnZSBvcmllbnRhdGlvbjogMCAobm9ybWFsKSwgMSAocm90YXRlZCA5MCBkZWdyZWVzIGNsb2Nrd2lzZSksDQotLy8JCQkJCQkJCTIgKHJvdGF0ZWQgMTgwIGRlZ3JlZXMpLCAzIChyb3RhdGVkIDkwIGRlZ3JlZXMgY291bnRlci1jbG9ja3dpc2UpLg0KLS8vCQkJcGFnZV94CQktCVggdmFsdWUgaW4gcGFnZSBjb29yZGluYXRlLCBmb3IgdGhlIHBvaW50IHRvIGJlIGNvbnZlcnRlZC4NCi0vLwkJCXBhZ2VfeQkJLQlZIHZhbHVlIGluIHBhZ2UgY29vcmRpbmF0ZSwgZm9yIHRoZSBwb2ludCB0byBiZSBjb252ZXJ0ZWQuDQotLy8JCQlkZXZpY2VfeAktCUEgcG9pbnRlciB0byBhbiBpbnRlZ2VyIHJlY2VpdmluZyB0aGUgcmVzdWx0IFggdmFsdWUgaW4gZGV2aWNlIGNvb3JkaW5hdGUuDQotLy8JCQlkZXZpY2VfeQktCUEgcG9pbnRlciB0byBhbiBpbnRlZ2VyIHJlY2VpdmluZyB0aGUgcmVzdWx0IFkgdmFsdWUgaW4gZGV2aWNlIGNvb3JkaW5hdGUuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJTm9uZS4NCi0vLyBDb21tZW50czoNCi0vLwkJCVNlZSBjb21tZW50cyBvZiBGUERGX0RldmljZVRvUGFnZSgpIGZ1bmN0aW9uLg0KLS8vDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX1BhZ2VUb0RldmljZShGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCBpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LA0KLQkJCQkJCWludCByb3RhdGUsIGRvdWJsZSBwYWdlX3gsIGRvdWJsZSBwYWdlX3ksIGludCogZGV2aWNlX3gsIGludCogZGV2aWNlX3kpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGQml0bWFwX0NyZWF0ZQ0KLS8vCQkJQ3JlYXRlIGEgRm94aXQgRGV2aWNlIEluZGVwZW5kZW50IEJpdG1hcCAoRlhESUIpLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQl3aWR0aAkJLQlOdW1iZXIgb2YgcGl4ZWxzIGluIGEgaG9yaXpvbnRhbCBsaW5lIG9mIHRoZSBiaXRtYXAuIE11c3QgYmUgZ3JlYXRlciB0aGFuIDAuDQotLy8JCQloZWlnaHQJCS0JTnVtYmVyIG9mIHBpeGVscyBpbiBhIHZlcnRpY2FsIGxpbmUgb2YgdGhlIGJpdG1hcC4gTXVzdCBiZSBncmVhdGVyIHRoYW4gMC4NCi0vLwkJCWFscGhhCQktCUEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgYWxwaGEgY2hhbm5lbCBpcyB1c2VkLiBOb24temVybyBmb3IgdXNpbmcgYWxwaGEsIHplcm8gZm9yIG5vdCB1c2luZy4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUaGUgY3JlYXRlZCBiaXRtYXAgaGFuZGxlLCBvciBOVUxMIGlmIHBhcmFtZXRlciBlcnJvciBvciBvdXQgb2YgbWVtb3J5Lg0KLS8vIENvbW1lbnRzOg0KLS8vCQkJQW4gRlhESUIgYWx3YXlzIHVzZSA0IGJ5dGUgcGVyIHBpeGVsLiBUaGUgZmlyc3QgYnl0ZSBvZiBhIHBpeGVsIGlzIGFsd2F5cyBkb3VibGUgd29yZCBhbGlnbmVkLg0KLS8vCQkJRWFjaCBwaXhlbCBjb250YWlucyByZWQgKFIpLCBncmVlbiAoRyksIGJsdWUgKEIpIGFuZCBvcHRpb25hbGx5IGFscGhhIChBKSB2YWx1ZXMuDQotLy8JCQlUaGUgYnl0ZSBvcmRlciBpcyBCR1J4ICh0aGUgbGFzdCBieXRlIHVudXNlZCBpZiBubyBhbHBoYSBjaGFubmVsKSBvciBCR1JBLg0KLS8vCQkJDQotLy8JCQlUaGUgcGl4ZWxzIGluIGEgaG9yaXpvbnRhbCBsaW5lIChhbHNvIGNhbGxlZCBzY2FuIGxpbmUpIGFyZSBzdG9yZWQgc2lkZSBieSBzaWRlLCB3aXRoIGxlZnQgbW9zdA0KLS8vCQkJcGl4ZWwgc3RvcmVkIGZpcnN0ICh3aXRoIGxvd2VyIG1lbW9yeSBhZGRyZXNzKS4gRWFjaCBzY2FuIGxpbmUgdXNlcyB3aWR0aCo0IGJ5dGVzLg0KLS8vDQotLy8JCQlTY2FuIGxpbmVzIGFyZSBzdG9yZWQgb25lIGFmdGVyIGFub3RoZXIsIHdpdGggdG9wIG1vc3Qgc2NhbiBsaW5lIHN0b3JlZCBmaXJzdC4gVGhlcmUgaXMgbm8gZ2FwDQotLy8JCQliZXR3ZWVuIGFkamFjZW50IHNjYW4gbGluZXMuDQotLy8NCi0vLwkJCVRoaXMgZnVuY3Rpb24gYWxsb2NhdGVzIGVub3VnaCBtZW1vcnkgZm9yIGhvbGRpbmcgYWxsIHBpeGVscyBpbiB0aGUgYml0bWFwLCBidXQgaXQgZG9lc24ndCANCi0vLwkJCWluaXRpYWxpemUgdGhlIGJ1ZmZlci4gQXBwbGljYXRpb25zIGNhbiB1c2UgRlBERkJpdG1hcF9GaWxsUmVjdCB0byBmaWxsIHRoZSBiaXRtYXAgdXNpbmcgYW55IGNvbG9yLg0KLURMTEVYUE9SVCBGUERGX0JJVE1BUCBTVERDQUxMIEZQREZCaXRtYXBfQ3JlYXRlKGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGFscGhhKTsNCi0NCi0vLyBNb3JlIERJQiBmb3JtYXRzDQotI2RlZmluZSBGUERGQml0bWFwX0dyYXkJCTEJCS8vIEdyYXkgc2NhbGUgYml0bWFwLCBvbmUgYnl0ZSBwZXIgcGl4ZWwuDQotI2RlZmluZSBGUERGQml0bWFwX0JHUgkJMgkJLy8gMyBieXRlcyBwZXIgcGl4ZWwsIGJ5dGUgb3JkZXI6IGJsdWUsIGdyZWVuLCByZWQuDQotI2RlZmluZSBGUERGQml0bWFwX0JHUngJCTMJCS8vIDQgYnl0ZXMgcGVyIHBpeGVsLCBieXRlIG9yZGVyOiBibHVlLCBncmVlbiwgcmVkLCB1bnVzZWQuDQotI2RlZmluZSBGUERGQml0bWFwX0JHUkEJCTQJCS8vIDQgYnl0ZXMgcGVyIHBpeGVsLCBieXRlIG9yZGVyOiBibHVlLCBncmVlbiwgcmVkLCBhbHBoYS4NCi0NCi0vLyBGdW5jdGlvbjogRlBERkJpdG1hcF9DcmVhdGVFeA0KLS8vCQkJQ3JlYXRlIGEgRm94aXQgRGV2aWNlIEluZGVwZW5kZW50IEJpdG1hcCAoRlhESUIpDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCXdpZHRoCQktCU51bWJlciBvZiBwaXhlbHMgaW4gYSBob3Jpem9udGFsIGxpbmUgb2YgdGhlIGJpdG1hcC4gTXVzdCBiZSBncmVhdGVyIHRoYW4gMC4NCi0vLwkJCWhlaWdodAkJLQlOdW1iZXIgb2YgcGl4ZWxzIGluIGEgdmVydGljYWwgbGluZSBvZiB0aGUgYml0bWFwLiBNdXN0IGJlIGdyZWF0ZXIgdGhhbiAwLg0KLS8vCQkJZm9ybWF0CQktCUEgbnVtYmVyIGluZGljYXRpbmcgZm9yIGJpdG1hcCBmb3JtYXQsIGFzIGRlZmluZWQgYWJvdmUuDQotLy8JCQlmaXJzdF9zY2FuCS0JQSBwb2ludGVyIHRvIHRoZSBmaXJzdCBieXRlIG9mIGZpcnN0IHNjYW4gbGluZSwgZm9yIGV4dGVybmFsIGJ1ZmZlcg0KLS8vCQkJCQkJCW9ubHkuIElmIHRoaXMgcGFyYW1ldGVyIGlzIE5VTEwsIHRoZW4gdGhlIFNESyB3aWxsIGNyZWF0ZSBpdHMgb3duIGJ1ZmZlci4NCi0vLwkJCXN0cmlkZQkJLQlOdW1iZXIgb2YgYnl0ZXMgZm9yIGVhY2ggc2NhbiBsaW5lLCBmb3IgZXh0ZXJuYWwgYnVmZmVyIG9ubHkuLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRoZSBjcmVhdGVkIGJpdG1hcCBoYW5kbGUsIG9yIE5VTEwgaWYgcGFyYW1ldGVyIGVycm9yIG9yIG91dCBvZiBtZW1vcnkuDQotLy8gQ29tbWVudHM6DQotLy8JCQlTaW1pbGFyIHRvIEZQREZCaXRtYXBfQ3JlYXRlIGZ1bmN0aW9uLCB3aXRoIG1vcmUgZm9ybWF0cyBhbmQgZXh0ZXJuYWwgYnVmZmVyIHN1cHBvcnRlZC4gDQotLy8JCQlCaXRtYXAgY3JlYXRlZCBieSB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIGluIGFueSBwbGFjZSB0aGF0IGEgRlBERl9CSVRNQVAgaGFuZGxlIGlzIA0KLS8vCQkJcmVxdWlyZWQuIA0KLS8vDQotLy8JCQlJZiBleHRlcm5hbCBzY2FubGluZSBidWZmZXIgaXMgdXNlZCwgdGhlbiB0aGUgYXBwbGljYXRpb24gc2hvdWxkIGRlc3Ryb3kgdGhlIGJ1ZmZlcg0KLS8vCQkJYnkgaXRzZWxmLiBGUERGQml0bWFwX0Rlc3Ryb3kgZnVuY3Rpb24gd2lsbCBub3QgZGVzdHJveSB0aGUgYnVmZmVyLg0KLS8vDQotRExMRVhQT1JUIEZQREZfQklUTUFQIFNURENBTEwgRlBERkJpdG1hcF9DcmVhdGVFeChpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBmb3JtYXQsIHZvaWQqIGZpcnN0X3NjYW4sIGludCBzdHJpZGUpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGQml0bWFwX0ZpbGxSZWN0DQotLy8JCQlGaWxsIGEgcmVjdGFuZ2xlIGFyZWEgaW4gYW4gRlhESUIuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWJpdG1hcAkJLQlUaGUgaGFuZGxlIHRvIHRoZSBiaXRtYXAuIFJldHVybmVkIGJ5IEZQREZCaXRtYXBfQ3JlYXRlIGZ1bmN0aW9uLg0KLS8vCQkJbGVmdAkJLQlUaGUgbGVmdCBzaWRlIHBvc2l0aW9uLiBTdGFydGluZyBmcm9tIDAgYXQgdGhlIGxlZnQtbW9zdCBwaXhlbC4NCi0vLwkJCXRvcAkJCS0JVGhlIHRvcCBzaWRlIHBvc2l0aW9uLiBTdGFydGluZyBmcm9tIDAgYXQgdGhlIHRvcC1tb3N0IHNjYW4gbGluZS4NCi0vLwkJCXdpZHRoCQktCU51bWJlciBvZiBwaXhlbHMgdG8gYmUgZmlsbGVkIGluIGVhY2ggc2NhbiBsaW5lLg0KLS8vCQkJaGVpZ2h0CQktCU51bWJlciBvZiBzY2FuIGxpbmVzIHRvIGJlIGZpbGxlZC4NCi0vLwkJCXJlZAkJCS0JQSBudW1iZXIgZnJvbSAwIHRvIDI1NSwgaWRlbnRpZnlpbmcgdGhlIHJlZCBpbnRlbnNpdHkuDQotLy8JCQlncmVlbgkJLQlBIG51bWJlciBmcm9tIDAgdG8gMjU1LCBpZGVudGlmeWluZyB0aGUgZ3JlZW4gaW50ZW5zaXR5Lg0KLS8vCQkJYmx1ZQkJLQlBIG51bWJlciBmcm9tIDAgdG8gMjU1LCBpZGVudGlmeWluZyB0aGUgYmx1ZSBpbnRlbnNpdHkuDQotLy8JCQlhbHBoYQkJLQkoT25seSBpZiB0aGUgYWxwaGEgY2hhbm5lbGVkIGlzIHVzZWQgd2hlbiBiaXRtYXAgY3JlYXRlZCkgQSBudW1iZXIgZnJvbSAwIHRvIDI1NSwNCi0vLwkJCQkJCQlpZGVudGlmeWluZyB0aGUgYWxwaGEgdmFsdWUuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJTm9uZS4NCi0vLyBDb21tZW50czoNCi0vLwkJCVRoaXMgZnVuY3Rpb24gc2V0IHRoZSBjb2xvciBhbmQgKG9wdGlvbmFsbHkpIGFscGhhIHZhbHVlIGluIHNwZWNpZmllZCByZWdpb24gb2YgdGhlIGJpdG1hcC4NCi0vLwkJCU5PVEU6IElmIGFscGhhIGNoYW5uZWwgaXMgdXNlZCwgdGhpcyBmdW5jdGlvbiBkb2VzIE5PVCBjb21wb3NpdGUgdGhlIGJhY2tncm91bmQgd2l0aCB0aGUgc291cmNlIGNvbG9yLA0KLS8vCQkJaW5zdGVhZCB0aGUgYmFja2dyb3VuZCB3aWxsIGJlIHJlcGxhY2VkIGJ5IHRoZSBzb3VyY2UgY29sb3IgYW5kIGFscGhhLg0KLS8vCQkJSWYgYWxwaGEgY2hhbm5lbCBpcyBub3QgdXNlZCwgdGhlICJhbHBoYSIgcGFyYW1ldGVyIGlzIGlnbm9yZWQuDQotLy8NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZCaXRtYXBfRmlsbFJlY3QoRlBERl9CSVRNQVAgYml0bWFwLCBpbnQgbGVmdCwgaW50IHRvcCwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCANCi0JCQkJCQkJCQlpbnQgcmVkLCBpbnQgZ3JlZW4sIGludCBibHVlLCBpbnQgYWxwaGEpOw0KLQ0KLS8vIEZ1bmN0aW9uOiBGUERGQml0bWFwX0dldEJ1ZmZlcg0KLS8vCQkJR2V0IGRhdGEgYnVmZmVyIG9mIGFuIEZYRElCDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWJpdG1hcAkJLQlIYW5kbGUgdG8gdGhlIGJpdG1hcC4gUmV0dXJuZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVGhlIHBvaW50ZXIgdG8gdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGJpdG1hcCBidWZmZXIuDQotLy8gQ29tbWVudHM6DQotLy8JCQlUaGUgc3RyaWRlIG1heSBiZSBtb3JlIHRoYW4gd2lkdGggKiBudW1iZXIgb2YgYnl0ZXMgcGVyIHBpeGVsDQotLy8JCQlBcHBsaWNhdGlvbnMgY2FuIHVzZSB0aGlzIGZ1bmN0aW9uIHRvIGdldCB0aGUgYml0bWFwIGJ1ZmZlciBwb2ludGVyLCB0aGVuIG1hbmlwdWxhdGUgYW55IGNvbG9yDQotLy8JCQlhbmQvb3IgYWxwaGEgdmFsdWVzIGZvciBhbnkgcGl4ZWxzIGluIHRoZSBiaXRtYXAuDQotRExMRVhQT1JUIHZvaWQqIFNURENBTEwgRlBERkJpdG1hcF9HZXRCdWZmZXIoRlBERl9CSVRNQVAgYml0bWFwKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkJpdG1hcF9HZXRXaWR0aA0KLS8vCQkJR2V0IHdpZHRoIG9mIGFuIEZYRElCLg0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQliaXRtYXAJCS0JSGFuZGxlIHRvIHRoZSBiaXRtYXAuIFJldHVybmVkIGJ5IEZQREZCaXRtYXBfQ3JlYXRlIGZ1bmN0aW9uLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRoZSBudW1iZXIgb2YgcGl4ZWxzIGluIGEgaG9yaXpvbnRhbCBsaW5lIG9mIHRoZSBiaXRtYXAuDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZCaXRtYXBfR2V0V2lkdGgoRlBERl9CSVRNQVAgYml0bWFwKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkJpdG1hcF9HZXRIZWlnaHQNCi0vLwkJCUdldCBoZWlnaHQgb2YgYW4gRlhESUIuDQotLy8gUGFyYW1ldGVyczoNCi0vLwkJCWJpdG1hcAkJLQlIYW5kbGUgdG8gdGhlIGJpdG1hcC4gUmV0dXJuZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJVGhlIG51bWJlciBvZiBwaXhlbHMgaW4gYSB2ZXJ0aWNhbCBsaW5lIG9mIHRoZSBiaXRtYXAuDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZCaXRtYXBfR2V0SGVpZ2h0KEZQREZfQklUTUFQIGJpdG1hcCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZCaXRtYXBfR2V0U3RyaWRlDQotLy8JCQlHZXQgbnVtYmVyIG9mIGJ5dGVzIGZvciBlYWNoIHNjYW4gbGluZSBpbiB0aGUgYml0bWFwIGJ1ZmZlci4NCi0vLyBQYXJhbWV0ZXJzOg0KLS8vCQkJYml0bWFwCQktCUhhbmRsZSB0byB0aGUgYml0bWFwLiBSZXR1cm5lZCBieSBGUERGQml0bWFwX0NyZWF0ZSBmdW5jdGlvbi4NCi0vLyBSZXR1cm4gdmFsdWU6DQotLy8JCQlUaGUgbnVtYmVyIG9mIGJ5dGVzIGZvciBlYWNoIHNjYW4gbGluZSBpbiB0aGUgYml0bWFwIGJ1ZmZlci4NCi0vLyBDb21tZW50czoNCi0vLwkJCVRoZSBzdHJpZGUgbWF5IGJlIG1vcmUgdGhhbiB3aWR0aCAqIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwNCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERkJpdG1hcF9HZXRTdHJpZGUoRlBERl9CSVRNQVAgYml0bWFwKTsNCi0NCi0vLyBGdW5jdGlvbjogRlBERkJpdG1hcF9EZXN0cm95DQotLy8JCQlEZXN0cm95IGFuIEZYRElCIGFuZCByZWxlYXNlIGFsbCByZWxhdGVkIGJ1ZmZlcnMuIA0KLS8vIFBhcmFtZXRlcnM6DQotLy8JCQliaXRtYXAJCS0JSGFuZGxlIHRvIHRoZSBiaXRtYXAuIFJldHVybmVkIGJ5IEZQREZCaXRtYXBfQ3JlYXRlIGZ1bmN0aW9uLg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCU5vbmUuDQotLy8gQ29tbWVudHM6DQotLy8JCQlUaGlzIGZ1bmN0aW9uIHdpbGwgbm90IGRlc3Ryb3kgYW55IGV4dGVybmFsIGJ1ZmZlci4NCi0vLw0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkJpdG1hcF9EZXN0cm95KEZQREZfQklUTUFQIGJpdG1hcCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZfVklFV0VSUkVGX0dldFByaW50U2NhbGluZw0KLS8vCQkJV2hldGhlciB0aGUgUERGIGRvY3VtZW50IHByZWZlcnMgdG8gYmUgc2NhbGVkIG9yIG5vdC4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIHRoZSBsb2FkZWQgZG9jdW1lbnQuDQotLy8gUmV0dXJuIHZhbHVlOg0KLS8vCQkJTm9uZS4NCi0vLw0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX1ZJRVdFUlJFRl9HZXRQcmludFNjYWxpbmcoRlBERl9ET0NVTUVOVCBkb2N1bWVudCk7DQotDQotLy8gRnVuY3Rpb246IEZQREZfR2V0TmFtZWREZXN0QnlOYW1lDQotLy8JCQlnZXQgYSBzcGVjaWFsIGRlc3QgaGFuZGxlIGJ5IHRoZSBpbmRleC4NCi0vLyBQYXJhbWV0ZXJzOiANCi0vLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIHRoZSBsb2FkZWQgZG9jdW1lbnQuDQotLy8JCQluYW1lCQktCVRoZSBuYW1lIG9mIGEgc3BlY2lhbCBuYW1lZCBkZXN0Lg0KLS8vIFJldHVybiB2YWx1ZToNCi0vLwkJCVRoZSBoYW5kbGUgb2YgdGhlIGRlc3QuDQotLy8NCi1ETExFWFBPUlQgRlBERl9ERVNUIFNURENBTEwgRlBERl9HZXROYW1lZERlc3RCeU5hbWUoRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0JZVEVTVFJJTkcgbmFtZSk7DQotDQotI2lmZGVmIF9fY3BsdXNwbHVzDQotfTsNCi0jZW5kaWYNCi0NCi0jZW5kaWYgLy8gX0ZQREZWSUVXX0hfDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworCisjaWZuZGVmIF9GUERGVklFV19IXworI2RlZmluZSBfRlBERlZJRVdfSF8KKworI2lmIGRlZmluZWQoX1dJTjMyKSAmJiAhZGVmaW5lZChfX1dJTkRPV1NfXykKKyNpbmNsdWRlIDx3aW5kb3dzLmg+CisjZW5kaWYKKworLy8gRGF0YSB0eXBlcwordHlwZWRlZiB2b2lkKglGUERGX01PRFVMRU1HUjsKKworLy8gUERGIHR5cGVzCit0eXBlZGVmIHZvaWQqCUZQREZfRE9DVU1FTlQ7CQkKK3R5cGVkZWYgdm9pZCoJRlBERl9QQUdFOwkJCQordHlwZWRlZiB2b2lkKglGUERGX1BBR0VPQkpFQ1Q7CS8vIFBhZ2Ugb2JqZWN0KHRleHQsIHBhdGgsIGV0YykKK3R5cGVkZWYgdm9pZCoJRlBERl9QQVRIOwordHlwZWRlZiB2b2lkKglGUERGX0NMSVBQQVRIOwkKK3R5cGVkZWYgdm9pZCoJRlBERl9CSVRNQVA7CQordHlwZWRlZiB2b2lkKglGUERGX0ZPTlQ7CQkJCisKK3R5cGVkZWYgdm9pZCoJRlBERl9URVhUUEFHRTsKK3R5cGVkZWYgdm9pZCoJRlBERl9TQ0hIQU5ETEU7Cit0eXBlZGVmIHZvaWQqCUZQREZfUEFHRUxJTks7Cit0eXBlZGVmIHZvaWQqCUZQREZfSE1PRFVMRTsKK3R5cGVkZWYgdm9pZCoJRlBERl9ET0NTQ0hIQU5ETEU7CisKK3R5cGVkZWYgdm9pZCoJRlBERl9CT09LTUFSSzsKK3R5cGVkZWYgdm9pZCoJRlBERl9ERVNUOwordHlwZWRlZiB2b2lkKglGUERGX0FDVElPTjsKK3R5cGVkZWYgdm9pZCoJRlBERl9MSU5LOworCisvLyBCYXNpYyBkYXRhIHR5cGVzCit0eXBlZGVmIGludAkJCQlGUERGX0JPT0w7Cit0eXBlZGVmIGludAkJCQlGUERGX0VSUk9SOwkKK3R5cGVkZWYgdW5zaWduZWQgbG9uZwlGUERGX0RXT1JEOworCit0eXBlZGVmCWZsb2F0CQkJRlNfRkxPQVQ7CisKKy8vIFN0cmluZyB0eXBlcwordHlwZWRlZiB1bnNpZ25lZCBzaG9ydAkJCUZQREZfV0NIQVI7Cit0eXBlZGVmIHVuc2lnbmVkIGNoYXIgY29uc3QqCUZQREZfTFBDQllURTsKKworLy8gRlBERlNESyBtYXkgdXNlIHRocmVlIHR5cGVzIG9mIHN0cmluZ3M6IGJ5dGUgc3RyaW5nLCB3aWRlIHN0cmluZyAoVVRGLTE2TEUgZW5jb2RlZCksIGFuZCBwbGF0Zm9ybSBkZXBlbmRlbnQgc3RyaW5nCit0eXBlZGVmIGNvbnN0IGNoYXIqCQkJCUZQREZfQllURVNUUklORzsKKwordHlwZWRlZiBjb25zdCB1bnNpZ25lZCBzaG9ydCoJRlBERl9XSURFU1RSSU5HOwkJLy8gRm94aXQgUERGIFNESyBhbHdheXMgdXNlIFVURi0xNkxFIGVuY29kaW5nIHdpZGUgc3RyaW5nLAorCQkJCQkJCQkJCQkJCQkvLyBlYWNoIGNoYXJhY3RlciB1c2UgMiBieXRlcyAoZXhjZXB0IHN1cnJvZ2F0aW9uKSwgd2l0aCBsb3cgYnl0ZSBmaXJzdC4KKworLy8gRm9yIFdpbmRvd3MgcHJvZ3JhbW1lcnM6IGZvciBtb3N0IGNhc2UgaXQncyBPSyB0byB0cmVhdCBGUERGX1dJREVTVFJJTkcgYXMgV2luZG93cyB1bmljb2RlIHN0cmluZywKKy8vCQkgaG93ZXZlciwgc3BlY2lhbCBjYXJlIG5lZWRzIHRvIGJlIHRha2VuIGlmIHlvdSBleHBlY3QgdG8gcHJvY2VzcyBVbmljb2RlIGxhcmdlciB0aGFuIDB4ZmZmZi4KKy8vIEZvciBMaW51eC9Vbml4IHByb2dyYW1tZXJzOiBtb3N0IGNvbXBpbGVyL2xpYnJhcnkgZW52aXJvbm1lbnQgdXNlcyA0IGJ5dGVzIGZvciBhIFVuaWNvZGUgY2hhcmFjdGVyLAorLy8JCXlvdSBoYXZlIHRvIGNvbnZlcnQgYmV0d2VlbiBGUERGX1dJREVTVFJJTkcgYW5kIHN5c3RlbSB3aWRlIHN0cmluZyBieSB5b3Vyc2VsZi4KKworI2lmZGVmIF9XSU4zMl9XQ0UKK3R5cGVkZWYgY29uc3QgdW5zaWduZWQgc2hvcnQqIEZQREZfU1RSSU5HOworI2Vsc2UKK3R5cGVkZWYgY29uc3QgY2hhciogRlBERl9TVFJJTkc7CisjZW5kaWYKKworI2lmbmRlZiBfRlNfREVGX01BVFJJWF8KKyNkZWZpbmUgX0ZTX0RFRl9NQVRSSVhfCisvKiogQGJyaWVmIE1hdHJpeCBmb3IgdHJhbnNmb3JtYXRpb24uICovCit0eXBlZGVmIHN0cnVjdCBfRlNfTUFUUklYXworeworCWZsb2F0CWE7CS8qKjwgQGJyaWVmIENvZWZmaWNpZW50IGEuKi8KKwlmbG9hdAliOwkvKio8IEBicmllZiBDb2VmZmljaWVudCBiLiovCisJZmxvYXQJYzsJLyoqPCBAYnJpZWYgQ29lZmZpY2llbnQgYy4qLworCWZsb2F0CWQ7CS8qKjwgQGJyaWVmIENvZWZmaWNpZW50IGQuKi8KKwlmbG9hdAllOwkvKio8IEBicmllZiBDb2VmZmljaWVudCBlLiovCisJZmxvYXQJZjsJLyoqPCBAYnJpZWYgQ29lZmZpY2llbnQgZi4qLworfSBGU19NQVRSSVg7CisjZW5kaWYKKworI2lmbmRlZiBfRlNfREVGX1JFQ1RGXworI2RlZmluZSBfRlNfREVGX1JFQ1RGXworLyoqIEBicmllZiBSZWN0YW5nbGUgYXJlYShmbG9hdCkgaW4gZGV2aWNlIG9yIHBhZ2UgY29vcmRpbmF0aW9uIHN5c3RlbS4gKi8KK3R5cGVkZWYgc3RydWN0IF9GU19SRUNURl8KK3sKKwkvKipAeyovCisJLyoqIEBicmllZiBUaGUgeC1jb29yZGluYXRlIG9mIHRoZSBsZWZ0LXRvcCBjb3JuZXIuICovCisJZmxvYXQJbGVmdDsKKwkvKiogQGJyaWVmIFRoZSB5LWNvb3JkaW5hdGUgb2YgdGhlIGxlZnQtdG9wIGNvcm5lci4gKi8KKwlmbG9hdAl0b3A7CisJLyoqIEBicmllZiBUaGUgeC1jb29yZGluYXRlIG9mIHRoZSByaWdodC1ib3R0b20gY29ybmVyLiAqLworCWZsb2F0CXJpZ2h0OworCS8qKiBAYnJpZWYgVGhlIHktY29vcmRpbmF0ZSBvZiB0aGUgcmlnaHQtYm90dG9tIGNvcm5lci4gKi8KKwlmbG9hdAlib3R0b207CisJLyoqQH0qLworfSogRlNfTFBSRUNURiwgRlNfUkVDVEY7CisvKiogQGJyaWVmIENvbnN0IFBvaW50ZXIgdG8gOjpGU19SRUNURiBzdHJ1Y3R1cmUuKi8KK3R5cGVkZWYgY29uc3QgRlNfUkVDVEYqCUZTX0xQQ1JFQ1RGOworI2VuZGlmCisKKyNpZiBkZWZpbmVkKF9XSU4zMikgJiYgZGVmaW5lZChGUERGU0RLX0VYUE9SVFMpCisvLyBPbiBXaW5kb3dzIHN5c3RlbSwgZnVuY3Rpb25zIGFyZSBleHBvcnRlZCBpbiBhIERMTAorI2RlZmluZSBETExFWFBPUlQgX19kZWNsc3BlYyggZGxsZXhwb3J0ICkKKyNkZWZpbmUgU1REQ0FMTCBfX3N0ZGNhbGwKKyNlbHNlCisjZGVmaW5lIERMTEVYUE9SVAorI2RlZmluZSBTVERDQUxMCisjZW5kaWYKKworZXh0ZXJuIGNvbnN0IGNoYXIgZ19FeHBpcmVEYXRlW107CitleHRlcm4gY29uc3QgY2hhciBnX01vZHVsZUNvZGVzW107CisKKy8vIEV4cG9ydGVkIEZ1bmN0aW9ucworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCisvLyBGdW5jdGlvbjogRlBERl9Jbml0TGlicmFyeQorLy8JCQlJbml0aWFsaXplIHRoZSBGUERGU0RLIGxpYnJhcnkgCisvLyBQYXJhbWV0ZXJzOgorLy8JCQloSW5zdGFuY2UJLQlGb3IgV0lOMzIgc3lzdGVtIG9ubHk6IHRoZSBpbnN0YW5jZSBvZiB0aGUgZXhlY3V0YWJsZSBvciBETEwgbW9kdWxlLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOb25lLgorLy8gQ29tbWVudHM6CisvLwkJCVlvdSBoYXZlIHRvIGNhbGwgdGhpcyBmdW5jdGlvbiBiZWZvcmUgeW91IGNhbiBjYWxsIGFueSBQREYgcHJvY2Vzc2luZyBmdW5jdGlvbnMuCisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9Jbml0TGlicmFyeSh2b2lkKiBoSW5zdGFuY2UpOworCisKKy8vIEZ1bmN0aW9uOiBGUERGX0Rlc3Ryb3lMaWJhcnkKKy8vCQkJUmVsZWFzZSBhbGwgcmVzb3VyY2VzIGFsbG9jYXRlZCBieSB0aGUgRlBERlNESyBsaWJyYXJ5LgorLy8gUGFyYW1ldGVyczoKKy8vCQkJTm9uZS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTm9uZS4KKy8vIENvbW1lbnRzOgorLy8JCQlZb3UgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbiB0byByZWxlYXNlIGFsbCBtZW1vcnkgYmxvY2tzIGFsbG9jYXRlZCBieSB0aGUgbGlicmFyeS4gCisvLwkJCUFmdGVyIHRoaXMgZnVuY3Rpb24gY2FsbGVkLCB5b3Ugc2hvdWxkIG5vdCBjYWxsIGFueSBQREYgcHJvY2Vzc2luZyBmdW5jdGlvbnMuCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfRGVzdHJveUxpYnJhcnkoKTsKKworLy9Qb2xpY3kgZm9yIGFjY2Vzc2luZyB0aGUgbG9jYWwgbWFjaGluZSB0aW1lLgorI2RlZmluZSBGUERGX1BPTElDWV9NQUNISU5FVElNRV9BQ0NFU1MJMAorCisvLyBGdW5jdGlvbjogRlBERl9TZXRTYW5kQm94UG9saWN5CisvLwkJCVNldCB0aGUgcG9saWN5IGZvciB0aGUgc2FuZGJveCBlbnZpcm9ubWVudC4KKy8vIFBhcmFtZXRlcnM6CQorLy8JCQlwb2xpY3kJCS0JVGhlIHNwZWNpZmllZCBwb2xpY3kgZm9yIHNldHRpbmcsIGZvciBleGFtcGxlOkZQREZfUE9MSUNZX01BQ0hJTkVUSU1FX0FDQ0VTUy4KKy8vCQkJZW5hYmxlCQktCVRydWUgZm9yIGVuYWJsZSwgRmFsc2UgZm9yIGRpc2FibGUgdGhlIHBvbGljeS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTm9uZS4KK0RMTEVYUE9SVCB2b2lkCVNURENBTEwgRlBERl9TZXRTYW5kQm94UG9saWN5KEZQREZfRFdPUkQgcG9saWN5LCBGUERGX0JPT0wgZW5hYmxlKTsKKworLyoqCisqIE9wZW4gYW5kIGxvYWQgYSBQREYgZG9jdW1lbnQuCisqIEBwYXJhbVtpbl0gZmlsZV9wYXRoCS0JUGF0aCB0byB0aGUgUERGIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pLgorKiBAcGFyYW1baW5dIHBhc3N3b3JkCS0JQSBzdHJpbmcgdXNlZCBhcyB0aGUgcGFzc3dvcmQgZm9yIFBERiBmaWxlLiAKKyoJCQkJCQkJSWYgbm8gcGFzc3dvcmQgbmVlZGVkLCBlbXB0eSBvciBOVUxMIGNhbiBiZSB1c2VkLgorKiBAbm90ZQkJTG9hZGVkIGRvY3VtZW50IGNhbiBiZSBjbG9zZWQgYnkgRlBERl9DbG9zZURvY3VtZW50LgorKgkJCUlmIHRoaXMgZnVuY3Rpb24gZmFpbHMsIHlvdSBjYW4gdXNlIEZQREZfR2V0TGFzdEVycm9yKCkgdG8gcmV0cmlldmUKKyoJCQl0aGUgcmVhc29uIHdoeSBpdCBmYWlscy4KKyogQHJldHZhbAlBIGhhbmRsZSB0byB0aGUgbG9hZGVkIGRvY3VtZW50LiBJZiBmYWlsZWQsIE5VTEwgaXMgcmV0dXJuZWQuCisqLworRExMRVhQT1JUIEZQREZfRE9DVU1FTlQJU1REQ0FMTCBGUERGX0xvYWREb2N1bWVudChGUERGX1NUUklORyBmaWxlX3BhdGgsIAorCUZQREZfQllURVNUUklORyBwYXNzd29yZCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGX0xvYWRNZW1Eb2N1bWVudAorLy8JCQlPcGVuIGFuZCBsb2FkIGEgUERGIGRvY3VtZW50IGZyb20gbWVtb3J5LgorLy8gUGFyYW1ldGVyczogCisvLwkJCWRhdGFfYnVmCS0JUG9pbnRlciB0byBhIGJ1ZmZlciBjb250YWluaW5nIHRoZSBQREYgZG9jdW1lbnQuCisvLwkJCXNpemUJCS0JTnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBQREYgZG9jdW1lbnQuCisvLwkJCXBhc3N3b3JkCS0JQSBzdHJpbmcgdXNlZCBhcyB0aGUgcGFzc3dvcmQgZm9yIFBERiBmaWxlLiAKKy8vCQkJCQkJCUlmIG5vIHBhc3N3b3JkIG5lZWRlZCwgZW1wdHkgb3IgTlVMTCBjYW4gYmUgdXNlZC4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJQSBoYW5kbGUgdG8gdGhlIGxvYWRlZCBkb2N1bWVudC4gSWYgZmFpbGVkLCBOVUxMIGlzIHJldHVybmVkLgorLy8gQ29tbWVudHM6CisvLwkJCVRoZSBtZW1vcnkgYnVmZmVyIG11c3QgcmVtYWluIHZhbGlkIHdoZW4gdGhlIGRvY3VtZW50IGlzIG9wZW4uCisvLwkJCUxvYWRlZCBkb2N1bWVudCBjYW4gYmUgY2xvc2VkIGJ5IEZQREZfQ2xvc2VEb2N1bWVudC4KKy8vCQkJSWYgdGhpcyBmdW5jdGlvbiBmYWlscywgeW91IGNhbiB1c2UgRlBERl9HZXRMYXN0RXJyb3IoKSB0byByZXRyaWV2ZQorLy8JCQl0aGUgcmVhc29uIHdoeSBpdCBmYWlscy4KKy8vCitETExFWFBPUlQgRlBERl9ET0NVTUVOVAlTVERDQUxMIEZQREZfTG9hZE1lbURvY3VtZW50KGNvbnN0IHZvaWQqIGRhdGFfYnVmLCAKKwkJCQkJCQkJCQkJaW50IHNpemUsIEZQREZfQllURVNUUklORyBwYXNzd29yZCk7CisKKy8vIFN0cnVjdHVyZSBmb3IgY3VzdG9tIGZpbGUgYWNjZXNzLgordHlwZWRlZiBzdHJ1Y3QgeworCS8vIEZpbGUgbGVuZ3RoLCBpbiBieXRlcy4KKwl1bnNpZ25lZCBsb25nCW1fRmlsZUxlbjsKKworCS8vIEEgZnVuY3Rpb24gcG9pbnRlciBmb3IgZ2V0dGluZyBhIGJsb2NrIG9mIGRhdGEgZnJvbSBzcGVjaWZpYyBwb3NpdGlvbi4KKwkvLyBQb3NpdGlvbiBpcyBzcGVjaWZpZWQgYnkgYnl0ZSBvZmZzZXQgZnJvbSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUuCisJLy8gVGhlIHBvc2l0aW9uIGFuZCBzaXplIHdpbGwgbmV2ZXIgZ28gb3V0IHJhbmdlIG9mIGZpbGUgbGVuZ3RoLgorCS8vIEl0IG1heSBiZSBwb3NzaWJsZSBmb3IgRlBERlNESyB0byBjYWxsIHRoaXMgZnVuY3Rpb24gbXVsdGlwbGUgdGltZXMgZm9yIHNhbWUgcG9zaXRpb24uCisJLy8gUmV0dXJuIHZhbHVlOiBzaG91bGQgYmUgbm9uLXplcm8gaWYgc3VjY2Vzc2Z1bCwgemVybyBmb3IgZXJyb3IuCisJaW50CQkJCSgqbV9HZXRCbG9jaykodm9pZCogcGFyYW0sIHVuc2lnbmVkIGxvbmcgcG9zaXRpb24sIHVuc2lnbmVkIGNoYXIqIHBCdWYsIHVuc2lnbmVkIGxvbmcgc2l6ZSk7CisKKwkvLyBBIGN1c3RvbSBwb2ludGVyIGZvciBhbGwgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgZGF0YS4KKwkvLyBUaGlzIHBvaW50ZXIgd2lsbCBiZSB1c2VkIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIgdG8gbV9HZXRCbG9jayBjYWxsYmFjay4KKwl2b2lkKgkJCW1fUGFyYW07Cit9IEZQREZfRklMRUFDQ0VTUzsKKworLy8gRnVuY3Rpb246IEZQREZfTG9hZEN1c3RvbURvY3VtZW50CisvLwkJCUxvYWQgUERGIGRvY3VtZW50IGZyb20gYSBjdXN0b20gYWNjZXNzIGRlc2NyaXB0b3IuCisvLyBQYXJhbWV0ZXJzOgorLy8JCQlwRmlsZUFjY2VzcwktCUEgc3RydWN0dXJlIGZvciBhY2Nlc3MgdGhlIGZpbGUuCisvLwkJCXBhc3N3b3JkCS0JT3B0aW9uYWwgcGFzc3dvcmQgZm9yIGRlY3J5cHRpbmcgdGhlIFBERiBmaWxlLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlBIGhhbmRsZSB0byB0aGUgbG9hZGVkIGRvY3VtZW50LiBJZiBmYWlsZWQsIE5VTEwgaXMgcmV0dXJuZWQuCisvLyBDb21tZW50czoKKy8vCQkJVGhlIGFwcGxpY2F0aW9uIHNob3VsZCBtYWludGFpbiB0aGUgZmlsZSByZXNvdXJjZXMgYmVpbmcgdmFsaWQgdW50aWwgdGhlIFBERiBkb2N1bWVudCBjbG9zZS4KKy8vCQkJTG9hZGVkIGRvY3VtZW50IGNhbiBiZSBjbG9zZWQgYnkgRlBERl9DbG9zZURvY3VtZW50LgorRExMRVhQT1JUIEZQREZfRE9DVU1FTlQgU1REQ0FMTCBGUERGX0xvYWRDdXN0b21Eb2N1bWVudChGUERGX0ZJTEVBQ0NFU1MqIHBGaWxlQWNjZXNzLCAKKwkJCQkJCQkJCQkJCQkJRlBERl9CWVRFU1RSSU5HIHBhc3N3b3JkKTsKKworLy8gRnVuY3Rpb246IEZQREZfR2V0RmlsZVZlcnNpb24KKy8vCQkJR2V0IHRoZSBmaWxlIHZlcnNpb24gb2YgdGhlIHNwZWNpZmljIFBERiBkb2N1bWVudC4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWRvYwkJCS0JSGFuZGxlIHRvIGRvY3VtZW50LgorLy8JCQlmaWxlVmVyc2lvbgktCVRoZSBQREYgZmlsZSB2ZXJzaW9uLiBGaWxlIHZlcnNpb246IDE0IGZvciAxLjQsIDE1IGZvciAxLjUsIC4uLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUUlVFIGlmIHRoaXMgY2FsbCBzdWNjZWVkLCBJZiBmYWlsZWQsIEZBTFNFIGlzIHJldHVybmVkLgorLy8gQ29tbWVudHM6CisvLwkJCUlmIHRoZSBkb2N1bWVudCBpcyBjcmVhdGVkIGJ5IGZ1bmN0aW9uIDo6RlBERl9DcmVhdGVOZXdEb2N1bWVudCwgdGhlbiB0aGlzIGZ1bmN0aW9uIHdvdWxkIGFsd2F5cyBmYWlsLgorRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZfR2V0RmlsZVZlcnNpb24oRlBERl9ET0NVTUVOVCBkb2MsIGludCogZmlsZVZlcnNpb24pOworCisjZGVmaW5lIEZQREZfRVJSX1NVQ0NFU1MJCTAJCS8vIE5vIGVycm9yLgorI2RlZmluZSBGUERGX0VSUl9VTktOT1dOCQkxCQkvLyBVbmtub3duIGVycm9yLgorI2RlZmluZSBGUERGX0VSUl9GSUxFCQkJMgkJLy8gRmlsZSBub3QgZm91bmQgb3IgY291bGQgbm90IGJlIG9wZW5lZC4KKyNkZWZpbmUgRlBERl9FUlJfRk9STUFUCQkJMwkJLy8gRmlsZSBub3QgaW4gUERGIGZvcm1hdCBvciBjb3JydXB0ZWQuCisjZGVmaW5lIEZQREZfRVJSX1BBU1NXT1JECQk0CQkvLyBQYXNzd29yZCByZXF1aXJlZCBvciBpbmNvcnJlY3QgcGFzc3dvcmQuCisjZGVmaW5lIEZQREZfRVJSX1NFQ1VSSVRZCQk1CQkvLyBVbnN1cHBvcnRlZCBzZWN1cml0eSBzY2hlbWUuCisjZGVmaW5lIEZQREZfRVJSX1BBR0UJCQk2CQkvLyBQYWdlIG5vdCBmb3VuZCBvciBjb250ZW50IGVycm9yLgorCisvLyBGdW5jdGlvbjogRlBERl9HZXRMYXN0RXJyb3IKKy8vCQkJR2V0IGxhc3QgZXJyb3IgY29kZSB3aGVuIGFuIFNESyBmdW5jdGlvbiBmYWlsZWQuCisvLyBQYXJhbWV0ZXJzOiAKKy8vCQkJTm9uZS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJQSAzMi1iaXQgaW50ZWdlciBpbmRpY2F0aW5nIGVycm9yIGNvZGVzIChkZWZpbmVkIGFib3ZlKS4KKy8vIENvbW1lbnRzOgorLy8JCQlJZiB0aGUgcHJldmlvdXMgU0RLIGNhbGwgc3VjY2VlZGVkLCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoaXMgZnVuY3Rpb24KKy8vCQkJaXMgbm90IGRlZmluZWQuCisvLworRExMRVhQT1JUIHVuc2lnbmVkIGxvbmcJU1REQ0FMTCBGUERGX0dldExhc3RFcnJvcigpOworCisvLyBGdW5jdGlvbjogRlBERl9HZXREb2NQZXJtaXNzaW9uCisvLwkJCUdldCBmaWxlIHBlcm1pc3Npb24gZmxhZ3Mgb2YgdGhlIGRvY3VtZW50LgorLy8gUGFyYW1ldGVyczogCisvLwkJCWRvY3VtZW50CS0JSGFuZGxlIHRvIGRvY3VtZW50LiBSZXR1cm5lZCBieSBGUERGX0xvYWREb2N1bWVudCBmdW5jdGlvbi4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJQSAzMi1iaXQgaW50ZWdlciBpbmRpY2F0aW5nIHBlcm1pc3Npb24gZmxhZ3MuIFBsZWFzZSByZWZlciB0byBQREYgUmVmZXJlbmNlIGZvcgorLy8JCQlkZXRhaWxlZCBkZXNjcmlwdGlvbi4gSWYgdGhlIGRvY3VtZW50IGlzIG5vdCBwcm90ZWN0ZWQsIDB4ZmZmZmZmZmYgd2lsbCBiZSByZXR1cm5lZC4KKy8vCitETExFWFBPUlQgdW5zaWduZWQgbG9uZwlTVERDQUxMIEZQREZfR2V0RG9jUGVybWlzc2lvbnMoRlBERl9ET0NVTUVOVCBkb2N1bWVudCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGX0dldFBhZ2VDb3VudAorLy8JCQlHZXQgdG90YWwgbnVtYmVyIG9mIHBhZ2VzIGluIGEgZG9jdW1lbnQuCisvLyBQYXJhbWV0ZXJzOiAKKy8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUb3RhbCBudW1iZXIgb2YgcGFnZXMgaW4gdGhlIGRvY3VtZW50LgorLy8KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX0dldFBhZ2VDb3VudChGUERGX0RPQ1VNRU5UIGRvY3VtZW50KTsKKworLy8gRnVuY3Rpb246IEZQREZfTG9hZFBhZ2UKKy8vCQkJTG9hZCBhIHBhZ2UgaW5zaWRlIGEgZG9jdW1lbnQuCisvLyBQYXJhbWV0ZXJzOiAKKy8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLgorLy8JCQlwYWdlX2luZGV4CS0JSW5kZXggbnVtYmVyIG9mIHRoZSBwYWdlLiAwIGZvciB0aGUgZmlyc3QgcGFnZS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJQSBoYW5kbGUgdG8gdGhlIGxvYWRlZCBwYWdlLiBJZiBmYWlsZWQsIE5VTEwgaXMgcmV0dXJuZWQuCisvLyBDb21tZW50czoKKy8vCQkJTG9hZGVkIHBhZ2UgY2FuIGJlIHJlbmRlcmVkIHRvIGRldmljZXMgdXNpbmcgRlBERl9SZW5kZXJQYWdlIGZ1bmN0aW9uLgorLy8JCQlMb2FkZWQgcGFnZSBjYW4gYmUgY2xvc2VkIGJ5IEZQREZfQ2xvc2VQYWdlLgorLy8KK0RMTEVYUE9SVCBGUERGX1BBR0UJU1REQ0FMTCBGUERGX0xvYWRQYWdlKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIGludCBwYWdlX2luZGV4KTsKKworLy8gRnVuY3Rpb246IEZQREZfR2V0UGFnZVdpZHRoCisvLwkJCUdldCBwYWdlIHdpZHRoLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVBhZ2Ugd2lkdGggKGV4Y2x1ZGluZyBub24tZGlzcGxheWFibGUgYXJlYSkgbWVhc3VyZWQgaW4gcG9pbnRzLgorLy8JCQlPbmUgcG9pbnQgaXMgMS83MiBpbmNoIChhcm91bmQgMC4zNTI4IG1tKS4KKy8vCitETExFWFBPUlQgZG91YmxlIFNURENBTEwgRlBERl9HZXRQYWdlV2lkdGgoRlBERl9QQUdFIHBhZ2UpOworCisvLyBGdW5jdGlvbjogRlBERl9HZXRQYWdlSGVpZ2h0CisvLwkJCUdldCBwYWdlIGhlaWdodC4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlQYWdlIGhlaWdodCAoZXhjbHVkaW5nIG5vbi1kaXNwbGF5YWJsZSBhcmVhKSBtZWFzdXJlZCBpbiBwb2ludHMuCisvLwkJCU9uZSBwb2ludCBpcyAxLzcyIGluY2ggKGFyb3VuZCAwLjM1MjggbW0pCisvLworRExMRVhQT1JUIGRvdWJsZSBTVERDQUxMIEZQREZfR2V0UGFnZUhlaWdodChGUERGX1BBR0UgcGFnZSk7CisKKy8vIEZ1bmN0aW9uOiBGUERGX0dldFBhZ2VTaXplQnlJbmRleAorLy8JCQlHZXQgdGhlIHNpemUgb2YgYSBwYWdlIGJ5IGluZGV4LgorLy8gUGFyYW1ldGVyczoKKy8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gZG9jdW1lbnQuIFJldHVybmVkIGJ5IEZQREZfTG9hZERvY3VtZW50IGZ1bmN0aW9uLgorLy8JCQlwYWdlX2luZGV4CS0JUGFnZSBpbmRleCwgemVybyBmb3IgdGhlIGZpcnN0IHBhZ2UuCisvLwkJCXdpZHRoCQktCVBvaW50ZXIgdG8gYSBkb3VibGUgdmFsdWUgcmVjZWl2aW5nIHRoZSBwYWdlIHdpZHRoIChpbiBwb2ludHMpLgorLy8JCQloZWlnaHQJCS0JUG9pbnRlciB0byBhIGRvdWJsZSB2YWx1ZSByZWNlaXZpbmcgdGhlIHBhZ2UgaGVpZ2h0IChpbiBwb2ludHMpLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOb24temVybyBmb3Igc3VjY2Vzcy4gMCBmb3IgZXJyb3IgKGRvY3VtZW50IG9yIHBhZ2Ugbm90IGZvdW5kKS4KKy8vCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERl9HZXRQYWdlU2l6ZUJ5SW5kZXgoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgaW50IHBhZ2VfaW5kZXgsIGRvdWJsZSogd2lkdGgsIGRvdWJsZSogaGVpZ2h0KTsKKworCisvLyBQYWdlIHJlbmRlcmluZyBmbGFncy4gVGhleSBjYW4gYmUgY29tYmluZWQgd2l0aCBiaXQgT1IuCisjZGVmaW5lIEZQREZfQU5OT1QJCQkweDAxCQkvLyBTZXQgaWYgYW5ub3RhdGlvbnMgYXJlIHRvIGJlIHJlbmRlcmVkLgorI2RlZmluZSBGUERGX0xDRF9URVhUCQkweDAyCQkvLyBTZXQgaWYgdXNpbmcgdGV4dCByZW5kZXJpbmcgb3B0aW1pemVkIGZvciBMQ0QgZGlzcGxheS4KKyNkZWZpbmUgRlBERl9OT19OQVRJVkVURVhUCTB4MDQJCS8vIERvbid0IHVzZSB0aGUgbmF0aXZlIHRleHQgb3V0cHV0IGF2YWlsYWJsZSBvbiBzb21lIHBsYXRmb3JtcworI2RlZmluZSBGUERGX0dSQVlTQ0FMRQkJMHgwOAkJLy8gR3JheXNjYWxlIG91dHB1dC4KKyNkZWZpbmUgRlBERl9ERUJVR19JTkZPCQkweDgwCQkvLyBTZXQgaWYgeW91IHdhbnQgdG8gZ2V0IHNvbWUgZGVidWcgaW5mby4gCisJCQkJCQkJCQkJLy8gUGxlYXNlIGRpc2N1c3Mgd2l0aCBGb3hpdCBmaXJzdCBpZiB5b3UgbmVlZCB0byBjb2xsZWN0IGRlYnVnIGluZm8uCisjZGVmaW5lIEZQREZfTk9fQ0FUQ0gJCTB4MTAwCQkvLyBTZXQgaWYgeW91IGRvbid0IHdhbnQgdG8gY2F0Y2ggZXhjZXB0aW9uLgorI2RlZmluZSBGUERGX1JFTkRFUl9MSU1JVEVESU1BR0VDQUNIRQkweDIwMAkvLyBMaW1pdCBpbWFnZSBjYWNoZSBzaXplLiAKKyNkZWZpbmUgRlBERl9SRU5ERVJfRk9SQ0VIQUxGVE9ORQkJMHg0MDAJLy8gQWx3YXlzIHVzZSBoYWxmdG9uZSBmb3IgaW1hZ2Ugc3RyZXRjaGluZy4KKyNkZWZpbmUgRlBERl9QUklOVElORwkJMHg4MDAJLy8gUmVuZGVyIGZvciBwcmludGluZy4KKyNkZWZpbmUgRlBERl9SRVZFUlNFX0JZVEVfT1JERVIJCTB4MTAJCS8vc2V0IHdoZXRoZXIgcmVuZGVyIGluIGEgcmV2ZXJzZSBCeXRlIG9yZGVyLCB0aGlzIGZsYWcgb25seSAKKwkJCQkJCQkJCQkJCS8vZW5hYmxlIHdoZW4gcmVuZGVyIHRvIGEgYml0bWFwLgorI2lmZGVmIF9XSU4zMgorLy8gRnVuY3Rpb246IEZQREZfUmVuZGVyUGFnZQorLy8JCQlSZW5kZXIgY29udGVudHMgaW4gYSBwYWdlIHRvIGEgZGV2aWNlIChzY3JlZW4sIGJpdG1hcCwgb3IgcHJpbnRlcikuCisvLwkJCVRoaXMgZnVuY3Rpb24gaXMgb25seSBzdXBwb3J0ZWQgb24gV2luZG93cyBzeXN0ZW0uCisvLyBQYXJhbWV0ZXJzOiAKKy8vCQkJZGMJCQktCUhhbmRsZSB0byBkZXZpY2UgY29udGV4dC4KKy8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLwkJCXN0YXJ0X3gJCS0JTGVmdCBwaXhlbCBwb3NpdGlvbiBvZiB0aGUgZGlzcGxheSBhcmVhIGluIHRoZSBkZXZpY2UgY29vcmRpbmF0ZS4KKy8vCQkJc3RhcnRfeQkJLQlUb3AgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgZGV2aWNlIGNvb3JkaW5hdGUuCisvLwkJCXNpemVfeAkJLQlIb3Jpem9udGFsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuCisvLwkJCXNpemVfeQkJLQlWZXJ0aWNhbCBzaXplIChpbiBwaXhlbHMpIGZvciBkaXNwbGF5aW5nIHRoZSBwYWdlLgorLy8JCQlyb3RhdGUJCS0JUGFnZSBvcmllbnRhdGlvbjogMCAobm9ybWFsKSwgMSAocm90YXRlZCA5MCBkZWdyZWVzIGNsb2Nrd2lzZSksCisvLwkJCQkJCQkJMiAocm90YXRlZCAxODAgZGVncmVlcyksIDMgKHJvdGF0ZWQgOTAgZGVncmVlcyBjb3VudGVyLWNsb2Nrd2lzZSkuCisvLwkJCWZsYWdzCQktCTAgZm9yIG5vcm1hbCBkaXNwbGF5LCBvciBjb21iaW5hdGlvbiBvZiBmbGFncyBkZWZpbmVkIGFib3ZlLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOb25lLgorLy8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9SZW5kZXJQYWdlKEhEQyBkYywgRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwgaW50IHNpemVfeSwKKwkJCQkJCWludCByb3RhdGUsIGludCBmbGFncyk7CisjZW5kaWYKKworLy8gRnVuY3Rpb246IEZQREZfUmVuZGVyUGFnZUJpdG1hcAorLy8JCQlSZW5kZXIgY29udGVudHMgaW4gYSBwYWdlIHRvIGEgZGV2aWNlIGluZGVwZW5kZW50IGJpdG1hcAorLy8gUGFyYW1ldGVyczogCisvLwkJCWJpdG1hcAkJLQlIYW5kbGUgdG8gdGhlIGRldmljZSBpbmRlcGVuZGVudCBiaXRtYXAgKGFzIHRoZSBvdXRwdXQgYnVmZmVyKS4KKy8vCQkJCQkJCUJpdG1hcCBoYW5kbGUgY2FuIGJlIGNyZWF0ZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uCisvLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBwYWdlLiBSZXR1cm5lZCBieSBGUERGX0xvYWRQYWdlIGZ1bmN0aW9uLgorLy8JCQlzdGFydF94CQktCUxlZnQgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgYml0bWFwIGNvb3JkaW5hdGUuCisvLwkJCXN0YXJ0X3kJCS0JVG9wIHBpeGVsIHBvc2l0aW9uIG9mIHRoZSBkaXNwbGF5IGFyZWEgaW4gdGhlIGJpdG1hcCBjb29yZGluYXRlLgorLy8JCQlzaXplX3gJCS0JSG9yaXpvbnRhbCBzaXplIChpbiBwaXhlbHMpIGZvciBkaXNwbGF5aW5nIHRoZSBwYWdlLgorLy8JCQlzaXplX3kJCS0JVmVydGljYWwgc2l6ZSAoaW4gcGl4ZWxzKSBmb3IgZGlzcGxheWluZyB0aGUgcGFnZS4KKy8vCQkJcm90YXRlCQktCVBhZ2Ugb3JpZW50YXRpb246IDAgKG5vcm1hbCksIDEgKHJvdGF0ZWQgOTAgZGVncmVlcyBjbG9ja3dpc2UpLAorLy8JCQkJCQkJCTIgKHJvdGF0ZWQgMTgwIGRlZ3JlZXMpLCAzIChyb3RhdGVkIDkwIGRlZ3JlZXMgY291bnRlci1jbG9ja3dpc2UpLgorLy8JCQlmbGFncwkJLQkwIGZvciBub3JtYWwgZGlzcGxheSwgb3IgY29tYmluYXRpb24gb2YgZmxhZ3MgZGVmaW5lZCBhYm92ZS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTm9uZS4KKy8vCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfUmVuZGVyUGFnZUJpdG1hcChGUERGX0JJVE1BUCBiaXRtYXAsIEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIAorCQkJCQkJaW50IHNpemVfeCwgaW50IHNpemVfeSwgaW50IHJvdGF0ZSwgaW50IGZsYWdzKTsKKworLy8gRnVuY3Rpb246IEZQREZfQ2xvc2VQYWdlCisvLwkJCUNsb3NlIGEgbG9hZGVkIFBERiBwYWdlLgorLy8gUGFyYW1ldGVyczogCisvLwkJCXBhZ2UJCS0JSGFuZGxlIHRvIHRoZSBsb2FkZWQgcGFnZS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTm9uZS4KKy8vCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfQ2xvc2VQYWdlKEZQREZfUEFHRSBwYWdlKTsKKworLy8gRnVuY3Rpb246IEZQREZfQ2xvc2VEb2N1bWVudAorLy8JCQlDbG9zZSBhIGxvYWRlZCBQREYgZG9jdW1lbnQuCisvLyBQYXJhbWV0ZXJzOiAKKy8vCQkJZG9jdW1lbnQJLQlIYW5kbGUgdG8gdGhlIGxvYWRlZCBkb2N1bWVudC4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTm9uZS4KKy8vCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfQ2xvc2VEb2N1bWVudChGUERGX0RPQ1VNRU5UIGRvY3VtZW50KTsKKworLy8gRnVuY3Rpb246IEZQREZfRGV2aWNlVG9QYWdlCisvLwkJCUNvbnZlcnQgdGhlIHNjcmVlbiBjb29yZGluYXRlIG9mIGEgcG9pbnQgdG8gcGFnZSBjb29yZGluYXRlLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLwkJCXN0YXJ0X3gJCS0JTGVmdCBwaXhlbCBwb3NpdGlvbiBvZiB0aGUgZGlzcGxheSBhcmVhIGluIHRoZSBkZXZpY2UgY29vcmRpbmF0ZS4KKy8vCQkJc3RhcnRfeQkJLQlUb3AgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgZGV2aWNlIGNvb3JkaW5hdGUuCisvLwkJCXNpemVfeAkJLQlIb3Jpem9udGFsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuCisvLwkJCXNpemVfeQkJLQlWZXJ0aWNhbCBzaXplIChpbiBwaXhlbHMpIGZvciBkaXNwbGF5aW5nIHRoZSBwYWdlLgorLy8JCQlyb3RhdGUJCS0JUGFnZSBvcmllbnRhdGlvbjogMCAobm9ybWFsKSwgMSAocm90YXRlZCA5MCBkZWdyZWVzIGNsb2Nrd2lzZSksCisvLwkJCQkJCQkJMiAocm90YXRlZCAxODAgZGVncmVlcyksIDMgKHJvdGF0ZWQgOTAgZGVncmVlcyBjb3VudGVyLWNsb2Nrd2lzZSkuCisvLwkJCWRldmljZV94CS0JWCB2YWx1ZSBpbiBkZXZpY2UgY29vcmRpbmF0ZSwgZm9yIHRoZSBwb2ludCB0byBiZSBjb252ZXJ0ZWQuCisvLwkJCWRldmljZV95CS0JWSB2YWx1ZSBpbiBkZXZpY2UgY29vcmRpbmF0ZSwgZm9yIHRoZSBwb2ludCB0byBiZSBjb252ZXJ0ZWQuCisvLwkJCXBhZ2VfeAkJLQlBIFBvaW50ZXIgdG8gYSBkb3VibGUgcmVjZWl2aW5nIHRoZSBjb252ZXJ0ZWQgWCB2YWx1ZSBpbiBwYWdlIGNvb3JkaW5hdGUuCisvLwkJCXBhZ2VfeQkJLQlBIFBvaW50ZXIgdG8gYSBkb3VibGUgcmVjZWl2aW5nIHRoZSBjb252ZXJ0ZWQgWSB2YWx1ZSBpbiBwYWdlIGNvb3JkaW5hdGUuCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCU5vbmUuCisvLyBDb21tZW50czoKKy8vCQkJVGhlIHBhZ2UgY29vcmRpbmF0ZSBzeXN0ZW0gaGFzIGl0cyBvcmlnaW4gYXQgbGVmdC1ib3R0b20gY29ybmVyIG9mIHRoZSBwYWdlLCB3aXRoIFggYXhpcyBnb2VzIGFsb25nCisvLwkJCXRoZSBib3R0b20gc2lkZSB0byB0aGUgcmlnaHQsIGFuZCBZIGF4aXMgZ29lcyBhbG9uZyB0aGUgbGVmdCBzaWRlIHVwd2FyZC4gTk9URTogdGhpcyBjb29yZGluYXRlIHN5c3RlbSAKKy8vCQkJY2FuIGJlIGFsdGVyZWQgd2hlbiB5b3Ugem9vbSwgc2Nyb2xsLCBvciByb3RhdGUgYSBwYWdlLCBob3dldmVyLCBhIHBvaW50IG9uIHRoZSBwYWdlIHNob3VsZCBhbHdheXMgaGF2ZSAKKy8vCQkJdGhlIHNhbWUgY29vcmRpbmF0ZSB2YWx1ZXMgaW4gdGhlIHBhZ2UgY29vcmRpbmF0ZSBzeXN0ZW0uIAorLy8KKy8vCQkJVGhlIGRldmljZSBjb29yZGluYXRlIHN5c3RlbSBpcyBkZXZpY2UgZGVwZW5kZW50LiBGb3Igc2NyZWVuIGRldmljZSwgaXRzIG9yaWdpbiBpcyBhdCBsZWZ0LXRvcAorLy8JCQljb3JuZXIgb2YgdGhlIHdpbmRvdy4gSG93ZXZlciB0aGlzIG9yaWdpbiBjYW4gYmUgYWx0ZXJlZCBieSBXaW5kb3dzIGNvb3JkaW5hdGUgdHJhbnNmb3JtYXRpb24KKy8vCQkJdXRpbGl0aWVzLiBZb3UgbXVzdCBtYWtlIHN1cmUgdGhlIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95IGFuZCByb3RhdGUgcGFyYW1ldGVycyBoYXZlIGV4YWN0bHkKKy8vCQkJc2FtZSB2YWx1ZXMgYXMgeW91IHVzZWQgaW4gRlBERl9SZW5kZXJQYWdlKCkgZnVuY3Rpb24gY2FsbC4KKy8vCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfRGV2aWNlVG9QYWdlKEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIGludCBzaXplX3gsIGludCBzaXplX3ksCisJCQkJCQlpbnQgcm90YXRlLCBpbnQgZGV2aWNlX3gsIGludCBkZXZpY2VfeSwgZG91YmxlKiBwYWdlX3gsIGRvdWJsZSogcGFnZV95KTsKKworLy8gRnVuY3Rpb246IEZQREZfUGFnZVRvRGV2aWNlCisvLwkJCUNvbnZlcnQgdGhlIHBhZ2UgY29vcmRpbmF0ZSBvZiBhIHBvaW50IHRvIHNjcmVlbiBjb29yZGluYXRlLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJcGFnZQkJLQlIYW5kbGUgdG8gdGhlIHBhZ2UuIFJldHVybmVkIGJ5IEZQREZfTG9hZFBhZ2UgZnVuY3Rpb24uCisvLwkJCXN0YXJ0X3gJCS0JTGVmdCBwaXhlbCBwb3NpdGlvbiBvZiB0aGUgZGlzcGxheSBhcmVhIGluIHRoZSBkZXZpY2UgY29vcmRpbmF0ZS4KKy8vCQkJc3RhcnRfeQkJLQlUb3AgcGl4ZWwgcG9zaXRpb24gb2YgdGhlIGRpc3BsYXkgYXJlYSBpbiB0aGUgZGV2aWNlIGNvb3JkaW5hdGUuCisvLwkJCXNpemVfeAkJLQlIb3Jpem9udGFsIHNpemUgKGluIHBpeGVscykgZm9yIGRpc3BsYXlpbmcgdGhlIHBhZ2UuCisvLwkJCXNpemVfeQkJLQlWZXJ0aWNhbCBzaXplIChpbiBwaXhlbHMpIGZvciBkaXNwbGF5aW5nIHRoZSBwYWdlLgorLy8JCQlyb3RhdGUJCS0JUGFnZSBvcmllbnRhdGlvbjogMCAobm9ybWFsKSwgMSAocm90YXRlZCA5MCBkZWdyZWVzIGNsb2Nrd2lzZSksCisvLwkJCQkJCQkJMiAocm90YXRlZCAxODAgZGVncmVlcyksIDMgKHJvdGF0ZWQgOTAgZGVncmVlcyBjb3VudGVyLWNsb2Nrd2lzZSkuCisvLwkJCXBhZ2VfeAkJLQlYIHZhbHVlIGluIHBhZ2UgY29vcmRpbmF0ZSwgZm9yIHRoZSBwb2ludCB0byBiZSBjb252ZXJ0ZWQuCisvLwkJCXBhZ2VfeQkJLQlZIHZhbHVlIGluIHBhZ2UgY29vcmRpbmF0ZSwgZm9yIHRoZSBwb2ludCB0byBiZSBjb252ZXJ0ZWQuCisvLwkJCWRldmljZV94CS0JQSBwb2ludGVyIHRvIGFuIGludGVnZXIgcmVjZWl2aW5nIHRoZSByZXN1bHQgWCB2YWx1ZSBpbiBkZXZpY2UgY29vcmRpbmF0ZS4KKy8vCQkJZGV2aWNlX3kJLQlBIHBvaW50ZXIgdG8gYW4gaW50ZWdlciByZWNlaXZpbmcgdGhlIHJlc3VsdCBZIHZhbHVlIGluIGRldmljZSBjb29yZGluYXRlLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOb25lLgorLy8gQ29tbWVudHM6CisvLwkJCVNlZSBjb21tZW50cyBvZiBGUERGX0RldmljZVRvUGFnZSgpIGZ1bmN0aW9uLgorLy8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9QYWdlVG9EZXZpY2UoRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwgaW50IHNpemVfeSwKKwkJCQkJCWludCByb3RhdGUsIGRvdWJsZSBwYWdlX3gsIGRvdWJsZSBwYWdlX3ksIGludCogZGV2aWNlX3gsIGludCogZGV2aWNlX3kpOworCisvLyBGdW5jdGlvbjogRlBERkJpdG1hcF9DcmVhdGUKKy8vCQkJQ3JlYXRlIGEgRm94aXQgRGV2aWNlIEluZGVwZW5kZW50IEJpdG1hcCAoRlhESUIpLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJd2lkdGgJCS0JTnVtYmVyIG9mIHBpeGVscyBpbiBhIGhvcml6b250YWwgbGluZSBvZiB0aGUgYml0bWFwLiBNdXN0IGJlIGdyZWF0ZXIgdGhhbiAwLgorLy8JCQloZWlnaHQJCS0JTnVtYmVyIG9mIHBpeGVscyBpbiBhIHZlcnRpY2FsIGxpbmUgb2YgdGhlIGJpdG1hcC4gTXVzdCBiZSBncmVhdGVyIHRoYW4gMC4KKy8vCQkJYWxwaGEJCS0JQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciBhbHBoYSBjaGFubmVsIGlzIHVzZWQuIE5vbi16ZXJvIGZvciB1c2luZyBhbHBoYSwgemVybyBmb3Igbm90IHVzaW5nLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUaGUgY3JlYXRlZCBiaXRtYXAgaGFuZGxlLCBvciBOVUxMIGlmIHBhcmFtZXRlciBlcnJvciBvciBvdXQgb2YgbWVtb3J5LgorLy8gQ29tbWVudHM6CisvLwkJCUFuIEZYRElCIGFsd2F5cyB1c2UgNCBieXRlIHBlciBwaXhlbC4gVGhlIGZpcnN0IGJ5dGUgb2YgYSBwaXhlbCBpcyBhbHdheXMgZG91YmxlIHdvcmQgYWxpZ25lZC4KKy8vCQkJRWFjaCBwaXhlbCBjb250YWlucyByZWQgKFIpLCBncmVlbiAoRyksIGJsdWUgKEIpIGFuZCBvcHRpb25hbGx5IGFscGhhIChBKSB2YWx1ZXMuCisvLwkJCVRoZSBieXRlIG9yZGVyIGlzIEJHUnggKHRoZSBsYXN0IGJ5dGUgdW51c2VkIGlmIG5vIGFscGhhIGNoYW5uZWwpIG9yIEJHUkEuCisvLwkJCQorLy8JCQlUaGUgcGl4ZWxzIGluIGEgaG9yaXpvbnRhbCBsaW5lIChhbHNvIGNhbGxlZCBzY2FuIGxpbmUpIGFyZSBzdG9yZWQgc2lkZSBieSBzaWRlLCB3aXRoIGxlZnQgbW9zdAorLy8JCQlwaXhlbCBzdG9yZWQgZmlyc3QgKHdpdGggbG93ZXIgbWVtb3J5IGFkZHJlc3MpLiBFYWNoIHNjYW4gbGluZSB1c2VzIHdpZHRoKjQgYnl0ZXMuCisvLworLy8JCQlTY2FuIGxpbmVzIGFyZSBzdG9yZWQgb25lIGFmdGVyIGFub3RoZXIsIHdpdGggdG9wIG1vc3Qgc2NhbiBsaW5lIHN0b3JlZCBmaXJzdC4gVGhlcmUgaXMgbm8gZ2FwCisvLwkJCWJldHdlZW4gYWRqYWNlbnQgc2NhbiBsaW5lcy4KKy8vCisvLwkJCVRoaXMgZnVuY3Rpb24gYWxsb2NhdGVzIGVub3VnaCBtZW1vcnkgZm9yIGhvbGRpbmcgYWxsIHBpeGVscyBpbiB0aGUgYml0bWFwLCBidXQgaXQgZG9lc24ndCAKKy8vCQkJaW5pdGlhbGl6ZSB0aGUgYnVmZmVyLiBBcHBsaWNhdGlvbnMgY2FuIHVzZSBGUERGQml0bWFwX0ZpbGxSZWN0IHRvIGZpbGwgdGhlIGJpdG1hcCB1c2luZyBhbnkgY29sb3IuCitETExFWFBPUlQgRlBERl9CSVRNQVAgU1REQ0FMTCBGUERGQml0bWFwX0NyZWF0ZShpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBhbHBoYSk7CisKKy8vIE1vcmUgRElCIGZvcm1hdHMKKyNkZWZpbmUgRlBERkJpdG1hcF9HcmF5CQkxCQkvLyBHcmF5IHNjYWxlIGJpdG1hcCwgb25lIGJ5dGUgcGVyIHBpeGVsLgorI2RlZmluZSBGUERGQml0bWFwX0JHUgkJMgkJLy8gMyBieXRlcyBwZXIgcGl4ZWwsIGJ5dGUgb3JkZXI6IGJsdWUsIGdyZWVuLCByZWQuCisjZGVmaW5lIEZQREZCaXRtYXBfQkdSeAkJMwkJLy8gNCBieXRlcyBwZXIgcGl4ZWwsIGJ5dGUgb3JkZXI6IGJsdWUsIGdyZWVuLCByZWQsIHVudXNlZC4KKyNkZWZpbmUgRlBERkJpdG1hcF9CR1JBCQk0CQkvLyA0IGJ5dGVzIHBlciBwaXhlbCwgYnl0ZSBvcmRlcjogYmx1ZSwgZ3JlZW4sIHJlZCwgYWxwaGEuCisKKy8vIEZ1bmN0aW9uOiBGUERGQml0bWFwX0NyZWF0ZUV4CisvLwkJCUNyZWF0ZSBhIEZveGl0IERldmljZSBJbmRlcGVuZGVudCBCaXRtYXAgKEZYRElCKQorLy8gUGFyYW1ldGVyczoKKy8vCQkJd2lkdGgJCS0JTnVtYmVyIG9mIHBpeGVscyBpbiBhIGhvcml6b250YWwgbGluZSBvZiB0aGUgYml0bWFwLiBNdXN0IGJlIGdyZWF0ZXIgdGhhbiAwLgorLy8JCQloZWlnaHQJCS0JTnVtYmVyIG9mIHBpeGVscyBpbiBhIHZlcnRpY2FsIGxpbmUgb2YgdGhlIGJpdG1hcC4gTXVzdCBiZSBncmVhdGVyIHRoYW4gMC4KKy8vCQkJZm9ybWF0CQktCUEgbnVtYmVyIGluZGljYXRpbmcgZm9yIGJpdG1hcCBmb3JtYXQsIGFzIGRlZmluZWQgYWJvdmUuCisvLwkJCWZpcnN0X3NjYW4JLQlBIHBvaW50ZXIgdG8gdGhlIGZpcnN0IGJ5dGUgb2YgZmlyc3Qgc2NhbiBsaW5lLCBmb3IgZXh0ZXJuYWwgYnVmZmVyCisvLwkJCQkJCQlvbmx5LiBJZiB0aGlzIHBhcmFtZXRlciBpcyBOVUxMLCB0aGVuIHRoZSBTREsgd2lsbCBjcmVhdGUgaXRzIG93biBidWZmZXIuCisvLwkJCXN0cmlkZQkJLQlOdW1iZXIgb2YgYnl0ZXMgZm9yIGVhY2ggc2NhbiBsaW5lLCBmb3IgZXh0ZXJuYWwgYnVmZmVyIG9ubHkuLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUaGUgY3JlYXRlZCBiaXRtYXAgaGFuZGxlLCBvciBOVUxMIGlmIHBhcmFtZXRlciBlcnJvciBvciBvdXQgb2YgbWVtb3J5LgorLy8gQ29tbWVudHM6CisvLwkJCVNpbWlsYXIgdG8gRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24sIHdpdGggbW9yZSBmb3JtYXRzIGFuZCBleHRlcm5hbCBidWZmZXIgc3VwcG9ydGVkLiAKKy8vCQkJQml0bWFwIGNyZWF0ZWQgYnkgdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCBpbiBhbnkgcGxhY2UgdGhhdCBhIEZQREZfQklUTUFQIGhhbmRsZSBpcyAKKy8vCQkJcmVxdWlyZWQuIAorLy8KKy8vCQkJSWYgZXh0ZXJuYWwgc2NhbmxpbmUgYnVmZmVyIGlzIHVzZWQsIHRoZW4gdGhlIGFwcGxpY2F0aW9uIHNob3VsZCBkZXN0cm95IHRoZSBidWZmZXIKKy8vCQkJYnkgaXRzZWxmLiBGUERGQml0bWFwX0Rlc3Ryb3kgZnVuY3Rpb24gd2lsbCBub3QgZGVzdHJveSB0aGUgYnVmZmVyLgorLy8KK0RMTEVYUE9SVCBGUERGX0JJVE1BUCBTVERDQUxMIEZQREZCaXRtYXBfQ3JlYXRlRXgoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgZm9ybWF0LCB2b2lkKiBmaXJzdF9zY2FuLCBpbnQgc3RyaWRlKTsKKworLy8gRnVuY3Rpb246IEZQREZCaXRtYXBfRmlsbFJlY3QKKy8vCQkJRmlsbCBhIHJlY3RhbmdsZSBhcmVhIGluIGFuIEZYRElCLgorLy8gUGFyYW1ldGVyczoKKy8vCQkJYml0bWFwCQktCVRoZSBoYW5kbGUgdG8gdGhlIGJpdG1hcC4gUmV0dXJuZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uCisvLwkJCWxlZnQJCS0JVGhlIGxlZnQgc2lkZSBwb3NpdGlvbi4gU3RhcnRpbmcgZnJvbSAwIGF0IHRoZSBsZWZ0LW1vc3QgcGl4ZWwuCisvLwkJCXRvcAkJCS0JVGhlIHRvcCBzaWRlIHBvc2l0aW9uLiBTdGFydGluZyBmcm9tIDAgYXQgdGhlIHRvcC1tb3N0IHNjYW4gbGluZS4KKy8vCQkJd2lkdGgJCS0JTnVtYmVyIG9mIHBpeGVscyB0byBiZSBmaWxsZWQgaW4gZWFjaCBzY2FuIGxpbmUuCisvLwkJCWhlaWdodAkJLQlOdW1iZXIgb2Ygc2NhbiBsaW5lcyB0byBiZSBmaWxsZWQuCisvLwkJCXJlZAkJCS0JQSBudW1iZXIgZnJvbSAwIHRvIDI1NSwgaWRlbnRpZnlpbmcgdGhlIHJlZCBpbnRlbnNpdHkuCisvLwkJCWdyZWVuCQktCUEgbnVtYmVyIGZyb20gMCB0byAyNTUsIGlkZW50aWZ5aW5nIHRoZSBncmVlbiBpbnRlbnNpdHkuCisvLwkJCWJsdWUJCS0JQSBudW1iZXIgZnJvbSAwIHRvIDI1NSwgaWRlbnRpZnlpbmcgdGhlIGJsdWUgaW50ZW5zaXR5LgorLy8JCQlhbHBoYQkJLQkoT25seSBpZiB0aGUgYWxwaGEgY2hhbm5lbGVkIGlzIHVzZWQgd2hlbiBiaXRtYXAgY3JlYXRlZCkgQSBudW1iZXIgZnJvbSAwIHRvIDI1NSwKKy8vCQkJCQkJCWlkZW50aWZ5aW5nIHRoZSBhbHBoYSB2YWx1ZS4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJTm9uZS4KKy8vIENvbW1lbnRzOgorLy8JCQlUaGlzIGZ1bmN0aW9uIHNldCB0aGUgY29sb3IgYW5kIChvcHRpb25hbGx5KSBhbHBoYSB2YWx1ZSBpbiBzcGVjaWZpZWQgcmVnaW9uIG9mIHRoZSBiaXRtYXAuCisvLwkJCU5PVEU6IElmIGFscGhhIGNoYW5uZWwgaXMgdXNlZCwgdGhpcyBmdW5jdGlvbiBkb2VzIE5PVCBjb21wb3NpdGUgdGhlIGJhY2tncm91bmQgd2l0aCB0aGUgc291cmNlIGNvbG9yLAorLy8JCQlpbnN0ZWFkIHRoZSBiYWNrZ3JvdW5kIHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIHNvdXJjZSBjb2xvciBhbmQgYWxwaGEuCisvLwkJCUlmIGFscGhhIGNoYW5uZWwgaXMgbm90IHVzZWQsIHRoZSAiYWxwaGEiIHBhcmFtZXRlciBpcyBpZ25vcmVkLgorLy8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkJpdG1hcF9GaWxsUmVjdChGUERGX0JJVE1BUCBiaXRtYXAsIGludCBsZWZ0LCBpbnQgdG9wLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIAorCQkJCQkJCQkJaW50IHJlZCwgaW50IGdyZWVuLCBpbnQgYmx1ZSwgaW50IGFscGhhKTsKKworLy8gRnVuY3Rpb246IEZQREZCaXRtYXBfR2V0QnVmZmVyCisvLwkJCUdldCBkYXRhIGJ1ZmZlciBvZiBhbiBGWERJQgorLy8gUGFyYW1ldGVyczoKKy8vCQkJYml0bWFwCQktCUhhbmRsZSB0byB0aGUgYml0bWFwLiBSZXR1cm5lZCBieSBGUERGQml0bWFwX0NyZWF0ZSBmdW5jdGlvbi4KKy8vIFJldHVybiB2YWx1ZToKKy8vCQkJVGhlIHBvaW50ZXIgdG8gdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGJpdG1hcCBidWZmZXIuCisvLyBDb21tZW50czoKKy8vCQkJVGhlIHN0cmlkZSBtYXkgYmUgbW9yZSB0aGFuIHdpZHRoICogbnVtYmVyIG9mIGJ5dGVzIHBlciBwaXhlbAorLy8JCQlBcHBsaWNhdGlvbnMgY2FuIHVzZSB0aGlzIGZ1bmN0aW9uIHRvIGdldCB0aGUgYml0bWFwIGJ1ZmZlciBwb2ludGVyLCB0aGVuIG1hbmlwdWxhdGUgYW55IGNvbG9yCisvLwkJCWFuZC9vciBhbHBoYSB2YWx1ZXMgZm9yIGFueSBwaXhlbHMgaW4gdGhlIGJpdG1hcC4KK0RMTEVYUE9SVCB2b2lkKiBTVERDQUxMIEZQREZCaXRtYXBfR2V0QnVmZmVyKEZQREZfQklUTUFQIGJpdG1hcCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGQml0bWFwX0dldFdpZHRoCisvLwkJCUdldCB3aWR0aCBvZiBhbiBGWERJQi4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWJpdG1hcAkJLQlIYW5kbGUgdG8gdGhlIGJpdG1hcC4gUmV0dXJuZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRoZSBudW1iZXIgb2YgcGl4ZWxzIGluIGEgaG9yaXpvbnRhbCBsaW5lIG9mIHRoZSBiaXRtYXAuCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkJpdG1hcF9HZXRXaWR0aChGUERGX0JJVE1BUCBiaXRtYXApOworCisvLyBGdW5jdGlvbjogRlBERkJpdG1hcF9HZXRIZWlnaHQKKy8vCQkJR2V0IGhlaWdodCBvZiBhbiBGWERJQi4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWJpdG1hcAkJLQlIYW5kbGUgdG8gdGhlIGJpdG1hcC4gUmV0dXJuZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRoZSBudW1iZXIgb2YgcGl4ZWxzIGluIGEgdmVydGljYWwgbGluZSBvZiB0aGUgYml0bWFwLgorRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZCaXRtYXBfR2V0SGVpZ2h0KEZQREZfQklUTUFQIGJpdG1hcCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGQml0bWFwX0dldFN0cmlkZQorLy8JCQlHZXQgbnVtYmVyIG9mIGJ5dGVzIGZvciBlYWNoIHNjYW4gbGluZSBpbiB0aGUgYml0bWFwIGJ1ZmZlci4KKy8vIFBhcmFtZXRlcnM6CisvLwkJCWJpdG1hcAkJLQlIYW5kbGUgdG8gdGhlIGJpdG1hcC4gUmV0dXJuZWQgYnkgRlBERkJpdG1hcF9DcmVhdGUgZnVuY3Rpb24uCisvLyBSZXR1cm4gdmFsdWU6CisvLwkJCVRoZSBudW1iZXIgb2YgYnl0ZXMgZm9yIGVhY2ggc2NhbiBsaW5lIGluIHRoZSBiaXRtYXAgYnVmZmVyLgorLy8gQ29tbWVudHM6CisvLwkJCVRoZSBzdHJpZGUgbWF5IGJlIG1vcmUgdGhhbiB3aWR0aCAqIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQml0bWFwX0dldFN0cmlkZShGUERGX0JJVE1BUCBiaXRtYXApOworCisvLyBGdW5jdGlvbjogRlBERkJpdG1hcF9EZXN0cm95CisvLwkJCURlc3Ryb3kgYW4gRlhESUIgYW5kIHJlbGVhc2UgYWxsIHJlbGF0ZWQgYnVmZmVycy4gCisvLyBQYXJhbWV0ZXJzOgorLy8JCQliaXRtYXAJCS0JSGFuZGxlIHRvIHRoZSBiaXRtYXAuIFJldHVybmVkIGJ5IEZQREZCaXRtYXBfQ3JlYXRlIGZ1bmN0aW9uLgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOb25lLgorLy8gQ29tbWVudHM6CisvLwkJCVRoaXMgZnVuY3Rpb24gd2lsbCBub3QgZGVzdHJveSBhbnkgZXh0ZXJuYWwgYnVmZmVyLgorLy8KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkJpdG1hcF9EZXN0cm95KEZQREZfQklUTUFQIGJpdG1hcCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGX1ZJRVdFUlJFRl9HZXRQcmludFNjYWxpbmcKKy8vCQkJV2hldGhlciB0aGUgUERGIGRvY3VtZW50IHByZWZlcnMgdG8gYmUgc2NhbGVkIG9yIG5vdC4KKy8vIFBhcmFtZXRlcnM6IAorLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byB0aGUgbG9hZGVkIGRvY3VtZW50LgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlOb25lLgorLy8KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX1ZJRVdFUlJFRl9HZXRQcmludFNjYWxpbmcoRlBERl9ET0NVTUVOVCBkb2N1bWVudCk7CisKKy8vIEZ1bmN0aW9uOiBGUERGX0dldE5hbWVkRGVzdEJ5TmFtZQorLy8JCQlnZXQgYSBzcGVjaWFsIGRlc3QgaGFuZGxlIGJ5IHRoZSBpbmRleC4KKy8vIFBhcmFtZXRlcnM6IAorLy8JCQlkb2N1bWVudAktCUhhbmRsZSB0byB0aGUgbG9hZGVkIGRvY3VtZW50LgorLy8JCQluYW1lCQktCVRoZSBuYW1lIG9mIGEgc3BlY2lhbCBuYW1lZCBkZXN0LgorLy8gUmV0dXJuIHZhbHVlOgorLy8JCQlUaGUgaGFuZGxlIG9mIHRoZSBkZXN0LgorLy8KK0RMTEVYUE9SVCBGUERGX0RFU1QgU1REQ0FMTCBGUERGX0dldE5hbWVkRGVzdEJ5TmFtZShGUERGX0RPQ1VNRU5UIGRvY3VtZW50LEZQREZfQllURVNUUklORyBuYW1lKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCit9OworI2VuZGlmCisKKyNlbmRpZiAvLyBfRlBERlZJRVdfSF8KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2FjdGlvbmhhbmRsZXIuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2FjdGlvbmhhbmRsZXIuaAppbmRleCBjOTNlNjc5Li4wZmZiZGRiIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnNka19hY3Rpb25oYW5kbGVyLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZzZGtfYWN0aW9uaGFuZGxlci5oCkBAIC0xLDgyICsxLDgyIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GU0RLX0FDVElPTkhBTkRMRVJfSF8NCi0jZGVmaW5lIF9GU0RLX0FDVElPTkhBTkRMRVJfSF8NCi0NCi0NCi1jbGFzcyBDUERGRG9jX0Vudmlyb25tZW50Ow0KLWNsYXNzIElGWEpTX1J1bnRpbWU7DQotDQotY2xhc3MgQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcg0KLXsNCi1wdWJsaWM6DQotCUZYX0JPT0wJRG9BY3Rpb25fSGlkZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOw0KLQlGWF9CT09MCURvQWN0aW9uX1N1Ym1pdEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsNCi0JRlhfQk9PTAlEb0FjdGlvbl9SZXNldEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsNCi0JRlhfQk9PTAlEb0FjdGlvbl9JbXBvcnREYXRhKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7DQotfTsNCi0NCi1jbGFzcyBDUERGU0RLX01lZGlhQWN0aW9uSGFuZGxlcg0KLXsNCi1wdWJsaWM6DQotCUZYX0JPT0wJRG9BY3Rpb25fUmVuZGl0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7DQotCUZYX0JPT0wJRG9BY3Rpb25fU291bmQoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsNCi0JRlhfQk9PTAlEb0FjdGlvbl9Nb3ZpZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOw0KLX07DQotDQotY2xhc3MgIENQREZTREtfQWN0aW9uSGFuZGxlciAvKjogcHVibGljIENSZWFkZXJfQWN0aW9uSGFuZGxlciovDQotew0KLXB1YmxpYzoNCi0JQ1BERlNES19BY3Rpb25IYW5kbGVyKENQREZEb2NfRW52aXJvbm1lbnQqIHBFdmkpOw0KLQl2aXJ0dWFsIH5DUERGU0RLX0FjdGlvbkhhbmRsZXIoKTsNCi0JDQotCXZpcnR1YWwgdm9pZAkJRGVzdHJveSgpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCURvQWN0aW9uX0RvY09wZW4oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENQREZTREtfRG9jVmlldyAqcERvY1ZpZXcqLyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJRG9BY3Rpb25fSmF2YVNjcmlwdChjb25zdCBDUERGX0FjdGlvbiYgSnNBY3Rpb24sQ0ZYX1dpZGVTdHJpbmcgY3NKU05hbWUsIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCURvQWN0aW9uX1BhZ2UoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgZW51bSBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVUeXBlLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3ICpwRG9jVmlldyovKTsNCi0JdmlydHVhbCBGWF9CT09MCQlEb0FjdGlvbl9Eb2N1bWVudChjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBlbnVtIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZVR5cGUsIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCURvQWN0aW9uX0Jvb2tNYXJrKENQREZfQm9va21hcmsgKnBCb29rTWFyaywgY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3ICpwRG9jVmlldyovKTsJDQotCXZpcnR1YWwgRlhfQk9PTAkJRG9BY3Rpb25fU2NyZWVuKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LC8qIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcsKi8gQ1BERlNES19Bbm5vdCogcFNjcmVlbik7DQotCXZpcnR1YWwgRlhfQk9PTAkJRG9BY3Rpb25fTGluayhjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3ICpwRG9jVmlldyovKTsNCi0JdmlydHVhbCBGWF9CT09MCQlEb0FjdGlvbl9GaWVsZChjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgLypDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3LCovIENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCBQREZTREtfRmllbGRBY3Rpb24mIGRhdGEpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCURvQWN0aW9uX0ZpZWxkSmF2YVNjcmlwdChjb25zdCBDUERGX0FjdGlvbiYgSnNBY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgUERGU0RLX0ZpZWxkQWN0aW9uJiBkYXRhKTsNCi1wdWJsaWM6DQotCXZvaWQJCQkJU2V0Rm9ybUFjdGlvbkhhbmRsZXIoQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlciogcEhhbmRsZXIpOw0KLQl2b2lkCQkJCVNldE1lZGlhQWN0aW9uSGFuZGxlcihDUERGU0RLX01lZGlhQWN0aW9uSGFuZGxlciogcEhhbmRsZXIpOw0KLQkNCi1wcml2YXRlOg0KLQlGWF9CT09MCQkJCUV4ZWN1dGVEb2N1bWVudE9wZW5BY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCAvKkNSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcsKi8gQ0ZYX1B0ckxpc3QmIGxpc3QpOw0KLQlGWF9CT09MCQkJCUV4ZWN1dGVEb2N1bWVudFBhZ2VBY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIC8qQ1JlYWRlcl9Eb2NWaWV3ICpwRG9jVmlldywqLyBDRlhfUHRyTGlzdCYgbGlzdCk7DQotCUZYX0JPT0wJCQkJRXhlY3V0ZUZpZWxkQWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCAvKkNSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcsKi8gQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIFBERlNES19GaWVsZEFjdGlvbiYgZGF0YSwgQ0ZYX1B0ckxpc3QmIGxpc3QpOw0KLQlGWF9CT09MCQkJCUV4ZWN1dGVTY3JlZW5BY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIC8qQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldywqLyBDUERGU0RLX0Fubm90KiBwU2NyZWVuLCBDRlhfUHRyTGlzdCYgbGlzdCk7DQotCUZYX0JPT0wJCQkJRXhlY3V0ZUJvb2tNYXJrKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgLypDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIENQREZfQm9va21hcmsqIHBCb29rbWFyaywgQ0ZYX1B0ckxpc3QmIGxpc3QpOw0KLQlGWF9CT09MCQkJCUV4ZWN1dGVMaW5rQWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgLypDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIENGWF9QdHJMaXN0JiBsaXN0KTsNCi0JDQotCXZvaWQJCQkJRG9BY3Rpb25fTm9Kcyhjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldyovKTsNCi0Jdm9pZAkJCQlSdW5Eb2N1bWVudFBhZ2VKYXZhU2NyaXB0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0KTsNCi0Jdm9pZAkJCQlSdW5Eb2N1bWVudE9wZW5KYXZhU2NyaXB0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNTY3JpcHROYW1lLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0KTsNCi0Jdm9pZAkJCQlSdW5GaWVsZEphdmFTY3JpcHQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBQREZTREtfRmllbGRBY3Rpb24mIGRhdGEsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQpOw0KLQkNCi1wcml2YXRlOg0KLQlGWF9CT09MCQkJCUlzVmFsaWRGaWVsZChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRGljdGlvbmFyeSogcEZpZWxkRGljdCk7DQotCUZYX0JPT0wJCQkJSXNWYWxpZERvY1ZpZXcoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcqLyk7DQotCQ0KLQl2b2lkCQkJCURvQWN0aW9uX0dvVG8oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCAvKkNSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcsKi8gY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbik7DQotCXZvaWQJCQkJRG9BY3Rpb25fR29Ub1IoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKTsNCi0Jdm9pZAkJCQlEb0FjdGlvbl9MYXVuY2goQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKTsNCi0Jdm9pZAkJCQlEb0FjdGlvbl9VUkkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKTsNCi0Jdm9pZAkJCQlEb0FjdGlvbl9OYW1lZChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pOw0KLQl2b2lkCQkJCURvQWN0aW9uX1NldE9DR1N0YXRlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgLypDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pOw0KLQkNCi1wcml2YXRlOg0KLQlDUERGRG9jX0Vudmlyb25tZW50KgkJCW1fcEV2aTsNCi0JQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcioJCW1fcEZvcm1BY3Rpb25IYW5kbGVyOw0KLQlDUERGU0RLX01lZGlhQWN0aW9uSGFuZGxlcioJCW1fcE1lZGlhQWN0aW9uSGFuZGxlcjsNCi19Ow0KLQ0KLSNlbmRpZiAvL19CQV9BQ1RJT05IQU5ETEVSX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRlNES19BQ1RJT05IQU5ETEVSX0hfCisjZGVmaW5lIF9GU0RLX0FDVElPTkhBTkRMRVJfSF8KKworCitjbGFzcyBDUERGRG9jX0Vudmlyb25tZW50OworY2xhc3MgSUZYSlNfUnVudGltZTsKKworY2xhc3MgQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcgoreworcHVibGljOgorCUZYX0JPT0wJRG9BY3Rpb25fSGlkZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOworCUZYX0JPT0wJRG9BY3Rpb25fU3VibWl0Rm9ybShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOworCUZYX0JPT0wJRG9BY3Rpb25fUmVzZXRGb3JtKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7CisJRlhfQk9PTAlEb0FjdGlvbl9JbXBvcnREYXRhKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7Cit9OworCitjbGFzcyBDUERGU0RLX01lZGlhQWN0aW9uSGFuZGxlcgoreworcHVibGljOgorCUZYX0JPT0wJRG9BY3Rpb25fUmVuZGl0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCk7CisJRlhfQk9PTAlEb0FjdGlvbl9Tb3VuZChjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOworCUZYX0JPT0wJRG9BY3Rpb25fTW92aWUoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KTsKK307CisKK2NsYXNzICBDUERGU0RLX0FjdGlvbkhhbmRsZXIgLyo6IHB1YmxpYyBDUmVhZGVyX0FjdGlvbkhhbmRsZXIqLworeworcHVibGljOgorCUNQREZTREtfQWN0aW9uSGFuZGxlcihDUERGRG9jX0Vudmlyb25tZW50KiBwRXZpKTsKKwl2aXJ0dWFsIH5DUERGU0RLX0FjdGlvbkhhbmRsZXIoKTsKKwkKKwl2aXJ0dWFsIHZvaWQJCURlc3Ryb3koKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCURvQWN0aW9uX0RvY09wZW4oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENQREZTREtfRG9jVmlldyAqcERvY1ZpZXcqLyk7CisJdmlydHVhbCBGWF9CT09MCQlEb0FjdGlvbl9KYXZhU2NyaXB0KGNvbnN0IENQREZfQWN0aW9uJiBKc0FjdGlvbixDRlhfV2lkZVN0cmluZyBjc0pTTmFtZSwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcqLyk7CisJdmlydHVhbCBGWF9CT09MCQlEb0FjdGlvbl9QYWdlKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIGVudW0gQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlVHlwZSwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcqLyk7CisJdmlydHVhbCBGWF9CT09MCQlEb0FjdGlvbl9Eb2N1bWVudChjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBlbnVtIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZVR5cGUsIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pOworCXZpcnR1YWwgRlhfQk9PTAkJRG9BY3Rpb25fQm9va01hcmsoQ1BERl9Cb29rbWFyayAqcEJvb2tNYXJrLCBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pOwkKKwl2aXJ0dWFsIEZYX0JPT0wJCURvQWN0aW9uX1NjcmVlbihjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwvKiBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3LCovIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCXZpcnR1YWwgRlhfQk9PTAkJRG9BY3Rpb25fTGluayhjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3ICpwRG9jVmlldyovKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCURvQWN0aW9uX0ZpZWxkKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCAvKkNSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcsKi8gQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIFBERlNES19GaWVsZEFjdGlvbiYgZGF0YSk7CisJdmlydHVhbCBGWF9CT09MCQlEb0FjdGlvbl9GaWVsZEphdmFTY3JpcHQoY29uc3QgQ1BERl9BY3Rpb24mIEpzQWN0aW9uLCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIFBERlNES19GaWVsZEFjdGlvbiYgZGF0YSk7CitwdWJsaWM6CisJdm9pZAkJCQlTZXRGb3JtQWN0aW9uSGFuZGxlcihDUERGU0RLX0Zvcm1BY3Rpb25IYW5kbGVyKiBwSGFuZGxlcik7CisJdm9pZAkJCQlTZXRNZWRpYUFjdGlvbkhhbmRsZXIoQ1BERlNES19NZWRpYUFjdGlvbkhhbmRsZXIqIHBIYW5kbGVyKTsKKwkKK3ByaXZhdGU6CisJRlhfQk9PTAkJCQlFeGVjdXRlRG9jdW1lbnRPcGVuQWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgLypDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3LCovIENGWF9QdHJMaXN0JiBsaXN0KTsKKwlGWF9CT09MCQkJCUV4ZWN1dGVEb2N1bWVudFBhZ2VBY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIC8qQ1JlYWRlcl9Eb2NWaWV3ICpwRG9jVmlldywqLyBDRlhfUHRyTGlzdCYgbGlzdCk7CisJRlhfQk9PTAkJCQlFeGVjdXRlRmllbGRBY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIC8qQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldywqLyBDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgUERGU0RLX0ZpZWxkQWN0aW9uJiBkYXRhLCBDRlhfUHRyTGlzdCYgbGlzdCk7CisJRlhfQk9PTAkJCQlFeGVjdXRlU2NyZWVuQWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCAvKkNSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcsKi8gQ1BERlNES19Bbm5vdCogcFNjcmVlbiwgQ0ZYX1B0ckxpc3QmIGxpc3QpOworCUZYX0JPT0wJCQkJRXhlY3V0ZUJvb2tNYXJrKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgLypDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIENQREZfQm9va21hcmsqIHBCb29rbWFyaywgQ0ZYX1B0ckxpc3QmIGxpc3QpOworCUZYX0JPT0wJCQkJRXhlY3V0ZUxpbmtBY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCAvKkNSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcsKi8gQ0ZYX1B0ckxpc3QmIGxpc3QpOworCQorCXZvaWQJCQkJRG9BY3Rpb25fTm9Kcyhjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldyovKTsKKwl2b2lkCQkJCVJ1bkRvY3VtZW50UGFnZUphdmFTY3JpcHQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQpOworCXZvaWQJCQkJUnVuRG9jdW1lbnRPcGVuSmF2YVNjcmlwdChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzU2NyaXB0TmFtZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNjcmlwdCk7CisJdm9pZAkJCQlSdW5GaWVsZEphdmFTY3JpcHQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBQREZTREtfRmllbGRBY3Rpb24mIGRhdGEsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQpOworCQorcHJpdmF0ZToKKwlGWF9CT09MCQkJCUlzVmFsaWRGaWVsZChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRGljdGlvbmFyeSogcEZpZWxkRGljdCk7CisJRlhfQk9PTAkJCQlJc1ZhbGlkRG9jVmlldyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldyovKTsKKwkKKwl2b2lkCQkJCURvQWN0aW9uX0dvVG8oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCAvKkNSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcsKi8gY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbik7CisJdm9pZAkJCQlEb0FjdGlvbl9Hb1RvUihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pOworCXZvaWQJCQkJRG9BY3Rpb25fTGF1bmNoKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbik7CisJdm9pZAkJCQlEb0FjdGlvbl9VUkkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKTsKKwl2b2lkCQkJCURvQWN0aW9uX05hbWVkKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbik7CisJdm9pZAkJCQlEb0FjdGlvbl9TZXRPQ0dTdGF0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIC8qQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldywqLyBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKTsKKwkKK3ByaXZhdGU6CisJQ1BERkRvY19FbnZpcm9ubWVudCoJCQltX3BFdmk7CisJQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcioJCW1fcEZvcm1BY3Rpb25IYW5kbGVyOworCUNQREZTREtfTWVkaWFBY3Rpb25IYW5kbGVyKgkJbV9wTWVkaWFBY3Rpb25IYW5kbGVyOworfTsKKworI2VuZGlmIC8vX0JBX0FDVElPTkhBTkRMRVJfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZzZGtfYW5ub3RoYW5kbGVyLmggYi9mcGRmc2RrL2luY2x1ZGUvZnNka19hbm5vdGhhbmRsZXIuaAppbmRleCBkYzJlNDBhLi5mZWMzZDkyIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnNka19hbm5vdGhhbmRsZXIuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnNka19hbm5vdGhhbmRsZXIuaApAQCAtMSwyNDggKzEsMjQ4IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GU0RLX0FOTk9USEFORExFUl9IXw0KLSNkZWZpbmUgX0ZTREtfQU5OT1RIQU5ETEVSX0hfDQotDQotDQotY2xhc3MgQ1BERkRvY19FbnZpcm9ubWVudDsNCi1jbGFzcyBDRkZMX0lGb3JtRmlsbGVyOw0KLWNsYXNzIENQREZTREtfUGFnZVZpZXc7DQotY2xhc3MgSVBERlNES19Bbm5vdEhhbmRsZXINCi17DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIH5JUERGU0RLX0Fubm90SGFuZGxlcigpIHt9Ow0KLQ0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXRUeXBlKCkgPSAwOw0KLQ0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXROYW1lKCkgPSAwOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuQW5zd2VyKENQREZTREtfQW5ub3QqIHBBbm5vdCkgPSAwOw0KLQkNCi0NCi0JdmlydHVhbCBDUERGU0RLX0Fubm90KgkJTmV3QW5ub3QoQ1BERl9Bbm5vdCogcEFubm90LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZSkgPSAwOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJUmVsZWFzZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkgPSAwOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJRGVsZXRlQW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90KSA9IDA7DQotCQ0KLQ0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRWaWV3QkJveChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCkgPSAwOw0KLQkNCi0JdmlydHVhbCBGWF9CT09MCQkJCUhpdFRlc3QoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA9IDA7DQotCQ0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25EcmF3KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCANCi0JCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQlGWF9EV09SRCBkd0ZsYWdzKSA9IDA7DQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25EcmF3U2xlZXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIA0KLQkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCWNvbnN0IENQREZfUmVjdCYgcmNXaW5kb3csIEZYX0RXT1JEIGR3RmxhZ3MpID0gMDsNCi0JDQotDQotCQ0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25DcmVhdGUoQ1BERlNES19Bbm5vdCogcEFubm90KSA9IDA7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbkxvYWQoQ1BERlNES19Bbm5vdCogcEFubm90KSA9IDA7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbkRlbGV0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpID0gMDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uUmVsZWFzZShDUERGU0RLX0Fubm90KiBwQW5ub3QpID0gMDsNCi0JDQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbk1vdXNlRW50ZXIoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPbk1vdXNlRXhpdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpID0gMDsNCi0JDQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA9IDA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgPSAwOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA9IDA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbk1vdXNlTW92ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgPSAwOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25Nb3VzZVdoZWVsKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uUkJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uUkJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA9IDA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25EYmxDbGsoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpID0gMDsNCi0vL2J5IHdqbS4NCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZ3MpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIGludCBuS2V5Q29kZSwgaW50IG5GbGFnKSA9IDA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktleVVwKENQREZTREtfQW5ub3QqIHBBbm5vdCwgaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpID0wIDsNCi0NCi0JdmlydHVhbAl2b2lkCQkJCU9uRGVTZWxlY3RlZChDUERGU0RLX0Fubm90KiBwQW5ub3QpID0gMDsNCi0JdmlydHVhbAl2b2lkCQkJCU9uU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KSA9IDA7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPblNldEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpID0gMDsNCi0NCi19Ow0KLQ0KLQ0KLWNsYXNzIENQREZTREtfQkZBbm5vdEhhbmRsZXI6cHVibGljIElQREZTREtfQW5ub3RIYW5kbGVyDQotew0KLXB1YmxpYzoNCi0JQ1BERlNES19CRkFubm90SGFuZGxlcihDUERGRG9jX0Vudmlyb25tZW50KglwQXBwKTptX3BGb3JtRmlsbGVyKE5VTEwpLG1fcEFwcChwQXBwKSB7fQ0KLQl2aXJ0dWFsCX5DUERGU0RLX0JGQW5ub3RIYW5kbGVyKCkge30NCi1wdWJsaWM6DQotDQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCUdldFR5cGUoKSAge3JldHVybiBDRlhfQnl0ZVN0cmluZygiV2lkZ2V0Iik7fQ0KLQ0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXROYW1lKCkgIHtyZXR1cm4gQ0ZYX0J5dGVTdHJpbmcoIldpZGdldEhhbmRsZXIiKTt9DQotCQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQ2FuQW5zd2VyKENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotDQotCXZpcnR1YWwgQ1BERlNES19Bbm5vdCoJCU5ld0Fubm90KENQREZfQW5ub3QqIHBBbm5vdCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2UpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJUmVsZWFzZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkgIDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCURlbGV0ZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkge30NCi0JDQotDQotCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUdldFZpZXdCQm94KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KSA7DQotCQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJSGl0VGVzdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQkNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgDQotCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJIEZYX0RXT1JEIGR3RmxhZ3MpIDsNCi0JDQotCXZpcnR1YWwgdm9pZAkJCQlPbkRyYXdTbGVlcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgDQotCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJY29uc3QgQ1BERl9SZWN0JiByY1dpbmRvdywgRlhfRFdPUkQgZHdGbGFncykge30NCi0JDQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbkNyZWF0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpIDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uTG9hZChDUERGU0RLX0Fubm90KiBwQW5ub3QpIDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uRGVsZXRlKENQREZTREtfQW5ub3QqIHBBbm5vdCkge30NCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uUmVsZWFzZShDUERGU0RLX0Fubm90KiBwQW5ub3QpIHt9DQotCQ0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25Nb3VzZUVudGVyKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZykgOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25Nb3VzZUV4aXQoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKSA7DQotCQ0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25Nb3VzZU1vdmUoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTW91c2VXaGVlbChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25SQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSB7cmV0dXJuIEZBTFNFO30NCi0JDQotLy9ieSB3am0uDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWdzKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIGludCBuS2V5Q29kZSwgaW50IG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uS2V5VXAoQ1BERlNES19Bbm5vdCogcEFubm90LCBpbnQgbktleUNvZGUsIGludCBuRmxhZyk7DQotDQotCXZpcnR1YWwJdm9pZAkJCQlPbkRlU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KSB7fQ0KLQl2aXJ0dWFsCXZvaWQJCQkJT25TZWxlY3RlZChDUERGU0RLX0Fubm90KiBwQW5ub3QpIHt9DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPblNldEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25LaWxsRm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZyk7DQotDQotCXZvaWQJCQkJCQlTZXRGb3JtRmlsbGVyKENGRkxfSUZvcm1GaWxsZXIqIHBGaWxsZXIpe21fcEZvcm1GaWxsZXIgPSBwRmlsbGVyO30NCi0JQ0ZGTF9JRm9ybUZpbGxlcioJCQlHZXRGb3JtRmlsbGVyKCkge3JldHVybiBtX3BGb3JtRmlsbGVyO30NCi1wcml2YXRlOg0KLQ0KLQlDUERGRG9jX0Vudmlyb25tZW50KgkJbV9wQXBwOw0KLQlDRkZMX0lGb3JtRmlsbGVyKgkJCW1fcEZvcm1GaWxsZXI7DQotfTsNCi0NCi0jZGVmaW5lIENCQV9Bbm5vdEhhbmRsZXJBcnJheSBDRlhfQXJyYXlUZW1wbGF0ZTxJUERGU0RLX0Fubm90SGFuZGxlcio+DQotY2xhc3MgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3INCi17DQotcHVibGljOg0KLQkvLyBEZXN0cm95IHRoZSBoYW5kbGVyDQotCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHApOw0KLQl2aXJ0dWFsIH5DUERGU0RLX0Fubm90SGFuZGxlck1ncigpIDsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQlSZWdpc3RlckFubm90SGFuZGxlcihJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlcik7DQotCXZvaWQJCQkJCQlVblJlZ2lzdGVyQW5ub3RIYW5kbGVyKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyKTsNCi0NCi0JdmlydHVhbCBDUERGU0RLX0Fubm90KgkJTmV3QW5ub3QoQ1BERl9Bbm5vdCAqIHBBbm5vdCwgQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3KTsNCi0JdmlydHVhbCB2b2lkCQkJCVJlbGVhc2VBbm5vdChDUERGU0RLX0Fubm90ICogcEFubm90KTsNCi0JDQotCXZpcnR1YWwgdm9pZAkJCQlBbm5vdF9PbkNyZWF0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJQW5ub3RfT25Mb2FkKENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotcHVibGljOg0KLQlJUERGU0RLX0Fubm90SGFuZGxlcioJCUdldEFubm90SGFuZGxlcihDUERGU0RLX0Fubm90KiBwQW5ub3QpIGNvbnN0Ow0KLQl2aXJ0dWFsIHZvaWQJCQkJQW5ub3RfT25EcmF3KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LA0KLQkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSxGWF9EV09SRCBkd0ZsYWdzKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCUFubm90X09uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncyk7DQotCXZpcnR1YWwgdm9pZAkJCQlBbm5vdF9Pbk1vdXNlRXhpdChDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncyk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfT25MQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfT25Nb3VzZU1vdmUoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCUFubm90X09uTW91c2VXaGVlbChDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PblJCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PblJCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQ0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFncyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PbktleURvd24oQ1BERlNES19Bbm5vdCogcEFubm90LCBpbnQgbktleUNvZGUsIGludCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PbktleVVwKENQREZTREtfQW5ub3QqIHBBbm5vdCwgaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfT25TZXRGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCUFubm90X09uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpOw0KLQ0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCUFubm90X09uR2V0Vmlld0JCb3goQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfT25IaXRUZXN0KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotDQotcHJpdmF0ZToNCi0JSVBERlNES19Bbm5vdEhhbmRsZXIqCQkJR2V0QW5ub3RIYW5kbGVyKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzVHlwZSkgY29uc3Q7DQotCUNQREZTREtfQW5ub3QqCQkJCUdldE5leHRBbm5vdChDUERGU0RLX0Fubm90KiBwU0RLQW5ub3QsRlhfQk9PTCBiTmV4dCk7DQotcHJpdmF0ZToNCi0JQ0JBX0Fubm90SGFuZGxlckFycmF5CQltX0hhbmRsZXJzOw0KLQlDRlhfTWFwQnl0ZVN0cmluZ1RvUHRyCQltX21hcFR5cGUySGFuZGxlcjsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCoJCW1fcEFwcDsNCi19Ow0KLQ0KLS8vI2RlZmluZSBDQkZfUGFnZTJBY2Nlc3NpYmxlCSBDRlhfTWFwUHRyVGVtcGxhdGU8Q1BERlNES19QYWdlVmlldyosIElBY2Nlc3NpYmxlKj4NCi0NCi10eXBlZGVmIGludCAoKkFJX0NPTVBBUkUpIChDUERGU0RLX0Fubm90KiBwMSwgQ1BERlNES19Bbm5vdCogcDIpOw0KLQ0KLWNsYXNzIENQREZTREtfQW5ub3RJdGVyYXRvcg0KLXsNCi1wcm90ZWN0ZWQ6DQotCUNQREZTREtfQW5ub3QqCU5leHRBbm5vdCAoY29uc3QgQ1BERlNES19Bbm5vdCogcEN1cnJlbnQpIDsNCi0JQ1BERlNES19Bbm5vdCoJUHJldkFubm90IChjb25zdCBDUERGU0RLX0Fubm90KiBwQ3VycmVudCkgOwkNCi0JQ1BERlNES19Bbm5vdCoJTmV4dEFubm90KGludCYgaW5kZXggKSA7DQotCUNQREZTREtfQW5ub3QqCVByZXZBbm5vdChpbnQmIGluZGV4ICkgOw0KLXB1YmxpYzoNCi0gICAgQ1BERlNES19Bbm5vdEl0ZXJhdG9yKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIEZYX0JPT0wgYlJldmVyc2UsDQotCQlGWF9CT09MIGJJZ25vcmVUb3Btb3N0PUZBTFNFLEZYX0JPT0wgYkNpcmNsZT1GQUxTRSxDRlhfUHRyQXJyYXkqIHBMaXN0PU5VTEwpOwkNCi0JdmlydHVhbCBDUERGU0RLX0Fubm90KglOZXh0IChjb25zdCBDUERGU0RLX0Fubm90KiBwQ3VycmVudCkgOw0KLQl2aXJ0dWFsIENQREZTREtfQW5ub3QqCVByZXYgKGNvbnN0IENQREZTREtfQW5ub3QqIHBDdXJyZW50KSA7CQ0KLQl2aXJ0dWFsIENQREZTREtfQW5ub3QqCU5leHQoaW50JiBpbmRleCApIDsNCi0JdmlydHVhbCBDUERGU0RLX0Fubm90KglQcmV2KGludCYgaW5kZXggKSA7DQotCXZpcnR1YWwgaW50ICAgICAgICAgICAgIENvdW50KCl7cmV0dXJuIG1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldFNpemUoKTt9DQotCQ0KLQl2aXJ0dWFsIEZYX0JPT0wgICAgICAgICBJbml0SXRlcmF0b3JBbm5vdExpc3QoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldyxDRlhfUHRyQXJyYXkqIHBMaXN0PU5VTEwpOw0KLQkNCi0Jdm9pZAkJCQkJSW5zZXJ0U29ydChDRlhfUHRyQXJyYXkgJmFycmF5TGlzdCwgQUlfQ09NUEFSRSBwQ29tcGFyZSk7DQotcHJvdGVjdGVkOg0KLQkvLwlDRlhfUHRyTGlzdAkJCSBtX3BJdGVyYXRvckFubm90TGlzdDsgDQotCUNGWF9QdHJBcnJheQkgICAgIG1fcEl0ZXJhdG9yQW5ub3RMaXN0OwkNCi0JRlhfQk9PTAkJCSAgICAgbV9iUmV2ZXJzZTsNCi0JRlhfQk9PTCAgICAgICAgICAgICAgbV9iSWdub3JlVG9wbW9zdDsNCi0JRlhfQk9PTCAgICAgICAgICAgICAgbV9iQ2lyY2xlOw0KLX07DQotDQotDQotDQotI2VuZGlmDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRlNES19BTk5PVEhBTkRMRVJfSF8KKyNkZWZpbmUgX0ZTREtfQU5OT1RIQU5ETEVSX0hfCisKKworY2xhc3MgQ1BERkRvY19FbnZpcm9ubWVudDsKK2NsYXNzIENGRkxfSUZvcm1GaWxsZXI7CitjbGFzcyBDUERGU0RLX1BhZ2VWaWV3OworY2xhc3MgSVBERlNES19Bbm5vdEhhbmRsZXIKK3sKKworcHVibGljOgorCXZpcnR1YWwgfklQREZTREtfQW5ub3RIYW5kbGVyKCkge307CisKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXRUeXBlKCkgPSAwOworCisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0TmFtZSgpID0gMDsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlDYW5BbnN3ZXIoQ1BERlNES19Bbm5vdCogcEFubm90KSA9IDA7CisJCisKKwl2aXJ0dWFsIENQREZTREtfQW5ub3QqCQlOZXdBbm5vdChDUERGX0Fubm90KiBwQW5ub3QsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlKSA9IDA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJUmVsZWFzZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCURlbGV0ZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkgPSAwOworCQorCisJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Vmlld0JCb3goQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpID0gMDsKKwkKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJSGl0VGVzdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpID0gMDsKKwkKKworCXZpcnR1YWwgdm9pZAkJCQlPbkRyYXcoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIAorCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQlGWF9EV09SRCBkd0ZsYWdzKSA9IDA7CisJCisJdmlydHVhbCB2b2lkCQkJCU9uRHJhd1NsZWVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCAKKwkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJY29uc3QgQ1BERl9SZWN0JiByY1dpbmRvdywgRlhfRFdPUkQgZHdGbGFncykgPSAwOworCQorCisJCisKKwl2aXJ0dWFsIHZvaWQJCQkJT25DcmVhdGUoQ1BERlNES19Bbm5vdCogcEFubm90KSA9IDA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJT25Mb2FkKENQREZTREtfQW5ub3QqIHBBbm5vdCkgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCU9uRGVsZXRlKENQREZTREtfQW5ub3QqIHBBbm5vdCkgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCU9uUmVsZWFzZShDUERGU0RLX0Fubm90KiBwQW5ub3QpID0gMDsKKwkKKworCXZpcnR1YWwgdm9pZAkJCQlPbk1vdXNlRW50ZXIoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uTW91c2VFeGl0KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZykgPSAwOworCQorCisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpID0gMDsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpID0gMDsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA9IDA7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTW91c2VNb3ZlKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA9IDA7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTW91c2VXaGVlbChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA9IDA7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uUkJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpID0gMDsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25SQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpID0gMDsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25SQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA9IDA7CisvL2J5IHdqbS4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFncykgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktleURvd24oQ1BERlNES19Bbm5vdCogcEFubm90LCBpbnQgbktleUNvZGUsIGludCBuRmxhZykgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktleVVwKENQREZTREtfQW5ub3QqIHBBbm5vdCwgaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpID0wIDsKKworCXZpcnR1YWwJdm9pZAkJCQlPbkRlU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KSA9IDA7CisJdmlydHVhbAl2b2lkCQkJCU9uU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KSA9IDA7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25TZXRGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKSA9IDA7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpID0gMDsKKworfTsKKworCitjbGFzcyBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOnB1YmxpYyBJUERGU0RLX0Fubm90SGFuZGxlcgoreworcHVibGljOgorCUNQREZTREtfQkZBbm5vdEhhbmRsZXIoQ1BERkRvY19FbnZpcm9ubWVudCoJcEFwcCk6bV9wRm9ybUZpbGxlcihOVUxMKSxtX3BBcHAocEFwcCkge30KKwl2aXJ0dWFsCX5DUERGU0RLX0JGQW5ub3RIYW5kbGVyKCkge30KK3B1YmxpYzoKKworCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCUdldFR5cGUoKSAge3JldHVybiBDRlhfQnl0ZVN0cmluZygiV2lkZ2V0Iik7fQorCisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0TmFtZSgpICB7cmV0dXJuIENGWF9CeXRlU3RyaW5nKCJXaWRnZXRIYW5kbGVyIik7fQorCQorCXZpcnR1YWwgRlhfQk9PTAkJCQlDYW5BbnN3ZXIoQ1BERlNES19Bbm5vdCogcEFubm90KTsKKworCXZpcnR1YWwgQ1BERlNES19Bbm5vdCoJCU5ld0Fubm90KENQREZfQW5ub3QqIHBBbm5vdCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2UpOworCisJdmlydHVhbCB2b2lkCQkJCVJlbGVhc2VBbm5vdChDUERGU0RLX0Fubm90KiBwQW5ub3QpICA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJRGVsZXRlQW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90KSB7fQorCQorCisJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Vmlld0JCb3goQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpIDsKKwkKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJSGl0VGVzdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCQorCisJdmlydHVhbCB2b2lkCQkJCU9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgCisJCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCSBGWF9EV09SRCBkd0ZsYWdzKSA7CisJCisJdmlydHVhbCB2b2lkCQkJCU9uRHJhd1NsZWVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCAKKwkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJY29uc3QgQ1BERl9SZWN0JiByY1dpbmRvdywgRlhfRFdPUkQgZHdGbGFncykge30KKwkKKworCXZpcnR1YWwgdm9pZAkJCQlPbkNyZWF0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpIDsKKworCXZpcnR1YWwgdm9pZAkJCQlPbkxvYWQoQ1BERlNES19Bbm5vdCogcEFubm90KSA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJT25EZWxldGUoQ1BERlNES19Bbm5vdCogcEFubm90KSB7fQorCisJdmlydHVhbCB2b2lkCQkJCU9uUmVsZWFzZShDUERGU0RLX0Fubm90KiBwQW5ub3QpIHt9CisJCisKKwl2aXJ0dWFsIHZvaWQJCQkJT25Nb3VzZUVudGVyKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZykgOworCXZpcnR1YWwgdm9pZAkJCQlPbk1vdXNlRXhpdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpIDsKKwkKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbk1vdXNlTW92ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbk1vdXNlV2hlZWwoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPblJCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uUkJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSA7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uUkJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkge3JldHVybiBGQUxTRTt9CisJCisvL2J5IHdqbS4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFncyk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIGludCBuS2V5Q29kZSwgaW50IG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25LZXlVcChDUERGU0RLX0Fubm90KiBwQW5ub3QsIGludCBuS2V5Q29kZSwgaW50IG5GbGFnKTsKKworCXZpcnR1YWwJdm9pZAkJCQlPbkRlU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KSB7fQorCXZpcnR1YWwJdm9pZAkJCQlPblNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCkge30KKworCXZpcnR1YWwgRlhfQk9PTAkJCQlPblNldEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktpbGxGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKTsKKworCXZvaWQJCQkJCQlTZXRGb3JtRmlsbGVyKENGRkxfSUZvcm1GaWxsZXIqIHBGaWxsZXIpe21fcEZvcm1GaWxsZXIgPSBwRmlsbGVyO30KKwlDRkZMX0lGb3JtRmlsbGVyKgkJCUdldEZvcm1GaWxsZXIoKSB7cmV0dXJuIG1fcEZvcm1GaWxsZXI7fQorcHJpdmF0ZToKKworCUNQREZEb2NfRW52aXJvbm1lbnQqCQltX3BBcHA7CisJQ0ZGTF9JRm9ybUZpbGxlcioJCQltX3BGb3JtRmlsbGVyOworfTsKKworI2RlZmluZSBDQkFfQW5ub3RIYW5kbGVyQXJyYXkgQ0ZYX0FycmF5VGVtcGxhdGU8SVBERlNES19Bbm5vdEhhbmRsZXIqPgorY2xhc3MgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IKK3sKK3B1YmxpYzoKKwkvLyBEZXN0cm95IHRoZSBoYW5kbGVyCisJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCk7CisJdmlydHVhbCB+Q1BERlNES19Bbm5vdEhhbmRsZXJNZ3IoKSA7CisKK3B1YmxpYzoKKwl2b2lkCQkJCQkJUmVnaXN0ZXJBbm5vdEhhbmRsZXIoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIpOworCXZvaWQJCQkJCQlVblJlZ2lzdGVyQW5ub3RIYW5kbGVyKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyKTsKKworCXZpcnR1YWwgQ1BERlNES19Bbm5vdCoJCU5ld0Fubm90KENQREZfQW5ub3QgKiBwQW5ub3QsIENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldyk7CisJdmlydHVhbCB2b2lkCQkJCVJlbGVhc2VBbm5vdChDUERGU0RLX0Fubm90ICogcEFubm90KTsKKwkKKwl2aXJ0dWFsIHZvaWQJCQkJQW5ub3RfT25DcmVhdGUoQ1BERlNES19Bbm5vdCogcEFubm90KTsKKwl2aXJ0dWFsIHZvaWQJCQkJQW5ub3RfT25Mb2FkKENQREZTREtfQW5ub3QqIHBBbm5vdCk7CitwdWJsaWM6CisJSVBERlNES19Bbm5vdEhhbmRsZXIqCQlHZXRBbm5vdEhhbmRsZXIoQ1BERlNES19Bbm5vdCogcEFubm90KSBjb25zdDsKKwl2aXJ0dWFsIHZvaWQJCQkJQW5ub3RfT25EcmF3KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LAorCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLEZYX0RXT1JEIGR3RmxhZ3MpOworCisJdmlydHVhbCB2b2lkCQkJCUFubm90X09uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncyk7CisJdmlydHVhbCB2b2lkCQkJCUFubm90X09uTW91c2VFeGl0KENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzKTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCUFubm90X09uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCUFubm90X09uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCQorCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9Pbk1vdXNlTW92ZShDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9Pbk1vdXNlV2hlZWwoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PblJCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCUFubm90X09uUkJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWdzKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfT25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlBbm5vdF9PbktleVVwKENQREZTREtfQW5ub3QqIHBBbm5vdCwgaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpOworCisJdmlydHVhbCBGWF9CT09MCQkJCUFubm90X09uU2V0Rm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCUFubm90X09uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpOworCisJdmlydHVhbCBDUERGX1JlY3QJCQlBbm5vdF9PbkdldFZpZXdCQm94KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQW5ub3RfT25IaXRUZXN0KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisKK3ByaXZhdGU6CisJSVBERlNES19Bbm5vdEhhbmRsZXIqCQkJR2V0QW5ub3RIYW5kbGVyKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzVHlwZSkgY29uc3Q7CisJQ1BERlNES19Bbm5vdCoJCQkJR2V0TmV4dEFubm90KENQREZTREtfQW5ub3QqIHBTREtBbm5vdCxGWF9CT09MIGJOZXh0KTsKK3ByaXZhdGU6CisJQ0JBX0Fubm90SGFuZGxlckFycmF5CQltX0hhbmRsZXJzOworCUNGWF9NYXBCeXRlU3RyaW5nVG9QdHIJCW1fbWFwVHlwZTJIYW5kbGVyOworCUNQREZEb2NfRW52aXJvbm1lbnQqCQltX3BBcHA7Cit9OworCisvLyNkZWZpbmUgQ0JGX1BhZ2UyQWNjZXNzaWJsZQkgQ0ZYX01hcFB0clRlbXBsYXRlPENQREZTREtfUGFnZVZpZXcqLCBJQWNjZXNzaWJsZSo+CisKK3R5cGVkZWYgaW50ICgqQUlfQ09NUEFSRSkgKENQREZTREtfQW5ub3QqIHAxLCBDUERGU0RLX0Fubm90KiBwMik7CisKK2NsYXNzIENQREZTREtfQW5ub3RJdGVyYXRvcgoreworcHJvdGVjdGVkOgorCUNQREZTREtfQW5ub3QqCU5leHRBbm5vdCAoY29uc3QgQ1BERlNES19Bbm5vdCogcEN1cnJlbnQpIDsKKwlDUERGU0RLX0Fubm90KglQcmV2QW5ub3QgKGNvbnN0IENQREZTREtfQW5ub3QqIHBDdXJyZW50KSA7CQorCUNQREZTREtfQW5ub3QqCU5leHRBbm5vdChpbnQmIGluZGV4ICkgOworCUNQREZTREtfQW5ub3QqCVByZXZBbm5vdChpbnQmIGluZGV4ICkgOworcHVibGljOgorICAgIENQREZTREtfQW5ub3RJdGVyYXRvcihDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBGWF9CT09MIGJSZXZlcnNlLAorCQlGWF9CT09MIGJJZ25vcmVUb3Btb3N0PUZBTFNFLEZYX0JPT0wgYkNpcmNsZT1GQUxTRSxDRlhfUHRyQXJyYXkqIHBMaXN0PU5VTEwpOwkKKwl2aXJ0dWFsIENQREZTREtfQW5ub3QqCU5leHQgKGNvbnN0IENQREZTREtfQW5ub3QqIHBDdXJyZW50KSA7CisJdmlydHVhbCBDUERGU0RLX0Fubm90KglQcmV2IChjb25zdCBDUERGU0RLX0Fubm90KiBwQ3VycmVudCkgOwkKKwl2aXJ0dWFsIENQREZTREtfQW5ub3QqCU5leHQoaW50JiBpbmRleCApIDsKKwl2aXJ0dWFsIENQREZTREtfQW5ub3QqCVByZXYoaW50JiBpbmRleCApIDsKKwl2aXJ0dWFsIGludCAgICAgICAgICAgICBDb3VudCgpe3JldHVybiBtX3BJdGVyYXRvckFubm90TGlzdC5HZXRTaXplKCk7fQorCQorCXZpcnR1YWwgRlhfQk9PTCAgICAgICAgIEluaXRJdGVyYXRvckFubm90TGlzdChDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LENGWF9QdHJBcnJheSogcExpc3Q9TlVMTCk7CisJCisJdm9pZAkJCQkJSW5zZXJ0U29ydChDRlhfUHRyQXJyYXkgJmFycmF5TGlzdCwgQUlfQ09NUEFSRSBwQ29tcGFyZSk7Citwcm90ZWN0ZWQ6CisJLy8JQ0ZYX1B0ckxpc3QJCQkgbV9wSXRlcmF0b3JBbm5vdExpc3Q7IAorCUNGWF9QdHJBcnJheQkgICAgIG1fcEl0ZXJhdG9yQW5ub3RMaXN0OwkKKwlGWF9CT09MCQkJICAgICBtX2JSZXZlcnNlOworCUZYX0JPT0wgICAgICAgICAgICAgIG1fYklnbm9yZVRvcG1vc3Q7CisJRlhfQk9PTCAgICAgICAgICAgICAgbV9iQ2lyY2xlOworfTsKKworCisKKyNlbmRpZgorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZnNka19iYXNlYW5ub3QuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2Jhc2Vhbm5vdC5oCmluZGV4IGI2Y2FkYjcuLjQ2NDI1MDggMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2Jhc2Vhbm5vdC5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2Jhc2Vhbm5vdC5oCkBAIC0xLDE4NiArMSwxODYgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZTREtfQkFTRUFOTk9UX0hfDQotI2RlZmluZSBfRlNES19CQVNFQU5OT1RfSF8NCi0NCi0jaWYgX0ZYX09TXyA9PSBfRlhfQU5EUk9JRF8NCi0jaW5jbHVkZSAidGltZS5oIg0KLSNlbHNlDQotI2luY2x1ZGUgPGN0aW1lPg0KLSNlbmRpZg0KLQ0KLWNsYXNzIENQREZTREtfUGFnZVZpZXc7DQotI2RlZmluZSBDRlhfSW50QXJyYXkJCQkJQ0ZYX0FycmF5VGVtcGxhdGU8aW50Pg0KLQ0KLWNsYXNzICBDUERGU0RLX0RhdGVUaW1lIDogcHVibGljIENGWF9PYmplY3QNCi17DQotcHVibGljOg0KLQlDUERGU0RLX0RhdGVUaW1lKCk7DQotCUNQREZTREtfRGF0ZVRpbWUoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIGR0U3RyKTsNCi0JQ1BERlNES19EYXRlVGltZShjb25zdCBDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSk7DQotCUNQREZTREtfRGF0ZVRpbWUoY29uc3QgRlhfU1lTVEVNVElNRSYgc3QpOw0KLQkNCi0JDQotCUNQREZTREtfRGF0ZVRpbWUmCW9wZXJhdG9yID0gKGNvbnN0IENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKTsNCi0JQ1BERlNES19EYXRlVGltZSYJb3BlcmF0b3IgPSAoY29uc3QgRlhfU1lTVEVNVElNRSYgc3QpOw0KLQlGWF9CT09MCQkJCW9wZXJhdG9yID09IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSk7DQotCUZYX0JPT0wJCQkJb3BlcmF0b3IgIT0gKENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKTsNCi0JRlhfQk9PTAkJCQlvcGVyYXRvciA+IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSk7DQotCUZYX0JPT0wJCQkJb3BlcmF0b3IgPj0gKENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKTsNCi0JRlhfQk9PTAkJCQlvcGVyYXRvciA8IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSk7DQotCUZYX0JPT0wJCQkJb3BlcmF0b3IgPD0gKENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKTsJDQotCQkJCQkJb3BlcmF0b3IgdGltZV90KCk7DQotCQ0KLQlDUERGU0RLX0RhdGVUaW1lJglGcm9tUERGRGF0ZVRpbWVTdHJpbmcoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIGR0U3RyKTsNCi0JQ0ZYX0J5dGVTdHJpbmcJCVRvQ29tbW9uRGF0ZVRpbWVTdHJpbmcoKTsNCi0JQ0ZYX0J5dGVTdHJpbmcJCVRvUERGRGF0ZVRpbWVTdHJpbmcoKTsNCi0Jdm9pZAkJCQlUb1N5c3RlbVRpbWUoRlhfU1lTVEVNVElNRSYgc3QpOw0KLQlDUERGU0RLX0RhdGVUaW1lCVRvR01UKCk7DQotCUNQREZTREtfRGF0ZVRpbWUmCUFkZERheXMoc2hvcnQgZGF5cyk7DQotCUNQREZTREtfRGF0ZVRpbWUmCUFkZFNlY29uZHMoaW50IHNlY29uZHMpOw0KLQkNCi0Jdm9pZAkJCQlSZXNldERhdGVUaW1lKCk7DQotCQ0KLQlzdHJ1Y3QgRlhfREFURVRJTUUNCi0Jew0KLQkJRlhfU0hPUlQJeWVhcjsNCi0JCUZYX0JZVEUJCW1vbnRoOw0KLQkJRlhfQllURQkJZGF5Ow0KLQkJRlhfQllURQkJaG91cjsNCi0JCUZYX0JZVEUJCW1pbnV0ZTsNCi0JCUZYX0JZVEUJCXNlY29uZDsNCi0JCUZYX0NIQVIJCXR6SG91cjsNCi0JCUZYX0JZVEUJCXR6TWludXRlOw0KLQl9ZHQ7DQotfTsNCi0NCi1jbGFzcyBDUERGU0RLX0Fubm90DQotew0KLXB1YmxpYzoNCi0JQ1BERlNES19Bbm5vdChDUERGX0Fubm90KiBwQW5ub3QsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotCXZpcnR1YWwgfkNQREZTREtfQW5ub3QoKTsNCi1wdWJsaWM6DQotCXZpcnR1YWwgRlhfRkxPQVQJCQlHZXRNaW5XaWR0aCgpIGNvbnN0Ow0KLQl2aXJ0dWFsIEZYX0ZMT0FUCQkJR2V0TWluSGVpZ2h0KCkgY29uc3Q7DQotCS8vZGVmaW5lIGxheW91dCBvcmRlciB0byA1Lg0KLQl2aXJ0dWFsIGludAkJCQkJR2V0TGF5b3V0T3JkZXIoKSBjb25zdCB7IHJldHVybiA1OyB9DQotDQotcHVibGljOg0KLQlDUERGX0Fubm90KgkJCQkJR2V0UERGQW5ub3QoKTsNCi0JDQotCXZvaWQJCQkJCQlTZXRQYWdlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotCUNQREZTREtfUGFnZVZpZXcqCQkJR2V0UGFnZVZpZXcoKTsJDQotCUZYX0RXT1JECQkJCQlHZXRGbGFncygpOw0KLQkNCi0JLy8gVGFiIE9yZGVyCQ0KLQlpbnQJCQkJCQkJR2V0VGFiT3JkZXIoKTsNCi0Jdm9pZAkJCQkJCVNldFRhYk9yZGVyKGludCBpVGFiT3JkZXIpOw0KLQkNCi0JLy8gU2VsZWN0aW9uDQotCUZYX0JPT0wJCQkJCQlJc1NlbGVjdGVkKCk7DQotCXZvaWQJCQkJCQlTZXRTZWxlY3RlZChGWF9CT09MIGJTZWxlY3RlZCk7DQotCQ0KLQlDRlhfQnl0ZVN0cmluZwkJCQlHZXRUeXBlKCkgY29uc3Q7DQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCUdldFN1YlR5cGUoKSBjb25zdDsNCi0NCi0JQ1BERl9QYWdlKgkJCQkJR2V0UERGUGFnZSgpOw0KLQ0KLXB1YmxpYzoNCi0JQ1BERl9EaWN0aW9uYXJ5KgkJCUdldEFubm90RGljdCgpIGNvbnN0Ow0KLQkNCi0Jdm9pZAkJCQkJCVNldFJlY3QoY29uc3QgQ1BERl9SZWN0JiByZWN0KTsNCi0JQ1BERl9SZWN0CQkJCQlHZXRSZWN0KCkgY29uc3Q7DQotCQ0KLQl2b2lkCQkJCQkJU2V0Q29udGVudHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNDb250ZW50cyk7DQotCUNGWF9XaWRlU3RyaW5nCQkJCUdldENvbnRlbnRzKCkgY29uc3Q7DQotCQ0KLQl2b2lkCQkJCQkJU2V0QW5ub3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSk7DQotCUNGWF9XaWRlU3RyaW5nCQkJCUdldEFubm90TmFtZSgpIGNvbnN0Ow0KLQkNCi0Jdm9pZAkJCQkJCVNldE1vZGlmaWVkRGF0ZShjb25zdCBGWF9TWVNURU1USU1FJiBzdCk7DQotCUZYX1NZU1RFTVRJTUUJCQkJR2V0TW9kaWZpZWREYXRlKCkgY29uc3Q7DQotDQotCXZvaWQJCQkJCQlTZXRGbGFncyhpbnQgbkZsYWdzKTsNCi0JaW50CQkJCQkJCUdldEZsYWdzKCkgY29uc3Q7DQotDQotCXZvaWQJCQkJCQlTZXRBcHBTdGF0ZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyKTsNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJR2V0QXBwU3RhdGUoKSBjb25zdDsNCi0JDQotCXZvaWQJCQkJCQlTZXRTdHJ1Y3RQYXJlbnQoaW50IGtleSk7DQotCWludAkJCQkJCQlHZXRTdHJ1Y3RQYXJlbnQoKSBjb25zdDsNCi0JDQotCS8vYm9yZGVyDQotCXZvaWQJCQkJCQlTZXRCb3JkZXJXaWR0aChpbnQgbldpZHRoKTsNCi0JaW50CQkJCQkJCUdldEJvcmRlcldpZHRoKCkgY29uc3Q7DQotCQ0KLQkvL0JCU19TT0xJRA0KLQkvL0JCU19EQVNIDQotCS8vQkJTX0JFVkVMRUQNCi0JLy9CQlNfSU5TRVQNCi0JLy9CQlNfVU5ERVJMSU5FDQotCQ0KLQl2b2lkCQkJCQkJU2V0Qm9yZGVyU3R5bGUoaW50IG5TdHlsZSk7DQotCWludAkJCQkJCQlHZXRCb3JkZXJTdHlsZSgpIGNvbnN0Ow0KLQkNCi0Jdm9pZAkJCQkJCVNldEJvcmRlckRhc2goY29uc3QgQ0ZYX0ludEFycmF5JiBhcnJheSk7DQotCXZvaWQJCQkJCQlHZXRCb3JkZXJEYXNoKENGWF9JbnRBcnJheSYgYXJyYXkpIGNvbnN0Ow0KLQkNCi0JLy9UaGUgYmFja2dyb3VuZCBvZiB0aGUgYW5ub3RhdGlvbidzIGljb24gd2hlbiBjbG9zZWQNCi0JLy9UaGUgdGl0bGUgYmFyIG9mIHRoZSBhbm5vdGF0aW9uJ3MgcG9wLXVwIHdpbmRvdw0KLQkvL1RoZSBib3JkZXIgb2YgYSBsaW5rIGFubm90YXRpb24NCi0JDQotCXZvaWQJCQkJCQlTZXRDb2xvcihGWF9DT0xPUlJFRiBjb2xvcik7DQotCXZvaWQJCQkJCQlSZW1vdmVDb2xvcigpOw0KLQlGWF9CT09MCQkJCQkJR2V0Q29sb3IoRlhfQ09MT1JSRUYmIGNvbG9yKSBjb25zdDsNCi0JDQotCUZYX0JPT0wJCQkJCQlJc1Zpc2libGUoKSBjb25zdDsNCi0JLy9hY3Rpb24NCi0NCi0JQ1BERl9BY3Rpb24JCQkJCUdldEFjdGlvbigpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJU2V0QWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhKTsNCi0Jdm9pZAkJCQkJCVJlbW92ZUFjdGlvbigpOw0KLQkNCi0JQ1BERl9BQWN0aW9uCQkJCUdldEFBY3Rpb24oKSBjb25zdDsNCi0Jdm9pZAkJCQkJCVNldEFBY3Rpb24oY29uc3QgQ1BERl9BQWN0aW9uJiBhYSk7DQotCXZvaWQJCQkJCQlSZW1vdmVBQWN0aW9uKCk7DQotCQ0KLQl2aXJ0dWFsIENQREZfQWN0aW9uCQkJR2V0QUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQpOw0KLQkNCi1wdWJsaWM6DQotCUZYX0JPT0wJCQkJCQlJc0FwcGVhcmFuY2VWYWxpZCgpOw0KLQlGWF9CT09MCQkJCQkJSXNBcHBlYXJhbmNlVmFsaWQoQ1BERl9Bbm5vdDo6QXBwZWFyYW5jZU1vZGUgbW9kZSk7DQotCXZvaWQJCQkJCQlEcmF3QXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBjb25zdCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJQ1BERl9Bbm5vdDo6QXBwZWFyYW5jZU1vZGUgbW9kZSwgY29uc3QgQ1BERl9SZW5kZXJPcHRpb25zKiBwT3B0aW9ucyk7DQotCXZvaWQJCQkJCQlEcmF3Qm9yZGVyKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIGNvbnN0IENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQljb25zdCBDUERGX1JlbmRlck9wdGlvbnMqIHBPcHRpb25zKTsNCi0JDQotCXZvaWQJCQkJCQlDbGVhckNhY2hlZEFQKCk7DQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJUmVzZXRBcHBlYXJhbmNlKCk7DQotCXZvaWQJCQkJCQlXcml0ZUFwcGVhcmFuY2UoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFR5cGUsIGNvbnN0IENQREZfUmVjdCYgcmNCQm94LCANCi0JCWNvbnN0IENQREZfTWF0cml4JiBtYXRyaXgsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzQ29udGVudHMsDQotCQljb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FQU3RhdGUgPSAiIik7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQlBbm5vdF9PbkRyYXcoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSxDUERGX1JlbmRlck9wdGlvbnMqIHBPcHRpb25zKTsNCi1wdWJsaWM6DQotDQotDQotcHJpdmF0ZToNCi0JRlhfQk9PTCBDcmVhdGVGb3JtRmlsbGVyKCk7DQotcHJvdGVjdGVkOg0KLQlDUERGX0Fubm90KgkJCW1fcEFubm90Ow0KLQlDUERGU0RLX1BhZ2VWaWV3KgltX3BQYWdlVmlldzsNCi0JRlhfQk9PTAkJCQltX2JTZWxlY3RlZDsNCi0JaW50CQkJCQltX25UYWJPcmRlcjsNCi0JDQotfTsNCi0NCi0NCi0NCi0jZW5kaWYNCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GU0RLX0JBU0VBTk5PVF9IXworI2RlZmluZSBfRlNES19CQVNFQU5OT1RfSF8KKworI2lmIF9GWF9PU18gPT0gX0ZYX0FORFJPSURfCisjaW5jbHVkZSAidGltZS5oIgorI2Vsc2UKKyNpbmNsdWRlIDxjdGltZT4KKyNlbmRpZgorCitjbGFzcyBDUERGU0RLX1BhZ2VWaWV3OworI2RlZmluZSBDRlhfSW50QXJyYXkJCQkJQ0ZYX0FycmF5VGVtcGxhdGU8aW50PgorCitjbGFzcyAgQ1BERlNES19EYXRlVGltZSA6IHB1YmxpYyBDRlhfT2JqZWN0Cit7CitwdWJsaWM6CisJQ1BERlNES19EYXRlVGltZSgpOworCUNQREZTREtfRGF0ZVRpbWUoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIGR0U3RyKTsKKwlDUERGU0RLX0RhdGVUaW1lKGNvbnN0IENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKTsKKwlDUERGU0RLX0RhdGVUaW1lKGNvbnN0IEZYX1NZU1RFTVRJTUUmIHN0KTsKKwkKKwkKKwlDUERGU0RLX0RhdGVUaW1lJglvcGVyYXRvciA9IChjb25zdCBDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSk7CisJQ1BERlNES19EYXRlVGltZSYJb3BlcmF0b3IgPSAoY29uc3QgRlhfU1lTVEVNVElNRSYgc3QpOworCUZYX0JPT0wJCQkJb3BlcmF0b3IgPT0gKENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKTsKKwlGWF9CT09MCQkJCW9wZXJhdG9yICE9IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSk7CisJRlhfQk9PTAkJCQlvcGVyYXRvciA+IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSk7CisJRlhfQk9PTAkJCQlvcGVyYXRvciA+PSAoQ1BERlNES19EYXRlVGltZSYgZGF0ZXRpbWUpOworCUZYX0JPT0wJCQkJb3BlcmF0b3IgPCAoQ1BERlNES19EYXRlVGltZSYgZGF0ZXRpbWUpOworCUZYX0JPT0wJCQkJb3BlcmF0b3IgPD0gKENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKTsJCisJCQkJCQlvcGVyYXRvciB0aW1lX3QoKTsKKwkKKwlDUERGU0RLX0RhdGVUaW1lJglGcm9tUERGRGF0ZVRpbWVTdHJpbmcoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIGR0U3RyKTsKKwlDRlhfQnl0ZVN0cmluZwkJVG9Db21tb25EYXRlVGltZVN0cmluZygpOworCUNGWF9CeXRlU3RyaW5nCQlUb1BERkRhdGVUaW1lU3RyaW5nKCk7CisJdm9pZAkJCQlUb1N5c3RlbVRpbWUoRlhfU1lTVEVNVElNRSYgc3QpOworCUNQREZTREtfRGF0ZVRpbWUJVG9HTVQoKTsKKwlDUERGU0RLX0RhdGVUaW1lJglBZGREYXlzKHNob3J0IGRheXMpOworCUNQREZTREtfRGF0ZVRpbWUmCUFkZFNlY29uZHMoaW50IHNlY29uZHMpOworCQorCXZvaWQJCQkJUmVzZXREYXRlVGltZSgpOworCQorCXN0cnVjdCBGWF9EQVRFVElNRQorCXsKKwkJRlhfU0hPUlQJeWVhcjsKKwkJRlhfQllURQkJbW9udGg7CisJCUZYX0JZVEUJCWRheTsKKwkJRlhfQllURQkJaG91cjsKKwkJRlhfQllURQkJbWludXRlOworCQlGWF9CWVRFCQlzZWNvbmQ7CisJCUZYX0NIQVIJCXR6SG91cjsKKwkJRlhfQllURQkJdHpNaW51dGU7CisJfWR0OworfTsKKworY2xhc3MgQ1BERlNES19Bbm5vdAoreworcHVibGljOgorCUNQREZTREtfQW5ub3QoQ1BERl9Bbm5vdCogcEFubm90LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCXZpcnR1YWwgfkNQREZTREtfQW5ub3QoKTsKK3B1YmxpYzoKKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJR2V0TWluV2lkdGgoKSBjb25zdDsKKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJR2V0TWluSGVpZ2h0KCkgY29uc3Q7CisJLy9kZWZpbmUgbGF5b3V0IG9yZGVyIHRvIDUuCisJdmlydHVhbCBpbnQJCQkJCUdldExheW91dE9yZGVyKCkgY29uc3QgeyByZXR1cm4gNTsgfQorCitwdWJsaWM6CisJQ1BERl9Bbm5vdCoJCQkJCUdldFBERkFubm90KCk7CisJCisJdm9pZAkJCQkJCVNldFBhZ2UoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KTsKKwlDUERGU0RLX1BhZ2VWaWV3KgkJCUdldFBhZ2VWaWV3KCk7CQorCUZYX0RXT1JECQkJCQlHZXRGbGFncygpOworCQorCS8vIFRhYiBPcmRlcgkKKwlpbnQJCQkJCQkJR2V0VGFiT3JkZXIoKTsKKwl2b2lkCQkJCQkJU2V0VGFiT3JkZXIoaW50IGlUYWJPcmRlcik7CisJCisJLy8gU2VsZWN0aW9uCisJRlhfQk9PTAkJCQkJCUlzU2VsZWN0ZWQoKTsKKwl2b2lkCQkJCQkJU2V0U2VsZWN0ZWQoRlhfQk9PTCBiU2VsZWN0ZWQpOworCQorCUNGWF9CeXRlU3RyaW5nCQkJCUdldFR5cGUoKSBjb25zdDsKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXRTdWJUeXBlKCkgY29uc3Q7CisKKwlDUERGX1BhZ2UqCQkJCQlHZXRQREZQYWdlKCk7CisKK3B1YmxpYzoKKwlDUERGX0RpY3Rpb25hcnkqCQkJR2V0QW5ub3REaWN0KCkgY29uc3Q7CisJCisJdm9pZAkJCQkJCVNldFJlY3QoY29uc3QgQ1BERl9SZWN0JiByZWN0KTsKKwlDUERGX1JlY3QJCQkJCUdldFJlY3QoKSBjb25zdDsKKwkKKwl2b2lkCQkJCQkJU2V0Q29udGVudHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNDb250ZW50cyk7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJR2V0Q29udGVudHMoKSBjb25zdDsKKwkKKwl2b2lkCQkJCQkJU2V0QW5ub3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSk7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJR2V0QW5ub3ROYW1lKCkgY29uc3Q7CisJCisJdm9pZAkJCQkJCVNldE1vZGlmaWVkRGF0ZShjb25zdCBGWF9TWVNURU1USU1FJiBzdCk7CisJRlhfU1lTVEVNVElNRQkJCQlHZXRNb2RpZmllZERhdGUoKSBjb25zdDsKKworCXZvaWQJCQkJCQlTZXRGbGFncyhpbnQgbkZsYWdzKTsKKwlpbnQJCQkJCQkJR2V0RmxhZ3MoKSBjb25zdDsKKworCXZvaWQJCQkJCQlTZXRBcHBTdGF0ZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyKTsKKwlDRlhfQnl0ZVN0cmluZwkJCQlHZXRBcHBTdGF0ZSgpIGNvbnN0OworCQorCXZvaWQJCQkJCQlTZXRTdHJ1Y3RQYXJlbnQoaW50IGtleSk7CisJaW50CQkJCQkJCUdldFN0cnVjdFBhcmVudCgpIGNvbnN0OworCQorCS8vYm9yZGVyCisJdm9pZAkJCQkJCVNldEJvcmRlcldpZHRoKGludCBuV2lkdGgpOworCWludAkJCQkJCQlHZXRCb3JkZXJXaWR0aCgpIGNvbnN0OworCQorCS8vQkJTX1NPTElECisJLy9CQlNfREFTSAorCS8vQkJTX0JFVkVMRUQKKwkvL0JCU19JTlNFVAorCS8vQkJTX1VOREVSTElORQorCQorCXZvaWQJCQkJCQlTZXRCb3JkZXJTdHlsZShpbnQgblN0eWxlKTsKKwlpbnQJCQkJCQkJR2V0Qm9yZGVyU3R5bGUoKSBjb25zdDsKKwkKKwl2b2lkCQkJCQkJU2V0Qm9yZGVyRGFzaChjb25zdCBDRlhfSW50QXJyYXkmIGFycmF5KTsKKwl2b2lkCQkJCQkJR2V0Qm9yZGVyRGFzaChDRlhfSW50QXJyYXkmIGFycmF5KSBjb25zdDsKKwkKKwkvL1RoZSBiYWNrZ3JvdW5kIG9mIHRoZSBhbm5vdGF0aW9uJ3MgaWNvbiB3aGVuIGNsb3NlZAorCS8vVGhlIHRpdGxlIGJhciBvZiB0aGUgYW5ub3RhdGlvbidzIHBvcC11cCB3aW5kb3cKKwkvL1RoZSBib3JkZXIgb2YgYSBsaW5rIGFubm90YXRpb24KKwkKKwl2b2lkCQkJCQkJU2V0Q29sb3IoRlhfQ09MT1JSRUYgY29sb3IpOworCXZvaWQJCQkJCQlSZW1vdmVDb2xvcigpOworCUZYX0JPT0wJCQkJCQlHZXRDb2xvcihGWF9DT0xPUlJFRiYgY29sb3IpIGNvbnN0OworCQorCUZYX0JPT0wJCQkJCQlJc1Zpc2libGUoKSBjb25zdDsKKwkvL2FjdGlvbgorCisJQ1BERl9BY3Rpb24JCQkJCUdldEFjdGlvbigpIGNvbnN0OworCXZvaWQJCQkJCQlTZXRBY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGEpOworCXZvaWQJCQkJCQlSZW1vdmVBY3Rpb24oKTsKKwkKKwlDUERGX0FBY3Rpb24JCQkJR2V0QUFjdGlvbigpIGNvbnN0OworCXZvaWQJCQkJCQlTZXRBQWN0aW9uKGNvbnN0IENQREZfQUFjdGlvbiYgYWEpOworCXZvaWQJCQkJCQlSZW1vdmVBQWN0aW9uKCk7CisJCisJdmlydHVhbCBDUERGX0FjdGlvbgkJCUdldEFBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlQUFUKTsKKwkKK3B1YmxpYzoKKwlGWF9CT09MCQkJCQkJSXNBcHBlYXJhbmNlVmFsaWQoKTsKKwlGWF9CT09MCQkJCQkJSXNBcHBlYXJhbmNlVmFsaWQoQ1BERl9Bbm5vdDo6QXBwZWFyYW5jZU1vZGUgbW9kZSk7CisJdm9pZAkJCQkJCURyYXdBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIGNvbnN0IENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCUNQREZfQW5ub3Q6OkFwcGVhcmFuY2VNb2RlIG1vZGUsIGNvbnN0IENQREZfUmVuZGVyT3B0aW9ucyogcE9wdGlvbnMpOworCXZvaWQJCQkJCQlEcmF3Qm9yZGVyKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIGNvbnN0IENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCWNvbnN0IENQREZfUmVuZGVyT3B0aW9ucyogcE9wdGlvbnMpOworCQorCXZvaWQJCQkJCQlDbGVhckNhY2hlZEFQKCk7CisJCisJdmlydHVhbCB2b2lkCQkJCVJlc2V0QXBwZWFyYW5jZSgpOworCXZvaWQJCQkJCQlXcml0ZUFwcGVhcmFuY2UoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFR5cGUsIGNvbnN0IENQREZfUmVjdCYgcmNCQm94LCAKKwkJY29uc3QgQ1BERl9NYXRyaXgmIG1hdHJpeCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNDb250ZW50cywKKwkJY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFN0YXRlID0gIiIpOworCitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJQW5ub3RfT25EcmF3KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsQ1BERl9SZW5kZXJPcHRpb25zKiBwT3B0aW9ucyk7CitwdWJsaWM6CisKKworcHJpdmF0ZToKKwlGWF9CT09MIENyZWF0ZUZvcm1GaWxsZXIoKTsKK3Byb3RlY3RlZDoKKwlDUERGX0Fubm90KgkJCW1fcEFubm90OworCUNQREZTREtfUGFnZVZpZXcqCW1fcFBhZ2VWaWV3OworCUZYX0JPT0wJCQkJbV9iU2VsZWN0ZWQ7CisJaW50CQkJCQltX25UYWJPcmRlcjsKKwkKK307CisKKworCisjZW5kaWYKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZzZGtfYmFzZWZvcm0uaCBiL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2Jhc2Vmb3JtLmgKaW5kZXggYmFhMWMyOC4uYjkzY2JiZCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZzZGtfYmFzZWZvcm0uaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnNka19iYXNlZm9ybS5oCkBAIC0xLDI5MiArMSwyOTIgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZTREtfQkFTRUZPUk1fSF8NCi0jZGVmaW5lIF9GU0RLX0JBU0VGT1JNX0hfDQotDQotI2lmIF9GWF9PU18gPT0gX0ZYX0FORFJPSURfDQotI2luY2x1ZGUgInRpbWUuaCINCi0jZWxzZQ0KLSNpbmNsdWRlIDxjdGltZT4NCi0jZW5kaWYNCi0NCi1jbGFzcyBDUERGU0RLX0RvY3VtZW50Ow0KLWNsYXNzICBDUERGU0RLX0RhdGVUaW1lOw0KLXN0cnVjdCBDUFdMX0NvbG9yOw0KLWNsYXNzIENGRkxfRm9ybUZpbGxlcjsNCi1jbGFzcyBDUERGU0RLX1BhZ2VWaWV3Ow0KLWNsYXNzIENQREZTREtfSW50ZXJGb3JtOw0KLQ0KLQ0KLXR5cGVkZWYgc3RydWN0IF9QREZTREtfRmllbGRBY3Rpb24NCi17DQotCV9QREZTREtfRmllbGRBY3Rpb24oKQ0KLQl7DQotCQliTW9kaWZpZXIgPSBGQUxTRTsNCi0JCWJTaGlmdCA9IEZBTFNFOw0KLQkJbkNvbW1pdEtleSA9IDA7DQotCQliS2V5RG93biA9IEZBTFNFOw0KLQkJblNlbEVuZCA9IG5TZWxTdGFydCA9IDA7DQotCQliV2lsbENvbW1pdCA9IEZBTFNFOw0KLQkJYkZpZWxkRnVsbCA9IEZBTFNFOw0KLQkJYlJDID0gVFJVRTsNCi0JfQ0KLQkNCi0JRlhfQk9PTAkJCQkJYk1vZGlmaWVyOwkJLy9pbg0KLQlGWF9CT09MCQkJCQliU2hpZnQ7CQkJLy9pbg0KLQlpbnQJCQkJCQluQ29tbWl0S2V5OwkJLy9pbg0KLQlDRlhfV2lkZVN0cmluZwkJCXNDaGFuZ2U7CQkvL2luW291dF0NCi0JQ0ZYX1dpZGVTdHJpbmcJCQlzQ2hhbmdlRXg7CQkvL2luDQotCUZYX0JPT0wJCQkJCWJLZXlEb3duOwkJLy9pbg0KLQlpbnQJCQkJCQluU2VsRW5kOwkJLy9pbltvdXRdDQotCWludAkJCQkJCW5TZWxTdGFydDsJCS8vaW5bb3V0XQ0KLQlDRlhfV2lkZVN0cmluZwkJCXNWYWx1ZTsJCQkvL2luW291dF0NCi0JRlhfQk9PTAkJCQkJYldpbGxDb21taXQ7CS8vaW4NCi0JRlhfQk9PTAkJCQkJYkZpZWxkRnVsbDsJCS8vaW4NCi0JRlhfQk9PTAkJCQkJYlJDOwkJCS8vaW5bb3V0XQ0KLX1QREZTREtfRmllbGRBY3Rpb247DQotY2xhc3MgQ1BERlNES19XaWRnZXQ6cHVibGljIENQREZTREtfQW5ub3QNCi17DQotcHVibGljOg0KLQlDUERGU0RLX1dpZGdldChDUERGX0Fubm90KiBwQW5ub3QsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0pOw0KLQl2aXJ0dWFsIH5DUERGU0RLX1dpZGdldCgpOw0KLQ0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJR2V0U3ViVHlwZSgpIGNvbnN0Ow0KLQkNCi0JdmlydHVhbCBDUERGX0FjdGlvbgkJCQlHZXRBQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCk7DQotDQotCWludAkJCQkJCQkJR2V0RmllbGRUeXBlKCkgY29uc3Q7DQotCS8vZGVmaW5lIGxheW91dCBvcmRlciB0byAyLg0KLQl2aXJ0dWFsIGludAkJCQkJCUdldExheW91dE9yZGVyKCkge3JldHVybiAyO30NCi0JLyoNCi0JRklFTERGTEFHX1JFQURPTkxZDQotCUZJRUxERkxBR19SRVFVSVJFRA0KLQlGSUVMREZMQUdfTk9FWFBPUlQNCi0JKi8NCi0JDQotCWludAkJCQkJCQkJR2V0RmllbGRGbGFncygpIGNvbnN0Ow0KLQlpbnQJCQkJCQkJCUdldFJvdGF0ZSgpIGNvbnN0Ow0KLQ0KLQlGWF9CT09MCQkJCQkJCUdldEZpbGxDb2xvcihGWF9DT0xPUlJFRiYgY29sb3IpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUdldEJvcmRlckNvbG9yKEZYX0NPTE9SUkVGJiBjb2xvcikgY29uc3Q7DQotCUZYX0JPT0wJCQkJCQkJR2V0VGV4dENvbG9yKEZYX0NPTE9SUkVGJiBjb2xvcikgY29uc3Q7DQotCUZYX0ZMT0FUCQkJCQkJR2V0Rm9udFNpemUoKSBjb25zdDsNCi0NCi0JaW50CQkJCQkJCQlHZXRTZWxlY3RlZEluZGV4KGludCBuSW5kZXgpIGNvbnN0Ow0KLQlDRlhfV2lkZVN0cmluZwkJCQkJR2V0VmFsdWUoKSBjb25zdDsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldERlZmF1bHRWYWx1ZSgpIGNvbnN0Ow0KLQlDRlhfV2lkZVN0cmluZwkJCQkJR2V0T3B0aW9uTGFiZWwoaW50IG5JbmRleCkgY29uc3Q7DQotCWludAkJCQkJCQkJQ291bnRPcHRpb25zKCkgY29uc3Q7DQotCUZYX0JPT0wJCQkJCQkJSXNPcHRpb25TZWxlY3RlZChpbnQgbkluZGV4KSBjb25zdDsNCi0JaW50CQkJCQkJCQlHZXRUb3BWaXNpYmxlSW5kZXgoKSBjb25zdDsNCi0JRlhfQk9PTAkJCQkJCQlJc0NoZWNrZWQoKSBjb25zdDsNCi0JLyoNCi0JQkZfQUxJR05fTEVGVA0KLQlCRl9BTElHTl9NSURETA0KLQlCRl9BTElHTl9SSUdIVA0KLQkqLw0KLQlpbnQJCQkJCQkJCUdldEFsaWdubWVudCgpIGNvbnN0Ow0KLQlpbnQJCQkJCQkJCUdldE1heExlbigpIGNvbnN0Ow0KLQlDRlhfV2lkZVN0cmluZwkJCQkJR2V0QWx0ZXJuYXRlTmFtZSgpIGNvbnN0Ow0KLQ0KLS8vU2V0IFByb3BlcnRpZXMuDQotCXZvaWQJCQkJCQkJU2V0Q2hlY2soRlhfQk9PTCBiQ2hlY2tlZCwgRlhfQk9PTCBiTm90aWZ5KTsNCi0Jdm9pZAkJCQkJCQlTZXRWYWx1ZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc1ZhbHVlLCBGWF9CT09MIGJOb3RpZnkpOw0KLQl2b2lkCQkJCQkJCVNldERlZmF1bHRWYWx1ZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc1ZhbHVlKTsNCi0Jdm9pZAkJCQkJCQlTZXRPcHRpb25TZWxlY3Rpb24oaW50IGluZGV4LCBGWF9CT09MIGJTZWxlY3RlZCwgRlhfQk9PTCBiTm90aWZ5KTsNCi0Jdm9pZAkJCQkJCQlDbGVhclNlbGVjdGlvbihGWF9CT09MIGJOb3RpZnkpOw0KLQl2b2lkCQkJCQkJCVNldFRvcFZpc2libGVJbmRleChpbnQgaW5kZXgpOw0KLQ0KLQl2b2lkCQkJCQkJCVJlc2V0QXBwZWFyYW5jZShGWF9MUENXU1RSIHNWYWx1ZSwgRlhfQk9PTCBiVmFsdWVDaGFuZ2VkKTsNCi0Jdm9pZAkJCQkJCQlSZXNldEZpZWxkQXBwZWFyYW5jZShGWF9CT09MIGJWYWx1ZUNoYW5nZWQpOw0KLQl2b2lkCQkJCQkJCVVwZGF0ZUZpZWxkKCk7DQotCUNGWF9XaWRlU3RyaW5nCQkJCQlPbkZvcm1hdChpbnQgbkNvbW1pdEtleSwgRlhfQk9PTCYgYkZvcm1hdGVkKTsNCi0JDQotLy9NZXNzYWdlLg0KLSAJRlhfQk9PTAkJCQkJCQlPbkFBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBQREZTREtfRmllbGRBY3Rpb24mIGRhdGEsIA0KLQkJCQkJCQkJCQkJCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7DQotDQotCUNQREZTREtfSW50ZXJGb3JtKgkJCQlHZXRJbnRlckZvcm0oKSBjb25zdCB7cmV0dXJuIG1fcEludGVyRm9ybTt9DQotCUNQREZfRm9ybUZpZWxkKgkJCQkJR2V0Rm9ybUZpZWxkKCkgY29uc3Q7DQotCUNQREZfRm9ybUNvbnRyb2wqCQkJCUdldEZvcm1Db250cm9sKCkgY29uc3Q7DQotCXN0YXRpYyBDUERGX0Zvcm1Db250cm9sKgkJR2V0Rm9ybUNvbnRyb2woQ1BERl9JbnRlckZvcm0qIHBJbnRlckZvcm0sIENQREZfRGljdGlvbmFyeSogcEFubm90RGljdCk7DQotDQotCXZvaWQJCQkJCQkJRHJhd1NoYWRvdyhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQkNCi0Jdm9pZAkJCQkJCQlTZXRBcHBNb2RpZmllZCgpOw0KLQl2b2lkCQkJCQkJCUNsZWFyQXBwTW9kaWZpZWQoKTsNCi0JRlhfQk9PTAkJCQkJCQlJc0FwcE1vZGlmaWVkKCkgY29uc3Q7DQotCQ0KLQlGWF9JTlQzMgkJCQkJCUdldEFwcGVhcmFuY2VBZ2UoKSBjb25zdDsNCi0JRlhfSU5UMzIJCQkJCQlHZXRWYWx1ZUFnZSgpIGNvbnN0Ow0KLQkNCi1wcml2YXRlOg0KLQl2b2lkCQkJCQkJCVJlc2V0QXBwZWFyYW5jZV9QdXNoQnV0dG9uKCk7DQotCXZvaWQJCQkJCQkJUmVzZXRBcHBlYXJhbmNlX0NoZWNrQm94KCk7DQotCXZvaWQJCQkJCQkJUmVzZXRBcHBlYXJhbmNlX1JhZGlvQnV0dG9uKCk7DQotCXZvaWQJCQkJCQkJUmVzZXRBcHBlYXJhbmNlX0NvbWJvQm94KEZYX0xQQ1dTVFIgc1ZhbHVlKTsNCi0Jdm9pZAkJCQkJCQlSZXNldEFwcGVhcmFuY2VfTGlzdEJveCgpOw0KLQl2b2lkCQkJCQkJCVJlc2V0QXBwZWFyYW5jZV9UZXh0RmllbGQoRlhfTFBDV1NUUiBzVmFsdWUpOw0KLQkNCi0JQ1BERl9SZWN0CQkJCQkJR2V0Q2xpZW50UmVjdCgpIGNvbnN0Ow0KLQlDUERGX1JlY3QJCQkJCQlHZXRSb3RhdGVkUmVjdCgpIGNvbnN0Ow0KLQkNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEJhY2tncm91bmRBcHBTdHJlYW0oKSBjb25zdDsNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEJvcmRlckFwcFN0cmVhbSgpIGNvbnN0Ow0KLQlDUERGX01hdHJpeAkJCQkJCUdldE1hdHJpeCgpIGNvbnN0Ow0KLQkNCi0JQ1BXTF9Db2xvcgkJCQkJCUdldFRleHRQV0xDb2xvcigpIGNvbnN0Ow0KLQlDUFdMX0NvbG9yCQkJCQkJR2V0Qm9yZGVyUFdMQ29sb3IoKSBjb25zdDsNCi0JQ1BXTF9Db2xvcgkJCQkJCUdldEZpbGxQV0xDb2xvcigpIGNvbnN0Ow0KLQkNCi0Jdm9pZAkJCQkJCQlBZGRJbWFnZVRvQXBwZWFyYW5jZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FQVHlwZSwgQ1BERl9TdHJlYW0qIHBJbWFnZSk7DQotCXZvaWQJCQkJCQkJUmVtb3ZlQXBwZWFyYW5jZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FQVHlwZSk7DQotcHVibGljOg0KLQlGWF9CT09MCQkJCQkJCUlzV2lkZ2V0QXBwZWFyYW5jZVZhbGlkKENQREZfQW5ub3Q6OkFwcGVhcmFuY2VNb2RlIG1vZGUpOw0KLQl2b2lkCQkJCQkJCURyYXdBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIGNvbnN0IENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQlDUERGX0Fubm90OjpBcHBlYXJhbmNlTW9kZSBtb2RlLCBjb25zdCBDUERGX1JlbmRlck9wdGlvbnMqIHBPcHRpb25zKTsNCi1wdWJsaWM6DQotCUZYX0JPT0wJCQkJCQkJSGl0VGVzdChGWF9GTE9BVCBwYWdlWCwgRlhfRkxPQVQgcGFnZVkpOw0KLXByaXZhdGU6DQotCUNQREZTREtfSW50ZXJGb3JtKgkJCQltX3BJbnRlckZvcm07DQotCUZYX0JPT0wJCQkJCQkJbV9iQXBwTW9kaWZpZWQ7DQotCUZYX0lOVDMyCQkJCQkJbV9uQXBwQWdlOw0KLQlGWF9JTlQzMgkJCQkJCW1fblZhbHVlQWdlOw0KLX07DQotDQotI2RlZmluZSBDUERGU0RLX1dpZGdldE1hcAkJCQlDRlhfTWFwUHRyVGVtcGxhdGU8Q1BERl9Gb3JtQ29udHJvbCosIENQREZTREtfV2lkZ2V0Kj4NCi0NCi1jbGFzcyBDUERGU0RLX0ludGVyRm9ybSA6IHB1YmxpYyBDUERGX0Zvcm1Ob3RpZnkNCi17DQotcHVibGljOg0KLQlDUERGU0RLX0ludGVyRm9ybShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOw0KLQl2aXJ0dWFsIH5DUERGU0RLX0ludGVyRm9ybSgpOw0KLQkNCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQkJRGVzdHJveSgpOw0KLQl2aXJ0dWFsIENQREZfSW50ZXJGb3JtKgkJCUdldEludGVyRm9ybSgpOw0KLQkNCi0JQ1BERlNES19Eb2N1bWVudCoJCQkJR2V0RG9jdW1lbnQoKTsNCi0JRlhfQk9PTAkJCQkJCQlIaWdobGlnaHRXaWRnZXRzKCk7DQotCQ0KLQlDUERGU0RLX1dpZGdldCoJCQkJCUdldFNpYmxpbmcoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIEZYX0JPT0wgYk5leHQpIGNvbnN0Ow0KLQlDUERGU0RLX1dpZGdldCoJCQkJCUdldFdpZGdldChDUERGX0Zvcm1Db250cm9sKiBwQ29udHJvbCkgY29uc3Q7DQotCXZvaWQJCQkJCQkJR2V0V2lkZ2V0cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpZWxkTmFtZSwgQ0ZYX1B0ckFycmF5JiB3aWRnZXRzKTsNCi0Jdm9pZAkJCQkJCQlHZXRXaWRnZXRzKENQREZfRm9ybUZpZWxkKiBwRmllbGQsIENGWF9QdHJBcnJheSYgd2lkZ2V0cyk7DQotCQ0KLQl2b2lkCQkJCQkJCUFkZE1hcChDUERGX0Zvcm1Db250cm9sKiBwQ29udHJvbCwgQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpOw0KLQl2b2lkCQkJCQkJCVJlbW92ZU1hcChDUERGX0Zvcm1Db250cm9sKiBwQ29udHJvbCk7DQotCQ0KLQl2b2lkCQkJCQkJCUVuYWJsZUNhbGN1bGF0ZShGWF9CT09MIGJFbmFibGVkKTsNCi0JRlhfQk9PTAkJCQkJCQlJc0NhbGN1bGF0ZUVuYWJsZWQoKSBjb25zdDsNCi0NCi0jaWZkZWYgX1dJTjMyDQotCUNQREZfU3RyZWFtKgkJCQkJTG9hZEltYWdlRnJvbUZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGaWxlKTsNCi0jZW5kaWYNCi0NCi0Jdm9pZAkJCQkJCQlPbktleVN0cm9rZUNvbW1pdChDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIGNzVmFsdWUsIEZYX0JPT0wmIGJSQyk7DQotCXZvaWQJCQkJCQkJT25WYWxpZGF0ZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIGNzVmFsdWUsIEZYX0JPT0wmIGJSQyk7DQotCXZvaWQJCQkJCQkJT25DYWxjdWxhdGUoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBOVUxMKTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJCU9uRm9ybWF0KENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCBpbnQgbkNvbW1pdEtleSwgRlhfQk9PTCYgYkZvcm1hdGVkKTsNCi0JDQotCXZvaWQJCQkJCQkJUmVzZXRGaWVsZEFwcGVhcmFuY2UoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIEZYX0xQQ1dTVFIgc1ZhbHVlLCBGWF9CT09MIGJWYWx1ZUNoYW5nZWQpOw0KLQl2b2lkCQkJCQkJCVVwZGF0ZUZpZWxkKENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkKTsNCi0JDQotcHVibGljOg0KLQlGWF9CT09MCQkJCQkJCURvQWN0aW9uX0hpZGUoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbik7DQotCUZYX0JPT0wJCQkJCQkJRG9BY3Rpb25fU3VibWl0Rm9ybShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKTsNCi0JRlhfQk9PTAkJCQkJCQlEb0FjdGlvbl9SZXNldEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbik7DQotCUZYX0JPT0wJCQkJCQkJRG9BY3Rpb25fSW1wb3J0RGF0YShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKTsNCi0JDQotCXZvaWQJCQkJCQkJR2V0RmllbGRGcm9tT2JqZWN0cyhjb25zdCBDRlhfUHRyQXJyYXkmIG9iamVjdHMsIENGWF9QdHJBcnJheSYgZmllbGRzKTsNCi0JRlhfQk9PTAkJCQkJCQlJc1ZhbGlkRmllbGQoQ1BERl9EaWN0aW9uYXJ5KiBwRmllbGREaWN0KTsNCi0JRlhfQk9PTAkJCQkJCQlTdWJtaXRGaWVsZHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIGNzRGVzdGluYXRpb24sIGNvbnN0IENGWF9QdHJBcnJheSYgZmllbGRzLCANCi0JCUZYX0JPT0wgYkluY2x1ZGVPckV4Y2x1ZGUsIEZYX0JPT0wgYlVybEVuY29kZWQpOw0KLQlGWF9CT09MCQkJCQkJCVN1Ym1pdEZvcm0oY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNEZXN0aW5hdGlvbiwgRlhfQk9PTCBiVXJsRW5jb2RlZCk7DQotCUZYX0JPT0wJCQkJCQkJSW1wb3J0Rm9ybUZyb21GREZGaWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBjc0ZERkZpbGVOYW1lLCBGWF9CT09MIGJOb3RpZnkpOw0KLQlGWF9CT09MCQkJCQkJCUV4cG9ydEZvcm1Ub0ZERkZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGREZGaWxlTmFtZSk7DQotCUZYX0JPT0wJCQkJCQkJRXhwb3J0Rm9ybVRvRkRGVGV4dEJ1ZihDRlhfQnl0ZVRleHRCdWYmIHRleHRCdWYpOw0KLQlGWF9CT09MCQkJCQkJCUV4cG9ydEZpZWxkc1RvRkRGRmlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZERkZpbGVOYW1lLCBjb25zdCBDRlhfUHRyQXJyYXkmIGZpZWxkcywNCi0JCUZYX0JPT0wgYkluY2x1ZGVPckV4Y2x1ZGUpOw0KLQlGWF9CT09MCQkJCQkJCUV4cG9ydEZpZWxkc1RvRkRGVGV4dEJ1Zihjb25zdCBDRlhfUHRyQXJyYXkmIGZpZWxkcyxGWF9CT09MIGJJbmNsdWRlT3JFeGNsdWRlLCBDRlhfQnl0ZVRleHRCdWYmIHRleHRCdWYpOw0KLQlGWF9CT09MCQkJCQkJCUV4cG9ydEZvcm1Ub1R4dEZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUeHRGaWxlTmFtZSk7DQotCUZYX0JPT0wJCQkJCQkJSW1wb3J0Rm9ybUZyb21UeHRGaWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVHh0RmlsZU5hbWUpOw0KLQlDRlhfV2lkZVN0cmluZwkJCQkJR2V0VGVtcG9yYXJ5RmlsZU5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGaWxlRXh0KTsNCi0JDQotcHJpdmF0ZToNCi0JdmlydHVhbCBpbnQJCQkJCQlCZWZvcmVWYWx1ZUNoYW5nZShjb25zdCBDUERGX0Zvcm1GaWVsZCogcEZpZWxkLCBDRlhfV2lkZVN0cmluZyYgY3NWYWx1ZSk7DQotCXZpcnR1YWwgaW50CQkJCQkJQWZ0ZXJWYWx1ZUNoYW5nZShjb25zdCBDUERGX0Zvcm1GaWVsZCogcEZpZWxkKTsNCi0JdmlydHVhbCBpbnQJCQkJCQlCZWZvcmVTZWxlY3Rpb25DaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIGNzVmFsdWUpOw0KLQl2aXJ0dWFsIGludAkJCQkJCUFmdGVyU2VsZWN0aW9uQ2hhbmdlKGNvbnN0IENQREZfRm9ybUZpZWxkKiBwRmllbGQpOw0KLQl2aXJ0dWFsIGludAkJCQkJCUFmdGVyQ2hlY2tlZFN0YXR1c0NoYW5nZShjb25zdCBDUERGX0Zvcm1GaWVsZCogcEZpZWxkLCBjb25zdCBDRlhfQnl0ZUFycmF5JiBzdGF0dXNBcnJheSk7DQotCXZpcnR1YWwgaW50CQkJCQkJQmVmb3JlRm9ybVJlc2V0KGNvbnN0IENQREZfSW50ZXJGb3JtKiBwRm9ybSk7DQotCXZpcnR1YWwgaW50CQkJCQkJQWZ0ZXJGb3JtUmVzZXQoY29uc3QgQ1BERl9JbnRlckZvcm0qIHBGb3JtKTsNCi0JdmlydHVhbCBpbnQJCQkJCQlCZWZvcmVGb3JtSW1wb3J0RGF0YShjb25zdCBDUERGX0ludGVyRm9ybSogcEZvcm0pOw0KLQl2aXJ0dWFsIGludAkJCQkJCUFmdGVyRm9ybUltcG9ydERhdGEoY29uc3QgQ1BERl9JbnRlckZvcm0qIHBGb3JtKTsNCi0JDQotcHJpdmF0ZToNCi0JRlhfQk9PTAkJCQkJCQlGREZUb1VSTEVuY29kZWREYXRhKENGWF9XaWRlU3RyaW5nIGNzRkRGRmlsZSwgQ0ZYX1dpZGVTdHJpbmcgY3NUeHRGaWxlKTsNCi0JRlhfQk9PTAkJCQkJCQlGREZUb1VSTEVuY29kZWREYXRhKEZYX0xQQllURSYgcEJ1ZiwgRlhfU1RSU0laRSYgbkJ1ZlNpemUpOw0KLQlpbnQJCQkJCQkJCUdldFBhZ2VJbmRleEJ5QW5ub3REaWN0KENQREZfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0KSBjb25zdDsNCi0Jdm9pZAkJCQkJCQlEb0ZERkJ1ZmZlcihDRlhfQnl0ZVN0cmluZyBzQnVmZmVyKTsNCi0JDQotcHJpdmF0ZToNCi0JQ1BERlNES19Eb2N1bWVudCoJCQkJbV9wRG9jdW1lbnQ7DQotCUNQREZfSW50ZXJGb3JtKgkJCQkJbV9wSW50ZXJGb3JtOw0KLQlDUERGU0RLX1dpZGdldE1hcAkJCQltX01hcDsNCi0JRlhfQk9PTAkJCQkJCQltX2JDYWxjdWxhdGU7DQotCUZYX0JPT0wJCQkJCQkJbV9iQnVzeTsNCi0NCi1wdWJsaWM6DQotCUZYX0JPT0wgSXNOZWVkSGlnaExpZ2h0KGludCBuRmllbGRUeXBlKTsNCi0Jdm9pZCAgICBSZW1vdmVBbGxIaWdoTGlnaHQoKTsNCi0Jdm9pZCAgICBTZXRIaWdobGlnaHRBbHBoYShGWF9CWVRFIGFscGhhKSB7bV9pSGlnaGxpZ2h0QWxwaGEgPSBhbHBoYTt9DQotCUZYX0JZVEUgR2V0SGlnaGxpZ2h0QWxwaGEoKSB7cmV0dXJuIG1faUhpZ2hsaWdodEFscGhhO30NCi0Jdm9pZCAgICBTZXRIaWdobGlnaHRDb2xvcihGWF9DT0xPUlJFRiBjbHIsIGludCBuRmllbGRUeXBlKTsNCi0JRlhfQ09MT1JSRUYgR2V0SGlnaGxpZ2h0Q29sb3IoaW50IG5GaWVsZFR5cGUpOw0KLXByaXZhdGU6DQotCUZYX0NPTE9SUkVGIG1fYUhpZ2hsaWdodENvbG9yWzZdOw0KLQlGWF9CWVRFIG1faUhpZ2hsaWdodEFscGhhOw0KLQlGWF9CT09MCW1fYk5lZWRIaWdodGxpZ2h0WzZdOw0KLX07DQotDQotI2RlZmluZSBCQUlfU1RSVUNUVVJFCQkwDQotI2RlZmluZSBCQUlfUk9XCQkJCTENCi0jZGVmaW5lIEJBSV9DT0xVTU4JCQkyDQotDQotI2RlZmluZSBDUERGU0RLX0Fubm90cwkJCQlDRlhfQXJyYXlUZW1wbGF0ZTxDUERGU0RLX0Fubm90Kj4NCi0jZGVmaW5lIENQREZTREtfU29ydEFubm90cwkJCUNHV19BcnJheVRlbXBsYXRlPENQREZTREtfQW5ub3QqPg0KLWNsYXNzIENCQV9Bbm5vdEl0ZXJhdG9yIA0KLXsNCi1wdWJsaWM6DQotCUNCQV9Bbm5vdEl0ZXJhdG9yKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNUeXBlLCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc1N1YlR5cGUpOw0KLQl2aXJ0dWFsIH5DQkFfQW5ub3RJdGVyYXRvcigpOw0KLQkNCi0JdmlydHVhbCBDUERGU0RLX0Fubm90KgkJCQlHZXRGaXJzdEFubm90KCk7DQotCXZpcnR1YWwgQ1BERlNES19Bbm5vdCoJCQkJR2V0TGFzdEFubm90KCk7DQotCXZpcnR1YWwgQ1BERlNES19Bbm5vdCoJCQkJR2V0TmV4dEFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotCXZpcnR1YWwgQ1BERlNES19Bbm5vdCoJCQkJR2V0UHJldkFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlSZWxlYXNlKCl7ZGVsZXRlIHRoaXM7fQ0KLQkNCi1wcml2YXRlOg0KLQl2b2lkCQkJCQkJCQlHZW5lcmF0ZVJlc3VsdHMoKTsNCi0Jc3RhdGljIGludAkJCQkJCQlDb21wYXJlQnlMZWZ0KENQREZTREtfQW5ub3QqIHAxLCBDUERGU0RLX0Fubm90KiBwMik7DQotCXN0YXRpYyBpbnQJCQkJCQkJQ29tcGFyZUJ5VG9wKENQREZTREtfQW5ub3QqIHAxLCBDUERGU0RLX0Fubm90KiBwMik7DQotCQ0KLQlzdGF0aWMgQ1BERl9SZWN0CQkJCQlHZXRBbm5vdFJlY3QoQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0JDQotcHJpdmF0ZToNCi0JQ1BERlNES19QYWdlVmlldyoJCQkJCW1fcFBhZ2VWaWV3Ow0KLQlDRlhfQnl0ZVN0cmluZwkJCQkJCW1fc1R5cGU7DQotCUNGWF9CeXRlU3RyaW5nCQkJCQkJbV9zU3ViVHlwZTsNCi0JaW50CQkJCQkJCQkJbV9uVGFiczsNCi0JDQotCUNQREZTREtfQW5ub3RzCQkJCQkJbV9Bbm5vdHM7DQotfTsNCi0NCi0jZW5kaWYgLy8jZGVmaW5lIF9GU0RLX0JBU0VGT1JNX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRlNES19CQVNFRk9STV9IXworI2RlZmluZSBfRlNES19CQVNFRk9STV9IXworCisjaWYgX0ZYX09TXyA9PSBfRlhfQU5EUk9JRF8KKyNpbmNsdWRlICJ0aW1lLmgiCisjZWxzZQorI2luY2x1ZGUgPGN0aW1lPgorI2VuZGlmCisKK2NsYXNzIENQREZTREtfRG9jdW1lbnQ7CitjbGFzcyAgQ1BERlNES19EYXRlVGltZTsKK3N0cnVjdCBDUFdMX0NvbG9yOworY2xhc3MgQ0ZGTF9Gb3JtRmlsbGVyOworY2xhc3MgQ1BERlNES19QYWdlVmlldzsKK2NsYXNzIENQREZTREtfSW50ZXJGb3JtOworCisKK3R5cGVkZWYgc3RydWN0IF9QREZTREtfRmllbGRBY3Rpb24KK3sKKwlfUERGU0RLX0ZpZWxkQWN0aW9uKCkKKwl7CisJCWJNb2RpZmllciA9IEZBTFNFOworCQliU2hpZnQgPSBGQUxTRTsKKwkJbkNvbW1pdEtleSA9IDA7CisJCWJLZXlEb3duID0gRkFMU0U7CisJCW5TZWxFbmQgPSBuU2VsU3RhcnQgPSAwOworCQliV2lsbENvbW1pdCA9IEZBTFNFOworCQliRmllbGRGdWxsID0gRkFMU0U7CisJCWJSQyA9IFRSVUU7CisJfQorCQorCUZYX0JPT0wJCQkJCWJNb2RpZmllcjsJCS8vaW4KKwlGWF9CT09MCQkJCQliU2hpZnQ7CQkJLy9pbgorCWludAkJCQkJCW5Db21taXRLZXk7CQkvL2luCisJQ0ZYX1dpZGVTdHJpbmcJCQlzQ2hhbmdlOwkJLy9pbltvdXRdCisJQ0ZYX1dpZGVTdHJpbmcJCQlzQ2hhbmdlRXg7CQkvL2luCisJRlhfQk9PTAkJCQkJYktleURvd247CQkvL2luCisJaW50CQkJCQkJblNlbEVuZDsJCS8vaW5bb3V0XQorCWludAkJCQkJCW5TZWxTdGFydDsJCS8vaW5bb3V0XQorCUNGWF9XaWRlU3RyaW5nCQkJc1ZhbHVlOwkJCS8vaW5bb3V0XQorCUZYX0JPT0wJCQkJCWJXaWxsQ29tbWl0OwkvL2luCisJRlhfQk9PTAkJCQkJYkZpZWxkRnVsbDsJCS8vaW4KKwlGWF9CT09MCQkJCQliUkM7CQkJLy9pbltvdXRdCit9UERGU0RLX0ZpZWxkQWN0aW9uOworY2xhc3MgQ1BERlNES19XaWRnZXQ6cHVibGljIENQREZTREtfQW5ub3QKK3sKK3B1YmxpYzoKKwlDUERGU0RLX1dpZGdldChDUERGX0Fubm90KiBwQW5ub3QsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0pOworCXZpcnR1YWwgfkNQREZTREtfV2lkZ2V0KCk7CisKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJR2V0U3ViVHlwZSgpIGNvbnN0OworCQorCXZpcnR1YWwgQ1BERl9BY3Rpb24JCQkJR2V0QUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQpOworCisJaW50CQkJCQkJCQlHZXRGaWVsZFR5cGUoKSBjb25zdDsKKwkvL2RlZmluZSBsYXlvdXQgb3JkZXIgdG8gMi4KKwl2aXJ0dWFsIGludAkJCQkJCUdldExheW91dE9yZGVyKCkge3JldHVybiAyO30KKwkvKgorCUZJRUxERkxBR19SRUFET05MWQorCUZJRUxERkxBR19SRVFVSVJFRAorCUZJRUxERkxBR19OT0VYUE9SVAorCSovCisJCisJaW50CQkJCQkJCQlHZXRGaWVsZEZsYWdzKCkgY29uc3Q7CisJaW50CQkJCQkJCQlHZXRSb3RhdGUoKSBjb25zdDsKKworCUZYX0JPT0wJCQkJCQkJR2V0RmlsbENvbG9yKEZYX0NPTE9SUkVGJiBjb2xvcikgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQlHZXRCb3JkZXJDb2xvcihGWF9DT0xPUlJFRiYgY29sb3IpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJR2V0VGV4dENvbG9yKEZYX0NPTE9SUkVGJiBjb2xvcikgY29uc3Q7CisJRlhfRkxPQVQJCQkJCQlHZXRGb250U2l6ZSgpIGNvbnN0OworCisJaW50CQkJCQkJCQlHZXRTZWxlY3RlZEluZGV4KGludCBuSW5kZXgpIGNvbnN0OworCUNGWF9XaWRlU3RyaW5nCQkJCQlHZXRWYWx1ZSgpIGNvbnN0OworCUNGWF9XaWRlU3RyaW5nCQkJCQlHZXREZWZhdWx0VmFsdWUoKSBjb25zdDsKKwlDRlhfV2lkZVN0cmluZwkJCQkJR2V0T3B0aW9uTGFiZWwoaW50IG5JbmRleCkgY29uc3Q7CisJaW50CQkJCQkJCQlDb3VudE9wdGlvbnMoKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCUlzT3B0aW9uU2VsZWN0ZWQoaW50IG5JbmRleCkgY29uc3Q7CisJaW50CQkJCQkJCQlHZXRUb3BWaXNpYmxlSW5kZXgoKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCUlzQ2hlY2tlZCgpIGNvbnN0OworCS8qCisJQkZfQUxJR05fTEVGVAorCUJGX0FMSUdOX01JRERMCisJQkZfQUxJR05fUklHSFQKKwkqLworCWludAkJCQkJCQkJR2V0QWxpZ25tZW50KCkgY29uc3Q7CisJaW50CQkJCQkJCQlHZXRNYXhMZW4oKSBjb25zdDsKKwlDRlhfV2lkZVN0cmluZwkJCQkJR2V0QWx0ZXJuYXRlTmFtZSgpIGNvbnN0OworCisvL1NldCBQcm9wZXJ0aWVzLgorCXZvaWQJCQkJCQkJU2V0Q2hlY2soRlhfQk9PTCBiQ2hlY2tlZCwgRlhfQk9PTCBiTm90aWZ5KTsKKwl2b2lkCQkJCQkJCVNldFZhbHVlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVmFsdWUsIEZYX0JPT0wgYk5vdGlmeSk7CisJdm9pZAkJCQkJCQlTZXREZWZhdWx0VmFsdWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNWYWx1ZSk7CisJdm9pZAkJCQkJCQlTZXRPcHRpb25TZWxlY3Rpb24oaW50IGluZGV4LCBGWF9CT09MIGJTZWxlY3RlZCwgRlhfQk9PTCBiTm90aWZ5KTsKKwl2b2lkCQkJCQkJCUNsZWFyU2VsZWN0aW9uKEZYX0JPT0wgYk5vdGlmeSk7CisJdm9pZAkJCQkJCQlTZXRUb3BWaXNpYmxlSW5kZXgoaW50IGluZGV4KTsKKworCXZvaWQJCQkJCQkJUmVzZXRBcHBlYXJhbmNlKEZYX0xQQ1dTVFIgc1ZhbHVlLCBGWF9CT09MIGJWYWx1ZUNoYW5nZWQpOworCXZvaWQJCQkJCQkJUmVzZXRGaWVsZEFwcGVhcmFuY2UoRlhfQk9PTCBiVmFsdWVDaGFuZ2VkKTsKKwl2b2lkCQkJCQkJCVVwZGF0ZUZpZWxkKCk7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCU9uRm9ybWF0KGludCBuQ29tbWl0S2V5LCBGWF9CT09MJiBiRm9ybWF0ZWQpOworCQorLy9NZXNzYWdlLgorIAlGWF9CT09MCQkJCQkJCU9uQUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIFBERlNES19GaWVsZEFjdGlvbiYgZGF0YSwgCisJCQkJCQkJCQkJCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCisJQ1BERlNES19JbnRlckZvcm0qCQkJCUdldEludGVyRm9ybSgpIGNvbnN0IHtyZXR1cm4gbV9wSW50ZXJGb3JtO30KKwlDUERGX0Zvcm1GaWVsZCoJCQkJCUdldEZvcm1GaWVsZCgpIGNvbnN0OworCUNQREZfRm9ybUNvbnRyb2wqCQkJCUdldEZvcm1Db250cm9sKCkgY29uc3Q7CisJc3RhdGljIENQREZfRm9ybUNvbnRyb2wqCQlHZXRGb3JtQ29udHJvbChDUERGX0ludGVyRm9ybSogcEludGVyRm9ybSwgQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0KTsKKworCXZvaWQJCQkJCQkJRHJhd1NoYWRvdyhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOworCQorCXZvaWQJCQkJCQkJU2V0QXBwTW9kaWZpZWQoKTsKKwl2b2lkCQkJCQkJCUNsZWFyQXBwTW9kaWZpZWQoKTsKKwlGWF9CT09MCQkJCQkJCUlzQXBwTW9kaWZpZWQoKSBjb25zdDsKKwkKKwlGWF9JTlQzMgkJCQkJCUdldEFwcGVhcmFuY2VBZ2UoKSBjb25zdDsKKwlGWF9JTlQzMgkJCQkJCUdldFZhbHVlQWdlKCkgY29uc3Q7CisJCitwcml2YXRlOgorCXZvaWQJCQkJCQkJUmVzZXRBcHBlYXJhbmNlX1B1c2hCdXR0b24oKTsKKwl2b2lkCQkJCQkJCVJlc2V0QXBwZWFyYW5jZV9DaGVja0JveCgpOworCXZvaWQJCQkJCQkJUmVzZXRBcHBlYXJhbmNlX1JhZGlvQnV0dG9uKCk7CisJdm9pZAkJCQkJCQlSZXNldEFwcGVhcmFuY2VfQ29tYm9Cb3goRlhfTFBDV1NUUiBzVmFsdWUpOworCXZvaWQJCQkJCQkJUmVzZXRBcHBlYXJhbmNlX0xpc3RCb3goKTsKKwl2b2lkCQkJCQkJCVJlc2V0QXBwZWFyYW5jZV9UZXh0RmllbGQoRlhfTFBDV1NUUiBzVmFsdWUpOworCQorCUNQREZfUmVjdAkJCQkJCUdldENsaWVudFJlY3QoKSBjb25zdDsKKwlDUERGX1JlY3QJCQkJCQlHZXRSb3RhdGVkUmVjdCgpIGNvbnN0OworCQorCUNGWF9CeXRlU3RyaW5nCQkJCQlHZXRCYWNrZ3JvdW5kQXBwU3RyZWFtKCkgY29uc3Q7CisJQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEJvcmRlckFwcFN0cmVhbSgpIGNvbnN0OworCUNQREZfTWF0cml4CQkJCQkJR2V0TWF0cml4KCkgY29uc3Q7CisJCisJQ1BXTF9Db2xvcgkJCQkJCUdldFRleHRQV0xDb2xvcigpIGNvbnN0OworCUNQV0xfQ29sb3IJCQkJCQlHZXRCb3JkZXJQV0xDb2xvcigpIGNvbnN0OworCUNQV0xfQ29sb3IJCQkJCQlHZXRGaWxsUFdMQ29sb3IoKSBjb25zdDsKKwkKKwl2b2lkCQkJCQkJCUFkZEltYWdlVG9BcHBlYXJhbmNlKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzQVBUeXBlLCBDUERGX1N0cmVhbSogcEltYWdlKTsKKwl2b2lkCQkJCQkJCVJlbW92ZUFwcGVhcmFuY2UoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFR5cGUpOworcHVibGljOgorCUZYX0JPT0wJCQkJCQkJSXNXaWRnZXRBcHBlYXJhbmNlVmFsaWQoQ1BERl9Bbm5vdDo6QXBwZWFyYW5jZU1vZGUgbW9kZSk7CisJdm9pZAkJCQkJCQlEcmF3QXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBjb25zdCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQlDUERGX0Fubm90OjpBcHBlYXJhbmNlTW9kZSBtb2RlLCBjb25zdCBDUERGX1JlbmRlck9wdGlvbnMqIHBPcHRpb25zKTsKK3B1YmxpYzoKKwlGWF9CT09MCQkJCQkJCUhpdFRlc3QoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKTsKK3ByaXZhdGU6CisJQ1BERlNES19JbnRlckZvcm0qCQkJCW1fcEludGVyRm9ybTsKKwlGWF9CT09MCQkJCQkJCW1fYkFwcE1vZGlmaWVkOworCUZYX0lOVDMyCQkJCQkJbV9uQXBwQWdlOworCUZYX0lOVDMyCQkJCQkJbV9uVmFsdWVBZ2U7Cit9OworCisjZGVmaW5lIENQREZTREtfV2lkZ2V0TWFwCQkJCUNGWF9NYXBQdHJUZW1wbGF0ZTxDUERGX0Zvcm1Db250cm9sKiwgQ1BERlNES19XaWRnZXQqPgorCitjbGFzcyBDUERGU0RLX0ludGVyRm9ybSA6IHB1YmxpYyBDUERGX0Zvcm1Ob3RpZnkKK3sKK3B1YmxpYzoKKwlDUERGU0RLX0ludGVyRm9ybShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpOworCXZpcnR1YWwgfkNQREZTREtfSW50ZXJGb3JtKCk7CisJCitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCQlEZXN0cm95KCk7CisJdmlydHVhbCBDUERGX0ludGVyRm9ybSoJCQlHZXRJbnRlckZvcm0oKTsKKwkKKwlDUERGU0RLX0RvY3VtZW50KgkJCQlHZXREb2N1bWVudCgpOworCUZYX0JPT0wJCQkJCQkJSGlnaGxpZ2h0V2lkZ2V0cygpOworCQorCUNQREZTREtfV2lkZ2V0KgkJCQkJR2V0U2libGluZyhDUERGU0RLX1dpZGdldCogcFdpZGdldCwgRlhfQk9PTCBiTmV4dCkgY29uc3Q7CisJQ1BERlNES19XaWRnZXQqCQkJCQlHZXRXaWRnZXQoQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wpIGNvbnN0OworCXZvaWQJCQkJCQkJR2V0V2lkZ2V0cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpZWxkTmFtZSwgQ0ZYX1B0ckFycmF5JiB3aWRnZXRzKTsKKwl2b2lkCQkJCQkJCUdldFdpZGdldHMoQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCwgQ0ZYX1B0ckFycmF5JiB3aWRnZXRzKTsKKwkKKwl2b2lkCQkJCQkJCUFkZE1hcChDUERGX0Zvcm1Db250cm9sKiBwQ29udHJvbCwgQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpOworCXZvaWQJCQkJCQkJUmVtb3ZlTWFwKENQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sKTsKKwkKKwl2b2lkCQkJCQkJCUVuYWJsZUNhbGN1bGF0ZShGWF9CT09MIGJFbmFibGVkKTsKKwlGWF9CT09MCQkJCQkJCUlzQ2FsY3VsYXRlRW5hYmxlZCgpIGNvbnN0OworCisjaWZkZWYgX1dJTjMyCisJQ1BERl9TdHJlYW0qCQkJCQlMb2FkSW1hZ2VGcm9tRmlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpbGUpOworI2VuZGlmCisKKwl2b2lkCQkJCQkJCU9uS2V5U3Ryb2tlQ29tbWl0KENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCBDRlhfV2lkZVN0cmluZyYgY3NWYWx1ZSwgRlhfQk9PTCYgYlJDKTsKKwl2b2lkCQkJCQkJCU9uVmFsaWRhdGUoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIENGWF9XaWRlU3RyaW5nJiBjc1ZhbHVlLCBGWF9CT09MJiBiUkMpOworCXZvaWQJCQkJCQkJT25DYWxjdWxhdGUoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBOVUxMKTsKKwlDRlhfV2lkZVN0cmluZwkJCQkJT25Gb3JtYXQoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIGludCBuQ29tbWl0S2V5LCBGWF9CT09MJiBiRm9ybWF0ZWQpOworCQorCXZvaWQJCQkJCQkJUmVzZXRGaWVsZEFwcGVhcmFuY2UoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIEZYX0xQQ1dTVFIgc1ZhbHVlLCBGWF9CT09MIGJWYWx1ZUNoYW5nZWQpOworCXZvaWQJCQkJCQkJVXBkYXRlRmllbGQoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQpOworCQorcHVibGljOgorCUZYX0JPT0wJCQkJCQkJRG9BY3Rpb25fSGlkZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKTsKKwlGWF9CT09MCQkJCQkJCURvQWN0aW9uX1N1Ym1pdEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbik7CisJRlhfQk9PTAkJCQkJCQlEb0FjdGlvbl9SZXNldEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbik7CisJRlhfQk9PTAkJCQkJCQlEb0FjdGlvbl9JbXBvcnREYXRhKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pOworCQorCXZvaWQJCQkJCQkJR2V0RmllbGRGcm9tT2JqZWN0cyhjb25zdCBDRlhfUHRyQXJyYXkmIG9iamVjdHMsIENGWF9QdHJBcnJheSYgZmllbGRzKTsKKwlGWF9CT09MCQkJCQkJCUlzVmFsaWRGaWVsZChDUERGX0RpY3Rpb25hcnkqIHBGaWVsZERpY3QpOworCUZYX0JPT0wJCQkJCQkJU3VibWl0RmllbGRzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBjc0Rlc3RpbmF0aW9uLCBjb25zdCBDRlhfUHRyQXJyYXkmIGZpZWxkcywgCisJCUZYX0JPT0wgYkluY2x1ZGVPckV4Y2x1ZGUsIEZYX0JPT0wgYlVybEVuY29kZWQpOworCUZYX0JPT0wJCQkJCQkJU3VibWl0Rm9ybShjb25zdCBDRlhfV2lkZVN0cmluZyYgc0Rlc3RpbmF0aW9uLCBGWF9CT09MIGJVcmxFbmNvZGVkKTsKKwlGWF9CT09MCQkJCQkJCUltcG9ydEZvcm1Gcm9tRkRGRmlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgY3NGREZGaWxlTmFtZSwgRlhfQk9PTCBiTm90aWZ5KTsKKwlGWF9CT09MCQkJCQkJCUV4cG9ydEZvcm1Ub0ZERkZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGREZGaWxlTmFtZSk7CisJRlhfQk9PTAkJCQkJCQlFeHBvcnRGb3JtVG9GREZUZXh0QnVmKENGWF9CeXRlVGV4dEJ1ZiYgdGV4dEJ1Zik7CisJRlhfQk9PTAkJCQkJCQlFeHBvcnRGaWVsZHNUb0ZERkZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGREZGaWxlTmFtZSwgY29uc3QgQ0ZYX1B0ckFycmF5JiBmaWVsZHMsCisJCUZYX0JPT0wgYkluY2x1ZGVPckV4Y2x1ZGUpOworCUZYX0JPT0wJCQkJCQkJRXhwb3J0RmllbGRzVG9GREZUZXh0QnVmKGNvbnN0IENGWF9QdHJBcnJheSYgZmllbGRzLEZYX0JPT0wgYkluY2x1ZGVPckV4Y2x1ZGUsIENGWF9CeXRlVGV4dEJ1ZiYgdGV4dEJ1Zik7CisJRlhfQk9PTAkJCQkJCQlFeHBvcnRGb3JtVG9UeHRGaWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVHh0RmlsZU5hbWUpOworCUZYX0JPT0wJCQkJCQkJSW1wb3J0Rm9ybUZyb21UeHRGaWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVHh0RmlsZU5hbWUpOworCUNGWF9XaWRlU3RyaW5nCQkJCQlHZXRUZW1wb3JhcnlGaWxlTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpbGVFeHQpOworCQorcHJpdmF0ZToKKwl2aXJ0dWFsIGludAkJCQkJCUJlZm9yZVZhbHVlQ2hhbmdlKGNvbnN0IENQREZfRm9ybUZpZWxkKiBwRmllbGQsIENGWF9XaWRlU3RyaW5nJiBjc1ZhbHVlKTsKKwl2aXJ0dWFsIGludAkJCQkJCUFmdGVyVmFsdWVDaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCk7CisJdmlydHVhbCBpbnQJCQkJCQlCZWZvcmVTZWxlY3Rpb25DaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIGNzVmFsdWUpOworCXZpcnR1YWwgaW50CQkJCQkJQWZ0ZXJTZWxlY3Rpb25DaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCk7CisJdmlydHVhbCBpbnQJCQkJCQlBZnRlckNoZWNrZWRTdGF0dXNDaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCwgY29uc3QgQ0ZYX0J5dGVBcnJheSYgc3RhdHVzQXJyYXkpOworCXZpcnR1YWwgaW50CQkJCQkJQmVmb3JlRm9ybVJlc2V0KGNvbnN0IENQREZfSW50ZXJGb3JtKiBwRm9ybSk7CisJdmlydHVhbCBpbnQJCQkJCQlBZnRlckZvcm1SZXNldChjb25zdCBDUERGX0ludGVyRm9ybSogcEZvcm0pOworCXZpcnR1YWwgaW50CQkJCQkJQmVmb3JlRm9ybUltcG9ydERhdGEoY29uc3QgQ1BERl9JbnRlckZvcm0qIHBGb3JtKTsKKwl2aXJ0dWFsIGludAkJCQkJCUFmdGVyRm9ybUltcG9ydERhdGEoY29uc3QgQ1BERl9JbnRlckZvcm0qIHBGb3JtKTsKKwkKK3ByaXZhdGU6CisJRlhfQk9PTAkJCQkJCQlGREZUb1VSTEVuY29kZWREYXRhKENGWF9XaWRlU3RyaW5nIGNzRkRGRmlsZSwgQ0ZYX1dpZGVTdHJpbmcgY3NUeHRGaWxlKTsKKwlGWF9CT09MCQkJCQkJCUZERlRvVVJMRW5jb2RlZERhdGEoRlhfTFBCWVRFJiBwQnVmLCBGWF9TVFJTSVpFJiBuQnVmU2l6ZSk7CisJaW50CQkJCQkJCQlHZXRQYWdlSW5kZXhCeUFubm90RGljdChDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRGljdGlvbmFyeSogcEFubm90RGljdCkgY29uc3Q7CisJdm9pZAkJCQkJCQlEb0ZERkJ1ZmZlcihDRlhfQnl0ZVN0cmluZyBzQnVmZmVyKTsKKwkKK3ByaXZhdGU6CisJQ1BERlNES19Eb2N1bWVudCoJCQkJbV9wRG9jdW1lbnQ7CisJQ1BERl9JbnRlckZvcm0qCQkJCQltX3BJbnRlckZvcm07CisJQ1BERlNES19XaWRnZXRNYXAJCQkJbV9NYXA7CisJRlhfQk9PTAkJCQkJCQltX2JDYWxjdWxhdGU7CisJRlhfQk9PTAkJCQkJCQltX2JCdXN5OworCitwdWJsaWM6CisJRlhfQk9PTCBJc05lZWRIaWdoTGlnaHQoaW50IG5GaWVsZFR5cGUpOworCXZvaWQgICAgUmVtb3ZlQWxsSGlnaExpZ2h0KCk7CisJdm9pZCAgICBTZXRIaWdobGlnaHRBbHBoYShGWF9CWVRFIGFscGhhKSB7bV9pSGlnaGxpZ2h0QWxwaGEgPSBhbHBoYTt9CisJRlhfQllURSBHZXRIaWdobGlnaHRBbHBoYSgpIHtyZXR1cm4gbV9pSGlnaGxpZ2h0QWxwaGE7fQorCXZvaWQgICAgU2V0SGlnaGxpZ2h0Q29sb3IoRlhfQ09MT1JSRUYgY2xyLCBpbnQgbkZpZWxkVHlwZSk7CisJRlhfQ09MT1JSRUYgR2V0SGlnaGxpZ2h0Q29sb3IoaW50IG5GaWVsZFR5cGUpOworcHJpdmF0ZToKKwlGWF9DT0xPUlJFRiBtX2FIaWdobGlnaHRDb2xvcls2XTsKKwlGWF9CWVRFIG1faUhpZ2hsaWdodEFscGhhOworCUZYX0JPT0wJbV9iTmVlZEhpZ2h0bGlnaHRbNl07Cit9OworCisjZGVmaW5lIEJBSV9TVFJVQ1RVUkUJCTAKKyNkZWZpbmUgQkFJX1JPVwkJCQkxCisjZGVmaW5lIEJBSV9DT0xVTU4JCQkyCisKKyNkZWZpbmUgQ1BERlNES19Bbm5vdHMJCQkJQ0ZYX0FycmF5VGVtcGxhdGU8Q1BERlNES19Bbm5vdCo+CisjZGVmaW5lIENQREZTREtfU29ydEFubm90cwkJCUNHV19BcnJheVRlbXBsYXRlPENQREZTREtfQW5ub3QqPgorY2xhc3MgQ0JBX0Fubm90SXRlcmF0b3IgCit7CitwdWJsaWM6CisJQ0JBX0Fubm90SXRlcmF0b3IoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc1R5cGUsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzU3ViVHlwZSk7CisJdmlydHVhbCB+Q0JBX0Fubm90SXRlcmF0b3IoKTsKKwkKKwl2aXJ0dWFsIENQREZTREtfQW5ub3QqCQkJCUdldEZpcnN0QW5ub3QoKTsKKwl2aXJ0dWFsIENQREZTREtfQW5ub3QqCQkJCUdldExhc3RBbm5vdCgpOworCXZpcnR1YWwgQ1BERlNES19Bbm5vdCoJCQkJR2V0TmV4dEFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCk7CisJdmlydHVhbCBDUERGU0RLX0Fubm90KgkJCQlHZXRQcmV2QW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90KTsKKwkKKwl2aXJ0dWFsIHZvaWQJCQkJCQlSZWxlYXNlKCl7ZGVsZXRlIHRoaXM7fQorCQorcHJpdmF0ZToKKwl2b2lkCQkJCQkJCQlHZW5lcmF0ZVJlc3VsdHMoKTsKKwlzdGF0aWMgaW50CQkJCQkJCUNvbXBhcmVCeUxlZnQoQ1BERlNES19Bbm5vdCogcDEsIENQREZTREtfQW5ub3QqIHAyKTsKKwlzdGF0aWMgaW50CQkJCQkJCUNvbXBhcmVCeVRvcChDUERGU0RLX0Fubm90KiBwMSwgQ1BERlNES19Bbm5vdCogcDIpOworCQorCXN0YXRpYyBDUERGX1JlY3QJCQkJCUdldEFubm90UmVjdChDUERGU0RLX0Fubm90KiBwQW5ub3QpOworCQorcHJpdmF0ZToKKwlDUERGU0RLX1BhZ2VWaWV3KgkJCQkJbV9wUGFnZVZpZXc7CisJQ0ZYX0J5dGVTdHJpbmcJCQkJCQltX3NUeXBlOworCUNGWF9CeXRlU3RyaW5nCQkJCQkJbV9zU3ViVHlwZTsKKwlpbnQJCQkJCQkJCQltX25UYWJzOworCQorCUNQREZTREtfQW5ub3RzCQkJCQkJbV9Bbm5vdHM7Cit9OworCisjZW5kaWYgLy8jZGVmaW5lIF9GU0RLX0JBU0VGT1JNX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2NvbW1vbi5oIGIvZnBkZnNkay9pbmNsdWRlL2ZzZGtfY29tbW9uLmgKaW5kZXggYjQ5YzFkMS4uMTk3OTE3YyAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZzZGtfY29tbW9uLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2ZzZGtfY29tbW9uLmgKQEAgLTEsNDYgKzEsNDYgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZTREtfQ09NTU9OX0hfDQotI2RlZmluZSBfRlNES19DT01NT05fSF8NCi0NCi0jZGVmaW5lIEJGRlRfU0lHTkFUVVJFCQkJCSJTaWduYXR1cmUiDQotDQotLy9mb3IgYWxsIGZpZWxkcw0KLSNkZWZpbmUgRklFTERGTEFHX1JFQURPTkxZCQkJCQkxDQotI2RlZmluZSBGSUVMREZMQUdfUkVRVUlSRUQJCQkJCTINCi0jZGVmaW5lIEZJRUxERkxBR19OT0VYUE9SVAkJCQkJNA0KLS8vZm9yIHRleHQgZmllbGRzDQotI2RlZmluZSBGSUVMREZMQUdfTVVMVElMSU5FCQkJCQkoMTw8MTIpDQotI2RlZmluZSBGSUVMREZMQUdfUEFTU1dPUkQJCQkJCSgxPDwxMykNCi0jZGVmaW5lIEZJRUxERkxBR19GSUxFU0VMRUNUCQkJCSgxPDwyMCkNCi0jZGVmaW5lIEZJRUxERkxBR19ET05PVFNQRUxMQ0hFQ0sJCQkoMTw8MjIpDQotI2RlZmluZSBGSUVMREZMQUdfRE9OT1RTQ1JPTEwJCQkJKDE8PDIzKQ0KLSNkZWZpbmUgRklFTERGTEFHX0NPTUIJCQkJCQkoMTw8MjQpDQotI2RlZmluZSBGSUVMREZMQUdfUklDSFRFWFQJCQkJCSgxPDwyNSkNCi0vL2ZvciBidXR0b24gZmlsZWRzDQotI2RlZmluZSBGSUVMREZMQUdfTk9UT0dHTEVUT09GRgkJCQkoMTw8MTQpDQotI2RlZmluZSBGSUVMREZMQUdfUkFESU8JCQkJCQkoMTw8MTUpDQotI2RlZmluZSBGSUVMREZMQUdfUFVTSEJVVFRPTgkJCQkoMTw8MTYpDQotI2RlZmluZSBGSUVMREZMQUdfUkFESU9TSU5VTklTT04JCQkoMTw8MjUpDQotLy9mb3IgY2hvaWNlIGZpZWxkcw0KLSNkZWZpbmUgRklFTERGTEFHX0NPTUJPCQkJCQkJKDE8PDE3KQ0KLSNkZWZpbmUgRklFTERGTEFHX0VESVQJCQkJCQkoMTw8MTgpDQotI2RlZmluZSBGSUVMREZMQUdfU09SVAkJCQkJCSgxPDwxOSkNCi0jZGVmaW5lIEZJRUxERkxBR19NVUxUSVNFTEVDVAkJCQkoMTw8MjEpDQotI2lmbmRlZiBGSUVMREZMQUdfRE9OT1RTUEVMTENIRUNLDQotI2RlZmluZSBGSUVMREZMQUdfRE9OT1RTUEVMTENIRUNLCQkoMTw8MjIpDQotI2VuZGlmDQotI2RlZmluZSBGSUVMREZMQUdfQ09NTUlUT05TRUxDSEFOR0UJCQkoMTw8MjYpDQotDQotI2RlZmluZSBCQlNfU09MSUQJCQkJCTANCi0jZGVmaW5lIEJCU19EQVNICQkJCQkxDQotI2RlZmluZSBCQlNfQkVWRUxFRAkJCQkJMg0KLSNkZWZpbmUgQkJTX0lOU0VUCQkJCQkzDQotI2RlZmluZSBCQlNfVU5ERVJMSU5FCQkJCTQNCi0NCi0NCi0jZW5kaWYNCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GU0RLX0NPTU1PTl9IXworI2RlZmluZSBfRlNES19DT01NT05fSF8KKworI2RlZmluZSBCRkZUX1NJR05BVFVSRQkJCQkiU2lnbmF0dXJlIgorCisvL2ZvciBhbGwgZmllbGRzCisjZGVmaW5lIEZJRUxERkxBR19SRUFET05MWQkJCQkJMQorI2RlZmluZSBGSUVMREZMQUdfUkVRVUlSRUQJCQkJCTIKKyNkZWZpbmUgRklFTERGTEFHX05PRVhQT1JUCQkJCQk0CisvL2ZvciB0ZXh0IGZpZWxkcworI2RlZmluZSBGSUVMREZMQUdfTVVMVElMSU5FCQkJCQkoMTw8MTIpCisjZGVmaW5lIEZJRUxERkxBR19QQVNTV09SRAkJCQkJKDE8PDEzKQorI2RlZmluZSBGSUVMREZMQUdfRklMRVNFTEVDVAkJCQkoMTw8MjApCisjZGVmaW5lIEZJRUxERkxBR19ET05PVFNQRUxMQ0hFQ0sJCQkoMTw8MjIpCisjZGVmaW5lIEZJRUxERkxBR19ET05PVFNDUk9MTAkJCQkoMTw8MjMpCisjZGVmaW5lIEZJRUxERkxBR19DT01CCQkJCQkJKDE8PDI0KQorI2RlZmluZSBGSUVMREZMQUdfUklDSFRFWFQJCQkJCSgxPDwyNSkKKy8vZm9yIGJ1dHRvbiBmaWxlZHMKKyNkZWZpbmUgRklFTERGTEFHX05PVE9HR0xFVE9PRkYJCQkJKDE8PDE0KQorI2RlZmluZSBGSUVMREZMQUdfUkFESU8JCQkJCQkoMTw8MTUpCisjZGVmaW5lIEZJRUxERkxBR19QVVNIQlVUVE9OCQkJCSgxPDwxNikKKyNkZWZpbmUgRklFTERGTEFHX1JBRElPU0lOVU5JU09OCQkJKDE8PDI1KQorLy9mb3IgY2hvaWNlIGZpZWxkcworI2RlZmluZSBGSUVMREZMQUdfQ09NQk8JCQkJCQkoMTw8MTcpCisjZGVmaW5lIEZJRUxERkxBR19FRElUCQkJCQkJKDE8PDE4KQorI2RlZmluZSBGSUVMREZMQUdfU09SVAkJCQkJCSgxPDwxOSkKKyNkZWZpbmUgRklFTERGTEFHX01VTFRJU0VMRUNUCQkJCSgxPDwyMSkKKyNpZm5kZWYgRklFTERGTEFHX0RPTk9UU1BFTExDSEVDSworI2RlZmluZSBGSUVMREZMQUdfRE9OT1RTUEVMTENIRUNLCQkoMTw8MjIpCisjZW5kaWYKKyNkZWZpbmUgRklFTERGTEFHX0NPTU1JVE9OU0VMQ0hBTkdFCQkJKDE8PDI2KQorCisjZGVmaW5lIEJCU19TT0xJRAkJCQkJMAorI2RlZmluZSBCQlNfREFTSAkJCQkJMQorI2RlZmluZSBCQlNfQkVWRUxFRAkJCQkJMgorI2RlZmluZSBCQlNfSU5TRVQJCQkJCTMKKyNkZWZpbmUgQkJTX1VOREVSTElORQkJCQk0CisKKworI2VuZGlmCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZnNka19kZWZpbmUuaCBiL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2RlZmluZS5oCmluZGV4IDVmOWNkZTMuLjJiZjQ3MjEgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2RlZmluZS5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX2RlZmluZS5oCkBAIC0xLDEyOCArMSwxMjggQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZQREZTREtfREVGSU5FX0gNCi0jZGVmaW5lIF9GUERGU0RLX0RFRklORV9IDQotDQotI2lmZGVmIF9XSU4zMg0KLSNpbmNsdWRlIDx0Y2hhci5oPg0KLSNpbmNsdWRlIDxtYXRoLmg+DQotI2VuZGlmDQotDQotLy8jZGVmaW5lIEFQSTUNCi0jZGVmaW5lIEFQSTYNCi0jZGVmaW5lICBfRlBERkFQSV9BU1lOQ19QQVJTSU5HXw0KLSNkZWZpbmUgX0ZYU0RLX09QRU5TT1VSQ0VfDQotDQotI2lmZGVmIF9GUERGRU1CX1dDRV8NCi0JI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZhcGkuaCIgDQotCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX3BhcnNlci5oIiANCi0JI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfbW9kdWxlLmgiIA0KLQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9yZW5kZXIuaCIgDQotCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX3BhZ2VvYmouaCIgDQotCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX3NlcmlhbC5oIiANCi0NCi0JI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmdGV4dC9mcGRmX3RleHQuaCINCi0NCi0JI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9meGdlL2Z4X2dlX3dpbjMyLmgiDQotCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnhnZS9meF9nZS5oIg0KLQ0KLQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2Z4Y29kZWMvZnhfY29kZWMuaCINCi0NCi0JI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmZG9jL2ZwZGZfZG9jLmgiIA0KLQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl92dC5oIiANCi0NCi0JI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9meGNydC9meF94bWwuaCIgDQotCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnhjcnQvZnhfY3J5cHQuaCINCi0NCi0jZWxzZQ0KLQkjaWZkZWYgQVBJNg0KLQkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfcGFyc2VyLmgiIA0KLQkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZhcGkuaCIgDQotCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9wYXJzZXIuaCIgDQotCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9tb2R1bGUuaCIgDQotCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9yZW5kZXIuaCIgDQotCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9wYWdlb2JqLmgiIA0KLQkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfc2VyaWFsLmgiIA0KLQ0KLQkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmdGV4dC9mcGRmX3RleHQuaCINCi0NCi0JCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnhnZS9meF9nZV93aW4zMi5oIg0KLQkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9meGdlL2Z4X2dlLmgiDQotDQotCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2Z4Y29kZWMvZnhfY29kZWMuaCINCi0NCi0JCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmRvYy9mcGRmX2RvYy5oIiANCi0JCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmRvYy9mcGRmX3Z0LmgiIA0KLQ0KLQkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9meGNydC9meF94bWwuaCIgDQotCS8vCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZmRybS9meF9jcnlwdC5oIg0KLQkJI2lmZGVmIF9MSUNFTlNFRF9CVUlMRF8NCi0JCQkjaW5jbHVkZSAiLi4vLi4vY3J5cHRvcHAvQ3J5cHRsaWIuaCINCi0JCSNlbmRpZg0KLQkjZW5kaWYNCi0jZW5kaWYNCi0NCi0NCi0jaWZuZGVmIEZYX0dldEFWYWx1ZQ0KLS8qKiBAYnJpZWYgSXQgcmV0cmlldmVzIGFuIGludGVuc2l0eSB2YWx1ZSBmb3IgdGhlIGFscGhhIGNvbXBvbmVudCBvZiBhICNGWF9BUkdCIHZhbHVlLiAqLw0KLSNkZWZpbmUgRlhfR2V0QVZhbHVlKGFyZ2IpCQkJKChhcmdiICYgMHhGRjAwMDAwMCkgPj4gMjQpDQotI2VuZGlmDQotDQotI2lmbmRlZiBGWF9HZXRSVmFsdWUNCi0vKiogQGJyaWVmIEl0IHJldHJpZXZlcyBhbiBpbnRlbnNpdHkgdmFsdWUgZm9yIHRoZSByZWQgY29tcG9uZW50IG9mIGEgI0ZYX0FSR0IgdmFsdWUuICovDQotI2RlZmluZSBGWF9HZXRSVmFsdWUoYXJnYikJCQkoKGFyZ2IgJiAweDAwRkYwMDAwKSA+PiAxNikNCi0jZW5kaWYNCi0NCi0jaWZuZGVmIEZYX0dldEdWYWx1ZQ0KLS8qKiBAYnJpZWYgSXQgcmV0cmlldmVzIGFuIGludGVuc2l0eSB2YWx1ZSBmb3IgdGhlIGdyZWVuIGNvbXBvbmVudCBvZiBhICNGWF9BUkdCIHZhbHVlLiAqLw0KLSNkZWZpbmUgRlhfR2V0R1ZhbHVlKGFyZ2IpCQkJKChhcmdiICYgMHgwMDAwRkYwMCkgPj4gOCkNCi0jZW5kaWYNCi0NCi0jaWZuZGVmIEZYX0dldEJWYWx1ZQ0KLS8qKiBAYnJpZWYgSXQgcmV0cmlldmVzIGFuIGludGVuc2l0eSB2YWx1ZSBmb3IgdGhlIGJsdWUgY29tcG9uZW50IG9mIGEgI0ZYX0FSR0IgdmFsdWUuICovDQotI2RlZmluZSBGWF9HZXRCVmFsdWUoYXJnYikJCQkoYXJnYiAmIDB4MDAwMDAwRkYpDQotI2VuZGlmDQotDQotI2lmbmRlZiBGWF9BUkdCVE9DT0xPUlJFRg0KLS8qKiBAYnJpZWYgQ29udmVydCBhICNGWF9BUkdCIHRvIGEgI0ZYX0NPTE9SUkVGLiAqLw0KLSNkZWZpbmUgRlhfQVJHQlRPQ09MT1JSRUYoYXJnYikJCSgoKChGWF9EV09SRClhcmdiICYgMHgwMEZGMDAwMCkgPj4gMTYpfCgoRlhfRFdPUkQpYXJnYiAmIDB4MDAwMEZGMDApfCgoKEZYX0RXT1JEKWFyZ2IgJiAweDAwMDAwMEZGKSA8PCAxNikpDQotI2VuZGlmDQotDQotI2lmbmRlZiBGWF9DT0xPUlJFRlRPQVJHQg0KLS8qKiBAYnJpZWYgQ29udmVydCBhICNGWF9DT0xPUlJFRiB0byBhICNGWF9BUkdCLiAqLw0KLSNkZWZpbmUgRlhfQ09MT1JSRUZUT0FSR0IocmdiKQkJKChGWF9EV09SRCkweEZGMDAwMDAwfCgoKEZYX0RXT1JEKXJnYiAmIDB4MDAwMDAwRkYpIDw8IDE2KXwoKEZYX0RXT1JEKXJnYiAmIDB4MDAwMEZGMDApfCgoKEZYX0RXT1JEKXJnYiAmIDB4MDBGRjAwMDApID4+IDE2KSkNCi0jZW5kaWYNCi0NCi10eXBlZGVmIHVuc2lnbmVkIGludCBGWF9VSU5UOwkNCi0NCi0jaW5jbHVkZSAiZnBkZnZpZXcuaCINCi0NCi1jbGFzcyBDUERGX0N1c3RvbUFjY2VzcyA6IHB1YmxpYyBJRlhfRmlsZVJlYWQsIHB1YmxpYyBDRlhfT2JqZWN0DQotew0KLXB1YmxpYzoNCi0JQ1BERl9DdXN0b21BY2Nlc3MoRlBERl9GSUxFQUNDRVNTKiBwRmlsZUFjY2Vzcyk7DQotCX5DUERGX0N1c3RvbUFjY2VzcygpIHt9DQotDQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcgR2V0RnVsbFBhdGgoKSB7IHJldHVybiAiIjsgfQ0KLQl2aXJ0dWFsIEZYX0ZJTEVTSVpFCUdldFNpemUoKSB7IHJldHVybiBtX0ZpbGVBY2Nlc3MubV9GaWxlTGVuOyB9DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJR2V0Qnl0ZShGWF9EV09SRCBwb3MsIEZYX0JZVEUmIGNoKTsNCi0JdmlydHVhbCBGWF9CT09MCQlHZXRCbG9jayhGWF9EV09SRCBwb3MsIEZYX0xQQllURSBwQnVmLCBGWF9EV09SRCBzaXplKTsNCi0JdmlydHVhbCB2b2lkCQlSZWxlYXNlKCkgeyBkZWxldGUgdGhpczsgfQ0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCVJlYWRCbG9jayh2b2lkKiBidWZmZXIsIEZYX0ZJTEVTSVpFIG9mZnNldCwgc2l6ZV90IHNpemUpOw0KLQ0KLQlGUERGX0ZJTEVBQ0NFU1MJCW1fRmlsZUFjY2VzczsNCi0JRlhfQllURQkJCQltX0J1ZmZlcls1MTJdOw0KLQlGWF9EV09SRAkJCW1fQnVmZmVyT2Zmc2V0Ow0KLX07DQotDQotdm9pZAkJRlNES19TZXRTYW5kQm94UG9saWN5KEZQREZfRFdPUkQgcG9saWN5LCBGUERGX0JPT0wgZW5hYmxlKTsNCi1GUERGX0JPT0wJRlNES19Jc1NhbmRCb3hQb2xpY3lFbmFibGVkKEZQREZfRFdPUkQgcG9saWN5KTsNCi0NCi0NCi0jZW5kaWYvL19GUERGU0RLX0RFRklORV9IDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRlBERlNES19ERUZJTkVfSAorI2RlZmluZSBfRlBERlNES19ERUZJTkVfSAorCisjaWZkZWYgX1dJTjMyCisjaW5jbHVkZSA8dGNoYXIuaD4KKyNpbmNsdWRlIDxtYXRoLmg+CisjZW5kaWYKKworLy8jZGVmaW5lIEFQSTUKKyNkZWZpbmUgQVBJNgorI2RlZmluZSAgX0ZQREZBUElfQVNZTkNfUEFSU0lOR18KKyNkZWZpbmUgX0ZYU0RLX09QRU5TT1VSQ0VfCisKKyNpZmRlZiBfRlBERkVNQl9XQ0VfCisJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZhcGkuaCIgCisJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfcGFyc2VyLmgiIAorCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX21vZHVsZS5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9yZW5kZXIuaCIgCisJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfcGFnZW9iai5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9zZXJpYWwuaCIgCisKKwkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZ0ZXh0L2ZwZGZfdGV4dC5oIgorCisJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9meGdlL2Z4X2dlX3dpbjMyLmgiCisJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9meGdlL2Z4X2dlLmgiCisKKwkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2Z4Y29kZWMvZnhfY29kZWMuaCIKKworCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmRvYy9mcGRmX2RvYy5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl92dC5oIiAKKworCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnhjcnQvZnhfeG1sLmgiIAorCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnhjcnQvZnhfY3J5cHQuaCIKKworI2Vsc2UKKwkjaWZkZWYgQVBJNgorCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9wYXJzZXIuaCIgCisJCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmYXBpLmgiIAorCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9wYXJzZXIuaCIgCisJCSNpbmNsdWRlICIuLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX21vZHVsZS5oIiAKKwkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfcmVuZGVyLmgiIAorCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9wYWdlb2JqLmgiIAorCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9zZXJpYWwuaCIgCisKKwkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmdGV4dC9mcGRmX3RleHQuaCIKKworCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2Z4Z2UvZnhfZ2Vfd2luMzIuaCIKKwkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9meGdlL2Z4X2dlLmgiCisKKwkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9meGNvZGVjL2Z4X2NvZGVjLmgiCisKKwkJI2luY2x1ZGUgIi4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmZG9jL2ZwZGZfZG9jLmgiIAorCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl92dC5oIiAKKworCQkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2Z4Y3J0L2Z4X3htbC5oIiAKKwkvLwkjaW5jbHVkZSAiLi4vLi4vY29yZS9pbmNsdWRlL2Zkcm0vZnhfY3J5cHQuaCIKKwkJI2lmZGVmIF9MSUNFTlNFRF9CVUlMRF8KKwkJCSNpbmNsdWRlICIuLi8uLi9jcnlwdG9wcC9DcnlwdGxpYi5oIgorCQkjZW5kaWYKKwkjZW5kaWYKKyNlbmRpZgorCisKKyNpZm5kZWYgRlhfR2V0QVZhbHVlCisvKiogQGJyaWVmIEl0IHJldHJpZXZlcyBhbiBpbnRlbnNpdHkgdmFsdWUgZm9yIHRoZSBhbHBoYSBjb21wb25lbnQgb2YgYSAjRlhfQVJHQiB2YWx1ZS4gKi8KKyNkZWZpbmUgRlhfR2V0QVZhbHVlKGFyZ2IpCQkJKChhcmdiICYgMHhGRjAwMDAwMCkgPj4gMjQpCisjZW5kaWYKKworI2lmbmRlZiBGWF9HZXRSVmFsdWUKKy8qKiBAYnJpZWYgSXQgcmV0cmlldmVzIGFuIGludGVuc2l0eSB2YWx1ZSBmb3IgdGhlIHJlZCBjb21wb25lbnQgb2YgYSAjRlhfQVJHQiB2YWx1ZS4gKi8KKyNkZWZpbmUgRlhfR2V0UlZhbHVlKGFyZ2IpCQkJKChhcmdiICYgMHgwMEZGMDAwMCkgPj4gMTYpCisjZW5kaWYKKworI2lmbmRlZiBGWF9HZXRHVmFsdWUKKy8qKiBAYnJpZWYgSXQgcmV0cmlldmVzIGFuIGludGVuc2l0eSB2YWx1ZSBmb3IgdGhlIGdyZWVuIGNvbXBvbmVudCBvZiBhICNGWF9BUkdCIHZhbHVlLiAqLworI2RlZmluZSBGWF9HZXRHVmFsdWUoYXJnYikJCQkoKGFyZ2IgJiAweDAwMDBGRjAwKSA+PiA4KQorI2VuZGlmCisKKyNpZm5kZWYgRlhfR2V0QlZhbHVlCisvKiogQGJyaWVmIEl0IHJldHJpZXZlcyBhbiBpbnRlbnNpdHkgdmFsdWUgZm9yIHRoZSBibHVlIGNvbXBvbmVudCBvZiBhICNGWF9BUkdCIHZhbHVlLiAqLworI2RlZmluZSBGWF9HZXRCVmFsdWUoYXJnYikJCQkoYXJnYiAmIDB4MDAwMDAwRkYpCisjZW5kaWYKKworI2lmbmRlZiBGWF9BUkdCVE9DT0xPUlJFRgorLyoqIEBicmllZiBDb252ZXJ0IGEgI0ZYX0FSR0IgdG8gYSAjRlhfQ09MT1JSRUYuICovCisjZGVmaW5lIEZYX0FSR0JUT0NPTE9SUkVGKGFyZ2IpCQkoKCgoRlhfRFdPUkQpYXJnYiAmIDB4MDBGRjAwMDApID4+IDE2KXwoKEZYX0RXT1JEKWFyZ2IgJiAweDAwMDBGRjAwKXwoKChGWF9EV09SRClhcmdiICYgMHgwMDAwMDBGRikgPDwgMTYpKQorI2VuZGlmCisKKyNpZm5kZWYgRlhfQ09MT1JSRUZUT0FSR0IKKy8qKiBAYnJpZWYgQ29udmVydCBhICNGWF9DT0xPUlJFRiB0byBhICNGWF9BUkdCLiAqLworI2RlZmluZSBGWF9DT0xPUlJFRlRPQVJHQihyZ2IpCQkoKEZYX0RXT1JEKTB4RkYwMDAwMDB8KCgoRlhfRFdPUkQpcmdiICYgMHgwMDAwMDBGRikgPDwgMTYpfCgoRlhfRFdPUkQpcmdiICYgMHgwMDAwRkYwMCl8KCgoRlhfRFdPUkQpcmdiICYgMHgwMEZGMDAwMCkgPj4gMTYpKQorI2VuZGlmCisKK3R5cGVkZWYgdW5zaWduZWQgaW50IEZYX1VJTlQ7CQorCisjaW5jbHVkZSAiZnBkZnZpZXcuaCIKKworY2xhc3MgQ1BERl9DdXN0b21BY2Nlc3MgOiBwdWJsaWMgSUZYX0ZpbGVSZWFkLCBwdWJsaWMgQ0ZYX09iamVjdAoreworcHVibGljOgorCUNQREZfQ3VzdG9tQWNjZXNzKEZQREZfRklMRUFDQ0VTUyogcEZpbGVBY2Nlc3MpOworCX5DUERGX0N1c3RvbUFjY2VzcygpIHt9CisKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nIEdldEZ1bGxQYXRoKCkgeyByZXR1cm4gIiI7IH0KKwl2aXJ0dWFsIEZYX0ZJTEVTSVpFCUdldFNpemUoKSB7IHJldHVybiBtX0ZpbGVBY2Nlc3MubV9GaWxlTGVuOyB9CisKKwl2aXJ0dWFsIEZYX0JPT0wJCUdldEJ5dGUoRlhfRFdPUkQgcG9zLCBGWF9CWVRFJiBjaCk7CisJdmlydHVhbCBGWF9CT09MCQlHZXRCbG9jayhGWF9EV09SRCBwb3MsIEZYX0xQQllURSBwQnVmLCBGWF9EV09SRCBzaXplKTsKKwl2aXJ0dWFsIHZvaWQJCVJlbGVhc2UoKSB7IGRlbGV0ZSB0aGlzOyB9CisKKwl2aXJ0dWFsIEZYX0JPT0wJCVJlYWRCbG9jayh2b2lkKiBidWZmZXIsIEZYX0ZJTEVTSVpFIG9mZnNldCwgc2l6ZV90IHNpemUpOworCisJRlBERl9GSUxFQUNDRVNTCQltX0ZpbGVBY2Nlc3M7CisJRlhfQllURQkJCQltX0J1ZmZlcls1MTJdOworCUZYX0RXT1JECQkJbV9CdWZmZXJPZmZzZXQ7Cit9OworCit2b2lkCQlGU0RLX1NldFNhbmRCb3hQb2xpY3koRlBERl9EV09SRCBwb2xpY3ksIEZQREZfQk9PTCBlbmFibGUpOworRlBERl9CT09MCUZTREtfSXNTYW5kQm94UG9saWN5RW5hYmxlZChGUERGX0RXT1JEIHBvbGljeSk7CisKKworI2VuZGlmLy9fRlBERlNES19ERUZJTkVfSApkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2ZzZGtfbWdyLmggYi9mcGRmc2RrL2luY2x1ZGUvZnNka19tZ3IuaAppbmRleCA5OTMzYzQxLi5iYjI1YjM1IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnNka19tZ3IuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnNka19tZ3IuaApAQCAtMSw2MTUgKzEsNjE1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GUERGU0RLX01HUl9IDQotI2RlZmluZSBfRlBERlNES19NR1JfSA0KLQ0KLSNpbmNsdWRlICJmc2RrX2NvbW1vbi5oIg0KLSNpbmNsdWRlICJmc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICJmeF9zeXN0ZW1oYW5kbGVyLmgiDQotI2luY2x1ZGUgImZzZGtfYmFzZWFubm90LmgiDQotI2luY2x1ZGUgImZzZGtfYmFzZWZvcm0uaCINCi0jaW5jbHVkZSAiZnBkZmZvcm1maWxsLmgiDQotI2luY2x1ZGUgImZzZGtfYW5ub3RoYW5kbGVyLmgiDQotI2luY2x1ZGUgImZzZGtfYWN0aW9uaGFuZGxlci5oIg0KLQ0KLS8vY3Jvc3MgcGxhdGZvcm0ga2V5Y29kZSBhbmQgZXZlbnRzIGRlZmluZS4NCi0jaW5jbHVkZSAiZnBkZl9md2xldmVudC5oIg0KLQ0KLQ0KLWNsYXNzIENQREZTREtfRG9jdW1lbnQ7DQotY2xhc3MgQ1BERlNES19QYWdlVmlldzsNCi1jbGFzcyBDUERGU0RLX0Fubm90Ow0KLWNsYXNzIENGRkxfSUZvcm1GaWxsZXI7DQotY2xhc3MgQ1BERlNES19XaWRnZXQ7DQotY2xhc3MgSUZYX1N5c3RlbUhhbmRsZXI7DQotY2xhc3MgQ1BERlNES19BY3Rpb25IYW5kbGVyOw0KLWNsYXNzIENKU19SdW50aW1lRmFjdG9yeTsNCi0NCi0jaW5jbHVkZSAiamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIg0KLQ0KLWNsYXNzIENQREZEb2NfRW52aXJvbm1lbnQNCi17DQotcHVibGljOg0KLQlDUERGRG9jX0Vudmlyb25tZW50KENQREZfRG9jdW1lbnQgKiBwRG9jKTsNCi0JfkNQREZEb2NfRW52aXJvbm1lbnQoKTsNCi0NCi0JaW50IFJlZ0FwcEhhbmRsZShGUERGX0ZPUk1GSUxMSU5GTyogcEZGaW5mbyk7Ly97IG1fcEluZm8gID0gcEZGaW5mbzsgcmV0dXJuIFRSVUU7fQ0KLQ0KLQl2aXJ0dWFsIHZvaWQJCVJlbGVhc2UoKQ0KLQl7DQotCQlpZiAobV9wSW5mbyAmJiBtX3BJbmZvLT5SZWxlYXNlKQ0KLQkJCW1fcEluZm8tPlJlbGVhc2UobV9wSW5mbyk7DQotCQlkZWxldGUgdGhpczsNCi0JfQ0KLQ0KLQl2aXJ0dWFsIHZvaWQgRkZJX0ludmFsaWRhdGUoRlBERl9QQUdFIHBhZ2UsIGRvdWJsZSBsZWZ0LCBkb3VibGUgdG9wLCBkb3VibGUgcmlnaHQsIGRvdWJsZSBib3R0b20pDQotCXsNCi0JCWlmIChtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9JbnZhbGlkYXRlKSANCi0JCXsNCi0JCQltX3BJbmZvLT5GRklfSW52YWxpZGF0ZShtX3BJbmZvLCBwYWdlLCBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20pOw0KLQkJfQ0KLQl9DQotCXZpcnR1YWwgdm9pZCBGRklfT3V0cHV0U2VsZWN0ZWRSZWN0KEZQREZfUEFHRSBwYWdlLCBkb3VibGUgbGVmdCwgZG91YmxlIHRvcCwgZG91YmxlIHJpZ2h0LCBkb3VibGUgYm90dG9tKQ0KLQl7DQotCQlpZiAobV9wSW5mbyAmJiBtX3BJbmZvLT5GRklfT3V0cHV0U2VsZWN0ZWRSZWN0KSANCi0JCXsNCi0JCQltX3BJbmZvLT5GRklfT3V0cHV0U2VsZWN0ZWRSZWN0KG1fcEluZm8sIHBhZ2UsIGxlZnQsIHRvcCwgcmlnaHQsIGJvdHRvbSk7DQotCQl9DQotCX0NCi0NCi0JdmlydHVhbCB2b2lkIEZGSV9TZXRDdXJzb3IoaW50IG5DdXJzb3JUeXBlKQ0KLQl7DQotCQlpZiAobV9wSW5mbyAmJiBtX3BJbmZvLT5GRklfU2V0Q3Vyc29yKSANCi0JCXsNCi0JCQltX3BJbmZvLT5GRklfU2V0Q3Vyc29yKG1fcEluZm8sIG5DdXJzb3JUeXBlKTsNCi0JCX0NCi0JfQ0KLQ0KLQl2aXJ0dWFsCWludCAgRkZJX1NldFRpbWVyKGludCB1RWxhcHNlLCBUaW1lckNhbGxiYWNrIGxwVGltZXJGdW5jKQ0KLQl7DQotCQlpZiAobV9wSW5mbyAmJiBtX3BJbmZvLT5GRklfU2V0VGltZXIpIA0KLQkJew0KLQkJCXJldHVybiBtX3BJbmZvLT5GRklfU2V0VGltZXIobV9wSW5mbywgdUVsYXBzZSwgbHBUaW1lckZ1bmMpOw0KLQkJfQ0KLQkJcmV0dXJuIC0xOw0KLQl9DQotCQkNCi0JdmlydHVhbCB2b2lkIEZGSV9LaWxsVGltZXIoaW50IG5UaW1lcklEKQ0KLQl7DQotCQlpZiAobV9wSW5mbyAmJiBtX3BJbmZvLT5GRklfS2lsbFRpbWVyKSANCi0JCXsNCi0JCQltX3BJbmZvLT5GRklfS2lsbFRpbWVyKG1fcEluZm8sIG5UaW1lcklEKTsNCi0JCX0NCi0JfQ0KLQlGWF9TWVNURU1USU1FIEZGSV9HZXRMb2NhbFRpbWUoKQ0KLQl7DQotCQlGWF9TWVNURU1USU1FIGZ4dGltZTsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX0dldExvY2FsVGltZSkNCi0JCXsNCi0JCQlGUERGX1NZU1RFTVRJTUUgc3lzdGltZSA9IG1fcEluZm8tPkZGSV9HZXRMb2NhbFRpbWUobV9wSW5mbyk7DQotCQkJZnh0aW1lLndEYXkgPSBzeXN0aW1lLndEYXk7DQotCQkJZnh0aW1lLndEYXlPZldlZWsgPSBzeXN0aW1lLndEYXlPZldlZWs7DQotCQkJZnh0aW1lLndIb3VyID0gc3lzdGltZS53SG91cjsNCi0JCQlmeHRpbWUud01pbGxpc2Vjb25kcyA9IHN5c3RpbWUud01pbGxpc2Vjb25kczsNCi0JCQlmeHRpbWUud01pbnV0ZSA9IHN5c3RpbWUud01pbnV0ZTsNCi0JCQlmeHRpbWUud01vbnRoID0gc3lzdGltZS53TW9udGg7DQotCQkJZnh0aW1lLndTZWNvbmQgPSBzeXN0aW1lLndTZWNvbmQ7DQotCQkJZnh0aW1lLndZZWFyID0gc3lzdGltZS53WWVhcjsNCi0JCX0NCi0JCXJldHVybiBmeHRpbWU7DQotCX0NCi0NCi0JdmlydHVhbCB2b2lkIEZGSV9PbkNoYW5nZSgpDQotCXsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX09uQ2hhbmdlKQ0KLQkJew0KLQkJCW1fcEluZm8tPkZGSV9PbkNoYW5nZShtX3BJbmZvKTsNCi0JCX0NCi0JfQ0KLQ0KLQl2aXJ0dWFsCUZYX0JPT0wJRkZJX0lzU0hJRlRLZXlEb3duKEZYX0RXT1JEIG5GbGFnKQ0KLQl7DQotCQkNCi0JCXJldHVybiAobkZsYWcgJiBGV0xfRVZFTlRGTEFHX1NoaWZ0S2V5KSAhPSAwOw0KLQl9DQotCXZpcnR1YWwJRlhfQk9PTAlGRklfSXNDVFJMS2V5RG93bihGWF9EV09SRCBuRmxhZykNCi0Jew0KLQ0KLQkJcmV0dXJuIChuRmxhZyAmIEZXTF9FVkVOVEZMQUdfQ29udHJvbEtleSkgIT0gMDsNCi0JfQ0KLQl2aXJ0dWFsCUZYX0JPT0wJRkZJX0lzQUxUS2V5RG93bihGWF9EV09SRCBuRmxhZykNCi0Jew0KLQ0KLQkJcmV0dXJuIChuRmxhZyAmIEZXTF9FVkVOVEZMQUdfQWx0S2V5KSAhPSAwOw0KLQl9DQotCXZpcnR1YWwJRlhfQk9PTAlGRklfSXNJTlNFUlRLZXlEb3duKEZYX0RXT1JEIG5GbGFnKQ0KLQl7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JdmlydHVhbCBpbnQgSlNfYXBwQWxlcnQoRlhfTFBDV1NUUiBNc2csIEZYX0xQQ1dTVFIgVGl0bGUsIEZYX1VJTlQgVHlwZSwgRlhfVUlOVCBJY29uKQ0KLQl7DQotCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX2FsZXJ0KQ0KLQkJew0KLQkJCUNGWF9CeXRlU3RyaW5nIGJzTXNnID0gQ0ZYX1dpZGVTdHJpbmcoTXNnKS5VVEYxNkxFX0VuY29kZSgpOw0KLQkJCUNGWF9CeXRlU3RyaW5nIGJzVGl0bGUgPSBDRlhfV2lkZVN0cmluZyhUaXRsZSkuVVRGMTZMRV9FbmNvZGUoKTsNCi0JCQlGUERGX1dJREVTVFJJTkcgcE1zZyA9IChGUERGX1dJREVTVFJJTkcpYnNNc2cuR2V0QnVmZmVyKGJzTXNnLkdldExlbmd0aCgpKTsNCi0JCQlGUERGX1dJREVTVFJJTkcgcFRpdGxlID0gKEZQREZfV0lERVNUUklORylic1RpdGxlLkdldEJ1ZmZlcihic1RpdGxlLkdldExlbmd0aCgpKTsNCi0JCQlpbnQgcmV0ID0gbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX2FsZXJ0KG1fcEluZm8tPm1fcEpzUGxhdGZvcm0sIHBNc2csIHBUaXRsZSwgVHlwZSwgSWNvbik7DQotCQkJYnNNc2cuUmVsZWFzZUJ1ZmZlcigpOw0KLQkJCWJzVGl0bGUuUmVsZWFzZUJ1ZmZlcigpOw0KLQkJCXJldHVybiByZXQ7DQotCQl9DQotCQlyZXR1cm4gLTE7DQotCX0NCi0NCi0JdmlydHVhbCBpbnQgSlNfYXBwUmVzcG9uc2UoRlhfTFBDV1NUUiBRdWVzdGlvbiwgRlhfTFBDV1NUUiBUaXRsZSwgRlhfTFBDV1NUUiBEZWZhdWx0LCBGWF9MUENXU1RSIGNMYWJlbCwgRlBERl9CT09MIGJQYXNzd29yZCwgdm9pZCogcmVzcG9uc2UsIGludCBsZW5ndGgpDQotCXsNCi0JCWlmIChtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX3Jlc3BvbnNlKQ0KLQkJew0KLQkJCUNGWF9CeXRlU3RyaW5nIGJzUXVlc3Rpb24gPSBDRlhfV2lkZVN0cmluZyhRdWVzdGlvbikuVVRGMTZMRV9FbmNvZGUoKTsNCi0JCQlDRlhfQnl0ZVN0cmluZyBic1RpdGxlID0gQ0ZYX1dpZGVTdHJpbmcoVGl0bGUpLlVURjE2TEVfRW5jb2RlKCk7DQotCQkJQ0ZYX0J5dGVTdHJpbmcgYnNEZWZhdWx0ID0gQ0ZYX1dpZGVTdHJpbmcoRGVmYXVsdCkuVVRGMTZMRV9FbmNvZGUoKTsNCi0JCQlDRlhfQnl0ZVN0cmluZyBic0xhYmVsID0gQ0ZYX1dpZGVTdHJpbmcoY0xhYmVsKS5VVEYxNkxFX0VuY29kZSgpOw0KLQkJCUZQREZfV0lERVNUUklORyBwUXVlc3Rpb24gPSAoRlBERl9XSURFU1RSSU5HKWJzUXVlc3Rpb24uR2V0QnVmZmVyKGJzUXVlc3Rpb24uR2V0TGVuZ3RoKCkpOw0KLQkJCUZQREZfV0lERVNUUklORyBwVGl0bGUgPSAoRlBERl9XSURFU1RSSU5HKWJzVGl0bGUuR2V0QnVmZmVyKGJzVGl0bGUuR2V0TGVuZ3RoKCkpOw0KLQkJCUZQREZfV0lERVNUUklORyBwRGVmYXVsdCA9IChGUERGX1dJREVTVFJJTkcpYnNEZWZhdWx0LkdldEJ1ZmZlcihic0RlZmF1bHQuR2V0TGVuZ3RoKCkpOw0KLQkJCUZQREZfV0lERVNUUklORyBwTGFiZWwgPSAoRlBERl9XSURFU1RSSU5HKWJzTGFiZWwuR2V0QnVmZmVyKGJzTGFiZWwuR2V0TGVuZ3RoKCkpOw0KLQkJCWludCByZXQgPSBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5hcHBfcmVzcG9uc2UobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSwgcFF1ZXN0aW9uLCBwVGl0bGUsIA0KLQkJCQlwRGVmYXVsdCwgcExhYmVsLCBiUGFzc3dvcmQsIHJlc3BvbnNlLCBsZW5ndGgpOw0KLQkJCWJzUXVlc3Rpb24uUmVsZWFzZUJ1ZmZlcigpOw0KLQkJCWJzVGl0bGUuUmVsZWFzZUJ1ZmZlcigpOw0KLQkJCWJzRGVmYXVsdC5SZWxlYXNlQnVmZmVyKCk7DQotCQkJYnNMYWJlbC5SZWxlYXNlQnVmZmVyKCk7DQotCQkJcmV0dXJuIHJldDsNCi0JCX0NCi0JCXJldHVybiAtMTsNCi0JfQ0KLQ0KLQl2aXJ0dWFsIHZvaWQgSlNfYXBwQmVlcChpbnQgblR5cGUpDQotCXsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybSAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5hcHBfYmVlcCkNCi0JCXsNCi0JCQltX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5hcHBfYmVlcChtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLCBuVHlwZSk7DQotCQl9DQotCX0NCi0NCi0JdmlydHVhbCBDRlhfV2lkZVN0cmluZyBKU19maWVsZEJyb3dzZSgpDQotCXsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybSAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5GaWVsZF9icm93c2UpDQotCQl7DQotCQkJaW50IG5MZW4gPSBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5GaWVsZF9icm93c2UobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSwgTlVMTCwgMCk7DQotCQkJaWYobkxlbiA8PSAwKQ0KLQkJCQlyZXR1cm4gTCIiOw0KLQkJCWNoYXIqIHBidWZmID0gbmV3IGNoYXJbbkxlbl07DQotCQkJaWYocGJ1ZmYpDQotCQkJCW1lbXNldChwYnVmZiwgMCwgbkxlbik7DQotCQkJZWxzZQkNCi0JCQkJcmV0dXJuIEwiIjsNCi0JCQluTGVuID0gbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RmllbGRfYnJvd3NlKG1fcEluZm8tPm1fcEpzUGxhdGZvcm0sIHBidWZmLCBuTGVuKTsNCi0JCQlDRlhfQnl0ZVN0cmluZyBic1JldCA9IENGWF9CeXRlU3RyaW5nKHBidWZmLCBuTGVuKTsNCi0JCQlDRlhfV2lkZVN0cmluZyB3c1JldCA9IENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoYnNSZXQpOw0KLQkJCWRlbGV0ZVtdIHBidWZmOw0KLQkJCXJldHVybiB3c1JldDsNCi0JCX0NCi0JCXJldHVybiBMIiI7DQotCX0NCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgSlNfZG9jR2V0RmlsZVBhdGgoKQ0KLQl7CQkNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybSAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfZ2V0RmlsZVBhdGgpDQotCQl7DQotCQkJaW50IG5MZW4gPSBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfZ2V0RmlsZVBhdGgobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSwgTlVMTCwgMCk7DQotCQkJaWYobkxlbiA8PSAwKQ0KLQkJCQlyZXR1cm4gTCIiOw0KLQkJCWNoYXIqIHBidWZmID0gbmV3IGNoYXJbbkxlbl07DQotCQkJaWYocGJ1ZmYpDQotCQkJCW1lbXNldChwYnVmZiwgMCwgbkxlbik7DQotCQkJZWxzZQ0KLQkJCQlyZXR1cm4gTCIiOw0KLQkJCW5MZW4gPSBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfZ2V0RmlsZVBhdGgobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSwgcGJ1ZmYsIG5MZW4pOw0KLQkJCUNGWF9CeXRlU3RyaW5nIGJzUmV0ID0gQ0ZYX0J5dGVTdHJpbmcocGJ1ZmYsIG5MZW4pOw0KLQkJCUNGWF9XaWRlU3RyaW5nIHdzUmV0ID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChic1JldCk7DQotCQkJZGVsZXRlW10gcGJ1ZmY7DQotCQkJcmV0dXJuIHdzUmV0Ow0KLQkJfQ0KLQkJcmV0dXJuIEwiIjsNCi0JfQ0KLQ0KLQl2b2lkIEpTX2RvY1N1Ym1pdEZvcm0odm9pZCogZm9ybURhdGEsIGludCBsZW5ndGgsIEZYX0xQQ1dTVFIgVVJMKQ0KLQl7DQotCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RG9jX3N1Ym1pdEZvcm0pDQotCQl7DQotCQkJQ0ZYX0J5dGVTdHJpbmcgYnNEZXN0aW5hdGlvbiA9IENGWF9XaWRlU3RyaW5nKFVSTCkuVVRGMTZMRV9FbmNvZGUoKTsNCi0JCQlGUERGX1dJREVTVFJJTkcgcERlc3RpbmF0aW9uID0gKEZQREZfV0lERVNUUklORylic0Rlc3RpbmF0aW9uLkdldEJ1ZmZlcihic0Rlc3RpbmF0aW9uLkdldExlbmd0aCgpKTsNCi0JCQltX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2Nfc3VibWl0Rm9ybShtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLCBmb3JtRGF0YSwgbGVuZ3RoLCBwRGVzdGluYXRpb24pOw0KLQkJCWJzRGVzdGluYXRpb24uUmVsZWFzZUJ1ZmZlcigpOw0KLQkJfQ0KLQl9DQotDQotCXZvaWQgSlNfZG9jbWFpbEZvcm0odm9pZCogbWFpbERhdGEsIGludCBsZW5ndGgsIEZQREZfQk9PTCBiVUksRlhfTFBDV1NUUiBUbywgRlhfTFBDV1NUUiBTdWJqZWN0LCBGWF9MUENXU1RSIENDLCBGWF9MUENXU1RSIEJDQywgRlhfTFBDV1NUUiBNc2cpDQotCXsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybSAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfbWFpbCkNCi0JCXsNCi0JCQlDRlhfQnl0ZVN0cmluZyBic1RvID0gQ0ZYX1dpZGVTdHJpbmcoVG8pLlVURjE2TEVfRW5jb2RlKCk7DQotCQkJQ0ZYX0J5dGVTdHJpbmcgYnNDQyA9IENGWF9XaWRlU3RyaW5nKFN1YmplY3QpLlVURjE2TEVfRW5jb2RlKCk7DQotCQkJQ0ZYX0J5dGVTdHJpbmcgYnNCY2MgPSBDRlhfV2lkZVN0cmluZyhCQ0MpLlVURjE2TEVfRW5jb2RlKCk7DQotCQkJQ0ZYX0J5dGVTdHJpbmcgYnNTdWJqZWN0ID0gQ0ZYX1dpZGVTdHJpbmcoU3ViamVjdCkuVVRGMTZMRV9FbmNvZGUoKTsNCi0JCQlDRlhfQnl0ZVN0cmluZyBic01zZyA9IENGWF9XaWRlU3RyaW5nKE1zZykuVVRGMTZMRV9FbmNvZGUoKTsNCi0JCQlGUERGX1dJREVTVFJJTkcgcFRvID0gKEZQREZfV0lERVNUUklORylic1RvLkdldEJ1ZmZlcihic1RvLkdldExlbmd0aCgpKTsNCi0JCQlGUERGX1dJREVTVFJJTkcgcENDID0gKEZQREZfV0lERVNUUklORylic0NDLkdldEJ1ZmZlcihic0NDLkdldExlbmd0aCgpKTsNCi0JCQlGUERGX1dJREVTVFJJTkcgcEJjYyA9IChGUERGX1dJREVTVFJJTkcpYnNCY2MuR2V0QnVmZmVyKGJzQmNjLkdldExlbmd0aCgpKTsNCi0JCQlGUERGX1dJREVTVFJJTkcgcFN1YmplY3QgPSAoRlBERl9XSURFU1RSSU5HKWJzU3ViamVjdC5HZXRCdWZmZXIoYnNTdWJqZWN0LkdldExlbmd0aCgpKTsNCi0JCQlGUERGX1dJREVTVFJJTkcgcE1zZyA9IChGUERGX1dJREVTVFJJTkcpYnNNc2cuR2V0QnVmZmVyKGJzTXNnLkdldExlbmd0aCgpKTsNCi0JCQltX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfbWFpbChtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLCBtYWlsRGF0YSwgbGVuZ3RoLCBiVUksIHBUbywgcFN1YmplY3QsDQotCQkJCXBDQywgcEJjYywgcE1zZyk7DQotCQkJYnNUby5SZWxlYXNlQnVmZmVyKCk7DQotCQkJYnNDQy5SZWxlYXNlQnVmZmVyKCk7DQotCQkJYnNCY2MuUmVsZWFzZUJ1ZmZlcigpOw0KLQkJCWJzU3ViamVjdC5SZWxlYXNlQnVmZmVyKCk7DQotCQkJYnNNc2cuUmVsZWFzZUJ1ZmZlcigpOw0KLQkJfQ0KLQl9DQotCUNGWF9XaWRlU3RyaW5nIEpTX2FwcGJyb3dzZUZvckRvYyhGUERGX0JPT0wgYlNhdmUsIEZYX0xQQ1dTVFIgY0ZpbGVuYW1lSW5pdCkNCi0Jew0KLQkJLy90byBkby4uLi4NCi0JCXJldHVybiBMIiI7DQotLy8gCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX2Jyb3dzZUZvckRvYykNCi0vLyAJCXsNCi0vLyAJCQlDRlhfQnl0ZVN0cmluZyBic0ZpbGVuYW1lSW5pdCA9IENGWF9XaWRlU3RyaW5nKGNGaWxlbmFtZUluaXQpLlVURjE2TEVfRW5jb2RlKCk7DQotLy8gCQkJRlBERl9XSURFU1RSSU5HIHBGaWxlTmFtZUluaXQgPSAoRlBERl9XSURFU1RSSU5HKWJzRmlsZW5hbWVJbml0LkdldEJ1ZmZlcihic0ZpbGVuYW1lSW5pdC5HZXRMZW5ndGgoKSk7DQotLy8gDQotLy8gCQkJbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX2Jyb3dzZUZvckRvYyhtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLCBwRmlsZU5hbWVJbml0KTsNCi0vLyAJCQlic0ZpbGVuYW1lSW5pdC5SZWxlYXNlQnVmZmVyKCk7DQotLy8gCQl9DQotCX0NCi0NCi0Jdm9pZCBKU19kb2NwcmludChGUERGX0JPT0wgYlVJICwgaW50IG5TdGFydCwgaW50IG5FbmQsIEZQREZfQk9PTCBiU2lsZW50ICxGUERGX0JPT0wgYlNocmlua1RvRml0LEZQREZfQk9PTCBiUHJpbnRBc0ltYWdlICxGUERGX0JPT0wgYlJldmVyc2UgLEZQREZfQk9PTCBiQW5ub3RhdGlvbnMpDQotCXsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybSAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfcHJpbnQpDQotCQl7DQotCQkJbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RG9jX3ByaW50KG1fcEluZm8tPm1fcEpzUGxhdGZvcm0sIGJVSSwgblN0YXJ0LCBuRW5kLCBiU2lsZW50LCBiU2hyaW5rVG9GaXQsIGJQcmludEFzSW1hZ2UsIGJSZXZlcnNlLCBiQW5ub3RhdGlvbnMpOw0KLQkJfQ0KLQl9DQotCXZvaWQgSlNfZG9jZ290b1BhZ2UoaW50IG5QYWdlTnVtKQ0KLQl7DQotCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RG9jX2dvdG9QYWdlKQ0KLQkJew0KLQkJCW1fcEluZm8tPm1fcEpzUGxhdGZvcm0tPkRvY19nb3RvUGFnZShtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLCBuUGFnZU51bSk7DQotCQl9DQotCX0NCi0NCi0JdmlydHVhbCBGUERGX1BBR0UJRkZJX0dldFBhZ2UoRlBERl9ET0NVTUVOVCBkb2N1bWVudCxpbnQgblBhZ2VJbmRleCkNCi0Jew0KLQkJaWYobV9wSW5mbyAmJiBtX3BJbmZvLT5GRklfR2V0UGFnZSkNCi0JCXsNCi0JCQlyZXR1cm4gbV9wSW5mby0+RkZJX0dldFBhZ2UobV9wSW5mbywgZG9jdW1lbnQsIG5QYWdlSW5kZXgpOw0KLQkJfQ0KLQkJcmV0dXJuIE5VTEw7DQotCX0NCi0NCi0JdmlydHVhbCBGUERGX1BBR0UgRkZJX0dldEN1cnJlbnRQYWdlKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpDQotCXsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX0dldEN1cnJlbnRQYWdlKQ0KLQkJew0KLQkJCXJldHVybiBtX3BJbmZvLT5GRklfR2V0Q3VycmVudFBhZ2UobV9wSW5mbywgZG9jdW1lbnQpOw0KLQkJfQ0KLQkJcmV0dXJuIE5VTEw7DQotCX0NCi0NCi0JaW50IAlGRklfR2V0Um90YXRpb24oRlBERl9QQUdFIHBhZ2UpDQotCXsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX0dldFJvdGF0aW9uKQ0KLQkJew0KLQkJCXJldHVybiBtX3BJbmZvLT5GRklfR2V0Um90YXRpb24obV9wSW5mbywgcGFnZSk7DQotCQl9DQotCQlyZXR1cm4gMDsNCi0JfQ0KLQl2b2lkCUZGSV9FeGVjdXRlTmFtZWRBY3Rpb24oRlhfTFBDU1RSIG5hbWVkQWN0aW9uKQ0KLQl7DQotCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9FeGVjdXRlTmFtZWRBY3Rpb24pDQotCQl7DQotCQkJbV9wSW5mby0+RkZJX0V4ZWN1dGVOYW1lZEFjdGlvbihtX3BJbmZvLCBuYW1lZEFjdGlvbik7DQotCQl9DQotCX0NCi0Jdm9pZAlGRklfT25TZXRGaWVsZElucHV0Rm9jdXModm9pZCogZmllbGQsRlBERl9XSURFU1RSSU5HIGZvY3VzVGV4dCwgRlBERl9EV09SRCBuVGV4dExlbiwgRlhfQk9PTCBiRm9jdXMpDQotCXsNCi0JCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX1NldFRleHRGaWVsZEZvY3VzKQ0KLQkJew0KLQkJCW1fcEluZm8tPkZGSV9TZXRUZXh0RmllbGRGb2N1cyhtX3BJbmZvLCBmb2N1c1RleHQsIG5UZXh0TGVuLCBiRm9jdXMpOw0KLQkJfQ0KLQl9DQotDQotCXZvaWQJRkZJX0RvVVJJQWN0aW9uKEZYX0xQQ1NUUiBic1VSSSkNCi0Jew0KLQkJaWYobV9wSW5mbyAmJiBtX3BJbmZvLT5GRklfRG9VUklBY3Rpb24pDQotCQl7DQotCQkJbV9wSW5mby0+RkZJX0RvVVJJQWN0aW9uKG1fcEluZm8sIGJzVVJJKTsNCi0JCX0NCi0JfQ0KLQ0KLQl2b2lkCUZGSV9Eb0dvVG9BY3Rpb24oaW50IG5QYWdlSW5kZXgsIGludCB6b29tTW9kZSwgZmxvYXQqIGZQb3NBcnJheSwgaW50IHNpemVPZkFycmF5KQ0KLQl7DQotCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9Eb0dvVG9BY3Rpb24pDQotCQl7DQotCQkJbV9wSW5mby0+RkZJX0RvR29Ub0FjdGlvbihtX3BJbmZvLCBuUGFnZUluZGV4LCB6b29tTW9kZSwgZlBvc0FycmF5LCBzaXplT2ZBcnJheSk7DQotCQl9DQotCX0NCi0NCi1wdWJsaWM6DQotCUZYX0JPT0wJCQkJSXNKU0luaXRpYXRlZCgpOw0KLQ0KLXB1YmxpYzoJDQotCXZvaWQJCQkJU2V0Q3VycmVudERvYyhDUERGU0RLX0RvY3VtZW50KiBwRlhEb2MpIHttX3BTREtEb2MgPSBwRlhEb2M7fQ0KLQlDUERGU0RLX0RvY3VtZW50KglHZXRDdXJyZW50RG9jKCk7DQotCUNQREZfRG9jdW1lbnQqCQlHZXRQREZEb2N1bWVudCgpIHtyZXR1cm4gbV9wUERGRG9jO30NCi0vLyAJQ1BERlNES19Eb2N1bWVudCogICBHZXREb2N1bWVudChpbnQgbkluZGV4KTsNCi0vLyAJaW50CQkJCQlDb3VudERvY3VtZW50cygpIHtyZXR1cm4gbV9kb2NNYXAuR2V0Q291bnQoKTt9DQotDQotCUNQREZTREtfRG9jdW1lbnQqCQlPcGVuRG9jdW1lbnQoQ0ZYX1dpZGVTdHJpbmcgJmZpbGVOYW1lKTsNCi0JQ1BERlNES19Eb2N1bWVudCoJCU9wZW5NZW1QREZEb2MoQ1BERl9Eb2N1bWVudCogcE5ld0RvYywgQ0ZYX1dpZGVTdHJpbmcgJmZpbGVOYW1lKTsNCi0JRlhfQk9PTAkJCQkJT3BlblVSTChDRlhfV2lkZVN0cmluZyAmZmlsZVBhdGgpOw0KLQkNCi0NCi0JQ0ZYX0J5dGVTdHJpbmcJCUdldEFwcE5hbWUoKSB7cmV0dXJuICIiO30NCi0NCi0JQ0ZGTF9JRm9ybUZpbGxlcioJR2V0SUZvcm1GaWxsZXIoKTsNCi0JSUZYX1N5c3RlbUhhbmRsZXIqCUdldFN5c0hhbmRsZXIoKSB7cmV0dXJuIG1fcFN5c0hhbmRsZXI7fQ0KLQ0KLXB1YmxpYzoNCi0JQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIEdldEFubm90SGFuZGxlck1ncigpOw0KLQlJRlhKU19SdW50aW1lKglHZXRKU1J1bnRpbWUoKTsNCi0JQ1BERlNES19BY3Rpb25IYW5kbGVyKiBHZXRBY3Rpb25IYW5kZXIoKTsNCi1wcml2YXRlOg0KLQlDUERGU0RLX0Fubm90SGFuZGxlck1nciogbV9wQW5ub3RIYW5kbGVyTWdyOw0KLQlDUERGU0RLX0FjdGlvbkhhbmRsZXIqCW1fcEFjdGlvbkhhbmRsZXI7DQotCUlGWEpTX1J1bnRpbWUqCW1fcEpTUnVudGltZTsNCi1wdWJsaWM6DQotCUZQREZfRk9STUZJTExJTkZPKiBHZXRGb3JtRmlsbEluZm8oKSB7cmV0dXJuIG1fcEluZm87fQ0KLXByaXZhdGU6DQotCUZQREZfRk9STUZJTExJTkZPKgltX3BJbmZvOw0KLS8vCUNGWF9NYXBQdHJUZW1wbGF0ZTxDUERGX0RvY3VtZW50KiwgQ1BERlNES19Eb2N1bWVudCo+IG1fZG9jTWFwOw0KLQlDUERGU0RLX0RvY3VtZW50KiBtX3BTREtEb2M7DQotCUNQREZfRG9jdW1lbnQqIG1fcFBERkRvYzsNCi0NCi0JQ0ZGTF9JRm9ybUZpbGxlciogbV9wSUZvcm1GaWxsZXI7DQotCUlGWF9TeXN0ZW1IYW5kbGVyKiBtX3BTeXNIYW5kbGVyOw0KLQ0KLXB1YmxpYzoNCi0JQ0pTX1J1bnRpbWVGYWN0b3J5KiAgbV9wSlNSdW50aW1lRmFjdG9yeTsNCi19Ow0KLQ0KLQ0KLQ0KLS8vIGNsYXNzIENGWF9BcHANCi0vLyB7DQotLy8gcHVibGljOg0KLS8vIAlDRlhfQXBwKCk6bV9wQ3VyRG9jKE5VTEwpIHt9DQotLy8gCXZvaWQgU2V0QXQoQ1BERl9Eb2N1bWVudCogcFBERkRvYywgQ1BERlNES19Eb2N1bWVudCogcEZYRG9jKTsNCi0vLyAJQ1BERlNES19Eb2N1bWVudCogR2V0QXQoQ1BERl9Eb2N1bWVudCogcFBERkRvYyk7DQotLy8gcHVibGljOg0KLS8vIAl2b2lkIFNldEN1cnJlbnREb2N1bWVudChDUERGU0RLX0RvY3VtZW50KiBwRlhEb2MpIHttX3BDdXJEb2MgPSBwRlhEb2M7fQ0KLS8vIAlDUERGU0RLX0RvY3VtZW50KiBHZXRDdXJyZW50RG9jdW1lbnQoKSB7cmV0dXJuIG1fcEN1ckRvYzt9DQotLy8gcHJpdmF0ZToNCi0vLyAJQ0ZYX01hcFB0clRlbXBsYXRlPENQREZfRG9jdW1lbnQqLCBDUERGU0RLX0RvY3VtZW50Kj4gbV9kb2NBcnJheTsNCi0vLyAJQ1BERlNES19Eb2N1bWVudCogbV9wQ3VyRG9jOw0KLS8vIH07DQotY2xhc3MgQ1BERlNES19JbnRlckZvcm07DQotY2xhc3MgQ1BERlNES19Eb2N1bWVudA0KLXsNCi1wdWJsaWM6DQotCUNQREZTREtfRG9jdW1lbnQoQ1BERl9Eb2N1bWVudCogcERvYywgQ1BERkRvY19FbnZpcm9ubWVudCogcEVudik7DQotCX5DUERGU0RLX0RvY3VtZW50KCk7DQotcHVibGljOg0KLQlDUERGU0RLX0ludGVyRm9ybSoJCUdldEludGVyRm9ybSgpIDsNCi0JQ1BERl9Eb2N1bWVudCoJCQlHZXREb2N1bWVudCgpIHtyZXR1cm4gbV9wRG9jO30NCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCUluaXRQYWdlVmlldygpOw0KLQl2b2lkCQkJCQlBZGRQYWdlVmlldyhDUERGX1BhZ2UqIHBQREZQYWdlLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpOw0KLQlDUERGU0RLX1BhZ2VWaWV3KgkJR2V0UGFnZVZpZXcoQ1BERl9QYWdlKiBwUERGUGFnZSwgRlhfQk9PTCBSZU5ldyA9IFRSVUUpOw0KLQlDUERGU0RLX1BhZ2VWaWV3KgkJR2V0UGFnZVZpZXcoaW50IG5JbmRleCk7DQotCUNQREZTREtfUGFnZVZpZXcqCQlHZXRDdXJyZW50VmlldygpOw0KLQl2b2lkCQkJCQlSZU1vdmVQYWdlVmlldyhDUERGX1BhZ2UqIHBQREZQYWdlKTsNCi0Jdm9pZAkJCQkJVXBkYXRlQWxsVmlld3MoQ1BERlNES19QYWdlVmlldyogcFNlbmRlciwgQ1BERlNES19Bbm5vdCogcEFubm90KTsNCi0NCi0JQ1BERlNES19Bbm5vdCoJCQlHZXRGb2N1c0Fubm90KCk7Ly97cmV0dXJuIE5VTEw7fQ0KLQ0KLQlJRlhKU19SdW50aW1lICoJCQlHZXRKc1J1bnRpbWUoKTsNCi0JDQotCUZYX0JPT0wJCQkJCVNldEZvY3VzQW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnID0gMCk7Ly97cmV0dXJuIEZBTFNFO30NCi0JRlhfQk9PTAkJCQkJS2lsbEZvY3VzQW5ub3QoRlhfVUlOVCBuRmxhZyA9IDApOw0KLQ0KLQlGWF9CT09MCQkJCQlFeHRyYWN0UGFnZXMoY29uc3QgQ0ZYX1dvcmRBcnJheSAmYXJyRXh0cmFQYWdlcywgQ1BERl9Eb2N1bWVudCogcERzdERvYyk7DQotCUZYX0JPT0wJCQkJCUluc2VydFBhZ2VzKGludCBuSW5zZXJ0QXQsIGNvbnN0IENQREZfRG9jdW1lbnQqIHBTcmNEb2MsIGNvbnN0IENGWF9Xb3JkQXJyYXkgJmFyclNyY1BhZ2VzKTsNCi0JRlhfQk9PTAkJCQkJRGVsZXRlUGFnZXMoaW50IG5TdGFydCwgaW50IG5Db3VudCk7DQotCUZYX0JPT0wJCQkJCVJlcGxhY2VQYWdlcyhpbnQgblBhZ2UsIGNvbnN0IENQREZfRG9jdW1lbnQqIHBTcmNEb2MsIGNvbnN0IENGWF9Xb3JkQXJyYXkgJmFyclNyY1BhZ2VzKTsNCi0NCi0Jdm9pZAkJCQkJT25DbG9zZURvY3VtZW50KCk7DQotDQotCWludAkJCQkJCUdldFBhZ2VDb3VudCgpIHtyZXR1cm4gbV9wRG9jLT5HZXRQYWdlQ291bnQoKTt9DQotCUZYX0JPT0wJCQkJCUdldFBlcm1pc3Npb25zKGludCBuRmxhZyk7DQotCUZYX0JPT0wJCQkJCUdldENoYW5nZU1hcmsoKSB7cmV0dXJuIG1fYkNoYW5nZU1hc2s7fQ0KLQl2b2lkCQkJCQlTZXRDaGFuZ2VNYXJrKCkge21fYkNoYW5nZU1hc2sgPSBUUlVFO30NCi0Jdm9pZAkJCQkJQ2xlYXJDaGFuZ2VNYXJrKCkge21fYkNoYW5nZU1hc2s9IEZBTFNFO30NCi0vLwlGWF9CT09MCQkJCQlHZXRDaGFuZ2VNYXJrKCl7cmV0dXJuIEZBTFNFO30vL0lzQW5ub3RNb2RpZmllZCgpfHxJc0Zvcm1Nb2RpZmllZCgpIHx8IElzV2lkZ2V0TW9kaWZpZWQoKXx8IG1fbkNoYW5nZU1hcms+MCA7fQkNCi0vLwl2b2lkICAgICAgICAgICAgICAgICAgICBDbGVhckNoYW5nZU1hcmsoKXt9DQotCUNGWF9XaWRlU3RyaW5nCQkJR2V0UGF0aCgpIDsNCi0JQ1BERl9QYWdlKgkJCQlHZXRQYWdlKGludCBuSW5kZXgpOw0KLQlDUERGRG9jX0Vudmlyb25tZW50ICoJR2V0RW52KCkge3JldHVybiBtX3BFbnY7IH0NCi0Jdm9pZAkJCQkgICAgUHJvY0phdmFzY3JpcHRGdW4oKTsNCi0JRlhfQk9PTAkJCQkJUHJvY09wZW5BY3Rpb24oKTsNCi0JQ1BERl9PQ0NvbnRleHQqCQkJR2V0T0NDb250ZXh0KCk7DQotcHJpdmF0ZToNCi0JLy9DRlhfQXJyYXlUZW1wbGF0ZTxDUERGU0RLX1BhZ2VWaWV3Kj4gbV9wYWdlQXJyYXk7DQotCUNGWF9NYXBQdHJUZW1wbGF0ZTxDUERGX1BhZ2UqLCBDUERGU0RLX1BhZ2VWaWV3Kj4gbV9wYWdlTWFwOw0KLQlDUERGX0RvY3VtZW50KgkJCW1fcERvYzsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qCQltX3BJbnRlckZvcm07DQotCUNQREZTREtfQW5ub3QqCQkJbV9wRm9jdXNBbm5vdDsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCAqCW1fcEVudjsNCi0JQ1BERl9PQ0NvbnRleHQgKgkJbV9wT2Njb250ZW50Ow0KLQlGWF9CT09MCQkJCQltX2JDaGFuZ2VNYXNrOw0KLX07DQotDQotY2xhc3MgQ1BERlNES19QYWdlVmlldw0KLXsNCi1wdWJsaWM6DQotCUNQREZTREtfUGFnZVZpZXcoQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyxDUERGX1BhZ2UqIHBhZ2UpOw0KLQl+Q1BERlNES19QYWdlVmlldygpOw0KLXB1YmxpYzoNCi0JdmlydHVhbAl2b2lkIFBhZ2VWaWV3X09uRHJhdyhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLENQREZfUmVuZGVyT3B0aW9ucyogcE9wdGlvbnMpIDsNCi1wdWJsaWM6DQotCUNQREZfQW5ub3QqCQkJCQkJR2V0UERGQW5ub3RBdFBvaW50KEZYX0ZMT0FUIHBhZ2VYLCBGWF9GTE9BVCBwYWdlWSk7DQotCUNQREZTREtfQW5ub3QqCQkJCQlHZXRGWEFubm90QXRQb2ludChGWF9GTE9BVCBwYWdlWCwgRlhfRkxPQVQgcGFnZVkpOw0KLQlDUERGX0Fubm90KgkJCQkJCUdldFBERldpZGdldEF0UG9pbnQoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKTsNCi0JQ1BERlNES19Bbm5vdCoJCQkJCUdldEZYV2lkZ2V0QXRQb2ludChGWF9GTE9BVCBwYWdlWCwgRlhfRkxPQVQgcGFnZVkpOw0KLQlDUERGU0RLX0Fubm90KgkJCQkJR2V0Rm9jdXNBbm5vdCgpIDsNCi0Jdm9pZAkJCQkJCQlTZXRGb2N1c0Fubm90KENQREZTREtfQW5ub3QqIHBTREtBbm5vdCxGWF9VSU5UIG5GbGFnID0gMCkge21fcFNES0RvYy0+U2V0Rm9jdXNBbm5vdChwU0RLQW5ub3QsIG5GbGFnKTt9DQotCUZYX0JPT0wJCQkJCQkJS2lsbEZvY3VzQW5ub3QoRlhfVUlOVCBuRmxhZyA9IDApIHtyZXR1cm4gbV9wU0RLRG9jLT5LaWxsRm9jdXNBbm5vdChuRmxhZyk7fQ0KLQlGWF9CT09MCQkJCQkJCUFubm90X0hhc0FwcGVhcmFuY2UoQ1BERl9Bbm5vdCogcEFubm90KTsNCi0NCi0JQ1BERlNES19Bbm5vdCoJCQkJCUFkZEFubm90KENQREZfRGljdGlvbmFyeSAqIHBEaWN0KTsNCi0JQ1BERlNES19Bbm5vdCoJCQkJCUFkZEFubm90KEZYX0xQQ1NUUiBscFN1YlR5cGUsQ1BERl9EaWN0aW9uYXJ5ICogcERpY3QpOw0KLQlDUERGU0RLX0Fubm90KgkJCQkJQWRkQW5ub3QoQ1BERl9Bbm5vdCAqIHBQREZBbm5vdCk7DQotCUZYX0JPT0wJCQkJCQkJRGVsZXRlQW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90KTsJCQkJCQkJDQotCQ0KLQlpbnQJCQkJCQkJCUNvdW50QW5ub3RzKCk7DQotCUNQREZTREtfQW5ub3QqCQkJCQlHZXRBbm5vdChpbnQgbkluZGV4KTsNCi0JQ1BERlNES19Bbm5vdCoJCQkJICAgIEdldEFubm90QnlEaWN0KENQREZfRGljdGlvbmFyeSAqIHBEaWN0KTsNCi0JQ1BERl9QYWdlKgkJCQkJCUdldFBERlBhZ2UoKXtyZXR1cm4gbV9wYWdlO30NCi0JQ1BERl9Eb2N1bWVudCoJCQkJCUdldFBERkRvY3VtZW50KCk7DQotCUNQREZTREtfRG9jdW1lbnQqCQkJCUdldFNES0RvY3VtZW50KCkge3JldHVybiBtX3BTREtEb2M7fQkNCi1wdWJsaWM6DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX1VJTlQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfVUlOVCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25DaGFyKGludCBuQ2hhciwgRlhfVUlOVCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25LZXlEb3duKGludCBuS2V5Q29kZSwgaW50IG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbktleVVwKGludCBuS2V5Q29kZSwgaW50IG5GbGFnKTsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIGludCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25Nb3VzZVdoZWVsKGRvdWJsZSBkZWx0YVgsIGRvdWJsZSBkZWx0YVksY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIGludCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJSXNWYWxpZEFubm90KEZYX0xQVk9JRCBwKTsNCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQkJR2V0Q3VycmVudE1hdHJpeChDUERGX01hdHJpeCYgbWF0cml4KSB7bWF0cml4ID0gbV9jdXJNYXRyaXg7fQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCVVwZGF0ZVJlY3RzKENGWF9SZWN0QXJyYXkmIHJlY3RzKTsNCi0Jdm9pZAkJCQkJCQlVcGRhdGVWaWV3KENQREZTREtfQW5ub3QqIHBBbm5vdCk7DQotCUNGWF9QdHJBcnJheSoJCQkJCUdldEFubm90TGlzdCgpeyByZXR1cm4gJm1fZnhBbm5vdEFycmF5OyB9DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIGludAkJCQkJCUdldFBhZ2VJbmRleCgpOw0KLQl2b2lkCQkJCQkJCUxvYWRGWEFubm90cygpOw0KLXByaXZhdGU6DQotCUNQREZfTWF0cml4IG1fY3VyTWF0cml4Ow0KLQ0KLXByaXZhdGU6DQotCXZvaWQgUGFnZVZpZXdfT25IaWdobGlnaHRGb3JtRmllbGRzKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0KTsNCi0NCi1wcml2YXRlOg0KLQlDUERGX1BhZ2UqIG1fcGFnZTsNCi0JQ1BERl9Bbm5vdExpc3QqIG1fcEFubm90TGlzdDsNCi0NCi0JLy9DUERGU0RLX0Fubm90KiBtX3BGb2N1c0Fubm90Ow0KLQlDRlhfUHRyQXJyYXkgIG1fZnhBbm5vdEFycmF5Ow0KLQ0KLQlDUERGU0RLX0RvY3VtZW50KiBtX3BTREtEb2M7DQotcHJpdmF0ZToNCi0JQ1BERlNES19XaWRnZXQqIG1fQ2FwdHVyZVdpZGdldDsNCi0JRlhfQk9PTCBtX2JFbnRlcldpZGdldDsNCi0JRlhfQk9PTCBtX2JFeGl0V2lkZ2V0Ow0KLQlGWF9CT09MIG1fYk9uV2lkZ2V0Ow0KLXB1YmxpYzoNCi0Jdm9pZCBTZXRWYWxpZChGWF9CT09MIGJWYWxpZCkge21fYlZhbGlkID0gYlZhbGlkO30NCi0JRlhfQk9PTCBJc1ZhbGlkKCkge3JldHVybiBtX2JWYWxpZDt9DQotcHJpdmF0ZToNCi0JRlhfQk9PTCBtX2JWYWxpZDsNCi19Ow0KLQ0KLQ0KLXRlbXBsYXRlPGNsYXNzIFRZUEU+DQotY2xhc3MgQ0dXX0FycmF5VGVtcGxhdGUgOiBwdWJsaWMgQ0ZYX0FycmF5VGVtcGxhdGU8VFlQRT4NCi17DQotcHVibGljOiANCi0JQ0dXX0FycmF5VGVtcGxhdGUoKXt9DQotCXZpcnR1YWwgfkNHV19BcnJheVRlbXBsYXRlKCl7fQ0KLQkNCi0JdHlwZWRlZiBpbnQgKCpMUF9DT01QQVJFKShUWVBFIHAxLCBUWVBFIHAyKTsNCi0JDQotCXZvaWQgU29ydChMUF9DT01QQVJFIHBDb21wYXJlLCBGWF9CT09MIGJBc2NlbnQgPSBUUlVFKQ0KLQl7DQotCQlpbnQgblNpemUgPSB0aGlzLT5HZXRTaXplKCk7DQotCQlRdWlja1NvcnQoMCwgblNpemUgLTEsIGJBc2NlbnQsIHBDb21wYXJlKTsNCi0JfQ0KLQkNCi1wcml2YXRlOg0KLQl2b2lkIFF1aWNrU29ydChGWF9VSU5UIG5TdGFydFBvcywgRlhfVUlOVCBuU3RvcFBvcywgRlhfQk9PTCBiQXNjZW5kLCBMUF9DT01QQVJFIHBDb21wYXJlKQ0KLQl7DQotCQlpZiAoblN0YXJ0UG9zID49IG5TdG9wUG9zKSByZXR1cm47DQotCQkNCi0JCWlmICgoblN0b3BQb3MgLSBuU3RhcnRQb3MpID09IDEpDQotCQl7DQotCQkJVFlQRSBWYWx1ZTEgPSB0aGlzLT5HZXRBdChuU3RhcnRQb3MpOw0KLQkJCVRZUEUgVmFsdWUyID0gdGhpcy0+R2V0QXQoblN0b3BQb3MpOw0KLQkJCQ0KLQkJCWludCBpR3JlYXRlID0gKCpwQ29tcGFyZSkoVmFsdWUxLCBWYWx1ZTIpOw0KLQkJCWlmICgoYkFzY2VuZCAmJiBpR3JlYXRlID4gMCkgfHwgKCFiQXNjZW5kICYmIGlHcmVhdGUgPCAwKSkNCi0JCQl7DQotCQkJCXRoaXMtPlNldEF0KG5TdGFydFBvcywgVmFsdWUyKTsNCi0JCQkJdGhpcy0+U2V0QXQoblN0b3BQb3MsIFZhbHVlMSk7DQotCQkJfQ0KLQkJCXJldHVybjsNCi0JCX0NCi0JCQ0KLQkJRlhfVUlOVCBtID0gKG5TdGFydFBvcyArIG5TdG9wUG9zKSAvIDI7DQotCQlGWF9VSU5UIGkgPSBuU3RhcnRQb3M7DQotCQkNCi0JCVRZUEUgVmFsdWUgPSB0aGlzLT5HZXRBdChtKTsNCi0JCQ0KLQkJd2hpbGUgKGkgPCBtKQ0KLQkJew0KLQkJCVRZUEUgdGVtcCA9IHRoaXMtPkdldEF0KGkpOw0KLQkJCQ0KLQkJCWludCBpR3JlYXRlID0gKCpwQ29tcGFyZSkodGVtcCwgVmFsdWUpOw0KLQkJCWlmICgoYkFzY2VuZCAmJiBpR3JlYXRlID4gMCkgfHwgKCFiQXNjZW5kICYmIGlHcmVhdGUgPCAwKSkNCi0JCQl7DQotCQkJCXRoaXMtPkluc2VydEF0KG0rMSwgdGVtcCk7DQotCQkJCXRoaXMtPlJlbW92ZUF0KGkpOw0KLQkJCQltLS07DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCWkrKzsNCi0JCQl9DQotCQl9DQotCQkNCi0JCUZYX1VJTlQgaiA9IG5TdG9wUG9zOw0KLQkJDQotCQl3aGlsZSAoaiA+IG0pDQotCQl7DQotCQkJVFlQRSB0ZW1wID0gdGhpcy0+R2V0QXQoaik7DQotCQkJDQotCQkJaW50IGlHcmVhdGUgPSAoKnBDb21wYXJlKSh0ZW1wLCBWYWx1ZSk7DQotCQkJaWYgKChiQXNjZW5kICYmIGlHcmVhdGUgPCAwKSB8fCAoIWJBc2NlbmQgJiYgaUdyZWF0ZSA+IDApKQ0KLQkJCXsNCi0JCQkJdGhpcy0+UmVtb3ZlQXQoaik7DQotCQkJCXRoaXMtPkluc2VydEF0KG0sIHRlbXApOw0KLQkJCQltKys7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCWotLTsNCi0JCQl9DQotCQl9DQotCQkNCi0JCWlmIChuU3RhcnRQb3MgPCBtKSBRdWlja1NvcnQoblN0YXJ0UG9zLCBtLCBiQXNjZW5kLCBwQ29tcGFyZSk7DQotCQlpZiAoblN0b3BQb3MgPiBtKSBRdWlja1NvcnQobSwgblN0b3BQb3MsIGJBc2NlbmQsIHBDb21wYXJlKTsNCi0JfQ0KLX07DQotDQotDQotI2VuZGlmIC8vX0ZQREZTREtfTUdSX0gNCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GUERGU0RLX01HUl9ICisjZGVmaW5lIF9GUERGU0RLX01HUl9ICisKKyNpbmNsdWRlICJmc2RrX2NvbW1vbi5oIgorI2luY2x1ZGUgImZzZGtfZGVmaW5lLmgiCisjaW5jbHVkZSAiZnhfc3lzdGVtaGFuZGxlci5oIgorI2luY2x1ZGUgImZzZGtfYmFzZWFubm90LmgiCisjaW5jbHVkZSAiZnNka19iYXNlZm9ybS5oIgorI2luY2x1ZGUgImZwZGZmb3JtZmlsbC5oIgorI2luY2x1ZGUgImZzZGtfYW5ub3RoYW5kbGVyLmgiCisjaW5jbHVkZSAiZnNka19hY3Rpb25oYW5kbGVyLmgiCisKKy8vY3Jvc3MgcGxhdGZvcm0ga2V5Y29kZSBhbmQgZXZlbnRzIGRlZmluZS4KKyNpbmNsdWRlICJmcGRmX2Z3bGV2ZW50LmgiCisKKworY2xhc3MgQ1BERlNES19Eb2N1bWVudDsKK2NsYXNzIENQREZTREtfUGFnZVZpZXc7CitjbGFzcyBDUERGU0RLX0Fubm90OworY2xhc3MgQ0ZGTF9JRm9ybUZpbGxlcjsKK2NsYXNzIENQREZTREtfV2lkZ2V0OworY2xhc3MgSUZYX1N5c3RlbUhhbmRsZXI7CitjbGFzcyBDUERGU0RLX0FjdGlvbkhhbmRsZXI7CitjbGFzcyBDSlNfUnVudGltZUZhY3Rvcnk7CisKKyNpbmNsdWRlICJqYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiCisKK2NsYXNzIENQREZEb2NfRW52aXJvbm1lbnQKK3sKK3B1YmxpYzoKKwlDUERGRG9jX0Vudmlyb25tZW50KENQREZfRG9jdW1lbnQgKiBwRG9jKTsKKwl+Q1BERkRvY19FbnZpcm9ubWVudCgpOworCisJaW50IFJlZ0FwcEhhbmRsZShGUERGX0ZPUk1GSUxMSU5GTyogcEZGaW5mbyk7Ly97IG1fcEluZm8gID0gcEZGaW5mbzsgcmV0dXJuIFRSVUU7fQorCisJdmlydHVhbCB2b2lkCQlSZWxlYXNlKCkKKwl7CisJCWlmIChtX3BJbmZvICYmIG1fcEluZm8tPlJlbGVhc2UpCisJCQltX3BJbmZvLT5SZWxlYXNlKG1fcEluZm8pOworCQlkZWxldGUgdGhpczsKKwl9CisKKwl2aXJ0dWFsIHZvaWQgRkZJX0ludmFsaWRhdGUoRlBERl9QQUdFIHBhZ2UsIGRvdWJsZSBsZWZ0LCBkb3VibGUgdG9wLCBkb3VibGUgcmlnaHQsIGRvdWJsZSBib3R0b20pCisJeworCQlpZiAobV9wSW5mbyAmJiBtX3BJbmZvLT5GRklfSW52YWxpZGF0ZSkgCisJCXsKKwkJCW1fcEluZm8tPkZGSV9JbnZhbGlkYXRlKG1fcEluZm8sIHBhZ2UsIGxlZnQsIHRvcCwgcmlnaHQsIGJvdHRvbSk7CisJCX0KKwl9CisJdmlydHVhbCB2b2lkIEZGSV9PdXRwdXRTZWxlY3RlZFJlY3QoRlBERl9QQUdFIHBhZ2UsIGRvdWJsZSBsZWZ0LCBkb3VibGUgdG9wLCBkb3VibGUgcmlnaHQsIGRvdWJsZSBib3R0b20pCisJeworCQlpZiAobV9wSW5mbyAmJiBtX3BJbmZvLT5GRklfT3V0cHV0U2VsZWN0ZWRSZWN0KSAKKwkJeworCQkJbV9wSW5mby0+RkZJX091dHB1dFNlbGVjdGVkUmVjdChtX3BJbmZvLCBwYWdlLCBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20pOworCQl9CisJfQorCisJdmlydHVhbCB2b2lkIEZGSV9TZXRDdXJzb3IoaW50IG5DdXJzb3JUeXBlKQorCXsKKwkJaWYgKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX1NldEN1cnNvcikgCisJCXsKKwkJCW1fcEluZm8tPkZGSV9TZXRDdXJzb3IobV9wSW5mbywgbkN1cnNvclR5cGUpOworCQl9CisJfQorCisJdmlydHVhbAlpbnQgIEZGSV9TZXRUaW1lcihpbnQgdUVsYXBzZSwgVGltZXJDYWxsYmFjayBscFRpbWVyRnVuYykKKwl7CisJCWlmIChtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9TZXRUaW1lcikgCisJCXsKKwkJCXJldHVybiBtX3BJbmZvLT5GRklfU2V0VGltZXIobV9wSW5mbywgdUVsYXBzZSwgbHBUaW1lckZ1bmMpOworCQl9CisJCXJldHVybiAtMTsKKwl9CisJCQorCXZpcnR1YWwgdm9pZCBGRklfS2lsbFRpbWVyKGludCBuVGltZXJJRCkKKwl7CisJCWlmIChtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9LaWxsVGltZXIpIAorCQl7CisJCQltX3BJbmZvLT5GRklfS2lsbFRpbWVyKG1fcEluZm8sIG5UaW1lcklEKTsKKwkJfQorCX0KKwlGWF9TWVNURU1USU1FIEZGSV9HZXRMb2NhbFRpbWUoKQorCXsKKwkJRlhfU1lTVEVNVElNRSBmeHRpbWU7CisJCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX0dldExvY2FsVGltZSkKKwkJeworCQkJRlBERl9TWVNURU1USU1FIHN5c3RpbWUgPSBtX3BJbmZvLT5GRklfR2V0TG9jYWxUaW1lKG1fcEluZm8pOworCQkJZnh0aW1lLndEYXkgPSBzeXN0aW1lLndEYXk7CisJCQlmeHRpbWUud0RheU9mV2VlayA9IHN5c3RpbWUud0RheU9mV2VlazsKKwkJCWZ4dGltZS53SG91ciA9IHN5c3RpbWUud0hvdXI7CisJCQlmeHRpbWUud01pbGxpc2Vjb25kcyA9IHN5c3RpbWUud01pbGxpc2Vjb25kczsKKwkJCWZ4dGltZS53TWludXRlID0gc3lzdGltZS53TWludXRlOworCQkJZnh0aW1lLndNb250aCA9IHN5c3RpbWUud01vbnRoOworCQkJZnh0aW1lLndTZWNvbmQgPSBzeXN0aW1lLndTZWNvbmQ7CisJCQlmeHRpbWUud1llYXIgPSBzeXN0aW1lLndZZWFyOworCQl9CisJCXJldHVybiBmeHRpbWU7CisJfQorCisJdmlydHVhbCB2b2lkIEZGSV9PbkNoYW5nZSgpCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9PbkNoYW5nZSkKKwkJeworCQkJbV9wSW5mby0+RkZJX09uQ2hhbmdlKG1fcEluZm8pOworCQl9CisJfQorCisJdmlydHVhbAlGWF9CT09MCUZGSV9Jc1NISUZUS2V5RG93bihGWF9EV09SRCBuRmxhZykKKwl7CisJCQorCQlyZXR1cm4gKG5GbGFnICYgRldMX0VWRU5URkxBR19TaGlmdEtleSkgIT0gMDsKKwl9CisJdmlydHVhbAlGWF9CT09MCUZGSV9Jc0NUUkxLZXlEb3duKEZYX0RXT1JEIG5GbGFnKQorCXsKKworCQlyZXR1cm4gKG5GbGFnICYgRldMX0VWRU5URkxBR19Db250cm9sS2V5KSAhPSAwOworCX0KKwl2aXJ0dWFsCUZYX0JPT0wJRkZJX0lzQUxUS2V5RG93bihGWF9EV09SRCBuRmxhZykKKwl7CisKKwkJcmV0dXJuIChuRmxhZyAmIEZXTF9FVkVOVEZMQUdfQWx0S2V5KSAhPSAwOworCX0KKwl2aXJ0dWFsCUZYX0JPT0wJRkZJX0lzSU5TRVJUS2V5RG93bihGWF9EV09SRCBuRmxhZykKKwl7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwl2aXJ0dWFsIGludCBKU19hcHBBbGVydChGWF9MUENXU1RSIE1zZywgRlhfTFBDV1NUUiBUaXRsZSwgRlhfVUlOVCBUeXBlLCBGWF9VSU5UIEljb24pCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX2FsZXJ0KQorCQl7CisJCQlDRlhfQnl0ZVN0cmluZyBic01zZyA9IENGWF9XaWRlU3RyaW5nKE1zZykuVVRGMTZMRV9FbmNvZGUoKTsKKwkJCUNGWF9CeXRlU3RyaW5nIGJzVGl0bGUgPSBDRlhfV2lkZVN0cmluZyhUaXRsZSkuVVRGMTZMRV9FbmNvZGUoKTsKKwkJCUZQREZfV0lERVNUUklORyBwTXNnID0gKEZQREZfV0lERVNUUklORylic01zZy5HZXRCdWZmZXIoYnNNc2cuR2V0TGVuZ3RoKCkpOworCQkJRlBERl9XSURFU1RSSU5HIHBUaXRsZSA9IChGUERGX1dJREVTVFJJTkcpYnNUaXRsZS5HZXRCdWZmZXIoYnNUaXRsZS5HZXRMZW5ndGgoKSk7CisJCQlpbnQgcmV0ID0gbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX2FsZXJ0KG1fcEluZm8tPm1fcEpzUGxhdGZvcm0sIHBNc2csIHBUaXRsZSwgVHlwZSwgSWNvbik7CisJCQlic01zZy5SZWxlYXNlQnVmZmVyKCk7CisJCQlic1RpdGxlLlJlbGVhc2VCdWZmZXIoKTsKKwkJCXJldHVybiByZXQ7CisJCX0KKwkJcmV0dXJuIC0xOworCX0KKworCXZpcnR1YWwgaW50IEpTX2FwcFJlc3BvbnNlKEZYX0xQQ1dTVFIgUXVlc3Rpb24sIEZYX0xQQ1dTVFIgVGl0bGUsIEZYX0xQQ1dTVFIgRGVmYXVsdCwgRlhfTFBDV1NUUiBjTGFiZWwsIEZQREZfQk9PTCBiUGFzc3dvcmQsIHZvaWQqIHJlc3BvbnNlLCBpbnQgbGVuZ3RoKQorCXsKKwkJaWYgKG1fcEluZm8gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybSAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5hcHBfcmVzcG9uc2UpCisJCXsKKwkJCUNGWF9CeXRlU3RyaW5nIGJzUXVlc3Rpb24gPSBDRlhfV2lkZVN0cmluZyhRdWVzdGlvbikuVVRGMTZMRV9FbmNvZGUoKTsKKwkJCUNGWF9CeXRlU3RyaW5nIGJzVGl0bGUgPSBDRlhfV2lkZVN0cmluZyhUaXRsZSkuVVRGMTZMRV9FbmNvZGUoKTsKKwkJCUNGWF9CeXRlU3RyaW5nIGJzRGVmYXVsdCA9IENGWF9XaWRlU3RyaW5nKERlZmF1bHQpLlVURjE2TEVfRW5jb2RlKCk7CisJCQlDRlhfQnl0ZVN0cmluZyBic0xhYmVsID0gQ0ZYX1dpZGVTdHJpbmcoY0xhYmVsKS5VVEYxNkxFX0VuY29kZSgpOworCQkJRlBERl9XSURFU1RSSU5HIHBRdWVzdGlvbiA9IChGUERGX1dJREVTVFJJTkcpYnNRdWVzdGlvbi5HZXRCdWZmZXIoYnNRdWVzdGlvbi5HZXRMZW5ndGgoKSk7CisJCQlGUERGX1dJREVTVFJJTkcgcFRpdGxlID0gKEZQREZfV0lERVNUUklORylic1RpdGxlLkdldEJ1ZmZlcihic1RpdGxlLkdldExlbmd0aCgpKTsKKwkJCUZQREZfV0lERVNUUklORyBwRGVmYXVsdCA9IChGUERGX1dJREVTVFJJTkcpYnNEZWZhdWx0LkdldEJ1ZmZlcihic0RlZmF1bHQuR2V0TGVuZ3RoKCkpOworCQkJRlBERl9XSURFU1RSSU5HIHBMYWJlbCA9IChGUERGX1dJREVTVFJJTkcpYnNMYWJlbC5HZXRCdWZmZXIoYnNMYWJlbC5HZXRMZW5ndGgoKSk7CisJCQlpbnQgcmV0ID0gbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX3Jlc3BvbnNlKG1fcEluZm8tPm1fcEpzUGxhdGZvcm0sIHBRdWVzdGlvbiwgcFRpdGxlLCAKKwkJCQlwRGVmYXVsdCwgcExhYmVsLCBiUGFzc3dvcmQsIHJlc3BvbnNlLCBsZW5ndGgpOworCQkJYnNRdWVzdGlvbi5SZWxlYXNlQnVmZmVyKCk7CisJCQlic1RpdGxlLlJlbGVhc2VCdWZmZXIoKTsKKwkJCWJzRGVmYXVsdC5SZWxlYXNlQnVmZmVyKCk7CisJCQlic0xhYmVsLlJlbGVhc2VCdWZmZXIoKTsKKwkJCXJldHVybiByZXQ7CisJCX0KKwkJcmV0dXJuIC0xOworCX0KKworCXZpcnR1YWwgdm9pZCBKU19hcHBCZWVwKGludCBuVHlwZSkKKwl7CisJCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybSAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5hcHBfYmVlcCkKKwkJeworCQkJbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+YXBwX2JlZXAobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSwgblR5cGUpOworCQl9CisJfQorCisJdmlydHVhbCBDRlhfV2lkZVN0cmluZyBKU19maWVsZEJyb3dzZSgpCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RmllbGRfYnJvd3NlKQorCQl7CisJCQlpbnQgbkxlbiA9IG1fcEluZm8tPm1fcEpzUGxhdGZvcm0tPkZpZWxkX2Jyb3dzZShtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLCBOVUxMLCAwKTsKKwkJCWlmKG5MZW4gPD0gMCkKKwkJCQlyZXR1cm4gTCIiOworCQkJY2hhciogcGJ1ZmYgPSBuZXcgY2hhcltuTGVuXTsKKwkJCWlmKHBidWZmKQorCQkJCW1lbXNldChwYnVmZiwgMCwgbkxlbik7CisJCQllbHNlCQorCQkJCXJldHVybiBMIiI7CisJCQluTGVuID0gbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RmllbGRfYnJvd3NlKG1fcEluZm8tPm1fcEpzUGxhdGZvcm0sIHBidWZmLCBuTGVuKTsKKwkJCUNGWF9CeXRlU3RyaW5nIGJzUmV0ID0gQ0ZYX0J5dGVTdHJpbmcocGJ1ZmYsIG5MZW4pOworCQkJQ0ZYX1dpZGVTdHJpbmcgd3NSZXQgPSBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGJzUmV0KTsKKwkJCWRlbGV0ZVtdIHBidWZmOworCQkJcmV0dXJuIHdzUmV0OworCQl9CisJCXJldHVybiBMIiI7CisJfQorCisJQ0ZYX1dpZGVTdHJpbmcgSlNfZG9jR2V0RmlsZVBhdGgoKQorCXsJCQorCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RG9jX2dldEZpbGVQYXRoKQorCQl7CisJCQlpbnQgbkxlbiA9IG1fcEluZm8tPm1fcEpzUGxhdGZvcm0tPkRvY19nZXRGaWxlUGF0aChtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLCBOVUxMLCAwKTsKKwkJCWlmKG5MZW4gPD0gMCkKKwkJCQlyZXR1cm4gTCIiOworCQkJY2hhciogcGJ1ZmYgPSBuZXcgY2hhcltuTGVuXTsKKwkJCWlmKHBidWZmKQorCQkJCW1lbXNldChwYnVmZiwgMCwgbkxlbik7CisJCQllbHNlCisJCQkJcmV0dXJuIEwiIjsKKwkJCW5MZW4gPSBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfZ2V0RmlsZVBhdGgobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSwgcGJ1ZmYsIG5MZW4pOworCQkJQ0ZYX0J5dGVTdHJpbmcgYnNSZXQgPSBDRlhfQnl0ZVN0cmluZyhwYnVmZiwgbkxlbik7CisJCQlDRlhfV2lkZVN0cmluZyB3c1JldCA9IENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoYnNSZXQpOworCQkJZGVsZXRlW10gcGJ1ZmY7CisJCQlyZXR1cm4gd3NSZXQ7CisJCX0KKwkJcmV0dXJuIEwiIjsKKwl9CisKKwl2b2lkIEpTX2RvY1N1Ym1pdEZvcm0odm9pZCogZm9ybURhdGEsIGludCBsZW5ndGgsIEZYX0xQQ1dTVFIgVVJMKQorCXsKKwkJaWYobV9wSW5mbyAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0tPkRvY19zdWJtaXRGb3JtKQorCQl7CisJCQlDRlhfQnl0ZVN0cmluZyBic0Rlc3RpbmF0aW9uID0gQ0ZYX1dpZGVTdHJpbmcoVVJMKS5VVEYxNkxFX0VuY29kZSgpOworCQkJRlBERl9XSURFU1RSSU5HIHBEZXN0aW5hdGlvbiA9IChGUERGX1dJREVTVFJJTkcpYnNEZXN0aW5hdGlvbi5HZXRCdWZmZXIoYnNEZXN0aW5hdGlvbi5HZXRMZW5ndGgoKSk7CisJCQltX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2Nfc3VibWl0Rm9ybShtX3BJbmZvLT5tX3BKc1BsYXRmb3JtLCBmb3JtRGF0YSwgbGVuZ3RoLCBwRGVzdGluYXRpb24pOworCQkJYnNEZXN0aW5hdGlvbi5SZWxlYXNlQnVmZmVyKCk7CisJCX0KKwl9CisKKwl2b2lkIEpTX2RvY21haWxGb3JtKHZvaWQqIG1haWxEYXRhLCBpbnQgbGVuZ3RoLCBGUERGX0JPT0wgYlVJLEZYX0xQQ1dTVFIgVG8sIEZYX0xQQ1dTVFIgU3ViamVjdCwgRlhfTFBDV1NUUiBDQywgRlhfTFBDV1NUUiBCQ0MsIEZYX0xQQ1dTVFIgTXNnKQorCXsKKwkJaWYobV9wSW5mbyAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0tPkRvY19tYWlsKQorCQl7CisJCQlDRlhfQnl0ZVN0cmluZyBic1RvID0gQ0ZYX1dpZGVTdHJpbmcoVG8pLlVURjE2TEVfRW5jb2RlKCk7CisJCQlDRlhfQnl0ZVN0cmluZyBic0NDID0gQ0ZYX1dpZGVTdHJpbmcoU3ViamVjdCkuVVRGMTZMRV9FbmNvZGUoKTsKKwkJCUNGWF9CeXRlU3RyaW5nIGJzQmNjID0gQ0ZYX1dpZGVTdHJpbmcoQkNDKS5VVEYxNkxFX0VuY29kZSgpOworCQkJQ0ZYX0J5dGVTdHJpbmcgYnNTdWJqZWN0ID0gQ0ZYX1dpZGVTdHJpbmcoU3ViamVjdCkuVVRGMTZMRV9FbmNvZGUoKTsKKwkJCUNGWF9CeXRlU3RyaW5nIGJzTXNnID0gQ0ZYX1dpZGVTdHJpbmcoTXNnKS5VVEYxNkxFX0VuY29kZSgpOworCQkJRlBERl9XSURFU1RSSU5HIHBUbyA9IChGUERGX1dJREVTVFJJTkcpYnNUby5HZXRCdWZmZXIoYnNUby5HZXRMZW5ndGgoKSk7CisJCQlGUERGX1dJREVTVFJJTkcgcENDID0gKEZQREZfV0lERVNUUklORylic0NDLkdldEJ1ZmZlcihic0NDLkdldExlbmd0aCgpKTsKKwkJCUZQREZfV0lERVNUUklORyBwQmNjID0gKEZQREZfV0lERVNUUklORylic0JjYy5HZXRCdWZmZXIoYnNCY2MuR2V0TGVuZ3RoKCkpOworCQkJRlBERl9XSURFU1RSSU5HIHBTdWJqZWN0ID0gKEZQREZfV0lERVNUUklORylic1N1YmplY3QuR2V0QnVmZmVyKGJzU3ViamVjdC5HZXRMZW5ndGgoKSk7CisJCQlGUERGX1dJREVTVFJJTkcgcE1zZyA9IChGUERGX1dJREVTVFJJTkcpYnNNc2cuR2V0QnVmZmVyKGJzTXNnLkdldExlbmd0aCgpKTsKKwkJCW1fcEluZm8tPm1fcEpzUGxhdGZvcm0tPkRvY19tYWlsKG1fcEluZm8tPm1fcEpzUGxhdGZvcm0sIG1haWxEYXRhLCBsZW5ndGgsIGJVSSwgcFRvLCBwU3ViamVjdCwKKwkJCQlwQ0MsIHBCY2MsIHBNc2cpOworCQkJYnNUby5SZWxlYXNlQnVmZmVyKCk7CisJCQlic0NDLlJlbGVhc2VCdWZmZXIoKTsKKwkJCWJzQmNjLlJlbGVhc2VCdWZmZXIoKTsKKwkJCWJzU3ViamVjdC5SZWxlYXNlQnVmZmVyKCk7CisJCQlic01zZy5SZWxlYXNlQnVmZmVyKCk7CisJCX0KKwl9CisJQ0ZYX1dpZGVTdHJpbmcgSlNfYXBwYnJvd3NlRm9yRG9jKEZQREZfQk9PTCBiU2F2ZSwgRlhfTFBDV1NUUiBjRmlsZW5hbWVJbml0KQorCXsKKwkJLy90byBkby4uLi4KKwkJcmV0dXJuIEwiIjsKKy8vIAkJaWYobV9wSW5mbyAmJiBtX3BJbmZvLT5tX3BKc1BsYXRmb3JtICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0tPmFwcF9icm93c2VGb3JEb2MpCisvLyAJCXsKKy8vIAkJCUNGWF9CeXRlU3RyaW5nIGJzRmlsZW5hbWVJbml0ID0gQ0ZYX1dpZGVTdHJpbmcoY0ZpbGVuYW1lSW5pdCkuVVRGMTZMRV9FbmNvZGUoKTsKKy8vIAkJCUZQREZfV0lERVNUUklORyBwRmlsZU5hbWVJbml0ID0gKEZQREZfV0lERVNUUklORylic0ZpbGVuYW1lSW5pdC5HZXRCdWZmZXIoYnNGaWxlbmFtZUluaXQuR2V0TGVuZ3RoKCkpOworLy8gCisvLyAJCQltX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5hcHBfYnJvd3NlRm9yRG9jKG1fcEluZm8tPm1fcEpzUGxhdGZvcm0sIHBGaWxlTmFtZUluaXQpOworLy8gCQkJYnNGaWxlbmFtZUluaXQuUmVsZWFzZUJ1ZmZlcigpOworLy8gCQl9CisJfQorCisJdm9pZCBKU19kb2NwcmludChGUERGX0JPT0wgYlVJICwgaW50IG5TdGFydCwgaW50IG5FbmQsIEZQREZfQk9PTCBiU2lsZW50ICxGUERGX0JPT0wgYlNocmlua1RvRml0LEZQREZfQk9PTCBiUHJpbnRBc0ltYWdlICxGUERGX0JPT0wgYlJldmVyc2UgLEZQREZfQk9PTCBiQW5ub3RhdGlvbnMpCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RG9jX3ByaW50KQorCQl7CisJCQltX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfcHJpbnQobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSwgYlVJLCBuU3RhcnQsIG5FbmQsIGJTaWxlbnQsIGJTaHJpbmtUb0ZpdCwgYlByaW50QXNJbWFnZSwgYlJldmVyc2UsIGJBbm5vdGF0aW9ucyk7CisJCX0KKwl9CisJdm9pZCBKU19kb2Nnb3RvUGFnZShpbnQgblBhZ2VOdW0pCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPm1fcEpzUGxhdGZvcm0gJiYgbV9wSW5mby0+bV9wSnNQbGF0Zm9ybS0+RG9jX2dvdG9QYWdlKQorCQl7CisJCQltX3BJbmZvLT5tX3BKc1BsYXRmb3JtLT5Eb2NfZ290b1BhZ2UobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSwgblBhZ2VOdW0pOworCQl9CisJfQorCisJdmlydHVhbCBGUERGX1BBR0UJRkZJX0dldFBhZ2UoRlBERl9ET0NVTUVOVCBkb2N1bWVudCxpbnQgblBhZ2VJbmRleCkKKwl7CisJCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX0dldFBhZ2UpCisJCXsKKwkJCXJldHVybiBtX3BJbmZvLT5GRklfR2V0UGFnZShtX3BJbmZvLCBkb2N1bWVudCwgblBhZ2VJbmRleCk7CisJCX0KKwkJcmV0dXJuIE5VTEw7CisJfQorCisJdmlydHVhbCBGUERGX1BBR0UgRkZJX0dldEN1cnJlbnRQYWdlKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9HZXRDdXJyZW50UGFnZSkKKwkJeworCQkJcmV0dXJuIG1fcEluZm8tPkZGSV9HZXRDdXJyZW50UGFnZShtX3BJbmZvLCBkb2N1bWVudCk7CisJCX0KKwkJcmV0dXJuIE5VTEw7CisJfQorCisJaW50IAlGRklfR2V0Um90YXRpb24oRlBERl9QQUdFIHBhZ2UpCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9HZXRSb3RhdGlvbikKKwkJeworCQkJcmV0dXJuIG1fcEluZm8tPkZGSV9HZXRSb3RhdGlvbihtX3BJbmZvLCBwYWdlKTsKKwkJfQorCQlyZXR1cm4gMDsKKwl9CisJdm9pZAlGRklfRXhlY3V0ZU5hbWVkQWN0aW9uKEZYX0xQQ1NUUiBuYW1lZEFjdGlvbikKKwl7CisJCWlmKG1fcEluZm8gJiYgbV9wSW5mby0+RkZJX0V4ZWN1dGVOYW1lZEFjdGlvbikKKwkJeworCQkJbV9wSW5mby0+RkZJX0V4ZWN1dGVOYW1lZEFjdGlvbihtX3BJbmZvLCBuYW1lZEFjdGlvbik7CisJCX0KKwl9CisJdm9pZAlGRklfT25TZXRGaWVsZElucHV0Rm9jdXModm9pZCogZmllbGQsRlBERl9XSURFU1RSSU5HIGZvY3VzVGV4dCwgRlBERl9EV09SRCBuVGV4dExlbiwgRlhfQk9PTCBiRm9jdXMpCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9TZXRUZXh0RmllbGRGb2N1cykKKwkJeworCQkJbV9wSW5mby0+RkZJX1NldFRleHRGaWVsZEZvY3VzKG1fcEluZm8sIGZvY3VzVGV4dCwgblRleHRMZW4sIGJGb2N1cyk7CisJCX0KKwl9CisKKwl2b2lkCUZGSV9Eb1VSSUFjdGlvbihGWF9MUENTVFIgYnNVUkkpCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9Eb1VSSUFjdGlvbikKKwkJeworCQkJbV9wSW5mby0+RkZJX0RvVVJJQWN0aW9uKG1fcEluZm8sIGJzVVJJKTsKKwkJfQorCX0KKworCXZvaWQJRkZJX0RvR29Ub0FjdGlvbihpbnQgblBhZ2VJbmRleCwgaW50IHpvb21Nb2RlLCBmbG9hdCogZlBvc0FycmF5LCBpbnQgc2l6ZU9mQXJyYXkpCisJeworCQlpZihtX3BJbmZvICYmIG1fcEluZm8tPkZGSV9Eb0dvVG9BY3Rpb24pCisJCXsKKwkJCW1fcEluZm8tPkZGSV9Eb0dvVG9BY3Rpb24obV9wSW5mbywgblBhZ2VJbmRleCwgem9vbU1vZGUsIGZQb3NBcnJheSwgc2l6ZU9mQXJyYXkpOworCQl9CisJfQorCitwdWJsaWM6CisJRlhfQk9PTAkJCQlJc0pTSW5pdGlhdGVkKCk7CisKK3B1YmxpYzoJCisJdm9pZAkJCQlTZXRDdXJyZW50RG9jKENQREZTREtfRG9jdW1lbnQqIHBGWERvYykge21fcFNES0RvYyA9IHBGWERvYzt9CisJQ1BERlNES19Eb2N1bWVudCoJR2V0Q3VycmVudERvYygpOworCUNQREZfRG9jdW1lbnQqCQlHZXRQREZEb2N1bWVudCgpIHtyZXR1cm4gbV9wUERGRG9jO30KKy8vIAlDUERGU0RLX0RvY3VtZW50KiAgIEdldERvY3VtZW50KGludCBuSW5kZXgpOworLy8gCWludAkJCQkJQ291bnREb2N1bWVudHMoKSB7cmV0dXJuIG1fZG9jTWFwLkdldENvdW50KCk7fQorCisJQ1BERlNES19Eb2N1bWVudCoJCU9wZW5Eb2N1bWVudChDRlhfV2lkZVN0cmluZyAmZmlsZU5hbWUpOworCUNQREZTREtfRG9jdW1lbnQqCQlPcGVuTWVtUERGRG9jKENQREZfRG9jdW1lbnQqIHBOZXdEb2MsIENGWF9XaWRlU3RyaW5nICZmaWxlTmFtZSk7CisJRlhfQk9PTAkJCQkJT3BlblVSTChDRlhfV2lkZVN0cmluZyAmZmlsZVBhdGgpOworCQorCisJQ0ZYX0J5dGVTdHJpbmcJCUdldEFwcE5hbWUoKSB7cmV0dXJuICIiO30KKworCUNGRkxfSUZvcm1GaWxsZXIqCUdldElGb3JtRmlsbGVyKCk7CisJSUZYX1N5c3RlbUhhbmRsZXIqCUdldFN5c0hhbmRsZXIoKSB7cmV0dXJuIG1fcFN5c0hhbmRsZXI7fQorCitwdWJsaWM6CisJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIEdldEFubm90SGFuZGxlck1ncigpOworCUlGWEpTX1J1bnRpbWUqCUdldEpTUnVudGltZSgpOworCUNQREZTREtfQWN0aW9uSGFuZGxlciogR2V0QWN0aW9uSGFuZGVyKCk7Citwcml2YXRlOgorCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBtX3BBbm5vdEhhbmRsZXJNZ3I7CisJQ1BERlNES19BY3Rpb25IYW5kbGVyKgltX3BBY3Rpb25IYW5kbGVyOworCUlGWEpTX1J1bnRpbWUqCW1fcEpTUnVudGltZTsKK3B1YmxpYzoKKwlGUERGX0ZPUk1GSUxMSU5GTyogR2V0Rm9ybUZpbGxJbmZvKCkge3JldHVybiBtX3BJbmZvO30KK3ByaXZhdGU6CisJRlBERl9GT1JNRklMTElORk8qCW1fcEluZm87CisvLwlDRlhfTWFwUHRyVGVtcGxhdGU8Q1BERl9Eb2N1bWVudCosIENQREZTREtfRG9jdW1lbnQqPiBtX2RvY01hcDsKKwlDUERGU0RLX0RvY3VtZW50KiBtX3BTREtEb2M7CisJQ1BERl9Eb2N1bWVudCogbV9wUERGRG9jOworCisJQ0ZGTF9JRm9ybUZpbGxlciogbV9wSUZvcm1GaWxsZXI7CisJSUZYX1N5c3RlbUhhbmRsZXIqIG1fcFN5c0hhbmRsZXI7CisKK3B1YmxpYzoKKwlDSlNfUnVudGltZUZhY3RvcnkqICBtX3BKU1J1bnRpbWVGYWN0b3J5OworfTsKKworCisKKy8vIGNsYXNzIENGWF9BcHAKKy8vIHsKKy8vIHB1YmxpYzoKKy8vIAlDRlhfQXBwKCk6bV9wQ3VyRG9jKE5VTEwpIHt9CisvLyAJdm9pZCBTZXRBdChDUERGX0RvY3VtZW50KiBwUERGRG9jLCBDUERGU0RLX0RvY3VtZW50KiBwRlhEb2MpOworLy8gCUNQREZTREtfRG9jdW1lbnQqIEdldEF0KENQREZfRG9jdW1lbnQqIHBQREZEb2MpOworLy8gcHVibGljOgorLy8gCXZvaWQgU2V0Q3VycmVudERvY3VtZW50KENQREZTREtfRG9jdW1lbnQqIHBGWERvYykge21fcEN1ckRvYyA9IHBGWERvYzt9CisvLyAJQ1BERlNES19Eb2N1bWVudCogR2V0Q3VycmVudERvY3VtZW50KCkge3JldHVybiBtX3BDdXJEb2M7fQorLy8gcHJpdmF0ZToKKy8vIAlDRlhfTWFwUHRyVGVtcGxhdGU8Q1BERl9Eb2N1bWVudCosIENQREZTREtfRG9jdW1lbnQqPiBtX2RvY0FycmF5OworLy8gCUNQREZTREtfRG9jdW1lbnQqIG1fcEN1ckRvYzsKKy8vIH07CitjbGFzcyBDUERGU0RLX0ludGVyRm9ybTsKK2NsYXNzIENQREZTREtfRG9jdW1lbnQKK3sKK3B1YmxpYzoKKwlDUERGU0RLX0RvY3VtZW50KENQREZfRG9jdW1lbnQqIHBEb2MsIENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYpOworCX5DUERGU0RLX0RvY3VtZW50KCk7CitwdWJsaWM6CisJQ1BERlNES19JbnRlckZvcm0qCQlHZXRJbnRlckZvcm0oKSA7CisJQ1BERl9Eb2N1bWVudCoJCQlHZXREb2N1bWVudCgpIHtyZXR1cm4gbV9wRG9jO30KKworcHVibGljOgorCXZvaWQJCQkJCUluaXRQYWdlVmlldygpOworCXZvaWQJCQkJCUFkZFBhZ2VWaWV3KENQREZfUGFnZSogcFBERlBhZ2UsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyk7CisJQ1BERlNES19QYWdlVmlldyoJCUdldFBhZ2VWaWV3KENQREZfUGFnZSogcFBERlBhZ2UsIEZYX0JPT0wgUmVOZXcgPSBUUlVFKTsKKwlDUERGU0RLX1BhZ2VWaWV3KgkJR2V0UGFnZVZpZXcoaW50IG5JbmRleCk7CisJQ1BERlNES19QYWdlVmlldyoJCUdldEN1cnJlbnRWaWV3KCk7CisJdm9pZAkJCQkJUmVNb3ZlUGFnZVZpZXcoQ1BERl9QYWdlKiBwUERGUGFnZSk7CisJdm9pZAkJCQkJVXBkYXRlQWxsVmlld3MoQ1BERlNES19QYWdlVmlldyogcFNlbmRlciwgQ1BERlNES19Bbm5vdCogcEFubm90KTsKKworCUNQREZTREtfQW5ub3QqCQkJR2V0Rm9jdXNBbm5vdCgpOy8ve3JldHVybiBOVUxMO30KKworCUlGWEpTX1J1bnRpbWUgKgkJCUdldEpzUnVudGltZSgpOworCQorCUZYX0JPT0wJCQkJCVNldEZvY3VzQW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnID0gMCk7Ly97cmV0dXJuIEZBTFNFO30KKwlGWF9CT09MCQkJCQlLaWxsRm9jdXNBbm5vdChGWF9VSU5UIG5GbGFnID0gMCk7CisKKwlGWF9CT09MCQkJCQlFeHRyYWN0UGFnZXMoY29uc3QgQ0ZYX1dvcmRBcnJheSAmYXJyRXh0cmFQYWdlcywgQ1BERl9Eb2N1bWVudCogcERzdERvYyk7CisJRlhfQk9PTAkJCQkJSW5zZXJ0UGFnZXMoaW50IG5JbnNlcnRBdCwgY29uc3QgQ1BERl9Eb2N1bWVudCogcFNyY0RvYywgY29uc3QgQ0ZYX1dvcmRBcnJheSAmYXJyU3JjUGFnZXMpOworCUZYX0JPT0wJCQkJCURlbGV0ZVBhZ2VzKGludCBuU3RhcnQsIGludCBuQ291bnQpOworCUZYX0JPT0wJCQkJCVJlcGxhY2VQYWdlcyhpbnQgblBhZ2UsIGNvbnN0IENQREZfRG9jdW1lbnQqIHBTcmNEb2MsIGNvbnN0IENGWF9Xb3JkQXJyYXkgJmFyclNyY1BhZ2VzKTsKKworCXZvaWQJCQkJCU9uQ2xvc2VEb2N1bWVudCgpOworCisJaW50CQkJCQkJR2V0UGFnZUNvdW50KCkge3JldHVybiBtX3BEb2MtPkdldFBhZ2VDb3VudCgpO30KKwlGWF9CT09MCQkJCQlHZXRQZXJtaXNzaW9ucyhpbnQgbkZsYWcpOworCUZYX0JPT0wJCQkJCUdldENoYW5nZU1hcmsoKSB7cmV0dXJuIG1fYkNoYW5nZU1hc2s7fQorCXZvaWQJCQkJCVNldENoYW5nZU1hcmsoKSB7bV9iQ2hhbmdlTWFzayA9IFRSVUU7fQorCXZvaWQJCQkJCUNsZWFyQ2hhbmdlTWFyaygpIHttX2JDaGFuZ2VNYXNrPSBGQUxTRTt9CisvLwlGWF9CT09MCQkJCQlHZXRDaGFuZ2VNYXJrKCl7cmV0dXJuIEZBTFNFO30vL0lzQW5ub3RNb2RpZmllZCgpfHxJc0Zvcm1Nb2RpZmllZCgpIHx8IElzV2lkZ2V0TW9kaWZpZWQoKXx8IG1fbkNoYW5nZU1hcms+MCA7fQkKKy8vCXZvaWQgICAgICAgICAgICAgICAgICAgIENsZWFyQ2hhbmdlTWFyaygpe30KKwlDRlhfV2lkZVN0cmluZwkJCUdldFBhdGgoKSA7CisJQ1BERl9QYWdlKgkJCQlHZXRQYWdlKGludCBuSW5kZXgpOworCUNQREZEb2NfRW52aXJvbm1lbnQgKglHZXRFbnYoKSB7cmV0dXJuIG1fcEVudjsgfQorCXZvaWQJCQkJICAgIFByb2NKYXZhc2NyaXB0RnVuKCk7CisJRlhfQk9PTAkJCQkJUHJvY09wZW5BY3Rpb24oKTsKKwlDUERGX09DQ29udGV4dCoJCQlHZXRPQ0NvbnRleHQoKTsKK3ByaXZhdGU6CisJLy9DRlhfQXJyYXlUZW1wbGF0ZTxDUERGU0RLX1BhZ2VWaWV3Kj4gbV9wYWdlQXJyYXk7CisJQ0ZYX01hcFB0clRlbXBsYXRlPENQREZfUGFnZSosIENQREZTREtfUGFnZVZpZXcqPiBtX3BhZ2VNYXA7CisJQ1BERl9Eb2N1bWVudCoJCQltX3BEb2M7CisKKwlDUERGU0RLX0ludGVyRm9ybSoJCW1fcEludGVyRm9ybTsKKwlDUERGU0RLX0Fubm90KgkJCW1fcEZvY3VzQW5ub3Q7CisJQ1BERkRvY19FbnZpcm9ubWVudCAqCW1fcEVudjsKKwlDUERGX09DQ29udGV4dCAqCQltX3BPY2NvbnRlbnQ7CisJRlhfQk9PTAkJCQkJbV9iQ2hhbmdlTWFzazsKK307CisKK2NsYXNzIENQREZTREtfUGFnZVZpZXcKK3sKK3B1YmxpYzoKKwlDUERGU0RLX1BhZ2VWaWV3KENQREZTREtfRG9jdW1lbnQqIHBTREtEb2MsQ1BERl9QYWdlKiBwYWdlKTsKKwl+Q1BERlNES19QYWdlVmlldygpOworcHVibGljOgorCXZpcnR1YWwJdm9pZCBQYWdlVmlld19PbkRyYXcoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSxDUERGX1JlbmRlck9wdGlvbnMqIHBPcHRpb25zKSA7CitwdWJsaWM6CisJQ1BERl9Bbm5vdCoJCQkJCQlHZXRQREZBbm5vdEF0UG9pbnQoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKTsKKwlDUERGU0RLX0Fubm90KgkJCQkJR2V0RlhBbm5vdEF0UG9pbnQoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKTsKKwlDUERGX0Fubm90KgkJCQkJCUdldFBERldpZGdldEF0UG9pbnQoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKTsKKwlDUERGU0RLX0Fubm90KgkJCQkJR2V0RlhXaWRnZXRBdFBvaW50KEZYX0ZMT0FUIHBhZ2VYLCBGWF9GTE9BVCBwYWdlWSk7CisJQ1BERlNES19Bbm5vdCoJCQkJCUdldEZvY3VzQW5ub3QoKSA7CisJdm9pZAkJCQkJCQlTZXRGb2N1c0Fubm90KENQREZTREtfQW5ub3QqIHBTREtBbm5vdCxGWF9VSU5UIG5GbGFnID0gMCkge21fcFNES0RvYy0+U2V0Rm9jdXNBbm5vdChwU0RLQW5ub3QsIG5GbGFnKTt9CisJRlhfQk9PTAkJCQkJCQlLaWxsRm9jdXNBbm5vdChGWF9VSU5UIG5GbGFnID0gMCkge3JldHVybiBtX3BTREtEb2MtPktpbGxGb2N1c0Fubm90KG5GbGFnKTt9CisJRlhfQk9PTAkJCQkJCQlBbm5vdF9IYXNBcHBlYXJhbmNlKENQREZfQW5ub3QqIHBBbm5vdCk7CisKKwlDUERGU0RLX0Fubm90KgkJCQkJQWRkQW5ub3QoQ1BERl9EaWN0aW9uYXJ5ICogcERpY3QpOworCUNQREZTREtfQW5ub3QqCQkJCQlBZGRBbm5vdChGWF9MUENTVFIgbHBTdWJUeXBlLENQREZfRGljdGlvbmFyeSAqIHBEaWN0KTsKKwlDUERGU0RLX0Fubm90KgkJCQkJQWRkQW5ub3QoQ1BERl9Bbm5vdCAqIHBQREZBbm5vdCk7CisJRlhfQk9PTAkJCQkJCQlEZWxldGVBbm5vdChDUERGU0RLX0Fubm90KiBwQW5ub3QpOwkJCQkJCQkKKwkKKwlpbnQJCQkJCQkJCUNvdW50QW5ub3RzKCk7CisJQ1BERlNES19Bbm5vdCoJCQkJCUdldEFubm90KGludCBuSW5kZXgpOworCUNQREZTREtfQW5ub3QqCQkJCSAgICBHZXRBbm5vdEJ5RGljdChDUERGX0RpY3Rpb25hcnkgKiBwRGljdCk7CisJQ1BERl9QYWdlKgkJCQkJCUdldFBERlBhZ2UoKXtyZXR1cm4gbV9wYWdlO30KKwlDUERGX0RvY3VtZW50KgkJCQkJR2V0UERGRG9jdW1lbnQoKTsKKwlDUERGU0RLX0RvY3VtZW50KgkJCQlHZXRTREtEb2N1bWVudCgpIHtyZXR1cm4gbV9wU0RLRG9jO30JCitwdWJsaWM6CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfVUlOVCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX1VJTlQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25DaGFyKGludCBuQ2hhciwgRlhfVUlOVCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbktleURvd24oaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25LZXlVcChpbnQgbktleUNvZGUsIGludCBuRmxhZyk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgaW50IG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTW91c2VXaGVlbChkb3VibGUgZGVsdGFYLCBkb3VibGUgZGVsdGFZLGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBpbnQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJSXNWYWxpZEFubm90KEZYX0xQVk9JRCBwKTsKK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQkJCUdldEN1cnJlbnRNYXRyaXgoQ1BERl9NYXRyaXgmIG1hdHJpeCkge21hdHJpeCA9IG1fY3VyTWF0cml4O30KKwl2aXJ0dWFsIHZvaWQJCQkJCVVwZGF0ZVJlY3RzKENGWF9SZWN0QXJyYXkmIHJlY3RzKTsKKwl2b2lkCQkJCQkJCVVwZGF0ZVZpZXcoQ1BERlNES19Bbm5vdCogcEFubm90KTsKKwlDRlhfUHRyQXJyYXkqCQkJCQlHZXRBbm5vdExpc3QoKXsgcmV0dXJuICZtX2Z4QW5ub3RBcnJheTsgfQorCitwdWJsaWM6CisJdmlydHVhbCBpbnQJCQkJCQlHZXRQYWdlSW5kZXgoKTsKKwl2b2lkCQkJCQkJCUxvYWRGWEFubm90cygpOworcHJpdmF0ZToKKwlDUERGX01hdHJpeCBtX2N1ck1hdHJpeDsKKworcHJpdmF0ZToKKwl2b2lkIFBhZ2VWaWV3X09uSGlnaGxpZ2h0Rm9ybUZpZWxkcyhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGU0RLX1dpZGdldCogcFdpZGdldCk7CisKK3ByaXZhdGU6CisJQ1BERl9QYWdlKiBtX3BhZ2U7CisJQ1BERl9Bbm5vdExpc3QqIG1fcEFubm90TGlzdDsKKworCS8vQ1BERlNES19Bbm5vdCogbV9wRm9jdXNBbm5vdDsKKwlDRlhfUHRyQXJyYXkgIG1fZnhBbm5vdEFycmF5OworCisJQ1BERlNES19Eb2N1bWVudCogbV9wU0RLRG9jOworcHJpdmF0ZToKKwlDUERGU0RLX1dpZGdldCogbV9DYXB0dXJlV2lkZ2V0OworCUZYX0JPT0wgbV9iRW50ZXJXaWRnZXQ7CisJRlhfQk9PTCBtX2JFeGl0V2lkZ2V0OworCUZYX0JPT0wgbV9iT25XaWRnZXQ7CitwdWJsaWM6CisJdm9pZCBTZXRWYWxpZChGWF9CT09MIGJWYWxpZCkge21fYlZhbGlkID0gYlZhbGlkO30KKwlGWF9CT09MIElzVmFsaWQoKSB7cmV0dXJuIG1fYlZhbGlkO30KK3ByaXZhdGU6CisJRlhfQk9PTCBtX2JWYWxpZDsKK307CisKKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4KK2NsYXNzIENHV19BcnJheVRlbXBsYXRlIDogcHVibGljIENGWF9BcnJheVRlbXBsYXRlPFRZUEU+Cit7CitwdWJsaWM6IAorCUNHV19BcnJheVRlbXBsYXRlKCl7fQorCXZpcnR1YWwgfkNHV19BcnJheVRlbXBsYXRlKCl7fQorCQorCXR5cGVkZWYgaW50ICgqTFBfQ09NUEFSRSkoVFlQRSBwMSwgVFlQRSBwMik7CisJCisJdm9pZCBTb3J0KExQX0NPTVBBUkUgcENvbXBhcmUsIEZYX0JPT0wgYkFzY2VudCA9IFRSVUUpCisJeworCQlpbnQgblNpemUgPSB0aGlzLT5HZXRTaXplKCk7CisJCVF1aWNrU29ydCgwLCBuU2l6ZSAtMSwgYkFzY2VudCwgcENvbXBhcmUpOworCX0KKwkKK3ByaXZhdGU6CisJdm9pZCBRdWlja1NvcnQoRlhfVUlOVCBuU3RhcnRQb3MsIEZYX1VJTlQgblN0b3BQb3MsIEZYX0JPT0wgYkFzY2VuZCwgTFBfQ09NUEFSRSBwQ29tcGFyZSkKKwl7CisJCWlmIChuU3RhcnRQb3MgPj0gblN0b3BQb3MpIHJldHVybjsKKwkJCisJCWlmICgoblN0b3BQb3MgLSBuU3RhcnRQb3MpID09IDEpCisJCXsKKwkJCVRZUEUgVmFsdWUxID0gdGhpcy0+R2V0QXQoblN0YXJ0UG9zKTsKKwkJCVRZUEUgVmFsdWUyID0gdGhpcy0+R2V0QXQoblN0b3BQb3MpOworCQkJCisJCQlpbnQgaUdyZWF0ZSA9ICgqcENvbXBhcmUpKFZhbHVlMSwgVmFsdWUyKTsKKwkJCWlmICgoYkFzY2VuZCAmJiBpR3JlYXRlID4gMCkgfHwgKCFiQXNjZW5kICYmIGlHcmVhdGUgPCAwKSkKKwkJCXsKKwkJCQl0aGlzLT5TZXRBdChuU3RhcnRQb3MsIFZhbHVlMik7CisJCQkJdGhpcy0+U2V0QXQoblN0b3BQb3MsIFZhbHVlMSk7CisJCQl9CisJCQlyZXR1cm47CisJCX0KKwkJCisJCUZYX1VJTlQgbSA9IChuU3RhcnRQb3MgKyBuU3RvcFBvcykgLyAyOworCQlGWF9VSU5UIGkgPSBuU3RhcnRQb3M7CisJCQorCQlUWVBFIFZhbHVlID0gdGhpcy0+R2V0QXQobSk7CisJCQorCQl3aGlsZSAoaSA8IG0pCisJCXsKKwkJCVRZUEUgdGVtcCA9IHRoaXMtPkdldEF0KGkpOworCQkJCisJCQlpbnQgaUdyZWF0ZSA9ICgqcENvbXBhcmUpKHRlbXAsIFZhbHVlKTsKKwkJCWlmICgoYkFzY2VuZCAmJiBpR3JlYXRlID4gMCkgfHwgKCFiQXNjZW5kICYmIGlHcmVhdGUgPCAwKSkKKwkJCXsKKwkJCQl0aGlzLT5JbnNlcnRBdChtKzEsIHRlbXApOworCQkJCXRoaXMtPlJlbW92ZUF0KGkpOworCQkJCW0tLTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlpKys7CisJCQl9CisJCX0KKwkJCisJCUZYX1VJTlQgaiA9IG5TdG9wUG9zOworCQkKKwkJd2hpbGUgKGogPiBtKQorCQl7CisJCQlUWVBFIHRlbXAgPSB0aGlzLT5HZXRBdChqKTsKKwkJCQorCQkJaW50IGlHcmVhdGUgPSAoKnBDb21wYXJlKSh0ZW1wLCBWYWx1ZSk7CisJCQlpZiAoKGJBc2NlbmQgJiYgaUdyZWF0ZSA8IDApIHx8ICghYkFzY2VuZCAmJiBpR3JlYXRlID4gMCkpCisJCQl7CisJCQkJdGhpcy0+UmVtb3ZlQXQoaik7CisJCQkJdGhpcy0+SW5zZXJ0QXQobSwgdGVtcCk7CisJCQkJbSsrOworCQkJfQorCQkJZWxzZQorCQkJeworCQkJCWotLTsKKwkJCX0KKwkJfQorCQkKKwkJaWYgKG5TdGFydFBvcyA8IG0pIFF1aWNrU29ydChuU3RhcnRQb3MsIG0sIGJBc2NlbmQsIHBDb21wYXJlKTsKKwkJaWYgKG5TdG9wUG9zID4gbSkgUXVpY2tTb3J0KG0sIG5TdG9wUG9zLCBiQXNjZW5kLCBwQ29tcGFyZSk7CisJfQorfTsKKworCisjZW5kaWYgLy9fRlBERlNES19NR1JfSAorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZnNka19yZW5kZXJjb250ZXh0LmggYi9mcGRmc2RrL2luY2x1ZGUvZnNka19yZW5kZXJjb250ZXh0LmgKaW5kZXggYzMzZGZkZC4uNTFjMzdiMyAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2ZzZGtfcmVuZGVyY29udGV4dC5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9mc2RrX3JlbmRlcmNvbnRleHQuaApAQCAtMSw0MSArMSw0MSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfUkVOREVSQ09OVEVOVF9IXw0KLSNkZWZpbmUgX1JFTkRFUkNPTlRFTlRfSF8NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZfcHJvZ3Jlc3NpdmUuaCINCi0NCi0vLyBFdmVyeXRoaW5nIGFib3V0IHJlbmRlcmluZyBpcyBwdXQgaGVyZTogZm9yIE9PTSByZWNvdmVyeQ0KLWNsYXNzIENSZW5kZXJDb250ZXh0IDogcHVibGljIENGWF9PYmplY3QNCi17DQotcHVibGljOg0KLQlDUmVuZGVyQ29udGV4dCgpIHsgQ2xlYXIoKTsgfQ0KLQl+Q1JlbmRlckNvbnRleHQoKTsNCi0JDQotCXZvaWQgQ2xlYXIoKTsNCi0JDQotCUNGWF9SZW5kZXJEZXZpY2UqCQltX3BEZXZpY2U7DQotCUNQREZfUmVuZGVyQ29udGV4dCoJCW1fcENvbnRleHQ7DQotCUNQREZfUHJvZ3Jlc3NpdmVSZW5kZXJlcioJbV9wUmVuZGVyZXI7DQotCUNQREZfQW5ub3RMaXN0KgkJCW1fcEFubm90czsNCi0JQ1BERl9SZW5kZXJPcHRpb25zKgkJbV9wT3B0aW9uczsNCi0jaWZkZWYgX1dJTjMyX1dDRQ0KLQlDRlhfRElCaXRtYXAqCW1fcEJpdG1hcDsNCi0JSEJJVE1BUAkJCW1faEJpdG1hcDsNCi0jZW5kaWYNCi19Ow0KLQ0KLWNsYXNzIElGU0RLX1BBVVNFX0FkYXB0ZXIgOiBwdWJsaWMgSUZYX1BhdXNlDQotew0KLXB1YmxpYzoNCi0JSUZTREtfUEFVU0VfQWRhcHRlcihJRlNES19QQVVTRSogSVBhdXNlICk7DQotCUZYX0JPT0wgTmVlZFRvUGF1c2VOb3coKTsNCi0JDQotcHJpdmF0ZToNCi0JSUZTREtfUEFVU0UqIG1fSVBhdXNlOw0KLX07DQotI2VuZGlmDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfUkVOREVSQ09OVEVOVF9IXworI2RlZmluZSBfUkVOREVSQ09OVEVOVF9IXworI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZfcHJvZ3Jlc3NpdmUuaCIKKworLy8gRXZlcnl0aGluZyBhYm91dCByZW5kZXJpbmcgaXMgcHV0IGhlcmU6IGZvciBPT00gcmVjb3ZlcnkKK2NsYXNzIENSZW5kZXJDb250ZXh0IDogcHVibGljIENGWF9PYmplY3QKK3sKK3B1YmxpYzoKKwlDUmVuZGVyQ29udGV4dCgpIHsgQ2xlYXIoKTsgfQorCX5DUmVuZGVyQ29udGV4dCgpOworCQorCXZvaWQgQ2xlYXIoKTsKKwkKKwlDRlhfUmVuZGVyRGV2aWNlKgkJbV9wRGV2aWNlOworCUNQREZfUmVuZGVyQ29udGV4dCoJCW1fcENvbnRleHQ7CisJQ1BERl9Qcm9ncmVzc2l2ZVJlbmRlcmVyKgltX3BSZW5kZXJlcjsKKwlDUERGX0Fubm90TGlzdCoJCQltX3BBbm5vdHM7CisJQ1BERl9SZW5kZXJPcHRpb25zKgkJbV9wT3B0aW9uczsKKyNpZmRlZiBfV0lOMzJfV0NFCisJQ0ZYX0RJQml0bWFwKgltX3BCaXRtYXA7CisJSEJJVE1BUAkJCW1faEJpdG1hcDsKKyNlbmRpZgorfTsKKworY2xhc3MgSUZTREtfUEFVU0VfQWRhcHRlciA6IHB1YmxpYyBJRlhfUGF1c2UKK3sKK3B1YmxpYzoKKwlJRlNES19QQVVTRV9BZGFwdGVyKElGU0RLX1BBVVNFKiBJUGF1c2UgKTsKKwlGWF9CT09MIE5lZWRUb1BhdXNlTm93KCk7CisJCitwcml2YXRlOgorCUlGU0RLX1BBVVNFKiBtX0lQYXVzZTsKK307CisjZW5kaWYKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9meF9zeXN0ZW1oYW5kbGVyLmggYi9mcGRmc2RrL2luY2x1ZGUvZnhfc3lzdGVtaGFuZGxlci5oCmluZGV4IGM3NjAzNzcuLmI5YWM0MTMgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9meF9zeXN0ZW1oYW5kbGVyLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2Z4X3N5c3RlbWhhbmRsZXIuaApAQCAtMSw4NSArMSw4NSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfRlhfU1lTVEVNSEFORExFUl9IXw0KLSNkZWZpbmUgX0ZYX1NZU1RFTUhBTkRMRVJfSF8NCi0NCi10eXBlZGVmIEZYX0xQVk9JRAkJCQlGWF9IV05EOw0KLXR5cGVkZWYgRlhfTFBWT0lECQkJCUZYX0hNRU5VOw0KLXR5cGVkZWYgdm9pZAkJCQkJKCpUaW1lckNhbGxiYWNrKShGWF9JTlQzMiBpZEV2ZW50KTsNCi0NCi10eXBlZGVmIHN0cnVjdCBfRlhfU1lTVEVNVElNRSANCi17DQotICAgIEZYX1dPUkQgd1llYXI7DQotICAgIEZYX1dPUkQgd01vbnRoOw0KLSAgICBGWF9XT1JEIHdEYXlPZldlZWs7DQotICAgIEZYX1dPUkQgd0RheTsNCi0gICAgRlhfV09SRCB3SG91cjsNCi0gICAgRlhfV09SRCB3TWludXRlOw0KLSAgICBGWF9XT1JEIHdTZWNvbmQ7DQotICAgIEZYX1dPUkQgd01pbGxpc2Vjb25kczsNCi19RlhfU1lTVEVNVElNRTsNCi0NCi0vL2N1cnNvciBzdHlsZQ0KLSNkZWZpbmUgRlhDVF9BUlJPVwkJCQkwDQotI2RlZmluZSBGWENUX05FU1cJCQkJMQ0KLSNkZWZpbmUgRlhDVF9OV1NFCQkJCTINCi0jZGVmaW5lIEZYQ1RfVkJFQU0JCQkJMw0KLSNkZWZpbmUgRlhDVF9IQkVBTQkJCQk0DQotI2RlZmluZSBGWENUX0hBTkQJCQkJNQ0KLQ0KLWNsYXNzIElGWF9TeXN0ZW1IYW5kbGVyDQotew0KLXB1YmxpYzoNCi0JdmlydHVhbCB+SUZYX1N5c3RlbUhhbmRsZXIoKSB7fQ0KLQl2aXJ0dWFsIHZvaWQJCQkJSW52YWxpZGF0ZVJlY3QoRlhfSFdORCBoV25kLCBGWF9SRUNUIHJlY3QpID0gMDsNCi0gICAgdmlydHVhbCB2b2lkCQkJCU91dHB1dFNlbGVjdGVkUmVjdCh2b2lkKiBwRm9ybUZpbGxlciwgQ1BERl9SZWN0JnJlY3QpID0gMDsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCUlzU2VsZWN0aW9uSW1wbGVtZW50ZWQoKSA9IDA7DQotDQotCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCUdldENsaXBib2FyZFRleHQoRlhfSFdORCBoV25kKSA9IDA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlTZXRDbGlwYm9hcmRUZXh0KEZYX0hXTkQgaFduZCwgQ0ZYX1dpZGVTdHJpbmcgc3RyaW5nKSA9IDA7DQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJQ2xpZW50VG9TY3JlZW4oRlhfSFdORCBoV25kLCBGWF9JTlQzMiYgeCwgRlhfSU5UMzImIHkpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCVNjcmVlblRvQ2xpZW50KEZYX0hXTkQgaFduZCwgRlhfSU5UMzImIHgsIEZYX0lOVDMyJiB5KSA9IDA7DQotDQotCS8qY3Vyc29yIHN0eWxlDQotCUZYQ1RfQVJST1cJDQotCUZYQ1RfTkVTVwkJDQotCUZYQ1RfTldTRQkJDQotCUZYQ1RfVkJFQU0JCQ0KLQlGWENUX0hCRUFNCQkNCi0JRlhDVF9IQU5EDQotCSovDQotCXZpcnR1YWwgdm9pZAkJCQlTZXRDdXJzb3IoRlhfSU5UMzIgbkN1cnNvclR5cGUpID0gMDsNCi0NCi0JdmlydHVhbCBGWF9ITUVOVQkJCUNyZWF0ZVBvcHVwTWVudSgpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCUFwcGVuZE1lbnVJdGVtKEZYX0hNRU5VIGhNZW51LCBGWF9JTlQzMiBuSUROZXdJdGVtLCBDRlhfV2lkZVN0cmluZyBzdHJpbmcpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCUVuYWJsZU1lbnVJdGVtKEZYX0hNRU5VIGhNZW51LCBGWF9JTlQzMiBuSURJdGVtLCBGWF9CT09MIGJFbmFibGVkKSA9IDA7DQotCXZpcnR1YWwgRlhfSU5UMzIJCQlUcmFja1BvcHVwTWVudShGWF9ITUVOVSBoTWVudSwgRlhfSU5UMzIgeCwgRlhfSU5UMzIgeSwgRlhfSFdORCBoUGFyZW50KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlEZXN0cm95TWVudShGWF9ITUVOVSBoTWVudSkgPSAwOw0KLQ0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXROYXRpdmVUcnVlVHlwZUZvbnQoRlhfSU5UMzIgbkNoYXJzZXQpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCUZpbmROYXRpdmVUcnVlVHlwZUZvbnQoRlhfSU5UMzIgbkNoYXJzZXQsIENGWF9CeXRlU3RyaW5nIHNGb250RmFjZU5hbWUpID0gMDsNCi0JdmlydHVhbCBDUERGX0ZvbnQqCQkJQWRkTmF0aXZlVHJ1ZVR5cGVGb250VG9QREYoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcgc0ZvbnRGYWNlTmFtZSwgRlhfQllURSBuQ2hhcnNldCkgPSAwOw0KLQ0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJU2V0VGltZXIoRlhfSU5UMzIgdUVsYXBzZSwgVGltZXJDYWxsYmFjayBscFRpbWVyRnVuYykgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJS2lsbFRpbWVyKEZYX0lOVDMyIG5JRCkgPSAwOw0KLQ0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNTSElGVEtleURvd24oRlhfRFdPUkQgbkZsYWcpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCUlzQ1RSTEtleURvd24oRlhfRFdPUkQgbkZsYWcpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCUlzQUxUS2V5RG93bihGWF9EV09SRCBuRmxhZykgPSAwOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNJTlNFUlRLZXlEb3duKEZYX0RXT1JEIG5GbGFnKSA9IDA7DQotDQotCXZpcnR1YWwJRlhfU1lTVEVNVElNRQkJR2V0TG9jYWxUaW1lKCkgPSAwOw0KLQ0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJR2V0Q2hhclNldCgpID0gMDsJDQotCXZpcnR1YWwgdm9pZCAJCQkJU2V0Q2hhclNldChGWF9JTlQzMiBuQ2hhclNldCkgPSAwOw0KLX07DQotDQotI2VuZGlmIC8vX0ZYX1NZU1RFTUhBTkRMRVJfSF8NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9GWF9TWVNURU1IQU5ETEVSX0hfCisjZGVmaW5lIF9GWF9TWVNURU1IQU5ETEVSX0hfCisKK3R5cGVkZWYgRlhfTFBWT0lECQkJCUZYX0hXTkQ7Cit0eXBlZGVmIEZYX0xQVk9JRAkJCQlGWF9ITUVOVTsKK3R5cGVkZWYgdm9pZAkJCQkJKCpUaW1lckNhbGxiYWNrKShGWF9JTlQzMiBpZEV2ZW50KTsKKwordHlwZWRlZiBzdHJ1Y3QgX0ZYX1NZU1RFTVRJTUUgCit7CisgICAgRlhfV09SRCB3WWVhcjsKKyAgICBGWF9XT1JEIHdNb250aDsKKyAgICBGWF9XT1JEIHdEYXlPZldlZWs7CisgICAgRlhfV09SRCB3RGF5OworICAgIEZYX1dPUkQgd0hvdXI7CisgICAgRlhfV09SRCB3TWludXRlOworICAgIEZYX1dPUkQgd1NlY29uZDsKKyAgICBGWF9XT1JEIHdNaWxsaXNlY29uZHM7Cit9RlhfU1lTVEVNVElNRTsKKworLy9jdXJzb3Igc3R5bGUKKyNkZWZpbmUgRlhDVF9BUlJPVwkJCQkwCisjZGVmaW5lIEZYQ1RfTkVTVwkJCQkxCisjZGVmaW5lIEZYQ1RfTldTRQkJCQkyCisjZGVmaW5lIEZYQ1RfVkJFQU0JCQkJMworI2RlZmluZSBGWENUX0hCRUFNCQkJCTQKKyNkZWZpbmUgRlhDVF9IQU5ECQkJCTUKKworY2xhc3MgSUZYX1N5c3RlbUhhbmRsZXIKK3sKK3B1YmxpYzoKKwl2aXJ0dWFsIH5JRlhfU3lzdGVtSGFuZGxlcigpIHt9CisJdmlydHVhbCB2b2lkCQkJCUludmFsaWRhdGVSZWN0KEZYX0hXTkQgaFduZCwgRlhfUkVDVCByZWN0KSA9IDA7CisgICAgdmlydHVhbCB2b2lkCQkJCU91dHB1dFNlbGVjdGVkUmVjdCh2b2lkKiBwRm9ybUZpbGxlciwgQ1BERl9SZWN0JnJlY3QpID0gMDsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlJc1NlbGVjdGlvbkltcGxlbWVudGVkKCkgPSAwOworCisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJR2V0Q2xpcGJvYXJkVGV4dChGWF9IV05EIGhXbmQpID0gMDsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJU2V0Q2xpcGJvYXJkVGV4dChGWF9IV05EIGhXbmQsIENGWF9XaWRlU3RyaW5nIHN0cmluZykgPSAwOworCQorCXZpcnR1YWwgdm9pZAkJCQlDbGllbnRUb1NjcmVlbihGWF9IV05EIGhXbmQsIEZYX0lOVDMyJiB4LCBGWF9JTlQzMiYgeSkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlTY3JlZW5Ub0NsaWVudChGWF9IV05EIGhXbmQsIEZYX0lOVDMyJiB4LCBGWF9JTlQzMiYgeSkgPSAwOworCisJLypjdXJzb3Igc3R5bGUKKwlGWENUX0FSUk9XCQorCUZYQ1RfTkVTVwkJCisJRlhDVF9OV1NFCQkKKwlGWENUX1ZCRUFNCQkKKwlGWENUX0hCRUFNCQkKKwlGWENUX0hBTkQKKwkqLworCXZpcnR1YWwgdm9pZAkJCQlTZXRDdXJzb3IoRlhfSU5UMzIgbkN1cnNvclR5cGUpID0gMDsKKworCXZpcnR1YWwgRlhfSE1FTlUJCQlDcmVhdGVQb3B1cE1lbnUoKSA9IDA7CisJdmlydHVhbCBGWF9CT09MCQkJCUFwcGVuZE1lbnVJdGVtKEZYX0hNRU5VIGhNZW51LCBGWF9JTlQzMiBuSUROZXdJdGVtLCBDRlhfV2lkZVN0cmluZyBzdHJpbmcpID0gMDsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJRW5hYmxlTWVudUl0ZW0oRlhfSE1FTlUgaE1lbnUsIEZYX0lOVDMyIG5JREl0ZW0sIEZYX0JPT0wgYkVuYWJsZWQpID0gMDsKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJVHJhY2tQb3B1cE1lbnUoRlhfSE1FTlUgaE1lbnUsIEZYX0lOVDMyIHgsIEZYX0lOVDMyIHksIEZYX0hXTkQgaFBhcmVudCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlEZXN0cm95TWVudShGWF9ITUVOVSBoTWVudSkgPSAwOworCisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0TmF0aXZlVHJ1ZVR5cGVGb250KEZYX0lOVDMyIG5DaGFyc2V0KSA9IDA7CisJdmlydHVhbCBGWF9CT09MCQkJCUZpbmROYXRpdmVUcnVlVHlwZUZvbnQoRlhfSU5UMzIgbkNoYXJzZXQsIENGWF9CeXRlU3RyaW5nIHNGb250RmFjZU5hbWUpID0gMDsKKwl2aXJ0dWFsIENQREZfRm9udCoJCQlBZGROYXRpdmVUcnVlVHlwZUZvbnRUb1BERihDUERGX0RvY3VtZW50KiBwRG9jLCBDRlhfQnl0ZVN0cmluZyBzRm9udEZhY2VOYW1lLCBGWF9CWVRFIG5DaGFyc2V0KSA9IDA7CisKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJU2V0VGltZXIoRlhfSU5UMzIgdUVsYXBzZSwgVGltZXJDYWxsYmFjayBscFRpbWVyRnVuYykgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlLaWxsVGltZXIoRlhfSU5UMzIgbklEKSA9IDA7CisKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlJc1NISUZUS2V5RG93bihGWF9EV09SRCBuRmxhZykgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0NUUkxLZXlEb3duKEZYX0RXT1JEIG5GbGFnKSA9IDA7CisJdmlydHVhbCBGWF9CT09MCQkJCUlzQUxUS2V5RG93bihGWF9EV09SRCBuRmxhZykgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0lOU0VSVEtleURvd24oRlhfRFdPUkQgbkZsYWcpID0gMDsKKworCXZpcnR1YWwJRlhfU1lTVEVNVElNRQkJR2V0TG9jYWxUaW1lKCkgPSAwOworCisJdmlydHVhbCBGWF9JTlQzMgkJCUdldENoYXJTZXQoKSA9IDA7CQorCXZpcnR1YWwgdm9pZCAJCQkJU2V0Q2hhclNldChGWF9JTlQzMiBuQ2hhclNldCkgPSAwOworfTsKKworI2VuZGlmIC8vX0ZYX1NZU1RFTUhBTkRMRVJfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2Z4ZWRpdC9meF9lZGl0LmggYi9mcGRmc2RrL2luY2x1ZGUvZnhlZGl0L2Z4X2VkaXQuaAppbmRleCAyYjczZTYxLi45NWI5MDk2IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnhlZGl0L2Z4X2VkaXQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnhlZGl0L2Z4X2VkaXQuaApAQCAtMSw0NzEgKzEsNDcxIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GWF9FRElUX0hfDQotI2RlZmluZSBfRlhfRURJVF9IXw0KLQ0KLSNkZWZpbmUgUFZUV09SRF9TVFlMRV9OT1JNQUwJCQkJMHgwMDAwTA0KLSNkZWZpbmUgUFZUV09SRF9TVFlMRV9ISUdITElHSFQJCQkJMHgwMDAxTA0KLSNkZWZpbmUgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUJCQkJMHgwMDAyTA0KLSNkZWZpbmUgUFZUV09SRF9TVFlMRV9DUk9TU09VVAkJCQkweDAwMDRMDQotI2RlZmluZSBQVlRXT1JEX1NUWUxFX1NRVUlHR0xZCQkJCTB4MDAwOEwNCi0jZGVmaW5lIFBWVFdPUkRfU1RZTEVfRFVBTENST1NTT1VUCQkJMHgwMDEwTA0KLSNkZWZpbmUgUFZUV09SRF9TVFlMRV9CT0xECQkJCQkweDAwMjBMDQotI2RlZmluZSBQVlRXT1JEX1NUWUxFX0lUQUxJQwkJCQkweDAwNDBMDQotDQotI2RlZmluZSBGWF9FRElUX0lTTEFUSU5XT1JEKHUpCSh1ID09IDB4MkQgfHwgKHUgPD0gMHgwMDVBICYmIHUgPj0gMHgwMDQxKSB8fCAodSA8PSAweDAwN0EgJiYgdSA+PSAweDAwNjEpIHx8ICh1IDw9IDB4MDJBRiAmJiB1ID49IDB4MDBDMCkpDQotDQotI2lmZGVmIEZYX1JFQURFUl9ETEwNCi0JI2lmZGVmIEZYRVRfRVhQT1JUDQotCQkjZGVmaW5lIEZYRVRfQ0xBU1MgX19kZWNsc3BlYyhkbGxleHBvcnQpDQotCSNlbHNlDQotCQkjZGVmaW5lIEZYRVRfQ0xBU1MNCi0JI2VuZGlmDQotI2Vsc2UNCi0JI2RlZmluZSBGWEVUX0NMQVNTDQotI2VuZGlmDQotDQotI2lmbmRlZiBERUZBVUxUX0NIQVJTRVQNCi0jZGVmaW5lIERFRkFVTFRfQ0hBUlNFVCAgICAgICAgIDENCi0jZW5kaWYgDQotDQotY2xhc3MgSUZYX0VkaXRfRm9udE1hcDsNCi1jbGFzcyBJRlhfRWRpdF9Ob3RpZnk7DQotY2xhc3MgSUZYX0VkaXRfSXRlcmF0b3I7DQotY2xhc3MgSUZYX0VkaXRfVW5kb0l0ZW07DQotY2xhc3MgSUZYX0VkaXQ7DQotY2xhc3MgSUZYX0xpc3RfTm90aWZ5Ow0KLWNsYXNzIElGWF9MaXN0Ow0KLWNsYXNzIElGWF9TeXN0ZW1IYW5kbGVyOw0KLQ0KLWNsYXNzIElGWF9FZGl0X0ZvbnRNYXANCi17DQotcHVibGljOg0KLQkvL21hcCBhIGZvbnRpbmRleCB0byBwZGYgZm9udC4NCi0JdmlydHVhbCBDUERGX0ZvbnQgKgkJCQkJCUdldFBERkZvbnQoRlhfSU5UMzIgbkZvbnRJbmRleCkgPSAwOw0KLQkvL2dldCB0aGUgYWxpYXMgb2YgYSBwZGYgZm9udC4NCi0JdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0UERGRm9udEFsaWFzKEZYX0lOVDMyIG5Gb250SW5kZXgpID0gMDsNCi0JLy9nZXQgdGhlIGluZGV4IG9mIGEgZm9udCB0aGF0IGNhbiBzaG93IGEgd29yZC4NCi0JdmlydHVhbCBGWF9JTlQzMgkJCQkJCUdldFdvcmRGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LCBGWF9JTlQzMiBuRm9udEluZGV4KSA9IDA7DQotCS8vZ2V0IHRoZSBjaGFyY29kZSBvZiB3b3JkIGZyb20gdW5pY29kZQ0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJQ2hhckNvZGVGcm9tVW5pY29kZShGWF9JTlQzMiBuRm9udEluZGV4LCBGWF9XT1JEIHdvcmQpID0gMDsNCi0JLy9nZXQgdGhlIGNoYXJzZXQgb2YgdW5pY29kZQ0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJQ2hhclNldEZyb21Vbmljb2RlKEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgbk9sZENoYXJzZXQpID0gMDsNCi19Ow0KLQ0KLWNsYXNzIElGWF9FZGl0X05vdGlmeQ0KLXsNCi0JLy90aGlzIGNsYXNzIGlzIGltcGxlbWVudGVkIGJ5IHVzZXINCi1wdWJsaWM6DQotCS8vc2V0IHRoZSBob3Jpem9udGFsIHNjcm9sbGJhciBpbmZvcm1hdGlvbi4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCUlPblNldFNjcm9sbEluZm9YKEZYX0ZMT0FUIGZQbGF0ZU1pbiwgRlhfRkxPQVQgZlBsYXRlTWF4LCANCi0JCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIA0KLQkJCQkJCQkJCQkJCUZYX0ZMT0FUIGZTbWFsbFN0ZXAsIEZYX0ZMT0FUIGZCaWdTdGVwKSA9IDA7DQotCS8vc2V0IHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXIgaW5mb3JtYXRpb24uDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxJbmZvWShGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgDQotCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkNvbnRlbnRNaW4sIEZYX0ZMT0FUIGZDb250ZW50TWF4LCANCi0JCQkJCQkJCQkJCQlGWF9GTE9BVCBmU21hbGxTdGVwLCBGWF9GTE9BVCBmQmlnU3RlcCkgPSAwOw0KLQkvL3NldCB0aGUgcG9zaXRpb24gb2YgaG9yaXpvbnRhbCBzY3JvbGxiYXIuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxQb3NYKEZYX0ZMT0FUIGZ4KSA9IDA7DQotCS8vc2V0IHRoZSBwb3NpdGlvbiBvZiB2ZXJ0aWNhbCBzY3JvbGxiYXIuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KSA9IDA7DQotCS8vc2V0IHRoZSBjYXJldCBpbmZvcm1hdGlvbi4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCUlPblNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsY29uc3QgQ1BERl9Qb2ludCAmIHB0SGVhZCxjb25zdCBDUERGX1BvaW50ICYgcHRGb290LCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UpID0gMDsNCi0JLy9pZiB0aGUgY2FyZXQgcG9zaXRpb24gaXMgY2hhbmdlZCAsc2VuZCB0aGUgaW5mb3JtYXRpb24gb2YgY3VycmVudCBwb3N0aW9uIHRvIHVzZXIuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25DYXJldENoYW5nZShjb25zdCBDUFZUX1NlY1Byb3BzICYgc2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgd29yZFByb3BzKSA9IDA7DQotCS8vaWYgdGhlIHRleHQgYXJlYSBpcyBjaGFuZ2VkLCBzZW5kIHRoZSBpbmZvcm1hdGlvbiB0byB1c2VyLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJSU9uQ29udGVudENoYW5nZShjb25zdCBDUERGX1JlY3QmIHJjQ29udGVudCkgPSAwOw0KLQkvL0ludmFsaWRhdGUgdGhlIHJlY3RhbmdsZSByZWxhdGl2ZSB0byB0aGUgYm91bmRpbmcgYm94IG9mIGVkaXQuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25JbnZhbGlkYXRlUmVjdChDUERGX1JlY3QgKiBwUmVjdCkgPSAwOw0KLX07DQotDQotY2xhc3MgSUZYX0VkaXRfT3ByTm90aWZ5DQotew0KLQkvL3RoaXMgY2xhc3MgaXMgaW1wbGVtZW50ZWQgYnkgdXNlcg0KLXB1YmxpYzoNCi0JLy9PcHJUeXBlOiAwDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkluc2VydFdvcmQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpID0gMDsNCi0JLy9PcHJUeXBlOiAxDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkluc2VydFJldHVybihjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkgPSAwOw0KLQkvL09wclR5cGU6IDINCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uQmFja1NwYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKSA9IDA7DQotCS8vT3ByVHlwZTogMw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25EZWxldGUoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpID0gMDsNCi0JLy9PcHJUeXBlOiA0DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkNsZWFyKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKSA9IDA7DQotCS8vT3ByVHlwZTogNQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25JbnNlcnRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKSA9IDA7DQotCS8vT3ByVHlwZTogNg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25TZXRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKSA9IDA7DQotCS8vDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkFkZFVuZG8oSUZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSkgPSAwOw0KLX07DQotDQotY2xhc3MgSUZYX0VkaXRfSXRlcmF0b3INCi17DQotcHVibGljOg0KLQl2aXJ0dWFsIH5JRlhfRWRpdF9JdGVyYXRvcigpICB7fQ0KLXB1YmxpYzoNCi0JLy9tb3ZlIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBuZXh0IHdvcmQuDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlOZXh0V29yZCgpID0gMDsNCi0JLy9tb3ZlIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBuZXh0IGxpbmUuDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlOZXh0TGluZSgpID0gMDsNCi0JLy9tb3ZlIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBuZXh0IHNlY3Rpb24uIA0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJTmV4dFNlY3Rpb24oKSA9IDA7DQotDQotCS8vbW92ZSB0aGUgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgcHJldmlvdXMgd29yZC4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCVByZXZXb3JkKCkgPSAwOw0KLQkvL21vdmUgdGhlIGN1cnJlbnQgcG9zaXRpb24gdG8gdGhlIHByZXZpb3VzIGxpbmUuDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlQcmV2TGluZSgpID0gMDsNCi0JLy9tb3ZlIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBwcmV2aW91cyBzZWN0aW9uLiANCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCVByZXZTZWN0aW9uKCkgPSAwOw0KLQ0KLQkvL2dldCB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIGN1cnJlbnQgd29yZC4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCUdldFdvcmQoQ1BWVF9Xb3JkICYgd29yZCkgY29uc3QgPSAwOw0KLQkvL2dldCB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIGN1cnJlbnQgbGluZS4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCUdldExpbmUoQ1BWVF9MaW5lICYgbGluZSkgY29uc3QgPSAwOw0KLQkvL2dldCB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIGN1cnJlbnQgc2VjdGlvbi4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCUdldFNlY3Rpb24oQ1BWVF9TZWN0aW9uICYgc2VjdGlvbikgY29uc3QgPSAwOw0KLQkvL3NldCB0aGUgY3VycmVudCBwb3NpdGlvbi4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNldEF0KEZYX0lOVDMyIG5Xb3JkSW5kZXgpID0gMDsNCi0JLy9zZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRBdChjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSA9IDA7DQotCS8vZ2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uLg0KLQl2aXJ0dWFsIGNvbnN0IENQVlRfV29yZFBsYWNlICYJCQlHZXRBdCgpIGNvbnN0ID0gMDsNCi0NCi0JLy9nZXQgdGhlIGVkaXQgd2hpY2ggdGhpcyBpdGVyYXRvciBiZWxvbmdzIHRvDQotCXZpcnR1YWwgSUZYX0VkaXQqCQkJCQkJR2V0RWRpdCgpIGNvbnN0ID0gMDsNCi19Ow0KLQ0KLWNsYXNzIElGWF9FZGl0X1VuZG9JdGVtDQotew0KLXB1YmxpYzoNCi0JdmlydHVhbCB2b2lkCQkJCQkJCVVuZG8oKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlSZWRvKCkgPSAwOw0KLQl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQkJCQlHZXRVbmRvVGl0bGUoKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlSZWxlYXNlKCkgPSAwOw0KLX07DQotDQotY2xhc3MgRlhFVF9DTEFTUyBJRlhfRWRpdA0KLXsNCi1wdWJsaWM6DQotCXN0YXRpYyBJRlhfRWRpdCoJCQkJCQlOZXdFZGl0KCk7DQotCXN0YXRpYwl2b2lkCQkJCQkJCURlbEVkaXQoSUZYX0VkaXQqIHBFZGl0KTsNCi0NCi1wdWJsaWM6DQotCS8vc2V0IGEgSUZYX0VkaXRfRm9udE1hcCBwb2ludGVyIGltcGxlbWVudGVkIGJ5IHVzZXIuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRGb250TWFwKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwKSA9IDA7DQotCS8vaWYgdXNlciBkb24ndCBsaWtlIHRvIHVzZSBGb250TWFwLCBpbXBsZW1lbnQgVlRQcm92aWRlciBhbmQgc2V0IGl0IGRpcmVjdGx5Lg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0VlRQcm92aWRlcihJUERGX1ZhcmlhYmxlVGV4dF9Qcm92aWRlciogcFByb3ZpZGVyKSA9IDA7DQotCS8vc2V0IGEgSUZYX0VkaXRfTm90aWZ5IHBvaW50ZXIgaW1wbGVtZW50ZWQgYnkgdXNlci4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNldE5vdGlmeShJRlhfRWRpdF9Ob3RpZnkgKiBwTm90aWZ5KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRPcHJOb3RpZnkoSUZYX0VkaXRfT3ByTm90aWZ5KiBwT3ByTm90aWZ5KSA9IDA7DQotCS8vZ2V0IGEgcG9pbnRlciBhbGxvY2F0ZWQgYnkgQ1BERl9FZGl0LCBieSB0aGlzIHBvaW50ZXIsIHVzZXIgY2FuIGl0ZXJhdGUgdGhlIGNvbnRlbnRzIG9mIGVkaXQsIGJ1dCBkb24ndCBuZWVkIHRvIHJlbGVhc2UuDQotCXZpcnR1YWwgSUZYX0VkaXRfSXRlcmF0b3IqCQkJCUdldEl0ZXJhdG9yKCkgPSAwOw0KLQkvL2dldCBhIFZUIHBvaW50ZXIgcmVsYXRpdmUgdG8gdGhpcyBlZGl0Lg0KLQl2aXJ0dWFsIElQREZfVmFyaWFibGVUZXh0KgkJCQlHZXRWYXJpYWJsZVRleHQoKSA9IDA7DQotCS8vZ2V0IHRoZSBJRlhfRWRpdF9Gb250TWFwIHBvaW50ZXIgc2V0IGJ5IHVzZXIuDQotCXZpcnR1YWwgSUZYX0VkaXRfRm9udE1hcCoJCQkJR2V0Rm9udE1hcCgpID0gMDsNCi0NCi0JLy9pbml0aWFsaXplIHRoZSBlZGl0Lg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJSW5pdGlhbGl6ZSgpID0gMDsNCi0NCi0JLy9zZXQgdGhlIGJvdW5kaW5nIGJveCBvZiB0aGUgdGV4dCBhcmVhLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0UGxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOw0KLQkvL3NldCB0aGUgc2Nyb2xsIG9yaWdpbg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0U2Nyb2xsUG9zKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgPSAwOw0KLQ0KLQkvL3NldCB0aGUgaG9yaXpvbnRhbCB0ZXh0IGFsaWdubWVudCBpbiB0ZXh0IGJveCwgbkZvcm1hdCAoMDpsZWZ0IDE6bWlkZGxlIDI6cmlnaHQpLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0QWxpZ25tZW50SChGWF9JTlQzMiBuRm9ybWF0ID0gMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vc2V0IHRoZSB2ZXJ0aWNhbCB0ZXh0IGFsaWdubWVudCBpbiB0ZXh0IGJveCwgbkZvcm1hdCAoMDp0b3AgMTpjZW50ZXIgMjpib3R0b20pLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0QWxpZ25tZW50VihGWF9JTlQzMiBuRm9ybWF0ID0gMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vaWYgdGhlIHRleHQgaXMgc2hvd24gaW4gc2VjcmV0ICwgc2V0IGEgY2hhcmFjdGVyIGZvciBzdWJzdGl0dXRlLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0UGFzc3dvcmRDaGFyKEZYX1dPUkQgd1N1YldvcmQgPSAnKicsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOw0KLQkvL3NldCB0aGUgbWF4aW1hbCBjb3VudCBvZiB3b3JkcyBvZiB0aGUgdGV4dC4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNldExpbWl0Q2hhcihGWF9JTlQzMiBuTGltaXRDaGFyID0gMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vaWYgc2V0IHRoZSBjb3VudCBvZiBjaGFyQXJyYXkgLCB0aGVuIGFsbCB3b3JkcyBpcyBzaG93biBpbiBlcXVhbCBzcGFjZS4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNldENoYXJBcnJheShGWF9JTlQzMiBuQ2hhckFycmF5ID0gMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vc2V0IHRoZSBzcGFjZSBvZiB0d28gY2hhcmFjdGVycy4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNldENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlID0gMC4wZiwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vc2V0IHRoZSBob3Jpem9udGFsIHNjYWxlIG9mIGFsbCBjaGFyYWN0ZXJzLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0SG9yelNjYWxlKEZYX0lOVDMyIG5Ib3J6U2NhbGUgPSAxMDAsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOw0KLQkvL3NldCB0aGUgbGVhZGluZyBvZiBhbGwgbGluZXMNCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNldExpbmVMZWFkaW5nKEZYX0ZMT0FUIGZMaW5lTGVhZGluZywgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vaWYgc2V0LCBDUkxGIGlzIGFsbG93ZWQuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRNdWx0aUxpbmUoRlhfQk9PTCBiTXVsdGlMaW5lID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vaWYgc2V0LCBhbGwgd29yZHMgYXV0byBmaXQgdGhlIHdpZHRoIG9mIHRoZSBib3VuZGluZyBib3guCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0QXV0b1JldHVybihGWF9CT09MIGJBdXRvID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vaWYgc2V0LCBhIGZvbnQgc2l6ZSBpcyBjYWxjdWxhdGVkIHRvIGZ1bGwgZml0IHRoZSBib3VuZGluZyBib3guDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRBdXRvRm9udFNpemUoRlhfQk9PTCBiQXV0byA9IFRSVUUsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOw0KLQkvL2lzIHNldCwgdGhlIHRleHQgaXMgYWxsb3dlZCB0byBzY3JvbGwuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRBdXRvU2Nyb2xsKEZYX0JPT0wgYkF1dG8gPSBUUlVFLCBGWF9CT09MIGJQYWludCA9IFRSVUUpID0gMDsNCi0JLy9zZXQgdGhlIGZvbnQgc2l6ZSBvZiBhbGwgd29yZHMuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOw0KLQkvL3RoZSB0ZXh0IGlzIGFsbG93ZWQgdG8gYXV0by1zY3JvbGwsIGFsbG93IHRoZSB0ZXh0IG92ZXJmbG93Pw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0VGV4dE92ZXJmbG93KEZYX0JPT0wgYkFsbG93ZWQgPSBGQUxTRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotDQotCS8vcXVlcnkgaWYgdGhlIGVkaXQgaXMgcmljaGVkaXQuDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJc1JpY2hUZXh0KCkgY29uc3QgPSAwOw0KLQkvL3NldCB0aGUgZWRpdCBpcyByaWNoZWRpdC4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNldFJpY2hUZXh0KEZYX0JPT0wgYlJpY2hUZXh0ID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7DQotCS8vc2V0IHRoZSBmb250c2l6ZSBvZiBzZWxlY3RlZCB0ZXh0Lg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSkgPSAwOwkNCi0JLy9zZXQgdGhlIGZvbnRpbmRleCBvZiBzZWxlY3RlZCB0ZXh0LCB1c2VyIGNhbiBjaGFuZ2UgdGhlIGZvbnQgb2Ygc2VsZWN0ZWQgdGV4dC4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCVNldFJpY2hGb250SW5kZXgoRlhfSU5UMzIgbkZvbnRJbmRleCkgPSAwOw0KLQkvL3NldCB0aGUgdGV4dGNvbG9yIG9mIHNlbGVjdGVkIHRleHQuDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dENvbG9yKEZYX0NPTE9SUkVGIGR3Q29sb3IpID0gMDsNCi0JLy9zZXQgdGhlIHRleHQgc2NyaXB0IHR5cGUgb2Ygc2VsZWN0ZWQgdGV4dC4gKDA6bm9ybWFsIDE6c3VwZXJzY3JpcHQgMjpzdWJzY3JpcHQpDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dFNjcmlwdChGWF9JTlQzMiBuU2NyaXB0VHlwZSkgPSAwOwkNCi0JLy9zZXQgdGhlIGJvbGQgZm9udCBzdHlsZSBvZiBzZWxlY3RlZCB0ZXh0Lg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaFRleHRCb2xkKEZYX0JPT0wgYkJvbGQgPSBUUlVFKSA9IDA7DQotCS8vc2V0IHRoZSBpdGFsaWMgZm9udCBzdHlsZSBvZiBzZWxlY3RlZCB0ZXh0Lg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaFRleHRJdGFsaWMoRlhfQk9PTCBiSXRhbGljID0gVFJVRSkgPSAwOw0KLQkvL3NldCB0aGUgdW5kZXJsaW5lIHN0eWxlIG9mIHNlbGVjdGVkIHRleHQuDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dFVuZGVybGluZShGWF9CT09MIGJVbmRlcmxpbmUgPSBUUlVFKSA9IDA7DQotCS8vc2V0IHRoZSBjcm9zc291dCBzdHlsZSBvZiBzZWxlY3RlZCB0ZXh0Lg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaFRleHRDcm9zc291dChGWF9CT09MIGJDcm9zc291dCA9IFRSVUUpID0gMDsNCi0JLy9zZXQgdGhlIGNoYXJzcGFjZSBvZiBzZWxlY3RlZCB0ZXh0LCBpbiB1c2VyIGNvb3JkaW5hdGUuDQotCXZpcnR1YWwJRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlKSA9IDA7DQotCS8vc2V0IHRoZSBob3Jpem9udGFsIHNjYWxlIG9mIHNlbGVjdGVkIHRleHQsIGRlZmF1bHQgdmFsdWUgaXMgMTAwLg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaFRleHRIb3J6U2NhbGUoRlhfSU5UMzIgbkhvcnpTY2FsZSA9IDEwMCkgPSAwOw0KLQkvL3NldCB0aGUgbGVhZGluZyBvZiBzZWxlY3RlZCBzZWN0aW9uLCBpbiB1c2VyIGNvb3JkaW5hdGUuDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dExpbmVMZWFkaW5nKEZYX0ZMT0FUIGZMaW5lTGVhZGluZykgPSAwOw0KLQkvL3NldCB0aGUgaW5kZW50IG9mIHNlbGVjdGVkIHNlY3Rpb24sIGluIHVzZXIgY29vcmRpbmF0ZS4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCVNldFJpY2hUZXh0TGluZUluZGVudChGWF9GTE9BVCBmTGluZUluZGVudCkgPSAwOw0KLQkvL3NldCB0aGUgYWxpZ25tZW50IG9mIHNlbGVjdGVkIHNlY3Rpb24sIG5BbGlnbm1lbnQoMDpsZWZ0IDE6bWlkZGxlIDI6cmlnaHQpDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dEFsaWdubWVudChGWF9JTlQzMiBuQWxpZ25tZW50KSA9IDA7DQotDQotCS8vc2V0IHRoZSBzZWxlY3RlZCByYW5nZSBvZiB0ZXh0Lg0KLQkvL2lmIG5TdGFydENoYXIgPT0gMCBhbmQgbkVuZENoYXIgPT0gLTEsIHNlbGVjdCBhbGwgdGhlIHRleHQuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRTZWwoRlhfSU5UMzIgblN0YXJ0Q2hhcixGWF9JTlQzMiBuRW5kQ2hhcikgPSAwOw0KLQkvL2dldCB0aGUgc2VsZWN0ZWQgcmFuZ2Ugb2YgdGV4dC4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCUdldFNlbChGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIpIGNvbnN0ID0gMDsNCi0JLy9zZWxlY3QgYWxsIHRoZSB0ZXh0Lg0KLQl2aXJ0dWFsCXZvaWQJCQkJCQkJU2VsZWN0QWxsKCkgPSAwOw0KLQkvL3NldCB0ZXh0IGlzIG5vdCBzZWxlY3RlZC4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNlbGVjdE5vbmUoKSA9IDA7CQkNCi0JLy9nZXQgdGhlIGNhcmV0IHBvc2l0aW9uLg0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJR2V0Q2FyZXQoKSBjb25zdCA9IDA7DQotCXZpcnR1YWwgQ1BWVF9Xb3JkUGxhY2UJCQkJCUdldENhcmV0V29yZFBsYWNlKCkgY29uc3QgPSAwOw0KLQkvL2dldCB0aGUgc3RyaW5nIG9mIHNlbGVjdGVkIHRleHQuDQotCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFNlbFRleHQoKSBjb25zdCA9IDA7DQotCS8vZ2V0IHRoZSB0ZXh0IGNvbmVudA0KLQl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQkJCQlHZXRUZXh0KCkgY29uc3QgPSAwOw0KLQkvL3F1ZXJ5IGlmIGFueSB0ZXh0IGlzIHNlbGVjdGVkLg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJSXNTZWxlY3RlZCgpIGNvbnN0ID0gMDsJDQotCS8vZ2V0IHRoZSBzY3JvbGwgb3JpZ2luDQotCXZpcnR1YWwgQ1BERl9Qb2ludAkJCQkJCUdldFNjcm9sbFBvcygpIGNvbnN0ID0gMDsNCi0JLy9nZXQgdGhlIGJvdW5kaW5nIGJveCBvZiB0aGUgdGV4dCBhcmVhLg0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCQkJCUdldFBsYXRlUmVjdCgpIGNvbnN0ID0gMDsNCi0JLy9nZXQgdGhlIGZhY3QgYXJlYSBvZiB0aGUgdGV4dC4NCi0JdmlydHVhbCBDUERGX1JlY3QJCQkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0ID0gMDsNCi0JLy9nZXQgdGhlIHZpc2libGUgd29yZCByYW5nZQ0KLQl2aXJ0dWFsIENQVlRfV29yZFJhbmdlCQkJCQlHZXRWaXNpYmxlV29yZFJhbmdlKCkgY29uc3QgPSAwOw0KLQkvL2dldCB0aGUgd2hvbGUgd29yZCByYW5nZQ0KLQl2aXJ0dWFsIENQVlRfV29yZFJhbmdlCQkJCQlHZXRXaG9sZVdvcmRSYW5nZSgpIGNvbnN0ID0gMDsNCi0JLy9nZXQgdGhlIHdvcmQgcmFuZ2Ugb2Ygc2VsZWN0IHRleHQNCi0JdmlydHVhbCBDUFZUX1dvcmRSYW5nZQkJCQkJR2V0U2VsZWN0V29yZFJhbmdlKCkgY29uc3QgPSAwOw0KLQ0KLQkvL3NlbmQgdGhlIG1vdXNlZG93biBtZXNzYWdlIHRvIGVkaXQgZm9yIHJlc3BvbnNlLg0KLQkvL2lmIFNoaWZ0IGtleSBpcyBob2xkLCBiU2hpZnQgaXMgVFJVRSwgaXMgQ3RybCBrZXkgaXMgaG9sZCwgYkN0cmwgaXMgVFJVRS4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uTW91c2VEb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7DQotCS8vc2VuZCB0aGUgbW91c2Vtb3ZlIG1lc3NhZ2UgdG8gZWRpdCB3aGVuIG1vdXNlIGRvd24gaXMgVFJVRS4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7DQotCS8vc2VuZCB0aGUgVVAga2V5IG1lc3NhZ2UgdG8gZWRpdC4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uVktfVVAoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOw0KLQkvL3NlbmQgdGhlIERPV04ga2V5IG1lc3NhZ2UgdG8gZWRpdC4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uVktfRE9XTihGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7DQotCS8vc2VuZCB0aGUgTEVGVCBrZXkgbWVzc2FnZSB0byBlZGl0Lg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19MRUZUKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsNCi0JLy9zZW5kIHRoZSBSSUdIVCBrZXkgbWVzc2FnZSB0byBlZGl0Lg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19SSUdIVChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7DQotCS8vc2VuZCB0aGUgSE9NRSBrZXkgbWVzc2FnZSB0byBlZGl0Lg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19IT01FKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsNCi0JLy9zZW5kIHRoZSBFTkQga2V5IG1lc3NhZ2UgdG8gZWRpdC4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uVktfRU5EKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsNCi0NCi0JLy9wdXQgdGV4dCBpbnRvIGVkaXQuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgdGV4dCxGWF9JTlQzMiBjaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VULA0KLQkJCQkJCQkJCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzID0gTlVMTCxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMgPSBOVUxMKSA9IDA7CQ0KLQkvL2luc2VydCBhIHdvcmQgaW50byB0aGUgZWRpdC4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCUluc2VydFdvcmQoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VULCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMgPSBOVUxMKSA9IDA7DQotCS8vaW5zZXJ0IGEgcmV0dXJuIGludG8gdGhlIGVkaXQuDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJbnNlcnRSZXR1cm4oY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyA9IE5VTEwsY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzID0gTlVMTCkgPSAwOwkNCi0JLy9pbnNlcnQgdGV4dCBpbnRvIHRoZSBlZGl0Lg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJSW5zZXJ0VGV4dChGWF9MUENXU1RSIHRleHQsIEZYX0lOVDMyIGNoYXJzZXQgPSBERUZBVUxUX0NIQVJTRVQsDQotCQkJCQkJCQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMgPSBOVUxMLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyA9IE5VTEwpID0gMDsNCi0JLy9kbyBiYWNrc3BhY2Ugb3BlcmF0aW9uLg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJQmFja3NwYWNlKCkgPSAwOw0KLQkvL2RvIGRlbGV0ZSBvcGVyYXRpb24uDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlEZWxldGUoKSA9IDA7CQ0KLQkvL2RlbGV0ZSB0aGUgc2VsZWN0ZWQgdGV4dC4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCUNsZWFyKCkgPSAwOw0KLQ0KLQkvL2RvIFJlZG8gb3BlcmF0aW9uLg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJUmVkbygpID0gMDsNCi0JLy9kbyBVbmRvIG9wZXJhdGlvbi4NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCVVuZG8oKSA9IDA7DQotCS8vbW92ZSBjYXJldA0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0Q2FyZXQoRlhfSU5UMzIgblBvcykgPSAwOw0KLQ0KLQkvL2FycmFuZ2UgYWxsIHdvcmRzIG92ZXIgYWdhaW4NCi0JdmlydHVhbCB2b2lkCQkJCQkJCVBhaW50KCkgPSAwOw0KLQkNCi0JLy9hbGxvdyB0byByZWZyZXNoIHNjcmVlbj8NCi0JdmlydHVhbCB2b2lkCQkJCQkJCUVuYWJsZVJlZnJlc2goRlhfQk9PTCBiUmVmcmVzaCkgPSAwOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJUmVmcmVzaFdvcmRSYW5nZShjb25zdCBDUFZUX1dvcmRSYW5nZSYgd3IpID0gMDsNCi0NCi0JLy9hbGxvdyB1bmRvL3JlZG8/DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlFbmFibGVVbmRvKEZYX0JPT0wgYlVuZG8pID0gMDsNCi0NCi0JLy9hbGxvdyBub3RpZnk/DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlFbmFibGVOb3RpZnkoRlhfQk9PTCBiTm90aWZ5KSA9IDA7DQotDQotCS8vYWxsb3cgb3ByIG5vdGlmeT8NCi0JdmlydHVhbCB2b2lkCQkJCQkJCUVuYWJsZU9wck5vdGlmeShGWF9CT09MIGJOb3RpZnkpID0gMDsNCi0NCi0JLy9tYXAgd29yZCBwbGFjZSB0byB3b3JkIGluZGV4Lg0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJV29yZFBsYWNlVG9Xb3JkSW5kZXgoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QgPSAwOw0KLQkvL21hcCB3b3JkIGluZGV4IHRvIHdvcmQgcGxhY2UuDQotCXZpcnR1YWwgQ1BWVF9Xb3JkUGxhY2UJCQkJCVdvcmRJbmRleFRvV29yZFBsYWNlKEZYX0lOVDMyIGluZGV4KSBjb25zdCA9IDA7DQotDQotCS8vZ2V0IHRoZSBiZWdpbm5pbmcgcG9zaXRpb24gb2YgYSBsaW5lDQotCXZpcnR1YWwgQ1BWVF9Xb3JkUGxhY2UJCQkJCUdldExpbmVCZWdpblBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0ID0gMDsNCi0NCi0JLy9nZXQgdGhlIGVuZGluZyBwb3NpdGlvbiBvZiBhIGxpbmUNCi0JdmlydHVhbCBDUFZUX1dvcmRQbGFjZQkJCQkJR2V0TGluZUVuZFBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0ID0gMDsNCi0NCi0JLy9nZXQgdGhlIGJlZ2lubmluZyBwb3NpdGlvbiBvZiBhIHNlY3Rpb24NCi0JdmlydHVhbCBDUFZUX1dvcmRQbGFjZQkJCQkJR2V0U2VjdGlvbkJlZ2luUGxhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QgPSAwOw0KLQ0KLQkvL2dldCB0aGUgZW5kaW5nIHBvc2l0aW9uIG9mIGEgc2VjdGlvbg0KLQl2aXJ0dWFsIENQVlRfV29yZFBsYWNlCQkJCQlHZXRTZWN0aW9uRW5kUGxhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QgPSAwOw0KLQ0KLQkvL3NlYXJjaCBhIHdvcmRwbGFjZSBmb3JtIHBvaW50DQotCXZpcnR1YWwgQ1BWVF9Xb3JkUGxhY2UJCQkJCVNlYXJjaFdvcmRQbGFjZShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3QgPSAwOw0KLQ0KLQkvL2dldCB0aGUgZm9udCBzaXplIG9mIG5vbl9yaWNoIHRleHQgb3IgZGVmYXVsdCBmb250IHNpemUgb2YgcmljaHRleHQuDQotCXZpcnR1YWwgRlhfRkxPQVQJCQkJCQlHZXRGb250U2l6ZSgpIGNvbnN0ID0gMDsNCi0JLy9nZXQgdGhlIG1hc2sgY2hhcmFjdGVyLg0KLQl2aXJ0dWFsIEZYX1dPUkQJCQkJCQkJR2V0UGFzc3dvcmRDaGFyKCkgY29uc3QgPSAwOw0KLQkvL2dldCB0aGUgY291bnQgb2YgY2hhckFycmF5DQotCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRDaGFyQXJyYXkoKSBjb25zdCA9IDA7DQotCS8vZ2V0IHRoZSBob3Jpem9udGFsIHNjYWxlIG9mIGFsbCBjaGFyYWN0ZXJzDQotCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRIb3J6U2NhbGUoKSBjb25zdCA9IDA7DQotCS8vZ2V0IHRoZSBzcGFjZSBvZiB0d28gY2hhcmFjdGVycw0KLQl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQkJR2V0Q2hhclNwYWNlKCkgY29uc3QgPSAwOw0KLQkvL2dldCB0aGUgbGF0aW4gd29yZHMgb2Ygc3BlY2lmaWVkIHJhbmdlDQotCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFJhbmdlVGV4dChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKSBjb25zdCA9IDA7DQotCS8vaXMgdGhlIHRleHQgZnVsbCBpbiBib3VuZGluZyBib3gNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCUlzVGV4dEZ1bGwoKSBjb25zdCA9IDA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlDYW5VbmRvKCkgY29uc3QgPSAwOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJQ2FuUmVkbygpIGNvbnN0ID0gMDsNCi0JLy9pZiB0aGUgY29udGVudCBpcyBjaGFuZ2VkIGFmdGVyIHNldHRleHQ/DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJc01vZGlmaWVkKCkgY29uc3QgPSAwOw0KLQkvL2dldCB0aGUgdG90YWwgd29yZHMgaW4gZWRpdA0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJR2V0VG90YWxXb3JkcygpIGNvbnN0ID0gMDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQkJCUFkZFVuZG9JdGVtKElGWF9FZGl0X1VuZG9JdGVtKiBwVW5kb0l0ZW0pID0gMDsNCi0NCi1wdWJsaWM6DQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0RWRpdEFwcGVhcmFuY2VTdHJlYW0oSUZYX0VkaXQqIHBFZGl0LCBjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQsIA0KLQkJCQkJCQkJCQkJCQljb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlID0gTlVMTCwgDQotCQkJCQkJCQkJCQkJCUZYX0JPT0wgYkNvbnRpbnVvdXMgPSBUUlVFLCBGWF9XT1JEIFN1YldvcmQgPSAwKTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRTZWxlY3RBcHBlYXJhbmNlU3RyZWFtKElGWF9FZGl0KiBwRWRpdCwgY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlID0gTlVMTCk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlEcmF3RWRpdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLCBJRlhfRWRpdCogcEVkaXQsIEZYX0NPTE9SUkVGIGNyVGV4dEZpbGwsIEZYX0NPTE9SUkVGIGNyVGV4dFN0cm9rZSwNCi0JCQkJCQkJCQkJCQkJY29uc3QgQ1BERl9SZWN0JiByY0NsaXAsIGNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlLCBJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIsIHZvaWQqIHBGRkxEYXRhKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCURyYXdVbmRlcmxpbmUoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwgSUZYX0VkaXQqIHBFZGl0LCBGWF9DT0xPUlJFRiBjb2xvciwNCi0JCQkJCQkJCQkJCQkJY29uc3QgQ1BERl9SZWN0JiByY0NsaXAsIGNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCURyYXdSaWNoRWRpdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLCBJRlhfRWRpdCogcEVkaXQsICANCi0JCQkJCQkJCQkJCQkJY29uc3QgQ1BERl9SZWN0JiByY0NsaXAsIGNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdlbmVyYXRlUGFnZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmplY3RzLCBJRlhfRWRpdCogcEVkaXQsDQotCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlLCBGWF9DT0xPUlJFRiBjclRleHQsIENGWF9BcnJheVRlbXBsYXRlPENQREZfVGV4dE9iamVjdCo+JiBPYmpBcnJheSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZW5lcmF0ZVJpY2hQYWdlT2JqZWN0cyhDUERGX1BhZ2VPYmplY3RzKiBwUGFnZU9iamVjdHMsIElGWF9FZGl0KiBwRWRpdCwNCi0JCQkJCQkJCQkJCQkJY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UsIENGWF9BcnJheVRlbXBsYXRlPENQREZfVGV4dE9iamVjdCo+JiBPYmpBcnJheSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZW5lcmF0ZVVuZGVybGluZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmplY3RzLCBJRlhfRWRpdCogcEVkaXQsDQotCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlLCBGWF9DT0xPUlJFRiBjb2xvcik7DQotfTsNCi0NCi1jbGFzcyBJRlhfTGlzdF9Ob3RpZnkNCi17DQotCS8vdGhpcyBjbGFzcyBpcyBpbXBsZW1lbnRlZCBieSB1c2VyDQotcHVibGljOg0KLQkvL3NldCB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXIgaW5mb3JtYXRpb24uDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxJbmZvWChGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgDQotCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkNvbnRlbnRNaW4sIEZYX0ZMT0FUIGZDb250ZW50TWF4LCANCi0JCQkJCQkJCQkJCQlGWF9GTE9BVCBmU21hbGxTdGVwLCBGWF9GTE9BVCBmQmlnU3RlcCkgPSAwOw0KLQkvL3NldCB0aGUgdmVydGljYWwgc2Nyb2xsYmFyIGluZm9ybWF0aW9uLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJSU9uU2V0U2Nyb2xsSW5mb1koRlhfRkxPQVQgZlBsYXRlTWluLCBGWF9GTE9BVCBmUGxhdGVNYXgsIA0KLQkJCQkJCQkJCQkJCUZYX0ZMT0FUIGZDb250ZW50TWluLCBGWF9GTE9BVCBmQ29udGVudE1heCwgDQotCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApID0gMDsNCi0JLy9zZXQgdGhlIHBvc2l0aW9uIG9mIGhvcml6b250YWwgc2Nyb2xsYmFyLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJSU9uU2V0U2Nyb2xsUG9zWChGWF9GTE9BVCBmeCkgPSAwOw0KLQkvL3NldCB0aGUgcG9zaXRpb24gb2YgdmVydGljYWwgc2Nyb2xsYmFyLg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJSU9uU2V0U2Nyb2xsUG9zWShGWF9GTE9BVCBmeSkgPSAwOw0KLQkvL0ludmFsaWRhdGUgdGhlIHJlY3RhbmdsZSByZWxhdGl2ZSB0byB0aGUgYm91bmRpbmcgYm94IG9mIGVkaXQuDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25JbnZhbGlkYXRlUmVjdChDUERGX1JlY3QgKiBwUmVjdCkgPSAwOw0KLX07DQotDQotY2xhc3MgRlhFVF9DTEFTUyBJRlhfTGlzdA0KLXsNCi1wdWJsaWM6DQotCXN0YXRpYyBJRlhfTGlzdCoJCQkJCQlOZXdMaXN0KCk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlEZWxMaXN0KElGWF9MaXN0KiBwTGlzdCk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNldE5vdGlmeShJRlhfTGlzdF9Ob3RpZnkgKiBwTm90aWZ5KSA9IDA7DQotDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRQbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKSA9IDA7DQotDQotCXZpcnR1YWwgQ1BERl9SZWN0CQkJCQkJR2V0UGxhdGVSZWN0KCkgY29uc3QgPSAwOw0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCQkJCUdldENvbnRlbnRSZWN0KCkgY29uc3QgPSAwOw0KLQ0KLQl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQkJR2V0Rm9udFNpemUoKSBjb25zdCA9IDA7DQotCXZpcnR1YWwgSUZYX0VkaXQqCQkJCQkJR2V0SXRlbUVkaXQoRlhfSU5UMzIgbkluZGV4KSBjb25zdCA9IDA7DQotCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRDb3VudCgpIGNvbnN0ID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCUlzSXRlbVNlbGVjdGVkKEZYX0lOVDMyIG5JbmRleCkgY29uc3QgPSAwOw0KLQl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQkJR2V0Rmlyc3RIZWlnaHQoKSBjb25zdCA9IDA7DQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0TXVsdGlwbGVTZWwoRlhfQk9PTCBiTXVsdGlwbGUpID0gMDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJCUlzTXVsdGlwbGVTZWwoKSBjb25zdCA9IDA7CQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJSXNWYWxpZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdCA9IDA7DQotCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlGaW5kTmV4dChGWF9JTlQzMiBuSW5kZXgsRlhfV0NIQVIgbkNoYXIpIGNvbnN0ID0gMDsJDQotDQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRTY3JvbGxQb3MoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTY3JvbGxUb0xpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpID0gMDsNCi0JdmlydHVhbCBDUERGX1JlY3QJCQkJCQlHZXRJdGVtUmVjdChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0ID0gMDsNCi0JdmlydHVhbCBGWF9JTlQzMgkJCQkJCUdldENhcmV0KCkgY29uc3QgPSAwOw0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJR2V0U2VsZWN0KCkgY29uc3QgPSAwOwkNCi0JdmlydHVhbCBGWF9JTlQzMgkJCQkJCUdldFRvcEl0ZW0oKSBjb25zdCA9IDA7DQotCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRJdGVtSW5kZXgoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdCA9IDA7DQotCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRGaXJzdFNlbGVjdGVkKCkgY29uc3QgPSAwOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJQWRkU3RyaW5nKEZYX0xQQ1dTVFIgc3RyaW5nKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRUb3BJdGVtKEZYX0lOVDMyIG5JbmRleCkgPSAwOwkNCi0JdmlydHVhbCB2b2lkCQkJCQkJCVNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRDYXJldChGWF9JTlQzMiBuSXRlbUluZGV4KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlFbXB0eSgpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCUNhbmNlbCgpID0gMDsNCi0JdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJR2V0VGV4dCgpIGNvbnN0ID0gMDsNCi0NCi0NCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uTW91c2VEb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19VUChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlPblZLX0RPV04oRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19MRUZUKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uVktfUklHSFQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19IT01FKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uVktfRU5EKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uVksoRlhfSU5UMzIgbkl0ZW1JbmRleCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlPbkNoYXIoRlhfV09SRCBuQ2hhcixGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7DQotfTsNCi0NCi0jZW5kaWYgDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRlhfRURJVF9IXworI2RlZmluZSBfRlhfRURJVF9IXworCisjZGVmaW5lIFBWVFdPUkRfU1RZTEVfTk9STUFMCQkJCTB4MDAwMEwKKyNkZWZpbmUgUFZUV09SRF9TVFlMRV9ISUdITElHSFQJCQkJMHgwMDAxTAorI2RlZmluZSBQVlRXT1JEX1NUWUxFX1VOREVSTElORQkJCQkweDAwMDJMCisjZGVmaW5lIFBWVFdPUkRfU1RZTEVfQ1JPU1NPVVQJCQkJMHgwMDA0TAorI2RlZmluZSBQVlRXT1JEX1NUWUxFX1NRVUlHR0xZCQkJCTB4MDAwOEwKKyNkZWZpbmUgUFZUV09SRF9TVFlMRV9EVUFMQ1JPU1NPVVQJCQkweDAwMTBMCisjZGVmaW5lIFBWVFdPUkRfU1RZTEVfQk9MRAkJCQkJMHgwMDIwTAorI2RlZmluZSBQVlRXT1JEX1NUWUxFX0lUQUxJQwkJCQkweDAwNDBMCisKKyNkZWZpbmUgRlhfRURJVF9JU0xBVElOV09SRCh1KQkodSA9PSAweDJEIHx8ICh1IDw9IDB4MDA1QSAmJiB1ID49IDB4MDA0MSkgfHwgKHUgPD0gMHgwMDdBICYmIHUgPj0gMHgwMDYxKSB8fCAodSA8PSAweDAyQUYgJiYgdSA+PSAweDAwQzApKQorCisjaWZkZWYgRlhfUkVBREVSX0RMTAorCSNpZmRlZiBGWEVUX0VYUE9SVAorCQkjZGVmaW5lIEZYRVRfQ0xBU1MgX19kZWNsc3BlYyhkbGxleHBvcnQpCisJI2Vsc2UKKwkJI2RlZmluZSBGWEVUX0NMQVNTCisJI2VuZGlmCisjZWxzZQorCSNkZWZpbmUgRlhFVF9DTEFTUworI2VuZGlmCisKKyNpZm5kZWYgREVGQVVMVF9DSEFSU0VUCisjZGVmaW5lIERFRkFVTFRfQ0hBUlNFVCAgICAgICAgIDEKKyNlbmRpZiAKKworY2xhc3MgSUZYX0VkaXRfRm9udE1hcDsKK2NsYXNzIElGWF9FZGl0X05vdGlmeTsKK2NsYXNzIElGWF9FZGl0X0l0ZXJhdG9yOworY2xhc3MgSUZYX0VkaXRfVW5kb0l0ZW07CitjbGFzcyBJRlhfRWRpdDsKK2NsYXNzIElGWF9MaXN0X05vdGlmeTsKK2NsYXNzIElGWF9MaXN0OworY2xhc3MgSUZYX1N5c3RlbUhhbmRsZXI7CisKK2NsYXNzIElGWF9FZGl0X0ZvbnRNYXAKK3sKK3B1YmxpYzoKKwkvL21hcCBhIGZvbnRpbmRleCB0byBwZGYgZm9udC4KKwl2aXJ0dWFsIENQREZfRm9udCAqCQkJCQkJR2V0UERGRm9udChGWF9JTlQzMiBuRm9udEluZGV4KSA9IDA7CisJLy9nZXQgdGhlIGFsaWFzIG9mIGEgcGRmIGZvbnQuCisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0UERGRm9udEFsaWFzKEZYX0lOVDMyIG5Gb250SW5kZXgpID0gMDsKKwkvL2dldCB0aGUgaW5kZXggb2YgYSBmb250IHRoYXQgY2FuIHNob3cgYSB3b3JkLgorCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRXb3JkRm9udEluZGV4KEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgY2hhcnNldCwgRlhfSU5UMzIgbkZvbnRJbmRleCkgPSAwOworCS8vZ2V0IHRoZSBjaGFyY29kZSBvZiB3b3JkIGZyb20gdW5pY29kZQorCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlDaGFyQ29kZUZyb21Vbmljb2RlKEZYX0lOVDMyIG5Gb250SW5kZXgsIEZYX1dPUkQgd29yZCkgPSAwOworCS8vZ2V0IHRoZSBjaGFyc2V0IG9mIHVuaWNvZGUKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJQ2hhclNldEZyb21Vbmljb2RlKEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgbk9sZENoYXJzZXQpID0gMDsKK307CisKK2NsYXNzIElGWF9FZGl0X05vdGlmeQoreworCS8vdGhpcyBjbGFzcyBpcyBpbXBsZW1lbnRlZCBieSB1c2VyCitwdWJsaWM6CisJLy9zZXQgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIGluZm9ybWF0aW9uLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxJbmZvWChGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIAorCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApID0gMDsKKwkvL3NldCB0aGUgdmVydGljYWwgc2Nyb2xsYmFyIGluZm9ybWF0aW9uLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxJbmZvWShGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIAorCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApID0gMDsKKwkvL3NldCB0aGUgcG9zaXRpb24gb2YgaG9yaXpvbnRhbCBzY3JvbGxiYXIuCisJdmlydHVhbCB2b2lkCQkJCQkJCUlPblNldFNjcm9sbFBvc1goRlhfRkxPQVQgZngpID0gMDsKKwkvL3NldCB0aGUgcG9zaXRpb24gb2YgdmVydGljYWwgc2Nyb2xsYmFyLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KSA9IDA7CisJLy9zZXQgdGhlIGNhcmV0IGluZm9ybWF0aW9uLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRDYXJldChGWF9CT09MIGJWaXNpYmxlLGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsY29uc3QgQ1BERl9Qb2ludCAmIHB0Rm9vdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlKSA9IDA7CisJLy9pZiB0aGUgY2FyZXQgcG9zaXRpb24gaXMgY2hhbmdlZCAsc2VuZCB0aGUgaW5mb3JtYXRpb24gb2YgY3VycmVudCBwb3N0aW9uIHRvIHVzZXIuCisJdmlydHVhbCB2b2lkCQkJCQkJCUlPbkNhcmV0Q2hhbmdlKGNvbnN0IENQVlRfU2VjUHJvcHMgJiBzZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiB3b3JkUHJvcHMpID0gMDsKKwkvL2lmIHRoZSB0ZXh0IGFyZWEgaXMgY2hhbmdlZCwgc2VuZCB0aGUgaW5mb3JtYXRpb24gdG8gdXNlci4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJSU9uQ29udGVudENoYW5nZShjb25zdCBDUERGX1JlY3QmIHJjQ29udGVudCkgPSAwOworCS8vSW52YWxpZGF0ZSB0aGUgcmVjdGFuZ2xlIHJlbGF0aXZlIHRvIHRoZSBib3VuZGluZyBib3ggb2YgZWRpdC4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJSU9uSW52YWxpZGF0ZVJlY3QoQ1BERl9SZWN0ICogcFJlY3QpID0gMDsKK307CisKK2NsYXNzIElGWF9FZGl0X09wck5vdGlmeQoreworCS8vdGhpcyBjbGFzcyBpcyBpbXBsZW1lbnRlZCBieSB1c2VyCitwdWJsaWM6CisJLy9PcHJUeXBlOiAwCisJdmlydHVhbCB2b2lkCQkJCQkJCU9uSW5zZXJ0V29yZChjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkgPSAwOworCS8vT3ByVHlwZTogMQorCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkluc2VydFJldHVybihjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkgPSAwOworCS8vT3ByVHlwZTogMgorCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkJhY2tTcGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkgPSAwOworCS8vT3ByVHlwZTogMworCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkRlbGV0ZShjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkgPSAwOworCS8vT3ByVHlwZTogNAorCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkNsZWFyKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKSA9IDA7CisJLy9PcHJUeXBlOiA1CisJdmlydHVhbCB2b2lkCQkJCQkJCU9uSW5zZXJ0VGV4dChjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkgPSAwOworCS8vT3ByVHlwZTogNgorCXZpcnR1YWwgdm9pZAkJCQkJCQlPblNldFRleHQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpID0gMDsKKwkvLworCXZpcnR1YWwgdm9pZAkJCQkJCQlPbkFkZFVuZG8oSUZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSkgPSAwOworfTsKKworY2xhc3MgSUZYX0VkaXRfSXRlcmF0b3IKK3sKK3B1YmxpYzoKKwl2aXJ0dWFsIH5JRlhfRWRpdF9JdGVyYXRvcigpICB7fQorcHVibGljOgorCS8vbW92ZSB0aGUgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgbmV4dCB3b3JkLgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlOZXh0V29yZCgpID0gMDsKKwkvL21vdmUgdGhlIGN1cnJlbnQgcG9zaXRpb24gdG8gdGhlIG5leHQgbGluZS4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJTmV4dExpbmUoKSA9IDA7CisJLy9tb3ZlIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBuZXh0IHNlY3Rpb24uIAorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlOZXh0U2VjdGlvbigpID0gMDsKKworCS8vbW92ZSB0aGUgY3VycmVudCBwb3NpdGlvbiB0byB0aGUgcHJldmlvdXMgd29yZC4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJUHJldldvcmQoKSA9IDA7CisJLy9tb3ZlIHRoZSBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBwcmV2aW91cyBsaW5lLgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlQcmV2TGluZSgpID0gMDsKKwkvL21vdmUgdGhlIGN1cnJlbnQgcG9zaXRpb24gdG8gdGhlIHByZXZpb3VzIHNlY3Rpb24uIAorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlQcmV2U2VjdGlvbigpID0gMDsKKworCS8vZ2V0IHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUgY3VycmVudCB3b3JkLgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlHZXRXb3JkKENQVlRfV29yZCAmIHdvcmQpIGNvbnN0ID0gMDsKKwkvL2dldCB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIGN1cnJlbnQgbGluZS4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJR2V0TGluZShDUFZUX0xpbmUgJiBsaW5lKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIGluZm9ybWF0aW9uIG9mIHRoZSBjdXJyZW50IHNlY3Rpb24uCisJdmlydHVhbCBGWF9CT09MCQkJCQkJCUdldFNlY3Rpb24oQ1BWVF9TZWN0aW9uICYgc2VjdGlvbikgY29uc3QgPSAwOworCS8vc2V0IHRoZSBjdXJyZW50IHBvc2l0aW9uLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRBdChGWF9JTlQzMiBuV29yZEluZGV4KSA9IDA7CisJLy9zZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldEF0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpID0gMDsKKwkvL2dldCB0aGUgY3VycmVudCBwb3NpdGlvbi4KKwl2aXJ0dWFsIGNvbnN0IENQVlRfV29yZFBsYWNlICYJCQlHZXRBdCgpIGNvbnN0ID0gMDsKKworCS8vZ2V0IHRoZSBlZGl0IHdoaWNoIHRoaXMgaXRlcmF0b3IgYmVsb25ncyB0bworCXZpcnR1YWwgSUZYX0VkaXQqCQkJCQkJR2V0RWRpdCgpIGNvbnN0ID0gMDsKK307CisKK2NsYXNzIElGWF9FZGl0X1VuZG9JdGVtCit7CitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCQkJCVVuZG8oKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJCVJlZG8oKSA9IDA7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJR2V0VW5kb1RpdGxlKCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlSZWxlYXNlKCkgPSAwOworfTsKKworY2xhc3MgRlhFVF9DTEFTUyBJRlhfRWRpdAoreworcHVibGljOgorCXN0YXRpYyBJRlhfRWRpdCoJCQkJCQlOZXdFZGl0KCk7CisJc3RhdGljCXZvaWQJCQkJCQkJRGVsRWRpdChJRlhfRWRpdCogcEVkaXQpOworCitwdWJsaWM6CisJLy9zZXQgYSBJRlhfRWRpdF9Gb250TWFwIHBvaW50ZXIgaW1wbGVtZW50ZWQgYnkgdXNlci4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwKiBwRm9udE1hcCkgPSAwOworCS8vaWYgdXNlciBkb24ndCBsaWtlIHRvIHVzZSBGb250TWFwLCBpbXBsZW1lbnQgVlRQcm92aWRlciBhbmQgc2V0IGl0IGRpcmVjdGx5LgorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRWVFByb3ZpZGVyKElQREZfVmFyaWFibGVUZXh0X1Byb3ZpZGVyKiBwUHJvdmlkZXIpID0gMDsKKwkvL3NldCBhIElGWF9FZGl0X05vdGlmeSBwb2ludGVyIGltcGxlbWVudGVkIGJ5IHVzZXIuCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldE5vdGlmeShJRlhfRWRpdF9Ob3RpZnkgKiBwTm90aWZ5KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJCVNldE9wck5vdGlmeShJRlhfRWRpdF9PcHJOb3RpZnkqIHBPcHJOb3RpZnkpID0gMDsKKwkvL2dldCBhIHBvaW50ZXIgYWxsb2NhdGVkIGJ5IENQREZfRWRpdCwgYnkgdGhpcyBwb2ludGVyLCB1c2VyIGNhbiBpdGVyYXRlIHRoZSBjb250ZW50cyBvZiBlZGl0LCBidXQgZG9uJ3QgbmVlZCB0byByZWxlYXNlLgorCXZpcnR1YWwgSUZYX0VkaXRfSXRlcmF0b3IqCQkJCUdldEl0ZXJhdG9yKCkgPSAwOworCS8vZ2V0IGEgVlQgcG9pbnRlciByZWxhdGl2ZSB0byB0aGlzIGVkaXQuCisJdmlydHVhbCBJUERGX1ZhcmlhYmxlVGV4dCoJCQkJR2V0VmFyaWFibGVUZXh0KCkgPSAwOworCS8vZ2V0IHRoZSBJRlhfRWRpdF9Gb250TWFwIHBvaW50ZXIgc2V0IGJ5IHVzZXIuCisJdmlydHVhbCBJRlhfRWRpdF9Gb250TWFwKgkJCQlHZXRGb250TWFwKCkgPSAwOworCisJLy9pbml0aWFsaXplIHRoZSBlZGl0LgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJbml0aWFsaXplKCkgPSAwOworCisJLy9zZXQgdGhlIGJvdW5kaW5nIGJveCBvZiB0aGUgdGV4dCBhcmVhLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRQbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7CisJLy9zZXQgdGhlIHNjcm9sbCBvcmlnaW4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0U2Nyb2xsUG9zKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgPSAwOworCisJLy9zZXQgdGhlIGhvcml6b250YWwgdGV4dCBhbGlnbm1lbnQgaW4gdGV4dCBib3gsIG5Gb3JtYXQgKDA6bGVmdCAxOm1pZGRsZSAyOnJpZ2h0KS4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0QWxpZ25tZW50SChGWF9JTlQzMiBuRm9ybWF0ID0gMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7CisJLy9zZXQgdGhlIHZlcnRpY2FsIHRleHQgYWxpZ25tZW50IGluIHRleHQgYm94LCBuRm9ybWF0ICgwOnRvcCAxOmNlbnRlciAyOmJvdHRvbSkuCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldEFsaWdubWVudFYoRlhfSU5UMzIgbkZvcm1hdCA9IDAsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOworCS8vaWYgdGhlIHRleHQgaXMgc2hvd24gaW4gc2VjcmV0ICwgc2V0IGEgY2hhcmFjdGVyIGZvciBzdWJzdGl0dXRlLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRQYXNzd29yZENoYXIoRlhfV09SRCB3U3ViV29yZCA9ICcqJywgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7CisJLy9zZXQgdGhlIG1heGltYWwgY291bnQgb2Ygd29yZHMgb2YgdGhlIHRleHQuCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldExpbWl0Q2hhcihGWF9JTlQzMiBuTGltaXRDaGFyID0gMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7CisJLy9pZiBzZXQgdGhlIGNvdW50IG9mIGNoYXJBcnJheSAsIHRoZW4gYWxsIHdvcmRzIGlzIHNob3duIGluIGVxdWFsIHNwYWNlLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRDaGFyQXJyYXkoRlhfSU5UMzIgbkNoYXJBcnJheSA9IDAsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOworCS8vc2V0IHRoZSBzcGFjZSBvZiB0d28gY2hhcmFjdGVycy4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UgPSAwLjBmLCBGWF9CT09MIGJQYWludCA9IFRSVUUpID0gMDsKKwkvL3NldCB0aGUgaG9yaXpvbnRhbCBzY2FsZSBvZiBhbGwgY2hhcmFjdGVycy4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0SG9yelNjYWxlKEZYX0lOVDMyIG5Ib3J6U2NhbGUgPSAxMDAsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOworCS8vc2V0IHRoZSBsZWFkaW5nIG9mIGFsbCBsaW5lcworCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRMaW5lTGVhZGluZyhGWF9GTE9BVCBmTGluZUxlYWRpbmcsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOworCS8vaWYgc2V0LCBDUkxGIGlzIGFsbG93ZWQuCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldE11bHRpTGluZShGWF9CT09MIGJNdWx0aUxpbmUgPSBUUlVFLCBGWF9CT09MIGJQYWludCA9IFRSVUUpID0gMDsKKwkvL2lmIHNldCwgYWxsIHdvcmRzIGF1dG8gZml0IHRoZSB3aWR0aCBvZiB0aGUgYm91bmRpbmcgYm94LgkKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0QXV0b1JldHVybihGWF9CT09MIGJBdXRvID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKSA9IDA7CisJLy9pZiBzZXQsIGEgZm9udCBzaXplIGlzIGNhbGN1bGF0ZWQgdG8gZnVsbCBmaXQgdGhlIGJvdW5kaW5nIGJveC4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0QXV0b0ZvbnRTaXplKEZYX0JPT0wgYkF1dG8gPSBUUlVFLCBGWF9CT09MIGJQYWludCA9IFRSVUUpID0gMDsKKwkvL2lzIHNldCwgdGhlIHRleHQgaXMgYWxsb3dlZCB0byBzY3JvbGwuCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldEF1dG9TY3JvbGwoRlhfQk9PTCBiQXV0byA9IFRSVUUsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOworCS8vc2V0IHRoZSBmb250IHNpemUgb2YgYWxsIHdvcmRzLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOworCS8vdGhlIHRleHQgaXMgYWxsb3dlZCB0byBhdXRvLXNjcm9sbCwgYWxsb3cgdGhlIHRleHQgb3ZlcmZsb3c/CisJdmlydHVhbCB2b2lkCQkJCQkJCVNldFRleHRPdmVyZmxvdyhGWF9CT09MIGJBbGxvd2VkID0gRkFMU0UsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSkgPSAwOworCisJLy9xdWVyeSBpZiB0aGUgZWRpdCBpcyByaWNoZWRpdC4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJSXNSaWNoVGV4dCgpIGNvbnN0ID0gMDsKKwkvL3NldCB0aGUgZWRpdCBpcyByaWNoZWRpdC4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0UmljaFRleHQoRlhfQk9PTCBiUmljaFRleHQgPSBUUlVFLCBGWF9CT09MIGJQYWludCA9IFRSVUUpID0gMDsKKwkvL3NldCB0aGUgZm9udHNpemUgb2Ygc2VsZWN0ZWQgdGV4dC4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSkgPSAwOwkKKwkvL3NldCB0aGUgZm9udGluZGV4IG9mIHNlbGVjdGVkIHRleHQsIHVzZXIgY2FuIGNoYW5nZSB0aGUgZm9udCBvZiBzZWxlY3RlZCB0ZXh0LgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoRm9udEluZGV4KEZYX0lOVDMyIG5Gb250SW5kZXgpID0gMDsKKwkvL3NldCB0aGUgdGV4dGNvbG9yIG9mIHNlbGVjdGVkIHRleHQuCisJdmlydHVhbCBGWF9CT09MCQkJCQkJCVNldFJpY2hUZXh0Q29sb3IoRlhfQ09MT1JSRUYgZHdDb2xvcikgPSAwOworCS8vc2V0IHRoZSB0ZXh0IHNjcmlwdCB0eXBlIG9mIHNlbGVjdGVkIHRleHQuICgwOm5vcm1hbCAxOnN1cGVyc2NyaXB0IDI6c3Vic2NyaXB0KQorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dFNjcmlwdChGWF9JTlQzMiBuU2NyaXB0VHlwZSkgPSAwOwkKKwkvL3NldCB0aGUgYm9sZCBmb250IHN0eWxlIG9mIHNlbGVjdGVkIHRleHQuCisJdmlydHVhbCBGWF9CT09MCQkJCQkJCVNldFJpY2hUZXh0Qm9sZChGWF9CT09MIGJCb2xkID0gVFJVRSkgPSAwOworCS8vc2V0IHRoZSBpdGFsaWMgZm9udCBzdHlsZSBvZiBzZWxlY3RlZCB0ZXh0LgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dEl0YWxpYyhGWF9CT09MIGJJdGFsaWMgPSBUUlVFKSA9IDA7CisJLy9zZXQgdGhlIHVuZGVybGluZSBzdHlsZSBvZiBzZWxlY3RlZCB0ZXh0LgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dFVuZGVybGluZShGWF9CT09MIGJVbmRlcmxpbmUgPSBUUlVFKSA9IDA7CisJLy9zZXQgdGhlIGNyb3Nzb3V0IHN0eWxlIG9mIHNlbGVjdGVkIHRleHQuCisJdmlydHVhbCBGWF9CT09MCQkJCQkJCVNldFJpY2hUZXh0Q3Jvc3NvdXQoRlhfQk9PTCBiQ3Jvc3NvdXQgPSBUUlVFKSA9IDA7CisJLy9zZXQgdGhlIGNoYXJzcGFjZSBvZiBzZWxlY3RlZCB0ZXh0LCBpbiB1c2VyIGNvb3JkaW5hdGUuCisJdmlydHVhbAlGWF9CT09MCQkJCQkJCVNldFJpY2hUZXh0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UpID0gMDsKKwkvL3NldCB0aGUgaG9yaXpvbnRhbCBzY2FsZSBvZiBzZWxlY3RlZCB0ZXh0LCBkZWZhdWx0IHZhbHVlIGlzIDEwMC4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaFRleHRIb3J6U2NhbGUoRlhfSU5UMzIgbkhvcnpTY2FsZSA9IDEwMCkgPSAwOworCS8vc2V0IHRoZSBsZWFkaW5nIG9mIHNlbGVjdGVkIHNlY3Rpb24sIGluIHVzZXIgY29vcmRpbmF0ZS4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaFRleHRMaW5lTGVhZGluZyhGWF9GTE9BVCBmTGluZUxlYWRpbmcpID0gMDsKKwkvL3NldCB0aGUgaW5kZW50IG9mIHNlbGVjdGVkIHNlY3Rpb24sIGluIHVzZXIgY29vcmRpbmF0ZS4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJU2V0UmljaFRleHRMaW5lSW5kZW50KEZYX0ZMT0FUIGZMaW5lSW5kZW50KSA9IDA7CisJLy9zZXQgdGhlIGFsaWdubWVudCBvZiBzZWxlY3RlZCBzZWN0aW9uLCBuQWxpZ25tZW50KDA6bGVmdCAxOm1pZGRsZSAyOnJpZ2h0KQorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlTZXRSaWNoVGV4dEFsaWdubWVudChGWF9JTlQzMiBuQWxpZ25tZW50KSA9IDA7CisKKwkvL3NldCB0aGUgc2VsZWN0ZWQgcmFuZ2Ugb2YgdGV4dC4KKwkvL2lmIG5TdGFydENoYXIgPT0gMCBhbmQgbkVuZENoYXIgPT0gLTEsIHNlbGVjdCBhbGwgdGhlIHRleHQuCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldFNlbChGWF9JTlQzMiBuU3RhcnRDaGFyLEZYX0lOVDMyIG5FbmRDaGFyKSA9IDA7CisJLy9nZXQgdGhlIHNlbGVjdGVkIHJhbmdlIG9mIHRleHQuCisJdmlydHVhbCB2b2lkCQkJCQkJCUdldFNlbChGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIpIGNvbnN0ID0gMDsKKwkvL3NlbGVjdCBhbGwgdGhlIHRleHQuCisJdmlydHVhbAl2b2lkCQkJCQkJCVNlbGVjdEFsbCgpID0gMDsKKwkvL3NldCB0ZXh0IGlzIG5vdCBzZWxlY3RlZC4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2VsZWN0Tm9uZSgpID0gMDsJCQorCS8vZ2V0IHRoZSBjYXJldCBwb3NpdGlvbi4KKwl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJR2V0Q2FyZXQoKSBjb25zdCA9IDA7CisJdmlydHVhbCBDUFZUX1dvcmRQbGFjZQkJCQkJR2V0Q2FyZXRXb3JkUGxhY2UoKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIHN0cmluZyBvZiBzZWxlY3RlZCB0ZXh0LgorCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFNlbFRleHQoKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIHRleHQgY29uZW50CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJR2V0VGV4dCgpIGNvbnN0ID0gMDsKKwkvL3F1ZXJ5IGlmIGFueSB0ZXh0IGlzIHNlbGVjdGVkLgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJc1NlbGVjdGVkKCkgY29uc3QgPSAwOwkKKwkvL2dldCB0aGUgc2Nyb2xsIG9yaWdpbgorCXZpcnR1YWwgQ1BERl9Qb2ludAkJCQkJCUdldFNjcm9sbFBvcygpIGNvbnN0ID0gMDsKKwkvL2dldCB0aGUgYm91bmRpbmcgYm94IG9mIHRoZSB0ZXh0IGFyZWEuCisJdmlydHVhbCBDUERGX1JlY3QJCQkJCQlHZXRQbGF0ZVJlY3QoKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIGZhY3QgYXJlYSBvZiB0aGUgdGV4dC4KKwl2aXJ0dWFsIENQREZfUmVjdAkJCQkJCUdldENvbnRlbnRSZWN0KCkgY29uc3QgPSAwOworCS8vZ2V0IHRoZSB2aXNpYmxlIHdvcmQgcmFuZ2UKKwl2aXJ0dWFsIENQVlRfV29yZFJhbmdlCQkJCQlHZXRWaXNpYmxlV29yZFJhbmdlKCkgY29uc3QgPSAwOworCS8vZ2V0IHRoZSB3aG9sZSB3b3JkIHJhbmdlCisJdmlydHVhbCBDUFZUX1dvcmRSYW5nZQkJCQkJR2V0V2hvbGVXb3JkUmFuZ2UoKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIHdvcmQgcmFuZ2Ugb2Ygc2VsZWN0IHRleHQKKwl2aXJ0dWFsIENQVlRfV29yZFJhbmdlCQkJCQlHZXRTZWxlY3RXb3JkUmFuZ2UoKSBjb25zdCA9IDA7CisKKwkvL3NlbmQgdGhlIG1vdXNlZG93biBtZXNzYWdlIHRvIGVkaXQgZm9yIHJlc3BvbnNlLgorCS8vaWYgU2hpZnQga2V5IGlzIGhvbGQsIGJTaGlmdCBpcyBUUlVFLCBpcyBDdHJsIGtleSBpcyBob2xkLCBiQ3RybCBpcyBUUlVFLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlPbk1vdXNlRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCS8vc2VuZCB0aGUgbW91c2Vtb3ZlIG1lc3NhZ2UgdG8gZWRpdCB3aGVuIG1vdXNlIGRvd24gaXMgVFJVRS4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJT25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsKKwkvL3NlbmQgdGhlIFVQIGtleSBtZXNzYWdlIHRvIGVkaXQuCisJdmlydHVhbCB2b2lkCQkJCQkJCU9uVktfVVAoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCS8vc2VuZCB0aGUgRE9XTiBrZXkgbWVzc2FnZSB0byBlZGl0LgorCXZpcnR1YWwgdm9pZAkJCQkJCQlPblZLX0RPV04oRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCS8vc2VuZCB0aGUgTEVGVCBrZXkgbWVzc2FnZSB0byBlZGl0LgorCXZpcnR1YWwgdm9pZAkJCQkJCQlPblZLX0xFRlQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCS8vc2VuZCB0aGUgUklHSFQga2V5IG1lc3NhZ2UgdG8gZWRpdC4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19SSUdIVChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7CisJLy9zZW5kIHRoZSBIT01FIGtleSBtZXNzYWdlIHRvIGVkaXQuCisJdmlydHVhbCB2b2lkCQkJCQkJCU9uVktfSE9NRShGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7CisJLy9zZW5kIHRoZSBFTkQga2V5IG1lc3NhZ2UgdG8gZWRpdC4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19FTkQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCisJLy9wdXQgdGV4dCBpbnRvIGVkaXQuCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldFRleHQoRlhfTFBDV1NUUiB0ZXh0LEZYX0lOVDMyIGNoYXJzZXQgPSBERUZBVUxUX0NIQVJTRVQsCisJCQkJCQkJCQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyA9IE5VTEwsY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzID0gTlVMTCkgPSAwOwkKKwkvL2luc2VydCBhIHdvcmQgaW50byB0aGUgZWRpdC4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJSW5zZXJ0V29yZChGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIGNoYXJzZXQgPSBERUZBVUxUX0NIQVJTRVQsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyA9IE5VTEwpID0gMDsKKwkvL2luc2VydCBhIHJldHVybiBpbnRvIHRoZSBlZGl0LgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJbnNlcnRSZXR1cm4oY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyA9IE5VTEwsY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzID0gTlVMTCkgPSAwOwkKKwkvL2luc2VydCB0ZXh0IGludG8gdGhlIGVkaXQuCisJdmlydHVhbCBGWF9CT09MCQkJCQkJCUluc2VydFRleHQoRlhfTFBDV1NUUiB0ZXh0LCBGWF9JTlQzMiBjaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VULAorCQkJCQkJCQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMgPSBOVUxMLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyA9IE5VTEwpID0gMDsKKwkvL2RvIGJhY2tzcGFjZSBvcGVyYXRpb24uCisJdmlydHVhbCBGWF9CT09MCQkJCQkJCUJhY2tzcGFjZSgpID0gMDsKKwkvL2RvIGRlbGV0ZSBvcGVyYXRpb24uCisJdmlydHVhbCBGWF9CT09MCQkJCQkJCURlbGV0ZSgpID0gMDsJCisJLy9kZWxldGUgdGhlIHNlbGVjdGVkIHRleHQuCisJdmlydHVhbCBGWF9CT09MCQkJCQkJCUNsZWFyKCkgPSAwOworCisJLy9kbyBSZWRvIG9wZXJhdGlvbi4KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJUmVkbygpID0gMDsKKwkvL2RvIFVuZG8gb3BlcmF0aW9uLgorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlVbmRvKCkgPSAwOworCS8vbW92ZSBjYXJldAorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRDYXJldChGWF9JTlQzMiBuUG9zKSA9IDA7CisKKwkvL2FycmFuZ2UgYWxsIHdvcmRzIG92ZXIgYWdhaW4KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJUGFpbnQoKSA9IDA7CisJCisJLy9hbGxvdyB0byByZWZyZXNoIHNjcmVlbj8KKwl2aXJ0dWFsIHZvaWQJCQkJCQkJRW5hYmxlUmVmcmVzaChGWF9CT09MIGJSZWZyZXNoKSA9IDA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJUmVmcmVzaFdvcmRSYW5nZShjb25zdCBDUFZUX1dvcmRSYW5nZSYgd3IpID0gMDsKKworCS8vYWxsb3cgdW5kby9yZWRvPworCXZpcnR1YWwgdm9pZAkJCQkJCQlFbmFibGVVbmRvKEZYX0JPT0wgYlVuZG8pID0gMDsKKworCS8vYWxsb3cgbm90aWZ5PworCXZpcnR1YWwgdm9pZAkJCQkJCQlFbmFibGVOb3RpZnkoRlhfQk9PTCBiTm90aWZ5KSA9IDA7CisKKwkvL2FsbG93IG9wciBub3RpZnk/CisJdmlydHVhbCB2b2lkCQkJCQkJCUVuYWJsZU9wck5vdGlmeShGWF9CT09MIGJOb3RpZnkpID0gMDsKKworCS8vbWFwIHdvcmQgcGxhY2UgdG8gd29yZCBpbmRleC4KKwl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJV29yZFBsYWNlVG9Xb3JkSW5kZXgoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QgPSAwOworCS8vbWFwIHdvcmQgaW5kZXggdG8gd29yZCBwbGFjZS4KKwl2aXJ0dWFsIENQVlRfV29yZFBsYWNlCQkJCQlXb3JkSW5kZXhUb1dvcmRQbGFjZShGWF9JTlQzMiBpbmRleCkgY29uc3QgPSAwOworCisJLy9nZXQgdGhlIGJlZ2lubmluZyBwb3NpdGlvbiBvZiBhIGxpbmUKKwl2aXJ0dWFsIENQVlRfV29yZFBsYWNlCQkJCQlHZXRMaW5lQmVnaW5QbGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSBjb25zdCA9IDA7CisKKwkvL2dldCB0aGUgZW5kaW5nIHBvc2l0aW9uIG9mIGEgbGluZQorCXZpcnR1YWwgQ1BWVF9Xb3JkUGxhY2UJCQkJCUdldExpbmVFbmRQbGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSBjb25zdCA9IDA7CisKKwkvL2dldCB0aGUgYmVnaW5uaW5nIHBvc2l0aW9uIG9mIGEgc2VjdGlvbgorCXZpcnR1YWwgQ1BWVF9Xb3JkUGxhY2UJCQkJCUdldFNlY3Rpb25CZWdpblBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0ID0gMDsKKworCS8vZ2V0IHRoZSBlbmRpbmcgcG9zaXRpb24gb2YgYSBzZWN0aW9uCisJdmlydHVhbCBDUFZUX1dvcmRQbGFjZQkJCQkJR2V0U2VjdGlvbkVuZFBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0ID0gMDsKKworCS8vc2VhcmNoIGEgd29yZHBsYWNlIGZvcm0gcG9pbnQKKwl2aXJ0dWFsIENQVlRfV29yZFBsYWNlCQkJCQlTZWFyY2hXb3JkUGxhY2UoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0ID0gMDsKKworCS8vZ2V0IHRoZSBmb250IHNpemUgb2Ygbm9uX3JpY2ggdGV4dCBvciBkZWZhdWx0IGZvbnQgc2l6ZSBvZiByaWNodGV4dC4KKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQkJR2V0Rm9udFNpemUoKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIG1hc2sgY2hhcmFjdGVyLgorCXZpcnR1YWwgRlhfV09SRAkJCQkJCQlHZXRQYXNzd29yZENoYXIoKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIGNvdW50IG9mIGNoYXJBcnJheQorCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRDaGFyQXJyYXkoKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIGhvcml6b250YWwgc2NhbGUgb2YgYWxsIGNoYXJhY3RlcnMKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJR2V0SG9yelNjYWxlKCkgY29uc3QgPSAwOworCS8vZ2V0IHRoZSBzcGFjZSBvZiB0d28gY2hhcmFjdGVycworCXZpcnR1YWwgRlhfRkxPQVQJCQkJCQlHZXRDaGFyU3BhY2UoKSBjb25zdCA9IDA7CisJLy9nZXQgdGhlIGxhdGluIHdvcmRzIG9mIHNwZWNpZmllZCByYW5nZQorCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFJhbmdlVGV4dChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKSBjb25zdCA9IDA7CisJLy9pcyB0aGUgdGV4dCBmdWxsIGluIGJvdW5kaW5nIGJveAorCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJc1RleHRGdWxsKCkgY29uc3QgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlDYW5VbmRvKCkgY29uc3QgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlDYW5SZWRvKCkgY29uc3QgPSAwOworCS8vaWYgdGhlIGNvbnRlbnQgaXMgY2hhbmdlZCBhZnRlciBzZXR0ZXh0PworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJc01vZGlmaWVkKCkgY29uc3QgPSAwOworCS8vZ2V0IHRoZSB0b3RhbCB3b3JkcyBpbiBlZGl0CisJdmlydHVhbCBGWF9JTlQzMgkJCQkJCUdldFRvdGFsV29yZHMoKSBjb25zdCA9IDA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJQWRkVW5kb0l0ZW0oSUZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSkgPSAwOworCitwdWJsaWM6CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRFZGl0QXBwZWFyYW5jZVN0cmVhbShJRlhfRWRpdCogcEVkaXQsIGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCwgCisJCQkJCQkJCQkJCQkJY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSA9IE5VTEwsIAorCQkJCQkJCQkJCQkJCUZYX0JPT0wgYkNvbnRpbnVvdXMgPSBUUlVFLCBGWF9XT1JEIFN1YldvcmQgPSAwKTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldFNlbGVjdEFwcGVhcmFuY2VTdHJlYW0oSUZYX0VkaXQqIHBFZGl0LCBjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UgPSBOVUxMKTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd0VkaXQoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwgSUZYX0VkaXQqIHBFZGl0LCBGWF9DT0xPUlJFRiBjclRleHRGaWxsLCBGWF9DT0xPUlJFRiBjclRleHRTdHJva2UsCisJCQkJCQkJCQkJCQkJY29uc3QgQ1BERl9SZWN0JiByY0NsaXAsIGNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlLCBJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIsIHZvaWQqIHBGRkxEYXRhKTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd1VuZGVybGluZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLCBJRlhfRWRpdCogcEVkaXQsIEZYX0NPTE9SUkVGIGNvbG9yLAorCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUmVjdCYgcmNDbGlwLCBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCURyYXdSaWNoRWRpdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLCBJRlhfRWRpdCogcEVkaXQsICAKKwkJCQkJCQkJCQkJCQljb25zdCBDUERGX1JlY3QmIHJjQ2xpcCwgY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZW5lcmF0ZVBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgSUZYX0VkaXQqIHBFZGl0LAorCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlLCBGWF9DT0xPUlJFRiBjclRleHQsIENGWF9BcnJheVRlbXBsYXRlPENQREZfVGV4dE9iamVjdCo+JiBPYmpBcnJheSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUdlbmVyYXRlUmljaFBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgSUZYX0VkaXQqIHBFZGl0LAorCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlLCBDRlhfQXJyYXlUZW1wbGF0ZTxDUERGX1RleHRPYmplY3QqPiYgT2JqQXJyYXkpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZW5lcmF0ZVVuZGVybGluZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmplY3RzLCBJRlhfRWRpdCogcEVkaXQsCisJCQkJCQkJCQkJCQkJY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UsIEZYX0NPTE9SUkVGIGNvbG9yKTsKK307CisKK2NsYXNzIElGWF9MaXN0X05vdGlmeQoreworCS8vdGhpcyBjbGFzcyBpcyBpbXBsZW1lbnRlZCBieSB1c2VyCitwdWJsaWM6CisJLy9zZXQgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIGluZm9ybWF0aW9uLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxJbmZvWChGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIAorCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApID0gMDsKKwkvL3NldCB0aGUgdmVydGljYWwgc2Nyb2xsYmFyIGluZm9ybWF0aW9uLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxJbmZvWShGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIAorCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApID0gMDsKKwkvL3NldCB0aGUgcG9zaXRpb24gb2YgaG9yaXpvbnRhbCBzY3JvbGxiYXIuCisJdmlydHVhbCB2b2lkCQkJCQkJCUlPblNldFNjcm9sbFBvc1goRlhfRkxPQVQgZngpID0gMDsKKwkvL3NldCB0aGUgcG9zaXRpb24gb2YgdmVydGljYWwgc2Nyb2xsYmFyLgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KSA9IDA7CisJLy9JbnZhbGlkYXRlIHRoZSByZWN0YW5nbGUgcmVsYXRpdmUgdG8gdGhlIGJvdW5kaW5nIGJveCBvZiBlZGl0LgorCXZpcnR1YWwgdm9pZAkJCQkJCQlJT25JbnZhbGlkYXRlUmVjdChDUERGX1JlY3QgKiBwUmVjdCkgPSAwOworfTsKKworY2xhc3MgRlhFVF9DTEFTUyBJRlhfTGlzdAoreworcHVibGljOgorCXN0YXRpYyBJRlhfTGlzdCoJCQkJCQlOZXdMaXN0KCk7CisJc3RhdGljIHZvaWQJCQkJCQkJCURlbExpc3QoSUZYX0xpc3QqIHBMaXN0KTsKKworcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRGb250TWFwKElGWF9FZGl0X0ZvbnRNYXAgKiBwRm9udE1hcCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXROb3RpZnkoSUZYX0xpc3RfTm90aWZ5ICogcE5vdGlmeSkgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCQkJCVNldFBsYXRlUmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJCVNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSkgPSAwOworCisJdmlydHVhbCBDUERGX1JlY3QJCQkJCQlHZXRQbGF0ZVJlY3QoKSBjb25zdCA9IDA7CisJdmlydHVhbCBDUERGX1JlY3QJCQkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0ID0gMDsKKworCXZpcnR1YWwgRlhfRkxPQVQJCQkJCQlHZXRGb250U2l6ZSgpIGNvbnN0ID0gMDsKKwl2aXJ0dWFsIElGWF9FZGl0KgkJCQkJCUdldEl0ZW1FZGl0KEZYX0lOVDMyIG5JbmRleCkgY29uc3QgPSAwOworCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRDb3VudCgpIGNvbnN0ID0gMDsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJSXNJdGVtU2VsZWN0ZWQoRlhfSU5UMzIgbkluZGV4KSBjb25zdCA9IDA7CisJdmlydHVhbCBGWF9GTE9BVAkJCQkJCUdldEZpcnN0SGVpZ2h0KCkgY29uc3QgPSAwOworCQorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRNdWx0aXBsZVNlbChGWF9CT09MIGJNdWx0aXBsZSkgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJc011bHRpcGxlU2VsKCkgY29uc3QgPSAwOwkKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJSXNWYWxpZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdCA9IDA7CisJdmlydHVhbCBGWF9JTlQzMgkJCQkJCUZpbmROZXh0KEZYX0lOVDMyIG5JbmRleCxGWF9XQ0hBUiBuQ2hhcikgY29uc3QgPSAwOwkKKworCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRTY3JvbGxQb3MoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJCVNjcm9sbFRvTGlzdEl0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCkgPSAwOworCXZpcnR1YWwgQ1BERl9SZWN0CQkJCQkJR2V0SXRlbVJlY3QoRlhfSU5UMzIgbkluZGV4KSBjb25zdCA9IDA7CisJdmlydHVhbCBGWF9JTlQzMgkJCQkJCUdldENhcmV0KCkgY29uc3QgPSAwOworCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRTZWxlY3QoKSBjb25zdCA9IDA7CQorCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRUb3BJdGVtKCkgY29uc3QgPSAwOworCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQlHZXRJdGVtSW5kZXgoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdCA9IDA7CisJdmlydHVhbCBGWF9JTlQzMgkJCQkJCUdldEZpcnN0U2VsZWN0ZWQoKSBjb25zdCA9IDA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJQWRkU3RyaW5nKEZYX0xQQ1dTVFIgc3RyaW5nKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJCVNldFRvcEl0ZW0oRlhfSU5UMzIgbkluZGV4KSA9IDA7CQorCXZpcnR1YWwgdm9pZAkJCQkJCQlTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlTZXRDYXJldChGWF9JTlQzMiBuSXRlbUluZGV4KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJCUVtcHR5KCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlDYW5jZWwoKSA9IDA7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJR2V0VGV4dCgpIGNvbnN0ID0gMDsKKworCisJdmlydHVhbCB2b2lkCQkJCQkJCU9uTW91c2VEb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJCU9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJCU9uVktfVVAoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlPblZLX0RPV04oRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlPblZLX0xFRlQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlPblZLX1JJR0hUKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19IT01FKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJT25WS19FTkQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlPblZLKEZYX0lOVDMyIG5JdGVtSW5kZXgsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlPbkNoYXIoRlhfV09SRCBuQ2hhcixGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKSA9IDA7Cit9OworCisjZW5kaWYgCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9meGVkaXQvZnhldF9lZGl0LmggYi9mcGRmc2RrL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfZWRpdC5oCmluZGV4IDcyYjc4MDkuLmY2NTcxNWIgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9meGVkaXQvZnhldF9lZGl0LmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2Z4ZWRpdC9meGV0X2VkaXQuaApAQCAtMSw4MjMgKzEsODIzIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9GWEVUX0VESVRfSF8NCi0jZGVmaW5lIF9GWEVUX0VESVRfSF8NCi0NCi0jaW5jbHVkZSAiZnhfZWRpdC5oIg0KLQ0KLWNsYXNzIENGWF9FZGl0X1BhZ2U7DQotc3RydWN0IENGWF9FZGl0X0xpbmVSZWN0Ow0KLWNsYXNzIENGWF9FZGl0X0xpbmVSZWN0QXJyYXk7DQotY2xhc3MgQ0ZYX0VkaXRfUmVjdEFycmF5Ow0KLWNsYXNzIENGWF9FZGl0X1JlZnJlc2g7DQotY2xhc3MgQ0ZYX0VkaXRfU2VsZWN0Ow0KLWNsYXNzIENGWF9FZGl0Ow0KLWNsYXNzIENGWF9FZGl0X0l0ZXJhdG9yOw0KLWNsYXNzIENGWF9FZGl0X1JlZnJlc2g7DQotY2xhc3MgQ0ZYX0VkaXRfVW5kb0l0ZW07DQotY2xhc3MgQ0ZYX0VkaXRfVW5kbzsNCi1jbGFzcyBDRlhfRWRpdF9Qcm92aWRlcjsNCi0NCi0jZGVmaW5lIEZYX0VESVRfSXNGbG9hdFplcm8oZikJCQkJCQkoZiA8IDAuMDAwMSAmJiBmID4gLTAuMDAwMSkNCi0jZGVmaW5lIEZYX0VESVRfSXNGbG9hdEVxdWFsKGZhLGZiKQkJCQkJRlhfRURJVF9Jc0Zsb2F0WmVybyhmYSAtIGZiKQ0KLSNkZWZpbmUgRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKGZhLGZiKQkJCQkoZmEgPiBmYiAmJiAhRlhfRURJVF9Jc0Zsb2F0RXF1YWwoZmEsZmIpKQ0KLSNkZWZpbmUgRlhfRURJVF9Jc0Zsb2F0U21hbGxlcihmYSxmYikJCQkJKGZhIDwgZmIgJiYgIUZYX0VESVRfSXNGbG9hdEVxdWFsKGZhLGZiKSkNCi0NCi10ZW1wbGF0ZTxjbGFzcyBUPiBUIEZYX0VESVRfTUlOIChjb25zdCBUICYgaSwgY29uc3QgVCAmIGopIHsgcmV0dXJuICgoaSA8IGopID8gaSA6IGopOyB9DQotdGVtcGxhdGU8Y2xhc3MgVD4gVCBGWF9FRElUX01BWCAoY29uc3QgVCAmIGksIGNvbnN0IFQgJiBqKSB7IHJldHVybiAoKGkgPiBqKSA/IGkgOiBqKTsgfQ0KLQ0KLSNkZWZpbmUJRlhfRURJVF9QSQkJCQkJCQkJCTMuMTQxNTkyNjUzNTg5NzlmDQotI2RlZmluZSBGWF9FRElUX0lUQUxJQ19BTkdFTAkJCQkJCTEwICogRlhfRURJVF9QSSAvIDE4MC4wZg0KLQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0VkaXRfUmVmcmVzaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotZW51bSBSRUZSRVNIX1BMQU5fRQ0KLXsNCi0JUlBfQU5BTFlTRSwNCi0JUlBfTk9BTkFMWVNFLA0KLQlSUF9PUFRJT05BTA0KLX07DQotDQotZW51bSBFRElUX1BST1BTX0UNCi17DQotCUVQX0xJTkVMRUFESU5HLA0KLQlFUF9MSU5FSU5ERU5ULA0KLQlFUF9BTElHTk1FTlQsDQotCUVQX0ZPTlRJTkRFWCwNCi0JRVBfRk9OVFNJWkUsDQotCUVQX1dPUkRDT0xPUiwNCi0JRVBfU0NSSVBUVFlQRSwNCi0JRVBfVU5ERVJMSU5FLA0KLQlFUF9DUk9TU09VVCwNCi0JRVBfQ0hBUlNQQUNFLA0KLQlFUF9IT1JaU0NBTEUsDQotCUVQX0JPTEQsDQotCUVQX0lUQUxJQw0KLX07DQotDQotc3RydWN0IENGWF9FZGl0X0xpbmVSZWN0DQotew0KLQlDRlhfRWRpdF9MaW5lUmVjdChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyTGluZSxjb25zdCBDUERGX1JlY3QgJiByY0xpbmUpIDoNCi0JCW1fd3JMaW5lKHdyTGluZSksIG1fcmNMaW5lKHJjTGluZSkNCi0Jew0KLQl9DQotDQotCUZYX0JPT0wgb3BlcmF0b3IgIT0gKGNvbnN0IENGWF9FZGl0X0xpbmVSZWN0ICYgbGluZXJlY3QpIGNvbnN0DQotCXsNCi0JCXJldHVybiBGWFNZU19tZW1jbXAodGhpcywgJmxpbmVyZWN0LCBzaXplb2YoQ0ZYX0VkaXRfTGluZVJlY3QpKSAhPSAwOw0KLQl9DQotDQotCUZYX0JPT0wgSXNTYW1lSGVpZ2h0KGNvbnN0IENGWF9FZGl0X0xpbmVSZWN0ICYgbGluZXJlY3QpIGNvbnN0DQotCXsNCi0JCXJldHVybiBGWF9FRElUX0lzRmxvYXRaZXJvKChtX3JjTGluZS50b3AgLSBtX3JjTGluZS5ib3R0b20pIC0gKGxpbmVyZWN0Lm1fcmNMaW5lLnRvcCAtbGluZXJlY3QubV9yY0xpbmUuYm90dG9tKSk7DQotCX0NCi0NCi0JRlhfQk9PTCBJc1NhbWVUb3AoY29uc3QgQ0ZYX0VkaXRfTGluZVJlY3QgJiBsaW5lcmVjdCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIEZYX0VESVRfSXNGbG9hdFplcm8obV9yY0xpbmUudG9wIC0gbGluZXJlY3QubV9yY0xpbmUudG9wKTsNCi0JfQ0KLQ0KLQlGWF9CT09MIElzU2FtZUxlZnQoY29uc3QgQ0ZYX0VkaXRfTGluZVJlY3QgJiBsaW5lcmVjdCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIEZYX0VESVRfSXNGbG9hdFplcm8obV9yY0xpbmUubGVmdCAtIGxpbmVyZWN0Lm1fcmNMaW5lLmxlZnQpOw0KLQl9DQotDQotCUZYX0JPT0wgSXNTYW1lUmlnaHQoY29uc3QgQ0ZYX0VkaXRfTGluZVJlY3QgJiBsaW5lcmVjdCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIEZYX0VESVRfSXNGbG9hdFplcm8obV9yY0xpbmUucmlnaHQgLSBsaW5lcmVjdC5tX3JjTGluZS5yaWdodCk7DQotCX0NCi0NCi0JQ1BWVF9Xb3JkUmFuZ2UJCQkJCQkJbV93ckxpbmU7DQotCUNQREZfUmVjdAkJCQkJCQkJbV9yY0xpbmU7DQotfTsNCi0NCi1jbGFzcyBDRlhfRWRpdF9MaW5lUmVjdEFycmF5DQotew0KLXB1YmxpYzoNCi0JQ0ZYX0VkaXRfTGluZVJlY3RBcnJheSgpDQotCXsNCi0JfQ0KLQ0KLQl2aXJ0dWFsIH5DRlhfRWRpdF9MaW5lUmVjdEFycmF5KCkNCi0Jew0KLQkJRW1wdHkoKTsNCi0JfQ0KLQ0KLQl2b2lkIEVtcHR5KCkNCi0Jew0KLQkJZm9yIChGWF9JTlQzMiBpID0gMCwgc3ogPSBtX0xpbmVSZWN0cy5HZXRTaXplKCk7IGkgPCBzejsgaSsrKQ0KLQkJCWRlbGV0ZSBtX0xpbmVSZWN0cy5HZXRBdChpKTsNCi0NCi0JCW1fTGluZVJlY3RzLlJlbW92ZUFsbCgpOw0KLQl9DQotDQotCXZvaWQgUmVtb3ZlQWxsKCkNCi0Jew0KLQkJbV9MaW5lUmVjdHMuUmVtb3ZlQWxsKCk7DQotCX0NCi0NCi0Jdm9pZCBvcGVyYXRvciA9IChDRlhfRWRpdF9MaW5lUmVjdEFycmF5ICYgcmVjdHMpDQotCXsNCi0JCUVtcHR5KCk7DQotCQlmb3IgKEZYX0lOVDMyIGkgPSAwLCBzeiA9IHJlY3RzLkdldFNpemUoKTsgaSA8IHN6OyBpKyspDQotCQkJbV9MaW5lUmVjdHMuQWRkKHJlY3RzLkdldEF0KGkpKTsNCi0NCi0JCXJlY3RzLlJlbW92ZUFsbCgpOw0KLQl9DQotDQotCXZvaWQgQWRkKGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3JMaW5lLGNvbnN0IENQREZfUmVjdCAmIHJjTGluZSkNCi0Jew0KLQkJaWYgKENGWF9FZGl0X0xpbmVSZWN0ICogcFJlY3QgPSBuZXcgQ0ZYX0VkaXRfTGluZVJlY3Qod3JMaW5lLHJjTGluZSkpDQotCQkJbV9MaW5lUmVjdHMuQWRkKHBSZWN0KTsNCi0JfQ0KLQ0KLQlGWF9JTlQzMiBHZXRTaXplKCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIG1fTGluZVJlY3RzLkdldFNpemUoKTsNCi0JfQ0KLQ0KLQlDRlhfRWRpdF9MaW5lUmVjdCAqIEdldEF0KEZYX0lOVDMyIG5JbmRleCkgY29uc3QNCi0Jew0KLQkJaWYgKG5JbmRleCA8IDAgfHwgbkluZGV4ID49IG1fTGluZVJlY3RzLkdldFNpemUoKSkNCi0JCQlyZXR1cm4gTlVMTDsNCi0NCi0JCXJldHVybiBtX0xpbmVSZWN0cy5HZXRBdChuSW5kZXgpOw0KLQl9DQotDQotCUNGWF9BcnJheVRlbXBsYXRlPENGWF9FZGl0X0xpbmVSZWN0Kj4JCW1fTGluZVJlY3RzOw0KLX07DQotDQotY2xhc3MgQ0ZYX0VkaXRfUmVjdEFycmF5DQotew0KLXB1YmxpYzoNCi0JQ0ZYX0VkaXRfUmVjdEFycmF5KCkNCi0Jew0KLQl9DQotDQotCXZpcnR1YWwgfkNGWF9FZGl0X1JlY3RBcnJheSgpDQotCXsNCi0JCXRoaXMtPkVtcHR5KCk7DQotCX0NCi0NCi0Jdm9pZCBFbXB0eSgpDQotCXsNCi0JCWZvciAoRlhfSU5UMzIgaSA9IDAsIHN6ID0gbV9SZWN0cy5HZXRTaXplKCk7IGkgPCBzejsgaSsrKQ0KLQkJCWRlbGV0ZSBtX1JlY3RzLkdldEF0KGkpOw0KLQ0KLQkJdGhpcy0+bV9SZWN0cy5SZW1vdmVBbGwoKTsNCi0JfQ0KLQ0KLQl2b2lkIEFkZChjb25zdCBDUERGX1JlY3QgJiByZWN0KQ0KLQl7DQotCQkvL2NoZWNrIGZvciBvdmVybGFwZWQgYXJlYQ0KLQkJZm9yIChGWF9JTlQzMiBpID0gMCwgc3ogPSBtX1JlY3RzLkdldFNpemUoKTsgaSA8IHN6OyBpKyspDQotCQkJaWYgKENQREZfUmVjdCAqIHBSZWN0ID0gbV9SZWN0cy5HZXRBdChpKSkNCi0JCQkJaWYgKHBSZWN0LT5Db250YWlucyhyZWN0KSlyZXR1cm47DQotDQotCQlpZiAoQ1BERl9SZWN0ICogcE5ld1JlY3QgPSBuZXcgQ1BERl9SZWN0KHJlY3QpKQ0KLQkJCW1fUmVjdHMuQWRkKHBOZXdSZWN0KTsNCi0JfQ0KLQ0KLQlGWF9JTlQzMiBHZXRTaXplKCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIG1fUmVjdHMuR2V0U2l6ZSgpOw0KLQl9DQotDQotCUNQREZfUmVjdCAqIEdldEF0KEZYX0lOVDMyIG5JbmRleCkgY29uc3QNCi0Jew0KLQkJaWYgKG5JbmRleCA8IDAgfHwgbkluZGV4ID49IG1fUmVjdHMuR2V0U2l6ZSgpKQ0KLQkJCXJldHVybiBOVUxMOw0KLQ0KLQkJcmV0dXJuIG1fUmVjdHMuR2V0QXQobkluZGV4KTsNCi0JfQ0KLQ0KLQlDRlhfQXJyYXlUZW1wbGF0ZTxDUERGX1JlY3QqPgkJCW1fUmVjdHM7DQotfTsNCi0NCi1jbGFzcyBDRlhfRWRpdF9SZWZyZXNoDQotew0KLXB1YmxpYzoNCi0JQ0ZYX0VkaXRfUmVmcmVzaCgpOw0KLQl2aXJ0dWFsIH5DRlhfRWRpdF9SZWZyZXNoKCk7DQotDQotCXZvaWQJCQkJCQkJCQlCZWdpblJlZnJlc2goKTsNCi0Jdm9pZAkJCQkJCQkJCVB1c2goY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiBsaW5lcmFuZ2UsY29uc3QgQ1BERl9SZWN0ICYgcmVjdCk7DQotCXZvaWQJCQkJCQkJCQlOb0FuYWx5c2UoKTsNCi0Jdm9pZAkJCQkJCQkJCUFuYWx5c2UoRlhfSU5UMzIgbkFsaWdubWVudCk7DQotCXZvaWQJCQkJCQkJCQlBZGRSZWZyZXNoKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpOw0KLQljb25zdCBDRlhfRWRpdF9SZWN0QXJyYXkgKgkJCQlHZXRSZWZyZXNoUmVjdHMoKSBjb25zdDsNCi0Jdm9pZAkJCQkJCQkJCUVuZFJlZnJlc2goKTsNCi0NCi1wcml2YXRlOg0KLQlDRlhfRWRpdF9MaW5lUmVjdEFycmF5CQkJCQltX05ld0xpbmVSZWN0czsNCi0JQ0ZYX0VkaXRfTGluZVJlY3RBcnJheQkJCQkJbV9PbGRMaW5lUmVjdHM7DQotCUNGWF9FZGl0X1JlY3RBcnJheQkJCQkJCW1fUmVmcmVzaFJlY3RzOw0KLX07DQotDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdF9TZWxlY3QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLWNsYXNzIENGWF9FZGl0X1NlbGVjdA0KLXsNCi1wdWJsaWM6DQotCUNGWF9FZGl0X1NlbGVjdCgpDQotCXsNCi0JfQ0KLQ0KLQlDRlhfRWRpdF9TZWxlY3QoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBiZWdpbixjb25zdCBDUFZUX1dvcmRQbGFjZSAmIGVuZCkNCi0Jew0KLQkJU2V0KGJlZ2luLGVuZCk7DQotCX0NCi0NCi0JQ0ZYX0VkaXRfU2VsZWN0KGNvbnN0IENQVlRfV29yZFJhbmdlICYgcmFuZ2UpDQotCXsNCi0JCVNldChyYW5nZS5CZWdpblBvcyxyYW5nZS5FbmRQb3MpOw0KLQl9DQotDQotCUNQVlRfV29yZFJhbmdlIENvbnZlcnRUb1dvcmRSYW5nZSgpIGNvbnN0DQotCXsNCi0JCXJldHVybiBDUFZUX1dvcmRSYW5nZSh0aGlzLT5CZWdpblBvcyx0aGlzLT5FbmRQb3MpOw0KLQl9DQotDQotCXZvaWQgRGVmYXVsdCgpDQotCXsNCi0JCUJlZ2luUG9zLkRlZmF1bHQoKTsNCi0JCUVuZFBvcy5EZWZhdWx0KCk7DQotCX0NCi0NCi0Jdm9pZCBTZXQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBiZWdpbixjb25zdCBDUFZUX1dvcmRQbGFjZSAmIGVuZCkNCi0Jew0KLQkJdGhpcy0+QmVnaW5Qb3MgPSBiZWdpbjsNCi0JCXRoaXMtPkVuZFBvcyA9IGVuZDsNCi0JfQ0KLQ0KLQl2b2lkIFNldEJlZ2luUG9zKGNvbnN0IENQVlRfV29yZFBsYWNlICYgYmVnaW4pDQotCXsNCi0JCXRoaXMtPkJlZ2luUG9zID0gYmVnaW47DQotCX0NCi0NCi0Jdm9pZCBTZXRFbmRQb3MoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBlbmQpDQotCXsNCi0JCXRoaXMtPkVuZFBvcyA9IGVuZDsNCi0JfQ0KLQ0KLQlGWF9CT09MIElzRXhpc3QoKSBjb25zdA0KLQl7DQotCQlyZXR1cm4gdGhpcy0+QmVnaW5Qb3MgIT0gdGhpcy0+RW5kUG9zOw0KLQl9DQotDQotCUZYX0JPT0wgb3BlcmF0b3IgIT0gKGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IpIGNvbnN0DQotCXsNCi0JCXJldHVybiB3ci5CZWdpblBvcyAhPSB0aGlzLT5CZWdpblBvcyB8fCB3ci5FbmRQb3MgIT0gdGhpcy0+RW5kUG9zOw0KLQl9DQotDQotCUNQVlRfV29yZFBsYWNlIEJlZ2luUG9zLEVuZFBvczsNCi19Ow0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0VkaXRfVW5kbyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotY2xhc3MgQ0ZYX0VkaXRfVW5kbw0KLXsNCi1wdWJsaWM6DQotCUNGWF9FZGl0X1VuZG8oRlhfSU5UMzIgbkJ1ZnNpemUgPSAxMDAwMCk7DQotCXZpcnR1YWwgfkNGWF9FZGl0X1VuZG8oKTsNCi0NCi0Jdm9pZAkJCQkJCQkJCVVuZG8oKTsNCi0Jdm9pZAkJCQkJCQkJCVJlZG8oKTsNCi0NCi0Jdm9pZAkJCQkJCQkJCUFkZEl0ZW0oSUZYX0VkaXRfVW5kb0l0ZW0qIHBJdGVtKTsNCi0NCi0JRlhfQk9PTAkJCQkJCQkJCUNhblVuZG8oKSBjb25zdDsNCi0JRlhfQk9PTAkJCQkJCQkJCUNhblJlZG8oKSBjb25zdDsNCi0JRlhfQk9PTAkJCQkJCQkJCUlzTW9kaWZpZWQoKSBjb25zdDsNCi0JRlhfQk9PTAkJCQkJCQkJCUlzV29ya2luZygpIGNvbnN0Ow0KLQ0KLQl2b2lkCQkJCQkJCQkJUmVzZXQoKTsNCi0NCi0JSUZYX0VkaXRfVW5kb0l0ZW0qCQkJCQkJR2V0SXRlbShGWF9JTlQzMiBuSW5kZXgpOw0KLQlGWF9JTlQzMgkJCQkJCQkJR2V0SXRlbUNvdW50KCl7cmV0dXJuIG1fVW5kb0l0ZW1TdGFjay5HZXRTaXplKCk7fQ0KLQlGWF9JTlQzMgkJCQkJCQkJR2V0Q3VyVW5kb1Bvcygpe3JldHVybiBtX25DdXJVbmRvUG9zO30NCi0NCi1wcml2YXRlOg0KLQl2b2lkCQkJCQkJCQkJU2V0QnVmU2l6ZShGWF9JTlQzMiBuU2l6ZSl7bV9uQnVmU2l6ZSA9IG5TaXplO30NCi0JRlhfSU5UMzIJCQkJCQkJCUdldEJ1ZlNpemUoKXtyZXR1cm4gbV9uQnVmU2l6ZTt9DQotDQotCXZvaWQJCQkJCQkJCQlSZW1vdmVIZWFkcygpOw0KLQl2b2lkCQkJCQkJCQkJUmVtb3ZlVGFpbHMoKTsNCi0NCi1wcml2YXRlOg0KLQlDRlhfQXJyYXlUZW1wbGF0ZTxJRlhfRWRpdF9VbmRvSXRlbSo+CW1fVW5kb0l0ZW1TdGFjazsNCi0JDQotCUZYX0lOVDMyCQkJCQkJCQltX25DdXJVbmRvUG9zOw0KLQlGWF9JTlQzMgkJCQkJCQkJbV9uQnVmU2l6ZTsNCi0JRlhfQk9PTAkJCQkJCQkJCW1fYk1vZGlmaWVkOyANCi0JRlhfQk9PTAkJCQkJCQkJCW1fYlZpcmdpbjsNCi0JRlhfQk9PTAkJCQkJCQkJCW1fYldvcmtpbmc7DQotfTsNCi0NCi1jbGFzcyBDRlhfRWRpdF9VbmRvSXRlbSA6IHB1YmxpYyBJRlhfRWRpdF9VbmRvSXRlbQ0KLXsNCi1wdWJsaWM6DQotCUNGWF9FZGl0X1VuZG9JdGVtKCkgOiBtX2JGaXJzdChUUlVFKSwgbV9iTGFzdChUUlVFKSB7fQ0KLQl2aXJ0dWFsIH5DRlhfRWRpdF9VbmRvSXRlbSgpe30NCi0NCi0JdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJR2V0VW5kb1RpdGxlKCkge3JldHVybiBMIiI7fQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJUmVsZWFzZSgpe2RlbGV0ZSB0aGlzO30NCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQkJCQlTZXRGaXJzdChGWF9CT09MIGJGaXJzdCl7bV9iRmlyc3QgPSBiRmlyc3Q7fQ0KLQlGWF9CT09MCQkJCQkJCQkJSXNGaXJzdCgpe3JldHVybiBtX2JGaXJzdDt9DQotCXZvaWQJCQkJCQkJCQlTZXRMYXN0KEZYX0JPT0wgYkxhc3Qpe21fYkxhc3QgPSBiTGFzdDt9DQotCUZYX0JPT0wJCQkJCQkJCQlJc0xhc3QoKXtyZXR1cm4gbV9iTGFzdDt9DQotDQotcHJpdmF0ZToNCi0JRlhfQk9PTAkJCQkJCQkJCW1fYkZpcnN0Ow0KLQlGWF9CT09MCQkJCQkJCQkJbV9iTGFzdDsNCi19Ow0KLQ0KLWNsYXNzIENGWF9FZGl0X0dyb3VwVW5kb0l0ZW0gOiBwdWJsaWMgSUZYX0VkaXRfVW5kb0l0ZW0NCi17DQotcHVibGljOg0KLQlDRlhfRWRpdF9Hcm91cFVuZG9JdGVtKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGl0bGUpOw0KLQl2aXJ0dWFsIH5DRlhfRWRpdF9Hcm91cFVuZG9JdGVtKCk7DQotDQotCXZvaWQJCQkJCQkJCQlBZGRVbmRvSXRlbShDRlhfRWRpdF9VbmRvSXRlbSogcFVuZG9JdGVtKTsNCi0Jdm9pZAkJCQkJCQkJCVVwZGF0ZUl0ZW1zKCk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJVW5kbygpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJUmVkbygpOw0KLQl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQkJCQlHZXRVbmRvVGl0bGUoKTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCVJlbGVhc2UoKTsNCi0NCi1wcml2YXRlOg0KLQlDRlhfV2lkZVN0cmluZwkJCQkJCQltX3NUaXRsZTsNCi0JQ0ZYX0FycmF5VGVtcGxhdGU8Q0ZYX0VkaXRfVW5kb0l0ZW0qPgltX0l0ZW1zOw0KLX07DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdF9VbmRvSXRlbSBkZXJpdmVkIGNsYXNzZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLWNsYXNzIENGWEVVX0luc2VydFdvcmQgOiBwdWJsaWMgQ0ZYX0VkaXRfVW5kb0l0ZW0NCi17DQotcHVibGljOg0KLQlDRlhFVV9JbnNlcnRXb3JkKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLA0KLQkJRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpOw0KLQl2aXJ0dWFsIH5DRlhFVV9JbnNlcnRXb3JkKCk7DQotDQotCXZvaWQJCQkJCQlSZWRvKCk7DQotCXZvaWQJCQkJCQlVbmRvKCk7DQotDQotcHJpdmF0ZToNCi0JQ0ZYX0VkaXQqCQkJCQltX3BFZGl0Ow0KLQ0KLQlDUFZUX1dvcmRQbGFjZQkJCQltX3dwT2xkOw0KLQlDUFZUX1dvcmRQbGFjZQkJCQltX3dwTmV3Ow0KLQlGWF9XT1JECQkJCQkJbV9Xb3JkOw0KLQlGWF9JTlQzMgkJCQkJbV9uQ2hhcnNldDsNCi0JQ1BWVF9Xb3JkUHJvcHMJCQkJbV9Xb3JkUHJvcHM7DQotfTsNCi0NCi1jbGFzcyBDRlhFVV9JbnNlcnRSZXR1cm4gOiBwdWJsaWMgQ0ZYX0VkaXRfVW5kb0l0ZW0NCi17DQotcHVibGljOg0KLQlDRlhFVV9JbnNlcnRSZXR1cm4oQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsDQotCQkJCQkJCSBjb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpOw0KLQl2aXJ0dWFsIH5DRlhFVV9JbnNlcnRSZXR1cm4oKTsNCi0NCi0Jdm9pZAkJCQkJCVJlZG8oKTsNCi0Jdm9pZAkJCQkJCVVuZG8oKTsNCi0NCi1wcml2YXRlOg0KLQlDRlhfRWRpdCAqCQkJCQltX3BFZGl0Ow0KLQ0KLQlDUFZUX1dvcmRQbGFjZQkJCQltX3dwT2xkOw0KLQlDUFZUX1dvcmRQbGFjZQkJCQltX3dwTmV3Ow0KLQlDUFZUX1NlY1Byb3BzCQkJCW1fU2VjUHJvcHM7DQotCUNQVlRfV29yZFByb3BzCQkJCW1fV29yZFByb3BzOw0KLX07DQotDQotY2xhc3MgQ0ZYRVVfQmFja3NwYWNlIDogcHVibGljIENGWF9FZGl0X1VuZG9JdGVtDQotew0KLXB1YmxpYzoNCi0JQ0ZYRVVfQmFja3NwYWNlKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLA0KLQkJCQkJCUZYX1dPUkQgd29yZCwgRlhfSU5UMzIgY2hhcnNldCwNCi0JCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICYgU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgV29yZFByb3BzKTsNCi0JdmlydHVhbCB+Q0ZYRVVfQmFja3NwYWNlKCk7DQotDQotCXZvaWQJCQkJCQlSZWRvKCk7DQotCXZvaWQJCQkJCQlVbmRvKCk7DQotDQotcHJpdmF0ZToNCi0JQ0ZYX0VkaXQgKgkJCQkJbV9wRWRpdDsNCi0NCi0JQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cE9sZDsNCi0JQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cE5ldzsNCi0JRlhfV09SRAkJCQkJCW1fV29yZDsNCi0JRlhfSU5UMzIJCQkJCW1fbkNoYXJzZXQ7DQotCUNQVlRfU2VjUHJvcHMJCQkJbV9TZWNQcm9wczsNCi0JQ1BWVF9Xb3JkUHJvcHMJCQkJbV9Xb3JkUHJvcHM7DQotfTsNCi0NCi1jbGFzcyBDRlhFVV9EZWxldGUgOiBwdWJsaWMgQ0ZYX0VkaXRfVW5kb0l0ZW0NCi17DQotcHVibGljOg0KLQlDRlhFVV9EZWxldGUoQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsDQotCQkJCQkJRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LA0KLQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgJiBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBXb3JkUHJvcHMsIEZYX0JPT0wgYlNlY0VuZCk7DQotCXZpcnR1YWwgfkNGWEVVX0RlbGV0ZSgpOw0KLQ0KLQl2b2lkCQkJCQkJUmVkbygpOw0KLQl2b2lkCQkJCQkJVW5kbygpOw0KLQ0KLXByaXZhdGU6DQotCUNGWF9FZGl0ICoJCQkJCW1fcEVkaXQ7DQotDQotCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BPbGQ7DQotCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BOZXc7DQotCUZYX1dPUkQJCQkJCQltX1dvcmQ7DQotCUZYX0lOVDMyCQkJCQltX25DaGFyc2V0Ow0KLQlDUFZUX1NlY1Byb3BzCQkJCW1fU2VjUHJvcHM7DQotCUNQVlRfV29yZFByb3BzCQkJCW1fV29yZFByb3BzOw0KLQlGWF9CT09MCQkJCQkJbV9iU2VjRW5kOw0KLX07DQotDQotY2xhc3MgQ0ZYRVVfQ2xlYXIgOiBwdWJsaWMgQ0ZYX0VkaXRfVW5kb0l0ZW0NCi17DQotcHVibGljOg0KLQlDRlhFVV9DbGVhcihDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyU2VsLCBjb25zdCBDRlhfV2lkZVN0cmluZyAmIHN3VGV4dCk7DQotCXZpcnR1YWwgfkNGWEVVX0NsZWFyKCk7DQotDQotCXZvaWQJCQkJCQlSZWRvKCk7DQotCXZvaWQJCQkJCQlVbmRvKCk7DQotDQotcHJpdmF0ZToNCi0JQ0ZYX0VkaXQqCQkJCQltX3BFZGl0Ow0KLQ0KLQlDUFZUX1dvcmRSYW5nZQkJCQltX3dyU2VsOw0KLQlDRlhfV2lkZVN0cmluZwkJCQltX3N3VGV4dDsNCi19Ow0KLQ0KLWNsYXNzIENGWEVVX0NsZWFyUmljaCA6IHB1YmxpYyBDRlhfRWRpdF9VbmRvSXRlbQ0KLXsNCi1wdWJsaWM6DQotCUNGWEVVX0NsZWFyUmljaChDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwT2xkUGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BOZXdQbGFjZSwNCi0JCQkJCQljb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyU2VsLA0KLQkJCQkJICAgRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LA0KLQkJCQkJICAgY29uc3QgQ1BWVF9TZWNQcm9wcyAmIFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIFdvcmRQcm9wcyk7DQotCXZpcnR1YWwgfkNGWEVVX0NsZWFyUmljaCgpOw0KLQ0KLQl2b2lkCQkJCQkJUmVkbygpOw0KLQl2b2lkCQkJCQkJVW5kbygpOw0KLQ0KLXByaXZhdGU6DQotCUNGWF9FZGl0ICoJCQkJCW1fcEVkaXQ7DQotDQotCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BPbGQ7DQotCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BOZXc7DQotCUNQVlRfV29yZFJhbmdlCQkJCW1fd3JTZWw7DQotCUZYX1dPUkQJCQkJCQltX1dvcmQ7DQotCUZYX0lOVDMyCQkJCQltX25DaGFyc2V0Ow0KLQlDUFZUX1NlY1Byb3BzCQkJCW1fU2VjUHJvcHM7DQotCUNQVlRfV29yZFByb3BzCQkJCW1fV29yZFByb3BzOw0KLX07DQotDQotY2xhc3MgQ0ZYRVVfSW5zZXJ0VGV4dCA6IHB1YmxpYyBDRlhfRWRpdF9VbmRvSXRlbQ0KLXsNCi1wdWJsaWM6DQotCUNGWEVVX0luc2VydFRleHQoQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsDQotCQkJCQkJICAgY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBzd1RleHQsIEZYX0lOVDMyIGNoYXJzZXQsDQotCQkJCQkJICAgY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzKTsNCi0JdmlydHVhbCB+Q0ZYRVVfSW5zZXJ0VGV4dCgpOw0KLQ0KLQl2b2lkCQkJCQkJUmVkbygpOw0KLQl2b2lkCQkJCQkJVW5kbygpOw0KLQ0KLXByaXZhdGU6DQotCUNGWF9FZGl0ICoJCQkJCW1fcEVkaXQ7DQotDQotCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BPbGQ7DQotCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BOZXc7DQotCUNGWF9XaWRlU3RyaW5nCQkJCW1fc3dUZXh0Ow0KLQlGWF9JTlQzMgkJCQkJbV9uQ2hhcnNldDsNCi0JQ1BWVF9TZWNQcm9wcwkJCQltX1NlY1Byb3BzOw0KLQlDUFZUX1dvcmRQcm9wcwkJCQltX1dvcmRQcm9wczsNCi19Ow0KLQ0KLWNsYXNzIENGWEVVX1NldFNlY1Byb3BzIDogcHVibGljIENGWF9FZGl0X1VuZG9JdGVtDQotew0KLXB1YmxpYzoNCi0JQ0ZYRVVfU2V0U2VjUHJvcHMoQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSwgRURJVF9QUk9QU19FIGVwLCANCi0JCWNvbnN0IENQVlRfU2VjUHJvcHMgJiBvbGRzZWNwcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBvbGR3b3JkcHJvcHMsIA0KLQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAmIG5ld3NlY3Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIG5ld3dvcmRwcm9wcywgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiByYW5nZSk7DQotCXZpcnR1YWwgfkNGWEVVX1NldFNlY1Byb3BzKCk7DQotDQotCXZvaWQJCQkJCQlSZWRvKCk7DQotCXZvaWQJCQkJCQlVbmRvKCk7DQotDQotcHJpdmF0ZToNCi0JQ0ZYX0VkaXQgKgkJCQkJbV9wRWRpdDsNCi0JQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cFBsYWNlOw0KLQlDUFZUX1dvcmRSYW5nZQkJCQltX3dyUGxhY2U7DQotCUVESVRfUFJPUFNfRQkJCQltX2VQcm9wczsNCi0NCi0JQ1BWVF9TZWNQcm9wcwkJCQltX09sZFNlY1Byb3BzOw0KLQlDUFZUX1NlY1Byb3BzCQkJCW1fTmV3U2VjUHJvcHM7DQotCUNQVlRfV29yZFByb3BzCQkJCW1fT2xkV29yZFByb3BzOw0KLQlDUFZUX1dvcmRQcm9wcwkJCQltX05ld1dvcmRQcm9wczsJDQotfTsNCi0NCi1jbGFzcyBDRlhFVV9TZXRXb3JkUHJvcHMgOiBwdWJsaWMgQ0ZYX0VkaXRfVW5kb0l0ZW0NCi17DQotcHVibGljOg0KLQlDRlhFVV9TZXRXb3JkUHJvcHMoQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSwgRURJVF9QUk9QU19FIGVwLCANCi0JCWNvbnN0IENQVlRfV29yZFByb3BzICYgb2xkcHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgbmV3cHJvcHMsIGNvbnN0IENQVlRfV29yZFJhbmdlICYgcmFuZ2UpOw0KLQl2aXJ0dWFsIH5DRlhFVV9TZXRXb3JkUHJvcHMoKTsNCi0NCi0Jdm9pZAkJCQkJCVJlZG8oKTsNCi0Jdm9pZAkJCQkJCVVuZG8oKTsNCi0NCi1wcml2YXRlOg0KLQlDRlhfRWRpdCAqCQkJCQltX3BFZGl0Ow0KLQlDUFZUX1dvcmRQbGFjZQkJCQltX3dwUGxhY2U7DQotCUNQVlRfV29yZFJhbmdlCQkJCW1fd3JQbGFjZTsNCi0JRURJVF9QUk9QU19FCQkJCW1fZVByb3BzOw0KLQkNCi0JQ1BWVF9Xb3JkUHJvcHMJCQkJbV9PbGRXb3JkUHJvcHM7DQotCUNQVlRfV29yZFByb3BzCQkJCW1fTmV3V29yZFByb3BzOwkNCi19Ow0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0VkaXQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLWNsYXNzIENGWF9FZGl0IDogcHVibGljIElGWF9FZGl0DQotew0KLQlmcmllbmQgY2xhc3MgQ0ZYX0VkaXRfSXRlcmF0b3I7DQotCWZyaWVuZCBjbGFzcyBDRlhFVV9JbnNlcnRXb3JkOw0KLQlmcmllbmQgY2xhc3MgQ0ZYRVVfSW5zZXJ0UmV0dXJuOw0KLQlmcmllbmQgY2xhc3MgQ0ZYRVVfQmFja3NwYWNlOw0KLQlmcmllbmQgY2xhc3MgQ0ZYRVVfRGVsZXRlOw0KLQlmcmllbmQgY2xhc3MgQ0ZYRVVfQ2xlYXI7DQotCWZyaWVuZCBjbGFzcyBDRlhFVV9DbGVhclJpY2g7DQotCWZyaWVuZCBjbGFzcyBDRlhFVV9TZXRTZWNQcm9wczsNCi0JZnJpZW5kIGNsYXNzIENGWEVVX1NldFdvcmRQcm9wczsJDQotCWZyaWVuZCBjbGFzcyBDRlhFVV9JbnNlcnRUZXh0Ow0KLQ0KLXB1YmxpYzoNCi0JQ0ZYX0VkaXQoSVBERl9WYXJpYWJsZVRleHQgKiBwVlQpOw0KLQl2aXJ0dWFsIH5DRlhfRWRpdCgpOw0KLQ0KLQl2b2lkCQkJCQkJCQkJU2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApOwkNCi0Jdm9pZAkJCQkJCQkJCVNldFZUUHJvdmlkZXIoSVBERl9WYXJpYWJsZVRleHRfUHJvdmlkZXIqIHBQcm92aWRlcik7DQotCXZvaWQJCQkJCQkJCQlTZXROb3RpZnkoSUZYX0VkaXRfTm90aWZ5ICogcE5vdGlmeSk7DQotCXZvaWQJCQkJCQkJCQlTZXRPcHJOb3RpZnkoSUZYX0VkaXRfT3ByTm90aWZ5KiBwT3ByTm90aWZ5KTsNCi0JSUZYX0VkaXRfSXRlcmF0b3IqCQkJCQkJR2V0SXRlcmF0b3IoKTsNCi0JSVBERl9WYXJpYWJsZVRleHQgKgkJCQkJCUdldFZhcmlhYmxlVGV4dCgpOw0KLQlJRlhfRWRpdF9Gb250TWFwKgkJCQkJCUdldEZvbnRNYXAoKTsNCi0NCi0Jdm9pZAkJCQkJCQkJCUluaXRpYWxpemUoKTsNCi0Jdm9pZAkJCQkJCQkJCVNldFBsYXRlUmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0LCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQl2b2lkCQkJCQkJCQkJU2V0U2Nyb2xsUG9zKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7DQotDQotCXZvaWQJCQkJCQkJCQlTZXRBbGlnbm1lbnRIKEZYX0lOVDMyIG5Gb3JtYXQgPSAwLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQl2b2lkCQkJCQkJCQkJU2V0QWxpZ25tZW50VihGWF9JTlQzMiBuRm9ybWF0ID0gMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsNCi0Jdm9pZAkJCQkJCQkJCVNldFBhc3N3b3JkQ2hhcihGWF9XT1JEIHdTdWJXb3JkID0gJyonLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQl2b2lkCQkJCQkJCQkJU2V0TGltaXRDaGFyKEZYX0lOVDMyIG5MaW1pdENoYXIgPSAwLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQl2b2lkCQkJCQkJCQkJU2V0Q2hhckFycmF5KEZYX0lOVDMyIG5DaGFyQXJyYXkgPSAwLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQl2b2lkCQkJCQkJCQkJU2V0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UgPSAwLjBmLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQl2b2lkCQkJCQkJCQkJU2V0SG9yelNjYWxlKEZYX0lOVDMyIG5Ib3J6U2NhbGUgPSAxMDAsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7DQotCXZvaWQJCQkJCQkJCQlTZXRMaW5lTGVhZGluZyhGWF9GTE9BVCBmTGluZUxlYWRpbmcsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7DQotCXZvaWQJCQkJCQkJCQlTZXRNdWx0aUxpbmUoRlhfQk9PTCBiTXVsdGlMaW5lID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsNCi0Jdm9pZAkJCQkJCQkJCVNldEF1dG9SZXR1cm4oRlhfQk9PTCBiQXV0byA9IFRSVUUsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7DQotCXZvaWQJCQkJCQkJCQlTZXRBdXRvRm9udFNpemUoRlhfQk9PTCBiQXV0byA9IFRSVUUsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7CQ0KLQl2b2lkCQkJCQkJCQkJU2V0QXV0b1Njcm9sbChGWF9CT09MIGJBdXRvID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsJDQotCXZvaWQJCQkJCQkJCQlTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7DQotCXZvaWQJCQkJCQkJCQlTZXRUZXh0T3ZlcmZsb3coRlhfQk9PTCBiQWxsb3dlZCA9IEZBTFNFLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQ0KLQlGWF9CT09MCQkJCQkJCQkJSXNSaWNoVGV4dCgpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCQkJU2V0UmljaFRleHQoRlhfQk9PTCBiUmljaFRleHQgPSBUUlVFLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQlGWF9CT09MCQkJCQkJCQkJU2V0UmljaEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSk7CQ0KLQlGWF9CT09MCQkJCQkJCQkJU2V0UmljaEZvbnRJbmRleChGWF9JTlQzMiBuRm9udEluZGV4KTsNCi0JRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0Q29sb3IoRlhfQ09MT1JSRUYgZHdDb2xvcik7DQotCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dFNjcmlwdChGWF9JTlQzMiBuU2NyaXB0VHlwZSk7DQotCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dEJvbGQoRlhfQk9PTCBiQm9sZCA9IFRSVUUpOwkNCi0JRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0SXRhbGljKEZYX0JPT0wgYkl0YWxpYyA9IFRSVUUpOw0KLQlGWF9CT09MCQkJCQkJCQkJU2V0UmljaFRleHRVbmRlcmxpbmUoRlhfQk9PTCBiVW5kZXJsaW5lID0gVFJVRSk7DQotCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dENyb3Nzb3V0KEZYX0JPT0wgYkNyb3Nzb3V0ID0gVFJVRSk7DQotCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlKTsNCi0JRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0SG9yelNjYWxlKEZYX0lOVDMyIG5Ib3J6U2NhbGUgPSAxMDApOw0KLQlGWF9CT09MCQkJCQkJCQkJU2V0UmljaFRleHRMaW5lTGVhZGluZyhGWF9GTE9BVCBmTGluZUxlYWRpbmcpOw0KLQlGWF9CT09MCQkJCQkJCQkJU2V0UmljaFRleHRMaW5lSW5kZW50KEZYX0ZMT0FUIGZMaW5lSW5kZW50KTsNCi0JRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0QWxpZ25tZW50KEZYX0lOVDMyIG5BbGlnbm1lbnQpOw0KLQ0KLQl2b2lkCQkJCQkJCQkJT25Nb3VzZURvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOw0KLQl2b2lkCQkJCQkJCQkJT25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOw0KLQl2b2lkCQkJCQkJCQkJT25WS19VUChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsNCi0Jdm9pZAkJCQkJCQkJCU9uVktfRE9XTihGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsNCi0Jdm9pZAkJCQkJCQkJCU9uVktfTEVGVChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsNCi0Jdm9pZAkJCQkJCQkJCU9uVktfUklHSFQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7DQotCXZvaWQJCQkJCQkJCQlPblZLX0hPTUUoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7DQotCXZvaWQJCQkJCQkJCQlPblZLX0VORChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsNCi0NCi0Jdm9pZAkJCQkJCQkJCVNldFRleHQoRlhfTFBDV1NUUiB0ZXh0LEZYX0lOVDMyIGNoYXJzZXQgPSBERUZBVUxUX0NIQVJTRVQsDQotCQkJCQkJCQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMgPSBOVUxMLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyA9IE5VTEwpOwkNCi0JRlhfQk9PTAkJCQkJCQkJCUluc2VydFdvcmQoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VULCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMgPSBOVUxMKTsNCi0JRlhfQk9PTAkJCQkJCQkJCUluc2VydFJldHVybihjb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzID0gTlVMTCxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMgPSBOVUxMKTsNCi0JRlhfQk9PTAkJCQkJCQkJCUJhY2tzcGFjZSgpOw0KLQlGWF9CT09MCQkJCQkJCQkJRGVsZXRlKCk7CQkNCi0JRlhfQk9PTAkJCQkJCQkJCUNsZWFyKCk7DQotCUZYX0JPT0wJCQkJCQkJCQlFbXB0eSgpOw0KLQlGWF9CT09MCQkJCQkJCQkJSW5zZXJ0VGV4dChGWF9MUENXU1RSIHRleHQsIEZYX0lOVDMyIGNoYXJzZXQgPSBERUZBVUxUX0NIQVJTRVQsDQotCQkJCQkJCQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMgPSBOVUxMLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyA9IE5VTEwpOw0KLQlGWF9CT09MCQkJCQkJCQkJUmVkbygpOw0KLQlGWF9CT09MCQkJCQkJCQkJVW5kbygpOwkNCi0JQ1BWVF9Xb3JkUGxhY2UJCQkJCQkJRG9JbnNlcnRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgRlhfTFBDV1NUUiB0ZXh0LCBGWF9JTlQzMiBjaGFyc2V0LCANCi0JCQkJCQkJCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpOw0KLQlGWF9JTlQzMgkJCQkJCQkJR2V0Q2hhclNldEZyb21Vbmljb2RlKEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgbk9sZENoYXJzZXQpOw0KLQ0KLQlGWF9JTlQzMgkJCQkJCQkJV29yZFBsYWNlVG9Xb3JkSW5kZXgoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7DQotCUNQVlRfV29yZFBsYWNlCQkJCQkJCVdvcmRJbmRleFRvV29yZFBsYWNlKEZYX0lOVDMyIGluZGV4KSBjb25zdDsJDQotDQotCUNQVlRfV29yZFBsYWNlCQkJCQkJCUdldExpbmVCZWdpblBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0Ow0KLQlDUFZUX1dvcmRQbGFjZQkJCQkJCQlHZXRMaW5lRW5kUGxhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7DQotCUNQVlRfV29yZFBsYWNlCQkJCQkJCUdldFNlY3Rpb25CZWdpblBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0Ow0KLQlDUFZUX1dvcmRQbGFjZQkJCQkJCQlHZXRTZWN0aW9uRW5kUGxhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7DQotCUNQVlRfV29yZFBsYWNlCQkJCQkJCVNlYXJjaFdvcmRQbGFjZShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3Q7DQotDQotCUZYX0lOVDMyCQkJCQkJCQlHZXRDYXJldCgpIGNvbnN0Ow0KLQlDUFZUX1dvcmRQbGFjZQkJCQkJCQlHZXRDYXJldFdvcmRQbGFjZSgpIGNvbnN0Ow0KLQlDRlhfV2lkZVN0cmluZwkJCQkJCQlHZXRTZWxUZXh0KCkgY29uc3Q7DQotCUNGWF9XaWRlU3RyaW5nCQkJCQkJCUdldFRleHQoKSBjb25zdDsNCi0JRlhfRkxPQVQJCQkJCQkJCUdldEZvbnRTaXplKCkgY29uc3Q7DQotCUZYX1dPUkQJCQkJCQkJCQlHZXRQYXNzd29yZENoYXIoKSBjb25zdDsNCi0JQ1BERl9Qb2ludAkJCQkJCQkJR2V0U2Nyb2xsUG9zKCkgY29uc3Q7DQotCUZYX0lOVDMyCQkJCQkJCQlHZXRDaGFyQXJyYXkoKSBjb25zdDsNCi0JQ1BERl9SZWN0CQkJCQkJCQlHZXRQbGF0ZVJlY3QoKSBjb25zdDsNCi0JQ1BERl9SZWN0CQkJCQkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0Ow0KLQlDRlhfV2lkZVN0cmluZwkJCQkJCQlHZXRSYW5nZVRleHQoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiByYW5nZSkgY29uc3Q7DQotCUZYX0lOVDMyCQkJCQkJCQlHZXRIb3J6U2NhbGUoKSBjb25zdDsNCi0JRlhfRkxPQVQJCQkJCQkJCUdldENoYXJTcGFjZSgpIGNvbnN0Ow0KLQlGWF9JTlQzMgkJCQkJCQkJR2V0VG90YWxXb3JkcygpIGNvbnN0Ow0KLQlGWF9JTlQzMgkJCQkJCQkJR2V0VG90YWxMaW5lcygpIGNvbnN0Ow0KLQ0KLQl2b2lkCQkJCQkJCQkJU2V0U2VsKEZYX0lOVDMyIG5TdGFydENoYXIsRlhfSU5UMzIgbkVuZENoYXIpOw0KLQl2b2lkCQkJCQkJCQkJR2V0U2VsKEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhcikgY29uc3Q7DQotDQotcHJpdmF0ZToNCi0Jdm9pZAkJCQkJCQkJCVNlbGVjdEFsbCgpOw0KLQl2b2lkCQkJCQkJCQkJU2VsZWN0Tm9uZSgpOw0KLQl2b2lkCQkJCQkJCQkJU2V0U2VsKGNvbnN0IENQVlRfV29yZFBsYWNlICYgYmVnaW4sY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBlbmQpOw0KLQlGWF9CT09MCQkJCQkJCQkJSXNTZWxlY3RlZCgpIGNvbnN0Ow0KLQ0KLQl2b2lkCQkJCQkJCQkJUmVhcnJhbmdlQWxsKCk7DQotCXZvaWQJCQkJCQkJCQlSZWFycmFuZ2VQYXJ0KGNvbnN0IENQVlRfV29yZFJhbmdlICYgcmFuZ2UpOw0KLQl2b2lkCQkJCQkJCQkJUGFpbnQoKTsNCi0Jdm9pZAkJCQkJCQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0Jdm9pZAkJCQkJCQkJCVNldFNjcm9sbEluZm8oKTsNCi0Jdm9pZAkJCQkJCQkJCVNldFNjcm9sbFBvc1goRlhfRkxPQVQgZngpOw0KLQl2b2lkCQkJCQkJCQkJU2V0U2Nyb2xsUG9zWShGWF9GTE9BVCBmeSk7DQotCXZvaWQJCQkJCQkJCQlTZXRTY3JvbGxMaW1pdCgpOw0KLQl2b2lkCQkJCQkJCQkJU2V0Q29udGVudENoYW5nZWQoKTsNCi0Jdm9pZAkJCQkJCQkJCUVuYWJsZU5vdGlmeShGWF9CT09MIGJOb3RpZnkpOw0KLQ0KLQl2b2lkCQkJCQkJCQkJU2V0VGV4dChGWF9MUENXU1RSIHRleHQsRlhfSU5UMzIgY2hhcnNldCwNCi0JCQkJCQkJCQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsRlhfQk9PTCBiQWRkVW5kbywgRlhfQk9PTCBiUGFpbnQpOwkNCi0JRlhfQk9PTAkJCQkJCQkJCUluc2VydFdvcmQoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsRlhfQk9PTCBiQWRkVW5kbywgRlhfQk9PTCBiUGFpbnQpOw0KLQlGWF9CT09MCQkJCQkJCQkJSW5zZXJ0UmV0dXJuKGNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMsY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzLEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KTsNCi0JRlhfQk9PTAkJCQkJCQkJCUJhY2tzcGFjZShGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCk7DQotCUZYX0JPT0wJCQkJCQkJCQlEZWxldGUoRlhfQk9PTCBiQWRkVW5kbywgRlhfQk9PTCBiUGFpbnQpOwkJDQotCUZYX0JPT0wJCQkJCQkJCQlDbGVhcihGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCk7DQotCUZYX0JPT0wJCQkJCQkJCQlJbnNlcnRUZXh0KEZYX0xQQ1dTVFIgdGV4dCwgRlhfSU5UMzIgY2hhcnNldCwNCi0JCQkJCQkJCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyxGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCk7DQotCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dFByb3BzKEVESVRfUFJPUFNfRSBlUHJvcHMsDQotCQkJCQkJCQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzKTsNCi0JRlhfQk9PTAkJCQkJCQkJCVNldFNlY1Byb3BzKEVESVRfUFJPUFNfRSBlUHJvcHMsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UsIA0KLQkJCQkJCQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3ciwgRlhfQk9PTCBiQWRkVW5kbyk7DQotCUZYX0JPT0wJCQkJCQkJCQlTZXRXb3JkUHJvcHMoRURJVF9QUk9QU19FIGVQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSwgDQotCQkJCQkJCQkJCQkJY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyLCBGWF9CT09MIGJBZGRVbmRvKTsNCi0Jdm9pZAkJCQkJCQkJCVBhaW50U2V0UHJvcHMoRURJVF9QUk9QU19FIGVQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3cik7DQotCXZvaWQJCQkJCQkJCQlQYWludEluc2VydFRleHQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ldyk7DQotDQotCWlubGluZSBDUERGX1BvaW50CQkJCQkJVlRUb0VkaXQoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdDsNCi0JaW5saW5lIENQREZfUG9pbnQJCQkJCQlFZGl0VG9WVChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0Ow0KLQlpbmxpbmUgQ1BERl9SZWN0CQkJCQkJVlRUb0VkaXQoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgY29uc3Q7DQotCWlubGluZSBDUERGX1JlY3QJCQkJCQlFZGl0VG9WVChjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdDsNCi0NCi0Jdm9pZAkJCQkJCQkJCUVuYWJsZVJlZnJlc2goRlhfQk9PTCBiUmVmcmVzaCk7DQotCXZvaWQJCQkJCQkJCQlSZWZyZXNoKFJFRlJFU0hfUExBTl9FIGVQbGFuLGNvbnN0IENQVlRfV29yZFJhbmdlICogcFJhbmdlMSA9IE5VTEwsY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UyID0gTlVMTCk7DQotCXZvaWQJCQkJCQkJCQlSZWZyZXNoUHVzaExpbmVSZWN0cyhjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyKTsNCi0Jdm9pZAkJCQkJCQkJCVJlZnJlc2hQdXNoUmFuZG9tUmVjdHMoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3cik7DQotCXZvaWQJCQkJCQkJCQlSZWZyZXNoV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cik7DQotDQotCXZvaWQJCQkJCQkJCQlTZXRDYXJldChGWF9JTlQzMiBuUG9zKTsNCi0Jdm9pZAkJCQkJCQkJCVNldENhcmV0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpOw0KLQl2b2lkCQkJCQkJCQkJU2V0Q2FyZXRJbmZvKCk7DQotCXZvaWQJCQkJCQkJCQlTZXRDYXJldE9yaWdpbigpOw0KLQl2b2lkCQkJCQkJCQkJU2V0Q2FyZXRDaGFuZ2UoKTsNCi0NCi0JQ1BWVF9Xb3JkUmFuZ2UJCQkJCQkJR2V0V2hvbGVXb3JkUmFuZ2UoKSBjb25zdDsNCi0JQ1BWVF9Xb3JkUmFuZ2UJCQkJCQkJR2V0VmlzaWJsZVdvcmRSYW5nZSgpIGNvbnN0Ow0KLQlDUFZUX1dvcmRSYW5nZQkJCQkJCQlHZXRMYXRpbldvcmRzUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7DQotCUNQVlRfV29yZFJhbmdlCQkJCQkJCUNvbWJpbmVXb3JkUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3cjEsIGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IyKTsNCi0JQ1BWVF9Xb3JkUmFuZ2UJCQkJCQkJR2V0U2VsZWN0V29yZFJhbmdlKCkgY29uc3Q7DQotDQotCXZvaWQJCQkJCQkJCQlFbmFibGVVbmRvKEZYX0JPT0wgYlVuZG8pOw0KLQl2b2lkCQkJCQkJCQkJRW5hYmxlT3ByTm90aWZ5KEZYX0JPT0wgYk5vdGlmeSk7DQotDQotCUZYX0JPT0wJCQkJCQkJCQlJc1RleHRGdWxsKCkgY29uc3Q7DQotCUZYX0JPT0wJCQkJCQkJCQlJc1RleHRPdmVyZmxvdygpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCQkJQ2FuVW5kbygpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCQkJQ2FuUmVkbygpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCQkJSXNNb2RpZmllZCgpIGNvbnN0Ow0KLQ0KLQl2b2lkCQkJCQkJCQkJQmVnaW5Hcm91cFVuZG8oY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUaXRsZSk7DQotCXZvaWQJCQkJCQkJCQlFbmRHcm91cFVuZG8oKTsNCi0Jdm9pZAkJCQkJCQkJCUFkZEVkaXRVbmRvSXRlbShDRlhfRWRpdF9VbmRvSXRlbSogcEVkaXRVbmRvSXRlbSk7DQotCXZvaWQJCQkJCQkJCQlBZGRVbmRvSXRlbShJRlhfRWRpdF9VbmRvSXRlbSogcFVuZG9JdGVtKTsNCi0NCi0Jdm9pZAkJCQkJCQkJCVNldFBhZ2VJbmZvKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSk7DQotCUNQVlRfV29yZFBsYWNlCQkJCQkJCVNlYXJjaFBhZ2VFbmRQbGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSYgd3BQYWdlQmVnaW4sIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdDsNCi0JRlhfRkxPQVQJCQkJCQkJCUdldExpbmVUb3AoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlKSBjb25zdDsNCi0JRlhfRkxPQVQJCQkJCQkJCUdldExpbmVCb3R0b20oY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlKSBjb25zdDsNCi0NCi1wcml2YXRlOgkNCi0JSVBERl9WYXJpYWJsZVRleHQqCQkJCQkJbV9wVlQ7DQotCUlGWF9FZGl0X05vdGlmeSoJCQkJCQltX3BOb3RpZnk7DQotCUlGWF9FZGl0X09wck5vdGlmeSoJCQkJCQltX3BPcHJOb3RpZnk7DQotCUNGWF9FZGl0X1Byb3ZpZGVyKgkJCQkJCW1fcFZUUHJvdmlkZTsNCi0NCi0JQ1BWVF9Xb3JkUGxhY2UJCQkJCQkJbV93cENhcmV0Ow0KLQlDUFZUX1dvcmRQbGFjZQkJCQkJCQltX3dwT2xkQ2FyZXQ7DQotCUNGWF9FZGl0X1NlbGVjdAkJCQkJCQltX1NlbFN0YXRlOw0KLQ0KLQlDUERGX1BvaW50CQkJCQkJCQltX3B0U2Nyb2xsUG9zOw0KLQlDUERGX1BvaW50CQkJCQkJCQltX3B0UmVmcmVzaFNjcm9sbFBvczsNCi0JRlhfQk9PTAkJCQkJCQkJCW1fYkVuYWJsZVNjcm9sbDsJDQotCUlGWF9FZGl0X0l0ZXJhdG9yICoJCQkJCQltX3BJdGVyYXRvcjsJDQotCUNGWF9FZGl0X1JlZnJlc2gJCQkJCQltX1JlZnJlc2g7DQotCUNQREZfUG9pbnQJCQkJCQkJCW1fcHRDYXJldDsNCi0JQ0ZYX0VkaXRfVW5kbwkJCQkJCQltX1VuZG87DQotCUZYX0lOVDMyCQkJCQkJCQltX25BbGlnbm1lbnQ7DQotCUZYX0JPT0wJCQkJCQkJCQltX2JOb3RpZnlGbGFnOw0KLQlGWF9CT09MCQkJCQkJCQkJbV9iVGV4dEZ1bGxGbGFnOw0KLQlGWF9CT09MCQkJCQkJCQkJbV9iRW5hYmxlT3ZlcmZsb3c7DQotCUZYX0JPT0wJCQkJCQkJCQltX2JFbmFibGVSZWZyZXNoOw0KLQlDUERGX1JlY3QJCQkJCQkJCW1fcmNPbGRDb250ZW50Ow0KLQlGWF9CT09MCQkJCQkJCQkJbV9iRW5hYmxlVW5kbzsNCi0JRlhfQk9PTAkJCQkJCQkJCW1fYk5vdGlmeTsNCi0JRlhfQk9PTAkJCQkJCQkJCW1fYk9wck5vdGlmeTsNCi0JQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbSoJCQkJCW1fcEdyb3VwVW5kb0l0ZW07DQotfTsNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X0l0ZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1jbGFzcyBDRlhfRWRpdF9JdGVyYXRvciA6IHB1YmxpYyBJRlhfRWRpdF9JdGVyYXRvcg0KLXsNCi1wdWJsaWM6DQotCUNGWF9FZGl0X0l0ZXJhdG9yKENGWF9FZGl0ICogcEVkaXQsSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwVlRJdGVyYXRvcik7DQotCXZpcnR1YWwgfkNGWF9FZGl0X0l0ZXJhdG9yKCk7DQotDQotCUZYX0JPT0wJCQkJCQkJCQlOZXh0V29yZCgpOw0KLQlGWF9CT09MCQkJCQkJCQkJTmV4dExpbmUoKTsNCi0JRlhfQk9PTAkJCQkJCQkJCU5leHRTZWN0aW9uKCk7DQotCUZYX0JPT0wJCQkJCQkJCQlQcmV2V29yZCgpOw0KLQlGWF9CT09MCQkJCQkJCQkJUHJldkxpbmUoKTsNCi0JRlhfQk9PTAkJCQkJCQkJCVByZXZTZWN0aW9uKCk7DQotDQotCUZYX0JPT0wJCQkJCQkJCQlHZXRXb3JkKENQVlRfV29yZCAmIHdvcmQpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCQkJR2V0TGluZShDUFZUX0xpbmUgJiBsaW5lKSBjb25zdDsNCi0JRlhfQk9PTAkJCQkJCQkJCUdldFNlY3Rpb24oQ1BWVF9TZWN0aW9uICYgc2VjdGlvbikgY29uc3Q7DQotCXZvaWQJCQkJCQkJCQlTZXRBdChGWF9JTlQzMiBuV29yZEluZGV4KTsNCi0Jdm9pZAkJCQkJCQkJCVNldEF0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpOw0KLQljb25zdCBDUFZUX1dvcmRQbGFjZSAmCQkJCQlHZXRBdCgpIGNvbnN0Ow0KLQlJRlhfRWRpdCoJCQkJCQkJCUdldEVkaXQoKSBjb25zdDsNCi0NCi1wcml2YXRlOg0KLQlDRlhfRWRpdCAqCQkJCQkJCQltX3BFZGl0Ow0KLQlJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvcioJCQkJbV9wVlRJdGVyYXRvcjsNCi19Ow0KLQ0KLWNsYXNzIENGWF9FZGl0X1Byb3ZpZGVyIDogcHVibGljIElQREZfVmFyaWFibGVUZXh0X1Byb3ZpZGVyDQotew0KLXB1YmxpYzoNCi0JQ0ZYX0VkaXRfUHJvdmlkZXIoSUZYX0VkaXRfRm9udE1hcCogcEZvbnRNYXApOw0KLQl2aXJ0dWFsIH5DRlhfRWRpdF9Qcm92aWRlcigpOw0KLQ0KLQlJRlhfRWRpdF9Gb250TWFwKgkJCUdldEZvbnRNYXAoKTsNCi0NCi0JRlhfSU5UMzIJCQkJCUdldENoYXJXaWR0aChGWF9JTlQzMiBuRm9udEluZGV4LCBGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIG5Xb3JkU3R5bGUpOw0KLQlGWF9JTlQzMgkJCQkJR2V0VHlwZUFzY2VudChGWF9JTlQzMiBuRm9udEluZGV4KTsNCi0JRlhfSU5UMzIJCQkJCUdldFR5cGVEZXNjZW50KEZYX0lOVDMyIG5Gb250SW5kZXgpOw0KLQlGWF9JTlQzMgkJCQkJR2V0V29yZEZvbnRJbmRleChGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIGNoYXJzZXQsIEZYX0lOVDMyIG5Gb250SW5kZXgpOw0KLQlGWF9JTlQzMgkJCQkJR2V0RGVmYXVsdEZvbnRJbmRleCgpOw0KLQlGWF9CT09MCQkJCQkJSXNMYXRpbldvcmQoRlhfV09SRCB3b3JkKTsNCi0NCi1wcml2YXRlOg0KLQlJRlhfRWRpdF9Gb250TWFwKgkJCW1fcEZvbnRNYXA7DQotfTsNCi0NCi0jZW5kaWYgLy9fRlhFVF9FRElUX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRlhFVF9FRElUX0hfCisjZGVmaW5lIF9GWEVUX0VESVRfSF8KKworI2luY2x1ZGUgImZ4X2VkaXQuaCIKKworY2xhc3MgQ0ZYX0VkaXRfUGFnZTsKK3N0cnVjdCBDRlhfRWRpdF9MaW5lUmVjdDsKK2NsYXNzIENGWF9FZGl0X0xpbmVSZWN0QXJyYXk7CitjbGFzcyBDRlhfRWRpdF9SZWN0QXJyYXk7CitjbGFzcyBDRlhfRWRpdF9SZWZyZXNoOworY2xhc3MgQ0ZYX0VkaXRfU2VsZWN0OworY2xhc3MgQ0ZYX0VkaXQ7CitjbGFzcyBDRlhfRWRpdF9JdGVyYXRvcjsKK2NsYXNzIENGWF9FZGl0X1JlZnJlc2g7CitjbGFzcyBDRlhfRWRpdF9VbmRvSXRlbTsKK2NsYXNzIENGWF9FZGl0X1VuZG87CitjbGFzcyBDRlhfRWRpdF9Qcm92aWRlcjsKKworI2RlZmluZSBGWF9FRElUX0lzRmxvYXRaZXJvKGYpCQkJCQkJKGYgPCAwLjAwMDEgJiYgZiA+IC0wLjAwMDEpCisjZGVmaW5lIEZYX0VESVRfSXNGbG9hdEVxdWFsKGZhLGZiKQkJCQkJRlhfRURJVF9Jc0Zsb2F0WmVybyhmYSAtIGZiKQorI2RlZmluZSBGWF9FRElUX0lzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCShmYSA+IGZiICYmICFGWF9FRElUX0lzRmxvYXRFcXVhbChmYSxmYikpCisjZGVmaW5lIEZYX0VESVRfSXNGbG9hdFNtYWxsZXIoZmEsZmIpCQkJCShmYSA8IGZiICYmICFGWF9FRElUX0lzRmxvYXRFcXVhbChmYSxmYikpCisKK3RlbXBsYXRlPGNsYXNzIFQ+IFQgRlhfRURJVF9NSU4gKGNvbnN0IFQgJiBpLCBjb25zdCBUICYgaikgeyByZXR1cm4gKChpIDwgaikgPyBpIDogaik7IH0KK3RlbXBsYXRlPGNsYXNzIFQ+IFQgRlhfRURJVF9NQVggKGNvbnN0IFQgJiBpLCBjb25zdCBUICYgaikgeyByZXR1cm4gKChpID4gaikgPyBpIDogaik7IH0KKworI2RlZmluZQlGWF9FRElUX1BJCQkJCQkJCQkJMy4xNDE1OTI2NTM1ODk3OWYKKyNkZWZpbmUgRlhfRURJVF9JVEFMSUNfQU5HRUwJCQkJCQkxMCAqIEZYX0VESVRfUEkgLyAxODAuMGYKKworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X1JlZnJlc2ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitlbnVtIFJFRlJFU0hfUExBTl9FCit7CisJUlBfQU5BTFlTRSwKKwlSUF9OT0FOQUxZU0UsCisJUlBfT1BUSU9OQUwKK307CisKK2VudW0gRURJVF9QUk9QU19FCit7CisJRVBfTElORUxFQURJTkcsCisJRVBfTElORUlOREVOVCwKKwlFUF9BTElHTk1FTlQsCisJRVBfRk9OVElOREVYLAorCUVQX0ZPTlRTSVpFLAorCUVQX1dPUkRDT0xPUiwKKwlFUF9TQ1JJUFRUWVBFLAorCUVQX1VOREVSTElORSwKKwlFUF9DUk9TU09VVCwKKwlFUF9DSEFSU1BBQ0UsCisJRVBfSE9SWlNDQUxFLAorCUVQX0JPTEQsCisJRVBfSVRBTElDCit9OworCitzdHJ1Y3QgQ0ZYX0VkaXRfTGluZVJlY3QKK3sKKwlDRlhfRWRpdF9MaW5lUmVjdChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyTGluZSxjb25zdCBDUERGX1JlY3QgJiByY0xpbmUpIDoKKwkJbV93ckxpbmUod3JMaW5lKSwgbV9yY0xpbmUocmNMaW5lKQorCXsKKwl9CisKKwlGWF9CT09MIG9wZXJhdG9yICE9IChjb25zdCBDRlhfRWRpdF9MaW5lUmVjdCAmIGxpbmVyZWN0KSBjb25zdAorCXsKKwkJcmV0dXJuIEZYU1lTX21lbWNtcCh0aGlzLCAmbGluZXJlY3QsIHNpemVvZihDRlhfRWRpdF9MaW5lUmVjdCkpICE9IDA7CisJfQorCisJRlhfQk9PTCBJc1NhbWVIZWlnaHQoY29uc3QgQ0ZYX0VkaXRfTGluZVJlY3QgJiBsaW5lcmVjdCkgY29uc3QKKwl7CisJCXJldHVybiBGWF9FRElUX0lzRmxvYXRaZXJvKChtX3JjTGluZS50b3AgLSBtX3JjTGluZS5ib3R0b20pIC0gKGxpbmVyZWN0Lm1fcmNMaW5lLnRvcCAtbGluZXJlY3QubV9yY0xpbmUuYm90dG9tKSk7CisJfQorCisJRlhfQk9PTCBJc1NhbWVUb3AoY29uc3QgQ0ZYX0VkaXRfTGluZVJlY3QgJiBsaW5lcmVjdCkgY29uc3QKKwl7CisJCXJldHVybiBGWF9FRElUX0lzRmxvYXRaZXJvKG1fcmNMaW5lLnRvcCAtIGxpbmVyZWN0Lm1fcmNMaW5lLnRvcCk7CisJfQorCisJRlhfQk9PTCBJc1NhbWVMZWZ0KGNvbnN0IENGWF9FZGl0X0xpbmVSZWN0ICYgbGluZXJlY3QpIGNvbnN0CisJeworCQlyZXR1cm4gRlhfRURJVF9Jc0Zsb2F0WmVybyhtX3JjTGluZS5sZWZ0IC0gbGluZXJlY3QubV9yY0xpbmUubGVmdCk7CisJfQorCisJRlhfQk9PTCBJc1NhbWVSaWdodChjb25zdCBDRlhfRWRpdF9MaW5lUmVjdCAmIGxpbmVyZWN0KSBjb25zdAorCXsKKwkJcmV0dXJuIEZYX0VESVRfSXNGbG9hdFplcm8obV9yY0xpbmUucmlnaHQgLSBsaW5lcmVjdC5tX3JjTGluZS5yaWdodCk7CisJfQorCisJQ1BWVF9Xb3JkUmFuZ2UJCQkJCQkJbV93ckxpbmU7CisJQ1BERl9SZWN0CQkJCQkJCQltX3JjTGluZTsKK307CisKK2NsYXNzIENGWF9FZGl0X0xpbmVSZWN0QXJyYXkKK3sKK3B1YmxpYzoKKwlDRlhfRWRpdF9MaW5lUmVjdEFycmF5KCkKKwl7CisJfQorCisJdmlydHVhbCB+Q0ZYX0VkaXRfTGluZVJlY3RBcnJheSgpCisJeworCQlFbXB0eSgpOworCX0KKworCXZvaWQgRW1wdHkoKQorCXsKKwkJZm9yIChGWF9JTlQzMiBpID0gMCwgc3ogPSBtX0xpbmVSZWN0cy5HZXRTaXplKCk7IGkgPCBzejsgaSsrKQorCQkJZGVsZXRlIG1fTGluZVJlY3RzLkdldEF0KGkpOworCisJCW1fTGluZVJlY3RzLlJlbW92ZUFsbCgpOworCX0KKworCXZvaWQgUmVtb3ZlQWxsKCkKKwl7CisJCW1fTGluZVJlY3RzLlJlbW92ZUFsbCgpOworCX0KKworCXZvaWQgb3BlcmF0b3IgPSAoQ0ZYX0VkaXRfTGluZVJlY3RBcnJheSAmIHJlY3RzKQorCXsKKwkJRW1wdHkoKTsKKwkJZm9yIChGWF9JTlQzMiBpID0gMCwgc3ogPSByZWN0cy5HZXRTaXplKCk7IGkgPCBzejsgaSsrKQorCQkJbV9MaW5lUmVjdHMuQWRkKHJlY3RzLkdldEF0KGkpKTsKKworCQlyZWN0cy5SZW1vdmVBbGwoKTsKKwl9CisKKwl2b2lkIEFkZChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyTGluZSxjb25zdCBDUERGX1JlY3QgJiByY0xpbmUpCisJeworCQlpZiAoQ0ZYX0VkaXRfTGluZVJlY3QgKiBwUmVjdCA9IG5ldyBDRlhfRWRpdF9MaW5lUmVjdCh3ckxpbmUscmNMaW5lKSkKKwkJCW1fTGluZVJlY3RzLkFkZChwUmVjdCk7CisJfQorCisJRlhfSU5UMzIgR2V0U2l6ZSgpIGNvbnN0CisJeworCQlyZXR1cm4gbV9MaW5lUmVjdHMuR2V0U2l6ZSgpOworCX0KKworCUNGWF9FZGl0X0xpbmVSZWN0ICogR2V0QXQoRlhfSU5UMzIgbkluZGV4KSBjb25zdAorCXsKKwkJaWYgKG5JbmRleCA8IDAgfHwgbkluZGV4ID49IG1fTGluZVJlY3RzLkdldFNpemUoKSkKKwkJCXJldHVybiBOVUxMOworCisJCXJldHVybiBtX0xpbmVSZWN0cy5HZXRBdChuSW5kZXgpOworCX0KKworCUNGWF9BcnJheVRlbXBsYXRlPENGWF9FZGl0X0xpbmVSZWN0Kj4JCW1fTGluZVJlY3RzOworfTsKKworY2xhc3MgQ0ZYX0VkaXRfUmVjdEFycmF5Cit7CitwdWJsaWM6CisJQ0ZYX0VkaXRfUmVjdEFycmF5KCkKKwl7CisJfQorCisJdmlydHVhbCB+Q0ZYX0VkaXRfUmVjdEFycmF5KCkKKwl7CisJCXRoaXMtPkVtcHR5KCk7CisJfQorCisJdm9pZCBFbXB0eSgpCisJeworCQlmb3IgKEZYX0lOVDMyIGkgPSAwLCBzeiA9IG1fUmVjdHMuR2V0U2l6ZSgpOyBpIDwgc3o7IGkrKykKKwkJCWRlbGV0ZSBtX1JlY3RzLkdldEF0KGkpOworCisJCXRoaXMtPm1fUmVjdHMuUmVtb3ZlQWxsKCk7CisJfQorCisJdm9pZCBBZGQoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkKKwl7CisJCS8vY2hlY2sgZm9yIG92ZXJsYXBlZCBhcmVhCisJCWZvciAoRlhfSU5UMzIgaSA9IDAsIHN6ID0gbV9SZWN0cy5HZXRTaXplKCk7IGkgPCBzejsgaSsrKQorCQkJaWYgKENQREZfUmVjdCAqIHBSZWN0ID0gbV9SZWN0cy5HZXRBdChpKSkKKwkJCQlpZiAocFJlY3QtPkNvbnRhaW5zKHJlY3QpKXJldHVybjsKKworCQlpZiAoQ1BERl9SZWN0ICogcE5ld1JlY3QgPSBuZXcgQ1BERl9SZWN0KHJlY3QpKQorCQkJbV9SZWN0cy5BZGQocE5ld1JlY3QpOworCX0KKworCUZYX0lOVDMyIEdldFNpemUoKSBjb25zdAorCXsKKwkJcmV0dXJuIG1fUmVjdHMuR2V0U2l6ZSgpOworCX0KKworCUNQREZfUmVjdCAqIEdldEF0KEZYX0lOVDMyIG5JbmRleCkgY29uc3QKKwl7CisJCWlmIChuSW5kZXggPCAwIHx8IG5JbmRleCA+PSBtX1JlY3RzLkdldFNpemUoKSkKKwkJCXJldHVybiBOVUxMOworCisJCXJldHVybiBtX1JlY3RzLkdldEF0KG5JbmRleCk7CisJfQorCisJQ0ZYX0FycmF5VGVtcGxhdGU8Q1BERl9SZWN0Kj4JCQltX1JlY3RzOworfTsKKworY2xhc3MgQ0ZYX0VkaXRfUmVmcmVzaAoreworcHVibGljOgorCUNGWF9FZGl0X1JlZnJlc2goKTsKKwl2aXJ0dWFsIH5DRlhfRWRpdF9SZWZyZXNoKCk7CisKKwl2b2lkCQkJCQkJCQkJQmVnaW5SZWZyZXNoKCk7CisJdm9pZAkJCQkJCQkJCVB1c2goY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiBsaW5lcmFuZ2UsY29uc3QgQ1BERl9SZWN0ICYgcmVjdCk7CisJdm9pZAkJCQkJCQkJCU5vQW5hbHlzZSgpOworCXZvaWQJCQkJCQkJCQlBbmFseXNlKEZYX0lOVDMyIG5BbGlnbm1lbnQpOworCXZvaWQJCQkJCQkJCQlBZGRSZWZyZXNoKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpOworCWNvbnN0IENGWF9FZGl0X1JlY3RBcnJheSAqCQkJCUdldFJlZnJlc2hSZWN0cygpIGNvbnN0OworCXZvaWQJCQkJCQkJCQlFbmRSZWZyZXNoKCk7CisKK3ByaXZhdGU6CisJQ0ZYX0VkaXRfTGluZVJlY3RBcnJheQkJCQkJbV9OZXdMaW5lUmVjdHM7CisJQ0ZYX0VkaXRfTGluZVJlY3RBcnJheQkJCQkJbV9PbGRMaW5lUmVjdHM7CisJQ0ZYX0VkaXRfUmVjdEFycmF5CQkJCQkJbV9SZWZyZXNoUmVjdHM7Cit9OworCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0VkaXRfU2VsZWN0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworY2xhc3MgQ0ZYX0VkaXRfU2VsZWN0Cit7CitwdWJsaWM6CisJQ0ZYX0VkaXRfU2VsZWN0KCkKKwl7CisJfQorCisJQ0ZYX0VkaXRfU2VsZWN0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgYmVnaW4sY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBlbmQpCisJeworCQlTZXQoYmVnaW4sZW5kKTsKKwl9CisKKwlDRlhfRWRpdF9TZWxlY3QoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiByYW5nZSkKKwl7CisJCVNldChyYW5nZS5CZWdpblBvcyxyYW5nZS5FbmRQb3MpOworCX0KKworCUNQVlRfV29yZFJhbmdlIENvbnZlcnRUb1dvcmRSYW5nZSgpIGNvbnN0CisJeworCQlyZXR1cm4gQ1BWVF9Xb3JkUmFuZ2UodGhpcy0+QmVnaW5Qb3MsdGhpcy0+RW5kUG9zKTsKKwl9CisKKwl2b2lkIERlZmF1bHQoKQorCXsKKwkJQmVnaW5Qb3MuRGVmYXVsdCgpOworCQlFbmRQb3MuRGVmYXVsdCgpOworCX0KKworCXZvaWQgU2V0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgYmVnaW4sY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBlbmQpCisJeworCQl0aGlzLT5CZWdpblBvcyA9IGJlZ2luOworCQl0aGlzLT5FbmRQb3MgPSBlbmQ7CisJfQorCisJdm9pZCBTZXRCZWdpblBvcyhjb25zdCBDUFZUX1dvcmRQbGFjZSAmIGJlZ2luKQorCXsKKwkJdGhpcy0+QmVnaW5Qb3MgPSBiZWdpbjsKKwl9CisKKwl2b2lkIFNldEVuZFBvcyhjb25zdCBDUFZUX1dvcmRQbGFjZSAmIGVuZCkKKwl7CisJCXRoaXMtPkVuZFBvcyA9IGVuZDsKKwl9CisKKwlGWF9CT09MIElzRXhpc3QoKSBjb25zdAorCXsKKwkJcmV0dXJuIHRoaXMtPkJlZ2luUG9zICE9IHRoaXMtPkVuZFBvczsKKwl9CisKKwlGWF9CT09MIG9wZXJhdG9yICE9IChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyKSBjb25zdAorCXsKKwkJcmV0dXJuIHdyLkJlZ2luUG9zICE9IHRoaXMtPkJlZ2luUG9zIHx8IHdyLkVuZFBvcyAhPSB0aGlzLT5FbmRQb3M7CisJfQorCisJQ1BWVF9Xb3JkUGxhY2UgQmVnaW5Qb3MsRW5kUG9zOworfTsKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdF9VbmRvIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworY2xhc3MgQ0ZYX0VkaXRfVW5kbworeworcHVibGljOgorCUNGWF9FZGl0X1VuZG8oRlhfSU5UMzIgbkJ1ZnNpemUgPSAxMDAwMCk7CisJdmlydHVhbCB+Q0ZYX0VkaXRfVW5kbygpOworCisJdm9pZAkJCQkJCQkJCVVuZG8oKTsKKwl2b2lkCQkJCQkJCQkJUmVkbygpOworCisJdm9pZAkJCQkJCQkJCUFkZEl0ZW0oSUZYX0VkaXRfVW5kb0l0ZW0qIHBJdGVtKTsKKworCUZYX0JPT0wJCQkJCQkJCQlDYW5VbmRvKCkgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQkJCUNhblJlZG8oKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCQkJSXNNb2RpZmllZCgpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJCQlJc1dvcmtpbmcoKSBjb25zdDsKKworCXZvaWQJCQkJCQkJCQlSZXNldCgpOworCisJSUZYX0VkaXRfVW5kb0l0ZW0qCQkJCQkJR2V0SXRlbShGWF9JTlQzMiBuSW5kZXgpOworCUZYX0lOVDMyCQkJCQkJCQlHZXRJdGVtQ291bnQoKXtyZXR1cm4gbV9VbmRvSXRlbVN0YWNrLkdldFNpemUoKTt9CisJRlhfSU5UMzIJCQkJCQkJCUdldEN1clVuZG9Qb3MoKXtyZXR1cm4gbV9uQ3VyVW5kb1Bvczt9CisKK3ByaXZhdGU6CisJdm9pZAkJCQkJCQkJCVNldEJ1ZlNpemUoRlhfSU5UMzIgblNpemUpe21fbkJ1ZlNpemUgPSBuU2l6ZTt9CisJRlhfSU5UMzIJCQkJCQkJCUdldEJ1ZlNpemUoKXtyZXR1cm4gbV9uQnVmU2l6ZTt9CisKKwl2b2lkCQkJCQkJCQkJUmVtb3ZlSGVhZHMoKTsKKwl2b2lkCQkJCQkJCQkJUmVtb3ZlVGFpbHMoKTsKKworcHJpdmF0ZToKKwlDRlhfQXJyYXlUZW1wbGF0ZTxJRlhfRWRpdF9VbmRvSXRlbSo+CW1fVW5kb0l0ZW1TdGFjazsKKwkKKwlGWF9JTlQzMgkJCQkJCQkJbV9uQ3VyVW5kb1BvczsKKwlGWF9JTlQzMgkJCQkJCQkJbV9uQnVmU2l6ZTsKKwlGWF9CT09MCQkJCQkJCQkJbV9iTW9kaWZpZWQ7IAorCUZYX0JPT0wJCQkJCQkJCQltX2JWaXJnaW47CisJRlhfQk9PTAkJCQkJCQkJCW1fYldvcmtpbmc7Cit9OworCitjbGFzcyBDRlhfRWRpdF9VbmRvSXRlbSA6IHB1YmxpYyBJRlhfRWRpdF9VbmRvSXRlbQoreworcHVibGljOgorCUNGWF9FZGl0X1VuZG9JdGVtKCkgOiBtX2JGaXJzdChUUlVFKSwgbV9iTGFzdChUUlVFKSB7fQorCXZpcnR1YWwgfkNGWF9FZGl0X1VuZG9JdGVtKCl7fQorCisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJR2V0VW5kb1RpdGxlKCkge3JldHVybiBMIiI7fQorCXZpcnR1YWwgdm9pZAkJCQkJCQlSZWxlYXNlKCl7ZGVsZXRlIHRoaXM7fQorCitwdWJsaWM6CisJdm9pZAkJCQkJCQkJCVNldEZpcnN0KEZYX0JPT0wgYkZpcnN0KXttX2JGaXJzdCA9IGJGaXJzdDt9CisJRlhfQk9PTAkJCQkJCQkJCUlzRmlyc3QoKXtyZXR1cm4gbV9iRmlyc3Q7fQorCXZvaWQJCQkJCQkJCQlTZXRMYXN0KEZYX0JPT0wgYkxhc3Qpe21fYkxhc3QgPSBiTGFzdDt9CisJRlhfQk9PTAkJCQkJCQkJCUlzTGFzdCgpe3JldHVybiBtX2JMYXN0O30KKworcHJpdmF0ZToKKwlGWF9CT09MCQkJCQkJCQkJbV9iRmlyc3Q7CisJRlhfQk9PTAkJCQkJCQkJCW1fYkxhc3Q7Cit9OworCitjbGFzcyBDRlhfRWRpdF9Hcm91cFVuZG9JdGVtIDogcHVibGljIElGWF9FZGl0X1VuZG9JdGVtCit7CitwdWJsaWM6CisJQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbShjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RpdGxlKTsKKwl2aXJ0dWFsIH5DRlhfRWRpdF9Hcm91cFVuZG9JdGVtKCk7CisKKwl2b2lkCQkJCQkJCQkJQWRkVW5kb0l0ZW0oQ0ZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSk7CisJdm9pZAkJCQkJCQkJCVVwZGF0ZUl0ZW1zKCk7CisKK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJVW5kbygpOworCXZpcnR1YWwgdm9pZAkJCQkJCQlSZWRvKCk7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJR2V0VW5kb1RpdGxlKCk7CisJdmlydHVhbCB2b2lkCQkJCQkJCVJlbGVhc2UoKTsKKworcHJpdmF0ZToKKwlDRlhfV2lkZVN0cmluZwkJCQkJCQltX3NUaXRsZTsKKwlDRlhfQXJyYXlUZW1wbGF0ZTxDRlhfRWRpdF9VbmRvSXRlbSo+CW1fSXRlbXM7Cit9OworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X1VuZG9JdGVtIGRlcml2ZWQgY2xhc3NlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK2NsYXNzIENGWEVVX0luc2VydFdvcmQgOiBwdWJsaWMgQ0ZYX0VkaXRfVW5kb0l0ZW0KK3sKK3B1YmxpYzoKKwlDRlhFVV9JbnNlcnRXb3JkKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLAorCQlGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIGNoYXJzZXQsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyk7CisJdmlydHVhbCB+Q0ZYRVVfSW5zZXJ0V29yZCgpOworCisJdm9pZAkJCQkJCVJlZG8oKTsKKwl2b2lkCQkJCQkJVW5kbygpOworCitwcml2YXRlOgorCUNGWF9FZGl0KgkJCQkJbV9wRWRpdDsKKworCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BPbGQ7CisJQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cE5ldzsKKwlGWF9XT1JECQkJCQkJbV9Xb3JkOworCUZYX0lOVDMyCQkJCQltX25DaGFyc2V0OworCUNQVlRfV29yZFByb3BzCQkJCW1fV29yZFByb3BzOworfTsKKworY2xhc3MgQ0ZYRVVfSW5zZXJ0UmV0dXJuIDogcHVibGljIENGWF9FZGl0X1VuZG9JdGVtCit7CitwdWJsaWM6CisJQ0ZYRVVfSW5zZXJ0UmV0dXJuKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLAorCQkJCQkJCSBjb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpOworCXZpcnR1YWwgfkNGWEVVX0luc2VydFJldHVybigpOworCisJdm9pZAkJCQkJCVJlZG8oKTsKKwl2b2lkCQkJCQkJVW5kbygpOworCitwcml2YXRlOgorCUNGWF9FZGl0ICoJCQkJCW1fcEVkaXQ7CisKKwlDUFZUX1dvcmRQbGFjZQkJCQltX3dwT2xkOworCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BOZXc7CisJQ1BWVF9TZWNQcm9wcwkJCQltX1NlY1Byb3BzOworCUNQVlRfV29yZFByb3BzCQkJCW1fV29yZFByb3BzOworfTsKKworY2xhc3MgQ0ZYRVVfQmFja3NwYWNlIDogcHVibGljIENGWF9FZGl0X1VuZG9JdGVtCit7CitwdWJsaWM6CisJQ0ZYRVVfQmFja3NwYWNlKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLAorCQkJCQkJRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LAorCQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAmIFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIFdvcmRQcm9wcyk7CisJdmlydHVhbCB+Q0ZYRVVfQmFja3NwYWNlKCk7CisKKwl2b2lkCQkJCQkJUmVkbygpOworCXZvaWQJCQkJCQlVbmRvKCk7CisKK3ByaXZhdGU6CisJQ0ZYX0VkaXQgKgkJCQkJbV9wRWRpdDsKKworCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BPbGQ7CisJQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cE5ldzsKKwlGWF9XT1JECQkJCQkJbV9Xb3JkOworCUZYX0lOVDMyCQkJCQltX25DaGFyc2V0OworCUNQVlRfU2VjUHJvcHMJCQkJbV9TZWNQcm9wczsKKwlDUFZUX1dvcmRQcm9wcwkJCQltX1dvcmRQcm9wczsKK307CisKK2NsYXNzIENGWEVVX0RlbGV0ZSA6IHB1YmxpYyBDRlhfRWRpdF9VbmRvSXRlbQoreworcHVibGljOgorCUNGWEVVX0RlbGV0ZShDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwT2xkUGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BOZXdQbGFjZSwKKwkJCQkJCUZYX1dPUkQgd29yZCwgRlhfSU5UMzIgY2hhcnNldCwKKwkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgJiBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBXb3JkUHJvcHMsIEZYX0JPT0wgYlNlY0VuZCk7CisJdmlydHVhbCB+Q0ZYRVVfRGVsZXRlKCk7CisKKwl2b2lkCQkJCQkJUmVkbygpOworCXZvaWQJCQkJCQlVbmRvKCk7CisKK3ByaXZhdGU6CisJQ0ZYX0VkaXQgKgkJCQkJbV9wRWRpdDsKKworCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BPbGQ7CisJQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cE5ldzsKKwlGWF9XT1JECQkJCQkJbV9Xb3JkOworCUZYX0lOVDMyCQkJCQltX25DaGFyc2V0OworCUNQVlRfU2VjUHJvcHMJCQkJbV9TZWNQcm9wczsKKwlDUFZUX1dvcmRQcm9wcwkJCQltX1dvcmRQcm9wczsKKwlGWF9CT09MCQkJCQkJbV9iU2VjRW5kOworfTsKKworY2xhc3MgQ0ZYRVVfQ2xlYXIgOiBwdWJsaWMgQ0ZYX0VkaXRfVW5kb0l0ZW0KK3sKK3B1YmxpYzoKKwlDRlhFVV9DbGVhcihDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyU2VsLCBjb25zdCBDRlhfV2lkZVN0cmluZyAmIHN3VGV4dCk7CisJdmlydHVhbCB+Q0ZYRVVfQ2xlYXIoKTsKKworCXZvaWQJCQkJCQlSZWRvKCk7CisJdm9pZAkJCQkJCVVuZG8oKTsKKworcHJpdmF0ZToKKwlDRlhfRWRpdCoJCQkJCW1fcEVkaXQ7CisKKwlDUFZUX1dvcmRSYW5nZQkJCQltX3dyU2VsOworCUNGWF9XaWRlU3RyaW5nCQkJCW1fc3dUZXh0OworfTsKKworY2xhc3MgQ0ZYRVVfQ2xlYXJSaWNoIDogcHVibGljIENGWF9FZGl0X1VuZG9JdGVtCit7CitwdWJsaWM6CisJQ0ZYRVVfQ2xlYXJSaWNoKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLAorCQkJCQkJY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3clNlbCwKKwkJCQkJICAgRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LAorCQkJCQkgICBjb25zdCBDUFZUX1NlY1Byb3BzICYgU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgV29yZFByb3BzKTsKKwl2aXJ0dWFsIH5DRlhFVV9DbGVhclJpY2goKTsKKworCXZvaWQJCQkJCQlSZWRvKCk7CisJdm9pZAkJCQkJCVVuZG8oKTsKKworcHJpdmF0ZToKKwlDRlhfRWRpdCAqCQkJCQltX3BFZGl0OworCisJQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cE9sZDsKKwlDUFZUX1dvcmRQbGFjZQkJCQltX3dwTmV3OworCUNQVlRfV29yZFJhbmdlCQkJCW1fd3JTZWw7CisJRlhfV09SRAkJCQkJCW1fV29yZDsKKwlGWF9JTlQzMgkJCQkJbV9uQ2hhcnNldDsKKwlDUFZUX1NlY1Byb3BzCQkJCW1fU2VjUHJvcHM7CisJQ1BWVF9Xb3JkUHJvcHMJCQkJbV9Xb3JkUHJvcHM7Cit9OworCitjbGFzcyBDRlhFVV9JbnNlcnRUZXh0IDogcHVibGljIENGWF9FZGl0X1VuZG9JdGVtCit7CitwdWJsaWM6CisJQ0ZYRVVfSW5zZXJ0VGV4dChDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwT2xkUGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BOZXdQbGFjZSwKKwkJCQkJCSAgIGNvbnN0IENGWF9XaWRlU3RyaW5nICYgc3dUZXh0LCBGWF9JTlQzMiBjaGFyc2V0LAorCQkJCQkJICAgY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzKTsKKwl2aXJ0dWFsIH5DRlhFVV9JbnNlcnRUZXh0KCk7CisKKwl2b2lkCQkJCQkJUmVkbygpOworCXZvaWQJCQkJCQlVbmRvKCk7CisKK3ByaXZhdGU6CisJQ0ZYX0VkaXQgKgkJCQkJbV9wRWRpdDsKKworCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BPbGQ7CisJQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cE5ldzsKKwlDRlhfV2lkZVN0cmluZwkJCQltX3N3VGV4dDsKKwlGWF9JTlQzMgkJCQkJbV9uQ2hhcnNldDsKKwlDUFZUX1NlY1Byb3BzCQkJCW1fU2VjUHJvcHM7CisJQ1BWVF9Xb3JkUHJvcHMJCQkJbV9Xb3JkUHJvcHM7Cit9OworCitjbGFzcyBDRlhFVV9TZXRTZWNQcm9wcyA6IHB1YmxpYyBDRlhfRWRpdF9VbmRvSXRlbQoreworcHVibGljOgorCUNGWEVVX1NldFNlY1Byb3BzKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UsIEVESVRfUFJPUFNfRSBlcCwgCisJCWNvbnN0IENQVlRfU2VjUHJvcHMgJiBvbGRzZWNwcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBvbGR3b3JkcHJvcHMsIAorCQljb25zdCBDUFZUX1NlY1Byb3BzICYgbmV3c2VjcHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgbmV3d29yZHByb3BzLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKTsKKwl2aXJ0dWFsIH5DRlhFVV9TZXRTZWNQcm9wcygpOworCisJdm9pZAkJCQkJCVJlZG8oKTsKKwl2b2lkCQkJCQkJVW5kbygpOworCitwcml2YXRlOgorCUNGWF9FZGl0ICoJCQkJCW1fcEVkaXQ7CisJQ1BWVF9Xb3JkUGxhY2UJCQkJbV93cFBsYWNlOworCUNQVlRfV29yZFJhbmdlCQkJCW1fd3JQbGFjZTsKKwlFRElUX1BST1BTX0UJCQkJbV9lUHJvcHM7CisKKwlDUFZUX1NlY1Byb3BzCQkJCW1fT2xkU2VjUHJvcHM7CisJQ1BWVF9TZWNQcm9wcwkJCQltX05ld1NlY1Byb3BzOworCUNQVlRfV29yZFByb3BzCQkJCW1fT2xkV29yZFByb3BzOworCUNQVlRfV29yZFByb3BzCQkJCW1fTmV3V29yZFByb3BzOwkKK307CisKK2NsYXNzIENGWEVVX1NldFdvcmRQcm9wcyA6IHB1YmxpYyBDRlhfRWRpdF9VbmRvSXRlbQoreworcHVibGljOgorCUNGWEVVX1NldFdvcmRQcm9wcyhDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlLCBFRElUX1BST1BTX0UgZXAsIAorCQljb25zdCBDUFZUX1dvcmRQcm9wcyAmIG9sZHByb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIG5ld3Byb3BzLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKTsKKwl2aXJ0dWFsIH5DRlhFVV9TZXRXb3JkUHJvcHMoKTsKKworCXZvaWQJCQkJCQlSZWRvKCk7CisJdm9pZAkJCQkJCVVuZG8oKTsKKworcHJpdmF0ZToKKwlDRlhfRWRpdCAqCQkJCQltX3BFZGl0OworCUNQVlRfV29yZFBsYWNlCQkJCW1fd3BQbGFjZTsKKwlDUFZUX1dvcmRSYW5nZQkJCQltX3dyUGxhY2U7CisJRURJVF9QUk9QU19FCQkJCW1fZVByb3BzOworCQorCUNQVlRfV29yZFByb3BzCQkJCW1fT2xkV29yZFByb3BzOworCUNQVlRfV29yZFByb3BzCQkJCW1fTmV3V29yZFByb3BzOwkKK307CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0VkaXQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitjbGFzcyBDRlhfRWRpdCA6IHB1YmxpYyBJRlhfRWRpdAoreworCWZyaWVuZCBjbGFzcyBDRlhfRWRpdF9JdGVyYXRvcjsKKwlmcmllbmQgY2xhc3MgQ0ZYRVVfSW5zZXJ0V29yZDsKKwlmcmllbmQgY2xhc3MgQ0ZYRVVfSW5zZXJ0UmV0dXJuOworCWZyaWVuZCBjbGFzcyBDRlhFVV9CYWNrc3BhY2U7CisJZnJpZW5kIGNsYXNzIENGWEVVX0RlbGV0ZTsKKwlmcmllbmQgY2xhc3MgQ0ZYRVVfQ2xlYXI7CisJZnJpZW5kIGNsYXNzIENGWEVVX0NsZWFyUmljaDsKKwlmcmllbmQgY2xhc3MgQ0ZYRVVfU2V0U2VjUHJvcHM7CisJZnJpZW5kIGNsYXNzIENGWEVVX1NldFdvcmRQcm9wczsJCisJZnJpZW5kIGNsYXNzIENGWEVVX0luc2VydFRleHQ7CisKK3B1YmxpYzoKKwlDRlhfRWRpdChJUERGX1ZhcmlhYmxlVGV4dCAqIHBWVCk7CisJdmlydHVhbCB+Q0ZYX0VkaXQoKTsKKworCXZvaWQJCQkJCQkJCQlTZXRGb250TWFwKElGWF9FZGl0X0ZvbnRNYXAgKiBwRm9udE1hcCk7CQorCXZvaWQJCQkJCQkJCQlTZXRWVFByb3ZpZGVyKElQREZfVmFyaWFibGVUZXh0X1Byb3ZpZGVyKiBwUHJvdmlkZXIpOworCXZvaWQJCQkJCQkJCQlTZXROb3RpZnkoSUZYX0VkaXRfTm90aWZ5ICogcE5vdGlmeSk7CisJdm9pZAkJCQkJCQkJCVNldE9wck5vdGlmeShJRlhfRWRpdF9PcHJOb3RpZnkqIHBPcHJOb3RpZnkpOworCUlGWF9FZGl0X0l0ZXJhdG9yKgkJCQkJCUdldEl0ZXJhdG9yKCk7CisJSVBERl9WYXJpYWJsZVRleHQgKgkJCQkJCUdldFZhcmlhYmxlVGV4dCgpOworCUlGWF9FZGl0X0ZvbnRNYXAqCQkJCQkJR2V0Rm9udE1hcCgpOworCisJdm9pZAkJCQkJCQkJCUluaXRpYWxpemUoKTsKKwl2b2lkCQkJCQkJCQkJU2V0UGxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7CisJdm9pZAkJCQkJCQkJCVNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOworCisJdm9pZAkJCQkJCQkJCVNldEFsaWdubWVudEgoRlhfSU5UMzIgbkZvcm1hdCA9IDAsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7CisJdm9pZAkJCQkJCQkJCVNldEFsaWdubWVudFYoRlhfSU5UMzIgbkZvcm1hdCA9IDAsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7CisJdm9pZAkJCQkJCQkJCVNldFBhc3N3b3JkQ2hhcihGWF9XT1JEIHdTdWJXb3JkID0gJyonLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOworCXZvaWQJCQkJCQkJCQlTZXRMaW1pdENoYXIoRlhfSU5UMzIgbkxpbWl0Q2hhciA9IDAsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7CisJdm9pZAkJCQkJCQkJCVNldENoYXJBcnJheShGWF9JTlQzMiBuQ2hhckFycmF5ID0gMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsKKwl2b2lkCQkJCQkJCQkJU2V0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UgPSAwLjBmLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOworCXZvaWQJCQkJCQkJCQlTZXRIb3J6U2NhbGUoRlhfSU5UMzIgbkhvcnpTY2FsZSA9IDEwMCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsKKwl2b2lkCQkJCQkJCQkJU2V0TGluZUxlYWRpbmcoRlhfRkxPQVQgZkxpbmVMZWFkaW5nLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOworCXZvaWQJCQkJCQkJCQlTZXRNdWx0aUxpbmUoRlhfQk9PTCBiTXVsdGlMaW5lID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsKKwl2b2lkCQkJCQkJCQkJU2V0QXV0b1JldHVybihGWF9CT09MIGJBdXRvID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsKKwl2b2lkCQkJCQkJCQkJU2V0QXV0b0ZvbnRTaXplKEZYX0JPT0wgYkF1dG8gPSBUUlVFLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOwkKKwl2b2lkCQkJCQkJCQkJU2V0QXV0b1Njcm9sbChGWF9CT09MIGJBdXRvID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsJCisJdm9pZAkJCQkJCQkJCVNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsKKwl2b2lkCQkJCQkJCQkJU2V0VGV4dE92ZXJmbG93KEZYX0JPT0wgYkFsbG93ZWQgPSBGQUxTRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsKKworCUZYX0JPT0wJCQkJCQkJCQlJc1JpY2hUZXh0KCkgY29uc3Q7CisJdm9pZAkJCQkJCQkJCVNldFJpY2hUZXh0KEZYX0JPT0wgYlJpY2hUZXh0ID0gVFJVRSwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsKKwlGWF9CT09MCQkJCQkJCQkJU2V0UmljaEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSk7CQorCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoRm9udEluZGV4KEZYX0lOVDMyIG5Gb250SW5kZXgpOworCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dENvbG9yKEZYX0NPTE9SUkVGIGR3Q29sb3IpOworCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dFNjcmlwdChGWF9JTlQzMiBuU2NyaXB0VHlwZSk7CisJRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0Qm9sZChGWF9CT09MIGJCb2xkID0gVFJVRSk7CQorCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dEl0YWxpYyhGWF9CT09MIGJJdGFsaWMgPSBUUlVFKTsKKwlGWF9CT09MCQkJCQkJCQkJU2V0UmljaFRleHRVbmRlcmxpbmUoRlhfQk9PTCBiVW5kZXJsaW5lID0gVFJVRSk7CisJRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0Q3Jvc3NvdXQoRlhfQk9PTCBiQ3Jvc3NvdXQgPSBUUlVFKTsKKwlGWF9CT09MCQkJCQkJCQkJU2V0UmljaFRleHRDaGFyU3BhY2UoRlhfRkxPQVQgZkNoYXJTcGFjZSk7CisJRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0SG9yelNjYWxlKEZYX0lOVDMyIG5Ib3J6U2NhbGUgPSAxMDApOworCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dExpbmVMZWFkaW5nKEZYX0ZMT0FUIGZMaW5lTGVhZGluZyk7CisJRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0TGluZUluZGVudChGWF9GTE9BVCBmTGluZUluZGVudCk7CisJRlhfQk9PTAkJCQkJCQkJCVNldFJpY2hUZXh0QWxpZ25tZW50KEZYX0lOVDMyIG5BbGlnbm1lbnQpOworCisJdm9pZAkJCQkJCQkJCU9uTW91c2VEb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKwl2b2lkCQkJCQkJCQkJT25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOworCXZvaWQJCQkJCQkJCQlPblZLX1VQKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOworCXZvaWQJCQkJCQkJCQlPblZLX0RPV04oRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7CisJdm9pZAkJCQkJCQkJCU9uVktfTEVGVChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKwl2b2lkCQkJCQkJCQkJT25WS19SSUdIVChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKwl2b2lkCQkJCQkJCQkJT25WS19IT01FKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOworCXZvaWQJCQkJCQkJCQlPblZLX0VORChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKworCXZvaWQJCQkJCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgdGV4dCxGWF9JTlQzMiBjaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VULAorCQkJCQkJCQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMgPSBOVUxMLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyA9IE5VTEwpOwkKKwlGWF9CT09MCQkJCQkJCQkJSW5zZXJ0V29yZChGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIGNoYXJzZXQgPSBERUZBVUxUX0NIQVJTRVQsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyA9IE5VTEwpOworCUZYX0JPT0wJCQkJCQkJCQlJbnNlcnRSZXR1cm4oY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyA9IE5VTEwsY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzID0gTlVMTCk7CisJRlhfQk9PTAkJCQkJCQkJCUJhY2tzcGFjZSgpOworCUZYX0JPT0wJCQkJCQkJCQlEZWxldGUoKTsJCQorCUZYX0JPT0wJCQkJCQkJCQlDbGVhcigpOworCUZYX0JPT0wJCQkJCQkJCQlFbXB0eSgpOworCUZYX0JPT0wJCQkJCQkJCQlJbnNlcnRUZXh0KEZYX0xQQ1dTVFIgdGV4dCwgRlhfSU5UMzIgY2hhcnNldCA9IERFRkFVTFRfQ0hBUlNFVCwKKwkJCQkJCQkJCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzID0gTlVMTCxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMgPSBOVUxMKTsKKwlGWF9CT09MCQkJCQkJCQkJUmVkbygpOworCUZYX0JPT0wJCQkJCQkJCQlVbmRvKCk7CQorCUNQVlRfV29yZFBsYWNlCQkJCQkJCURvSW5zZXJ0VGV4dChjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIEZYX0xQQ1dTVFIgdGV4dCwgRlhfSU5UMzIgY2hhcnNldCwgCisJCQkJCQkJCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpOworCUZYX0lOVDMyCQkJCQkJCQlHZXRDaGFyU2V0RnJvbVVuaWNvZGUoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuT2xkQ2hhcnNldCk7CisKKwlGWF9JTlQzMgkJCQkJCQkJV29yZFBsYWNlVG9Xb3JkSW5kZXgoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7CisJQ1BWVF9Xb3JkUGxhY2UJCQkJCQkJV29yZEluZGV4VG9Xb3JkUGxhY2UoRlhfSU5UMzIgaW5kZXgpIGNvbnN0OwkKKworCUNQVlRfV29yZFBsYWNlCQkJCQkJCUdldExpbmVCZWdpblBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0OworCUNQVlRfV29yZFBsYWNlCQkJCQkJCUdldExpbmVFbmRQbGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSBjb25zdDsKKwlDUFZUX1dvcmRQbGFjZQkJCQkJCQlHZXRTZWN0aW9uQmVnaW5QbGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSBjb25zdDsKKwlDUFZUX1dvcmRQbGFjZQkJCQkJCQlHZXRTZWN0aW9uRW5kUGxhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7CisJQ1BWVF9Xb3JkUGxhY2UJCQkJCQkJU2VhcmNoV29yZFBsYWNlKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdDsKKworCUZYX0lOVDMyCQkJCQkJCQlHZXRDYXJldCgpIGNvbnN0OworCUNQVlRfV29yZFBsYWNlCQkJCQkJCUdldENhcmV0V29yZFBsYWNlKCkgY29uc3Q7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCQkJR2V0U2VsVGV4dCgpIGNvbnN0OworCUNGWF9XaWRlU3RyaW5nCQkJCQkJCUdldFRleHQoKSBjb25zdDsKKwlGWF9GTE9BVAkJCQkJCQkJR2V0Rm9udFNpemUoKSBjb25zdDsKKwlGWF9XT1JECQkJCQkJCQkJR2V0UGFzc3dvcmRDaGFyKCkgY29uc3Q7CisJQ1BERl9Qb2ludAkJCQkJCQkJR2V0U2Nyb2xsUG9zKCkgY29uc3Q7CisJRlhfSU5UMzIJCQkJCQkJCUdldENoYXJBcnJheSgpIGNvbnN0OworCUNQREZfUmVjdAkJCQkJCQkJR2V0UGxhdGVSZWN0KCkgY29uc3Q7CisJQ1BERl9SZWN0CQkJCQkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0OworCUNGWF9XaWRlU3RyaW5nCQkJCQkJCUdldFJhbmdlVGV4dChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKSBjb25zdDsKKwlGWF9JTlQzMgkJCQkJCQkJR2V0SG9yelNjYWxlKCkgY29uc3Q7CisJRlhfRkxPQVQJCQkJCQkJCUdldENoYXJTcGFjZSgpIGNvbnN0OworCUZYX0lOVDMyCQkJCQkJCQlHZXRUb3RhbFdvcmRzKCkgY29uc3Q7CisJRlhfSU5UMzIJCQkJCQkJCUdldFRvdGFsTGluZXMoKSBjb25zdDsKKworCXZvaWQJCQkJCQkJCQlTZXRTZWwoRlhfSU5UMzIgblN0YXJ0Q2hhcixGWF9JTlQzMiBuRW5kQ2hhcik7CisJdm9pZAkJCQkJCQkJCUdldFNlbChGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIpIGNvbnN0OworCitwcml2YXRlOgorCXZvaWQJCQkJCQkJCQlTZWxlY3RBbGwoKTsKKwl2b2lkCQkJCQkJCQkJU2VsZWN0Tm9uZSgpOworCXZvaWQJCQkJCQkJCQlTZXRTZWwoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBiZWdpbixjb25zdCBDUFZUX1dvcmRQbGFjZSAmIGVuZCk7CisJRlhfQk9PTAkJCQkJCQkJCUlzU2VsZWN0ZWQoKSBjb25zdDsKKworCXZvaWQJCQkJCQkJCQlSZWFycmFuZ2VBbGwoKTsKKwl2b2lkCQkJCQkJCQkJUmVhcnJhbmdlUGFydChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKTsKKwl2b2lkCQkJCQkJCQkJUGFpbnQoKTsKKwl2b2lkCQkJCQkJCQkJU2Nyb2xsVG9DYXJldCgpOworCXZvaWQJCQkJCQkJCQlTZXRTY3JvbGxJbmZvKCk7CisJdm9pZAkJCQkJCQkJCVNldFNjcm9sbFBvc1goRlhfRkxPQVQgZngpOworCXZvaWQJCQkJCQkJCQlTZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KTsKKwl2b2lkCQkJCQkJCQkJU2V0U2Nyb2xsTGltaXQoKTsKKwl2b2lkCQkJCQkJCQkJU2V0Q29udGVudENoYW5nZWQoKTsKKwl2b2lkCQkJCQkJCQkJRW5hYmxlTm90aWZ5KEZYX0JPT0wgYk5vdGlmeSk7CisKKwl2b2lkCQkJCQkJCQkJU2V0VGV4dChGWF9MUENXU1RSIHRleHQsRlhfSU5UMzIgY2hhcnNldCwKKwkJCQkJCQkJCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyxGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCk7CQorCUZYX0JPT0wJCQkJCQkJCQlJbnNlcnRXb3JkKEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgY2hhcnNldCwgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzLEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KTsKKwlGWF9CT09MCQkJCQkJCQkJSW5zZXJ0UmV0dXJuKGNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMsY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzLEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KTsKKwlGWF9CT09MCQkJCQkJCQkJQmFja3NwYWNlKEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KTsKKwlGWF9CT09MCQkJCQkJCQkJRGVsZXRlKEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KTsJCQorCUZYX0JPT0wJCQkJCQkJCQlDbGVhcihGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCk7CisJRlhfQk9PTAkJCQkJCQkJCUluc2VydFRleHQoRlhfTFBDV1NUUiB0ZXh0LCBGWF9JTlQzMiBjaGFyc2V0LAorCQkJCQkJCQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsRlhfQk9PTCBiQWRkVW5kbywgRlhfQk9PTCBiUGFpbnQpOworCUZYX0JPT0wJCQkJCQkJCQlTZXRSaWNoVGV4dFByb3BzKEVESVRfUFJPUFNfRSBlUHJvcHMsCisJCQkJCQkJCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpOworCUZYX0JPT0wJCQkJCQkJCQlTZXRTZWNQcm9wcyhFRElUX1BST1BTX0UgZVByb3BzLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlLCAKKwkJCQkJCQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3ciwgRlhfQk9PTCBiQWRkVW5kbyk7CisJRlhfQk9PTAkJCQkJCQkJCVNldFdvcmRQcm9wcyhFRElUX1BST1BTX0UgZVByb3BzLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlLCAKKwkJCQkJCQkJCQkJCWNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3ciwgRlhfQk9PTCBiQWRkVW5kbyk7CisJdm9pZAkJCQkJCQkJCVBhaW50U2V0UHJvcHMoRURJVF9QUk9QU19FIGVQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3cik7CisJdm9pZAkJCQkJCQkJCVBhaW50SW5zZXJ0VGV4dChjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwT2xkLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3KTsKKworCWlubGluZSBDUERGX1BvaW50CQkJCQkJVlRUb0VkaXQoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdDsKKwlpbmxpbmUgQ1BERl9Qb2ludAkJCQkJCUVkaXRUb1ZUKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3Q7CisJaW5saW5lIENQREZfUmVjdAkJCQkJCVZUVG9FZGl0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QpIGNvbnN0OworCWlubGluZSBDUERGX1JlY3QJCQkJCQlFZGl0VG9WVChjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdDsKKworCXZvaWQJCQkJCQkJCQlFbmFibGVSZWZyZXNoKEZYX0JPT0wgYlJlZnJlc2gpOworCXZvaWQJCQkJCQkJCQlSZWZyZXNoKFJFRlJFU0hfUExBTl9FIGVQbGFuLGNvbnN0IENQVlRfV29yZFJhbmdlICogcFJhbmdlMSA9IE5VTEwsY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UyID0gTlVMTCk7CisJdm9pZAkJCQkJCQkJCVJlZnJlc2hQdXNoTGluZVJlY3RzKGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IpOworCXZvaWQJCQkJCQkJCQlSZWZyZXNoUHVzaFJhbmRvbVJlY3RzKGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IpOworCXZvaWQJCQkJCQkJCQlSZWZyZXNoV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cik7CisKKwl2b2lkCQkJCQkJCQkJU2V0Q2FyZXQoRlhfSU5UMzIgblBvcyk7CisJdm9pZAkJCQkJCQkJCVNldENhcmV0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpOworCXZvaWQJCQkJCQkJCQlTZXRDYXJldEluZm8oKTsKKwl2b2lkCQkJCQkJCQkJU2V0Q2FyZXRPcmlnaW4oKTsKKwl2b2lkCQkJCQkJCQkJU2V0Q2FyZXRDaGFuZ2UoKTsKKworCUNQVlRfV29yZFJhbmdlCQkJCQkJCUdldFdob2xlV29yZFJhbmdlKCkgY29uc3Q7CisJQ1BWVF9Xb3JkUmFuZ2UJCQkJCQkJR2V0VmlzaWJsZVdvcmRSYW5nZSgpIGNvbnN0OworCUNQVlRfV29yZFJhbmdlCQkJCQkJCUdldExhdGluV29yZHNSYW5nZShjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSBjb25zdDsKKwlDUFZUX1dvcmRSYW5nZQkJCQkJCQlDb21iaW5lV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IxLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyMik7CisJQ1BWVF9Xb3JkUmFuZ2UJCQkJCQkJR2V0U2VsZWN0V29yZFJhbmdlKCkgY29uc3Q7CisKKwl2b2lkCQkJCQkJCQkJRW5hYmxlVW5kbyhGWF9CT09MIGJVbmRvKTsKKwl2b2lkCQkJCQkJCQkJRW5hYmxlT3ByTm90aWZ5KEZYX0JPT0wgYk5vdGlmeSk7CisKKwlGWF9CT09MCQkJCQkJCQkJSXNUZXh0RnVsbCgpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJCQlJc1RleHRPdmVyZmxvdygpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJCQlDYW5VbmRvKCkgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQkJCUNhblJlZG8oKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCQkJSXNNb2RpZmllZCgpIGNvbnN0OworCisJdm9pZAkJCQkJCQkJCUJlZ2luR3JvdXBVbmRvKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGl0bGUpOworCXZvaWQJCQkJCQkJCQlFbmRHcm91cFVuZG8oKTsKKwl2b2lkCQkJCQkJCQkJQWRkRWRpdFVuZG9JdGVtKENGWF9FZGl0X1VuZG9JdGVtKiBwRWRpdFVuZG9JdGVtKTsKKwl2b2lkCQkJCQkJCQkJQWRkVW5kb0l0ZW0oSUZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSk7CisKKwl2b2lkCQkJCQkJCQkJU2V0UGFnZUluZm8oY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlKTsKKwlDUFZUX1dvcmRQbGFjZQkJCQkJCQlTZWFyY2hQYWdlRW5kUGxhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHdwUGFnZUJlZ2luLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3Q7CisJRlhfRkxPQVQJCQkJCQkJCUdldExpbmVUb3AoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlKSBjb25zdDsKKwlGWF9GTE9BVAkJCQkJCQkJR2V0TGluZUJvdHRvbShjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UpIGNvbnN0OworCitwcml2YXRlOgkKKwlJUERGX1ZhcmlhYmxlVGV4dCoJCQkJCQltX3BWVDsKKwlJRlhfRWRpdF9Ob3RpZnkqCQkJCQkJbV9wTm90aWZ5OworCUlGWF9FZGl0X09wck5vdGlmeSoJCQkJCQltX3BPcHJOb3RpZnk7CisJQ0ZYX0VkaXRfUHJvdmlkZXIqCQkJCQkJbV9wVlRQcm92aWRlOworCisJQ1BWVF9Xb3JkUGxhY2UJCQkJCQkJbV93cENhcmV0OworCUNQVlRfV29yZFBsYWNlCQkJCQkJCW1fd3BPbGRDYXJldDsKKwlDRlhfRWRpdF9TZWxlY3QJCQkJCQkJbV9TZWxTdGF0ZTsKKworCUNQREZfUG9pbnQJCQkJCQkJCW1fcHRTY3JvbGxQb3M7CisJQ1BERl9Qb2ludAkJCQkJCQkJbV9wdFJlZnJlc2hTY3JvbGxQb3M7CisJRlhfQk9PTAkJCQkJCQkJCW1fYkVuYWJsZVNjcm9sbDsJCisJSUZYX0VkaXRfSXRlcmF0b3IgKgkJCQkJCW1fcEl0ZXJhdG9yOwkKKwlDRlhfRWRpdF9SZWZyZXNoCQkJCQkJbV9SZWZyZXNoOworCUNQREZfUG9pbnQJCQkJCQkJCW1fcHRDYXJldDsKKwlDRlhfRWRpdF9VbmRvCQkJCQkJCW1fVW5kbzsKKwlGWF9JTlQzMgkJCQkJCQkJbV9uQWxpZ25tZW50OworCUZYX0JPT0wJCQkJCQkJCQltX2JOb3RpZnlGbGFnOworCUZYX0JPT0wJCQkJCQkJCQltX2JUZXh0RnVsbEZsYWc7CisJRlhfQk9PTAkJCQkJCQkJCW1fYkVuYWJsZU92ZXJmbG93OworCUZYX0JPT0wJCQkJCQkJCQltX2JFbmFibGVSZWZyZXNoOworCUNQREZfUmVjdAkJCQkJCQkJbV9yY09sZENvbnRlbnQ7CisJRlhfQk9PTAkJCQkJCQkJCW1fYkVuYWJsZVVuZG87CisJRlhfQk9PTAkJCQkJCQkJCW1fYk5vdGlmeTsKKwlGWF9CT09MCQkJCQkJCQkJbV9iT3ByTm90aWZ5OworCUNGWF9FZGl0X0dyb3VwVW5kb0l0ZW0qCQkJCQltX3BHcm91cFVuZG9JdGVtOworfTsKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdF9JdGVyYXRvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK2NsYXNzIENGWF9FZGl0X0l0ZXJhdG9yIDogcHVibGljIElGWF9FZGl0X0l0ZXJhdG9yCit7CitwdWJsaWM6CisJQ0ZYX0VkaXRfSXRlcmF0b3IoQ0ZYX0VkaXQgKiBwRWRpdCxJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBWVEl0ZXJhdG9yKTsKKwl2aXJ0dWFsIH5DRlhfRWRpdF9JdGVyYXRvcigpOworCisJRlhfQk9PTAkJCQkJCQkJCU5leHRXb3JkKCk7CisJRlhfQk9PTAkJCQkJCQkJCU5leHRMaW5lKCk7CisJRlhfQk9PTAkJCQkJCQkJCU5leHRTZWN0aW9uKCk7CisJRlhfQk9PTAkJCQkJCQkJCVByZXZXb3JkKCk7CisJRlhfQk9PTAkJCQkJCQkJCVByZXZMaW5lKCk7CisJRlhfQk9PTAkJCQkJCQkJCVByZXZTZWN0aW9uKCk7CisKKwlGWF9CT09MCQkJCQkJCQkJR2V0V29yZChDUFZUX1dvcmQgJiB3b3JkKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCQkJR2V0TGluZShDUFZUX0xpbmUgJiBsaW5lKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCQkJR2V0U2VjdGlvbihDUFZUX1NlY3Rpb24gJiBzZWN0aW9uKSBjb25zdDsKKwl2b2lkCQkJCQkJCQkJU2V0QXQoRlhfSU5UMzIgbldvcmRJbmRleCk7CisJdm9pZAkJCQkJCQkJCVNldEF0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpOworCWNvbnN0IENQVlRfV29yZFBsYWNlICYJCQkJCUdldEF0KCkgY29uc3Q7CisJSUZYX0VkaXQqCQkJCQkJCQlHZXRFZGl0KCkgY29uc3Q7CisKK3ByaXZhdGU6CisJQ0ZYX0VkaXQgKgkJCQkJCQkJbV9wRWRpdDsKKwlJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvcioJCQkJbV9wVlRJdGVyYXRvcjsKK307CisKK2NsYXNzIENGWF9FZGl0X1Byb3ZpZGVyIDogcHVibGljIElQREZfVmFyaWFibGVUZXh0X1Byb3ZpZGVyCit7CitwdWJsaWM6CisJQ0ZYX0VkaXRfUHJvdmlkZXIoSUZYX0VkaXRfRm9udE1hcCogcEZvbnRNYXApOworCXZpcnR1YWwgfkNGWF9FZGl0X1Byb3ZpZGVyKCk7CisKKwlJRlhfRWRpdF9Gb250TWFwKgkJCUdldEZvbnRNYXAoKTsKKworCUZYX0lOVDMyCQkJCQlHZXRDaGFyV2lkdGgoRlhfSU5UMzIgbkZvbnRJbmRleCwgRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuV29yZFN0eWxlKTsKKwlGWF9JTlQzMgkJCQkJR2V0VHlwZUFzY2VudChGWF9JTlQzMiBuRm9udEluZGV4KTsKKwlGWF9JTlQzMgkJCQkJR2V0VHlwZURlc2NlbnQoRlhfSU5UMzIgbkZvbnRJbmRleCk7CisJRlhfSU5UMzIJCQkJCUdldFdvcmRGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LCBGWF9JTlQzMiBuRm9udEluZGV4KTsKKwlGWF9JTlQzMgkJCQkJR2V0RGVmYXVsdEZvbnRJbmRleCgpOworCUZYX0JPT0wJCQkJCQlJc0xhdGluV29yZChGWF9XT1JEIHdvcmQpOworCitwcml2YXRlOgorCUlGWF9FZGl0X0ZvbnRNYXAqCQkJbV9wRm9udE1hcDsKK307CisKKyNlbmRpZiAvL19GWEVUX0VESVRfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2Z4ZWRpdC9meGV0X2xpc3QuaCBiL2ZwZGZzZGsvaW5jbHVkZS9meGVkaXQvZnhldF9saXN0LmgKaW5kZXggZDc3YmU4Ni4uMTE1N2JiZSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2Z4ZWRpdC9meGV0X2xpc3QuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfbGlzdC5oCkBAIC0xLDM2MyArMSwzNjMgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZYRVRfTElTVF9IXw0KLSNkZWZpbmUgX0ZYRVRfTElTVF9IXw0KLQ0KLSNpbmNsdWRlICJmeF9lZGl0LmgiDQotDQotY2xhc3MgSUZYX0VkaXQ7DQotDQotY2xhc3MgQ0xTVF9TaXplDQotew0KLXB1YmxpYzoNCi0JQ0xTVF9TaXplKCkgOiB4KDAuMGYpLCB5KDAuMGYpDQotCXsJCQ0KLQl9DQotDQotCUNMU1RfU2l6ZShGWF9GTE9BVCB4LEZYX0ZMT0FUIHkpDQotCXsgDQotCQl0aGlzLT54ID0geDsNCi0JCXRoaXMtPnkgPSB5Ow0KLQl9DQotDQotCXZvaWQgRGVmYXVsdCgpDQotCXsNCi0JCXggPSAwLjBmOw0KLQkJeSA9IDAuMGY7DQotCX0NCi0NCi0JRlhfQk9PTCBvcGVyYXRvciAhPSAoY29uc3QgQ0xTVF9TaXplICYgc2l6ZSkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIEZYU1lTX21lbWNtcCh0aGlzLCAmc2l6ZSwgc2l6ZW9mKENMU1RfU2l6ZSkpICE9IDA7DQotCX0NCi0NCi0JRlhfRkxPQVQgeCx5Ow0KLX07DQotDQotY2xhc3MgQ0xTVF9SZWN0IDogcHVibGljIENQREZfUmVjdA0KLXsNCi1wdWJsaWM6DQotCUNMU1RfUmVjdCgpDQotCXsJDQotCQlsZWZ0ID0gdG9wID0gcmlnaHQgPSBib3R0b20gPSAwLjBmOw0KLQl9DQotDQotCUNMU1RfUmVjdChGWF9GTE9BVCBsZWZ0LEZYX0ZMT0FUIHRvcCwNCi0JCQkJCQlGWF9GTE9BVCByaWdodCxGWF9GTE9BVCBib3R0b20pDQotCXsgDQotCQl0aGlzLT5sZWZ0ID0gbGVmdDsgDQotCQl0aGlzLT50b3AgPSB0b3A7IA0KLQkJdGhpcy0+cmlnaHQgPSByaWdodDsgDQotCQl0aGlzLT5ib3R0b20gPSBib3R0b207IA0KLQl9DQotDQotCUNMU1RfUmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0KQ0KLQl7IA0KLQkJdGhpcy0+bGVmdCA9IHJlY3QubGVmdDsgDQotCQl0aGlzLT50b3AgPSByZWN0LnRvcDsgDQotCQl0aGlzLT5yaWdodCA9IHJlY3QucmlnaHQ7IA0KLQkJdGhpcy0+Ym90dG9tID0gcmVjdC5ib3R0b207IA0KLQl9DQotDQotCXZvaWQgRGVmYXVsdCgpDQotCXsNCi0JCWxlZnQgPSB0b3AgPSByaWdodCA9IGJvdHRvbSA9IDAuMGY7DQotCX0NCi0NCi0JY29uc3QgQ0xTVF9SZWN0IG9wZXJhdG9yID0gKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpDQotCXsNCi0JCXRoaXMtPmxlZnQgPSByZWN0LmxlZnQ7DQotCQl0aGlzLT50b3AgPSByZWN0LnRvcDsNCi0JCXRoaXMtPnJpZ2h0ID0gcmVjdC5yaWdodDsNCi0JCXRoaXMtPmJvdHRvbSA9IHJlY3QuYm90dG9tOw0KLQ0KLQkJcmV0dXJuICp0aGlzOw0KLQl9DQotDQotCUZYX0JPT0wgb3BlcmF0b3IgPT0gKGNvbnN0IENMU1RfUmVjdCAmIHJlY3QpIGNvbnN0DQotCXsNCi0JCXJldHVybiBGWFNZU19tZW1jbXAodGhpcywgJnJlY3QsIHNpemVvZihDTFNUX1JlY3QpKSA9PSAwOw0KLQl9DQotDQotCUZYX0JPT0wgb3BlcmF0b3IgIT0gKGNvbnN0IENMU1RfUmVjdCAmIHJlY3QpIGNvbnN0DQotCXsNCi0JCXJldHVybiBGWFNZU19tZW1jbXAodGhpcywgJnJlY3QsIHNpemVvZihDTFNUX1JlY3QpKSAhPSAwOw0KLQl9DQotDQotCUZYX0ZMT0FUIFdpZHRoKCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIHRoaXMtPnJpZ2h0IC0gdGhpcy0+bGVmdDsNCi0JfQ0KLQ0KLQlGWF9GTE9BVCBIZWlnaHQoKSBjb25zdA0KLQl7DQotCQlpZiAodGhpcy0+dG9wID4gdGhpcy0+Ym90dG9tKQ0KLQkJCXJldHVybiB0aGlzLT50b3AgLSB0aGlzLT5ib3R0b207DQotCQllbHNlDQotCQkJcmV0dXJuIHRoaXMtPmJvdHRvbSAtIHRoaXMtPnRvcDsNCi0JfQ0KLQ0KLQlDUERGX1BvaW50IExlZnRUb3AoKSBjb25zdA0KLQl7DQotCQlyZXR1cm4gQ1BERl9Qb2ludChsZWZ0LHRvcCk7DQotCX0NCi0NCi0JQ1BERl9Qb2ludCBSaWdodEJvdHRvbSgpIGNvbnN0DQotCXsNCi0JCXJldHVybiBDUERGX1BvaW50KHJpZ2h0LGJvdHRvbSk7DQotCX0NCi0NCi0JY29uc3QgQ0xTVF9SZWN0IG9wZXJhdG9yICs9IChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIA0KLQl7DQotCQl0aGlzLT5sZWZ0ICs9IHBvaW50Lng7DQotCQl0aGlzLT5yaWdodCArPSBwb2ludC54Ow0KLQkJdGhpcy0+dG9wICs9IHBvaW50Lnk7DQotCQl0aGlzLT5ib3R0b20gKz0gcG9pbnQueTsNCi0NCi0JCXJldHVybiAqdGhpczsNCi0JfQ0KLQ0KLQljb25zdCBDTFNUX1JlY3Qgb3BlcmF0b3IgLT0gKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgDQotCXsNCi0JCXRoaXMtPmxlZnQgLT0gcG9pbnQueDsNCi0JCXRoaXMtPnJpZ2h0IC09IHBvaW50Lng7DQotCQl0aGlzLT50b3AgLT0gcG9pbnQueTsNCi0JCXRoaXMtPmJvdHRvbSAtPSBwb2ludC55Ow0KLQ0KLQkJcmV0dXJuICp0aGlzOw0KLQl9DQotDQotCUNMU1RfUmVjdCBvcGVyYXRvciArIChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0DQotCXsNCi0JCXJldHVybiBDTFNUX1JlY3QobGVmdCArIHBvaW50LngsDQotCQkJCQl0b3AgKyBwb2ludC55LA0KLQkJCQkJcmlnaHQgKyBwb2ludC54LA0KLQkJCQkJYm90dG9tICsgcG9pbnQueSk7DQotCX0NCi0NCi0JQ0xTVF9SZWN0IG9wZXJhdG9yIC0gKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIENMU1RfUmVjdChsZWZ0IC0gcG9pbnQueCwNCi0JCQkJCXRvcCAtIHBvaW50LnksDQotCQkJCQlyaWdodCAtIHBvaW50LngsDQotCQkJCQlib3R0b20gLSBwb2ludC55KTsNCi0JfQ0KLX07DQotDQotY2xhc3MgQ0ZYX0xpc3RJdGVtDQotew0KLXB1YmxpYzoNCi0JQ0ZYX0xpc3RJdGVtKCk7DQotCXZpcnR1YWwgfkNGWF9MaXN0SXRlbSgpOw0KLQ0KLQl2b2lkCQkJCQkJCVNldEZvbnRNYXAoSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwKTsNCi0JSUZYX0VkaXRfSXRlcmF0b3IqCQkJCUdldEl0ZXJhdG9yKCkgY29uc3Q7DQotCUlGWF9FZGl0KgkJCQkJCUdldEVkaXQoKSBjb25zdDsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQkJU2V0UmVjdChjb25zdCBDTFNUX1JlY3QgJiByZWN0KTsJCQ0KLQl2b2lkCQkJCQkJCVNldFNlbGVjdChGWF9CT09MIGJTZWxlY3RlZCk7CQ0KLQl2b2lkCQkJCQkJCVNldENhcmV0KEZYX0JPT0wgYkNhcmV0KTsNCi0Jdm9pZAkJCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgdGV4dCk7DQotCXZvaWQJCQkJCQkJU2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFRleHQoKSBjb25zdDsNCi0NCi0JQ0xTVF9SZWN0CQkJCQkJR2V0UmVjdCgpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUlzU2VsZWN0ZWQoKSBjb25zdDsNCi0JRlhfQk9PTAkJCQkJCQlJc0NhcmV0KCkgY29uc3Q7DQotCUZYX0ZMT0FUCQkJCQkJR2V0SXRlbUhlaWdodCgpIGNvbnN0OwkNCi0JRlhfV09SRAkJCQkJCQlHZXRGaXJzdENoYXIoKSBjb25zdDsNCi0NCi1wcml2YXRlOg0KLQlJRlhfRWRpdCoJCQkJCQltX3BFZGl0Ow0KLQlGWF9CT09MCQkJCQkJCW1fYlNlbGVjdGVkOwkJLy/Kx7fx0aHW0A0KLQlGWF9CT09MCQkJCQkJCW1fYkNhcmV0OwkJLy/Kx7fxzqq9ubXjo6y24NGhyrHTww0KLQlDTFNUX1JlY3QJCQkJCQltX3JjTGlzdEl0ZW07CS8vxNqyv9f4seoNCi19Ow0KLQ0KLWNsYXNzIENGWF9MaXN0Q29udGFpbmVyDQotew0KLXB1YmxpYzoNCi0JQ0ZYX0xpc3RDb250YWluZXIoKSA6IG1fcmNQbGF0ZSgwLjBmLDAuMGYsMC4wZiwwLjBmKSwgbV9yY0NvbnRlbnQoMC4wZiwwLjBmLDAuMGYsMC4wZil7fQ0KLQl2aXJ0dWFsIH5DRlhfTGlzdENvbnRhaW5lcigpe30NCi0JdmlydHVhbCB2b2lkCQkJCQlTZXRQbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCl7bV9yY1BsYXRlID0gcmVjdDt9DQotCUNQREZfUmVjdAkJCQkJCUdldFBsYXRlUmVjdCgpIGNvbnN0e3JldHVybiBtX3JjUGxhdGU7fQ0KLQl2b2lkCQkJCQkJCVNldENvbnRlbnRSZWN0KGNvbnN0IENMU1RfUmVjdCAmIHJlY3Qpe21fcmNDb250ZW50ID0gcmVjdDt9DQotCUNMU1RfUmVjdAkJCQkJCUdldENvbnRlbnRSZWN0KCkgY29uc3R7cmV0dXJuIG1fcmNDb250ZW50O30NCi0JQ1BERl9Qb2ludAkJCQkJCUdldEJUUG9pbnQoKSBjb25zdHtyZXR1cm4gQ1BERl9Qb2ludChtX3JjUGxhdGUubGVmdCxtX3JjUGxhdGUudG9wKTt9DQotCUNQREZfUG9pbnQJCQkJCQlHZXRFVFBvaW50KCkgY29uc3R7cmV0dXJuIENQREZfUG9pbnQobV9yY1BsYXRlLnJpZ2h0LG1fcmNQbGF0ZS5ib3R0b20pO30NCi1wdWJsaWM6DQotCUNQREZfUG9pbnQJCQkJCQlJbm5lclRvT3V0ZXIoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdHtyZXR1cm4gQ1BERl9Qb2ludChwb2ludC54ICsgR2V0QlRQb2ludCgpLngsR2V0QlRQb2ludCgpLnkgLSBwb2ludC55KTt9DQotCUNQREZfUG9pbnQJCQkJCQlPdXRlclRvSW5uZXIoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdHtyZXR1cm4gQ1BERl9Qb2ludChwb2ludC54IC0gR2V0QlRQb2ludCgpLngsR2V0QlRQb2ludCgpLnkgLSBwb2ludC55KTt9DQotCUNQREZfUmVjdAkJCQkJCUlubmVyVG9PdXRlcihjb25zdCBDTFNUX1JlY3QgJiByZWN0KSBjb25zdHtDUERGX1BvaW50IHB0TGVmdFRvcCA9IElubmVyVG9PdXRlcihDUERGX1BvaW50KHJlY3QubGVmdCxyZWN0LnRvcCkpOw0KLQkJCQkJCQkJCQkJCQkJCQkJCQlDUERGX1BvaW50IHB0UmlnaHRCb3R0b20gPSBJbm5lclRvT3V0ZXIoQ1BERl9Qb2ludChyZWN0LnJpZ2h0LHJlY3QuYm90dG9tKSk7DQotCQkJCQkJCQkJCQkJCQkJCQkJCXJldHVybiBDUERGX1JlY3QocHRMZWZ0VG9wLngscHRSaWdodEJvdHRvbS55LHB0UmlnaHRCb3R0b20ueCxwdExlZnRUb3AueSk7fQ0KLQlDTFNUX1JlY3QJCQkJCQlPdXRlclRvSW5uZXIoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgY29uc3R7Q1BERl9Qb2ludCBwdExlZnRUb3AgPSBPdXRlclRvSW5uZXIoQ1BERl9Qb2ludChyZWN0LmxlZnQscmVjdC50b3ApKTsNCi0JCQkJCQkJCQkJCQkJCQkJCQkJQ1BERl9Qb2ludCBwdFJpZ2h0Qm90dG9tID0gT3V0ZXJUb0lubmVyKENQREZfUG9pbnQocmVjdC5yaWdodCxyZWN0LmJvdHRvbSkpOw0KLQkJCQkJCQkJCQkJCQkJCQkJCQlyZXR1cm4gQ0xTVF9SZWN0KHB0TGVmdFRvcC54LHB0TGVmdFRvcC55LHB0UmlnaHRCb3R0b20ueCxwdFJpZ2h0Qm90dG9tLnkpO30NCi1wcml2YXRlOg0KLQlDUERGX1JlY3QJCQkJCQltX3JjUGxhdGU7IAkNCi0JQ0xTVF9SZWN0CQkJCQkJbV9yY0NvbnRlbnQ7CQkvL3Bvc2l0aXZlIGZvcmV2ZXIhDQotfTsNCi0NCi10ZW1wbGF0ZTxjbGFzcyBUWVBFPiBjbGFzcyBDTFNUX0FycmF5VGVtcGxhdGUgOiBwdWJsaWMgQ0ZYX0FycmF5VGVtcGxhdGU8VFlQRT4NCi17DQotcHVibGljOgkNCi0JRlhfQk9PTCBJc0VtcHR5KCkgeyByZXR1cm4gQ0ZYX0FycmF5VGVtcGxhdGU8VFlQRT46OkdldFNpemUoKSA8PSAwOyB9DQotCVRZUEUgR2V0QXQoRlhfSU5UMzIgbkluZGV4KSBjb25zdCB7IGlmIChuSW5kZXggPj0gMCAmJiBuSW5kZXggPCBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6R2V0U2l6ZSgpKSByZXR1cm4gQ0ZYX0FycmF5VGVtcGxhdGU8VFlQRT46OkdldEF0KG5JbmRleCk7IHJldHVybiBOVUxMO30NCi0Jdm9pZCBSZW1vdmVBdChGWF9JTlQzMiBuSW5kZXgpe2lmIChuSW5kZXggPj0gMCAmJiBuSW5kZXggPCBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6R2V0U2l6ZSgpKSBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6UmVtb3ZlQXQobkluZGV4KTt9DQotfTsNCi0NCi1jbGFzcyBDRlhfTGlzdCA6IHByb3RlY3RlZCBDRlhfTGlzdENvbnRhaW5lciAsIHB1YmxpYyBJRlhfTGlzdA0KLXsNCi1wdWJsaWM6DQotCUNGWF9MaXN0KCk7DQotCXZpcnR1YWwgfkNGWF9MaXN0KCk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldEZvbnRNYXAoSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpOw0KLQ0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRQbGF0ZVJlY3QoKSBjb25zdDsNCi0JdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Q29udGVudFJlY3QoKSBjb25zdDsNCi0NCi0JdmlydHVhbCBGWF9GTE9BVAkJCQlHZXRGb250U2l6ZSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIElGWF9FZGl0KgkJCQlHZXRJdGVtRWRpdChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0Ow0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCUdldENvdW50KCkgY29uc3Q7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJSXNJdGVtU2VsZWN0ZWQoRlhfSU5UMzIgbkluZGV4KSBjb25zdDsNCi0JdmlydHVhbCBGWF9GTE9BVAkJCQlHZXRGaXJzdEhlaWdodCgpIGNvbnN0Ow0KLQkNCi0JdmlydHVhbCB2b2lkCQkJCQlTZXRNdWx0aXBsZVNlbChGWF9CT09MIGJNdWx0aXBsZSk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJSXNNdWx0aXBsZVNlbCgpIGNvbnN0OwkNCi0JdmlydHVhbCBGWF9CT09MCQkJCQlJc1ZhbGlkKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Ow0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCUZpbmROZXh0KEZYX0lOVDMyIG5JbmRleCxGWF9XQ0hBUiBuQ2hhcikgY29uc3Q7CQ0KLQ0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCB2b2lkCQkJCQlFbXB0eSgpOw0KLQ0KLQl2b2lkCQkJCQkJCUFkZEl0ZW0oRlhfTFBDV1NUUiBzdHIpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVJlQXJyYW5nZShGWF9JTlQzMiBuSXRlbUluZGV4KTsJDQotDQotCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUdldEl0ZW1SZWN0KEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7CQ0KLQlDRlhfV2lkZVN0cmluZwkJCQkJR2V0SXRlbVRleHQoRlhfSU5UMzIgbkluZGV4KSBjb25zdDsNCi0NCi0Jdm9pZAkJCQkJCQlTZXRJdGVtU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYlNlbGVjdGVkKTsNCi0Jdm9pZAkJCQkJCQlTZXRJdGVtQ2FyZXQoRlhfSU5UMzIgbkl0ZW1JbmRleCwgRlhfQk9PTCBiQ2FyZXQpOw0KLQ0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCUdldEl0ZW1JbmRleChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0OwkJDQotCUZYX0lOVDMyCQkJCQkJR2V0Rmlyc3RTZWxlY3RlZCgpIGNvbnN0Ow0KLQlGWF9JTlQzMgkJCQkJCUdldExhc3RTZWxlY3RlZCgpIGNvbnN0Ow0KLQlGWF9XQ0hBUgkJCQkJCVRvdXBwZXIoRlhfV0NIQVIgYykgY29uc3Q7DQotCQkNCi1wcml2YXRlOg0KLQlDTFNUX0FycmF5VGVtcGxhdGU8Q0ZYX0xpc3RJdGVtKj4JbV9hTGlzdEl0ZW1zOw0KLQlGWF9GTE9BVAkJCQkJCQltX2ZGb250U2l6ZTsNCi0JSUZYX0VkaXRfRm9udE1hcCoJCQkJCW1fcEZvbnRNYXA7DQotCUZYX0JPT0wJCQkJCQkJCW1fYk11bHRpcGxlOwkNCi19Ow0KLQ0KLXN0cnVjdCBDUExTVF9TZWxlY3RfSXRlbQ0KLXsNCi0JQ1BMU1RfU2VsZWN0X0l0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCxGWF9JTlQzMiBuU3RhdGUpDQotCXsNCi0JCXRoaXMtPm5JdGVtSW5kZXggPSBuSXRlbUluZGV4Ow0KLQkJdGhpcy0+blN0YXRlID0gblN0YXRlOw0KLQl9DQotDQotCUZYX0lOVDMyCQluSXRlbUluZGV4Ow0KLQlGWF9JTlQzMgkJblN0YXRlOyAvLzA6bm9ybWFsIHNlbGVjdCAtMTp0byBkZXNlbGVjdCAxOiB0byBzZWxlY3QNCi19Ow0KLQ0KLWNsYXNzIENQTFNUX1NlbGVjdA0KLXsNCi1wdWJsaWM6DQotCUNQTFNUX1NlbGVjdCgpOw0KLQl2aXJ0dWFsIH5DUExTVF9TZWxlY3QoKTsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQkJQWRkKEZYX0lOVDMyIG5JdGVtSW5kZXgpOw0KLQl2b2lkCQkJCQkJCUFkZChGWF9JTlQzMiBuQmVnaW5JbmRleCwgRlhfSU5UMzIgbkVuZEluZGV4KTsNCi0Jdm9pZAkJCQkJCQlTdWIoRlhfSU5UMzIgbkl0ZW1JbmRleCk7DQotCXZvaWQJCQkJCQkJU3ViKEZYX0lOVDMyIG5CZWdpbkluZGV4LCBGWF9JTlQzMiBuRW5kSW5kZXgpOw0KLQlGWF9CT09MCQkJCQkJCUlzRXhpc3QoRlhfSU5UMzIgbkl0ZW1JbmRleCkgY29uc3Q7DQotCUZYX0lOVDMyCQkJCQkJRmluZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdDsNCi0JRlhfSU5UMzIJCQkJCQlHZXRDb3VudCgpIGNvbnN0Ow0KLQlGWF9JTlQzMgkJCQkJCUdldEl0ZW1JbmRleChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0Ow0KLQlGWF9JTlQzMgkJCQkJCUdldFN0YXRlKEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7DQotCXZvaWQJCQkJCQkJRG9uZSgpOw0KLQl2b2lkCQkJCQkJCURlc2VsZWN0QWxsKCk7DQotDQotcHJpdmF0ZToNCi0JQ0ZYX0FycmF5VGVtcGxhdGU8Q1BMU1RfU2VsZWN0X0l0ZW0qPgltX2FJdGVtczsNCi19Ow0KLQ0KLWNsYXNzIENGWF9MaXN0Q3RybCA6IHB1YmxpYyBDRlhfTGlzdA0KLXsNCi1wdWJsaWM6DQotCUNGWF9MaXN0Q3RybCgpOw0KLQl2aXJ0dWFsIH5DRlhfTGlzdEN0cmwoKTsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQkJU2V0Tm90aWZ5KElGWF9MaXN0X05vdGlmeSAqIHBOb3RpZnkpOw0KLQ0KLQl2b2lkCQkJCQkJCU9uTW91c2VEb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsNCi0Jdm9pZAkJCQkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7DQotCXZvaWQJCQkJCQkJT25WS19VUChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsNCi0Jdm9pZAkJCQkJCQlPblZLX0RPV04oRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7DQotCXZvaWQJCQkJCQkJT25WS19MRUZUKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOw0KLQl2b2lkCQkJCQkJCU9uVktfUklHSFQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7DQotCXZvaWQJCQkJCQkJT25WS19IT01FKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOw0KLQl2b2lkCQkJCQkJCU9uVktfRU5EKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOw0KLQl2b2lkCQkJCQkJCU9uVksoRlhfSU5UMzIgbkl0ZW1JbmRleCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsNCi0JRlhfQk9PTAkJCQkJCQlPbkNoYXIoRlhfV09SRCBuQ2hhcixGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsNCi0NCi0JdmlydHVhbCBDUERGX1BvaW50CQkJCUluVG9PdXQoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdDsNCi0JdmlydHVhbCBDUERGX1BvaW50CQkJCU91dFRvSW4oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdDsNCi0JdmlydHVhbCBDUERGX1JlY3QJCQkJSW5Ub091dChjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdDsNCi0JdmlydHVhbCBDUERGX1JlY3QJCQkJT3V0VG9Jbihjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQlTZXRQbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCk7DQotCXZvaWQJCQkJCQkJU2V0U2Nyb2xsUG9zKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7DQotCXZvaWQJCQkJCQkJU2Nyb2xsVG9MaXN0SXRlbShGWF9JTlQzMiBuSXRlbUluZGV4KTsNCi0JdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0SXRlbVJlY3QoRlhfSU5UMzIgbkluZGV4KSBjb25zdDsNCi0JRlhfSU5UMzIJCQkJCQlHZXRDYXJldCgpIGNvbnN0IHtyZXR1cm4gbV9uQ2FyZXRJbmRleDt9DQotCUZYX0lOVDMyCQkJCQkJR2V0U2VsZWN0KCkgY29uc3Qge3JldHVybiBtX25TZWxJdGVtO30JDQotCUZYX0lOVDMyCQkJCQkJR2V0VG9wSXRlbSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0Ow0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCUdldEl0ZW1JbmRleChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0Ow0KLQ0KLQl2b2lkCQkJCQkJCUFkZFN0cmluZyhGWF9MUENXU1RSIHN0cmluZyk7DQotCXZvaWQJCQkJCQkJU2V0VG9wSXRlbShGWF9JTlQzMiBuSW5kZXgpOwkNCi0Jdm9pZAkJCQkJCQlTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJU2V0Q2FyZXQoRlhfSU5UMzIgbkl0ZW1JbmRleCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJRW1wdHkoKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlDYW5jZWwoKTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFRleHQoKSBjb25zdDsNCi0NCi1wcml2YXRlOg0KLQl2b2lkCQkJCQkJCVNldE11bHRpcGxlU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYlNlbGVjdGVkKTsNCi0Jdm9pZAkJCQkJCQlTZXRTaW5nbGVTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCk7DQotCXZvaWQJCQkJCQkJSW52YWxpZGF0ZUl0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCk7DQotCXZvaWQJCQkJCQkJU2VsZWN0SXRlbXMoKTsNCi0JRlhfQk9PTAkJCQkJCQlJc0l0ZW1WaXNpYmxlKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0OwkJDQotCXZvaWQJCQkJCQkJU2V0U2Nyb2xsSW5mbygpOw0KLQl2b2lkCQkJCQkJCVNldFNjcm9sbFBvc1koRlhfRkxPQVQgZnkpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVJlQXJyYW5nZShGWF9JTlQzMiBuSXRlbUluZGV4KTsJDQotDQotcHJpdmF0ZToNCi0JSUZYX0xpc3RfTm90aWZ5KgkJCQltX3BOb3RpZnk7DQotCUZYX0JPT0wJCQkJCQkJbV9iTm90aWZ5RmxhZzsNCi0JQ1BERl9Qb2ludAkJCQkJCW1fcHRTY3JvbGxQb3M7DQotCUNQTFNUX1NlbGVjdAkJCQkJbV9hU2VsSXRlbXM7CS8vZm9yIG11bHRpcGxlDQotCUZYX0lOVDMyCQkJCQkJbV9uU2VsSXRlbTsJCS8vZm9yIHNpbmdsZQ0KLQlGWF9JTlQzMgkJCQkJCW1fbkZvb3RJbmRleDsJLy9mb3IgbXVsdGlwbGUNCi0JRlhfQk9PTAkJCQkJCQltX2JDdHJsU2VsOwkJLy9mb3IgbXVsdGlwbGUNCi0JRlhfSU5UMzIJCQkJCQltX25DYXJldEluZGV4OwkvL2ZvciBtdWx0aXBsZQ0KLX07DQotDQotI2VuZGlmDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRlhFVF9MSVNUX0hfCisjZGVmaW5lIF9GWEVUX0xJU1RfSF8KKworI2luY2x1ZGUgImZ4X2VkaXQuaCIKKworY2xhc3MgSUZYX0VkaXQ7CisKK2NsYXNzIENMU1RfU2l6ZQoreworcHVibGljOgorCUNMU1RfU2l6ZSgpIDogeCgwLjBmKSwgeSgwLjBmKQorCXsJCQorCX0KKworCUNMU1RfU2l6ZShGWF9GTE9BVCB4LEZYX0ZMT0FUIHkpCisJeyAKKwkJdGhpcy0+eCA9IHg7CisJCXRoaXMtPnkgPSB5OworCX0KKworCXZvaWQgRGVmYXVsdCgpCisJeworCQl4ID0gMC4wZjsKKwkJeSA9IDAuMGY7CisJfQorCisJRlhfQk9PTCBvcGVyYXRvciAhPSAoY29uc3QgQ0xTVF9TaXplICYgc2l6ZSkgY29uc3QKKwl7CisJCXJldHVybiBGWFNZU19tZW1jbXAodGhpcywgJnNpemUsIHNpemVvZihDTFNUX1NpemUpKSAhPSAwOworCX0KKworCUZYX0ZMT0FUIHgseTsKK307CisKK2NsYXNzIENMU1RfUmVjdCA6IHB1YmxpYyBDUERGX1JlY3QKK3sKK3B1YmxpYzoKKwlDTFNUX1JlY3QoKQorCXsJCisJCWxlZnQgPSB0b3AgPSByaWdodCA9IGJvdHRvbSA9IDAuMGY7CisJfQorCisJQ0xTVF9SZWN0KEZYX0ZMT0FUIGxlZnQsRlhfRkxPQVQgdG9wLAorCQkJCQkJRlhfRkxPQVQgcmlnaHQsRlhfRkxPQVQgYm90dG9tKQorCXsgCisJCXRoaXMtPmxlZnQgPSBsZWZ0OyAKKwkJdGhpcy0+dG9wID0gdG9wOyAKKwkJdGhpcy0+cmlnaHQgPSByaWdodDsgCisJCXRoaXMtPmJvdHRvbSA9IGJvdHRvbTsgCisJfQorCisJQ0xTVF9SZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QpCisJeyAKKwkJdGhpcy0+bGVmdCA9IHJlY3QubGVmdDsgCisJCXRoaXMtPnRvcCA9IHJlY3QudG9wOyAKKwkJdGhpcy0+cmlnaHQgPSByZWN0LnJpZ2h0OyAKKwkJdGhpcy0+Ym90dG9tID0gcmVjdC5ib3R0b207IAorCX0KKworCXZvaWQgRGVmYXVsdCgpCisJeworCQlsZWZ0ID0gdG9wID0gcmlnaHQgPSBib3R0b20gPSAwLjBmOworCX0KKworCWNvbnN0IENMU1RfUmVjdCBvcGVyYXRvciA9IChjb25zdCBDUERGX1JlY3QgJiByZWN0KQorCXsKKwkJdGhpcy0+bGVmdCA9IHJlY3QubGVmdDsKKwkJdGhpcy0+dG9wID0gcmVjdC50b3A7CisJCXRoaXMtPnJpZ2h0ID0gcmVjdC5yaWdodDsKKwkJdGhpcy0+Ym90dG9tID0gcmVjdC5ib3R0b207CisKKwkJcmV0dXJuICp0aGlzOworCX0KKworCUZYX0JPT0wgb3BlcmF0b3IgPT0gKGNvbnN0IENMU1RfUmVjdCAmIHJlY3QpIGNvbnN0CisJeworCQlyZXR1cm4gRlhTWVNfbWVtY21wKHRoaXMsICZyZWN0LCBzaXplb2YoQ0xTVF9SZWN0KSkgPT0gMDsKKwl9CisKKwlGWF9CT09MIG9wZXJhdG9yICE9IChjb25zdCBDTFNUX1JlY3QgJiByZWN0KSBjb25zdAorCXsKKwkJcmV0dXJuIEZYU1lTX21lbWNtcCh0aGlzLCAmcmVjdCwgc2l6ZW9mKENMU1RfUmVjdCkpICE9IDA7CisJfQorCisJRlhfRkxPQVQgV2lkdGgoKSBjb25zdAorCXsKKwkJcmV0dXJuIHRoaXMtPnJpZ2h0IC0gdGhpcy0+bGVmdDsKKwl9CisKKwlGWF9GTE9BVCBIZWlnaHQoKSBjb25zdAorCXsKKwkJaWYgKHRoaXMtPnRvcCA+IHRoaXMtPmJvdHRvbSkKKwkJCXJldHVybiB0aGlzLT50b3AgLSB0aGlzLT5ib3R0b207CisJCWVsc2UKKwkJCXJldHVybiB0aGlzLT5ib3R0b20gLSB0aGlzLT50b3A7CisJfQorCisJQ1BERl9Qb2ludCBMZWZ0VG9wKCkgY29uc3QKKwl7CisJCXJldHVybiBDUERGX1BvaW50KGxlZnQsdG9wKTsKKwl9CisKKwlDUERGX1BvaW50IFJpZ2h0Qm90dG9tKCkgY29uc3QKKwl7CisJCXJldHVybiBDUERGX1BvaW50KHJpZ2h0LGJvdHRvbSk7CisJfQorCisJY29uc3QgQ0xTVF9SZWN0IG9wZXJhdG9yICs9IChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIAorCXsKKwkJdGhpcy0+bGVmdCArPSBwb2ludC54OworCQl0aGlzLT5yaWdodCArPSBwb2ludC54OworCQl0aGlzLT50b3AgKz0gcG9pbnQueTsKKwkJdGhpcy0+Ym90dG9tICs9IHBvaW50Lnk7CisKKwkJcmV0dXJuICp0aGlzOworCX0KKworCWNvbnN0IENMU1RfUmVjdCBvcGVyYXRvciAtPSAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSAKKwl7CisJCXRoaXMtPmxlZnQgLT0gcG9pbnQueDsKKwkJdGhpcy0+cmlnaHQgLT0gcG9pbnQueDsKKwkJdGhpcy0+dG9wIC09IHBvaW50Lnk7CisJCXRoaXMtPmJvdHRvbSAtPSBwb2ludC55OworCisJCXJldHVybiAqdGhpczsKKwl9CisKKwlDTFNUX1JlY3Qgb3BlcmF0b3IgKyAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdAorCXsKKwkJcmV0dXJuIENMU1RfUmVjdChsZWZ0ICsgcG9pbnQueCwKKwkJCQkJdG9wICsgcG9pbnQueSwKKwkJCQkJcmlnaHQgKyBwb2ludC54LAorCQkJCQlib3R0b20gKyBwb2ludC55KTsKKwl9CisKKwlDTFNUX1JlY3Qgb3BlcmF0b3IgLSAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdAorCXsKKwkJcmV0dXJuIENMU1RfUmVjdChsZWZ0IC0gcG9pbnQueCwKKwkJCQkJdG9wIC0gcG9pbnQueSwKKwkJCQkJcmlnaHQgLSBwb2ludC54LAorCQkJCQlib3R0b20gLSBwb2ludC55KTsKKwl9Cit9OworCitjbGFzcyBDRlhfTGlzdEl0ZW0KK3sKK3B1YmxpYzoKKwlDRlhfTGlzdEl0ZW0oKTsKKwl2aXJ0dWFsIH5DRlhfTGlzdEl0ZW0oKTsKKworCXZvaWQJCQkJCQkJU2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApOworCUlGWF9FZGl0X0l0ZXJhdG9yKgkJCQlHZXRJdGVyYXRvcigpIGNvbnN0OworCUlGWF9FZGl0KgkJCQkJCUdldEVkaXQoKSBjb25zdDsKKworcHVibGljOgorCXZvaWQJCQkJCQkJU2V0UmVjdChjb25zdCBDTFNUX1JlY3QgJiByZWN0KTsJCQorCXZvaWQJCQkJCQkJU2V0U2VsZWN0KEZYX0JPT0wgYlNlbGVjdGVkKTsJCisJdm9pZAkJCQkJCQlTZXRDYXJldChGWF9CT09MIGJDYXJldCk7CisJdm9pZAkJCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgdGV4dCk7CisJdm9pZAkJCQkJCQlTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpOworCUNGWF9XaWRlU3RyaW5nCQkJCQlHZXRUZXh0KCkgY29uc3Q7CisKKwlDTFNUX1JlY3QJCQkJCQlHZXRSZWN0KCkgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQlJc1NlbGVjdGVkKCkgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQlJc0NhcmV0KCkgY29uc3Q7CisJRlhfRkxPQVQJCQkJCQlHZXRJdGVtSGVpZ2h0KCkgY29uc3Q7CQorCUZYX1dPUkQJCQkJCQkJR2V0Rmlyc3RDaGFyKCkgY29uc3Q7CisKK3ByaXZhdGU6CisJSUZYX0VkaXQqCQkJCQkJbV9wRWRpdDsKKwlGWF9CT09MCQkJCQkJCW1fYlNlbGVjdGVkOwkJLy/Kx7fx0aHW0AorCUZYX0JPT0wJCQkJCQkJbV9iQ2FyZXQ7CQkvL8rHt/HOqr25teOjrLbg0aHKsdPDCisJQ0xTVF9SZWN0CQkJCQkJbV9yY0xpc3RJdGVtOwkvL8Tasr/X+LHqCit9OworCitjbGFzcyBDRlhfTGlzdENvbnRhaW5lcgoreworcHVibGljOgorCUNGWF9MaXN0Q29udGFpbmVyKCkgOiBtX3JjUGxhdGUoMC4wZiwwLjBmLDAuMGYsMC4wZiksIG1fcmNDb250ZW50KDAuMGYsMC4wZiwwLjBmLDAuMGYpe30KKwl2aXJ0dWFsIH5DRlhfTGlzdENvbnRhaW5lcigpe30KKwl2aXJ0dWFsIHZvaWQJCQkJCVNldFBsYXRlUmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0KXttX3JjUGxhdGUgPSByZWN0O30KKwlDUERGX1JlY3QJCQkJCQlHZXRQbGF0ZVJlY3QoKSBjb25zdHtyZXR1cm4gbV9yY1BsYXRlO30KKwl2b2lkCQkJCQkJCVNldENvbnRlbnRSZWN0KGNvbnN0IENMU1RfUmVjdCAmIHJlY3Qpe21fcmNDb250ZW50ID0gcmVjdDt9CisJQ0xTVF9SZWN0CQkJCQkJR2V0Q29udGVudFJlY3QoKSBjb25zdHtyZXR1cm4gbV9yY0NvbnRlbnQ7fQorCUNQREZfUG9pbnQJCQkJCQlHZXRCVFBvaW50KCkgY29uc3R7cmV0dXJuIENQREZfUG9pbnQobV9yY1BsYXRlLmxlZnQsbV9yY1BsYXRlLnRvcCk7fQorCUNQREZfUG9pbnQJCQkJCQlHZXRFVFBvaW50KCkgY29uc3R7cmV0dXJuIENQREZfUG9pbnQobV9yY1BsYXRlLnJpZ2h0LG1fcmNQbGF0ZS5ib3R0b20pO30KK3B1YmxpYzoKKwlDUERGX1BvaW50CQkJCQkJSW5uZXJUb091dGVyKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3R7cmV0dXJuIENQREZfUG9pbnQocG9pbnQueCArIEdldEJUUG9pbnQoKS54LEdldEJUUG9pbnQoKS55IC0gcG9pbnQueSk7fQorCUNQREZfUG9pbnQJCQkJCQlPdXRlclRvSW5uZXIoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdHtyZXR1cm4gQ1BERl9Qb2ludChwb2ludC54IC0gR2V0QlRQb2ludCgpLngsR2V0QlRQb2ludCgpLnkgLSBwb2ludC55KTt9CisJQ1BERl9SZWN0CQkJCQkJSW5uZXJUb091dGVyKGNvbnN0IENMU1RfUmVjdCAmIHJlY3QpIGNvbnN0e0NQREZfUG9pbnQgcHRMZWZ0VG9wID0gSW5uZXJUb091dGVyKENQREZfUG9pbnQocmVjdC5sZWZ0LHJlY3QudG9wKSk7CisJCQkJCQkJCQkJCQkJCQkJCQkJQ1BERl9Qb2ludCBwdFJpZ2h0Qm90dG9tID0gSW5uZXJUb091dGVyKENQREZfUG9pbnQocmVjdC5yaWdodCxyZWN0LmJvdHRvbSkpOworCQkJCQkJCQkJCQkJCQkJCQkJCXJldHVybiBDUERGX1JlY3QocHRMZWZ0VG9wLngscHRSaWdodEJvdHRvbS55LHB0UmlnaHRCb3R0b20ueCxwdExlZnRUb3AueSk7fQorCUNMU1RfUmVjdAkJCQkJCU91dGVyVG9Jbm5lcihjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdHtDUERGX1BvaW50IHB0TGVmdFRvcCA9IE91dGVyVG9Jbm5lcihDUERGX1BvaW50KHJlY3QubGVmdCxyZWN0LnRvcCkpOworCQkJCQkJCQkJCQkJCQkJCQkJCUNQREZfUG9pbnQgcHRSaWdodEJvdHRvbSA9IE91dGVyVG9Jbm5lcihDUERGX1BvaW50KHJlY3QucmlnaHQscmVjdC5ib3R0b20pKTsKKwkJCQkJCQkJCQkJCQkJCQkJCQlyZXR1cm4gQ0xTVF9SZWN0KHB0TGVmdFRvcC54LHB0TGVmdFRvcC55LHB0UmlnaHRCb3R0b20ueCxwdFJpZ2h0Qm90dG9tLnkpO30KK3ByaXZhdGU6CisJQ1BERl9SZWN0CQkJCQkJbV9yY1BsYXRlOyAJCisJQ0xTVF9SZWN0CQkJCQkJbV9yY0NvbnRlbnQ7CQkvL3Bvc2l0aXZlIGZvcmV2ZXIhCit9OworCit0ZW1wbGF0ZTxjbGFzcyBUWVBFPiBjbGFzcyBDTFNUX0FycmF5VGVtcGxhdGUgOiBwdWJsaWMgQ0ZYX0FycmF5VGVtcGxhdGU8VFlQRT4KK3sKK3B1YmxpYzoJCisJRlhfQk9PTCBJc0VtcHR5KCkgeyByZXR1cm4gQ0ZYX0FycmF5VGVtcGxhdGU8VFlQRT46OkdldFNpemUoKSA8PSAwOyB9CisJVFlQRSBHZXRBdChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0IHsgaWYgKG5JbmRleCA+PSAwICYmIG5JbmRleCA8IENGWF9BcnJheVRlbXBsYXRlPFRZUEU+OjpHZXRTaXplKCkpIHJldHVybiBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6R2V0QXQobkluZGV4KTsgcmV0dXJuIE5VTEw7fQorCXZvaWQgUmVtb3ZlQXQoRlhfSU5UMzIgbkluZGV4KXtpZiAobkluZGV4ID49IDAgJiYgbkluZGV4IDwgQ0ZYX0FycmF5VGVtcGxhdGU8VFlQRT46OkdldFNpemUoKSkgQ0ZYX0FycmF5VGVtcGxhdGU8VFlQRT46OlJlbW92ZUF0KG5JbmRleCk7fQorfTsKKworY2xhc3MgQ0ZYX0xpc3QgOiBwcm90ZWN0ZWQgQ0ZYX0xpc3RDb250YWluZXIgLCBwdWJsaWMgSUZYX0xpc3QKK3sKK3B1YmxpYzoKKwlDRlhfTGlzdCgpOworCXZpcnR1YWwgfkNGWF9MaXN0KCk7CisKK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQkJCVNldEZvbnRNYXAoSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCVNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSk7CisKKwl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRQbGF0ZVJlY3QoKSBjb25zdDsKKwl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0OworCisJdmlydHVhbCBGWF9GTE9BVAkJCQlHZXRGb250U2l6ZSgpIGNvbnN0OworCXZpcnR1YWwgSUZYX0VkaXQqCQkJCUdldEl0ZW1FZGl0KEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7CisJdmlydHVhbCBGWF9JTlQzMgkJCQlHZXRDb3VudCgpIGNvbnN0OworCXZpcnR1YWwgRlhfQk9PTAkJCQkJSXNJdGVtU2VsZWN0ZWQoRlhfSU5UMzIgbkluZGV4KSBjb25zdDsKKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJCUdldEZpcnN0SGVpZ2h0KCkgY29uc3Q7CisJCisJdmlydHVhbCB2b2lkCQkJCQlTZXRNdWx0aXBsZVNlbChGWF9CT09MIGJNdWx0aXBsZSk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlJc011bHRpcGxlU2VsKCkgY29uc3Q7CQorCXZpcnR1YWwgRlhfQk9PTAkJCQkJSXNWYWxpZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdDsKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJCUZpbmROZXh0KEZYX0lOVDMyIG5JbmRleCxGWF9XQ0hBUiBuQ2hhcikgY29uc3Q7CQorCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQlFbXB0eSgpOworCisJdm9pZAkJCQkJCQlBZGRJdGVtKEZYX0xQQ1dTVFIgc3RyKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCVJlQXJyYW5nZShGWF9JTlQzMiBuSXRlbUluZGV4KTsJCisKKwl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRJdGVtUmVjdChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0OwkKKwlDRlhfV2lkZVN0cmluZwkJCQkJR2V0SXRlbVRleHQoRlhfSU5UMzIgbkluZGV4KSBjb25zdDsKKworCXZvaWQJCQkJCQkJU2V0SXRlbVNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4LCBGWF9CT09MIGJTZWxlY3RlZCk7CisJdm9pZAkJCQkJCQlTZXRJdGVtQ2FyZXQoRlhfSU5UMzIgbkl0ZW1JbmRleCwgRlhfQk9PTCBiQ2FyZXQpOworCisJdmlydHVhbCBGWF9JTlQzMgkJCQlHZXRJdGVtSW5kZXgoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdDsJCQorCUZYX0lOVDMyCQkJCQkJR2V0Rmlyc3RTZWxlY3RlZCgpIGNvbnN0OworCUZYX0lOVDMyCQkJCQkJR2V0TGFzdFNlbGVjdGVkKCkgY29uc3Q7CisJRlhfV0NIQVIJCQkJCQlUb3VwcGVyKEZYX1dDSEFSIGMpIGNvbnN0OworCQkKK3ByaXZhdGU6CisJQ0xTVF9BcnJheVRlbXBsYXRlPENGWF9MaXN0SXRlbSo+CW1fYUxpc3RJdGVtczsKKwlGWF9GTE9BVAkJCQkJCQltX2ZGb250U2l6ZTsKKwlJRlhfRWRpdF9Gb250TWFwKgkJCQkJbV9wRm9udE1hcDsKKwlGWF9CT09MCQkJCQkJCQltX2JNdWx0aXBsZTsJCit9OworCitzdHJ1Y3QgQ1BMU1RfU2VsZWN0X0l0ZW0KK3sKKwlDUExTVF9TZWxlY3RfSXRlbShGWF9JTlQzMiBuSXRlbUluZGV4LEZYX0lOVDMyIG5TdGF0ZSkKKwl7CisJCXRoaXMtPm5JdGVtSW5kZXggPSBuSXRlbUluZGV4OworCQl0aGlzLT5uU3RhdGUgPSBuU3RhdGU7CisJfQorCisJRlhfSU5UMzIJCW5JdGVtSW5kZXg7CisJRlhfSU5UMzIJCW5TdGF0ZTsgLy8wOm5vcm1hbCBzZWxlY3QgLTE6dG8gZGVzZWxlY3QgMTogdG8gc2VsZWN0Cit9OworCitjbGFzcyBDUExTVF9TZWxlY3QKK3sKK3B1YmxpYzoKKwlDUExTVF9TZWxlY3QoKTsKKwl2aXJ0dWFsIH5DUExTVF9TZWxlY3QoKTsKKworcHVibGljOgorCXZvaWQJCQkJCQkJQWRkKEZYX0lOVDMyIG5JdGVtSW5kZXgpOworCXZvaWQJCQkJCQkJQWRkKEZYX0lOVDMyIG5CZWdpbkluZGV4LCBGWF9JTlQzMiBuRW5kSW5kZXgpOworCXZvaWQJCQkJCQkJU3ViKEZYX0lOVDMyIG5JdGVtSW5kZXgpOworCXZvaWQJCQkJCQkJU3ViKEZYX0lOVDMyIG5CZWdpbkluZGV4LCBGWF9JTlQzMiBuRW5kSW5kZXgpOworCUZYX0JPT0wJCQkJCQkJSXNFeGlzdChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdDsKKwlGWF9JTlQzMgkJCQkJCUZpbmQoRlhfSU5UMzIgbkl0ZW1JbmRleCkgY29uc3Q7CisJRlhfSU5UMzIJCQkJCQlHZXRDb3VudCgpIGNvbnN0OworCUZYX0lOVDMyCQkJCQkJR2V0SXRlbUluZGV4KEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7CisJRlhfSU5UMzIJCQkJCQlHZXRTdGF0ZShGWF9JTlQzMiBuSW5kZXgpIGNvbnN0OworCXZvaWQJCQkJCQkJRG9uZSgpOworCXZvaWQJCQkJCQkJRGVzZWxlY3RBbGwoKTsKKworcHJpdmF0ZToKKwlDRlhfQXJyYXlUZW1wbGF0ZTxDUExTVF9TZWxlY3RfSXRlbSo+CW1fYUl0ZW1zOworfTsKKworY2xhc3MgQ0ZYX0xpc3RDdHJsIDogcHVibGljIENGWF9MaXN0Cit7CitwdWJsaWM6CisJQ0ZYX0xpc3RDdHJsKCk7CisJdmlydHVhbCB+Q0ZYX0xpc3RDdHJsKCk7CisKK3B1YmxpYzoKKwl2b2lkCQkJCQkJCVNldE5vdGlmeShJRlhfTGlzdF9Ob3RpZnkgKiBwTm90aWZ5KTsKKworCXZvaWQJCQkJCQkJT25Nb3VzZURvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOworCXZvaWQJCQkJCQkJT25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOworCXZvaWQJCQkJCQkJT25WS19VUChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKwl2b2lkCQkJCQkJCU9uVktfRE9XTihGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKwl2b2lkCQkJCQkJCU9uVktfTEVGVChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKwl2b2lkCQkJCQkJCU9uVktfUklHSFQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7CisJdm9pZAkJCQkJCQlPblZLX0hPTUUoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7CisJdm9pZAkJCQkJCQlPblZLX0VORChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKwl2b2lkCQkJCQkJCU9uVksoRlhfSU5UMzIgbkl0ZW1JbmRleCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKKwlGWF9CT09MCQkJCQkJCU9uQ2hhcihGWF9XT1JEIG5DaGFyLEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOworCisJdmlydHVhbCBDUERGX1BvaW50CQkJCUluVG9PdXQoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdDsKKwl2aXJ0dWFsIENQREZfUG9pbnQJCQkJT3V0VG9Jbihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0OworCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUluVG9PdXQoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgY29uc3Q7CisJdmlydHVhbCBDUERGX1JlY3QJCQkJT3V0VG9Jbihjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdDsKKworCXZpcnR1YWwgdm9pZAkJCQkJU2V0UGxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QpOworCXZvaWQJCQkJCQkJU2V0U2Nyb2xsUG9zKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7CisJdm9pZAkJCQkJCQlTY3JvbGxUb0xpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpOworCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUdldEl0ZW1SZWN0KEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7CisJRlhfSU5UMzIJCQkJCQlHZXRDYXJldCgpIGNvbnN0IHtyZXR1cm4gbV9uQ2FyZXRJbmRleDt9CisJRlhfSU5UMzIJCQkJCQlHZXRTZWxlY3QoKSBjb25zdCB7cmV0dXJuIG1fblNlbEl0ZW07fQkKKwlGWF9JTlQzMgkJCQkJCUdldFRvcEl0ZW0oKSBjb25zdDsKKwl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0OworCXZpcnR1YWwgRlhfSU5UMzIJCQkJR2V0SXRlbUluZGV4KGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3Q7CisKKwl2b2lkCQkJCQkJCUFkZFN0cmluZyhGWF9MUENXU1RSIHN0cmluZyk7CisJdm9pZAkJCQkJCQlTZXRUb3BJdGVtKEZYX0lOVDMyIG5JbmRleCk7CQorCXZvaWQJCQkJCQkJU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgpOworCXZpcnR1YWwgdm9pZAkJCQkJU2V0Q2FyZXQoRlhfSU5UMzIgbkl0ZW1JbmRleCk7CisJdmlydHVhbCB2b2lkCQkJCQlFbXB0eSgpOworCXZpcnR1YWwgdm9pZAkJCQkJQ2FuY2VsKCk7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFRleHQoKSBjb25zdDsKKworcHJpdmF0ZToKKwl2b2lkCQkJCQkJCVNldE11bHRpcGxlU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYlNlbGVjdGVkKTsKKwl2b2lkCQkJCQkJCVNldFNpbmdsZVNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4KTsKKwl2b2lkCQkJCQkJCUludmFsaWRhdGVJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpOworCXZvaWQJCQkJCQkJU2VsZWN0SXRlbXMoKTsKKwlGWF9CT09MCQkJCQkJCUlzSXRlbVZpc2libGUoRlhfSU5UMzIgbkl0ZW1JbmRleCkgY29uc3Q7CQkKKwl2b2lkCQkJCQkJCVNldFNjcm9sbEluZm8oKTsKKwl2b2lkCQkJCQkJCVNldFNjcm9sbFBvc1koRlhfRkxPQVQgZnkpOworCXZpcnR1YWwgdm9pZAkJCQkJUmVBcnJhbmdlKEZYX0lOVDMyIG5JdGVtSW5kZXgpOwkKKworcHJpdmF0ZToKKwlJRlhfTGlzdF9Ob3RpZnkqCQkJCW1fcE5vdGlmeTsKKwlGWF9CT09MCQkJCQkJCW1fYk5vdGlmeUZsYWc7CisJQ1BERl9Qb2ludAkJCQkJCW1fcHRTY3JvbGxQb3M7CisJQ1BMU1RfU2VsZWN0CQkJCQltX2FTZWxJdGVtczsJLy9mb3IgbXVsdGlwbGUKKwlGWF9JTlQzMgkJCQkJCW1fblNlbEl0ZW07CQkvL2ZvciBzaW5nbGUKKwlGWF9JTlQzMgkJCQkJCW1fbkZvb3RJbmRleDsJLy9mb3IgbXVsdGlwbGUKKwlGWF9CT09MCQkJCQkJCW1fYkN0cmxTZWw7CQkvL2ZvciBtdWx0aXBsZQorCUZYX0lOVDMyCQkJCQkJbV9uQ2FyZXRJbmRleDsJLy9mb3IgbXVsdGlwbGUKK307CisKKyNlbmRpZgorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfc3R1Yi5oIGIvZnBkZnNkay9pbmNsdWRlL2Z4ZWRpdC9meGV0X3N0dWIuaAppbmRleCBhYTUwY2Q1Li5hMWFhMmUyIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfc3R1Yi5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9meGVkaXQvZnhldF9zdHViLmgKQEAgLTEsMjYgKzEsMjYgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZYRVRfU1RVQl9IXw0KLSNkZWZpbmUgX0ZYRVRfU1RVQl9IXw0KLQ0KLSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX21vZHVsZS5oIiANCi0jaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9yZW5kZXIuaCIgDQotI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfcGFnZW9iai5oIiANCi0jaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl92dC5oIiANCi0jaW5jbHVkZSAiLi4vZnhfc3lzdGVtaGFuZGxlci5oIg0KLSNpZmRlZiBGWF9SRUFERVJfRExMDQotCSNpZmRlZiBfREVCVUcNCi0JCSNwcmFnbWEgY29tbWVudChsaWIsICJYOi9wZGYvZnhjb3JlL0xpYi9kYmdfdzMyX3ZjNi9meGNvcmVkbGxbZGJnLHczMix2YzZdLmxpYiIpDQotCQkjcHJhZ21hIGNvbW1lbnQobGliLCAiWDovcGRmL2Z4Y29yZS9MaWIvZGJnX3czMl92YzYvZnBkZmRvY2RsbFtkYmcsdzMyLHZjNl0ubGliIikNCi0JI2Vsc2UNCi0JCSNwcmFnbWEgY29tbWVudChsaWIsICJYOi9wZGYvZnhjb3JlL0xpYi9yZWxfdzMyX3ZjNi9meGNvcmVkbGxbcmVsLHczMix2YzZdLmxpYiIpDQotCQkjcHJhZ21hIGNvbW1lbnQobGliLCAiWDovcGRmL2Z4Y29yZS9MaWIvcmVsX3czMl92YzYvZnBkZmRvY2RsbFtyZWwsdzMyLHZjNl0ubGliIikNCi0JI2VuZGlmDQotI2VuZGlmDQotDQotI2VuZGlmIA0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0ZYRVRfU1RVQl9IXworI2RlZmluZSBfRlhFVF9TVFVCX0hfCisKKyNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX21vZHVsZS5oIiAKKyNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX3JlbmRlci5oIiAKKyNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX3BhZ2VvYmouaCIgCisjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl92dC5oIiAKKyNpbmNsdWRlICIuLi9meF9zeXN0ZW1oYW5kbGVyLmgiCisjaWZkZWYgRlhfUkVBREVSX0RMTAorCSNpZmRlZiBfREVCVUcKKwkJI3ByYWdtYSBjb21tZW50KGxpYiwgIlg6L3BkZi9meGNvcmUvTGliL2RiZ193MzJfdmM2L2Z4Y29yZWRsbFtkYmcsdzMyLHZjNl0ubGliIikKKwkJI3ByYWdtYSBjb21tZW50KGxpYiwgIlg6L3BkZi9meGNvcmUvTGliL2RiZ193MzJfdmM2L2ZwZGZkb2NkbGxbZGJnLHczMix2YzZdLmxpYiIpCisJI2Vsc2UKKwkJI3ByYWdtYSBjb21tZW50KGxpYiwgIlg6L3BkZi9meGNvcmUvTGliL3JlbF93MzJfdmM2L2Z4Y29yZWRsbFtyZWwsdzMyLHZjNl0ubGliIikKKwkJI3ByYWdtYSBjb21tZW50KGxpYiwgIlg6L3BkZi9meGNvcmUvTGliL3JlbF93MzJfdmM2L2ZwZGZkb2NkbGxbcmVsLHczMix2YzZdLmxpYiIpCisJI2VuZGlmCisjZW5kaWYKKworI2VuZGlmIAorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9Db25zdHMuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0NvbnN0cy5oCmluZGV4IDMyYjAyMTcuLmMzYTk1NGUgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0NvbnN0cy5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0NvbnN0cy5oCkBAIC0xLDEyNiArMSwxMjYgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0NPTlNUU19IXw0KLSNkZWZpbmUgX0NPTlNUU19IXw0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBib3JkZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotY2xhc3MgQ0pTX0JvcmRlciA6IHB1YmxpYyBDSlNfT2JqZWN0DQotew0KLXB1YmxpYzoNCi0JQ0pTX0JvcmRlcihKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19Cb3JkZXIodm9pZCl7fTsNCi0NCi0JREVDTEFSRV9KU19DTEFTU19DT05TVCgpOw0KLX07DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGRpc3BsYXkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotY2xhc3MgQ0pTX0Rpc3BsYXkgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19EaXNwbGF5KEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsNCi0JdmlydHVhbCB+Q0pTX0Rpc3BsYXkodm9pZCl7fTsNCi0NCi0JREVDTEFSRV9KU19DTEFTU19DT05TVCgpOw0KLX07DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvbnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotY2xhc3MgQ0pTX0ZvbnQgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19Gb250KEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsNCi0JdmlydHVhbCB+Q0pTX0ZvbnQodm9pZCl7fTsNCi0NCi0JREVDTEFSRV9KU19DTEFTU19DT05TVCgpOw0KLX07DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGhpZ2hsaWdodCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1jbGFzcyBDSlNfSGlnaGxpZ2h0IDogcHVibGljIENKU19PYmplY3QNCi17DQotcHVibGljOg0KLQlDSlNfSGlnaGxpZ2h0KEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsNCi0JdmlydHVhbCB+Q0pTX0hpZ2hsaWdodCh2b2lkKXt9Ow0KLQ0KLQlERUNMQVJFX0pTX0NMQVNTX0NPTlNUKCk7DQotfTsNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcG9zaXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotY2xhc3MgQ0pTX1Bvc2l0aW9uIDogcHVibGljIENKU19PYmplY3QNCi17DQotcHVibGljOg0KLQlDSlNfUG9zaXRpb24oSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9Ow0KLQl2aXJ0dWFsIH5DSlNfUG9zaXRpb24odm9pZCl7fTsNCi0NCi0JREVDTEFSRV9KU19DTEFTU19DT05TVCgpOw0KLX07DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHNjYWxlSG93IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLWNsYXNzIENKU19TY2FsZUhvdyA6IHB1YmxpYyBDSlNfT2JqZWN0DQotew0KLXB1YmxpYzoNCi0JQ0pTX1NjYWxlSG93KEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsNCi0JdmlydHVhbCB+Q0pTX1NjYWxlSG93KHZvaWQpe307DQotDQotCURFQ0xBUkVfSlNfQ0xBU1NfQ09OU1QoKTsNCi19Ow0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzY2FsZVdoZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotY2xhc3MgQ0pTX1NjYWxlV2hlbiA6IHB1YmxpYyBDSlNfT2JqZWN0DQotew0KLXB1YmxpYzoNCi0JQ0pTX1NjYWxlV2hlbihKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19TY2FsZVdoZW4odm9pZCl7fTsNCi0NCi0JREVDTEFSRV9KU19DTEFTU19DT05TVCgpOw0KLX07DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHN0eWxlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLWNsYXNzIENKU19TdHlsZSA6IHB1YmxpYyBDSlNfT2JqZWN0DQotew0KLXB1YmxpYzoNCi0JQ0pTX1N0eWxlKEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsNCi0JdmlydHVhbCB+Q0pTX1N0eWxlKHZvaWQpe307DQotDQotCURFQ0xBUkVfSlNfQ0xBU1NfQ09OU1QoKTsNCi19Ow0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB6b29tdHlwZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1jbGFzcyBDSlNfWm9vbXR5cGUgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19ab29tdHlwZShKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19ab29tdHlwZSh2b2lkKXt9Ow0KLQ0KLQlERUNMQVJFX0pTX0NMQVNTX0NPTlNUKCk7DQotfTsNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX0dsb2JhbENvbnN0cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1jbGFzcyBDSlNfR2xvYmFsQ29uc3RzIDogcHVibGljIENKU19PYmplY3QNCi17DQotcHVibGljOg0KLQlzdGF0aWMgaW50CQkJCUluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lKTsNCi19Ow0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfR2xvYmFsQXJyYXlzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLWNsYXNzIENKU19HbG9iYWxBcnJheXMgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCXN0YXRpYyBpbnQJCQkJSW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUpOw0KLX07DQotDQotI2VuZGlmIC8vX0NPTlNUU19IXw0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0NPTlNUU19IXworI2RlZmluZSBfQ09OU1RTX0hfCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBib3JkZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK2NsYXNzIENKU19Cb3JkZXIgOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19Cb3JkZXIoSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9OworCXZpcnR1YWwgfkNKU19Cb3JkZXIodm9pZCl7fTsKKworCURFQ0xBUkVfSlNfQ0xBU1NfQ09OU1QoKTsKK307CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBkaXNwbGF5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitjbGFzcyBDSlNfRGlzcGxheSA6IHB1YmxpYyBDSlNfT2JqZWN0Cit7CitwdWJsaWM6CisJQ0pTX0Rpc3BsYXkoSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9OworCXZpcnR1YWwgfkNKU19EaXNwbGF5KHZvaWQpe307CisKKwlERUNMQVJFX0pTX0NMQVNTX0NPTlNUKCk7Cit9OworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gZm9udCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworY2xhc3MgQ0pTX0ZvbnQgOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19Gb250KEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsKKwl2aXJ0dWFsIH5DSlNfRm9udCh2b2lkKXt9OworCisJREVDTEFSRV9KU19DTEFTU19DT05TVCgpOworfTsKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGhpZ2hsaWdodCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworY2xhc3MgQ0pTX0hpZ2hsaWdodCA6IHB1YmxpYyBDSlNfT2JqZWN0Cit7CitwdWJsaWM6CisJQ0pTX0hpZ2hsaWdodChKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307CisJdmlydHVhbCB+Q0pTX0hpZ2hsaWdodCh2b2lkKXt9OworCisJREVDTEFSRV9KU19DTEFTU19DT05TVCgpOworfTsKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHBvc2l0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitjbGFzcyBDSlNfUG9zaXRpb24gOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19Qb3NpdGlvbihKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307CisJdmlydHVhbCB+Q0pTX1Bvc2l0aW9uKHZvaWQpe307CisKKwlERUNMQVJFX0pTX0NMQVNTX0NPTlNUKCk7Cit9OworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gc2NhbGVIb3cgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK2NsYXNzIENKU19TY2FsZUhvdyA6IHB1YmxpYyBDSlNfT2JqZWN0Cit7CitwdWJsaWM6CisJQ0pTX1NjYWxlSG93KEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsKKwl2aXJ0dWFsIH5DSlNfU2NhbGVIb3codm9pZCl7fTsKKworCURFQ0xBUkVfSlNfQ0xBU1NfQ09OU1QoKTsKK307CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzY2FsZVdoZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK2NsYXNzIENKU19TY2FsZVdoZW4gOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19TY2FsZVdoZW4oSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9OworCXZpcnR1YWwgfkNKU19TY2FsZVdoZW4odm9pZCl7fTsKKworCURFQ0xBUkVfSlNfQ0xBU1NfQ09OU1QoKTsKK307CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzdHlsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworY2xhc3MgQ0pTX1N0eWxlIDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfU3R5bGUoSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9OworCXZpcnR1YWwgfkNKU19TdHlsZSh2b2lkKXt9OworCisJREVDTEFSRV9KU19DTEFTU19DT05TVCgpOworfTsKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHpvb210eXBlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitjbGFzcyBDSlNfWm9vbXR5cGUgOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19ab29tdHlwZShKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307CisJdmlydHVhbCB+Q0pTX1pvb210eXBlKHZvaWQpe307CisKKwlERUNMQVJFX0pTX0NMQVNTX0NPTlNUKCk7Cit9OworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX0dsb2JhbENvbnN0cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworY2xhc3MgQ0pTX0dsb2JhbENvbnN0cyA6IHB1YmxpYyBDSlNfT2JqZWN0Cit7CitwdWJsaWM6CisJc3RhdGljIGludAkJCQlJbml0KElKU19SdW50aW1lKiBwUnVudGltZSk7Cit9OworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX0dsb2JhbEFycmF5cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworY2xhc3MgQ0pTX0dsb2JhbEFycmF5cyA6IHB1YmxpYyBDSlNfT2JqZWN0Cit7CitwdWJsaWM6CisJc3RhdGljIGludAkJCQlJbml0KElKU19SdW50aW1lKiBwUnVudGltZSk7Cit9OworCisjZW5kaWYgLy9fQ09OU1RTX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmggYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9Eb2N1bWVudC5oCmluZGV4IDNlOTY2OWI4Li5jYThiNTFiIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9Eb2N1bWVudC5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmgKQEAgLTEsMjgyICsxLDI4MiBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfRE9DVU1FTlRfSF8NCi0jZGVmaW5lIF9ET0NVTUVOVF9IXw0KLQ0KLQ0KLQ0KLWNsYXNzIFByaW50UGFyYW1zT2JqIDogcHVibGljIENKU19FbWJlZE9iag0KLXsNCi1wdWJsaWM6DQotCVByaW50UGFyYW1zT2JqKENKU19PYmplY3QqIHBKU09iamVjdCk7DQotCXZpcnR1YWwgflByaW50UGFyYW1zT2JqKCl7fQ0KLQkNCi1wdWJsaWM6DQotCUZYX0JPT0wgYlVJOw0KLQlpbnQgblN0YXJ0Ow0KLQlpbnQgbkVuZDsNCi0JRlhfQk9PTCBiU2lsZW50Ow0KLQlGWF9CT09MIGJTaHJpbmtUb0ZpdDsNCi0JRlhfQk9PTCBiUHJpbnRBc0ltYWdlOw0KLQlGWF9CT09MIGJSZXZlcnNlOw0KLQlGWF9CT09MIGJBbm5vdGF0aW9uczsNCi19Ow0KLQ0KLWNsYXNzIENKU19QcmludFBhcmFtc09iaiA6IHB1YmxpYyBDSlNfT2JqZWN0DQotew0KLXB1YmxpYzoNCi0JQ0pTX1ByaW50UGFyYW1zT2JqKEpTRlhPYmplY3QgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9DQotCXZpcnR1YWwgfkNKU19QcmludFBhcmFtc09iaigpe30NCi0JDQotCURFQ0xBUkVfSlNfQ0xBU1MoQ0pTX1ByaW50UGFyYW1zT2JqKTsNCi19Ow0KLQ0KLQ0KLWNsYXNzIEljb247DQotY2xhc3MgRmllbGQ7DQotDQotc3RydWN0IEljb25FbGVtZW50DQotew0KLQlJY29uRWxlbWVudCgpIDogSWNvbk5hbWUoTCIiKSwgSWNvblN0cmVhbShOVUxMKSwgTmV4dEljb24oTlVMTCl7fQ0KLQl2aXJ0dWFsIH5JY29uRWxlbWVudCgpDQotCXsNCi0JfQ0KLQlDRlhfV2lkZVN0cmluZwlJY29uTmFtZTsNCi0JSWNvbkVsZW1lbnQqCU5leHRJY29uOw0KLQlJY29uKgkJCUljb25TdHJlYW07DQotfTsNCi0NCi1jbGFzcyBJY29uVHJlZQ0KLXsNCi1wdWJsaWM6DQotCUljb25UcmVlKCk6bV9wSGVhZChOVUxMKSwgbV9wRW5kKE5VTEwpLCBtX2lMZW5ndGgoMCkNCi0Jew0KLQ0KLQl9DQotDQotCXZpcnR1YWwgfkljb25UcmVlKCkNCi0Jew0KLQl9DQotDQotcHVibGljOg0KLQl2b2lkCQkJSW5zZXJ0SWNvbkVsZW1lbnQoSWNvbkVsZW1lbnQqIHBOZXdJY29uKTsNCi0Jdm9pZAkJCURlbGV0ZUljb25FbGVtZW50KENGWF9XaWRlU3RyaW5nIHN3SWNvbk5hbWUpOw0KLQl2b2lkCQkJRGVsZXRlSWNvblRyZWUoKTsNCi0JaW50CQkJCUdldExlbmd0aCgpOw0KLQlJY29uRWxlbWVudCoJb3BlcmF0b3JbXShpbnQgaUluZGV4KTsNCi0NCi1wcml2YXRlOg0KLQlJY29uRWxlbWVudCoJbV9wSGVhZDsNCi0JSWNvbkVsZW1lbnQqCW1fcEVuZDsNCi0JaW50CQkJCW1faUxlbmd0aDsNCi19Ow0KLQ0KLXN0cnVjdCBDSlNfRGVsYXlEYXRhOw0KLXN0cnVjdCBDSlNfRGVsYXlBbm5vdDsNCi1zdHJ1Y3QgQ0pTX0Fubm90T2JqOw0KLQ0KLWNsYXNzIERvY3VtZW50IDogcHVibGljIENKU19FbWJlZE9iag0KLXsNCi1wdWJsaWM6DQotCURvY3VtZW50KENKU19PYmplY3QqIHBKU09iamVjdCk7DQotCXZpcnR1YWwgfkRvY3VtZW50KCk7DQotDQotcHVibGljOg0KLQlGWF9CT09MCUFEQkUoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAlhdXRob3IoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAliYXNlVVJMKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJYm9va21hcmtSb290KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJY2FsY3VsYXRlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJQ29sbGFiKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJY3JlYXRpb25EYXRlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJY3JlYXRvcihPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MCWRlbGF5KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJZGlydHkoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAlkb2N1bWVudEZpbGVOYW1lKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgZXh0ZXJuYWwoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAlmaWxlc2l6ZShPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MCWljb25zKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJaW5mbyhPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MCWtleXdvcmRzKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJbGF5b3V0KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJbWVkaWEoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAltb2REYXRlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJbW91c2VYKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJbW91c2VZKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJbnVtRmllbGRzKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJbnVtUGFnZXMoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAlwYWdlTnVtKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJcGFnZVdpbmRvd1JlY3QoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAlwYXRoKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJcHJvZHVjZXIoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAlzdWJqZWN0KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJdGl0bGUoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAl6b29tKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJem9vbVR5cGUoT0JKX1BST1BfUEFSQU1TKTsNCi0NCi0JRlhfQk9PTCBhZGRBbm5vdChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJYWRkRmllbGQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCWFkZExpbmsoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCWFkZEljb24oT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCWNhbGN1bGF0ZU5vdyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJY2xvc2VEb2MoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCWNyZWF0ZURhdGFPYmplY3QoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIGRlbGV0ZVBhZ2VzKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlleHBvcnRBc1RleHQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCWV4cG9ydEFzRkRGKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlleHBvcnRBc1hGREYoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIGV4dHJhY3RQYWdlcyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJZ2V0QW5ub3QoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCWdldEFubm90cyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJZ2V0QW5ub3QzRChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJZ2V0QW5ub3RzM0QoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCWdldEZpZWxkKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlnZXRJY29uKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlnZXRMaW5rcyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJZ2V0TnRoRmllbGROYW1lKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlnZXRPQ0dzKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlnZXRQYWdlQm94KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlnZXRQYWdlTnRoV29yZChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJZ2V0UGFnZU50aFdvcmRRdWFkcyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJZ2V0UGFnZU51bVdvcmRzKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBnZXRQcmludFBhcmFtcyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgZ2V0VVJMKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlpbXBvcnRBbkZERihPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJaW1wb3J0QW5YRkRGKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlpbXBvcnRUZXh0RGF0YShPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgaW5zZXJ0UGFnZXMoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCW1haWxGb3JtKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlwcmludChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJcmVtb3ZlRmllbGQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIHJlcGxhY2VQYWdlcyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJcmVzZXRGb3JtKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAlzYXZlQXMoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCXN1Ym1pdEZvcm0oT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCW1haWxEb2MoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCXJlbW92ZUljb24oT0JKX01FVEhPRF9QQVJBTVMpOw0KLQkNCi1wdWJsaWM6DQotCXZvaWQgQXR0YWNoRG9jKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOw0KLQlDUERGU0RLX0RvY3VtZW50KiBHZXRSZWFkZXJEb2MoKTsNCi0NCi0Jc3RhdGljIEZYX0JPT0wJCQkJRXh0cmFjdEZpbGVOYW1lKENQREZTREtfRG9jdW1lbnQqIHBEb2MsIENGWF9CeXRlU3RyaW5nJiBzdHJGaWxlTmFtZSk7DQotCXN0YXRpYyBGWF9CT09MCQkJCUV4dHJhY3RGb2xkZXJOYW1lKENQREZTREtfRG9jdW1lbnQqIHBEb2MsIENGWF9CeXRlU3RyaW5nJiBzdHJGb2xkZXJOYW1lKTsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQlBZGREZWxheURhdGEoQ0pTX0RlbGF5RGF0YSogcERhdGEpOw0KLQl2b2lkCQkJCQkJRG9GaWVsZERlbGF5KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzRmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCk7DQotDQotCXZvaWQJCQkJCQlBZGREZWxheUFubm90RGF0YShDSlNfQW5ub3RPYmogKnBEYXRhKTsNCi0Jdm9pZAkJCQkJCURvQW5ub3REZWxheSgpOw0KLQl2b2lkCQkJCQkJU2V0SXNvbGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSkge21faXNvbGF0ZSA9IGlzb2xhdGU7fQ0KLQ0KLXByaXZhdGU6DQotCUNGWF9XaWRlU3RyaW5nCQkJCVJldmVyc2FsU3RyKENGWF9XaWRlU3RyaW5nIGNiRnJvbSk7DQotCUNGWF9XaWRlU3RyaW5nCQkJCUN1dFN0cmluZyhDRlhfV2lkZVN0cmluZyBjYkZyb20pOw0KLQlib29sCQkJCQkJSXNFbmNsb3NlZEluUmVjdChDRlhfRmxvYXRSZWN0IHJlY3QsIENGWF9GbG9hdFJlY3QgTGlua1JlY3QpOw0KLQlpbnQJCQkJCQkJQ291bnRXb3JkcyhDUERGX1RleHRPYmplY3QqIHBUZXh0T2JqKTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJR2V0T2JqV29yZFN0cihDUERGX1RleHRPYmplY3QqIHBUZXh0T2JqLCBpbnQgbldvcmRJbmRleCk7DQotDQotCUZYX0JPT0wJCQkJCQlQYXJzZXJQYXJhbXMoSlNPYmplY3QgKnBPYmosQ0pTX0Fubm90T2JqJiBhbm5vdG9iaik7DQotDQotcHJpdmF0ZToNCi0Jdjg6Oklzb2xhdGUqCQkJCQltX2lzb2xhdGU7DQotCUljb25UcmVlKgkJCQkJbV9wSWNvblRyZWU7DQotCUNQREZTREtfRG9jdW1lbnQqCQkJbV9wRG9jdW1lbnQ7DQotCUNGWF9XaWRlU3RyaW5nCQkJCW1fY3dCYXNlVVJMOw0KLQ0KLQlGWF9CT09MCQkJCQkJCQltX2JEZWxheTsNCi0JQ0ZYX0FycmF5VGVtcGxhdGU8Q0pTX0RlbGF5RGF0YSo+CW1fRGVsYXlEYXRhOw0KLQlDRlhfQXJyYXlUZW1wbGF0ZTxDSlNfQW5ub3RPYmoqPgltX0RlbGF5QW5ub3REYXRhOw0KLX07DQotDQotY2xhc3MgQ0pTX0RvY3VtZW50IDogcHVibGljIENKU19PYmplY3QNCi17DQotcHVibGljOg0KLQlDSlNfRG9jdW1lbnQoSlNGWE9iamVjdCBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19Eb2N1bWVudCgpe307DQotDQotCXZpcnR1YWwgRlhfQk9PTAlJbml0SW5zdGFuY2UoSUZYSlNfQ29udGV4dCogY2MpOwkNCi0NCi0JREVDTEFSRV9KU19DTEFTUyhDSlNfRG9jdW1lbnQpOw0KLQ0KLQlKU19TVEFUSUNfUFJPUChBREJFLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKGF1dGhvciwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUChiYXNlVVJMLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKGJvb2ttYXJrUm9vdCwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUChjYWxjdWxhdGUsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AoQ29sbGFiLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKGNyZWF0aW9uRGF0ZSwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUChjcmVhdG9yLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKGRlbGF5LCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKGRpcnR5LCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKGRvY3VtZW50RmlsZU5hbWUsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AoZXh0ZXJuYWwsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AoZmlsZXNpemUsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AoaWNvbnMsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AoaW5mbywgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUChrZXl3b3JkcywgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUChsYXlvdXQsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AobWVkaWEsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AobW9kRGF0ZSwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUChtb3VzZVgsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AobW91c2VZLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKG51bUZpZWxkcywgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUChudW1QYWdlcywgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUChwYWdlTnVtLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHBhZ2VXaW5kb3dSZWN0LCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHBhdGgsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1AocHJvZHVjZXIsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX1BST1Aoc3ViamVjdCwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUCh0aXRsZSwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfUFJPUCh6b29tLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHpvb21UeXBlLCBEb2N1bWVudCk7DQotDQotCUpTX1NUQVRJQ19NRVRIT0QoYWRkQW5ub3QsRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGFkZEZpZWxkLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoYWRkTGluaywgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGFkZEljb24sIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChjYWxjdWxhdGVOb3csIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChjbG9zZURvYywgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGNyZWF0ZURhdGFPYmplY3QsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChkZWxldGVQYWdlcywgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGV4cG9ydEFzVGV4dCwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGV4cG9ydEFzRkRGLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZXhwb3J0QXNYRkRGLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZXh0cmFjdFBhZ2VzLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZ2V0QW5ub3QsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRBbm5vdHMsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRBbm5vdDNELCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZ2V0QW5ub3RzM0QsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRGaWVsZCwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGdldEljb24sIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRMaW5rcywgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGdldE50aEZpZWxkTmFtZSwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGdldE9DR3MsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRQYWdlQm94LCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZ2V0UGFnZU50aFdvcmQsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRQYWdlTnRoV29yZFF1YWRzLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZ2V0UGFnZU51bVdvcmRzLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZ2V0UHJpbnRQYXJhbXMsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRVUkwsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChpbXBvcnRBbkZERiwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGltcG9ydEFuWEZERiwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGltcG9ydFRleHREYXRhLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoaW5zZXJ0UGFnZXMsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChtYWlsRm9ybSwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKHByaW50LCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QocmVtb3ZlRmllbGQsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChyZXBsYWNlUGFnZXMsIERvY3VtZW50KTsNCi0JSlNfU1RBVElDX01FVEhPRChyZW1vdmVJY29uLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0QocmVzZXRGb3JtLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0Qoc2F2ZUFzLCBEb2N1bWVudCk7DQotCUpTX1NUQVRJQ19NRVRIT0Qoc3VibWl0Rm9ybSwgRG9jdW1lbnQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKG1haWxEb2MsIERvY3VtZW50KTsNCi19Ow0KLQ0KLSNlbmRpZi8vX0RPQ1VNRU5UX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfRE9DVU1FTlRfSF8KKyNkZWZpbmUgX0RPQ1VNRU5UX0hfCisKKworCitjbGFzcyBQcmludFBhcmFtc09iaiA6IHB1YmxpYyBDSlNfRW1iZWRPYmoKK3sKK3B1YmxpYzoKKwlQcmludFBhcmFtc09iaihDSlNfT2JqZWN0KiBwSlNPYmplY3QpOworCXZpcnR1YWwgflByaW50UGFyYW1zT2JqKCl7fQorCQorcHVibGljOgorCUZYX0JPT0wgYlVJOworCWludCBuU3RhcnQ7CisJaW50IG5FbmQ7CisJRlhfQk9PTCBiU2lsZW50OworCUZYX0JPT0wgYlNocmlua1RvRml0OworCUZYX0JPT0wgYlByaW50QXNJbWFnZTsKKwlGWF9CT09MIGJSZXZlcnNlOworCUZYX0JPT0wgYkFubm90YXRpb25zOworfTsKKworY2xhc3MgQ0pTX1ByaW50UGFyYW1zT2JqIDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfUHJpbnRQYXJhbXNPYmooSlNGWE9iamVjdCBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge30KKwl2aXJ0dWFsIH5DSlNfUHJpbnRQYXJhbXNPYmooKXt9CisJCisJREVDTEFSRV9KU19DTEFTUyhDSlNfUHJpbnRQYXJhbXNPYmopOworfTsKKworCitjbGFzcyBJY29uOworY2xhc3MgRmllbGQ7CisKK3N0cnVjdCBJY29uRWxlbWVudAoreworCUljb25FbGVtZW50KCkgOiBJY29uTmFtZShMIiIpLCBJY29uU3RyZWFtKE5VTEwpLCBOZXh0SWNvbihOVUxMKXt9CisJdmlydHVhbCB+SWNvbkVsZW1lbnQoKQorCXsKKwl9CisJQ0ZYX1dpZGVTdHJpbmcJSWNvbk5hbWU7CisJSWNvbkVsZW1lbnQqCU5leHRJY29uOworCUljb24qCQkJSWNvblN0cmVhbTsKK307CisKK2NsYXNzIEljb25UcmVlCit7CitwdWJsaWM6CisJSWNvblRyZWUoKTptX3BIZWFkKE5VTEwpLCBtX3BFbmQoTlVMTCksIG1faUxlbmd0aCgwKQorCXsKKworCX0KKworCXZpcnR1YWwgfkljb25UcmVlKCkKKwl7CisJfQorCitwdWJsaWM6CisJdm9pZAkJCUluc2VydEljb25FbGVtZW50KEljb25FbGVtZW50KiBwTmV3SWNvbik7CisJdm9pZAkJCURlbGV0ZUljb25FbGVtZW50KENGWF9XaWRlU3RyaW5nIHN3SWNvbk5hbWUpOworCXZvaWQJCQlEZWxldGVJY29uVHJlZSgpOworCWludAkJCQlHZXRMZW5ndGgoKTsKKwlJY29uRWxlbWVudCoJb3BlcmF0b3JbXShpbnQgaUluZGV4KTsKKworcHJpdmF0ZToKKwlJY29uRWxlbWVudCoJbV9wSGVhZDsKKwlJY29uRWxlbWVudCoJbV9wRW5kOworCWludAkJCQltX2lMZW5ndGg7Cit9OworCitzdHJ1Y3QgQ0pTX0RlbGF5RGF0YTsKK3N0cnVjdCBDSlNfRGVsYXlBbm5vdDsKK3N0cnVjdCBDSlNfQW5ub3RPYmo7CisKK2NsYXNzIERvY3VtZW50IDogcHVibGljIENKU19FbWJlZE9iagoreworcHVibGljOgorCURvY3VtZW50KENKU19PYmplY3QqIHBKU09iamVjdCk7CisJdmlydHVhbCB+RG9jdW1lbnQoKTsKKworcHVibGljOgorCUZYX0JPT0wJQURCRShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJYXV0aG9yKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAliYXNlVVJMKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAlib29rbWFya1Jvb3QoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCWNhbGN1bGF0ZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJQ29sbGFiKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAljcmVhdGlvbkRhdGUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCWNyZWF0b3IoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCWRlbGF5KE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAlkaXJ0eShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJZG9jdW1lbnRGaWxlTmFtZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgZXh0ZXJuYWwoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCWZpbGVzaXplKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAlpY29ucyhPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJaW5mbyhPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJa2V5d29yZHMoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCWxheW91dChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJbWVkaWEoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCW1vZERhdGUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCW1vdXNlWChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJbW91c2VZKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAludW1GaWVsZHMoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCW51bVBhZ2VzKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAlwYWdlTnVtKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAlwYWdlV2luZG93UmVjdChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJcGF0aChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJcHJvZHVjZXIoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCXN1YmplY3QoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCXRpdGxlKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAl6b29tKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAl6b29tVHlwZShPQkpfUFJPUF9QQVJBTVMpOworCisJRlhfQk9PTCBhZGRBbm5vdChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAlhZGRGaWVsZChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAlhZGRMaW5rKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCWFkZEljb24oT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJY2FsY3VsYXRlTm93KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCWNsb3NlRG9jKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCWNyZWF0ZURhdGFPYmplY3QoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgZGVsZXRlUGFnZXMoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJZXhwb3J0QXNUZXh0KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCWV4cG9ydEFzRkRGKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCWV4cG9ydEFzWEZERihPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBleHRyYWN0UGFnZXMoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJZ2V0QW5ub3QoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJZ2V0QW5ub3RzKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCWdldEFubm90M0QoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJZ2V0QW5ub3RzM0QoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJZ2V0RmllbGQoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJZ2V0SWNvbihPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAlnZXRMaW5rcyhPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAlnZXROdGhGaWVsZE5hbWUoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJZ2V0T0NHcyhPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAlnZXRQYWdlQm94KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCWdldFBhZ2VOdGhXb3JkKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCWdldFBhZ2VOdGhXb3JkUXVhZHMoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJZ2V0UGFnZU51bVdvcmRzKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIGdldFByaW50UGFyYW1zKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIGdldFVSTChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAlpbXBvcnRBbkZERihPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAlpbXBvcnRBblhGREYoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJaW1wb3J0VGV4dERhdGEoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgaW5zZXJ0UGFnZXMoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJbWFpbEZvcm0oT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJcHJpbnQoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJcmVtb3ZlRmllbGQoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgcmVwbGFjZVBhZ2VzKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCXJlc2V0Rm9ybShPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAlzYXZlQXMoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJc3VibWl0Rm9ybShPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAltYWlsRG9jKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCXJlbW92ZUljb24oT0JKX01FVEhPRF9QQVJBTVMpOworCQorcHVibGljOgorCXZvaWQgQXR0YWNoRG9jKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOworCUNQREZTREtfRG9jdW1lbnQqIEdldFJlYWRlckRvYygpOworCisJc3RhdGljIEZYX0JPT0wJCQkJRXh0cmFjdEZpbGVOYW1lKENQREZTREtfRG9jdW1lbnQqIHBEb2MsIENGWF9CeXRlU3RyaW5nJiBzdHJGaWxlTmFtZSk7CisJc3RhdGljIEZYX0JPT0wJCQkJRXh0cmFjdEZvbGRlck5hbWUoQ1BERlNES19Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcmIHN0ckZvbGRlck5hbWUpOworCitwdWJsaWM6CisJdm9pZAkJCQkJCUFkZERlbGF5RGF0YShDSlNfRGVsYXlEYXRhKiBwRGF0YSk7CisJdm9pZAkJCQkJCURvRmllbGREZWxheShjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgpOworCisJdm9pZAkJCQkJCUFkZERlbGF5QW5ub3REYXRhKENKU19Bbm5vdE9iaiAqcERhdGEpOworCXZvaWQJCQkJCQlEb0Fubm90RGVsYXkoKTsKKwl2b2lkCQkJCQkJU2V0SXNvbGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSkge21faXNvbGF0ZSA9IGlzb2xhdGU7fQorCitwcml2YXRlOgorCUNGWF9XaWRlU3RyaW5nCQkJCVJldmVyc2FsU3RyKENGWF9XaWRlU3RyaW5nIGNiRnJvbSk7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJQ3V0U3RyaW5nKENGWF9XaWRlU3RyaW5nIGNiRnJvbSk7CisJYm9vbAkJCQkJCUlzRW5jbG9zZWRJblJlY3QoQ0ZYX0Zsb2F0UmVjdCByZWN0LCBDRlhfRmxvYXRSZWN0IExpbmtSZWN0KTsKKwlpbnQJCQkJCQkJQ291bnRXb3JkcyhDUERGX1RleHRPYmplY3QqIHBUZXh0T2JqKTsKKwlDRlhfV2lkZVN0cmluZwkJCQlHZXRPYmpXb3JkU3RyKENQREZfVGV4dE9iamVjdCogcFRleHRPYmosIGludCBuV29yZEluZGV4KTsKKworCUZYX0JPT0wJCQkJCQlQYXJzZXJQYXJhbXMoSlNPYmplY3QgKnBPYmosQ0pTX0Fubm90T2JqJiBhbm5vdG9iaik7CisKK3ByaXZhdGU6CisJdjg6Oklzb2xhdGUqCQkJCQltX2lzb2xhdGU7CisJSWNvblRyZWUqCQkJCQltX3BJY29uVHJlZTsKKwlDUERGU0RLX0RvY3VtZW50KgkJCW1fcERvY3VtZW50OworCUNGWF9XaWRlU3RyaW5nCQkJCW1fY3dCYXNlVVJMOworCisJRlhfQk9PTAkJCQkJCQkJbV9iRGVsYXk7CisJQ0ZYX0FycmF5VGVtcGxhdGU8Q0pTX0RlbGF5RGF0YSo+CW1fRGVsYXlEYXRhOworCUNGWF9BcnJheVRlbXBsYXRlPENKU19Bbm5vdE9iaio+CW1fRGVsYXlBbm5vdERhdGE7Cit9OworCitjbGFzcyBDSlNfRG9jdW1lbnQgOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19Eb2N1bWVudChKU0ZYT2JqZWN0IHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsKKwl2aXJ0dWFsIH5DSlNfRG9jdW1lbnQoKXt9OworCisJdmlydHVhbCBGWF9CT09MCUluaXRJbnN0YW5jZShJRlhKU19Db250ZXh0KiBjYyk7CQorCisJREVDTEFSRV9KU19DTEFTUyhDSlNfRG9jdW1lbnQpOworCisJSlNfU1RBVElDX1BST1AoQURCRSwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKGF1dGhvciwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKGJhc2VVUkwsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChib29rbWFya1Jvb3QsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChjYWxjdWxhdGUsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChDb2xsYWIsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChjcmVhdGlvbkRhdGUsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChjcmVhdG9yLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX1BST1AoZGVsYXksIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChkaXJ0eSwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKGRvY3VtZW50RmlsZU5hbWUsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChleHRlcm5hbCwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKGZpbGVzaXplLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX1BST1AoaWNvbnMsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChpbmZvLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX1BST1Aoa2V5d29yZHMsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChsYXlvdXQsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChtZWRpYSwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKG1vZERhdGUsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChtb3VzZVgsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChtb3VzZVksIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChudW1GaWVsZHMsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChudW1QYWdlcywgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKHBhZ2VOdW0sIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChwYWdlV2luZG93UmVjdCwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKHBhdGgsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUChwcm9kdWNlciwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKHN1YmplY3QsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUCh0aXRsZSwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19QUk9QKHpvb20sIERvY3VtZW50KTsKKwlKU19TVEFUSUNfUFJPUCh6b29tVHlwZSwgRG9jdW1lbnQpOworCisJSlNfU1RBVElDX01FVEhPRChhZGRBbm5vdCxEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChhZGRGaWVsZCwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoYWRkTGluaywgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoYWRkSWNvbiwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoY2FsY3VsYXRlTm93LCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChjbG9zZURvYywgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoY3JlYXRlRGF0YU9iamVjdCwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoZGVsZXRlUGFnZXMsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGV4cG9ydEFzVGV4dCwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoZXhwb3J0QXNGREYsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGV4cG9ydEFzWEZERiwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoZXh0cmFjdFBhZ2VzLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChnZXRBbm5vdCwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoZ2V0QW5ub3RzLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChnZXRBbm5vdDNELCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChnZXRBbm5vdHMzRCwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QoZ2V0RmllbGQsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGdldEljb24sIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGdldExpbmtzLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChnZXROdGhGaWVsZE5hbWUsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGdldE9DR3MsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGdldFBhZ2VCb3gsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGdldFBhZ2VOdGhXb3JkLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChnZXRQYWdlTnRoV29yZFF1YWRzLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChnZXRQYWdlTnVtV29yZHMsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGdldFByaW50UGFyYW1zLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChnZXRVUkwsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGltcG9ydEFuRkRGLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChpbXBvcnRBblhGREYsIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKGltcG9ydFRleHREYXRhLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChpbnNlcnRQYWdlcywgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QobWFpbEZvcm0sIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKHByaW50LCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChyZW1vdmVGaWVsZCwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QocmVwbGFjZVBhZ2VzLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChyZW1vdmVJY29uLCBEb2N1bWVudCk7CisJSlNfU1RBVElDX01FVEhPRChyZXNldEZvcm0sIERvY3VtZW50KTsKKwlKU19TVEFUSUNfTUVUSE9EKHNhdmVBcywgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0Qoc3VibWl0Rm9ybSwgRG9jdW1lbnQpOworCUpTX1NUQVRJQ19NRVRIT0QobWFpbERvYywgRG9jdW1lbnQpOworfTsKKworI2VuZGlmLy9fRE9DVU1FTlRfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvRmllbGQuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0ZpZWxkLmgKaW5kZXggMWIwYmIwNS4uMmFlYTg1YSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvRmllbGQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oCkBAIC0xLDM1NSArMSwzNTUgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0ZJRUxEX0hfDQotI2RlZmluZSBfRklFTERfSF8NCi0NCi1jbGFzcyBEb2N1bWVudDsNCi0NCi1lbnVtIEZJRUxEX1BST1ANCi17DQotCUZQX0FMSUdOTUVOVCwNCi0JRlBfQk9SREVSU1RZTEUsDQotCUZQX0JVVFRPTkFMSUdOWCwNCi0JRlBfQlVUVE9OQUxJR05ZLA0KLQlGUF9CVVRUT05GSVRCT1VORFMsDQotCUZQX0JVVFRPTlBPU0lUSU9OLA0KLQlGUF9CVVRUT05TQ0FMRUhPVywNCi0JRlBfQlVUVE9OU0NBTEVXSEVOLA0KLQlGUF9DQUxDT1JERVJJTkRFWCwNCi0JRlBfQ0hBUkxJTUlULA0KLQlGUF9DT01CLA0KLQlGUF9DT01NSVRPTlNFTENIQU5HRSwNCi0JRlBfQ1VSUkVOVFZBTFVFSU5ESUNFUywNCi0JRlBfREVGQVVMVFZBTFVFLA0KLQlGUF9ET05PVFNDUk9MTCwNCi0JRlBfRElTUExBWSwNCi0JRlBfRklMTENPTE9SLA0KLQlGUF9ISURERU4sDQotCUZQX0hJR0hMSUdIVCwNCi0JRlBfTElORVdJRFRILA0KLQlGUF9NVUxUSUxJTkUsDQotCUZQX01VTFRJUExFU0VMRUNUSU9OLA0KLQlGUF9QQVNTV09SRCwNCi0JRlBfUkVDVCwNCi0JRlBfUklDSFRFWFQsDQotCUZQX1JJQ0hWQUxVRSwNCi0JRlBfUk9UQVRJT04sDQotCUZQX1NUUk9LRUNPTE9SLA0KLQlGUF9TVFlMRSwNCi0JRlBfVEVYVENPTE9SLA0KLQlGUF9URVhURk9OVCwNCi0JRlBfVEVYVFNJWkUsDQotCUZQX1VTRVJOQU1FLA0KLQlGUF9WQUxVRQ0KLX07DQotDQotY2xhc3MgQ0pTX1dpZGVTdHJpbmdBcnJheQ0KLXsNCi1wdWJsaWM6DQotCUNKU19XaWRlU3RyaW5nQXJyYXkoKXt9DQotCXZpcnR1YWwgfkNKU19XaWRlU3RyaW5nQXJyYXkoKQ0KLQl7DQotCQlmb3IgKGludCBpPTAsc3o9bV9EYXRhLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJCWRlbGV0ZSBtX0RhdGEuR2V0QXQoaSk7DQotCQltX0RhdGEuUmVtb3ZlQWxsKCk7DQotCX0NCi0NCi0Jdm9pZCBBZGQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZykNCi0Jew0KLQkJbV9EYXRhLkFkZChuZXcgQ0ZYX1dpZGVTdHJpbmcoc3RyaW5nKSk7DQotCX0NCi0NCi0JaW50IEdldFNpemUoKSBjb25zdA0KLQl7DQotCQlyZXR1cm4gbV9EYXRhLkdldFNpemUoKTsNCi0JfQ0KLQ0KLQlDRlhfV2lkZVN0cmluZyBHZXRBdChpbnQgaSkgY29uc3QNCi0Jew0KLQkJcmV0dXJuICptX0RhdGEuR2V0QXQoaSk7DQotCX0NCi0NCi1wcml2YXRlOg0KLQlDRlhfQXJyYXlUZW1wbGF0ZTxDRlhfV2lkZVN0cmluZyo+CW1fRGF0YTsNCi19Ow0KLQ0KLXN0cnVjdCBDSlNfRGVsYXlEYXRhDQotew0KLQlDRlhfV2lkZVN0cmluZwkJCXNGaWVsZE5hbWU7DQotCWludAkJCQkJCW5Db250cm9sSW5kZXg7DQotCWVudW0gRklFTERfUFJPUAkJCWVQcm9wOw0KLQlGWF9JTlQzMgkJCQludW07DQotCWJvb2wJCQkJCWI7DQotCUNGWF9CeXRlU3RyaW5nCQkJc3RyaW5nOw0KLQlDRlhfV2lkZVN0cmluZwkJCXdpZGVzdHJpbmc7DQotCUNQREZfUmVjdAkJCQlyZWN0Ow0KLQlDUFdMX0NvbG9yCQkJCWNvbG9yOw0KLQlDRlhfRFdvcmRBcnJheQkJCXdvcmRhcnJheTsNCi0JQ0pTX1dpZGVTdHJpbmdBcnJheQkJd2lkZXN0cmluZ2FycmF5Ow0KLX07DQotDQotY2xhc3MgRmllbGQgOiBwdWJsaWMgQ0pTX0VtYmVkT2JqDQotew0KLXB1YmxpYzoNCi0JRmllbGQoQ0pTX09iamVjdCogcEpTT2JqZWN0KTsJDQotCXZpcnR1YWwgfkZpZWxkKHZvaWQpOw0KLQ0KLSAgICBGWF9CT09MIGFsaWdubWVudChPQkpfUFJPUF9QQVJBTVMpOw0KLSAgICBGWF9CT09MIGJvcmRlclN0eWxlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgYnV0dG9uQWxpZ25YKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgYnV0dG9uQWxpZ25ZKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgYnV0dG9uRml0Qm91bmRzKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgYnV0dG9uUG9zaXRpb24oT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBidXR0b25TY2FsZUhvdyhPQkpfUFJPUF9QQVJBTVMpOw0KLSAgICBGWF9CT09MIGJ1dHRvblNjYWxlV2hlbihPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIGNhbGNPcmRlckluZGV4KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgY2hhckxpbWl0KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgY29tYihPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIGNvbW1pdE9uU2VsQ2hhbmdlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgY3VycmVudFZhbHVlSW5kaWNlcyhPQkpfUFJPUF9QQVJBTVMpOw0KLSAgICBGWF9CT09MIGRlZmF1bHRTdHlsZShPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIGRlZmF1bHRWYWx1ZShPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIGRvTm90U2Nyb2xsKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgZG9Ob3RTcGVsbENoZWNrKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgZGVsYXkoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBkaXNwbGF5KE9CSl9QUk9QX1BBUkFNUyk7DQotICAgIEZYX0JPT0wgZG9jKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgZWRpdGFibGUoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBleHBvcnRWYWx1ZXMoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBmaWxlU2VsZWN0KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgZmlsbENvbG9yKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgaGlkZGVuKE9CSl9QUk9QX1BBUkFNUyk7DQotICAgIEZYX0JPT0wgaGlnaGxpZ2h0KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgbGluZVdpZHRoKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgbXVsdGlsaW5lKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgbXVsdGlwbGVTZWxlY3Rpb24oT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBuYW1lKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgbnVtSXRlbXMoT0JKX1BST1BfUEFSQU1TKTsNCi0gICAgRlhfQk9PTCBwYWdlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgcGFzc3dvcmQoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBwcmludChPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHJhZGlvc0luVW5pc29uKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgcmVhZG9ubHkoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCByZWN0KE9CSl9QUk9QX1BBUkFNUyk7DQotICAgIEZYX0JPT0wgcmVxdWlyZWQoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCByaWNoVGV4dChPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHJpY2hWYWx1ZShPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHJvdGF0aW9uKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgc3Ryb2tlQ29sb3IoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBzdHlsZShPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHN1Ym1pdE5hbWUoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCB0ZXh0Q29sb3IoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCB0ZXh0Rm9udChPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHRleHRTaXplKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgdHlwZShPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHVzZXJOYW1lKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgdmFsdWUoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCB2YWx1ZUFzU3RyaW5nKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgc291cmNlKE9CSl9QUk9QX1BBUkFNUyk7DQotDQotCUZYX0JPT0wgYnJvd3NlRm9yRmlsZVRvU3VibWl0KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBidXR0b25HZXRDYXB0aW9uKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBidXR0b25HZXRJY29uKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBidXR0b25JbXBvcnRJY29uKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBidXR0b25TZXRDYXB0aW9uKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBidXR0b25TZXRJY29uKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBjaGVja1RoaXNCb3goT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIGNsZWFySXRlbXMoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIGRlZmF1bHRJc0NoZWNrZWQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIGRlbGV0ZUl0ZW1BdChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgZ2V0QXJyYXkoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIGdldEl0ZW1BdChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgZ2V0TG9jayhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgaW5zZXJ0SXRlbUF0KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBpc0JveENoZWNrZWQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIGlzRGVmYXVsdENoZWNrZWQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIHNldEFjdGlvbihPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgc2V0Rm9jdXMoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIHNldEl0ZW1zKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBzZXRMb2NrKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBzaWduYXR1cmVHZXRNb2RpZmljYXRpb25zKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBzaWduYXR1cmVHZXRTZWVkVmFsdWUoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIHNpZ25hdHVyZUluZm8oT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIHNpZ25hdHVyZVNldFNlZWRWYWx1ZShPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgc2lnbmF0dXJlU2lnbihPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgc2lnbmF0dXJlVmFsaWRhdGUoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQ0KLXB1YmxpYzoNCi0Jc3RhdGljIHZvaWQgU2V0QWxpZ25tZW50KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0cmluZyk7DQotICAgIHN0YXRpYyB2b2lkIFNldEJvcmRlclN0eWxlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0cmluZyk7DQotCXN0YXRpYyB2b2lkIFNldEJ1dHRvbkFsaWduWChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpOw0KLQlzdGF0aWMgdm9pZCBTZXRCdXR0b25BbGlnblkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKTsNCi0Jc3RhdGljIHZvaWQgU2V0QnV0dG9uRml0Qm91bmRzKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKTsNCi0Jc3RhdGljIHZvaWQgU2V0QnV0dG9uUG9zaXRpb24oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKTsNCi0Jc3RhdGljIHZvaWQgU2V0QnV0dG9uU2NhbGVIb3coQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKTsNCi0gICAgc3RhdGljIHZvaWQgU2V0QnV0dG9uU2NhbGVXaGVuKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcik7DQotCXN0YXRpYyB2b2lkIFNldENhbGNPcmRlckluZGV4KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcik7DQotCXN0YXRpYyB2b2lkIFNldENoYXJMaW1pdChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpOw0KLQlzdGF0aWMgdm9pZCBTZXRDb21iKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKTsNCi0Jc3RhdGljIHZvaWQgU2V0Q29tbWl0T25TZWxDaGFuZ2UoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpOw0KLQlzdGF0aWMgdm9pZCBTZXRDdXJyZW50VmFsdWVJbmRpY2VzKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0ZYX0RXb3JkQXJyYXkmIGFycmF5KTsNCi0gICAgc3RhdGljIHZvaWQgU2V0RGVmYXVsdFN0eWxlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCk7DQotCXN0YXRpYyB2b2lkIFNldERlZmF1bHRWYWx1ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpOw0KLQlzdGF0aWMgdm9pZCBTZXREb05vdFNjcm9sbChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYik7DQotCXN0YXRpYyB2b2lkIFNldERpc3BsYXkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKTsNCi0Jc3RhdGljIHZvaWQgU2V0RmlsbENvbG9yKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpOw0KLQlzdGF0aWMgdm9pZCBTZXRIaWRkZW4oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpOw0KLSAgICBzdGF0aWMgdm9pZCBTZXRIaWdobGlnaHQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyaW5nKTsNCi0Jc3RhdGljIHZvaWQgU2V0TGluZVdpZHRoKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcik7DQotCXN0YXRpYyB2b2lkIFNldE11bHRpbGluZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYik7DQotCXN0YXRpYyB2b2lkIFNldE11bHRpcGxlU2VsZWN0aW9uKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKTsNCi0Jc3RhdGljIHZvaWQgU2V0UGFzc3dvcmQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpOw0KLQlzdGF0aWMgdm9pZCBTZXRSZWN0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ1BERl9SZWN0JiByZWN0KTsNCi0Jc3RhdGljIHZvaWQgU2V0UmljaFRleHQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpOw0KLQlzdGF0aWMgdm9pZCBTZXRSaWNoVmFsdWUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4KTsNCi0Jc3RhdGljIHZvaWQgU2V0Um90YXRpb24oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKTsNCi0Jc3RhdGljIHZvaWQgU2V0U3Ryb2tlQ29sb3IoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7DQotCXN0YXRpYyB2b2lkIFNldFN0eWxlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0cmluZyk7DQotCXN0YXRpYyB2b2lkIFNldFRleHRDb2xvcihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKTsNCi0Jc3RhdGljIHZvaWQgU2V0VGV4dEZvbnQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyaW5nKTsNCi0Jc3RhdGljIHZvaWQgU2V0VGV4dFNpemUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKTsNCi0Jc3RhdGljIHZvaWQgU2V0VXNlck5hbWUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKTsNCi0Jc3RhdGljIHZvaWQgU2V0VmFsdWUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDSlNfV2lkZVN0cmluZ0FycmF5JiBzdHJBcnJheSk7DQotDQotcHVibGljOg0KLQlzdGF0aWMgdm9pZAkJCQkJCQlBZGRGaWVsZChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGludCBuUGFnZUluZGV4LCBpbnQgbkZpZWxkVHlwZSwgDQotCQkJCQkJCQkJCQljb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUsIGNvbnN0IENQREZfUmVjdCYgcmNDb29yZHMpOw0KLXB1YmxpYzoNCi0Jc3RhdGljIHZvaWQJCQkJCQkJVXBkYXRlRm9ybUZpZWxkKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIA0KLQkJCQkJCQkJCQkJRlhfQk9PTCBiQ2hhbmdlTWFyaywgRlhfQk9PTCBiUmVzZXRBUCwgRlhfQk9PTCBiUmVmcmVzaCk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCVVwZGF0ZUZvcm1Db250cm9sKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sLCANCi0JCQkJCQkJCQkJCUZYX0JPT0wgYkNoYW5nZU1hcmssIEZYX0JPT0wgYlJlc2V0QVAsIEZYX0JPT0wgYlJlZnJlc2gpOw0KLQ0KLQlzdGF0aWMgQ1BERlNES19XaWRnZXQqCQkJCQlHZXRXaWRnZXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQlHZXRGb3JtRmllbGRzKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIGNzRmllbGROYW1lLCBDRlhfUHRyQXJyYXkmIEZpZWxkc0FycmF5KTsNCi0NCi0Jc3RhdGljIHZvaWQJCQkJCQkJRG9EZWxheShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIENKU19EZWxheURhdGEqIHBEYXRhKTsNCi0NCi1wdWJsaWM6DQotCUZYX0JPT0wJCQkJCQkJCUF0dGFjaEZpZWxkKERvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBjc0ZpZWxkTmFtZSk7DQotCXZvaWQJCQkJCQkJCVNldERlbGF5KEZYX0JPT0wgYkRlbGF5KTsNCi0Jdm9pZAkJCQkJCQkJU2V0SXNvbGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSkge21faXNvbGF0ZSA9IGlzb2xhdGU7fQ0KLXByb3RlY3RlZDoNCi0Jdm9pZAkJCQkJCQkJUGFyc2VGaWVsZE5hbWUoY29uc3Qgc3RkOjp3c3RyaW5nICZzdHJGaWVsZE5hbWVQYXJzZWQsc3RkOjp3c3RyaW5nICZzdHJGaWVsZE5hbWUsaW50ICYgaUNvbnRyb2xObyk7DQotCXZvaWQJCQkJCQkJCUdldEZvcm1GaWVsZHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIGNzRmllbGROYW1lLCBDRlhfUHRyQXJyYXkmIEZpZWxkc0FycmF5KTsNCi0JQ1BERl9Gb3JtQ29udHJvbCogCQkJCQlHZXRTbWFydEZpZWxkQ29udHJvbChDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCk7DQotCUZYX0JPT0wJCQkJCQkJCVZhbHVlSXNPY2N1cihDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcgY3NPcHRMYWJlbCk7DQotDQotCXZvaWQJCQkJCQkJCUFkZERlbGF5X0ludChlbnVtIEZJRUxEX1BST1AgcHJvcCwgRlhfSU5UMzIgbik7DQotCXZvaWQJCQkJCQkJCUFkZERlbGF5X0Jvb2woZW51bSBGSUVMRF9QUk9QIHByb3AsYm9vbCBiKTsNCi0Jdm9pZAkJCQkJCQkJQWRkRGVsYXlfU3RyaW5nKGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyaW5nKTsNCi0Jdm9pZAkJCQkJCQkJQWRkRGVsYXlfV2lkZVN0cmluZyhlbnVtIEZJRUxEX1BST1AgcHJvcCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZyk7DQotCXZvaWQJCQkJCQkJCUFkZERlbGF5X1JlY3QoZW51bSBGSUVMRF9QUk9QIHByb3AsIGNvbnN0IENQREZfUmVjdCYgcmVjdCk7DQotCXZvaWQJCQkJCQkJCUFkZERlbGF5X0NvbG9yKGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7DQotCXZvaWQJCQkJCQkJCUFkZERlbGF5X1dvcmRBcnJheShlbnVtIEZJRUxEX1BST1AgcHJvcCwgY29uc3QgQ0ZYX0RXb3JkQXJyYXkmIGFycmF5KTsNCi0Jdm9pZAkJCQkJCQkJQWRkRGVsYXlfV2lkZVN0cmluZ0FycmF5KGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDSlNfV2lkZVN0cmluZ0FycmF5JiBhcnJheSk7DQotDQotCXZvaWQJCQkJCQkJCURvRGVsYXkoKTsNCi1wdWJsaWM6DQotCURvY3VtZW50KgkJCQkJCQltX3BKU0RvYzsNCi0JQ1BERlNES19Eb2N1bWVudCoJCQkJCW1fcERvY3VtZW50Ow0KLQlDRlhfV2lkZVN0cmluZwkJCQkJCW1fRmllbGROYW1lOw0KLQlpbnQJCQkJCQkJCQltX25Gb3JtQ29udHJvbEluZGV4Ow0KLQlGWF9CT09MCQkJCQkJCQltX2JDYW5TZXQ7DQotDQotCUZYX0JPT0wJCQkJCQkJCW1fYkRlbGF5Ow0KLQl2ODo6SXNvbGF0ZSoJCQkJCQkJbV9pc29sYXRlOw0KLX07DQotDQotY2xhc3MgQ0pTX0ZpZWxkIDogcHVibGljIENKU19PYmplY3QNCi17DQotcHVibGljOg0KLQlDSlNfRmllbGQoSlNGWE9iamVjdCBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19GaWVsZCh2b2lkKXt9Ow0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJSW5pdEluc3RhbmNlKElGWEpTX0NvbnRleHQqIGNjKTsNCi0NCi0JREVDTEFSRV9KU19DTEFTUyhDSlNfRmllbGQpOw0KLQ0KLSAgICBKU19TVEFUSUNfUFJPUChhbGlnbm1lbnQsIEZpZWxkKTsNCi0gICAgSlNfU1RBVElDX1BST1AoYm9yZGVyU3R5bGUsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AoYnV0dG9uQWxpZ25YLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKGJ1dHRvbkFsaWduWSwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUChidXR0b25GaXRCb3VuZHMsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AoYnV0dG9uUG9zaXRpb24sIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AoYnV0dG9uU2NhbGVIb3csIEZpZWxkKTsNCi0gICAgSlNfU1RBVElDX1BST1AoYnV0dG9uU2NhbGVXaGVuLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKGNhbGNPcmRlckluZGV4LCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKGNoYXJMaW1pdCwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUChjb21iLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKGNvbW1pdE9uU2VsQ2hhbmdlLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKGN1cnJlbnRWYWx1ZUluZGljZXMsIEZpZWxkKTsNCi0gICAgSlNfU1RBVElDX1BST1AoZGVmYXVsdFN0eWxlLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKGRlZmF1bHRWYWx1ZSwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUChkb05vdFNjcm9sbCwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUChkb05vdFNwZWxsQ2hlY2ssIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AoZGVsYXksIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AoZGlzcGxheSwgRmllbGQpOw0KLSAgICBKU19TVEFUSUNfUFJPUChkb2MsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AoZWRpdGFibGUsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AoZXhwb3J0VmFsdWVzLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKGZpbGVTZWxlY3QsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AoZmlsbENvbG9yLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKGhpZGRlbiwgRmllbGQpOw0KLSAgICBKU19TVEFUSUNfUFJPUChoaWdobGlnaHQsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AobGluZVdpZHRoLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKG11bHRpbGluZSwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUChtdWx0aXBsZVNlbGVjdGlvbiwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUChuYW1lLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKG51bUl0ZW1zLCBGaWVsZCk7DQotICAgIEpTX1NUQVRJQ19QUk9QKHBhZ2UsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AocGFzc3dvcmQsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AocHJpbnQsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AocmFkaW9zSW5Vbmlzb24sIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AocmVhZG9ubHksIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AocmVjdCwgRmllbGQpOw0KLSAgICBKU19TVEFUSUNfUFJPUChyZXF1aXJlZCwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUChyaWNoVGV4dCwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUChyaWNoVmFsdWUsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1Aocm90YXRpb24sIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1Aoc3Ryb2tlQ29sb3IsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1Aoc3R5bGUsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1Aoc3VibWl0TmFtZSwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUCh0ZXh0Q29sb3IsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AodGV4dEZvbnQsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AodGV4dFNpemUsIEZpZWxkKTsNCi0JSlNfU1RBVElDX1BST1AodHlwZSwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUCh1c2VyTmFtZSwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUCh2YWx1ZSwgRmllbGQpOw0KLQlKU19TVEFUSUNfUFJPUCh2YWx1ZUFzU3RyaW5nLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19QUk9QKHNvdXJjZSwgRmllbGQpOw0KLQ0KLQlKU19TVEFUSUNfTUVUSE9EKGJyb3dzZUZvckZpbGVUb1N1Ym1pdCwgRmllbGQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGJ1dHRvbkdldENhcHRpb24sIEZpZWxkKTsNCi0JSlNfU1RBVElDX01FVEhPRChidXR0b25HZXRJY29uLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoYnV0dG9uSW1wb3J0SWNvbiwgRmllbGQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKGJ1dHRvblNldENhcHRpb24sIEZpZWxkKTsNCi0JSlNfU1RBVElDX01FVEhPRChidXR0b25TZXRJY29uLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoY2hlY2tUaGlzQm94LCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoY2xlYXJJdGVtcywgRmllbGQpOw0KLSAJSlNfU1RBVElDX01FVEhPRChkZWZhdWx0SXNDaGVja2VkLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZGVsZXRlSXRlbUF0LCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoZ2V0QXJyYXksIEZpZWxkKTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRJdGVtQXQsIEZpZWxkKTsNCi0JSlNfU1RBVElDX01FVEhPRChnZXRMb2NrLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoaW5zZXJ0SXRlbUF0LCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoaXNCb3hDaGVja2VkLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0QoaXNEZWZhdWx0Q2hlY2tlZCwgRmllbGQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKHNldEFjdGlvbiwgRmllbGQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKHNldEZvY3VzLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0Qoc2V0SXRlbXMsIEZpZWxkKTsNCi0JSlNfU1RBVElDX01FVEhPRChzZXRMb2NrLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0Qoc2lnbmF0dXJlR2V0TW9kaWZpY2F0aW9ucywgRmllbGQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKHNpZ25hdHVyZUdldFNlZWRWYWx1ZSwgRmllbGQpOw0KLQlKU19TVEFUSUNfTUVUSE9EKHNpZ25hdHVyZUluZm8sIEZpZWxkKTsNCi0JSlNfU1RBVElDX01FVEhPRChzaWduYXR1cmVTZXRTZWVkVmFsdWUsIEZpZWxkKTsNCi0JSlNfU1RBVElDX01FVEhPRChzaWduYXR1cmVTaWduLCBGaWVsZCk7DQotCUpTX1NUQVRJQ19NRVRIT0Qoc2lnbmF0dXJlVmFsaWRhdGUsIEZpZWxkKTsNCi19Ow0KLQ0KLSNlbmRpZiAvL19GSUVMRF9IXw0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0ZJRUxEX0hfCisjZGVmaW5lIF9GSUVMRF9IXworCitjbGFzcyBEb2N1bWVudDsKKworZW51bSBGSUVMRF9QUk9QCit7CisJRlBfQUxJR05NRU5ULAorCUZQX0JPUkRFUlNUWUxFLAorCUZQX0JVVFRPTkFMSUdOWCwKKwlGUF9CVVRUT05BTElHTlksCisJRlBfQlVUVE9ORklUQk9VTkRTLAorCUZQX0JVVFRPTlBPU0lUSU9OLAorCUZQX0JVVFRPTlNDQUxFSE9XLAorCUZQX0JVVFRPTlNDQUxFV0hFTiwKKwlGUF9DQUxDT1JERVJJTkRFWCwKKwlGUF9DSEFSTElNSVQsCisJRlBfQ09NQiwKKwlGUF9DT01NSVRPTlNFTENIQU5HRSwKKwlGUF9DVVJSRU5UVkFMVUVJTkRJQ0VTLAorCUZQX0RFRkFVTFRWQUxVRSwKKwlGUF9ET05PVFNDUk9MTCwKKwlGUF9ESVNQTEFZLAorCUZQX0ZJTExDT0xPUiwKKwlGUF9ISURERU4sCisJRlBfSElHSExJR0hULAorCUZQX0xJTkVXSURUSCwKKwlGUF9NVUxUSUxJTkUsCisJRlBfTVVMVElQTEVTRUxFQ1RJT04sCisJRlBfUEFTU1dPUkQsCisJRlBfUkVDVCwKKwlGUF9SSUNIVEVYVCwKKwlGUF9SSUNIVkFMVUUsCisJRlBfUk9UQVRJT04sCisJRlBfU1RST0tFQ09MT1IsCisJRlBfU1RZTEUsCisJRlBfVEVYVENPTE9SLAorCUZQX1RFWFRGT05ULAorCUZQX1RFWFRTSVpFLAorCUZQX1VTRVJOQU1FLAorCUZQX1ZBTFVFCit9OworCitjbGFzcyBDSlNfV2lkZVN0cmluZ0FycmF5Cit7CitwdWJsaWM6CisJQ0pTX1dpZGVTdHJpbmdBcnJheSgpe30KKwl2aXJ0dWFsIH5DSlNfV2lkZVN0cmluZ0FycmF5KCkKKwl7CisJCWZvciAoaW50IGk9MCxzej1tX0RhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQlkZWxldGUgbV9EYXRhLkdldEF0KGkpOworCQltX0RhdGEuUmVtb3ZlQWxsKCk7CisJfQorCisJdm9pZCBBZGQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZykKKwl7CisJCW1fRGF0YS5BZGQobmV3IENGWF9XaWRlU3RyaW5nKHN0cmluZykpOworCX0KKworCWludCBHZXRTaXplKCkgY29uc3QKKwl7CisJCXJldHVybiBtX0RhdGEuR2V0U2l6ZSgpOworCX0KKworCUNGWF9XaWRlU3RyaW5nIEdldEF0KGludCBpKSBjb25zdAorCXsKKwkJcmV0dXJuICptX0RhdGEuR2V0QXQoaSk7CisJfQorCitwcml2YXRlOgorCUNGWF9BcnJheVRlbXBsYXRlPENGWF9XaWRlU3RyaW5nKj4JbV9EYXRhOworfTsKKworc3RydWN0IENKU19EZWxheURhdGEKK3sKKwlDRlhfV2lkZVN0cmluZwkJCXNGaWVsZE5hbWU7CisJaW50CQkJCQkJbkNvbnRyb2xJbmRleDsKKwllbnVtIEZJRUxEX1BST1AJCQllUHJvcDsKKwlGWF9JTlQzMgkJCQludW07CisJYm9vbAkJCQkJYjsKKwlDRlhfQnl0ZVN0cmluZwkJCXN0cmluZzsKKwlDRlhfV2lkZVN0cmluZwkJCXdpZGVzdHJpbmc7CisJQ1BERl9SZWN0CQkJCXJlY3Q7CisJQ1BXTF9Db2xvcgkJCQljb2xvcjsKKwlDRlhfRFdvcmRBcnJheQkJCXdvcmRhcnJheTsKKwlDSlNfV2lkZVN0cmluZ0FycmF5CQl3aWRlc3RyaW5nYXJyYXk7Cit9OworCitjbGFzcyBGaWVsZCA6IHB1YmxpYyBDSlNfRW1iZWRPYmoKK3sKK3B1YmxpYzoKKwlGaWVsZChDSlNfT2JqZWN0KiBwSlNPYmplY3QpOwkKKwl2aXJ0dWFsIH5GaWVsZCh2b2lkKTsKKworICAgIEZYX0JPT0wgYWxpZ25tZW50KE9CSl9QUk9QX1BBUkFNUyk7CisgICAgRlhfQk9PTCBib3JkZXJTdHlsZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgYnV0dG9uQWxpZ25YKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBidXR0b25BbGlnblkoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGJ1dHRvbkZpdEJvdW5kcyhPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgYnV0dG9uUG9zaXRpb24oT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGJ1dHRvblNjYWxlSG93KE9CSl9QUk9QX1BBUkFNUyk7CisgICAgRlhfQk9PTCBidXR0b25TY2FsZVdoZW4oT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGNhbGNPcmRlckluZGV4KE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBjaGFyTGltaXQoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGNvbWIoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGNvbW1pdE9uU2VsQ2hhbmdlKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBjdXJyZW50VmFsdWVJbmRpY2VzKE9CSl9QUk9QX1BBUkFNUyk7CisgICAgRlhfQk9PTCBkZWZhdWx0U3R5bGUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGRlZmF1bHRWYWx1ZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgZG9Ob3RTY3JvbGwoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGRvTm90U3BlbGxDaGVjayhPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgZGVsYXkoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGRpc3BsYXkoT0JKX1BST1BfUEFSQU1TKTsKKyAgICBGWF9CT09MIGRvYyhPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgZWRpdGFibGUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGV4cG9ydFZhbHVlcyhPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgZmlsZVNlbGVjdChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgZmlsbENvbG9yKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBoaWRkZW4oT0JKX1BST1BfUEFSQU1TKTsKKyAgICBGWF9CT09MIGhpZ2hsaWdodChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgbGluZVdpZHRoKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBtdWx0aWxpbmUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIG11bHRpcGxlU2VsZWN0aW9uKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBuYW1lKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBudW1JdGVtcyhPQkpfUFJPUF9QQVJBTVMpOworICAgIEZYX0JPT0wgcGFnZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgcGFzc3dvcmQoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHByaW50KE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCByYWRpb3NJblVuaXNvbihPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgcmVhZG9ubHkoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHJlY3QoT0JKX1BST1BfUEFSQU1TKTsKKyAgICBGWF9CT09MIHJlcXVpcmVkKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCByaWNoVGV4dChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgcmljaFZhbHVlKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCByb3RhdGlvbihPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgc3Ryb2tlQ29sb3IoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHN0eWxlKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBzdWJtaXROYW1lKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCB0ZXh0Q29sb3IoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHRleHRGb250KE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCB0ZXh0U2l6ZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgdHlwZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgdXNlck5hbWUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHZhbHVlKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCB2YWx1ZUFzU3RyaW5nKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBzb3VyY2UoT0JKX1BST1BfUEFSQU1TKTsKKworCUZYX0JPT0wgYnJvd3NlRm9yRmlsZVRvU3VibWl0KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIGJ1dHRvbkdldENhcHRpb24oT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgYnV0dG9uR2V0SWNvbihPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBidXR0b25JbXBvcnRJY29uKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIGJ1dHRvblNldENhcHRpb24oT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgYnV0dG9uU2V0SWNvbihPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBjaGVja1RoaXNCb3goT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgY2xlYXJJdGVtcyhPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBkZWZhdWx0SXNDaGVja2VkKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIGRlbGV0ZUl0ZW1BdChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBnZXRBcnJheShPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBnZXRJdGVtQXQoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgZ2V0TG9jayhPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBpbnNlcnRJdGVtQXQoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgaXNCb3hDaGVja2VkKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIGlzRGVmYXVsdENoZWNrZWQoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgc2V0QWN0aW9uKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIHNldEZvY3VzKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIHNldEl0ZW1zKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIHNldExvY2soT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgc2lnbmF0dXJlR2V0TW9kaWZpY2F0aW9ucyhPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBzaWduYXR1cmVHZXRTZWVkVmFsdWUoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgc2lnbmF0dXJlSW5mbyhPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBzaWduYXR1cmVTZXRTZWVkVmFsdWUoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgc2lnbmF0dXJlU2lnbihPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBzaWduYXR1cmVWYWxpZGF0ZShPQkpfTUVUSE9EX1BBUkFNUyk7CisKK3B1YmxpYzoKKwlzdGF0aWMgdm9pZCBTZXRBbGlnbm1lbnQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyaW5nKTsKKyAgICBzdGF0aWMgdm9pZCBTZXRCb3JkZXJTdHlsZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpOworCXN0YXRpYyB2b2lkIFNldEJ1dHRvbkFsaWduWChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpOworCXN0YXRpYyB2b2lkIFNldEJ1dHRvbkFsaWduWShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpOworCXN0YXRpYyB2b2lkIFNldEJ1dHRvbkZpdEJvdW5kcyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYik7CisJc3RhdGljIHZvaWQgU2V0QnV0dG9uUG9zaXRpb24oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKTsKKwlzdGF0aWMgdm9pZCBTZXRCdXR0b25TY2FsZUhvdyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpOworICAgIHN0YXRpYyB2b2lkIFNldEJ1dHRvblNjYWxlV2hlbihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpOworCXN0YXRpYyB2b2lkIFNldENhbGNPcmRlckluZGV4KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcik7CisJc3RhdGljIHZvaWQgU2V0Q2hhckxpbWl0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcik7CisJc3RhdGljIHZvaWQgU2V0Q29tYihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYik7CisJc3RhdGljIHZvaWQgU2V0Q29tbWl0T25TZWxDaGFuZ2UoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpOworCXN0YXRpYyB2b2lkIFNldEN1cnJlbnRWYWx1ZUluZGljZXMoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDRlhfRFdvcmRBcnJheSYgYXJyYXkpOworICAgIHN0YXRpYyB2b2lkIFNldERlZmF1bHRTdHlsZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgpOworCXN0YXRpYyB2b2lkIFNldERlZmF1bHRWYWx1ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpOworCXN0YXRpYyB2b2lkIFNldERvTm90U2Nyb2xsKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKTsKKwlzdGF0aWMgdm9pZCBTZXREaXNwbGF5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcik7CisJc3RhdGljIHZvaWQgU2V0RmlsbENvbG9yKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpOworCXN0YXRpYyB2b2lkIFNldEhpZGRlbihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYik7CisgICAgc3RhdGljIHZvaWQgU2V0SGlnaGxpZ2h0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0cmluZyk7CisJc3RhdGljIHZvaWQgU2V0TGluZVdpZHRoKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcik7CisJc3RhdGljIHZvaWQgU2V0TXVsdGlsaW5lKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKTsKKwlzdGF0aWMgdm9pZCBTZXRNdWx0aXBsZVNlbGVjdGlvbihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYik7CisJc3RhdGljIHZvaWQgU2V0UGFzc3dvcmQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpOworCXN0YXRpYyB2b2lkIFNldFJlY3QoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDUERGX1JlY3QmIHJlY3QpOworCXN0YXRpYyB2b2lkIFNldFJpY2hUZXh0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKTsKKwlzdGF0aWMgdm9pZCBTZXRSaWNoVmFsdWUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4KTsKKwlzdGF0aWMgdm9pZCBTZXRSb3RhdGlvbihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpOworCXN0YXRpYyB2b2lkIFNldFN0cm9rZUNvbG9yKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpOworCXN0YXRpYyB2b2lkIFNldFN0eWxlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0cmluZyk7CisJc3RhdGljIHZvaWQgU2V0VGV4dENvbG9yKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpOworCXN0YXRpYyB2b2lkIFNldFRleHRGb250KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0cmluZyk7CisJc3RhdGljIHZvaWQgU2V0VGV4dFNpemUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKTsKKwlzdGF0aWMgdm9pZCBTZXRVc2VyTmFtZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpOworCXN0YXRpYyB2b2lkIFNldFZhbHVlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0pTX1dpZGVTdHJpbmdBcnJheSYgc3RyQXJyYXkpOworCitwdWJsaWM6CisJc3RhdGljIHZvaWQJCQkJCQkJQWRkRmllbGQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBpbnQgblBhZ2VJbmRleCwgaW50IG5GaWVsZFR5cGUsIAorCQkJCQkJCQkJCQljb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUsIGNvbnN0IENQREZfUmVjdCYgcmNDb29yZHMpOworcHVibGljOgorCXN0YXRpYyB2b2lkCQkJCQkJCVVwZGF0ZUZvcm1GaWVsZChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCAKKwkJCQkJCQkJCQkJRlhfQk9PTCBiQ2hhbmdlTWFyaywgRlhfQk9PTCBiUmVzZXRBUCwgRlhfQk9PTCBiUmVmcmVzaCk7CisJc3RhdGljIHZvaWQJCQkJCQkJVXBkYXRlRm9ybUNvbnRyb2woQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wsIAorCQkJCQkJCQkJCQlGWF9CT09MIGJDaGFuZ2VNYXJrLCBGWF9CT09MIGJSZXNldEFQLCBGWF9CT09MIGJSZWZyZXNoKTsKKworCXN0YXRpYyBDUERGU0RLX1dpZGdldCoJCQkJCUdldFdpZGdldChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCk7CisJc3RhdGljIHZvaWQJCQkJCQkJR2V0Rm9ybUZpZWxkcyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBjc0ZpZWxkTmFtZSwgQ0ZYX1B0ckFycmF5JiBGaWVsZHNBcnJheSk7CisKKwlzdGF0aWMgdm9pZAkJCQkJCQlEb0RlbGF5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ0pTX0RlbGF5RGF0YSogcERhdGEpOworCitwdWJsaWM6CisJRlhfQk9PTAkJCQkJCQkJQXR0YWNoRmllbGQoRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIGNzRmllbGROYW1lKTsKKwl2b2lkCQkJCQkJCQlTZXREZWxheShGWF9CT09MIGJEZWxheSk7CisJdm9pZAkJCQkJCQkJU2V0SXNvbGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSkge21faXNvbGF0ZSA9IGlzb2xhdGU7fQorcHJvdGVjdGVkOgorCXZvaWQJCQkJCQkJCVBhcnNlRmllbGROYW1lKGNvbnN0IHN0ZDo6d3N0cmluZyAmc3RyRmllbGROYW1lUGFyc2VkLHN0ZDo6d3N0cmluZyAmc3RyRmllbGROYW1lLGludCAmIGlDb250cm9sTm8pOworCXZvaWQJCQkJCQkJCUdldEZvcm1GaWVsZHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIGNzRmllbGROYW1lLCBDRlhfUHRyQXJyYXkmIEZpZWxkc0FycmF5KTsKKwlDUERGX0Zvcm1Db250cm9sKiAJCQkJCUdldFNtYXJ0RmllbGRDb250cm9sKENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkKTsKKwlGWF9CT09MCQkJCQkJCQlWYWx1ZUlzT2NjdXIoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIENGWF9XaWRlU3RyaW5nIGNzT3B0TGFiZWwpOworCisJdm9pZAkJCQkJCQkJQWRkRGVsYXlfSW50KGVudW0gRklFTERfUFJPUCBwcm9wLCBGWF9JTlQzMiBuKTsKKwl2b2lkCQkJCQkJCQlBZGREZWxheV9Cb29sKGVudW0gRklFTERfUFJPUCBwcm9wLGJvb2wgYik7CisJdm9pZAkJCQkJCQkJQWRkRGVsYXlfU3RyaW5nKGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyaW5nKTsKKwl2b2lkCQkJCQkJCQlBZGREZWxheV9XaWRlU3RyaW5nKGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKTsKKwl2b2lkCQkJCQkJCQlBZGREZWxheV9SZWN0KGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDUERGX1JlY3QmIHJlY3QpOworCXZvaWQJCQkJCQkJCUFkZERlbGF5X0NvbG9yKGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7CisJdm9pZAkJCQkJCQkJQWRkRGVsYXlfV29yZEFycmF5KGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDRlhfRFdvcmRBcnJheSYgYXJyYXkpOworCXZvaWQJCQkJCQkJCUFkZERlbGF5X1dpZGVTdHJpbmdBcnJheShlbnVtIEZJRUxEX1BST1AgcHJvcCwgY29uc3QgQ0pTX1dpZGVTdHJpbmdBcnJheSYgYXJyYXkpOworCisJdm9pZAkJCQkJCQkJRG9EZWxheSgpOworcHVibGljOgorCURvY3VtZW50KgkJCQkJCQltX3BKU0RvYzsKKwlDUERGU0RLX0RvY3VtZW50KgkJCQkJbV9wRG9jdW1lbnQ7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCQltX0ZpZWxkTmFtZTsKKwlpbnQJCQkJCQkJCQltX25Gb3JtQ29udHJvbEluZGV4OworCUZYX0JPT0wJCQkJCQkJCW1fYkNhblNldDsKKworCUZYX0JPT0wJCQkJCQkJCW1fYkRlbGF5OworCXY4OjpJc29sYXRlKgkJCQkJCQltX2lzb2xhdGU7Cit9OworCitjbGFzcyBDSlNfRmllbGQgOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19GaWVsZChKU0ZYT2JqZWN0IHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsKKwl2aXJ0dWFsIH5DSlNfRmllbGQodm9pZCl7fTsKKworCXZpcnR1YWwgRlhfQk9PTAlJbml0SW5zdGFuY2UoSUZYSlNfQ29udGV4dCogY2MpOworCisJREVDTEFSRV9KU19DTEFTUyhDSlNfRmllbGQpOworCisgICAgSlNfU1RBVElDX1BST1AoYWxpZ25tZW50LCBGaWVsZCk7CisgICAgSlNfU1RBVElDX1BST1AoYm9yZGVyU3R5bGUsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChidXR0b25BbGlnblgsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChidXR0b25BbGlnblksIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChidXR0b25GaXRCb3VuZHMsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChidXR0b25Qb3NpdGlvbiwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKGJ1dHRvblNjYWxlSG93LCBGaWVsZCk7CisgICAgSlNfU1RBVElDX1BST1AoYnV0dG9uU2NhbGVXaGVuLCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1AoY2FsY09yZGVySW5kZXgsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChjaGFyTGltaXQsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChjb21iLCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1AoY29tbWl0T25TZWxDaGFuZ2UsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChjdXJyZW50VmFsdWVJbmRpY2VzLCBGaWVsZCk7CisgICAgSlNfU1RBVElDX1BST1AoZGVmYXVsdFN0eWxlLCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1AoZGVmYXVsdFZhbHVlLCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1AoZG9Ob3RTY3JvbGwsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChkb05vdFNwZWxsQ2hlY2ssIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChkZWxheSwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKGRpc3BsYXksIEZpZWxkKTsKKyAgICBKU19TVEFUSUNfUFJPUChkb2MsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChlZGl0YWJsZSwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKGV4cG9ydFZhbHVlcywgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKGZpbGVTZWxlY3QsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChmaWxsQ29sb3IsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChoaWRkZW4sIEZpZWxkKTsKKyAgICBKU19TVEFUSUNfUFJPUChoaWdobGlnaHQsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChsaW5lV2lkdGgsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChtdWx0aWxpbmUsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChtdWx0aXBsZVNlbGVjdGlvbiwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKG5hbWUsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChudW1JdGVtcywgRmllbGQpOworICAgIEpTX1NUQVRJQ19QUk9QKHBhZ2UsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChwYXNzd29yZCwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKHByaW50LCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1AocmFkaW9zSW5Vbmlzb24sIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChyZWFkb25seSwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKHJlY3QsIEZpZWxkKTsKKyAgICBKU19TVEFUSUNfUFJPUChyZXF1aXJlZCwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKHJpY2hUZXh0LCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1AocmljaFZhbHVlLCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1Aocm90YXRpb24sIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChzdHJva2VDb2xvciwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKHN0eWxlLCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1Aoc3VibWl0TmFtZSwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKHRleHRDb2xvciwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKHRleHRGb250LCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1AodGV4dFNpemUsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUCh0eXBlLCBGaWVsZCk7CisJSlNfU1RBVElDX1BST1AodXNlck5hbWUsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUCh2YWx1ZSwgRmllbGQpOworCUpTX1NUQVRJQ19QUk9QKHZhbHVlQXNTdHJpbmcsIEZpZWxkKTsKKwlKU19TVEFUSUNfUFJPUChzb3VyY2UsIEZpZWxkKTsKKworCUpTX1NUQVRJQ19NRVRIT0QoYnJvd3NlRm9yRmlsZVRvU3VibWl0LCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChidXR0b25HZXRDYXB0aW9uLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChidXR0b25HZXRJY29uLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChidXR0b25JbXBvcnRJY29uLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChidXR0b25TZXRDYXB0aW9uLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChidXR0b25TZXRJY29uLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChjaGVja1RoaXNCb3gsIEZpZWxkKTsKKwlKU19TVEFUSUNfTUVUSE9EKGNsZWFySXRlbXMsIEZpZWxkKTsKKyAJSlNfU1RBVElDX01FVEhPRChkZWZhdWx0SXNDaGVja2VkLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChkZWxldGVJdGVtQXQsIEZpZWxkKTsKKwlKU19TVEFUSUNfTUVUSE9EKGdldEFycmF5LCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChnZXRJdGVtQXQsIEZpZWxkKTsKKwlKU19TVEFUSUNfTUVUSE9EKGdldExvY2ssIEZpZWxkKTsKKwlKU19TVEFUSUNfTUVUSE9EKGluc2VydEl0ZW1BdCwgRmllbGQpOworCUpTX1NUQVRJQ19NRVRIT0QoaXNCb3hDaGVja2VkLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChpc0RlZmF1bHRDaGVja2VkLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChzZXRBY3Rpb24sIEZpZWxkKTsKKwlKU19TVEFUSUNfTUVUSE9EKHNldEZvY3VzLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChzZXRJdGVtcywgRmllbGQpOworCUpTX1NUQVRJQ19NRVRIT0Qoc2V0TG9jaywgRmllbGQpOworCUpTX1NUQVRJQ19NRVRIT0Qoc2lnbmF0dXJlR2V0TW9kaWZpY2F0aW9ucywgRmllbGQpOworCUpTX1NUQVRJQ19NRVRIT0Qoc2lnbmF0dXJlR2V0U2VlZFZhbHVlLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChzaWduYXR1cmVJbmZvLCBGaWVsZCk7CisJSlNfU1RBVElDX01FVEhPRChzaWduYXR1cmVTZXRTZWVkVmFsdWUsIEZpZWxkKTsKKwlKU19TVEFUSUNfTUVUSE9EKHNpZ25hdHVyZVNpZ24sIEZpZWxkKTsKKwlKU19TVEFUSUNfTUVUSE9EKHNpZ25hdHVyZVZhbGlkYXRlLCBGaWVsZCk7Cit9OworCisjZW5kaWYgLy9fRklFTERfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgKaW5kZXggNTY3ZWU4Mi4uMzA4N2I2YSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oCkBAIC0xLDExMiArMSwxMTIgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0lKQVZBU0NSSVBUX0hfDQotI2RlZmluZSBfSUpBVkFTQ1JJUFRfSF8NCi0NCi1jbGFzcyBJRlhKU19Db250ZXh0ICANCi17DQotcHVibGljOg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJQ29tcGlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0LCBDRlhfV2lkZVN0cmluZyYgaW5mbykgPSAwOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJUnVuU2NyaXB0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQsIENGWF9XaWRlU3RyaW5nJiBpbmZvKSA9IDA7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJT25BcHBfSW5pdCgpID0gMDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uRG9jX09wZW4oQ1BERlNES19Eb2N1bWVudCogcERvYywgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0clRhcmdldE5hbWUpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRG9jX1dpbGxQcmludChDUERGU0RLX0RvY3VtZW50KiBwRG9jKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19EaWRQcmludChDUERGU0RLX0RvY3VtZW50KiBwRG9jKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19XaWxsU2F2ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19EaWRTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRG9jX1dpbGxDbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKSA9IDA7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlPblBhZ2VfT3BlbihDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPblBhZ2VfQ2xvc2UoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25QYWdlX0luVmlldyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPblBhZ2VfT3V0VmlldyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KSA9IDA7DQotCQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9Nb3VzZURvd24oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9Nb3VzZUVudGVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfTW91c2VFeGl0KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfTW91c2VVcChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBWYWx1ZSkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9CbHVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBWYWx1ZSkgPSAwOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9DYWxjdWxhdGUoQ1BERl9Gb3JtRmllbGQqIHBTb3VyY2UsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wmIGJSYykgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9Gb3JtYXQoaW50IG5Db21taXRLZXksIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wgYldpbGxDb21taXQpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfS2V5c3Ryb2tlKGludCBuQ29tbWl0S2V5LCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsDQotCQkJCQkJCQkJRlhfQk9PTCBLZXlEb3duLCBGWF9CT09MIGJNb2RpZmllciwgaW50ICZuU2VsRW5kLGludCAmblNlbFN0YXJ0LCBGWF9CT09MIGJTaGlmdCwNCi0JCQkJCQkJCQlDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0LCANCi0JCQkJCQkJCQlGWF9CT09MIGJGaWVsZEZ1bGwsIEZYX0JPT0wgJmJSYykgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9WYWxpZGF0ZShDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIEZYX0JPT0wgYktleURvd24sDQotCQkJCQkJCQkJRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MJiBiUmMpID0gMDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fQmx1cihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX09wZW4oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9DbG9zZShGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX01vdXNlRG93bihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX01vdXNlVXAoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9Nb3VzZUVudGVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fTW91c2VFeGl0KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fSW5WaWV3KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fT3V0VmlldyhGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pID0gMDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uQm9va21hcmtfTW91c2VVcChDUERGX0Jvb2ttYXJrKiBwQm9va01hcmspID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uTGlua19Nb3VzZVVwKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpID0gMDsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uTWVudV9FeGVjKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQsIGNvbnN0IENGWF9XaWRlU3RyaW5nICYpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uQmF0Y2hFeGVjKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCU9uQ29uc29sZV9FeGVjKCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25FeHRlcm5hbF9FeGVjKCkgPSAwOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJRW5hYmxlTWVzc2FnZUJveChGWF9CT09MIGJFbmFibGUpID0gMDsNCi19Ow0KLQ0KLWNsYXNzIElGWEpTX1J1bnRpbWUNCi17DQotcHVibGljOg0KLQl2aXJ0dWFsIElGWEpTX0NvbnRleHQqCQlOZXdDb250ZXh0KCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJUmVsZWFzZUNvbnRleHQoSUZYSlNfQ29udGV4dCAqIHBDb250ZXh0KSA9IDA7DQotCXZpcnR1YWwgSUZYSlNfQ29udGV4dCoJCUdldEN1cnJlbnRDb250ZXh0KCkgPSAwOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJU2V0UmVhZGVyRG9jdW1lbnQoQ1BERlNES19Eb2N1bWVudCogcFJlYWRlckRvYykgPSAwOw0KLQl2aXJ0dWFsCUNQREZTREtfRG9jdW1lbnQqCUdldFJlYWRlckRvY3VtZW50KCkgPSAwOwkNCi0NCi0JdmlydHVhbCB2b2lkCQkJCUdldE9iamVjdE5hbWVzKENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlHZXRPYmplY3RDb25zdHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3T2JqTmFtZSwgQ0ZYX1dpZGVTdHJpbmdBcnJheSYgYXJyYXkpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCUdldE9iamVjdFByb3BzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQlHZXRPYmplY3RNZXRob2RzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KSA9IDA7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlFeGl0KCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJRW50ZXIoKSA9IDA7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0VudGVyZWQoKSA9IDA7DQotfTsNCi0NCi1jbGFzcyBDUERGRG9jX0Vudmlyb25tZW50Ow0KLWNsYXNzIENKU19HbG9iYWxEYXRhOw0KLQ0KLWNsYXNzIENKU19SdW50aW1lRmFjdG9yeQ0KLXsNCi1wdWJsaWM6DQotCUNKU19SdW50aW1lRmFjdG9yeSgpOm1fYkluaXQoRkFMU0UpLG1fblJlZigwKSxtX3BHbG9iYWxEYXRhKE5VTEwpLG1fbkdsb2JhbERhdGFDb3VudCgwKSB7fQ0KLQl+Q0pTX1J1bnRpbWVGYWN0b3J5KCk7DQotCUlGWEpTX1J1bnRpbWUqCQkJCQlOZXdKU1J1bnRpbWUoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCk7DQotCXZvaWQJCQkJCQkJRGVsZXRlSlNSdW50aW1lKElGWEpTX1J1bnRpbWUqIHBSdW50aW1lKTsNCi0Jdm9pZAkJCQkJCQlBZGRSZWYoKTsNCi0Jdm9pZAkJCQkJCQlSZWxlYXNlKCk7DQotDQotCUNKU19HbG9iYWxEYXRhKgkJCQkJTmV3R2xvYmFsRGF0YShDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwKTsNCi0Jdm9pZAkJCQkJCQlSZWxlYXNlR2xvYmFsRGF0YSgpOw0KLXByaXZhdGU6DQotCUZYX0JPT0wgbV9iSW5pdDsNCi0JaW50IG1fblJlZjsNCi0JQ0pTX0dsb2JhbERhdGEqCQkJCQltX3BHbG9iYWxEYXRhOw0KLQlGWF9JTlQzMgkJCQkJCW1fbkdsb2JhbERhdGFDb3VudDsNCi19Ow0KLQ0KLSNlbmRpZiAvL19JSkFWQVNDUklQVF9IXw0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0lKQVZBU0NSSVBUX0hfCisjZGVmaW5lIF9JSkFWQVNDUklQVF9IXworCitjbGFzcyBJRlhKU19Db250ZXh0ICAKK3sKK3B1YmxpYzoKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQ29tcGlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0LCBDRlhfV2lkZVN0cmluZyYgaW5mbykgPSAwOworCXZpcnR1YWwgRlhfQk9PTAkJCQlSdW5TY3JpcHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNjcmlwdCwgQ0ZYX1dpZGVTdHJpbmcmIGluZm8pID0gMDsKKworcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQlPbkFwcF9Jbml0KCkgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCU9uRG9jX09wZW4oQ1BERlNES19Eb2N1bWVudCogcERvYywgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0clRhcmdldE5hbWUpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJT25Eb2NfV2lsbFByaW50KENQREZTREtfRG9jdW1lbnQqIHBEb2MpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJT25Eb2NfRGlkUHJpbnQoQ1BERlNES19Eb2N1bWVudCogcERvYykgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19XaWxsU2F2ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uRG9jX0RpZFNhdmUoQ1BERlNES19Eb2N1bWVudCogcERvYykgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19XaWxsQ2xvc2UoQ1BERlNES19Eb2N1bWVudCogcERvYykgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCU9uUGFnZV9PcGVuKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJT25QYWdlX0Nsb3NlKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJT25QYWdlX0luVmlldyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uUGFnZV9PdXRWaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpID0gMDsKKwkKKwl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9Nb3VzZURvd24oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX01vdXNlRW50ZXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX01vdXNlRXhpdChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfTW91c2VVcChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfRm9jdXMoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfQmx1cihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgVmFsdWUpID0gMDsKKworCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX0NhbGN1bGF0ZShDUERGX0Zvcm1GaWVsZCogcFNvdXJjZSwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCYgYlJjKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfRm9ybWF0KGludCBuQ29tbWl0S2V5LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfS2V5c3Ryb2tlKGludCBuQ29tbWl0S2V5LCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsCisJCQkJCQkJCQlGWF9CT09MIEtleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLCBpbnQgJm5TZWxFbmQsaW50ICZuU2VsU3RhcnQsIEZYX0JPT0wgYlNoaWZ0LAorCQkJCQkJCQkJQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCBiV2lsbENvbW1pdCwgCisJCQkJCQkJCQlGWF9CT09MIGJGaWVsZEZ1bGwsIEZYX0JPT0wgJmJSYykgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX1ZhbGlkYXRlKENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwgRlhfQk9PTCBiS2V5RG93biwKKwkJCQkJCQkJCUZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCYgYlJjKSA9IDA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fRm9jdXMoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX09wZW4oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX0Nsb3NlKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9Nb3VzZURvd24oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX01vdXNlVXAoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX01vdXNlRW50ZXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX01vdXNlRXhpdChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fSW5WaWV3KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9PdXRWaWV3KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCU9uQm9va21hcmtfTW91c2VVcChDUERGX0Jvb2ttYXJrKiBwQm9va01hcmspID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJT25MaW5rX01vdXNlVXAoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCkgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCU9uTWVudV9FeGVjKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQsIGNvbnN0IENGWF9XaWRlU3RyaW5nICYpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJT25CYXRjaEV4ZWMoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlPbkNvbnNvbGVfRXhlYygpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJT25FeHRlcm5hbF9FeGVjKCkgPSAwOworCisJdmlydHVhbCB2b2lkCQkJCUVuYWJsZU1lc3NhZ2VCb3goRlhfQk9PTCBiRW5hYmxlKSA9IDA7Cit9OworCitjbGFzcyBJRlhKU19SdW50aW1lCit7CitwdWJsaWM6CisJdmlydHVhbCBJRlhKU19Db250ZXh0KgkJTmV3Q29udGV4dCgpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJUmVsZWFzZUNvbnRleHQoSUZYSlNfQ29udGV4dCAqIHBDb250ZXh0KSA9IDA7CisJdmlydHVhbCBJRlhKU19Db250ZXh0KgkJR2V0Q3VycmVudENvbnRleHQoKSA9IDA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJU2V0UmVhZGVyRG9jdW1lbnQoQ1BERlNES19Eb2N1bWVudCogcFJlYWRlckRvYykgPSAwOworCXZpcnR1YWwJQ1BERlNES19Eb2N1bWVudCoJR2V0UmVhZGVyRG9jdW1lbnQoKSA9IDA7CQorCisJdmlydHVhbCB2b2lkCQkJCUdldE9iamVjdE5hbWVzKENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCUdldE9iamVjdENvbnN0cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dPYmpOYW1lLCBDRlhfV2lkZVN0cmluZ0FycmF5JiBhcnJheSkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlHZXRPYmplY3RQcm9wcyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dPYmpOYW1lLCBDRlhfV2lkZVN0cmluZ0FycmF5JiBhcnJheSkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQlHZXRPYmplY3RNZXRob2RzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KSA9IDA7CisKKwl2aXJ0dWFsIHZvaWQJCQkJRXhpdCgpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJRW50ZXIoKSA9IDA7CisJdmlydHVhbCBGWF9CT09MCQkJCUlzRW50ZXJlZCgpID0gMDsKK307CisKK2NsYXNzIENQREZEb2NfRW52aXJvbm1lbnQ7CitjbGFzcyBDSlNfR2xvYmFsRGF0YTsKKworY2xhc3MgQ0pTX1J1bnRpbWVGYWN0b3J5Cit7CitwdWJsaWM6CisJQ0pTX1J1bnRpbWVGYWN0b3J5KCk6bV9iSW5pdChGQUxTRSksbV9uUmVmKDApLG1fcEdsb2JhbERhdGEoTlVMTCksbV9uR2xvYmFsRGF0YUNvdW50KDApIHt9CisJfkNKU19SdW50aW1lRmFjdG9yeSgpOworCUlGWEpTX1J1bnRpbWUqCQkJCQlOZXdKU1J1bnRpbWUoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCk7CisJdm9pZAkJCQkJCQlEZWxldGVKU1J1bnRpbWUoSUZYSlNfUnVudGltZSogcFJ1bnRpbWUpOworCXZvaWQJCQkJCQkJQWRkUmVmKCk7CisJdm9pZAkJCQkJCQlSZWxlYXNlKCk7CisKKwlDSlNfR2xvYmFsRGF0YSoJCQkJCU5ld0dsb2JhbERhdGEoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCk7CisJdm9pZAkJCQkJCQlSZWxlYXNlR2xvYmFsRGF0YSgpOworcHJpdmF0ZToKKwlGWF9CT09MIG1fYkluaXQ7CisJaW50IG1fblJlZjsKKwlDSlNfR2xvYmFsRGF0YSoJCQkJCW1fcEdsb2JhbERhdGE7CisJRlhfSU5UMzIJCQkJCQltX25HbG9iYWxEYXRhQ291bnQ7Cit9OworCisjZW5kaWYgLy9fSUpBVkFTQ1JJUFRfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSWNvbi5oIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSWNvbi5oCmluZGV4IDI2ZmVjMmQuLjk0MjZkMzIgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0ljb24uaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9JY29uLmgKQEAgLTEsNDIgKzEsNDIgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0lDT05fSF8NCi0jZGVmaW5lIF9JQ09OX0hfDQotDQotY2xhc3MgSWNvbiA6IHB1YmxpYyBDSlNfRW1iZWRPYmoNCi17DQotcHVibGljOg0KLQlJY29uKENKU19PYmplY3QqIHBKU09iamVjdCk7DQotCXZpcnR1YWwgfkljb24oKTsNCi0NCi1wdWJsaWM6DQotCUZYX0JPT0wgbmFtZShPQkpfUFJPUF9QQVJBTVMpOw0KLQkNCi1wdWJsaWM6DQotCXZvaWQJCQkJU2V0U3RyZWFtKENQREZfU3RyZWFtKiBwSWNvblN0cmVhbSk7DQotCUNQREZfU3RyZWFtKgkJR2V0U3RyZWFtKCk7DQotCXZvaWQJCQkJU2V0SWNvbk5hbWUoQ0ZYX1dpZGVTdHJpbmcgbmFtZSk7DQotCUNGWF9XaWRlU3RyaW5nCQlHZXRJY29uTmFtZSgpOw0KLXByaXZhdGU6DQotCUNQREZfU3RyZWFtKgkJbV9wSWNvblN0cmVhbTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCW1fc3dJY29uTmFtZTsNCi19Ow0KLQ0KLWNsYXNzIENKU19JY29uIDogcHVibGljIENKU19PYmplY3QNCi17DQotcHVibGljOg0KLQlDSlNfSWNvbihKU0ZYT2JqZWN0IHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KXt9Ow0KLQl2aXJ0dWFsIH5DSlNfSWNvbigpe307DQotDQotcHVibGljOg0KLQlERUNMQVJFX0pTX0NMQVNTKENKU19JY29uKTsNCi0NCi0JSlNfU1RBVElDX1BST1AobmFtZSwgSWNvbik7DQotfTsNCi0NCi0jZW5kaWYgLy9fSUNPTl9IXw0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0lDT05fSF8KKyNkZWZpbmUgX0lDT05fSF8KKworY2xhc3MgSWNvbiA6IHB1YmxpYyBDSlNfRW1iZWRPYmoKK3sKK3B1YmxpYzoKKwlJY29uKENKU19PYmplY3QqIHBKU09iamVjdCk7CisJdmlydHVhbCB+SWNvbigpOworCitwdWJsaWM6CisJRlhfQk9PTCBuYW1lKE9CSl9QUk9QX1BBUkFNUyk7CisJCitwdWJsaWM6CisJdm9pZAkJCQlTZXRTdHJlYW0oQ1BERl9TdHJlYW0qIHBJY29uU3RyZWFtKTsKKwlDUERGX1N0cmVhbSoJCUdldFN0cmVhbSgpOworCXZvaWQJCQkJU2V0SWNvbk5hbWUoQ0ZYX1dpZGVTdHJpbmcgbmFtZSk7CisJQ0ZYX1dpZGVTdHJpbmcJCUdldEljb25OYW1lKCk7Citwcml2YXRlOgorCUNQREZfU3RyZWFtKgkJbV9wSWNvblN0cmVhbTsKKwlDRlhfV2lkZVN0cmluZwkJbV9zd0ljb25OYW1lOworfTsKKworY2xhc3MgQ0pTX0ljb24gOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19JY29uKEpTRlhPYmplY3QgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3Qpe307CisJdmlydHVhbCB+Q0pTX0ljb24oKXt9OworCitwdWJsaWM6CisJREVDTEFSRV9KU19DTEFTUyhDSlNfSWNvbik7CisKKwlKU19TVEFUSUNfUFJPUChuYW1lLCBJY29uKTsKK307CisKKyNlbmRpZiAvL19JQ09OX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnNvbGUuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnNvbGUuaAppbmRleCBkYTg0MmJkLi5mNDM1MTM1IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db25zb2xlLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29uc29sZS5oCkBAIC0xLDIzOSArMSwyMzkgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0pTX0NPTlNPTEVfSF8NCi0jZGVmaW5lIF9KU19DT05TT0xFX0hfDQotDQotI2luY2x1ZGUgIi4uL3Jlcy9yZXNvdXJjZS5oIg0KLQ0KLSNkZWZpbmUgV1NUX05PTkUJCTB4MDAJCQkJCS8vIE5vIHNpemUgY2hhbmdlZA0KLSNkZWZpbmUgV1NUX0xFRlQJCTB4MDEJCQkJCS8vIHNpemUgdG8gbGVmdA0KLSNkZWZpbmUgV1NUX1RPUAkJCTB4MDIJCQkJCS8vIHNpemUgdG8gdG9wDQotI2RlZmluZSBXU1RfUklHSFQJCTB4MDQJCQkJCS8vIHNpemUgdG8gcmlnaHQNCi0jZGVmaW5lIFdTVF9CT1RUT00JCTB4MDgJCQkJCS8vIHNpemUgdG8gYm90dG9tDQotI2RlZmluZSBXU1RfVE9QTEVGVAkJKFdTVF9UT1B8V1NUX0xFRlQpCQkvLyBzaXplIHRvIHRvcCAmIGxlZnQNCi0jZGVmaW5lIFdTVF9UT1BSSUdIVAkoV1NUX1RPUHxXU1RfUklHSFQpCQkvLyBzaXplIHRvIHRvcCAmIHJpZ2h0DQotI2RlZmluZSBXU1RfQk9UVE9NUklHSFQJKFdTVF9CT1RUT018V1NUX1JJR0hUKQkvLyBzaXplIHRvIGJvdHRvbSAmIHJpZ2h0DQotI2RlZmluZSBXU1RfQk9UVE9NTEVGVAkoV1NUX0JPVFRPTXxXU1RfTEVGVCkJLy8gc2l6ZSB0byBib3R0b20gJiByaWdodA0KLQ0KLSNpZm5kZWYgSURDX0RMR1NJWkVCT1gNCi0jZGVmaW5lIElEQ19ETEdTSVpFQk9YICA1MA0KLSNlbmRpZgkvKiBJRENfRExHU0laRUJPWCAqLw0KLQ0KLWVudW0geyBtX2lkU2l6ZUljb24gPSBJRENfRExHU0laRUJPWCB9Ow0KLWVudW0gewkJCQkvLyBwb3NzaWJsZSBDb250cm9sIHJlU2l6ZSBUeXBlDQotCUNTVF9OT05FID0gMCwNCi0JQ1NUX1JFU0laRSwJCS8vIE5PTU9WRSArIFNJWkUsIGFkZCBhbGwgZGVsdGEtc2l6ZSBvZiBkbGcgdG8gY29udHJvbA0KLQlDU1RfUkVQT1MsCQkvLyBNT1ZFKGFic29sdXRlbHkpICsgTk9TSVpFLCBtb3ZlIGNvbnRyb2wncyBwb3MgYnkgZGVsdGEtc2l6ZQ0KLQlDU1RfUkVMQVRJVkUsCS8vIE1PVkUocHJvcG9ydGlvbmFsKSAgKyBOT1NJWkUsIGtlZXAgY29udHJvbCBhbHdheXMgYXQgYSByZWxhdGl2ZSBwb3MNCi0JQ1NUX1pPT00sCQkvLyBNT1ZFICsgU0laRSAoYm90aCBhcmUgYXV0b21hdGljYWxseSBwcm9wb3J0aW9uYWwpDQotCUNTVF9ERUxUQV9aT09NCS8vIE1PVkUocHJvcG9ydGlvbmFsLCBzZXQgbWFudWFsbHkpICsgU0laRShwcm9wb3J0aW9uYWwsIHNldCBtYW51YWxsKQ0KLX07DQotDQotLy8gY29udGFpbmVkIGNsYXNzIHRvIGhvbGQgaXRlbSBzdGF0ZQ0KLS8vDQotY2xhc3MgQ0pTX0l0ZW1DdHJsDQotew0KLXB1YmxpYzoNCi0JVUlOVAltX25JRDsNCi0JVUlOVAltX3N0eExlZnQgIAkgICA6IDQ7CQkJLy8gd2hlbiBsZWZ0IHJlc2l6aW5nIC4uLg0KLQlVSU5UCW1fc3R4UmlnaHQgICAgIDogNDsJCQkvLyB3aGVuIHJpZ2h0IHJlc2l6aW5nIC4uLg0KLQlVSU5UCW1fc3R5VG9wICAgCSAgIDogNDsJCQkvLyB3aGVuIHRvcCByZXNpemluZyAuLi4NCi0JVUlOVAltX3N0eUJvdHRvbSAgICA6IDQ7CQkJLy8gd2hlbiBib3R0b20gcmVzaXppbmcgLi4uDQotCVVJTlQJbV9iRmxpY2tlckZyZWUgOiAxOw0KLQlVSU5UCW1fYkludmFsaWRhdGUgIDogMTsJCQkvLyBJbnZhbGlkYXRlIGN0cmwncyByZWN0KGVnLiBuby1hdXRvbWF0aWNhbCB1cGRhdGUgZm9yIHN0YXRpYyB3aGVuIHJlc2l6ZSttb3ZlKQ0KLQlVSU5UCW1fcjAJCSAgIDogMTQ7DQotCUNSZWN0CW1fd1JlY3Q7DQotCWRvdWJsZQltX3hSYXRpbywgbV9jeFJhdGlvOw0KLQlkb3VibGUJbV95UmF0aW8sIG1fY3lSYXRpbzsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZvaWQgQXNzaWduKGNvbnN0IENKU19JdGVtQ3RybCYgc3JjKTsNCi0NCi1wdWJsaWM6DQotCUNKU19JdGVtQ3RybCgpOw0KLQlDSlNfSXRlbUN0cmwoY29uc3QgQ0pTX0l0ZW1DdHJsJiBzcmMpOw0KLQ0KLQlIRFdQIE9uU2l6ZShIRFdQIGhkd3AsIGludCBzaXplVHlwZSwgQ1JlY3QgKnBuQ2x0UmVjdCwgQ1JlY3QgKnBvQ2x0UmVjdCwgQ1JlY3QgKnBSMCwgQ1duZCAqcERsZyk7DQotDQotCUNKU19JdGVtQ3RybCYgb3BlcmF0b3I9KGNvbnN0IENKU19JdGVtQ3RybCYgc3JjKTsNCi19Ow0KLQ0KLWNsYXNzIENKU19SZXNpemVEbGcgOiBwdWJsaWMgQ0RpYWxvZw0KLXsNCi0vLwlERUNMQVJFX0RZTkFNSUMoQ0pTX1Jlc2l6ZURsZykNCi1wdWJsaWM6DQotCUNKU19SZXNpemVEbGcoVUlOVCBuSUQsQ1duZCAqcFBhcmVudFduZCA9IE5VTEwpOw0KLQl2aXJ0dWFsIH5DSlNfUmVzaXplRGxnKCk7DQotDQotDQotcHVibGljOg0KLQlzdGQ6OnZlY3RvcjxDSlNfSXRlbUN0cmw+CW1fSXRlbXM7ICAgICAgICAgICAvLyBhcnJheSBvZiBjb250cm9sbGVkIGl0ZW1zDQotCUNSZWN0CQkJCQltX2NsdFJlY3QsIG1fY2x0UjA7DQotCWludAkJCQkJCW1feE1pbiwgbV95TWluOw0KLQlpbnQJCQkJCQltX3hTdCwgIG1feVN0OwkJLy9zdGVwPw0KLQlVSU5UCQkJCQltX25EZWxheVNpZGU7CQkvL2RyYWcgc2lkZSBvZiB3aW5kb3cNCi0JQ1N0YXRpYwkJCQkJbV93bmRTaXplSWNvbjsgICAgIC8vIHNpemUgaWNvbiB3aW5kb3cNCi0NCi1wcm90ZWN0ZWQ6DQotCXZvaWQgCQkJCQlBZGRDb250cm9sKCBVSU5UIG5JRCwgaW50IHhsLCBpbnQgeHIsIGludCB5dCwgaW50IHliLCBpbnQgYkZsaWNrZXJGcmVlID0gMCwgDQotCQkJCQkJCQkJICAgIGRvdWJsZSB4UmF0aW8gPSAtMS4wLCBkb3VibGUgY3hSYXRpbyA9IC0xLjAsDQotCQkJCQkJCQkJICAgIGRvdWJsZSB5UmF0aW8gPSAtMS4wLCBkb3VibGUgY3lSYXRpbyA9IC0xLjAgKTsNCi0Jdm9pZCAJCQkJCUFsbG93U2l6aW5nKGludCB4c3QsIGludCB5c3QpOw0KLQl2b2lkIAkJCQkJSGlkZVNpemVJY29uKHZvaWQpOwkNCi0JdmlydHVhbCBCT09MCQkJT25Jbml0RGlhbG9nKCk7DQotDQotCXZvaWQJCQkJCU9uU2l6aW5nKFVJTlQgblNpZGUsIExQUkVDVCBscFJlY3QpOw0KLQl2b2lkCQkJCQlPblNpemUoVUlOVCBuVHlwZSwgaW50IGN4LCBpbnQgY3kpOw0KLQl2b2lkCQkJCQlPbkdldE1pbk1heEluZm8oTUlOTUFYSU5GTyAqcG1taSk7DQotCUJPT0wJCQkJCU9uRXJhc2VCa2duZChDREMqIHBEQyk7DQotDQotcHVibGljOg0KLQlpbnQJCQkJCQlVcGRhdGVDb250cm9sUmVjdChVSU5UIG5JRCwgQ1JlY3QgKnBucik7DQotfTsNCi0NCi0NCi0vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLUNJY29uTGlzdEJveCBmb3IgQ1duZEVsZW1lbnRMaXN0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KLQ0KLWNsYXNzIENJY29uTGlzdEJveCA6IHB1YmxpYyBDTGlzdEJveA0KLXsNCi1wdWJsaWM6DQotCUNJY29uTGlzdEJveCgpOw0KLQl2aXJ0dWFsIH5DSWNvbkxpc3RCb3goKTsNCi0NCi1wdWJsaWM6DQotCWludAkJCQlJbnNlcnRTdHJpbmcoaW50IG5JbmRleCwgTFBDV1NUUiBscHN6SXRlbSAsIGludCBuSW1hZ2UpOw0KLQl2aXJ0dWFsCXZvaWQJUmVzZXRDb250ZW50KCk7DQotCXZpcnR1YWwgdm9pZAlHZXRUZXh0KGludCBuSW5kZXgsIENTdHJpbmcmIHJTdHJpbmcpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJRHJhd0l0ZW0oTFBEUkFXSVRFTVNUUlVDVCBscERyYXdJdGVtU3RydWN0KTsNCi0Jdm9pZAkJCU1lYXN1cmVJdGVtKExQTUVBU1VSRUlURU1TVFJVQ1QgbHBNZWFzdXJlSXRlbVN0cnVjdCk7DQotCWludAkJCQlDb21wYXJlSXRlbShMUENPTVBBUkVJVEVNU1RSVUNUIGxwQ29tcGFyZUl0ZW1TdHJ1Y3QpOw0KLQ0KLXByb3RlY3RlZDoNCi0JLy8gR2VuZXJhdGVkIG1lc3NhZ2UgbWFwIGZ1bmN0aW9ucw0KLQkvL3t7QUZYX01TRyhDSWNvbkxpc3RCb3gpDQotCWFmeF9tc2cgdm9pZCBPbk1vdXNlTW92ZShVSU5UIG5GbGFncywgQ1BvaW50IHBvaW50KTsNCi0JLy99fUFGWF9NU0cJDQotCURFQ0xBUkVfTUVTU0FHRV9NQVAoKQ0KLQ0KLXByb3RlY3RlZDoNCi0Jc3RydWN0IEl0ZW1EYXRhcyANCi0Jew0KLQkJQ1N0cmluZwljc1RleHQ7DQotCQlpbnQJCW5JbWFnZTsNCi0JfTsNCi19Ow0KLS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLUNXbmRFbGVtZW50TGlzdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQotI2RlZmluZSBJRENfTElTVF9KU19FTEVNRU5UIDEwMDcwDQotDQotI2RlZmluZSBFTEVNRU5UX0xJU1RfV0lEVEggMTQwDQotI2RlZmluZSBFTEVNRU5UX0xJU1RfSEVJR0hUIDE4MA0KLSNkZWZpbmUgRUxFTUVOVF9MSVNUX1RPUF9PRkZTRVQgMTMNCi0NCi0jZGVmaW5lIEVMRU1FTlRfVFlQRV9OQU1FCTANCi0jZGVmaW5lIEVMRU1FTlRfVFlQRV9DT05TVAkxDQotI2RlZmluZSBFTEVNRU5UX1RZUEVfRlVOCTINCi0jZGVmaW5lIEVMRU1FTlRfVFlQRV9QUk8JMw0KLQ0KLWNsYXNzIENXbmRFbGVtZW50TGlzdCA6IHB1YmxpYyBDV25kDQotew0KLXB1YmxpYzoNCi0JQ1duZEVsZW1lbnRMaXN0KCk7DQotCXZpcnR1YWwgfkNXbmRFbGVtZW50TGlzdCgpOw0KLQkNCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAlPblNpemUoVUlOVCBuVHlwZSwgaW50IGN4LCBpbnQgY3kpOw0KLQl2aXJ0dWFsIEJPT0wJQ3JlYXRlKENXbmQqIHBQYXJlbnRXbmQpOw0KLQl2aXJ0dWFsIEJPT0wJU2hvd1dpbmRvdyhpbnQgbkNtZFNob3cpOw0KLQl2b2lkCQkJUmVtb3ZlQWxsRWxlbWVudCgpOw0KLQl2b2lkCQkJU2V0RWxlbWVudExpc3QoTFBDV1NUUiogcEVsZW1lbnQsIGludCogcFR5cGUgLCAgaW50IGlDb3VudCk7DQotCXZvaWQJCQlBZGRFbGVtZW50KENGWF9XaWRlU3RyaW5nIGNzVmFsdWUgLCBpbnQgblR5cGUpOw0KLQlCT09MCQkJR2V0RWxlbWVudFNlbChDU3RyaW5nICZjc0VsZW1lbnQpOw0KLQlCT09MCQkJU2VsZWN0TmV4dCgpOw0KLQlCT09MCQkJU2VsZWN0UHJldmlvdXMoKTsNCi0JQk9PTAkJCVNlbGVjdEZpcnN0KCk7DQotCUJPT0wJCQlTZWxlY3RMYXN0KCk7DQotCUJPT0wJCQlTZWxlY3ROZXh0UGFnZSgpOw0KLQlCT09MCQkJU2VsZWN0UHJldmlvdXNQYWdlKCk7DQotCWludAkJCQlHZXRMaXN0SGVpZ2h0KCk7DQotCQ0KLXByb3RlY3RlZDoNCi0JLy8gR2VuZXJhdGVkIG1lc3NhZ2UgbWFwIGZ1bmN0aW9ucw0KLQkvL3t7QUZYX01TRyhDV25kRWxlbWVudExpc3QpDQotCWFmeF9tc2cgdm9pZCBPblBhaW50KCk7DQotCWFmeF9tc2cgQk9PTCBPbk5jQWN0aXZhdGUoQk9PTCBiQWN0aXZlKTsNCi0JYWZ4X21zZyB2b2lkIE9uU2VsSlNFbGVtZW50KCk7DQotCWFmeF9tc2cgdm9pZCBPbkRibGNsa0pTRWxlbWVudCgpOw0KLQlhZnhfbXNnIHZvaWQgT25EZXN0cm95KCk7DQotCS8vfX1BRlhfTVNHCQ0KLQlERUNMQVJFX01FU1NBR0VfTUFQKCkNCi1wcm90ZWN0ZWQ6DQotCUNJY29uTGlzdEJveAltX0xpc3RCb3g7DQotCUJPT0wJCQltX2JCbG9jazsNCi19Ow0KLQ0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotLy8gQ0pTX0NvbnNvbGVEbGcgttS7sL/yDQotY2xhc3MgQ0pTX0NvbnNvbGVEbGcgOiBwdWJsaWMgQ0pTX1Jlc2l6ZURsZw0KLXsNCi0JREVDTEFSRV9EWU5BTUlDKENKU19Db25zb2xlRGxnKQ0KLQ0KLXB1YmxpYzoNCi0JQ0pTX0NvbnNvbGVEbGcoQ1JlYWRlcl9BcHAqIHBBcHAsIENXbmQqIHBQYXJlbnQpOwkNCi0JdmlydHVhbCB+Q0pTX0NvbnNvbGVEbGcoKTsNCi0NCi0JZW51bSB7IElERCA9IElERF9KU19DT05TT0xFIH07DQotDQotCXZvaWQJCQkJQ3JlYXRlKCk7DQotDQotCXZvaWQJCQkJQXBwZW5kQ29uc29sZVRleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3VGV4dCk7DQotCXZvaWQJCQkJU2V0Q29uc29sZVRleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3VGV4dCk7DQotCUNGWF9XaWRlU3RyaW5nCQlHZXRDb25zb2xlVGV4dCgpIGNvbnN0Ow0KLQlDRlhfV2lkZVN0cmluZwkJR2V0U2NyaXB0VGV4dCgpIGNvbnN0Ow0KLQ0KLQlCT09MCQkJCVJlc2V0RWxlbWVudExpc3QoTFBDV1NUUiBscHN0clJlZik7DQotCUlGWEpTX1J1bnRpbWUqCQlHZXRKU1J1bnRpbWUoKTsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZpcnR1YWwgdm9pZAkJRG9EYXRhRXhjaGFuZ2UoQ0RhdGFFeGNoYW5nZSogcERYKTsJLy8gRERYL0REViDWp7PWDQotDQotcHJvdGVjdGVkOg0KLQl2aXJ0dWFsIEJPT0wJCU9uSW5pdERpYWxvZygpOwkNCi0JdmlydHVhbCB2b2lkCQlPbkNhbmNlbCgpOw0KLQ0KLQl2aXJ0dWFsIEJPT0wJCVByZVRyYW5zbGF0ZU1lc3NhZ2UoTVNHKiBwTXNnKTsNCi0NCi1wcm90ZWN0ZWQ6DQotCS8vIEdlbmVyYXRlZCBtZXNzYWdlIG1hcCBmdW5jdGlvbnMNCi0JLy97e0FGWF9NU0coQ0pTX0NvbnNvbGVEbGcpDQotCWFmeF9tc2cgdm9pZCBPbkJuQ2xpY2tlZENsZWFyKCk7DQotCWFmeF9tc2cgdm9pZCBPbkJuQ2xpY2tlZE9rKCk7DQotCWFmeF9tc2cgdm9pZCBPbkJuQ2xpY2tUaXBzKCk7DQotCWFmeF9tc2cgdm9pZCBPblNpemluZyhVSU5UIG5TaWRlLCBMUFJFQ1QgbHBSZWN0KTsNCi0JYWZ4X21zZyB2b2lkIE9uU2l6ZShVSU5UIG5UeXBlLCBpbnQgY3gsIGludCBjeSk7DQotCWFmeF9tc2cgdm9pZCBPbkdldE1pbk1heEluZm8oTUlOTUFYSU5GTyAqcG1taSk7DQotCWFmeF9tc2cgQk9PTCBPbkVyYXNlQmtnbmQoQ0RDKiBwREMpOw0KLQlhZnhfbXNnIHZvaWQgT25TaG93V2luZG93KEJPT0wgYlNob3csIFVJTlQgblN0YXR1cyk7DQotDQotCWFmeF9tc2cgdm9pZCBPbkxCdXR0b25Eb3duKFVJTlQgbkZsYWdzLCBDUG9pbnQgcG9pbnQpOw0KLQlhZnhfbXNnIHZvaWQgT25DaGFuZ2VTY3JpcHRFZGl0KFdQQVJBTSB3UGFyYW0gLCBMUEFSQU0gbFBhcmFtKTsNCi0JYWZ4X21zZyB2b2lkIE9uTW92ZShpbnQgeCAsIGludCB5KTsNCi0JcHVibGljOg0KLQl2aXJ0dWFsIGludAlEb01vZGFsKCk7CQ0KLQkvL319QUZYX01TRw0KLQlERUNMQVJFX01FU1NBR0VfTUFQKCkNCi0NCi1wdWJsaWM6DQotCUNHV19MaW5lTnVtYmVyRWRpdAkJCW1fZWR0U0M7DQotCUJPT0wJCQkJCQltX2JUaXBzOw0KLQljb25zdCBVSU5UCQkJCQltX3VUZXh0bGltaXRlZDsNCi0JRlhfSEdMT0JBTAkJCQkJbV9oR2xvYmFsOw0KLQlDUmVhZGVyX0FwcCAqCQkJCW1fcEFwcDsNCi0JQ1duZEVsZW1lbnRMaXN0CQkJCW1fV25kRWxlbWVudExpc3Q7DQotfTsNCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9KU19DT05TT0xFX0hfCisjZGVmaW5lIF9KU19DT05TT0xFX0hfCisKKyNpbmNsdWRlICIuLi9yZXMvcmVzb3VyY2UuaCIKKworI2RlZmluZSBXU1RfTk9ORQkJMHgwMAkJCQkJLy8gTm8gc2l6ZSBjaGFuZ2VkCisjZGVmaW5lIFdTVF9MRUZUCQkweDAxCQkJCQkvLyBzaXplIHRvIGxlZnQKKyNkZWZpbmUgV1NUX1RPUAkJCTB4MDIJCQkJCS8vIHNpemUgdG8gdG9wCisjZGVmaW5lIFdTVF9SSUdIVAkJMHgwNAkJCQkJLy8gc2l6ZSB0byByaWdodAorI2RlZmluZSBXU1RfQk9UVE9NCQkweDA4CQkJCQkvLyBzaXplIHRvIGJvdHRvbQorI2RlZmluZSBXU1RfVE9QTEVGVAkJKFdTVF9UT1B8V1NUX0xFRlQpCQkvLyBzaXplIHRvIHRvcCAmIGxlZnQKKyNkZWZpbmUgV1NUX1RPUFJJR0hUCShXU1RfVE9QfFdTVF9SSUdIVCkJCS8vIHNpemUgdG8gdG9wICYgcmlnaHQKKyNkZWZpbmUgV1NUX0JPVFRPTVJJR0hUCShXU1RfQk9UVE9NfFdTVF9SSUdIVCkJLy8gc2l6ZSB0byBib3R0b20gJiByaWdodAorI2RlZmluZSBXU1RfQk9UVE9NTEVGVAkoV1NUX0JPVFRPTXxXU1RfTEVGVCkJLy8gc2l6ZSB0byBib3R0b20gJiByaWdodAorCisjaWZuZGVmIElEQ19ETEdTSVpFQk9YCisjZGVmaW5lIElEQ19ETEdTSVpFQk9YICA1MAorI2VuZGlmCS8qIElEQ19ETEdTSVpFQk9YICovCisKK2VudW0geyBtX2lkU2l6ZUljb24gPSBJRENfRExHU0laRUJPWCB9OworZW51bSB7CQkJCS8vIHBvc3NpYmxlIENvbnRyb2wgcmVTaXplIFR5cGUKKwlDU1RfTk9ORSA9IDAsCisJQ1NUX1JFU0laRSwJCS8vIE5PTU9WRSArIFNJWkUsIGFkZCBhbGwgZGVsdGEtc2l6ZSBvZiBkbGcgdG8gY29udHJvbAorCUNTVF9SRVBPUywJCS8vIE1PVkUoYWJzb2x1dGVseSkgKyBOT1NJWkUsIG1vdmUgY29udHJvbCdzIHBvcyBieSBkZWx0YS1zaXplCisJQ1NUX1JFTEFUSVZFLAkvLyBNT1ZFKHByb3BvcnRpb25hbCkgICsgTk9TSVpFLCBrZWVwIGNvbnRyb2wgYWx3YXlzIGF0IGEgcmVsYXRpdmUgcG9zCisJQ1NUX1pPT00sCQkvLyBNT1ZFICsgU0laRSAoYm90aCBhcmUgYXV0b21hdGljYWxseSBwcm9wb3J0aW9uYWwpCisJQ1NUX0RFTFRBX1pPT00JLy8gTU9WRShwcm9wb3J0aW9uYWwsIHNldCBtYW51YWxseSkgKyBTSVpFKHByb3BvcnRpb25hbCwgc2V0IG1hbnVhbGwpCit9OworCisvLyBjb250YWluZWQgY2xhc3MgdG8gaG9sZCBpdGVtIHN0YXRlCisvLworY2xhc3MgQ0pTX0l0ZW1DdHJsCit7CitwdWJsaWM6CisJVUlOVAltX25JRDsKKwlVSU5UCW1fc3R4TGVmdCAgCSAgIDogNDsJCQkvLyB3aGVuIGxlZnQgcmVzaXppbmcgLi4uCisJVUlOVAltX3N0eFJpZ2h0ICAgICA6IDQ7CQkJLy8gd2hlbiByaWdodCByZXNpemluZyAuLi4KKwlVSU5UCW1fc3R5VG9wICAgCSAgIDogNDsJCQkvLyB3aGVuIHRvcCByZXNpemluZyAuLi4KKwlVSU5UCW1fc3R5Qm90dG9tICAgIDogNDsJCQkvLyB3aGVuIGJvdHRvbSByZXNpemluZyAuLi4KKwlVSU5UCW1fYkZsaWNrZXJGcmVlIDogMTsKKwlVSU5UCW1fYkludmFsaWRhdGUgIDogMTsJCQkvLyBJbnZhbGlkYXRlIGN0cmwncyByZWN0KGVnLiBuby1hdXRvbWF0aWNhbCB1cGRhdGUgZm9yIHN0YXRpYyB3aGVuIHJlc2l6ZSttb3ZlKQorCVVJTlQJbV9yMAkJICAgOiAxNDsKKwlDUmVjdAltX3dSZWN0OworCWRvdWJsZQltX3hSYXRpbywgbV9jeFJhdGlvOworCWRvdWJsZQltX3lSYXRpbywgbV9jeVJhdGlvOworCitwcm90ZWN0ZWQ6CisJdm9pZCBBc3NpZ24oY29uc3QgQ0pTX0l0ZW1DdHJsJiBzcmMpOworCitwdWJsaWM6CisJQ0pTX0l0ZW1DdHJsKCk7CisJQ0pTX0l0ZW1DdHJsKGNvbnN0IENKU19JdGVtQ3RybCYgc3JjKTsKKworCUhEV1AgT25TaXplKEhEV1AgaGR3cCwgaW50IHNpemVUeXBlLCBDUmVjdCAqcG5DbHRSZWN0LCBDUmVjdCAqcG9DbHRSZWN0LCBDUmVjdCAqcFIwLCBDV25kICpwRGxnKTsKKworCUNKU19JdGVtQ3RybCYgb3BlcmF0b3I9KGNvbnN0IENKU19JdGVtQ3RybCYgc3JjKTsKK307CisKK2NsYXNzIENKU19SZXNpemVEbGcgOiBwdWJsaWMgQ0RpYWxvZworeworLy8JREVDTEFSRV9EWU5BTUlDKENKU19SZXNpemVEbGcpCitwdWJsaWM6CisJQ0pTX1Jlc2l6ZURsZyhVSU5UIG5JRCxDV25kICpwUGFyZW50V25kID0gTlVMTCk7CisJdmlydHVhbCB+Q0pTX1Jlc2l6ZURsZygpOworCisKK3B1YmxpYzoKKwlzdGQ6OnZlY3RvcjxDSlNfSXRlbUN0cmw+CW1fSXRlbXM7ICAgICAgICAgICAvLyBhcnJheSBvZiBjb250cm9sbGVkIGl0ZW1zCisJQ1JlY3QJCQkJCW1fY2x0UmVjdCwgbV9jbHRSMDsKKwlpbnQJCQkJCQltX3hNaW4sIG1feU1pbjsKKwlpbnQJCQkJCQltX3hTdCwgIG1feVN0OwkJLy9zdGVwPworCVVJTlQJCQkJCW1fbkRlbGF5U2lkZTsJCS8vZHJhZyBzaWRlIG9mIHdpbmRvdworCUNTdGF0aWMJCQkJCW1fd25kU2l6ZUljb247ICAgICAvLyBzaXplIGljb24gd2luZG93CisKK3Byb3RlY3RlZDoKKwl2b2lkIAkJCQkJQWRkQ29udHJvbCggVUlOVCBuSUQsIGludCB4bCwgaW50IHhyLCBpbnQgeXQsIGludCB5YiwgaW50IGJGbGlja2VyRnJlZSA9IDAsIAorCQkJCQkJCQkJICAgIGRvdWJsZSB4UmF0aW8gPSAtMS4wLCBkb3VibGUgY3hSYXRpbyA9IC0xLjAsCisJCQkJCQkJCQkgICAgZG91YmxlIHlSYXRpbyA9IC0xLjAsIGRvdWJsZSBjeVJhdGlvID0gLTEuMCApOworCXZvaWQgCQkJCQlBbGxvd1NpemluZyhpbnQgeHN0LCBpbnQgeXN0KTsKKwl2b2lkIAkJCQkJSGlkZVNpemVJY29uKHZvaWQpOwkKKwl2aXJ0dWFsIEJPT0wJCQlPbkluaXREaWFsb2coKTsKKworCXZvaWQJCQkJCU9uU2l6aW5nKFVJTlQgblNpZGUsIExQUkVDVCBscFJlY3QpOworCXZvaWQJCQkJCU9uU2l6ZShVSU5UIG5UeXBlLCBpbnQgY3gsIGludCBjeSk7CisJdm9pZAkJCQkJT25HZXRNaW5NYXhJbmZvKE1JTk1BWElORk8gKnBtbWkpOworCUJPT0wJCQkJCU9uRXJhc2VCa2duZChDREMqIHBEQyk7CisKK3B1YmxpYzoKKwlpbnQJCQkJCQlVcGRhdGVDb250cm9sUmVjdChVSU5UIG5JRCwgQ1JlY3QgKnBucik7Cit9OworCisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tQ0ljb25MaXN0Qm94IGZvciBDV25kRWxlbWVudExpc3QtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIENJY29uTGlzdEJveCA6IHB1YmxpYyBDTGlzdEJveAoreworcHVibGljOgorCUNJY29uTGlzdEJveCgpOworCXZpcnR1YWwgfkNJY29uTGlzdEJveCgpOworCitwdWJsaWM6CisJaW50CQkJCUluc2VydFN0cmluZyhpbnQgbkluZGV4LCBMUENXU1RSIGxwc3pJdGVtICwgaW50IG5JbWFnZSk7CisJdmlydHVhbAl2b2lkCVJlc2V0Q29udGVudCgpOworCXZpcnR1YWwgdm9pZAlHZXRUZXh0KGludCBuSW5kZXgsIENTdHJpbmcmIHJTdHJpbmcpOworCisJdmlydHVhbCB2b2lkCURyYXdJdGVtKExQRFJBV0lURU1TVFJVQ1QgbHBEcmF3SXRlbVN0cnVjdCk7CisJdm9pZAkJCU1lYXN1cmVJdGVtKExQTUVBU1VSRUlURU1TVFJVQ1QgbHBNZWFzdXJlSXRlbVN0cnVjdCk7CisJaW50CQkJCUNvbXBhcmVJdGVtKExQQ09NUEFSRUlURU1TVFJVQ1QgbHBDb21wYXJlSXRlbVN0cnVjdCk7CisKK3Byb3RlY3RlZDoKKwkvLyBHZW5lcmF0ZWQgbWVzc2FnZSBtYXAgZnVuY3Rpb25zCisJLy97e0FGWF9NU0coQ0ljb25MaXN0Qm94KQorCWFmeF9tc2cgdm9pZCBPbk1vdXNlTW92ZShVSU5UIG5GbGFncywgQ1BvaW50IHBvaW50KTsKKwkvL319QUZYX01TRwkKKwlERUNMQVJFX01FU1NBR0VfTUFQKCkKKworcHJvdGVjdGVkOgorCXN0cnVjdCBJdGVtRGF0YXMgCisJeworCQlDU3RyaW5nCWNzVGV4dDsKKwkJaW50CQluSW1hZ2U7CisJfTsKK307CisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1DV25kRWxlbWVudExpc3QtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorI2RlZmluZSBJRENfTElTVF9KU19FTEVNRU5UIDEwMDcwCisKKyNkZWZpbmUgRUxFTUVOVF9MSVNUX1dJRFRIIDE0MAorI2RlZmluZSBFTEVNRU5UX0xJU1RfSEVJR0hUIDE4MAorI2RlZmluZSBFTEVNRU5UX0xJU1RfVE9QX09GRlNFVCAxMworCisjZGVmaW5lIEVMRU1FTlRfVFlQRV9OQU1FCTAKKyNkZWZpbmUgRUxFTUVOVF9UWVBFX0NPTlNUCTEKKyNkZWZpbmUgRUxFTUVOVF9UWVBFX0ZVTgkyCisjZGVmaW5lIEVMRU1FTlRfVFlQRV9QUk8JMworCitjbGFzcyBDV25kRWxlbWVudExpc3QgOiBwdWJsaWMgQ1duZAoreworcHVibGljOgorCUNXbmRFbGVtZW50TGlzdCgpOworCXZpcnR1YWwgfkNXbmRFbGVtZW50TGlzdCgpOworCQorcHVibGljOgorCXZpcnR1YWwgdm9pZAlPblNpemUoVUlOVCBuVHlwZSwgaW50IGN4LCBpbnQgY3kpOworCXZpcnR1YWwgQk9PTAlDcmVhdGUoQ1duZCogcFBhcmVudFduZCk7CisJdmlydHVhbCBCT09MCVNob3dXaW5kb3coaW50IG5DbWRTaG93KTsKKwl2b2lkCQkJUmVtb3ZlQWxsRWxlbWVudCgpOworCXZvaWQJCQlTZXRFbGVtZW50TGlzdChMUENXU1RSKiBwRWxlbWVudCwgaW50KiBwVHlwZSAsICBpbnQgaUNvdW50KTsKKwl2b2lkCQkJQWRkRWxlbWVudChDRlhfV2lkZVN0cmluZyBjc1ZhbHVlICwgaW50IG5UeXBlKTsKKwlCT09MCQkJR2V0RWxlbWVudFNlbChDU3RyaW5nICZjc0VsZW1lbnQpOworCUJPT0wJCQlTZWxlY3ROZXh0KCk7CisJQk9PTAkJCVNlbGVjdFByZXZpb3VzKCk7CisJQk9PTAkJCVNlbGVjdEZpcnN0KCk7CisJQk9PTAkJCVNlbGVjdExhc3QoKTsKKwlCT09MCQkJU2VsZWN0TmV4dFBhZ2UoKTsKKwlCT09MCQkJU2VsZWN0UHJldmlvdXNQYWdlKCk7CisJaW50CQkJCUdldExpc3RIZWlnaHQoKTsKKwkKK3Byb3RlY3RlZDoKKwkvLyBHZW5lcmF0ZWQgbWVzc2FnZSBtYXAgZnVuY3Rpb25zCisJLy97e0FGWF9NU0coQ1duZEVsZW1lbnRMaXN0KQorCWFmeF9tc2cgdm9pZCBPblBhaW50KCk7CisJYWZ4X21zZyBCT09MIE9uTmNBY3RpdmF0ZShCT09MIGJBY3RpdmUpOworCWFmeF9tc2cgdm9pZCBPblNlbEpTRWxlbWVudCgpOworCWFmeF9tc2cgdm9pZCBPbkRibGNsa0pTRWxlbWVudCgpOworCWFmeF9tc2cgdm9pZCBPbkRlc3Ryb3koKTsKKwkvL319QUZYX01TRwkKKwlERUNMQVJFX01FU1NBR0VfTUFQKCkKK3Byb3RlY3RlZDoKKwlDSWNvbkxpc3RCb3gJbV9MaXN0Qm94OworCUJPT0wJCQltX2JCbG9jazsKK307CisKKy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisvLyBDSlNfQ29uc29sZURsZyC21Luwv/IKK2NsYXNzIENKU19Db25zb2xlRGxnIDogcHVibGljIENKU19SZXNpemVEbGcKK3sKKwlERUNMQVJFX0RZTkFNSUMoQ0pTX0NvbnNvbGVEbGcpCisKK3B1YmxpYzoKKwlDSlNfQ29uc29sZURsZyhDUmVhZGVyX0FwcCogcEFwcCwgQ1duZCogcFBhcmVudCk7CQorCXZpcnR1YWwgfkNKU19Db25zb2xlRGxnKCk7CisKKwllbnVtIHsgSUREID0gSUREX0pTX0NPTlNPTEUgfTsKKworCXZvaWQJCQkJQ3JlYXRlKCk7CisKKwl2b2lkCQkJCUFwcGVuZENvbnNvbGVUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd1RleHQpOworCXZvaWQJCQkJU2V0Q29uc29sZVRleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3VGV4dCk7CisJQ0ZYX1dpZGVTdHJpbmcJCUdldENvbnNvbGVUZXh0KCkgY29uc3Q7CisJQ0ZYX1dpZGVTdHJpbmcJCUdldFNjcmlwdFRleHQoKSBjb25zdDsKKworCUJPT0wJCQkJUmVzZXRFbGVtZW50TGlzdChMUENXU1RSIGxwc3RyUmVmKTsKKwlJRlhKU19SdW50aW1lKgkJR2V0SlNSdW50aW1lKCk7CisKK3Byb3RlY3RlZDoKKwl2aXJ0dWFsIHZvaWQJCURvRGF0YUV4Y2hhbmdlKENEYXRhRXhjaGFuZ2UqIHBEWCk7CS8vIEREWC9ERFYg1qez1gorCitwcm90ZWN0ZWQ6CisJdmlydHVhbCBCT09MCQlPbkluaXREaWFsb2coKTsJCisJdmlydHVhbCB2b2lkCQlPbkNhbmNlbCgpOworCisJdmlydHVhbCBCT09MCQlQcmVUcmFuc2xhdGVNZXNzYWdlKE1TRyogcE1zZyk7CisKK3Byb3RlY3RlZDoKKwkvLyBHZW5lcmF0ZWQgbWVzc2FnZSBtYXAgZnVuY3Rpb25zCisJLy97e0FGWF9NU0coQ0pTX0NvbnNvbGVEbGcpCisJYWZ4X21zZyB2b2lkIE9uQm5DbGlja2VkQ2xlYXIoKTsKKwlhZnhfbXNnIHZvaWQgT25CbkNsaWNrZWRPaygpOworCWFmeF9tc2cgdm9pZCBPbkJuQ2xpY2tUaXBzKCk7CisJYWZ4X21zZyB2b2lkIE9uU2l6aW5nKFVJTlQgblNpZGUsIExQUkVDVCBscFJlY3QpOworCWFmeF9tc2cgdm9pZCBPblNpemUoVUlOVCBuVHlwZSwgaW50IGN4LCBpbnQgY3kpOworCWFmeF9tc2cgdm9pZCBPbkdldE1pbk1heEluZm8oTUlOTUFYSU5GTyAqcG1taSk7CisJYWZ4X21zZyBCT09MIE9uRXJhc2VCa2duZChDREMqIHBEQyk7CisJYWZ4X21zZyB2b2lkIE9uU2hvd1dpbmRvdyhCT09MIGJTaG93LCBVSU5UIG5TdGF0dXMpOworCisJYWZ4X21zZyB2b2lkIE9uTEJ1dHRvbkRvd24oVUlOVCBuRmxhZ3MsIENQb2ludCBwb2ludCk7CisJYWZ4X21zZyB2b2lkIE9uQ2hhbmdlU2NyaXB0RWRpdChXUEFSQU0gd1BhcmFtICwgTFBBUkFNIGxQYXJhbSk7CisJYWZ4X21zZyB2b2lkIE9uTW92ZShpbnQgeCAsIGludCB5KTsKKwlwdWJsaWM6CisJdmlydHVhbCBpbnQJRG9Nb2RhbCgpOwkKKwkvL319QUZYX01TRworCURFQ0xBUkVfTUVTU0FHRV9NQVAoKQorCitwdWJsaWM6CisJQ0dXX0xpbmVOdW1iZXJFZGl0CQkJbV9lZHRTQzsKKwlCT09MCQkJCQkJbV9iVGlwczsKKwljb25zdCBVSU5UCQkJCQltX3VUZXh0bGltaXRlZDsKKwlGWF9IR0xPQkFMCQkJCQltX2hHbG9iYWw7CisJQ1JlYWRlcl9BcHAgKgkJCQltX3BBcHA7CisJQ1duZEVsZW1lbnRMaXN0CQkJCW1fV25kRWxlbWVudExpc3Q7Cit9OworCiAjZW5kaWYgLy9fSlNfQ09OU09MRV9IXwpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaAppbmRleCAwZTc5MTY5Li44MDY4MDg2IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oCkBAIC0xLDEwMSArMSwxMDEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0pTX0NPTlRFWFRfSF8NCi0jZGVmaW5lIF9KU19DT05URVhUX0hfDQotDQotY2xhc3MgQ0pTX0V2ZW50SGFuZGxlcjsNCi1jbGFzcyBDSlNfUnVudGltZTsNCi0NCi1jbGFzcyBDSlNfQ29udGV4dCA6IHB1YmxpYyBJRlhKU19Db250ZXh0DQotew0KLXB1YmxpYzoNCi0JQ0pTX0NvbnRleHQoQ0pTX1J1bnRpbWUqIHBSdW50aW1lKTsNCi0JdmlydHVhbCB+Q0pTX0NvbnRleHQoKTsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlDb21waWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQsIENGWF9XaWRlU3RyaW5nJiBpbmZvKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCVJ1blNjcmlwdChjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0LCBDRlhfV2lkZVN0cmluZyYgaW5mbyk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJT25BcHBfSW5pdCgpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJT25Eb2NfT3BlbihDUERGU0RLX0RvY3VtZW50KiBwRG9jLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyVGFyZ2V0TmFtZSk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19XaWxsUHJpbnQoQ1BERlNES19Eb2N1bWVudCogcERvYyk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19EaWRQcmludChDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRG9jX1dpbGxTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25Eb2NfRGlkU2F2ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uRG9jX1dpbGxDbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uUGFnZV9PcGVuKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25QYWdlX0Nsb3NlKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25QYWdlX0luVmlldyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uUGFnZV9PdXRWaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpOw0KLQkNCi0JdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfTW91c2VEb3duKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQgKnBUYXJnZXQpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9Nb3VzZUVudGVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQgKnBUYXJnZXQpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9Nb3VzZUV4aXQoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCAqcFRhcmdldCk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX01vdXNlVXAoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCAqcFRhcmdldCk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBWYWx1ZSk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfQ2FsY3VsYXRlKENQREZfRm9ybUZpZWxkKiBwU291cmNlLCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MJiBiUmMpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9Gb3JtYXQoaW50IG5Db21taXRLZXksIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wgYldpbGxDb21taXQpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9LZXlzdHJva2UoaW50IG5Db21taXRLZXksIENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwNCi0JCQkJCQkJCQlGWF9CT09MIGJLZXlEb3duLCBGWF9CT09MIGJNb2RpZmllciwgaW50ICZuU2VsRW5kLGludCAmblNlbFN0YXJ0LCBGWF9CT09MIGJTaGlmdCwNCi0JCQkJCQkJCQlDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0LCANCi0JCQkJCQkJCQlGWF9CT09MIGJGaWVsZEZ1bGwsIEZYX0JPT0wgJmJSYyk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX1ZhbGlkYXRlKENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwgRlhfQk9PTCBiS2V5RG93biwNCi0JCQkJCQkJCQlGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wmIGJSYyk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9Gb2N1cyhGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fQmx1cihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fT3BlbihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fQ2xvc2UoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX01vdXNlRG93bihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fTW91c2VVcChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fTW91c2VFbnRlcihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fTW91c2VFeGl0KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7DQotCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9JblZpZXcoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX091dFZpZXcoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCU9uQm9va21hcmtfTW91c2VVcChDUERGX0Jvb2ttYXJrKiBwQm9va01hcmspOw0KLQl2aXJ0dWFsIHZvaWQJCQkJT25MaW5rX01vdXNlVXAoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbk1lbnVfRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyVGFyZ2V0TmFtZSk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkJhdGNoRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uQ29uc29sZV9FeGVjKCk7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkV4dGVybmFsX0V4ZWMoKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCUVuYWJsZU1lc3NhZ2VCb3goRlhfQk9PTCBiRW5hYmxlKSB7bV9iTXNnQm94RW5hYmxlID0gYkVuYWJsZTt9DQotCUZYX0JPT0wJCQkJCQlJc01zZ0JveEVuYWJsZWQoKSBjb25zdCB7cmV0dXJuIG1fYk1zZ0JveEVuYWJsZTt9DQotDQotcHVibGljOg0KLQlDUERGRG9jX0Vudmlyb25tZW50KgkJCUdldFJlYWRlckFwcCgpOw0KLQlDSlNfUnVudGltZSoJCQkJR2V0SlNSdW50aW1lKCl7cmV0dXJuIG1fcFJ1bnRpbWU7fQ0KLQ0KLQlGWF9CT09MCQkJCQkJRG9Kb2IoaW50IG5Nb2RlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0LCBDRlhfV2lkZVN0cmluZyYgaW5mbyk7DQotDQotCUNKU19FdmVudEhhbmRsZXIqCQkJR2V0RXZlbnRIYW5kbGVyKCl7cmV0dXJuIG1fcEV2ZW50SGFuZGxlcjt9OwkNCi0JQ1BERlNES19Eb2N1bWVudCoJCQlHZXRSZWFkZXJEb2N1bWVudCgpOw0KLQ0KLXByaXZhdGU6DQotCUNKU19SdW50aW1lKgkJCQltX3BSdW50aW1lOwkNCi0JQ0pTX0V2ZW50SGFuZGxlcioJCQltX3BFdmVudEhhbmRsZXI7CQ0KLQ0KLQlGWF9CT09MCQkJCQkJbV9iQnVzeTsJDQotCUZYX0JPT0wJCQkJCQltX2JNc2dCb3hFbmFibGU7DQotfTsNCi0NCi0vLyBzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcgSlNHZXRTdHJpbmdGcm9tSUQoQ0pTX0NvbnRleHQqIHBDb250ZXh0LCBVSU5UIElEKQ0KLS8vIHsNCi0vLyAJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLS8vIA0KLS8vIAlyZXR1cm4gSlNfTG9hZFN0cmluZyhwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCksIElEKTsNCi0vLyB9DQotDQotI2VuZGlmIC8vX0pTX0NPTlRFWFRfSF8NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9KU19DT05URVhUX0hfCisjZGVmaW5lIF9KU19DT05URVhUX0hfCisKK2NsYXNzIENKU19FdmVudEhhbmRsZXI7CitjbGFzcyBDSlNfUnVudGltZTsKKworY2xhc3MgQ0pTX0NvbnRleHQgOiBwdWJsaWMgSUZYSlNfQ29udGV4dAoreworcHVibGljOgorCUNKU19Db250ZXh0KENKU19SdW50aW1lKiBwUnVudGltZSk7CisJdmlydHVhbCB+Q0pTX0NvbnRleHQoKTsKKworcHVibGljOgorCXZpcnR1YWwgRlhfQk9PTAkJCQlDb21waWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQsIENGWF9XaWRlU3RyaW5nJiBpbmZvKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJUnVuU2NyaXB0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQsIENGWF9XaWRlU3RyaW5nJiBpbmZvKTsKKworcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQlPbkFwcF9Jbml0KCk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJT25Eb2NfT3BlbihDUERGU0RLX0RvY3VtZW50KiBwRG9jLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyVGFyZ2V0TmFtZSk7CisJdmlydHVhbCB2b2lkCQkJCU9uRG9jX1dpbGxQcmludChDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25Eb2NfRGlkUHJpbnQoQ1BERlNES19Eb2N1bWVudCogcERvYyk7CisJdmlydHVhbCB2b2lkCQkJCU9uRG9jX1dpbGxTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOworCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19EaWRTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOworCXZpcnR1YWwgdm9pZAkJCQlPbkRvY19XaWxsQ2xvc2UoQ1BERlNES19Eb2N1bWVudCogcERvYyk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJT25QYWdlX09wZW4oQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCk7CisJdmlydHVhbCB2b2lkCQkJCU9uUGFnZV9DbG9zZShDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25QYWdlX0luVmlldyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25QYWdlX091dFZpZXcoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCk7CisJCisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfTW91c2VEb3duKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQgKnBUYXJnZXQpOworCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX01vdXNlRW50ZXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCAqcFRhcmdldCk7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfTW91c2VFeGl0KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQgKnBUYXJnZXQpOworCXZpcnR1YWwgdm9pZAkJCQlPbkZpZWxkX01vdXNlVXAoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCAqcFRhcmdldCk7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfRm9jdXMoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9CbHVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBWYWx1ZSk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9DYWxjdWxhdGUoQ1BERl9Gb3JtRmllbGQqIHBTb3VyY2UsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wmIGJSYyk7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfRm9ybWF0KGludCBuQ29tbWl0S2V5LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0KTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25GaWVsZF9LZXlzdHJva2UoaW50IG5Db21taXRLZXksIENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwKKwkJCQkJCQkJCUZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLCBpbnQgJm5TZWxFbmQsaW50ICZuU2VsU3RhcnQsIEZYX0JPT0wgYlNoaWZ0LAorCQkJCQkJCQkJQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCBiV2lsbENvbW1pdCwgCisJCQkJCQkJCQlGWF9CT09MIGJGaWVsZEZ1bGwsIEZYX0JPT0wgJmJSYyk7CisJdmlydHVhbCB2b2lkCQkJCU9uRmllbGRfVmFsaWRhdGUoQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LCBGWF9CT09MIGJLZXlEb3duLAorCQkJCQkJCQkJRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MJiBiUmMpOworCisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7CisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fT3BlbihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9DbG9zZShGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9Nb3VzZURvd24oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fTW91c2VVcChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9Nb3VzZUVudGVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7CisJdmlydHVhbCB2b2lkCQkJCU9uU2NyZWVuX01vdXNlRXhpdChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCXZpcnR1YWwgdm9pZAkJCQlPblNjcmVlbl9JblZpZXcoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsKKwl2aXJ0dWFsIHZvaWQJCQkJT25TY3JlZW5fT3V0VmlldyhGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCisJdmlydHVhbCB2b2lkCQkJCU9uQm9va21hcmtfTW91c2VVcChDUERGX0Jvb2ttYXJrKiBwQm9va01hcmspOworCXZpcnR1YWwgdm9pZAkJCQlPbkxpbmtfTW91c2VVcChDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KTsKKworCXZpcnR1YWwgdm9pZAkJCQlPbk1lbnVfRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyVGFyZ2V0TmFtZSk7CisJdmlydHVhbCB2b2lkCQkJCU9uQmF0Y2hFeGVjKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpOworCXZpcnR1YWwgdm9pZAkJCQlPbkNvbnNvbGVfRXhlYygpOworCXZpcnR1YWwgdm9pZAkJCQlPbkV4dGVybmFsX0V4ZWMoKTsKKworCXZpcnR1YWwgdm9pZAkJCQlFbmFibGVNZXNzYWdlQm94KEZYX0JPT0wgYkVuYWJsZSkge21fYk1zZ0JveEVuYWJsZSA9IGJFbmFibGU7fQorCUZYX0JPT0wJCQkJCQlJc01zZ0JveEVuYWJsZWQoKSBjb25zdCB7cmV0dXJuIG1fYk1zZ0JveEVuYWJsZTt9CisKK3B1YmxpYzoKKwlDUERGRG9jX0Vudmlyb25tZW50KgkJCUdldFJlYWRlckFwcCgpOworCUNKU19SdW50aW1lKgkJCQlHZXRKU1J1bnRpbWUoKXtyZXR1cm4gbV9wUnVudGltZTt9CisKKwlGWF9CT09MCQkJCQkJRG9Kb2IoaW50IG5Nb2RlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0LCBDRlhfV2lkZVN0cmluZyYgaW5mbyk7CisKKwlDSlNfRXZlbnRIYW5kbGVyKgkJCUdldEV2ZW50SGFuZGxlcigpe3JldHVybiBtX3BFdmVudEhhbmRsZXI7fTsJCisJQ1BERlNES19Eb2N1bWVudCoJCQlHZXRSZWFkZXJEb2N1bWVudCgpOworCitwcml2YXRlOgorCUNKU19SdW50aW1lKgkJCQltX3BSdW50aW1lOwkKKwlDSlNfRXZlbnRIYW5kbGVyKgkJCW1fcEV2ZW50SGFuZGxlcjsJCisKKwlGWF9CT09MCQkJCQkJbV9iQnVzeTsJCisJRlhfQk9PTAkJCQkJCW1fYk1zZ0JveEVuYWJsZTsKK307CisKKy8vIHN0YXRpYyBDRlhfV2lkZVN0cmluZyBKU0dldFN0cmluZ0Zyb21JRChDSlNfQ29udGV4dCogcENvbnRleHQsIFVJTlQgSUQpCisvLyB7CisvLyAJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworLy8gCisvLyAJcmV0dXJuIEpTX0xvYWRTdHJpbmcocENvbnRleHQtPkdldFJlYWRlckFwcCgpLCBJRCk7CisvLyB9CisKKyNlbmRpZiAvL19KU19DT05URVhUX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgKaW5kZXggODFkNDQ1NS4uY2MyMDMzMyAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgKQEAgLTEsNzg1ICsxLDc4NSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfSlNfREVGSU5FX0hfDQotI2RlZmluZSBfSlNfREVGSU5FX0hfDQotDQotdHlwZWRlZiB2ODo6VmFsdWUJCQlKU1ZhbHVlOw0KLXR5cGVkZWYgdjg6OkhhbmRsZTx2ODo6T2JqZWN0PglKU09iamVjdDsNCi10eXBlZGVmIHY4OjpIYW5kbGU8djg6Ok9iamVjdD4JSlNGWE9iamVjdDsNCi10eXBlZGVmIHVuc2lnbmVkCQlKU0Jvb2w7DQotDQotc3RydWN0IEpTQ29uc3RTcGVjDQotew0KLQljb25zdCB3Y2hhcl90KiBwTmFtZTsNCi0JZG91YmxlIG51bWJlcjsNCi0JY29uc3Qgd2NoYXJfdCogc3RyaW5nOw0KLQlGWF9CWVRFIHQ7IC8vMDpkb3VibGUgMTpzdHINCi19Ow0KLQ0KLXN0cnVjdCBKU1Byb3BlcnR5U3BlYw0KLXsNCi0JY29uc3Qgd2NoYXJfdCogcE5hbWU7DQotCXY4OjpBY2Nlc3NvckdldHRlckNhbGxiYWNrIHBQcm9wR2V0Ow0KLQl2ODo6QWNjZXNzb3JTZXR0ZXJDYWxsYmFjayBwUHJvcFB1dDsNCi19Ow0KLQ0KLXN0cnVjdCBKU01ldGhvZFNwZWMNCi17DQotCWNvbnN0IHdjaGFyX3QqIHBOYW1lOw0KLQl2ODo6RnVuY3Rpb25DYWxsYmFjayBwTWV0aG9kQ2FsbDsNCi0JdW5zaWduZWQgblBhcmFtTnVtOw0KLX07DQotDQotdHlwZWRlZiBDRlhfV2lkZVN0cmluZwlKU19FcnJvclN0cmluZzsNCi0NCi0jZGVmaW5lIEpTX1RSVUUJCQkodW5zaWduZWQpMQ0KLSNkZWZpbmUgSlNfRkFMU0UJCSh1bnNpZ25lZCkwDQotDQotDQotI2RlZmluZSBDSlNfUG9pbnRzQXJyYXkJCUNGWF9BcnJheVRlbXBsYXRlPGZsb2F0Pg0KLSNkZWZpbmUgQ0pTX0ludEFycmF5CQlDRlhfQXJyYXlUZW1wbGF0ZTxpbnQ+DQotDQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gUFVCTElDIERFRklORSBTUEVDID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCi0jaWZuZGVmIF9fR05VQ19fDQotI2RlZmluZSBKU19XSURFU1RSSU5HKHdpZGVzdHJpbmcpIEwjd2lkZXN0cmluZw0KLSNlbHNlDQotI2RlZmluZSBKU19XSURFU1RSSU5HKHdpZGVzdHJpbmcpIEwiIiN3aWRlc3RyaW5nDQotI2VuZGlmDQotDQotI2RlZmluZSBPQkpfUFJPUF9QQVJBTVMJCQlJRlhKU19Db250ZXh0KiBjYywgQ0pTX1Byb3BWYWx1ZSYgdnAsIEpTX0Vycm9yU3RyaW5nJiBzRXJyb3INCi0jZGVmaW5lIE9CSl9NRVRIT0RfUEFSQU1TCQlJRlhKU19Db250ZXh0KiBjYywgY29uc3QgQ0pTX1BhcmFtZXRlcnMmIHBhcmFtcywgQ0pTX1ZhbHVlJiB2UmV0LCBKU19FcnJvclN0cmluZyYgc0Vycm9yDQotI2RlZmluZSBCRUdJTl9KU19TVEFUSUNfQ09OU1QoanNfY2xhc3NfbmFtZSkgSlNDb25zdFNwZWMganNfY2xhc3NfbmFtZTo6SlNfQ2xhc3NfQ29uc3RzW10gPSB7DQotI2RlZmluZSBKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKGNvbnN0X25hbWUsIHBWYWx1ZSkge0pTX1dJREVTVFJJTkcoY29uc3RfbmFtZSksIHBWYWx1ZSwgTCIiLCAwfSwNCi0jZGVmaW5lIEpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoY29uc3RfbmFtZSwgcFZhbHVlKSB7SlNfV0lERVNUUklORyhjb25zdF9uYW1lKSwgMCwgSlNfV0lERVNUUklORyhwVmFsdWUpLCAxfSwNCi0jZGVmaW5lIEVORF9KU19TVEFUSUNfQ09OU1QoKSB7MCwgMCwgMCwgMH19Ow0KLQ0KLSNkZWZpbmUgQkVHSU5fSlNfU1RBVElDX1BST1AoanNfY2xhc3NfbmFtZSkgSlNQcm9wZXJ0eVNwZWMganNfY2xhc3NfbmFtZTo6SlNfQ2xhc3NfUHJvcGVydGllc1tdID0gew0KLSNkZWZpbmUgSlNfU1RBVElDX1BST1BfRU5UUlkocHJvcF9uYW1lKSB7SlNfV0lERVNUUklORyhwcm9wX25hbWUpLCBnZXRfIyNwcm9wX25hbWUjI19zdGF0aWMsIHNldF8jI3Byb3BfbmFtZSMjX3N0YXRpY30sDQotI2RlZmluZSBFTkRfSlNfU1RBVElDX1BST1AoKSB7MCwgMCwgMH19Ow0KLQ0KLSNkZWZpbmUgQkVHSU5fSlNfU1RBVElDX01FVEhPRChqc19jbGFzc19uYW1lKSBKU01ldGhvZFNwZWMganNfY2xhc3NfbmFtZTo6SlNfQ2xhc3NfTWV0aG9kc1tdID0gew0KLSNkZWZpbmUgSlNfU1RBVElDX01FVEhPRF9FTlRSWShtZXRob2RfbmFtZSwgbmFyZ3MpIHtKU19XSURFU1RSSU5HKG1ldGhvZF9uYW1lKSwgbWV0aG9kX25hbWUjI19zdGF0aWMsIG5hcmdzfSwNCi0jZGVmaW5lIEVORF9KU19TVEFUSUNfTUVUSE9EKCkgezAsIDAsIDB9fTsNCi0jZGVmaW5lIE1FTUxFQUtDSEVDS18xKCkgKCh2b2lkKTApDQotI2RlZmluZSBNRU1MRUFLQ0hFQ0tfMihtYWluX25hbWUsIHN1Yl9uYW1lKSAoKHZvaWQpMCkNCi0NCi0NCi0vKg0KLSNpZmRlZiBfREVCVUcNCi0jZGVmaW5lIE1FTUxFQUtDSEVDS18xKCkgXA0KLQlfQ3J0TWVtU3RhdGUgc3RhdGUxO1wNCi0JX0NydE1lbUNoZWNrcG9pbnQoJnN0YXRlMSk7DQotDQotI2RlZmluZSBNRU1MRUFLQ0hFQ0tfMihtYWluX25hbWUsc3ViX25hbWUpIFwNCi0JX0NydE1lbVN0YXRlIHN0YXRlMjtcDQotCV9DcnRNZW1DaGVja3BvaW50KCZzdGF0ZTIpO1wNCi0JX0NydE1lbVN0YXRlIGRpZmY7XA0KLQlfQ3J0TWVtRGlmZmVyZW5jZSgmZGlmZiwmc3RhdGUxLCZzdGF0ZTIpO1wNCi0JaWYgKGRpZmYubFNpemVzW19OT1JNQUxfQkxPQ0tdID4gMClcDQotCXtcDQotCQlUUkFDRSgiRGV0ZWN0ZWQgbm9ybWFsIGJsb2NrIG1lbW9yeSBsZWFrcyBpbiBKUyBNb2R1bGUhIFslcy4lc11cbiIsI21haW5fbmFtZSwjc3ViX25hbWUpO1wNCi0JCV9DcnRNZW1EdW1wU3RhdGlzdGljcygmZGlmZik7XA0KLQl9DQotI2Vsc2UNCi0JI2RlZmluZSBNRU1MRUFLQ0hFQ0tfMSgpICgodm9pZCkwKQ0KLQkjZGVmaW5lIE1FTUxFQUtDSEVDS18yKG1haW5fbmFtZSxzdWJfbmFtZSkgKCh2b2lkKTApDQotI2VuZGlmDQotKi8NCi0NCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFBST1AgQ0FMTEJBQ0sgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCi0NCi0jZGVmaW5lIEpTX1NUQVRJQ19QUk9QX0dFVChwcm9wX25hbWUsIGNsYXNzX25hbWUpXA0KLQlzdGF0aWMgdm9pZCBnZXRfIyNwcm9wX25hbWUjI19zdGF0aWMoSlNfUFJPUEdFVF9BUkdTKVwNCi17XA0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IGluZm8uR2V0SXNvbGF0ZSgpO1wNCi0Jdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gaXNvbGF0ZS0+R2V0Q3VycmVudENvbnRleHQoKTtcDQotCXY4OjpMb2NhbDx2ODo6VmFsdWU+IHYgPSBjb250ZXh0LT5HZXRFbWJlZGRlckRhdGEoMSk7XA0KLQlBU1NFUlQoIXYuSXNFbXB0eSgpKTtcDQotCWlmKHYuSXNFbXB0eSgpKSByZXR1cm47XA0KLQl2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD4gZmllbGQgPSB2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD46OkNhc3Qodik7XA0KLQlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IChJRlhKU19SdW50aW1lKilmaWVsZC0+VmFsdWUoKTtcDQotCUlGWEpTX0NvbnRleHQqIGNjID0gcFJ1bnRpbWUtPkdldEN1cnJlbnRDb250ZXh0KCk7XA0KLQlDSlNfUHJvcFZhbHVlIHZhbHVlKGlzb2xhdGUpO1wNCi0JdmFsdWUuU3RhcnRHZXR0aW5nKCk7XA0KLQlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLGluZm8uSG9sZGVyKCkpO1wNCi0JQVNTRVJUKHBKU09iaiAhPSBOVUxMKTtcDQotCWNsYXNzX25hbWUqIHBPYmogPSAoY2xhc3NfbmFtZSopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpO1wNCi0JQVNTRVJUKHBPYmogIT0gTlVMTCk7XA0KLQlKU19FcnJvclN0cmluZyBzRXJyb3I7XA0KLQlGWF9CT09MIGJSZXQgPSBGQUxTRTtcDQotCXRyeVwNCi0Je1wNCi0JCU1FTUxFQUtDSEVDS18xKCk7XA0KLQkJYlJldCA9IHBPYmotPnByb3BfbmFtZShjYywgdmFsdWUsIHNFcnJvcik7XA0KLQkJTUVNTEVBS0NIRUNLXzIoY2xhc3NfbmFtZSwgcHJvcF9uYW1lKTtcDQotCX1cDQotCWNhdGNoICguLi4pXA0KLQl7XA0KLQkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wNCi0JCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNwcm9wX25hbWUpO1wNCi0JCUpTX0Vycm9yKE5VTEwsQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChjYk5hbWUpLCBMIlVua25vd24gZXJyb3IgaXMgY2F0Y2hlZCEiKTtcDQotCQlyZXR1cm4gO1wNCi0JfVwNCi0JaWYgKGJSZXQpXA0KLQl7XA0KLQkJaW5mby5HZXRSZXR1cm5WYWx1ZSgpLlNldCgodjg6OkhhbmRsZTx2ODo6VmFsdWU+KXZhbHVlKTtcDQotCQlyZXR1cm4gO1wNCi0JfVwNCi0JZWxzZVwNCi0Je1wNCi0JQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wNCi0JCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNwcm9wX25hbWUpO1wNCi0JCUpTX0Vycm9yKE5VTEwsQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChjYk5hbWUpLCBzRXJyb3IpO1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLX0NCi0NCi0jZGVmaW5lIEpTX1NUQVRJQ19QUk9QX1NFVChwcm9wX25hbWUsIGNsYXNzX25hbWUpXA0KLQlzdGF0aWMgdm9pZCBzZXRfIyNwcm9wX25hbWUjI19zdGF0aWMoSlNfUFJPUFBVVF9BUkdTKVwNCi17XA0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IGluZm8uR2V0SXNvbGF0ZSgpO1wNCi0Jdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gaXNvbGF0ZS0+R2V0Q3VycmVudENvbnRleHQoKTtcDQotCXY4OjpMb2NhbDx2ODo6VmFsdWU+IHYgPSBjb250ZXh0LT5HZXRFbWJlZGRlckRhdGEoMSk7XA0KLQlBU1NFUlQoIXYuSXNFbXB0eSgpKTtcDQotCWlmKHYuSXNFbXB0eSgpKSByZXR1cm47XA0KLQl2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD4gZmllbGQgPSB2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD46OkNhc3Qodik7XA0KLQlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IChJRlhKU19SdW50aW1lKilmaWVsZC0+VmFsdWUoKTtcDQotCUlGWEpTX0NvbnRleHQqIGNjID0gcFJ1bnRpbWUtPkdldEN1cnJlbnRDb250ZXh0KCk7XA0KLQlDSlNfUHJvcFZhbHVlIHByb3BWYWx1ZShDSlNfVmFsdWUoaXNvbGF0ZSx2YWx1ZSxWVF91bmtub3duKSk7XA0KLQlwcm9wVmFsdWUuU3RhcnRTZXR0aW5nKCk7XA0KLQlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLGluZm8uSG9sZGVyKCkpO1wNCi0JQVNTRVJUKHBKU09iaiAhPSBOVUxMKTtcDQotCWNsYXNzX25hbWUqIHBPYmogPSAoY2xhc3NfbmFtZSopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpO1wNCi0JQVNTRVJUKHBPYmogIT0gTlVMTCk7XA0KLQlKU19FcnJvclN0cmluZyBzRXJyb3I7XA0KLQlGWF9CT09MIGJSZXQgPSBGQUxTRTtcDQotCXRyeVwNCi0Je1wNCi0JCU1FTUxFQUtDSEVDS18xKCk7XA0KLQkJYlJldCA9IHBPYmotPnByb3BfbmFtZShjYywgcHJvcFZhbHVlLCBzRXJyb3IpO1wNCi0JCU1FTUxFQUtDSEVDS18yKGNsYXNzX25hbWUsIHByb3BfbmFtZSk7XA0KLQl9XA0KLQljYXRjaCAoLi4uKVwNCi0Je1wNCi0JCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcDQotCQljYk5hbWUuRm9ybWF0KCIlcy4lcyIsICNjbGFzc19uYW1lLCAjcHJvcF9uYW1lKTtcDQotCQlKU19FcnJvcihOVUxMLENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgTCJVbmtub3duIGVycm9yIGlzIGNhdGNoZWQhIik7XA0KLQkJcmV0dXJuIDtcDQotCX1cDQotCWlmIChiUmV0KVwNCi0Je1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLQllbHNlXA0KLQl7XA0KLQkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wNCi0JCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNwcm9wX25hbWUpO1wNCi0JCUpTX0Vycm9yKE5VTEwsQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChjYk5hbWUpLCBzRXJyb3IpO1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLX0NCi0NCi0jZGVmaW5lIEpTX1NUQVRJQ19QUk9QKHByb3BfbmFtZSwgY2xhc3NfbmFtZSlcDQotSlNfU1RBVElDX1BST1BfR0VUKHByb3BfbmFtZSwgY2xhc3NfbmFtZSk7XA0KLUpTX1NUQVRJQ19QUk9QX1NFVChwcm9wX25hbWUsIGNsYXNzX25hbWUpDQotDQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gTUVUSE9EIENBTExCQUNLID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCi0NCi0jZGVmaW5lIEpTX1NUQVRJQ19NRVRIT0QobWV0aG9kX25hbWUsIGNsYXNzX25hbWUpXA0KLQlzdGF0aWMgdm9pZCBtZXRob2RfbmFtZSMjX3N0YXRpYyhKU19NRVRIT0RfQVJHUylcDQote1wNCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBpbmZvLkdldElzb2xhdGUoKTtcDQotCXY4OjpMb2NhbDx2ODo6Q29udGV4dD4gY29udGV4dCA9IGlzb2xhdGUtPkdldEN1cnJlbnRDb250ZXh0KCk7XA0KLQl2ODo6TG9jYWw8djg6OlZhbHVlPiB2ID0gY29udGV4dC0+R2V0RW1iZWRkZXJEYXRhKDEpO1wNCi0JQVNTRVJUKCF2LklzRW1wdHkoKSk7XA0KLQlpZih2LklzRW1wdHkoKSkgcmV0dXJuO1wNCi0Jdjg6OkhhbmRsZTx2ODo6RXh0ZXJuYWw+IGZpZWxkID0gdjg6OkhhbmRsZTx2ODo6RXh0ZXJuYWw+OjpDYXN0KHYpO1wNCi0JSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSAoSUZYSlNfUnVudGltZSopZmllbGQtPlZhbHVlKCk7XA0KLQlJRlhKU19Db250ZXh0KiBjYyA9IHBSdW50aW1lLT5HZXRDdXJyZW50Q29udGV4dCgpO1wNCi0JQ0pTX1BhcmFtZXRlcnMgcGFyYW1ldGVycztcDQotCWZvciAodW5zaWduZWQgaW50IGkgPSAwOyBpPCh1bnNpZ25lZCBpbnQpaW5mby5MZW5ndGgoKTsgaSsrKVwNCi0gICAge1wNCi0JCXBhcmFtZXRlcnMucHVzaF9iYWNrKENKU19WYWx1ZShpc29sYXRlLCBpbmZvW2ldLCBWVF91bmtub3duKSk7XA0KLQl9XA0KLQlDSlNfVmFsdWUgdmFsdWVSZXMoaXNvbGF0ZSk7XA0KLQlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCAqKUpTX0dldFByaXZhdGUoaXNvbGF0ZSxpbmZvLkhvbGRlcigpKTtcDQotCUFTU0VSVChwSlNPYmogIT0gTlVMTCk7XA0KLQljbGFzc19uYW1lKiBwT2JqID0gKGNsYXNzX25hbWUqKXBKU09iai0+R2V0RW1iZWRPYmplY3QoKTtcDQotCUFTU0VSVChwT2JqICE9IE5VTEwpO1wNCi0JSlNfRXJyb3JTdHJpbmcgc0Vycm9yO1wNCi0JRlhfQk9PTCBiUmV0ID0gRkFMU0U7XA0KLQl0cnlcDQotCXtcDQotCQlNRU1MRUFLQ0hFQ0tfMSgpO1wNCi0JCWJSZXQgPSBwT2JqLT5tZXRob2RfbmFtZShjYywgcGFyYW1ldGVycywgdmFsdWVSZXMsIHNFcnJvcik7XA0KLQkJTUVNTEVBS0NIRUNLXzIoY2xhc3NfbmFtZSwgbWV0aG9kX25hbWUpO1wNCi0JfVwNCi0JY2F0Y2ggKC4uLilcDQotCXtcDQotCQlDRlhfQnl0ZVN0cmluZyBjYk5hbWU7XA0KLQkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgI21ldGhvZF9uYW1lKTtcDQotCQlKU19FcnJvcihOVUxMLCBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNiTmFtZSksIEwiVW5rbm93biBlcnJvciBpcyBjYXRjaGVkISIpO1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLQlpZiAoYlJldClcDQotCXtcDQotCQlpbmZvLkdldFJldHVyblZhbHVlKCkuU2V0KHZhbHVlUmVzLlRvSlNWYWx1ZSgpKTtcDQotCQlyZXR1cm4gO1wNCi0JfVwNCi0JZWxzZVwNCi0Je1wNCi0JCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcDQotCQljYk5hbWUuRm9ybWF0KCIlcy4lcyIsICNjbGFzc19uYW1lLCAjbWV0aG9kX25hbWUpO1wNCi0JCUpTX0Vycm9yKE5VTEwsIENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgc0Vycm9yKTtcDQotCQlyZXR1cm4gO1wNCi0JfVwNCi19DQotDQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBKUyBDTEFTUyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLw0KLQ0KLSNkZWZpbmUgREVDTEFSRV9KU19DTEFTUyhqc19jbGFzc19uYW1lKSBcDQotCXN0YXRpYyBKU0Jvb2wgSlNDb25zdHJ1Y3RvcihJRlhKU19Db250ZXh0KiBjYywgSlNGWE9iamVjdCBvYmosSlNGWE9iamVjdCBnbG9iYWwpO1wNCi0Jc3RhdGljIEpTQm9vbCBKU0Rlc3RydWN0b3IoSlNGWE9iamVjdCBvYmopO1wNCi0Jc3RhdGljIGludCBJbml0KElKU19SdW50aW1lKiBwUnVudGltZSwgRlhKU09CSlRZUEUgZU9ialR5cGUpO1wNCi0Jc3RhdGljIHZvaWQgR2V0Q29uc3RzKEpTQ29uc3RTcGVjKiYgcENvbnN0cywgaW50JiBuU2l6ZSk7XA0KLQlzdGF0aWMgdm9pZCBHZXRQcm9wZXJ0aWVzKEpTUHJvcGVydHlTcGVjKiYgcFByb3BlcnRpZXMsIGludCYgblNpemUpO1wNCi0Jc3RhdGljIHZvaWQgR2V0TWV0aG9kcyhKU01ldGhvZFNwZWMqJiBwTWV0aG9kcywgaW50JiBuU2l6ZSk7XA0KLQlzdGF0aWMgSlNDb25zdFNwZWMgSlNfQ2xhc3NfQ29uc3RzW107XA0KLQlzdGF0aWMgSlNQcm9wZXJ0eVNwZWMgSlNfQ2xhc3NfUHJvcGVydGllc1tdO1wNCi0Jc3RhdGljIEpTTWV0aG9kU3BlYwlKU19DbGFzc19NZXRob2RzW107XA0KLQlzdGF0aWMgY29uc3Qgd2NoYXJfdCogbV9wQ2xhc3NOYW1lDQotDQotI2RlZmluZSBJTVBMRU1FTlRfSlNfQ0xBU1NfUklDSChqc19jbGFzc19uYW1lLCBjbGFzc19hbHRlcm5hdGUsIGNsYXNzX25hbWUpIFwNCi1jb25zdCB3Y2hhcl90KiBqc19jbGFzc19uYW1lOjptX3BDbGFzc05hbWUgPSBKU19XSURFU1RSSU5HKGNsYXNzX25hbWUpO1wNCi1KU0Jvb2wganNfY2xhc3NfbmFtZTo6SlNDb25zdHJ1Y3RvcihJRlhKU19Db250ZXh0KiBjYywgSlNGWE9iamVjdCBvYmosIEpTRlhPYmplY3QgZ2xvYmFsKVwNCi17XA0KLQlDSlNfT2JqZWN0KiBwT2JqID0gRlhfTkVXIGpzX2NsYXNzX25hbWUob2JqKTtcDQotCXBPYmotPlNldEVtYmVkT2JqZWN0KEZYX05FVyBjbGFzc19hbHRlcm5hdGUocE9iaikpO1wNCi0JSlNfU2V0UHJpdmF0ZShOVUxMLG9iaiwodm9pZCopcE9iaik7IFwNCi0JcE9iai0+SW5pdEluc3RhbmNlKGNjKTtcDQotCXJldHVybiBKU19UUlVFO1wNCi19XA0KLVwNCi1KU0Jvb2wganNfY2xhc3NfbmFtZTo6SlNEZXN0cnVjdG9yKEpTRlhPYmplY3Qgb2JqKSBcDQote1wNCi0JanNfY2xhc3NfbmFtZSogcE9iaiA9IChqc19jbGFzc19uYW1lKilKU19HZXRQcml2YXRlKE5VTEwsb2JqKTtcDQotCUFTU0VSVChwT2JqICE9IE5VTEwpO1wNCi0JcE9iai0+RXhpdEluc3RhbmNlKCk7XA0KLQlkZWxldGUgcE9iajtcDQotCXJldHVybiBKU19UUlVFO1wNCi19XA0KLVwNCi1pbnQganNfY2xhc3NfbmFtZTo6SW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUsIEZYSlNPQkpUWVBFIGVPYmpUeXBlKVwNCi17XA0KLQlpbnQgbk9iakRlZm5JRCA9IEpTX0RlZmluZU9iaihwUnVudGltZSwganNfY2xhc3NfbmFtZTo6bV9wQ2xhc3NOYW1lLCBlT2JqVHlwZSwgSlNDb25zdHJ1Y3RvciwgSlNEZXN0cnVjdG9yLCAwKTtcDQotCWlmIChuT2JqRGVmbklEID49IDApXA0KLQl7XA0KLQkJZm9yIChpbnQgaj0wLCBzemo9c2l6ZW9mKEpTX0NsYXNzX1Byb3BlcnRpZXMpL3NpemVvZihKU1Byb3BlcnR5U3BlYyktMTsgajxzemo7IGorKylcDQotCQl7XA0KLQkJCWlmIChKU19EZWZpbmVPYmpQcm9wZXJ0eShwUnVudGltZSwgbk9iakRlZm5JRCwgSlNfQ2xhc3NfUHJvcGVydGllc1tqXS5wTmFtZSwgSlNfQ2xhc3NfUHJvcGVydGllc1tqXS5wUHJvcEdldCwgSlNfQ2xhc3NfUHJvcGVydGllc1tqXS5wUHJvcFB1dCkgPCAwKSByZXR1cm4gLTE7XA0KLQkJfVwNCi0JCWZvciAoaW50IGs9MCwgc3prPXNpemVvZihKU19DbGFzc19NZXRob2RzKS9zaXplb2YoSlNNZXRob2RTcGVjKS0xOyBrPHN6azsgaysrKVwNCi0JCXtcDQotCQkJaWYgKEpTX0RlZmluZU9iak1ldGhvZChwUnVudGltZSwgbk9iakRlZm5JRCxKU19DbGFzc19NZXRob2RzW2tdLnBOYW1lLCBKU19DbGFzc19NZXRob2RzW2tdLnBNZXRob2RDYWxsLCBKU19DbGFzc19NZXRob2RzW2tdLm5QYXJhbU51bSkgPCAwKSByZXR1cm4gLTE7XA0KLQkJfVwNCi0JCXJldHVybiBuT2JqRGVmbklEO1wNCi0JfVwNCi0JcmV0dXJuIC0xO1wNCi19XA0KLXZvaWQganNfY2xhc3NfbmFtZTo6R2V0Q29uc3RzKEpTQ29uc3RTcGVjKiYgcENvbnN0cywgaW50JiBuU2l6ZSlcDQote1wNCi0JcENvbnN0cyA9IEpTX0NsYXNzX0NvbnN0cztcDQotCW5TaXplID0gc2l6ZW9mKEpTX0NsYXNzX0NvbnN0cykgLyBzaXplb2YoSlNDb25zdFNwZWMpIC0gMTtcDQotfVwNCi12b2lkIGpzX2NsYXNzX25hbWU6OkdldFByb3BlcnRpZXMoSlNQcm9wZXJ0eVNwZWMqJiBwUHJvcGVydGllcywgaW50JiBuU2l6ZSlcDQote1wNCi0JcFByb3BlcnRpZXMgPSBKU19DbGFzc19Qcm9wZXJ0aWVzO1wNCi0JblNpemUgPSBzaXplb2YoSlNfQ2xhc3NfUHJvcGVydGllcykgLyBzaXplb2YoSlNQcm9wZXJ0eVNwZWMpIC0gMTtcDQotfVwNCi12b2lkIGpzX2NsYXNzX25hbWU6OkdldE1ldGhvZHMoSlNNZXRob2RTcGVjKiYgcE1ldGhvZHMsIGludCYgblNpemUpXA0KLXtcDQotCXBNZXRob2RzID0gSlNfQ2xhc3NfTWV0aG9kcztcDQotCW5TaXplID0gc2l6ZW9mKEpTX0NsYXNzX01ldGhvZHMpIC8gc2l6ZW9mKEpTTWV0aG9kU3BlYykgLSAxO1wNCi19DQotDQotI2RlZmluZSBJTVBMRU1FTlRfSlNfQ0xBU1MoanNfY2xhc3NfbmFtZSwgY2xhc3NfbmFtZSkgSU1QTEVNRU5UX0pTX0NMQVNTX1JJQ0goanNfY2xhc3NfbmFtZSwgY2xhc3NfbmFtZSwgY2xhc3NfbmFtZSkNCi0NCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IENPTlNUIENMQVNTID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovDQotDQotI2RlZmluZSBERUNMQVJFX0pTX0NMQVNTX0NPTlNUKCkgXA0KLQlzdGF0aWMgaW50IEluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lLCBGWEpTT0JKVFlQRSBlT2JqVHlwZSk7XA0KLQlzdGF0aWMgdm9pZCBHZXRDb25zdHMoSlNDb25zdFNwZWMqJiBwQ29uc3RzLCBpbnQmIG5TaXplKTtcDQotCXN0YXRpYyBKU0NvbnN0U3BlYyBKU19DbGFzc19Db25zdHNbXTtcDQotCXN0YXRpYyBjb25zdCB3Y2hhcl90KiBtX3BDbGFzc05hbWUNCi0NCi0jZGVmaW5lIElNUExFTUVOVF9KU19DTEFTU19DT05TVChqc19jbGFzc19uYW1lLCBjbGFzc19uYW1lKSBcDQotY29uc3Qgd2NoYXJfdCoganNfY2xhc3NfbmFtZTo6bV9wQ2xhc3NOYW1lID0gSlNfV0lERVNUUklORyhjbGFzc19uYW1lKTtcDQotaW50IGpzX2NsYXNzX25hbWU6OkluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lLCBGWEpTT0JKVFlQRSBlT2JqVHlwZSlcDQote1wNCi0JaW50IG5PYmpEZWZuSUQgPSBKU19EZWZpbmVPYmoocFJ1bnRpbWUsIGpzX2NsYXNzX25hbWU6Om1fcENsYXNzTmFtZSwgZU9ialR5cGUsIE5VTEwsIE5VTEwsIDApO1wNCi0JaWYgKG5PYmpEZWZuSUQgPj0wKVwNCi0Je1wNCi0JCWZvciAoaW50IGk9MCwgc3o9c2l6ZW9mKEpTX0NsYXNzX0NvbnN0cykvc2l6ZW9mKEpTQ29uc3RTcGVjKS0xOyBpPHN6OyBpKyspXA0KLQkJe1wNCi0JCQlpZiAoSlNfQ2xhc3NfQ29uc3RzW2ldLnQgPT0gMClcDQotCQkJe1wNCi0JCQkJaWYgKEpTX0RlZmluZU9iakNvbnN0KHBSdW50aW1lLCBuT2JqRGVmbklELCBKU19DbGFzc19Db25zdHNbaV0ucE5hbWUsIEpTX05ld051bWJlcihwUnVudGltZSxKU19DbGFzc19Db25zdHNbaV0ubnVtYmVyKSkgPCAwKSByZXR1cm4gLTE7XA0KLQkJCX1cDQotCQkJZWxzZVwNCi0JCQl7XA0KLQkJCWlmIChKU19EZWZpbmVPYmpDb25zdChwUnVudGltZSwgbk9iakRlZm5JRCwgSlNfQ2xhc3NfQ29uc3RzW2ldLnBOYW1lLCBKU19OZXdTdHJpbmcocFJ1bnRpbWUsSlNfQ2xhc3NfQ29uc3RzW2ldLnN0cmluZykpIDwgMCkgcmV0dXJuIC0xO1wNCi0JCQl9XA0KLQkJfVwNCi0JCXJldHVybiBuT2JqRGVmbklEO1wNCi0JfVwNCi0JcmV0dXJuIC0xO1wNCi19XA0KLXZvaWQganNfY2xhc3NfbmFtZTo6R2V0Q29uc3RzKEpTQ29uc3RTcGVjKiYgcENvbnN0cywgaW50JiBuU2l6ZSlcDQote1wNCi0JcENvbnN0cyA9IEpTX0NsYXNzX0NvbnN0cztcDQotCW5TaXplID0gc2l6ZW9mKEpTX0NsYXNzX0NvbnN0cykvc2l6ZW9mKEpTQ29uc3RTcGVjKS0xO1wNCi19DQotDQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTUEVDSUFMIEpTIENMQVNTID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovDQotDQotI2RlZmluZSBERUNMQVJFX1NQRUNJQUxfSlNfQ0xBU1MoanNfY2xhc3NfbmFtZSkgXA0KLQlzdGF0aWMgSlNCb29sIEpTQ29uc3RydWN0b3IoSUZYSlNfQ29udGV4dCogY2MsIEpTRlhPYmplY3Qgb2JqLCBKU0ZYT2JqZWN0IGdsb2JhbCk7XA0KLQlzdGF0aWMgSlNCb29sIEpTRGVzdHJ1Y3RvcihKU0ZYT2JqZWN0IG9iaik7XA0KLQlzdGF0aWMgdm9pZCBHZXRDb25zdHMoSlNDb25zdFNwZWMqJiBwQ29uc3RzLCBpbnQmIG5TaXplKTtcDQotCXN0YXRpYyB2b2lkIEdldFByb3BlcnRpZXMoSlNQcm9wZXJ0eVNwZWMqJiBwUHJvcGVydGllcywgaW50JiBuU2l6ZSk7XA0KLQlzdGF0aWMgdm9pZCBHZXRNZXRob2RzKEpTTWV0aG9kU3BlYyomIHBNZXRob2RzLCBpbnQmIG5TaXplKTtcDQotCXN0YXRpYyBKU0NvbnN0U3BlYyBKU19DbGFzc19Db25zdHNbXTtcDQotCXN0YXRpYyBKU1Byb3BlcnR5U3BlYyBKU19DbGFzc19Qcm9wZXJ0aWVzW107XA0KLQlzdGF0aWMgSlNNZXRob2RTcGVjCUpTX0NsYXNzX01ldGhvZHNbXTtcDQotCXN0YXRpYyBpbnQgSW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUsIEZYSlNPQkpUWVBFIGVPYmpUeXBlKTtcDQotCXN0YXRpYyBjb25zdCB3Y2hhcl90KiBtX3BDbGFzc05hbWU7XA0KLQlzdGF0aWMgdm9pZCBxdWVyeXByb3BfIyNqc19jbGFzc19uYW1lIyNfc3RhdGljKEpTX1BST1BRVUVSWV9BUkdTKTtcDQotCXN0YXRpYyB2b2lkIGdldHByb3BfIyNqc19jbGFzc19uYW1lIyNfc3RhdGljKEpTX05BTUVEX1BST1BHRVRfQVJHUyk7XA0KLQlzdGF0aWMgdm9pZCBwdXRwcm9wXyMjanNfY2xhc3NfbmFtZSMjX3N0YXRpYyhKU19OQU1FRF9QUk9QUFVUX0FSR1MpO1wNCi0Jc3RhdGljIHZvaWQgZGVscHJvcF8jI2pzX2NsYXNzX25hbWUjI19zdGF0aWMoSlNfUFJPUERFTF9BUkdTKQ0KLQ0KLSNkZWZpbmUgSU1QTEVNRU5UX1NQRUNJQUxfSlNfQ0xBU1MoanNfY2xhc3NfbmFtZSwgY2xhc3NfYWx0ZXJuYXRlLCBjbGFzc19uYW1lKSBcDQotY29uc3Qgd2NoYXJfdCAqIGpzX2NsYXNzX25hbWU6Om1fcENsYXNzTmFtZSA9IEpTX1dJREVTVFJJTkcoY2xhc3NfbmFtZSk7XA0KLQl2b2lkIGpzX2NsYXNzX25hbWU6OnF1ZXJ5cHJvcF8jI2pzX2NsYXNzX25hbWUjI19zdGF0aWMoSlNfUFJPUFFVRVJZX0FSR1MpXA0KLXtcDQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gaW5mby5HZXRJc29sYXRlKCk7XA0KLQl2ODo6U3RyaW5nOjpVdGY4VmFsdWUgdXRmOF92YWx1ZShwcm9wZXJ0eSk7XA0KLQlDRlhfV2lkZVN0cmluZyBwcm9wbmFtZSA9IENGWF9XaWRlU3RyaW5nOjpGcm9tVVRGOCgqdXRmOF92YWx1ZSwgdXRmOF92YWx1ZS5sZW5ndGgoKSk7XA0KLQlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLGluZm8uSG9sZGVyKCkpO1wNCi0JQVNTRVJUKHBKU09iaiAhPSBOVUxMKTtcDQotCWNsYXNzX2FsdGVybmF0ZSogcE9iaiA9IChjbGFzc19hbHRlcm5hdGUqKXBKU09iai0+R2V0RW1iZWRPYmplY3QoKTtcDQotCUFTU0VSVChwT2JqICE9IE5VTEwpO1wNCi0JRlhfQk9PTCBiUmV0ID0gRkFMU0U7XA0KLQl0cnlcDQotCXtcDQotCQlNRU1MRUFLQ0hFQ0tfMSgpO1wNCi0JCWJSZXQgPSBwT2JqLT5RdWVyeVByb3BlcnR5KChGWF9MUENXU1RSKXByb3BuYW1lKTtcDQotCQlNRU1MRUFLQ0hFQ0tfMihjbGFzc19uYW1lLCAoRlhfTFBDV1NUUilwcm9wX25hbWUpO1wNCi0JfVwNCi0JY2F0Y2ggKC4uLilcDQotCXtcDQotCQlyZXR1cm4gO1wNCi0JfVwNCi0JaWYgKGJSZXQpXA0KLQl7XA0KLQkJaW5mby5HZXRSZXR1cm5WYWx1ZSgpLlNldCgweDAwNCk7XA0KLQkJcmV0dXJuIDtcDQotCX1cDQotCWVsc2VcDQotCXtcDQotCQlpbmZvLkdldFJldHVyblZhbHVlKCkuU2V0KDApO1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLQlyZXR1cm4gO1wNCi19XA0KLQl2b2lkIGpzX2NsYXNzX25hbWU6OmdldHByb3BfIyNqc19jbGFzc19uYW1lIyNfc3RhdGljKEpTX05BTUVEX1BST1BHRVRfQVJHUylcDQote1wNCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBpbmZvLkdldElzb2xhdGUoKTtcDQotCXY4OjpMb2NhbDx2ODo6Q29udGV4dD4gY29udGV4dCA9IGlzb2xhdGUtPkdldEN1cnJlbnRDb250ZXh0KCk7XA0KLQl2ODo6TG9jYWw8djg6OlZhbHVlPiB2ID0gY29udGV4dC0+R2V0RW1iZWRkZXJEYXRhKDEpO1wNCi0JQVNTRVJUKCF2LklzRW1wdHkoKSk7XA0KLQlpZih2LklzRW1wdHkoKSkgcmV0dXJuO1wNCi0Jdjg6OkhhbmRsZTx2ODo6RXh0ZXJuYWw+IGZpZWxkID0gdjg6OkhhbmRsZTx2ODo6RXh0ZXJuYWw+OjpDYXN0KHYpO1wNCi0JSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSAoSUZYSlNfUnVudGltZSopZmllbGQtPlZhbHVlKCk7XA0KLQlJRlhKU19Db250ZXh0KiBjYyA9IHBSdW50aW1lLT5HZXRDdXJyZW50Q29udGV4dCgpO1wNCi0Jdjg6OlN0cmluZzo6VXRmOFZhbHVlIHV0ZjhfdmFsdWUocHJvcGVydHkpO1wNCi0JQ0ZYX1dpZGVTdHJpbmcgcHJvcG5hbWUgPSBDRlhfV2lkZVN0cmluZzo6RnJvbVVURjgoKnV0ZjhfdmFsdWUsIHV0ZjhfdmFsdWUubGVuZ3RoKCkpO1wNCi0JQ0pTX1Byb3BWYWx1ZSB2YWx1ZShpc29sYXRlKTtcDQotCXZhbHVlLlN0YXJ0R2V0dGluZygpO1wNCi0JQ0pTX09iamVjdCogcEpTT2JqID0gKENKU19PYmplY3QqKUpTX0dldFByaXZhdGUoaXNvbGF0ZSxpbmZvLkhvbGRlcigpKTtcDQotCUFTU0VSVChwSlNPYmogIT0gTlVMTCk7XA0KLQljbGFzc19hbHRlcm5hdGUqIHBPYmogPSAoY2xhc3NfYWx0ZXJuYXRlKilwSlNPYmotPkdldEVtYmVkT2JqZWN0KCk7XA0KLQlBU1NFUlQocE9iaiAhPSBOVUxMKTtcDQotCUpTX0Vycm9yU3RyaW5nIHNFcnJvcjtcDQotCUZYX0JPT0wgYlJldCA9IEZBTFNFO1wNCi0JdHJ5XA0KLQl7XA0KLQkJTUVNTEVBS0NIRUNLXzEoKTtcDQotCQliUmV0ID0gcE9iai0+RG9Qcm9wZXJ0eShjYywgKEZYX0xQQ1dTVFIpcHJvcG5hbWUsIHZhbHVlLCBzRXJyb3IpO1wNCi0JCU1FTUxFQUtDSEVDS18yKGNsYXNzX25hbWUsIEwiR2V0UHJvcGVydHkiKTtcDQotCX1cDQotCWNhdGNoICguLi4pXA0KLQl7XA0KLQkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wNCi0JCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsIEwiR2V0UHJvcGVydHkiKTtcDQotCQlKU19FcnJvcihOVUxMLENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgTCJVbmtub3duIGVycm9yIGlzIGNhdGNoZWQhIik7XA0KLQkJcmV0dXJuIDtcDQotCX1cDQotCWlmIChiUmV0KVwNCi0Je1wNCi0JCWluZm8uR2V0UmV0dXJuVmFsdWUoKS5TZXQoKHY4OjpIYW5kbGU8djg6OlZhbHVlPil2YWx1ZSk7XA0KLQkJcmV0dXJuIDtcDQotCX1cDQotCWVsc2VcDQotCXtcDQotCQlDRlhfQnl0ZVN0cmluZyBjYk5hbWU7XA0KLQkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgTCJHZXRQcm9wZXJ0eSIpO1wNCi0JCUpTX0Vycm9yKE5VTEwsQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChjYk5hbWUpLCBzRXJyb3IpO1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLQlKU19FcnJvcihOVUxMLEwiR2V0UHJvcGVydHkiLCBMIkVtYmVkZWQgb2JqZWN0IG5vdCBmb3VuZCEiKTtcDQotCXJldHVybiA7XA0KLX1cDQotCXZvaWQganNfY2xhc3NfbmFtZTo6cHV0cHJvcF8jI2pzX2NsYXNzX25hbWUjI19zdGF0aWMoSlNfTkFNRURfUFJPUFBVVF9BUkdTKVwNCi17XA0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IGluZm8uR2V0SXNvbGF0ZSgpO1wNCi0Jdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gaXNvbGF0ZS0+R2V0Q3VycmVudENvbnRleHQoKTtcDQotCXY4OjpMb2NhbDx2ODo6VmFsdWU+IHYgPSBjb250ZXh0LT5HZXRFbWJlZGRlckRhdGEoMSk7XA0KLQlBU1NFUlQoIXYuSXNFbXB0eSgpKTtcDQotCWlmKHYuSXNFbXB0eSgpKSByZXR1cm47XA0KLQl2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD4gZmllbGQgPSB2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD46OkNhc3Qodik7XA0KLQlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IChJRlhKU19SdW50aW1lKilmaWVsZC0+VmFsdWUoKTtcDQotCUlGWEpTX0NvbnRleHQqIGNjID0gcFJ1bnRpbWUtPkdldEN1cnJlbnRDb250ZXh0KCk7XA0KLQl2ODo6U3RyaW5nOjpVdGY4VmFsdWUgdXRmOF92YWx1ZShwcm9wZXJ0eSk7XA0KLQlDRlhfV2lkZVN0cmluZyBwcm9wbmFtZSA9IENGWF9XaWRlU3RyaW5nOjpGcm9tVVRGOCgqdXRmOF92YWx1ZSwgdXRmOF92YWx1ZS5sZW5ndGgoKSk7XA0KLQlDSlNfUHJvcFZhbHVlIFByb3BWYWx1ZShDSlNfVmFsdWUoaXNvbGF0ZSx2YWx1ZSxWVF91bmtub3duKSk7XA0KLQlQcm9wVmFsdWUuU3RhcnRTZXR0aW5nKCk7XA0KLQlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLGluZm8uSG9sZGVyKCkpO1wNCi0JaWYoIXBKU09iaikgcmV0dXJuO1wNCi0JY2xhc3NfYWx0ZXJuYXRlKiBwT2JqID0gKGNsYXNzX2FsdGVybmF0ZSopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpO1wNCi0JQVNTRVJUKHBPYmogIT0gTlVMTCk7XA0KLQlKU19FcnJvclN0cmluZyBzRXJyb3I7XA0KLQlGWF9CT09MIGJSZXQgPSBGQUxTRTtcDQotCXRyeVwNCi0Je1wNCi0JCU1FTUxFQUtDSEVDS18xKCk7XA0KLQkJYlJldCA9IHBPYmotPkRvUHJvcGVydHkoY2MsIChGWF9MUENXU1RSKXByb3BuYW1lLCBQcm9wVmFsdWUsIHNFcnJvcik7XA0KLQkJTUVNTEVBS0NIRUNLXzIoY2xhc3NfbmFtZSxMIlB1dFByb3BlcnR5Iik7XA0KLQl9XA0KLQljYXRjaCAoLi4uKVwNCi0Je1wNCi0JCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcDQotCQljYk5hbWUuRm9ybWF0KCIlcy4lcyIsICNjbGFzc19uYW1lLCAiUHV0UHJvcGVydHkiKTtcDQotCQlKU19FcnJvcihOVUxMLENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgTCJVbmtub3duIGVycm9yIGlzIGNhdGNoZWQhIik7XA0KLQkJcmV0dXJuIDtcDQotCX1cDQotCWlmIChiUmV0KVwNCi0Je1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLQllbHNlXA0KLQl7XA0KLQkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wNCi0JCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICJQdXRQcm9wZXJ0eSIpO1wNCi0JCUpTX0Vycm9yKE5VTEwsQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChjYk5hbWUpLCBzRXJyb3IpO1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLQlKU19FcnJvcihOVUxMLEwiUHV0UHJvcGVydHkiLCBMIkVtYmVkZWQgb2JqZWN0IG5vdCBmb3VuZCEiKTtcDQotCXJldHVybiA7XA0KLX1cDQotCXZvaWQganNfY2xhc3NfbmFtZTo6ZGVscHJvcF8jI2pzX2NsYXNzX25hbWUjI19zdGF0aWMoSlNfUFJPUERFTF9BUkdTKVwNCi17XA0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IGluZm8uR2V0SXNvbGF0ZSgpO1wNCi0Jdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gaXNvbGF0ZS0+R2V0Q3VycmVudENvbnRleHQoKTtcDQotCXY4OjpMb2NhbDx2ODo6VmFsdWU+IHYgPSBjb250ZXh0LT5HZXRFbWJlZGRlckRhdGEoMSk7XA0KLQlBU1NFUlQoIXYuSXNFbXB0eSgpKTtcDQotCWlmKHYuSXNFbXB0eSgpKSByZXR1cm47XA0KLQl2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD4gZmllbGQgPSB2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD46OkNhc3Qodik7XA0KLQlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IChJRlhKU19SdW50aW1lKilmaWVsZC0+VmFsdWUoKTtcDQotCUlGWEpTX0NvbnRleHQqIGNjID0gcFJ1bnRpbWUtPkdldEN1cnJlbnRDb250ZXh0KCk7XA0KLQl2ODo6U3RyaW5nOjpVdGY4VmFsdWUgdXRmOF92YWx1ZShwcm9wZXJ0eSk7XA0KLQlDRlhfV2lkZVN0cmluZyBwcm9wbmFtZSA9IENGWF9XaWRlU3RyaW5nOjpGcm9tVVRGOCgqdXRmOF92YWx1ZSwgdXRmOF92YWx1ZS5sZW5ndGgoKSk7XA0KLQlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLGluZm8uSG9sZGVyKCkpO1wNCi0JQVNTRVJUKHBKU09iaiAhPSBOVUxMKTtcDQotCWNsYXNzX2FsdGVybmF0ZSogcE9iaiA9IChjbGFzc19hbHRlcm5hdGUqKXBKU09iai0+R2V0RW1iZWRPYmplY3QoKTtcDQotCUFTU0VSVChwT2JqICE9IE5VTEwpO1wNCi0JSlNfRXJyb3JTdHJpbmcgc0Vycm9yO1wNCi0JRlhfQk9PTCBiUmV0ID0gRkFMU0U7XA0KLQl0cnlcDQotCXtcDQotCQlNRU1MRUFLQ0hFQ0tfMSgpO1wNCi0JCWJSZXQgPSBwT2JqLT5EZWxQcm9wZXJ0eShjYywgKEZYX0xQQ1dTVFIpcHJvcG5hbWUsIHNFcnJvcik7XA0KLQkJTUVNTEVBS0NIRUNLXzIoY2xhc3NfbmFtZSxMIkRlbFByb3BlcnR5Iik7XA0KLQl9XA0KLQljYXRjaCAoLi4uKVwNCi0Je1wNCi0JCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcDQotCQljYk5hbWUuRm9ybWF0KCIlcy4lcyIsICNjbGFzc19uYW1lLCAiRGVsUHJvcGVydHkiKTtcDQotCQlyZXR1cm4gO1wNCi0JfVwNCi0JaWYgKGJSZXQpXA0KLQl7XA0KLQkJcmV0dXJuIDtcDQotCX1cDQotCWVsc2VcDQotCXtcDQotCQlDRlhfQnl0ZVN0cmluZyBjYk5hbWU7XA0KLQkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgIkRlbFByb3BlcnR5Iik7XA0KLQkJcmV0dXJuIDtcDQotCX1cDQotCXJldHVybiA7XA0KLX1cDQotSlNCb29sIGpzX2NsYXNzX25hbWU6OkpTQ29uc3RydWN0b3IoSUZYSlNfQ29udGV4dCogY2MsIEpTRlhPYmplY3QgIG9iaixKU0ZYT2JqZWN0ICBnbG9iYWwpXA0KLXtcDQotCUNKU19PYmplY3QqIHBPYmogPSBGWF9ORVcganNfY2xhc3NfbmFtZShvYmopO1wNCi0JcE9iai0+U2V0RW1iZWRPYmplY3QoRlhfTkVXIGNsYXNzX2FsdGVybmF0ZShwT2JqKSk7XA0KLQlKU19TZXRQcml2YXRlKE5VTEwsb2JqLCAodm9pZCopcE9iaik7IFwNCi0JcE9iai0+SW5pdEluc3RhbmNlKGNjKTtcDQotCXJldHVybiBKU19UUlVFO1wNCi19XA0KLVwNCi1KU0Jvb2wganNfY2xhc3NfbmFtZTo6SlNEZXN0cnVjdG9yKEpTRlhPYmplY3Qgb2JqKSBcDQote1wNCi0JanNfY2xhc3NfbmFtZSogcE9iaiA9IChqc19jbGFzc19uYW1lKilKU19HZXRQcml2YXRlKE5VTEwsb2JqKTtcDQotCUFTU0VSVChwT2JqICE9IE5VTEwpO1wNCi0JcE9iai0+RXhpdEluc3RhbmNlKCk7XA0KLQlkZWxldGUgcE9iajtcDQotCXJldHVybiBKU19UUlVFO1wNCi19XA0KLVwNCi1pbnQganNfY2xhc3NfbmFtZTo6SW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUsIEZYSlNPQkpUWVBFIGVPYmpUeXBlKVwNCi17XA0KLVwNCi0JaW50IG5PYmpEZWZuSUQgPSBKU19EZWZpbmVPYmoocFJ1bnRpbWUsIGpzX2NsYXNzX25hbWU6Om1fcENsYXNzTmFtZSwgZU9ialR5cGUsIEpTQ29uc3RydWN0b3IsIEpTRGVzdHJ1Y3RvciwgMCk7XA0KLVwNCi0JaWYgKG5PYmpEZWZuSUQgPj0gMClcDQotCXtcDQotCQlmb3IgKGludCBqPTAsIHN6aj1zaXplb2YoSlNfQ2xhc3NfUHJvcGVydGllcykvc2l6ZW9mKEpTUHJvcGVydHlTcGVjKS0xOyBqPHN6ajsgaisrKVwNCi0JCXtcDQotCQkJaWYgKEpTX0RlZmluZU9ialByb3BlcnR5KHBSdW50aW1lLCBuT2JqRGVmbklELCBKU19DbGFzc19Qcm9wZXJ0aWVzW2pdLnBOYW1lLCBKU19DbGFzc19Qcm9wZXJ0aWVzW2pdLnBQcm9wR2V0LEpTX0NsYXNzX1Byb3BlcnRpZXNbal0ucFByb3BQdXQpPDApcmV0dXJuIC0xO1wNCi0JCX1cDQotXA0KLQkJZm9yIChpbnQgaz0wLCBzems9c2l6ZW9mKEpTX0NsYXNzX01ldGhvZHMpL3NpemVvZihKU01ldGhvZFNwZWMpLTE7IGs8c3prOyBrKyspXA0KLQkJe1wNCi0JCQlpZiAoSlNfRGVmaW5lT2JqTWV0aG9kKHBSdW50aW1lLCBuT2JqRGVmbklELEpTX0NsYXNzX01ldGhvZHNba10ucE5hbWUsSlNfQ2xhc3NfTWV0aG9kc1trXS5wTWV0aG9kQ2FsbCxKU19DbGFzc19NZXRob2RzW2tdLm5QYXJhbU51bSk8MClyZXR1cm4gLTE7XA0KLQkJfVwNCi0JCWlmIChKU19EZWZpbmVPYmpBbGxQcm9wZXJ0aWVzKHBSdW50aW1lLCBuT2JqRGVmbklELCBqc19jbGFzc19uYW1lOjpxdWVyeXByb3BfIyNqc19jbGFzc19uYW1lIyNfc3RhdGljLCBqc19jbGFzc19uYW1lOjpnZXRwcm9wXyMjanNfY2xhc3NfbmFtZSMjX3N0YXRpYyxqc19jbGFzc19uYW1lOjpwdXRwcm9wXyMjanNfY2xhc3NfbmFtZSMjX3N0YXRpYyxqc19jbGFzc19uYW1lOjpkZWxwcm9wXyMjanNfY2xhc3NfbmFtZSMjX3N0YXRpYyk8MCkgcmV0dXJuIC0xO1wNCi1cDQotCQlyZXR1cm4gbk9iakRlZm5JRDtcDQotCX1cDQotXA0KLQlyZXR1cm4gLTE7XA0KLX1cDQotdm9pZCBqc19jbGFzc19uYW1lOjpHZXRDb25zdHMoSlNDb25zdFNwZWMqJiBwQ29uc3RzLCBpbnQmIG5TaXplKVwNCi17XA0KLQlwQ29uc3RzID0gSlNfQ2xhc3NfQ29uc3RzO1wNCi0JblNpemUgPSBzaXplb2YoSlNfQ2xhc3NfQ29uc3RzKS9zaXplb2YoSlNDb25zdFNwZWMpLTE7XA0KLX1cDQotdm9pZCBqc19jbGFzc19uYW1lOjpHZXRQcm9wZXJ0aWVzKEpTUHJvcGVydHlTcGVjKiYgcFByb3BlcnRpZXMsIGludCYgblNpemUpXA0KLXtcDQotCXBQcm9wZXJ0aWVzID0gSlNfQ2xhc3NfUHJvcGVydGllcztcDQotCW5TaXplID0gc2l6ZW9mKEpTX0NsYXNzX1Byb3BlcnRpZXMpL3NpemVvZihKU1Byb3BlcnR5U3BlYyktMTtcDQotfVwNCi12b2lkIGpzX2NsYXNzX25hbWU6OkdldE1ldGhvZHMoSlNNZXRob2RTcGVjKiYgcE1ldGhvZHMsIGludCYgblNpemUpXA0KLXtcDQotCXBNZXRob2RzID0gSlNfQ2xhc3NfTWV0aG9kcztcDQotCW5TaXplID0gc2l6ZW9mKEpTX0NsYXNzX01ldGhvZHMpL3NpemVvZihKU01ldGhvZFNwZWMpLTE7XA0KLX0NCi0NCi0jZGVmaW5lIEpTX1NQRUNJQUxfU1RBVElDX01FVEhPRChtZXRob2RfbmFtZSwgY2xhc3NfYWx0ZXJuYXRlLCBjbGFzc19uYW1lKVwNCi0Jc3RhdGljIHZvaWQgbWV0aG9kX25hbWUjI19zdGF0aWMoSlNfTUVUSE9EX0FSR1MpXA0KLXtcDQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gaW5mby5HZXRJc29sYXRlKCk7XA0KLQl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPSBpc29sYXRlLT5HZXRDdXJyZW50Q29udGV4dCgpO1wNCi0Jdjg6OkxvY2FsPHY4OjpWYWx1ZT4gdiA9IGNvbnRleHQtPkdldEVtYmVkZGVyRGF0YSgxKTtcDQotCUFTU0VSVCghdi5Jc0VtcHR5KCkpO1wNCi0JaWYodi5Jc0VtcHR5KCkpIHJldHVybjtcDQotCXY4OjpIYW5kbGU8djg6OkV4dGVybmFsPiBmaWVsZCA9IHY4OjpIYW5kbGU8djg6OkV4dGVybmFsPjo6Q2FzdCh2KTtcDQotCUlGWEpTX1J1bnRpbWUqIHBSdW50aW1lID0gKElGWEpTX1J1bnRpbWUqKWZpZWxkLT5WYWx1ZSgpO1wNCi0JSUZYSlNfQ29udGV4dCogY2MgPSBwUnVudGltZS0+R2V0Q3VycmVudENvbnRleHQoKTtcDQotCUNKU19QYXJhbWV0ZXJzIHBhcmFtZXRlcnM7XA0KLQlmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaTwodW5zaWduZWQgaW50KWluZm8uTGVuZ3RoKCk7IGkrKylcDQotCXtcDQotCXBhcmFtZXRlcnMucHVzaF9iYWNrKENKU19WYWx1ZShpc29sYXRlLCBpbmZvW2ldLCBWVF91bmtub3duKSk7XA0KLQl9XA0KLQlDSlNfVmFsdWUgdmFsdWVSZXMoaXNvbGF0ZSk7XA0KLQlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCAqKUpTX0dldFByaXZhdGUoaXNvbGF0ZSwgaW5mby5Ib2xkZXIoKSk7XA0KLQlBU1NFUlQocEpTT2JqICE9IE5VTEwpO1wNCi0JY2xhc3NfYWx0ZXJuYXRlKiBwT2JqID0gKGNsYXNzX2FsdGVybmF0ZSopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpO1wNCi0JQVNTRVJUKHBPYmogIT0gTlVMTCk7XA0KLQlKU19FcnJvclN0cmluZyBzRXJyb3I7XA0KLQlGWF9CT09MIGJSZXQgPSBGQUxTRTtcDQotCXRyeVwNCi0Je1wNCi0JCU1FTUxFQUtDSEVDS18xKCk7XA0KLQkJYlJldCA9IHBPYmotPm1ldGhvZF9uYW1lKGNjLCBwYXJhbWV0ZXJzLCB2YWx1ZVJlcywgc0Vycm9yKTtcDQotCQlNRU1MRUFLQ0hFQ0tfMihjbGFzc19uYW1lLCBtZXRob2RfbmFtZSk7XA0KLQl9XA0KLQljYXRjaCAoLi4uKVwNCi0Je1wNCi0JCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcDQotCQljYk5hbWUuRm9ybWF0KCIlcy4lcyIsICNjbGFzc19uYW1lLCAjbWV0aG9kX25hbWUpO1wNCi0JCUpTX0Vycm9yKE5VTEwsIENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgTCJVbmtub3duIGVycm9yIGlzIGNhdGNoZWQhIik7XA0KLQkJcmV0dXJuIDtcDQotCX1cDQotCWlmIChiUmV0KVwNCi0Je1wNCi0JCWluZm8uR2V0UmV0dXJuVmFsdWUoKS5TZXQodmFsdWVSZXMuVG9KU1ZhbHVlKCkpO1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLQllbHNlXA0KLQl7XA0KLQkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wNCi0JCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNtZXRob2RfbmFtZSk7XA0KLQkJSlNfRXJyb3IoTlVMTCwgQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChjYk5hbWUpLCBzRXJyb3IpO1wNCi0JCXJldHVybiA7XA0KLQl9XA0KLQlKU19FcnJvcihOVUxMLCAgSlNfV0lERVNUUklORyhtZXRob2RfbmFtZSksIEwiRW1iZWRlZCBvYmplY3Qgbm90IGZvdW5kISIpO1wNCi0gICAgcmV0dXJuIDtcDQotfQ0KLQ0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gR0xPQkFMIE1FVEhPRFMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCi0jZGVmaW5lIEpTX1NUQVRJQ19HTE9CQUxfRlVOKGZ1bl9uYW1lKSBcDQotc3RhdGljIHZvaWQgZnVuX25hbWUjI19zdGF0aWMoSlNfTUVUSE9EX0FSR1MpXA0KLXtcDQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gaW5mby5HZXRJc29sYXRlKCk7XA0KLQl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPSBpc29sYXRlLT5HZXRDdXJyZW50Q29udGV4dCgpO1wNCi0Jdjg6OkxvY2FsPHY4OjpWYWx1ZT4gdiA9IGNvbnRleHQtPkdldEVtYmVkZGVyRGF0YSgxKTtcDQotCUFTU0VSVCghdi5Jc0VtcHR5KCkpO1wNCi0JaWYodi5Jc0VtcHR5KCkpIHJldHVybjtcDQotCXY4OjpIYW5kbGU8djg6OkV4dGVybmFsPiBmaWVsZCA9IHY4OjpIYW5kbGU8djg6OkV4dGVybmFsPjo6Q2FzdCh2KTtcDQotCUlGWEpTX1J1bnRpbWUqIHBSdW50aW1lID0gKElGWEpTX1J1bnRpbWUqKWZpZWxkLT5WYWx1ZSgpO1wNCi0JSUZYSlNfQ29udGV4dCogY2MgPSBwUnVudGltZS0+R2V0Q3VycmVudENvbnRleHQoKTtcDQotCUNKU19QYXJhbWV0ZXJzIHBhcmFtZXRlcnM7XA0KLQlmb3IgKHVuc2lnbmVkIGludCBpID0gMDsgaTwodW5zaWduZWQgaW50KWluZm8uTGVuZ3RoKCk7IGkrKylcDQotCXtcDQotCXBhcmFtZXRlcnMucHVzaF9iYWNrKENKU19WYWx1ZShpc29sYXRlLCBpbmZvW2ldLCBWVF91bmtub3duKSk7XA0KLQl9XA0KLQlDSlNfVmFsdWUgdmFsdWVSZXMoaXNvbGF0ZSk7XA0KLQlKU19FcnJvclN0cmluZyBzRXJyb3I7XA0KLQlpZiAoIWZ1bl9uYW1lKGNjLCBwYXJhbWV0ZXJzLCB2YWx1ZVJlcywgc0Vycm9yKSlcDQotCXtcDQotCQlKU19FcnJvcihOVUxMLCBKU19XSURFU1RSSU5HKGZ1bl9uYW1lKSwgc0Vycm9yKTtcDQotCQlyZXR1cm4gO1wNCi0JfVwNCi0JaW5mby5HZXRSZXR1cm5WYWx1ZSgpLlNldCh2YWx1ZVJlcy5Ub0pTVmFsdWUoKSk7XA0KLQlyZXR1cm4gO1wNCi19DQotDQotI2RlZmluZSBKU19TVEFUSUNfREVDTEFSRV9HTE9CQUxfRlVOKCkgXA0KLXN0YXRpYyBKU01ldGhvZFNwZWMJZ2xvYmFsX21ldGhvZHNbXTsgXA0KLXN0YXRpYyBpbnQgSW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUpDQotDQotI2RlZmluZSBCRUdJTl9KU19TVEFUSUNfR0xPQkFMX0ZVTihqc19jbGFzc19uYW1lKSBcDQotSlNNZXRob2RTcGVjIGpzX2NsYXNzX25hbWU6Omdsb2JhbF9tZXRob2RzW10gPSB7DQotDQotI2RlZmluZSBKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShtZXRob2RfbmFtZSxuYXJncykgSlNfU1RBVElDX01FVEhPRF9FTlRSWShtZXRob2RfbmFtZSxuYXJncykNCi0NCi0jZGVmaW5lIEVORF9KU19TVEFUSUNfR0xPQkFMX0ZVTigpIEVORF9KU19TVEFUSUNfTUVUSE9EKCkNCi0NCi0jZGVmaW5lIElNUExFTUVOVF9KU19TVEFUSUNfR0xPQkFMX0ZVTihqc19jbGFzc19uYW1lKSBcDQotaW50IGpzX2NsYXNzX25hbWU6OkluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lKVwNCi17XA0KLQlmb3IgKGludCBpPTAsIHN6PXNpemVvZihqc19jbGFzc19uYW1lOjpnbG9iYWxfbWV0aG9kcykvc2l6ZW9mKEpTTWV0aG9kU3BlYyktMTsgaTxzejsgaSsrKVwNCi0Je1wNCi0JCWlmIChKU19EZWZpbmVHbG9iYWxNZXRob2QocFJ1bnRpbWUsXA0KLQkJCQlqc19jbGFzc19uYW1lOjpnbG9iYWxfbWV0aG9kc1tpXS5wTmFtZSxcDQotCQkJCWpzX2NsYXNzX25hbWU6Omdsb2JhbF9tZXRob2RzW2ldLnBNZXRob2RDYWxsLFwNCi0JCQkJanNfY2xhc3NfbmFtZTo6Z2xvYmFsX21ldGhvZHNbaV0ublBhcmFtTnVtXA0KLQkJCQkpIDwgMFwNCi0JCQkpcmV0dXJuIC0xO1wNCi0JfVwNCi0JcmV0dXJuIDA7XA0KLX0NCi0NCi0vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IEdMT0JBTCBDT05TVFMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCi0jZGVmaW5lIERFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIGNvbnN0X25hbWUgLCBjb25zdF92YWx1ZSlcDQotaWYgKEpTX0RlZmluZUdsb2JhbENvbnN0KHBSdW50aW1lLEpTX1dJREVTVFJJTkcoY29uc3RfbmFtZSksSlNfTmV3U3RyaW5nKHBSdW50aW1lLEpTX1dJREVTVFJJTkcoY29uc3RfdmFsdWUpKSkpIHJldHVybiAtMQ0KLQ0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gR0xPQkFMIEFSUkFZUyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLw0KLQ0KLSNkZWZpbmUgREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSlcDQotaW50IHNpemUgPSBzaXplb2YoQXJyYXlDb250ZW50KSAvIHNpemVvZihGWF9MUENXU1RSKTtcDQotXA0KLUNKU19BcnJheSBhcnJheShwUnVudGltZSk7XA0KLWZvciAoaW50IGk9MDsgaTxzaXplOyBpKyspIGFycmF5LlNldEVsZW1lbnQoaSxDSlNfVmFsdWUocFJ1bnRpbWUsKEZYX0xQQ1dTVFIpQXJyYXlDb250ZW50W2ldKSk7XA0KLVwNCi1DSlNfUHJvcFZhbHVlIHByb3AocFJ1bnRpbWUpO1wNCi1wcm9wIDw8IGFycmF5O1wNCi1pZiAoSlNfRGVmaW5lR2xvYmFsQ29uc3QocFJ1bnRpbWUsIChjb25zdCB3Y2hhcl90KilBcnJheU5hbWUsIHByb3AuVG9KU1ZhbHVlKCkpIDwgMClcDQotCXJldHVybiAtMQ0KLQ0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLw0KLQ0KLSNkZWZpbmUgVkFMVUVfTkFNRV9TVFJJTkcJCUwic3RyaW5nIg0KLSNkZWZpbmUgVkFMVUVfTkFNRV9OVU1CRVIJCUwibnVtYmVyIg0KLSNkZWZpbmUgVkFMVUVfTkFNRV9CT09MRUFOCQlMImJvb2xlYW4iDQotI2RlZmluZSBWQUxVRV9OQU1FX0RBVEUJCQlMImRhdGUiDQotI2RlZmluZSBWQUxVRV9OQU1FX09CSkVDVAkJTCJvYmplY3QiDQotI2RlZmluZSBWQUxVRV9OQU1FX0ZYT0JKCQlMImZ4b2JqIg0KLSNkZWZpbmUgVkFMVUVfTkFNRV9OVUxMCQkJTCJudWxsIg0KLSNkZWZpbmUgVkFMVUVfTkFNRV9VTkRFRklORUQJTCJ1bmRlZmluZWQiDQotDQotI2RlZmluZSBDTEFTU05BTUVfQVJSQVkJCQlMIkFycmF5Ig0KLSNkZWZpbmUgQ0xBU1NOQU1FX0RBVEUJCQlMIkRhdGUiDQotI2RlZmluZSBDTEFTU05BTUVfU1RSSU5HCQlMInY4OjpTdHJpbmciDQotDQotY29uc3QgdW5zaWduZWQgaW50IEpTQ09OU1RfblN0cmluZ0hhc2ggPSBKU19DYWxjSGFzaChWQUxVRV9OQU1FX1NUUklORyx3Y3NsZW4oVkFMVUVfTkFNRV9TVFJJTkcpKTsNCi1jb25zdCB1bnNpZ25lZCBpbnQgSlNDT05TVF9uTnVtYmVySGFzaCA9IEpTX0NhbGNIYXNoKFZBTFVFX05BTUVfTlVNQkVSLHdjc2xlbihWQUxVRV9OQU1FX05VTUJFUikpOw0KLWNvbnN0IHVuc2lnbmVkIGludCBKU0NPTlNUX25Cb29sSGFzaCA9IEpTX0NhbGNIYXNoKFZBTFVFX05BTUVfQk9PTEVBTix3Y3NsZW4oVkFMVUVfTkFNRV9CT09MRUFOKSk7DQotY29uc3QgdW5zaWduZWQgaW50IEpTQ09OU1RfbkRhdGVIYXNoID0gSlNfQ2FsY0hhc2goVkFMVUVfTkFNRV9EQVRFLHdjc2xlbihWQUxVRV9OQU1FX0RBVEUpKTsNCi1jb25zdCB1bnNpZ25lZCBpbnQgSlNDT05TVF9uT2JqZWN0SGFzaCA9IEpTX0NhbGNIYXNoKFZBTFVFX05BTUVfT0JKRUNULHdjc2xlbihWQUxVRV9OQU1FX09CSkVDVCkpOw0KLWNvbnN0IHVuc2lnbmVkIGludCBKU0NPTlNUX25GWG9iakhhc2ggPSBKU19DYWxjSGFzaChWQUxVRV9OQU1FX0ZYT0JKLHdjc2xlbihWQUxVRV9OQU1FX0ZYT0JKKSk7DQotY29uc3QgdW5zaWduZWQgaW50IEpTQ09OU1Rfbk51bGxIYXNoID0gSlNfQ2FsY0hhc2goVkFMVUVfTkFNRV9OVUxMLHdjc2xlbihWQUxVRV9OQU1FX05VTEwpKTsNCi1jb25zdCB1bnNpZ25lZCBpbnQgSlNDT05TVF9uVW5kZWZIYXNoID0gSlNfQ2FsY0hhc2goVkFMVUVfTkFNRV9VTkRFRklORUQsd2NzbGVuKFZBTFVFX05BTUVfVU5ERUZJTkVEKSk7DQotDQotc3RhdGljIEZYSlNWQUxVRVRZUEUgR0VUX1ZBTFVFX1RZUEUodjg6OkhhbmRsZTx2ODo6VmFsdWU+IHApDQotew0KLQ0KLQkJY29uc3QgdW5zaWduZWQgaW50IG5IYXNoID0gSlNfQ2FsY0hhc2goSlNfR2V0VHlwZW9mKHApKTsNCi0NCi0JCWlmIChuSGFzaCA9PSBKU0NPTlNUX25VbmRlZkhhc2gpDQotCQkJcmV0dXJuIFZUX3VuZGVmaW5lZDsNCi0JCWVsc2UgaWYgKG5IYXNoID09IEpTQ09OU1Rfbk51bGxIYXNoKQ0KLQkJCXJldHVybiBWVF9udWxsOw0KLQkJZWxzZSBpZiAobkhhc2ggPT0gSlNDT05TVF9uU3RyaW5nSGFzaCkNCi0JCQlyZXR1cm4gVlRfc3RyaW5nOw0KLQkJZWxzZSBpZiAobkhhc2ggPT0gSlNDT05TVF9uTnVtYmVySGFzaCkNCi0JCQlyZXR1cm4gVlRfbnVtYmVyOw0KLQkJZWxzZSBpZiAobkhhc2ggPT0gSlNDT05TVF9uQm9vbEhhc2gpDQotCQkJcmV0dXJuIFZUX2Jvb2xlYW47DQotCQllbHNlIGlmIChuSGFzaCA9PSBKU0NPTlNUX25EYXRlSGFzaCkNCi0JCQlyZXR1cm4gVlRfZGF0ZTsNCi0JCWVsc2UgaWYgKG5IYXNoID09IEpTQ09OU1Rfbk9iamVjdEhhc2gpDQotCQkJcmV0dXJuIFZUX29iamVjdDsJCQ0KLQkJZWxzZSBpZiAobkhhc2ggPT0gSlNDT05TVF9uRlhvYmpIYXNoKQ0KLQkJCXJldHVybiBWVF9meG9iamVjdDsNCi0NCi0JCS8qDQotCQljb25zdCBjaGFyICogc1R5cGUgPSBwLT5nZXRUeXBlb2YoKS0+dG9EY2hhcnMoKTsNCi0JCWlmIChzdHJjbXAoc1R5cGUsVkFMVUVfTkFNRV9TVFJJTkcpID09IDApDQotCQkJcmV0dXJuIFZUX3N0cmluZzsNCi0JCWVsc2UgaWYgKHN0cmNtcChzVHlwZSxWQUxVRV9OQU1FX05VTUJFUikgPT0gMCkNCi0JCQlyZXR1cm4gVlRfbnVtYmVyOw0KLQkJZWxzZSBpZiAoc3RyY21wKHNUeXBlLFZBTFVFX05BTUVfQk9PTEVBTikgPT0gMCkNCi0JCQlyZXR1cm4gVlRfYm9vbGVhbjsNCi0JCWVsc2UgaWYgKHN0cmNtcChzVHlwZSxWQUxVRV9OQU1FX0RBVEUpID09IDApDQotCQkJcmV0dXJuIFZUX2RhdGU7DQotCQllbHNlIGlmIChzdHJjbXAoc1R5cGUsVkFMVUVfTkFNRV9PQkpFQ1QpID09IDApDQotCQkJcmV0dXJuIFZUX29iamVjdDsNCi0JCWVsc2UgaWYgKHN0cmNtcChzVHlwZSxWQUxVRV9OQU1FX0ZYT0JKKSA9PSAwKQ0KLQkJCXJldHVybiBWVF9vYmplY3Q7DQotCQllbHNlIGlmIChzdHJjbXAoc1R5cGUsVkFMVUVfTkFNRV9OVUxMKSA9PSAwKQ0KLQkJCXJldHVybiBWVF9udWxsOw0KLQkJZWxzZSBpZiAoc3RyY21wKHNUeXBlLFZBTFVFX05BTUVfVU5ERUZJTkVEKSA9PSAwKQ0KLQkJCXJldHVybiBWVF91bmRlZmluZWQ7DQotCQkJKi8NCi0NCi0JcmV0dXJuIFZUX3Vua25vd247DQotfQ0KLQ0KLSNlbmRpZiAvL19KU19ERUZJTkVfSF8NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9KU19ERUZJTkVfSF8KKyNkZWZpbmUgX0pTX0RFRklORV9IXworCit0eXBlZGVmIHY4OjpWYWx1ZQkJCUpTVmFsdWU7Cit0eXBlZGVmIHY4OjpIYW5kbGU8djg6Ok9iamVjdD4JSlNPYmplY3Q7Cit0eXBlZGVmIHY4OjpIYW5kbGU8djg6Ok9iamVjdD4JSlNGWE9iamVjdDsKK3R5cGVkZWYgdW5zaWduZWQJCUpTQm9vbDsKKworc3RydWN0IEpTQ29uc3RTcGVjCit7CisJY29uc3Qgd2NoYXJfdCogcE5hbWU7CisJZG91YmxlIG51bWJlcjsKKwljb25zdCB3Y2hhcl90KiBzdHJpbmc7CisJRlhfQllURSB0OyAvLzA6ZG91YmxlIDE6c3RyCit9OworCitzdHJ1Y3QgSlNQcm9wZXJ0eVNwZWMKK3sKKwljb25zdCB3Y2hhcl90KiBwTmFtZTsKKwl2ODo6QWNjZXNzb3JHZXR0ZXJDYWxsYmFjayBwUHJvcEdldDsKKwl2ODo6QWNjZXNzb3JTZXR0ZXJDYWxsYmFjayBwUHJvcFB1dDsKK307CisKK3N0cnVjdCBKU01ldGhvZFNwZWMKK3sKKwljb25zdCB3Y2hhcl90KiBwTmFtZTsKKwl2ODo6RnVuY3Rpb25DYWxsYmFjayBwTWV0aG9kQ2FsbDsKKwl1bnNpZ25lZCBuUGFyYW1OdW07Cit9OworCit0eXBlZGVmIENGWF9XaWRlU3RyaW5nCUpTX0Vycm9yU3RyaW5nOworCisjZGVmaW5lIEpTX1RSVUUJCQkodW5zaWduZWQpMQorI2RlZmluZSBKU19GQUxTRQkJKHVuc2lnbmVkKTAKKworCisjZGVmaW5lIENKU19Qb2ludHNBcnJheQkJQ0ZYX0FycmF5VGVtcGxhdGU8ZmxvYXQ+CisjZGVmaW5lIENKU19JbnRBcnJheQkJQ0ZYX0FycmF5VGVtcGxhdGU8aW50PgorCisvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBQVUJMSUMgREVGSU5FIFNQRUMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLworI2lmbmRlZiBfX0dOVUNfXworI2RlZmluZSBKU19XSURFU1RSSU5HKHdpZGVzdHJpbmcpIEwjd2lkZXN0cmluZworI2Vsc2UKKyNkZWZpbmUgSlNfV0lERVNUUklORyh3aWRlc3RyaW5nKSBMIiIjd2lkZXN0cmluZworI2VuZGlmCisKKyNkZWZpbmUgT0JKX1BST1BfUEFSQU1TCQkJSUZYSlNfQ29udGV4dCogY2MsIENKU19Qcm9wVmFsdWUmIHZwLCBKU19FcnJvclN0cmluZyYgc0Vycm9yCisjZGVmaW5lIE9CSl9NRVRIT0RfUEFSQU1TCQlJRlhKU19Db250ZXh0KiBjYywgY29uc3QgQ0pTX1BhcmFtZXRlcnMmIHBhcmFtcywgQ0pTX1ZhbHVlJiB2UmV0LCBKU19FcnJvclN0cmluZyYgc0Vycm9yCisjZGVmaW5lIEJFR0lOX0pTX1NUQVRJQ19DT05TVChqc19jbGFzc19uYW1lKSBKU0NvbnN0U3BlYyBqc19jbGFzc19uYW1lOjpKU19DbGFzc19Db25zdHNbXSA9IHsKKyNkZWZpbmUgSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUihjb25zdF9uYW1lLCBwVmFsdWUpIHtKU19XSURFU1RSSU5HKGNvbnN0X25hbWUpLCBwVmFsdWUsIEwiIiwgMH0sCisjZGVmaW5lIEpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoY29uc3RfbmFtZSwgcFZhbHVlKSB7SlNfV0lERVNUUklORyhjb25zdF9uYW1lKSwgMCwgSlNfV0lERVNUUklORyhwVmFsdWUpLCAxfSwKKyNkZWZpbmUgRU5EX0pTX1NUQVRJQ19DT05TVCgpIHswLCAwLCAwLCAwfX07CisKKyNkZWZpbmUgQkVHSU5fSlNfU1RBVElDX1BST1AoanNfY2xhc3NfbmFtZSkgSlNQcm9wZXJ0eVNwZWMganNfY2xhc3NfbmFtZTo6SlNfQ2xhc3NfUHJvcGVydGllc1tdID0geworI2RlZmluZSBKU19TVEFUSUNfUFJPUF9FTlRSWShwcm9wX25hbWUpIHtKU19XSURFU1RSSU5HKHByb3BfbmFtZSksIGdldF8jI3Byb3BfbmFtZSMjX3N0YXRpYywgc2V0XyMjcHJvcF9uYW1lIyNfc3RhdGljfSwKKyNkZWZpbmUgRU5EX0pTX1NUQVRJQ19QUk9QKCkgezAsIDAsIDB9fTsKKworI2RlZmluZSBCRUdJTl9KU19TVEFUSUNfTUVUSE9EKGpzX2NsYXNzX25hbWUpIEpTTWV0aG9kU3BlYyBqc19jbGFzc19uYW1lOjpKU19DbGFzc19NZXRob2RzW10gPSB7CisjZGVmaW5lIEpTX1NUQVRJQ19NRVRIT0RfRU5UUlkobWV0aG9kX25hbWUsIG5hcmdzKSB7SlNfV0lERVNUUklORyhtZXRob2RfbmFtZSksIG1ldGhvZF9uYW1lIyNfc3RhdGljLCBuYXJnc30sCisjZGVmaW5lIEVORF9KU19TVEFUSUNfTUVUSE9EKCkgezAsIDAsIDB9fTsKKyNkZWZpbmUgTUVNTEVBS0NIRUNLXzEoKSAoKHZvaWQpMCkKKyNkZWZpbmUgTUVNTEVBS0NIRUNLXzIobWFpbl9uYW1lLCBzdWJfbmFtZSkgKCh2b2lkKTApCisKKworLyoKKyNpZmRlZiBfREVCVUcKKyNkZWZpbmUgTUVNTEVBS0NIRUNLXzEoKSBcCisJX0NydE1lbVN0YXRlIHN0YXRlMTtcCisJX0NydE1lbUNoZWNrcG9pbnQoJnN0YXRlMSk7CisKKyNkZWZpbmUgTUVNTEVBS0NIRUNLXzIobWFpbl9uYW1lLHN1Yl9uYW1lKSBcCisJX0NydE1lbVN0YXRlIHN0YXRlMjtcCisJX0NydE1lbUNoZWNrcG9pbnQoJnN0YXRlMik7XAorCV9DcnRNZW1TdGF0ZSBkaWZmO1wKKwlfQ3J0TWVtRGlmZmVyZW5jZSgmZGlmZiwmc3RhdGUxLCZzdGF0ZTIpO1wKKwlpZiAoZGlmZi5sU2l6ZXNbX05PUk1BTF9CTE9DS10gPiAwKVwKKwl7XAorCQlUUkFDRSgiRGV0ZWN0ZWQgbm9ybWFsIGJsb2NrIG1lbW9yeSBsZWFrcyBpbiBKUyBNb2R1bGUhIFslcy4lc11cbiIsI21haW5fbmFtZSwjc3ViX25hbWUpO1wKKwkJX0NydE1lbUR1bXBTdGF0aXN0aWNzKCZkaWZmKTtcCisJfQorI2Vsc2UKKwkjZGVmaW5lIE1FTUxFQUtDSEVDS18xKCkgKCh2b2lkKTApCisJI2RlZmluZSBNRU1MRUFLQ0hFQ0tfMihtYWluX25hbWUsc3ViX25hbWUpICgodm9pZCkwKQorI2VuZGlmCisqLworCisvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFBST1AgQ0FMTEJBQ0sgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KKworI2RlZmluZSBKU19TVEFUSUNfUFJPUF9HRVQocHJvcF9uYW1lLCBjbGFzc19uYW1lKVwKKwlzdGF0aWMgdm9pZCBnZXRfIyNwcm9wX25hbWUjI19zdGF0aWMoSlNfUFJPUEdFVF9BUkdTKVwKK3tcCisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBpbmZvLkdldElzb2xhdGUoKTtcCisJdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gaXNvbGF0ZS0+R2V0Q3VycmVudENvbnRleHQoKTtcCisJdjg6OkxvY2FsPHY4OjpWYWx1ZT4gdiA9IGNvbnRleHQtPkdldEVtYmVkZGVyRGF0YSgxKTtcCisJQVNTRVJUKCF2LklzRW1wdHkoKSk7XAorCWlmKHYuSXNFbXB0eSgpKSByZXR1cm47XAorCXY4OjpIYW5kbGU8djg6OkV4dGVybmFsPiBmaWVsZCA9IHY4OjpIYW5kbGU8djg6OkV4dGVybmFsPjo6Q2FzdCh2KTtcCisJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSAoSUZYSlNfUnVudGltZSopZmllbGQtPlZhbHVlKCk7XAorCUlGWEpTX0NvbnRleHQqIGNjID0gcFJ1bnRpbWUtPkdldEN1cnJlbnRDb250ZXh0KCk7XAorCUNKU19Qcm9wVmFsdWUgdmFsdWUoaXNvbGF0ZSk7XAorCXZhbHVlLlN0YXJ0R2V0dGluZygpO1wKKwlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLGluZm8uSG9sZGVyKCkpO1wKKwlBU1NFUlQocEpTT2JqICE9IE5VTEwpO1wKKwljbGFzc19uYW1lKiBwT2JqID0gKGNsYXNzX25hbWUqKXBKU09iai0+R2V0RW1iZWRPYmplY3QoKTtcCisJQVNTRVJUKHBPYmogIT0gTlVMTCk7XAorCUpTX0Vycm9yU3RyaW5nIHNFcnJvcjtcCisJRlhfQk9PTCBiUmV0ID0gRkFMU0U7XAorCXRyeVwKKwl7XAorCQlNRU1MRUFLQ0hFQ0tfMSgpO1wKKwkJYlJldCA9IHBPYmotPnByb3BfbmFtZShjYywgdmFsdWUsIHNFcnJvcik7XAorCQlNRU1MRUFLQ0hFQ0tfMihjbGFzc19uYW1lLCBwcm9wX25hbWUpO1wKKwl9XAorCWNhdGNoICguLi4pXAorCXtcCisJCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcCisJCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNwcm9wX25hbWUpO1wKKwkJSlNfRXJyb3IoTlVMTCxDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNiTmFtZSksIEwiVW5rbm93biBlcnJvciBpcyBjYXRjaGVkISIpO1wKKwkJcmV0dXJuIDtcCisJfVwKKwlpZiAoYlJldClcCisJe1wKKwkJaW5mby5HZXRSZXR1cm5WYWx1ZSgpLlNldCgodjg6OkhhbmRsZTx2ODo6VmFsdWU+KXZhbHVlKTtcCisJCXJldHVybiA7XAorCX1cCisJZWxzZVwKKwl7XAorCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcCisJCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNwcm9wX25hbWUpO1wKKwkJSlNfRXJyb3IoTlVMTCxDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNiTmFtZSksIHNFcnJvcik7XAorCQlyZXR1cm4gO1wKKwl9XAorfQorCisjZGVmaW5lIEpTX1NUQVRJQ19QUk9QX1NFVChwcm9wX25hbWUsIGNsYXNzX25hbWUpXAorCXN0YXRpYyB2b2lkIHNldF8jI3Byb3BfbmFtZSMjX3N0YXRpYyhKU19QUk9QUFVUX0FSR1MpXAore1wKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IGluZm8uR2V0SXNvbGF0ZSgpO1wKKwl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPSBpc29sYXRlLT5HZXRDdXJyZW50Q29udGV4dCgpO1wKKwl2ODo6TG9jYWw8djg6OlZhbHVlPiB2ID0gY29udGV4dC0+R2V0RW1iZWRkZXJEYXRhKDEpO1wKKwlBU1NFUlQoIXYuSXNFbXB0eSgpKTtcCisJaWYodi5Jc0VtcHR5KCkpIHJldHVybjtcCisJdjg6OkhhbmRsZTx2ODo6RXh0ZXJuYWw+IGZpZWxkID0gdjg6OkhhbmRsZTx2ODo6RXh0ZXJuYWw+OjpDYXN0KHYpO1wKKwlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IChJRlhKU19SdW50aW1lKilmaWVsZC0+VmFsdWUoKTtcCisJSUZYSlNfQ29udGV4dCogY2MgPSBwUnVudGltZS0+R2V0Q3VycmVudENvbnRleHQoKTtcCisJQ0pTX1Byb3BWYWx1ZSBwcm9wVmFsdWUoQ0pTX1ZhbHVlKGlzb2xhdGUsdmFsdWUsVlRfdW5rbm93bikpO1wKKwlwcm9wVmFsdWUuU3RhcnRTZXR0aW5nKCk7XAorCUNKU19PYmplY3QqIHBKU09iaiA9IChDSlNfT2JqZWN0KilKU19HZXRQcml2YXRlKGlzb2xhdGUsaW5mby5Ib2xkZXIoKSk7XAorCUFTU0VSVChwSlNPYmogIT0gTlVMTCk7XAorCWNsYXNzX25hbWUqIHBPYmogPSAoY2xhc3NfbmFtZSopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpO1wKKwlBU1NFUlQocE9iaiAhPSBOVUxMKTtcCisJSlNfRXJyb3JTdHJpbmcgc0Vycm9yO1wKKwlGWF9CT09MIGJSZXQgPSBGQUxTRTtcCisJdHJ5XAorCXtcCisJCU1FTUxFQUtDSEVDS18xKCk7XAorCQliUmV0ID0gcE9iai0+cHJvcF9uYW1lKGNjLCBwcm9wVmFsdWUsIHNFcnJvcik7XAorCQlNRU1MRUFLQ0hFQ0tfMihjbGFzc19uYW1lLCBwcm9wX25hbWUpO1wKKwl9XAorCWNhdGNoICguLi4pXAorCXtcCisJCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcCisJCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNwcm9wX25hbWUpO1wKKwkJSlNfRXJyb3IoTlVMTCxDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNiTmFtZSksIEwiVW5rbm93biBlcnJvciBpcyBjYXRjaGVkISIpO1wKKwkJcmV0dXJuIDtcCisJfVwKKwlpZiAoYlJldClcCisJe1wKKwkJcmV0dXJuIDtcCisJfVwKKwllbHNlXAorCXtcCisJCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcCisJCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNwcm9wX25hbWUpO1wKKwkJSlNfRXJyb3IoTlVMTCxDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNiTmFtZSksIHNFcnJvcik7XAorCQlyZXR1cm4gO1wKKwl9XAorfQorCisjZGVmaW5lIEpTX1NUQVRJQ19QUk9QKHByb3BfbmFtZSwgY2xhc3NfbmFtZSlcCitKU19TVEFUSUNfUFJPUF9HRVQocHJvcF9uYW1lLCBjbGFzc19uYW1lKTtcCitKU19TVEFUSUNfUFJPUF9TRVQocHJvcF9uYW1lLCBjbGFzc19uYW1lKQorCisvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBNRVRIT0QgQ0FMTEJBQ0sgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLworCisjZGVmaW5lIEpTX1NUQVRJQ19NRVRIT0QobWV0aG9kX25hbWUsIGNsYXNzX25hbWUpXAorCXN0YXRpYyB2b2lkIG1ldGhvZF9uYW1lIyNfc3RhdGljKEpTX01FVEhPRF9BUkdTKVwKK3tcCisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBpbmZvLkdldElzb2xhdGUoKTtcCisJdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gaXNvbGF0ZS0+R2V0Q3VycmVudENvbnRleHQoKTtcCisJdjg6OkxvY2FsPHY4OjpWYWx1ZT4gdiA9IGNvbnRleHQtPkdldEVtYmVkZGVyRGF0YSgxKTtcCisJQVNTRVJUKCF2LklzRW1wdHkoKSk7XAorCWlmKHYuSXNFbXB0eSgpKSByZXR1cm47XAorCXY4OjpIYW5kbGU8djg6OkV4dGVybmFsPiBmaWVsZCA9IHY4OjpIYW5kbGU8djg6OkV4dGVybmFsPjo6Q2FzdCh2KTtcCisJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSAoSUZYSlNfUnVudGltZSopZmllbGQtPlZhbHVlKCk7XAorCUlGWEpTX0NvbnRleHQqIGNjID0gcFJ1bnRpbWUtPkdldEN1cnJlbnRDb250ZXh0KCk7XAorCUNKU19QYXJhbWV0ZXJzIHBhcmFtZXRlcnM7XAorCWZvciAodW5zaWduZWQgaW50IGkgPSAwOyBpPCh1bnNpZ25lZCBpbnQpaW5mby5MZW5ndGgoKTsgaSsrKVwKKyAgICB7XAorCQlwYXJhbWV0ZXJzLnB1c2hfYmFjayhDSlNfVmFsdWUoaXNvbGF0ZSwgaW5mb1tpXSwgVlRfdW5rbm93bikpO1wKKwl9XAorCUNKU19WYWx1ZSB2YWx1ZVJlcyhpc29sYXRlKTtcCisJQ0pTX09iamVjdCogcEpTT2JqID0gKENKU19PYmplY3QgKilKU19HZXRQcml2YXRlKGlzb2xhdGUsaW5mby5Ib2xkZXIoKSk7XAorCUFTU0VSVChwSlNPYmogIT0gTlVMTCk7XAorCWNsYXNzX25hbWUqIHBPYmogPSAoY2xhc3NfbmFtZSopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpO1wKKwlBU1NFUlQocE9iaiAhPSBOVUxMKTtcCisJSlNfRXJyb3JTdHJpbmcgc0Vycm9yO1wKKwlGWF9CT09MIGJSZXQgPSBGQUxTRTtcCisJdHJ5XAorCXtcCisJCU1FTUxFQUtDSEVDS18xKCk7XAorCQliUmV0ID0gcE9iai0+bWV0aG9kX25hbWUoY2MsIHBhcmFtZXRlcnMsIHZhbHVlUmVzLCBzRXJyb3IpO1wKKwkJTUVNTEVBS0NIRUNLXzIoY2xhc3NfbmFtZSwgbWV0aG9kX25hbWUpO1wKKwl9XAorCWNhdGNoICguLi4pXAorCXtcCisJCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcCisJCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNtZXRob2RfbmFtZSk7XAorCQlKU19FcnJvcihOVUxMLCBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNiTmFtZSksIEwiVW5rbm93biBlcnJvciBpcyBjYXRjaGVkISIpO1wKKwkJcmV0dXJuIDtcCisJfVwKKwlpZiAoYlJldClcCisJe1wKKwkJaW5mby5HZXRSZXR1cm5WYWx1ZSgpLlNldCh2YWx1ZVJlcy5Ub0pTVmFsdWUoKSk7XAorCQlyZXR1cm4gO1wKKwl9XAorCWVsc2VcCisJe1wKKwkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wKKwkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgI21ldGhvZF9uYW1lKTtcCisJCUpTX0Vycm9yKE5VTEwsIENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgc0Vycm9yKTtcCisJCXJldHVybiA7XAorCX1cCit9CisKKy8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gSlMgQ0xBU1MgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KKworI2RlZmluZSBERUNMQVJFX0pTX0NMQVNTKGpzX2NsYXNzX25hbWUpIFwKKwlzdGF0aWMgSlNCb29sIEpTQ29uc3RydWN0b3IoSUZYSlNfQ29udGV4dCogY2MsIEpTRlhPYmplY3Qgb2JqLEpTRlhPYmplY3QgZ2xvYmFsKTtcCisJc3RhdGljIEpTQm9vbCBKU0Rlc3RydWN0b3IoSlNGWE9iamVjdCBvYmopO1wKKwlzdGF0aWMgaW50IEluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lLCBGWEpTT0JKVFlQRSBlT2JqVHlwZSk7XAorCXN0YXRpYyB2b2lkIEdldENvbnN0cyhKU0NvbnN0U3BlYyomIHBDb25zdHMsIGludCYgblNpemUpO1wKKwlzdGF0aWMgdm9pZCBHZXRQcm9wZXJ0aWVzKEpTUHJvcGVydHlTcGVjKiYgcFByb3BlcnRpZXMsIGludCYgblNpemUpO1wKKwlzdGF0aWMgdm9pZCBHZXRNZXRob2RzKEpTTWV0aG9kU3BlYyomIHBNZXRob2RzLCBpbnQmIG5TaXplKTtcCisJc3RhdGljIEpTQ29uc3RTcGVjIEpTX0NsYXNzX0NvbnN0c1tdO1wKKwlzdGF0aWMgSlNQcm9wZXJ0eVNwZWMgSlNfQ2xhc3NfUHJvcGVydGllc1tdO1wKKwlzdGF0aWMgSlNNZXRob2RTcGVjCUpTX0NsYXNzX01ldGhvZHNbXTtcCisJc3RhdGljIGNvbnN0IHdjaGFyX3QqIG1fcENsYXNzTmFtZQorCisjZGVmaW5lIElNUExFTUVOVF9KU19DTEFTU19SSUNIKGpzX2NsYXNzX25hbWUsIGNsYXNzX2FsdGVybmF0ZSwgY2xhc3NfbmFtZSkgXAorY29uc3Qgd2NoYXJfdCoganNfY2xhc3NfbmFtZTo6bV9wQ2xhc3NOYW1lID0gSlNfV0lERVNUUklORyhjbGFzc19uYW1lKTtcCitKU0Jvb2wganNfY2xhc3NfbmFtZTo6SlNDb25zdHJ1Y3RvcihJRlhKU19Db250ZXh0KiBjYywgSlNGWE9iamVjdCBvYmosIEpTRlhPYmplY3QgZ2xvYmFsKVwKK3tcCisJQ0pTX09iamVjdCogcE9iaiA9IEZYX05FVyBqc19jbGFzc19uYW1lKG9iaik7XAorCXBPYmotPlNldEVtYmVkT2JqZWN0KEZYX05FVyBjbGFzc19hbHRlcm5hdGUocE9iaikpO1wKKwlKU19TZXRQcml2YXRlKE5VTEwsb2JqLCh2b2lkKilwT2JqKTsgXAorCXBPYmotPkluaXRJbnN0YW5jZShjYyk7XAorCXJldHVybiBKU19UUlVFO1wKK31cCitcCitKU0Jvb2wganNfY2xhc3NfbmFtZTo6SlNEZXN0cnVjdG9yKEpTRlhPYmplY3Qgb2JqKSBcCit7XAorCWpzX2NsYXNzX25hbWUqIHBPYmogPSAoanNfY2xhc3NfbmFtZSopSlNfR2V0UHJpdmF0ZShOVUxMLG9iaik7XAorCUFTU0VSVChwT2JqICE9IE5VTEwpO1wKKwlwT2JqLT5FeGl0SW5zdGFuY2UoKTtcCisJZGVsZXRlIHBPYmo7XAorCXJldHVybiBKU19UUlVFO1wKK31cCitcCitpbnQganNfY2xhc3NfbmFtZTo6SW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUsIEZYSlNPQkpUWVBFIGVPYmpUeXBlKVwKK3tcCisJaW50IG5PYmpEZWZuSUQgPSBKU19EZWZpbmVPYmoocFJ1bnRpbWUsIGpzX2NsYXNzX25hbWU6Om1fcENsYXNzTmFtZSwgZU9ialR5cGUsIEpTQ29uc3RydWN0b3IsIEpTRGVzdHJ1Y3RvciwgMCk7XAorCWlmIChuT2JqRGVmbklEID49IDApXAorCXtcCisJCWZvciAoaW50IGo9MCwgc3pqPXNpemVvZihKU19DbGFzc19Qcm9wZXJ0aWVzKS9zaXplb2YoSlNQcm9wZXJ0eVNwZWMpLTE7IGo8c3pqOyBqKyspXAorCQl7XAorCQkJaWYgKEpTX0RlZmluZU9ialByb3BlcnR5KHBSdW50aW1lLCBuT2JqRGVmbklELCBKU19DbGFzc19Qcm9wZXJ0aWVzW2pdLnBOYW1lLCBKU19DbGFzc19Qcm9wZXJ0aWVzW2pdLnBQcm9wR2V0LCBKU19DbGFzc19Qcm9wZXJ0aWVzW2pdLnBQcm9wUHV0KSA8IDApIHJldHVybiAtMTtcCisJCX1cCisJCWZvciAoaW50IGs9MCwgc3prPXNpemVvZihKU19DbGFzc19NZXRob2RzKS9zaXplb2YoSlNNZXRob2RTcGVjKS0xOyBrPHN6azsgaysrKVwKKwkJe1wKKwkJCWlmIChKU19EZWZpbmVPYmpNZXRob2QocFJ1bnRpbWUsIG5PYmpEZWZuSUQsSlNfQ2xhc3NfTWV0aG9kc1trXS5wTmFtZSwgSlNfQ2xhc3NfTWV0aG9kc1trXS5wTWV0aG9kQ2FsbCwgSlNfQ2xhc3NfTWV0aG9kc1trXS5uUGFyYW1OdW0pIDwgMCkgcmV0dXJuIC0xO1wKKwkJfVwKKwkJcmV0dXJuIG5PYmpEZWZuSUQ7XAorCX1cCisJcmV0dXJuIC0xO1wKK31cCit2b2lkIGpzX2NsYXNzX25hbWU6OkdldENvbnN0cyhKU0NvbnN0U3BlYyomIHBDb25zdHMsIGludCYgblNpemUpXAore1wKKwlwQ29uc3RzID0gSlNfQ2xhc3NfQ29uc3RzO1wKKwluU2l6ZSA9IHNpemVvZihKU19DbGFzc19Db25zdHMpIC8gc2l6ZW9mKEpTQ29uc3RTcGVjKSAtIDE7XAorfVwKK3ZvaWQganNfY2xhc3NfbmFtZTo6R2V0UHJvcGVydGllcyhKU1Byb3BlcnR5U3BlYyomIHBQcm9wZXJ0aWVzLCBpbnQmIG5TaXplKVwKK3tcCisJcFByb3BlcnRpZXMgPSBKU19DbGFzc19Qcm9wZXJ0aWVzO1wKKwluU2l6ZSA9IHNpemVvZihKU19DbGFzc19Qcm9wZXJ0aWVzKSAvIHNpemVvZihKU1Byb3BlcnR5U3BlYykgLSAxO1wKK31cCit2b2lkIGpzX2NsYXNzX25hbWU6OkdldE1ldGhvZHMoSlNNZXRob2RTcGVjKiYgcE1ldGhvZHMsIGludCYgblNpemUpXAore1wKKwlwTWV0aG9kcyA9IEpTX0NsYXNzX01ldGhvZHM7XAorCW5TaXplID0gc2l6ZW9mKEpTX0NsYXNzX01ldGhvZHMpIC8gc2l6ZW9mKEpTTWV0aG9kU3BlYykgLSAxO1wKK30KKworI2RlZmluZSBJTVBMRU1FTlRfSlNfQ0xBU1MoanNfY2xhc3NfbmFtZSwgY2xhc3NfbmFtZSkgSU1QTEVNRU5UX0pTX0NMQVNTX1JJQ0goanNfY2xhc3NfbmFtZSwgY2xhc3NfbmFtZSwgY2xhc3NfbmFtZSkKKworLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBDT05TVCBDTEFTUyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLworCisjZGVmaW5lIERFQ0xBUkVfSlNfQ0xBU1NfQ09OU1QoKSBcCisJc3RhdGljIGludCBJbml0KElKU19SdW50aW1lKiBwUnVudGltZSwgRlhKU09CSlRZUEUgZU9ialR5cGUpO1wKKwlzdGF0aWMgdm9pZCBHZXRDb25zdHMoSlNDb25zdFNwZWMqJiBwQ29uc3RzLCBpbnQmIG5TaXplKTtcCisJc3RhdGljIEpTQ29uc3RTcGVjIEpTX0NsYXNzX0NvbnN0c1tdO1wKKwlzdGF0aWMgY29uc3Qgd2NoYXJfdCogbV9wQ2xhc3NOYW1lCisKKyNkZWZpbmUgSU1QTEVNRU5UX0pTX0NMQVNTX0NPTlNUKGpzX2NsYXNzX25hbWUsIGNsYXNzX25hbWUpIFwKK2NvbnN0IHdjaGFyX3QqIGpzX2NsYXNzX25hbWU6Om1fcENsYXNzTmFtZSA9IEpTX1dJREVTVFJJTkcoY2xhc3NfbmFtZSk7XAoraW50IGpzX2NsYXNzX25hbWU6OkluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lLCBGWEpTT0JKVFlQRSBlT2JqVHlwZSlcCit7XAorCWludCBuT2JqRGVmbklEID0gSlNfRGVmaW5lT2JqKHBSdW50aW1lLCBqc19jbGFzc19uYW1lOjptX3BDbGFzc05hbWUsIGVPYmpUeXBlLCBOVUxMLCBOVUxMLCAwKTtcCisJaWYgKG5PYmpEZWZuSUQgPj0wKVwKKwl7XAorCQlmb3IgKGludCBpPTAsIHN6PXNpemVvZihKU19DbGFzc19Db25zdHMpL3NpemVvZihKU0NvbnN0U3BlYyktMTsgaTxzejsgaSsrKVwKKwkJe1wKKwkJCWlmIChKU19DbGFzc19Db25zdHNbaV0udCA9PSAwKVwKKwkJCXtcCisJCQkJaWYgKEpTX0RlZmluZU9iakNvbnN0KHBSdW50aW1lLCBuT2JqRGVmbklELCBKU19DbGFzc19Db25zdHNbaV0ucE5hbWUsIEpTX05ld051bWJlcihwUnVudGltZSxKU19DbGFzc19Db25zdHNbaV0ubnVtYmVyKSkgPCAwKSByZXR1cm4gLTE7XAorCQkJfVwKKwkJCWVsc2VcCisJCQl7XAorCQkJaWYgKEpTX0RlZmluZU9iakNvbnN0KHBSdW50aW1lLCBuT2JqRGVmbklELCBKU19DbGFzc19Db25zdHNbaV0ucE5hbWUsIEpTX05ld1N0cmluZyhwUnVudGltZSxKU19DbGFzc19Db25zdHNbaV0uc3RyaW5nKSkgPCAwKSByZXR1cm4gLTE7XAorCQkJfVwKKwkJfVwKKwkJcmV0dXJuIG5PYmpEZWZuSUQ7XAorCX1cCisJcmV0dXJuIC0xO1wKK31cCit2b2lkIGpzX2NsYXNzX25hbWU6OkdldENvbnN0cyhKU0NvbnN0U3BlYyomIHBDb25zdHMsIGludCYgblNpemUpXAore1wKKwlwQ29uc3RzID0gSlNfQ2xhc3NfQ29uc3RzO1wKKwluU2l6ZSA9IHNpemVvZihKU19DbGFzc19Db25zdHMpL3NpemVvZihKU0NvbnN0U3BlYyktMTtcCit9CisKKy8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU1BFQ0lBTCBKUyBDTEFTUyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLworCisjZGVmaW5lIERFQ0xBUkVfU1BFQ0lBTF9KU19DTEFTUyhqc19jbGFzc19uYW1lKSBcCisJc3RhdGljIEpTQm9vbCBKU0NvbnN0cnVjdG9yKElGWEpTX0NvbnRleHQqIGNjLCBKU0ZYT2JqZWN0IG9iaiwgSlNGWE9iamVjdCBnbG9iYWwpO1wKKwlzdGF0aWMgSlNCb29sIEpTRGVzdHJ1Y3RvcihKU0ZYT2JqZWN0IG9iaik7XAorCXN0YXRpYyB2b2lkIEdldENvbnN0cyhKU0NvbnN0U3BlYyomIHBDb25zdHMsIGludCYgblNpemUpO1wKKwlzdGF0aWMgdm9pZCBHZXRQcm9wZXJ0aWVzKEpTUHJvcGVydHlTcGVjKiYgcFByb3BlcnRpZXMsIGludCYgblNpemUpO1wKKwlzdGF0aWMgdm9pZCBHZXRNZXRob2RzKEpTTWV0aG9kU3BlYyomIHBNZXRob2RzLCBpbnQmIG5TaXplKTtcCisJc3RhdGljIEpTQ29uc3RTcGVjIEpTX0NsYXNzX0NvbnN0c1tdO1wKKwlzdGF0aWMgSlNQcm9wZXJ0eVNwZWMgSlNfQ2xhc3NfUHJvcGVydGllc1tdO1wKKwlzdGF0aWMgSlNNZXRob2RTcGVjCUpTX0NsYXNzX01ldGhvZHNbXTtcCisJc3RhdGljIGludCBJbml0KElKU19SdW50aW1lKiBwUnVudGltZSwgRlhKU09CSlRZUEUgZU9ialR5cGUpO1wKKwlzdGF0aWMgY29uc3Qgd2NoYXJfdCogbV9wQ2xhc3NOYW1lO1wKKwlzdGF0aWMgdm9pZCBxdWVyeXByb3BfIyNqc19jbGFzc19uYW1lIyNfc3RhdGljKEpTX1BST1BRVUVSWV9BUkdTKTtcCisJc3RhdGljIHZvaWQgZ2V0cHJvcF8jI2pzX2NsYXNzX25hbWUjI19zdGF0aWMoSlNfTkFNRURfUFJPUEdFVF9BUkdTKTtcCisJc3RhdGljIHZvaWQgcHV0cHJvcF8jI2pzX2NsYXNzX25hbWUjI19zdGF0aWMoSlNfTkFNRURfUFJPUFBVVF9BUkdTKTtcCisJc3RhdGljIHZvaWQgZGVscHJvcF8jI2pzX2NsYXNzX25hbWUjI19zdGF0aWMoSlNfUFJPUERFTF9BUkdTKQorCisjZGVmaW5lIElNUExFTUVOVF9TUEVDSUFMX0pTX0NMQVNTKGpzX2NsYXNzX25hbWUsIGNsYXNzX2FsdGVybmF0ZSwgY2xhc3NfbmFtZSkgXAorY29uc3Qgd2NoYXJfdCAqIGpzX2NsYXNzX25hbWU6Om1fcENsYXNzTmFtZSA9IEpTX1dJREVTVFJJTkcoY2xhc3NfbmFtZSk7XAorCXZvaWQganNfY2xhc3NfbmFtZTo6cXVlcnlwcm9wXyMjanNfY2xhc3NfbmFtZSMjX3N0YXRpYyhKU19QUk9QUVVFUllfQVJHUylcCit7XAorCXY4OjpJc29sYXRlKiBpc29sYXRlID0gaW5mby5HZXRJc29sYXRlKCk7XAorCXY4OjpTdHJpbmc6OlV0ZjhWYWx1ZSB1dGY4X3ZhbHVlKHByb3BlcnR5KTtcCisJQ0ZYX1dpZGVTdHJpbmcgcHJvcG5hbWUgPSBDRlhfV2lkZVN0cmluZzo6RnJvbVVURjgoKnV0ZjhfdmFsdWUsIHV0ZjhfdmFsdWUubGVuZ3RoKCkpO1wKKwlDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLGluZm8uSG9sZGVyKCkpO1wKKwlBU1NFUlQocEpTT2JqICE9IE5VTEwpO1wKKwljbGFzc19hbHRlcm5hdGUqIHBPYmogPSAoY2xhc3NfYWx0ZXJuYXRlKilwSlNPYmotPkdldEVtYmVkT2JqZWN0KCk7XAorCUFTU0VSVChwT2JqICE9IE5VTEwpO1wKKwlGWF9CT09MIGJSZXQgPSBGQUxTRTtcCisJdHJ5XAorCXtcCisJCU1FTUxFQUtDSEVDS18xKCk7XAorCQliUmV0ID0gcE9iai0+UXVlcnlQcm9wZXJ0eSgoRlhfTFBDV1NUUilwcm9wbmFtZSk7XAorCQlNRU1MRUFLQ0hFQ0tfMihjbGFzc19uYW1lLCAoRlhfTFBDV1NUUilwcm9wX25hbWUpO1wKKwl9XAorCWNhdGNoICguLi4pXAorCXtcCisJCXJldHVybiA7XAorCX1cCisJaWYgKGJSZXQpXAorCXtcCisJCWluZm8uR2V0UmV0dXJuVmFsdWUoKS5TZXQoMHgwMDQpO1wKKwkJcmV0dXJuIDtcCisJfVwKKwllbHNlXAorCXtcCisJCWluZm8uR2V0UmV0dXJuVmFsdWUoKS5TZXQoMCk7XAorCQlyZXR1cm4gO1wKKwl9XAorCXJldHVybiA7XAorfVwKKwl2b2lkIGpzX2NsYXNzX25hbWU6OmdldHByb3BfIyNqc19jbGFzc19uYW1lIyNfc3RhdGljKEpTX05BTUVEX1BST1BHRVRfQVJHUylcCit7XAorCXY4OjpJc29sYXRlKiBpc29sYXRlID0gaW5mby5HZXRJc29sYXRlKCk7XAorCXY4OjpMb2NhbDx2ODo6Q29udGV4dD4gY29udGV4dCA9IGlzb2xhdGUtPkdldEN1cnJlbnRDb250ZXh0KCk7XAorCXY4OjpMb2NhbDx2ODo6VmFsdWU+IHYgPSBjb250ZXh0LT5HZXRFbWJlZGRlckRhdGEoMSk7XAorCUFTU0VSVCghdi5Jc0VtcHR5KCkpO1wKKwlpZih2LklzRW1wdHkoKSkgcmV0dXJuO1wKKwl2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD4gZmllbGQgPSB2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD46OkNhc3Qodik7XAorCUlGWEpTX1J1bnRpbWUqIHBSdW50aW1lID0gKElGWEpTX1J1bnRpbWUqKWZpZWxkLT5WYWx1ZSgpO1wKKwlJRlhKU19Db250ZXh0KiBjYyA9IHBSdW50aW1lLT5HZXRDdXJyZW50Q29udGV4dCgpO1wKKwl2ODo6U3RyaW5nOjpVdGY4VmFsdWUgdXRmOF92YWx1ZShwcm9wZXJ0eSk7XAorCUNGWF9XaWRlU3RyaW5nIHByb3BuYW1lID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21VVEY4KCp1dGY4X3ZhbHVlLCB1dGY4X3ZhbHVlLmxlbmd0aCgpKTtcCisJQ0pTX1Byb3BWYWx1ZSB2YWx1ZShpc29sYXRlKTtcCisJdmFsdWUuU3RhcnRHZXR0aW5nKCk7XAorCUNKU19PYmplY3QqIHBKU09iaiA9IChDSlNfT2JqZWN0KilKU19HZXRQcml2YXRlKGlzb2xhdGUsaW5mby5Ib2xkZXIoKSk7XAorCUFTU0VSVChwSlNPYmogIT0gTlVMTCk7XAorCWNsYXNzX2FsdGVybmF0ZSogcE9iaiA9IChjbGFzc19hbHRlcm5hdGUqKXBKU09iai0+R2V0RW1iZWRPYmplY3QoKTtcCisJQVNTRVJUKHBPYmogIT0gTlVMTCk7XAorCUpTX0Vycm9yU3RyaW5nIHNFcnJvcjtcCisJRlhfQk9PTCBiUmV0ID0gRkFMU0U7XAorCXRyeVwKKwl7XAorCQlNRU1MRUFLQ0hFQ0tfMSgpO1wKKwkJYlJldCA9IHBPYmotPkRvUHJvcGVydHkoY2MsIChGWF9MUENXU1RSKXByb3BuYW1lLCB2YWx1ZSwgc0Vycm9yKTtcCisJCU1FTUxFQUtDSEVDS18yKGNsYXNzX25hbWUsIEwiR2V0UHJvcGVydHkiKTtcCisJfVwKKwljYXRjaCAoLi4uKVwKKwl7XAorCQlDRlhfQnl0ZVN0cmluZyBjYk5hbWU7XAorCQljYk5hbWUuRm9ybWF0KCIlcy4lcyIsICNjbGFzc19uYW1lLCBMIkdldFByb3BlcnR5Iik7XAorCQlKU19FcnJvcihOVUxMLENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgTCJVbmtub3duIGVycm9yIGlzIGNhdGNoZWQhIik7XAorCQlyZXR1cm4gO1wKKwl9XAorCWlmIChiUmV0KVwKKwl7XAorCQlpbmZvLkdldFJldHVyblZhbHVlKCkuU2V0KCh2ODo6SGFuZGxlPHY4OjpWYWx1ZT4pdmFsdWUpO1wKKwkJcmV0dXJuIDtcCisJfVwKKwllbHNlXAorCXtcCisJCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcCisJCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsIEwiR2V0UHJvcGVydHkiKTtcCisJCUpTX0Vycm9yKE5VTEwsQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChjYk5hbWUpLCBzRXJyb3IpO1wKKwkJcmV0dXJuIDtcCisJfVwKKwlKU19FcnJvcihOVUxMLEwiR2V0UHJvcGVydHkiLCBMIkVtYmVkZWQgb2JqZWN0IG5vdCBmb3VuZCEiKTtcCisJcmV0dXJuIDtcCit9XAorCXZvaWQganNfY2xhc3NfbmFtZTo6cHV0cHJvcF8jI2pzX2NsYXNzX25hbWUjI19zdGF0aWMoSlNfTkFNRURfUFJPUFBVVF9BUkdTKVwKK3tcCisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBpbmZvLkdldElzb2xhdGUoKTtcCisJdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gaXNvbGF0ZS0+R2V0Q3VycmVudENvbnRleHQoKTtcCisJdjg6OkxvY2FsPHY4OjpWYWx1ZT4gdiA9IGNvbnRleHQtPkdldEVtYmVkZGVyRGF0YSgxKTtcCisJQVNTRVJUKCF2LklzRW1wdHkoKSk7XAorCWlmKHYuSXNFbXB0eSgpKSByZXR1cm47XAorCXY4OjpIYW5kbGU8djg6OkV4dGVybmFsPiBmaWVsZCA9IHY4OjpIYW5kbGU8djg6OkV4dGVybmFsPjo6Q2FzdCh2KTtcCisJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSAoSUZYSlNfUnVudGltZSopZmllbGQtPlZhbHVlKCk7XAorCUlGWEpTX0NvbnRleHQqIGNjID0gcFJ1bnRpbWUtPkdldEN1cnJlbnRDb250ZXh0KCk7XAorCXY4OjpTdHJpbmc6OlV0ZjhWYWx1ZSB1dGY4X3ZhbHVlKHByb3BlcnR5KTtcCisJQ0ZYX1dpZGVTdHJpbmcgcHJvcG5hbWUgPSBDRlhfV2lkZVN0cmluZzo6RnJvbVVURjgoKnV0ZjhfdmFsdWUsIHV0ZjhfdmFsdWUubGVuZ3RoKCkpO1wKKwlDSlNfUHJvcFZhbHVlIFByb3BWYWx1ZShDSlNfVmFsdWUoaXNvbGF0ZSx2YWx1ZSxWVF91bmtub3duKSk7XAorCVByb3BWYWx1ZS5TdGFydFNldHRpbmcoKTtcCisJQ0pTX09iamVjdCogcEpTT2JqID0gKENKU19PYmplY3QqKUpTX0dldFByaXZhdGUoaXNvbGF0ZSxpbmZvLkhvbGRlcigpKTtcCisJaWYoIXBKU09iaikgcmV0dXJuO1wKKwljbGFzc19hbHRlcm5hdGUqIHBPYmogPSAoY2xhc3NfYWx0ZXJuYXRlKilwSlNPYmotPkdldEVtYmVkT2JqZWN0KCk7XAorCUFTU0VSVChwT2JqICE9IE5VTEwpO1wKKwlKU19FcnJvclN0cmluZyBzRXJyb3I7XAorCUZYX0JPT0wgYlJldCA9IEZBTFNFO1wKKwl0cnlcCisJe1wKKwkJTUVNTEVBS0NIRUNLXzEoKTtcCisJCWJSZXQgPSBwT2JqLT5Eb1Byb3BlcnR5KGNjLCAoRlhfTFBDV1NUUilwcm9wbmFtZSwgUHJvcFZhbHVlLCBzRXJyb3IpO1wKKwkJTUVNTEVBS0NIRUNLXzIoY2xhc3NfbmFtZSxMIlB1dFByb3BlcnR5Iik7XAorCX1cCisJY2F0Y2ggKC4uLilcCisJe1wKKwkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wKKwkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgIlB1dFByb3BlcnR5Iik7XAorCQlKU19FcnJvcihOVUxMLENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgTCJVbmtub3duIGVycm9yIGlzIGNhdGNoZWQhIik7XAorCQlyZXR1cm4gO1wKKwl9XAorCWlmIChiUmV0KVwKKwl7XAorCQlyZXR1cm4gO1wKKwl9XAorCWVsc2VcCisJe1wKKwkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wKKwkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgIlB1dFByb3BlcnR5Iik7XAorCQlKU19FcnJvcihOVUxMLENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgc0Vycm9yKTtcCisJCXJldHVybiA7XAorCX1cCisJSlNfRXJyb3IoTlVMTCxMIlB1dFByb3BlcnR5IiwgTCJFbWJlZGVkIG9iamVjdCBub3QgZm91bmQhIik7XAorCXJldHVybiA7XAorfVwKKwl2b2lkIGpzX2NsYXNzX25hbWU6OmRlbHByb3BfIyNqc19jbGFzc19uYW1lIyNfc3RhdGljKEpTX1BST1BERUxfQVJHUylcCit7XAorCXY4OjpJc29sYXRlKiBpc29sYXRlID0gaW5mby5HZXRJc29sYXRlKCk7XAorCXY4OjpMb2NhbDx2ODo6Q29udGV4dD4gY29udGV4dCA9IGlzb2xhdGUtPkdldEN1cnJlbnRDb250ZXh0KCk7XAorCXY4OjpMb2NhbDx2ODo6VmFsdWU+IHYgPSBjb250ZXh0LT5HZXRFbWJlZGRlckRhdGEoMSk7XAorCUFTU0VSVCghdi5Jc0VtcHR5KCkpO1wKKwlpZih2LklzRW1wdHkoKSkgcmV0dXJuO1wKKwl2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD4gZmllbGQgPSB2ODo6SGFuZGxlPHY4OjpFeHRlcm5hbD46OkNhc3Qodik7XAorCUlGWEpTX1J1bnRpbWUqIHBSdW50aW1lID0gKElGWEpTX1J1bnRpbWUqKWZpZWxkLT5WYWx1ZSgpO1wKKwlJRlhKU19Db250ZXh0KiBjYyA9IHBSdW50aW1lLT5HZXRDdXJyZW50Q29udGV4dCgpO1wKKwl2ODo6U3RyaW5nOjpVdGY4VmFsdWUgdXRmOF92YWx1ZShwcm9wZXJ0eSk7XAorCUNGWF9XaWRlU3RyaW5nIHByb3BuYW1lID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21VVEY4KCp1dGY4X3ZhbHVlLCB1dGY4X3ZhbHVlLmxlbmd0aCgpKTtcCisJQ0pTX09iamVjdCogcEpTT2JqID0gKENKU19PYmplY3QqKUpTX0dldFByaXZhdGUoaXNvbGF0ZSxpbmZvLkhvbGRlcigpKTtcCisJQVNTRVJUKHBKU09iaiAhPSBOVUxMKTtcCisJY2xhc3NfYWx0ZXJuYXRlKiBwT2JqID0gKGNsYXNzX2FsdGVybmF0ZSopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpO1wKKwlBU1NFUlQocE9iaiAhPSBOVUxMKTtcCisJSlNfRXJyb3JTdHJpbmcgc0Vycm9yO1wKKwlGWF9CT09MIGJSZXQgPSBGQUxTRTtcCisJdHJ5XAorCXtcCisJCU1FTUxFQUtDSEVDS18xKCk7XAorCQliUmV0ID0gcE9iai0+RGVsUHJvcGVydHkoY2MsIChGWF9MUENXU1RSKXByb3BuYW1lLCBzRXJyb3IpO1wKKwkJTUVNTEVBS0NIRUNLXzIoY2xhc3NfbmFtZSxMIkRlbFByb3BlcnR5Iik7XAorCX1cCisJY2F0Y2ggKC4uLilcCisJe1wKKwkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wKKwkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgIkRlbFByb3BlcnR5Iik7XAorCQlyZXR1cm4gO1wKKwl9XAorCWlmIChiUmV0KVwKKwl7XAorCQlyZXR1cm4gO1wKKwl9XAorCWVsc2VcCisJe1wKKwkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wKKwkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgIkRlbFByb3BlcnR5Iik7XAorCQlyZXR1cm4gO1wKKwl9XAorCXJldHVybiA7XAorfVwKK0pTQm9vbCBqc19jbGFzc19uYW1lOjpKU0NvbnN0cnVjdG9yKElGWEpTX0NvbnRleHQqIGNjLCBKU0ZYT2JqZWN0ICBvYmosSlNGWE9iamVjdCAgZ2xvYmFsKVwKK3tcCisJQ0pTX09iamVjdCogcE9iaiA9IEZYX05FVyBqc19jbGFzc19uYW1lKG9iaik7XAorCXBPYmotPlNldEVtYmVkT2JqZWN0KEZYX05FVyBjbGFzc19hbHRlcm5hdGUocE9iaikpO1wKKwlKU19TZXRQcml2YXRlKE5VTEwsb2JqLCAodm9pZCopcE9iaik7IFwKKwlwT2JqLT5Jbml0SW5zdGFuY2UoY2MpO1wKKwlyZXR1cm4gSlNfVFJVRTtcCit9XAorXAorSlNCb29sIGpzX2NsYXNzX25hbWU6OkpTRGVzdHJ1Y3RvcihKU0ZYT2JqZWN0IG9iaikgXAore1wKKwlqc19jbGFzc19uYW1lKiBwT2JqID0gKGpzX2NsYXNzX25hbWUqKUpTX0dldFByaXZhdGUoTlVMTCxvYmopO1wKKwlBU1NFUlQocE9iaiAhPSBOVUxMKTtcCisJcE9iai0+RXhpdEluc3RhbmNlKCk7XAorCWRlbGV0ZSBwT2JqO1wKKwlyZXR1cm4gSlNfVFJVRTtcCit9XAorXAoraW50IGpzX2NsYXNzX25hbWU6OkluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lLCBGWEpTT0JKVFlQRSBlT2JqVHlwZSlcCit7XAorXAorCWludCBuT2JqRGVmbklEID0gSlNfRGVmaW5lT2JqKHBSdW50aW1lLCBqc19jbGFzc19uYW1lOjptX3BDbGFzc05hbWUsIGVPYmpUeXBlLCBKU0NvbnN0cnVjdG9yLCBKU0Rlc3RydWN0b3IsIDApO1wKK1wKKwlpZiAobk9iakRlZm5JRCA+PSAwKVwKKwl7XAorCQlmb3IgKGludCBqPTAsIHN6aj1zaXplb2YoSlNfQ2xhc3NfUHJvcGVydGllcykvc2l6ZW9mKEpTUHJvcGVydHlTcGVjKS0xOyBqPHN6ajsgaisrKVwKKwkJe1wKKwkJCWlmIChKU19EZWZpbmVPYmpQcm9wZXJ0eShwUnVudGltZSwgbk9iakRlZm5JRCwgSlNfQ2xhc3NfUHJvcGVydGllc1tqXS5wTmFtZSwgSlNfQ2xhc3NfUHJvcGVydGllc1tqXS5wUHJvcEdldCxKU19DbGFzc19Qcm9wZXJ0aWVzW2pdLnBQcm9wUHV0KTwwKXJldHVybiAtMTtcCisJCX1cCitcCisJCWZvciAoaW50IGs9MCwgc3prPXNpemVvZihKU19DbGFzc19NZXRob2RzKS9zaXplb2YoSlNNZXRob2RTcGVjKS0xOyBrPHN6azsgaysrKVwKKwkJe1wKKwkJCWlmIChKU19EZWZpbmVPYmpNZXRob2QocFJ1bnRpbWUsIG5PYmpEZWZuSUQsSlNfQ2xhc3NfTWV0aG9kc1trXS5wTmFtZSxKU19DbGFzc19NZXRob2RzW2tdLnBNZXRob2RDYWxsLEpTX0NsYXNzX01ldGhvZHNba10ublBhcmFtTnVtKTwwKXJldHVybiAtMTtcCisJCX1cCisJCWlmIChKU19EZWZpbmVPYmpBbGxQcm9wZXJ0aWVzKHBSdW50aW1lLCBuT2JqRGVmbklELCBqc19jbGFzc19uYW1lOjpxdWVyeXByb3BfIyNqc19jbGFzc19uYW1lIyNfc3RhdGljLCBqc19jbGFzc19uYW1lOjpnZXRwcm9wXyMjanNfY2xhc3NfbmFtZSMjX3N0YXRpYyxqc19jbGFzc19uYW1lOjpwdXRwcm9wXyMjanNfY2xhc3NfbmFtZSMjX3N0YXRpYyxqc19jbGFzc19uYW1lOjpkZWxwcm9wXyMjanNfY2xhc3NfbmFtZSMjX3N0YXRpYyk8MCkgcmV0dXJuIC0xO1wKK1wKKwkJcmV0dXJuIG5PYmpEZWZuSUQ7XAorCX1cCitcCisJcmV0dXJuIC0xO1wKK31cCit2b2lkIGpzX2NsYXNzX25hbWU6OkdldENvbnN0cyhKU0NvbnN0U3BlYyomIHBDb25zdHMsIGludCYgblNpemUpXAore1wKKwlwQ29uc3RzID0gSlNfQ2xhc3NfQ29uc3RzO1wKKwluU2l6ZSA9IHNpemVvZihKU19DbGFzc19Db25zdHMpL3NpemVvZihKU0NvbnN0U3BlYyktMTtcCit9XAordm9pZCBqc19jbGFzc19uYW1lOjpHZXRQcm9wZXJ0aWVzKEpTUHJvcGVydHlTcGVjKiYgcFByb3BlcnRpZXMsIGludCYgblNpemUpXAore1wKKwlwUHJvcGVydGllcyA9IEpTX0NsYXNzX1Byb3BlcnRpZXM7XAorCW5TaXplID0gc2l6ZW9mKEpTX0NsYXNzX1Byb3BlcnRpZXMpL3NpemVvZihKU1Byb3BlcnR5U3BlYyktMTtcCit9XAordm9pZCBqc19jbGFzc19uYW1lOjpHZXRNZXRob2RzKEpTTWV0aG9kU3BlYyomIHBNZXRob2RzLCBpbnQmIG5TaXplKVwKK3tcCisJcE1ldGhvZHMgPSBKU19DbGFzc19NZXRob2RzO1wKKwluU2l6ZSA9IHNpemVvZihKU19DbGFzc19NZXRob2RzKS9zaXplb2YoSlNNZXRob2RTcGVjKS0xO1wKK30KKworI2RlZmluZSBKU19TUEVDSUFMX1NUQVRJQ19NRVRIT0QobWV0aG9kX25hbWUsIGNsYXNzX2FsdGVybmF0ZSwgY2xhc3NfbmFtZSlcCisJc3RhdGljIHZvaWQgbWV0aG9kX25hbWUjI19zdGF0aWMoSlNfTUVUSE9EX0FSR1MpXAore1wKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IGluZm8uR2V0SXNvbGF0ZSgpO1wKKwl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPSBpc29sYXRlLT5HZXRDdXJyZW50Q29udGV4dCgpO1wKKwl2ODo6TG9jYWw8djg6OlZhbHVlPiB2ID0gY29udGV4dC0+R2V0RW1iZWRkZXJEYXRhKDEpO1wKKwlBU1NFUlQoIXYuSXNFbXB0eSgpKTtcCisJaWYodi5Jc0VtcHR5KCkpIHJldHVybjtcCisJdjg6OkhhbmRsZTx2ODo6RXh0ZXJuYWw+IGZpZWxkID0gdjg6OkhhbmRsZTx2ODo6RXh0ZXJuYWw+OjpDYXN0KHYpO1wKKwlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IChJRlhKU19SdW50aW1lKilmaWVsZC0+VmFsdWUoKTtcCisJSUZYSlNfQ29udGV4dCogY2MgPSBwUnVudGltZS0+R2V0Q3VycmVudENvbnRleHQoKTtcCisJQ0pTX1BhcmFtZXRlcnMgcGFyYW1ldGVycztcCisJZm9yICh1bnNpZ25lZCBpbnQgaSA9IDA7IGk8KHVuc2lnbmVkIGludClpbmZvLkxlbmd0aCgpOyBpKyspXAorCXtcCisJcGFyYW1ldGVycy5wdXNoX2JhY2soQ0pTX1ZhbHVlKGlzb2xhdGUsIGluZm9baV0sIFZUX3Vua25vd24pKTtcCisJfVwKKwlDSlNfVmFsdWUgdmFsdWVSZXMoaXNvbGF0ZSk7XAorCUNKU19PYmplY3QqIHBKU09iaiA9IChDSlNfT2JqZWN0ICopSlNfR2V0UHJpdmF0ZShpc29sYXRlLCBpbmZvLkhvbGRlcigpKTtcCisJQVNTRVJUKHBKU09iaiAhPSBOVUxMKTtcCisJY2xhc3NfYWx0ZXJuYXRlKiBwT2JqID0gKGNsYXNzX2FsdGVybmF0ZSopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpO1wKKwlBU1NFUlQocE9iaiAhPSBOVUxMKTtcCisJSlNfRXJyb3JTdHJpbmcgc0Vycm9yO1wKKwlGWF9CT09MIGJSZXQgPSBGQUxTRTtcCisJdHJ5XAorCXtcCisJCU1FTUxFQUtDSEVDS18xKCk7XAorCQliUmV0ID0gcE9iai0+bWV0aG9kX25hbWUoY2MsIHBhcmFtZXRlcnMsIHZhbHVlUmVzLCBzRXJyb3IpO1wKKwkJTUVNTEVBS0NIRUNLXzIoY2xhc3NfbmFtZSwgbWV0aG9kX25hbWUpO1wKKwl9XAorCWNhdGNoICguLi4pXAorCXtcCisJCUNGWF9CeXRlU3RyaW5nIGNiTmFtZTtcCisJCWNiTmFtZS5Gb3JtYXQoIiVzLiVzIiwgI2NsYXNzX25hbWUsICNtZXRob2RfbmFtZSk7XAorCQlKU19FcnJvcihOVUxMLCBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNiTmFtZSksIEwiVW5rbm93biBlcnJvciBpcyBjYXRjaGVkISIpO1wKKwkJcmV0dXJuIDtcCisJfVwKKwlpZiAoYlJldClcCisJe1wKKwkJaW5mby5HZXRSZXR1cm5WYWx1ZSgpLlNldCh2YWx1ZVJlcy5Ub0pTVmFsdWUoKSk7XAorCQlyZXR1cm4gO1wKKwl9XAorCWVsc2VcCisJe1wKKwkJQ0ZYX0J5dGVTdHJpbmcgY2JOYW1lO1wKKwkJY2JOYW1lLkZvcm1hdCgiJXMuJXMiLCAjY2xhc3NfbmFtZSwgI21ldGhvZF9uYW1lKTtcCisJCUpTX0Vycm9yKE5VTEwsIENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY2JOYW1lKSwgc0Vycm9yKTtcCisJCXJldHVybiA7XAorCX1cCisJSlNfRXJyb3IoTlVMTCwgIEpTX1dJREVTVFJJTkcobWV0aG9kX25hbWUpLCBMIkVtYmVkZWQgb2JqZWN0IG5vdCBmb3VuZCEiKTtcCisgICAgcmV0dXJuIDtcCit9CisKKy8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gR0xPQkFMIE1FVEhPRFMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KKyNkZWZpbmUgSlNfU1RBVElDX0dMT0JBTF9GVU4oZnVuX25hbWUpIFwKK3N0YXRpYyB2b2lkIGZ1bl9uYW1lIyNfc3RhdGljKEpTX01FVEhPRF9BUkdTKVwKK3tcCisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBpbmZvLkdldElzb2xhdGUoKTtcCisJdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gaXNvbGF0ZS0+R2V0Q3VycmVudENvbnRleHQoKTtcCisJdjg6OkxvY2FsPHY4OjpWYWx1ZT4gdiA9IGNvbnRleHQtPkdldEVtYmVkZGVyRGF0YSgxKTtcCisJQVNTRVJUKCF2LklzRW1wdHkoKSk7XAorCWlmKHYuSXNFbXB0eSgpKSByZXR1cm47XAorCXY4OjpIYW5kbGU8djg6OkV4dGVybmFsPiBmaWVsZCA9IHY4OjpIYW5kbGU8djg6OkV4dGVybmFsPjo6Q2FzdCh2KTtcCisJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSAoSUZYSlNfUnVudGltZSopZmllbGQtPlZhbHVlKCk7XAorCUlGWEpTX0NvbnRleHQqIGNjID0gcFJ1bnRpbWUtPkdldEN1cnJlbnRDb250ZXh0KCk7XAorCUNKU19QYXJhbWV0ZXJzIHBhcmFtZXRlcnM7XAorCWZvciAodW5zaWduZWQgaW50IGkgPSAwOyBpPCh1bnNpZ25lZCBpbnQpaW5mby5MZW5ndGgoKTsgaSsrKVwKKwl7XAorCXBhcmFtZXRlcnMucHVzaF9iYWNrKENKU19WYWx1ZShpc29sYXRlLCBpbmZvW2ldLCBWVF91bmtub3duKSk7XAorCX1cCisJQ0pTX1ZhbHVlIHZhbHVlUmVzKGlzb2xhdGUpO1wKKwlKU19FcnJvclN0cmluZyBzRXJyb3I7XAorCWlmICghZnVuX25hbWUoY2MsIHBhcmFtZXRlcnMsIHZhbHVlUmVzLCBzRXJyb3IpKVwKKwl7XAorCQlKU19FcnJvcihOVUxMLCBKU19XSURFU1RSSU5HKGZ1bl9uYW1lKSwgc0Vycm9yKTtcCisJCXJldHVybiA7XAorCX1cCisJaW5mby5HZXRSZXR1cm5WYWx1ZSgpLlNldCh2YWx1ZVJlcy5Ub0pTVmFsdWUoKSk7XAorCXJldHVybiA7XAorfQorCisjZGVmaW5lIEpTX1NUQVRJQ19ERUNMQVJFX0dMT0JBTF9GVU4oKSBcCitzdGF0aWMgSlNNZXRob2RTcGVjCWdsb2JhbF9tZXRob2RzW107IFwKK3N0YXRpYyBpbnQgSW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUpCisKKyNkZWZpbmUgQkVHSU5fSlNfU1RBVElDX0dMT0JBTF9GVU4oanNfY2xhc3NfbmFtZSkgXAorSlNNZXRob2RTcGVjIGpzX2NsYXNzX25hbWU6Omdsb2JhbF9tZXRob2RzW10gPSB7CisKKyNkZWZpbmUgSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkobWV0aG9kX25hbWUsbmFyZ3MpIEpTX1NUQVRJQ19NRVRIT0RfRU5UUlkobWV0aG9kX25hbWUsbmFyZ3MpCisKKyNkZWZpbmUgRU5EX0pTX1NUQVRJQ19HTE9CQUxfRlVOKCkgRU5EX0pTX1NUQVRJQ19NRVRIT0QoKQorCisjZGVmaW5lIElNUExFTUVOVF9KU19TVEFUSUNfR0xPQkFMX0ZVTihqc19jbGFzc19uYW1lKSBcCitpbnQganNfY2xhc3NfbmFtZTo6SW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUpXAore1wKKwlmb3IgKGludCBpPTAsIHN6PXNpemVvZihqc19jbGFzc19uYW1lOjpnbG9iYWxfbWV0aG9kcykvc2l6ZW9mKEpTTWV0aG9kU3BlYyktMTsgaTxzejsgaSsrKVwKKwl7XAorCQlpZiAoSlNfRGVmaW5lR2xvYmFsTWV0aG9kKHBSdW50aW1lLFwKKwkJCQlqc19jbGFzc19uYW1lOjpnbG9iYWxfbWV0aG9kc1tpXS5wTmFtZSxcCisJCQkJanNfY2xhc3NfbmFtZTo6Z2xvYmFsX21ldGhvZHNbaV0ucE1ldGhvZENhbGwsXAorCQkJCWpzX2NsYXNzX25hbWU6Omdsb2JhbF9tZXRob2RzW2ldLm5QYXJhbU51bVwKKwkJCQkpIDwgMFwKKwkJCSlyZXR1cm4gLTE7XAorCX1cCisJcmV0dXJuIDA7XAorfQorCisvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IEdMT0JBTCBDT05TVFMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KKyNkZWZpbmUgREVGSU5FX0dMT0JBTF9DT05TVChwUnVudGltZSwgY29uc3RfbmFtZSAsIGNvbnN0X3ZhbHVlKVwKK2lmIChKU19EZWZpbmVHbG9iYWxDb25zdChwUnVudGltZSxKU19XSURFU1RSSU5HKGNvbnN0X25hbWUpLEpTX05ld1N0cmluZyhwUnVudGltZSxKU19XSURFU1RSSU5HKGNvbnN0X3ZhbHVlKSkpKSByZXR1cm4gLTEKKworLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBHTE9CQUwgQVJSQVlTID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCisKKyNkZWZpbmUgREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSlcCitpbnQgc2l6ZSA9IHNpemVvZihBcnJheUNvbnRlbnQpIC8gc2l6ZW9mKEZYX0xQQ1dTVFIpO1wKK1wKK0NKU19BcnJheSBhcnJheShwUnVudGltZSk7XAorZm9yIChpbnQgaT0wOyBpPHNpemU7IGkrKykgYXJyYXkuU2V0RWxlbWVudChpLENKU19WYWx1ZShwUnVudGltZSwoRlhfTFBDV1NUUilBcnJheUNvbnRlbnRbaV0pKTtcCitcCitDSlNfUHJvcFZhbHVlIHByb3AocFJ1bnRpbWUpO1wKK3Byb3AgPDwgYXJyYXk7XAoraWYgKEpTX0RlZmluZUdsb2JhbENvbnN0KHBSdW50aW1lLCAoY29uc3Qgd2NoYXJfdCopQXJyYXlOYW1lLCBwcm9wLlRvSlNWYWx1ZSgpKSA8IDApXAorCXJldHVybiAtMQorCisvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KKworI2RlZmluZSBWQUxVRV9OQU1FX1NUUklORwkJTCJzdHJpbmciCisjZGVmaW5lIFZBTFVFX05BTUVfTlVNQkVSCQlMIm51bWJlciIKKyNkZWZpbmUgVkFMVUVfTkFNRV9CT09MRUFOCQlMImJvb2xlYW4iCisjZGVmaW5lIFZBTFVFX05BTUVfREFURQkJCUwiZGF0ZSIKKyNkZWZpbmUgVkFMVUVfTkFNRV9PQkpFQ1QJCUwib2JqZWN0IgorI2RlZmluZSBWQUxVRV9OQU1FX0ZYT0JKCQlMImZ4b2JqIgorI2RlZmluZSBWQUxVRV9OQU1FX05VTEwJCQlMIm51bGwiCisjZGVmaW5lIFZBTFVFX05BTUVfVU5ERUZJTkVECUwidW5kZWZpbmVkIgorCisjZGVmaW5lIENMQVNTTkFNRV9BUlJBWQkJCUwiQXJyYXkiCisjZGVmaW5lIENMQVNTTkFNRV9EQVRFCQkJTCJEYXRlIgorI2RlZmluZSBDTEFTU05BTUVfU1RSSU5HCQlMInY4OjpTdHJpbmciCisKK2NvbnN0IHVuc2lnbmVkIGludCBKU0NPTlNUX25TdHJpbmdIYXNoID0gSlNfQ2FsY0hhc2goVkFMVUVfTkFNRV9TVFJJTkcsd2NzbGVuKFZBTFVFX05BTUVfU1RSSU5HKSk7Citjb25zdCB1bnNpZ25lZCBpbnQgSlNDT05TVF9uTnVtYmVySGFzaCA9IEpTX0NhbGNIYXNoKFZBTFVFX05BTUVfTlVNQkVSLHdjc2xlbihWQUxVRV9OQU1FX05VTUJFUikpOworY29uc3QgdW5zaWduZWQgaW50IEpTQ09OU1RfbkJvb2xIYXNoID0gSlNfQ2FsY0hhc2goVkFMVUVfTkFNRV9CT09MRUFOLHdjc2xlbihWQUxVRV9OQU1FX0JPT0xFQU4pKTsKK2NvbnN0IHVuc2lnbmVkIGludCBKU0NPTlNUX25EYXRlSGFzaCA9IEpTX0NhbGNIYXNoKFZBTFVFX05BTUVfREFURSx3Y3NsZW4oVkFMVUVfTkFNRV9EQVRFKSk7Citjb25zdCB1bnNpZ25lZCBpbnQgSlNDT05TVF9uT2JqZWN0SGFzaCA9IEpTX0NhbGNIYXNoKFZBTFVFX05BTUVfT0JKRUNULHdjc2xlbihWQUxVRV9OQU1FX09CSkVDVCkpOworY29uc3QgdW5zaWduZWQgaW50IEpTQ09OU1RfbkZYb2JqSGFzaCA9IEpTX0NhbGNIYXNoKFZBTFVFX05BTUVfRlhPQkosd2NzbGVuKFZBTFVFX05BTUVfRlhPQkopKTsKK2NvbnN0IHVuc2lnbmVkIGludCBKU0NPTlNUX25OdWxsSGFzaCA9IEpTX0NhbGNIYXNoKFZBTFVFX05BTUVfTlVMTCx3Y3NsZW4oVkFMVUVfTkFNRV9OVUxMKSk7Citjb25zdCB1bnNpZ25lZCBpbnQgSlNDT05TVF9uVW5kZWZIYXNoID0gSlNfQ2FsY0hhc2goVkFMVUVfTkFNRV9VTkRFRklORUQsd2NzbGVuKFZBTFVFX05BTUVfVU5ERUZJTkVEKSk7CisKK3N0YXRpYyBGWEpTVkFMVUVUWVBFIEdFVF9WQUxVRV9UWVBFKHY4OjpIYW5kbGU8djg6OlZhbHVlPiBwKQoreworCisJCWNvbnN0IHVuc2lnbmVkIGludCBuSGFzaCA9IEpTX0NhbGNIYXNoKEpTX0dldFR5cGVvZihwKSk7CisKKwkJaWYgKG5IYXNoID09IEpTQ09OU1RfblVuZGVmSGFzaCkKKwkJCXJldHVybiBWVF91bmRlZmluZWQ7CisJCWVsc2UgaWYgKG5IYXNoID09IEpTQ09OU1Rfbk51bGxIYXNoKQorCQkJcmV0dXJuIFZUX251bGw7CisJCWVsc2UgaWYgKG5IYXNoID09IEpTQ09OU1RfblN0cmluZ0hhc2gpCisJCQlyZXR1cm4gVlRfc3RyaW5nOworCQllbHNlIGlmIChuSGFzaCA9PSBKU0NPTlNUX25OdW1iZXJIYXNoKQorCQkJcmV0dXJuIFZUX251bWJlcjsKKwkJZWxzZSBpZiAobkhhc2ggPT0gSlNDT05TVF9uQm9vbEhhc2gpCisJCQlyZXR1cm4gVlRfYm9vbGVhbjsKKwkJZWxzZSBpZiAobkhhc2ggPT0gSlNDT05TVF9uRGF0ZUhhc2gpCisJCQlyZXR1cm4gVlRfZGF0ZTsKKwkJZWxzZSBpZiAobkhhc2ggPT0gSlNDT05TVF9uT2JqZWN0SGFzaCkKKwkJCXJldHVybiBWVF9vYmplY3Q7CQkKKwkJZWxzZSBpZiAobkhhc2ggPT0gSlNDT05TVF9uRlhvYmpIYXNoKQorCQkJcmV0dXJuIFZUX2Z4b2JqZWN0OworCisJCS8qCisJCWNvbnN0IGNoYXIgKiBzVHlwZSA9IHAtPmdldFR5cGVvZigpLT50b0RjaGFycygpOworCQlpZiAoc3RyY21wKHNUeXBlLFZBTFVFX05BTUVfU1RSSU5HKSA9PSAwKQorCQkJcmV0dXJuIFZUX3N0cmluZzsKKwkJZWxzZSBpZiAoc3RyY21wKHNUeXBlLFZBTFVFX05BTUVfTlVNQkVSKSA9PSAwKQorCQkJcmV0dXJuIFZUX251bWJlcjsKKwkJZWxzZSBpZiAoc3RyY21wKHNUeXBlLFZBTFVFX05BTUVfQk9PTEVBTikgPT0gMCkKKwkJCXJldHVybiBWVF9ib29sZWFuOworCQllbHNlIGlmIChzdHJjbXAoc1R5cGUsVkFMVUVfTkFNRV9EQVRFKSA9PSAwKQorCQkJcmV0dXJuIFZUX2RhdGU7CisJCWVsc2UgaWYgKHN0cmNtcChzVHlwZSxWQUxVRV9OQU1FX09CSkVDVCkgPT0gMCkKKwkJCXJldHVybiBWVF9vYmplY3Q7CisJCWVsc2UgaWYgKHN0cmNtcChzVHlwZSxWQUxVRV9OQU1FX0ZYT0JKKSA9PSAwKQorCQkJcmV0dXJuIFZUX29iamVjdDsKKwkJZWxzZSBpZiAoc3RyY21wKHNUeXBlLFZBTFVFX05BTUVfTlVMTCkgPT0gMCkKKwkJCXJldHVybiBWVF9udWxsOworCQllbHNlIGlmIChzdHJjbXAoc1R5cGUsVkFMVUVfTkFNRV9VTkRFRklORUQpID09IDApCisJCQlyZXR1cm4gVlRfdW5kZWZpbmVkOworCQkJKi8KKworCXJldHVybiBWVF91bmtub3duOworfQorCisjZW5kaWYgLy9fSlNfREVGSU5FX0hfCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oCmluZGV4IGQ4OGM1MGMuLmQxNjkzM2EgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oCkBAIC0xLDE2NyArMSwxNjcgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0pTX0VWRU5USEFORExFUl9IXw0KLSNkZWZpbmUgX0pTX0VWRU5USEFORExFUl9IXw0KLQ0KLWNsYXNzIENKU19Db250ZXh0Ow0KLWNsYXNzIEZpZWxkOw0KLQ0KLWVudW0gSlNfRVZFTlRfVA0KLXsNCi0JSkVUX1VOS05PV04sDQotCUpFVF9BUFBfSU5JVCwNCi0JSkVUX0RPQ19PUEVOLA0KLQlKRVRfRE9DX1dJTExQUklOVCwNCi0JSkVUX0RPQ19ESURQUklOVCwNCi0JSkVUX0RPQ19XSUxMU0FWRSwNCi0JSkVUX0RPQ19ESURTQVZFLA0KLQlKRVRfRE9DX1dJTExDTE9TRSwNCi0JSkVUX1BBR0VfT1BFTiwNCi0JSkVUX1BBR0VfQ0xPU0UsDQotCUpFVF9QQUdFX0lOVklFVywNCi0JSkVUX1BBR0VfT1VUVklFVywNCi0JSkVUX0ZJRUxEX01PVVNFRE9XTiwNCi0JSkVUX0ZJRUxEX01PVVNFVVAsDQotCUpFVF9GSUVMRF9NT1VTRUVOVEVSLA0KLQlKRVRfRklFTERfTU9VU0VFWElULA0KLQlKRVRfRklFTERfRk9DVVMsDQotCUpFVF9GSUVMRF9CTFVSLA0KLQlKRVRfRklFTERfS0VZU1RST0tFLA0KLQlKRVRfRklFTERfVkFMSURBVEUsDQotCUpFVF9GSUVMRF9DQUxDVUxBVEUsDQotCUpFVF9GSUVMRF9GT1JNQVQsDQotCUpFVF9TQ1JFRU5fRk9DVVMsDQotCUpFVF9TQ1JFRU5fQkxVUiwNCi0JSkVUX1NDUkVFTl9PUEVOLA0KLQlKRVRfU0NSRUVOX0NMT1NFLA0KLQlKRVRfU0NSRUVOX01PVVNFRE9XTiwNCi0JSkVUX1NDUkVFTl9NT1VTRVVQLA0KLQlKRVRfU0NSRUVOX01PVVNFRU5URVIsDQotCUpFVF9TQ1JFRU5fTU9VU0VFWElULA0KLQlKRVRfU0NSRUVOX0lOVklFVywNCi0JSkVUX1NDUkVFTl9PVVRWSUVXLA0KLQlKRVRfQkFUQ0hfRVhFQywNCi0JSkVUX01FTlVfRVhFQywNCi0JSkVUX0NPTlNPTEVfRVhFQywNCi0JSkVUX0VYVEVSTkFMX0VYRUMsDQotCUpFVF9CT09LTUFSS19NT1VTRVVQLA0KLQlKRVRfTElOS19NT1VTRVVQDQotfTsNCi0NCi1jbGFzcyBDSlNfRXZlbnRIYW5kbGVyDQotew0KLXB1YmxpYzoNCi0JQ0pTX0V2ZW50SGFuZGxlcihDSlNfQ29udGV4dCAqIHBDb250ZXh0KTsNCi0JdmlydHVhbCB+Q0pTX0V2ZW50SGFuZGxlcigpOw0KLQ0KLQl2b2lkCQkJCQlPbkFwcF9Jbml0KCk7DQotDQotCXZvaWQJCQkJCU9uRG9jX09wZW4oQ1BERlNES19Eb2N1bWVudCogcERvYywgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0clRhcmdldE5hbWUpOw0KLQl2b2lkCQkJCQlPbkRvY19XaWxsUHJpbnQoQ1BERlNES19Eb2N1bWVudCogcERvYyk7DQotCXZvaWQJCQkJCU9uRG9jX0RpZFByaW50KENQREZTREtfRG9jdW1lbnQqIHBEb2MpOw0KLQl2b2lkCQkJCQlPbkRvY19XaWxsU2F2ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsNCi0Jdm9pZAkJCQkJT25Eb2NfRGlkU2F2ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsNCi0Jdm9pZAkJCQkJT25Eb2NfV2lsbENsb3NlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOw0KLQ0KLQl2b2lkCQkJCQlPblBhZ2VfT3BlbihDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsNCi0Jdm9pZAkJCQkJT25QYWdlX0Nsb3NlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOw0KLQl2b2lkCQkJCQlPblBhZ2VfSW5WaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpOw0KLQl2b2lkCQkJCQlPblBhZ2VfT3V0VmlldyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KTsNCi0JDQotCXZvaWQJCQkJCU9uRmllbGRfQ2FsY3VsYXRlKENQREZfRm9ybUZpZWxkKiBwU291cmNlLCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MJiBiUmMpOw0KLQl2b2lkCQkJCQlPbkZpZWxkX0Zvcm1hdChpbnQgbkNvbW1pdEtleSwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCBiV2lsbENvbW1pdCk7DQotCXZvaWQJCQkJCU9uRmllbGRfS2V5c3Ryb2tlKGludCBuQ29tbWl0S2V5LCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsDQotCQkJCQkJCQlGWF9CT09MIEtleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLCBpbnQgJm5TZWxFbmQsaW50ICZuU2VsU3RhcnQsIEZYX0JPT0wgYlNoaWZ0LA0KLQkJCQkJCQkJQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCBiV2lsbENvbW1pdCwgDQotCQkJCQkJCQlGWF9CT09MIGJGaWVsZEZ1bGwsIEZYX0JPT0wgJmJSYyk7DQotCXZvaWQJCQkJCU9uRmllbGRfVmFsaWRhdGUoQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LCBGWF9CT09MIGJLZXlEb3duLA0KLQkJCQkJCQkJRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MJiBiUmMpOw0KLQ0KLQl2b2lkCQkJCQlPbkZpZWxkX01vdXNlRG93bihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KTsNCi0Jdm9pZAkJCQkJT25GaWVsZF9Nb3VzZUVudGVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQgKnBUYXJnZXQpOw0KLQl2b2lkCQkJCQlPbkZpZWxkX01vdXNlRXhpdChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KTsNCi0Jdm9pZAkJCQkJT25GaWVsZF9Nb3VzZVVwKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQgKnBUYXJnZXQpOw0KLQl2b2lkCQkJCQlPbkZpZWxkX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlKTsNCi0Jdm9pZAkJCQkJT25GaWVsZF9Gb2N1cyhGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgVmFsdWUpOw0KLQ0KLQl2b2lkCQkJCQlPblNjcmVlbl9Gb2N1cyhGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOw0KLQl2b2lkCQkJCQlPblNjcmVlbl9CbHVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7DQotCXZvaWQJCQkJCU9uU2NyZWVuX09wZW4oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsNCi0Jdm9pZAkJCQkJT25TY3JlZW5fQ2xvc2UoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsNCi0Jdm9pZAkJCQkJT25TY3JlZW5fTW91c2VEb3duKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7DQotCXZvaWQJCQkJCU9uU2NyZWVuX01vdXNlVXAoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsNCi0Jdm9pZAkJCQkJT25TY3JlZW5fTW91c2VFbnRlcihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOw0KLQl2b2lkCQkJCQlPblNjcmVlbl9Nb3VzZUV4aXQoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsNCi0Jdm9pZAkJCQkJT25TY3JlZW5fSW5WaWV3KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7DQotCXZvaWQJCQkJCU9uU2NyZWVuX091dFZpZXcoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsNCi0NCi0Jdm9pZAkJCQkJT25Cb29rbWFya19Nb3VzZVVwKENQREZfQm9va21hcmsqIHBCb29rTWFyayk7DQotCXZvaWQJCQkJCU9uTGlua19Nb3VzZVVwKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpOw0KLQ0KLQl2b2lkCQkJCQlPbk1lbnVfRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyVGFyZ2V0TmFtZSk7DQotCXZvaWQJCQkJCU9uQmF0Y2hFeGVjKENQREZTREtfRG9jdW1lbnQgKnBUYXJnZXQpOw0KLQl2b2lkCQkJCQlPbkNvbnNvbGVfRXhlYygpOw0KLQl2b2lkCQkJCQlPbkV4dGVybmFsX0V4ZWMoKTsNCi0NCi1wdWJsaWM6DQotICAgIHZvaWQJCQkJCUluaXRpYWwoSlNfRVZFTlRfVCB0eXBlKTsNCi0Jdm9pZAkJCQkJRGVzdHJveSgpOw0KLQlGWF9CT09MCQkJCQlJc1ZhbGlkKCk7DQotDQotCQ0KLQlDRlhfV2lkZVN0cmluZyYJCQlDaGFuZ2UoKTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQlDaGFuZ2VFeCgpOw0KLQlpbnQJCQkJCQlDb21taXRLZXkoKTsNCi0JRlhfQk9PTAkJCQkJRmllbGRGdWxsKCk7DQotCUZYX0JPT0wJCQkJCUtleURvd24oKTsNCi0JRlhfQk9PTAkJCQkJTW9kaWZpZXIoKTsNCi0JRlhfTFBDV1NUUgkJCQlOYW1lKCk7DQotCUZYX0xQQ1dTVFIJCQkJVHlwZSgpOw0KLQlGWF9CT09MJgkJCQlSYygpOw0KLQlpbnQmCQkJCQlTZWxFbmQoKTsNCi0JaW50JgkJCQkJU2VsU3RhcnQoKTsNCi0JRlhfQk9PTAkJCQkJU2hpZnQoKTsNCi0JRmllbGQqCQkJCQlTb3VyY2UoKTsNCi0JRmllbGQqCQkJCQlUYXJnZXRfRmllbGQoKTsNCi0JQ0ZYX1dpZGVTdHJpbmcmCQkJVmFsdWUoKTsNCi0JRlhfQk9PTAkJCQkJV2lsbENvbW1pdCgpOw0KLQlDRlhfV2lkZVN0cmluZwkJCVRhcmdldE5hbWUoKTsNCi0NCi0JSlNfRVZFTlRfVAkJCQlFdmVudFR5cGUoKSB7cmV0dXJuIG1fZUV2ZW50VHlwZTt9OwkNCi0NCi1wdWJsaWM6DQotCUNKU19Db250ZXh0KgkJCW1fcEpTQ29udGV4dDsNCi0JSlNfRVZFTlRfVAkJCQltX2VFdmVudFR5cGU7DQotCUZYX0JPT0wJCQkJCW1fYlZhbGlkOw0KLQ0KLQlDRlhfV2lkZVN0cmluZwkJCW1fc3RyVGFyZ2V0TmFtZTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQltX3N0clNvdXJjZU5hbWU7DQotCUNGWF9XaWRlU3RyaW5nKgkJCW1fcFdpZGVTdHJDaGFuZ2U7DQotCUNGWF9XaWRlU3RyaW5nCQkJbV9XaWRlU3RyQ2hhbmdlRHU7DQotCUNGWF9XaWRlU3RyaW5nCQkJbV9XaWRlU3RyQ2hhbmdlRXg7DQotCWludAkJCQkJCW1fbkNvbW1pdEtleTsNCi0JRlhfQk9PTAkJCQkJbV9iS2V5RG93bjsNCi0JRlhfQk9PTAkJCQkJbV9iTW9kaWZpZXI7DQotCUZYX0JPT0wJCQkJCW1fYlNoaWZ0Ow0KLQlpbnQqCQkJCQltX3BJU2VsRW5kOw0KLQlpbnQJCQkJCQltX25TZWxFbmREdTsNCi0JaW50KgkJCQkJbV9wSVNlbFN0YXJ0Ow0KLQlpbnQJCQkJCQltX25TZWxTdGFydER1Ow0KLQlGWF9CT09MCQkJCQltX2JXaWxsQ29tbWl0Ow0KLQlDRlhfV2lkZVN0cmluZyoJCQltX3BWYWx1ZTsNCi0JRlhfQk9PTAkJCQkJbV9iRmllbGRGdWxsOw0KLQlGWF9CT09MKgkJCQltX3BiUmM7DQotCUZYX0JPT0wJCQkJCW1fYlJjRHU7DQotDQotCUNQREZTREtfRG9jdW1lbnQqCQltX3BTb3VyY2VEb2M7DQotCUNQREZfQm9va21hcmsqCQkJbV9wVGFyZ2V0Qm9va01hcms7DQotCUNQREZTREtfRG9jdW1lbnQqCQltX3BUYXJnZXREb2M7DQotCUNQREZTREtfQW5ub3QqCQkJbV9wVGFyZ2V0QW5ub3Q7DQotfTsNCi0NCi0jZW5kaWYgLy9fSlNfRVZFTlRIQU5ETEVSX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfSlNfRVZFTlRIQU5ETEVSX0hfCisjZGVmaW5lIF9KU19FVkVOVEhBTkRMRVJfSF8KKworY2xhc3MgQ0pTX0NvbnRleHQ7CitjbGFzcyBGaWVsZDsKKworZW51bSBKU19FVkVOVF9UCit7CisJSkVUX1VOS05PV04sCisJSkVUX0FQUF9JTklULAorCUpFVF9ET0NfT1BFTiwKKwlKRVRfRE9DX1dJTExQUklOVCwKKwlKRVRfRE9DX0RJRFBSSU5ULAorCUpFVF9ET0NfV0lMTFNBVkUsCisJSkVUX0RPQ19ESURTQVZFLAorCUpFVF9ET0NfV0lMTENMT1NFLAorCUpFVF9QQUdFX09QRU4sCisJSkVUX1BBR0VfQ0xPU0UsCisJSkVUX1BBR0VfSU5WSUVXLAorCUpFVF9QQUdFX09VVFZJRVcsCisJSkVUX0ZJRUxEX01PVVNFRE9XTiwKKwlKRVRfRklFTERfTU9VU0VVUCwKKwlKRVRfRklFTERfTU9VU0VFTlRFUiwKKwlKRVRfRklFTERfTU9VU0VFWElULAorCUpFVF9GSUVMRF9GT0NVUywKKwlKRVRfRklFTERfQkxVUiwKKwlKRVRfRklFTERfS0VZU1RST0tFLAorCUpFVF9GSUVMRF9WQUxJREFURSwKKwlKRVRfRklFTERfQ0FMQ1VMQVRFLAorCUpFVF9GSUVMRF9GT1JNQVQsCisJSkVUX1NDUkVFTl9GT0NVUywKKwlKRVRfU0NSRUVOX0JMVVIsCisJSkVUX1NDUkVFTl9PUEVOLAorCUpFVF9TQ1JFRU5fQ0xPU0UsCisJSkVUX1NDUkVFTl9NT1VTRURPV04sCisJSkVUX1NDUkVFTl9NT1VTRVVQLAorCUpFVF9TQ1JFRU5fTU9VU0VFTlRFUiwKKwlKRVRfU0NSRUVOX01PVVNFRVhJVCwKKwlKRVRfU0NSRUVOX0lOVklFVywKKwlKRVRfU0NSRUVOX09VVFZJRVcsCisJSkVUX0JBVENIX0VYRUMsCisJSkVUX01FTlVfRVhFQywKKwlKRVRfQ09OU09MRV9FWEVDLAorCUpFVF9FWFRFUk5BTF9FWEVDLAorCUpFVF9CT09LTUFSS19NT1VTRVVQLAorCUpFVF9MSU5LX01PVVNFVVAKK307CisKK2NsYXNzIENKU19FdmVudEhhbmRsZXIKK3sKK3B1YmxpYzoKKwlDSlNfRXZlbnRIYW5kbGVyKENKU19Db250ZXh0ICogcENvbnRleHQpOworCXZpcnR1YWwgfkNKU19FdmVudEhhbmRsZXIoKTsKKworCXZvaWQJCQkJCU9uQXBwX0luaXQoKTsKKworCXZvaWQJCQkJCU9uRG9jX09wZW4oQ1BERlNES19Eb2N1bWVudCogcERvYywgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0clRhcmdldE5hbWUpOworCXZvaWQJCQkJCU9uRG9jX1dpbGxQcmludChDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsKKwl2b2lkCQkJCQlPbkRvY19EaWRQcmludChDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsKKwl2b2lkCQkJCQlPbkRvY19XaWxsU2F2ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsKKwl2b2lkCQkJCQlPbkRvY19EaWRTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOworCXZvaWQJCQkJCU9uRG9jX1dpbGxDbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsKKworCXZvaWQJCQkJCU9uUGFnZV9PcGVuKENQREZTREtfRG9jdW1lbnQqIHBEb2MpOworCXZvaWQJCQkJCU9uUGFnZV9DbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKTsKKwl2b2lkCQkJCQlPblBhZ2VfSW5WaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpOworCXZvaWQJCQkJCU9uUGFnZV9PdXRWaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpOworCQorCXZvaWQJCQkJCU9uRmllbGRfQ2FsY3VsYXRlKENQREZfRm9ybUZpZWxkKiBwU291cmNlLCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MJiBiUmMpOworCXZvaWQJCQkJCU9uRmllbGRfRm9ybWF0KGludCBuQ29tbWl0S2V5LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0KTsKKwl2b2lkCQkJCQlPbkZpZWxkX0tleXN0cm9rZShpbnQgbkNvbW1pdEtleSwgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LAorCQkJCQkJCQlGWF9CT09MIEtleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLCBpbnQgJm5TZWxFbmQsaW50ICZuU2VsU3RhcnQsIEZYX0JPT0wgYlNoaWZ0LAorCQkJCQkJCQlDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0LCAKKwkJCQkJCQkJRlhfQk9PTCBiRmllbGRGdWxsLCBGWF9CT09MICZiUmMpOworCXZvaWQJCQkJCU9uRmllbGRfVmFsaWRhdGUoQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LCBGWF9CT09MIGJLZXlEb3duLAorCQkJCQkJCQlGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wmIGJSYyk7CisKKwl2b2lkCQkJCQlPbkZpZWxkX01vdXNlRG93bihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KTsKKwl2b2lkCQkJCQlPbkZpZWxkX01vdXNlRW50ZXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCAqcFRhcmdldCk7CisJdm9pZAkJCQkJT25GaWVsZF9Nb3VzZUV4aXQoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCAqcFRhcmdldCk7CisJdm9pZAkJCQkJT25GaWVsZF9Nb3VzZVVwKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQgKnBUYXJnZXQpOworCXZvaWQJCQkJCU9uRmllbGRfQmx1cihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgVmFsdWUpOworCXZvaWQJCQkJCU9uRmllbGRfRm9jdXMoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlKTsKKworCXZvaWQJCQkJCU9uU2NyZWVuX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7CisJdm9pZAkJCQkJT25TY3JlZW5fQmx1cihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCXZvaWQJCQkJCU9uU2NyZWVuX09wZW4oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsKKwl2b2lkCQkJCQlPblNjcmVlbl9DbG9zZShGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCXZvaWQJCQkJCU9uU2NyZWVuX01vdXNlRG93bihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCXZvaWQJCQkJCU9uU2NyZWVuX01vdXNlVXAoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKTsKKwl2b2lkCQkJCQlPblNjcmVlbl9Nb3VzZUVudGVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7CisJdm9pZAkJCQkJT25TY3JlZW5fTW91c2VFeGl0KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7CisJdm9pZAkJCQkJT25TY3JlZW5fSW5WaWV3KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbik7CisJdm9pZAkJCQkJT25TY3JlZW5fT3V0VmlldyhGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pOworCisJdm9pZAkJCQkJT25Cb29rbWFya19Nb3VzZVVwKENQREZfQm9va21hcmsqIHBCb29rTWFyayk7CisJdm9pZAkJCQkJT25MaW5rX01vdXNlVXAoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCk7CisKKwl2b2lkCQkJCQlPbk1lbnVfRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyVGFyZ2V0TmFtZSk7CisJdm9pZAkJCQkJT25CYXRjaEV4ZWMoQ1BERlNES19Eb2N1bWVudCAqcFRhcmdldCk7CisJdm9pZAkJCQkJT25Db25zb2xlX0V4ZWMoKTsKKwl2b2lkCQkJCQlPbkV4dGVybmFsX0V4ZWMoKTsKKworcHVibGljOgorICAgIHZvaWQJCQkJCUluaXRpYWwoSlNfRVZFTlRfVCB0eXBlKTsKKwl2b2lkCQkJCQlEZXN0cm95KCk7CisJRlhfQk9PTAkJCQkJSXNWYWxpZCgpOworCisJCisJQ0ZYX1dpZGVTdHJpbmcmCQkJQ2hhbmdlKCk7CisJQ0ZYX1dpZGVTdHJpbmcJCQlDaGFuZ2VFeCgpOworCWludAkJCQkJCUNvbW1pdEtleSgpOworCUZYX0JPT0wJCQkJCUZpZWxkRnVsbCgpOworCUZYX0JPT0wJCQkJCUtleURvd24oKTsKKwlGWF9CT09MCQkJCQlNb2RpZmllcigpOworCUZYX0xQQ1dTVFIJCQkJTmFtZSgpOworCUZYX0xQQ1dTVFIJCQkJVHlwZSgpOworCUZYX0JPT0wmCQkJCVJjKCk7CisJaW50JgkJCQkJU2VsRW5kKCk7CisJaW50JgkJCQkJU2VsU3RhcnQoKTsKKwlGWF9CT09MCQkJCQlTaGlmdCgpOworCUZpZWxkKgkJCQkJU291cmNlKCk7CisJRmllbGQqCQkJCQlUYXJnZXRfRmllbGQoKTsKKwlDRlhfV2lkZVN0cmluZyYJCQlWYWx1ZSgpOworCUZYX0JPT0wJCQkJCVdpbGxDb21taXQoKTsKKwlDRlhfV2lkZVN0cmluZwkJCVRhcmdldE5hbWUoKTsKKworCUpTX0VWRU5UX1QJCQkJRXZlbnRUeXBlKCkge3JldHVybiBtX2VFdmVudFR5cGU7fTsJCisKK3B1YmxpYzoKKwlDSlNfQ29udGV4dCoJCQltX3BKU0NvbnRleHQ7CisJSlNfRVZFTlRfVAkJCQltX2VFdmVudFR5cGU7CisJRlhfQk9PTAkJCQkJbV9iVmFsaWQ7CisKKwlDRlhfV2lkZVN0cmluZwkJCW1fc3RyVGFyZ2V0TmFtZTsKKwlDRlhfV2lkZVN0cmluZwkJCW1fc3RyU291cmNlTmFtZTsKKwlDRlhfV2lkZVN0cmluZyoJCQltX3BXaWRlU3RyQ2hhbmdlOworCUNGWF9XaWRlU3RyaW5nCQkJbV9XaWRlU3RyQ2hhbmdlRHU7CisJQ0ZYX1dpZGVTdHJpbmcJCQltX1dpZGVTdHJDaGFuZ2VFeDsKKwlpbnQJCQkJCQltX25Db21taXRLZXk7CisJRlhfQk9PTAkJCQkJbV9iS2V5RG93bjsKKwlGWF9CT09MCQkJCQltX2JNb2RpZmllcjsKKwlGWF9CT09MCQkJCQltX2JTaGlmdDsKKwlpbnQqCQkJCQltX3BJU2VsRW5kOworCWludAkJCQkJCW1fblNlbEVuZER1OworCWludCoJCQkJCW1fcElTZWxTdGFydDsKKwlpbnQJCQkJCQltX25TZWxTdGFydER1OworCUZYX0JPT0wJCQkJCW1fYldpbGxDb21taXQ7CisJQ0ZYX1dpZGVTdHJpbmcqCQkJbV9wVmFsdWU7CisJRlhfQk9PTAkJCQkJbV9iRmllbGRGdWxsOworCUZYX0JPT0wqCQkJCW1fcGJSYzsKKwlGWF9CT09MCQkJCQltX2JSY0R1OworCisJQ1BERlNES19Eb2N1bWVudCoJCW1fcFNvdXJjZURvYzsKKwlDUERGX0Jvb2ttYXJrKgkJCW1fcFRhcmdldEJvb2tNYXJrOworCUNQREZTREtfRG9jdW1lbnQqCQltX3BUYXJnZXREb2M7CisJQ1BERlNES19Bbm5vdCoJCQltX3BUYXJnZXRBbm5vdDsKK307CisKKyNlbmRpZiAvL19KU19FVkVOVEhBTkRMRVJfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfR2xvYmFsRGF0YS5oIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfR2xvYmFsRGF0YS5oCmluZGV4IDk3YTU0MDIuLjEwMDFmZjYgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0dsb2JhbERhdGEuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19HbG9iYWxEYXRhLmgKQEAgLTEsOTcgKzEsOTcgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0pTX0dMT0JBTERBVEFfSF8NCi0jZGVmaW5lIF9KU19HTE9CQUxEQVRBX0hfDQotDQotI2RlZmluZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSCQkwDQotI2RlZmluZSBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTgkJMQ0KLSNkZWZpbmUgSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORwkJMg0KLSNkZWZpbmUgSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVAkJMw0KLSNkZWZpbmUgSlNfR0xPQkFMREFUQV9UWVBFX05VTEwJCQk0DQotDQotY2xhc3MgQ0pTX0tleVZhbHVlOw0KLWNsYXNzIENKU19HbG9iYWxWYXJpYWJsZUFycmF5Ow0KLWNsYXNzIENKU19HbG9iYWxEYXRhX0VsZW1lbnQ7DQotDQotY2xhc3MgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkNCi17DQotcHVibGljOg0KLQlDSlNfR2xvYmFsVmFyaWFibGVBcnJheSgpOw0KLQl2aXJ0dWFsIH5DSlNfR2xvYmFsVmFyaWFibGVBcnJheSgpOw0KLQ0KLQl2b2lkCQkJQWRkKENKU19LZXlWYWx1ZSogcCk7DQotCWludAkJCQlDb3VudCgpIGNvbnN0Ow0KLQlDSlNfS2V5VmFsdWUqCUdldEF0KGludCBpbmRleCkgY29uc3Q7DQotCXZvaWQJCQlDb3B5KGNvbnN0IENKU19HbG9iYWxWYXJpYWJsZUFycmF5JiBhcnJheSk7DQotDQotCXZvaWQJCQlFbXB0eSgpOw0KLQ0KLXByaXZhdGU6DQotCUNGWF9BcnJheVRlbXBsYXRlPENKU19LZXlWYWx1ZSo+IGFycmF5Ow0KLX07DQotDQotY2xhc3MgQ0pTX0tleVZhbHVlDQotew0KLXB1YmxpYzoNCi0JQ0pTX0tleVZhbHVlKCl7fQ0KLQl2aXJ0dWFsIH5DSlNfS2V5VmFsdWUoKXt9DQotDQotCUNGWF9CeXRlU3RyaW5nCQkJCQlzS2V5Ow0KLQlpbnQJCQkJCQkJCW5UeXBlOyAvLzA6aW50IDE6Ym9vbCAyOnN0cmluZyAzOm9iag0KLQlkb3VibGUJCQkJCQkJZERhdGE7DQotCWJvb2wJCQkJCQkJYkRhdGE7DQotCUNGWF9CeXRlU3RyaW5nCQkJCQlzRGF0YTsNCi0JQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkJCQlvYmpEYXRhOw0KLX07DQotDQotY2xhc3MgQ0pTX0dsb2JhbERhdGFfRWxlbWVudA0KLXsNCi1wdWJsaWM6DQotCUNKU19HbG9iYWxEYXRhX0VsZW1lbnQoKXt9DQotCXZpcnR1YWwgfkNKU19HbG9iYWxEYXRhX0VsZW1lbnQoKXt9DQotDQotCUNKU19LZXlWYWx1ZQkJCWRhdGE7DQotCUZYX0JPT0wJCQkJCWJQZXJzaXN0ZW50Ow0KLX07DQotDQotY2xhc3MgQ0pTX0dsb2JhbERhdGENCi17DQotcHVibGljOg0KLQlDSlNfR2xvYmFsRGF0YShDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwKTsNCi0JdmlydHVhbCB+Q0pTX0dsb2JhbERhdGEoKTsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQkJCVNldEdsb2JhbFZhcmlhYmxlTnVtYmVyKEZYX0xQQ1NUUiBwcm9wbmFtZSwgZG91YmxlIGREYXRhKTsNCi0Jdm9pZAkJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVCb29sZWFuKEZYX0xQQ1NUUiBwcm9wbmFtZSwgYm9vbCBiRGF0YSk7DQotCXZvaWQJCQkJCQkJCVNldEdsb2JhbFZhcmlhYmxlU3RyaW5nKEZYX0xQQ1NUUiBwcm9wbmFtZSwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNEYXRhKTsNCi0Jdm9pZAkJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVPYmplY3QoRlhfTFBDU1RSIHByb3BuYW1lLCBjb25zdCBDSlNfR2xvYmFsVmFyaWFibGVBcnJheSYgYXJyYXkpOw0KLQl2b2lkCQkJCQkJCQlTZXRHbG9iYWxWYXJpYWJsZU51bGwoRlhfTFBDU1RSIHByb3BuYW1lKTsNCi0NCi0JRlhfQk9PTAkJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVQZXJzaXN0ZW50KEZYX0xQQ1NUUiBwcm9wbmFtZSwgRlhfQk9PTCBiUGVyc2lzdGVudCk7DQotCUZYX0JPT0wJCQkJCQkJCURlbGV0ZUdsb2JhbFZhcmlhYmxlKEZYX0xQQ1NUUiBwcm9wbmFtZSk7DQotCQ0KLQlGWF9JTlQzMgkJCQkJCQlHZXRTaXplKCkgY29uc3Q7DQotCUNKU19HbG9iYWxEYXRhX0VsZW1lbnQqCQkJCUdldEF0KGludCBpbmRleCkgY29uc3Q7DQotDQotcHJpdmF0ZToNCi0Jdm9pZAkJCQkJCQkJTG9hZEdsb2JhbFBlcnNpc3RlbnRWYXJpYWJsZXMoKTsNCi0Jdm9pZAkJCQkJCQkJU2F2ZUdsb2JhbFBlcnNpc2l0ZW50VmFyaWFibGVzKCk7DQotCQ0KLQlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KgkJCQlHZXRHbG9iYWxWYXJpYWJsZShGWF9MUENTVFIgcHJvcG5hbWUpOwkNCi0JaW50CQkJCQkJCQkJRmluZEdsb2JhbFZhcmlhYmxlKEZYX0xQQ1NUUiBwcm9wbmFtZSk7DQotDQotCXZvaWQJCQkJCQkJCUxvYWRGaWxlQnVmZmVyKEZYX0xQQ1dTVFIgc0ZpbGVQYXRoLCBGWF9MUEJZVEUmIHBCdWZmZXIsIEZYX0lOVDMyJiBuTGVuZ3RoKTsNCi0Jdm9pZAkJCQkJCQkJV3JpdGVGaWxlQnVmZmVyKEZYX0xQQ1dTVFIgc0ZpbGVQYXRoLCBGWF9MUENTVFIgcEJ1ZmZlciwgRlhfSU5UMzIgbkxlbmd0aCk7DQotCXZvaWQJCQkJCQkJCU1ha2VCeXRlU3RyaW5nKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBuYW1lLCBDSlNfS2V5VmFsdWUqIHBEYXRhLCBDRlhfQmluYXJ5QnVmJiBzRGF0YSk7DQotDQotcHJpdmF0ZToNCi0JQ0ZYX0FycmF5VGVtcGxhdGU8Q0pTX0dsb2JhbERhdGFfRWxlbWVudCo+CW1fYXJyYXlHbG9iYWxEYXRhOw0KLQlDRlhfV2lkZVN0cmluZwkJCQkJCQkJbV9zRmlsZVBhdGg7DQotCUNQREZEb2NfRW52aXJvbm1lbnQqCQkJCQkJCQltX3BBcHA7DQotfTsNCi0NCi0jZW5kaWYgLy9fSlNfR0xPQkFMREFUQV9IXw0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0pTX0dMT0JBTERBVEFfSF8KKyNkZWZpbmUgX0pTX0dMT0JBTERBVEFfSF8KKworI2RlZmluZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSCQkwCisjZGVmaW5lIEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOCQkxCisjZGVmaW5lIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkcJCTIKKyNkZWZpbmUgSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVAkJMworI2RlZmluZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTAkJCTQKKworY2xhc3MgQ0pTX0tleVZhbHVlOworY2xhc3MgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk7CitjbGFzcyBDSlNfR2xvYmFsRGF0YV9FbGVtZW50OworCitjbGFzcyBDSlNfR2xvYmFsVmFyaWFibGVBcnJheQoreworcHVibGljOgorCUNKU19HbG9iYWxWYXJpYWJsZUFycmF5KCk7CisJdmlydHVhbCB+Q0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkoKTsKKworCXZvaWQJCQlBZGQoQ0pTX0tleVZhbHVlKiBwKTsKKwlpbnQJCQkJQ291bnQoKSBjb25zdDsKKwlDSlNfS2V5VmFsdWUqCUdldEF0KGludCBpbmRleCkgY29uc3Q7CisJdm9pZAkJCUNvcHkoY29uc3QgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkmIGFycmF5KTsKKworCXZvaWQJCQlFbXB0eSgpOworCitwcml2YXRlOgorCUNGWF9BcnJheVRlbXBsYXRlPENKU19LZXlWYWx1ZSo+IGFycmF5OworfTsKKworY2xhc3MgQ0pTX0tleVZhbHVlCit7CitwdWJsaWM6CisJQ0pTX0tleVZhbHVlKCl7fQorCXZpcnR1YWwgfkNKU19LZXlWYWx1ZSgpe30KKworCUNGWF9CeXRlU3RyaW5nCQkJCQlzS2V5OworCWludAkJCQkJCQkJblR5cGU7IC8vMDppbnQgMTpib29sIDI6c3RyaW5nIDM6b2JqCisJZG91YmxlCQkJCQkJCWREYXRhOworCWJvb2wJCQkJCQkJYkRhdGE7CisJQ0ZYX0J5dGVTdHJpbmcJCQkJCXNEYXRhOworCUNKU19HbG9iYWxWYXJpYWJsZUFycmF5CQkJb2JqRGF0YTsKK307CisKK2NsYXNzIENKU19HbG9iYWxEYXRhX0VsZW1lbnQKK3sKK3B1YmxpYzoKKwlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KCl7fQorCXZpcnR1YWwgfkNKU19HbG9iYWxEYXRhX0VsZW1lbnQoKXt9CisKKwlDSlNfS2V5VmFsdWUJCQlkYXRhOworCUZYX0JPT0wJCQkJCWJQZXJzaXN0ZW50OworfTsKKworY2xhc3MgQ0pTX0dsb2JhbERhdGEKK3sKK3B1YmxpYzoKKwlDSlNfR2xvYmFsRGF0YShDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwKTsKKwl2aXJ0dWFsIH5DSlNfR2xvYmFsRGF0YSgpOworCitwdWJsaWM6CisJdm9pZAkJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVOdW1iZXIoRlhfTFBDU1RSIHByb3BuYW1lLCBkb3VibGUgZERhdGEpOworCXZvaWQJCQkJCQkJCVNldEdsb2JhbFZhcmlhYmxlQm9vbGVhbihGWF9MUENTVFIgcHJvcG5hbWUsIGJvb2wgYkRhdGEpOworCXZvaWQJCQkJCQkJCVNldEdsb2JhbFZhcmlhYmxlU3RyaW5nKEZYX0xQQ1NUUiBwcm9wbmFtZSwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNEYXRhKTsKKwl2b2lkCQkJCQkJCQlTZXRHbG9iYWxWYXJpYWJsZU9iamVjdChGWF9MUENTVFIgcHJvcG5hbWUsIGNvbnN0IENKU19HbG9iYWxWYXJpYWJsZUFycmF5JiBhcnJheSk7CisJdm9pZAkJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVOdWxsKEZYX0xQQ1NUUiBwcm9wbmFtZSk7CisKKwlGWF9CT09MCQkJCQkJCQlTZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQoRlhfTFBDU1RSIHByb3BuYW1lLCBGWF9CT09MIGJQZXJzaXN0ZW50KTsKKwlGWF9CT09MCQkJCQkJCQlEZWxldGVHbG9iYWxWYXJpYWJsZShGWF9MUENTVFIgcHJvcG5hbWUpOworCQorCUZYX0lOVDMyCQkJCQkJCUdldFNpemUoKSBjb25zdDsKKwlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KgkJCQlHZXRBdChpbnQgaW5kZXgpIGNvbnN0OworCitwcml2YXRlOgorCXZvaWQJCQkJCQkJCUxvYWRHbG9iYWxQZXJzaXN0ZW50VmFyaWFibGVzKCk7CisJdm9pZAkJCQkJCQkJU2F2ZUdsb2JhbFBlcnNpc2l0ZW50VmFyaWFibGVzKCk7CisJCisJQ0pTX0dsb2JhbERhdGFfRWxlbWVudCoJCQkJR2V0R2xvYmFsVmFyaWFibGUoRlhfTFBDU1RSIHByb3BuYW1lKTsJCisJaW50CQkJCQkJCQkJRmluZEdsb2JhbFZhcmlhYmxlKEZYX0xQQ1NUUiBwcm9wbmFtZSk7CisKKwl2b2lkCQkJCQkJCQlMb2FkRmlsZUJ1ZmZlcihGWF9MUENXU1RSIHNGaWxlUGF0aCwgRlhfTFBCWVRFJiBwQnVmZmVyLCBGWF9JTlQzMiYgbkxlbmd0aCk7CisJdm9pZAkJCQkJCQkJV3JpdGVGaWxlQnVmZmVyKEZYX0xQQ1dTVFIgc0ZpbGVQYXRoLCBGWF9MUENTVFIgcEJ1ZmZlciwgRlhfSU5UMzIgbkxlbmd0aCk7CisJdm9pZAkJCQkJCQkJTWFrZUJ5dGVTdHJpbmcoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIG5hbWUsIENKU19LZXlWYWx1ZSogcERhdGEsIENGWF9CaW5hcnlCdWYmIHNEYXRhKTsKKworcHJpdmF0ZToKKwlDRlhfQXJyYXlUZW1wbGF0ZTxDSlNfR2xvYmFsRGF0YV9FbGVtZW50Kj4JbV9hcnJheUdsb2JhbERhdGE7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCQkJCW1fc0ZpbGVQYXRoOworCUNQREZEb2NfRW52aXJvbm1lbnQqCQkJCQkJCQltX3BBcHA7Cit9OworCisjZW5kaWYgLy9fSlNfR0xPQkFMREFUQV9IXwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfTW9kdWxlLmggYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Nb2R1bGUuaAppbmRleCBkNzI1ZjZiLi4xZmNiNTgzIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Nb2R1bGUuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Nb2R1bGUuaApAQCAtMSw0NyArMSw0NyBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfSlNfTU9EVUxFX0hfDQotI2RlZmluZSBfSlNfTU9EVUxFX0hfDQotDQotY2xhc3MgQ0pTX0dsb2JhbERhdGE7DQotY2xhc3MgQ0pTX0NvbnNvbGVEbGc7DQotDQotY2xhc3MgQ0pTX01vZHVsZSA6IHB1YmxpYyBJUmVhZGVyX01vZHVsZQ0KLXsNCi1wdWJsaWM6DQotCUNKU19Nb2R1bGUoSE1PRFVMRSBoTW9kdWxlLCBDUmVhZGVyX0FwcCogcEFwcCk7DQotCXZpcnR1YWwgfkNKU19Nb2R1bGUoKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQlEZXN0cm95KCl7ZGVsZXRlIHRoaXM7fQ0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJR2V0TW9kdWxlTmFtZSgpOw0KLQ0KLXB1YmxpYzoNCi0Jc3RhdGljIENKU19Nb2R1bGUqCQkJCUdldE1vZHVsZShDUmVhZGVyX0FwcCogcEFwcCk7DQotDQotCUlGWEpTX1J1bnRpbWUqCQkJCQlOZXdKU1J1bnRpbWUoKTsNCi0JQ0pTX0dsb2JhbERhdGEqCQkJCQlOZXdHbG9iYWxEYXRhKCk7DQotCXZvaWQJCQkJCQkJUmVsZWFzZUdsb2JhbERhdGEoKTsNCi0NCi1wdWJsaWM6DQotCS8vY29uc29sZQ0KLQl2b2lkCQkJCQkJCVNob3dDb25zb2xlKCk7DQotCXZvaWQJCQkJCQkJSGlkZUNvbnNvbGUoKTsNCi0Jdm9pZAkJCQkJCQlDbGVhckNvbnNvbGUoKTsNCi0Jdm9pZAkJCQkJCQlQcmludExpbmVDb25zb2xlKEZYX0xQQ1dTVFIgc3RyaW5nKTsNCi0NCi1wcml2YXRlOg0KLQlITU9EVUxFCQkJCQkJCW1faE1vZHVsZTsNCi0JQ1JlYWRlcl9BcHAqCQkJCQltX3BBcHA7DQotDQotCUZYX0JPT0wJCQkJCQkJbV9iSW5pdGlhbDsNCi0JQ0pTX0dsb2JhbERhdGEqCQkJCQltX3BHbG9iYWxEYXRhOw0KLQlGWF9JTlQzMgkJCQkJCW1fbkdsb2JhbERhdGFDb3VudDsNCi0NCi0JQ0pTX0NvbnNvbGVEbGcqCQkJCQltX3BDb25zb2xlOw0KLX07DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfSlNfTU9EVUxFX0hfCisjZGVmaW5lIF9KU19NT0RVTEVfSF8KKworY2xhc3MgQ0pTX0dsb2JhbERhdGE7CitjbGFzcyBDSlNfQ29uc29sZURsZzsKKworY2xhc3MgQ0pTX01vZHVsZSA6IHB1YmxpYyBJUmVhZGVyX01vZHVsZQoreworcHVibGljOgorCUNKU19Nb2R1bGUoSE1PRFVMRSBoTW9kdWxlLCBDUmVhZGVyX0FwcCogcEFwcCk7CisJdmlydHVhbCB+Q0pTX01vZHVsZSgpOworCisJdmlydHVhbCB2b2lkCQkJCQlEZXN0cm95KCl7ZGVsZXRlIHRoaXM7fQorCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCQlHZXRNb2R1bGVOYW1lKCk7CisKK3B1YmxpYzoKKwlzdGF0aWMgQ0pTX01vZHVsZSoJCQkJR2V0TW9kdWxlKENSZWFkZXJfQXBwKiBwQXBwKTsKKworCUlGWEpTX1J1bnRpbWUqCQkJCQlOZXdKU1J1bnRpbWUoKTsKKwlDSlNfR2xvYmFsRGF0YSoJCQkJCU5ld0dsb2JhbERhdGEoKTsKKwl2b2lkCQkJCQkJCVJlbGVhc2VHbG9iYWxEYXRhKCk7CisKK3B1YmxpYzoKKwkvL2NvbnNvbGUKKwl2b2lkCQkJCQkJCVNob3dDb25zb2xlKCk7CisJdm9pZAkJCQkJCQlIaWRlQ29uc29sZSgpOworCXZvaWQJCQkJCQkJQ2xlYXJDb25zb2xlKCk7CisJdm9pZAkJCQkJCQlQcmludExpbmVDb25zb2xlKEZYX0xQQ1dTVFIgc3RyaW5nKTsKKworcHJpdmF0ZToKKwlITU9EVUxFCQkJCQkJCW1faE1vZHVsZTsKKwlDUmVhZGVyX0FwcCoJCQkJCW1fcEFwcDsKKworCUZYX0JPT0wJCQkJCQkJbV9iSW5pdGlhbDsKKwlDSlNfR2xvYmFsRGF0YSoJCQkJCW1fcEdsb2JhbERhdGE7CisJRlhfSU5UMzIJCQkJCQltX25HbG9iYWxEYXRhQ291bnQ7CisKKwlDSlNfQ29uc29sZURsZyoJCQkJCW1fcENvbnNvbGU7Cit9OworCiAjZW5kaWYgLy9fSlNfTU9EVUxFX0hfClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmggYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaAppbmRleCA4YjkxZjhjLi5mMjJkYTc2IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaApAQCAtMSwyODggKzEsMjg4IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9KU19PQkpFQ1RfSF8NCi0jZGVmaW5lIF9KU19PQkpFQ1RfSF8NCi0NCi1jbGFzcyBDSlNfT2JqZWN0Ow0KLWNsYXNzIENKU19UaW1lcjsNCi1jbGFzcyBDSlNfQ29udGV4dDsNCi0NCi1jbGFzcyBDSlNfRW1iZWRPYmogOiBwdWJsaWMgQ0ZYX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19FbWJlZE9iaihDSlNfT2JqZWN0KiBwSlNPYmplY3QpOw0KLQl2aXJ0dWFsIH5DSlNfRW1iZWRPYmooKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCVRpbWVyUHJvYyhDSlNfVGltZXIqIHBUaW1lcil7fTsNCi0NCi0JQ0pTX1RpbWVyKgkJCQkJQmVnaW5UaW1lcihDUERGRG9jX0Vudmlyb25tZW50ICogcEFwcCwgRlhfVUlOVCBuRWxhcHNlKTsNCi0Jdm9pZAkJCQkJCUVuZFRpbWVyKENKU19UaW1lciogcFRpbWVyKTsNCi0NCi0JQ0pTX09iamVjdCoJCQkJCUdldEpTT2JqZWN0KCl7cmV0dXJuIG1fcEpTT2JqZWN0O307DQotCW9wZXJhdG9yCQkJCQlDSlNfT2JqZWN0KiAoKXtyZXR1cm4gbV9wSlNPYmplY3Q7fTsNCi0NCi0JQ1BERlNES19QYWdlVmlldyAqCQkJSlNHZXRQYWdlVmlldyhJRlhKU19Db250ZXh0KiBjYyk7DQotCWludAkJCQkJCQlNc2dCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9MUENXU1RSIHN3TXNnLCBGWF9MUENXU1RSIHN3VGl0bGUgPSBOVUxMLCBGWF9VSU5UIG5UeXBlID0gMCwgRlhfVUlOVCBuSWNvbiA9IDApOw0KLQl2b2lkCQkJCQkJQWxlcnQoQ0pTX0NvbnRleHQqIHBDb250ZXh0LCBGWF9MUENXU1RSIHN3TXNnKTsNCi0JRlhfQk9PTAkJCQkJCUlzU2FmZU1vZGUoSUZYSlNfQ29udGV4dCogY2MpOw0KLQ0KLXByb3RlY3RlZDoNCi0NCi0JQ0pTX09iamVjdCoJCQkJCW1fcEpTT2JqZWN0Ow0KLX07DQotDQotY2xhc3MgQ0pTX09iamVjdCA6IHB1YmxpYyBDRlhfT2JqZWN0DQotew0KLXB1YmxpYzoNCi0JQ0pTX09iamVjdChKU0ZYT2JqZWN0IHBPYmplY3QpOw0KLQl2aXJ0dWFsIH5DSlNfT2JqZWN0KHZvaWQpOw0KLQkNCi0Jdm9pZAkJCQkJCU1ha2VXZWFrKCk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlJc1R5cGUoRlhfTFBDU1RSIHNDbGFzc05hbWUpe3JldHVybiBUUlVFO307DQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCUdldENsYXNzTmFtZSgpe3JldHVybiAiIjt9Ow0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJSW5pdEluc3RhbmNlKElGWEpTX0NvbnRleHQqIGNjKXtyZXR1cm4gVFJVRTt9Ow0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJRXhpdEluc3RhbmNlKCl7cmV0dXJuIFRSVUU7fTsNCi0NCi0Jb3BlcmF0b3IJCQkJCUpTRlhPYmplY3QgKCkge3JldHVybiB2ODo6TG9jYWw8djg6Ok9iamVjdD46Ok5ldyhtX3BJc29sYXRlLCBtX3BPYmplY3QpO30NCi0Jb3BlcmF0b3IJCQkJCUNKU19FbWJlZE9iaiogKCl7cmV0dXJuIG1fcEVtYmVkT2JqO307DQotDQotCXZvaWQJCQkJCQlTZXRFbWJlZE9iamVjdChDSlNfRW1iZWRPYmoqIHBPYmope21fcEVtYmVkT2JqID0gcE9iajt9Ow0KLQlDSlNfRW1iZWRPYmogKgkJCQlHZXRFbWJlZE9iamVjdCgpe3JldHVybiBtX3BFbWJlZE9iajt9Ow0KLQ0KLQlzdGF0aWMgQ1BERlNES19QYWdlVmlldyAqCUpTR2V0UGFnZVZpZXcoSUZYSlNfQ29udGV4dCogY2MpOw0KLQlzdGF0aWMgaW50CQkJCQlNc2dCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9MUENXU1RSIHN3TXNnLCBGWF9MUENXU1RSIHN3VGl0bGUgPSBOVUxMLCBGWF9VSU5UIG5UeXBlID0gMCxGWF9VSU5UIG5JY29uID0gMCk7DQotCXN0YXRpYyB2b2lkCQkJCQlBbGVydChDSlNfQ29udGV4dCogcENvbnRleHQsIEZYX0xQQ1dTVFIgc3dNc2cpOw0KLQ0KLQl2ODo6SXNvbGF0ZSoJCQkJCUdldElzb2xhdGUoKSB7cmV0dXJuIG1fcElzb2xhdGU7fQ0KLXByb3RlY3RlZDoNCi0JQ0pTX0VtYmVkT2JqICoJCQkJbV9wRW1iZWRPYmo7DQotCXY4OjpQZXJzaXN0ZW50PHY4OjpPYmplY3Q+CQkJbV9wT2JqZWN0Ow0KLQl2ODo6SXNvbGF0ZSoJCQkJCW1fcElzb2xhdGU7DQotfTsNCi0NCi1zdHJ1Y3QgSlNfVElNRVJfTUFQDQotew0KLQlGWF9VSU5UIG5JRDsNCi0JQ0pTX1RpbWVyICogcFRpbWVyOw0KLX07DQotDQotdHlwZWRlZiBDRlhfQXJyYXlUZW1wbGF0ZTxKU19USU1FUl9NQVAqPglDVGltZXJNYXBBcnJheTsNCi0NCi1zdHJ1Y3QgSlNfVElNRVJfTUFQQVJSQVkNCi17DQotcHVibGljOg0KLQlKU19USU1FUl9NQVBBUlJBWSgpDQotCXsNCi0JfQ0KLQ0KLQl+SlNfVElNRVJfTUFQQVJSQVkoKQ0KLQl7DQotCQlSZXNldCgpOw0KLQl9DQotDQotCXZvaWQgUmVzZXQoKQ0KLQl7DQotCQlmb3IgKGludCBpPTAsc3o9bV9BcnJheS5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQlkZWxldGUgbV9BcnJheS5HZXRBdChpKTsNCi0NCi0JCW1fQXJyYXkuUmVtb3ZlQWxsKCk7DQotCX0NCi0NCi0Jdm9pZCBTZXRBdChGWF9VSU5UIG5JbmRleCxDSlNfVGltZXIgKiBwVGltZXIpDQotCXsNCi0JCWludCBpID0gRmluZChuSW5kZXgpOw0KLQ0KLQkJaWYgKGk+PTApDQotCQl7DQotCQkJaWYgKEpTX1RJTUVSX01BUCAqIHBNYXAgPSBtX0FycmF5LkdldEF0KGkpKQ0KLQkJCQlwTWFwLT5wVGltZXIgPSBwVGltZXI7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYgKEpTX1RJTUVSX01BUCAqIHBNYXAgPSBuZXcgSlNfVElNRVJfTUFQKQ0KLQkJCXsNCi0JCQkJcE1hcC0+bklEID0gbkluZGV4Ow0KLQkJCQlwTWFwLT5wVGltZXIgPSBwVGltZXI7DQotCQkJCW1fQXJyYXkuQWRkKHBNYXApOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlDSlNfVGltZXIgKiBHZXRBdChGWF9VSU5UIG5JbmRleCkNCi0Jew0KLQkJaW50IGkgPSBGaW5kKG5JbmRleCk7DQotDQotCQlpZiAoaT49MCkNCi0JCXsNCi0JCQlpZiAoSlNfVElNRVJfTUFQICogcE1hcCA9IG1fQXJyYXkuR2V0QXQoaSkpDQotCQkJCXJldHVybiBwTWFwLT5wVGltZXI7DQotCQl9DQotCQlyZXR1cm4gTlVMTDsNCi0JfQ0KLQ0KLQl2b2lkIFJlbW92ZUF0KEZYX1VJTlQgbkluZGV4KQ0KLQl7DQotCQlpbnQgaSA9IEZpbmQobkluZGV4KTsNCi0NCi0JCWlmIChpPj0wKQ0KLQkJew0KLQkJCWRlbGV0ZSBtX0FycmF5LkdldEF0KGkpOw0KLQkJCW1fQXJyYXkuUmVtb3ZlQXQoaSk7DQotCQl9DQotCQkvL1RvIHByZXZlbnQgcG90ZW50aWFsIGZha2UgbWVtb3J5IGxlYWsgcmVwb3J0ZWQgYnkgdmM2Lg0KLQkJaWYobV9BcnJheS5HZXRTaXplKCkgPT0gMCkNCi0JCQltX0FycmF5LlJlbW92ZUFsbCgpOw0KLQl9DQotDQotCWludCBGaW5kKEZYX1VJTlQgbkluZGV4KQ0KLQl7CQkNCi0JCWZvciAoaW50IGk9MCxzej1tX0FycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJewkJCQ0KLQkJCWlmIChKU19USU1FUl9NQVAgKiBwTWFwID0gbV9BcnJheS5HZXRBdChpKSkNCi0JCQl7DQotCQkJCWlmIChwTWFwLT5uSUQgPT0gbkluZGV4KQ0KLQkJCQkJcmV0dXJuIGk7DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJcmV0dXJuIC0xOw0KLQl9DQotDQotCUNUaW1lck1hcEFycmF5CQltX0FycmF5Ow0KLX07DQotDQotc3RhdGljIEpTX1RJTUVSX01BUEFSUkFZCW1fc1RpbWVNYXA7DQotDQotY2xhc3MgQ0pTX1J1bnRpbWU7DQotDQotY2xhc3MgQ0pTX1RpbWVyDQotew0KLXB1YmxpYzoNCi0JQ0pTX1RpbWVyKENKU19FbWJlZE9iaiAqIHBPYmosQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCk6IG1fcEVtYmVkT2JqKHBPYmopLCANCi0JCW1fblRpbWVySUQoMCksIA0KLQkJbV9iUHJvY2Vzc2luZyhGQUxTRSksDQotCQltX2R3U3RhcnRUaW1lKDApLA0KLQkJbV9kd1RpbWVPdXQoMCksDQotCQltX2R3RWxhcHNlKDApLA0KLQkJbV9wUnVudGltZShOVUxMKSwNCi0JCW1fblR5cGUoMCksDQotCQltX3BBcHAocEFwcCkNCi0Jew0KLQl9DQotCQ0KLQl2aXJ0dWFsIH5DSlNfVGltZXIoKQ0KLQl7DQotCQlLaWxsSlNUaW1lcigpOw0KLQl9DQotDQotcHVibGljOg0KLQlGWF9VSU5UIFNldEpTVGltZXIoRlhfVUlOVCBuRWxhcHNlKQ0KLQl7CQ0KLQkJaWYgKG1fblRpbWVySUQpS2lsbEpTVGltZXIoKTsNCi0JCUlGWF9TeXN0ZW1IYW5kbGVyKiBwSGFuZGxlciA9IG1fcEFwcC0+R2V0U3lzSGFuZGxlcigpOw0KLQkJbV9uVGltZXJJRCA9IHBIYW5kbGVyLT5TZXRUaW1lcihuRWxhcHNlLFRpbWVyUHJvYyk7DQotCQltX3NUaW1lTWFwLlNldEF0KG1fblRpbWVySUQsdGhpcyk7DQotCQltX2R3RWxhcHNlID0gbkVsYXBzZTsNCi0JCXJldHVybiBtX25UaW1lcklEOw0KLQl9Ow0KLQ0KLQl2b2lkIEtpbGxKU1RpbWVyKCkNCi0Jew0KLQkJaWYgKG1fblRpbWVySUQpDQotCQl7DQotCQkJSUZYX1N5c3RlbUhhbmRsZXIqIHBIYW5kbGVyID0gbV9wQXBwLT5HZXRTeXNIYW5kbGVyKCk7DQotCQkJcEhhbmRsZXItPktpbGxUaW1lcihtX25UaW1lcklEKTsNCi0JCQltX3NUaW1lTWFwLlJlbW92ZUF0KG1fblRpbWVySUQpOw0KLQkJCW1fblRpbWVySUQgPSAwOw0KLQkJfQ0KLQl9Ow0KLQ0KLQl2b2lkIFNldFR5cGUoaW50IG5UeXBlKQ0KLQl7DQotCQltX25UeXBlID0gblR5cGU7DQotCX0NCi0NCi0JaW50IEdldFR5cGUoKSBjb25zdA0KLQl7DQotCQlyZXR1cm4gbV9uVHlwZTsNCi0JfQ0KLQ0KLQl2b2lkIFNldFN0YXJ0VGltZShGWF9EV09SRCBkd1N0YXJ0VGltZSkNCi0Jew0KLQkJbV9kd1N0YXJ0VGltZSA9IGR3U3RhcnRUaW1lOw0KLQl9DQotDQotCUZYX0RXT1JEIEdldFN0YXJ0VGltZSgpIGNvbnN0DQotCXsNCi0JCXJldHVybiBtX2R3U3RhcnRUaW1lOw0KLQl9DQotDQotCXZvaWQgU2V0VGltZU91dChGWF9EV09SRCBkd1RpbWVPdXQpDQotCXsNCi0JCW1fZHdUaW1lT3V0ID0gZHdUaW1lT3V0Ow0KLQl9DQotDQotCUZYX0RXT1JEIEdldFRpbWVPdXQoKSBjb25zdA0KLQl7DQotCQlyZXR1cm4gbV9kd1RpbWVPdXQ7DQotCX0NCi0NCi0Jdm9pZCBTZXRSdW50aW1lKENKU19SdW50aW1lKiBwUnVudGltZSkNCi0Jew0KLQkJbV9wUnVudGltZSA9IHBSdW50aW1lOw0KLQl9DQotCQ0KLQlDSlNfUnVudGltZSogR2V0UnVudGltZSgpIGNvbnN0DQotCXsNCi0JCXJldHVybiBtX3BSdW50aW1lOw0KLQl9DQotDQotCXZvaWQgU2V0SlNjcmlwdChjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0KQ0KLQl7DQotCQltX3N3SlNjcmlwdCA9IHNjcmlwdDsNCi0JfQ0KLQ0KLQlDRlhfV2lkZVN0cmluZyBHZXRKU2NyaXB0KCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIG1fc3dKU2NyaXB0Ow0KLQl9DQotDQotCXN0YXRpYyB2b2lkIFRpbWVyUHJvYyhpbnQgaWRFdmVudCkNCi0Jew0KLQkJaWYgKENKU19UaW1lciAqIHBUaW1lciA9IG1fc1RpbWVNYXAuR2V0QXQoaWRFdmVudCkpDQotCQl7DQotCQkJaWYgKCFwVGltZXItPm1fYlByb2Nlc3NpbmcpDQotCQkJew0KLQkJCQlwVGltZXItPm1fYlByb2Nlc3NpbmcgPSBUUlVFOw0KLQkJCQlpZiAocFRpbWVyLT5tX3BFbWJlZE9iaikgcFRpbWVyLT5tX3BFbWJlZE9iai0+VGltZXJQcm9jKHBUaW1lcik7DQotCQkJCXBUaW1lci0+bV9iUHJvY2Vzc2luZyA9IEZBTFNFOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCS8vCVRSQUNFKEwiQlVTWSFcbiIpOw0KLQkJCX0NCi0JCX0NCi0JfTsNCi0NCi1wcml2YXRlOg0KLQlGWF9VSU5UCQkJCQkJCW1fblRpbWVySUQ7CQ0KLQlDSlNfRW1iZWRPYmoqCQkJCQltX3BFbWJlZE9iajsNCi0JRlhfQk9PTAkJCQkJCQltX2JQcm9jZXNzaW5nOw0KLQ0KLQkvL2RhdGENCi0JRlhfRFdPUkQJCQkJCQkJbV9kd1N0YXJ0VGltZTsNCi0JRlhfRFdPUkQJCQkJCQkJbV9kd1RpbWVPdXQ7DQotCUZYX0RXT1JECQkJCQkJbV9kd0VsYXBzZTsNCi0JQ0pTX1J1bnRpbWUqCQkJCQltX3BSdW50aW1lOw0KLQlDRlhfV2lkZVN0cmluZwkJCQkJbV9zd0pTY3JpcHQ7DQotCWludAkJCQkJCQkJbV9uVHlwZTsgLy8wOkludGVydmFsOyAxOlRpbWVPdXQNCi0NCi0JQ1BERkRvY19FbnZpcm9ubWVudCoJCQltX3BBcHA7DQotfTsNCi0jZW5kaWYgLy9fSlNfT0JKRUNUX0hfDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfSlNfT0JKRUNUX0hfCisjZGVmaW5lIF9KU19PQkpFQ1RfSF8KKworY2xhc3MgQ0pTX09iamVjdDsKK2NsYXNzIENKU19UaW1lcjsKK2NsYXNzIENKU19Db250ZXh0OworCitjbGFzcyBDSlNfRW1iZWRPYmogOiBwdWJsaWMgQ0ZYX09iamVjdAoreworcHVibGljOgorCUNKU19FbWJlZE9iaihDSlNfT2JqZWN0KiBwSlNPYmplY3QpOworCXZpcnR1YWwgfkNKU19FbWJlZE9iaigpOworCisJdmlydHVhbCB2b2lkCQkJCVRpbWVyUHJvYyhDSlNfVGltZXIqIHBUaW1lcil7fTsKKworCUNKU19UaW1lcioJCQkJCUJlZ2luVGltZXIoQ1BERkRvY19FbnZpcm9ubWVudCAqIHBBcHAsIEZYX1VJTlQgbkVsYXBzZSk7CisJdm9pZAkJCQkJCUVuZFRpbWVyKENKU19UaW1lciogcFRpbWVyKTsKKworCUNKU19PYmplY3QqCQkJCQlHZXRKU09iamVjdCgpe3JldHVybiBtX3BKU09iamVjdDt9OworCW9wZXJhdG9yCQkJCQlDSlNfT2JqZWN0KiAoKXtyZXR1cm4gbV9wSlNPYmplY3Q7fTsKKworCUNQREZTREtfUGFnZVZpZXcgKgkJCUpTR2V0UGFnZVZpZXcoSUZYSlNfQ29udGV4dCogY2MpOworCWludAkJCQkJCQlNc2dCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9MUENXU1RSIHN3TXNnLCBGWF9MUENXU1RSIHN3VGl0bGUgPSBOVUxMLCBGWF9VSU5UIG5UeXBlID0gMCwgRlhfVUlOVCBuSWNvbiA9IDApOworCXZvaWQJCQkJCQlBbGVydChDSlNfQ29udGV4dCogcENvbnRleHQsIEZYX0xQQ1dTVFIgc3dNc2cpOworCUZYX0JPT0wJCQkJCQlJc1NhZmVNb2RlKElGWEpTX0NvbnRleHQqIGNjKTsKKworcHJvdGVjdGVkOgorCisJQ0pTX09iamVjdCoJCQkJCW1fcEpTT2JqZWN0OworfTsKKworY2xhc3MgQ0pTX09iamVjdCA6IHB1YmxpYyBDRlhfT2JqZWN0Cit7CitwdWJsaWM6CisJQ0pTX09iamVjdChKU0ZYT2JqZWN0IHBPYmplY3QpOworCXZpcnR1YWwgfkNKU19PYmplY3Qodm9pZCk7CisJCisJdm9pZAkJCQkJCU1ha2VXZWFrKCk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNUeXBlKEZYX0xQQ1NUUiBzQ2xhc3NOYW1lKXtyZXR1cm4gVFJVRTt9OworCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCUdldENsYXNzTmFtZSgpe3JldHVybiAiIjt9OworCisJdmlydHVhbCBGWF9CT09MCQkJCUluaXRJbnN0YW5jZShJRlhKU19Db250ZXh0KiBjYyl7cmV0dXJuIFRSVUU7fTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJRXhpdEluc3RhbmNlKCl7cmV0dXJuIFRSVUU7fTsKKworCW9wZXJhdG9yCQkJCQlKU0ZYT2JqZWN0ICgpIHtyZXR1cm4gdjg6OkxvY2FsPHY4OjpPYmplY3Q+OjpOZXcobV9wSXNvbGF0ZSwgbV9wT2JqZWN0KTt9CisJb3BlcmF0b3IJCQkJCUNKU19FbWJlZE9iaiogKCl7cmV0dXJuIG1fcEVtYmVkT2JqO307CisKKwl2b2lkCQkJCQkJU2V0RW1iZWRPYmplY3QoQ0pTX0VtYmVkT2JqKiBwT2JqKXttX3BFbWJlZE9iaiA9IHBPYmo7fTsKKwlDSlNfRW1iZWRPYmogKgkJCQlHZXRFbWJlZE9iamVjdCgpe3JldHVybiBtX3BFbWJlZE9iajt9OworCisJc3RhdGljIENQREZTREtfUGFnZVZpZXcgKglKU0dldFBhZ2VWaWV3KElGWEpTX0NvbnRleHQqIGNjKTsKKwlzdGF0aWMgaW50CQkJCQlNc2dCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9MUENXU1RSIHN3TXNnLCBGWF9MUENXU1RSIHN3VGl0bGUgPSBOVUxMLCBGWF9VSU5UIG5UeXBlID0gMCxGWF9VSU5UIG5JY29uID0gMCk7CisJc3RhdGljIHZvaWQJCQkJCUFsZXJ0KENKU19Db250ZXh0KiBwQ29udGV4dCwgRlhfTFBDV1NUUiBzd01zZyk7CisKKwl2ODo6SXNvbGF0ZSoJCQkJCUdldElzb2xhdGUoKSB7cmV0dXJuIG1fcElzb2xhdGU7fQorcHJvdGVjdGVkOgorCUNKU19FbWJlZE9iaiAqCQkJCW1fcEVtYmVkT2JqOworCXY4OjpQZXJzaXN0ZW50PHY4OjpPYmplY3Q+CQkJbV9wT2JqZWN0OworCXY4OjpJc29sYXRlKgkJCQkJbV9wSXNvbGF0ZTsKK307CisKK3N0cnVjdCBKU19USU1FUl9NQVAKK3sKKwlGWF9VSU5UIG5JRDsKKwlDSlNfVGltZXIgKiBwVGltZXI7Cit9OworCit0eXBlZGVmIENGWF9BcnJheVRlbXBsYXRlPEpTX1RJTUVSX01BUCo+CUNUaW1lck1hcEFycmF5OworCitzdHJ1Y3QgSlNfVElNRVJfTUFQQVJSQVkKK3sKK3B1YmxpYzoKKwlKU19USU1FUl9NQVBBUlJBWSgpCisJeworCX0KKworCX5KU19USU1FUl9NQVBBUlJBWSgpCisJeworCQlSZXNldCgpOworCX0KKworCXZvaWQgUmVzZXQoKQorCXsKKwkJZm9yIChpbnQgaT0wLHN6PW1fQXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQlkZWxldGUgbV9BcnJheS5HZXRBdChpKTsKKworCQltX0FycmF5LlJlbW92ZUFsbCgpOworCX0KKworCXZvaWQgU2V0QXQoRlhfVUlOVCBuSW5kZXgsQ0pTX1RpbWVyICogcFRpbWVyKQorCXsKKwkJaW50IGkgPSBGaW5kKG5JbmRleCk7CisKKwkJaWYgKGk+PTApCisJCXsKKwkJCWlmIChKU19USU1FUl9NQVAgKiBwTWFwID0gbV9BcnJheS5HZXRBdChpKSkKKwkJCQlwTWFwLT5wVGltZXIgPSBwVGltZXI7CisJCX0KKwkJZWxzZQorCQl7CisJCQlpZiAoSlNfVElNRVJfTUFQICogcE1hcCA9IG5ldyBKU19USU1FUl9NQVApCisJCQl7CisJCQkJcE1hcC0+bklEID0gbkluZGV4OworCQkJCXBNYXAtPnBUaW1lciA9IHBUaW1lcjsKKwkJCQltX0FycmF5LkFkZChwTWFwKTsKKwkJCX0KKwkJfQorCX0KKworCUNKU19UaW1lciAqIEdldEF0KEZYX1VJTlQgbkluZGV4KQorCXsKKwkJaW50IGkgPSBGaW5kKG5JbmRleCk7CisKKwkJaWYgKGk+PTApCisJCXsKKwkJCWlmIChKU19USU1FUl9NQVAgKiBwTWFwID0gbV9BcnJheS5HZXRBdChpKSkKKwkJCQlyZXR1cm4gcE1hcC0+cFRpbWVyOworCQl9CisJCXJldHVybiBOVUxMOworCX0KKworCXZvaWQgUmVtb3ZlQXQoRlhfVUlOVCBuSW5kZXgpCisJeworCQlpbnQgaSA9IEZpbmQobkluZGV4KTsKKworCQlpZiAoaT49MCkKKwkJeworCQkJZGVsZXRlIG1fQXJyYXkuR2V0QXQoaSk7CisJCQltX0FycmF5LlJlbW92ZUF0KGkpOworCQl9CisJCS8vVG8gcHJldmVudCBwb3RlbnRpYWwgZmFrZSBtZW1vcnkgbGVhayByZXBvcnRlZCBieSB2YzYuCisJCWlmKG1fQXJyYXkuR2V0U2l6ZSgpID09IDApCisJCQltX0FycmF5LlJlbW92ZUFsbCgpOworCX0KKworCWludCBGaW5kKEZYX1VJTlQgbkluZGV4KQorCXsJCQorCQlmb3IgKGludCBpPTAsc3o9bV9BcnJheS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJewkJCQorCQkJaWYgKEpTX1RJTUVSX01BUCAqIHBNYXAgPSBtX0FycmF5LkdldEF0KGkpKQorCQkJeworCQkJCWlmIChwTWFwLT5uSUQgPT0gbkluZGV4KQorCQkJCQlyZXR1cm4gaTsKKwkJCX0KKwkJfQorCisJCXJldHVybiAtMTsKKwl9CisKKwlDVGltZXJNYXBBcnJheQkJbV9BcnJheTsKK307CisKK3N0YXRpYyBKU19USU1FUl9NQVBBUlJBWQltX3NUaW1lTWFwOworCitjbGFzcyBDSlNfUnVudGltZTsKKworY2xhc3MgQ0pTX1RpbWVyCit7CitwdWJsaWM6CisJQ0pTX1RpbWVyKENKU19FbWJlZE9iaiAqIHBPYmosQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCk6IG1fcEVtYmVkT2JqKHBPYmopLCAKKwkJbV9uVGltZXJJRCgwKSwgCisJCW1fYlByb2Nlc3NpbmcoRkFMU0UpLAorCQltX2R3U3RhcnRUaW1lKDApLAorCQltX2R3VGltZU91dCgwKSwKKwkJbV9kd0VsYXBzZSgwKSwKKwkJbV9wUnVudGltZShOVUxMKSwKKwkJbV9uVHlwZSgwKSwKKwkJbV9wQXBwKHBBcHApCisJeworCX0KKwkKKwl2aXJ0dWFsIH5DSlNfVGltZXIoKQorCXsKKwkJS2lsbEpTVGltZXIoKTsKKwl9CisKK3B1YmxpYzoKKwlGWF9VSU5UIFNldEpTVGltZXIoRlhfVUlOVCBuRWxhcHNlKQorCXsJCisJCWlmIChtX25UaW1lcklEKUtpbGxKU1RpbWVyKCk7CisJCUlGWF9TeXN0ZW1IYW5kbGVyKiBwSGFuZGxlciA9IG1fcEFwcC0+R2V0U3lzSGFuZGxlcigpOworCQltX25UaW1lcklEID0gcEhhbmRsZXItPlNldFRpbWVyKG5FbGFwc2UsVGltZXJQcm9jKTsKKwkJbV9zVGltZU1hcC5TZXRBdChtX25UaW1lcklELHRoaXMpOworCQltX2R3RWxhcHNlID0gbkVsYXBzZTsKKwkJcmV0dXJuIG1fblRpbWVySUQ7CisJfTsKKworCXZvaWQgS2lsbEpTVGltZXIoKQorCXsKKwkJaWYgKG1fblRpbWVySUQpCisJCXsKKwkJCUlGWF9TeXN0ZW1IYW5kbGVyKiBwSGFuZGxlciA9IG1fcEFwcC0+R2V0U3lzSGFuZGxlcigpOworCQkJcEhhbmRsZXItPktpbGxUaW1lcihtX25UaW1lcklEKTsKKwkJCW1fc1RpbWVNYXAuUmVtb3ZlQXQobV9uVGltZXJJRCk7CisJCQltX25UaW1lcklEID0gMDsKKwkJfQorCX07CisKKwl2b2lkIFNldFR5cGUoaW50IG5UeXBlKQorCXsKKwkJbV9uVHlwZSA9IG5UeXBlOworCX0KKworCWludCBHZXRUeXBlKCkgY29uc3QKKwl7CisJCXJldHVybiBtX25UeXBlOworCX0KKworCXZvaWQgU2V0U3RhcnRUaW1lKEZYX0RXT1JEIGR3U3RhcnRUaW1lKQorCXsKKwkJbV9kd1N0YXJ0VGltZSA9IGR3U3RhcnRUaW1lOworCX0KKworCUZYX0RXT1JEIEdldFN0YXJ0VGltZSgpIGNvbnN0CisJeworCQlyZXR1cm4gbV9kd1N0YXJ0VGltZTsKKwl9CisKKwl2b2lkIFNldFRpbWVPdXQoRlhfRFdPUkQgZHdUaW1lT3V0KQorCXsKKwkJbV9kd1RpbWVPdXQgPSBkd1RpbWVPdXQ7CisJfQorCisJRlhfRFdPUkQgR2V0VGltZU91dCgpIGNvbnN0CisJeworCQlyZXR1cm4gbV9kd1RpbWVPdXQ7CisJfQorCisJdm9pZCBTZXRSdW50aW1lKENKU19SdW50aW1lKiBwUnVudGltZSkKKwl7CisJCW1fcFJ1bnRpbWUgPSBwUnVudGltZTsKKwl9CisJCisJQ0pTX1J1bnRpbWUqIEdldFJ1bnRpbWUoKSBjb25zdAorCXsKKwkJcmV0dXJuIG1fcFJ1bnRpbWU7CisJfQorCisJdm9pZCBTZXRKU2NyaXB0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQpCisJeworCQltX3N3SlNjcmlwdCA9IHNjcmlwdDsKKwl9CisKKwlDRlhfV2lkZVN0cmluZyBHZXRKU2NyaXB0KCkgY29uc3QKKwl7CisJCXJldHVybiBtX3N3SlNjcmlwdDsKKwl9CisKKwlzdGF0aWMgdm9pZCBUaW1lclByb2MoaW50IGlkRXZlbnQpCisJeworCQlpZiAoQ0pTX1RpbWVyICogcFRpbWVyID0gbV9zVGltZU1hcC5HZXRBdChpZEV2ZW50KSkKKwkJeworCQkJaWYgKCFwVGltZXItPm1fYlByb2Nlc3NpbmcpCisJCQl7CisJCQkJcFRpbWVyLT5tX2JQcm9jZXNzaW5nID0gVFJVRTsKKwkJCQlpZiAocFRpbWVyLT5tX3BFbWJlZE9iaikgcFRpbWVyLT5tX3BFbWJlZE9iai0+VGltZXJQcm9jKHBUaW1lcik7CisJCQkJcFRpbWVyLT5tX2JQcm9jZXNzaW5nID0gRkFMU0U7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkvLwlUUkFDRShMIkJVU1khXG4iKTsKKwkJCX0KKwkJfQorCX07CisKK3ByaXZhdGU6CisJRlhfVUlOVAkJCQkJCQltX25UaW1lcklEOwkKKwlDSlNfRW1iZWRPYmoqCQkJCQltX3BFbWJlZE9iajsKKwlGWF9CT09MCQkJCQkJCW1fYlByb2Nlc3Npbmc7CisKKwkvL2RhdGEKKwlGWF9EV09SRAkJCQkJCQltX2R3U3RhcnRUaW1lOworCUZYX0RXT1JECQkJCQkJCW1fZHdUaW1lT3V0OworCUZYX0RXT1JECQkJCQkJbV9kd0VsYXBzZTsKKwlDSlNfUnVudGltZSoJCQkJCW1fcFJ1bnRpbWU7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCW1fc3dKU2NyaXB0OworCWludAkJCQkJCQkJbV9uVHlwZTsgLy8wOkludGVydmFsOyAxOlRpbWVPdXQKKworCUNQREZEb2NfRW52aXJvbm1lbnQqCQkJbV9wQXBwOworfTsKKyNlbmRpZiAvL19KU19PQkpFQ1RfSF8KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaAppbmRleCAzMmY4NDU3Li4wYTE5NWYxIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19SdW50aW1lLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oCkBAIC0xLDcwICsxLDcwIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9KU19SVU5USU1FX0hfDQotI2RlZmluZSBfSlNfUlVOVElNRV9IXw0KLQ0KLWNsYXNzIENKU19GaWVsZEV2ZW50DQotew0KLXB1YmxpYzoNCi0JQ0ZYX1dpZGVTdHJpbmcJCXNUYXJnZXROYW1lOw0KLQlKU19FVkVOVF9UCQkJZUV2ZW50VHlwZTsNCi0JQ0pTX0ZpZWxkRXZlbnQqCQlwTmV4dDsNCi19Ow0KLQ0KLWNsYXNzIENKU19SdW50aW1lIDogcHVibGljIElGWEpTX1J1bnRpbWUNCi17DQotcHVibGljOg0KLQlDSlNfUnVudGltZShDUERGRG9jX0Vudmlyb25tZW50ICogcEFwcCk7DQotCXZpcnR1YWwgfkNKU19SdW50aW1lKCk7DQotDQotCXZpcnR1YWwgSUZYSlNfQ29udGV4dCAqCQkJCQlOZXdDb250ZXh0KCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlSZWxlYXNlQ29udGV4dChJRlhKU19Db250ZXh0ICogcENvbnRleHQpOw0KLQl2aXJ0dWFsIElGWEpTX0NvbnRleHQqCQkJCQlHZXRDdXJyZW50Q29udGV4dCgpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0UmVhZGVyRG9jdW1lbnQoQ1BERlNES19Eb2N1bWVudCAqcFJlYWRlckRvYyk7DQotCXZpcnR1YWwgQ1BERlNES19Eb2N1bWVudCAqCQkJCUdldFJlYWRlckRvY3VtZW50KCl7cmV0dXJuIG1fcERvY3VtZW50O30NCi0NCi0JdmlydHVhbCB2b2lkCQkJCQkJCUdldE9iamVjdE5hbWVzKENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCUdldE9iamVjdENvbnN0cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dPYmpOYW1lLCBDRlhfV2lkZVN0cmluZ0FycmF5JiBhcnJheSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlHZXRPYmplY3RQcm9wcyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dPYmpOYW1lLCBDRlhfV2lkZVN0cmluZ0FycmF5JiBhcnJheSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlHZXRPYmplY3RNZXRob2RzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQkJCUV4aXQoKTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCUVudGVyKCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlJc0VudGVyZWQoKTsNCi0NCi0JQ1BERkRvY19FbnZpcm9ubWVudCAqCQkJCQkJCUdldFJlYWRlckFwcCgpe3JldHVybiBtX3BBcHA7fQ0KLQ0KLQlGWF9CT09MCQkJCQkJCQkJSW5pdEpTT2JqZWN0cygpOw0KLQ0KLQlGWF9CT09MCQkJCQkJCQkJQWRkRXZlbnRUb0xvb3AoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUYXJnZXROYW1lLCBKU19FVkVOVF9UIGVFdmVudFR5cGUpOw0KLQl2b2lkCQkJCQkJCQkJUmVtb3ZlRXZlbnRJbkxvb3AoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUYXJnZXROYW1lLCBKU19FVkVOVF9UIGVFdmVudFR5cGUpOw0KLQl2b2lkCQkJCQkJCQkJUmVtb3ZlRXZlbnRzSW5Mb29wKENKU19GaWVsZEV2ZW50KiBwU3RhcnQpOw0KLQ0KLQl2b2lkCQkJCQkJCQkJQmVnaW5CbG9jaygpe21fYkJsb2NraW5nID0gVFJVRTt9DQotCXZvaWQJCQkJCQkJCQlFbmRCbG9jaygpe21fYkJsb2NraW5nID0gRkFMU0U7fQ0KLQlGWF9CT09MCQkJCQkJCQkJSXNCbG9ja2luZygpe3JldHVybiBtX2JCbG9ja2luZzt9DQotDQotCW9wZXJhdG9yCQkJCQkJCQlJSlNfUnVudGltZSooKSB7cmV0dXJuIChJSlNfUnVudGltZSopbV9pc29sYXRlO30NCi0Jdjg6Oklzb2xhdGUqCQkJCQkJCQlHZXRJc29sYXRlKCl7cmV0dXJuIG1faXNvbGF0ZTt9Ow0KLQl2b2lkCQkJCQkJCQkJU2V0SXNvbGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSl7bV9pc29sYXRlID0gaXNvbGF0ZTt9DQotDQotCXY4OjpIYW5kbGU8djg6OkNvbnRleHQ+CQkJCQkJCU5ld0pTQ29udGV4dCgpOw0KLXByb3RlY3RlZDoNCi0JQ0ZYX0FycmF5VGVtcGxhdGU8Q0pTX0NvbnRleHQgKj4JCW1fQ29udGV4dEFycmF5Ow0KLQlDUERGRG9jX0Vudmlyb25tZW50ICoJCQkJCQkJbV9wQXBwOw0KLQlDUERGU0RLX0RvY3VtZW50ICoJCQkJCQltX3BEb2N1bWVudDsNCi0JRlhfQk9PTAkJCQkJCQkJCW1fYkJsb2NraW5nOw0KLQlDSlNfRmllbGRFdmVudCoJCQkJCQkJbV9wRmllbGRFdmVudFBhdGg7DQotDQotCXY4OjpJc29sYXRlKgkJCQkJCQkJbV9pc29sYXRlOw0KLQl2ODo6UGVyc2lzdGVudDx2ODo6Q29udGV4dD4JCQkJCQltX2NvbnRleHQ7DQotCUZYX0JPT0wJCQkJCQkJCQltX2JSZWdpc3RlcmVkOw0KLX07DQotDQotI2VuZGlmIC8vX0pTX1JVTlRJTUVfSF8NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9KU19SVU5USU1FX0hfCisjZGVmaW5lIF9KU19SVU5USU1FX0hfCisKK2NsYXNzIENKU19GaWVsZEV2ZW50Cit7CitwdWJsaWM6CisJQ0ZYX1dpZGVTdHJpbmcJCXNUYXJnZXROYW1lOworCUpTX0VWRU5UX1QJCQllRXZlbnRUeXBlOworCUNKU19GaWVsZEV2ZW50KgkJcE5leHQ7Cit9OworCitjbGFzcyBDSlNfUnVudGltZSA6IHB1YmxpYyBJRlhKU19SdW50aW1lCit7CitwdWJsaWM6CisJQ0pTX1J1bnRpbWUoQ1BERkRvY19FbnZpcm9ubWVudCAqIHBBcHApOworCXZpcnR1YWwgfkNKU19SdW50aW1lKCk7CisKKwl2aXJ0dWFsIElGWEpTX0NvbnRleHQgKgkJCQkJTmV3Q29udGV4dCgpOworCXZpcnR1YWwgdm9pZAkJCQkJCQlSZWxlYXNlQ29udGV4dChJRlhKU19Db250ZXh0ICogcENvbnRleHQpOworCXZpcnR1YWwgSUZYSlNfQ29udGV4dCoJCQkJCUdldEN1cnJlbnRDb250ZXh0KCk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJU2V0UmVhZGVyRG9jdW1lbnQoQ1BERlNES19Eb2N1bWVudCAqcFJlYWRlckRvYyk7CisJdmlydHVhbCBDUERGU0RLX0RvY3VtZW50ICoJCQkJR2V0UmVhZGVyRG9jdW1lbnQoKXtyZXR1cm4gbV9wRG9jdW1lbnQ7fQorCisJdmlydHVhbCB2b2lkCQkJCQkJCUdldE9iamVjdE5hbWVzKENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJR2V0T2JqZWN0Q29uc3RzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJR2V0T2JqZWN0UHJvcHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3T2JqTmFtZSwgQ0ZYX1dpZGVTdHJpbmdBcnJheSYgYXJyYXkpOworCXZpcnR1YWwgdm9pZAkJCQkJCQlHZXRPYmplY3RNZXRob2RzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KTsKKworCXZpcnR1YWwgdm9pZAkJCQkJCQlFeGl0KCk7CisJdmlydHVhbCB2b2lkCQkJCQkJCUVudGVyKCk7CisJdmlydHVhbCBGWF9CT09MCQkJCQkJCUlzRW50ZXJlZCgpOworCisJQ1BERkRvY19FbnZpcm9ubWVudCAqCQkJCQkJCUdldFJlYWRlckFwcCgpe3JldHVybiBtX3BBcHA7fQorCisJRlhfQk9PTAkJCQkJCQkJCUluaXRKU09iamVjdHMoKTsKKworCUZYX0JPT0wJCQkJCQkJCQlBZGRFdmVudFRvTG9vcChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RhcmdldE5hbWUsIEpTX0VWRU5UX1QgZUV2ZW50VHlwZSk7CisJdm9pZAkJCQkJCQkJCVJlbW92ZUV2ZW50SW5Mb29wKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGFyZ2V0TmFtZSwgSlNfRVZFTlRfVCBlRXZlbnRUeXBlKTsKKwl2b2lkCQkJCQkJCQkJUmVtb3ZlRXZlbnRzSW5Mb29wKENKU19GaWVsZEV2ZW50KiBwU3RhcnQpOworCisJdm9pZAkJCQkJCQkJCUJlZ2luQmxvY2soKXttX2JCbG9ja2luZyA9IFRSVUU7fQorCXZvaWQJCQkJCQkJCQlFbmRCbG9jaygpe21fYkJsb2NraW5nID0gRkFMU0U7fQorCUZYX0JPT0wJCQkJCQkJCQlJc0Jsb2NraW5nKCl7cmV0dXJuIG1fYkJsb2NraW5nO30KKworCW9wZXJhdG9yCQkJCQkJCQlJSlNfUnVudGltZSooKSB7cmV0dXJuIChJSlNfUnVudGltZSopbV9pc29sYXRlO30KKwl2ODo6SXNvbGF0ZSoJCQkJCQkJCUdldElzb2xhdGUoKXtyZXR1cm4gbV9pc29sYXRlO307CisJdm9pZAkJCQkJCQkJCVNldElzb2xhdGUodjg6Oklzb2xhdGUqIGlzb2xhdGUpe21faXNvbGF0ZSA9IGlzb2xhdGU7fQorCisJdjg6OkhhbmRsZTx2ODo6Q29udGV4dD4JCQkJCQkJTmV3SlNDb250ZXh0KCk7Citwcm90ZWN0ZWQ6CisJQ0ZYX0FycmF5VGVtcGxhdGU8Q0pTX0NvbnRleHQgKj4JCW1fQ29udGV4dEFycmF5OworCUNQREZEb2NfRW52aXJvbm1lbnQgKgkJCQkJCQltX3BBcHA7CisJQ1BERlNES19Eb2N1bWVudCAqCQkJCQkJbV9wRG9jdW1lbnQ7CisJRlhfQk9PTAkJCQkJCQkJCW1fYkJsb2NraW5nOworCUNKU19GaWVsZEV2ZW50KgkJCQkJCQltX3BGaWVsZEV2ZW50UGF0aDsKKworCXY4OjpJc29sYXRlKgkJCQkJCQkJbV9pc29sYXRlOworCXY4OjpQZXJzaXN0ZW50PHY4OjpDb250ZXh0PgkJCQkJCW1fY29udGV4dDsKKwlGWF9CT09MCQkJCQkJCQkJbV9iUmVnaXN0ZXJlZDsKK307CisKKyNlbmRpZiAvL19KU19SVU5USU1FX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmggYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oCmluZGV4IGY4N2Y5ZTEuLjAzMGNkZDUgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaApAQCAtMSwxODYgKzEsMTg2IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9KU19WQUxVRV9IXw0KLSNkZWZpbmUgX0pTX1ZBTFVFX0hfDQotDQotY2xhc3MgQ0pTX0FycmF5Ow0KLWNsYXNzIENKU19EYXRlOw0KLQ0KLWNsYXNzIENKU19WYWx1ZQ0KLXsNCi1wdWJsaWM6DQotCUNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSk7DQotCUNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSxGWEpTVkFMVUVUWVBFIHQpOw0KLQlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIGNvbnN0IGludCAmaVZhbHVlKTsNCi0JQ0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBjb25zdCBkb3VibGUgJmRWYWx1ZSk7DQotCUNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgY29uc3QgZmxvYXQgJmZWYWx1ZSk7CQ0KLQlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIGNvbnN0IGJvb2wgJmJWYWx1ZSk7DQotCUNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgSlNGWE9iamVjdCk7DQotCUNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgQ0pTX09iamVjdCAqKTsNCi0JQ0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBGWF9MUENTVFIgcFN0cik7DQotCUNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgRlhfTFBDV1NUUiBwV3N0cik7DQotCUNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgQ0pTX0FycmF5JiBhcnJheSk7DQotCQ0KLQl+Q0pTX1ZhbHVlKCk7DQotDQotCXZvaWQgU2V0TnVsbCgpOw0KLSAgICB2b2lkIEF0dGFjaCh2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcFZhbHVlLEZYSlNWQUxVRVRZUEUgdCk7DQotCXZvaWQgQXR0YWNoKENKU19WYWx1ZSAqcFZhbHVlKTsNCi0Jdm9pZCBEZXRhY2goKTsNCi0NCi0NCi0Jb3BlcmF0b3IgaW50KCkgY29uc3Q7DQotCW9wZXJhdG9yIGJvb2woKSBjb25zdDsNCi0Jb3BlcmF0b3IgZG91YmxlKCkgY29uc3Q7DQotCW9wZXJhdG9yIGZsb2F0KCkgY29uc3Q7DQotCW9wZXJhdG9yIENKU19PYmplY3QgKigpIGNvbnN0Ow0KLQkvL29wZXJhdG9yIEpTRlhPYmplY3QgKigpIGNvbnN0Ow0KLQlvcGVyYXRvciB2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KCkgY29uc3Q7DQotCW9wZXJhdG9yIHY4OjpIYW5kbGU8djg6OkFycmF5PigpIGNvbnN0Ow0KLQlvcGVyYXRvciBDRlhfV2lkZVN0cmluZygpIGNvbnN0Ow0KLQkvL29wZXJhdG9yIEZYX1dDSEFSICooKSBjb25zdDsNCi0Jb3BlcmF0b3IgQ0ZYX0J5dGVTdHJpbmcoKSBjb25zdDsNCi0Jdjg6OkhhbmRsZTx2ODo6VmFsdWU+IFRvSlNWYWx1ZSgpOw0KLQ0KLQl2b2lkIG9wZXJhdG9yID0gKGludCBpVmFsdWUpOw0KLQl2b2lkIG9wZXJhdG9yID0gKGJvb2wgYlZhbHVlKTsJDQotCXZvaWQgb3BlcmF0b3IgPSAoZG91YmxlKTsJDQotCXZvaWQgb3BlcmF0b3IgPSAoZmxvYXQpOwkNCi0Jdm9pZCBvcGVyYXRvciA9IChDSlNfT2JqZWN0ICopOwkNCi0Jdm9pZCBvcGVyYXRvciA9ICh2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KTsNCi0vLwl2b2lkIG9wZXJhdG9yID0gKEpTT2JqZWN0ICopOw0KLQl2b2lkIG9wZXJhdG9yID0gKENKU19BcnJheSAmKTsNCi0Jdm9pZCBvcGVyYXRvciA9IChDSlNfRGF0ZSAmKTsNCi0Jdm9pZCBvcGVyYXRvciA9IChGWF9MUENXU1RSIHBXc3RyKTsJDQotCXZvaWQgb3BlcmF0b3IgPSAoRlhfTFBDU1RSIHBTdHIpOwkNCi0Jdm9pZCBvcGVyYXRvciA9IChDSlNfVmFsdWUgdmFsdWUpOw0KLQkNCi0JRlhfQk9PTCBJc0FycmF5T2JqZWN0KCkgY29uc3Q7DQotCUZYX0JPT0wJSXNEYXRlT2JqZWN0KCkgY29uc3Q7DQotCUZYSlNWQUxVRVRZUEUgR2V0VHlwZSgpIGNvbnN0Ow0KLQ0KLQlGWF9CT09MIENvbnZlcnRUb0FycmF5KENKU19BcnJheSAmKSBjb25zdDsNCi0JRlhfQk9PTCBDb252ZXJ0VG9EYXRlKENKU19EYXRlICYpIGNvbnN0Ow0KLQ0KLQl2ODo6SXNvbGF0ZSogR2V0SXNvbGF0ZSgpIHtyZXR1cm4gbV9pc29sYXRlO30NCi1wcm90ZWN0ZWQ6CQ0KLQl2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gbV9wVmFsdWU7DQotCUZYSlNWQUxVRVRZUEUgbV9lVHlwZTsNCi0Jdjg6Oklzb2xhdGUqIG1faXNvbGF0ZTsNCi19Ow0KLQ0KLXRlbXBsYXRlPGNsYXNzIFRZUEU+IGNsYXNzIENKU19QYXJhbWV0ZXJzVG1wbCA6IHB1YmxpYyBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPg0KLXsNCi1wdWJsaWM6DQotCXZvaWQgcHVzaF9iYWNrKFRZUEUgbmV3RWxlbWVudCl7Q0ZYX0FycmF5VGVtcGxhdGU8VFlQRT46OkFkZChuZXdFbGVtZW50KTt9DQotCWludCBzaXplKCkgY29uc3R7cmV0dXJuIENGWF9BcnJheVRlbXBsYXRlPFRZUEU+OjpHZXRTaXplKCk7fQ0KLX07DQotdHlwZWRlZiBDSlNfUGFyYW1ldGVyc1RtcGw8Q0pTX1ZhbHVlPiBDSlNfUGFyYW1ldGVyczsNCi0NCi1jbGFzcyBDSlNfUHJvcFZhbHVlOiBwdWJsaWMgQ0pTX1ZhbHVlDQotew0KLXB1YmxpYzoNCi0JQ0pTX1Byb3BWYWx1ZShjb25zdCBDSlNfVmFsdWUgJik7DQotCUNKU19Qcm9wVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUpOw0KLQl+Q0pTX1Byb3BWYWx1ZSgpOw0KLXB1YmxpYzoNCi0JRlhfQk9PTCBJc1NldHRpbmcoKTsNCi0JRlhfQk9PTCBJc0dldHRpbmcoKTsNCi0Jdm9pZCBvcGVyYXRvcjw8KGludCApOw0KLQl2b2lkIG9wZXJhdG9yPj4oaW50ICYpIGNvbnN0Ow0KLQl2b2lkIG9wZXJhdG9yPDwoYm9vbCk7DQotCXZvaWQgb3BlcmF0b3I+Pihib29sICYpIGNvbnN0Ow0KLQl2b2lkIG9wZXJhdG9yPDwoZG91YmxlICk7DQotCXZvaWQgb3BlcmF0b3I+Pihkb3VibGUgJikgY29uc3Q7DQotCXZvaWQgb3BlcmF0b3I8PChDSlNfT2JqZWN0ICpwT2JqKTsNCi0Jdm9pZCBvcGVyYXRvcj4+KENKU19PYmplY3QgKiZwcE9iaikgY29uc3Q7DQotCXZvaWQgb3BlcmF0b3I8PChDRlhfQnl0ZVN0cmluZyk7DQotCXZvaWQgb3BlcmF0b3I+PihDRlhfQnl0ZVN0cmluZyAmKSBjb25zdDsNCi0Jdm9pZCBvcGVyYXRvcjw8KENGWF9XaWRlU3RyaW5nKTsNCi0Jdm9pZCBvcGVyYXRvcj4+KENGWF9XaWRlU3RyaW5nICYpIGNvbnN0Ow0KLQl2b2lkIG9wZXJhdG9yPDwoRlhfTFBDV1NUUiBjX3N0cmluZyk7DQotDQotCXZvaWQgb3BlcmF0b3I8PChKU0ZYT2JqZWN0KTsNCi0Jdm9pZCBvcGVyYXRvcj4+KEpTRlhPYmplY3QgJikgY29uc3Q7DQotDQotCXZvaWQgb3BlcmF0b3I+PihDSlNfQXJyYXkgJmFycmF5KSBjb25zdDsNCi0Jdm9pZCBvcGVyYXRvcjw8KENKU19BcnJheSAmYXJyYXkpOw0KLQ0KLQl2b2lkIG9wZXJhdG9yPDwoQ0pTX0RhdGUgJmRhdGUpOw0KLQl2b2lkIG9wZXJhdG9yPj4oQ0pTX0RhdGUgJmRhdGUpIGNvbnN0Ow0KLQ0KLQlvcGVyYXRvciB2ODo6SGFuZGxlPHY4OjpWYWx1ZT4oKSBjb25zdDsNCi0NCi0Jdm9pZCBTdGFydFNldHRpbmcoKTsNCi0Jdm9pZCBTdGFydEdldHRpbmcoKTsNCi1wcml2YXRlOg0KLQlGWF9CT09MIG1fYklzU2V0dGluZzsNCi19Ow0KLQ0KLWNsYXNzIENKU19BcnJheQ0KLXsNCi1wdWJsaWM6DQotCUNKU19BcnJheSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSk7DQotCXZpcnR1YWwgfkNKU19BcnJheSgpOw0KLQ0KLQl2b2lkIEF0dGFjaCh2ODo6SGFuZGxlPHY4OjpBcnJheT4gcEFycmF5KTsNCi0Jdm9pZCBHZXRFbGVtZW50KHVuc2lnbmVkIGluZGV4LENKU19WYWx1ZSAmdmFsdWUpOw0KLQl2b2lkIFNldEVsZW1lbnQodW5zaWduZWQgaW5kZXgsQ0pTX1ZhbHVlIHZhbHVlKTsNCi0gICAgaW50IEdldExlbmd0aCgpOw0KLQlGWF9CT09MIElzQXR0YWNoZWQoKTsNCi0Jb3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6QXJyYXk+KCk7DQotDQotCXY4OjpJc29sYXRlKiBHZXRJc29sYXRlKCkge3JldHVybiBtX2lzb2xhdGU7fQ0KLXByaXZhdGU6DQotCXY4OjpIYW5kbGU8djg6OkFycmF5PiBtX3BBcnJheTsNCi0Jdjg6Oklzb2xhdGUqIG1faXNvbGF0ZTsNCi19Ow0KLQ0KLWNsYXNzIENKU19EYXRlDQotew0KLWZyaWVuZCBjbGFzcyBDSlNfVmFsdWU7DQotcHVibGljOg0KLQlDSlNfRGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSk7DQotCUNKU19EYXRlKHY4OjpJc29sYXRlKiBpc29sYXRlLGRvdWJsZSBkTXNlY190aW1lKTsNCi0JQ0pTX0RhdGUodjg6Oklzb2xhdGUqIGlzb2xhdGUsaW50IHllYXIsIGludCBtb24sIGludCBkYXksaW50IGhvdXIsIGludCBtaW4sIGludCBzZWMpOw0KLQl2aXJ0dWFsIH5DSlNfRGF0ZSgpOw0KLQl2b2lkIEF0dGFjaCh2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcERhdGUpOw0KLQ0KLQlpbnQgICAgIEdldFllYXIoKTsNCi0Jdm9pZCAgICBTZXRZZWFyKGludCBpWWVhcik7DQotDQotCWludCAgICAgR2V0TW9udGgoKTsNCi0Jdm9pZCAgICBTZXRNb250aChpbnQgaU1vbnRoKTsNCi0NCi0JaW50ICAgICBHZXREYXkoKTsNCi0Jdm9pZCAgICBTZXREYXkoaW50IGlEYXkpOw0KLQ0KLQlpbnQgICAgIEdldEhvdXJzKCk7DQotCXZvaWQgICAgU2V0SG91cnMoaW50IGlIb3Vycyk7DQotDQotCWludCAgICAgR2V0TWludXRlcygpOw0KLQl2b2lkICAgIFNldE1pbnV0ZXMoaW50IG1pbnV0ZXMpOw0KLQ0KLQlpbnQgICAgIEdldFNlY29uZHMoKTsNCi0Jdm9pZCAgICBTZXRTZWNvbmRzKGludCBzZWNvbmRzKTsNCi0NCi0Jb3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6VmFsdWU+KCk7DQotCW9wZXJhdG9yIGRvdWJsZSgpIGNvbnN0Ow0KLQ0KLQlDRlhfV2lkZVN0cmluZwlUb1N0cmluZygpIGNvbnN0Ow0KLQ0KLQlzdGF0aWMgZG91YmxlCU1ha2VEYXRlKGludCB5ZWFyLCBpbnQgbW9uLCBpbnQgbWRheSxpbnQgaG91ciwgaW50IG1pbiwgaW50IHNlYyxpbnQgbXMpOw0KLQ0KLQlGWF9CT09MCUlzVmFsaWREYXRlKCk7DQotDQotcHJvdGVjdGVkOg0KLQl2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gbV9wRGF0ZTsNCi0Jdjg6Oklzb2xhdGUqIG1faXNvbGF0ZTsNCi19Ow0KLQ0KLSNlbmRpZiAvL19KU19WQUxVRV9IXw0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0pTX1ZBTFVFX0hfCisjZGVmaW5lIF9KU19WQUxVRV9IXworCitjbGFzcyBDSlNfQXJyYXk7CitjbGFzcyBDSlNfRGF0ZTsKKworY2xhc3MgQ0pTX1ZhbHVlCit7CitwdWJsaWM6CisJQ0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlKTsKKwlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIHY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUsRlhKU1ZBTFVFVFlQRSB0KTsKKwlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIGNvbnN0IGludCAmaVZhbHVlKTsKKwlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIGNvbnN0IGRvdWJsZSAmZFZhbHVlKTsKKwlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIGNvbnN0IGZsb2F0ICZmVmFsdWUpOwkKKwlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIGNvbnN0IGJvb2wgJmJWYWx1ZSk7CisJQ0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBKU0ZYT2JqZWN0KTsKKwlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIENKU19PYmplY3QgKik7CisJQ0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBGWF9MUENTVFIgcFN0cik7CisJQ0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBGWF9MUENXU1RSIHBXc3RyKTsKKwlDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIENKU19BcnJheSYgYXJyYXkpOworCQorCX5DSlNfVmFsdWUoKTsKKworCXZvaWQgU2V0TnVsbCgpOworICAgIHZvaWQgQXR0YWNoKHY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUsRlhKU1ZBTFVFVFlQRSB0KTsKKwl2b2lkIEF0dGFjaChDSlNfVmFsdWUgKnBWYWx1ZSk7CisJdm9pZCBEZXRhY2goKTsKKworCisJb3BlcmF0b3IgaW50KCkgY29uc3Q7CisJb3BlcmF0b3IgYm9vbCgpIGNvbnN0OworCW9wZXJhdG9yIGRvdWJsZSgpIGNvbnN0OworCW9wZXJhdG9yIGZsb2F0KCkgY29uc3Q7CisJb3BlcmF0b3IgQ0pTX09iamVjdCAqKCkgY29uc3Q7CisJLy9vcGVyYXRvciBKU0ZYT2JqZWN0ICooKSBjb25zdDsKKwlvcGVyYXRvciB2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KCkgY29uc3Q7CisJb3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6QXJyYXk+KCkgY29uc3Q7CisJb3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSBjb25zdDsKKwkvL29wZXJhdG9yIEZYX1dDSEFSICooKSBjb25zdDsKKwlvcGVyYXRvciBDRlhfQnl0ZVN0cmluZygpIGNvbnN0OworCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBUb0pTVmFsdWUoKTsKKworCXZvaWQgb3BlcmF0b3IgPSAoaW50IGlWYWx1ZSk7CisJdm9pZCBvcGVyYXRvciA9IChib29sIGJWYWx1ZSk7CQorCXZvaWQgb3BlcmF0b3IgPSAoZG91YmxlKTsJCisJdm9pZCBvcGVyYXRvciA9IChmbG9hdCk7CQorCXZvaWQgb3BlcmF0b3IgPSAoQ0pTX09iamVjdCAqKTsJCisJdm9pZCBvcGVyYXRvciA9ICh2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KTsKKy8vCXZvaWQgb3BlcmF0b3IgPSAoSlNPYmplY3QgKik7CisJdm9pZCBvcGVyYXRvciA9IChDSlNfQXJyYXkgJik7CisJdm9pZCBvcGVyYXRvciA9IChDSlNfRGF0ZSAmKTsKKwl2b2lkIG9wZXJhdG9yID0gKEZYX0xQQ1dTVFIgcFdzdHIpOwkKKwl2b2lkIG9wZXJhdG9yID0gKEZYX0xQQ1NUUiBwU3RyKTsJCisJdm9pZCBvcGVyYXRvciA9IChDSlNfVmFsdWUgdmFsdWUpOworCQorCUZYX0JPT0wgSXNBcnJheU9iamVjdCgpIGNvbnN0OworCUZYX0JPT0wJSXNEYXRlT2JqZWN0KCkgY29uc3Q7CisJRlhKU1ZBTFVFVFlQRSBHZXRUeXBlKCkgY29uc3Q7CisKKwlGWF9CT09MIENvbnZlcnRUb0FycmF5KENKU19BcnJheSAmKSBjb25zdDsKKwlGWF9CT09MIENvbnZlcnRUb0RhdGUoQ0pTX0RhdGUgJikgY29uc3Q7CisKKwl2ODo6SXNvbGF0ZSogR2V0SXNvbGF0ZSgpIHtyZXR1cm4gbV9pc29sYXRlO30KK3Byb3RlY3RlZDoJCisJdjg6OkhhbmRsZTx2ODo6VmFsdWU+IG1fcFZhbHVlOworCUZYSlNWQUxVRVRZUEUgbV9lVHlwZTsKKwl2ODo6SXNvbGF0ZSogbV9pc29sYXRlOworfTsKKwordGVtcGxhdGU8Y2xhc3MgVFlQRT4gY2xhc3MgQ0pTX1BhcmFtZXRlcnNUbXBsIDogcHVibGljIENGWF9BcnJheVRlbXBsYXRlPFRZUEU+Cit7CitwdWJsaWM6CisJdm9pZCBwdXNoX2JhY2soVFlQRSBuZXdFbGVtZW50KXtDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6QWRkKG5ld0VsZW1lbnQpO30KKwlpbnQgc2l6ZSgpIGNvbnN0e3JldHVybiBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6R2V0U2l6ZSgpO30KK307Cit0eXBlZGVmIENKU19QYXJhbWV0ZXJzVG1wbDxDSlNfVmFsdWU+IENKU19QYXJhbWV0ZXJzOworCitjbGFzcyBDSlNfUHJvcFZhbHVlOiBwdWJsaWMgQ0pTX1ZhbHVlCit7CitwdWJsaWM6CisJQ0pTX1Byb3BWYWx1ZShjb25zdCBDSlNfVmFsdWUgJik7CisJQ0pTX1Byb3BWYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSk7CisJfkNKU19Qcm9wVmFsdWUoKTsKK3B1YmxpYzoKKwlGWF9CT09MIElzU2V0dGluZygpOworCUZYX0JPT0wgSXNHZXR0aW5nKCk7CisJdm9pZCBvcGVyYXRvcjw8KGludCApOworCXZvaWQgb3BlcmF0b3I+PihpbnQgJikgY29uc3Q7CisJdm9pZCBvcGVyYXRvcjw8KGJvb2wpOworCXZvaWQgb3BlcmF0b3I+Pihib29sICYpIGNvbnN0OworCXZvaWQgb3BlcmF0b3I8PChkb3VibGUgKTsKKwl2b2lkIG9wZXJhdG9yPj4oZG91YmxlICYpIGNvbnN0OworCXZvaWQgb3BlcmF0b3I8PChDSlNfT2JqZWN0ICpwT2JqKTsKKwl2b2lkIG9wZXJhdG9yPj4oQ0pTX09iamVjdCAqJnBwT2JqKSBjb25zdDsKKwl2b2lkIG9wZXJhdG9yPDwoQ0ZYX0J5dGVTdHJpbmcpOworCXZvaWQgb3BlcmF0b3I+PihDRlhfQnl0ZVN0cmluZyAmKSBjb25zdDsKKwl2b2lkIG9wZXJhdG9yPDwoQ0ZYX1dpZGVTdHJpbmcpOworCXZvaWQgb3BlcmF0b3I+PihDRlhfV2lkZVN0cmluZyAmKSBjb25zdDsKKwl2b2lkIG9wZXJhdG9yPDwoRlhfTFBDV1NUUiBjX3N0cmluZyk7CisKKwl2b2lkIG9wZXJhdG9yPDwoSlNGWE9iamVjdCk7CisJdm9pZCBvcGVyYXRvcj4+KEpTRlhPYmplY3QgJikgY29uc3Q7CisKKwl2b2lkIG9wZXJhdG9yPj4oQ0pTX0FycmF5ICZhcnJheSkgY29uc3Q7CisJdm9pZCBvcGVyYXRvcjw8KENKU19BcnJheSAmYXJyYXkpOworCisJdm9pZCBvcGVyYXRvcjw8KENKU19EYXRlICZkYXRlKTsKKwl2b2lkIG9wZXJhdG9yPj4oQ0pTX0RhdGUgJmRhdGUpIGNvbnN0OworCisJb3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6VmFsdWU+KCkgY29uc3Q7CisKKwl2b2lkIFN0YXJ0U2V0dGluZygpOworCXZvaWQgU3RhcnRHZXR0aW5nKCk7Citwcml2YXRlOgorCUZYX0JPT0wgbV9iSXNTZXR0aW5nOworfTsKKworY2xhc3MgQ0pTX0FycmF5Cit7CitwdWJsaWM6CisJQ0pTX0FycmF5KHY4OjpJc29sYXRlKiBpc29sYXRlKTsKKwl2aXJ0dWFsIH5DSlNfQXJyYXkoKTsKKworCXZvaWQgQXR0YWNoKHY4OjpIYW5kbGU8djg6OkFycmF5PiBwQXJyYXkpOworCXZvaWQgR2V0RWxlbWVudCh1bnNpZ25lZCBpbmRleCxDSlNfVmFsdWUgJnZhbHVlKTsKKwl2b2lkIFNldEVsZW1lbnQodW5zaWduZWQgaW5kZXgsQ0pTX1ZhbHVlIHZhbHVlKTsKKyAgICBpbnQgR2V0TGVuZ3RoKCk7CisJRlhfQk9PTCBJc0F0dGFjaGVkKCk7CisJb3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6QXJyYXk+KCk7CisKKwl2ODo6SXNvbGF0ZSogR2V0SXNvbGF0ZSgpIHtyZXR1cm4gbV9pc29sYXRlO30KK3ByaXZhdGU6CisJdjg6OkhhbmRsZTx2ODo6QXJyYXk+IG1fcEFycmF5OworCXY4OjpJc29sYXRlKiBtX2lzb2xhdGU7Cit9OworCitjbGFzcyBDSlNfRGF0ZQoreworZnJpZW5kIGNsYXNzIENKU19WYWx1ZTsKK3B1YmxpYzoKKwlDSlNfRGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSk7CisJQ0pTX0RhdGUodjg6Oklzb2xhdGUqIGlzb2xhdGUsZG91YmxlIGRNc2VjX3RpbWUpOworCUNKU19EYXRlKHY4OjpJc29sYXRlKiBpc29sYXRlLGludCB5ZWFyLCBpbnQgbW9uLCBpbnQgZGF5LGludCBob3VyLCBpbnQgbWluLCBpbnQgc2VjKTsKKwl2aXJ0dWFsIH5DSlNfRGF0ZSgpOworCXZvaWQgQXR0YWNoKHY4OjpIYW5kbGU8djg6OlZhbHVlPiBwRGF0ZSk7CisKKwlpbnQgICAgIEdldFllYXIoKTsKKwl2b2lkICAgIFNldFllYXIoaW50IGlZZWFyKTsKKworCWludCAgICAgR2V0TW9udGgoKTsKKwl2b2lkICAgIFNldE1vbnRoKGludCBpTW9udGgpOworCisJaW50ICAgICBHZXREYXkoKTsKKwl2b2lkICAgIFNldERheShpbnQgaURheSk7CisKKwlpbnQgICAgIEdldEhvdXJzKCk7CisJdm9pZCAgICBTZXRIb3VycyhpbnQgaUhvdXJzKTsKKworCWludCAgICAgR2V0TWludXRlcygpOworCXZvaWQgICAgU2V0TWludXRlcyhpbnQgbWludXRlcyk7CisKKwlpbnQgICAgIEdldFNlY29uZHMoKTsKKwl2b2lkICAgIFNldFNlY29uZHMoaW50IHNlY29uZHMpOworCisJb3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6VmFsdWU+KCk7CisJb3BlcmF0b3IgZG91YmxlKCkgY29uc3Q7CisKKwlDRlhfV2lkZVN0cmluZwlUb1N0cmluZygpIGNvbnN0OworCisJc3RhdGljIGRvdWJsZQlNYWtlRGF0ZShpbnQgeWVhciwgaW50IG1vbiwgaW50IG1kYXksaW50IGhvdXIsIGludCBtaW4sIGludCBzZWMsaW50IG1zKTsKKworCUZYX0JPT0wJSXNWYWxpZERhdGUoKTsKKworcHJvdGVjdGVkOgorCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBtX3BEYXRlOworCXY4OjpJc29sYXRlKiBtX2lzb2xhdGU7Cit9OworCisjZW5kaWYgLy9fSlNfVkFMVUVfSF8KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oCmluZGV4IGQxMzc1Y2MuLjE2NjQ3MmIgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgKQEAgLTEsMzkgKzEsMzkgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0pBVkFTQ1JJUFRfSF8NCi0jZGVmaW5lIF9KQVZBU0NSSVBUX0hfDQotDQotDQotI2lmbmRlZiBfSU5DX1BERkFQSQ0KLQkjZGVmaW5lIF9JTkNfUERGQVBJDQotDQotCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmFwaS9mcGRmX21vZHVsZS5oIiANCi0JI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmZG9jL2ZwZGZfZG9jLmgiIA0KLQkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl92dC5oIiANCi0JI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9meGNydC9meF94bWwuaCIgDQotCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZmRybS9meF9jcnlwdC5oIiANCi0JI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfcGFnZW9iai5oIiANCi0JI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfc2VyaWFsLmgiDQotDQotDQotCSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4X3N5c3RlbWhhbmRsZXIuaCIJDQotI2VuZGlmDQotDQotDQotI2luY2x1ZGUgIi4uL2pzYXBpL2Z4anNfdjguaCINCi0jaW5jbHVkZSAiLi4vZnhlZGl0L2Z4X2VkaXQuaCINCi0jaW5jbHVkZSAiLi4vcGRmd2luZG93L0lQREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vZnNka19tZ3IuaCINCi0NCi0NCi0jaW5jbHVkZSA8c3RyaW5nPg0KLS8vI3ByYWdtYSB3YXJuaW5nKCBkaXNhYmxlIDogNDc4NikgDQotI2luY2x1ZGUgPHZlY3Rvcj4NCi0NCi0NCi0jZW5kaWYgLy9fSkFWQVNDUklQVF9IXw0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0pBVkFTQ1JJUFRfSF8KKyNkZWZpbmUgX0pBVkFTQ1JJUFRfSF8KKworCisjaWZuZGVmIF9JTkNfUERGQVBJCisJI2RlZmluZSBfSU5DX1BERkFQSQorCisJI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfbW9kdWxlLmgiIAorCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmRvYy9mcGRmX2RvYy5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl92dC5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2Z4Y3J0L2Z4X3htbC5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2Zkcm0vZnhfY3J5cHQuaCIgCisJI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfcGFnZW9iai5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9zZXJpYWwuaCIKKworCisJI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhfc3lzdGVtaGFuZGxlci5oIgkKKyNlbmRpZgorCisKKyNpbmNsdWRlICIuLi9qc2FwaS9meGpzX3Y4LmgiCisjaW5jbHVkZSAiLi4vZnhlZGl0L2Z4X2VkaXQuaCIKKyNpbmNsdWRlICIuLi9wZGZ3aW5kb3cvSVBERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uL2ZzZGtfbWdyLmgiCisKKworI2luY2x1ZGUgPHN0cmluZz4KKy8vI3ByYWdtYSB3YXJuaW5nKCBkaXNhYmxlIDogNDc4NikgCisjaW5jbHVkZSA8dmVjdG9yPgorCisKKyNlbmRpZiAvL19KQVZBU0NSSVBUX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaAppbmRleCBhNDg1YTlhLi44ZDRlNjgzIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9QdWJsaWNNZXRob2RzLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvUHVibGljTWV0aG9kcy5oCkBAIC0xLDEwMSArMSwxMDEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1BVQkxJQ01FVEhPRFNfSF8NCi0jZGVmaW5lIF9QVUJMSUNNRVRIT0RTX0hfDQotDQotY2xhc3MgQ0pTX1B1YmxpY01ldGhvZHMgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19QdWJsaWNNZXRob2RzKEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsNCi0JdmlydHVhbCB+Q0pTX1B1YmxpY01ldGhvZHModm9pZCl7fTsNCi0NCi1wdWJsaWM6DQotCXN0YXRpYyBGWF9CT09MIEFGTnVtYmVyX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCXN0YXRpYyBGWF9CT09MIEFGTnVtYmVyX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUyk7DQotCXN0YXRpYyBGWF9CT09MIEFGUGVyY2VudF9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlzdGF0aWMgRlhfQk9PTCBBRlBlcmNlbnRfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0Jc3RhdGljIEZYX0JPT0wgQUZEYXRlX0Zvcm1hdEV4KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0Jc3RhdGljIEZYX0JPT0wgQUZEYXRlX0tleXN0cm9rZUV4KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0Jc3RhdGljIEZYX0JPT0wgQUZEYXRlX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCXN0YXRpYyBGWF9CT09MIEFGRGF0ZV9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlzdGF0aWMgRlhfQk9PTCBBRlRpbWVfRm9ybWF0RXgoT0JKX01FVEhPRF9QQVJBTVMpOyAvLw0KLQlzdGF0aWMgRlhfQk9PTCBBRlRpbWVfS2V5c3Ryb2tlRXgoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlzdGF0aWMgRlhfQk9PTCBBRlRpbWVfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0Jc3RhdGljIEZYX0JPT0wgQUZUaW1lX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUyk7DQotCXN0YXRpYyBGWF9CT09MIEFGU3BlY2lhbF9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlzdGF0aWMgRlhfQk9PTCBBRlNwZWNpYWxfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0Jc3RhdGljIEZYX0JPT0wgQUZTcGVjaWFsX0tleXN0cm9rZUV4KE9CSl9NRVRIT0RfUEFSQU1TKTsvLw0KLQlzdGF0aWMgRlhfQk9PTCBBRlNpbXBsZShPQkpfTUVUSE9EX1BBUkFNUyk7DQotCXN0YXRpYyBGWF9CT09MIEFGTWFrZU51bWJlcihPQkpfTUVUSE9EX1BBUkFNUyk7DQotCXN0YXRpYyBGWF9CT09MIEFGU2ltcGxlX0NhbGN1bGF0ZShPQkpfTUVUSE9EX1BBUkFNUyk7DQotCXN0YXRpYyBGWF9CT09MIEFGUmFuZ2VfVmFsaWRhdGUoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlzdGF0aWMgRlhfQk9PTCBBRk1lcmdlQ2hhbmdlKE9CSl9NRVRIT0RfUEFSQU1TKTsgDQotCXN0YXRpYyBGWF9CT09MIEFGUGFyc2VEYXRlRXgoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlzdGF0aWMgRlhfQk9PTCBBRkV4dHJhY3ROdW1zKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0NCi1wdWJsaWM6DQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGTnVtYmVyX0Zvcm1hdCk7DQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGTnVtYmVyX0tleXN0cm9rZSk7DQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGUGVyY2VudF9Gb3JtYXQpOw0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlBlcmNlbnRfS2V5c3Ryb2tlKTsNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZEYXRlX0Zvcm1hdEV4KTsNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZEYXRlX0tleXN0cm9rZUV4KTsNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZEYXRlX0Zvcm1hdCk7DQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGRGF0ZV9LZXlzdHJva2UpOw0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlRpbWVfRm9ybWF0RXgpOw0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlRpbWVfS2V5c3Ryb2tlRXgpOw0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlRpbWVfRm9ybWF0KTsNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZUaW1lX0tleXN0cm9rZSk7DQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGU3BlY2lhbF9Gb3JtYXQpOw0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlNwZWNpYWxfS2V5c3Ryb2tlKTsNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZTcGVjaWFsX0tleXN0cm9rZUV4KTsNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZTaW1wbGUpOw0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRk1ha2VOdW1iZXIpOwkNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZTaW1wbGVfQ2FsY3VsYXRlKTsNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZSYW5nZV9WYWxpZGF0ZSk7DQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGTWVyZ2VDaGFuZ2UpOw0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlBhcnNlRGF0ZUV4KTsNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZFeHRyYWN0TnVtcyk7DQotDQotCUpTX1NUQVRJQ19ERUNMQVJFX0dMT0JBTF9GVU4oKTsNCi0JDQotcHVibGljOg0KLQlzdGF0aWMgaW50CQkJCVBhcnNlU3RyaW5nSW50ZWdlcihjb25zdCBDRlhfV2lkZVN0cmluZyAmIHN0cmluZyxpbnQgblN0YXJ0LGludCAmIG5Ta2lwLCBpbnQgbk1heFN0ZXApOw0KLQlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJUGFyc2VTdHJpbmdTdHJpbmcoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZywgaW50IG5TdGFydCwgaW50JiBuU2tpcCk7DQotCXN0YXRpYyBkb3VibGUJCQlNYWtlUmVndWxhckRhdGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiB2YWx1ZSxjb25zdCBDRlhfV2lkZVN0cmluZyAmIGZvcm1hdCwgRlhfQk9PTCYgYldyb25nRm9ybWF0KTsNCi0Jc3RhdGljIENGWF9XaWRlU3RyaW5nCU1ha2VGb3JtYXREYXRlKGRvdWJsZSBkRGF0ZSxjb25zdCBDRlhfV2lkZVN0cmluZyAmIGZvcm1hdCk7DQotCXN0YXRpYyBGWF9CT09MCQkJQ29udmVydFN0cmluZ1RvTnVtYmVyKEZYX0xQQ1dTVFIgc3dTb3VyY2UsIGRvdWJsZSAmIGRSZXQsIEZYX0JPT0wgJiBiRG90KTsNCi0Jc3RhdGljIGRvdWJsZQkJCVBhcnNlU3RyaW5nVG9OdW1iZXIoRlhfTFBDV1NUUiBzd1NvdXJjZSk7DQotCXN0YXRpYyBkb3VibGUJCQlQYXJzZU5vcm1hbERhdGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiB2YWx1ZSwgRlhfQk9PTCYgYldyb25nRm9ybWF0KTsNCi0Jc3RhdGljIGRvdWJsZSAgICAgICAgICAgTWFrZUludGVyRGF0ZShDRlhfV2lkZVN0cmluZyBzdHJWYWx1ZSk7DQotCXN0YXRpYyBkb3VibGUJCQlQYXJzZU51bWJlcihGWF9MUENXU1RSIHN3U291cmNlLCBGWF9CT09MJiBiQWxsRGlnaXRzLCBGWF9CT09MJiBiRG90LCBGWF9CT09MJiBiU2lnbiwgRlhfQk9PTCYgYktYSlMpOw0KLQ0KLXB1YmxpYzoNCi0Jc3RhdGljIENGWF9XaWRlU3RyaW5nCVN0ckxUcmltKEZYX0xQQ1dTVFIgcFN0cik7DQotCXN0YXRpYyBDRlhfV2lkZVN0cmluZwlTdHJSVHJpbShGWF9MUENXU1RSIHBTdHIpOw0KLQlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJU3RyVHJpbShGWF9MUENXU1RSIHBTdHIpOw0KLQ0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJU3RyTFRyaW0oRlhfTFBDU1RSIHBTdHIpOw0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJU3RyUlRyaW0oRlhfTFBDU1RSIHBTdHIpOw0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJU3RyVHJpbShGWF9MUENTVFIgcFN0cik7DQotDQotCXN0YXRpYyBGWF9CT09MCQkJSXNOdW1iZXIoRlhfTFBDU1RSIHN0cmluZyk7DQotCXN0YXRpYyBGWF9CT09MCQkJSXNOdW1iZXIoRlhfTFBDV1NUUiBzdHJpbmcpOw0KLQ0KLQlzdGF0aWMgRlhfQk9PTAkJCUlzRGlnaXQoY2hhciBjaCk7DQotCXN0YXRpYyBGWF9CT09MCQkJSXNEaWdpdCh3Y2hhcl90IGNoKTsNCi0Jc3RhdGljIEZYX0JPT0wJCQlJc0FscGhhYmV0aWMod2NoYXJfdCBjaCk7DQotCXN0YXRpYyBGWF9CT09MCQkJSXNBbHBoYU51bWVyaWMod2NoYXJfdCBjaCk7DQotDQotCXN0YXRpYyBGWF9CT09MCQkJbWFza1NhdGlzZmllZCh3Y2hhcl90IGNfQ2hhbmdlLHdjaGFyX3QgY19NYXNrKTsNCi0Jc3RhdGljIEZYX0JPT0wJCQlpc1Jlc2VydmVkTWFza0NoYXIod2NoYXJfdCBjaCk7DQotDQotCXN0YXRpYyBkb3VibGUJCQlBRl9TaW1wbGUoRlhfTFBDV1NUUiBzRnVjdGlvbiwgZG91YmxlIGRWYWx1ZTEsIGRvdWJsZSBkVmFsdWUyKTsNCi0Jc3RhdGljIENKU19BcnJheQkJQUZfTWFrZUFycmF5RnJvbUxpc3Qodjg6Oklzb2xhdGUqIGlzb2xhdGUsIENKU19WYWx1ZSB2YWwpOw0KLX07DQotDQotI2VuZGlmIC8vX1BVQkxJQ01FVEhPRFNfSF8NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9QVUJMSUNNRVRIT0RTX0hfCisjZGVmaW5lIF9QVUJMSUNNRVRIT0RTX0hfCisKK2NsYXNzIENKU19QdWJsaWNNZXRob2RzIDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfUHVibGljTWV0aG9kcyhKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307CisJdmlydHVhbCB+Q0pTX1B1YmxpY01ldGhvZHModm9pZCl7fTsKKworcHVibGljOgorCXN0YXRpYyBGWF9CT09MIEFGTnVtYmVyX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUyk7CisJc3RhdGljIEZYX0JPT0wgQUZOdW1iZXJfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlzdGF0aWMgRlhfQk9PTCBBRlBlcmNlbnRfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlzdGF0aWMgRlhfQk9PTCBBRlBlcmNlbnRfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlzdGF0aWMgRlhfQk9PTCBBRkRhdGVfRm9ybWF0RXgoT0JKX01FVEhPRF9QQVJBTVMpOworCXN0YXRpYyBGWF9CT09MIEFGRGF0ZV9LZXlzdHJva2VFeChPQkpfTUVUSE9EX1BBUkFNUyk7CisJc3RhdGljIEZYX0JPT0wgQUZEYXRlX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUyk7CisJc3RhdGljIEZYX0JPT0wgQUZEYXRlX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUyk7CisJc3RhdGljIEZYX0JPT0wgQUZUaW1lX0Zvcm1hdEV4KE9CSl9NRVRIT0RfUEFSQU1TKTsgLy8KKwlzdGF0aWMgRlhfQk9PTCBBRlRpbWVfS2V5c3Ryb2tlRXgoT0JKX01FVEhPRF9QQVJBTVMpOworCXN0YXRpYyBGWF9CT09MIEFGVGltZV9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpOworCXN0YXRpYyBGWF9CT09MIEFGVGltZV9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpOworCXN0YXRpYyBGWF9CT09MIEFGU3BlY2lhbF9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpOworCXN0YXRpYyBGWF9CT09MIEFGU3BlY2lhbF9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpOworCXN0YXRpYyBGWF9CT09MIEFGU3BlY2lhbF9LZXlzdHJva2VFeChPQkpfTUVUSE9EX1BBUkFNUyk7Ly8KKwlzdGF0aWMgRlhfQk9PTCBBRlNpbXBsZShPQkpfTUVUSE9EX1BBUkFNUyk7CisJc3RhdGljIEZYX0JPT0wgQUZNYWtlTnVtYmVyKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlzdGF0aWMgRlhfQk9PTCBBRlNpbXBsZV9DYWxjdWxhdGUoT0JKX01FVEhPRF9QQVJBTVMpOworCXN0YXRpYyBGWF9CT09MIEFGUmFuZ2VfVmFsaWRhdGUoT0JKX01FVEhPRF9QQVJBTVMpOworCXN0YXRpYyBGWF9CT09MIEFGTWVyZ2VDaGFuZ2UoT0JKX01FVEhPRF9QQVJBTVMpOyAKKwlzdGF0aWMgRlhfQk9PTCBBRlBhcnNlRGF0ZUV4KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlzdGF0aWMgRlhfQk9PTCBBRkV4dHJhY3ROdW1zKE9CSl9NRVRIT0RfUEFSQU1TKTsKKworcHVibGljOgorCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGTnVtYmVyX0Zvcm1hdCk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZOdW1iZXJfS2V5c3Ryb2tlKTsKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlBlcmNlbnRfRm9ybWF0KTsKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlBlcmNlbnRfS2V5c3Ryb2tlKTsKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRkRhdGVfRm9ybWF0RXgpOworCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGRGF0ZV9LZXlzdHJva2VFeCk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZEYXRlX0Zvcm1hdCk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZEYXRlX0tleXN0cm9rZSk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZUaW1lX0Zvcm1hdEV4KTsKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTihBRlRpbWVfS2V5c3Ryb2tlRXgpOworCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGVGltZV9Gb3JtYXQpOworCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGVGltZV9LZXlzdHJva2UpOworCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGU3BlY2lhbF9Gb3JtYXQpOworCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGU3BlY2lhbF9LZXlzdHJva2UpOworCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGU3BlY2lhbF9LZXlzdHJva2VFeCk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZTaW1wbGUpOworCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGTWFrZU51bWJlcik7CQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOKEFGU2ltcGxlX0NhbGN1bGF0ZSk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZSYW5nZV9WYWxpZGF0ZSk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZNZXJnZUNoYW5nZSk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZQYXJzZURhdGVFeCk7CisJSlNfU1RBVElDX0dMT0JBTF9GVU4oQUZFeHRyYWN0TnVtcyk7CisKKwlKU19TVEFUSUNfREVDTEFSRV9HTE9CQUxfRlVOKCk7CisJCitwdWJsaWM6CisJc3RhdGljIGludAkJCQlQYXJzZVN0cmluZ0ludGVnZXIoY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBzdHJpbmcsaW50IG5TdGFydCxpbnQgJiBuU2tpcCwgaW50IG5NYXhTdGVwKTsKKwlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJUGFyc2VTdHJpbmdTdHJpbmcoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZywgaW50IG5TdGFydCwgaW50JiBuU2tpcCk7CisJc3RhdGljIGRvdWJsZQkJCU1ha2VSZWd1bGFyRGF0ZShjb25zdCBDRlhfV2lkZVN0cmluZyAmIHZhbHVlLGNvbnN0IENGWF9XaWRlU3RyaW5nICYgZm9ybWF0LCBGWF9CT09MJiBiV3JvbmdGb3JtYXQpOworCXN0YXRpYyBDRlhfV2lkZVN0cmluZwlNYWtlRm9ybWF0RGF0ZShkb3VibGUgZERhdGUsY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBmb3JtYXQpOworCXN0YXRpYyBGWF9CT09MCQkJQ29udmVydFN0cmluZ1RvTnVtYmVyKEZYX0xQQ1dTVFIgc3dTb3VyY2UsIGRvdWJsZSAmIGRSZXQsIEZYX0JPT0wgJiBiRG90KTsKKwlzdGF0aWMgZG91YmxlCQkJUGFyc2VTdHJpbmdUb051bWJlcihGWF9MUENXU1RSIHN3U291cmNlKTsKKwlzdGF0aWMgZG91YmxlCQkJUGFyc2VOb3JtYWxEYXRlKGNvbnN0IENGWF9XaWRlU3RyaW5nICYgdmFsdWUsIEZYX0JPT0wmIGJXcm9uZ0Zvcm1hdCk7CisJc3RhdGljIGRvdWJsZSAgICAgICAgICAgTWFrZUludGVyRGF0ZShDRlhfV2lkZVN0cmluZyBzdHJWYWx1ZSk7CisJc3RhdGljIGRvdWJsZQkJCVBhcnNlTnVtYmVyKEZYX0xQQ1dTVFIgc3dTb3VyY2UsIEZYX0JPT0wmIGJBbGxEaWdpdHMsIEZYX0JPT0wmIGJEb3QsIEZYX0JPT0wmIGJTaWduLCBGWF9CT09MJiBiS1hKUyk7CisKK3B1YmxpYzoKKwlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJU3RyTFRyaW0oRlhfTFBDV1NUUiBwU3RyKTsKKwlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJU3RyUlRyaW0oRlhfTFBDV1NUUiBwU3RyKTsKKwlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJU3RyVHJpbShGWF9MUENXU1RSIHBTdHIpOworCisJc3RhdGljIENGWF9CeXRlU3RyaW5nCVN0ckxUcmltKEZYX0xQQ1NUUiBwU3RyKTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJU3RyUlRyaW0oRlhfTFBDU1RSIHBTdHIpOworCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwlTdHJUcmltKEZYX0xQQ1NUUiBwU3RyKTsKKworCXN0YXRpYyBGWF9CT09MCQkJSXNOdW1iZXIoRlhfTFBDU1RSIHN0cmluZyk7CisJc3RhdGljIEZYX0JPT0wJCQlJc051bWJlcihGWF9MUENXU1RSIHN0cmluZyk7CisKKwlzdGF0aWMgRlhfQk9PTAkJCUlzRGlnaXQoY2hhciBjaCk7CisJc3RhdGljIEZYX0JPT0wJCQlJc0RpZ2l0KHdjaGFyX3QgY2gpOworCXN0YXRpYyBGWF9CT09MCQkJSXNBbHBoYWJldGljKHdjaGFyX3QgY2gpOworCXN0YXRpYyBGWF9CT09MCQkJSXNBbHBoYU51bWVyaWMod2NoYXJfdCBjaCk7CisKKwlzdGF0aWMgRlhfQk9PTAkJCW1hc2tTYXRpc2ZpZWQod2NoYXJfdCBjX0NoYW5nZSx3Y2hhcl90IGNfTWFzayk7CisJc3RhdGljIEZYX0JPT0wJCQlpc1Jlc2VydmVkTWFza0NoYXIod2NoYXJfdCBjaCk7CisKKwlzdGF0aWMgZG91YmxlCQkJQUZfU2ltcGxlKEZYX0xQQ1dTVFIgc0Z1Y3Rpb24sIGRvdWJsZSBkVmFsdWUxLCBkb3VibGUgZFZhbHVlMik7CisJc3RhdGljIENKU19BcnJheQkJQUZfTWFrZUFycmF5RnJvbUxpc3Qodjg6Oklzb2xhdGUqIGlzb2xhdGUsIENKU19WYWx1ZSB2YWwpOworfTsKKworI2VuZGlmIC8vX1BVQkxJQ01FVEhPRFNfSF8KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L2FwcC5oIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvYXBwLmgKaW5kZXggMzVlZTQwMS4uNjI3M2E3ZCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvYXBwLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvYXBwLmgKQEAgLTEsMjI1ICsxLDIyNSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfQVBQX0hfDQotI2RlZmluZSBfQVBQX0hfDQotDQotY2xhc3MgQ0pTX1J1bnRpbWU7DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBUaW1lck9iaiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotY2xhc3MgQ0pTX1RpbWVyOw0KLQ0KLWNsYXNzIFRpbWVyT2JqIDogcHVibGljIENKU19FbWJlZE9iag0KLXsNCi1wdWJsaWM6DQotCVRpbWVyT2JqKENKU19PYmplY3QqIHBKU09iamVjdCk7DQotCXZpcnR1YWwgflRpbWVyT2JqKCk7DQotCQ0KLXB1YmxpYzoNCi0Jdm9pZAkJCVNldFRpbWVyKENKU19UaW1lciogcFRpbWVyKTsNCi0JQ0pTX1RpbWVyKgkJR2V0VGltZXIoKSBjb25zdDsNCi0JDQotcHJpdmF0ZToNCi0JQ0pTX1RpbWVyKgkJbV9wVGltZXI7DQotfTsNCi0NCi1jbGFzcyBDSlNfVGltZXJPYmogOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19UaW1lck9iaihKU0ZYT2JqZWN0IHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fQ0KLQl2aXJ0dWFsIH5DSlNfVGltZXJPYmooKXt9DQotCQ0KLQlERUNMQVJFX0pTX0NMQVNTKENKU19UaW1lck9iaik7DQotfTsNCi0NCi0NCi0vLyBzdHJ1Y3QgQVBQX01FTlVJVEVNX0FSUkFZOw0KLS8vIA0KLS8vIHN0cnVjdCBBUFBfTUVOVUlURU0NCi0vLyB7DQotLy8gCUFQUF9NRU5VSVRFTSgpIDogb1N1Yk1lbnUoTlVMTCksIGNOYW1lKEwiIiksIGNSZXR1cm4oTCIiKSwgYk1hcmtlZChmYWxzZSksIGJFbmFibGVkKHRydWUpDQotLy8gCXsNCi0vLyAJfQ0KLS8vIAlDRlhfV2lkZVN0cmluZyBjTmFtZTsNCi0vLyAJQ0ZYX1dpZGVTdHJpbmcgY1JldHVybjsNCi0vLyAJQVBQX01FTlVJVEVNX0FSUkFZKiBvU3ViTWVudTsNCi0vLyAJYm9vbCBiTWFya2VkOw0KLS8vIAlib29sIGJFbmFibGVkOw0KLS8vIH07DQotDQotLy8gc3RydWN0IEFQUF9NRU5VSVRFTV9BUlJBWQ0KLS8vIHsNCi0vLyAJQVBQX01FTlVJVEVNX0FSUkFZKCkgOiBtX2hNZW51KE5VTEwpLCBwQ29udGVudHMoTlVMTCksIG5TaXplKDApDQotLy8gCXsNCi0vLyANCi0vLyAJfQ0KLS8vIAlBUFBfTUVOVUlURU0gKiBwQ29udGVudHM7DQotLy8gCUhNRU5VIG1faE1lbnU7DQotLy8gCWludAluU2l6ZTsNCi0vLyB9Ow0KLQ0KLS8vIHN0cnVjdCBBUFBfTUVOVTsNCi0vLyBzdHJ1Y3QgQVBQX01FTlVfQVJSQVkNCi0vLyB7DQotLy8gCUFQUF9NRU5VX0FSUkFZKCk6DQotLy8gICAgIHBDb250ZW50KE5VTEwpDQotLy8gCXsNCi0vLyAJfQ0KLS8vIA0KLS8vIAlBUFBfTUVOVSogcENvbnRlbnQ7DQotLy8gfTsNCi0NCi0vLyBzdHJ1Y3QgQVBQX01FTlUNCi0vLyB7DQotLy8gCUFQUF9NRU5VKCk6YlN1Yk1lbnUoZmFsc2UpLCANCi0vLyAJU3ViTWVudUl0ZW1zKE5VTEwpLA0KLS8vIAljd01lbnVJdGVtTmFtZShMIiIpLA0KLS8vIAloTWVudShOVUxMKSwNCi0vLyAJaVNpemUoMCkNCi0vLyAJew0KLS8vIA0KLS8vIAl9DQotLy8gDQotLy8gCUFQUF9NRU5VKENGWF9XaWRlU3RyaW5nICZjd05hbWUpOg0KLS8vIAljd01lbnVJdGVtTmFtZShjd05hbWUpLA0KLS8vIAliU3ViTWVudShmYWxzZSksDQotLy8gCVN1Yk1lbnVJdGVtcyhOVUxMKSwNCi0vLyAJaE1lbnUoTlVMTCksDQotLy8gCWlTaXplKDApDQotLy8gCXsNCi0vLyANCi0vLyAJfQ0KLS8vIAkNCi0vLyAJQ0ZYX1dpZGVTdHJpbmcgY3dNZW51SXRlbU5hbWU7DQotLy8gCWJvb2wgYlN1Yk1lbnU7CQ0KLS8vIAlBUFBfTUVOVV9BUlJBWSogU3ViTWVudUl0ZW1zOw0KLS8vIAlpbnQgaVNpemU7DQotLy8gCUhNRU5VIGhNZW51Ow0KLS8vIH07DQotDQotY2xhc3MgYXBwIDogcHVibGljIENKU19FbWJlZE9iag0KLXsNCi1wdWJsaWM6DQotCWFwcChDSlNfT2JqZWN0ICogcEpTT2JqZWN0KTsNCi0JdmlydHVhbCB+YXBwKCk7DQotDQotcHVibGljOg0KLQlGWF9CT09MCQkJCQkJYWN0aXZlRG9jcyhPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MCQkJCQkJY2FsY3VsYXRlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQlmb3Jtc1ZlcnNpb24oT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCWZzKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQlmdWxsc2NyZWVuKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQlsYW5ndWFnZShPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MCQkJCQkJbWVkaWEoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCXBsYXRmb3JtKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQlydW50aW1lSGlnaGxpZ2h0KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQl2aWV3ZXJUeXBlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQl2aWV3ZXJWYXJpYXRpb24oT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCXZpZXdlclZlcnNpb24oT0JKX1BST1BfUEFSQU1TKTsJDQotDQotDQotCUZYX0JPT0wJCQkJCQlhbGVydChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQliZWVwKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCWJyb3dzZUZvckRvYyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQljbGVhckludGVydmFsKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCWNsZWFyVGltZU91dChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQlleGVjRGlhbG9nKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCWV4ZWNNZW51SXRlbShPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQlmaW5kQ29tcG9uZW50KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCWdvQmFjayhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQlnb0ZvcndhcmQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCQkJCQkJbGF1bmNoVVJMKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCW1haWxNc2coT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCQkJCQkJbmV3RkRGKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCW5ld0RvYyhPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wJCQkJCQlvcGVuRG9jKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCW9wZW5GREYoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCQkJCQkJcG9wVXBNZW51RXgoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MCQkJCQkJcG9wVXBNZW51KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCXJlc3BvbnNlKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCXNldEludGVydmFsKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTAkJCQkJCXNldFRpbWVPdXQoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQ0KLXByaXZhdGU6DQotLy8JRlhfRFdPUkQJCQkJCUFwcEdldFRpY2tDb3VudCgpOyANCi0Jdm9pZAkJCQkJCVRpbWVyUHJvYyhDSlNfVGltZXIqIHBUaW1lcik7DQotCXZvaWQJCQkJCQlSdW5Kc1NjcmlwdChDSlNfUnVudGltZSAqIHBSdW50aW1lLGNvbnN0IENGWF9XaWRlU3RyaW5nICYgd3NTY3JpcHQpOw0KLS8vCXZvaWQJCQkJCQlQYXJzZVBvcHVwTWVudU9iaihBUFBfTUVOVUlURU0gKiBwcE1lbnVJdGVtLEpTT2JqZWN0ICogcE9iaik7DQotLy8Jdm9pZAkJCQkJCURlbGV0ZU1lbnVJdGVtcyhBUFBfTUVOVUlURU1fQVJSQVkgKiBwTWVudUl0ZW1zKTsNCi0vLyAJdm9pZAkJCQkJCUFkZE1lbnVJdGVtKEFQUF9NRU5VSVRFTV9BUlJBWSAqIHBNZW51SXRlbXMsIEhNRU5VIGhNZW51LCBNRU5VSVRFTUlORk8gTWVudUl0ZW1JbmZvKTsNCi0vLyAJdm9pZAkJCQkJCUluaXRNZW51SXRlbUluZm8oTUVOVUlURU1JTkZPJiBNZW51SXRlbUluZm8pOw0KLS8vIAl2b2lkCQkJCQkJRGVzdHJveVBvcFVwTWVudSgpOw0KLQ0KLS8vIAl2b2lkCQkJCQkJUGFyc2VyTWVudUl0ZW0oQVBQX01FTlUqIHBIZWFkLCBjb25zdCBDSlNfUGFyYW1ldGVycyZwYXJhbXMpOw0KLS8vIAl2b2lkCQkJCQkJQWRkSXRlbVRvTWVudShBUFBfTUVOVSogcEhlYWQsIEhNRU5VIGhNZW51LCBNRU5VSVRFTUlORk8gTWVudUl0ZW1JbmZvKTsNCi0vLyAJdm9pZAkJCQkJCURlc3Ryb3lNZW51SXRlbXMoQVBQX01FTlUqIHBIZWFkKTsNCi0NCi1wdWJsaWM6DQotCXN0YXRpYyBDRlhfV2lkZVN0cmluZwkJU3lzUGF0aFRvUERGUGF0aChjb25zdCBDRlhfV2lkZVN0cmluZyYgc09sZFBhdGgpOw0KLQlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJCVBERlBhdGhUb1N5c1BhdGgoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNPbGRQYXRoKTsNCi0Jc3RhdGljIENGWF9XaWRlU3RyaW5nCQlSZWxhdGl2ZVBhdGhUb1N5c1BhdGgoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNPbGRQYXRoLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpbGVQYXRoKTsNCi0NCi0NCi1wcml2YXRlOg0KLQ0KLQlib29sCQkJCQkJbV9iQ2FsY3VsYXRlOwkNCi0JQ0pTX1J1bnRpbWUqCQkJCW1fcFJ1bnRpbWU7DQotCWJvb2wJCQkJCQltX2JSdW50aW1lSGlnaExpZ2h0Ow0KLQ0KLQlDRlhfQXJyYXlUZW1wbGF0ZTxDSlNfVGltZXIqPgltX2FUaW1lcjsNCi0vLwlBUFBfTUVOVSoJCQkJCW1fcE1lbnVIZWFkOw0KLQkNCi1wdWJsaWM6DQotLy8Jc3RhdGljIENSZWFkZXJfQXBwKiBzX0FwcDsNCi19Ow0KLQ0KLWNsYXNzIENKU19BcHAgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19BcHAoSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9Ow0KLQl2aXJ0dWFsIH5DSlNfQXBwKHZvaWQpe307DQotDQotCURFQ0xBUkVfSlNfQ0xBU1MoQ0pTX0FwcCk7DQotDQotCUpTX1NUQVRJQ19QUk9QKGFjdGl2ZURvY3MsIGFwcCk7DQotCUpTX1NUQVRJQ19QUk9QKGNhbGN1bGF0ZSwgYXBwKTsNCi0JSlNfU1RBVElDX1BST1AoZm9ybXNWZXJzaW9uLCBhcHApOw0KLQlKU19TVEFUSUNfUFJPUChmcywgYXBwKTsNCi0JSlNfU1RBVElDX1BST1AoZnVsbHNjcmVlbiwgYXBwKTsNCi0JSlNfU1RBVElDX1BST1AobGFuZ3VhZ2UsIGFwcCk7DQotCUpTX1NUQVRJQ19QUk9QKG1lZGlhLCBhcHApOw0KLQlKU19TVEFUSUNfUFJPUChwbGF0Zm9ybSwgYXBwKTsNCi0JSlNfU1RBVElDX1BST1AocnVudGltZUhpZ2hsaWdodCwgYXBwKTsNCi0JSlNfU1RBVElDX1BST1Aodmlld2VyVHlwZSwgYXBwKTsNCi0JSlNfU1RBVElDX1BST1Aodmlld2VyVmFyaWF0aW9uLCBhcHApOw0KLQlKU19TVEFUSUNfUFJPUCh2aWV3ZXJWZXJzaW9uLCBhcHApOwkNCi0NCi0JSlNfU1RBVElDX01FVEhPRChhbGVydCwgYXBwKTsNCi0JSlNfU1RBVElDX01FVEhPRChiZWVwLCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKGJyb3dzZUZvckRvYywgYXBwKTsNCi0JSlNfU1RBVElDX01FVEhPRChjbGVhckludGVydmFsLCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKGNsZWFyVGltZU91dCwgYXBwKTsNCi0JSlNfU1RBVElDX01FVEhPRChleGVjRGlhbG9nLCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKGV4ZWNNZW51SXRlbSwgYXBwKTsNCi0JSlNfU1RBVElDX01FVEhPRChmaW5kQ29tcG9uZW50LCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKGdvQmFjaywgYXBwKTsNCi0JSlNfU1RBVElDX01FVEhPRChnb0ZvcndhcmQsIGFwcCk7DQotCUpTX1NUQVRJQ19NRVRIT0QobGF1bmNoVVJMLCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKG1haWxNc2csIGFwcCk7DQotCUpTX1NUQVRJQ19NRVRIT0QobmV3RkRGLCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKG5ld0RvYywgYXBwKTsNCi0JSlNfU1RBVElDX01FVEhPRChvcGVuRG9jLCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKG9wZW5GREYsIGFwcCk7DQotCUpTX1NUQVRJQ19NRVRIT0QocG9wVXBNZW51RXgsIGFwcCk7DQotCUpTX1NUQVRJQ19NRVRIT0QocG9wVXBNZW51LCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKHJlc3BvbnNlLCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKHNldEludGVydmFsLCBhcHApOw0KLQlKU19TVEFUSUNfTUVUSE9EKHNldFRpbWVPdXQsIGFwcCk7DQotDQotfTsNCi0NCi0jZW5kaWYgLy9fQVBQX0hfDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfQVBQX0hfCisjZGVmaW5lIF9BUFBfSF8KKworY2xhc3MgQ0pTX1J1bnRpbWU7CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVGltZXJPYmogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitjbGFzcyBDSlNfVGltZXI7CisKK2NsYXNzIFRpbWVyT2JqIDogcHVibGljIENKU19FbWJlZE9iagoreworcHVibGljOgorCVRpbWVyT2JqKENKU19PYmplY3QqIHBKU09iamVjdCk7CisJdmlydHVhbCB+VGltZXJPYmooKTsKKwkKK3B1YmxpYzoKKwl2b2lkCQkJU2V0VGltZXIoQ0pTX1RpbWVyKiBwVGltZXIpOworCUNKU19UaW1lcioJCUdldFRpbWVyKCkgY29uc3Q7CisJCitwcml2YXRlOgorCUNKU19UaW1lcioJCW1fcFRpbWVyOworfTsKKworY2xhc3MgQ0pTX1RpbWVyT2JqIDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfVGltZXJPYmooSlNGWE9iamVjdCBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge30KKwl2aXJ0dWFsIH5DSlNfVGltZXJPYmooKXt9CisJCisJREVDTEFSRV9KU19DTEFTUyhDSlNfVGltZXJPYmopOworfTsKKworCisvLyBzdHJ1Y3QgQVBQX01FTlVJVEVNX0FSUkFZOworLy8gCisvLyBzdHJ1Y3QgQVBQX01FTlVJVEVNCisvLyB7CisvLyAJQVBQX01FTlVJVEVNKCkgOiBvU3ViTWVudShOVUxMKSwgY05hbWUoTCIiKSwgY1JldHVybihMIiIpLCBiTWFya2VkKGZhbHNlKSwgYkVuYWJsZWQodHJ1ZSkKKy8vIAl7CisvLyAJfQorLy8gCUNGWF9XaWRlU3RyaW5nIGNOYW1lOworLy8gCUNGWF9XaWRlU3RyaW5nIGNSZXR1cm47CisvLyAJQVBQX01FTlVJVEVNX0FSUkFZKiBvU3ViTWVudTsKKy8vIAlib29sIGJNYXJrZWQ7CisvLyAJYm9vbCBiRW5hYmxlZDsKKy8vIH07CisKKy8vIHN0cnVjdCBBUFBfTUVOVUlURU1fQVJSQVkKKy8vIHsKKy8vIAlBUFBfTUVOVUlURU1fQVJSQVkoKSA6IG1faE1lbnUoTlVMTCksIHBDb250ZW50cyhOVUxMKSwgblNpemUoMCkKKy8vIAl7CisvLyAKKy8vIAl9CisvLyAJQVBQX01FTlVJVEVNICogcENvbnRlbnRzOworLy8gCUhNRU5VIG1faE1lbnU7CisvLyAJaW50CW5TaXplOworLy8gfTsKKworLy8gc3RydWN0IEFQUF9NRU5VOworLy8gc3RydWN0IEFQUF9NRU5VX0FSUkFZCisvLyB7CisvLyAJQVBQX01FTlVfQVJSQVkoKToKKy8vICAgICBwQ29udGVudChOVUxMKQorLy8gCXsKKy8vIAl9CisvLyAKKy8vIAlBUFBfTUVOVSogcENvbnRlbnQ7CisvLyB9OworCisvLyBzdHJ1Y3QgQVBQX01FTlUKKy8vIHsKKy8vIAlBUFBfTUVOVSgpOmJTdWJNZW51KGZhbHNlKSwgCisvLyAJU3ViTWVudUl0ZW1zKE5VTEwpLAorLy8gCWN3TWVudUl0ZW1OYW1lKEwiIiksCisvLyAJaE1lbnUoTlVMTCksCisvLyAJaVNpemUoMCkKKy8vIAl7CisvLyAKKy8vIAl9CisvLyAKKy8vIAlBUFBfTUVOVShDRlhfV2lkZVN0cmluZyAmY3dOYW1lKToKKy8vIAljd01lbnVJdGVtTmFtZShjd05hbWUpLAorLy8gCWJTdWJNZW51KGZhbHNlKSwKKy8vIAlTdWJNZW51SXRlbXMoTlVMTCksCisvLyAJaE1lbnUoTlVMTCksCisvLyAJaVNpemUoMCkKKy8vIAl7CisvLyAKKy8vIAl9CisvLyAJCisvLyAJQ0ZYX1dpZGVTdHJpbmcgY3dNZW51SXRlbU5hbWU7CisvLyAJYm9vbCBiU3ViTWVudTsJCisvLyAJQVBQX01FTlVfQVJSQVkqIFN1Yk1lbnVJdGVtczsKKy8vIAlpbnQgaVNpemU7CisvLyAJSE1FTlUgaE1lbnU7CisvLyB9OworCitjbGFzcyBhcHAgOiBwdWJsaWMgQ0pTX0VtYmVkT2JqCit7CitwdWJsaWM6CisJYXBwKENKU19PYmplY3QgKiBwSlNPYmplY3QpOworCXZpcnR1YWwgfmFwcCgpOworCitwdWJsaWM6CisJRlhfQk9PTAkJCQkJCWFjdGl2ZURvY3MoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJY2FsY3VsYXRlKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCWZvcm1zVmVyc2lvbihPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQlmcyhPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQlmdWxsc2NyZWVuKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCWxhbmd1YWdlKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCW1lZGlhKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCXBsYXRmb3JtKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCXJ1bnRpbWVIaWdobGlnaHQoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJdmlld2VyVHlwZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQl2aWV3ZXJWYXJpYXRpb24oT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJdmlld2VyVmVyc2lvbihPQkpfUFJPUF9QQVJBTVMpOwkKKworCisJRlhfQk9PTAkJCQkJCWFsZXJ0KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJYmVlcChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCWJyb3dzZUZvckRvYyhPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCWNsZWFySW50ZXJ2YWwoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQljbGVhclRpbWVPdXQoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQlleGVjRGlhbG9nKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJZXhlY01lbnVJdGVtKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJZmluZENvbXBvbmVudChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCWdvQmFjayhPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCWdvRm9yd2FyZChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCWxhdW5jaFVSTChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCW1haWxNc2coT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQluZXdGREYoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQluZXdEb2MoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQlvcGVuRG9jKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJb3BlbkZERihPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCXBvcFVwTWVudUV4KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJcG9wVXBNZW51KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MCQkJCQkJcmVzcG9uc2UoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wJCQkJCQlzZXRJbnRlcnZhbChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTAkJCQkJCXNldFRpbWVPdXQoT0JKX01FVEhPRF9QQVJBTVMpOworCitwcml2YXRlOgorLy8JRlhfRFdPUkQJCQkJCUFwcEdldFRpY2tDb3VudCgpOyAKKwl2b2lkCQkJCQkJVGltZXJQcm9jKENKU19UaW1lciogcFRpbWVyKTsKKwl2b2lkCQkJCQkJUnVuSnNTY3JpcHQoQ0pTX1J1bnRpbWUgKiBwUnVudGltZSxjb25zdCBDRlhfV2lkZVN0cmluZyAmIHdzU2NyaXB0KTsKKy8vCXZvaWQJCQkJCQlQYXJzZVBvcHVwTWVudU9iaihBUFBfTUVOVUlURU0gKiBwcE1lbnVJdGVtLEpTT2JqZWN0ICogcE9iaik7CisvLwl2b2lkCQkJCQkJRGVsZXRlTWVudUl0ZW1zKEFQUF9NRU5VSVRFTV9BUlJBWSAqIHBNZW51SXRlbXMpOworLy8gCXZvaWQJCQkJCQlBZGRNZW51SXRlbShBUFBfTUVOVUlURU1fQVJSQVkgKiBwTWVudUl0ZW1zLCBITUVOVSBoTWVudSwgTUVOVUlURU1JTkZPIE1lbnVJdGVtSW5mbyk7CisvLyAJdm9pZAkJCQkJCUluaXRNZW51SXRlbUluZm8oTUVOVUlURU1JTkZPJiBNZW51SXRlbUluZm8pOworLy8gCXZvaWQJCQkJCQlEZXN0cm95UG9wVXBNZW51KCk7CisKKy8vIAl2b2lkCQkJCQkJUGFyc2VyTWVudUl0ZW0oQVBQX01FTlUqIHBIZWFkLCBjb25zdCBDSlNfUGFyYW1ldGVycyZwYXJhbXMpOworLy8gCXZvaWQJCQkJCQlBZGRJdGVtVG9NZW51KEFQUF9NRU5VKiBwSGVhZCwgSE1FTlUgaE1lbnUsIE1FTlVJVEVNSU5GTyBNZW51SXRlbUluZm8pOworLy8gCXZvaWQJCQkJCQlEZXN0cm95TWVudUl0ZW1zKEFQUF9NRU5VKiBwSGVhZCk7CisKK3B1YmxpYzoKKwlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJCVN5c1BhdGhUb1BERlBhdGgoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNPbGRQYXRoKTsKKwlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJCVBERlBhdGhUb1N5c1BhdGgoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNPbGRQYXRoKTsKKwlzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcJCVJlbGF0aXZlUGF0aFRvU3lzUGF0aChjb25zdCBDRlhfV2lkZVN0cmluZyYgc09sZFBhdGgsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzRmlsZVBhdGgpOworCisKK3ByaXZhdGU6CisKKwlib29sCQkJCQkJbV9iQ2FsY3VsYXRlOwkKKwlDSlNfUnVudGltZSoJCQkJbV9wUnVudGltZTsKKwlib29sCQkJCQkJbV9iUnVudGltZUhpZ2hMaWdodDsKKworCUNGWF9BcnJheVRlbXBsYXRlPENKU19UaW1lcio+CW1fYVRpbWVyOworLy8JQVBQX01FTlUqCQkJCQltX3BNZW51SGVhZDsKKwkKK3B1YmxpYzoKKy8vCXN0YXRpYyBDUmVhZGVyX0FwcCogc19BcHA7Cit9OworCitjbGFzcyBDSlNfQXBwIDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfQXBwKEpTRlhPYmplY3QgIHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsKKwl2aXJ0dWFsIH5DSlNfQXBwKHZvaWQpe307CisKKwlERUNMQVJFX0pTX0NMQVNTKENKU19BcHApOworCisJSlNfU1RBVElDX1BST1AoYWN0aXZlRG9jcywgYXBwKTsKKwlKU19TVEFUSUNfUFJPUChjYWxjdWxhdGUsIGFwcCk7CisJSlNfU1RBVElDX1BST1AoZm9ybXNWZXJzaW9uLCBhcHApOworCUpTX1NUQVRJQ19QUk9QKGZzLCBhcHApOworCUpTX1NUQVRJQ19QUk9QKGZ1bGxzY3JlZW4sIGFwcCk7CisJSlNfU1RBVElDX1BST1AobGFuZ3VhZ2UsIGFwcCk7CisJSlNfU1RBVElDX1BST1AobWVkaWEsIGFwcCk7CisJSlNfU1RBVElDX1BST1AocGxhdGZvcm0sIGFwcCk7CisJSlNfU1RBVElDX1BST1AocnVudGltZUhpZ2hsaWdodCwgYXBwKTsKKwlKU19TVEFUSUNfUFJPUCh2aWV3ZXJUeXBlLCBhcHApOworCUpTX1NUQVRJQ19QUk9QKHZpZXdlclZhcmlhdGlvbiwgYXBwKTsKKwlKU19TVEFUSUNfUFJPUCh2aWV3ZXJWZXJzaW9uLCBhcHApOwkKKworCUpTX1NUQVRJQ19NRVRIT0QoYWxlcnQsIGFwcCk7CisJSlNfU1RBVElDX01FVEhPRChiZWVwLCBhcHApOworCUpTX1NUQVRJQ19NRVRIT0QoYnJvd3NlRm9yRG9jLCBhcHApOworCUpTX1NUQVRJQ19NRVRIT0QoY2xlYXJJbnRlcnZhbCwgYXBwKTsKKwlKU19TVEFUSUNfTUVUSE9EKGNsZWFyVGltZU91dCwgYXBwKTsKKwlKU19TVEFUSUNfTUVUSE9EKGV4ZWNEaWFsb2csIGFwcCk7CisJSlNfU1RBVElDX01FVEhPRChleGVjTWVudUl0ZW0sIGFwcCk7CisJSlNfU1RBVElDX01FVEhPRChmaW5kQ29tcG9uZW50LCBhcHApOworCUpTX1NUQVRJQ19NRVRIT0QoZ29CYWNrLCBhcHApOworCUpTX1NUQVRJQ19NRVRIT0QoZ29Gb3J3YXJkLCBhcHApOworCUpTX1NUQVRJQ19NRVRIT0QobGF1bmNoVVJMLCBhcHApOworCUpTX1NUQVRJQ19NRVRIT0QobWFpbE1zZywgYXBwKTsKKwlKU19TVEFUSUNfTUVUSE9EKG5ld0ZERiwgYXBwKTsKKwlKU19TVEFUSUNfTUVUSE9EKG5ld0RvYywgYXBwKTsKKwlKU19TVEFUSUNfTUVUSE9EKG9wZW5Eb2MsIGFwcCk7CisJSlNfU1RBVElDX01FVEhPRChvcGVuRkRGLCBhcHApOworCUpTX1NUQVRJQ19NRVRIT0QocG9wVXBNZW51RXgsIGFwcCk7CisJSlNfU1RBVElDX01FVEhPRChwb3BVcE1lbnUsIGFwcCk7CisJSlNfU1RBVElDX01FVEhPRChyZXNwb25zZSwgYXBwKTsKKwlKU19TVEFUSUNfTUVUSE9EKHNldEludGVydmFsLCBhcHApOworCUpTX1NUQVRJQ19NRVRIT0Qoc2V0VGltZU91dCwgYXBwKTsKKworfTsKKworI2VuZGlmIC8vX0FQUF9IXwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvY29sb3IuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L2NvbG9yLmgKaW5kZXggMTkxMGUxNi4uZDBhYTcyZiAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvY29sb3IuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9jb2xvci5oCkBAIC0xLDc4ICsxLDc4IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9DT0xPUl9IXw0KLSNkZWZpbmUgX0NPTE9SX0hfDQotDQotY2xhc3MgY29sb3IgOiBwdWJsaWMgQ0pTX0VtYmVkT2JqDQotew0KLXB1YmxpYzoNCi0JY29sb3IoQ0pTX09iamVjdCogcEpTT2JqZWN0KTsNCi0JdmlydHVhbCB+Y29sb3Iodm9pZCk7DQotDQotCUZYX0JPT0wgYmxhY2soT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBibHVlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgY3lhbihPQkpfUFJPUF9QQVJBTVMpOwkNCi0JRlhfQk9PTCBka0dyYXkoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBncmF5KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgZ3JlZW4oT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBsdEdyYXkoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBtYWdlbnRhKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgcmVkKE9CSl9QUk9QX1BBUkFNUyk7CQ0KLQlGWF9CT09MIHRyYW5zcGFyZW50KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgd2hpdGUoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCB5ZWxsb3coT0JKX1BST1BfUEFSQU1TKTsNCi0NCi0JRlhfQk9PTCBjb252ZXJ0KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBlcXVhbChPQkpfTUVUSE9EX1BBUkFNUyk7DQotDQotcHVibGljOiAgDQotCXN0YXRpYyB2b2lkCQlDb252ZXJ0UFdMQ29sb3JUb0FycmF5KGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yLCBDSlNfQXJyYXkmIGFycmF5KTsNCi0Jc3RhdGljIHZvaWQJCUNvbnZlcnRBcnJheVRvUFdMQ29sb3IoQ0pTX0FycmF5JiBhcnJheSwgQ1BXTF9Db2xvciYgY29sb3IpOw0KLQ0KLXByaXZhdGU6DQotCUNQV0xfQ29sb3IJCW1fY3JUcmFuc3BhcmVudDsNCi0JQ1BXTF9Db2xvcgkJbV9jckJsYWNrOw0KLQlDUFdMX0NvbG9yCQltX2NyV2hpdGU7DQotCUNQV0xfQ29sb3IJCW1fY3JSZWQ7DQotCUNQV0xfQ29sb3IJCW1fY3JHcmVlbjsNCi0JQ1BXTF9Db2xvcgkJbV9jckJsdWU7DQotCUNQV0xfQ29sb3IJCW1fY3JDeWFuOw0KLQlDUFdMX0NvbG9yCQltX2NyTWFnZW50YTsNCi0JQ1BXTF9Db2xvcgkJbV9jclllbGxvdzsNCi0JQ1BXTF9Db2xvcgkJbV9jckRLR3JheTsNCi0JQ1BXTF9Db2xvcgkJbV9jckdyYXk7DQotCUNQV0xfQ29sb3IJCW1fY3JMVEdyYXk7DQotfTsNCi0NCi1jbGFzcyBDSlNfQ29sb3IgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19Db2xvcihKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19Db2xvcih2b2lkKXt9Ow0KLQ0KLQlERUNMQVJFX0pTX0NMQVNTKENKU19Db2xvcik7DQotDQotCUpTX1NUQVRJQ19QUk9QKGJsYWNrLCBjb2xvcik7DQotCUpTX1NUQVRJQ19QUk9QKGJsdWUsIGNvbG9yKTsNCi0JSlNfU1RBVElDX1BST1AoY3lhbiwgY29sb3IpOwkNCi0JSlNfU1RBVElDX1BST1AoZGtHcmF5LCBjb2xvcik7DQotCUpTX1NUQVRJQ19QUk9QKGdyYXksIGNvbG9yKTsNCi0JSlNfU1RBVElDX1BST1AoZ3JlZW4sIGNvbG9yKTsNCi0JSlNfU1RBVElDX1BST1AobHRHcmF5LCBjb2xvcik7DQotCUpTX1NUQVRJQ19QUk9QKG1hZ2VudGEsIGNvbG9yKTsNCi0JSlNfU1RBVElDX1BST1AocmVkLCBjb2xvcik7CQ0KLQlKU19TVEFUSUNfUFJPUCh0cmFuc3BhcmVudCwgY29sb3IpOw0KLQlKU19TVEFUSUNfUFJPUCh3aGl0ZSwgY29sb3IpOw0KLQlKU19TVEFUSUNfUFJPUCh5ZWxsb3csIGNvbG9yKTsNCi0NCi0JSlNfU1RBVElDX01FVEhPRChjb252ZXJ0LGNvbG9yKTsNCi0JSlNfU1RBVElDX01FVEhPRChlcXVhbCxjb2xvcik7DQotDQotfTsNCi0NCi0jZW5kaWYgLy9fQ09MT1JfSF8NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9DT0xPUl9IXworI2RlZmluZSBfQ09MT1JfSF8KKworY2xhc3MgY29sb3IgOiBwdWJsaWMgQ0pTX0VtYmVkT2JqCit7CitwdWJsaWM6CisJY29sb3IoQ0pTX09iamVjdCogcEpTT2JqZWN0KTsKKwl2aXJ0dWFsIH5jb2xvcih2b2lkKTsKKworCUZYX0JPT0wgYmxhY2soT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGJsdWUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGN5YW4oT0JKX1BST1BfUEFSQU1TKTsJCisJRlhfQk9PTCBka0dyYXkoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGdyYXkoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGdyZWVuKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBsdEdyYXkoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIG1hZ2VudGEoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHJlZChPQkpfUFJPUF9QQVJBTVMpOwkKKwlGWF9CT09MIHRyYW5zcGFyZW50KE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCB3aGl0ZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgeWVsbG93KE9CSl9QUk9QX1BBUkFNUyk7CisKKwlGWF9CT09MIGNvbnZlcnQoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgZXF1YWwoT0JKX01FVEhPRF9QQVJBTVMpOworCitwdWJsaWM6ICAKKwlzdGF0aWMgdm9pZAkJQ29udmVydFBXTENvbG9yVG9BcnJheShjb25zdCBDUFdMX0NvbG9yJiBjb2xvciwgQ0pTX0FycmF5JiBhcnJheSk7CisJc3RhdGljIHZvaWQJCUNvbnZlcnRBcnJheVRvUFdMQ29sb3IoQ0pTX0FycmF5JiBhcnJheSwgQ1BXTF9Db2xvciYgY29sb3IpOworCitwcml2YXRlOgorCUNQV0xfQ29sb3IJCW1fY3JUcmFuc3BhcmVudDsKKwlDUFdMX0NvbG9yCQltX2NyQmxhY2s7CisJQ1BXTF9Db2xvcgkJbV9jcldoaXRlOworCUNQV0xfQ29sb3IJCW1fY3JSZWQ7CisJQ1BXTF9Db2xvcgkJbV9jckdyZWVuOworCUNQV0xfQ29sb3IJCW1fY3JCbHVlOworCUNQV0xfQ29sb3IJCW1fY3JDeWFuOworCUNQV0xfQ29sb3IJCW1fY3JNYWdlbnRhOworCUNQV0xfQ29sb3IJCW1fY3JZZWxsb3c7CisJQ1BXTF9Db2xvcgkJbV9jckRLR3JheTsKKwlDUFdMX0NvbG9yCQltX2NyR3JheTsKKwlDUFdMX0NvbG9yCQltX2NyTFRHcmF5OworfTsKKworY2xhc3MgQ0pTX0NvbG9yIDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfQ29sb3IoSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9OworCXZpcnR1YWwgfkNKU19Db2xvcih2b2lkKXt9OworCisJREVDTEFSRV9KU19DTEFTUyhDSlNfQ29sb3IpOworCisJSlNfU1RBVElDX1BST1AoYmxhY2ssIGNvbG9yKTsKKwlKU19TVEFUSUNfUFJPUChibHVlLCBjb2xvcik7CisJSlNfU1RBVElDX1BST1AoY3lhbiwgY29sb3IpOwkKKwlKU19TVEFUSUNfUFJPUChka0dyYXksIGNvbG9yKTsKKwlKU19TVEFUSUNfUFJPUChncmF5LCBjb2xvcik7CisJSlNfU1RBVElDX1BST1AoZ3JlZW4sIGNvbG9yKTsKKwlKU19TVEFUSUNfUFJPUChsdEdyYXksIGNvbG9yKTsKKwlKU19TVEFUSUNfUFJPUChtYWdlbnRhLCBjb2xvcik7CisJSlNfU1RBVElDX1BST1AocmVkLCBjb2xvcik7CQorCUpTX1NUQVRJQ19QUk9QKHRyYW5zcGFyZW50LCBjb2xvcik7CisJSlNfU1RBVElDX1BST1Aod2hpdGUsIGNvbG9yKTsKKwlKU19TVEFUSUNfUFJPUCh5ZWxsb3csIGNvbG9yKTsKKworCUpTX1NUQVRJQ19NRVRIT0QoY29udmVydCxjb2xvcik7CisJSlNfU1RBVElDX01FVEhPRChlcXVhbCxjb2xvcik7CisKK307CisKKyNlbmRpZiAvL19DT0xPUl9IXworCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9jb25zb2xlLmggYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9jb25zb2xlLmgKaW5kZXggOThhMzI5My4uNzBkOTkzYiAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvY29uc29sZS5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L2NvbnNvbGUuaApAQCAtMSwzOCArMSwzOCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfQ09OU09MRV9IXw0KLSNkZWZpbmUgX0NPTlNPTEVfSF8NCi0NCi1jbGFzcyBjb25zb2xlIDogcHVibGljIENKU19FbWJlZE9iag0KLXsNCi1wdWJsaWM6DQotCWNvbnNvbGUoQ0pTX09iamVjdCogcEpTT2JqZWN0KTsNCi0JdmlydHVhbCB+Y29uc29sZSh2b2lkKTsNCi0NCi1wdWJsaWM6DQotCUZYX0JPT0wgY2xlYXIoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIGhpZGUoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIHByaW50bG4oT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIHNob3coT0JKX01FVEhPRF9QQVJBTVMpOw0KLX07DQotDQotY2xhc3MgQ0pTX0NvbnNvbGUgOiBwdWJsaWMgQ0pTX09iamVjdCAgDQotew0KLXB1YmxpYzoNCi0JQ0pTX0NvbnNvbGUoSlNGWE9iamVjdCBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19Db25zb2xlKHZvaWQpe307DQotDQotCURFQ0xBUkVfSlNfQ0xBU1MoQ0pTX0NvbnNvbGUpOw0KLQ0KLQlKU19TVEFUSUNfTUVUSE9EKGNsZWFyLCBjb25zb2xlKTsNCi0JSlNfU1RBVElDX01FVEhPRChoaWRlLCBjb25zb2xlKTsNCi0JSlNfU1RBVElDX01FVEhPRChwcmludGxuLCBjb25zb2xlKTsNCi0JSlNfU1RBVElDX01FVEhPRChzaG93LCBjb25zb2xlKTsNCi19Ow0KLQ0KLSNlbmRpZiAvL19DT05TT0xFX0hfDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfQ09OU09MRV9IXworI2RlZmluZSBfQ09OU09MRV9IXworCitjbGFzcyBjb25zb2xlIDogcHVibGljIENKU19FbWJlZE9iagoreworcHVibGljOgorCWNvbnNvbGUoQ0pTX09iamVjdCogcEpTT2JqZWN0KTsKKwl2aXJ0dWFsIH5jb25zb2xlKHZvaWQpOworCitwdWJsaWM6CisJRlhfQk9PTCBjbGVhcihPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBoaWRlKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIHByaW50bG4oT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgc2hvdyhPQkpfTUVUSE9EX1BBUkFNUyk7Cit9OworCitjbGFzcyBDSlNfQ29uc29sZSA6IHB1YmxpYyBDSlNfT2JqZWN0ICAKK3sKK3B1YmxpYzoKKwlDSlNfQ29uc29sZShKU0ZYT2JqZWN0IHBPYmplY3QpIDogQ0pTX09iamVjdChwT2JqZWN0KSB7fTsKKwl2aXJ0dWFsIH5DSlNfQ29uc29sZSh2b2lkKXt9OworCisJREVDTEFSRV9KU19DTEFTUyhDSlNfQ29uc29sZSk7CisKKwlKU19TVEFUSUNfTUVUSE9EKGNsZWFyLCBjb25zb2xlKTsKKwlKU19TVEFUSUNfTUVUSE9EKGhpZGUsIGNvbnNvbGUpOworCUpTX1NUQVRJQ19NRVRIT0QocHJpbnRsbiwgY29uc29sZSk7CisJSlNfU1RBVElDX01FVEhPRChzaG93LCBjb25zb2xlKTsKK307CisKKyNlbmRpZiAvL19DT05TT0xFX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L2V2ZW50LmggYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9ldmVudC5oCmluZGV4IDkxZjJjNjUuLjA0MGE5MzMgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L2V2ZW50LmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvZXZlbnQuaApAQCAtMSw3MCArMSw3MCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfRVZFTlRfSF8NCi0jZGVmaW5lIF9FVkVOVF9IXw0KLQ0KLWNsYXNzIGV2ZW50IDogcHVibGljIENKU19FbWJlZE9iag0KLXsNCi1wdWJsaWM6DQotCWV2ZW50KENKU19PYmplY3QgKiBwSlNPYmplY3QpOw0KLQl2aXJ0dWFsIH5ldmVudCh2b2lkKTsNCi0NCi1wdWJsaWM6DQotCUZYX0JPT0wgY2hhbmdlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgY2hhbmdlRXgoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBjb21taXRLZXkoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBmaWVsZEZ1bGwoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBrZXlEb3duKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgbW9kaWZpZXIoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBuYW1lKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgcmMoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCByaWNoQ2hhbmdlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgcmljaENoYW5nZUV4KE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgcmljaFZhbHVlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgc2VsRW5kKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgc2VsU3RhcnQoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCBzaGlmdChPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHNvdXJjZShPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHRhcmdldChPQkpfUFJPUF9QQVJBTVMpOw0KLQlGWF9CT09MIHRhcmdldE5hbWUoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCB0eXBlKE9CSl9QUk9QX1BBUkFNUyk7DQotCUZYX0JPT0wgdmFsdWUoT0JKX1BST1BfUEFSQU1TKTsNCi0JRlhfQk9PTCB3aWxsQ29tbWl0KE9CSl9QUk9QX1BBUkFNUyk7DQotDQotfTsNCi0NCi1jbGFzcyBDSlNfRXZlbnQgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19FdmVudChKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19FdmVudCh2b2lkKXt9Ow0KLQ0KLQlERUNMQVJFX0pTX0NMQVNTKENKU19FdmVudCk7DQotDQotCUpTX1NUQVRJQ19QUk9QKGNoYW5nZSwgZXZlbnQpOw0KLQlKU19TVEFUSUNfUFJPUChjaGFuZ2VFeCwgZXZlbnQpOw0KLQlKU19TVEFUSUNfUFJPUChjb21taXRLZXksIGV2ZW50KTsNCi0JSlNfU1RBVElDX1BST1AoZmllbGRGdWxsLCBldmVudCk7DQotCUpTX1NUQVRJQ19QUk9QKGtleURvd24sIGV2ZW50KTsNCi0JSlNfU1RBVElDX1BST1AobW9kaWZpZXIsIGV2ZW50KTsNCi0JSlNfU1RBVElDX1BST1AobmFtZSwgZXZlbnQpOw0KLQlKU19TVEFUSUNfUFJPUChyYywgZXZlbnQpOw0KLQlKU19TVEFUSUNfUFJPUChyaWNoQ2hhbmdlLCBldmVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHJpY2hDaGFuZ2VFeCwgZXZlbnQpOw0KLQlKU19TVEFUSUNfUFJPUChyaWNoVmFsdWUsIGV2ZW50KTsNCi0JSlNfU1RBVElDX1BST1Aoc2VsRW5kLCBldmVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHNlbFN0YXJ0LCBldmVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHNoaWZ0LCBldmVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHNvdXJjZSwgZXZlbnQpOw0KLQlKU19TVEFUSUNfUFJPUCh0YXJnZXQsIGV2ZW50KTsNCi0JSlNfU1RBVElDX1BST1AodGFyZ2V0TmFtZSwgZXZlbnQpOw0KLQlKU19TVEFUSUNfUFJPUCh0eXBlLCBldmVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHZhbHVlLCBldmVudCk7DQotCUpTX1NUQVRJQ19QUk9QKHdpbGxDb21taXQsIGV2ZW50KTsNCi19Ow0KLQ0KLSNlbmRpZiAvL19FVkVOVF9IXw0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX0VWRU5UX0hfCisjZGVmaW5lIF9FVkVOVF9IXworCitjbGFzcyBldmVudCA6IHB1YmxpYyBDSlNfRW1iZWRPYmoKK3sKK3B1YmxpYzoKKwlldmVudChDSlNfT2JqZWN0ICogcEpTT2JqZWN0KTsKKwl2aXJ0dWFsIH5ldmVudCh2b2lkKTsKKworcHVibGljOgorCUZYX0JPT0wgY2hhbmdlKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBjaGFuZ2VFeChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgY29tbWl0S2V5KE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBmaWVsZEZ1bGwoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIGtleURvd24oT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIG1vZGlmaWVyKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBuYW1lKE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCByYyhPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgcmljaENoYW5nZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgcmljaENoYW5nZUV4KE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCByaWNoVmFsdWUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHNlbEVuZChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgc2VsU3RhcnQoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHNoaWZ0KE9CSl9QUk9QX1BBUkFNUyk7CisJRlhfQk9PTCBzb3VyY2UoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHRhcmdldChPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgdGFyZ2V0TmFtZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgdHlwZShPQkpfUFJPUF9QQVJBTVMpOworCUZYX0JPT0wgdmFsdWUoT0JKX1BST1BfUEFSQU1TKTsKKwlGWF9CT09MIHdpbGxDb21taXQoT0JKX1BST1BfUEFSQU1TKTsKKworfTsKKworY2xhc3MgQ0pTX0V2ZW50IDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfRXZlbnQoSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9OworCXZpcnR1YWwgfkNKU19FdmVudCh2b2lkKXt9OworCisJREVDTEFSRV9KU19DTEFTUyhDSlNfRXZlbnQpOworCisJSlNfU1RBVElDX1BST1AoY2hhbmdlLCBldmVudCk7CisJSlNfU1RBVElDX1BST1AoY2hhbmdlRXgsIGV2ZW50KTsKKwlKU19TVEFUSUNfUFJPUChjb21taXRLZXksIGV2ZW50KTsKKwlKU19TVEFUSUNfUFJPUChmaWVsZEZ1bGwsIGV2ZW50KTsKKwlKU19TVEFUSUNfUFJPUChrZXlEb3duLCBldmVudCk7CisJSlNfU1RBVElDX1BST1AobW9kaWZpZXIsIGV2ZW50KTsKKwlKU19TVEFUSUNfUFJPUChuYW1lLCBldmVudCk7CisJSlNfU1RBVElDX1BST1AocmMsIGV2ZW50KTsKKwlKU19TVEFUSUNfUFJPUChyaWNoQ2hhbmdlLCBldmVudCk7CisJSlNfU1RBVElDX1BST1AocmljaENoYW5nZUV4LCBldmVudCk7CisJSlNfU1RBVElDX1BST1AocmljaFZhbHVlLCBldmVudCk7CisJSlNfU1RBVElDX1BST1Aoc2VsRW5kLCBldmVudCk7CisJSlNfU1RBVElDX1BST1Aoc2VsU3RhcnQsIGV2ZW50KTsKKwlKU19TVEFUSUNfUFJPUChzaGlmdCwgZXZlbnQpOworCUpTX1NUQVRJQ19QUk9QKHNvdXJjZSwgZXZlbnQpOworCUpTX1NUQVRJQ19QUk9QKHRhcmdldCwgZXZlbnQpOworCUpTX1NUQVRJQ19QUk9QKHRhcmdldE5hbWUsIGV2ZW50KTsKKwlKU19TVEFUSUNfUFJPUCh0eXBlLCBldmVudCk7CisJSlNfU1RBVElDX1BST1AodmFsdWUsIGV2ZW50KTsKKwlKU19TVEFUSUNfUFJPUCh3aWxsQ29tbWl0LCBldmVudCk7Cit9OworCisjZW5kaWYgLy9fRVZFTlRfSF8KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L2dsb2JhbC5oIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvZ2xvYmFsLmgKaW5kZXggN2VmZmQ1Ny4uZjU4NjdjNSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvZ2xvYmFsLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvZ2xvYmFsLmgKQEAgLTEsODUgKzEsODUgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX0dMT0JBTF9IXw0KLSNkZWZpbmUgX0dMT0JBTF9IXw0KLQ0KLWNsYXNzIENKU19HbG9iYWxEYXRhOw0KLQ0KLXN0cnVjdCBqc19nbG9iYWxfZGF0YQ0KLXsNCi0JanNfZ2xvYmFsX2RhdGEoKQ0KLQl7DQotCQluVHlwZSA9IDA7DQotCQlkRGF0YSA9IDA7DQotCQliRGF0YSA9IEZBTFNFOw0KLQkJc0RhdGEgPSAiIjsNCi0JCWJQZXJzaXN0ZW50ID0gRkFMU0U7DQotCQliRGVsZXRlZCA9IEZBTFNFOw0KLQl9DQotDQotCX5qc19nbG9iYWxfZGF0YSgpDQotCXsNCi0JCXBEYXRhLlJlc2V0KCk7DQotCX0NCi0JaW50CQkJCQluVHlwZTsgLy8wOmludCAxOmJvb2wgMjpzdHJpbmcgMzpvYmoNCi0JZG91YmxlCQkJCWREYXRhOw0KLQlib29sCQkJCWJEYXRhOw0KLQlDRlhfQnl0ZVN0cmluZwkJc0RhdGE7DQotCXY4OjpQZXJzaXN0ZW50PHY4OjpPYmplY3Q+ICBwRGF0YTsNCi0JYm9vbAkJCQliUGVyc2lzdGVudDsNCi0JYm9vbAkJCQliRGVsZXRlZDsNCi19Ow0KLQ0KLWNsYXNzIGdsb2JhbF9hbHRlcm5hdGUgOiBwdWJsaWMgQ0pTX0VtYmVkT2JqDQotew0KLXB1YmxpYzoNCi0JZ2xvYmFsX2FsdGVybmF0ZShDSlNfT2JqZWN0KiBwSlNPYmplY3QpOw0KLQl2aXJ0dWFsIH5nbG9iYWxfYWx0ZXJuYXRlKCk7DQotDQotcHVibGljOg0KLQlGWF9CT09MCQkJCQkJc2V0UGVyc2lzdGVudChPQkpfTUVUSE9EX1BBUkFNUyk7DQotDQotcHVibGljOg0KLQlGWF9CT09MCQkJCQkJUXVlcnlQcm9wZXJ0eShGWF9MUENXU1RSIHByb3BuYW1lKTsNCi0JRlhfQk9PTAkJCQkJCURvUHJvcGVydHkoSUZYSlNfQ29udGV4dCogY2MsIEZYX0xQQ1dTVFIgcHJvcG5hbWUsIENKU19Qcm9wVmFsdWUgJiB2cCwgSlNfRXJyb3JTdHJpbmcgJiBzRXJyb3IpOw0KLQlGWF9CT09MCQkJCQkJRGVsUHJvcGVydHkoSUZYSlNfQ29udGV4dCogY2MsIEZYX0xQQ1dTVFIgcHJvcG5hbWUsIEpTX0Vycm9yU3RyaW5nICYgc0Vycm9yKTsNCi0NCi0Jdm9pZAkJCQkJCUluaXRpYWwoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCk7DQotDQotcHJpdmF0ZToNCi0Jdm9pZAkJCQkJCVVwZGF0ZUdsb2JhbFBlcnNpc3RlbnRWYXJpYWJsZXMoKTsNCi0Jdm9pZAkJCQkJCUNvbW1pdEdsb2JhbFBlcnNpc2l0ZW50VmFyaWFibGVzKCk7DQotCXZvaWQJCQkJCQlEZXN0cm95R2xvYmFsUGVyc2lzaXRlbnRWYXJpYWJsZXMoKTsNCi0JRlhfQk9PTAkJCQkJCVNldEdsb2JhbFZhcmlhYmxlcyhGWF9MUENTVFIgcHJvcG5hbWUsIGludCBuVHlwZSwgDQotCQkJCQkJCQkJZG91YmxlIGREYXRhLCBib29sIGJEYXRhLCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0RhdGEsIEpTT2JqZWN0IHBEYXRhLCBib29sIGJEZWZhdWx0UGVyc2lzdGVudCk7DQotDQotCXZvaWQJCQkJCQlPYmplY3RUb0FycmF5KHY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaiwgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkmIGFycmF5KTsNCi0Jdm9pZAkJCQkJCVB1dE9iamVjdFByb3BlcnR5KHY4OjpIYW5kbGU8djg6Ok9iamVjdD4gb2JqLCBDSlNfS2V5VmFsdWUqIHBEYXRhKTsNCi0NCi1wcml2YXRlOg0KLQlDRlhfTWFwQnl0ZVN0cmluZ1RvUHRyCQltX21hcEdsb2JhbDsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJbV9zRmlsZVBhdGg7DQotCUNKU19HbG9iYWxEYXRhKgkJCQltX3BHbG9iYWxEYXRhOw0KLQlDUERGRG9jX0Vudmlyb25tZW50KgkJCQltX3BBcHA7DQotfTsNCi0NCi0NCi1jbGFzcyBDSlNfR2xvYmFsIDogcHVibGljIENKU19PYmplY3QNCi17DQotcHVibGljOg0KLQlDSlNfR2xvYmFsKEpTRlhPYmplY3QgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9Ow0KLQl2aXJ0dWFsIH5DSlNfR2xvYmFsKHZvaWQpe307DQotDQotCXZpcnR1YWwgRlhfQk9PTAlJbml0SW5zdGFuY2UoSUZYSlNfQ29udGV4dCogY2MpOwkNCi0NCi0JREVDTEFSRV9TUEVDSUFMX0pTX0NMQVNTKENKU19HbG9iYWwpOw0KLQ0KLQlKU19TUEVDSUFMX1NUQVRJQ19NRVRIT0Qoc2V0UGVyc2lzdGVudCwgZ2xvYmFsX2FsdGVybmF0ZSwgZ2xvYmFsKTsNCi0NCi19Ow0KLQ0KLSNlbmRpZiAvL19HTE9CQUxfSF8NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9HTE9CQUxfSF8KKyNkZWZpbmUgX0dMT0JBTF9IXworCitjbGFzcyBDSlNfR2xvYmFsRGF0YTsKKworc3RydWN0IGpzX2dsb2JhbF9kYXRhCit7CisJanNfZ2xvYmFsX2RhdGEoKQorCXsKKwkJblR5cGUgPSAwOworCQlkRGF0YSA9IDA7CisJCWJEYXRhID0gRkFMU0U7CisJCXNEYXRhID0gIiI7CisJCWJQZXJzaXN0ZW50ID0gRkFMU0U7CisJCWJEZWxldGVkID0gRkFMU0U7CisJfQorCisJfmpzX2dsb2JhbF9kYXRhKCkKKwl7CisJCXBEYXRhLlJlc2V0KCk7CisJfQorCWludAkJCQkJblR5cGU7IC8vMDppbnQgMTpib29sIDI6c3RyaW5nIDM6b2JqCisJZG91YmxlCQkJCWREYXRhOworCWJvb2wJCQkJYkRhdGE7CisJQ0ZYX0J5dGVTdHJpbmcJCXNEYXRhOworCXY4OjpQZXJzaXN0ZW50PHY4OjpPYmplY3Q+ICBwRGF0YTsKKwlib29sCQkJCWJQZXJzaXN0ZW50OworCWJvb2wJCQkJYkRlbGV0ZWQ7Cit9OworCitjbGFzcyBnbG9iYWxfYWx0ZXJuYXRlIDogcHVibGljIENKU19FbWJlZE9iagoreworcHVibGljOgorCWdsb2JhbF9hbHRlcm5hdGUoQ0pTX09iamVjdCogcEpTT2JqZWN0KTsKKwl2aXJ0dWFsIH5nbG9iYWxfYWx0ZXJuYXRlKCk7CisKK3B1YmxpYzoKKwlGWF9CT09MCQkJCQkJc2V0UGVyc2lzdGVudChPQkpfTUVUSE9EX1BBUkFNUyk7CisKK3B1YmxpYzoKKwlGWF9CT09MCQkJCQkJUXVlcnlQcm9wZXJ0eShGWF9MUENXU1RSIHByb3BuYW1lKTsKKwlGWF9CT09MCQkJCQkJRG9Qcm9wZXJ0eShJRlhKU19Db250ZXh0KiBjYywgRlhfTFBDV1NUUiBwcm9wbmFtZSwgQ0pTX1Byb3BWYWx1ZSAmIHZwLCBKU19FcnJvclN0cmluZyAmIHNFcnJvcik7CisJRlhfQk9PTAkJCQkJCURlbFByb3BlcnR5KElGWEpTX0NvbnRleHQqIGNjLCBGWF9MUENXU1RSIHByb3BuYW1lLCBKU19FcnJvclN0cmluZyAmIHNFcnJvcik7CisKKwl2b2lkCQkJCQkJSW5pdGlhbChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwKTsKKworcHJpdmF0ZToKKwl2b2lkCQkJCQkJVXBkYXRlR2xvYmFsUGVyc2lzdGVudFZhcmlhYmxlcygpOworCXZvaWQJCQkJCQlDb21taXRHbG9iYWxQZXJzaXNpdGVudFZhcmlhYmxlcygpOworCXZvaWQJCQkJCQlEZXN0cm95R2xvYmFsUGVyc2lzaXRlbnRWYXJpYWJsZXMoKTsKKwlGWF9CT09MCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVzKEZYX0xQQ1NUUiBwcm9wbmFtZSwgaW50IG5UeXBlLCAKKwkJCQkJCQkJCWRvdWJsZSBkRGF0YSwgYm9vbCBiRGF0YSwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNEYXRhLCBKU09iamVjdCBwRGF0YSwgYm9vbCBiRGVmYXVsdFBlcnNpc3RlbnQpOworCisJdm9pZAkJCQkJCU9iamVjdFRvQXJyYXkodjg6OkhhbmRsZTx2ODo6T2JqZWN0PiBwT2JqLCBDSlNfR2xvYmFsVmFyaWFibGVBcnJheSYgYXJyYXkpOworCXZvaWQJCQkJCQlQdXRPYmplY3RQcm9wZXJ0eSh2ODo6SGFuZGxlPHY4OjpPYmplY3Q+IG9iaiwgQ0pTX0tleVZhbHVlKiBwRGF0YSk7CisKK3ByaXZhdGU6CisJQ0ZYX01hcEJ5dGVTdHJpbmdUb1B0cgkJbV9tYXBHbG9iYWw7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJbV9zRmlsZVBhdGg7CisJQ0pTX0dsb2JhbERhdGEqCQkJCW1fcEdsb2JhbERhdGE7CisJQ1BERkRvY19FbnZpcm9ubWVudCoJCQkJbV9wQXBwOworfTsKKworCitjbGFzcyBDSlNfR2xvYmFsIDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfR2xvYmFsKEpTRlhPYmplY3QgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3QpIHt9OworCXZpcnR1YWwgfkNKU19HbG9iYWwodm9pZCl7fTsKKworCXZpcnR1YWwgRlhfQk9PTAlJbml0SW5zdGFuY2UoSUZYSlNfQ29udGV4dCogY2MpOwkKKworCURFQ0xBUkVfU1BFQ0lBTF9KU19DTEFTUyhDSlNfR2xvYmFsKTsKKworCUpTX1NQRUNJQUxfU1RBVElDX01FVEhPRChzZXRQZXJzaXN0ZW50LCBnbG9iYWxfYWx0ZXJuYXRlLCBnbG9iYWwpOworCit9OworCisjZW5kaWYgLy9fR0xPQkFMX0hfCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9yZXBvcnQuaCBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L3JlcG9ydC5oCmluZGV4IDhhNDA4NGQuLmZiNWFkZjMgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L3JlcG9ydC5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L3JlcG9ydC5oCkBAIC0xLDM1ICsxLDM1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9SRVBPUlRfSF8NCi0jZGVmaW5lIF9SRVBPUlRfSF8NCi0NCi1jbGFzcyBSZXBvcnQgOiBwdWJsaWMgQ0pTX0VtYmVkT2JqDQotew0KLXB1YmxpYzoNCi0JUmVwb3J0KENKU19PYmplY3QgKiBwSlNPYmplY3QpOw0KLQl2aXJ0dWFsIH5SZXBvcnQoKTsNCi0NCi1wdWJsaWM6DQotCUZYX0JPT0wgc2F2ZShPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgd3JpdGVUZXh0KE9CSl9NRVRIT0RfUEFSQU1TKTsNCi19Ow0KLQ0KLWNsYXNzIENKU19SZXBvcnQgOiBwdWJsaWMgQ0pTX09iamVjdA0KLXsNCi1wdWJsaWM6DQotCUNKU19SZXBvcnQoSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3Qpe307DQotCXZpcnR1YWwgfkNKU19SZXBvcnQoKXt9Ow0KLQ0KLXB1YmxpYzoNCi0JREVDTEFSRV9KU19DTEFTUyhDSlNfUmVwb3J0KTsNCi0NCi0JSlNfU1RBVElDX01FVEhPRChzYXZlLCBSZXBvcnQpDQotCUpTX1NUQVRJQ19NRVRIT0Qod3JpdGVUZXh0LCBSZXBvcnQpOw0KLX07DQotDQotI2VuZGlmIC8vX1JFUE9SVF9IXw0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1JFUE9SVF9IXworI2RlZmluZSBfUkVQT1JUX0hfCisKK2NsYXNzIFJlcG9ydCA6IHB1YmxpYyBDSlNfRW1iZWRPYmoKK3sKK3B1YmxpYzoKKwlSZXBvcnQoQ0pTX09iamVjdCAqIHBKU09iamVjdCk7CisJdmlydHVhbCB+UmVwb3J0KCk7CisKK3B1YmxpYzoKKwlGWF9CT09MIHNhdmUoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgd3JpdGVUZXh0KE9CSl9NRVRIT0RfUEFSQU1TKTsKK307CisKK2NsYXNzIENKU19SZXBvcnQgOiBwdWJsaWMgQ0pTX09iamVjdAoreworcHVibGljOgorCUNKU19SZXBvcnQoSlNGWE9iamVjdCAgcE9iamVjdCkgOiBDSlNfT2JqZWN0KHBPYmplY3Qpe307CisJdmlydHVhbCB+Q0pTX1JlcG9ydCgpe307CisKK3B1YmxpYzoKKwlERUNMQVJFX0pTX0NMQVNTKENKU19SZXBvcnQpOworCisJSlNfU1RBVElDX01FVEhPRChzYXZlLCBSZXBvcnQpCisJSlNfU1RBVElDX01FVEhPRCh3cml0ZVRleHQsIFJlcG9ydCk7Cit9OworCisjZW5kaWYgLy9fUkVQT1JUX0hfCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L3Jlc291cmNlLmggYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC9yZXNvdXJjZS5oCmluZGV4IDBiNzY2OGUuLjcxMGNjNTAgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L3Jlc291cmNlLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvcmVzb3VyY2UuaApAQCAtMSwxMTAgKzEsMTEwIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jZGVmaW5lIElERF9KU19NU0dCT1ggICAgICAgICAgICAgICAgICAgMjU2MDANCi0jZGVmaW5lIElERF9SRVNQT05TRSAgICAgICAgICAgICAgICAgICAgMjU2MDENCi0jZGVmaW5lIElEQ19KU19NU0dfVEVYVCAgICAgICAgICAgICAgICAgMjU2MDINCi0jZGVmaW5lIElEX0pTX01TR19PSyAgICAgICAgICAgICAgICAgICAgMjU2MDMNCi0jZGVmaW5lIElEX0pTX01TR19DQU5DRUwgICAgICAgICAgICAgICAgMjU2MDQNCi0jZGVmaW5lIElEQ19KU19NU0dfSUNPTiAgICAgICAgICAgICAgICAgMjU2MDUNCi0jZGVmaW5lIElEX0pTX01TR19ZRVMgICAgICAgICAgICAgICAgICAgMjU2MDYNCi0jZGVmaW5lIElEX0pTX01TR19OTyAgICAgICAgICAgICAgICAgICAgMjU2MDcNCi0jZGVmaW5lIElEQ19KU19RVUVTVElPTiAgICAgICAgICAgICAgICAgMjU2MDgNCi0jZGVmaW5lIElEX0pTX09LICAgICAgICAgICAgICAgICAgICAgICAgMjU2MDkNCi0jZGVmaW5lIElEX0pTX0NBTkNFTCAgICAgICAgICAgICAgICAgICAgMjU2MTANCi0jZGVmaW5lIElEQ19KU19BTlNXRVIgICAgICAgICAgICAgICAgICAgMjU2MTENCi0jZGVmaW5lIElEQ19KU19FRElUICAgICAgICAgICAgICAgICAgICAgMjU2MTINCi0jZGVmaW5lIElEU19TVFJJTkdfSlNBTEVSVCAgICAgICAgICAgICAgMjU2MTMNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SICAgICAgICAgMjU2MTQNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UgMjU2MTUNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNJTlBVVEVSUk9SICAgICAgICAgMjU2MTYNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HICAgICAgMjU2MTcNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNQQVJTRURBVEUgICAgICAgICAgMjU2MTgNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNSQU5HRTEgICAgICAgICAgICAgMjU2MTkNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNSQU5HRTIgICAgICAgICAgICAgMjU2MjANCi0jZGVmaW5lIElEU19TVFJJTkdfSlNSQU5HRTMgICAgICAgICAgICAgMjU2MjENCi0jZGVmaW5lIElEU19TVFJJTkdfSlNSQU5HRTQgICAgICAgICAgICAgMjU2MjINCi0jZGVmaW5lIElEU19TVFJJTkdfRklMRU9QRU5GQUlMICAgICAgICAgMjU2MjMNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNBVFRFTlRJT04gICAgICAgICAgMjU2MjQNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNTVUJNSVRTICAgICAgICAgICAgMjU2MjUNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNTVUJNSVRGICAgICAgICAgICAgMjU2MjYNCi0jZGVmaW5lIElEU19TVFJJTkdfTk9UU1VQUE9SVCAgICAgICAgICAgMjU2MjcNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNCVVNZICAgICAgICAgICAgICAgMjU2MjgNCi0jZGVmaW5lIElEU19TVFJJTkdfSlNFVkVOVCAgICAgICAgICAgICAgMjU2MjkNCi0jZGVmaW5lIElEU19TVFJJTkdfUlVOICAgICAgICAgICAgICAgICAgMjU2MzANCi0jZGVmaW5lIElEU19TVFJJTkdfVU5IQU5ETEVEICAgICAgICAgICAgMjU2MzENCi0jZGVmaW5lIElEU19TVFJJTkdfSlNQUklOVDEgICAgICAgICAgICAgMjU2MzINCi0jZGVmaW5lIElEU19TVFJJTkdfSlNQUklOVDIgICAgICAgICAgICAgMjU2MzMNCi0jZGVmaW5lIElEU19TVFJJTkdfTEFVTkNIVVJMICAgICAgICAgICAgMjU2MzQNCi0jZGVmaW5lIElEU19KU1BBUkFNX0lOQ09SUkVDVCAgICAgICAgICAgMjU2MzUNCi0jZGVmaW5lIElERF9KU19DT05TT0xFICAgICAgICAgICAgICAgICAgMjU2MzYNCi0jZGVmaW5lIElEU19TVFJJTkdfU0FGRU1PREVMICAgICAgICAgICAgMjU2MzYNCi0jZGVmaW5lIElEQ19FRFRTQ1JJUFQgICAgICAgICAgICAgICAgICAgMjU2MzcNCi0jZGVmaW5lIElEQ19CVE5DTEVBUiAgICAgICAgICAgICAgICAgICAgMjU2MzgNCi0jZGVmaW5lIElEQ19FRFRPVVRQVVQgICAgICAgICAgICAgICAgICAgMjU2MzkNCi0jZGVmaW5lIElEQ19DSEVDS19USVBTICAgICAgICAgICAgICAgICAgMjU2NDANCi0jZGVmaW5lIElEQ19CVE5SVU4gICAgICAgICAgICAgICAgICAgICAgMjU2NDENCi0NCi0NCi0NCi1zdGF0aWMgQ0ZYX1dpZGVTdHJpbmcgSlNHZXRTdHJpbmdGcm9tSUQoQ0pTX0NvbnRleHQqIHBDb250ZXh0LCBGWF9VSU5UIElEKQ0KLXsNCi0Jc3dpdGNoKElEKQ0KLQl7ICAgICAgICAgICAgICAgICAgDQotCWNhc2UgSURTX1NUUklOR19KU0FMRVJUOg0KLQkJcmV0dXJuIEwiQWxlcnQiOw0KLQljYXNlIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SOg0KLSAgICAgICAgcmV0dXJuIEwiVGhlIGFtb3VudCBvZiBwYXJhbWV0ZXJzIGlzIG5vdCBjb3JyZWN0ICEiOwkNCi0JY2FzZSBJRFNfU1RSSU5HX0pTQUZOVU1CRVJfS0VZU1RST0tFOg0KLQkJcmV0dXJuIEwiVGhlIGlucHV0IHZhbHVlIGlzIGludmFsaWQuIjsNCi0JY2FzZQlJRFNfU1RSSU5HX0pTSU5QVVRFUlJPUjoNCi0gICAgICAgIHJldHVybiBMIklucHV0IGVycm9yICEiOw0KLQljYXNlCUlEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HOg0KLQkJcmV0dXJuIEwiVGhlIHZhbHVlIHlvdSBhcmUgZ29pbmcgdG8gaW5wdXQgaXMgdG9vIGxvbmcuIjsNCi0JY2FzZQlJRFNfU1RSSU5HX0pTUEFSU0VEQVRFOg0KLQkJcmV0dXJuIEwiVGhlIGlucHV0IHN0cmluZyBjYW4ndCBiZSBwYXJzZWQgdG8gYSB2YWxpZCBkYXRlIHRpbWUgKCVzKS4iOw0KLQljYXNlCUlEU19TVFJJTkdfSlNSQU5HRTE6DQotCQlyZXR1cm4gTCJJbnZhbGlkIHZhbHVlOiBtdXN0IGJlIGdyZWF0ZXIgb3IgZXF1YWwgdG8gJXMgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcy4iOwkNCi0JY2FzZQlJRFNfU1RSSU5HX0pTUkFOR0UyOg0KLQkJcmV0dXJuIEwiSW52YWxpZCB2YWx1ZTogbXVzdCBiZSBncmVhdGVyIG9yIGVxdWFsIHRvICVzLiI7DQotCWNhc2UJSURTX1NUUklOR19KU1JBTkdFMzoNCi0JCXJldHVybiBMIkludmFsaWQgdmFsdWU6IG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzLiI7DQotCWNhc2UJSURTX1NUUklOR19KU1JBTkdFNDoNCi0JCXJldHVybiBMIlJhbmdlIEVycm9yIjsJDQotCWNhc2UJSURTX1NUUklOR19GSUxFT1BFTkZBSUw6DQotICAgICAgICByZXR1cm4gTCJPcGVuaW5nIGZpbGUgZmFpbGVkLiI7DQotCWNhc2UJSURTX1NUUklOR19KU0FUVEVOVElPTjoNCi0JCXJldHVybiBMIkF0dGVudGlvbiI7CQ0KLQljYXNlCUlEU19TVFJJTkdfSlNTVUJNSVRTOg0KLQkJcmV0dXJuIEwiU3VibWl0IGZvcm0gc3VjY2Vzc2Z1bGx5ISI7DQotCWNhc2UJSURTX1NUUklOR19KU1NVQk1JVEY6DQotCQlyZXR1cm4gTCJTdWJtaXQgZm9ybSBmYWlsZWQhIjsJDQotCWNhc2UJSURTX1NUUklOR19OT1RTVVBQT1JUOg0KLQkJcmV0dXJuIEwiTm90IHN1cHBvcnRlZC4iOw0KLQljYXNlCUlEU19TVFJJTkdfSlNCVVNZOg0KLQkJcmV0dXJuIEwiU3lzdGVtIGlzIGJ1c3khIjsJDQotCWNhc2UJSURTX1NUUklOR19KU0VWRU5UOg0KLQkJcmV0dXJuIEwiVGhlIGV2ZW50IG9mIHRoZSBmb3JtZmllbGQgZXhpc3RzISI7CQ0KLQljYXNlCUlEU19TVFJJTkdfUlVOOg0KLQkJcmV0dXJuIEwiSXQgcnVucyBzdWNjZXNzZnVsbHkuIjsNCi0JY2FzZQlJRFNfU1RSSU5HX1VOSEFORExFRDoNCi0JCXJldHVybiBMIkFuIHVuaGFuZGxlZCBlcnJvciEiOw0KLQljYXNlCUlEU19TVFJJTkdfSlNQUklOVDE6DQotCQlyZXR1cm4gTCJUaGUgc2Vjb25kIHBhcmFtZXRlciBjYW4ndCBjb252ZXJ0IHRvIERhdGUhIjsNCi0JY2FzZQlJRFNfU1RSSU5HX0pTUFJJTlQyOg0KLQkJcmV0dXJuIEwiVGhlIHNlY29uZCBwYXJhbWV0ZXIgaXNuJ3QgYSB2YWxpZCBEYXRlISI7DQotCWNhc2UJSURTX1NUUklOR19MQVVOQ0hVUkw6DQotCQlyZXR1cm4gTCJUaGUgRG9jdW1lbnQgaXMgdHJ5aW5nIHRvIGNvbm5lY3QgdG8gXHJcbiVzXHJcbklmIHlvdSB0cnVzdCB0aGUgc2l0ZSwgY2hvb3NlIE9LLiBJZiB5b3UgZG9uJ3QgdHJ1c3QgdGhlIHNpdGUsIGNob29zZSBDYW5jZWwuIjsJDQotCWNhc2UJSURTX0pTUEFSQU1fSU5DT1JSRUNUOg0KLQkJcmV0dXJuIEwiVGhlIHBhcmFtZXRlciB5b3UgaW5wdXR0ZWQgaXMgaW5jb3JyZWN0ISI7DQotCWNhc2UJSURTX1NUUklOR19TQUZFTU9ERUw6DQotCQlyZXR1cm4gTCJTZWN1cmUgcmVhZGluZyBtb2RlIjsNCi0JZGVmYXVsdDoNCi0JCXJldHVybiBMIiI7DQotDQotCX0NCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2RlZmluZSBJRERfSlNfTVNHQk9YICAgICAgICAgICAgICAgICAgIDI1NjAwCisjZGVmaW5lIElERF9SRVNQT05TRSAgICAgICAgICAgICAgICAgICAgMjU2MDEKKyNkZWZpbmUgSURDX0pTX01TR19URVhUICAgICAgICAgICAgICAgICAyNTYwMgorI2RlZmluZSBJRF9KU19NU0dfT0sgICAgICAgICAgICAgICAgICAgIDI1NjAzCisjZGVmaW5lIElEX0pTX01TR19DQU5DRUwgICAgICAgICAgICAgICAgMjU2MDQKKyNkZWZpbmUgSURDX0pTX01TR19JQ09OICAgICAgICAgICAgICAgICAyNTYwNQorI2RlZmluZSBJRF9KU19NU0dfWUVTICAgICAgICAgICAgICAgICAgIDI1NjA2CisjZGVmaW5lIElEX0pTX01TR19OTyAgICAgICAgICAgICAgICAgICAgMjU2MDcKKyNkZWZpbmUgSURDX0pTX1FVRVNUSU9OICAgICAgICAgICAgICAgICAyNTYwOAorI2RlZmluZSBJRF9KU19PSyAgICAgICAgICAgICAgICAgICAgICAgIDI1NjA5CisjZGVmaW5lIElEX0pTX0NBTkNFTCAgICAgICAgICAgICAgICAgICAgMjU2MTAKKyNkZWZpbmUgSURDX0pTX0FOU1dFUiAgICAgICAgICAgICAgICAgICAyNTYxMQorI2RlZmluZSBJRENfSlNfRURJVCAgICAgICAgICAgICAgICAgICAgIDI1NjEyCisjZGVmaW5lIElEU19TVFJJTkdfSlNBTEVSVCAgICAgICAgICAgICAgMjU2MTMKKyNkZWZpbmUgSURTX1NUUklOR19KU1BBUkFNRVJST1IgICAgICAgICAyNTYxNAorI2RlZmluZSBJRFNfU1RSSU5HX0pTQUZOVU1CRVJfS0VZU1RST0tFIDI1NjE1CisjZGVmaW5lIElEU19TVFJJTkdfSlNJTlBVVEVSUk9SICAgICAgICAgMjU2MTYKKyNkZWZpbmUgSURTX1NUUklOR19KU1BBUkFNX1RPT0xPTkcgICAgICAyNTYxNworI2RlZmluZSBJRFNfU1RSSU5HX0pTUEFSU0VEQVRFICAgICAgICAgIDI1NjE4CisjZGVmaW5lIElEU19TVFJJTkdfSlNSQU5HRTEgICAgICAgICAgICAgMjU2MTkKKyNkZWZpbmUgSURTX1NUUklOR19KU1JBTkdFMiAgICAgICAgICAgICAyNTYyMAorI2RlZmluZSBJRFNfU1RSSU5HX0pTUkFOR0UzICAgICAgICAgICAgIDI1NjIxCisjZGVmaW5lIElEU19TVFJJTkdfSlNSQU5HRTQgICAgICAgICAgICAgMjU2MjIKKyNkZWZpbmUgSURTX1NUUklOR19GSUxFT1BFTkZBSUwgICAgICAgICAyNTYyMworI2RlZmluZSBJRFNfU1RSSU5HX0pTQVRURU5USU9OICAgICAgICAgIDI1NjI0CisjZGVmaW5lIElEU19TVFJJTkdfSlNTVUJNSVRTICAgICAgICAgICAgMjU2MjUKKyNkZWZpbmUgSURTX1NUUklOR19KU1NVQk1JVEYgICAgICAgICAgICAyNTYyNgorI2RlZmluZSBJRFNfU1RSSU5HX05PVFNVUFBPUlQgICAgICAgICAgIDI1NjI3CisjZGVmaW5lIElEU19TVFJJTkdfSlNCVVNZICAgICAgICAgICAgICAgMjU2MjgKKyNkZWZpbmUgSURTX1NUUklOR19KU0VWRU5UICAgICAgICAgICAgICAyNTYyOQorI2RlZmluZSBJRFNfU1RSSU5HX1JVTiAgICAgICAgICAgICAgICAgIDI1NjMwCisjZGVmaW5lIElEU19TVFJJTkdfVU5IQU5ETEVEICAgICAgICAgICAgMjU2MzEKKyNkZWZpbmUgSURTX1NUUklOR19KU1BSSU5UMSAgICAgICAgICAgICAyNTYzMgorI2RlZmluZSBJRFNfU1RSSU5HX0pTUFJJTlQyICAgICAgICAgICAgIDI1NjMzCisjZGVmaW5lIElEU19TVFJJTkdfTEFVTkNIVVJMICAgICAgICAgICAgMjU2MzQKKyNkZWZpbmUgSURTX0pTUEFSQU1fSU5DT1JSRUNUICAgICAgICAgICAyNTYzNQorI2RlZmluZSBJRERfSlNfQ09OU09MRSAgICAgICAgICAgICAgICAgIDI1NjM2CisjZGVmaW5lIElEU19TVFJJTkdfU0FGRU1PREVMICAgICAgICAgICAgMjU2MzYKKyNkZWZpbmUgSURDX0VEVFNDUklQVCAgICAgICAgICAgICAgICAgICAyNTYzNworI2RlZmluZSBJRENfQlROQ0xFQVIgICAgICAgICAgICAgICAgICAgIDI1NjM4CisjZGVmaW5lIElEQ19FRFRPVVRQVVQgICAgICAgICAgICAgICAgICAgMjU2MzkKKyNkZWZpbmUgSURDX0NIRUNLX1RJUFMgICAgICAgICAgICAgICAgICAyNTY0MAorI2RlZmluZSBJRENfQlROUlVOICAgICAgICAgICAgICAgICAgICAgIDI1NjQxCisKKworCitzdGF0aWMgQ0ZYX1dpZGVTdHJpbmcgSlNHZXRTdHJpbmdGcm9tSUQoQ0pTX0NvbnRleHQqIHBDb250ZXh0LCBGWF9VSU5UIElEKQoreworCXN3aXRjaChJRCkKKwl7ICAgICAgICAgICAgICAgICAgCisJY2FzZSBJRFNfU1RSSU5HX0pTQUxFUlQ6CisJCXJldHVybiBMIkFsZXJ0IjsKKwljYXNlIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SOgorICAgICAgICByZXR1cm4gTCJUaGUgYW1vdW50IG9mIHBhcmFtZXRlcnMgaXMgbm90IGNvcnJlY3QgISI7CQorCWNhc2UgSURTX1NUUklOR19KU0FGTlVNQkVSX0tFWVNUUk9LRToKKwkJcmV0dXJuIEwiVGhlIGlucHV0IHZhbHVlIGlzIGludmFsaWQuIjsKKwljYXNlCUlEU19TVFJJTkdfSlNJTlBVVEVSUk9SOgorICAgICAgICByZXR1cm4gTCJJbnB1dCBlcnJvciAhIjsKKwljYXNlCUlEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HOgorCQlyZXR1cm4gTCJUaGUgdmFsdWUgeW91IGFyZSBnb2luZyB0byBpbnB1dCBpcyB0b28gbG9uZy4iOworCWNhc2UJSURTX1NUUklOR19KU1BBUlNFREFURToKKwkJcmV0dXJuIEwiVGhlIGlucHV0IHN0cmluZyBjYW4ndCBiZSBwYXJzZWQgdG8gYSB2YWxpZCBkYXRlIHRpbWUgKCVzKS4iOworCWNhc2UJSURTX1NUUklOR19KU1JBTkdFMToKKwkJcmV0dXJuIEwiSW52YWxpZCB2YWx1ZTogbXVzdCBiZSBncmVhdGVyIG9yIGVxdWFsIHRvICVzIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMuIjsJCisJY2FzZQlJRFNfU1RSSU5HX0pTUkFOR0UyOgorCQlyZXR1cm4gTCJJbnZhbGlkIHZhbHVlOiBtdXN0IGJlIGdyZWF0ZXIgb3IgZXF1YWwgdG8gJXMuIjsKKwljYXNlCUlEU19TVFJJTkdfSlNSQU5HRTM6CisJCXJldHVybiBMIkludmFsaWQgdmFsdWU6IG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzLiI7CisJY2FzZQlJRFNfU1RSSU5HX0pTUkFOR0U0OgorCQlyZXR1cm4gTCJSYW5nZSBFcnJvciI7CQorCWNhc2UJSURTX1NUUklOR19GSUxFT1BFTkZBSUw6CisgICAgICAgIHJldHVybiBMIk9wZW5pbmcgZmlsZSBmYWlsZWQuIjsKKwljYXNlCUlEU19TVFJJTkdfSlNBVFRFTlRJT046CisJCXJldHVybiBMIkF0dGVudGlvbiI7CQorCWNhc2UJSURTX1NUUklOR19KU1NVQk1JVFM6CisJCXJldHVybiBMIlN1Ym1pdCBmb3JtIHN1Y2Nlc3NmdWxseSEiOworCWNhc2UJSURTX1NUUklOR19KU1NVQk1JVEY6CisJCXJldHVybiBMIlN1Ym1pdCBmb3JtIGZhaWxlZCEiOwkKKwljYXNlCUlEU19TVFJJTkdfTk9UU1VQUE9SVDoKKwkJcmV0dXJuIEwiTm90IHN1cHBvcnRlZC4iOworCWNhc2UJSURTX1NUUklOR19KU0JVU1k6CisJCXJldHVybiBMIlN5c3RlbSBpcyBidXN5ISI7CQorCWNhc2UJSURTX1NUUklOR19KU0VWRU5UOgorCQlyZXR1cm4gTCJUaGUgZXZlbnQgb2YgdGhlIGZvcm1maWVsZCBleGlzdHMhIjsJCisJY2FzZQlJRFNfU1RSSU5HX1JVTjoKKwkJcmV0dXJuIEwiSXQgcnVucyBzdWNjZXNzZnVsbHkuIjsKKwljYXNlCUlEU19TVFJJTkdfVU5IQU5ETEVEOgorCQlyZXR1cm4gTCJBbiB1bmhhbmRsZWQgZXJyb3IhIjsKKwljYXNlCUlEU19TVFJJTkdfSlNQUklOVDE6CisJCXJldHVybiBMIlRoZSBzZWNvbmQgcGFyYW1ldGVyIGNhbid0IGNvbnZlcnQgdG8gRGF0ZSEiOworCWNhc2UJSURTX1NUUklOR19KU1BSSU5UMjoKKwkJcmV0dXJuIEwiVGhlIHNlY29uZCBwYXJhbWV0ZXIgaXNuJ3QgYSB2YWxpZCBEYXRlISI7CisJY2FzZQlJRFNfU1RSSU5HX0xBVU5DSFVSTDoKKwkJcmV0dXJuIEwiVGhlIERvY3VtZW50IGlzIHRyeWluZyB0byBjb25uZWN0IHRvIFxyXG4lc1xyXG5JZiB5b3UgdHJ1c3QgdGhlIHNpdGUsIGNob29zZSBPSy4gSWYgeW91IGRvbid0IHRydXN0IHRoZSBzaXRlLCBjaG9vc2UgQ2FuY2VsLiI7CQorCWNhc2UJSURTX0pTUEFSQU1fSU5DT1JSRUNUOgorCQlyZXR1cm4gTCJUaGUgcGFyYW1ldGVyIHlvdSBpbnB1dHRlZCBpcyBpbmNvcnJlY3QhIjsKKwljYXNlCUlEU19TVFJJTkdfU0FGRU1PREVMOgorCQlyZXR1cm4gTCJTZWN1cmUgcmVhZGluZyBtb2RlIjsKKwlkZWZhdWx0OgorCQlyZXR1cm4gTCIiOworCisJfQorfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC91dGlsLmggYi9mcGRmc2RrL2luY2x1ZGUvamF2YXNjcmlwdC91dGlsLmgKaW5kZXggOWY0ZWZjMy4uMTQ4NTdjOSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL2phdmFzY3JpcHQvdXRpbC5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9qYXZhc2NyaXB0L3V0aWwuaApAQCAtMSw0NSArMSw0NSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfVVRJTF9IXw0KLSNkZWZpbmUgX1VUSUxfSF8NCi0NCi1jbGFzcyB1dGlsIDogcHVibGljIENKU19FbWJlZE9iag0KLXsNCi1wdWJsaWM6DQotCXV0aWwoQ0pTX09iamVjdCAqIHBKU09iamVjdCk7DQotCXZpcnR1YWwgfnV0aWwodm9pZCk7DQotDQotcHVibGljOg0KLQlGWF9CT09MIHByaW50ZChPQkpfTUVUSE9EX1BBUkFNUyk7DQotCUZYX0JPT0wgcHJpbnRmKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBwcmludHgoT0JKX01FVEhPRF9QQVJBTVMpOw0KLQlGWF9CT09MIHNjYW5kKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0JRlhfQk9PTCBieXRlVG9DaGFyKE9CSl9NRVRIT0RfUEFSQU1TKTsNCi0NCi1wdWJsaWM6DQotCXN0YXRpYyB2b2lkCQlwcmludGQoY29uc3Qgc3RkOjp3c3RyaW5nICZjRm9ybWF0LENKU19EYXRlIERhdGUsYm9vbCBiWEZBUGljdHVyZSwgc3RkOjp3c3RyaW5nICZjUHVycG9zZSk7DQotCXN0YXRpYyB2b2lkCQlwcmludHgoY29uc3Qgc3RkOjpzdHJpbmcgJmNGb3JtYXQsY29uc3Qgc3RkOjpzdHJpbmcgJmNTb3VyY2UsIHN0ZDo6c3RyaW5nICZjUHVycG9zZSk7DQotCXN0YXRpYyBpbnQJCVBhcnN0RGF0YVR5cGUoc3RkOjp3c3RyaW5nKiBzRm9ybWF0KTsNCi19Ow0KLQ0KLWNsYXNzIENKU19VdGlsIDogcHVibGljIENKU19PYmplY3QNCi17DQotcHVibGljOg0KLQlDSlNfVXRpbChKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307DQotCXZpcnR1YWwgfkNKU19VdGlsKHZvaWQpe307DQotDQotCURFQ0xBUkVfSlNfQ0xBU1MoQ0pTX1V0aWwpOw0KLQ0KLQlKU19TVEFUSUNfTUVUSE9EKHByaW50ZCwgdXRpbCk7DQotCUpTX1NUQVRJQ19NRVRIT0QocHJpbnRmLCB1dGlsKTsNCi0JSlNfU1RBVElDX01FVEhPRChwcmludHgsIHV0aWwpOw0KLQlKU19TVEFUSUNfTUVUSE9EKHNjYW5kLCB1dGlsKTsNCi0JSlNfU1RBVElDX01FVEhPRChieXRlVG9DaGFyLCB1dGlsKTsNCi19Ow0KLQ0KLUZYX0lOVDY0IEZYX2F0b2k2NChjb25zdCBjaGFyICpucHRyKTsNCi0jZW5kaWYgLy9fVVRJTF9IXw0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1VUSUxfSF8KKyNkZWZpbmUgX1VUSUxfSF8KKworY2xhc3MgdXRpbCA6IHB1YmxpYyBDSlNfRW1iZWRPYmoKK3sKK3B1YmxpYzoKKwl1dGlsKENKU19PYmplY3QgKiBwSlNPYmplY3QpOworCXZpcnR1YWwgfnV0aWwodm9pZCk7CisKK3B1YmxpYzoKKwlGWF9CT09MIHByaW50ZChPQkpfTUVUSE9EX1BBUkFNUyk7CisJRlhfQk9PTCBwcmludGYoT0JKX01FVEhPRF9QQVJBTVMpOworCUZYX0JPT0wgcHJpbnR4KE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIHNjYW5kKE9CSl9NRVRIT0RfUEFSQU1TKTsKKwlGWF9CT09MIGJ5dGVUb0NoYXIoT0JKX01FVEhPRF9QQVJBTVMpOworCitwdWJsaWM6CisJc3RhdGljIHZvaWQJCXByaW50ZChjb25zdCBzdGQ6OndzdHJpbmcgJmNGb3JtYXQsQ0pTX0RhdGUgRGF0ZSxib29sIGJYRkFQaWN0dXJlLCBzdGQ6OndzdHJpbmcgJmNQdXJwb3NlKTsKKwlzdGF0aWMgdm9pZAkJcHJpbnR4KGNvbnN0IHN0ZDo6c3RyaW5nICZjRm9ybWF0LGNvbnN0IHN0ZDo6c3RyaW5nICZjU291cmNlLCBzdGQ6OnN0cmluZyAmY1B1cnBvc2UpOworCXN0YXRpYyBpbnQJCVBhcnN0RGF0YVR5cGUoc3RkOjp3c3RyaW5nKiBzRm9ybWF0KTsKK307CisKK2NsYXNzIENKU19VdGlsIDogcHVibGljIENKU19PYmplY3QKK3sKK3B1YmxpYzoKKwlDSlNfVXRpbChKU0ZYT2JqZWN0ICBwT2JqZWN0KSA6IENKU19PYmplY3QocE9iamVjdCkge307CisJdmlydHVhbCB+Q0pTX1V0aWwodm9pZCl7fTsKKworCURFQ0xBUkVfSlNfQ0xBU1MoQ0pTX1V0aWwpOworCisJSlNfU1RBVElDX01FVEhPRChwcmludGQsIHV0aWwpOworCUpTX1NUQVRJQ19NRVRIT0QocHJpbnRmLCB1dGlsKTsKKwlKU19TVEFUSUNfTUVUSE9EKHByaW50eCwgdXRpbCk7CisJSlNfU1RBVElDX01FVEhPRChzY2FuZCwgdXRpbCk7CisJSlNfU1RBVElDX01FVEhPRChieXRlVG9DaGFyLCB1dGlsKTsKK307CisKK0ZYX0lOVDY0IEZYX2F0b2k2NChjb25zdCBjaGFyICpucHRyKTsKKyNlbmRpZiAvL19VVElMX0hfCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L0lQREZXaW5kb3cuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvSVBERldpbmRvdy5oCmluZGV4IDUzYjk2YTYuLjIyZjAyM2QgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvSVBERldpbmRvdy5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvSVBERldpbmRvdy5oCkBAIC0xLDI4ICsxLDI4IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9JUERGV0lORE9XX0hfDQotI2RlZmluZSBfSVBERldJTkRPV19IXw0KLQ0KLSNpbmNsdWRlICJQV0xfV25kLmgiDQotI2luY2x1ZGUgIlBXTF9FZGl0Q3RybC5oIg0KLSNpbmNsdWRlICJQV0xfRWRpdC5oIg0KLSNpbmNsdWRlICJQV0xfTGlzdEJveC5oIg0KLSNpbmNsdWRlICJQV0xfQ29tYm9Cb3guaCINCi0jaW5jbHVkZSAiUFdMX0J1dHRvbi5oIg0KLSNpbmNsdWRlICJQV0xfU3BlY2lhbEJ1dHRvbi5oIg0KLSNpbmNsdWRlICJQV0xfSWNvbi5oIg0KLSNpbmNsdWRlICJQV0xfTGFiZWwuaCINCi0jaW5jbHVkZSAiUFdMX0xpc3RDdHJsLmgiDQotI2luY2x1ZGUgIlBXTF9DYXJldC5oIg0KLSNpbmNsdWRlICJQV0xfU2Nyb2xsQmFyLmgiDQotI2luY2x1ZGUgIlBXTF9Ob3RlLmgiDQotI2luY2x1ZGUgIlBXTF9JY29uTGlzdC5oIg0KLSNpbmNsdWRlICJQV0xfRm9udE1hcC5oIg0KLSNpbmNsdWRlICJQV0xfU2lnbmF0dXJlLmgiDQotI2luY2x1ZGUgIlBXTF9VdGlscy5oIg0KLQ0KLSNlbmRpZiAvL19JUERGV0lORE9XX0hfDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfSVBERldJTkRPV19IXworI2RlZmluZSBfSVBERldJTkRPV19IXworCisjaW5jbHVkZSAiUFdMX1duZC5oIgorI2luY2x1ZGUgIlBXTF9FZGl0Q3RybC5oIgorI2luY2x1ZGUgIlBXTF9FZGl0LmgiCisjaW5jbHVkZSAiUFdMX0xpc3RCb3guaCIKKyNpbmNsdWRlICJQV0xfQ29tYm9Cb3guaCIKKyNpbmNsdWRlICJQV0xfQnV0dG9uLmgiCisjaW5jbHVkZSAiUFdMX1NwZWNpYWxCdXR0b24uaCIKKyNpbmNsdWRlICJQV0xfSWNvbi5oIgorI2luY2x1ZGUgIlBXTF9MYWJlbC5oIgorI2luY2x1ZGUgIlBXTF9MaXN0Q3RybC5oIgorI2luY2x1ZGUgIlBXTF9DYXJldC5oIgorI2luY2x1ZGUgIlBXTF9TY3JvbGxCYXIuaCIKKyNpbmNsdWRlICJQV0xfTm90ZS5oIgorI2luY2x1ZGUgIlBXTF9JY29uTGlzdC5oIgorI2luY2x1ZGUgIlBXTF9Gb250TWFwLmgiCisjaW5jbHVkZSAiUFdMX1NpZ25hdHVyZS5oIgorI2luY2x1ZGUgIlBXTF9VdGlscy5oIgorCisjZW5kaWYgLy9fSVBERldJTkRPV19IXwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgKaW5kZXggMjI3MDNlMS4uYTgzYmU0MSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oCkBAIC0xLDI4ICsxLDI4IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9QREZXSU5ET1dfSF8NCi0jZGVmaW5lIF9QREZXSU5ET1dfSF8NCi0NCi0vLyAjZGVmaW5lIFZDX0VYVFJBTEVBTg0KLS8vICNpbmNsdWRlIDxhZnhleHQuaD4NCi0vLyAjaW5jbHVkZSA8YWZ4Y21uLmg+DQotDQotI2lmbmRlZiBfSU5DX1BERkFQSQ0KLQkjZGVmaW5lIF9JTkNfUERGQVBJDQotIA0KLQkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZhcGkvZnBkZl9tb2R1bGUuaCIgDQotCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmRvYy9mcGRmX2RvYy5oIiANCi0JI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmZG9jL2ZwZGZfdnQuaCIgDQotCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnhjcnQvZnhfeG1sLmgiIA0KLQ0KLQkjaW5jbHVkZSAiLi4vZnBkZl9md2xldmVudC5oIg0KLQkjaW5jbHVkZSAiLi4vZnhfc3lzdGVtaGFuZGxlci5oIg0KLSNlbmRpZg0KLQ0KLSNpbmNsdWRlICIuLi9meGVkaXQvZnhfZWRpdC5oIg0KLSNlbmRpZg0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1BERldJTkRPV19IXworI2RlZmluZSBfUERGV0lORE9XX0hfCisKKy8vICNkZWZpbmUgVkNfRVhUUkFMRUFOCisvLyAjaW5jbHVkZSA8YWZ4ZXh0Lmg+CisvLyAjaW5jbHVkZSA8YWZ4Y21uLmg+CisKKyNpZm5kZWYgX0lOQ19QREZBUEkKKwkjZGVmaW5lIF9JTkNfUERGQVBJCisgCisJI2luY2x1ZGUgIi4uLy4uLy4uL2NvcmUvaW5jbHVkZS9mcGRmYXBpL2ZwZGZfbW9kdWxlLmgiIAorCSNpbmNsdWRlICIuLi8uLi8uLi9jb3JlL2luY2x1ZGUvZnBkZmRvYy9mcGRmX2RvYy5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2ZwZGZkb2MvZnBkZl92dC5oIiAKKwkjaW5jbHVkZSAiLi4vLi4vLi4vY29yZS9pbmNsdWRlL2Z4Y3J0L2Z4X3htbC5oIiAKKworCSNpbmNsdWRlICIuLi9mcGRmX2Z3bGV2ZW50LmgiCisJI2luY2x1ZGUgIi4uL2Z4X3N5c3RlbWhhbmRsZXIuaCIKKyNlbmRpZgorCisjaW5jbHVkZSAiLi4vZnhlZGl0L2Z4X2VkaXQuaCIKKyNlbmRpZgorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9CdXR0b24uaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oCmluZGV4IDIwMmEwZDEuLjg0MTZjNGQgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oCkBAIC0xLDI4ICsxLDI4IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9QV0xfQlVUVE9OX0hfDQotI2RlZmluZSBfUFdMX0JVVFRPTl9IXw0KLQ0KLWNsYXNzIFBXTF9DTEFTUyBDUFdMX0J1dHRvbiA6IHB1YmxpYyBDUFdMX1duZCAgDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9CdXR0b24oKTsNCi0JdmlydHVhbCB+Q1BXTF9CdXR0b24oKTsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCUdldENsYXNzTmFtZSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIHZvaWQJCQkJT25DcmVhdGUoUFdMX0NSRUFURVBBUkFNICYgY3ApOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQ0KLXByb3RlY3RlZDoNCi0JRlhfQk9PTAkJCQkJCW1fYk1vdXNlRG93bjsJDQotfTsNCi0NCi0jZW5kaWYgLy8gIWRlZmluZWQoQUZYX1BXTF9CVVRUT05fSF9fNUE2MDgwQUFfMzNDNV80RkM5XzkxRkNfRDk2NDRDNDExMjBBX19JTkNMVURFRF8pDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfUFdMX0JVVFRPTl9IXworI2RlZmluZSBfUFdMX0JVVFRPTl9IXworCitjbGFzcyBQV0xfQ0xBU1MgQ1BXTF9CdXR0b24gOiBwdWJsaWMgQ1BXTF9XbmQgIAoreworcHVibGljOgorCUNQV0xfQnV0dG9uKCk7CisJdmlydHVhbCB+Q1BXTF9CdXR0b24oKTsKKworcHVibGljOgorCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCUdldENsYXNzTmFtZSgpIGNvbnN0OworCXZpcnR1YWwgdm9pZAkJCQlPbkNyZWF0ZShQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisKK3Byb3RlY3RlZDoKKwlGWF9CT09MCQkJCQkJbV9iTW91c2VEb3duOwkKK307CisKKyNlbmRpZiAvLyAhZGVmaW5lZChBRlhfUFdMX0JVVFRPTl9IX181QTYwODBBQV8zM0M1XzRGQzlfOTFGQ19EOTY0NEM0MTEyMEFfX0lOQ0xVREVEXykKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ2FyZXQuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0NhcmV0LmgKaW5kZXggNDU4NmQ0Ny4uNjAwZTUwOSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ2FyZXQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9DYXJldC5oCkBAIC0xLDU4ICsxLDU4IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9QV0xfQ0FSRVRfSF8NCi0jZGVmaW5lIF9QV0xfQ0FSRVRfSF8NCi0NCi1zdHJ1Y3QgUFdMX0NBUkVUX0lORk8NCi17DQotcHVibGljOg0KLQlQV0xfQ0FSRVRfSU5GTygpIDogYlZpc2libGUoRkFMU0UpLCBwdEhlYWQoMCwwKSwgcHRGb290KDAsMCkNCi0JewkJDQotCX0NCi0NCi0JRlhfQk9PTAkJCQkJCWJWaXNpYmxlOw0KLQlDUERGX1BvaW50CQkJCQlwdEhlYWQ7DQotCUNQREZfUG9pbnQJCQkJCXB0Rm9vdDsNCi19Ow0KLQ0KLQ0KLWNsYXNzIENQV0xfQ2FyZXQgOiBwdWJsaWMgQ1BXTF9XbmQgIA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfQ2FyZXQoKTsNCi0JdmlydHVhbCB+Q1BXTF9DYXJldCgpOw0KLXB1YmxpYzoNCi0JdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZAkJCQlHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsNCi0JdmlydHVhbCB2b2lkCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsNCi0JdmlydHVhbCB2b2lkCQkJCUludmFsaWRhdGVSZWN0KENQREZfUmVjdCAqIHBSZWN0ID0gTlVMTCk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlTZXRWaXNpYmxlKEZYX0JPT0wgYlZpc2libGUpIHt9DQotDQotCXZpcnR1YWwJdm9pZAkJCQlUaW1lclByb2MoKTsNCi0NCi0Jdm9pZAkJCQkJCVNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsIGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsIGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QpOwkNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJR2V0Q2FyZXRBcHBlYXJhbmNlU3RyZWFtKGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCk7DQotDQotcHJpdmF0ZToNCi0Jdm9pZAkJCQkJCUdldENhcmV0QXBwKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0sY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KTsNCi0JQ1BERl9SZWN0CQkJCQlHZXRDYXJldFJlY3QoKSBjb25zdDsNCi0NCi0JRlhfQk9PTAkJCQkJCW1fYkZsYXNoOw0KLQlDUERGX1BvaW50CQkJCQltX3B0SGVhZDsNCi0JQ1BERl9Qb2ludAkJCQkJbV9wdEZvb3Q7DQotCUZYX0ZMT0FUCQkJCQltX2ZXaWR0aDsNCi0JRlhfSU5UMzIJCQkJCQltX25EZWxheTsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQlTZXRJbnZhbGlkUmVjdChDUERGX1JlY3QgcmMpIHttX3JjSW52YWxpZCA9IHJjO30NCi1wcml2YXRlOg0KLQlDUERGX1JlY3QJCQkJCW1fcmNJbnZhbGlkOw0KLX07DQotDQotI2VuZGlmIC8vICFkZWZpbmVkKEFGWF9QV0xfQ0FSRVRfSF9fNkE3Mjk2MTJfNDE3M180QjY1X0JDQUJfN0M2Qzg1MEVDQTQ3X19JTkNMVURFRF8pDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfUFdMX0NBUkVUX0hfCisjZGVmaW5lIF9QV0xfQ0FSRVRfSF8KKworc3RydWN0IFBXTF9DQVJFVF9JTkZPCit7CitwdWJsaWM6CisJUFdMX0NBUkVUX0lORk8oKSA6IGJWaXNpYmxlKEZBTFNFKSwgcHRIZWFkKDAsMCksIHB0Rm9vdCgwLDApCisJewkJCisJfQorCisJRlhfQk9PTAkJCQkJCWJWaXNpYmxlOworCUNQREZfUG9pbnQJCQkJCXB0SGVhZDsKKwlDUERGX1BvaW50CQkJCQlwdEZvb3Q7Cit9OworCisKK2NsYXNzIENQV0xfQ2FyZXQgOiBwdWJsaWMgQ1BXTF9XbmQgIAoreworcHVibGljOgorCUNQV0xfQ2FyZXQoKTsKKwl2aXJ0dWFsIH5DUFdMX0NhcmV0KCk7CitwdWJsaWM6CisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CisJdmlydHVhbCB2b2lkCQkJCUdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pOworCXZpcnR1YWwgdm9pZAkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7CisJdmlydHVhbCB2b2lkCQkJCUludmFsaWRhdGVSZWN0KENQREZfUmVjdCAqIHBSZWN0ID0gTlVMTCk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJU2V0VmlzaWJsZShGWF9CT09MIGJWaXNpYmxlKSB7fQorCisJdmlydHVhbAl2b2lkCQkJCVRpbWVyUHJvYygpOworCisJdm9pZAkJCQkJCVNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsIGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsIGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QpOwkKKwlDRlhfQnl0ZVN0cmluZwkJCQlHZXRDYXJldEFwcGVhcmFuY2VTdHJlYW0oY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KTsKKworcHJpdmF0ZToKKwl2b2lkCQkJCQkJR2V0Q2FyZXRBcHAoQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSxjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQpOworCUNQREZfUmVjdAkJCQkJR2V0Q2FyZXRSZWN0KCkgY29uc3Q7CisKKwlGWF9CT09MCQkJCQkJbV9iRmxhc2g7CisJQ1BERl9Qb2ludAkJCQkJbV9wdEhlYWQ7CisJQ1BERl9Qb2ludAkJCQkJbV9wdEZvb3Q7CisJRlhfRkxPQVQJCQkJCW1fZldpZHRoOworCUZYX0lOVDMyCQkJCQkJbV9uRGVsYXk7CisKK3B1YmxpYzoKKwl2b2lkCQkJCQkJU2V0SW52YWxpZFJlY3QoQ1BERl9SZWN0IHJjKSB7bV9yY0ludmFsaWQgPSByYzt9Citwcml2YXRlOgorCUNQREZfUmVjdAkJCQkJbV9yY0ludmFsaWQ7Cit9OworCisjZW5kaWYgLy8gIWRlZmluZWQoQUZYX1BXTF9DQVJFVF9IX182QTcyOTYxMl80MTczXzRCNjVfQkNBQl83QzZDODUwRUNBNDdfX0lOQ0xVREVEXykKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ29tYm9Cb3guaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0NvbWJvQm94LmgKaW5kZXggZjY0YjYzNi4uNWI5MWZlNCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ29tYm9Cb3guaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Db21ib0JveC5oCkBAIC0xLDExNSArMSwxMTUgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1BXTF9DT01CT0JPWF9IXw0KLSNkZWZpbmUgX1BXTF9DT01CT0JPWF9IXw0KLQ0KLWNsYXNzIENQV0xfQ0JFZGl0IDogcHVibGljIENQV0xfRWRpdA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfQ0JFZGl0KCl7fTsNCi0JdmlydHVhbCB+Q1BXTF9DQkVkaXQoKXt9Ow0KLX07DQotDQotY2xhc3MgUFdMX0NMQVNTIENQV0xfQ0JMaXN0Qm94IDogcHVibGljIENQV0xfTGlzdEJveA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfQ0JMaXN0Qm94KCl7fTsNCi0JdmlydHVhbCB+Q1BXTF9DQkxpc3RCb3goKXt9Ow0KLQ0KLXB1YmxpYzoNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25LZXlEb3duKEZYX1dPUkQgbkNoYXIsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpOw0KLX07DQotDQotI2RlZmluZSBQV0xfQ09NQk9CT1hfQlVUVE9OX1dJRFRICQkxMw0KLQ0KLWNsYXNzIENQV0xfQ0JCdXR0b24gOiBwdWJsaWMgQ1BXTF9XbmQNCi17DQotcHVibGljOg0KLQlDUFdMX0NCQnV0dG9uKCl7fTsNCi0JdmlydHVhbCB+Q1BXTF9DQkJ1dHRvbigpe307DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJR2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSk7DQotCXZpcnR1YWwgdm9pZAkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotDQotfTsNCi0NCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9Db21ib0JveCA6IHB1YmxpYyBDUFdMX1duZCAgDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9Db21ib0JveCgpOw0KLQlvcGVyYXRvciBDUFdMX0VkaXQqICgpCQl7cmV0dXJuIG1fcEVkaXQ7fQ0KLQ0KLXB1YmxpYzoNCi0JdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkNyZWF0ZShQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktleURvd24oRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOwkNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uQ2hhcihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZyk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJQ3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApOw0KLQl2aXJ0dWFsIHZvaWQJCQkJUmVQb3NDaGlsZFduZCgpOw0KLQ0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCUdldEZvY3VzUmVjdCgpIGNvbnN0Ow0KLQkNCi0JdmlydHVhbCB2b2lkCQkJCVNldEZvY3VzKCk7DQotCXZpcnR1YWwgdm9pZAkJCQlLaWxsRm9jdXMoKTsNCi0NCi0JRlhfQk9PTAkJCQkJCUlzTW9kaWZpZWQoKSBjb25zdDsNCi0NCi1wdWJsaWM6CQ0KLQl2b2lkCQkJCQkJU2V0RmlsbGVyTm90aWZ5KElQV0xfRmlsbGVyX05vdGlmeSogcE5vdGlmeSk7DQotDQotCUNGWF9XaWRlU3RyaW5nCQkJCUdldFRleHQoKSBjb25zdDsNCi0Jdm9pZAkJCQkJCVNldFRleHQoRlhfTFBDV1NUUiB0ZXh0KTsNCi0NCi0Jdm9pZAkJCQkJCUFkZFN0cmluZyhGWF9MUENXU1RSIHN0cmluZyk7DQotCUZYX0lOVDMyCQkJCQlHZXRTZWxlY3QoKSBjb25zdDsNCi0Jdm9pZAkJCQkJCVNldFNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4KTsNCi0NCi0Jdm9pZAkJCQkJCVNldEVkaXRTZWwoRlhfSU5UMzIgblN0YXJ0Q2hhcixGWF9JTlQzMiBuRW5kQ2hhcik7DQotCXZvaWQJCQkJCQlHZXRFZGl0U2VsKEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhciApIGNvbnN0Ow0KLQl2b2lkCQkJCQkJQ2xlYXIoKTsNCi0Jdm9pZAkJCQkJCVNlbGVjdEFsbCgpOw0KLQlGWF9CT09MCQkJCQkJSXNQb3B1cCgpIGNvbnN0Ow0KLQ0KLQl2b2lkCQkJCQkJU2V0U2VsZWN0VGV4dCgpOw0KLQ0KLXByaXZhdGU6CQ0KLQl2b2lkCQkJCQkJQ3JlYXRlRWRpdChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotCXZvaWQJCQkJCQlDcmVhdGVCdXR0b24oY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApOw0KLQl2b2lkCQkJCQkJQ3JlYXRlTGlzdEJveChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotDQotCXZvaWQJCQkJCQlTZXRQb3B1cChGWF9CT09MIGJQb3B1cCk7DQotCQ0KLXByaXZhdGU6DQotCUNQV0xfQ0JFZGl0KgkJCQltX3BFZGl0Ow0KLQlDUFdMX0NCQnV0dG9uKgkJCQltX3BCdXR0b247DQotCUNQV0xfQ0JMaXN0Qm94KgkJCQltX3BMaXN0Ow0KLQ0KLQlGWF9CT09MCQkJCQkJbV9iUG9wdXA7DQotCUNQREZfUmVjdAkJCQkJbV9yY09sZFdpbmRvdzsNCi0JRlhfSU5UMzIJCQkJCW1fblBvcHVwV2hlcmU7DQotCUZYX0lOVDMyCQkJCQltX25TZWxlY3RJdGVtOw0KLQlJUFdMX0ZpbGxlcl9Ob3RpZnkqCQkJbV9wRmlsbGVyTm90aWZ5Ow0KLQ0KLXB1YmxpYzoNCi0Jdm9pZAkJCQkJCQlBdHRhY2hGRkxEYXRhKHZvaWQqIHBEYXRhKSB7bV9wRm9ybUZpbGxlciA9IHBEYXRhO30NCi1wcml2YXRlOg0KLQl2b2lkKgkJCQkJCQltX3BGb3JtRmlsbGVyOw0KLX07DQotDQotI2VuZGlmIC8vICFkZWZpbmVkKEFGWF9QV0xfQ09NQk9CT1hfSF9fOUQ2NjQ1RjhfNjRBQV80ODA2Xzk0RThfOTVGREVERDM5QzE3X19JTkNMVURFRF8pDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfUFdMX0NPTUJPQk9YX0hfCisjZGVmaW5lIF9QV0xfQ09NQk9CT1hfSF8KKworY2xhc3MgQ1BXTF9DQkVkaXQgOiBwdWJsaWMgQ1BXTF9FZGl0Cit7CitwdWJsaWM6CisJQ1BXTF9DQkVkaXQoKXt9OworCXZpcnR1YWwgfkNQV0xfQ0JFZGl0KCl7fTsKK307CisKK2NsYXNzIFBXTF9DTEFTUyBDUFdMX0NCTGlzdEJveCA6IHB1YmxpYyBDUFdMX0xpc3RCb3gKK3sKK3B1YmxpYzoKKwlDUFdMX0NCTGlzdEJveCgpe307CisJdmlydHVhbCB+Q1BXTF9DQkxpc3RCb3goKXt9OworCitwdWJsaWM6CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCisJdmlydHVhbCBGWF9CT09MCQkJCU9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9CT09MICYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpOworfTsKKworI2RlZmluZSBQV0xfQ09NQk9CT1hfQlVUVE9OX1dJRFRICQkxMworCitjbGFzcyBDUFdMX0NCQnV0dG9uIDogcHVibGljIENQV0xfV25kCit7CitwdWJsaWM6CisJQ1BXTF9DQkJ1dHRvbigpe307CisJdmlydHVhbCB+Q1BXTF9DQkJ1dHRvbigpe307CisKK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQkJR2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSk7CisJdmlydHVhbCB2b2lkCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsKKworfTsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfQ29tYm9Cb3ggOiBwdWJsaWMgQ1BXTF9XbmQgIAoreworcHVibGljOgorCUNQV0xfQ29tYm9Cb3goKTsKKwlvcGVyYXRvciBDUFdMX0VkaXQqICgpCQl7cmV0dXJuIG1fcEVkaXQ7fQorCitwdWJsaWM6CisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CisJdmlydHVhbCB2b2lkCQkJCU9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlPbktleURvd24oRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOwkKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKTsKKworCXZpcnR1YWwgdm9pZAkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOworCisJdmlydHVhbCB2b2lkCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIHZvaWQJCQkJUmVQb3NDaGlsZFduZCgpOworCisJdmlydHVhbCBDUERGX1JlY3QJCQlHZXRGb2N1c1JlY3QoKSBjb25zdDsKKwkKKwl2aXJ0dWFsIHZvaWQJCQkJU2V0Rm9jdXMoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJS2lsbEZvY3VzKCk7CisKKwlGWF9CT09MCQkJCQkJSXNNb2RpZmllZCgpIGNvbnN0OworCitwdWJsaWM6CQorCXZvaWQJCQkJCQlTZXRGaWxsZXJOb3RpZnkoSVBXTF9GaWxsZXJfTm90aWZ5KiBwTm90aWZ5KTsKKworCUNGWF9XaWRlU3RyaW5nCQkJCUdldFRleHQoKSBjb25zdDsKKwl2b2lkCQkJCQkJU2V0VGV4dChGWF9MUENXU1RSIHRleHQpOworCisJdm9pZAkJCQkJCUFkZFN0cmluZyhGWF9MUENXU1RSIHN0cmluZyk7CisJRlhfSU5UMzIJCQkJCUdldFNlbGVjdCgpIGNvbnN0OworCXZvaWQJCQkJCQlTZXRTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCk7CisKKwl2b2lkCQkJCQkJU2V0RWRpdFNlbChGWF9JTlQzMiBuU3RhcnRDaGFyLEZYX0lOVDMyIG5FbmRDaGFyKTsKKwl2b2lkCQkJCQkJR2V0RWRpdFNlbChGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIgKSBjb25zdDsKKwl2b2lkCQkJCQkJQ2xlYXIoKTsKKwl2b2lkCQkJCQkJU2VsZWN0QWxsKCk7CisJRlhfQk9PTAkJCQkJCUlzUG9wdXAoKSBjb25zdDsKKworCXZvaWQJCQkJCQlTZXRTZWxlY3RUZXh0KCk7CisKK3ByaXZhdGU6CQorCXZvaWQJCQkJCQlDcmVhdGVFZGl0KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2b2lkCQkJCQkJQ3JlYXRlQnV0dG9uKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2b2lkCQkJCQkJQ3JlYXRlTGlzdEJveChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7CisKKwl2b2lkCQkJCQkJU2V0UG9wdXAoRlhfQk9PTCBiUG9wdXApOworCQorcHJpdmF0ZToKKwlDUFdMX0NCRWRpdCoJCQkJbV9wRWRpdDsKKwlDUFdMX0NCQnV0dG9uKgkJCQltX3BCdXR0b247CisJQ1BXTF9DQkxpc3RCb3gqCQkJCW1fcExpc3Q7CisKKwlGWF9CT09MCQkJCQkJbV9iUG9wdXA7CisJQ1BERl9SZWN0CQkJCQltX3JjT2xkV2luZG93OworCUZYX0lOVDMyCQkJCQltX25Qb3B1cFdoZXJlOworCUZYX0lOVDMyCQkJCQltX25TZWxlY3RJdGVtOworCUlQV0xfRmlsbGVyX05vdGlmeSoJCQltX3BGaWxsZXJOb3RpZnk7CisKK3B1YmxpYzoKKwl2b2lkCQkJCQkJCUF0dGFjaEZGTERhdGEodm9pZCogcERhdGEpIHttX3BGb3JtRmlsbGVyID0gcERhdGE7fQorcHJpdmF0ZToKKwl2b2lkKgkJCQkJCQltX3BGb3JtRmlsbGVyOworfTsKKworI2VuZGlmIC8vICFkZWZpbmVkKEFGWF9QV0xfQ09NQk9CT1hfSF9fOUQ2NjQ1RjhfNjRBQV80ODA2Xzk0RThfOTVGREVERDM5QzE3X19JTkNMVURFRF8pCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaAppbmRleCA3MWY2NzU2Li5kODZjYjc3IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9FZGl0LmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdC5oCkBAIC0xLDEzOCArMSwxMzggQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1BXTF9FRElUX0hfDQotI2RlZmluZSBfUFdMX0VESVRfSF8NCi0NCi1jbGFzcyBJUFdMX0ZpbGxlcl9Ob3RpZnk7DQotY2xhc3MgQ1BXTF9FZGl0Ow0KLWNsYXNzIElQV0xfU3BlbGxDaGVjazsNCi0NCi1jbGFzcyBJUFdMX0ZpbGxlcl9Ob3RpZnkNCi17DQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCVF1ZXJ5V2hlcmVQb3B1cCh2b2lkKiBwUHJpdmF0ZURhdGEsIEZYX0ZMT0FUIGZQb3B1cE1pbixGWF9GTE9BVCBmUG9wdXBNYXgsIA0KLQkJCQkJCQkJCQlGWF9JTlQzMiAmIG5SZXQsIEZYX0ZMT0FUICYgZlBvcHVwUmV0KSA9IDA7IC8vblJldDogKDA6Ym90dG9tIDE6dG9wKQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uQmVmb3JlS2V5U3Ryb2tlKEZYX0JPT0wgYkVkaXRPckxpc3QsIHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfSU5UMzIgbktleUNvZGUsDQotCQkJCQkJCQkJCUNGWF9XaWRlU3RyaW5nICYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIA0KLQkJCQkJCQkJCQlpbnQgblNlbFN0YXJ0LCBpbnQgblNlbEVuZCwNCi0JCQkJCQkJCQkJRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCAmIGJSQywgRlhfQk9PTCAmIGJFeGl0LCBGWF9EV09SRCBuRmxhZykgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uQWZ0ZXJLZXlTdHJva2UoRlhfQk9PTCBiRWRpdE9yTGlzdCwgdm9pZCogcFByaXZhdGVEYXRhLCBGWF9CT09MICYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKSA9IDA7DQotfTsNCi0NCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9FZGl0IDogcHVibGljIENQV0xfRWRpdEN0cmwsIHB1YmxpYyBJRlhfRWRpdF9PcHJOb3RpZnkNCi17DQotcHVibGljOg0KLQlDUFdMX0VkaXQoKTsNCi0JdmlydHVhbCB+Q1BXTF9FZGl0KCk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25EZXN0cm95KCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25DcmVhdGVkKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJUmVQb3NDaGlsZFduZCgpOw0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRDbGllbnRSZWN0KCkgY29uc3Q7DQotDQotCXZpcnR1YWwgdm9pZAkJCQkJR2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uRGJsQ2xrKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKTsNCi0NCi0JdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Rm9jdXNSZWN0KCkgY29uc3Q7DQotDQotcHVibGljOgkJDQotCXZvaWQJCQkJCQkJU2V0QWxpZ25Gb3JtYXRIKFBXTF9FRElUX0FMSUdORk9STUFUX0ggbkZvcm1hdCA9IFBFQUhfTEVGVCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsJLy8wOmxlZnQgMTpyaWdodCAyOm1pZGRsZSANCi0Jdm9pZAkJCQkJCQlTZXRBbGlnbkZvcm1hdFYoUFdMX0VESVRfQUxJR05GT1JNQVRfViBuRm9ybWF0ID0gUEVBVl9UT1AsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7CS8vMDp0b3AgMTpib3R0b20gMjpjZW50ZXINCi0NCi0Jdm9pZAkJCQkJCQlTZXRDaGFyQXJyYXkoRlhfSU5UMzIgbkNoYXJBcnJheSk7DQotCXZvaWQJCQkJCQkJU2V0TGltaXRDaGFyKEZYX0lOVDMyIG5MaW1pdENoYXIpOw0KLQ0KLQl2b2lkCQkJCQkJCVNldEhvcnpTY2FsZShGWF9JTlQzMiBuSG9yelNjYWxlLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQl2b2lkCQkJCQkJCVNldENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOw0KLQ0KLQl2b2lkCQkJCQkJCVNldExpbmVMZWFkaW5nKEZYX0ZMT0FUIGZMaW5lTGVhZGluZywgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsNCi0NCi0Jdm9pZAkJCQkJCQlFbmFibGVTcGVsbENoZWNrKEZYX0JPT0wgYkVuYWJsZWQpOw0KLQ0KLQlGWF9CT09MCQkJCQkJCUNhblNlbGVjdEFsbCgpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUNhbkNsZWFyKCkgY29uc3Q7DQotCUZYX0JPT0wJCQkJCQkJQ2FuQ29weSgpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUNhbkN1dCgpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUNhblBhc3RlKCkgY29uc3Q7DQotDQotCXZpcnR1YWwgdm9pZAkJCQkJQ29weVRleHQoKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlQYXN0ZVRleHQoKTsNCi0JdmlydHVhbCB2b2lkIAkJCQkJQ3V0VGV4dCgpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldFRleHQoRlhfTFBDV1NUUiBjc1RleHQpOw0KLQl2b2lkCQkJCQkJCVJlcGxhY2VTZWwoRlhfTFBDV1NUUiBjc1RleHQpOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZwkJCQkJR2V0VGV4dEFwcGVhcmFuY2VTdHJlYW0oY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KSBjb25zdDsNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldENhcmV0QXBwZWFyYW5jZVN0cmVhbShjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQpIGNvbnN0OwkNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldFNlbGVjdEFwcGVhcmFuY2VTdHJlYW0oY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KSBjb25zdDsNCi0NCi0JRlhfQk9PTAkJCQkJCQlJc1RleHRGdWxsKCkgY29uc3Q7CQ0KLQ0KLQlzdGF0aWMgRlhfRkxPQVQJCQkJCUdldENoYXJBcnJheUF1dG9Gb250U2l6ZShDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDUERGX1JlY3QmIHJjUGxhdGUsIEZYX0lOVDMyIG5DaGFyQXJyYXkpOw0KLQ0KLQl2b2lkCQkJCQkJCVNldEZpbGxlck5vdGlmeShJUFdMX0ZpbGxlcl9Ob3RpZnkqIHBOb3RpZnkpIHttX3BGaWxsZXJOb3RpZnkgPSBwTm90aWZ5O30NCi0NCi0Jdm9pZAkJCQkJCQlHZW5lcmF0ZVBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgDQotCQkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBDRlhfQXJyYXlUZW1wbGF0ZTxDUERGX1RleHRPYmplY3QqPiYgT2JqQXJyYXkpOw0KLQl2b2lkCQkJCQkJCUdlbmVyYXRlUGFnZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmplY3RzLCANCi0JCQkJCQkJCQkJY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQpOw0KLQ0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCB2b2lkCQkJCQlPblNldEZvY3VzKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25LaWxsRm9jdXMoKTsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZpcnR1YWwgdm9pZAkJCQkJT25JbnNlcnRXb3JkKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlPbkluc2VydFJldHVybihjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25CYWNrU3BhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uRGVsZXRlKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlPbkNsZWFyKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlPblNldFRleHQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uSW5zZXJ0VGV4dChjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25BZGRVbmRvKElGWF9FZGl0X1VuZG9JdGVtKiBwVW5kb0l0ZW0pOw0KLQ0KLXByaXZhdGU6CQ0KLQlDUFZUX1dvcmRSYW5nZQkJCQkJR2V0U2VsZWN0V29yZFJhbmdlKCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZAkJCQkJU2hvd1ZTY3JvbGxCYXIoRlhfQk9PTCBiU2hvdyk7DQotCUZYX0JPT0wJCQkJCQkJSXNWU2Nyb2xsQmFyVmlzaWJsZSgpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCVNldFBhcmFtQnlGbGFnKCk7DQotDQotCUZYX0ZMT0FUCQkJCQkJR2V0Q2hhckFycmF5QXV0b0ZvbnRTaXplKEZYX0lOVDMyIG5DaGFyQXJyYXkpOw0KLQlDUERGX1BvaW50CQkJCQkJR2V0V29yZFJpZ2h0Qm90dG9tUG9pbnQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHdwV29yZCk7DQotDQotCUNQVlRfV29yZFJhbmdlCQkJCQlDb21iaW5lV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjEsIGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjIpOw0KLQlDUFZUX1dvcmRSYW5nZQkJCQkJR2V0TGF0aW5Xb3Jkc1JhbmdlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3Q7DQotCUNQVlRfV29yZFJhbmdlCQkJCQlHZXRMYXRpbldvcmRzUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7DQotCUNQVlRfV29yZFJhbmdlCQkJCQlHZXRBcmFiaWNXb3Jkc1JhbmdlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0Ow0KLQlDUFZUX1dvcmRSYW5nZQkJCQkJR2V0U2FtZVdvcmRzUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSwgRlhfQk9PTCBiTGF0aW4sIEZYX0JPT0wgYkFyYWJpYykgY29uc3Q7DQotDQotCXZvaWQJCQkJCQkJQWp1c3RBcmFiaWNXb3Jkcyhjb25zdCBDUFZUX1dvcmRSYW5nZSYgd3IpOw0KLXB1YmxpYzoNCi0JRlhfQk9PTAkJCQkJCQlJc1Byb2NlZWR0b09uQ2hhcihGWF9XT1JEIG5LZXlDb2RlLCBGWF9EV09SRCBuRmxhZyk7DQotcHJpdmF0ZToNCi0JSVBXTF9GaWxsZXJfTm90aWZ5KgkJCQltX3BGaWxsZXJOb3RpZnk7DQotCUlQV0xfU3BlbGxDaGVjayoJCQkJbV9wU3BlbGxDaGVjazsNCi0JRlhfQk9PTAkJCQkJCQltX2JGb2N1czsNCi0JQ1BERl9SZWN0CQkJCQkJbV9yY09sZFdpbmRvdzsNCi1wdWJsaWM6DQotCXZvaWQJCQkJCQkJQXR0YWNoRkZMRGF0YSh2b2lkKiBwRGF0YSkge21fcEZvcm1GaWxsZXIgPSBwRGF0YTt9DQotcHJpdmF0ZToNCi0Jdm9pZCoJCQkJCQkJbV9wRm9ybUZpbGxlcjsNCi19Ow0KLQ0KLSNlbmRpZiANCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9QV0xfRURJVF9IXworI2RlZmluZSBfUFdMX0VESVRfSF8KKworY2xhc3MgSVBXTF9GaWxsZXJfTm90aWZ5OworY2xhc3MgQ1BXTF9FZGl0OworY2xhc3MgSVBXTF9TcGVsbENoZWNrOworCitjbGFzcyBJUFdMX0ZpbGxlcl9Ob3RpZnkKK3sKK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQkJCVF1ZXJ5V2hlcmVQb3B1cCh2b2lkKiBwUHJpdmF0ZURhdGEsIEZYX0ZMT0FUIGZQb3B1cE1pbixGWF9GTE9BVCBmUG9wdXBNYXgsIAorCQkJCQkJCQkJCUZYX0lOVDMyICYgblJldCwgRlhfRkxPQVQgJiBmUG9wdXBSZXQpID0gMDsgLy9uUmV0OiAoMDpib3R0b20gMTp0b3ApCisJdmlydHVhbCB2b2lkCQkJCQlPbkJlZm9yZUtleVN0cm9rZShGWF9CT09MIGJFZGl0T3JMaXN0LCB2b2lkKiBwUHJpdmF0ZURhdGEsIEZYX0lOVDMyIG5LZXlDb2RlLAorCQkJCQkJCQkJCUNGWF9XaWRlU3RyaW5nICYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIAorCQkJCQkJCQkJCWludCBuU2VsU3RhcnQsIGludCBuU2VsRW5kLAorCQkJCQkJCQkJCUZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgJiBiUkMsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCU9uQWZ0ZXJLZXlTdHJva2UoRlhfQk9PTCBiRWRpdE9yTGlzdCwgdm9pZCogcFByaXZhdGVEYXRhLCBGWF9CT09MICYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKSA9IDA7Cit9OworCitjbGFzcyBQV0xfQ0xBU1MgQ1BXTF9FZGl0IDogcHVibGljIENQV0xfRWRpdEN0cmwsIHB1YmxpYyBJRlhfRWRpdF9PcHJOb3RpZnkKK3sKK3B1YmxpYzoKKwlDUFdMX0VkaXQoKTsKKwl2aXJ0dWFsIH5DUFdMX0VkaXQoKTsKKworcHVibGljOgorCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCQlHZXRDbGFzc05hbWUoKSBjb25zdDsKKwl2aXJ0dWFsIHZvaWQJCQkJCU9uRGVzdHJveSgpOworCXZpcnR1YWwgdm9pZAkJCQkJT25DcmVhdGVkKCk7CisJdmlydHVhbCB2b2lkCQkJCQlSZVBvc0NoaWxkV25kKCk7CisJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Q2xpZW50UmVjdCgpIGNvbnN0OworCisJdmlydHVhbCB2b2lkCQkJCQlHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTEJ1dHRvbkRibENsayhjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25Nb3VzZVdoZWVsKHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbkNoYXIoRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOworCisJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Rm9jdXNSZWN0KCkgY29uc3Q7CisKK3B1YmxpYzoJCQorCXZvaWQJCQkJCQkJU2V0QWxpZ25Gb3JtYXRIKFBXTF9FRElUX0FMSUdORk9STUFUX0ggbkZvcm1hdCA9IFBFQUhfTEVGVCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsJLy8wOmxlZnQgMTpyaWdodCAyOm1pZGRsZSAKKwl2b2lkCQkJCQkJCVNldEFsaWduRm9ybWF0VihQV0xfRURJVF9BTElHTkZPUk1BVF9WIG5Gb3JtYXQgPSBQRUFWX1RPUCwgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsJLy8wOnRvcCAxOmJvdHRvbSAyOmNlbnRlcgorCisJdm9pZAkJCQkJCQlTZXRDaGFyQXJyYXkoRlhfSU5UMzIgbkNoYXJBcnJheSk7CisJdm9pZAkJCQkJCQlTZXRMaW1pdENoYXIoRlhfSU5UMzIgbkxpbWl0Q2hhcik7CisKKwl2b2lkCQkJCQkJCVNldEhvcnpTY2FsZShGWF9JTlQzMiBuSG9yelNjYWxlLCBGWF9CT09MIGJQYWludCA9IFRSVUUpOworCXZvaWQJCQkJCQkJU2V0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UsIEZYX0JPT0wgYlBhaW50ID0gVFJVRSk7CisKKwl2b2lkCQkJCQkJCVNldExpbmVMZWFkaW5nKEZYX0ZMT0FUIGZMaW5lTGVhZGluZywgRlhfQk9PTCBiUGFpbnQgPSBUUlVFKTsKKworCXZvaWQJCQkJCQkJRW5hYmxlU3BlbGxDaGVjayhGWF9CT09MIGJFbmFibGVkKTsKKworCUZYX0JPT0wJCQkJCQkJQ2FuU2VsZWN0QWxsKCkgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQlDYW5DbGVhcigpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJQ2FuQ29weSgpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJQ2FuQ3V0KCkgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQlDYW5QYXN0ZSgpIGNvbnN0OworCisJdmlydHVhbCB2b2lkCQkJCQlDb3B5VGV4dCgpOworCXZpcnR1YWwgdm9pZAkJCQkJUGFzdGVUZXh0KCk7CisJdmlydHVhbCB2b2lkIAkJCQkJQ3V0VGV4dCgpOworCisJdmlydHVhbCB2b2lkCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KTsKKwl2b2lkCQkJCQkJCVJlcGxhY2VTZWwoRlhfTFBDV1NUUiBjc1RleHQpOworCisJQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldFRleHRBcHBlYXJhbmNlU3RyZWFtKGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCkgY29uc3Q7CisJQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldENhcmV0QXBwZWFyYW5jZVN0cmVhbShjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQpIGNvbnN0OwkKKwlDRlhfQnl0ZVN0cmluZwkJCQkJR2V0U2VsZWN0QXBwZWFyYW5jZVN0cmVhbShjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQpIGNvbnN0OworCisJRlhfQk9PTAkJCQkJCQlJc1RleHRGdWxsKCkgY29uc3Q7CQorCisJc3RhdGljIEZYX0ZMT0FUCQkJCQlHZXRDaGFyQXJyYXlBdXRvRm9udFNpemUoQ1BERl9Gb250KiBwRm9udCwgY29uc3QgQ1BERl9SZWN0JiByY1BsYXRlLCBGWF9JTlQzMiBuQ2hhckFycmF5KTsKKworCXZvaWQJCQkJCQkJU2V0RmlsbGVyTm90aWZ5KElQV0xfRmlsbGVyX05vdGlmeSogcE5vdGlmeSkge21fcEZpbGxlck5vdGlmeSA9IHBOb3RpZnk7fQorCisJdm9pZAkJCQkJCQlHZW5lcmF0ZVBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgCisJCQkJCQkJCQkJY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIENGWF9BcnJheVRlbXBsYXRlPENQREZfVGV4dE9iamVjdCo+JiBPYmpBcnJheSk7CisJdm9pZAkJCQkJCQlHZW5lcmF0ZVBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgCisJCQkJCQkJCQkJY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQlPblNldEZvY3VzKCk7CisJdmlydHVhbCB2b2lkCQkJCQlPbktpbGxGb2N1cygpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQlPbkluc2VydFdvcmQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpOworCXZpcnR1YWwgdm9pZAkJCQkJT25JbnNlcnRSZXR1cm4oY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpOworCXZpcnR1YWwgdm9pZAkJCQkJT25CYWNrU3BhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpOworCXZpcnR1YWwgdm9pZAkJCQkJT25EZWxldGUoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpOworCXZpcnR1YWwgdm9pZAkJCQkJT25DbGVhcihjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSk7CisJdmlydHVhbCB2b2lkCQkJCQlPblNldFRleHQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpOworCXZpcnR1YWwgdm9pZAkJCQkJT25JbnNlcnRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCU9uQWRkVW5kbyhJRlhfRWRpdF9VbmRvSXRlbSogcFVuZG9JdGVtKTsKKworcHJpdmF0ZToJCisJQ1BWVF9Xb3JkUmFuZ2UJCQkJCUdldFNlbGVjdFdvcmRSYW5nZSgpIGNvbnN0OworCXZpcnR1YWwgdm9pZAkJCQkJU2hvd1ZTY3JvbGxCYXIoRlhfQk9PTCBiU2hvdyk7CisJRlhfQk9PTAkJCQkJCQlJc1ZTY3JvbGxCYXJWaXNpYmxlKCkgY29uc3Q7CisJdm9pZAkJCQkJCQlTZXRQYXJhbUJ5RmxhZygpOworCisJRlhfRkxPQVQJCQkJCQlHZXRDaGFyQXJyYXlBdXRvRm9udFNpemUoRlhfSU5UMzIgbkNoYXJBcnJheSk7CisJQ1BERl9Qb2ludAkJCQkJCUdldFdvcmRSaWdodEJvdHRvbVBvaW50KGNvbnN0IENQVlRfV29yZFBsYWNlJiB3cFdvcmQpOworCisJQ1BWVF9Xb3JkUmFuZ2UJCQkJCUNvbWJpbmVXb3JkUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UmIHdyMSwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UmIHdyMik7CisJQ1BWVF9Xb3JkUmFuZ2UJCQkJCUdldExhdGluV29yZHNSYW5nZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0OworCUNQVlRfV29yZFJhbmdlCQkJCQlHZXRMYXRpbldvcmRzUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7CisJQ1BWVF9Xb3JkUmFuZ2UJCQkJCUdldEFyYWJpY1dvcmRzUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3Q7CisJQ1BWVF9Xb3JkUmFuZ2UJCQkJCUdldFNhbWVXb3Jkc1JhbmdlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UsIEZYX0JPT0wgYkxhdGluLCBGWF9CT09MIGJBcmFiaWMpIGNvbnN0OworCisJdm9pZAkJCQkJCQlBanVzdEFyYWJpY1dvcmRzKGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cik7CitwdWJsaWM6CisJRlhfQk9PTAkJCQkJCQlJc1Byb2NlZWR0b09uQ2hhcihGWF9XT1JEIG5LZXlDb2RlLCBGWF9EV09SRCBuRmxhZyk7Citwcml2YXRlOgorCUlQV0xfRmlsbGVyX05vdGlmeSoJCQkJbV9wRmlsbGVyTm90aWZ5OworCUlQV0xfU3BlbGxDaGVjayoJCQkJbV9wU3BlbGxDaGVjazsKKwlGWF9CT09MCQkJCQkJCW1fYkZvY3VzOworCUNQREZfUmVjdAkJCQkJCW1fcmNPbGRXaW5kb3c7CitwdWJsaWM6CisJdm9pZAkJCQkJCQlBdHRhY2hGRkxEYXRhKHZvaWQqIHBEYXRhKSB7bV9wRm9ybUZpbGxlciA9IHBEYXRhO30KK3ByaXZhdGU6CisJdm9pZCoJCQkJCQkJbV9wRm9ybUZpbGxlcjsKK307CisKKyNlbmRpZiAKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmgKaW5kZXggM2RmMGY0Yy4uYjEzZDVlMSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9FZGl0Q3RybC5oCkBAIC0xLDE3MSArMSwxNzEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1BXTF9FRElUQ1RSTF9IXw0KLSNkZWZpbmUgX1BXTF9FRElUQ1RSTF9IXw0KLQ0KLWVudW0gUFdMX0VESVRfQUxJR05GT1JNQVRfSA0KLXsNCi0JUEVBSF9MRUZUID0gMCwNCi0JUEVBSF9NSURETEUsDQotCVBFQUhfUklHSFQNCi19Ow0KLQ0KLWVudW0gUFdMX0VESVRfQUxJR05GT1JNQVRfVg0KLXsNCi0JUEVBVl9UT1AgPSAwLAkNCi0JUEVBVl9DRU5URVIsDQotCVBFQVZfQk9UVE9NDQotfTsNCi0NCi1jbGFzcyBJUFdMX0VkaXRfTm90aWZ5Ow0KLWNsYXNzIENQV0xfRWRpdEN0cmw7DQotY2xhc3MgQ1BXTF9DYXJldDsNCi1jbGFzcyBJRlhfRWRpdDsNCi1jbGFzcyBDUFdMX0VkaXQ7DQotDQotY2xhc3MgSVBXTF9FZGl0X05vdGlmeQ0KLXsNCi1wdWJsaWM6DQotCS8vd2hlbiB0aGUgcG9zaXRpb24gb2YgY2FyZXQgaXMgY2hhbmdlZCBpbiBlZGl0DQotCXZpcnR1YWwgdm9pZAkJCQkJT25DYXJldE1vdmUoRlhfSU5UMzIgeDEsIEZYX0lOVDMyIHkxLCBGWF9JTlQzMiB4MiwgRlhfSU5UMzIgeTIpIHt9DQotCXZpcnR1YWwgdm9pZAkJCQkJT25Db250ZW50Q2hhbmdlKGNvbnN0IENQREZfUmVjdCYgcmNDb250ZW50KXt9DQotCS8vT3ByVHlwZTogMCBJbnNlcnRXb3JkDQotCS8vMSBJbnNlcnRSZXR1cm4NCi0JLy8yIEJhY2tTcGFjZQ0KLQkvLzMgRGVsZXRlDQotCS8vNCBDbGVhcg0KLQkvLzUgSW5zZXJ0VGV4dA0KLQkvLzYgU2V0VGV4dA0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uSW5zZXJ0V29yZChjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSl7fQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uSW5zZXJ0UmV0dXJuKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKXt9DQotCXZpcnR1YWwgdm9pZAkJCQkJT25CYWNrU3BhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2Upe30NCi0JdmlydHVhbCB2b2lkCQkJCQlPbkRlbGV0ZShjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSl7fQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uQ2xlYXIoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2Upe30NCi0JdmlydHVhbCB2b2lkCQkJCQlPbkluc2VydFRleHQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2Upe30NCi0JdmlydHVhbCB2b2lkCQkJCQlPblNldFRleHQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2Upe30NCi0JdmlydHVhbCB2b2lkCQkJCQlPbkFkZFVuZG8oQ1BXTF9FZGl0KiBwRWRpdCkge30NCi19Ow0KLQ0KLWNsYXNzIFBXTF9DTEFTUyBDUFdMX0VkaXRDdHJsIDogcHVibGljIENQV0xfV25kLCBwdWJsaWMgSUZYX0VkaXRfTm90aWZ5DQotew0KLQlmcmllbmQgY2xhc3MgQ1BXTF9FZGl0X05vdGlmeTsNCi0NCi1wdWJsaWM6DQotCUNQV0xfRWRpdEN0cmwoKTsNCi0JdmlydHVhbCB+Q1BXTF9FZGl0Q3RybCgpOw0KLQ0KLXB1YmxpYzoNCi0JdmlydHVhbCB2b2lkCQkJCQlPbkNyZWF0ZShQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25DcmVhdGVkKCk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25LZXlEb3duKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbkNoYXIoRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOwkNCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlSZVBvc0NoaWxkV25kKCk7CQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSk7DQotCXZpcnR1YWwgRlhfRkxPQVQJCQkJR2V0Rm9udFNpemUoKSBjb25zdDsNCi0JDQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldFRleHQoRlhfTFBDV1NUUiBjc1RleHQpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCUNvcHlUZXh0KCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJUGFzdGVUZXh0KCk7DQotCXZpcnR1YWwgdm9pZCAJCQkJCUN1dFRleHQoKTsNCi0NCi0JQ1BERl9SZWN0CQkJCQkJR2V0Q29udGVudFJlY3QoKSBjb25zdDsNCi0Jdm9pZAkJCQkJCQlHZXRDYXJldFBvcyhGWF9JTlQzMiYgeCwgRlhfSU5UMzImIHkpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUlzTW9kaWZpZWQoKSBjb25zdDsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFRleHQoKSBjb25zdDsNCi0Jdm9pZAkJCQkJCQlTZXRTZWwoRlhfSU5UMzIgblN0YXJ0Q2hhcixGWF9JTlQzMiBuRW5kQ2hhcik7DQotCXZvaWQJCQkJCQkJR2V0U2VsKEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhciApIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCUdldFRleHRSYW5nZShjb25zdCBDUERGX1JlY3QmIHJlY3QsIEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhcikgY29uc3Q7DQotCUNGWF9XaWRlU3RyaW5nCQkJCQlHZXRUZXh0KEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhcikgY29uc3Q7DQotCXZvaWQJCQkJCQkJQ2xlYXIoKTsNCi0Jdm9pZAkJCQkJCQlTZWxlY3RBbGwoKTsNCi0NCi0JRlhfSU5UMzIJCQkJCQlHZXRDYXJldCgpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCVNldENhcmV0KEZYX0lOVDMyIG5Qb3MpOw0KLQlGWF9JTlQzMgkJCQkJCUdldFRvdGFsV29yZHMoKSBjb25zdDsNCi0NCi0Jdm9pZAkJCQkJCQlQYWludCgpOw0KLQ0KLQl2b2lkCQkJCQkJCUVuYWJsZVJlZnJlc2goRlhfQk9PTCBiUmVmcmVzaCk7CQ0KLQlDUERGX1BvaW50CQkJCQkJR2V0U2Nyb2xsUG9zKCkgY29uc3Q7DQotCXZvaWQJCQkJCQkJU2V0U2Nyb2xsUG9zKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsNCi0NCi0Jdm9pZAkJCQkJCQlTZXRFZGl0Tm90aWZ5KElQV0xfRWRpdF9Ob3RpZnkqIHBOb3RpZnkpIHttX3BFZGl0Tm90aWZ5ID0gcE5vdGlmeTt9CQ0KLQ0KLQl2b2lkCQkJCQkJCVNldENoYXJTZXQoRlhfQllURSBuQ2hhclNldCl7bV9uQ2hhclNldCA9IG5DaGFyU2V0O30NCi0JRlhfSU5UMzIJCQkJCQlHZXRDaGFyU2V0KCkgY29uc3Q7DQotDQotCXZvaWQJCQkJCQkJU2V0Q29kZVBhZ2UoRlhfSU5UMzIgbkNvZGVQYWdlKXttX25Db2RlUGFnZSA9IG5Db2RlUGFnZTt9DQotCUZYX0lOVDMyCQkJCQkJR2V0Q29kZVBhZ2UoKSBjb25zdCB7cmV0dXJuIG1fbkNvZGVQYWdlO30NCi0NCi0JQ1BERl9Gb250ICoJCQkJCQlHZXRDYXJldEZvbnQoKSBjb25zdDsNCi0JRlhfRkxPQVQJCQkJCQlHZXRDYXJldEZvbnRTaXplKCkgY29uc3Q7DQotDQotCUZYX0JPT0wJCQkJCQkJQ2FuVW5kbygpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUNhblJlZG8oKSBjb25zdDsNCi0Jdm9pZAkJCQkJCQlSZWRvKCk7DQotCXZvaWQJCQkJCQkJVW5kbygpOw0KLQ0KLQl2b2lkCQkJCQkJCVNldFJlYWR5VG9JbnB1dCgpOw0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCB2b2lkCQkJCQlTaG93VlNjcm9sbEJhcihGWF9CT09MIGJTaG93KTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQlJbnNlcnRXb3JkKEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgbkNoYXJzZXQpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUluc2VydFJldHVybigpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUluc2VydFRleHQoRlhfTFBDV1NUUiBjc1RleHQpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldEN1cnNvcigpOw0KLQlGWF9CT09MCQkJCQkJCUlzV25kSG9yVigpOw0KLQ0KLQl2b2lkCQkJCQkJCURlbGV0ZSgpOw0KLQl2b2lkCQkJCQkJCUJhY2tzcGFjZSgpOw0KLQ0KLXByb3RlY3RlZDoNCi0Jdm9pZAkJCQkJCQlHZXRDYXJldEluZm8oQ1BERl9Qb2ludCAmIHB0SGVhZCwgQ1BERl9Qb2ludCAmIHB0Rm9vdCkgY29uc3Q7DQotCXZvaWQJCQkJCQkJU2V0Q2FyZXQoRlhfQk9PTCBiVmlzaWJsZSwgY29uc3QgQ1BERl9Qb2ludCAmIHB0SGVhZCwgY29uc3QgQ1BERl9Qb2ludCAmIHB0Rm9vdCk7DQotCQ0KLQl2b2lkCQkJCQkJCVNldEVkaXRDYXJldChGWF9CT09MIGJWaXNpYmxlKTsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZpcnR1YWwgdm9pZAkJCQkJSU9uU2V0U2Nyb2xsSW5mb1goRlhfRkxPQVQgZlBsYXRlTWluLCBGWF9GTE9BVCBmUGxhdGVNYXgsIA0KLQkJCQkJCQkJCQkJCUZYX0ZMT0FUIGZDb250ZW50TWluLCBGWF9GTE9BVCBmQ29udGVudE1heCwgDQotCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApe30NCi0JdmlydHVhbCB2b2lkCQkJCQlJT25TZXRTY3JvbGxJbmZvWShGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgDQotCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkNvbnRlbnRNaW4sIEZYX0ZMT0FUIGZDb250ZW50TWF4LCANCi0JCQkJCQkJCQkJCQlGWF9GTE9BVCBmU21hbGxTdGVwLCBGWF9GTE9BVCBmQmlnU3RlcCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJSU9uU2V0U2Nyb2xsUG9zWChGWF9GTE9BVCBmeCl7fQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCUlPblNldFNjcm9sbFBvc1koRlhfRkxPQVQgZnkpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUlPblNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsY29uc3QgQ1BERl9Qb2ludCAmIHB0SGVhZCxjb25zdCBDUERGX1BvaW50ICYgcHRGb290LCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUlPbkNhcmV0Q2hhbmdlKGNvbnN0IENQVlRfU2VjUHJvcHMgJiBzZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiB3b3JkUHJvcHMpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUlPbkNvbnRlbnRDaGFuZ2UoY29uc3QgQ1BERl9SZWN0JiByY0NvbnRlbnQpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUlPbkludmFsaWRhdGVSZWN0KENQREZfUmVjdCAqIHBSZWN0KTsNCi0NCi1wcml2YXRlOg0KLQl2b2lkCQkJCQkJCUNyZWF0ZUVkaXRDYXJldChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotDQotcHJvdGVjdGVkOg0KLQlJRlhfRWRpdCoJCQkJCQltX3BFZGl0Ow0KLQlDUFdMX0NhcmV0KgkJCQkJCW1fcEVkaXRDYXJldDsNCi0JRlhfQk9PTAkJCQkJCQltX2JNb3VzZURvd247DQotCUlQV0xfRWRpdF9Ob3RpZnkqCQkJCW1fcEVkaXROb3RpZnk7CQ0KLQ0KLXByaXZhdGU6DQotCUZYX0lOVDMyCQkJCQkJbV9uQ2hhclNldDsNCi0JRlhfSU5UMzIJCQkJCQltX25Db2RlUGFnZTsNCi19Ow0KLQ0KLSNlbmRpZg0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1BXTF9FRElUQ1RSTF9IXworI2RlZmluZSBfUFdMX0VESVRDVFJMX0hfCisKK2VudW0gUFdMX0VESVRfQUxJR05GT1JNQVRfSAoreworCVBFQUhfTEVGVCA9IDAsCisJUEVBSF9NSURETEUsCisJUEVBSF9SSUdIVAorfTsKKworZW51bSBQV0xfRURJVF9BTElHTkZPUk1BVF9WCit7CisJUEVBVl9UT1AgPSAwLAkKKwlQRUFWX0NFTlRFUiwKKwlQRUFWX0JPVFRPTQorfTsKKworY2xhc3MgSVBXTF9FZGl0X05vdGlmeTsKK2NsYXNzIENQV0xfRWRpdEN0cmw7CitjbGFzcyBDUFdMX0NhcmV0OworY2xhc3MgSUZYX0VkaXQ7CitjbGFzcyBDUFdMX0VkaXQ7CisKK2NsYXNzIElQV0xfRWRpdF9Ob3RpZnkKK3sKK3B1YmxpYzoKKwkvL3doZW4gdGhlIHBvc2l0aW9uIG9mIGNhcmV0IGlzIGNoYW5nZWQgaW4gZWRpdAorCXZpcnR1YWwgdm9pZAkJCQkJT25DYXJldE1vdmUoRlhfSU5UMzIgeDEsIEZYX0lOVDMyIHkxLCBGWF9JTlQzMiB4MiwgRlhfSU5UMzIgeTIpIHt9CisJdmlydHVhbCB2b2lkCQkJCQlPbkNvbnRlbnRDaGFuZ2UoY29uc3QgQ1BERl9SZWN0JiByY0NvbnRlbnQpe30KKwkvL09wclR5cGU6IDAgSW5zZXJ0V29yZAorCS8vMSBJbnNlcnRSZXR1cm4KKwkvLzIgQmFja1NwYWNlCisJLy8zIERlbGV0ZQorCS8vNCBDbGVhcgorCS8vNSBJbnNlcnRUZXh0CisJLy82IFNldFRleHQKKwl2aXJ0dWFsIHZvaWQJCQkJCU9uSW5zZXJ0V29yZChjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSl7fQorCXZpcnR1YWwgdm9pZAkJCQkJT25JbnNlcnRSZXR1cm4oY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2Upe30KKwl2aXJ0dWFsIHZvaWQJCQkJCU9uQmFja1NwYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKXt9CisJdmlydHVhbCB2b2lkCQkJCQlPbkRlbGV0ZShjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSl7fQorCXZpcnR1YWwgdm9pZAkJCQkJT25DbGVhcihjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSl7fQorCXZpcnR1YWwgdm9pZAkJCQkJT25JbnNlcnRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKXt9CisJdmlydHVhbCB2b2lkCQkJCQlPblNldFRleHQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2Upe30KKwl2aXJ0dWFsIHZvaWQJCQkJCU9uQWRkVW5kbyhDUFdMX0VkaXQqIHBFZGl0KSB7fQorfTsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfRWRpdEN0cmwgOiBwdWJsaWMgQ1BXTF9XbmQsIHB1YmxpYyBJRlhfRWRpdF9Ob3RpZnkKK3sKKwlmcmllbmQgY2xhc3MgQ1BXTF9FZGl0X05vdGlmeTsKKworcHVibGljOgorCUNQV0xfRWRpdEN0cmwoKTsKKwl2aXJ0dWFsIH5DUFdMX0VkaXRDdHJsKCk7CisKK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQkJCU9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCU9uQ3JlYXRlZCgpOworCisJdmlydHVhbCBGWF9CT09MCQkJCQlPbktleURvd24oRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CQorCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CQorCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCB2b2lkCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOworCisJdmlydHVhbCB2b2lkCQkJCQlDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7CisJdmlydHVhbCB2b2lkCQkJCQlSZVBvc0NoaWxkV25kKCk7CQorCXZpcnR1YWwgdm9pZAkJCQkJU2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKTsKKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJCUdldEZvbnRTaXplKCkgY29uc3Q7CisJCitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KTsKKworCXZpcnR1YWwgdm9pZAkJCQkJQ29weVRleHQoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCVBhc3RlVGV4dCgpOworCXZpcnR1YWwgdm9pZCAJCQkJCUN1dFRleHQoKTsKKworCUNQREZfUmVjdAkJCQkJCUdldENvbnRlbnRSZWN0KCkgY29uc3Q7CisJdm9pZAkJCQkJCQlHZXRDYXJldFBvcyhGWF9JTlQzMiYgeCwgRlhfSU5UMzImIHkpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJSXNNb2RpZmllZCgpIGNvbnN0OworCisJQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFRleHQoKSBjb25zdDsKKwl2b2lkCQkJCQkJCVNldFNlbChGWF9JTlQzMiBuU3RhcnRDaGFyLEZYX0lOVDMyIG5FbmRDaGFyKTsKKwl2b2lkCQkJCQkJCUdldFNlbChGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIgKSBjb25zdDsKKwl2b2lkCQkJCQkJCUdldFRleHRSYW5nZShjb25zdCBDUERGX1JlY3QmIHJlY3QsIEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhcikgY29uc3Q7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFRleHQoRlhfSU5UMzIgJiBuU3RhcnRDaGFyLCBGWF9JTlQzMiAmIG5FbmRDaGFyKSBjb25zdDsKKwl2b2lkCQkJCQkJCUNsZWFyKCk7CisJdm9pZAkJCQkJCQlTZWxlY3RBbGwoKTsKKworCUZYX0lOVDMyCQkJCQkJR2V0Q2FyZXQoKSBjb25zdDsKKwl2b2lkCQkJCQkJCVNldENhcmV0KEZYX0lOVDMyIG5Qb3MpOworCUZYX0lOVDMyCQkJCQkJR2V0VG90YWxXb3JkcygpIGNvbnN0OworCisJdm9pZAkJCQkJCQlQYWludCgpOworCisJdm9pZAkJCQkJCQlFbmFibGVSZWZyZXNoKEZYX0JPT0wgYlJlZnJlc2gpOwkKKwlDUERGX1BvaW50CQkJCQkJR2V0U2Nyb2xsUG9zKCkgY29uc3Q7CisJdm9pZAkJCQkJCQlTZXRTY3JvbGxQb3MoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCisJdm9pZAkJCQkJCQlTZXRFZGl0Tm90aWZ5KElQV0xfRWRpdF9Ob3RpZnkqIHBOb3RpZnkpIHttX3BFZGl0Tm90aWZ5ID0gcE5vdGlmeTt9CQorCisJdm9pZAkJCQkJCQlTZXRDaGFyU2V0KEZYX0JZVEUgbkNoYXJTZXQpe21fbkNoYXJTZXQgPSBuQ2hhclNldDt9CisJRlhfSU5UMzIJCQkJCQlHZXRDaGFyU2V0KCkgY29uc3Q7CisKKwl2b2lkCQkJCQkJCVNldENvZGVQYWdlKEZYX0lOVDMyIG5Db2RlUGFnZSl7bV9uQ29kZVBhZ2UgPSBuQ29kZVBhZ2U7fQorCUZYX0lOVDMyCQkJCQkJR2V0Q29kZVBhZ2UoKSBjb25zdCB7cmV0dXJuIG1fbkNvZGVQYWdlO30KKworCUNQREZfRm9udCAqCQkJCQkJR2V0Q2FyZXRGb250KCkgY29uc3Q7CisJRlhfRkxPQVQJCQkJCQlHZXRDYXJldEZvbnRTaXplKCkgY29uc3Q7CisKKwlGWF9CT09MCQkJCQkJCUNhblVuZG8oKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCUNhblJlZG8oKSBjb25zdDsKKwl2b2lkCQkJCQkJCVJlZG8oKTsKKwl2b2lkCQkJCQkJCVVuZG8oKTsKKworCXZvaWQJCQkJCQkJU2V0UmVhZHlUb0lucHV0KCk7Citwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQlTaG93VlNjcm9sbEJhcihGWF9CT09MIGJTaG93KTsKKworCXZpcnR1YWwgdm9pZAkJCQkJSW5zZXJ0V29yZChGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIG5DaGFyc2V0KTsKKwl2aXJ0dWFsIHZvaWQJCQkJCUluc2VydFJldHVybigpOworCXZpcnR1YWwgdm9pZAkJCQkJSW5zZXJ0VGV4dChGWF9MUENXU1RSIGNzVGV4dCk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJCVNldEN1cnNvcigpOworCUZYX0JPT0wJCQkJCQkJSXNXbmRIb3JWKCk7CisKKwl2b2lkCQkJCQkJCURlbGV0ZSgpOworCXZvaWQJCQkJCQkJQmFja3NwYWNlKCk7CisKK3Byb3RlY3RlZDoKKwl2b2lkCQkJCQkJCUdldENhcmV0SW5mbyhDUERGX1BvaW50ICYgcHRIZWFkLCBDUERGX1BvaW50ICYgcHRGb290KSBjb25zdDsKKwl2b2lkCQkJCQkJCVNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsIGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsIGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QpOworCQorCXZvaWQJCQkJCQkJU2V0RWRpdENhcmV0KEZYX0JPT0wgYlZpc2libGUpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQlJT25TZXRTY3JvbGxJbmZvWChGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIAorCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApe30KKwl2aXJ0dWFsIHZvaWQJCQkJCUlPblNldFNjcm9sbEluZm9ZKEZYX0ZMT0FUIGZQbGF0ZU1pbiwgRlhfRkxPQVQgZlBsYXRlTWF4LCAKKwkJCQkJCQkJCQkJCUZYX0ZMT0FUIGZDb250ZW50TWluLCBGWF9GTE9BVCBmQ29udGVudE1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmU21hbGxTdGVwLCBGWF9GTE9BVCBmQmlnU3RlcCk7CisJdmlydHVhbCB2b2lkCQkJCQlJT25TZXRTY3JvbGxQb3NYKEZYX0ZMT0FUIGZ4KXt9CisJdmlydHVhbCB2b2lkCQkJCQlJT25TZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KTsKKwl2aXJ0dWFsIHZvaWQJCQkJCUlPblNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsY29uc3QgQ1BERl9Qb2ludCAmIHB0SGVhZCxjb25zdCBDUERGX1BvaW50ICYgcHRGb290LCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UpOworCXZpcnR1YWwgdm9pZAkJCQkJSU9uQ2FyZXRDaGFuZ2UoY29uc3QgQ1BWVF9TZWNQcm9wcyAmIHNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIHdvcmRQcm9wcyk7CisJdmlydHVhbCB2b2lkCQkJCQlJT25Db250ZW50Q2hhbmdlKGNvbnN0IENQREZfUmVjdCYgcmNDb250ZW50KTsKKwl2aXJ0dWFsIHZvaWQJCQkJCUlPbkludmFsaWRhdGVSZWN0KENQREZfUmVjdCAqIHBSZWN0KTsKKworcHJpdmF0ZToKKwl2b2lkCQkJCQkJCUNyZWF0ZUVkaXRDYXJldChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7CisKK3Byb3RlY3RlZDoKKwlJRlhfRWRpdCoJCQkJCQltX3BFZGl0OworCUNQV0xfQ2FyZXQqCQkJCQkJbV9wRWRpdENhcmV0OworCUZYX0JPT0wJCQkJCQkJbV9iTW91c2VEb3duOworCUlQV0xfRWRpdF9Ob3RpZnkqCQkJCW1fcEVkaXROb3RpZnk7CQorCitwcml2YXRlOgorCUZYX0lOVDMyCQkJCQkJbV9uQ2hhclNldDsKKwlGWF9JTlQzMgkJCQkJCW1fbkNvZGVQYWdlOworfTsKKworI2VuZGlmCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0ZvbnRNYXAuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0ZvbnRNYXAuaAppbmRleCA4NThiYjJhLi5iM2RhNTMzIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Gb250TWFwLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRm9udE1hcC5oCkBAIC0xLDEzNyArMSwxMzcgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1BXTF9GT05UTUFQX0hfDQotI2RlZmluZSBfUFdMX0ZPTlRNQVBfSF8NCi0NCi1zdHJ1Y3QgQ1BXTF9Gb250TWFwX0RhdGENCi17DQotCUNQREZfRm9udCoJCQlwRm9udDsNCi0JRlhfSU5UMzIJCQluQ2hhcnNldDsNCi0JQ0ZYX0J5dGVTdHJpbmcJCXNGb250TmFtZTsNCi19Ow0KLQ0KLXN0cnVjdCBDUFdMX0ZvbnRNYXBfTmF0aXZlDQotew0KLQlGWF9JTlQzMgkJCW5DaGFyc2V0Ow0KLQlDRlhfQnl0ZVN0cmluZwkJc0ZvbnROYW1lOw0KLX07DQotDQotI2lmbmRlZiBBTlNJX0NIQVJTRVQNCi0NCi0jZGVmaW5lIEFOU0lfQ0hBUlNFVCAgICAgICAgICAgIDANCi0jZGVmaW5lIERFRkFVTFRfQ0hBUlNFVCAgICAgICAgIDENCi0jZGVmaW5lIFNZTUJPTF9DSEFSU0VUICAgICAgICAgIDINCi0jZGVmaW5lIFNISUZUSklTX0NIQVJTRVQgICAgICAgIDEyOA0KLSNkZWZpbmUgSEFOR0VVTF9DSEFSU0VUICAgICAgICAgMTI5DQotI2RlZmluZSBIQU5HVUxfQ0hBUlNFVCAgICAgICAgICAxMjkNCi0jZGVmaW5lIEdCMjMxMl9DSEFSU0VUICAgICAgICAgIDEzNA0KLSNkZWZpbmUgQ0hJTkVTRUJJRzVfQ0hBUlNFVCAgICAgMTM2DQotI2RlZmluZSBPRU1fQ0hBUlNFVCAgICAgICAgICAgICAyNTUNCi0jZGVmaW5lIEpPSEFCX0NIQVJTRVQgICAgICAgICAgIDEzMA0KLSNkZWZpbmUgSEVCUkVXX0NIQVJTRVQgICAgICAgICAgMTc3DQotI2RlZmluZSBBUkFCSUNfQ0hBUlNFVCAgICAgICAgICAxNzgNCi0jZGVmaW5lIEdSRUVLX0NIQVJTRVQgICAgICAgICAgIDE2MQ0KLSNkZWZpbmUgVFVSS0lTSF9DSEFSU0VUICAgICAgICAgMTYyDQotI2RlZmluZSBWSUVUTkFNRVNFX0NIQVJTRVQgICAgICAxNjMNCi0jZGVmaW5lIFRIQUlfQ0hBUlNFVCAgICAgICAgICAgIDIyMg0KLSNkZWZpbmUgRUFTVEVVUk9QRV9DSEFSU0VUICAgICAgMjM4DQotI2RlZmluZSBSVVNTSUFOX0NIQVJTRVQgICAgICAgICAyMDQNCi0jZGVmaW5lIEJBTFRJQ19DSEFSU0VUICAgICAgICAgIDE4Ng0KLQ0KLSNlbmRpZg0KLQ0KLSNpZm5kZWYgUFdMX0NMQVNTDQotDQotCSNpZmRlZiBGWF9SRUFERVJfRExMDQotCQkjZGVmaW5lIFBXTF9DTEFTUwkJX19kZWNsc3BlYyhkbGxleHBvcnQpDQotCSNlbHNlDQotCQkjZGVmaW5lIFBXTF9DTEFTUw0KLQkjZW5kaWYNCi0jZW5kaWYNCi0NCi1jbGFzcyBJRlhfU3lzdGVtSGFuZGxlcjsNCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9Gb250TWFwIDogcHVibGljIElGWF9FZGl0X0ZvbnRNYXANCi17DQotcHVibGljOg0KLQlDUFdMX0ZvbnRNYXAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyKTsNCi0JdmlydHVhbCB+Q1BXTF9Gb250TWFwKCk7DQotDQotCXZpcnR1YWwgQ1BERl9Gb250KgkJCQkJCQlHZXRQREZGb250KEZYX0lOVDMyIG5Gb250SW5kZXgpOw0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJCQkJR2V0UERGRm9udEFsaWFzKEZYX0lOVDMyIG5Gb250SW5kZXgpOw0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJCUdldFdvcmRGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuQ2hhcnNldCwgRlhfSU5UMzIgbkZvbnRJbmRleCk7DQotCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQkJQ2hhckNvZGVGcm9tVW5pY29kZShGWF9JTlQzMiBuRm9udEluZGV4LCBGWF9XT1JEIHdvcmQpOw0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJCUNoYXJTZXRGcm9tVW5pY29kZShGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIG5PbGRDaGFyc2V0KTsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQkJCQkJSW5pdGlhbChGWF9MUENTVFIgZm9udG5hbWUgPSBOVUxMKTsNCi0Jdm9pZAkJCQkJCQkJCQlTZXRTeXN0ZW1IYW5kbGVyKElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlcik7DQotDQotCUZYX0lOVDMyCQkJCQkJCQkJR2V0Rm9udE1hcENvdW50KCkgY29uc3Q7DQotCWNvbnN0IENQV0xfRm9udE1hcF9EYXRhKgkJCQkJR2V0Rm9udE1hcERhdGEoRlhfSU5UMzIgbkluZGV4KSBjb25zdDsNCi0NCi1wdWJsaWM6DQotCXN0YXRpYyBGWF9JTlQzMgkJCQkJCQkJR2V0TmF0aXZlQ2hhcnNldCgpOw0KLQlDRlhfQnl0ZVN0cmluZwkJCQkJCQkJR2V0TmF0aXZlRm9udE5hbWUoRlhfSU5UMzIgbkNoYXJzZXQpOw0KLQ0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCQlHZXREZWZhdWx0Rm9udEJ5Q2hhcnNldChGWF9JTlQzMiBuQ2hhcnNldCk7DQotDQotCUNQREZfRm9udCoJCQkJCQkJCQlBZGRGb250VG9Eb2N1bWVudChDUERGX0RvY3VtZW50KiBwRG9jLCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lLCBGWF9CWVRFIG5DaGFyc2V0KTsNCi0Jc3RhdGljIEZYX0JPT0wJCQkJCQkJCUlzU3RhbmRhcmRGb250KGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUpOwkJCQkJCQkNCi0JQ1BERl9Gb250KgkJCQkJCQkJCUFkZFN0YW5kYXJkRm9udChDUERGX0RvY3VtZW50KiBwRG9jLCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lKTsNCi0JQ1BERl9Gb250KgkJCQkJCQkJCUFkZFN5c3RlbUZvbnQoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSwgDQotCQkJCQkJCQkJCQkJCUZYX0JZVEUgbkNoYXJzZXQpOw0KLQ0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCBDUERGX0ZvbnQqCQkJCQkJCUZpbmRGb250U2FtZUNoYXJzZXQoQ0ZYX0J5dGVTdHJpbmcmIHNGb250QWxpYXMsIEZYX0lOVDMyIG5DaGFyc2V0KTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCQlBZGRlZEZvbnQoQ1BERl9Gb250KiBwRm9udCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250QWxpYXMpOw0KLQlGWF9CT09MCQkJCQkJCQkJCUtub3dXb3JkKEZYX0lOVDMyIG5Gb250SW5kZXgsIEZYX1dPUkQgd29yZCk7DQotDQotCXZpcnR1YWwgQ1BERl9Eb2N1bWVudCoJCQkJCQlHZXREb2N1bWVudCgpOw0KLQ0KLQl2b2lkCQkJCQkJCQkJCUVtcHR5KCk7DQotCUZYX0lOVDMyCQkJCQkJCQkJR2V0Rm9udEluZGV4KGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUsIEZYX0lOVDMyIG5DaGFyc2V0LCBGWF9CT09MIGJGaW5kKTsNCi0JRlhfSU5UMzIJCQkJCQkJCQlHZXRQV0xGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuQ2hhcnNldCk7DQotCUZYX0lOVDMyCQkJCQkJCQkJQWRkRm9udERhdGEoQ1BERl9Gb250KiBwRm9udCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250QWxpYXMsIEZYX0lOVDMyIG5DaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VUKTsNCi0NCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCQkJCUVuY29kZUZvbnRBbGlhcyhjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lLCBGWF9JTlQzMiBuQ2hhcnNldCk7DQotCUNGWF9CeXRlU3RyaW5nCQkJCQkJCQlFbmNvZGVGb250QWxpYXMoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSk7DQotDQotcHJpdmF0ZToNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCQkJCUdldEZvbnROYW1lKEZYX0lOVDMyIG5Gb250SW5kZXgpOw0KLQlGWF9JTlQzMgkJCQkJCQkJCUZpbmRGb250KGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUsIEZYX0lOVDMyIG5DaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VUKTsNCi0NCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCQkJCUdldE5hdGl2ZUZvbnQoRlhfSU5UMzIgbkNoYXJzZXQpOw0KLQ0KLXB1YmxpYzoNCi0Jc3RydWN0IENoYXJzZXRGb250TWFwIHsNCi0JCUZYX0lOVDMyCQkJCQkJCQljaGFyc2V0Ow0KLQkJY29uc3QgY2hhcioJCQkJCQkJCWZvbnRuYW1lOw0KLQl9Ow0KLQlzdGF0aWMgY29uc3QgQ2hhcnNldEZvbnRNYXAJCQkJCWRlZmF1bHRUVEZNYXBbXTsNCi0NCi1wcm90ZWN0ZWQ6DQotCUNGWF9BcnJheVRlbXBsYXRlPENQV0xfRm9udE1hcF9EYXRhKj4JCW1fYURhdGE7DQotCUNGWF9BcnJheVRlbXBsYXRlPENQV0xfRm9udE1hcF9OYXRpdmUqPgkJbV9hTmF0aXZlRm9udDsNCi0NCi1wcml2YXRlOg0KLQlDUERGX0RvY3VtZW50KgkJCQkJCQkJbV9wUERGRG9jOw0KLQlJRlhfU3lzdGVtSGFuZGxlcioJCQkJCQkJbV9wU3lzdGVtSGFuZGxlcjsNCi19Ow0KLQ0KLWNsYXNzIFBXTF9DTEFTUyBDUFdMX0RvY0ZvbnRNYXAgOiBwdWJsaWMgQ1BXTF9Gb250TWFwDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9Eb2NGb250TWFwKElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlciwgQ1BERl9Eb2N1bWVudCogcEF0dGFjaGVkRG9jKTsNCi0JdmlydHVhbCB+Q1BXTF9Eb2NGb250TWFwKCk7DQotDQotCXZpcnR1YWwgQ1BERl9Eb2N1bWVudCoJCQkJCQlHZXREb2N1bWVudCgpOw0KLQ0KLXByaXZhdGU6DQotCUNQREZfRG9jdW1lbnQqCQkJCQkJCQltX3BBdHRhY2hlZERvYzsNCi19Ow0KLQ0KLSNlbmRpZg0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1BXTF9GT05UTUFQX0hfCisjZGVmaW5lIF9QV0xfRk9OVE1BUF9IXworCitzdHJ1Y3QgQ1BXTF9Gb250TWFwX0RhdGEKK3sKKwlDUERGX0ZvbnQqCQkJcEZvbnQ7CisJRlhfSU5UMzIJCQluQ2hhcnNldDsKKwlDRlhfQnl0ZVN0cmluZwkJc0ZvbnROYW1lOworfTsKKworc3RydWN0IENQV0xfRm9udE1hcF9OYXRpdmUKK3sKKwlGWF9JTlQzMgkJCW5DaGFyc2V0OworCUNGWF9CeXRlU3RyaW5nCQlzRm9udE5hbWU7Cit9OworCisjaWZuZGVmIEFOU0lfQ0hBUlNFVAorCisjZGVmaW5lIEFOU0lfQ0hBUlNFVCAgICAgICAgICAgIDAKKyNkZWZpbmUgREVGQVVMVF9DSEFSU0VUICAgICAgICAgMQorI2RlZmluZSBTWU1CT0xfQ0hBUlNFVCAgICAgICAgICAyCisjZGVmaW5lIFNISUZUSklTX0NIQVJTRVQgICAgICAgIDEyOAorI2RlZmluZSBIQU5HRVVMX0NIQVJTRVQgICAgICAgICAxMjkKKyNkZWZpbmUgSEFOR1VMX0NIQVJTRVQgICAgICAgICAgMTI5CisjZGVmaW5lIEdCMjMxMl9DSEFSU0VUICAgICAgICAgIDEzNAorI2RlZmluZSBDSElORVNFQklHNV9DSEFSU0VUICAgICAxMzYKKyNkZWZpbmUgT0VNX0NIQVJTRVQgICAgICAgICAgICAgMjU1CisjZGVmaW5lIEpPSEFCX0NIQVJTRVQgICAgICAgICAgIDEzMAorI2RlZmluZSBIRUJSRVdfQ0hBUlNFVCAgICAgICAgICAxNzcKKyNkZWZpbmUgQVJBQklDX0NIQVJTRVQgICAgICAgICAgMTc4CisjZGVmaW5lIEdSRUVLX0NIQVJTRVQgICAgICAgICAgIDE2MQorI2RlZmluZSBUVVJLSVNIX0NIQVJTRVQgICAgICAgICAxNjIKKyNkZWZpbmUgVklFVE5BTUVTRV9DSEFSU0VUICAgICAgMTYzCisjZGVmaW5lIFRIQUlfQ0hBUlNFVCAgICAgICAgICAgIDIyMgorI2RlZmluZSBFQVNURVVST1BFX0NIQVJTRVQgICAgICAyMzgKKyNkZWZpbmUgUlVTU0lBTl9DSEFSU0VUICAgICAgICAgMjA0CisjZGVmaW5lIEJBTFRJQ19DSEFSU0VUICAgICAgICAgIDE4NgorCisjZW5kaWYKKworI2lmbmRlZiBQV0xfQ0xBU1MKKworCSNpZmRlZiBGWF9SRUFERVJfRExMCisJCSNkZWZpbmUgUFdMX0NMQVNTCQlfX2RlY2xzcGVjKGRsbGV4cG9ydCkKKwkjZWxzZQorCQkjZGVmaW5lIFBXTF9DTEFTUworCSNlbmRpZgorI2VuZGlmCisKK2NsYXNzIElGWF9TeXN0ZW1IYW5kbGVyOworY2xhc3MgUFdMX0NMQVNTIENQV0xfRm9udE1hcCA6IHB1YmxpYyBJRlhfRWRpdF9Gb250TWFwCit7CitwdWJsaWM6CisJQ1BXTF9Gb250TWFwKElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlcik7CisJdmlydHVhbCB+Q1BXTF9Gb250TWFwKCk7CisKKwl2aXJ0dWFsIENQREZfRm9udCoJCQkJCQkJR2V0UERGRm9udChGWF9JTlQzMiBuRm9udEluZGV4KTsKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJCQkJR2V0UERGRm9udEFsaWFzKEZYX0lOVDMyIG5Gb250SW5kZXgpOworCXZpcnR1YWwgRlhfSU5UMzIJCQkJCQkJR2V0V29yZEZvbnRJbmRleChGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIG5DaGFyc2V0LCBGWF9JTlQzMiBuRm9udEluZGV4KTsKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJCUNoYXJDb2RlRnJvbVVuaWNvZGUoRlhfSU5UMzIgbkZvbnRJbmRleCwgRlhfV09SRCB3b3JkKTsKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJCQkJCUNoYXJTZXRGcm9tVW5pY29kZShGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIG5PbGRDaGFyc2V0KTsKKworcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQkJCQkJSW5pdGlhbChGWF9MUENTVFIgZm9udG5hbWUgPSBOVUxMKTsKKwl2b2lkCQkJCQkJCQkJCVNldFN5c3RlbUhhbmRsZXIoSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyKTsKKworCUZYX0lOVDMyCQkJCQkJCQkJR2V0Rm9udE1hcENvdW50KCkgY29uc3Q7CisJY29uc3QgQ1BXTF9Gb250TWFwX0RhdGEqCQkJCQlHZXRGb250TWFwRGF0YShGWF9JTlQzMiBuSW5kZXgpIGNvbnN0OworCitwdWJsaWM6CisJc3RhdGljIEZYX0lOVDMyCQkJCQkJCQlHZXROYXRpdmVDaGFyc2V0KCk7CisJQ0ZYX0J5dGVTdHJpbmcJCQkJCQkJCUdldE5hdGl2ZUZvbnROYW1lKEZYX0lOVDMyIG5DaGFyc2V0KTsKKworCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJCUdldERlZmF1bHRGb250QnlDaGFyc2V0KEZYX0lOVDMyIG5DaGFyc2V0KTsKKworCUNQREZfRm9udCoJCQkJCQkJCQlBZGRGb250VG9Eb2N1bWVudChDUERGX0RvY3VtZW50KiBwRG9jLCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lLCBGWF9CWVRFIG5DaGFyc2V0KTsKKwlzdGF0aWMgRlhfQk9PTAkJCQkJCQkJSXNTdGFuZGFyZEZvbnQoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSk7CQkJCQkJCQorCUNQREZfRm9udCoJCQkJCQkJCQlBZGRTdGFuZGFyZEZvbnQoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSk7CisJQ1BERl9Gb250KgkJCQkJCQkJCUFkZFN5c3RlbUZvbnQoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSwgCisJCQkJCQkJCQkJCQkJRlhfQllURSBuQ2hhcnNldCk7CisKK3Byb3RlY3RlZDoKKwl2aXJ0dWFsIENQREZfRm9udCoJCQkJCQkJRmluZEZvbnRTYW1lQ2hhcnNldChDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcywgRlhfSU5UMzIgbkNoYXJzZXQpOworCXZpcnR1YWwgdm9pZAkJCQkJCQkJQWRkZWRGb250KENQREZfRm9udCogcEZvbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzKTsKKwlGWF9CT09MCQkJCQkJCQkJCUtub3dXb3JkKEZYX0lOVDMyIG5Gb250SW5kZXgsIEZYX1dPUkQgd29yZCk7CisKKwl2aXJ0dWFsIENQREZfRG9jdW1lbnQqCQkJCQkJR2V0RG9jdW1lbnQoKTsKKworCXZvaWQJCQkJCQkJCQkJRW1wdHkoKTsKKwlGWF9JTlQzMgkJCQkJCQkJCUdldEZvbnRJbmRleChjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lLCBGWF9JTlQzMiBuQ2hhcnNldCwgRlhfQk9PTCBiRmluZCk7CisJRlhfSU5UMzIJCQkJCQkJCQlHZXRQV0xGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuQ2hhcnNldCk7CisJRlhfSU5UMzIJCQkJCQkJCQlBZGRGb250RGF0YShDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcywgRlhfSU5UMzIgbkNoYXJzZXQgPSBERUZBVUxUX0NIQVJTRVQpOworCisJQ0ZYX0J5dGVTdHJpbmcJCQkJCQkJCUVuY29kZUZvbnRBbGlhcyhjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lLCBGWF9JTlQzMiBuQ2hhcnNldCk7CisJQ0ZYX0J5dGVTdHJpbmcJCQkJCQkJCUVuY29kZUZvbnRBbGlhcyhjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lKTsKKworcHJpdmF0ZToKKwlDRlhfQnl0ZVN0cmluZwkJCQkJCQkJR2V0Rm9udE5hbWUoRlhfSU5UMzIgbkZvbnRJbmRleCk7CisJRlhfSU5UMzIJCQkJCQkJCQlGaW5kRm9udChjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lLCBGWF9JTlQzMiBuQ2hhcnNldCA9IERFRkFVTFRfQ0hBUlNFVCk7CisKKwlDRlhfQnl0ZVN0cmluZwkJCQkJCQkJR2V0TmF0aXZlRm9udChGWF9JTlQzMiBuQ2hhcnNldCk7CisKK3B1YmxpYzoKKwlzdHJ1Y3QgQ2hhcnNldEZvbnRNYXAgeworCQlGWF9JTlQzMgkJCQkJCQkJY2hhcnNldDsKKwkJY29uc3QgY2hhcioJCQkJCQkJCWZvbnRuYW1lOworCX07CisJc3RhdGljIGNvbnN0IENoYXJzZXRGb250TWFwCQkJCQlkZWZhdWx0VFRGTWFwW107CisKK3Byb3RlY3RlZDoKKwlDRlhfQXJyYXlUZW1wbGF0ZTxDUFdMX0ZvbnRNYXBfRGF0YSo+CQltX2FEYXRhOworCUNGWF9BcnJheVRlbXBsYXRlPENQV0xfRm9udE1hcF9OYXRpdmUqPgkJbV9hTmF0aXZlRm9udDsKKworcHJpdmF0ZToKKwlDUERGX0RvY3VtZW50KgkJCQkJCQkJbV9wUERGRG9jOworCUlGWF9TeXN0ZW1IYW5kbGVyKgkJCQkJCQltX3BTeXN0ZW1IYW5kbGVyOworfTsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfRG9jRm9udE1hcCA6IHB1YmxpYyBDUFdMX0ZvbnRNYXAKK3sKK3B1YmxpYzoKKwlDUFdMX0RvY0ZvbnRNYXAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyLCBDUERGX0RvY3VtZW50KiBwQXR0YWNoZWREb2MpOworCXZpcnR1YWwgfkNQV0xfRG9jRm9udE1hcCgpOworCisJdmlydHVhbCBDUERGX0RvY3VtZW50KgkJCQkJCUdldERvY3VtZW50KCk7CisKK3ByaXZhdGU6CisJQ1BERl9Eb2N1bWVudCoJCQkJCQkJCW1fcEF0dGFjaGVkRG9jOworfTsKKworI2VuZGlmCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9JY29uLmggYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9JY29uLmgKaW5kZXggZDZiMTIxZS4uNGEwODRmZCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfSWNvbi5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0ljb24uaApAQCAtMSw1OSArMSw1OSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfUFdMX0lDT05fSF8NCi0jZGVmaW5lIF9QV0xfSUNPTl9IXw0KLQ0KLWNsYXNzIFBXTF9DTEFTUyBDUFdMX0ltYWdlIDogcHVibGljIENQV0xfV25kDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9JbWFnZSgpOw0KLQl2aXJ0dWFsIH5DUFdMX0ltYWdlKCk7DQotDQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCQlHZXRJbWFnZUFwcFN0cmVhbSgpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCUdldFNjYWxlKEZYX0ZMT0FUICYgZkhTY2FsZSxGWF9GTE9BVCAmIGZWU2NhbGUpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUdldEltYWdlT2Zmc2V0KEZYX0ZMT0FUICYgeCxGWF9GTE9BVCAmIHkpOw0KLQl2aXJ0dWFsIENQREZfU3RyZWFtICoJCQlHZXRQREZTdHJlYW0oKTsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQkJU2V0UERGU3RyZWFtKENQREZfU3RyZWFtKiBwU3RyZWFtKTsJDQotCXZvaWQJCQkJCQkJR2V0SW1hZ2VTaXplKEZYX0ZMT0FUICYgZldpZHRoLEZYX0ZMT0FUICYgZkhlaWdodCk7DQotCUNQREZfTWF0cml4CQkJCQkJR2V0SW1hZ2VNYXRyaXgoKTsNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEltYWdlQWxpYXMoKTsNCi0Jdm9pZAkJCQkJCQlTZXRJbWFnZUFsaWFzKEZYX0xQQ1NUUiBzSW1hZ2VBbGlhcyk7DQotDQotcHJvdGVjdGVkOg0KLQlDUERGX1N0cmVhbSoJCQkJCW1fcFBERlN0cmVhbTsNCi0JQ0ZYX0J5dGVTdHJpbmcJCQkJCW1fc0ltYWdlQWxpYXM7DQotfTsNCi0NCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9JY29uIDogcHVibGljIENQV0xfSW1hZ2UgDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9JY29uKCk7DQotCXZpcnR1YWwgfkNQV0xfSWNvbigpOw0KLQ0KLQl2aXJ0dWFsIENQREZfSWNvbkZpdCAqCQkJR2V0SWNvbkZpdCgpe3JldHVybiBtX3BJY29uRml0O307DQotDQotCXZpcnR1YWwgdm9pZAkJCQkJR2V0U2NhbGUoRlhfRkxPQVQgJiBmSFNjYWxlLEZYX0ZMT0FUICYgZlZTY2FsZSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJR2V0SW1hZ2VPZmZzZXQoRlhfRkxPQVQgJiB4LEZYX0ZMT0FUICYgeSk7DQotDQotCUZYX0lOVDMyCQkJCQkJR2V0U2NhbGVNZXRob2QoKTsNCi0JRlhfQk9PTAkJCQkJCQlJc1Byb3BvcnRpb25hbFNjYWxlKCk7DQotCXZvaWQJCQkJCQkJR2V0SWNvblBvc2l0aW9uKEZYX0ZMT0FUICYgZkxlZnQsIEZYX0ZMT0FUICYgZkJvdHRvbSk7DQotCUZYX0JPT0wJCQkJCQkJR2V0Rml0dGluZ0JvdW5kcygpOw0KLQ0KLQl2b2lkCQkJCQkJCVNldEljb25GaXQoQ1BERl9JY29uRml0ICogcEljb25GaXQpe21fcEljb25GaXQgPSBwSWNvbkZpdDt9Ow0KLQ0KLXByaXZhdGU6DQotCUNQREZfSWNvbkZpdCAqCQkJCQltX3BJY29uRml0Ow0KLX07DQotDQotDQotI2VuZGlmIC8vICFkZWZpbmVkKEFGWF9QV0xfQlVUVE9OX0hfXzVBNjA4MEFBXzMzQzVfNEZDOV85MUZDX0Q5NjQ0QzQxMTIwQV9fSU5DTFVERURfKQ0KLQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1BXTF9JQ09OX0hfCisjZGVmaW5lIF9QV0xfSUNPTl9IXworCitjbGFzcyBQV0xfQ0xBU1MgQ1BXTF9JbWFnZSA6IHB1YmxpYyBDUFdMX1duZAoreworcHVibGljOgorCUNQV0xfSW1hZ2UoKTsKKwl2aXJ0dWFsIH5DUFdMX0ltYWdlKCk7CisKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJR2V0SW1hZ2VBcHBTdHJlYW0oKTsKKworCXZpcnR1YWwgdm9pZAkJCQkJR2V0U2NhbGUoRlhfRkxPQVQgJiBmSFNjYWxlLEZYX0ZMT0FUICYgZlZTY2FsZSk7CisJdmlydHVhbCB2b2lkCQkJCQlHZXRJbWFnZU9mZnNldChGWF9GTE9BVCAmIHgsRlhfRkxPQVQgJiB5KTsKKwl2aXJ0dWFsIENQREZfU3RyZWFtICoJCQlHZXRQREZTdHJlYW0oKTsKKworcHVibGljOgorCXZvaWQJCQkJCQkJU2V0UERGU3RyZWFtKENQREZfU3RyZWFtKiBwU3RyZWFtKTsJCisJdm9pZAkJCQkJCQlHZXRJbWFnZVNpemUoRlhfRkxPQVQgJiBmV2lkdGgsRlhfRkxPQVQgJiBmSGVpZ2h0KTsKKwlDUERGX01hdHJpeAkJCQkJCUdldEltYWdlTWF0cml4KCk7CisJQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEltYWdlQWxpYXMoKTsKKwl2b2lkCQkJCQkJCVNldEltYWdlQWxpYXMoRlhfTFBDU1RSIHNJbWFnZUFsaWFzKTsKKworcHJvdGVjdGVkOgorCUNQREZfU3RyZWFtKgkJCQkJbV9wUERGU3RyZWFtOworCUNGWF9CeXRlU3RyaW5nCQkJCQltX3NJbWFnZUFsaWFzOworfTsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfSWNvbiA6IHB1YmxpYyBDUFdMX0ltYWdlIAoreworcHVibGljOgorCUNQV0xfSWNvbigpOworCXZpcnR1YWwgfkNQV0xfSWNvbigpOworCisJdmlydHVhbCBDUERGX0ljb25GaXQgKgkJCUdldEljb25GaXQoKXtyZXR1cm4gbV9wSWNvbkZpdDt9OworCisJdmlydHVhbCB2b2lkCQkJCQlHZXRTY2FsZShGWF9GTE9BVCAmIGZIU2NhbGUsRlhfRkxPQVQgJiBmVlNjYWxlKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCUdldEltYWdlT2Zmc2V0KEZYX0ZMT0FUICYgeCxGWF9GTE9BVCAmIHkpOworCisJRlhfSU5UMzIJCQkJCQlHZXRTY2FsZU1ldGhvZCgpOworCUZYX0JPT0wJCQkJCQkJSXNQcm9wb3J0aW9uYWxTY2FsZSgpOworCXZvaWQJCQkJCQkJR2V0SWNvblBvc2l0aW9uKEZYX0ZMT0FUICYgZkxlZnQsIEZYX0ZMT0FUICYgZkJvdHRvbSk7CisJRlhfQk9PTAkJCQkJCQlHZXRGaXR0aW5nQm91bmRzKCk7CisKKwl2b2lkCQkJCQkJCVNldEljb25GaXQoQ1BERl9JY29uRml0ICogcEljb25GaXQpe21fcEljb25GaXQgPSBwSWNvbkZpdDt9OworCitwcml2YXRlOgorCUNQREZfSWNvbkZpdCAqCQkJCQltX3BJY29uRml0OworfTsKKworCisjZW5kaWYgLy8gIWRlZmluZWQoQUZYX1BXTF9CVVRUT05fSF9fNUE2MDgwQUFfMzNDNV80RkM5XzkxRkNfRDk2NDRDNDExMjBBX19JTkNMVURFRF8pCisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfSWNvbkxpc3QuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0ljb25MaXN0LmgKaW5kZXggZTUxOTI5MC4uZjA4NDQ0OCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfSWNvbkxpc3QuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9JY29uTGlzdC5oCkBAIC0xLDEyNSArMSwxMjUgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1BXTF9JY29uTGlzdF9IXw0KLSNkZWZpbmUgX1BXTF9JY29uTGlzdF9IXw0KLQ0KLWNsYXNzIElQV0xfSWNvbkxpc3RfTm90aWZ5Ow0KLWNsYXNzIENQV0xfSWNvbkxpc3RfSXRlbTsNCi1jbGFzcyBDUFdMX0ljb25MaXN0X0NvbnRlbnQ7DQotY2xhc3MgQ1BXTF9JY29uTGlzdDsNCi1jbGFzcyBDUFdMX0xhYmVsOw0KLQ0KLWNsYXNzIElQV0xfSWNvbkxpc3RfTm90aWZ5DQotew0KLXB1YmxpYzoNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25Ob3RlTGlzdFNlbENoYW5nZWQoRlhfSU5UMzIgbkl0ZW1JbmRleCkgPSAwOw0KLX07DQotDQotY2xhc3MgQ1BXTF9JY29uTGlzdF9JdGVtIDogcHVibGljIENQV0xfV25kDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9JY29uTGlzdF9JdGVtKCk7DQotCXZpcnR1YWwgfkNQV0xfSWNvbkxpc3RfSXRlbSgpOw0KLQ0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJCUdldENsYXNzTmFtZSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVJlUG9zQ2hpbGRXbmQoKTsNCi0NCi0Jdm9pZAkJCQkJCQkJU2V0U2VsZWN0KEZYX0JPT0wgYlNlbGVjdGVkKTsNCi0JRlhfQk9PTAkJCQkJCQkJSXNTZWxlY3RlZCgpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCQlTZXREYXRhKHZvaWQqIHBEYXRhKTsNCi0Jdm9pZAkJCQkJCQkJU2V0SWNvbihGWF9JTlQzMiBuSWNvbkluZGV4KTsNCi0Jdm9pZAkJCQkJCQkJU2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyKTsNCi0Jdm9pZAkJCQkJCQkJU2V0SWNvbkZpbGxDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7DQotCUNGWF9XaWRlU3RyaW5nCQkJCQkJR2V0VGV4dCgpIGNvbnN0Ow0KLQ0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCBGWF9GTE9BVAkJCQkJR2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQkJT25FbmFibGVkKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCU9uRGlzYWJsZWQoKTsNCi0NCi1wcml2YXRlOg0KLQlGWF9JTlQzMgkJCQkJCQltX25JY29uSW5kZXg7DQotCXZvaWQqCQkJCQkJCQltX3BEYXRhOw0KLQlGWF9CT09MCQkJCQkJCQltX2JTZWxlY3RlZDsNCi0JQ1BXTF9MYWJlbCoJCQkJCQkJbV9wVGV4dDsNCi0JQ1BXTF9Db2xvcgkJCQkJCQltX2NySWNvbjsNCi19Ow0KLQ0KLWNsYXNzIENQV0xfSWNvbkxpc3RfQ29udGVudCA6IHB1YmxpYyBDUFdMX0xpc3RDdHJsDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9JY29uTGlzdF9Db250ZW50KEZYX0lOVDMyIG5MaXN0Q291bnQpOw0KLQl2aXJ0dWFsIH5DUFdMX0ljb25MaXN0X0NvbnRlbnQoKTsNCi0NCi0Jdm9pZAkJCQkJCQkJU2V0U2VsZWN0KEZYX0lOVDMyIG5JbmRleCk7DQotCUZYX0lOVDMyCQkJCQkJCUdldFNlbGVjdCgpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCQlTZXROb3RpZnkoSVBXTF9JY29uTGlzdF9Ob3RpZnkqIHBOb3RpZnkpOw0KLQl2b2lkCQkJCQkJCQlFbmFibGVOb3RpZnkoRlhfQk9PTCBiTm90aWZ5KTsNCi0Jdm9pZAkJCQkJCQkJU2V0TGlzdERhdGEoRlhfSU5UMzIgbkl0ZW1JbmRleCwgdm9pZCogcERhdGEpOw0KLQl2b2lkCQkJCQkJCQlTZXRMaXN0SWNvbihGWF9JTlQzMiBuSXRlbUluZGV4LCBGWF9JTlQzMiBuSWNvbkluZGV4KTsNCi0Jdm9pZAkJCQkJCQkJU2V0TGlzdFN0cmluZyhGWF9JTlQzMiBuSXRlbUluZGV4LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyKTsNCi0Jdm9pZAkJCQkJCQkJU2V0SWNvbkZpbGxDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7DQotCUNGWF9XaWRlU3RyaW5nCQkJCQkJR2V0TGlzdFN0cmluZyhGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdDsNCi0JSVBXTF9JY29uTGlzdF9Ob3RpZnkqCQkJCUdldE5vdGlmeSgpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCQlTY3JvbGxUb0l0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCk7DQotDQotcHJvdGVjdGVkOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJT25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJT25LZXlEb3duKEZYX1dPUkQgbkNoYXIpOw0KLQ0KLXByaXZhdGU6DQotCUNQV0xfSWNvbkxpc3RfSXRlbSoJCQkJCUdldExpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCQlTZWxlY3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYlNlbGVjdCk7DQotCUZYX0lOVDMyCQkJCQkJCUZpbmRJdGVtSW5kZXgoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQkNCi0JRlhfQk9PTAkJCQkJCQkJbV9uU2VsZWN0SW5kZXg7DQotCUlQV0xfSWNvbkxpc3RfTm90aWZ5KgkJCQltX3BOb3RpZnk7DQotCUZYX0JPT0wJCQkJCQkJCW1fYkVuYWJsZU5vdGlmeTsNCi0JRlhfQk9PTAkJCQkJCQkJbV9iTW91c2VEb3duOw0KLQlGWF9JTlQzMgkJCQkJCQltX25MaXN0Q291bnQ7DQotfTsNCi0NCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9JY29uTGlzdCA6IHB1YmxpYyBDUFdMX1duZA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfSWNvbkxpc3QoRlhfSU5UMzIgbkxpc3RDb3VudCk7DQotCXZpcnR1YWwgfkNQV0xfSWNvbkxpc3QoKTsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJT25Nb3VzZVdoZWVsKHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsNCi0NCi0Jdm9pZAkJCQkJCQkJU2V0U2VsZWN0KEZYX0lOVDMyIG5JbmRleCk7DQotCXZvaWQJCQkJCQkJCVNldFRvcEl0ZW0oRlhfSU5UMzIgbkluZGV4KTsNCi0JRlhfSU5UMzIJCQkJCQkJR2V0U2VsZWN0KCkgY29uc3Q7DQotCXZvaWQJCQkJCQkJCVNldE5vdGlmeShJUFdMX0ljb25MaXN0X05vdGlmeSogcE5vdGlmeSk7DQotCXZvaWQJCQkJCQkJCUVuYWJsZU5vdGlmeShGWF9CT09MIGJOb3RpZnkpOw0KLQl2b2lkCQkJCQkJCQlTZXRMaXN0RGF0YShGWF9JTlQzMiBuSXRlbUluZGV4LCB2b2lkKiBwRGF0YSk7DQotCXZvaWQJCQkJCQkJCVNldExpc3RJY29uKEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0lOVDMyIG5JY29uSW5kZXgpOw0KLQl2b2lkCQkJCQkJCQlTZXRMaXN0U3RyaW5nKEZYX0lOVDMyIG5JdGVtSW5kZXgsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHIpOw0KLQl2b2lkCQkJCQkJCQlTZXRJY29uRmlsbENvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJCQlHZXRMaXN0U3RyaW5nKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Ow0KLQ0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25DcmVhdGVkKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVJlUG9zQ2hpbGRXbmQoKTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJQ3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApOw0KLQkNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSA9IDAsIEZYX0lOVFBUUiBsUGFyYW0gPSAwKTsNCi0NCi1wcml2YXRlOg0KLQlDUFdMX0ljb25MaXN0X0NvbnRlbnQqCQkJCW1fcExpc3RDb250ZW50Ow0KLQlGWF9JTlQzMgkJCQkJCQltX25MaXN0Q291bnQ7DQotfTsNCi0gDQotI2VuZGlmIC8vX1BXTF9JY29uTGlzdF9IXw0KLQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1BXTF9JY29uTGlzdF9IXworI2RlZmluZSBfUFdMX0ljb25MaXN0X0hfCisKK2NsYXNzIElQV0xfSWNvbkxpc3RfTm90aWZ5OworY2xhc3MgQ1BXTF9JY29uTGlzdF9JdGVtOworY2xhc3MgQ1BXTF9JY29uTGlzdF9Db250ZW50OworY2xhc3MgQ1BXTF9JY29uTGlzdDsKK2NsYXNzIENQV0xfTGFiZWw7CisKK2NsYXNzIElQV0xfSWNvbkxpc3RfTm90aWZ5Cit7CitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCQkJT25Ob3RlTGlzdFNlbENoYW5nZWQoRlhfSU5UMzIgbkl0ZW1JbmRleCkgPSAwOworfTsKKworY2xhc3MgQ1BXTF9JY29uTGlzdF9JdGVtIDogcHVibGljIENQV0xfV25kCit7CitwdWJsaWM6CisJQ1BXTF9JY29uTGlzdF9JdGVtKCk7CisJdmlydHVhbCB+Q1BXTF9JY29uTGlzdF9JdGVtKCk7CisKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJCUdldENsYXNzTmFtZSgpIGNvbnN0OworCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlSZVBvc0NoaWxkV25kKCk7CisKKwl2b2lkCQkJCQkJCQlTZXRTZWxlY3QoRlhfQk9PTCBiU2VsZWN0ZWQpOworCUZYX0JPT0wJCQkJCQkJCUlzU2VsZWN0ZWQoKSBjb25zdDsKKwl2b2lkCQkJCQkJCQlTZXREYXRhKHZvaWQqIHBEYXRhKTsKKwl2b2lkCQkJCQkJCQlTZXRJY29uKEZYX0lOVDMyIG5JY29uSW5kZXgpOworCXZvaWQJCQkJCQkJCVNldFRleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cik7CisJdm9pZAkJCQkJCQkJU2V0SWNvbkZpbGxDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCQlHZXRUZXh0KCkgY29uc3Q7CisKK3Byb3RlY3RlZDoKKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQlHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbkVuYWJsZWQoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbkRpc2FibGVkKCk7CisKK3ByaXZhdGU6CisJRlhfSU5UMzIJCQkJCQkJbV9uSWNvbkluZGV4OworCXZvaWQqCQkJCQkJCQltX3BEYXRhOworCUZYX0JPT0wJCQkJCQkJCW1fYlNlbGVjdGVkOworCUNQV0xfTGFiZWwqCQkJCQkJCW1fcFRleHQ7CisJQ1BXTF9Db2xvcgkJCQkJCQltX2NySWNvbjsKK307CisKK2NsYXNzIENQV0xfSWNvbkxpc3RfQ29udGVudCA6IHB1YmxpYyBDUFdMX0xpc3RDdHJsCit7CitwdWJsaWM6CisJQ1BXTF9JY29uTGlzdF9Db250ZW50KEZYX0lOVDMyIG5MaXN0Q291bnQpOworCXZpcnR1YWwgfkNQV0xfSWNvbkxpc3RfQ29udGVudCgpOworCisJdm9pZAkJCQkJCQkJU2V0U2VsZWN0KEZYX0lOVDMyIG5JbmRleCk7CisJRlhfSU5UMzIJCQkJCQkJR2V0U2VsZWN0KCkgY29uc3Q7CisJdm9pZAkJCQkJCQkJU2V0Tm90aWZ5KElQV0xfSWNvbkxpc3RfTm90aWZ5KiBwTm90aWZ5KTsKKwl2b2lkCQkJCQkJCQlFbmFibGVOb3RpZnkoRlhfQk9PTCBiTm90aWZ5KTsKKwl2b2lkCQkJCQkJCQlTZXRMaXN0RGF0YShGWF9JTlQzMiBuSXRlbUluZGV4LCB2b2lkKiBwRGF0YSk7CisJdm9pZAkJCQkJCQkJU2V0TGlzdEljb24oRlhfSU5UMzIgbkl0ZW1JbmRleCwgRlhfSU5UMzIgbkljb25JbmRleCk7CisJdm9pZAkJCQkJCQkJU2V0TGlzdFN0cmluZyhGWF9JTlQzMiBuSXRlbUluZGV4LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyKTsKKwl2b2lkCQkJCQkJCQlTZXRJY29uRmlsbENvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKTsKKwlDRlhfV2lkZVN0cmluZwkJCQkJCUdldExpc3RTdHJpbmcoRlhfSU5UMzIgbkl0ZW1JbmRleCkgY29uc3Q7CisJSVBXTF9JY29uTGlzdF9Ob3RpZnkqCQkJCUdldE5vdGlmeSgpIGNvbnN0OworCXZvaWQJCQkJCQkJCVNjcm9sbFRvSXRlbShGWF9JTlQzMiBuSXRlbUluZGV4KTsKKworcHJvdGVjdGVkOgorCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCU9uS2V5RG93bihGWF9XT1JEIG5DaGFyKTsKKworcHJpdmF0ZToKKwlDUFdMX0ljb25MaXN0X0l0ZW0qCQkJCQlHZXRMaXN0SXRlbShGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdDsKKwl2b2lkCQkJCQkJCQlTZWxlY3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYlNlbGVjdCk7CisJRlhfSU5UMzIJCQkJCQkJRmluZEl0ZW1JbmRleChjb25zdCBDUERGX1BvaW50JiBwb2ludCk7CisJCisJRlhfQk9PTAkJCQkJCQkJbV9uU2VsZWN0SW5kZXg7CisJSVBXTF9JY29uTGlzdF9Ob3RpZnkqCQkJCW1fcE5vdGlmeTsKKwlGWF9CT09MCQkJCQkJCQltX2JFbmFibGVOb3RpZnk7CisJRlhfQk9PTAkJCQkJCQkJbV9iTW91c2VEb3duOworCUZYX0lOVDMyCQkJCQkJCW1fbkxpc3RDb3VudDsKK307CisKK2NsYXNzIFBXTF9DTEFTUyBDUFdMX0ljb25MaXN0IDogcHVibGljIENQV0xfV25kCit7CitwdWJsaWM6CisJQ1BXTF9JY29uTGlzdChGWF9JTlQzMiBuTGlzdENvdW50KTsKKwl2aXJ0dWFsIH5DUFdMX0ljb25MaXN0KCk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQlPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOworCisJdm9pZAkJCQkJCQkJU2V0U2VsZWN0KEZYX0lOVDMyIG5JbmRleCk7CisJdm9pZAkJCQkJCQkJU2V0VG9wSXRlbShGWF9JTlQzMiBuSW5kZXgpOworCUZYX0lOVDMyCQkJCQkJCUdldFNlbGVjdCgpIGNvbnN0OworCXZvaWQJCQkJCQkJCVNldE5vdGlmeShJUFdMX0ljb25MaXN0X05vdGlmeSogcE5vdGlmeSk7CisJdm9pZAkJCQkJCQkJRW5hYmxlTm90aWZ5KEZYX0JPT0wgYk5vdGlmeSk7CisJdm9pZAkJCQkJCQkJU2V0TGlzdERhdGEoRlhfSU5UMzIgbkl0ZW1JbmRleCwgdm9pZCogcERhdGEpOworCXZvaWQJCQkJCQkJCVNldExpc3RJY29uKEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0lOVDMyIG5JY29uSW5kZXgpOworCXZvaWQJCQkJCQkJCVNldExpc3RTdHJpbmcoRlhfSU5UMzIgbkl0ZW1JbmRleCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cik7CisJdm9pZAkJCQkJCQkJU2V0SWNvbkZpbGxDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCQlHZXRMaXN0U3RyaW5nKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0OworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQkJT25DcmVhdGVkKCk7CisJdmlydHVhbCB2b2lkCQkJCQkJUmVQb3NDaGlsZFduZCgpOworCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwkKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOworCitwcml2YXRlOgorCUNQV0xfSWNvbkxpc3RfQ29udGVudCoJCQkJbV9wTGlzdENvbnRlbnQ7CisJRlhfSU5UMzIJCQkJCQkJbV9uTGlzdENvdW50OworfTsKKyAKKyNlbmRpZiAvL19QV0xfSWNvbkxpc3RfSF8KKworCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MYWJlbC5oIGIvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGFiZWwuaAppbmRleCAxNmJkMWFlLi4yOWVhNTEzIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MYWJlbC5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xhYmVsLmgKQEAgLTEsNTEgKzEsNTEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1BXTF9MQUJFTF9IXw0KLSNkZWZpbmUgX1BXTF9MQUJFTF9IXw0KLQ0KLWNsYXNzIElGWF9FZGl0Ow0KLQ0KLWNsYXNzIFBXTF9DTEFTUyBDUFdMX0xhYmVsIDogcHVibGljIENQV0xfV25kDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9MYWJlbCgpOw0KLQl2aXJ0dWFsIH5DUFdMX0xhYmVsKCk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSk7DQotCXZpcnR1YWwgRlhfRkxPQVQJCQkJR2V0Rm9udFNpemUoKSBjb25zdDsNCi0NCi1wdWJsaWM6CQkNCi0Jdm9pZAkJCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KTsNCi0JQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFRleHQoKSBjb25zdDsNCi0NCi0Jdm9pZAkJCQkJCQlTZXRMaW1pdENoYXIoRlhfSU5UMzIgbkxpbWl0Q2hhcik7DQotCXZvaWQJCQkJCQkJU2V0SG9yelNjYWxlKEZYX0lOVDMyIG5Ib3J6U2NhbGUpOw0KLQl2b2lkCQkJCQkJCVNldENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlKTsNCi0NCi0JQ1BERl9SZWN0CQkJCQkJR2V0Q29udGVudFJlY3QoKSBjb25zdDsJDQotCUZYX0lOVDMyCQkJCQkJR2V0VG90YWxXb3JkcygpOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZwkJCQkJR2V0VGV4dEFwcGVhcmFuY2VTdHJlYW0oY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KSBjb25zdDsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZpcnR1YWwgdm9pZAkJCQkJT25DcmVhdGVkKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVJlUG9zQ2hpbGRXbmQoKTsJDQotDQotcHJpdmF0ZToNCi0Jdm9pZAkJCQkJCQlTZXRQYXJhbUJ5RmxhZygpOw0KLQ0KLXByaXZhdGU6DQotCUlGWF9FZGl0KgkJCQkJCW1fcEVkaXQ7DQotfTsNCi0NCi0jZW5kaWYNCi0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9QV0xfTEFCRUxfSF8KKyNkZWZpbmUgX1BXTF9MQUJFTF9IXworCitjbGFzcyBJRlhfRWRpdDsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfTGFiZWwgOiBwdWJsaWMgQ1BXTF9XbmQKK3sKK3B1YmxpYzoKKwlDUFdMX0xhYmVsKCk7CisJdmlydHVhbCB+Q1BXTF9MYWJlbCgpOworCitwdWJsaWM6CisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJCUdldENsYXNzTmFtZSgpIGNvbnN0OwkKKwl2aXJ0dWFsIHZvaWQJCQkJCVNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSk7CisJdmlydHVhbCBGWF9GTE9BVAkJCQlHZXRGb250U2l6ZSgpIGNvbnN0OworCitwdWJsaWM6CQkKKwl2b2lkCQkJCQkJCVNldFRleHQoRlhfTFBDV1NUUiBjc1RleHQpOworCUNGWF9XaWRlU3RyaW5nCQkJCQlHZXRUZXh0KCkgY29uc3Q7CisKKwl2b2lkCQkJCQkJCVNldExpbWl0Q2hhcihGWF9JTlQzMiBuTGltaXRDaGFyKTsKKwl2b2lkCQkJCQkJCVNldEhvcnpTY2FsZShGWF9JTlQzMiBuSG9yelNjYWxlKTsKKwl2b2lkCQkJCQkJCVNldENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlKTsKKworCUNQREZfUmVjdAkJCQkJCUdldENvbnRlbnRSZWN0KCkgY29uc3Q7CQorCUZYX0lOVDMyCQkJCQkJR2V0VG90YWxXb3JkcygpOworCisJQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldFRleHRBcHBlYXJhbmNlU3RyZWFtKGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCkgY29uc3Q7CisKK3Byb3RlY3RlZDoKKwl2aXJ0dWFsIHZvaWQJCQkJCU9uQ3JlYXRlZCgpOworCXZpcnR1YWwgdm9pZAkJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOworCXZpcnR1YWwgdm9pZAkJCQkJR2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSk7CisJdmlydHVhbCB2b2lkCQkJCQlSZVBvc0NoaWxkV25kKCk7CQorCitwcml2YXRlOgorCXZvaWQJCQkJCQkJU2V0UGFyYW1CeUZsYWcoKTsKKworcHJpdmF0ZToKKwlJRlhfRWRpdCoJCQkJCQltX3BFZGl0OworfTsKKworI2VuZGlmCisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEJveC5oIGIvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEJveC5oCmluZGV4IDZlZjgyYzguLjc5NjE1NzkgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RCb3guaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MaXN0Qm94LmgKQEAgLTEsMTAzICsxLDEwMyBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfUFdMX0xJU1RCT1hfSF8NCi0jZGVmaW5lIF9QV0xfTElTVEJPWF9IXw0KLQ0KLWNsYXNzIENQREZfTGlzdEN0cmw7DQotY2xhc3MgQ1BXTF9MaXN0X05vdGlmeTsNCi1jbGFzcyBDUFdMX0xpc3RCb3g7DQotY2xhc3MgSVBXTF9GaWxsZXJfTm90aWZ5Ow0KLQ0KLWNsYXNzIENQV0xfTGlzdF9Ob3RpZnkgOiBwdWJsaWMgSUZYX0xpc3RfTm90aWZ5DQotew0KLXB1YmxpYzoNCi0JQ1BXTF9MaXN0X05vdGlmeShDUFdMX0xpc3RCb3ggKiBwTGlzdCk7DQotCXZpcnR1YWwgfkNQV0xfTGlzdF9Ob3RpZnkoKTsNCi0NCi0Jdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxJbmZvWChGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgDQotCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkNvbnRlbnRNaW4sIEZYX0ZMT0FUIGZDb250ZW50TWF4LCANCi0JCQkJCQkJCQkJCQlGWF9GTE9BVCBmU21hbGxTdGVwLCBGWF9GTE9BVCBmQmlnU3RlcCl7fQ0KLQl2b2lkCQkJCQkJCUlPblNldFNjcm9sbEluZm9ZKEZYX0ZMT0FUIGZQbGF0ZU1pbiwgRlhfRkxPQVQgZlBsYXRlTWF4LCANCi0JCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIA0KLQkJCQkJCQkJCQkJCUZYX0ZMT0FUIGZTbWFsbFN0ZXAsIEZYX0ZMT0FUIGZCaWdTdGVwKTsNCi0Jdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxQb3NYKEZYX0ZMT0FUIGZ4KXt9DQotCXZvaWQJCQkJCQkJSU9uU2V0U2Nyb2xsUG9zWShGWF9GTE9BVCBmeSk7DQotCXZvaWQJCQkJCQkJSU9uU2V0Q2FyZXQoRlhfQk9PTCBiVmlzaWJsZSxjb25zdCBDUERGX1BvaW50ICYgcHRIZWFkLGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSk7DQotCXZvaWQJCQkJCQkJSU9uQ2FyZXRDaGFuZ2UoY29uc3QgQ1BWVF9TZWNQcm9wcyAmIHNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIHdvcmRQcm9wcyk7DQotCXZvaWQJCQkJCQkJSU9uSW52YWxpZGF0ZVJlY3QoQ1BERl9SZWN0ICogcFJlY3QpOw0KLQ0KLXByaXZhdGU6DQotCUNQV0xfTGlzdEJveCoJCQkJCW1fcExpc3Q7CQ0KLX07DQotDQotY2xhc3MgUFdMX0NMQVNTIENQV0xfTGlzdEJveCA6IHB1YmxpYyBDUFdMX1duZA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfTGlzdEJveCgpOw0KLQl2aXJ0dWFsIH5DUFdMX0xpc3RCb3goKTsNCi0NCi0JdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJCUdldENsYXNzTmFtZSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uQ3JlYXRlZCgpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uRGVzdHJveSgpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbktleURvd24oRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uQ2hhcihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlLaWxsRm9jdXMoKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVJlUG9zQ2hpbGRXbmQoKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0LEZYX0JPT0wgYlJlZnJlc2ggPSBUUlVFKTsNCi0JdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCUdldFRleHQoKSBjb25zdDsJDQotCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUdldEZvY3VzUmVjdCgpIGNvbnN0Ow0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSk7DQotCXZpcnR1YWwgRlhfRkxPQVQJCQkJR2V0Rm9udFNpemUoKSBjb25zdDsNCi0NCi0Jdm9pZAkJCQkJCQlPbk5vdGlmeVNlbENoYW5nZWQoRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCAmIGJFeGl0ICwgRlhfRFdPUkQgbkZsYWcpOw0KLQ0KLQl2b2lkCQkJCQkJCUFkZFN0cmluZyhGWF9MUENXU1RSIHN0cmluZyk7CQ0KLQl2b2lkCQkJCQkJCVNldFRvcFZpc2libGVJbmRleChGWF9JTlQzMiBuSXRlbUluZGV4KTsNCi0Jdm9pZAkJCQkJCQlTY3JvbGxUb0xpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpOw0KLQl2b2lkCQkJCQkJCVJlc2V0Q29udGVudCgpOw0KLQl2b2lkCQkJCQkJCVJlc2V0KCk7DQotCXZvaWQJCQkJCQkJU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgpOw0KLQl2b2lkCQkJCQkJCVNldENhcmV0KEZYX0lOVDMyIG5JdGVtSW5kZXgpOw0KLQl2b2lkCQkJCQkJCVNldEhvdmVyU2VsKEZYX0JPT0wgYkhvdmVyU2VsKTsNCi0JDQotCUZYX0lOVDMyCQkJCQkJR2V0Q291bnQoKSBjb25zdDsNCi0JRlhfQk9PTAkJCQkJCQlJc011bHRpcGxlU2VsKCkgY29uc3Q7DQotCUZYX0lOVDMyCQkJCQkJR2V0Q2FyZXRJbmRleCgpIGNvbnN0Ow0KLQlGWF9JTlQzMgkJCQkJCUdldEN1clNlbCgpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUlzSXRlbVNlbGVjdGVkKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Ow0KLQlGWF9JTlQzMgkJCQkJCUdldFRvcFZpc2libGVJbmRleCgpIGNvbnN0Ow0KLQlGWF9JTlQzMgkJCQkJCUZpbmROZXh0KEZYX0lOVDMyIG5JbmRleCxGWF9XQ0hBUiBuQ2hhcikgY29uc3Q7DQotCUNQREZfUmVjdAkJCQkJCUdldENvbnRlbnRSZWN0KCkgY29uc3Q7CQ0KLQlGWF9GTE9BVAkJCQkJCUdldEZpcnN0SGVpZ2h0KCkgY29uc3Q7DQotCUNQREZfUmVjdAkJCQkJCUdldExpc3RSZWN0KCkgY29uc3Q7DQotDQotCXZvaWQJCQkJCQkJU2V0RmlsbGVyTm90aWZ5KElQV0xfRmlsbGVyX05vdGlmeSogcE5vdGlmeSkge21fcEZpbGxlck5vdGlmeSA9IHBOb3RpZnk7fQ0KLQ0KLXByb3RlY3RlZDoNCi0JSUZYX0xpc3QqCQkJCQkJbV9wTGlzdDsNCi0JQ1BXTF9MaXN0X05vdGlmeSoJCQkJbV9wTGlzdE5vdGlmeTsNCi0JRlhfQk9PTAkJCQkJCQltX2JNb3VzZURvd247DQotCUZYX0JPT0wJCQkJCQkJbV9iSG92ZXJTZWw7DQotCUlQV0xfRmlsbGVyX05vdGlmeSoJCQkJbV9wRmlsbGVyTm90aWZ5Ow0KLXB1YmxpYzoNCi0Jdm9pZAkJCQkJCQlBdHRhY2hGRkxEYXRhKHZvaWQqIHBEYXRhKSB7bV9wRm9ybUZpbGxlciA9IHBEYXRhO30NCi1wcml2YXRlOg0KLQl2b2lkKgkJCQkJCQltX3BGb3JtRmlsbGVyOw0KLX07DQotDQotI2VuZGlmIC8vICFkZWZpbmVkKEFGWF9QV0xfTElTVEJPWF9IX19GOEMwREQ3Ml9DQzNDXzQ4MDZfODZGQl9FOUQwMkIwNEEzNEJfX0lOQ0xVREVEXykNCi0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9QV0xfTElTVEJPWF9IXworI2RlZmluZSBfUFdMX0xJU1RCT1hfSF8KKworY2xhc3MgQ1BERl9MaXN0Q3RybDsKK2NsYXNzIENQV0xfTGlzdF9Ob3RpZnk7CitjbGFzcyBDUFdMX0xpc3RCb3g7CitjbGFzcyBJUFdMX0ZpbGxlcl9Ob3RpZnk7CisKK2NsYXNzIENQV0xfTGlzdF9Ob3RpZnkgOiBwdWJsaWMgSUZYX0xpc3RfTm90aWZ5Cit7CitwdWJsaWM6CisJQ1BXTF9MaXN0X05vdGlmeShDUFdMX0xpc3RCb3ggKiBwTGlzdCk7CisJdmlydHVhbCB+Q1BXTF9MaXN0X05vdGlmeSgpOworCisJdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxJbmZvWChGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIAorCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApe30KKwl2b2lkCQkJCQkJCUlPblNldFNjcm9sbEluZm9ZKEZYX0ZMT0FUIGZQbGF0ZU1pbiwgRlhfRkxPQVQgZlBsYXRlTWF4LCAKKwkJCQkJCQkJCQkJCUZYX0ZMT0FUIGZDb250ZW50TWluLCBGWF9GTE9BVCBmQ29udGVudE1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmU21hbGxTdGVwLCBGWF9GTE9BVCBmQmlnU3RlcCk7CisJdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxQb3NYKEZYX0ZMT0FUIGZ4KXt9CisJdm9pZAkJCQkJCQlJT25TZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KTsKKwl2b2lkCQkJCQkJCUlPblNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsY29uc3QgQ1BERl9Qb2ludCAmIHB0SGVhZCxjb25zdCBDUERGX1BvaW50ICYgcHRGb290LCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UpOworCXZvaWQJCQkJCQkJSU9uQ2FyZXRDaGFuZ2UoY29uc3QgQ1BWVF9TZWNQcm9wcyAmIHNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIHdvcmRQcm9wcyk7CisJdm9pZAkJCQkJCQlJT25JbnZhbGlkYXRlUmVjdChDUERGX1JlY3QgKiBwUmVjdCk7CisKK3ByaXZhdGU6CisJQ1BXTF9MaXN0Qm94KgkJCQkJbV9wTGlzdDsJCit9OworCitjbGFzcyBQV0xfQ0xBU1MgQ1BXTF9MaXN0Qm94IDogcHVibGljIENQV0xfV25kCit7CitwdWJsaWM6CisJQ1BXTF9MaXN0Qm94KCk7CisJdmlydHVhbCB+Q1BXTF9MaXN0Qm94KCk7CisKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CisJdmlydHVhbCB2b2lkCQkJCQlPbkNyZWF0ZWQoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCU9uRGVzdHJveSgpOworCXZpcnR1YWwgdm9pZAkJCQkJR2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSk7CisJdmlydHVhbCB2b2lkCQkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbkNoYXIoRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCUtpbGxGb2N1cygpOworCisJdmlydHVhbCB2b2lkCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOworCXZpcnR1YWwgdm9pZAkJCQkJUmVQb3NDaGlsZFduZCgpOworCXZpcnR1YWwgdm9pZAkJCQkJU2V0VGV4dChGWF9MUENXU1RSIGNzVGV4dCxGWF9CT09MIGJSZWZyZXNoID0gVFJVRSk7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCUdldFRleHQoKSBjb25zdDsJCisJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Rm9jdXNSZWN0KCkgY29uc3Q7CisJdmlydHVhbCB2b2lkCQkJCQlTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpOworCXZpcnR1YWwgRlhfRkxPQVQJCQkJR2V0Rm9udFNpemUoKSBjb25zdDsKKworCXZvaWQJCQkJCQkJT25Ob3RpZnlTZWxDaGFuZ2VkKEZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgJiBiRXhpdCAsIEZYX0RXT1JEIG5GbGFnKTsKKworCXZvaWQJCQkJCQkJQWRkU3RyaW5nKEZYX0xQQ1dTVFIgc3RyaW5nKTsJCisJdm9pZAkJCQkJCQlTZXRUb3BWaXNpYmxlSW5kZXgoRlhfSU5UMzIgbkl0ZW1JbmRleCk7CisJdm9pZAkJCQkJCQlTY3JvbGxUb0xpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpOworCXZvaWQJCQkJCQkJUmVzZXRDb250ZW50KCk7CisJdm9pZAkJCQkJCQlSZXNldCgpOworCXZvaWQJCQkJCQkJU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgpOworCXZvaWQJCQkJCQkJU2V0Q2FyZXQoRlhfSU5UMzIgbkl0ZW1JbmRleCk7CisJdm9pZAkJCQkJCQlTZXRIb3ZlclNlbChGWF9CT09MIGJIb3ZlclNlbCk7CisJCisJRlhfSU5UMzIJCQkJCQlHZXRDb3VudCgpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJSXNNdWx0aXBsZVNlbCgpIGNvbnN0OworCUZYX0lOVDMyCQkJCQkJR2V0Q2FyZXRJbmRleCgpIGNvbnN0OworCUZYX0lOVDMyCQkJCQkJR2V0Q3VyU2VsKCkgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQlJc0l0ZW1TZWxlY3RlZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdDsKKwlGWF9JTlQzMgkJCQkJCUdldFRvcFZpc2libGVJbmRleCgpIGNvbnN0OworCUZYX0lOVDMyCQkJCQkJRmluZE5leHQoRlhfSU5UMzIgbkluZGV4LEZYX1dDSEFSIG5DaGFyKSBjb25zdDsKKwlDUERGX1JlY3QJCQkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0OwkKKwlGWF9GTE9BVAkJCQkJCUdldEZpcnN0SGVpZ2h0KCkgY29uc3Q7CisJQ1BERl9SZWN0CQkJCQkJR2V0TGlzdFJlY3QoKSBjb25zdDsKKworCXZvaWQJCQkJCQkJU2V0RmlsbGVyTm90aWZ5KElQV0xfRmlsbGVyX05vdGlmeSogcE5vdGlmeSkge21fcEZpbGxlck5vdGlmeSA9IHBOb3RpZnk7fQorCitwcm90ZWN0ZWQ6CisJSUZYX0xpc3QqCQkJCQkJbV9wTGlzdDsKKwlDUFdMX0xpc3RfTm90aWZ5KgkJCQltX3BMaXN0Tm90aWZ5OworCUZYX0JPT0wJCQkJCQkJbV9iTW91c2VEb3duOworCUZYX0JPT0wJCQkJCQkJbV9iSG92ZXJTZWw7CisJSVBXTF9GaWxsZXJfTm90aWZ5KgkJCQltX3BGaWxsZXJOb3RpZnk7CitwdWJsaWM6CisJdm9pZAkJCQkJCQlBdHRhY2hGRkxEYXRhKHZvaWQqIHBEYXRhKSB7bV9wRm9ybUZpbGxlciA9IHBEYXRhO30KK3ByaXZhdGU6CisJdm9pZCoJCQkJCQkJbV9wRm9ybUZpbGxlcjsKK307CisKKyNlbmRpZiAvLyAhZGVmaW5lZChBRlhfUFdMX0xJU1RCT1hfSF9fRjhDMERENzJfQ0MzQ180ODA2Xzg2RkJfRTlEMDJCMDRBMzRCX19JTkNMVURFRF8pCisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEN0cmwuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmgKaW5kZXggM2EzYjkyMi4uODk5NzI5NiAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEN0cmwuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MaXN0Q3RybC5oCkBAIC0xLDUzICsxLDUzIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9QV0xfTElTVENUUkxfSF8NCi0jZGVmaW5lIF9QV0xfTElTVENUUkxfSF8NCi0NCi1jbGFzcyBDUFdMX0xpc3RDdHJsOw0KLQ0KLWNsYXNzIENQV0xfTGlzdEN0cmwgOiBwdWJsaWMgQ1BXTF9XbmQNCi17DQotcHVibGljOg0KLQlDUFdMX0xpc3RDdHJsKCk7DQotCXZpcnR1YWwgfkNQV0xfTGlzdEN0cmwoKTsNCi0NCi1wdWJsaWM6DQotCXZvaWQJCQkJCQkJCVNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCUNQREZfUG9pbnQJCQkJCQkJR2V0U2Nyb2xsUG9zKCkgY29uc3Q7DQotCUNQREZfUmVjdAkJCQkJCQlHZXRTY3JvbGxBcmVhKCkgY29uc3Q7DQotCQ0KLQl2b2lkCQkJCQkJCQlTZXRJdGVtU3BhY2UoRlhfRkxPQVQgZlNwYWNlKTsNCi0Jdm9pZAkJCQkJCQkJU2V0VG9wU3BhY2UoRlhfRkxPQVQgZlNwYWNlKTsNCi0Jdm9pZAkJCQkJCQkJU2V0Qm90dG9tU3BhY2UoRlhfRkxPQVQgZlNwYWNlKTsNCi0Jdm9pZAkJCQkJCQkJUmVzZXRGYWNlKCk7DQotCXZvaWQJCQkJCQkJCVJlc2V0Q29udGVudChGWF9JTlQzMiBuU3RhcnQpOw0KLQlGWF9JTlQzMgkJCQkJCQlHZXRJdGVtSW5kZXgoQ1BXTF9XbmQqIHBJdGVtKTsNCi0JRlhfRkxPQVQJCQkJCQkJR2V0Q29udGVudHNIZWlnaHQoRlhfRkxPQVQgZkxpbWl0V2lkdGgpOw0KLQ0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCB2b2lkCQkJCQkJUmVQb3NDaGlsZFduZCgpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlEcmF3Q2hpbGRBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOw0KLQ0KLXB1YmxpYzoNCi0JQ1BERl9Qb2ludAkJCQkJCQlJblRvT3V0KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdDsNCi0JQ1BERl9Qb2ludAkJCQkJCQlPdXRUb0luKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdDsNCi0JQ1BERl9SZWN0CQkJCQkJCUluVG9PdXQoY29uc3QgQ1BERl9SZWN0JiByZWN0KSBjb25zdDsNCi0JQ1BERl9SZWN0CQkJCQkJCU91dFRvSW4oY29uc3QgQ1BERl9SZWN0JiByZWN0KSBjb25zdDsNCi0NCi1wcml2YXRlOg0KLQl2b2lkCQkJCQkJCQlSZXNldEFsbChGWF9CT09MIGJNb3ZlLEZYX0lOVDMyIG5TdGFydCk7DQotDQotcHJpdmF0ZToNCi0JQ1BERl9SZWN0CQkJCQkJCW1fcmNDb250ZW50Ow0KLQlDUERGX1BvaW50CQkJCQkJCW1fcHRTY3JvbGw7DQotCUZYX0ZMT0FUCQkJCQkJCW1fZkl0ZW1TcGFjZTsNCi0JRlhfRkxPQVQJCQkJCQkJbV9mVG9wU3BhY2U7DQotCUZYX0ZMT0FUCQkJCQkJCW1fZkJvdHRvbVNwYWNlOw0KLX07DQotDQotI2VuZGlmDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2lmbmRlZiBfUFdMX0xJU1RDVFJMX0hfCisjZGVmaW5lIF9QV0xfTElTVENUUkxfSF8KKworY2xhc3MgQ1BXTF9MaXN0Q3RybDsKKworY2xhc3MgQ1BXTF9MaXN0Q3RybCA6IHB1YmxpYyBDUFdMX1duZAoreworcHVibGljOgorCUNQV0xfTGlzdEN0cmwoKTsKKwl2aXJ0dWFsIH5DUFdMX0xpc3RDdHJsKCk7CisKK3B1YmxpYzoKKwl2b2lkCQkJCQkJCQlTZXRTY3JvbGxQb3MoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCUNQREZfUG9pbnQJCQkJCQkJR2V0U2Nyb2xsUG9zKCkgY29uc3Q7CisJQ1BERl9SZWN0CQkJCQkJCUdldFNjcm9sbEFyZWEoKSBjb25zdDsKKwkKKwl2b2lkCQkJCQkJCQlTZXRJdGVtU3BhY2UoRlhfRkxPQVQgZlNwYWNlKTsKKwl2b2lkCQkJCQkJCQlTZXRUb3BTcGFjZShGWF9GTE9BVCBmU3BhY2UpOworCXZvaWQJCQkJCQkJCVNldEJvdHRvbVNwYWNlKEZYX0ZMT0FUIGZTcGFjZSk7CisJdm9pZAkJCQkJCQkJUmVzZXRGYWNlKCk7CisJdm9pZAkJCQkJCQkJUmVzZXRDb250ZW50KEZYX0lOVDMyIG5TdGFydCk7CisJRlhfSU5UMzIJCQkJCQkJR2V0SXRlbUluZGV4KENQV0xfV25kKiBwSXRlbSk7CisJRlhfRkxPQVQJCQkJCQkJR2V0Q29udGVudHNIZWlnaHQoRlhfRkxPQVQgZkxpbWl0V2lkdGgpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQkJUmVQb3NDaGlsZFduZCgpOworCXZpcnR1YWwgdm9pZAkJCQkJCURyYXdDaGlsZEFwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7CisKK3B1YmxpYzoKKwlDUERGX1BvaW50CQkJCQkJCUluVG9PdXQoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0OworCUNQREZfUG9pbnQJCQkJCQkJT3V0VG9Jbihjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3Q7CisJQ1BERl9SZWN0CQkJCQkJCUluVG9PdXQoY29uc3QgQ1BERl9SZWN0JiByZWN0KSBjb25zdDsKKwlDUERGX1JlY3QJCQkJCQkJT3V0VG9Jbihjb25zdCBDUERGX1JlY3QmIHJlY3QpIGNvbnN0OworCitwcml2YXRlOgorCXZvaWQJCQkJCQkJCVJlc2V0QWxsKEZYX0JPT0wgYk1vdmUsRlhfSU5UMzIgblN0YXJ0KTsKKworcHJpdmF0ZToKKwlDUERGX1JlY3QJCQkJCQkJbV9yY0NvbnRlbnQ7CisJQ1BERl9Qb2ludAkJCQkJCQltX3B0U2Nyb2xsOworCUZYX0ZMT0FUCQkJCQkJCW1fZkl0ZW1TcGFjZTsKKwlGWF9GTE9BVAkJCQkJCQltX2ZUb3BTcGFjZTsKKwlGWF9GTE9BVAkJCQkJCQltX2ZCb3R0b21TcGFjZTsKK307CisKKyNlbmRpZgorCmRpZmYgLS1naXQgYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Ob3RlLmggYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Ob3RlLmgKaW5kZXggODkzMDhlNi4uN2NjOWUwNCAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTm90ZS5oCisrKyBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX05vdGUuaApAQCAtMSwzNTUgKzEsMzU1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9QV0xfTk9URV9IXw0KLSNkZWZpbmUgX1BXTF9OT1RFX0hfDQotDQotY2xhc3MgSVBXTF9Ob3RlTm90aWZ5Ow0KLWNsYXNzIElQV0xfTm90ZUhhbmRsZXI7DQotY2xhc3MgSVBXTF9Ob3RlSXRlbTsNCi1jbGFzcyBDUFdMX05vdGVJdGVtOw0KLWNsYXNzIENQV0xfTm90ZTsNCi1jbGFzcyBDUFdMX0xhYmVsOw0KLWNsYXNzIENQV0xfRWRpdDsNCi1jbGFzcyBDUFdMX05vdGVfSWNvbjsNCi1jbGFzcyBDUFdMX05vdGVfQ2xvc2VCb3g7DQotY2xhc3MgQ1BXTF9Ob3RlX0xCQm94Ow0KLWNsYXNzIENQV0xfTm90ZV9SQkJveDsNCi1jbGFzcyBDUFdMX05vdGVfRWRpdDsNCi1jbGFzcyBDUFdMX05vdGVfT3B0aW9uczsNCi1jbGFzcyBDUFdMX05vdGVfQ29udGVudHM7DQotY2xhc3MgSVBvcHVwX05vdGU7DQotDQotDQotY2xhc3MgSVBXTF9Ob3RlTm90aWZ5DQotew0KLXB1YmxpYzoNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25Ob3RlTW92ZShjb25zdCBGWF9SRUNUJiBydFdpbikgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlPbk5vdGVTaG93KEZYX0JPT0wgYlNob3cpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25Ob3RlQWN0aXZhdGUoRlhfQk9PTCBiQWN0aXZlKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCU9uTm90ZUNsb3NlKCkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlPbkl0ZW1DcmVhdGUoSVBXTF9Ob3RlSXRlbSogcEl0ZW0pID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25JdGVtRGVsZXRlKElQV0xfTm90ZUl0ZW0qIHBJdGVtKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCU9uU2V0QXV0aG9yTmFtZShJUFdMX05vdGVJdGVtKiBwSXRlbSkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlPblNldEJrQ29sb3IoSVBXTF9Ob3RlSXRlbSogcEl0ZW0pID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25TZXRDb250ZW50cyhJUFdMX05vdGVJdGVtKiBwSXRlbSkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlPblNldERhdGVUaW1lKElQV0xfTm90ZUl0ZW0qIHBJdGVtKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCU9uU2V0U3ViamVjdE5hbWUoSVBXTF9Ob3RlSXRlbSogcEl0ZW0pID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25Qb3B1cE1lbnUoRlhfSU5UMzIgeCwgRlhfSU5UMzIgeSkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlPblBvcHVwTWVudShJUFdMX05vdGVJdGVtKiBwSXRlbSwgRlhfSU5UMzIgeCwgRlhfSU5UMzIgeSkgPSAwOw0KLX07DQotDQotY2xhc3MgSVBXTF9Ob3RlSGFuZGxlcg0KLXsNCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQkJCU9uTm90ZUNvbG9yQ2hhbmdlZChjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikgPSAwOw0KLX07DQotDQotY2xhc3MgSVBXTF9Ob3RlSXRlbQ0KLXsNCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQkJCVNldFByaXZhdGVEYXRhKHZvaWQqIHBEYXRhKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVNldEJrQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJU2V0U3ViamVjdE5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVNldEF1dGhvck5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVNldERhdGVUaW1lKEZYX1NZU1RFTVRJTUUgdGltZSkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKSA9IDA7DQotDQotCXZpcnR1YWwgSVBXTF9Ob3RlSXRlbSoJCQkJQ3JlYXRlU3ViSXRlbSgpID0gMDsNCi0JdmlydHVhbCBGWF9JTlQzMgkJCQkJQ291bnRTdWJJdGVtcygpIGNvbnN0ID0gMDsNCi0JdmlydHVhbCBJUFdMX05vdGVJdGVtKgkJCQlHZXRTdWJJdGVtcyhGWF9JTlQzMiBpbmRleCkgY29uc3QgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkgPSAwOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRGb2N1cygpID0gMDsNCi0JDQotCXZpcnR1YWwgSVBXTF9Ob3RlSXRlbSoJCQkJR2V0UGFyZW50SXRlbSgpIGNvbnN0ID0gMDsNCi0JdmlydHVhbCB2b2lkKgkJCQkJCUdldFByaXZhdGVEYXRhKCkgY29uc3QgPSAwOw0KLQl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQkJCUdldEF1dGhvck5hbWUoKSBjb25zdCA9IDA7DQotCXZpcnR1YWwgQ1BXTF9Db2xvcgkJCQkJR2V0QmtDb2xvcigpIGNvbnN0ID0gMDsNCi0JdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQlHZXRDb250ZW50cygpIGNvbnN0ID0gMDsNCi0JdmlydHVhbCBGWF9TWVNURU1USU1FCQkJCUdldERhdGVUaW1lKCkgY29uc3QgPSAwOw0KLQl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQkJCUdldFN1YmplY3ROYW1lKCkgY29uc3QgPSAwOw0KLQ0KLQl2aXJ0dWFsIENQV0xfRWRpdCoJCQkJCUdldEVkaXQoKSBjb25zdCA9IDA7DQotfTsNCi0NCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9Ob3RlX0ljb24gOiBwdWJsaWMgQ1BXTF9XbmQNCi17DQotcHVibGljOg0KLQlDUFdMX05vdGVfSWNvbigpOw0KLQl2aXJ0dWFsIH5DUFdMX05vdGVfSWNvbigpOw0KLQ0KLQl2b2lkCQkJCQkJCQlTZXRJY29uVHlwZShGWF9JTlQzMiBuVHlwZSk7DQotDQotcHVibGljOg0KLQ0KLXByb3RlY3RlZDoNCi0JdmlydHVhbCB2b2lkCQkJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOw0KLQ0KLXByaXZhdGU6DQotCUZYX0lOVDMyCQkJCQkJCW1fblR5cGU7DQotfTsNCi0NCi1jbGFzcyBDUFdMX05vdGVfQ2xvc2VCb3ggOiBwdWJsaWMgQ1BXTF9CdXR0b24NCi17DQotcHVibGljOg0KLQlDUFdMX05vdGVfQ2xvc2VCb3goKTsNCi0JdmlydHVhbCB+Q1BXTF9Ob3RlX0Nsb3NlQm94KCk7DQotDQotcHJvdGVjdGVkOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQ0KLXByaXZhdGU6DQotCUZYX0JPT0wJCQkJCQkJCW1fYk1vdXNlRG93bjsNCi19Ow0KLQ0KLWNsYXNzIENQV0xfTm90ZV9MQkJveCA6IHB1YmxpYyBDUFdMX1duZA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfTm90ZV9MQkJveCgpOw0KLQl2aXJ0dWFsIH5DUFdMX05vdGVfTEJCb3goKTsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZpcnR1YWwgdm9pZAkJCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsNCi19Ow0KLQ0KLWNsYXNzIENQV0xfTm90ZV9SQkJveCA6IHB1YmxpYyBDUFdMX1duZA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfTm90ZV9SQkJveCgpOw0KLQl2aXJ0dWFsIH5DUFdMX05vdGVfUkJCb3goKTsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZpcnR1YWwgdm9pZAkJCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsNCi19Ow0KLQ0KLWNsYXNzIENQV0xfTm90ZV9FZGl0IDogcHVibGljIENQV0xfRWRpdA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfTm90ZV9FZGl0KCk7DQotCXZpcnR1YWwgfkNQV0xfTm90ZV9FZGl0KCk7DQotDQotCXZvaWQJCQkJCQkJCUVuYWJsZU5vdGlmeShGWF9CT09MIGJFbmFibGUpIHttX2JFbmFibGVOb3RpZnkgPSBiRW5hYmxlO30NCi0JdmlydHVhbCBGWF9GTE9BVAkJCQkJR2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCk7DQotCUZYX0ZMT0FUCQkJCQkJCUdldEl0ZW1MZWZ0TWFyZ2luKCk7DQotCUZYX0ZMT0FUCQkJCQkJCUdldEl0ZW1SaWdodE1hcmdpbigpOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KTsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZpcnR1YWwgdm9pZAkJCQkJCU9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0gPSAwLCBGWF9JTlRQVFIgbFBhcmFtID0gMCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVJlUG9zQ2hpbGRXbmQoKTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25TZXRGb2N1cygpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlPbktpbGxGb2N1cygpOwkNCi0NCi1wcml2YXRlOg0KLQlGWF9CT09MCQkJCQkJCQltX2JFbmFibGVOb3RpZnk7DQotCUZYX0ZMT0FUCQkJCQkJCW1fZk9sZEl0ZW1IZWlnaHQ7DQotCUZYX0JPT0wJCQkJCQkJCW1fYlNpemVDaGFuZ2VkOw0KLQlGWF9GTE9BVAkJCQkJCQltX2ZPbGRNaW47DQotCUZYX0ZMT0FUCQkJCQkJCW1fZk9sZE1heDsNCi19Ow0KLQ0KLWNsYXNzIENQV0xfTm90ZV9PcHRpb25zIDogcHVibGljIENQV0xfV25kDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9Ob3RlX09wdGlvbnMoKTsNCi0JdmlydHVhbCB+Q1BXTF9Ob3RlX09wdGlvbnMoKTsNCi0NCi0JQ1BERl9SZWN0CQkJCQkJCUdldENvbnRlbnRSZWN0KCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVNldFRleHRDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpOw0KLQl2b2lkCQkJCQkJCQlTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCk7DQotDQotcHJvdGVjdGVkOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlSZVBvc0NoaWxkV25kKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOw0KLQ0KLXByaXZhdGU6DQotCUNQV0xfTGFiZWwqCQkJCQkJCW1fcFRleHQ7DQotfTsNCi0NCi1jbGFzcyBDUFdMX05vdGVfQ29udGVudHMgOiBwdWJsaWMgQ1BXTF9MaXN0Q3RybA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfTm90ZV9Db250ZW50cygpOw0KLQl2aXJ0dWFsIH5DUFdMX05vdGVfQ29udGVudHMoKTsNCi0NCi0JdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJCQlHZXRDbGFzc05hbWUoKSBjb25zdDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJT25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSA9IDAsIEZYX0lOVFBUUiBsUGFyYW0gPSAwKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQ0KLQl2b2lkCQkJCQkJCQlTZXRFZGl0Rm9jdXMoRlhfQk9PTCBiTGFzdCk7DQotCUNQV0xfRWRpdCoJCQkJCQkJR2V0RWRpdCgpIGNvbnN0Ow0KLQ0KLXB1YmxpYzoNCi0Jdm9pZAkJCQkJCQkJU2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpOw0KLQlDRlhfV2lkZVN0cmluZwkJCQkJCUdldFRleHQoKSBjb25zdDsNCi0NCi0JQ1BXTF9Ob3RlSXRlbSoJCQkJCQlDcmVhdGVTdWJJdGVtKCk7DQotCXZvaWQJCQkJCQkJCURlbGV0ZVN1Ykl0ZW0oSVBXTF9Ob3RlSXRlbSogcE5vdGVJdGVtKTsNCi0JRlhfSU5UMzIJCQkJCQkJQ291bnRTdWJJdGVtcygpIGNvbnN0Ow0KLQlJUFdMX05vdGVJdGVtKgkJCQkJCUdldFN1Ykl0ZW1zKEZYX0lOVDMyIGluZGV4KSBjb25zdDsNCi0NCi0JdmlydHVhbCBJUFdMX05vdGVJdGVtKgkJCQlHZXRIaXROb3RlSXRlbShjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotCXZvaWQJCQkJCQkJCUVuYWJsZVJlYWQoRlhfQk9PTCBiRW5hYmxlZCk7DQotCXZvaWQJCQkJCQkJCUVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKTsNCi0NCi1wcm90ZWN0ZWQ6DQotCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsNCi0NCi1wcml2YXRlOg0KLQlDUFdMX05vdGVfRWRpdCoJCQkJCQltX3BFZGl0Ow0KLX07DQotDQotY2xhc3MgUFdMX0NMQVNTIENQV0xfTm90ZUl0ZW0gOiBwdWJsaWMgQ1BXTF9XbmQsIHB1YmxpYyBJUFdMX05vdGVJdGVtIA0KLXsNCi1wdWJsaWM6DQotCUNQV0xfTm90ZUl0ZW0oKTsNCi0JdmlydHVhbCB+Q1BXTF9Ob3RlSXRlbSgpOw0KLQ0KLXB1YmxpYzoNCi0JdmlydHVhbCB2b2lkCQkJCQkJU2V0UHJpdmF0ZURhdGEodm9pZCogcERhdGEpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJU2V0U3ViamVjdE5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJU2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlTZXREYXRlVGltZShGWF9TWVNURU1USU1FIHRpbWUpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKTsNCi0NCi0JdmlydHVhbCBJUFdMX05vdGVJdGVtKgkJCQlDcmVhdGVTdWJJdGVtKCk7DQotCXZpcnR1YWwgRlhfSU5UMzIJCQkJCUNvdW50U3ViSXRlbXMoKSBjb25zdDsNCi0JdmlydHVhbCBJUFdMX05vdGVJdGVtKgkJCQlHZXRTdWJJdGVtcyhGWF9JTlQzMiBpbmRleCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZAkJCQkJCURlbGV0ZVN1Ykl0ZW0oSVBXTF9Ob3RlSXRlbSogcE5vdGVJdGVtKTsNCi0JdmlydHVhbCB2b2lkCQkJCQkJU2V0Rm9jdXMoKXtTZXROb3RlRm9jdXMoRkFMU0UpO30NCi0NCi0JdmlydHVhbCBJUFdMX05vdGVJdGVtKgkJCQlHZXRQYXJlbnRJdGVtKCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZCoJCQkJCQlHZXRQcml2YXRlRGF0YSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQkJCUdldEF1dGhvck5hbWUoKSBjb25zdDsNCi0JdmlydHVhbCBDUFdMX0NvbG9yCQkJCQlHZXRCa0NvbG9yKCkgY29uc3Q7DQotCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCQkJR2V0Q29udGVudHMoKSBjb25zdDsNCi0JdmlydHVhbCBGWF9TWVNURU1USU1FCQkJCUdldERhdGVUaW1lKCkgY29uc3Q7DQotCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCQkJR2V0U3ViamVjdE5hbWUoKSBjb25zdDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJSXNUb3BJdGVtKCkgY29uc3QgeyByZXR1cm4gRkFMU0U7fQ0KLQl2aXJ0dWFsIENQV0xfRWRpdCoJCQkJCUdldEVkaXQoKSBjb25zdDsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJT25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCQkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7DQotCXZpcnR1YWwgSVBXTF9Ob3RlSXRlbSoJCQkJR2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOw0KLQl2aXJ0dWFsIElQV0xfTm90ZUl0ZW0qCQkJCUdldEZvY3VzZWROb3RlSXRlbSgpIGNvbnN0Ow0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlSZXNldFN1YmplY3ROYW1lKEZYX0lOVDMyIG5JdGVtSW5kZXgpOw0KLQl2b2lkCQkJCQkJCQlFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpOw0KLQl2b2lkCQkJCQkJCQlFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCk7DQotDQotcHJvdGVjdGVkOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlSZVBvc0NoaWxkV25kKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQkJT25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSA9IDAsIEZYX0lOVFBUUiBsUGFyYW0gPSAwKTsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgRlhfRkxPQVQJCQkJCUdldEl0ZW1IZWlnaHQoRlhfRkxPQVQgZkxpbWl0V2lkdGgpOw0KLQl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQlHZXRJdGVtTGVmdE1hcmdpbigpOw0KLQl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQlHZXRJdGVtUmlnaHRNYXJnaW4oKTsNCi0JQ1BXTF9Ob3RlSXRlbSoJCQkJCQlDcmVhdGVOb3RlSXRlbSgpOw0KLQlDUFdMX05vdGVJdGVtKgkJCQkJCUdldFBhcmVudE5vdGVJdGVtKCkgY29uc3Q7DQotDQotCXZvaWQJCQkJCQkJCVNldE5vdGVGb2N1cyhGWF9CT09MIGJMYXN0KTsNCi0Jdm9pZAkJCQkJCQkJT25Db250ZW50c1ZhbGlkYXRlKCk7DQotCQ0KLQl2b2lkCQkJCQkJCQlPbkNyZWF0ZU5vdGVJdGVtKCk7DQotDQotcHJvdGVjdGVkOg0KLQl2b2lkCQkJCQkJCQlQb3B1cE5vdGVJdGVtTWVudShjb25zdCBDUERGX1BvaW50JiBwb2ludCk7DQotDQotCXZpcnR1YWwgY29uc3QgQ1BXTF9Ob3RlKgkJCUdldE5vdGUoKSBjb25zdDsNCi0JdmlydHVhbCBJUFdMX05vdGVOb3RpZnkqCQkJR2V0Tm90ZU5vdGlmeSgpIGNvbnN0Ow0KLQ0KLXByb3RlY3RlZDoNCi0JQ1BXTF9MYWJlbCoJCQkJCQkJbV9wU3ViamVjdDsNCi0JQ1BXTF9MYWJlbCoJCQkJCQkJbV9wRGF0ZVRpbWU7DQotCUNQV0xfTm90ZV9Db250ZW50cyoJCQkJCW1fcENvbnRlbnRzOw0KLQ0KLXByaXZhdGU6DQotCXZvaWQqCQkJCQkJCQltX3BQcml2YXRlRGF0YTsNCi0JRlhfU1lTVEVNVElNRQkJCQkJCW1fZHROb3RlOw0KLQlDRlhfV2lkZVN0cmluZwkJCQkJCW1fc0F1dGhvcjsNCi0NCi0JRlhfRkxPQVQJCQkJCQkJbV9mT2xkSXRlbUhlaWdodDsNCi0JRlhfQk9PTAkJCQkJCQkJbV9iU2l6ZUNoYW5nZWQ7DQotCUZYX0JPT0wJCQkJCQkJCW1fYkFsbG93TW9kaWZ5Ow0KLX07DQotDQotY2xhc3MgUFdMX0NMQVNTIENQV0xfTm90ZSA6IHB1YmxpYyBDUFdMX05vdGVJdGVtDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9Ob3RlKElQb3B1cF9Ob3RlKiBwUG9wdXBOb3RlLCBJUFdMX05vdGVOb3RpZnkqIHBOb3RlTm90aWZ5LCBJUFdMX05vdGVIYW5kbGVyKiBwTm90ZUhhbmRsZXIpOw0KLQl2aXJ0dWFsIH5DUFdMX05vdGUoKTsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgdm9pZAkJCQkJCVNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVNldEF1dGhvck5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKTsNCi0JdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQlHZXRBdXRob3JOYW1lKCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVNldEJrQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlSZXNldFN1YmplY3ROYW1lKEZYX0lOVDMyIG5JdGVtSW5kZXgpe30NCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJSXNUb3BJdGVtKCkgY29uc3Qge3JldHVybiBUUlVFO30NCi0JdmlydHVhbCBjb25zdCBDUFdMX05vdGUqCQkJR2V0Tm90ZSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIElQV0xfTm90ZU5vdGlmeSoJCQlHZXROb3RlTm90aWZ5KCkgY29uc3Q7DQotDQotcHVibGljOg0KLQlJUFdMX05vdGVJdGVtKgkJCQkJCVJlcGx5KCk7DQotCXZvaWQJCQkJCQkJCUVuYWJsZU5vdGlmeShGWF9CT09MIGJFbmFibGVkKTsNCi0Jdm9pZAkJCQkJCQkJU2V0SWNvblR5cGUoRlhfSU5UMzIgblR5cGUpOw0KLQl2b2lkCQkJCQkJCQlTZXRPcHRpb25zVGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpOw0KLQl2b2lkCQkJCQkJCQlFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpOw0KLQl2b2lkCQkJCQkJCQlFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCk7DQotDQotCUNGWF9XaWRlU3RyaW5nCQkJCQkJR2V0UmVwbHlTdHJpbmcoKSBjb25zdDsNCi0Jdm9pZAkJCQkJCQkJU2V0UmVwbHlTdHJpbmcoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZyk7DQotDQotCS8vMC1ub3JtYWwgLyAxLWNhcHRpb24gLyAyLWxlZnRib3R0b20gY29ybmVyIC8gMy1yaWdodGJvdHRvbSBjb3JuZXIgLyA0LWNsb3NlIC8gNS1vcHRpb25zIA0KLQlGWF9JTlQzMgkJCQkJCQlOb3RlSGl0VGVzdChjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3Q7DQotCUNQREZfUmVjdAkJCQkJCQlHZXRDYXB0aW9uUmVjdCgpIGNvbnN0IHtyZXR1cm4gbV9yY0NhcHRpb247fQ0KLQlJUG9wdXBfTm90ZSoJCQkJCQlHZXRQb3B1cE5vdGUoKSBjb25zdCB7cmV0dXJuIG1fcFBvcHVwTm90ZTt9DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCQlPblJCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCQkJT25Nb3VzZVdoZWVsKHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotDQotcHJvdGVjdGVkOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlSZVBvc0NoaWxkV25kKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQkJT25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSA9IDAsIEZYX0lOVFBUUiBsUGFyYW0gPSAwKTsNCi0NCi0JRlhfQk9PTAkJCQkJCQkJUmVzZXRTY3JvbGxCYXIoKTsNCi0Jdm9pZAkJCQkJCQkJUmVQb3NOb3RlQ2hpbGRyZW4oKTsNCi0JRlhfQk9PTAkJCQkJCQkJU2Nyb2xsQmFyU2hvdWxkVmlzaWJsZSgpOw0KLQ0KLXByaXZhdGU6DQotCUNQV0xfTGFiZWwqCQkJCQkJCW1fcEF1dGhvcjsNCi0JQ1BXTF9Ob3RlX0ljb24qCQkJCQkJbV9wSWNvbjsNCi0JQ1BXTF9Ob3RlX0Nsb3NlQm94KgkJCQkJbV9wQ2xvc2VCb3g7DQotCUNQV0xfTm90ZV9MQkJveCoJCQkJCW1fcExCQm94Ow0KLQlDUFdMX05vdGVfUkJCb3gqCQkJCQltX3BSQkJveDsNCi0JQ1BXTF9TY3JvbGxCYXIqCQkJCQkJbV9wQ29udGVudHNCYXI7CQ0KLQlDUFdMX05vdGVfT3B0aW9ucyoJCQkJCW1fcE9wdGlvbnM7DQotCUlQV0xfTm90ZU5vdGlmeSoJCQkJCW1fcE5vdGVOb3RpZnk7DQotCUZYX0JPT0wJCQkJCQkJCW1fYlJlc2l6aW5nOw0KLQlQV0xfU0NST0xMX0lORk8JCQkJCQltX09sZFNjcm9sbEluZm87DQotCUNQREZfUmVjdAkJCQkJCQltX3JjQ2FwdGlvbjsNCi0JRlhfQk9PTAkJCQkJCQkJbV9iRW5hbGJsZU5vdGlmeTsNCi0JSVBvcHVwX05vdGUqCQkJCQkJbV9wUG9wdXBOb3RlOw0KLQlJUFdMX05vdGVIYW5kbGVyKgkJCQkJbV9wTm90ZUhhbmRsZXI7DQotCUNGWF9XaWRlU3RyaW5nCQkJCQkJbV9zUmVwbHlTdHJpbmc7DQotfTsNCi0NCi0jZW5kaWYNCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9QV0xfTk9URV9IXworI2RlZmluZSBfUFdMX05PVEVfSF8KKworY2xhc3MgSVBXTF9Ob3RlTm90aWZ5OworY2xhc3MgSVBXTF9Ob3RlSGFuZGxlcjsKK2NsYXNzIElQV0xfTm90ZUl0ZW07CitjbGFzcyBDUFdMX05vdGVJdGVtOworY2xhc3MgQ1BXTF9Ob3RlOworY2xhc3MgQ1BXTF9MYWJlbDsKK2NsYXNzIENQV0xfRWRpdDsKK2NsYXNzIENQV0xfTm90ZV9JY29uOworY2xhc3MgQ1BXTF9Ob3RlX0Nsb3NlQm94OworY2xhc3MgQ1BXTF9Ob3RlX0xCQm94OworY2xhc3MgQ1BXTF9Ob3RlX1JCQm94OworY2xhc3MgQ1BXTF9Ob3RlX0VkaXQ7CitjbGFzcyBDUFdMX05vdGVfT3B0aW9uczsKK2NsYXNzIENQV0xfTm90ZV9Db250ZW50czsKK2NsYXNzIElQb3B1cF9Ob3RlOworCisKK2NsYXNzIElQV0xfTm90ZU5vdGlmeQoreworcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQkJCU9uTm90ZU1vdmUoY29uc3QgRlhfUkVDVCYgcnRXaW4pID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbk5vdGVTaG93KEZYX0JPT0wgYlNob3cpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbk5vdGVBY3RpdmF0ZShGWF9CT09MIGJBY3RpdmUpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbk5vdGVDbG9zZSgpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbkl0ZW1DcmVhdGUoSVBXTF9Ob3RlSXRlbSogcEl0ZW0pID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbkl0ZW1EZWxldGUoSVBXTF9Ob3RlSXRlbSogcEl0ZW0pID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPblNldEF1dGhvck5hbWUoSVBXTF9Ob3RlSXRlbSogcEl0ZW0pID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPblNldEJrQ29sb3IoSVBXTF9Ob3RlSXRlbSogcEl0ZW0pID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPblNldENvbnRlbnRzKElQV0xfTm90ZUl0ZW0qIHBJdGVtKSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJT25TZXREYXRlVGltZShJUFdMX05vdGVJdGVtKiBwSXRlbSkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCU9uU2V0U3ViamVjdE5hbWUoSVBXTF9Ob3RlSXRlbSogcEl0ZW0pID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPblBvcHVwTWVudShGWF9JTlQzMiB4LCBGWF9JTlQzMiB5KSA9IDA7CisJdmlydHVhbCB2b2lkCQkJCQkJT25Qb3B1cE1lbnUoSVBXTF9Ob3RlSXRlbSogcEl0ZW0sIEZYX0lOVDMyIHgsIEZYX0lOVDMyIHkpID0gMDsKK307CisKK2NsYXNzIElQV0xfTm90ZUhhbmRsZXIKK3sKK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbk5vdGVDb2xvckNoYW5nZWQoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpID0gMDsKK307CisKK2NsYXNzIElQV0xfTm90ZUl0ZW0KK3sKK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRQcml2YXRlRGF0YSh2b2lkKiBwRGF0YSkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCVNldEJrQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRBdXRob3JOYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCVNldERhdGVUaW1lKEZYX1NZU1RFTVRJTUUgdGltZSkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCVNldENvbnRlbnRzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzQ29udGVudHMpID0gMDsKKworCXZpcnR1YWwgSVBXTF9Ob3RlSXRlbSoJCQkJQ3JlYXRlU3ViSXRlbSgpID0gMDsKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJCQlDb3VudFN1Ykl0ZW1zKCkgY29uc3QgPSAwOworCXZpcnR1YWwgSVBXTF9Ob3RlSXRlbSoJCQkJR2V0U3ViSXRlbXMoRlhfSU5UMzIgaW5kZXgpIGNvbnN0ID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCVNldEZvY3VzKCkgPSAwOworCQorCXZpcnR1YWwgSVBXTF9Ob3RlSXRlbSoJCQkJR2V0UGFyZW50SXRlbSgpIGNvbnN0ID0gMDsKKwl2aXJ0dWFsIHZvaWQqCQkJCQkJR2V0UHJpdmF0ZURhdGEoKSBjb25zdCA9IDA7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQlHZXRBdXRob3JOYW1lKCkgY29uc3QgPSAwOworCXZpcnR1YWwgQ1BXTF9Db2xvcgkJCQkJR2V0QmtDb2xvcigpIGNvbnN0ID0gMDsKKwl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQkJCUdldENvbnRlbnRzKCkgY29uc3QgPSAwOworCXZpcnR1YWwgRlhfU1lTVEVNVElNRQkJCQlHZXREYXRlVGltZSgpIGNvbnN0ID0gMDsKKwl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQkJCUdldFN1YmplY3ROYW1lKCkgY29uc3QgPSAwOworCisJdmlydHVhbCBDUFdMX0VkaXQqCQkJCQlHZXRFZGl0KCkgY29uc3QgPSAwOworfTsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfTm90ZV9JY29uIDogcHVibGljIENQV0xfV25kCit7CitwdWJsaWM6CisJQ1BXTF9Ob3RlX0ljb24oKTsKKwl2aXJ0dWFsIH5DUFdMX05vdGVfSWNvbigpOworCisJdm9pZAkJCQkJCQkJU2V0SWNvblR5cGUoRlhfSU5UMzIgblR5cGUpOworCitwdWJsaWM6CisKK3Byb3RlY3RlZDoKKwl2aXJ0dWFsIHZvaWQJCQkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7CisKK3ByaXZhdGU6CisJRlhfSU5UMzIJCQkJCQkJbV9uVHlwZTsKK307CisKK2NsYXNzIENQV0xfTm90ZV9DbG9zZUJveCA6IHB1YmxpYyBDUFdMX0J1dHRvbgoreworcHVibGljOgorCUNQV0xfTm90ZV9DbG9zZUJveCgpOworCXZpcnR1YWwgfkNQV0xfTm90ZV9DbG9zZUJveCgpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisKK3ByaXZhdGU6CisJRlhfQk9PTAkJCQkJCQkJbV9iTW91c2VEb3duOworfTsKKworY2xhc3MgQ1BXTF9Ob3RlX0xCQm94IDogcHVibGljIENQV0xfV25kCit7CitwdWJsaWM6CisJQ1BXTF9Ob3RlX0xCQm94KCk7CisJdmlydHVhbCB+Q1BXTF9Ob3RlX0xCQm94KCk7CisKK3Byb3RlY3RlZDoKKwl2aXJ0dWFsIHZvaWQJCQkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7Cit9OworCitjbGFzcyBDUFdMX05vdGVfUkJCb3ggOiBwdWJsaWMgQ1BXTF9XbmQKK3sKK3B1YmxpYzoKKwlDUFdMX05vdGVfUkJCb3goKTsKKwl2aXJ0dWFsIH5DUFdMX05vdGVfUkJCb3goKTsKKworcHJvdGVjdGVkOgorCXZpcnR1YWwgdm9pZAkJCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsKK307CisKK2NsYXNzIENQV0xfTm90ZV9FZGl0IDogcHVibGljIENQV0xfRWRpdAoreworcHVibGljOgorCUNQV0xfTm90ZV9FZGl0KCk7CisJdmlydHVhbCB+Q1BXTF9Ob3RlX0VkaXQoKTsKKworCXZvaWQJCQkJCQkJCUVuYWJsZU5vdGlmeShGWF9CT09MIGJFbmFibGUpIHttX2JFbmFibGVOb3RpZnkgPSBiRW5hYmxlO30KKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQlHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKTsKKwlGWF9GTE9BVAkJCQkJCQlHZXRJdGVtTGVmdE1hcmdpbigpOworCUZYX0ZMT0FUCQkJCQkJCUdldEl0ZW1SaWdodE1hcmdpbigpOworCisJdmlydHVhbCB2b2lkCQkJCQkJU2V0VGV4dChGWF9MUENXU1RSIGNzVGV4dCk7CisKK3Byb3RlY3RlZDoKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOworCXZpcnR1YWwgdm9pZAkJCQkJCVJlUG9zQ2hpbGRXbmQoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPblNldEZvY3VzKCk7CisJdmlydHVhbCB2b2lkCQkJCQkJT25LaWxsRm9jdXMoKTsJCisKK3ByaXZhdGU6CisJRlhfQk9PTAkJCQkJCQkJbV9iRW5hYmxlTm90aWZ5OworCUZYX0ZMT0FUCQkJCQkJCW1fZk9sZEl0ZW1IZWlnaHQ7CisJRlhfQk9PTAkJCQkJCQkJbV9iU2l6ZUNoYW5nZWQ7CisJRlhfRkxPQVQJCQkJCQkJbV9mT2xkTWluOworCUZYX0ZMT0FUCQkJCQkJCW1fZk9sZE1heDsKK307CisKK2NsYXNzIENQV0xfTm90ZV9PcHRpb25zIDogcHVibGljIENQV0xfV25kCit7CitwdWJsaWM6CisJQ1BXTF9Ob3RlX09wdGlvbnMoKTsKKwl2aXJ0dWFsIH5DUFdMX05vdGVfT3B0aW9ucygpOworCisJQ1BERl9SZWN0CQkJCQkJCUdldENvbnRlbnRSZWN0KCkgY29uc3Q7CisJdmlydHVhbCB2b2lkCQkJCQkJU2V0VGV4dENvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcik7CisJdm9pZAkJCQkJCQkJU2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQkJUmVQb3NDaGlsZFduZCgpOworCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7CisKK3ByaXZhdGU6CisJQ1BXTF9MYWJlbCoJCQkJCQkJbV9wVGV4dDsKK307CisKK2NsYXNzIENQV0xfTm90ZV9Db250ZW50cyA6IHB1YmxpYyBDUFdMX0xpc3RDdHJsCit7CitwdWJsaWM6CisJQ1BXTF9Ob3RlX0NvbnRlbnRzKCk7CisJdmlydHVhbCB+Q1BXTF9Ob3RlX0NvbnRlbnRzKCk7CisKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJCUdldENsYXNzTmFtZSgpIGNvbnN0OworCXZpcnR1YWwgdm9pZAkJCQkJCU9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0gPSAwLCBGWF9JTlRQVFIgbFBhcmFtID0gMCk7CisJdmlydHVhbCBGWF9CT09MCQkJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCisJdm9pZAkJCQkJCQkJU2V0RWRpdEZvY3VzKEZYX0JPT0wgYkxhc3QpOworCUNQV0xfRWRpdCoJCQkJCQkJR2V0RWRpdCgpIGNvbnN0OworCitwdWJsaWM6CisJdm9pZAkJCQkJCQkJU2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpOworCUNGWF9XaWRlU3RyaW5nCQkJCQkJR2V0VGV4dCgpIGNvbnN0OworCisJQ1BXTF9Ob3RlSXRlbSoJCQkJCQlDcmVhdGVTdWJJdGVtKCk7CisJdm9pZAkJCQkJCQkJRGVsZXRlU3ViSXRlbShJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0pOworCUZYX0lOVDMyCQkJCQkJCUNvdW50U3ViSXRlbXMoKSBjb25zdDsKKwlJUFdMX05vdGVJdGVtKgkJCQkJCUdldFN1Ykl0ZW1zKEZYX0lOVDMyIGluZGV4KSBjb25zdDsKKworCXZpcnR1YWwgSVBXTF9Ob3RlSXRlbSoJCQkJR2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpOworCXZvaWQJCQkJCQkJCUVuYWJsZVJlYWQoRlhfQk9PTCBiRW5hYmxlZCk7CisJdm9pZAkJCQkJCQkJRW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQkJQ3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApOworCitwcml2YXRlOgorCUNQV0xfTm90ZV9FZGl0KgkJCQkJCW1fcEVkaXQ7Cit9OworCitjbGFzcyBQV0xfQ0xBU1MgQ1BXTF9Ob3RlSXRlbSA6IHB1YmxpYyBDUFdMX1duZCwgcHVibGljIElQV0xfTm90ZUl0ZW0gCit7CitwdWJsaWM6CisJQ1BXTF9Ob3RlSXRlbSgpOworCXZpcnR1YWwgfkNQV0xfTm90ZUl0ZW0oKTsKKworcHVibGljOgorCXZpcnR1YWwgdm9pZAkJCQkJCVNldFByaXZhdGVEYXRhKHZvaWQqIHBEYXRhKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpOworCXZpcnR1YWwgdm9pZAkJCQkJCVNldEF1dGhvck5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlTZXREYXRlVGltZShGWF9TWVNURU1USU1FIHRpbWUpOworCXZpcnR1YWwgdm9pZAkJCQkJCVNldENvbnRlbnRzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzQ29udGVudHMpOworCisJdmlydHVhbCBJUFdMX05vdGVJdGVtKgkJCQlDcmVhdGVTdWJJdGVtKCk7CisJdmlydHVhbCBGWF9JTlQzMgkJCQkJQ291bnRTdWJJdGVtcygpIGNvbnN0OworCXZpcnR1YWwgSVBXTF9Ob3RlSXRlbSoJCQkJR2V0U3ViSXRlbXMoRlhfSU5UMzIgaW5kZXgpIGNvbnN0OworCXZpcnR1YWwgdm9pZAkJCQkJCURlbGV0ZVN1Ykl0ZW0oSVBXTF9Ob3RlSXRlbSogcE5vdGVJdGVtKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRGb2N1cygpe1NldE5vdGVGb2N1cyhGQUxTRSk7fQorCisJdmlydHVhbCBJUFdMX05vdGVJdGVtKgkJCQlHZXRQYXJlbnRJdGVtKCkgY29uc3Q7CisJdmlydHVhbCB2b2lkKgkJCQkJCUdldFByaXZhdGVEYXRhKCkgY29uc3Q7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQlHZXRBdXRob3JOYW1lKCkgY29uc3Q7CisJdmlydHVhbCBDUFdMX0NvbG9yCQkJCQlHZXRCa0NvbG9yKCkgY29uc3Q7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQlHZXRDb250ZW50cygpIGNvbnN0OworCXZpcnR1YWwgRlhfU1lTVEVNVElNRQkJCQlHZXREYXRlVGltZSgpIGNvbnN0OworCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCQkJR2V0U3ViamVjdE5hbWUoKSBjb25zdDsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQlJc1RvcEl0ZW0oKSBjb25zdCB7IHJldHVybiBGQUxTRTt9CisJdmlydHVhbCBDUFdMX0VkaXQqCQkJCQlHZXRFZGl0KCkgY29uc3Q7CisKK3B1YmxpYzoKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQkJT25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJCQlHZXRDbGFzc05hbWUoKSBjb25zdDsKKwl2aXJ0dWFsIElQV0xfTm90ZUl0ZW0qCQkJCUdldEhpdE5vdGVJdGVtKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKwl2aXJ0dWFsIElQV0xfTm90ZUl0ZW0qCQkJCUdldEZvY3VzZWROb3RlSXRlbSgpIGNvbnN0OworCisJdmlydHVhbCB2b2lkCQkJCQkJUmVzZXRTdWJqZWN0TmFtZShGWF9JTlQzMiBuSXRlbUluZGV4KTsKKwl2b2lkCQkJCQkJCQlFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpOworCXZvaWQJCQkJCQkJCUVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKTsKKworcHJvdGVjdGVkOgorCXZpcnR1YWwgdm9pZAkJCQkJCVJlUG9zQ2hpbGRXbmQoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7CisKKwl2aXJ0dWFsIHZvaWQJCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOworCitwdWJsaWM6CisJdmlydHVhbCBGWF9GTE9BVAkJCQkJR2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCk7CisJdmlydHVhbCBGWF9GTE9BVAkJCQkJR2V0SXRlbUxlZnRNYXJnaW4oKTsKKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJCQlHZXRJdGVtUmlnaHRNYXJnaW4oKTsKKwlDUFdMX05vdGVJdGVtKgkJCQkJCUNyZWF0ZU5vdGVJdGVtKCk7CisJQ1BXTF9Ob3RlSXRlbSoJCQkJCQlHZXRQYXJlbnROb3RlSXRlbSgpIGNvbnN0OworCisJdm9pZAkJCQkJCQkJU2V0Tm90ZUZvY3VzKEZYX0JPT0wgYkxhc3QpOworCXZvaWQJCQkJCQkJCU9uQ29udGVudHNWYWxpZGF0ZSgpOworCQorCXZvaWQJCQkJCQkJCU9uQ3JlYXRlTm90ZUl0ZW0oKTsKKworcHJvdGVjdGVkOgorCXZvaWQJCQkJCQkJCVBvcHVwTm90ZUl0ZW1NZW51KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KTsKKworCXZpcnR1YWwgY29uc3QgQ1BXTF9Ob3RlKgkJCUdldE5vdGUoKSBjb25zdDsKKwl2aXJ0dWFsIElQV0xfTm90ZU5vdGlmeSoJCQlHZXROb3RlTm90aWZ5KCkgY29uc3Q7CisKK3Byb3RlY3RlZDoKKwlDUFdMX0xhYmVsKgkJCQkJCQltX3BTdWJqZWN0OworCUNQV0xfTGFiZWwqCQkJCQkJCW1fcERhdGVUaW1lOworCUNQV0xfTm90ZV9Db250ZW50cyoJCQkJCW1fcENvbnRlbnRzOworCitwcml2YXRlOgorCXZvaWQqCQkJCQkJCQltX3BQcml2YXRlRGF0YTsKKwlGWF9TWVNURU1USU1FCQkJCQkJbV9kdE5vdGU7CisJQ0ZYX1dpZGVTdHJpbmcJCQkJCQltX3NBdXRob3I7CisKKwlGWF9GTE9BVAkJCQkJCQltX2ZPbGRJdGVtSGVpZ2h0OworCUZYX0JPT0wJCQkJCQkJCW1fYlNpemVDaGFuZ2VkOworCUZYX0JPT0wJCQkJCQkJCW1fYkFsbG93TW9kaWZ5OworfTsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfTm90ZSA6IHB1YmxpYyBDUFdMX05vdGVJdGVtCit7CitwdWJsaWM6CisJQ1BXTF9Ob3RlKElQb3B1cF9Ob3RlKiBwUG9wdXBOb3RlLCBJUFdMX05vdGVOb3RpZnkqIHBOb3RlTm90aWZ5LCBJUFdMX05vdGVIYW5kbGVyKiBwTm90ZUhhbmRsZXIpOworCXZpcnR1YWwgfkNQV0xfTm90ZSgpOworCitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCQkJU2V0U3ViamVjdE5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlTZXRBdXRob3JOYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSk7CisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQlHZXRBdXRob3JOYW1lKCkgY29uc3Q7CisJdmlydHVhbCB2b2lkCQkJCQkJU2V0QmtDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7CisJdmlydHVhbCB2b2lkCQkJCQkJUmVzZXRTdWJqZWN0TmFtZShGWF9JTlQzMiBuSXRlbUluZGV4KXt9CisJdmlydHVhbCBGWF9CT09MCQkJCQkJSXNUb3BJdGVtKCkgY29uc3Qge3JldHVybiBUUlVFO30KKwl2aXJ0dWFsIGNvbnN0IENQV0xfTm90ZSoJCQlHZXROb3RlKCkgY29uc3Q7CisJdmlydHVhbCBJUFdMX05vdGVOb3RpZnkqCQkJR2V0Tm90ZU5vdGlmeSgpIGNvbnN0OworCitwdWJsaWM6CisJSVBXTF9Ob3RlSXRlbSoJCQkJCQlSZXBseSgpOworCXZvaWQJCQkJCQkJCUVuYWJsZU5vdGlmeShGWF9CT09MIGJFbmFibGVkKTsKKwl2b2lkCQkJCQkJCQlTZXRJY29uVHlwZShGWF9JTlQzMiBuVHlwZSk7CisJdm9pZAkJCQkJCQkJU2V0T3B0aW9uc1RleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUZXh0KTsKKwl2b2lkCQkJCQkJCQlFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpOworCXZvaWQJCQkJCQkJCUVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKTsKKworCUNGWF9XaWRlU3RyaW5nCQkJCQkJR2V0UmVwbHlTdHJpbmcoKSBjb25zdDsKKwl2b2lkCQkJCQkJCQlTZXRSZXBseVN0cmluZyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKTsKKworCS8vMC1ub3JtYWwgLyAxLWNhcHRpb24gLyAyLWxlZnRib3R0b20gY29ybmVyIC8gMy1yaWdodGJvdHRvbSBjb3JuZXIgLyA0LWNsb3NlIC8gNS1vcHRpb25zIAorCUZYX0lOVDMyCQkJCQkJCU5vdGVIaXRUZXN0KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdDsKKwlDUERGX1JlY3QJCQkJCQkJR2V0Q2FwdGlvblJlY3QoKSBjb25zdCB7cmV0dXJuIG1fcmNDYXB0aW9uO30KKwlJUG9wdXBfTm90ZSoJCQkJCQlHZXRQb3B1cE5vdGUoKSBjb25zdCB7cmV0dXJuIG1fcFBvcHVwTm90ZTt9CisKK3B1YmxpYzoKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCU9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJCU9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQkJUmVQb3NDaGlsZFduZCgpOworCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKworCXZpcnR1YWwgdm9pZAkJCQkJCU9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0gPSAwLCBGWF9JTlRQVFIgbFBhcmFtID0gMCk7CisKKwlGWF9CT09MCQkJCQkJCQlSZXNldFNjcm9sbEJhcigpOworCXZvaWQJCQkJCQkJCVJlUG9zTm90ZUNoaWxkcmVuKCk7CisJRlhfQk9PTAkJCQkJCQkJU2Nyb2xsQmFyU2hvdWxkVmlzaWJsZSgpOworCitwcml2YXRlOgorCUNQV0xfTGFiZWwqCQkJCQkJCW1fcEF1dGhvcjsKKwlDUFdMX05vdGVfSWNvbioJCQkJCQltX3BJY29uOworCUNQV0xfTm90ZV9DbG9zZUJveCoJCQkJCW1fcENsb3NlQm94OworCUNQV0xfTm90ZV9MQkJveCoJCQkJCW1fcExCQm94OworCUNQV0xfTm90ZV9SQkJveCoJCQkJCW1fcFJCQm94OworCUNQV0xfU2Nyb2xsQmFyKgkJCQkJCW1fcENvbnRlbnRzQmFyOwkKKwlDUFdMX05vdGVfT3B0aW9ucyoJCQkJCW1fcE9wdGlvbnM7CisJSVBXTF9Ob3RlTm90aWZ5KgkJCQkJbV9wTm90ZU5vdGlmeTsKKwlGWF9CT09MCQkJCQkJCQltX2JSZXNpemluZzsKKwlQV0xfU0NST0xMX0lORk8JCQkJCQltX09sZFNjcm9sbEluZm87CisJQ1BERl9SZWN0CQkJCQkJCW1fcmNDYXB0aW9uOworCUZYX0JPT0wJCQkJCQkJCW1fYkVuYWxibGVOb3RpZnk7CisJSVBvcHVwX05vdGUqCQkJCQkJbV9wUG9wdXBOb3RlOworCUlQV0xfTm90ZUhhbmRsZXIqCQkJCQltX3BOb3RlSGFuZGxlcjsKKwlDRlhfV2lkZVN0cmluZwkJCQkJCW1fc1JlcGx5U3RyaW5nOworfTsKKworI2VuZGlmCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIGIvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgKaW5kZXggMzE5NmIyMi4uZDI1NjU0MiAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgKQEAgLTEsMTY2ICsxLDE2NiBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfUFdMX1NDUk9MTEJBUl9IXw0KLSNkZWZpbmUgX1BXTF9TQ1JPTExCQVJfSF8NCi0NCi1jbGFzcyBDUFdMX1NCQnV0dG9uOw0KLWNsYXNzIENQV0xfU2Nyb2xsQmFyOw0KLQ0KLXN0cnVjdCBQV0xfU0NST0xMX0lORk8NCi17DQotcHVibGljOg0KLQlQV0xfU0NST0xMX0lORk8oKSA6IGZDb250ZW50TWluKDAuMGYpLCBmQ29udGVudE1heCgwLjBmKSwgZlBsYXRlV2lkdGgoMC4wZiksIGZCaWdTdGVwKDAuMGYpLCBmU21hbGxTdGVwKDAuMGYpDQotCXsNCi0JfQ0KLQlGWF9GTE9BVAkJCQkJZkNvbnRlbnRNaW47DQotCUZYX0ZMT0FUCQkJCQlmQ29udGVudE1heDsJDQotCUZYX0ZMT0FUCQkJCQlmUGxhdGVXaWR0aDsJDQotCUZYX0ZMT0FUCQkJCQlmQmlnU3RlcDsNCi0JRlhfRkxPQVQJCQkJCWZTbWFsbFN0ZXA7DQotfTsNCi0NCi1lbnVtIFBXTF9TQ1JPTExCQVJfVFlQRQ0KLXsNCi0JU0JUX0hTQ1JPTEwsDQotCVNCVF9WU0NST0xMDQotfTsNCi0NCi1lbnVtIFBXTF9TQkJVVFRPTl9UWVBFDQotew0KLQlQU0JUX01JTiwNCi0JUFNCVF9NQVgsDQotCVBTQlRfUE9TDQotfTsNCi0NCi1jbGFzcyBDUFdMX1NCQnV0dG9uIDogcHVibGljIENQV0xfV25kICANCi17DQotcHVibGljOg0KLQlDUFdMX1NCQnV0dG9uKFBXTF9TQ1JPTExCQVJfVFlQRSBlU2Nyb2xsQmFyVHlwZSxQV0xfU0JCVVRUT05fVFlQRSBlQnV0dG9uVHlwZSk7DQotCXZpcnR1YWwgfkNQV0xfU0JCdXR0b24oKTsNCi0NCi1wdWJsaWM6DQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCUdldENsYXNzTmFtZSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIHZvaWQJCQkJT25DcmVhdGUoUFdMX0NSRUFURVBBUkFNICYgY3ApOw0KLQl2aXJ0dWFsIHZvaWQJCQkJR2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSk7DQotCXZpcnR1YWwgdm9pZAkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0NCi1wcm90ZWN0ZWQ6DQotCVBXTF9TQ1JPTExCQVJfVFlQRQkJCW1fZVNjcm9sbEJhclR5cGU7DQotCVBXTF9TQkJVVFRPTl9UWVBFCQkJbV9lU0JCdXR0b25UeXBlOw0KLQ0KLQlGWF9CT09MCQkJCQkJbV9iTW91c2VEb3duOw0KLX07DQotDQotc3RydWN0IFBXTF9GTE9BVFJBTkdFDQotew0KLXB1YmxpYzoNCi0JUFdMX0ZMT0FUUkFOR0UoKTsNCi0JUFdMX0ZMT0FUUkFOR0UoRlhfRkxPQVQgbWluLEZYX0ZMT0FUIG1heCk7DQotCXZvaWQgRGVmYXVsdCgpOw0KLQl2b2lkIFNldChGWF9GTE9BVCBtaW4sRlhfRkxPQVQgbWF4KTsNCi0JRlhfQk9PTAlJbihGWF9GTE9BVCB4KSBjb25zdDsNCi0JRlhfRkxPQVQgR2V0V2lkdGgoKSBjb25zdDsNCi0NCi0JRlhfRkxPQVQgZk1pbixmTWF4Ow0KLX07DQotDQotc3RydWN0IFBXTF9TQ1JPTExfUFJJVkFURURBVEENCi17DQotcHVibGljOg0KLQlQV0xfU0NST0xMX1BSSVZBVEVEQVRBKCk7DQotDQotCXZvaWQgRGVmYXVsdCgpOw0KLQl2b2lkIFNldFNjcm9sbFJhbmdlKEZYX0ZMT0FUIG1pbixGWF9GTE9BVCBtYXgpOw0KLQl2b2lkIFNldENsaWVudFdpZHRoKEZYX0ZMT0FUIHdpZHRoKTsNCi0Jdm9pZCBTZXRTbWFsbFN0ZXAoRlhfRkxPQVQgc3RlcCk7DQotCXZvaWQgU2V0QmlnU3RlcChGWF9GTE9BVCBzdGVwKTsNCi0JRlhfQk9PTCBTZXRQb3MoRlhfRkxPQVQgcG9zKTsNCi0NCi0Jdm9pZCBBZGRTbWFsbCgpOw0KLQl2b2lkIFN1YlNtYWxsKCk7DQotCXZvaWQgQWRkQmlnKCk7DQotCXZvaWQgU3ViQmlnKCk7DQotDQotCVBXTF9GTE9BVFJBTkdFCQkJCVNjcm9sbFJhbmdlOw0KLQlGWF9GTE9BVAkJCQkJZkNsaWVudFdpZHRoOw0KLQlGWF9GTE9BVAkJCQkJZlNjcm9sbFBvczsNCi0JRlhfRkxPQVQJCQkJCWZCaWdTdGVwOw0KLQlGWF9GTE9BVAkJCQkJZlNtYWxsU3RlcDsNCi19Ow0KLQ0KLWNsYXNzIENQV0xfU2Nyb2xsQmFyIDogcHVibGljIENQV0xfV25kICANCi17DQotcHVibGljOg0KLQlDUFdMX1Njcm9sbEJhcihQV0xfU0NST0xMQkFSX1RZUEUgc2JUeXBlID0gU0JUX0hTQ1JPTEwpOw0KLQl2aXJ0dWFsIH5DUFdMX1Njcm9sbEJhcigpOw0KLQ0KLXB1YmxpYzoNCi0JdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7DQotCXZpcnR1YWwgdm9pZAkJCQlPbkNyZWF0ZShQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotCXZpcnR1YWwgdm9pZAkJCQlSZVBvc0NoaWxkV25kKCk7DQotCXZpcnR1YWwgdm9pZAkJCQlHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsNCi0JdmlydHVhbCB2b2lkCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsNCi0JdmlydHVhbCB2b2lkCQkJCU9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0gPSAwLCBGWF9JTlRQVFIgbFBhcmFtID0gMCk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQlDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotCQ0KLQlGWF9GTE9BVAkJCQkJR2V0U2Nyb2xsQmFyV2lkdGgoKSBjb25zdDsJDQotCVBXTF9TQ1JPTExCQVJfVFlQRQkJCUdldFNjcm9sbEJhclR5cGUoKSBjb25zdCB7cmV0dXJuIG1fc2JUeXBlO307DQotDQotCXZvaWQJCQkJCQlTZXROb3RpZnlGb3JldmVyKEZYX0JPT0wgYkZvcmV2ZXIpIHttX2JOb3RpZnlGb3JldmVyID0gYkZvcmV2ZXI7fQ0KLQ0KLXByb3RlY3RlZDoJCQkNCi0Jdm9pZAkJCQkJCVNldFNjcm9sbFJhbmdlKEZYX0ZMT0FUIGZNaW4sRlhfRkxPQVQgZk1heCxGWF9GTE9BVCBmQ2xpZW50V2lkdGgpOw0KLQl2b2lkCQkJCQkJU2V0U2Nyb2xsUG9zKEZYX0ZMT0FUIGZQb3MpOw0KLQl2b2lkCQkJCQkJTW92ZVBvc0J1dHRvbihGWF9CT09MIGJSZWZyZXNoKTsNCi0Jdm9pZAkJCQkJCVNldFNjcm9sbFN0ZXAoRlhfRkxPQVQgZkJpZ1N0ZXAsRlhfRkxPQVQgZlNtYWxsU3RlcCk7DQotCXZvaWQJCQkJCQlOb3RpZnlTY3JvbGxXaW5kb3coKTsNCi0JQ1BERl9SZWN0CQkJCQlHZXRTY3JvbGxBcmVhKCkgY29uc3Q7DQotDQotcHJpdmF0ZToNCi0Jdm9pZAkJCQkJCUNyZWF0ZUJ1dHRvbnMoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApOw0KLQ0KLQl2b2lkCQkJCQkJT25NaW5CdXR0b25MQkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsNCi0Jdm9pZAkJCQkJCU9uTWluQnV0dG9uTEJVcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOw0KLQl2b2lkCQkJCQkJT25NaW5CdXR0b25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsNCi0NCi0Jdm9pZAkJCQkJCU9uTWF4QnV0dG9uTEJEb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7DQotCXZvaWQJCQkJCQlPbk1heEJ1dHRvbkxCVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsNCi0Jdm9pZAkJCQkJCU9uTWF4QnV0dG9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7DQotDQotCXZvaWQJCQkJCQlPblBvc0J1dHRvbkxCRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOw0KLQl2b2lkCQkJCQkJT25Qb3NCdXR0b25MQlVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7DQotCXZvaWQJCQkJCQlPblBvc0J1dHRvbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOw0KLQ0KLQlGWF9GTE9BVAkJCQkJVHJ1ZVRvRmFjZShGWF9GTE9BVCk7DQotCUZYX0ZMT0FUCQkJCQlGYWNlVG9UcnVlKEZYX0ZMT0FUKTsNCi0NCi0JdmlydHVhbAl2b2lkCQkJCVRpbWVyUHJvYygpOw0KLQ0KLXByaXZhdGU6DQotCVBXTF9TQ1JPTExCQVJfVFlQRQkJCW1fc2JUeXBlOw0KLQlQV0xfU0NST0xMX0lORk8JCQkJbV9PcmlnaW5JbmZvOw0KLQlDUFdMX1NCQnV0dG9uKgkJCQltX3BNaW5CdXR0b247DQotCUNQV0xfU0JCdXR0b24qCQkJCW1fcE1heEJ1dHRvbjsNCi0JQ1BXTF9TQkJ1dHRvbioJCQkJbV9wUG9zQnV0dG9uOw0KLQlQV0xfU0NST0xMX1BSSVZBVEVEQVRBCQltX3NEYXRhOw0KLQlGWF9CT09MCQkJCQkJbV9iTW91c2VEb3duOwkNCi0JRlhfQk9PTAkJCQkJCW1fYk1pbk9yTWF4Ow0KLQlGWF9CT09MCQkJCQkJbV9iTm90aWZ5Rm9yZXZlcjsNCi0JRlhfRkxPQVQJCQkJCW1fbk9sZFBvczsNCi0JRlhfRkxPQVQJCQkJCW1fZk9sZFBvc0J1dHRvbjsNCi19Ow0KLQ0KLSNlbmRpZiAvLyAhZGVmaW5lZChBRlhfUFdMX1NDUk9MTEJBUl9IX19EQ0ZFQzA4Ml8yNjUxXzQ4QTRfQjhGM182M0YxQjNDQzVFMTBfX0lOQ0xVREVEXykNCi0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9QV0xfU0NST0xMQkFSX0hfCisjZGVmaW5lIF9QV0xfU0NST0xMQkFSX0hfCisKK2NsYXNzIENQV0xfU0JCdXR0b247CitjbGFzcyBDUFdMX1Njcm9sbEJhcjsKKworc3RydWN0IFBXTF9TQ1JPTExfSU5GTworeworcHVibGljOgorCVBXTF9TQ1JPTExfSU5GTygpIDogZkNvbnRlbnRNaW4oMC4wZiksIGZDb250ZW50TWF4KDAuMGYpLCBmUGxhdGVXaWR0aCgwLjBmKSwgZkJpZ1N0ZXAoMC4wZiksIGZTbWFsbFN0ZXAoMC4wZikKKwl7CisJfQorCUZYX0ZMT0FUCQkJCQlmQ29udGVudE1pbjsKKwlGWF9GTE9BVAkJCQkJZkNvbnRlbnRNYXg7CQorCUZYX0ZMT0FUCQkJCQlmUGxhdGVXaWR0aDsJCisJRlhfRkxPQVQJCQkJCWZCaWdTdGVwOworCUZYX0ZMT0FUCQkJCQlmU21hbGxTdGVwOworfTsKKworZW51bSBQV0xfU0NST0xMQkFSX1RZUEUKK3sKKwlTQlRfSFNDUk9MTCwKKwlTQlRfVlNDUk9MTAorfTsKKworZW51bSBQV0xfU0JCVVRUT05fVFlQRQoreworCVBTQlRfTUlOLAorCVBTQlRfTUFYLAorCVBTQlRfUE9TCit9OworCitjbGFzcyBDUFdMX1NCQnV0dG9uIDogcHVibGljIENQV0xfV25kICAKK3sKK3B1YmxpYzoKKwlDUFdMX1NCQnV0dG9uKFBXTF9TQ1JPTExCQVJfVFlQRSBlU2Nyb2xsQmFyVHlwZSxQV0xfU0JCVVRUT05fVFlQRSBlQnV0dG9uVHlwZSk7CisJdmlydHVhbCB+Q1BXTF9TQkJ1dHRvbigpOworCitwdWJsaWM6CisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CisJdmlydHVhbCB2b2lkCQkJCU9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIHZvaWQJCQkJR2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSk7CisJdmlydHVhbCB2b2lkCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCitwcm90ZWN0ZWQ6CisJUFdMX1NDUk9MTEJBUl9UWVBFCQkJbV9lU2Nyb2xsQmFyVHlwZTsKKwlQV0xfU0JCVVRUT05fVFlQRQkJCW1fZVNCQnV0dG9uVHlwZTsKKworCUZYX0JPT0wJCQkJCQltX2JNb3VzZURvd247Cit9OworCitzdHJ1Y3QgUFdMX0ZMT0FUUkFOR0UKK3sKK3B1YmxpYzoKKwlQV0xfRkxPQVRSQU5HRSgpOworCVBXTF9GTE9BVFJBTkdFKEZYX0ZMT0FUIG1pbixGWF9GTE9BVCBtYXgpOworCXZvaWQgRGVmYXVsdCgpOworCXZvaWQgU2V0KEZYX0ZMT0FUIG1pbixGWF9GTE9BVCBtYXgpOworCUZYX0JPT0wJSW4oRlhfRkxPQVQgeCkgY29uc3Q7CisJRlhfRkxPQVQgR2V0V2lkdGgoKSBjb25zdDsKKworCUZYX0ZMT0FUIGZNaW4sZk1heDsKK307CisKK3N0cnVjdCBQV0xfU0NST0xMX1BSSVZBVEVEQVRBCit7CitwdWJsaWM6CisJUFdMX1NDUk9MTF9QUklWQVRFREFUQSgpOworCisJdm9pZCBEZWZhdWx0KCk7CisJdm9pZCBTZXRTY3JvbGxSYW5nZShGWF9GTE9BVCBtaW4sRlhfRkxPQVQgbWF4KTsKKwl2b2lkIFNldENsaWVudFdpZHRoKEZYX0ZMT0FUIHdpZHRoKTsKKwl2b2lkIFNldFNtYWxsU3RlcChGWF9GTE9BVCBzdGVwKTsKKwl2b2lkIFNldEJpZ1N0ZXAoRlhfRkxPQVQgc3RlcCk7CisJRlhfQk9PTCBTZXRQb3MoRlhfRkxPQVQgcG9zKTsKKworCXZvaWQgQWRkU21hbGwoKTsKKwl2b2lkIFN1YlNtYWxsKCk7CisJdm9pZCBBZGRCaWcoKTsKKwl2b2lkIFN1YkJpZygpOworCisJUFdMX0ZMT0FUUkFOR0UJCQkJU2Nyb2xsUmFuZ2U7CisJRlhfRkxPQVQJCQkJCWZDbGllbnRXaWR0aDsKKwlGWF9GTE9BVAkJCQkJZlNjcm9sbFBvczsKKwlGWF9GTE9BVAkJCQkJZkJpZ1N0ZXA7CisJRlhfRkxPQVQJCQkJCWZTbWFsbFN0ZXA7Cit9OworCitjbGFzcyBDUFdMX1Njcm9sbEJhciA6IHB1YmxpYyBDUFdMX1duZCAgCit7CitwdWJsaWM6CisJQ1BXTF9TY3JvbGxCYXIoUFdMX1NDUk9MTEJBUl9UWVBFIHNiVHlwZSA9IFNCVF9IU0NST0xMKTsKKwl2aXJ0dWFsIH5DUFdMX1Njcm9sbEJhcigpOworCitwdWJsaWM6CisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CisJdmlydHVhbCB2b2lkCQkJCU9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIHZvaWQJCQkJUmVQb3NDaGlsZFduZCgpOworCXZpcnR1YWwgdm9pZAkJCQlHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsKKwl2aXJ0dWFsIHZvaWQJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOworCisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgdm9pZAkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOworCisJdmlydHVhbCB2b2lkCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwkKKwlGWF9GTE9BVAkJCQkJR2V0U2Nyb2xsQmFyV2lkdGgoKSBjb25zdDsJCisJUFdMX1NDUk9MTEJBUl9UWVBFCQkJR2V0U2Nyb2xsQmFyVHlwZSgpIGNvbnN0IHtyZXR1cm4gbV9zYlR5cGU7fTsKKworCXZvaWQJCQkJCQlTZXROb3RpZnlGb3JldmVyKEZYX0JPT0wgYkZvcmV2ZXIpIHttX2JOb3RpZnlGb3JldmVyID0gYkZvcmV2ZXI7fQorCitwcm90ZWN0ZWQ6CQkJCisJdm9pZAkJCQkJCVNldFNjcm9sbFJhbmdlKEZYX0ZMT0FUIGZNaW4sRlhfRkxPQVQgZk1heCxGWF9GTE9BVCBmQ2xpZW50V2lkdGgpOworCXZvaWQJCQkJCQlTZXRTY3JvbGxQb3MoRlhfRkxPQVQgZlBvcyk7CisJdm9pZAkJCQkJCU1vdmVQb3NCdXR0b24oRlhfQk9PTCBiUmVmcmVzaCk7CisJdm9pZAkJCQkJCVNldFNjcm9sbFN0ZXAoRlhfRkxPQVQgZkJpZ1N0ZXAsRlhfRkxPQVQgZlNtYWxsU3RlcCk7CisJdm9pZAkJCQkJCU5vdGlmeVNjcm9sbFdpbmRvdygpOworCUNQREZfUmVjdAkJCQkJR2V0U2Nyb2xsQXJlYSgpIGNvbnN0OworCitwcml2YXRlOgorCXZvaWQJCQkJCQlDcmVhdGVCdXR0b25zKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKworCXZvaWQJCQkJCQlPbk1pbkJ1dHRvbkxCRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOworCXZvaWQJCQkJCQlPbk1pbkJ1dHRvbkxCVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsKKwl2b2lkCQkJCQkJT25NaW5CdXR0b25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsKKworCXZvaWQJCQkJCQlPbk1heEJ1dHRvbkxCRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOworCXZvaWQJCQkJCQlPbk1heEJ1dHRvbkxCVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsKKwl2b2lkCQkJCQkJT25NYXhCdXR0b25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsKKworCXZvaWQJCQkJCQlPblBvc0J1dHRvbkxCRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOworCXZvaWQJCQkJCQlPblBvc0J1dHRvbkxCVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsKKwl2b2lkCQkJCQkJT25Qb3NCdXR0b25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KTsKKworCUZYX0ZMT0FUCQkJCQlUcnVlVG9GYWNlKEZYX0ZMT0FUKTsKKwlGWF9GTE9BVAkJCQkJRmFjZVRvVHJ1ZShGWF9GTE9BVCk7CisKKwl2aXJ0dWFsCXZvaWQJCQkJVGltZXJQcm9jKCk7CisKK3ByaXZhdGU6CisJUFdMX1NDUk9MTEJBUl9UWVBFCQkJbV9zYlR5cGU7CisJUFdMX1NDUk9MTF9JTkZPCQkJCW1fT3JpZ2luSW5mbzsKKwlDUFdMX1NCQnV0dG9uKgkJCQltX3BNaW5CdXR0b247CisJQ1BXTF9TQkJ1dHRvbioJCQkJbV9wTWF4QnV0dG9uOworCUNQV0xfU0JCdXR0b24qCQkJCW1fcFBvc0J1dHRvbjsKKwlQV0xfU0NST0xMX1BSSVZBVEVEQVRBCQltX3NEYXRhOworCUZYX0JPT0wJCQkJCQltX2JNb3VzZURvd247CQorCUZYX0JPT0wJCQkJCQltX2JNaW5Pck1heDsKKwlGWF9CT09MCQkJCQkJbV9iTm90aWZ5Rm9yZXZlcjsKKwlGWF9GTE9BVAkJCQkJbV9uT2xkUG9zOworCUZYX0ZMT0FUCQkJCQltX2ZPbGRQb3NCdXR0b247Cit9OworCisjZW5kaWYgLy8gIWRlZmluZWQoQUZYX1BXTF9TQ1JPTExCQVJfSF9fRENGRUMwODJfMjY1MV80OEE0X0I4RjNfNjNGMUIzQ0M1RTEwX19JTkNMVURFRF8pCisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2lnbmF0dXJlLmggYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TaWduYXR1cmUuaAppbmRleCA3MTJmNzQwLi5lYzQ0NzliIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TaWduYXR1cmUuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TaWduYXR1cmUuaApAQCAtMSw2NyArMSw2NyBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2lmbmRlZiBfUFdMX1NJR05BVFVSRV9IXw0KLSNkZWZpbmUgX1BXTF9TSUdOQVRVUkVfSF8NCi0NCi1jbGFzcyBDUFdMX1NpZ25hdHVyZTsNCi1jbGFzcyBDUFdMX0xhYmVsOw0KLWNsYXNzIENQV0xfU2lnbmF0dXJlX0ltYWdlOw0KLQ0KLWNsYXNzIENQV0xfU2lnbmF0dXJlX0ltYWdlIDogcHVibGljIENQV0xfSW1hZ2UNCi17DQotcHVibGljOg0KLQlDUFdMX1NpZ25hdHVyZV9JbWFnZSgpOw0KLQl2aXJ0dWFsIH5DUFdMX1NpZ25hdHVyZV9JbWFnZSgpOw0KLQ0KLQl2b2lkCQkJCQkJCQlTZXRJbWFnZShDRlhfRElCU291cmNlKiBwSW1hZ2UpOw0KLQlDRlhfRElCU291cmNlKgkJCQkJCUdldEltYWdlKCk7DQotDQotcHJvdGVjdGVkOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCUdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pOw0KLQ0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlHZXRTY2FsZShGWF9GTE9BVCAmIGZIU2NhbGUsRlhfRkxPQVQgJiBmVlNjYWxlKTsNCi0NCi1wcml2YXRlOg0KLQlDRlhfRElCU291cmNlKgkJCQkJCW1fcEltYWdlOw0KLX07DQotDQotY2xhc3MgUFdMX0NMQVNTIENQV0xfU2lnbmF0dXJlIDogcHVibGljIENQV0xfV25kDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9TaWduYXR1cmUoKTsNCi0JdmlydHVhbCB+Q1BXTF9TaWduYXR1cmUoKTsNCi0NCi0Jdm9pZAkJCQkJCQkJU2V0VGV4dChGWF9MUENXU1RSIHNUZXh0KTsNCi0Jdm9pZAkJCQkJCQkJU2V0RGVzY3JpcHRpb24oRlhfTFBDV1NUUiBzdHJpbmcpOw0KLQl2b2lkCQkJCQkJCQlTZXRJbWFnZShDRlhfRElCU291cmNlKiBwSW1hZ2UpOw0KLQl2b2lkCQkJCQkJCQlTZXRJbWFnZVN0cmVhbShDUERGX1N0cmVhbSAqIHBTdHJlYW0sIEZYX0xQQ1NUUiBzSW1hZ2VBbGlhcyk7DQotDQotCXZvaWQJCQkJCQkJCVNldFRleHRGbGFnKEZYX0JPT0wgYlRleHRFeGlzdCk7DQotCXZvaWQJCQkJCQkJCVNldEltYWdlRmxhZyhGWF9CT09MIGJJbWFnZUV4aXN0KTsNCi0Jdm9pZAkJCQkJCQkJU2V0Rm94aXRGbGFnKEZYX0JPT0wgYkZsYWdFeGlzdCk7DQotDQotcHJvdGVjdGVkOg0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlSZVBvc0NoaWxkV25kKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCQlHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsNCi0NCi1wcml2YXRlOg0KLQlDUFdMX0xhYmVsKgkJCQkJCQltX3BUZXh0Ow0KLQlDUFdMX0xhYmVsKgkJCQkJCQltX3BEZXNjcmlwdGlvbjsNCi0JQ1BXTF9TaWduYXR1cmVfSW1hZ2UqCQkJCW1fcEltYWdlOw0KLQ0KLQlGWF9CT09MCQkJCQkJCQltX2JUZXh0RXhpc3Q7DQotCUZYX0JPT0wJCQkJCQkJCW1fYkltYWdlRXhpc3Q7DQotCUZYX0JPT0wJCQkJCQkJCW1fYkZsYWdFeGlzdDsNCi19Ow0KLQ0KLSNlbmRpZiAvLyBfUFdMX1NJR05BVFVSRV9IXw0KLQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1BXTF9TSUdOQVRVUkVfSF8KKyNkZWZpbmUgX1BXTF9TSUdOQVRVUkVfSF8KKworY2xhc3MgQ1BXTF9TaWduYXR1cmU7CitjbGFzcyBDUFdMX0xhYmVsOworY2xhc3MgQ1BXTF9TaWduYXR1cmVfSW1hZ2U7CisKK2NsYXNzIENQV0xfU2lnbmF0dXJlX0ltYWdlIDogcHVibGljIENQV0xfSW1hZ2UKK3sKK3B1YmxpYzoKKwlDUFdMX1NpZ25hdHVyZV9JbWFnZSgpOworCXZpcnR1YWwgfkNQV0xfU2lnbmF0dXJlX0ltYWdlKCk7CisKKwl2b2lkCQkJCQkJCQlTZXRJbWFnZShDRlhfRElCU291cmNlKiBwSW1hZ2UpOworCUNGWF9ESUJTb3VyY2UqCQkJCQkJR2V0SW1hZ2UoKTsKKworcHJvdGVjdGVkOgorCXZpcnR1YWwgdm9pZAkJCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsKKworCXZpcnR1YWwgdm9pZAkJCQkJCUdldFNjYWxlKEZYX0ZMT0FUICYgZkhTY2FsZSxGWF9GTE9BVCAmIGZWU2NhbGUpOworCitwcml2YXRlOgorCUNGWF9ESUJTb3VyY2UqCQkJCQkJbV9wSW1hZ2U7Cit9OworCitjbGFzcyBQV0xfQ0xBU1MgQ1BXTF9TaWduYXR1cmUgOiBwdWJsaWMgQ1BXTF9XbmQKK3sKK3B1YmxpYzoKKwlDUFdMX1NpZ25hdHVyZSgpOworCXZpcnR1YWwgfkNQV0xfU2lnbmF0dXJlKCk7CisKKwl2b2lkCQkJCQkJCQlTZXRUZXh0KEZYX0xQQ1dTVFIgc1RleHQpOworCXZvaWQJCQkJCQkJCVNldERlc2NyaXB0aW9uKEZYX0xQQ1dTVFIgc3RyaW5nKTsKKwl2b2lkCQkJCQkJCQlTZXRJbWFnZShDRlhfRElCU291cmNlKiBwSW1hZ2UpOworCXZvaWQJCQkJCQkJCVNldEltYWdlU3RyZWFtKENQREZfU3RyZWFtICogcFN0cmVhbSwgRlhfTFBDU1RSIHNJbWFnZUFsaWFzKTsKKworCXZvaWQJCQkJCQkJCVNldFRleHRGbGFnKEZYX0JPT0wgYlRleHRFeGlzdCk7CisJdm9pZAkJCQkJCQkJU2V0SW1hZ2VGbGFnKEZYX0JPT0wgYkltYWdlRXhpc3QpOworCXZvaWQJCQkJCQkJCVNldEZveGl0RmxhZyhGWF9CT09MIGJGbGFnRXhpc3QpOworCitwcm90ZWN0ZWQ6CisJdmlydHVhbCB2b2lkCQkJCQkJUmVQb3NDaGlsZFduZCgpOworCXZpcnR1YWwgdm9pZAkJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKworCXZpcnR1YWwgdm9pZAkJCQkJCURyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsKKworcHJpdmF0ZToKKwlDUFdMX0xhYmVsKgkJCQkJCQltX3BUZXh0OworCUNQV0xfTGFiZWwqCQkJCQkJCW1fcERlc2NyaXB0aW9uOworCUNQV0xfU2lnbmF0dXJlX0ltYWdlKgkJCQltX3BJbWFnZTsKKworCUZYX0JPT0wJCQkJCQkJCW1fYlRleHRFeGlzdDsKKwlGWF9CT09MCQkJCQkJCQltX2JJbWFnZUV4aXN0OworCUZYX0JPT0wJCQkJCQkJCW1fYkZsYWdFeGlzdDsKK307CisKKyNlbmRpZiAvLyBfUFdMX1NJR05BVFVSRV9IXworCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1NwZWNpYWxCdXR0b24uaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1NwZWNpYWxCdXR0b24uaAppbmRleCA1NTYxMzAxLi5hZTg4MmVhIDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TcGVjaWFsQnV0dG9uLmgKKysrIGIvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU3BlY2lhbEJ1dHRvbi5oCkBAIC0xLDYzICsxLDYzIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9QV0xfU1BFQ0lBTEJVVFRPTl9IXw0KLSNkZWZpbmUgX1BXTF9TUEVDSUFMQlVUVE9OX0hfDQotDQotI2lmIF9NU0NfVkVSID4gMTAwMA0KLSNwcmFnbWEgb25jZQ0KLSNlbmRpZiAvLyBfTVNDX1ZFUiA+IDEwMDANCi0NCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9QdXNoQnV0dG9uIDogcHVibGljIENQV0xfQnV0dG9uICANCi17DQotcHVibGljOg0KLQlDUFdMX1B1c2hCdXR0b24oKTsNCi0JdmlydHVhbCB+Q1BXTF9QdXNoQnV0dG9uKCk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXRDbGFzc05hbWUoKSBjb25zdDsNCi0JdmlydHVhbCBDUERGX1JlY3QJCQlHZXRGb2N1c1JlY3QoKSBjb25zdDsNCi19Ow0KLQ0KLWNsYXNzIFBXTF9DTEFTUyBDUFdMX0NoZWNrQm94IDogcHVibGljIENQV0xfQnV0dG9uDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9DaGVja0JveCgpOw0KLQl2aXJ0dWFsIH5DUFdMX0NoZWNrQm94KCk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXRDbGFzc05hbWUoKSBjb25zdDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoRlhfV09SRCBuQ2hhcik7DQotDQotCXZvaWQJCQkJCQlTZXRDaGVjayhGWF9CT09MIGJDaGVjayk7DQotCUZYX0JPT0wJCQkJCQlJc0NoZWNrZWQoKSBjb25zdDsNCi0NCi1wcml2YXRlOg0KLQlGWF9CT09MCQkJCQkJbV9iQ2hlY2tlZDsNCi19Ow0KLQ0KLWNsYXNzIFBXTF9DTEFTUyBDUFdMX1JhZGlvQnV0dG9uIDogcHVibGljIENQV0xfQnV0dG9uDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9SYWRpb0J1dHRvbigpOw0KLQl2aXJ0dWFsIH5DUFdMX1JhZGlvQnV0dG9uKCk7DQotDQotcHVibGljOg0KLQl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXRDbGFzc05hbWUoKSBjb25zdDsNCi0JdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlPbkNoYXIoRlhfV09SRCBuQ2hhcik7DQotDQotCXZvaWQJCQkJCQlTZXRDaGVjayhGWF9CT09MIGJDaGVjayk7DQotCUZYX0JPT0wJCQkJCQlJc0NoZWNrZWQoKSBjb25zdDsNCi0NCi1wcml2YXRlOg0KLQlGWF9CT09MCQkJCQkJbV9iQ2hlY2tlZDsNCi19Ow0KLQ0KLSNlbmRpZg0KLQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpZm5kZWYgX1BXTF9TUEVDSUFMQlVUVE9OX0hfCisjZGVmaW5lIF9QV0xfU1BFQ0lBTEJVVFRPTl9IXworCisjaWYgX01TQ19WRVIgPiAxMDAwCisjcHJhZ21hIG9uY2UKKyNlbmRpZiAvLyBfTVNDX1ZFUiA+IDEwMDAKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfUHVzaEJ1dHRvbiA6IHB1YmxpYyBDUFdMX0J1dHRvbiAgCit7CitwdWJsaWM6CisJQ1BXTF9QdXNoQnV0dG9uKCk7CisJdmlydHVhbCB+Q1BXTF9QdXNoQnV0dG9uKCk7CisKK3B1YmxpYzoKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQlHZXRDbGFzc05hbWUoKSBjb25zdDsKKwl2aXJ0dWFsIENQREZfUmVjdAkJCUdldEZvY3VzUmVjdCgpIGNvbnN0OworfTsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfQ2hlY2tCb3ggOiBwdWJsaWMgQ1BXTF9CdXR0b24KK3sKK3B1YmxpYzoKKwlDUFdMX0NoZWNrQm94KCk7CisJdmlydHVhbCB+Q1BXTF9DaGVja0JveCgpOworCitwdWJsaWM6CisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uQ2hhcihGWF9XT1JEIG5DaGFyKTsKKworCXZvaWQJCQkJCQlTZXRDaGVjayhGWF9CT09MIGJDaGVjayk7CisJRlhfQk9PTAkJCQkJCUlzQ2hlY2tlZCgpIGNvbnN0OworCitwcml2YXRlOgorCUZYX0JPT0wJCQkJCQltX2JDaGVja2VkOworfTsKKworY2xhc3MgUFdMX0NMQVNTIENQV0xfUmFkaW9CdXR0b24gOiBwdWJsaWMgQ1BXTF9CdXR0b24KK3sKK3B1YmxpYzoKKwlDUFdMX1JhZGlvQnV0dG9uKCk7CisJdmlydHVhbCB+Q1BXTF9SYWRpb0J1dHRvbigpOworCitwdWJsaWM6CisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCk7CisJdmlydHVhbCBGWF9CT09MCQkJCU9uQ2hhcihGWF9XT1JEIG5DaGFyKTsKKworCXZvaWQJCQkJCQlTZXRDaGVjayhGWF9CT09MIGJDaGVjayk7CisJRlhfQk9PTAkJCQkJCUlzQ2hlY2tlZCgpIGNvbnN0OworCitwcml2YXRlOgorCUZYX0JPT0wJCQkJCQltX2JDaGVja2VkOworfTsKKworI2VuZGlmCisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCBiL2ZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1V0aWxzLmgKaW5kZXggMmVjY2MzNi4uNDg5ZWI0YSAxMDA2NDQKLS0tIGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oCkBAIC0xLDIzNyArMSwyMzcgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpZm5kZWYgX1BXTF9VVElMU19IXw0KLSNkZWZpbmUgX1BXTF9VVElMU19IXw0KLQ0KLXRlbXBsYXRlPGNsYXNzIFQ+IFQgUFdMX01JTiAoY29uc3QgVCAmIGksIGNvbnN0IFQgJiBqKSB7IHJldHVybiAoKGkgPCBqKSA/IGkgOiBqKTsgfQ0KLXRlbXBsYXRlPGNsYXNzIFQ+IFQgUFdMX01BWCAoY29uc3QgVCAmIGksIGNvbnN0IFQgJiBqKSB7IHJldHVybiAoKGkgPiBqKSA/IGkgOiBqKTsgfQ0KLQ0KLSNkZWZpbmUgUFdMX1BERjJXSU4oY29sb3IpCQkJCQkoRlhfQllURShjb2xvcioyNTUpKQ0KLSNkZWZpbmUgUFdMX1dJTjJQREYoY29sb3IpCQkJCQkoKEZYX0ZMT0FUKSgoRlhfRkxPQVQpY29sb3IvMjU1LjBmKSkNCi0NCi0jZGVmaW5lIFBXTF9NQUtFRFdPUkQobG93LGhpZ2gpCQkJCSgoRlhfRFdPUkQpKChGWF9XT1JEKShsb3cpIHwgKEZYX0RXT1JEKSgoKEZYX1dPUkQpKGhpZ2gpKTw8MTYpKSkgDQotI2RlZmluZSBQV0xfR0VUTE9XV09SRChkd29yZCkJCQkJKChGWF9XT1JEKShkd29yZCkpDQotI2RlZmluZSBQV0xfR0VUSElHSFdPUkQoZHdvcmQpCQkJCSgoRlhfV09SRCkoZHdvcmQ+PjE2KSkNCi0NCi0jZGVmaW5lIFBXTF9JQ09OVFlQRV9DSEVDS01BUksJCQkJMA0KLSNkZWZpbmUgUFdMX0lDT05UWVBFX0NJUkNMRQkJCQkJMQ0KLSNkZWZpbmUgUFdMX0lDT05UWVBFX0NPTU1FTlQJCQkJMg0KLSNkZWZpbmUgUFdMX0lDT05UWVBFX0NST1NTCQkJCQkzDQotI2RlZmluZSBQV0xfSUNPTlRZUEVfSEVMUAkJCQkJNA0KLSNkZWZpbmUgUFdMX0lDT05UWVBFX0lOU0VSVFRFWFQJCQkJNQ0KLSNkZWZpbmUgUFdMX0lDT05UWVBFX0tFWQkJCQkJNg0KLSNkZWZpbmUgUFdMX0lDT05UWVBFX05FV1BBUkFHUkFQSAkJCTcNCi0jZGVmaW5lIFBXTF9JQ09OVFlQRV9URVhUTk9URQkJCQk4DQotI2RlZmluZSBQV0xfSUNPTlRZUEVfUEFSQUdSQVBICQkJCTkNCi0jZGVmaW5lIFBXTF9JQ09OVFlQRV9SSUdIVEFSUk9XCQkJCTEwDQotI2RlZmluZSBQV0xfSUNPTlRZUEVfUklHSFRQT0lOVEVSCQkJMTENCi0jZGVmaW5lIFBXTF9JQ09OVFlQRV9TVEFSCQkJCQkxMg0KLSNkZWZpbmUgUFdMX0lDT05UWVBFX1VQQVJST1cJCQkJMTMNCi0jZGVmaW5lIFBXTF9JQ09OVFlQRV9VUExFRlRBUlJPVwkJCTE0DQotDQotI2RlZmluZSBQV0xfSUNPTlRZUEVfR1JBUEgJCQkJCTE1DQotI2RlZmluZSBQV0xfSUNPTlRZUEVfUEFQRVJDTElQCQkJCTE2DQotI2RlZmluZSBQV0xfSUNPTlRZUEVfQVRUQUNITUVOVAkJCQkxNw0KLSNkZWZpbmUgUFdMX0lDT05UWVBFX1RBRwkJCQkJMTgNCi0NCi0jZGVmaW5lIFBXTF9JQ09OVFlQRV9GT1hJVAkJCQkJMTkNCi0NCi0jZGVmaW5lIFBXTF9JQ09OVFlQRV9VTktOT1dOCQkJCS0xDQotDQotLy9jaGVja2JveCAmIHJhZGlvYnV0dG9uIHN0eWxlDQotI2RlZmluZSBQQ1NfQ0hFQ0sJCQkJCQkJMA0KLSNkZWZpbmUgUENTX0NJUkNMRQkJCQkJCQkxDQotI2RlZmluZSBQQ1NfQ1JPU1MJCQkJCQkJMg0KLSNkZWZpbmUgUENTX0RJQU1PTkQJCQkJCQkJMw0KLSNkZWZpbmUgUENTX1NRVUFSRQkJCQkJCQk0DQotI2RlZmluZSBQQ1NfU1RBUgkJCQkJCQk1DQotDQotI2RlZmluZQlQV0xfUEkJCQkJCQkJCTMuMTQxNTkyNjUzNTg5NzlmDQotI2RlZmluZSBQV0xfQkVaSUVSCQkJCQkJCTAuNTUyMjg0NzQ5ODMwOGYNCi0NCi0vL3B1c2hidXR0b24gbGF5b3V0IHN0eWxlDQotI2RlZmluZSBQUEJMX0xBQkVMCQkJCQkJCTANCi0jZGVmaW5lIFBQQkxfSUNPTgkJCQkJCQkxDQotI2RlZmluZSBQUEJMX0lDT05UT1BMQUJFTEJPVFRPTQkJCQkyDQotI2RlZmluZQlQUEJMX0xBQkVMVE9QSUNPTkJPVFRPTQkJCQkzDQotI2RlZmluZQlQUEJMX0lDT05MRUZUTEFCRUxSSUdIVAkJCQk0DQotI2RlZmluZSBQUEJMX0xBQkVMTEVGVElDT05SSUdIVAkJCQk1DQotI2RlZmluZSBQUEJMX0xBQkVMT1ZFUklDT04JCQkJCTYNCi0NCi1jbGFzcyBDUFdMX1BvaW50IDogcHVibGljIENQREZfUG9pbnQNCi17DQotcHVibGljOg0KLQlDUFdMX1BvaW50KCkgOiBDUERGX1BvaW50KDAuMGYsMC4wZil7fQ0KLQlDUFdMX1BvaW50KEZYX0ZMT0FUIGZ4LCBGWF9GTE9BVCBmeSkgOiBDUERGX1BvaW50KGZ4LGZ5KSB7fQ0KLQlDUFdMX1BvaW50KGNvbnN0IENQV0xfUG9pbnQmIHBvaW50KSA6IENQREZfUG9pbnQocG9pbnQueCwgcG9pbnQueSkge30NCi19Ow0KLQ0KLWVudW0gUFdMX1BBVEhEQVRBX1RZUEUNCi17DQotCVBXTFBUX01PVkVUTywNCi0JUFdMUFRfTElORVRPLA0KLQlQV0xQVF9CRVpJRVJUTywNCi0JUFdMUFRfVU5LTk9XTg0KLX07DQotDQotZW51bSBQV0xfUEFUSF9UWVBFDQotew0KLQlQV0xQVF9QQVRIREFUQSwNCi0JUFdMUFRfU1RSRUFNDQotfTsNCi0NCi1jbGFzcyBDUFdMX1BhdGhEYXRhDQotew0KLXB1YmxpYzoNCi0JQ1BXTF9QYXRoRGF0YSgpIDogcG9pbnQoKSwgdHlwZShQV0xQVF9VTktOT1dOKXt9DQotCUNQV0xfUGF0aERhdGEoY29uc3QgQ1BXTF9Qb2ludCYgcHQsIFBXTF9QQVRIREFUQV9UWVBFIHRwKSA6IHBvaW50KHB0KSwgdHlwZSh0cCkge30NCi0NCi0JQ1BXTF9Qb2ludAkJCQkJCQkJcG9pbnQ7DQotCVBXTF9QQVRIREFUQV9UWVBFCQkJCQkJdHlwZTsNCi19Ow0KLQ0KLWNsYXNzIElQV0xfU3BlbGxDaGVjazsNCi0NCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9VdGlscw0KLXsNCi1wdWJsaWM6DQotCXN0YXRpYyBDUERGX1JlY3QJCQkJCQlJbmZsYXRlUmVjdChjb25zdCBDUERGX1JlY3QmIHJjUmVjdCwgRlhfRkxPQVQgZlNpemUpOw0KLQlzdGF0aWMgQ1BERl9SZWN0CQkJCQkJRGVmbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0JiByY1JlY3QsIEZYX0ZMT0FUIGZTaXplKTsNCi0Jc3RhdGljIEZYX0JPT0wJCQkJCQkJSW50ZXJzZWN0UmVjdChjb25zdCBDUERGX1JlY3QmIHJlY3QxLCBjb25zdCBDUERGX1JlY3QmIHJlY3QyKTsNCi0Jc3RhdGljIEZYX0JPT0wJCQkJCQkJQ29udGFpbnNSZWN0KGNvbnN0IENQREZfUmVjdCYgcmNQYXJlbnQsIGNvbnN0IENQREZfUmVjdCYgcmNDaGlsZCk7DQotCXN0YXRpYyBDUERGX1JlY3QJCQkJCQlTY2FsZVJlY3QoY29uc3QgQ1BERl9SZWN0JiByY1JlY3QsRlhfRkxPQVQgZlNjYWxlKTsNCi0Jc3RhdGljIENQVlRfV29yZFJhbmdlCQkJCQlPdmVybGFwV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjEsIGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjIpOw0KLQlzdGF0aWMgQ1BERl9SZWN0CQkJCQkJR2V0Q2VudGVyU3F1YXJlKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpOw0KLQlzdGF0aWMgQ1BXTF9Db2xvcgkJCQkJCVN1YnN0cmFjdENvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBzQ29sb3IsRlhfRkxPQVQgZkNvbG9yU3ViKTsNCi0Jc3RhdGljIENQV0xfQ29sb3IJCQkJCQlEZXZpZGVDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgc0NvbG9yLEZYX0ZMT0FUIGZDb2xvckRldmlkZSk7DQotCXN0YXRpYyBDUERGX1JlY3QJCQkJCQlNYXhSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QxLGNvbnN0IENQREZfUmVjdCAmIHJlY3QyKTsNCi0Jc3RhdGljIENQREZfUmVjdAkJCQkJCU9mZnNldFJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCxGWF9GTE9BVCB4LEZYX0ZMT0FUIHkpOw0KLQlzdGF0aWMgQ1BERl9Qb2ludAkJCQkJCU9mZnNldFBvaW50KGNvbnN0ICBDUERGX1BvaW50ICYgcG9pbnQsRlhfRkxPQVQgeCxGWF9GTE9BVCB5KTsNCi0Jc3RhdGljIEZYX0NPTE9SUkVGCQkJCQkJUFdMQ29sb3JUb0ZYQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IsIEZYX0lOVDMyIG5UcmFuc3BhcmFuY3kgPSAyNTUpOw0KLQlzdGF0aWMgRlhfQk9PTAkJCQkJCQlJc0JsYWNrT3JXaGl0ZShjb25zdCBDUFdMX0NvbG9yJiBjb2xvcik7DQotCXN0YXRpYyBDUFdMX0NvbG9yCQkJCQkJR2V0UmV2ZXJzZUNvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKTsNCi0NCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRDb2xvckFwcFN0cmVhbShjb25zdCBDUFdMX0NvbG9yICYgY29sb3IsY29uc3QgRlhfQk9PTCAmIGJGaWxsT3JTdHJva2UgPSBUUlVFKTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRCb3JkZXJBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgRlhfRkxPQVQgZldpZHRoLA0KLQkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3IgJiBjb2xvciwgY29uc3QgQ1BXTF9Db2xvciAmIGNyTGVmdFRvcCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyUmlnaHRCb3R0b20sDQotCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLCBjb25zdCBDUFdMX0Rhc2ggJiBkYXNoKTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRDaXJjbGVCb3JkZXJBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgRlhfRkxPQVQgZldpZHRoLA0KLQkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3IgJiBjb2xvciwgY29uc3QgQ1BXTF9Db2xvciAmIGNyTGVmdFRvcCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyUmlnaHRCb3R0b20sDQotCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLCBjb25zdCBDUFdMX0Rhc2ggJiBkYXNoKTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRSZWN0RmlsbEFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByZWN0LGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcik7DQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0Q2lyY2xlRmlsbEFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByZWN0LGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcik7DQotDQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0UHVzaEJ1dHRvbkFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsDQotCQkJCQkJCQkJCQkJCQlJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAsDQotCQkJCQkJCQkJCQkJCQlDUERGX1N0cmVhbSAqIHBJY29uU3RyZWFtLA0KLQkJCQkJCQkJCQkJCQkJQ1BERl9JY29uRml0ICYgSWNvbkZpdCwNCi0JCQkJCQkJCQkJCQkJCWNvbnN0IENGWF9XaWRlU3RyaW5nICYgc0xhYmVsLAkJCQkJCQkJCQkJCQkJDQotCQkJCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0LA0KLQkJCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkZvbnRTaXplLA0KLQkJCQkJCQkJCQkJCQkJRlhfSU5UMzIgbkxheU91dCk7DQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0Q2hlY2tCb3hBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LA0KLQkJCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLA0KLQkJCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCk7DQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0UmFkaW9CdXR0b25BcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LA0KLQkJCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLA0KLQkJCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCk7DQotDQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0RWRpdEFwcFN0cmVhbShJRlhfRWRpdCogcEVkaXQsIGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UgPSBOVUxMLCANCi0JCQkJCQkJCQkJCQkJCUZYX0JPT0wgYkNvbnRpbnVvdXMgPSBUUlVFLCBGWF9XT1JEIFN1YldvcmQgPSAwKTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRFZGl0U2VsQXBwU3RyZWFtKElGWF9FZGl0KiBwRWRpdCwgY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0LA0KLQkJCQkJCQkJCQkJCQkJY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UgPSBOVUxMKTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRTcGVsbENoZWNrQXBwU3RyZWFtKElGWF9FZGl0KiBwRWRpdCwgSVBXTF9TcGVsbENoZWNrKiBwU3BlbGxDaGVjaywNCi0JCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCwNCi0JCQkJCQkJCQkJCQkJCWNvbnN0IENQVlRfV29yZFJhbmdlICogcFJhbmdlID0gTlVMTCk7DQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0VGV4dEFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwLA0KLQkJCQkJCQkJCQkJCQkJY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBzVGV4dCwgRlhfSU5UMzIgbkFsaWdubWVudEgsIEZYX0lOVDMyIG5BbGlnbm1lbnRWLA0KLQkJCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkZvbnRTaXplLCBGWF9CT09MIGJNdWx0aUxpbmUsIEZYX0JPT0wgYkF1dG9SZXR1cm4sIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpOw0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldERyb3BCdXR0b25BcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94KTsNCi0NCi0Jc3RhdGljIHZvaWQJCQkJCQkJCURyYXdGaWxsUmVjdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLGNvbnN0IENQREZfUmVjdCAmIHJlY3QsDQotCQkJCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yICYgY29sb3IsIEZYX0lOVDMyIG5UcmFuc3BhcmFuY3kpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd0ZpbGxSZWN0KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQkJCQkJCQljb25zdCBDUERGX1JlY3QgJiByZWN0LGNvbnN0IEZYX0NPTE9SUkVGICYgY29sb3IpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd1N0cm9rZVJlY3QoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSxjb25zdCBDUERGX1JlY3QgJiByZWN0LA0KLQkJCQkJCQkJCQkJCQkJY29uc3QgRlhfQ09MT1JSRUYgJiBjb2xvciwgRlhfRkxPQVQgZldpZHRoKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCURyYXdTdHJva2VMaW5lKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQkJCQkJCQljb25zdCBDUERGX1BvaW50ICYgcHRNb3ZlVG8sIGNvbnN0IENQREZfUG9pbnQgJiBwdExpbmVUbywgY29uc3QgRlhfQ09MT1JSRUYgJiBjb2xvciwgRlhfRkxPQVQgZldpZHRoKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCURyYXdCb3JkZXIoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCQkJCQkJCQkJCQljb25zdCBDUERGX1JlY3QgJiByZWN0LCBGWF9GTE9BVCBmV2lkdGgsDQotCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLCBjb25zdCBDUFdMX0NvbG9yICYgY3JMZWZ0VG9wLCBjb25zdCBDUFdMX0NvbG9yICYgY3JSaWdodEJvdHRvbSwNCi0JCQkJCQkJCQkJCQlGWF9JTlQzMiBuU3R5bGUsIGNvbnN0IENQV0xfRGFzaCAmIGRhc2gsIEZYX0lOVDMyIG5UcmFuc3BhcmFuY3kpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd0ZpbGxBcmVhKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQkJCQkJCQljb25zdCBDUERGX1BvaW50KiBwUHRzLCBGWF9JTlQzMiBuQ291bnQsIGNvbnN0IEZYX0NPTE9SUkVGJiBjb2xvcik7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlEcmF3U2hhZG93KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQkJCQkJCQlGWF9CT09MIGJWZXJ0aWNhbCwgRlhfQk9PTCBiSG9yaXpvbnRhbCwgQ1BERl9SZWN0IHJlY3QsDQotCQkJCQkJCQkJCQkJCQlGWF9JTlQzMiBuVHJhbnNwYXJhbmN5LCBGWF9JTlQzMiBuU3RhcnRHcmF5LCBGWF9JTlQzMiBuRW5kR3JheSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlEcmF3RWRpdFNwZWxsQ2hlY2soQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwgSUZYX0VkaXQqIHBFZGl0LCANCi0JCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUmVjdCYgcmNDbGlwLCBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSwgDQotCQkJCQkJCQkJCQkJCQlJUFdMX1NwZWxsQ2hlY2sqIHBTcGVsbENoZWNrKTsNCi1wdWJsaWM6DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlDb252ZXJ0Q01ZSzJSR0IoRlhfRkxPQVQgZEMsRlhfRkxPQVQgZE0sRlhfRkxPQVQgZFksRlhfRkxPQVQgZEssRlhfRkxPQVQgJmRSLEZYX0ZMT0FUICZkRyxGWF9GTE9BVCAmZEIpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJQ29udmVydFJHQjJDTVlLKEZYX0ZMT0FUIGRSLEZYX0ZMT0FUIGRHLEZYX0ZMT0FUIGRCLEZYX0ZMT0FUICZkQyxGWF9GTE9BVCAmZE0sRlhfRkxPQVQgJmRZLEZYX0ZMT0FUICZkSyk7DQotCQ0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJQ29udmVydFJHQjJHUkFZKEZYX0ZMT0FUIGRSLEZYX0ZMT0FUIGRHLEZYX0ZMT0FUIGRCLEZYX0ZMT0FUICZkR3JheSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlDb252ZXJ0R1JBWTJSR0IoRlhfRkxPQVQgZEdyYXksRlhfRkxPQVQgJmRSLEZYX0ZMT0FUICZkRyxGWF9GTE9BVCAmZEIpOw0KLQ0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJQ29udmVydENNWUsyR1JBWShGWF9GTE9BVCBkQyxGWF9GTE9BVCBkTSxGWF9GTE9BVCBkWSxGWF9GTE9BVCBkSyxGWF9GTE9BVCAmZEdyYXkpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJQ29udmVydEdSQVkyQ01ZSyhGWF9GTE9BVCBkR3JheSxGWF9GTE9BVCAmZEMsRlhfRkxPQVQgJmRNLEZYX0ZMT0FUICZkWSxGWF9GTE9BVCAmZEspOw0KLQ0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJUFdMQ29sb3JUb0FSR0IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IsIEZYX0lOVDMyJiBhbHBoYSwgRlhfRkxPQVQmIHJlZCwgRlhfRkxPQVQmIGdyZWVuLCBGWF9GTE9BVCYgYmx1ZSk7DQotDQotcHVibGljOg0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEljb25BcHBTdHJlYW0oRlhfSU5UMzIgblR5cGUsIGNvbnN0IENQREZfUmVjdCYgcmVjdCwgY29uc3QgQ1BXTF9Db2xvciYgY3JGaWxsLCANCi0JCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yJiBjclN0cm9rZSA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd0ljb25BcHBTdHJlYW0oQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCQkJCQkJCQkJCQlGWF9JTlQzMiBuVHlwZSwgY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgY29uc3QgQ1BXTF9Db2xvciYgY3JGaWxsLCANCi0JCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yJiBjclN0cm9rZSwgY29uc3QgRlhfSU5UMzIgblRyYW5zcGFyYW5jeSk7DQotDQotcHJpdmF0ZToNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoY29uc3QgQ1BXTF9QYXRoRGF0YSogcFBhdGhEYXRhLCBGWF9JTlQzMiBuQ291bnQpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0UGF0aERhdGFGcm9tQXJyYXkoQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUFdMX1BhdGhEYXRhKiBwUGF0aERhdGEsIEZYX0lOVDMyIG5Db3VudCk7DQotDQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0QXBwU3RyZWFtX0NoZWNrKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCk7DQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0QXBwU3RyZWFtX0NpcmNsZShjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpOw0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFwcFN0cmVhbV9Dcm9zcyhjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpOw0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFwcFN0cmVhbV9EaWFtb25kKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCk7DQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0QXBwU3RyZWFtX1NxdWFyZShjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpOw0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFwcFN0cmVhbV9TdGFyKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCk7DQotDQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0QVBfQ2hlY2soY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBUF9DaXJjbGUoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBUF9Dcm9zcyhjb25zdCBDUERGX1JlY3QgJiBjckJCb3gpOw0KLQlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFQX0RpYW1vbmQoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBUF9TcXVhcmUoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KTsNCi0Jc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBUF9TdGFyKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCk7DQotCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0QVBfSGFsZkNpcmNsZShjb25zdCBDUERGX1JlY3QgJiBjckJCb3gsRlhfRkxPQVQgZlJvdGF0ZSk7DQotDQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19DaGVja21hcmsoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX0NpcmNsZShDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfQ29tbWVudChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfQ3Jvc3MoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX0hlbHAoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX0luc2VydFRleHQoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX0tleShDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfTmV3UGFyYWdyYXBoKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19UZXh0Tm90ZShDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfUGFyYWdyYXBoKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19SaWdodEFycm93KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19SaWdodFBvaW50ZXIoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX1N0YXIoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX1VwQXJyb3coQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX1VwTGVmdEFycm93KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19HcmFwaChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOw0KLQlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfUGFwZXJjbGlwKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19BdHRhY2htZW50KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7DQotCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19UYWcoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsNCi0Jc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX0ZveGl0KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7DQotfTsNCi0NCi0jZW5kaWYgLy8gIWRlZmluZWQoQUZYX1BXTF9VVElMU19IX19EMzI4MTJBRF9BODc1XzRFMDhfOUQzQ18wQTU3MDIwOTg3QzZfX0lOQ0xVREVEXykNCi0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9QV0xfVVRJTFNfSF8KKyNkZWZpbmUgX1BXTF9VVElMU19IXworCit0ZW1wbGF0ZTxjbGFzcyBUPiBUIFBXTF9NSU4gKGNvbnN0IFQgJiBpLCBjb25zdCBUICYgaikgeyByZXR1cm4gKChpIDwgaikgPyBpIDogaik7IH0KK3RlbXBsYXRlPGNsYXNzIFQ+IFQgUFdMX01BWCAoY29uc3QgVCAmIGksIGNvbnN0IFQgJiBqKSB7IHJldHVybiAoKGkgPiBqKSA/IGkgOiBqKTsgfQorCisjZGVmaW5lIFBXTF9QREYyV0lOKGNvbG9yKQkJCQkJKEZYX0JZVEUoY29sb3IqMjU1KSkKKyNkZWZpbmUgUFdMX1dJTjJQREYoY29sb3IpCQkJCQkoKEZYX0ZMT0FUKSgoRlhfRkxPQVQpY29sb3IvMjU1LjBmKSkKKworI2RlZmluZSBQV0xfTUFLRURXT1JEKGxvdyxoaWdoKQkJCQkoKEZYX0RXT1JEKSgoRlhfV09SRCkobG93KSB8IChGWF9EV09SRCkoKChGWF9XT1JEKShoaWdoKSk8PDE2KSkpIAorI2RlZmluZSBQV0xfR0VUTE9XV09SRChkd29yZCkJCQkJKChGWF9XT1JEKShkd29yZCkpCisjZGVmaW5lIFBXTF9HRVRISUdIV09SRChkd29yZCkJCQkJKChGWF9XT1JEKShkd29yZD4+MTYpKQorCisjZGVmaW5lIFBXTF9JQ09OVFlQRV9DSEVDS01BUksJCQkJMAorI2RlZmluZSBQV0xfSUNPTlRZUEVfQ0lSQ0xFCQkJCQkxCisjZGVmaW5lIFBXTF9JQ09OVFlQRV9DT01NRU5UCQkJCTIKKyNkZWZpbmUgUFdMX0lDT05UWVBFX0NST1NTCQkJCQkzCisjZGVmaW5lIFBXTF9JQ09OVFlQRV9IRUxQCQkJCQk0CisjZGVmaW5lIFBXTF9JQ09OVFlQRV9JTlNFUlRURVhUCQkJCTUKKyNkZWZpbmUgUFdMX0lDT05UWVBFX0tFWQkJCQkJNgorI2RlZmluZSBQV0xfSUNPTlRZUEVfTkVXUEFSQUdSQVBICQkJNworI2RlZmluZSBQV0xfSUNPTlRZUEVfVEVYVE5PVEUJCQkJOAorI2RlZmluZSBQV0xfSUNPTlRZUEVfUEFSQUdSQVBICQkJCTkKKyNkZWZpbmUgUFdMX0lDT05UWVBFX1JJR0hUQVJST1cJCQkJMTAKKyNkZWZpbmUgUFdMX0lDT05UWVBFX1JJR0hUUE9JTlRFUgkJCTExCisjZGVmaW5lIFBXTF9JQ09OVFlQRV9TVEFSCQkJCQkxMgorI2RlZmluZSBQV0xfSUNPTlRZUEVfVVBBUlJPVwkJCQkxMworI2RlZmluZSBQV0xfSUNPTlRZUEVfVVBMRUZUQVJST1cJCQkxNAorCisjZGVmaW5lIFBXTF9JQ09OVFlQRV9HUkFQSAkJCQkJMTUKKyNkZWZpbmUgUFdMX0lDT05UWVBFX1BBUEVSQ0xJUAkJCQkxNgorI2RlZmluZSBQV0xfSUNPTlRZUEVfQVRUQUNITUVOVAkJCQkxNworI2RlZmluZSBQV0xfSUNPTlRZUEVfVEFHCQkJCQkxOAorCisjZGVmaW5lIFBXTF9JQ09OVFlQRV9GT1hJVAkJCQkJMTkKKworI2RlZmluZSBQV0xfSUNPTlRZUEVfVU5LTk9XTgkJCQktMQorCisvL2NoZWNrYm94ICYgcmFkaW9idXR0b24gc3R5bGUKKyNkZWZpbmUgUENTX0NIRUNLCQkJCQkJCTAKKyNkZWZpbmUgUENTX0NJUkNMRQkJCQkJCQkxCisjZGVmaW5lIFBDU19DUk9TUwkJCQkJCQkyCisjZGVmaW5lIFBDU19ESUFNT05ECQkJCQkJCTMKKyNkZWZpbmUgUENTX1NRVUFSRQkJCQkJCQk0CisjZGVmaW5lIFBDU19TVEFSCQkJCQkJCTUKKworI2RlZmluZQlQV0xfUEkJCQkJCQkJCTMuMTQxNTkyNjUzNTg5NzlmCisjZGVmaW5lIFBXTF9CRVpJRVIJCQkJCQkJMC41NTIyODQ3NDk4MzA4ZgorCisvL3B1c2hidXR0b24gbGF5b3V0IHN0eWxlCisjZGVmaW5lIFBQQkxfTEFCRUwJCQkJCQkJMAorI2RlZmluZSBQUEJMX0lDT04JCQkJCQkJMQorI2RlZmluZSBQUEJMX0lDT05UT1BMQUJFTEJPVFRPTQkJCQkyCisjZGVmaW5lCVBQQkxfTEFCRUxUT1BJQ09OQk9UVE9NCQkJCTMKKyNkZWZpbmUJUFBCTF9JQ09OTEVGVExBQkVMUklHSFQJCQkJNAorI2RlZmluZSBQUEJMX0xBQkVMTEVGVElDT05SSUdIVAkJCQk1CisjZGVmaW5lIFBQQkxfTEFCRUxPVkVSSUNPTgkJCQkJNgorCitjbGFzcyBDUFdMX1BvaW50IDogcHVibGljIENQREZfUG9pbnQKK3sKK3B1YmxpYzoKKwlDUFdMX1BvaW50KCkgOiBDUERGX1BvaW50KDAuMGYsMC4wZil7fQorCUNQV0xfUG9pbnQoRlhfRkxPQVQgZngsIEZYX0ZMT0FUIGZ5KSA6IENQREZfUG9pbnQoZngsZnkpIHt9CisJQ1BXTF9Qb2ludChjb25zdCBDUFdMX1BvaW50JiBwb2ludCkgOiBDUERGX1BvaW50KHBvaW50LngsIHBvaW50LnkpIHt9Cit9OworCitlbnVtIFBXTF9QQVRIREFUQV9UWVBFCit7CisJUFdMUFRfTU9WRVRPLAorCVBXTFBUX0xJTkVUTywKKwlQV0xQVF9CRVpJRVJUTywKKwlQV0xQVF9VTktOT1dOCit9OworCitlbnVtIFBXTF9QQVRIX1RZUEUKK3sKKwlQV0xQVF9QQVRIREFUQSwKKwlQV0xQVF9TVFJFQU0KK307CisKK2NsYXNzIENQV0xfUGF0aERhdGEKK3sKK3B1YmxpYzoKKwlDUFdMX1BhdGhEYXRhKCkgOiBwb2ludCgpLCB0eXBlKFBXTFBUX1VOS05PV04pe30KKwlDUFdMX1BhdGhEYXRhKGNvbnN0IENQV0xfUG9pbnQmIHB0LCBQV0xfUEFUSERBVEFfVFlQRSB0cCkgOiBwb2ludChwdCksIHR5cGUodHApIHt9CisKKwlDUFdMX1BvaW50CQkJCQkJCQlwb2ludDsKKwlQV0xfUEFUSERBVEFfVFlQRQkJCQkJCXR5cGU7Cit9OworCitjbGFzcyBJUFdMX1NwZWxsQ2hlY2s7CisKK2NsYXNzIFBXTF9DTEFTUyBDUFdMX1V0aWxzCit7CitwdWJsaWM6CisJc3RhdGljIENQREZfUmVjdAkJCQkJCUluZmxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCYgcmNSZWN0LCBGWF9GTE9BVCBmU2l6ZSk7CisJc3RhdGljIENQREZfUmVjdAkJCQkJCURlZmxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCYgcmNSZWN0LCBGWF9GTE9BVCBmU2l6ZSk7CisJc3RhdGljIEZYX0JPT0wJCQkJCQkJSW50ZXJzZWN0UmVjdChjb25zdCBDUERGX1JlY3QmIHJlY3QxLCBjb25zdCBDUERGX1JlY3QmIHJlY3QyKTsKKwlzdGF0aWMgRlhfQk9PTAkJCQkJCQlDb250YWluc1JlY3QoY29uc3QgQ1BERl9SZWN0JiByY1BhcmVudCwgY29uc3QgQ1BERl9SZWN0JiByY0NoaWxkKTsKKwlzdGF0aWMgQ1BERl9SZWN0CQkJCQkJU2NhbGVSZWN0KGNvbnN0IENQREZfUmVjdCYgcmNSZWN0LEZYX0ZMT0FUIGZTY2FsZSk7CisJc3RhdGljIENQVlRfV29yZFJhbmdlCQkJCQlPdmVybGFwV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjEsIGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjIpOworCXN0YXRpYyBDUERGX1JlY3QJCQkJCQlHZXRDZW50ZXJTcXVhcmUoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCk7CisJc3RhdGljIENQV0xfQ29sb3IJCQkJCQlTdWJzdHJhY3RDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgc0NvbG9yLEZYX0ZMT0FUIGZDb2xvclN1Yik7CisJc3RhdGljIENQV0xfQ29sb3IJCQkJCQlEZXZpZGVDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgc0NvbG9yLEZYX0ZMT0FUIGZDb2xvckRldmlkZSk7CisJc3RhdGljIENQREZfUmVjdAkJCQkJCU1heFJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdDEsY29uc3QgQ1BERl9SZWN0ICYgcmVjdDIpOworCXN0YXRpYyBDUERGX1JlY3QJCQkJCQlPZmZzZXRSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QsRlhfRkxPQVQgeCxGWF9GTE9BVCB5KTsKKwlzdGF0aWMgQ1BERl9Qb2ludAkJCQkJCU9mZnNldFBvaW50KGNvbnN0ICBDUERGX1BvaW50ICYgcG9pbnQsRlhfRkxPQVQgeCxGWF9GTE9BVCB5KTsKKwlzdGF0aWMgRlhfQ09MT1JSRUYJCQkJCQlQV0xDb2xvclRvRlhDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvciwgRlhfSU5UMzIgblRyYW5zcGFyYW5jeSA9IDI1NSk7CisJc3RhdGljIEZYX0JPT0wJCQkJCQkJSXNCbGFja09yV2hpdGUoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpOworCXN0YXRpYyBDUFdMX0NvbG9yCQkJCQkJR2V0UmV2ZXJzZUNvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKTsKKworCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0Q29sb3JBcHBTdHJlYW0oY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLGNvbnN0IEZYX0JPT0wgJiBiRmlsbE9yU3Ryb2tlID0gVFJVRSk7CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRCb3JkZXJBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgRlhfRkxPQVQgZldpZHRoLAorCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLCBjb25zdCBDUFdMX0NvbG9yICYgY3JMZWZ0VG9wLCBjb25zdCBDUFdMX0NvbG9yICYgY3JSaWdodEJvdHRvbSwKKwkJCQkJCQkJCQkJCUZYX0lOVDMyIG5TdHlsZSwgY29uc3QgQ1BXTF9EYXNoICYgZGFzaCk7CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRDaXJjbGVCb3JkZXJBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgRlhfRkxPQVQgZldpZHRoLAorCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLCBjb25zdCBDUFdMX0NvbG9yICYgY3JMZWZ0VG9wLCBjb25zdCBDUFdMX0NvbG9yICYgY3JSaWdodEJvdHRvbSwKKwkJCQkJCQkJCQkJCUZYX0lOVDMyIG5TdHlsZSwgY29uc3QgQ1BXTF9EYXNoICYgZGFzaCk7CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRSZWN0RmlsbEFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByZWN0LGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcik7CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRDaXJjbGVGaWxsQXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJlY3QsY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yKTsKKworCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0UHVzaEJ1dHRvbkFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsCisJCQkJCQkJCQkJCQkJCUlGWF9FZGl0X0ZvbnRNYXAgKiBwRm9udE1hcCwKKwkJCQkJCQkJCQkJCQkJQ1BERl9TdHJlYW0gKiBwSWNvblN0cmVhbSwKKwkJCQkJCQkJCQkJCQkJQ1BERl9JY29uRml0ICYgSWNvbkZpdCwKKwkJCQkJCQkJCQkJCQkJY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBzTGFiZWwsCQkJCQkJCQkJCQkJCQkKKwkJCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCwKKwkJCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkZvbnRTaXplLAorCQkJCQkJCQkJCQkJCQlGWF9JTlQzMiBuTGF5T3V0KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldENoZWNrQm94QXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwKKwkJCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLAorCQkJCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldFJhZGlvQnV0dG9uQXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwKKwkJCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLAorCQkJCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KTsKKworCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0RWRpdEFwcFN0cmVhbShJRlhfRWRpdCogcEVkaXQsIGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UgPSBOVUxMLCAKKwkJCQkJCQkJCQkJCQkJRlhfQk9PTCBiQ29udGludW91cyA9IFRSVUUsIEZYX1dPUkQgU3ViV29yZCA9IDApOworCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0RWRpdFNlbEFwcFN0cmVhbShJRlhfRWRpdCogcEVkaXQsIGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCwKKwkJCQkJCQkJCQkJCQkJY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UgPSBOVUxMKTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldFNwZWxsQ2hlY2tBcHBTdHJlYW0oSUZYX0VkaXQqIHBFZGl0LCBJUFdMX1NwZWxsQ2hlY2sqIHBTcGVsbENoZWNrLAorCQkJCQkJCQkJCQkJCQljb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQsCisJCQkJCQkJCQkJCQkJCWNvbnN0IENQVlRfV29yZFJhbmdlICogcFJhbmdlID0gTlVMTCk7CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRUZXh0QXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCxJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAsCisJCQkJCQkJCQkJCQkJCWNvbnN0IENGWF9XaWRlU3RyaW5nICYgc1RleHQsIEZYX0lOVDMyIG5BbGlnbm1lbnRILCBGWF9JTlQzMiBuQWxpZ25tZW50ViwKKwkJCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkZvbnRTaXplLCBGWF9CT09MIGJNdWx0aUxpbmUsIEZYX0JPT0wgYkF1dG9SZXR1cm4sIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpOworCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0RHJvcEJ1dHRvbkFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByY0JCb3gpOworCisJc3RhdGljIHZvaWQJCQkJCQkJCURyYXdGaWxsUmVjdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLGNvbnN0IENQREZfUmVjdCAmIHJlY3QsCisJCQkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3IgJiBjb2xvciwgRlhfSU5UMzIgblRyYW5zcGFyYW5jeSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCURyYXdGaWxsUmVjdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQkJCQkJCQkJCQkJCQljb25zdCBDUERGX1JlY3QgJiByZWN0LGNvbnN0IEZYX0NPTE9SUkVGICYgY29sb3IpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlEcmF3U3Ryb2tlUmVjdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLGNvbnN0IENQREZfUmVjdCAmIHJlY3QsCisJCQkJCQkJCQkJCQkJCWNvbnN0IEZYX0NPTE9SUkVGICYgY29sb3IsIEZYX0ZMT0FUIGZXaWR0aCk7CisJc3RhdGljIHZvaWQJCQkJCQkJCURyYXdTdHJva2VMaW5lKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQgJiBwdE1vdmVUbywgY29uc3QgQ1BERl9Qb2ludCAmIHB0TGluZVRvLCBjb25zdCBGWF9DT0xPUlJFRiAmIGNvbG9yLCBGWF9GTE9BVCBmV2lkdGgpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlEcmF3Qm9yZGVyKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkJCQkJCQljb25zdCBDUERGX1JlY3QgJiByZWN0LCBGWF9GTE9BVCBmV2lkdGgsCisJCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yICYgY29sb3IsIGNvbnN0IENQV0xfQ29sb3IgJiBjckxlZnRUb3AsIGNvbnN0IENQV0xfQ29sb3IgJiBjclJpZ2h0Qm90dG9tLAorCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLCBjb25zdCBDUFdMX0Rhc2ggJiBkYXNoLCBGWF9JTlQzMiBuVHJhbnNwYXJhbmN5KTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd0ZpbGxBcmVhKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQqIHBQdHMsIEZYX0lOVDMyIG5Db3VudCwgY29uc3QgRlhfQ09MT1JSRUYmIGNvbG9yKTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd1NoYWRvdyhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQkJCQkJCQkJCQkJCQlGWF9CT09MIGJWZXJ0aWNhbCwgRlhfQk9PTCBiSG9yaXpvbnRhbCwgQ1BERl9SZWN0IHJlY3QsCisJCQkJCQkJCQkJCQkJCUZYX0lOVDMyIG5UcmFuc3BhcmFuY3ksIEZYX0lOVDMyIG5TdGFydEdyYXksIEZYX0lOVDMyIG5FbmRHcmF5KTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJRHJhd0VkaXRTcGVsbENoZWNrKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsIElGWF9FZGl0KiBwRWRpdCwgCisJCQkJCQkJCQkJCQkJCWNvbnN0IENQREZfUmVjdCYgcmNDbGlwLCBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSwgCisJCQkJCQkJCQkJCQkJCUlQV0xfU3BlbGxDaGVjayogcFNwZWxsQ2hlY2spOworcHVibGljOgorCXN0YXRpYyB2b2lkCQkJCQkJCQlDb252ZXJ0Q01ZSzJSR0IoRlhfRkxPQVQgZEMsRlhfRkxPQVQgZE0sRlhfRkxPQVQgZFksRlhfRkxPQVQgZEssRlhfRkxPQVQgJmRSLEZYX0ZMT0FUICZkRyxGWF9GTE9BVCAmZEIpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlDb252ZXJ0UkdCMkNNWUsoRlhfRkxPQVQgZFIsRlhfRkxPQVQgZEcsRlhfRkxPQVQgZEIsRlhfRkxPQVQgJmRDLEZYX0ZMT0FUICZkTSxGWF9GTE9BVCAmZFksRlhfRkxPQVQgJmRLKTsKKwkKKwlzdGF0aWMgdm9pZAkJCQkJCQkJQ29udmVydFJHQjJHUkFZKEZYX0ZMT0FUIGRSLEZYX0ZMT0FUIGRHLEZYX0ZMT0FUIGRCLEZYX0ZMT0FUICZkR3JheSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUNvbnZlcnRHUkFZMlJHQihGWF9GTE9BVCBkR3JheSxGWF9GTE9BVCAmZFIsRlhfRkxPQVQgJmRHLEZYX0ZMT0FUICZkQik7CisKKwlzdGF0aWMgdm9pZAkJCQkJCQkJQ29udmVydENNWUsyR1JBWShGWF9GTE9BVCBkQyxGWF9GTE9BVCBkTSxGWF9GTE9BVCBkWSxGWF9GTE9BVCBkSyxGWF9GTE9BVCAmZEdyYXkpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlDb252ZXJ0R1JBWTJDTVlLKEZYX0ZMT0FUIGRHcmF5LEZYX0ZMT0FUICZkQyxGWF9GTE9BVCAmZE0sRlhfRkxPQVQgJmRZLEZYX0ZMT0FUICZkSyk7CisKKwlzdGF0aWMgdm9pZAkJCQkJCQkJUFdMQ29sb3JUb0FSR0IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IsIEZYX0lOVDMyJiBhbHBoYSwgRlhfRkxPQVQmIHJlZCwgRlhfRkxPQVQmIGdyZWVuLCBGWF9GTE9BVCYgYmx1ZSk7CisKK3B1YmxpYzoKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEljb25BcHBTdHJlYW0oRlhfSU5UMzIgblR5cGUsIGNvbnN0IENQREZfUmVjdCYgcmVjdCwgY29uc3QgQ1BXTF9Db2xvciYgY3JGaWxsLCAKKwkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3ImIGNyU3Ryb2tlID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUik7CisJc3RhdGljIHZvaWQJCQkJCQkJCURyYXdJY29uQXBwU3RyZWFtKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkJCQkJCQlGWF9JTlQzMiBuVHlwZSwgY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgY29uc3QgQ1BXTF9Db2xvciYgY3JGaWxsLCAKKwkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3ImIGNyU3Ryb2tlLCBjb25zdCBGWF9JTlQzMiBuVHJhbnNwYXJhbmN5KTsKKworcHJpdmF0ZToKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFwcFN0cmVhbUZyb21BcnJheShjb25zdCBDUFdMX1BhdGhEYXRhKiBwUGF0aERhdGEsIEZYX0lOVDMyIG5Db3VudCk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUdldFBhdGhEYXRhRnJvbUFycmF5KENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BXTF9QYXRoRGF0YSogcFBhdGhEYXRhLCBGWF9JTlQzMiBuQ291bnQpOworCisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBcHBTdHJlYW1fQ2hlY2soY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFwcFN0cmVhbV9DaXJjbGUoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFwcFN0cmVhbV9Dcm9zcyhjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpOworCXN0YXRpYyBDRlhfQnl0ZVN0cmluZwkJCQkJR2V0QXBwU3RyZWFtX0RpYW1vbmQoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFwcFN0cmVhbV9TcXVhcmUoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFwcFN0cmVhbV9TdGFyKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCk7CisKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFQX0NoZWNrKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCk7CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBUF9DaXJjbGUoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFQX0Nyb3NzKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCk7CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBUF9EaWFtb25kKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCk7CisJc3RhdGljIENGWF9CeXRlU3RyaW5nCQkJCQlHZXRBUF9TcXVhcmUoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFQX1N0YXIoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KTsKKwlzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcJCQkJCUdldEFQX0hhbGZDaXJjbGUoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94LEZYX0ZMT0FUIGZSb3RhdGUpOworCisJc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX0NoZWNrbWFyayhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19DaXJjbGUoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfQ29tbWVudChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19Dcm9zcyhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19IZWxwKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX0luc2VydFRleHQoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfS2V5KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX05ld1BhcmFncmFwaChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19UZXh0Tm90ZShDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19QYXJhZ3JhcGgoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfUmlnaHRBcnJvdyhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19SaWdodFBvaW50ZXIoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKTsKKwlzdGF0aWMgdm9pZAkJCQkJCQkJR2V0R3JhcGhpY3NfU3RhcihDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19VcEFycm93KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX1VwTGVmdEFycm93KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX0dyYXBoKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX1BhcGVyY2xpcChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19BdHRhY2htZW50KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSk7CisJc3RhdGljIHZvaWQJCQkJCQkJCUdldEdyYXBoaWNzX1RhZyhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworCXN0YXRpYyB2b2lkCQkJCQkJCQlHZXRHcmFwaGljc19Gb3hpdChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpOworfTsKKworI2VuZGlmIC8vICFkZWZpbmVkKEFGWF9QV0xfVVRJTFNfSF9fRDMyODEyQURfQTg3NV80RTA4XzlEM0NfMEE1NzAyMDk4N0M2X19JTkNMVURFRF8pCisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmggYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaAppbmRleCA3ZTllMjVkLi5jM2RkOWI3IDEwMDY0NAotLS0gYS9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaAorKysgYi9mcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaApAQCAtMSw0OTMgKzEsNDkzIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaWZuZGVmIF9QV0xfV05EX0hfDQotI2RlZmluZSBfUFdMX1dORF9IXw0KLQ0KLWNsYXNzIElQV0xfUHJvdmlkZXI7DQotY2xhc3MgQ1BXTF9XbmQ7DQotY2xhc3MgQ1BXTF9Nc2dDb250cm9sOw0KLWNsYXNzIENQV0xfV25kOw0KLWNsYXNzIENQV0xfU2Nyb2xsQmFyOw0KLWNsYXNzIENQV0xfVGltZXI7DQotY2xhc3MgQ1BXTF9UaW1lckhhbmRsZXI7DQotY2xhc3MgSVBXTF9TcGVsbENoZWNrOw0KLWNsYXNzIElGWF9TeXN0ZW1IYW5kbGVyOw0KLQ0KLSNpZmRlZiBGWF9SRUFERVJfRExMDQotCSNpZmRlZiBQV0xfRVhQT1JUDQotCQkJI2RlZmluZSBQV0xfQ0xBU1MJCV9fZGVjbHNwZWMoZGxsZXhwb3J0KQ0KLQkJCSNkZWZpbmUgUFdMX0ZVTkNUSU9OCVBXTF9DTEFTUwkNCi0JCSNlbHNlDQotCQkJI2RlZmluZSBQV0xfQ0xBU1MNCi0JCQkjZGVmaW5lIFBXTF9GVU5DVElPTg0KLQkjZW5kaWYNCi0jZWxzZQ0KLQkjZGVmaW5lIFBXTF9DTEFTUw0KLQkjZGVmaW5lIFBXTF9GVU5DVElPTg0KLSNlbmRpZg0KLQ0KLS8vd2luZG93IHN0eWxlcw0KLSNkZWZpbmUgUFdTX0NISUxECQkJCQkJCTB4ODAwMDAwMDBMDQotI2RlZmluZSBQV1NfQk9SREVSCQkJCQkJCTB4NDAwMDAwMDBMDQotI2RlZmluZSBQV1NfQkFDS0dST1VORAkJCQkJCTB4MjAwMDAwMDBMDQotI2RlZmluZSBQV1NfSFNDUk9MTAkJCQkJCQkweDEwMDAwMDAwTA0KLSNkZWZpbmUgUFdTX1ZTQ1JPTEwJCQkJCQkJMHgwODAwMDAwMEwNCi0jZGVmaW5lIFBXU19WSVNJQkxFCQkJCQkJCTB4MDQwMDAwMDBMDQotI2RlZmluZSBQV1NfRElTQUJMRQkJCQkJCQkweDAyMDAwMDAwTA0KLSNkZWZpbmUgUFdTX1JFQURPTkxZCQkJCQkJMHgwMTAwMDAwMEwNCi0jZGVmaW5lIFBXU19BVVRPRk9OVFNJWkUJCQkJCTB4MDA4MDAwMDBMDQotI2RlZmluZSBQV1NfQVVUT1RSQU5TUEFSRU5UCQkJCQkweDAwNDAwMDAwTA0KLSNkZWZpbmUgUFdTX05PUkVGUkVTSENMSVAJCQkJCTB4MDAyMDAwMDBMDQotDQotLy9lZGl0IGFuZCBsYWJlbCBzdHlsZXMNCi0jZGVmaW5lIFBFU19NVUxUSUxJTkUJCQkJCQkweDAwMDFMDQotI2RlZmluZSBQRVNfUEFTU1dPUkQJCQkJCQkweDAwMDJMDQotI2RlZmluZSBQRVNfTEVGVAkJCQkJCQkweDAwMDRMDQotI2RlZmluZSBQRVNfUklHSFQJCQkJCQkJMHgwMDA4TA0KLSNkZWZpbmUgUEVTX01JRERMRQkJCQkJCQkweDAwMTBMDQotI2RlZmluZSBQRVNfVE9QCQkJCQkJCQkweDAwMjBMDQotI2RlZmluZSBQRVNfQk9UVE9NCQkJCQkJCTB4MDA0MEwNCi0jZGVmaW5lIFBFU19DRU5URVIJCQkJCQkJMHgwMDgwTA0KLSNkZWZpbmUgUEVTX0NIQVJBUlJBWQkJCQkJCTB4MDEwMEwNCi0jZGVmaW5lIFBFU19BVVRPU0NST0xMCQkJCQkJMHgwMjAwTA0KLSNkZWZpbmUgUEVTX0FVVE9SRVRVUk4JCQkJCQkweDA0MDBMDQotI2RlZmluZSBQRVNfVU5ETwkJCQkJCQkweDA4MDBMDQotI2RlZmluZSBQRVNfUklDSAkJCQkJCQkweDEwMDBMDQotI2RlZmluZSBQRVNfU1BFTExDSEVDSwkJCQkJCTB4MjAwMEwNCi0jZGVmaW5lIFBFU19URVhUT1ZFUkZMT1cJCQkJCTB4NDAwMEwNCi0jZGVmaW5lIFBFU19OT1JFQUQJCQkJCQkJMHg4MDAwTA0KLQ0KLS8vbGlzdGJveCBzdHlsZXMNCi0jZGVmaW5lIFBMQlNfTVVMVElQTEVTRUwJCQkJCTB4MDAwMUwNCi0jZGVmaW5lIFBMQlNfSE9WRVJTRUwJCQkJCQkweDAwMDhMDQotDQotLy9jb21ib2JveCBzdHlsZXMNCi0jZGVmaW5lIFBDQlNfQUxMT1dDVVNUT01URVhUCQkJCTB4MDAwMUwNCi0NCi0vL3JpY2hlZGl0IHN0eWxlcw0KLSNkZWZpbmUgUFJFU19NVUxUSUxJTkUJCQkJCQkweDAwMDFMDQotI2RlZmluZSBQUkVTX0FVVE9SRVRVUk4JCQkJCQkweDAwMDJMDQotI2RlZmluZSBQUkVTX0FVVE9TQ1JPTEwJCQkJCQkweDAwMDRMDQotI2RlZmluZSBQUkVTX1NQRUxMQ0hFQ0sJCQkJCQkweDAwMDhMDQotI2RlZmluZSBQUkVTX1VORE8JCQkJCQkJMHgwMTAwTA0KLSNkZWZpbmUgUFJFU19NVUxUSVBBR0VTCQkJCQkJMHgwMjAwTA0KLSNkZWZpbmUgUFJFU19URVhUT1ZFUkZMT1cJCQkJCTB4MDQwMEwNCi0NCi0vL2JvcmRlciBzdHlsZQ0KLSNkZWZpbmUgUEJTX1NPTElECQkJCQkJCTANCi0jZGVmaW5lIFBCU19EQVNICQkJCQkJCTENCi0jZGVmaW5lIFBCU19CRVZFTEVECQkJCQkJCTINCi0jZGVmaW5lIFBCU19JTlNFVAkJCQkJCQkzDQotI2RlZmluZSBQQlNfVU5ERVJMSU5FRAkJCQkJCTQNCi0jZGVmaW5lIFBCU19TSEFET1cJCQkJCQkJNQ0KLQ0KLS8vbm90aWZpY2F0aW9uIG1lc3NhZ2VzDQotI2RlZmluZSBQTk1fQUREQ0hJTEQJCQkJCQkweDAwMDAwMDAwTA0KLSNkZWZpbmUgUE5NX1JFTU9WRUNISUxECQkJCQkJMHgwMDAwMDAwMUwNCi0jZGVmaW5lIFBOTV9TRVRTQ1JPTExJTkZPCQkJCQkweDAwMDAwMDAyTA0KLSNkZWZpbmUgUE5NX1NFVFNDUk9MTFBPUwkJCQkJMHgwMDAwMDAwM0wNCi0jZGVmaW5lIFBOTV9TQ1JPTExXSU5ET1cJCQkJCTB4MDAwMDAwMDRMDQotI2RlZmluZSBQTk1fTEJVVFRPTkRPV04JCQkJCQkweDAwMDAwMDA1TA0KLSNkZWZpbmUgUE5NX0xCVVRUT05VUAkJCQkJCTB4MDAwMDAwMDZMDQotI2RlZmluZSBQTk1fTU9VU0VNT1ZFCQkJCQkJMHgwMDAwMDAwN0wNCi0jZGVmaW5lCVBOTV9OT1RFUkVTRVQJCQkJCQkweDAwMDAwMDA4TA0KLSNkZWZpbmUgUE5NX1NFVENBUkVUSU5GTwkJCQkJMHgwMDAwMDAwOUwNCi0jZGVmaW5lIFBOTV9TRUxDSEFOR0VECQkJCQkJMHgwMDAwMDAwQUwNCi0jZGVmaW5lCVBOTV9OT1RFRURJVENIQU5HRUQJCQkJCTB4MDAwMDAwMEJMDQotDQotI2RlZmluZSBQV0xfQ0xBU1NOQU1FX0VESVQJCQkJCSJDUFdMX0VkaXQiDQotDQotc3RydWN0IENQV0xfRGFzaA0KLXsNCi0JQ1BXTF9EYXNoKEZYX0lOVDMyIGRhc2gsIEZYX0lOVDMyIGdhcCwgRlhfSU5UMzIgcGhhc2UpIDogbkRhc2goZGFzaCksIG5HYXAoZ2FwKSwgblBoYXNlKHBoYXNlKQ0KLQl7fQ0KLQ0KLQlGWF9JTlQzMgkJCW5EYXNoOw0KLQlGWF9JTlQzMgkJCW5HYXA7DQotCUZYX0lOVDMyCQkJblBoYXNlOw0KLX07DQotDQotc3RydWN0IFBXTF9DTEFTUyBDUFdMX0NvbG9yDQotew0KLQlDUFdMX0NvbG9yKEZYX0lOVDMyIHR5cGUgPSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQsIEZYX0ZMT0FUIGNvbG9yMSA9IDAuMGYsIEZYX0ZMT0FUIGNvbG9yMiA9IDAuMGYsIEZYX0ZMT0FUIGNvbG9yMyA9IDAuMGYsIEZYX0ZMT0FUIGNvbG9yNCA9IDAuMGYpDQotCQk6IG5Db2xvclR5cGUodHlwZSksIGZDb2xvcjEoY29sb3IxKSwgZkNvbG9yMihjb2xvcjIpLCBmQ29sb3IzKGNvbG9yMyksIGZDb2xvcjQoY29sb3I0KQ0KLQl7fQ0KLQ0KLQlDUFdMX0NvbG9yKEZYX0lOVDMyIHIsIEZYX0lOVDMyIGcsIEZYX0lOVDMyIGIpIDoNCi0JCW5Db2xvclR5cGUoQ09MT1JUWVBFX1JHQiksIGZDb2xvcjEoci8yNTUuMGYpLCBmQ29sb3IyKGcvMjU1LjBmKSwgZkNvbG9yMyhiLzI1NS4wZiksIGZDb2xvcjQoMCkNCi0Je30NCi0JDQotCXZvaWQgQ29udmVydENvbG9yVHlwZShGWF9JTlQzMiBuQ29sb3JUeXBlKTsNCi0NCi0JLyoNCi0JQ09MT1JUWVBFX1RSQU5TUEFSRU5UDQotCUNPTE9SVFlQRV9SR0INCi0JQ09MT1JUWVBFX0NNWUsNCi0JQ09MT1JUWVBFX0dSQVkNCi0JKi8NCi0JRlhfSU5UMzIJCQkJCW5Db2xvclR5cGU7IA0KLQlGWF9GTE9BVAkJCQkJZkNvbG9yMSxmQ29sb3IyLGZDb2xvcjMsZkNvbG9yNDsNCi19Ow0KLQ0KLWlubGluZSBGWF9CT09MIG9wZXJhdG9yID09IChjb25zdCBDUFdMX0NvbG9yICZjMSwgY29uc3QgQ1BXTF9Db2xvciAmYzIpDQotew0KLQlyZXR1cm4gYzEubkNvbG9yVHlwZSA9PSBjMi5uQ29sb3JUeXBlICYmIA0KLQkJYzEuZkNvbG9yMSAtIGMyLmZDb2xvcjEgPCAwLjAwMDEgJiYgYzEuZkNvbG9yMSAtIGMyLmZDb2xvcjEgPiAtMC4wMDAxICYmDQotCQljMS5mQ29sb3IyIC0gYzIuZkNvbG9yMiA8IDAuMDAwMSAmJiBjMS5mQ29sb3IyIC0gYzIuZkNvbG9yMiA+IC0wLjAwMDEgJiYNCi0JCWMxLmZDb2xvcjMgLSBjMi5mQ29sb3IzIDwgMC4wMDAxICYmIGMxLmZDb2xvcjMgLSBjMi5mQ29sb3IzID4gLTAuMDAwMSAmJg0KLQkJYzEuZkNvbG9yNCAtIGMyLmZDb2xvcjQgPCAwLjAwMDEgJiYgYzEuZkNvbG9yNCAtIGMyLmZDb2xvcjQgPiAtMC4wMDAxOw0KLX0NCi0NCi1pbmxpbmUgRlhfQk9PTCBvcGVyYXRvciAhPSAoY29uc3QgQ1BXTF9Db2xvciAmYzEsIGNvbnN0IENQV0xfQ29sb3IgJmMyKQ0KLXsNCi0JcmV0dXJuICFvcGVyYXRvciA9PSAoYzEsIGMyKTsNCi19DQotDQotI2RlZmluZSBQV0xfU0NST0xMQkFSX1dJRFRICQkJCQkxMi4wZg0KLSNkZWZpbmUgUFdMX1NDUk9MTEJBUl9CVVRUT05fV0lEVEgJCQk5LjBmDQotI2RlZmluZSBQV0xfU0NST0xMQkFSX1BPU0JVVFRPTl9NSU5XSURUSAkyLjBmDQotI2RlZmluZSBQV0xfU0NST0xMQkFSX1RSQU5TUEFSQU5DWQkJCTE1MA0KLSNkZWZpbmUgUFdMX1NDUk9MTEJBUl9CS0NPTE9SCQkJCUNQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwyMjAuMGYvMjU1LjBmLDIyMC4wZi8yNTUuMGYsMjIwLjBmLzI1NS4wZikNCi0jZGVmaW5lIFBXTF9ERUZBVUxUX1NFTFRFWFRDT0xPUgkJCUNQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwxLDEsMSkNCi0jZGVmaW5lIFBXTF9ERUZBVUxUX1NFTEJBQ0tDT0xPUgkJCUNQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwwLDUxLjBmLzI1NS4wZiwxMTMuMGYvMjU1LjBmKQ0KLSNkZWZpbmUgUFdMX0RFRkFVTFRfQkFDS0NPTE9SCQkJCVBXTF9ERUZBVUxUX1NFTFRFWFRDT0xPUg0KLSNkZWZpbmUgUFdMX0RFRkFVTFRfVEVYVENPTE9SCQkJCUNQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwwLDAsMCkNCi0jZGVmaW5lIFBXTF9ERUZBVUxUX0ZPTlRTSVpFCQkJCTkuMGYNCi0jZGVmaW5lIFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IJCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwKQ0KLSNkZWZpbmUgUFdMX0RFRkFVTFRfV0hJVEVDT0xPUgkJCQlDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpDQotI2RlZmluZSBQV0xfREVGQVVMVF9IRUFWWUdSQVlDT0xPUgkJCUNQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC41MCkNCi0jZGVmaW5lIFBXTF9ERUZBVUxUX0xJR0hUR1JBWUNPTE9SCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwLjc1KQ0KLSNkZWZpbmUgUFdMX1RSSUFOR0xFX0hBTEZMRU4JCQkJMi4wZg0KLSNkZWZpbmUJUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4JCTMuMGYNCi0jZGVmaW5lIFBXTF9JTlZBTElEQVRFX0lORkxBVEUJCQkJMg0KLQ0KLWNsYXNzIElQV0xfU3BlbGxDaGVjaw0KLXsNCi1wdWJsaWM6DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJCQlDaGVja1dvcmQoRlhfTFBDU1RSIHNXb3JkKSA9IDA7DQotCXZpcnR1YWwgdm9pZAkJCQkJCQlTdWdnZXN0V29yZHMoRlhfTFBDU1RSIHNXb3JkLCBDRlhfQnl0ZVN0cmluZ0FycmF5ICYgc1N1Z2dlc3QpID0gMDsJDQotfTsNCi0NCi1jbGFzcyBJUFdMX1Byb3ZpZGVyDQotew0KLXB1YmxpYzoNCi0JLy9nZXQgYSBtYXRyaXggd2hpY2ggbWFwIHVzZXIgc3BhY2UgdG8gQ1duZCBjbGllbnQgc3BhY2UNCi0JdmlydHVhbCBDUERGX01hdHJpeAkJCQkJCUdldFdpbmRvd01hdHJpeCh2b2lkKiBwQXR0YWNoZWREYXRhKSA9IDA7DQotDQotCS8qDQotCTAgTCImVW5kb1x0Q3RybCtaIg0KLQkxIEwiJlJlZG9cdEN0cmwrU2hpZnQrWiINCi0JMiBMIkN1JnRcdEN0cmwrWCINCi0JMyBMIiZDb3B5XHRDdHJsK0MiDQotCTQgTCImUGFzdGVcdEN0cmwrViINCi0JNSBMIiZEZWxldGUiDQotCTYgIEwiJlNlbGVjdCBBbGxcdEN0cmwrQSINCi0JKi8NCi0JdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJTG9hZFBvcHVwTWVudVN0cmluZyhGWF9JTlQzMiBuSW5kZXgpID0gMDsNCi19Ow0KLQ0KLWNsYXNzIElQV0xfRm9jdXNIYW5kbGVyDQotew0KLXB1YmxpYzoNCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uU2V0Rm9jdXMoQ1BXTF9XbmQqIHBXbmQpID0gMDsNCi0JdmlydHVhbCB2b2lkCQkJCQkJCU9uS2lsbEZvY3VzKENQV0xfV25kKiBwV25kKSA9IDA7DQotfTsNCi0NCi1zdHJ1Y3QgUFdMX0NSRUFURVBBUkFNDQotew0KLXB1YmxpYzoNCi0JUFdMX0NSRUFURVBBUkFNKCkgOiByY1JlY3RXbmQoMCwwLDAsMCksDQotCQlwU3lzdGVtSGFuZGxlcihOVUxMKSwNCi0JCXBGb250TWFwKE5VTEwpLA0KLQkJcFByb3ZpZGVyKE5VTEwpLA0KLQkJcEZvY3VzSGFuZGxlcihOVUxMKSwNCi0JCWR3RmxhZ3MoMCksDQotCQlzQmFja2dyb3VuZENvbG9yKCksDQotCQloQXR0YWNoZWRXbmQoTlVMTCksDQotCQlwU3BlbGxDaGVjayhOVUxMKSwNCi0JCW5Cb3JkZXJTdHlsZShQQlNfU09MSUQpLA0KLQkJZHdCb3JkZXJXaWR0aCgxKSwNCi0JCXNCb3JkZXJDb2xvcigpLA0KLQkJc1RleHRDb2xvcigpLA0KLQkJc1RleHRTdHJva2VDb2xvcigpLA0KLQkJblRyYW5zcGFyZW5jeSgyNTUpLA0KLQkJZkZvbnRTaXplKFBXTF9ERUZBVUxUX0ZPTlRTSVpFKSwNCi0JCXNEYXNoKDMsMCwwKSwJDQotCQlwQXR0YWNoZWREYXRhKE5VTEwpLA0KLQkJcFBhcmVudFduZChOVUxMKSwNCi0JCXBNc2dDb250cm9sKE5VTEwpLA0KLQkJZUN1cnNvclR5cGUoRlhDVF9BUlJPVyksDQotCQltdENoaWxkKDEsMCwwLDEsMCwwKQ0KLQl7DQotCX0NCi0NCi0JQ1BERl9SZWN0CQkJCXJjUmVjdFduZDsJCQkJLy9yZXF1aXJlZAkNCi0JSUZYX1N5c3RlbUhhbmRsZXIqCQlwU3lzdGVtSGFuZGxlcjsJCQkvL3JlcXVpcmVkDQotCUlGWF9FZGl0X0ZvbnRNYXAqCQlwRm9udE1hcDsJCQkJLy9yZXF1aXJlZCBmb3IgdGV4dCB3aW5kb3cNCi0JSVBXTF9Qcm92aWRlcioJCQlwUHJvdmlkZXI7CQkJCS8vcmVxdWlyZWQgZm9yIHNlbGYgY29vcmRpbmF0ZQ0KLQlJUFdMX0ZvY3VzSGFuZGxlcioJCXBGb2N1c0hhbmRsZXI7CQkJLy9vcHRpb25hbA0KLQlGWF9EV09SRAkJCQlkd0ZsYWdzOwkJCQkvL29wdGlvbmFsDQotCUNQV0xfQ29sb3IJCQkJc0JhY2tncm91bmRDb2xvcjsJCS8vb3B0aW9uYWwNCi0JRlhfSFdORAkJCQkJaEF0dGFjaGVkV25kOwkJCS8vcmVxdWlyZWQgZm9yIG5vLXJlYWRlciBmcmFtZXdvcmsNCi0JSVBXTF9TcGVsbENoZWNrKgkJcFNwZWxsQ2hlY2s7CQkJLy9yZXF1aXJlZCBmb3Igc3BlbGxjaGVja2luZw0KLQlGWF9JTlQzMgkJCQluQm9yZGVyU3R5bGU7CQkJLy9vcHRpb25hbA0KLQlGWF9JTlQzMgkJCQlkd0JvcmRlcldpZHRoOwkJCS8vb3B0aW9uYWwNCi0JQ1BXTF9Db2xvcgkJCQlzQm9yZGVyQ29sb3I7CQkJLy9vcHRpb25hbA0KLQlDUFdMX0NvbG9yCQkJCXNUZXh0Q29sb3I7CQkJCS8vb3B0aW9uYWwNCi0JQ1BXTF9Db2xvcgkJCQlzVGV4dFN0cm9rZUNvbG9yOwkJLy9vcHRpb25hbA0KLQlGWF9JTlQzMgkJCQluVHJhbnNwYXJlbmN5OwkJCS8vb3B0aW9uYWwNCi0JRlhfRkxPQVQJCQkJZkZvbnRTaXplOwkJCQkvL29wdGlvbmFsDQotCUNQV0xfRGFzaAkJCQlzRGFzaDsJCQkJCS8vb3B0aW9uYWwNCi0Jdm9pZCoJCQkJCXBBdHRhY2hlZERhdGE7CQkJLy9vcHRpb25hbA0KLQlDUFdMX1duZCoJCQkJcFBhcmVudFduZDsJCQkJLy9pZ25vcmUNCi0JQ1BXTF9Nc2dDb250cm9sKgkJcE1zZ0NvbnRyb2w7CQkJLy9pZ25vcmUNCi0JRlhfSU5UMzIJCQkJZUN1cnNvclR5cGU7CQkJLy9pZ25vcmUNCi0JQ1BERl9NYXRyaXgJCQkJbXRDaGlsZDsJCQkJLy9pZ25vcmUNCi19Ow0KLQ0KLWNsYXNzIENQV0xfVGltZXINCi17DQotcHVibGljOg0KLQlDUFdMX1RpbWVyKENQV0xfVGltZXJIYW5kbGVyKiBwQXR0YWNoZWQsIElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlcik7DQotCXZpcnR1YWwgfkNQV0xfVGltZXIoKTsNCi0NCi0JRlhfSU5UMzIJCQkJCQkJU2V0UFdMVGltZXIoRlhfSU5UMzIgbkVsYXBzZSk7DQotCXZvaWQJCQkJCQkJCUtpbGxQV0xUaW1lcigpOw0KLQlzdGF0aWMgdm9pZCAJCQkJCQlUaW1lclByb2MoRlhfSU5UMzIgaWRFdmVudCk7DQotDQotcHJpdmF0ZToNCi0JRlhfSU5UMzIJCQkJCQkJbV9uVGltZXJJRDsJDQotCUNQV0xfVGltZXJIYW5kbGVyKgkJCQkJbV9wQXR0YWNoZWQ7DQotCUlGWF9TeXN0ZW1IYW5kbGVyKgkJCQkJbV9wU3lzdGVtSGFuZGxlcjsNCi19Ow0KLQ0KLWNsYXNzIFBXTF9DTEFTUyBDUFdMX1RpbWVySGFuZGxlcg0KLXsNCi1wdWJsaWM6DQotCUNQV0xfVGltZXJIYW5kbGVyKCk7DQotCXZpcnR1YWwgfkNQV0xfVGltZXJIYW5kbGVyKCk7DQotDQotCXZvaWQJCQkJCQkJCUJlZ2luVGltZXIoRlhfSU5UMzIgbkVsYXBzZSk7DQotCXZvaWQJCQkJCQkJCUVuZFRpbWVyKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJCVRpbWVyUHJvYygpOw0KLQl2aXJ0dWFsIElGWF9TeXN0ZW1IYW5kbGVyKgkJCUdldFN5c3RlbUhhbmRsZXIoKSBjb25zdCA9IDA7DQotDQotcHJpdmF0ZToNCi0JQ1BXTF9UaW1lcioJCQkJCQkJbV9wVGltZXI7DQotfTsNCi0NCi1jbGFzcyBQV0xfQ0xBU1MgQ1BXTF9XbmQgOiBwdWJsaWMgQ1BXTF9UaW1lckhhbmRsZXINCi17DQotCWZyaWVuZCBjbGFzcyBDUFdMX01zZ0NvbnRyb2w7DQotcHVibGljOg0KLQlDUFdMX1duZCgpOw0KLQl2aXJ0dWFsIH5DUFdMX1duZCgpOw0KLQ0KLQl2b2lkCQkJCQkJCUNyZWF0ZShjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotCXZpcnR1YWwgQ0ZYX0J5dGVTdHJpbmcJCQlHZXRDbGFzc05hbWUoKSBjb25zdDsJDQotCXZvaWQJCQkJCQkJRGVzdHJveSgpOw0KLQl2b2lkCQkJCQkJCU1vdmUoY29uc3QgQ1BERl9SZWN0ICYgcmNOZXcsRlhfQk9PTCBiUmVzZXQsRlhfQk9PTCBiUmVmcmVzaCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJSW52YWxpZGF0ZVJlY3QoQ1BERl9SZWN0KiBwUmVjdCA9IE5VTEwpOw0KLQ0KLQl2b2lkCQkJCQkJCUdldEFwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVTdHJpbmcgJiBzQXBwU3RyZWFtKTsNCi0Jdm9pZAkJCQkJCQlEcmF3QXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsNCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCQlPbktleURvd24oRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uS2V5VXAoRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uQ2hhcihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uRGJsQ2xrKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25NQnV0dG9uRGJsQ2xrKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTUJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25NQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25SQnV0dG9uRGJsQ2xrKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOw0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uUkJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25Nb3VzZVdoZWVsKHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQkJU2V0Rm9jdXMoKTsNCi0JdmlydHVhbCB2b2lkCQkJCQlLaWxsRm9jdXMoKTsNCi0Jdm9pZAkJCQkJCQlTZXRDYXB0dXJlKCk7DQotCXZvaWQJCQkJCQkJUmVsZWFzZUNhcHR1cmUoKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldFRleHRDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldFRleHRTdHJva2VDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldFZpc2libGUoRlhfQk9PTCBiVmlzaWJsZSk7DQotDQotCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUdldEZvY3VzUmVjdCgpIGNvbnN0Ow0KLQl2aXJ0dWFsIENQV0xfQ29sb3IJCQkJR2V0QmFja2dyb3VuZENvbG9yKCkgY29uc3Q7DQotCXZpcnR1YWwgQ1BXTF9Db2xvcgkJCQlHZXRCb3JkZXJDb2xvcigpIGNvbnN0Ow0KLQl2aXJ0dWFsIENQV0xfQ29sb3IJCQkJR2V0VGV4dENvbG9yKCkgY29uc3Q7DQotCXZpcnR1YWwgQ1BXTF9Db2xvcgkJCQlHZXRUZXh0U3Ryb2tlQ29sb3IoKSBjb25zdDsNCi0JdmlydHVhbCBGWF9GTE9BVAkJCQlHZXRGb250U2l6ZSgpIGNvbnN0Ow0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJCUdldElubmVyQm9yZGVyV2lkdGgoKSBjb25zdDsNCi0JdmlydHVhbCBDUFdMX0NvbG9yCQkJCUdldEJvcmRlckxlZnRUb3BDb2xvcihGWF9JTlQzMiBuQm9yZGVyU3R5bGUpIGNvbnN0Ow0KLQl2aXJ0dWFsIENQV0xfQ29sb3IJCQkJR2V0Qm9yZGVyUmlnaHRCb3R0b21Db2xvcihGWF9JTlQzMiBuQm9yZGVyU3R5bGUpIGNvbnN0Ow0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJCUlzTW9kaWZpZWQoKSBjb25zdCB7cmV0dXJuIEZBTFNFO30NCi0NCi0JdmlydHVhbCB2b2lkCQkJCQlTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpOwkNCi0NCi0Jdm9pZAkJCQkJCQlTZXRCYWNrZ3JvdW5kQ29sb3IoY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yKTsJCQ0KLQl2b2lkCQkJCQkJCVNldEJvcmRlckNvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcik7DQotCXZvaWQJCQkJCQkJU2V0Qm9yZGVyV2lkdGgoRlhfSU5UMzIgbkJvcmRlcldpZHRoKTsNCi0Jdm9pZAkJCQkJCQlTZXRDbGlwUmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0KTsNCi0Jdm9pZAkJCQkJCQlTZXRCb3JkZXJTdHlsZShGWF9JTlQzMiBlQm9yZGVyU3R5bGUpOwkNCi0Jdm9pZAkJCQkJCQlTZXRCb3JkZXJEYXNoKGNvbnN0IENQV0xfRGFzaCAmIHNEYXNoKTsNCi0NCi0JQ1BERl9SZWN0CQkJCQkJR2V0T3JpZ2luV2luZG93UmVjdCgpIGNvbnN0Ow0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRXaW5kb3dSZWN0KCkgY29uc3Q7DQotCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUdldENsaWVudFJlY3QoKSBjb25zdDsNCi0JQ1BERl9Qb2ludAkJCQkJCUdldENlbnRlclBvaW50KCkgY29uc3Q7DQotCUNQREZfUmVjdAkJCQkJCUdldENsaWVudENlbnRlclNxdWFyZSgpIGNvbnN0Ow0KLQlDUERGX1JlY3QJCQkJCQlHZXRXaW5kb3dDZW50ZXJTcXVhcmUoKSBjb25zdDsJCQ0KLQlGWF9JTlQzMgkJCQkJCUdldEJvcmRlcldpZHRoKCkgY29uc3Q7CQkNCi0JRlhfQk9PTAkJCQkJCQlJc1Zpc2libGUoKSBjb25zdCB7cmV0dXJuIG1fYlZpc2libGU7fQkNCi0JRlhfQk9PTAkJCQkJCQlIYXNGbGFnKEZYX0RXT1JEIGR3RmxhZ3MpIGNvbnN0Ow0KLQl2b2lkCQkJCQkJCUFkZEZsYWcoRlhfRFdPUkQgZHdGbGFncyk7DQotCXZvaWQJCQkJCQkJUmVtb3ZlRmxhZyhGWF9EV09SRCBkd0ZsYWdzKTsNCi0JQ1BERl9SZWN0CQkJCQkJR2V0Q2xpcFJlY3QoKSBjb25zdDsJCQ0KLQlDUFdMX1duZCoJCQkJCQlHZXRQYXJlbnRXaW5kb3coKSBjb25zdDsJCQ0KLQlGWF9JTlQzMgkJCQkJCUdldEJvcmRlclN0eWxlKCkgY29uc3Q7CQ0KLQlDUFdMX0Rhc2gJCQkJCQlHZXRCb3JkZXJEYXNoKCkgY29uc3Q7DQotCXZvaWQqCQkJCQkJCUdldEF0dGFjaGVkRGF0YSgpIGNvbnN0Ow0KLQkNCi0JRlhfQk9PTAkJCQkJCQlXbmRIaXRUZXN0KGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3Q7DQotCUZYX0JPT0wJCQkJCQkJQ2xpZW50SGl0VGVzdChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUlzQ2FwdHVyZU1vdXNlKCkgY29uc3Q7DQotDQotCWNvbnN0IENQV0xfV25kKgkJCQkJR2V0Rm9jdXNlZCgpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUlzRm9jdXNlZCgpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUlzUmVhZE9ubHkoKSBjb25zdDsNCi0JQ1BXTF9TY3JvbGxCYXIqCQkJCQlHZXRWU2Nyb2xsQmFyKCkgY29uc3Q7DQotDQotCUlGWF9FZGl0X0ZvbnRNYXAqCQkJCUdldEZvbnRNYXAoKSBjb25zdDsNCi0JSVBXTF9Qcm92aWRlcioJCQkJCUdldFByb3ZpZGVyKCkgY29uc3Q7DQotCXZpcnR1YWwgSUZYX1N5c3RlbUhhbmRsZXIqCQlHZXRTeXN0ZW1IYW5kbGVyKCkgY29uc3Q7DQotCUlQV0xfRm9jdXNIYW5kbGVyKgkJCQlHZXRGb2N1c0hhbmRsZXIoKSBjb25zdDsNCi0JDQotCUZYX0lOVDMyCQkJCQkJR2V0VHJhbnNwYXJlbmN5KCk7DQotCXZvaWQJCQkJCQkJU2V0VHJhbnNwYXJlbmN5KEZYX0lOVDMyIG5UcmFuc3BhcmVuY3kpOw0KLQ0KLQlDUERGX01hdHJpeAkJCQkJCUdldENoaWxkVG9Sb290KCkgY29uc3Q7DQotCUNQREZfTWF0cml4CQkJCQkJR2V0Q2hpbGRNYXRyaXgoKSBjb25zdDsNCi0Jdm9pZAkJCQkJCQlTZXRDaGlsZE1hdHJpeChjb25zdCBDUERGX01hdHJpeCYgbXQpOw0KLQlDUERGX01hdHJpeAkJCQkJCUdldFdpbmRvd01hdHJpeCgpIGNvbnN0Ow0KLQ0KLQl2aXJ0dWFsIENQREZfUG9pbnQJCQkJQ2hpbGRUb1BhcmVudChjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3Q7DQotCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUNoaWxkVG9QYXJlbnQoY29uc3QgQ1BERl9SZWN0JiByZWN0KSBjb25zdDsNCi0JdmlydHVhbCBDUERGX1BvaW50CQkJCVBhcmVudFRvQ2hpbGQoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0Ow0KLQl2aXJ0dWFsIENQREZfUmVjdAkJCQlQYXJlbnRUb0NoaWxkKGNvbnN0IENQREZfUmVjdCYgcmVjdCkgY29uc3Q7DQotDQotCS8vdGhvc2UgbWV0aG9kcyBvbmx5IGltcGxlbWVudGVkIGJ5IGxpc3RjdHJsIGl0ZW0NCi0JdmlydHVhbCBGWF9GTE9BVAkJCQlHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKSB7cmV0dXJuIDA7fSANCi0JdmlydHVhbCBGWF9GTE9BVAkJCQlHZXRJdGVtTGVmdE1hcmdpbigpIHtyZXR1cm4gMDt9IA0KLQl2aXJ0dWFsIEZYX0ZMT0FUCQkJCUdldEl0ZW1SaWdodE1hcmdpbigpIHtyZXR1cm4gMDt9IA0KLQ0KLQl2b2lkCQkJCQkJCUVuYWJsZVdpbmRvdyhGWF9CT09MIGJFbmFibGUpOw0KLQlGWF9CT09MCQkJCQkJCUlzRW5hYmxlZCgpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVNldEN1cnNvcigpOw0KLQ0KLXByb3RlY3RlZDoJDQotCXZpcnR1YWwgdm9pZAkJCQkJQ3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCVJlUG9zQ2hpbGRXbmQoKTsNCi0Jdm9pZAkJCQkJCQlHZXRBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCUdldENoaWxkQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQlEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7DQotCXZpcnR1YWwgdm9pZAkJCQkJRHJhd0NoaWxkQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsNCi0NCi0JdmlydHVhbCB2b2lkCQkJCQlPbkNyZWF0ZShQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25DcmVhdGVkKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25EZXN0cm95KCk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQkJT25TZXRGb2N1cygpOw0KLQl2aXJ0dWFsIHZvaWQJCQkJCU9uS2lsbEZvY3VzKCk7DQotDQotCXZpcnR1YWwgdm9pZAkJCQkJT25FbmFibGVkKCk7DQotCXZpcnR1YWwgdm9pZAkJCQkJT25EaXNhYmxlZCgpOw0KLQ0KLQl2b2lkCQkJCQkJCVNldE5vdGlmeUZsYWcoRlhfQk9PTCBiTm90aWZ5aW5nID0gVFJVRSl7bV9iTm90aWZ5aW5nID0gYk5vdGlmeWluZzt9Ow0KLSANCi0JRlhfQk9PTAkJCQkJCQlJc1ZhbGlkKCkgY29uc3Q7DQotCVBXTF9DUkVBVEVQQVJBTQkJCQkJR2V0Q3JlYXRpb25QYXJhbSgpIGNvbnN0OwkJDQotCUZYX0JPT0wJCQkJCQkJSXNOb3RpZnlpbmcoKSBjb25zdCB7cmV0dXJuIG1fYk5vdGlmeWluZzt9CQ0KLQkNCi0Jdm9pZAkJCQkJCQlJbnZhbGlkYXRlUmVjdE1vdmUoY29uc3QgQ1BERl9SZWN0ICYgcmNPbGQsIGNvbnN0IENQREZfUmVjdCAmIHJjTmV3KTsNCi0NCi0Jdm9pZAkJCQkJCQlQV0x0b1duZChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0lOVDMyJiB4LCBGWF9JTlQzMiYgeSkgY29uc3Q7DQotCUZYX1JFQ1QJCQkJCQkJUFdMdG9XbmQoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgY29uc3Q7CQ0KLQlGWF9IV05ECQkJCQkJCUdldEF0dGFjaGVkSFduZCgpIGNvbnN0Ow0KLQkNCi0JRlhfQk9PTAkJCQkJCQlJc1duZENhcHR1cmVNb3VzZShjb25zdCBDUFdMX1duZCAqIHBXbmQpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUlzV25kQ2FwdHVyZUtleWJvYXJkKGNvbnN0IENQV0xfV25kICogcFduZCkgY29uc3Q7CQ0KLQljb25zdCBDUFdMX1duZCoJCQkJCUdldFJvb3RXbmQoKSBjb25zdDsJDQotDQotCUZYX0JPT0wJCQkJCQkJSXNDVFJMcHJlc3NlZChGWF9EV09SRCBuRmxhZykgY29uc3Q7DQotCUZYX0JPT0wJCQkJCQkJSXNTSElGVHByZXNzZWQoRlhfRFdPUkQgbkZsYWcpIGNvbnN0Ow0KLQlGWF9CT09MCQkJCQkJCUlzQUxUcHJlc3NlZChGWF9EV09SRCBuRmxhZykgY29uc3Q7DQotCUZYX0JPT0wJCQkJCQkJSXNJTlNFUlRwcmVzc2VkKEZYX0RXT1JEIG5GbGFnKSBjb25zdDsNCi0NCi1wcml2YXRlOg0KLQl2b2lkCQkJCQkJCUFkZENoaWxkKENQV0xfV25kICogcFduZCk7DQotCXZvaWQJCQkJCQkJUmVtb3ZlQ2hpbGQoQ1BXTF9XbmQgKiBwV25kKTsNCi0NCi0Jdm9pZAkJCQkJCQlDcmVhdGVTY3JvbGxCYXIoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApOw0KLQl2b2lkCQkJCQkJCUNyZWF0ZVZTY3JvbGxCYXIoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApOwkNCi0NCi0Jdm9pZAkJCQkJCQlBanVzdFN0eWxlKCk7CQ0KLQl2b2lkCQkJCQkJCUNyZWF0ZU1zZ0NvbnRyb2woKTsNCi0Jdm9pZAkJCQkJCQlEZXN0cm95TXNnQ29udHJvbCgpOw0KLQkNCi0JQ1BXTF9Nc2dDb250cm9sKgkJCQlHZXRNc2dDb250cm9sKCkgY29uc3Q7CQ0KLQkNCi1wcm90ZWN0ZWQ6DQotCUNGWF9BcnJheVRlbXBsYXRlPENQV0xfV25kKj4JbV9hQ2hpbGRyZW47DQotDQotcHJpdmF0ZToNCi0JUFdMX0NSRUFURVBBUkFNCQkJCQltX3NQcml2YXRlUGFyYW07DQotCQ0KLQlDUFdMX1Njcm9sbEJhcioJCQkJCW1fcFZTY3JvbGxCYXI7DQotDQotCUNQREZfUmVjdAkJCQkJCW1fcmNXaW5kb3c7DQotCUNQREZfUmVjdAkJCQkJCW1fcmNDbGlwOw0KLQ0KLQlGWF9CT09MCQkJCQkJCW1fYkNyZWF0ZWQ7CQkJDQotCUZYX0JPT0wJCQkJCQkJbV9iVmlzaWJsZTsNCi0JRlhfQk9PTAkJCQkJCQltX2JOb3RpZnlpbmc7CQ0KLQlGWF9CT09MCQkJCQkJCW1fYkVuYWJsZWQ7DQotfTsNCi0NCi0vLyAjaWZuZGVmIFZLX0VORA0KLS8vIA0KLS8vICNkZWZpbmUgVktfRU5EICAgICAgICAgICAgMHgyMw0KLS8vICNkZWZpbmUgVktfSE9NRSAgICAgICAgICAgMHgyNA0KLS8vICNkZWZpbmUgVktfTEVGVCAgICAgICAgICAgMHgyNQ0KLS8vICNkZWZpbmUgVktfVVAgICAgICAgICAgICAgMHgyNg0KLS8vICNkZWZpbmUgVktfUklHSFQgICAgICAgICAgMHgyNw0KLS8vICNkZWZpbmUgVktfRE9XTiAgICAgICAgICAgMHgyOA0KLS8vICNkZWZpbmUgVktfSU5TRVJUICAgICAgICAgMHgyRA0KLS8vICNkZWZpbmUgVktfREVMRVRFICAgICAgICAgMHgyRQ0KLS8vIA0KLS8vICNkZWZpbmUgVktfQkFDSyAgICAgICAgICAgMHgwOA0KLS8vICNkZWZpbmUgVktfVEFCICAgICAgICAgICAgMHgwOQ0KLS8vIA0KLS8vICNkZWZpbmUgVktfQ0xFQVIgICAgICAgICAgMHgwQw0KLS8vICNkZWZpbmUgVktfUkVUVVJOICAgICAgICAgMHgwRA0KLS8vICNkZWZpbmUgVktfRVNDQVBFICAgICAgICAgMHgxQg0KLS8vICNkZWZpbmUgVktfU1BBQ0UgICAgICAgICAgMHgyMA0KLS8vICNlbmRpZg0KLS8vIA0KLS8vICNkZWZpbmUgVktfTk9ORQkJCSAgMA0KLQ0KLSNlbmRpZiAvLyAhZGVmaW5lZChBRlhfUFdMX1dORF9IX19EMzI4MTJBRF9BODc1XzRFMDhfOUQzQ18wQTU3MDIwOTg3QzZfX0lOQ0xVREVEXykNCi0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaWZuZGVmIF9QV0xfV05EX0hfCisjZGVmaW5lIF9QV0xfV05EX0hfCisKK2NsYXNzIElQV0xfUHJvdmlkZXI7CitjbGFzcyBDUFdMX1duZDsKK2NsYXNzIENQV0xfTXNnQ29udHJvbDsKK2NsYXNzIENQV0xfV25kOworY2xhc3MgQ1BXTF9TY3JvbGxCYXI7CitjbGFzcyBDUFdMX1RpbWVyOworY2xhc3MgQ1BXTF9UaW1lckhhbmRsZXI7CitjbGFzcyBJUFdMX1NwZWxsQ2hlY2s7CitjbGFzcyBJRlhfU3lzdGVtSGFuZGxlcjsKKworI2lmZGVmIEZYX1JFQURFUl9ETEwKKwkjaWZkZWYgUFdMX0VYUE9SVAorCQkJI2RlZmluZSBQV0xfQ0xBU1MJCV9fZGVjbHNwZWMoZGxsZXhwb3J0KQorCQkJI2RlZmluZSBQV0xfRlVOQ1RJT04JUFdMX0NMQVNTCQorCQkjZWxzZQorCQkJI2RlZmluZSBQV0xfQ0xBU1MKKwkJCSNkZWZpbmUgUFdMX0ZVTkNUSU9OCisJI2VuZGlmCisjZWxzZQorCSNkZWZpbmUgUFdMX0NMQVNTCisJI2RlZmluZSBQV0xfRlVOQ1RJT04KKyNlbmRpZgorCisvL3dpbmRvdyBzdHlsZXMKKyNkZWZpbmUgUFdTX0NISUxECQkJCQkJCTB4ODAwMDAwMDBMCisjZGVmaW5lIFBXU19CT1JERVIJCQkJCQkJMHg0MDAwMDAwMEwKKyNkZWZpbmUgUFdTX0JBQ0tHUk9VTkQJCQkJCQkweDIwMDAwMDAwTAorI2RlZmluZSBQV1NfSFNDUk9MTAkJCQkJCQkweDEwMDAwMDAwTAorI2RlZmluZSBQV1NfVlNDUk9MTAkJCQkJCQkweDA4MDAwMDAwTAorI2RlZmluZSBQV1NfVklTSUJMRQkJCQkJCQkweDA0MDAwMDAwTAorI2RlZmluZSBQV1NfRElTQUJMRQkJCQkJCQkweDAyMDAwMDAwTAorI2RlZmluZSBQV1NfUkVBRE9OTFkJCQkJCQkweDAxMDAwMDAwTAorI2RlZmluZSBQV1NfQVVUT0ZPTlRTSVpFCQkJCQkweDAwODAwMDAwTAorI2RlZmluZSBQV1NfQVVUT1RSQU5TUEFSRU5UCQkJCQkweDAwNDAwMDAwTAorI2RlZmluZSBQV1NfTk9SRUZSRVNIQ0xJUAkJCQkJMHgwMDIwMDAwMEwKKworLy9lZGl0IGFuZCBsYWJlbCBzdHlsZXMKKyNkZWZpbmUgUEVTX01VTFRJTElORQkJCQkJCTB4MDAwMUwKKyNkZWZpbmUgUEVTX1BBU1NXT1JECQkJCQkJMHgwMDAyTAorI2RlZmluZSBQRVNfTEVGVAkJCQkJCQkweDAwMDRMCisjZGVmaW5lIFBFU19SSUdIVAkJCQkJCQkweDAwMDhMCisjZGVmaW5lIFBFU19NSURETEUJCQkJCQkJMHgwMDEwTAorI2RlZmluZSBQRVNfVE9QCQkJCQkJCQkweDAwMjBMCisjZGVmaW5lIFBFU19CT1RUT00JCQkJCQkJMHgwMDQwTAorI2RlZmluZSBQRVNfQ0VOVEVSCQkJCQkJCTB4MDA4MEwKKyNkZWZpbmUgUEVTX0NIQVJBUlJBWQkJCQkJCTB4MDEwMEwKKyNkZWZpbmUgUEVTX0FVVE9TQ1JPTEwJCQkJCQkweDAyMDBMCisjZGVmaW5lIFBFU19BVVRPUkVUVVJOCQkJCQkJMHgwNDAwTAorI2RlZmluZSBQRVNfVU5ETwkJCQkJCQkweDA4MDBMCisjZGVmaW5lIFBFU19SSUNICQkJCQkJCTB4MTAwMEwKKyNkZWZpbmUgUEVTX1NQRUxMQ0hFQ0sJCQkJCQkweDIwMDBMCisjZGVmaW5lIFBFU19URVhUT1ZFUkZMT1cJCQkJCTB4NDAwMEwKKyNkZWZpbmUgUEVTX05PUkVBRAkJCQkJCQkweDgwMDBMCisKKy8vbGlzdGJveCBzdHlsZXMKKyNkZWZpbmUgUExCU19NVUxUSVBMRVNFTAkJCQkJMHgwMDAxTAorI2RlZmluZSBQTEJTX0hPVkVSU0VMCQkJCQkJMHgwMDA4TAorCisvL2NvbWJvYm94IHN0eWxlcworI2RlZmluZSBQQ0JTX0FMTE9XQ1VTVE9NVEVYVAkJCQkweDAwMDFMCisKKy8vcmljaGVkaXQgc3R5bGVzCisjZGVmaW5lIFBSRVNfTVVMVElMSU5FCQkJCQkJMHgwMDAxTAorI2RlZmluZSBQUkVTX0FVVE9SRVRVUk4JCQkJCQkweDAwMDJMCisjZGVmaW5lIFBSRVNfQVVUT1NDUk9MTAkJCQkJCTB4MDAwNEwKKyNkZWZpbmUgUFJFU19TUEVMTENIRUNLCQkJCQkJMHgwMDA4TAorI2RlZmluZSBQUkVTX1VORE8JCQkJCQkJMHgwMTAwTAorI2RlZmluZSBQUkVTX01VTFRJUEFHRVMJCQkJCQkweDAyMDBMCisjZGVmaW5lIFBSRVNfVEVYVE9WRVJGTE9XCQkJCQkweDA0MDBMCisKKy8vYm9yZGVyIHN0eWxlCisjZGVmaW5lIFBCU19TT0xJRAkJCQkJCQkwCisjZGVmaW5lIFBCU19EQVNICQkJCQkJCTEKKyNkZWZpbmUgUEJTX0JFVkVMRUQJCQkJCQkJMgorI2RlZmluZSBQQlNfSU5TRVQJCQkJCQkJMworI2RlZmluZSBQQlNfVU5ERVJMSU5FRAkJCQkJCTQKKyNkZWZpbmUgUEJTX1NIQURPVwkJCQkJCQk1CisKKy8vbm90aWZpY2F0aW9uIG1lc3NhZ2VzCisjZGVmaW5lIFBOTV9BRERDSElMRAkJCQkJCTB4MDAwMDAwMDBMCisjZGVmaW5lIFBOTV9SRU1PVkVDSElMRAkJCQkJCTB4MDAwMDAwMDFMCisjZGVmaW5lIFBOTV9TRVRTQ1JPTExJTkZPCQkJCQkweDAwMDAwMDAyTAorI2RlZmluZSBQTk1fU0VUU0NST0xMUE9TCQkJCQkweDAwMDAwMDAzTAorI2RlZmluZSBQTk1fU0NST0xMV0lORE9XCQkJCQkweDAwMDAwMDA0TAorI2RlZmluZSBQTk1fTEJVVFRPTkRPV04JCQkJCQkweDAwMDAwMDA1TAorI2RlZmluZSBQTk1fTEJVVFRPTlVQCQkJCQkJMHgwMDAwMDAwNkwKKyNkZWZpbmUgUE5NX01PVVNFTU9WRQkJCQkJCTB4MDAwMDAwMDdMCisjZGVmaW5lCVBOTV9OT1RFUkVTRVQJCQkJCQkweDAwMDAwMDA4TAorI2RlZmluZSBQTk1fU0VUQ0FSRVRJTkZPCQkJCQkweDAwMDAwMDA5TAorI2RlZmluZSBQTk1fU0VMQ0hBTkdFRAkJCQkJCTB4MDAwMDAwMEFMCisjZGVmaW5lCVBOTV9OT1RFRURJVENIQU5HRUQJCQkJCTB4MDAwMDAwMEJMCisKKyNkZWZpbmUgUFdMX0NMQVNTTkFNRV9FRElUCQkJCQkiQ1BXTF9FZGl0IgorCitzdHJ1Y3QgQ1BXTF9EYXNoCit7CisJQ1BXTF9EYXNoKEZYX0lOVDMyIGRhc2gsIEZYX0lOVDMyIGdhcCwgRlhfSU5UMzIgcGhhc2UpIDogbkRhc2goZGFzaCksIG5HYXAoZ2FwKSwgblBoYXNlKHBoYXNlKQorCXt9CisKKwlGWF9JTlQzMgkJCW5EYXNoOworCUZYX0lOVDMyCQkJbkdhcDsKKwlGWF9JTlQzMgkJCW5QaGFzZTsKK307CisKK3N0cnVjdCBQV0xfQ0xBU1MgQ1BXTF9Db2xvcgoreworCUNQV0xfQ29sb3IoRlhfSU5UMzIgdHlwZSA9IENPTE9SVFlQRV9UUkFOU1BBUkVOVCwgRlhfRkxPQVQgY29sb3IxID0gMC4wZiwgRlhfRkxPQVQgY29sb3IyID0gMC4wZiwgRlhfRkxPQVQgY29sb3IzID0gMC4wZiwgRlhfRkxPQVQgY29sb3I0ID0gMC4wZikKKwkJOiBuQ29sb3JUeXBlKHR5cGUpLCBmQ29sb3IxKGNvbG9yMSksIGZDb2xvcjIoY29sb3IyKSwgZkNvbG9yMyhjb2xvcjMpLCBmQ29sb3I0KGNvbG9yNCkKKwl7fQorCisJQ1BXTF9Db2xvcihGWF9JTlQzMiByLCBGWF9JTlQzMiBnLCBGWF9JTlQzMiBiKSA6CisJCW5Db2xvclR5cGUoQ09MT1JUWVBFX1JHQiksIGZDb2xvcjEoci8yNTUuMGYpLCBmQ29sb3IyKGcvMjU1LjBmKSwgZkNvbG9yMyhiLzI1NS4wZiksIGZDb2xvcjQoMCkKKwl7fQorCQorCXZvaWQgQ29udmVydENvbG9yVHlwZShGWF9JTlQzMiBuQ29sb3JUeXBlKTsKKworCS8qCisJQ09MT1JUWVBFX1RSQU5TUEFSRU5UCisJQ09MT1JUWVBFX1JHQgorCUNPTE9SVFlQRV9DTVlLCisJQ09MT1JUWVBFX0dSQVkKKwkqLworCUZYX0lOVDMyCQkJCQluQ29sb3JUeXBlOyAKKwlGWF9GTE9BVAkJCQkJZkNvbG9yMSxmQ29sb3IyLGZDb2xvcjMsZkNvbG9yNDsKK307CisKK2lubGluZSBGWF9CT09MIG9wZXJhdG9yID09IChjb25zdCBDUFdMX0NvbG9yICZjMSwgY29uc3QgQ1BXTF9Db2xvciAmYzIpCit7CisJcmV0dXJuIGMxLm5Db2xvclR5cGUgPT0gYzIubkNvbG9yVHlwZSAmJiAKKwkJYzEuZkNvbG9yMSAtIGMyLmZDb2xvcjEgPCAwLjAwMDEgJiYgYzEuZkNvbG9yMSAtIGMyLmZDb2xvcjEgPiAtMC4wMDAxICYmCisJCWMxLmZDb2xvcjIgLSBjMi5mQ29sb3IyIDwgMC4wMDAxICYmIGMxLmZDb2xvcjIgLSBjMi5mQ29sb3IyID4gLTAuMDAwMSAmJgorCQljMS5mQ29sb3IzIC0gYzIuZkNvbG9yMyA8IDAuMDAwMSAmJiBjMS5mQ29sb3IzIC0gYzIuZkNvbG9yMyA+IC0wLjAwMDEgJiYKKwkJYzEuZkNvbG9yNCAtIGMyLmZDb2xvcjQgPCAwLjAwMDEgJiYgYzEuZkNvbG9yNCAtIGMyLmZDb2xvcjQgPiAtMC4wMDAxOworfQorCitpbmxpbmUgRlhfQk9PTCBvcGVyYXRvciAhPSAoY29uc3QgQ1BXTF9Db2xvciAmYzEsIGNvbnN0IENQV0xfQ29sb3IgJmMyKQoreworCXJldHVybiAhb3BlcmF0b3IgPT0gKGMxLCBjMik7Cit9CisKKyNkZWZpbmUgUFdMX1NDUk9MTEJBUl9XSURUSAkJCQkJMTIuMGYKKyNkZWZpbmUgUFdMX1NDUk9MTEJBUl9CVVRUT05fV0lEVEgJCQk5LjBmCisjZGVmaW5lIFBXTF9TQ1JPTExCQVJfUE9TQlVUVE9OX01JTldJRFRICTIuMGYKKyNkZWZpbmUgUFdMX1NDUk9MTEJBUl9UUkFOU1BBUkFOQ1kJCQkxNTAKKyNkZWZpbmUgUFdMX1NDUk9MTEJBUl9CS0NPTE9SCQkJCUNQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwyMjAuMGYvMjU1LjBmLDIyMC4wZi8yNTUuMGYsMjIwLjBmLzI1NS4wZikKKyNkZWZpbmUgUFdMX0RFRkFVTFRfU0VMVEVYVENPTE9SCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLDEsMSwxKQorI2RlZmluZSBQV0xfREVGQVVMVF9TRUxCQUNLQ09MT1IJCQlDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsMCw1MS4wZi8yNTUuMGYsMTEzLjBmLzI1NS4wZikKKyNkZWZpbmUgUFdMX0RFRkFVTFRfQkFDS0NPTE9SCQkJCVBXTF9ERUZBVUxUX1NFTFRFWFRDT0xPUgorI2RlZmluZSBQV0xfREVGQVVMVF9URVhUQ09MT1IJCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLDAsMCwwKQorI2RlZmluZSBQV0xfREVGQVVMVF9GT05UU0laRQkJCQk5LjBmCisjZGVmaW5lIFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IJCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwKQorI2RlZmluZSBQV0xfREVGQVVMVF9XSElURUNPTE9SCQkJCUNQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMSkKKyNkZWZpbmUgUFdMX0RFRkFVTFRfSEVBVllHUkFZQ09MT1IJCQlDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDAuNTApCisjZGVmaW5lIFBXTF9ERUZBVUxUX0xJR0hUR1JBWUNPTE9SCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwLjc1KQorI2RlZmluZSBQV0xfVFJJQU5HTEVfSEFMRkxFTgkJCQkyLjBmCisjZGVmaW5lCVBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOCQkzLjBmCisjZGVmaW5lIFBXTF9JTlZBTElEQVRFX0lORkxBVEUJCQkJMgorCitjbGFzcyBJUFdMX1NwZWxsQ2hlY2sKK3sKK3B1YmxpYzoKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCQkJQ2hlY2tXb3JkKEZYX0xQQ1NUUiBzV29yZCkgPSAwOworCXZpcnR1YWwgdm9pZAkJCQkJCQlTdWdnZXN0V29yZHMoRlhfTFBDU1RSIHNXb3JkLCBDRlhfQnl0ZVN0cmluZ0FycmF5ICYgc1N1Z2dlc3QpID0gMDsJCit9OworCitjbGFzcyBJUFdMX1Byb3ZpZGVyCit7CitwdWJsaWM6CisJLy9nZXQgYSBtYXRyaXggd2hpY2ggbWFwIHVzZXIgc3BhY2UgdG8gQ1duZCBjbGllbnQgc3BhY2UKKwl2aXJ0dWFsIENQREZfTWF0cml4CQkJCQkJR2V0V2luZG93TWF0cml4KHZvaWQqIHBBdHRhY2hlZERhdGEpID0gMDsKKworCS8qCisJMCBMIiZVbmRvXHRDdHJsK1oiCisJMSBMIiZSZWRvXHRDdHJsK1NoaWZ0K1oiCisJMiBMIkN1JnRcdEN0cmwrWCIKKwkzIEwiJkNvcHlcdEN0cmwrQyIKKwk0IEwiJlBhc3RlXHRDdHJsK1YiCisJNSBMIiZEZWxldGUiCisJNiAgTCImU2VsZWN0IEFsbFx0Q3RybCtBIgorCSovCisJdmlydHVhbCBDRlhfV2lkZVN0cmluZwkJCQkJTG9hZFBvcHVwTWVudVN0cmluZyhGWF9JTlQzMiBuSW5kZXgpID0gMDsKK307CisKK2NsYXNzIElQV0xfRm9jdXNIYW5kbGVyCit7CitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCQkJCU9uU2V0Rm9jdXMoQ1BXTF9XbmQqIHBXbmQpID0gMDsKKwl2aXJ0dWFsIHZvaWQJCQkJCQkJT25LaWxsRm9jdXMoQ1BXTF9XbmQqIHBXbmQpID0gMDsKK307CisKK3N0cnVjdCBQV0xfQ1JFQVRFUEFSQU0KK3sKK3B1YmxpYzoKKwlQV0xfQ1JFQVRFUEFSQU0oKSA6IHJjUmVjdFduZCgwLDAsMCwwKSwKKwkJcFN5c3RlbUhhbmRsZXIoTlVMTCksCisJCXBGb250TWFwKE5VTEwpLAorCQlwUHJvdmlkZXIoTlVMTCksCisJCXBGb2N1c0hhbmRsZXIoTlVMTCksCisJCWR3RmxhZ3MoMCksCisJCXNCYWNrZ3JvdW5kQ29sb3IoKSwKKwkJaEF0dGFjaGVkV25kKE5VTEwpLAorCQlwU3BlbGxDaGVjayhOVUxMKSwKKwkJbkJvcmRlclN0eWxlKFBCU19TT0xJRCksCisJCWR3Qm9yZGVyV2lkdGgoMSksCisJCXNCb3JkZXJDb2xvcigpLAorCQlzVGV4dENvbG9yKCksCisJCXNUZXh0U3Ryb2tlQ29sb3IoKSwKKwkJblRyYW5zcGFyZW5jeSgyNTUpLAorCQlmRm9udFNpemUoUFdMX0RFRkFVTFRfRk9OVFNJWkUpLAorCQlzRGFzaCgzLDAsMCksCQorCQlwQXR0YWNoZWREYXRhKE5VTEwpLAorCQlwUGFyZW50V25kKE5VTEwpLAorCQlwTXNnQ29udHJvbChOVUxMKSwKKwkJZUN1cnNvclR5cGUoRlhDVF9BUlJPVyksCisJCW10Q2hpbGQoMSwwLDAsMSwwLDApCisJeworCX0KKworCUNQREZfUmVjdAkJCQlyY1JlY3RXbmQ7CQkJCS8vcmVxdWlyZWQJCisJSUZYX1N5c3RlbUhhbmRsZXIqCQlwU3lzdGVtSGFuZGxlcjsJCQkvL3JlcXVpcmVkCisJSUZYX0VkaXRfRm9udE1hcCoJCXBGb250TWFwOwkJCQkvL3JlcXVpcmVkIGZvciB0ZXh0IHdpbmRvdworCUlQV0xfUHJvdmlkZXIqCQkJcFByb3ZpZGVyOwkJCQkvL3JlcXVpcmVkIGZvciBzZWxmIGNvb3JkaW5hdGUKKwlJUFdMX0ZvY3VzSGFuZGxlcioJCXBGb2N1c0hhbmRsZXI7CQkJLy9vcHRpb25hbAorCUZYX0RXT1JECQkJCWR3RmxhZ3M7CQkJCS8vb3B0aW9uYWwKKwlDUFdMX0NvbG9yCQkJCXNCYWNrZ3JvdW5kQ29sb3I7CQkvL29wdGlvbmFsCisJRlhfSFdORAkJCQkJaEF0dGFjaGVkV25kOwkJCS8vcmVxdWlyZWQgZm9yIG5vLXJlYWRlciBmcmFtZXdvcmsKKwlJUFdMX1NwZWxsQ2hlY2sqCQlwU3BlbGxDaGVjazsJCQkvL3JlcXVpcmVkIGZvciBzcGVsbGNoZWNraW5nCisJRlhfSU5UMzIJCQkJbkJvcmRlclN0eWxlOwkJCS8vb3B0aW9uYWwKKwlGWF9JTlQzMgkJCQlkd0JvcmRlcldpZHRoOwkJCS8vb3B0aW9uYWwKKwlDUFdMX0NvbG9yCQkJCXNCb3JkZXJDb2xvcjsJCQkvL29wdGlvbmFsCisJQ1BXTF9Db2xvcgkJCQlzVGV4dENvbG9yOwkJCQkvL29wdGlvbmFsCisJQ1BXTF9Db2xvcgkJCQlzVGV4dFN0cm9rZUNvbG9yOwkJLy9vcHRpb25hbAorCUZYX0lOVDMyCQkJCW5UcmFuc3BhcmVuY3k7CQkJLy9vcHRpb25hbAorCUZYX0ZMT0FUCQkJCWZGb250U2l6ZTsJCQkJLy9vcHRpb25hbAorCUNQV0xfRGFzaAkJCQlzRGFzaDsJCQkJCS8vb3B0aW9uYWwKKwl2b2lkKgkJCQkJcEF0dGFjaGVkRGF0YTsJCQkvL29wdGlvbmFsCisJQ1BXTF9XbmQqCQkJCXBQYXJlbnRXbmQ7CQkJCS8vaWdub3JlCisJQ1BXTF9Nc2dDb250cm9sKgkJcE1zZ0NvbnRyb2w7CQkJLy9pZ25vcmUKKwlGWF9JTlQzMgkJCQllQ3Vyc29yVHlwZTsJCQkvL2lnbm9yZQorCUNQREZfTWF0cml4CQkJCW10Q2hpbGQ7CQkJCS8vaWdub3JlCit9OworCitjbGFzcyBDUFdMX1RpbWVyCit7CitwdWJsaWM6CisJQ1BXTF9UaW1lcihDUFdMX1RpbWVySGFuZGxlciogcEF0dGFjaGVkLCBJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIpOworCXZpcnR1YWwgfkNQV0xfVGltZXIoKTsKKworCUZYX0lOVDMyCQkJCQkJCVNldFBXTFRpbWVyKEZYX0lOVDMyIG5FbGFwc2UpOworCXZvaWQJCQkJCQkJCUtpbGxQV0xUaW1lcigpOworCXN0YXRpYyB2b2lkIAkJCQkJCVRpbWVyUHJvYyhGWF9JTlQzMiBpZEV2ZW50KTsKKworcHJpdmF0ZToKKwlGWF9JTlQzMgkJCQkJCQltX25UaW1lcklEOwkKKwlDUFdMX1RpbWVySGFuZGxlcioJCQkJCW1fcEF0dGFjaGVkOworCUlGWF9TeXN0ZW1IYW5kbGVyKgkJCQkJbV9wU3lzdGVtSGFuZGxlcjsKK307CisKK2NsYXNzIFBXTF9DTEFTUyBDUFdMX1RpbWVySGFuZGxlcgoreworcHVibGljOgorCUNQV0xfVGltZXJIYW5kbGVyKCk7CisJdmlydHVhbCB+Q1BXTF9UaW1lckhhbmRsZXIoKTsKKworCXZvaWQJCQkJCQkJCUJlZ2luVGltZXIoRlhfSU5UMzIgbkVsYXBzZSk7CisJdm9pZAkJCQkJCQkJRW5kVGltZXIoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCQlUaW1lclByb2MoKTsKKwl2aXJ0dWFsIElGWF9TeXN0ZW1IYW5kbGVyKgkJCUdldFN5c3RlbUhhbmRsZXIoKSBjb25zdCA9IDA7CisKK3ByaXZhdGU6CisJQ1BXTF9UaW1lcioJCQkJCQkJbV9wVGltZXI7Cit9OworCitjbGFzcyBQV0xfQ0xBU1MgQ1BXTF9XbmQgOiBwdWJsaWMgQ1BXTF9UaW1lckhhbmRsZXIKK3sKKwlmcmllbmQgY2xhc3MgQ1BXTF9Nc2dDb250cm9sOworcHVibGljOgorCUNQV0xfV25kKCk7CisJdmlydHVhbCB+Q1BXTF9XbmQoKTsKKworCXZvaWQJCQkJCQkJQ3JlYXRlKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIENGWF9CeXRlU3RyaW5nCQkJR2V0Q2xhc3NOYW1lKCkgY29uc3Q7CQorCXZvaWQJCQkJCQkJRGVzdHJveSgpOworCXZvaWQJCQkJCQkJTW92ZShjb25zdCBDUERGX1JlY3QgJiByY05ldyxGWF9CT09MIGJSZXNldCxGWF9CT09MIGJSZWZyZXNoKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCUludmFsaWRhdGVSZWN0KENQREZfUmVjdCogcFJlY3QgPSBOVUxMKTsKKworCXZvaWQJCQkJCQkJR2V0QXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVN0cmluZyAmIHNBcHBTdHJlYW0pOworCXZvaWQJCQkJCQkJRHJhd0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSk7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbktleVVwKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uQ2hhcihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbkxCdXR0b25EYmxDbGsoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbk1CdXR0b25EYmxDbGsoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbk1CdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25NQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPblJCdXR0b25EYmxDbGsoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPblJCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCXZpcnR1YWwgRlhfQk9PTAkJCQkJT25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZyk7CisJdmlydHVhbCBGWF9CT09MCQkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCU9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpOworCisJdmlydHVhbCB2b2lkCQkJCQlTZXRGb2N1cygpOworCXZpcnR1YWwgdm9pZAkJCQkJS2lsbEZvY3VzKCk7CisJdm9pZAkJCQkJCQlTZXRDYXB0dXJlKCk7CisJdm9pZAkJCQkJCQlSZWxlYXNlQ2FwdHVyZSgpOworCisJdmlydHVhbCB2b2lkCQkJCQlPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtID0gMCwgRlhfSU5UUFRSIGxQYXJhbSA9IDApOworCXZpcnR1YWwgdm9pZAkJCQkJU2V0VGV4dENvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcik7CisJdmlydHVhbCB2b2lkCQkJCQlTZXRUZXh0U3Ryb2tlQ29sb3IoY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCVNldFZpc2libGUoRlhfQk9PTCBiVmlzaWJsZSk7CisKKwl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRGb2N1c1JlY3QoKSBjb25zdDsKKwl2aXJ0dWFsIENQV0xfQ29sb3IJCQkJR2V0QmFja2dyb3VuZENvbG9yKCkgY29uc3Q7CisJdmlydHVhbCBDUFdMX0NvbG9yCQkJCUdldEJvcmRlckNvbG9yKCkgY29uc3Q7CisJdmlydHVhbCBDUFdMX0NvbG9yCQkJCUdldFRleHRDb2xvcigpIGNvbnN0OworCXZpcnR1YWwgQ1BXTF9Db2xvcgkJCQlHZXRUZXh0U3Ryb2tlQ29sb3IoKSBjb25zdDsKKwl2aXJ0dWFsIEZYX0ZMT0FUCQkJCUdldEZvbnRTaXplKCkgY29uc3Q7CisJdmlydHVhbCBGWF9JTlQzMgkJCQlHZXRJbm5lckJvcmRlcldpZHRoKCkgY29uc3Q7CisJdmlydHVhbCBDUFdMX0NvbG9yCQkJCUdldEJvcmRlckxlZnRUb3BDb2xvcihGWF9JTlQzMiBuQm9yZGVyU3R5bGUpIGNvbnN0OworCXZpcnR1YWwgQ1BXTF9Db2xvcgkJCQlHZXRCb3JkZXJSaWdodEJvdHRvbUNvbG9yKEZYX0lOVDMyIG5Cb3JkZXJTdHlsZSkgY29uc3Q7CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJCUlzTW9kaWZpZWQoKSBjb25zdCB7cmV0dXJuIEZBTFNFO30KKworCXZpcnR1YWwgdm9pZAkJCQkJU2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKTsJCisKKwl2b2lkCQkJCQkJCVNldEJhY2tncm91bmRDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpOwkJCisJdm9pZAkJCQkJCQlTZXRCb3JkZXJDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpOworCXZvaWQJCQkJCQkJU2V0Qm9yZGVyV2lkdGgoRlhfSU5UMzIgbkJvcmRlcldpZHRoKTsKKwl2b2lkCQkJCQkJCVNldENsaXBSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QpOworCXZvaWQJCQkJCQkJU2V0Qm9yZGVyU3R5bGUoRlhfSU5UMzIgZUJvcmRlclN0eWxlKTsJCisJdm9pZAkJCQkJCQlTZXRCb3JkZXJEYXNoKGNvbnN0IENQV0xfRGFzaCAmIHNEYXNoKTsKKworCUNQREZfUmVjdAkJCQkJCUdldE9yaWdpbldpbmRvd1JlY3QoKSBjb25zdDsKKwl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRXaW5kb3dSZWN0KCkgY29uc3Q7CisJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Q2xpZW50UmVjdCgpIGNvbnN0OworCUNQREZfUG9pbnQJCQkJCQlHZXRDZW50ZXJQb2ludCgpIGNvbnN0OworCUNQREZfUmVjdAkJCQkJCUdldENsaWVudENlbnRlclNxdWFyZSgpIGNvbnN0OworCUNQREZfUmVjdAkJCQkJCUdldFdpbmRvd0NlbnRlclNxdWFyZSgpIGNvbnN0OwkJCisJRlhfSU5UMzIJCQkJCQlHZXRCb3JkZXJXaWR0aCgpIGNvbnN0OwkJCisJRlhfQk9PTAkJCQkJCQlJc1Zpc2libGUoKSBjb25zdCB7cmV0dXJuIG1fYlZpc2libGU7fQkKKwlGWF9CT09MCQkJCQkJCUhhc0ZsYWcoRlhfRFdPUkQgZHdGbGFncykgY29uc3Q7CisJdm9pZAkJCQkJCQlBZGRGbGFnKEZYX0RXT1JEIGR3RmxhZ3MpOworCXZvaWQJCQkJCQkJUmVtb3ZlRmxhZyhGWF9EV09SRCBkd0ZsYWdzKTsKKwlDUERGX1JlY3QJCQkJCQlHZXRDbGlwUmVjdCgpIGNvbnN0OwkJCisJQ1BXTF9XbmQqCQkJCQkJR2V0UGFyZW50V2luZG93KCkgY29uc3Q7CQkKKwlGWF9JTlQzMgkJCQkJCUdldEJvcmRlclN0eWxlKCkgY29uc3Q7CQorCUNQV0xfRGFzaAkJCQkJCUdldEJvcmRlckRhc2goKSBjb25zdDsKKwl2b2lkKgkJCQkJCQlHZXRBdHRhY2hlZERhdGEoKSBjb25zdDsKKwkKKwlGWF9CT09MCQkJCQkJCVduZEhpdFRlc3QoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCUNsaWVudEhpdFRlc3QoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCUlzQ2FwdHVyZU1vdXNlKCkgY29uc3Q7CisKKwljb25zdCBDUFdMX1duZCoJCQkJCUdldEZvY3VzZWQoKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCUlzRm9jdXNlZCgpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJSXNSZWFkT25seSgpIGNvbnN0OworCUNQV0xfU2Nyb2xsQmFyKgkJCQkJR2V0VlNjcm9sbEJhcigpIGNvbnN0OworCisJSUZYX0VkaXRfRm9udE1hcCoJCQkJR2V0Rm9udE1hcCgpIGNvbnN0OworCUlQV0xfUHJvdmlkZXIqCQkJCQlHZXRQcm92aWRlcigpIGNvbnN0OworCXZpcnR1YWwgSUZYX1N5c3RlbUhhbmRsZXIqCQlHZXRTeXN0ZW1IYW5kbGVyKCkgY29uc3Q7CisJSVBXTF9Gb2N1c0hhbmRsZXIqCQkJCUdldEZvY3VzSGFuZGxlcigpIGNvbnN0OworCQorCUZYX0lOVDMyCQkJCQkJR2V0VHJhbnNwYXJlbmN5KCk7CisJdm9pZAkJCQkJCQlTZXRUcmFuc3BhcmVuY3koRlhfSU5UMzIgblRyYW5zcGFyZW5jeSk7CisKKwlDUERGX01hdHJpeAkJCQkJCUdldENoaWxkVG9Sb290KCkgY29uc3Q7CisJQ1BERl9NYXRyaXgJCQkJCQlHZXRDaGlsZE1hdHJpeCgpIGNvbnN0OworCXZvaWQJCQkJCQkJU2V0Q2hpbGRNYXRyaXgoY29uc3QgQ1BERl9NYXRyaXgmIG10KTsKKwlDUERGX01hdHJpeAkJCQkJCUdldFdpbmRvd01hdHJpeCgpIGNvbnN0OworCisJdmlydHVhbCBDUERGX1BvaW50CQkJCUNoaWxkVG9QYXJlbnQoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0OworCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUNoaWxkVG9QYXJlbnQoY29uc3QgQ1BERl9SZWN0JiByZWN0KSBjb25zdDsKKwl2aXJ0dWFsIENQREZfUG9pbnQJCQkJUGFyZW50VG9DaGlsZChjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3Q7CisJdmlydHVhbCBDUERGX1JlY3QJCQkJUGFyZW50VG9DaGlsZChjb25zdCBDUERGX1JlY3QmIHJlY3QpIGNvbnN0OworCisJLy90aG9zZSBtZXRob2RzIG9ubHkgaW1wbGVtZW50ZWQgYnkgbGlzdGN0cmwgaXRlbQorCXZpcnR1YWwgRlhfRkxPQVQJCQkJR2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkge3JldHVybiAwO30gCisJdmlydHVhbCBGWF9GTE9BVAkJCQlHZXRJdGVtTGVmdE1hcmdpbigpIHtyZXR1cm4gMDt9IAorCXZpcnR1YWwgRlhfRkxPQVQJCQkJR2V0SXRlbVJpZ2h0TWFyZ2luKCkge3JldHVybiAwO30gCisKKwl2b2lkCQkJCQkJCUVuYWJsZVdpbmRvdyhGWF9CT09MIGJFbmFibGUpOworCUZYX0JPT0wJCQkJCQkJSXNFbmFibGVkKCk7CisJdmlydHVhbCB2b2lkCQkJCQlTZXRDdXJzb3IoKTsKKworcHJvdGVjdGVkOgkKKwl2aXJ0dWFsIHZvaWQJCQkJCUNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCVJlUG9zQ2hpbGRXbmQoKTsKKwl2b2lkCQkJCQkJCUdldEFwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSk7CisJdmlydHVhbCB2b2lkCQkJCQlHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsKKwl2aXJ0dWFsIHZvaWQJCQkJCUdldENoaWxkQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKTsKKworCXZpcnR1YWwgdm9pZAkJCQkJRHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpOworCXZpcnR1YWwgdm9pZAkJCQkJRHJhd0NoaWxkQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKTsKKworCXZpcnR1YWwgdm9pZAkJCQkJT25DcmVhdGUoUFdMX0NSRUFURVBBUkFNICYgY3ApOworCXZpcnR1YWwgdm9pZAkJCQkJT25DcmVhdGVkKCk7CisJdmlydHVhbCB2b2lkCQkJCQlPbkRlc3Ryb3koKTsKKworCXZpcnR1YWwgdm9pZAkJCQkJT25TZXRGb2N1cygpOworCXZpcnR1YWwgdm9pZAkJCQkJT25LaWxsRm9jdXMoKTsKKworCXZpcnR1YWwgdm9pZAkJCQkJT25FbmFibGVkKCk7CisJdmlydHVhbCB2b2lkCQkJCQlPbkRpc2FibGVkKCk7CisKKwl2b2lkCQkJCQkJCVNldE5vdGlmeUZsYWcoRlhfQk9PTCBiTm90aWZ5aW5nID0gVFJVRSl7bV9iTm90aWZ5aW5nID0gYk5vdGlmeWluZzt9OworIAorCUZYX0JPT0wJCQkJCQkJSXNWYWxpZCgpIGNvbnN0OworCVBXTF9DUkVBVEVQQVJBTQkJCQkJR2V0Q3JlYXRpb25QYXJhbSgpIGNvbnN0OwkJCisJRlhfQk9PTAkJCQkJCQlJc05vdGlmeWluZygpIGNvbnN0IHtyZXR1cm4gbV9iTm90aWZ5aW5nO30JCisJCisJdm9pZAkJCQkJCQlJbnZhbGlkYXRlUmVjdE1vdmUoY29uc3QgQ1BERl9SZWN0ICYgcmNPbGQsIGNvbnN0IENQREZfUmVjdCAmIHJjTmV3KTsKKworCXZvaWQJCQkJCQkJUFdMdG9XbmQoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9JTlQzMiYgeCwgRlhfSU5UMzImIHkpIGNvbnN0OworCUZYX1JFQ1QJCQkJCQkJUFdMdG9XbmQoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgY29uc3Q7CQorCUZYX0hXTkQJCQkJCQkJR2V0QXR0YWNoZWRIV25kKCkgY29uc3Q7CisJCisJRlhfQk9PTAkJCQkJCQlJc1duZENhcHR1cmVNb3VzZShjb25zdCBDUFdMX1duZCAqIHBXbmQpIGNvbnN0OworCUZYX0JPT0wJCQkJCQkJSXNXbmRDYXB0dXJlS2V5Ym9hcmQoY29uc3QgQ1BXTF9XbmQgKiBwV25kKSBjb25zdDsJCisJY29uc3QgQ1BXTF9XbmQqCQkJCQlHZXRSb290V25kKCkgY29uc3Q7CQorCisJRlhfQk9PTAkJCQkJCQlJc0NUUkxwcmVzc2VkKEZYX0RXT1JEIG5GbGFnKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCUlzU0hJRlRwcmVzc2VkKEZYX0RXT1JEIG5GbGFnKSBjb25zdDsKKwlGWF9CT09MCQkJCQkJCUlzQUxUcHJlc3NlZChGWF9EV09SRCBuRmxhZykgY29uc3Q7CisJRlhfQk9PTAkJCQkJCQlJc0lOU0VSVHByZXNzZWQoRlhfRFdPUkQgbkZsYWcpIGNvbnN0OworCitwcml2YXRlOgorCXZvaWQJCQkJCQkJQWRkQ2hpbGQoQ1BXTF9XbmQgKiBwV25kKTsKKwl2b2lkCQkJCQkJCVJlbW92ZUNoaWxkKENQV0xfV25kICogcFduZCk7CisKKwl2b2lkCQkJCQkJCUNyZWF0ZVNjcm9sbEJhcihjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCk7CisJdm9pZAkJCQkJCQlDcmVhdGVWU2Nyb2xsQmFyKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKTsJCisKKwl2b2lkCQkJCQkJCUFqdXN0U3R5bGUoKTsJCisJdm9pZAkJCQkJCQlDcmVhdGVNc2dDb250cm9sKCk7CisJdm9pZAkJCQkJCQlEZXN0cm95TXNnQ29udHJvbCgpOworCQorCUNQV0xfTXNnQ29udHJvbCoJCQkJR2V0TXNnQ29udHJvbCgpIGNvbnN0OwkKKwkKK3Byb3RlY3RlZDoKKwlDRlhfQXJyYXlUZW1wbGF0ZTxDUFdMX1duZCo+CW1fYUNoaWxkcmVuOworCitwcml2YXRlOgorCVBXTF9DUkVBVEVQQVJBTQkJCQkJbV9zUHJpdmF0ZVBhcmFtOworCQorCUNQV0xfU2Nyb2xsQmFyKgkJCQkJbV9wVlNjcm9sbEJhcjsKKworCUNQREZfUmVjdAkJCQkJCW1fcmNXaW5kb3c7CisJQ1BERl9SZWN0CQkJCQkJbV9yY0NsaXA7CisKKwlGWF9CT09MCQkJCQkJCW1fYkNyZWF0ZWQ7CQkJCisJRlhfQk9PTAkJCQkJCQltX2JWaXNpYmxlOworCUZYX0JPT0wJCQkJCQkJbV9iTm90aWZ5aW5nOwkKKwlGWF9CT09MCQkJCQkJCW1fYkVuYWJsZWQ7Cit9OworCisvLyAjaWZuZGVmIFZLX0VORAorLy8gCisvLyAjZGVmaW5lIFZLX0VORCAgICAgICAgICAgIDB4MjMKKy8vICNkZWZpbmUgVktfSE9NRSAgICAgICAgICAgMHgyNAorLy8gI2RlZmluZSBWS19MRUZUICAgICAgICAgICAweDI1CisvLyAjZGVmaW5lIFZLX1VQICAgICAgICAgICAgIDB4MjYKKy8vICNkZWZpbmUgVktfUklHSFQgICAgICAgICAgMHgyNworLy8gI2RlZmluZSBWS19ET1dOICAgICAgICAgICAweDI4CisvLyAjZGVmaW5lIFZLX0lOU0VSVCAgICAgICAgIDB4MkQKKy8vICNkZWZpbmUgVktfREVMRVRFICAgICAgICAgMHgyRQorLy8gCisvLyAjZGVmaW5lIFZLX0JBQ0sgICAgICAgICAgIDB4MDgKKy8vICNkZWZpbmUgVktfVEFCICAgICAgICAgICAgMHgwOQorLy8gCisvLyAjZGVmaW5lIFZLX0NMRUFSICAgICAgICAgIDB4MEMKKy8vICNkZWZpbmUgVktfUkVUVVJOICAgICAgICAgMHgwRAorLy8gI2RlZmluZSBWS19FU0NBUEUgICAgICAgICAweDFCCisvLyAjZGVmaW5lIFZLX1NQQUNFICAgICAgICAgIDB4MjAKKy8vICNlbmRpZgorLy8gCisvLyAjZGVmaW5lIFZLX05PTkUJCQkgIDAKKworI2VuZGlmIC8vICFkZWZpbmVkKEFGWF9QV0xfV05EX0hfX0QzMjgxMkFEX0E4NzVfNEUwOF85RDNDXzBBNTcwMjA5ODdDNl9fSU5DTFVERURfKQorCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX0NCQV9Gb250bWFwLmNwcCBiL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX0NCQV9Gb250bWFwLmNwcAppbmRleCA1OTYxN2FjLi4wYzdjZDQ4IDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9DQkFfRm9udG1hcC5jcHAKKysrIGIvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfQ0JBX0ZvbnRtYXAuY3BwCkBAIC0xLDMwMCArMSwzMDAgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRm9ybUZpbGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NCQV9Gb250bWFwLmgiDQotDQotQ0JBX0ZvbnRNYXA6OkNCQV9Gb250TWFwKENQREZTREtfQW5ub3QqIHBBbm5vdCwgSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyKSA6DQotCUNQV0xfRm9udE1hcChwU3lzdGVtSGFuZGxlciksDQotCW1fcERvY3VtZW50KE5VTEwpLA0KLQltX3BBbm5vdERpY3QoTlVMTCksDQotCW1fcERlZmF1bHRGb250KE5VTEwpLA0KLQltX3NBUFR5cGUoIk4iKQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9QYWdlKiBwUGFnZSA9IHBBbm5vdC0+R2V0UERGUGFnZSgpOw0KLQ0KLQltX3BEb2N1bWVudCA9IHBQYWdlLT5tX3BEb2N1bWVudDsNCi0JbV9wQW5ub3REaWN0ID0gcEFubm90LT5HZXRQREZBbm5vdCgpLT5tX3BBbm5vdERpY3Q7DQotfQ0KLQ0KLUNCQV9Gb250TWFwOjpDQkFfRm9udE1hcChDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRGljdGlvbmFyeSogcEFubm90RGljdCwgDQotCQkJCQkJIElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlcikgOg0KLQlDUFdMX0ZvbnRNYXAocFN5c3RlbUhhbmRsZXIpLA0KLQltX3BEb2N1bWVudChwRG9jdW1lbnQpLA0KLQltX3BBbm5vdERpY3QocEFubm90RGljdCksDQotCW1fcERlZmF1bHRGb250KE5VTEwpLA0KLQltX3NBUFR5cGUoIk4iKQ0KLXsNCi19DQotDQotQ0JBX0ZvbnRNYXA6On5DQkFfRm9udE1hcCgpDQotew0KLX0NCi0NCi12b2lkIENCQV9Gb250TWFwOjpSZXNldCgpDQotew0KLQlFbXB0eSgpOw0KLQltX3BEZWZhdWx0Rm9udCA9IE5VTEw7DQotCW1fc0RlZmF1bHRGb250TmFtZSA9ICIiOw0KLX0NCi0NCi12b2lkIENCQV9Gb250TWFwOjpJbml0aWFsKEZYX0xQQ1NUUiBmb250bmFtZSkNCi17DQotCUZYX0lOVDMyIG5DaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VUOw0KLQ0KLQlpZiAoIW1fcERlZmF1bHRGb250KQ0KLQl7DQotCQltX3BEZWZhdWx0Rm9udCA9IEdldEFubm90RGVmYXVsdEZvbnQobV9zRGVmYXVsdEZvbnROYW1lKTsJDQotCQlpZiAobV9wRGVmYXVsdEZvbnQpDQotCQl7DQotCQkJaWYgKGNvbnN0IENGWF9TdWJzdEZvbnQqIHBTdWJzdEZvbnQgPSBtX3BEZWZhdWx0Rm9udC0+R2V0U3Vic3RGb250KCkpDQotCQkJCW5DaGFyc2V0ID0gcFN1YnN0Rm9udC0+bV9DaGFyc2V0Ow0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCWlmIChtX3NEZWZhdWx0Rm9udE5hbWUgPT0gIldpbmdkaW5ncyIgfHwgbV9zRGVmYXVsdEZvbnROYW1lID09ICJXaW5nZGluZ3MyIiB8fA0KLQkJCQkJbV9zRGVmYXVsdEZvbnROYW1lID09ICJXaW5nZGluZ3MzIiB8fCBtX3NEZWZhdWx0Rm9udE5hbWUgPT0gIldlYmRpbmdzIikNCi0JCQkJCQluQ2hhcnNldCA9IFNZTUJPTF9DSEFSU0VUOw0KLQkJCQllbHNlDQotCQkJCQluQ2hhcnNldCA9IEFOU0lfQ0hBUlNFVDsNCi0JCQl9DQotCQkJQWRkRm9udERhdGEobV9wRGVmYXVsdEZvbnQsIG1fc0RlZmF1bHRGb250TmFtZSwgbkNoYXJzZXQpOw0KLQkJCUFkZEZvbnRUb0Fubm90RGljdChtX3BEZWZhdWx0Rm9udCwgbV9zRGVmYXVsdEZvbnROYW1lKTsNCi0JCX0NCi0JfQ0KLQ0KLQlpZiAobkNoYXJzZXQgIT0gQU5TSV9DSEFSU0VUKQ0KLQkJQ1BXTF9Gb250TWFwOjpJbml0aWFsKGZvbnRuYW1lKTsNCi19DQotDQotdm9pZCBDQkFfRm9udE1hcDo6U2V0RGVmYXVsdEZvbnQoQ1BERl9Gb250ICogcEZvbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nICYgc0ZvbnROYW1lKQ0KLXsNCi0JQVNTRVJUKHBGb250ICE9IE5VTEwpOw0KLQ0KLQlpZiAobV9wRGVmYXVsdEZvbnQpIHJldHVybjsNCi0NCi0JbV9wRGVmYXVsdEZvbnQgPSBwRm9udDsNCi0JbV9zRGVmYXVsdEZvbnROYW1lID0gc0ZvbnROYW1lOw0KLQ0KLS8vCWlmIChtX3NEZWZhdWx0Rm9udE5hbWUuSXNFbXB0eSgpKQ0KLS8vCQltX3NEZWZhdWx0Rm9udE5hbWUgPSBwRm9udC0+R2V0Rm9udFR5cGVOYW1lKCk7DQotDQotCUZYX0lOVDMyIG5DaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VUOw0KLQlpZiAoY29uc3QgQ0ZYX1N1YnN0Rm9udCogcFN1YnN0Rm9udCA9IG1fcERlZmF1bHRGb250LT5HZXRTdWJzdEZvbnQoKSkNCi0JCW5DaGFyc2V0ID0gcFN1YnN0Rm9udC0+bV9DaGFyc2V0Ow0KLQlBZGRGb250RGF0YShtX3BEZWZhdWx0Rm9udCwgbV9zRGVmYXVsdEZvbnROYW1lLCBuQ2hhcnNldCk7DQotfQ0KLQ0KLUNQREZfRm9udCogQ0JBX0ZvbnRNYXA6OkZpbmRGb250U2FtZUNoYXJzZXQoQ0ZYX0J5dGVTdHJpbmcmIHNGb250QWxpYXMsIEZYX0lOVDMyIG5DaGFyc2V0KQ0KLXsNCi0JQVNTRVJUKG1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0NCi0JaWYgKG1fcEFubm90RGljdC0+R2V0U3RyaW5nKCJTdWJ0eXBlIikgPT0gIldpZGdldCIpDQotCXsNCi0JCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IEdldERvY3VtZW50KCk7DQotCQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQkJQ1BERl9EaWN0aW9uYXJ5ICogcFJvb3REaWN0ID0gcERvY3VtZW50LT5HZXRSb290KCk7DQotCQlpZiAoIXBSb290RGljdCkgcmV0dXJuIE5VTEw7DQotDQotCQlDUERGX0RpY3Rpb25hcnkqIHBBY3JvRm9ybURpY3QgPSBwUm9vdERpY3QtPkdldERpY3QoIkFjcm9Gb3JtIik7DQotCQlpZiAoIXBBY3JvRm9ybURpY3QpIHJldHVybiBOVUxMOw0KLQ0KLQkJQ1BERl9EaWN0aW9uYXJ5ICogcERSRGljdCA9IHBBY3JvRm9ybURpY3QtPkdldERpY3QoIkRSIik7DQotCQlpZiAoIXBEUkRpY3QpIHJldHVybiBOVUxMOw0KLQ0KLQkJcmV0dXJuIEZpbmRSZXNGb250U2FtZUNoYXJzZXQocERSRGljdCwgc0ZvbnRBbGlhcywgbkNoYXJzZXQpOw0KLQl9DQotDQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi1DUERGX0RvY3VtZW50KiBDQkFfRm9udE1hcDo6R2V0RG9jdW1lbnQoKQ0KLXsNCi0JcmV0dXJuIG1fcERvY3VtZW50Ow0KLX0NCi0NCi1DUERGX0ZvbnQqIENCQV9Gb250TWFwOjpGaW5kUmVzRm9udFNhbWVDaGFyc2V0KENQREZfRGljdGlvbmFyeSogcFJlc0RpY3QsIENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzLCANCi0JCQkJCQkJCQkJCQkJRlhfSU5UMzIgbkNoYXJzZXQpDQotew0KLQlpZiAoIXBSZXNEaWN0KSByZXR1cm4gTlVMTDsNCi0NCi0JQ1BERl9Eb2N1bWVudCogcERvY3VtZW50ID0gR2V0RG9jdW1lbnQoKTsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwRm9udHMgPSBwUmVzRGljdC0+R2V0RGljdCgiRm9udCIpOw0KLQlpZiAocEZvbnRzID09IE5VTEwpIHJldHVybiBOVUxMOw0KLQ0KLQlDUERGX0ZvbnQqIHBGaW5kID0gTlVMTDsNCi0NCi0JRlhfUE9TSVRJT04gcG9zID0gcEZvbnRzLT5HZXRTdGFydFBvcygpOw0KLQl3aGlsZSAocG9zKQ0KLQl7DQotCQlDUERGX09iamVjdCogcE9iaiA9IE5VTEw7DQotCQlDRlhfQnl0ZVN0cmluZyBjc0tleTsNCi0JCXBPYmogPSBwRm9udHMtPkdldE5leHRFbGVtZW50KHBvcywgY3NLZXkpOw0KLQkJaWYgKHBPYmogPT0gTlVMTCkgY29udGludWU7DQotDQotCQlDUERGX09iamVjdCogcERpcmVjdCA9IHBPYmotPkdldERpcmVjdCgpOw0KLQkJaWYgKHBEaXJlY3QgPT0gTlVMTCB8fCBwRGlyZWN0LT5HZXRUeXBlKCkgIT0gUERGT0JKX0RJQ1RJT05BUlkpIGNvbnRpbnVlOw0KLQ0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwRWxlbWVudCA9IChDUERGX0RpY3Rpb25hcnkqKXBEaXJlY3Q7DQotCQlpZiAocEVsZW1lbnQtPkdldFN0cmluZygiVHlwZSIpICE9ICJGb250IikgY29udGludWU7DQotDQotCQlDUERGX0ZvbnQqIHBGb250ID0gcERvY3VtZW50LT5Mb2FkRm9udChwRWxlbWVudCk7DQotCQlpZiAocEZvbnQgPT0gTlVMTCkgY29udGludWU7DQotCQljb25zdCBDRlhfU3Vic3RGb250KiBwU3Vic3QgPSBwRm9udC0+R2V0U3Vic3RGb250KCk7DQotCQlpZiAocFN1YnN0ID09IE5VTEwpIGNvbnRpbnVlOw0KLQkJaWYgKHBTdWJzdC0+bV9DaGFyc2V0ID09IG5DaGFyc2V0KQ0KLQkJew0KLQkJCXNGb250QWxpYXMgPSBjc0tleTsNCi0JCQlwRmluZCA9IHBGb250Ow0KLQkJfQ0KLQl9DQotCXJldHVybiBwRmluZDsNCi19DQotDQotdm9pZCBDQkFfRm9udE1hcDo6QWRkZWRGb250KENQREZfRm9udCogcEZvbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzKQ0KLXsNCi0JQWRkRm9udFRvQW5ub3REaWN0KHBGb250LCBzRm9udEFsaWFzKTsNCi19DQotDQotdm9pZCBDQkFfRm9udE1hcDo6QWRkRm9udFRvQW5ub3REaWN0KENQREZfRm9udCogcEZvbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzQWxpYXMpDQotew0KLQlpZiAoIXBGb250KQlyZXR1cm47DQotDQotCUFTU0VSVChtX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwQVBEaWN0ID0gbV9wQW5ub3REaWN0LT5HZXREaWN0KCJBUCIpOw0KLQ0KLQlpZiAocEFQRGljdCA9PSBOVUxMKSANCi0Jew0KLQkJcEFQRGljdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7DQotCQltX3BBbm5vdERpY3QtPlNldEF0KCJBUCIsIHBBUERpY3QpOw0KLQl9DQotDQotCS8vdG8gYXZvaWQgY2hlY2tib3ggYW5kIHJhZGlvYnV0dG9uDQotCUNQREZfT2JqZWN0KiBwT2JqZWN0ID0gcEFQRGljdC0+R2V0RWxlbWVudChtX3NBUFR5cGUpOw0KLQlpZiAocE9iamVjdCAmJiBwT2JqZWN0LT5HZXRUeXBlKCkgPT0gUERGT0JKX0RJQ1RJT05BUlkpDQotCQlyZXR1cm47DQotDQotCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gcEFQRGljdC0+R2V0U3RyZWFtKG1fc0FQVHlwZSk7DQotCWlmIChwU3RyZWFtID09IE5VTEwpIA0KLQl7DQotCQlwU3RyZWFtID0gRlhfTkVXIENQREZfU3RyZWFtKE5VTEwsIDAsIE5VTEwpOw0KLQkJRlhfSU5UMzIgb2JqbnVtID0gbV9wRG9jdW1lbnQtPkFkZEluZGlyZWN0T2JqZWN0KHBTdHJlYW0pOw0KLQkJcEFQRGljdC0+U2V0QXRSZWZlcmVuY2UobV9zQVBUeXBlLCBtX3BEb2N1bWVudCwgb2JqbnVtKTsNCi0JfQ0KLQ0KLQlDUERGX0RpY3Rpb25hcnkgKiBwU3RyZWFtRGljdCA9IHBTdHJlYW0tPkdldERpY3QoKTsNCi0NCi0JaWYgKCFwU3RyZWFtRGljdCkNCi0Jew0KLQkJcFN0cmVhbURpY3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5Ow0KLQkJcFN0cmVhbS0+SW5pdFN0cmVhbShOVUxMLCAwLCBwU3RyZWFtRGljdCk7DQotCX0NCi0NCi0JaWYgKHBTdHJlYW1EaWN0KQ0KLQl7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBTdHJlYW1SZXNMaXN0ID0gcFN0cmVhbURpY3QtPkdldERpY3QoIlJlc291cmNlcyIpOw0KLQkJaWYgKCFwU3RyZWFtUmVzTGlzdCkNCi0JCXsNCi0JCQlwU3RyZWFtUmVzTGlzdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnkoKTsNCi0JCQlwU3RyZWFtRGljdC0+U2V0QXQoIlJlc291cmNlcyIsIHBTdHJlYW1SZXNMaXN0KTsNCi0JCX0NCi0NCi0JCWlmIChwU3RyZWFtUmVzTGlzdCkgDQotCQl7DQotCQkJQ1BERl9EaWN0aW9uYXJ5KiBwU3RyZWFtUmVzRm9udExpc3QgPSBwU3RyZWFtUmVzTGlzdC0+R2V0RGljdCgiRm9udCIpOw0KLQkJCWlmICghcFN0cmVhbVJlc0ZvbnRMaXN0KSANCi0JCQl7DQotCQkJCXBTdHJlYW1SZXNGb250TGlzdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7DQotCQkJCUZYX0lOVDMyIG9iam51bSA9IG1fcERvY3VtZW50LT5BZGRJbmRpcmVjdE9iamVjdChwU3RyZWFtUmVzRm9udExpc3QpOw0KLQkJCQlwU3RyZWFtUmVzTGlzdC0+U2V0QXRSZWZlcmVuY2UoIkZvbnQiLCBtX3BEb2N1bWVudCwgb2JqbnVtKTsNCi0JCQl9DQotCQkJaWYgKCFwU3RyZWFtUmVzRm9udExpc3QtPktleUV4aXN0KHNBbGlhcykpDQotCQkJCXBTdHJlYW1SZXNGb250TGlzdC0+U2V0QXRSZWZlcmVuY2Uoc0FsaWFzLCBtX3BEb2N1bWVudCwgcEZvbnQtPkdldEZvbnREaWN0KCkpOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUNQREZfRm9udCogQ0JBX0ZvbnRNYXA6OkdldEFubm90RGVmYXVsdEZvbnQoQ0ZYX0J5dGVTdHJpbmcgJnNBbGlhcykNCi17DQotCUFTU0VSVChtX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwQWNyb0Zvcm1EaWN0ID0gTlVMTDsNCi0NCi0JRlhfQk9PTCBiV2lkZ2V0ID0gKG1fcEFubm90RGljdC0+R2V0U3RyaW5nKCJTdWJ0eXBlIikgPT0gIldpZGdldCIpOw0KLQ0KLQlpZiAoYldpZGdldCkNCi0Jew0KLQkJaWYgKENQREZfRGljdGlvbmFyeSAqIHBSb290RGljdCA9IG1fcERvY3VtZW50LT5HZXRSb290KCkpDQotCQkJcEFjcm9Gb3JtRGljdCA9IHBSb290RGljdC0+R2V0RGljdCgiQWNyb0Zvcm0iKTsNCi0JfQ0KLQkNCi0JQ0ZYX0J5dGVTdHJpbmcgc0RBOw0KLQkNCi0Jc0RBID0gRlBERl9HZXRGaWVsZEF0dHIobV9wQW5ub3REaWN0LCAiREEiKS0+R2V0U3RyaW5nKCk7DQotDQotCWlmIChiV2lkZ2V0KQ0KLQl7DQotCQlpZiAoc0RBLklzRW1wdHkoKSkNCi0JCXsNCi0JCQlzREEgPSBGUERGX0dldEZpZWxkQXR0cihwQWNyb0Zvcm1EaWN0LCAiREEiKS0+R2V0U3RyaW5nKCk7CQ0KLQkJfQ0KLQl9DQotCQ0KLQlDUERGX0RpY3Rpb25hcnkgKiBwRm9udERpY3QgPSBOVUxMOwkNCi0NCi0JaWYgKCFzREEuSXNFbXB0eSgpKQ0KLQl7DQotCQlDUERGX1NpbXBsZVBhcnNlciBzeW50YXgoc0RBKTsNCi0JCXN5bnRheC5GaW5kVGFnUGFyYW0oIlRmIiwgMik7DQotCQlDRlhfQnl0ZVN0cmluZyBzRm9udE5hbWUgPSBzeW50YXguR2V0V29yZCgpOw0KLQkJc0FsaWFzID0gUERGX05hbWVEZWNvZGUoc0ZvbnROYW1lKS5NaWQoMSk7DQotDQotCQlpZiAoQ1BERl9EaWN0aW9uYXJ5ICogcERSRGljdCA9IG1fcEFubm90RGljdC0+R2V0RGljdCgiRFIiKSkNCi0JCQlpZiAoQ1BERl9EaWN0aW9uYXJ5KiBwRFJGb250RGljdCA9IHBEUkRpY3QtPkdldERpY3QoIkZvbnQiKSkNCi0JCQkJcEZvbnREaWN0ID0gcERSRm9udERpY3QtPkdldERpY3Qoc0FsaWFzKTsNCi0NCi0JCWlmICghcEZvbnREaWN0KQ0KLQkJCWlmIChDUERGX0RpY3Rpb25hcnkqIHBBUERpY3QgPSBtX3BBbm5vdERpY3QtPkdldERpY3QoIkFQIikpDQotCQkJCWlmIChDUERGX0RpY3Rpb25hcnkqIHBOb3JtYWxEaWN0ID0gcEFQRGljdC0+R2V0RGljdCgiTiIpKQ0KLQkJCQkJaWYgKENQREZfRGljdGlvbmFyeSogcE5vcm1hbFJlc0RpY3QgPSBwTm9ybWFsRGljdC0+R2V0RGljdCgiUmVzb3VyY2VzIikpDQotCQkJCQkJaWYgKENQREZfRGljdGlvbmFyeSogcFJlc0ZvbnREaWN0ID0gcE5vcm1hbFJlc0RpY3QtPkdldERpY3QoIkZvbnQiKSkNCi0JCQkJCQkJcEZvbnREaWN0ID0gcFJlc0ZvbnREaWN0LT5HZXREaWN0KHNBbGlhcyk7DQotDQotCQlpZiAoYldpZGdldCkNCi0JCXsJCQkNCi0JCQlpZiAoIXBGb250RGljdCkNCi0JCQl7DQotCQkJCWlmIChwQWNyb0Zvcm1EaWN0KQ0KLQkJCQl7DQotCQkJCQlpZiAoQ1BERl9EaWN0aW9uYXJ5ICogcERSRGljdCA9IHBBY3JvRm9ybURpY3QtPkdldERpY3QoIkRSIikpDQotCQkJCQkJaWYgKENQREZfRGljdGlvbmFyeSogcERSRm9udERpY3QgPSBwRFJEaWN0LT5HZXREaWN0KCJGb250IikpDQotCQkJCQkJCXBGb250RGljdCA9IHBEUkZvbnREaWN0LT5HZXREaWN0KHNBbGlhcyk7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0NCi0JaWYgKHBGb250RGljdCkNCi0JCXJldHVybiBtX3BEb2N1bWVudC0+TG9hZEZvbnQocEZvbnREaWN0KTsNCi0JZWxzZQ0KLQkJcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLXZvaWQgQ0JBX0ZvbnRNYXA6OlNldEFQVHlwZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FQVHlwZSkNCi17DQotCW1fc0FQVHlwZSA9IHNBUFR5cGU7DQotDQotCVJlc2V0KCk7DQotCUluaXRpYWwoKTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9Gb3JtRmlsbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9DQkFfRm9udG1hcC5oIgorCitDQkFfRm9udE1hcDo6Q0JBX0ZvbnRNYXAoQ1BERlNES19Bbm5vdCogcEFubm90LCBJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIpIDoKKwlDUFdMX0ZvbnRNYXAocFN5c3RlbUhhbmRsZXIpLAorCW1fcERvY3VtZW50KE5VTEwpLAorCW1fcEFubm90RGljdChOVUxMKSwKKwltX3BEZWZhdWx0Rm9udChOVUxMKSwKKwltX3NBUFR5cGUoIk4iKQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisKKwlDUERGX1BhZ2UqIHBQYWdlID0gcEFubm90LT5HZXRQREZQYWdlKCk7CisKKwltX3BEb2N1bWVudCA9IHBQYWdlLT5tX3BEb2N1bWVudDsKKwltX3BBbm5vdERpY3QgPSBwQW5ub3QtPkdldFBERkFubm90KCktPm1fcEFubm90RGljdDsKK30KKworQ0JBX0ZvbnRNYXA6OkNCQV9Gb250TWFwKENQREZfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0LCAKKwkJCQkJCSBJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIpIDoKKwlDUFdMX0ZvbnRNYXAocFN5c3RlbUhhbmRsZXIpLAorCW1fcERvY3VtZW50KHBEb2N1bWVudCksCisJbV9wQW5ub3REaWN0KHBBbm5vdERpY3QpLAorCW1fcERlZmF1bHRGb250KE5VTEwpLAorCW1fc0FQVHlwZSgiTiIpCit7Cit9CisKK0NCQV9Gb250TWFwOjp+Q0JBX0ZvbnRNYXAoKQoreworfQorCit2b2lkIENCQV9Gb250TWFwOjpSZXNldCgpCit7CisJRW1wdHkoKTsKKwltX3BEZWZhdWx0Rm9udCA9IE5VTEw7CisJbV9zRGVmYXVsdEZvbnROYW1lID0gIiI7Cit9CisKK3ZvaWQgQ0JBX0ZvbnRNYXA6OkluaXRpYWwoRlhfTFBDU1RSIGZvbnRuYW1lKQoreworCUZYX0lOVDMyIG5DaGFyc2V0ID0gREVGQVVMVF9DSEFSU0VUOworCisJaWYgKCFtX3BEZWZhdWx0Rm9udCkKKwl7CisJCW1fcERlZmF1bHRGb250ID0gR2V0QW5ub3REZWZhdWx0Rm9udChtX3NEZWZhdWx0Rm9udE5hbWUpOwkKKwkJaWYgKG1fcERlZmF1bHRGb250KQorCQl7CisJCQlpZiAoY29uc3QgQ0ZYX1N1YnN0Rm9udCogcFN1YnN0Rm9udCA9IG1fcERlZmF1bHRGb250LT5HZXRTdWJzdEZvbnQoKSkKKwkJCQluQ2hhcnNldCA9IHBTdWJzdEZvbnQtPm1fQ2hhcnNldDsKKwkJCWVsc2UKKwkJCXsKKwkJCQlpZiAobV9zRGVmYXVsdEZvbnROYW1lID09ICJXaW5nZGluZ3MiIHx8IG1fc0RlZmF1bHRGb250TmFtZSA9PSAiV2luZ2RpbmdzMiIgfHwKKwkJCQkJbV9zRGVmYXVsdEZvbnROYW1lID09ICJXaW5nZGluZ3MzIiB8fCBtX3NEZWZhdWx0Rm9udE5hbWUgPT0gIldlYmRpbmdzIikKKwkJCQkJCW5DaGFyc2V0ID0gU1lNQk9MX0NIQVJTRVQ7CisJCQkJZWxzZQorCQkJCQluQ2hhcnNldCA9IEFOU0lfQ0hBUlNFVDsKKwkJCX0KKwkJCUFkZEZvbnREYXRhKG1fcERlZmF1bHRGb250LCBtX3NEZWZhdWx0Rm9udE5hbWUsIG5DaGFyc2V0KTsKKwkJCUFkZEZvbnRUb0Fubm90RGljdChtX3BEZWZhdWx0Rm9udCwgbV9zRGVmYXVsdEZvbnROYW1lKTsKKwkJfQorCX0KKworCWlmIChuQ2hhcnNldCAhPSBBTlNJX0NIQVJTRVQpCisJCUNQV0xfRm9udE1hcDo6SW5pdGlhbChmb250bmFtZSk7Cit9CisKK3ZvaWQgQ0JBX0ZvbnRNYXA6OlNldERlZmF1bHRGb250KENQREZfRm9udCAqIHBGb250LCBjb25zdCBDRlhfQnl0ZVN0cmluZyAmIHNGb250TmFtZSkKK3sKKwlBU1NFUlQocEZvbnQgIT0gTlVMTCk7CisKKwlpZiAobV9wRGVmYXVsdEZvbnQpIHJldHVybjsKKworCW1fcERlZmF1bHRGb250ID0gcEZvbnQ7CisJbV9zRGVmYXVsdEZvbnROYW1lID0gc0ZvbnROYW1lOworCisvLwlpZiAobV9zRGVmYXVsdEZvbnROYW1lLklzRW1wdHkoKSkKKy8vCQltX3NEZWZhdWx0Rm9udE5hbWUgPSBwRm9udC0+R2V0Rm9udFR5cGVOYW1lKCk7CisKKwlGWF9JTlQzMiBuQ2hhcnNldCA9IERFRkFVTFRfQ0hBUlNFVDsKKwlpZiAoY29uc3QgQ0ZYX1N1YnN0Rm9udCogcFN1YnN0Rm9udCA9IG1fcERlZmF1bHRGb250LT5HZXRTdWJzdEZvbnQoKSkKKwkJbkNoYXJzZXQgPSBwU3Vic3RGb250LT5tX0NoYXJzZXQ7CisJQWRkRm9udERhdGEobV9wRGVmYXVsdEZvbnQsIG1fc0RlZmF1bHRGb250TmFtZSwgbkNoYXJzZXQpOworfQorCitDUERGX0ZvbnQqIENCQV9Gb250TWFwOjpGaW5kRm9udFNhbWVDaGFyc2V0KENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzLCBGWF9JTlQzMiBuQ2hhcnNldCkKK3sKKwlBU1NFUlQobV9wQW5ub3REaWN0ICE9IE5VTEwpOworCisJaWYgKG1fcEFubm90RGljdC0+R2V0U3RyaW5nKCJTdWJ0eXBlIikgPT0gIldpZGdldCIpCisJeworCQlDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBHZXREb2N1bWVudCgpOworCQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJCUNQREZfRGljdGlvbmFyeSAqIHBSb290RGljdCA9IHBEb2N1bWVudC0+R2V0Um9vdCgpOworCQlpZiAoIXBSb290RGljdCkgcmV0dXJuIE5VTEw7CisKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwQWNyb0Zvcm1EaWN0ID0gcFJvb3REaWN0LT5HZXREaWN0KCJBY3JvRm9ybSIpOworCQlpZiAoIXBBY3JvRm9ybURpY3QpIHJldHVybiBOVUxMOworCisJCUNQREZfRGljdGlvbmFyeSAqIHBEUkRpY3QgPSBwQWNyb0Zvcm1EaWN0LT5HZXREaWN0KCJEUiIpOworCQlpZiAoIXBEUkRpY3QpIHJldHVybiBOVUxMOworCisJCXJldHVybiBGaW5kUmVzRm9udFNhbWVDaGFyc2V0KHBEUkRpY3QsIHNGb250QWxpYXMsIG5DaGFyc2V0KTsKKwl9CisKKwlyZXR1cm4gTlVMTDsKK30KKworQ1BERl9Eb2N1bWVudCogQ0JBX0ZvbnRNYXA6OkdldERvY3VtZW50KCkKK3sKKwlyZXR1cm4gbV9wRG9jdW1lbnQ7Cit9CisKK0NQREZfRm9udCogQ0JBX0ZvbnRNYXA6OkZpbmRSZXNGb250U2FtZUNoYXJzZXQoQ1BERl9EaWN0aW9uYXJ5KiBwUmVzRGljdCwgQ0ZYX0J5dGVTdHJpbmcmIHNGb250QWxpYXMsIAorCQkJCQkJCQkJCQkJCUZYX0lOVDMyIG5DaGFyc2V0KQoreworCWlmICghcFJlc0RpY3QpIHJldHVybiBOVUxMOworCisJQ1BERl9Eb2N1bWVudCogcERvY3VtZW50ID0gR2V0RG9jdW1lbnQoKTsKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwRm9udHMgPSBwUmVzRGljdC0+R2V0RGljdCgiRm9udCIpOworCWlmIChwRm9udHMgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisKKwlDUERGX0ZvbnQqIHBGaW5kID0gTlVMTDsKKworCUZYX1BPU0lUSU9OIHBvcyA9IHBGb250cy0+R2V0U3RhcnRQb3MoKTsKKwl3aGlsZSAocG9zKQorCXsKKwkJQ1BERl9PYmplY3QqIHBPYmogPSBOVUxMOworCQlDRlhfQnl0ZVN0cmluZyBjc0tleTsKKwkJcE9iaiA9IHBGb250cy0+R2V0TmV4dEVsZW1lbnQocG9zLCBjc0tleSk7CisJCWlmIChwT2JqID09IE5VTEwpIGNvbnRpbnVlOworCisJCUNQREZfT2JqZWN0KiBwRGlyZWN0ID0gcE9iai0+R2V0RGlyZWN0KCk7CisJCWlmIChwRGlyZWN0ID09IE5VTEwgfHwgcERpcmVjdC0+R2V0VHlwZSgpICE9IFBERk9CSl9ESUNUSU9OQVJZKSBjb250aW51ZTsKKworCQlDUERGX0RpY3Rpb25hcnkqIHBFbGVtZW50ID0gKENQREZfRGljdGlvbmFyeSopcERpcmVjdDsKKwkJaWYgKHBFbGVtZW50LT5HZXRTdHJpbmcoIlR5cGUiKSAhPSAiRm9udCIpIGNvbnRpbnVlOworCisJCUNQREZfRm9udCogcEZvbnQgPSBwRG9jdW1lbnQtPkxvYWRGb250KHBFbGVtZW50KTsKKwkJaWYgKHBGb250ID09IE5VTEwpIGNvbnRpbnVlOworCQljb25zdCBDRlhfU3Vic3RGb250KiBwU3Vic3QgPSBwRm9udC0+R2V0U3Vic3RGb250KCk7CisJCWlmIChwU3Vic3QgPT0gTlVMTCkgY29udGludWU7CisJCWlmIChwU3Vic3QtPm1fQ2hhcnNldCA9PSBuQ2hhcnNldCkKKwkJeworCQkJc0ZvbnRBbGlhcyA9IGNzS2V5OworCQkJcEZpbmQgPSBwRm9udDsKKwkJfQorCX0KKwlyZXR1cm4gcEZpbmQ7Cit9CisKK3ZvaWQgQ0JBX0ZvbnRNYXA6OkFkZGVkRm9udChDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcykKK3sKKwlBZGRGb250VG9Bbm5vdERpY3QocEZvbnQsIHNGb250QWxpYXMpOworfQorCit2b2lkIENCQV9Gb250TWFwOjpBZGRGb250VG9Bbm5vdERpY3QoQ1BERl9Gb250KiBwRm9udCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBbGlhcykKK3sKKwlpZiAoIXBGb250KQlyZXR1cm47CisKKwlBU1NFUlQobV9wQW5ub3REaWN0ICE9IE5VTEwpOworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZfRGljdGlvbmFyeSogcEFQRGljdCA9IG1fcEFubm90RGljdC0+R2V0RGljdCgiQVAiKTsKKworCWlmIChwQVBEaWN0ID09IE5VTEwpIAorCXsKKwkJcEFQRGljdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7CisJCW1fcEFubm90RGljdC0+U2V0QXQoIkFQIiwgcEFQRGljdCk7CisJfQorCisJLy90byBhdm9pZCBjaGVja2JveCBhbmQgcmFkaW9idXR0b24KKwlDUERGX09iamVjdCogcE9iamVjdCA9IHBBUERpY3QtPkdldEVsZW1lbnQobV9zQVBUeXBlKTsKKwlpZiAocE9iamVjdCAmJiBwT2JqZWN0LT5HZXRUeXBlKCkgPT0gUERGT0JKX0RJQ1RJT05BUlkpCisJCXJldHVybjsKKworCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gcEFQRGljdC0+R2V0U3RyZWFtKG1fc0FQVHlwZSk7CisJaWYgKHBTdHJlYW0gPT0gTlVMTCkgCisJeworCQlwU3RyZWFtID0gRlhfTkVXIENQREZfU3RyZWFtKE5VTEwsIDAsIE5VTEwpOworCQlGWF9JTlQzMiBvYmpudW0gPSBtX3BEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocFN0cmVhbSk7CisJCXBBUERpY3QtPlNldEF0UmVmZXJlbmNlKG1fc0FQVHlwZSwgbV9wRG9jdW1lbnQsIG9iam51bSk7CisJfQorCisJQ1BERl9EaWN0aW9uYXJ5ICogcFN0cmVhbURpY3QgPSBwU3RyZWFtLT5HZXREaWN0KCk7CisKKwlpZiAoIXBTdHJlYW1EaWN0KQorCXsKKwkJcFN0cmVhbURpY3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5OworCQlwU3RyZWFtLT5Jbml0U3RyZWFtKE5VTEwsIDAsIHBTdHJlYW1EaWN0KTsKKwl9CisKKwlpZiAocFN0cmVhbURpY3QpCisJeworCQlDUERGX0RpY3Rpb25hcnkqIHBTdHJlYW1SZXNMaXN0ID0gcFN0cmVhbURpY3QtPkdldERpY3QoIlJlc291cmNlcyIpOworCQlpZiAoIXBTdHJlYW1SZXNMaXN0KQorCQl7CisJCQlwU3RyZWFtUmVzTGlzdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnkoKTsKKwkJCXBTdHJlYW1EaWN0LT5TZXRBdCgiUmVzb3VyY2VzIiwgcFN0cmVhbVJlc0xpc3QpOworCQl9CisKKwkJaWYgKHBTdHJlYW1SZXNMaXN0KSAKKwkJeworCQkJQ1BERl9EaWN0aW9uYXJ5KiBwU3RyZWFtUmVzRm9udExpc3QgPSBwU3RyZWFtUmVzTGlzdC0+R2V0RGljdCgiRm9udCIpOworCQkJaWYgKCFwU3RyZWFtUmVzRm9udExpc3QpIAorCQkJeworCQkJCXBTdHJlYW1SZXNGb250TGlzdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7CisJCQkJRlhfSU5UMzIgb2JqbnVtID0gbV9wRG9jdW1lbnQtPkFkZEluZGlyZWN0T2JqZWN0KHBTdHJlYW1SZXNGb250TGlzdCk7CisJCQkJcFN0cmVhbVJlc0xpc3QtPlNldEF0UmVmZXJlbmNlKCJGb250IiwgbV9wRG9jdW1lbnQsIG9iam51bSk7CisJCQl9CisJCQlpZiAoIXBTdHJlYW1SZXNGb250TGlzdC0+S2V5RXhpc3Qoc0FsaWFzKSkKKwkJCQlwU3RyZWFtUmVzRm9udExpc3QtPlNldEF0UmVmZXJlbmNlKHNBbGlhcywgbV9wRG9jdW1lbnQsIHBGb250LT5HZXRGb250RGljdCgpKTsKKwkJfQorCX0KK30KKworQ1BERl9Gb250KiBDQkFfRm9udE1hcDo6R2V0QW5ub3REZWZhdWx0Rm9udChDRlhfQnl0ZVN0cmluZyAmc0FsaWFzKQoreworCUFTU0VSVChtX3BBbm5vdERpY3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwQWNyb0Zvcm1EaWN0ID0gTlVMTDsKKworCUZYX0JPT0wgYldpZGdldCA9IChtX3BBbm5vdERpY3QtPkdldFN0cmluZygiU3VidHlwZSIpID09ICJXaWRnZXQiKTsKKworCWlmIChiV2lkZ2V0KQorCXsKKwkJaWYgKENQREZfRGljdGlvbmFyeSAqIHBSb290RGljdCA9IG1fcERvY3VtZW50LT5HZXRSb290KCkpCisJCQlwQWNyb0Zvcm1EaWN0ID0gcFJvb3REaWN0LT5HZXREaWN0KCJBY3JvRm9ybSIpOworCX0KKwkKKwlDRlhfQnl0ZVN0cmluZyBzREE7CisJCisJc0RBID0gRlBERl9HZXRGaWVsZEF0dHIobV9wQW5ub3REaWN0LCAiREEiKS0+R2V0U3RyaW5nKCk7CisKKwlpZiAoYldpZGdldCkKKwl7CisJCWlmIChzREEuSXNFbXB0eSgpKQorCQl7CisJCQlzREEgPSBGUERGX0dldEZpZWxkQXR0cihwQWNyb0Zvcm1EaWN0LCAiREEiKS0+R2V0U3RyaW5nKCk7CQorCQl9CisJfQorCQorCUNQREZfRGljdGlvbmFyeSAqIHBGb250RGljdCA9IE5VTEw7CQorCisJaWYgKCFzREEuSXNFbXB0eSgpKQorCXsKKwkJQ1BERl9TaW1wbGVQYXJzZXIgc3ludGF4KHNEQSk7CisJCXN5bnRheC5GaW5kVGFnUGFyYW0oIlRmIiwgMik7CisJCUNGWF9CeXRlU3RyaW5nIHNGb250TmFtZSA9IHN5bnRheC5HZXRXb3JkKCk7CisJCXNBbGlhcyA9IFBERl9OYW1lRGVjb2RlKHNGb250TmFtZSkuTWlkKDEpOworCisJCWlmIChDUERGX0RpY3Rpb25hcnkgKiBwRFJEaWN0ID0gbV9wQW5ub3REaWN0LT5HZXREaWN0KCJEUiIpKQorCQkJaWYgKENQREZfRGljdGlvbmFyeSogcERSRm9udERpY3QgPSBwRFJEaWN0LT5HZXREaWN0KCJGb250IikpCisJCQkJcEZvbnREaWN0ID0gcERSRm9udERpY3QtPkdldERpY3Qoc0FsaWFzKTsKKworCQlpZiAoIXBGb250RGljdCkKKwkJCWlmIChDUERGX0RpY3Rpb25hcnkqIHBBUERpY3QgPSBtX3BBbm5vdERpY3QtPkdldERpY3QoIkFQIikpCisJCQkJaWYgKENQREZfRGljdGlvbmFyeSogcE5vcm1hbERpY3QgPSBwQVBEaWN0LT5HZXREaWN0KCJOIikpCisJCQkJCWlmIChDUERGX0RpY3Rpb25hcnkqIHBOb3JtYWxSZXNEaWN0ID0gcE5vcm1hbERpY3QtPkdldERpY3QoIlJlc291cmNlcyIpKQorCQkJCQkJaWYgKENQREZfRGljdGlvbmFyeSogcFJlc0ZvbnREaWN0ID0gcE5vcm1hbFJlc0RpY3QtPkdldERpY3QoIkZvbnQiKSkKKwkJCQkJCQlwRm9udERpY3QgPSBwUmVzRm9udERpY3QtPkdldERpY3Qoc0FsaWFzKTsKKworCQlpZiAoYldpZGdldCkKKwkJewkJCQorCQkJaWYgKCFwRm9udERpY3QpCisJCQl7CisJCQkJaWYgKHBBY3JvRm9ybURpY3QpCisJCQkJeworCQkJCQlpZiAoQ1BERl9EaWN0aW9uYXJ5ICogcERSRGljdCA9IHBBY3JvRm9ybURpY3QtPkdldERpY3QoIkRSIikpCisJCQkJCQlpZiAoQ1BERl9EaWN0aW9uYXJ5KiBwRFJGb250RGljdCA9IHBEUkRpY3QtPkdldERpY3QoIkZvbnQiKSkKKwkJCQkJCQlwRm9udERpY3QgPSBwRFJGb250RGljdC0+R2V0RGljdChzQWxpYXMpOworCQkJCX0KKwkJCX0KKwkJfQorCX0KKworCWlmIChwRm9udERpY3QpCisJCXJldHVybiBtX3BEb2N1bWVudC0+TG9hZEZvbnQocEZvbnREaWN0KTsKKwllbHNlCisJCXJldHVybiBOVUxMOworfQorCit2b2lkIENCQV9Gb250TWFwOjpTZXRBUFR5cGUoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFR5cGUpCit7CisJbV9zQVBUeXBlID0gc0FQVHlwZTsKKworCVJlc2V0KCk7CisJSW5pdGlhbCgpOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9DaGVja0JveC5jcHAgYi9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9DaGVja0JveC5jcHAKaW5kZXggZGI3OTkyNi4uZjgwMzVjNyAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfQ2hlY2tCb3guY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX0NoZWNrQm94LmNwcApAQCAtMSwxNDQgKzEsMTQ0IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ2hlY2tCb3guaCINCi0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGRkxfQ2hlY2tCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGRkxfQ2hlY2tCb3g6OkNGRkxfQ2hlY2tCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpIDoNCi0JQ0ZGTF9CdXR0b24ocEFwcCwgcFdpZGdldCkNCi17DQotfQ0KLQ0KLUNGRkxfQ2hlY2tCb3g6On5DRkZMX0NoZWNrQm94KCkNCi17DQotfQ0KLQ0KLUNQV0xfV25kKiBDRkZMX0NoZWNrQm94OjpOZXdQREZXaW5kb3coY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JQ1BXTF9DaGVja0JveCogcFduZCA9IG5ldyBDUFdMX0NoZWNrQm94KCk7DQotCXBXbmQtPkNyZWF0ZShjcCk7DQotDQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotCXBXbmQtPlNldENoZWNrKG1fcFdpZGdldC0+SXNDaGVja2VkKCkpOw0KLQkNCi0JcmV0dXJuIHBXbmQ7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9DaGVja0JveDo6T25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuS2V5Q29kZSwgRlhfVUlOVCBuRmxhZ3MpDQotew0KLQlzd2l0Y2ggKG5LZXlDb2RlKQ0KLQl7DQotCWNhc2UgRldMX1ZLRVlfUmV0dXJuOg0KLQljYXNlIEZXTF9WS0VZX1NwYWNlOg0KLQkJcmV0dXJuIFRSVUU7DQotCWRlZmF1bHQ6DQotCQlyZXR1cm4gQ0ZGTF9Gb3JtRmlsbGVyOjpPbktleURvd24ocEFubm90LCBuS2V5Q29kZSwgbkZsYWdzKTsNCi0JfQ0KLX0NCi1GWF9CT09MCUNGRkxfQ2hlY2tCb3g6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQ0KLXsNCi0Jc3dpdGNoIChuQ2hhcikNCi0Jew0KLQljYXNlIEZXTF9WS0VZX1JldHVybjoJDQotCWNhc2UgRldMX1ZLRVlfU3BhY2U6DQotCQl7DQotCQkJQ0ZGTF9JRm9ybUZpbGxlciogcElGb3JtRmlsbGVyID0gbV9wQXBwLT5HZXRJRm9ybUZpbGxlcigpOw0KLQkJCUFTU0VSVChwSUZvcm1GaWxsZXIgIT0gTlVMTCk7DQotDQotCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcEFubm90LT5HZXRQYWdlVmlldygpOw0KLQkJCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotDQotCQkJRlhfQk9PTCBiUmVzZXQgPSBGQUxTRTsNCi0JCQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7DQotDQotCQkJcElGb3JtRmlsbGVyLT5PbkJ1dHRvblVwKG1fcFdpZGdldCwgcFBhZ2VWaWV3LCBiUmVzZXQsIGJFeGl0LG5GbGFncyk7DQotDQotCQkJaWYgKGJSZXNldCkgcmV0dXJuIFRSVUU7DQotCQkJaWYgKGJFeGl0KSByZXR1cm4gVFJVRTsNCi0NCi0JCQlDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihwQW5ub3QsIG5DaGFyLCBuRmxhZ3MpOw0KLQ0KLQkJCWlmIChDUFdMX0NoZWNrQm94ICogcFduZCA9IChDUFdMX0NoZWNrQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBUUlVFKSkNCi0JCQkJcFduZC0+U2V0Q2hlY2soIXBXbmQtPklzQ2hlY2tlZCgpKTsNCi0NCi0JCQlDb21taXREYXRhKHBQYWdlVmlldyxuRmxhZ3MpOw0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQlkZWZhdWx0Og0KLQkJcmV0dXJuIENGRkxfRm9ybUZpbGxlcjo6T25DaGFyKHBBbm5vdCwgbkNoYXIsIG5GbGFncyk7DQotCX0NCi19DQotDQotRlhfQk9PTCBDRkZMX0NoZWNrQm94OjpPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQ0ZGTF9CdXR0b246Ok9uTEJ1dHRvblVwKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsNCi0NCi0JaWYgKElzVmFsaWQoKSkNCi0Jew0KLQkJaWYgKENQV0xfQ2hlY2tCb3ggKiBwV25kID0gKENQV0xfQ2hlY2tCb3gqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpKQ0KLQkJew0KLQkJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7DQotCQkJcFduZC0+U2V0Q2hlY2soIXBXaWRnZXQtPklzQ2hlY2tlZCgpKTsNCi0JCS8vCXBXbmQtPlNldENoZWNrKCFwV25kLT5Jc0NoZWNrZWQoKSk7DQotCQl9DQotDQotCQlpZiAoIUNvbW1pdERhdGEocFBhZ2VWaWV3LCBuRmxhZ3MpKSByZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9DaGVja0JveDo6SXNEYXRhQ2hhbmdlZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQ0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQlpZiAoQ1BXTF9DaGVja0JveCogcFduZCA9IChDUFdMX0NoZWNrQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsNCi0JCXJldHVybiBwV25kLT5Jc0NoZWNrZWQoKSAhPSBtX3BXaWRnZXQtPklzQ2hlY2tlZCgpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBDRkZMX0NoZWNrQm94OjpTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQ0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQlpZiAoQ1BXTF9DaGVja0JveCogcFduZCA9IChDUFdMX0NoZWNrQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsNCi0JCQ0KLQkJRlhfQk9PTCBiTmV3Q2hlY2tlZCA9IHBXbmQtPklzQ2hlY2tlZCgpOw0KLQkJDQotDQotCQlpZiAoYk5ld0NoZWNrZWQpDQotCQl7DQotCQkJQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCA9IG1fcFdpZGdldC0+R2V0Rm9ybUZpZWxkKCk7DQotCQkJQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsNCi0NCi0JCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1wRmllbGQtPkNvdW50Q29udHJvbHMoKTsgaTxzejsgaSsrKQ0KLQkJCXsNCi0JCQkJaWYgKENQREZfRm9ybUNvbnRyb2wqIHBDdHJsID0gcEZpZWxkLT5HZXRDb250cm9sKGkpKQ0KLQkJCQl7DQotCQkJCQlpZiAocEN0cmwtPklzQ2hlY2tlZCgpKQ0KLQkJCQkJew0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJbV9wV2lkZ2V0LT5TZXRDaGVjayhiTmV3Q2hlY2tlZCwgRkFMU0UpOw0KLQkJbV9wV2lkZ2V0LT5VcGRhdGVGaWVsZCgpOw0KLQkJU2V0Q2hhbmdlTWFyaygpOw0KLQl9DQotDQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRm9ybUZpbGxlci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ2hlY2tCb3guaCIKKworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGRkxfQ2hlY2tCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRkZMX0NoZWNrQm94OjpDRkZMX0NoZWNrQm94KENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0KSA6CisJQ0ZGTF9CdXR0b24ocEFwcCwgcFdpZGdldCkKK3sKK30KKworQ0ZGTF9DaGVja0JveDo6fkNGRkxfQ2hlY2tCb3goKQoreworfQorCitDUFdMX1duZCogQ0ZGTF9DaGVja0JveDo6TmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKKwlDUFdMX0NoZWNrQm94KiBwV25kID0gbmV3IENQV0xfQ2hlY2tCb3goKTsKKwlwV25kLT5DcmVhdGUoY3ApOworCisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKwlwV25kLT5TZXRDaGVjayhtX3BXaWRnZXQtPklzQ2hlY2tlZCgpKTsKKwkKKwlyZXR1cm4gcFduZDsKK30KKworRlhfQk9PTAlDRkZMX0NoZWNrQm94OjpPbktleURvd24oQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5LZXlDb2RlLCBGWF9VSU5UIG5GbGFncykKK3sKKwlzd2l0Y2ggKG5LZXlDb2RlKQorCXsKKwljYXNlIEZXTF9WS0VZX1JldHVybjoKKwljYXNlIEZXTF9WS0VZX1NwYWNlOgorCQlyZXR1cm4gVFJVRTsKKwlkZWZhdWx0OgorCQlyZXR1cm4gQ0ZGTF9Gb3JtRmlsbGVyOjpPbktleURvd24ocEFubm90LCBuS2V5Q29kZSwgbkZsYWdzKTsKKwl9Cit9CitGWF9CT09MCUNGRkxfQ2hlY2tCb3g6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQoreworCXN3aXRjaCAobkNoYXIpCisJeworCWNhc2UgRldMX1ZLRVlfUmV0dXJuOgkKKwljYXNlIEZXTF9WS0VZX1NwYWNlOgorCQl7CisJCQlDRkZMX0lGb3JtRmlsbGVyKiBwSUZvcm1GaWxsZXIgPSBtX3BBcHAtPkdldElGb3JtRmlsbGVyKCk7CisJCQlBU1NFUlQocElGb3JtRmlsbGVyICE9IE5VTEwpOworCisJCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwQW5ub3QtPkdldFBhZ2VWaWV3KCk7CisJCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCisJCQlGWF9CT09MIGJSZXNldCA9IEZBTFNFOworCQkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOworCisJCQlwSUZvcm1GaWxsZXItPk9uQnV0dG9uVXAobV9wV2lkZ2V0LCBwUGFnZVZpZXcsIGJSZXNldCwgYkV4aXQsbkZsYWdzKTsKKworCQkJaWYgKGJSZXNldCkgcmV0dXJuIFRSVUU7CisJCQlpZiAoYkV4aXQpIHJldHVybiBUUlVFOworCisJCQlDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihwQW5ub3QsIG5DaGFyLCBuRmxhZ3MpOworCisJCQlpZiAoQ1BXTF9DaGVja0JveCAqIHBXbmQgPSAoQ1BXTF9DaGVja0JveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSkpCisJCQkJcFduZC0+U2V0Q2hlY2soIXBXbmQtPklzQ2hlY2tlZCgpKTsKKworCQkJQ29tbWl0RGF0YShwUGFnZVZpZXcsbkZsYWdzKTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJZGVmYXVsdDoKKwkJcmV0dXJuIENGRkxfRm9ybUZpbGxlcjo6T25DaGFyKHBBbm5vdCwgbkNoYXIsIG5GbGFncyk7CisJfQorfQorCitGWF9CT09MIENGRkxfQ2hlY2tCb3g6Ok9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQ0ZGTF9CdXR0b246Ok9uTEJ1dHRvblVwKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKworCWlmIChJc1ZhbGlkKCkpCisJeworCQlpZiAoQ1BXTF9DaGVja0JveCAqIHBXbmQgPSAoQ1BXTF9DaGVja0JveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSkpCisJCXsKKwkJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7CisJCQlwV25kLT5TZXRDaGVjayghcFdpZGdldC0+SXNDaGVja2VkKCkpOworCQkvLwlwV25kLT5TZXRDaGVjayghcFduZC0+SXNDaGVja2VkKCkpOworCQl9CisKKwkJaWYgKCFDb21taXREYXRhKHBQYWdlVmlldywgbkZsYWdzKSkgcmV0dXJuIEZBTFNFOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MCUNGRkxfQ2hlY2tCb3g6OklzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCWlmIChDUFdMX0NoZWNrQm94KiBwV25kID0gKENQV0xfQ2hlY2tCb3gqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CisJCXJldHVybiBwV25kLT5Jc0NoZWNrZWQoKSAhPSBtX3BXaWRnZXQtPklzQ2hlY2tlZCgpOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDRkZMX0NoZWNrQm94OjpTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisKKwlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworCisJaWYgKENQV0xfQ2hlY2tCb3gqIHBXbmQgPSAoQ1BXTF9DaGVja0JveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJCisJCUZYX0JPT0wgYk5ld0NoZWNrZWQgPSBwV25kLT5Jc0NoZWNrZWQoKTsKKwkJCisKKwkJaWYgKGJOZXdDaGVja2VkKQorCQl7CisJCQlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gbV9wV2lkZ2V0LT5HZXRGb3JtRmllbGQoKTsKKwkJCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwkJCWZvciAoRlhfSU5UMzIgaT0wLHN6PXBGaWVsZC0+Q291bnRDb250cm9scygpOyBpPHN6OyBpKyspCisJCQl7CisJCQkJaWYgKENQREZfRm9ybUNvbnRyb2wqIHBDdHJsID0gcEZpZWxkLT5HZXRDb250cm9sKGkpKQorCQkJCXsKKwkJCQkJaWYgKHBDdHJsLT5Jc0NoZWNrZWQoKSkKKwkJCQkJeworCQkJCQkJYnJlYWs7CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCX0KKworCQltX3BXaWRnZXQtPlNldENoZWNrKGJOZXdDaGVja2VkLCBGQUxTRSk7CisJCW1fcFdpZGdldC0+VXBkYXRlRmllbGQoKTsKKwkJU2V0Q2hhbmdlTWFyaygpOworCX0KKworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfQ29tYm9Cb3guY3BwIGIvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfQ29tYm9Cb3guY3BwCmluZGV4IDNmMmM0NTMuLmVlNmI3YmQgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX0NvbWJvQm94LmNwcAorKysgYi9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9Db21ib0JveC5jcHAKQEAgLTEsNDQyICsxLDQ0MiBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9Gb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0lGb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ0JBX0ZvbnRtYXAuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Db21ib0JveC5oIg0KLQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZGTF9Db21ib0JveCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0ZGTF9Db21ib0JveDo6Q0ZGTF9Db21ib0JveChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwQW5ub3QpIDoNCi0JQ0ZGTF9Gb3JtRmlsbGVyKHBBcHAsIHBBbm5vdCksIG1fcEZvbnRNYXAoIE5VTEwgKQ0KLXsNCi0JLy9tX3BGb250TWFwID0gbmV3IENCQV9Gb250TWFwKCBwQW5ub3QsIEdldFN5c3RlbUhhbmRsZXIoKSApOw0KLSAgICAgICAgbV9TdGF0ZS5uSW5kZXggPSAwOw0KLSAgICAgICAgbV9TdGF0ZS5uU3RhcnQgPSAwOw0KLSAgICAgICAgbV9TdGF0ZS5uRW5kICAgPSAwOw0KLX0NCi0NCi1DRkZMX0NvbWJvQm94Ojp+Q0ZGTF9Db21ib0JveCgpDQotew0KLQlpZiAobV9wRm9udE1hcCkNCi0Jew0KLQkJZGVsZXRlIG1fcEZvbnRNYXA7DQotCQltX3BGb250TWFwID0gTlVMTDsNCi0JfQ0KLQ0KLS8vIAlmb3IgKGludCBpPTAsc3o9bV9JTUJveC5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0vLyAJew0KLS8vIAkJZGVsZXRlIG1fSU1Cb3guR2V0QXQoaSk7DQotLy8gCX0NCi0vLyANCi0vLyAJbV9JTUJveC5SZW1vdmVBbGwoKTsNCi19DQotDQotUFdMX0NSRUFURVBBUkFNIENGRkxfQ29tYm9Cb3g6OkdldENyZWF0ZVBhcmFtKCkNCi17DQotCVBXTF9DUkVBVEVQQVJBTSBjcCA9IENGRkxfRm9ybUZpbGxlcjo6R2V0Q3JlYXRlUGFyYW0oKTsNCi0NCi0JQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0NCi0JaW50IG5GbGFncyA9IG1fcFdpZGdldC0+R2V0RmllbGRGbGFncygpOw0KLQkNCi0JaWYgKG5GbGFncyAmIEZJRUxERkxBR19FRElUKQ0KLQl7CQkNCi0JCWNwLmR3RmxhZ3MgfD0gUENCU19BTExPV0NVU1RPTVRFWFQ7DQotCX0NCi0NCi0JLyoNCi0JaWYgKG5GbGFncyAmIEZJRUxERkxBR19DT01NSVRPTlNFTENIQU5HRSkNCi0JewkJDQotCQltX2JDb21taXRPblNlbGVjdENoYW5nZSA9IFRSVUU7DQotCX0NCi0JKi8NCi0NCi0JaWYgKCFtX3BGb250TWFwKQ0KLQl7DQotCQlBU1NFUlQodGhpcy0+bV9wQXBwICE9IE5VTEwpOw0KLQkJbV9wRm9udE1hcCA9IG5ldyBDQkFfRm9udE1hcChtX3BXaWRnZXQsIEdldFN5c3RlbUhhbmRsZXIoKSk7DQotCQltX3BGb250TWFwLT5Jbml0aWFsKCk7DQotCX0NCi0NCi0JY3AucEZvbnRNYXAgPSBtX3BGb250TWFwOw0KLQljcC5wRm9jdXNIYW5kbGVyID0gdGhpczsNCi0NCi0JcmV0dXJuIGNwOw0KLX0NCi0NCi1DUFdMX1duZCogQ0ZGTF9Db21ib0JveDo6TmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCUNQV0xfQ29tYm9Cb3ggKiBwV25kID0gbmV3IENQV0xfQ29tYm9Cb3goKTsNCi0JcFduZC0+QXR0YWNoRkZMRGF0YSh0aGlzKTsNCi0JcFduZC0+Q3JlYXRlKGNwKTsNCi0NCi0JQVNTRVJUKG1fcEFwcCAhPSBOVUxMKTsNCi0JQ0ZGTF9JRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBtX3BBcHAtPkdldElGb3JtRmlsbGVyKCk7DQotCXBXbmQtPlNldEZpbGxlck5vdGlmeShwRm9ybUZpbGxlcik7DQotDQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotCUZYX0lOVDMyIG5DdXJTZWwgPSBtX3BXaWRnZXQtPkdldFNlbGVjdGVkSW5kZXgoMCk7DQotCQ0KLQlDRlhfV2lkZVN0cmluZyBzd1RleHQ7DQotCQ0KLQlpZiAobkN1clNlbCA8IDApDQotCQlzd1RleHQgPSBtX3BXaWRnZXQtPkdldFZhbHVlKCk7DQotCWVsc2UNCi0JCXN3VGV4dCA9IG1fcFdpZGdldC0+R2V0T3B0aW9uTGFiZWwobkN1clNlbCk7DQotCQ0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX3BXaWRnZXQtPkNvdW50T3B0aW9ucygpOyBpPHN6OyBpKyspDQotCXsNCi0JCXBXbmQtPkFkZFN0cmluZyhtX3BXaWRnZXQtPkdldE9wdGlvbkxhYmVsKGkpKTsJCQkNCi0JfQ0KLQkNCi0JcFduZC0+U2V0U2VsZWN0KG5DdXJTZWwpOw0KLQlwV25kLT5TZXRUZXh0KHN3VGV4dCk7DQotCQ0KLQlyZXR1cm4gcFduZDsNCi19DQotDQotDQotRlhfQk9PTAlDRkZMX0NvbWJvQm94OjpPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncykNCi17DQotCXJldHVybiBDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihwQW5ub3QsIG5DaGFyLCBuRmxhZ3MpOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfQ29tYm9Cb3g6OklzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JaWYgKENQV0xfQ29tYm9Cb3ggKiBwV25kID0gKENQV0xfQ29tYm9Cb3gqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0Jew0KLQkJRlhfSU5UMzIgbkN1clNlbCA9IHBXbmQtPkdldFNlbGVjdCgpOw0KLQ0KLQkJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0NCi0JCWlmIChtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19FRElUKQ0KLQkJew0KLQkJCWlmIChuQ3VyU2VsID49IDApDQotCQkJew0KLQkJCQlyZXR1cm4gbkN1clNlbCAhPSBtX3BXaWRnZXQtPkdldFNlbGVjdGVkSW5kZXgoMCk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCXJldHVybiBwV25kLT5HZXRUZXh0KCkgIT0gbV9wV2lkZ2V0LT5HZXRWYWx1ZSgpOw0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlyZXR1cm4gbkN1clNlbCAhPSBtX3BXaWRnZXQtPkdldFNlbGVjdGVkSW5kZXgoMCk7DQotCQl9DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBDRkZMX0NvbWJvQm94OjpTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQlpZiAoQ1BXTF9Db21ib0JveCogcFduZCA9IChDUFdMX0NvbWJvQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsNCi0JCUNGWF9XaWRlU3RyaW5nIHN3VGV4dCA9IHBXbmQtPkdldFRleHQoKTsNCi0JCUZYX0lOVDMyIG5DdXJTZWwgPSBwV25kLT5HZXRTZWxlY3QoKTsNCi0NCi0JCS8vbWFudGlzOjAwMDQxNTcNCi0JCUZYX0JPT0wgYlNldFZhbHVlID0gVFJVRTsNCi0NCi0JCWlmIChtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19FRElUKQ0KLQkJew0KLQkJCWlmIChuQ3VyU2VsID49IDApDQotCQkJew0KLQkJCQlpZiAoc3dUZXh0ICE9IG1fcFdpZGdldC0+R2V0T3B0aW9uTGFiZWwobkN1clNlbCkpDQotCQkJCQliU2V0VmFsdWUgPSBUUlVFOw0KLQkJCQllbHNlDQotCQkJCQliU2V0VmFsdWUgPSBGQUxTRTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCQliU2V0VmFsdWUgPSBUUlVFOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJCWJTZXRWYWx1ZSA9IEZBTFNFOw0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgc09sZFZhbHVlOw0KLQkJDQotDQotCQlpZiAoYlNldFZhbHVlKQ0KLQkJew0KLQkJCXNPbGRWYWx1ZSA9IG1fcFdpZGdldC0+R2V0VmFsdWUoKTsNCi0JCQltX3BXaWRnZXQtPlNldFZhbHVlKHN3VGV4dCwgRkFMU0UpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCW1fcFdpZGdldC0+R2V0U2VsZWN0ZWRJbmRleCgwKTsNCi0JCQltX3BXaWRnZXQtPlNldE9wdGlvblNlbGVjdGlvbihuQ3VyU2VsLCBUUlVFLCBGQUxTRSk7DQotCQl9DQotDQotCQltX3BXaWRnZXQtPlJlc2V0RmllbGRBcHBlYXJhbmNlKFRSVUUpOw0KLQkJbV9wV2lkZ2V0LT5VcGRhdGVGaWVsZCgpOw0KLQkJU2V0Q2hhbmdlTWFyaygpOw0KLQ0KLQkJbV9wV2lkZ2V0LT5HZXRQREZQYWdlKCk7DQotCQkNCi0NCi0JfQ0KLX0NCi0NCi0gdm9pZCBDRkZMX0NvbWJvQm94OjpHZXRBY3Rpb25EYXRhKCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSkNCi17DQotCXN3aXRjaCAodHlwZSkNCi0Jew0KLQljYXNlIENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlOg0KLQkJaWYgKENQV0xfQ29tYm9Cb3gqIHBDb21ib0JveCA9IChDUFdMX0NvbWJvQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCQl7DQotCQkJaWYgKENQV0xfRWRpdCogcEVkaXQgPSAoQ1BXTF9FZGl0KikqcENvbWJvQm94KQ0KLQkJCXsNCi0JCQkJZmEuYkZpZWxkRnVsbCA9IHBFZGl0LT5Jc1RleHRGdWxsKCk7CQ0KLQkJCQlpbnQgblNlbFN0YXJ0ID0gMDsNCi0JCQkJaW50IG5TZWxFbmQgPSAwOw0KLQkJCQlwRWRpdC0+R2V0U2VsKG5TZWxTdGFydCwgblNlbEVuZCk7DQotCQkJCWZhLm5TZWxFbmQgPSBuU2VsRW5kOw0KLQkJCQlmYS5uU2VsU3RhcnQgPSBuU2VsU3RhcnQ7DQotCQkJCWZhLnNWYWx1ZSA9IHBFZGl0LT5HZXRUZXh0KCk7DQotCQkJCWZhLnNDaGFuZ2VFeCA9IEdldFNlbGVjdEV4cG9ydFRleHQoKTsNCi0NCi0JCQkJaWYgKGZhLmJGaWVsZEZ1bGwpDQotCQkJCXsNCi0JCQkJCWZhLnNDaGFuZ2UgPSBMIiI7DQotCQkJCQlmYS5zQ2hhbmdlRXggPSBMIiI7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FBY3Rpb246OlZhbGlkYXRlOg0KLQkJaWYgKENQV0xfQ29tYm9Cb3gqIHBDb21ib0JveCA9IChDUFdMX0NvbWJvQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCQl7DQotCQkJaWYgKENQV0xfRWRpdCogcEVkaXQgPSAoQ1BXTF9FZGl0KikqcENvbWJvQm94KQ0KLQkJCXsNCi0JCQkJZmEuc1ZhbHVlID0gcEVkaXQtPkdldFRleHQoKTsNCi0JCQl9DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FBY3Rpb246Okxvc2VGb2N1czoNCi0JY2FzZSBDUERGX0FBY3Rpb246OkdldEZvY3VzOg0KLQkJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0JCWZhLnNWYWx1ZSA9IG1fcFdpZGdldC0+R2V0VmFsdWUoKTsNCi0JCWJyZWFrOw0KLQlkZWZhdWx0Og0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotDQotDQotdm9pZCBDRkZMX0NvbWJvQm94OjpTZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCANCi0JCQkJCQkJCQljb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhKQ0KLXsNCi0Jc3dpdGNoICh0eXBlKQ0KLQl7DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2U6DQotCQlpZiAoQ1BXTF9Db21ib0JveCogcENvbWJvQm94ID0gKENQV0xfQ29tYm9Cb3gqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0JCXsNCi0JCQlpZiAoQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKSpwQ29tYm9Cb3gpDQotCQkJew0KLQkJCQlwRWRpdC0+U2V0U2VsKGZhLm5TZWxTdGFydCwgZmEublNlbEVuZCk7DQotCQkJCXBFZGl0LT5SZXBsYWNlU2VsKGZhLnNDaGFuZ2UpOw0KLQkJCX0NCi0JCX0NCi0JCWJyZWFrOw0KLQlkZWZhdWx0Og0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotRlhfQk9PTAlDRkZMX0NvbWJvQm94OjpJc0FjdGlvbkRhdGFDaGFuZ2VkKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU9sZCwgDQotCQkJCQkJCQkJY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU5ldykNCi17DQotCXN3aXRjaCAodHlwZSkNCi0Jew0KLQljYXNlIENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlOg0KLQkJcmV0dXJuICghZmFPbGQuYkZpZWxkRnVsbCAmJiBmYU9sZC5uU2VsRW5kICE9IGZhTmV3Lm5TZWxFbmQpIHx8IGZhT2xkLm5TZWxTdGFydCAhPSBmYU5ldy5uU2VsU3RhcnQgfHwNCi0JCQlmYU9sZC5zQ2hhbmdlICE9IGZhTmV3LnNDaGFuZ2U7DQotCWRlZmF1bHQ6DQotCQlicmVhazsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Db21ib0JveDo6U2F2ZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotDQotCWlmIChDUFdMX0NvbWJvQm94KiBwQ29tYm9Cb3ggPSAoQ1BXTF9Db21ib0JveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7DQotCQltX1N0YXRlLm5JbmRleCA9IHBDb21ib0JveC0+R2V0U2VsZWN0KCk7DQotDQotCQlpZiAoQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKSpwQ29tYm9Cb3gpDQotCQl7DQotCQkJcEVkaXQtPkdldFNlbChtX1N0YXRlLm5TdGFydCwgbV9TdGF0ZS5uRW5kKTsNCi0JCQltX1N0YXRlLnNWYWx1ZSA9IHBFZGl0LT5HZXRUZXh0KCk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRkZMX0NvbWJvQm94OjpSZXN0b3JlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0NCi0JaWYgKENQV0xfQ29tYm9Cb3gqIHBDb21ib0JveCA9IChDUFdMX0NvbWJvQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBUUlVFKSkNCi0Jew0KLQkJaWYgKG1fU3RhdGUubkluZGV4ID49IDApDQotCQkJcENvbWJvQm94LT5TZXRTZWxlY3QobV9TdGF0ZS5uSW5kZXgpOw0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopKnBDb21ib0JveCkNCi0JCQl7DQotCQkJCXBFZGl0LT5TZXRUZXh0KG1fU3RhdGUuc1ZhbHVlKTsNCi0JCQkJcEVkaXQtPlNldFNlbChtX1N0YXRlLm5TdGFydCwgbV9TdGF0ZS5uRW5kKTsNCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotQ1BXTF9XbmQqIENGRkxfQ29tYm9Cb3g6OlJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKQ0KLXsNCi0JaWYgKGJSZXN0b3JlVmFsdWUpDQotCQlTYXZlU3RhdGUocFBhZ2VWaWV3KTsNCi0JDQotCURlc3Ryb3lQREZXaW5kb3cocFBhZ2VWaWV3KTsNCi0JDQotCUNQV0xfV25kKiBwUmV0ID0gTlVMTDsNCi0JDQotCWlmIChiUmVzdG9yZVZhbHVlKQ0KLQl7DQotCQlSZXN0b3JlU3RhdGUocFBhZ2VWaWV3KTsNCi0JCXBSZXQgPSB0aGlzLT5HZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSk7DQotCX0NCi0JZWxzZQ0KLQkJcFJldCA9IHRoaXMtPkdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpOw0KLQkNCi0JbV9wV2lkZ2V0LT5VcGRhdGVGaWVsZCgpOw0KLQkNCi0JcmV0dXJuIHBSZXQ7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Db21ib0JveDo6T25LZXlTdHJva2UoRlhfQk9PTCBiS2V5RG93biwgRlhfVUlOVCBuRmxhZykNCi17DQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotCQ0KLQlpbnQgbkZsYWdzID0gbV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCk7DQotCQ0KLQlpZiAobkZsYWdzICYgRklFTERGTEFHX0NPTU1JVE9OU0VMQ0hBTkdFKQ0KLQl7DQotCQlpZiAobV9iVmFsaWQpDQotCQl7DQotCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gdGhpcy0+R2V0Q3VyUGFnZVZpZXcoKTsNCi0JCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQ0KLQkJCWlmIChDb21taXREYXRhKHBQYWdlVmlldywgbkZsYWcpKQ0KLQkJCXsNCi0JCQkJRGVzdHJveVBERldpbmRvdyhwUGFnZVZpZXcpOw0KLQkJCQltX2JWYWxpZCA9IEZBTFNFOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENGRkxfQ29tYm9Cb3g6Ok9uU2V0Rm9jdXMoQ1BXTF9XbmQqIHBXbmQpDQotew0KLQlBU1NFUlQobV9wQXBwICE9IE5VTEwpOw0KLQ0KLQlBU1NFUlQocFduZCAhPSBOVUxMKTsNCi0NCi0JaWYgKHBXbmQtPkdldENsYXNzTmFtZSgpID09IFBXTF9DTEFTU05BTUVfRURJVCkNCi0Jew0KLQkJQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKXBXbmQ7DQotCQlwRWRpdC0+U2V0Q2hhclNldCgxMzQpOw0KLQkJcEVkaXQtPlNldENvZGVQYWdlKDkzNik7DQotDQotCQlwRWRpdC0+U2V0UmVhZHlUb0lucHV0KCk7DQotCQlDRlhfV2lkZVN0cmluZyB3c1RleHQgPSBwRWRpdC0+R2V0VGV4dCgpOw0KLQkJaW50IG5DaGFyYWN0ZXJzID0gd3NUZXh0LkdldExlbmd0aCgpOw0KLQkJQ0ZYX0J5dGVTdHJpbmcgYnNVVEZUZXh0ID0gd3NUZXh0LlVURjE2TEVfRW5jb2RlKCk7DQotCQl1bnNpZ25lZCBzaG9ydCogcEJ1ZmZlciA9ICh1bnNpZ25lZCBzaG9ydCopKEZYX0xQQ1NUUilic1VURlRleHQ7DQotCQltX3BBcHAtPkZGSV9PblNldEZpZWxkSW5wdXRGb2N1cyhtX3BXaWRnZXQtPkdldEZvcm1GaWVsZCgpLCBwQnVmZmVyLCBuQ2hhcmFjdGVycywgVFJVRSk7DQotDQotIAkJcEVkaXQtPlNldEVkaXROb3RpZnkodGhpcyk7DQotCX0NCi19DQotDQotdm9pZCBDRkZMX0NvbWJvQm94OjpPbktpbGxGb2N1cyhDUFdMX1duZCogcFduZCkNCi17DQotCUFTU0VSVChtX3BBcHAgIT0gTlVMTCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9Db21ib0JveDo6Q2FuQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Db21ib0JveDo6Q2FuQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0NvbWJvQm94OjpDYW5QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Db21ib0JveDo6RG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Db21ib0JveDo6RG9DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi19DQotDQotdm9pZCBDRkZMX0NvbWJvQm94OjpEb1Bhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Db21ib0JveDo6T25BZGRVbmRvKENQV0xfRWRpdCogcEVkaXQpDQotew0KLQlBU1NFUlQocEVkaXQgIT0gTlVMTCk7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENGRkxfQ29tYm9Cb3g6OkdldFNlbGVjdEV4cG9ydFRleHQoKQ0KLXsNCi0JQ0ZYX1dpZGVTdHJpbmcgc3dSZXQ7DQotCQ0KLQlpbnQgbkV4cG9ydCA9IC0xOw0KLQlDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcgPSBHZXRDdXJQYWdlVmlldygpOw0KLQlpZiAoQ1BXTF9Db21ib0JveCAqIHBDb21ib0JveCA9IChDUFdMX0NvbWJvQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsNCi0JCW5FeHBvcnQgPSBwQ29tYm9Cb3gtPkdldFNlbGVjdCgpOw0KLQl9DQotCQ0KLQlpZiAobkV4cG9ydCA+PSAwKQ0KLQl7DQotCQlpZiAoQ1BERl9Gb3JtRmllbGQgKiBwRm9ybUZpZWxkID0gbV9wV2lkZ2V0LT5HZXRGb3JtRmllbGQoKSkNCi0JCXsNCi0JCQlzd1JldCA9IHBGb3JtRmllbGQtPkdldE9wdGlvblZhbHVlKG5FeHBvcnQpOw0KLQkJCWlmIChzd1JldC5Jc0VtcHR5KCkpDQotCQkJCXN3UmV0ID0gcEZvcm1GaWVsZC0+R2V0T3B0aW9uTGFiZWwobkV4cG9ydCk7DQotCQl9DQotCX0NCi0JDQotCXJldHVybiBzd1JldDsNCi19DQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9Gb3JtRmlsbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9JRm9ybUZpbGxlci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ0JBX0ZvbnRtYXAuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NvbWJvQm94LmgiCisKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX0NvbWJvQm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0ZGTF9Db21ib0JveDo6Q0ZGTF9Db21ib0JveChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwQW5ub3QpIDoKKwlDRkZMX0Zvcm1GaWxsZXIocEFwcCwgcEFubm90KSwgbV9wRm9udE1hcCggTlVMTCApCit7CisJLy9tX3BGb250TWFwID0gbmV3IENCQV9Gb250TWFwKCBwQW5ub3QsIEdldFN5c3RlbUhhbmRsZXIoKSApOworICAgICAgICBtX1N0YXRlLm5JbmRleCA9IDA7CisgICAgICAgIG1fU3RhdGUublN0YXJ0ID0gMDsKKyAgICAgICAgbV9TdGF0ZS5uRW5kICAgPSAwOworfQorCitDRkZMX0NvbWJvQm94Ojp+Q0ZGTF9Db21ib0JveCgpCit7CisJaWYgKG1fcEZvbnRNYXApCisJeworCQlkZWxldGUgbV9wRm9udE1hcDsKKwkJbV9wRm9udE1hcCA9IE5VTEw7CisJfQorCisvLyAJZm9yIChpbnQgaT0wLHN6PW1fSU1Cb3guR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisvLyAJeworLy8gCQlkZWxldGUgbV9JTUJveC5HZXRBdChpKTsKKy8vIAl9CisvLyAKKy8vIAltX0lNQm94LlJlbW92ZUFsbCgpOworfQorCitQV0xfQ1JFQVRFUEFSQU0gQ0ZGTF9Db21ib0JveDo6R2V0Q3JlYXRlUGFyYW0oKQoreworCVBXTF9DUkVBVEVQQVJBTSBjcCA9IENGRkxfRm9ybUZpbGxlcjo6R2V0Q3JlYXRlUGFyYW0oKTsKKworCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisKKwlpbnQgbkZsYWdzID0gbV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCk7CisJCisJaWYgKG5GbGFncyAmIEZJRUxERkxBR19FRElUKQorCXsJCQorCQljcC5kd0ZsYWdzIHw9IFBDQlNfQUxMT1dDVVNUT01URVhUOworCX0KKworCS8qCisJaWYgKG5GbGFncyAmIEZJRUxERkxBR19DT01NSVRPTlNFTENIQU5HRSkKKwl7CQkKKwkJbV9iQ29tbWl0T25TZWxlY3RDaGFuZ2UgPSBUUlVFOworCX0KKwkqLworCisJaWYgKCFtX3BGb250TWFwKQorCXsKKwkJQVNTRVJUKHRoaXMtPm1fcEFwcCAhPSBOVUxMKTsKKwkJbV9wRm9udE1hcCA9IG5ldyBDQkFfRm9udE1hcChtX3BXaWRnZXQsIEdldFN5c3RlbUhhbmRsZXIoKSk7CisJCW1fcEZvbnRNYXAtPkluaXRpYWwoKTsKKwl9CisKKwljcC5wRm9udE1hcCA9IG1fcEZvbnRNYXA7CisJY3AucEZvY3VzSGFuZGxlciA9IHRoaXM7CisKKwlyZXR1cm4gY3A7Cit9CisKK0NQV0xfV25kKiBDRkZMX0NvbWJvQm94OjpOZXdQREZXaW5kb3coY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCUNQV0xfQ29tYm9Cb3ggKiBwV25kID0gbmV3IENQV0xfQ29tYm9Cb3goKTsKKwlwV25kLT5BdHRhY2hGRkxEYXRhKHRoaXMpOworCXBXbmQtPkNyZWF0ZShjcCk7CisKKwlBU1NFUlQobV9wQXBwICE9IE5VTEwpOworCUNGRkxfSUZvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gbV9wQXBwLT5HZXRJRm9ybUZpbGxlcigpOworCXBXbmQtPlNldEZpbGxlck5vdGlmeShwRm9ybUZpbGxlcik7CisKKwlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworCUZYX0lOVDMyIG5DdXJTZWwgPSBtX3BXaWRnZXQtPkdldFNlbGVjdGVkSW5kZXgoMCk7CisJCisJQ0ZYX1dpZGVTdHJpbmcgc3dUZXh0OworCQorCWlmIChuQ3VyU2VsIDwgMCkKKwkJc3dUZXh0ID0gbV9wV2lkZ2V0LT5HZXRWYWx1ZSgpOworCWVsc2UKKwkJc3dUZXh0ID0gbV9wV2lkZ2V0LT5HZXRPcHRpb25MYWJlbChuQ3VyU2VsKTsKKwkKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX3BXaWRnZXQtPkNvdW50T3B0aW9ucygpOyBpPHN6OyBpKyspCisJeworCQlwV25kLT5BZGRTdHJpbmcobV9wV2lkZ2V0LT5HZXRPcHRpb25MYWJlbChpKSk7CQkJCisJfQorCQorCXBXbmQtPlNldFNlbGVjdChuQ3VyU2VsKTsKKwlwV25kLT5TZXRUZXh0KHN3VGV4dCk7CisJCisJcmV0dXJuIHBXbmQ7Cit9CisKKworRlhfQk9PTAlDRkZMX0NvbWJvQm94OjpPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncykKK3sKKwlyZXR1cm4gQ0ZGTF9Gb3JtRmlsbGVyOjpPbkNoYXIocEFubm90LCBuQ2hhciwgbkZsYWdzKTsKK30KKworRlhfQk9PTAlDRkZMX0NvbWJvQm94OjpJc0RhdGFDaGFuZ2VkKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKKwlpZiAoQ1BXTF9Db21ib0JveCAqIHBXbmQgPSAoQ1BXTF9Db21ib0JveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJRlhfSU5UMzIgbkN1clNlbCA9IHBXbmQtPkdldFNlbGVjdCgpOworCisJCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisKKwkJaWYgKG1fcFdpZGdldC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX0VESVQpCisJCXsKKwkJCWlmIChuQ3VyU2VsID49IDApCisJCQl7CisJCQkJcmV0dXJuIG5DdXJTZWwgIT0gbV9wV2lkZ2V0LT5HZXRTZWxlY3RlZEluZGV4KDApOworCQkJfQorCQkJZWxzZQorCQkJeworCQkJCXJldHVybiBwV25kLT5HZXRUZXh0KCkgIT0gbV9wV2lkZ2V0LT5HZXRWYWx1ZSgpOworCQkJfQorCQl9CisJCWVsc2UKKwkJeworCQkJcmV0dXJuIG5DdXJTZWwgIT0gbV9wV2lkZ2V0LT5HZXRTZWxlY3RlZEluZGV4KDApOworCQl9CisJfQorCQorCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDRkZMX0NvbWJvQm94OjpTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCWlmIChDUFdMX0NvbWJvQm94KiBwV25kID0gKENQV0xfQ29tYm9Cb3gqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CisJCUNGWF9XaWRlU3RyaW5nIHN3VGV4dCA9IHBXbmQtPkdldFRleHQoKTsKKwkJRlhfSU5UMzIgbkN1clNlbCA9IHBXbmQtPkdldFNlbGVjdCgpOworCisJCS8vbWFudGlzOjAwMDQxNTcKKwkJRlhfQk9PTCBiU2V0VmFsdWUgPSBUUlVFOworCisJCWlmIChtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19FRElUKQorCQl7CisJCQlpZiAobkN1clNlbCA+PSAwKQorCQkJeworCQkJCWlmIChzd1RleHQgIT0gbV9wV2lkZ2V0LT5HZXRPcHRpb25MYWJlbChuQ3VyU2VsKSkKKwkJCQkJYlNldFZhbHVlID0gVFJVRTsKKwkJCQllbHNlCisJCQkJCWJTZXRWYWx1ZSA9IEZBTFNFOworCQkJfQorCQkJZWxzZQorCQkJCWJTZXRWYWx1ZSA9IFRSVUU7CisJCX0KKwkJZWxzZQorCQkJYlNldFZhbHVlID0gRkFMU0U7CisKKwkJQ0ZYX1dpZGVTdHJpbmcgc09sZFZhbHVlOworCQkKKworCQlpZiAoYlNldFZhbHVlKQorCQl7CisJCQlzT2xkVmFsdWUgPSBtX3BXaWRnZXQtPkdldFZhbHVlKCk7CisJCQltX3BXaWRnZXQtPlNldFZhbHVlKHN3VGV4dCwgRkFMU0UpOworCQl9CisJCWVsc2UKKwkJeworCQkJbV9wV2lkZ2V0LT5HZXRTZWxlY3RlZEluZGV4KDApOworCQkJbV9wV2lkZ2V0LT5TZXRPcHRpb25TZWxlY3Rpb24obkN1clNlbCwgVFJVRSwgRkFMU0UpOworCQl9CisKKwkJbV9wV2lkZ2V0LT5SZXNldEZpZWxkQXBwZWFyYW5jZShUUlVFKTsKKwkJbV9wV2lkZ2V0LT5VcGRhdGVGaWVsZCgpOworCQlTZXRDaGFuZ2VNYXJrKCk7CisKKwkJbV9wV2lkZ2V0LT5HZXRQREZQYWdlKCk7CisJCQorCisJfQorfQorCisgdm9pZCBDRkZMX0NvbWJvQm94OjpHZXRBY3Rpb25EYXRhKCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSkKK3sKKwlzd2l0Y2ggKHR5cGUpCisJeworCWNhc2UgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2U6CisJCWlmIChDUFdMX0NvbWJvQm94KiBwQ29tYm9Cb3ggPSAoQ1BXTF9Db21ib0JveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCQl7CisJCQlpZiAoQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKSpwQ29tYm9Cb3gpCisJCQl7CisJCQkJZmEuYkZpZWxkRnVsbCA9IHBFZGl0LT5Jc1RleHRGdWxsKCk7CQorCQkJCWludCBuU2VsU3RhcnQgPSAwOworCQkJCWludCBuU2VsRW5kID0gMDsKKwkJCQlwRWRpdC0+R2V0U2VsKG5TZWxTdGFydCwgblNlbEVuZCk7CisJCQkJZmEublNlbEVuZCA9IG5TZWxFbmQ7CisJCQkJZmEublNlbFN0YXJ0ID0gblNlbFN0YXJ0OworCQkJCWZhLnNWYWx1ZSA9IHBFZGl0LT5HZXRUZXh0KCk7CisJCQkJZmEuc0NoYW5nZUV4ID0gR2V0U2VsZWN0RXhwb3J0VGV4dCgpOworCisJCQkJaWYgKGZhLmJGaWVsZEZ1bGwpCisJCQkJeworCQkJCQlmYS5zQ2hhbmdlID0gTCIiOworCQkJCQlmYS5zQ2hhbmdlRXggPSBMIiI7CisJCQkJfQorCQkJfQorCQl9CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpWYWxpZGF0ZToKKwkJaWYgKENQV0xfQ29tYm9Cb3gqIHBDb21ib0JveCA9IChDUFdMX0NvbWJvQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpCisJCXsKKwkJCWlmIChDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopKnBDb21ib0JveCkKKwkJCXsKKwkJCQlmYS5zVmFsdWUgPSBwRWRpdC0+R2V0VGV4dCgpOworCQkJfQorCQl9CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpMb3NlRm9jdXM6CisJY2FzZSBDUERGX0FBY3Rpb246OkdldEZvY3VzOgorCQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworCQlmYS5zVmFsdWUgPSBtX3BXaWRnZXQtPkdldFZhbHVlKCk7CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCWJyZWFrOworCX0KK30KKworCisKK3ZvaWQgQ0ZGTF9Db21ib0JveDo6U2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgCisJCQkJCQkJCQljb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhKQoreworCXN3aXRjaCAodHlwZSkKKwl7CisJY2FzZSBDUERGX0FBY3Rpb246OktleVN0cm9rZToKKwkJaWYgKENQV0xfQ29tYm9Cb3gqIHBDb21ib0JveCA9IChDUFdMX0NvbWJvQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpCisJCXsKKwkJCWlmIChDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopKnBDb21ib0JveCkKKwkJCXsKKwkJCQlwRWRpdC0+U2V0U2VsKGZhLm5TZWxTdGFydCwgZmEublNlbEVuZCk7CisJCQkJcEVkaXQtPlJlcGxhY2VTZWwoZmEuc0NoYW5nZSk7CisJCQl9CisJCX0KKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJYnJlYWs7CisJfQorfQorCitGWF9CT09MCUNGRkxfQ29tYm9Cb3g6OklzQWN0aW9uRGF0YUNoYW5nZWQoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBjb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhT2xkLCAKKwkJCQkJCQkJCWNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmFOZXcpCit7CisJc3dpdGNoICh0eXBlKQorCXsKKwljYXNlIENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlOgorCQlyZXR1cm4gKCFmYU9sZC5iRmllbGRGdWxsICYmIGZhT2xkLm5TZWxFbmQgIT0gZmFOZXcublNlbEVuZCkgfHwgZmFPbGQublNlbFN0YXJ0ICE9IGZhTmV3Lm5TZWxTdGFydCB8fAorCQkJZmFPbGQuc0NoYW5nZSAhPSBmYU5ldy5zQ2hhbmdlOworCWRlZmF1bHQ6CisJCWJyZWFrOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDRkZMX0NvbWJvQm94OjpTYXZlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7CisKKwlpZiAoQ1BXTF9Db21ib0JveCogcENvbWJvQm94ID0gKENQV0xfQ29tYm9Cb3gqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CisJCW1fU3RhdGUubkluZGV4ID0gcENvbWJvQm94LT5HZXRTZWxlY3QoKTsKKworCQlpZiAoQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKSpwQ29tYm9Cb3gpCisJCXsKKwkJCXBFZGl0LT5HZXRTZWwobV9TdGF0ZS5uU3RhcnQsIG1fU3RhdGUubkVuZCk7CisJCQltX1N0YXRlLnNWYWx1ZSA9IHBFZGl0LT5HZXRUZXh0KCk7CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZGTF9Db21ib0JveDo6UmVzdG9yZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKKwlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCisJaWYgKENQV0xfQ29tYm9Cb3gqIHBDb21ib0JveCA9IChDUFdMX0NvbWJvQm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBUUlVFKSkKKwl7CisJCWlmIChtX1N0YXRlLm5JbmRleCA+PSAwKQorCQkJcENvbWJvQm94LT5TZXRTZWxlY3QobV9TdGF0ZS5uSW5kZXgpOworCQllbHNlCisJCXsKKwkJCWlmIChDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopKnBDb21ib0JveCkKKwkJCXsKKwkJCQlwRWRpdC0+U2V0VGV4dChtX1N0YXRlLnNWYWx1ZSk7CisJCQkJcEVkaXQtPlNldFNlbChtX1N0YXRlLm5TdGFydCwgbV9TdGF0ZS5uRW5kKTsKKwkJCX0KKwkJfQorCX0KK30KKworQ1BXTF9XbmQqIENGRkxfQ29tYm9Cb3g6OlJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKQoreworCWlmIChiUmVzdG9yZVZhbHVlKQorCQlTYXZlU3RhdGUocFBhZ2VWaWV3KTsKKwkKKwlEZXN0cm95UERGV2luZG93KHBQYWdlVmlldyk7CisJCisJQ1BXTF9XbmQqIHBSZXQgPSBOVUxMOworCQorCWlmIChiUmVzdG9yZVZhbHVlKQorCXsKKwkJUmVzdG9yZVN0YXRlKHBQYWdlVmlldyk7CisJCXBSZXQgPSB0aGlzLT5HZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSk7CisJfQorCWVsc2UKKwkJcFJldCA9IHRoaXMtPkdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpOworCQorCW1fcFdpZGdldC0+VXBkYXRlRmllbGQoKTsKKwkKKwlyZXR1cm4gcFJldDsKK30KKwordm9pZCBDRkZMX0NvbWJvQm94OjpPbktleVN0cm9rZShGWF9CT09MIGJLZXlEb3duLCBGWF9VSU5UIG5GbGFnKQoreworCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisJCisJaW50IG5GbGFncyA9IG1fcFdpZGdldC0+R2V0RmllbGRGbGFncygpOworCQorCWlmIChuRmxhZ3MgJiBGSUVMREZMQUdfQ09NTUlUT05TRUxDSEFOR0UpCisJeworCQlpZiAobV9iVmFsaWQpCisJCXsKKwkJCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHRoaXMtPkdldEN1clBhZ2VWaWV3KCk7CisJCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCisJCQlpZiAoQ29tbWl0RGF0YShwUGFnZVZpZXcsIG5GbGFnKSkKKwkJCXsKKwkJCQlEZXN0cm95UERGV2luZG93KHBQYWdlVmlldyk7CisJCQkJbV9iVmFsaWQgPSBGQUxTRTsKKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBDRkZMX0NvbWJvQm94OjpPblNldEZvY3VzKENQV0xfV25kKiBwV25kKQoreworCUFTU0VSVChtX3BBcHAgIT0gTlVMTCk7CisKKwlBU1NFUlQocFduZCAhPSBOVUxMKTsKKworCWlmIChwV25kLT5HZXRDbGFzc05hbWUoKSA9PSBQV0xfQ0xBU1NOQU1FX0VESVQpCisJeworCQlDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopcFduZDsKKwkJcEVkaXQtPlNldENoYXJTZXQoMTM0KTsKKwkJcEVkaXQtPlNldENvZGVQYWdlKDkzNik7CisKKwkJcEVkaXQtPlNldFJlYWR5VG9JbnB1dCgpOworCQlDRlhfV2lkZVN0cmluZyB3c1RleHQgPSBwRWRpdC0+R2V0VGV4dCgpOworCQlpbnQgbkNoYXJhY3RlcnMgPSB3c1RleHQuR2V0TGVuZ3RoKCk7CisJCUNGWF9CeXRlU3RyaW5nIGJzVVRGVGV4dCA9IHdzVGV4dC5VVEYxNkxFX0VuY29kZSgpOworCQl1bnNpZ25lZCBzaG9ydCogcEJ1ZmZlciA9ICh1bnNpZ25lZCBzaG9ydCopKEZYX0xQQ1NUUilic1VURlRleHQ7CisJCW1fcEFwcC0+RkZJX09uU2V0RmllbGRJbnB1dEZvY3VzKG1fcFdpZGdldC0+R2V0Rm9ybUZpZWxkKCksIHBCdWZmZXIsIG5DaGFyYWN0ZXJzLCBUUlVFKTsKKworIAkJcEVkaXQtPlNldEVkaXROb3RpZnkodGhpcyk7CisJfQorfQorCit2b2lkIENGRkxfQ29tYm9Cb3g6Ok9uS2lsbEZvY3VzKENQV0xfV25kKiBwV25kKQoreworCUFTU0VSVChtX3BBcHAgIT0gTlVMTCk7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9Db21ib0JveDo6Q2FuQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDRkZMX0NvbWJvQm94OjpDYW5DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9Db21ib0JveDo6Q2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZGTF9Db21ib0JveDo6RG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworfQorCit2b2lkIENGRkxfQ29tYm9Cb3g6OkRvQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworfQorCit2b2lkIENGRkxfQ29tYm9Cb3g6OkRvUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7Cit9CisKK3ZvaWQgQ0ZGTF9Db21ib0JveDo6T25BZGRVbmRvKENQV0xfRWRpdCogcEVkaXQpCit7CisJQVNTRVJUKHBFZGl0ICE9IE5VTEwpOworfQorCitDRlhfV2lkZVN0cmluZyBDRkZMX0NvbWJvQm94OjpHZXRTZWxlY3RFeHBvcnRUZXh0KCkKK3sKKwlDRlhfV2lkZVN0cmluZyBzd1JldDsKKwkKKwlpbnQgbkV4cG9ydCA9IC0xOworCUNQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldyA9IEdldEN1clBhZ2VWaWV3KCk7CisJaWYgKENQV0xfQ29tYm9Cb3ggKiBwQ29tYm9Cb3ggPSAoQ1BXTF9Db21ib0JveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJbkV4cG9ydCA9IHBDb21ib0JveC0+R2V0U2VsZWN0KCk7CisJfQorCQorCWlmIChuRXhwb3J0ID49IDApCisJeworCQlpZiAoQ1BERl9Gb3JtRmllbGQgKiBwRm9ybUZpZWxkID0gbV9wV2lkZ2V0LT5HZXRGb3JtRmllbGQoKSkKKwkJeworCQkJc3dSZXQgPSBwRm9ybUZpZWxkLT5HZXRPcHRpb25WYWx1ZShuRXhwb3J0KTsKKwkJCWlmIChzd1JldC5Jc0VtcHR5KCkpCisJCQkJc3dSZXQgPSBwRm9ybUZpZWxkLT5HZXRPcHRpb25MYWJlbChuRXhwb3J0KTsKKwkJfQorCX0KKwkKKwlyZXR1cm4gc3dSZXQ7Cit9CmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmNwcCBiL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuY3BwCmluZGV4IGY1MTRiZjIuLjUzMGI4MGMgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuY3BwCkBAIC0xLDkyNSArMSw5MjUgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Ob3RpZnkuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9DQkFfRm9udG1hcC5oIg0KLQ0KLSNkZWZpbmUgR2V0UmVkKHJnYikJCQkoKEZYX0JZVEUpKHJnYikpDQotI2RlZmluZSBHZXRHcmVlbihyZ2IpCQkoKEZYX0JZVEUpKCgoRlhfV09SRCkocmdiKSkgPj4gOCkpDQotI2RlZmluZSBHZXRCbHVlKHJnYikJCSgoRlhfQllURSkoKHJnYik+PjE2KSkNCi0NCi0jZGVmaW5lIEZGTF9ISU5UX0VMQVBTRQkJODAwDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX0Zvcm1GaWxsZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGRkxfRm9ybUZpbGxlcjo6Q0ZGTF9Gb3JtRmlsbGVyKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi0JOm1fcEFwcChwQXBwKSwNCi0JbV9wQW5ub3QocEFubm90KSwNCi0JbV9iVmFsaWQoRkFMU0UpLA0KLQltX3B0T2xkUG9zKDAsMCkNCi17IA0KLQltX3BXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKSBwQW5ub3Q7DQotfQ0KLQ0KLUNGRkxfRm9ybUZpbGxlcjo6fkNGRkxfRm9ybUZpbGxlcigpDQotew0KLQlGWF9QT1NJVElPTiBwb3MgPSBtX01hcHMuR2V0U3RhcnRQb3NpdGlvbigpOw0KLQl3aGlsZSAocG9zKQ0KLQl7DQotCQlDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3ID0gTlVMTDsNCi0JCUNQV0xfV25kKiBwV25kID0gTlVMTDsNCi0JCW1fTWFwcy5HZXROZXh0QXNzb2MocG9zLCBwUGFnZVZpZXcsIHBXbmQpOw0KLQ0KLQkJaWYgKHBXbmQpDQotCQl7DQotCQkJQ0ZGTF9Qcml2YXRlRGF0YSogcERhdGEgPSAoQ0ZGTF9Qcml2YXRlRGF0YSopcFduZC0+R2V0QXR0YWNoZWREYXRhKCk7DQotCQkJcFduZC0+RGVzdHJveSgpOw0KLQkJCWRlbGV0ZSBwV25kOw0KLQkJCWRlbGV0ZSBwRGF0YTsNCi0JCX0NCi0JfQ0KLQltX01hcHMuUmVtb3ZlQWxsKCk7DQotDQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpTZXRXaW5kb3dSZWN0KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgY29uc3QgQ1BERl9SZWN0JiByY1dpbmRvdykNCi17DQotCWlmIChDUFdMX1duZCogcFduZCA9IHRoaXMtPkdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0Jew0KLQkJcFduZC0+TW92ZShDUERGX1JlY3QocmNXaW5kb3cpLCBUUlVFLCBGQUxTRSk7DQotCX0NCi19DQotDQotQ1BERl9SZWN0IENGRkxfRm9ybUZpbGxlcjo6R2V0V2luZG93UmVjdChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQlpZiAoQ1BXTF9XbmQqIHBXbmQgPSB0aGlzLT5HZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsNCi0JCXJldHVybiBwV25kLT5HZXRXaW5kb3dSZWN0KCk7DQotCX0NCi0NCi0JcmV0dXJuIENQREZfUmVjdCgwLDAsMCwwKTsNCi19DQotDQotRlhfUkVDVCBDRkZMX0Zvcm1GaWxsZXI6OkdldFZpZXdCQm94KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9SZWN0IHJjQW5ub3QgPSBtX3BXaWRnZXQtPkdldFJlY3QoKTsNCi0NCi0JaWYgKENQV0xfV25kKiBwV25kID0gdGhpcy0+R2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7DQotCQlDUERGX1JlY3QgcmNXaW5kb3cgPSBwV25kLT5HZXRXaW5kb3dSZWN0KCk7DQotCQlyY0Fubm90ID0gUFdMdG9GRkwocmNXaW5kb3cpOw0KLQl9DQotDQotCUNQREZfUmVjdCByY1dpbiA9IHJjQW5ub3Q7DQotLy8JcFBhZ2VWaWV3LT5Eb2NUb1dpbmRvdyhyY0Fubm90LCByY1dpbik7DQotDQotCUNQREZfUmVjdCByY0ZvY3VzID0gdGhpcy0+R2V0Rm9jdXNCb3gocFBhZ2VWaWV3KTsNCi0JaWYgKCFyY0ZvY3VzLklzRW1wdHkoKSkNCi0JCXJjV2luLlVuaW9uKHJjRm9jdXMpOw0KLQ0KLQlDUERGX1JlY3QgcmVjdCA9IENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KHJjV2luLDEpOw0KLQ0KLQlyZXR1cm4gcmVjdC5HZXRPdXR0ZXJSZWN0KCk7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpPbkRyYXcoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCAvKkhEQyBoREMsKi8gQ1BERlNES19Bbm5vdCogcEFubm90LCANCi0JCQkJCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJCQkJCS8qY29uc3QgQ1JlY3QmIHJjV2luZG93LCovIEZYX0RXT1JEIGR3RmxhZ3MpDQotew0KLQlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOw0KLQ0KLQlpZiAoQ1BXTF9XbmQgKiBwV25kID0gR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7DQotCQlDUERGX01hdHJpeCBtdCA9IHRoaXMtPkdldEN1ck1hdHJpeCgpOw0KLQkJbXQuQ29uY2F0KCpwVXNlcjJEZXZpY2UpOw0KLQkJcFduZC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwmbXQpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsNCi0JCWlmIChDRkZMX0lGb3JtRmlsbGVyOjpJc1Zpc2libGUocFdpZGdldCkpDQotCQkJcFdpZGdldC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpOb3JtYWwsIE5VTEwpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpPbkRyYXdEZWFjdGl2ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIA0KLQkJCQkJCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csKi8gRlhfRFdPUkQgZHdGbGFncykNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCQ0KLQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopcEFubm90Ow0KLQkNCi0JcFdpZGdldC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpOb3JtYWwsIE5VTEwpOw0KLX0NCi0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6T25DcmVhdGUoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi19DQotDQotdm9pZCBDRkZMX0Zvcm1GaWxsZXI6Ok9uTG9hZChDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6T25EZWxldGUoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi19DQotDQotdm9pZCBDRkZMX0Zvcm1GaWxsZXI6Ok9uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpPbk1vdXNlRXhpdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCUVuZFRpbWVyKCk7DQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Gb3JtRmlsbGVyOjpPbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlpZiAoQ1BXTF9XbmQgKiBwV25kID0gR2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSkpDQotCXsJCQ0KLQkJbV9iVmFsaWQgPSBUUlVFOw0KLQkJRlhfUkVDVCByZWN0ID0gdGhpcy0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LHBBbm5vdCk7DQotCQl0aGlzLT5JbnZhbGlkYXRlUmVjdChyZWN0LmxlZnQsIHJlY3QudG9wLCByZWN0LnJpZ2h0LCByZWN0LmJvdHRvbSk7DQotDQotIAkJaWYoIXJlY3QuQ29udGFpbnMoKGludClwb2ludC54LCAoaW50KXBvaW50LnkpKQ0KLSAgCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJcmV0dXJuIHBXbmQtPk9uTEJ1dHRvbkRvd24oV25kdG9QV0wocFBhZ2VWaWV3LCBwb2ludCksbkZsYWdzKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9Gb3JtRmlsbGVyOjpPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0JewkNCi0JCUZYX1JFQ1QgcmNGRkwgPSAgdGhpcy0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBwQW5ub3QpOw0KLQkJdGhpcy0+SW52YWxpZGF0ZVJlY3QocmNGRkwubGVmdCwgcmNGRkwudG9wLCByY0ZGTC5yaWdodCwgcmNGRkwuYm90dG9tKTsNCi0JCXBXbmQtPk9uTEJ1dHRvblVwKFduZHRvUFdMKHBQYWdlVmlldywgcG9pbnQpLG5GbGFncyk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9Gb3JtRmlsbGVyOjpPbkxCdXR0b25EYmxDbGsoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCWlmIChDUFdMX1duZCAqIHBXbmQgPSBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsJCQkJDQotCQlwV25kLT5PbkxCdXR0b25EYmxDbGsoV25kdG9QV0wocFBhZ2VWaWV3LCBwb2ludCksbkZsYWdzKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDRkZMX0Zvcm1GaWxsZXI6Ok9uTW91c2VNb3ZlKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlpZiAoKG1fcHRPbGRQb3MueCAhPSBwb2ludC54KSB8fCAobV9wdE9sZFBvcy55ICE9IHBvaW50LnkpKQ0KLQl7DQotCQltX3B0T2xkUG9zID0gcG9pbnQ7DQotCX0NCi0NCi0JaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0JewkJCQkNCi0JCXBXbmQtPk9uTW91c2VNb3ZlKFduZHRvUFdMKHBQYWdlVmlldywgcG9pbnQpLG5GbGFncyk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Gb3JtRmlsbGVyOjpPbk1vdXNlV2hlZWwoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JaWYgKCFJc1ZhbGlkKCkpIHJldHVybiBGQUxTRTsNCi0NCi0JaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpKQ0KLQl7CQkJCQ0KLQkJcmV0dXJuIHBXbmQtPk9uTW91c2VXaGVlbCh6RGVsdGEsIFduZHRvUFdMKHBQYWdlVmlldywgcG9pbnQpLG5GbGFncyk7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENGRkxfRm9ybUZpbGxlcjo6T25SQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpKQ0KLQl7CQkJCQ0KLQkJcFduZC0+T25SQnV0dG9uRG93bihXbmR0b1BXTChwUGFnZVZpZXcsIHBvaW50KSxuRmxhZ3MpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6T25SQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCWlmIChDUFdMX1duZCAqIHBXbmQgPSBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsJCQkJDQotCQlwV25kLT5PblJCdXR0b25VcChXbmR0b1BXTChwUGFnZVZpZXcsIHBvaW50KSxuRmxhZ3MpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6T25SQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlpZiAoQ1BXTF9XbmQgKiBwV25kID0gR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7CQkJCQ0KLQkJcFduZC0+T25SQnV0dG9uRGJsQ2xrKFduZHRvUFdMKHBQYWdlVmlldywgcG9pbnQpLG5GbGFncyk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Gb3JtRmlsbGVyOjpPbktleURvd24oQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5LZXlDb2RlLCBGWF9VSU5UIG5GbGFncykNCi17DQotCWlmIChJc1ZhbGlkKCkpDQotCXsNCi0JCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHRoaXMtPkdldEN1clBhZ2VWaWV3KCk7DQotCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQ0KLQkJaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0JCXsJCQkJDQotCQkJcmV0dXJuIHBXbmQtPk9uS2V5RG93bihuS2V5Q29kZSxuRmxhZ3MpOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQ0KLXsNCi0JaWYgKElzVmFsaWQoKSkNCi0Jew0KLQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gdGhpcy0+R2V0Q3VyUGFnZVZpZXcoKTsNCi0JCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotDQotCQlpZiAoQ1BXTF9XbmQgKiBwV25kID0gR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQkJewkJCQkNCi0JCQlyZXR1cm4gcFduZC0+T25DaGFyKG5DaGFyLG5GbGFncyk7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6T25EZVNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCUFTU0VSVChGQUxTRSk7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpPblNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCUFTU0VSVChGQUxTRSk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9Gb3JtRmlsbGVyOjpPblNldEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZykNCi17DQotCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7DQotDQotCUNQREZfUGFnZSAqIHBQYWdlID0gcFdpZGdldC0+R2V0UERGUGFnZSgpOw0KLSAJQ1BERlNES19Eb2N1bWVudCAqIHBEb2MgPSBtX3BBcHAtPkdldEN1cnJlbnREb2MoKTsNCi0JQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcERvYy0+R2V0UGFnZVZpZXcocFBhZ2UpOw0KLSAJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0NCi0gCQ0KLQ0KLQlDUFdMX1duZCAqIHBXbmQgPSBOVUxMOw0KLQlpZiAoIChwV25kID0gR2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSkpKQ0KLQl7CQkJCQ0KLQkJcFduZC0+U2V0Rm9jdXMoKTsNCi0JfQ0KLQ0KLQltX2JWYWxpZCA9IFRSVUU7DQotCQ0KLQkNCi0JDQotDQotCW1fYlZhbGlkID0gVFJVRTsNCi0JRlhfUkVDVCByY1JlY3QgPSB0aGlzLT5HZXRWaWV3QkJveChwUGFnZVZpZXcscEFubm90KTsNCi0JdGhpcy0+SW52YWxpZGF0ZVJlY3QocmNSZWN0LmxlZnQsIHJjUmVjdC50b3AsIHJjUmVjdC5yaWdodCwgcmNSZWN0LmJvdHRvbSk7DQotCQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0Zvcm1GaWxsZXI6Ok9uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZykNCi17DQotCWlmIChJc1ZhbGlkKCkpDQotCXsNCi0JCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHRoaXMtPkdldEN1clBhZ2VWaWV3KCk7DQotCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQ0KLQkJQ29tbWl0RGF0YShwUGFnZVZpZXcsIG5GbGFnKTsNCi0NCi0JCWlmIChDUFdMX1duZCogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0JCXsJCQkJDQotCQkJcFduZC0+S2lsbEZvY3VzKCk7DQotCQl9DQotCQkNCi0JCXN3aXRjaCAobV9wV2lkZ2V0LT5HZXRGaWVsZFR5cGUoKSkNCi0JCXsNCi0JCWNhc2UgRklFTERUWVBFX1BVU0hCVVRUT046DQotCQljYXNlIEZJRUxEVFlQRV9DSEVDS0JPWDoNCi0JCWNhc2UgRklFTERUWVBFX1JBRElPQlVUVE9OOg0KLQkJCUVzY2FwZUZpbGxlcihwUGFnZVZpZXcsIFRSVUUpOw0KLQkJCWJyZWFrOw0KLQkJZGVmYXVsdDoNCi0JCQlFc2NhcGVGaWxsZXIocFBhZ2VWaWV3LCBGQUxTRSk7DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9Gb3JtRmlsbGVyOjpJc1ZhbGlkKCkgY29uc3QNCi17DQotCXJldHVybiBtX2JWYWxpZDsNCi19DQotDQotUFdMX0NSRUFURVBBUkFNCUNGRkxfRm9ybUZpbGxlcjo6R2V0Q3JlYXRlUGFyYW0oKQ0KLXsNCi0JQVNTRVJUKG1fcEFwcCAhPSBOVUxMKTsNCi0NCi0JUFdMX0NSRUFURVBBUkFNIGNwOw0KLQ0KLQljcC5wUGFyZW50V25kID0gTlVMTDsJDQotCWNwLnBQcm92aWRlciA9IHRoaXM7DQotCWNwLnJjUmVjdFduZCA9IEdldFBERldpbmRvd1JlY3QoKTsNCi0JDQotCUZYX0RXT1JEIGR3Q3JlYXRlRmxhZ3MgPSBQV1NfQk9SREVSIHwgUFdTX0JBQ0tHUk9VTkQgfCBQV1NfVklTSUJMRTsNCi0NCi0JQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0NCi0NCi0JRlhfRFdPUkQgZHdGaWVsZEZsYWcgPSBtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKTsNCi0NCi0JaWYgKGR3RmllbGRGbGFnICYgRklFTERGTEFHX1JFQURPTkxZKQ0KLQl7CQkNCi0JCWR3Q3JlYXRlRmxhZ3MgfD0gUFdTX1JFQURPTkxZOw0KLQl9DQotDQotCUZYX0NPTE9SUkVGIGNvbG9yOw0KLQlpZiAobV9wV2lkZ2V0LT5HZXRGaWxsQ29sb3IoY29sb3IpKQ0KLQl7DQotCQljcC5zQmFja2dyb3VuZENvbG9yID0gQ1BXTF9Db2xvcihHZXRSZWQoY29sb3IpLCBHZXRHcmVlbihjb2xvciksIEdldEJsdWUoY29sb3IpKTsNCi0JfQ0KLQ0KLQlpZiAobV9wV2lkZ2V0LT5HZXRCb3JkZXJDb2xvcihjb2xvcikpDQotCXsNCi0JCWNwLnNCb3JkZXJDb2xvciA9IENQV0xfQ29sb3IoR2V0UmVkKGNvbG9yKSwgR2V0R3JlZW4oY29sb3IpLCBHZXRCbHVlKGNvbG9yKSk7DQotCX0NCi0NCi0JY3Auc1RleHRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMCk7DQotDQotCWlmIChtX3BXaWRnZXQtPkdldFRleHRDb2xvcihjb2xvcikpDQotCXsNCi0JCWNwLnNUZXh0Q29sb3IgPSBDUFdMX0NvbG9yKEdldFJlZChjb2xvciksIEdldEdyZWVuKGNvbG9yKSwgR2V0Qmx1ZShjb2xvcikpOw0KLQl9DQotDQotCWNwLmZGb250U2l6ZSA9IG1fcFdpZGdldC0+R2V0Rm9udFNpemUoKTsNCi0JY3AuZHdCb3JkZXJXaWR0aCA9IG1fcFdpZGdldC0+R2V0Qm9yZGVyV2lkdGgoKTsNCi0JDQotCWludCBuQm9yZGVyU3R5bGUgPSBtX3BXaWRnZXQtPkdldEJvcmRlclN0eWxlKCk7DQotDQotCXN3aXRjaCAobkJvcmRlclN0eWxlKQ0KLQl7DQotCWNhc2UgQkJTX1NPTElEOg0KLQkJY3AubkJvcmRlclN0eWxlID0gUEJTX1NPTElEOw0KLQkJYnJlYWs7DQotCWNhc2UgQkJTX0RBU0g6DQotCQljcC5uQm9yZGVyU3R5bGUgPSBQQlNfREFTSDsNCi0JCWNwLnNEYXNoID0gQ1BXTF9EYXNoKDMsMywwKTsJCQkNCi0JCWJyZWFrOw0KLQljYXNlIEJCU19CRVZFTEVEOg0KLQkJY3AubkJvcmRlclN0eWxlID0gUEJTX0JFVkVMRUQ7DQotCQljcC5kd0JvcmRlcldpZHRoICo9IDI7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfSU5TRVQ6DQotCQljcC5uQm9yZGVyU3R5bGUgPSBQQlNfSU5TRVQ7DQotCQljcC5kd0JvcmRlcldpZHRoICo9IDI7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfVU5ERVJMSU5FOg0KLQkJY3AubkJvcmRlclN0eWxlID0gUEJTX1VOREVSTElORUQ7DQotCQlicmVhazsNCi0JfQ0KLQ0KLQlpZiAoY3AuZkZvbnRTaXplIDw9IDApDQotCXsNCi0JCWR3Q3JlYXRlRmxhZ3MgfD0gUFdTX0FVVE9GT05UU0laRTsNCi0JfQ0KLQ0KLQljcC5kd0ZsYWdzID0gZHdDcmVhdGVGbGFnczsNCi0JY3AucFN5c3RlbUhhbmRsZXIgPSBtX3BBcHAtPkdldFN5c0hhbmRsZXIoKTsNCi0JcmV0dXJuIGNwOw0KLX0NCi0NCi1DUFdMX1duZCogQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRQREZXaW5kb3coQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MIGJOZXcpDQotew0KLQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQlDUFdMX1duZCogcFduZCA9IE5VTEw7DQotCW1fTWFwcy5Mb29rdXAocFBhZ2VWaWV3LCBwV25kKTsNCi0NCi0JaWYgKGJOZXcpDQotCXsNCi0JCWlmIChwV25kKQ0KLQkJew0KLQkJCUNGRkxfUHJpdmF0ZURhdGEqIHBQcml2YXRlRGF0YSA9IChDRkZMX1ByaXZhdGVEYXRhKilwV25kLT5HZXRBdHRhY2hlZERhdGEoKTsNCi0JCQlBU1NFUlQocFByaXZhdGVEYXRhICE9IE5VTEwpOw0KLQ0KLQkJCWlmIChwUHJpdmF0ZURhdGEtPm5XaWRnZXRBZ2UgIT0gbV9wV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCkpDQotCQkJew0KLQkJCQlyZXR1cm4gdGhpcy0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBtX3BXaWRnZXQtPkdldFZhbHVlQWdlKCkgPT0gcFByaXZhdGVEYXRhLT5uVmFsdWVBZ2UpOw0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlQV0xfQ1JFQVRFUEFSQU0gY3AgPSBHZXRDcmVhdGVQYXJhbSgpOw0KLQkJCWNwLmhBdHRhY2hlZFduZCA9IChGWF9IV05EKW1fcFdpZGdldDsNCi0NCi0JCQlDRkZMX1ByaXZhdGVEYXRhKiBwUHJpdmF0ZURhdGEgPSBuZXcgQ0ZGTF9Qcml2YXRlRGF0YTsNCi0JCQlwUHJpdmF0ZURhdGEtPnBXaWRnZXQgPSBtX3BXaWRnZXQ7DQotCQkJcFByaXZhdGVEYXRhLT5wUGFnZVZpZXcgPSBwUGFnZVZpZXc7DQotCQkJcFByaXZhdGVEYXRhLT5uV2lkZ2V0QWdlID0gbV9wV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCk7DQotICAgICAgICAgICAgICAgICAgICAgICAgcFByaXZhdGVEYXRhLT5uVmFsdWVBZ2UgPSAwOw0KLQ0KLQkJCWNwLnBBdHRhY2hlZERhdGEgPSBwUHJpdmF0ZURhdGE7DQotDQotCQkJcFduZCA9IE5ld1BERldpbmRvdyhjcCwgcFBhZ2VWaWV3KTsNCi0NCi0JCQlpZiAocFduZCkNCi0JCQl7DQotCQkJCW1fTWFwcy5TZXRBdChwUGFnZVZpZXcsIHBXbmQpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gcFduZDsNCi19DQotDQotdm9pZCBDRkZMX0Zvcm1GaWxsZXI6OkRlc3Ryb3lQREZXaW5kb3coQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JQ1BXTF9XbmQqIHBXbmQgPSBOVUxMOw0KLQltX01hcHMuTG9va3VwKHBQYWdlVmlldywgcFduZCk7DQotDQotCWlmIChwV25kKQ0KLQl7DQotCQlDRkZMX1ByaXZhdGVEYXRhKiBwRGF0YSA9IChDRkZMX1ByaXZhdGVEYXRhKilwV25kLT5HZXRBdHRhY2hlZERhdGEoKTsNCi0JCXBEYXRhLT5wUGFnZVZpZXcgPSBOVUxMOw0KLQkJcFduZC0+RGVzdHJveSgpOw0KLQkJZGVsZXRlIHBXbmQ7DQotCQlkZWxldGUgcERhdGE7DQotCX0NCi0NCi0JbV9NYXBzLlJlbW92ZUtleShwUGFnZVZpZXcpOw0KLX0NCi0NCi1DUERGX01hdHJpeAlDRkZMX0Zvcm1GaWxsZXI6OkdldFdpbmRvd01hdHJpeCh2b2lkKiBwQXR0YWNoZWREYXRhKQ0KLXsNCi0JaWYgKENGRkxfUHJpdmF0ZURhdGEqIHBQcml2YXRlRGF0YSA9IChDRkZMX1ByaXZhdGVEYXRhKilwQXR0YWNoZWREYXRhKQ0KLQl7DQotCQlpZiAocFByaXZhdGVEYXRhLT5wUGFnZVZpZXcpDQotCQl7DQotCQkJQ1BERl9NYXRyaXggbXRQYWdlVmlldzsNCi0JCQlwUHJpdmF0ZURhdGEtPnBQYWdlVmlldy0+R2V0Q3VycmVudE1hdHJpeChtdFBhZ2VWaWV3KTsNCi0JCQlDUERGX01hdHJpeCBtdCA9IEdldEN1ck1hdHJpeCgpOw0KLQkJCW10LkNvbmNhdChtdFBhZ2VWaWV3KTsNCi0JCQkNCi0JCQlyZXR1cm4gbXQ7DQotCQl9DQotCX0NCi0JcmV0dXJuIENQREZfTWF0cml4KDEsMCwwLDEsMCwwKTsNCi19DQotDQotQ1BERl9NYXRyaXgJQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRDdXJNYXRyaXgoKQ0KLXsNCi0JQ1BERl9NYXRyaXggbXQ7DQotDQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotDQotCUNQREZfUmVjdCByY0RBIDsNCi0JbV9wV2lkZ2V0LT5HZXRQREZBbm5vdCgpLT5HZXRSZWN0KHJjREEpOw0KLQ0KLQ0KLQlzd2l0Y2ggKG1fcFdpZGdldC0+R2V0Um90YXRlKCkpDQotCXsNCi0JZGVmYXVsdDoNCi0JY2FzZSAwOgkJDQotCQltdCA9IENQREZfTWF0cml4KDEsMCwwLDEsMCwwKTsNCi0JCWJyZWFrOw0KLQljYXNlIDkwOg0KLQkJbXQgPSBDUERGX01hdHJpeCgwLDEsLTEsMCxyY0RBLnJpZ2h0IC0gcmNEQS5sZWZ0LDApOw0KLQkJYnJlYWs7DQotCWNhc2UgMTgwOg0KLQkJbXQgPSBDUERGX01hdHJpeCgtMSwwLDAsLTEscmNEQS5yaWdodCAtIHJjREEubGVmdCxyY0RBLnRvcCAtIHJjREEuYm90dG9tKTsNCi0JCWJyZWFrOw0KLQljYXNlIDI3MDoNCi0JCW10ID0gQ1BERl9NYXRyaXgoMCwtMSwxLDAsMCxyY0RBLnRvcCAtIHJjREEuYm90dG9tKTsNCi0JCWJyZWFrOw0KLQl9DQotCW10LmUgKz0gcmNEQS5sZWZ0Ow0KLQltdC5mICs9IHJjREEuYm90dG9tOw0KLQ0KLQlyZXR1cm4gbXQ7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENGRkxfRm9ybUZpbGxlcjo6TG9hZFBvcHVwTWVudVN0cmluZyhpbnQgbkluZGV4KQ0KLXsNCi0JQVNTRVJUKG1fcEFwcCAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIEwiIjsNCi19DQotDQotQ1BERl9SZWN0IENGRkxfRm9ybUZpbGxlcjo6R2V0UERGV2luZG93UmVjdCgpIGNvbnN0DQotew0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQlDUERGX1JlY3QgcmVjdEFubm90Ow0KLQltX3BXaWRnZXQtPkdldFBERkFubm90KCktPkdldFJlY3QocmVjdEFubm90KTsNCi0NCi0JRlhfRkxPQVQgZldpZHRoID0gcmVjdEFubm90LnJpZ2h0IC0gcmVjdEFubm90LmxlZnQ7DQotCUZYX0ZMT0FUIGZIZWlnaHQgPSByZWN0QW5ub3QudG9wIC0gcmVjdEFubm90LmJvdHRvbTsNCi0NCi0NCi0JaWYgKChtX3BXaWRnZXQtPkdldFJvdGF0ZSgpIC8gOTApICYgMHgwMSkNCi0JCXJldHVybiBDUERGX1JlY3QoMCwwLGZIZWlnaHQsZldpZHRoKTsNCi0JZWxzZQ0KLQkJcmV0dXJuIENQREZfUmVjdCgwLDAsZldpZHRoLGZIZWlnaHQpOw0KLX0NCi0NCi1DUERGU0RLX1BhZ2VWaWV3KiBDRkZMX0Zvcm1GaWxsZXI6OkdldEN1clBhZ2VWaWV3KCkNCi17DQotDQotCUNQREZfUGFnZSogcFBhZ2UgPSBtX3BBbm5vdC0+R2V0UERGUGFnZSgpOw0KLQlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gbV9wQXBwLT5HZXRDdXJyZW50RG9jKCk7DQotCWlmKHBTREtEb2MpDQotCXsNCi0JCXJldHVybiBwU0RLRG9jLT5HZXRQYWdlVmlldyhwUGFnZSk7DQotCX0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUNQREZfUmVjdCBDRkZMX0Zvcm1GaWxsZXI6OkdldEZvY3VzQm94KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCWlmIChDUFdMX1duZCAqIHBXbmQgPSBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsJCQkNCi0JCUNQREZfUmVjdCByY0ZvY3VzID0gIEZGTHRvV25kKHBQYWdlVmlldywgUFdMdG9GRkwocFduZC0+R2V0Rm9jdXNSZWN0KCkpKTsNCi0JCUFTU0VSVChwUGFnZVZpZXcpOw0KLQkJQ1BERl9SZWN0IHJjUGFnZSA9IHBQYWdlVmlldy0+R2V0UERGUGFnZSgpLT5HZXRQYWdlQkJveCgpOw0KLQkJaWYocmNQYWdlLkNvbnRhaW5zKHJjRm9jdXMpKQ0KLQkJCXJldHVybiByY0ZvY3VzOw0KLQkJZWxzZQ0KLQkJCXJldHVybiBDUERGX1JlY3QoMCwwLDAsMCk7DQotCX0NCi0JcmV0dXJuIENQREZfUmVjdCgwLDAsMCwwKTsNCi19DQotDQotQ1BERl9SZWN0IENGRkxfRm9ybUZpbGxlcjo6RkZMdG9QV0woY29uc3QgQ1BERl9SZWN0JiByZWN0KQ0KLXsNCi0JQ1BERl9NYXRyaXggbXQ7DQotCW10LlNldFJldmVyc2UoR2V0Q3VyTWF0cml4KCkpOw0KLQkNCi0JQ1BERl9SZWN0IHRlbXAgPSByZWN0Ow0KLQltdC5UcmFuc2Zvcm1SZWN0KHRlbXApOw0KLQ0KLQlyZXR1cm4gdGVtcDsNCi19DQotDQotQ1BERl9SZWN0IENGRkxfRm9ybUZpbGxlcjo6UFdMdG9GRkwoY29uc3QgQ1BERl9SZWN0JiByZWN0KQ0KLXsNCi0JQ1BERl9NYXRyaXggbXQgPSBHZXRDdXJNYXRyaXgoKTsNCi0JDQotCUNQREZfUmVjdCB0ZW1wID0gcmVjdDsNCi0JbXQuVHJhbnNmb3JtUmVjdCh0ZW1wKTsNCi0NCi0JcmV0dXJuIHRlbXA7DQotfQ0KLQ0KLUNQREZfUG9pbnQgQ0ZGTF9Gb3JtRmlsbGVyOjpGRkx0b1BXTChjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUNQREZfTWF0cml4IG10Ow0KLQltdC5TZXRSZXZlcnNlKEdldEN1ck1hdHJpeCgpKTsNCi0NCi0JQ1BERl9Qb2ludCBwdCA9IHBvaW50Ow0KLQltdC5UcmFuc2Zvcm0ocHQueCxwdC55KTsNCi0NCi0JcmV0dXJuIHB0Ow0KLX0NCi0NCi1DUERGX1BvaW50IENGRkxfRm9ybUZpbGxlcjo6UFdMdG9GRkwoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQ0KLXsNCi0JQ1BERl9NYXRyaXggbXQgPSBHZXRDdXJNYXRyaXgoKTsNCi0NCi0JQ1BERl9Qb2ludCBwdCA9IHBvaW50Ow0KLQltdC5UcmFuc2Zvcm0ocHQueCxwdC55KTsNCi0NCi0JcmV0dXJuIHB0Ow0KLX0NCi0NCi1DUERGX1BvaW50IENGRkxfRm9ybUZpbGxlcjo6V25kdG9QV0woQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBjb25zdCBDUERGX1BvaW50JiBwdCkNCi17DQotLy8gCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotLy8gDQotLy8gCUNQREZfUG9pbnQgcG9pbnQoMC4wZiwgMC4wZik7DQotLy8gCXBQYWdlVmlldy0+V2luZG93VG9Eb2MocHQueCwgcHQueSwgcG9pbnQueCwgcG9pbnQueSk7DQotLy8gDQotIAlyZXR1cm4gRkZMdG9QV0wocHQpOw0KLS8vCXJldHVybiBDUERGX1BvaW50KDAsIDApOw0KLX0NCi0NCi1DUERGX1JlY3QgQ0ZGTF9Gb3JtRmlsbGVyOjpGRkx0b1duZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIGNvbnN0IENQREZfUmVjdCAmIHJlY3QpDQotew0KLS8vIAlGWF9SRUNUIHJjUmV0KDAsMCwwLDApOw0KLS8vIA0KLS8vIAlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOwkNCi0vLyAJcFBhZ2VWaWV3LT5Eb2NUb1dpbmRvdyhyZWN0LCByY1JldCk7DQotLy8gCQ0KLSAJcmV0dXJuIHJlY3Q7DQotDQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpGRkxfRnJlZURhdGEodm9pZCogcERhdGEpDQotew0KLQlBU1NFUlQocERhdGEgIT0gTlVMTCk7DQotDQotCWRlbGV0ZSAoQ0ZGTF9Qcml2YXRlRGF0YSopcERhdGE7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Gb3JtRmlsbGVyOjpDb21taXREYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfVUlOVCBuRmxhZykNCi17DQotCWlmIChJc0RhdGFDaGFuZ2VkKHBQYWdlVmlldykpDQotCXsNCi0JCS8vQ0ZGTF9JRm9ybUZpbGxlciogcElGb3JtRmlsbGVyID0gQ0ZGTF9Nb2R1bGU6OkdldEZvcm1GaWxsZXIobV9wQXBwKTsNCi0JCUNGRkxfSUZvcm1GaWxsZXIqIHBJRm9ybUZpbGxlciA9IG1fcEFwcC0+R2V0SUZvcm1GaWxsZXIoKTsvL05VTEw7DQotCQlBU1NFUlQocElGb3JtRmlsbGVyICE9IE5VTEwpOw0KLQ0KLQkJRlhfQk9PTCBiUkMgPSBUUlVFOw0KLQkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOw0KLQ0KLQkJcElGb3JtRmlsbGVyLT5PbktleVN0cm9rZUNvbW1pdChtX3BXaWRnZXQsIHBQYWdlVmlldywgYlJDLCBiRXhpdCwgbkZsYWcpOw0KLQkJaWYgKGJFeGl0KSByZXR1cm4gVFJVRTsNCi0JCWlmICghYlJDKQ0KLQkJew0KLQkJCXRoaXMtPlJlc2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpOw0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQ0KLQkJcElGb3JtRmlsbGVyLT5PblZhbGlkYXRlKG1fcFdpZGdldCwgcFBhZ2VWaWV3LCBiUkMsIGJFeGl0LCBuRmxhZyk7DQotCQlpZiAoYkV4aXQpIHJldHVybiBUUlVFOw0KLQkJaWYgKCFiUkMpDQotCQl7DQotCQkJdGhpcy0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSk7DQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotDQotCQlTYXZlRGF0YShwUGFnZVZpZXcpOw0KLQ0KLQkJcElGb3JtRmlsbGVyLT5PbkNhbGN1bGF0ZShtX3BXaWRnZXQsIHBQYWdlVmlldywgYkV4aXQsbkZsYWcpOw0KLQkJaWYgKGJFeGl0KSByZXR1cm4gVFJVRTsNCi0NCi0JCXBJRm9ybUZpbGxlci0+T25Gb3JtYXQobV9wV2lkZ2V0LCBwUGFnZVZpZXcsIGJFeGl0LG5GbGFnKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0Zvcm1GaWxsZXI6OklzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6U2F2ZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi19DQotDQotdm9pZCBDRkZMX0Zvcm1GaWxsZXI6OkdldEtleVN0cm9rZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGRkxfS2V5U3Ryb2tlRGF0YSYgZGF0YSkNCi17DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpTZXRDaGFuZ2VNYXJrKCkNCi17DQotCW1fcEFwcC0+RkZJX09uQ2hhbmdlKCk7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLA0KLQkJCQkJCQlQREZTREtfRmllbGRBY3Rpb24mIGZhKQ0KLXsNCi0JZmEuc1ZhbHVlID0gbV9wV2lkZ2V0LT5HZXRWYWx1ZSgpOw0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6U2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgDQotCQkJCQkJCQkJY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSkNCi17DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9Gb3JtRmlsbGVyOjpJc0FjdGlvbkRhdGFDaGFuZ2VkKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU9sZCwgDQotCQkJCQkJCQkJY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU5ldykNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBDRkZMX0Zvcm1GaWxsZXI6OlNhdmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6UmVzdG9yZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotfQ0KLQ0KLUNQV0xfV25kKiAgQ0ZGTF9Gb3JtRmlsbGVyOjpSZXNldFBERldpbmRvdyhDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wgYlJlc3RvcmVWYWx1ZSkNCi17DQotCXJldHVybiBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSk7IA0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6VGltZXJQcm9jKCkNCi17DQotDQotfQ0KLQ0KLUlGWF9TeXN0ZW1IYW5kbGVyKiBDRkZMX0Zvcm1GaWxsZXI6OkdldFN5c3RlbUhhbmRsZXIoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcEFwcC0+R2V0U3lzSGFuZGxlcigpOw0KLS8vCXJldHVybiBOVUxMOw0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6T25LZXlTdHJva2UoRlhfQk9PTCBiS2V5RG93bikNCi17DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpFc2NhcGVGaWxsZXIoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MIGJEZXN0cm95UERGV2luZG93KQ0KLXsNCi0JbV9iVmFsaWQgPSBGQUxTRTsNCi0JDQotCUZYX1JFQ1QgcmNSZWN0ID0gdGhpcy0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBtX3BXaWRnZXQpOw0KLQl0aGlzLT5JbnZhbGlkYXRlUmVjdChyY1JlY3QubGVmdCwgcmNSZWN0LnRvcCwgcmNSZWN0LnJpZ2h0LCByY1JlY3QuYm90dG9tKTsNCi0NCi0JaWYoYkRlc3Ryb3lQREZXaW5kb3cpDQotIAkJRGVzdHJveVBERldpbmRvdyhwUGFnZVZpZXcpOw0KLX0NCi0NCi1GWF9CT09MIENGRkxfRm9ybUZpbGxlcjo6Q2FuQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Gb3JtRmlsbGVyOjpDYW5DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6Q2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6RG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpEb0N1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6RG9QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLX0NCi0NCi12b2lkIENGRkxfRm9ybUZpbGxlcjo6SW52YWxpZGF0ZVJlY3QoZG91YmxlIGxlZnQsIGRvdWJsZSB0b3AsIGRvdWJsZSByaWdodCwgZG91YmxlIGJvdHRvbSkNCi17DQotCUNQREZfUGFnZSAqIHBQYWdlID0gbV9wV2lkZ2V0LT5HZXRQREZQYWdlKCk7DQotCW1fcEFwcC0+RkZJX0ludmFsaWRhdGUocFBhZ2UsIGxlZnQsIHRvcCwgcmlnaHQsIGJvdHRvbSk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZGTF9CdXR0b24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGRkxfQnV0dG9uOjpDRkZMX0J1dHRvbihDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwV2lkZ2V0KSA6DQotCUNGRkxfRm9ybUZpbGxlcihwQXBwLCBwV2lkZ2V0KSwNCi0JbV9iTW91c2VJbihGQUxTRSksDQotCW1fYk1vdXNlRG93bihGQUxTRSkNCi17DQotfQ0KLQ0KLUNGRkxfQnV0dG9uOjp+Q0ZGTF9CdXR0b24oKQ0KLXsNCi19DQotDQotdm9pZCBDRkZMX0J1dHRvbjo6T25Nb3VzZUVudGVyKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JbV9iTW91c2VJbiA9IFRSVUU7DQotCUZYX1JFQ1QgcmVjdCA9IHRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldyxwQW5ub3QpOw0KLQl0aGlzLT5JbnZhbGlkYXRlUmVjdChyZWN0LmxlZnQsIHJlY3QudG9wLCByZWN0LnJpZ2h0LCByZWN0LmJvdHRvbSk7DQotLy8JOjpJbnZhbGlkYXRlUmVjdChwUGFnZVZpZXctPkdldFBhZ2VWaWV3V25kKCksICZ0aGlzLT5HZXRWaWV3QkJveChwUGFnZVZpZXcsIHBBbm5vdCksIFRSVUUpOw0KLX0NCi0NCi12b2lkIENGRkxfQnV0dG9uOjpPbk1vdXNlRXhpdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCW1fYk1vdXNlSW4gPSBGQUxTRTsNCi0NCi0JRlhfUkVDVCByZWN0ID0gdGhpcy0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LHBBbm5vdCk7DQotCXRoaXMtPkludmFsaWRhdGVSZWN0KHJlY3QubGVmdCwgcmVjdC50b3AsIHJlY3QucmlnaHQsIHJlY3QuYm90dG9tKTsNCi0vLwk6OkludmFsaWRhdGVSZWN0KHBQYWdlVmlldy0+R2V0UGFnZVZpZXdXbmQoKSwgJnRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KSwgVFJVRSk7DQotCUVuZFRpbWVyKCk7DQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotLy8JbV9wV2lkZ2V0LT5IaWRlSGludCgpOw0KLX0NCi0NCi1GWF9CT09MIENGRkxfQnV0dG9uOjpPbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlDUERGX1JlY3QgcmNBbm5vdCA9IHBBbm5vdC0+R2V0UmVjdCgpOw0KLQlpZighcmNBbm5vdC5Db250YWlucyhwb2ludC54LCBwb2ludC55KSkNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JbV9iTW91c2VEb3duID0gVFJVRTsNCi0JbV9iVmFsaWQgPSBUUlVFOw0KLQlGWF9SRUNUIHJlY3QgPSB0aGlzLT5HZXRWaWV3QkJveChwUGFnZVZpZXcsIHBBbm5vdCk7DQotCXRoaXMtPkludmFsaWRhdGVSZWN0KHJlY3QubGVmdCwgcmVjdC50b3AsIHJlY3QucmlnaHQsIHJlY3QuYm90dG9tKTsNCi0vLwk6OkludmFsaWRhdGVSZWN0KHBQYWdlVmlldy0+R2V0UGFnZVZpZXdXbmQoKSwgJnRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KSwgVFJVRSk7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfQnV0dG9uOjpPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQ1BERl9SZWN0IHJjQW5ub3QgPSBwQW5ub3QtPkdldFJlY3QoKTsNCi0JaWYoIXJjQW5ub3QuQ29udGFpbnMocG9pbnQueCwgcG9pbnQueSkpDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCW1fYk1vdXNlRG93biA9IEZBTFNFOw0KLQltX3BXaWRnZXQtPkdldFBERlBhZ2UoKTsNCi0JDQotDQotCUZYX1JFQ1QgcmVjdCA9IHRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KTsNCi0JdGhpcy0+SW52YWxpZGF0ZVJlY3QocmVjdC5sZWZ0LCByZWN0LnRvcCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20pOw0KLS8vIAk6OkludmFsaWRhdGVSZWN0KHBQYWdlVmlldy0+R2V0UGFnZVZpZXdXbmQoKSwgJnRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KSwgVFJVRSk7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfQnV0dG9uOjpPbk1vdXNlTW92ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKG1fcEFwcCAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9CdXR0b246Ok9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIA0KLQkJCQkJCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJCQkJCQkvKmNvbnN0IENSZWN0JiByY1dpbmRvdywqLyBGWF9EV09SRCBkd0ZsYWdzKQ0KLXsNCi0JQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsNCi0NCi0JQ1BERl9Gb3JtQ29udHJvbCogcEN0cmwgPSBwV2lkZ2V0LT5HZXRGb3JtQ29udHJvbCgpOw0KLQlBU1NFUlQocEN0cmwgIT0gTlVMTCk7DQotDQotCUNQREZfRm9ybUNvbnRyb2w6OkhpZ2hsaWdodGluZ01vZGUgZUhNID0gcEN0cmwtPkdldEhpZ2hsaWdodGluZ01vZGUoKTsNCi0NCi0JaWYgKGVITSA9PSBDUERGX0Zvcm1Db250cm9sOjpQdXNoKQ0KLQl7DQotCQlpZiAobV9iTW91c2VEb3duKQ0KLQkJew0KLQkJCWlmIChwV2lkZ2V0LT5Jc1dpZGdldEFwcGVhcmFuY2VWYWxpZChDUERGX0Fubm90OjpEb3duKSkNCi0JCQkJcFdpZGdldC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpEb3duLCBOVUxMKTsNCi0JCQllbHNlDQotCQkJCXBXaWRnZXQtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsNCi0JCX0NCi0JCWVsc2UgaWYgKG1fYk1vdXNlSW4pDQotCQl7DQotCQkJaWYgKHBXaWRnZXQtPklzV2lkZ2V0QXBwZWFyYW5jZVZhbGlkKENQREZfQW5ub3Q6OlJvbGxvdmVyKSkNCi0JCQkJcFdpZGdldC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpSb2xsb3ZlciwgTlVMTCk7DQotCQkJZWxzZQ0KLQkJCQlwV2lkZ2V0LT5EcmF3QXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIENQREZfQW5ub3Q6Ok5vcm1hbCwgTlVMTCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJcFdpZGdldC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpOb3JtYWwsIE5VTEwpOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0JCXBXaWRnZXQtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsNCi19DQotDQotDQotdm9pZCBDRkZMX0J1dHRvbjo6T25EcmF3RGVhY3RpdmUoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCAvKkhEQyBoREMsKi8gQ1BERlNES19Bbm5vdCogcEFubm90LCANCi0JCQkJCQkJCSBDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJCQkJCQkJIC8qY29uc3QgQ1JlY3QmIHJjV2luZG93LCAqL0ZYX0RXT1JEIGR3RmxhZ3MpDQotew0KLQlPbkRyYXcocFBhZ2VWaWV3LCBwQW5ub3QsIHBEZXZpY2UsIHBVc2VyMkRldmljZSwgZHdGbGFncyk7DQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTm90aWZ5LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9DQkFfRm9udG1hcC5oIgorCisjZGVmaW5lIEdldFJlZChyZ2IpCQkJKChGWF9CWVRFKShyZ2IpKQorI2RlZmluZSBHZXRHcmVlbihyZ2IpCQkoKEZYX0JZVEUpKCgoRlhfV09SRCkocmdiKSkgPj4gOCkpCisjZGVmaW5lIEdldEJsdWUocmdiKQkJKChGWF9CWVRFKSgocmdiKT4+MTYpKQorCisjZGVmaW5lIEZGTF9ISU5UX0VMQVBTRQkJODAwCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZGTF9Gb3JtRmlsbGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0ZGTF9Gb3JtRmlsbGVyOjpDRkZMX0Zvcm1GaWxsZXIoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19Bbm5vdCogcEFubm90KQorCTptX3BBcHAocEFwcCksCisJbV9wQW5ub3QocEFubm90KSwKKwltX2JWYWxpZChGQUxTRSksCisJbV9wdE9sZFBvcygwLDApCit7IAorCW1fcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopIHBBbm5vdDsKK30KKworQ0ZGTF9Gb3JtRmlsbGVyOjp+Q0ZGTF9Gb3JtRmlsbGVyKCkKK3sKKwlGWF9QT1NJVElPTiBwb3MgPSBtX01hcHMuR2V0U3RhcnRQb3NpdGlvbigpOworCXdoaWxlIChwb3MpCisJeworCQlDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3ID0gTlVMTDsKKwkJQ1BXTF9XbmQqIHBXbmQgPSBOVUxMOworCQltX01hcHMuR2V0TmV4dEFzc29jKHBvcywgcFBhZ2VWaWV3LCBwV25kKTsKKworCQlpZiAocFduZCkKKwkJeworCQkJQ0ZGTF9Qcml2YXRlRGF0YSogcERhdGEgPSAoQ0ZGTF9Qcml2YXRlRGF0YSopcFduZC0+R2V0QXR0YWNoZWREYXRhKCk7CisJCQlwV25kLT5EZXN0cm95KCk7CisJCQlkZWxldGUgcFduZDsKKwkJCWRlbGV0ZSBwRGF0YTsKKwkJfQorCX0KKwltX01hcHMuUmVtb3ZlQWxsKCk7CisKK30KKwordm9pZCBDRkZMX0Zvcm1GaWxsZXI6OlNldFdpbmRvd1JlY3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBjb25zdCBDUERGX1JlY3QmIHJjV2luZG93KQoreworCWlmIChDUFdMX1duZCogcFduZCA9IHRoaXMtPkdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CisJCXBXbmQtPk1vdmUoQ1BERl9SZWN0KHJjV2luZG93KSwgVFJVRSwgRkFMU0UpOworCX0KK30KKworQ1BERl9SZWN0IENGRkxfRm9ybUZpbGxlcjo6R2V0V2luZG93UmVjdChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJaWYgKENQV0xfV25kKiBwV25kID0gdGhpcy0+R2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJcmV0dXJuIHBXbmQtPkdldFdpbmRvd1JlY3QoKTsKKwl9CisKKwlyZXR1cm4gQ1BERl9SZWN0KDAsMCwwLDApOworfQorCitGWF9SRUNUIENGRkxfRm9ybUZpbGxlcjo6R2V0Vmlld0JCb3goQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCisJQ1BERl9SZWN0IHJjQW5ub3QgPSBtX3BXaWRnZXQtPkdldFJlY3QoKTsKKworCWlmIChDUFdMX1duZCogcFduZCA9IHRoaXMtPkdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CisJCUNQREZfUmVjdCByY1dpbmRvdyA9IHBXbmQtPkdldFdpbmRvd1JlY3QoKTsKKwkJcmNBbm5vdCA9IFBXTHRvRkZMKHJjV2luZG93KTsKKwl9CisKKwlDUERGX1JlY3QgcmNXaW4gPSByY0Fubm90OworLy8JcFBhZ2VWaWV3LT5Eb2NUb1dpbmRvdyhyY0Fubm90LCByY1dpbik7CisKKwlDUERGX1JlY3QgcmNGb2N1cyA9IHRoaXMtPkdldEZvY3VzQm94KHBQYWdlVmlldyk7CisJaWYgKCFyY0ZvY3VzLklzRW1wdHkoKSkKKwkJcmNXaW4uVW5pb24ocmNGb2N1cyk7CisKKwlDUERGX1JlY3QgcmVjdCA9IENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KHJjV2luLDEpOworCisJcmV0dXJuIHJlY3QuR2V0T3V0dGVyUmVjdCgpOworfQorCit2b2lkIENGRkxfRm9ybUZpbGxlcjo6T25EcmF3KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgLypIREMgaERDLCovIENQREZTREtfQW5ub3QqIHBBbm5vdCwgCisJCQkJCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csKi8gRlhfRFdPUkQgZHdGbGFncykKK3sKKwlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOworCisJaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CisJCUNQREZfTWF0cml4IG10ID0gdGhpcy0+R2V0Q3VyTWF0cml4KCk7CisJCW10LkNvbmNhdCgqcFVzZXIyRGV2aWNlKTsKKwkJcFduZC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwmbXQpOworCX0KKwllbHNlCisJeworCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopcEFubm90OworCQlpZiAoQ0ZGTF9JRm9ybUZpbGxlcjo6SXNWaXNpYmxlKHBXaWRnZXQpKQorCQkJcFdpZGdldC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpOb3JtYWwsIE5VTEwpOworCX0KK30KKwordm9pZCBDRkZMX0Zvcm1GaWxsZXI6Ok9uRHJhd0RlYWN0aXZlKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgLypIREMgaERDLCovIENQREZTREtfQW5ub3QqIHBBbm5vdCwgCisJCQkJCQlDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csKi8gRlhfRFdPUkQgZHdGbGFncykKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCQorCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7CisJCisJcFdpZGdldC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpOb3JtYWwsIE5VTEwpOworfQorCisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpPbkNyZWF0ZShDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpPbkxvYWQoQ1BERlNES19Bbm5vdCogcEFubm90KQoreworfQorCit2b2lkIENGRkxfRm9ybUZpbGxlcjo6T25EZWxldGUoQ1BERlNES19Bbm5vdCogcEFubm90KQoreworfQorCit2b2lkIENGRkxfRm9ybUZpbGxlcjo6T25Nb3VzZUVudGVyKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KQoreworfQorCit2b2lkIENGRkxfRm9ybUZpbGxlcjo6T25Nb3VzZUV4aXQoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJRW5kVGltZXIoKTsKKwlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworfQorCitGWF9CT09MIENGRkxfRm9ybUZpbGxlcjo6T25MQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCWlmIChDUFdMX1duZCAqIHBXbmQgPSBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBUUlVFKSkKKwl7CQkKKwkJbV9iVmFsaWQgPSBUUlVFOworCQlGWF9SRUNUIHJlY3QgPSB0aGlzLT5HZXRWaWV3QkJveChwUGFnZVZpZXcscEFubm90KTsKKwkJdGhpcy0+SW52YWxpZGF0ZVJlY3QocmVjdC5sZWZ0LCByZWN0LnRvcCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20pOworCisgCQlpZighcmVjdC5Db250YWlucygoaW50KXBvaW50LngsIChpbnQpcG9pbnQueSkpCisgIAkJCXJldHVybiBGQUxTRTsKKworCQlyZXR1cm4gcFduZC0+T25MQnV0dG9uRG93bihXbmR0b1BXTChwUGFnZVZpZXcsIHBvaW50KSxuRmxhZ3MpOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAlDRkZMX0Zvcm1GaWxsZXI6Ok9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CQorCQlGWF9SRUNUIHJjRkZMID0gIHRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KTsKKwkJdGhpcy0+SW52YWxpZGF0ZVJlY3QocmNGRkwubGVmdCwgcmNGRkwudG9wLCByY0ZGTC5yaWdodCwgcmNGRkwuYm90dG9tKTsKKwkJcFduZC0+T25MQnV0dG9uVXAoV25kdG9QV0wocFBhZ2VWaWV3LCBwb2ludCksbkZsYWdzKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6T25MQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CQkJCQorCQlwV25kLT5PbkxCdXR0b25EYmxDbGsoV25kdG9QV0wocFBhZ2VWaWV3LCBwb2ludCksbkZsYWdzKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENGRkxfRm9ybUZpbGxlcjo6T25Nb3VzZU1vdmUoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlpZiAoKG1fcHRPbGRQb3MueCAhPSBwb2ludC54KSB8fCAobV9wdE9sZFBvcy55ICE9IHBvaW50LnkpKQorCXsKKwkJbV9wdE9sZFBvcyA9IHBvaW50OworCX0KKworCWlmIChDUFdMX1duZCAqIHBXbmQgPSBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpCisJewkJCQkKKwkJcFduZC0+T25Nb3VzZU1vdmUoV25kdG9QV0wocFBhZ2VWaWV3LCBwb2ludCksbkZsYWdzKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENGRkxfRm9ybUZpbGxlcjo6T25Nb3VzZVdoZWVsKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlpZiAoIUlzVmFsaWQoKSkgcmV0dXJuIEZBTFNFOworCisJaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpKQorCXsJCQkJCisJCXJldHVybiBwV25kLT5Pbk1vdXNlV2hlZWwoekRlbHRhLCBXbmR0b1BXTChwUGFnZVZpZXcsIHBvaW50KSxuRmxhZ3MpOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDRkZMX0Zvcm1GaWxsZXI6Ok9uUkJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlpZiAoQ1BXTF9XbmQgKiBwV25kID0gR2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSkpCisJewkJCQkKKwkJcFduZC0+T25SQnV0dG9uRG93bihXbmR0b1BXTChwUGFnZVZpZXcsIHBvaW50KSxuRmxhZ3MpOworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9Gb3JtRmlsbGVyOjpPblJCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCWlmIChDUFdMX1duZCAqIHBXbmQgPSBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpCisJewkJCQkKKwkJcFduZC0+T25SQnV0dG9uVXAoV25kdG9QV0wocFBhZ2VWaWV3LCBwb2ludCksbkZsYWdzKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6T25SQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CQkJCQorCQlwV25kLT5PblJCdXR0b25EYmxDbGsoV25kdG9QV0wocFBhZ2VWaWV3LCBwb2ludCksbkZsYWdzKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENGRkxfRm9ybUZpbGxlcjo6T25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuS2V5Q29kZSwgRlhfVUlOVCBuRmxhZ3MpCit7CisJaWYgKElzVmFsaWQoKSkKKwl7CisJCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHRoaXMtPkdldEN1clBhZ2VWaWV3KCk7CisJCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7CisKKwkJaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwkJewkJCQkKKwkJCXJldHVybiBwV25kLT5PbktleURvd24obktleUNvZGUsbkZsYWdzKTsKKwkJfQorCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAlDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQoreworCWlmIChJc1ZhbGlkKCkpCisJeworCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSB0aGlzLT5HZXRDdXJQYWdlVmlldygpOworCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCisJCWlmIChDUFdMX1duZCAqIHBXbmQgPSBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpCisJCXsJCQkJCisJCQlyZXR1cm4gcFduZC0+T25DaGFyKG5DaGFyLG5GbGFncyk7CisJCX0KKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpPbkRlU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KQoreworCUFTU0VSVChGQUxTRSk7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpPblNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlBU1NFUlQoRkFMU0UpOworfQorCitGWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6T25TZXRGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWcpCit7CisJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsKKworCUNQREZfUGFnZSAqIHBQYWdlID0gcFdpZGdldC0+R2V0UERGUGFnZSgpOworIAlDUERGU0RLX0RvY3VtZW50ICogcERvYyA9IG1fcEFwcC0+R2V0Q3VycmVudERvYygpOworCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBEb2MtPkdldFBhZ2VWaWV3KHBQYWdlKTsKKyAJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKworIAkKKworCUNQV0xfV25kICogcFduZCA9IE5VTEw7CisJaWYgKCAocFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpKSkKKwl7CQkJCQorCQlwV25kLT5TZXRGb2N1cygpOworCX0KKworCW1fYlZhbGlkID0gVFJVRTsKKwkKKwkKKwkKKworCW1fYlZhbGlkID0gVFJVRTsKKwlGWF9SRUNUIHJjUmVjdCA9IHRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldyxwQW5ub3QpOworCXRoaXMtPkludmFsaWRhdGVSZWN0KHJjUmVjdC5sZWZ0LCByY1JlY3QudG9wLCByY1JlY3QucmlnaHQsIHJjUmVjdC5ib3R0b20pOworCQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6T25LaWxsRm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnKQoreworCWlmIChJc1ZhbGlkKCkpCisJeworCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSB0aGlzLT5HZXRDdXJQYWdlVmlldygpOworCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCisJCUNvbW1pdERhdGEocFBhZ2VWaWV3LCBuRmxhZyk7CisKKwkJaWYgKENQV0xfV25kKiBwV25kID0gR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCQl7CQkJCQorCQkJcFduZC0+S2lsbEZvY3VzKCk7CisJCX0KKwkJCisJCXN3aXRjaCAobV9wV2lkZ2V0LT5HZXRGaWVsZFR5cGUoKSkKKwkJeworCQljYXNlIEZJRUxEVFlQRV9QVVNIQlVUVE9OOgorCQljYXNlIEZJRUxEVFlQRV9DSEVDS0JPWDoKKwkJY2FzZSBGSUVMRFRZUEVfUkFESU9CVVRUT046CisJCQlFc2NhcGVGaWxsZXIocFBhZ2VWaWV3LCBUUlVFKTsKKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJRXNjYXBlRmlsbGVyKHBQYWdlVmlldywgRkFMU0UpOworCQkJYnJlYWs7CisJCX0KKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDRkZMX0Zvcm1GaWxsZXI6OklzVmFsaWQoKSBjb25zdAoreworCXJldHVybiBtX2JWYWxpZDsKK30KKworUFdMX0NSRUFURVBBUkFNCUNGRkxfRm9ybUZpbGxlcjo6R2V0Q3JlYXRlUGFyYW0oKQoreworCUFTU0VSVChtX3BBcHAgIT0gTlVMTCk7CisKKwlQV0xfQ1JFQVRFUEFSQU0gY3A7CisKKwljcC5wUGFyZW50V25kID0gTlVMTDsJCisJY3AucFByb3ZpZGVyID0gdGhpczsKKwljcC5yY1JlY3RXbmQgPSBHZXRQREZXaW5kb3dSZWN0KCk7CisJCisJRlhfRFdPUkQgZHdDcmVhdGVGbGFncyA9IFBXU19CT1JERVIgfCBQV1NfQkFDS0dST1VORCB8IFBXU19WSVNJQkxFOworCisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCisJRlhfRFdPUkQgZHdGaWVsZEZsYWcgPSBtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKTsKKworCWlmIChkd0ZpZWxkRmxhZyAmIEZJRUxERkxBR19SRUFET05MWSkKKwl7CQkKKwkJZHdDcmVhdGVGbGFncyB8PSBQV1NfUkVBRE9OTFk7CisJfQorCisJRlhfQ09MT1JSRUYgY29sb3I7CisJaWYgKG1fcFdpZGdldC0+R2V0RmlsbENvbG9yKGNvbG9yKSkKKwl7CisJCWNwLnNCYWNrZ3JvdW5kQ29sb3IgPSBDUFdMX0NvbG9yKEdldFJlZChjb2xvciksIEdldEdyZWVuKGNvbG9yKSwgR2V0Qmx1ZShjb2xvcikpOworCX0KKworCWlmIChtX3BXaWRnZXQtPkdldEJvcmRlckNvbG9yKGNvbG9yKSkKKwl7CisJCWNwLnNCb3JkZXJDb2xvciA9IENQV0xfQ29sb3IoR2V0UmVkKGNvbG9yKSwgR2V0R3JlZW4oY29sb3IpLCBHZXRCbHVlKGNvbG9yKSk7CisJfQorCisJY3Auc1RleHRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMCk7CisKKwlpZiAobV9wV2lkZ2V0LT5HZXRUZXh0Q29sb3IoY29sb3IpKQorCXsKKwkJY3Auc1RleHRDb2xvciA9IENQV0xfQ29sb3IoR2V0UmVkKGNvbG9yKSwgR2V0R3JlZW4oY29sb3IpLCBHZXRCbHVlKGNvbG9yKSk7CisJfQorCisJY3AuZkZvbnRTaXplID0gbV9wV2lkZ2V0LT5HZXRGb250U2l6ZSgpOworCWNwLmR3Qm9yZGVyV2lkdGggPSBtX3BXaWRnZXQtPkdldEJvcmRlcldpZHRoKCk7CisJCisJaW50IG5Cb3JkZXJTdHlsZSA9IG1fcFdpZGdldC0+R2V0Qm9yZGVyU3R5bGUoKTsKKworCXN3aXRjaCAobkJvcmRlclN0eWxlKQorCXsKKwljYXNlIEJCU19TT0xJRDoKKwkJY3AubkJvcmRlclN0eWxlID0gUEJTX1NPTElEOworCQlicmVhazsKKwljYXNlIEJCU19EQVNIOgorCQljcC5uQm9yZGVyU3R5bGUgPSBQQlNfREFTSDsKKwkJY3Auc0Rhc2ggPSBDUFdMX0Rhc2goMywzLDApOwkJCQorCQlicmVhazsKKwljYXNlIEJCU19CRVZFTEVEOgorCQljcC5uQm9yZGVyU3R5bGUgPSBQQlNfQkVWRUxFRDsKKwkJY3AuZHdCb3JkZXJXaWR0aCAqPSAyOworCQlicmVhazsKKwljYXNlIEJCU19JTlNFVDoKKwkJY3AubkJvcmRlclN0eWxlID0gUEJTX0lOU0VUOworCQljcC5kd0JvcmRlcldpZHRoICo9IDI7CisJCWJyZWFrOworCWNhc2UgQkJTX1VOREVSTElORToKKwkJY3AubkJvcmRlclN0eWxlID0gUEJTX1VOREVSTElORUQ7CisJCWJyZWFrOworCX0KKworCWlmIChjcC5mRm9udFNpemUgPD0gMCkKKwl7CisJCWR3Q3JlYXRlRmxhZ3MgfD0gUFdTX0FVVE9GT05UU0laRTsKKwl9CisKKwljcC5kd0ZsYWdzID0gZHdDcmVhdGVGbGFnczsKKwljcC5wU3lzdGVtSGFuZGxlciA9IG1fcEFwcC0+R2V0U3lzSGFuZGxlcigpOworCXJldHVybiBjcDsKK30KKworQ1BXTF9XbmQqIENGRkxfRm9ybUZpbGxlcjo6R2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiTmV3KQoreworCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7CisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCUNQV0xfV25kKiBwV25kID0gTlVMTDsKKwltX01hcHMuTG9va3VwKHBQYWdlVmlldywgcFduZCk7CisKKwlpZiAoYk5ldykKKwl7CisJCWlmIChwV25kKQorCQl7CisJCQlDRkZMX1ByaXZhdGVEYXRhKiBwUHJpdmF0ZURhdGEgPSAoQ0ZGTF9Qcml2YXRlRGF0YSopcFduZC0+R2V0QXR0YWNoZWREYXRhKCk7CisJCQlBU1NFUlQocFByaXZhdGVEYXRhICE9IE5VTEwpOworCisJCQlpZiAocFByaXZhdGVEYXRhLT5uV2lkZ2V0QWdlICE9IG1fcFdpZGdldC0+R2V0QXBwZWFyYW5jZUFnZSgpKQorCQkJeworCQkJCXJldHVybiB0aGlzLT5SZXNldFBERldpbmRvdyhwUGFnZVZpZXcsIG1fcFdpZGdldC0+R2V0VmFsdWVBZ2UoKSA9PSBwUHJpdmF0ZURhdGEtPm5WYWx1ZUFnZSk7CisJCQl9CisJCX0KKwkJZWxzZQorCQl7CisJCQlQV0xfQ1JFQVRFUEFSQU0gY3AgPSBHZXRDcmVhdGVQYXJhbSgpOworCQkJY3AuaEF0dGFjaGVkV25kID0gKEZYX0hXTkQpbV9wV2lkZ2V0OworCisJCQlDRkZMX1ByaXZhdGVEYXRhKiBwUHJpdmF0ZURhdGEgPSBuZXcgQ0ZGTF9Qcml2YXRlRGF0YTsKKwkJCXBQcml2YXRlRGF0YS0+cFdpZGdldCA9IG1fcFdpZGdldDsKKwkJCXBQcml2YXRlRGF0YS0+cFBhZ2VWaWV3ID0gcFBhZ2VWaWV3OworCQkJcFByaXZhdGVEYXRhLT5uV2lkZ2V0QWdlID0gbV9wV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICBwUHJpdmF0ZURhdGEtPm5WYWx1ZUFnZSA9IDA7CisKKwkJCWNwLnBBdHRhY2hlZERhdGEgPSBwUHJpdmF0ZURhdGE7CisKKwkJCXBXbmQgPSBOZXdQREZXaW5kb3coY3AsIHBQYWdlVmlldyk7CisKKwkJCWlmIChwV25kKQorCQkJeworCQkJCW1fTWFwcy5TZXRBdChwUGFnZVZpZXcsIHBXbmQpOworCQkJfQorCQl9CisJfQorCisJcmV0dXJuIHBXbmQ7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpEZXN0cm95UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKKwlDUFdMX1duZCogcFduZCA9IE5VTEw7CisJbV9NYXBzLkxvb2t1cChwUGFnZVZpZXcsIHBXbmQpOworCisJaWYgKHBXbmQpCisJeworCQlDRkZMX1ByaXZhdGVEYXRhKiBwRGF0YSA9IChDRkZMX1ByaXZhdGVEYXRhKilwV25kLT5HZXRBdHRhY2hlZERhdGEoKTsKKwkJcERhdGEtPnBQYWdlVmlldyA9IE5VTEw7CisJCXBXbmQtPkRlc3Ryb3koKTsKKwkJZGVsZXRlIHBXbmQ7CisJCWRlbGV0ZSBwRGF0YTsKKwl9CisKKwltX01hcHMuUmVtb3ZlS2V5KHBQYWdlVmlldyk7Cit9CisKK0NQREZfTWF0cml4CUNGRkxfRm9ybUZpbGxlcjo6R2V0V2luZG93TWF0cml4KHZvaWQqIHBBdHRhY2hlZERhdGEpCit7CisJaWYgKENGRkxfUHJpdmF0ZURhdGEqIHBQcml2YXRlRGF0YSA9IChDRkZMX1ByaXZhdGVEYXRhKilwQXR0YWNoZWREYXRhKQorCXsKKwkJaWYgKHBQcml2YXRlRGF0YS0+cFBhZ2VWaWV3KQorCQl7CisJCQlDUERGX01hdHJpeCBtdFBhZ2VWaWV3OworCQkJcFByaXZhdGVEYXRhLT5wUGFnZVZpZXctPkdldEN1cnJlbnRNYXRyaXgobXRQYWdlVmlldyk7CisJCQlDUERGX01hdHJpeCBtdCA9IEdldEN1ck1hdHJpeCgpOworCQkJbXQuQ29uY2F0KG10UGFnZVZpZXcpOworCQkJCisJCQlyZXR1cm4gbXQ7CisJCX0KKwl9CisJcmV0dXJuIENQREZfTWF0cml4KDEsMCwwLDEsMCwwKTsKK30KKworQ1BERl9NYXRyaXgJQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRDdXJNYXRyaXgoKQoreworCUNQREZfTWF0cml4IG10OworCisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCUNQREZfUmVjdCByY0RBIDsKKwltX3BXaWRnZXQtPkdldFBERkFubm90KCktPkdldFJlY3QocmNEQSk7CisKKworCXN3aXRjaCAobV9wV2lkZ2V0LT5HZXRSb3RhdGUoKSkKKwl7CisJZGVmYXVsdDoKKwljYXNlIDA6CQkKKwkJbXQgPSBDUERGX01hdHJpeCgxLDAsMCwxLDAsMCk7CisJCWJyZWFrOworCWNhc2UgOTA6CisJCW10ID0gQ1BERl9NYXRyaXgoMCwxLC0xLDAscmNEQS5yaWdodCAtIHJjREEubGVmdCwwKTsKKwkJYnJlYWs7CisJY2FzZSAxODA6CisJCW10ID0gQ1BERl9NYXRyaXgoLTEsMCwwLC0xLHJjREEucmlnaHQgLSByY0RBLmxlZnQscmNEQS50b3AgLSByY0RBLmJvdHRvbSk7CisJCWJyZWFrOworCWNhc2UgMjcwOgorCQltdCA9IENQREZfTWF0cml4KDAsLTEsMSwwLDAscmNEQS50b3AgLSByY0RBLmJvdHRvbSk7CisJCWJyZWFrOworCX0KKwltdC5lICs9IHJjREEubGVmdDsKKwltdC5mICs9IHJjREEuYm90dG9tOworCisJcmV0dXJuIG10OworfQorCitDRlhfV2lkZVN0cmluZyBDRkZMX0Zvcm1GaWxsZXI6OkxvYWRQb3B1cE1lbnVTdHJpbmcoaW50IG5JbmRleCkKK3sKKwlBU1NFUlQobV9wQXBwICE9IE5VTEwpOworCisJcmV0dXJuIEwiIjsKK30KKworQ1BERl9SZWN0IENGRkxfRm9ybUZpbGxlcjo6R2V0UERGV2luZG93UmVjdCgpIGNvbnN0Cit7CisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCUNQREZfUmVjdCByZWN0QW5ub3Q7CisJbV9wV2lkZ2V0LT5HZXRQREZBbm5vdCgpLT5HZXRSZWN0KHJlY3RBbm5vdCk7CisKKwlGWF9GTE9BVCBmV2lkdGggPSByZWN0QW5ub3QucmlnaHQgLSByZWN0QW5ub3QubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gcmVjdEFubm90LnRvcCAtIHJlY3RBbm5vdC5ib3R0b207CisKKworCWlmICgobV9wV2lkZ2V0LT5HZXRSb3RhdGUoKSAvIDkwKSAmIDB4MDEpCisJCXJldHVybiBDUERGX1JlY3QoMCwwLGZIZWlnaHQsZldpZHRoKTsKKwllbHNlCisJCXJldHVybiBDUERGX1JlY3QoMCwwLGZXaWR0aCxmSGVpZ2h0KTsKK30KKworQ1BERlNES19QYWdlVmlldyogQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRDdXJQYWdlVmlldygpCit7CisKKwlDUERGX1BhZ2UqIHBQYWdlID0gbV9wQW5ub3QtPkdldFBERlBhZ2UoKTsKKwlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gbV9wQXBwLT5HZXRDdXJyZW50RG9jKCk7CisJaWYocFNES0RvYykKKwl7CisJCXJldHVybiBwU0RLRG9jLT5HZXRQYWdlVmlldyhwUGFnZSk7CisJfQorCXJldHVybiBOVUxMOworfQorCitDUERGX1JlY3QgQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRGb2N1c0JveChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJaWYgKENQV0xfV25kICogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CQkJCisJCUNQREZfUmVjdCByY0ZvY3VzID0gIEZGTHRvV25kKHBQYWdlVmlldywgUFdMdG9GRkwocFduZC0+R2V0Rm9jdXNSZWN0KCkpKTsKKwkJQVNTRVJUKHBQYWdlVmlldyk7CisJCUNQREZfUmVjdCByY1BhZ2UgPSBwUGFnZVZpZXctPkdldFBERlBhZ2UoKS0+R2V0UGFnZUJCb3goKTsKKwkJaWYocmNQYWdlLkNvbnRhaW5zKHJjRm9jdXMpKQorCQkJcmV0dXJuIHJjRm9jdXM7CisJCWVsc2UKKwkJCXJldHVybiBDUERGX1JlY3QoMCwwLDAsMCk7CisJfQorCXJldHVybiBDUERGX1JlY3QoMCwwLDAsMCk7Cit9CisKK0NQREZfUmVjdCBDRkZMX0Zvcm1GaWxsZXI6OkZGTHRvUFdMKGNvbnN0IENQREZfUmVjdCYgcmVjdCkKK3sKKwlDUERGX01hdHJpeCBtdDsKKwltdC5TZXRSZXZlcnNlKEdldEN1ck1hdHJpeCgpKTsKKwkKKwlDUERGX1JlY3QgdGVtcCA9IHJlY3Q7CisJbXQuVHJhbnNmb3JtUmVjdCh0ZW1wKTsKKworCXJldHVybiB0ZW1wOworfQorCitDUERGX1JlY3QgQ0ZGTF9Gb3JtRmlsbGVyOjpQV0x0b0ZGTChjb25zdCBDUERGX1JlY3QmIHJlY3QpCit7CisJQ1BERl9NYXRyaXggbXQgPSBHZXRDdXJNYXRyaXgoKTsKKwkKKwlDUERGX1JlY3QgdGVtcCA9IHJlY3Q7CisJbXQuVHJhbnNmb3JtUmVjdCh0ZW1wKTsKKworCXJldHVybiB0ZW1wOworfQorCitDUERGX1BvaW50IENGRkxfRm9ybUZpbGxlcjo6RkZMdG9QV0woY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQ1BERl9NYXRyaXggbXQ7CisJbXQuU2V0UmV2ZXJzZShHZXRDdXJNYXRyaXgoKSk7CisKKwlDUERGX1BvaW50IHB0ID0gcG9pbnQ7CisJbXQuVHJhbnNmb3JtKHB0LngscHQueSk7CisKKwlyZXR1cm4gcHQ7Cit9CisKK0NQREZfUG9pbnQgQ0ZGTF9Gb3JtRmlsbGVyOjpQV0x0b0ZGTChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CisJQ1BERl9NYXRyaXggbXQgPSBHZXRDdXJNYXRyaXgoKTsKKworCUNQREZfUG9pbnQgcHQgPSBwb2ludDsKKwltdC5UcmFuc2Zvcm0ocHQueCxwdC55KTsKKworCXJldHVybiBwdDsKK30KKworQ1BERl9Qb2ludCBDRkZMX0Zvcm1GaWxsZXI6OlduZHRvUFdMKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgY29uc3QgQ1BERl9Qb2ludCYgcHQpCit7CisvLyAJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKy8vIAorLy8gCUNQREZfUG9pbnQgcG9pbnQoMC4wZiwgMC4wZik7CisvLyAJcFBhZ2VWaWV3LT5XaW5kb3dUb0RvYyhwdC54LCBwdC55LCBwb2ludC54LCBwb2ludC55KTsKKy8vIAorIAlyZXR1cm4gRkZMdG9QV0wocHQpOworLy8JcmV0dXJuIENQREZfUG9pbnQoMCwgMCk7Cit9CisKK0NQREZfUmVjdCBDRkZMX0Zvcm1GaWxsZXI6OkZGTHRvV25kKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkKK3sKKy8vIAlGWF9SRUNUIHJjUmV0KDAsMCwwLDApOworLy8gCisvLyAJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsJCisvLyAJcFBhZ2VWaWV3LT5Eb2NUb1dpbmRvdyhyZWN0LCByY1JldCk7CisvLyAJCisgCXJldHVybiByZWN0OworCit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpGRkxfRnJlZURhdGEodm9pZCogcERhdGEpCit7CisJQVNTRVJUKHBEYXRhICE9IE5VTEwpOworCisJZGVsZXRlIChDRkZMX1ByaXZhdGVEYXRhKilwRGF0YTsKK30KKworRlhfQk9PTCBDRkZMX0Zvcm1GaWxsZXI6OkNvbW1pdERhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9VSU5UIG5GbGFnKQoreworCWlmIChJc0RhdGFDaGFuZ2VkKHBQYWdlVmlldykpCisJeworCQkvL0NGRkxfSUZvcm1GaWxsZXIqIHBJRm9ybUZpbGxlciA9IENGRkxfTW9kdWxlOjpHZXRGb3JtRmlsbGVyKG1fcEFwcCk7CisJCUNGRkxfSUZvcm1GaWxsZXIqIHBJRm9ybUZpbGxlciA9IG1fcEFwcC0+R2V0SUZvcm1GaWxsZXIoKTsvL05VTEw7CisJCUFTU0VSVChwSUZvcm1GaWxsZXIgIT0gTlVMTCk7CisKKwkJRlhfQk9PTCBiUkMgPSBUUlVFOworCQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7CisKKwkJcElGb3JtRmlsbGVyLT5PbktleVN0cm9rZUNvbW1pdChtX3BXaWRnZXQsIHBQYWdlVmlldywgYlJDLCBiRXhpdCwgbkZsYWcpOworCQlpZiAoYkV4aXQpIHJldHVybiBUUlVFOworCQlpZiAoIWJSQykKKwkJeworCQkJdGhpcy0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSk7CisJCQlyZXR1cm4gVFJVRTsKKwkJfQorCisJCXBJRm9ybUZpbGxlci0+T25WYWxpZGF0ZShtX3BXaWRnZXQsIHBQYWdlVmlldywgYlJDLCBiRXhpdCwgbkZsYWcpOworCQlpZiAoYkV4aXQpIHJldHVybiBUUlVFOworCQlpZiAoIWJSQykKKwkJeworCQkJdGhpcy0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSk7CisJCQlyZXR1cm4gVFJVRTsKKwkJfQorCisJCVNhdmVEYXRhKHBQYWdlVmlldyk7CisKKwkJcElGb3JtRmlsbGVyLT5PbkNhbGN1bGF0ZShtX3BXaWRnZXQsIHBQYWdlVmlldywgYkV4aXQsbkZsYWcpOworCQlpZiAoYkV4aXQpIHJldHVybiBUUlVFOworCisJCXBJRm9ybUZpbGxlci0+T25Gb3JtYXQobV9wV2lkZ2V0LCBwUGFnZVZpZXcsIGJFeGl0LG5GbGFnKTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDRkZMX0Zvcm1GaWxsZXI6OklzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDRkZMX0Zvcm1GaWxsZXI6OlNhdmVEYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKK30KKwordm9pZCBDRkZMX0Zvcm1GaWxsZXI6OkdldEtleVN0cm9rZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGRkxfS2V5U3Ryb2tlRGF0YSYgZGF0YSkKK3sKK30KKwordm9pZCBDRkZMX0Zvcm1GaWxsZXI6OlNldENoYW5nZU1hcmsoKQoreworCW1fcEFwcC0+RkZJX09uQ2hhbmdlKCk7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLAorCQkJCQkJCVBERlNES19GaWVsZEFjdGlvbiYgZmEpCit7CisJZmEuc1ZhbHVlID0gbV9wV2lkZ2V0LT5HZXRWYWx1ZSgpOworfQorCit2b2lkIENGRkxfRm9ybUZpbGxlcjo6U2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgCisJCQkJCQkJCQljb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhKQoreworfQorCitGWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6SXNBY3Rpb25EYXRhQ2hhbmdlZChDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIGNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmFPbGQsIAorCQkJCQkJCQkJY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU5ldykKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpTYXZlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworfQorCit2b2lkIENGRkxfRm9ybUZpbGxlcjo6UmVzdG9yZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKK30KKworQ1BXTF9XbmQqICBDRkZMX0Zvcm1GaWxsZXI6OlJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKQoreworCXJldHVybiBHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSk7IAorfQorCit2b2lkIENGRkxfRm9ybUZpbGxlcjo6VGltZXJQcm9jKCkKK3sKKworfQorCitJRlhfU3lzdGVtSGFuZGxlciogQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRTeXN0ZW1IYW5kbGVyKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wQXBwLT5HZXRTeXNIYW5kbGVyKCk7CisvLwlyZXR1cm4gTlVMTDsKK30KKwordm9pZCBDRkZMX0Zvcm1GaWxsZXI6Ok9uS2V5U3Ryb2tlKEZYX0JPT0wgYktleURvd24pCit7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpFc2NhcGVGaWxsZXIoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MIGJEZXN0cm95UERGV2luZG93KQoreworCW1fYlZhbGlkID0gRkFMU0U7CisJCisJRlhfUkVDVCByY1JlY3QgPSB0aGlzLT5HZXRWaWV3QkJveChwUGFnZVZpZXcsIG1fcFdpZGdldCk7CisJdGhpcy0+SW52YWxpZGF0ZVJlY3QocmNSZWN0LmxlZnQsIHJjUmVjdC50b3AsIHJjUmVjdC5yaWdodCwgcmNSZWN0LmJvdHRvbSk7CisKKwlpZihiRGVzdHJveVBERldpbmRvdykKKyAJCURlc3Ryb3lQREZXaW5kb3cocFBhZ2VWaWV3KTsKK30KKworRlhfQk9PTCBDRkZMX0Zvcm1GaWxsZXI6OkNhbkNvcHkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDRkZMX0Zvcm1GaWxsZXI6OkNhbkN1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGRkxfRm9ybUZpbGxlcjo6Q2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDRkZMX0Zvcm1GaWxsZXI6OkRvQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpEb0N1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7Cit9CisKK3ZvaWQgQ0ZGTF9Gb3JtRmlsbGVyOjpEb1Bhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKK30KKwordm9pZCBDRkZMX0Zvcm1GaWxsZXI6OkludmFsaWRhdGVSZWN0KGRvdWJsZSBsZWZ0LCBkb3VibGUgdG9wLCBkb3VibGUgcmlnaHQsIGRvdWJsZSBib3R0b20pCit7CisJQ1BERl9QYWdlICogcFBhZ2UgPSBtX3BXaWRnZXQtPkdldFBERlBhZ2UoKTsKKwltX3BBcHAtPkZGSV9JbnZhbGlkYXRlKHBQYWdlLCBsZWZ0LCB0b3AsIHJpZ2h0LCBib3R0b20pOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGRkxfQnV0dG9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0ZGTF9CdXR0b246OkNGRkxfQnV0dG9uKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfQW5ub3QqIHBXaWRnZXQpIDoKKwlDRkZMX0Zvcm1GaWxsZXIocEFwcCwgcFdpZGdldCksCisJbV9iTW91c2VJbihGQUxTRSksCisJbV9iTW91c2VEb3duKEZBTFNFKQoreworfQorCitDRkZMX0J1dHRvbjo6fkNGRkxfQnV0dG9uKCkKK3sKK30KKwordm9pZCBDRkZMX0J1dHRvbjo6T25Nb3VzZUVudGVyKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KQoreworCW1fYk1vdXNlSW4gPSBUUlVFOworCUZYX1JFQ1QgcmVjdCA9IHRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldyxwQW5ub3QpOworCXRoaXMtPkludmFsaWRhdGVSZWN0KHJlY3QubGVmdCwgcmVjdC50b3AsIHJlY3QucmlnaHQsIHJlY3QuYm90dG9tKTsKKy8vCTo6SW52YWxpZGF0ZVJlY3QocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCAmdGhpcy0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBwQW5ub3QpLCBUUlVFKTsKK30KKwordm9pZCBDRkZMX0J1dHRvbjo6T25Nb3VzZUV4aXQoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJbV9iTW91c2VJbiA9IEZBTFNFOworCisJRlhfUkVDVCByZWN0ID0gdGhpcy0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LHBBbm5vdCk7CisJdGhpcy0+SW52YWxpZGF0ZVJlY3QocmVjdC5sZWZ0LCByZWN0LnRvcCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20pOworLy8JOjpJbnZhbGlkYXRlUmVjdChwUGFnZVZpZXctPkdldFBhZ2VWaWV3V25kKCksICZ0aGlzLT5HZXRWaWV3QkJveChwUGFnZVZpZXcsIHBBbm5vdCksIFRSVUUpOworCUVuZFRpbWVyKCk7CisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKy8vCW1fcFdpZGdldC0+SGlkZUhpbnQoKTsKK30KKworRlhfQk9PTCBDRkZMX0J1dHRvbjo6T25MQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUNQREZfUmVjdCByY0Fubm90ID0gcEFubm90LT5HZXRSZWN0KCk7CisJaWYoIXJjQW5ub3QuQ29udGFpbnMocG9pbnQueCwgcG9pbnQueSkpCisJCXJldHVybiBGQUxTRTsKKworCW1fYk1vdXNlRG93biA9IFRSVUU7CisJbV9iVmFsaWQgPSBUUlVFOworCUZYX1JFQ1QgcmVjdCA9IHRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KTsKKwl0aGlzLT5JbnZhbGlkYXRlUmVjdChyZWN0LmxlZnQsIHJlY3QudG9wLCByZWN0LnJpZ2h0LCByZWN0LmJvdHRvbSk7CisvLwk6OkludmFsaWRhdGVSZWN0KHBQYWdlVmlldy0+R2V0UGFnZVZpZXdXbmQoKSwgJnRoaXMtPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KSwgVFJVRSk7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9CdXR0b246Ok9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQ1BERl9SZWN0IHJjQW5ub3QgPSBwQW5ub3QtPkdldFJlY3QoKTsKKwlpZighcmNBbm5vdC5Db250YWlucyhwb2ludC54LCBwb2ludC55KSkKKwkJcmV0dXJuIEZBTFNFOworCisJbV9iTW91c2VEb3duID0gRkFMU0U7CisJbV9wV2lkZ2V0LT5HZXRQREZQYWdlKCk7CisJCisKKwlGWF9SRUNUIHJlY3QgPSB0aGlzLT5HZXRWaWV3QkJveChwUGFnZVZpZXcsIHBBbm5vdCk7CisJdGhpcy0+SW52YWxpZGF0ZVJlY3QocmVjdC5sZWZ0LCByZWN0LnRvcCwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20pOworLy8gCTo6SW52YWxpZGF0ZVJlY3QocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCAmdGhpcy0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBwQW5ub3QpLCBUUlVFKTsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDRkZMX0J1dHRvbjo6T25Nb3VzZU1vdmUoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQobV9wQXBwICE9IE5VTEwpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ0ZGTF9CdXR0b246Ok9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIAorCQkJCQkJCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkJLypjb25zdCBDUmVjdCYgcmNXaW5kb3csKi8gRlhfRFdPUkQgZHdGbGFncykKK3sKKwlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisKKwlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopcEFubm90OworCisJQ1BERl9Gb3JtQ29udHJvbCogcEN0cmwgPSBwV2lkZ2V0LT5HZXRGb3JtQ29udHJvbCgpOworCUFTU0VSVChwQ3RybCAhPSBOVUxMKTsKKworCUNQREZfRm9ybUNvbnRyb2w6OkhpZ2hsaWdodGluZ01vZGUgZUhNID0gcEN0cmwtPkdldEhpZ2hsaWdodGluZ01vZGUoKTsKKworCWlmIChlSE0gPT0gQ1BERl9Gb3JtQ29udHJvbDo6UHVzaCkKKwl7CisJCWlmIChtX2JNb3VzZURvd24pCisJCXsKKwkJCWlmIChwV2lkZ2V0LT5Jc1dpZGdldEFwcGVhcmFuY2VWYWxpZChDUERGX0Fubm90OjpEb3duKSkKKwkJCQlwV2lkZ2V0LT5EcmF3QXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIENQREZfQW5ub3Q6OkRvd24sIE5VTEwpOworCQkJZWxzZQorCQkJCXBXaWRnZXQtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsKKwkJfQorCQllbHNlIGlmIChtX2JNb3VzZUluKQorCQl7CisJCQlpZiAocFdpZGdldC0+SXNXaWRnZXRBcHBlYXJhbmNlVmFsaWQoQ1BERl9Bbm5vdDo6Um9sbG92ZXIpKQorCQkJCXBXaWRnZXQtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Um9sbG92ZXIsIE5VTEwpOworCQkJZWxzZQorCQkJCXBXaWRnZXQtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCXBXaWRnZXQtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsKKwkJfQorCX0KKwllbHNlCisJCXBXaWRnZXQtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsKK30KKworCit2b2lkIENGRkxfQnV0dG9uOjpPbkRyYXdEZWFjdGl2ZShDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIC8qSERDIGhEQywqLyBDUERGU0RLX0Fubm90KiBwQW5ub3QsIAorCQkJCQkJCQkgQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQkJIC8qY29uc3QgQ1JlY3QmIHJjV2luZG93LCAqL0ZYX0RXT1JEIGR3RmxhZ3MpCit7CisJT25EcmF3KHBQYWdlVmlldywgcEFubm90LCBwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIGR3RmxhZ3MpOworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfSUZvcm1GaWxsZXIuY3BwIGIvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfSUZvcm1GaWxsZXIuY3BwCmluZGV4IDY4NmIzOGMuLjJiMjFlMTMgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX0lGb3JtRmlsbGVyLmNwcAorKysgYi9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9JRm9ybUZpbGxlci5jcHAKQEAgLTEsMTE5NyArMSwxMTk3IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfSUZvcm1GaWxsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9DaGVja0JveC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NvbWJvQm94LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTGlzdEJveC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1B1c2hCdXR0b24uaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9SYWRpb0J1dHRvbi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1RleHRGaWVsZC5oIg0KLQ0KLSNkZWZpbmUgRkZMX01BWExJU1RCT1hIRUlHSFQJCTE0MC4wZg0KLQ0KLS8vIEhIT09LIENGRkxfSUZvcm1GaWxsZXI6Om1faG9va1NoZWV0ID0gTlVMTDsNCi0vLyBNU0cgQ0ZGTF9JRm9ybUZpbGxlcjo6Z19Nc2c7DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZGTF9JRm9ybUZpbGxlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGRkxfSUZvcm1GaWxsZXI6OkNGRkxfSUZvcm1GaWxsZXIoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCkgOiANCi0JbV9wQXBwKHBBcHApLA0KLQltX2JOb3RpZnlpbmcoRkFMU0UpDQotew0KLX0NCi0NCi1DRkZMX0lGb3JtRmlsbGVyOjp+Q0ZGTF9JRm9ybUZpbGxlcigpDQotew0KLQlGWF9QT1NJVElPTiBwb3MgPSBtX01hcHMuR2V0U3RhcnRQb3NpdGlvbigpOw0KLQl3aGlsZSAocG9zKQ0KLQl7DQotCQlDUERGU0RLX0Fubm90ICogcEFubm90ID0gTlVMTDsNCi0JCUNGRkxfRm9ybUZpbGxlciAqIHBGb3JtRmlsbGVyID0gTlVMTDsNCi0JCW1fTWFwcy5HZXROZXh0QXNzb2MocG9zLHBBbm5vdCxwRm9ybUZpbGxlcik7DQotCQlkZWxldGUgcEZvcm1GaWxsZXI7DQotCX0NCi0JbV9NYXBzLlJlbW92ZUFsbCgpOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OkFubm90X0hpdFRlc3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LENQREZTREtfQW5ub3QqIHBBbm5vdCwgQ1BERl9Qb2ludCBwb2ludCkNCi17DQotCUNQREZfUmVjdCByYyA9IHBBbm5vdC0+R2V0UmVjdCgpOw0KLQlpZihyYy5Db250YWlucyhwb2ludC54LCBwb2ludC55KSkNCi0JCXJldHVybiBUUlVFOw0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX1JFQ1QgQ0ZGTF9JRm9ybUZpbGxlcjo6R2V0Vmlld0JCb3goQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpDQotCXsNCi0JCXJldHVybiBwRm9ybUZpbGxlci0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBwQW5ub3QpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0JCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotDQotCQlDUERGX0Fubm90KiBwUERGQW5ub3QgPSBwQW5ub3QtPkdldFBERkFubm90KCk7DQotCQlBU1NFUlQocFBERkFubm90ICE9IE5VTEwpOw0KLQ0KLQkJQ1BERl9SZWN0IHJjQW5ub3Q7DQotCQlwUERGQW5ub3QtPkdldFJlY3QocmNBbm5vdCk7DQotDQotLy8gCQlDUmVjdCByY1dpbjsNCi0vLyAJCXBQYWdlVmlldy0+RG9jVG9XaW5kb3cocmNBbm5vdCwgcmNXaW4pOw0KLQkJQ1BERl9SZWN0IHJjV2luID0gQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QocmNBbm5vdCwxKTsNCi0vLwkJcmNXaW4uSW5mbGF0ZVJlY3QoMSwgMSk7DQotDQotCQlyZXR1cm4gcmNXaW4uR2V0T3V0dGVyUmVjdCgpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6T25EcmF3KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgLypIREMgaERDLCovIENQREZTREtfQW5ub3QqIHBBbm5vdCwgDQotCQkJCQkJQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCQkJCQkvKmNvbnN0IENSZWN0JiByY1dpbmRvdywqLyBGWF9EV09SRCBkd0ZsYWdzKQ0KLXsNCi0JQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0JQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsNCi0NCi0JaWYgKElzVmlzaWJsZShwV2lkZ2V0KSkNCi0Jew0KLQkJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQ0KLQkJew0KLSAJCQlpZiAocEZvcm1GaWxsZXItPklzVmFsaWQoKSkNCi0gCQkJew0KLQkJCQlwRm9ybUZpbGxlci0+T25EcmF3KHBQYWdlVmlldywgcEFubm90LCBwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIGR3RmxhZ3MpOw0KLQkJCQkNCi0JCQkJcEFubm90LT5HZXRQREZQYWdlKCk7DQotCQkJCQ0KLQ0KLQkJCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBtX3BBcHAtPkdldEN1cnJlbnREb2MoKTsNCi0JCQkJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JCQkJaWYgKHBEb2N1bWVudC0+R2V0Rm9jdXNBbm5vdCgpID09IHBBbm5vdCkNCi0JCQkJew0KLQkJCQkJQ1BERl9SZWN0IHJjRm9jdXMgPSBwRm9ybUZpbGxlci0+R2V0Rm9jdXNCb3gocFBhZ2VWaWV3KTsNCi0JCQkJCWlmICghcmNGb2N1cy5Jc0VtcHR5KCkpDQotCQkJCQl7DQotCQkJCQkJQ0ZYX1BhdGhEYXRhIHBhdGg7DQotCQkJCQkJDQotCQkJCQkJcGF0aC5TZXRQb2ludENvdW50KDUpOw0KLQkJCQkJCXBhdGguU2V0UG9pbnQoMCwgcmNGb2N1cy5sZWZ0LCAgcmNGb2N1cy50b3AsIEZYUFRfTU9WRVRPKTsNCi0JCQkJCQlwYXRoLlNldFBvaW50KDEsIHJjRm9jdXMubGVmdCwgIHJjRm9jdXMuYm90dG9tLCBGWFBUX0xJTkVUTyk7DQotCQkJCQkJcGF0aC5TZXRQb2ludCgyLCByY0ZvY3VzLnJpZ2h0LCAgcmNGb2N1cy5ib3R0b20sIEZYUFRfTElORVRPKTsNCi0JCQkJCQlwYXRoLlNldFBvaW50KDMsIHJjRm9jdXMucmlnaHQsICByY0ZvY3VzLnRvcCwgRlhQVF9MSU5FVE8pOw0KLQkJCQkJCXBhdGguU2V0UG9pbnQoNCwgcmNGb2N1cy5sZWZ0LCAgcmNGb2N1cy50b3AsIEZYUFRfTElORVRPKTsNCi0JCQkJCQkNCi0JCQkJCQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOw0KLQkJCQkJCWdzZC5TZXREYXNoQ291bnQoMSk7CQkJCQ0KLQkJCQkJCWdzZC5tX0Rhc2hBcnJheVswXSA9IDEuMGY7DQotCQkJCQkJZ3NkLm1fRGFzaFBoYXNlID0gMDsJDQotCQkJCQkJDQotCQkJCQkJZ3NkLm1fTGluZVdpZHRoID0gMS4wZjsNCi0JCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLCBBcmdiRW5jb2RlKDI1NSwwLDAsMCksIEZYRklMTF9BTFRFUk5BVEUpOw0KLQ0KLQkJCQkJLy8JOjpEcmF3Rm9jdXNSZWN0KGhEQywgJnJjRm9jdXMpOwkNCi0JCQkJCX0NCi0JCQkJfQ0KLQ0KLQkJCQlyZXR1cm47DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQ0KLQkJCXBGb3JtRmlsbGVyLT5PbkRyYXdEZWFjdGl2ZShwUGFnZVZpZXcsIHBBbm5vdCwgcERldmljZSwgcFVzZXIyRGV2aWNlLCBkd0ZsYWdzKTsNCi0JCWVsc2UNCi0JCQlwV2lkZ2V0LT5EcmF3QXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIENQREZfQW5ub3Q6Ok5vcm1hbCwgTlVMTCk7DQotDQotCQlpZiAoIUlzUmVhZE9ubHkocFdpZGdldCkgJiYgSXNGaWxsaW5nQWxsb3dlZChwV2lkZ2V0KSkNCi0JCXsNCi0JCQlwV2lkZ2V0LT5EcmF3U2hhZG93KHBEZXZpY2UsIHBQYWdlVmlldyk7DQotCQl9DQotCQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6T25DcmVhdGUoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQ0KLQl7DQotCQlwRm9ybUZpbGxlci0+T25DcmVhdGUocEFubm90KTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uTG9hZChDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpDQotCXsNCi0JCXBGb3JtRmlsbGVyLT5PbkxvYWQocEFubm90KTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uRGVsZXRlKENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkNCi0Jew0KLQkJcEZvcm1GaWxsZXItPk9uRGVsZXRlKHBBbm5vdCk7DQotCX0NCi0NCi0JVW5SZWdpc3RlckZvcm1GaWxsZXIocEFubm90KTsNCi19DQotDQotdm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpPbk1vdXNlRW50ZXIoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWcpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOw0KLQkNCi0JaWYgKCFtX2JOb3RpZnlpbmcpDQotCXsNCi0JCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7DQotCQlpZiAocFdpZGdldC0+R2V0QUFjdGlvbihDUERGX0FBY3Rpb246OkN1cnNvckVudGVyKSkNCi0JCXsNCi0JCQltX2JOb3RpZnlpbmcgPSBUUlVFOw0KLQkJCQ0KLQkJCWludCBuVmFsdWVBZ2UgPSBwV2lkZ2V0LT5HZXRWYWx1ZUFnZSgpOw0KLQ0KLQkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsNCi0JCQkNCi0JCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQkJCQ0KLQkJCQ0KLQkJCQ0KLQkJCVBERlNES19GaWVsZEFjdGlvbiBmYTsNCi0JCQlmYS5iTW9kaWZpZXIgPSBtX3BBcHAtPkZGSV9Jc0NUUkxLZXlEb3duKG5GbGFnKTsNCi0gCQkJZmEuYlNoaWZ0ID0gbV9wQXBwLT5GRklfSXNTSElGVEtleURvd24obkZsYWcpOw0KLQkJCXBXaWRnZXQtPk9uQUFjdGlvbihDUERGX0FBY3Rpb246OkN1cnNvckVudGVyLCBmYSwgcFBhZ2VWaWV3ICk7DQotCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotCQkJDQotCQkJLy9pZiAoICFJc1ZhbGlkQW5ub3QocFBhZ2VWaWV3LCBwQW5ub3QpICkgcmV0dXJuOw0KLQkJCQ0KLQkJCWlmIChwV2lkZ2V0LT5Jc0FwcE1vZGlmaWVkKCkpDQotCQkJew0KLQkJCQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocFdpZGdldCwgRkFMU0UpKQ0KLQkJCQl7DQotCQkJCQlwRm9ybUZpbGxlci0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBwV2lkZ2V0LT5HZXRWYWx1ZUFnZSgpID09IG5WYWx1ZUFnZSk7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0JDQotCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIFRSVUUpKQ0KLQl7DQotCQlwRm9ybUZpbGxlci0+T25Nb3VzZUVudGVyKHBQYWdlVmlldywgcEFubm90KTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uTW91c2VFeGl0KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnKQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsNCi0JDQotCWlmICghbV9iTm90aWZ5aW5nKQ0KLQl7DQotCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopcEFubm90Ow0KLQkJaWYgKHBXaWRnZXQtPkdldEFBY3Rpb24oQ1BERl9BQWN0aW9uOjpDdXJzb3JFeGl0KSkNCi0JCXsNCi0JCQltX2JOb3RpZnlpbmcgPSBUUlVFOw0KLQkJCXBXaWRnZXQtPkdldEFwcGVhcmFuY2VBZ2UoKTsNCi0JCQlpbnQgblZhbHVlQWdlID0gcFdpZGdldC0+R2V0VmFsdWVBZ2UoKTsNCi0JCQlwV2lkZ2V0LT5DbGVhckFwcE1vZGlmaWVkKCk7DQotCQkJDQotCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0JCQkNCi0JCQkNCi0JCQkNCi0JCQlQREZTREtfRmllbGRBY3Rpb24gZmE7DQotCQkJZmEuYk1vZGlmaWVyID0gbV9wQXBwLT5GRklfSXNDVFJMS2V5RG93bihuRmxhZyk7DQotIAkJCWZhLmJTaGlmdCA9IG1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKTsNCi0JCQkNCi0JCQlwV2lkZ2V0LT5PbkFBY3Rpb24oQ1BERl9BQWN0aW9uOjpDdXJzb3JFeGl0LCBmYSwgcFBhZ2VWaWV3KTsNCi0JCQltX2JOb3RpZnlpbmcgPSBGQUxTRTsNCi0JCQkNCi0JCQkvL2lmICghSXNWYWxpZEFubm90KHBQYWdlVmlldywgcEFubm90KSkgcmV0dXJuOw0KLQkJCQ0KLQkJCWlmIChwV2lkZ2V0LT5Jc0FwcE1vZGlmaWVkKCkpDQotCQkJew0KLQkJCQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocFdpZGdldCwgRkFMU0UpKQ0KLQkJCQl7DQotCQkJCQlwRm9ybUZpbGxlci0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBuVmFsdWVBZ2UgPT0gcFdpZGdldC0+R2V0VmFsdWVBZ2UoKSk7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0JDQotCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkNCi0Jew0KLQkJcEZvcm1GaWxsZXItPk9uTW91c2VFeGl0KHBQYWdlVmlldywgcEFubm90KTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6Ok9uTEJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7DQotCQ0KLQlpZiAoIW1fYk5vdGlmeWluZykNCi0Jew0KLQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsNCi0JCWlmIChBbm5vdF9IaXRUZXN0KHBQYWdlVmlldywgcEFubm90LCBwb2ludCkgJiYgcFdpZGdldC0+R2V0QUFjdGlvbihDUERGX0FBY3Rpb246OkJ1dHRvbkRvd24pKQ0KLQkJew0KLQkJCW1fYk5vdGlmeWluZyA9IFRSVUU7DQotCQkJcFdpZGdldC0+R2V0QXBwZWFyYW5jZUFnZSgpOw0KLQkJCWludCBuVmFsdWVBZ2UgPSBwV2lkZ2V0LT5HZXRWYWx1ZUFnZSgpOw0KLQkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsNCi0JCQkNCi0JCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQkJCQ0KLQkJCQ0KLQkJCQ0KLQkJCVBERlNES19GaWVsZEFjdGlvbiBmYTsNCi0JCQlmYS5iTW9kaWZpZXIgPSBtX3BBcHAtPkZGSV9Jc0NUUkxLZXlEb3duKG5GbGFncyk7DQotIAkJCWZhLmJTaGlmdCA9IG1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFncyk7DQotCQkJcFdpZGdldC0+T25BQWN0aW9uKENQREZfQUFjdGlvbjo6QnV0dG9uRG93biwgZmEsIHBQYWdlVmlldyk7DQotCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotCQkJDQotCQkJaWYgKCFJc1ZhbGlkQW5ub3QocFBhZ2VWaWV3LCBwQW5ub3QpKSByZXR1cm4gVFJVRTsNCi0JCQkNCi0JCQlpZiAocFdpZGdldC0+SXNBcHBNb2RpZmllZCgpKQ0KLQkJCXsNCi0JCQkJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBXaWRnZXQsIEZBTFNFKSkNCi0JCQkJew0KLQkJCQkJcEZvcm1GaWxsZXItPlJlc2V0UERGV2luZG93KHBQYWdlVmlldywgblZhbHVlQWdlID09IHBXaWRnZXQtPkdldFZhbHVlQWdlKCkpOw0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotCQ0KLQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpDQotCXsNCi0JCXJldHVybiBwRm9ybUZpbGxlci0+T25MQnV0dG9uRG93bihwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpPbkxCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsNCi0JDQotCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7DQotCS8vIAlDUmVhZGVyX1BhZ2UqIHBQYWdlID0gcEFubm90LT5HZXRQYWdlKCk7DQotCS8vIAlBU1NFUlQocFBhZ2UgIT0gTlVMTCk7DQotCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCA9IG1fcEFwcC0+R2V0Q3VycmVudERvYygpOw0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOwkJDQotCQ0KLQlzd2l0Y2ggKHBXaWRnZXQtPkdldEZpZWxkVHlwZSgpKQ0KLQl7DQotCWNhc2UgRklFTERUWVBFX1BVU0hCVVRUT046DQotCWNhc2UgRklFTERUWVBFX0NIRUNLQk9YOg0KLQljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoNCi0JCWlmIChHZXRWaWV3QkJveChwUGFnZVZpZXcsIHBBbm5vdCkuQ29udGFpbnMoKGludClwb2ludC54LCAoaW50KXBvaW50LnkpKQ0KLQkJew0KLQkJCXBEb2N1bWVudC0+U2V0Rm9jdXNBbm5vdChwQW5ub3QpOw0KLQkJfQ0KLQkJYnJlYWs7DQotCWRlZmF1bHQ6DQotCQlwRG9jdW1lbnQtPlNldEZvY3VzQW5ub3QocEFubm90KTsNCi0JCWJyZWFrOw0KLQl9DQotCQ0KLQlGWF9CT09MIGJSZXQgPSBGQUxTRTsNCi0JDQotCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkNCi0Jew0KLQkJYlJldCA9IHBGb3JtRmlsbGVyLT5PbkxCdXR0b25VcChwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7DQotCX0NCi0NCi0JaWYgKHBEb2N1bWVudC0+R2V0Rm9jdXNBbm5vdCgpID09IHBBbm5vdCkNCi0Jew0KLQkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOw0KLQkJRlhfQk9PTCBiUmVzZXQgPSBGQUxTRTsNCi0JCU9uQnV0dG9uVXAocFdpZGdldCwgcFBhZ2VWaWV3LCBiUmVzZXQsIGJFeGl0LG5GbGFncyk7DQotCQlpZiAoYkV4aXQpIHJldHVybiBUUlVFOw0KLQl9DQotCXJldHVybiBiUmV0Ow0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uQnV0dG9uVXAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYlJlc2V0LCBGWF9CT09MJiBiRXhpdCxGWF9VSU5UIG5GbGFnKQ0KLXsNCi0JQVNTRVJUKHBXaWRnZXQgIT0gTlVMTCk7DQotCQ0KLQlpZiAoIW1fYk5vdGlmeWluZykNCi0Jew0KLQkJaWYgKHBXaWRnZXQtPkdldEFBY3Rpb24oQ1BERl9BQWN0aW9uOjpCdXR0b25VcCkpDQotCQl7DQotCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsNCi0JCQlpbnQgbkFnZSA9IHBXaWRnZXQtPkdldEFwcGVhcmFuY2VBZ2UoKTsNCi0JCQlpbnQgblZhbHVlQWdlID0gcFdpZGdldC0+R2V0VmFsdWVBZ2UoKTsNCi0JCQkNCi0JCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLS8vIAkJCUNSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcgPSBwUGFnZVZpZXctPkdldERvY1ZpZXcoKTsNCi0vLyAJCQlBU1NFUlQocERvY1ZpZXcgIT0gTlVMTCk7DQotCQkJDQotCQkJDQotCQkJDQotCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhOw0KLQkJCWZhLmJNb2RpZmllciA9IG1fcEFwcC0+RkZJX0lzQ1RSTEtleURvd24obkZsYWcpOw0KLSAJCQlmYS5iU2hpZnQgPSBtX3BBcHAtPkZGSV9Jc1NISUZUS2V5RG93bihuRmxhZyk7DQotDQotCQkJcFdpZGdldC0+T25BQWN0aW9uKENQREZfQUFjdGlvbjo6QnV0dG9uVXAsIGZhLCBwUGFnZVZpZXcpOw0KLQkJCW1fYk5vdGlmeWluZyA9IEZBTFNFOw0KLQkJCQ0KLQkJCWlmICghSXNWYWxpZEFubm90KHBQYWdlVmlldywgcFdpZGdldCkpDQotCQkJew0KLQkJCQliRXhpdCA9IFRSVUU7DQotCQkJCXJldHVybjsNCi0JCQl9DQotCQkJDQotCQkJaWYgKG5BZ2UgIT0gcFdpZGdldC0+R2V0QXBwZWFyYW5jZUFnZSgpKQ0KLQkJCXsNCi0JCQkJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBXaWRnZXQsIEZBTFNFKSkNCi0JCQkJew0KLQkJCQkJcEZvcm1GaWxsZXItPlJlc2V0UERGV2luZG93KHBQYWdlVmlldywgblZhbHVlQWdlID09IHBXaWRnZXQtPkdldFZhbHVlQWdlKCkpOw0KLQkJCQl9DQotCQkJCQ0KLQkJCQliUmVzZXQgPSBUUlVFOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6Ok9uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsNCi0NCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQ0KLQl7DQotCQlyZXR1cm4gcEZvcm1GaWxsZXItPk9uTEJ1dHRvbkRibENsayhwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6Ok9uTW91c2VNb3ZlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOw0KLQ0KLQkvL2NoYW5nZSBjdXJzb3INCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgVFJVRSkpDQotCXsNCi0JCXJldHVybiBwRm9ybUZpbGxlci0+T25Nb3VzZU1vdmUocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpPbk1vdXNlV2hlZWwoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsNCi0NCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQ0KLQl7DQotCQlyZXR1cm4gcEZvcm1GaWxsZXItPk9uTW91c2VXaGVlbChwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCB6RGVsdGEsIHBvaW50KTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6T25SQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsNCi0NCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQ0KLQl7DQotCQlyZXR1cm4gcEZvcm1GaWxsZXItPk9uUkJ1dHRvbkRvd24ocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpPblJCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsNCi0NCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQ0KLQl7DQotCQlyZXR1cm4gcEZvcm1GaWxsZXItPk9uUkJ1dHRvblVwKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6T25SQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOw0KLQ0KLQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpDQotCXsNCi0JCXJldHVybiBwRm9ybUZpbGxlci0+T25SQnV0dG9uRGJsQ2xrKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6T25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuS2V5Q29kZSwgRlhfVUlOVCBuRmxhZ3MpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOw0KLQ0KLQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpDQotCXsNCi0JCXJldHVybiBwRm9ybUZpbGxlci0+T25LZXlEb3duKHBBbm5vdCwgbktleUNvZGUsIG5GbGFncyk7CQ0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncykNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7DQotDQotCWlmIChuQ2hhciA9PSBGV0xfVktFWV9UYWIpIHJldHVybiBUUlVFOw0KLQ0KLQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpDQotCXsNCi0JCXJldHVybiBwRm9ybUZpbGxlci0+T25DaGFyKHBBbm5vdCwgbkNoYXIsIG5GbGFncyk7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uRGVTZWxlY3RlZChDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOw0KLQ0KLQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpDQotCXsNCi0JCXBGb3JtRmlsbGVyLT5PbkRlU2VsZWN0ZWQocEFubm90KTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsNCi0NCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQ0KLQl7DQotCQlwRm9ybUZpbGxlci0+T25TZWxlY3RlZChwQW5ub3QpOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9JRm9ybUZpbGxlcjo6T25TZXRGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsRlhfVUlOVCBuRmxhZykNCi17DQotCWlmKCFwQW5ub3QpIHJldHVybiBGQUxTRTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsNCi0NCi0JaWYgKCFtX2JOb3RpZnlpbmcpDQotCXsNCi0JCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7DQotIAkJaWYgKHBXaWRnZXQtPkdldEFBY3Rpb24oQ1BERl9BQWN0aW9uOjpHZXRGb2N1cykpDQotIAkJew0KLSAgCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsNCi0JCQlwV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCk7DQotCQkJaW50IG5WYWx1ZUFnZSA9IHBXaWRnZXQtPkdldFZhbHVlQWdlKCk7DQotIAkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsNCi0gDQotIA0KLSAJCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwQW5ub3QtPkdldFBhZ2VWaWV3KCk7DQotIAkJCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotIAkJCQ0KLSAJCQlQREZTREtfRmllbGRBY3Rpb24gZmE7DQotCQkJZmEuYk1vZGlmaWVyID0gbV9wQXBwLT5GRklfSXNDVFJMS2V5RG93bihuRmxhZyk7DQotIAkJCWZhLmJTaGlmdCA9IG1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKTsNCi0NCi0gDQotIAkJCUNGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBXaWRnZXQsIFRSVUUpOw0KLSAJCQlpZighcEZvcm1GaWxsZXIpIHJldHVybiBGQUxTRTsNCi0gCQkJcEZvcm1GaWxsZXItPkdldEFjdGlvbkRhdGEocFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OkdldEZvY3VzLCBmYSk7DQotIA0KLSAJCQlwV2lkZ2V0LT5PbkFBY3Rpb24oQ1BERl9BQWN0aW9uOjpHZXRGb2N1cywgZmEsIHBQYWdlVmlldyk7DQotIAkJCW1fYk5vdGlmeWluZyA9IEZBTFNFOw0KLSAJCQkNCi0gLy8JCQlpZiAoIUlzVmFsaWRBbm5vdChtX3BBcHAsIHBEb2N1bWVudCwgcERvY1ZpZXcsIHBQYWdlVmlldywgcEFubm90KSkgcmV0dXJuIEZBTFNFOw0KLSANCi0gCQkJaWYgKHBXaWRnZXQtPklzQXBwTW9kaWZpZWQoKSkNCi0gCQkJew0KLSAJCQkJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBXaWRnZXQsIEZBTFNFKSkNCi0gCQkJCXsNCi0gCQkJCQlwRm9ybUZpbGxlci0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBuVmFsdWVBZ2UgPT0gcFdpZGdldC0+R2V0VmFsdWVBZ2UoKSk7DQotIAkJCQl9DQotIAkJCX0NCi0JCX0NCi0JfQ0KLQkNCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgVFJVRSkpDQotCXsNCi0JCWlmIChwRm9ybUZpbGxlci0+T25TZXRGb2N1cyhwQW5ub3QsIG5GbGFnKSkNCi0JCXsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JCWVsc2UNCi0JCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6T25LaWxsRm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LEZYX1VJTlQgbkZsYWcpDQotew0KLQlpZighcEFubm90KSByZXR1cm4gRkFMU0U7DQotCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7DQotDQotCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkNCi0Jew0KLQkJaWYgKHBGb3JtRmlsbGVyLT5PbktpbGxGb2N1cyhwQW5ub3QsIG5GbGFnKSkNCi0JCXsNCi0gCQkJaWYgKCFtX2JOb3RpZnlpbmcpDQotIAkJCXsNCi0gCQkJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7DQotIAkJCQlpZiAocFdpZGdldC0+R2V0QUFjdGlvbihDUERGX0FBY3Rpb246Okxvc2VGb2N1cykpDQotIAkJCQl7DQotIAkJCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsNCi0gCQkJCQlwV2lkZ2V0LT5DbGVhckFwcE1vZGlmaWVkKCk7DQotIA0KLSAJCQkJCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBXaWRnZXQtPkdldFBhZ2VWaWV3KCk7DQotIAkJCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0gDQotIAkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhOw0KLQkJCQkJZmEuYk1vZGlmaWVyID0gbV9wQXBwLT5GRklfSXNDVFJMS2V5RG93bihuRmxhZyk7DQotIAkJCQkJZmEuYlNoaWZ0ID0gbV9wQXBwLT5GRklfSXNTSElGVEtleURvd24obkZsYWcpOw0KLSANCi0gCQkJCQlwRm9ybUZpbGxlci0+R2V0QWN0aW9uRGF0YShwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6TG9zZUZvY3VzLCBmYSk7DQotIA0KLSAJCQkJCXBXaWRnZXQtPk9uQUFjdGlvbihDUERGX0FBY3Rpb246Okxvc2VGb2N1cywgZmEsIHBQYWdlVmlldyk7DQotIAkJCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotIA0KLSAJCQkJfQ0KLSAJCQl9DQotCQl9DQotCQllbHNlDQotCQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OklzVmlzaWJsZShDUERGU0RLX1dpZGdldCogcFdpZGdldCkNCi17DQotCXJldHVybiBwV2lkZ2V0LT5Jc1Zpc2libGUoKTsNCi19DQotDQotRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpJc1JlYWRPbmx5KENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0KQ0KLXsNCi0JQVNTRVJUKHBXaWRnZXQgIT0gTlVMTCk7DQotDQotCWludCBuRmllbGRGbGFncyA9IHBXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKTsNCi0NCi0JcmV0dXJuIChuRmllbGRGbGFncyAmIEZJRUxERkxBR19SRUFET05MWSkgPT0gRklFTERGTEFHX1JFQURPTkxZOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OklzRmlsbGluZ0FsbG93ZWQoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpDQotew0KLQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsNCi0NCi0JaWYgKHBXaWRnZXQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQ0KLQkJcmV0dXJuIFRSVUU7DQotIAllbHNlDQotIAl7DQotIAkJQ1BERl9QYWdlKiBwUGFnZSA9IHBXaWRnZXQtPkdldFBERlBhZ2UoKTsNCi0gCQlBU1NFUlQocFBhZ2UgIT0gTlVMTCk7DQotIA0KLSAJCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IHBQYWdlLT5tX3BEb2N1bWVudDsNCi0gCQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLSANCi0JCUZYX0RXT1JEIGR3UGVybWlzc2lvbnMgPSBwRG9jdW1lbnQtPkdldFVzZXJQZXJtaXNzaW9ucygpOw0KLSAJCXJldHVybiAoZHdQZXJtaXNzaW9ucyZGUERGUEVSTV9GSUxMX0ZPUk0pIHx8IA0KLSAJCQkJKGR3UGVybWlzc2lvbnMmRlBERlBFUk1fQU5OT1RfRk9STSkgfHwgDQotIAkJCShkd1Blcm1pc3Npb25zJkZQREZQRVJNX01PRElGWSk7DQotIAl9DQotCXJldHVybiBUUlVFOwkNCi19DQotDQotQ0ZGTF9Gb3JtRmlsbGVyKiBDRkZMX0lGb3JtRmlsbGVyOjpHZXRGb3JtRmlsbGVyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfQk9PTCBiUmVnaXN0ZXIpDQotew0KLS8vIAlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLS8vIAlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOw0KLQ0KLQlDRkZMX0Zvcm1GaWxsZXIgKiBwRm9ybUZpbGxlciA9IE5VTEw7DQotCW1fTWFwcy5Mb29rdXAocEFubm90LCBwRm9ybUZpbGxlcik7DQotDQotCWlmIChwRm9ybUZpbGxlcikNCi0JCXJldHVybiBwRm9ybUZpbGxlcjsNCi0NCi0JaWYgKGJSZWdpc3RlcikNCi0Jew0KLQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsJCQ0KLQ0KLQkJaW50IG5GaWVsZFR5cGUgPSBwV2lkZ2V0LT5HZXRGaWVsZFR5cGUoKTsNCi0JCXN3aXRjaChuRmllbGRUeXBlKQ0KLQkJew0KLSAJCWNhc2UgRklFTERUWVBFX1BVU0hCVVRUT046DQotIAkJCXBGb3JtRmlsbGVyID0gbmV3IENGRkxfUHVzaEJ1dHRvbihtX3BBcHAsIHBXaWRnZXQpOw0KLSAJCQlicmVhazsNCi0JCWNhc2UgRklFTERUWVBFX0NIRUNLQk9YOg0KLQkJCXBGb3JtRmlsbGVyID0gbmV3IENGRkxfQ2hlY2tCb3gobV9wQXBwLCBwV2lkZ2V0KTsNCi0JCQlicmVhazsNCi0gCQljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoNCi0gCQkJcEZvcm1GaWxsZXIgPSBuZXcgQ0ZGTF9SYWRpb0J1dHRvbihtX3BBcHAsIHBXaWRnZXQpOw0KLSAJCQlicmVhazsNCi0gCQljYXNlIEZJRUxEVFlQRV9URVhURklFTEQ6DQotCQkJcEZvcm1GaWxsZXIgPSBuZXcgQ0ZGTF9UZXh0RmllbGQobV9wQXBwLCBwV2lkZ2V0KTsNCi0JCQlicmVhazsNCi0JCWNhc2UgRklFTERUWVBFX0xJU1RCT1g6DQotCQkJcEZvcm1GaWxsZXIgPSBuZXcgQ0ZGTF9MaXN0Qm94KG1fcEFwcCwgcFdpZGdldCk7DQotCQkJYnJlYWs7DQotCQljYXNlIEZJRUxEVFlQRV9DT01CT0JPWDoNCi0JCQlwRm9ybUZpbGxlciA9IG5ldyBDRkZMX0NvbWJvQm94KG1fcEFwcCwgcFdpZGdldCk7DQotCQkJYnJlYWs7DQotCQljYXNlIEZJRUxEVFlQRV9VTktOT1dOOg0KLQkJZGVmYXVsdDoNCi0JCQlwRm9ybUZpbGxlciA9IE5VTEw7DQotCQkJYnJlYWs7DQotCQl9DQotDQotCQlpZiAocEZvcm1GaWxsZXIpDQotCQl7DQotCQkJbV9NYXBzLlNldEF0KHBBbm5vdCwgcEZvcm1GaWxsZXIpOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBwRm9ybUZpbGxlcjsNCi19DQotDQotdm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpSZW1vdmVGb3JtRmlsbGVyKENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCWlmICggcEFubm90ICE9IE5VTEwgKQ0KLQl7DQotCQlVblJlZ2lzdGVyRm9ybUZpbGxlciggcEFubm90ICk7DQotCX0NCi19DQotDQotdm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpVblJlZ2lzdGVyRm9ybUZpbGxlcihDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLQlDRkZMX0Zvcm1GaWxsZXIgKiBwRm9ybUZpbGxlciA9IE5VTEw7DQotDQotCWlmIChtX01hcHMuTG9va3VwKHBBbm5vdCxwRm9ybUZpbGxlcikpDQotCXsNCi0JCWlmIChwRm9ybUZpbGxlcikNCi0JCQlkZWxldGUgcEZvcm1GaWxsZXI7DQotCQltX01hcHMuUmVtb3ZlS2V5KHBBbm5vdCk7DQotCX0NCi19DQotDQotdm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpTZXRGb2N1c0Fubm90VGFiKENQREZTREtfQW5ub3QqIHBXaWRnZXQsIEZYX0JPT0wgYlNhbWVGaWVsZCwgRlhfQk9PTCBiTmV4dCkNCi17DQotDQotfQ0KLQ0KLXZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6UXVlcnlXaGVyZVBvcHVwKHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfRkxPQVQgZlBvcHVwTWluLEZYX0ZMT0FUIGZQb3B1cE1heCwgRlhfSU5UMzIgJiBuUmV0LCBGWF9GTE9BVCAmIGZQb3B1cFJldCkNCi17DQotCUFTU0VSVChwUHJpdmF0ZURhdGEgIT0gTlVMTCk7DQotDQotCUNGRkxfUHJpdmF0ZURhdGEqIHBEYXRhID0gKENGRkxfUHJpdmF0ZURhdGEqKXBQcml2YXRlRGF0YTsNCi0NCi0JDQotDQotDQotCUNQREZfUmVjdCByY1BhZ2VWaWV3KDAsMCwwLDApOw0KLQlyY1BhZ2VWaWV3LnJpZ2h0ID0gcERhdGEtPnBXaWRnZXQtPkdldFBERlBhZ2UoKS0+R2V0UGFnZVdpZHRoKCk7DQotCXJjUGFnZVZpZXcuYm90dG9tID0gcERhdGEtPnBXaWRnZXQtPkdldFBERlBhZ2UoKS0+R2V0UGFnZUhlaWdodCgpOw0KLQlyY1BhZ2VWaWV3Lk5vcm1hbGl6ZSgpOw0KLQ0KLQ0KLQlBU1NFUlQocERhdGEtPnBXaWRnZXQgIT0gTlVMTCk7DQotCUNQREZfUmVjdCByY0Fubm90ID0gcERhdGEtPnBXaWRnZXQtPkdldFJlY3QoKTsNCi0NCi0JRlhfRkxPQVQgZlRvcCA9IDAuMGY7DQotCUZYX0ZMT0FUIGZCb3R0b20gPSAwLjBmOw0KLQ0KLQlDUERGU0RLX1dpZGdldCAqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBEYXRhLT5wV2lkZ2V0Ow0KLQlzd2l0Y2ggKHBXaWRnZXQtPkdldFJvdGF0ZSgpIC8gOTApDQotCXsNCi0JZGVmYXVsdDoNCi0JY2FzZSAwOg0KLQkJZlRvcCA9IHJjUGFnZVZpZXcudG9wIC0gcmNBbm5vdC50b3A7DQotCQlmQm90dG9tID0gcmNBbm5vdC5ib3R0b20gLSByY1BhZ2VWaWV3LmJvdHRvbTsNCi0JCWJyZWFrOw0KLQljYXNlIDE6DQotCQlmVG9wID0gcmNBbm5vdC5sZWZ0IC0gcmNQYWdlVmlldy5sZWZ0Ow0KLQkJZkJvdHRvbSA9IHJjUGFnZVZpZXcucmlnaHQgLSByY0Fubm90LnJpZ2h0Ow0KLQkJYnJlYWs7DQotCWNhc2UgMjoNCi0JCWZUb3AgPSByY0Fubm90LmJvdHRvbSAtIHJjUGFnZVZpZXcuYm90dG9tOw0KLQkJZkJvdHRvbSA9IHJjUGFnZVZpZXcudG9wIC0gcmNBbm5vdC50b3A7DQotCQlicmVhazsNCi0JY2FzZSAzOg0KLQkJZlRvcCA9IHJjUGFnZVZpZXcucmlnaHQgLSByY0Fubm90LnJpZ2h0Ow0KLQkJZkJvdHRvbSA9IHJjQW5ub3QubGVmdCAtIHJjUGFnZVZpZXcubGVmdDsNCi0JCWJyZWFrOw0KLQl9DQotDQotCUZYX0ZMT0FUIGZGYWN0SGVpZ2h0ID0gMDsNCi0JRlhfQk9PTCBiQm90dG9tID0gVFJVRTsNCi0JRlhfRkxPQVQgZk1heExpc3RCb3hIZWlnaHQgPSAwOw0KLQlpZiAoZlBvcHVwTWF4ID4gRkZMX01BWExJU1RCT1hIRUlHSFQpDQotCXsNCi0JCWlmIChmUG9wdXBNaW4gPiBGRkxfTUFYTElTVEJPWEhFSUdIVCkNCi0JCXsNCi0JCQlmTWF4TGlzdEJveEhlaWdodCA9IGZQb3B1cE1pbjsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlmTWF4TGlzdEJveEhlaWdodCA9IEZGTF9NQVhMSVNUQk9YSEVJR0hUOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0JCWZNYXhMaXN0Qm94SGVpZ2h0ID0gZlBvcHVwTWF4Ow0KLQ0KLQlpZiAoZkJvdHRvbSA+IGZNYXhMaXN0Qm94SGVpZ2h0KQ0KLQl7DQotCQlmRmFjdEhlaWdodCA9IGZNYXhMaXN0Qm94SGVpZ2h0Ow0KLQkJYkJvdHRvbSA9IFRSVUU7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlpZiAoZlRvcCA+IGZNYXhMaXN0Qm94SGVpZ2h0KQ0KLQkJew0KLQkJCWZGYWN0SGVpZ2h0ID0gZk1heExpc3RCb3hIZWlnaHQ7DQotCQkJYkJvdHRvbSA9IEZBTFNFOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChmVG9wID4gZkJvdHRvbSkNCi0JCQl7DQotCQkJCWZGYWN0SGVpZ2h0ID0gZlRvcDsNCi0JCQkJYkJvdHRvbSA9IEZBTFNFOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlmRmFjdEhlaWdodCA9IGZCb3R0b207DQotCQkJCWJCb3R0b20gPSBUUlVFOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQluUmV0ID0gYkJvdHRvbSA/IDAgOiAxOw0KLQlmUG9wdXBSZXQgPSBmRmFjdEhlaWdodDsNCi19DQotDQotdm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpPblNldFdpbmRvd1JlY3Qodm9pZCogcFByaXZhdGVEYXRhLCBjb25zdCBDUERGX1JlY3QgJiByY1dpbmRvdykNCi17DQotCUFTU0VSVChwUHJpdmF0ZURhdGEgIT0gTlVMTCk7DQotDQotCUNGRkxfUHJpdmF0ZURhdGEqIHBEYXRhID0gKENGRkxfUHJpdmF0ZURhdGEqKXBQcml2YXRlRGF0YTsNCi0NCi0JaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBEYXRhLT5wV2lkZ2V0LCBUUlVFKSkNCi0Jew0KLQ0KLQkJQ1BERl9SZWN0IHJjT2xkID0gcEZvcm1GaWxsZXItPlBXTHRvRkZMKHBGb3JtRmlsbGVyLT5HZXRXaW5kb3dSZWN0KHBEYXRhLT5wUGFnZVZpZXcpKTsNCi0JCUNQREZfUmVjdCByY05ldyA9IHBGb3JtRmlsbGVyLT5QV0x0b0ZGTChyY1dpbmRvdyk7DQotCQlwRm9ybUZpbGxlci0+U2V0V2luZG93UmVjdChwRGF0YS0+cFBhZ2VWaWV3LCByY1dpbmRvdyk7DQotDQotCQlDUERGX1JlY3QgdW5SZWN0ID0gcmNPbGQ7DQotCQl1blJlY3QuVW5pb24ocmNOZXcpOw0KLQkJLy9GWF9SRUNUIHJjUmVjdCA9IHVuUmVjdC5HZXRPdXR0ZXJSZWN0KCk7DQotCQl1blJlY3QubGVmdCA9IChGWF9GTE9BVCkodW5SZWN0LmxlZnQgLSAwLjUpOw0KLQkJdW5SZWN0LnJpZ2h0ID0gKEZYX0ZMT0FUKSh1blJlY3QucmlnaHQgKyAwLjUpOw0KLQkJdW5SZWN0LnRvcCA9IChGWF9GTE9BVCkodW5SZWN0LnRvcCArIDAuNSk7DQotCQl1blJlY3QuYm90dG9tID0gKEZYX0ZMT0FUKSh1blJlY3QuYm90dG9tIC0wLjUpOw0KLQkJbV9wQXBwLT5GRklfSW52YWxpZGF0ZShwRGF0YS0+cFdpZGdldC0+R2V0UERGUGFnZSgpLCB1blJlY3QubGVmdCwgdW5SZWN0LnRvcCwgdW5SZWN0LnJpZ2h0LCB1blJlY3QuYm90dG9tKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uS2V5U3Ryb2tlKEZYX0JPT0wgYkVkaXRPckxpc3QsIHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfSU5UMzIgbktleUNvZGUsIENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsIA0KLQkJCQkJCQkJICAgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LCBGWF9CT09MIGJLZXlEb3duLCANCi0JCQkJCQkJCSAgIEZYX0JPT0wgJiBiUkMsIEZYX0JPT0wgJiBiRXhpdCkNCi17DQotCUFTU0VSVChwUHJpdmF0ZURhdGEgIT0gTlVMTCk7DQotCUNGRkxfUHJpdmF0ZURhdGEqIHBEYXRhID0gKENGRkxfUHJpdmF0ZURhdGEqKXBQcml2YXRlRGF0YTsNCi0JQVNTRVJUKHBEYXRhLT5wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQlDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwRGF0YS0+cFdpZGdldCwgRkFMU0UpOw0KLQlBU1NFUlQocEZvcm1GaWxsZXIgIT0gTlVMTCk7DQotDQotCXBGb3JtRmlsbGVyLT5PbktleVN0cm9rZShiS2V5RG93bik7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6T25LZXlTdHJva2VDb21taXQoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYlJDLCBGWF9CT09MJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAoIW1fYk5vdGlmeWluZykNCi0Jew0KLQkJQVNTRVJUKHBXaWRnZXQgIT0gTlVMTCk7DQotCQlpZiAocFdpZGdldC0+R2V0QUFjdGlvbihDUERGX0FBY3Rpb246OktleVN0cm9rZSkpDQotCQl7DQotCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsNCi0JCQlwV2lkZ2V0LT5DbGVhckFwcE1vZGlmaWVkKCk7DQotDQotCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0vLyAJCQlDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3ID0gcFBhZ2VWaWV3LT5HZXREb2NWaWV3KCk7DQotLy8gCQkJQVNTRVJUKHBEb2NWaWV3ICE9IE5VTEwpOw0KLQkJCQ0KLQkJDQotDQotCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhOw0KLQkJCWZhLmJNb2RpZmllciA9IG1fcEFwcC0+RkZJX0lzQ1RSTEtleURvd24obkZsYWcpOw0KLSAJCQlmYS5iU2hpZnQgPSBtX3BBcHAtPkZGSV9Jc1NISUZUS2V5RG93bihuRmxhZyk7DQotCQkJZmEuYldpbGxDb21taXQgPSBUUlVFOw0KLQkJCWZhLm5Db21taXRLZXkgPSBHZXRDb21taXRLZXkoKTsNCi0JCQlmYS5iS2V5RG93biA9IEdldEtleURvd24oKTsNCi0JCQlmYS5iUkMgPSBUUlVFOw0KLQ0KLQkJCUNGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBXaWRnZXQsIEZBTFNFKTsNCi0JCQlBU1NFUlQocEZvcm1GaWxsZXIgIT0gTlVMTCk7DQotDQotCQkJcEZvcm1GaWxsZXItPkdldEFjdGlvbkRhdGEocFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OktleVN0cm9rZSwgZmEpOw0KLQkJCXBGb3JtRmlsbGVyLT5TYXZlU3RhdGUocFBhZ2VWaWV3KTsNCi0NCi0JCQlQREZTREtfRmllbGRBY3Rpb24gZmFPbGQgPSBmYTsNCi0JCQlwV2lkZ2V0LT5PbkFBY3Rpb24oQ1BERl9BQWN0aW9uOjpLZXlTdHJva2UsIGZhLCBwUGFnZVZpZXcpOw0KLQ0KLQkJCWJSQyA9IGZhLmJSQzsNCi0vLwkJCWJFeGl0ID0gIUlzVmFsaWRBbm5vdChtX3BBcHAsIHBEb2N1bWVudCwgcERvY1ZpZXcsIHBQYWdlVmlldywgcFdpZGdldCk7DQotDQotCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpPblZhbGlkYXRlKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wmIGJSQywgRlhfQk9PTCYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JaWYgKCFtX2JOb3RpZnlpbmcpDQotCXsNCi0JCUFTU0VSVChwV2lkZ2V0ICE9IE5VTEwpOw0KLQkJaWYgKHBXaWRnZXQtPkdldEFBY3Rpb24oQ1BERl9BQWN0aW9uOjpWYWxpZGF0ZSkpDQotCQl7DQotCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsNCi0JCQlwV2lkZ2V0LT5DbGVhckFwcE1vZGlmaWVkKCk7DQotDQotCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0vLyAJCQlDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3ID0gcFBhZ2VWaWV3LT5HZXREb2NWaWV3KCk7DQotLy8gCQkJQVNTRVJUKHBEb2NWaWV3ICE9IE5VTEwpOw0KLQkJCQ0KLQkJCQ0KLQ0KLQkJCVBERlNES19GaWVsZEFjdGlvbiBmYTsNCi0JCQlmYS5iTW9kaWZpZXIgPSBtX3BBcHAtPkZGSV9Jc0NUUkxLZXlEb3duKG5GbGFnKTsNCi0gCQkJZmEuYlNoaWZ0ID0gbV9wQXBwLT5GRklfSXNTSElGVEtleURvd24obkZsYWcpOw0KLQkJCWZhLmJLZXlEb3duID0gR2V0S2V5RG93bigpOw0KLQkJCWZhLmJSQyA9IFRSVUU7DQotDQotCQkJQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocFdpZGdldCwgRkFMU0UpOw0KLQkJCUFTU0VSVChwRm9ybUZpbGxlciAhPSBOVUxMKTsNCi0NCi0JCQlwRm9ybUZpbGxlci0+R2V0QWN0aW9uRGF0YShwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6VmFsaWRhdGUsIGZhKTsNCi0JCQlwRm9ybUZpbGxlci0+U2F2ZVN0YXRlKHBQYWdlVmlldyk7DQotDQotCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhT2xkID0gZmE7DQotCQkJcFdpZGdldC0+T25BQWN0aW9uKENQREZfQUFjdGlvbjo6VmFsaWRhdGUsIGZhLCBwUGFnZVZpZXcpOw0KLQ0KLQkJCWJSQyA9IGZhLmJSQzsNCi0vLwkJCWJFeGl0ID0gIUlzVmFsaWRBbm5vdChtX3BBcHAsIHBEb2N1bWVudCwgcERvY1ZpZXcsIHBQYWdlVmlldywgcFdpZGdldCk7DQotDQotCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpPbkNhbGN1bGF0ZShDUERGU0RLX1dpZGdldCogcFdpZGdldCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAoIW1fYk5vdGlmeWluZykNCi0Jew0KLQkJQVNTRVJUKHBXaWRnZXQgIT0gTlVMTCk7DQotCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLS8vIAkJQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldyA9IHBQYWdlVmlldy0+R2V0RG9jVmlldygpOw0KLS8vIAkJQVNTRVJUKHBEb2NWaWV3ICE9IE5VTEwpOw0KLQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50ID0gcFBhZ2VWaWV3LT5HZXRTREtEb2N1bWVudCgpOw0KLQkJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQkJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCQlwSW50ZXJGb3JtLT5PbkNhbGN1bGF0ZShwV2lkZ2V0LT5HZXRGb3JtRmllbGQoKSk7DQotDQotLy8JCWJFeGl0ID0gIUlzVmFsaWRBbm5vdChtX3BBcHAsIHBEb2N1bWVudCwgcERvY1ZpZXcsIHBQYWdlVmlldywgcFdpZGdldCk7DQotDQotCQltX2JOb3RpZnlpbmcgPSBGQUxTRTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uRm9ybWF0KENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wmIGJFeGl0LCBGWF9EV09SRCBuRmxhZykNCi17DQotCWlmICghbV9iTm90aWZ5aW5nKQ0KLQl7DQotCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsNCi0JCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotLy8gCQlDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3ID0gcFBhZ2VWaWV3LT5HZXREb2NWaWV3KCk7DQotLy8gCQlBU1NFUlQocERvY1ZpZXcgIT0gTlVMTCk7DQotCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBwUGFnZVZpZXctPkdldFNES0RvY3VtZW50KCk7DQotCQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQkJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKXBEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JCUZYX0JPT0wgYkZvcm1hdGVkID0gRkFMU0U7DQotCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwSW50ZXJGb3JtLT5PbkZvcm1hdChwV2lkZ2V0LT5HZXRGb3JtRmllbGQoKSwgR2V0Q29tbWl0S2V5KCksIGJGb3JtYXRlZCk7DQotDQotLy8JCWJFeGl0ID0gIUlzVmFsaWRBbm5vdChtX3BBcHAsIHBEb2N1bWVudCwgcERvY1ZpZXcsIHBQYWdlVmlldywgcFdpZGdldCk7DQotDQotCQlpZiAoYkV4aXQpIHJldHVybjsNCi0NCi0JCWlmIChiRm9ybWF0ZWQpDQotCQl7DQotCQkJcEludGVyRm9ybS0+UmVzZXRGaWVsZEFwcGVhcmFuY2UocFdpZGdldC0+R2V0Rm9ybUZpZWxkKCksIHNWYWx1ZSwgVFJVRSk7DQotCQkJcEludGVyRm9ybS0+VXBkYXRlRmllbGQocFdpZGdldC0+R2V0Rm9ybUZpZWxkKCkpOw0KLQkJfQ0KLQ0KLQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotCX0NCi19DQotDQotLy8gTFJFU1VMVCBDQUxMQkFDSyBDRkZMX0lGb3JtRmlsbGVyOjpGRkxfV25kUHJvYygNCi0vLyAJCQkJCQkJCQkgIGludCBjb2RlLCAgICAgICAvLyBob29rIGNvZGUNCi0vLyAJCQkJCQkJCQkgIFdQQVJBTSB3UGFyYW0sICAvLyB2aXJ0dWFsLWtleSBjb2RlDQotLy8gCQkJCQkJCQkJICBMUEFSQU0gbFBhcmFtICAgLy8ga2V5c3Ryb2tlLW1lc3NhZ2UgaW5mb3JtYXRpb24NCi0vLyAJCQkJCQkJCQkJKQ0KLS8vIHsNCi0vLyAJaWYgKGNvZGUgIT0gSENfQUNUSU9OKQ0KLS8vIAl7DQotLy8gCQlyZXR1cm4gQ2FsbE5leHRIb29rRXggKG1faG9va1NoZWV0LCBjb2RlLCB3UGFyYW0sIGxQYXJhbSk7DQotLy8gCX0NCi0vLyANCi0vLyAJRlhTWVNfbWVtY3B5KCZnX01zZywgKHZvaWQqKWxQYXJhbSwgc2l6ZW9mKE1TRykpOwkNCi0vLyANCi0vLyAJcmV0dXJuIDA7DQotLy8gfQ0KLQ0KLS8vIE1TRwlDRkZMX0lGb3JtRmlsbGVyOjpHZXRMYXN0TWVzc2FnZSgpDQotLy8gew0KLS8vIAlyZXR1cm4gZ19Nc2c7DQotLy8gfQ0KLQ0KLWludCBDRkZMX0lGb3JtRmlsbGVyOjpHZXRDb21taXRLZXkoKQ0KLXsNCi0vLwlNU0cgbXNnID0gQ0ZGTF9JRm9ybUZpbGxlcjo6R2V0TGFzdE1lc3NhZ2UoKTsNCi0NCi0JaW50IG5Db21taXRLZXkgPSAwOw0KLS8vIAlzd2l0Y2ggKG1zZy5tZXNzYWdlKQ0KLS8vIAl7DQotLy8gCWNhc2UgV01fTEJVVFRPTkRPV046DQotLy8gCWNhc2UgV01fTEJVVFRPTlVQOg0KLS8vIAkJbkNvbW1pdEtleSA9IDE7DQotLy8gCQlicmVhazsNCi0vLyAJY2FzZSBXTV9LRVlET1dOOg0KLS8vIAkJc3dpdGNoIChtc2cud1BhcmFtKQ0KLS8vIAkJew0KLS8vIAkJY2FzZSBWS19SRVRVUk46DQotLy8gCQkJbkNvbW1pdEtleSA9IDI7DQotLy8gCQkJYnJlYWs7DQotLy8gCQljYXNlIFZLX1RBQjoNCi0vLyAJCQluQ29tbWl0S2V5ID0gMzsNCi0vLyAJCQlicmVhazsNCi0vLyAJCX0NCi0vLyAJCWJyZWFrOw0KLS8vIAl9DQotDQotCXJldHVybiBuQ29tbWl0S2V5Ow0KLX0NCi0NCi1GWF9CT09MIENGRkxfSUZvcm1GaWxsZXI6OkdldEtleURvd24oKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotLy8gCU1TRyBtc2cgPSBDRkZMX0lGb3JtRmlsbGVyOjpHZXRMYXN0TWVzc2FnZSgpOw0KLS8vIA0KLS8vIAlyZXR1cm4gbXNnLm1lc3NhZ2UgPT0gV01fS0VZRE9XTiB8fCBtc2cubWVzc2FnZSA9PSBXTV9DSEFSOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OklzVmFsaWRBbm5vdChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotDQotCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotDQotCWlmKHBQYWdlVmlldykNCi0JCXJldHVybiBwUGFnZVZpZXctPklzVmFsaWRBbm5vdChwQW5ub3QtPkdldFBERkFubm90KCkpOw0KLQllbHNlDQotCQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6QmVmb3JlVW5kbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQ0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6OkJlZm9yZVJlZG8oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0JQmVmb3JlVW5kbyhwRG9jdW1lbnQpOw0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6OkFmdGVyVW5kbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6OkFmdGVyUmVkbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OkNhbkNvcHkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OkNhbkN1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6Q2FuUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6OkRvQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLX0NCi0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6OkRvQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6RG9QYXN0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQ0KLX0NCi12b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uQmVmb3JlS2V5U3Ryb2tlKEZYX0JPT0wgYkVkaXRPckxpc3QsIHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfSU5UMzIgbktleUNvZGUsDQotCQkJCQkJCQkJCQkgIENGWF9XaWRlU3RyaW5nICYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIA0KLQkJCQkJCQkJCQkJICBpbnQgblNlbFN0YXJ0LCBpbnQgblNlbEVuZCwNCi0JCQkJCQkJCQkJRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCAmIGJSQywgRlhfQk9PTCAmIGJFeGl0LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUFTU0VSVChwUHJpdmF0ZURhdGEgIT0gTlVMTCk7DQotCUNGRkxfUHJpdmF0ZURhdGEqIHBEYXRhID0gKENGRkxfUHJpdmF0ZURhdGEqKXBQcml2YXRlRGF0YTsNCi0JQVNTRVJUKHBEYXRhLT5wV2lkZ2V0ICE9IE5VTEwpOw0KLQkNCi0JQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocERhdGEtPnBXaWRnZXQsIEZBTFNFKTsNCi0JQVNTRVJUKHBGb3JtRmlsbGVyICE9IE5VTEwpOw0KLQkNCi0JaWYgKCFtX2JOb3RpZnlpbmcpDQotCXsNCi0JCWlmIChwRGF0YS0+cFdpZGdldC0+R2V0QUFjdGlvbihDUERGX0FBY3Rpb246OktleVN0cm9rZSkpDQotCQl7DQotCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsNCi0JCQlpbnQgbkFnZSA9IHBEYXRhLT5wV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCk7DQotCQkJaW50IG5WYWx1ZUFnZSA9IHBEYXRhLT5wV2lkZ2V0LT5HZXRWYWx1ZUFnZSgpOw0KLQ0KLQkJCUFTU0VSVChwRGF0YS0+cFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCAgPSBwRGF0YS0+cFBhZ2VWaWV3LT5HZXRTREtEb2N1bWVudCgpOw0KLQkJCQ0KLQkJCVBERlNES19GaWVsZEFjdGlvbiBmYTsNCi0gCQkJZmEuYk1vZGlmaWVyID0gbV9wQXBwLT5GRklfSXNDVFJMS2V5RG93bihuRmxhZyk7DQotIAkJCWZhLmJTaGlmdCA9IG1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKTsNCi0JCQlmYS5zQ2hhbmdlID0gc3RyQ2hhbmdlOw0KLQkJCWZhLnNDaGFuZ2VFeCA9IHN0ckNoYW5nZUV4Ow0KLQkJCWZhLmJLZXlEb3duID0gYktleURvd247DQotCQkJZmEuYldpbGxDb21taXQgPSBGQUxTRTsNCi0JCQlmYS5iUkMgPSBUUlVFOw0KLQkJCWZhLm5TZWxTdGFydCA9IG5TZWxTdGFydDsNCi0JCQlmYS5uU2VsRW5kID0gblNlbEVuZDsNCi0NCi0NCi0JCQlwRm9ybUZpbGxlci0+R2V0QWN0aW9uRGF0YShwRGF0YS0+cFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OktleVN0cm9rZSwgZmEpOw0KLQkJCXBGb3JtRmlsbGVyLT5TYXZlU3RhdGUocERhdGEtPnBQYWdlVmlldyk7DQotCQkJDQotCQkJaWYgKHBEYXRhLT5wV2lkZ2V0LT5PbkFBY3Rpb24oQ1BERl9BQWN0aW9uOjpLZXlTdHJva2UsIGZhLCBwRGF0YS0+cFBhZ2VWaWV3KSkNCi0JCQl7DQotCQkJCWlmICghSXNWYWxpZEFubm90KHBEYXRhLT5wUGFnZVZpZXcsIHBEYXRhLT5wV2lkZ2V0KSkNCi0JCQkJew0KLQkJCQkJYkV4aXQgPSBUUlVFOw0KLQkJCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotCQkJCQlyZXR1cm47DQotCQkJCX0NCi0JCQkJDQotCQkJCWlmIChuQWdlICE9IHBEYXRhLT5wV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCkpDQotCQkJCXsNCi0JCQkJCUNQV0xfV25kKiBwV25kID0gcEZvcm1GaWxsZXItPlJlc2V0UERGV2luZG93KHBEYXRhLT5wUGFnZVZpZXcsIG5WYWx1ZUFnZSA9PSBwRGF0YS0+cFdpZGdldC0+R2V0VmFsdWVBZ2UoKSk7DQotCQkJCQlwRGF0YSA9IChDRkZMX1ByaXZhdGVEYXRhKilwV25kLT5HZXRBdHRhY2hlZERhdGEoKTsNCi0JCQkJCWJFeGl0ID0gVFJVRTsNCi0JCQkJfQ0KLQkJCQkNCi0JCQkJaWYgKGZhLmJSQykNCi0JCQkJew0KLQkJCQkJcEZvcm1GaWxsZXItPlNldEFjdGlvbkRhdGEocERhdGEtPnBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2UsIGZhKTsNCi0JCQkJCWJSQyA9IEZBTFNFOw0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJcEZvcm1GaWxsZXItPlJlc3RvcmVTdGF0ZShwRGF0YS0+cFBhZ2VWaWV3KTsNCi0JCQkJCWJSQyA9IEZBTFNFOw0KLQkJCQl9DQotCQkJCQ0KLQkJCQlpZiAocERvY3VtZW50LT5HZXRGb2N1c0Fubm90KCkgIT0gcERhdGEtPnBXaWRnZXQpDQotCQkJCXsNCi0JCQkJCXBGb3JtRmlsbGVyLT5Db21taXREYXRhKHBEYXRhLT5wUGFnZVZpZXcsbkZsYWcpOw0KLQkJCQkJYkV4aXQgPSBUUlVFOw0KLQkJCQl9DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7CQkJDQotCQkJCWlmICghSXNWYWxpZEFubm90KHBEYXRhLT5wUGFnZVZpZXcsIHBEYXRhLT5wV2lkZ2V0KSkNCi0JCQkJew0KLQkJCQkJYkV4aXQgPSBUUlVFOw0KLQkJCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotCQkJCQlyZXR1cm47DQotCQkJCX0NCi0JCQl9DQotCQkJDQotCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7DQotCQl9DQotCX0NCi19DQotDQotdm9pZAlDRkZMX0lGb3JtRmlsbGVyOjpPbkFmdGVyS2V5U3Ryb2tlKEZYX0JPT0wgYkVkaXRPckxpc3QsIHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfQk9PTCAmIGJFeGl0LEZYX0RXT1JEIG5GbGFnKSANCi17DQotCUFTU0VSVChwUHJpdmF0ZURhdGEgIT0gTlVMTCk7DQotCUNGRkxfUHJpdmF0ZURhdGEqIHBEYXRhID0gKENGRkxfUHJpdmF0ZURhdGEqKXBQcml2YXRlRGF0YTsNCi0JQVNTRVJUKHBEYXRhLT5wV2lkZ2V0ICE9IE5VTEwpOw0KLQkNCi0JQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocERhdGEtPnBXaWRnZXQsIEZBTFNFKTsNCi0JQVNTRVJUKHBGb3JtRmlsbGVyICE9IE5VTEwpOw0KLQkNCi0JaWYgKCFiRWRpdE9yTGlzdCkNCi0JCXBGb3JtRmlsbGVyLT5PbktleVN0cm9rZShiRXhpdCk7DQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0lGb3JtRmlsbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9DaGVja0JveC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ29tYm9Cb3guaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0xpc3RCb3guaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1B1c2hCdXR0b24uaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1JhZGlvQnV0dG9uLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9UZXh0RmllbGQuaCIKKworI2RlZmluZSBGRkxfTUFYTElTVEJPWEhFSUdIVAkJMTQwLjBmCisKKy8vIEhIT09LIENGRkxfSUZvcm1GaWxsZXI6Om1faG9va1NoZWV0ID0gTlVMTDsKKy8vIE1TRyBDRkZMX0lGb3JtRmlsbGVyOjpnX01zZzsKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZGTF9JRm9ybUZpbGxlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRkZMX0lGb3JtRmlsbGVyOjpDRkZMX0lGb3JtRmlsbGVyKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHApIDogCisJbV9wQXBwKHBBcHApLAorCW1fYk5vdGlmeWluZyhGQUxTRSkKK3sKK30KKworQ0ZGTF9JRm9ybUZpbGxlcjo6fkNGRkxfSUZvcm1GaWxsZXIoKQoreworCUZYX1BPU0lUSU9OIHBvcyA9IG1fTWFwcy5HZXRTdGFydFBvc2l0aW9uKCk7CisJd2hpbGUgKHBvcykKKwl7CisJCUNQREZTREtfQW5ub3QgKiBwQW5ub3QgPSBOVUxMOworCQlDRkZMX0Zvcm1GaWxsZXIgKiBwRm9ybUZpbGxlciA9IE5VTEw7CisJCW1fTWFwcy5HZXROZXh0QXNzb2MocG9zLHBBbm5vdCxwRm9ybUZpbGxlcik7CisJCWRlbGV0ZSBwRm9ybUZpbGxlcjsKKwl9CisJbV9NYXBzLlJlbW92ZUFsbCgpOworfQorCitGWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OkFubm90X0hpdFRlc3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LENQREZTREtfQW5ub3QqIHBBbm5vdCwgQ1BERl9Qb2ludCBwb2ludCkKK3sKKwlDUERGX1JlY3QgcmMgPSBwQW5ub3QtPkdldFJlY3QoKTsKKwlpZihyYy5Db250YWlucyhwb2ludC54LCBwb2ludC55KSkKKwkJcmV0dXJuIFRSVUU7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9SRUNUIENGRkxfSUZvcm1GaWxsZXI6OkdldFZpZXdCQm94KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90KQoreworCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkKKwl7CisJCXJldHVybiBwRm9ybUZpbGxlci0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBwQW5ub3QpOworCX0KKwllbHNlCisJeworCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCQlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCisJCUNQREZfQW5ub3QqIHBQREZBbm5vdCA9IHBBbm5vdC0+R2V0UERGQW5ub3QoKTsKKwkJQVNTRVJUKHBQREZBbm5vdCAhPSBOVUxMKTsKKworCQlDUERGX1JlY3QgcmNBbm5vdDsKKwkJcFBERkFubm90LT5HZXRSZWN0KHJjQW5ub3QpOworCisvLyAJCUNSZWN0IHJjV2luOworLy8gCQlwUGFnZVZpZXctPkRvY1RvV2luZG93KHJjQW5ub3QsIHJjV2luKTsKKwkJQ1BERl9SZWN0IHJjV2luID0gQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QocmNBbm5vdCwxKTsKKy8vCQlyY1dpbi5JbmZsYXRlUmVjdCgxLCAxKTsKKworCQlyZXR1cm4gcmNXaW4uR2V0T3V0dGVyUmVjdCgpOworCX0KK30KKwordm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpPbkRyYXcoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCAvKkhEQyBoREMsKi8gQ1BERlNES19Bbm5vdCogcEFubm90LCAKKwkJCQkJCUNGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkvKmNvbnN0IENSZWN0JiByY1dpbmRvdywqLyBGWF9EV09SRCBkd0ZsYWdzKQoreworCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7CisJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsKKworCWlmIChJc1Zpc2libGUocFdpZGdldCkpCisJeworCQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJCXsKKyAJCQlpZiAocEZvcm1GaWxsZXItPklzVmFsaWQoKSkKKyAJCQl7CisJCQkJcEZvcm1GaWxsZXItPk9uRHJhdyhwUGFnZVZpZXcsIHBBbm5vdCwgcERldmljZSwgcFVzZXIyRGV2aWNlLCBkd0ZsYWdzKTsKKwkJCQkKKwkJCQlwQW5ub3QtPkdldFBERlBhZ2UoKTsKKwkJCQkKKworCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCA9IG1fcEFwcC0+R2V0Q3VycmVudERvYygpOworCQkJCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwkJCQlpZiAocERvY3VtZW50LT5HZXRGb2N1c0Fubm90KCkgPT0gcEFubm90KQorCQkJCXsKKwkJCQkJQ1BERl9SZWN0IHJjRm9jdXMgPSBwRm9ybUZpbGxlci0+R2V0Rm9jdXNCb3gocFBhZ2VWaWV3KTsKKwkJCQkJaWYgKCFyY0ZvY3VzLklzRW1wdHkoKSkKKwkJCQkJeworCQkJCQkJQ0ZYX1BhdGhEYXRhIHBhdGg7CisJCQkJCQkKKwkJCQkJCXBhdGguU2V0UG9pbnRDb3VudCg1KTsKKwkJCQkJCXBhdGguU2V0UG9pbnQoMCwgcmNGb2N1cy5sZWZ0LCAgcmNGb2N1cy50b3AsIEZYUFRfTU9WRVRPKTsKKwkJCQkJCXBhdGguU2V0UG9pbnQoMSwgcmNGb2N1cy5sZWZ0LCAgcmNGb2N1cy5ib3R0b20sIEZYUFRfTElORVRPKTsKKwkJCQkJCXBhdGguU2V0UG9pbnQoMiwgcmNGb2N1cy5yaWdodCwgIHJjRm9jdXMuYm90dG9tLCBGWFBUX0xJTkVUTyk7CisJCQkJCQlwYXRoLlNldFBvaW50KDMsIHJjRm9jdXMucmlnaHQsICByY0ZvY3VzLnRvcCwgRlhQVF9MSU5FVE8pOworCQkJCQkJcGF0aC5TZXRQb2ludCg0LCByY0ZvY3VzLmxlZnQsICByY0ZvY3VzLnRvcCwgRlhQVF9MSU5FVE8pOworCQkJCQkJCisJCQkJCQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOworCQkJCQkJZ3NkLlNldERhc2hDb3VudCgxKTsJCQkJCisJCQkJCQlnc2QubV9EYXNoQXJyYXlbMF0gPSAxLjBmOworCQkJCQkJZ3NkLm1fRGFzaFBoYXNlID0gMDsJCisJCQkJCQkKKwkJCQkJCWdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CisJCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLCBBcmdiRW5jb2RlKDI1NSwwLDAsMCksIEZYRklMTF9BTFRFUk5BVEUpOworCisJCQkJCS8vCTo6RHJhd0ZvY3VzUmVjdChoREMsICZyY0ZvY3VzKTsJCisJCQkJCX0KKwkJCQl9CisKKwkJCQlyZXR1cm47CisJCQl9CisJCX0KKworCQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJCQlwRm9ybUZpbGxlci0+T25EcmF3RGVhY3RpdmUocFBhZ2VWaWV3LCBwQW5ub3QsIHBEZXZpY2UsIHBVc2VyMkRldmljZSwgZHdGbGFncyk7CisJCWVsc2UKKwkJCXBXaWRnZXQtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsKKworCQlpZiAoIUlzUmVhZE9ubHkocFdpZGdldCkgJiYgSXNGaWxsaW5nQWxsb3dlZChwV2lkZ2V0KSkKKwkJeworCQkJcFdpZGdldC0+RHJhd1NoYWRvdyhwRGV2aWNlLCBwUGFnZVZpZXcpOworCQl9CisJCisJfQorfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uQ3JlYXRlKENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJeworCQlwRm9ybUZpbGxlci0+T25DcmVhdGUocEFubm90KTsKKwl9Cit9CisKK3ZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6T25Mb2FkKENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJeworCQlwRm9ybUZpbGxlci0+T25Mb2FkKHBBbm5vdCk7CisJfQorfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uRGVsZXRlKENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJeworCQlwRm9ybUZpbGxlci0+T25EZWxldGUocEFubm90KTsKKwl9CisKKwlVblJlZ2lzdGVyRm9ybUZpbGxlcihwQW5ub3QpOworfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZykKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7CisJCisJaWYgKCFtX2JOb3RpZnlpbmcpCisJeworCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopcEFubm90OworCQlpZiAocFdpZGdldC0+R2V0QUFjdGlvbihDUERGX0FBY3Rpb246OkN1cnNvckVudGVyKSkKKwkJeworCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsKKwkJCQorCQkJaW50IG5WYWx1ZUFnZSA9IHBXaWRnZXQtPkdldFZhbHVlQWdlKCk7CisKKwkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsKKwkJCQorCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKwkJCQorCQkJCisJCQkKKwkJCVBERlNES19GaWVsZEFjdGlvbiBmYTsKKwkJCWZhLmJNb2RpZmllciA9IG1fcEFwcC0+RkZJX0lzQ1RSTEtleURvd24obkZsYWcpOworIAkJCWZhLmJTaGlmdCA9IG1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKTsKKwkJCXBXaWRnZXQtPk9uQUFjdGlvbihDUERGX0FBY3Rpb246OkN1cnNvckVudGVyLCBmYSwgcFBhZ2VWaWV3ICk7CisJCQltX2JOb3RpZnlpbmcgPSBGQUxTRTsKKwkJCQorCQkJLy9pZiAoICFJc1ZhbGlkQW5ub3QocFBhZ2VWaWV3LCBwQW5ub3QpICkgcmV0dXJuOworCQkJCisJCQlpZiAocFdpZGdldC0+SXNBcHBNb2RpZmllZCgpKQorCQkJeworCQkJCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwV2lkZ2V0LCBGQUxTRSkpCisJCQkJeworCQkJCQlwRm9ybUZpbGxlci0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBwV2lkZ2V0LT5HZXRWYWx1ZUFnZSgpID09IG5WYWx1ZUFnZSk7CisJCQkJfQorCQkJfQorCQl9CisJfQorCQorCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIFRSVUUpKQorCXsKKwkJcEZvcm1GaWxsZXItPk9uTW91c2VFbnRlcihwUGFnZVZpZXcsIHBBbm5vdCk7CisJfQorfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uTW91c2VFeGl0KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFnKQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsKKwkKKwlpZiAoIW1fYk5vdGlmeWluZykKKwl7CisJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7CisJCWlmIChwV2lkZ2V0LT5HZXRBQWN0aW9uKENQREZfQUFjdGlvbjo6Q3Vyc29yRXhpdCkpCisJCXsKKwkJCW1fYk5vdGlmeWluZyA9IFRSVUU7CisJCQlwV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCk7CisJCQlpbnQgblZhbHVlQWdlID0gcFdpZGdldC0+R2V0VmFsdWVBZ2UoKTsKKwkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsKKwkJCQorCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKwkJCQorCQkJCisJCQkKKwkJCVBERlNES19GaWVsZEFjdGlvbiBmYTsKKwkJCWZhLmJNb2RpZmllciA9IG1fcEFwcC0+RkZJX0lzQ1RSTEtleURvd24obkZsYWcpOworIAkJCWZhLmJTaGlmdCA9IG1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKTsKKwkJCQorCQkJcFdpZGdldC0+T25BQWN0aW9uKENQREZfQUFjdGlvbjo6Q3Vyc29yRXhpdCwgZmEsIHBQYWdlVmlldyk7CisJCQltX2JOb3RpZnlpbmcgPSBGQUxTRTsKKwkJCQorCQkJLy9pZiAoIUlzVmFsaWRBbm5vdChwUGFnZVZpZXcsIHBBbm5vdCkpIHJldHVybjsKKwkJCQorCQkJaWYgKHBXaWRnZXQtPklzQXBwTW9kaWZpZWQoKSkKKwkJCXsKKwkJCQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocFdpZGdldCwgRkFMU0UpKQorCQkJCXsKKwkJCQkJcEZvcm1GaWxsZXItPlJlc2V0UERGV2luZG93KHBQYWdlVmlldywgblZhbHVlQWdlID09IHBXaWRnZXQtPkdldFZhbHVlQWdlKCkpOworCQkJCX0KKwkJCX0KKwkJfQorCX0KKwkKKwlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJeworCQlwRm9ybUZpbGxlci0+T25Nb3VzZUV4aXQocFBhZ2VWaWV3LCBwQW5ub3QpOworCX0KK30KKworRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpPbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOworCQorCWlmICghbV9iTm90aWZ5aW5nKQorCXsKKwkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsKKwkJaWYgKEFubm90X0hpdFRlc3QocFBhZ2VWaWV3LCBwQW5ub3QsIHBvaW50KSAmJiBwV2lkZ2V0LT5HZXRBQWN0aW9uKENQREZfQUFjdGlvbjo6QnV0dG9uRG93bikpCisJCXsKKwkJCW1fYk5vdGlmeWluZyA9IFRSVUU7CisJCQlwV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCk7CisJCQlpbnQgblZhbHVlQWdlID0gcFdpZGdldC0+R2V0VmFsdWVBZ2UoKTsKKwkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsKKwkJCQorCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKwkJCQorCQkJCisJCQkKKwkJCVBERlNES19GaWVsZEFjdGlvbiBmYTsKKwkJCWZhLmJNb2RpZmllciA9IG1fcEFwcC0+RkZJX0lzQ1RSTEtleURvd24obkZsYWdzKTsKKyAJCQlmYS5iU2hpZnQgPSBtX3BBcHAtPkZGSV9Jc1NISUZUS2V5RG93bihuRmxhZ3MpOworCQkJcFdpZGdldC0+T25BQWN0aW9uKENQREZfQUFjdGlvbjo6QnV0dG9uRG93biwgZmEsIHBQYWdlVmlldyk7CisJCQltX2JOb3RpZnlpbmcgPSBGQUxTRTsKKwkJCQorCQkJaWYgKCFJc1ZhbGlkQW5ub3QocFBhZ2VWaWV3LCBwQW5ub3QpKSByZXR1cm4gVFJVRTsKKwkJCQorCQkJaWYgKHBXaWRnZXQtPklzQXBwTW9kaWZpZWQoKSkKKwkJCXsKKwkJCQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocFdpZGdldCwgRkFMU0UpKQorCQkJCXsKKwkJCQkJcEZvcm1GaWxsZXItPlJlc2V0UERGV2luZG93KHBQYWdlVmlldywgblZhbHVlQWdlID09IHBXaWRnZXQtPkdldFZhbHVlQWdlKCkpOworCQkJCX0KKwkJCX0KKwkJfQorCX0KKwkKKwlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJeworCQlyZXR1cm4gcEZvcm1GaWxsZXItPk9uTEJ1dHRvbkRvd24ocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOworCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6T25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7CisJCisJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsKKwkvLyAJQ1JlYWRlcl9QYWdlKiBwUGFnZSA9IHBBbm5vdC0+R2V0UGFnZSgpOworCS8vIAlBU1NFUlQocFBhZ2UgIT0gTlVMTCk7CisJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50ID0gbV9wQXBwLT5HZXRDdXJyZW50RG9jKCk7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsJCQorCQorCXN3aXRjaCAocFdpZGdldC0+R2V0RmllbGRUeXBlKCkpCisJeworCWNhc2UgRklFTERUWVBFX1BVU0hCVVRUT046CisJY2FzZSBGSUVMRFRZUEVfQ0hFQ0tCT1g6CisJY2FzZSBGSUVMRFRZUEVfUkFESU9CVVRUT046CisJCWlmIChHZXRWaWV3QkJveChwUGFnZVZpZXcsIHBBbm5vdCkuQ29udGFpbnMoKGludClwb2ludC54LCAoaW50KXBvaW50LnkpKQorCQl7CisJCQlwRG9jdW1lbnQtPlNldEZvY3VzQW5ub3QocEFubm90KTsKKwkJfQorCQlicmVhazsKKwlkZWZhdWx0OgorCQlwRG9jdW1lbnQtPlNldEZvY3VzQW5ub3QocEFubm90KTsKKwkJYnJlYWs7CisJfQorCQorCUZYX0JPT0wgYlJldCA9IEZBTFNFOworCQorCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkKKwl7CisJCWJSZXQgPSBwRm9ybUZpbGxlci0+T25MQnV0dG9uVXAocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOworCX0KKworCWlmIChwRG9jdW1lbnQtPkdldEZvY3VzQW5ub3QoKSA9PSBwQW5ub3QpCisJeworCQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7CisJCUZYX0JPT0wgYlJlc2V0ID0gRkFMU0U7CisJCU9uQnV0dG9uVXAocFdpZGdldCwgcFBhZ2VWaWV3LCBiUmVzZXQsIGJFeGl0LG5GbGFncyk7CisJCWlmIChiRXhpdCkgcmV0dXJuIFRSVUU7CisJfQorCXJldHVybiBiUmV0OworfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uQnV0dG9uVXAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYlJlc2V0LCBGWF9CT09MJiBiRXhpdCxGWF9VSU5UIG5GbGFnKQoreworCUFTU0VSVChwV2lkZ2V0ICE9IE5VTEwpOworCQorCWlmICghbV9iTm90aWZ5aW5nKQorCXsKKwkJaWYgKHBXaWRnZXQtPkdldEFBY3Rpb24oQ1BERl9BQWN0aW9uOjpCdXR0b25VcCkpCisJCXsKKwkJCW1fYk5vdGlmeWluZyA9IFRSVUU7CisJCQlpbnQgbkFnZSA9IHBXaWRnZXQtPkdldEFwcGVhcmFuY2VBZ2UoKTsKKwkJCWludCBuVmFsdWVBZ2UgPSBwV2lkZ2V0LT5HZXRWYWx1ZUFnZSgpOworCQkJCisJCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworLy8gCQkJQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldyA9IHBQYWdlVmlldy0+R2V0RG9jVmlldygpOworLy8gCQkJQVNTRVJUKHBEb2NWaWV3ICE9IE5VTEwpOworCQkJCisJCQkKKwkJCQorCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhOworCQkJZmEuYk1vZGlmaWVyID0gbV9wQXBwLT5GRklfSXNDVFJMS2V5RG93bihuRmxhZyk7CisgCQkJZmEuYlNoaWZ0ID0gbV9wQXBwLT5GRklfSXNTSElGVEtleURvd24obkZsYWcpOworCisJCQlwV2lkZ2V0LT5PbkFBY3Rpb24oQ1BERl9BQWN0aW9uOjpCdXR0b25VcCwgZmEsIHBQYWdlVmlldyk7CisJCQltX2JOb3RpZnlpbmcgPSBGQUxTRTsKKwkJCQorCQkJaWYgKCFJc1ZhbGlkQW5ub3QocFBhZ2VWaWV3LCBwV2lkZ2V0KSkKKwkJCXsKKwkJCQliRXhpdCA9IFRSVUU7CisJCQkJcmV0dXJuOworCQkJfQorCQkJCisJCQlpZiAobkFnZSAhPSBwV2lkZ2V0LT5HZXRBcHBlYXJhbmNlQWdlKCkpCisJCQl7CisJCQkJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBXaWRnZXQsIEZBTFNFKSkKKwkJCQl7CisJCQkJCXBGb3JtRmlsbGVyLT5SZXNldFBERldpbmRvdyhwUGFnZVZpZXcsIG5WYWx1ZUFnZSA9PSBwV2lkZ2V0LT5HZXRWYWx1ZUFnZSgpKTsKKwkJCQl9CisJCQkJCisJCQkJYlJlc2V0ID0gVFJVRTsKKwkJCX0KKwkJfQorCX0KK30KKworRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpPbkxCdXR0b25EYmxDbGsoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7CisKKwlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJeworCQlyZXR1cm4gcEZvcm1GaWxsZXItPk9uTEJ1dHRvbkRibENsayhwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6Ok9uTW91c2VNb3ZlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOworCisJLy9jaGFuZ2UgY3Vyc29yCisJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgVFJVRSkpCisJeworCQlyZXR1cm4gcEZvcm1GaWxsZXItPk9uTW91c2VNb3ZlKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6T25Nb3VzZVdoZWVsKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7CisKKwlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJeworCQlyZXR1cm4gcEZvcm1GaWxsZXItPk9uTW91c2VXaGVlbChwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCB6RGVsdGEsIHBvaW50KTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6T25SQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsKKworCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkKKwl7CisJCXJldHVybiBwRm9ybUZpbGxlci0+T25SQnV0dG9uRG93bihwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6Ok9uUkJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOworCisJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQorCXsKKwkJcmV0dXJuIHBGb3JtRmlsbGVyLT5PblJCdXR0b25VcChwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6Ok9uUkJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsKKworCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkKKwl7CisJCXJldHVybiBwRm9ybUZpbGxlci0+T25SQnV0dG9uRGJsQ2xrKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6T25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuS2V5Q29kZSwgRlhfVUlOVCBuRmxhZ3MpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQocEFubm90LT5HZXRQREZBbm5vdCgpLT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpOworCisJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQorCXsKKwkJcmV0dXJuIHBGb3JtRmlsbGVyLT5PbktleURvd24ocEFubm90LCBuS2V5Q29kZSwgbkZsYWdzKTsJCisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsKKworCWlmIChuQ2hhciA9PSBGV0xfVktFWV9UYWIpIHJldHVybiBUUlVFOworCisJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgRkFMU0UpKQorCXsKKwkJcmV0dXJuIHBGb3JtRmlsbGVyLT5PbkNoYXIocEFubm90LCBuQ2hhciwgbkZsYWdzKTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6T25EZVNlbGVjdGVkKENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7CisKKwlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocEFubm90LCBGQUxTRSkpCisJeworCQlwRm9ybUZpbGxlci0+T25EZVNlbGVjdGVkKHBBbm5vdCk7CisJfQorfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uU2VsZWN0ZWQoQ1BERlNES19Bbm5vdCogcEFubm90KQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsKKworCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkKKwl7CisJCXBGb3JtRmlsbGVyLT5PblNlbGVjdGVkKHBBbm5vdCk7CisJfQorfQorCitGWF9CT09MIENGRkxfSUZvcm1GaWxsZXI6Ok9uU2V0Rm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LEZYX1VJTlQgbkZsYWcpCit7CisJaWYoIXBBbm5vdCkgcmV0dXJuIEZBTFNFOworCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7CisKKwlpZiAoIW1fYk5vdGlmeWluZykKKwl7CisJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7CisgCQlpZiAocFdpZGdldC0+R2V0QUFjdGlvbihDUERGX0FBY3Rpb246OkdldEZvY3VzKSkKKyAJCXsKKyAgCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsKKwkJCXBXaWRnZXQtPkdldEFwcGVhcmFuY2VBZ2UoKTsKKwkJCWludCBuVmFsdWVBZ2UgPSBwV2lkZ2V0LT5HZXRWYWx1ZUFnZSgpOworIAkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsKKyAKKyAKKyAJCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwQW5ub3QtPkdldFBhZ2VWaWV3KCk7CisgCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKyAJCQkKKyAJCQlQREZTREtfRmllbGRBY3Rpb24gZmE7CisJCQlmYS5iTW9kaWZpZXIgPSBtX3BBcHAtPkZGSV9Jc0NUUkxLZXlEb3duKG5GbGFnKTsKKyAJCQlmYS5iU2hpZnQgPSBtX3BBcHAtPkZGSV9Jc1NISUZUS2V5RG93bihuRmxhZyk7CisKKyAKKyAJCQlDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwV2lkZ2V0LCBUUlVFKTsKKyAJCQlpZighcEZvcm1GaWxsZXIpIHJldHVybiBGQUxTRTsKKyAJCQlwRm9ybUZpbGxlci0+R2V0QWN0aW9uRGF0YShwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6R2V0Rm9jdXMsIGZhKTsKKyAKKyAJCQlwV2lkZ2V0LT5PbkFBY3Rpb24oQ1BERl9BQWN0aW9uOjpHZXRGb2N1cywgZmEsIHBQYWdlVmlldyk7CisgCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7CisgCQkJCisgLy8JCQlpZiAoIUlzVmFsaWRBbm5vdChtX3BBcHAsIHBEb2N1bWVudCwgcERvY1ZpZXcsIHBQYWdlVmlldywgcEFubm90KSkgcmV0dXJuIEZBTFNFOworIAorIAkJCWlmIChwV2lkZ2V0LT5Jc0FwcE1vZGlmaWVkKCkpCisgCQkJeworIAkJCQlpZiAoQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocFdpZGdldCwgRkFMU0UpKQorIAkJCQl7CisgCQkJCQlwRm9ybUZpbGxlci0+UmVzZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBuVmFsdWVBZ2UgPT0gcFdpZGdldC0+R2V0VmFsdWVBZ2UoKSk7CisgCQkJCX0KKyAJCQl9CisJCX0KKwl9CisJCisJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBBbm5vdCwgVFJVRSkpCisJeworCQlpZiAocEZvcm1GaWxsZXItPk9uU2V0Rm9jdXMocEFubm90LCBuRmxhZykpCisJCXsKKwkJCXJldHVybiBUUlVFOworCQl9CisJCWVsc2UKKwkJCXJldHVybiBGQUxTRTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpPbktpbGxGb2N1cyhDUERGU0RLX0Fubm90KiBwQW5ub3QsRlhfVUlOVCBuRmxhZykKK3sKKwlpZighcEFubm90KSByZXR1cm4gRkFMU0U7CisJQVNTRVJUKHBBbm5vdC0+R2V0UERGQW5ub3QoKS0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKTsKKworCWlmIChDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwQW5ub3QsIEZBTFNFKSkKKwl7CisJCWlmIChwRm9ybUZpbGxlci0+T25LaWxsRm9jdXMocEFubm90LCBuRmxhZykpCisJCXsKKyAJCQlpZiAoIW1fYk5vdGlmeWluZykKKyAJCQl7CisgCQkJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7CisgCQkJCWlmIChwV2lkZ2V0LT5HZXRBQWN0aW9uKENQREZfQUFjdGlvbjo6TG9zZUZvY3VzKSkKKyAJCQkJeworIAkJCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsKKyAJCQkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsKKyAKKyAJCQkJCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBXaWRnZXQtPkdldFBhZ2VWaWV3KCk7CisgCQkJCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworIAorIAkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhOworCQkJCQlmYS5iTW9kaWZpZXIgPSBtX3BBcHAtPkZGSV9Jc0NUUkxLZXlEb3duKG5GbGFnKTsKKyAJCQkJCWZhLmJTaGlmdCA9IG1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKTsKKyAKKyAJCQkJCXBGb3JtRmlsbGVyLT5HZXRBY3Rpb25EYXRhKHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpMb3NlRm9jdXMsIGZhKTsKKyAKKyAJCQkJCXBXaWRnZXQtPk9uQUFjdGlvbihDUERGX0FBY3Rpb246Okxvc2VGb2N1cywgZmEsIHBQYWdlVmlldyk7CisgCQkJCQltX2JOb3RpZnlpbmcgPSBGQUxTRTsKKyAKKyAJCQkJfQorIAkJCX0KKwkJfQorCQllbHNlCisJCQlyZXR1cm4gRkFMU0U7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9JRm9ybUZpbGxlcjo6SXNWaXNpYmxlKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0KQoreworCXJldHVybiBwV2lkZ2V0LT5Jc1Zpc2libGUoKTsKK30KKworRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpJc1JlYWRPbmx5KENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0KQoreworCUFTU0VSVChwV2lkZ2V0ICE9IE5VTEwpOworCisJaW50IG5GaWVsZEZsYWdzID0gcFdpZGdldC0+R2V0RmllbGRGbGFncygpOworCisJcmV0dXJuIChuRmllbGRGbGFncyAmIEZJRUxERkxBR19SRUFET05MWSkgPT0gRklFTERGTEFHX1JFQURPTkxZOworfQorCitGWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OklzRmlsbGluZ0FsbG93ZWQoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpCit7CisJQVNTRVJUKHBXaWRnZXQgIT0gTlVMTCk7CisKKwlpZiAocFdpZGdldC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX1BVU0hCVVRUT04pCisJCXJldHVybiBUUlVFOworIAllbHNlCisgCXsKKyAJCUNQREZfUGFnZSogcFBhZ2UgPSBwV2lkZ2V0LT5HZXRQREZQYWdlKCk7CisgCQlBU1NFUlQocFBhZ2UgIT0gTlVMTCk7CisgCisgCQlDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBwUGFnZS0+bV9wRG9jdW1lbnQ7CisgCQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworIAorCQlGWF9EV09SRCBkd1Blcm1pc3Npb25zID0gcERvY3VtZW50LT5HZXRVc2VyUGVybWlzc2lvbnMoKTsKKyAJCXJldHVybiAoZHdQZXJtaXNzaW9ucyZGUERGUEVSTV9GSUxMX0ZPUk0pIHx8IAorIAkJCQkoZHdQZXJtaXNzaW9ucyZGUERGUEVSTV9BTk5PVF9GT1JNKSB8fCAKKyAJCQkoZHdQZXJtaXNzaW9ucyZGUERGUEVSTV9NT0RJRlkpOworIAl9CisJcmV0dXJuIFRSVUU7CQorfQorCitDRkZMX0Zvcm1GaWxsZXIqIENGRkxfSUZvcm1GaWxsZXI6OkdldEZvcm1GaWxsZXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9CT09MIGJSZWdpc3RlcikKK3sKKy8vIAlBU1NFUlQocEFubm90ICE9IE5VTEwpOworLy8gCUFTU0VSVChwQW5ub3QtPkdldFBERkFubm90KCktPkdldFN1YlR5cGUoKSA9PSAiV2lkZ2V0Iik7CisKKwlDRkZMX0Zvcm1GaWxsZXIgKiBwRm9ybUZpbGxlciA9IE5VTEw7CisJbV9NYXBzLkxvb2t1cChwQW5ub3QsIHBGb3JtRmlsbGVyKTsKKworCWlmIChwRm9ybUZpbGxlcikKKwkJcmV0dXJuIHBGb3JtRmlsbGVyOworCisJaWYgKGJSZWdpc3RlcikKKwl7CisJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7CQkKKworCQlpbnQgbkZpZWxkVHlwZSA9IHBXaWRnZXQtPkdldEZpZWxkVHlwZSgpOworCQlzd2l0Y2gobkZpZWxkVHlwZSkKKwkJeworIAkJY2FzZSBGSUVMRFRZUEVfUFVTSEJVVFRPTjoKKyAJCQlwRm9ybUZpbGxlciA9IG5ldyBDRkZMX1B1c2hCdXR0b24obV9wQXBwLCBwV2lkZ2V0KTsKKyAJCQlicmVhazsKKwkJY2FzZSBGSUVMRFRZUEVfQ0hFQ0tCT1g6CisJCQlwRm9ybUZpbGxlciA9IG5ldyBDRkZMX0NoZWNrQm94KG1fcEFwcCwgcFdpZGdldCk7CisJCQlicmVhazsKKyAJCWNhc2UgRklFTERUWVBFX1JBRElPQlVUVE9OOgorIAkJCXBGb3JtRmlsbGVyID0gbmV3IENGRkxfUmFkaW9CdXR0b24obV9wQXBwLCBwV2lkZ2V0KTsKKyAJCQlicmVhazsKKyAJCWNhc2UgRklFTERUWVBFX1RFWFRGSUVMRDoKKwkJCXBGb3JtRmlsbGVyID0gbmV3IENGRkxfVGV4dEZpZWxkKG1fcEFwcCwgcFdpZGdldCk7CisJCQlicmVhazsKKwkJY2FzZSBGSUVMRFRZUEVfTElTVEJPWDoKKwkJCXBGb3JtRmlsbGVyID0gbmV3IENGRkxfTGlzdEJveChtX3BBcHAsIHBXaWRnZXQpOworCQkJYnJlYWs7CisJCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOgorCQkJcEZvcm1GaWxsZXIgPSBuZXcgQ0ZGTF9Db21ib0JveChtX3BBcHAsIHBXaWRnZXQpOworCQkJYnJlYWs7CisJCWNhc2UgRklFTERUWVBFX1VOS05PV046CisJCWRlZmF1bHQ6CisJCQlwRm9ybUZpbGxlciA9IE5VTEw7CisJCQlicmVhazsKKwkJfQorCisJCWlmIChwRm9ybUZpbGxlcikKKwkJeworCQkJbV9NYXBzLlNldEF0KHBBbm5vdCwgcEZvcm1GaWxsZXIpOworCQl9CisJfQorCisJcmV0dXJuIHBGb3JtRmlsbGVyOworfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6OlJlbW92ZUZvcm1GaWxsZXIoQ1BERlNES19Bbm5vdCogcEFubm90KQoreworCWlmICggcEFubm90ICE9IE5VTEwgKQorCXsKKwkJVW5SZWdpc3RlckZvcm1GaWxsZXIoIHBBbm5vdCApOworCX0KK30KKwordm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpVblJlZ2lzdGVyRm9ybUZpbGxlcihDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJQ0ZGTF9Gb3JtRmlsbGVyICogcEZvcm1GaWxsZXIgPSBOVUxMOworCisJaWYgKG1fTWFwcy5Mb29rdXAocEFubm90LHBGb3JtRmlsbGVyKSkKKwl7CisJCWlmIChwRm9ybUZpbGxlcikKKwkJCWRlbGV0ZSBwRm9ybUZpbGxlcjsKKwkJbV9NYXBzLlJlbW92ZUtleShwQW5ub3QpOworCX0KK30KKwordm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpTZXRGb2N1c0Fubm90VGFiKENQREZTREtfQW5ub3QqIHBXaWRnZXQsIEZYX0JPT0wgYlNhbWVGaWVsZCwgRlhfQk9PTCBiTmV4dCkKK3sKKworfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6OlF1ZXJ5V2hlcmVQb3B1cCh2b2lkKiBwUHJpdmF0ZURhdGEsIEZYX0ZMT0FUIGZQb3B1cE1pbixGWF9GTE9BVCBmUG9wdXBNYXgsIEZYX0lOVDMyICYgblJldCwgRlhfRkxPQVQgJiBmUG9wdXBSZXQpCit7CisJQVNTRVJUKHBQcml2YXRlRGF0YSAhPSBOVUxMKTsKKworCUNGRkxfUHJpdmF0ZURhdGEqIHBEYXRhID0gKENGRkxfUHJpdmF0ZURhdGEqKXBQcml2YXRlRGF0YTsKKworCQorCisKKwlDUERGX1JlY3QgcmNQYWdlVmlldygwLDAsMCwwKTsKKwlyY1BhZ2VWaWV3LnJpZ2h0ID0gcERhdGEtPnBXaWRnZXQtPkdldFBERlBhZ2UoKS0+R2V0UGFnZVdpZHRoKCk7CisJcmNQYWdlVmlldy5ib3R0b20gPSBwRGF0YS0+cFdpZGdldC0+R2V0UERGUGFnZSgpLT5HZXRQYWdlSGVpZ2h0KCk7CisJcmNQYWdlVmlldy5Ob3JtYWxpemUoKTsKKworCisJQVNTRVJUKHBEYXRhLT5wV2lkZ2V0ICE9IE5VTEwpOworCUNQREZfUmVjdCByY0Fubm90ID0gcERhdGEtPnBXaWRnZXQtPkdldFJlY3QoKTsKKworCUZYX0ZMT0FUIGZUb3AgPSAwLjBmOworCUZYX0ZMT0FUIGZCb3R0b20gPSAwLjBmOworCisJQ1BERlNES19XaWRnZXQgKiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwRGF0YS0+cFdpZGdldDsKKwlzd2l0Y2ggKHBXaWRnZXQtPkdldFJvdGF0ZSgpIC8gOTApCisJeworCWRlZmF1bHQ6CisJY2FzZSAwOgorCQlmVG9wID0gcmNQYWdlVmlldy50b3AgLSByY0Fubm90LnRvcDsKKwkJZkJvdHRvbSA9IHJjQW5ub3QuYm90dG9tIC0gcmNQYWdlVmlldy5ib3R0b207CisJCWJyZWFrOworCWNhc2UgMToKKwkJZlRvcCA9IHJjQW5ub3QubGVmdCAtIHJjUGFnZVZpZXcubGVmdDsKKwkJZkJvdHRvbSA9IHJjUGFnZVZpZXcucmlnaHQgLSByY0Fubm90LnJpZ2h0OworCQlicmVhazsKKwljYXNlIDI6CisJCWZUb3AgPSByY0Fubm90LmJvdHRvbSAtIHJjUGFnZVZpZXcuYm90dG9tOworCQlmQm90dG9tID0gcmNQYWdlVmlldy50b3AgLSByY0Fubm90LnRvcDsKKwkJYnJlYWs7CisJY2FzZSAzOgorCQlmVG9wID0gcmNQYWdlVmlldy5yaWdodCAtIHJjQW5ub3QucmlnaHQ7CisJCWZCb3R0b20gPSByY0Fubm90LmxlZnQgLSByY1BhZ2VWaWV3LmxlZnQ7CisJCWJyZWFrOworCX0KKworCUZYX0ZMT0FUIGZGYWN0SGVpZ2h0ID0gMDsKKwlGWF9CT09MIGJCb3R0b20gPSBUUlVFOworCUZYX0ZMT0FUIGZNYXhMaXN0Qm94SGVpZ2h0ID0gMDsKKwlpZiAoZlBvcHVwTWF4ID4gRkZMX01BWExJU1RCT1hIRUlHSFQpCisJeworCQlpZiAoZlBvcHVwTWluID4gRkZMX01BWExJU1RCT1hIRUlHSFQpCisJCXsKKwkJCWZNYXhMaXN0Qm94SGVpZ2h0ID0gZlBvcHVwTWluOworCQl9CisJCWVsc2UKKwkJeworCQkJZk1heExpc3RCb3hIZWlnaHQgPSBGRkxfTUFYTElTVEJPWEhFSUdIVDsKKwkJfQorCX0KKwllbHNlCisJCWZNYXhMaXN0Qm94SGVpZ2h0ID0gZlBvcHVwTWF4OworCisJaWYgKGZCb3R0b20gPiBmTWF4TGlzdEJveEhlaWdodCkKKwl7CisJCWZGYWN0SGVpZ2h0ID0gZk1heExpc3RCb3hIZWlnaHQ7CisJCWJCb3R0b20gPSBUUlVFOworCX0KKwllbHNlCisJeworCQlpZiAoZlRvcCA+IGZNYXhMaXN0Qm94SGVpZ2h0KQorCQl7CisJCQlmRmFjdEhlaWdodCA9IGZNYXhMaXN0Qm94SGVpZ2h0OworCQkJYkJvdHRvbSA9IEZBTFNFOworCQl9CisJCWVsc2UKKwkJeworCQkJaWYgKGZUb3AgPiBmQm90dG9tKQorCQkJeworCQkJCWZGYWN0SGVpZ2h0ID0gZlRvcDsKKwkJCQliQm90dG9tID0gRkFMU0U7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJZkZhY3RIZWlnaHQgPSBmQm90dG9tOworCQkJCWJCb3R0b20gPSBUUlVFOworCQkJfQorCQl9CisJfQorCisJblJldCA9IGJCb3R0b20gPyAwIDogMTsKKwlmUG9wdXBSZXQgPSBmRmFjdEhlaWdodDsKK30KKwordm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpPblNldFdpbmRvd1JlY3Qodm9pZCogcFByaXZhdGVEYXRhLCBjb25zdCBDUERGX1JlY3QgJiByY1dpbmRvdykKK3sKKwlBU1NFUlQocFByaXZhdGVEYXRhICE9IE5VTEwpOworCisJQ0ZGTF9Qcml2YXRlRGF0YSogcERhdGEgPSAoQ0ZGTF9Qcml2YXRlRGF0YSopcFByaXZhdGVEYXRhOworCisJaWYgKENGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBEYXRhLT5wV2lkZ2V0LCBUUlVFKSkKKwl7CisKKwkJQ1BERl9SZWN0IHJjT2xkID0gcEZvcm1GaWxsZXItPlBXTHRvRkZMKHBGb3JtRmlsbGVyLT5HZXRXaW5kb3dSZWN0KHBEYXRhLT5wUGFnZVZpZXcpKTsKKwkJQ1BERl9SZWN0IHJjTmV3ID0gcEZvcm1GaWxsZXItPlBXTHRvRkZMKHJjV2luZG93KTsKKwkJcEZvcm1GaWxsZXItPlNldFdpbmRvd1JlY3QocERhdGEtPnBQYWdlVmlldywgcmNXaW5kb3cpOworCisJCUNQREZfUmVjdCB1blJlY3QgPSByY09sZDsKKwkJdW5SZWN0LlVuaW9uKHJjTmV3KTsKKwkJLy9GWF9SRUNUIHJjUmVjdCA9IHVuUmVjdC5HZXRPdXR0ZXJSZWN0KCk7CisJCXVuUmVjdC5sZWZ0ID0gKEZYX0ZMT0FUKSh1blJlY3QubGVmdCAtIDAuNSk7CisJCXVuUmVjdC5yaWdodCA9IChGWF9GTE9BVCkodW5SZWN0LnJpZ2h0ICsgMC41KTsKKwkJdW5SZWN0LnRvcCA9IChGWF9GTE9BVCkodW5SZWN0LnRvcCArIDAuNSk7CisJCXVuUmVjdC5ib3R0b20gPSAoRlhfRkxPQVQpKHVuUmVjdC5ib3R0b20gLTAuNSk7CisJCW1fcEFwcC0+RkZJX0ludmFsaWRhdGUocERhdGEtPnBXaWRnZXQtPkdldFBERlBhZ2UoKSwgdW5SZWN0LmxlZnQsIHVuUmVjdC50b3AsIHVuUmVjdC5yaWdodCwgdW5SZWN0LmJvdHRvbSk7CisJfQorfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uS2V5U3Ryb2tlKEZYX0JPT0wgYkVkaXRPckxpc3QsIHZvaWQqIHBQcml2YXRlRGF0YSwgRlhfSU5UMzIgbktleUNvZGUsIENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsIAorCQkJCQkJCQkgICBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIEZYX0JPT0wgYktleURvd24sIAorCQkJCQkJCQkgICBGWF9CT09MICYgYlJDLCBGWF9CT09MICYgYkV4aXQpCit7CisJQVNTRVJUKHBQcml2YXRlRGF0YSAhPSBOVUxMKTsKKwlDRkZMX1ByaXZhdGVEYXRhKiBwRGF0YSA9IChDRkZMX1ByaXZhdGVEYXRhKilwUHJpdmF0ZURhdGE7CisJQVNTRVJUKHBEYXRhLT5wV2lkZ2V0ICE9IE5VTEwpOworCisJQ0ZGTF9Gb3JtRmlsbGVyKiBwRm9ybUZpbGxlciA9IEdldEZvcm1GaWxsZXIocERhdGEtPnBXaWRnZXQsIEZBTFNFKTsKKwlBU1NFUlQocEZvcm1GaWxsZXIgIT0gTlVMTCk7CisKKwlwRm9ybUZpbGxlci0+T25LZXlTdHJva2UoYktleURvd24pOworfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uS2V5U3Ryb2tlQ29tbWl0KENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wmIGJSQywgRlhfQk9PTCYgYkV4aXQsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmICghbV9iTm90aWZ5aW5nKQorCXsKKwkJQVNTRVJUKHBXaWRnZXQgIT0gTlVMTCk7CisJCWlmIChwV2lkZ2V0LT5HZXRBQWN0aW9uKENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlKSkKKwkJeworCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsKKwkJCXBXaWRnZXQtPkNsZWFyQXBwTW9kaWZpZWQoKTsKKworCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKy8vIAkJCUNSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcgPSBwUGFnZVZpZXctPkdldERvY1ZpZXcoKTsKKy8vIAkJCUFTU0VSVChwRG9jVmlldyAhPSBOVUxMKTsKKwkJCQorCQkKKworCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhOworCQkJZmEuYk1vZGlmaWVyID0gbV9wQXBwLT5GRklfSXNDVFJMS2V5RG93bihuRmxhZyk7CisgCQkJZmEuYlNoaWZ0ID0gbV9wQXBwLT5GRklfSXNTSElGVEtleURvd24obkZsYWcpOworCQkJZmEuYldpbGxDb21taXQgPSBUUlVFOworCQkJZmEubkNvbW1pdEtleSA9IEdldENvbW1pdEtleSgpOworCQkJZmEuYktleURvd24gPSBHZXRLZXlEb3duKCk7CisJCQlmYS5iUkMgPSBUUlVFOworCisJCQlDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwV2lkZ2V0LCBGQUxTRSk7CisJCQlBU1NFUlQocEZvcm1GaWxsZXIgIT0gTlVMTCk7CisKKwkJCXBGb3JtRmlsbGVyLT5HZXRBY3Rpb25EYXRhKHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2UsIGZhKTsKKwkJCXBGb3JtRmlsbGVyLT5TYXZlU3RhdGUocFBhZ2VWaWV3KTsKKworCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhT2xkID0gZmE7CisJCQlwV2lkZ2V0LT5PbkFBY3Rpb24oQ1BERl9BQWN0aW9uOjpLZXlTdHJva2UsIGZhLCBwUGFnZVZpZXcpOworCisJCQliUkMgPSBmYS5iUkM7CisvLwkJCWJFeGl0ID0gIUlzVmFsaWRBbm5vdChtX3BBcHAsIHBEb2N1bWVudCwgcERvY1ZpZXcsIHBQYWdlVmlldywgcFdpZGdldCk7CisKKwkJCW1fYk5vdGlmeWluZyA9IEZBTFNFOworCQl9CisJfQorfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uVmFsaWRhdGUoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCYgYlJDLCBGWF9CT09MJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpCit7CisJaWYgKCFtX2JOb3RpZnlpbmcpCisJeworCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsKKwkJaWYgKHBXaWRnZXQtPkdldEFBY3Rpb24oQ1BERl9BQWN0aW9uOjpWYWxpZGF0ZSkpCisJCXsKKwkJCW1fYk5vdGlmeWluZyA9IFRSVUU7CisJCQlwV2lkZ2V0LT5DbGVhckFwcE1vZGlmaWVkKCk7CisKKwkJCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7CisvLyAJCQlDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3ID0gcFBhZ2VWaWV3LT5HZXREb2NWaWV3KCk7CisvLyAJCQlBU1NFUlQocERvY1ZpZXcgIT0gTlVMTCk7CisJCQkKKwkJCQorCisJCQlQREZTREtfRmllbGRBY3Rpb24gZmE7CisJCQlmYS5iTW9kaWZpZXIgPSBtX3BBcHAtPkZGSV9Jc0NUUkxLZXlEb3duKG5GbGFnKTsKKyAJCQlmYS5iU2hpZnQgPSBtX3BBcHAtPkZGSV9Jc1NISUZUS2V5RG93bihuRmxhZyk7CisJCQlmYS5iS2V5RG93biA9IEdldEtleURvd24oKTsKKwkJCWZhLmJSQyA9IFRSVUU7CisKKwkJCUNGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBXaWRnZXQsIEZBTFNFKTsKKwkJCUFTU0VSVChwRm9ybUZpbGxlciAhPSBOVUxMKTsKKworCQkJcEZvcm1GaWxsZXItPkdldEFjdGlvbkRhdGEocFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OlZhbGlkYXRlLCBmYSk7CisJCQlwRm9ybUZpbGxlci0+U2F2ZVN0YXRlKHBQYWdlVmlldyk7CisKKwkJCVBERlNES19GaWVsZEFjdGlvbiBmYU9sZCA9IGZhOworCQkJcFdpZGdldC0+T25BQWN0aW9uKENQREZfQUFjdGlvbjo6VmFsaWRhdGUsIGZhLCBwUGFnZVZpZXcpOworCisJCQliUkMgPSBmYS5iUkM7CisvLwkJCWJFeGl0ID0gIUlzVmFsaWRBbm5vdChtX3BBcHAsIHBEb2N1bWVudCwgcERvY1ZpZXcsIHBQYWdlVmlldywgcFdpZGdldCk7CisKKwkJCW1fYk5vdGlmeWluZyA9IEZBTFNFOworCQl9CisJfQorfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6Ok9uQ2FsY3VsYXRlKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wmIGJFeGl0LCBGWF9EV09SRCBuRmxhZykKK3sKKwlpZiAoIW1fYk5vdGlmeWluZykKKwl7CisJCUFTU0VSVChwV2lkZ2V0ICE9IE5VTEwpOworCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworLy8gCQlDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3ID0gcFBhZ2VWaWV3LT5HZXREb2NWaWV3KCk7CisvLyAJCUFTU0VSVChwRG9jVmlldyAhPSBOVUxMKTsKKwkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50ID0gcFBhZ2VWaWV3LT5HZXRTREtEb2N1bWVudCgpOworCQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCQlwSW50ZXJGb3JtLT5PbkNhbGN1bGF0ZShwV2lkZ2V0LT5HZXRGb3JtRmllbGQoKSk7CisKKy8vCQliRXhpdCA9ICFJc1ZhbGlkQW5ub3QobV9wQXBwLCBwRG9jdW1lbnQsIHBEb2NWaWV3LCBwUGFnZVZpZXcsIHBXaWRnZXQpOworCisJCW1fYk5vdGlmeWluZyA9IEZBTFNFOworCX0KK30KKwordm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpPbkZvcm1hdChDUERGU0RLX1dpZGdldCogcFdpZGdldCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpCit7CisJaWYgKCFtX2JOb3RpZnlpbmcpCisJeworCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsKKwkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKy8vIAkJQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldyA9IHBQYWdlVmlldy0+R2V0RG9jVmlldygpOworLy8gCQlBU1NFUlQocERvY1ZpZXcgIT0gTlVMTCk7CisJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCA9IHBQYWdlVmlldy0+R2V0U0RLRG9jdW1lbnQoKTsKKwkJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKworCQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwkJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwkJRlhfQk9PTCBiRm9ybWF0ZWQgPSBGQUxTRTsKKwkJQ0ZYX1dpZGVTdHJpbmcgc1ZhbHVlID0gcEludGVyRm9ybS0+T25Gb3JtYXQocFdpZGdldC0+R2V0Rm9ybUZpZWxkKCksIEdldENvbW1pdEtleSgpLCBiRm9ybWF0ZWQpOworCisvLwkJYkV4aXQgPSAhSXNWYWxpZEFubm90KG1fcEFwcCwgcERvY3VtZW50LCBwRG9jVmlldywgcFBhZ2VWaWV3LCBwV2lkZ2V0KTsKKworCQlpZiAoYkV4aXQpIHJldHVybjsKKworCQlpZiAoYkZvcm1hdGVkKQorCQl7CisJCQlwSW50ZXJGb3JtLT5SZXNldEZpZWxkQXBwZWFyYW5jZShwV2lkZ2V0LT5HZXRGb3JtRmllbGQoKSwgc1ZhbHVlLCBUUlVFKTsKKwkJCXBJbnRlckZvcm0tPlVwZGF0ZUZpZWxkKHBXaWRnZXQtPkdldEZvcm1GaWVsZCgpKTsKKwkJfQorCisJCW1fYk5vdGlmeWluZyA9IEZBTFNFOworCX0KK30KKworLy8gTFJFU1VMVCBDQUxMQkFDSyBDRkZMX0lGb3JtRmlsbGVyOjpGRkxfV25kUHJvYygKKy8vIAkJCQkJCQkJCSAgaW50IGNvZGUsICAgICAgIC8vIGhvb2sgY29kZQorLy8gCQkJCQkJCQkJICBXUEFSQU0gd1BhcmFtLCAgLy8gdmlydHVhbC1rZXkgY29kZQorLy8gCQkJCQkJCQkJICBMUEFSQU0gbFBhcmFtICAgLy8ga2V5c3Ryb2tlLW1lc3NhZ2UgaW5mb3JtYXRpb24KKy8vIAkJCQkJCQkJCQkpCisvLyB7CisvLyAJaWYgKGNvZGUgIT0gSENfQUNUSU9OKQorLy8gCXsKKy8vIAkJcmV0dXJuIENhbGxOZXh0SG9va0V4IChtX2hvb2tTaGVldCwgY29kZSwgd1BhcmFtLCBsUGFyYW0pOworLy8gCX0KKy8vIAorLy8gCUZYU1lTX21lbWNweSgmZ19Nc2csICh2b2lkKilsUGFyYW0sIHNpemVvZihNU0cpKTsJCisvLyAKKy8vIAlyZXR1cm4gMDsKKy8vIH0KKworLy8gTVNHCUNGRkxfSUZvcm1GaWxsZXI6OkdldExhc3RNZXNzYWdlKCkKKy8vIHsKKy8vIAlyZXR1cm4gZ19Nc2c7CisvLyB9CisKK2ludCBDRkZMX0lGb3JtRmlsbGVyOjpHZXRDb21taXRLZXkoKQoreworLy8JTVNHIG1zZyA9IENGRkxfSUZvcm1GaWxsZXI6OkdldExhc3RNZXNzYWdlKCk7CisKKwlpbnQgbkNvbW1pdEtleSA9IDA7CisvLyAJc3dpdGNoIChtc2cubWVzc2FnZSkKKy8vIAl7CisvLyAJY2FzZSBXTV9MQlVUVE9ORE9XTjoKKy8vIAljYXNlIFdNX0xCVVRUT05VUDoKKy8vIAkJbkNvbW1pdEtleSA9IDE7CisvLyAJCWJyZWFrOworLy8gCWNhc2UgV01fS0VZRE9XTjoKKy8vIAkJc3dpdGNoIChtc2cud1BhcmFtKQorLy8gCQl7CisvLyAJCWNhc2UgVktfUkVUVVJOOgorLy8gCQkJbkNvbW1pdEtleSA9IDI7CisvLyAJCQlicmVhazsKKy8vIAkJY2FzZSBWS19UQUI6CisvLyAJCQluQ29tbWl0S2V5ID0gMzsKKy8vIAkJCWJyZWFrOworLy8gCQl9CisvLyAJCWJyZWFrOworLy8gCX0KKworCXJldHVybiBuQ29tbWl0S2V5OworfQorCitGWF9CT09MIENGRkxfSUZvcm1GaWxsZXI6OkdldEtleURvd24oKQoreworCXJldHVybiBUUlVFOworLy8gCU1TRyBtc2cgPSBDRkZMX0lGb3JtRmlsbGVyOjpHZXRMYXN0TWVzc2FnZSgpOworLy8gCisvLyAJcmV0dXJuIG1zZy5tZXNzYWdlID09IFdNX0tFWURPV04gfHwgbXNnLm1lc3NhZ2UgPT0gV01fQ0hBUjsKK30KKworRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpJc1ZhbGlkQW5ub3QoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisKKwlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisKKwlpZihwUGFnZVZpZXcpCisJCXJldHVybiBwUGFnZVZpZXctPklzVmFsaWRBbm5vdChwQW5ub3QtPkdldFBERkFubm90KCkpOworCWVsc2UKKwkJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6OkJlZm9yZVVuZG8oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworCit9CisKK3ZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6QmVmb3JlUmVkbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJQmVmb3JlVW5kbyhwRG9jdW1lbnQpOworfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6OkFmdGVyVW5kbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7Cit9CisKK3ZvaWQgQ0ZGTF9JRm9ybUZpbGxlcjo6QWZ0ZXJSZWRvKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKK30KKworRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpDYW5Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAlDRkZMX0lGb3JtRmlsbGVyOjpDYW5DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGRkxfSUZvcm1GaWxsZXI6OkNhblBhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKworCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpEb0NvcHkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworfQorCit2b2lkIENGRkxfSUZvcm1GaWxsZXI6OkRvQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKK30KKwordm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpEb1Bhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKworfQordm9pZCBDRkZMX0lGb3JtRmlsbGVyOjpPbkJlZm9yZUtleVN0cm9rZShGWF9CT09MIGJFZGl0T3JMaXN0LCB2b2lkKiBwUHJpdmF0ZURhdGEsIEZYX0lOVDMyIG5LZXlDb2RlLAorCQkJCQkJCQkJCQkgIENGWF9XaWRlU3RyaW5nICYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIAorCQkJCQkJCQkJCQkgIGludCBuU2VsU3RhcnQsIGludCBuU2VsRW5kLAorCQkJCQkJCQkJCUZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgJiBiUkMsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQVNTRVJUKHBQcml2YXRlRGF0YSAhPSBOVUxMKTsKKwlDRkZMX1ByaXZhdGVEYXRhKiBwRGF0YSA9IChDRkZMX1ByaXZhdGVEYXRhKilwUHJpdmF0ZURhdGE7CisJQVNTRVJUKHBEYXRhLT5wV2lkZ2V0ICE9IE5VTEwpOworCQorCUNGRkxfRm9ybUZpbGxlciogcEZvcm1GaWxsZXIgPSBHZXRGb3JtRmlsbGVyKHBEYXRhLT5wV2lkZ2V0LCBGQUxTRSk7CisJQVNTRVJUKHBGb3JtRmlsbGVyICE9IE5VTEwpOworCQorCWlmICghbV9iTm90aWZ5aW5nKQorCXsKKwkJaWYgKHBEYXRhLT5wV2lkZ2V0LT5HZXRBQWN0aW9uKENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlKSkKKwkJeworCQkJbV9iTm90aWZ5aW5nID0gVFJVRTsKKwkJCWludCBuQWdlID0gcERhdGEtPnBXaWRnZXQtPkdldEFwcGVhcmFuY2VBZ2UoKTsKKwkJCWludCBuVmFsdWVBZ2UgPSBwRGF0YS0+cFdpZGdldC0+R2V0VmFsdWVBZ2UoKTsKKworCQkJQVNTRVJUKHBEYXRhLT5wUGFnZVZpZXcgIT0gTlVMTCk7CisJCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQgID0gcERhdGEtPnBQYWdlVmlldy0+R2V0U0RLRG9jdW1lbnQoKTsKKwkJCQorCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhOworIAkJCWZhLmJNb2RpZmllciA9IG1fcEFwcC0+RkZJX0lzQ1RSTEtleURvd24obkZsYWcpOworIAkJCWZhLmJTaGlmdCA9IG1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKTsKKwkJCWZhLnNDaGFuZ2UgPSBzdHJDaGFuZ2U7CisJCQlmYS5zQ2hhbmdlRXggPSBzdHJDaGFuZ2VFeDsKKwkJCWZhLmJLZXlEb3duID0gYktleURvd247CisJCQlmYS5iV2lsbENvbW1pdCA9IEZBTFNFOworCQkJZmEuYlJDID0gVFJVRTsKKwkJCWZhLm5TZWxTdGFydCA9IG5TZWxTdGFydDsKKwkJCWZhLm5TZWxFbmQgPSBuU2VsRW5kOworCisKKwkJCXBGb3JtRmlsbGVyLT5HZXRBY3Rpb25EYXRhKHBEYXRhLT5wUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlLCBmYSk7CisJCQlwRm9ybUZpbGxlci0+U2F2ZVN0YXRlKHBEYXRhLT5wUGFnZVZpZXcpOworCQkJCisJCQlpZiAocERhdGEtPnBXaWRnZXQtPk9uQUFjdGlvbihDUERGX0FBY3Rpb246OktleVN0cm9rZSwgZmEsIHBEYXRhLT5wUGFnZVZpZXcpKQorCQkJeworCQkJCWlmICghSXNWYWxpZEFubm90KHBEYXRhLT5wUGFnZVZpZXcsIHBEYXRhLT5wV2lkZ2V0KSkKKwkJCQl7CisJCQkJCWJFeGl0ID0gVFJVRTsKKwkJCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7CisJCQkJCXJldHVybjsKKwkJCQl9CisJCQkJCisJCQkJaWYgKG5BZ2UgIT0gcERhdGEtPnBXaWRnZXQtPkdldEFwcGVhcmFuY2VBZ2UoKSkKKwkJCQl7CisJCQkJCUNQV0xfV25kKiBwV25kID0gcEZvcm1GaWxsZXItPlJlc2V0UERGV2luZG93KHBEYXRhLT5wUGFnZVZpZXcsIG5WYWx1ZUFnZSA9PSBwRGF0YS0+cFdpZGdldC0+R2V0VmFsdWVBZ2UoKSk7CisJCQkJCXBEYXRhID0gKENGRkxfUHJpdmF0ZURhdGEqKXBXbmQtPkdldEF0dGFjaGVkRGF0YSgpOworCQkJCQliRXhpdCA9IFRSVUU7CisJCQkJfQorCQkJCQorCQkJCWlmIChmYS5iUkMpCisJCQkJeworCQkJCQlwRm9ybUZpbGxlci0+U2V0QWN0aW9uRGF0YShwRGF0YS0+cFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OktleVN0cm9rZSwgZmEpOworCQkJCQliUkMgPSBGQUxTRTsKKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJcEZvcm1GaWxsZXItPlJlc3RvcmVTdGF0ZShwRGF0YS0+cFBhZ2VWaWV3KTsKKwkJCQkJYlJDID0gRkFMU0U7CisJCQkJfQorCQkJCQorCQkJCWlmIChwRG9jdW1lbnQtPkdldEZvY3VzQW5ub3QoKSAhPSBwRGF0YS0+cFdpZGdldCkKKwkJCQl7CisJCQkJCXBGb3JtRmlsbGVyLT5Db21taXREYXRhKHBEYXRhLT5wUGFnZVZpZXcsbkZsYWcpOworCQkJCQliRXhpdCA9IFRSVUU7CisJCQkJfQorCQkJfQorCQkJZWxzZQorCQkJewkJCQorCQkJCWlmICghSXNWYWxpZEFubm90KHBEYXRhLT5wUGFnZVZpZXcsIHBEYXRhLT5wV2lkZ2V0KSkKKwkJCQl7CisJCQkJCWJFeGl0ID0gVFJVRTsKKwkJCQkJbV9iTm90aWZ5aW5nID0gRkFMU0U7CisJCQkJCXJldHVybjsKKwkJCQl9CisJCQl9CisJCQkKKwkJCW1fYk5vdGlmeWluZyA9IEZBTFNFOworCQl9CisJfQorfQorCit2b2lkCUNGRkxfSUZvcm1GaWxsZXI6Ok9uQWZ0ZXJLZXlTdHJva2UoRlhfQk9PTCBiRWRpdE9yTGlzdCwgdm9pZCogcFByaXZhdGVEYXRhLCBGWF9CT09MICYgYkV4aXQsRlhfRFdPUkQgbkZsYWcpIAoreworCUFTU0VSVChwUHJpdmF0ZURhdGEgIT0gTlVMTCk7CisJQ0ZGTF9Qcml2YXRlRGF0YSogcERhdGEgPSAoQ0ZGTF9Qcml2YXRlRGF0YSopcFByaXZhdGVEYXRhOworCUFTU0VSVChwRGF0YS0+cFdpZGdldCAhPSBOVUxMKTsKKwkKKwlDRkZMX0Zvcm1GaWxsZXIqIHBGb3JtRmlsbGVyID0gR2V0Rm9ybUZpbGxlcihwRGF0YS0+cFdpZGdldCwgRkFMU0UpOworCUFTU0VSVChwRm9ybUZpbGxlciAhPSBOVUxMKTsKKwkKKwlpZiAoIWJFZGl0T3JMaXN0KQorCQlwRm9ybUZpbGxlci0+T25LZXlTdHJva2UoYkV4aXQpOworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfTGlzdEJveC5jcHAgYi9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9MaXN0Qm94LmNwcAppbmRleCA5ZGRiNmEwLi44N2FlNTUyIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9MaXN0Qm94LmNwcAorKysgYi9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9MaXN0Qm94LmNwcApAQCAtMSwzMTkgKzEsMzE5IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTGlzdEJveC5oIg0KLS8vI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTW9kdWxlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfSUZvcm1GaWxsZXIuaCINCi0vLyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1VuZG8uaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9DQkFfRm9udG1hcC5oIg0KLQ0KLQ0KLSNkZWZpbmUJRkZMX0RFRkFVTFRMSVNUQk9YRk9OVFNJWkUJCTEyLjBmDQotDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX0xpc3RCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGRkxfTGlzdEJveDo6Q0ZGTF9MaXN0Qm94KENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfQW5ub3QqIHBXaWRnZXQpIDoNCi0JQ0ZGTF9Gb3JtRmlsbGVyKHBBcHAsIHBXaWRnZXQpLA0KLQltX3BGb250TWFwKE5VTEwpDQotew0KLX0NCi0NCi1DRkZMX0xpc3RCb3g6On5DRkZMX0xpc3RCb3goKQ0KLXsNCi0JaWYgKG1fcEZvbnRNYXApDQotCXsNCi0JCWRlbGV0ZSBtX3BGb250TWFwOw0KLQkJbV9wRm9udE1hcCA9IE5VTEw7DQotCX0NCi19DQotDQotUFdMX0NSRUFURVBBUkFNCUNGRkxfTGlzdEJveDo6R2V0Q3JlYXRlUGFyYW0oKQ0KLXsNCi0JUFdMX0NSRUFURVBBUkFNIGNwID0gQ0ZGTF9Gb3JtRmlsbGVyOjpHZXRDcmVhdGVQYXJhbSgpOw0KLQ0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQlGWF9EV09SRCBkd0ZpZWxkRmxhZyA9IG1fcFdpZGdldC0+R2V0RmllbGRGbGFncygpOw0KLQkJDQotCWlmIChkd0ZpZWxkRmxhZyAmIEZJRUxERkxBR19NVUxUSVNFTEVDVCkNCi0JewkJDQotCQljcC5kd0ZsYWdzIHw9IFBMQlNfTVVMVElQTEVTRUw7DQotCX0NCi0NCi0JaWYgKGR3RmllbGRGbGFnICYgRklFTERGTEFHX0NPTU1JVE9OU0VMQ0hBTkdFKQ0KLQl7DQotCQkvL2NwLmR3RmxhZ3MgfD0gUExCU19DT01NSVRTRUxFQ1RFRFZBTFVFOw0KLQl9DQotDQotCWNwLmR3RmxhZ3MgfD0gUFdTX1ZTQ1JPTEw7DQotDQotCWlmIChjcC5kd0ZsYWdzICYgUFdTX0FVVE9GT05UU0laRSkNCi0JCWNwLmZGb250U2l6ZSA9IEZGTF9ERUZBVUxUTElTVEJPWEZPTlRTSVpFOw0KLQ0KLQlpZiAoIW1fcEZvbnRNYXApDQotCXsNCi0JCUFTU0VSVCh0aGlzLT5tX3BBcHAgIT0gTlVMTCk7DQotCQltX3BGb250TWFwID0gbmV3IENCQV9Gb250TWFwKG1fcFdpZGdldCxtX3BBcHAtPkdldFN5c0hhbmRsZXIoKSk7Ly8sIElTeXN0ZW1IYW5kbGU6OkdldFN5c3RlbUhhbmRsZXIobV9wQXBwKSk7DQotCQltX3BGb250TWFwLT5Jbml0aWFsKCk7DQotCX0NCi0JY3AucEZvbnRNYXAgPSBtX3BGb250TWFwOw0KLQ0KLQlyZXR1cm4gY3A7DQotfQ0KLQ0KLUNQV0xfV25kKiBDRkZMX0xpc3RCb3g6Ok5ld1BERldpbmRvdyhjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQlDUFdMX0xpc3RCb3gqIHBXbmQgPSBuZXcgQ1BXTF9MaXN0Qm94KCk7DQotCXBXbmQtPkF0dGFjaEZGTERhdGEodGhpcyk7DQotCXBXbmQtPkNyZWF0ZShjcCk7DQotDQotCUFTU0VSVChtX3BBcHAgIT0gTlVMTCk7DQotCUNGRkxfSUZvcm1GaWxsZXIqIHBJRm9ybUZpbGxlciA9IG1fcEFwcC0+R2V0SUZvcm1GaWxsZXIoKTsNCi0JcFduZC0+U2V0RmlsbGVyTm90aWZ5KHBJRm9ybUZpbGxlcik7DQotDQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotCQ0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX3BXaWRnZXQtPkNvdW50T3B0aW9ucygpOyBpPHN6OyBpKyspDQotCQlwV25kLT5BZGRTdHJpbmcobV9wV2lkZ2V0LT5HZXRPcHRpb25MYWJlbChpKSk7DQotCQ0KLQlpZiAocFduZC0+SGFzRmxhZyhQTEJTX01VTFRJUExFU0VMKSkNCi0Jew0KLQkJbV9PcmlnaW5TZWxlY3Rpb25zLlJlbW92ZUFsbCgpOw0KLQkJDQotCQlGWF9CT09MIGJTZXRDYXJldCA9IEZBTFNFOw0KLQkJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9wV2lkZ2V0LT5Db3VudE9wdGlvbnMoKTsgaTxzejsgaSsrKQ0KLQkJew0KLQkJCWlmIChtX3BXaWRnZXQtPklzT3B0aW9uU2VsZWN0ZWQoaSkpDQotCQkJew0KLQkJCQlpZiAoIWJTZXRDYXJldCkNCi0JCQkJew0KLQkJCQkJcFduZC0+U2V0Q2FyZXQoaSk7DQotCQkJCQliU2V0Q2FyZXQgPSBUUlVFOw0KLQkJCQl9DQotCQkJCXBXbmQtPlNlbGVjdChpKTsNCi0JCQkJbV9PcmlnaW5TZWxlY3Rpb25zLlNldEF0KGksIE5VTEwpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCWZvciAoaW50IGk9MCxzej1tX3BXaWRnZXQtPkNvdW50T3B0aW9ucygpOyBpPHN6OyBpKyspDQotCQl7DQotCQkJaWYgKG1fcFdpZGdldC0+SXNPcHRpb25TZWxlY3RlZChpKSkNCi0JCQl7DQotCQkJCXBXbmQtPlNlbGVjdChpKTsNCi0JCQkJYnJlYWs7DQotCQkJfQ0KLQkJfQ0KLQl9DQotCQ0KLQlwV25kLT5TZXRUb3BWaXNpYmxlSW5kZXgobV9wV2lkZ2V0LT5HZXRUb3BWaXNpYmxlSW5kZXgoKSk7DQotCQ0KLQlyZXR1cm4gcFduZDsNCi19DQotDQotDQotRlhfQk9PTAlDRkZMX0xpc3RCb3g6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQ0KLXsNCi0JcmV0dXJuIENGRkxfRm9ybUZpbGxlcjo6T25DaGFyKHBBbm5vdCwgbkNoYXIsIG5GbGFncyk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9MaXN0Qm94OjpJc0RhdGFDaGFuZ2VkKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotDQotCWlmIChDUFdMX0xpc3RCb3gqIHBMaXN0Qm94ID0gKENQV0xfTGlzdEJveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7DQotCQlpZiAobV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfTVVMVElTRUxFQ1QpDQotCQl7DQotCQkJaW50IG5TZWxDb3VudCA9IDA7DQotCQkJZm9yIChGWF9JTlQzMiBpPTAsc3o9cExpc3RCb3gtPkdldENvdW50KCk7IGk8c3o7IGkrKykNCi0JCQl7DQotCQkJCWlmIChwTGlzdEJveC0+SXNJdGVtU2VsZWN0ZWQoaSkpDQotCQkJCXsNCi0JCQkJCXZvaWQqIHAgPSBOVUxMOw0KLQkJCQkJaWYgKCFtX09yaWdpblNlbGVjdGlvbnMuTG9va3VwKGksIHApKQ0KLQkJCQkJCXJldHVybiBUUlVFOw0KLQ0KLQkJCQkJblNlbENvdW50Kys7DQotCQkJCX0NCi0JCQl9DQotDQotCQkJcmV0dXJuIG5TZWxDb3VudCAhPSBtX09yaWdpblNlbGVjdGlvbnMuR2V0Q291bnQoKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlyZXR1cm4gcExpc3RCb3gtPkdldEN1clNlbCgpICE9IG1fcFdpZGdldC0+R2V0U2VsZWN0ZWRJbmRleCgwKTsNCi0JCX0NCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENGRkxfTGlzdEJveDo6U2F2ZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0NCi0JaWYgKENQV0xfTGlzdEJveCogcExpc3RCb3ggPSAoQ1BXTF9MaXN0Qm94KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsNCi0JCUNGWF9JbnRBcnJheSBhT2xkU2VsZWN0LCBhTmV3U2VsZWN0Ow0KLQ0KLQkJew0KLQkJCWZvciAoaW50IGk9MCxzej1tX3BXaWRnZXQtPkNvdW50T3B0aW9ucygpOyBpPHN6OyBpKyspDQotCQkJew0KLQkJCQlpZiAobV9wV2lkZ2V0LT5Jc09wdGlvblNlbGVjdGVkKGkpKQ0KLQkJCQl7DQotCQkJCQlhT2xkU2VsZWN0LkFkZChpKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0NCi0JCQ0KLQkJRlhfSU5UMzIgbk5ld1RvcEluZGV4ID0gcExpc3RCb3gtPkdldFRvcFZpc2libGVJbmRleCgpOw0KLQ0KLQkJbV9wV2lkZ2V0LT5DbGVhclNlbGVjdGlvbihGQUxTRSk7CQ0KLQ0KLQkJaWYgKG1fcFdpZGdldC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX01VTFRJU0VMRUNUKQ0KLQkJew0KLQkJCWZvciAoRlhfSU5UMzIgaT0wLHN6PXBMaXN0Qm94LT5HZXRDb3VudCgpOyBpPHN6OyBpKyspDQotCQkJew0KLQkJCQlpZiAocExpc3RCb3gtPklzSXRlbVNlbGVjdGVkKGkpKQ0KLQkJCQl7DQotCQkJCQltX3BXaWRnZXQtPlNldE9wdGlvblNlbGVjdGlvbihpLCBUUlVFLCBGQUxTRSk7DQotCQkJCQlhTmV3U2VsZWN0LkFkZChpKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQltX3BXaWRnZXQtPlNldE9wdGlvblNlbGVjdGlvbihwTGlzdEJveC0+R2V0Q3VyU2VsKCksIFRSVUUsIEZBTFNFKTsNCi0JCQlhTmV3U2VsZWN0LkFkZChwTGlzdEJveC0+R2V0Q3VyU2VsKCkpOw0KLQkJfQ0KLQ0KLQkJbV9wV2lkZ2V0LT5TZXRUb3BWaXNpYmxlSW5kZXgobk5ld1RvcEluZGV4KTsNCi0JCW1fcFdpZGdldC0+UmVzZXRGaWVsZEFwcGVhcmFuY2UoVFJVRSk7DQotCQltX3BXaWRnZXQtPlVwZGF0ZUZpZWxkKCk7DQotCQlTZXRDaGFuZ2VNYXJrKCk7DQotCX0NCi19DQotDQotdm9pZCBDRkZMX0xpc3RCb3g6OkdldEFjdGlvbkRhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsDQotCQkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSkNCi17DQotCXN3aXRjaCAodHlwZSkNCi0Jew0KLQljYXNlIENQREZfQUFjdGlvbjo6VmFsaWRhdGU6DQotCQlpZiAobV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfTVVMVElTRUxFQ1QpDQotCQl7DQotCQkJZmEuc1ZhbHVlID0gTCIiOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChDUFdMX0xpc3RCb3gqIHBMaXN0Qm94ID0gKENQV0xfTGlzdEJveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQkJCXsNCi0JCQkJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0JCQkJRlhfSU5UMzIgbkN1clNlbCA9IHBMaXN0Qm94LT5HZXRDdXJTZWwoKTsNCi0JCQkJaWYgKG5DdXJTZWwgPj0gMCkNCi0JCQkJCWZhLnNWYWx1ZSA9IG1fcFdpZGdldC0+R2V0T3B0aW9uTGFiZWwobkN1clNlbCk7DQotCQkJfQ0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpMb3NlRm9jdXM6DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpHZXRGb2N1czoNCi0JCWlmIChtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19NVUxUSVNFTEVDVCkNCi0JCXsNCi0JCQlmYS5zVmFsdWUgPSBMIiI7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0JCQlGWF9JTlQzMiBuQ3VyU2VsID0gbV9wV2lkZ2V0LT5HZXRTZWxlY3RlZEluZGV4KDApOw0KLQkJCWlmIChuQ3VyU2VsID49IDApDQotCQkJCWZhLnNWYWx1ZSA9IG1fcFdpZGdldC0+R2V0T3B0aW9uTGFiZWwobkN1clNlbCk7DQotCQl9DQotCQlicmVhazsNCi0JZGVmYXVsdDoNCi0JCWJyZWFrOw0KLQl9DQotfQ0KLQ0KLQ0KLXZvaWQgQ0ZGTF9MaXN0Qm94OjpTZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCANCi0JCQkJCQkJCWNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmEpDQotew0KLX0NCi0NCi12b2lkIENGRkxfTGlzdEJveDo6U2F2ZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotDQotCWlmIChDUFdMX0xpc3RCb3gqIHBMaXN0Qm94ID0gKENQV0xfTGlzdEJveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7DQotCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1wTGlzdEJveC0+R2V0Q291bnQoKTsgaTxzejsgaSsrKQ0KLQkJew0KLQkJCWlmIChwTGlzdEJveC0+SXNJdGVtU2VsZWN0ZWQoaSkpDQotCQkJew0KLQkJCQltX1N0YXRlLkFkZChpKTsNCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRkZMX0xpc3RCb3g6OlJlc3RvcmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQlpZiAoQ1BXTF9MaXN0Qm94KiBwTGlzdEJveCA9IChDUFdMX0xpc3RCb3gqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0Jew0KLQkJZm9yIChpbnQgaT0wLHN6PW1fU3RhdGUuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQkJcExpc3RCb3gtPlNlbGVjdChtX1N0YXRlW2ldKTsNCi0JfQ0KLX0NCi0NCi1DUFdMX1duZCogQ0ZGTF9MaXN0Qm94OjpSZXNldFBERldpbmRvdyhDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0JPT0wgYlJlc3RvcmVWYWx1ZSkNCi17DQotCWlmIChiUmVzdG9yZVZhbHVlKQ0KLQkJU2F2ZVN0YXRlKHBQYWdlVmlldyk7DQotCQ0KLQlEZXN0cm95UERGV2luZG93KHBQYWdlVmlldyk7DQotCQ0KLQlDUFdMX1duZCogcFJldCA9IE5VTEw7DQotCQ0KLQlpZiAoYlJlc3RvcmVWYWx1ZSkNCi0Jew0KLQkJUmVzdG9yZVN0YXRlKHBQYWdlVmlldyk7DQotCQlwUmV0ID0gdGhpcy0+R2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpOw0KLQl9DQotCWVsc2UNCi0JCXBSZXQgPSB0aGlzLT5HZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBUUlVFKTsNCi0JDQotCW1fcFdpZGdldC0+VXBkYXRlRmllbGQoKTsNCi0JDQotCXJldHVybiBwUmV0Ow0KLX0NCi0NCi12b2lkIENGRkxfTGlzdEJveDo6T25LZXlTdHJva2UoRlhfQk9PTCBiS2V5RG93biwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQlpbnQgbkZsYWdzID0gbV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCk7DQotCQ0KLQlpZiAobkZsYWdzICYgRklFTERGTEFHX0NPTU1JVE9OU0VMQ0hBTkdFKQ0KLQl7DQotCQlpZiAobV9iVmFsaWQpDQotCQl7DQotCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gdGhpcy0+R2V0Q3VyUGFnZVZpZXcoKTsNCi0JCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQ0KLQkJCWlmIChDb21taXREYXRhKHBQYWdlVmlldywgbkZsYWcpKQ0KLQkJCXsNCi0JCQkJRGVzdHJveVBERldpbmRvdyhwUGFnZVZpZXcpOw0KLQkJCQltX2JWYWxpZCA9IEZBTFNFOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0xpc3RCb3guaCIKKy8vI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTW9kdWxlLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9JRm9ybUZpbGxlci5oIgorLy8jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9VbmRvLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9DQkFfRm9udG1hcC5oIgorCisKKyNkZWZpbmUJRkZMX0RFRkFVTFRMSVNUQk9YRk9OVFNJWkUJCTEyLjBmCisKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX0xpc3RCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRkZMX0xpc3RCb3g6OkNGRkxfTGlzdEJveChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwV2lkZ2V0KSA6CisJQ0ZGTF9Gb3JtRmlsbGVyKHBBcHAsIHBXaWRnZXQpLAorCW1fcEZvbnRNYXAoTlVMTCkKK3sKK30KKworQ0ZGTF9MaXN0Qm94Ojp+Q0ZGTF9MaXN0Qm94KCkKK3sKKwlpZiAobV9wRm9udE1hcCkKKwl7CisJCWRlbGV0ZSBtX3BGb250TWFwOworCQltX3BGb250TWFwID0gTlVMTDsKKwl9Cit9CisKK1BXTF9DUkVBVEVQQVJBTQlDRkZMX0xpc3RCb3g6OkdldENyZWF0ZVBhcmFtKCkKK3sKKwlQV0xfQ1JFQVRFUEFSQU0gY3AgPSBDRkZMX0Zvcm1GaWxsZXI6OkdldENyZWF0ZVBhcmFtKCk7CisKKwlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworCUZYX0RXT1JEIGR3RmllbGRGbGFnID0gbV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCk7CisJCQorCWlmIChkd0ZpZWxkRmxhZyAmIEZJRUxERkxBR19NVUxUSVNFTEVDVCkKKwl7CQkKKwkJY3AuZHdGbGFncyB8PSBQTEJTX01VTFRJUExFU0VMOworCX0KKworCWlmIChkd0ZpZWxkRmxhZyAmIEZJRUxERkxBR19DT01NSVRPTlNFTENIQU5HRSkKKwl7CisJCS8vY3AuZHdGbGFncyB8PSBQTEJTX0NPTU1JVFNFTEVDVEVEVkFMVUU7CisJfQorCisJY3AuZHdGbGFncyB8PSBQV1NfVlNDUk9MTDsKKworCWlmIChjcC5kd0ZsYWdzICYgUFdTX0FVVE9GT05UU0laRSkKKwkJY3AuZkZvbnRTaXplID0gRkZMX0RFRkFVTFRMSVNUQk9YRk9OVFNJWkU7CisKKwlpZiAoIW1fcEZvbnRNYXApCisJeworCQlBU1NFUlQodGhpcy0+bV9wQXBwICE9IE5VTEwpOworCQltX3BGb250TWFwID0gbmV3IENCQV9Gb250TWFwKG1fcFdpZGdldCxtX3BBcHAtPkdldFN5c0hhbmRsZXIoKSk7Ly8sIElTeXN0ZW1IYW5kbGU6OkdldFN5c3RlbUhhbmRsZXIobV9wQXBwKSk7CisJCW1fcEZvbnRNYXAtPkluaXRpYWwoKTsKKwl9CisJY3AucEZvbnRNYXAgPSBtX3BGb250TWFwOworCisJcmV0dXJuIGNwOworfQorCitDUFdMX1duZCogQ0ZGTF9MaXN0Qm94OjpOZXdQREZXaW5kb3coY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCUNQV0xfTGlzdEJveCogcFduZCA9IG5ldyBDUFdMX0xpc3RCb3goKTsKKwlwV25kLT5BdHRhY2hGRkxEYXRhKHRoaXMpOworCXBXbmQtPkNyZWF0ZShjcCk7CisKKwlBU1NFUlQobV9wQXBwICE9IE5VTEwpOworCUNGRkxfSUZvcm1GaWxsZXIqIHBJRm9ybUZpbGxlciA9IG1fcEFwcC0+R2V0SUZvcm1GaWxsZXIoKTsKKwlwV25kLT5TZXRGaWxsZXJOb3RpZnkocElGb3JtRmlsbGVyKTsKKworCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisJCisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9wV2lkZ2V0LT5Db3VudE9wdGlvbnMoKTsgaTxzejsgaSsrKQorCQlwV25kLT5BZGRTdHJpbmcobV9wV2lkZ2V0LT5HZXRPcHRpb25MYWJlbChpKSk7CisJCisJaWYgKHBXbmQtPkhhc0ZsYWcoUExCU19NVUxUSVBMRVNFTCkpCisJeworCQltX09yaWdpblNlbGVjdGlvbnMuUmVtb3ZlQWxsKCk7CisJCQorCQlGWF9CT09MIGJTZXRDYXJldCA9IEZBTFNFOworCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX3BXaWRnZXQtPkNvdW50T3B0aW9ucygpOyBpPHN6OyBpKyspCisJCXsKKwkJCWlmIChtX3BXaWRnZXQtPklzT3B0aW9uU2VsZWN0ZWQoaSkpCisJCQl7CisJCQkJaWYgKCFiU2V0Q2FyZXQpCisJCQkJeworCQkJCQlwV25kLT5TZXRDYXJldChpKTsKKwkJCQkJYlNldENhcmV0ID0gVFJVRTsKKwkJCQl9CisJCQkJcFduZC0+U2VsZWN0KGkpOworCQkJCW1fT3JpZ2luU2VsZWN0aW9ucy5TZXRBdChpLCBOVUxMKTsKKwkJCX0KKwkJfQorCX0KKwllbHNlCisJeworCQlmb3IgKGludCBpPTAsc3o9bV9wV2lkZ2V0LT5Db3VudE9wdGlvbnMoKTsgaTxzejsgaSsrKQorCQl7CisJCQlpZiAobV9wV2lkZ2V0LT5Jc09wdGlvblNlbGVjdGVkKGkpKQorCQkJeworCQkJCXBXbmQtPlNlbGVjdChpKTsKKwkJCQlicmVhazsKKwkJCX0KKwkJfQorCX0KKwkKKwlwV25kLT5TZXRUb3BWaXNpYmxlSW5kZXgobV9wV2lkZ2V0LT5HZXRUb3BWaXNpYmxlSW5kZXgoKSk7CisJCisJcmV0dXJuIHBXbmQ7Cit9CisKKworRlhfQk9PTAlDRkZMX0xpc3RCb3g6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQoreworCXJldHVybiBDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihwQW5ub3QsIG5DaGFyLCBuRmxhZ3MpOworfQorCitGWF9CT09MCUNGRkxfTGlzdEJveDo6SXNEYXRhQ2hhbmdlZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCWlmIChDUFdMX0xpc3RCb3gqIHBMaXN0Qm94ID0gKENQV0xfTGlzdEJveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJaWYgKG1fcFdpZGdldC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX01VTFRJU0VMRUNUKQorCQl7CisJCQlpbnQgblNlbENvdW50ID0gMDsKKwkJCWZvciAoRlhfSU5UMzIgaT0wLHN6PXBMaXN0Qm94LT5HZXRDb3VudCgpOyBpPHN6OyBpKyspCisJCQl7CisJCQkJaWYgKHBMaXN0Qm94LT5Jc0l0ZW1TZWxlY3RlZChpKSkKKwkJCQl7CisJCQkJCXZvaWQqIHAgPSBOVUxMOworCQkJCQlpZiAoIW1fT3JpZ2luU2VsZWN0aW9ucy5Mb29rdXAoaSwgcCkpCisJCQkJCQlyZXR1cm4gVFJVRTsKKworCQkJCQluU2VsQ291bnQrKzsKKwkJCQl9CisJCQl9CisKKwkJCXJldHVybiBuU2VsQ291bnQgIT0gbV9PcmlnaW5TZWxlY3Rpb25zLkdldENvdW50KCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlyZXR1cm4gcExpc3RCb3gtPkdldEN1clNlbCgpICE9IG1fcFdpZGdldC0+R2V0U2VsZWN0ZWRJbmRleCgwKTsKKwkJfQorCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZGTF9MaXN0Qm94OjpTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCWlmIChDUFdMX0xpc3RCb3gqIHBMaXN0Qm94ID0gKENQV0xfTGlzdEJveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJQ0ZYX0ludEFycmF5IGFPbGRTZWxlY3QsIGFOZXdTZWxlY3Q7CisKKwkJeworCQkJZm9yIChpbnQgaT0wLHN6PW1fcFdpZGdldC0+Q291bnRPcHRpb25zKCk7IGk8c3o7IGkrKykKKwkJCXsKKwkJCQlpZiAobV9wV2lkZ2V0LT5Jc09wdGlvblNlbGVjdGVkKGkpKQorCQkJCXsKKwkJCQkJYU9sZFNlbGVjdC5BZGQoaSk7CisJCQkJfQorCQkJfQorCQl9CisKKwkJCisJCUZYX0lOVDMyIG5OZXdUb3BJbmRleCA9IHBMaXN0Qm94LT5HZXRUb3BWaXNpYmxlSW5kZXgoKTsKKworCQltX3BXaWRnZXQtPkNsZWFyU2VsZWN0aW9uKEZBTFNFKTsJCisKKwkJaWYgKG1fcFdpZGdldC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX01VTFRJU0VMRUNUKQorCQl7CisJCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1wTGlzdEJveC0+R2V0Q291bnQoKTsgaTxzejsgaSsrKQorCQkJeworCQkJCWlmIChwTGlzdEJveC0+SXNJdGVtU2VsZWN0ZWQoaSkpCisJCQkJeworCQkJCQltX3BXaWRnZXQtPlNldE9wdGlvblNlbGVjdGlvbihpLCBUUlVFLCBGQUxTRSk7CisJCQkJCWFOZXdTZWxlY3QuQWRkKGkpOworCQkJCX0KKwkJCX0KKwkJfQorCQllbHNlCisJCXsKKwkJCW1fcFdpZGdldC0+U2V0T3B0aW9uU2VsZWN0aW9uKHBMaXN0Qm94LT5HZXRDdXJTZWwoKSwgVFJVRSwgRkFMU0UpOworCQkJYU5ld1NlbGVjdC5BZGQocExpc3RCb3gtPkdldEN1clNlbCgpKTsKKwkJfQorCisJCW1fcFdpZGdldC0+U2V0VG9wVmlzaWJsZUluZGV4KG5OZXdUb3BJbmRleCk7CisJCW1fcFdpZGdldC0+UmVzZXRGaWVsZEFwcGVhcmFuY2UoVFJVRSk7CisJCW1fcFdpZGdldC0+VXBkYXRlRmllbGQoKTsKKwkJU2V0Q2hhbmdlTWFyaygpOworCX0KK30KKwordm9pZCBDRkZMX0xpc3RCb3g6OkdldEFjdGlvbkRhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsCisJCQkJCQlQREZTREtfRmllbGRBY3Rpb24mIGZhKQoreworCXN3aXRjaCAodHlwZSkKKwl7CisJY2FzZSBDUERGX0FBY3Rpb246OlZhbGlkYXRlOgorCQlpZiAobV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfTVVMVElTRUxFQ1QpCisJCXsKKwkJCWZhLnNWYWx1ZSA9IEwiIjsKKwkJfQorCQllbHNlCisJCXsKKwkJCWlmIChDUFdMX0xpc3RCb3gqIHBMaXN0Qm94ID0gKENQV0xfTGlzdEJveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCQkJeworCQkJCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisJCQkJRlhfSU5UMzIgbkN1clNlbCA9IHBMaXN0Qm94LT5HZXRDdXJTZWwoKTsKKwkJCQlpZiAobkN1clNlbCA+PSAwKQorCQkJCQlmYS5zVmFsdWUgPSBtX3BXaWRnZXQtPkdldE9wdGlvbkxhYmVsKG5DdXJTZWwpOworCQkJfQorCQl9CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpMb3NlRm9jdXM6CisJY2FzZSBDUERGX0FBY3Rpb246OkdldEZvY3VzOgorCQlpZiAobV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfTVVMVElTRUxFQ1QpCisJCXsKKwkJCWZhLnNWYWx1ZSA9IEwiIjsKKwkJfQorCQllbHNlCisJCXsKKwkJCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisJCQlGWF9JTlQzMiBuQ3VyU2VsID0gbV9wV2lkZ2V0LT5HZXRTZWxlY3RlZEluZGV4KDApOworCQkJaWYgKG5DdXJTZWwgPj0gMCkKKwkJCQlmYS5zVmFsdWUgPSBtX3BXaWRnZXQtPkdldE9wdGlvbkxhYmVsKG5DdXJTZWwpOworCQl9CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCWJyZWFrOworCX0KK30KKworCit2b2lkIENGRkxfTGlzdEJveDo6U2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgCisJCQkJCQkJCWNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmEpCit7Cit9CisKK3ZvaWQgQ0ZGTF9MaXN0Qm94OjpTYXZlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7CisKKwlpZiAoQ1BXTF9MaXN0Qm94KiBwTGlzdEJveCA9IChDUFdMX0xpc3RCb3gqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwl7CisJCWZvciAoRlhfSU5UMzIgaT0wLHN6PXBMaXN0Qm94LT5HZXRDb3VudCgpOyBpPHN6OyBpKyspCisJCXsKKwkJCWlmIChwTGlzdEJveC0+SXNJdGVtU2VsZWN0ZWQoaSkpCisJCQl7CisJCQkJbV9TdGF0ZS5BZGQoaSk7CisJCQl9CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZGTF9MaXN0Qm94OjpSZXN0b3JlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCWlmIChDUFdMX0xpc3RCb3gqIHBMaXN0Qm94ID0gKENQV0xfTGlzdEJveCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJZm9yIChpbnQgaT0wLHN6PW1fU3RhdGUuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQlwTGlzdEJveC0+U2VsZWN0KG1fU3RhdGVbaV0pOworCX0KK30KKworQ1BXTF9XbmQqIENGRkxfTGlzdEJveDo6UmVzZXRQREZXaW5kb3coQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MIGJSZXN0b3JlVmFsdWUpCit7CisJaWYgKGJSZXN0b3JlVmFsdWUpCisJCVNhdmVTdGF0ZShwUGFnZVZpZXcpOworCQorCURlc3Ryb3lQREZXaW5kb3cocFBhZ2VWaWV3KTsKKwkKKwlDUFdMX1duZCogcFJldCA9IE5VTEw7CisJCisJaWYgKGJSZXN0b3JlVmFsdWUpCisJeworCQlSZXN0b3JlU3RhdGUocFBhZ2VWaWV3KTsKKwkJcFJldCA9IHRoaXMtPkdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKTsKKwl9CisJZWxzZQorCQlwUmV0ID0gdGhpcy0+R2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSk7CisJCisJbV9wV2lkZ2V0LT5VcGRhdGVGaWVsZCgpOworCQorCXJldHVybiBwUmV0OworfQorCit2b2lkIENGRkxfTGlzdEJveDo6T25LZXlTdHJva2UoRlhfQk9PTCBiS2V5RG93biwgRlhfRFdPUkQgbkZsYWcpCit7CisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCWludCBuRmxhZ3MgPSBtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKTsKKwkKKwlpZiAobkZsYWdzICYgRklFTERGTEFHX0NPTU1JVE9OU0VMQ0hBTkdFKQorCXsKKwkJaWYgKG1fYlZhbGlkKQorCQl7CisJCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSB0aGlzLT5HZXRDdXJQYWdlVmlldygpOworCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKworCQkJaWYgKENvbW1pdERhdGEocFBhZ2VWaWV3LCBuRmxhZykpCisJCQl7CisJCQkJRGVzdHJveVBERldpbmRvdyhwUGFnZVZpZXcpOworCQkJCW1fYlZhbGlkID0gRkFMU0U7CisJCQl9CisJCX0KKwl9Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX05vdGlmeS5jcHAgYi9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9Ob3RpZnkuY3BwCmluZGV4IGYxOGVkNTEuLmY2YTJmZWIgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX05vdGlmeS5jcHAKKysrIGIvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfTm90aWZ5LmNwcApAQCAtMSwxNzIgKzEsMTcyIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0vLyAjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfTm90aWZ5LmgiDQotLy8gI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ29tYm9Cb3guaCINCi0vLyAjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Nb2R1bGUuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX05vdGlmeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi0vLyNwcmFnbWEgd2FybmluZyhkaXNhYmxlOiA0ODAwKQ0KLQ0KLUNGRkxfTm90aWZ5OjpDRkZMX05vdGlmeShDRkZMX0Zvcm1GaWxsZXIgKiBwRm9ybUZpbGxlcikgOiANCi0JbV9wRm9ybUZpbGxlcihwRm9ybUZpbGxlciksDQotCW1fYkRvQWN0aW9uaW5nKEZBTFNFKSwNCi0JbV9uTm90aWZ5RmxhZygwKQ0KLXsNCi0JQVNTRVJUKG1fcEZvcm1GaWxsZXIgIT0gTlVMTCk7DQotfQ0KLQ0KLUNGRkxfTm90aWZ5Ojp+Q0ZGTF9Ob3RpZnkoKQ0KLXsNCi19DQotDQotdm9pZCBDRkZMX05vdGlmeTo6QmVmb3JlTm90aWZ5KCkNCi17DQotCW1fbk5vdGlmeUZsYWcgKys7DQotfQ0KLQ0KLQ0KLXZvaWQgQ0ZGTF9Ob3RpZnk6OkFmdGVyTm90aWZ5KCkNCi17DQotCW1fbk5vdGlmeUZsYWcgLS07DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uTW91c2VVcChGWF9CT09MICYgYkV4aXQpDQotew0KLQlCZWZvcmVOb3RpZnkoKTsNCi0JRlhfQk9PTCBiUmV0ID0gRkFMU0U7Ly9Eb0FBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZTo6QnV0dG9uVXAsIGJFeGl0KTsNCi0JQWZ0ZXJOb3RpZnkoKTsNCi0JcmV0dXJuIGJSZXQ7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uTW91c2VEb3duKEZYX0JPT0wgJiBiRXhpdCkNCi17DQotCUJlZm9yZU5vdGlmeSgpOw0KLQlGWF9CT09MIGJSZXQgPSBGQUxTRTsvL0RvQUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlOjpCdXR0b25Eb3duLCBiRXhpdCk7DQotCUFmdGVyTm90aWZ5KCk7DQotCXJldHVybiBiUmV0Ow0KLX0NCi0NCi1GWF9CT09MIENGRkxfTm90aWZ5OjpPbk1vdXNlRW50ZXIoRlhfQk9PTCAmIGJFeGl0KQ0KLXsNCi0JQmVmb3JlTm90aWZ5KCk7DQotCUZYX0JPT0wgYlJldCA9IEZBTFNFOy8vRG9BQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGU6OkN1cnNvckVudGVyLCBiRXhpdCk7DQotCUFmdGVyTm90aWZ5KCk7DQotCXJldHVybiBiUmV0Ow0KLX0NCi0NCi1GWF9CT09MIENGRkxfTm90aWZ5OjpPbk1vdXNlRXhpdChGWF9CT09MICYgYkV4aXQpDQotew0KLQlCZWZvcmVOb3RpZnkoKTsNCi0JRlhfQk9PTCBiUmV0ID0gRkFMU0U7Ly9Eb0FBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZTo6Q3Vyc29yRXhpdCwgYkV4aXQpOw0KLQlBZnRlck5vdGlmeSgpOw0KLQlyZXR1cm4gYlJldDsNCi19DQotDQotRlhfQk9PTCBDRkZMX05vdGlmeTo6T25TZXRGb2N1cyhGWF9CT09MICYgYkV4aXQpDQotew0KLQlCZWZvcmVOb3RpZnkoKTsNCi0JRlhfQk9PTCBiUmV0ID0gRkFMU0U7Ly9Eb0FBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZTo6R2V0Rm9jdXMsIGJFeGl0KTsNCi0JQWZ0ZXJOb3RpZnkoKTsNCi0JcmV0dXJuIGJSZXQ7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uS2lsbEZvY3VzKEZYX0JPT0wgJiBiRXhpdCkNCi17DQotCUJlZm9yZU5vdGlmeSgpOw0KLQlGWF9CT09MIGJSZXQgPSBGQUxTRTsvL0RvQUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlOjpMb3NlRm9jdXMsIGJFeGl0KTsNCi0JQWZ0ZXJOb3RpZnkoKTsNCi0JcmV0dXJuIGJSZXQ7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uQ2FsY3VsYXRlKCkNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENGRkxfTm90aWZ5OjpPbkZvcm1hdChpbnQgaUNvbW1pdEtleSkNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENGRkxfTm90aWZ5OjpPbktleVN0cm9rZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgaW50IG5Db21taXRLZXksIENGWF9XaWRlU3RyaW5nJiBzdHJWYWx1ZSwgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZSwgDQotCQkJCQkJCSAgIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwgRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCBiTW9kaWZpZXIsDQotCQkJCQkJCSAgIEZYX0JPT0wgYlNoaWZ0LCBGWF9CT09MIGJXaWxsQ29tbWl0LCBGWF9CT09MIGJGaWVsZEZ1bGwsIA0KLQkJCQkJCQkgICBpbnQmIG5TZWxTdGFydCwgaW50JiBuU2VsRW5kLCBGWF9CT09MJiBiUkMpDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBDRkZMX05vdGlmeTo6T25WYWxpZGF0ZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIHN0clZhbHVlLCBDRlhfV2lkZVN0cmluZyAmIHN0ckNoYW5nZSwgDQotCQkJCQkJCQkJICAgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LCBGWF9CT09MIGJLZXlEb3duLCBGWF9CT09MIGJNb2RpZmllciwNCi0JCQkJCQkJCQkgICBGWF9CT09MIGJTaGlmdCwgRlhfQk9PTCAmIGJSQykNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfTm90aWZ5OjpEb0FBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlQUFULCBGWF9CT09MICYgYkV4aXQpDQotew0KLQlpZiAodGhpcy0+bV9iRG9BY3Rpb25pbmcpIHJldHVybiBGQUxTRTsNCi0JDQotCUNQREZfQWN0aW9uIGFjdGlvbjsNCi0JaWYgKCFGaW5kQUFjdGlvbihlQUFULGFjdGlvbikpIHJldHVybiBGQUxTRTsNCi0NCi0JdGhpcy0+bV9iRG9BY3Rpb25pbmcgPSBUUlVFOwkNCi0JRXhlY3V0ZUFjdGlvblRyZWUoZUFBVCxhY3Rpb24sYkV4aXQpOwkNCi0JdGhpcy0+bV9iRG9BY3Rpb25pbmcgPSBGQUxTRTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9Ob3RpZnk6OkV4ZWN1dGVBY3Rpb25UcmVlKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCxDUERGX0FjdGlvbiAmIGFjdGlvbiwgRlhfQk9PTCYgYkV4aXQpDQotew0KLQlpZiAoIUV4ZWN1dGVBY3Rpb24oZUFBVCxhY3Rpb24sYkV4aXQpKSByZXR1cm4gRkFMU0U7DQotCWlmIChiRXhpdCkgcmV0dXJuIFRSVUU7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PWFjdGlvbi5HZXRTdWJBY3Rpb25zQ291bnQoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlDUERGX0FjdGlvbiBzdWJhY3Rpb24gPSBhY3Rpb24uR2V0U3ViQWN0aW9uKGkpOw0KLQkJaWYgKCFFeGVjdXRlQWN0aW9uVHJlZShlQUFULHN1YmFjdGlvbixiRXhpdCkpIHJldHVybiBGQUxTRTsNCi0JCWlmIChiRXhpdCkgYnJlYWs7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9Ob3RpZnk6OkZpbmRBQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCxDUERGX0FjdGlvbiAmIGFjdGlvbikNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDRkZMX05vdGlmeTo6RmluZEFBY3Rpb24oQ1BERl9BQWN0aW9uIGFhY3Rpb24sQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlQUFULENQREZfQWN0aW9uICYgYWN0aW9uKQ0KLXsNCi0JQ1BERl9BY3Rpb24gTXlBY3Rpb247DQotDQotCWlmIChhYWN0aW9uLkFjdGlvbkV4aXN0KGVBQVQpKQ0KLQl7DQotCQlNeUFjdGlvbiA9IGFhY3Rpb24uR2V0QWN0aW9uKGVBQVQpOw0KLQl9DQotCWVsc2UNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0NCi0JaWYgKE15QWN0aW9uLkdldFR5cGUoKSA9PSBDUERGX0FjdGlvbjo6VW5rbm93bikNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JYWN0aW9uID0gTXlBY3Rpb247DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfTm90aWZ5OjpFeGVjdXRlQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCxDUERGX0FjdGlvbiAmIGFjdGlvbixGWF9CT09MJiBiRXhpdCkNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotLy8jcHJhZ21hIHdhcm5pbmcoZGVmYXVsdDogNDgwMCkNCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisvLyAjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX05vdGlmeS5oIgorLy8gI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ29tYm9Cb3guaCIKKy8vICNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX01vZHVsZS5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX05vdGlmeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworLy8jcHJhZ21hIHdhcm5pbmcoZGlzYWJsZTogNDgwMCkKKworQ0ZGTF9Ob3RpZnk6OkNGRkxfTm90aWZ5KENGRkxfRm9ybUZpbGxlciAqIHBGb3JtRmlsbGVyKSA6IAorCW1fcEZvcm1GaWxsZXIocEZvcm1GaWxsZXIpLAorCW1fYkRvQWN0aW9uaW5nKEZBTFNFKSwKKwltX25Ob3RpZnlGbGFnKDApCit7CisJQVNTRVJUKG1fcEZvcm1GaWxsZXIgIT0gTlVMTCk7Cit9CisKK0NGRkxfTm90aWZ5Ojp+Q0ZGTF9Ob3RpZnkoKQoreworfQorCit2b2lkIENGRkxfTm90aWZ5OjpCZWZvcmVOb3RpZnkoKQoreworCW1fbk5vdGlmeUZsYWcgKys7Cit9CisKKwordm9pZCBDRkZMX05vdGlmeTo6QWZ0ZXJOb3RpZnkoKQoreworCW1fbk5vdGlmeUZsYWcgLS07Cit9CisKK0ZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uTW91c2VVcChGWF9CT09MICYgYkV4aXQpCit7CisJQmVmb3JlTm90aWZ5KCk7CisJRlhfQk9PTCBiUmV0ID0gRkFMU0U7Ly9Eb0FBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZTo6QnV0dG9uVXAsIGJFeGl0KTsKKwlBZnRlck5vdGlmeSgpOworCXJldHVybiBiUmV0OworfQorCitGWF9CT09MIENGRkxfTm90aWZ5OjpPbk1vdXNlRG93bihGWF9CT09MICYgYkV4aXQpCit7CisJQmVmb3JlTm90aWZ5KCk7CisJRlhfQk9PTCBiUmV0ID0gRkFMU0U7Ly9Eb0FBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZTo6QnV0dG9uRG93biwgYkV4aXQpOworCUFmdGVyTm90aWZ5KCk7CisJcmV0dXJuIGJSZXQ7Cit9CisKK0ZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uTW91c2VFbnRlcihGWF9CT09MICYgYkV4aXQpCit7CisJQmVmb3JlTm90aWZ5KCk7CisJRlhfQk9PTCBiUmV0ID0gRkFMU0U7Ly9Eb0FBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZTo6Q3Vyc29yRW50ZXIsIGJFeGl0KTsKKwlBZnRlck5vdGlmeSgpOworCXJldHVybiBiUmV0OworfQorCitGWF9CT09MIENGRkxfTm90aWZ5OjpPbk1vdXNlRXhpdChGWF9CT09MICYgYkV4aXQpCit7CisJQmVmb3JlTm90aWZ5KCk7CisJRlhfQk9PTCBiUmV0ID0gRkFMU0U7Ly9Eb0FBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZTo6Q3Vyc29yRXhpdCwgYkV4aXQpOworCUFmdGVyTm90aWZ5KCk7CisJcmV0dXJuIGJSZXQ7Cit9CisKK0ZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uU2V0Rm9jdXMoRlhfQk9PTCAmIGJFeGl0KQoreworCUJlZm9yZU5vdGlmeSgpOworCUZYX0JPT0wgYlJldCA9IEZBTFNFOy8vRG9BQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGU6OkdldEZvY3VzLCBiRXhpdCk7CisJQWZ0ZXJOb3RpZnkoKTsKKwlyZXR1cm4gYlJldDsKK30KKworRlhfQk9PTCBDRkZMX05vdGlmeTo6T25LaWxsRm9jdXMoRlhfQk9PTCAmIGJFeGl0KQoreworCUJlZm9yZU5vdGlmeSgpOworCUZYX0JPT0wgYlJldCA9IEZBTFNFOy8vRG9BQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGU6Okxvc2VGb2N1cywgYkV4aXQpOworCUFmdGVyTm90aWZ5KCk7CisJcmV0dXJuIGJSZXQ7Cit9CisKK0ZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uQ2FsY3VsYXRlKCkKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDRkZMX05vdGlmeTo6T25Gb3JtYXQoaW50IGlDb21taXRLZXkpCit7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgQ0ZGTF9Ob3RpZnk6Ok9uS2V5U3Ryb2tlKENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCBpbnQgbkNvbW1pdEtleSwgQ0ZYX1dpZGVTdHJpbmcmIHN0clZhbHVlLCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlLCAKKwkJCQkJCQkgICBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIEZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLAorCQkJCQkJCSAgIEZYX0JPT0wgYlNoaWZ0LCBGWF9CT09MIGJXaWxsQ29tbWl0LCBGWF9CT09MIGJGaWVsZEZ1bGwsIAorCQkJCQkJCSAgIGludCYgblNlbFN0YXJ0LCBpbnQmIG5TZWxFbmQsIEZYX0JPT0wmIGJSQykKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDRkZMX05vdGlmeTo6T25WYWxpZGF0ZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIHN0clZhbHVlLCBDRlhfV2lkZVN0cmluZyAmIHN0ckNoYW5nZSwgCisJCQkJCQkJCQkgICBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIEZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLAorCQkJCQkJCQkJICAgRlhfQk9PTCBiU2hpZnQsIEZYX0JPT0wgJiBiUkMpCit7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9Ob3RpZnk6OkRvQUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQsIEZYX0JPT0wgJiBiRXhpdCkKK3sKKwlpZiAodGhpcy0+bV9iRG9BY3Rpb25pbmcpIHJldHVybiBGQUxTRTsKKwkKKwlDUERGX0FjdGlvbiBhY3Rpb247CisJaWYgKCFGaW5kQUFjdGlvbihlQUFULGFjdGlvbikpIHJldHVybiBGQUxTRTsKKworCXRoaXMtPm1fYkRvQWN0aW9uaW5nID0gVFJVRTsJCisJRXhlY3V0ZUFjdGlvblRyZWUoZUFBVCxhY3Rpb24sYkV4aXQpOwkKKwl0aGlzLT5tX2JEb0FjdGlvbmluZyA9IEZBTFNFOworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MCUNGRkxfTm90aWZ5OjpFeGVjdXRlQWN0aW9uVHJlZShDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQsQ1BERl9BY3Rpb24gJiBhY3Rpb24sIEZYX0JPT0wmIGJFeGl0KQoreworCWlmICghRXhlY3V0ZUFjdGlvbihlQUFULGFjdGlvbixiRXhpdCkpIHJldHVybiBGQUxTRTsKKwlpZiAoYkV4aXQpIHJldHVybiBUUlVFOworCisJZm9yIChGWF9JTlQzMiBpPTAsc3o9YWN0aW9uLkdldFN1YkFjdGlvbnNDb3VudCgpOyBpPHN6OyBpKyspCisJeworCQlDUERGX0FjdGlvbiBzdWJhY3Rpb24gPSBhY3Rpb24uR2V0U3ViQWN0aW9uKGkpOworCQlpZiAoIUV4ZWN1dGVBY3Rpb25UcmVlKGVBQVQsc3ViYWN0aW9uLGJFeGl0KSkgcmV0dXJuIEZBTFNFOworCQlpZiAoYkV4aXQpIGJyZWFrOworCX0KKworCXJldHVybiBUUlVFOworfQorCisKK0ZYX0JPT0wJQ0ZGTF9Ob3RpZnk6OkZpbmRBQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCxDUERGX0FjdGlvbiAmIGFjdGlvbikKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ0ZGTF9Ob3RpZnk6OkZpbmRBQWN0aW9uKENQREZfQUFjdGlvbiBhYWN0aW9uLENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCxDUERGX0FjdGlvbiAmIGFjdGlvbikKK3sKKwlDUERGX0FjdGlvbiBNeUFjdGlvbjsKKworCWlmIChhYWN0aW9uLkFjdGlvbkV4aXN0KGVBQVQpKQorCXsKKwkJTXlBY3Rpb24gPSBhYWN0aW9uLkdldEFjdGlvbihlQUFUKTsKKwl9CisJZWxzZQorCQlyZXR1cm4gRkFMU0U7CisKKworCWlmIChNeUFjdGlvbi5HZXRUeXBlKCkgPT0gQ1BERl9BY3Rpb246OlVua25vd24pCisJCXJldHVybiBGQUxTRTsKKworCWFjdGlvbiA9IE15QWN0aW9uOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9Ob3RpZnk6OkV4ZWN1dGVBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlQUFULENQREZfQWN0aW9uICYgYWN0aW9uLEZYX0JPT0wmIGJFeGl0KQoreworCXJldHVybiBGQUxTRTsKK30KKy8vI3ByYWdtYSB3YXJuaW5nKGRlZmF1bHQ6IDQ4MDApCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX1B1c2hCdXR0b24uY3BwIGIvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfUHVzaEJ1dHRvbi5jcHAKaW5kZXggMWFmYmU4Yi4uYjhhMDdmYiAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfUHVzaEJ1dHRvbi5jcHAKKysrIGIvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfUHVzaEJ1dHRvbi5jcHAKQEAgLTEsNDMgKzEsNDMgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRm9ybUZpbGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9QdXNoQnV0dG9uLmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX1B1c2hCdXR0b24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGRkxfUHVzaEJ1dHRvbjo6Q0ZGTF9QdXNoQnV0dG9uKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfQW5ub3QqIHBBbm5vdCk6DQotCUNGRkxfQnV0dG9uKCBwQXBwLCBwQW5ub3QpDQotew0KLX0NCi0NCi1DRkZMX1B1c2hCdXR0b246On5DRkZMX1B1c2hCdXR0b24oKQ0KLXsNCi19DQotDQotQ1BXTF9XbmQqIENGRkxfUHVzaEJ1dHRvbjo6TmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCUNQV0xfUHVzaEJ1dHRvbiogcFduZCA9IG5ldyBDUFdMX1B1c2hCdXR0b24oKTsNCi0JcFduZC0+Q3JlYXRlKGNwKTsNCi0JDQotCXJldHVybiBwV25kOw0KLX0NCi0NCi0NCi1GWF9CT09MCUNGRkxfUHVzaEJ1dHRvbjo6T25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuQ2hhciwgRlhfVUlOVCBuRmxhZ3MpDQotew0KLQlyZXR1cm4gQ0ZGTF9Gb3JtRmlsbGVyOjpPbkNoYXIocEFubm90LCBuQ2hhciwgbkZsYWdzKTsNCi19DQotDQotdm9pZCBDRkZMX1B1c2hCdXR0b246Ok9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsICBDUERGU0RLX0Fubm90KiBwQW5ub3QsIA0KLQkJCQkJCQkgQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCQkJCQkJIEZYX0RXT1JEIGR3RmxhZ3MpDQotew0KLQlDRkZMX0J1dHRvbjo6T25EcmF3KHBQYWdlVmlldywgcEFubm90LCBwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIGR3RmxhZ3MpOw0KLX0NCi0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0Zvcm1GaWxsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1B1c2hCdXR0b24uaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX1B1c2hCdXR0b24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRkZMX1B1c2hCdXR0b246OkNGRkxfUHVzaEJ1dHRvbihDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwQW5ub3QpOgorCUNGRkxfQnV0dG9uKCBwQXBwLCBwQW5ub3QpCit7Cit9CisKK0NGRkxfUHVzaEJ1dHRvbjo6fkNGRkxfUHVzaEJ1dHRvbigpCit7Cit9CisKK0NQV0xfV25kKiBDRkZMX1B1c2hCdXR0b246Ok5ld1BERldpbmRvdyhjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJQ1BXTF9QdXNoQnV0dG9uKiBwV25kID0gbmV3IENQV0xfUHVzaEJ1dHRvbigpOworCXBXbmQtPkNyZWF0ZShjcCk7CisJCisJcmV0dXJuIHBXbmQ7Cit9CisKKworRlhfQk9PTAlDRkZMX1B1c2hCdXR0b246Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQoreworCXJldHVybiBDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihwQW5ub3QsIG5DaGFyLCBuRmxhZ3MpOworfQorCit2b2lkIENGRkxfUHVzaEJ1dHRvbjo6T25EcmF3KENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgIENQREZTREtfQW5ub3QqIHBBbm5vdCwgCisJCQkJCQkJIENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkJIEZYX0RXT1JEIGR3RmxhZ3MpCit7CisJQ0ZGTF9CdXR0b246Ok9uRHJhdyhwUGFnZVZpZXcsIHBBbm5vdCwgcERldmljZSwgcFVzZXIyRGV2aWNlLCBkd0ZsYWdzKTsKK30KKworCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9SYWRpb0J1dHRvbi5jcHAgYi9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9SYWRpb0J1dHRvbi5jcHAKaW5kZXggNDYyYzA1ZS4uYWFjYjdkOCAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfUmFkaW9CdXR0b24uY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX1JhZGlvQnV0dG9uLmNwcApAQCAtMSwxMzcgKzEsMTM3IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0Zvcm1GaWxsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfUmFkaW9CdXR0b24uaCINCi0vLyNpbmNsdWRlICIuLi9pbmNsdWRlL0ZGTF9VbmRvLmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRkZMX1JhZGlvQnV0dG9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DRkZMX1JhZGlvQnV0dG9uOjpDRkZMX1JhZGlvQnV0dG9uKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfQW5ub3QqIHBXaWRnZXQpIDoNCi0JQ0ZGTF9CdXR0b24ocEFwcCwgcFdpZGdldCkNCi17DQotfQ0KLQ0KLUNGRkxfUmFkaW9CdXR0b246On5DRkZMX1JhZGlvQnV0dG9uKCkNCi17DQotfQ0KLQ0KLUNQV0xfV25kKiBDRkZMX1JhZGlvQnV0dG9uOjpOZXdQREZXaW5kb3coY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JQ1BXTF9SYWRpb0J1dHRvbiogcFduZCA9IG5ldyBDUFdMX1JhZGlvQnV0dG9uKCk7DQotCXBXbmQtPkNyZWF0ZShjcCk7DQotDQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotCXBXbmQtPlNldENoZWNrKG1fcFdpZGdldC0+SXNDaGVja2VkKCkpOw0KLQkNCi0JcmV0dXJuIHBXbmQ7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9SYWRpb0J1dHRvbjo6T25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfVUlOVCBuS2V5Q29kZSwgRlhfVUlOVCBuRmxhZ3MpDQotew0KLQlzd2l0Y2ggKG5LZXlDb2RlKQ0KLQl7DQotCWNhc2UgRldMX1ZLRVlfUmV0dXJuOg0KLQljYXNlIEZXTF9WS0VZX1NwYWNlOg0KLQkJcmV0dXJuIFRSVUU7DQotCWRlZmF1bHQ6DQotCQlyZXR1cm4gQ0ZGTF9Gb3JtRmlsbGVyOjpPbktleURvd24ocEFubm90LCBuS2V5Q29kZSwgbkZsYWdzKTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MCUNGRkxfUmFkaW9CdXR0b246Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQ0KLXsNCi0Jc3dpdGNoIChuQ2hhcikNCi0Jew0KLQljYXNlIEZXTF9WS0VZX1JldHVybjoJDQotCWNhc2UgRldMX1ZLRVlfU3BhY2U6DQotCQl7DQotCQkJQ0ZGTF9JRm9ybUZpbGxlciogcElGb3JtRmlsbGVyID0gbV9wQXBwLT5HZXRJRm9ybUZpbGxlcigpOw0KLQkJCUFTU0VSVChwSUZvcm1GaWxsZXIgIT0gTlVMTCk7DQotDQotCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcEFubm90LT5HZXRQYWdlVmlldygpOw0KLQkJCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotDQotCQkJRlhfQk9PTCBiUmVzZXQgPSBGQUxTRTsNCi0JCQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7DQotDQotCQkJcElGb3JtRmlsbGVyLT5PbkJ1dHRvblVwKG1fcFdpZGdldCwgcFBhZ2VWaWV3LCBiUmVzZXQsIGJFeGl0LG5GbGFncyk7DQotDQotCQkJaWYgKGJSZXNldCkgcmV0dXJuIFRSVUU7DQotCQkJaWYgKGJFeGl0KSByZXR1cm4gVFJVRTsNCi0NCi0JCQlDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihwQW5ub3QsIG5DaGFyLCBuRmxhZ3MpOw0KLQ0KLQkJCWlmIChDUFdMX1JhZGlvQnV0dG9uICogcFduZCA9IChDUFdMX1JhZGlvQnV0dG9uKilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBUUlVFKSkNCi0JCQkJcFduZC0+U2V0Q2hlY2soVFJVRSk7DQotCQkJQ29tbWl0RGF0YShwUGFnZVZpZXcsbkZsYWdzKTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JZGVmYXVsdDoNCi0JCXJldHVybiBDRkZMX0Zvcm1GaWxsZXI6Ok9uQ2hhcihwQW5ub3QsIG5DaGFyLCBuRmxhZ3MpOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9SYWRpb0J1dHRvbjo6T25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUNGRkxfQnV0dG9uOjpPbkxCdXR0b25VcChwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7DQotDQotCWlmIChJc1ZhbGlkKCkpDQotCXsNCi0JCWlmIChDUFdMX1JhZGlvQnV0dG9uICogcFduZCA9IChDUFdMX1JhZGlvQnV0dG9uKilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBUUlVFKSkNCi0JCQlwV25kLT5TZXRDaGVjayhUUlVFKTsNCi0NCi0JCWlmICghQ29tbWl0RGF0YShwUGFnZVZpZXcsbkZsYWdzKSkgcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNGRkxfUmFkaW9CdXR0b246OklzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0NCi0JaWYgKENQV0xfUmFkaW9CdXR0b24qIHBXbmQgPSAoQ1BXTF9SYWRpb0J1dHRvbiopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7DQotCQlyZXR1cm4gcFduZC0+SXNDaGVja2VkKCkgIT0gbV9wV2lkZ2V0LT5Jc0NoZWNrZWQoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9SYWRpb0J1dHRvbjo6U2F2ZURhdGEoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0NCi0JaWYgKENQV0xfUmFkaW9CdXR0b24qIHBXbmQgPSAoQ1BXTF9SYWRpb0J1dHRvbiopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7DQotCQkNCi0JCUZYX0JPT0wgYk5ld0NoZWNrZWQgPSBwV25kLT5Jc0NoZWNrZWQoKTsNCi0NCi0JCWlmIChiTmV3Q2hlY2tlZCkNCi0JCXsNCi0JCQlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gbV9wV2lkZ2V0LT5HZXRGb3JtRmllbGQoKTsNCi0JCQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJCWZvciAoRlhfSU5UMzIgaT0wLHN6PXBGaWVsZC0+Q291bnRDb250cm9scygpOyBpPHN6OyBpKyspDQotCQkJew0KLQkJCQlpZiAoQ1BERl9Gb3JtQ29udHJvbCogcEN0cmwgPSBwRmllbGQtPkdldENvbnRyb2woaSkpDQotCQkJCXsNCi0JCQkJCWlmIChwQ3RybC0+SXNDaGVja2VkKCkpDQotCQkJCQl7DQotCQkJCQkJYnJlYWs7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9DQotDQotCQltX3BXaWRnZXQtPlNldENoZWNrKGJOZXdDaGVja2VkLCBGQUxTRSk7DQotCQltX3BXaWRnZXQtPlVwZGF0ZUZpZWxkKCk7DQotCQlTZXRDaGFuZ2VNYXJrKCk7DQotCX0NCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9Gb3JtRmlsbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9Gb3JtRmlsbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9SYWRpb0J1dHRvbi5oIgorLy8jaW5jbHVkZSAiLi4vaW5jbHVkZS9GRkxfVW5kby5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGRkxfUmFkaW9CdXR0b24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRkZMX1JhZGlvQnV0dG9uOjpDRkZMX1JhZGlvQnV0dG9uKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfQW5ub3QqIHBXaWRnZXQpIDoKKwlDRkZMX0J1dHRvbihwQXBwLCBwV2lkZ2V0KQoreworfQorCitDRkZMX1JhZGlvQnV0dG9uOjp+Q0ZGTF9SYWRpb0J1dHRvbigpCit7Cit9CisKK0NQV0xfV25kKiBDRkZMX1JhZGlvQnV0dG9uOjpOZXdQREZXaW5kb3coY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCUNQV0xfUmFkaW9CdXR0b24qIHBXbmQgPSBuZXcgQ1BXTF9SYWRpb0J1dHRvbigpOworCXBXbmQtPkNyZWF0ZShjcCk7CisKKwlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworCXBXbmQtPlNldENoZWNrKG1fcFdpZGdldC0+SXNDaGVja2VkKCkpOworCQorCXJldHVybiBwV25kOworfQorCitGWF9CT09MCUNGRkxfUmFkaW9CdXR0b246Ok9uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbktleUNvZGUsIEZYX1VJTlQgbkZsYWdzKQoreworCXN3aXRjaCAobktleUNvZGUpCisJeworCWNhc2UgRldMX1ZLRVlfUmV0dXJuOgorCWNhc2UgRldMX1ZLRVlfU3BhY2U6CisJCXJldHVybiBUUlVFOworCWRlZmF1bHQ6CisJCXJldHVybiBDRkZMX0Zvcm1GaWxsZXI6Ok9uS2V5RG93bihwQW5ub3QsIG5LZXlDb2RlLCBuRmxhZ3MpOworCX0KK30KKworRlhfQk9PTAlDRkZMX1JhZGlvQnV0dG9uOjpPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5DaGFyLCBGWF9VSU5UIG5GbGFncykKK3sKKwlzd2l0Y2ggKG5DaGFyKQorCXsKKwljYXNlIEZXTF9WS0VZX1JldHVybjoJCisJY2FzZSBGV0xfVktFWV9TcGFjZToKKwkJeworCQkJQ0ZGTF9JRm9ybUZpbGxlciogcElGb3JtRmlsbGVyID0gbV9wQXBwLT5HZXRJRm9ybUZpbGxlcigpOworCQkJQVNTRVJUKHBJRm9ybUZpbGxlciAhPSBOVUxMKTsKKworCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcEFubm90LT5HZXRQYWdlVmlldygpOworCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKworCQkJRlhfQk9PTCBiUmVzZXQgPSBGQUxTRTsKKwkJCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsKKworCQkJcElGb3JtRmlsbGVyLT5PbkJ1dHRvblVwKG1fcFdpZGdldCwgcFBhZ2VWaWV3LCBiUmVzZXQsIGJFeGl0LG5GbGFncyk7CisKKwkJCWlmIChiUmVzZXQpIHJldHVybiBUUlVFOworCQkJaWYgKGJFeGl0KSByZXR1cm4gVFJVRTsKKworCQkJQ0ZGTF9Gb3JtRmlsbGVyOjpPbkNoYXIocEFubm90LCBuQ2hhciwgbkZsYWdzKTsKKworCQkJaWYgKENQV0xfUmFkaW9CdXR0b24gKiBwV25kID0gKENQV0xfUmFkaW9CdXR0b24qKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpKQorCQkJCXBXbmQtPlNldENoZWNrKFRSVUUpOworCQkJQ29tbWl0RGF0YShwUGFnZVZpZXcsbkZsYWdzKTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJZGVmYXVsdDoKKwkJcmV0dXJuIENGRkxfRm9ybUZpbGxlcjo6T25DaGFyKHBBbm5vdCwgbkNoYXIsIG5GbGFncyk7CisJfQorfQorCitGWF9CT09MCUNGRkxfUmFkaW9CdXR0b246Ok9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9VSU5UIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQ0ZGTF9CdXR0b246Ok9uTEJ1dHRvblVwKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKworCWlmIChJc1ZhbGlkKCkpCisJeworCQlpZiAoQ1BXTF9SYWRpb0J1dHRvbiAqIHBXbmQgPSAoQ1BXTF9SYWRpb0J1dHRvbiopR2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSkpCisJCQlwV25kLT5TZXRDaGVjayhUUlVFKTsKKworCQlpZiAoIUNvbW1pdERhdGEocFBhZ2VWaWV3LG5GbGFncykpIHJldHVybiBGQUxTRTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDRkZMX1JhZGlvQnV0dG9uOjpJc0RhdGFDaGFuZ2VkKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKKwlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworCisJaWYgKENQV0xfUmFkaW9CdXR0b24qIHBXbmQgPSAoQ1BXTF9SYWRpb0J1dHRvbiopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJcmV0dXJuIHBXbmQtPklzQ2hlY2tlZCgpICE9IG1fcFdpZGdldC0+SXNDaGVja2VkKCk7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIENGRkxfUmFkaW9CdXR0b246OlNhdmVEYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKKwlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworCisJaWYgKENQV0xfUmFkaW9CdXR0b24qIHBXbmQgPSAoQ1BXTF9SYWRpb0J1dHRvbiopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJCisJCUZYX0JPT0wgYk5ld0NoZWNrZWQgPSBwV25kLT5Jc0NoZWNrZWQoKTsKKworCQlpZiAoYk5ld0NoZWNrZWQpCisJCXsKKwkJCUNQREZfRm9ybUZpZWxkKiBwRmllbGQgPSBtX3BXaWRnZXQtPkdldEZvcm1GaWVsZCgpOworCQkJQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsKKworCQkJZm9yIChGWF9JTlQzMiBpPTAsc3o9cEZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGk8c3o7IGkrKykKKwkJCXsKKwkJCQlpZiAoQ1BERl9Gb3JtQ29udHJvbCogcEN0cmwgPSBwRmllbGQtPkdldENvbnRyb2woaSkpCisJCQkJeworCQkJCQlpZiAocEN0cmwtPklzQ2hlY2tlZCgpKQorCQkJCQl7CisJCQkJCQlicmVhazsKKwkJCQkJfQorCQkJCX0KKwkJCX0KKwkJfQorCisJCW1fcFdpZGdldC0+U2V0Q2hlY2soYk5ld0NoZWNrZWQsIEZBTFNFKTsKKwkJbV9wV2lkZ2V0LT5VcGRhdGVGaWVsZCgpOworCQlTZXRDaGFuZ2VNYXJrKCk7CisJfQorfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9UZXh0RmllbGQuY3BwIGIvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfVGV4dEZpZWxkLmNwcAppbmRleCA3NjQ0ZDRiLi44Y2Q2MmZhIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9UZXh0RmllbGQuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX1RleHRGaWVsZC5jcHAKQEAgLTEsNDEyICsxLDQxMiBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotLy8jaW5jbHVkZSAiLi4vaW5jbHVkZS9Gb3JtRmlsbGVyLmgiDQotLy8jaW5jbHVkZSAiLi4vaW5jbHVkZS9GRkxfRm9ybUZpbGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1RleHRGaWVsZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX0NCQV9Gb250bWFwLmgiDQotLy8jaW5jbHVkZSAiLi4vaW5jbHVkZS9GRkxfTm90aWZ5LmgiDQotDQotQ0ZGTF9FZGl0VW5kb0l0ZW06OkNGRkxfRWRpdFVuZG9JdGVtKENQV0xfRWRpdCogcEVkaXQpIDogbV9wRWRpdChwRWRpdCkNCi17DQotfQ0KLQ0KLUNGRkxfRWRpdFVuZG9JdGVtOjp+Q0ZGTF9FZGl0VW5kb0l0ZW0oKQ0KLXsNCi19DQotDQotdm9pZCBDRkZMX0VkaXRVbmRvSXRlbTo6VW5kbygpDQotew0KLX0NCi0NCi12b2lkIENGRkxfRWRpdFVuZG9JdGVtOjpSZWRvKCkNCi17DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENGRkxfRWRpdFVuZG9JdGVtOjpHZXREZXNjcigpDQotew0KLQlyZXR1cm4gTCJJbnB1dCI7DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9FZGl0VW5kb0l0ZW06OlJlbGVhc2UoKQ0KLXsNCi0JZGVsZXRlIHRoaXM7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZGTF9UZXh0RmllbGQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGRkxfVGV4dEZpZWxkOjpDRkZMX1RleHRGaWVsZChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX0Fubm90KiBwQW5ub3QpIDoNCi0JQ0ZGTF9Gb3JtRmlsbGVyKHBBcHAsIHBBbm5vdCksDQotCW1fcEZvbnRNYXAoTlVMTCkvLywNCi0JLy9tX3BTcGVsbENoZWNrKE5VTEwpDQotew0KLQltX1N0YXRlLm5TdGFydCA9IG1fU3RhdGUubkVuZCA9IDA7DQotfQ0KLQ0KLUNGRkxfVGV4dEZpZWxkOjp+Q0ZGTF9UZXh0RmllbGQoKQ0KLXsNCi0JaWYgKG1fcEZvbnRNYXApDQotCXsNCi0JCWRlbGV0ZSBtX3BGb250TWFwOw0KLQkJbV9wRm9udE1hcCA9IE5VTEw7DQotCX0NCi0NCi19DQotDQotUFdMX0NSRUFURVBBUkFNIENGRkxfVGV4dEZpZWxkOjpHZXRDcmVhdGVQYXJhbSgpDQotew0KLQlQV0xfQ1JFQVRFUEFSQU0gY3AgPSBDRkZMX0Zvcm1GaWxsZXI6OkdldENyZWF0ZVBhcmFtKCk7DQotDQotCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7DQotCWludCBuRmxhZ3MgPSBtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKTsNCi0NCi0NCi0JaWYgKG5GbGFncyAmIEZJRUxERkxBR19QQVNTV09SRCkNCi0JewkJDQotCQljcC5kd0ZsYWdzIHw9IFBFU19QQVNTV09SRDsNCi0JfQ0KLQ0KLQlpZiAoIShuRmxhZ3MgJiBGSUVMREZMQUdfRE9OT1RTUEVMTENIRUNLKSkNCi0JewkJDQotCX0NCi0NCi0JaWYgKG5GbGFncyAmIEZJRUxERkxBR19NVUxUSUxJTkUpDQotCXsJCQ0KLQkJY3AuZHdGbGFncyB8PSBQRVNfTVVMVElMSU5FIHwgUEVTX0FVVE9SRVRVUk4gfCBQRVNfVE9QOw0KLQ0KLQkJaWYgKCEobkZsYWdzICYgRklFTERGTEFHX0RPTk9UU0NST0xMKSkNCi0JCXsNCi0JCQljcC5kd0ZsYWdzIHw9IFBXU19WU0NST0xMIHwgUEVTX0FVVE9TQ1JPTEw7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQljcC5kd0ZsYWdzIHw9IFBFU19DRU5URVI7DQotDQotCQlpZiAoIShuRmxhZ3MgJiBGSUVMREZMQUdfRE9OT1RTQ1JPTEwpKQ0KLQkJew0KLQkJCWNwLmR3RmxhZ3MgfD0gUEVTX0FVVE9TQ1JPTEw7DQotCQl9DQotCX0NCi0NCi0JaWYgKG5GbGFncyAmIEZJRUxERkxBR19DT01CKQ0KLQl7CQkNCi0JCWNwLmR3RmxhZ3MgfD0gUEVTX0NIQVJBUlJBWTsNCi0JfQ0KLQ0KLQlpZiAobkZsYWdzICYgRklFTERGTEFHX1JJQ0hURVhUKQ0KLQl7CQkNCi0JCWNwLmR3RmxhZ3MgfD0gUEVTX1JJQ0g7DQotCX0NCi0NCi0JY3AuZHdGbGFncyB8PSBQRVNfVU5ETzsNCi0JDQotIAlzd2l0Y2ggKG1fcFdpZGdldC0+R2V0QWxpZ25tZW50KCkpDQotIAl7DQotIAlkZWZhdWx0Og0KLSAJY2FzZSBCRl9BTElHTl9MRUZUOg0KLSAJCWNwLmR3RmxhZ3MgfD0gUEVTX0xFRlQ7DQotIAkJYnJlYWs7DQotIAljYXNlIEJGX0FMSUdOX01JRERMRToNCi0gCQljcC5kd0ZsYWdzIHw9IFBFU19NSURETEU7DQotIAkJYnJlYWs7DQotIAljYXNlIEJGX0FMSUdOX1JJR0hUOg0KLSAJCWNwLmR3RmxhZ3MgfD0gUEVTX1JJR0hUOw0KLSAJCWJyZWFrOw0KLSAJfQ0KLQ0KLQlpZiAoIW1fcEZvbnRNYXApDQotCXsNCi0JCUFTU0VSVCh0aGlzLT5tX3BBcHAgIT0gTlVMTCk7DQotCQltX3BGb250TWFwID0gbmV3IENCQV9Gb250TWFwKG1fcFdpZGdldCwgLypJU3lzdGVtSGFuZGxlOjpHZXRTeXN0ZW1IYW5kbGVyKG1fcEFwcCkqL21fcEFwcC0+R2V0U3lzSGFuZGxlcigpKTsNCi0JCW1fcEZvbnRNYXAtPkluaXRpYWwoKTsNCi0JfQ0KLQljcC5wRm9udE1hcCA9IG1fcEZvbnRNYXA7DQotCWNwLnBGb2N1c0hhbmRsZXIgPSB0aGlzOw0KLQ0KLQlyZXR1cm4gY3A7DQotfQ0KLQ0KLUNQV0xfV25kKiBDRkZMX1RleHRGaWVsZDo6TmV3UERGV2luZG93KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3AsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCUNQV0xfRWRpdCAqIHBXbmQgPSBuZXcgQ1BXTF9FZGl0KCk7DQotCQlwV25kLT5BdHRhY2hGRkxEYXRhKHRoaXMpOw0KLQlwV25kLT5DcmVhdGUoY3ApOw0KLQ0KLQ0KLQ0KLQlBU1NFUlQobV9wQXBwICE9IE5VTEwpOw0KLQlDRkZMX0lGb3JtRmlsbGVyKiBwSUZvcm1GaWxsZXIgPSBtX3BBcHAtPkdldElGb3JtRmlsbGVyKCk7DQotCXBXbmQtPlNldEZpbGxlck5vdGlmeShwSUZvcm1GaWxsZXIpOw0KLQ0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQlGWF9JTlQzMiBuTWF4TGVuID0gbV9wV2lkZ2V0LT5HZXRNYXhMZW4oKTsNCi0JQ0ZYX1dpZGVTdHJpbmcgc3dWYWx1ZSA9IG1fcFdpZGdldC0+R2V0VmFsdWUoKTsNCi0JDQotCWlmIChuTWF4TGVuID4gMCkNCi0Jew0KLQkJaWYgKHBXbmQtPkhhc0ZsYWcoUEVTX0NIQVJBUlJBWSkpDQotCQl7DQotCQkJcFduZC0+U2V0Q2hhckFycmF5KG5NYXhMZW4pOw0KLQkJCXBXbmQtPlNldEFsaWduRm9ybWF0VihQRUFWX0NFTlRFUik7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJcFduZC0+U2V0TGltaXRDaGFyKG5NYXhMZW4pOw0KLQkJfQ0KLQl9DQotCQ0KLQlwV25kLT5TZXRUZXh0KHN3VmFsdWUpOw0KLQkNCi0JcmV0dXJuIHBXbmQ7DQotfQ0KLQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9UZXh0RmllbGQ6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQ0KLXsNCi0Jc3dpdGNoIChuQ2hhcikNCi0Jew0KLQljYXNlIEZXTF9WS0VZX1JldHVybjoNCi0gCQlpZiAoIShtX3BXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19NVUxUSUxJTkUpKQ0KLSAJCXsNCi0gCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gdGhpcy0+R2V0Q3VyUGFnZVZpZXcoKTsNCi0gCQkJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsNCi0gCQkJbV9iVmFsaWQgPSAhbV9iVmFsaWQ7DQotCQkJQ1BERl9SZWN0IHJjQW5ub3QgPSBwQW5ub3QtPkdldFJlY3QoKTsNCi0JCQltX3BBcHAtPkZGSV9JbnZhbGlkYXRlKHBBbm5vdC0+R2V0UERGUGFnZSgpLCByY0Fubm90LmxlZnQsIHJjQW5ub3QudG9wLCByY0Fubm90LnJpZ2h0LCByY0Fubm90LmJvdHRvbSk7DQotIA0KLSAJCQlpZiAobV9iVmFsaWQpDQotIAkJCXsNCi0gCQkJCWlmIChDUFdMX1duZCogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpKQ0KLSAJCQkJCXBXbmQtPlNldEZvY3VzKCk7DQotIAkJCX0NCi0gCQkJZWxzZQ0KLSAJCQl7DQotIAkJCQlpZiAoQ29tbWl0RGF0YShwUGFnZVZpZXcsIG5GbGFncykpDQotIAkJCQl7DQotIAkJCQkJRGVzdHJveVBERldpbmRvdyhwUGFnZVZpZXcpOw0KLSAJCQkJCXJldHVybiBUUlVFOw0KLSAJCQkJfQ0KLSAJCQkJZWxzZQ0KLSAJCQkJew0KLSAJCQkJCXJldHVybiBGQUxTRTsNCi0gCQkJCX0NCi0gCQkJfQ0KLSAJCX0NCi0JCWJyZWFrOw0KLQljYXNlIEZXTF9WS0VZX0VzY2FwZToNCi0JCXsNCi0JCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSB0aGlzLT5HZXRDdXJQYWdlVmlldygpOw0KLQkJCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotCQkJRXNjYXBlRmlsbGVyKHBQYWdlVmlldyxUUlVFKTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gQ0ZGTF9Gb3JtRmlsbGVyOjpPbkNoYXIocEFubm90LCBuQ2hhciwgbkZsYWdzKTsNCi19DQotDQotRlhfQk9PTAlDRkZMX1RleHRGaWVsZDo6SXNEYXRhQ2hhbmdlZChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLSAJaWYgKENQV0xfRWRpdCAqIHBFZGl0ID0gKENQV0xfRWRpdCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLSAJCXJldHVybiBwRWRpdC0+R2V0VGV4dCgpICE9IG1fcFdpZGdldC0+R2V0VmFsdWUoKTsNCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENGRkxfVGV4dEZpZWxkOjpTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQlpZiAoQ1BXTF9FZGl0KiBwV25kID0gKENQV0xfRWRpdCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQl7DQotCQlDRlhfV2lkZVN0cmluZyBzT2xkVmFsdWUgPSBtX3BXaWRnZXQtPkdldFZhbHVlKCk7DQotCQlDRlhfV2lkZVN0cmluZyBzTmV3VmFsdWUgPSBwV25kLT5HZXRUZXh0KCk7DQotDQotCQltX3BXaWRnZXQtPlNldFZhbHVlKHNOZXdWYWx1ZSwgRkFMU0UpOwkNCi0JCW1fcFdpZGdldC0+UmVzZXRGaWVsZEFwcGVhcmFuY2UoVFJVRSk7DQotCQltX3BXaWRnZXQtPlVwZGF0ZUZpZWxkKCk7DQotCQlTZXRDaGFuZ2VNYXJrKCk7DQotCX0NCi19DQotDQotdm9pZCBDRkZMX1RleHRGaWVsZDo6R2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwNCi0JCQkJCQkJCQlQREZTREtfRmllbGRBY3Rpb24mIGZhKQ0KLXsNCi0Jc3dpdGNoICh0eXBlKQ0KLQl7DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2U6DQotCQlpZiAoQ1BXTF9FZGl0KiBwV25kID0gKENQV0xfRWRpdCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQ0KLQkJew0KLQkJCWZhLmJGaWVsZEZ1bGwgPSBwV25kLT5Jc1RleHRGdWxsKCk7CQ0KLQ0KLQkJCWZhLnNWYWx1ZSA9IHBXbmQtPkdldFRleHQoKTsNCi0JCQkNCi0JCQlpZiAoZmEuYkZpZWxkRnVsbCkNCi0JCQl7DQotCQkJCWZhLnNDaGFuZ2UgPSBMIiI7DQotCQkJCWZhLnNDaGFuZ2VFeCA9IEwiIjsNCi0JCQl9DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FBY3Rpb246OlZhbGlkYXRlOg0KLQkJaWYgKENQV0xfRWRpdCogcFduZCA9IChDUFdMX0VkaXQqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0JCXsNCi0JCQlmYS5zVmFsdWUgPSBwV25kLT5HZXRUZXh0KCk7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FBY3Rpb246Okxvc2VGb2N1czoNCi0JY2FzZSBDUERGX0FBY3Rpb246OkdldEZvY3VzOg0KLQkJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsNCi0JCWZhLnNWYWx1ZSA9IG1fcFdpZGdldC0+R2V0VmFsdWUoKTsNCi0JCWJyZWFrOw0KLQlkZWZhdWx0Og0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotdm9pZCBDRkZMX1RleHRGaWVsZDo6U2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgDQotIAkJCQkJCQkJCWNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmEpDQotew0KLQlzd2l0Y2ggKHR5cGUpDQotCXsNCi0JY2FzZSBDUERGX0FBY3Rpb246OktleVN0cm9rZToNCi0JCWlmIChDUFdMX0VkaXQgKiBwRWRpdCA9IChDUFdMX0VkaXQqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkNCi0JCXsNCi0JCQlwRWRpdC0+U2V0Rm9jdXMoKTsNCi0JCQlwRWRpdC0+U2V0U2VsKGZhLm5TZWxTdGFydCwgZmEublNlbEVuZCk7DQotCQkJcEVkaXQtPlJlcGxhY2VTZWwoZmEuc0NoYW5nZSk7DQotCQl9DQotCQlicmVhazsNCi0JZGVmYXVsdDoNCi0JCWJyZWFrOw0KLQl9DQotfQ0KLQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9UZXh0RmllbGQ6OklzQWN0aW9uRGF0YUNoYW5nZWQoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBjb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhT2xkLCANCi0JCQkJCQkJCQljb25zdCBQREZTREtfRmllbGRBY3Rpb24mIGZhTmV3KQ0KLXsNCi0Jc3dpdGNoICh0eXBlKQ0KLQl7DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2U6DQotCQlyZXR1cm4gKCFmYU9sZC5iRmllbGRGdWxsICYmIGZhT2xkLm5TZWxFbmQgIT0gZmFOZXcublNlbEVuZCkgfHwgZmFPbGQublNlbFN0YXJ0ICE9IGZhTmV3Lm5TZWxTdGFydCB8fA0KLQkJCWZhT2xkLnNDaGFuZ2UgIT0gZmFOZXcuc0NoYW5nZTsNCi0JZGVmYXVsdDoNCi0JCWJyZWFrOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBDRkZMX1RleHRGaWVsZDo6U2F2ZVN0YXRlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotDQotCWlmIChDUFdMX0VkaXQqIHBXbmQgPSAoQ1BXTF9FZGl0KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpDQotCXsNCi0JCXBXbmQtPkdldFNlbChtX1N0YXRlLm5TdGFydCwgbV9TdGF0ZS5uRW5kKTsNCi0JCW1fU3RhdGUuc1ZhbHVlID0gcFduZC0+R2V0VGV4dCgpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9UZXh0RmllbGQ6OlJlc3RvcmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQ0KLQlpZiAoQ1BXTF9FZGl0KiBwV25kID0gKENQV0xfRWRpdCopR2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSkpDQotCXsNCi0JCXBXbmQtPlNldFRleHQobV9TdGF0ZS5zVmFsdWUpOw0KLQkJcFduZC0+U2V0U2VsKG1fU3RhdGUublN0YXJ0LCBtX1N0YXRlLm5FbmQpOw0KLQl9DQotfQ0KLQ0KLUNQV0xfV25kKiBDRkZMX1RleHRGaWVsZDo6UmVzZXRQREZXaW5kb3coQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9CT09MIGJSZXN0b3JlVmFsdWUpDQotew0KLQlpZiAoYlJlc3RvcmVWYWx1ZSkNCi0JCVNhdmVTdGF0ZShwUGFnZVZpZXcpOw0KLQ0KLQlEZXN0cm95UERGV2luZG93KHBQYWdlVmlldyk7DQotDQotCUNQV0xfV25kKiBwUmV0ID0gTlVMTDsNCi0NCi0JaWYgKGJSZXN0b3JlVmFsdWUpDQotCXsNCi0JCVJlc3RvcmVTdGF0ZShwUGFnZVZpZXcpOw0KLQkJcFJldCA9IHRoaXMtPkdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKTsNCi0JfQ0KLQllbHNlDQotCQlwUmV0ID0gdGhpcy0+R2V0UERGV2luZG93KHBQYWdlVmlldywgVFJVRSk7DQotDQotCW1fcFdpZGdldC0+VXBkYXRlRmllbGQoKTsNCi0JDQotCXJldHVybiBwUmV0Ow0KLX0NCi0NCi12b2lkIENGRkxfVGV4dEZpZWxkOjpPblNldEZvY3VzKENQV0xfV25kKiBwV25kKQ0KLXsNCi0JQVNTRVJUKG1fcEFwcCAhPSBOVUxMKTsNCi0JDQotIAlBU1NFUlQocFduZCAhPSBOVUxMKTsNCi0gDQotIAlpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gUFdMX0NMQVNTTkFNRV9FRElUKQ0KLSAJew0KLSAJCUNQV0xfRWRpdCogcEVkaXQgPSAoQ1BXTF9FZGl0KilwV25kOw0KLQkJcEVkaXQtPlNldENoYXJTZXQoMTM0KTsNCi0JCXBFZGl0LT5TZXRDb2RlUGFnZSg5MzYpOw0KLSANCi0JCXBFZGl0LT5TZXRSZWFkeVRvSW5wdXQoKTsNCi0JCUNGWF9XaWRlU3RyaW5nIHdzVGV4dCA9IHBFZGl0LT5HZXRUZXh0KCk7DQotCQlpbnQgbkNoYXJhY3RlcnMgPSB3c1RleHQuR2V0TGVuZ3RoKCk7DQotCQlDRlhfQnl0ZVN0cmluZyBic1VURlRleHQgPSB3c1RleHQuVVRGMTZMRV9FbmNvZGUoKTsNCi0JCXVuc2lnbmVkIHNob3J0KiBwQnVmZmVyID0gKHVuc2lnbmVkIHNob3J0KikoRlhfTFBDU1RSKWJzVVRGVGV4dDsNCi0JCW1fcEFwcC0+RkZJX09uU2V0RmllbGRJbnB1dEZvY3VzKG1fcFdpZGdldC0+R2V0Rm9ybUZpZWxkKCksIHBCdWZmZXIsIG5DaGFyYWN0ZXJzLCBUUlVFKTsNCi0gDQotIAkJcEVkaXQtPlNldEVkaXROb3RpZnkodGhpcyk7DQotIAkJLy9wVW5kby0+QmVnaW5FZGl0KHBEb2N1bWVudCk7DQotIAl9DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9UZXh0RmllbGQ6Ok9uS2lsbEZvY3VzKENQV0xfV25kKiBwV25kKQ0KLXsNCi0NCi19DQotDQotRlhfQk9PTAlDRkZMX1RleHRGaWVsZDo6Q2FuQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9UZXh0RmllbGQ6OkNhbkN1dChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZGTF9UZXh0RmllbGQ6OkNhblBhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBDRkZMX1RleHRGaWVsZDo6RG9Db3B5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotDQotfQ0KLQ0KLXZvaWQgQ0ZGTF9UZXh0RmllbGQ6OkRvQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotfQ0KLQ0KLXZvaWQgQ0ZGTF9UZXh0RmllbGQ6OkRvUGFzdGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0NCi19DQotDQotdm9pZCBDRkZMX1RleHRGaWVsZDo6T25BZGRVbmRvKENQV0xfRWRpdCogcEVkaXQpDQotew0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisvLyNpbmNsdWRlICIuLi9pbmNsdWRlL0Zvcm1GaWxsZXIuaCIKKy8vI2luY2x1ZGUgIi4uL2luY2x1ZGUvRkZMX0Zvcm1GaWxsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Zvcm1maWxsZXIvRkZMX1RleHRGaWVsZC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfQ0JBX0ZvbnRtYXAuaCIKKy8vI2luY2x1ZGUgIi4uL2luY2x1ZGUvRkZMX05vdGlmeS5oIgorCitDRkZMX0VkaXRVbmRvSXRlbTo6Q0ZGTF9FZGl0VW5kb0l0ZW0oQ1BXTF9FZGl0KiBwRWRpdCkgOiBtX3BFZGl0KHBFZGl0KQoreworfQorCitDRkZMX0VkaXRVbmRvSXRlbTo6fkNGRkxfRWRpdFVuZG9JdGVtKCkKK3sKK30KKwordm9pZCBDRkZMX0VkaXRVbmRvSXRlbTo6VW5kbygpCit7Cit9CisKK3ZvaWQgQ0ZGTF9FZGl0VW5kb0l0ZW06OlJlZG8oKQoreworfQorCitDRlhfV2lkZVN0cmluZyBDRkZMX0VkaXRVbmRvSXRlbTo6R2V0RGVzY3IoKQoreworCXJldHVybiBMIklucHV0IjsKK30KKwordm9pZCBDRkZMX0VkaXRVbmRvSXRlbTo6UmVsZWFzZSgpCit7CisJZGVsZXRlIHRoaXM7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZGTF9UZXh0RmllbGQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRkZMX1RleHRGaWVsZDo6Q0ZGTF9UZXh0RmllbGQoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19Bbm5vdCogcEFubm90KSA6CisJQ0ZGTF9Gb3JtRmlsbGVyKHBBcHAsIHBBbm5vdCksCisJbV9wRm9udE1hcChOVUxMKS8vLAorCS8vbV9wU3BlbGxDaGVjayhOVUxMKQoreworCW1fU3RhdGUublN0YXJ0ID0gbV9TdGF0ZS5uRW5kID0gMDsKK30KKworQ0ZGTF9UZXh0RmllbGQ6On5DRkZMX1RleHRGaWVsZCgpCit7CisJaWYgKG1fcEZvbnRNYXApCisJeworCQlkZWxldGUgbV9wRm9udE1hcDsKKwkJbV9wRm9udE1hcCA9IE5VTEw7CisJfQorCit9CisKK1BXTF9DUkVBVEVQQVJBTSBDRkZMX1RleHRGaWVsZDo6R2V0Q3JlYXRlUGFyYW0oKQoreworCVBXTF9DUkVBVEVQQVJBTSBjcCA9IENGRkxfRm9ybUZpbGxlcjo6R2V0Q3JlYXRlUGFyYW0oKTsKKworCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisJaW50IG5GbGFncyA9IG1fcFdpZGdldC0+R2V0RmllbGRGbGFncygpOworCisKKwlpZiAobkZsYWdzICYgRklFTERGTEFHX1BBU1NXT1JEKQorCXsJCQorCQljcC5kd0ZsYWdzIHw9IFBFU19QQVNTV09SRDsKKwl9CisKKwlpZiAoIShuRmxhZ3MgJiBGSUVMREZMQUdfRE9OT1RTUEVMTENIRUNLKSkKKwl7CQkKKwl9CisKKwlpZiAobkZsYWdzICYgRklFTERGTEFHX01VTFRJTElORSkKKwl7CQkKKwkJY3AuZHdGbGFncyB8PSBQRVNfTVVMVElMSU5FIHwgUEVTX0FVVE9SRVRVUk4gfCBQRVNfVE9QOworCisJCWlmICghKG5GbGFncyAmIEZJRUxERkxBR19ET05PVFNDUk9MTCkpCisJCXsKKwkJCWNwLmR3RmxhZ3MgfD0gUFdTX1ZTQ1JPTEwgfCBQRVNfQVVUT1NDUk9MTDsKKwkJfQorCX0KKwllbHNlCisJeworCQljcC5kd0ZsYWdzIHw9IFBFU19DRU5URVI7CisKKwkJaWYgKCEobkZsYWdzICYgRklFTERGTEFHX0RPTk9UU0NST0xMKSkKKwkJeworCQkJY3AuZHdGbGFncyB8PSBQRVNfQVVUT1NDUk9MTDsKKwkJfQorCX0KKworCWlmIChuRmxhZ3MgJiBGSUVMREZMQUdfQ09NQikKKwl7CQkKKwkJY3AuZHdGbGFncyB8PSBQRVNfQ0hBUkFSUkFZOworCX0KKworCWlmIChuRmxhZ3MgJiBGSUVMREZMQUdfUklDSFRFWFQpCisJewkJCisJCWNwLmR3RmxhZ3MgfD0gUEVTX1JJQ0g7CisJfQorCisJY3AuZHdGbGFncyB8PSBQRVNfVU5ETzsKKwkKKyAJc3dpdGNoIChtX3BXaWRnZXQtPkdldEFsaWdubWVudCgpKQorIAl7CisgCWRlZmF1bHQ6CisgCWNhc2UgQkZfQUxJR05fTEVGVDoKKyAJCWNwLmR3RmxhZ3MgfD0gUEVTX0xFRlQ7CisgCQlicmVhazsKKyAJY2FzZSBCRl9BTElHTl9NSURETEU6CisgCQljcC5kd0ZsYWdzIHw9IFBFU19NSURETEU7CisgCQlicmVhazsKKyAJY2FzZSBCRl9BTElHTl9SSUdIVDoKKyAJCWNwLmR3RmxhZ3MgfD0gUEVTX1JJR0hUOworIAkJYnJlYWs7CisgCX0KKworCWlmICghbV9wRm9udE1hcCkKKwl7CisJCUFTU0VSVCh0aGlzLT5tX3BBcHAgIT0gTlVMTCk7CisJCW1fcEZvbnRNYXAgPSBuZXcgQ0JBX0ZvbnRNYXAobV9wV2lkZ2V0LCAvKklTeXN0ZW1IYW5kbGU6OkdldFN5c3RlbUhhbmRsZXIobV9wQXBwKSovbV9wQXBwLT5HZXRTeXNIYW5kbGVyKCkpOworCQltX3BGb250TWFwLT5Jbml0aWFsKCk7CisJfQorCWNwLnBGb250TWFwID0gbV9wRm9udE1hcDsKKwljcC5wRm9jdXNIYW5kbGVyID0gdGhpczsKKworCXJldHVybiBjcDsKK30KKworQ1BXTF9XbmQqIENGRkxfVGV4dEZpZWxkOjpOZXdQREZXaW5kb3coY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCUNQV0xfRWRpdCAqIHBXbmQgPSBuZXcgQ1BXTF9FZGl0KCk7CisJCXBXbmQtPkF0dGFjaEZGTERhdGEodGhpcyk7CisJcFduZC0+Q3JlYXRlKGNwKTsKKworCisKKwlBU1NFUlQobV9wQXBwICE9IE5VTEwpOworCUNGRkxfSUZvcm1GaWxsZXIqIHBJRm9ybUZpbGxlciA9IG1fcEFwcC0+R2V0SUZvcm1GaWxsZXIoKTsKKwlwV25kLT5TZXRGaWxsZXJOb3RpZnkocElGb3JtRmlsbGVyKTsKKworCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisJRlhfSU5UMzIgbk1heExlbiA9IG1fcFdpZGdldC0+R2V0TWF4TGVuKCk7CisJQ0ZYX1dpZGVTdHJpbmcgc3dWYWx1ZSA9IG1fcFdpZGdldC0+R2V0VmFsdWUoKTsKKwkKKwlpZiAobk1heExlbiA+IDApCisJeworCQlpZiAocFduZC0+SGFzRmxhZyhQRVNfQ0hBUkFSUkFZKSkKKwkJeworCQkJcFduZC0+U2V0Q2hhckFycmF5KG5NYXhMZW4pOworCQkJcFduZC0+U2V0QWxpZ25Gb3JtYXRWKFBFQVZfQ0VOVEVSKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCXBXbmQtPlNldExpbWl0Q2hhcihuTWF4TGVuKTsKKwkJfQorCX0KKwkKKwlwV25kLT5TZXRUZXh0KHN3VmFsdWUpOworCQorCXJldHVybiBwV25kOworfQorCisKK0ZYX0JPT0wJQ0ZGTF9UZXh0RmllbGQ6Ok9uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX1VJTlQgbkNoYXIsIEZYX1VJTlQgbkZsYWdzKQoreworCXN3aXRjaCAobkNoYXIpCisJeworCWNhc2UgRldMX1ZLRVlfUmV0dXJuOgorIAkJaWYgKCEobV9wV2lkZ2V0LT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfTVVMVElMSU5FKSkKKyAJCXsKKyAJCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSB0aGlzLT5HZXRDdXJQYWdlVmlldygpOworIAkJCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7CisgCQkJbV9iVmFsaWQgPSAhbV9iVmFsaWQ7CisJCQlDUERGX1JlY3QgcmNBbm5vdCA9IHBBbm5vdC0+R2V0UmVjdCgpOworCQkJbV9wQXBwLT5GRklfSW52YWxpZGF0ZShwQW5ub3QtPkdldFBERlBhZ2UoKSwgcmNBbm5vdC5sZWZ0LCByY0Fubm90LnRvcCwgcmNBbm5vdC5yaWdodCwgcmNBbm5vdC5ib3R0b20pOworIAorIAkJCWlmIChtX2JWYWxpZCkKKyAJCQl7CisgCQkJCWlmIChDUFdMX1duZCogcFduZCA9IEdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpKQorIAkJCQkJcFduZC0+U2V0Rm9jdXMoKTsKKyAJCQl9CisgCQkJZWxzZQorIAkJCXsKKyAJCQkJaWYgKENvbW1pdERhdGEocFBhZ2VWaWV3LCBuRmxhZ3MpKQorIAkJCQl7CisgCQkJCQlEZXN0cm95UERGV2luZG93KHBQYWdlVmlldyk7CisgCQkJCQlyZXR1cm4gVFJVRTsKKyAJCQkJfQorIAkJCQllbHNlCisgCQkJCXsKKyAJCQkJCXJldHVybiBGQUxTRTsKKyAJCQkJfQorIAkJCX0KKyAJCX0KKwkJYnJlYWs7CisJY2FzZSBGV0xfVktFWV9Fc2NhcGU6CisJCXsKKwkJCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHRoaXMtPkdldEN1clBhZ2VWaWV3KCk7CisJCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworCQkJRXNjYXBlRmlsbGVyKHBQYWdlVmlldyxUUlVFKTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCisJcmV0dXJuIENGRkxfRm9ybUZpbGxlcjo6T25DaGFyKHBBbm5vdCwgbkNoYXIsIG5GbGFncyk7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9UZXh0RmllbGQ6OklzRGF0YUNoYW5nZWQoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCUFTU0VSVChtX3BXaWRnZXQgIT0gTlVMTCk7CisKKyAJaWYgKENQV0xfRWRpdCAqIHBFZGl0ID0gKENQV0xfRWRpdCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorIAkJcmV0dXJuIHBFZGl0LT5HZXRUZXh0KCkgIT0gbV9wV2lkZ2V0LT5HZXRWYWx1ZSgpOworCisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIENGRkxfVGV4dEZpZWxkOjpTYXZlRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJQVNTRVJUKG1fcFdpZGdldCAhPSBOVUxMKTsKKworCWlmIChDUFdMX0VkaXQqIHBXbmQgPSAoQ1BXTF9FZGl0KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpCisJeworCQlDRlhfV2lkZVN0cmluZyBzT2xkVmFsdWUgPSBtX3BXaWRnZXQtPkdldFZhbHVlKCk7CisJCUNGWF9XaWRlU3RyaW5nIHNOZXdWYWx1ZSA9IHBXbmQtPkdldFRleHQoKTsKKworCQltX3BXaWRnZXQtPlNldFZhbHVlKHNOZXdWYWx1ZSwgRkFMU0UpOwkKKwkJbV9wV2lkZ2V0LT5SZXNldEZpZWxkQXBwZWFyYW5jZShUUlVFKTsKKwkJbV9wV2lkZ2V0LT5VcGRhdGVGaWVsZCgpOworCQlTZXRDaGFuZ2VNYXJrKCk7CisJfQorfQorCit2b2lkIENGRkxfVGV4dEZpZWxkOjpHZXRBY3Rpb25EYXRhKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLAorCQkJCQkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSkKK3sKKwlzd2l0Y2ggKHR5cGUpCisJeworCWNhc2UgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2U6CisJCWlmIChDUFdMX0VkaXQqIHBXbmQgPSAoQ1BXTF9FZGl0KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSkpCisJCXsKKwkJCWZhLmJGaWVsZEZ1bGwgPSBwV25kLT5Jc1RleHRGdWxsKCk7CQorCisJCQlmYS5zVmFsdWUgPSBwV25kLT5HZXRUZXh0KCk7CisJCQkKKwkJCWlmIChmYS5iRmllbGRGdWxsKQorCQkJeworCQkJCWZhLnNDaGFuZ2UgPSBMIiI7CisJCQkJZmEuc0NoYW5nZUV4ID0gTCIiOworCQkJfQorCQl9CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpWYWxpZGF0ZToKKwkJaWYgKENQV0xfRWRpdCogcFduZCA9IChDUFdMX0VkaXQqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwkJeworCQkJZmEuc1ZhbHVlID0gcFduZC0+R2V0VGV4dCgpOworCQl9CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpMb3NlRm9jdXM6CisJY2FzZSBDUERGX0FBY3Rpb246OkdldEZvY3VzOgorCQlBU1NFUlQobV9wV2lkZ2V0ICE9IE5VTEwpOworCQlmYS5zVmFsdWUgPSBtX3BXaWRnZXQtPkdldFZhbHVlKCk7CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCWJyZWFrOworCX0KK30KKwordm9pZCBDRkZMX1RleHRGaWVsZDo6U2V0QWN0aW9uRGF0YShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgCisgCQkJCQkJCQkJY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYSkKK3sKKwlzd2l0Y2ggKHR5cGUpCisJeworCWNhc2UgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2U6CisJCWlmIChDUFdMX0VkaXQgKiBwRWRpdCA9IChDUFdMX0VkaXQqKUdldFBERldpbmRvdyhwUGFnZVZpZXcsIEZBTFNFKSkKKwkJeworCQkJcEVkaXQtPlNldEZvY3VzKCk7CisJCQlwRWRpdC0+U2V0U2VsKGZhLm5TZWxTdGFydCwgZmEublNlbEVuZCk7CisJCQlwRWRpdC0+UmVwbGFjZVNlbChmYS5zQ2hhbmdlKTsKKwkJfQorCQlicmVhazsKKwlkZWZhdWx0OgorCQlicmVhazsKKwl9Cit9CisKKworRlhfQk9PTAlDRkZMX1RleHRGaWVsZDo6SXNBY3Rpb25EYXRhQ2hhbmdlZChDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIGNvbnN0IFBERlNES19GaWVsZEFjdGlvbiYgZmFPbGQsIAorCQkJCQkJCQkJY29uc3QgUERGU0RLX0ZpZWxkQWN0aW9uJiBmYU5ldykKK3sKKwlzd2l0Y2ggKHR5cGUpCisJeworCWNhc2UgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2U6CisJCXJldHVybiAoIWZhT2xkLmJGaWVsZEZ1bGwgJiYgZmFPbGQublNlbEVuZCAhPSBmYU5ldy5uU2VsRW5kKSB8fCBmYU9sZC5uU2VsU3RhcnQgIT0gZmFOZXcublNlbFN0YXJ0IHx8CisJCQlmYU9sZC5zQ2hhbmdlICE9IGZhTmV3LnNDaGFuZ2U7CisJZGVmYXVsdDoKKwkJYnJlYWs7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIENGRkxfVGV4dEZpZWxkOjpTYXZlU3RhdGUoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQoreworCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7CisKKwlpZiAoQ1BXTF9FZGl0KiBwV25kID0gKENQV0xfRWRpdCopR2V0UERGV2luZG93KHBQYWdlVmlldywgRkFMU0UpKQorCXsKKwkJcFduZC0+R2V0U2VsKG1fU3RhdGUublN0YXJ0LCBtX1N0YXRlLm5FbmQpOworCQltX1N0YXRlLnNWYWx1ZSA9IHBXbmQtPkdldFRleHQoKTsKKwl9Cit9CisKK3ZvaWQgQ0ZGTF9UZXh0RmllbGQ6OlJlc3RvcmVTdGF0ZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKworCWlmIChDUFdMX0VkaXQqIHBXbmQgPSAoQ1BXTF9FZGl0KilHZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBUUlVFKSkKKwl7CisJCXBXbmQtPlNldFRleHQobV9TdGF0ZS5zVmFsdWUpOworCQlwV25kLT5TZXRTZWwobV9TdGF0ZS5uU3RhcnQsIG1fU3RhdGUubkVuZCk7CisJfQorfQorCitDUFdMX1duZCogQ0ZGTF9UZXh0RmllbGQ6OlJlc2V0UERGV2luZG93KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfQk9PTCBiUmVzdG9yZVZhbHVlKQoreworCWlmIChiUmVzdG9yZVZhbHVlKQorCQlTYXZlU3RhdGUocFBhZ2VWaWV3KTsKKworCURlc3Ryb3lQREZXaW5kb3cocFBhZ2VWaWV3KTsKKworCUNQV0xfV25kKiBwUmV0ID0gTlVMTDsKKworCWlmIChiUmVzdG9yZVZhbHVlKQorCXsKKwkJUmVzdG9yZVN0YXRlKHBQYWdlVmlldyk7CisJCXBSZXQgPSB0aGlzLT5HZXRQREZXaW5kb3cocFBhZ2VWaWV3LCBGQUxTRSk7CisJfQorCWVsc2UKKwkJcFJldCA9IHRoaXMtPkdldFBERldpbmRvdyhwUGFnZVZpZXcsIFRSVUUpOworCisJbV9wV2lkZ2V0LT5VcGRhdGVGaWVsZCgpOworCQorCXJldHVybiBwUmV0OworfQorCit2b2lkIENGRkxfVGV4dEZpZWxkOjpPblNldEZvY3VzKENQV0xfV25kKiBwV25kKQoreworCUFTU0VSVChtX3BBcHAgIT0gTlVMTCk7CisJCisgCUFTU0VSVChwV25kICE9IE5VTEwpOworIAorIAlpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gUFdMX0NMQVNTTkFNRV9FRElUKQorIAl7CisgCQlDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopcFduZDsKKwkJcEVkaXQtPlNldENoYXJTZXQoMTM0KTsKKwkJcEVkaXQtPlNldENvZGVQYWdlKDkzNik7CisgCisJCXBFZGl0LT5TZXRSZWFkeVRvSW5wdXQoKTsKKwkJQ0ZYX1dpZGVTdHJpbmcgd3NUZXh0ID0gcEVkaXQtPkdldFRleHQoKTsKKwkJaW50IG5DaGFyYWN0ZXJzID0gd3NUZXh0LkdldExlbmd0aCgpOworCQlDRlhfQnl0ZVN0cmluZyBic1VURlRleHQgPSB3c1RleHQuVVRGMTZMRV9FbmNvZGUoKTsKKwkJdW5zaWduZWQgc2hvcnQqIHBCdWZmZXIgPSAodW5zaWduZWQgc2hvcnQqKShGWF9MUENTVFIpYnNVVEZUZXh0OworCQltX3BBcHAtPkZGSV9PblNldEZpZWxkSW5wdXRGb2N1cyhtX3BXaWRnZXQtPkdldEZvcm1GaWVsZCgpLCBwQnVmZmVyLCBuQ2hhcmFjdGVycywgVFJVRSk7CisgCisgCQlwRWRpdC0+U2V0RWRpdE5vdGlmeSh0aGlzKTsKKyAJCS8vcFVuZG8tPkJlZ2luRWRpdChwRG9jdW1lbnQpOworIAl9Cit9CisKK3ZvaWQgQ0ZGTF9UZXh0RmllbGQ6Ok9uS2lsbEZvY3VzKENQV0xfV25kKiBwV25kKQoreworCit9CisKK0ZYX0JPT0wJQ0ZGTF9UZXh0RmllbGQ6OkNhbkNvcHkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDRkZMX1RleHRGaWVsZDo6Q2FuQ3V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZGTF9UZXh0RmllbGQ6OkNhblBhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZGTF9UZXh0RmllbGQ6OkRvQ29weShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisKK30KKwordm9pZCBDRkZMX1RleHRGaWVsZDo6RG9DdXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQoreworfQorCit2b2lkIENGRkxfVGV4dEZpZWxkOjpEb1Bhc3RlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKworfQorCit2b2lkIENGRkxfVGV4dEZpZWxkOjpPbkFkZFVuZG8oQ1BXTF9FZGl0KiBwRWRpdCkKK3sKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfVXRpbHMuY3BwIGIvZnBkZnNkay9zcmMvZm9ybWZpbGxlci9GRkxfVXRpbHMuY3BwCmluZGV4IDJlOTA4MTAuLjNlYTc4OTEgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2Zvcm1maWxsZXIvRkZMX1V0aWxzLmNwcAorKysgYi9mcGRmc2RrL3NyYy9mb3JtZmlsbGVyL0ZGTF9VdGlscy5jcHAKQEAgLTEsMTMzICsxLDEzMyBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9Gb3JtRmlsbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfVXRpbHMuaCINCi0NCi1DUERGX1JlY3QgQ0ZGTF9VdGlsczo6TWF4UmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0MSxjb25zdCBDUERGX1JlY3QgJiByZWN0MikNCi17DQotCUNQREZfUmVjdCByY1JldDsNCi0NCi0JcmNSZXQubGVmdCA9IEZGTF9NSU4ocmVjdDEubGVmdCxyZWN0Mi5sZWZ0KTsNCi0JcmNSZXQuYm90dG9tID0gRkZMX01JTihyZWN0MS5ib3R0b20scmVjdDIuYm90dG9tKTsNCi0JcmNSZXQucmlnaHQgPSBGRkxfTUFYKHJlY3QxLnJpZ2h0LHJlY3QyLnJpZ2h0KTsNCi0JcmNSZXQudG9wID0gRkZMX01BWChyZWN0MS50b3AscmVjdDIudG9wKTsNCi0NCi0JcmV0dXJuIHJjUmV0Ow0KLX0NCi0NCi1DUERGX1JlY3QgQ0ZGTF9VdGlsczo6SW5mbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgY3JSZWN0LGNvbnN0IEZYX0ZMT0FUICYgZlNpemUpDQotew0KLQlDUERGX1JlY3QgY3JOZXcoY3JSZWN0LmxlZnQgLSBmU2l6ZSwNCi0JCQkJCWNyUmVjdC5ib3R0b20gLSBmU2l6ZSwNCi0JCQkJCWNyUmVjdC5yaWdodCArIGZTaXplLA0KLQkJCQkJY3JSZWN0LnRvcCArIGZTaXplKTsNCi0JY3JOZXcuTm9ybWFsaXplKCk7DQotCXJldHVybiBjck5ldzsNCi19DQotDQotQ1BERl9SZWN0IENGRkxfVXRpbHM6OkRlZmxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIGNyUmVjdCxjb25zdCBGWF9GTE9BVCAmIGZTaXplKQ0KLXsNCi0JQ1BERl9SZWN0IGNyTmV3KGNyUmVjdC5sZWZ0ICsgZlNpemUsDQotCQkJCQljclJlY3QuYm90dG9tICsgZlNpemUsDQotCQkJCQljclJlY3QucmlnaHQgLSBmU2l6ZSwNCi0JCQkJCWNyUmVjdC50b3AgLSBmU2l6ZSk7DQotCWNyTmV3Lk5vcm1hbGl6ZSgpOw0KLQlyZXR1cm4gY3JOZXc7DQotfQ0KLQ0KLS8qDQotRlhfQk9PTCBDRkZMX1V0aWxzOjpSZWN0Q29udGFpbnNSZWN0KGNvbnN0IENQREZfUmVjdCAmIGZhdGhlcixjb25zdCBDUERGX1JlY3QgJiBzb24pDQotew0KLQlyZXR1cm4gKGZhdGhlci5sZWZ0IDw9IHNvbi5sZWZ0ICYmIGZhdGhlci5yaWdodCA+PSBzb24ucmlnaHQgJiYgDQotCQkJCWZhdGhlci5ib3R0b20gPD0gc29uLmJvdHRvbSAmJiBmYXRoZXIudG9wID49IHNvbi50b3ApOw0KLQ0KLX0NCi0NCi1GWF9CT09MIENGRkxfVXRpbHM6OlJlY3RDb250YWluc1BvaW50KGNvbnN0IENQREZfUmVjdCAmIGZhdGhlcixjb25zdCBDUERGX1BvaW50ICYgc29uKQ0KLXsNCi0JcmV0dXJuIChmYXRoZXIubGVmdCA8PSBzb24ueCAmJiBmYXRoZXIucmlnaHQgPj0gc29uLnggJiYgDQotCQkJCWZhdGhlci5ib3R0b20gPD0gc29uLnkgJiYgZmF0aGVyLnRvcCA+PSBzb24ueSk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZGTF9VdGlsczo6UmVjdENvbnRhaW5zWFkoY29uc3QgQ1BERl9SZWN0ICYgZmF0aGVyLEZYX0ZMT0FUIHgsRlhfRkxPQVQgeSkNCi17DQotCXJldHVybiAoZmF0aGVyLmxlZnQgPD0geCAmJiBmYXRoZXIucmlnaHQgPj0geCAmJiANCi0JCQkJZmF0aGVyLmJvdHRvbSA8PSB5ICYmIGZhdGhlci50b3AgPj0geSk7DQotfQ0KLSovDQotDQotRlhfQk9PTCBDRkZMX1V0aWxzOjpUcmFjZU9iamVjdChDUERGX09iamVjdCogcE9iaikNCi17DQotCWlmICghcE9iaikgcmV0dXJuIEZBTFNFOw0KLQ0KLQlGWF9EV09SRAlkd09iak51bSA9IHBPYmotPkdldE9iak51bSgpOw0KLQlzd2l0Y2ggKHBPYmotPkdldFR5cGUoKSkNCi0Jew0KLQljYXNlIFBERk9CSl9BUlJBWToNCi0JCXsNCi0JCQlDUERGX0FycmF5KiBwQXJyYXkgPSAoQ1BERl9BcnJheSopcE9iajsNCi0JCQlmb3IgKEZYX0RXT1JEIGkgPSAwOyBpIDwgcEFycmF5LT5HZXRDb3VudCgpOyBpICsrKQ0KLQkJCXsNCi0JCQkJQ1BERl9PYmplY3QqIHBFbGVtZW50ID0gcEFycmF5LT5HZXRFbGVtZW50VmFsdWUoaSk7CQkJCQ0KLQkJCQlUcmFjZU9iamVjdChwRWxlbWVudCk7DQotCQkJfQ0KLQkJfQ0KLQkJYnJlYWs7DQotDQotCWNhc2UgUERGT0JKX0RJQ1RJT05BUlk6DQotCQl7DQotCQkJQ1BERl9EaWN0aW9uYXJ5KiBwRGljdCA9IChDUERGX0RpY3Rpb25hcnkqKXBPYmo7DQotDQotCQkJRlhfUE9TSVRJT04gZlBvcyA9IHBEaWN0LT5HZXRTdGFydFBvcygpOw0KLQkJCUNGWF9CeXRlU3RyaW5nIGNzS2V5Ow0KLQkJCWRvDQotCQkJew0KLQkJCQlDUERGX09iamVjdCogcEVsZW1lbnQgPSBwRGljdC0+R2V0TmV4dEVsZW1lbnQoZlBvcywgY3NLZXkpOw0KLSAJCQkJLy9UUkFDRShjc0tleSArICJcbiIpOw0KLQkJCQlpZiAoIXBFbGVtZW50KSBicmVhazsNCi0JCQkJVHJhY2VPYmplY3QocEVsZW1lbnQpOw0KLQkJCX13aGlsZSAoVFJVRSk7DQotCQl9DQotCQlicmVhazsNCi0NCi0JY2FzZSBQREZPQkpfU1RSRUFNOg0KLQkJew0KLQkJCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gKENQREZfU3RyZWFtKilwT2JqOw0KLQkJCUNQREZfRGljdGlvbmFyeSogcERpY3QgPSBwU3RyZWFtLT5HZXREaWN0KCk7DQotCQkJVHJhY2VPYmplY3QocERpY3QpOw0KLQkJfQ0KLQkJYnJlYWs7DQotDQotCWNhc2UgUERGT0JKX1JFRkVSRU5DRToNCi0JCXsNCi0JCQlDUERGX09iamVjdCogcERpcmVjdE9iaiA9IHBPYmotPkdldERpcmVjdCgpOw0KLQkJCVRyYWNlT2JqZWN0KHBEaXJlY3RPYmopOw0KLQkJfQ0KLQkJYnJlYWs7DQotDQotCWNhc2UgUERGT0JKX0JPT0xFQU46DQotCQlicmVhazsNCi0JY2FzZSBQREZPQkpfTlVNQkVSOg0KLQkJLy9UUkFDRSgiJWRcbiIsKEZYX0lOVDMyKXBPYmopOw0KLQkJYnJlYWs7DQotCWNhc2UgUERGT0JKX1NUUklORzoNCi0JCS8vVFJBQ0UoKChDUERGX1N0cmluZyopcE9iaiktPkdldFN0cmluZygpICsgIlxuIik7DQotCQlicmVhazsNCi0JY2FzZSBQREZPQkpfTkFNRToNCi0JCS8vVFJBQ0UoKChDUERGX05hbWUqKXBPYmopLT5HZXRTdHJpbmcoKSArICJcbiIpOw0KLQkJYnJlYWs7DQotCWNhc2UgUERGT0JKX05VTEw6DQotLy8JY2FzZSBQREZPQkpfS0VZV09SRDoNCi0vLwljYXNlIFBERk9CSl9FT0Y6DQotCWRlZmF1bHQ6DQotCQlicmVhazsNCi0JfQ0KLQlpZiAoZHdPYmpOdW0gPT0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZm9ybWZpbGxlci9Gb3JtRmlsbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9mb3JtZmlsbGVyL0ZGTF9VdGlscy5oIgorCitDUERGX1JlY3QgQ0ZGTF9VdGlsczo6TWF4UmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0MSxjb25zdCBDUERGX1JlY3QgJiByZWN0MikKK3sKKwlDUERGX1JlY3QgcmNSZXQ7CisKKwlyY1JldC5sZWZ0ID0gRkZMX01JTihyZWN0MS5sZWZ0LHJlY3QyLmxlZnQpOworCXJjUmV0LmJvdHRvbSA9IEZGTF9NSU4ocmVjdDEuYm90dG9tLHJlY3QyLmJvdHRvbSk7CisJcmNSZXQucmlnaHQgPSBGRkxfTUFYKHJlY3QxLnJpZ2h0LHJlY3QyLnJpZ2h0KTsKKwlyY1JldC50b3AgPSBGRkxfTUFYKHJlY3QxLnRvcCxyZWN0Mi50b3ApOworCisJcmV0dXJuIHJjUmV0OworfQorCitDUERGX1JlY3QgQ0ZGTF9VdGlsczo6SW5mbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgY3JSZWN0LGNvbnN0IEZYX0ZMT0FUICYgZlNpemUpCit7CisJQ1BERl9SZWN0IGNyTmV3KGNyUmVjdC5sZWZ0IC0gZlNpemUsCisJCQkJCWNyUmVjdC5ib3R0b20gLSBmU2l6ZSwKKwkJCQkJY3JSZWN0LnJpZ2h0ICsgZlNpemUsCisJCQkJCWNyUmVjdC50b3AgKyBmU2l6ZSk7CisJY3JOZXcuTm9ybWFsaXplKCk7CisJcmV0dXJuIGNyTmV3OworfQorCitDUERGX1JlY3QgQ0ZGTF9VdGlsczo6RGVmbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgY3JSZWN0LGNvbnN0IEZYX0ZMT0FUICYgZlNpemUpCit7CisJQ1BERl9SZWN0IGNyTmV3KGNyUmVjdC5sZWZ0ICsgZlNpemUsCisJCQkJCWNyUmVjdC5ib3R0b20gKyBmU2l6ZSwKKwkJCQkJY3JSZWN0LnJpZ2h0IC0gZlNpemUsCisJCQkJCWNyUmVjdC50b3AgLSBmU2l6ZSk7CisJY3JOZXcuTm9ybWFsaXplKCk7CisJcmV0dXJuIGNyTmV3OworfQorCisvKgorRlhfQk9PTCBDRkZMX1V0aWxzOjpSZWN0Q29udGFpbnNSZWN0KGNvbnN0IENQREZfUmVjdCAmIGZhdGhlcixjb25zdCBDUERGX1JlY3QgJiBzb24pCit7CisJcmV0dXJuIChmYXRoZXIubGVmdCA8PSBzb24ubGVmdCAmJiBmYXRoZXIucmlnaHQgPj0gc29uLnJpZ2h0ICYmIAorCQkJCWZhdGhlci5ib3R0b20gPD0gc29uLmJvdHRvbSAmJiBmYXRoZXIudG9wID49IHNvbi50b3ApOworCit9CisKK0ZYX0JPT0wgQ0ZGTF9VdGlsczo6UmVjdENvbnRhaW5zUG9pbnQoY29uc3QgQ1BERl9SZWN0ICYgZmF0aGVyLGNvbnN0IENQREZfUG9pbnQgJiBzb24pCit7CisJcmV0dXJuIChmYXRoZXIubGVmdCA8PSBzb24ueCAmJiBmYXRoZXIucmlnaHQgPj0gc29uLnggJiYgCisJCQkJZmF0aGVyLmJvdHRvbSA8PSBzb24ueSAmJiBmYXRoZXIudG9wID49IHNvbi55KTsKK30KKworRlhfQk9PTCBDRkZMX1V0aWxzOjpSZWN0Q29udGFpbnNYWShjb25zdCBDUERGX1JlY3QgJiBmYXRoZXIsRlhfRkxPQVQgeCxGWF9GTE9BVCB5KQoreworCXJldHVybiAoZmF0aGVyLmxlZnQgPD0geCAmJiBmYXRoZXIucmlnaHQgPj0geCAmJiAKKwkJCQlmYXRoZXIuYm90dG9tIDw9IHkgJiYgZmF0aGVyLnRvcCA+PSB5KTsKK30KKyovCisKK0ZYX0JPT0wgQ0ZGTF9VdGlsczo6VHJhY2VPYmplY3QoQ1BERl9PYmplY3QqIHBPYmopCit7CisJaWYgKCFwT2JqKSByZXR1cm4gRkFMU0U7CisKKwlGWF9EV09SRAlkd09iak51bSA9IHBPYmotPkdldE9iak51bSgpOworCXN3aXRjaCAocE9iai0+R2V0VHlwZSgpKQorCXsKKwljYXNlIFBERk9CSl9BUlJBWToKKwkJeworCQkJQ1BERl9BcnJheSogcEFycmF5ID0gKENQREZfQXJyYXkqKXBPYmo7CisJCQlmb3IgKEZYX0RXT1JEIGkgPSAwOyBpIDwgcEFycmF5LT5HZXRDb3VudCgpOyBpICsrKQorCQkJeworCQkJCUNQREZfT2JqZWN0KiBwRWxlbWVudCA9IHBBcnJheS0+R2V0RWxlbWVudFZhbHVlKGkpOwkJCQkKKwkJCQlUcmFjZU9iamVjdChwRWxlbWVudCk7CisJCQl9CisJCX0KKwkJYnJlYWs7CisKKwljYXNlIFBERk9CSl9ESUNUSU9OQVJZOgorCQl7CisJCQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gKENQREZfRGljdGlvbmFyeSopcE9iajsKKworCQkJRlhfUE9TSVRJT04gZlBvcyA9IHBEaWN0LT5HZXRTdGFydFBvcygpOworCQkJQ0ZYX0J5dGVTdHJpbmcgY3NLZXk7CisJCQlkbworCQkJeworCQkJCUNQREZfT2JqZWN0KiBwRWxlbWVudCA9IHBEaWN0LT5HZXROZXh0RWxlbWVudChmUG9zLCBjc0tleSk7CisgCQkJCS8vVFJBQ0UoY3NLZXkgKyAiXG4iKTsKKwkJCQlpZiAoIXBFbGVtZW50KSBicmVhazsKKwkJCQlUcmFjZU9iamVjdChwRWxlbWVudCk7CisJCQl9d2hpbGUgKFRSVUUpOworCQl9CisJCWJyZWFrOworCisJY2FzZSBQREZPQkpfU1RSRUFNOgorCQl7CisJCQlDUERGX1N0cmVhbSogcFN0cmVhbSA9IChDUERGX1N0cmVhbSopcE9iajsKKwkJCUNQREZfRGljdGlvbmFyeSogcERpY3QgPSBwU3RyZWFtLT5HZXREaWN0KCk7CisJCQlUcmFjZU9iamVjdChwRGljdCk7CisJCX0KKwkJYnJlYWs7CisKKwljYXNlIFBERk9CSl9SRUZFUkVOQ0U6CisJCXsKKwkJCUNQREZfT2JqZWN0KiBwRGlyZWN0T2JqID0gcE9iai0+R2V0RGlyZWN0KCk7CisJCQlUcmFjZU9iamVjdChwRGlyZWN0T2JqKTsKKwkJfQorCQlicmVhazsKKworCWNhc2UgUERGT0JKX0JPT0xFQU46CisJCWJyZWFrOworCWNhc2UgUERGT0JKX05VTUJFUjoKKwkJLy9UUkFDRSgiJWRcbiIsKEZYX0lOVDMyKXBPYmopOworCQlicmVhazsKKwljYXNlIFBERk9CSl9TVFJJTkc6CisJCS8vVFJBQ0UoKChDUERGX1N0cmluZyopcE9iaiktPkdldFN0cmluZygpICsgIlxuIik7CisJCWJyZWFrOworCWNhc2UgUERGT0JKX05BTUU6CisJCS8vVFJBQ0UoKChDUERGX05hbWUqKXBPYmopLT5HZXRTdHJpbmcoKSArICJcbiIpOworCQlicmVhazsKKwljYXNlIFBERk9CSl9OVUxMOgorLy8JY2FzZSBQREZPQkpfS0VZV09SRDoKKy8vCWNhc2UgUERGT0JKX0VPRjoKKwlkZWZhdWx0OgorCQlicmVhazsKKwl9CisJaWYgKGR3T2JqTnVtID09IDApIHJldHVybiBGQUxTRTsKKworCXJldHVybiBUUlVFOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mcGRmX2RhdGFhdmFpbC5jcHAgYi9mcGRmc2RrL3NyYy9mcGRmX2RhdGFhdmFpbC5jcHAKaW5kZXggOWU1NmMyZS4uYjU0ODNmOSAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnBkZl9kYXRhYXZhaWwuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2ZwZGZfZGF0YWF2YWlsLmNwcApAQCAtMSwxNjUgKzEsMTY1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZfZGF0YWF2YWlsLmgiDQotDQotZXh0ZXJuIHZvaWQgUHJvY2Vzc1BhcnNlRXJyb3IoRlhfRFdPUkQgZXJyX2NvZGUpOw0KLWNsYXNzIENGUERGX0ZpbGVBdmFpbFdyYXAgOiBwdWJsaWMgSUZYX0ZpbGVBdmFpbA0KLXsNCi1wdWJsaWM6DQotCUNGUERGX0ZpbGVBdmFpbFdyYXAoKQ0KLQl7DQotCQltX3BmaWxlQXZhaWwgPSBOVUxMOw0KLQl9DQotDQotCXZvaWQgU2V0KEZYX0ZJTEVBVkFJTCogcGZpbGVBdmFpbCkNCi0Jew0KLQkJbV9wZmlsZUF2YWlsID0gcGZpbGVBdmFpbDsNCi0JfQ0KLQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQlJc0RhdGFBdmFpbCggRlhfRklMRVNJWkUgb2Zmc2V0LCBGWF9EV09SRCBzaXplKQ0KLQl7DQotCQlyZXR1cm4gbV9wZmlsZUF2YWlsLT5Jc0RhdGFBdmFpbChtX3BmaWxlQXZhaWwsIG9mZnNldCwgc2l6ZSk7DQotCX0NCi0NCi1wcml2YXRlOg0KLQlGWF9GSUxFQVZBSUwqIG1fcGZpbGVBdmFpbDsNCi19OyAgDQotDQotY2xhc3MgQ0ZQREZfRmlsZUFjY2Vzc1dyYXAgOiBwdWJsaWMgSUZYX0ZpbGVSZWFkDQotew0KLXB1YmxpYzoNCi0JQ0ZQREZfRmlsZUFjY2Vzc1dyYXAoKQ0KLQl7DQotCQltX3BGaWxlQWNjZXNzID0gTlVMTDsNCi0JfQ0KLQ0KLQl2b2lkIFNldChGUERGX0ZJTEVBQ0NFU1MqIHBGaWxlKQ0KLQl7DQotCQltX3BGaWxlQWNjZXNzID0gcEZpbGU7DQotCX0NCi0NCi0JdmlydHVhbCBGWF9GSUxFU0laRQkJR2V0U2l6ZSgpDQotCXsNCi0JCXJldHVybiBtX3BGaWxlQWNjZXNzLT5tX0ZpbGVMZW47IA0KLQl9DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCVJlYWRCbG9jayh2b2lkKiBidWZmZXIsIEZYX0ZJTEVTSVpFIG9mZnNldCwgc2l6ZV90IHNpemUpDQotCXsNCi0JCXJldHVybiBtX3BGaWxlQWNjZXNzLT5tX0dldEJsb2NrKG1fcEZpbGVBY2Nlc3MtPm1fUGFyYW0sIG9mZnNldCwgKEZYX0xQQllURSlidWZmZXIsIHNpemUpOw0KLQl9DQotDQotCXZpcnR1YWwgdm9pZAkJCVJlbGVhc2UoKQ0KLQl7DQotCX0NCi0NCi1wcml2YXRlOg0KLQlGUERGX0ZJTEVBQ0NFU1MqCQltX3BGaWxlQWNjZXNzOw0KLX07DQotDQotY2xhc3MgQ0ZQREZfRG93bmxvYWRIaW50c1dyYXAgOiBwdWJsaWMgSUZYX0Rvd25sb2FkSGludHMNCi17DQotcHVibGljOg0KLQlDRlBERl9Eb3dubG9hZEhpbnRzV3JhcChGWF9ET1dOTE9BREhJTlRTKiBwRG93bmxvYWRIaW50cykNCi0Jew0KLQkJbV9wRG93bmxvYWRIaW50cyA9IHBEb3dubG9hZEhpbnRzOw0KLQl9DQotcHVibGljOg0KLQl2aXJ0dWFsIHZvaWQJCQlBZGRTZWdtZW50KEZYX0ZJTEVTSVpFIG9mZnNldCwgRlhfRFdPUkQgc2l6ZSkgDQotCXsNCi0JCW1fcERvd25sb2FkSGludHMtPkFkZFNlZ21lbnQobV9wRG93bmxvYWRIaW50cywgb2Zmc2V0LCBzaXplKTsNCi0JfQkNCi1wcml2YXRlOg0KLQlGWF9ET1dOTE9BREhJTlRTKiBtX3BEb3dubG9hZEhpbnRzOw0KLX07DQotDQotY2xhc3MgQ0ZQREZfRGF0YUF2YWlsIDogcHVibGljIENGWF9PYmplY3QNCi17DQotcHVibGljOg0KLQlDRlBERl9EYXRhQXZhaWwoKQ0KLQl7DQotCQltX3BEYXRhQXZhaWwgPSBOVUxMOw0KLQl9DQotDQotCX5DRlBERl9EYXRhQXZhaWwoKQ0KLQl7DQotCQlpZiAobV9wRGF0YUF2YWlsKSBkZWxldGUgbV9wRGF0YUF2YWlsOw0KLQl9DQotDQotCUNQREZfRGF0YUF2YWlsKgkJCW1fcERhdGFBdmFpbDsNCi0JQ0ZQREZfRmlsZUF2YWlsV3JhcAkJbV9GaWxlQXZhaWw7DQotCUNGUERGX0ZpbGVBY2Nlc3NXcmFwCW1fRmlsZVJlYWQ7DQotfTsNCi0NCi1ETExFWFBPUlQgRlBERl9BVkFJTCBTVERDQUxMIEZQREZBdmFpbF9DcmVhdGUoRlhfRklMRUFWQUlMKiBmaWxlX2F2YWlsLCBGUERGX0ZJTEVBQ0NFU1MqIGZpbGUpDQotew0KLQlDRlBERl9EYXRhQXZhaWwqIHBBdmFpbCA9IEZYX05FVyBDRlBERl9EYXRhQXZhaWw7DQotCXBBdmFpbC0+bV9GaWxlQXZhaWwuU2V0KGZpbGVfYXZhaWwpOw0KLQlwQXZhaWwtPm1fRmlsZVJlYWQuU2V0KGZpbGUpOw0KLQlwQXZhaWwtPm1fcERhdGFBdmFpbCA9IEZYX05FVyBDUERGX0RhdGFBdmFpbCgmcEF2YWlsLT5tX0ZpbGVBdmFpbCwgJnBBdmFpbC0+bV9GaWxlUmVhZCk7DQotCXJldHVybiBwQXZhaWw7DQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkF2YWlsX0Rlc3Ryb3koRlBERl9BVkFJTCBhdmFpbCkNCi17DQotCWlmIChhdmFpbCA9PSBOVUxMKSByZXR1cm47DQotCWRlbGV0ZSAoQ0ZQREZfRGF0YUF2YWlsKilhdmFpbDsNCi19DQotDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZBdmFpbF9Jc0RvY0F2YWlsKEZQREZfQVZBSUwgYXZhaWwsIEZYX0RPV05MT0FESElOVFMqIGhpbnRzKQ0KLXsNCi0JaWYgKGF2YWlsID09IE5VTEwgfHwgaGludHMgPT0gTlVMTCkgcmV0dXJuIDA7DQotCUNGUERGX0Rvd25sb2FkSGludHNXcmFwIGhpbnRzX3dyYXAoaGludHMpOw0KLQlyZXR1cm4gKChDRlBERl9EYXRhQXZhaWwqKWF2YWlsKS0+bV9wRGF0YUF2YWlsLT5Jc0RvY0F2YWlsKCZoaW50c193cmFwKTsNCi19DQotDQotZXh0ZXJuIHZvaWQgQ2hlY2tVblN1cHBvcnRFcnJvcihDUERGX0RvY3VtZW50ICogcERvYywgRlhfRFdPUkQgZXJyX2NvZGUpOw0KLQ0KLURMTEVYUE9SVCBGUERGX0RPQ1VNRU5UIFNURENBTEwgRlBERkF2YWlsX0dldERvY3VtZW50KEZQREZfQVZBSUwgYXZhaWwsCUZQREZfQllURVNUUklORyBwYXNzd29yZCkNCi17DQotCWlmIChhdmFpbCA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0JQ1BERl9QYXJzZXIqIHBQYXJzZXIgPSBGWF9ORVcgQ1BERl9QYXJzZXI7DQotCXBQYXJzZXItPlNldFBhc3N3b3JkKHBhc3N3b3JkKTsNCi0NCi0JRlhfRFdPUkQgZXJyX2NvZGUgPSBwUGFyc2VyLT5TdGFydEFzeW5QYXJzZSgoKENGUERGX0RhdGFBdmFpbCopYXZhaWwpLT5tX3BEYXRhQXZhaWwtPkdldEZpbGVSZWFkKCkpOw0KLQlpZiAoZXJyX2NvZGUpIHsNCi0JCWRlbGV0ZSBwUGFyc2VyOw0KLQkJUHJvY2Vzc1BhcnNlRXJyb3IoZXJyX2NvZGUpOw0KLQkJcmV0dXJuIE5VTEw7DQotCX0NCi0JKChDRlBERl9EYXRhQXZhaWwqKWF2YWlsKS0+bV9wRGF0YUF2YWlsLT5TZXREb2N1bWVudChwUGFyc2VyLT5HZXREb2N1bWVudCgpKTsNCi0JQ2hlY2tVblN1cHBvcnRFcnJvcihwUGFyc2VyLT5HZXREb2N1bWVudCgpLCBGUERGX0VSUl9TVUNDRVNTKTsNCi0JcmV0dXJuIHBQYXJzZXItPkdldERvY3VtZW50KCk7DQotfQ0KLQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQXZhaWxfR2V0Rmlyc3RQYWdlTnVtKEZQREZfRE9DVU1FTlQgZG9jKQ0KLXsNCi0JaWYgKGRvYyA9PSBOVUxMKSByZXR1cm4gMDsNCi0JQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2M7DQotCXJldHVybiAoKENQREZfUGFyc2VyKilwRG9jLT5HZXRQYXJzZXIoKSktPkdldEZpcnN0UGFnZU5vKCk7DQotfQ0KLQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQXZhaWxfSXNQYWdlQXZhaWwoRlBERl9BVkFJTCBhdmFpbCwgaW50IHBhZ2VfaW5kZXgsIEZYX0RPV05MT0FESElOVFMqIGhpbnRzKQ0KLXsNCi0JaWYgKGF2YWlsID09IE5VTEwgfHwgaGludHMgPT0gTlVMTCkgcmV0dXJuIDA7DQotCUNGUERGX0Rvd25sb2FkSGludHNXcmFwIGhpbnRzX3dyYXAoaGludHMpOw0KLQlyZXR1cm4gKChDRlBERl9EYXRhQXZhaWwqKWF2YWlsKS0+bV9wRGF0YUF2YWlsLT5Jc1BhZ2VBdmFpbChwYWdlX2luZGV4LCAmaGludHNfd3JhcCk7DQotfQ0KLQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQXZhaWxfSXNGb3JtQXZhaWwoRlBERl9BVkFJTCBhdmFpbCwgRlhfRE9XTkxPQURISU5UUyogaGludHMpDQotew0KLQlpZiAoYXZhaWwgPT0gTlVMTCB8fCBoaW50cyA9PSBOVUxMKSByZXR1cm4gLTE7DQotCUNGUERGX0Rvd25sb2FkSGludHNXcmFwIGhpbnRzX3dyYXAoaGludHMpOw0KLQlyZXR1cm4gKChDRlBERl9EYXRhQXZhaWwqKWF2YWlsKS0+bV9wRGF0YUF2YWlsLT5Jc0Zvcm1BdmFpbCgmaGludHNfd3JhcCk7DQotfQ0KLQ0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGQXZhaWxfSXNMaW5lYXJpemVkKEZQREZfQVZBSUwgYXZhaWwpDQotew0KLQkJaWYgKGF2YWlsID09IE5VTEwpIHJldHVybiAtMTsNCi0JcmV0dXJuICgoQ0ZQREZfRGF0YUF2YWlsKilhdmFpbCktPm1fcERhdGFBdmFpbC0+SXNMaW5lYXJpemVkUERGKCk7DQotDQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmX2RhdGFhdmFpbC5oIgorCitleHRlcm4gdm9pZCBQcm9jZXNzUGFyc2VFcnJvcihGWF9EV09SRCBlcnJfY29kZSk7CitjbGFzcyBDRlBERl9GaWxlQXZhaWxXcmFwIDogcHVibGljIElGWF9GaWxlQXZhaWwKK3sKK3B1YmxpYzoKKwlDRlBERl9GaWxlQXZhaWxXcmFwKCkKKwl7CisJCW1fcGZpbGVBdmFpbCA9IE5VTEw7CisJfQorCisJdm9pZCBTZXQoRlhfRklMRUFWQUlMKiBwZmlsZUF2YWlsKQorCXsKKwkJbV9wZmlsZUF2YWlsID0gcGZpbGVBdmFpbDsKKwl9CisKKwl2aXJ0dWFsIEZYX0JPT0wJCQlJc0RhdGFBdmFpbCggRlhfRklMRVNJWkUgb2Zmc2V0LCBGWF9EV09SRCBzaXplKQorCXsKKwkJcmV0dXJuIG1fcGZpbGVBdmFpbC0+SXNEYXRhQXZhaWwobV9wZmlsZUF2YWlsLCBvZmZzZXQsIHNpemUpOworCX0KKworcHJpdmF0ZToKKwlGWF9GSUxFQVZBSUwqIG1fcGZpbGVBdmFpbDsKK307ICAKKworY2xhc3MgQ0ZQREZfRmlsZUFjY2Vzc1dyYXAgOiBwdWJsaWMgSUZYX0ZpbGVSZWFkCit7CitwdWJsaWM6CisJQ0ZQREZfRmlsZUFjY2Vzc1dyYXAoKQorCXsKKwkJbV9wRmlsZUFjY2VzcyA9IE5VTEw7CisJfQorCisJdm9pZCBTZXQoRlBERl9GSUxFQUNDRVNTKiBwRmlsZSkKKwl7CisJCW1fcEZpbGVBY2Nlc3MgPSBwRmlsZTsKKwl9CisKKwl2aXJ0dWFsIEZYX0ZJTEVTSVpFCQlHZXRTaXplKCkKKwl7CisJCXJldHVybiBtX3BGaWxlQWNjZXNzLT5tX0ZpbGVMZW47IAorCX0KKworCXZpcnR1YWwgRlhfQk9PTAkJCVJlYWRCbG9jayh2b2lkKiBidWZmZXIsIEZYX0ZJTEVTSVpFIG9mZnNldCwgc2l6ZV90IHNpemUpCisJeworCQlyZXR1cm4gbV9wRmlsZUFjY2Vzcy0+bV9HZXRCbG9jayhtX3BGaWxlQWNjZXNzLT5tX1BhcmFtLCBvZmZzZXQsIChGWF9MUEJZVEUpYnVmZmVyLCBzaXplKTsKKwl9CisKKwl2aXJ0dWFsIHZvaWQJCQlSZWxlYXNlKCkKKwl7CisJfQorCitwcml2YXRlOgorCUZQREZfRklMRUFDQ0VTUyoJCW1fcEZpbGVBY2Nlc3M7Cit9OworCitjbGFzcyBDRlBERl9Eb3dubG9hZEhpbnRzV3JhcCA6IHB1YmxpYyBJRlhfRG93bmxvYWRIaW50cworeworcHVibGljOgorCUNGUERGX0Rvd25sb2FkSGludHNXcmFwKEZYX0RPV05MT0FESElOVFMqIHBEb3dubG9hZEhpbnRzKQorCXsKKwkJbV9wRG93bmxvYWRIaW50cyA9IHBEb3dubG9hZEhpbnRzOworCX0KK3B1YmxpYzoKKwl2aXJ0dWFsIHZvaWQJCQlBZGRTZWdtZW50KEZYX0ZJTEVTSVpFIG9mZnNldCwgRlhfRFdPUkQgc2l6ZSkgCisJeworCQltX3BEb3dubG9hZEhpbnRzLT5BZGRTZWdtZW50KG1fcERvd25sb2FkSGludHMsIG9mZnNldCwgc2l6ZSk7CisJfQkKK3ByaXZhdGU6CisJRlhfRE9XTkxPQURISU5UUyogbV9wRG93bmxvYWRIaW50czsKK307CisKK2NsYXNzIENGUERGX0RhdGFBdmFpbCA6IHB1YmxpYyBDRlhfT2JqZWN0Cit7CitwdWJsaWM6CisJQ0ZQREZfRGF0YUF2YWlsKCkKKwl7CisJCW1fcERhdGFBdmFpbCA9IE5VTEw7CisJfQorCisJfkNGUERGX0RhdGFBdmFpbCgpCisJeworCQlpZiAobV9wRGF0YUF2YWlsKSBkZWxldGUgbV9wRGF0YUF2YWlsOworCX0KKworCUNQREZfRGF0YUF2YWlsKgkJCW1fcERhdGFBdmFpbDsKKwlDRlBERl9GaWxlQXZhaWxXcmFwCQltX0ZpbGVBdmFpbDsKKwlDRlBERl9GaWxlQWNjZXNzV3JhcAltX0ZpbGVSZWFkOworfTsKKworRExMRVhQT1JUIEZQREZfQVZBSUwgU1REQ0FMTCBGUERGQXZhaWxfQ3JlYXRlKEZYX0ZJTEVBVkFJTCogZmlsZV9hdmFpbCwgRlBERl9GSUxFQUNDRVNTKiBmaWxlKQoreworCUNGUERGX0RhdGFBdmFpbCogcEF2YWlsID0gRlhfTkVXIENGUERGX0RhdGFBdmFpbDsKKwlwQXZhaWwtPm1fRmlsZUF2YWlsLlNldChmaWxlX2F2YWlsKTsKKwlwQXZhaWwtPm1fRmlsZVJlYWQuU2V0KGZpbGUpOworCXBBdmFpbC0+bV9wRGF0YUF2YWlsID0gRlhfTkVXIENQREZfRGF0YUF2YWlsKCZwQXZhaWwtPm1fRmlsZUF2YWlsLCAmcEF2YWlsLT5tX0ZpbGVSZWFkKTsKKwlyZXR1cm4gcEF2YWlsOworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZBdmFpbF9EZXN0cm95KEZQREZfQVZBSUwgYXZhaWwpCit7CisJaWYgKGF2YWlsID09IE5VTEwpIHJldHVybjsKKwlkZWxldGUgKENGUERGX0RhdGFBdmFpbCopYXZhaWw7Cit9CisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQXZhaWxfSXNEb2NBdmFpbChGUERGX0FWQUlMIGF2YWlsLCBGWF9ET1dOTE9BREhJTlRTKiBoaW50cykKK3sKKwlpZiAoYXZhaWwgPT0gTlVMTCB8fCBoaW50cyA9PSBOVUxMKSByZXR1cm4gMDsKKwlDRlBERl9Eb3dubG9hZEhpbnRzV3JhcCBoaW50c193cmFwKGhpbnRzKTsKKwlyZXR1cm4gKChDRlBERl9EYXRhQXZhaWwqKWF2YWlsKS0+bV9wRGF0YUF2YWlsLT5Jc0RvY0F2YWlsKCZoaW50c193cmFwKTsKK30KKworZXh0ZXJuIHZvaWQgQ2hlY2tVblN1cHBvcnRFcnJvcihDUERGX0RvY3VtZW50ICogcERvYywgRlhfRFdPUkQgZXJyX2NvZGUpOworCitETExFWFBPUlQgRlBERl9ET0NVTUVOVCBTVERDQUxMIEZQREZBdmFpbF9HZXREb2N1bWVudChGUERGX0FWQUlMIGF2YWlsLAlGUERGX0JZVEVTVFJJTkcgcGFzc3dvcmQpCit7CisJaWYgKGF2YWlsID09IE5VTEwpIHJldHVybiBOVUxMOworCUNQREZfUGFyc2VyKiBwUGFyc2VyID0gRlhfTkVXIENQREZfUGFyc2VyOworCXBQYXJzZXItPlNldFBhc3N3b3JkKHBhc3N3b3JkKTsKKworCUZYX0RXT1JEIGVycl9jb2RlID0gcFBhcnNlci0+U3RhcnRBc3luUGFyc2UoKChDRlBERl9EYXRhQXZhaWwqKWF2YWlsKS0+bV9wRGF0YUF2YWlsLT5HZXRGaWxlUmVhZCgpKTsKKwlpZiAoZXJyX2NvZGUpIHsKKwkJZGVsZXRlIHBQYXJzZXI7CisJCVByb2Nlc3NQYXJzZUVycm9yKGVycl9jb2RlKTsKKwkJcmV0dXJuIE5VTEw7CisJfQorCSgoQ0ZQREZfRGF0YUF2YWlsKilhdmFpbCktPm1fcERhdGFBdmFpbC0+U2V0RG9jdW1lbnQocFBhcnNlci0+R2V0RG9jdW1lbnQoKSk7CisJQ2hlY2tVblN1cHBvcnRFcnJvcihwUGFyc2VyLT5HZXREb2N1bWVudCgpLCBGUERGX0VSUl9TVUNDRVNTKTsKKwlyZXR1cm4gcFBhcnNlci0+R2V0RG9jdW1lbnQoKTsKK30KKworRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZBdmFpbF9HZXRGaXJzdFBhZ2VOdW0oRlBERl9ET0NVTUVOVCBkb2MpCit7CisJaWYgKGRvYyA9PSBOVUxMKSByZXR1cm4gMDsKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvYzsKKwlyZXR1cm4gKChDUERGX1BhcnNlciopcERvYy0+R2V0UGFyc2VyKCkpLT5HZXRGaXJzdFBhZ2VObygpOworfQorCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkF2YWlsX0lzUGFnZUF2YWlsKEZQREZfQVZBSUwgYXZhaWwsIGludCBwYWdlX2luZGV4LCBGWF9ET1dOTE9BREhJTlRTKiBoaW50cykKK3sKKwlpZiAoYXZhaWwgPT0gTlVMTCB8fCBoaW50cyA9PSBOVUxMKSByZXR1cm4gMDsKKwlDRlBERl9Eb3dubG9hZEhpbnRzV3JhcCBoaW50c193cmFwKGhpbnRzKTsKKwlyZXR1cm4gKChDRlBERl9EYXRhQXZhaWwqKWF2YWlsKS0+bV9wRGF0YUF2YWlsLT5Jc1BhZ2VBdmFpbChwYWdlX2luZGV4LCAmaGludHNfd3JhcCk7Cit9CisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQXZhaWxfSXNGb3JtQXZhaWwoRlBERl9BVkFJTCBhdmFpbCwgRlhfRE9XTkxPQURISU5UUyogaGludHMpCit7CisJaWYgKGF2YWlsID09IE5VTEwgfHwgaGludHMgPT0gTlVMTCkgcmV0dXJuIC0xOworCUNGUERGX0Rvd25sb2FkSGludHNXcmFwIGhpbnRzX3dyYXAoaGludHMpOworCXJldHVybiAoKENGUERGX0RhdGFBdmFpbCopYXZhaWwpLT5tX3BEYXRhQXZhaWwtPklzRm9ybUF2YWlsKCZoaW50c193cmFwKTsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZBdmFpbF9Jc0xpbmVhcml6ZWQoRlBERl9BVkFJTCBhdmFpbCkKK3sKKwkJaWYgKGF2YWlsID09IE5VTEwpIHJldHVybiAtMTsKKwlyZXR1cm4gKChDRlBERl9EYXRhQXZhaWwqKWF2YWlsKS0+bV9wRGF0YUF2YWlsLT5Jc0xpbmVhcml6ZWRQREYoKTsKKworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnBkZl9leHQuY3BwIGIvZnBkZnNkay9zcmMvZnBkZl9leHQuY3BwCmluZGV4IGUyZTJkODQuLjJkOWU1YWUgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZwZGZfZXh0LmNwcAorKysgYi9mcGRmc2RrL3NyYy9mcGRmX2V4dC5jcHAKQEAgLTEsMjQ1ICsxLDI0NSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmX2V4dC5oIg0KLQ0KLSNkZWZpbmUgIEZQREZTREtfVU5TVVBQT1JUX0NBTEwgMTAwDQotDQotY2xhc3MgQ0ZTREtfVW5zdXBwb3J0SW5mb19BZGFwdGVyDQotew0KLXB1YmxpYzoNCi0JQ0ZTREtfVW5zdXBwb3J0SW5mb19BZGFwdGVyKFVOU1VQUE9SVF9JTkZPKiB1bnNwX2luZm8peyBtX3Vuc3BfaW5mbyA9IHVuc3BfaW5mbzt9DQotLy8JRlhfQk9PTCBOZWVkVG9QYXVzZU5vdygpOw0KLQl2b2lkIFJlcG9ydEVycm9yKGludCBuRXJyb3JUeXBlKTsNCi0NCi1wcml2YXRlOg0KLQlVTlNVUFBPUlRfSU5GTyogbV91bnNwX2luZm87DQotfTsNCi0NCi12b2lkIENGU0RLX1Vuc3VwcG9ydEluZm9fQWRhcHRlcjo6UmVwb3J0RXJyb3IoaW50IG5FcnJvclR5cGUpDQotew0KLQlpZihtX3Vuc3BfaW5mbyAmJiBtX3Vuc3BfaW5mby0+RlNES19VblN1cHBvcnRfSGFuZGxlcikNCi0Jew0KLQkJbV91bnNwX2luZm8tPkZTREtfVW5TdXBwb3J0X0hhbmRsZXIobV91bnNwX2luZm8sbkVycm9yVHlwZSk7DQotCX0NCi19DQotDQotdm9pZCBGcmVlVW5zdXBwb3J0SW5mbyhGWF9MUFZPSUQgcERhdGEpDQotew0KLQlDRlNES19VbnN1cHBvcnRJbmZvX0FkYXB0ZXIgKiBwQWRhcHRlciA9IChDRlNES19VbnN1cHBvcnRJbmZvX0FkYXB0ZXIgKilwRGF0YTsNCi0JZGVsZXRlIHBBZGFwdGVyOw0KLX0NCi0NCi1GWF9CT09MIEZQREZfVW5TdXBwb3J0RXJyb3IoaW50IG5FcnJvcikNCi17DQotCUNGU0RLX1Vuc3VwcG9ydEluZm9fQWRhcHRlciAqIHBBZGFwdGVyID0gKENGU0RLX1Vuc3VwcG9ydEluZm9fQWRhcHRlciAqKUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+R2V0UHJpdmF0ZURhdGEoKHZvaWQgKilGUERGU0RLX1VOU1VQUE9SVF9DQUxMKTsNCi0NCi0JaWYoIXBBZGFwdGVyKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlwQWRhcHRlci0+UmVwb3J0RXJyb3IobkVycm9yKTsNCi0JcmV0dXJuIFRSVUU7DQotfQkNCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlNES19TZXRVblNwT2JqUHJvY2Vzc0hhbmRsZXIoVU5TVVBQT1JUX0lORk8qIHVuc3BfaW5mbykNCi17DQotCWlmICghdW5zcF9pbmZvIHx8IHVuc3BfaW5mby0+dmVyc2lvbiE9MSkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ0ZTREtfVW5zdXBwb3J0SW5mb19BZGFwdGVyICogcEFkYXB0ZXIgPSBuZXcgQ0ZTREtfVW5zdXBwb3J0SW5mb19BZGFwdGVyKHVuc3BfaW5mbyk7DQotDQotCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+U2V0UHJpdmF0ZURhdGEoKHZvaWQgKilGUERGU0RLX1VOU1VQUE9SVF9DQUxMLHBBZGFwdGVyLCAmRnJlZVVuc3VwcG9ydEluZm8pOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBDaGVja1VuU3VwcG9ydEFubm90KENQREZfRG9jdW1lbnQgKiBwRG9jLCBDUERGX0Fubm90KiBwUERGQW5ub3QpDQotew0KLQlDRlhfQnl0ZVN0cmluZyBjYlN1YlR5cGUgPSBwUERGQW5ub3QtPkdldFN1YlR5cGUoKTsNCi0JaWYoY2JTdWJUeXBlLkNvbXBhcmUoIjNEIikgPT0gMCkNCi0Jew0KLQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfQU5OT1RfM0RBTk5PVCk7DQotCX0NCi0JZWxzZSBpZihjYlN1YlR5cGUuQ29tcGFyZSgiU2NyZWVuIikgPT0wKQ0KLQl7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBBbm5vdERpY3QgPSBwUERGQW5ub3QtPm1fcEFubm90RGljdDsNCi0JCUNGWF9CeXRlU3RyaW5nIGNiU3RyaW5nOw0KLQkJaWYocEFubm90RGljdC0+S2V5RXhpc3QoIklUIikpDQotCQkJY2JTdHJpbmcgPSBwQW5ub3REaWN0LT5HZXRTdHJpbmcoIklUIik7DQotCQlpZihjYlN0cmluZy5Db21wYXJlKCJJbWciKSAhPSAwKQ0KLQkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0FOTk9UX1NDUkVFTl9NRURJQSk7DQotCX0NCi0JZWxzZSBpZihjYlN1YlR5cGUuQ29tcGFyZSgiTW92aWUiKSA9PTApDQotCXsNCi0JCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0FOTk9UX01PVklFKTsNCi0JfQ0KLQllbHNlIGlmKGNiU3ViVHlwZS5Db21wYXJlKCJTb3VuZCIpID09MCkNCi0Jew0KLQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfQU5OT1RfU09VTkQpOw0KLQl9DQotCWVsc2UgaWYoY2JTdWJUeXBlLkNvbXBhcmUoIlJpY2hNZWRpYSIpID09MCkNCi0Jew0KLQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfQU5OT1RfU0NSRUVOX1JJQ0hNRURJQSk7DQotCX0NCi0JZWxzZSBpZihjYlN1YlR5cGUuQ29tcGFyZSgiRmlsZUF0dGFjaG1lbnQiKSA9PTApDQotCXsNCi0JCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0FOTk9UX0FUVEFDSE1FTlQpOw0KLQl9DQotCWVsc2UgaWYoY2JTdWJUeXBlLkNvbXBhcmUoIldpZGdldCIpID09MCkNCi0Jew0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0ID0gcFBERkFubm90LT5tX3BBbm5vdERpY3Q7DQotCQlDRlhfQnl0ZVN0cmluZyBjYlN0cmluZzsNCi0JCWlmKHBBbm5vdERpY3QtPktleUV4aXN0KCJGVCIpKQ0KLQkJew0KLQkJCWNiU3RyaW5nID0gcEFubm90RGljdC0+R2V0U3RyaW5nKCJGVCIpOw0KLQkJfQkNCi0JCWlmKGNiU3RyaW5nLkNvbXBhcmUoIlNpZyIpID09IDApDQotCQl7DQotCQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfQU5OT1RfU0lHKTsNCi0JCX0NCi0JfQ0KLQkNCi19DQotDQotRlhfQk9PTCBDaGVja1NoYXJlZEZvcm0oQ1hNTF9FbGVtZW50ICogcEVsZW1lbnQsIENGWF9CeXRlU3RyaW5nIGNiTmFtZSkNCi17DQotCWludCBjb3VudCA9IHBFbGVtZW50LT5Db3VudEF0dHJzKCk7DQotCWludCBpPTA7DQotCWZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSANCi0Jew0KLQkJQ0ZYX0J5dGVTdHJpbmcgc3BhY2UsIG5hbWU7IA0KLQkJQ0ZYX1dpZGVTdHJpbmcgdmFsdWU7DQotCQlwRWxlbWVudC0+R2V0QXR0ckJ5SW5kZXgoaSwgc3BhY2UsIG5hbWUsIHZhbHVlKTsNCi0JCWlmIChzcGFjZSA9PSBGWF9CU1RSQygieG1sbnMiKSAmJiBuYW1lID09IEZYX0JTVFJDKCJhZGhvY3dmIikgJiYgdmFsdWUgPT0gIEwiaHR0cDovL25zLmFkb2JlLmNvbS9BY3JvYmF0QWRob2NXb3JrZmxvdy8xLjAvIikNCi0JCXsNCi0JCQlDWE1MX0VsZW1lbnQgKnBWZXJzaW9uID0gcEVsZW1lbnQtPkdldEVsZW1lbnQoImFkaG9jd2YiLGNiTmFtZSk7DQotCQkJaWYgKCFwVmVyc2lvbikNCi0JCQkJY29udGludWU7DQotCQkJQ0ZYX1dpZGVTdHJpbmcgd3NDb250ZW50ID0gcFZlcnNpb24tPkdldENvbnRlbnQoMCk7IC8vID09IDEuMQ0KLQkJCWludCBuVHlwZSA9IHdzQ29udGVudC5HZXRJbnRlZ2VyKCk7DQotCQkJc3dpdGNoKG5UeXBlKQ0KLQkJCXsNCi0JCQljYXNlIDE6DQotCQkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19TSEFSRURGT1JNX0FDUk9CQVQpOw0KLQkJCQlicmVhazsNCi0JCQljYXNlIDI6DQotCQkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19TSEFSRURGT1JNX0ZJTEVTWVNURU0pOw0KLQkJCQlicmVhazsNCi0JCQljYXNlIDA6DQotCQkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19TSEFSRURGT1JNX0VNQUlMKTsNCi0JCQkJYnJlYWs7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCUZYX0RXT1JEIG5Db3VudCA9IHBFbGVtZW50LT5Db3VudENoaWxkcmVuKCk7DQotCWZvcihpPTA7IGk8KGludCluQ291bnQ7IGkrKykNCi0Jew0KLQkJQ1hNTF9FbGVtZW50OjpDaGlsZFR5cGUgY2hpbGRUeXBlID0gcEVsZW1lbnQtPkdldENoaWxkVHlwZShpKTsNCi0JCWlmKGNoaWxkVHlwZSA9PSBDWE1MX0VsZW1lbnQ6OkVsZW1lbnQpDQotCQl7DQotCQkJQ1hNTF9FbGVtZW50ICogcENoaWxkID0gcEVsZW1lbnQtPkdldEVsZW1lbnQoaSk7DQotCQkJaWYoQ2hlY2tTaGFyZWRGb3JtKHBDaGlsZCwgY2JOYW1lKSkNCi0JCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENoZWNrVW5TdXBwb3J0RXJyb3IoQ1BERl9Eb2N1bWVudCAqIHBEb2MsIEZYX0RXT1JEIGVycl9jb2RlKQ0KLXsNCi0JLy8gU2VjdXJpdHkNCi0JaWYoZXJyX2NvZGUgPT0gRlBERl9FUlJfU0VDVVJJVFkpDQotCXsNCi0JCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19TRUNVUklUWSk7DQotCQlyZXR1cm4gOw0KLQl9DQotCWlmKCFwRG9jKQ0KLQkJcmV0dXJuIDsNCi0NCi0JLy8gUG9ydGZvbGlvcyBhbmQgUGFja2FnZXMgDQotCUNQREZfRGljdGlvbmFyeSAqIHBSb290RGljdCA9IHBEb2MtPkdldFJvb3QoKTsNCi0JaWYocFJvb3REaWN0KQ0KLQl7DQotCQlDRlhfQnl0ZVN0cmluZyBjYlN0cmluZzsNCi0JCWlmKHBSb290RGljdC0+S2V5RXhpc3QoIkNvbGxlY3Rpb24iKSkNCi0JCXsNCi0JCQlGUERGX1VuU3VwcG9ydEVycm9yKEZQREZfVU5TUF9ET0NfUE9SVEFCTEVDT0xMRUNUSU9OKTsNCi0JCQlyZXR1cm4gOw0KLQkJfQ0KLQkJaWYocFJvb3REaWN0LT5LZXlFeGlzdCgiTmFtZXMiKSkNCi0JCXsNCi0JCQlDUERGX0RpY3Rpb25hcnkqIHBOYW1lRGljdCA9IHBSb290RGljdC0+R2V0RGljdCgiTmFtZXMiKTsNCi0JCQlpZihwTmFtZURpY3QtPktleUV4aXN0KCJFbWJlZGRlZEZpbGVzIikpDQotCQkJew0KLQkJCQlGUERGX1VuU3VwcG9ydEVycm9yKEZQREZfVU5TUF9ET0NfQVRUQUNITUVOVCk7DQotCQkJCXJldHVybjsNCi0JCQl9DQotCQkJZWxzZSBpZihwTmFtZURpY3QtPktleUV4aXN0KCJKYXZhU2NyaXB0IikpDQotCQkJew0KLQkJCQlDUERGX0RpY3Rpb25hcnkqIHBKU0RpY3QgPSBwTmFtZURpY3QtPkdldERpY3QoIkphdmFTY3JpcHQiKTsNCi0JCQkJQ1BERl9BcnJheSAqIHBBcnJheSA9IHBKU0RpY3QtPkdldEFycmF5KCJOYW1lcyIpOw0KLQkJCQlpZiAocEFycmF5KSB7DQotCQkJCQlpbnQgbkNvdW50ID0gcEFycmF5LT5HZXRDb3VudCgpOw0KLQkJCQkJZm9yKGludCBpPTA7IGk8bkNvdW50OyBpKyspDQotCQkJCQl7DQotCQkJCQkJQ0ZYX0J5dGVTdHJpbmcgY2JTdHIgPSBwQXJyYXktPkdldFN0cmluZyhpKTsNCi0JCQkJCQlpZihjYlN0ci5Db21wYXJlKCJjb20uYWRvYmUuYWNyb2JhdC5TaGFyZWRSZXZpZXcuUmVnaXN0ZXIiKSA9PSAwKQ0KLQkJCQkJCXsNCi0JCQkJCQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfRE9DX1NIQVJFRFJFVklFVyk7DQotCQkJCQkJCXJldHVybjsNCi0JCQkJCQl9DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0NCi0JLy8gU2hhcmVkRm9ybQ0KLQlDUERGX01ldGFkYXRhIG1ldGFEYXRhOw0KLQltZXRhRGF0YS5Mb2FkRG9jKHBEb2MpOw0KLQlDWE1MX0VsZW1lbnQgKiBwRWxlbWVudCA9IG1ldGFEYXRhLkdldFJvb3QoKTsNCi0JaWYocEVsZW1lbnQpDQotCQlDaGVja1NoYXJlZEZvcm0ocEVsZW1lbnQsICJ3b3JrZmxvd1R5cGUiKTsNCi0NCi0JDQotCS8vIFhGQSBGb3Jtcw0KLQlDUERGX0ludGVyRm9ybSAqIHBJbnRlckZvcm0gPSBGWF9ORVcgQ1BERl9JbnRlckZvcm0ocERvYyxGQUxTRSk7DQotCWlmIChwSW50ZXJGb3JtKQ0KLQl7DQotCQlpZihwSW50ZXJGb3JtLT5IYXNYRkFGb3JtKCkpDQotCQl7DQotCQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfRE9DX1hGQUZPUk0pOw0KLQkJfQ0KLQkJZGVsZXRlIHBJbnRlckZvcm07DQotCX0NCi19DQotDQotRExMRVhQT1JUIGludCBGUERGRG9jX0dldFBhZ2VNb2RlKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpDQotew0KLQlpZiAoIWRvY3VtZW50KSByZXR1cm4gUEFHRU1PREVfVU5LT05PV047DQotCUNQREZfRGljdGlvbmFyeSAqcFJvb3QgPSAoKENQREZfRG9jdW1lbnQqKWRvY3VtZW50KS0+R2V0Um9vdCgpOw0KLQlpZiAoIXBSb290KQ0KLQkJcmV0dXJuIFBBR0VNT0RFX1VOS09OT1dOOw0KLQlDUERGX09iamVjdCogcE5hbWUgPSBwUm9vdC0+R2V0RWxlbWVudCgiUGFnZU1vZGUiKTsNCi0JaWYgKCFwTmFtZSkNCi0JCXJldHVybiBQQUdFTU9ERV9VU0VOT05FOw0KLQlDRlhfQnl0ZVN0cmluZyBzdHJQYWdlTW9kZSA9IHBOYW1lLT5HZXRTdHJpbmcoKTsNCi0JDQotCWlmIChzdHJQYWdlTW9kZS5Jc0VtcHR5KCl8fHN0clBhZ2VNb2RlLkVxdWFsTm9DYXNlKEZYX0JTVFIoIlVzZU5vbmUiKSkpDQotCQlyZXR1cm4gUEFHRU1PREVfVVNFTk9ORTsNCi0JZWxzZSBpZiAoc3RyUGFnZU1vZGUuRXF1YWxOb0Nhc2UoRlhfQlNUUigiVXNlT3V0bGluZXMiKSkpDQotCQlyZXR1cm4gUEFHRU1PREVfVVNFT1VUTElORVM7DQotCWVsc2UgaWYgKHN0clBhZ2VNb2RlLkVxdWFsTm9DYXNlKEZYX0JTVFIoIlVzZVRodW1icyIpKSkNCi0JCXJldHVybiBQQUdFTU9ERV9VU0VUSFVNQlM7DQotCWVsc2UgaWYgKHN0clBhZ2VNb2RlLkVxdWFsTm9DYXNlKEZYX0JTVFIoIkZ1bGxTY3JlZW4iKSkpDQotCQlyZXR1cm4gUEFHRU1PREVfRlVMTFNDUkVFTjsNCi0JZWxzZSBpZiAoc3RyUGFnZU1vZGUuRXF1YWxOb0Nhc2UoRlhfQlNUUigiVXNlT0MiKSkpDQotCQlyZXR1cm4gUEFHRU1PREVfVVNFT0M7DQotCWVsc2UgaWYgKHN0clBhZ2VNb2RlLkVxdWFsTm9DYXNlKEZYX0JTVFIoIlVzZUF0dGFjaG1lbnRzIikpKQ0KLQkJcmV0dXJuIFBBR0VNT0RFX1VTRUFUVEFDSE1FTlRTOw0KLQ0KLQlyZXR1cm4gUEFHRU1PREVfVU5LT05PV047DQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmX2V4dC5oIgorCisjZGVmaW5lICBGUERGU0RLX1VOU1VQUE9SVF9DQUxMIDEwMAorCitjbGFzcyBDRlNES19VbnN1cHBvcnRJbmZvX0FkYXB0ZXIKK3sKK3B1YmxpYzoKKwlDRlNES19VbnN1cHBvcnRJbmZvX0FkYXB0ZXIoVU5TVVBQT1JUX0lORk8qIHVuc3BfaW5mbyl7IG1fdW5zcF9pbmZvID0gdW5zcF9pbmZvO30KKy8vCUZYX0JPT0wgTmVlZFRvUGF1c2VOb3coKTsKKwl2b2lkIFJlcG9ydEVycm9yKGludCBuRXJyb3JUeXBlKTsKKworcHJpdmF0ZToKKwlVTlNVUFBPUlRfSU5GTyogbV91bnNwX2luZm87Cit9OworCit2b2lkIENGU0RLX1Vuc3VwcG9ydEluZm9fQWRhcHRlcjo6UmVwb3J0RXJyb3IoaW50IG5FcnJvclR5cGUpCit7CisJaWYobV91bnNwX2luZm8gJiYgbV91bnNwX2luZm8tPkZTREtfVW5TdXBwb3J0X0hhbmRsZXIpCisJeworCQltX3Vuc3BfaW5mby0+RlNES19VblN1cHBvcnRfSGFuZGxlcihtX3Vuc3BfaW5mbyxuRXJyb3JUeXBlKTsKKwl9Cit9CisKK3ZvaWQgRnJlZVVuc3VwcG9ydEluZm8oRlhfTFBWT0lEIHBEYXRhKQoreworCUNGU0RLX1Vuc3VwcG9ydEluZm9fQWRhcHRlciAqIHBBZGFwdGVyID0gKENGU0RLX1Vuc3VwcG9ydEluZm9fQWRhcHRlciAqKXBEYXRhOworCWRlbGV0ZSBwQWRhcHRlcjsKK30KKworRlhfQk9PTCBGUERGX1VuU3VwcG9ydEVycm9yKGludCBuRXJyb3IpCit7CisJQ0ZTREtfVW5zdXBwb3J0SW5mb19BZGFwdGVyICogcEFkYXB0ZXIgPSAoQ0ZTREtfVW5zdXBwb3J0SW5mb19BZGFwdGVyICopQ1BERl9Nb2R1bGVNZ3I6OkdldCgpLT5HZXRQcml2YXRlRGF0YSgodm9pZCAqKUZQREZTREtfVU5TVVBQT1JUX0NBTEwpOworCisJaWYoIXBBZGFwdGVyKQorCQlyZXR1cm4gRkFMU0U7CisJcEFkYXB0ZXItPlJlcG9ydEVycm9yKG5FcnJvcik7CisJcmV0dXJuIFRSVUU7Cit9CQorCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlNES19TZXRVblNwT2JqUHJvY2Vzc0hhbmRsZXIoVU5TVVBQT1JUX0lORk8qIHVuc3BfaW5mbykKK3sKKwlpZiAoIXVuc3BfaW5mbyB8fCB1bnNwX2luZm8tPnZlcnNpb24hPTEpCisJCXJldHVybiBGQUxTRTsKKwlDRlNES19VbnN1cHBvcnRJbmZvX0FkYXB0ZXIgKiBwQWRhcHRlciA9IG5ldyBDRlNES19VbnN1cHBvcnRJbmZvX0FkYXB0ZXIodW5zcF9pbmZvKTsKKworCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+U2V0UHJpdmF0ZURhdGEoKHZvaWQgKilGUERGU0RLX1VOU1VQUE9SVF9DQUxMLHBBZGFwdGVyLCAmRnJlZVVuc3VwcG9ydEluZm8pOworCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ2hlY2tVblN1cHBvcnRBbm5vdChDUERGX0RvY3VtZW50ICogcERvYywgQ1BERl9Bbm5vdCogcFBERkFubm90KQoreworCUNGWF9CeXRlU3RyaW5nIGNiU3ViVHlwZSA9IHBQREZBbm5vdC0+R2V0U3ViVHlwZSgpOworCWlmKGNiU3ViVHlwZS5Db21wYXJlKCIzRCIpID09IDApCisJeworCQlGUERGX1VuU3VwcG9ydEVycm9yKEZQREZfVU5TUF9BTk5PVF8zREFOTk9UKTsKKwl9CisJZWxzZSBpZihjYlN1YlR5cGUuQ29tcGFyZSgiU2NyZWVuIikgPT0wKQorCXsKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0ID0gcFBERkFubm90LT5tX3BBbm5vdERpY3Q7CisJCUNGWF9CeXRlU3RyaW5nIGNiU3RyaW5nOworCQlpZihwQW5ub3REaWN0LT5LZXlFeGlzdCgiSVQiKSkKKwkJCWNiU3RyaW5nID0gcEFubm90RGljdC0+R2V0U3RyaW5nKCJJVCIpOworCQlpZihjYlN0cmluZy5Db21wYXJlKCJJbWciKSAhPSAwKQorCQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfQU5OT1RfU0NSRUVOX01FRElBKTsKKwl9CisJZWxzZSBpZihjYlN1YlR5cGUuQ29tcGFyZSgiTW92aWUiKSA9PTApCisJeworCQlGUERGX1VuU3VwcG9ydEVycm9yKEZQREZfVU5TUF9BTk5PVF9NT1ZJRSk7CisJfQorCWVsc2UgaWYoY2JTdWJUeXBlLkNvbXBhcmUoIlNvdW5kIikgPT0wKQorCXsKKwkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfQU5OT1RfU09VTkQpOworCX0KKwllbHNlIGlmKGNiU3ViVHlwZS5Db21wYXJlKCJSaWNoTWVkaWEiKSA9PTApCisJeworCQlGUERGX1VuU3VwcG9ydEVycm9yKEZQREZfVU5TUF9BTk5PVF9TQ1JFRU5fUklDSE1FRElBKTsKKwl9CisJZWxzZSBpZihjYlN1YlR5cGUuQ29tcGFyZSgiRmlsZUF0dGFjaG1lbnQiKSA9PTApCisJeworCQlGUERGX1VuU3VwcG9ydEVycm9yKEZQREZfVU5TUF9BTk5PVF9BVFRBQ0hNRU5UKTsKKwl9CisJZWxzZSBpZihjYlN1YlR5cGUuQ29tcGFyZSgiV2lkZ2V0IikgPT0wKQorCXsKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0ID0gcFBERkFubm90LT5tX3BBbm5vdERpY3Q7CisJCUNGWF9CeXRlU3RyaW5nIGNiU3RyaW5nOworCQlpZihwQW5ub3REaWN0LT5LZXlFeGlzdCgiRlQiKSkKKwkJeworCQkJY2JTdHJpbmcgPSBwQW5ub3REaWN0LT5HZXRTdHJpbmcoIkZUIik7CisJCX0JCisJCWlmKGNiU3RyaW5nLkNvbXBhcmUoIlNpZyIpID09IDApCisJCXsKKwkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0FOTk9UX1NJRyk7CisJCX0KKwl9CisJCit9CisKK0ZYX0JPT0wgQ2hlY2tTaGFyZWRGb3JtKENYTUxfRWxlbWVudCAqIHBFbGVtZW50LCBDRlhfQnl0ZVN0cmluZyBjYk5hbWUpCit7CisJaW50IGNvdW50ID0gcEVsZW1lbnQtPkNvdW50QXR0cnMoKTsKKwlpbnQgaT0wOworCWZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSAKKwl7CisJCUNGWF9CeXRlU3RyaW5nIHNwYWNlLCBuYW1lOyAKKwkJQ0ZYX1dpZGVTdHJpbmcgdmFsdWU7CisJCXBFbGVtZW50LT5HZXRBdHRyQnlJbmRleChpLCBzcGFjZSwgbmFtZSwgdmFsdWUpOworCQlpZiAoc3BhY2UgPT0gRlhfQlNUUkMoInhtbG5zIikgJiYgbmFtZSA9PSBGWF9CU1RSQygiYWRob2N3ZiIpICYmIHZhbHVlID09ICBMImh0dHA6Ly9ucy5hZG9iZS5jb20vQWNyb2JhdEFkaG9jV29ya2Zsb3cvMS4wLyIpCisJCXsKKwkJCUNYTUxfRWxlbWVudCAqcFZlcnNpb24gPSBwRWxlbWVudC0+R2V0RWxlbWVudCgiYWRob2N3ZiIsY2JOYW1lKTsKKwkJCWlmICghcFZlcnNpb24pCisJCQkJY29udGludWU7CisJCQlDRlhfV2lkZVN0cmluZyB3c0NvbnRlbnQgPSBwVmVyc2lvbi0+R2V0Q29udGVudCgwKTsgLy8gPT0gMS4xCisJCQlpbnQgblR5cGUgPSB3c0NvbnRlbnQuR2V0SW50ZWdlcigpOworCQkJc3dpdGNoKG5UeXBlKQorCQkJeworCQkJY2FzZSAxOgorCQkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19TSEFSRURGT1JNX0FDUk9CQVQpOworCQkJCWJyZWFrOworCQkJY2FzZSAyOgorCQkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19TSEFSRURGT1JNX0ZJTEVTWVNURU0pOworCQkJCWJyZWFrOworCQkJY2FzZSAwOgorCQkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19TSEFSRURGT1JNX0VNQUlMKTsKKwkJCQlicmVhazsKKwkJCX0KKwkJfQorCX0KKworCUZYX0RXT1JEIG5Db3VudCA9IHBFbGVtZW50LT5Db3VudENoaWxkcmVuKCk7CisJZm9yKGk9MDsgaTwoaW50KW5Db3VudDsgaSsrKQorCXsKKwkJQ1hNTF9FbGVtZW50OjpDaGlsZFR5cGUgY2hpbGRUeXBlID0gcEVsZW1lbnQtPkdldENoaWxkVHlwZShpKTsKKwkJaWYoY2hpbGRUeXBlID09IENYTUxfRWxlbWVudDo6RWxlbWVudCkKKwkJeworCQkJQ1hNTF9FbGVtZW50ICogcENoaWxkID0gcEVsZW1lbnQtPkdldEVsZW1lbnQoaSk7CisJCQlpZihDaGVja1NoYXJlZEZvcm0ocENoaWxkLCBjYk5hbWUpKQorCQkJCXJldHVybiBUUlVFOworCQl9CisJfQorCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDaGVja1VuU3VwcG9ydEVycm9yKENQREZfRG9jdW1lbnQgKiBwRG9jLCBGWF9EV09SRCBlcnJfY29kZSkKK3sKKwkvLyBTZWN1cml0eQorCWlmKGVycl9jb2RlID09IEZQREZfRVJSX1NFQ1VSSVRZKQorCXsKKwkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfRE9DX1NFQ1VSSVRZKTsKKwkJcmV0dXJuIDsKKwl9CisJaWYoIXBEb2MpCisJCXJldHVybiA7CisKKwkvLyBQb3J0Zm9saW9zIGFuZCBQYWNrYWdlcyAKKwlDUERGX0RpY3Rpb25hcnkgKiBwUm9vdERpY3QgPSBwRG9jLT5HZXRSb290KCk7CisJaWYocFJvb3REaWN0KQorCXsKKwkJQ0ZYX0J5dGVTdHJpbmcgY2JTdHJpbmc7CisJCWlmKHBSb290RGljdC0+S2V5RXhpc3QoIkNvbGxlY3Rpb24iKSkKKwkJeworCQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfRE9DX1BPUlRBQkxFQ09MTEVDVElPTik7CisJCQlyZXR1cm4gOworCQl9CisJCWlmKHBSb290RGljdC0+S2V5RXhpc3QoIk5hbWVzIikpCisJCXsKKwkJCUNQREZfRGljdGlvbmFyeSogcE5hbWVEaWN0ID0gcFJvb3REaWN0LT5HZXREaWN0KCJOYW1lcyIpOworCQkJaWYocE5hbWVEaWN0LT5LZXlFeGlzdCgiRW1iZWRkZWRGaWxlcyIpKQorCQkJeworCQkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19BVFRBQ0hNRU5UKTsKKwkJCQlyZXR1cm47CisJCQl9CisJCQllbHNlIGlmKHBOYW1lRGljdC0+S2V5RXhpc3QoIkphdmFTY3JpcHQiKSkKKwkJCXsKKwkJCQlDUERGX0RpY3Rpb25hcnkqIHBKU0RpY3QgPSBwTmFtZURpY3QtPkdldERpY3QoIkphdmFTY3JpcHQiKTsKKwkJCQlDUERGX0FycmF5ICogcEFycmF5ID0gcEpTRGljdC0+R2V0QXJyYXkoIk5hbWVzIik7CisJCQkJaWYgKHBBcnJheSkgeworCQkJCQlpbnQgbkNvdW50ID0gcEFycmF5LT5HZXRDb3VudCgpOworCQkJCQlmb3IoaW50IGk9MDsgaTxuQ291bnQ7IGkrKykKKwkJCQkJeworCQkJCQkJQ0ZYX0J5dGVTdHJpbmcgY2JTdHIgPSBwQXJyYXktPkdldFN0cmluZyhpKTsKKwkJCQkJCWlmKGNiU3RyLkNvbXBhcmUoImNvbS5hZG9iZS5hY3JvYmF0LlNoYXJlZFJldmlldy5SZWdpc3RlciIpID09IDApCisJCQkJCQl7CisJCQkJCQkJRlBERl9VblN1cHBvcnRFcnJvcihGUERGX1VOU1BfRE9DX1NIQVJFRFJFVklFVyk7CisJCQkJCQkJcmV0dXJuOworCQkJCQkJfQorCQkJCQl9CisJCQkJfQorCQkJfQorCQl9CisJfQorCisJLy8gU2hhcmVkRm9ybQorCUNQREZfTWV0YWRhdGEgbWV0YURhdGE7CisJbWV0YURhdGEuTG9hZERvYyhwRG9jKTsKKwlDWE1MX0VsZW1lbnQgKiBwRWxlbWVudCA9IG1ldGFEYXRhLkdldFJvb3QoKTsKKwlpZihwRWxlbWVudCkKKwkJQ2hlY2tTaGFyZWRGb3JtKHBFbGVtZW50LCAid29ya2Zsb3dUeXBlIik7CisKKwkKKwkvLyBYRkEgRm9ybXMKKwlDUERGX0ludGVyRm9ybSAqIHBJbnRlckZvcm0gPSBGWF9ORVcgQ1BERl9JbnRlckZvcm0ocERvYyxGQUxTRSk7CisJaWYgKHBJbnRlckZvcm0pCisJeworCQlpZihwSW50ZXJGb3JtLT5IYXNYRkFGb3JtKCkpCisJCXsKKwkJCUZQREZfVW5TdXBwb3J0RXJyb3IoRlBERl9VTlNQX0RPQ19YRkFGT1JNKTsKKwkJfQorCQlkZWxldGUgcEludGVyRm9ybTsKKwl9Cit9CisKK0RMTEVYUE9SVCBpbnQgRlBERkRvY19HZXRQYWdlTW9kZShGUERGX0RPQ1VNRU5UIGRvY3VtZW50KQoreworCWlmICghZG9jdW1lbnQpIHJldHVybiBQQUdFTU9ERV9VTktPTk9XTjsKKwlDUERGX0RpY3Rpb25hcnkgKnBSb290ID0gKChDUERGX0RvY3VtZW50Kilkb2N1bWVudCktPkdldFJvb3QoKTsKKwlpZiAoIXBSb290KQorCQlyZXR1cm4gUEFHRU1PREVfVU5LT05PV047CisJQ1BERl9PYmplY3QqIHBOYW1lID0gcFJvb3QtPkdldEVsZW1lbnQoIlBhZ2VNb2RlIik7CisJaWYgKCFwTmFtZSkKKwkJcmV0dXJuIFBBR0VNT0RFX1VTRU5PTkU7CisJQ0ZYX0J5dGVTdHJpbmcgc3RyUGFnZU1vZGUgPSBwTmFtZS0+R2V0U3RyaW5nKCk7CisJCisJaWYgKHN0clBhZ2VNb2RlLklzRW1wdHkoKXx8c3RyUGFnZU1vZGUuRXF1YWxOb0Nhc2UoRlhfQlNUUigiVXNlTm9uZSIpKSkKKwkJcmV0dXJuIFBBR0VNT0RFX1VTRU5PTkU7CisJZWxzZSBpZiAoc3RyUGFnZU1vZGUuRXF1YWxOb0Nhc2UoRlhfQlNUUigiVXNlT3V0bGluZXMiKSkpCisJCXJldHVybiBQQUdFTU9ERV9VU0VPVVRMSU5FUzsKKwllbHNlIGlmIChzdHJQYWdlTW9kZS5FcXVhbE5vQ2FzZShGWF9CU1RSKCJVc2VUaHVtYnMiKSkpCisJCXJldHVybiBQQUdFTU9ERV9VU0VUSFVNQlM7CisJZWxzZSBpZiAoc3RyUGFnZU1vZGUuRXF1YWxOb0Nhc2UoRlhfQlNUUigiRnVsbFNjcmVlbiIpKSkKKwkJcmV0dXJuIFBBR0VNT0RFX0ZVTExTQ1JFRU47CisJZWxzZSBpZiAoc3RyUGFnZU1vZGUuRXF1YWxOb0Nhc2UoRlhfQlNUUigiVXNlT0MiKSkpCisJCXJldHVybiBQQUdFTU9ERV9VU0VPQzsKKwllbHNlIGlmIChzdHJQYWdlTW9kZS5FcXVhbE5vQ2FzZShGWF9CU1RSKCJVc2VBdHRhY2htZW50cyIpKSkKKwkJcmV0dXJuIFBBR0VNT0RFX1VTRUFUVEFDSE1FTlRTOworCisJcmV0dXJuIFBBR0VNT0RFX1VOS09OT1dOOworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnBkZl9mbGF0dGVuLmNwcCBiL2ZwZGZzZGsvc3JjL2ZwZGZfZmxhdHRlbi5jcHAKaW5kZXggZjA0MTAwZi4uNmQzNDQwZiAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnBkZl9mbGF0dGVuLmNwcAorKysgYi9mcGRmc2RrL3NyYy9mcGRmX2ZsYXR0ZW4uY3BwCkBAIC0xLDU2MSArMSw1NjEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZl9mbGF0dGVuLmgiDQotDQotdHlwZWRlZiBDRlhfQXJyYXlUZW1wbGF0ZTxDUERGX0RpY3Rpb25hcnkqPiBDUERGX09iamVjdEFycmF5Ow0KLXR5cGVkZWYgQ0ZYX0FycmF5VGVtcGxhdGU8Q1BERl9SZWN0PiBDUERGX1JlY3RBcnJheTsNCi0NCi1lbnVtIEZQREZfVFlQRSB7IE1BWCwgTUlOIH07DQotZW51bSBGUERGX1ZBTFVFIHsgVE9QLCBMRUZULCBSSUdIVCwgQk9UVE9NIH07DQotDQotRlhfQk9PTCBJc1ZhbGlhYmxlUmVjdChDUERGX1JlY3QgcmVjdCwgQ1BERl9SZWN0IHJjUGFnZSkNCi17DQotCWlmICggcmVjdC5sZWZ0IC0gcmVjdC5yaWdodCA+IDAuMDAwMDAxZiB8fCANCi0JCSByZWN0LmJvdHRvbSAtIHJlY3QudG9wID4gMC4wMDAwMDFmKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQkNCi0JaWYgKHJlY3QubGVmdCA9PSAwLjBmICYmDQotCQlyZWN0LnRvcCA9PSAwLjBmICYmDQotCQlyZWN0LnJpZ2h0ID09IDAuMGYgJiYNCi0JCXJlY3QuYm90dG9tID09IDAuMGYpDQotCQlyZXR1cm4gRkFMU0U7DQotCQ0KLQlpZiAoIXJjUGFnZS5Jc0VtcHR5KCkpDQotCXsNCi0JCWlmIChyZWN0LmxlZnQgLSByY1BhZ2UubGVmdCA8IC0xMC4wMDAwMDFmIHx8DQotCQkJcmVjdC5yaWdodCAtIHJjUGFnZS5yaWdodCA+IDEwLjAwMDAwMWYgfHwNCi0JCQlyZWN0LnRvcCAtIHJjUGFnZS50b3AgPiAxMC4wMDAwMDFmIHx8DQotCQkJcmVjdC5ib3R0b20gLSByY1BhZ2UuYm90dG9tIDwgLTEwLjAwMDAwMWYpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotDQotRlhfQk9PTCBHZXRDb250ZW50c1JlY3QoIENQREZfRG9jdW1lbnQgKiBwRG9jLCBDUERGX0RpY3Rpb25hcnkqIHBEaWN0LCBDUERGX1JlY3RBcnJheSAqIHBSZWN0QXJyYXkgKQ0KLXsNCi0JQ1BERl9QYWdlKiBwUERGUGFnZSA9IEZYX05FVyBDUERGX1BhZ2U7DQotCXBQREZQYWdlLT5Mb2FkKCBwRG9jLCBwRGljdCwgRkFMU0UgKTsNCi0JcFBERlBhZ2UtPlBhcnNlQ29udGVudCgpOw0KLQ0KLQlGWF9QT1NJVElPTiBwb3MgPSBwUERGUGFnZS0+R2V0Rmlyc3RPYmplY3RQb3NpdGlvbigpOw0KLQkNCi0Jd2hpbGUgKHBvcykNCi0Jew0KLQkJQ1BERl9QYWdlT2JqZWN0KiBwUGFnZU9iamVjdCA9IHBQREZQYWdlLT5HZXROZXh0T2JqZWN0KHBvcyk7DQotCQlpZiAoIXBQYWdlT2JqZWN0KWNvbnRpbnVlOw0KLQkJDQotCQlDUERGX1JlY3QgcmM7DQotCQlyYy5sZWZ0ID0gcFBhZ2VPYmplY3QtPm1fTGVmdDsNCi0JCXJjLnJpZ2h0ID0gcFBhZ2VPYmplY3QtPm1fUmlnaHQ7DQotCQlyYy5ib3R0b20gPSBwUGFnZU9iamVjdC0+bV9Cb3R0b207DQotCQlyYy50b3AgPSBwUGFnZU9iamVjdC0+bV9Ub3A7DQotCQkNCi0JCWlmIChJc1ZhbGlhYmxlUmVjdChyYywgcERpY3QtPkdldFJlY3QoIk1lZGlhQm94IikpKQ0KLQkJew0KLQkJCXBSZWN0QXJyYXktPkFkZChyYyk7DQotCQl9DQotCX0NCi0JDQotCWRlbGV0ZSBwUERGUGFnZTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLQ0KLXZvaWQgUGFyc2VyU3RyZWFtKCBDUERGX0RpY3Rpb25hcnkgKiBwUGFnZURpYywgQ1BERl9EaWN0aW9uYXJ5KiBwU3RyZWFtLCBDUERGX1JlY3RBcnJheSAqIHBSZWN0QXJyYXksIENQREZfT2JqZWN0QXJyYXkgKiBwT2JqZWN0QXJyYXkgKQ0KLXsNCi0JaWYgKCFwU3RyZWFtKXJldHVybjsNCi0JQ1BERl9SZWN0IHJlY3Q7DQotCWlmIChwU3RyZWFtLT5LZXlFeGlzdCgiUmVjdCIpKQ0KLQkJcmVjdCA9IHBTdHJlYW0tPkdldFJlY3QoIlJlY3QiKTsNCi0JZWxzZSBpZiAocFN0cmVhbS0+S2V5RXhpc3QoIkJCb3giKSkNCi0JCXJlY3QgPSBwU3RyZWFtLT5HZXRSZWN0KCJCQm94Iik7DQotCQ0KLQlpZiAoSXNWYWxpYWJsZVJlY3QocmVjdCwgcFBhZ2VEaWMtPkdldFJlY3QoIk1lZGlhQm94IikpKQ0KLQkJcFJlY3RBcnJheS0+QWRkKHJlY3QpOw0KLQkNCi0JcE9iamVjdEFycmF5LT5BZGQocFN0cmVhbSk7DQotfQ0KLQ0KLQ0KLWludCBQYXJzZXJBbm5vdHMoIENQREZfRG9jdW1lbnQqIHBTb3VyY2VEb2MsIENQREZfRGljdGlvbmFyeSAqIHBQYWdlRGljLCBDUERGX1JlY3RBcnJheSAqIHBSZWN0QXJyYXksIENQREZfT2JqZWN0QXJyYXkgKiBwT2JqZWN0QXJyYXksIGludCBuVXNhZ2UpDQotew0KLQlpZiAoIXBTb3VyY2VEb2MgfHwgIXBQYWdlRGljKSByZXR1cm4gRkxBVFRFTl9GQUlMOw0KLQkNCi0JR2V0Q29udGVudHNSZWN0KCBwU291cmNlRG9jLCBwUGFnZURpYywgcFJlY3RBcnJheSApOw0KLQlDUERGX0FycmF5KiBwQW5ub3RzID0gcFBhZ2VEaWMtPkdldEFycmF5KCJBbm5vdHMiKTsNCi0JaWYgKHBBbm5vdHMpDQotCXsNCi0JCUZYX0RXT1JEIGR3U2l6ZSA9IHBBbm5vdHMtPkdldENvdW50KCk7DQotCQkNCi0JCWZvciAoaW50IGkgPSAwOyBpIDwgKGludClkd1NpemU7IGkrKykNCi0JCXsNCi0JCQlDUERGX09iamVjdCogcE9iaiA9IHBBbm5vdHMtPkdldEVsZW1lbnRWYWx1ZShpKTsNCi0JCQkNCi0JCQlpZiAoIXBPYmopY29udGludWU7DQotCQkJDQotCQkJaWYgKHBPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfRElDVElPTkFSWSkNCi0JCQl7DQotCQkJCUNQREZfRGljdGlvbmFyeSogcEFubm90RGljID0gKENQREZfRGljdGlvbmFyeSopcE9iajsNCi0JCQkJQ0ZYX0J5dGVTdHJpbmcgc1N1YnR5cGUgPSBwQW5ub3REaWMtPkdldFN0cmluZygiU3VidHlwZSIpOw0KLQkJCQlpZiAoc1N1YnR5cGUgPT0gIlBvcHVwIiljb250aW51ZTsNCi0NCi0JCQkJaW50IG5Bbm5vdEZsYWcgPSBwQW5ub3REaWMtPkdldEludGVnZXIoIkYiKTsNCi0NCi0JCQkJaWYobkFubm90RmxhZyAmIEFOTk9URkxBR19ISURERU4pIA0KLQkJCQkJY29udGludWU7DQotCQkJCWlmKG5Vc2FnZSA9PSBGTEFUX05PUk1BTERJU1BMQVkpDQotCQkJCXsNCi0JCQkJCWlmKG5Bbm5vdEZsYWcgJiBBTk5PVEZMQUdfSU5WSVNJQkxFKQ0KLQkJCQkJCWNvbnRpbnVlOw0KLQkJCQkJUGFyc2VyU3RyZWFtKCBwUGFnZURpYywgcEFubm90RGljLCBwUmVjdEFycmF5LCBwT2JqZWN0QXJyYXkgKTsJCQ0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJaWYobkFubm90RmxhZyAmIEFOTk9URkxBR19QUklOVCkNCi0JCQkJCQlQYXJzZXJTdHJlYW0oIHBQYWdlRGljLCBwQW5ub3REaWMsIHBSZWN0QXJyYXksIHBPYmplY3RBcnJheSApOw0KLQkJCQl9CQkJDQotCQkJfQ0KLQkJfQ0KLQkJcmV0dXJuIEZMQVRURU5fU1VDQ0VTUzsNCi0JfWVsc2V7DQotCQlyZXR1cm4gRkxBVFRFTl9OT1RJTkdUT0RPOw0KLQl9DQotfQ0KLQ0KLQ0KLUZYX0ZMT0FUIEdldE1pbk1heFZhbHVlKCBDUERGX1JlY3RBcnJheSYgYXJyYXksIEZQREZfVFlQRSB0eXBlLCBGUERGX1ZBTFVFIHZhbHVlKQ0KLXsNCi0JaW50IG5SZWN0cyA9IGFycmF5LkdldFNpemUoKTsNCi0JRlhfRkxPQVQgZlJldCA9IDAuMGY7DQotCQ0KLQlpZiAoblJlY3RzIDw9IDApcmV0dXJuIDAuMGY7DQotCQ0KLQlGWF9GTE9BVCogcEFycmF5ID0gbmV3IEZYX0ZMT0FUW25SZWN0c107DQotCXN3aXRjaCh2YWx1ZSkNCi0Jew0KLQljYXNlIExFRlQ6DQotCQl7DQotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBuUmVjdHM7IGkrKykNCi0JCQkJcEFycmF5W2ldID0gQ1BERl9SZWN0KGFycmF5LkdldEF0KGkpKS5sZWZ0Ow0KLQkJCQ0KLQkJCWJyZWFrOw0KLQkJfQ0KLQljYXNlIFRPUDoNCi0JCXsNCi0JCQlmb3IgKGludCBpID0gMDsgaSA8IG5SZWN0czsgaSsrKQ0KLQkJCQlwQXJyYXlbaV0gPSBDUERGX1JlY3QoYXJyYXkuR2V0QXQoaSkpLnRvcDsNCi0JCQkNCi0JCQlicmVhazsNCi0JCX0NCi0JY2FzZSBSSUdIVDoNCi0JCXsNCi0JCQlmb3IgKGludCBpID0gMDsgaSA8IG5SZWN0czsgaSsrKQ0KLQkJCQlwQXJyYXlbaV0gPSBDUERGX1JlY3QoYXJyYXkuR2V0QXQoaSkpLnJpZ2h0Ow0KLQkJCQ0KLQkJCWJyZWFrOw0KLQkJfQ0KLQljYXNlIEJPVFRPTToNCi0JCXsNCi0JCQlmb3IgKGludCBpID0gMDsgaSA8IG5SZWN0czsgaSsrKQ0KLQkJCQlwQXJyYXlbaV0gPSBDUERGX1JlY3QoYXJyYXkuR2V0QXQoaSkpLmJvdHRvbTsNCi0JCQkNCi0JCQlicmVhazsNCi0JCX0NCi0JZGVmYXVsdDoNCi0JCWJyZWFrOw0KLQl9DQotCWZSZXQgPSBwQXJyYXlbMF07DQotCWlmICh0eXBlID09IE1BWCkNCi0Jew0KLQkJZm9yIChpbnQgaSA9IDE7IGkgPCBuUmVjdHM7IGkrKykNCi0JCQlpZiAoZlJldCA8PSBwQXJyYXlbaV0pDQotCQkJCWZSZXQgPSBwQXJyYXlbaV07DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlmb3IgKGludCBpID0gMTsgaSA8IG5SZWN0czsgaSsrKQ0KLQkJCWlmIChmUmV0ID49IHBBcnJheVtpXSkNCi0JCQkJZlJldCA9IHBBcnJheVtpXTsNCi0JfQ0KLQlkZWxldGVbXSBwQXJyYXk7DQotCXJldHVybiBmUmV0Ow0KLX0NCi0NCi1DUERGX1JlY3QgQ2FsY3VsYXRlUmVjdCggQ1BERl9SZWN0QXJyYXkgKiBwUmVjdEFycmF5ICkNCi17DQotDQotCUNQREZfUmVjdCByY1JldDsNCi0JDQotCXJjUmV0LmxlZnQgPSBHZXRNaW5NYXhWYWx1ZSgqcFJlY3RBcnJheSwgTUlOLCBMRUZUKTsNCi0JcmNSZXQudG9wID0gR2V0TWluTWF4VmFsdWUoKnBSZWN0QXJyYXksIE1BWCwgVE9QKTsNCi0JcmNSZXQucmlnaHQgPSBHZXRNaW5NYXhWYWx1ZSgqcFJlY3RBcnJheSwgTUFYLCBSSUdIVCk7DQotCXJjUmV0LmJvdHRvbSA9IEdldE1pbk1heFZhbHVlKCpwUmVjdEFycmF5LCBNSU4sIEJPVFRPTSk7DQotCQ0KLQlyZXR1cm4gcmNSZXQ7DQotfQ0KLQ0KLQ0KLXZvaWQgU2V0UGFnZUNvbnRlbnRzKENGWF9CeXRlU3RyaW5nIGtleSwgQ1BERl9EaWN0aW9uYXJ5KiBwUGFnZSwgQ1BERl9Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0JQ1BERl9PYmplY3QqIHBDb250ZW50c09iaiA9IHBQYWdlLT5HZXRTdHJlYW0oIkNvbnRlbnRzIik7DQotCWlmICghcENvbnRlbnRzT2JqKQ0KLQl7DQotCQlwQ29udGVudHNPYmogPSBwUGFnZS0+R2V0QXJyYXkoIkNvbnRlbnRzIik7DQotCX0NCi0JDQotCWlmICghcENvbnRlbnRzT2JqKQ0KLQl7DQotCQkvL0NyZWF0ZSBhIG5ldyBjb250ZW50cyBkaWN0aW9uYXJ5DQotCQlpZiAoIWtleS5Jc0VtcHR5KCkpDQotCQl7DQotCQkJQ1BERl9TdHJlYW0qIHBOZXdDb250ZW50cyA9IEZYX05FVyBDUERGX1N0cmVhbShOVUxMLCAwLCBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5KTsNCi0JCQlpZiAoIXBOZXdDb250ZW50cylyZXR1cm47DQotCQkJcFBhZ2UtPlNldEF0UmVmZXJlbmNlKCJDb250ZW50cyIsIHBEb2N1bWVudCwgcERvY3VtZW50LT5BZGRJbmRpcmVjdE9iamVjdChwTmV3Q29udGVudHMpKTsNCi0JCQkNCi0JCQlDRlhfQnl0ZVN0cmluZyBzU3RyZWFtOw0KLQkJCXNTdHJlYW0uRm9ybWF0KCJxIDEgMCAwIDEgMCAwIGNtIC8lcyBEbyBRIiwgKEZYX0xQQ1NUUilrZXkpOw0KLQkJCXBOZXdDb250ZW50cy0+U2V0RGF0YSgoRlhfTFBDQllURSlzU3RyZWFtLCBzU3RyZWFtLkdldExlbmd0aCgpLCBGQUxTRSwgRkFMU0UpOw0KLQkJfQ0KLQkJcmV0dXJuOw0KLQl9DQotDQotCWludCBpVHlwZSA9IHBDb250ZW50c09iai0+R2V0VHlwZSgpOw0KLQlDUERGX0FycmF5KiBwQ29udGVudHNBcnJheSA9IE5VTEw7DQotCQ0KLQlzd2l0Y2goaVR5cGUpDQotCXsNCi0JY2FzZSBQREZPQkpfU1RSRUFNOg0KLQkJew0KLQkJCXBDb250ZW50c0FycmF5ID0gRlhfTkVXIENQREZfQXJyYXk7DQotCQkJQ1BERl9TdHJlYW0qIHBDb250ZW50cyA9IChDUERGX1N0cmVhbSopcENvbnRlbnRzT2JqOw0KLQkJCUZYX0RXT1JEIGR3T2JqTnVtID0gcERvY3VtZW50LT5BZGRJbmRpcmVjdE9iamVjdChwQ29udGVudHMpOw0KLQkJCUNQREZfU3RyZWFtQWNjIGFjYzsNCi0JCQlhY2MuTG9hZEFsbERhdGEocENvbnRlbnRzKTsNCi0JCQlDRlhfQnl0ZVN0cmluZyBzU3RyZWFtID0gInFcbiI7DQotCQkJQ0ZYX0J5dGVTdHJpbmcgc0JvZHkgPSBDRlhfQnl0ZVN0cmluZygoRlhfTFBDU1RSKWFjYy5HZXREYXRhKCksIGFjYy5HZXRTaXplKCkpOw0KLQkJCXNTdHJlYW0gPSBzU3RyZWFtICsgc0JvZHkgKyAiXG5RIjsNCi0JCQlwQ29udGVudHMtPlNldERhdGEoKEZYX0xQQ0JZVEUpc1N0cmVhbSwgc1N0cmVhbS5HZXRMZW5ndGgoKSwgRkFMU0UsIEZBTFNFKTsNCi0JCQlwQ29udGVudHNBcnJheS0+QWRkUmVmZXJlbmNlKHBEb2N1bWVudCwgZHdPYmpOdW0pOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQkJDQotCWNhc2UgUERGT0JKX0FSUkFZOg0KLQkJew0KLQkJCXBDb250ZW50c0FycmF5ID0gKENQREZfQXJyYXkqKXBDb250ZW50c09iajsNCi0JCQlicmVhazsNCi0JCX0NCi0JZGVmYXVsdDoNCi0JCWJyZWFrOw0KLQl9CQ0KLQkNCi0JaWYgKCFwQ29udGVudHNBcnJheSlyZXR1cm47DQotCQ0KLQlGWF9EV09SRCBkd09iak51bSA9IHBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocENvbnRlbnRzQXJyYXkpOw0KLQlwUGFnZS0+U2V0QXRSZWZlcmVuY2UoIkNvbnRlbnRzIiwgcERvY3VtZW50LCBkd09iak51bSk7DQotCQ0KLQlpZiAoIWtleS5Jc0VtcHR5KCkpDQotCXsNCi0JCUNQREZfU3RyZWFtKiBwTmV3Q29udGVudHMgPSBGWF9ORVcgQ1BERl9TdHJlYW0oTlVMTCwgMCwgRlhfTkVXIENQREZfRGljdGlvbmFyeSk7DQotCQlkd09iak51bSA9IHBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocE5ld0NvbnRlbnRzKTsNCi0JCXBDb250ZW50c0FycmF5LT5BZGRSZWZlcmVuY2UocERvY3VtZW50LCBkd09iak51bSk7DQotCQkNCi0JCUNGWF9CeXRlU3RyaW5nIHNTdHJlYW07DQotCQlzU3RyZWFtLkZvcm1hdCgicSAxIDAgMCAxIDAgMCBjbSAvJXMgRG8gUSIsIChGWF9MUENTVFIpa2V5KTsNCi0JCXBOZXdDb250ZW50cy0+U2V0RGF0YSgoRlhfTFBDQllURSlzU3RyZWFtLCBzU3RyZWFtLkdldExlbmd0aCgpLCBGQUxTRSwgRkFMU0UpOw0KLQl9DQotfQ0KLSANCi1DRlhfQWZmaW5lTWF0cml4IEdldE1hdHJpeChDUERGX1JlY3QgcmNBbm5vdCwgQ1BERl9SZWN0IHJjU3RyZWFtLCBDRlhfQWZmaW5lTWF0cml4IG1hdHJpeCkNCi17DQotCWlmKHJjU3RyZWFtLklzRW1wdHkoKSkNCi0JCXJldHVybiBDRlhfQWZmaW5lTWF0cml4KCk7DQotCQ0KLQltYXRyaXguVHJhbnNmb3JtUmVjdChyY1N0cmVhbSk7DQotCXJjU3RyZWFtLk5vcm1hbGl6ZSgpOw0KLQkNCi0JRlhfRkxPQVQgYSA9IHJjQW5ub3QuV2lkdGgoKS9yY1N0cmVhbS5XaWR0aCgpOw0KLQlGWF9GTE9BVCBkID0gcmNBbm5vdC5IZWlnaHQoKS9yY1N0cmVhbS5IZWlnaHQoKTsNCi0JDQotCUZYX0ZMT0FUIGUgPSByY0Fubm90LmxlZnQgLSByY1N0cmVhbS5sZWZ0ICogYTsNCi0JRlhfRkxPQVQgZiA9IHJjQW5ub3QuYm90dG9tIC0gcmNTdHJlYW0uYm90dG9tICogZDsNCi0JcmV0dXJuIENGWF9BZmZpbmVNYXRyaXgoYSwgMCwgMCwgZCwgZSwgZik7DQotfQ0KLQ0KLXZvaWQgR2V0T2Zmc2V0KEZYX0ZMT0FUJiBmYSwgRlhfRkxPQVQmIGZkLCBGWF9GTE9BVCYgZmUsIEZYX0ZMT0FUJiBmZiwgQ1BERl9SZWN0IHJjQW5ub3QsIENQREZfUmVjdCByY1N0cmVhbSwgQ0ZYX0FmZmluZU1hdHJpeCBtYXRyaXgpDQotew0KLQlGWF9GTE9BVCBmU3RyZWFtV2lkdGggPSAwLjBmOw0KLQlGWF9GTE9BVCBmU3RyZWFtSGVpZ2h0ID0gMC4wZjsNCi0NCi0NCi0JDQotCWlmIChtYXRyaXguYSAhPSAwICYmIG1hdHJpeC5kICE9IDApDQotCXsNCi0JCWZTdHJlYW1XaWR0aCA9IHJjU3RyZWFtLnJpZ2h0IC0gcmNTdHJlYW0ubGVmdDsNCi0JCWZTdHJlYW1IZWlnaHQgPSByY1N0cmVhbS50b3AgLSByY1N0cmVhbS5ib3R0b207DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlmU3RyZWFtV2lkdGggPSByY1N0cmVhbS50b3AgLSByY1N0cmVhbS5ib3R0b207DQotCQlmU3RyZWFtSGVpZ2h0ID0gcmNTdHJlYW0ucmlnaHQgLSByY1N0cmVhbS5sZWZ0Ow0KLQl9DQotCQ0KLQlGWF9GTE9BVCB4MSA9IG1hdHJpeC5hICogcmNTdHJlYW0ubGVmdCArIG1hdHJpeC5jICogcmNTdHJlYW0uYm90dG9tICsgbWF0cml4LmU7DQotCUZYX0ZMT0FUIHkxID0gbWF0cml4LmIgKiByY1N0cmVhbS5sZWZ0ICsgbWF0cml4LmQgKiByY1N0cmVhbS5ib3R0b20gKyBtYXRyaXguZjsNCi0JRlhfRkxPQVQgeDIgPSBtYXRyaXguYSAqIHJjU3RyZWFtLmxlZnQgKyBtYXRyaXguYyAqIHJjU3RyZWFtLnRvcCArIG1hdHJpeC5lOw0KLQlGWF9GTE9BVCB5MiA9IG1hdHJpeC5iICogcmNTdHJlYW0ubGVmdCArIG1hdHJpeC5kICogcmNTdHJlYW0udG9wICsgbWF0cml4LmY7DQotCUZYX0ZMT0FUIHgzID0gbWF0cml4LmEgKiByY1N0cmVhbS5yaWdodCArIG1hdHJpeC5jICogcmNTdHJlYW0uYm90dG9tICsgbWF0cml4LmU7DQotCUZYX0ZMT0FUIHkzID0gbWF0cml4LmIgKiByY1N0cmVhbS5yaWdodCArIG1hdHJpeC5kICogcmNTdHJlYW0uYm90dG9tICsgbWF0cml4LmY7DQotCUZYX0ZMT0FUIHg0ID0gbWF0cml4LmEgKiByY1N0cmVhbS5yaWdodCArIG1hdHJpeC5jICogcmNTdHJlYW0udG9wICsgbWF0cml4LmU7DQotCUZYX0ZMT0FUIHk0ID0gbWF0cml4LmIgKiByY1N0cmVhbS5yaWdodCArIG1hdHJpeC5kICogcmNTdHJlYW0udG9wICsgbWF0cml4LmY7DQotCQ0KLQlGWF9GTE9BVCBsZWZ0ID0gRlhfTUlOKEZYX01JTih4MSwgeDIpLCBGWF9NSU4oeDMsIHg0KSk7DQotCUZYX0ZMT0FUIGJvdHRvbSA9IEZYX01JTihGWF9NSU4oeTEsIHkyKSwgRlhfTUlOKHkzLCB5NCkpOw0KLQkNCi0JZmEgPSAocmNBbm5vdC5yaWdodCAtIHJjQW5ub3QubGVmdCkvZlN0cmVhbVdpZHRoOw0KLQlmZCA9IChyY0Fubm90LnRvcCAtIHJjQW5ub3QuYm90dG9tKS9mU3RyZWFtSGVpZ2h0Ow0KLQlmZSA9IHJjQW5ub3QubGVmdCAtIGxlZnQgKiBmYTsNCi0JZmYgPSByY0Fubm90LmJvdHRvbSAtIGJvdHRvbSAqIGZkOw0KLX0NCi0NCi0NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERlBhZ2VfRmxhdHRlbiggRlBERl9QQUdFIHBhZ2UsIGludCBuRmxhZykNCi17DQotCWlmICghcGFnZSkNCi0Jew0KLQkJcmV0dXJuIEZMQVRURU5fRkFJTDsNCi0JfQ0KLQ0KLQlDUERGX1BhZ2UgKiBwUGFnZSA9IChDUERGX1BhZ2UqKSggcGFnZSApOw0KLQlDUERGX0RvY3VtZW50ICogcERvY3VtZW50ID0gcFBhZ2UtPm1fcERvY3VtZW50Ow0KLQlDUERGX0RpY3Rpb25hcnkgKiBwUGFnZURpY3QgPSBwUGFnZS0+bV9wRm9ybURpY3Q7DQotCQ0KLQlpZiAoICFwRG9jdW1lbnQgfHwgIXBQYWdlRGljdCApDQotCXsNCi0JCXJldHVybiBGTEFUVEVOX0ZBSUw7DQotCX0NCi0NCi0JQ1BERl9PYmplY3RBcnJheSBPYmplY3RBcnJheTsNCi0JQ1BERl9SZWN0QXJyYXkgIFJlY3RBcnJheTsNCi0NCi0JaW50IGlSZXQgPSBGTEFUVEVOX0ZBSUw7DQotCWlSZXQgPSBQYXJzZXJBbm5vdHMoIHBEb2N1bWVudCwgcFBhZ2VEaWN0LCAmUmVjdEFycmF5LCAmT2JqZWN0QXJyYXksIG5GbGFnKTsNCi0JaWYgKGlSZXQgPT0gRkxBVFRFTl9OT1RJTkdUT0RPKQ0KLQl7DQotCQlyZXR1cm4gRkxBVFRFTl9OT1RJTkdUT0RPOw0KLQl9ZWxzZSBpZiAoaVJldCA9PSBGTEFUVEVOX0ZBSUwpDQotCXsNCi0JCXJldHVybiBGTEFUVEVOX0ZBSUw7DQotCX0NCi0JDQotCUNQREZfUmVjdCByY09yaWdpbmFsQ0I7DQotCUNQREZfUmVjdCByY01lcmdlciA9IENhbGN1bGF0ZVJlY3QoICZSZWN0QXJyYXkgKTsNCi0JQ1BERl9SZWN0IHJjT3JpZ2luYWxNQiA9IHBQYWdlRGljdC0+R2V0UmVjdCgiTWVkaWFCb3giKTsNCi0NCi0JaWYgKHBQYWdlRGljdC0+S2V5RXhpc3QoIkNyb3BCb3giKSkNCi0JCXJjT3JpZ2luYWxNQiA9IHBQYWdlRGljdC0+R2V0UmVjdCgiQ3JvcEJveCIpOw0KLQkNCi0JaWYgKHJjT3JpZ2luYWxNQi5Jc0VtcHR5KCkpIAkNCi0Jew0KLQkJcmNPcmlnaW5hbE1CID0gQ1BERl9SZWN0KDAuMGYsIDAuMGYsIDYxMi4wZiwgNzkyLjBmKTsNCi0JfQ0KLQkNCi0JcmNNZXJnZXIubGVmdCA9IHJjTWVyZ2VyLmxlZnQgPCByY09yaWdpbmFsTUIubGVmdD8gcmNPcmlnaW5hbE1CLmxlZnQgOiByY01lcmdlci5sZWZ0Ow0KLQlyY01lcmdlci5yaWdodCA9IHJjTWVyZ2VyLnJpZ2h0ID4gcmNPcmlnaW5hbE1CLnJpZ2h0PyByY09yaWdpbmFsTUIucmlnaHQgOiByY01lcmdlci5yaWdodDsNCi0JcmNNZXJnZXIudG9wID0gcmNNZXJnZXIudG9wID4gcmNPcmlnaW5hbE1CLnRvcD8gcmNPcmlnaW5hbE1CLnRvcCA6IHJjTWVyZ2VyLnRvcDsNCi0JcmNNZXJnZXIuYm90dG9tID0gcmNNZXJnZXIuYm90dG9tIDwgcmNPcmlnaW5hbE1CLmJvdHRvbT8gcmNPcmlnaW5hbE1CLmJvdHRvbSA6IHJjTWVyZ2VyLmJvdHRvbTsNCi0JDQotCWlmIChwUGFnZURpY3QtPktleUV4aXN0KCJBcnRCb3giKSkNCi0JCXJjT3JpZ2luYWxDQiA9IHBQYWdlRGljdC0+R2V0UmVjdCgiQXJ0Qm94Iik7DQotCWVsc2UNCi0JCXJjT3JpZ2luYWxDQiA9IHJjT3JpZ2luYWxNQjsNCi0NCi0JaWYgKCFyY09yaWdpbmFsTUIuSXNFbXB0eSgpKQ0KLQl7DQotCQlDUERGX0FycmF5KiBwTWVkaWFCb3ggPSBGWF9ORVcgQ1BERl9BcnJheSgpOwkNCi0NCi0JCXBNZWRpYUJveC0+QWRkKEZYX05FVyBDUERGX051bWJlcihyY09yaWdpbmFsTUIubGVmdCkpOw0KLQkJcE1lZGlhQm94LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKHJjT3JpZ2luYWxNQi5ib3R0b20pKTsNCi0JCXBNZWRpYUJveC0+QWRkKEZYX05FVyBDUERGX051bWJlcihyY09yaWdpbmFsTUIucmlnaHQpKTsNCi0JCXBNZWRpYUJveC0+QWRkKEZYX05FVyBDUERGX051bWJlcihyY09yaWdpbmFsTUIudG9wKSk7DQotDQotCQlwUGFnZURpY3QtPlNldEF0KCJNZWRpYUJveCIscE1lZGlhQm94KTsNCi0JfQ0KLQkNCi0JaWYgKCFyY09yaWdpbmFsQ0IuSXNFbXB0eSgpKQ0KLQl7DQotCQlDUERGX0FycmF5KiBwQ3JvcEJveCA9IEZYX05FVyBDUERGX0FycmF5KCk7DQotCQlwQ3JvcEJveC0+QWRkKEZYX05FVyBDUERGX051bWJlcihyY09yaWdpbmFsQ0IubGVmdCkpOw0KLQkJcENyb3BCb3gtPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIocmNPcmlnaW5hbENCLmJvdHRvbSkpOw0KLQkJcENyb3BCb3gtPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIocmNPcmlnaW5hbENCLnJpZ2h0KSk7DQotCQlwQ3JvcEJveC0+QWRkKEZYX05FVyBDUERGX051bWJlcihyY09yaWdpbmFsQ0IudG9wKSk7DQotCQlwUGFnZURpY3QtPlNldEF0KCJBcnRCb3giLCBwQ3JvcEJveCk7DQotCX0NCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwUmVzID0gTlVMTDsNCi0JcFJlcyA9IHBQYWdlRGljdC0+R2V0RGljdCgiUmVzb3VyY2VzIik7DQotCWlmICghcFJlcykNCi0Jew0KLQkJcFJlcyA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7DQotCQlwUGFnZURpY3QtPlNldEF0KCAiUmVzb3VyY2VzIiwgcFJlcyApOw0KLQl9DQotDQotCUNQREZfU3RyZWFtKiBwTmV3WE9iamVjdCA9IEZYX05FVyBDUERGX1N0cmVhbShOVUxMLCAwLCBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5KTsNCi0JRlhfRFdPUkQgZHdPYmpOdW0gPSBwRG9jdW1lbnQtPkFkZEluZGlyZWN0T2JqZWN0KHBOZXdYT2JqZWN0KTsNCi0JQ1BERl9EaWN0aW9uYXJ5KiBwUGFnZVhPYmplY3QgPSBwUmVzLT5HZXREaWN0KCJYT2JqZWN0Iik7DQotCWlmICghcFBhZ2VYT2JqZWN0KQ0KLQl7DQotCQlwUGFnZVhPYmplY3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5Ow0KLQkJcFJlcy0+U2V0QXQoIlhPYmplY3QiLCBwUGFnZVhPYmplY3QpOw0KLQl9DQotDQotCUNGWF9CeXRlU3RyaW5nIGtleSA9ICIiOw0KLQlpbnQgblN0cmVhbXMgPSBPYmplY3RBcnJheS5HZXRTaXplKCk7DQotDQotCWlmIChuU3RyZWFtcyA+IDApDQotCXsNCi0JCWZvciAoaW50IGlLZXkgPSAwOyAvKmlLZXkgPCAxMDAqLzsgaUtleSsrKQ0KLQkJew0KLQkJCWNoYXIgc0V4dGVuZFs1XSA9IHswfTsNCi0JCQlGWFNZU19pdG9hKGlLZXksIHNFeHRlbmQsIDEwKTsNCi0JCQlrZXkgPSBDRlhfQnl0ZVN0cmluZygiRkZUIikgKyBDRlhfQnl0ZVN0cmluZyhzRXh0ZW5kKTsNCi0NCi0JCQlpZiAoIXBQYWdlWE9iamVjdC0+S2V5RXhpc3Qoa2V5KSkNCi0JCQkJYnJlYWs7DQotCQl9DQotCX0NCi0NCi0JU2V0UGFnZUNvbnRlbnRzKGtleSwgcFBhZ2VEaWN0LCBwRG9jdW1lbnQpOw0KLQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBOZXdYT1JlcyA9IE5VTEw7DQotDQotCWlmICgha2V5LklzRW1wdHkoKSkNCi0Jew0KLQkJcFBhZ2VYT2JqZWN0LT5TZXRBdFJlZmVyZW5jZShrZXksIHBEb2N1bWVudCwgZHdPYmpOdW0pOw0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwTmV3T1hiamVjdERpYyA9IHBOZXdYT2JqZWN0LT5HZXREaWN0KCk7DQotCQlwTmV3WE9SZXMgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5Ow0KLQkJcE5ld09YYmplY3REaWMtPlNldEF0KCJSZXNvdXJjZXMiLCBwTmV3WE9SZXMpOw0KLQkJcE5ld09YYmplY3REaWMtPlNldEF0TmFtZSgiVHlwZSIsICJYT2JqZWN0Iik7DQotCQlwTmV3T1hiamVjdERpYy0+U2V0QXROYW1lKCJTdWJ0eXBlIiwgIkZvcm0iKTsNCi0JCXBOZXdPWGJqZWN0RGljLT5TZXRBdEludGVnZXIoIkZvcm1UeXBlIiwgMSk7DQotCQlwTmV3T1hiamVjdERpYy0+U2V0QXROYW1lKCJOYW1lIiwgIkZSTSIpOw0KLQkJQ1BERl9SZWN0IHJjQkJveCA9IHBQYWdlRGljdC0+R2V0UmVjdCgiQXJ0Qm94Iik7IA0KLQkJcE5ld09YYmplY3REaWMtPlNldEF0UmVjdCgiQkJveCIsIHJjQkJveCk7DQotCX0NCi0JDQotCWZvciAoaW50IGkgPSAwOyBpIDwgblN0cmVhbXM7IGkrKykNCi0Jew0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWMgPSBPYmplY3RBcnJheS5HZXRBdChpKTsNCi0JCWlmICghcEFubm90RGljKWNvbnRpbnVlOw0KLQ0KLQkJQ1BERl9SZWN0IHJjQW5ub3QgPSBwQW5ub3REaWMtPkdldFJlY3QoIlJlY3QiKTsNCi0JCXJjQW5ub3QuTm9ybWFsaXplKCk7DQotDQotCQlDRlhfQnl0ZVN0cmluZyBzQW5ub3RTdGF0ZSA9IHBBbm5vdERpYy0+R2V0U3RyaW5nKCJBUyIpOw0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3RBUCA9IHBBbm5vdERpYy0+R2V0RGljdCgiQVAiKTsNCi0JCWlmICghcEFubm90QVApY29udGludWU7DQotDQotCQlDUERGX1N0cmVhbSogcEFQU3RyZWFtID0gcEFubm90QVAtPkdldFN0cmVhbSgiTiIpOw0KLQkJaWYgKCFwQVBTdHJlYW0pDQotCQl7DQotCQkJQ1BERl9EaWN0aW9uYXJ5KiBwQVBEaWMgPSBwQW5ub3RBUC0+R2V0RGljdCgiTiIpOw0KLQkJCWlmICghcEFQRGljKWNvbnRpbnVlOw0KLQ0KLQkJCWlmICghc0Fubm90U3RhdGUuSXNFbXB0eSgpKQ0KLQkJCXsNCi0JCQkJcEFQU3RyZWFtID0gcEFQRGljLT5HZXRTdHJlYW0oc0Fubm90U3RhdGUpOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlGWF9QT1NJVElPTiBwb3MgPSBwQVBEaWMtPkdldFN0YXJ0UG9zKCk7DQotCQkJCWlmIChwb3MpDQotCQkJCXsNCi0JCQkJCUNGWF9CeXRlU3RyaW5nIHNLZXk7DQotCQkJCQlDUERGX09iamVjdCogcEZpcnN0T2JqID0gcEFQRGljLT5HZXROZXh0RWxlbWVudChwb3MsIHNLZXkpOw0KLQkJCQkJaWYgKHBGaXJzdE9iaikNCi0JCQkJCXsNCi0JCQkJCQlpZiAocEZpcnN0T2JqLT5HZXRUeXBlKCkgPT0gUERGT0JKX1JFRkVSRU5DRSkNCi0JCQkJCQkJcEZpcnN0T2JqID0gcEZpcnN0T2JqLT5HZXREaXJlY3QoKTsNCi0JCQkJCQkNCi0JCQkJCQlpZiAocEZpcnN0T2JqLT5HZXRUeXBlKCkgIT0gUERGT0JKX1NUUkVBTSkNCi0JCQkJCQkJY29udGludWU7DQotDQotCQkJCQkJcEFQU3RyZWFtID0gKENQREZfU3RyZWFtKilwRmlyc3RPYmo7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9DQotDQotCQlpZiAoIXBBUFN0cmVhbSljb250aW51ZTsNCi0NCi0JCUNQREZfRGljdGlvbmFyeSogcEFQRGljID0gcEFQU3RyZWFtLT5HZXREaWN0KCk7DQotCQlDRlhfQWZmaW5lTWF0cml4IG1hdHJpeCA9IHBBUERpYy0+R2V0TWF0cml4KCJNYXRyaXgiKTsNCi0NCi0JCUNQREZfUmVjdCByY1N0cmVhbTsNCi0JCWlmIChwQVBEaWMtPktleUV4aXN0KCJSZWN0IikpDQotCQkJcmNTdHJlYW0gPSBwQVBEaWMtPkdldFJlY3QoIlJlY3QiKTsNCi0JCWVsc2UgaWYgKHBBUERpYy0+S2V5RXhpc3QoIkJCb3giKSkNCi0JCQlyY1N0cmVhbSA9IHBBUERpYy0+R2V0UmVjdCgiQkJveCIpOw0KLQ0KLQkJaWYgKHJjU3RyZWFtLklzRW1wdHkoKSljb250aW51ZTsNCi0NCi0JCUNQREZfT2JqZWN0KiBwT2JqID0gcEFQU3RyZWFtOw0KLQ0KLQkJaWYgKHBPYmopDQotCQl7CQkNCi0JCQlDUERGX0RpY3Rpb25hcnkqIHBPYmpEaWMgPSBwT2JqLT5HZXREaWN0KCk7DQotCQkJaWYgKHBPYmpEaWMpDQotCQkJew0KLQkJCQlwT2JqRGljLT5TZXRBdE5hbWUoIlR5cGUiLCAiWE9iamVjdCIpOw0KLQkJCQlwT2JqRGljLT5TZXRBdE5hbWUoIlN1YnR5cGUiLCAiRm9ybSIpOw0KLQkJCX0NCi0JCX0NCi0NCi0JCUNQREZfRGljdGlvbmFyeSogcFhPYmplY3QgPSBwTmV3WE9SZXMtPkdldERpY3QoIlhPYmplY3QiKTsNCi0JCWlmICghcFhPYmplY3QpDQotCQl7DQotCQkJcFhPYmplY3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5Ow0KLQkJCXBOZXdYT1Jlcy0+U2V0QXQoIlhPYmplY3QiLCBwWE9iamVjdCk7DQotCQl9DQotDQotCQlDRlhfQnl0ZVN0cmluZyBzRm9ybU5hbWU7DQotCQlzRm9ybU5hbWUuRm9ybWF0KCJGJWQiLCBpKTsNCi0JCUZYX0RXT1JEIGR3T2JqTnVtID0gcERvY3VtZW50LT5BZGRJbmRpcmVjdE9iamVjdChwT2JqKTsNCi0JCXBYT2JqZWN0LT5TZXRBdFJlZmVyZW5jZShzRm9ybU5hbWUsIHBEb2N1bWVudCwgZHdPYmpOdW0pOw0KLQ0KLQkJQ1BERl9TdHJlYW1BY2MgYWNjOw0KLQkJYWNjLkxvYWRBbGxEYXRhKHBOZXdYT2JqZWN0KTsNCi0NCi0JCUZYX0xQQ0JZVEUgcERhdGEgPSBhY2MuR2V0RGF0YSgpOw0KLQkJQ0ZYX0J5dGVTdHJpbmcgc1N0cmVhbShwRGF0YSwgYWNjLkdldFNpemUoKSk7DQotCQlDRlhfQnl0ZVN0cmluZyBzVGVtcDsNCi0NCi0JCWlmIChtYXRyaXguSXNJZGVudGl0eSgpKQ0KLQkJew0KLQkJCW1hdHJpeC5hID0gMS4wZjsNCi0JCQltYXRyaXguYiA9IDAuMGY7DQotCQkJbWF0cml4LmMgPSAwLjBmOw0KLQkJCW1hdHJpeC5kID0gMS4wZjsNCi0JCQltYXRyaXguZSA9IDAuMGY7DQotCQkJbWF0cml4LmYgPSAwLjBmOw0KLQkJfQ0KLQ0KLQkJQ0ZYX0FmZmluZU1hdHJpeCBtID0gR2V0TWF0cml4KHJjQW5ub3QsIHJjU3RyZWFtLCBtYXRyaXgpOw0KLQkJc1RlbXAuRm9ybWF0KCJxICVmIDAgMCAlZiAlZiAlZiBjbSAvJXMgRG8gUVxuIiwgbS5hLCBtLmQsIG0uZSwgbS5mLCAoRlhfTFBDU1RSKXNGb3JtTmFtZSk7DQotCQlzU3RyZWFtICs9IHNUZW1wOw0KLQ0KLQkJcE5ld1hPYmplY3QtPlNldERhdGEoKEZYX0xQQ0JZVEUpc1N0cmVhbSwgc1N0cmVhbS5HZXRMZW5ndGgoKSwgRkFMU0UsIEZBTFNFKTsNCi0JfQ0KLQlwUGFnZURpY3QtPlJlbW92ZUF0KCAiQW5ub3RzIiApOw0KLQ0KLQlPYmplY3RBcnJheS5SZW1vdmVBbGwoKTsNCi0JUmVjdEFycmF5LlJlbW92ZUFsbCgpOw0KLQ0KLQlyZXR1cm4gRkxBVFRFTl9TVUNDRVNTOw0KLX0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZl9mbGF0dGVuLmgiCisKK3R5cGVkZWYgQ0ZYX0FycmF5VGVtcGxhdGU8Q1BERl9EaWN0aW9uYXJ5Kj4gQ1BERl9PYmplY3RBcnJheTsKK3R5cGVkZWYgQ0ZYX0FycmF5VGVtcGxhdGU8Q1BERl9SZWN0PiBDUERGX1JlY3RBcnJheTsKKworZW51bSBGUERGX1RZUEUgeyBNQVgsIE1JTiB9OworZW51bSBGUERGX1ZBTFVFIHsgVE9QLCBMRUZULCBSSUdIVCwgQk9UVE9NIH07CisKK0ZYX0JPT0wgSXNWYWxpYWJsZVJlY3QoQ1BERl9SZWN0IHJlY3QsIENQREZfUmVjdCByY1BhZ2UpCit7CisJaWYgKCByZWN0LmxlZnQgLSByZWN0LnJpZ2h0ID4gMC4wMDAwMDFmIHx8IAorCQkgcmVjdC5ib3R0b20gLSByZWN0LnRvcCA+IDAuMDAwMDAxZikKKwkJcmV0dXJuIEZBTFNFOworCQorCWlmIChyZWN0LmxlZnQgPT0gMC4wZiAmJgorCQlyZWN0LnRvcCA9PSAwLjBmICYmCisJCXJlY3QucmlnaHQgPT0gMC4wZiAmJgorCQlyZWN0LmJvdHRvbSA9PSAwLjBmKQorCQlyZXR1cm4gRkFMU0U7CisJCisJaWYgKCFyY1BhZ2UuSXNFbXB0eSgpKQorCXsKKwkJaWYgKHJlY3QubGVmdCAtIHJjUGFnZS5sZWZ0IDwgLTEwLjAwMDAwMWYgfHwKKwkJCXJlY3QucmlnaHQgLSByY1BhZ2UucmlnaHQgPiAxMC4wMDAwMDFmIHx8CisJCQlyZWN0LnRvcCAtIHJjUGFnZS50b3AgPiAxMC4wMDAwMDFmIHx8CisJCQlyZWN0LmJvdHRvbSAtIHJjUGFnZS5ib3R0b20gPCAtMTAuMDAwMDAxZikKKwkJCXJldHVybiBGQUxTRTsKKwl9CisJCisJcmV0dXJuIFRSVUU7Cit9CisKKworRlhfQk9PTCBHZXRDb250ZW50c1JlY3QoIENQREZfRG9jdW1lbnQgKiBwRG9jLCBDUERGX0RpY3Rpb25hcnkqIHBEaWN0LCBDUERGX1JlY3RBcnJheSAqIHBSZWN0QXJyYXkgKQoreworCUNQREZfUGFnZSogcFBERlBhZ2UgPSBGWF9ORVcgQ1BERl9QYWdlOworCXBQREZQYWdlLT5Mb2FkKCBwRG9jLCBwRGljdCwgRkFMU0UgKTsKKwlwUERGUGFnZS0+UGFyc2VDb250ZW50KCk7CisKKwlGWF9QT1NJVElPTiBwb3MgPSBwUERGUGFnZS0+R2V0Rmlyc3RPYmplY3RQb3NpdGlvbigpOworCQorCXdoaWxlIChwb3MpCisJeworCQlDUERGX1BhZ2VPYmplY3QqIHBQYWdlT2JqZWN0ID0gcFBERlBhZ2UtPkdldE5leHRPYmplY3QocG9zKTsKKwkJaWYgKCFwUGFnZU9iamVjdCljb250aW51ZTsKKwkJCisJCUNQREZfUmVjdCByYzsKKwkJcmMubGVmdCA9IHBQYWdlT2JqZWN0LT5tX0xlZnQ7CisJCXJjLnJpZ2h0ID0gcFBhZ2VPYmplY3QtPm1fUmlnaHQ7CisJCXJjLmJvdHRvbSA9IHBQYWdlT2JqZWN0LT5tX0JvdHRvbTsKKwkJcmMudG9wID0gcFBhZ2VPYmplY3QtPm1fVG9wOworCQkKKwkJaWYgKElzVmFsaWFibGVSZWN0KHJjLCBwRGljdC0+R2V0UmVjdCgiTWVkaWFCb3giKSkpCisJCXsKKwkJCXBSZWN0QXJyYXktPkFkZChyYyk7CisJCX0KKwl9CisJCisJZGVsZXRlIHBQREZQYWdlOworCXJldHVybiBUUlVFOworfQorCisKK3ZvaWQgUGFyc2VyU3RyZWFtKCBDUERGX0RpY3Rpb25hcnkgKiBwUGFnZURpYywgQ1BERl9EaWN0aW9uYXJ5KiBwU3RyZWFtLCBDUERGX1JlY3RBcnJheSAqIHBSZWN0QXJyYXksIENQREZfT2JqZWN0QXJyYXkgKiBwT2JqZWN0QXJyYXkgKQoreworCWlmICghcFN0cmVhbSlyZXR1cm47CisJQ1BERl9SZWN0IHJlY3Q7CisJaWYgKHBTdHJlYW0tPktleUV4aXN0KCJSZWN0IikpCisJCXJlY3QgPSBwU3RyZWFtLT5HZXRSZWN0KCJSZWN0Iik7CisJZWxzZSBpZiAocFN0cmVhbS0+S2V5RXhpc3QoIkJCb3giKSkKKwkJcmVjdCA9IHBTdHJlYW0tPkdldFJlY3QoIkJCb3giKTsKKwkKKwlpZiAoSXNWYWxpYWJsZVJlY3QocmVjdCwgcFBhZ2VEaWMtPkdldFJlY3QoIk1lZGlhQm94IikpKQorCQlwUmVjdEFycmF5LT5BZGQocmVjdCk7CisJCisJcE9iamVjdEFycmF5LT5BZGQocFN0cmVhbSk7Cit9CisKKworaW50IFBhcnNlckFubm90cyggQ1BERl9Eb2N1bWVudCogcFNvdXJjZURvYywgQ1BERl9EaWN0aW9uYXJ5ICogcFBhZ2VEaWMsIENQREZfUmVjdEFycmF5ICogcFJlY3RBcnJheSwgQ1BERl9PYmplY3RBcnJheSAqIHBPYmplY3RBcnJheSwgaW50IG5Vc2FnZSkKK3sKKwlpZiAoIXBTb3VyY2VEb2MgfHwgIXBQYWdlRGljKSByZXR1cm4gRkxBVFRFTl9GQUlMOworCQorCUdldENvbnRlbnRzUmVjdCggcFNvdXJjZURvYywgcFBhZ2VEaWMsIHBSZWN0QXJyYXkgKTsKKwlDUERGX0FycmF5KiBwQW5ub3RzID0gcFBhZ2VEaWMtPkdldEFycmF5KCJBbm5vdHMiKTsKKwlpZiAocEFubm90cykKKwl7CisJCUZYX0RXT1JEIGR3U2l6ZSA9IHBBbm5vdHMtPkdldENvdW50KCk7CisJCQorCQlmb3IgKGludCBpID0gMDsgaSA8IChpbnQpZHdTaXplOyBpKyspCisJCXsKKwkJCUNQREZfT2JqZWN0KiBwT2JqID0gcEFubm90cy0+R2V0RWxlbWVudFZhbHVlKGkpOworCQkJCisJCQlpZiAoIXBPYmopY29udGludWU7CisJCQkKKwkJCWlmIChwT2JqLT5HZXRUeXBlKCkgPT0gUERGT0JKX0RJQ1RJT05BUlkpCisJCQl7CisJCQkJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWMgPSAoQ1BERl9EaWN0aW9uYXJ5KilwT2JqOworCQkJCUNGWF9CeXRlU3RyaW5nIHNTdWJ0eXBlID0gcEFubm90RGljLT5HZXRTdHJpbmcoIlN1YnR5cGUiKTsKKwkJCQlpZiAoc1N1YnR5cGUgPT0gIlBvcHVwIiljb250aW51ZTsKKworCQkJCWludCBuQW5ub3RGbGFnID0gcEFubm90RGljLT5HZXRJbnRlZ2VyKCJGIik7CisKKwkJCQlpZihuQW5ub3RGbGFnICYgQU5OT1RGTEFHX0hJRERFTikgCisJCQkJCWNvbnRpbnVlOworCQkJCWlmKG5Vc2FnZSA9PSBGTEFUX05PUk1BTERJU1BMQVkpCisJCQkJeworCQkJCQlpZihuQW5ub3RGbGFnICYgQU5OT1RGTEFHX0lOVklTSUJMRSkKKwkJCQkJCWNvbnRpbnVlOworCQkJCQlQYXJzZXJTdHJlYW0oIHBQYWdlRGljLCBwQW5ub3REaWMsIHBSZWN0QXJyYXksIHBPYmplY3RBcnJheSApOwkJCisJCQkJfQorCQkJCWVsc2UKKwkJCQl7CisJCQkJCWlmKG5Bbm5vdEZsYWcgJiBBTk5PVEZMQUdfUFJJTlQpCisJCQkJCQlQYXJzZXJTdHJlYW0oIHBQYWdlRGljLCBwQW5ub3REaWMsIHBSZWN0QXJyYXksIHBPYmplY3RBcnJheSApOworCQkJCX0JCQkKKwkJCX0KKwkJfQorCQlyZXR1cm4gRkxBVFRFTl9TVUNDRVNTOworCX1lbHNleworCQlyZXR1cm4gRkxBVFRFTl9OT1RJTkdUT0RPOworCX0KK30KKworCitGWF9GTE9BVCBHZXRNaW5NYXhWYWx1ZSggQ1BERl9SZWN0QXJyYXkmIGFycmF5LCBGUERGX1RZUEUgdHlwZSwgRlBERl9WQUxVRSB2YWx1ZSkKK3sKKwlpbnQgblJlY3RzID0gYXJyYXkuR2V0U2l6ZSgpOworCUZYX0ZMT0FUIGZSZXQgPSAwLjBmOworCQorCWlmIChuUmVjdHMgPD0gMClyZXR1cm4gMC4wZjsKKwkKKwlGWF9GTE9BVCogcEFycmF5ID0gbmV3IEZYX0ZMT0FUW25SZWN0c107CisJc3dpdGNoKHZhbHVlKQorCXsKKwljYXNlIExFRlQ6CisJCXsKKwkJCWZvciAoaW50IGkgPSAwOyBpIDwgblJlY3RzOyBpKyspCisJCQkJcEFycmF5W2ldID0gQ1BERl9SZWN0KGFycmF5LkdldEF0KGkpKS5sZWZ0OworCQkJCisJCQlicmVhazsKKwkJfQorCWNhc2UgVE9QOgorCQl7CisJCQlmb3IgKGludCBpID0gMDsgaSA8IG5SZWN0czsgaSsrKQorCQkJCXBBcnJheVtpXSA9IENQREZfUmVjdChhcnJheS5HZXRBdChpKSkudG9wOworCQkJCisJCQlicmVhazsKKwkJfQorCWNhc2UgUklHSFQ6CisJCXsKKwkJCWZvciAoaW50IGkgPSAwOyBpIDwgblJlY3RzOyBpKyspCisJCQkJcEFycmF5W2ldID0gQ1BERl9SZWN0KGFycmF5LkdldEF0KGkpKS5yaWdodDsKKwkJCQorCQkJYnJlYWs7CisJCX0KKwljYXNlIEJPVFRPTToKKwkJeworCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBuUmVjdHM7IGkrKykKKwkJCQlwQXJyYXlbaV0gPSBDUERGX1JlY3QoYXJyYXkuR2V0QXQoaSkpLmJvdHRvbTsKKwkJCQorCQkJYnJlYWs7CisJCX0KKwlkZWZhdWx0OgorCQlicmVhazsKKwl9CisJZlJldCA9IHBBcnJheVswXTsKKwlpZiAodHlwZSA9PSBNQVgpCisJeworCQlmb3IgKGludCBpID0gMTsgaSA8IG5SZWN0czsgaSsrKQorCQkJaWYgKGZSZXQgPD0gcEFycmF5W2ldKQorCQkJCWZSZXQgPSBwQXJyYXlbaV07CisJfQorCWVsc2UKKwl7CisJCWZvciAoaW50IGkgPSAxOyBpIDwgblJlY3RzOyBpKyspCisJCQlpZiAoZlJldCA+PSBwQXJyYXlbaV0pCisJCQkJZlJldCA9IHBBcnJheVtpXTsKKwl9CisJZGVsZXRlW10gcEFycmF5OworCXJldHVybiBmUmV0OworfQorCitDUERGX1JlY3QgQ2FsY3VsYXRlUmVjdCggQ1BERl9SZWN0QXJyYXkgKiBwUmVjdEFycmF5ICkKK3sKKworCUNQREZfUmVjdCByY1JldDsKKwkKKwlyY1JldC5sZWZ0ID0gR2V0TWluTWF4VmFsdWUoKnBSZWN0QXJyYXksIE1JTiwgTEVGVCk7CisJcmNSZXQudG9wID0gR2V0TWluTWF4VmFsdWUoKnBSZWN0QXJyYXksIE1BWCwgVE9QKTsKKwlyY1JldC5yaWdodCA9IEdldE1pbk1heFZhbHVlKCpwUmVjdEFycmF5LCBNQVgsIFJJR0hUKTsKKwlyY1JldC5ib3R0b20gPSBHZXRNaW5NYXhWYWx1ZSgqcFJlY3RBcnJheSwgTUlOLCBCT1RUT00pOworCQorCXJldHVybiByY1JldDsKK30KKworCit2b2lkIFNldFBhZ2VDb250ZW50cyhDRlhfQnl0ZVN0cmluZyBrZXksIENQREZfRGljdGlvbmFyeSogcFBhZ2UsIENQREZfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKwlDUERGX09iamVjdCogcENvbnRlbnRzT2JqID0gcFBhZ2UtPkdldFN0cmVhbSgiQ29udGVudHMiKTsKKwlpZiAoIXBDb250ZW50c09iaikKKwl7CisJCXBDb250ZW50c09iaiA9IHBQYWdlLT5HZXRBcnJheSgiQ29udGVudHMiKTsKKwl9CisJCisJaWYgKCFwQ29udGVudHNPYmopCisJeworCQkvL0NyZWF0ZSBhIG5ldyBjb250ZW50cyBkaWN0aW9uYXJ5CisJCWlmICgha2V5LklzRW1wdHkoKSkKKwkJeworCQkJQ1BERl9TdHJlYW0qIHBOZXdDb250ZW50cyA9IEZYX05FVyBDUERGX1N0cmVhbShOVUxMLCAwLCBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5KTsKKwkJCWlmICghcE5ld0NvbnRlbnRzKXJldHVybjsKKwkJCXBQYWdlLT5TZXRBdFJlZmVyZW5jZSgiQ29udGVudHMiLCBwRG9jdW1lbnQsIHBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocE5ld0NvbnRlbnRzKSk7CisJCQkKKwkJCUNGWF9CeXRlU3RyaW5nIHNTdHJlYW07CisJCQlzU3RyZWFtLkZvcm1hdCgicSAxIDAgMCAxIDAgMCBjbSAvJXMgRG8gUSIsIChGWF9MUENTVFIpa2V5KTsKKwkJCXBOZXdDb250ZW50cy0+U2V0RGF0YSgoRlhfTFBDQllURSlzU3RyZWFtLCBzU3RyZWFtLkdldExlbmd0aCgpLCBGQUxTRSwgRkFMU0UpOworCQl9CisJCXJldHVybjsKKwl9CisKKwlpbnQgaVR5cGUgPSBwQ29udGVudHNPYmotPkdldFR5cGUoKTsKKwlDUERGX0FycmF5KiBwQ29udGVudHNBcnJheSA9IE5VTEw7CisJCisJc3dpdGNoKGlUeXBlKQorCXsKKwljYXNlIFBERk9CSl9TVFJFQU06CisJCXsKKwkJCXBDb250ZW50c0FycmF5ID0gRlhfTkVXIENQREZfQXJyYXk7CisJCQlDUERGX1N0cmVhbSogcENvbnRlbnRzID0gKENQREZfU3RyZWFtKilwQ29udGVudHNPYmo7CisJCQlGWF9EV09SRCBkd09iak51bSA9IHBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocENvbnRlbnRzKTsKKwkJCUNQREZfU3RyZWFtQWNjIGFjYzsKKwkJCWFjYy5Mb2FkQWxsRGF0YShwQ29udGVudHMpOworCQkJQ0ZYX0J5dGVTdHJpbmcgc1N0cmVhbSA9ICJxXG4iOworCQkJQ0ZYX0J5dGVTdHJpbmcgc0JvZHkgPSBDRlhfQnl0ZVN0cmluZygoRlhfTFBDU1RSKWFjYy5HZXREYXRhKCksIGFjYy5HZXRTaXplKCkpOworCQkJc1N0cmVhbSA9IHNTdHJlYW0gKyBzQm9keSArICJcblEiOworCQkJcENvbnRlbnRzLT5TZXREYXRhKChGWF9MUENCWVRFKXNTdHJlYW0sIHNTdHJlYW0uR2V0TGVuZ3RoKCksIEZBTFNFLCBGQUxTRSk7CisJCQlwQ29udGVudHNBcnJheS0+QWRkUmVmZXJlbmNlKHBEb2N1bWVudCwgZHdPYmpOdW0pOworCQkJYnJlYWs7CisJCX0KKwkJCisJY2FzZSBQREZPQkpfQVJSQVk6CisJCXsKKwkJCXBDb250ZW50c0FycmF5ID0gKENQREZfQXJyYXkqKXBDb250ZW50c09iajsKKwkJCWJyZWFrOworCQl9CisJZGVmYXVsdDoKKwkJYnJlYWs7CisJfQkKKwkKKwlpZiAoIXBDb250ZW50c0FycmF5KXJldHVybjsKKwkKKwlGWF9EV09SRCBkd09iak51bSA9IHBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocENvbnRlbnRzQXJyYXkpOworCXBQYWdlLT5TZXRBdFJlZmVyZW5jZSgiQ29udGVudHMiLCBwRG9jdW1lbnQsIGR3T2JqTnVtKTsKKwkKKwlpZiAoIWtleS5Jc0VtcHR5KCkpCisJeworCQlDUERGX1N0cmVhbSogcE5ld0NvbnRlbnRzID0gRlhfTkVXIENQREZfU3RyZWFtKE5VTEwsIDAsIEZYX05FVyBDUERGX0RpY3Rpb25hcnkpOworCQlkd09iak51bSA9IHBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocE5ld0NvbnRlbnRzKTsKKwkJcENvbnRlbnRzQXJyYXktPkFkZFJlZmVyZW5jZShwRG9jdW1lbnQsIGR3T2JqTnVtKTsKKwkJCisJCUNGWF9CeXRlU3RyaW5nIHNTdHJlYW07CisJCXNTdHJlYW0uRm9ybWF0KCJxIDEgMCAwIDEgMCAwIGNtIC8lcyBEbyBRIiwgKEZYX0xQQ1NUUilrZXkpOworCQlwTmV3Q29udGVudHMtPlNldERhdGEoKEZYX0xQQ0JZVEUpc1N0cmVhbSwgc1N0cmVhbS5HZXRMZW5ndGgoKSwgRkFMU0UsIEZBTFNFKTsKKwl9Cit9CisgCitDRlhfQWZmaW5lTWF0cml4IEdldE1hdHJpeChDUERGX1JlY3QgcmNBbm5vdCwgQ1BERl9SZWN0IHJjU3RyZWFtLCBDRlhfQWZmaW5lTWF0cml4IG1hdHJpeCkKK3sKKwlpZihyY1N0cmVhbS5Jc0VtcHR5KCkpCisJCXJldHVybiBDRlhfQWZmaW5lTWF0cml4KCk7CisJCisJbWF0cml4LlRyYW5zZm9ybVJlY3QocmNTdHJlYW0pOworCXJjU3RyZWFtLk5vcm1hbGl6ZSgpOworCQorCUZYX0ZMT0FUIGEgPSByY0Fubm90LldpZHRoKCkvcmNTdHJlYW0uV2lkdGgoKTsKKwlGWF9GTE9BVCBkID0gcmNBbm5vdC5IZWlnaHQoKS9yY1N0cmVhbS5IZWlnaHQoKTsKKwkKKwlGWF9GTE9BVCBlID0gcmNBbm5vdC5sZWZ0IC0gcmNTdHJlYW0ubGVmdCAqIGE7CisJRlhfRkxPQVQgZiA9IHJjQW5ub3QuYm90dG9tIC0gcmNTdHJlYW0uYm90dG9tICogZDsKKwlyZXR1cm4gQ0ZYX0FmZmluZU1hdHJpeChhLCAwLCAwLCBkLCBlLCBmKTsKK30KKwordm9pZCBHZXRPZmZzZXQoRlhfRkxPQVQmIGZhLCBGWF9GTE9BVCYgZmQsIEZYX0ZMT0FUJiBmZSwgRlhfRkxPQVQmIGZmLCBDUERGX1JlY3QgcmNBbm5vdCwgQ1BERl9SZWN0IHJjU3RyZWFtLCBDRlhfQWZmaW5lTWF0cml4IG1hdHJpeCkKK3sKKwlGWF9GTE9BVCBmU3RyZWFtV2lkdGggPSAwLjBmOworCUZYX0ZMT0FUIGZTdHJlYW1IZWlnaHQgPSAwLjBmOworCisKKwkKKwlpZiAobWF0cml4LmEgIT0gMCAmJiBtYXRyaXguZCAhPSAwKQorCXsKKwkJZlN0cmVhbVdpZHRoID0gcmNTdHJlYW0ucmlnaHQgLSByY1N0cmVhbS5sZWZ0OworCQlmU3RyZWFtSGVpZ2h0ID0gcmNTdHJlYW0udG9wIC0gcmNTdHJlYW0uYm90dG9tOworCX0KKwllbHNlCisJeworCQlmU3RyZWFtV2lkdGggPSByY1N0cmVhbS50b3AgLSByY1N0cmVhbS5ib3R0b207CisJCWZTdHJlYW1IZWlnaHQgPSByY1N0cmVhbS5yaWdodCAtIHJjU3RyZWFtLmxlZnQ7CisJfQorCQorCUZYX0ZMT0FUIHgxID0gbWF0cml4LmEgKiByY1N0cmVhbS5sZWZ0ICsgbWF0cml4LmMgKiByY1N0cmVhbS5ib3R0b20gKyBtYXRyaXguZTsKKwlGWF9GTE9BVCB5MSA9IG1hdHJpeC5iICogcmNTdHJlYW0ubGVmdCArIG1hdHJpeC5kICogcmNTdHJlYW0uYm90dG9tICsgbWF0cml4LmY7CisJRlhfRkxPQVQgeDIgPSBtYXRyaXguYSAqIHJjU3RyZWFtLmxlZnQgKyBtYXRyaXguYyAqIHJjU3RyZWFtLnRvcCArIG1hdHJpeC5lOworCUZYX0ZMT0FUIHkyID0gbWF0cml4LmIgKiByY1N0cmVhbS5sZWZ0ICsgbWF0cml4LmQgKiByY1N0cmVhbS50b3AgKyBtYXRyaXguZjsKKwlGWF9GTE9BVCB4MyA9IG1hdHJpeC5hICogcmNTdHJlYW0ucmlnaHQgKyBtYXRyaXguYyAqIHJjU3RyZWFtLmJvdHRvbSArIG1hdHJpeC5lOworCUZYX0ZMT0FUIHkzID0gbWF0cml4LmIgKiByY1N0cmVhbS5yaWdodCArIG1hdHJpeC5kICogcmNTdHJlYW0uYm90dG9tICsgbWF0cml4LmY7CisJRlhfRkxPQVQgeDQgPSBtYXRyaXguYSAqIHJjU3RyZWFtLnJpZ2h0ICsgbWF0cml4LmMgKiByY1N0cmVhbS50b3AgKyBtYXRyaXguZTsKKwlGWF9GTE9BVCB5NCA9IG1hdHJpeC5iICogcmNTdHJlYW0ucmlnaHQgKyBtYXRyaXguZCAqIHJjU3RyZWFtLnRvcCArIG1hdHJpeC5mOworCQorCUZYX0ZMT0FUIGxlZnQgPSBGWF9NSU4oRlhfTUlOKHgxLCB4MiksIEZYX01JTih4MywgeDQpKTsKKwlGWF9GTE9BVCBib3R0b20gPSBGWF9NSU4oRlhfTUlOKHkxLCB5MiksIEZYX01JTih5MywgeTQpKTsKKwkKKwlmYSA9IChyY0Fubm90LnJpZ2h0IC0gcmNBbm5vdC5sZWZ0KS9mU3RyZWFtV2lkdGg7CisJZmQgPSAocmNBbm5vdC50b3AgLSByY0Fubm90LmJvdHRvbSkvZlN0cmVhbUhlaWdodDsKKwlmZSA9IHJjQW5ub3QubGVmdCAtIGxlZnQgKiBmYTsKKwlmZiA9IHJjQW5ub3QuYm90dG9tIC0gYm90dG9tICogZmQ7Cit9CisKKworRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZQYWdlX0ZsYXR0ZW4oIEZQREZfUEFHRSBwYWdlLCBpbnQgbkZsYWcpCit7CisJaWYgKCFwYWdlKQorCXsKKwkJcmV0dXJuIEZMQVRURU5fRkFJTDsKKwl9CisKKwlDUERGX1BhZ2UgKiBwUGFnZSA9IChDUERGX1BhZ2UqKSggcGFnZSApOworCUNQREZfRG9jdW1lbnQgKiBwRG9jdW1lbnQgPSBwUGFnZS0+bV9wRG9jdW1lbnQ7CisJQ1BERl9EaWN0aW9uYXJ5ICogcFBhZ2VEaWN0ID0gcFBhZ2UtPm1fcEZvcm1EaWN0OworCQorCWlmICggIXBEb2N1bWVudCB8fCAhcFBhZ2VEaWN0ICkKKwl7CisJCXJldHVybiBGTEFUVEVOX0ZBSUw7CisJfQorCisJQ1BERl9PYmplY3RBcnJheSBPYmplY3RBcnJheTsKKwlDUERGX1JlY3RBcnJheSAgUmVjdEFycmF5OworCisJaW50IGlSZXQgPSBGTEFUVEVOX0ZBSUw7CisJaVJldCA9IFBhcnNlckFubm90cyggcERvY3VtZW50LCBwUGFnZURpY3QsICZSZWN0QXJyYXksICZPYmplY3RBcnJheSwgbkZsYWcpOworCWlmIChpUmV0ID09IEZMQVRURU5fTk9USU5HVE9ETykKKwl7CisJCXJldHVybiBGTEFUVEVOX05PVElOR1RPRE87CisJfWVsc2UgaWYgKGlSZXQgPT0gRkxBVFRFTl9GQUlMKQorCXsKKwkJcmV0dXJuIEZMQVRURU5fRkFJTDsKKwl9CisJCisJQ1BERl9SZWN0IHJjT3JpZ2luYWxDQjsKKwlDUERGX1JlY3QgcmNNZXJnZXIgPSBDYWxjdWxhdGVSZWN0KCAmUmVjdEFycmF5ICk7CisJQ1BERl9SZWN0IHJjT3JpZ2luYWxNQiA9IHBQYWdlRGljdC0+R2V0UmVjdCgiTWVkaWFCb3giKTsKKworCWlmIChwUGFnZURpY3QtPktleUV4aXN0KCJDcm9wQm94IikpCisJCXJjT3JpZ2luYWxNQiA9IHBQYWdlRGljdC0+R2V0UmVjdCgiQ3JvcEJveCIpOworCQorCWlmIChyY09yaWdpbmFsTUIuSXNFbXB0eSgpKSAJCisJeworCQlyY09yaWdpbmFsTUIgPSBDUERGX1JlY3QoMC4wZiwgMC4wZiwgNjEyLjBmLCA3OTIuMGYpOworCX0KKwkKKwlyY01lcmdlci5sZWZ0ID0gcmNNZXJnZXIubGVmdCA8IHJjT3JpZ2luYWxNQi5sZWZ0PyByY09yaWdpbmFsTUIubGVmdCA6IHJjTWVyZ2VyLmxlZnQ7CisJcmNNZXJnZXIucmlnaHQgPSByY01lcmdlci5yaWdodCA+IHJjT3JpZ2luYWxNQi5yaWdodD8gcmNPcmlnaW5hbE1CLnJpZ2h0IDogcmNNZXJnZXIucmlnaHQ7CisJcmNNZXJnZXIudG9wID0gcmNNZXJnZXIudG9wID4gcmNPcmlnaW5hbE1CLnRvcD8gcmNPcmlnaW5hbE1CLnRvcCA6IHJjTWVyZ2VyLnRvcDsKKwlyY01lcmdlci5ib3R0b20gPSByY01lcmdlci5ib3R0b20gPCByY09yaWdpbmFsTUIuYm90dG9tPyByY09yaWdpbmFsTUIuYm90dG9tIDogcmNNZXJnZXIuYm90dG9tOworCQorCWlmIChwUGFnZURpY3QtPktleUV4aXN0KCJBcnRCb3giKSkKKwkJcmNPcmlnaW5hbENCID0gcFBhZ2VEaWN0LT5HZXRSZWN0KCJBcnRCb3giKTsKKwllbHNlCisJCXJjT3JpZ2luYWxDQiA9IHJjT3JpZ2luYWxNQjsKKworCWlmICghcmNPcmlnaW5hbE1CLklzRW1wdHkoKSkKKwl7CisJCUNQREZfQXJyYXkqIHBNZWRpYUJveCA9IEZYX05FVyBDUERGX0FycmF5KCk7CQorCisJCXBNZWRpYUJveC0+QWRkKEZYX05FVyBDUERGX051bWJlcihyY09yaWdpbmFsTUIubGVmdCkpOworCQlwTWVkaWFCb3gtPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIocmNPcmlnaW5hbE1CLmJvdHRvbSkpOworCQlwTWVkaWFCb3gtPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIocmNPcmlnaW5hbE1CLnJpZ2h0KSk7CisJCXBNZWRpYUJveC0+QWRkKEZYX05FVyBDUERGX051bWJlcihyY09yaWdpbmFsTUIudG9wKSk7CisKKwkJcFBhZ2VEaWN0LT5TZXRBdCgiTWVkaWFCb3giLHBNZWRpYUJveCk7CisJfQorCQorCWlmICghcmNPcmlnaW5hbENCLklzRW1wdHkoKSkKKwl7CisJCUNQREZfQXJyYXkqIHBDcm9wQm94ID0gRlhfTkVXIENQREZfQXJyYXkoKTsKKwkJcENyb3BCb3gtPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIocmNPcmlnaW5hbENCLmxlZnQpKTsKKwkJcENyb3BCb3gtPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIocmNPcmlnaW5hbENCLmJvdHRvbSkpOworCQlwQ3JvcEJveC0+QWRkKEZYX05FVyBDUERGX051bWJlcihyY09yaWdpbmFsQ0IucmlnaHQpKTsKKwkJcENyb3BCb3gtPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIocmNPcmlnaW5hbENCLnRvcCkpOworCQlwUGFnZURpY3QtPlNldEF0KCJBcnRCb3giLCBwQ3JvcEJveCk7CisJfQorCisJQ1BERl9EaWN0aW9uYXJ5KiBwUmVzID0gTlVMTDsKKwlwUmVzID0gcFBhZ2VEaWN0LT5HZXREaWN0KCJSZXNvdXJjZXMiKTsKKwlpZiAoIXBSZXMpCisJeworCQlwUmVzID0gRlhfTkVXIENQREZfRGljdGlvbmFyeTsKKwkJcFBhZ2VEaWN0LT5TZXRBdCggIlJlc291cmNlcyIsIHBSZXMgKTsKKwl9CisKKwlDUERGX1N0cmVhbSogcE5ld1hPYmplY3QgPSBGWF9ORVcgQ1BERl9TdHJlYW0oTlVMTCwgMCwgRlhfTkVXIENQREZfRGljdGlvbmFyeSk7CisJRlhfRFdPUkQgZHdPYmpOdW0gPSBwRG9jdW1lbnQtPkFkZEluZGlyZWN0T2JqZWN0KHBOZXdYT2JqZWN0KTsKKwlDUERGX0RpY3Rpb25hcnkqIHBQYWdlWE9iamVjdCA9IHBSZXMtPkdldERpY3QoIlhPYmplY3QiKTsKKwlpZiAoIXBQYWdlWE9iamVjdCkKKwl7CisJCXBQYWdlWE9iamVjdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7CisJCXBSZXMtPlNldEF0KCJYT2JqZWN0IiwgcFBhZ2VYT2JqZWN0KTsKKwl9CisKKwlDRlhfQnl0ZVN0cmluZyBrZXkgPSAiIjsKKwlpbnQgblN0cmVhbXMgPSBPYmplY3RBcnJheS5HZXRTaXplKCk7CisKKwlpZiAoblN0cmVhbXMgPiAwKQorCXsKKwkJZm9yIChpbnQgaUtleSA9IDA7IC8qaUtleSA8IDEwMCovOyBpS2V5KyspCisJCXsKKwkJCWNoYXIgc0V4dGVuZFs1XSA9IHswfTsKKwkJCUZYU1lTX2l0b2EoaUtleSwgc0V4dGVuZCwgMTApOworCQkJa2V5ID0gQ0ZYX0J5dGVTdHJpbmcoIkZGVCIpICsgQ0ZYX0J5dGVTdHJpbmcoc0V4dGVuZCk7CisKKwkJCWlmICghcFBhZ2VYT2JqZWN0LT5LZXlFeGlzdChrZXkpKQorCQkJCWJyZWFrOworCQl9CisJfQorCisJU2V0UGFnZUNvbnRlbnRzKGtleSwgcFBhZ2VEaWN0LCBwRG9jdW1lbnQpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwTmV3WE9SZXMgPSBOVUxMOworCisJaWYgKCFrZXkuSXNFbXB0eSgpKQorCXsKKwkJcFBhZ2VYT2JqZWN0LT5TZXRBdFJlZmVyZW5jZShrZXksIHBEb2N1bWVudCwgZHdPYmpOdW0pOworCQlDUERGX0RpY3Rpb25hcnkqIHBOZXdPWGJqZWN0RGljID0gcE5ld1hPYmplY3QtPkdldERpY3QoKTsKKwkJcE5ld1hPUmVzID0gRlhfTkVXIENQREZfRGljdGlvbmFyeTsKKwkJcE5ld09YYmplY3REaWMtPlNldEF0KCJSZXNvdXJjZXMiLCBwTmV3WE9SZXMpOworCQlwTmV3T1hiamVjdERpYy0+U2V0QXROYW1lKCJUeXBlIiwgIlhPYmplY3QiKTsKKwkJcE5ld09YYmplY3REaWMtPlNldEF0TmFtZSgiU3VidHlwZSIsICJGb3JtIik7CisJCXBOZXdPWGJqZWN0RGljLT5TZXRBdEludGVnZXIoIkZvcm1UeXBlIiwgMSk7CisJCXBOZXdPWGJqZWN0RGljLT5TZXRBdE5hbWUoIk5hbWUiLCAiRlJNIik7CisJCUNQREZfUmVjdCByY0JCb3ggPSBwUGFnZURpY3QtPkdldFJlY3QoIkFydEJveCIpOyAKKwkJcE5ld09YYmplY3REaWMtPlNldEF0UmVjdCgiQkJveCIsIHJjQkJveCk7CisJfQorCQorCWZvciAoaW50IGkgPSAwOyBpIDwgblN0cmVhbXM7IGkrKykKKwl7CisJCUNQREZfRGljdGlvbmFyeSogcEFubm90RGljID0gT2JqZWN0QXJyYXkuR2V0QXQoaSk7CisJCWlmICghcEFubm90RGljKWNvbnRpbnVlOworCisJCUNQREZfUmVjdCByY0Fubm90ID0gcEFubm90RGljLT5HZXRSZWN0KCJSZWN0Iik7CisJCXJjQW5ub3QuTm9ybWFsaXplKCk7CisKKwkJQ0ZYX0J5dGVTdHJpbmcgc0Fubm90U3RhdGUgPSBwQW5ub3REaWMtPkdldFN0cmluZygiQVMiKTsKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3RBUCA9IHBBbm5vdERpYy0+R2V0RGljdCgiQVAiKTsKKwkJaWYgKCFwQW5ub3RBUCljb250aW51ZTsKKworCQlDUERGX1N0cmVhbSogcEFQU3RyZWFtID0gcEFubm90QVAtPkdldFN0cmVhbSgiTiIpOworCQlpZiAoIXBBUFN0cmVhbSkKKwkJeworCQkJQ1BERl9EaWN0aW9uYXJ5KiBwQVBEaWMgPSBwQW5ub3RBUC0+R2V0RGljdCgiTiIpOworCQkJaWYgKCFwQVBEaWMpY29udGludWU7CisKKwkJCWlmICghc0Fubm90U3RhdGUuSXNFbXB0eSgpKQorCQkJeworCQkJCXBBUFN0cmVhbSA9IHBBUERpYy0+R2V0U3RyZWFtKHNBbm5vdFN0YXRlKTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlGWF9QT1NJVElPTiBwb3MgPSBwQVBEaWMtPkdldFN0YXJ0UG9zKCk7CisJCQkJaWYgKHBvcykKKwkJCQl7CisJCQkJCUNGWF9CeXRlU3RyaW5nIHNLZXk7CisJCQkJCUNQREZfT2JqZWN0KiBwRmlyc3RPYmogPSBwQVBEaWMtPkdldE5leHRFbGVtZW50KHBvcywgc0tleSk7CisJCQkJCWlmIChwRmlyc3RPYmopCisJCQkJCXsKKwkJCQkJCWlmIChwRmlyc3RPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfUkVGRVJFTkNFKQorCQkJCQkJCXBGaXJzdE9iaiA9IHBGaXJzdE9iai0+R2V0RGlyZWN0KCk7CisJCQkJCQkKKwkJCQkJCWlmIChwRmlyc3RPYmotPkdldFR5cGUoKSAhPSBQREZPQkpfU1RSRUFNKQorCQkJCQkJCWNvbnRpbnVlOworCisJCQkJCQlwQVBTdHJlYW0gPSAoQ1BERl9TdHJlYW0qKXBGaXJzdE9iajsKKwkJCQkJfQorCQkJCX0KKwkJCX0KKwkJfQorCisJCWlmICghcEFQU3RyZWFtKWNvbnRpbnVlOworCisJCUNQREZfRGljdGlvbmFyeSogcEFQRGljID0gcEFQU3RyZWFtLT5HZXREaWN0KCk7CisJCUNGWF9BZmZpbmVNYXRyaXggbWF0cml4ID0gcEFQRGljLT5HZXRNYXRyaXgoIk1hdHJpeCIpOworCisJCUNQREZfUmVjdCByY1N0cmVhbTsKKwkJaWYgKHBBUERpYy0+S2V5RXhpc3QoIlJlY3QiKSkKKwkJCXJjU3RyZWFtID0gcEFQRGljLT5HZXRSZWN0KCJSZWN0Iik7CisJCWVsc2UgaWYgKHBBUERpYy0+S2V5RXhpc3QoIkJCb3giKSkKKwkJCXJjU3RyZWFtID0gcEFQRGljLT5HZXRSZWN0KCJCQm94Iik7CisKKwkJaWYgKHJjU3RyZWFtLklzRW1wdHkoKSljb250aW51ZTsKKworCQlDUERGX09iamVjdCogcE9iaiA9IHBBUFN0cmVhbTsKKworCQlpZiAocE9iaikKKwkJewkJCisJCQlDUERGX0RpY3Rpb25hcnkqIHBPYmpEaWMgPSBwT2JqLT5HZXREaWN0KCk7CisJCQlpZiAocE9iakRpYykKKwkJCXsKKwkJCQlwT2JqRGljLT5TZXRBdE5hbWUoIlR5cGUiLCAiWE9iamVjdCIpOworCQkJCXBPYmpEaWMtPlNldEF0TmFtZSgiU3VidHlwZSIsICJGb3JtIik7CisJCQl9CisJCX0KKworCQlDUERGX0RpY3Rpb25hcnkqIHBYT2JqZWN0ID0gcE5ld1hPUmVzLT5HZXREaWN0KCJYT2JqZWN0Iik7CisJCWlmICghcFhPYmplY3QpCisJCXsKKwkJCXBYT2JqZWN0ID0gRlhfTkVXIENQREZfRGljdGlvbmFyeTsKKwkJCXBOZXdYT1Jlcy0+U2V0QXQoIlhPYmplY3QiLCBwWE9iamVjdCk7CisJCX0KKworCQlDRlhfQnl0ZVN0cmluZyBzRm9ybU5hbWU7CisJCXNGb3JtTmFtZS5Gb3JtYXQoIkYlZCIsIGkpOworCQlGWF9EV09SRCBkd09iak51bSA9IHBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocE9iaik7CisJCXBYT2JqZWN0LT5TZXRBdFJlZmVyZW5jZShzRm9ybU5hbWUsIHBEb2N1bWVudCwgZHdPYmpOdW0pOworCisJCUNQREZfU3RyZWFtQWNjIGFjYzsKKwkJYWNjLkxvYWRBbGxEYXRhKHBOZXdYT2JqZWN0KTsKKworCQlGWF9MUENCWVRFIHBEYXRhID0gYWNjLkdldERhdGEoKTsKKwkJQ0ZYX0J5dGVTdHJpbmcgc1N0cmVhbShwRGF0YSwgYWNjLkdldFNpemUoKSk7CisJCUNGWF9CeXRlU3RyaW5nIHNUZW1wOworCisJCWlmIChtYXRyaXguSXNJZGVudGl0eSgpKQorCQl7CisJCQltYXRyaXguYSA9IDEuMGY7CisJCQltYXRyaXguYiA9IDAuMGY7CisJCQltYXRyaXguYyA9IDAuMGY7CisJCQltYXRyaXguZCA9IDEuMGY7CisJCQltYXRyaXguZSA9IDAuMGY7CisJCQltYXRyaXguZiA9IDAuMGY7CisJCX0KKworCQlDRlhfQWZmaW5lTWF0cml4IG0gPSBHZXRNYXRyaXgocmNBbm5vdCwgcmNTdHJlYW0sIG1hdHJpeCk7CisJCXNUZW1wLkZvcm1hdCgicSAlZiAwIDAgJWYgJWYgJWYgY20gLyVzIERvIFFcbiIsIG0uYSwgbS5kLCBtLmUsIG0uZiwgKEZYX0xQQ1NUUilzRm9ybU5hbWUpOworCQlzU3RyZWFtICs9IHNUZW1wOworCisJCXBOZXdYT2JqZWN0LT5TZXREYXRhKChGWF9MUENCWVRFKXNTdHJlYW0sIHNTdHJlYW0uR2V0TGVuZ3RoKCksIEZBTFNFLCBGQUxTRSk7CisJfQorCXBQYWdlRGljdC0+UmVtb3ZlQXQoICJBbm5vdHMiICk7CisKKwlPYmplY3RBcnJheS5SZW1vdmVBbGwoKTsKKwlSZWN0QXJyYXkuUmVtb3ZlQWxsKCk7CisKKwlyZXR1cm4gRkxBVFRFTl9TVUNDRVNTOworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnBkZl9wcm9ncmVzc2l2ZS5jcHAgYi9mcGRmc2RrL3NyYy9mcGRmX3Byb2dyZXNzaXZlLmNwcAppbmRleCAyOTQ5NmUwLi5iNjY5MWFmIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mcGRmX3Byb2dyZXNzaXZlLmNwcAorKysgYi9mcGRmc2RrL3NyYy9mcGRmX3Byb2dyZXNzaXZlLmNwcApAQCAtMSwxMTQgKzEsMTE0IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmX3Byb2dyZXNzaXZlLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmdmlldy5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfcmVuZGVyY29udGV4dC5oIg0KLQ0KLWV4dGVybiB2b2lkICgqRnVuY19SZW5kZXJQYWdlKSggQ1JlbmRlckNvbnRleHQqLCBGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCBpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LA0KLQkJCQkJCWludCByb3RhdGUsIGludCBmbGFncyxGWF9CT09MIGJOZWVkVG9SZXN0b3JlLCBJRlNES19QQVVTRV9BZGFwdGVyICogcGF1c2UgKTsNCi0NCi1leHRlcm4gdm9pZCBEcm9wQ29udGV4dCh2b2lkKiBkYXRhKTsNCi0NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERl9SZW5kZXJQYWdlQml0bWFwX1N0YXJ0KCBGUERGX0JJVE1BUCBiaXRtYXAsIEZQREZfUEFHRSBwYWdlLCANCi0JCQkJCQkJCQkJCQkJaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCBpbnQgc2l6ZV94LA0KLQkJCQkJCQkJCQkJCSAgICBpbnQgc2l6ZV95LCBpbnQgcm90YXRlLCBpbnQgZmxhZ3MsDQotCQkJCQkJCQkJCQkJCUlGU0RLX1BBVVNFICogcGF1c2UgKQ0KLXsNCi0JaWYgKGJpdG1hcCA9PSBOVUxMIHx8IHBhZ2UgPT0gTlVMTCkNCi0JCXJldHVybiBGUERGX1JFTkRFUl9GQUlMRUQ7DQotDQotIAlpZiAoIXBhdXNlKQ0KLSAJCXJldHVybiBGUERGX1JFTkRFUl9GQUlMRUQ7DQotDQotCWlmIChwYXVzZS0+dmVyc2lvbiAhPTEpDQotCQlyZXR1cm4gRlBERl9SRU5ERVJfRkFJTEVEOw0KLQ0KLQlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsNCi0JDQotLy8JRlhNVF9DU0xPQ0tfT0JKKCZwUGFnZS0+bV9QYWdlTG9jayk7DQotCQ0KLQlDUmVuZGVyQ29udGV4dCogcENvbnRleHQgPSBGWF9ORVcgQ1JlbmRlckNvbnRleHQ7DQotCXBQYWdlLT5TZXRQcml2YXRlRGF0YSgodm9pZCopMSwgcENvbnRleHQsIERyb3BDb250ZXh0ICk7DQotI2lmZGVmIF9TS0lBX1NVUFBPUlRfDQotCXBDb250ZXh0LT5tX3BEZXZpY2UgPSBGWF9ORVcgQ0ZYX1NraWFEZXZpY2U7DQotCWlmIChmbGFncyAmIEZQREZfUkVWRVJTRV9CWVRFX09SREVSKQ0KLQkJKChDRlhfU2tpYURldmljZSopcENvbnRleHQtPm1fcERldmljZSktPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXAsMCxUUlVFKTsNCi0JZWxzZQ0KLQkJKChDRlhfU2tpYURldmljZSopcENvbnRleHQtPm1fcERldmljZSktPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXApOw0KLSNlbHNlDQotCXBDb250ZXh0LT5tX3BEZXZpY2UgPSBGWF9ORVcgQ0ZYX0Z4Z2VEZXZpY2U7DQotCWlmIChmbGFncyAmIEZQREZfUkVWRVJTRV9CWVRFX09SREVSKQ0KLQkJKChDRlhfRnhnZURldmljZSopcENvbnRleHQtPm1fcERldmljZSktPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXAsMCxUUlVFKTsNCi0JZWxzZQ0KLQkJKChDRlhfRnhnZURldmljZSopcENvbnRleHQtPm1fcERldmljZSktPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXApOw0KLSNlbmRpZg0KLQlJRlNES19QQVVTRV9BZGFwdGVyIElQYXVzZUFkYXB0ZXIocGF1c2UpOw0KLQkNCi0JaWYgKGZsYWdzICYgRlBERl9OT19DQVRDSCkNCi0JCUZ1bmNfUmVuZGVyUGFnZShwQ29udGV4dCwgcGFnZSwgc3RhcnRfeCwgc3RhcnRfeSwgc2l6ZV94LCBzaXplX3ksIHJvdGF0ZSwgZmxhZ3MsRkFMU0UsICZJUGF1c2VBZGFwdGVyKTsNCi0JZWxzZSB7DQotCQl0cnkgew0KLQkJCUZ1bmNfUmVuZGVyUGFnZShwQ29udGV4dCwgcGFnZSwgc3RhcnRfeCwgc3RhcnRfeSwgc2l6ZV94LCBzaXplX3ksIHJvdGF0ZSwgZmxhZ3MsRkFMU0UsICZJUGF1c2VBZGFwdGVyKTsNCi0JCQl9DQotCQljYXRjaCAoLi4uKXt9DQotCX0NCi0NCi0JaWYgKCBwQ29udGV4dC0+bV9wUmVuZGVyZXIgKQ0KLQl7DQotCQlDUERGX1Byb2dyZXNzaXZlUmVuZGVyZXI6OlJlbmRlclN0YXR1cyBzdGF0dXMgPSBDUERGX1Byb2dyZXNzaXZlUmVuZGVyZXI6OkZhaWxlZDsNCi0JCXN0YXR1cyA9IHBDb250ZXh0LT5tX3BSZW5kZXJlci0+R2V0U3RhdHVzKCk7DQotCQlyZXR1cm4gc3RhdHVzOw0KLQl9DQotCXJldHVybiBGUERGX1JFTkRFUl9GQUlMRUQ7DQotfQ0KLQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2VfQ29udGludWUoRlBERl9QQUdFIHBhZ2UsSUZTREtfUEFVU0UgKiBwYXVzZSkNCi17DQotCWlmIChwYWdlID09IE5VTEwpDQotCQlyZXR1cm4gRlBERl9SRU5ERVJfRkFJTEVEOw0KLQ0KLSAJaWYgKCFwYXVzZSkNCi0JCXJldHVybiBGUERGX1JFTkRFUl9GQUlMRUQ7DQotCQ0KLQlpZiAocGF1c2UtPnZlcnNpb24gIT0xKQ0KLQkJcmV0dXJuIEZQREZfUkVOREVSX0ZBSUxFRDsNCi0NCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotDQotLy8JRlhNVF9DU0xPQ0tfT0JKKCZwUGFnZS0+bV9QYWdlTG9jayk7DQotDQotCUNSZW5kZXJDb250ZXh0ICogcENvbnRleHQgPSAoQ1JlbmRlckNvbnRleHQqKXBQYWdlLT5HZXRQcml2YXRlRGF0YSgodm9pZCopMSk7DQotCWlmIChwQ29udGV4dCAmJiBwQ29udGV4dC0+bV9wUmVuZGVyZXIpDQotCXsNCi0JCUlGU0RLX1BBVVNFX0FkYXB0ZXIgSVBhdXNlQWRhcHRlcihwYXVzZSk7DQotCQlwQ29udGV4dC0+bV9wUmVuZGVyZXItPkNvbnRpbnVlKCZJUGF1c2VBZGFwdGVyKTsNCi0NCi0JCUNQREZfUHJvZ3Jlc3NpdmVSZW5kZXJlcjo6UmVuZGVyU3RhdHVzIHN0YXR1cyA9IENQREZfUHJvZ3Jlc3NpdmVSZW5kZXJlcjo6RmFpbGVkOw0KLQkJc3RhdHVzID0gcENvbnRleHQtPm1fcFJlbmRlcmVyLT5HZXRTdGF0dXMoKTsNCi0JCXJldHVybiBzdGF0dXM7DQotCX0NCi0JcmV0dXJuIEZQREZfUkVOREVSX0ZBSUxFRDsNCi19DQotDQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2VfQ2xvc2UoRlBERl9QQUdFIHBhZ2UpDQotew0KLQlpZiAocGFnZSA9PSBOVUxMKSByZXR1cm47DQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQ0KLS8vCUZYTVRfQ1NMT0NLX09CSigmcFBhZ2UtPm1fUGFnZUxvY2spOw0KLQ0KLQlDUmVuZGVyQ29udGV4dCAqIHBDb250ZXh0ID0gKENSZW5kZXJDb250ZXh0KilwUGFnZS0+R2V0UHJpdmF0ZURhdGEoKHZvaWQqKTEpOw0KLQlpZiAocENvbnRleHQpDQotCXsNCi0JCXBDb250ZXh0LT5tX3BEZXZpY2UtPlJlc3RvcmVTdGF0ZSgpOw0KLQkJZGVsZXRlIHBDb250ZXh0Ow0KLQkJcFBhZ2UtPlJlbW92ZVByaXZhdGVEYXRhKCh2b2lkKikxKTsNCi0JfQ0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmX3Byb2dyZXNzaXZlLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZnZpZXcuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfcmVuZGVyY29udGV4dC5oIgorCitleHRlcm4gdm9pZCAoKkZ1bmNfUmVuZGVyUGFnZSkoIENSZW5kZXJDb250ZXh0KiwgRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwgaW50IHNpemVfeSwKKwkJCQkJCWludCByb3RhdGUsIGludCBmbGFncyxGWF9CT09MIGJOZWVkVG9SZXN0b3JlLCBJRlNES19QQVVTRV9BZGFwdGVyICogcGF1c2UgKTsKKworZXh0ZXJuIHZvaWQgRHJvcENvbnRleHQodm9pZCogZGF0YSk7CisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2VCaXRtYXBfU3RhcnQoIEZQREZfQklUTUFQIGJpdG1hcCwgRlBERl9QQUdFIHBhZ2UsIAorCQkJCQkJCQkJCQkJCWludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwKKwkJCQkJCQkJCQkJCSAgICBpbnQgc2l6ZV95LCBpbnQgcm90YXRlLCBpbnQgZmxhZ3MsCisJCQkJCQkJCQkJCQkJSUZTREtfUEFVU0UgKiBwYXVzZSApCit7CisJaWYgKGJpdG1hcCA9PSBOVUxMIHx8IHBhZ2UgPT0gTlVMTCkKKwkJcmV0dXJuIEZQREZfUkVOREVSX0ZBSUxFRDsKKworIAlpZiAoIXBhdXNlKQorIAkJcmV0dXJuIEZQREZfUkVOREVSX0ZBSUxFRDsKKworCWlmIChwYXVzZS0+dmVyc2lvbiAhPTEpCisJCXJldHVybiBGUERGX1JFTkRFUl9GQUlMRUQ7CisKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKwkKKy8vCUZYTVRfQ1NMT0NLX09CSigmcFBhZ2UtPm1fUGFnZUxvY2spOworCQorCUNSZW5kZXJDb250ZXh0KiBwQ29udGV4dCA9IEZYX05FVyBDUmVuZGVyQ29udGV4dDsKKwlwUGFnZS0+U2V0UHJpdmF0ZURhdGEoKHZvaWQqKTEsIHBDb250ZXh0LCBEcm9wQ29udGV4dCApOworI2lmZGVmIF9TS0lBX1NVUFBPUlRfCisJcENvbnRleHQtPm1fcERldmljZSA9IEZYX05FVyBDRlhfU2tpYURldmljZTsKKwlpZiAoZmxhZ3MgJiBGUERGX1JFVkVSU0VfQllURV9PUkRFUikKKwkJKChDRlhfU2tpYURldmljZSopcENvbnRleHQtPm1fcERldmljZSktPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXAsMCxUUlVFKTsKKwllbHNlCisJCSgoQ0ZYX1NraWFEZXZpY2UqKXBDb250ZXh0LT5tX3BEZXZpY2UpLT5BdHRhY2goKENGWF9ESUJpdG1hcCopYml0bWFwKTsKKyNlbHNlCisJcENvbnRleHQtPm1fcERldmljZSA9IEZYX05FVyBDRlhfRnhnZURldmljZTsKKwlpZiAoZmxhZ3MgJiBGUERGX1JFVkVSU0VfQllURV9PUkRFUikKKwkJKChDRlhfRnhnZURldmljZSopcENvbnRleHQtPm1fcERldmljZSktPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXAsMCxUUlVFKTsKKwllbHNlCisJCSgoQ0ZYX0Z4Z2VEZXZpY2UqKXBDb250ZXh0LT5tX3BEZXZpY2UpLT5BdHRhY2goKENGWF9ESUJpdG1hcCopYml0bWFwKTsKKyNlbmRpZgorCUlGU0RLX1BBVVNFX0FkYXB0ZXIgSVBhdXNlQWRhcHRlcihwYXVzZSk7CisJCisJaWYgKGZsYWdzICYgRlBERl9OT19DQVRDSCkKKwkJRnVuY19SZW5kZXJQYWdlKHBDb250ZXh0LCBwYWdlLCBzdGFydF94LCBzdGFydF95LCBzaXplX3gsIHNpemVfeSwgcm90YXRlLCBmbGFncyxGQUxTRSwgJklQYXVzZUFkYXB0ZXIpOworCWVsc2UgeworCQl0cnkgeworCQkJRnVuY19SZW5kZXJQYWdlKHBDb250ZXh0LCBwYWdlLCBzdGFydF94LCBzdGFydF95LCBzaXplX3gsIHNpemVfeSwgcm90YXRlLCBmbGFncyxGQUxTRSwgJklQYXVzZUFkYXB0ZXIpOworCQkJfQorCQljYXRjaCAoLi4uKXt9CisJfQorCisJaWYgKCBwQ29udGV4dC0+bV9wUmVuZGVyZXIgKQorCXsKKwkJQ1BERl9Qcm9ncmVzc2l2ZVJlbmRlcmVyOjpSZW5kZXJTdGF0dXMgc3RhdHVzID0gQ1BERl9Qcm9ncmVzc2l2ZVJlbmRlcmVyOjpGYWlsZWQ7CisJCXN0YXR1cyA9IHBDb250ZXh0LT5tX3BSZW5kZXJlci0+R2V0U3RhdHVzKCk7CisJCXJldHVybiBzdGF0dXM7CisJfQorCXJldHVybiBGUERGX1JFTkRFUl9GQUlMRUQ7Cit9CisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2VfQ29udGludWUoRlBERl9QQUdFIHBhZ2UsSUZTREtfUEFVU0UgKiBwYXVzZSkKK3sKKwlpZiAocGFnZSA9PSBOVUxMKQorCQlyZXR1cm4gRlBERl9SRU5ERVJfRkFJTEVEOworCisgCWlmICghcGF1c2UpCisJCXJldHVybiBGUERGX1JFTkRFUl9GQUlMRUQ7CisJCisJaWYgKHBhdXNlLT52ZXJzaW9uICE9MSkKKwkJcmV0dXJuIEZQREZfUkVOREVSX0ZBSUxFRDsKKworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCisvLwlGWE1UX0NTTE9DS19PQkooJnBQYWdlLT5tX1BhZ2VMb2NrKTsKKworCUNSZW5kZXJDb250ZXh0ICogcENvbnRleHQgPSAoQ1JlbmRlckNvbnRleHQqKXBQYWdlLT5HZXRQcml2YXRlRGF0YSgodm9pZCopMSk7CisJaWYgKHBDb250ZXh0ICYmIHBDb250ZXh0LT5tX3BSZW5kZXJlcikKKwl7CisJCUlGU0RLX1BBVVNFX0FkYXB0ZXIgSVBhdXNlQWRhcHRlcihwYXVzZSk7CisJCXBDb250ZXh0LT5tX3BSZW5kZXJlci0+Q29udGludWUoJklQYXVzZUFkYXB0ZXIpOworCisJCUNQREZfUHJvZ3Jlc3NpdmVSZW5kZXJlcjo6UmVuZGVyU3RhdHVzIHN0YXR1cyA9IENQREZfUHJvZ3Jlc3NpdmVSZW5kZXJlcjo6RmFpbGVkOworCQlzdGF0dXMgPSBwQ29udGV4dC0+bV9wUmVuZGVyZXItPkdldFN0YXR1cygpOworCQlyZXR1cm4gc3RhdHVzOworCX0KKwlyZXR1cm4gRlBERl9SRU5ERVJfRkFJTEVEOworfQorCisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9SZW5kZXJQYWdlX0Nsb3NlKEZQREZfUEFHRSBwYWdlKQoreworCWlmIChwYWdlID09IE5VTEwpIHJldHVybjsKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKworLy8JRlhNVF9DU0xPQ0tfT0JKKCZwUGFnZS0+bV9QYWdlTG9jayk7CisKKwlDUmVuZGVyQ29udGV4dCAqIHBDb250ZXh0ID0gKENSZW5kZXJDb250ZXh0KilwUGFnZS0+R2V0UHJpdmF0ZURhdGEoKHZvaWQqKTEpOworCWlmIChwQ29udGV4dCkKKwl7CisJCXBDb250ZXh0LT5tX3BEZXZpY2UtPlJlc3RvcmVTdGF0ZSgpOworCQlkZWxldGUgcENvbnRleHQ7CisJCXBQYWdlLT5SZW1vdmVQcml2YXRlRGF0YSgodm9pZCopMSk7CisJfQorfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mcGRmX3NlYXJjaGV4LmNwcCBiL2ZwZGZzZGsvc3JjL2ZwZGZfc2VhcmNoZXguY3BwCmluZGV4IDU0MGNkNTUuLjIxODMxYTMgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZwZGZfc2VhcmNoZXguY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2ZwZGZfc2VhcmNoZXguY3BwCkBAIC0xLDE1ICsxLDE1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZfc2VhcmNoZXguaCINCi0NCi0NCi1ETExFWFBPUlQgaW50IFNURENBTEwgIEZQREZUZXh0X0dldENoYXJJbmRleEZyb21UZXh0SW5kZXgoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCBuVGV4dEluZGV4KQ0KLXsNCi0JaWYoIXRleHRfcGFnZSkgcmV0dXJuIC0xOw0KLQlyZXR1cm4gKChJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2UpLT5DaGFySW5kZXhGcm9tVGV4dEluZGV4KG5UZXh0SW5kZXgpOw0KLX0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZl9zZWFyY2hleC5oIgorCisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCAgRlBERlRleHRfR2V0Q2hhckluZGV4RnJvbVRleHRJbmRleChGUERGX1RFWFRQQUdFIHRleHRfcGFnZSwgaW50IG5UZXh0SW5kZXgpCit7CisJaWYoIXRleHRfcGFnZSkgcmV0dXJuIC0xOworCXJldHVybiAoKElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZSktPkNoYXJJbmRleEZyb21UZXh0SW5kZXgoblRleHRJbmRleCk7Cit9CmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mcGRmX3RyYW5zZm9ybXBhZ2UuY3BwIGIvZnBkZnNkay9zcmMvZnBkZl90cmFuc2Zvcm1wYWdlLmNwcAppbmRleCBmMTcxYzVlLi43MjliMWNkIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mcGRmX3RyYW5zZm9ybXBhZ2UuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2ZwZGZfdHJhbnNmb3JtcGFnZS5jcHAKQEAgLTEsMzI1ICsxLDMyNSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmX3RyYW5zZm9ybXBhZ2UuaCINCi0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX1NldE1lZGlhQm94KEZQREZfUEFHRSBwYWdlLCBmbG9hdCBsZWZ0LCBmbG9hdCBib3R0b20sIGZsb2F0IHJpZ2h0LCBmbG9hdCB0b3ApDQotew0KLQlpZighcGFnZSkNCi0JCXJldHVybjsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotCUNQREZfRGljdGlvbmFyeSogcFBhZ2VEaWN0ID0gcFBhZ2UtPm1fcEZvcm1EaWN0Ow0KLQlDUERGX0FycmF5KiBwTWVkaWFCb3hBcnJheSA9IEZYX05FVyBDUERGX0FycmF5Ow0KLQlwTWVkaWFCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcihsZWZ0KSk7DQotCXBNZWRpYUJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKGJvdHRvbSkpOw0KLQlwTWVkaWFCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcihGWF9GTE9BVChyaWdodCkpKTsNCi0JcE1lZGlhQm94QXJyYXktPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIoRlhfRkxPQVQodG9wKSkpOw0KLQkNCi0JcFBhZ2VEaWN0LT5TZXRBdCgiTWVkaWFCb3giLCBwTWVkaWFCb3hBcnJheSk7DQotfQ0KLQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VfU2V0Q3JvcEJveChGUERGX1BBR0UgcGFnZSwgZmxvYXQgbGVmdCwgZmxvYXQgYm90dG9tLCBmbG9hdCByaWdodCwgZmxvYXQgdG9wKQ0KLXsNCi0JaWYoIXBhZ2UpDQotCQlyZXR1cm47DQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBQYWdlLT5tX3BGb3JtRGljdDsNCi0JQ1BERl9BcnJheSogcENyb3BCb3hBcnJheSA9IEZYX05FVyBDUERGX0FycmF5Ow0KLQlwQ3JvcEJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKGxlZnQpKTsNCi0JcENyb3BCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcihib3R0b20pKTsNCi0JcENyb3BCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcihGWF9GTE9BVChyaWdodCkpKTsNCi0JcENyb3BCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcihGWF9GTE9BVCh0b3ApKSk7DQotCQ0KLQkNCi0JcFBhZ2VEaWN0LT5TZXRBdCgiQ3JvcEJveCIsIHBDcm9wQm94QXJyYXkpOw0KLX0NCi0NCi0NCi1ETExFWFBPUlQgRlhfQk9PTCBTVERDQUxMIEZQREZQYWdlX0dldE1lZGlhQm94KEZQREZfUEFHRSBwYWdlLCBmbG9hdCogbGVmdCwgZmxvYXQqIGJvdHRvbSwgZmxvYXQqIHJpZ2h0LCBmbG9hdCogdG9wKQ0KLXsNCi0JaWYoIXBhZ2UpDQotCQlyZXR1cm4gRkFMU0U7DQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBQYWdlLT5tX3BGb3JtRGljdDsNCi0JQ1BERl9BcnJheSogcEFycmF5ID0gcFBhZ2VEaWN0LT5HZXRBcnJheSgiTWVkaWFCb3giKTsNCi0JaWYocEFycmF5KQ0KLQl7DQotCQkqbGVmdCA9IHBBcnJheS0+R2V0RmxvYXQoMCk7DQotCQkqYm90dG9tID0gcEFycmF5LT5HZXRGbG9hdCgxKTsNCi0JCSpyaWdodCA9IHBBcnJheS0+R2V0RmxvYXQoMik7DQotCQkqdG9wID0gcEFycmF5LT5HZXRGbG9hdCgzKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlX0dldENyb3BCb3goRlBERl9QQUdFIHBhZ2UsIGZsb2F0KiBsZWZ0LCBmbG9hdCogYm90dG9tLCBmbG9hdCogcmlnaHQsIGZsb2F0KiB0b3ApDQotew0KLQlpZighcGFnZSkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotCUNQREZfRGljdGlvbmFyeSogcFBhZ2VEaWN0ID0gcFBhZ2UtPm1fcEZvcm1EaWN0Ow0KLQlDUERGX0FycmF5KiBwQXJyYXkgPSBwUGFnZURpY3QtPkdldEFycmF5KCJDcm9wQm94Iik7DQotCWlmKHBBcnJheSkNCi0Jew0KLQkJKmxlZnQgPSBwQXJyYXktPkdldEZsb2F0KDApOw0KLQkJKmJvdHRvbSA9IHBBcnJheS0+R2V0RmxvYXQoMSk7DQotCQkqcmlnaHQgPSBwQXJyYXktPkdldEZsb2F0KDIpOw0KLQkJKnRvcCA9IHBBcnJheS0+R2V0RmxvYXQoMyk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGUGFnZV9UcmFuc0Zvcm1XaXRoQ2xpcChGUERGX1BBR0UgcGFnZSwgRlNfTUFUUklYKiBtYXRyaXgsIEZTX1JFQ1RGKiBjbGlwUmVjdCkNCi17DQotCWlmKCFwYWdlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQlDRlhfQnl0ZVRleHRCdWYgdGV4dEJ1ZjsNCi0JdGV4dEJ1Zjw8InEgIjsNCi0JQ0ZYX0Zsb2F0UmVjdCByZWN0KGNsaXBSZWN0LT5sZWZ0LCBjbGlwUmVjdC0+Ym90dG9tLCBjbGlwUmVjdC0+cmlnaHQsIGNsaXBSZWN0LT50b3ApOw0KLQlyZWN0Lk5vcm1hbGl6ZSgpOw0KLQlDRlhfQnl0ZVN0cmluZyBic0NsaXBwaW5nOw0KLQlic0NsaXBwaW5nLkZvcm1hdCgiJWYgJWYgJWYgJWYgcmUgVyogbiAiLCByZWN0LmxlZnQsIHJlY3QuYm90dG9tLCByZWN0LldpZHRoKCksIHJlY3QuSGVpZ2h0KCkpOw0KLQl0ZXh0QnVmPDxic0NsaXBwaW5nOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBic01hdGl4Ow0KLQlic01hdGl4LkZvcm1hdCgiJWYgJWYgJWYgJWYgJWYgJWYgY20gIiwgbWF0cml4LT5hLCBtYXRyaXgtPmIsbWF0cml4LT5jLG1hdHJpeC0+ZCxtYXRyaXgtPmUsbWF0cml4LT5mKTsNCi0JdGV4dEJ1Zjw8YnNNYXRpeDsNCi0JDQotDQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljID0gcFBhZ2UtPm1fcEZvcm1EaWN0Ow0KLQlDUERGX09iamVjdCogcENvbnRlbnRPYmogPSBwUGFnZURpYy0+R2V0RWxlbWVudCgiQ29udGVudHMiKTsNCi0JaWYoIXBDb250ZW50T2JqKQ0KLQkJcENvbnRlbnRPYmogPSBwUGFnZURpYy0+R2V0QXJyYXkoIkNvbnRlbnRzIik7DQotCWlmKCFwQ29udGVudE9iaikNCi0JCXJldHVybiBGQUxTRTsNCi0JDQotCUNQREZfRGljdGlvbmFyeSogcERpYyA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7DQotCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gRlhfTkVXIENQREZfU3RyZWFtKE5VTEwsMCwgcERpYyk7DQotCXBTdHJlYW0tPlNldERhdGEodGV4dEJ1Zi5HZXRCdWZmZXIoKSwgdGV4dEJ1Zi5HZXRTaXplKCksIEZBTFNFLCBGQUxTRSk7DQotCUNQREZfRG9jdW1lbnQqIHBEb2MgPSBwUGFnZS0+bV9wRG9jdW1lbnQ7DQotCWlmKCFwRG9jKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlwRG9jLT5BZGRJbmRpcmVjdE9iamVjdChwU3RyZWFtKTsNCi0NCi0JcERpYyA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7DQotCUNQREZfU3RyZWFtKiBwRW5kU3RyZWFtID0gRlhfTkVXIENQREZfU3RyZWFtKE5VTEwsMCwgcERpYyk7DQotCXBFbmRTdHJlYW0tPlNldERhdGEoKEZYX0xQQ0JZVEUpIiBRIiwgMiwgRkFMU0UsIEZBTFNFKTsNCi0JcERvYy0+QWRkSW5kaXJlY3RPYmplY3QocEVuZFN0cmVhbSk7DQotCQ0KLQlDUERGX0FycmF5KiBwQ29udGVudEFycmF5ID0gTlVMTDsNCi0JaWYgKHBDb250ZW50T2JqICYmIHBDb250ZW50T2JqLT5HZXRUeXBlKCkgPT0gUERGT0JKX0FSUkFZKQ0KLQl7DQotCQlwQ29udGVudEFycmF5ID0gKENQREZfQXJyYXkqKXBDb250ZW50T2JqOw0KLQkJQ1BERl9SZWZlcmVuY2UqIHBSZWYgPSBGWF9ORVcgQ1BERl9SZWZlcmVuY2UocERvYywgcFN0cmVhbS0+R2V0T2JqTnVtKCkpOw0KLQkJcENvbnRlbnRBcnJheS0+SW5zZXJ0QXQoMCwgcFJlZik7DQotCQlwQ29udGVudEFycmF5LT5BZGRSZWZlcmVuY2UocERvYyxwRW5kU3RyZWFtKTsNCi0JCQ0KLQl9DQotCWVsc2UgaWYocENvbnRlbnRPYmogJiYgcENvbnRlbnRPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfUkVGRVJFTkNFKQ0KLQl7DQotCQlDUERGX1JlZmVyZW5jZSogcFJlZmVyZW5jZSA9IChDUERGX1JlZmVyZW5jZSopcENvbnRlbnRPYmo7DQotCQlDUERGX09iamVjdCogcERpcmVjdE9iaiA9IHBSZWZlcmVuY2UtPkdldERpcmVjdCgpOw0KLQkJaWYocERpcmVjdE9iaiAhPSBOVUxMKQ0KLQkJew0KLQkJCWlmKHBEaXJlY3RPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfQVJSQVkpDQotCQkJew0KLQkJCQlwQ29udGVudEFycmF5ID0gKENQREZfQXJyYXkqKXBEaXJlY3RPYmo7DQotCQkJCUNQREZfUmVmZXJlbmNlKiBwUmVmID0gRlhfTkVXIENQREZfUmVmZXJlbmNlKHBEb2MsIHBTdHJlYW0tPkdldE9iak51bSgpKTsNCi0JCQkJcENvbnRlbnRBcnJheS0+SW5zZXJ0QXQoMCwgcFJlZik7DQotCQkJCXBDb250ZW50QXJyYXktPkFkZFJlZmVyZW5jZShwRG9jLHBFbmRTdHJlYW0pOw0KLQkJCQkNCi0JCQl9DQotCQkJZWxzZSBpZihwRGlyZWN0T2JqLT5HZXRUeXBlKCkgPT0gUERGT0JKX1NUUkVBTSkNCi0JCQl7DQotCQkJCXBDb250ZW50QXJyYXkgPSBGWF9ORVcgQ1BERl9BcnJheSgpOw0KLQkJCQlwQ29udGVudEFycmF5LT5BZGRSZWZlcmVuY2UocERvYyxwU3RyZWFtLT5HZXRPYmpOdW0oKSk7DQotCQkJCXBDb250ZW50QXJyYXktPkFkZFJlZmVyZW5jZShwRG9jLHBEaXJlY3RPYmotPkdldE9iak51bSgpKTsNCi0JCQkJcENvbnRlbnRBcnJheS0+QWRkUmVmZXJlbmNlKHBEb2MsIHBFbmRTdHJlYW0pOw0KLQkJCQlwUGFnZURpYy0+U2V0QXRSZWZlcmVuY2UoIkNvbnRlbnRzIiwgcERvYywgcERvYy0+QWRkSW5kaXJlY3RPYmplY3QocENvbnRlbnRBcnJheSkpOw0KLQkJCX0NCi0JCX0NCi0JfQkNCi0NCi0JLy9OZWVkIHRvIHRyYW5zZm9ybSB0aGUgcGF0dGVybnMgYXMgd2VsbC4NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwUmVzID0gcFBhZ2VEaWMtPkdldERpY3QoRlhfQlNUUkMoIlJlc291cmNlcyIpKTsNCi0JaWYocFJlcykNCi0Jew0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwUGF0dGVuRGljdCA9IHBSZXMtPkdldERpY3QoRlhfQlNUUkMoIlBhdHRlcm4iKSk7DQotCQlpZihwUGF0dGVuRGljdCkNCi0JCXsNCi0JCQlGWF9QT1NJVElPTiBwb3MgPSBwUGF0dGVuRGljdC0+R2V0U3RhcnRQb3MoKTsNCi0JCQl3aGlsZShwb3MpDQotCQkJew0KLQkJCQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gTlVMTDsNCi0JCQkJQ0ZYX0J5dGVTdHJpbmcga2V5Ow0KLQkJCQlDUERGX09iamVjdCogcE9iaiA9IHBQYXR0ZW5EaWN0LT5HZXROZXh0RWxlbWVudChwb3MsIGtleSk7DQotCQkJCWlmKHBPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfUkVGRVJFTkNFKQ0KLQkJCQkJcE9iaiA9IHBPYmotPkdldERpcmVjdCgpOw0KLQkJCQlpZihwT2JqLT5HZXRUeXBlKCkgPT0gUERGT0JKX0RJQ1RJT05BUlkpDQotCQkJCXsNCi0JCQkJCXBEaWN0ID0gKENQREZfRGljdGlvbmFyeSopcE9iajsNCi0JCQkJfQ0KLQkJCQllbHNlIGlmKHBPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfU1RSRUFNKQ0KLQkJCQl7DQotCQkJCQlwRGljdCA9ICgoQ1BERl9TdHJlYW0qKXBPYmopLT5HZXREaWN0KCk7DQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQkJY29udGludWU7DQotCQkJCQ0KLQkJCQlDRlhfQWZmaW5lTWF0cml4IG0gPSBwRGljdC0+R2V0TWF0cml4KEZYX0JTVFJDKCJNYXRyaXgiKSk7DQotCQkJCUNGWF9BZmZpbmVNYXRyaXggdCA9ICooQ0ZYX0FmZmluZU1hdHJpeCopbWF0cml4Ow0KLQkJCQltLkNvbmNhdCh0KTsNCi0JCQkJcERpY3QtPlNldEF0TWF0cml4KEZYX0JTVFJDKCJNYXRyaXgiKSwgbSk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlT2JqX1RyYW5zZm9ybUNsaXBQYXRoKEZQREZfUEFHRU9CSkVDVCBwYWdlX29iamVjdCxkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKQ0KLXsNCi0JQ1BERl9QYWdlT2JqZWN0KiBwUGFnZU9iaiA9IChDUERGX1BhZ2VPYmplY3QqKXBhZ2Vfb2JqZWN0Ow0KLQlpZihwUGFnZU9iaiA9PSBOVUxMKQ0KLQkJcmV0dXJuOw0KLQlDRlhfQWZmaW5lTWF0cml4IG1hdHJpeCgoRlhfRkxPQVQpYSwoRlhfRkxPQVQpYiwoRlhfRkxPQVQpYywoRlhfRkxPQVQpZCwoRlhfRkxPQVQpZSwoRlhfRkxPQVQpZik7DQotCQ0KLQkvL1NwZWNpYWwgdHJlYXRtZW50IHRvIHNoYWRpbmcgb2JqZWN0LCBiZWNhdXNlIHRoZSBDbGlwUGF0aCBmb3Igc2hhZGluZyBvYmplY3QgaXMgYWxyZWFkeSB0cmFuc2Zvcm1lZC4NCi0JaWYocFBhZ2VPYmotPm1fVHlwZSAhPSBQREZQQUdFX1NIQURJTkcpDQotCQlwUGFnZU9iai0+VHJhbnNmb3JtQ2xpcFBhdGgobWF0cml4KTsNCi0JcFBhZ2VPYmotPlRyYW5zZm9ybUdlbmVyYWxTdGF0ZShtYXRyaXgpOw0KLX0NCi0NCi0NCi1ETExFWFBPUlQgRlBERl9DTElQUEFUSCBTVERDQUxMIEZQREZfQ3JlYXRlQ2xpcFBhdGgoZmxvYXQgbGVmdCwgZmxvYXQgYm90dG9tLCBmbG9hdCByaWdodCwgZmxvYXQgdG9wKQ0KLXsNCi0JQ1BERl9DbGlwUGF0aCogcE5ld0NsaXBQYXRoID0gIEZYX05FVyBDUERGX0NsaXBQYXRoKCk7DQotCXBOZXdDbGlwUGF0aC0+R2V0TW9kaWZ5KCk7DQotCUNQREZfUGF0aCBQYXRoOw0KLQlQYXRoLkdldE1vZGlmeSgpOw0KLQlQYXRoLkFwcGVuZFJlY3QobGVmdCwgYm90dG9tLCByaWdodCwgdG9wKTsNCi0JcE5ld0NsaXBQYXRoLT5BcHBlbmRQYXRoKFBhdGgsIEZYRklMTF9BTFRFUk5BVEUsIEZBTFNFKTsNCi0JcmV0dXJuIHBOZXdDbGlwUGF0aDsNCi19DQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX0Rlc3Ryb3lDbGlwUGF0aChGUERGX0NMSVBQQVRIIGNsaXBQYXRoKQ0KLXsNCi0JaWYoY2xpcFBhdGgpDQotCQlkZWxldGUgKENQREZfQ2xpcFBhdGgqKWNsaXBQYXRoOw0KLX0NCi0NCi12b2lkIE91dHB1dFBhdGgoQ0ZYX0J5dGVUZXh0QnVmJiBidWYsIENQREZfUGF0aCBwYXRoKQ0KLXsNCi0JY29uc3QgQ0ZYX1BhdGhEYXRhKiBwUGF0aERhdGEgPSBwYXRoOw0KLQlpZiAocFBhdGhEYXRhID09IE5VTEwpIHJldHVybjsNCi0JDQotCUZYX1BBVEhQT0lOVCogcFBvaW50cyA9IHBQYXRoRGF0YS0+R2V0UG9pbnRzKCk7DQotCQ0KLQlpZiAocGF0aC5Jc1JlY3QoKSkgew0KLQkJYnVmIDw8IChwUG9pbnRzWzBdLm1fUG9pbnRYKSA8PCAiICIgPDwgKHBQb2ludHNbMF0ubV9Qb2ludFkpIDw8ICIgIiANCi0JCQk8PCAocFBvaW50c1syXS5tX1BvaW50WCAtIHBQb2ludHNbMF0ubV9Qb2ludFgpIDw8ICIgIiANCi0JCQk8PCAocFBvaW50c1syXS5tX1BvaW50WSAtIHBQb2ludHNbMF0ubV9Qb2ludFkpIDw8ICIgcmVcbiI7DQotCQlyZXR1cm47DQotCX0NCi0JDQotCUNGWF9CeXRlU3RyaW5nIHRlbXA7DQotCWZvciAoaW50IGkgPSAwOyBpIDwgcFBhdGhEYXRhLT5HZXRQb2ludENvdW50KCk7IGkgKyspIHsNCi0JCWJ1ZiA8PCAocFBvaW50c1tpXS5tX1BvaW50WCkgPDwgIiAiIDw8IChwUG9pbnRzW2ldLm1fUG9pbnRZKTsNCi0JCWludCBwb2ludF90eXBlID0gcFBvaW50c1tpXS5tX0ZsYWcgJiBGWFBUX1RZUEU7DQotCQlpZiAocG9pbnRfdHlwZSA9PSBGWFBUX01PVkVUTykNCi0JCQlidWYgPDwgIiBtXG4iOw0KLQkJZWxzZSBpZiAocG9pbnRfdHlwZSA9PSBGWFBUX0JFWklFUlRPKSB7DQotCQkJYnVmIDw8ICIgIiA8PCAocFBvaW50c1tpKzFdLm1fUG9pbnRYKSA8PCAiICIgPDwgKHBQb2ludHNbaSsxXS5tX1BvaW50WSkgPDwgIiAiIDw8IA0KLQkJCQkocFBvaW50c1tpKzJdLm1fUG9pbnRYKSA8PCAiICIgPDwgKHBQb2ludHNbaSsyXS5tX1BvaW50WSk7DQotCQkJaWYgKHBQb2ludHNbaSsyXS5tX0ZsYWcgJiBGWFBUX0NMT1NFRklHVVJFKQ0KLQkJCQlidWYgPDwgIiBjIGhcbiI7DQotCQkJZWxzZQ0KLQkJCQlidWYgPDwgIiBjXG4iOw0KLQkJCWkgKz0gMjsNCi0JCX0gZWxzZSBpZiAocG9pbnRfdHlwZSA9PSBGWFBUX0xJTkVUTykgew0KLQkJCWlmIChwUG9pbnRzW2ldLm1fRmxhZyAmIEZYUFRfQ0xPU0VGSUdVUkUpDQotCQkJCWJ1ZiA8PCAiIGwgaFxuIjsNCi0JCQllbHNlDQotCQkJCWJ1ZiA8PCAiIGxcbiI7DQotCQl9DQotCX0NCi19DQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGUGFnZV9JbnNlcnRDbGlwUGF0aChGUERGX1BBR0UgcGFnZSxGUERGX0NMSVBQQVRIIGNsaXBQYXRoKQ0KLXsNCi0JaWYoIXBhZ2UpDQotCQlyZXR1cm47DQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljID0gcFBhZ2UtPm1fcEZvcm1EaWN0Ow0KLQlDUERGX09iamVjdCogcENvbnRlbnRPYmogPSBwUGFnZURpYy0+R2V0RWxlbWVudCgiQ29udGVudHMiKTsNCi0JaWYoIXBDb250ZW50T2JqKQ0KLQkJcENvbnRlbnRPYmogPSBwUGFnZURpYy0+R2V0QXJyYXkoIkNvbnRlbnRzIik7DQotCWlmKCFwQ29udGVudE9iaikNCi0JCXJldHVybjsNCi0NCi0JQ0ZYX0J5dGVUZXh0QnVmIHN0ckNsaXA7DQotCUNQREZfQ2xpcFBhdGgqIHBDbGlwUGF0aCA9IChDUERGX0NsaXBQYXRoKiljbGlwUGF0aDsNCi0JRlhfRFdPUkQgaTsNCi0JZm9yIChpID0gMDsgaSA8IHBDbGlwUGF0aC0+R2V0UGF0aENvdW50KCk7IGkgKyspIHsNCi0JCUNQREZfUGF0aCBwYXRoID0gcENsaXBQYXRoLT5HZXRQYXRoKGkpOw0KLQkJaW50IGlDbGlwVHlwZSA9IHBDbGlwUGF0aC0+R2V0Q2xpcFR5cGUoaSk7DQotCQlpZiAocGF0aC5HZXRQb2ludENvdW50KCkgPT0gMCkgew0KLQkJCS8vIEVtcHR5IGNsaXBwaW5nICh0b3RhbGx5IGNsaXBwZWQgb3V0KQ0KLQkJCXN0ckNsaXAgPDwgIjAgMCBtIFcgbiAiOw0KLQkJfSBlbHNlIHsNCi0JCQlPdXRwdXRQYXRoKHN0ckNsaXAsIHBhdGgpOw0KLQkJCWlmIChpQ2xpcFR5cGUgPT0gRlhGSUxMX1dJTkRJTkcpDQotCQkJCXN0ckNsaXAgPDwgIlcgblxuIjsNCi0JCQllbHNlDQotCQkJCXN0ckNsaXAgPDwgIlcqIG5cbiI7DQotCQl9DQotCX0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwRGljID0gRlhfTkVXIENQREZfRGljdGlvbmFyeTsNCi0JQ1BERl9TdHJlYW0qIHBTdHJlYW0gPSBGWF9ORVcgQ1BERl9TdHJlYW0oTlVMTCwwLCBwRGljKTsNCi0JcFN0cmVhbS0+U2V0RGF0YShzdHJDbGlwLkdldEJ1ZmZlcigpLCBzdHJDbGlwLkdldFNpemUoKSwgRkFMU0UsIEZBTFNFKTsNCi0JQ1BERl9Eb2N1bWVudCogcERvYyA9IHBQYWdlLT5tX3BEb2N1bWVudDsNCi0JaWYoIXBEb2MpDQotCQlyZXR1cm47DQotCXBEb2MtPkFkZEluZGlyZWN0T2JqZWN0KHBTdHJlYW0pOw0KLQkNCi0JQ1BERl9BcnJheSogcENvbnRlbnRBcnJheSA9IE5VTEw7DQotCWlmIChwQ29udGVudE9iaiAmJiBwQ29udGVudE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9BUlJBWSkNCi0Jew0KLQkJcENvbnRlbnRBcnJheSA9IChDUERGX0FycmF5KilwQ29udGVudE9iajsNCi0JCUNQREZfUmVmZXJlbmNlKiBwUmVmID0gRlhfTkVXIENQREZfUmVmZXJlbmNlKHBEb2MsIHBTdHJlYW0tPkdldE9iak51bSgpKTsNCi0JCXBDb250ZW50QXJyYXktPkluc2VydEF0KDAsIHBSZWYpOw0KLQkJDQotCX0NCi0JZWxzZSBpZihwQ29udGVudE9iaiAmJiBwQ29udGVudE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9SRUZFUkVOQ0UpDQotCXsNCi0JCUNQREZfUmVmZXJlbmNlKiBwUmVmZXJlbmNlID0gKENQREZfUmVmZXJlbmNlKilwQ29udGVudE9iajsNCi0JCUNQREZfT2JqZWN0KiBwRGlyZWN0T2JqID0gcFJlZmVyZW5jZS0+R2V0RGlyZWN0KCk7DQotCQlpZihwRGlyZWN0T2JqICE9IE5VTEwpDQotCQl7DQotCQkJaWYocERpcmVjdE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9BUlJBWSkNCi0JCQl7DQotCQkJCXBDb250ZW50QXJyYXkgPSAoQ1BERl9BcnJheSopcERpcmVjdE9iajsNCi0JCQkJQ1BERl9SZWZlcmVuY2UqIHBSZWYgPSBGWF9ORVcgQ1BERl9SZWZlcmVuY2UocERvYywgcFN0cmVhbS0+R2V0T2JqTnVtKCkpOw0KLQkJCQlwQ29udGVudEFycmF5LT5JbnNlcnRBdCgwLCBwUmVmKTsNCi0JCQkJDQotCQkJfQ0KLQkJCWVsc2UgaWYocERpcmVjdE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9TVFJFQU0pDQotCQkJew0KLQkJCQlwQ29udGVudEFycmF5ID0gRlhfTkVXIENQREZfQXJyYXkoKTsNCi0JCQkJcENvbnRlbnRBcnJheS0+QWRkUmVmZXJlbmNlKHBEb2MscFN0cmVhbS0+R2V0T2JqTnVtKCkpOw0KLQkJCQlwQ29udGVudEFycmF5LT5BZGRSZWZlcmVuY2UocERvYyxwRGlyZWN0T2JqLT5HZXRPYmpOdW0oKSk7DQotCQkJCXBQYWdlRGljLT5TZXRBdFJlZmVyZW5jZSgiQ29udGVudHMiLCBwRG9jLCBwRG9jLT5BZGRJbmRpcmVjdE9iamVjdChwQ29udGVudEFycmF5KSk7DQotCQkJfQ0KLQkJfQ0KLQl9CQ0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZl90cmFuc2Zvcm1wYWdlLmgiCisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VfU2V0TWVkaWFCb3goRlBERl9QQUdFIHBhZ2UsIGZsb2F0IGxlZnQsIGZsb2F0IGJvdHRvbSwgZmxvYXQgcmlnaHQsIGZsb2F0IHRvcCkKK3sKKwlpZighcGFnZSkKKwkJcmV0dXJuOworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCUNQREZfRGljdGlvbmFyeSogcFBhZ2VEaWN0ID0gcFBhZ2UtPm1fcEZvcm1EaWN0OworCUNQREZfQXJyYXkqIHBNZWRpYUJveEFycmF5ID0gRlhfTkVXIENQREZfQXJyYXk7CisJcE1lZGlhQm94QXJyYXktPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIobGVmdCkpOworCXBNZWRpYUJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKGJvdHRvbSkpOworCXBNZWRpYUJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKEZYX0ZMT0FUKHJpZ2h0KSkpOworCXBNZWRpYUJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKEZYX0ZMT0FUKHRvcCkpKTsKKwkKKwlwUGFnZURpY3QtPlNldEF0KCJNZWRpYUJveCIsIHBNZWRpYUJveEFycmF5KTsKK30KKworCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX1NldENyb3BCb3goRlBERl9QQUdFIHBhZ2UsIGZsb2F0IGxlZnQsIGZsb2F0IGJvdHRvbSwgZmxvYXQgcmlnaHQsIGZsb2F0IHRvcCkKK3sKKwlpZighcGFnZSkKKwkJcmV0dXJuOworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCUNQREZfRGljdGlvbmFyeSogcFBhZ2VEaWN0ID0gcFBhZ2UtPm1fcEZvcm1EaWN0OworCUNQREZfQXJyYXkqIHBDcm9wQm94QXJyYXkgPSBGWF9ORVcgQ1BERl9BcnJheTsKKwlwQ3JvcEJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKGxlZnQpKTsKKwlwQ3JvcEJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKGJvdHRvbSkpOworCXBDcm9wQm94QXJyYXktPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIoRlhfRkxPQVQocmlnaHQpKSk7CisJcENyb3BCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcihGWF9GTE9BVCh0b3ApKSk7CisJCisJCisJcFBhZ2VEaWN0LT5TZXRBdCgiQ3JvcEJveCIsIHBDcm9wQm94QXJyYXkpOworfQorCisKK0RMTEVYUE9SVCBGWF9CT09MIFNURENBTEwgRlBERlBhZ2VfR2V0TWVkaWFCb3goRlBERl9QQUdFIHBhZ2UsIGZsb2F0KiBsZWZ0LCBmbG9hdCogYm90dG9tLCBmbG9hdCogcmlnaHQsIGZsb2F0KiB0b3ApCit7CisJaWYoIXBhZ2UpCisJCXJldHVybiBGQUxTRTsKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKwlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBQYWdlLT5tX3BGb3JtRGljdDsKKwlDUERGX0FycmF5KiBwQXJyYXkgPSBwUGFnZURpY3QtPkdldEFycmF5KCJNZWRpYUJveCIpOworCWlmKHBBcnJheSkKKwl7CisJCSpsZWZ0ID0gcEFycmF5LT5HZXRGbG9hdCgwKTsKKwkJKmJvdHRvbSA9IHBBcnJheS0+R2V0RmxvYXQoMSk7CisJCSpyaWdodCA9IHBBcnJheS0+R2V0RmxvYXQoMik7CisJCSp0b3AgPSBwQXJyYXktPkdldEZsb2F0KDMpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VfR2V0Q3JvcEJveChGUERGX1BBR0UgcGFnZSwgZmxvYXQqIGxlZnQsIGZsb2F0KiBib3R0b20sIGZsb2F0KiByaWdodCwgZmxvYXQqIHRvcCkKK3sKKwlpZighcGFnZSkKKwkJcmV0dXJuIEZBTFNFOworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCUNQREZfRGljdGlvbmFyeSogcFBhZ2VEaWN0ID0gcFBhZ2UtPm1fcEZvcm1EaWN0OworCUNQREZfQXJyYXkqIHBBcnJheSA9IHBQYWdlRGljdC0+R2V0QXJyYXkoIkNyb3BCb3giKTsKKwlpZihwQXJyYXkpCisJeworCQkqbGVmdCA9IHBBcnJheS0+R2V0RmxvYXQoMCk7CisJCSpib3R0b20gPSBwQXJyYXktPkdldEZsb2F0KDEpOworCQkqcmlnaHQgPSBwQXJyYXktPkdldEZsb2F0KDIpOworCQkqdG9wID0gcEFycmF5LT5HZXRGbG9hdCgzKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCXJldHVybiBGQUxTRTsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlX1RyYW5zRm9ybVdpdGhDbGlwKEZQREZfUEFHRSBwYWdlLCBGU19NQVRSSVgqIG1hdHJpeCwgRlNfUkVDVEYqIGNsaXBSZWN0KQoreworCWlmKCFwYWdlKQorCQlyZXR1cm4gRkFMU0U7CisKKwlDRlhfQnl0ZVRleHRCdWYgdGV4dEJ1ZjsKKwl0ZXh0QnVmPDwicSAiOworCUNGWF9GbG9hdFJlY3QgcmVjdChjbGlwUmVjdC0+bGVmdCwgY2xpcFJlY3QtPmJvdHRvbSwgY2xpcFJlY3QtPnJpZ2h0LCBjbGlwUmVjdC0+dG9wKTsKKwlyZWN0Lk5vcm1hbGl6ZSgpOworCUNGWF9CeXRlU3RyaW5nIGJzQ2xpcHBpbmc7CisJYnNDbGlwcGluZy5Gb3JtYXQoIiVmICVmICVmICVmIHJlIFcqIG4gIiwgcmVjdC5sZWZ0LCByZWN0LmJvdHRvbSwgcmVjdC5XaWR0aCgpLCByZWN0LkhlaWdodCgpKTsKKwl0ZXh0QnVmPDxic0NsaXBwaW5nOworCisJQ0ZYX0J5dGVTdHJpbmcgYnNNYXRpeDsKKwlic01hdGl4LkZvcm1hdCgiJWYgJWYgJWYgJWYgJWYgJWYgY20gIiwgbWF0cml4LT5hLCBtYXRyaXgtPmIsbWF0cml4LT5jLG1hdHJpeC0+ZCxtYXRyaXgtPmUsbWF0cml4LT5mKTsKKwl0ZXh0QnVmPDxic01hdGl4OworCQorCisJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7CisJQ1BERl9EaWN0aW9uYXJ5KiBwUGFnZURpYyA9IHBQYWdlLT5tX3BGb3JtRGljdDsKKwlDUERGX09iamVjdCogcENvbnRlbnRPYmogPSBwUGFnZURpYy0+R2V0RWxlbWVudCgiQ29udGVudHMiKTsKKwlpZighcENvbnRlbnRPYmopCisJCXBDb250ZW50T2JqID0gcFBhZ2VEaWMtPkdldEFycmF5KCJDb250ZW50cyIpOworCWlmKCFwQ29udGVudE9iaikKKwkJcmV0dXJuIEZBTFNFOworCQorCUNQREZfRGljdGlvbmFyeSogcERpYyA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7CisJQ1BERl9TdHJlYW0qIHBTdHJlYW0gPSBGWF9ORVcgQ1BERl9TdHJlYW0oTlVMTCwwLCBwRGljKTsKKwlwU3RyZWFtLT5TZXREYXRhKHRleHRCdWYuR2V0QnVmZmVyKCksIHRleHRCdWYuR2V0U2l6ZSgpLCBGQUxTRSwgRkFMU0UpOworCUNQREZfRG9jdW1lbnQqIHBEb2MgPSBwUGFnZS0+bV9wRG9jdW1lbnQ7CisJaWYoIXBEb2MpCisJCXJldHVybiBGQUxTRTsKKwlwRG9jLT5BZGRJbmRpcmVjdE9iamVjdChwU3RyZWFtKTsKKworCXBEaWMgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5OworCUNQREZfU3RyZWFtKiBwRW5kU3RyZWFtID0gRlhfTkVXIENQREZfU3RyZWFtKE5VTEwsMCwgcERpYyk7CisJcEVuZFN0cmVhbS0+U2V0RGF0YSgoRlhfTFBDQllURSkiIFEiLCAyLCBGQUxTRSwgRkFMU0UpOworCXBEb2MtPkFkZEluZGlyZWN0T2JqZWN0KHBFbmRTdHJlYW0pOworCQorCUNQREZfQXJyYXkqIHBDb250ZW50QXJyYXkgPSBOVUxMOworCWlmIChwQ29udGVudE9iaiAmJiBwQ29udGVudE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9BUlJBWSkKKwl7CisJCXBDb250ZW50QXJyYXkgPSAoQ1BERl9BcnJheSopcENvbnRlbnRPYmo7CisJCUNQREZfUmVmZXJlbmNlKiBwUmVmID0gRlhfTkVXIENQREZfUmVmZXJlbmNlKHBEb2MsIHBTdHJlYW0tPkdldE9iak51bSgpKTsKKwkJcENvbnRlbnRBcnJheS0+SW5zZXJ0QXQoMCwgcFJlZik7CisJCXBDb250ZW50QXJyYXktPkFkZFJlZmVyZW5jZShwRG9jLHBFbmRTdHJlYW0pOworCQkKKwl9CisJZWxzZSBpZihwQ29udGVudE9iaiAmJiBwQ29udGVudE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9SRUZFUkVOQ0UpCisJeworCQlDUERGX1JlZmVyZW5jZSogcFJlZmVyZW5jZSA9IChDUERGX1JlZmVyZW5jZSopcENvbnRlbnRPYmo7CisJCUNQREZfT2JqZWN0KiBwRGlyZWN0T2JqID0gcFJlZmVyZW5jZS0+R2V0RGlyZWN0KCk7CisJCWlmKHBEaXJlY3RPYmogIT0gTlVMTCkKKwkJeworCQkJaWYocERpcmVjdE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9BUlJBWSkKKwkJCXsKKwkJCQlwQ29udGVudEFycmF5ID0gKENQREZfQXJyYXkqKXBEaXJlY3RPYmo7CisJCQkJQ1BERl9SZWZlcmVuY2UqIHBSZWYgPSBGWF9ORVcgQ1BERl9SZWZlcmVuY2UocERvYywgcFN0cmVhbS0+R2V0T2JqTnVtKCkpOworCQkJCXBDb250ZW50QXJyYXktPkluc2VydEF0KDAsIHBSZWYpOworCQkJCXBDb250ZW50QXJyYXktPkFkZFJlZmVyZW5jZShwRG9jLHBFbmRTdHJlYW0pOworCQkJCQorCQkJfQorCQkJZWxzZSBpZihwRGlyZWN0T2JqLT5HZXRUeXBlKCkgPT0gUERGT0JKX1NUUkVBTSkKKwkJCXsKKwkJCQlwQ29udGVudEFycmF5ID0gRlhfTkVXIENQREZfQXJyYXkoKTsKKwkJCQlwQ29udGVudEFycmF5LT5BZGRSZWZlcmVuY2UocERvYyxwU3RyZWFtLT5HZXRPYmpOdW0oKSk7CisJCQkJcENvbnRlbnRBcnJheS0+QWRkUmVmZXJlbmNlKHBEb2MscERpcmVjdE9iai0+R2V0T2JqTnVtKCkpOworCQkJCXBDb250ZW50QXJyYXktPkFkZFJlZmVyZW5jZShwRG9jLCBwRW5kU3RyZWFtKTsKKwkJCQlwUGFnZURpYy0+U2V0QXRSZWZlcmVuY2UoIkNvbnRlbnRzIiwgcERvYywgcERvYy0+QWRkSW5kaXJlY3RPYmplY3QocENvbnRlbnRBcnJheSkpOworCQkJfQorCQl9CisJfQkKKworCS8vTmVlZCB0byB0cmFuc2Zvcm0gdGhlIHBhdHRlcm5zIGFzIHdlbGwuCisJQ1BERl9EaWN0aW9uYXJ5KiBwUmVzID0gcFBhZ2VEaWMtPkdldERpY3QoRlhfQlNUUkMoIlJlc291cmNlcyIpKTsKKwlpZihwUmVzKQorCXsKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwUGF0dGVuRGljdCA9IHBSZXMtPkdldERpY3QoRlhfQlNUUkMoIlBhdHRlcm4iKSk7CisJCWlmKHBQYXR0ZW5EaWN0KQorCQl7CisJCQlGWF9QT1NJVElPTiBwb3MgPSBwUGF0dGVuRGljdC0+R2V0U3RhcnRQb3MoKTsKKwkJCXdoaWxlKHBvcykKKwkJCXsKKwkJCQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gTlVMTDsKKwkJCQlDRlhfQnl0ZVN0cmluZyBrZXk7CisJCQkJQ1BERl9PYmplY3QqIHBPYmogPSBwUGF0dGVuRGljdC0+R2V0TmV4dEVsZW1lbnQocG9zLCBrZXkpOworCQkJCWlmKHBPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfUkVGRVJFTkNFKQorCQkJCQlwT2JqID0gcE9iai0+R2V0RGlyZWN0KCk7CisJCQkJaWYocE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9ESUNUSU9OQVJZKQorCQkJCXsKKwkJCQkJcERpY3QgPSAoQ1BERl9EaWN0aW9uYXJ5KilwT2JqOworCQkJCX0KKwkJCQllbHNlIGlmKHBPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfU1RSRUFNKQorCQkJCXsKKwkJCQkJcERpY3QgPSAoKENQREZfU3RyZWFtKilwT2JqKS0+R2V0RGljdCgpOworCQkJCX0KKwkJCQllbHNlCisJCQkJCWNvbnRpbnVlOworCQkJCQorCQkJCUNGWF9BZmZpbmVNYXRyaXggbSA9IHBEaWN0LT5HZXRNYXRyaXgoRlhfQlNUUkMoIk1hdHJpeCIpKTsKKwkJCQlDRlhfQWZmaW5lTWF0cml4IHQgPSAqKENGWF9BZmZpbmVNYXRyaXgqKW1hdHJpeDsKKwkJCQltLkNvbmNhdCh0KTsKKwkJCQlwRGljdC0+U2V0QXRNYXRyaXgoRlhfQlNUUkMoIk1hdHJpeCIpLCBtKTsKKwkJCX0KKwkJfQorCX0KKworCXJldHVybiBUUlVFOworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlT2JqX1RyYW5zZm9ybUNsaXBQYXRoKEZQREZfUEFHRU9CSkVDVCBwYWdlX29iamVjdCxkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKQoreworCUNQREZfUGFnZU9iamVjdCogcFBhZ2VPYmogPSAoQ1BERl9QYWdlT2JqZWN0KilwYWdlX29iamVjdDsKKwlpZihwUGFnZU9iaiA9PSBOVUxMKQorCQlyZXR1cm47CisJQ0ZYX0FmZmluZU1hdHJpeCBtYXRyaXgoKEZYX0ZMT0FUKWEsKEZYX0ZMT0FUKWIsKEZYX0ZMT0FUKWMsKEZYX0ZMT0FUKWQsKEZYX0ZMT0FUKWUsKEZYX0ZMT0FUKWYpOworCQorCS8vU3BlY2lhbCB0cmVhdG1lbnQgdG8gc2hhZGluZyBvYmplY3QsIGJlY2F1c2UgdGhlIENsaXBQYXRoIGZvciBzaGFkaW5nIG9iamVjdCBpcyBhbHJlYWR5IHRyYW5zZm9ybWVkLgorCWlmKHBQYWdlT2JqLT5tX1R5cGUgIT0gUERGUEFHRV9TSEFESU5HKQorCQlwUGFnZU9iai0+VHJhbnNmb3JtQ2xpcFBhdGgobWF0cml4KTsKKwlwUGFnZU9iai0+VHJhbnNmb3JtR2VuZXJhbFN0YXRlKG1hdHJpeCk7Cit9CisKKworRExMRVhQT1JUIEZQREZfQ0xJUFBBVEggU1REQ0FMTCBGUERGX0NyZWF0ZUNsaXBQYXRoKGZsb2F0IGxlZnQsIGZsb2F0IGJvdHRvbSwgZmxvYXQgcmlnaHQsIGZsb2F0IHRvcCkKK3sKKwlDUERGX0NsaXBQYXRoKiBwTmV3Q2xpcFBhdGggPSAgRlhfTkVXIENQREZfQ2xpcFBhdGgoKTsKKwlwTmV3Q2xpcFBhdGgtPkdldE1vZGlmeSgpOworCUNQREZfUGF0aCBQYXRoOworCVBhdGguR2V0TW9kaWZ5KCk7CisJUGF0aC5BcHBlbmRSZWN0KGxlZnQsIGJvdHRvbSwgcmlnaHQsIHRvcCk7CisJcE5ld0NsaXBQYXRoLT5BcHBlbmRQYXRoKFBhdGgsIEZYRklMTF9BTFRFUk5BVEUsIEZBTFNFKTsKKwlyZXR1cm4gcE5ld0NsaXBQYXRoOworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfRGVzdHJveUNsaXBQYXRoKEZQREZfQ0xJUFBBVEggY2xpcFBhdGgpCit7CisJaWYoY2xpcFBhdGgpCisJCWRlbGV0ZSAoQ1BERl9DbGlwUGF0aCopY2xpcFBhdGg7Cit9CisKK3ZvaWQgT3V0cHV0UGF0aChDRlhfQnl0ZVRleHRCdWYmIGJ1ZiwgQ1BERl9QYXRoIHBhdGgpCit7CisJY29uc3QgQ0ZYX1BhdGhEYXRhKiBwUGF0aERhdGEgPSBwYXRoOworCWlmIChwUGF0aERhdGEgPT0gTlVMTCkgcmV0dXJuOworCQorCUZYX1BBVEhQT0lOVCogcFBvaW50cyA9IHBQYXRoRGF0YS0+R2V0UG9pbnRzKCk7CisJCisJaWYgKHBhdGguSXNSZWN0KCkpIHsKKwkJYnVmIDw8IChwUG9pbnRzWzBdLm1fUG9pbnRYKSA8PCAiICIgPDwgKHBQb2ludHNbMF0ubV9Qb2ludFkpIDw8ICIgIiAKKwkJCTw8IChwUG9pbnRzWzJdLm1fUG9pbnRYIC0gcFBvaW50c1swXS5tX1BvaW50WCkgPDwgIiAiIAorCQkJPDwgKHBQb2ludHNbMl0ubV9Qb2ludFkgLSBwUG9pbnRzWzBdLm1fUG9pbnRZKSA8PCAiIHJlXG4iOworCQlyZXR1cm47CisJfQorCQorCUNGWF9CeXRlU3RyaW5nIHRlbXA7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBwUGF0aERhdGEtPkdldFBvaW50Q291bnQoKTsgaSArKykgeworCQlidWYgPDwgKHBQb2ludHNbaV0ubV9Qb2ludFgpIDw8ICIgIiA8PCAocFBvaW50c1tpXS5tX1BvaW50WSk7CisJCWludCBwb2ludF90eXBlID0gcFBvaW50c1tpXS5tX0ZsYWcgJiBGWFBUX1RZUEU7CisJCWlmIChwb2ludF90eXBlID09IEZYUFRfTU9WRVRPKQorCQkJYnVmIDw8ICIgbVxuIjsKKwkJZWxzZSBpZiAocG9pbnRfdHlwZSA9PSBGWFBUX0JFWklFUlRPKSB7CisJCQlidWYgPDwgIiAiIDw8IChwUG9pbnRzW2krMV0ubV9Qb2ludFgpIDw8ICIgIiA8PCAocFBvaW50c1tpKzFdLm1fUG9pbnRZKSA8PCAiICIgPDwgCisJCQkJKHBQb2ludHNbaSsyXS5tX1BvaW50WCkgPDwgIiAiIDw8IChwUG9pbnRzW2krMl0ubV9Qb2ludFkpOworCQkJaWYgKHBQb2ludHNbaSsyXS5tX0ZsYWcgJiBGWFBUX0NMT1NFRklHVVJFKQorCQkJCWJ1ZiA8PCAiIGMgaFxuIjsKKwkJCWVsc2UKKwkJCQlidWYgPDwgIiBjXG4iOworCQkJaSArPSAyOworCQl9IGVsc2UgaWYgKHBvaW50X3R5cGUgPT0gRlhQVF9MSU5FVE8pIHsKKwkJCWlmIChwUG9pbnRzW2ldLm1fRmxhZyAmIEZYUFRfQ0xPU0VGSUdVUkUpCisJCQkJYnVmIDw8ICIgbCBoXG4iOworCQkJZWxzZQorCQkJCWJ1ZiA8PCAiIGxcbiI7CisJCX0KKwl9Cit9CisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VfSW5zZXJ0Q2xpcFBhdGgoRlBERl9QQUdFIHBhZ2UsRlBERl9DTElQUEFUSCBjbGlwUGF0aCkKK3sKKwlpZighcGFnZSkKKwkJcmV0dXJuOworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCUNQREZfRGljdGlvbmFyeSogcFBhZ2VEaWMgPSBwUGFnZS0+bV9wRm9ybURpY3Q7CisJQ1BERl9PYmplY3QqIHBDb250ZW50T2JqID0gcFBhZ2VEaWMtPkdldEVsZW1lbnQoIkNvbnRlbnRzIik7CisJaWYoIXBDb250ZW50T2JqKQorCQlwQ29udGVudE9iaiA9IHBQYWdlRGljLT5HZXRBcnJheSgiQ29udGVudHMiKTsKKwlpZighcENvbnRlbnRPYmopCisJCXJldHVybjsKKworCUNGWF9CeXRlVGV4dEJ1ZiBzdHJDbGlwOworCUNQREZfQ2xpcFBhdGgqIHBDbGlwUGF0aCA9IChDUERGX0NsaXBQYXRoKiljbGlwUGF0aDsKKwlGWF9EV09SRCBpOworCWZvciAoaSA9IDA7IGkgPCBwQ2xpcFBhdGgtPkdldFBhdGhDb3VudCgpOyBpICsrKSB7CisJCUNQREZfUGF0aCBwYXRoID0gcENsaXBQYXRoLT5HZXRQYXRoKGkpOworCQlpbnQgaUNsaXBUeXBlID0gcENsaXBQYXRoLT5HZXRDbGlwVHlwZShpKTsKKwkJaWYgKHBhdGguR2V0UG9pbnRDb3VudCgpID09IDApIHsKKwkJCS8vIEVtcHR5IGNsaXBwaW5nICh0b3RhbGx5IGNsaXBwZWQgb3V0KQorCQkJc3RyQ2xpcCA8PCAiMCAwIG0gVyBuICI7CisJCX0gZWxzZSB7CisJCQlPdXRwdXRQYXRoKHN0ckNsaXAsIHBhdGgpOworCQkJaWYgKGlDbGlwVHlwZSA9PSBGWEZJTExfV0lORElORykKKwkJCQlzdHJDbGlwIDw8ICJXIG5cbiI7CisJCQllbHNlCisJCQkJc3RyQ2xpcCA8PCAiVyogblxuIjsKKwkJfQorCX0KKwlDUERGX0RpY3Rpb25hcnkqIHBEaWMgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5OworCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gRlhfTkVXIENQREZfU3RyZWFtKE5VTEwsMCwgcERpYyk7CisJcFN0cmVhbS0+U2V0RGF0YShzdHJDbGlwLkdldEJ1ZmZlcigpLCBzdHJDbGlwLkdldFNpemUoKSwgRkFMU0UsIEZBTFNFKTsKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gcFBhZ2UtPm1fcERvY3VtZW50OworCWlmKCFwRG9jKQorCQlyZXR1cm47CisJcERvYy0+QWRkSW5kaXJlY3RPYmplY3QocFN0cmVhbSk7CisJCisJQ1BERl9BcnJheSogcENvbnRlbnRBcnJheSA9IE5VTEw7CisJaWYgKHBDb250ZW50T2JqICYmIHBDb250ZW50T2JqLT5HZXRUeXBlKCkgPT0gUERGT0JKX0FSUkFZKQorCXsKKwkJcENvbnRlbnRBcnJheSA9IChDUERGX0FycmF5KilwQ29udGVudE9iajsKKwkJQ1BERl9SZWZlcmVuY2UqIHBSZWYgPSBGWF9ORVcgQ1BERl9SZWZlcmVuY2UocERvYywgcFN0cmVhbS0+R2V0T2JqTnVtKCkpOworCQlwQ29udGVudEFycmF5LT5JbnNlcnRBdCgwLCBwUmVmKTsKKwkJCisJfQorCWVsc2UgaWYocENvbnRlbnRPYmogJiYgcENvbnRlbnRPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfUkVGRVJFTkNFKQorCXsKKwkJQ1BERl9SZWZlcmVuY2UqIHBSZWZlcmVuY2UgPSAoQ1BERl9SZWZlcmVuY2UqKXBDb250ZW50T2JqOworCQlDUERGX09iamVjdCogcERpcmVjdE9iaiA9IHBSZWZlcmVuY2UtPkdldERpcmVjdCgpOworCQlpZihwRGlyZWN0T2JqICE9IE5VTEwpCisJCXsKKwkJCWlmKHBEaXJlY3RPYmotPkdldFR5cGUoKSA9PSBQREZPQkpfQVJSQVkpCisJCQl7CisJCQkJcENvbnRlbnRBcnJheSA9IChDUERGX0FycmF5KilwRGlyZWN0T2JqOworCQkJCUNQREZfUmVmZXJlbmNlKiBwUmVmID0gRlhfTkVXIENQREZfUmVmZXJlbmNlKHBEb2MsIHBTdHJlYW0tPkdldE9iak51bSgpKTsKKwkJCQlwQ29udGVudEFycmF5LT5JbnNlcnRBdCgwLCBwUmVmKTsKKwkJCQkKKwkJCX0KKwkJCWVsc2UgaWYocERpcmVjdE9iai0+R2V0VHlwZSgpID09IFBERk9CSl9TVFJFQU0pCisJCQl7CisJCQkJcENvbnRlbnRBcnJheSA9IEZYX05FVyBDUERGX0FycmF5KCk7CisJCQkJcENvbnRlbnRBcnJheS0+QWRkUmVmZXJlbmNlKHBEb2MscFN0cmVhbS0+R2V0T2JqTnVtKCkpOworCQkJCXBDb250ZW50QXJyYXktPkFkZFJlZmVyZW5jZShwRG9jLHBEaXJlY3RPYmotPkdldE9iak51bSgpKTsKKwkJCQlwUGFnZURpYy0+U2V0QXRSZWZlcmVuY2UoIkNvbnRlbnRzIiwgcERvYywgcERvYy0+QWRkSW5kaXJlY3RPYmplY3QocENvbnRlbnRBcnJheSkpOworCQkJfQorCQl9CisJfQkKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnBkZmRvYy5jcHAgYi9mcGRmc2RrL3NyYy9mcGRmZG9jLmNwcAppbmRleCBkNWQ5MDAwLi40ZmE2YmEyIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mcGRmZG9jLmNwcAorKysgYi9mcGRmc2RrL3NyYy9mcGRmZG9jLmNwcApAQCAtMSwyNTkgKzEsMjU5IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZkb2MuaCINCi0NCi1zdGF0aWMgaW50IHRoaXNfbW9kdWxlID0gMDsNCi0NCi1zdGF0aWMgQ1BERl9Cb29rbWFyayBGaW5kQm9va21hcmsoQ1BERl9Cb29rbWFya1RyZWUmIHRyZWUsIENQREZfQm9va21hcmsgVGhpcywgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHRpdGxlKQ0KLXsNCi0JaWYgKFRoaXMgIT0gTlVMTCkgew0KLQkJLy8gRmlyc3QgY2hlY2sgdGhpcyBpdGVtDQotCQlDRlhfV2lkZVN0cmluZyB0aGlzX3RpdGxlID0gVGhpcy5HZXRUaXRsZSgpOw0KLQkJaWYgKHRoaXNfdGl0bGUuQ29tcGFyZU5vQ2FzZSh0aXRsZSkgPT0gMCkNCi0JCQlyZXR1cm4gVGhpczsNCi0JfQ0KLQkvLyBnbyBpbnRvIGNoaWxkcmVuIGl0ZW1zDQotCUNQREZfQm9va21hcmsgQ2hpbGQgPSB0cmVlLkdldEZpcnN0Q2hpbGQoVGhpcyk7DQotCXdoaWxlIChDaGlsZCAhPSBOVUxMKSB7DQotCQkvLyBjaGVjayBpZiB0aGlzIGl0ZW0NCi0JCUNQREZfQm9va21hcmsgRm91bmQgPSBGaW5kQm9va21hcmsodHJlZSwgQ2hpbGQsIHRpdGxlKTsNCi0JCWlmIChGb3VuZCkgcmV0dXJuIEZvdW5kOw0KLQkJQ2hpbGQgPSB0cmVlLkdldE5leHRTaWJsaW5nKENoaWxkKTsNCi0JfQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PS01BUksgU1REQ0FMTCBGUERGQm9va21hcmtfRmluZChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBGUERGX1dJREVTVFJJTkcgdGl0bGUpDQotew0KLQlpZiAoZG9jdW1lbnQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7DQotCWlmICh0aXRsZSA9PSBOVUxMIHx8IHRpdGxlWzBdID09IDApIHJldHVybiBOVUxMOw0KLQ0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50Ow0KLQlDUERGX0Jvb2ttYXJrVHJlZSB0cmVlKHBEb2MpOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyB3c3RyID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21VVEYxNkxFKHRpdGxlKTsNCi0JcmV0dXJuIEZpbmRCb29rbWFyayh0cmVlLCBOVUxMLCB3c3RyKTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZCb29rbWFya19HZXREZXN0KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfQk9PS01BUksgYm9va21hcmspDQotew0KLQlpZiAoZG9jdW1lbnQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7DQotCWlmIChib29rbWFyayA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0NCi0JQ1BERl9Cb29rbWFyayBCb29rbWFyayA9IChDUERGX0RpY3Rpb25hcnkqKWJvb2ttYXJrOw0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50Ow0KLQlDUERGX0Rlc3QgZGVzdCA9IEJvb2ttYXJrLkdldERlc3QocERvYyk7DQotCWlmIChkZXN0ICE9IE5VTEwpIHJldHVybiBkZXN0Ow0KLQ0KLQkvLyBJZiB0aGlzIGJvb2ttYXJrIGlzIG5vdCBkaXJlY3RseSBhc3NvY2lhdGVkIHdpdGggYSBkZXN0LCB3ZSB0cnkgdG8gZ2V0IGFjdGlvbg0KLQlDUERGX0FjdGlvbiBBY3Rpb24gPSBCb29rbWFyay5HZXRBY3Rpb24oKTsNCi0JaWYgKEFjdGlvbiA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0JcmV0dXJuIEFjdGlvbi5HZXREZXN0KHBEb2MpOw0KLX0NCi0NCi1ETExFWFBPUlQgRlBERl9BQ1RJT04gU1REQ0FMTCBGUERGQm9va21hcmtfR2V0QWN0aW9uKEZQREZfQk9PS01BUksgYm9va21hcmspDQotew0KLQlpZiAoYm9va21hcmsgPT0gTlVMTCkgcmV0dXJuIE5VTEw7DQotDQotCUNQREZfQm9va21hcmsgQm9va21hcmsgPSAoQ1BERl9EaWN0aW9uYXJ5Kilib29rbWFyazsNCi0JcmV0dXJuIEJvb2ttYXJrLkdldEFjdGlvbigpOw0KLX0NCi0NCi1ETExFWFBPUlQgdW5zaWduZWQgbG9uZyBTVERDQUxMIEZQREZBY3Rpb25fR2V0VHlwZShGUERGX0FDVElPTiBhY3Rpb24pDQotew0KLQlpZiAoYWN0aW9uID09IE5VTEwpIHJldHVybiAwOw0KLQ0KLQlDUERGX0FjdGlvbiBBY3Rpb24gPSAoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb247DQotCUNQREZfQWN0aW9uOjpBY3Rpb25UeXBlIHR5cGUgPSBBY3Rpb24uR2V0VHlwZSgpOw0KLQlzd2l0Y2ggKHR5cGUpIHsNCi0JY2FzZSBDUERGX0FjdGlvbjo6R29UbzoNCi0JCXJldHVybiBQREZBQ1RJT05fR09UTzsNCi0JY2FzZSBDUERGX0FjdGlvbjo6R29Ub1I6DQotCQlyZXR1cm4gUERGQUNUSU9OX1JFTU9URUdPVE87DQotCWNhc2UgQ1BERl9BY3Rpb246OlVSSToNCi0JCXJldHVybiBQREZBQ1RJT05fVVJJOw0KLQljYXNlIENQREZfQWN0aW9uOjpMYXVuY2g6DQotCQlyZXR1cm4gUERGQUNUSU9OX0xBVU5DSDsNCi0JZGVmYXVsdDoNCi0JCXJldHVybiBQREZBQ1RJT05fVU5TVVBQT1JURUQ7DQotCX0NCi0JcmV0dXJuIFBERkFDVElPTl9VTlNVUFBPUlRFRDsNCi19DQotDQotRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZBY3Rpb25fR2V0RGVzdChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBGUERGX0FDVElPTiBhY3Rpb24pDQotew0KLQlpZiAoZG9jdW1lbnQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7DQotCWlmIChhY3Rpb24gPT0gTlVMTCkgcmV0dXJuIE5VTEw7DQotCUNQREZfRG9jdW1lbnQqIHBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7DQotCUNQREZfQWN0aW9uIEFjdGlvbiA9IChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbjsNCi0NCi0JcmV0dXJuIEFjdGlvbi5HZXREZXN0KHBEb2MpOw0KLX0NCi0NCi1ETExFWFBPUlQgdW5zaWduZWQgbG9uZyBTVERDQUxMIEZQREZBY3Rpb25fR2V0VVJJUGF0aChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBGUERGX0FDVElPTiBhY3Rpb24sIA0KLQkJCQkJCQkJCQkJICB2b2lkKiBidWZmZXIsIHVuc2lnbmVkIGxvbmcgYnVmbGVuKQ0KLXsNCi0JaWYgKGRvY3VtZW50ID09IE5VTEwpIHJldHVybiAwOw0KLQlpZiAoYWN0aW9uID09IE5VTEwpIHJldHVybiAwOw0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50Ow0KLQlDUERGX0FjdGlvbiBBY3Rpb24gPSAoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb247DQotDQotCUNGWF9CeXRlU3RyaW5nIHBhdGggPSBBY3Rpb24uR2V0VVJJKHBEb2MpOw0KLQl1bnNpZ25lZCBsb25nIGxlbiA9IHBhdGguR2V0TGVuZ3RoKCkgKyAxOw0KLQlpZiAoYnVmZmVyICE9IE5VTEwgJiYgYnVmbGVuID49IGxlbikNCi0JCUZYU1lTX21lbWNweShidWZmZXIsIChGWF9MUENTVFIpcGF0aCwgbGVuKTsNCi0JcmV0dXJuIGxlbjsNCi19DQotDQotRExMRVhQT1JUIHVuc2lnbmVkIGxvbmcgU1REQ0FMTCBGUERGRGVzdF9HZXRQYWdlSW5kZXgoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9ERVNUIGRlc3QpDQotew0KLQlpZiAoZG9jdW1lbnQgPT0gTlVMTCkgcmV0dXJuIDA7DQotCWlmIChkZXN0ID09IE5VTEwpIHJldHVybiAwOw0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50Ow0KLQlDUERGX0Rlc3QgRGVzdCA9IChDUERGX0FycmF5KilkZXN0Ow0KLQ0KLQlyZXR1cm4gRGVzdC5HZXRQYWdlSW5kZXgocERvYyk7DQotfQ0KLQ0KLXN0YXRpYyB2b2lkIFJlbGVhc2VMaW5rTGlzdChGWF9MUFZPSUQgZGF0YSkNCi17DQotCWRlbGV0ZSAoQ1BERl9MaW5rTGlzdCopZGF0YTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfTElOSyBTVERDQUxMIEZQREZMaW5rX0dldExpbmtBdFBvaW50KEZQREZfUEFHRSBwYWdlLCBkb3VibGUgeCwgZG91YmxlIHkpDQotew0KLQlpZiAocGFnZSA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotDQotCS8vIExpbmsgbGlzdCBpcyBzdG9yZWQgd2l0aCB0aGUgZG9jdW1lbnQNCi0JQ1BERl9Eb2N1bWVudCogcERvYyA9IHBQYWdlLT5tX3BEb2N1bWVudDsNCi0JQ1BERl9MaW5rTGlzdCogcExpbmtMaXN0ID0gKENQREZfTGlua0xpc3QqKXBEb2MtPkdldFByaXZhdGVEYXRhKCZ0aGlzX21vZHVsZSk7DQotCWlmIChwTGlua0xpc3QgPT0gTlVMTCkgew0KLQkJcExpbmtMaXN0ID0gRlhfTkVXIENQREZfTGlua0xpc3QocERvYyk7DQotCQlwRG9jLT5TZXRQcml2YXRlRGF0YSgmdGhpc19tb2R1bGUsIHBMaW5rTGlzdCwgUmVsZWFzZUxpbmtMaXN0KTsNCi0JfQ0KLQ0KLQlyZXR1cm4gcExpbmtMaXN0LT5HZXRMaW5rQXRQb2ludChwUGFnZSwgKEZYX0ZMT0FUKXgsIChGWF9GTE9BVCl5KTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZMaW5rX0dldERlc3QoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9MSU5LIGxpbmspDQotew0KLQlpZiAoZG9jdW1lbnQgPT0gTlVMTCkgcmV0dXJuIE5VTEw7DQotCUNQREZfRG9jdW1lbnQqIHBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7DQotCWlmIChsaW5rID09IE5VTEwpIHJldHVybiBOVUxMOw0KLQlDUERGX0xpbmsgTGluayA9IChDUERGX0RpY3Rpb25hcnkqKWxpbms7DQotDQotCUZQREZfREVTVCBkZXN0ID0gTGluay5HZXREZXN0KHBEb2MpOw0KLQlpZiAoZGVzdCkgcmV0dXJuIGRlc3Q7DQotDQotCS8vIElmIHRoaXMgbGluayBpcyBub3QgZGlyZWN0bHkgYXNzb2NpYXRlZCB3aXRoIGEgZGVzdCwgd2UgdHJ5IHRvIGdldCBhY3Rpb24NCi0JQ1BERl9BY3Rpb24gQWN0aW9uID0gTGluay5HZXRBY3Rpb24oKTsNCi0JaWYgKEFjdGlvbiA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0JcmV0dXJuIEFjdGlvbi5HZXREZXN0KHBEb2MpOw0KLX0NCi0NCi1ETExFWFBPUlQgRlBERl9BQ1RJT04gU1REQ0FMTCBGUERGTGlua19HZXRBY3Rpb24oRlBERl9MSU5LIGxpbmspDQotew0KLQlpZiAobGluayA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0JQ1BERl9MaW5rIExpbmsgPSAoQ1BERl9EaWN0aW9uYXJ5KilsaW5rOw0KLQ0KLQlyZXR1cm4gTGluay5HZXRBY3Rpb24oKTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZMaW5rX0VudW1lcmF0ZShGUERGX1BBR0UgcGFnZSwgaW50KiBzdGFydFBvcywgRlBERl9MSU5LKiBsaW5rQW5ub3QpDQotew0KLQlpZighcGFnZSB8fCAhc3RhcnRQb3MgfHwgIWxpbmtBbm5vdCkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotCWlmKCFwUGFnZS0+bV9wRm9ybURpY3QpIHJldHVybiBGQUxTRTsNCi0JQ1BERl9BcnJheSogcEFubm90cyA9IHBQYWdlLT5tX3BGb3JtRGljdC0+R2V0QXJyYXkoIkFubm90cyIpOw0KLQlpZighcEFubm90cykgcmV0dXJuIEZBTFNFOw0KLQlmb3IgKGludCBpID0gKnN0YXJ0UG9zOyBpIDwgKGludClwQW5ub3RzLT5HZXRDb3VudCgpOyBpICsrKSB7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gKENQREZfRGljdGlvbmFyeSopcEFubm90cy0+R2V0RWxlbWVudFZhbHVlKGkpOw0KLQkJaWYgKHBEaWN0ID09IE5VTEwgfHwgcERpY3QtPkdldFR5cGUoKSAhPSBQREZPQkpfRElDVElPTkFSWSkgY29udGludWU7DQotCQlpZihwRGljdC0+R2V0U3RyaW5nKEZYX0JTVFJDKCJTdWJ0eXBlIikpLkVxdWFsKEZYX0JTVFJDKCJMaW5rIikpKQ0KLQkJew0KLQkJCSpzdGFydFBvcyA9IGkrMTsNCi0JCQkqbGlua0Fubm90ID0gKEZQREZfTElOSylwRGljdDsgDQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkxpbmtfR2V0QW5ub3RSZWN0KEZQREZfTElOSyBsaW5rQW5ub3QsIEZTX1JFQ1RGKiByZWN0KQ0KLXsNCi0JaWYoIWxpbmtBbm5vdCB8fCAhcmVjdCkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0ID0gKENQREZfRGljdGlvbmFyeSopbGlua0Fubm90Ow0KLQlDUERGX1JlY3QgcnQgPSBwQW5ub3REaWN0LT5HZXRSZWN0KEZYX0JTVFJDKCJSZWN0IikpOw0KLQlyZWN0LT5sZWZ0ID0gcnQubGVmdDsNCi0JcmVjdC0+Ym90dG9tID0gcnQuYm90dG9tOw0KLQlyZWN0LT5yaWdodCA9IHJ0LnJpZ2h0Ow0KLQlyZWN0LT50b3AgPSBydC50b3A7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERkxpbmtfQ291bnRRdWFkUG9pbnRzKEZQREZfTElOSyBsaW5rQW5ub3QpDQotew0KLQlpZighbGlua0Fubm90KQ0KLQkJcmV0dXJuIDA7DQotCUNQREZfRGljdGlvbmFyeSogcEFubm90RGljdCA9IChDUERGX0RpY3Rpb25hcnkqKWxpbmtBbm5vdDsNCi0JQ1BERl9BcnJheSogcEFycmF5ID0gcEFubm90RGljdC0+R2V0QXJyYXkoRlhfQlNUUkMoIlF1YWRQb2ludHMiKSk7DQotCWlmIChwQXJyYXkgPT0gTlVMTCkNCi0JCXJldHVybiAwOw0KLQllbHNlDQotCQlyZXR1cm4gcEFycmF5LT5HZXRDb3VudCgpIC8gODsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZMaW5rX0dldFF1YWRQb2ludHMoRlBERl9MSU5LIGxpbmtBbm5vdCwgaW50IHF1YWRJbmRleCwgRlNfUVVBRFBPSU5UU0YqIHF1YWRQb2ludHMpDQotew0KLQlpZighbGlua0Fubm90IHx8ICFxdWFkUG9pbnRzKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDUERGX0RpY3Rpb25hcnkqIHBBbm5vdERpY3QgPSAoQ1BERl9EaWN0aW9uYXJ5KilsaW5rQW5ub3Q7DQotCUNQREZfQXJyYXkqIHBBcnJheSA9IHBBbm5vdERpY3QtPkdldEFycmF5KEZYX0JTVFJDKCJRdWFkUG9pbnRzIikpOw0KLQlpZiAocEFycmF5KSB7DQotCQlpZiAoMCA+IHF1YWRJbmRleCB8fCBxdWFkSW5kZXggPj0gKGludClwQXJyYXktPkdldENvdW50KCkvOCB8fA0KLQkJCSgocXVhZEluZGV4KjgrNykgPj0gKGludClwQXJyYXktPkdldENvdW50KCkpKSByZXR1cm4gRkFMU0U7DQotCQlxdWFkUG9pbnRzLT54MSA9IHBBcnJheS0+R2V0TnVtYmVyKHF1YWRJbmRleCo4KTsNCi0JCXF1YWRQb2ludHMtPnkxID0gcEFycmF5LT5HZXROdW1iZXIocXVhZEluZGV4KjgrMSk7DQotCQlxdWFkUG9pbnRzLT54MiA9IHBBcnJheS0+R2V0TnVtYmVyKHF1YWRJbmRleCo4KzIpOw0KLQkJcXVhZFBvaW50cy0+eTIgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCszKTsNCi0JCXF1YWRQb2ludHMtPngzID0gcEFycmF5LT5HZXROdW1iZXIocXVhZEluZGV4KjgrNCk7DQotCQlxdWFkUG9pbnRzLT55MyA9IHBBcnJheS0+R2V0TnVtYmVyKHF1YWRJbmRleCo4KzUpOw0KLQkJcXVhZFBvaW50cy0+eDQgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCs2KTsNCi0JCXF1YWRQb2ludHMtPnk0ID0gcEFycmF5LT5HZXROdW1iZXIocXVhZEluZGV4KjgrNyk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfSANCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi0NCi1ETExFWFBPUlQgdW5zaWduZWQgbG9uZyBTVERDQUxMIEZQREZfR2V0TWV0YVRleHQoRlBERl9ET0NVTUVOVCBkb2MsIEZQREZfQllURVNUUklORyB0YWcsDQotCQkJCQkJCQkJCQkJIHZvaWQqIGJ1ZmZlciwgdW5zaWduZWQgbG9uZyBidWZsZW4pDQotew0KLQlpZiAoZG9jID09IE5VTEwgfHwgdGFnID09IE5VTEwpIHJldHVybiAwOw0KLQ0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvYzsNCi0JLy8gR2V0IGluZm8gZGljdGlvbmFyeQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBJbmZvID0gcERvYy0+R2V0SW5mbygpOw0KLQlpZiAocEluZm8gPT0gTlVMTCkgcmV0dXJuIDA7DQotDQotCUNGWF9XaWRlU3RyaW5nIHRleHQgPSBwSW5mby0+R2V0VW5pY29kZVRleHQodGFnKTsNCi0NCi0JLy8gVXNlIFVURi0xNkxFIGVuY29kaW5nDQotCUNGWF9CeXRlU3RyaW5nIGJzdHIgPSB0ZXh0LlVURjE2TEVfRW5jb2RlKCk7DQotCXVuc2lnbmVkIGxvbmcgbGVuID0gYnN0ci5HZXRMZW5ndGgoKTsNCi0JaWYgKGJ1ZmZlciAhPSBOVUxMIHx8IGJ1ZmxlbiA+PSBsZW4rMikgew0KLQkJRlhTWVNfbWVtY3B5KGJ1ZmZlciwgKEZYX0xQQ1NUUilic3RyLCBsZW4pOw0KLQkJLy8gdXNlIGRvdWJsZSB6ZXJvIGFzIHRyYWlsZXINCi0JCSgoRlhfQllURSopYnVmZmVyKVtsZW5dID0gKChGWF9CWVRFKilidWZmZXIpW2xlbisxXSA9IDA7DQotCX0NCi0JcmV0dXJuIGxlbisyOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZmRvYy5oIgorCitzdGF0aWMgaW50IHRoaXNfbW9kdWxlID0gMDsKKworc3RhdGljIENQREZfQm9va21hcmsgRmluZEJvb2ttYXJrKENQREZfQm9va21hcmtUcmVlJiB0cmVlLCBDUERGX0Jvb2ttYXJrIFRoaXMsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiB0aXRsZSkKK3sKKwlpZiAoVGhpcyAhPSBOVUxMKSB7CisJCS8vIEZpcnN0IGNoZWNrIHRoaXMgaXRlbQorCQlDRlhfV2lkZVN0cmluZyB0aGlzX3RpdGxlID0gVGhpcy5HZXRUaXRsZSgpOworCQlpZiAodGhpc190aXRsZS5Db21wYXJlTm9DYXNlKHRpdGxlKSA9PSAwKQorCQkJcmV0dXJuIFRoaXM7CisJfQorCS8vIGdvIGludG8gY2hpbGRyZW4gaXRlbXMKKwlDUERGX0Jvb2ttYXJrIENoaWxkID0gdHJlZS5HZXRGaXJzdENoaWxkKFRoaXMpOworCXdoaWxlIChDaGlsZCAhPSBOVUxMKSB7CisJCS8vIGNoZWNrIGlmIHRoaXMgaXRlbQorCQlDUERGX0Jvb2ttYXJrIEZvdW5kID0gRmluZEJvb2ttYXJrKHRyZWUsIENoaWxkLCB0aXRsZSk7CisJCWlmIChGb3VuZCkgcmV0dXJuIEZvdW5kOworCQlDaGlsZCA9IHRyZWUuR2V0TmV4dFNpYmxpbmcoQ2hpbGQpOworCX0KKwlyZXR1cm4gTlVMTDsKK30KKworRExMRVhQT1JUIEZQREZfQk9PS01BUksgU1REQ0FMTCBGUERGQm9va21hcmtfRmluZChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBGUERGX1dJREVTVFJJTkcgdGl0bGUpCit7CisJaWYgKGRvY3VtZW50ID09IE5VTEwpIHJldHVybiBOVUxMOworCWlmICh0aXRsZSA9PSBOVUxMIHx8IHRpdGxlWzBdID09IDApIHJldHVybiBOVUxMOworCisJQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsKKwlDUERGX0Jvb2ttYXJrVHJlZSB0cmVlKHBEb2MpOworCisJQ0ZYX1dpZGVTdHJpbmcgd3N0ciA9IENGWF9XaWRlU3RyaW5nOjpGcm9tVVRGMTZMRSh0aXRsZSk7CisJcmV0dXJuIEZpbmRCb29rbWFyayh0cmVlLCBOVUxMLCB3c3RyKTsKK30KKworRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZCb29rbWFya19HZXREZXN0KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfQk9PS01BUksgYm9va21hcmspCit7CisJaWYgKGRvY3VtZW50ID09IE5VTEwpIHJldHVybiBOVUxMOworCWlmIChib29rbWFyayA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKworCUNQREZfQm9va21hcmsgQm9va21hcmsgPSAoQ1BERl9EaWN0aW9uYXJ5Kilib29rbWFyazsKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50OworCUNQREZfRGVzdCBkZXN0ID0gQm9va21hcmsuR2V0RGVzdChwRG9jKTsKKwlpZiAoZGVzdCAhPSBOVUxMKSByZXR1cm4gZGVzdDsKKworCS8vIElmIHRoaXMgYm9va21hcmsgaXMgbm90IGRpcmVjdGx5IGFzc29jaWF0ZWQgd2l0aCBhIGRlc3QsIHdlIHRyeSB0byBnZXQgYWN0aW9uCisJQ1BERl9BY3Rpb24gQWN0aW9uID0gQm9va21hcmsuR2V0QWN0aW9uKCk7CisJaWYgKEFjdGlvbiA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKwlyZXR1cm4gQWN0aW9uLkdldERlc3QocERvYyk7Cit9CisKK0RMTEVYUE9SVCBGUERGX0FDVElPTiBTVERDQUxMIEZQREZCb29rbWFya19HZXRBY3Rpb24oRlBERl9CT09LTUFSSyBib29rbWFyaykKK3sKKwlpZiAoYm9va21hcmsgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisKKwlDUERGX0Jvb2ttYXJrIEJvb2ttYXJrID0gKENQREZfRGljdGlvbmFyeSopYm9va21hcms7CisJcmV0dXJuIEJvb2ttYXJrLkdldEFjdGlvbigpOworfQorCitETExFWFBPUlQgdW5zaWduZWQgbG9uZyBTVERDQUxMIEZQREZBY3Rpb25fR2V0VHlwZShGUERGX0FDVElPTiBhY3Rpb24pCit7CisJaWYgKGFjdGlvbiA9PSBOVUxMKSByZXR1cm4gMDsKKworCUNQREZfQWN0aW9uIEFjdGlvbiA9IChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbjsKKwlDUERGX0FjdGlvbjo6QWN0aW9uVHlwZSB0eXBlID0gQWN0aW9uLkdldFR5cGUoKTsKKwlzd2l0Y2ggKHR5cGUpIHsKKwljYXNlIENQREZfQWN0aW9uOjpHb1RvOgorCQlyZXR1cm4gUERGQUNUSU9OX0dPVE87CisJY2FzZSBDUERGX0FjdGlvbjo6R29Ub1I6CisJCXJldHVybiBQREZBQ1RJT05fUkVNT1RFR09UTzsKKwljYXNlIENQREZfQWN0aW9uOjpVUkk6CisJCXJldHVybiBQREZBQ1RJT05fVVJJOworCWNhc2UgQ1BERl9BY3Rpb246OkxhdW5jaDoKKwkJcmV0dXJuIFBERkFDVElPTl9MQVVOQ0g7CisJZGVmYXVsdDoKKwkJcmV0dXJuIFBERkFDVElPTl9VTlNVUFBPUlRFRDsKKwl9CisJcmV0dXJuIFBERkFDVElPTl9VTlNVUFBPUlRFRDsKK30KKworRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZBY3Rpb25fR2V0RGVzdChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBGUERGX0FDVElPTiBhY3Rpb24pCit7CisJaWYgKGRvY3VtZW50ID09IE5VTEwpIHJldHVybiBOVUxMOworCWlmIChhY3Rpb24gPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisJQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsKKwlDUERGX0FjdGlvbiBBY3Rpb24gPSAoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb247CisKKwlyZXR1cm4gQWN0aW9uLkdldERlc3QocERvYyk7Cit9CisKK0RMTEVYUE9SVCB1bnNpZ25lZCBsb25nIFNURENBTEwgRlBERkFjdGlvbl9HZXRVUklQYXRoKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfQUNUSU9OIGFjdGlvbiwgCisJCQkJCQkJCQkJCSAgdm9pZCogYnVmZmVyLCB1bnNpZ25lZCBsb25nIGJ1ZmxlbikKK3sKKwlpZiAoZG9jdW1lbnQgPT0gTlVMTCkgcmV0dXJuIDA7CisJaWYgKGFjdGlvbiA9PSBOVUxMKSByZXR1cm4gMDsKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50OworCUNQREZfQWN0aW9uIEFjdGlvbiA9IChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbjsKKworCUNGWF9CeXRlU3RyaW5nIHBhdGggPSBBY3Rpb24uR2V0VVJJKHBEb2MpOworCXVuc2lnbmVkIGxvbmcgbGVuID0gcGF0aC5HZXRMZW5ndGgoKSArIDE7CisJaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmxlbiA+PSBsZW4pCisJCUZYU1lTX21lbWNweShidWZmZXIsIChGWF9MUENTVFIpcGF0aCwgbGVuKTsKKwlyZXR1cm4gbGVuOworfQorCitETExFWFBPUlQgdW5zaWduZWQgbG9uZyBTVERDQUxMIEZQREZEZXN0X0dldFBhZ2VJbmRleChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBGUERGX0RFU1QgZGVzdCkKK3sKKwlpZiAoZG9jdW1lbnQgPT0gTlVMTCkgcmV0dXJuIDA7CisJaWYgKGRlc3QgPT0gTlVMTCkgcmV0dXJuIDA7CisJQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsKKwlDUERGX0Rlc3QgRGVzdCA9IChDUERGX0FycmF5KilkZXN0OworCisJcmV0dXJuIERlc3QuR2V0UGFnZUluZGV4KHBEb2MpOworfQorCitzdGF0aWMgdm9pZCBSZWxlYXNlTGlua0xpc3QoRlhfTFBWT0lEIGRhdGEpCit7CisJZGVsZXRlIChDUERGX0xpbmtMaXN0KilkYXRhOworfQorCitETExFWFBPUlQgRlBERl9MSU5LIFNURENBTEwgRlBERkxpbmtfR2V0TGlua0F0UG9pbnQoRlBERl9QQUdFIHBhZ2UsIGRvdWJsZSB4LCBkb3VibGUgeSkKK3sKKwlpZiAocGFnZSA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKworCS8vIExpbmsgbGlzdCBpcyBzdG9yZWQgd2l0aCB0aGUgZG9jdW1lbnQKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gcFBhZ2UtPm1fcERvY3VtZW50OworCUNQREZfTGlua0xpc3QqIHBMaW5rTGlzdCA9IChDUERGX0xpbmtMaXN0KilwRG9jLT5HZXRQcml2YXRlRGF0YSgmdGhpc19tb2R1bGUpOworCWlmIChwTGlua0xpc3QgPT0gTlVMTCkgeworCQlwTGlua0xpc3QgPSBGWF9ORVcgQ1BERl9MaW5rTGlzdChwRG9jKTsKKwkJcERvYy0+U2V0UHJpdmF0ZURhdGEoJnRoaXNfbW9kdWxlLCBwTGlua0xpc3QsIFJlbGVhc2VMaW5rTGlzdCk7CisJfQorCisJcmV0dXJuIHBMaW5rTGlzdC0+R2V0TGlua0F0UG9pbnQocFBhZ2UsIChGWF9GTE9BVCl4LCAoRlhfRkxPQVQpeSk7Cit9CisKK0RMTEVYUE9SVCBGUERGX0RFU1QgU1REQ0FMTCBGUERGTGlua19HZXREZXN0KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIEZQREZfTElOSyBsaW5rKQoreworCWlmIChkb2N1bWVudCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50OworCWlmIChsaW5rID09IE5VTEwpIHJldHVybiBOVUxMOworCUNQREZfTGluayBMaW5rID0gKENQREZfRGljdGlvbmFyeSopbGluazsKKworCUZQREZfREVTVCBkZXN0ID0gTGluay5HZXREZXN0KHBEb2MpOworCWlmIChkZXN0KSByZXR1cm4gZGVzdDsKKworCS8vIElmIHRoaXMgbGluayBpcyBub3QgZGlyZWN0bHkgYXNzb2NpYXRlZCB3aXRoIGEgZGVzdCwgd2UgdHJ5IHRvIGdldCBhY3Rpb24KKwlDUERGX0FjdGlvbiBBY3Rpb24gPSBMaW5rLkdldEFjdGlvbigpOworCWlmIChBY3Rpb24gPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisJcmV0dXJuIEFjdGlvbi5HZXREZXN0KHBEb2MpOworfQorCitETExFWFBPUlQgRlBERl9BQ1RJT04gU1REQ0FMTCBGUERGTGlua19HZXRBY3Rpb24oRlBERl9MSU5LIGxpbmspCit7CisJaWYgKGxpbmsgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisJQ1BERl9MaW5rIExpbmsgPSAoQ1BERl9EaWN0aW9uYXJ5KilsaW5rOworCisJcmV0dXJuIExpbmsuR2V0QWN0aW9uKCk7Cit9CisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGTGlua19FbnVtZXJhdGUoRlBERl9QQUdFIHBhZ2UsIGludCogc3RhcnRQb3MsIEZQREZfTElOSyogbGlua0Fubm90KQoreworCWlmKCFwYWdlIHx8ICFzdGFydFBvcyB8fCAhbGlua0Fubm90KQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7CisJaWYoIXBQYWdlLT5tX3BGb3JtRGljdCkgcmV0dXJuIEZBTFNFOworCUNQREZfQXJyYXkqIHBBbm5vdHMgPSBwUGFnZS0+bV9wRm9ybURpY3QtPkdldEFycmF5KCJBbm5vdHMiKTsKKwlpZighcEFubm90cykgcmV0dXJuIEZBTFNFOworCWZvciAoaW50IGkgPSAqc3RhcnRQb3M7IGkgPCAoaW50KXBBbm5vdHMtPkdldENvdW50KCk7IGkgKyspIHsKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwRGljdCA9IChDUERGX0RpY3Rpb25hcnkqKXBBbm5vdHMtPkdldEVsZW1lbnRWYWx1ZShpKTsKKwkJaWYgKHBEaWN0ID09IE5VTEwgfHwgcERpY3QtPkdldFR5cGUoKSAhPSBQREZPQkpfRElDVElPTkFSWSkgY29udGludWU7CisJCWlmKHBEaWN0LT5HZXRTdHJpbmcoRlhfQlNUUkMoIlN1YnR5cGUiKSkuRXF1YWwoRlhfQlNUUkMoIkxpbmsiKSkpCisJCXsKKwkJCSpzdGFydFBvcyA9IGkrMTsKKwkJCSpsaW5rQW5ub3QgPSAoRlBERl9MSU5LKXBEaWN0OyAKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCXJldHVybiBGQUxTRTsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZMaW5rX0dldEFubm90UmVjdChGUERGX0xJTksgbGlua0Fubm90LCBGU19SRUNURiogcmVjdCkKK3sKKwlpZighbGlua0Fubm90IHx8ICFyZWN0KQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0ID0gKENQREZfRGljdGlvbmFyeSopbGlua0Fubm90OworCUNQREZfUmVjdCBydCA9IHBBbm5vdERpY3QtPkdldFJlY3QoRlhfQlNUUkMoIlJlY3QiKSk7CisJcmVjdC0+bGVmdCA9IHJ0LmxlZnQ7CisJcmVjdC0+Ym90dG9tID0gcnQuYm90dG9tOworCXJlY3QtPnJpZ2h0ID0gcnQucmlnaHQ7CisJcmVjdC0+dG9wID0gcnQudG9wOworCXJldHVybiBUUlVFOworfQorCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkxpbmtfQ291bnRRdWFkUG9pbnRzKEZQREZfTElOSyBsaW5rQW5ub3QpCit7CisJaWYoIWxpbmtBbm5vdCkKKwkJcmV0dXJuIDA7CisJQ1BERl9EaWN0aW9uYXJ5KiBwQW5ub3REaWN0ID0gKENQREZfRGljdGlvbmFyeSopbGlua0Fubm90OworCUNQREZfQXJyYXkqIHBBcnJheSA9IHBBbm5vdERpY3QtPkdldEFycmF5KEZYX0JTVFJDKCJRdWFkUG9pbnRzIikpOworCWlmIChwQXJyYXkgPT0gTlVMTCkKKwkJcmV0dXJuIDA7CisJZWxzZQorCQlyZXR1cm4gcEFycmF5LT5HZXRDb3VudCgpIC8gODsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZMaW5rX0dldFF1YWRQb2ludHMoRlBERl9MSU5LIGxpbmtBbm5vdCwgaW50IHF1YWRJbmRleCwgRlNfUVVBRFBPSU5UU0YqIHF1YWRQb2ludHMpCit7CisJaWYoIWxpbmtBbm5vdCB8fCAhcXVhZFBvaW50cykKKwkJcmV0dXJuIEZBTFNFOworCUNQREZfRGljdGlvbmFyeSogcEFubm90RGljdCA9IChDUERGX0RpY3Rpb25hcnkqKWxpbmtBbm5vdDsKKwlDUERGX0FycmF5KiBwQXJyYXkgPSBwQW5ub3REaWN0LT5HZXRBcnJheShGWF9CU1RSQygiUXVhZFBvaW50cyIpKTsKKwlpZiAocEFycmF5KSB7CisJCWlmICgwID4gcXVhZEluZGV4IHx8IHF1YWRJbmRleCA+PSAoaW50KXBBcnJheS0+R2V0Q291bnQoKS84IHx8CisJCQkoKHF1YWRJbmRleCo4KzcpID49IChpbnQpcEFycmF5LT5HZXRDb3VudCgpKSkgcmV0dXJuIEZBTFNFOworCQlxdWFkUG9pbnRzLT54MSA9IHBBcnJheS0+R2V0TnVtYmVyKHF1YWRJbmRleCo4KTsKKwkJcXVhZFBvaW50cy0+eTEgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCsxKTsKKwkJcXVhZFBvaW50cy0+eDIgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCsyKTsKKwkJcXVhZFBvaW50cy0+eTIgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCszKTsKKwkJcXVhZFBvaW50cy0+eDMgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCs0KTsKKwkJcXVhZFBvaW50cy0+eTMgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCs1KTsKKwkJcXVhZFBvaW50cy0+eDQgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCs2KTsKKwkJcXVhZFBvaW50cy0+eTQgPSBwQXJyYXktPkdldE51bWJlcihxdWFkSW5kZXgqOCs3KTsKKwkJcmV0dXJuIFRSVUU7CisJfSAKKwlyZXR1cm4gRkFMU0U7Cit9CisKKworRExMRVhQT1JUIHVuc2lnbmVkIGxvbmcgU1REQ0FMTCBGUERGX0dldE1ldGFUZXh0KEZQREZfRE9DVU1FTlQgZG9jLCBGUERGX0JZVEVTVFJJTkcgdGFnLAorCQkJCQkJCQkJCQkJIHZvaWQqIGJ1ZmZlciwgdW5zaWduZWQgbG9uZyBidWZsZW4pCit7CisJaWYgKGRvYyA9PSBOVUxMIHx8IHRhZyA9PSBOVUxMKSByZXR1cm4gMDsKKworCUNQREZfRG9jdW1lbnQqIHBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jOworCS8vIEdldCBpbmZvIGRpY3Rpb25hcnkKKwlDUERGX0RpY3Rpb25hcnkqIHBJbmZvID0gcERvYy0+R2V0SW5mbygpOworCWlmIChwSW5mbyA9PSBOVUxMKSByZXR1cm4gMDsKKworCUNGWF9XaWRlU3RyaW5nIHRleHQgPSBwSW5mby0+R2V0VW5pY29kZVRleHQodGFnKTsKKworCS8vIFVzZSBVVEYtMTZMRSBlbmNvZGluZworCUNGWF9CeXRlU3RyaW5nIGJzdHIgPSB0ZXh0LlVURjE2TEVfRW5jb2RlKCk7CisJdW5zaWduZWQgbG9uZyBsZW4gPSBic3RyLkdldExlbmd0aCgpOworCWlmIChidWZmZXIgIT0gTlVMTCB8fCBidWZsZW4gPj0gbGVuKzIpIHsKKwkJRlhTWVNfbWVtY3B5KGJ1ZmZlciwgKEZYX0xQQ1NUUilic3RyLCBsZW4pOworCQkvLyB1c2UgZG91YmxlIHplcm8gYXMgdHJhaWxlcgorCQkoKEZYX0JZVEUqKWJ1ZmZlcilbbGVuXSA9ICgoRlhfQllURSopYnVmZmVyKVtsZW4rMV0gPSAwOworCX0KKwlyZXR1cm4gbGVuKzI7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2ZwZGZlZGl0aW1nLmNwcCBiL2ZwZGZzZGsvc3JjL2ZwZGZlZGl0aW1nLmNwcAppbmRleCBlYTgxMjAzLi5jMjlkMmI3IDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mcGRmZWRpdGltZy5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnBkZmVkaXRpbWcuY3BwCkBAIC0xLDc0ICsxLDc0IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZlZGl0LmgiDQotDQotDQotRExMRVhQT1JUIEZQREZfUEFHRU9CSkVDVCBTVERDQUxMIEZQREZQYWdlT2JqX05ld0ltZ2VPYmooRlBERl9ET0NVTUVOVCBkb2N1bWVudCkNCi17DQotCWlmICghZG9jdW1lbnQpDQotCQlyZXR1cm4gTlVMTDsNCi0JQ1BERl9JbWFnZU9iamVjdCogcEltYWdlT2JqID0gRlhfTkVXIENQREZfSW1hZ2VPYmplY3Q7DQotCUNQREZfSW1hZ2UqIHBJbWcgPSBGWF9ORVcgQ1BERl9JbWFnZSgoQ1BERl9Eb2N1bWVudCAqKWRvY3VtZW50KTsNCi0JcEltYWdlT2JqLT5tX3BJbWFnZSA9IHBJbWc7DQotCXJldHVybiBwSW1hZ2VPYmo7DQotfQ0KLQ0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGSW1hZ2VPYmpfTG9hZEpwZWdGaWxlKEZQREZfUEFHRSogcGFnZXMsIGludCBuQ291bnQsRlBERl9QQUdFT0JKRUNUIGltYWdlX29iamVjdCwgRlBERl9GSUxFQUNDRVNTKiBmaWxlQWNjZXNzKQ0KLXsNCi0JaWYgKCFpbWFnZV9vYmplY3QgfHwgIWZpbGVBY2Nlc3MpDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCUlGWF9GaWxlUmVhZCogcEZpbGUgPSBGWF9ORVcgQ1BERl9DdXN0b21BY2Nlc3MoZmlsZUFjY2Vzcyk7DQotDQotCUNQREZfSW1hZ2VPYmplY3QqIHBJbWdPYmogPSAoQ1BERl9JbWFnZU9iamVjdCopaW1hZ2Vfb2JqZWN0Ow0KLQlwSW1nT2JqLT5tX0dlbmVyYWxTdGF0ZS5HZXRNb2RpZnkoKTsNCi0JZm9yIChpbnQgaW5kZXg9MDtpbmRleDxuQ291bnQ7aW5kZXgrKykNCi0Jew0KLQkJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2VzW2luZGV4XTsgDQotCQlwSW1nT2JqLT5tX3BJbWFnZS0+UmVzZXRDYWNoZShwUGFnZSxOVUxMKTsNCi0JfQ0KLQlwSW1nT2JqLT5tX3BJbWFnZS0+U2V0SnBlZ0ltYWdlKHBGaWxlKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLQ0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGSW1hZ2VPYmpfU2V0TWF0cml4CShGUERGX1BBR0VPQkpFQ1QgaW1hZ2Vfb2JqZWN0LA0KLQkJCQkJCQkJCQkJCSBkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKQ0KLXsNCi0JaWYgKCFpbWFnZV9vYmplY3QpDQotCQlyZXR1cm4gRkFMU0U7DQotCUNQREZfSW1hZ2VPYmplY3QqIHBJbWdPYmogPSAoQ1BERl9JbWFnZU9iamVjdCopaW1hZ2Vfb2JqZWN0Ow0KLQlwSW1nT2JqLT5tX01hdHJpeC5hID0gKEZYX0ZMT0FUKWE7DQotCXBJbWdPYmotPm1fTWF0cml4LmIgPSAoRlhfRkxPQVQpYjsNCi0JcEltZ09iai0+bV9NYXRyaXguYyA9IChGWF9GTE9BVCljOw0KLQlwSW1nT2JqLT5tX01hdHJpeC5kID0gKEZYX0ZMT0FUKWQ7DQotCXBJbWdPYmotPm1fTWF0cml4LmUgPSAoRlhfRkxPQVQpZTsNCi0JcEltZ09iai0+bV9NYXRyaXguZiA9IChGWF9GTE9BVClmOw0KLQlwSW1nT2JqLT5DYWxjQm91bmRpbmdCb3goKTsNCi0JcmV0dXJuICBUUlVFOw0KLX0NCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkltYWdlT2JqX1NldEJpdG1hcChGUERGX1BBR0UqIHBhZ2VzLGludCBuQ291bnQsRlBERl9QQUdFT0JKRUNUIGltYWdlX29iamVjdCxGUERGX0JJVE1BUCBiaXRtYXApDQotew0KLQlpZiAoIWltYWdlX29iamVjdCB8fCAhYml0bWFwKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfRElCaXRtYXAqIHBCbXAgPSBOVUxMOw0KLQlwQm1wID0gKENGWF9ESUJpdG1hcCopYml0bWFwOw0KLQlDUERGX0ltYWdlT2JqZWN0KiBwSW1nT2JqID0gKENQREZfSW1hZ2VPYmplY3QqKWltYWdlX29iamVjdDsNCi0JcEltZ09iai0+bV9HZW5lcmFsU3RhdGUuR2V0TW9kaWZ5KCk7DQotCWZvciAoaW50IGluZGV4PTA7aW5kZXg8bkNvdW50O2luZGV4KyspDQotCXsNCi0JCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlc1tpbmRleF07IA0KLQkJcEltZ09iai0+bV9wSW1hZ2UtPlJlc2V0Q2FjaGUocFBhZ2UsTlVMTCk7DQotCX0NCi0JcEltZ09iai0+bV9wSW1hZ2UtPlNldEltYWdlKHBCbXAsRkFMU0UpOw0KLQlwSW1nT2JqLT5DYWxjQm91bmRpbmdCb3goKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmZWRpdC5oIgorCisKK0RMTEVYUE9SVCBGUERGX1BBR0VPQkpFQ1QgU1REQ0FMTCBGUERGUGFnZU9ial9OZXdJbWdlT2JqKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpCit7CisJaWYgKCFkb2N1bWVudCkKKwkJcmV0dXJuIE5VTEw7CisJQ1BERl9JbWFnZU9iamVjdCogcEltYWdlT2JqID0gRlhfTkVXIENQREZfSW1hZ2VPYmplY3Q7CisJQ1BERl9JbWFnZSogcEltZyA9IEZYX05FVyBDUERGX0ltYWdlKChDUERGX0RvY3VtZW50ICopZG9jdW1lbnQpOworCXBJbWFnZU9iai0+bV9wSW1hZ2UgPSBwSW1nOworCXJldHVybiBwSW1hZ2VPYmo7Cit9CisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGSW1hZ2VPYmpfTG9hZEpwZWdGaWxlKEZQREZfUEFHRSogcGFnZXMsIGludCBuQ291bnQsRlBERl9QQUdFT0JKRUNUIGltYWdlX29iamVjdCwgRlBERl9GSUxFQUNDRVNTKiBmaWxlQWNjZXNzKQoreworCWlmICghaW1hZ2Vfb2JqZWN0IHx8ICFmaWxlQWNjZXNzKQorCQlyZXR1cm4gRkFMU0U7CisKKwlJRlhfRmlsZVJlYWQqIHBGaWxlID0gRlhfTkVXIENQREZfQ3VzdG9tQWNjZXNzKGZpbGVBY2Nlc3MpOworCisJQ1BERl9JbWFnZU9iamVjdCogcEltZ09iaiA9IChDUERGX0ltYWdlT2JqZWN0KilpbWFnZV9vYmplY3Q7CisJcEltZ09iai0+bV9HZW5lcmFsU3RhdGUuR2V0TW9kaWZ5KCk7CisJZm9yIChpbnQgaW5kZXg9MDtpbmRleDxuQ291bnQ7aW5kZXgrKykKKwl7CisJCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlc1tpbmRleF07IAorCQlwSW1nT2JqLT5tX3BJbWFnZS0+UmVzZXRDYWNoZShwUGFnZSxOVUxMKTsKKwl9CisJcEltZ09iai0+bV9wSW1hZ2UtPlNldEpwZWdJbWFnZShwRmlsZSk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkltYWdlT2JqX1NldE1hdHJpeAkoRlBERl9QQUdFT0JKRUNUIGltYWdlX29iamVjdCwKKwkJCQkJCQkJCQkJCSBkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKQoreworCWlmICghaW1hZ2Vfb2JqZWN0KQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERl9JbWFnZU9iamVjdCogcEltZ09iaiA9IChDUERGX0ltYWdlT2JqZWN0KilpbWFnZV9vYmplY3Q7CisJcEltZ09iai0+bV9NYXRyaXguYSA9IChGWF9GTE9BVClhOworCXBJbWdPYmotPm1fTWF0cml4LmIgPSAoRlhfRkxPQVQpYjsKKwlwSW1nT2JqLT5tX01hdHJpeC5jID0gKEZYX0ZMT0FUKWM7CisJcEltZ09iai0+bV9NYXRyaXguZCA9IChGWF9GTE9BVClkOworCXBJbWdPYmotPm1fTWF0cml4LmUgPSAoRlhfRkxPQVQpZTsKKwlwSW1nT2JqLT5tX01hdHJpeC5mID0gKEZYX0ZMT0FUKWY7CisJcEltZ09iai0+Q2FsY0JvdW5kaW5nQm94KCk7CisJcmV0dXJuICBUUlVFOworfQorCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERkltYWdlT2JqX1NldEJpdG1hcChGUERGX1BBR0UqIHBhZ2VzLGludCBuQ291bnQsRlBERl9QQUdFT0JKRUNUIGltYWdlX29iamVjdCxGUERGX0JJVE1BUCBiaXRtYXApCit7CisJaWYgKCFpbWFnZV9vYmplY3QgfHwgIWJpdG1hcCkKKwkJcmV0dXJuIEZBTFNFOworCUNGWF9ESUJpdG1hcCogcEJtcCA9IE5VTEw7CisJcEJtcCA9IChDRlhfRElCaXRtYXAqKWJpdG1hcDsKKwlDUERGX0ltYWdlT2JqZWN0KiBwSW1nT2JqID0gKENQREZfSW1hZ2VPYmplY3QqKWltYWdlX29iamVjdDsKKwlwSW1nT2JqLT5tX0dlbmVyYWxTdGF0ZS5HZXRNb2RpZnkoKTsKKwlmb3IgKGludCBpbmRleD0wO2luZGV4PG5Db3VudDtpbmRleCsrKQorCXsKKwkJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2VzW2luZGV4XTsgCisJCXBJbWdPYmotPm1fcEltYWdlLT5SZXNldENhY2hlKHBQYWdlLE5VTEwpOworCX0KKwlwSW1nT2JqLT5tX3BJbWFnZS0+U2V0SW1hZ2UocEJtcCxGQUxTRSk7CisJcEltZ09iai0+Q2FsY0JvdW5kaW5nQm94KCk7CisJcmV0dXJuIFRSVUU7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2ZwZGZlZGl0cGFnZS5jcHAgYi9mcGRmc2RrL3NyYy9mcGRmZWRpdHBhZ2UuY3BwCmluZGV4IGQ5Y2JiZTQuLjNmMjJiNTYgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZwZGZlZGl0cGFnZS5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnBkZmVkaXRwYWdlLmNwcApAQCAtMSwzMTYgKzEsMzE2IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0vLyAjaW5jbHVkZSAieDovcGRmL2ZwZGZhcGk1L2luY2x1ZGUvZnBkZmFwaS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZmVkaXQuaCINCi0NCi0NCi0jaWYgX0ZYX09TXyA9PSBfRlhfQU5EUk9JRF8NCi0jaW5jbHVkZSAidGltZS5oIg0KLSNlbHNlDQotI2luY2x1ZGUgPGN0aW1lPg0KLSNlbmRpZg0KLQ0KLURMTEVYUE9SVCBGUERGX0RPQ1VNRU5UIFNURENBTEwgRlBERl9DcmVhdGVOZXdEb2N1bWVudCgpDQotew0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gRlhfTkVXIENQREZfRG9jdW1lbnQ7DQotCWlmICghcERvYykNCi0JCXJldHVybiBOVUxMOw0KLQlwRG9jLT5DcmVhdGVOZXdEb2MoKTsNCi0JdGltZV90IGN1cnJlbnRUaW1lOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBEYXRlU3RyOw0KLQ0KLQlpZihGU0RLX0lzU2FuZEJveFBvbGljeUVuYWJsZWQoRlBERl9QT0xJQ1lfTUFDSElORVRJTUVfQUNDRVNTKSkNCi0Jew0KLQkJaWYgKCAtMSAhPSB0aW1lKCAmY3VycmVudFRpbWUgKSApDQotCQl7DQotCQkJdG0gKiBwVE0gPSBsb2NhbHRpbWUoICZjdXJyZW50VGltZSApOw0KLQkJCWlmICggcFRNICkNCi0JCQl7DQotCQkJCURhdGVTdHIuRm9ybWF0KAkiRDolMDRkJTAyZCUwMmQlMDJkJTAyZCUwMmQiLCBwVE0tPnRtX3llYXIrMTkwMCwgcFRNLT50bV9tb24rMSwNCi0JCQkJCXBUTS0+dG1fbWRheSwgcFRNLT50bV9ob3VyLCBwVE0tPnRtX21pbiwgcFRNLT50bV9zZWMgKTsNCi0JCQl9DQotCQl9DQotCX0NCi0JDQotCUNQREZfRGljdGlvbmFyeSogcEluZm9EaWN0ID0gTlVMTDsNCi0JcEluZm9EaWN0ID0gcERvYy0+R2V0SW5mbygpOw0KLQlpZiAocEluZm9EaWN0KQ0KLQl7DQotCQlpZihGU0RLX0lzU2FuZEJveFBvbGljeUVuYWJsZWQoRlBERl9QT0xJQ1lfTUFDSElORVRJTUVfQUNDRVNTKSkNCi0JCQlwSW5mb0RpY3QtPlNldEF0KCJDcmVhdGlvbkRhdGUiLCBuZXcgQ1BERl9TdHJpbmcoRGF0ZVN0cikpOw0KLSNpZmRlZiBGT1hJVF9DSFJPTUVfQlVJTEQNCi0JCXBJbmZvRGljdC0+U2V0QXQoIkNyZWF0b3IiLEZYX05FVyBDUERGX1N0cmluZyhMIkdvb2dsZSIpKTsNCi0jZWxzZQ0KLQkJcEluZm9EaWN0LT5TZXRBdCgiQ3JlYXRvciIsRlhfTkVXIENQREZfU3RyaW5nKEwiRm94aXQgUERGIFNESyBETEwgMi4wIC0gRm94aXQgU29mdHdhcmUiKSk7DQotI2VuZGlmDQotCX0NCi0NCi0JcmV0dXJuIHBEb2M7DQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VfRGVsZXRlKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIGludCBwYWdlX2luZGV4KQ0KLXsNCi0JQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsNCi0JaWYgKHBEb2MgPT0gTlVMTCkgDQotCQlyZXR1cm47DQotCWlmIChwYWdlX2luZGV4IDwgMCB8fCBwYWdlX2luZGV4ID49IHBEb2MtPkdldFBhZ2VDb3VudCgpKSANCi0JCXJldHVybjsNCi0NCi0JcERvYy0+RGVsZXRlUGFnZShwYWdlX2luZGV4KTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfUEFHRSBTVERDQUxMIEZQREZQYWdlX05ldyhGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBpbnQgcGFnZV9pbmRleCwgZG91YmxlIHdpZHRoLCBkb3VibGUgaGVpZ2h0KQ0KLXsNCi0JaWYgKCFkb2N1bWVudCkNCi0JCXJldHVybiBOVUxMOw0KLQ0KLS8vCUNQREZfUGFyc2VyKiBwUGFyc2VyID0gKENQREZfUGFyc2VyKilkb2N1bWVudDsNCi0JQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsNCi0JaWYocGFnZV9pbmRleCA8IDApDQotCQlwYWdlX2luZGV4ID0gMDsNCi0JaWYocERvYy0+R2V0UGFnZUNvdW50KCk8cGFnZV9pbmRleCkNCi0JCXBhZ2VfaW5kZXggPSBwRG9jLT5HZXRQYWdlQ291bnQoKTsNCi0vLwlpZiAocGFnZV9pbmRleCA8IDAgfHwgcGFnZV9pbmRleCA+PSBwRG9jLT5HZXRQYWdlQ291bnQoKSkgDQotLy8JCXJldHVybiBOVUxMOw0KLQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBEb2MtPkNyZWF0ZU5ld1BhZ2UocGFnZV9pbmRleCk7DQotCWlmKCFwUGFnZURpY3QpDQotCQlyZXR1cm4gTlVMTDsNCi0JQ1BERl9BcnJheSogcE1lZGlhQm94QXJyYXkgPSBGWF9ORVcgQ1BERl9BcnJheTsNCi0JcE1lZGlhQm94QXJyYXktPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIoMCkpOw0KLQlwTWVkaWFCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcigwKSk7DQotCXBNZWRpYUJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKEZYX0ZMT0FUKHdpZHRoKSkpOw0KLQlwTWVkaWFCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcihGWF9GTE9BVChoZWlnaHQpKSk7DQotDQotCXBQYWdlRGljdC0+U2V0QXQoIk1lZGlhQm94IiwgcE1lZGlhQm94QXJyYXkpOw0KLQlwUGFnZURpY3QtPlNldEF0KCJSb3RhdGUiLCBGWF9ORVcgQ1BERl9OdW1iZXIoMCkpOw0KLQlwUGFnZURpY3QtPlNldEF0KCJSZXNvdXJjZXMiLCBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5KTsNCi0NCi0JQ1BERl9QYWdlKiBwUGFnZSA9IEZYX05FVyBDUERGX1BhZ2U7DQotCXBQYWdlLT5Mb2FkKHBEb2MscFBhZ2VEaWN0KTsNCi0JcFBhZ2UtPlBhcnNlQ29udGVudCgpOw0KLQ0KLQlyZXR1cm4gcFBhZ2U7DQotfQ0KLQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGUGFnZV9HZXRSb3RhdGlvbihGUERGX1BBR0UgcGFnZSkNCi17DQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQlpZiAoIXBQYWdlIHx8ICFwUGFnZS0+bV9wRm9ybURpY3QgfHwgIXBQYWdlLT5tX3BGb3JtRGljdC0+S2V5RXhpc3QoIlR5cGUiKQ0KLQkJfHwgcFBhZ2UtPm1fcEZvcm1EaWN0LT5HZXRFbGVtZW50KCJUeXBlIiktPkdldERpcmVjdCgpLT5HZXRTdHJpbmcoKS5Db21wYXJlKCJQYWdlIikpDQotCXsNCi0JCXJldHVybiAtMTsNCi0JfQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gcFBhZ2UtPm1fcEZvcm1EaWN0Ow0KLQ0KLQlpbnQgcm90YXRlID0gMDsNCi0JaWYocERpY3QgIT0gTlVMTCkNCi0Jew0KLQkJaWYocERpY3QtPktleUV4aXN0KCJSb3RhdGUiKSkNCi0JCQlyb3RhdGUgPSBwRGljdC0+R2V0RWxlbWVudCgiUm90YXRlIiktPkdldERpcmVjdCgpLT5HZXRJbnRlZ2VyKCkgLyA5MDsNCi0JCWVsc2UNCi0JCXsNCi0JCQlpZihwRGljdC0+S2V5RXhpc3QoIlBhcmVudCIpKQ0KLQkJCXsNCi0JCQkJQ1BERl9EaWN0aW9uYXJ5KiBwUGFnZXMgPSAoQ1BERl9EaWN0aW9uYXJ5KilwRGljdC0+R2V0RWxlbWVudCgiUGFyZW50IiktPkdldERpcmVjdCgpOw0KLQkJCQl3aGlsZShwUGFnZXMpDQotCQkJCXsNCi0JCQkJCWlmKHBQYWdlcy0+S2V5RXhpc3QoIlJvdGF0ZSIpKQ0KLQkJCQkJew0KLQkJCQkJCXJvdGF0ZSA9IHBQYWdlcy0+R2V0RWxlbWVudCgiUm90YXRlIiktPkdldERpcmVjdCgpLT5HZXRJbnRlZ2VyKCkgLyA5MDsNCi0JCQkJCQlicmVhazsNCi0JCQkJCX0NCi0JCQkJCWVsc2UgaWYocFBhZ2VzLT5LZXlFeGlzdCgiUGFyZW50IikpDQotCQkJCQkJcFBhZ2VzID0gKENQREZfRGljdGlvbmFyeSopcFBhZ2VzLT5HZXRFbGVtZW50KCJQYXJlbnQiKS0+R2V0RGlyZWN0KCk7DQotCQkJCQllbHNlIGJyZWFrOw0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJcmV0dXJuIC0xOw0KLQl9DQotCQ0KLQlyZXR1cm4gcm90YXRlOw0KLX0NCi0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX0luc2VydE9iamVjdChGUERGX1BBR0UgcGFnZSwgRlBERl9QQUdFT0JKRUNUIHBhZ2Vfb2JqKQ0KLXsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotCWlmICghcFBhZ2UgfHwgIXBQYWdlLT5tX3BGb3JtRGljdCB8fCAhcFBhZ2UtPm1fcEZvcm1EaWN0LT5LZXlFeGlzdCgiVHlwZSIpDQotCQl8fCBwUGFnZS0+bV9wRm9ybURpY3QtPkdldEVsZW1lbnQoIlR5cGUiKS0+R2V0RGlyZWN0KCktPkdldFN0cmluZygpLkNvbXBhcmUoIlBhZ2UiKSkNCi0Jew0KLQkJcmV0dXJuOw0KLQl9DQotCUNQREZfUGFnZU9iamVjdCogcFBhZ2VPYmogPSAoQ1BERl9QYWdlT2JqZWN0KilwYWdlX29iajsNCi0JaWYocFBhZ2VPYmogPT0gTlVMTCkNCi0JCXJldHVybjsNCi0JRlhfUE9TSVRJT04gTGFzdFBlcnNpdGlvbiA9IHBQYWdlLT5HZXRMYXN0T2JqZWN0UG9zaXRpb24oKTsNCi0NCi0JcFBhZ2UtPkluc2VydE9iamVjdChMYXN0UGVyc2l0aW9uLCBwUGFnZU9iaik7DQotCXN3aXRjaChwUGFnZU9iai0+bV9UeXBlKQ0KLQl7DQotCWNhc2UgRlBERl9QQUdFT0JKX1BBVEg6DQotCQl7DQotCQkJQ1BERl9QYXRoT2JqZWN0KiBwUGF0aE9iaiA9IChDUERGX1BhdGhPYmplY3QqKXBQYWdlT2JqOw0KLQkJCXBQYXRoT2JqLT5DYWxjQm91bmRpbmdCb3goKTsNCi0JCQlicmVhazsNCi0JCX0NCi0JY2FzZSBGUERGX1BBR0VPQkpfVEVYVDoNCi0JCXsNCi0JCQkvLwlDUERGX1BhdGhPYmplY3QqIHBQYXRoT2JqID0gKENQREZfUGF0aE9iamVjdCopcFBhZ2VPYmo7DQotCQkJLy8JcFBhdGhPYmotPkNhbGNCb3VuZGluZ0JveCgpOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQljYXNlIEZQREZfUEFHRU9CSl9JTUFHRToNCi0JCXsNCi0JCQlDUERGX0ltYWdlT2JqZWN0KiBwSW1hZ2VPYmogPSAoQ1BERl9JbWFnZU9iamVjdCopcFBhZ2VPYmo7DQotCQkJcEltYWdlT2JqLT5DYWxjQm91bmRpbmdCb3goKTsNCi0JCQlicmVhazsNCi0JCX0NCi0JY2FzZSBGUERGX1BBR0VPQkpfU0hBRElORzoNCi0JCXsNCi0JCQlDUERGX1NoYWRpbmdPYmplY3QqIHBTaGFkaW5nT2JqID0gKENQREZfU2hhZGluZ09iamVjdCopcFBhZ2VPYmo7DQotCQkJcFNoYWRpbmdPYmotPkNhbGNCb3VuZGluZ0JveCgpOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQljYXNlIEZQREZfUEFHRU9CSl9GT1JNOg0KLQkJew0KLQkJCUNQREZfRm9ybU9iamVjdCogcEZvcm1PYmogPSAoQ1BERl9Gb3JtT2JqZWN0KilwUGFnZU9iajsNCi0JCQlwRm9ybU9iai0+Q2FsY0JvdW5kaW5nQm94KCk7DQotCQkJYnJlYWs7DQotCQl9DQotCWRlZmF1bHQ6DQotCQlicmVhazsNCi0JfQ0KLQ0KLQkvLwlwUGFnZS0+UGFyc2VDb250ZW50KCk7DQotCS8vcFBhZ2UtPkdlbmVyYXRlQ29udGVudCgpOw0KLQ0KLX0NCi0NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERlBhZ2VfQ291bnRPYmplY3QoRlBERl9QQUdFIHBhZ2UpDQotew0KLQlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsNCi0JaWYgKCFwUGFnZSB8fCAhcFBhZ2UtPm1fcEZvcm1EaWN0IHx8ICFwUGFnZS0+bV9wRm9ybURpY3QtPktleUV4aXN0KCJUeXBlIikNCi0JCXx8IHBQYWdlLT5tX3BGb3JtRGljdC0+R2V0RWxlbWVudCgiVHlwZSIpLT5HZXREaXJlY3QoKS0+R2V0U3RyaW5nKCkuQ29tcGFyZSgiUGFnZSIpKQ0KLQl7DQotCQlyZXR1cm4gLTE7DQotCX0NCi0JcmV0dXJuIHBQYWdlLT5Db3VudE9iamVjdHMoKTsNCi0vLwlyZXR1cm4gMDsNCi19DQotDQotRExMRVhQT1JUIEZQREZfUEFHRU9CSkVDVCBTVERDQUxMIEZQREZQYWdlX0dldE9iamVjdChGUERGX1BBR0UgcGFnZSwgaW50IGluZGV4KQ0KLXsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotCWlmICghcFBhZ2UgfHwgIXBQYWdlLT5tX3BGb3JtRGljdCB8fCAhcFBhZ2UtPm1fcEZvcm1EaWN0LT5LZXlFeGlzdCgiVHlwZSIpDQotCQl8fCBwUGFnZS0+bV9wRm9ybURpY3QtPkdldEVsZW1lbnQoIlR5cGUiKS0+R2V0RGlyZWN0KCktPkdldFN0cmluZygpLkNvbXBhcmUoIlBhZ2UiKSkNCi0Jew0KLQkJcmV0dXJuIE5VTEw7DQotCX0NCi0JcmV0dXJuIHBQYWdlLT5HZXRPYmplY3RCeUluZGV4KGluZGV4KTsNCi0vLwlyZXR1cm4gTlVMTDsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlX0hhc1RyYW5zcGFyZW5jeShGUERGX1BBR0UgcGFnZSkNCi17DQotCWlmKCFwYWdlKSByZXR1cm4gRkFMU0U7DQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQ0KLQlyZXR1cm4gcFBhZ2UtPkJhY2tncm91bmRBbHBoYU5lZWRlZCgpOw0KLX0NCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VPYmpfSGFzVHJhbnNwYXJlbmN5KEZQREZfUEFHRU9CSkVDVCBwYWdlT2JqZWN0KQ0KLXsNCi0JaWYoIXBhZ2VPYmplY3QpIHJldHVybiBGQUxTRTsNCi0JQ1BERl9QYWdlT2JqZWN0KiBwUGFnZU9iaiA9IChDUERGX1BhZ2VPYmplY3QqKXBhZ2VPYmplY3Q7DQotDQotCWNvbnN0IENQREZfR2VuZXJhbFN0YXRlRGF0YSogcEdlbmVyYWxTdGF0ZSA9IHBQYWdlT2JqLT5tX0dlbmVyYWxTdGF0ZTsNCi0JaW50IGJsZW5kX3R5cGUgPSBwR2VuZXJhbFN0YXRlID8gcEdlbmVyYWxTdGF0ZS0+bV9CbGVuZFR5cGUgOiBGWERJQl9CTEVORF9OT1JNQUw7DQotCWlmIChibGVuZF90eXBlICE9IEZYRElCX0JMRU5EX05PUk1BTCkgcmV0dXJuIFRSVUU7DQotDQotCUNQREZfRGljdGlvbmFyeSogcFNNYXNrRGljdCA9IHBHZW5lcmFsU3RhdGUgPyAoQ1BERl9EaWN0aW9uYXJ5KilwR2VuZXJhbFN0YXRlLT5tX3BTb2Z0TWFzayA6IE5VTEw7DQotCWlmKHBTTWFza0RpY3QpIHJldHVybiBUUlVFOw0KLQ0KLQlpZihwR2VuZXJhbFN0YXRlICYmIHBHZW5lcmFsU3RhdGUtPm1fRmlsbEFscGhhICE9IDEuMGYpDQotCQlyZXR1cm4gVFJVRTsNCi0NCi0JaWYocFBhZ2VPYmotPm1fVHlwZSA9PSBQREZQQUdFX1BBVEgpDQotCXsNCi0JCWlmKHBHZW5lcmFsU3RhdGUgJiYgcEdlbmVyYWxTdGF0ZS0+bV9TdHJva2VBbHBoYSAhPSAxLjBmKQ0KLQkJCXJldHVybiBUUlVFOw0KLQl9DQotDQotCWlmKHBQYWdlT2JqLT5tX1R5cGUgPT0gUERGUEFHRV9GT1JNKQ0KLQl7DQotCQlDUERGX0Zvcm1PYmplY3QqIHBGb3JtT2JqID0gKENQREZfRm9ybU9iamVjdCopcFBhZ2VPYmo7DQotCQlpZihwRm9ybU9iai0+bV9wRm9ybSAmJiAocEZvcm1PYmotPm1fcEZvcm0tPm1fVHJhbnNwYXJlbmN5ICYgUERGVFJBTlNfSVNPTEFURUQpKQ0KLQkJCXJldHVybiBUUlVFOw0KLQkJaWYocEZvcm1PYmotPm1fcEZvcm0gJiYgKCEocEZvcm1PYmotPm1fcEZvcm0tPm1fVHJhbnNwYXJlbmN5ICYgUERGVFJBTlNfSVNPTEFURUQpICYmIChwRm9ybU9iai0+bV9wRm9ybS0+bV9UcmFuc3BhcmVuY3kgJiBQREZUUkFOU19HUk9VUCkpKQ0KLQkJCXJldHVybiBUUlVFOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlX0dlbmVyYXRlQ29udGVudChGUERGX1BBR0UgcGFnZSkNCi17DQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQlpZiAoIXBQYWdlIHx8ICFwUGFnZS0+bV9wRm9ybURpY3QgfHwgIXBQYWdlLT5tX3BGb3JtRGljdC0+S2V5RXhpc3QoIlR5cGUiKQ0KLQkJfHwgcFBhZ2UtPm1fcEZvcm1EaWN0LT5HZXRFbGVtZW50KCJUeXBlIiktPkdldERpcmVjdCgpLT5HZXRTdHJpbmcoKS5Db21wYXJlKCJQYWdlIikpDQotCXsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQlDUERGX1BhZ2VDb250ZW50R2VuZXJhdGUgQ0cocFBhZ2UpOw0KLQlDRy5HZW5lcmF0ZUNvbnRlbnQoKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VPYmpfVHJhbnNmb3JtKEZQREZfUEFHRU9CSkVDVCBwYWdlX29iamVjdCwNCi0JCQkgZG91YmxlIGEsIGRvdWJsZSBiLCBkb3VibGUgYywgZG91YmxlIGQsIGRvdWJsZSBlLCBkb3VibGUgZikgIA0KLXsNCi0JQ1BERl9QYWdlT2JqZWN0KiBwUGFnZU9iaiA9IChDUERGX1BhZ2VPYmplY3QqKXBhZ2Vfb2JqZWN0Ow0KLQlpZihwUGFnZU9iaiA9PSBOVUxMKQ0KLQkJcmV0dXJuOw0KLS8vUERGX0ltYWdlT2JqZWN0KiBwSW1hZ2VPYmogPSBGWF9ORVcgQ1BERl9JbWFnZU9iamVjdDsNCi0JQ0ZYX0FmZmluZU1hdHJpeCBtYXRyaXgoKEZYX0ZMT0FUKWEsKEZYX0ZMT0FUKWIsKEZYX0ZMT0FUKWMsKEZYX0ZMT0FUKWQsKEZYX0ZMT0FUKWUsKEZYX0ZMT0FUKWYpOw0KLQlwUGFnZU9iai0+VHJhbnNmb3JtKG1hdHJpeCk7DQotfQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VfVHJhbnNmb3JtQW5ub3RzKEZQREZfUEFHRSBwYWdlLA0KLQkJCQkJCQkJCQkJICAgZG91YmxlIGEsIGRvdWJsZSBiLCBkb3VibGUgYywgZG91YmxlIGQsIGRvdWJsZSBlLCBkb3VibGUgZikNCi17DQotCWlmKHBhZ2UgPT0gTlVMTCkNCi0JCXJldHVybjsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotCUNQREZfQW5ub3RMaXN0IEFubm90TGlzdChwUGFnZSk7DQotCWZvciAoaW50IGk9MDsgaTxBbm5vdExpc3QuQ291bnQoKTtpKyspDQotCXsNCi0JCUNQREZfQW5ub3QqIHBBbm5vdCA9IEFubm90TGlzdC5HZXRBdChpKTsNCi0JCS8vIHRyYW5zZm9ybUFubm90cyBSZWN0YW5nbGUNCi0JCUNQREZfUmVjdCByZWN0Ow0KLQkJcEFubm90LT5HZXRSZWN0KHJlY3QpOw0KLQkJQ0ZYX0FmZmluZU1hdHJpeCBtYXRyaXgoKEZYX0ZMT0FUKWEsKEZYX0ZMT0FUKWIsKEZYX0ZMT0FUKWMsKEZYX0ZMT0FUKWQsKEZYX0ZMT0FUKWUsKEZYX0ZMT0FUKWYpOw0KLQkJcmVjdC5UcmFuc2Zvcm0oJm1hdHJpeCk7DQotCQlDUERGX0FycmF5ICpwUmVjdEFycmF5ID0gTlVMTDsNCi0JCXBSZWN0QXJyYXkgPSBwQW5ub3QtPm1fcEFubm90RGljdC0+R2V0QXJyYXkoIlJlY3QiKTsNCi0JCWlmICghcFJlY3RBcnJheSkgcFJlY3RBcnJheT1DUERGX0FycmF5OjpDcmVhdGUoKTsNCi0JCXBSZWN0QXJyYXktPlNldEF0KDAsRlhfTkVXIENQREZfTnVtYmVyKHJlY3QubGVmdCkpOw0KLQkJcFJlY3RBcnJheS0+U2V0QXQoMSxGWF9ORVcgQ1BERl9OdW1iZXIocmVjdC5ib3R0b20pKTsNCi0JCXBSZWN0QXJyYXktPlNldEF0KDIsRlhfTkVXIENQREZfTnVtYmVyKHJlY3QucmlnaHQpKTsNCi0JCXBSZWN0QXJyYXktPlNldEF0KDMsRlhfTkVXIENQREZfTnVtYmVyKHJlY3QudG9wKSk7DQotCQlwQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXQoIlJlY3QiLHBSZWN0QXJyYXkpOw0KLQ0KLQkJLy9UcmFuc2Zvcm0gQVAncyByZWN0YW5nbGUNCi0JCS8vVG8gRG8NCi0NCi0JfQ0KLQ0KLX0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisvLyAjaW5jbHVkZSAieDovcGRmL2ZwZGZhcGk1L2luY2x1ZGUvZnBkZmFwaS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZlZGl0LmgiCisKKworI2lmIF9GWF9PU18gPT0gX0ZYX0FORFJPSURfCisjaW5jbHVkZSAidGltZS5oIgorI2Vsc2UKKyNpbmNsdWRlIDxjdGltZT4KKyNlbmRpZgorCitETExFWFBPUlQgRlBERl9ET0NVTUVOVCBTVERDQUxMIEZQREZfQ3JlYXRlTmV3RG9jdW1lbnQoKQoreworCUNQREZfRG9jdW1lbnQqIHBEb2MgPSBGWF9ORVcgQ1BERl9Eb2N1bWVudDsKKwlpZiAoIXBEb2MpCisJCXJldHVybiBOVUxMOworCXBEb2MtPkNyZWF0ZU5ld0RvYygpOworCXRpbWVfdCBjdXJyZW50VGltZTsKKworCUNGWF9CeXRlU3RyaW5nIERhdGVTdHI7CisKKwlpZihGU0RLX0lzU2FuZEJveFBvbGljeUVuYWJsZWQoRlBERl9QT0xJQ1lfTUFDSElORVRJTUVfQUNDRVNTKSkKKwl7CisJCWlmICggLTEgIT0gdGltZSggJmN1cnJlbnRUaW1lICkgKQorCQl7CisJCQl0bSAqIHBUTSA9IGxvY2FsdGltZSggJmN1cnJlbnRUaW1lICk7CisJCQlpZiAoIHBUTSApCisJCQl7CisJCQkJRGF0ZVN0ci5Gb3JtYXQoCSJEOiUwNGQlMDJkJTAyZCUwMmQlMDJkJTAyZCIsIHBUTS0+dG1feWVhcisxOTAwLCBwVE0tPnRtX21vbisxLAorCQkJCQlwVE0tPnRtX21kYXksIHBUTS0+dG1faG91ciwgcFRNLT50bV9taW4sIHBUTS0+dG1fc2VjICk7CisJCQl9CisJCX0KKwl9CisJCisJQ1BERl9EaWN0aW9uYXJ5KiBwSW5mb0RpY3QgPSBOVUxMOworCXBJbmZvRGljdCA9IHBEb2MtPkdldEluZm8oKTsKKwlpZiAocEluZm9EaWN0KQorCXsKKwkJaWYoRlNES19Jc1NhbmRCb3hQb2xpY3lFbmFibGVkKEZQREZfUE9MSUNZX01BQ0hJTkVUSU1FX0FDQ0VTUykpCisJCQlwSW5mb0RpY3QtPlNldEF0KCJDcmVhdGlvbkRhdGUiLCBuZXcgQ1BERl9TdHJpbmcoRGF0ZVN0cikpOworI2lmZGVmIEZPWElUX0NIUk9NRV9CVUlMRAorCQlwSW5mb0RpY3QtPlNldEF0KCJDcmVhdG9yIixGWF9ORVcgQ1BERl9TdHJpbmcoTCJHb29nbGUiKSk7CisjZWxzZQorCQlwSW5mb0RpY3QtPlNldEF0KCJDcmVhdG9yIixGWF9ORVcgQ1BERl9TdHJpbmcoTCJGb3hpdCBQREYgU0RLIERMTCAyLjAgLSBGb3hpdCBTb2Z0d2FyZSIpKTsKKyNlbmRpZgorCX0KKworCXJldHVybiBwRG9jOworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZQYWdlX0RlbGV0ZShGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBpbnQgcGFnZV9pbmRleCkKK3sKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50OworCWlmIChwRG9jID09IE5VTEwpIAorCQlyZXR1cm47CisJaWYgKHBhZ2VfaW5kZXggPCAwIHx8IHBhZ2VfaW5kZXggPj0gcERvYy0+R2V0UGFnZUNvdW50KCkpIAorCQlyZXR1cm47CisKKwlwRG9jLT5EZWxldGVQYWdlKHBhZ2VfaW5kZXgpOworfQorCitETExFWFBPUlQgRlBERl9QQUdFIFNURENBTEwgRlBERlBhZ2VfTmV3KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsIGludCBwYWdlX2luZGV4LCBkb3VibGUgd2lkdGgsIGRvdWJsZSBoZWlnaHQpCit7CisJaWYgKCFkb2N1bWVudCkKKwkJcmV0dXJuIE5VTEw7CisKKy8vCUNQREZfUGFyc2VyKiBwUGFyc2VyID0gKENQREZfUGFyc2VyKilkb2N1bWVudDsKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50OworCWlmKHBhZ2VfaW5kZXggPCAwKQorCQlwYWdlX2luZGV4ID0gMDsKKwlpZihwRG9jLT5HZXRQYWdlQ291bnQoKTxwYWdlX2luZGV4KQorCQlwYWdlX2luZGV4ID0gcERvYy0+R2V0UGFnZUNvdW50KCk7CisvLwlpZiAocGFnZV9pbmRleCA8IDAgfHwgcGFnZV9pbmRleCA+PSBwRG9jLT5HZXRQYWdlQ291bnQoKSkgCisvLwkJcmV0dXJuIE5VTEw7CisKKwlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBEb2MtPkNyZWF0ZU5ld1BhZ2UocGFnZV9pbmRleCk7CisJaWYoIXBQYWdlRGljdCkKKwkJcmV0dXJuIE5VTEw7CisJQ1BERl9BcnJheSogcE1lZGlhQm94QXJyYXkgPSBGWF9ORVcgQ1BERl9BcnJheTsKKwlwTWVkaWFCb3hBcnJheS0+QWRkKEZYX05FVyBDUERGX051bWJlcigwKSk7CisJcE1lZGlhQm94QXJyYXktPkFkZChGWF9ORVcgQ1BERl9OdW1iZXIoMCkpOworCXBNZWRpYUJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKEZYX0ZMT0FUKHdpZHRoKSkpOworCXBNZWRpYUJveEFycmF5LT5BZGQoRlhfTkVXIENQREZfTnVtYmVyKEZYX0ZMT0FUKGhlaWdodCkpKTsKKworCXBQYWdlRGljdC0+U2V0QXQoIk1lZGlhQm94IiwgcE1lZGlhQm94QXJyYXkpOworCXBQYWdlRGljdC0+U2V0QXQoIlJvdGF0ZSIsIEZYX05FVyBDUERGX051bWJlcigwKSk7CisJcFBhZ2VEaWN0LT5TZXRBdCgiUmVzb3VyY2VzIiwgRlhfTkVXIENQREZfRGljdGlvbmFyeSk7CisKKwlDUERGX1BhZ2UqIHBQYWdlID0gRlhfTkVXIENQREZfUGFnZTsKKwlwUGFnZS0+TG9hZChwRG9jLHBQYWdlRGljdCk7CisJcFBhZ2UtPlBhcnNlQ29udGVudCgpOworCisJcmV0dXJuIHBQYWdlOworfQorCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlBhZ2VfR2V0Um90YXRpb24oRlBERl9QQUdFIHBhZ2UpCit7CisJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7CisJaWYgKCFwUGFnZSB8fCAhcFBhZ2UtPm1fcEZvcm1EaWN0IHx8ICFwUGFnZS0+bV9wRm9ybURpY3QtPktleUV4aXN0KCJUeXBlIikKKwkJfHwgcFBhZ2UtPm1fcEZvcm1EaWN0LT5HZXRFbGVtZW50KCJUeXBlIiktPkdldERpcmVjdCgpLT5HZXRTdHJpbmcoKS5Db21wYXJlKCJQYWdlIikpCisJeworCQlyZXR1cm4gLTE7CisJfQorCUNQREZfRGljdGlvbmFyeSogcERpY3QgPSBwUGFnZS0+bV9wRm9ybURpY3Q7CisKKwlpbnQgcm90YXRlID0gMDsKKwlpZihwRGljdCAhPSBOVUxMKQorCXsKKwkJaWYocERpY3QtPktleUV4aXN0KCJSb3RhdGUiKSkKKwkJCXJvdGF0ZSA9IHBEaWN0LT5HZXRFbGVtZW50KCJSb3RhdGUiKS0+R2V0RGlyZWN0KCktPkdldEludGVnZXIoKSAvIDkwOworCQllbHNlCisJCXsKKwkJCWlmKHBEaWN0LT5LZXlFeGlzdCgiUGFyZW50IikpCisJCQl7CisJCQkJQ1BERl9EaWN0aW9uYXJ5KiBwUGFnZXMgPSAoQ1BERl9EaWN0aW9uYXJ5KilwRGljdC0+R2V0RWxlbWVudCgiUGFyZW50IiktPkdldERpcmVjdCgpOworCQkJCXdoaWxlKHBQYWdlcykKKwkJCQl7CisJCQkJCWlmKHBQYWdlcy0+S2V5RXhpc3QoIlJvdGF0ZSIpKQorCQkJCQl7CisJCQkJCQlyb3RhdGUgPSBwUGFnZXMtPkdldEVsZW1lbnQoIlJvdGF0ZSIpLT5HZXREaXJlY3QoKS0+R2V0SW50ZWdlcigpIC8gOTA7CisJCQkJCQlicmVhazsKKwkJCQkJfQorCQkJCQllbHNlIGlmKHBQYWdlcy0+S2V5RXhpc3QoIlBhcmVudCIpKQorCQkJCQkJcFBhZ2VzID0gKENQREZfRGljdGlvbmFyeSopcFBhZ2VzLT5HZXRFbGVtZW50KCJQYXJlbnQiKS0+R2V0RGlyZWN0KCk7CisJCQkJCWVsc2UgYnJlYWs7CisJCQkJfQorCQkJfQorCQl9CisJfQorCWVsc2UKKwl7CisJCXJldHVybiAtMTsKKwl9CisJCisJcmV0dXJuIHJvdGF0ZTsKK30KKworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGUGFnZV9JbnNlcnRPYmplY3QoRlBERl9QQUdFIHBhZ2UsIEZQREZfUEFHRU9CSkVDVCBwYWdlX29iaikKK3sKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKwlpZiAoIXBQYWdlIHx8ICFwUGFnZS0+bV9wRm9ybURpY3QgfHwgIXBQYWdlLT5tX3BGb3JtRGljdC0+S2V5RXhpc3QoIlR5cGUiKQorCQl8fCBwUGFnZS0+bV9wRm9ybURpY3QtPkdldEVsZW1lbnQoIlR5cGUiKS0+R2V0RGlyZWN0KCktPkdldFN0cmluZygpLkNvbXBhcmUoIlBhZ2UiKSkKKwl7CisJCXJldHVybjsKKwl9CisJQ1BERl9QYWdlT2JqZWN0KiBwUGFnZU9iaiA9IChDUERGX1BhZ2VPYmplY3QqKXBhZ2Vfb2JqOworCWlmKHBQYWdlT2JqID09IE5VTEwpCisJCXJldHVybjsKKwlGWF9QT1NJVElPTiBMYXN0UGVyc2l0aW9uID0gcFBhZ2UtPkdldExhc3RPYmplY3RQb3NpdGlvbigpOworCisJcFBhZ2UtPkluc2VydE9iamVjdChMYXN0UGVyc2l0aW9uLCBwUGFnZU9iaik7CisJc3dpdGNoKHBQYWdlT2JqLT5tX1R5cGUpCisJeworCWNhc2UgRlBERl9QQUdFT0JKX1BBVEg6CisJCXsKKwkJCUNQREZfUGF0aE9iamVjdCogcFBhdGhPYmogPSAoQ1BERl9QYXRoT2JqZWN0KilwUGFnZU9iajsKKwkJCXBQYXRoT2JqLT5DYWxjQm91bmRpbmdCb3goKTsKKwkJCWJyZWFrOworCQl9CisJY2FzZSBGUERGX1BBR0VPQkpfVEVYVDoKKwkJeworCQkJLy8JQ1BERl9QYXRoT2JqZWN0KiBwUGF0aE9iaiA9IChDUERGX1BhdGhPYmplY3QqKXBQYWdlT2JqOworCQkJLy8JcFBhdGhPYmotPkNhbGNCb3VuZGluZ0JveCgpOworCQkJYnJlYWs7CisJCX0KKwljYXNlIEZQREZfUEFHRU9CSl9JTUFHRToKKwkJeworCQkJQ1BERl9JbWFnZU9iamVjdCogcEltYWdlT2JqID0gKENQREZfSW1hZ2VPYmplY3QqKXBQYWdlT2JqOworCQkJcEltYWdlT2JqLT5DYWxjQm91bmRpbmdCb3goKTsKKwkJCWJyZWFrOworCQl9CisJY2FzZSBGUERGX1BBR0VPQkpfU0hBRElORzoKKwkJeworCQkJQ1BERl9TaGFkaW5nT2JqZWN0KiBwU2hhZGluZ09iaiA9IChDUERGX1NoYWRpbmdPYmplY3QqKXBQYWdlT2JqOworCQkJcFNoYWRpbmdPYmotPkNhbGNCb3VuZGluZ0JveCgpOworCQkJYnJlYWs7CisJCX0KKwljYXNlIEZQREZfUEFHRU9CSl9GT1JNOgorCQl7CisJCQlDUERGX0Zvcm1PYmplY3QqIHBGb3JtT2JqID0gKENQREZfRm9ybU9iamVjdCopcFBhZ2VPYmo7CisJCQlwRm9ybU9iai0+Q2FsY0JvdW5kaW5nQm94KCk7CisJCQlicmVhazsKKwkJfQorCWRlZmF1bHQ6CisJCWJyZWFrOworCX0KKworCS8vCXBQYWdlLT5QYXJzZUNvbnRlbnQoKTsKKwkvL3BQYWdlLT5HZW5lcmF0ZUNvbnRlbnQoKTsKKworfQorCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlBhZ2VfQ291bnRPYmplY3QoRlBERl9QQUdFIHBhZ2UpCit7CisJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7CisJaWYgKCFwUGFnZSB8fCAhcFBhZ2UtPm1fcEZvcm1EaWN0IHx8ICFwUGFnZS0+bV9wRm9ybURpY3QtPktleUV4aXN0KCJUeXBlIikKKwkJfHwgcFBhZ2UtPm1fcEZvcm1EaWN0LT5HZXRFbGVtZW50KCJUeXBlIiktPkdldERpcmVjdCgpLT5HZXRTdHJpbmcoKS5Db21wYXJlKCJQYWdlIikpCisJeworCQlyZXR1cm4gLTE7CisJfQorCXJldHVybiBwUGFnZS0+Q291bnRPYmplY3RzKCk7CisvLwlyZXR1cm4gMDsKK30KKworRExMRVhQT1JUIEZQREZfUEFHRU9CSkVDVCBTVERDQUxMIEZQREZQYWdlX0dldE9iamVjdChGUERGX1BBR0UgcGFnZSwgaW50IGluZGV4KQoreworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCWlmICghcFBhZ2UgfHwgIXBQYWdlLT5tX3BGb3JtRGljdCB8fCAhcFBhZ2UtPm1fcEZvcm1EaWN0LT5LZXlFeGlzdCgiVHlwZSIpCisJCXx8IHBQYWdlLT5tX3BGb3JtRGljdC0+R2V0RWxlbWVudCgiVHlwZSIpLT5HZXREaXJlY3QoKS0+R2V0U3RyaW5nKCkuQ29tcGFyZSgiUGFnZSIpKQorCXsKKwkJcmV0dXJuIE5VTEw7CisJfQorCXJldHVybiBwUGFnZS0+R2V0T2JqZWN0QnlJbmRleChpbmRleCk7CisvLwlyZXR1cm4gTlVMTDsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlX0hhc1RyYW5zcGFyZW5jeShGUERGX1BBR0UgcGFnZSkKK3sKKwlpZighcGFnZSkgcmV0dXJuIEZBTFNFOworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCisJcmV0dXJuIHBQYWdlLT5CYWNrZ3JvdW5kQWxwaGFOZWVkZWQoKTsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZQYWdlT2JqX0hhc1RyYW5zcGFyZW5jeShGUERGX1BBR0VPQkpFQ1QgcGFnZU9iamVjdCkKK3sKKwlpZighcGFnZU9iamVjdCkgcmV0dXJuIEZBTFNFOworCUNQREZfUGFnZU9iamVjdCogcFBhZ2VPYmogPSAoQ1BERl9QYWdlT2JqZWN0KilwYWdlT2JqZWN0OworCisJY29uc3QgQ1BERl9HZW5lcmFsU3RhdGVEYXRhKiBwR2VuZXJhbFN0YXRlID0gcFBhZ2VPYmotPm1fR2VuZXJhbFN0YXRlOworCWludCBibGVuZF90eXBlID0gcEdlbmVyYWxTdGF0ZSA/IHBHZW5lcmFsU3RhdGUtPm1fQmxlbmRUeXBlIDogRlhESUJfQkxFTkRfTk9STUFMOworCWlmIChibGVuZF90eXBlICE9IEZYRElCX0JMRU5EX05PUk1BTCkgcmV0dXJuIFRSVUU7CisKKwlDUERGX0RpY3Rpb25hcnkqIHBTTWFza0RpY3QgPSBwR2VuZXJhbFN0YXRlID8gKENQREZfRGljdGlvbmFyeSopcEdlbmVyYWxTdGF0ZS0+bV9wU29mdE1hc2sgOiBOVUxMOworCWlmKHBTTWFza0RpY3QpIHJldHVybiBUUlVFOworCisJaWYocEdlbmVyYWxTdGF0ZSAmJiBwR2VuZXJhbFN0YXRlLT5tX0ZpbGxBbHBoYSAhPSAxLjBmKQorCQlyZXR1cm4gVFJVRTsKKworCWlmKHBQYWdlT2JqLT5tX1R5cGUgPT0gUERGUEFHRV9QQVRIKQorCXsKKwkJaWYocEdlbmVyYWxTdGF0ZSAmJiBwR2VuZXJhbFN0YXRlLT5tX1N0cm9rZUFscGhhICE9IDEuMGYpCisJCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlpZihwUGFnZU9iai0+bV9UeXBlID09IFBERlBBR0VfRk9STSkKKwl7CisJCUNQREZfRm9ybU9iamVjdCogcEZvcm1PYmogPSAoQ1BERl9Gb3JtT2JqZWN0KilwUGFnZU9iajsKKwkJaWYocEZvcm1PYmotPm1fcEZvcm0gJiYgKHBGb3JtT2JqLT5tX3BGb3JtLT5tX1RyYW5zcGFyZW5jeSAmIFBERlRSQU5TX0lTT0xBVEVEKSkKKwkJCXJldHVybiBUUlVFOworCQlpZihwRm9ybU9iai0+bV9wRm9ybSAmJiAoIShwRm9ybU9iai0+bV9wRm9ybS0+bV9UcmFuc3BhcmVuY3kgJiBQREZUUkFOU19JU09MQVRFRCkgJiYgKHBGb3JtT2JqLT5tX3BGb3JtLT5tX1RyYW5zcGFyZW5jeSAmIFBERlRSQU5TX0dST1VQKSkpCisJCQlyZXR1cm4gVFJVRTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERlBhZ2VfR2VuZXJhdGVDb250ZW50KEZQREZfUEFHRSBwYWdlKQoreworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCWlmICghcFBhZ2UgfHwgIXBQYWdlLT5tX3BGb3JtRGljdCB8fCAhcFBhZ2UtPm1fcEZvcm1EaWN0LT5LZXlFeGlzdCgiVHlwZSIpCisJCXx8IHBQYWdlLT5tX3BGb3JtRGljdC0+R2V0RWxlbWVudCgiVHlwZSIpLT5HZXREaXJlY3QoKS0+R2V0U3RyaW5nKCkuQ29tcGFyZSgiUGFnZSIpKQorCXsKKwkJcmV0dXJuIEZBTFNFOworCX0KKwlDUERGX1BhZ2VDb250ZW50R2VuZXJhdGUgQ0cocFBhZ2UpOworCUNHLkdlbmVyYXRlQ29udGVudCgpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlBhZ2VPYmpfVHJhbnNmb3JtKEZQREZfUEFHRU9CSkVDVCBwYWdlX29iamVjdCwKKwkJCSBkb3VibGUgYSwgZG91YmxlIGIsIGRvdWJsZSBjLCBkb3VibGUgZCwgZG91YmxlIGUsIGRvdWJsZSBmKSAgCit7CisJQ1BERl9QYWdlT2JqZWN0KiBwUGFnZU9iaiA9IChDUERGX1BhZ2VPYmplY3QqKXBhZ2Vfb2JqZWN0OworCWlmKHBQYWdlT2JqID09IE5VTEwpCisJCXJldHVybjsKKy8vUERGX0ltYWdlT2JqZWN0KiBwSW1hZ2VPYmogPSBGWF9ORVcgQ1BERl9JbWFnZU9iamVjdDsKKwlDRlhfQWZmaW5lTWF0cml4IG1hdHJpeCgoRlhfRkxPQVQpYSwoRlhfRkxPQVQpYiwoRlhfRkxPQVQpYywoRlhfRkxPQVQpZCwoRlhfRkxPQVQpZSwoRlhfRkxPQVQpZik7CisJcFBhZ2VPYmotPlRyYW5zZm9ybShtYXRyaXgpOworfQorRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGUGFnZV9UcmFuc2Zvcm1Bbm5vdHMoRlBERl9QQUdFIHBhZ2UsCisJCQkJCQkJCQkJCSAgIGRvdWJsZSBhLCBkb3VibGUgYiwgZG91YmxlIGMsIGRvdWJsZSBkLCBkb3VibGUgZSwgZG91YmxlIGYpCit7CisJaWYocGFnZSA9PSBOVUxMKQorCQlyZXR1cm47CisJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7CisJQ1BERl9Bbm5vdExpc3QgQW5ub3RMaXN0KHBQYWdlKTsKKwlmb3IgKGludCBpPTA7IGk8QW5ub3RMaXN0LkNvdW50KCk7aSsrKQorCXsKKwkJQ1BERl9Bbm5vdCogcEFubm90ID0gQW5ub3RMaXN0LkdldEF0KGkpOworCQkvLyB0cmFuc2Zvcm1Bbm5vdHMgUmVjdGFuZ2xlCisJCUNQREZfUmVjdCByZWN0OworCQlwQW5ub3QtPkdldFJlY3QocmVjdCk7CisJCUNGWF9BZmZpbmVNYXRyaXggbWF0cml4KChGWF9GTE9BVClhLChGWF9GTE9BVCliLChGWF9GTE9BVCljLChGWF9GTE9BVClkLChGWF9GTE9BVCllLChGWF9GTE9BVClmKTsKKwkJcmVjdC5UcmFuc2Zvcm0oJm1hdHJpeCk7CisJCUNQREZfQXJyYXkgKnBSZWN0QXJyYXkgPSBOVUxMOworCQlwUmVjdEFycmF5ID0gcEFubm90LT5tX3BBbm5vdERpY3QtPkdldEFycmF5KCJSZWN0Iik7CisJCWlmICghcFJlY3RBcnJheSkgcFJlY3RBcnJheT1DUERGX0FycmF5OjpDcmVhdGUoKTsKKwkJcFJlY3RBcnJheS0+U2V0QXQoMCxGWF9ORVcgQ1BERl9OdW1iZXIocmVjdC5sZWZ0KSk7CisJCXBSZWN0QXJyYXktPlNldEF0KDEsRlhfTkVXIENQREZfTnVtYmVyKHJlY3QuYm90dG9tKSk7CisJCXBSZWN0QXJyYXktPlNldEF0KDIsRlhfTkVXIENQREZfTnVtYmVyKHJlY3QucmlnaHQpKTsKKwkJcFJlY3RBcnJheS0+U2V0QXQoMyxGWF9ORVcgQ1BERl9OdW1iZXIocmVjdC50b3ApKTsKKwkJcEFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0KCJSZWN0IixwUmVjdEFycmF5KTsKKworCQkvL1RyYW5zZm9ybSBBUCdzIHJlY3RhbmdsZQorCQkvL1RvIERvCisKKwl9CisKK30KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2ZwZGZmb3JtZmlsbC5jcHAgYi9mcGRmc2RrL3NyYy9mcGRmZm9ybWZpbGwuY3BwCmluZGV4IDEwMTE0NmIuLjJkZTc2MDMgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZwZGZmb3JtZmlsbC5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnBkZmZvcm1maWxsLmNwcApAQCAtMSw0NDEgKzEsNDQxIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmdmlldy5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZmb3JtZmlsbC5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19tZ3IuaCINCi0NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotDQotDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQRFBhZ2VfSGFzRm9ybUZpZWxkQXRQb2ludChGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgRlBERl9QQUdFIHBhZ2UsZG91YmxlIHBhZ2VfeCwgZG91YmxlIHBhZ2VfeSkNCi17DQotCWlmKCFwYWdlIHx8ICFoSGFuZGxlKQ0KLQkJcmV0dXJuIC0xOw0KLQlDUERGX1BhZ2UgKiBwUGFnZSA9IChDUERGX1BhZ2UqKSBwYWdlOw0KLQ0KLQlDUERGX0ludGVyRm9ybSAqIHBJbnRlckZvcm0gPSBOVUxMOw0KLQlwSW50ZXJGb3JtID0gbmV3IENQREZfSW50ZXJGb3JtKHBQYWdlLT5tX3BEb2N1bWVudCxGQUxTRSk7DQotCWlmICghcEludGVyRm9ybSkNCi0JCXJldHVybiAtMTsNCi0JQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gcEludGVyRm9ybS0+R2V0Q29udHJvbEF0UG9pbnQocFBhZ2UsIChGWF9GTE9BVClwYWdlX3gsIChGWF9GTE9BVClwYWdlX3kpOw0KLQlpZighcEZvcm1DdHJsKQ0KLQl7DQotCQlkZWxldGUgcEludGVyRm9ybTsNCi0JCXJldHVybiAtMTsNCi0JfQ0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IHBGb3JtQ3RybC0+R2V0RmllbGQoKTsNCi0JaWYoIXBGb3JtRmllbGQpDQotCXsNCi0JCWRlbGV0ZSBwSW50ZXJGb3JtOw0KLQkJcmV0dXJuIC0xOw0KLQl9DQotCQ0KLQlpbnQgblR5cGUgPSBwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKTsNCi0JZGVsZXRlIHBJbnRlckZvcm07DQotCXJldHVybiBuVHlwZTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfRk9STUhBTkRMRSBTVERDQUxMIEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9GT1JNRklMTElORk8qIGZvcm1JbmZvKQ0KLXsNCi0JaWYoIWRvY3VtZW50IHx8ICFmb3JtSW5mbyB8fCBmb3JtSW5mby0+dmVyc2lvbiE9MSkNCi0JCXJldHVybiBOVUxMOw0KLQlDUERGX0RvY3VtZW50ICogcERvY3VtZW50ID0gKENQREZfRG9jdW1lbnQqKSBkb2N1bWVudDsNCi0gCUNQREZEb2NfRW52aXJvbm1lbnQgKiBwRW52ID0gTlVMTDsNCi0JcEVudiA9IG5ldyBDUERGRG9jX0Vudmlyb25tZW50KHBEb2N1bWVudCk7DQotCWlmICghcEVudikNCi0JCXJldHVybiBOVUxMOw0KLQlwRW52LT5SZWdBcHBIYW5kbGUoZm9ybUluZm8pOw0KLQ0KLQlpZihwRW52LT5HZXRQREZEb2N1bWVudCgpKQ0KLQl7DQotCQlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gbmV3IENQREZTREtfRG9jdW1lbnQocEVudi0+R2V0UERGRG9jdW1lbnQoKSwgcEVudik7DQotCQlpZihwU0RLRG9jKQ0KLQkJCXBFbnYtPlNldEN1cnJlbnREb2MocFNES0RvYyk7DQotCX0NCi0JcmV0dXJuIHBFbnY7DQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkRPQ19FeGl0Rm9ybUZpbGxFbnZpcm91bWVudChGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSkNCi17DQotCWlmKCFoSGFuZGxlKQ0KLQkJcmV0dXJuOyANCi0JQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsNCi0JaWYocFNES0RvYykNCi0Jew0KLQkJKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+U2V0Q3VycmVudERvYyhOVUxMKTsNCi0JCWRlbGV0ZSBwU0RLRG9jOw0KLQl9DQotCWRlbGV0ZSAoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZTsNCi0JaEhhbmRsZSA9IE5VTEw7DQotfQ0KLQ0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX09uTW91c2VNb3ZlKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLCBGUERGX1BBR0UgcGFnZSwgaW50IG1vZGlmaWVyLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95KQ0KLXsJDQotCWlmICghaEhhbmRsZSB8fCAhcGFnZSkNCi0JCXJldHVybiBGQUxTRTsNCi0vLyAJQ1BERl9QYWdlICogcFBhZ2UgPSAoQ1BERl9QYWdlKikgcGFnZTsNCi0vLyAJQ1BERl9Eb2N1bWVudCAqIHBEb2MgPSBwUGFnZS0+bV9wRG9jdW1lbnQ7DQotLy8JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlOw0KLQlDUERGU0RLX0RvY3VtZW50KiBwRlhEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCk7DQotCWlmKCFwRlhEb2MpDQotCQlyZXR1cm4gRkFMU0U7DQotCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBGWERvYy0+R2V0UGFnZVZpZXcoKENQREZfUGFnZSopcGFnZSk7DQotCWlmKCFwUGFnZVZpZXcpDQotCQlyZXR1cm4gRkFMU0U7DQotCQ0KLS8vIAlkb3VibGUgcGFnZV94ID0gMDsNCi0vLyAJZG91YmxlIHBhZ2VfeSA9IDA7DQotLy8JcEVudi0+RkZJX0RldmljZVRvUGFnZShwYWdlLCBwb2ludF94LCBwb2ludF95LCAmcGFnZV94LCAmcGFnZV95KTsNCi0JQ1BERl9Qb2ludCBwdCgoRlhfRkxPQVQpcGFnZV94LCAoRlhfRkxPQVQpcGFnZV95KTsNCi0JcmV0dXJuIHBQYWdlVmlldy0+T25Nb3VzZU1vdmUocHQsIG1vZGlmaWVyKTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25MQnV0dG9uRG93bihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgRlBERl9QQUdFIHBhZ2UsIGludCBtb2RpZmllciwgZG91YmxlIHBhZ2VfeCwgZG91YmxlIHBhZ2VfeSkNCi17DQotCWlmICghaEhhbmRsZSB8fCAhcGFnZSkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ1BERlNES19Eb2N1bWVudCogcEZYRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpOw0KLQlpZighcEZYRG9jKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwRlhEb2MtPkdldFBhZ2VWaWV3KChDUERGX1BhZ2UqKXBhZ2UpOw0KLQlpZighcFBhZ2VWaWV3KQ0KLQkJcmV0dXJuIEZBTFNFOw0KLS8vIAlkb3VibGUgcGFnZV94ID0gMDsNCi0vLyAJZG91YmxlIHBhZ2VfeSA9IDA7DQotLy8gCXBFbnYtPkZGSV9EZXZpY2VUb1BhZ2UocGFnZSwgcG9pbnRfeCwgcG9pbnRfeSwgJnBhZ2VfeCwgJnBhZ2VfeSk7DQotCUNQREZfUG9pbnQgcHQoKEZYX0ZMT0FUKXBhZ2VfeCwgKEZYX0ZMT0FUKXBhZ2VfeSk7DQotIAlyZXR1cm4gcFBhZ2VWaWV3LT5PbkxCdXR0b25Eb3duKHB0LCBtb2RpZmllcik7DQotfQ0KLQ0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX09uTEJ1dHRvblVwKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLCBGUERGX1BBR0UgcGFnZSwgaW50IG1vZGlmaWVyLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95KQ0KLXsNCi0JaWYgKCFoSGFuZGxlIHx8ICFwYWdlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDUERGU0RLX0RvY3VtZW50KiBwRlhEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCk7DQotCWlmKCFwRlhEb2MpDQotCQlyZXR1cm4gRkFMU0U7DQotCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBGWERvYy0+R2V0UGFnZVZpZXcoKENQREZfUGFnZSopcGFnZSk7DQotCWlmKCFwUGFnZVZpZXcpDQotCQlyZXR1cm4gRkFMU0U7DQotLy8gCWRvdWJsZSBwYWdlX3ggPSAwOw0KLS8vIAlkb3VibGUgcGFnZV95ID0gMDsNCi0vLyAJcEVudi0+RkZJX0RldmljZVRvUGFnZShwYWdlLCBwb2ludF94LCBwb2ludF95LCAmcGFnZV94LCAmcGFnZV95KTsNCi0JQ1BERl9Qb2ludCBwdCgoRlhfRkxPQVQpcGFnZV94LCAoRlhfRkxPQVQpcGFnZV95KTsNCi0JcmV0dXJuIHBQYWdlVmlldy0+T25MQnV0dG9uVXAocHQsIG1vZGlmaWVyKTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25LZXlEb3duKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLCBGUERGX1BBR0UgcGFnZSwgaW50IG5LZXlDb2RlLCBpbnQgbW9kaWZpZXIpDQotew0KLQlpZiAoIWhIYW5kbGUgfHwgIXBhZ2UpDQotCQlyZXR1cm4gRkFMU0U7DQotCUNQREZTREtfRG9jdW1lbnQqIHBGWERvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsNCi0JaWYoIXBGWERvYykNCi0JCXJldHVybiBGQUxTRTsNCi0JQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcEZYRG9jLT5HZXRQYWdlVmlldygoQ1BERl9QYWdlKilwYWdlKTsNCi0JaWYoIXBQYWdlVmlldykNCi0JCXJldHVybiBGQUxTRTsNCi0JDQotCQ0KLQlyZXR1cm4gcFBhZ2VWaWV3LT5PbktleURvd24obktleUNvZGUsIG1vZGlmaWVyKTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25LZXlVcChGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgRlBERl9QQUdFIHBhZ2UsIGludCBuS2V5Q29kZSwgaW50IG1vZGlmaWVyKQ0KLXsNCi0JaWYgKCFoSGFuZGxlIHx8ICFwYWdlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDUERGU0RLX0RvY3VtZW50KiBwRlhEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCk7DQotCWlmKCFwRlhEb2MpDQotCQlyZXR1cm4gRkFMU0U7DQotCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBGWERvYy0+R2V0UGFnZVZpZXcoKENQREZfUGFnZSopcGFnZSk7DQotCWlmKCFwUGFnZVZpZXcpDQotCQlyZXR1cm4gRkFMU0U7DQotCQ0KLQkNCi0JcmV0dXJuIHBQYWdlVmlldy0+T25LZXlVcChuS2V5Q29kZSwgbW9kaWZpZXIpOw0KLX0NCi0NCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRk9STV9PbkNoYXIoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIEZQREZfUEFHRSBwYWdlLCBpbnQgbkNoYXIsICBpbnQgbW9kaWZpZXIpDQotew0KLQlpZiAoIWhIYW5kbGUgfHwgIXBhZ2UpDQotCQlyZXR1cm4gRkFMU0U7DQotCUNQREZTREtfRG9jdW1lbnQqIHBGWERvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsNCi0JaWYoIXBGWERvYykNCi0JCXJldHVybiBGQUxTRTsNCi0JQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcEZYRG9jLT5HZXRQYWdlVmlldygoQ1BERl9QYWdlKilwYWdlKTsNCi0JaWYoIXBQYWdlVmlldykNCi0JCXJldHVybiBGQUxTRTsNCi0JcmV0dXJuIHBQYWdlVmlldy0+T25DaGFyKG5DaGFyLCBtb2RpZmllcik7DQotDQotfQ0KLQ0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX0ZvcmNlVG9LaWxsRm9jdXMoRlBERl9GT1JNSEFORExFIGhIYW5kbGUpDQotew0KLQlpZighaEhhbmRsZSkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsNCi0JaWYoIXBTREtEb2MpDQotCQlyZXR1cm4gRkFMU0U7DQotCS8vS2lsbCB0aGUgY3VycmVudCBmb2N1cy4gDQotCXJldHVybiBwU0RLRG9jLT5LaWxsRm9jdXNBbm5vdCgwKTsNCi19DQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX0ZGTERyYXcoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIEZQREZfQklUTUFQIGJpdG1hcCwgRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgDQotCQkJCQkJCQkJCQkJICBpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LCBpbnQgcm90YXRlLCBpbnQgZmxhZ3MpDQotew0KLQlpZiAoIWhIYW5kbGUgfHwgIXBhZ2UpDQotCQlyZXR1cm4gOw0KLQlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsNCi0JDQotCUNQREZfUmVuZGVyT3B0aW9ucyBvcHRpb25zOw0KLQlpZiAoZmxhZ3MgJiBGUERGX0xDRF9URVhUKQ0KLQkJb3B0aW9ucy5tX0ZsYWdzIHw9IFJFTkRFUl9DTEVBUlRZUEU7DQotCWVsc2UNCi0JCW9wdGlvbnMubV9GbGFncyAmPSB+UkVOREVSX0NMRUFSVFlQRTsNCi0JDQotCS8vR3JheXNjYWxlIG91dHB1dA0KLQlpZiAoZmxhZ3MgJiBGUERGX0dSQVlTQ0FMRSkNCi0Jew0KLQkJb3B0aW9ucy5tX0NvbG9yTW9kZSA9IFJFTkRFUl9DT0xPUl9HUkFZOw0KLQkJb3B0aW9ucy5tX0ZvcmVDb2xvciA9IDA7DQotCQlvcHRpb25zLm1fQmFja0NvbG9yID0gMHhmZmZmZmY7DQotCX0NCi0JDQotCW9wdGlvbnMubV9BZGRGbGFncyA9IGZsYWdzID4+IDg7DQotDQotCW9wdGlvbnMubV9wT0NDb250ZXh0ID0gRlhfTkVXIENQREZfT0NDb250ZXh0KHBQYWdlLT5tX3BEb2N1bWVudCk7DQotDQotCS8vRlhNVF9DU0xPQ0tfT0JKKCZwUGFnZS0+bV9QYWdlTG9jayk7DQotCQ0KLQlDRlhfQWZmaW5lTWF0cml4IG1hdHJpeDsNCi0JcFBhZ2UtPkdldERpc3BsYXlNYXRyaXgobWF0cml4LCBzdGFydF94LCBzdGFydF95LCBzaXplX3gsIHNpemVfeSwgcm90YXRlKTsgDQotCQ0KLQlGWF9SRUNUIGNsaXA7DQotCWNsaXAubGVmdCA9IHN0YXJ0X3g7DQotCWNsaXAucmlnaHQgPSBzdGFydF94ICsgc2l6ZV94Ow0KLQljbGlwLnRvcCA9IHN0YXJ0X3k7DQotCWNsaXAuYm90dG9tID0gc3RhcnRfeSArIHNpemVfeTsNCi0NCi0jaWZkZWYgX1NLSUFfU1VQUE9SVF8NCi0JQ0ZYX1NraWFEZXZpY2UqIHBEZXZpY2UgPSBGWF9ORVcgQ0ZYX1NraWFEZXZpY2U7DQotI2Vsc2UNCi0JQ0ZYX0Z4Z2VEZXZpY2UqIHBEZXZpY2UgPSBOVUxMOw0KLQlwRGV2aWNlID0gRlhfTkVXIENGWF9GeGdlRGV2aWNlOw0KLSNlbmRpZg0KLQ0KLQlpZiAoIXBEZXZpY2UpDQotCQlyZXR1cm47DQotCXBEZXZpY2UtPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXApOw0KLQlwRGV2aWNlLT5TYXZlU3RhdGUoKTsNCi0JcERldmljZS0+U2V0Q2xpcF9SZWN0KCZjbGlwKTsNCi0JDQotDQotCUNQREZfUmVuZGVyQ29udGV4dCogcENvbnRleHQgPSBOVUxMOw0KLQlwQ29udGV4dCA9IEZYX05FVyBDUERGX1JlbmRlckNvbnRleHQ7DQotCWlmICghcENvbnRleHQpDQotCXsNCi0JCWRlbGV0ZSBwRGV2aWNlOw0KLQkJcERldmljZSA9IE5VTEw7DQotCQlyZXR1cm47DQotCX0NCi0NCi0NCi0vLwlDUERGX0RvY3VtZW50KiBwRG9jID0gcFBhZ2UtPm1fcERvY3VtZW50Ow0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGU7DQotCUNQREZTREtfRG9jdW1lbnQqIHBGWERvYyA9IHBFbnYtPkdldEN1cnJlbnREb2MoKTsNCi0JaWYoIXBGWERvYykNCi0Jew0KLQkJZGVsZXRlIHBDb250ZXh0Ow0KLQkJZGVsZXRlIHBEZXZpY2U7DQotCQlwQ29udGV4dCA9IE5VTEw7DQotCQlwRGV2aWNlID0gTlVMTDsNCi0JCXJldHVybjsNCi0JfQ0KLQlpZihDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwRlhEb2MtPkdldFBhZ2VWaWV3KHBQYWdlKSkNCi0Jew0KLQkJcFBhZ2VWaWV3LT5QYWdlVmlld19PbkRyYXcocERldmljZSwgJm1hdHJpeCwgJm9wdGlvbnMpOw0KLQl9DQotCXBEZXZpY2UtPlJlc3RvcmVTdGF0ZSgpOw0KLQ0KLQlpZihvcHRpb25zLm1fcE9DQ29udGV4dCkNCi0Jew0KLQkJZGVsZXRlIG9wdGlvbnMubV9wT0NDb250ZXh0Ow0KLQkJb3B0aW9ucy5tX3BPQ0NvbnRleHQgPSBOVUxMOw0KLQl9DQotCWlmKHBDb250ZXh0KQ0KLQl7DQotCQlkZWxldGUgcENvbnRleHQ7DQotCQlwQ29udGV4dCA9IE5VTEw7DQotCX0NCi0JaWYocERldmljZSkNCi0Jew0KLQkJZGVsZXRlIHBEZXZpY2U7DQotCQlwRGV2aWNlID0gTlVMTDsNCi0JfQ0KLQ0KLX0NCi0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfU2V0Rm9ybUZpZWxkSGlnaGxpZ2h0Q29sb3IoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIGludCBmaWVsZFR5cGUsIHVuc2lnbmVkIGxvbmcgY29sb3IpDQotew0KLQlpZiAoIWhIYW5kbGUpDQotCQlyZXR1cm47DQotLy8JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IChDUERGRG9jX0Vudmlyb25tZW50KiApaEhhbmRsZTsNCi0JQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsNCi0JaWYocFNES0RvYykNCi0Jew0KLQkJaWYoQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSBwU0RLRG9jLT5HZXRJbnRlckZvcm0oKSkNCi0JCXsNCi0JCQlwSW50ZXJGb3JtLT5TZXRIaWdobGlnaHRDb2xvcihjb2xvciwgZmllbGRUeXBlKTsNCi0JCX0NCi0JDQotCX0NCi0NCi19DQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX1NldEZvcm1GaWVsZEhpZ2hsaWdodEFscGhhKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLCB1bnNpZ25lZCBjaGFyIGFscGhhKQ0KLXsNCi0JaWYgKCFoSGFuZGxlKQ0KLQkJcmV0dXJuOw0KLQlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpOw0KLQlpZihwU0RLRG9jKQ0KLQl7DQotCQlpZihDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBTREtEb2MtPkdldEludGVyRm9ybSgpKQ0KLQkJCXBJbnRlckZvcm0tPlNldEhpZ2hsaWdodEFscGhhKGFscGhhKTsNCi0JfQ0KLX0NCi0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfUmVtb3ZlRm9ybUZpZWxkSGlnaGxpZ2h0KEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKQ0KLXsNCi0JaWYgKCFoSGFuZGxlKQ0KLQkJcmV0dXJuOw0KLQlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpOw0KLQlpZihwU0RLRG9jKQ0KLQl7DQotCQlpZihDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBTREtEb2MtPkdldEludGVyRm9ybSgpKQ0KLQkJCXBJbnRlckZvcm0tPlJlbW92ZUFsbEhpZ2hMaWdodCgpOw0KLQl9DQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9PbkFmdGVyTG9hZFBhZ2UoRlBERl9QQUdFIHBhZ2UsIEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKQ0KLXsNCi0JaWYoIWhIYW5kbGUgfHwgIXBhZ2UpDQotCQlyZXR1cm47DQotCUNQREZTREtfRG9jdW1lbnQqIHBTREtEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCk7DQotCWlmKCFwU0RLRG9jKQ0KLQkJcmV0dXJuOw0KLQlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsNCi0JQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcFNES0RvYy0+R2V0UGFnZVZpZXcocFBhZ2UsIFRSVUUpOw0KLQlpZihwUGFnZVZpZXcpDQotCXsNCi0JCXBQYWdlVmlldy0+U2V0VmFsaWQoVFJVRSk7DQotCX0JDQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9PbkJlZm9yZUNsb3NlUGFnZShGUERGX1BBR0UgcGFnZSwgRlBERl9GT1JNSEFORExFIGhIYW5kbGUpDQotew0KLQlpZighaEhhbmRsZSB8fCAhcGFnZSkNCi0JCXJldHVybjsNCi0JQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBTREtEb2MtPkdldFBhZ2VWaWV3KHBQYWdlLCBGQUxTRSk7DQotCWlmKHBQYWdlVmlldykNCi0Jew0KLQkJcFBhZ2VWaWV3LT5TZXRWYWxpZChGQUxTRSk7DQotCQkvLyBSZU1vdmVQYWdlVmlldygpIHRha2VzIGNhcmUgb2YgdGhlIGRlbGV0ZSBmb3IgdXMuDQotCQlwU0RLRG9jLT5SZU1vdmVQYWdlVmlldyhwUGFnZSk7DQotCX0NCi19DQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGT1JNX0RvRG9jdW1lbnRKU0FjdGlvbihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSkNCi17DQotCWlmKCFoSGFuZGxlKQ0KLQkJcmV0dXJuOw0KLQlpZiggQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKSkNCi0Jew0KLQkJcFNES0RvYy0+SW5pdFBhZ2VWaWV3KCk7DQotCQlpZigoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5Jc0pTSW5pdGlhdGVkKCkpDQotCQkJcFNES0RvYy0+UHJvY0phdmFzY3JpcHRGdW4oKTsNCi0JfQkNCi19DQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGT1JNX0RvRG9jdW1lbnRPcGVuQWN0aW9uKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKQ0KLXsNCi0JaWYoIWhIYW5kbGUpDQotCQlyZXR1cm47DQotCWlmKCBDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpKQ0KLQl7DQotCQlpZigoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5Jc0pTSW5pdGlhdGVkKCkpDQotCQkJcFNES0RvYy0+UHJvY09wZW5BY3Rpb24oKTsNCi0JfQ0KLX0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fRG9Eb2N1bWVudEFBY3Rpb24oRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIGludCBhYVR5cGUpDQotew0KLQlpZighaEhhbmRsZSkNCi0JCXJldHVybjsNCi0JQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsNCi0JaWYocFNES0RvYykNCi0Jew0KLQkJQ1BERl9Eb2N1bWVudCogcERvYyA9IHBTREtEb2MtPkdldERvY3VtZW50KCk7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBEaWMgPSBwRG9jLT5HZXRSb290KCk7DQotCQlpZiAoIXBEaWMpDQotCQkJcmV0dXJuOw0KLQkJQ1BERl9BQWN0aW9uIGFhID0gcERpYy0+R2V0RGljdChGWF9CU1RSQygiQUEiKSk7DQotCQkNCi0JCWlmKGFhLkFjdGlvbkV4aXN0KChDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlKWFhVHlwZSkpDQotCQl7DQotCQkJQ1BERl9BY3Rpb24gYWN0aW9uID0gYWEuR2V0QWN0aW9uKChDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlKWFhVHlwZSk7DQotCQkJQ1BERlNES19BY3Rpb25IYW5kbGVyICpwQWN0aW9uSGFuZGxlciA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEFjdGlvbkhhbmRlcigpOw0KLQkJCUFTU0VSVChwQWN0aW9uSGFuZGxlciAhPSBOVUxMKTsNCi0JCQlwQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fRG9jdW1lbnQoYWN0aW9uLCAoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSlhYVR5cGUsIHBTREtEb2MpOw0KLQkJfQ0KLQl9DQotfQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9Eb1BhZ2VBQWN0aW9uKEZQREZfUEFHRSBwYWdlLCBGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgaW50IGFhVHlwZSkNCi17DQotCWlmKCFoSGFuZGxlIHx8ICFwYWdlKQ0KLQkJcmV0dXJuOw0KLQlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpOw0KLQlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsNCi0JQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcFNES0RvYy0+R2V0UGFnZVZpZXcocFBhZ2UsIEZBTFNFKTsNCi0JaWYocFBhZ2VWaWV3KQ0KLQl7DQotCQlDUERGRG9jX0Vudmlyb25tZW50ICpwRW52ID0gcFNES0RvYy0+R2V0RW52KCk7DQotCQlBU1NFUlQocEVudiAhPSBOVUxMKTsNCi0JCQkNCi0JCUNQREZTREtfQWN0aW9uSGFuZGxlciAqcEFjdGlvbkhhbmRsZXIgPSBwRW52LT5HZXRBY3Rpb25IYW5kZXIoKTsNCi0JCUFTU0VSVChwQWN0aW9uSGFuZGxlciAhPSBOVUxMKTsNCi0JCQ0KLQkJQ1BERl9EaWN0aW9uYXJ5ICpwUGFnZURpY3QgPSBwUGFnZS0+bV9wRm9ybURpY3Q7DQotCQlBU1NFUlQocFBhZ2VEaWN0ICE9IE5VTEwpOw0KLQkJIA0KLQkJQ1BERl9BQWN0aW9uIGFhID0gcFBhZ2VEaWN0LT5HZXREaWN0KEZYX0JTVFJDKCJBQSIpKTsNCi0NCi0JCUZYX0JPT0wgYkV4aXN0T0FBY3Rpb24gPSBGQUxTRTsNCi0JCUZYX0JPT0wgYkV4aXN0Q0FBY3Rpb24gPSBGQUxTRTsNCi0JCWlmIChGUERGUEFHRV9BQUNUSU9OX09QRU4gPT0gYWFUeXBlKQ0KLQkJew0KLQkJCWJFeGlzdE9BQWN0aW9uID0gYWEuQWN0aW9uRXhpc3QoQ1BERl9BQWN0aW9uOjpPcGVuUGFnZSk7DQotCQkJaWYgKGJFeGlzdE9BQWN0aW9uKQ0KLQkJCXsNCi0JCQkJQ1BERl9BY3Rpb24gYWN0aW9uID0gYWEuR2V0QWN0aW9uKENQREZfQUFjdGlvbjo6T3BlblBhZ2UpOw0KLQkJCQlwQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fUGFnZShhY3Rpb24sIENQREZfQUFjdGlvbjo6T3BlblBhZ2UsIHBTREtEb2MpOw0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQliRXhpc3RDQUFjdGlvbiA9IGFhLkFjdGlvbkV4aXN0KENQREZfQUFjdGlvbjo6Q2xvc2VQYWdlKTsNCi0JCQlpZiAoYkV4aXN0Q0FBY3Rpb24pDQotCQkJew0KLQkJCQlDUERGX0FjdGlvbiBhY3Rpb24gPSBhYS5HZXRBY3Rpb24oQ1BERl9BQWN0aW9uOjpDbG9zZVBhZ2UpOw0KLQkJCQlwQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fUGFnZShhY3Rpb24sIENQREZfQUFjdGlvbjo6Q2xvc2VQYWdlLCBwU0RLRG9jKTsNCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZnZpZXcuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZmb3JtZmlsbC5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfbWdyLmgiCisKKworI2luY2x1ZGUgIi4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorCisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERQYWdlX0hhc0Zvcm1GaWVsZEF0UG9pbnQoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIEZQREZfUEFHRSBwYWdlLGRvdWJsZSBwYWdlX3gsIGRvdWJsZSBwYWdlX3kpCit7CisJaWYoIXBhZ2UgfHwgIWhIYW5kbGUpCisJCXJldHVybiAtMTsKKwlDUERGX1BhZ2UgKiBwUGFnZSA9IChDUERGX1BhZ2UqKSBwYWdlOworCisJQ1BERl9JbnRlckZvcm0gKiBwSW50ZXJGb3JtID0gTlVMTDsKKwlwSW50ZXJGb3JtID0gbmV3IENQREZfSW50ZXJGb3JtKHBQYWdlLT5tX3BEb2N1bWVudCxGQUxTRSk7CisJaWYgKCFwSW50ZXJGb3JtKQorCQlyZXR1cm4gLTE7CisJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gcEludGVyRm9ybS0+R2V0Q29udHJvbEF0UG9pbnQocFBhZ2UsIChGWF9GTE9BVClwYWdlX3gsIChGWF9GTE9BVClwYWdlX3kpOworCWlmKCFwRm9ybUN0cmwpCisJeworCQlkZWxldGUgcEludGVyRm9ybTsKKwkJcmV0dXJuIC0xOworCX0KKwlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IHBGb3JtQ3RybC0+R2V0RmllbGQoKTsKKwlpZighcEZvcm1GaWVsZCkKKwl7CisJCWRlbGV0ZSBwSW50ZXJGb3JtOworCQlyZXR1cm4gLTE7CisJfQorCQorCWludCBuVHlwZSA9IHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpOworCWRlbGV0ZSBwSW50ZXJGb3JtOworCXJldHVybiBuVHlwZTsKK30KKworRExMRVhQT1JUIEZQREZfRk9STUhBTkRMRSBTVERDQUxMIEZQREZET0NfSW5pdEZvcm1GaWxsRW52aXJvdW1lbnQoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgRlBERl9GT1JNRklMTElORk8qIGZvcm1JbmZvKQoreworCWlmKCFkb2N1bWVudCB8fCAhZm9ybUluZm8gfHwgZm9ybUluZm8tPnZlcnNpb24hPTEpCisJCXJldHVybiBOVUxMOworCUNQREZfRG9jdW1lbnQgKiBwRG9jdW1lbnQgPSAoQ1BERl9Eb2N1bWVudCopIGRvY3VtZW50OworIAlDUERGRG9jX0Vudmlyb25tZW50ICogcEVudiA9IE5VTEw7CisJcEVudiA9IG5ldyBDUERGRG9jX0Vudmlyb25tZW50KHBEb2N1bWVudCk7CisJaWYgKCFwRW52KQorCQlyZXR1cm4gTlVMTDsKKwlwRW52LT5SZWdBcHBIYW5kbGUoZm9ybUluZm8pOworCisJaWYocEVudi0+R2V0UERGRG9jdW1lbnQoKSkKKwl7CisJCUNQREZTREtfRG9jdW1lbnQqIHBTREtEb2MgPSBuZXcgQ1BERlNES19Eb2N1bWVudChwRW52LT5HZXRQREZEb2N1bWVudCgpLCBwRW52KTsKKwkJaWYocFNES0RvYykKKwkJCXBFbnYtPlNldEN1cnJlbnREb2MocFNES0RvYyk7CisJfQorCXJldHVybiBwRW52OworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZET0NfRXhpdEZvcm1GaWxsRW52aXJvdW1lbnQoRlBERl9GT1JNSEFORExFIGhIYW5kbGUpCit7CisJaWYoIWhIYW5kbGUpCisJCXJldHVybjsgCisJQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsKKwlpZihwU0RLRG9jKQorCXsKKwkJKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+U2V0Q3VycmVudERvYyhOVUxMKTsKKwkJZGVsZXRlIHBTREtEb2M7CisJfQorCWRlbGV0ZSAoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZTsKKwloSGFuZGxlID0gTlVMTDsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZPUk1fT25Nb3VzZU1vdmUoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIEZQREZfUEFHRSBwYWdlLCBpbnQgbW9kaWZpZXIsIGRvdWJsZSBwYWdlX3gsIGRvdWJsZSBwYWdlX3kpCit7CQorCWlmICghaEhhbmRsZSB8fCAhcGFnZSkKKwkJcmV0dXJuIEZBTFNFOworLy8gCUNQREZfUGFnZSAqIHBQYWdlID0gKENQREZfUGFnZSopIHBhZ2U7CisvLyAJQ1BERl9Eb2N1bWVudCAqIHBEb2MgPSBwUGFnZS0+bV9wRG9jdW1lbnQ7CisvLwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGU7CisJQ1BERlNES19Eb2N1bWVudCogcEZYRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpOworCWlmKCFwRlhEb2MpCisJCXJldHVybiBGQUxTRTsKKwlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwRlhEb2MtPkdldFBhZ2VWaWV3KChDUERGX1BhZ2UqKXBhZ2UpOworCWlmKCFwUGFnZVZpZXcpCisJCXJldHVybiBGQUxTRTsKKwkKKy8vIAlkb3VibGUgcGFnZV94ID0gMDsKKy8vIAlkb3VibGUgcGFnZV95ID0gMDsKKy8vCXBFbnYtPkZGSV9EZXZpY2VUb1BhZ2UocGFnZSwgcG9pbnRfeCwgcG9pbnRfeSwgJnBhZ2VfeCwgJnBhZ2VfeSk7CisJQ1BERl9Qb2ludCBwdCgoRlhfRkxPQVQpcGFnZV94LCAoRlhfRkxPQVQpcGFnZV95KTsKKwlyZXR1cm4gcFBhZ2VWaWV3LT5Pbk1vdXNlTW92ZShwdCwgbW9kaWZpZXIpOworfQorCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRk9STV9PbkxCdXR0b25Eb3duKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLCBGUERGX1BBR0UgcGFnZSwgaW50IG1vZGlmaWVyLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95KQoreworCWlmICghaEhhbmRsZSB8fCAhcGFnZSkKKwkJcmV0dXJuIEZBTFNFOworCUNQREZTREtfRG9jdW1lbnQqIHBGWERvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsKKwlpZighcEZYRG9jKQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcEZYRG9jLT5HZXRQYWdlVmlldygoQ1BERl9QYWdlKilwYWdlKTsKKwlpZighcFBhZ2VWaWV3KQorCQlyZXR1cm4gRkFMU0U7CisvLyAJZG91YmxlIHBhZ2VfeCA9IDA7CisvLyAJZG91YmxlIHBhZ2VfeSA9IDA7CisvLyAJcEVudi0+RkZJX0RldmljZVRvUGFnZShwYWdlLCBwb2ludF94LCBwb2ludF95LCAmcGFnZV94LCAmcGFnZV95KTsKKwlDUERGX1BvaW50IHB0KChGWF9GTE9BVClwYWdlX3gsIChGWF9GTE9BVClwYWdlX3kpOworIAlyZXR1cm4gcFBhZ2VWaWV3LT5PbkxCdXR0b25Eb3duKHB0LCBtb2RpZmllcik7Cit9CisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX09uTEJ1dHRvblVwKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLCBGUERGX1BBR0UgcGFnZSwgaW50IG1vZGlmaWVyLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95KQoreworCWlmICghaEhhbmRsZSB8fCAhcGFnZSkKKwkJcmV0dXJuIEZBTFNFOworCUNQREZTREtfRG9jdW1lbnQqIHBGWERvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsKKwlpZighcEZYRG9jKQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcEZYRG9jLT5HZXRQYWdlVmlldygoQ1BERl9QYWdlKilwYWdlKTsKKwlpZighcFBhZ2VWaWV3KQorCQlyZXR1cm4gRkFMU0U7CisvLyAJZG91YmxlIHBhZ2VfeCA9IDA7CisvLyAJZG91YmxlIHBhZ2VfeSA9IDA7CisvLyAJcEVudi0+RkZJX0RldmljZVRvUGFnZShwYWdlLCBwb2ludF94LCBwb2ludF95LCAmcGFnZV94LCAmcGFnZV95KTsKKwlDUERGX1BvaW50IHB0KChGWF9GTE9BVClwYWdlX3gsIChGWF9GTE9BVClwYWdlX3kpOworCXJldHVybiBwUGFnZVZpZXctPk9uTEJ1dHRvblVwKHB0LCBtb2RpZmllcik7Cit9CisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX09uS2V5RG93bihGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgRlBERl9QQUdFIHBhZ2UsIGludCBuS2V5Q29kZSwgaW50IG1vZGlmaWVyKQoreworCWlmICghaEhhbmRsZSB8fCAhcGFnZSkKKwkJcmV0dXJuIEZBTFNFOworCUNQREZTREtfRG9jdW1lbnQqIHBGWERvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsKKwlpZighcEZYRG9jKQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcEZYRG9jLT5HZXRQYWdlVmlldygoQ1BERl9QYWdlKilwYWdlKTsKKwlpZighcFBhZ2VWaWV3KQorCQlyZXR1cm4gRkFMU0U7CisJCisJCisJcmV0dXJuIHBQYWdlVmlldy0+T25LZXlEb3duKG5LZXlDb2RlLCBtb2RpZmllcik7Cit9CisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGT1JNX09uS2V5VXAoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIEZQREZfUEFHRSBwYWdlLCBpbnQgbktleUNvZGUsIGludCBtb2RpZmllcikKK3sKKwlpZiAoIWhIYW5kbGUgfHwgIXBhZ2UpCisJCXJldHVybiBGQUxTRTsKKwlDUERGU0RLX0RvY3VtZW50KiBwRlhEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCk7CisJaWYoIXBGWERvYykKKwkJcmV0dXJuIEZBTFNFOworCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBGWERvYy0+R2V0UGFnZVZpZXcoKENQREZfUGFnZSopcGFnZSk7CisJaWYoIXBQYWdlVmlldykKKwkJcmV0dXJuIEZBTFNFOworCQorCQorCXJldHVybiBwUGFnZVZpZXctPk9uS2V5VXAobktleUNvZGUsIG1vZGlmaWVyKTsKK30KKworCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRk9STV9PbkNoYXIoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIEZQREZfUEFHRSBwYWdlLCBpbnQgbkNoYXIsICBpbnQgbW9kaWZpZXIpCit7CisJaWYgKCFoSGFuZGxlIHx8ICFwYWdlKQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERlNES19Eb2N1bWVudCogcEZYRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpOworCWlmKCFwRlhEb2MpCisJCXJldHVybiBGQUxTRTsKKwlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwRlhEb2MtPkdldFBhZ2VWaWV3KChDUERGX1BhZ2UqKXBhZ2UpOworCWlmKCFwUGFnZVZpZXcpCisJCXJldHVybiBGQUxTRTsKKwlyZXR1cm4gcFBhZ2VWaWV3LT5PbkNoYXIobkNoYXIsIG1vZGlmaWVyKTsKKworfQorCitETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRk9STV9Gb3JjZVRvS2lsbEZvY3VzKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKQoreworCWlmKCFoSGFuZGxlKQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsKKwlpZighcFNES0RvYykKKwkJcmV0dXJuIEZBTFNFOworCS8vS2lsbCB0aGUgY3VycmVudCBmb2N1cy4gCisJcmV0dXJuIHBTREtEb2MtPktpbGxGb2N1c0Fubm90KDApOworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfRkZMRHJhdyhGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgRlBERl9CSVRNQVAgYml0bWFwLCBGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCAKKwkJCQkJCQkJCQkJCSAgaW50IHNpemVfeCwgaW50IHNpemVfeSwgaW50IHJvdGF0ZSwgaW50IGZsYWdzKQoreworCWlmICghaEhhbmRsZSB8fCAhcGFnZSkKKwkJcmV0dXJuIDsKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKwkKKwlDUERGX1JlbmRlck9wdGlvbnMgb3B0aW9uczsKKwlpZiAoZmxhZ3MgJiBGUERGX0xDRF9URVhUKQorCQlvcHRpb25zLm1fRmxhZ3MgfD0gUkVOREVSX0NMRUFSVFlQRTsKKwllbHNlCisJCW9wdGlvbnMubV9GbGFncyAmPSB+UkVOREVSX0NMRUFSVFlQRTsKKwkKKwkvL0dyYXlzY2FsZSBvdXRwdXQKKwlpZiAoZmxhZ3MgJiBGUERGX0dSQVlTQ0FMRSkKKwl7CisJCW9wdGlvbnMubV9Db2xvck1vZGUgPSBSRU5ERVJfQ09MT1JfR1JBWTsKKwkJb3B0aW9ucy5tX0ZvcmVDb2xvciA9IDA7CisJCW9wdGlvbnMubV9CYWNrQ29sb3IgPSAweGZmZmZmZjsKKwl9CisJCisJb3B0aW9ucy5tX0FkZEZsYWdzID0gZmxhZ3MgPj4gODsKKworCW9wdGlvbnMubV9wT0NDb250ZXh0ID0gRlhfTkVXIENQREZfT0NDb250ZXh0KHBQYWdlLT5tX3BEb2N1bWVudCk7CisKKwkvL0ZYTVRfQ1NMT0NLX09CSigmcFBhZ2UtPm1fUGFnZUxvY2spOworCQorCUNGWF9BZmZpbmVNYXRyaXggbWF0cml4OworCXBQYWdlLT5HZXREaXNwbGF5TWF0cml4KG1hdHJpeCwgc3RhcnRfeCwgc3RhcnRfeSwgc2l6ZV94LCBzaXplX3ksIHJvdGF0ZSk7IAorCQorCUZYX1JFQ1QgY2xpcDsKKwljbGlwLmxlZnQgPSBzdGFydF94OworCWNsaXAucmlnaHQgPSBzdGFydF94ICsgc2l6ZV94OworCWNsaXAudG9wID0gc3RhcnRfeTsKKwljbGlwLmJvdHRvbSA9IHN0YXJ0X3kgKyBzaXplX3k7CisKKyNpZmRlZiBfU0tJQV9TVVBQT1JUXworCUNGWF9Ta2lhRGV2aWNlKiBwRGV2aWNlID0gRlhfTkVXIENGWF9Ta2lhRGV2aWNlOworI2Vsc2UKKwlDRlhfRnhnZURldmljZSogcERldmljZSA9IE5VTEw7CisJcERldmljZSA9IEZYX05FVyBDRlhfRnhnZURldmljZTsKKyNlbmRpZgorCisJaWYgKCFwRGV2aWNlKQorCQlyZXR1cm47CisJcERldmljZS0+QXR0YWNoKChDRlhfRElCaXRtYXAqKWJpdG1hcCk7CisJcERldmljZS0+U2F2ZVN0YXRlKCk7CisJcERldmljZS0+U2V0Q2xpcF9SZWN0KCZjbGlwKTsKKwkKKworCUNQREZfUmVuZGVyQ29udGV4dCogcENvbnRleHQgPSBOVUxMOworCXBDb250ZXh0ID0gRlhfTkVXIENQREZfUmVuZGVyQ29udGV4dDsKKwlpZiAoIXBDb250ZXh0KQorCXsKKwkJZGVsZXRlIHBEZXZpY2U7CisJCXBEZXZpY2UgPSBOVUxMOworCQlyZXR1cm47CisJfQorCisKKy8vCUNQREZfRG9jdW1lbnQqIHBEb2MgPSBwUGFnZS0+bV9wRG9jdW1lbnQ7CisJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlOworCUNQREZTREtfRG9jdW1lbnQqIHBGWERvYyA9IHBFbnYtPkdldEN1cnJlbnREb2MoKTsKKwlpZighcEZYRG9jKQorCXsKKwkJZGVsZXRlIHBDb250ZXh0OworCQlkZWxldGUgcERldmljZTsKKwkJcENvbnRleHQgPSBOVUxMOworCQlwRGV2aWNlID0gTlVMTDsKKwkJcmV0dXJuOworCX0KKwlpZihDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwRlhEb2MtPkdldFBhZ2VWaWV3KHBQYWdlKSkKKwl7CisJCXBQYWdlVmlldy0+UGFnZVZpZXdfT25EcmF3KHBEZXZpY2UsICZtYXRyaXgsICZvcHRpb25zKTsKKwl9CisJcERldmljZS0+UmVzdG9yZVN0YXRlKCk7CisKKwlpZihvcHRpb25zLm1fcE9DQ29udGV4dCkKKwl7CisJCWRlbGV0ZSBvcHRpb25zLm1fcE9DQ29udGV4dDsKKwkJb3B0aW9ucy5tX3BPQ0NvbnRleHQgPSBOVUxMOworCX0KKwlpZihwQ29udGV4dCkKKwl7CisJCWRlbGV0ZSBwQ29udGV4dDsKKwkJcENvbnRleHQgPSBOVUxMOworCX0KKwlpZihwRGV2aWNlKQorCXsKKwkJZGVsZXRlIHBEZXZpY2U7CisJCXBEZXZpY2UgPSBOVUxMOworCX0KKworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfU2V0Rm9ybUZpZWxkSGlnaGxpZ2h0Q29sb3IoRlBERl9GT1JNSEFORExFIGhIYW5kbGUsIGludCBmaWVsZFR5cGUsIHVuc2lnbmVkIGxvbmcgY29sb3IpCit7CisJaWYgKCFoSGFuZGxlKQorCQlyZXR1cm47CisvLwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gKENQREZEb2NfRW52aXJvbm1lbnQqICloSGFuZGxlOworCUNQREZTREtfRG9jdW1lbnQqIHBTREtEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCk7CisJaWYocFNES0RvYykKKwl7CisJCWlmKENQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gcFNES0RvYy0+R2V0SW50ZXJGb3JtKCkpCisJCXsKKwkJCXBJbnRlckZvcm0tPlNldEhpZ2hsaWdodENvbG9yKGNvbG9yLCBmaWVsZFR5cGUpOworCQl9CisJCisJfQorCit9CisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9TZXRGb3JtRmllbGRIaWdobGlnaHRBbHBoYShGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgdW5zaWduZWQgY2hhciBhbHBoYSkKK3sKKwlpZiAoIWhIYW5kbGUpCisJCXJldHVybjsKKwlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpOworCWlmKHBTREtEb2MpCisJeworCQlpZihDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBTREtEb2MtPkdldEludGVyRm9ybSgpKQorCQkJcEludGVyRm9ybS0+U2V0SGlnaGxpZ2h0QWxwaGEoYWxwaGEpOworCX0KK30KKworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX1JlbW92ZUZvcm1GaWVsZEhpZ2hsaWdodChGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSkKK3sKKwlpZiAoIWhIYW5kbGUpCisJCXJldHVybjsKKwlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jID0gKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+R2V0Q3VycmVudERvYygpOworCWlmKHBTREtEb2MpCisJeworCQlpZihDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBTREtEb2MtPkdldEludGVyRm9ybSgpKQorCQkJcEludGVyRm9ybS0+UmVtb3ZlQWxsSGlnaExpZ2h0KCk7CisJfQorfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fT25BZnRlckxvYWRQYWdlKEZQREZfUEFHRSBwYWdlLCBGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSkKK3sKKwlpZighaEhhbmRsZSB8fCAhcGFnZSkKKwkJcmV0dXJuOworCUNQREZTREtfRG9jdW1lbnQqIHBTREtEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCk7CisJaWYoIXBTREtEb2MpCisJCXJldHVybjsKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKwlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwU0RLRG9jLT5HZXRQYWdlVmlldyhwUGFnZSwgVFJVRSk7CisJaWYocFBhZ2VWaWV3KQorCXsKKwkJcFBhZ2VWaWV3LT5TZXRWYWxpZChUUlVFKTsKKwl9CQorfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fT25CZWZvcmVDbG9zZVBhZ2UoRlBERl9QQUdFIHBhZ2UsIEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKQoreworCWlmKCFoSGFuZGxlIHx8ICFwYWdlKQorCQlyZXR1cm47CisJQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKwlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwU0RLRG9jLT5HZXRQYWdlVmlldyhwUGFnZSwgRkFMU0UpOworCWlmKHBQYWdlVmlldykKKwl7CisJCXBQYWdlVmlldy0+U2V0VmFsaWQoRkFMU0UpOworCQkvLyBSZU1vdmVQYWdlVmlldygpIHRha2VzIGNhcmUgb2YgdGhlIGRlbGV0ZSBmb3IgdXMuCisJCXBTREtEb2MtPlJlTW92ZVBhZ2VWaWV3KHBQYWdlKTsKKwl9Cit9CitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fRG9Eb2N1bWVudEpTQWN0aW9uKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlKQoreworCWlmKCFoSGFuZGxlKQorCQlyZXR1cm47CisJaWYoIENQREZTREtfRG9jdW1lbnQqIHBTREtEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCkpCisJeworCQlwU0RLRG9jLT5Jbml0UGFnZVZpZXcoKTsKKwkJaWYoKChDUERGRG9jX0Vudmlyb25tZW50KiloSGFuZGxlKS0+SXNKU0luaXRpYXRlZCgpKQorCQkJcFNES0RvYy0+UHJvY0phdmFzY3JpcHRGdW4oKTsKKwl9CQorfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZPUk1fRG9Eb2N1bWVudE9wZW5BY3Rpb24oRlBERl9GT1JNSEFORExFIGhIYW5kbGUpCit7CisJaWYoIWhIYW5kbGUpCisJCXJldHVybjsKKwlpZiggQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKSkKKwl7CisJCWlmKCgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPklzSlNJbml0aWF0ZWQoKSkKKwkJCXBTREtEb2MtPlByb2NPcGVuQWN0aW9uKCk7CisJfQorfQorRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGT1JNX0RvRG9jdW1lbnRBQWN0aW9uKEZQREZfRk9STUhBTkRMRSBoSGFuZGxlLCBpbnQgYWFUeXBlKQoreworCWlmKCFoSGFuZGxlKQorCQlyZXR1cm47CisJQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEN1cnJlbnREb2MoKTsKKwlpZihwU0RLRG9jKQorCXsKKwkJQ1BERl9Eb2N1bWVudCogcERvYyA9IHBTREtEb2MtPkdldERvY3VtZW50KCk7CisJCUNQREZfRGljdGlvbmFyeSogcERpYyA9IHBEb2MtPkdldFJvb3QoKTsKKwkJaWYgKCFwRGljKQorCQkJcmV0dXJuOworCQlDUERGX0FBY3Rpb24gYWEgPSBwRGljLT5HZXREaWN0KEZYX0JTVFJDKCJBQSIpKTsKKwkJCisJCWlmKGFhLkFjdGlvbkV4aXN0KChDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlKWFhVHlwZSkpCisJCXsKKwkJCUNQREZfQWN0aW9uIGFjdGlvbiA9IGFhLkdldEFjdGlvbigoQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSlhYVR5cGUpOworCQkJQ1BERlNES19BY3Rpb25IYW5kbGVyICpwQWN0aW9uSGFuZGxlciA9ICgoQ1BERkRvY19FbnZpcm9ubWVudCopaEhhbmRsZSktPkdldEFjdGlvbkhhbmRlcigpOworCQkJQVNTRVJUKHBBY3Rpb25IYW5kbGVyICE9IE5VTEwpOworCQkJcEFjdGlvbkhhbmRsZXItPkRvQWN0aW9uX0RvY3VtZW50KGFjdGlvbiwgKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUpYWFUeXBlLCBwU0RLRG9jKTsKKwkJfQorCX0KK30KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRk9STV9Eb1BhZ2VBQWN0aW9uKEZQREZfUEFHRSBwYWdlLCBGUERGX0ZPUk1IQU5ETEUgaEhhbmRsZSwgaW50IGFhVHlwZSkKK3sKKwlpZighaEhhbmRsZSB8fCAhcGFnZSkKKwkJcmV0dXJuOworCUNQREZTREtfRG9jdW1lbnQqIHBTREtEb2MgPSAoKENQREZEb2NfRW52aXJvbm1lbnQqKWhIYW5kbGUpLT5HZXRDdXJyZW50RG9jKCk7CisJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7CisJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcFNES0RvYy0+R2V0UGFnZVZpZXcocFBhZ2UsIEZBTFNFKTsKKwlpZihwUGFnZVZpZXcpCisJeworCQlDUERGRG9jX0Vudmlyb25tZW50ICpwRW52ID0gcFNES0RvYy0+R2V0RW52KCk7CisJCUFTU0VSVChwRW52ICE9IE5VTEwpOworCQkJCisJCUNQREZTREtfQWN0aW9uSGFuZGxlciAqcEFjdGlvbkhhbmRsZXIgPSBwRW52LT5HZXRBY3Rpb25IYW5kZXIoKTsKKwkJQVNTRVJUKHBBY3Rpb25IYW5kbGVyICE9IE5VTEwpOworCQkKKwkJQ1BERl9EaWN0aW9uYXJ5ICpwUGFnZURpY3QgPSBwUGFnZS0+bV9wRm9ybURpY3Q7CisJCUFTU0VSVChwUGFnZURpY3QgIT0gTlVMTCk7CisJCSAKKwkJQ1BERl9BQWN0aW9uIGFhID0gcFBhZ2VEaWN0LT5HZXREaWN0KEZYX0JTVFJDKCJBQSIpKTsKKworCQlGWF9CT09MIGJFeGlzdE9BQWN0aW9uID0gRkFMU0U7CisJCUZYX0JPT0wgYkV4aXN0Q0FBY3Rpb24gPSBGQUxTRTsKKwkJaWYgKEZQREZQQUdFX0FBQ1RJT05fT1BFTiA9PSBhYVR5cGUpCisJCXsKKwkJCWJFeGlzdE9BQWN0aW9uID0gYWEuQWN0aW9uRXhpc3QoQ1BERl9BQWN0aW9uOjpPcGVuUGFnZSk7CisJCQlpZiAoYkV4aXN0T0FBY3Rpb24pCisJCQl7CisJCQkJQ1BERl9BY3Rpb24gYWN0aW9uID0gYWEuR2V0QWN0aW9uKENQREZfQUFjdGlvbjo6T3BlblBhZ2UpOworCQkJCXBBY3Rpb25IYW5kbGVyLT5Eb0FjdGlvbl9QYWdlKGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpPcGVuUGFnZSwgcFNES0RvYyk7CisJCQl9CisJCX0KKwkJZWxzZQorCQl7CisJCQliRXhpc3RDQUFjdGlvbiA9IGFhLkFjdGlvbkV4aXN0KENQREZfQUFjdGlvbjo6Q2xvc2VQYWdlKTsKKwkJCWlmIChiRXhpc3RDQUFjdGlvbikKKwkJCXsKKwkJCQlDUERGX0FjdGlvbiBhY3Rpb24gPSBhYS5HZXRBY3Rpb24oQ1BERl9BQWN0aW9uOjpDbG9zZVBhZ2UpOworCQkJCXBBY3Rpb25IYW5kbGVyLT5Eb0FjdGlvbl9QYWdlKGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpDbG9zZVBhZ2UsIHBTREtEb2MpOworCQkJfQorCQl9CisJfQorfQorCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2ZwZGZvb20uY3BwIGIvZnBkZnNkay9zcmMvZnBkZm9vbS5jcHAKaW5kZXggZmI2N2E1YS4uOWJhOTgzYiAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnBkZm9vbS5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnBkZm9vbS5jcHAKQEAgLTEsMjcgKzEsMjcgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZm9vbS5oIg0KLQ0KLXZvaWQgT09NX0hhbmRsZXIoRlhNRU1fRm94aXRNZ3IqIHBGb3hpdE1nciwgdm9pZCogcGFyYW0pDQotew0KLQlpZiAoIXBhcmFtKSByZXR1cm47DQotCSgoT09NX0lORk8qKXBhcmFtKS0+RlNES19PT01fSGFuZGxlcigoT09NX0lORk8qKXBhcmFtKTsNCi19DQotDQotDQotRExMRVhQT1JUIEZYX0JPT0wgU1REQ0FMTCBGU0RLX1NldE9PTUhhbmRsZXIoT09NX0lORk8qIG9vbUluZm8pDQotew0KLSNpZm5kZWYgX0ZYU0RLX09QRU5TT1VSQ0VfDQotCWlmICghb29tSW5mbyB8fCBvb21JbmZvLT52ZXJzaW9uIT0xKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlGWE1FTV9TZXRPT01IYW5kbGVyKEZYTUVNX0dldERlZmF1bHRNZ3IoKSxPT01fSGFuZGxlcixvb21JbmZvKTsNCi0JcmV0dXJuIFRSVUU7DQotI2Vsc2UNCi0JcmV0dXJuIFRSVUU7DQotI2VuZGlmDQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmb29tLmgiCisKK3ZvaWQgT09NX0hhbmRsZXIoRlhNRU1fRm94aXRNZ3IqIHBGb3hpdE1nciwgdm9pZCogcGFyYW0pCit7CisJaWYgKCFwYXJhbSkgcmV0dXJuOworCSgoT09NX0lORk8qKXBhcmFtKS0+RlNES19PT01fSGFuZGxlcigoT09NX0lORk8qKXBhcmFtKTsKK30KKworCitETExFWFBPUlQgRlhfQk9PTCBTVERDQUxMIEZTREtfU2V0T09NSGFuZGxlcihPT01fSU5GTyogb29tSW5mbykKK3sKKyNpZm5kZWYgX0ZYU0RLX09QRU5TT1VSQ0VfCisJaWYgKCFvb21JbmZvIHx8IG9vbUluZm8tPnZlcnNpb24hPTEpCisJCXJldHVybiBGQUxTRTsKKwlGWE1FTV9TZXRPT01IYW5kbGVyKEZYTUVNX0dldERlZmF1bHRNZ3IoKSxPT01fSGFuZGxlcixvb21JbmZvKTsKKwlyZXR1cm4gVFJVRTsKKyNlbHNlCisJcmV0dXJuIFRSVUU7CisjZW5kaWYKK30KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2ZwZGZwcG8uY3BwIGIvZnBkZnNkay9zcmMvZnBkZnBwby5jcHAKaW5kZXggZTYwNTQ4NC4uYTgwMzQ1NCAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnBkZnBwby5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnBkZnBwby5jcHAKQEAgLTEsNDYwICsxLDQ2MCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZnBwby5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiDQotDQotY2xhc3MgQ1BERl9QYWdlT3JnYW5pemVyDQotew0KLXB1YmxpYzoNCi0JQ1BERl9QYWdlT3JnYW5pemVyKCk7DQotCX5DUERGX1BhZ2VPcmdhbml6ZXIoKTsNCi0JDQotcHVibGljOg0KLQlGWF9CT09MCQkJCVBERkRvY0luaXQoQ1BERl9Eb2N1bWVudCAqcERlc3RQREZEb2MsIENQREZfRG9jdW1lbnQgKnBTcmNQREZEb2MpOw0KLQlGWF9CT09MCQkJCUV4cG9ydFBhZ2UoQ1BERl9Eb2N1bWVudCAqcFNyY1BERkRvYywgQ0ZYX1dvcmRBcnJheSogblBhZ2VOdW0sIENQREZfRG9jdW1lbnQgKnBEZXN0UERGRG9jLCBpbnQgbkluZGV4KTsNCi0JQ1BERl9PYmplY3QqCQlQYWdlRGljdEdldEluaGVyaXRhYmxlVGFnKENQREZfRGljdGlvbmFyeSAqcERpY3QsIENGWF9CeXRlU3RyaW5nIG5TcmN0YWcpOw0KLQlGWF9CT09MCQkJCVVwZGF0ZVJlZmVyZW5jZShDUERGX09iamVjdCAqcE9iaiwgQ1BERl9Eb2N1bWVudCAqcERvYywgQ0ZYX01hcFB0clRvUHRyKiBwTWFwUHRyVG9QdHIpOw0KLQlpbnQJCQkJCUdldE5ld09iaklkKENQREZfRG9jdW1lbnQgKnBEb2MsIENGWF9NYXBQdHJUb1B0ciogcE1hcFB0clRvUHRyLCBDUERGX1JlZmVyZW5jZSAqcFJlZik7DQotCQ0KLX07DQotDQotDQotQ1BERl9QYWdlT3JnYW5pemVyOjpDUERGX1BhZ2VPcmdhbml6ZXIoKQ0KLXsNCi0NCi19DQotDQotQ1BERl9QYWdlT3JnYW5pemVyOjp+Q1BERl9QYWdlT3JnYW5pemVyKCkNCi17DQotDQotfQ0KLQ0KLUZYX0JPT0wgQ1BERl9QYWdlT3JnYW5pemVyOjpQREZEb2NJbml0KENQREZfRG9jdW1lbnQgKnBEZXN0UERGRG9jLCBDUERGX0RvY3VtZW50ICpwU3JjUERGRG9jKQ0KLXsNCi0JaWYoIXBEZXN0UERGRG9jIHx8ICFwU3JjUERGRG9jKQ0KLQkJcmV0dXJuIGZhbHNlOw0KLQkNCi0JQ1BERl9EaWN0aW9uYXJ5KiBwTmV3Um9vdCA9IHBEZXN0UERGRG9jLT5HZXRSb290KCk7DQotCWlmKCFwTmV3Um9vdCkJcmV0dXJuIEZBTFNFOw0KLQkNCi0JLy9TZXQgdGhlIGRvY3VtZW50IGluZm9ybWF0aW9uLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0JDQotCUNQREZfRGljdGlvbmFyeSogREluZm9EaWN0ID0gcERlc3RQREZEb2MtPkdldEluZm8oKTsNCi0JDQotCWlmKCFESW5mb0RpY3QpDQotCQlyZXR1cm4gRkFMU0U7DQotCQ0KLQlDRlhfQnl0ZVN0cmluZyBwcm9kdWNlcnN0cjsNCi0JDQotI2lmZGVmIEZPWElUX0NIUk9NRV9CVUlMRA0KLQlwcm9kdWNlcnN0ci5Gb3JtYXQoIkdvb2dsZSIpOw0KLSNlbHNlDQotCSBwcm9kdWNlcnN0ci5Gb3JtYXQoIkZveGl0IFBERiBTREsgJXMgLSBGb3hpdCBDb3Jwb3JhdGlvbiIsICIyLjAiKTsNCi0jZW5kaWYNCi0JREluZm9EaWN0LT5TZXRBdCgiUHJvZHVjZXIiLCBuZXcgQ1BERl9TdHJpbmcocHJvZHVjZXJzdHIpKTsNCi0NCi0JLy9TZXQgdHlwZS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0JQ0ZYX0J5dGVTdHJpbmcgY2JSb290VHlwZSA9IHBOZXdSb290LT5HZXRTdHJpbmcoIlR5cGUiLCIiKTsNCi0JaWYoIGNiUm9vdFR5cGUuRXF1YWwoIiIpICkNCi0Jew0KLQkJcE5ld1Jvb3QtPlNldEF0KCJUeXBlIiwgbmV3IENQREZfTmFtZSgiQ2F0YWxvZyIpKTsNCi0JfQ0KLQkNCi0JQ1BERl9EaWN0aW9uYXJ5KiBwTmV3UGFnZXMgPSAoQ1BERl9EaWN0aW9uYXJ5KilwTmV3Um9vdC0+R2V0RWxlbWVudCgiUGFnZXMiKS0+R2V0RGlyZWN0KCk7DQotCWlmKCFwTmV3UGFnZXMpDQotCXsNCi0JCXBOZXdQYWdlcyA9IG5ldyBDUERGX0RpY3Rpb25hcnk7DQotCQlGWF9EV09SRCBOZXdQYWdlc09OID0gcERlc3RQREZEb2MtPkFkZEluZGlyZWN0T2JqZWN0KHBOZXdQYWdlcyk7DQotCQlwTmV3Um9vdC0+U2V0QXQoIlBhZ2VzIiwgbmV3IENQREZfUmVmZXJlbmNlKHBEZXN0UERGRG9jLCBOZXdQYWdlc09OKSk7DQotCX0NCi0JDQotCUNGWF9CeXRlU3RyaW5nIGNiUGFnZVR5cGUgPSBwTmV3UGFnZXMtPkdldFN0cmluZygiVHlwZSIsIiIpOw0KLQlpZihjYlBhZ2VUeXBlLkVxdWFsKCIiKSkNCi0Jew0KLQkJcE5ld1BhZ2VzLT5TZXRBdCgiVHlwZSIsIG5ldyBDUERGX05hbWUoIlBhZ2VzIikpOw0KLQl9DQotDQotCUNQREZfQXJyYXkqIHBLZXlzQXJyYXkgPSBwTmV3UGFnZXMtPkdldEFycmF5KCJLaWRzIik7DQotCWlmKHBLZXlzQXJyYXkgPT0gTlVMTCkNCi0Jew0KLQkJQ1BERl9BcnJheSogcE5ld0tpZHMgPSBuZXcgQ1BERl9BcnJheTsNCi0JCUZYX0RXT1JEIEtpZHNvYmpudW0gPSAtMTsNCi0JCUtpZHNvYmpudW0gPSBwRGVzdFBERkRvYy0+QWRkSW5kaXJlY3RPYmplY3QocE5ld0tpZHMpOy8vLCBLaWRzb2JqbnVtLCBLaWRzZ2VubnVtKTsNCi0JCQ0KLQkJcE5ld1BhZ2VzLT5TZXRBdCgiS2lkcyIsIG5ldyBDUERGX1JlZmVyZW5jZShwRGVzdFBERkRvYywgS2lkc29iam51bSkpOy8vLCBLaWRzZ2VubnVtKSk7DQotCQlwTmV3UGFnZXMtPlNldEF0KCJDb3VudCIsIG5ldyBDUERGX051bWJlcigwKSk7CQkNCi0JfQ0KLQ0KLQlyZXR1cm4gdHJ1ZTsNCi19DQotDQotRlhfQk9PTCBDUERGX1BhZ2VPcmdhbml6ZXI6OkV4cG9ydFBhZ2UoQ1BERl9Eb2N1bWVudCAqcFNyY1BERkRvYywgQ0ZYX1dvcmRBcnJheSogblBhZ2VOdW0sIA0KLQkJCQkJCQkJCQkJCUNQREZfRG9jdW1lbnQgKnBEZXN0UERGRG9jLGludCBuSW5kZXgpDQotew0KLQlpbnQgY3VycGFnZSA9bkluZGV4Ow0KLQ0KLQlDRlhfTWFwUHRyVG9QdHIqIHBNYXBQdHJUb1B0ciA9IG5ldyBDRlhfTWFwUHRyVG9QdHI7DQotCXBNYXBQdHJUb1B0ci0+SW5pdEhhc2hUYWJsZSgxMDAxKTsNCi0NCi0JZm9yKGludCBpPTA7IGk8blBhZ2VOdW0tPkdldFNpemUoKTsgaSsrKQ0KLQl7DQotCQkNCi0JCUNQREZfRGljdGlvbmFyeSogcEN1clBhZ2VEaWN0ID0gcERlc3RQREZEb2MtPkNyZWF0ZU5ld1BhZ2UoY3VycGFnZSk7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBTcmNQYWdlRGljdCA9IHBTcmNQREZEb2MtPkdldFBhZ2UoblBhZ2VOdW0tPkdldEF0KGkpLTEpOw0KLQkJaWYoIXBTcmNQYWdlRGljdCB8fCAhcEN1clBhZ2VEaWN0KQ0KLQkJew0KLQkJCWRlbGV0ZSBwTWFwUHRyVG9QdHI7DQotCQkJcmV0dXJuIEZBTFNFOw0KLQkJfQ0KLQkJDQotCQkvLyBDbG9uZSB0aGUgcGFnZSBkaWN0aW9uYXJ5Ly8vLy8vLy8vLy8NCi0JCUZYX1BPU0lUSU9OCVNyY1BvcyA9IHBTcmNQYWdlRGljdC0+R2V0U3RhcnRQb3MoKTsNCi0JCXdoaWxlIChTcmNQb3MpDQotCQl7DQotCQkJQ0ZYX0J5dGVTdHJpbmcgY2JTcmNLZXlTdHI7DQotCQkJQ1BERl9PYmplY3QqIHBPYmogPSBwU3JjUGFnZURpY3QtPkdldE5leHRFbGVtZW50KFNyY1BvcywgY2JTcmNLZXlTdHIpOw0KLQkJCWlmKGNiU3JjS2V5U3RyLkNvbXBhcmUoKCJUeXBlIikpICYmIGNiU3JjS2V5U3RyLkNvbXBhcmUoKCJQYXJlbnQiKSkpDQotCQkJew0KLQkJCQlpZihwQ3VyUGFnZURpY3QtPktleUV4aXN0KGNiU3JjS2V5U3RyKSkNCi0JCQkJCXBDdXJQYWdlRGljdC0+UmVtb3ZlQXQoY2JTcmNLZXlTdHIpOw0KLQkJCQlwQ3VyUGFnZURpY3QtPlNldEF0KGNiU3JjS2V5U3RyLCBwT2JqLT5DbG9uZSgpKTsNCi0JCQl9DQotCQl9DQotCQkNCi0JCS8vaW5oZXJpdGFibGUgaXRlbS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotCQlDUERGX09iamVjdCogcEluaGVyaXRhYmxlID0gTlVMTDsNCi0JCS8vMQlNZWRpYUJveCAgLy9yZXF1aXJlZA0KLQkJaWYoIXBDdXJQYWdlRGljdC0+S2V5RXhpc3QoIk1lZGlhQm94IikpDQotCQl7DQotCQkJDQotCQkJcEluaGVyaXRhYmxlID0gUGFnZURpY3RHZXRJbmhlcml0YWJsZVRhZyhwU3JjUGFnZURpY3QsICJNZWRpYUJveCIpOw0KLQkJCWlmKCFwSW5oZXJpdGFibGUpIA0KLQkJCXsNCi0JCQkJLy9TZWFyY2ggdGhlICJDcm9wQm94IiBmcm9tIHNvdXJjZSBwYWdlIGRpY3Rpb25hcnksIGlmIG5vdCBleGlzdHMsd2UgdGFrZSB0aGUgbGV0dGVyIHNpemUuDQotCQkJCXBJbmhlcml0YWJsZSA9IFBhZ2VEaWN0R2V0SW5oZXJpdGFibGVUYWcocFNyY1BhZ2VEaWN0LCAiQ3JvcEJveCIpOw0KLQkJCQlpZihwSW5oZXJpdGFibGUpDQotCQkJCQlwQ3VyUGFnZURpY3QtPlNldEF0KCJNZWRpYUJveCIsIHBJbmhlcml0YWJsZS0+Q2xvbmUoKSk7DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJLy9NYWtlIHRoZSBkZWZhdWx0IHNpemUgdG8gYmUgbGV0dGVyIHNpemUgKDguNSd4MTEnKQ0KLQkJCQkJQ1BERl9BcnJheSogcEFycmF5ID0gbmV3IENQREZfQXJyYXk7DQotCQkJCQlwQXJyYXktPkFkZE51bWJlcigwKTsNCi0JCQkJCXBBcnJheS0+QWRkTnVtYmVyKDApOw0KLQkJCQkJcEFycmF5LT5BZGROdW1iZXIoNjEyKTsNCi0JCQkJCXBBcnJheS0+QWRkTnVtYmVyKDc5Mik7DQotCQkJCQlwQ3VyUGFnZURpY3QtPlNldEF0KCJNZWRpYUJveCIsIHBBcnJheSk7DQotCQkJCX0NCi0JCQl9DQotCQkJZWxzZQ0KLQkJCQlwQ3VyUGFnZURpY3QtPlNldEF0KCJNZWRpYUJveCIsIHBJbmhlcml0YWJsZS0+Q2xvbmUoKSk7DQotCQl9DQotCQkvLzIgUmVzb3VyY2VzIC8vcmVxdWlyZWQNCi0JCWlmKCFwQ3VyUGFnZURpY3QtPktleUV4aXN0KCJSZXNvdXJjZXMiKSkNCi0JCXsNCi0JCQlwSW5oZXJpdGFibGUgPSBQYWdlRGljdEdldEluaGVyaXRhYmxlVGFnKHBTcmNQYWdlRGljdCwgIlJlc291cmNlcyIpOw0KLQkJCWlmKCFwSW5oZXJpdGFibGUpIA0KLQkJCXsNCi0JCQkJZGVsZXRlIHBNYXBQdHJUb1B0cjsNCi0JCQkJcmV0dXJuIEZBTFNFOw0KLQkJCX0NCi0JCQlwQ3VyUGFnZURpY3QtPlNldEF0KCJSZXNvdXJjZXMiLCBwSW5oZXJpdGFibGUtPkNsb25lKCkpOw0KLQkJfQ0KLQkJLy8zIENyb3BCb3ggIC8vT3B0aW9uYWwNCi0JCWlmKCFwQ3VyUGFnZURpY3QtPktleUV4aXN0KCJDcm9wQm94IikpDQotCQl7DQotCQkJcEluaGVyaXRhYmxlID0gUGFnZURpY3RHZXRJbmhlcml0YWJsZVRhZyhwU3JjUGFnZURpY3QsICJDcm9wQm94Iik7DQotCQkJaWYocEluaGVyaXRhYmxlKSANCi0JCQkJcEN1clBhZ2VEaWN0LT5TZXRBdCgiQ3JvcEJveCIsIHBJbmhlcml0YWJsZS0+Q2xvbmUoKSk7DQotCQl9DQotCQkvLzQgUm90YXRlICAvL09wdGlvbmFsDQotCQlpZighcEN1clBhZ2VEaWN0LT5LZXlFeGlzdCgiUm90YXRlIikpDQotCQl7DQotCQkJcEluaGVyaXRhYmxlID0gUGFnZURpY3RHZXRJbmhlcml0YWJsZVRhZyhwU3JjUGFnZURpY3QsICJSb3RhdGUiKTsNCi0JCQlpZihwSW5oZXJpdGFibGUpIA0KLQkJCQlwQ3VyUGFnZURpY3QtPlNldEF0KCJSb3RhdGUiLCBwSW5oZXJpdGFibGUtPkNsb25lKCkpOw0KLQkJfQ0KLQ0KLQkJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotCQkvL1VwZGF0ZSB0aGUgcmVmZXJlbmNlDQotCQlGWF9EV09SRCBkd09sZFBhZ2VPYmogPSBwU3JjUGFnZURpY3QtPkdldE9iak51bSgpOw0KLQkJRlhfRFdPUkQgZHdOZXdQYWdlT2JqID0gcEN1clBhZ2VEaWN0LT5HZXRPYmpOdW0oKTsNCi0JCQ0KLQkJcE1hcFB0clRvUHRyLT5TZXRBdCgoRlhfTFBWT0lEKShGWF9VSU5UUFRSKWR3T2xkUGFnZU9iaiwgKEZYX0xQVk9JRCkoRlhfVUlOVFBUUilkd05ld1BhZ2VPYmopOw0KLQ0KLQkJdGhpcy0+VXBkYXRlUmVmZXJlbmNlKHBDdXJQYWdlRGljdCwgcERlc3RQREZEb2MsIHBNYXBQdHJUb1B0cik7DQotCQljdXJwYWdlKys7DQotCX0NCi0NCi0JZGVsZXRlIHBNYXBQdHJUb1B0cjsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUNQREZfT2JqZWN0KiBDUERGX1BhZ2VPcmdhbml6ZXI6OlBhZ2VEaWN0R2V0SW5oZXJpdGFibGVUYWcoQ1BERl9EaWN0aW9uYXJ5ICpwRGljdCwgQ0ZYX0J5dGVTdHJpbmcgblNyY3RhZykNCi17DQotCWlmKCFwRGljdCB8fCAhcERpY3QtPktleUV4aXN0KCJUeXBlIikgfHwgblNyY3RhZy5Jc0VtcHR5KCkpCQ0KLQkJcmV0dXJuIE5VTEw7DQotDQotCUNQREZfT2JqZWN0KiBwVHlwZSA9IHBEaWN0LT5HZXRFbGVtZW50KCJUeXBlIiktPkdldERpcmVjdCgpOw0KLQlpZighcFR5cGUgfHwgcFR5cGUtPkdldFR5cGUoKSAhPSBQREZPQkpfTkFNRSkJcmV0dXJuIE5VTEw7DQotDQotCWlmKHBUeXBlLT5HZXRTdHJpbmcoKS5Db21wYXJlKCJQYWdlIikpCXJldHVybiBOVUxMOw0KLQ0KLQlpZighcERpY3QtPktleUV4aXN0KCJQYXJlbnQiKSkJcmV0dXJuIE5VTEw7DQotCUNQREZfT2JqZWN0KiBwUGFyZW50ID0gcERpY3QtPkdldEVsZW1lbnQoIlBhcmVudCIpLT5HZXREaXJlY3QoKTsNCi0JaWYoIXBQYXJlbnQgfHwgcFBhcmVudC0+R2V0VHlwZSgpICE9IFBERk9CSl9ESUNUSU9OQVJZKQlyZXR1cm4gTlVMTDsNCi0JDQotCUNQREZfRGljdGlvbmFyeSogcHAgPSAoQ1BERl9EaWN0aW9uYXJ5KilwUGFyZW50Ow0KLQkNCi0JaWYocERpY3QtPktleUV4aXN0KChjb25zdCBjaGFyKiluU3JjdGFnKSkJDQotCQlyZXR1cm4gcERpY3QtPkdldEVsZW1lbnQoKGNvbnN0IGNoYXIqKW5TcmN0YWcpOw0KLQl3aGlsZSAocHApDQotCXsNCi0JCWlmKHBwLT5LZXlFeGlzdCgoY29uc3QgY2hhciopblNyY3RhZykpCQ0KLQkJCXJldHVybiBwcC0+R2V0RWxlbWVudCgoY29uc3QgY2hhciopblNyY3RhZyk7DQotCQllbHNlIGlmKHBwLT5LZXlFeGlzdCgiUGFyZW50IikpDQotCQkJcHAgPSAoQ1BERl9EaWN0aW9uYXJ5KilwcC0+R2V0RWxlbWVudCgiUGFyZW50IiktPkdldERpcmVjdCgpOw0KLQkJZWxzZSBicmVhazsNCi0JfQ0KLQkNCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERl9QYWdlT3JnYW5pemVyOjpVcGRhdGVSZWZlcmVuY2UoQ1BERl9PYmplY3QgKnBPYmosIENQREZfRG9jdW1lbnQgKnBEb2MsIA0KLQkJCQkJCQkJCQkgQ0ZYX01hcFB0clRvUHRyKiBwTWFwUHRyVG9QdHIpDQotew0KLQlzd2l0Y2ggKHBPYmotPkdldFR5cGUoKSkNCi0Jew0KLQljYXNlIFBERk9CSl9SRUZFUkVOQ0U6DQotCQl7DQotCQkJQ1BERl9SZWZlcmVuY2UqIHBSZWZlcmVuY2UgPSAoQ1BERl9SZWZlcmVuY2UqKXBPYmo7DQotCQkJaW50IG5ld29iam51bSA9IEdldE5ld09iaklkKHBEb2MsIHBNYXBQdHJUb1B0ciwgcFJlZmVyZW5jZSk7DQotCQkJaWYgKG5ld29iam51bSA9PSAwKSByZXR1cm4gRkFMU0U7DQotCQkJcFJlZmVyZW5jZS0+U2V0UmVmKHBEb2MsIG5ld29iam51bSk7Ly8sIDApOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQljYXNlIFBERk9CSl9ESUNUSU9OQVJZOg0KLQkJew0KLQkJCUNQREZfRGljdGlvbmFyeSogcERpY3QgPSAoQ1BERl9EaWN0aW9uYXJ5KilwT2JqOw0KLQkJCQ0KLQkJCUZYX1BPU0lUSU9OIHBvcyA9IHBEaWN0LT5HZXRTdGFydFBvcygpOw0KLQkJCXdoaWxlKHBvcykNCi0JCQl7DQotCQkJCUNGWF9CeXRlU3RyaW5nIGtleSgiIik7DQotCQkJCUNQREZfT2JqZWN0KiBwTmV4dE9iaiA9IHBEaWN0LT5HZXROZXh0RWxlbWVudChwb3MsIGtleSk7DQotCQkJCWlmICghRlhTWVNfc3RyY21wKGtleSwgIlBhcmVudCIpIHx8ICFGWFNZU19zdHJjbXAoa2V5LCAiUHJldiIpIHx8ICFGWFNZU19zdHJjbXAoa2V5LCAiRmlyc3QiKSkNCi0JCQkJCWNvbnRpbnVlOw0KLQkJCQlpZihwTmV4dE9iaikNCi0JCQkJew0KLQkJCQkJaWYoIVVwZGF0ZVJlZmVyZW5jZShwTmV4dE9iaiwgcERvYywgcE1hcFB0clRvUHRyKSkNCi0JCQkJCQlwRGljdC0+UmVtb3ZlQXQoa2V5KTsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCQlyZXR1cm4gRkFMU0U7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJfQ0KLQljYXNlCVBERk9CSl9BUlJBWToNCi0JCXsNCi0JCQlDUERGX0FycmF5KiBwQXJyYXkgPSAoQ1BERl9BcnJheSopcE9iajsNCi0JCQlGWF9EV09SRCBjb3VudCA9IHBBcnJheS0+R2V0Q291bnQoKTsNCi0JCQlmb3IoRlhfRFdPUkQgaSA9IDA7IGkgPCBjb3VudDsgaSArKykNCi0JCQl7DQotCQkJCUNQREZfT2JqZWN0KiBwTmV4dE9iaiA9IHBBcnJheS0+R2V0RWxlbWVudChpKTsNCi0JCQkJaWYocE5leHRPYmopDQotCQkJCXsNCi0JCQkJCWlmKCFVcGRhdGVSZWZlcmVuY2UocE5leHRPYmosIHBEb2MsIHBNYXBQdHJUb1B0cikpDQotCQkJCQkJcmV0dXJuIEZBTFNFOw0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJCXJldHVybiBGQUxTRTsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQl9DQotCWNhc2UJUERGT0JKX1NUUkVBTToNCi0JCXsNCi0JCQlDUERGX1N0cmVhbSogcFN0cmVhbSA9IChDUERGX1N0cmVhbSopcE9iajsNCi0JCQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gcFN0cmVhbS0+R2V0RGljdCgpOw0KLQkJCWlmKHBEaWN0KQ0KLQkJCXsNCi0JCQkJaWYoIVVwZGF0ZVJlZmVyZW5jZShwRGljdCwgcERvYywgcE1hcFB0clRvUHRyKSkNCi0JCQkJCXJldHVybiBGQUxTRTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCQlyZXR1cm4gRkFMU0U7DQotCQkJYnJlYWs7DQotCQl9DQotCWRlZmF1bHQ6CWJyZWFrOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1pbnQJQ1BERl9QYWdlT3JnYW5pemVyOjpHZXROZXdPYmpJZChDUERGX0RvY3VtZW50ICpwRG9jLCBDRlhfTWFwUHRyVG9QdHIqIHBNYXBQdHJUb1B0ciwNCi0JCQkJCQkJCQlDUERGX1JlZmVyZW5jZSAqcFJlZikNCi17DQotCXNpemVfdCBkd09iam51bSA9IDA7DQotCWlmKCFwUmVmKQ0KLQkJcmV0dXJuIDA7DQotCWR3T2JqbnVtID0gcFJlZi0+R2V0UmVmT2JqTnVtKCk7DQotCQ0KLQlzaXplX3QgZHdOZXdPYmpOdW0gPSAwOw0KLQkNCi0JcE1hcFB0clRvUHRyLT5Mb29rdXAoKEZYX0xQVk9JRClkd09iam51bSwgKEZYX0xQVk9JRCYpZHdOZXdPYmpOdW0pOw0KLQlpZihkd05ld09iak51bSkNCi0Jew0KLQkJcmV0dXJuIChpbnQpZHdOZXdPYmpOdW07DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDUERGX09iamVjdCogcENsb25lICA9IHBSZWYtPkdldERpcmVjdCgpLT5DbG9uZSgpOw0KLQkJaWYoIXBDbG9uZSkJCQlyZXR1cm4gMDsNCi0JCQ0KLQkJaWYocENsb25lLT5HZXRUeXBlKCkgPT0gUERGT0JKX0RJQ1RJT05BUlkpDQotCQl7DQotCQkJQ1BERl9EaWN0aW9uYXJ5KiBwRGljdENsb25lID0gKENQREZfRGljdGlvbmFyeSopcENsb25lOw0KLQkJCWlmKHBEaWN0Q2xvbmUtPktleUV4aXN0KCJUeXBlIikpDQotCQkJew0KLQkJCQlDRlhfQnl0ZVN0cmluZyBzdHJUeXBlID0gcERpY3RDbG9uZS0+R2V0U3RyaW5nKCJUeXBlIik7DQotCQkJCWlmKCFGWFNZU19zdHJpY21wKHN0clR5cGUsICJQYWdlcyIpKQ0KLQkJCQl7DQotCQkJCQlwRGljdENsb25lLT5SZWxlYXNlKCk7DQotCQkJCQlyZXR1cm4gNDsNCi0JCQkJfQ0KLQkJCQllbHNlIGlmKCFGWFNZU19zdHJpY21wKHN0clR5cGUsICJQYWdlIikpDQotCQkJCXsNCi0JCQkJCXBEaWN0Q2xvbmUtPlJlbGVhc2UoKTsNCi0JCQkJCXJldHVybiAgMDsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JCWR3TmV3T2JqTnVtID0gcERvYy0+QWRkSW5kaXJlY3RPYmplY3QocENsb25lKTsvLywgb251bSwgZ251bSk7DQotCQlwTWFwUHRyVG9QdHItPlNldEF0KChGWF9MUFZPSUQpZHdPYmpudW0sIChGWF9MUFZPSUQpZHdOZXdPYmpOdW0pOw0KLQkJDQotCQlpZighVXBkYXRlUmVmZXJlbmNlKHBDbG9uZSwgcERvYywgcE1hcFB0clRvUHRyKSkNCi0JCXsNCi0JCQlwQ2xvbmUtPlJlbGVhc2UoKTsNCi0JCQlyZXR1cm4gMDsNCi0JCX0NCi0JCXJldHVybiAoaW50KWR3TmV3T2JqTnVtOw0KLQl9DQotCXJldHVybiAwOw0KLX0NCi0NCi1GUERGX0JPT0wgUGFyc2VyUGFnZVJhbmdlU3RyaW5nKENGWF9CeXRlU3RyaW5nIHJhbmdzdHJpbmcsIENGWF9Xb3JkQXJyYXkqIHBhZ2VBcnJheSxpbnQgbkNvdW50KQ0KLXsNCi0NCi0JaWYocmFuZ3N0cmluZy5HZXRMZW5ndGgoKSAhPSAwKQ0KLQl7DQotCQlyYW5nc3RyaW5nLlJlbW92ZSgnICcpOw0KLQkJaW50IG5MZW5ndGggPSByYW5nc3RyaW5nLkdldExlbmd0aCgpOw0KLQkJQ0ZYX0J5dGVTdHJpbmcgY2JDb21wYXJlU3RyaW5nKCIwMTIzNDU2Nzg5LSwiKTsNCi0JCWZvcihpbnQgaT0wOyBpPG5MZW5ndGg7IGkrKykNCi0JCXsNCi0JCQlpZihjYkNvbXBhcmVTdHJpbmcuRmluZChyYW5nc3RyaW5nW2ldKSA9PSAtMSkNCi0JCQkJcmV0dXJuIEZBTFNFOw0KLQkJfQ0KLQkJQ0ZYX0J5dGVTdHJpbmcgY2JNaWRSYW5nZTsNCi0JCWludCBuU3RyaW5nRnJvbSA9IDA7DQotCQlpbnQgblN0cmluZ1RvPTA7DQotCQl3aGlsZShuU3RyaW5nVG8gPCBuTGVuZ3RoKQ0KLQkJew0KLQkJCW5TdHJpbmdUbyA9IHJhbmdzdHJpbmcuRmluZCgnLCcsblN0cmluZ0Zyb20pOw0KLQkJCWlmKG5TdHJpbmdUbyA9PSAtMSkNCi0JCQl7DQotCQkJCW5TdHJpbmdUbyA9IG5MZW5ndGg7DQotCQkJfQ0KLQkJCWNiTWlkUmFuZ2UgPSByYW5nc3RyaW5nLk1pZChuU3RyaW5nRnJvbSxuU3RyaW5nVG8tblN0cmluZ0Zyb20pOw0KLQkJCQ0KLQkJCWludCBuTWlkID0gY2JNaWRSYW5nZS5GaW5kKCctJyk7DQotCQkJaWYobk1pZCA9PSAtMSkNCi0JCQl7DQotCQkJCWxvbmcgbFBhZ2VOdW0gPSBhdG9sKGNiTWlkUmFuZ2UpOw0KLQkJCQlpZihsUGFnZU51bSA8PSAwIHx8IGxQYWdlTnVtID4gbkNvdW50KQ0KLQkJCQkJcmV0dXJuIEZBTFNFOw0KLQkJCQlwYWdlQXJyYXktPkFkZCgoRlhfV09SRClsUGFnZU51bSk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCWludCBuU3RhcnRQYWdlTnVtID0gYXRvbChjYk1pZFJhbmdlLk1pZCgwLG5NaWQpKTsNCi0JCQkJaWYgKG5TdGFydFBhZ2VOdW0gPT0wKQ0KLQkJCQl7DQotCQkJCQlyZXR1cm4gRkFMU0U7DQotCQkJCX0NCi0NCi0NCi0JCQkJbk1pZCA9IG5NaWQrMTsNCi0JCQkJaW50IG5FbmQgPSBjYk1pZFJhbmdlLkdldExlbmd0aCgpLW5NaWQ7DQotDQotCQkJCWlmKG5FbmQgPT0wKXJldHVybiBGQUxTRTsNCi0JCQkJDQotCQkJCS8vCQkJCWludCBuRW5kUGFnZU51bSA9IChuRW5kID09IDApP25Db3VudDphdG9sKGNiTWlkUmFuZ2UuTWlkKG5NaWQsbkVuZCkpOw0KLQkJCQlpbnQgbkVuZFBhZ2VOdW0gPSBhdG9sKGNiTWlkUmFuZ2UuTWlkKG5NaWQsbkVuZCkpOw0KLQkJCQkNCi0JCQkJaWYoblN0YXJ0UGFnZU51bSA8IDAgfHxuU3RhcnRQYWdlTnVtID5uRW5kUGFnZU51bXx8IG5FbmRQYWdlTnVtID4gbkNvdW50KQ0KLQkJCQl7DQotCQkJCQlyZXR1cm4gRkFMU0U7DQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQl7DQotCQkJCQlmb3IoaW50IG5JbmRleD1uU3RhcnRQYWdlTnVtOyBuSW5kZXggPD0gbkVuZFBhZ2VOdW07IG5JbmRleCArKykNCi0JCQkJCQlwYWdlQXJyYXktPkFkZChuSW5kZXgpOw0KLQkJCQl9DQotCQkJfQ0KLQkJCW5TdHJpbmdGcm9tID0gblN0cmluZ1RvICsxOw0KLQkJfQ0KLQl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERl9JbXBvcnRQYWdlcyhGUERGX0RPQ1VNRU5UIGRlc3RfZG9jLEZQREZfRE9DVU1FTlQgc3JjX2RvYywgDQotCQkJCQkJCQkJCQkgRlBERl9CWVRFU1RSSU5HIHBhZ2VyYW5nZSwgaW50IGluZGV4KQ0KLXsNCi0JaWYoZGVzdF9kb2MgPT0gTlVMTCB8fCBzcmNfZG9jID09IE5VTEwgKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfV29yZEFycmF5IHBhZ2VBcnJheTsNCi0JQ1BERl9Eb2N1bWVudCogcFNyY0RvYyA9IChDUERGX0RvY3VtZW50KilzcmNfZG9jOw0KLQlpbnQgbkNvdW50ID0gcFNyY0RvYy0+R2V0UGFnZUNvdW50KCk7DQotCWlmKHBhZ2VyYW5nZSkNCi0Jew0KLQkJaWYoUGFyc2VyUGFnZVJhbmdlU3RyaW5nKHBhZ2VyYW5nZSwmcGFnZUFycmF5LG5Db3VudCkgPT0gRkFMU0UpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJZm9yKGludCBpPTE7IGk8PW5Db3VudDsgaSsrKQ0KLQkJew0KLQkJCXBhZ2VBcnJheS5BZGQoaSk7DQotCQl9DQotCX0NCi0JDQotCUNQREZfRG9jdW1lbnQqIHBEZXN0RG9jID0gKENQREZfRG9jdW1lbnQqKWRlc3RfZG9jOw0KLQlDUERGX1BhZ2VPcmdhbml6ZXIgcGFnZU9yZzsNCi0NCi0JcGFnZU9yZy5QREZEb2NJbml0KHBEZXN0RG9jLHBTcmNEb2MpOw0KLQ0KLQlpZihwYWdlT3JnLkV4cG9ydFBhZ2UocFNyY0RvYywmcGFnZUFycmF5LHBEZXN0RG9jLGluZGV4KSkNCi0JCXJldHVybiBUUlVFOw0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLURMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX0NvcHlWaWV3ZXJQcmVmZXJlbmNlcyhGUERGX0RPQ1VNRU5UIGRlc3RfZG9jLCBGUERGX0RPQ1VNRU5UIHNyY19kb2MpDQotew0KLQlpZihzcmNfZG9jID09IE5VTEwgfHwgZGVzdF9kb2MgPT0gTlVMTCkNCi0JCXJldHVybiBmYWxzZTsNCi0JQ1BERl9Eb2N1bWVudCogcFNyY0RvYyA9IChDUERGX0RvY3VtZW50KilzcmNfZG9jOw0KLQlDUERGX0RpY3Rpb25hcnkqIHBTcmNEaWN0ID0gcFNyY0RvYy0+R2V0Um9vdCgpOw0KLQlwU3JjRGljdCA9IHBTcmNEaWN0LT5HZXREaWN0KEZYX0JTVFJDKCJWaWV3ZXJQcmVmZXJlbmNlcyIpKTs7DQotCWlmKCFwU3JjRGljdCkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ1BERl9Eb2N1bWVudCogcERzdERvYyA9IChDUERGX0RvY3VtZW50KilkZXN0X2RvYzsNCi0JQ1BERl9EaWN0aW9uYXJ5KiBwRHN0RGljdCA9IHBEc3REb2MtPkdldFJvb3QoKTsNCi0JaWYoIXBEc3REaWN0KQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlwRHN0RGljdC0+U2V0QXQoRlhfQlNUUkMoIlZpZXdlclByZWZlcmVuY2VzIiksIHBTcmNEaWN0LT5DbG9uZShUUlVFKSk7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmcHBvLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIgorCitjbGFzcyBDUERGX1BhZ2VPcmdhbml6ZXIKK3sKK3B1YmxpYzoKKwlDUERGX1BhZ2VPcmdhbml6ZXIoKTsKKwl+Q1BERl9QYWdlT3JnYW5pemVyKCk7CisJCitwdWJsaWM6CisJRlhfQk9PTAkJCQlQREZEb2NJbml0KENQREZfRG9jdW1lbnQgKnBEZXN0UERGRG9jLCBDUERGX0RvY3VtZW50ICpwU3JjUERGRG9jKTsKKwlGWF9CT09MCQkJCUV4cG9ydFBhZ2UoQ1BERl9Eb2N1bWVudCAqcFNyY1BERkRvYywgQ0ZYX1dvcmRBcnJheSogblBhZ2VOdW0sIENQREZfRG9jdW1lbnQgKnBEZXN0UERGRG9jLCBpbnQgbkluZGV4KTsKKwlDUERGX09iamVjdCoJCVBhZ2VEaWN0R2V0SW5oZXJpdGFibGVUYWcoQ1BERl9EaWN0aW9uYXJ5ICpwRGljdCwgQ0ZYX0J5dGVTdHJpbmcgblNyY3RhZyk7CisJRlhfQk9PTAkJCQlVcGRhdGVSZWZlcmVuY2UoQ1BERl9PYmplY3QgKnBPYmosIENQREZfRG9jdW1lbnQgKnBEb2MsIENGWF9NYXBQdHJUb1B0ciogcE1hcFB0clRvUHRyKTsKKwlpbnQJCQkJCUdldE5ld09iaklkKENQREZfRG9jdW1lbnQgKnBEb2MsIENGWF9NYXBQdHJUb1B0ciogcE1hcFB0clRvUHRyLCBDUERGX1JlZmVyZW5jZSAqcFJlZik7CisJCit9OworCisKK0NQREZfUGFnZU9yZ2FuaXplcjo6Q1BERl9QYWdlT3JnYW5pemVyKCkKK3sKKworfQorCitDUERGX1BhZ2VPcmdhbml6ZXI6On5DUERGX1BhZ2VPcmdhbml6ZXIoKQoreworCit9CisKK0ZYX0JPT0wgQ1BERl9QYWdlT3JnYW5pemVyOjpQREZEb2NJbml0KENQREZfRG9jdW1lbnQgKnBEZXN0UERGRG9jLCBDUERGX0RvY3VtZW50ICpwU3JjUERGRG9jKQoreworCWlmKCFwRGVzdFBERkRvYyB8fCAhcFNyY1BERkRvYykKKwkJcmV0dXJuIGZhbHNlOworCQorCUNQREZfRGljdGlvbmFyeSogcE5ld1Jvb3QgPSBwRGVzdFBERkRvYy0+R2V0Um9vdCgpOworCWlmKCFwTmV3Um9vdCkJcmV0dXJuIEZBTFNFOworCQorCS8vU2V0IHRoZSBkb2N1bWVudCBpbmZvcm1hdGlvbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisJCisJQ1BERl9EaWN0aW9uYXJ5KiBESW5mb0RpY3QgPSBwRGVzdFBERkRvYy0+R2V0SW5mbygpOworCQorCWlmKCFESW5mb0RpY3QpCisJCXJldHVybiBGQUxTRTsKKwkKKwlDRlhfQnl0ZVN0cmluZyBwcm9kdWNlcnN0cjsKKwkKKyNpZmRlZiBGT1hJVF9DSFJPTUVfQlVJTEQKKwlwcm9kdWNlcnN0ci5Gb3JtYXQoIkdvb2dsZSIpOworI2Vsc2UKKwkgcHJvZHVjZXJzdHIuRm9ybWF0KCJGb3hpdCBQREYgU0RLICVzIC0gRm94aXQgQ29ycG9yYXRpb24iLCAiMi4wIik7CisjZW5kaWYKKwlESW5mb0RpY3QtPlNldEF0KCJQcm9kdWNlciIsIG5ldyBDUERGX1N0cmluZyhwcm9kdWNlcnN0cikpOworCisJLy9TZXQgdHlwZS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKwlDRlhfQnl0ZVN0cmluZyBjYlJvb3RUeXBlID0gcE5ld1Jvb3QtPkdldFN0cmluZygiVHlwZSIsIiIpOworCWlmKCBjYlJvb3RUeXBlLkVxdWFsKCIiKSApCisJeworCQlwTmV3Um9vdC0+U2V0QXQoIlR5cGUiLCBuZXcgQ1BERl9OYW1lKCJDYXRhbG9nIikpOworCX0KKwkKKwlDUERGX0RpY3Rpb25hcnkqIHBOZXdQYWdlcyA9IChDUERGX0RpY3Rpb25hcnkqKXBOZXdSb290LT5HZXRFbGVtZW50KCJQYWdlcyIpLT5HZXREaXJlY3QoKTsKKwlpZighcE5ld1BhZ2VzKQorCXsKKwkJcE5ld1BhZ2VzID0gbmV3IENQREZfRGljdGlvbmFyeTsKKwkJRlhfRFdPUkQgTmV3UGFnZXNPTiA9IHBEZXN0UERGRG9jLT5BZGRJbmRpcmVjdE9iamVjdChwTmV3UGFnZXMpOworCQlwTmV3Um9vdC0+U2V0QXQoIlBhZ2VzIiwgbmV3IENQREZfUmVmZXJlbmNlKHBEZXN0UERGRG9jLCBOZXdQYWdlc09OKSk7CisJfQorCQorCUNGWF9CeXRlU3RyaW5nIGNiUGFnZVR5cGUgPSBwTmV3UGFnZXMtPkdldFN0cmluZygiVHlwZSIsIiIpOworCWlmKGNiUGFnZVR5cGUuRXF1YWwoIiIpKQorCXsKKwkJcE5ld1BhZ2VzLT5TZXRBdCgiVHlwZSIsIG5ldyBDUERGX05hbWUoIlBhZ2VzIikpOworCX0KKworCUNQREZfQXJyYXkqIHBLZXlzQXJyYXkgPSBwTmV3UGFnZXMtPkdldEFycmF5KCJLaWRzIik7CisJaWYocEtleXNBcnJheSA9PSBOVUxMKQorCXsKKwkJQ1BERl9BcnJheSogcE5ld0tpZHMgPSBuZXcgQ1BERl9BcnJheTsKKwkJRlhfRFdPUkQgS2lkc29iam51bSA9IC0xOworCQlLaWRzb2JqbnVtID0gcERlc3RQREZEb2MtPkFkZEluZGlyZWN0T2JqZWN0KHBOZXdLaWRzKTsvLywgS2lkc29iam51bSwgS2lkc2dlbm51bSk7CisJCQorCQlwTmV3UGFnZXMtPlNldEF0KCJLaWRzIiwgbmV3IENQREZfUmVmZXJlbmNlKHBEZXN0UERGRG9jLCBLaWRzb2JqbnVtKSk7Ly8sIEtpZHNnZW5udW0pKTsKKwkJcE5ld1BhZ2VzLT5TZXRBdCgiQ291bnQiLCBuZXcgQ1BERl9OdW1iZXIoMCkpOwkJCisJfQorCisJcmV0dXJuIHRydWU7Cit9CisKK0ZYX0JPT0wgQ1BERl9QYWdlT3JnYW5pemVyOjpFeHBvcnRQYWdlKENQREZfRG9jdW1lbnQgKnBTcmNQREZEb2MsIENGWF9Xb3JkQXJyYXkqIG5QYWdlTnVtLCAKKwkJCQkJCQkJCQkJCUNQREZfRG9jdW1lbnQgKnBEZXN0UERGRG9jLGludCBuSW5kZXgpCit7CisJaW50IGN1cnBhZ2UgPW5JbmRleDsKKworCUNGWF9NYXBQdHJUb1B0ciogcE1hcFB0clRvUHRyID0gbmV3IENGWF9NYXBQdHJUb1B0cjsKKwlwTWFwUHRyVG9QdHItPkluaXRIYXNoVGFibGUoMTAwMSk7CisKKwlmb3IoaW50IGk9MDsgaTxuUGFnZU51bS0+R2V0U2l6ZSgpOyBpKyspCisJeworCQkKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwQ3VyUGFnZURpY3QgPSBwRGVzdFBERkRvYy0+Q3JlYXRlTmV3UGFnZShjdXJwYWdlKTsKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwU3JjUGFnZURpY3QgPSBwU3JjUERGRG9jLT5HZXRQYWdlKG5QYWdlTnVtLT5HZXRBdChpKS0xKTsKKwkJaWYoIXBTcmNQYWdlRGljdCB8fCAhcEN1clBhZ2VEaWN0KQorCQl7CisJCQlkZWxldGUgcE1hcFB0clRvUHRyOworCQkJcmV0dXJuIEZBTFNFOworCQl9CisJCQorCQkvLyBDbG9uZSB0aGUgcGFnZSBkaWN0aW9uYXJ5Ly8vLy8vLy8vLy8KKwkJRlhfUE9TSVRJT04JU3JjUG9zID0gcFNyY1BhZ2VEaWN0LT5HZXRTdGFydFBvcygpOworCQl3aGlsZSAoU3JjUG9zKQorCQl7CisJCQlDRlhfQnl0ZVN0cmluZyBjYlNyY0tleVN0cjsKKwkJCUNQREZfT2JqZWN0KiBwT2JqID0gcFNyY1BhZ2VEaWN0LT5HZXROZXh0RWxlbWVudChTcmNQb3MsIGNiU3JjS2V5U3RyKTsKKwkJCWlmKGNiU3JjS2V5U3RyLkNvbXBhcmUoKCJUeXBlIikpICYmIGNiU3JjS2V5U3RyLkNvbXBhcmUoKCJQYXJlbnQiKSkpCisJCQl7CisJCQkJaWYocEN1clBhZ2VEaWN0LT5LZXlFeGlzdChjYlNyY0tleVN0cikpCisJCQkJCXBDdXJQYWdlRGljdC0+UmVtb3ZlQXQoY2JTcmNLZXlTdHIpOworCQkJCXBDdXJQYWdlRGljdC0+U2V0QXQoY2JTcmNLZXlTdHIsIHBPYmotPkNsb25lKCkpOworCQkJfQorCQl9CisJCQorCQkvL2luaGVyaXRhYmxlIGl0ZW0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCQlDUERGX09iamVjdCogcEluaGVyaXRhYmxlID0gTlVMTDsKKwkJLy8xCU1lZGlhQm94ICAvL3JlcXVpcmVkCisJCWlmKCFwQ3VyUGFnZURpY3QtPktleUV4aXN0KCJNZWRpYUJveCIpKQorCQl7CisJCQkKKwkJCXBJbmhlcml0YWJsZSA9IFBhZ2VEaWN0R2V0SW5oZXJpdGFibGVUYWcocFNyY1BhZ2VEaWN0LCAiTWVkaWFCb3giKTsKKwkJCWlmKCFwSW5oZXJpdGFibGUpIAorCQkJeworCQkJCS8vU2VhcmNoIHRoZSAiQ3JvcEJveCIgZnJvbSBzb3VyY2UgcGFnZSBkaWN0aW9uYXJ5LCBpZiBub3QgZXhpc3RzLHdlIHRha2UgdGhlIGxldHRlciBzaXplLgorCQkJCXBJbmhlcml0YWJsZSA9IFBhZ2VEaWN0R2V0SW5oZXJpdGFibGVUYWcocFNyY1BhZ2VEaWN0LCAiQ3JvcEJveCIpOworCQkJCWlmKHBJbmhlcml0YWJsZSkKKwkJCQkJcEN1clBhZ2VEaWN0LT5TZXRBdCgiTWVkaWFCb3giLCBwSW5oZXJpdGFibGUtPkNsb25lKCkpOworCQkJCWVsc2UKKwkJCQl7CisJCQkJCS8vTWFrZSB0aGUgZGVmYXVsdCBzaXplIHRvIGJlIGxldHRlciBzaXplICg4LjUneDExJykKKwkJCQkJQ1BERl9BcnJheSogcEFycmF5ID0gbmV3IENQREZfQXJyYXk7CisJCQkJCXBBcnJheS0+QWRkTnVtYmVyKDApOworCQkJCQlwQXJyYXktPkFkZE51bWJlcigwKTsKKwkJCQkJcEFycmF5LT5BZGROdW1iZXIoNjEyKTsKKwkJCQkJcEFycmF5LT5BZGROdW1iZXIoNzkyKTsKKwkJCQkJcEN1clBhZ2VEaWN0LT5TZXRBdCgiTWVkaWFCb3giLCBwQXJyYXkpOworCQkJCX0KKwkJCX0KKwkJCWVsc2UKKwkJCQlwQ3VyUGFnZURpY3QtPlNldEF0KCJNZWRpYUJveCIsIHBJbmhlcml0YWJsZS0+Q2xvbmUoKSk7CisJCX0KKwkJLy8yIFJlc291cmNlcyAvL3JlcXVpcmVkCisJCWlmKCFwQ3VyUGFnZURpY3QtPktleUV4aXN0KCJSZXNvdXJjZXMiKSkKKwkJeworCQkJcEluaGVyaXRhYmxlID0gUGFnZURpY3RHZXRJbmhlcml0YWJsZVRhZyhwU3JjUGFnZURpY3QsICJSZXNvdXJjZXMiKTsKKwkJCWlmKCFwSW5oZXJpdGFibGUpIAorCQkJeworCQkJCWRlbGV0ZSBwTWFwUHRyVG9QdHI7CisJCQkJcmV0dXJuIEZBTFNFOworCQkJfQorCQkJcEN1clBhZ2VEaWN0LT5TZXRBdCgiUmVzb3VyY2VzIiwgcEluaGVyaXRhYmxlLT5DbG9uZSgpKTsKKwkJfQorCQkvLzMgQ3JvcEJveCAgLy9PcHRpb25hbAorCQlpZighcEN1clBhZ2VEaWN0LT5LZXlFeGlzdCgiQ3JvcEJveCIpKQorCQl7CisJCQlwSW5oZXJpdGFibGUgPSBQYWdlRGljdEdldEluaGVyaXRhYmxlVGFnKHBTcmNQYWdlRGljdCwgIkNyb3BCb3giKTsKKwkJCWlmKHBJbmhlcml0YWJsZSkgCisJCQkJcEN1clBhZ2VEaWN0LT5TZXRBdCgiQ3JvcEJveCIsIHBJbmhlcml0YWJsZS0+Q2xvbmUoKSk7CisJCX0KKwkJLy80IFJvdGF0ZSAgLy9PcHRpb25hbAorCQlpZighcEN1clBhZ2VEaWN0LT5LZXlFeGlzdCgiUm90YXRlIikpCisJCXsKKwkJCXBJbmhlcml0YWJsZSA9IFBhZ2VEaWN0R2V0SW5oZXJpdGFibGVUYWcocFNyY1BhZ2VEaWN0LCAiUm90YXRlIik7CisJCQlpZihwSW5oZXJpdGFibGUpIAorCQkJCXBDdXJQYWdlRGljdC0+U2V0QXQoIlJvdGF0ZSIsIHBJbmhlcml0YWJsZS0+Q2xvbmUoKSk7CisJCX0KKworCQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKwkJLy9VcGRhdGUgdGhlIHJlZmVyZW5jZQorCQlGWF9EV09SRCBkd09sZFBhZ2VPYmogPSBwU3JjUGFnZURpY3QtPkdldE9iak51bSgpOworCQlGWF9EV09SRCBkd05ld1BhZ2VPYmogPSBwQ3VyUGFnZURpY3QtPkdldE9iak51bSgpOworCQkKKwkJcE1hcFB0clRvUHRyLT5TZXRBdCgoRlhfTFBWT0lEKShGWF9VSU5UUFRSKWR3T2xkUGFnZU9iaiwgKEZYX0xQVk9JRCkoRlhfVUlOVFBUUilkd05ld1BhZ2VPYmopOworCisJCXRoaXMtPlVwZGF0ZVJlZmVyZW5jZShwQ3VyUGFnZURpY3QsIHBEZXN0UERGRG9jLCBwTWFwUHRyVG9QdHIpOworCQljdXJwYWdlKys7CisJfQorCisJZGVsZXRlIHBNYXBQdHJUb1B0cjsKKwlyZXR1cm4gVFJVRTsKK30KKworQ1BERl9PYmplY3QqIENQREZfUGFnZU9yZ2FuaXplcjo6UGFnZURpY3RHZXRJbmhlcml0YWJsZVRhZyhDUERGX0RpY3Rpb25hcnkgKnBEaWN0LCBDRlhfQnl0ZVN0cmluZyBuU3JjdGFnKQoreworCWlmKCFwRGljdCB8fCAhcERpY3QtPktleUV4aXN0KCJUeXBlIikgfHwgblNyY3RhZy5Jc0VtcHR5KCkpCQorCQlyZXR1cm4gTlVMTDsKKworCUNQREZfT2JqZWN0KiBwVHlwZSA9IHBEaWN0LT5HZXRFbGVtZW50KCJUeXBlIiktPkdldERpcmVjdCgpOworCWlmKCFwVHlwZSB8fCBwVHlwZS0+R2V0VHlwZSgpICE9IFBERk9CSl9OQU1FKQlyZXR1cm4gTlVMTDsKKworCWlmKHBUeXBlLT5HZXRTdHJpbmcoKS5Db21wYXJlKCJQYWdlIikpCXJldHVybiBOVUxMOworCisJaWYoIXBEaWN0LT5LZXlFeGlzdCgiUGFyZW50IikpCXJldHVybiBOVUxMOworCUNQREZfT2JqZWN0KiBwUGFyZW50ID0gcERpY3QtPkdldEVsZW1lbnQoIlBhcmVudCIpLT5HZXREaXJlY3QoKTsKKwlpZighcFBhcmVudCB8fCBwUGFyZW50LT5HZXRUeXBlKCkgIT0gUERGT0JKX0RJQ1RJT05BUlkpCXJldHVybiBOVUxMOworCQorCUNQREZfRGljdGlvbmFyeSogcHAgPSAoQ1BERl9EaWN0aW9uYXJ5KilwUGFyZW50OworCQorCWlmKHBEaWN0LT5LZXlFeGlzdCgoY29uc3QgY2hhciopblNyY3RhZykpCQorCQlyZXR1cm4gcERpY3QtPkdldEVsZW1lbnQoKGNvbnN0IGNoYXIqKW5TcmN0YWcpOworCXdoaWxlIChwcCkKKwl7CisJCWlmKHBwLT5LZXlFeGlzdCgoY29uc3QgY2hhciopblNyY3RhZykpCQorCQkJcmV0dXJuIHBwLT5HZXRFbGVtZW50KChjb25zdCBjaGFyKiluU3JjdGFnKTsKKwkJZWxzZSBpZihwcC0+S2V5RXhpc3QoIlBhcmVudCIpKQorCQkJcHAgPSAoQ1BERl9EaWN0aW9uYXJ5KilwcC0+R2V0RWxlbWVudCgiUGFyZW50IiktPkdldERpcmVjdCgpOworCQllbHNlIGJyZWFrOworCX0KKwkKKwlyZXR1cm4gTlVMTDsKK30KKworRlhfQk9PTCBDUERGX1BhZ2VPcmdhbml6ZXI6OlVwZGF0ZVJlZmVyZW5jZShDUERGX09iamVjdCAqcE9iaiwgQ1BERl9Eb2N1bWVudCAqcERvYywgCisJCQkJCQkJCQkJIENGWF9NYXBQdHJUb1B0ciogcE1hcFB0clRvUHRyKQoreworCXN3aXRjaCAocE9iai0+R2V0VHlwZSgpKQorCXsKKwljYXNlIFBERk9CSl9SRUZFUkVOQ0U6CisJCXsKKwkJCUNQREZfUmVmZXJlbmNlKiBwUmVmZXJlbmNlID0gKENQREZfUmVmZXJlbmNlKilwT2JqOworCQkJaW50IG5ld29iam51bSA9IEdldE5ld09iaklkKHBEb2MsIHBNYXBQdHJUb1B0ciwgcFJlZmVyZW5jZSk7CisJCQlpZiAobmV3b2JqbnVtID09IDApIHJldHVybiBGQUxTRTsKKwkJCXBSZWZlcmVuY2UtPlNldFJlZihwRG9jLCBuZXdvYmpudW0pOy8vLCAwKTsKKwkJCWJyZWFrOworCQl9CisJY2FzZSBQREZPQkpfRElDVElPTkFSWToKKwkJeworCQkJQ1BERl9EaWN0aW9uYXJ5KiBwRGljdCA9IChDUERGX0RpY3Rpb25hcnkqKXBPYmo7CisJCQkKKwkJCUZYX1BPU0lUSU9OIHBvcyA9IHBEaWN0LT5HZXRTdGFydFBvcygpOworCQkJd2hpbGUocG9zKQorCQkJeworCQkJCUNGWF9CeXRlU3RyaW5nIGtleSgiIik7CisJCQkJQ1BERl9PYmplY3QqIHBOZXh0T2JqID0gcERpY3QtPkdldE5leHRFbGVtZW50KHBvcywga2V5KTsKKwkJCQlpZiAoIUZYU1lTX3N0cmNtcChrZXksICJQYXJlbnQiKSB8fCAhRlhTWVNfc3RyY21wKGtleSwgIlByZXYiKSB8fCAhRlhTWVNfc3RyY21wKGtleSwgIkZpcnN0IikpCisJCQkJCWNvbnRpbnVlOworCQkJCWlmKHBOZXh0T2JqKQorCQkJCXsKKwkJCQkJaWYoIVVwZGF0ZVJlZmVyZW5jZShwTmV4dE9iaiwgcERvYywgcE1hcFB0clRvUHRyKSkKKwkJCQkJCXBEaWN0LT5SZW1vdmVBdChrZXkpOworCQkJCX0KKwkJCQllbHNlCisJCQkJCXJldHVybiBGQUxTRTsKKwkJCX0KKwkJCWJyZWFrOworCQl9CisJY2FzZQlQREZPQkpfQVJSQVk6CisJCXsKKwkJCUNQREZfQXJyYXkqIHBBcnJheSA9IChDUERGX0FycmF5KilwT2JqOworCQkJRlhfRFdPUkQgY291bnQgPSBwQXJyYXktPkdldENvdW50KCk7CisJCQlmb3IoRlhfRFdPUkQgaSA9IDA7IGkgPCBjb3VudDsgaSArKykKKwkJCXsKKwkJCQlDUERGX09iamVjdCogcE5leHRPYmogPSBwQXJyYXktPkdldEVsZW1lbnQoaSk7CisJCQkJaWYocE5leHRPYmopCisJCQkJeworCQkJCQlpZighVXBkYXRlUmVmZXJlbmNlKHBOZXh0T2JqLCBwRG9jLCBwTWFwUHRyVG9QdHIpKQorCQkJCQkJcmV0dXJuIEZBTFNFOworCQkJCX0KKwkJCQllbHNlCisJCQkJCXJldHVybiBGQUxTRTsKKwkJCX0KKwkJCWJyZWFrOworCQl9CisJY2FzZQlQREZPQkpfU1RSRUFNOgorCQl7CisJCQlDUERGX1N0cmVhbSogcFN0cmVhbSA9IChDUERGX1N0cmVhbSopcE9iajsKKwkJCUNQREZfRGljdGlvbmFyeSogcERpY3QgPSBwU3RyZWFtLT5HZXREaWN0KCk7CisJCQlpZihwRGljdCkKKwkJCXsKKwkJCQlpZighVXBkYXRlUmVmZXJlbmNlKHBEaWN0LCBwRG9jLCBwTWFwUHRyVG9QdHIpKQorCQkJCQlyZXR1cm4gRkFMU0U7CisJCQl9CisJCQllbHNlCisJCQkJcmV0dXJuIEZBTFNFOworCQkJYnJlYWs7CisJCX0KKwlkZWZhdWx0OglicmVhazsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworaW50CUNQREZfUGFnZU9yZ2FuaXplcjo6R2V0TmV3T2JqSWQoQ1BERl9Eb2N1bWVudCAqcERvYywgQ0ZYX01hcFB0clRvUHRyKiBwTWFwUHRyVG9QdHIsCisJCQkJCQkJCQlDUERGX1JlZmVyZW5jZSAqcFJlZikKK3sKKwlzaXplX3QgZHdPYmpudW0gPSAwOworCWlmKCFwUmVmKQorCQlyZXR1cm4gMDsKKwlkd09iam51bSA9IHBSZWYtPkdldFJlZk9iak51bSgpOworCQorCXNpemVfdCBkd05ld09iak51bSA9IDA7CisJCisJcE1hcFB0clRvUHRyLT5Mb29rdXAoKEZYX0xQVk9JRClkd09iam51bSwgKEZYX0xQVk9JRCYpZHdOZXdPYmpOdW0pOworCWlmKGR3TmV3T2JqTnVtKQorCXsKKwkJcmV0dXJuIChpbnQpZHdOZXdPYmpOdW07CisJfQorCWVsc2UKKwl7CisJCUNQREZfT2JqZWN0KiBwQ2xvbmUgID0gcFJlZi0+R2V0RGlyZWN0KCktPkNsb25lKCk7CisJCWlmKCFwQ2xvbmUpCQkJcmV0dXJuIDA7CisJCQorCQlpZihwQ2xvbmUtPkdldFR5cGUoKSA9PSBQREZPQkpfRElDVElPTkFSWSkKKwkJeworCQkJQ1BERl9EaWN0aW9uYXJ5KiBwRGljdENsb25lID0gKENQREZfRGljdGlvbmFyeSopcENsb25lOworCQkJaWYocERpY3RDbG9uZS0+S2V5RXhpc3QoIlR5cGUiKSkKKwkJCXsKKwkJCQlDRlhfQnl0ZVN0cmluZyBzdHJUeXBlID0gcERpY3RDbG9uZS0+R2V0U3RyaW5nKCJUeXBlIik7CisJCQkJaWYoIUZYU1lTX3N0cmljbXAoc3RyVHlwZSwgIlBhZ2VzIikpCisJCQkJeworCQkJCQlwRGljdENsb25lLT5SZWxlYXNlKCk7CisJCQkJCXJldHVybiA0OworCQkJCX0KKwkJCQllbHNlIGlmKCFGWFNZU19zdHJpY21wKHN0clR5cGUsICJQYWdlIikpCisJCQkJeworCQkJCQlwRGljdENsb25lLT5SZWxlYXNlKCk7CisJCQkJCXJldHVybiAgMDsKKwkJCQl9CisJCQl9CisJCX0KKwkJZHdOZXdPYmpOdW0gPSBwRG9jLT5BZGRJbmRpcmVjdE9iamVjdChwQ2xvbmUpOy8vLCBvbnVtLCBnbnVtKTsKKwkJcE1hcFB0clRvUHRyLT5TZXRBdCgoRlhfTFBWT0lEKWR3T2JqbnVtLCAoRlhfTFBWT0lEKWR3TmV3T2JqTnVtKTsKKwkJCisJCWlmKCFVcGRhdGVSZWZlcmVuY2UocENsb25lLCBwRG9jLCBwTWFwUHRyVG9QdHIpKQorCQl7CisJCQlwQ2xvbmUtPlJlbGVhc2UoKTsKKwkJCXJldHVybiAwOworCQl9CisJCXJldHVybiAoaW50KWR3TmV3T2JqTnVtOworCX0KKwlyZXR1cm4gMDsKK30KKworRlBERl9CT09MIFBhcnNlclBhZ2VSYW5nZVN0cmluZyhDRlhfQnl0ZVN0cmluZyByYW5nc3RyaW5nLCBDRlhfV29yZEFycmF5KiBwYWdlQXJyYXksaW50IG5Db3VudCkKK3sKKworCWlmKHJhbmdzdHJpbmcuR2V0TGVuZ3RoKCkgIT0gMCkKKwl7CisJCXJhbmdzdHJpbmcuUmVtb3ZlKCcgJyk7CisJCWludCBuTGVuZ3RoID0gcmFuZ3N0cmluZy5HZXRMZW5ndGgoKTsKKwkJQ0ZYX0J5dGVTdHJpbmcgY2JDb21wYXJlU3RyaW5nKCIwMTIzNDU2Nzg5LSwiKTsKKwkJZm9yKGludCBpPTA7IGk8bkxlbmd0aDsgaSsrKQorCQl7CisJCQlpZihjYkNvbXBhcmVTdHJpbmcuRmluZChyYW5nc3RyaW5nW2ldKSA9PSAtMSkKKwkJCQlyZXR1cm4gRkFMU0U7CisJCX0KKwkJQ0ZYX0J5dGVTdHJpbmcgY2JNaWRSYW5nZTsKKwkJaW50IG5TdHJpbmdGcm9tID0gMDsKKwkJaW50IG5TdHJpbmdUbz0wOworCQl3aGlsZShuU3RyaW5nVG8gPCBuTGVuZ3RoKQorCQl7CisJCQluU3RyaW5nVG8gPSByYW5nc3RyaW5nLkZpbmQoJywnLG5TdHJpbmdGcm9tKTsKKwkJCWlmKG5TdHJpbmdUbyA9PSAtMSkKKwkJCXsKKwkJCQluU3RyaW5nVG8gPSBuTGVuZ3RoOworCQkJfQorCQkJY2JNaWRSYW5nZSA9IHJhbmdzdHJpbmcuTWlkKG5TdHJpbmdGcm9tLG5TdHJpbmdUby1uU3RyaW5nRnJvbSk7CisJCQkKKwkJCWludCBuTWlkID0gY2JNaWRSYW5nZS5GaW5kKCctJyk7CisJCQlpZihuTWlkID09IC0xKQorCQkJeworCQkJCWxvbmcgbFBhZ2VOdW0gPSBhdG9sKGNiTWlkUmFuZ2UpOworCQkJCWlmKGxQYWdlTnVtIDw9IDAgfHwgbFBhZ2VOdW0gPiBuQ291bnQpCisJCQkJCXJldHVybiBGQUxTRTsKKwkJCQlwYWdlQXJyYXktPkFkZCgoRlhfV09SRClsUGFnZU51bSk7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJaW50IG5TdGFydFBhZ2VOdW0gPSBhdG9sKGNiTWlkUmFuZ2UuTWlkKDAsbk1pZCkpOworCQkJCWlmIChuU3RhcnRQYWdlTnVtID09MCkKKwkJCQl7CisJCQkJCXJldHVybiBGQUxTRTsKKwkJCQl9CisKKworCQkJCW5NaWQgPSBuTWlkKzE7CisJCQkJaW50IG5FbmQgPSBjYk1pZFJhbmdlLkdldExlbmd0aCgpLW5NaWQ7CisKKwkJCQlpZihuRW5kID09MClyZXR1cm4gRkFMU0U7CisJCQkJCisJCQkJLy8JCQkJaW50IG5FbmRQYWdlTnVtID0gKG5FbmQgPT0gMCk/bkNvdW50OmF0b2woY2JNaWRSYW5nZS5NaWQobk1pZCxuRW5kKSk7CisJCQkJaW50IG5FbmRQYWdlTnVtID0gYXRvbChjYk1pZFJhbmdlLk1pZChuTWlkLG5FbmQpKTsKKwkJCQkKKwkJCQlpZihuU3RhcnRQYWdlTnVtIDwgMCB8fG5TdGFydFBhZ2VOdW0gPm5FbmRQYWdlTnVtfHwgbkVuZFBhZ2VOdW0gPiBuQ291bnQpCisJCQkJeworCQkJCQlyZXR1cm4gRkFMU0U7CisJCQkJfQorCQkJCWVsc2UKKwkJCQl7CisJCQkJCWZvcihpbnQgbkluZGV4PW5TdGFydFBhZ2VOdW07IG5JbmRleCA8PSBuRW5kUGFnZU51bTsgbkluZGV4ICsrKQorCQkJCQkJcGFnZUFycmF5LT5BZGQobkluZGV4KTsKKwkJCQl9CisJCQl9CisJCQluU3RyaW5nRnJvbSA9IG5TdHJpbmdUbyArMTsKKwkJfQorCX0KKwlyZXR1cm4gVFJVRTsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZfSW1wb3J0UGFnZXMoRlBERl9ET0NVTUVOVCBkZXN0X2RvYyxGUERGX0RPQ1VNRU5UIHNyY19kb2MsIAorCQkJCQkJCQkJCQkgRlBERl9CWVRFU1RSSU5HIHBhZ2VyYW5nZSwgaW50IGluZGV4KQoreworCWlmKGRlc3RfZG9jID09IE5VTEwgfHwgc3JjX2RvYyA9PSBOVUxMICkKKwkJcmV0dXJuIEZBTFNFOworCUNGWF9Xb3JkQXJyYXkgcGFnZUFycmF5OworCUNQREZfRG9jdW1lbnQqIHBTcmNEb2MgPSAoQ1BERl9Eb2N1bWVudCopc3JjX2RvYzsKKwlpbnQgbkNvdW50ID0gcFNyY0RvYy0+R2V0UGFnZUNvdW50KCk7CisJaWYocGFnZXJhbmdlKQorCXsKKwkJaWYoUGFyc2VyUGFnZVJhbmdlU3RyaW5nKHBhZ2VyYW5nZSwmcGFnZUFycmF5LG5Db3VudCkgPT0gRkFMU0UpCisJCQlyZXR1cm4gRkFMU0U7CisJfQorCWVsc2UKKwl7CisJCWZvcihpbnQgaT0xOyBpPD1uQ291bnQ7IGkrKykKKwkJeworCQkJcGFnZUFycmF5LkFkZChpKTsKKwkJfQorCX0KKwkKKwlDUERGX0RvY3VtZW50KiBwRGVzdERvYyA9IChDUERGX0RvY3VtZW50KilkZXN0X2RvYzsKKwlDUERGX1BhZ2VPcmdhbml6ZXIgcGFnZU9yZzsKKworCXBhZ2VPcmcuUERGRG9jSW5pdChwRGVzdERvYyxwU3JjRG9jKTsKKworCWlmKHBhZ2VPcmcuRXhwb3J0UGFnZShwU3JjRG9jLCZwYWdlQXJyYXkscERlc3REb2MsaW5kZXgpKQorCQlyZXR1cm4gVFJVRTsKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX0NvcHlWaWV3ZXJQcmVmZXJlbmNlcyhGUERGX0RPQ1VNRU5UIGRlc3RfZG9jLCBGUERGX0RPQ1VNRU5UIHNyY19kb2MpCit7CisJaWYoc3JjX2RvYyA9PSBOVUxMIHx8IGRlc3RfZG9jID09IE5VTEwpCisJCXJldHVybiBmYWxzZTsKKwlDUERGX0RvY3VtZW50KiBwU3JjRG9jID0gKENQREZfRG9jdW1lbnQqKXNyY19kb2M7CisJQ1BERl9EaWN0aW9uYXJ5KiBwU3JjRGljdCA9IHBTcmNEb2MtPkdldFJvb3QoKTsKKwlwU3JjRGljdCA9IHBTcmNEaWN0LT5HZXREaWN0KEZYX0JTVFJDKCJWaWV3ZXJQcmVmZXJlbmNlcyIpKTs7CisJaWYoIXBTcmNEaWN0KQorCQlyZXR1cm4gRkFMU0U7CisJQ1BERl9Eb2N1bWVudCogcERzdERvYyA9IChDUERGX0RvY3VtZW50KilkZXN0X2RvYzsKKwlDUERGX0RpY3Rpb25hcnkqIHBEc3REaWN0ID0gcERzdERvYy0+R2V0Um9vdCgpOworCWlmKCFwRHN0RGljdCkKKwkJcmV0dXJuIEZBTFNFOworCXBEc3REaWN0LT5TZXRBdChGWF9CU1RSQygiVmlld2VyUHJlZmVyZW5jZXMiKSwgcFNyY0RpY3QtPkNsb25lKFRSVUUpKTsKKwlyZXR1cm4gVFJVRTsKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnBkZnNhdmUuY3BwIGIvZnBkZnNkay9zcmMvZnBkZnNhdmUuY3BwCmluZGV4IDgyNzJlYjAuLjBjN2FjYzggMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZwZGZzYXZlLmNwcAorKysgYi9mcGRmc2RrL3NyYy9mcGRmc2F2ZS5jcHAKQEAgLTEsOTEgKzEsOTEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZnNhdmUuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmZWRpdC5oIg0KLSNpZiBfRlhfT1NfID09IF9GWF9BTkRST0lEXw0KLSNpbmNsdWRlICJ0aW1lLmgiDQotI2Vsc2UNCi0jaW5jbHVkZSA8Y3RpbWU+DQotI2VuZGlmDQotDQotY2xhc3MgQ0ZYX0lGaWxlV3JpdGU6cHVibGljIElGWF9TdHJlYW1Xcml0ZQ0KLXsNCi0JDQotcHVibGljOg0KLQlDRlhfSUZpbGVXcml0ZSgpOw0KLQlGWF9CT09MCQkJCUluaXQoIEZQREZfRklMRVdSSVRFICogcEZpbGVXcml0ZVN0cnVjdCApOw0KLQl2aXJ0dWFsCUZYX0JPT0wJCVdyaXRlQmxvY2soY29uc3Qgdm9pZCogcERhdGEsIHNpemVfdCBzaXplKTsNCi0JdmlydHVhbCB2b2lkCQlSZWxlYXNlKCl7fTsNCi0JDQotcHJvdGVjdGVkOg0KLQlGUERGX0ZJTEVXUklURSoJCW1fcEZpbGVXcml0ZVN0cnVjdDsNCi19Ow0KLQ0KLUNGWF9JRmlsZVdyaXRlOjpDRlhfSUZpbGVXcml0ZSgpDQotew0KLQltX3BGaWxlV3JpdGVTdHJ1Y3QgPSBOVUxMOw0KLX0NCi0NCi1GWF9CT09MIENGWF9JRmlsZVdyaXRlOjpJbml0KCBGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGVTdHJ1Y3QgKQ0KLXsNCi0JaWYgKCFwRmlsZVdyaXRlU3RydWN0KQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQllbHNlDQotCXsNCi0JCW1fcEZpbGVXcml0ZVN0cnVjdCA9IHBGaWxlV3JpdGVTdHJ1Y3Q7DQotCX0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0lGaWxlV3JpdGU6OldyaXRlQmxvY2soY29uc3Qgdm9pZCogcERhdGEsIHNpemVfdCBzaXplKQ0KLXsNCi0JaWYgKG1fcEZpbGVXcml0ZVN0cnVjdCkNCi0Jew0KLQkJbV9wRmlsZVdyaXRlU3RydWN0LT5Xcml0ZUJsb2NrKCBtX3BGaWxlV3JpdGVTdHJ1Y3QsIHBEYXRhLCBzaXplICk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQllbHNlIA0KLQkJcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GUERGX0JPT0wgX0ZQREZfRG9jX1NhdmUoRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGUsRlBERl9EV09SRCBmbGFncywgRlBERl9CT09MIGJTZXRWZXJzaW9uLA0KLQkJCQkJCSBpbnQgZmlsZVZlcmlvbikNCi17DQotCUNQREZfRG9jdW1lbnQqIHBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7DQotCWlmICghcERvYykgDQotCQlyZXR1cm4gMDsNCi0JDQotCWlmICggZmxhZ3MgPCAxIHx8IGZsYWdzID4gMiApDQotCXsNCi0JCWZsYWdzID0gMDsNCi0JfQ0KLQkNCi0JQ1BERl9DcmVhdG9yIEZpbGVNYWtlcihwRG9jKTsNCi0JaWYoYlNldFZlcnNpb24pDQotCQlGaWxlTWFrZXIuU2V0RmlsZVZlcnNpb24oZmlsZVZlcmlvbik7DQotCUNGWF9JRmlsZVdyaXRlKiBwU3RyZWFtV3JpdGUgPSBOVUxMOw0KLQlGWF9CT09MIGJSZXQ7DQotCXBTdHJlYW1Xcml0ZSA9IG5ldyBDRlhfSUZpbGVXcml0ZTsNCi0JcFN0cmVhbVdyaXRlLT5Jbml0KCBwRmlsZVdyaXRlICk7DQotCWJSZXQgPSBGaWxlTWFrZXIuQ3JlYXRlKHBTdHJlYW1Xcml0ZSwgZmxhZ3MpOw0KLQlkZWxldGUgcFN0cmVhbVdyaXRlOw0KLQlyZXR1cm4gYlJldDsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZfU2F2ZUFzQ29weSgJRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGUsDQotCQkJCQkJCQkJCQkJRlBERl9EV09SRCBmbGFncyApDQotew0KLQlyZXR1cm4gX0ZQREZfRG9jX1NhdmUoZG9jdW1lbnQsIHBGaWxlV3JpdGUsIGZsYWdzLCBGQUxTRSAsIDApOw0KLX0NCi0NCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERl9TYXZlV2l0aFZlcnNpb24oCUZQREZfRE9DVU1FTlQgZG9jdW1lbnQsRlBERl9GSUxFV1JJVEUgKiBwRmlsZVdyaXRlLA0KLQlGUERGX0RXT1JEIGZsYWdzLCBpbnQgZmlsZVZlcnNpb24pDQotew0KLQlyZXR1cm4gX0ZQREZfRG9jX1NhdmUoZG9jdW1lbnQsIHBGaWxlV3JpdGUsIGZsYWdzLCBUUlVFICwgZmlsZVZlcnNpb24pOw0KLX0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnBkZnNhdmUuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZlZGl0LmgiCisjaWYgX0ZYX09TXyA9PSBfRlhfQU5EUk9JRF8KKyNpbmNsdWRlICJ0aW1lLmgiCisjZWxzZQorI2luY2x1ZGUgPGN0aW1lPgorI2VuZGlmCisKK2NsYXNzIENGWF9JRmlsZVdyaXRlOnB1YmxpYyBJRlhfU3RyZWFtV3JpdGUKK3sKKwkKK3B1YmxpYzoKKwlDRlhfSUZpbGVXcml0ZSgpOworCUZYX0JPT0wJCQkJSW5pdCggRlBERl9GSUxFV1JJVEUgKiBwRmlsZVdyaXRlU3RydWN0ICk7CisJdmlydHVhbAlGWF9CT09MCQlXcml0ZUJsb2NrKGNvbnN0IHZvaWQqIHBEYXRhLCBzaXplX3Qgc2l6ZSk7CisJdmlydHVhbCB2b2lkCQlSZWxlYXNlKCl7fTsKKwkKK3Byb3RlY3RlZDoKKwlGUERGX0ZJTEVXUklURSoJCW1fcEZpbGVXcml0ZVN0cnVjdDsKK307CisKK0NGWF9JRmlsZVdyaXRlOjpDRlhfSUZpbGVXcml0ZSgpCit7CisJbV9wRmlsZVdyaXRlU3RydWN0ID0gTlVMTDsKK30KKworRlhfQk9PTCBDRlhfSUZpbGVXcml0ZTo6SW5pdCggRlBERl9GSUxFV1JJVEUgKiBwRmlsZVdyaXRlU3RydWN0ICkKK3sKKwlpZiAoIXBGaWxlV3JpdGVTdHJ1Y3QpCisJCXJldHVybiBGQUxTRTsKKwllbHNlCisJeworCQltX3BGaWxlV3JpdGVTdHJ1Y3QgPSBwRmlsZVdyaXRlU3RydWN0OworCX0KKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDRlhfSUZpbGVXcml0ZTo6V3JpdGVCbG9jayhjb25zdCB2b2lkKiBwRGF0YSwgc2l6ZV90IHNpemUpCit7CisJaWYgKG1fcEZpbGVXcml0ZVN0cnVjdCkKKwl7CisJCW1fcEZpbGVXcml0ZVN0cnVjdC0+V3JpdGVCbG9jayggbV9wRmlsZVdyaXRlU3RydWN0LCBwRGF0YSwgc2l6ZSApOworCQlyZXR1cm4gVFJVRTsKKwl9CisJZWxzZSAKKwkJcmV0dXJuIEZBTFNFOworfQorCitGUERGX0JPT0wgX0ZQREZfRG9jX1NhdmUoRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGUsRlBERl9EV09SRCBmbGFncywgRlBERl9CT09MIGJTZXRWZXJzaW9uLAorCQkJCQkJIGludCBmaWxlVmVyaW9uKQoreworCUNQREZfRG9jdW1lbnQqIHBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7CisJaWYgKCFwRG9jKSAKKwkJcmV0dXJuIDA7CisJCisJaWYgKCBmbGFncyA8IDEgfHwgZmxhZ3MgPiAyICkKKwl7CisJCWZsYWdzID0gMDsKKwl9CisJCisJQ1BERl9DcmVhdG9yIEZpbGVNYWtlcihwRG9jKTsKKwlpZihiU2V0VmVyc2lvbikKKwkJRmlsZU1ha2VyLlNldEZpbGVWZXJzaW9uKGZpbGVWZXJpb24pOworCUNGWF9JRmlsZVdyaXRlKiBwU3RyZWFtV3JpdGUgPSBOVUxMOworCUZYX0JPT0wgYlJldDsKKwlwU3RyZWFtV3JpdGUgPSBuZXcgQ0ZYX0lGaWxlV3JpdGU7CisJcFN0cmVhbVdyaXRlLT5Jbml0KCBwRmlsZVdyaXRlICk7CisJYlJldCA9IEZpbGVNYWtlci5DcmVhdGUocFN0cmVhbVdyaXRlLCBmbGFncyk7CisJZGVsZXRlIHBTdHJlYW1Xcml0ZTsKKwlyZXR1cm4gYlJldDsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZfU2F2ZUFzQ29weSgJRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGUsCisJCQkJCQkJCQkJCQlGUERGX0RXT1JEIGZsYWdzICkKK3sKKwlyZXR1cm4gX0ZQREZfRG9jX1NhdmUoZG9jdW1lbnQsIHBGaWxlV3JpdGUsIGZsYWdzLCBGQUxTRSAsIDApOworfQorCisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX1NhdmVXaXRoVmVyc2lvbigJRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0ZJTEVXUklURSAqIHBGaWxlV3JpdGUsCisJRlBERl9EV09SRCBmbGFncywgaW50IGZpbGVWZXJzaW9uKQoreworCXJldHVybiBfRlBERl9Eb2NfU2F2ZShkb2N1bWVudCwgcEZpbGVXcml0ZSwgZmxhZ3MsIFRSVUUgLCBmaWxlVmVyc2lvbik7Cit9CmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mcGRmc2RrZGxsLnJjIGIvZnBkZnNkay9zcmMvZnBkZnNka2RsbC5yYwppbmRleCBlZTEyMDQ5Li5mMjAzZjJlIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mcGRmc2RrZGxsLnJjCisrKyBiL2ZwZGZzZGsvc3JjL2ZwZGZzZGtkbGwucmMKQEAgLTEsMTA5ICsxLDEwOSBAQAotLy9NaWNyb3NvZnQgRGV2ZWxvcGVyIFN0dWRpbyBnZW5lcmF0ZWQgcmVzb3VyY2Ugc2NyaXB0Lg0KLS8vDQotI2luY2x1ZGUgInJlc291cmNlLmgiDQotDQotI2RlZmluZSBBUFNUVURJT19SRUFET05MWV9TWU1CT0xTDQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0vLw0KLS8vIEdlbmVyYXRlZCBmcm9tIHRoZSBURVhUSU5DTFVERSAyIHJlc291cmNlLg0KLS8vDQotI2luY2x1ZGUgImFmeHJlcy5oIg0KLQ0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotI3VuZGVmIEFQU1RVRElPX1JFQURPTkxZX1NZTUJPTFMNCi0NCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KLS8vIENoaW5lc2UgKFAuUi5DLikgcmVzb3VyY2VzDQotDQotI2lmICFkZWZpbmVkKEFGWF9SRVNPVVJDRV9ETEwpIHx8IGRlZmluZWQoQUZYX1RBUkdfQ0hTKQ0KLSNpZmRlZiBfV0lOMzINCi1MQU5HVUFHRSBMQU5HX0NISU5FU0UsIFNVQkxBTkdfQ0hJTkVTRV9TSU1QTElGSUVEDQotI3ByYWdtYSBjb2RlX3BhZ2UoOTM2KQ0KLSNlbmRpZiAvL19XSU4zMg0KLQ0KLSNpZm5kZWYgX01BQw0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotLy8NCi0vLyBWZXJzaW9uDQotLy8NCi0NCi1WU19WRVJTSU9OX0lORk8gVkVSU0lPTklORk8NCi0gRklMRVZFUlNJT04gMiwwLDAsMTcwNQ0KLSBQUk9EVUNUVkVSU0lPTiAyLDAsMCwxNzA1DQotIEZJTEVGTEFHU01BU0sgMHgzZkwNCi0jaWZkZWYgX0RFQlVHDQotIEZJTEVGTEFHUyAweDFMDQotI2Vsc2UNCi0gRklMRUZMQUdTIDB4MEwNCi0jZW5kaWYNCi0gRklMRU9TIDB4NDAwMDRMDQotIEZJTEVUWVBFIDB4MkwNCi0gRklMRVNVQlRZUEUgMHgwTA0KLUJFR0lODQotICAgIEJMT0NLICJTdHJpbmdGaWxlSW5mbyINCi0gICAgQkVHSU4NCi0gICAgICAgIEJMT0NLICIwODA5MDRiMCINCi0gICAgICAgIEJFR0lODQotICAgICAgICAgICAgVkFMVUUgIkNvbW1lbnRzIiwgIkZveGl0IENvcnBvcmF0aW9uXDAiDQotICAgICAgICAgICAgVkFMVUUgIkNvbXBhbnlOYW1lIiwgIkZveGl0IENvcnBvcmF0aW9uXDAiDQotICAgICAgICAgICAgVkFMVUUgIkZpbGVEZXNjcmlwdGlvbiIsICJmcGRmc2RrXDAiDQotICAgICAgICAgICAgVkFMVUUgIkZpbGVWZXJzaW9uIiwgIjIsIDAsIDAsIDE3MDVcMCINCi0gICAgICAgICAgICBWQUxVRSAiSW50ZXJuYWxOYW1lIiwgImZwZGZzZGtcMCINCi0gICAgICAgICAgICBWQUxVRSAiTGVnYWxDb3B5cmlnaHQiLCAiQ29weXJpZ2h0IChDKSAyMDA0LTIwMDkgRm94aXQgQ29ycG9yYXRpb25cMCINCi0gICAgICAgICAgICBWQUxVRSAiTGVnYWxUcmFkZW1hcmtzIiwgIlwwIg0KLSAgICAgICAgICAgIFZBTFVFICJPcmlnaW5hbEZpbGVuYW1lIiwgImZwZGZzZGsuZGxsXDAiDQotICAgICAgICAgICAgVkFMVUUgIlByaXZhdGVCdWlsZCIsICJcMCINCi0gICAgICAgICAgICBWQUxVRSAiUHJvZHVjdE5hbWUiLCAiRm94aXQgUERGIFNESyBETExcMCINCi0gICAgICAgICAgICBWQUxVRSAiUHJvZHVjdFZlcnNpb24iLCAiMiwgMCwgMCwgMTcwNVwwIg0KLSAgICAgICAgICAgIFZBTFVFICJTcGVjaWFsQnVpbGQiLCAiXDAiDQotICAgICAgICBFTkQNCi0gICAgRU5EDQotICAgIEJMT0NLICJWYXJGaWxlSW5mbyINCi0gICAgQkVHSU4NCi0gICAgICAgIFZBTFVFICJUcmFuc2xhdGlvbiIsIDB4ODA5LCAxMjAwDQotICAgIEVORA0KLUVORA0KLQ0KLSNlbmRpZiAgICAvLyAhX01BQw0KLQ0KLQ0KLSNpZmRlZiBBUFNUVURJT19JTlZPS0VEDQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0vLw0KLS8vIFRFWFRJTkNMVURFDQotLy8NCi0NCi0xIFRFWFRJTkNMVURFIE1PVkVBQkxFIFBVUkUgDQotQkVHSU4NCi0gICAgInJlc291cmNlLmhcMCINCi1FTkQNCi0NCi0yIFRFWFRJTkNMVURFIE1PVkVBQkxFIFBVUkUgDQotQkVHSU4NCi0gICAgIiNpbmNsdWRlICIiYWZ4cmVzLmgiIlxyXG4iDQotICAgICJcMCINCi1FTkQNCi0NCi0zIFRFWFRJTkNMVURFIE1PVkVBQkxFIFBVUkUgDQotQkVHSU4NCi0gICAgIlxyXG4iDQotICAgICJcMCINCi1FTkQNCi0NCi0jZW5kaWYgICAgLy8gQVBTVFVESU9fSU5WT0tFRA0KLQ0KLSNlbmRpZiAgICAvLyBDaGluZXNlIChQLlIuQy4pIHJlc291cmNlcw0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotDQotDQotDQotI2lmbmRlZiBBUFNUVURJT19JTlZPS0VEDQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0vLw0KLS8vIEdlbmVyYXRlZCBmcm9tIHRoZSBURVhUSU5DTFVERSAzIHJlc291cmNlLg0KLS8vDQotDQotDQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0jZW5kaWYgICAgLy8gbm90IEFQU1RVRElPX0lOVk9LRUQNCi0NCisvL01pY3Jvc29mdCBEZXZlbG9wZXIgU3R1ZGlvIGdlbmVyYXRlZCByZXNvdXJjZSBzY3JpcHQuCisvLworI2luY2x1ZGUgInJlc291cmNlLmgiCisKKyNkZWZpbmUgQVBTVFVESU9fUkVBRE9OTFlfU1lNQk9MUworLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKy8vCisvLyBHZW5lcmF0ZWQgZnJvbSB0aGUgVEVYVElOQ0xVREUgMiByZXNvdXJjZS4KKy8vCisjaW5jbHVkZSAiYWZ4cmVzLmgiCisKKy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisjdW5kZWYgQVBTVFVESU9fUkVBRE9OTFlfU1lNQk9MUworCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworLy8gQ2hpbmVzZSAoUC5SLkMuKSByZXNvdXJjZXMKKworI2lmICFkZWZpbmVkKEFGWF9SRVNPVVJDRV9ETEwpIHx8IGRlZmluZWQoQUZYX1RBUkdfQ0hTKQorI2lmZGVmIF9XSU4zMgorTEFOR1VBR0UgTEFOR19DSElORVNFLCBTVUJMQU5HX0NISU5FU0VfU0lNUExJRklFRAorI3ByYWdtYSBjb2RlX3BhZ2UoOTM2KQorI2VuZGlmIC8vX1dJTjMyCisKKyNpZm5kZWYgX01BQworLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKy8vCisvLyBWZXJzaW9uCisvLworCitWU19WRVJTSU9OX0lORk8gVkVSU0lPTklORk8KKyBGSUxFVkVSU0lPTiAyLDAsMCwxNzA1CisgUFJPRFVDVFZFUlNJT04gMiwwLDAsMTcwNQorIEZJTEVGTEFHU01BU0sgMHgzZkwKKyNpZmRlZiBfREVCVUcKKyBGSUxFRkxBR1MgMHgxTAorI2Vsc2UKKyBGSUxFRkxBR1MgMHgwTAorI2VuZGlmCisgRklMRU9TIDB4NDAwMDRMCisgRklMRVRZUEUgMHgyTAorIEZJTEVTVUJUWVBFIDB4MEwKK0JFR0lOCisgICAgQkxPQ0sgIlN0cmluZ0ZpbGVJbmZvIgorICAgIEJFR0lOCisgICAgICAgIEJMT0NLICIwODA5MDRiMCIKKyAgICAgICAgQkVHSU4KKyAgICAgICAgICAgIFZBTFVFICJDb21tZW50cyIsICJGb3hpdCBDb3Jwb3JhdGlvblwwIgorICAgICAgICAgICAgVkFMVUUgIkNvbXBhbnlOYW1lIiwgIkZveGl0IENvcnBvcmF0aW9uXDAiCisgICAgICAgICAgICBWQUxVRSAiRmlsZURlc2NyaXB0aW9uIiwgImZwZGZzZGtcMCIKKyAgICAgICAgICAgIFZBTFVFICJGaWxlVmVyc2lvbiIsICIyLCAwLCAwLCAxNzA1XDAiCisgICAgICAgICAgICBWQUxVRSAiSW50ZXJuYWxOYW1lIiwgImZwZGZzZGtcMCIKKyAgICAgICAgICAgIFZBTFVFICJMZWdhbENvcHlyaWdodCIsICJDb3B5cmlnaHQgKEMpIDIwMDQtMjAwOSBGb3hpdCBDb3Jwb3JhdGlvblwwIgorICAgICAgICAgICAgVkFMVUUgIkxlZ2FsVHJhZGVtYXJrcyIsICJcMCIKKyAgICAgICAgICAgIFZBTFVFICJPcmlnaW5hbEZpbGVuYW1lIiwgImZwZGZzZGsuZGxsXDAiCisgICAgICAgICAgICBWQUxVRSAiUHJpdmF0ZUJ1aWxkIiwgIlwwIgorICAgICAgICAgICAgVkFMVUUgIlByb2R1Y3ROYW1lIiwgIkZveGl0IFBERiBTREsgRExMXDAiCisgICAgICAgICAgICBWQUxVRSAiUHJvZHVjdFZlcnNpb24iLCAiMiwgMCwgMCwgMTcwNVwwIgorICAgICAgICAgICAgVkFMVUUgIlNwZWNpYWxCdWlsZCIsICJcMCIKKyAgICAgICAgRU5ECisgICAgRU5ECisgICAgQkxPQ0sgIlZhckZpbGVJbmZvIgorICAgIEJFR0lOCisgICAgICAgIFZBTFVFICJUcmFuc2xhdGlvbiIsIDB4ODA5LCAxMjAwCisgICAgRU5ECitFTkQKKworI2VuZGlmICAgIC8vICFfTUFDCisKKworI2lmZGVmIEFQU1RVRElPX0lOVk9LRUQKKy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisvLworLy8gVEVYVElOQ0xVREUKKy8vCisKKzEgVEVYVElOQ0xVREUgTU9WRUFCTEUgUFVSRSAKK0JFR0lOCisgICAgInJlc291cmNlLmhcMCIKK0VORAorCisyIFRFWFRJTkNMVURFIE1PVkVBQkxFIFBVUkUgCitCRUdJTgorICAgICIjaW5jbHVkZSAiImFmeHJlcy5oIiJcclxuIgorICAgICJcMCIKK0VORAorCiszIFRFWFRJTkNMVURFIE1PVkVBQkxFIFBVUkUgCitCRUdJTgorICAgICJcclxuIgorICAgICJcMCIKK0VORAorCisjZW5kaWYgICAgLy8gQVBTVFVESU9fSU5WT0tFRAorCisjZW5kaWYgICAgLy8gQ2hpbmVzZSAoUC5SLkMuKSByZXNvdXJjZXMKKy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKKworCisjaWZuZGVmIEFQU1RVRElPX0lOVk9LRUQKKy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisvLworLy8gR2VuZXJhdGVkIGZyb20gdGhlIFRFWFRJTkNMVURFIDMgcmVzb3VyY2UuCisvLworCisKKy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisjZW5kaWYgICAgLy8gbm90IEFQU1RVRElPX0lOVk9LRUQKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnBkZnRleHQuY3BwIGIvZnBkZnNkay9zcmMvZnBkZnRleHQuY3BwCmluZGV4IDYwNDJmY2MuLjFhYTA1NDIgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZwZGZ0ZXh0LmNwcAorKysgYi9mcGRmc2RrL3NyYy9mcGRmdGV4dC5jcHAKQEAgLTEsMjc4ICsxLDI3OCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmdGV4dC5oIg0KLQ0KLSNpZmRlZiBfV0lOMzINCi0jaW5jbHVkZSA8dGNoYXIuaD4NCi0jZW5kaWYNCi0NCi0gICAgICAgIC8vIGphYmRlbG1hbGVrOiBjb21tZW50ZWQgb3V0IHRvIGJ1aWxkIG9uIExpbnV4LiAgTm90IHVzZWQuDQotCS8vIGV4dGVybiBIQU5ETEUgZ19oTW9kdWxlOw0KLQ0KLURMTEVYUE9SVCBGUERGX1RFWFRQQUdFIFNURENBTEwgRlBERlRleHRfTG9hZFBhZ2UoRlBERl9QQUdFIHBhZ2UpDQotew0KLQlpZiAoIXBhZ2UpIHJldHVybiBOVUxMOw0KLQlJUERGX1RleHRQYWdlKiB0ZXh0cGFnZT1OVUxMOw0KLQl0cnkNCi0Jew0KLQkJQ1BERl9WaWV3ZXJQcmVmZXJlbmNlcyB2aWV3UmVmKCgoQ1BERl9QYWdlKilwYWdlKS0+bV9wRG9jdW1lbnQpOw0KLQkJdGV4dHBhZ2U9SVBERl9UZXh0UGFnZTo6Q3JlYXRlVGV4dFBhZ2UoKENQREZfUGFnZSopcGFnZSx2aWV3UmVmLklzRGlyZWN0aW9uUjJMKCkpOw0KLQkJdGV4dHBhZ2UtPlBhcnNlVGV4dFBhZ2UoKTsNCi0JfQ0KLQljYXRjaCAoLi4uKQ0KLQl7DQotCQlpZiAodGV4dHBhZ2UpDQotCQkJZGVsZXRlIHRleHRwYWdlOw0KLQkJcmV0dXJuIE5VTEw7DQotCX0NCi0JcmV0dXJuIHRleHRwYWdlOw0KLX0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0Nsb3NlUGFnZShGUERGX1RFWFRQQUdFIHRleHRfcGFnZSkNCi17DQotCWlmICh0ZXh0X3BhZ2Upew0KLQkJSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsNCi0JCWRlbGV0ZSB0ZXh0cGFnZTsNCi0JCXRleHRfcGFnZT1OVUxMOw0KLQl9DQotfQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGVGV4dF9Db3VudENoYXJzKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlKQ0KLXsNCi0JaWYgKCF0ZXh0X3BhZ2UpIHJldHVybgktMTsNCi0JSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsNCi0JcmV0dXJuICB0ZXh0cGFnZS0+Q291bnRDaGFycygpOw0KLX0NCi1ETExFWFBPUlQgdW5zaWduZWQgaW50IFNURENBTEwgRlBERlRleHRfR2V0VW5pY29kZShGUERGX1RFWFRQQUdFIHRleHRfcGFnZSwgaW50IGluZGV4KQ0KLXsNCi0JaWYgKCF0ZXh0X3BhZ2UpIHJldHVybiAtMTsNCi0JSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsNCi0NCi0JaWYgKGluZGV4PDAgfHwgaW5kZXg+PXRleHRwYWdlLT5Db3VudENoYXJzKCkpIHJldHVybiAwOw0KLQ0KLQlGUERGX0NIQVJfSU5GTwljaGFyaW5mbzsNCi0JdGV4dHBhZ2UtPkdldENoYXJJbmZvKGluZGV4LGNoYXJpbmZvKTsNCi0JcmV0dXJuIGNoYXJpbmZvLm1fVW5pY29kZTsNCi19DQotRExMRVhQT1JUIGRvdWJsZSBTVERDQUxMIEZQREZUZXh0X0dldEZvbnRTaXplKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLCBpbnQgaW5kZXgpDQotew0KLQlpZiAoIXRleHRfcGFnZSkgcmV0dXJuIDA7DQotCUlQREZfVGV4dFBhZ2UqIHRleHRwYWdlPShJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2U7DQotDQotCWlmIChpbmRleDwwIHx8IGluZGV4Pj10ZXh0cGFnZS0+Q291bnRDaGFycygpKSByZXR1cm4gMDsNCi0NCi0JRlBERl9DSEFSX0lORk8JY2hhcmluZm87DQotCXRleHRwYWdlLT5HZXRDaGFySW5mbyhpbmRleCxjaGFyaW5mbyk7DQotCXJldHVybiBjaGFyaW5mby5tX0ZvbnRTaXplOw0KLX0NCi0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0dldENoYXJCb3goRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCBpbmRleCxkb3VibGUqIGxlZnQsDQotCQkJCQkJCQkJCQkJCWRvdWJsZSogcmlnaHQsIGRvdWJsZSogYm90dG9tLCBkb3VibGUqIHRvcCkNCi17DQotCWlmICghdGV4dF9wYWdlKSByZXR1cm47DQotCUlQREZfVGV4dFBhZ2UqIHRleHRwYWdlPShJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2U7DQotCQ0KLQlpZiAoaW5kZXg8MCB8fCBpbmRleD49dGV4dHBhZ2UtPkNvdW50Q2hhcnMoKSkgcmV0dXJuIDsNCi0JRlBERl9DSEFSX0lORk8JY2hhcmluZm87DQotCXRleHRwYWdlLT5HZXRDaGFySW5mbyhpbmRleCxjaGFyaW5mbyk7DQotCSpsZWZ0PWNoYXJpbmZvLm1fQ2hhckJveC5sZWZ0Ow0KLQkqcmlnaHQ9Y2hhcmluZm8ubV9DaGFyQm94LnJpZ2h0Ow0KLQkqYm90dG9tPWNoYXJpbmZvLm1fQ2hhckJveC5ib3R0b207DQotCSp0b3A9Y2hhcmluZm8ubV9DaGFyQm94LnRvcDsNCi19DQotDQotLy9zZWxlY3QNCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0Q2hhckluZGV4QXRQb3MoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsZG91YmxlIHgsZG91YmxlIHksZG91YmxlIHhUb3JlbGFuY2UsZG91YmxlIHlUb3JlbGFuY2UpDQotew0KLQlpZiAoIXRleHRfcGFnZSkgcmV0dXJuIC0zOw0KLQlJUERGX1RleHRQYWdlKiB0ZXh0cGFnZT0oSVBERl9UZXh0UGFnZSopdGV4dF9wYWdlOw0KLQlyZXR1cm4gdGV4dHBhZ2UtPkdldEluZGV4QXRQb3MoKEZYX0ZMT0FUKXgsKEZYX0ZMT0FUKXksKEZYX0ZMT0FUKXhUb3JlbGFuY2UsKEZYX0ZMT0FUKXlUb3JlbGFuY2UpOw0KLX0NCi0NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0VGV4dChGUERGX1RFWFRQQUdFIHRleHRfcGFnZSxpbnQgc3RhcnQsaW50IGNvdW50LHVuc2lnbmVkIHNob3J0KiByZXN1bHQpDQotew0KLQlpZiAoIXRleHRfcGFnZSkgcmV0dXJuIDA7DQotCUlQREZfVGV4dFBhZ2UqIHRleHRwYWdlPShJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2U7DQotCQ0KLQlpZiAoc3RhcnQ+PXRleHRwYWdlLT5Db3VudENoYXJzKCkpIHJldHVybiAwOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzdHI9dGV4dHBhZ2UtPkdldFBhZ2VUZXh0KHN0YXJ0LGNvdW50KTsNCi0JaWYoc3RyLkdldExlbmd0aCgpPmNvdW50KQ0KLQkJc3RyID0gc3RyLkxlZnQoY291bnQpOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBjYlVURjE2c3RyID0gc3RyLlVURjE2TEVfRW5jb2RlKCk7DQotCUZYU1lTX21lbWNweShyZXN1bHQsY2JVVEYxNnN0ci5HZXRCdWZmZXIoY2JVVEYxNnN0ci5HZXRMZW5ndGgoKSksY2JVVEYxNnN0ci5HZXRMZW5ndGgoKSk7DQotCWNiVVRGMTZzdHIuUmVsZWFzZUJ1ZmZlcihjYlVURjE2c3RyLkdldExlbmd0aCgpKTsNCi0NCi0JcmV0dXJuIGNiVVRGMTZzdHIuR2V0TGVuZ3RoKCkvc2l6ZW9mKHVuc2lnbmVkIHNob3J0KTsNCi19DQotDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0NvdW50UmVjdHMoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsaW50IHN0YXJ0LGludCBjb3VudCkNCi17DQotCWlmICghdGV4dF9wYWdlKSByZXR1cm4gMDsNCi0JSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsNCi0JcmV0dXJuCXRleHRwYWdlLT5Db3VudFJlY3RzKHN0YXJ0LGNvdW50KTsNCi0NCi19DQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGVGV4dF9HZXRSZWN0KEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLGludCByZWN0X2luZGV4LCBkb3VibGUqIGxlZnQsZG91YmxlKiAgdG9wLA0KLQkJCQkJCQkJCQlkb3VibGUqICByaWdodCwgZG91YmxlKiAgYm90dG9tKQ0KLXsNCi0JaWYgKCF0ZXh0X3BhZ2UpIHJldHVybjsNCi0JSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsNCi0JQ0ZYX0Zsb2F0UmVjdAlyZWN0Ow0KLQl0ZXh0cGFnZS0+R2V0UmVjdChyZWN0X2luZGV4LHJlY3QubGVmdCxyZWN0LnRvcCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tKTsNCi0JKmxlZnQ9cmVjdC5sZWZ0Ow0KLQkqdG9wPXJlY3QudG9wOw0KLQkqcmlnaHQ9cmVjdC5yaWdodDsNCi0JKmJvdHRvbT1yZWN0LmJvdHRvbTsNCi19DQotDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0dldEJvdW5kZWRUZXh0KEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLGRvdWJsZSBsZWZ0LCBkb3VibGUgdG9wLCANCi0JCQkJCQkJCQkJCSAgZG91YmxlIHJpZ2h0LCBkb3VibGUgYm90dG9tLHVuc2lnbmVkIHNob3J0KiBidWZmZXIsaW50IGJ1ZmxlbikNCi17DQotCWlmICghdGV4dF9wYWdlKSByZXR1cm4gMDsNCi0JSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsNCi0JQ0ZYX0Zsb2F0UmVjdCByZWN0KChGWF9GTE9BVClsZWZ0LChGWF9GTE9BVClib3R0b20sKEZYX0ZMT0FUKXJpZ2h0LChGWF9GTE9BVCl0b3ApOw0KLQlDRlhfV2lkZVN0cmluZyBzdHI9dGV4dHBhZ2UtPkdldFRleHRCeVJlY3QocmVjdCk7DQotDQotCWlmIChidWZsZW48PTAgfHwgYnVmZmVyPT1OVUxMKQ0KLQl7DQotCQlyZXR1cm4gc3RyLkdldExlbmd0aCgpOw0KLQl9DQotDQotCUNGWF9CeXRlU3RyaW5nIGNiVVRGMTZTdHIgPSBzdHIuVVRGMTZMRV9FbmNvZGUoKTsNCi0JaW50IGxlbiA9IGNiVVRGMTZTdHIuR2V0TGVuZ3RoKCkvc2l6ZW9mKHVuc2lnbmVkIHNob3J0KTsNCi0JaW50IHNpemUgPSBidWZsZW4gPiBsZW4gPyBsZW4gOiBidWZsZW47DQotCUZYU1lTX21lbWNweShidWZmZXIsY2JVVEYxNlN0ci5HZXRCdWZmZXIoc2l6ZSpzaXplb2YodW5zaWduZWQgc2hvcnQpKSxzaXplKnNpemVvZih1bnNpZ25lZCBzaG9ydCkpOw0KLQljYlVURjE2U3RyLlJlbGVhc2VCdWZmZXIoc2l6ZSpzaXplb2YodW5zaWduZWQgc2hvcnQpKTsNCi0NCi0JcmV0dXJuIHNpemU7DQotCQkNCi19DQotDQotLy9TZWFyY2gNCi0vLy0xIGZvciBlbmQNCi1ETExFWFBPUlQgRlBERl9TQ0hIQU5ETEUgU1REQ0FMTCBGUERGVGV4dF9GaW5kU3RhcnQoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsRlBERl9XSURFU1RSSU5HIGZpbmR3aGF0LHVuc2lnbmVkIGxvbmcgZmxhZ3MsaW50IHN0YXJ0X2luZGV4KQ0KLXsNCi0JaWYgKCF0ZXh0X3BhZ2UpIHJldHVybiBOVUxMOw0KLQlJUERGX1RleHRQYWdlRmluZCogdGV4dHBhZ2VGaW5kPU5VTEw7DQotCXRyeQ0KLQl7DQotCQl0ZXh0cGFnZUZpbmQ9SVBERl9UZXh0UGFnZUZpbmQ6OkNyZWF0ZVBhZ2VGaW5kKChJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2UpOw0KLQkJdGV4dHBhZ2VGaW5kLT5GaW5kRmlyc3QoQ0ZYX1dpZGVTdHJpbmc6OkZyb21VVEYxNkxFKGZpbmR3aGF0KSxmbGFncyxzdGFydF9pbmRleCk7DQotCX0NCi0JY2F0Y2ggKC4uLikNCi0Jew0KLQkJaWYgKHRleHRwYWdlRmluZCkNCi0JCQlkZWxldGUgdGV4dHBhZ2VGaW5kOw0KLQkJcmV0dXJuIE5VTEw7CQkNCi0JfQ0KLQlyZXR1cm4gdGV4dHBhZ2VGaW5kOw0KLX0NCi1ETExFWFBPUlQgRlBERl9CT09MCVNURENBTEwgRlBERlRleHRfRmluZE5leHQoRlBERl9TQ0hIQU5ETEUgaGFuZGxlKQ0KLXsNCi0JaWYgKCFoYW5kbGUpIHJldHVybiBGQUxTRTsNCi0JSVBERl9UZXh0UGFnZUZpbmQqIHRleHRwYWdlRmluZD0oSVBERl9UZXh0UGFnZUZpbmQqKWhhbmRsZTsNCi0JcmV0dXJuCXRleHRwYWdlRmluZC0+RmluZE5leHQoKTsNCi19DQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZUZXh0X0ZpbmRQcmV2KEZQREZfU0NISEFORExFIGhhbmRsZSkNCi17DQotCWlmICghaGFuZGxlKSByZXR1cm4gRkFMU0U7DQotCUlQREZfVGV4dFBhZ2VGaW5kKiB0ZXh0cGFnZUZpbmQ9KElQREZfVGV4dFBhZ2VGaW5kKiloYW5kbGU7DQotCXJldHVybgl0ZXh0cGFnZUZpbmQtPkZpbmRQcmV2KCk7DQotfQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGVGV4dF9HZXRTY2hSZXN1bHRJbmRleChGUERGX1NDSEhBTkRMRSBoYW5kbGUpDQotew0KLQlpZiAoIWhhbmRsZSkgcmV0dXJuIDA7DQotCUlQREZfVGV4dFBhZ2VGaW5kKiB0ZXh0cGFnZUZpbmQ9KElQREZfVGV4dFBhZ2VGaW5kKiloYW5kbGU7DQotCXJldHVybiB0ZXh0cGFnZUZpbmQtPkdldEN1ck9yZGVyKCk7DQotfQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGVGV4dF9HZXRTY2hDb3VudChGUERGX1NDSEhBTkRMRSBoYW5kbGUpDQotew0KLQlpZiAoIWhhbmRsZSkgcmV0dXJuIDA7DQotCUlQREZfVGV4dFBhZ2VGaW5kKiB0ZXh0cGFnZUZpbmQ9KElQREZfVGV4dFBhZ2VGaW5kKiloYW5kbGU7DQotCXJldHVybiB0ZXh0cGFnZUZpbmQtPkdldE1hdGNoZWRDb3VudCgpOw0KLX0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0ZpbmRDbG9zZShGUERGX1NDSEhBTkRMRSBoYW5kbGUpDQotew0KLQlpZiAoIWhhbmRsZSkgcmV0dXJuOw0KLQlJUERGX1RleHRQYWdlRmluZCogdGV4dHBhZ2VGaW5kPShJUERGX1RleHRQYWdlRmluZCopaGFuZGxlOw0KLQlkZWxldGUJdGV4dHBhZ2VGaW5kOw0KLQloYW5kbGU9TlVMTDsNCi19DQotDQotLy93ZWIgbGluaw0KLURMTEVYUE9SVCBGUERGX1BBR0VMSU5LIFNURENBTEwgRlBERkxpbmtfTG9hZFdlYkxpbmtzKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlKQ0KLXsNCi0JaWYgKCF0ZXh0X3BhZ2UpIHJldHVybiBOVUxMOw0KLQlJUERGX0xpbmtFeHRyYWN0KiBwYWdlTGluaz1OVUxMOw0KLQl0cnkNCi0Jew0KLQkJcGFnZUxpbms9SVBERl9MaW5rRXh0cmFjdDo6Q3JlYXRlTGlua0V4dHJhY3QoKTsNCi0JCXBhZ2VMaW5rLT5FeHRyYWN0TGlua3MoKElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZSk7DQotCX0NCi0JY2F0Y2ggKC4uLikNCi0Jew0KLQkJaWYgKHBhZ2VMaW5rKQ0KLQkJCWRlbGV0ZSBwYWdlTGluazsNCi0JCXJldHVybiBOVUxMOw0KLQl9DQotCXJldHVybiBwYWdlTGluazsNCi19DQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZMaW5rX0NvdW50V2ViTGlua3MoRlBERl9QQUdFTElOSyBsaW5rX3BhZ2UpDQotew0KLQlpZiAoIWxpbmtfcGFnZSkgcmV0dXJuIDA7DQotCUlQREZfTGlua0V4dHJhY3QqIHBhZ2VMaW5rPShJUERGX0xpbmtFeHRyYWN0KilsaW5rX3BhZ2U7DQotCXJldHVybglwYWdlTGluay0+Q291bnRMaW5rcygpOw0KLX0NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERkxpbmtfR2V0VVJMKEZQREZfUEFHRUxJTksgbGlua19wYWdlLGludCBsaW5rX2luZGV4LCB1bnNpZ25lZCBzaG9ydCogYnVmZmVyLGludCBidWZsZW4pDQotew0KLQlpZiAoIWxpbmtfcGFnZSkgcmV0dXJuIDA7DQotCUlQREZfTGlua0V4dHJhY3QqIHBhZ2VMaW5rPShJUERGX0xpbmtFeHRyYWN0KilsaW5rX3BhZ2U7DQotCUNGWF9XaWRlU3RyaW5nIHVybD1wYWdlTGluay0+R2V0VVJMKGxpbmtfaW5kZXgpOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBjYlVURjE2VVJMID0gdXJsLlVURjE2TEVfRW5jb2RlKCk7DQotCWludCBsZW49IGNiVVRGMTZVUkwuR2V0TGVuZ3RoKCkvc2l6ZW9mKHVuc2lnbmVkIHNob3J0KTsNCi0JaWYgKGJ1ZmZlcj09TlVMTCB8fCBidWZsZW48PTApDQotCQlyZXR1cm4gbGVuOw0KLQlpbnQgc2l6ZT1sZW48YnVmbGVuID8gbGVuIDpidWZsZW47DQotCWlmIChzaXplPjApDQotCXsNCi0JCUZYU1lTX21lbWNweShidWZmZXIsY2JVVEYxNlVSTC5HZXRCdWZmZXIoc2l6ZSpzaXplb2YodW5zaWduZWQgc2hvcnQpKSxzaXplKnNpemVvZih1bnNpZ25lZCBzaG9ydCkpOw0KLQkJY2JVVEYxNlVSTC5SZWxlYXNlQnVmZmVyKHNpemUqc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSk7DQotCX0NCi0JcmV0dXJuIHNpemU7DQotfQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGTGlua19Db3VudFJlY3RzKEZQREZfUEFHRUxJTksgbGlua19wYWdlLGludCBsaW5rX2luZGV4KQ0KLXsNCi0JaWYgKCFsaW5rX3BhZ2UpIHJldHVybiAwOw0KLQlJUERGX0xpbmtFeHRyYWN0KiBwYWdlTGluaz0oSVBERl9MaW5rRXh0cmFjdCopbGlua19wYWdlOw0KLQlDRlhfUmVjdEFycmF5IHJlY3RBcnJheTsNCi0JcGFnZUxpbmstPkdldFJlY3RzKGxpbmtfaW5kZXgscmVjdEFycmF5KTsNCi0JcmV0dXJuIHJlY3RBcnJheS5HZXRTaXplKCk7DQotfQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkxpbmtfR2V0UmVjdChGUERGX1BBR0VMSU5LIGxpbmtfcGFnZSxpbnQgbGlua19pbmRleCwgIGludCByZWN0X2luZGV4LCBkb3VibGUqIGxlZnQsDQotCQkJCQkJCQkJCWRvdWJsZSogIHRvcCxkb3VibGUqICByaWdodCwgZG91YmxlKiAgYm90dG9tKQ0KLXsNCi0JaWYgKCFsaW5rX3BhZ2UpIHJldHVybjsNCi0JSVBERl9MaW5rRXh0cmFjdCogcGFnZUxpbms9KElQREZfTGlua0V4dHJhY3QqKWxpbmtfcGFnZTsNCi0JQ0ZYX1JlY3RBcnJheSByZWN0QXJyYXk7DQotCXBhZ2VMaW5rLT5HZXRSZWN0cyhsaW5rX2luZGV4LHJlY3RBcnJheSk7DQotCUNGWF9GbG9hdFJlY3QgcmVjdDsNCi0JcmVjdD1yZWN0QXJyYXkuR2V0QXQocmVjdF9pbmRleCk7DQotCSpsZWZ0PXJlY3QubGVmdDsNCi0JKnJpZ2h0PXJlY3QucmlnaHQ7DQotCSp0b3A9cmVjdC50b3A7DQotCSpib3R0b209cmVjdC5ib3R0b207DQotfQ0KLURMTEVYUE9SVCB2b2lkCVNURENBTEwJRlBERkxpbmtfQ2xvc2VXZWJMaW5rcyhGUERGX1BBR0VMSU5LIGxpbmtfcGFnZSkNCi17DQotCWlmICghbGlua19wYWdlKSByZXR1cm47DQotCUlQREZfTGlua0V4dHJhY3QqIHBhZ2VMaW5rPShJUERGX0xpbmtFeHRyYWN0KilsaW5rX3BhZ2U7DQotCWRlbGV0ZSBwYWdlTGluazsNCi0JcGFnZUxpbmsgPU5VTEw7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmdGV4dC5oIgorCisjaWZkZWYgX1dJTjMyCisjaW5jbHVkZSA8dGNoYXIuaD4KKyNlbmRpZgorCisgICAgICAgIC8vIGphYmRlbG1hbGVrOiBjb21tZW50ZWQgb3V0IHRvIGJ1aWxkIG9uIExpbnV4LiAgTm90IHVzZWQuCisJLy8gZXh0ZXJuIEhBTkRMRSBnX2hNb2R1bGU7CisKK0RMTEVYUE9SVCBGUERGX1RFWFRQQUdFIFNURENBTEwgRlBERlRleHRfTG9hZFBhZ2UoRlBERl9QQUdFIHBhZ2UpCit7CisJaWYgKCFwYWdlKSByZXR1cm4gTlVMTDsKKwlJUERGX1RleHRQYWdlKiB0ZXh0cGFnZT1OVUxMOworCXRyeQorCXsKKwkJQ1BERl9WaWV3ZXJQcmVmZXJlbmNlcyB2aWV3UmVmKCgoQ1BERl9QYWdlKilwYWdlKS0+bV9wRG9jdW1lbnQpOworCQl0ZXh0cGFnZT1JUERGX1RleHRQYWdlOjpDcmVhdGVUZXh0UGFnZSgoQ1BERl9QYWdlKilwYWdlLHZpZXdSZWYuSXNEaXJlY3Rpb25SMkwoKSk7CisJCXRleHRwYWdlLT5QYXJzZVRleHRQYWdlKCk7CisJfQorCWNhdGNoICguLi4pCisJeworCQlpZiAodGV4dHBhZ2UpCisJCQlkZWxldGUgdGV4dHBhZ2U7CisJCXJldHVybiBOVUxMOworCX0KKwlyZXR1cm4gdGV4dHBhZ2U7Cit9CitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0Nsb3NlUGFnZShGUERGX1RFWFRQQUdFIHRleHRfcGFnZSkKK3sKKwlpZiAodGV4dF9wYWdlKXsKKwkJSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsKKwkJZGVsZXRlIHRleHRwYWdlOworCQl0ZXh0X3BhZ2U9TlVMTDsKKwl9Cit9CitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfQ291bnRDaGFycyhGUERGX1RFWFRQQUdFIHRleHRfcGFnZSkKK3sKKwlpZiAoIXRleHRfcGFnZSkgcmV0dXJuCS0xOworCUlQREZfVGV4dFBhZ2UqIHRleHRwYWdlPShJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2U7CisJcmV0dXJuICB0ZXh0cGFnZS0+Q291bnRDaGFycygpOworfQorRExMRVhQT1JUIHVuc2lnbmVkIGludCBTVERDQUxMIEZQREZUZXh0X0dldFVuaWNvZGUoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCBpbmRleCkKK3sKKwlpZiAoIXRleHRfcGFnZSkgcmV0dXJuIC0xOworCUlQREZfVGV4dFBhZ2UqIHRleHRwYWdlPShJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2U7CisKKwlpZiAoaW5kZXg8MCB8fCBpbmRleD49dGV4dHBhZ2UtPkNvdW50Q2hhcnMoKSkgcmV0dXJuIDA7CisKKwlGUERGX0NIQVJfSU5GTwljaGFyaW5mbzsKKwl0ZXh0cGFnZS0+R2V0Q2hhckluZm8oaW5kZXgsY2hhcmluZm8pOworCXJldHVybiBjaGFyaW5mby5tX1VuaWNvZGU7Cit9CitETExFWFBPUlQgZG91YmxlIFNURENBTEwgRlBERlRleHRfR2V0Rm9udFNpemUoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsIGludCBpbmRleCkKK3sKKwlpZiAoIXRleHRfcGFnZSkgcmV0dXJuIDA7CisJSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsKKworCWlmIChpbmRleDwwIHx8IGluZGV4Pj10ZXh0cGFnZS0+Q291bnRDaGFycygpKSByZXR1cm4gMDsKKworCUZQREZfQ0hBUl9JTkZPCWNoYXJpbmZvOworCXRleHRwYWdlLT5HZXRDaGFySW5mbyhpbmRleCxjaGFyaW5mbyk7CisJcmV0dXJuIGNoYXJpbmZvLm1fRm9udFNpemU7Cit9CisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERlRleHRfR2V0Q2hhckJveChGUERGX1RFWFRQQUdFIHRleHRfcGFnZSwgaW50IGluZGV4LGRvdWJsZSogbGVmdCwKKwkJCQkJCQkJCQkJCQlkb3VibGUqIHJpZ2h0LCBkb3VibGUqIGJvdHRvbSwgZG91YmxlKiB0b3ApCit7CisJaWYgKCF0ZXh0X3BhZ2UpIHJldHVybjsKKwlJUERGX1RleHRQYWdlKiB0ZXh0cGFnZT0oSVBERl9UZXh0UGFnZSopdGV4dF9wYWdlOworCQorCWlmIChpbmRleDwwIHx8IGluZGV4Pj10ZXh0cGFnZS0+Q291bnRDaGFycygpKSByZXR1cm4gOworCUZQREZfQ0hBUl9JTkZPCWNoYXJpbmZvOworCXRleHRwYWdlLT5HZXRDaGFySW5mbyhpbmRleCxjaGFyaW5mbyk7CisJKmxlZnQ9Y2hhcmluZm8ubV9DaGFyQm94LmxlZnQ7CisJKnJpZ2h0PWNoYXJpbmZvLm1fQ2hhckJveC5yaWdodDsKKwkqYm90dG9tPWNoYXJpbmZvLm1fQ2hhckJveC5ib3R0b207CisJKnRvcD1jaGFyaW5mby5tX0NoYXJCb3gudG9wOworfQorCisvL3NlbGVjdAorRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0dldENoYXJJbmRleEF0UG9zKEZQREZfVEVYVFBBR0UgdGV4dF9wYWdlLGRvdWJsZSB4LGRvdWJsZSB5LGRvdWJsZSB4VG9yZWxhbmNlLGRvdWJsZSB5VG9yZWxhbmNlKQoreworCWlmICghdGV4dF9wYWdlKSByZXR1cm4gLTM7CisJSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsKKwlyZXR1cm4gdGV4dHBhZ2UtPkdldEluZGV4QXRQb3MoKEZYX0ZMT0FUKXgsKEZYX0ZMT0FUKXksKEZYX0ZMT0FUKXhUb3JlbGFuY2UsKEZYX0ZMT0FUKXlUb3JlbGFuY2UpOworfQorCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0VGV4dChGUERGX1RFWFRQQUdFIHRleHRfcGFnZSxpbnQgc3RhcnQsaW50IGNvdW50LHVuc2lnbmVkIHNob3J0KiByZXN1bHQpCit7CisJaWYgKCF0ZXh0X3BhZ2UpIHJldHVybiAwOworCUlQREZfVGV4dFBhZ2UqIHRleHRwYWdlPShJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2U7CisJCisJaWYgKHN0YXJ0Pj10ZXh0cGFnZS0+Q291bnRDaGFycygpKSByZXR1cm4gMDsKKworCUNGWF9XaWRlU3RyaW5nIHN0cj10ZXh0cGFnZS0+R2V0UGFnZVRleHQoc3RhcnQsY291bnQpOworCWlmKHN0ci5HZXRMZW5ndGgoKT5jb3VudCkKKwkJc3RyID0gc3RyLkxlZnQoY291bnQpOworCisJQ0ZYX0J5dGVTdHJpbmcgY2JVVEYxNnN0ciA9IHN0ci5VVEYxNkxFX0VuY29kZSgpOworCUZYU1lTX21lbWNweShyZXN1bHQsY2JVVEYxNnN0ci5HZXRCdWZmZXIoY2JVVEYxNnN0ci5HZXRMZW5ndGgoKSksY2JVVEYxNnN0ci5HZXRMZW5ndGgoKSk7CisJY2JVVEYxNnN0ci5SZWxlYXNlQnVmZmVyKGNiVVRGMTZzdHIuR2V0TGVuZ3RoKCkpOworCisJcmV0dXJuIGNiVVRGMTZzdHIuR2V0TGVuZ3RoKCkvc2l6ZW9mKHVuc2lnbmVkIHNob3J0KTsKK30KKworRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZUZXh0X0NvdW50UmVjdHMoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsaW50IHN0YXJ0LGludCBjb3VudCkKK3sKKwlpZiAoIXRleHRfcGFnZSkgcmV0dXJuIDA7CisJSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsKKwlyZXR1cm4JdGV4dHBhZ2UtPkNvdW50UmVjdHMoc3RhcnQsY291bnQpOworCit9CitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZUZXh0X0dldFJlY3QoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsaW50IHJlY3RfaW5kZXgsIGRvdWJsZSogbGVmdCxkb3VibGUqICB0b3AsCisJCQkJCQkJCQkJZG91YmxlKiAgcmlnaHQsIGRvdWJsZSogIGJvdHRvbSkKK3sKKwlpZiAoIXRleHRfcGFnZSkgcmV0dXJuOworCUlQREZfVGV4dFBhZ2UqIHRleHRwYWdlPShJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2U7CisJQ0ZYX0Zsb2F0UmVjdAlyZWN0OworCXRleHRwYWdlLT5HZXRSZWN0KHJlY3RfaW5kZXgscmVjdC5sZWZ0LHJlY3QudG9wLHJlY3QucmlnaHQscmVjdC5ib3R0b20pOworCSpsZWZ0PXJlY3QubGVmdDsKKwkqdG9wPXJlY3QudG9wOworCSpyaWdodD1yZWN0LnJpZ2h0OworCSpib3R0b209cmVjdC5ib3R0b207Cit9CisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGVGV4dF9HZXRCb3VuZGVkVGV4dChGUERGX1RFWFRQQUdFIHRleHRfcGFnZSxkb3VibGUgbGVmdCwgZG91YmxlIHRvcCwgCisJCQkJCQkJCQkJCSAgZG91YmxlIHJpZ2h0LCBkb3VibGUgYm90dG9tLHVuc2lnbmVkIHNob3J0KiBidWZmZXIsaW50IGJ1ZmxlbikKK3sKKwlpZiAoIXRleHRfcGFnZSkgcmV0dXJuIDA7CisJSVBERl9UZXh0UGFnZSogdGV4dHBhZ2U9KElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZTsKKwlDRlhfRmxvYXRSZWN0IHJlY3QoKEZYX0ZMT0FUKWxlZnQsKEZYX0ZMT0FUKWJvdHRvbSwoRlhfRkxPQVQpcmlnaHQsKEZYX0ZMT0FUKXRvcCk7CisJQ0ZYX1dpZGVTdHJpbmcgc3RyPXRleHRwYWdlLT5HZXRUZXh0QnlSZWN0KHJlY3QpOworCisJaWYgKGJ1Zmxlbjw9MCB8fCBidWZmZXI9PU5VTEwpCisJeworCQlyZXR1cm4gc3RyLkdldExlbmd0aCgpOworCX0KKworCUNGWF9CeXRlU3RyaW5nIGNiVVRGMTZTdHIgPSBzdHIuVVRGMTZMRV9FbmNvZGUoKTsKKwlpbnQgbGVuID0gY2JVVEYxNlN0ci5HZXRMZW5ndGgoKS9zaXplb2YodW5zaWduZWQgc2hvcnQpOworCWludCBzaXplID0gYnVmbGVuID4gbGVuID8gbGVuIDogYnVmbGVuOworCUZYU1lTX21lbWNweShidWZmZXIsY2JVVEYxNlN0ci5HZXRCdWZmZXIoc2l6ZSpzaXplb2YodW5zaWduZWQgc2hvcnQpKSxzaXplKnNpemVvZih1bnNpZ25lZCBzaG9ydCkpOworCWNiVVRGMTZTdHIuUmVsZWFzZUJ1ZmZlcihzaXplKnNpemVvZih1bnNpZ25lZCBzaG9ydCkpOworCisJcmV0dXJuIHNpemU7CisJCQorfQorCisvL1NlYXJjaAorLy8tMSBmb3IgZW5kCitETExFWFBPUlQgRlBERl9TQ0hIQU5ETEUgU1REQ0FMTCBGUERGVGV4dF9GaW5kU3RhcnQoRlBERl9URVhUUEFHRSB0ZXh0X3BhZ2UsRlBERl9XSURFU1RSSU5HIGZpbmR3aGF0LHVuc2lnbmVkIGxvbmcgZmxhZ3MsaW50IHN0YXJ0X2luZGV4KQoreworCWlmICghdGV4dF9wYWdlKSByZXR1cm4gTlVMTDsKKwlJUERGX1RleHRQYWdlRmluZCogdGV4dHBhZ2VGaW5kPU5VTEw7CisJdHJ5CisJeworCQl0ZXh0cGFnZUZpbmQ9SVBERl9UZXh0UGFnZUZpbmQ6OkNyZWF0ZVBhZ2VGaW5kKChJUERGX1RleHRQYWdlKil0ZXh0X3BhZ2UpOworCQl0ZXh0cGFnZUZpbmQtPkZpbmRGaXJzdChDRlhfV2lkZVN0cmluZzo6RnJvbVVURjE2TEUoZmluZHdoYXQpLGZsYWdzLHN0YXJ0X2luZGV4KTsKKwl9CisJY2F0Y2ggKC4uLikKKwl7CisJCWlmICh0ZXh0cGFnZUZpbmQpCisJCQlkZWxldGUgdGV4dHBhZ2VGaW5kOworCQlyZXR1cm4gTlVMTDsJCQorCX0KKwlyZXR1cm4gdGV4dHBhZ2VGaW5kOworfQorRExMRVhQT1JUIEZQREZfQk9PTAlTVERDQUxMIEZQREZUZXh0X0ZpbmROZXh0KEZQREZfU0NISEFORExFIGhhbmRsZSkKK3sKKwlpZiAoIWhhbmRsZSkgcmV0dXJuIEZBTFNFOworCUlQREZfVGV4dFBhZ2VGaW5kKiB0ZXh0cGFnZUZpbmQ9KElQREZfVGV4dFBhZ2VGaW5kKiloYW5kbGU7CisJcmV0dXJuCXRleHRwYWdlRmluZC0+RmluZE5leHQoKTsKK30KK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGVGV4dF9GaW5kUHJldihGUERGX1NDSEhBTkRMRSBoYW5kbGUpCit7CisJaWYgKCFoYW5kbGUpIHJldHVybiBGQUxTRTsKKwlJUERGX1RleHRQYWdlRmluZCogdGV4dHBhZ2VGaW5kPShJUERGX1RleHRQYWdlRmluZCopaGFuZGxlOworCXJldHVybgl0ZXh0cGFnZUZpbmQtPkZpbmRQcmV2KCk7Cit9CitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0U2NoUmVzdWx0SW5kZXgoRlBERl9TQ0hIQU5ETEUgaGFuZGxlKQoreworCWlmICghaGFuZGxlKSByZXR1cm4gMDsKKwlJUERGX1RleHRQYWdlRmluZCogdGV4dHBhZ2VGaW5kPShJUERGX1RleHRQYWdlRmluZCopaGFuZGxlOworCXJldHVybiB0ZXh0cGFnZUZpbmQtPkdldEN1ck9yZGVyKCk7Cit9CitETExFWFBPUlQgaW50IFNURENBTEwgRlBERlRleHRfR2V0U2NoQ291bnQoRlBERl9TQ0hIQU5ETEUgaGFuZGxlKQoreworCWlmICghaGFuZGxlKSByZXR1cm4gMDsKKwlJUERGX1RleHRQYWdlRmluZCogdGV4dHBhZ2VGaW5kPShJUERGX1RleHRQYWdlRmluZCopaGFuZGxlOworCXJldHVybiB0ZXh0cGFnZUZpbmQtPkdldE1hdGNoZWRDb3VudCgpOworfQorRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGVGV4dF9GaW5kQ2xvc2UoRlBERl9TQ0hIQU5ETEUgaGFuZGxlKQoreworCWlmICghaGFuZGxlKSByZXR1cm47CisJSVBERl9UZXh0UGFnZUZpbmQqIHRleHRwYWdlRmluZD0oSVBERl9UZXh0UGFnZUZpbmQqKWhhbmRsZTsKKwlkZWxldGUJdGV4dHBhZ2VGaW5kOworCWhhbmRsZT1OVUxMOworfQorCisvL3dlYiBsaW5rCitETExFWFBPUlQgRlBERl9QQUdFTElOSyBTVERDQUxMIEZQREZMaW5rX0xvYWRXZWJMaW5rcyhGUERGX1RFWFRQQUdFIHRleHRfcGFnZSkKK3sKKwlpZiAoIXRleHRfcGFnZSkgcmV0dXJuIE5VTEw7CisJSVBERl9MaW5rRXh0cmFjdCogcGFnZUxpbms9TlVMTDsKKwl0cnkKKwl7CisJCXBhZ2VMaW5rPUlQREZfTGlua0V4dHJhY3Q6OkNyZWF0ZUxpbmtFeHRyYWN0KCk7CisJCXBhZ2VMaW5rLT5FeHRyYWN0TGlua3MoKElQREZfVGV4dFBhZ2UqKXRleHRfcGFnZSk7CisJfQorCWNhdGNoICguLi4pCisJeworCQlpZiAocGFnZUxpbmspCisJCQlkZWxldGUgcGFnZUxpbms7CisJCXJldHVybiBOVUxMOworCX0KKwlyZXR1cm4gcGFnZUxpbms7Cit9CitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkxpbmtfQ291bnRXZWJMaW5rcyhGUERGX1BBR0VMSU5LIGxpbmtfcGFnZSkKK3sKKwlpZiAoIWxpbmtfcGFnZSkgcmV0dXJuIDA7CisJSVBERl9MaW5rRXh0cmFjdCogcGFnZUxpbms9KElQREZfTGlua0V4dHJhY3QqKWxpbmtfcGFnZTsKKwlyZXR1cm4JcGFnZUxpbmstPkNvdW50TGlua3MoKTsKK30KK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGTGlua19HZXRVUkwoRlBERl9QQUdFTElOSyBsaW5rX3BhZ2UsaW50IGxpbmtfaW5kZXgsIHVuc2lnbmVkIHNob3J0KiBidWZmZXIsaW50IGJ1ZmxlbikKK3sKKwlpZiAoIWxpbmtfcGFnZSkgcmV0dXJuIDA7CisJSVBERl9MaW5rRXh0cmFjdCogcGFnZUxpbms9KElQREZfTGlua0V4dHJhY3QqKWxpbmtfcGFnZTsKKwlDRlhfV2lkZVN0cmluZyB1cmw9cGFnZUxpbmstPkdldFVSTChsaW5rX2luZGV4KTsKKworCUNGWF9CeXRlU3RyaW5nIGNiVVRGMTZVUkwgPSB1cmwuVVRGMTZMRV9FbmNvZGUoKTsKKwlpbnQgbGVuPSBjYlVURjE2VVJMLkdldExlbmd0aCgpL3NpemVvZih1bnNpZ25lZCBzaG9ydCk7CisJaWYgKGJ1ZmZlcj09TlVMTCB8fCBidWZsZW48PTApCisJCXJldHVybiBsZW47CisJaW50IHNpemU9bGVuPGJ1ZmxlbiA/IGxlbiA6YnVmbGVuOworCWlmIChzaXplPjApCisJeworCQlGWFNZU19tZW1jcHkoYnVmZmVyLGNiVVRGMTZVUkwuR2V0QnVmZmVyKHNpemUqc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSksc2l6ZSpzaXplb2YodW5zaWduZWQgc2hvcnQpKTsKKwkJY2JVVEYxNlVSTC5SZWxlYXNlQnVmZmVyKHNpemUqc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSk7CisJfQorCXJldHVybiBzaXplOworfQorRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZMaW5rX0NvdW50UmVjdHMoRlBERl9QQUdFTElOSyBsaW5rX3BhZ2UsaW50IGxpbmtfaW5kZXgpCit7CisJaWYgKCFsaW5rX3BhZ2UpIHJldHVybiAwOworCUlQREZfTGlua0V4dHJhY3QqIHBhZ2VMaW5rPShJUERGX0xpbmtFeHRyYWN0KilsaW5rX3BhZ2U7CisJQ0ZYX1JlY3RBcnJheSByZWN0QXJyYXk7CisJcGFnZUxpbmstPkdldFJlY3RzKGxpbmtfaW5kZXgscmVjdEFycmF5KTsKKwlyZXR1cm4gcmVjdEFycmF5LkdldFNpemUoKTsKK30KK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkxpbmtfR2V0UmVjdChGUERGX1BBR0VMSU5LIGxpbmtfcGFnZSxpbnQgbGlua19pbmRleCwgIGludCByZWN0X2luZGV4LCBkb3VibGUqIGxlZnQsCisJCQkJCQkJCQkJZG91YmxlKiAgdG9wLGRvdWJsZSogIHJpZ2h0LCBkb3VibGUqICBib3R0b20pCit7CisJaWYgKCFsaW5rX3BhZ2UpIHJldHVybjsKKwlJUERGX0xpbmtFeHRyYWN0KiBwYWdlTGluaz0oSVBERl9MaW5rRXh0cmFjdCopbGlua19wYWdlOworCUNGWF9SZWN0QXJyYXkgcmVjdEFycmF5OworCXBhZ2VMaW5rLT5HZXRSZWN0cyhsaW5rX2luZGV4LHJlY3RBcnJheSk7CisJQ0ZYX0Zsb2F0UmVjdCByZWN0OworCXJlY3Q9cmVjdEFycmF5LkdldEF0KHJlY3RfaW5kZXgpOworCSpsZWZ0PXJlY3QubGVmdDsKKwkqcmlnaHQ9cmVjdC5yaWdodDsKKwkqdG9wPXJlY3QudG9wOworCSpib3R0b209cmVjdC5ib3R0b207Cit9CitETExFWFBPUlQgdm9pZAlTVERDQUxMCUZQREZMaW5rX0Nsb3NlV2ViTGlua3MoRlBERl9QQUdFTElOSyBsaW5rX3BhZ2UpCit7CisJaWYgKCFsaW5rX3BhZ2UpIHJldHVybjsKKwlJUERGX0xpbmtFeHRyYWN0KiBwYWdlTGluaz0oSVBERl9MaW5rRXh0cmFjdCopbGlua19wYWdlOworCWRlbGV0ZSBwYWdlTGluazsKKwlwYWdlTGluayA9TlVMTDsKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnBkZnZpZXcuY3BwIGIvZnBkZnNkay9zcmMvZnBkZnZpZXcuY3BwCmluZGV4IGU3MmU1YWIuLmE1YmE3OTYgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZwZGZ2aWV3LmNwcAorKysgYi9mcGRmc2RrL3NyYy9mcGRmdmlldy5jcHAKQEAgLTEsODc5ICsxLDg3OSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmdmlldy5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfcmVuZGVyY29udGV4dC5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZfcHJvZ3Jlc3NpdmUuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmX2V4dC5oIg0KLQ0KLQ0KLUNQREZfQ3VzdG9tQWNjZXNzOjpDUERGX0N1c3RvbUFjY2VzcyhGUERGX0ZJTEVBQ0NFU1MqIHBGaWxlQWNjZXNzKQ0KLXsNCi0JbV9GaWxlQWNjZXNzID0gKnBGaWxlQWNjZXNzOw0KLQltX0J1ZmZlck9mZnNldCA9IChGWF9EV09SRCktMTsNCi19DQotDQotRlhfQk9PTCBDUERGX0N1c3RvbUFjY2Vzczo6R2V0Qnl0ZShGWF9EV09SRCBwb3MsIEZYX0JZVEUmIGNoKQ0KLXsNCi0JaWYgKHBvcyA+PSBtX0ZpbGVBY2Nlc3MubV9GaWxlTGVuKSByZXR1cm4gRkFMU0U7DQotCWlmIChtX0J1ZmZlck9mZnNldCA9PSAoRlhfRFdPUkQpLTEgfHwgcG9zIDwgbV9CdWZmZXJPZmZzZXQgfHwgcG9zID49IG1fQnVmZmVyT2Zmc2V0ICsgNTEyKSB7DQotCQkvLyBOZWVkIHRvIHJlYWQgZnJvbSBmaWxlIGFjY2Vzcw0KLQkJbV9CdWZmZXJPZmZzZXQgPSBwb3M7DQotCQlpbnQgc2l6ZSA9IDUxMjsNCi0JCWlmIChwb3MgKyA1MTIgPiBtX0ZpbGVBY2Nlc3MubV9GaWxlTGVuKQ0KLQkJCXNpemUgPSBtX0ZpbGVBY2Nlc3MubV9GaWxlTGVuIC0gcG9zOw0KLQkJaWYgKCFtX0ZpbGVBY2Nlc3MubV9HZXRCbG9jayhtX0ZpbGVBY2Nlc3MubV9QYXJhbSwgbV9CdWZmZXJPZmZzZXQsIG1fQnVmZmVyLCBzaXplKSkNCi0JCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0JY2ggPSBtX0J1ZmZlcltwb3MgLSBtX0J1ZmZlck9mZnNldF07DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQREZfQ3VzdG9tQWNjZXNzOjpHZXRCbG9jayhGWF9EV09SRCBwb3MsIEZYX0xQQllURSBwQnVmLCBGWF9EV09SRCBzaXplKQ0KLXsNCi0JaWYgKHBvcyArIHNpemUgPiBtX0ZpbGVBY2Nlc3MubV9GaWxlTGVuKSByZXR1cm4gRkFMU0U7DQotCXJldHVybiBtX0ZpbGVBY2Nlc3MubV9HZXRCbG9jayhtX0ZpbGVBY2Nlc3MubV9QYXJhbSwgcG9zLCBwQnVmLCBzaXplKTsNCi19DQotDQotRlhfQk9PTCBDUERGX0N1c3RvbUFjY2Vzczo6UmVhZEJsb2NrKHZvaWQqIGJ1ZmZlciwgRlhfRklMRVNJWkUgb2Zmc2V0LCBzaXplX3Qgc2l6ZSkNCi17DQotCS8vCW1fRmlsZUFjY2VzcyA9ICpwRmlsZUFjY2VzczsNCi0JLy8JbV9CdWZmZXJPZmZzZXQgPSAoRlhfRFdPUkQpLTE7DQotCWlmIChvZmZzZXQgKyBzaXplID4gbV9GaWxlQWNjZXNzLm1fRmlsZUxlbikgcmV0dXJuIEZBTFNFOw0KLQlyZXR1cm4gbV9GaWxlQWNjZXNzLm1fR2V0QmxvY2sobV9GaWxlQWNjZXNzLm1fUGFyYW0sIG9mZnNldCwoRlhfTFBCWVRFKSBidWZmZXIsIHNpemUpOw0KLQ0KLQkvLwlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLS8vMCBiaXQ6IEZQREZfUE9MSUNZX01BQ0hJTkVUSU1FX0FDQ0VTUw0KLXN0YXRpYyBGWF9EV09SRCBmb3hpdF9zYW5kYm94X3BvbGljeSA9IDB4RkZGRkZGRkY7DQotDQotdm9pZCBGU0RLX1NldFNhbmRCb3hQb2xpY3koRlBERl9EV09SRCBwb2xpY3ksIEZQREZfQk9PTCBlbmFibGUpDQotew0KLQlzd2l0Y2gocG9saWN5KQ0KLQl7DQotCWNhc2UgRlBERl9QT0xJQ1lfTUFDSElORVRJTUVfQUNDRVNTOg0KLQkJew0KLQkJCWlmKGVuYWJsZSkNCi0JCQkJZm94aXRfc2FuZGJveF9wb2xpY3kgfD0gMHgwMTsNCi0JCQllbHNlDQotCQkJCWZveGl0X3NhbmRib3hfcG9saWN5ICY9IDB4RkZGRkZGRkU7DQotCQl9DQotCQlicmVhazsNCi0JZGVmYXVsdDoNCi0JCWJyZWFrOw0KLQl9DQotfQ0KLQ0KLUZQREZfQk9PTCBGU0RLX0lzU2FuZEJveFBvbGljeUVuYWJsZWQoRlBERl9EV09SRCBwb2xpY3kpDQotew0KLQlzd2l0Y2gocG9saWN5KQ0KLQl7DQotCWNhc2UgRlBERl9QT0xJQ1lfTUFDSElORVRJTUVfQUNDRVNTOg0KLQkJew0KLQkJCWlmKGZveGl0X3NhbmRib3hfcG9saWN5JjB4MDEpDQotCQkJCXJldHVybiBUUlVFOw0KLQkJCWVsc2UNCi0JCQkJcmV0dXJuIEZBTFNFOw0KLQkJfQ0KLQkJYnJlYWs7DQotCWRlZmF1bHQ6DQotCQlicmVhazsNCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLQ0KLSNpZm5kZWYgX1QNCi0jZGVmaW5lIF9UKHgpIHgNCi0jZW5kaWYNCi0NCi0jaWZkZWYgQVBJNQ0KLQlDUERGX01vZHVsZU1ncioJZ19wTW9kdWxlTWdyID0gTlVMTDsNCi0jZWxzZQ0KLQlDQ29kZWNfTW9kdWxlTWdyKglnX3BDb2RlY01vZHVsZSA9IE5VTEw7DQotI2lmZGVmIF9GWFNES19PUEVOU09VUkNFXw0KLQlGWE1FTV9Gb3hpdE1nciogZ19wRm94aXRNZ3IgPSBOVUxMOw0KLSNlbmRpZg0KLSNlbmRpZg0KLQ0KLS8vZXh0ZXJuIENQREZTREtfRm9ybUZpbGxBcHAqIGdfcEZvcm1GaWxsQXBwOw0KLQ0KLSNpZiBfRlhfT1NfID09IF9GWF9MSU5VWF9FTUJFRERFRF8NCi1jbGFzcyBDRm9udE1hcHBlciA6IHB1YmxpYyBJUERGX0ZvbnRNYXBwZXINCi17DQotcHVibGljOg0KLQlDRm9udE1hcHBlcigpOw0KLQl2aXJ0dWFsIH5DRm9udE1hcHBlcigpOw0KLQ0KLQl2aXJ0dWFsIEZUX0ZhY2UgRmluZFN1YnN0Rm9udCgNCi0JCQkJCQkJQ1BERl9Eb2N1bWVudCogcERvYywJCQkJLy8gW0lOXSBUaGUgUERGIGRvY3VtZW50DQotCQkJCQkJCWNvbnN0IENGWF9CeXRlU3RyaW5nJiBmYWNlX25hbWUsCS8vIFtJTl0gT3JpZ2luYWwgbmFtZQ0KLQkJCQkJCQlGWF9CT09MIGJUcnVlVHlwZSwJCQkJCS8vIFtJTl0gVHJ1ZVR5cGUgb3IgVHlwZTENCi0JCQkJCQkJRlhfRFdPUkQgZmxhZ3MsCQkJCQkJLy8gW0lOXSBQREYgZm9udCBmbGFncyAoc2VlIFBERiBSZWZlcmVuY2Ugc2VjdGlvbiA1LjcuMSkNCi0JCQkJCQkJaW50IGZvbnRfd2VpZ2h0LAkJCQkJLy8gW0lOXSBvcmlnaW5hbCBmb250IHdlaWdodC4gMCBmb3Igbm90IHNwZWNpZmllZA0KLQkJCQkJCQlpbnQgQ2hhcnNldENQLAkJCQkJCS8vIFtJTl0gY29kZSBwYWdlIGZvciBjaGFyc2V0IChzZWUgV2luMzIgR2V0QUNQKCkpDQotCQkJCQkJCUZYX0JPT0wgYlZlcnRpY2FsLA0KLQkJCQkJCQlDUERGX1N1YnN0Rm9udCogcFN1YnN0Rm9udAkJCS8vIFtPVVRdIFN1YnN0IGZvbnQgZGF0YQ0KLQkJCQkJCSk7DQotDQotCUZUX0ZhY2UgbV9TeXNGYWNlOw0KLX07DQotDQotQ0ZvbnRNYXBwZXIqIGdfcEZvbnRNYXBwZXIgPSBOVUxMOw0KLSNlbmRpZgkJLy8gI2lmIF9GWF9PU18gPT0gX0ZYX0xJTlVYX0VNQkVEREVEXw0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9Jbml0TGlicmFyeShGWF9MUFZPSUQgaEluc3RhbmNlKQ0KLXsNCi0jaWZkZWYgQVBJNQ0KLQlDUERGX01vZHVsZU1ncjo6Q3JlYXRlKCk7DQotCWdfcE1vZHVsZU1nciA9IENQREZfTW9kdWxlTWdyOjpHZXQoKTsNCi0JICNpZiBfRlhfT1NfID09IF9GWF9XSU4zMl9NT0JJTEVfIHx8IF9GWF9PU18gPT0gX0ZYX0xJTlVYX0VNQkVEREVEXw0KLQkgCWdfcE1vZHVsZU1nci0+SW5pdEVtYmVkZGVkKCk7DQotCSAjaWZkZWYgX0dCMV9DTUFQU18NCi0JIAlnX3BNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZEdCMUNNYXBzKCk7DQotCSAjZW5kaWYNCi0JICNpZmRlZiBfR0IxX0NNQVBTXzRfDQotCSAJZ19wTW9kdWxlTWdyLT5Mb2FkRW1iZWRkZWRHQjFDTWFwc180KCk7DQotCSAjZW5kaWYNCi0JICNpZmRlZiBfQ05TMV9DTUFQU18NCi0JIAlnX3BNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZENOUzFDTWFwcygpOw0KLQkgI2VuZGlmDQotCSAjaWZkZWYgX0pBUEFOMV9DTUFQU18NCi0JIAlnX3BNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZEphcGFuMUNNYXBzKCk7DQotCSAjZW5kaWYNCi0JICNpZmRlZiBfSkFQQU4xX0NNQVBTXzZfDQotCSAJZ19wTW9kdWxlTWdyLT5Mb2FkRW1iZWRkZWRKYXBhbjFDTWFwc182KCk7DQotCSAjZW5kaWYNCi0JICNpZmRlZiBfS09SRUExX0NNQVBTXw0KLQkgCWdfcE1vZHVsZU1nci0+TG9hZEVtYmVkZGVkS29yZWExQ01hcHMoKTsNCi0JICNlbmRpZg0KLQkgI2lmZGVmIF9KUFhfREVDT0RFUl8NCi0JIAlnX3BNb2R1bGVNZ3ItPkluaXRKcHhNb2R1bGUoKTsNCi0JIAlnX3BNb2R1bGVNZ3ItPkluaXRKYmlnMk1vZHVsZSgpOw0KLQkgLy8JZ19wTW9kdWxlTWdyLT5Jbml0SWNjTW9kdWxlKCk7DQotCSAjZW5kaWYNCi0JICNlbHNlDQotCSAJZ19wTW9kdWxlTWdyLT5Jbml0RGVza3RvcCgpOw0KLQkgI2VuZGlmDQotI2Vsc2UNCi0jaWZkZWYgX0ZYU0RLX09QRU5TT1VSQ0VfDQotCWdfcEZveGl0TWdyID0gRlhNRU1fQ3JlYXRlTWVtb3J5TWdyKDEwMjQgKiAxMDI0ICogMzIsIFRSVUUpOw0KLSNlbmRpZg0KLQlnX3BDb2RlY01vZHVsZSA9IENDb2RlY19Nb2R1bGVNZ3I6OkNyZWF0ZSgpOw0KLQkNCi0JQ0ZYX0dFTW9kdWxlOjpDcmVhdGUoKTsNCi0JQ0ZYX0dFTW9kdWxlOjpHZXQoKS0+U2V0Q29kZWNNb2R1bGUoZ19wQ29kZWNNb2R1bGUpOw0KLQkNCi0JQ1BERl9Nb2R1bGVNZ3I6OkNyZWF0ZSgpOw0KLQlDUERGX01vZHVsZU1ncjo6R2V0KCktPlNldENvZGVjTW9kdWxlKGdfcENvZGVjTW9kdWxlKTsNCi0JQ1BERl9Nb2R1bGVNZ3I6OkdldCgpLT5Jbml0UGFnZU1vZHVsZSgpOw0KLQlDUERGX01vZHVsZU1ncjo6R2V0KCktPkluaXRSZW5kZXJNb2R1bGUoKTsNCi0jaWZkZWYgRk9YSVRfQ0hST01FX0JVSUxEDQotCUNQREZfTW9kdWxlTWdyICogcE1vZHVsZU1nciA9IENQREZfTW9kdWxlTWdyOjpHZXQoKTsNCi0JaWYgKCBwTW9kdWxlTWdyICkNCi0Jew0KLQkJcE1vZHVsZU1nci0+TG9hZEVtYmVkZGVkR0IxQ01hcHMoKTsNCi0JCXBNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZEphcGFuMUNNYXBzKCk7DQotCQlwTW9kdWxlTWdyLT5Mb2FkRW1iZWRkZWRDTlMxQ01hcHMoKTsNCi0JCXBNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZEtvcmVhMUNNYXBzKCk7DQotCX0NCi0jZW5kaWYgDQotI2VuZGlmDQotDQotI2lmZGVmIF9XSU4zMg0KLQkvLyBHZXQgbW9kdWxlIHBhdGgNCi0JVENIQVIgYXBwX3BhdGhbTUFYX1BBVEhdOw0KLQk6OkdldE1vZHVsZUZpbGVOYW1lKChISU5TVEFOQ0UpaEluc3RhbmNlLCBhcHBfcGF0aCwgTUFYX1BBVEgpOw0KLQlzaXplX3QgbGVuID0gX3Rjc2xlbihhcHBfcGF0aCk7DQotCWZvciAoc2l6ZV90IGkgPSBsZW47IGkgPj0gMDsgaSAtLSkNCi0JCWlmIChhcHBfcGF0aFtpXSA9PSAnXFwnKSB7DQotCQkJYXBwX3BhdGhbaV0gPSAwOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQkJDQotI2lmZGVmIF9VTklDT0RFDQotCQkjaWZuZGVmIF9GWFNES19PUEVOU09VUkNFXw0KLQkJQ1BERl9Nb2R1bGVNZ3I6OkdldCgpLT5TZXRNb2R1bGVQYXRoKE5VTEwsIENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShhcHBfcGF0aCkpOw0KLQkJI2VuZGlmDQotI2Vsc2UNCi0jaWZuZGVmIF9GWFNES19PUEVOU09VUkNFXw0KLQkJQ1BERl9Nb2R1bGVNZ3I6OkdldCgpLT5TZXRNb2R1bGVQYXRoKE5VTEwsIGFwcF9wYXRoKTsNCi0jZW5kaWYNCi0jZW5kaWYNCi0jZW5kaWYNCi19DQotDQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX0Rlc3Ryb3lMaWJyYXJ5KCkNCi17DQotDQotI2lmIF9GWF9PU18gPT0gX0ZYX0xJTlVYX0VNQkVEREVEXw0KLQlpZiAoZ19wRm9udE1hcHBlcikgZGVsZXRlIGdfcEZvbnRNYXBwZXI7DQotI2VuZGlmDQotI2lmZGVmIEFQSTUNCi0JZ19wTW9kdWxlTWdyLT5EZXN0cm95KCk7DQotI2Vsc2UNCi0JQ1BERl9Nb2R1bGVNZ3I6OkRlc3Ryb3koKTsNCi0JQ0ZYX0dFTW9kdWxlOjpEZXN0cm95KCk7DQotCWdfcENvZGVjTW9kdWxlLT5EZXN0cm95KCk7DQotI2VuZGlmDQotI2lmbmRlZiBfRlhTREtfT1BFTlNPVVJDRV8NCi0JRlhNRU1fQ29sbGVjdEFsbChGWE1FTV9HZXREZWZhdWx0TWdyKCkpOw0KLSNlbHNlDQotCUZYTUVNX0Rlc3Ryb3lGb3hpdE1ncihnX3BGb3hpdE1ncik7DQotI2VuZGlmDQotfQ0KLQ0KLSNpZm5kZWYgX1dJTjMyDQotaW50IGdfTGFzdEVycm9yOw0KLXZvaWQgU2V0TGFzdEVycm9yKGludCBlcnIpDQotew0KLQlnX0xhc3RFcnJvciA9IGVycjsNCi19DQotDQotaW50IEdldExhc3RFcnJvcigpDQotew0KLQlyZXR1cm4gZ19MYXN0RXJyb3I7DQotfQ0KLSNlbmRpZg0KLQ0KLXZvaWQgUHJvY2Vzc1BhcnNlRXJyb3IoRlhfRFdPUkQgZXJyX2NvZGUpDQotew0KLQkvLyBUcmFuc2xhdGUgRlBERkFQSSBlcnJvciBjb2RlIHRvIEZQREZWSUVXIGVycm9yIGNvZGUNCi0Jc3dpdGNoIChlcnJfY29kZSkgew0KLQkJY2FzZSBQREZQQVJTRV9FUlJPUl9GSUxFOg0KLQkJCWVycl9jb2RlID0gRlBERl9FUlJfRklMRTsNCi0JCQlicmVhazsNCi0JCWNhc2UgUERGUEFSU0VfRVJST1JfRk9STUFUOg0KLQkJCWVycl9jb2RlID0gRlBERl9FUlJfRk9STUFUOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQREZQQVJTRV9FUlJPUl9QQVNTV09SRDoNCi0JCQllcnJfY29kZSA9IEZQREZfRVJSX1BBU1NXT1JEOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQREZQQVJTRV9FUlJPUl9IQU5ETEVSOg0KLQkJCWVycl9jb2RlID0gRlBERl9FUlJfU0VDVVJJVFk7DQotCQkJYnJlYWs7DQotCX0NCi0JU2V0TGFzdEVycm9yKGVycl9jb2RlKTsNCi19DQotDQotRExMRVhQT1JUIHZvaWQJU1REQ0FMTCBGUERGX1NldFNhbmRCb3hQb2xpY3koRlBERl9EV09SRCBwb2xpY3ksIEZQREZfQk9PTCBlbmFibGUpDQotew0KLQlyZXR1cm4gRlNES19TZXRTYW5kQm94UG9saWN5KHBvbGljeSwgZW5hYmxlKTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfRE9DVU1FTlQgU1REQ0FMTCBGUERGX0xvYWREb2N1bWVudChGUERGX1NUUklORyBmaWxlX3BhdGgsIEZQREZfQllURVNUUklORyBwYXNzd29yZCkNCi17DQotCUNQREZfUGFyc2VyKiBwUGFyc2VyID0gRlhfTkVXIENQREZfUGFyc2VyOw0KLQlwUGFyc2VyLT5TZXRQYXNzd29yZChwYXNzd29yZCk7DQotCXRyeSB7DQotCQlGWF9EV09SRCBlcnJfY29kZSA9IHBQYXJzZXItPlN0YXJ0UGFyc2UoKEZYX0xQQ1NUUilmaWxlX3BhdGgpOw0KLQkJaWYgKGVycl9jb2RlKSB7DQotCQkJZGVsZXRlIHBQYXJzZXI7DQotCQkJUHJvY2Vzc1BhcnNlRXJyb3IoZXJyX2NvZGUpOw0KLQkJCXJldHVybiBOVUxMOw0KLQkJfQ0KLQl9DQotCWNhdGNoICguLi4pIHsNCi0JCWRlbGV0ZSBwUGFyc2VyOw0KLQkJU2V0TGFzdEVycm9yKEZQREZfRVJSX1VOS05PV04pOw0KLQkJcmV0dXJuIE5VTEw7DQotCX0NCi0JcmV0dXJuIHBQYXJzZXItPkdldERvY3VtZW50KCk7DQotfQ0KLQ0KLWV4dGVybiB2b2lkIENoZWNrVW5TdXBwb3J0RXJyb3IoQ1BERl9Eb2N1bWVudCAqIHBEb2MsIEZYX0RXT1JEIGVycl9jb2RlKTsNCi0NCi1jbGFzcyBDTWVtRmlsZTogcHVibGljIElGWF9GaWxlUmVhZCwgcHVibGljIENGWF9PYmplY3QNCi17DQotcHVibGljOg0KLQlDTWVtRmlsZShGWF9CWVRFKiBwQnVmLCBGWF9GSUxFU0laRSBzaXplKTptX3BCdWYocEJ1ZiksbV9zaXplKHNpemUpIHt9DQotDQotCXZpcnR1YWwgdm9pZAkJCVJlbGVhc2UoKSB7ZGVsZXRlIHRoaXM7fQ0KLQl2aXJ0dWFsIEZYX0ZJTEVTSVpFCQlHZXRTaXplKCkge3JldHVybiBtX3NpemU7fQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQlSZWFkQmxvY2sodm9pZCogYnVmZmVyLCBGWF9GSUxFU0laRSBvZmZzZXQsIHNpemVfdCBzaXplKSANCi0Jew0KLQkJaWYob2Zmc2V0K3NpemUgPiAoRlhfRFdPUkQpbV9zaXplKSByZXR1cm4gRkFMU0U7DQotCQlGWFNZU19tZW1jcHkoYnVmZmVyLCBtX3BCdWYrb2Zmc2V0LCBzaXplKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotcHJpdmF0ZToNCi0JRlhfQllURSogbV9wQnVmOw0KLQlGWF9GSUxFU0laRSBtX3NpemU7DQotfTsNCi1ETExFWFBPUlQgRlBERl9ET0NVTUVOVCBTVERDQUxMIEZQREZfTG9hZE1lbURvY3VtZW50KGNvbnN0IHZvaWQqIGRhdGFfYnVmLCBpbnQgc2l6ZSwgRlBERl9CWVRFU1RSSU5HIHBhc3N3b3JkKQ0KLXsNCi0JQ1BERl9QYXJzZXIqIHBQYXJzZXIgPSBGWF9ORVcgQ1BERl9QYXJzZXI7DQotCXBQYXJzZXItPlNldFBhc3N3b3JkKHBhc3N3b3JkKTsNCi0JdHJ5IHsNCi0JCUNNZW1GaWxlKiBwTWVtRmlsZSA9IEZYX05FVyBDTWVtRmlsZSgoRlhfQllURSopZGF0YV9idWYsIHNpemUpOw0KLQkJRlhfRFdPUkQgZXJyX2NvZGUgPSBwUGFyc2VyLT5TdGFydFBhcnNlKHBNZW1GaWxlKTsNCi0JCWlmIChlcnJfY29kZSkgew0KLQkJCWRlbGV0ZSBwUGFyc2VyOw0KLQkJCVByb2Nlc3NQYXJzZUVycm9yKGVycl9jb2RlKTsNCi0JCQlyZXR1cm4gTlVMTDsNCi0JCX0NCi0JCUNQREZfRG9jdW1lbnQgKiBwRG9jID0gTlVMTDsNCi0JCXBEb2MgPSBwUGFyc2VyP3BQYXJzZXItPkdldERvY3VtZW50KCk6TlVMTDsNCi0JCUNoZWNrVW5TdXBwb3J0RXJyb3IocERvYywgZXJyX2NvZGUpOw0KLQl9DQotCWNhdGNoICguLi4pIHsNCi0JCWRlbGV0ZSBwUGFyc2VyOw0KLQkJU2V0TGFzdEVycm9yKEZQREZfRVJSX1VOS05PV04pOw0KLQkJcmV0dXJuIE5VTEw7DQotCX0NCi0JcmV0dXJuIHBQYXJzZXItPkdldERvY3VtZW50KCk7DQotfQ0KLQ0KLURMTEVYUE9SVCBGUERGX0RPQ1VNRU5UIFNURENBTEwgRlBERl9Mb2FkQ3VzdG9tRG9jdW1lbnQoRlBERl9GSUxFQUNDRVNTKiBwRmlsZUFjY2VzcywgRlBERl9CWVRFU1RSSU5HIHBhc3N3b3JkKQ0KLXsNCi0JQ1BERl9QYXJzZXIqIHBQYXJzZXIgPSBGWF9ORVcgQ1BERl9QYXJzZXI7DQotCXBQYXJzZXItPlNldFBhc3N3b3JkKHBhc3N3b3JkKTsNCi0JQ1BERl9DdXN0b21BY2Nlc3MqIHBGaWxlID0gRlhfTkVXIENQREZfQ3VzdG9tQWNjZXNzKHBGaWxlQWNjZXNzKTsNCi0JdHJ5IHsNCi0JCUZYX0RXT1JEIGVycl9jb2RlID0gcFBhcnNlci0+U3RhcnRQYXJzZShwRmlsZSk7DQotCQlpZiAoZXJyX2NvZGUpIHsNCi0JCQlkZWxldGUgcFBhcnNlcjsNCi0JCQlQcm9jZXNzUGFyc2VFcnJvcihlcnJfY29kZSk7DQotCQkJcmV0dXJuIE5VTEw7DQotCQl9DQotCQlDUERGX0RvY3VtZW50ICogcERvYyA9IE5VTEw7DQotCQlwRG9jID0gcFBhcnNlcj9wUGFyc2VyLT5HZXREb2N1bWVudCgpOk5VTEw7DQotCQlDaGVja1VuU3VwcG9ydEVycm9yKHBEb2MsIGVycl9jb2RlKTsNCi0JfQ0KLQljYXRjaCAoLi4uKSB7DQotCQlkZWxldGUgcFBhcnNlcjsNCi0JCVNldExhc3RFcnJvcihGUERGX0VSUl9VTktOT1dOKTsNCi0JCXJldHVybiBOVUxMOw0KLQl9DQotCXJldHVybiBwUGFyc2VyLT5HZXREb2N1bWVudCgpOw0KLX0NCi0NCi1ETExFWFBPUlQgRlBERl9CT09MIFNURENBTEwgRlBERl9HZXRGaWxlVmVyc2lvbihGUERGX0RPQ1VNRU5UIGRvYywgaW50KiBmaWxlVmVyc2lvbikNCi17DQotCWlmKCFkb2N8fCFmaWxlVmVyc2lvbikgcmV0dXJuIEZBTFNFOw0KLQkqZmlsZVZlcnNpb24gPSAwOw0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvYzsNCi0JQ1BERl9QYXJzZXIqIHBQYXJzZXIgPSAoQ1BERl9QYXJzZXIqKXBEb2MtPkdldFBhcnNlcigpOw0KLQlpZighcFBhcnNlcikNCi0JCXJldHVybiBGQUxTRTsNCi0JKmZpbGVWZXJzaW9uID0gcFBhcnNlci0+R2V0RmlsZVZlcnNpb24oKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8vIGphYmRlbG1hbGVrOiBjaGFuZ2VkIHJldHVybiB0eXBlIGZyb20gRlhfRFdPUkQgdG8gYnVpbGQgb24gTGludXggKGFuZCBtYXRjaCBoZWFkZXIpLg0KLURMTEVYUE9SVCB1bnNpZ25lZCBsb25nIFNURENBTEwgRlBERl9HZXREb2NQZXJtaXNzaW9ucyhGUERGX0RPQ1VNRU5UIGRvY3VtZW50KQ0KLXsNCi0JaWYgKGRvY3VtZW50ID09IE5VTEwpIHJldHVybiAwOw0KLQlDUERGX0RvY3VtZW50KnBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7DQotCUNQREZfUGFyc2VyKiBwUGFyc2VyID0gCShDUERGX1BhcnNlciopcERvYy0+R2V0UGFyc2VyKCk7DQotCUNQREZfRGljdGlvbmFyeSogcERpY3QgPSBwUGFyc2VyLT5HZXRFbmNyeXB0RGljdCgpOw0KLQlpZiAocERpY3QgPT0gTlVMTCkgcmV0dXJuIChGWF9EV09SRCktMTsNCi0NCi0JcmV0dXJuIHBEaWN0LT5HZXRJbnRlZ2VyKCJQIik7DQotfQ0KLQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX0dldFBhZ2VDb3VudChGUERGX0RPQ1VNRU5UIGRvY3VtZW50KQ0KLXsNCi0JaWYgKGRvY3VtZW50ID09IE5VTEwpIHJldHVybiAwOw0KLQlyZXR1cm4gKChDUERGX0RvY3VtZW50Kilkb2N1bWVudCktPkdldFBhZ2VDb3VudCgpOw0KLX0NCi0NCi1ETExFWFBPUlQgRlBERl9QQUdFIFNURENBTEwgRlBERl9Mb2FkUGFnZShGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBpbnQgcGFnZV9pbmRleCkNCi17DQotCWlmIChkb2N1bWVudCA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0JaWYgKHBhZ2VfaW5kZXggPCAwIHx8IHBhZ2VfaW5kZXggPj0gRlBERl9HZXRQYWdlQ291bnQoZG9jdW1lbnQpKSByZXR1cm4gTlVMTDsNCi0vLwlDUERGX1BhcnNlciogcFBhcnNlciA9IChDUERGX1BhcnNlciopZG9jdW1lbnQ7DQotCUNQREZfRG9jdW1lbnQqIHBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7DQotCWlmIChwRG9jID09IE5VTEwpIHJldHVybiBOVUxMOw0KLQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gcERvYy0+R2V0UGFnZShwYWdlX2luZGV4KTsNCi0JaWYgKHBEaWN0ID09IE5VTEwpIHJldHVybiBOVUxMOw0KLQlDUERGX1BhZ2UqIHBQYWdlID0gRlhfTkVXIENQREZfUGFnZTsNCi0JcFBhZ2UtPkxvYWQocERvYywgcERpY3QpOw0KLQl0cnkgew0KLQkJcFBhZ2UtPlBhcnNlQ29udGVudCgpOw0KLQl9DQotCWNhdGNoICguLi4pIHsNCi0JCWRlbGV0ZSBwUGFnZTsNCi0JCXJldHVybiBOVUxMOw0KLQl9DQotCQ0KLS8vCUNoZWNrVW5TdXBwb3J0RXJyb3IocERvYywgMCk7DQotDQotCXJldHVybiBwUGFnZTsNCi19DQotDQotRExMRVhQT1JUIGRvdWJsZSBTVERDQUxMIEZQREZfR2V0UGFnZVdpZHRoKEZQREZfUEFHRSBwYWdlKQ0KLXsNCi0JaWYgKCFwYWdlKQ0KLQkJcmV0dXJuIDAuMDsNCi0JcmV0dXJuICgoQ1BERl9QYWdlKilwYWdlKS0+R2V0UGFnZVdpZHRoKCk7DQotfQ0KLQ0KLURMTEVYUE9SVCBkb3VibGUgU1REQ0FMTCBGUERGX0dldFBhZ2VIZWlnaHQoRlBERl9QQUdFIHBhZ2UpDQotew0KLQlpZiAoIXBhZ2UpIHJldHVybiAwLjA7DQotCXJldHVybiAoKENQREZfUGFnZSopcGFnZSktPkdldFBhZ2VIZWlnaHQoKTsNCi19DQotDQotdm9pZCBEcm9wQ29udGV4dCh2b2lkKiBkYXRhKQ0KLXsNCi0JZGVsZXRlIChDUmVuZGVyQ29udGV4dCopZGF0YTsNCi19DQotDQotdm9pZCBGUERGX1JlbmRlclBhZ2VfUmV0YWlsKENSZW5kZXJDb250ZXh0KiBwQ29udGV4dCwgRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwgaW50IHNpemVfeSwNCi0JCQkJCQlpbnQgcm90YXRlLCBpbnQgZmxhZ3MsRlhfQk9PTCBiTmVlZFRvUmVzdG9yZSwgSUZTREtfUEFVU0VfQWRhcHRlciAqIHBhdXNlICApOw0KLXZvaWQgKCpGdW5jX1JlbmRlclBhZ2UpKENSZW5kZXJDb250ZXh0KiwgRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwgaW50IHNpemVfeSwNCi0JCQkJCQlpbnQgcm90YXRlLCBpbnQgZmxhZ3MsRlhfQk9PTCBiTmVlZFRvUmVzdG9yZSwgSUZTREtfUEFVU0VfQWRhcHRlciAqIHBhdXNlICApID0gRlBERl9SZW5kZXJQYWdlX1JldGFpbDsNCi0NCi0jaWYgZGVmaW5lZChfREVCVUcpIHx8IGRlZmluZWQoREVCVUcpDQotI2RlZmluZSBERUJVR19UUkFDRQ0KLSNlbmRpZg0KLQ0KLSNpZiBkZWZpbmVkKF9XSU4zMikNCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfUmVuZGVyUGFnZShIREMgZGMsIEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIGludCBzaXplX3gsIGludCBzaXplX3ksDQotCQkJCQkJaW50IHJvdGF0ZSwgaW50IGZsYWdzKQ0KLXsNCi0JaWYgKHBhZ2U9PU5VTEwpIHJldHVybjsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotDQotCUNSZW5kZXJDb250ZXh0KiBwQ29udGV4dCA9IEZYX05FVyBDUmVuZGVyQ29udGV4dDsNCi0JcFBhZ2UtPlNldFByaXZhdGVEYXRhKCh2b2lkKikxLCBwQ29udGV4dCwgRHJvcENvbnRleHQpOw0KLQ0KLSNpZm5kZWYgX1dJTjMyX1dDRQ0KLQlDRlhfRElCaXRtYXAqIHBCaXRtYXAgPSBOVUxMOw0KLQlGWF9CT09MIGJCYWNrZ3JvdW5kQWxwaGFOZWVkZWQ9RkFMU0U7DQotCWJCYWNrZ3JvdW5kQWxwaGFOZWVkZWQgPSBwUGFnZS0+QmFja2dyb3VuZEFscGhhTmVlZGVkKCk7DQotCWlmIChiQmFja2dyb3VuZEFscGhhTmVlZGVkKQ0KLQl7DQotCQkNCi0JCXBCaXRtYXAgPSBGWF9ORVcgQ0ZYX0RJQml0bWFwOw0KLQkJcEJpdG1hcC0+Q3JlYXRlKHNpemVfeCwgc2l6ZV95LCBGWERJQl9BcmdiKTsNCi0JCXBCaXRtYXAtPkNsZWFyKDB4MDBmZmZmZmYpOw0KLSNpZmRlZiBfU0tJQV9TVVBQT1JUXw0KLQkJcENvbnRleHQtPm1fcERldmljZSA9IEZYX05FVyBDRlhfU2tpYURldmljZTsNCi0JCSgoQ0ZYX1NraWFEZXZpY2UqKXBDb250ZXh0LT5tX3BEZXZpY2UpLT5BdHRhY2goKENGWF9ESUJpdG1hcCopcEJpdG1hcCk7DQotI2Vsc2UNCi0JCXBDb250ZXh0LT5tX3BEZXZpY2UgPSBGWF9ORVcgQ0ZYX0Z4Z2VEZXZpY2U7DQotCQkoKENGWF9GeGdlRGV2aWNlKilwQ29udGV4dC0+bV9wRGV2aWNlKS0+QXR0YWNoKChDRlhfRElCaXRtYXAqKXBCaXRtYXApOw0KLSNlbmRpZg0KLQl9DQotCWVsc2UNCi0JcENvbnRleHQtPm1fcERldmljZSA9IEZYX05FVyBDRlhfV2luZG93c0RldmljZShkYyk7DQotCWlmIChmbGFncyAmIEZQREZfTk9fQ0FUQ0gpDQotCQlGdW5jX1JlbmRlclBhZ2UocENvbnRleHQsIHBhZ2UsIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95LCByb3RhdGUsIGZsYWdzLFRSVUUsTlVMTCk7DQotCWVsc2Ugew0KLQkJdHJ5IHsNCi0JCQlGdW5jX1JlbmRlclBhZ2UocENvbnRleHQsIHBhZ2UsIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95LCByb3RhdGUsIGZsYWdzLFRSVUUsTlVMTCk7DQotCQl9IGNhdGNoICguLi4pIHsNCi0JCX0NCi0JfQ0KLQlpZiAoYkJhY2tncm91bmRBbHBoYU5lZWRlZCkgDQotCXsNCi0JCWlmIChwQml0bWFwKQ0KLQkJew0KLQkJCUNGWF9XaW5kb3dzRGV2aWNlIFdpbkRDKGRjKTsNCi0JCQkNCi0gCQkJaWYgKFdpbkRDLkdldERldmljZUNhcHMoRlhEQ19ERVZJQ0VfQ0xBU1MpID09IEZYRENfUFJJTlRFUikNCi0gCQkJew0KLQkJCQlDRlhfRElCaXRtYXAqIHBEc3QgPSBGWF9ORVcgQ0ZYX0RJQml0bWFwOw0KLQkJCQlwRHN0LT5DcmVhdGUocEJpdG1hcC0+R2V0V2lkdGgoKSwgcEJpdG1hcC0+R2V0SGVpZ2h0KCksRlhESUJfUmdiMzIpOw0KLQkJCQlGWFNZU19tZW1jcHkocERzdC0+R2V0QnVmZmVyKCksIHBCaXRtYXAtPkdldEJ1ZmZlcigpLCBwQml0bWFwLT5HZXRQaXRjaCgpKnBCaXRtYXAtPkdldEhlaWdodCgpKTsNCi0vLwkJCQlXaW5EQy5TZXRESUJpdHMocERzdCwwLDApOw0KLQkJCQlXaW5EQy5TdHJldGNoRElCaXRzKHBEc3QsMCwwLHNpemVfeCoyLHNpemVfeSoyKTsNCi0JCQkJZGVsZXRlIHBEc3Q7DQotIAkJCX0NCi0gCQkJZWxzZQ0KLSAJCQkJV2luREMuU2V0RElCaXRzKHBCaXRtYXAsMCwwKTsNCi0NCi0JCX0NCi0JfQ0KLSNlbHNlDQotCS8vIGdldCBjbGlwIHJlZ2lvbg0KLQlSRUNUIHJlY3QsIGNsaXByZWN0Ow0KLQlyZWN0LmxlZnQgPSBzdGFydF94Ow0KLQlyZWN0LnRvcCA9IHN0YXJ0X3k7DQotCXJlY3QucmlnaHQgPSBzdGFydF94ICsgc2l6ZV94Ow0KLQlyZWN0LmJvdHRvbSA9IHN0YXJ0X3kgKyBzaXplX3k7DQotCUdldENsaXBCb3goZGMsICZjbGlwcmVjdCk7DQotCUludGVyc2VjdFJlY3QoJnJlY3QsICZyZWN0LCAmY2xpcHJlY3QpOw0KLQlpbnQgd2lkdGggPSByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0Ow0KLQlpbnQgaGVpZ2h0ID0gcmVjdC5ib3R0b20gLSByZWN0LnRvcDsNCi0NCi0jaWZkZWYgREVCVUdfVFJBQ0UNCi0Jew0KLQkJY2hhciBzdHJbMTI4XTsNCi0JCXNwcmludGYoc3RyLCAiUmVuZGVyaW5nIERJQiAlZCB4ICVkIiwgd2lkdGgsIGhlaWdodCk7DQotCQlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKDk5OSwgc3RyKTsNCi0JfQ0KLSNlbmRpZg0KLQ0KLQkvLyBDcmVhdGUgYSBESUIgc2VjdGlvbg0KLQlMUFZPSUQgcEJ1ZmZlcjsNCi0JQklUTUFQSU5GT0hFQURFUiBibWloOw0KLQlGWFNZU19tZW1zZXQoJmJtaWgsIDAsIHNpemVvZiBibWloKTsNCi0JYm1paC5iaVNpemUgPSBzaXplb2YgYm1paDsNCi0JYm1paC5iaUJpdENvdW50ID0gMjQ7DQotCWJtaWguYmlIZWlnaHQgPSAtaGVpZ2h0Ow0KLQlibWloLmJpUGxhbmVzID0gMTsNCi0JYm1paC5iaVdpZHRoID0gd2lkdGg7DQotCXBDb250ZXh0LT5tX2hCaXRtYXAgPSBDcmVhdGVESUJTZWN0aW9uKGRjLCAoQklUTUFQSU5GTyopJmJtaWgsIERJQl9SR0JfQ09MT1JTLCAmcEJ1ZmZlciwgTlVMTCwgMCk7DQotCWlmIChwQ29udGV4dC0+bV9oQml0bWFwID09IE5VTEwpIHsNCi0jaWYgZGVmaW5lZChERUJVRykgfHwgZGVmaW5lZChfREVCVUcpDQotCQljaGFyIHN0clsxMjhdOw0KLQkJc3ByaW50ZihzdHIsICJFcnJvciBDcmVhdGVESUJTZWN0aW9uOiAlZCB4ICVkLCBlcnJvciBjb2RlID0gJWQiLCB3aWR0aCwgaGVpZ2h0LCBHZXRMYXN0RXJyb3IoKSk7DQotCQlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKEZQREZFUlJfT1VUX09GX01FTU9SWSwgc3RyKTsNCi0jZWxzZQ0KLQkJQ1BERl9Nb2R1bGVNZ3I6OkdldCgpLT5SZXBvcnRFcnJvcihGUERGRVJSX09VVF9PRl9NRU1PUlksIE5VTEwpOw0KLSNlbmRpZg0KLQl9DQotCUZYU1lTX21lbXNldChwQnVmZmVyLCAweGZmLCBoZWlnaHQqKCh3aWR0aCozKzMpLzQqNCkpOw0KLQ0KLSNpZmRlZiBERUJVR19UUkFDRQ0KLQl7DQotCQlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKDk5OSwgIkRJQlNlY3Rpb24gY3JlYXRlZCIpOw0KLQl9DQotI2VuZGlmDQotDQotCS8vIENyZWF0ZSBhIGRldmljZSB3aXRoIHRoaXMgZXh0ZXJuYWwgYnVmZmVyDQotCXBDb250ZXh0LT5tX3BCaXRtYXAgPSBGWF9ORVcgQ0ZYX0RJQml0bWFwOw0KLQlwQ29udGV4dC0+bV9wQml0bWFwLT5DcmVhdGUod2lkdGgsIGhlaWdodCwgRlhESUJfUmdiLCAoRlhfTFBCWVRFKXBCdWZmZXIpOw0KLQlwQ29udGV4dC0+bV9wRGV2aWNlID0gRlhfTkVXIENQREZfRnhnZURldmljZTsNCi0JKChDUERGX0Z4Z2VEZXZpY2UqKXBDb250ZXh0LT5tX3BEZXZpY2UpLT5BdHRhY2gocENvbnRleHQtPm1fcEJpdG1hcCk7DQotCQ0KLSNpZmRlZiBERUJVR19UUkFDRQ0KLQlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKDk5OSwgIlJlYWR5IGZvciBQREYgcmVuZGVyaW5nIik7DQotI2VuZGlmDQotDQotCS8vIG91dHB1dCB0byBiaXRtYXAgZGV2aWNlDQotCWlmIChmbGFncyAmIEZQREZfTk9fQ0FUQ0gpDQotCQlGdW5jX1JlbmRlclBhZ2UocENvbnRleHQsIHBhZ2UsIHN0YXJ0X3ggLSByZWN0LmxlZnQsIHN0YXJ0X3kgLSByZWN0LnRvcCwgc2l6ZV94LCBzaXplX3ksIHJvdGF0ZSwgZmxhZ3MpOw0KLQllbHNlIHsNCi0JCXRyeSB7DQotCQkJRnVuY19SZW5kZXJQYWdlKHBDb250ZXh0LCBwYWdlLCBzdGFydF94IC0gcmVjdC5sZWZ0LCBzdGFydF95IC0gcmVjdC50b3AsIHNpemVfeCwgc2l6ZV95LCByb3RhdGUsIGZsYWdzKTsNCi0JCX0gY2F0Y2ggKC4uLikgew0KLQkJfQ0KLQl9DQotDQotI2lmZGVmIERFQlVHX1RSQUNFDQotCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+UmVwb3J0RXJyb3IoOTk5LCAiRmluaXNoZWQgUERGIHJlbmRlcmluZyIpOw0KLSNlbmRpZg0KLQ0KLQkvLyBOb3cgb3V0cHV0IHRvIHJlYWwgZGV2aWNlDQotCUhEQyBoTWVtREMgPSBDcmVhdGVDb21wYXRpYmxlREMoZGMpOw0KLQlpZiAoaE1lbURDID09IE5VTEwpIHsNCi0jaWYgZGVmaW5lZChERUJVRykgfHwgZGVmaW5lZChfREVCVUcpDQotCQljaGFyIHN0clsxMjhdOw0KLQkJc3ByaW50ZihzdHIsICJFcnJvciBDcmVhdGVDb21wYXRpYmxlREMuIEVycm9yIGNvZGUgPSAlZCIsIEdldExhc3RFcnJvcigpKTsNCi0JCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+UmVwb3J0RXJyb3IoRlBERkVSUl9PVVRfT0ZfTUVNT1JZLCBzdHIpOw0KLSNlbHNlDQotCQlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKEZQREZFUlJfT1VUX09GX01FTU9SWSwgTlVMTCk7DQotI2VuZGlmDQotCX0NCi0NCi0JSEdESU9CSiBoT2xkQml0bWFwID0gU2VsZWN0T2JqZWN0KGhNZW1EQywgcENvbnRleHQtPm1faEJpdG1hcCk7DQotDQotI2lmZGVmIERFQlVHX1RSQUNFDQotCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+UmVwb3J0RXJyb3IoOTk5LCAiUmVhZHkgZm9yIHNjcmVlbiByZW5kZXJpbmciKTsNCi0jZW5kaWYNCi0NCi0JQml0Qmx0KGRjLCByZWN0LmxlZnQsIHJlY3QudG9wLCB3aWR0aCwgaGVpZ2h0LCBoTWVtREMsIDAsIDAsIFNSQ0NPUFkpOw0KLQlTZWxlY3RPYmplY3QoaE1lbURDLCBoT2xkQml0bWFwKTsNCi0JRGVsZXRlREMoaE1lbURDKTsNCi0NCi0jaWZkZWYgREVCVUdfVFJBQ0UNCi0JQ1BERl9Nb2R1bGVNZ3I6OkdldCgpLT5SZXBvcnRFcnJvcig5OTksICJGaW5pc2hlZCBzY3JlZW4gcmVuZGVyaW5nIik7DQotI2VuZGlmDQotDQotI2VuZGlmDQotCWlmIChiQmFja2dyb3VuZEFscGhhTmVlZGVkKQ0KLQl7DQotCQlpZiAocEJpdG1hcCkNCi0JCQlkZWxldGUgcEJpdG1hcDsNCi0JCXBCaXRtYXAgPSBOVUxMOw0KLQl9DQotCWRlbGV0ZSBwQ29udGV4dDsNCi0JcFBhZ2UtPlJlbW92ZVByaXZhdGVEYXRhKCh2b2lkKikxKTsNCi19DQotI2VuZGlmDQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX1JlbmRlclBhZ2VCaXRtYXAoRlBERl9CSVRNQVAgYml0bWFwLCBGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCANCi0JCQkJCQlpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LCBpbnQgcm90YXRlLCBpbnQgZmxhZ3MpDQotew0KLQlpZiAoYml0bWFwID09IE5VTEwgfHwgcGFnZSA9PSBOVUxMKSByZXR1cm47DQotCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOw0KLQ0KLQ0KLQlDUmVuZGVyQ29udGV4dCogcENvbnRleHQgPSBGWF9ORVcgQ1JlbmRlckNvbnRleHQ7DQotCXBQYWdlLT5TZXRQcml2YXRlRGF0YSgodm9pZCopMSwgcENvbnRleHQsIERyb3BDb250ZXh0KTsNCi0jaWZkZWYgX1NLSUFfU1VQUE9SVF8NCi0JcENvbnRleHQtPm1fcERldmljZSA9IEZYX05FVyBDRlhfU2tpYURldmljZTsNCi0NCi0JaWYgKGZsYWdzICYgRlBERl9SRVZFUlNFX0JZVEVfT1JERVIpDQotCQkoKENGWF9Ta2lhRGV2aWNlKilwQ29udGV4dC0+bV9wRGV2aWNlKS0+QXR0YWNoKChDRlhfRElCaXRtYXAqKWJpdG1hcCwwLFRSVUUpOw0KLQllbHNlDQotCQkoKENGWF9Ta2lhRGV2aWNlKilwQ29udGV4dC0+bV9wRGV2aWNlKS0+QXR0YWNoKChDRlhfRElCaXRtYXAqKWJpdG1hcCk7DQotI2Vsc2UNCi0JcENvbnRleHQtPm1fcERldmljZSA9IEZYX05FVyBDRlhfRnhnZURldmljZTsNCi0NCi0JaWYgKGZsYWdzICYgRlBERl9SRVZFUlNFX0JZVEVfT1JERVIpDQotCQkoKENGWF9GeGdlRGV2aWNlKilwQ29udGV4dC0+bV9wRGV2aWNlKS0+QXR0YWNoKChDRlhfRElCaXRtYXAqKWJpdG1hcCwwLFRSVUUpOw0KLQllbHNlDQotCQkoKENGWF9GeGdlRGV2aWNlKilwQ29udGV4dC0+bV9wRGV2aWNlKS0+QXR0YWNoKChDRlhfRElCaXRtYXAqKWJpdG1hcCk7DQotI2VuZGlmDQotCWlmIChmbGFncyAmIEZQREZfTk9fQ0FUQ0gpDQotCQlGdW5jX1JlbmRlclBhZ2UocENvbnRleHQsIHBhZ2UsIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95LCByb3RhdGUsIGZsYWdzLFRSVUUsTlVMTCk7DQotCWVsc2Ugew0KLQkJdHJ5IHsNCi0JCQlGdW5jX1JlbmRlclBhZ2UocENvbnRleHQsIHBhZ2UsIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95LCByb3RhdGUsIGZsYWdzLFRSVUUsTlVMTCk7DQotCQl9IGNhdGNoICguLi4pIHsNCi0JCX0NCi0JfQ0KLQ0KLQlkZWxldGUgcENvbnRleHQ7DQotCXBQYWdlLT5SZW1vdmVQcml2YXRlRGF0YSgodm9pZCopMSk7DQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9DbG9zZVBhZ2UoRlBERl9QQUdFIHBhZ2UpDQotew0KLQlpZiAoIXBhZ2UpIHJldHVybjsNCi0JZGVsZXRlIChDUERGX1BhZ2UqKXBhZ2U7DQotDQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9DbG9zZURvY3VtZW50KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpDQotew0KLQlpZiAoIWRvY3VtZW50KQ0KLQkJcmV0dXJuOw0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50OwkNCi0JQ1BERl9QYXJzZXIqIHBQYXJzZXIgPSAoQ1BERl9QYXJzZXIqKXBEb2MtPkdldFBhcnNlcigpOw0KLQlpZiAocFBhcnNlciA9PSBOVUxMKSANCi0Jew0KLQkJZGVsZXRlIHBEb2M7DQotCQlyZXR1cm47DQotCX0NCi0JZGVsZXRlIHBQYXJzZXI7DQotLy8JZGVsZXRlIHBEb2M7DQotfQ0KLQ0KLURMTEVYUE9SVCB1bnNpZ25lZCBsb25nIFNURENBTEwgRlBERl9HZXRMYXN0RXJyb3IoKQ0KLXsNCi0JcmV0dXJuIEdldExhc3RFcnJvcigpOw0KLX0NCi0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfRGV2aWNlVG9QYWdlKEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIGludCBzaXplX3gsIGludCBzaXplX3ksDQotCQkJCQkJaW50IHJvdGF0ZSwgaW50IGRldmljZV94LCBpbnQgZGV2aWNlX3ksIGRvdWJsZSogcGFnZV94LCBkb3VibGUqIHBhZ2VfeSkNCi17DQotCWlmIChwYWdlID09IE5VTEwgfHwgcGFnZV94ID09IE5VTEwgfHwgcGFnZV95ID09IE5VTEwpIHJldHVybjsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotDQotCUNQREZfTWF0cml4IHBhZ2UyZGV2aWNlOw0KLQlwUGFnZS0+R2V0RGlzcGxheU1hdHJpeChwYWdlMmRldmljZSwgc3RhcnRfeCwgc3RhcnRfeSwgc2l6ZV94LCBzaXplX3ksIHJvdGF0ZSk7DQotCUNQREZfTWF0cml4IGRldmljZTJwYWdlOw0KLQlkZXZpY2UycGFnZS5TZXRSZXZlcnNlKHBhZ2UyZGV2aWNlKTsNCi0NCi0JRlhfRkxPQVQgcGFnZV94X2YsIHBhZ2VfeV9mOw0KLQlkZXZpY2UycGFnZS5UcmFuc2Zvcm0oKEZYX0ZMT0FUKShkZXZpY2VfeCksIChGWF9GTE9BVCkoZGV2aWNlX3kpLCBwYWdlX3hfZiwgcGFnZV95X2YpOw0KLQ0KLQkqcGFnZV94ID0gKHBhZ2VfeF9mKTsNCi0JKnBhZ2VfeSA9IChwYWdlX3lfZik7DQotfQ0KLQ0KLURMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9QYWdlVG9EZXZpY2UoRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwgaW50IHNpemVfeSwNCi0JCQkJCQlpbnQgcm90YXRlLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95LCBpbnQqIGRldmljZV94LCBpbnQqIGRldmljZV95KQ0KLXsNCi0JaWYgKHBhZ2UgPT0gTlVMTCB8fCBkZXZpY2VfeCA9PSBOVUxMIHx8IGRldmljZV95ID09IE5VTEwpIHJldHVybjsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotDQotCUNQREZfTWF0cml4IHBhZ2UyZGV2aWNlOw0KLQlwUGFnZS0+R2V0RGlzcGxheU1hdHJpeChwYWdlMmRldmljZSwgc3RhcnRfeCwgc3RhcnRfeSwgc2l6ZV94LCBzaXplX3ksIHJvdGF0ZSk7DQotDQotCUZYX0ZMT0FUIGRldmljZV94X2YsIGRldmljZV95X2Y7DQotCXBhZ2UyZGV2aWNlLlRyYW5zZm9ybSgoKEZYX0ZMT0FUKXBhZ2VfeCksICgoRlhfRkxPQVQpcGFnZV95KSwgZGV2aWNlX3hfZiwgZGV2aWNlX3lfZik7DQotDQotCSpkZXZpY2VfeCA9IEZYU1lTX3JvdW5kKGRldmljZV94X2YpOw0KLQkqZGV2aWNlX3kgPSBGWFNZU19yb3VuZChkZXZpY2VfeV9mKTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQklUTUFQIFNURENBTEwgRlBERkJpdG1hcF9DcmVhdGUoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYWxwaGEpDQotew0KLQlDRlhfRElCaXRtYXAqIHBCaXRtYXAgPSBGWF9ORVcgQ0ZYX0RJQml0bWFwOw0KLQlwQml0bWFwLT5DcmVhdGUod2lkdGgsIGhlaWdodCwgYWxwaGEgPyBGWERJQl9BcmdiIDogRlhESUJfUmdiMzIpOw0KLQlyZXR1cm4gcEJpdG1hcDsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQklUTUFQIFNURENBTEwgRlBERkJpdG1hcF9DcmVhdGVFeChpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBmb3JtYXQsIHZvaWQqIGZpcnN0X3NjYW4sIGludCBzdHJpZGUpDQotew0KLQlGWERJQl9Gb3JtYXQgZnhfZm9ybWF0Ow0KLQlzd2l0Y2ggKGZvcm1hdCkgew0KLQkJY2FzZSBGUERGQml0bWFwX0dyYXk6DQotCQkJZnhfZm9ybWF0ID0gRlhESUJfOGJwcFJnYjsNCi0JCQlicmVhazsNCi0JCWNhc2UgRlBERkJpdG1hcF9CR1I6DQotCQkJZnhfZm9ybWF0ID0gRlhESUJfUmdiOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBGUERGQml0bWFwX0JHUng6DQotCQkJZnhfZm9ybWF0ID0gRlhESUJfUmdiMzI7DQotCQkJYnJlYWs7DQotCQljYXNlIEZQREZCaXRtYXBfQkdSQToNCi0JCQlmeF9mb3JtYXQgPSBGWERJQl9BcmdiOw0KLQkJCWJyZWFrOw0KLQkJZGVmYXVsdDoNCi0JCQlyZXR1cm4gTlVMTDsNCi0JfQ0KLQlDRlhfRElCaXRtYXAqIHBCaXRtYXAgPSBGWF9ORVcgQ0ZYX0RJQml0bWFwOw0KLQlwQml0bWFwLT5DcmVhdGUod2lkdGgsIGhlaWdodCwgZnhfZm9ybWF0LCAoRlhfTFBCWVRFKWZpcnN0X3NjYW4sIHN0cmlkZSk7DQotCXJldHVybiBwQml0bWFwOw0KLX0NCi0NCi1ETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZCaXRtYXBfRmlsbFJlY3QoRlBERl9CSVRNQVAgYml0bWFwLCBpbnQgbGVmdCwgaW50IHRvcCwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCANCi0JCQkJCQkJCQlpbnQgcmVkLCBpbnQgZ3JlZW4sIGludCBibHVlLCBpbnQgYWxwaGEpDQotew0KLQlpZiAoYml0bWFwID09IE5VTEwpIHJldHVybjsNCi0jaWZkZWYgX1NLSUFfU1VQUE9SVF8NCi0JQ0ZYX1NraWFEZXZpY2UgZGV2aWNlOw0KLSNlbHNlDQotCUNGWF9GeGdlRGV2aWNlIGRldmljZTsNCi0jZW5kaWYNCi0JZGV2aWNlLkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXApOw0KLQlpZiAoISgoQ0ZYX0RJQml0bWFwKiliaXRtYXApLT5IYXNBbHBoYSgpKSBhbHBoYSA9IDI1NTsNCi0JRlhfUkVDVCByZWN0KGxlZnQsIHRvcCwgbGVmdCt3aWR0aCwgdG9wK2hlaWdodCk7DQotCWRldmljZS5GaWxsUmVjdCgmcmVjdCwgRlhBUkdCX01BS0UoYWxwaGEsIHJlZCwgZ3JlZW4sIGJsdWUpKTsNCi19DQotDQotRExMRVhQT1JUIHZvaWQqIFNURENBTEwgRlBERkJpdG1hcF9HZXRCdWZmZXIoRlBERl9CSVRNQVAgYml0bWFwKQ0KLXsNCi0JaWYgKGJpdG1hcCA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0JcmV0dXJuICgoQ0ZYX0RJQml0bWFwKiliaXRtYXApLT5HZXRCdWZmZXIoKTsNCi19DQotDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZCaXRtYXBfR2V0V2lkdGgoRlBERl9CSVRNQVAgYml0bWFwKQ0KLXsNCi0JaWYgKGJpdG1hcCA9PSBOVUxMKSByZXR1cm4gMDsNCi0JcmV0dXJuICgoQ0ZYX0RJQml0bWFwKiliaXRtYXApLT5HZXRXaWR0aCgpOw0KLX0NCi0NCi1ETExFWFBPUlQgaW50IFNURENBTEwgRlBERkJpdG1hcF9HZXRIZWlnaHQoRlBERl9CSVRNQVAgYml0bWFwKQ0KLXsNCi0JaWYgKGJpdG1hcCA9PSBOVUxMKSByZXR1cm4gMDsNCi0JcmV0dXJuICgoQ0ZYX0RJQml0bWFwKiliaXRtYXApLT5HZXRIZWlnaHQoKTsNCi19DQotDQotRExMRVhQT1JUIGludCBTVERDQUxMIEZQREZCaXRtYXBfR2V0U3RyaWRlKEZQREZfQklUTUFQIGJpdG1hcCkNCi17DQotCWlmIChiaXRtYXAgPT0gTlVMTCkgcmV0dXJuIDA7DQotCXJldHVybiAoKENGWF9ESUJpdG1hcCopYml0bWFwKS0+R2V0UGl0Y2goKTsNCi19DQotDQotRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGQml0bWFwX0Rlc3Ryb3koRlBERl9CSVRNQVAgYml0bWFwKQ0KLXsNCi0JaWYgKGJpdG1hcCA9PSBOVUxMKSByZXR1cm47DQotCWRlbGV0ZSAoQ0ZYX0RJQml0bWFwKiliaXRtYXA7DQotfQ0KLQ0KLXZvaWQgRlBERl9SZW5kZXJQYWdlX1JldGFpbChDUmVuZGVyQ29udGV4dCogcENvbnRleHQsIEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIGludCBzaXplX3gsIGludCBzaXplX3ksDQotCQkJCQkJaW50IHJvdGF0ZSwgaW50IGZsYWdzLEZYX0JPT0wgYk5lZWRUb1Jlc3RvcmUsIElGU0RLX1BBVVNFX0FkYXB0ZXIgKiBwYXVzZSApDQotew0KLS8vI2lmZGVmIF9MSUNFTlNFRF9CVUlMRF8NCi0JQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7DQotCWlmIChwUGFnZSA9PSBOVUxMKSByZXR1cm47DQotDQotCWlmICghcENvbnRleHQtPm1fcE9wdGlvbnMpDQotCQlwQ29udGV4dC0+bV9wT3B0aW9ucyA9IG5ldyBDUERGX1JlbmRlck9wdGlvbnM7DQotLy8JQ1BERl9SZW5kZXJPcHRpb25zIG9wdGlvbnM7DQotCWlmIChmbGFncyAmIEZQREZfTENEX1RFWFQpDQotCQlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9GbGFncyB8PSBSRU5ERVJfQ0xFQVJUWVBFOw0KLQllbHNlDQotCQlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9GbGFncyAmPSB+UkVOREVSX0NMRUFSVFlQRTsNCi0JaWYgKGZsYWdzICYgRlBERl9OT19OQVRJVkVURVhUKQ0KLQkJcENvbnRleHQtPm1fcE9wdGlvbnMtPm1fRmxhZ3MgfD0gUkVOREVSX05PX05BVElWRVRFWFQ7DQotCWlmIChmbGFncyAmIEZQREZfUkVOREVSX0xJTUlURURJTUFHRUNBQ0hFKQ0KLQkJcENvbnRleHQtPm1fcE9wdGlvbnMtPm1fRmxhZ3MgfD0gUkVOREVSX0xJTUlURURJTUFHRUNBQ0hFOw0KLQlpZiAoZmxhZ3MgJiBGUERGX1JFTkRFUl9GT1JDRUhBTEZUT05FKQ0KLQkJcENvbnRleHQtPm1fcE9wdGlvbnMtPm1fRmxhZ3MgfD0gUkVOREVSX0ZPUkNFX0hBTEZUT05FOw0KLQkvL0dyYXlzY2FsZSBvdXRwdXQNCi0JaWYgKGZsYWdzICYgRlBERl9HUkFZU0NBTEUpDQotCXsNCi0JCXBDb250ZXh0LT5tX3BPcHRpb25zLT5tX0NvbG9yTW9kZSA9IFJFTkRFUl9DT0xPUl9HUkFZOw0KLQkJcENvbnRleHQtPm1fcE9wdGlvbnMtPm1fRm9yZUNvbG9yID0gMDsNCi0JCXBDb250ZXh0LT5tX3BPcHRpb25zLT5tX0JhY2tDb2xvciA9IDB4ZmZmZmZmOw0KLQl9DQotCWNvbnN0IENQREZfT0NDb250ZXh0OjpVc2FnZVR5cGUgdXNhZ2UgPSAoZmxhZ3MgJiBGUERGX1BSSU5USU5HKSA/IENQREZfT0NDb250ZXh0OjpQcmludCA6IENQREZfT0NDb250ZXh0OjpWaWV3Ow0KLQ0KLQlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9BZGRGbGFncyA9IGZsYWdzID4+IDg7DQotDQotCXBDb250ZXh0LT5tX3BPcHRpb25zLT5tX3BPQ0NvbnRleHQgPSBuZXcgQ1BERl9PQ0NvbnRleHQocFBhZ2UtPm1fcERvY3VtZW50LCB1c2FnZSk7DQotDQotDQotCUNGWF9BZmZpbmVNYXRyaXggbWF0cml4Ow0KLQlwUGFnZS0+R2V0RGlzcGxheU1hdHJpeChtYXRyaXgsIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95LCByb3RhdGUpOyANCi0NCi0JRlhfUkVDVCBjbGlwOw0KLQljbGlwLmxlZnQgPSBzdGFydF94Ow0KLQljbGlwLnJpZ2h0ID0gc3RhcnRfeCArIHNpemVfeDsNCi0JY2xpcC50b3AgPSBzdGFydF95Ow0KLQljbGlwLmJvdHRvbSA9IHN0YXJ0X3kgKyBzaXplX3k7DQotCXBDb250ZXh0LT5tX3BEZXZpY2UtPlNhdmVTdGF0ZSgpOw0KLQlwQ29udGV4dC0+bV9wRGV2aWNlLT5TZXRDbGlwX1JlY3QoJmNsaXApOw0KLQ0KLQlwQ29udGV4dC0+bV9wQ29udGV4dCA9IEZYX05FVyBDUERGX1JlbmRlckNvbnRleHQ7DQotCXBDb250ZXh0LT5tX3BDb250ZXh0LT5DcmVhdGUocFBhZ2UpOw0KLQlwQ29udGV4dC0+bV9wQ29udGV4dC0+QXBwZW5kT2JqZWN0TGlzdChwUGFnZSwgJm1hdHJpeCk7DQotDQotCWlmIChmbGFncyAmIEZQREZfQU5OT1QpIHsNCi0JCXBDb250ZXh0LT5tX3BBbm5vdHMgPSBGWF9ORVcgQ1BERl9Bbm5vdExpc3QocFBhZ2UpOw0KLQkJRlhfQk9PTCBiUHJpbnRpbmcgPSBwQ29udGV4dC0+bV9wRGV2aWNlLT5HZXREZXZpY2VDbGFzcygpICE9IEZYRENfRElTUExBWTsNCi0JCXBDb250ZXh0LT5tX3BBbm5vdHMtPkRpc3BsYXlBbm5vdHMocFBhZ2UsIHBDb250ZXh0LT5tX3BDb250ZXh0LCBiUHJpbnRpbmcsICZtYXRyaXgsIFRSVUUsIE5VTEwpOw0KLQl9DQotDQotCXBDb250ZXh0LT5tX3BSZW5kZXJlciA9IEZYX05FVyBDUERGX1Byb2dyZXNzaXZlUmVuZGVyZXI7DQotCXBDb250ZXh0LT5tX3BSZW5kZXJlci0+U3RhcnQocENvbnRleHQtPm1fcENvbnRleHQsIHBDb250ZXh0LT5tX3BEZXZpY2UsIHBDb250ZXh0LT5tX3BPcHRpb25zLCBwYXVzZSk7DQotCWlmIChiTmVlZFRvUmVzdG9yZSkNCi0Jew0KLQkgIHBDb250ZXh0LT5tX3BEZXZpY2UtPlJlc3RvcmVTdGF0ZSgpOw0KLQl9DQotCQ0KLS8vI2VuZGlmDQotfQ0KLQ0KLURMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX0dldFBhZ2VTaXplQnlJbmRleChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBpbnQgcGFnZV9pbmRleCwgZG91YmxlKiB3aWR0aCwgZG91YmxlKiBoZWlnaHQpDQotew0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50Ow0KLQlpZihwRG9jID09IE5VTEwpDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRGljdGlvbmFyeSogcERpY3QgPSBwRG9jLT5HZXRQYWdlKHBhZ2VfaW5kZXgpOw0KLQlpZiAocERpY3QgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDUERGX1BhZ2UgcGFnZTsNCi0JcGFnZS5Mb2FkKHBEb2MsIHBEaWN0KTsNCi0JKndpZHRoID0gcGFnZS5HZXRQYWdlV2lkdGgoKTsNCi0JKmhlaWdodCA9IHBhZ2UuR2V0UGFnZUhlaWdodCgpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZfVklFV0VSUkVGX0dldFByaW50U2NhbGluZyhGUERGX0RPQ1VNRU5UIGRvY3VtZW50KQ0KLXsNCi0JQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsNCi0JaWYgKCFwRG9jKSByZXR1cm4gVFJVRTsNCi0JQ1BERl9WaWV3ZXJQcmVmZXJlbmNlcyB2aWV3UmVmKHBEb2MpOw0KLQlyZXR1cm4gdmlld1JlZi5QcmludFNjYWxpbmcoKTsNCi19DQotDQotRExMRVhQT1JUIEZQREZfREVTVCBTVERDQUxMIEZQREZfR2V0TmFtZWREZXN0QnlOYW1lKEZQREZfRE9DVU1FTlQgZG9jdW1lbnQsRlBERl9CWVRFU1RSSU5HIG5hbWUpDQotew0KLQlpZiAoZG9jdW1lbnQgPT0gTlVMTCkNCi0JCXJldHVybiBOVUxMOw0KLQlpZiAobmFtZSA9PSBOVUxMIHx8IG5hbWVbMF0gPT0gMCkgDQotCQlyZXR1cm4gTlVMTDsNCi0NCi0JQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsNCi0JQ1BERl9OYW1lVHJlZSBuYW1lX3RyZWUocERvYywgRlhfQlNUUkMoIkRlc3RzIikpOw0KLQlyZXR1cm4gbmFtZV90cmVlLkxvb2t1cE5hbWVkRGVzdChwRG9jLCBuYW1lKTsNCi19DQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZ2aWV3LmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX3JlbmRlcmNvbnRleHQuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZfcHJvZ3Jlc3NpdmUuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZfZXh0LmgiCisKKworQ1BERl9DdXN0b21BY2Nlc3M6OkNQREZfQ3VzdG9tQWNjZXNzKEZQREZfRklMRUFDQ0VTUyogcEZpbGVBY2Nlc3MpCit7CisJbV9GaWxlQWNjZXNzID0gKnBGaWxlQWNjZXNzOworCW1fQnVmZmVyT2Zmc2V0ID0gKEZYX0RXT1JEKS0xOworfQorCitGWF9CT09MIENQREZfQ3VzdG9tQWNjZXNzOjpHZXRCeXRlKEZYX0RXT1JEIHBvcywgRlhfQllURSYgY2gpCit7CisJaWYgKHBvcyA+PSBtX0ZpbGVBY2Nlc3MubV9GaWxlTGVuKSByZXR1cm4gRkFMU0U7CisJaWYgKG1fQnVmZmVyT2Zmc2V0ID09IChGWF9EV09SRCktMSB8fCBwb3MgPCBtX0J1ZmZlck9mZnNldCB8fCBwb3MgPj0gbV9CdWZmZXJPZmZzZXQgKyA1MTIpIHsKKwkJLy8gTmVlZCB0byByZWFkIGZyb20gZmlsZSBhY2Nlc3MKKwkJbV9CdWZmZXJPZmZzZXQgPSBwb3M7CisJCWludCBzaXplID0gNTEyOworCQlpZiAocG9zICsgNTEyID4gbV9GaWxlQWNjZXNzLm1fRmlsZUxlbikKKwkJCXNpemUgPSBtX0ZpbGVBY2Nlc3MubV9GaWxlTGVuIC0gcG9zOworCQlpZiAoIW1fRmlsZUFjY2Vzcy5tX0dldEJsb2NrKG1fRmlsZUFjY2Vzcy5tX1BhcmFtLCBtX0J1ZmZlck9mZnNldCwgbV9CdWZmZXIsIHNpemUpKQorCQkJcmV0dXJuIEZBTFNFOworCX0KKwljaCA9IG1fQnVmZmVyW3BvcyAtIG1fQnVmZmVyT2Zmc2V0XTsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDUERGX0N1c3RvbUFjY2Vzczo6R2V0QmxvY2soRlhfRFdPUkQgcG9zLCBGWF9MUEJZVEUgcEJ1ZiwgRlhfRFdPUkQgc2l6ZSkKK3sKKwlpZiAocG9zICsgc2l6ZSA+IG1fRmlsZUFjY2Vzcy5tX0ZpbGVMZW4pIHJldHVybiBGQUxTRTsKKwlyZXR1cm4gbV9GaWxlQWNjZXNzLm1fR2V0QmxvY2sobV9GaWxlQWNjZXNzLm1fUGFyYW0sIHBvcywgcEJ1Ziwgc2l6ZSk7Cit9CisKK0ZYX0JPT0wgQ1BERl9DdXN0b21BY2Nlc3M6OlJlYWRCbG9jayh2b2lkKiBidWZmZXIsIEZYX0ZJTEVTSVpFIG9mZnNldCwgc2l6ZV90IHNpemUpCit7CisJLy8JbV9GaWxlQWNjZXNzID0gKnBGaWxlQWNjZXNzOworCS8vCW1fQnVmZmVyT2Zmc2V0ID0gKEZYX0RXT1JEKS0xOworCWlmIChvZmZzZXQgKyBzaXplID4gbV9GaWxlQWNjZXNzLm1fRmlsZUxlbikgcmV0dXJuIEZBTFNFOworCXJldHVybiBtX0ZpbGVBY2Nlc3MubV9HZXRCbG9jayhtX0ZpbGVBY2Nlc3MubV9QYXJhbSwgb2Zmc2V0LChGWF9MUEJZVEUpIGJ1ZmZlciwgc2l6ZSk7CisKKwkvLwlyZXR1cm4gRkFMU0U7Cit9CisKKy8vMCBiaXQ6IEZQREZfUE9MSUNZX01BQ0hJTkVUSU1FX0FDQ0VTUworc3RhdGljIEZYX0RXT1JEIGZveGl0X3NhbmRib3hfcG9saWN5ID0gMHhGRkZGRkZGRjsKKwordm9pZCBGU0RLX1NldFNhbmRCb3hQb2xpY3koRlBERl9EV09SRCBwb2xpY3ksIEZQREZfQk9PTCBlbmFibGUpCit7CisJc3dpdGNoKHBvbGljeSkKKwl7CisJY2FzZSBGUERGX1BPTElDWV9NQUNISU5FVElNRV9BQ0NFU1M6CisJCXsKKwkJCWlmKGVuYWJsZSkKKwkJCQlmb3hpdF9zYW5kYm94X3BvbGljeSB8PSAweDAxOworCQkJZWxzZQorCQkJCWZveGl0X3NhbmRib3hfcG9saWN5ICY9IDB4RkZGRkZGRkU7CisJCX0KKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJYnJlYWs7CisJfQorfQorCitGUERGX0JPT0wgRlNES19Jc1NhbmRCb3hQb2xpY3lFbmFibGVkKEZQREZfRFdPUkQgcG9saWN5KQoreworCXN3aXRjaChwb2xpY3kpCisJeworCWNhc2UgRlBERl9QT0xJQ1lfTUFDSElORVRJTUVfQUNDRVNTOgorCQl7CisJCQlpZihmb3hpdF9zYW5kYm94X3BvbGljeSYweDAxKQorCQkJCXJldHVybiBUUlVFOworCQkJZWxzZQorCQkJCXJldHVybiBGQUxTRTsKKwkJfQorCQlicmVhazsKKwlkZWZhdWx0OgorCQlicmVhazsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCisKKyNpZm5kZWYgX1QKKyNkZWZpbmUgX1QoeCkgeAorI2VuZGlmCisKKyNpZmRlZiBBUEk1CisJQ1BERl9Nb2R1bGVNZ3IqCWdfcE1vZHVsZU1nciA9IE5VTEw7CisjZWxzZQorCUNDb2RlY19Nb2R1bGVNZ3IqCWdfcENvZGVjTW9kdWxlID0gTlVMTDsKKyNpZmRlZiBfRlhTREtfT1BFTlNPVVJDRV8KKwlGWE1FTV9Gb3hpdE1nciogZ19wRm94aXRNZ3IgPSBOVUxMOworI2VuZGlmCisjZW5kaWYKKworLy9leHRlcm4gQ1BERlNES19Gb3JtRmlsbEFwcCogZ19wRm9ybUZpbGxBcHA7CisKKyNpZiBfRlhfT1NfID09IF9GWF9MSU5VWF9FTUJFRERFRF8KK2NsYXNzIENGb250TWFwcGVyIDogcHVibGljIElQREZfRm9udE1hcHBlcgoreworcHVibGljOgorCUNGb250TWFwcGVyKCk7CisJdmlydHVhbCB+Q0ZvbnRNYXBwZXIoKTsKKworCXZpcnR1YWwgRlRfRmFjZSBGaW5kU3Vic3RGb250KAorCQkJCQkJCUNQREZfRG9jdW1lbnQqIHBEb2MsCQkJCS8vIFtJTl0gVGhlIFBERiBkb2N1bWVudAorCQkJCQkJCWNvbnN0IENGWF9CeXRlU3RyaW5nJiBmYWNlX25hbWUsCS8vIFtJTl0gT3JpZ2luYWwgbmFtZQorCQkJCQkJCUZYX0JPT0wgYlRydWVUeXBlLAkJCQkJLy8gW0lOXSBUcnVlVHlwZSBvciBUeXBlMQorCQkJCQkJCUZYX0RXT1JEIGZsYWdzLAkJCQkJCS8vIFtJTl0gUERGIGZvbnQgZmxhZ3MgKHNlZSBQREYgUmVmZXJlbmNlIHNlY3Rpb24gNS43LjEpCisJCQkJCQkJaW50IGZvbnRfd2VpZ2h0LAkJCQkJLy8gW0lOXSBvcmlnaW5hbCBmb250IHdlaWdodC4gMCBmb3Igbm90IHNwZWNpZmllZAorCQkJCQkJCWludCBDaGFyc2V0Q1AsCQkJCQkJLy8gW0lOXSBjb2RlIHBhZ2UgZm9yIGNoYXJzZXQgKHNlZSBXaW4zMiBHZXRBQ1AoKSkKKwkJCQkJCQlGWF9CT09MIGJWZXJ0aWNhbCwKKwkJCQkJCQlDUERGX1N1YnN0Rm9udCogcFN1YnN0Rm9udAkJCS8vIFtPVVRdIFN1YnN0IGZvbnQgZGF0YQorCQkJCQkJKTsKKworCUZUX0ZhY2UgbV9TeXNGYWNlOworfTsKKworQ0ZvbnRNYXBwZXIqIGdfcEZvbnRNYXBwZXIgPSBOVUxMOworI2VuZGlmCQkvLyAjaWYgX0ZYX09TXyA9PSBfRlhfTElOVVhfRU1CRURERURfCisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9Jbml0TGlicmFyeShGWF9MUFZPSUQgaEluc3RhbmNlKQoreworI2lmZGVmIEFQSTUKKwlDUERGX01vZHVsZU1ncjo6Q3JlYXRlKCk7CisJZ19wTW9kdWxlTWdyID0gQ1BERl9Nb2R1bGVNZ3I6OkdldCgpOworCSAjaWYgX0ZYX09TXyA9PSBfRlhfV0lOMzJfTU9CSUxFXyB8fCBfRlhfT1NfID09IF9GWF9MSU5VWF9FTUJFRERFRF8KKwkgCWdfcE1vZHVsZU1nci0+SW5pdEVtYmVkZGVkKCk7CisJICNpZmRlZiBfR0IxX0NNQVBTXworCSAJZ19wTW9kdWxlTWdyLT5Mb2FkRW1iZWRkZWRHQjFDTWFwcygpOworCSAjZW5kaWYKKwkgI2lmZGVmIF9HQjFfQ01BUFNfNF8KKwkgCWdfcE1vZHVsZU1nci0+TG9hZEVtYmVkZGVkR0IxQ01hcHNfNCgpOworCSAjZW5kaWYKKwkgI2lmZGVmIF9DTlMxX0NNQVBTXworCSAJZ19wTW9kdWxlTWdyLT5Mb2FkRW1iZWRkZWRDTlMxQ01hcHMoKTsKKwkgI2VuZGlmCisJICNpZmRlZiBfSkFQQU4xX0NNQVBTXworCSAJZ19wTW9kdWxlTWdyLT5Mb2FkRW1iZWRkZWRKYXBhbjFDTWFwcygpOworCSAjZW5kaWYKKwkgI2lmZGVmIF9KQVBBTjFfQ01BUFNfNl8KKwkgCWdfcE1vZHVsZU1nci0+TG9hZEVtYmVkZGVkSmFwYW4xQ01hcHNfNigpOworCSAjZW5kaWYKKwkgI2lmZGVmIF9LT1JFQTFfQ01BUFNfCisJIAlnX3BNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZEtvcmVhMUNNYXBzKCk7CisJICNlbmRpZgorCSAjaWZkZWYgX0pQWF9ERUNPREVSXworCSAJZ19wTW9kdWxlTWdyLT5Jbml0SnB4TW9kdWxlKCk7CisJIAlnX3BNb2R1bGVNZ3ItPkluaXRKYmlnMk1vZHVsZSgpOworCSAvLwlnX3BNb2R1bGVNZ3ItPkluaXRJY2NNb2R1bGUoKTsKKwkgI2VuZGlmCisJICNlbHNlCisJIAlnX3BNb2R1bGVNZ3ItPkluaXREZXNrdG9wKCk7CisJICNlbmRpZgorI2Vsc2UKKyNpZmRlZiBfRlhTREtfT1BFTlNPVVJDRV8KKwlnX3BGb3hpdE1nciA9IEZYTUVNX0NyZWF0ZU1lbW9yeU1ncigxMDI0ICogMTAyNCAqIDMyLCBUUlVFKTsKKyNlbmRpZgorCWdfcENvZGVjTW9kdWxlID0gQ0NvZGVjX01vZHVsZU1ncjo6Q3JlYXRlKCk7CisJCisJQ0ZYX0dFTW9kdWxlOjpDcmVhdGUoKTsKKwlDRlhfR0VNb2R1bGU6OkdldCgpLT5TZXRDb2RlY01vZHVsZShnX3BDb2RlY01vZHVsZSk7CisJCisJQ1BERl9Nb2R1bGVNZ3I6OkNyZWF0ZSgpOworCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+U2V0Q29kZWNNb2R1bGUoZ19wQ29kZWNNb2R1bGUpOworCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+SW5pdFBhZ2VNb2R1bGUoKTsKKwlDUERGX01vZHVsZU1ncjo6R2V0KCktPkluaXRSZW5kZXJNb2R1bGUoKTsKKyNpZmRlZiBGT1hJVF9DSFJPTUVfQlVJTEQKKwlDUERGX01vZHVsZU1nciAqIHBNb2R1bGVNZ3IgPSBDUERGX01vZHVsZU1ncjo6R2V0KCk7CisJaWYgKCBwTW9kdWxlTWdyICkKKwl7CisJCXBNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZEdCMUNNYXBzKCk7CisJCXBNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZEphcGFuMUNNYXBzKCk7CisJCXBNb2R1bGVNZ3ItPkxvYWRFbWJlZGRlZENOUzFDTWFwcygpOworCQlwTW9kdWxlTWdyLT5Mb2FkRW1iZWRkZWRLb3JlYTFDTWFwcygpOworCX0KKyNlbmRpZiAKKyNlbmRpZgorCisjaWZkZWYgX1dJTjMyCisJLy8gR2V0IG1vZHVsZSBwYXRoCisJVENIQVIgYXBwX3BhdGhbTUFYX1BBVEhdOworCTo6R2V0TW9kdWxlRmlsZU5hbWUoKEhJTlNUQU5DRSloSW5zdGFuY2UsIGFwcF9wYXRoLCBNQVhfUEFUSCk7CisJc2l6ZV90IGxlbiA9IF90Y3NsZW4oYXBwX3BhdGgpOworCWZvciAoc2l6ZV90IGkgPSBsZW47IGkgPj0gMDsgaSAtLSkKKwkJaWYgKGFwcF9wYXRoW2ldID09ICdcXCcpIHsKKwkJCWFwcF9wYXRoW2ldID0gMDsKKwkJCWJyZWFrOworCQl9CisJCQorI2lmZGVmIF9VTklDT0RFCisJCSNpZm5kZWYgX0ZYU0RLX09QRU5TT1VSQ0VfCisJCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+U2V0TW9kdWxlUGF0aChOVUxMLCBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoYXBwX3BhdGgpKTsKKwkJI2VuZGlmCisjZWxzZQorI2lmbmRlZiBfRlhTREtfT1BFTlNPVVJDRV8KKwkJQ1BERl9Nb2R1bGVNZ3I6OkdldCgpLT5TZXRNb2R1bGVQYXRoKE5VTEwsIGFwcF9wYXRoKTsKKyNlbmRpZgorI2VuZGlmCisjZW5kaWYKK30KKworCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfRGVzdHJveUxpYnJhcnkoKQoreworCisjaWYgX0ZYX09TXyA9PSBfRlhfTElOVVhfRU1CRURERURfCisJaWYgKGdfcEZvbnRNYXBwZXIpIGRlbGV0ZSBnX3BGb250TWFwcGVyOworI2VuZGlmCisjaWZkZWYgQVBJNQorCWdfcE1vZHVsZU1nci0+RGVzdHJveSgpOworI2Vsc2UKKwlDUERGX01vZHVsZU1ncjo6RGVzdHJveSgpOworCUNGWF9HRU1vZHVsZTo6RGVzdHJveSgpOworCWdfcENvZGVjTW9kdWxlLT5EZXN0cm95KCk7CisjZW5kaWYKKyNpZm5kZWYgX0ZYU0RLX09QRU5TT1VSQ0VfCisJRlhNRU1fQ29sbGVjdEFsbChGWE1FTV9HZXREZWZhdWx0TWdyKCkpOworI2Vsc2UKKwlGWE1FTV9EZXN0cm95Rm94aXRNZ3IoZ19wRm94aXRNZ3IpOworI2VuZGlmCit9CisKKyNpZm5kZWYgX1dJTjMyCitpbnQgZ19MYXN0RXJyb3I7Cit2b2lkIFNldExhc3RFcnJvcihpbnQgZXJyKQoreworCWdfTGFzdEVycm9yID0gZXJyOworfQorCitpbnQgR2V0TGFzdEVycm9yKCkKK3sKKwlyZXR1cm4gZ19MYXN0RXJyb3I7Cit9CisjZW5kaWYKKwordm9pZCBQcm9jZXNzUGFyc2VFcnJvcihGWF9EV09SRCBlcnJfY29kZSkKK3sKKwkvLyBUcmFuc2xhdGUgRlBERkFQSSBlcnJvciBjb2RlIHRvIEZQREZWSUVXIGVycm9yIGNvZGUKKwlzd2l0Y2ggKGVycl9jb2RlKSB7CisJCWNhc2UgUERGUEFSU0VfRVJST1JfRklMRToKKwkJCWVycl9jb2RlID0gRlBERl9FUlJfRklMRTsKKwkJCWJyZWFrOworCQljYXNlIFBERlBBUlNFX0VSUk9SX0ZPUk1BVDoKKwkJCWVycl9jb2RlID0gRlBERl9FUlJfRk9STUFUOworCQkJYnJlYWs7CisJCWNhc2UgUERGUEFSU0VfRVJST1JfUEFTU1dPUkQ6CisJCQllcnJfY29kZSA9IEZQREZfRVJSX1BBU1NXT1JEOworCQkJYnJlYWs7CisJCWNhc2UgUERGUEFSU0VfRVJST1JfSEFORExFUjoKKwkJCWVycl9jb2RlID0gRlBERl9FUlJfU0VDVVJJVFk7CisJCQlicmVhazsKKwl9CisJU2V0TGFzdEVycm9yKGVycl9jb2RlKTsKK30KKworRExMRVhQT1JUIHZvaWQJU1REQ0FMTCBGUERGX1NldFNhbmRCb3hQb2xpY3koRlBERl9EV09SRCBwb2xpY3ksIEZQREZfQk9PTCBlbmFibGUpCit7CisJcmV0dXJuIEZTREtfU2V0U2FuZEJveFBvbGljeShwb2xpY3ksIGVuYWJsZSk7Cit9CisKK0RMTEVYUE9SVCBGUERGX0RPQ1VNRU5UIFNURENBTEwgRlBERl9Mb2FkRG9jdW1lbnQoRlBERl9TVFJJTkcgZmlsZV9wYXRoLCBGUERGX0JZVEVTVFJJTkcgcGFzc3dvcmQpCit7CisJQ1BERl9QYXJzZXIqIHBQYXJzZXIgPSBGWF9ORVcgQ1BERl9QYXJzZXI7CisJcFBhcnNlci0+U2V0UGFzc3dvcmQocGFzc3dvcmQpOworCXRyeSB7CisJCUZYX0RXT1JEIGVycl9jb2RlID0gcFBhcnNlci0+U3RhcnRQYXJzZSgoRlhfTFBDU1RSKWZpbGVfcGF0aCk7CisJCWlmIChlcnJfY29kZSkgeworCQkJZGVsZXRlIHBQYXJzZXI7CisJCQlQcm9jZXNzUGFyc2VFcnJvcihlcnJfY29kZSk7CisJCQlyZXR1cm4gTlVMTDsKKwkJfQorCX0KKwljYXRjaCAoLi4uKSB7CisJCWRlbGV0ZSBwUGFyc2VyOworCQlTZXRMYXN0RXJyb3IoRlBERl9FUlJfVU5LTk9XTik7CisJCXJldHVybiBOVUxMOworCX0KKwlyZXR1cm4gcFBhcnNlci0+R2V0RG9jdW1lbnQoKTsKK30KKworZXh0ZXJuIHZvaWQgQ2hlY2tVblN1cHBvcnRFcnJvcihDUERGX0RvY3VtZW50ICogcERvYywgRlhfRFdPUkQgZXJyX2NvZGUpOworCitjbGFzcyBDTWVtRmlsZTogcHVibGljIElGWF9GaWxlUmVhZCwgcHVibGljIENGWF9PYmplY3QKK3sKK3B1YmxpYzoKKwlDTWVtRmlsZShGWF9CWVRFKiBwQnVmLCBGWF9GSUxFU0laRSBzaXplKTptX3BCdWYocEJ1ZiksbV9zaXplKHNpemUpIHt9CisKKwl2aXJ0dWFsIHZvaWQJCQlSZWxlYXNlKCkge2RlbGV0ZSB0aGlzO30KKwl2aXJ0dWFsIEZYX0ZJTEVTSVpFCQlHZXRTaXplKCkge3JldHVybiBtX3NpemU7fQorCXZpcnR1YWwgRlhfQk9PTAkJCVJlYWRCbG9jayh2b2lkKiBidWZmZXIsIEZYX0ZJTEVTSVpFIG9mZnNldCwgc2l6ZV90IHNpemUpIAorCXsKKwkJaWYob2Zmc2V0K3NpemUgPiAoRlhfRFdPUkQpbV9zaXplKSByZXR1cm4gRkFMU0U7CisJCUZYU1lTX21lbWNweShidWZmZXIsIG1fcEJ1ZitvZmZzZXQsIHNpemUpOworCQlyZXR1cm4gVFJVRTsKKwl9Citwcml2YXRlOgorCUZYX0JZVEUqIG1fcEJ1ZjsKKwlGWF9GSUxFU0laRSBtX3NpemU7Cit9OworRExMRVhQT1JUIEZQREZfRE9DVU1FTlQgU1REQ0FMTCBGUERGX0xvYWRNZW1Eb2N1bWVudChjb25zdCB2b2lkKiBkYXRhX2J1ZiwgaW50IHNpemUsIEZQREZfQllURVNUUklORyBwYXNzd29yZCkKK3sKKwlDUERGX1BhcnNlciogcFBhcnNlciA9IEZYX05FVyBDUERGX1BhcnNlcjsKKwlwUGFyc2VyLT5TZXRQYXNzd29yZChwYXNzd29yZCk7CisJdHJ5IHsKKwkJQ01lbUZpbGUqIHBNZW1GaWxlID0gRlhfTkVXIENNZW1GaWxlKChGWF9CWVRFKilkYXRhX2J1Ziwgc2l6ZSk7CisJCUZYX0RXT1JEIGVycl9jb2RlID0gcFBhcnNlci0+U3RhcnRQYXJzZShwTWVtRmlsZSk7CisJCWlmIChlcnJfY29kZSkgeworCQkJZGVsZXRlIHBQYXJzZXI7CisJCQlQcm9jZXNzUGFyc2VFcnJvcihlcnJfY29kZSk7CisJCQlyZXR1cm4gTlVMTDsKKwkJfQorCQlDUERGX0RvY3VtZW50ICogcERvYyA9IE5VTEw7CisJCXBEb2MgPSBwUGFyc2VyP3BQYXJzZXItPkdldERvY3VtZW50KCk6TlVMTDsKKwkJQ2hlY2tVblN1cHBvcnRFcnJvcihwRG9jLCBlcnJfY29kZSk7CisJfQorCWNhdGNoICguLi4pIHsKKwkJZGVsZXRlIHBQYXJzZXI7CisJCVNldExhc3RFcnJvcihGUERGX0VSUl9VTktOT1dOKTsKKwkJcmV0dXJuIE5VTEw7CisJfQorCXJldHVybiBwUGFyc2VyLT5HZXREb2N1bWVudCgpOworfQorCitETExFWFBPUlQgRlBERl9ET0NVTUVOVCBTVERDQUxMIEZQREZfTG9hZEN1c3RvbURvY3VtZW50KEZQREZfRklMRUFDQ0VTUyogcEZpbGVBY2Nlc3MsIEZQREZfQllURVNUUklORyBwYXNzd29yZCkKK3sKKwlDUERGX1BhcnNlciogcFBhcnNlciA9IEZYX05FVyBDUERGX1BhcnNlcjsKKwlwUGFyc2VyLT5TZXRQYXNzd29yZChwYXNzd29yZCk7CisJQ1BERl9DdXN0b21BY2Nlc3MqIHBGaWxlID0gRlhfTkVXIENQREZfQ3VzdG9tQWNjZXNzKHBGaWxlQWNjZXNzKTsKKwl0cnkgeworCQlGWF9EV09SRCBlcnJfY29kZSA9IHBQYXJzZXItPlN0YXJ0UGFyc2UocEZpbGUpOworCQlpZiAoZXJyX2NvZGUpIHsKKwkJCWRlbGV0ZSBwUGFyc2VyOworCQkJUHJvY2Vzc1BhcnNlRXJyb3IoZXJyX2NvZGUpOworCQkJcmV0dXJuIE5VTEw7CisJCX0KKwkJQ1BERl9Eb2N1bWVudCAqIHBEb2MgPSBOVUxMOworCQlwRG9jID0gcFBhcnNlcj9wUGFyc2VyLT5HZXREb2N1bWVudCgpOk5VTEw7CisJCUNoZWNrVW5TdXBwb3J0RXJyb3IocERvYywgZXJyX2NvZGUpOworCX0KKwljYXRjaCAoLi4uKSB7CisJCWRlbGV0ZSBwUGFyc2VyOworCQlTZXRMYXN0RXJyb3IoRlBERl9FUlJfVU5LTk9XTik7CisJCXJldHVybiBOVUxMOworCX0KKwlyZXR1cm4gcFBhcnNlci0+R2V0RG9jdW1lbnQoKTsKK30KKworRExMRVhQT1JUIEZQREZfQk9PTCBTVERDQUxMIEZQREZfR2V0RmlsZVZlcnNpb24oRlBERl9ET0NVTUVOVCBkb2MsIGludCogZmlsZVZlcnNpb24pCit7CisJaWYoIWRvY3x8IWZpbGVWZXJzaW9uKSByZXR1cm4gRkFMU0U7CisJKmZpbGVWZXJzaW9uID0gMDsKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvYzsKKwlDUERGX1BhcnNlciogcFBhcnNlciA9IChDUERGX1BhcnNlciopcERvYy0+R2V0UGFyc2VyKCk7CisJaWYoIXBQYXJzZXIpCisJCXJldHVybiBGQUxTRTsKKwkqZmlsZVZlcnNpb24gPSBwUGFyc2VyLT5HZXRGaWxlVmVyc2lvbigpOworCXJldHVybiBUUlVFOworfQorCisvLyBqYWJkZWxtYWxlazogY2hhbmdlZCByZXR1cm4gdHlwZSBmcm9tIEZYX0RXT1JEIHRvIGJ1aWxkIG9uIExpbnV4IChhbmQgbWF0Y2ggaGVhZGVyKS4KK0RMTEVYUE9SVCB1bnNpZ25lZCBsb25nIFNURENBTEwgRlBERl9HZXREb2NQZXJtaXNzaW9ucyhGUERGX0RPQ1VNRU5UIGRvY3VtZW50KQoreworCWlmIChkb2N1bWVudCA9PSBOVUxMKSByZXR1cm4gMDsKKwlDUERGX0RvY3VtZW50KnBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7CisJQ1BERl9QYXJzZXIqIHBQYXJzZXIgPSAJKENQREZfUGFyc2VyKilwRG9jLT5HZXRQYXJzZXIoKTsKKwlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gcFBhcnNlci0+R2V0RW5jcnlwdERpY3QoKTsKKwlpZiAocERpY3QgPT0gTlVMTCkgcmV0dXJuIChGWF9EV09SRCktMTsKKworCXJldHVybiBwRGljdC0+R2V0SW50ZWdlcigiUCIpOworfQorCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERl9HZXRQYWdlQ291bnQoRlBERl9ET0NVTUVOVCBkb2N1bWVudCkKK3sKKwlpZiAoZG9jdW1lbnQgPT0gTlVMTCkgcmV0dXJuIDA7CisJcmV0dXJuICgoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQpLT5HZXRQYWdlQ291bnQoKTsKK30KKworRExMRVhQT1JUIEZQREZfUEFHRSBTVERDQUxMIEZQREZfTG9hZFBhZ2UoRlBERl9ET0NVTUVOVCBkb2N1bWVudCwgaW50IHBhZ2VfaW5kZXgpCit7CisJaWYgKGRvY3VtZW50ID09IE5VTEwpIHJldHVybiBOVUxMOworCWlmIChwYWdlX2luZGV4IDwgMCB8fCBwYWdlX2luZGV4ID49IEZQREZfR2V0UGFnZUNvdW50KGRvY3VtZW50KSkgcmV0dXJuIE5VTEw7CisvLwlDUERGX1BhcnNlciogcFBhcnNlciA9IChDUERGX1BhcnNlciopZG9jdW1lbnQ7CisJQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsKKwlpZiAocERvYyA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKwlDUERGX0RpY3Rpb25hcnkqIHBEaWN0ID0gcERvYy0+R2V0UGFnZShwYWdlX2luZGV4KTsKKwlpZiAocERpY3QgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisJQ1BERl9QYWdlKiBwUGFnZSA9IEZYX05FVyBDUERGX1BhZ2U7CisJcFBhZ2UtPkxvYWQocERvYywgcERpY3QpOworCXRyeSB7CisJCXBQYWdlLT5QYXJzZUNvbnRlbnQoKTsKKwl9CisJY2F0Y2ggKC4uLikgeworCQlkZWxldGUgcFBhZ2U7CisJCXJldHVybiBOVUxMOworCX0KKwkKKy8vCUNoZWNrVW5TdXBwb3J0RXJyb3IocERvYywgMCk7CisKKwlyZXR1cm4gcFBhZ2U7Cit9CisKK0RMTEVYUE9SVCBkb3VibGUgU1REQ0FMTCBGUERGX0dldFBhZ2VXaWR0aChGUERGX1BBR0UgcGFnZSkKK3sKKwlpZiAoIXBhZ2UpCisJCXJldHVybiAwLjA7CisJcmV0dXJuICgoQ1BERl9QYWdlKilwYWdlKS0+R2V0UGFnZVdpZHRoKCk7Cit9CisKK0RMTEVYUE9SVCBkb3VibGUgU1REQ0FMTCBGUERGX0dldFBhZ2VIZWlnaHQoRlBERl9QQUdFIHBhZ2UpCit7CisJaWYgKCFwYWdlKSByZXR1cm4gMC4wOworCXJldHVybiAoKENQREZfUGFnZSopcGFnZSktPkdldFBhZ2VIZWlnaHQoKTsKK30KKwordm9pZCBEcm9wQ29udGV4dCh2b2lkKiBkYXRhKQoreworCWRlbGV0ZSAoQ1JlbmRlckNvbnRleHQqKWRhdGE7Cit9CisKK3ZvaWQgRlBERl9SZW5kZXJQYWdlX1JldGFpbChDUmVuZGVyQ29udGV4dCogcENvbnRleHQsIEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIGludCBzaXplX3gsIGludCBzaXplX3ksCisJCQkJCQlpbnQgcm90YXRlLCBpbnQgZmxhZ3MsRlhfQk9PTCBiTmVlZFRvUmVzdG9yZSwgSUZTREtfUEFVU0VfQWRhcHRlciAqIHBhdXNlICApOwordm9pZCAoKkZ1bmNfUmVuZGVyUGFnZSkoQ1JlbmRlckNvbnRleHQqLCBGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCBpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LAorCQkJCQkJaW50IHJvdGF0ZSwgaW50IGZsYWdzLEZYX0JPT0wgYk5lZWRUb1Jlc3RvcmUsIElGU0RLX1BBVVNFX0FkYXB0ZXIgKiBwYXVzZSAgKSA9IEZQREZfUmVuZGVyUGFnZV9SZXRhaWw7CisKKyNpZiBkZWZpbmVkKF9ERUJVRykgfHwgZGVmaW5lZChERUJVRykKKyNkZWZpbmUgREVCVUdfVFJBQ0UKKyNlbmRpZgorCisjaWYgZGVmaW5lZChfV0lOMzIpCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfUmVuZGVyUGFnZShIREMgZGMsIEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIGludCBzaXplX3gsIGludCBzaXplX3ksCisJCQkJCQlpbnQgcm90YXRlLCBpbnQgZmxhZ3MpCit7CisJaWYgKHBhZ2U9PU5VTEwpIHJldHVybjsKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKworCUNSZW5kZXJDb250ZXh0KiBwQ29udGV4dCA9IEZYX05FVyBDUmVuZGVyQ29udGV4dDsKKwlwUGFnZS0+U2V0UHJpdmF0ZURhdGEoKHZvaWQqKTEsIHBDb250ZXh0LCBEcm9wQ29udGV4dCk7CisKKyNpZm5kZWYgX1dJTjMyX1dDRQorCUNGWF9ESUJpdG1hcCogcEJpdG1hcCA9IE5VTEw7CisJRlhfQk9PTCBiQmFja2dyb3VuZEFscGhhTmVlZGVkPUZBTFNFOworCWJCYWNrZ3JvdW5kQWxwaGFOZWVkZWQgPSBwUGFnZS0+QmFja2dyb3VuZEFscGhhTmVlZGVkKCk7CisJaWYgKGJCYWNrZ3JvdW5kQWxwaGFOZWVkZWQpCisJeworCQkKKwkJcEJpdG1hcCA9IEZYX05FVyBDRlhfRElCaXRtYXA7CisJCXBCaXRtYXAtPkNyZWF0ZShzaXplX3gsIHNpemVfeSwgRlhESUJfQXJnYik7CisJCXBCaXRtYXAtPkNsZWFyKDB4MDBmZmZmZmYpOworI2lmZGVmIF9TS0lBX1NVUFBPUlRfCisJCXBDb250ZXh0LT5tX3BEZXZpY2UgPSBGWF9ORVcgQ0ZYX1NraWFEZXZpY2U7CisJCSgoQ0ZYX1NraWFEZXZpY2UqKXBDb250ZXh0LT5tX3BEZXZpY2UpLT5BdHRhY2goKENGWF9ESUJpdG1hcCopcEJpdG1hcCk7CisjZWxzZQorCQlwQ29udGV4dC0+bV9wRGV2aWNlID0gRlhfTkVXIENGWF9GeGdlRGV2aWNlOworCQkoKENGWF9GeGdlRGV2aWNlKilwQ29udGV4dC0+bV9wRGV2aWNlKS0+QXR0YWNoKChDRlhfRElCaXRtYXAqKXBCaXRtYXApOworI2VuZGlmCisJfQorCWVsc2UKKwlwQ29udGV4dC0+bV9wRGV2aWNlID0gRlhfTkVXIENGWF9XaW5kb3dzRGV2aWNlKGRjKTsKKwlpZiAoZmxhZ3MgJiBGUERGX05PX0NBVENIKQorCQlGdW5jX1JlbmRlclBhZ2UocENvbnRleHQsIHBhZ2UsIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95LCByb3RhdGUsIGZsYWdzLFRSVUUsTlVMTCk7CisJZWxzZSB7CisJCXRyeSB7CisJCQlGdW5jX1JlbmRlclBhZ2UocENvbnRleHQsIHBhZ2UsIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95LCByb3RhdGUsIGZsYWdzLFRSVUUsTlVMTCk7CisJCX0gY2F0Y2ggKC4uLikgeworCQl9CisJfQorCWlmIChiQmFja2dyb3VuZEFscGhhTmVlZGVkKSAKKwl7CisJCWlmIChwQml0bWFwKQorCQl7CisJCQlDRlhfV2luZG93c0RldmljZSBXaW5EQyhkYyk7CisJCQkKKyAJCQlpZiAoV2luREMuR2V0RGV2aWNlQ2FwcyhGWERDX0RFVklDRV9DTEFTUykgPT0gRlhEQ19QUklOVEVSKQorIAkJCXsKKwkJCQlDRlhfRElCaXRtYXAqIHBEc3QgPSBGWF9ORVcgQ0ZYX0RJQml0bWFwOworCQkJCXBEc3QtPkNyZWF0ZShwQml0bWFwLT5HZXRXaWR0aCgpLCBwQml0bWFwLT5HZXRIZWlnaHQoKSxGWERJQl9SZ2IzMik7CisJCQkJRlhTWVNfbWVtY3B5KHBEc3QtPkdldEJ1ZmZlcigpLCBwQml0bWFwLT5HZXRCdWZmZXIoKSwgcEJpdG1hcC0+R2V0UGl0Y2goKSpwQml0bWFwLT5HZXRIZWlnaHQoKSk7CisvLwkJCQlXaW5EQy5TZXRESUJpdHMocERzdCwwLDApOworCQkJCVdpbkRDLlN0cmV0Y2hESUJpdHMocERzdCwwLDAsc2l6ZV94KjIsc2l6ZV95KjIpOworCQkJCWRlbGV0ZSBwRHN0OworIAkJCX0KKyAJCQllbHNlCisgCQkJCVdpbkRDLlNldERJQml0cyhwQml0bWFwLDAsMCk7CisKKwkJfQorCX0KKyNlbHNlCisJLy8gZ2V0IGNsaXAgcmVnaW9uCisJUkVDVCByZWN0LCBjbGlwcmVjdDsKKwlyZWN0LmxlZnQgPSBzdGFydF94OworCXJlY3QudG9wID0gc3RhcnRfeTsKKwlyZWN0LnJpZ2h0ID0gc3RhcnRfeCArIHNpemVfeDsKKwlyZWN0LmJvdHRvbSA9IHN0YXJ0X3kgKyBzaXplX3k7CisJR2V0Q2xpcEJveChkYywgJmNsaXByZWN0KTsKKwlJbnRlcnNlY3RSZWN0KCZyZWN0LCAmcmVjdCwgJmNsaXByZWN0KTsKKwlpbnQgd2lkdGggPSByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0OworCWludCBoZWlnaHQgPSByZWN0LmJvdHRvbSAtIHJlY3QudG9wOworCisjaWZkZWYgREVCVUdfVFJBQ0UKKwl7CisJCWNoYXIgc3RyWzEyOF07CisJCXNwcmludGYoc3RyLCAiUmVuZGVyaW5nIERJQiAlZCB4ICVkIiwgd2lkdGgsIGhlaWdodCk7CisJCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+UmVwb3J0RXJyb3IoOTk5LCBzdHIpOworCX0KKyNlbmRpZgorCisJLy8gQ3JlYXRlIGEgRElCIHNlY3Rpb24KKwlMUFZPSUQgcEJ1ZmZlcjsKKwlCSVRNQVBJTkZPSEVBREVSIGJtaWg7CisJRlhTWVNfbWVtc2V0KCZibWloLCAwLCBzaXplb2YgYm1paCk7CisJYm1paC5iaVNpemUgPSBzaXplb2YgYm1paDsKKwlibWloLmJpQml0Q291bnQgPSAyNDsKKwlibWloLmJpSGVpZ2h0ID0gLWhlaWdodDsKKwlibWloLmJpUGxhbmVzID0gMTsKKwlibWloLmJpV2lkdGggPSB3aWR0aDsKKwlwQ29udGV4dC0+bV9oQml0bWFwID0gQ3JlYXRlRElCU2VjdGlvbihkYywgKEJJVE1BUElORk8qKSZibWloLCBESUJfUkdCX0NPTE9SUywgJnBCdWZmZXIsIE5VTEwsIDApOworCWlmIChwQ29udGV4dC0+bV9oQml0bWFwID09IE5VTEwpIHsKKyNpZiBkZWZpbmVkKERFQlVHKSB8fCBkZWZpbmVkKF9ERUJVRykKKwkJY2hhciBzdHJbMTI4XTsKKwkJc3ByaW50ZihzdHIsICJFcnJvciBDcmVhdGVESUJTZWN0aW9uOiAlZCB4ICVkLCBlcnJvciBjb2RlID0gJWQiLCB3aWR0aCwgaGVpZ2h0LCBHZXRMYXN0RXJyb3IoKSk7CisJCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+UmVwb3J0RXJyb3IoRlBERkVSUl9PVVRfT0ZfTUVNT1JZLCBzdHIpOworI2Vsc2UKKwkJQ1BERl9Nb2R1bGVNZ3I6OkdldCgpLT5SZXBvcnRFcnJvcihGUERGRVJSX09VVF9PRl9NRU1PUlksIE5VTEwpOworI2VuZGlmCisJfQorCUZYU1lTX21lbXNldChwQnVmZmVyLCAweGZmLCBoZWlnaHQqKCh3aWR0aCozKzMpLzQqNCkpOworCisjaWZkZWYgREVCVUdfVFJBQ0UKKwl7CisJCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+UmVwb3J0RXJyb3IoOTk5LCAiRElCU2VjdGlvbiBjcmVhdGVkIik7CisJfQorI2VuZGlmCisKKwkvLyBDcmVhdGUgYSBkZXZpY2Ugd2l0aCB0aGlzIGV4dGVybmFsIGJ1ZmZlcgorCXBDb250ZXh0LT5tX3BCaXRtYXAgPSBGWF9ORVcgQ0ZYX0RJQml0bWFwOworCXBDb250ZXh0LT5tX3BCaXRtYXAtPkNyZWF0ZSh3aWR0aCwgaGVpZ2h0LCBGWERJQl9SZ2IsIChGWF9MUEJZVEUpcEJ1ZmZlcik7CisJcENvbnRleHQtPm1fcERldmljZSA9IEZYX05FVyBDUERGX0Z4Z2VEZXZpY2U7CisJKChDUERGX0Z4Z2VEZXZpY2UqKXBDb250ZXh0LT5tX3BEZXZpY2UpLT5BdHRhY2gocENvbnRleHQtPm1fcEJpdG1hcCk7CisJCisjaWZkZWYgREVCVUdfVFJBQ0UKKwlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKDk5OSwgIlJlYWR5IGZvciBQREYgcmVuZGVyaW5nIik7CisjZW5kaWYKKworCS8vIG91dHB1dCB0byBiaXRtYXAgZGV2aWNlCisJaWYgKGZsYWdzICYgRlBERl9OT19DQVRDSCkKKwkJRnVuY19SZW5kZXJQYWdlKHBDb250ZXh0LCBwYWdlLCBzdGFydF94IC0gcmVjdC5sZWZ0LCBzdGFydF95IC0gcmVjdC50b3AsIHNpemVfeCwgc2l6ZV95LCByb3RhdGUsIGZsYWdzKTsKKwllbHNlIHsKKwkJdHJ5IHsKKwkJCUZ1bmNfUmVuZGVyUGFnZShwQ29udGV4dCwgcGFnZSwgc3RhcnRfeCAtIHJlY3QubGVmdCwgc3RhcnRfeSAtIHJlY3QudG9wLCBzaXplX3gsIHNpemVfeSwgcm90YXRlLCBmbGFncyk7CisJCX0gY2F0Y2ggKC4uLikgeworCQl9CisJfQorCisjaWZkZWYgREVCVUdfVFJBQ0UKKwlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKDk5OSwgIkZpbmlzaGVkIFBERiByZW5kZXJpbmciKTsKKyNlbmRpZgorCisJLy8gTm93IG91dHB1dCB0byByZWFsIGRldmljZQorCUhEQyBoTWVtREMgPSBDcmVhdGVDb21wYXRpYmxlREMoZGMpOworCWlmIChoTWVtREMgPT0gTlVMTCkgeworI2lmIGRlZmluZWQoREVCVUcpIHx8IGRlZmluZWQoX0RFQlVHKQorCQljaGFyIHN0clsxMjhdOworCQlzcHJpbnRmKHN0ciwgIkVycm9yIENyZWF0ZUNvbXBhdGlibGVEQy4gRXJyb3IgY29kZSA9ICVkIiwgR2V0TGFzdEVycm9yKCkpOworCQlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKEZQREZFUlJfT1VUX09GX01FTU9SWSwgc3RyKTsKKyNlbHNlCisJCUNQREZfTW9kdWxlTWdyOjpHZXQoKS0+UmVwb3J0RXJyb3IoRlBERkVSUl9PVVRfT0ZfTUVNT1JZLCBOVUxMKTsKKyNlbmRpZgorCX0KKworCUhHRElPQkogaE9sZEJpdG1hcCA9IFNlbGVjdE9iamVjdChoTWVtREMsIHBDb250ZXh0LT5tX2hCaXRtYXApOworCisjaWZkZWYgREVCVUdfVFJBQ0UKKwlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKDk5OSwgIlJlYWR5IGZvciBzY3JlZW4gcmVuZGVyaW5nIik7CisjZW5kaWYKKworCUJpdEJsdChkYywgcmVjdC5sZWZ0LCByZWN0LnRvcCwgd2lkdGgsIGhlaWdodCwgaE1lbURDLCAwLCAwLCBTUkNDT1BZKTsKKwlTZWxlY3RPYmplY3QoaE1lbURDLCBoT2xkQml0bWFwKTsKKwlEZWxldGVEQyhoTWVtREMpOworCisjaWZkZWYgREVCVUdfVFJBQ0UKKwlDUERGX01vZHVsZU1ncjo6R2V0KCktPlJlcG9ydEVycm9yKDk5OSwgIkZpbmlzaGVkIHNjcmVlbiByZW5kZXJpbmciKTsKKyNlbmRpZgorCisjZW5kaWYKKwlpZiAoYkJhY2tncm91bmRBbHBoYU5lZWRlZCkKKwl7CisJCWlmIChwQml0bWFwKQorCQkJZGVsZXRlIHBCaXRtYXA7CisJCXBCaXRtYXAgPSBOVUxMOworCX0KKwlkZWxldGUgcENvbnRleHQ7CisJcFBhZ2UtPlJlbW92ZVByaXZhdGVEYXRhKCh2b2lkKikxKTsKK30KKyNlbmRpZgorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfUmVuZGVyUGFnZUJpdG1hcChGUERGX0JJVE1BUCBiaXRtYXAsIEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIAorCQkJCQkJaW50IHNpemVfeCwgaW50IHNpemVfeSwgaW50IHJvdGF0ZSwgaW50IGZsYWdzKQoreworCWlmIChiaXRtYXAgPT0gTlVMTCB8fCBwYWdlID09IE5VTEwpIHJldHVybjsKKwlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcGFnZTsKKworCisJQ1JlbmRlckNvbnRleHQqIHBDb250ZXh0ID0gRlhfTkVXIENSZW5kZXJDb250ZXh0OworCXBQYWdlLT5TZXRQcml2YXRlRGF0YSgodm9pZCopMSwgcENvbnRleHQsIERyb3BDb250ZXh0KTsKKyNpZmRlZiBfU0tJQV9TVVBQT1JUXworCXBDb250ZXh0LT5tX3BEZXZpY2UgPSBGWF9ORVcgQ0ZYX1NraWFEZXZpY2U7CisKKwlpZiAoZmxhZ3MgJiBGUERGX1JFVkVSU0VfQllURV9PUkRFUikKKwkJKChDRlhfU2tpYURldmljZSopcENvbnRleHQtPm1fcERldmljZSktPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXAsMCxUUlVFKTsKKwllbHNlCisJCSgoQ0ZYX1NraWFEZXZpY2UqKXBDb250ZXh0LT5tX3BEZXZpY2UpLT5BdHRhY2goKENGWF9ESUJpdG1hcCopYml0bWFwKTsKKyNlbHNlCisJcENvbnRleHQtPm1fcERldmljZSA9IEZYX05FVyBDRlhfRnhnZURldmljZTsKKworCWlmIChmbGFncyAmIEZQREZfUkVWRVJTRV9CWVRFX09SREVSKQorCQkoKENGWF9GeGdlRGV2aWNlKilwQ29udGV4dC0+bV9wRGV2aWNlKS0+QXR0YWNoKChDRlhfRElCaXRtYXAqKWJpdG1hcCwwLFRSVUUpOworCWVsc2UKKwkJKChDRlhfRnhnZURldmljZSopcENvbnRleHQtPm1fcERldmljZSktPkF0dGFjaCgoQ0ZYX0RJQml0bWFwKiliaXRtYXApOworI2VuZGlmCisJaWYgKGZsYWdzICYgRlBERl9OT19DQVRDSCkKKwkJRnVuY19SZW5kZXJQYWdlKHBDb250ZXh0LCBwYWdlLCBzdGFydF94LCBzdGFydF95LCBzaXplX3gsIHNpemVfeSwgcm90YXRlLCBmbGFncyxUUlVFLE5VTEwpOworCWVsc2UgeworCQl0cnkgeworCQkJRnVuY19SZW5kZXJQYWdlKHBDb250ZXh0LCBwYWdlLCBzdGFydF94LCBzdGFydF95LCBzaXplX3gsIHNpemVfeSwgcm90YXRlLCBmbGFncyxUUlVFLE5VTEwpOworCQl9IGNhdGNoICguLi4pIHsKKwkJfQorCX0KKworCWRlbGV0ZSBwQ29udGV4dDsKKwlwUGFnZS0+UmVtb3ZlUHJpdmF0ZURhdGEoKHZvaWQqKTEpOworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfQ2xvc2VQYWdlKEZQREZfUEFHRSBwYWdlKQoreworCWlmICghcGFnZSkgcmV0dXJuOworCWRlbGV0ZSAoQ1BERl9QYWdlKilwYWdlOworCit9CisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERl9DbG9zZURvY3VtZW50KEZQREZfRE9DVU1FTlQgZG9jdW1lbnQpCit7CisJaWYgKCFkb2N1bWVudCkKKwkJcmV0dXJuOworCUNQREZfRG9jdW1lbnQqIHBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7CQorCUNQREZfUGFyc2VyKiBwUGFyc2VyID0gKENQREZfUGFyc2VyKilwRG9jLT5HZXRQYXJzZXIoKTsKKwlpZiAocFBhcnNlciA9PSBOVUxMKSAKKwl7CisJCWRlbGV0ZSBwRG9jOworCQlyZXR1cm47CisJfQorCWRlbGV0ZSBwUGFyc2VyOworLy8JZGVsZXRlIHBEb2M7Cit9CisKK0RMTEVYUE9SVCB1bnNpZ25lZCBsb25nIFNURENBTEwgRlBERl9HZXRMYXN0RXJyb3IoKQoreworCXJldHVybiBHZXRMYXN0RXJyb3IoKTsKK30KKworRExMRVhQT1JUIHZvaWQgU1REQ0FMTCBGUERGX0RldmljZVRvUGFnZShGUERGX1BBR0UgcGFnZSwgaW50IHN0YXJ0X3gsIGludCBzdGFydF95LCBpbnQgc2l6ZV94LCBpbnQgc2l6ZV95LAorCQkJCQkJaW50IHJvdGF0ZSwgaW50IGRldmljZV94LCBpbnQgZGV2aWNlX3ksIGRvdWJsZSogcGFnZV94LCBkb3VibGUqIHBhZ2VfeSkKK3sKKwlpZiAocGFnZSA9PSBOVUxMIHx8IHBhZ2VfeCA9PSBOVUxMIHx8IHBhZ2VfeSA9PSBOVUxMKSByZXR1cm47CisJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7CisKKwlDUERGX01hdHJpeCBwYWdlMmRldmljZTsKKwlwUGFnZS0+R2V0RGlzcGxheU1hdHJpeChwYWdlMmRldmljZSwgc3RhcnRfeCwgc3RhcnRfeSwgc2l6ZV94LCBzaXplX3ksIHJvdGF0ZSk7CisJQ1BERl9NYXRyaXggZGV2aWNlMnBhZ2U7CisJZGV2aWNlMnBhZ2UuU2V0UmV2ZXJzZShwYWdlMmRldmljZSk7CisKKwlGWF9GTE9BVCBwYWdlX3hfZiwgcGFnZV95X2Y7CisJZGV2aWNlMnBhZ2UuVHJhbnNmb3JtKChGWF9GTE9BVCkoZGV2aWNlX3gpLCAoRlhfRkxPQVQpKGRldmljZV95KSwgcGFnZV94X2YsIHBhZ2VfeV9mKTsKKworCSpwYWdlX3ggPSAocGFnZV94X2YpOworCSpwYWdlX3kgPSAocGFnZV95X2YpOworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZfUGFnZVRvRGV2aWNlKEZQREZfUEFHRSBwYWdlLCBpbnQgc3RhcnRfeCwgaW50IHN0YXJ0X3ksIGludCBzaXplX3gsIGludCBzaXplX3ksCisJCQkJCQlpbnQgcm90YXRlLCBkb3VibGUgcGFnZV94LCBkb3VibGUgcGFnZV95LCBpbnQqIGRldmljZV94LCBpbnQqIGRldmljZV95KQoreworCWlmIChwYWdlID09IE5VTEwgfHwgZGV2aWNlX3ggPT0gTlVMTCB8fCBkZXZpY2VfeSA9PSBOVUxMKSByZXR1cm47CisJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBhZ2U7CisKKwlDUERGX01hdHJpeCBwYWdlMmRldmljZTsKKwlwUGFnZS0+R2V0RGlzcGxheU1hdHJpeChwYWdlMmRldmljZSwgc3RhcnRfeCwgc3RhcnRfeSwgc2l6ZV94LCBzaXplX3ksIHJvdGF0ZSk7CisKKwlGWF9GTE9BVCBkZXZpY2VfeF9mLCBkZXZpY2VfeV9mOworCXBhZ2UyZGV2aWNlLlRyYW5zZm9ybSgoKEZYX0ZMT0FUKXBhZ2VfeCksICgoRlhfRkxPQVQpcGFnZV95KSwgZGV2aWNlX3hfZiwgZGV2aWNlX3lfZik7CisKKwkqZGV2aWNlX3ggPSBGWFNZU19yb3VuZChkZXZpY2VfeF9mKTsKKwkqZGV2aWNlX3kgPSBGWFNZU19yb3VuZChkZXZpY2VfeV9mKTsKK30KKworRExMRVhQT1JUIEZQREZfQklUTUFQIFNURENBTEwgRlBERkJpdG1hcF9DcmVhdGUoaW50IHdpZHRoLCBpbnQgaGVpZ2h0LCBpbnQgYWxwaGEpCit7CisJQ0ZYX0RJQml0bWFwKiBwQml0bWFwID0gRlhfTkVXIENGWF9ESUJpdG1hcDsKKwlwQml0bWFwLT5DcmVhdGUod2lkdGgsIGhlaWdodCwgYWxwaGEgPyBGWERJQl9BcmdiIDogRlhESUJfUmdiMzIpOworCXJldHVybiBwQml0bWFwOworfQorCitETExFWFBPUlQgRlBERl9CSVRNQVAgU1REQ0FMTCBGUERGQml0bWFwX0NyZWF0ZUV4KGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGZvcm1hdCwgdm9pZCogZmlyc3Rfc2NhbiwgaW50IHN0cmlkZSkKK3sKKwlGWERJQl9Gb3JtYXQgZnhfZm9ybWF0OworCXN3aXRjaCAoZm9ybWF0KSB7CisJCWNhc2UgRlBERkJpdG1hcF9HcmF5OgorCQkJZnhfZm9ybWF0ID0gRlhESUJfOGJwcFJnYjsKKwkJCWJyZWFrOworCQljYXNlIEZQREZCaXRtYXBfQkdSOgorCQkJZnhfZm9ybWF0ID0gRlhESUJfUmdiOworCQkJYnJlYWs7CisJCWNhc2UgRlBERkJpdG1hcF9CR1J4OgorCQkJZnhfZm9ybWF0ID0gRlhESUJfUmdiMzI7CisJCQlicmVhazsKKwkJY2FzZSBGUERGQml0bWFwX0JHUkE6CisJCQlmeF9mb3JtYXQgPSBGWERJQl9BcmdiOworCQkJYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlyZXR1cm4gTlVMTDsKKwl9CisJQ0ZYX0RJQml0bWFwKiBwQml0bWFwID0gRlhfTkVXIENGWF9ESUJpdG1hcDsKKwlwQml0bWFwLT5DcmVhdGUod2lkdGgsIGhlaWdodCwgZnhfZm9ybWF0LCAoRlhfTFBCWVRFKWZpcnN0X3NjYW4sIHN0cmlkZSk7CisJcmV0dXJuIHBCaXRtYXA7Cit9CisKK0RMTEVYUE9SVCB2b2lkIFNURENBTEwgRlBERkJpdG1hcF9GaWxsUmVjdChGUERGX0JJVE1BUCBiaXRtYXAsIGludCBsZWZ0LCBpbnQgdG9wLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIAorCQkJCQkJCQkJaW50IHJlZCwgaW50IGdyZWVuLCBpbnQgYmx1ZSwgaW50IGFscGhhKQoreworCWlmIChiaXRtYXAgPT0gTlVMTCkgcmV0dXJuOworI2lmZGVmIF9TS0lBX1NVUFBPUlRfCisJQ0ZYX1NraWFEZXZpY2UgZGV2aWNlOworI2Vsc2UKKwlDRlhfRnhnZURldmljZSBkZXZpY2U7CisjZW5kaWYKKwlkZXZpY2UuQXR0YWNoKChDRlhfRElCaXRtYXAqKWJpdG1hcCk7CisJaWYgKCEoKENGWF9ESUJpdG1hcCopYml0bWFwKS0+SGFzQWxwaGEoKSkgYWxwaGEgPSAyNTU7CisJRlhfUkVDVCByZWN0KGxlZnQsIHRvcCwgbGVmdCt3aWR0aCwgdG9wK2hlaWdodCk7CisJZGV2aWNlLkZpbGxSZWN0KCZyZWN0LCBGWEFSR0JfTUFLRShhbHBoYSwgcmVkLCBncmVlbiwgYmx1ZSkpOworfQorCitETExFWFBPUlQgdm9pZCogU1REQ0FMTCBGUERGQml0bWFwX0dldEJ1ZmZlcihGUERGX0JJVE1BUCBiaXRtYXApCit7CisJaWYgKGJpdG1hcCA9PSBOVUxMKSByZXR1cm4gTlVMTDsKKwlyZXR1cm4gKChDRlhfRElCaXRtYXAqKWJpdG1hcCktPkdldEJ1ZmZlcigpOworfQorCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkJpdG1hcF9HZXRXaWR0aChGUERGX0JJVE1BUCBiaXRtYXApCit7CisJaWYgKGJpdG1hcCA9PSBOVUxMKSByZXR1cm4gMDsKKwlyZXR1cm4gKChDRlhfRElCaXRtYXAqKWJpdG1hcCktPkdldFdpZHRoKCk7Cit9CisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGQml0bWFwX0dldEhlaWdodChGUERGX0JJVE1BUCBiaXRtYXApCit7CisJaWYgKGJpdG1hcCA9PSBOVUxMKSByZXR1cm4gMDsKKwlyZXR1cm4gKChDRlhfRElCaXRtYXAqKWJpdG1hcCktPkdldEhlaWdodCgpOworfQorCitETExFWFBPUlQgaW50IFNURENBTEwgRlBERkJpdG1hcF9HZXRTdHJpZGUoRlBERl9CSVRNQVAgYml0bWFwKQoreworCWlmIChiaXRtYXAgPT0gTlVMTCkgcmV0dXJuIDA7CisJcmV0dXJuICgoQ0ZYX0RJQml0bWFwKiliaXRtYXApLT5HZXRQaXRjaCgpOworfQorCitETExFWFBPUlQgdm9pZCBTVERDQUxMIEZQREZCaXRtYXBfRGVzdHJveShGUERGX0JJVE1BUCBiaXRtYXApCit7CisJaWYgKGJpdG1hcCA9PSBOVUxMKSByZXR1cm47CisJZGVsZXRlIChDRlhfRElCaXRtYXAqKWJpdG1hcDsKK30KKwordm9pZCBGUERGX1JlbmRlclBhZ2VfUmV0YWlsKENSZW5kZXJDb250ZXh0KiBwQ29udGV4dCwgRlBERl9QQUdFIHBhZ2UsIGludCBzdGFydF94LCBpbnQgc3RhcnRfeSwgaW50IHNpemVfeCwgaW50IHNpemVfeSwKKwkJCQkJCWludCByb3RhdGUsIGludCBmbGFncyxGWF9CT09MIGJOZWVkVG9SZXN0b3JlLCBJRlNES19QQVVTRV9BZGFwdGVyICogcGF1c2UgKQoreworLy8jaWZkZWYgX0xJQ0VOU0VEX0JVSUxEXworCUNQREZfUGFnZSogcFBhZ2UgPSAoQ1BERl9QYWdlKilwYWdlOworCWlmIChwUGFnZSA9PSBOVUxMKSByZXR1cm47CisKKwlpZiAoIXBDb250ZXh0LT5tX3BPcHRpb25zKQorCQlwQ29udGV4dC0+bV9wT3B0aW9ucyA9IG5ldyBDUERGX1JlbmRlck9wdGlvbnM7CisvLwlDUERGX1JlbmRlck9wdGlvbnMgb3B0aW9uczsKKwlpZiAoZmxhZ3MgJiBGUERGX0xDRF9URVhUKQorCQlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9GbGFncyB8PSBSRU5ERVJfQ0xFQVJUWVBFOworCWVsc2UKKwkJcENvbnRleHQtPm1fcE9wdGlvbnMtPm1fRmxhZ3MgJj0gflJFTkRFUl9DTEVBUlRZUEU7CisJaWYgKGZsYWdzICYgRlBERl9OT19OQVRJVkVURVhUKQorCQlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9GbGFncyB8PSBSRU5ERVJfTk9fTkFUSVZFVEVYVDsKKwlpZiAoZmxhZ3MgJiBGUERGX1JFTkRFUl9MSU1JVEVESU1BR0VDQUNIRSkKKwkJcENvbnRleHQtPm1fcE9wdGlvbnMtPm1fRmxhZ3MgfD0gUkVOREVSX0xJTUlURURJTUFHRUNBQ0hFOworCWlmIChmbGFncyAmIEZQREZfUkVOREVSX0ZPUkNFSEFMRlRPTkUpCisJCXBDb250ZXh0LT5tX3BPcHRpb25zLT5tX0ZsYWdzIHw9IFJFTkRFUl9GT1JDRV9IQUxGVE9ORTsKKwkvL0dyYXlzY2FsZSBvdXRwdXQKKwlpZiAoZmxhZ3MgJiBGUERGX0dSQVlTQ0FMRSkKKwl7CisJCXBDb250ZXh0LT5tX3BPcHRpb25zLT5tX0NvbG9yTW9kZSA9IFJFTkRFUl9DT0xPUl9HUkFZOworCQlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9Gb3JlQ29sb3IgPSAwOworCQlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9CYWNrQ29sb3IgPSAweGZmZmZmZjsKKwl9CisJY29uc3QgQ1BERl9PQ0NvbnRleHQ6OlVzYWdlVHlwZSB1c2FnZSA9IChmbGFncyAmIEZQREZfUFJJTlRJTkcpID8gQ1BERl9PQ0NvbnRleHQ6OlByaW50IDogQ1BERl9PQ0NvbnRleHQ6OlZpZXc7CisKKwlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9BZGRGbGFncyA9IGZsYWdzID4+IDg7CisKKwlwQ29udGV4dC0+bV9wT3B0aW9ucy0+bV9wT0NDb250ZXh0ID0gbmV3IENQREZfT0NDb250ZXh0KHBQYWdlLT5tX3BEb2N1bWVudCwgdXNhZ2UpOworCisKKwlDRlhfQWZmaW5lTWF0cml4IG1hdHJpeDsKKwlwUGFnZS0+R2V0RGlzcGxheU1hdHJpeChtYXRyaXgsIHN0YXJ0X3gsIHN0YXJ0X3ksIHNpemVfeCwgc2l6ZV95LCByb3RhdGUpOyAKKworCUZYX1JFQ1QgY2xpcDsKKwljbGlwLmxlZnQgPSBzdGFydF94OworCWNsaXAucmlnaHQgPSBzdGFydF94ICsgc2l6ZV94OworCWNsaXAudG9wID0gc3RhcnRfeTsKKwljbGlwLmJvdHRvbSA9IHN0YXJ0X3kgKyBzaXplX3k7CisJcENvbnRleHQtPm1fcERldmljZS0+U2F2ZVN0YXRlKCk7CisJcENvbnRleHQtPm1fcERldmljZS0+U2V0Q2xpcF9SZWN0KCZjbGlwKTsKKworCXBDb250ZXh0LT5tX3BDb250ZXh0ID0gRlhfTkVXIENQREZfUmVuZGVyQ29udGV4dDsKKwlwQ29udGV4dC0+bV9wQ29udGV4dC0+Q3JlYXRlKHBQYWdlKTsKKwlwQ29udGV4dC0+bV9wQ29udGV4dC0+QXBwZW5kT2JqZWN0TGlzdChwUGFnZSwgJm1hdHJpeCk7CisKKwlpZiAoZmxhZ3MgJiBGUERGX0FOTk9UKSB7CisJCXBDb250ZXh0LT5tX3BBbm5vdHMgPSBGWF9ORVcgQ1BERl9Bbm5vdExpc3QocFBhZ2UpOworCQlGWF9CT09MIGJQcmludGluZyA9IHBDb250ZXh0LT5tX3BEZXZpY2UtPkdldERldmljZUNsYXNzKCkgIT0gRlhEQ19ESVNQTEFZOworCQlwQ29udGV4dC0+bV9wQW5ub3RzLT5EaXNwbGF5QW5ub3RzKHBQYWdlLCBwQ29udGV4dC0+bV9wQ29udGV4dCwgYlByaW50aW5nLCAmbWF0cml4LCBUUlVFLCBOVUxMKTsKKwl9CisKKwlwQ29udGV4dC0+bV9wUmVuZGVyZXIgPSBGWF9ORVcgQ1BERl9Qcm9ncmVzc2l2ZVJlbmRlcmVyOworCXBDb250ZXh0LT5tX3BSZW5kZXJlci0+U3RhcnQocENvbnRleHQtPm1fcENvbnRleHQsIHBDb250ZXh0LT5tX3BEZXZpY2UsIHBDb250ZXh0LT5tX3BPcHRpb25zLCBwYXVzZSk7CisJaWYgKGJOZWVkVG9SZXN0b3JlKQorCXsKKwkgIHBDb250ZXh0LT5tX3BEZXZpY2UtPlJlc3RvcmVTdGF0ZSgpOworCX0KKwkKKy8vI2VuZGlmCit9CisKK0RMTEVYUE9SVCBpbnQgU1REQ0FMTCBGUERGX0dldFBhZ2VTaXplQnlJbmRleChGUERGX0RPQ1VNRU5UIGRvY3VtZW50LCBpbnQgcGFnZV9pbmRleCwgZG91YmxlKiB3aWR0aCwgZG91YmxlKiBoZWlnaHQpCit7CisJQ1BERl9Eb2N1bWVudCogcERvYyA9IChDUERGX0RvY3VtZW50Kilkb2N1bWVudDsKKwlpZihwRG9jID09IE5VTEwpCisJCXJldHVybiBGQUxTRTsKKworCUNQREZfRGljdGlvbmFyeSogcERpY3QgPSBwRG9jLT5HZXRQYWdlKHBhZ2VfaW5kZXgpOworCWlmIChwRGljdCA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CisKKwlDUERGX1BhZ2UgcGFnZTsKKwlwYWdlLkxvYWQocERvYywgcERpY3QpOworCSp3aWR0aCA9IHBhZ2UuR2V0UGFnZVdpZHRoKCk7CisJKmhlaWdodCA9IHBhZ2UuR2V0UGFnZUhlaWdodCgpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0RMTEVYUE9SVCBGUERGX0JPT0wgU1REQ0FMTCBGUERGX1ZJRVdFUlJFRl9HZXRQcmludFNjYWxpbmcoRlBERl9ET0NVTUVOVCBkb2N1bWVudCkKK3sKKwlDUERGX0RvY3VtZW50KiBwRG9jID0gKENQREZfRG9jdW1lbnQqKWRvY3VtZW50OworCWlmICghcERvYykgcmV0dXJuIFRSVUU7CisJQ1BERl9WaWV3ZXJQcmVmZXJlbmNlcyB2aWV3UmVmKHBEb2MpOworCXJldHVybiB2aWV3UmVmLlByaW50U2NhbGluZygpOworfQorCitETExFWFBPUlQgRlBERl9ERVNUIFNURENBTEwgRlBERl9HZXROYW1lZERlc3RCeU5hbWUoRlBERl9ET0NVTUVOVCBkb2N1bWVudCxGUERGX0JZVEVTVFJJTkcgbmFtZSkKK3sKKwlpZiAoZG9jdW1lbnQgPT0gTlVMTCkKKwkJcmV0dXJuIE5VTEw7CisJaWYgKG5hbWUgPT0gTlVMTCB8fCBuYW1lWzBdID09IDApIAorCQlyZXR1cm4gTlVMTDsKKworCUNQREZfRG9jdW1lbnQqIHBEb2MgPSAoQ1BERl9Eb2N1bWVudCopZG9jdW1lbnQ7CisJQ1BERl9OYW1lVHJlZSBuYW1lX3RyZWUocERvYywgRlhfQlNUUkMoIkRlc3RzIikpOworCXJldHVybiBuYW1lX3RyZWUuTG9va3VwTmFtZWREZXN0KHBEb2MsIG5hbWUpOworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnNka19hY3Rpb25oYW5kbGVyLmNwcCBiL2ZwZGZzZGsvc3JjL2ZzZGtfYWN0aW9uaGFuZGxlci5jcHAKaW5kZXggMmEzODk4Yy4uNWRlZDk4NCAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnNka19hY3Rpb25oYW5kbGVyLmNwcAorKysgYi9mcGRmc2RrL3NyYy9mc2RrX2FjdGlvbmhhbmRsZXIuY3BwCkBAIC0xLDg1MCArMSw4NTAgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19tZ3IuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2FjdGlvbmhhbmRsZXIuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0JBX0FjdGlvbkhhbmRsZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUERGU0RLX0FjdGlvbkhhbmRsZXI6OkNQREZTREtfQWN0aW9uSGFuZGxlcihDUERGRG9jX0Vudmlyb25tZW50KiBwRXZpKSA6IA0KLQltX3BFdmkocEV2aSksDQotCW1fcEZvcm1BY3Rpb25IYW5kbGVyKE5VTEwpLA0KLQltX3BNZWRpYUFjdGlvbkhhbmRsZXIoTlVMTCkNCi17DQotCQltX3BGb3JtQWN0aW9uSGFuZGxlciA9IG5ldyBDUERGU0RLX0Zvcm1BY3Rpb25IYW5kbGVyOw0KLX0NCi0NCi1DUERGU0RLX0FjdGlvbkhhbmRsZXI6On5DUERGU0RLX0FjdGlvbkhhbmRsZXIoKQ0KLXsNCi0JaWYobV9wRm9ybUFjdGlvbkhhbmRsZXIpDQotCXsNCi0JCWRlbGV0ZSBtX3BGb3JtQWN0aW9uSGFuZGxlcjsNCi0JCW1fcEZvcm1BY3Rpb25IYW5kbGVyID0gTlVMTDsNCi0JfQ0KLX0NCi0NCi12b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6U2V0Rm9ybUFjdGlvbkhhbmRsZXIoQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlciogcEhhbmRsZXIpDQotew0KLQlBU1NFUlQocEhhbmRsZXIgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BGb3JtQWN0aW9uSGFuZGxlciA9PSBOVUxMKTsNCi0JbV9wRm9ybUFjdGlvbkhhbmRsZXIgPSBwSGFuZGxlcjsNCi19DQotDQotdm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OlNldE1lZGlhQWN0aW9uSGFuZGxlcihDUERGU0RLX01lZGlhQWN0aW9uSGFuZGxlciogcEhhbmRsZXIpDQotew0KLQlBU1NFUlQocEhhbmRsZXIgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BNZWRpYUFjdGlvbkhhbmRsZXIgPT0gTlVMTCk7DQotCW1fcE1lZGlhQWN0aW9uSGFuZGxlciA9IHBIYW5kbGVyOw0KLX0NCi0NCi12b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RGVzdHJveSgpDQotew0KLQlkZWxldGUgdGhpczsNCi19DQotDQotLy9kb2N1bWVudCBvcGVuDQotRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0RvY09wZW4oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50DQotCQkJCQkJCQkJCQkJLypDUmVhZGVyX0RvY3VtZW50KiBwRG9jdW1lbnQsIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcqLykNCi17DQotCUNGWF9QdHJMaXN0IGxpc3Q7DQotCXJldHVybiBFeGVjdXRlRG9jdW1lbnRPcGVuQWN0aW9uKGFjdGlvbiwgcERvY3VtZW50LCAvKnBEb2NWaWV3LCAqL2xpc3QpOw0KLX0NCi0NCi0vL2RvY3VtZW50IG9wZW4NCi1GWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fSmF2YVNjcmlwdChjb25zdCBDUERGX0FjdGlvbiYgSnNBY3Rpb24sQ0ZYX1dpZGVTdHJpbmcgY3NKU05hbWUsDQotCQkJCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pDQotew0KLQlpZiAoSnNBY3Rpb24uR2V0VHlwZSgpID09IENQREZfQWN0aW9uOjpKYXZhU2NyaXB0KQ0KLQl7DQotCQlDRlhfV2lkZVN0cmluZyBzd0pTID0gSnNBY3Rpb24uR2V0SmF2YVNjcmlwdCgpOw0KLQkJaWYgKCFzd0pTLklzRW1wdHkoKSkNCi0JCXsNCi0JCQlSdW5Eb2N1bWVudE9wZW5KYXZhU2NyaXB0KHBEb2N1bWVudCwgY3NKU05hbWUsIHN3SlMpOw0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0ZpZWxkSmF2YVNjcmlwdChjb25zdCBDUERGX0FjdGlvbiYgSnNBY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgDQotCQkJCQkJCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgDQotCQkJCQkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uJiBkYXRhKQ0KLXsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2N1bWVudC0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52KTsNCi0JaWYgKHBFbnYtPklzSlNJbml0aWF0ZWQoKSAmJiBKc0FjdGlvbi5HZXRUeXBlKCkgPT0gQ1BERl9BY3Rpb246OkphdmFTY3JpcHQpDQotCXsNCi0JCUNGWF9XaWRlU3RyaW5nIHN3SlMgPSBKc0FjdGlvbi5HZXRKYXZhU2NyaXB0KCk7DQotCQlpZiAoIXN3SlMuSXNFbXB0eSgpKQ0KLQkJew0KLQkJCVJ1bkZpZWxkSmF2YVNjcmlwdChwRG9jdW1lbnQsIHBGb3JtRmllbGQsIHR5cGUsIGRhdGEsIHN3SlMpOw0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1BhZ2UoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgZW51bSBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVUeXBlLA0KLQkJCQkJCQkJCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3ICpwRG9jVmlldyovKQ0KLXsNCi0JQ0ZYX1B0ckxpc3QgbGlzdDsNCi0JcmV0dXJuIEV4ZWN1dGVEb2N1bWVudFBhZ2VBY3Rpb24oYWN0aW9uLCBlVHlwZSwgcERvY3VtZW50LC8qIHBEb2NWaWV3LCovIGxpc3QpOw0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fRG9jdW1lbnQoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgZW51bSBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVUeXBlLA0KLQkJCQkJCQkJCQkJIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pDQotew0KLQlDRlhfUHRyTGlzdCBsaXN0Ow0KLQlyZXR1cm4gRXhlY3V0ZURvY3VtZW50UGFnZUFjdGlvbihhY3Rpb24sIGVUeXBlLCBwRG9jdW1lbnQsLyogcERvY1ZpZXcsKi8gbGlzdCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19BY3Rpb25IYW5kbGVyOjpEb0FjdGlvbl9Cb29rTWFyayhDUERGX0Jvb2ttYXJrICpwQm9va01hcmssIGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgDQotCQkJCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pDQotew0KLQlDRlhfUHRyTGlzdCBsaXN0Ow0KLQlyZXR1cm4gdGhpcy0+RXhlY3V0ZUJvb2tNYXJrKGFjdGlvbiwgcERvY3VtZW50LC8qIHBEb2NWaWV3LCovIHBCb29rTWFyaywgbGlzdCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19BY3Rpb25IYW5kbGVyOjpEb0FjdGlvbl9TY3JlZW4oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCANCi0JCQkJCQkJCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LC8qIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcsKi8gQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUNGWF9QdHJMaXN0IGxpc3Q7DQotCXJldHVybiB0aGlzLT5FeGVjdXRlU2NyZWVuQWN0aW9uKGFjdGlvbiwgdHlwZSwgcERvY3VtZW50LC8qIHBEb2NWaWV3LCovIHBTY3JlZW4sIGxpc3QpOw0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fTGluayhjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCANCi0JCQkJCQkJCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcqLykNCi17DQotCUNGWF9QdHJMaXN0IGxpc3Q7DQotCXJldHVybiBFeGVjdXRlTGlua0FjdGlvbihhY3Rpb24sIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBsaXN0KTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0ZpZWxkKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgDQotCQkJCQkJCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwvKiBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3LCovIA0KLQkJCQkJCQkJCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgUERGU0RLX0ZpZWxkQWN0aW9uJiBkYXRhKQ0KLXsNCi0JQ0ZYX1B0ckxpc3QgbGlzdDsNCi0JcmV0dXJuIEV4ZWN1dGVGaWVsZEFjdGlvbihhY3Rpb24sIHR5cGUsIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBwRm9ybUZpZWxkLCBkYXRhLCBsaXN0KTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkV4ZWN1dGVEb2N1bWVudE9wZW5BY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LA0KLQkJCQkJCQkJCQkJCQkgLypDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3LCovIENGWF9QdHJMaXN0JiBsaXN0KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKGxpc3QuRmluZCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlsaXN0LkFkZFRhaWwoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKTsNCi0NCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2N1bWVudC0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52KTsNCi0JaWYgKGFjdGlvbi5HZXRUeXBlKCkgPT0gQ1BERl9BY3Rpb246OkphdmFTY3JpcHQpDQotCXsNCi0JCWlmKHBFbnYtPklzSlNJbml0aWF0ZWQoKSkNCi0JCXsNCi0JCQlDRlhfV2lkZVN0cmluZyBzd0pTID0gYWN0aW9uLkdldEphdmFTY3JpcHQoKTsNCi0JCQlpZiAoIXN3SlMuSXNFbXB0eSgpKQ0KLQkJCXsNCi0JCQkJUnVuRG9jdW1lbnRPcGVuSmF2YVNjcmlwdChwRG9jdW1lbnQsIEwiIiwgc3dKUyk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJRG9BY3Rpb25fTm9KcyhhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsNCi0JfQ0KLQ0KLS8vIAlpZiAoIUlzVmFsaWREb2NWaWV3KHBEb2N1bWVudCwgcERvY1ZpZXcpKQ0KLS8vIAkJcmV0dXJuIEZBTFNFOw0KLQ0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1hY3Rpb24uR2V0U3ViQWN0aW9uc0NvdW50KCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJQ1BERl9BY3Rpb24gc3ViYWN0aW9uID0gYWN0aW9uLkdldFN1YkFjdGlvbihpKTsNCi0JCWlmICghRXhlY3V0ZURvY3VtZW50T3BlbkFjdGlvbihzdWJhY3Rpb24sIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBsaXN0KSkgcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RXhlY3V0ZUxpbmtBY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LA0KLQkJCQkJCQkJCQkJCSAvKkNSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcsKi8gQ0ZYX1B0ckxpc3QmIGxpc3QpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAobGlzdC5GaW5kKChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbikpDQotCQlyZXR1cm4gRkFMU0U7DQotCWxpc3QuQWRkVGFpbCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pOw0KLQ0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcERvY3VtZW50LT5HZXRFbnYoKTsNCi0JQVNTRVJUKHBFbnYpOw0KLQlpZiAoYWN0aW9uLkdldFR5cGUoKSA9PSBDUERGX0FjdGlvbjo6SmF2YVNjcmlwdCkNCi0Jew0KLQkJaWYocEVudi0+SXNKU0luaXRpYXRlZCgpKQ0KLQkJew0KLQkJCUNGWF9XaWRlU3RyaW5nIHN3SlMgPSBhY3Rpb24uR2V0SmF2YVNjcmlwdCgpOw0KLQkJCWlmICghc3dKUy5Jc0VtcHR5KCkpDQotCQkJew0KLQkJCQlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IHBEb2N1bWVudC0+R2V0SnNSdW50aW1lKCk7IC8vPz8/Pw0KLQkJCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCQkJCXBSdW50aW1lLT5TZXRSZWFkZXJEb2N1bWVudChwRG9jdW1lbnQpOw0KLQ0KLQkJCQlJRlhKU19Db250ZXh0KiBwQ29udGV4dCA9IHBSdW50aW1lLT5OZXdDb250ZXh0KCk7DQotCQkJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JCQkJcENvbnRleHQtPk9uTGlua19Nb3VzZVVwKHBEb2N1bWVudCk7DQotDQotCQkJCUNGWF9XaWRlU3RyaW5nIGNzSW5mbzsNCi0JCQkJRlhfQk9PTCBiUmV0ID0gcENvbnRleHQtPlJ1blNjcmlwdChzd0pTLCBjc0luZm8pOw0KLQkJCQlpZiAoIWJSZXQpDQotCQkJCXsNCi0JCQkJCS8vQ0JDTF9Gb3JtTm90aWZ5OjpNc2dCb3hKU0Vycm9yKHBQYWdlVmlldy0+R2V0UGFnZVZpZXdXbmQoKSwgY3NJbmZvKTsNCi0JCQkJfQ0KLQ0KLQkJCQlwUnVudGltZS0+UmVsZWFzZUNvbnRleHQocENvbnRleHQpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCURvQWN0aW9uX05vSnMoYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7DQotCX0NCi0NCi0vLyAJaWYgKCFJc1ZhbGlkRG9jVmlldyhwRG9jdW1lbnQsIHBEb2NWaWV3KSkNCi0vLyAJCXJldHVybiBGQUxTRTsNCi0NCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9YWN0aW9uLkdldFN1YkFjdGlvbnNDb3VudCgpOyBpPHN6OyBpKyspDQotCXsNCi0JCUNQREZfQWN0aW9uIHN1YmFjdGlvbiA9IGFjdGlvbi5HZXRTdWJBY3Rpb24oaSk7DQotCQlpZiAoIUV4ZWN1dGVMaW5rQWN0aW9uKHN1YmFjdGlvbiwgcERvY3VtZW50LC8qIHBEb2NWaWV3LCovIGxpc3QpKSByZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19BY3Rpb25IYW5kbGVyOjpFeGVjdXRlRG9jdW1lbnRQYWdlQWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwNCi0JCQkJCQkJCQkJCQkgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LC8qIENSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcsKi8gQ0ZYX1B0ckxpc3QmIGxpc3QpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAobGlzdC5GaW5kKChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbikpDQotCQlyZXR1cm4gRkFMU0U7DQotCWxpc3QuQWRkVGFpbCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pOw0KLQ0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcERvY3VtZW50LT5HZXRFbnYoKTsNCi0JQVNTRVJUKHBFbnYpOw0KLQlpZiAoYWN0aW9uLkdldFR5cGUoKSA9PSBDUERGX0FjdGlvbjo6SmF2YVNjcmlwdCkNCi0Jew0KLQkJaWYocEVudi0+SXNKU0luaXRpYXRlZCgpKQ0KLQkJew0KLQkJCUNGWF9XaWRlU3RyaW5nIHN3SlMgPSBhY3Rpb24uR2V0SmF2YVNjcmlwdCgpOw0KLQkJCWlmICghc3dKUy5Jc0VtcHR5KCkpDQotCQkJew0KLQkJCQlSdW5Eb2N1bWVudFBhZ2VKYXZhU2NyaXB0KHBEb2N1bWVudCwgdHlwZSwgc3dKUyk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJRG9BY3Rpb25fTm9KcyhhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsNCi0JfQ0KLQ0KLQlpZiAoIUlzVmFsaWREb2NWaWV3KHBEb2N1bWVudC8qLCBwRG9jVmlldyovKSkNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9YWN0aW9uLkdldFN1YkFjdGlvbnNDb3VudCgpOyBpPHN6OyBpKyspDQotCXsNCi0JCUNQREZfQWN0aW9uIHN1YmFjdGlvbiA9IGFjdGlvbi5HZXRTdWJBY3Rpb24oaSk7DQotCQlpZiAoIUV4ZWN1dGVEb2N1bWVudFBhZ2VBY3Rpb24oc3ViYWN0aW9uLCB0eXBlLCBwRG9jdW1lbnQsLyogcERvY1ZpZXcsKi8gbGlzdCkpIHJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OklzVmFsaWRGaWVsZChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRGljdGlvbmFyeSogcEZpZWxkRGljdCkNCi17DQotCUFTU0VSVChtX3BFdmkgIT0gTlVMTCk7DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotCUFTU0VSVChwRmllbGREaWN0ICE9IE5VTEwpOw0KLQ0KLQlpZiAoMS8qbV9wQXBwLT5Jc1ZhbGlkRG9jdW1lbnQocERvY3VtZW50KSovKQ0KLQl7DQotCQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JCUNQREZfSW50ZXJGb3JtKiBwUERGSW50ZXJGb3JtID0gcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCQlBU1NFUlQocFBERkludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JCXJldHVybiBwUERGSW50ZXJGb3JtLT5HZXRGaWVsZEJ5RGljdChwRmllbGREaWN0KSAhPSBOVUxMOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkV4ZWN1dGVGaWVsZEFjdGlvbihjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIA0KLQkJCQkJCQkJCQkgIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwvKiBDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCANCi0JCQkJCQkJCQkJICBQREZTREtfRmllbGRBY3Rpb24mIGRhdGEsIENGWF9QdHJMaXN0JiBsaXN0KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKGxpc3QuRmluZCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlsaXN0LkFkZFRhaWwoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKTsNCi0NCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2N1bWVudC0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52KTsNCi0JaWYgKGFjdGlvbi5HZXRUeXBlKCkgPT0gQ1BERl9BY3Rpb246OkphdmFTY3JpcHQpDQotCXsNCi0JCWlmKHBFbnYtPklzSlNJbml0aWF0ZWQoKSkNCi0JCXsNCi0JCQlDRlhfV2lkZVN0cmluZyBzd0pTID0gYWN0aW9uLkdldEphdmFTY3JpcHQoKTsNCi0JCQlpZiAoIXN3SlMuSXNFbXB0eSgpKQ0KLQkJCXsNCi0JCQkJUnVuRmllbGRKYXZhU2NyaXB0KHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgdHlwZSwgZGF0YSwgc3dKUyk7DQotCQkJCWlmICghSXNWYWxpZEZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZC0+R2V0RmllbGREaWN0KCkpKQ0KLQkJCQkJcmV0dXJuIEZBTFNFOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCURvQWN0aW9uX05vSnMoYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7DQotLy8gCQlpZiAoIUlzVmFsaWREb2NWaWV3KHBEb2N1bWVudCwgcERvY1ZpZXcpKQ0KLS8vIAkJCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1hY3Rpb24uR2V0U3ViQWN0aW9uc0NvdW50KCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJQ1BERl9BY3Rpb24gc3ViYWN0aW9uID0gYWN0aW9uLkdldFN1YkFjdGlvbihpKTsNCi0JCWlmICghRXhlY3V0ZUZpZWxkQWN0aW9uKHN1YmFjdGlvbiwgdHlwZSwgcERvY3VtZW50LC8qIHBEb2NWaWV3LCovIHBGb3JtRmllbGQsIGRhdGEsIGxpc3QpKSByZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19BY3Rpb25IYW5kbGVyOjpFeGVjdXRlU2NyZWVuQWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgDQotCQkJCQkJCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwvKiBDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIENQREZTREtfQW5ub3QqIHBTY3JlZW4sIENGWF9QdHJMaXN0JiBsaXN0KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKGxpc3QuRmluZCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlsaXN0LkFkZFRhaWwoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKTsNCi0NCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2N1bWVudC0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52KTsNCi0JaWYgKGFjdGlvbi5HZXRUeXBlKCkgPT0gQ1BERl9BY3Rpb246OkphdmFTY3JpcHQpDQotCXsNCi0JCWlmKHBFbnYtPklzSlNJbml0aWF0ZWQoKSkNCi0JCXsNCi0JCQlDRlhfV2lkZVN0cmluZyBzd0pTID0gYWN0aW9uLkdldEphdmFTY3JpcHQoKTsNCi0JCQlpZiAoIXN3SlMuSXNFbXB0eSgpKQ0KLQkJCXsNCi0JCQkJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwRG9jdW1lbnQtPkdldEpzUnVudGltZSgpOw0KLQkJCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCQkJCXBSdW50aW1lLT5TZXRSZWFkZXJEb2N1bWVudChwRG9jdW1lbnQpOw0KLQ0KLQkJCQlJRlhKU19Db250ZXh0KiBwQ29udGV4dCA9IHBSdW50aW1lLT5OZXdDb250ZXh0KCk7DQotCQkJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JLy8gCQkJc3dpdGNoICh0eXBlKQ0KLQkvLyAJCQl7DQotCS8vIAkJCWNhc2UgQ1BERl9BQWN0aW9uOjpDdXJzb3JFbnRlcjoNCi0JLy8gCQkJCXBDb250ZXh0LT5PblNjcmVlbl9Nb3VzZUVudGVyKElzQ1RSTHByZXNzZWQoKSwgSXNTSElGVHByZXNzZWQoKSwgcFNjcmVlbik7DQotCS8vIAkJCQlicmVhazsNCi0JLy8gCQkJY2FzZSBDUERGX0FBY3Rpb246OkN1cnNvckV4aXQ6DQotCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fTW91c2VFeGl0KElzQ1RSTHByZXNzZWQoKSwgSXNTSElGVHByZXNzZWQoKSwgcFNjcmVlbik7DQotCS8vIAkJCQlicmVhazsNCi0JLy8gCQkJY2FzZSBDUERGX0FBY3Rpb246OkJ1dHRvbkRvd246DQotCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fTW91c2VEb3duKElzQ1RSTHByZXNzZWQoKSwgSXNTSElGVHByZXNzZWQoKSwgcFNjcmVlbik7DQotCS8vIAkJCQlicmVhazsNCi0JLy8gCQkJY2FzZSBDUERGX0FBY3Rpb246OkJ1dHRvblVwOg0KLQkvLyAJCQkJcENvbnRleHQtPk9uU2NyZWVuX01vdXNlVXAoSXNDVFJMcHJlc3NlZCgpLCBJc1NISUZUcHJlc3NlZCgpLCBwU2NyZWVuKTsNCi0JLy8gCQkJCWJyZWFrOw0KLQkvLyAJCQljYXNlIENQREZfQUFjdGlvbjo6R2V0Rm9jdXM6DQotCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fRm9jdXMoSXNDVFJMcHJlc3NlZCgpLCBJc1NISUZUcHJlc3NlZCgpLCBwU2NyZWVuKTsNCi0JLy8gCQkJCWJyZWFrOw0KLQkvLyAJCQljYXNlIENQREZfQUFjdGlvbjo6TG9zZUZvY3VzOg0KLQkvLyAJCQkJcENvbnRleHQtPk9uU2NyZWVuX0JsdXIoSXNDVFJMcHJlc3NlZCgpLCBJc1NISUZUcHJlc3NlZCgpLCBwU2NyZWVuKTsNCi0JLy8gCQkJCWJyZWFrOw0KLQkvLyAJCQljYXNlIENQREZfQUFjdGlvbjo6UGFnZU9wZW46DQotCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fT3BlbihJc0NUUkxwcmVzc2VkKCksIElzU0hJRlRwcmVzc2VkKCksIHBTY3JlZW4pOw0KLQkvLyAJCQkJYnJlYWs7DQotCS8vIAkJCWNhc2UgQ1BERl9BQWN0aW9uOjpQYWdlQ2xvc2U6DQotCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fQ2xvc2UoSXNDVFJMcHJlc3NlZCgpLCBJc1NISUZUcHJlc3NlZCgpLCBwU2NyZWVuKTsNCi0JLy8gCQkJCWJyZWFrOw0KLQkvLyAJCQljYXNlIENQREZfQUFjdGlvbjo6UGFnZVZpc2libGU6DQotCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fSW5WaWV3KElzQ1RSTHByZXNzZWQoKSwgSXNTSElGVHByZXNzZWQoKSwgcFNjcmVlbik7DQotCS8vIAkJCQlicmVhazsNCi0JLy8gCQkJY2FzZSBDUERGX0FBY3Rpb246OlBhZ2VJbnZpc2libGU6DQotCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fT3V0VmlldyhJc0NUUkxwcmVzc2VkKCksIElzU0hJRlRwcmVzc2VkKCksIHBTY3JlZW4pOw0KLQkvLyAJCQkJYnJlYWs7DQotCS8vIAkJCWRlZmF1bHQ6DQotCS8vIAkJCQlBU1NFUlQoRkFMU0UpOw0KLQkvLyAJCQkJYnJlYWs7DQotCS8vIAkJCX0NCi0NCi0JCQkJQ0ZYX1dpZGVTdHJpbmcgY3NJbmZvOw0KLQkJCQlGWF9CT09MIGJSZXQgPSBwQ29udGV4dC0+UnVuU2NyaXB0KHN3SlMsIGNzSW5mbyk7DQotCQkJCWlmICghYlJldCkNCi0JCQkJew0KLQkJCQkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOw0KLQkJCQl9DQotDQotCQkJCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJRG9BY3Rpb25fTm9KcyhhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsNCi0JfQ0KLQ0KLS8vIAlpZiAoIUlzVmFsaWREb2NWaWV3KHBEb2N1bWVudCwgcERvY1ZpZXcpKQ0KLS8vIAkJcmV0dXJuIEZBTFNFOw0KLQ0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1hY3Rpb24uR2V0U3ViQWN0aW9uc0NvdW50KCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJQ1BERl9BY3Rpb24gc3ViYWN0aW9uID0gYWN0aW9uLkdldFN1YkFjdGlvbihpKTsNCi0JCWlmICghRXhlY3V0ZVNjcmVlbkFjdGlvbihzdWJhY3Rpb24sIHR5cGUsIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBwU2NyZWVuLCBsaXN0KSkgcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RXhlY3V0ZUJvb2tNYXJrKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgDQotCQkJCQkJCQkJCS8qQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldywqLyBDUERGX0Jvb2ttYXJrKiBwQm9va21hcmssIENGWF9QdHJMaXN0JiBsaXN0KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKGxpc3QuRmluZCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlsaXN0LkFkZFRhaWwoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKTsNCi0NCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2N1bWVudC0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52KTsNCi0JaWYgKGFjdGlvbi5HZXRUeXBlKCkgPT0gQ1BERl9BY3Rpb246OkphdmFTY3JpcHQpDQotCXsNCi0JCWlmKHBFbnYtPklzSlNJbml0aWF0ZWQoKSkNCi0JCXsNCi0JCQlDRlhfV2lkZVN0cmluZyBzd0pTID0gYWN0aW9uLkdldEphdmFTY3JpcHQoKTsNCi0JCQlpZiAoIXN3SlMuSXNFbXB0eSgpKQ0KLQkJCXsNCi0JCQkJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwRG9jdW1lbnQtPkdldEpzUnVudGltZSgpOw0KLQkJCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCQkJCXBSdW50aW1lLT5TZXRSZWFkZXJEb2N1bWVudChwRG9jdW1lbnQpOw0KLQ0KLQkJCQlJRlhKU19Db250ZXh0KiBwQ29udGV4dCA9IHBSdW50aW1lLT5OZXdDb250ZXh0KCk7DQotCQkJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JCQkJcENvbnRleHQtPk9uQm9va21hcmtfTW91c2VVcChwQm9va21hcmspOw0KLQ0KLQkJCQlDRlhfV2lkZVN0cmluZyBjc0luZm87DQotCQkJCUZYX0JPT0wgYlJldCA9IHBDb250ZXh0LT5SdW5TY3JpcHQoc3dKUywgY3NJbmZvKTsNCi0JCQkJaWYgKCFiUmV0KQ0KLQkJCQl7DQotCQkJCQkvL0NCQ0xfRm9ybU5vdGlmeTo6TXNnQm94SlNFcnJvcihwUGFnZVZpZXctPkdldFBhZ2VWaWV3V25kKCksIGNzSW5mbyk7DQotCQkJCX0NCi0NCi0JCQkJcFJ1bnRpbWUtPlJlbGVhc2VDb250ZXh0KHBDb250ZXh0KTsNCi0JCQl9DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlEb0FjdGlvbl9Ob0pzKGFjdGlvbiwgcERvY3VtZW50LyosIHBEb2NWaWV3Ki8pOw0KLQl9DQotDQotLy8gCWlmICghSXNWYWxpZERvY1ZpZXcocERvY3VtZW50LCBwRG9jVmlldykpDQotLy8gCQlyZXR1cm4gRkFMU0U7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PWFjdGlvbi5HZXRTdWJBY3Rpb25zQ291bnQoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlDUERGX0FjdGlvbiBzdWJhY3Rpb24gPSBhY3Rpb24uR2V0U3ViQWN0aW9uKGkpOw0KLQkJaWYgKCFFeGVjdXRlQm9va01hcmsoc3ViYWN0aW9uLCBwRG9jdW1lbnQsLyogcERvY1ZpZXcsKi8gcEJvb2ttYXJrLCBsaXN0KSkgcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fTm9Kcyhjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQvKiwgQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldyovKQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0Jc3dpdGNoIChhY3Rpb24uR2V0VHlwZSgpKQ0KLQl7DQotCWNhc2UgQ1BERl9BY3Rpb246OkdvVG86DQotCQlEb0FjdGlvbl9Hb1RvKHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBhY3Rpb24pOw0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BY3Rpb246OkdvVG9SOg0KLQkJRG9BY3Rpb25fR29Ub1IocERvY3VtZW50LCBhY3Rpb24pOw0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BY3Rpb246OkdvVG9FOg0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BY3Rpb246OkxhdW5jaDoNCi0JCURvQWN0aW9uX0xhdW5jaChwRG9jdW1lbnQsIGFjdGlvbik7DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6VGhyZWFkOg0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BY3Rpb246OlVSSToNCi0JCURvQWN0aW9uX1VSSShwRG9jdW1lbnQsIGFjdGlvbik7DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6U291bmQ6DQotCQlpZiAobV9wTWVkaWFBY3Rpb25IYW5kbGVyKQ0KLQkJew0KLQkJCW1fcE1lZGlhQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fU291bmQoYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6TW92aWU6DQotCQlpZiAobV9wTWVkaWFBY3Rpb25IYW5kbGVyKQ0KLQkJew0KLQkJCW1fcE1lZGlhQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fTW92aWUoYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6SGlkZToNCi0JCWlmIChtX3BGb3JtQWN0aW9uSGFuZGxlcikNCi0JCXsNCi0JCQltX3BGb3JtQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fSGlkZShhY3Rpb24sIHBEb2N1bWVudCk7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6TmFtZWQ6DQotCQlEb0FjdGlvbl9OYW1lZChwRG9jdW1lbnQsIGFjdGlvbik7DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6U3VibWl0Rm9ybToNCi0JCWlmIChtX3BGb3JtQWN0aW9uSGFuZGxlcikNCi0JCXsNCi0JCQltX3BGb3JtQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fU3VibWl0Rm9ybShhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQWN0aW9uOjpSZXNldEZvcm06DQotCQlpZiAobV9wRm9ybUFjdGlvbkhhbmRsZXIpDQotCQl7DQotCQkJbV9wRm9ybUFjdGlvbkhhbmRsZXItPkRvQWN0aW9uX1Jlc2V0Rm9ybShhY3Rpb24sIHBEb2N1bWVudCk7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6SW1wb3J0RGF0YToNCi0JCWlmIChtX3BGb3JtQWN0aW9uSGFuZGxlcikNCi0JCXsNCi0JCQltX3BGb3JtQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fSW1wb3J0RGF0YShhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQWN0aW9uOjpKYXZhU2NyaXB0Og0KLQkJQVNTRVJUKEZBTFNFKTsNCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQWN0aW9uOjpTZXRPQ0dTdGF0ZToNCi0JCURvQWN0aW9uX1NldE9DR1N0YXRlKHBEb2N1bWVudCwgLypwRG9jVmlldywqLyBhY3Rpb24pOw0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BY3Rpb246OlJlbmRpdGlvbjoNCi0JCWlmIChtX3BNZWRpYUFjdGlvbkhhbmRsZXIpDQotCQl7DQotCQkJbV9wTWVkaWFBY3Rpb25IYW5kbGVyLT5Eb0FjdGlvbl9SZW5kaXRpb24oYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6VHJhbnM6DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FjdGlvbjo6R29UbzNEVmlldzoNCi0JCWJyZWFrOw0KLQlkZWZhdWx0Og0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OklzVmFsaWREb2NWaWV3KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3Ki8pDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQkvL0FTU0VSVChwRG9jVmlldyAhPSBOVUxMKTsNCi0NCi0JLy9yZXR1cm4gcERvY3VtZW50LT5Jc1ZhbGlkRG9jVmlldyhwRG9jVmlldyk7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fR29UbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIC8qQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldywqLw0KLQkJCQkJCQkJICBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0vLwlBU1NFUlQocERvY1ZpZXcgIT0gTlVMTCk7DQotCUFTU0VSVChhY3Rpb24gIT0gTlVMTCk7DQotDQotCUNQREZfRG9jdW1lbnQqIHBQREZEb2N1bWVudCA9IHBEb2N1bWVudC0+R2V0RG9jdW1lbnQoKTsNCi0JQVNTRVJUKHBQREZEb2N1bWVudCAhPSBOVUxMKTsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBEb2N1bWVudC0+R2V0RW52KCk7DQotCUFTU0VSVChwQXBwICE9IE5VTEwpOw0KLQ0KLQlDUERGX0Rlc3QgTXlEZXN0ID0gYWN0aW9uLkdldERlc3QocFBERkRvY3VtZW50KTsNCi0JaW50IG5QYWdlSW5kZXggPSBNeURlc3QuR2V0UGFnZUluZGV4KHBQREZEb2N1bWVudCk7DQotCWludCBuRml0VHlwZSA9IE15RGVzdC5HZXRab29tTW9kZSgpOw0KLQljb25zdCBDUERGX0FycmF5ICogcE15QXJyYXkgPSAoQ1BERl9BcnJheSopTXlEZXN0Lm1fcE9iajsNCi0JZmxvYXQqIHBQb3NBcnkgPSBOVUxMOw0KLQlpbnQgc2l6ZU9mQXJ5ID0gMDsNCi0JaWYgKHBNeUFycmF5ICE9IE5VTEwpDQotCXsNCi0JCXBQb3NBcnkgPSBuZXcgZmxvYXRbcE15QXJyYXktPkdldENvdW50KCldOw0KLQkJaW50IGogPSAwOw0KLQkJZm9yIChpbnQgaSA9IDI7IGkgPCAoaW50KXBNeUFycmF5LT5HZXRDb3VudCgpOyBpKyspDQotCQl7DQotCQkJcFBvc0FyeVtqKytdID0gcE15QXJyYXktPkdldEZsb2F0KGkpOw0KLQkJfQ0KLQkJc2l6ZU9mQXJ5ID0gajsNCi0JfQ0KLQlwQXBwLT5GRklfRG9Hb1RvQWN0aW9uKG5QYWdlSW5kZXgsIG5GaXRUeXBlLCBwUG9zQXJ5LCBzaXplT2ZBcnkpOw0KLQlpZihwUG9zQXJ5KQ0KLQkJZGVsZXRlW10gcFBvc0FyeTsNCi19DQotDQotdm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0dvVG9SKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbikNCi17DQotDQotfQ0KLQ0KLXZvaWQgQ1BERlNES19BY3Rpb25IYW5kbGVyOjpEb0FjdGlvbl9MYXVuY2goQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQ0KLXsNCi0NCi19DQotDQotdm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1VSSShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pDQotew0KLSAJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0gCUFTU0VSVChhY3Rpb24gIT0gTlVMTCk7DQotDQotIAlDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwID0gcERvY3VtZW50LT5HZXRFbnYoKTsNCi0gCUFTU0VSVChwQXBwICE9IE5VTEwpOw0KLSANCi0gCUNGWF9CeXRlU3RyaW5nIHNVUkkgPSBhY3Rpb24uR2V0VVJJKHBEb2N1bWVudC0+R2V0RG9jdW1lbnQoKSk7DQotIAlwQXBwLT5GRklfRG9VUklBY3Rpb24oRlhfTFBDU1RSKHNVUkkpKTsNCi19DQotDQotdm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX05hbWVkKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbikNCi17DQotIAlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLSAJQVNTRVJUKGFjdGlvbiAhPSBOVUxMKTsNCi0gDQotIAlDRlhfQnl0ZVN0cmluZyBjc05hbWUgPSBhY3Rpb24uR2V0TmFtZWRBY3Rpb24oKTsNCi0gCXBEb2N1bWVudC0+R2V0RW52KCktPkZGSV9FeGVjdXRlTmFtZWRBY3Rpb24oY3NOYW1lKTsNCi19DQotDQotDQotdm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1NldE9DR1N0YXRlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwvKiBDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pDQotew0KLX0NCi0NCi12b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6UnVuRmllbGRKYXZhU2NyaXB0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwNCi0JCQkJCQkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uJiBkYXRhLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0KQ0KLXsNCi0JQVNTRVJUKHR5cGUgIT0gQ1BERl9BQWN0aW9uOjpDYWxjdWxhdGUpOw0KLQlBU1NFUlQodHlwZSAhPSBDUERGX0FBY3Rpb246OkZvcm1hdCk7DQotDQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUlGWEpTX1J1bnRpbWUqIHBSdW50aW1lID0gcERvY3VtZW50LT5HZXRKc1J1bnRpbWUoKTsNCi0JQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOw0KLQ0KLQlwUnVudGltZS0+U2V0UmVhZGVyRG9jdW1lbnQocERvY3VtZW50KTsNCi0NCi0JSUZYSlNfQ29udGV4dCogcENvbnRleHQgPSBwUnVudGltZS0+TmV3Q29udGV4dCgpOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotDQotCXN3aXRjaCAodHlwZSkNCi0Jew0KLQljYXNlIENQREZfQUFjdGlvbjo6Q3Vyc29yRW50ZXI6DQotCQlwQ29udGV4dC0+T25GaWVsZF9Nb3VzZUVudGVyKGRhdGEuYk1vZGlmaWVyLCBkYXRhLmJTaGlmdCwgcEZvcm1GaWVsZCk7DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FBY3Rpb246OkN1cnNvckV4aXQ6DQotCQlwQ29udGV4dC0+T25GaWVsZF9Nb3VzZUV4aXQoZGF0YS5iTW9kaWZpZXIsIGRhdGEuYlNoaWZ0LCBwRm9ybUZpZWxkKTsNCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQUFjdGlvbjo6QnV0dG9uRG93bjoNCi0JCXBDb250ZXh0LT5PbkZpZWxkX01vdXNlRG93bihkYXRhLmJNb2RpZmllciwgZGF0YS5iU2hpZnQsIHBGb3JtRmllbGQpOw0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpCdXR0b25VcDoNCi0JCXBDb250ZXh0LT5PbkZpZWxkX01vdXNlVXAoZGF0YS5iTW9kaWZpZXIsIGRhdGEuYlNoaWZ0LCBwRm9ybUZpZWxkKTsNCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQUFjdGlvbjo6R2V0Rm9jdXM6DQotCQlwQ29udGV4dC0+T25GaWVsZF9Gb2N1cyhkYXRhLmJNb2RpZmllciwgZGF0YS5iU2hpZnQsIHBGb3JtRmllbGQsIGRhdGEuc1ZhbHVlKTsNCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQUFjdGlvbjo6TG9zZUZvY3VzOg0KLQkJcENvbnRleHQtPk9uRmllbGRfQmx1cihkYXRhLmJNb2RpZmllciwgZGF0YS5iU2hpZnQsIHBGb3JtRmllbGQsIGRhdGEuc1ZhbHVlKTsNCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlOg0KLQkJcENvbnRleHQtPk9uRmllbGRfS2V5c3Ryb2tlKGRhdGEubkNvbW1pdEtleSwgZGF0YS5zQ2hhbmdlLCBkYXRhLnNDaGFuZ2VFeCwgZGF0YS5iS2V5RG93biwgDQotCQkJZGF0YS5iTW9kaWZpZXIsIGRhdGEublNlbEVuZCwgZGF0YS5uU2VsU3RhcnQsIGRhdGEuYlNoaWZ0LCBwRm9ybUZpZWxkLCBkYXRhLnNWYWx1ZSwNCi0JCQlkYXRhLmJXaWxsQ29tbWl0LCBkYXRhLmJGaWVsZEZ1bGwsIGRhdGEuYlJDKTsNCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQUFjdGlvbjo6VmFsaWRhdGU6DQotCQlwQ29udGV4dC0+T25GaWVsZF9WYWxpZGF0ZShkYXRhLnNDaGFuZ2UsIGRhdGEuc0NoYW5nZUV4LCBkYXRhLmJLZXlEb3duLCBkYXRhLmJNb2RpZmllciwNCi0JCQlkYXRhLmJTaGlmdCwgcEZvcm1GaWVsZCwgZGF0YS5zVmFsdWUsIGRhdGEuYlJDKTsNCi0JCWJyZWFrOw0KLQlkZWZhdWx0Og0KLQkJQVNTRVJUKEZBTFNFKTsNCi0JCWJyZWFrOw0KLQl9DQotDQotCUNGWF9XaWRlU3RyaW5nIGNzSW5mbzsNCi0JRlhfQk9PTCBiUmV0ID0gcENvbnRleHQtPlJ1blNjcmlwdChzY3JpcHQsIGNzSW5mbyk7DQotCWlmICghYlJldCkNCi0Jew0KLQkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOw0KLQl9DQotDQotCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19BY3Rpb25IYW5kbGVyOjpSdW5Eb2N1bWVudE9wZW5KYXZhU2NyaXB0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNTY3JpcHROYW1lLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwRG9jdW1lbnQtPkdldEpzUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCXBSdW50aW1lLT5TZXRSZWFkZXJEb2N1bWVudChwRG9jdW1lbnQpOw0KLQ0KLQlJRlhKU19Db250ZXh0KiBwQ29udGV4dCA9IHBSdW50aW1lLT5OZXdDb250ZXh0KCk7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JcENvbnRleHQtPk9uRG9jX09wZW4ocERvY3VtZW50LCBzU2NyaXB0TmFtZSk7DQotDQotCUNGWF9XaWRlU3RyaW5nIGNzSW5mbzsNCi0JRlhfQk9PTCBiUmV0ID0gcENvbnRleHQtPlJ1blNjcmlwdChzY3JpcHQsIGNzSW5mbyk7DQotCWlmICghYlJldCkNCi0Jew0KLQkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOw0KLQl9DQotDQotCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19BY3Rpb25IYW5kbGVyOjpSdW5Eb2N1bWVudFBhZ2VKYXZhU2NyaXB0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwRG9jdW1lbnQtPkdldEpzUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCXBSdW50aW1lLT5TZXRSZWFkZXJEb2N1bWVudChwRG9jdW1lbnQpOw0KLQ0KLQlJRlhKU19Db250ZXh0KiBwQ29udGV4dCA9IHBSdW50aW1lLT5OZXdDb250ZXh0KCk7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0Jc3dpdGNoICh0eXBlKQ0KLQl7CQ0KLQljYXNlIENQREZfQUFjdGlvbjo6T3BlblBhZ2U6DQotCQlwQ29udGV4dC0+T25QYWdlX09wZW4ocERvY3VtZW50KTsNCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQUFjdGlvbjo6Q2xvc2VQYWdlOg0KLQkJcENvbnRleHQtPk9uUGFnZV9DbG9zZShwRG9jdW1lbnQpOw0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpDbG9zZURvY3VtZW50Og0KLQkJcENvbnRleHQtPk9uRG9jX1dpbGxDbG9zZShwRG9jdW1lbnQpOw0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpTYXZlRG9jdW1lbnQ6DQotCQlwQ29udGV4dC0+T25Eb2NfV2lsbFNhdmUocERvY3VtZW50KTsNCi0JCWJyZWFrOw0KLQljYXNlIENQREZfQUFjdGlvbjo6RG9jdW1lbnRTYXZlZDoNCi0JCXBDb250ZXh0LT5PbkRvY19EaWRTYXZlKHBEb2N1bWVudCk7DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FBY3Rpb246OlByaW50RG9jdW1lbnQ6DQotCQlwQ29udGV4dC0+T25Eb2NfV2lsbFByaW50KHBEb2N1bWVudCk7DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FBY3Rpb246OkRvY3VtZW50UHJpbnRlZDoNCi0JCXBDb250ZXh0LT5PbkRvY19EaWRQcmludChwRG9jdW1lbnQpOw0KLQkJYnJlYWs7DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpQYWdlVmlzaWJsZToNCi0JCXBDb250ZXh0LT5PblBhZ2VfSW5WaWV3KHBEb2N1bWVudCk7DQotCQlicmVhazsNCi0JY2FzZSBDUERGX0FBY3Rpb246OlBhZ2VJbnZpc2libGU6DQotCQlwQ29udGV4dC0+T25QYWdlX091dFZpZXcocERvY3VtZW50KTsNCi0JCWJyZWFrOw0KLQlkZWZhdWx0Og0KLQkJQVNTRVJUKEZBTFNFKTsNCi0JCWJyZWFrOw0KLQl9DQotDQotCUNGWF9XaWRlU3RyaW5nIGNzSW5mbzsNCi0JRlhfQk9PTCBiUmV0ID0gcENvbnRleHQtPlJ1blNjcmlwdChzY3JpcHQsIGNzSW5mbyk7DQotCWlmICghYlJldCkNCi0Jew0KLQkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOw0KLQl9DQotDQotCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7DQotfQ0KLQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fSGlkZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQkNCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKXBEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQkNCi0JaWYgKHBJbnRlckZvcm0tPkRvQWN0aW9uX0hpZGUoYWN0aW9uKSkNCi0Jew0KLQkJcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfRm9ybUFjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1N1Ym1pdEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0JDQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBwSW50ZXJGb3JtLT5Eb0FjdGlvbl9TdWJtaXRGb3JtKGFjdGlvbik7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fUmVzZXRGb3JtKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotCQ0KLQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotCQ0KLQlpZiAocEludGVyRm9ybS0+RG9BY3Rpb25fUmVzZXRGb3JtKGFjdGlvbikpDQotCXsJDQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfRm9ybUFjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0ltcG9ydERhdGEoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0JDQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0JDQotCWlmIChwSW50ZXJGb3JtLT5Eb0FjdGlvbl9JbXBvcnREYXRhKGFjdGlvbikpDQotCXsNCi0JCXBEb2N1bWVudC0+U2V0Q2hhbmdlTWFyaygpOwkNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19NZWRpYUFjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1JlbmRpdGlvbihjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19NZWRpYUFjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1NvdW5kKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX01lZGlhQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fTW92aWUoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19tZ3IuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfYWN0aW9uaGFuZGxlci5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDQkFfQWN0aW9uSGFuZGxlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkNQREZTREtfQWN0aW9uSGFuZGxlcihDUERGRG9jX0Vudmlyb25tZW50KiBwRXZpKSA6IAorCW1fcEV2aShwRXZpKSwKKwltX3BGb3JtQWN0aW9uSGFuZGxlcihOVUxMKSwKKwltX3BNZWRpYUFjdGlvbkhhbmRsZXIoTlVMTCkKK3sKKwkJbV9wRm9ybUFjdGlvbkhhbmRsZXIgPSBuZXcgQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcjsKK30KKworQ1BERlNES19BY3Rpb25IYW5kbGVyOjp+Q1BERlNES19BY3Rpb25IYW5kbGVyKCkKK3sKKwlpZihtX3BGb3JtQWN0aW9uSGFuZGxlcikKKwl7CisJCWRlbGV0ZSBtX3BGb3JtQWN0aW9uSGFuZGxlcjsKKwkJbV9wRm9ybUFjdGlvbkhhbmRsZXIgPSBOVUxMOworCX0KK30KKwordm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OlNldEZvcm1BY3Rpb25IYW5kbGVyKENQREZTREtfRm9ybUFjdGlvbkhhbmRsZXIqIHBIYW5kbGVyKQoreworCUFTU0VSVChwSGFuZGxlciAhPSBOVUxMKTsKKwlBU1NFUlQobV9wRm9ybUFjdGlvbkhhbmRsZXIgPT0gTlVMTCk7CisJbV9wRm9ybUFjdGlvbkhhbmRsZXIgPSBwSGFuZGxlcjsKK30KKwordm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OlNldE1lZGlhQWN0aW9uSGFuZGxlcihDUERGU0RLX01lZGlhQWN0aW9uSGFuZGxlciogcEhhbmRsZXIpCit7CisJQVNTRVJUKHBIYW5kbGVyICE9IE5VTEwpOworCUFTU0VSVChtX3BNZWRpYUFjdGlvbkhhbmRsZXIgPT0gTlVMTCk7CisJbV9wTWVkaWFBY3Rpb25IYW5kbGVyID0gcEhhbmRsZXI7Cit9CisKK3ZvaWQgQ1BERlNES19BY3Rpb25IYW5kbGVyOjpEZXN0cm95KCkKK3sKKwlkZWxldGUgdGhpczsKK30KKworLy9kb2N1bWVudCBvcGVuCitGWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fRG9jT3Blbihjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQKKwkJCQkJCQkJCQkJCS8qQ1JlYWRlcl9Eb2N1bWVudCogcERvY3VtZW50LCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pCit7CisJQ0ZYX1B0ckxpc3QgbGlzdDsKKwlyZXR1cm4gRXhlY3V0ZURvY3VtZW50T3BlbkFjdGlvbihhY3Rpb24sIHBEb2N1bWVudCwgLypwRG9jVmlldywgKi9saXN0KTsKK30KKworLy9kb2N1bWVudCBvcGVuCitGWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fSmF2YVNjcmlwdChjb25zdCBDUERGX0FjdGlvbiYgSnNBY3Rpb24sQ0ZYX1dpZGVTdHJpbmcgY3NKU05hbWUsCisJCQkJCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcqLykKK3sKKwlpZiAoSnNBY3Rpb24uR2V0VHlwZSgpID09IENQREZfQWN0aW9uOjpKYXZhU2NyaXB0KQorCXsKKwkJQ0ZYX1dpZGVTdHJpbmcgc3dKUyA9IEpzQWN0aW9uLkdldEphdmFTY3JpcHQoKTsKKwkJaWYgKCFzd0pTLklzRW1wdHkoKSkKKwkJeworCQkJUnVuRG9jdW1lbnRPcGVuSmF2YVNjcmlwdChwRG9jdW1lbnQsIGNzSlNOYW1lLCBzd0pTKTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fRmllbGRKYXZhU2NyaXB0KGNvbnN0IENQREZfQWN0aW9uJiBKc0FjdGlvbiwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCAKKwkJCQkJCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIAorCQkJCQkJCQkJUERGU0RLX0ZpZWxkQWN0aW9uJiBkYXRhKQoreworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jdW1lbnQtPkdldEVudigpOworCUFTU0VSVChwRW52KTsKKwlpZiAocEVudi0+SXNKU0luaXRpYXRlZCgpICYmIEpzQWN0aW9uLkdldFR5cGUoKSA9PSBDUERGX0FjdGlvbjo6SmF2YVNjcmlwdCkKKwl7CisJCUNGWF9XaWRlU3RyaW5nIHN3SlMgPSBKc0FjdGlvbi5HZXRKYXZhU2NyaXB0KCk7CisJCWlmICghc3dKUy5Jc0VtcHR5KCkpCisJCXsKKwkJCVJ1bkZpZWxkSmF2YVNjcmlwdChwRG9jdW1lbnQsIHBGb3JtRmllbGQsIHR5cGUsIGRhdGEsIHN3SlMpOworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fUGFnZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBlbnVtIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZVR5cGUsCisJCQkJCQkJCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcqLykKK3sKKwlDRlhfUHRyTGlzdCBsaXN0OworCXJldHVybiBFeGVjdXRlRG9jdW1lbnRQYWdlQWN0aW9uKGFjdGlvbiwgZVR5cGUsIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBsaXN0KTsKK30KKworRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0RvY3VtZW50KGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIGVudW0gQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlVHlwZSwKKwkJCQkJCQkJCQkJIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3Ki8pCit7CisJQ0ZYX1B0ckxpc3QgbGlzdDsKKwlyZXR1cm4gRXhlY3V0ZURvY3VtZW50UGFnZUFjdGlvbihhY3Rpb24sIGVUeXBlLCBwRG9jdW1lbnQsLyogcERvY1ZpZXcsKi8gbGlzdCk7Cit9CisKK0ZYX0JPT0wJQ1BERlNES19BY3Rpb25IYW5kbGVyOjpEb0FjdGlvbl9Cb29rTWFyayhDUERGX0Jvb2ttYXJrICpwQm9va01hcmssIGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgCisJCQkJCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcqLykKK3sKKwlDRlhfUHRyTGlzdCBsaXN0OworCXJldHVybiB0aGlzLT5FeGVjdXRlQm9va01hcmsoYWN0aW9uLCBwRG9jdW1lbnQsLyogcERvY1ZpZXcsKi8gcEJvb2tNYXJrLCBsaXN0KTsKK30KKworRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1NjcmVlbihjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIAorCQkJCQkJCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwvKiBDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3LCovIENQREZTREtfQW5ub3QqIHBTY3JlZW4pCit7CisJQ0ZYX1B0ckxpc3QgbGlzdDsKKwlyZXR1cm4gdGhpcy0+RXhlY3V0ZVNjcmVlbkFjdGlvbihhY3Rpb24sIHR5cGUsIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBwU2NyZWVuLCBsaXN0KTsKK30KKworRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0xpbmsoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgCisJCQkJCQkJCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcqLykKK3sKKwlDRlhfUHRyTGlzdCBsaXN0OworCXJldHVybiBFeGVjdXRlTGlua0FjdGlvbihhY3Rpb24sIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBsaXN0KTsKK30KKworRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0ZpZWxkKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgCisJCQkJCQkJCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LC8qIENSZWFkZXJfRG9jVmlldyAqcERvY1ZpZXcsKi8gCisJCQkJCQkJCQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIFBERlNES19GaWVsZEFjdGlvbiYgZGF0YSkKK3sKKwlDRlhfUHRyTGlzdCBsaXN0OworCXJldHVybiBFeGVjdXRlRmllbGRBY3Rpb24oYWN0aW9uLCB0eXBlLCBwRG9jdW1lbnQsLyogcERvY1ZpZXcsKi8gcEZvcm1GaWVsZCwgZGF0YSwgbGlzdCk7Cit9CisKK0ZYX0JPT0wJQ1BERlNES19BY3Rpb25IYW5kbGVyOjpFeGVjdXRlRG9jdW1lbnRPcGVuQWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwKKwkJCQkJCQkJCQkJCQkgLypDUmVhZGVyX0RvY1ZpZXcgKnBEb2NWaWV3LCovIENGWF9QdHJMaXN0JiBsaXN0KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAobGlzdC5GaW5kKChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbikpCisJCXJldHVybiBGQUxTRTsKKwlsaXN0LkFkZFRhaWwoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKTsKKworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jdW1lbnQtPkdldEVudigpOworCUFTU0VSVChwRW52KTsKKwlpZiAoYWN0aW9uLkdldFR5cGUoKSA9PSBDUERGX0FjdGlvbjo6SmF2YVNjcmlwdCkKKwl7CisJCWlmKHBFbnYtPklzSlNJbml0aWF0ZWQoKSkKKwkJeworCQkJQ0ZYX1dpZGVTdHJpbmcgc3dKUyA9IGFjdGlvbi5HZXRKYXZhU2NyaXB0KCk7CisJCQlpZiAoIXN3SlMuSXNFbXB0eSgpKQorCQkJeworCQkJCVJ1bkRvY3VtZW50T3BlbkphdmFTY3JpcHQocERvY3VtZW50LCBMIiIsIHN3SlMpOworCQkJfQorCQl9CisJfQorCWVsc2UKKwl7CisJCURvQWN0aW9uX05vSnMoYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7CisJfQorCisvLyAJaWYgKCFJc1ZhbGlkRG9jVmlldyhwRG9jdW1lbnQsIHBEb2NWaWV3KSkKKy8vIAkJcmV0dXJuIEZBTFNFOworCisJZm9yIChGWF9JTlQzMiBpPTAsc3o9YWN0aW9uLkdldFN1YkFjdGlvbnNDb3VudCgpOyBpPHN6OyBpKyspCisJeworCQlDUERGX0FjdGlvbiBzdWJhY3Rpb24gPSBhY3Rpb24uR2V0U3ViQWN0aW9uKGkpOworCQlpZiAoIUV4ZWN1dGVEb2N1bWVudE9wZW5BY3Rpb24oc3ViYWN0aW9uLCBwRG9jdW1lbnQsLyogcERvY1ZpZXcsKi8gbGlzdCkpIHJldHVybiBGQUxTRTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkV4ZWN1dGVMaW5rQWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwKKwkJCQkJCQkJCQkJCSAvKkNSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcsKi8gQ0ZYX1B0ckxpc3QmIGxpc3QpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmIChsaXN0LkZpbmQoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKSkKKwkJcmV0dXJuIEZBTFNFOworCWxpc3QuQWRkVGFpbCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pOworCisJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2N1bWVudC0+R2V0RW52KCk7CisJQVNTRVJUKHBFbnYpOworCWlmIChhY3Rpb24uR2V0VHlwZSgpID09IENQREZfQWN0aW9uOjpKYXZhU2NyaXB0KQorCXsKKwkJaWYocEVudi0+SXNKU0luaXRpYXRlZCgpKQorCQl7CisJCQlDRlhfV2lkZVN0cmluZyBzd0pTID0gYWN0aW9uLkdldEphdmFTY3JpcHQoKTsKKwkJCWlmICghc3dKUy5Jc0VtcHR5KCkpCisJCQl7CisJCQkJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwRG9jdW1lbnQtPkdldEpzUnVudGltZSgpOyAvLz8/Pz8KKwkJCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwkJCQlwUnVudGltZS0+U2V0UmVhZGVyRG9jdW1lbnQocERvY3VtZW50KTsKKworCQkJCUlGWEpTX0NvbnRleHQqIHBDb250ZXh0ID0gcFJ1bnRpbWUtPk5ld0NvbnRleHQoKTsKKwkJCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwkJCQlwQ29udGV4dC0+T25MaW5rX01vdXNlVXAocERvY3VtZW50KTsKKworCQkJCUNGWF9XaWRlU3RyaW5nIGNzSW5mbzsKKwkJCQlGWF9CT09MIGJSZXQgPSBwQ29udGV4dC0+UnVuU2NyaXB0KHN3SlMsIGNzSW5mbyk7CisJCQkJaWYgKCFiUmV0KQorCQkJCXsKKwkJCQkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOworCQkJCX0KKworCQkJCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7CisJCQl9CisJCX0KKwl9CisJZWxzZQorCXsKKwkJRG9BY3Rpb25fTm9KcyhhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsKKwl9CisKKy8vIAlpZiAoIUlzVmFsaWREb2NWaWV3KHBEb2N1bWVudCwgcERvY1ZpZXcpKQorLy8gCQlyZXR1cm4gRkFMU0U7CisKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1hY3Rpb24uR2V0U3ViQWN0aW9uc0NvdW50KCk7IGk8c3o7IGkrKykKKwl7CisJCUNQREZfQWN0aW9uIHN1YmFjdGlvbiA9IGFjdGlvbi5HZXRTdWJBY3Rpb24oaSk7CisJCWlmICghRXhlY3V0ZUxpbmtBY3Rpb24oc3ViYWN0aW9uLCBwRG9jdW1lbnQsLyogcERvY1ZpZXcsKi8gbGlzdCkpIHJldHVybiBGQUxTRTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkV4ZWN1dGVEb2N1bWVudFBhZ2VBY3Rpb24oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLAorCQkJCQkJCQkJCQkJIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwvKiBDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIENGWF9QdHJMaXN0JiBsaXN0KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAobGlzdC5GaW5kKChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbikpCisJCXJldHVybiBGQUxTRTsKKwlsaXN0LkFkZFRhaWwoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKTsKKworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jdW1lbnQtPkdldEVudigpOworCUFTU0VSVChwRW52KTsKKwlpZiAoYWN0aW9uLkdldFR5cGUoKSA9PSBDUERGX0FjdGlvbjo6SmF2YVNjcmlwdCkKKwl7CisJCWlmKHBFbnYtPklzSlNJbml0aWF0ZWQoKSkKKwkJeworCQkJQ0ZYX1dpZGVTdHJpbmcgc3dKUyA9IGFjdGlvbi5HZXRKYXZhU2NyaXB0KCk7CisJCQlpZiAoIXN3SlMuSXNFbXB0eSgpKQorCQkJeworCQkJCVJ1bkRvY3VtZW50UGFnZUphdmFTY3JpcHQocERvY3VtZW50LCB0eXBlLCBzd0pTKTsKKwkJCX0KKwkJfQorCX0KKwllbHNlCisJeworCQlEb0FjdGlvbl9Ob0pzKGFjdGlvbiwgcERvY3VtZW50LyosIHBEb2NWaWV3Ki8pOworCX0KKworCWlmICghSXNWYWxpZERvY1ZpZXcocERvY3VtZW50LyosIHBEb2NWaWV3Ki8pKQorCQlyZXR1cm4gRkFMU0U7CisKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1hY3Rpb24uR2V0U3ViQWN0aW9uc0NvdW50KCk7IGk8c3o7IGkrKykKKwl7CisJCUNQREZfQWN0aW9uIHN1YmFjdGlvbiA9IGFjdGlvbi5HZXRTdWJBY3Rpb24oaSk7CisJCWlmICghRXhlY3V0ZURvY3VtZW50UGFnZUFjdGlvbihzdWJhY3Rpb24sIHR5cGUsIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBsaXN0KSkgcmV0dXJuIEZBTFNFOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6SXNWYWxpZEZpZWxkKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9EaWN0aW9uYXJ5KiBwRmllbGREaWN0KQoreworCUFTU0VSVChtX3BFdmkgIT0gTlVMTCk7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKwlBU1NFUlQocEZpZWxkRGljdCAhPSBOVUxMKTsKKworCWlmICgxLyptX3BBcHAtPklzVmFsaWREb2N1bWVudChwRG9jdW1lbnQpKi8pCisJeworCQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJCUNQREZfSW50ZXJGb3JtKiBwUERGSW50ZXJGb3JtID0gcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7CisJCUFTU0VSVChwUERGSW50ZXJGb3JtICE9IE5VTEwpOworCisJCXJldHVybiBwUERGSW50ZXJGb3JtLT5HZXRGaWVsZEJ5RGljdChwRmllbGREaWN0KSAhPSBOVUxMOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkV4ZWN1dGVGaWVsZEFjdGlvbihjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIAorCQkJCQkJCQkJCSAgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LC8qIENSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcsKi8gQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIAorCQkJCQkJCQkJCSAgUERGU0RLX0ZpZWxkQWN0aW9uJiBkYXRhLCBDRlhfUHRyTGlzdCYgbGlzdCkKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKGxpc3QuRmluZCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pKQorCQlyZXR1cm4gRkFMU0U7CisJbGlzdC5BZGRUYWlsKChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbik7CisKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcERvY3VtZW50LT5HZXRFbnYoKTsKKwlBU1NFUlQocEVudik7CisJaWYgKGFjdGlvbi5HZXRUeXBlKCkgPT0gQ1BERl9BY3Rpb246OkphdmFTY3JpcHQpCisJeworCQlpZihwRW52LT5Jc0pTSW5pdGlhdGVkKCkpCisJCXsKKwkJCUNGWF9XaWRlU3RyaW5nIHN3SlMgPSBhY3Rpb24uR2V0SmF2YVNjcmlwdCgpOworCQkJaWYgKCFzd0pTLklzRW1wdHkoKSkKKwkJCXsKKwkJCQlSdW5GaWVsZEphdmFTY3JpcHQocERvY3VtZW50LCBwRm9ybUZpZWxkLCB0eXBlLCBkYXRhLCBzd0pTKTsKKwkJCQlpZiAoIUlzVmFsaWRGaWVsZChwRG9jdW1lbnQsIHBGb3JtRmllbGQtPkdldEZpZWxkRGljdCgpKSkKKwkJCQkJcmV0dXJuIEZBTFNFOworCQkJfQorCQl9CisJfQorCWVsc2UKKwl7CisJCURvQWN0aW9uX05vSnMoYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7CisvLyAJCWlmICghSXNWYWxpZERvY1ZpZXcocERvY3VtZW50LCBwRG9jVmlldykpCisvLyAJCQlyZXR1cm4gRkFMU0U7CisJfQorCisJZm9yIChGWF9JTlQzMiBpPTAsc3o9YWN0aW9uLkdldFN1YkFjdGlvbnNDb3VudCgpOyBpPHN6OyBpKyspCisJeworCQlDUERGX0FjdGlvbiBzdWJhY3Rpb24gPSBhY3Rpb24uR2V0U3ViQWN0aW9uKGkpOworCQlpZiAoIUV4ZWN1dGVGaWVsZEFjdGlvbihzdWJhY3Rpb24sIHR5cGUsIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBwRm9ybUZpZWxkLCBkYXRhLCBsaXN0KSkgcmV0dXJuIEZBTFNFOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RXhlY3V0ZVNjcmVlbkFjdGlvbihjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIAorCQkJCQkJCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwvKiBDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIENQREZTREtfQW5ub3QqIHBTY3JlZW4sIENGWF9QdHJMaXN0JiBsaXN0KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAobGlzdC5GaW5kKChDUERGX0RpY3Rpb25hcnkqKWFjdGlvbikpCisJCXJldHVybiBGQUxTRTsKKwlsaXN0LkFkZFRhaWwoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKTsKKworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jdW1lbnQtPkdldEVudigpOworCUFTU0VSVChwRW52KTsKKwlpZiAoYWN0aW9uLkdldFR5cGUoKSA9PSBDUERGX0FjdGlvbjo6SmF2YVNjcmlwdCkKKwl7CisJCWlmKHBFbnYtPklzSlNJbml0aWF0ZWQoKSkKKwkJeworCQkJQ0ZYX1dpZGVTdHJpbmcgc3dKUyA9IGFjdGlvbi5HZXRKYXZhU2NyaXB0KCk7CisJCQlpZiAoIXN3SlMuSXNFbXB0eSgpKQorCQkJeworCQkJCUlGWEpTX1J1bnRpbWUqIHBSdW50aW1lID0gcERvY3VtZW50LT5HZXRKc1J1bnRpbWUoKTsKKwkJCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwkJCQlwUnVudGltZS0+U2V0UmVhZGVyRG9jdW1lbnQocERvY3VtZW50KTsKKworCQkJCUlGWEpTX0NvbnRleHQqIHBDb250ZXh0ID0gcFJ1bnRpbWUtPk5ld0NvbnRleHQoKTsKKwkJCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwkvLyAJCQlzd2l0Y2ggKHR5cGUpCisJLy8gCQkJeworCS8vIAkJCWNhc2UgQ1BERl9BQWN0aW9uOjpDdXJzb3JFbnRlcjoKKwkvLyAJCQkJcENvbnRleHQtPk9uU2NyZWVuX01vdXNlRW50ZXIoSXNDVFJMcHJlc3NlZCgpLCBJc1NISUZUcHJlc3NlZCgpLCBwU2NyZWVuKTsKKwkvLyAJCQkJYnJlYWs7CisJLy8gCQkJY2FzZSBDUERGX0FBY3Rpb246OkN1cnNvckV4aXQ6CisJLy8gCQkJCXBDb250ZXh0LT5PblNjcmVlbl9Nb3VzZUV4aXQoSXNDVFJMcHJlc3NlZCgpLCBJc1NISUZUcHJlc3NlZCgpLCBwU2NyZWVuKTsKKwkvLyAJCQkJYnJlYWs7CisJLy8gCQkJY2FzZSBDUERGX0FBY3Rpb246OkJ1dHRvbkRvd246CisJLy8gCQkJCXBDb250ZXh0LT5PblNjcmVlbl9Nb3VzZURvd24oSXNDVFJMcHJlc3NlZCgpLCBJc1NISUZUcHJlc3NlZCgpLCBwU2NyZWVuKTsKKwkvLyAJCQkJYnJlYWs7CisJLy8gCQkJY2FzZSBDUERGX0FBY3Rpb246OkJ1dHRvblVwOgorCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fTW91c2VVcChJc0NUUkxwcmVzc2VkKCksIElzU0hJRlRwcmVzc2VkKCksIHBTY3JlZW4pOworCS8vIAkJCQlicmVhazsKKwkvLyAJCQljYXNlIENQREZfQUFjdGlvbjo6R2V0Rm9jdXM6CisJLy8gCQkJCXBDb250ZXh0LT5PblNjcmVlbl9Gb2N1cyhJc0NUUkxwcmVzc2VkKCksIElzU0hJRlRwcmVzc2VkKCksIHBTY3JlZW4pOworCS8vIAkJCQlicmVhazsKKwkvLyAJCQljYXNlIENQREZfQUFjdGlvbjo6TG9zZUZvY3VzOgorCS8vIAkJCQlwQ29udGV4dC0+T25TY3JlZW5fQmx1cihJc0NUUkxwcmVzc2VkKCksIElzU0hJRlRwcmVzc2VkKCksIHBTY3JlZW4pOworCS8vIAkJCQlicmVhazsKKwkvLyAJCQljYXNlIENQREZfQUFjdGlvbjo6UGFnZU9wZW46CisJLy8gCQkJCXBDb250ZXh0LT5PblNjcmVlbl9PcGVuKElzQ1RSTHByZXNzZWQoKSwgSXNTSElGVHByZXNzZWQoKSwgcFNjcmVlbik7CisJLy8gCQkJCWJyZWFrOworCS8vIAkJCWNhc2UgQ1BERl9BQWN0aW9uOjpQYWdlQ2xvc2U6CisJLy8gCQkJCXBDb250ZXh0LT5PblNjcmVlbl9DbG9zZShJc0NUUkxwcmVzc2VkKCksIElzU0hJRlRwcmVzc2VkKCksIHBTY3JlZW4pOworCS8vIAkJCQlicmVhazsKKwkvLyAJCQljYXNlIENQREZfQUFjdGlvbjo6UGFnZVZpc2libGU6CisJLy8gCQkJCXBDb250ZXh0LT5PblNjcmVlbl9JblZpZXcoSXNDVFJMcHJlc3NlZCgpLCBJc1NISUZUcHJlc3NlZCgpLCBwU2NyZWVuKTsKKwkvLyAJCQkJYnJlYWs7CisJLy8gCQkJY2FzZSBDUERGX0FBY3Rpb246OlBhZ2VJbnZpc2libGU6CisJLy8gCQkJCXBDb250ZXh0LT5PblNjcmVlbl9PdXRWaWV3KElzQ1RSTHByZXNzZWQoKSwgSXNTSElGVHByZXNzZWQoKSwgcFNjcmVlbik7CisJLy8gCQkJCWJyZWFrOworCS8vIAkJCWRlZmF1bHQ6CisJLy8gCQkJCUFTU0VSVChGQUxTRSk7CisJLy8gCQkJCWJyZWFrOworCS8vIAkJCX0KKworCQkJCUNGWF9XaWRlU3RyaW5nIGNzSW5mbzsKKwkJCQlGWF9CT09MIGJSZXQgPSBwQ29udGV4dC0+UnVuU2NyaXB0KHN3SlMsIGNzSW5mbyk7CisJCQkJaWYgKCFiUmV0KQorCQkJCXsKKwkJCQkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOworCQkJCX0KKworCQkJCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7CisJCQl9CisJCX0KKwl9CisJZWxzZQorCXsKKwkJRG9BY3Rpb25fTm9KcyhhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsKKwl9CisKKy8vIAlpZiAoIUlzVmFsaWREb2NWaWV3KHBEb2N1bWVudCwgcERvY1ZpZXcpKQorLy8gCQlyZXR1cm4gRkFMU0U7CisKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1hY3Rpb24uR2V0U3ViQWN0aW9uc0NvdW50KCk7IGk8c3o7IGkrKykKKwl7CisJCUNQREZfQWN0aW9uIHN1YmFjdGlvbiA9IGFjdGlvbi5HZXRTdWJBY3Rpb24oaSk7CisJCWlmICghRXhlY3V0ZVNjcmVlbkFjdGlvbihzdWJhY3Rpb24sIHR5cGUsIHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBwU2NyZWVuLCBsaXN0KSkgcmV0dXJuIEZBTFNFOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MCUNQREZTREtfQWN0aW9uSGFuZGxlcjo6RXhlY3V0ZUJvb2tNYXJrKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgCisJCQkJCQkJCQkJLypDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3LCovIENQREZfQm9va21hcmsqIHBCb29rbWFyaywgQ0ZYX1B0ckxpc3QmIGxpc3QpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmIChsaXN0LkZpbmQoKENQREZfRGljdGlvbmFyeSopYWN0aW9uKSkKKwkJcmV0dXJuIEZBTFNFOworCWxpc3QuQWRkVGFpbCgoQ1BERl9EaWN0aW9uYXJ5KilhY3Rpb24pOworCisJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2N1bWVudC0+R2V0RW52KCk7CisJQVNTRVJUKHBFbnYpOworCWlmIChhY3Rpb24uR2V0VHlwZSgpID09IENQREZfQWN0aW9uOjpKYXZhU2NyaXB0KQorCXsKKwkJaWYocEVudi0+SXNKU0luaXRpYXRlZCgpKQorCQl7CisJCQlDRlhfV2lkZVN0cmluZyBzd0pTID0gYWN0aW9uLkdldEphdmFTY3JpcHQoKTsKKwkJCWlmICghc3dKUy5Jc0VtcHR5KCkpCisJCQl7CisJCQkJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwRG9jdW1lbnQtPkdldEpzUnVudGltZSgpOworCQkJCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCQkJCXBSdW50aW1lLT5TZXRSZWFkZXJEb2N1bWVudChwRG9jdW1lbnQpOworCisJCQkJSUZYSlNfQ29udGV4dCogcENvbnRleHQgPSBwUnVudGltZS0+TmV3Q29udGV4dCgpOworCQkJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKworCQkJCXBDb250ZXh0LT5PbkJvb2ttYXJrX01vdXNlVXAocEJvb2ttYXJrKTsKKworCQkJCUNGWF9XaWRlU3RyaW5nIGNzSW5mbzsKKwkJCQlGWF9CT09MIGJSZXQgPSBwQ29udGV4dC0+UnVuU2NyaXB0KHN3SlMsIGNzSW5mbyk7CisJCQkJaWYgKCFiUmV0KQorCQkJCXsKKwkJCQkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOworCQkJCX0KKworCQkJCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7CisJCQl9CisJCX0KKwl9CisJZWxzZQorCXsKKwkJRG9BY3Rpb25fTm9KcyhhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsKKwl9CisKKy8vIAlpZiAoIUlzVmFsaWREb2NWaWV3KHBEb2N1bWVudCwgcERvY1ZpZXcpKQorLy8gCQlyZXR1cm4gRkFMU0U7CisKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1hY3Rpb24uR2V0U3ViQWN0aW9uc0NvdW50KCk7IGk8c3o7IGkrKykKKwl7CisJCUNQREZfQWN0aW9uIHN1YmFjdGlvbiA9IGFjdGlvbi5HZXRTdWJBY3Rpb24oaSk7CisJCWlmICghRXhlY3V0ZUJvb2tNYXJrKHN1YmFjdGlvbiwgcERvY3VtZW50LC8qIHBEb2NWaWV3LCovIHBCb29rbWFyaywgbGlzdCkpIHJldHVybiBGQUxTRTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX05vSnMoY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbiwgQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LyosIENSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcqLykKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJc3dpdGNoIChhY3Rpb24uR2V0VHlwZSgpKQorCXsKKwljYXNlIENQREZfQWN0aW9uOjpHb1RvOgorCQlEb0FjdGlvbl9Hb1RvKHBEb2N1bWVudCwvKiBwRG9jVmlldywqLyBhY3Rpb24pOworCQlicmVhazsKKwljYXNlIENQREZfQWN0aW9uOjpHb1RvUjoKKwkJRG9BY3Rpb25fR29Ub1IocERvY3VtZW50LCBhY3Rpb24pOworCQlicmVhazsKKwljYXNlIENQREZfQWN0aW9uOjpHb1RvRToKKwkJYnJlYWs7CisJY2FzZSBDUERGX0FjdGlvbjo6TGF1bmNoOgorCQlEb0FjdGlvbl9MYXVuY2gocERvY3VtZW50LCBhY3Rpb24pOworCQlicmVhazsKKwljYXNlIENQREZfQWN0aW9uOjpUaHJlYWQ6CisJCWJyZWFrOworCWNhc2UgQ1BERl9BY3Rpb246OlVSSToKKwkJRG9BY3Rpb25fVVJJKHBEb2N1bWVudCwgYWN0aW9uKTsKKwkJYnJlYWs7CisJY2FzZSBDUERGX0FjdGlvbjo6U291bmQ6CisJCWlmIChtX3BNZWRpYUFjdGlvbkhhbmRsZXIpCisJCXsKKwkJCW1fcE1lZGlhQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fU291bmQoYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBDUERGX0FjdGlvbjo6TW92aWU6CisJCWlmIChtX3BNZWRpYUFjdGlvbkhhbmRsZXIpCisJCXsKKwkJCW1fcE1lZGlhQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fTW92aWUoYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBDUERGX0FjdGlvbjo6SGlkZToKKwkJaWYgKG1fcEZvcm1BY3Rpb25IYW5kbGVyKQorCQl7CisJCQltX3BGb3JtQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fSGlkZShhY3Rpb24sIHBEb2N1bWVudCk7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBDUERGX0FjdGlvbjo6TmFtZWQ6CisJCURvQWN0aW9uX05hbWVkKHBEb2N1bWVudCwgYWN0aW9uKTsKKwkJYnJlYWs7CisJY2FzZSBDUERGX0FjdGlvbjo6U3VibWl0Rm9ybToKKwkJaWYgKG1fcEZvcm1BY3Rpb25IYW5kbGVyKQorCQl7CisJCQltX3BGb3JtQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fU3VibWl0Rm9ybShhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsKKwkJfQorCQlicmVhazsKKwljYXNlIENQREZfQWN0aW9uOjpSZXNldEZvcm06CisJCWlmIChtX3BGb3JtQWN0aW9uSGFuZGxlcikKKwkJeworCQkJbV9wRm9ybUFjdGlvbkhhbmRsZXItPkRvQWN0aW9uX1Jlc2V0Rm9ybShhY3Rpb24sIHBEb2N1bWVudCk7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBDUERGX0FjdGlvbjo6SW1wb3J0RGF0YToKKwkJaWYgKG1fcEZvcm1BY3Rpb25IYW5kbGVyKQorCQl7CisJCQltX3BGb3JtQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fSW1wb3J0RGF0YShhY3Rpb24sIHBEb2N1bWVudC8qLCBwRG9jVmlldyovKTsKKwkJfQorCQlicmVhazsKKwljYXNlIENQREZfQWN0aW9uOjpKYXZhU2NyaXB0OgorCQlBU1NFUlQoRkFMU0UpOworCQlicmVhazsKKwljYXNlIENQREZfQWN0aW9uOjpTZXRPQ0dTdGF0ZToKKwkJRG9BY3Rpb25fU2V0T0NHU3RhdGUocERvY3VtZW50LCAvKnBEb2NWaWV3LCovIGFjdGlvbik7CisJCWJyZWFrOworCWNhc2UgQ1BERl9BY3Rpb246OlJlbmRpdGlvbjoKKwkJaWYgKG1fcE1lZGlhQWN0aW9uSGFuZGxlcikKKwkJeworCQkJbV9wTWVkaWFBY3Rpb25IYW5kbGVyLT5Eb0FjdGlvbl9SZW5kaXRpb24oYWN0aW9uLCBwRG9jdW1lbnQvKiwgcERvY1ZpZXcqLyk7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBDUERGX0FjdGlvbjo6VHJhbnM6CisJCWJyZWFrOworCWNhc2UgQ1BERl9BY3Rpb246OkdvVG8zRFZpZXc6CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCWJyZWFrOworCX0KK30KKworRlhfQk9PTAlDUERGU0RLX0FjdGlvbkhhbmRsZXI6OklzVmFsaWREb2NWaWV3KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudC8qLCBDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3Ki8pCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKwkvL0FTU0VSVChwRG9jVmlldyAhPSBOVUxMKTsKKworCS8vcmV0dXJuIHBEb2N1bWVudC0+SXNWYWxpZERvY1ZpZXcocERvY1ZpZXcpOworCXJldHVybiBUUlVFOworfQorCit2b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fR29UbyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIC8qQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldywqLworCQkJCQkJCQkgIGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKy8vCUFTU0VSVChwRG9jVmlldyAhPSBOVUxMKTsKKwlBU1NFUlQoYWN0aW9uICE9IE5VTEwpOworCisJQ1BERl9Eb2N1bWVudCogcFBERkRvY3VtZW50ID0gcERvY3VtZW50LT5HZXREb2N1bWVudCgpOworCUFTU0VSVChwUERGRG9jdW1lbnQgIT0gTlVMTCk7CisJQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBEb2N1bWVudC0+R2V0RW52KCk7CisJQVNTRVJUKHBBcHAgIT0gTlVMTCk7CisKKwlDUERGX0Rlc3QgTXlEZXN0ID0gYWN0aW9uLkdldERlc3QocFBERkRvY3VtZW50KTsKKwlpbnQgblBhZ2VJbmRleCA9IE15RGVzdC5HZXRQYWdlSW5kZXgocFBERkRvY3VtZW50KTsKKwlpbnQgbkZpdFR5cGUgPSBNeURlc3QuR2V0Wm9vbU1vZGUoKTsKKwljb25zdCBDUERGX0FycmF5ICogcE15QXJyYXkgPSAoQ1BERl9BcnJheSopTXlEZXN0Lm1fcE9iajsKKwlmbG9hdCogcFBvc0FyeSA9IE5VTEw7CisJaW50IHNpemVPZkFyeSA9IDA7CisJaWYgKHBNeUFycmF5ICE9IE5VTEwpCisJeworCQlwUG9zQXJ5ID0gbmV3IGZsb2F0W3BNeUFycmF5LT5HZXRDb3VudCgpXTsKKwkJaW50IGogPSAwOworCQlmb3IgKGludCBpID0gMjsgaSA8IChpbnQpcE15QXJyYXktPkdldENvdW50KCk7IGkrKykKKwkJeworCQkJcFBvc0FyeVtqKytdID0gcE15QXJyYXktPkdldEZsb2F0KGkpOworCQl9CisJCXNpemVPZkFyeSA9IGo7CisJfQorCXBBcHAtPkZGSV9Eb0dvVG9BY3Rpb24oblBhZ2VJbmRleCwgbkZpdFR5cGUsIHBQb3NBcnksIHNpemVPZkFyeSk7CisJaWYocFBvc0FyeSkKKwkJZGVsZXRlW10gcFBvc0FyeTsKK30KKwordm9pZCBDUERGU0RLX0FjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX0dvVG9SKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbikKK3sKKworfQorCit2b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fTGF1bmNoKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbikKK3sKKworfQorCit2b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fVVJJKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbikKK3sKKyAJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKyAJQVNTRVJUKGFjdGlvbiAhPSBOVUxMKTsKKworIAlDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwID0gcERvY3VtZW50LT5HZXRFbnYoKTsKKyAJQVNTRVJUKHBBcHAgIT0gTlVMTCk7CisgCisgCUNGWF9CeXRlU3RyaW5nIHNVUkkgPSBhY3Rpb24uR2V0VVJJKHBEb2N1bWVudC0+R2V0RG9jdW1lbnQoKSk7CisgCXBBcHAtPkZGSV9Eb1VSSUFjdGlvbihGWF9MUENTVFIoc1VSSSkpOworfQorCit2b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fTmFtZWQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQoreworIAlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworIAlBU1NFUlQoYWN0aW9uICE9IE5VTEwpOworIAorIAlDRlhfQnl0ZVN0cmluZyBjc05hbWUgPSBhY3Rpb24uR2V0TmFtZWRBY3Rpb24oKTsKKyAJcERvY3VtZW50LT5HZXRFbnYoKS0+RkZJX0V4ZWN1dGVOYW1lZEFjdGlvbihjc05hbWUpOworfQorCisKK3ZvaWQgQ1BERlNES19BY3Rpb25IYW5kbGVyOjpEb0FjdGlvbl9TZXRPQ0dTdGF0ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsLyogQ1JlYWRlcl9Eb2NWaWV3KiBwRG9jVmlldywqLyBjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQoreworfQorCit2b2lkIENQREZTREtfQWN0aW9uSGFuZGxlcjo6UnVuRmllbGRKYXZhU2NyaXB0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwKKwkJCQkJCQkJCQlQREZTREtfRmllbGRBY3Rpb24mIGRhdGEsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQpCit7CisJQVNTRVJUKHR5cGUgIT0gQ1BERl9BQWN0aW9uOjpDYWxjdWxhdGUpOworCUFTU0VSVCh0eXBlICE9IENQREZfQUFjdGlvbjo6Rm9ybWF0KTsKKworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IHBEb2N1bWVudC0+R2V0SnNSdW50aW1lKCk7CisJQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOworCisJcFJ1bnRpbWUtPlNldFJlYWRlckRvY3VtZW50KHBEb2N1bWVudCk7CisKKwlJRlhKU19Db250ZXh0KiBwQ29udGV4dCA9IHBSdW50aW1lLT5OZXdDb250ZXh0KCk7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJc3dpdGNoICh0eXBlKQorCXsKKwljYXNlIENQREZfQUFjdGlvbjo6Q3Vyc29yRW50ZXI6CisJCXBDb250ZXh0LT5PbkZpZWxkX01vdXNlRW50ZXIoZGF0YS5iTW9kaWZpZXIsIGRhdGEuYlNoaWZ0LCBwRm9ybUZpZWxkKTsKKwkJYnJlYWs7CisJY2FzZSBDUERGX0FBY3Rpb246OkN1cnNvckV4aXQ6CisJCXBDb250ZXh0LT5PbkZpZWxkX01vdXNlRXhpdChkYXRhLmJNb2RpZmllciwgZGF0YS5iU2hpZnQsIHBGb3JtRmllbGQpOworCQlicmVhazsKKwljYXNlIENQREZfQUFjdGlvbjo6QnV0dG9uRG93bjoKKwkJcENvbnRleHQtPk9uRmllbGRfTW91c2VEb3duKGRhdGEuYk1vZGlmaWVyLCBkYXRhLmJTaGlmdCwgcEZvcm1GaWVsZCk7CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpCdXR0b25VcDoKKwkJcENvbnRleHQtPk9uRmllbGRfTW91c2VVcChkYXRhLmJNb2RpZmllciwgZGF0YS5iU2hpZnQsIHBGb3JtRmllbGQpOworCQlicmVhazsKKwljYXNlIENQREZfQUFjdGlvbjo6R2V0Rm9jdXM6CisJCXBDb250ZXh0LT5PbkZpZWxkX0ZvY3VzKGRhdGEuYk1vZGlmaWVyLCBkYXRhLmJTaGlmdCwgcEZvcm1GaWVsZCwgZGF0YS5zVmFsdWUpOworCQlicmVhazsKKwljYXNlIENQREZfQUFjdGlvbjo6TG9zZUZvY3VzOgorCQlwQ29udGV4dC0+T25GaWVsZF9CbHVyKGRhdGEuYk1vZGlmaWVyLCBkYXRhLmJTaGlmdCwgcEZvcm1GaWVsZCwgZGF0YS5zVmFsdWUpOworCQlicmVhazsKKwljYXNlIENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlOgorCQlwQ29udGV4dC0+T25GaWVsZF9LZXlzdHJva2UoZGF0YS5uQ29tbWl0S2V5LCBkYXRhLnNDaGFuZ2UsIGRhdGEuc0NoYW5nZUV4LCBkYXRhLmJLZXlEb3duLCAKKwkJCWRhdGEuYk1vZGlmaWVyLCBkYXRhLm5TZWxFbmQsIGRhdGEublNlbFN0YXJ0LCBkYXRhLmJTaGlmdCwgcEZvcm1GaWVsZCwgZGF0YS5zVmFsdWUsCisJCQlkYXRhLmJXaWxsQ29tbWl0LCBkYXRhLmJGaWVsZEZ1bGwsIGRhdGEuYlJDKTsKKwkJYnJlYWs7CisJY2FzZSBDUERGX0FBY3Rpb246OlZhbGlkYXRlOgorCQlwQ29udGV4dC0+T25GaWVsZF9WYWxpZGF0ZShkYXRhLnNDaGFuZ2UsIGRhdGEuc0NoYW5nZUV4LCBkYXRhLmJLZXlEb3duLCBkYXRhLmJNb2RpZmllciwKKwkJCWRhdGEuYlNoaWZ0LCBwRm9ybUZpZWxkLCBkYXRhLnNWYWx1ZSwgZGF0YS5iUkMpOworCQlicmVhazsKKwlkZWZhdWx0OgorCQlBU1NFUlQoRkFMU0UpOworCQlicmVhazsKKwl9CisKKwlDRlhfV2lkZVN0cmluZyBjc0luZm87CisJRlhfQk9PTCBiUmV0ID0gcENvbnRleHQtPlJ1blNjcmlwdChzY3JpcHQsIGNzSW5mbyk7CisJaWYgKCFiUmV0KQorCXsKKwkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOworCX0KKworCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7Cit9CisKK3ZvaWQgQ1BERlNES19BY3Rpb25IYW5kbGVyOjpSdW5Eb2N1bWVudE9wZW5KYXZhU2NyaXB0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNTY3JpcHROYW1lLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IHBEb2N1bWVudC0+R2V0SnNSdW50aW1lKCk7CisJQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOworCisJcFJ1bnRpbWUtPlNldFJlYWRlckRvY3VtZW50KHBEb2N1bWVudCk7CisKKwlJRlhKU19Db250ZXh0KiBwQ29udGV4dCA9IHBSdW50aW1lLT5OZXdDb250ZXh0KCk7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJcENvbnRleHQtPk9uRG9jX09wZW4ocERvY3VtZW50LCBzU2NyaXB0TmFtZSk7CisKKwlDRlhfV2lkZVN0cmluZyBjc0luZm87CisJRlhfQk9PTCBiUmV0ID0gcENvbnRleHQtPlJ1blNjcmlwdChzY3JpcHQsIGNzSW5mbyk7CisJaWYgKCFiUmV0KQorCXsKKwkJLy9DQkNMX0Zvcm1Ob3RpZnk6Ok1zZ0JveEpTRXJyb3IocFBhZ2VWaWV3LT5HZXRQYWdlVmlld1duZCgpLCBjc0luZm8pOworCX0KKworCXBSdW50aW1lLT5SZWxlYXNlQ29udGV4dChwQ29udGV4dCk7Cit9CisKK3ZvaWQgQ1BERlNES19BY3Rpb25IYW5kbGVyOjpSdW5Eb2N1bWVudFBhZ2VKYXZhU2NyaXB0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSB0eXBlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlJRlhKU19SdW50aW1lKiBwUnVudGltZSA9IHBEb2N1bWVudC0+R2V0SnNSdW50aW1lKCk7CisJQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOworCisJcFJ1bnRpbWUtPlNldFJlYWRlckRvY3VtZW50KHBEb2N1bWVudCk7CisKKwlJRlhKU19Db250ZXh0KiBwQ29udGV4dCA9IHBSdW50aW1lLT5OZXdDb250ZXh0KCk7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJc3dpdGNoICh0eXBlKQorCXsJCisJY2FzZSBDUERGX0FBY3Rpb246Ok9wZW5QYWdlOgorCQlwQ29udGV4dC0+T25QYWdlX09wZW4ocERvY3VtZW50KTsKKwkJYnJlYWs7CisJY2FzZSBDUERGX0FBY3Rpb246OkNsb3NlUGFnZToKKwkJcENvbnRleHQtPk9uUGFnZV9DbG9zZShwRG9jdW1lbnQpOworCQlicmVhazsKKwljYXNlIENQREZfQUFjdGlvbjo6Q2xvc2VEb2N1bWVudDoKKwkJcENvbnRleHQtPk9uRG9jX1dpbGxDbG9zZShwRG9jdW1lbnQpOworCQlicmVhazsKKwljYXNlIENQREZfQUFjdGlvbjo6U2F2ZURvY3VtZW50OgorCQlwQ29udGV4dC0+T25Eb2NfV2lsbFNhdmUocERvY3VtZW50KTsKKwkJYnJlYWs7CisJY2FzZSBDUERGX0FBY3Rpb246OkRvY3VtZW50U2F2ZWQ6CisJCXBDb250ZXh0LT5PbkRvY19EaWRTYXZlKHBEb2N1bWVudCk7CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpQcmludERvY3VtZW50OgorCQlwQ29udGV4dC0+T25Eb2NfV2lsbFByaW50KHBEb2N1bWVudCk7CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpEb2N1bWVudFByaW50ZWQ6CisJCXBDb250ZXh0LT5PbkRvY19EaWRQcmludChwRG9jdW1lbnQpOworCQlicmVhazsKKwljYXNlIENQREZfQUFjdGlvbjo6UGFnZVZpc2libGU6CisJCXBDb250ZXh0LT5PblBhZ2VfSW5WaWV3KHBEb2N1bWVudCk7CisJCWJyZWFrOworCWNhc2UgQ1BERl9BQWN0aW9uOjpQYWdlSW52aXNpYmxlOgorCQlwQ29udGV4dC0+T25QYWdlX091dFZpZXcocERvY3VtZW50KTsKKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJQVNTRVJUKEZBTFNFKTsKKwkJYnJlYWs7CisJfQorCisJQ0ZYX1dpZGVTdHJpbmcgY3NJbmZvOworCUZYX0JPT0wgYlJldCA9IHBDb250ZXh0LT5SdW5TY3JpcHQoc2NyaXB0LCBjc0luZm8pOworCWlmICghYlJldCkKKwl7CisJCS8vQ0JDTF9Gb3JtTm90aWZ5OjpNc2dCb3hKU0Vycm9yKHBQYWdlVmlldy0+R2V0UGFnZVZpZXdXbmQoKSwgY3NJbmZvKTsKKwl9CisKKwlwUnVudGltZS0+UmVsZWFzZUNvbnRleHQocENvbnRleHQpOworfQorCisKK0ZYX0JPT0wJQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fSGlkZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKwkKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKwkKKwlpZiAocEludGVyRm9ybS0+RG9BY3Rpb25fSGlkZShhY3Rpb24pKQorCXsKKwkJcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7CisJCXJldHVybiBUUlVFOworCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ1BERlNES19Gb3JtQWN0aW9uSGFuZGxlcjo6RG9BY3Rpb25fU3VibWl0Rm9ybShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKwkKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gcEludGVyRm9ybS0+RG9BY3Rpb25fU3VibWl0Rm9ybShhY3Rpb24pOworfQorCitGWF9CT09MCUNQREZTREtfRm9ybUFjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1Jlc2V0Rm9ybShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKwkKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKwkKKwlpZiAocEludGVyRm9ybS0+RG9BY3Rpb25fUmVzZXRGb3JtKGFjdGlvbikpCisJewkKKwkJcmV0dXJuIFRSVUU7CisJfQorCQorCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAlDUERGU0RLX0Zvcm1BY3Rpb25IYW5kbGVyOjpEb0FjdGlvbl9JbXBvcnREYXRhKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24sIENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCkKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCQorCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCQorCWlmIChwSW50ZXJGb3JtLT5Eb0FjdGlvbl9JbXBvcnREYXRhKGFjdGlvbikpCisJeworCQlwRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsJCisJCXJldHVybiBUUlVFOworCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ1BERlNES19NZWRpYUFjdGlvbkhhbmRsZXI6OkRvQWN0aW9uX1JlbmRpdGlvbihjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNQREZTREtfTWVkaWFBY3Rpb25IYW5kbGVyOjpEb0FjdGlvbl9Tb3VuZChjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNQREZTREtfTWVkaWFBY3Rpb25IYW5kbGVyOjpEb0FjdGlvbl9Nb3ZpZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uLCBDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpCit7CisJcmV0dXJuIEZBTFNFOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9mc2RrX2Fubm90aGFuZGxlci5jcHAgYi9mcGRmc2RrL3NyYy9mc2RrX2Fubm90aGFuZGxlci5jcHAKaW5kZXggYjJhMjRhOC4uOWYyMDhkMyAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnNka19hbm5vdGhhbmRsZXIuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2ZzZGtfYW5ub3RoYW5kbGVyLmNwcApAQCAtMSw5NDUgKzEsOTQ1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfbWdyLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfYW5ub3RoYW5kbGVyLmgiDQotDQotDQotQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkNQREZTREtfQW5ub3RIYW5kbGVyTWdyKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHApDQotew0KLQltX3BBcHAgPSBwQXBwOw0KLQ0KLQlDUERGU0RLX0JGQW5ub3RIYW5kbGVyKiBwSGFuZGxlciA9IG5ldyBDUERGU0RLX0JGQW5ub3RIYW5kbGVyKG1fcEFwcCk7DQotCXBIYW5kbGVyLT5TZXRGb3JtRmlsbGVyKG1fcEFwcC0+R2V0SUZvcm1GaWxsZXIoKSk7DQotCVJlZ2lzdGVyQW5ub3RIYW5kbGVyKHBIYW5kbGVyKTsNCi19DQotDQotQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6On5DUERGU0RLX0Fubm90SGFuZGxlck1ncigpDQotew0KLQlmb3IoaW50IGk9MDsgaTxtX0hhbmRsZXJzLkdldFNpemUoKTsgaSsrKQ0KLQl7DQotCQlJUERGU0RLX0Fubm90SGFuZGxlciogcEhhbmRsZXIgPSBtX0hhbmRsZXJzLkdldEF0KGkpOw0KLQkJZGVsZXRlIHBIYW5kbGVyOw0KLQl9DQotCW1fSGFuZGxlcnMuUmVtb3ZlQWxsKCk7DQotCW1fbWFwVHlwZTJIYW5kbGVyLlJlbW92ZUFsbCgpOw0KLX0NCi0NCi12b2lkCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpSZWdpc3RlckFubm90SGFuZGxlcihJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlcikNCi17DQotCUFTU0VSVChwQW5ub3RIYW5kbGVyICE9IE5VTEwpOw0KLQkNCi0JQVNTRVJUKEdldEFubm90SGFuZGxlcihwQW5ub3RIYW5kbGVyLT5HZXRUeXBlKCkpID09IE5VTEwpOw0KLQkNCi0JbV9IYW5kbGVycy5BZGQocEFubm90SGFuZGxlcik7DQotCW1fbWFwVHlwZTJIYW5kbGVyLlNldEF0KHBBbm5vdEhhbmRsZXItPkdldFR5cGUoKSwgKHZvaWQqKXBBbm5vdEhhbmRsZXIpOw0KLX0NCi0NCi12b2lkIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpVblJlZ2lzdGVyQW5ub3RIYW5kbGVyKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyKQ0KLXsNCi0JQVNTRVJUKHBBbm5vdEhhbmRsZXIgIT0gTlVMTCk7DQotCQ0KLQltX21hcFR5cGUySGFuZGxlci5SZW1vdmVLZXkocEFubm90SGFuZGxlci0+R2V0VHlwZSgpKTsNCi0JDQotCWZvciAoaW50IGk9MCwgc3o9bV9IYW5kbGVycy5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJaWYgKG1fSGFuZGxlcnMuR2V0QXQoaSkgPT0gcEFubm90SGFuZGxlcikNCi0JCXsNCi0JCQltX0hhbmRsZXJzLlJlbW92ZUF0KGkpOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUNQREZTREtfQW5ub3QqIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpOZXdBbm5vdChDUERGX0Fubm90ICogcEFubm90LCBDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQkNCi0JaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdC0+R2V0U3ViVHlwZSgpKSkNCi0Jew0KLQkJcmV0dXJuIHBBbm5vdEhhbmRsZXItPk5ld0Fubm90KHBBbm5vdCwgcFBhZ2VWaWV3KTsNCi0JfQ0KLQkNCi0JcmV0dXJuIG5ldyBDUERGU0RLX0Fubm90KHBBbm5vdCwgcFBhZ2VWaWV3KTsNCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6UmVsZWFzZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCQ0KLQlwQW5ub3QtPkdldFBERlBhZ2UoKTsNCi0JDQotCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQ0KLQl7DQotCQlwQW5ub3RIYW5kbGVyLT5PblJlbGVhc2UocEFubm90KTsNCi0JCXBBbm5vdEhhbmRsZXItPlJlbGVhc2VBbm5vdChwQW5ub3QpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJZGVsZXRlIChDUERGU0RLX0Fubm90KilwQW5ub3Q7DQotCX0NCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25DcmVhdGUoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JDQotCUNQREZfQW5ub3QqIHBQREZBbm5vdCA9IHBBbm5vdC0+R2V0UERGQW5ub3QoKTsNCi0JQVNTRVJUKHBQREZBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBQREZBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQkNCi0JQ1BERlNES19EYXRlVGltZSBjdXJUaW1lOw0KLQlwUERGQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXRTdHJpbmcoIk0iLCBjdXJUaW1lLlRvUERGRGF0ZVRpbWVTdHJpbmcoKSk7DQotCXBQREZBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdE51bWJlcigiRiIsIChpbnQpMCk7CQ0KLQkNCi0JaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpDQotCXsNCi0JCXBBbm5vdEhhbmRsZXItPk9uQ3JlYXRlKHBBbm5vdCk7DQotCX0NCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25Mb2FkKENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCQ0KLQlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkNCi0Jew0KLQkJcEFubm90SGFuZGxlci0+T25Mb2FkKHBBbm5vdCk7DQotCX0NCi19DQotDQotSVBERlNES19Bbm5vdEhhbmRsZXIqIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpHZXRBbm5vdEhhbmRsZXIoQ1BERlNES19Bbm5vdCogcEFubm90KSBjb25zdA0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JDQotCUNQREZfQW5ub3QqIHBQREZBbm5vdCA9IHBBbm5vdC0+R2V0UERGQW5ub3QoKTsNCi0JQVNTRVJUKHBQREZBbm5vdCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBHZXRBbm5vdEhhbmRsZXIocFBERkFubm90LT5HZXRTdWJUeXBlKCkpOw0KLX0NCi0NCi1JUERGU0RLX0Fubm90SGFuZGxlciogQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkdldEFubm90SGFuZGxlcihjb25zdCBDRlhfQnl0ZVN0cmluZyYgc1R5cGUpIGNvbnN0DQotew0KLQl2b2lkKiBwUmV0ID0gTlVMTDsNCi0JbV9tYXBUeXBlMkhhbmRsZXIuTG9va3VwKHNUeXBlLCBwUmV0KTsJDQotCXJldHVybiAoSVBERlNES19Bbm5vdEhhbmRsZXIqKXBSZXQ7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uRHJhdyhDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSxGWF9EV09SRCBkd0ZsYWdzKQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JDQotCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQ0KLQl7DQotCQlwQW5ub3RIYW5kbGVyLT5PbkRyYXcocFBhZ2VWaWV3LCBwQW5ub3QsIHBEZXZpY2UsIHBVc2VyMkRldmljZSwgZHdGbGFncyk7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlwQW5ub3QtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsNCi0JfQ0KLX0NCi0NCi0NCi1GWF9CT09MIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpBbm5vdF9PbkxCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCQ0KLQlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkNCi0Jew0KLQkJcmV0dXJuIHBBbm5vdEhhbmRsZXItPk9uTEJ1dHRvbkRvd24ocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLSB7DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotDQotCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQ0KLQl7DQotCQlyZXR1cm4gcEFubm90SGFuZGxlci0+T25MQnV0dG9uVXAocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi0gfQ0KLUZYX0JPT0wgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQkNCi0JaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpDQotCXsNCi0JCXJldHVybiBwQW5ub3RIYW5kbGVyLT5PbkxCdXR0b25EYmxDbGsocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25Nb3VzZU1vdmUoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JDQotCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQ0KLQl7DQotCQlyZXR1cm4gcEFubm90SGFuZGxlci0+T25Nb3VzZU1vdmUocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25Nb3VzZVdoZWVsKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JDQotCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQ0KLQl7DQotCQlyZXR1cm4gcEFubm90SGFuZGxlci0+T25Nb3VzZVdoZWVsKHBQYWdlVmlldywgcEFubm90LG5GbGFncyx6RGVsdGEsIHBvaW50KTsNCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLUZYX0JPT0wgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uUkJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JDQotCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQ0KLQl7DQotCQlyZXR1cm4gcEFubm90SGFuZGxlci0+T25SQnV0dG9uRG93bihwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi1GWF9CT09MIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpBbm5vdF9PblJCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQkNCi0JaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpDQotCXsNCi0JCXJldHVybiBwQW5ub3RIYW5kbGVyLT5PblJCdXR0b25VcChwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpBbm5vdF9Pbk1vdXNlRW50ZXIoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCQ0KLQlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkNCi0Jew0KLQkJcEFubm90SGFuZGxlci0+T25Nb3VzZUVudGVyKHBQYWdlVmlldywgcEFubm90LCBuRmxhZyk7DQotCX0NCi0JcmV0dXJuIDsNCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25Nb3VzZUV4aXQoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCQ0KLQlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkNCi0Jew0KLQkJcEFubm90SGFuZGxlci0+T25Nb3VzZUV4aXQocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFnKTsNCi0JfQ0KLQlyZXR1cm47DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uQ2hhcihDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZ3MpDQotew0KLQ0KLQlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkNCi0Jew0KLQkJcmV0dXJuIHBBbm5vdEhhbmRsZXItPk9uQ2hhcihwQW5ub3QsbkNoYXIsIG5GbGFncyk7DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLQ0KLX0NCi0NCi1GWF9CT09MCQkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIGludCBuS2V5Q29kZSwgaW50IG5GbGFnKQ0KLXsNCi0NCi0JaWYgKCFtX3BBcHAtPkZGSV9Jc0NUUkxLZXlEb3duKG5GbGFnKSAmJiAhbV9wQXBwLT5GRklfSXNBTFRLZXlEb3duKG5GbGFnKSkNCi0Jew0KLQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2UgPSBwQW5ub3QtPkdldFBhZ2VWaWV3KCk7DQotCQlDUERGU0RLX0Fubm90KiBwRm9jdXNBbm5vdCA9IHBQYWdlLT5HZXRGb2N1c0Fubm90KCk7DQotCQlpZiAocEZvY3VzQW5ub3QgJiYgKG5LZXlDb2RlID09IEZXTF9WS0VZX1RhYikpDQotCQl7DQotCQkJQ1BERlNES19Bbm5vdCogcE5leHQgPSBHZXROZXh0QW5ub3QocEZvY3VzQW5ub3QsICFtX3BBcHAtPkZGSV9Jc1NISUZUS2V5RG93bihuRmxhZykpOw0KLQ0KLQkJCWlmKHBOZXh0ICYmIHBOZXh0ICE9IHBGb2N1c0Fubm90KQ0KLQkJCXsNCi0JCQkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50ID0gcFBhZ2UtPkdldFNES0RvY3VtZW50KCk7DQotCQkJCXBEb2N1bWVudC0+U2V0Rm9jdXNBbm5vdChwTmV4dCk7DQotCQkJCXJldHVybiBUUlVFOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkNCi0Jew0KLQkJcmV0dXJuIHBBbm5vdEhhbmRsZXItPk9uS2V5RG93bihwQW5ub3QsbktleUNvZGUsIG5GbGFnKTsNCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLUZYX0JPT0wJCQlDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25LZXlVcChDUERGU0RLX0Fubm90KiBwQW5ub3QsIGludCBuS2V5Q29kZSwgaW50IG5GbGFnKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCQkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uU2V0Rm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotDQotCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQ0KLQl7DQotCQlpZiAocEFubm90SGFuZGxlci0+T25TZXRGb2N1cyhwQW5ub3QsIG5GbGFnKSkNCi0JCXsNCi0JCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZSA9IHBBbm5vdC0+R2V0UGFnZVZpZXcoKTsNCi0JCQlBU1NFUlQocFBhZ2UgIT0gTlVMTCk7DQotDQotCQkJcFBhZ2UtPkdldFNES0RvY3VtZW50KCk7DQotCS8vCQlwRG9jdW1lbnQtPlNldFRvcG1vc3RBbm5vdChwQW5ub3QpOw0KLQ0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCXJldHVybiBGQUxTRTsNCi0JCX0NCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCQkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQkNCi0JaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpDQotCXsNCi0JCWlmIChwQW5ub3RIYW5kbGVyLT5PbktpbGxGb2N1cyhwQW5ub3QsIG5GbGFnKSkNCi0JCXsJDQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCQllbHNlDQotCQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUNQREZfUmVjdAlDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25HZXRWaWV3QkJveChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCUFTU0VSVChwQW5ub3QpOw0KLQlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkNCi0Jew0KLQkJcmV0dXJuIHBBbm5vdEhhbmRsZXItPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KTsNCi0JfQ0KLQlyZXR1cm4gcEFubm90LT5HZXRSZWN0KCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uSGl0VGVzdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlBU1NFUlQocEFubm90KTsNCi0JaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpDQotCXsNCi0JCWlmKHBBbm5vdEhhbmRsZXItPkNhbkFuc3dlcihwQW5ub3QpKQ0KLQkJCXJldHVybiBwQW5ub3RIYW5kbGVyLT5IaXRUZXN0KHBQYWdlVmlldywgcEFubm90LCBwb2ludCk7DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1DUERGU0RLX0Fubm90KglDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6R2V0TmV4dEFubm90KENQREZTREtfQW5ub3QqIHBTREtBbm5vdCxGWF9CT09MIGJOZXh0KQ0KLXsNCi0JIENCQV9Bbm5vdEl0ZXJhdG9yIGFpKHBTREtBbm5vdC0+R2V0UGFnZVZpZXcoKSwgIldpZGdldCIsICIiKTsNCi0NCi0JIENQREZTREtfQW5ub3QqIHBOZXh0ID0gYk5leHQgPyANCi0JCSBhaS5HZXROZXh0QW5ub3QocFNES0Fubm90KSA6IA0KLQkJYWkuR2V0UHJldkFubm90KHBTREtBbm5vdCk7DQotCQ0KLQkJcmV0dXJuIHBOZXh0Ow0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfQkZBbm5vdEhhbmRsZXI6OkNhbkFuc3dlcihDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLQlBU1NFUlQocEFubm90KTsNCi0JQVNTRVJUKHBBbm5vdC0+R2V0VHlwZSgpID09ICJXaWRnZXQiKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsNCi0JDQotCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkNCi0Jew0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsNCi0JCWlmICghcFdpZGdldC0+SXNWaXNpYmxlKCkpIHJldHVybiBGQUxTRTsNCi0NCi0JCWludCBuRmllbGRGbGFncyA9IHBXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKTsNCi0JCWlmICgobkZpZWxkRmxhZ3MgJiBGSUVMREZMQUdfUkVBRE9OTFkpID09IEZJRUxERkxBR19SRUFET05MWSkgcmV0dXJuIEZBTFNFOw0KLQkJaWYgKHBXaWRnZXQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQ0KLQkJCXJldHVybiBUUlVFOw0KLQkJZWxzZQ0KLQkJew0KLQkJCUNQREZfUGFnZSogcFBhZ2UgPSBwV2lkZ2V0LT5HZXRQREZQYWdlKCk7DQotCQkJQVNTRVJUKHBQYWdlICE9IE5VTEwpOw0KLQkJCQ0KLQkJCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IHBQYWdlLT5tX3BEb2N1bWVudDsNCi0JCQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQkJCQ0KLQkJCUZYX0RXT1JEIGR3UGVybWlzc2lvbnMgPSBwRG9jdW1lbnQtPkdldFVzZXJQZXJtaXNzaW9ucygpOw0KLQkJCXJldHVybiAoZHdQZXJtaXNzaW9ucyZGUERGUEVSTV9GSUxMX0ZPUk0pIHx8IA0KLQkJCQkoZHdQZXJtaXNzaW9ucyZGUERGUEVSTV9BTk5PVF9GT1JNKSB8fCANCi0gCQkJKGR3UGVybWlzc2lvbnMmRlBERlBFUk1fQU5OT1RfRk9STSk7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1DUERGU0RLX0Fubm90KgkJQ1BERlNES19CRkFubm90SGFuZGxlcjo6TmV3QW5ub3QoQ1BERl9Bbm5vdCogcEFubm90LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZSkNCi17DQotCUFTU0VSVChwUGFnZSAhPSBOVUxMKTsNCi0JcFBhZ2UtPkdldFBERkRvY3VtZW50KCk7DQotCQ0KLQlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jICA9IG1fcEFwcC0+R2V0Q3VycmVudERvYygpOw0KLQlBU1NFUlQocFNES0RvYyk7DQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwU0RLRG9jLT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotCQ0KLQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IE5VTEw7DQotCWlmIChDUERGX0Zvcm1Db250cm9sKiBwQ3RybCA9IENQREZTREtfV2lkZ2V0OjpHZXRGb3JtQ29udHJvbChwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKSwgcEFubm90LT5tX3BBbm5vdERpY3QpKQ0KLQl7DQotCQlwV2lkZ2V0ID0gbmV3IENQREZTREtfV2lkZ2V0KHBBbm5vdCwgcFBhZ2UsIHBJbnRlckZvcm0pOw0KLQkJcEludGVyRm9ybS0+QWRkTWFwKHBDdHJsLCBwV2lkZ2V0KTsNCi0JCUNQREZfSW50ZXJGb3JtKiBwUERGSW50ZXJGb3JtID0gcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCQlpZihwUERGSW50ZXJGb3JtICYmIHBQREZJbnRlckZvcm0tPk5lZWRDb25zdHJ1Y3RBUCgpKQ0KLQkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShOVUxMLEZBTFNFKTsNCi0JfQ0KLQkNCi0JcmV0dXJuIHBXaWRnZXQ7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19CRkFubm90SGFuZGxlcjo6UmVsZWFzZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotDQotCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJbV9wRm9ybUZpbGxlci0+T25EZWxldGUocEFubm90KTsNCi0JDQotCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7DQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gcFdpZGdldC0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQkNCi0JQ1BERl9Gb3JtQ29udHJvbCogcEN0cm9sID0gcFdpZGdldC0+R2V0Rm9ybUNvbnRyb2woKTsNCi0JcEludGVyRm9ybS0+UmVtb3ZlTWFwKHBDdHJvbCk7DQotCQ0KLQ0KLQlkZWxldGUgcFdpZGdldDsNCi19DQotDQotDQotdm9pZCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbkRyYXcoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsICBGWF9EV09SRCBkd0ZsYWdzKQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsNCi0JDQotCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkNCi0Jew0KLQkJcEFubm90LT5EcmF3QXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIENQREZfQW5ub3Q6Ok5vcm1hbCwgTlVMTCk7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlpZiAobV9wRm9ybUZpbGxlcikNCi0JCXsNCi0JCQltX3BGb3JtRmlsbGVyLT5PbkRyYXcocFBhZ2VWaWV3LCBwQW5ub3QsIHBEZXZpY2UsIHBVc2VyMkRldmljZSwgZHdGbGFncyk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbk1vdXNlRW50ZXIoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKSANCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCSBtX3BGb3JtRmlsbGVyLT5Pbk1vdXNlRW50ZXIocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFnKTsNCi0JfQ0KLQkNCi0NCi19DQotdm9pZCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbk1vdXNlRXhpdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpIA0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsNCi0JDQotCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkNCi0Jew0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKG1fcEZvcm1GaWxsZXIpDQotCQkJIG1fcEZvcm1GaWxsZXItPk9uTW91c2VFeGl0KHBQYWdlVmlldywgcEFubm90LCBuRmxhZyk7DQotCX0NCi0JDQotfQ0KLUZYX0JPT0wgQ1BERlNES19CRkFubm90SGFuZGxlcjo6T25MQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5PbkxCdXR0b25Eb3duKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsNCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uTEJ1dHRvblVwKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsNCi0JDQotCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkNCi0Jew0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKG1fcEZvcm1GaWxsZXIpDQotCQkJcmV0dXJuIG1fcEZvcm1GaWxsZXItPk9uTEJ1dHRvblVwKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsNCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5PbkxCdXR0b25EYmxDbGsocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOw0KLQl9DQotCQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19CRkFubm90SGFuZGxlcjo6T25Nb3VzZU1vdmUoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotewkNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsNCi0NCi0JaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQ0KLQl7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlpZiAobV9wRm9ybUZpbGxlcikNCi0JCQlyZXR1cm4gbV9wRm9ybUZpbGxlci0+T25Nb3VzZU1vdmUocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi0NCi19DQotDQotDQotRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbk1vdXNlV2hlZWwoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5Pbk1vdXNlV2hlZWwocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgekRlbHRhLHBvaW50KTsNCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uUkJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOw0KLQkNCi0JaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQ0KLQl7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlpZiAobV9wRm9ybUZpbGxlcikNCi0JCQlyZXR1cm4gbV9wRm9ybUZpbGxlci0+T25SQnV0dG9uRG93bihwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPblJCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5PblJCdXR0b25VcChwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWdzKQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsNCi0JDQotCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkNCi0Jew0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKG1fcEZvcm1GaWxsZXIpDQotCQkJcmV0dXJuIG1fcEZvcm1GaWxsZXItPk9uQ2hhcihwQW5ub3QsbkNoYXIsIG5GbGFncyk7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbktleURvd24oQ1BERlNES19Bbm5vdCogcEFubm90LCBpbnQgbktleUNvZGUsIGludCBuRmxhZykNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5PbktleURvd24ocEFubm90LG5LZXlDb2RlLCBuRmxhZyk7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbktleVVwKENQREZTREtfQW5ub3QqIHBBbm5vdCwgaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpDQotew0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLXZvaWQJQ1BERlNES19CRkFubm90SGFuZGxlcjo6T25DcmVhdGUoQ1BERlNES19Bbm5vdCogcEFubm90KSANCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCW1fcEZvcm1GaWxsZXItPk9uQ3JlYXRlKHBBbm5vdCk7DQotCX0NCi19DQotDQotdm9pZCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbkxvYWQoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0JDQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwQW5ub3Q7DQotCQkNCi0JaWYgKCFwV2lkZ2V0LT5Jc0FwcGVhcmFuY2VWYWxpZCgpKQ0KLQkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShOVUxMLCBGQUxTRSk7DQotCQkNCi0JCWludCBuRmllbGRUeXBlID0gcFdpZGdldC0+R2V0RmllbGRUeXBlKCk7DQotCQkNCi0JCWlmIChuRmllbGRUeXBlID09IEZJRUxEVFlQRV9URVhURklFTEQgfHwgbkZpZWxkVHlwZSA9PSBGSUVMRFRZUEVfQ09NQk9CT1gpDQotCQl7DQotCQkJRlhfQk9PTCBiRm9ybWF0ZWQgPSBGQUxTRTsNCi0JCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwV2lkZ2V0LT5PbkZvcm1hdCgwLCBiRm9ybWF0ZWQpOw0KLQkJCQ0KLQkJCWlmIChiRm9ybWF0ZWQgJiYgbkZpZWxkVHlwZSA9PSBGSUVMRFRZUEVfQ09NQk9CT1gpDQotCQkJew0KLQkJCQlwV2lkZ2V0LT5SZXNldEFwcGVhcmFuY2Uoc1ZhbHVlLCBGQUxTRSk7DQotCQkJfQ0KLQkJfQ0KLQkJDQotDQotCQlpZiAobV9wRm9ybUZpbGxlcikNCi0JCQltX3BGb3JtRmlsbGVyLT5PbkxvYWQocEFubm90KTsNCi0NCi0JfQ0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uU2V0Rm9jdXMoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5PblNldEZvY3VzKHBBbm5vdCxuRmxhZyk7DQotCX0NCi0JDQotCXJldHVybiBUUlVFOw0KLX0NCi1GWF9CT09MCUNQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOw0KLQkNCi0JaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQ0KLQl7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlpZiAobV9wRm9ybUZpbGxlcikNCi0JCQlyZXR1cm4gbV9wRm9ybUZpbGxlci0+T25LaWxsRm9jdXMocEFubm90LG5GbGFnKTsNCi0JfQ0KLQkNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpHZXRWaWV3QkJveChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCkNCi17DQotCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7DQotCQ0KLQlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpDQotCXsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BGb3JtRmlsbGVyKQ0KLQkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5HZXRWaWV3QkJveChwUGFnZVZpZXcsIHBBbm5vdCk7DQotDQotCX0NCi0JDQotCXJldHVybiBDUERGX1JlY3QoMCwwLDAsMCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19CRkFubm90SGFuZGxlcjo6SGl0VGVzdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlBU1NFUlQocFBhZ2VWaWV3KTsNCi0JQVNTRVJUKHBBbm5vdCk7DQotDQotCUNQREZfUmVjdCByZWN0ID0gR2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBwQW5ub3QpOw0KLQlyZXR1cm4gcmVjdC5Db250YWlucyhwb2ludC54LCBwb2ludC55KTsNCi19DQotDQotLy9DUmVhZGVyX0Fubm90SXRlcmF0b3JFeA0KLQ0KLUNQREZTREtfQW5ub3RJdGVyYXRvcjo6Q1BERlNES19Bbm5vdEl0ZXJhdG9yKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsRlhfQk9PTCBiUmV2ZXJzZSwNCi0JCQkJCQkJCQkJCQkgRlhfQk9PTCBiSWdub3JlVG9wbW9zdC8qPUZBTFNFKi8sDQotCQkJCQkJCQkJCQkJIEZYX0JPT0wgYkNpcmNsZS8qPUZBTFNFKi8sDQotCQkJCQkJCQkJCQkJIENGWF9QdHJBcnJheSAqcExpc3QvKj1OVUxMKi8pDQotew0KLQlBU1NFUlQocFBhZ2VWaWV3KTsNCi0JbV9iUmV2ZXJzZT1iUmV2ZXJzZTsNCi0JbV9iSWdub3JlVG9wbW9zdD0gYklnbm9yZVRvcG1vc3Q7DQotCW1fYkNpcmNsZT1iQ2lyY2xlOw0KLQltX3BJdGVyYXRvckFubm90TGlzdC5SZW1vdmVBbGwoKTsNCi0JSW5pdEl0ZXJhdG9yQW5ub3RMaXN0KHBQYWdlVmlldyxwTGlzdCk7DQotfQ0KLQ0KLUNQREZTREtfQW5ub3QqCUNQREZTREtfQW5ub3RJdGVyYXRvcjo6TmV4dEFubm90IChjb25zdCBDUERGU0RLX0Fubm90KiBwQ3VycmVudCkgDQotew0KLQkNCi0JaW50IGluZGV4PS0xOw0KLQlpbnQgbkNvdW50PXRoaXMtPm1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldFNpemUoKTsNCi0JaWYocEN1cnJlbnQpew0KLQkJZm9yKGludCBpPTA7aTxuQ291bnQ7aSsrKXsNCi0JCQlDUERGU0RLX0Fubm90ICogcFJlYWRlckFubm90PSAoQ1BERlNES19Bbm5vdCAqKW1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldEF0KGkpOw0KLQkJCWlmKHBSZWFkZXJBbm5vdCA9PXBDdXJyZW50KXsJCQkNCi0JCQkJaW5kZXg9aTsNCi0JCQkJYnJlYWs7DQotCQkJfQkJCQ0KLQkJfQ0KLQl9CQ0KLQlyZXR1cm4gTmV4dEFubm90KGluZGV4KTsNCi19DQotQ1BERlNES19Bbm5vdCoJQ1BERlNES19Bbm5vdEl0ZXJhdG9yOjpQcmV2QW5ub3QgKGNvbnN0IENQREZTREtfQW5ub3QqcEN1cnJlbnQpDQotew0KLQkNCi0JaW50IGluZGV4PS0xOw0KLQlpbnQgbkNvdW50PXRoaXMtPm1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldFNpemUoKTsNCi0JaWYocEN1cnJlbnQpew0KLQkJZm9yKGludCBpPTA7aTxuQ291bnQ7aSsrKXsNCi0JCQlDUERGU0RLX0Fubm90ICogcFJlYWRlckFubm90PSAoQ1BERlNES19Bbm5vdCopbV9wSXRlcmF0b3JBbm5vdExpc3QuR2V0QXQoaSk7DQotCQkJaWYocFJlYWRlckFubm90ID09cEN1cnJlbnQpewkJCQ0KLQkJCQlpbmRleD1pOw0KLQkJCQlicmVhazsNCi0JCQl9CQkJDQotCQl9CQ0KLQl9DQotCXJldHVybiBQcmV2QW5ub3QoaW5kZXgpOwkNCi19DQotQ1BERlNES19Bbm5vdCoJQ1BERlNES19Bbm5vdEl0ZXJhdG9yOjpOZXh0QW5ub3QgKGludCYgaW5kZXgpIA0KLXsJDQotCQ0KLQlpbnQgbkNvdW50PW1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldFNpemUoKTsNCi0gICAgaWYobkNvdW50PD0wKSBpbmRleD0tMTsNCi0gICAgZWxzZXsNCi0JCWlmKGluZGV4PDApew0KLQkJCWluZGV4PTA7CQkNCi0JCX0NCi0JCWVsc2V7CQkNCi0JCQlpZihtX2JDaXJjbGUpewkJCQ0KLQkJCQlpbmRleD0oIGluZGV4IDxuQ291bnQtMSkgPyAoaW5kZXgrMSkgOjA7CQkNCi0JCQl9DQotCQkJZWxzZXsNCi0JCQkJaW5kZXg9KCBpbmRleCA8bkNvdW50LTEpID8gKGluZGV4KzEpIDotMTsJCQ0KLQkJCX0NCi0JCQkNCi0JCX0JDQotCX0NCi0JcmV0dXJuIChpbmRleCA8MCkgPyBOVUxMIDogKENQREZTREtfQW5ub3QqKW1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldEF0KGluZGV4KTsJCQ0KLX0NCi0NCi0NCi1DUERGU0RLX0Fubm90KglDUERGU0RLX0Fubm90SXRlcmF0b3I6OlByZXZBbm5vdCAoaW50JiBpbmRleCkNCi17DQotCQ0KLQlpbnQgbkNvdW50PW1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldFNpemUoKTsNCi0gICAgaWYobkNvdW50PD0wKSBpbmRleD0tMTsNCi0JZWxzZXsJDQotCQlpZihpbmRleDwwKXsNCi0JCQlpbmRleD1uQ291bnQtMTsJCSANCi0JCX0NCi0JCWVsc2V7CQ0KLQkJCWlmKG1fYkNpcmNsZSl7CQkJDQotCQkJCWluZGV4ID0gKCBpbmRleCA+MCkgPyAoaW5kZXgtMSkgOm5Db3VudC0xOwkJDQotCQkJfQ0KLQkJCWVsc2V7DQotCQkJCWluZGV4ID0gKCBpbmRleCA+MCkgPyAoaW5kZXgtMSkgOi0xOwkNCi0JCQl9CQkJCQ0KLQkJfQ0KLQl9DQotCXJldHVybiAoaW5kZXggPDApID8gTlVMTCA6IChDUERGU0RLX0Fubm90KiltX3BJdGVyYXRvckFubm90TGlzdC5HZXRBdChpbmRleCk7CQkNCi19DQotDQotDQotQ1BERlNES19Bbm5vdCpDUERGU0RLX0Fubm90SXRlcmF0b3I6Ok5leHQoY29uc3QgQ1BERlNES19Bbm5vdCogcEN1cnJlbnQpIA0KLXsNCi0NCi0JcmV0dXJuIChtX2JSZXZlcnNlKSA/IFByZXZBbm5vdChwQ3VycmVudCk6TmV4dEFubm90KHBDdXJyZW50KTsJCSANCi0NCi19DQotDQotQ1BERlNES19Bbm5vdCoJQ1BERlNES19Bbm5vdEl0ZXJhdG9yOjpQcmV2KGNvbnN0IENQREZTREtfQW5ub3QqIHBDdXJyZW50KSANCi17DQotDQotCXJldHVybiAobV9iUmV2ZXJzZSkgPyBOZXh0QW5ub3QocEN1cnJlbnQpOlByZXZBbm5vdChwQ3VycmVudCk7CQkgDQotfQ0KLQ0KLUNQREZTREtfQW5ub3QqQ1BERlNES19Bbm5vdEl0ZXJhdG9yOjpOZXh0KGludCYgaW5kZXggKQ0KLXsNCi0JDQotCXJldHVybiAobV9iUmV2ZXJzZSkgPyBQcmV2QW5ub3QoaW5kZXgpOk5leHRBbm5vdChpbmRleCk7CQkgDQotCQ0KLX0NCi0NCi1DUERGU0RLX0Fubm90KglDUERGU0RLX0Fubm90SXRlcmF0b3I6OlByZXYoaW50JiBpbmRleCApDQotew0KLQkNCi0JcmV0dXJuIChtX2JSZXZlcnNlKSA/IE5leHRBbm5vdChpbmRleCk6UHJldkFubm90KGluZGV4KTsJCSANCi19DQotDQotDQotdm9pZCBDUERGU0RLX0Fubm90SXRlcmF0b3I6Okluc2VydFNvcnQoQ0ZYX1B0ckFycmF5ICZhcnJheUxpc3QsIEFJX0NPTVBBUkUgcENvbXBhcmUpDQotew0KLQlmb3IgKGludCBpID0gMTsgaSA8IGFycmF5TGlzdC5HZXRTaXplKCk7IGkrKykNCi0Jew0KLQkJaWYgKHBDb21wYXJlKChDUERGU0RLX0Fubm90KikoYXJyYXlMaXN0W2ldKSAsIChDUERGU0RLX0Fubm90KikoYXJyYXlMaXN0W2ktMV0pKSA8IDApDQotCQl7DQotCQkJaW50IGogPSBpLTE7DQotCQkJQ1BERlNES19Bbm5vdCogcFRlbXAgPSAoQ1BERlNES19Bbm5vdCopYXJyYXlMaXN0W2ldOw0KLQkJCQ0KLQkJCWRvDQotCQkJew0KLQkJCQlhcnJheUxpc3RbaiArIDFdID0gYXJyYXlMaXN0W2pdOw0KLQkJCX0gd2hpbGUgKC0taiA+PSAwICYmIHBDb21wYXJlKHBUZW1wLCAoQ1BERlNES19Bbm5vdCopYXJyYXlMaXN0W2pdKSA8IDApOw0KLQ0KLQkJCWFycmF5TGlzdFtqKzFdID0gcFRlbXA7DQotCQl9DQotCX0NCi19DQotDQotaW50IEx5T3JkZXJDb21wYXJlKENQREZTREtfQW5ub3QqIHAxLCBDUERGU0RLX0Fubm90KiBwMikNCi17DQotCWlmKHAxLT5HZXRMYXlvdXRPcmRlcigpIDwgcDItPkdldExheW91dE9yZGVyKCkpDQotCQlyZXR1cm4gLTE7DQotCWVsc2UgaWYgKHAxLT5HZXRMYXlvdXRPcmRlcigpID09IHAyLT5HZXRMYXlvdXRPcmRlcigpKQ0KLQkJcmV0dXJuIDA7DQotCWVsc2UNCi0JCXJldHVybiAxOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfQW5ub3RJdGVyYXRvcjo6SW5pdEl0ZXJhdG9yQW5ub3RMaXN0KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyxDRlhfUHRyQXJyYXkgKiBwQW5ub3RMaXN0KQ0KLXsNCi0JQVNTRVJUKHBQYWdlVmlldyk7DQotCQ0KLQkNCi0NCi0JaWYocEFubm90TGlzdD09TlVMTCl7CQ0KLQkJcEFubm90TGlzdD1wUGFnZVZpZXctPkdldEFubm90TGlzdCgpOw0KLQl9DQotDQotCXRoaXMtPm1fcEl0ZXJhdG9yQW5ub3RMaXN0LlJlbW92ZUFsbCgpOw0KLQlpZighcEFubm90TGlzdCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDUERGU0RLX0Fubm90ICogcFRvcE1vc3RBbm5vdD0gKG1fYklnbm9yZVRvcG1vc3QpID8gTlVMTCA6IHBQYWdlVmlldy0+R2V0Rm9jdXNBbm5vdCgpOw0KLQ0KLQ0KLQlpbnQgbkNvdW50ID1wQW5ub3RMaXN0LT5HZXRTaXplKCk7DQotDQotCWZvcihpbnQgaSA9IG5Db3VudC0gMSA7aSA+PSAwO2ktLSkNCi0Jew0KLQkJQ1BERlNES19Bbm5vdCAqIHBSZWFkZXJBbm5vdD0gKENQREZTREtfQW5ub3QqKXBBbm5vdExpc3QtPkdldEF0KGkpOw0KLQkJbV9wSXRlcmF0b3JBbm5vdExpc3QuQWRkKHBSZWFkZXJBbm5vdCk7CQ0KLQl9DQotDQotCUluc2VydFNvcnQobV9wSXRlcmF0b3JBbm5vdExpc3QsJkx5T3JkZXJDb21wYXJlKTsNCi0NCi0JaWYocFRvcE1vc3RBbm5vdCkNCi0Jew0KLQkJZm9yKGludCBpPTAgO2k8bkNvdW50O2krKykNCi0JCXsNCi0JCQlDUERGU0RLX0Fubm90ICogcFJlYWRlckFubm90ID0gKENQREZTREtfQW5ub3QqKW1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldEF0KGkpOw0KLQkJCWlmKHBSZWFkZXJBbm5vdCA9PSBwVG9wTW9zdEFubm90KQ0KLQkJCXsNCi0JCQkJbV9wSXRlcmF0b3JBbm5vdExpc3QuUmVtb3ZlQXQoaSk7DQotCQkJCW1fcEl0ZXJhdG9yQW5ub3RMaXN0Lkluc2VydEF0KDAsIHBSZWFkZXJBbm5vdCk7DQotCQkJCWJyZWFrOw0KLQkJCX0JDQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX21nci5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19hbm5vdGhhbmRsZXIuaCIKKworCitDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6Q1BERlNES19Bbm5vdEhhbmRsZXJNZ3IoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCkKK3sKKwltX3BBcHAgPSBwQXBwOworCisJQ1BERlNES19CRkFubm90SGFuZGxlciogcEhhbmRsZXIgPSBuZXcgQ1BERlNES19CRkFubm90SGFuZGxlcihtX3BBcHApOworCXBIYW5kbGVyLT5TZXRGb3JtRmlsbGVyKG1fcEFwcC0+R2V0SUZvcm1GaWxsZXIoKSk7CisJUmVnaXN0ZXJBbm5vdEhhbmRsZXIocEhhbmRsZXIpOworfQorCitDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6fkNQREZTREtfQW5ub3RIYW5kbGVyTWdyKCkKK3sKKwlmb3IoaW50IGk9MDsgaTxtX0hhbmRsZXJzLkdldFNpemUoKTsgaSsrKQorCXsKKwkJSVBERlNES19Bbm5vdEhhbmRsZXIqIHBIYW5kbGVyID0gbV9IYW5kbGVycy5HZXRBdChpKTsKKwkJZGVsZXRlIHBIYW5kbGVyOworCX0KKwltX0hhbmRsZXJzLlJlbW92ZUFsbCgpOworCW1fbWFwVHlwZTJIYW5kbGVyLlJlbW92ZUFsbCgpOworfQorCit2b2lkCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpSZWdpc3RlckFubm90SGFuZGxlcihJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlcikKK3sKKwlBU1NFUlQocEFubm90SGFuZGxlciAhPSBOVUxMKTsKKwkKKwlBU1NFUlQoR2V0QW5ub3RIYW5kbGVyKHBBbm5vdEhhbmRsZXItPkdldFR5cGUoKSkgPT0gTlVMTCk7CisJCisJbV9IYW5kbGVycy5BZGQocEFubm90SGFuZGxlcik7CisJbV9tYXBUeXBlMkhhbmRsZXIuU2V0QXQocEFubm90SGFuZGxlci0+R2V0VHlwZSgpLCAodm9pZCopcEFubm90SGFuZGxlcik7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OlVuUmVnaXN0ZXJBbm5vdEhhbmRsZXIoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIpCit7CisJQVNTRVJUKHBBbm5vdEhhbmRsZXIgIT0gTlVMTCk7CisJCisJbV9tYXBUeXBlMkhhbmRsZXIuUmVtb3ZlS2V5KHBBbm5vdEhhbmRsZXItPkdldFR5cGUoKSk7CisJCisJZm9yIChpbnQgaT0wLCBzej1tX0hhbmRsZXJzLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJaWYgKG1fSGFuZGxlcnMuR2V0QXQoaSkgPT0gcEFubm90SGFuZGxlcikKKwkJeworCQkJbV9IYW5kbGVycy5SZW1vdmVBdChpKTsKKwkJCWJyZWFrOworCQl9CisJfQorfQorCitDUERGU0RLX0Fubm90KiBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6TmV3QW5ub3QoQ1BERl9Bbm5vdCAqIHBBbm5vdCwgQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3KQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKHBQYWdlVmlldyAhPSBOVUxMKTsKKwkKKwlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90LT5HZXRTdWJUeXBlKCkpKQorCXsKKwkJcmV0dXJuIHBBbm5vdEhhbmRsZXItPk5ld0Fubm90KHBBbm5vdCwgcFBhZ2VWaWV3KTsKKwl9CisJCisJcmV0dXJuIG5ldyBDUERGU0RLX0Fubm90KHBBbm5vdCwgcFBhZ2VWaWV3KTsKK30KKwordm9pZCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6UmVsZWFzZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCQorCXBBbm5vdC0+R2V0UERGUGFnZSgpOworCQorCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQorCXsKKwkJcEFubm90SGFuZGxlci0+T25SZWxlYXNlKHBBbm5vdCk7CisJCXBBbm5vdEhhbmRsZXItPlJlbGVhc2VBbm5vdChwQW5ub3QpOworCX0KKwllbHNlCisJeworCQlkZWxldGUgKENQREZTREtfQW5ub3QqKXBBbm5vdDsKKwl9Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uQ3JlYXRlKENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCQorCUNQREZfQW5ub3QqIHBQREZBbm5vdCA9IHBBbm5vdC0+R2V0UERGQW5ub3QoKTsKKwlBU1NFUlQocFBERkFubm90ICE9IE5VTEwpOworCUFTU0VSVChwUERGQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlDUERGU0RLX0RhdGVUaW1lIGN1clRpbWU7CisJcFBERkFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0U3RyaW5nKCJNIiwgY3VyVGltZS5Ub1BERkRhdGVUaW1lU3RyaW5nKCkpOworCXBQREZBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdE51bWJlcigiRiIsIChpbnQpMCk7CQorCQorCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQorCXsKKwkJcEFubm90SGFuZGxlci0+T25DcmVhdGUocEFubm90KTsKKwl9Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uTG9hZChDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwkKKwlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkKKwl7CisJCXBBbm5vdEhhbmRsZXItPk9uTG9hZChwQW5ub3QpOworCX0KK30KKworSVBERlNES19Bbm5vdEhhbmRsZXIqIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpHZXRBbm5vdEhhbmRsZXIoQ1BERlNES19Bbm5vdCogcEFubm90KSBjb25zdAoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJCisJQ1BERl9Bbm5vdCogcFBERkFubm90ID0gcEFubm90LT5HZXRQREZBbm5vdCgpOworCUFTU0VSVChwUERGQW5ub3QgIT0gTlVMTCk7CisJCisJcmV0dXJuIEdldEFubm90SGFuZGxlcihwUERGQW5ub3QtPkdldFN1YlR5cGUoKSk7Cit9CisKK0lQREZTREtfQW5ub3RIYW5kbGVyKiBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6R2V0QW5ub3RIYW5kbGVyKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzVHlwZSkgY29uc3QKK3sKKwl2b2lkKiBwUmV0ID0gTlVMTDsKKwltX21hcFR5cGUySGFuZGxlci5Mb29rdXAoc1R5cGUsIHBSZXQpOwkKKwlyZXR1cm4gKElQREZTREtfQW5ub3RIYW5kbGVyKilwUmV0OworfQorCit2b2lkIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpBbm5vdF9PbkRyYXcoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsRlhfRFdPUkQgZHdGbGFncykKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCQorCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQorCXsKKwkJcEFubm90SGFuZGxlci0+T25EcmF3KHBQYWdlVmlldywgcEFubm90LCBwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIGR3RmxhZ3MpOworCX0KKwllbHNlCisJeworCQlwQW5ub3QtPkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Bbm5vdDo6Tm9ybWFsLCBOVUxMKTsKKwl9Cit9CisKKworRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25MQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwkKKwlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkKKwl7CisJCXJldHVybiBwQW5ub3RIYW5kbGVyLT5PbkxCdXR0b25Eb3duKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQorIHsKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCisJaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpCisJeworCQlyZXR1cm4gcEFubm90SGFuZGxlci0+T25MQnV0dG9uVXAocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOworCX0KKwlyZXR1cm4gRkFMU0U7CisgfQorRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25MQnV0dG9uRGJsQ2xrKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCQorCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQorCXsKKwkJcmV0dXJuIHBBbm5vdEhhbmRsZXItPk9uTEJ1dHRvbkRibENsayhwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7CisJfQorCXJldHVybiBGQUxTRTsKK30KK0ZYX0JPT0wgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uTW91c2VNb3ZlKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCQorCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQorCXsKKwkJcmV0dXJuIHBBbm5vdEhhbmRsZXItPk9uTW91c2VNb3ZlKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25Nb3VzZVdoZWVsKENQREZTREtfUGFnZVZpZXcgKiBwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJCisJaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpCisJeworCQlyZXR1cm4gcEFubm90SGFuZGxlci0+T25Nb3VzZVdoZWVsKHBQYWdlVmlldywgcEFubm90LG5GbGFncyx6RGVsdGEsIHBvaW50KTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25SQnV0dG9uRG93bihDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwkKKwlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkKKwl7CisJCXJldHVybiBwQW5ub3RIYW5kbGVyLT5PblJCdXR0b25Eb3duKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorRlhfQk9PTCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25SQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJCisJaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpCisJeworCQlyZXR1cm4gcEFubm90SGFuZGxlci0+T25SQnV0dG9uVXAocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOworCX0KKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJCisJaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpCisJeworCQlwQW5ub3RIYW5kbGVyLT5Pbk1vdXNlRW50ZXIocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFnKTsKKwl9CisJcmV0dXJuIDsKK30KKwordm9pZCBDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25Nb3VzZUV4aXQoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZykKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCQorCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQorCXsKKwkJcEFubm90SGFuZGxlci0+T25Nb3VzZUV4aXQocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFnKTsKKwl9CisJcmV0dXJuOworfQorCitGWF9CT09MIENQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpBbm5vdF9PbkNoYXIoQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWdzKQoreworCisJaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpCisJeworCQlyZXR1cm4gcEFubm90SGFuZGxlci0+T25DaGFyKHBBbm5vdCxuQ2hhciwgbkZsYWdzKTsKKwl9CisJcmV0dXJuIEZBTFNFOworCit9CisKK0ZYX0JPT0wJCQlDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25LZXlEb3duKENQREZTREtfQW5ub3QqIHBBbm5vdCwgaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpCit7CisKKwlpZiAoIW1fcEFwcC0+RkZJX0lzQ1RSTEtleURvd24obkZsYWcpICYmICFtX3BBcHAtPkZGSV9Jc0FMVEtleURvd24obkZsYWcpKQorCXsKKwkJQ1BERlNES19QYWdlVmlldyogcFBhZ2UgPSBwQW5ub3QtPkdldFBhZ2VWaWV3KCk7CisJCUNQREZTREtfQW5ub3QqIHBGb2N1c0Fubm90ID0gcFBhZ2UtPkdldEZvY3VzQW5ub3QoKTsKKwkJaWYgKHBGb2N1c0Fubm90ICYmIChuS2V5Q29kZSA9PSBGV0xfVktFWV9UYWIpKQorCQl7CisJCQlDUERGU0RLX0Fubm90KiBwTmV4dCA9IEdldE5leHRBbm5vdChwRm9jdXNBbm5vdCwgIW1fcEFwcC0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKSk7CisKKwkJCWlmKHBOZXh0ICYmIHBOZXh0ICE9IHBGb2N1c0Fubm90KQorCQkJeworCQkJCUNQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCA9IHBQYWdlLT5HZXRTREtEb2N1bWVudCgpOworCQkJCXBEb2N1bWVudC0+U2V0Rm9jdXNBbm5vdChwTmV4dCk7CisJCQkJcmV0dXJuIFRSVUU7CisJCQl9CisJCX0KKwl9CisKKwlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkKKwl7CisJCXJldHVybiBwQW5ub3RIYW5kbGVyLT5PbktleURvd24ocEFubm90LG5LZXlDb2RlLCBuRmxhZyk7CisJfQorCXJldHVybiBGQUxTRTsKK30KK0ZYX0JPT0wJCQlDUERGU0RLX0Fubm90SGFuZGxlck1ncjo6QW5ub3RfT25LZXlVcChDUERGU0RLX0Fubm90KiBwQW5ub3QsIGludCBuS2V5Q29kZSwgaW50IG5GbGFnKQoreworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAkJCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyOjpBbm5vdF9PblNldEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKworCWlmIChJUERGU0RLX0Fubm90SGFuZGxlciogcEFubm90SGFuZGxlciA9IEdldEFubm90SGFuZGxlcihwQW5ub3QpKQorCXsKKwkJaWYgKHBBbm5vdEhhbmRsZXItPk9uU2V0Rm9jdXMocEFubm90LCBuRmxhZykpCisJCXsKKwkJCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlID0gcEFubm90LT5HZXRQYWdlVmlldygpOworCQkJQVNTRVJUKHBQYWdlICE9IE5VTEwpOworCisJCQlwUGFnZS0+R2V0U0RLRG9jdW1lbnQoKTsKKwkvLwkJcERvY3VtZW50LT5TZXRUb3Btb3N0QW5ub3QocEFubm90KTsKKworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwkJZWxzZQorCQl7CisJCQlyZXR1cm4gRkFMU0U7CisJCX0KKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCQkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwkKKwlpZiAoSVBERlNES19Bbm5vdEhhbmRsZXIqIHBBbm5vdEhhbmRsZXIgPSBHZXRBbm5vdEhhbmRsZXIocEFubm90KSkKKwl7CisJCWlmIChwQW5ub3RIYW5kbGVyLT5PbktpbGxGb2N1cyhwQW5ub3QsIG5GbGFnKSkKKwkJewkKKwkJCXJldHVybiBUUlVFOworCQl9CisJCWVsc2UKKwkJCXJldHVybiBGQUxTRTsKKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitDUERGX1JlY3QJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uR2V0Vmlld0JCb3goQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJQVNTRVJUKHBBbm5vdCk7CisJaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpCisJeworCQlyZXR1cm4gcEFubm90SGFuZGxlci0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBwQW5ub3QpOworCX0KKwlyZXR1cm4gcEFubm90LT5HZXRSZWN0KCk7Cit9CisKK0ZYX0JPT0wJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkFubm90X09uSGl0VGVzdChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQVNTRVJUKHBBbm5vdCk7CisJaWYgKElQREZTREtfQW5ub3RIYW5kbGVyKiBwQW5ub3RIYW5kbGVyID0gR2V0QW5ub3RIYW5kbGVyKHBBbm5vdCkpCisJeworCQlpZihwQW5ub3RIYW5kbGVyLT5DYW5BbnN3ZXIocEFubm90KSkKKwkJCXJldHVybiBwQW5ub3RIYW5kbGVyLT5IaXRUZXN0KHBQYWdlVmlldywgcEFubm90LCBwb2ludCk7CisJfQorCXJldHVybiBGQUxTRTsKK30KKworQ1BERlNES19Bbm5vdCoJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3I6OkdldE5leHRBbm5vdChDUERGU0RLX0Fubm90KiBwU0RLQW5ub3QsRlhfQk9PTCBiTmV4dCkKK3sKKwkgQ0JBX0Fubm90SXRlcmF0b3IgYWkocFNES0Fubm90LT5HZXRQYWdlVmlldygpLCAiV2lkZ2V0IiwgIiIpOworCisJIENQREZTREtfQW5ub3QqIHBOZXh0ID0gYk5leHQgPyAKKwkJIGFpLkdldE5leHRBbm5vdChwU0RLQW5ub3QpIDogCisJCWFpLkdldFByZXZBbm5vdChwU0RLQW5ub3QpOworCQorCQlyZXR1cm4gcE5leHQ7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19CRkFubm90SGFuZGxlcjo6Q2FuQW5zd2VyKENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlBU1NFUlQocEFubm90KTsKKwlBU1NFUlQocEFubm90LT5HZXRUeXBlKCkgPT0gIldpZGdldCIpOworCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7CisJCisJaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQorCXsKKwl9CisJZWxzZQorCXsKKwkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsKKwkJaWYgKCFwV2lkZ2V0LT5Jc1Zpc2libGUoKSkgcmV0dXJuIEZBTFNFOworCisJCWludCBuRmllbGRGbGFncyA9IHBXaWRnZXQtPkdldEZpZWxkRmxhZ3MoKTsKKwkJaWYgKChuRmllbGRGbGFncyAmIEZJRUxERkxBR19SRUFET05MWSkgPT0gRklFTERGTEFHX1JFQURPTkxZKSByZXR1cm4gRkFMU0U7CisJCWlmIChwV2lkZ2V0LT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfUFVTSEJVVFRPTikKKwkJCXJldHVybiBUUlVFOworCQllbHNlCisJCXsKKwkJCUNQREZfUGFnZSogcFBhZ2UgPSBwV2lkZ2V0LT5HZXRQREZQYWdlKCk7CisJCQlBU1NFUlQocFBhZ2UgIT0gTlVMTCk7CisJCQkKKwkJCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IHBQYWdlLT5tX3BEb2N1bWVudDsKKwkJCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisJCQkKKwkJCUZYX0RXT1JEIGR3UGVybWlzc2lvbnMgPSBwRG9jdW1lbnQtPkdldFVzZXJQZXJtaXNzaW9ucygpOworCQkJcmV0dXJuIChkd1Blcm1pc3Npb25zJkZQREZQRVJNX0ZJTExfRk9STSkgfHwgCisJCQkJKGR3UGVybWlzc2lvbnMmRlBERlBFUk1fQU5OT1RfRk9STSkgfHwgCisgCQkJKGR3UGVybWlzc2lvbnMmRlBERlBFUk1fQU5OT1RfRk9STSk7CisJCX0KKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0NQREZTREtfQW5ub3QqCQlDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpOZXdBbm5vdChDUERGX0Fubm90KiBwQW5ub3QsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlKQoreworCUFTU0VSVChwUGFnZSAhPSBOVUxMKTsKKwlwUGFnZS0+R2V0UERGRG9jdW1lbnQoKTsKKwkKKwlDUERGU0RLX0RvY3VtZW50KiBwU0RLRG9jICA9IG1fcEFwcC0+R2V0Q3VycmVudERvYygpOworCUFTU0VSVChwU0RLRG9jKTsKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcFNES0RvYy0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisJCisJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBOVUxMOworCWlmIChDUERGX0Zvcm1Db250cm9sKiBwQ3RybCA9IENQREZTREtfV2lkZ2V0OjpHZXRGb3JtQ29udHJvbChwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKSwgcEFubm90LT5tX3BBbm5vdERpY3QpKQorCXsKKwkJcFdpZGdldCA9IG5ldyBDUERGU0RLX1dpZGdldChwQW5ub3QsIHBQYWdlLCBwSW50ZXJGb3JtKTsKKwkJcEludGVyRm9ybS0+QWRkTWFwKHBDdHJsLCBwV2lkZ2V0KTsKKwkJQ1BERl9JbnRlckZvcm0qIHBQREZJbnRlckZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwkJaWYocFBERkludGVyRm9ybSAmJiBwUERGSW50ZXJGb3JtLT5OZWVkQ29uc3RydWN0QVAoKSkKKwkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShOVUxMLEZBTFNFKTsKKwl9CisJCisJcmV0dXJuIHBXaWRnZXQ7Cit9CisKK3ZvaWQgQ1BERlNES19CRkFubm90SGFuZGxlcjo6UmVsZWFzZUFubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCisJaWYgKG1fcEZvcm1GaWxsZXIpCisJCW1fcEZvcm1GaWxsZXItPk9uRGVsZXRlKHBBbm5vdCk7CisJCisJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBXaWRnZXQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCQorCUNQREZfRm9ybUNvbnRyb2wqIHBDdHJvbCA9IHBXaWRnZXQtPkdldEZvcm1Db250cm9sKCk7CisJcEludGVyRm9ybS0+UmVtb3ZlTWFwKHBDdHJvbCk7CisJCisKKwlkZWxldGUgcFdpZGdldDsKK30KKworCit2b2lkIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uRHJhdyhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwgIEZYX0RXT1JEIGR3RmxhZ3MpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOworCQorCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkKKwl7CisJCXBBbm5vdC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpOb3JtYWwsIE5VTEwpOworCX0KKwllbHNlCisJeworCQlpZiAobV9wRm9ybUZpbGxlcikKKwkJeworCQkJbV9wRm9ybUZpbGxlci0+T25EcmF3KHBQYWdlVmlldywgcEFubm90LCBwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIGR3RmxhZ3MpOworCQl9CisJfQorfQorCit2b2lkIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uTW91c2VFbnRlcihDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpIAoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsKKwkKKwlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpCisJeworCX0KKwllbHNlCisJeworCQlpZiAobV9wRm9ybUZpbGxlcikKKwkJCSBtX3BGb3JtRmlsbGVyLT5Pbk1vdXNlRW50ZXIocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFnKTsKKwl9CisJCisKK30KK3ZvaWQgQ1BERlNES19CRkFubm90SGFuZGxlcjo6T25Nb3VzZUV4aXQoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFnKSAKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7CisJCisJaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQorCXsKKwl9CisJZWxzZQorCXsKKwkJaWYgKG1fcEZvcm1GaWxsZXIpCisJCQkgbV9wRm9ybUZpbGxlci0+T25Nb3VzZUV4aXQocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFnKTsKKwl9CisJCit9CitGWF9CT09MIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uTEJ1dHRvbkRvd24oQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOworCQorCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkKKwl7CisJfQorCWVsc2UKKwl7CisJCWlmIChtX3BGb3JtRmlsbGVyKQorCQkJcmV0dXJuIG1fcEZvcm1GaWxsZXItPk9uTEJ1dHRvbkRvd24ocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOworCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19CRkFubm90SGFuZGxlcjo6T25MQnV0dG9uVXAoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOworCQorCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkKKwl7CisJfQorCWVsc2UKKwl7CisJCWlmIChtX3BGb3JtRmlsbGVyKQorCQkJcmV0dXJuIG1fcEZvcm1GaWxsZXItPk9uTEJ1dHRvblVwKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uTEJ1dHRvbkRibENsayhDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7CisJCisJaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQorCXsKKwl9CisJZWxzZQorCXsKKwkJaWYgKG1fcEZvcm1GaWxsZXIpCisJCQlyZXR1cm4gbV9wRm9ybUZpbGxlci0+T25MQnV0dG9uRGJsQ2xrKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uTW91c2VNb3ZlKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQorewkKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7CisKKwlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpCisJeworCX0KKwllbHNlCisJeworCQlpZiAobV9wRm9ybUZpbGxlcikKKwkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5Pbk1vdXNlTW92ZShwUGFnZVZpZXcsIHBBbm5vdCwgbkZsYWdzLCBwb2ludCk7CisJfQorCisJcmV0dXJuIEZBTFNFOworCit9CisKKworRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbk1vdXNlV2hlZWwoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIEZYX0RXT1JEIG5GbGFncywgc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7CisJCisJaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQorCXsKKwl9CisJZWxzZQorCXsKKwkJaWYgKG1fcEZvcm1GaWxsZXIpCisJCQlyZXR1cm4gbV9wRm9ybUZpbGxlci0+T25Nb3VzZVdoZWVsKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHpEZWx0YSxwb2ludCk7CisJfQorCQorCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPblJCdXR0b25Eb3duKENQREZTREtfUGFnZVZpZXcgKnBQYWdlVmlldywgQ1BERlNES19Bbm5vdCogcEFubm90LCBGWF9EV09SRCBuRmxhZ3MsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsKKwkKKwlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpCisJeworCX0KKwllbHNlCisJeworCQlpZiAobV9wRm9ybUZpbGxlcikKKwkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5PblJCdXR0b25Eb3duKHBQYWdlVmlldywgcEFubm90LCBuRmxhZ3MsIHBvaW50KTsKKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPblJCdXR0b25VcChDUERGU0RLX1BhZ2VWaWV3ICpwUGFnZVZpZXcsIENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWdzLCBjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7CisJCisJaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQorCXsKKwl9CisJZWxzZQorCXsKKwkJaWYgKG1fcEZvcm1GaWxsZXIpCisJCQlyZXR1cm4gbV9wRm9ybUZpbGxlci0+T25SQnV0dG9uVXAocFBhZ2VWaWV3LCBwQW5ub3QsIG5GbGFncywgcG9pbnQpOworCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19CRkFubm90SGFuZGxlcjo6T25DaGFyKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFncykKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7CisJCisJaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQorCXsKKwl9CisJZWxzZQorCXsKKwkJaWYgKG1fcEZvcm1GaWxsZXIpCisJCQlyZXR1cm4gbV9wRm9ybUZpbGxlci0+T25DaGFyKHBBbm5vdCxuQ2hhciwgbkZsYWdzKTsKKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uS2V5RG93bihDUERGU0RLX0Fubm90KiBwQW5ub3QsIGludCBuS2V5Q29kZSwgaW50IG5GbGFnKQoreworCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisJQ0ZYX0J5dGVTdHJpbmcgc1N1YlR5cGUgPSBwQW5ub3QtPkdldFN1YlR5cGUoKTsKKwkKKwlpZiAoc1N1YlR5cGUgPT0gQkZGVF9TSUdOQVRVUkUpCisJeworCX0KKwllbHNlCisJeworCQlpZiAobV9wRm9ybUZpbGxlcikKKwkJCXJldHVybiBtX3BGb3JtRmlsbGVyLT5PbktleURvd24ocEFubm90LG5LZXlDb2RlLCBuRmxhZyk7CisJfQorCQorCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPbktleVVwKENQREZTREtfQW5ub3QqIHBBbm5vdCwgaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpCit7CisKKwlyZXR1cm4gRkFMU0U7Cit9Cit2b2lkCUNQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uQ3JlYXRlKENQREZTREtfQW5ub3QqIHBBbm5vdCkgCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOworCQorCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkKKwl7CisJfQorCWVsc2UKKwl7CisJCWlmIChtX3BGb3JtRmlsbGVyKQorCQkJbV9wRm9ybUZpbGxlci0+T25DcmVhdGUocEFubm90KTsKKwl9Cit9CisKK3ZvaWQgQ1BERlNES19CRkFubm90SGFuZGxlcjo6T25Mb2FkKENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCQorCUNGWF9CeXRlU3RyaW5nIHNTdWJUeXBlID0gcEFubm90LT5HZXRTdWJUeXBlKCk7CisJCisJaWYgKHNTdWJUeXBlID09IEJGRlRfU0lHTkFUVVJFKQorCXsKKwl9CisJZWxzZQorCXsKKwkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBBbm5vdDsKKwkJCisJaWYgKCFwV2lkZ2V0LT5Jc0FwcGVhcmFuY2VWYWxpZCgpKQorCQkJcFdpZGdldC0+UmVzZXRBcHBlYXJhbmNlKE5VTEwsIEZBTFNFKTsKKwkJCisJCWludCBuRmllbGRUeXBlID0gcFdpZGdldC0+R2V0RmllbGRUeXBlKCk7CisJCQorCQlpZiAobkZpZWxkVHlwZSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEIHx8IG5GaWVsZFR5cGUgPT0gRklFTERUWVBFX0NPTUJPQk9YKQorCQl7CisJCQlGWF9CT09MIGJGb3JtYXRlZCA9IEZBTFNFOworCQkJQ0ZYX1dpZGVTdHJpbmcgc1ZhbHVlID0gcFdpZGdldC0+T25Gb3JtYXQoMCwgYkZvcm1hdGVkKTsKKwkJCQorCQkJaWYgKGJGb3JtYXRlZCAmJiBuRmllbGRUeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCkKKwkJCXsKKwkJCQlwV2lkZ2V0LT5SZXNldEFwcGVhcmFuY2Uoc1ZhbHVlLCBGQUxTRSk7CisJCQl9CisJCX0KKwkJCisKKwkJaWYgKG1fcEZvcm1GaWxsZXIpCisJCQltX3BGb3JtRmlsbGVyLT5PbkxvYWQocEFubm90KTsKKworCX0KK30KKworRlhfQk9PTAlDUERGU0RLX0JGQW5ub3RIYW5kbGVyOjpPblNldEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOworCQorCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkKKwl7CisJfQorCWVsc2UKKwl7CisJCWlmIChtX3BGb3JtRmlsbGVyKQorCQkJcmV0dXJuIG1fcEZvcm1GaWxsZXItPk9uU2V0Rm9jdXMocEFubm90LG5GbGFnKTsKKwl9CisJCisJcmV0dXJuIFRSVUU7Cit9CitGWF9CT09MCUNQREZTREtfQkZBbm5vdEhhbmRsZXI6Ok9uS2lsbEZvY3VzKENQREZTREtfQW5ub3QqIHBBbm5vdCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOworCQorCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkKKwl7CisJfQorCWVsc2UKKwl7CisJCWlmIChtX3BGb3JtRmlsbGVyKQorCQkJcmV0dXJuIG1fcEZvcm1GaWxsZXItPk9uS2lsbEZvY3VzKHBBbm5vdCxuRmxhZyk7CisJfQorCQorCXJldHVybiBUUlVFOworfQorCitDUERGX1JlY3QgQ1BERlNES19CRkFubm90SGFuZGxlcjo6R2V0Vmlld0JCb3goQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzU3ViVHlwZSA9IHBBbm5vdC0+R2V0U3ViVHlwZSgpOworCQorCWlmIChzU3ViVHlwZSA9PSBCRkZUX1NJR05BVFVSRSkKKwl7CisJfQorCWVsc2UKKwl7CisJCWlmIChtX3BGb3JtRmlsbGVyKQorCQkJcmV0dXJuIG1fcEZvcm1GaWxsZXItPkdldFZpZXdCQm94KHBQYWdlVmlldywgcEFubm90KTsKKworCX0KKwkKKwlyZXR1cm4gQ1BERl9SZWN0KDAsMCwwLDApOworfQorCitGWF9CT09MCUNQREZTREtfQkZBbm5vdEhhbmRsZXI6OkhpdFRlc3QoQ1BERlNES19QYWdlVmlldyAqcFBhZ2VWaWV3LCBDUERGU0RLX0Fubm90KiBwQW5ub3QsIGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUFTU0VSVChwUGFnZVZpZXcpOworCUFTU0VSVChwQW5ub3QpOworCisJQ1BERl9SZWN0IHJlY3QgPSBHZXRWaWV3QkJveChwUGFnZVZpZXcsIHBBbm5vdCk7CisJcmV0dXJuIHJlY3QuQ29udGFpbnMocG9pbnQueCwgcG9pbnQueSk7Cit9CisKKy8vQ1JlYWRlcl9Bbm5vdEl0ZXJhdG9yRXgKKworQ1BERlNES19Bbm5vdEl0ZXJhdG9yOjpDUERGU0RLX0Fubm90SXRlcmF0b3IoQ1BERlNES19QYWdlVmlldyAqIHBQYWdlVmlldyxGWF9CT09MIGJSZXZlcnNlLAorCQkJCQkJCQkJCQkJIEZYX0JPT0wgYklnbm9yZVRvcG1vc3QvKj1GQUxTRSovLAorCQkJCQkJCQkJCQkJIEZYX0JPT0wgYkNpcmNsZS8qPUZBTFNFKi8sCisJCQkJCQkJCQkJCQkgQ0ZYX1B0ckFycmF5ICpwTGlzdC8qPU5VTEwqLykKK3sKKwlBU1NFUlQocFBhZ2VWaWV3KTsKKwltX2JSZXZlcnNlPWJSZXZlcnNlOworCW1fYklnbm9yZVRvcG1vc3Q9IGJJZ25vcmVUb3Btb3N0OworCW1fYkNpcmNsZT1iQ2lyY2xlOworCW1fcEl0ZXJhdG9yQW5ub3RMaXN0LlJlbW92ZUFsbCgpOworCUluaXRJdGVyYXRvckFubm90TGlzdChwUGFnZVZpZXcscExpc3QpOworfQorCitDUERGU0RLX0Fubm90KglDUERGU0RLX0Fubm90SXRlcmF0b3I6Ok5leHRBbm5vdCAoY29uc3QgQ1BERlNES19Bbm5vdCogcEN1cnJlbnQpIAoreworCQorCWludCBpbmRleD0tMTsKKwlpbnQgbkNvdW50PXRoaXMtPm1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldFNpemUoKTsKKwlpZihwQ3VycmVudCl7CisJCWZvcihpbnQgaT0wO2k8bkNvdW50O2krKyl7CisJCQlDUERGU0RLX0Fubm90ICogcFJlYWRlckFubm90PSAoQ1BERlNES19Bbm5vdCAqKW1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldEF0KGkpOworCQkJaWYocFJlYWRlckFubm90ID09cEN1cnJlbnQpewkJCQorCQkJCWluZGV4PWk7CisJCQkJYnJlYWs7CisJCQl9CQkJCisJCX0KKwl9CQorCXJldHVybiBOZXh0QW5ub3QoaW5kZXgpOworfQorQ1BERlNES19Bbm5vdCoJQ1BERlNES19Bbm5vdEl0ZXJhdG9yOjpQcmV2QW5ub3QgKGNvbnN0IENQREZTREtfQW5ub3QqcEN1cnJlbnQpCit7CisJCisJaW50IGluZGV4PS0xOworCWludCBuQ291bnQ9dGhpcy0+bV9wSXRlcmF0b3JBbm5vdExpc3QuR2V0U2l6ZSgpOworCWlmKHBDdXJyZW50KXsKKwkJZm9yKGludCBpPTA7aTxuQ291bnQ7aSsrKXsKKwkJCUNQREZTREtfQW5ub3QgKiBwUmVhZGVyQW5ub3Q9IChDUERGU0RLX0Fubm90KiltX3BJdGVyYXRvckFubm90TGlzdC5HZXRBdChpKTsKKwkJCWlmKHBSZWFkZXJBbm5vdCA9PXBDdXJyZW50KXsJCQkKKwkJCQlpbmRleD1pOworCQkJCWJyZWFrOworCQkJfQkJCQorCQl9CQorCX0KKwlyZXR1cm4gUHJldkFubm90KGluZGV4KTsJCit9CitDUERGU0RLX0Fubm90KglDUERGU0RLX0Fubm90SXRlcmF0b3I6Ok5leHRBbm5vdCAoaW50JiBpbmRleCkgCit7CQorCQorCWludCBuQ291bnQ9bV9wSXRlcmF0b3JBbm5vdExpc3QuR2V0U2l6ZSgpOworICAgIGlmKG5Db3VudDw9MCkgaW5kZXg9LTE7CisgICAgZWxzZXsKKwkJaWYoaW5kZXg8MCl7CisJCQlpbmRleD0wOwkJCisJCX0KKwkJZWxzZXsJCQorCQkJaWYobV9iQ2lyY2xlKXsJCQkKKwkJCQlpbmRleD0oIGluZGV4IDxuQ291bnQtMSkgPyAoaW5kZXgrMSkgOjA7CQkKKwkJCX0KKwkJCWVsc2V7CisJCQkJaW5kZXg9KCBpbmRleCA8bkNvdW50LTEpID8gKGluZGV4KzEpIDotMTsJCQorCQkJfQorCQkJCisJCX0JCisJfQorCXJldHVybiAoaW5kZXggPDApID8gTlVMTCA6IChDUERGU0RLX0Fubm90KiltX3BJdGVyYXRvckFubm90TGlzdC5HZXRBdChpbmRleCk7CQkKK30KKworCitDUERGU0RLX0Fubm90KglDUERGU0RLX0Fubm90SXRlcmF0b3I6OlByZXZBbm5vdCAoaW50JiBpbmRleCkKK3sKKwkKKwlpbnQgbkNvdW50PW1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldFNpemUoKTsKKyAgICBpZihuQ291bnQ8PTApIGluZGV4PS0xOworCWVsc2V7CQorCQlpZihpbmRleDwwKXsKKwkJCWluZGV4PW5Db3VudC0xOwkJIAorCQl9CisJCWVsc2V7CQorCQkJaWYobV9iQ2lyY2xlKXsJCQkKKwkJCQlpbmRleCA9ICggaW5kZXggPjApID8gKGluZGV4LTEpIDpuQ291bnQtMTsJCQorCQkJfQorCQkJZWxzZXsKKwkJCQlpbmRleCA9ICggaW5kZXggPjApID8gKGluZGV4LTEpIDotMTsJCisJCQl9CQkJCQorCQl9CisJfQorCXJldHVybiAoaW5kZXggPDApID8gTlVMTCA6IChDUERGU0RLX0Fubm90KiltX3BJdGVyYXRvckFubm90TGlzdC5HZXRBdChpbmRleCk7CQkKK30KKworCitDUERGU0RLX0Fubm90KkNQREZTREtfQW5ub3RJdGVyYXRvcjo6TmV4dChjb25zdCBDUERGU0RLX0Fubm90KiBwQ3VycmVudCkgCit7CisKKwlyZXR1cm4gKG1fYlJldmVyc2UpID8gUHJldkFubm90KHBDdXJyZW50KTpOZXh0QW5ub3QocEN1cnJlbnQpOwkJIAorCit9CisKK0NQREZTREtfQW5ub3QqCUNQREZTREtfQW5ub3RJdGVyYXRvcjo6UHJldihjb25zdCBDUERGU0RLX0Fubm90KiBwQ3VycmVudCkgCit7CisKKwlyZXR1cm4gKG1fYlJldmVyc2UpID8gTmV4dEFubm90KHBDdXJyZW50KTpQcmV2QW5ub3QocEN1cnJlbnQpOwkJIAorfQorCitDUERGU0RLX0Fubm90KkNQREZTREtfQW5ub3RJdGVyYXRvcjo6TmV4dChpbnQmIGluZGV4ICkKK3sKKwkKKwlyZXR1cm4gKG1fYlJldmVyc2UpID8gUHJldkFubm90KGluZGV4KTpOZXh0QW5ub3QoaW5kZXgpOwkJIAorCQorfQorCitDUERGU0RLX0Fubm90KglDUERGU0RLX0Fubm90SXRlcmF0b3I6OlByZXYoaW50JiBpbmRleCApCit7CisJCisJcmV0dXJuIChtX2JSZXZlcnNlKSA/IE5leHRBbm5vdChpbmRleCk6UHJldkFubm90KGluZGV4KTsJCSAKK30KKworCit2b2lkIENQREZTREtfQW5ub3RJdGVyYXRvcjo6SW5zZXJ0U29ydChDRlhfUHRyQXJyYXkgJmFycmF5TGlzdCwgQUlfQ09NUEFSRSBwQ29tcGFyZSkKK3sKKwlmb3IgKGludCBpID0gMTsgaSA8IGFycmF5TGlzdC5HZXRTaXplKCk7IGkrKykKKwl7CisJCWlmIChwQ29tcGFyZSgoQ1BERlNES19Bbm5vdCopKGFycmF5TGlzdFtpXSkgLCAoQ1BERlNES19Bbm5vdCopKGFycmF5TGlzdFtpLTFdKSkgPCAwKQorCQl7CisJCQlpbnQgaiA9IGktMTsKKwkJCUNQREZTREtfQW5ub3QqIHBUZW1wID0gKENQREZTREtfQW5ub3QqKWFycmF5TGlzdFtpXTsKKwkJCQorCQkJZG8KKwkJCXsKKwkJCQlhcnJheUxpc3RbaiArIDFdID0gYXJyYXlMaXN0W2pdOworCQkJfSB3aGlsZSAoLS1qID49IDAgJiYgcENvbXBhcmUocFRlbXAsIChDUERGU0RLX0Fubm90KilhcnJheUxpc3Rbal0pIDwgMCk7CisKKwkJCWFycmF5TGlzdFtqKzFdID0gcFRlbXA7CisJCX0KKwl9Cit9CisKK2ludCBMeU9yZGVyQ29tcGFyZShDUERGU0RLX0Fubm90KiBwMSwgQ1BERlNES19Bbm5vdCogcDIpCit7CisJaWYocDEtPkdldExheW91dE9yZGVyKCkgPCBwMi0+R2V0TGF5b3V0T3JkZXIoKSkKKwkJcmV0dXJuIC0xOworCWVsc2UgaWYgKHAxLT5HZXRMYXlvdXRPcmRlcigpID09IHAyLT5HZXRMYXlvdXRPcmRlcigpKQorCQlyZXR1cm4gMDsKKwllbHNlCisJCXJldHVybiAxOworfQorCitGWF9CT09MIENQREZTREtfQW5ub3RJdGVyYXRvcjo6SW5pdEl0ZXJhdG9yQW5ub3RMaXN0KENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyxDRlhfUHRyQXJyYXkgKiBwQW5ub3RMaXN0KQoreworCUFTU0VSVChwUGFnZVZpZXcpOworCQorCQorCisJaWYocEFubm90TGlzdD09TlVMTCl7CQorCQlwQW5ub3RMaXN0PXBQYWdlVmlldy0+R2V0QW5ub3RMaXN0KCk7CisJfQorCisJdGhpcy0+bV9wSXRlcmF0b3JBbm5vdExpc3QuUmVtb3ZlQWxsKCk7CisJaWYoIXBBbm5vdExpc3QpIHJldHVybiBGQUxTRTsKKworCUNQREZTREtfQW5ub3QgKiBwVG9wTW9zdEFubm90PSAobV9iSWdub3JlVG9wbW9zdCkgPyBOVUxMIDogcFBhZ2VWaWV3LT5HZXRGb2N1c0Fubm90KCk7CisKKworCWludCBuQ291bnQgPXBBbm5vdExpc3QtPkdldFNpemUoKTsKKworCWZvcihpbnQgaSA9IG5Db3VudC0gMSA7aSA+PSAwO2ktLSkKKwl7CisJCUNQREZTREtfQW5ub3QgKiBwUmVhZGVyQW5ub3Q9IChDUERGU0RLX0Fubm90KilwQW5ub3RMaXN0LT5HZXRBdChpKTsKKwkJbV9wSXRlcmF0b3JBbm5vdExpc3QuQWRkKHBSZWFkZXJBbm5vdCk7CQorCX0KKworCUluc2VydFNvcnQobV9wSXRlcmF0b3JBbm5vdExpc3QsJkx5T3JkZXJDb21wYXJlKTsKKworCWlmKHBUb3BNb3N0QW5ub3QpCisJeworCQlmb3IoaW50IGk9MCA7aTxuQ291bnQ7aSsrKQorCQl7CisJCQlDUERGU0RLX0Fubm90ICogcFJlYWRlckFubm90ID0gKENQREZTREtfQW5ub3QqKW1fcEl0ZXJhdG9yQW5ub3RMaXN0LkdldEF0KGkpOworCQkJaWYocFJlYWRlckFubm90ID09IHBUb3BNb3N0QW5ub3QpCisJCQl7CisJCQkJbV9wSXRlcmF0b3JBbm5vdExpc3QuUmVtb3ZlQXQoaSk7CisJCQkJbV9wSXRlcmF0b3JBbm5vdExpc3QuSW5zZXJ0QXQoMCwgcFJlYWRlckFubm90KTsKKwkJCQlicmVhazsKKwkJCX0JCisJCX0KKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnNka19iYXNlYW5ub3QuY3BwIGIvZnBkZnNkay9zcmMvZnNka19iYXNlYW5ub3QuY3BwCmluZGV4IGFjMzZlM2MuLmM4ZTA3MzUgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZzZGtfYmFzZWFubm90LmNwcAorKysgYi9mcGRmc2RrL3NyYy9mc2RrX2Jhc2Vhbm5vdC5jcHAKQEAgLTEsMTE4NyArMSwxMTg3IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfbWdyLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19iYXNlYW5ub3QuaCINCi0NCi0NCi0vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KLS8vCQkJCQkJCQlDUERGU0RLX0RhdGVUaW1lCQ0KLS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQotaW50IF9nQWZ4R2V0VGltZVpvbmVJblNlY29uZHMoRlhfQ0hBUiB0emhvdXIsIEZYX0JZVEUgdHptaW51dGUpDQotew0KLQlyZXR1cm4gKGludCl0emhvdXIgKiAzNjAwICsgKGludCl0em1pbnV0ZSAqICh0emhvdXIgPj0gMCA/IDYwIDogLTYwKTsNCi19DQotDQotRlhfQk9PTCBfZ0FmeElzTGVhcFllYXIoRlhfU0hPUlQgeWVhcikNCi17DQotCXJldHVybiAoKHllYXIgJSA0MDAgPT0gMCkgfHwgKCh5ZWFyICUgNCA9PSAwKSAmJiAoeWVhciAlIDEwMCAhPSAwKSkpOw0KLX0NCi0NCi1GWF9XT1JEIF9nQWZ4R2V0WWVhckRheXMoRlhfU0hPUlQgeWVhcikNCi17DQotCXJldHVybiAoX2dBZnhJc0xlYXBZZWFyKHllYXIpID09IFRSVUUgPyAzNjYgOiAzNjUpOw0KLX0NCi0NCi1GWF9CWVRFIF9nQWZ4R2V0TW9udGhEYXlzKEZYX1NIT1JUIHllYXIsIEZYX0JZVEUgbW9udGgpDQotew0KLQlGWF9CWVRFCW1EYXlzOw0KLQlzd2l0Y2ggKG1vbnRoKQ0KLQl7DQotCWNhc2UgMToNCi0JY2FzZSAzOg0KLQljYXNlIDU6DQotCWNhc2UgNzoNCi0JY2FzZSA4Og0KLQljYXNlIDEwOg0KLQljYXNlIDEyOg0KLQkJbURheXMgPSAzMTsNCi0JCWJyZWFrOw0KLQ0KLQljYXNlIDQ6DQotCWNhc2UgNjoNCi0JY2FzZSA5Og0KLQljYXNlIDExOg0KLQkJbURheXMgPSAzMDsNCi0JCWJyZWFrOw0KLQ0KLQljYXNlIDI6DQotCQlpZiAoX2dBZnhJc0xlYXBZZWFyKHllYXIpID09IFRSVUUpDQotCQkJbURheXMgPSAyOTsNCi0JCWVsc2UNCi0JCQltRGF5cyA9IDI4Ow0KLQkJYnJlYWs7DQotDQotCWRlZmF1bHQ6DQotCQltRGF5cyA9IDA7DQotCQlicmVhazsNCi0JfQ0KLQ0KLQlyZXR1cm4gbURheXM7DQotfQ0KLQ0KLUNQREZTREtfRGF0ZVRpbWU6OkNQREZTREtfRGF0ZVRpbWUoKQ0KLXsNCi0JUmVzZXREYXRlVGltZSgpOw0KLX0NCi0NCi1DUERGU0RLX0RhdGVUaW1lOjpDUERGU0RLX0RhdGVUaW1lKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBkdFN0cikNCi17DQotCVJlc2V0RGF0ZVRpbWUoKTsNCi0NCi0JRnJvbVBERkRhdGVUaW1lU3RyaW5nKGR0U3RyKTsNCi19DQotDQotQ1BERlNES19EYXRlVGltZTo6Q1BERlNES19EYXRlVGltZShjb25zdCBDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSkNCi17DQotCW9wZXJhdG9yID0gKGRhdGV0aW1lKTsNCi19DQotDQotQ1BERlNES19EYXRlVGltZTo6Q1BERlNES19EYXRlVGltZShjb25zdCBGWF9TWVNURU1USU1FJiBzdCkNCi17DQotCW9wZXJhdG9yID0gKHN0KSA7DQotfQ0KLQ0KLQ0KLXZvaWQgQ1BERlNES19EYXRlVGltZTo6UmVzZXREYXRlVGltZSgpDQotew0KLQl0enNldCgpOw0KLQ0KLQl0aW1lX3QJY3VyVGltZTsNCi0JdGltZSgmY3VyVGltZSk7DQotCXN0cnVjdCB0bSogbmV3dGltZTsNCi0JLy9uZXd0aW1lID0gZ210aW1lKCZjdXJUaW1lKTsNCi0JbmV3dGltZSA9IGxvY2FsdGltZSgmY3VyVGltZSk7DQotDQotCWR0LnllYXIgPSBuZXd0aW1lLT50bV95ZWFyICsgMTkwMDsNCi0JZHQubW9udGggPSBuZXd0aW1lLT50bV9tb24gKyAxOw0KLQlkdC5kYXkgPSBuZXd0aW1lLT50bV9tZGF5Ow0KLQlkdC5ob3VyID0gbmV3dGltZS0+dG1faG91cjsNCi0JZHQubWludXRlID0gbmV3dGltZS0+dG1fbWluOw0KLQlkdC5zZWNvbmQgPSBuZXd0aW1lLT50bV9zZWM7DQotLy8gCWR0LnR6SG91ciA9IF90aW1lem9uZSAvIDM2MDAgKiAtMTsNCi0vLyAJZHQudHpNaW51dGUgPSAoYWJzKF90aW1lem9uZSkgJSAzNjAwKSAvIDYwOw0KLX0NCi0NCi1DUERGU0RLX0RhdGVUaW1lJiBDUERGU0RLX0RhdGVUaW1lOjpvcGVyYXRvciA9IChjb25zdCBDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSkNCi17DQotCUZYU1lTX21lbWNweSgmZHQsICZkYXRldGltZS5kdCwgc2l6ZW9mKEZYX0RBVEVUSU1FKSk7DQotCXJldHVybiAqdGhpczsNCi19DQotDQotQ1BERlNES19EYXRlVGltZSYgQ1BERlNES19EYXRlVGltZTo6b3BlcmF0b3IgPSAoY29uc3QgRlhfU1lTVEVNVElNRSYgc3QpDQotew0KLQl0enNldCgpOw0KLQ0KLQlkdC55ZWFyID0gKEZYX1NIT1JUKXN0LndZZWFyOw0KLQlkdC5tb250aCA9IChGWF9CWVRFKXN0LndNb250aDsNCi0JZHQuZGF5ID0gKEZYX0JZVEUpc3Qud0RheTsNCi0JZHQuaG91ciA9IChGWF9CWVRFKXN0LndIb3VyOw0KLQlkdC5taW51dGUgPSAoRlhfQllURSlzdC53TWludXRlOw0KLQlkdC5zZWNvbmQgPSAoRlhfQllURSlzdC53U2Vjb25kOw0KLS8vIAlkdC50ekhvdXIgPSBfdGltZXpvbmUgLyAzNjAwICogLTE7DQotLy8gCWR0LnR6TWludXRlID0gKGFicyhfdGltZXpvbmUpICUgMzYwMCkgLyA2MDsNCi0JcmV0dXJuICp0aGlzOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfRGF0ZVRpbWU6Om9wZXJhdG9yID09IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSkNCi17DQotCXJldHVybiAoRlhTWVNfbWVtY21wKCZkdCwgJmRhdGV0aW1lLmR0LCBzaXplb2YoRlhfREFURVRJTUUpKSA9PSAwKTsNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0RhdGVUaW1lOjpvcGVyYXRvciAhPSAoQ1BERlNES19EYXRlVGltZSYgZGF0ZXRpbWUpDQotew0KLQlyZXR1cm4gKEZYU1lTX21lbWNtcCgmZHQsICZkYXRldGltZS5kdCwgc2l6ZW9mKEZYX0RBVEVUSU1FKSkgIT0gMCk7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19EYXRlVGltZTo6b3BlcmF0b3IgPiAoQ1BERlNES19EYXRlVGltZSYgZGF0ZXRpbWUpDQotew0KLQlDUERGU0RLX0RhdGVUaW1lIGR0MSA9IFRvR01UKCk7DQotCUNQREZTREtfRGF0ZVRpbWUgZHQyID0gZGF0ZXRpbWUuVG9HTVQoKTsNCi0JaW50IGQxID0gKCgoaW50KWR0MS5kdC55ZWFyKSA8PCAxNikgfCAoKChpbnQpZHQxLmR0Lm1vbnRoKSA8PCA4KSB8IChpbnQpZHQxLmR0LmRheTsNCi0JaW50IGQyID0gKCgoaW50KWR0MS5kdC5ob3VyKSA8PCAxNikgfCAoKChpbnQpZHQxLmR0Lm1pbnV0ZSkgPDwgOCkgfCAoaW50KWR0MS5kdC5zZWNvbmQ7DQotCWludCBkMyA9ICgoKGludClkdDIuZHQueWVhcikgPDwgMTYpIHwgKCgoaW50KWR0Mi5kdC5tb250aCkgPDwgOCkgfCAoaW50KWR0Mi5kdC5kYXk7DQotCWludCBkNCA9ICgoKGludClkdDIuZHQuaG91cikgPDwgMTYpIHwgKCgoaW50KWR0Mi5kdC5taW51dGUpIDw8IDgpIHwgKGludClkdDIuZHQuc2Vjb25kOw0KLQ0KLQlpZiAoZDEgPiBkMykgcmV0dXJuIFRSVUU7DQotCWlmIChkMiA+IGQ0KSByZXR1cm4gVFJVRTsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfRGF0ZVRpbWU6Om9wZXJhdG9yID49IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSkNCi17DQotCUNQREZTREtfRGF0ZVRpbWUgZHQxID0gVG9HTVQoKTsNCi0JQ1BERlNES19EYXRlVGltZSBkdDIgPSBkYXRldGltZS5Ub0dNVCgpOw0KLQlpbnQgZDEgPSAoKChpbnQpZHQxLmR0LnllYXIpIDw8IDE2KSB8ICgoKGludClkdDEuZHQubW9udGgpIDw8IDgpIHwgKGludClkdDEuZHQuZGF5Ow0KLQlpbnQgZDIgPSAoKChpbnQpZHQxLmR0LmhvdXIpIDw8IDE2KSB8ICgoKGludClkdDEuZHQubWludXRlKSA8PCA4KSB8IChpbnQpZHQxLmR0LnNlY29uZDsNCi0JaW50IGQzID0gKCgoaW50KWR0Mi5kdC55ZWFyKSA8PCAxNikgfCAoKChpbnQpZHQyLmR0Lm1vbnRoKSA8PCA4KSB8IChpbnQpZHQyLmR0LmRheTsNCi0JaW50IGQ0ID0gKCgoaW50KWR0Mi5kdC5ob3VyKSA8PCAxNikgfCAoKChpbnQpZHQyLmR0Lm1pbnV0ZSkgPDwgOCkgfCAoaW50KWR0Mi5kdC5zZWNvbmQ7DQotDQotCWlmIChkMSA+PSBkMykgcmV0dXJuIFRSVUU7DQotCWlmIChkMiA+PSBkNCkgcmV0dXJuIFRSVUU7DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0RhdGVUaW1lOjpvcGVyYXRvciA8IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSkNCi17DQotCUNQREZTREtfRGF0ZVRpbWUgZHQxID0gVG9HTVQoKTsNCi0JQ1BERlNES19EYXRlVGltZSBkdDIgPSBkYXRldGltZS5Ub0dNVCgpOw0KLQlpbnQgZDEgPSAoKChpbnQpZHQxLmR0LnllYXIpIDw8IDE2KSB8ICgoKGludClkdDEuZHQubW9udGgpIDw8IDgpIHwgKGludClkdDEuZHQuZGF5Ow0KLQlpbnQgZDIgPSAoKChpbnQpZHQxLmR0LmhvdXIpIDw8IDE2KSB8ICgoKGludClkdDEuZHQubWludXRlKSA8PCA4KSB8IChpbnQpZHQxLmR0LnNlY29uZDsNCi0JaW50IGQzID0gKCgoaW50KWR0Mi5kdC55ZWFyKSA8PCAxNikgfCAoKChpbnQpZHQyLmR0Lm1vbnRoKSA8PCA4KSB8IChpbnQpZHQyLmR0LmRheTsNCi0JaW50IGQ0ID0gKCgoaW50KWR0Mi5kdC5ob3VyKSA8PCAxNikgfCAoKChpbnQpZHQyLmR0Lm1pbnV0ZSkgPDwgOCkgfCAoaW50KWR0Mi5kdC5zZWNvbmQ7DQotDQotCWlmIChkMSA8IGQzKSByZXR1cm4gVFJVRTsNCi0JaWYgKGQyIDwgZDQpIHJldHVybiBUUlVFOw0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19EYXRlVGltZTo6b3BlcmF0b3IgPD0gKENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKQ0KLXsNCi0JQ1BERlNES19EYXRlVGltZSBkdDEgPSBUb0dNVCgpOw0KLQlDUERGU0RLX0RhdGVUaW1lIGR0MiA9IGRhdGV0aW1lLlRvR01UKCk7DQotCWludCBkMSA9ICgoKGludClkdDEuZHQueWVhcikgPDwgMTYpIHwgKCgoaW50KWR0MS5kdC5tb250aCkgPDwgOCkgfCAoaW50KWR0MS5kdC5kYXk7DQotCWludCBkMiA9ICgoKGludClkdDEuZHQuaG91cikgPDwgMTYpIHwgKCgoaW50KWR0MS5kdC5taW51dGUpIDw8IDgpIHwgKGludClkdDEuZHQuc2Vjb25kOw0KLQlpbnQgZDMgPSAoKChpbnQpZHQyLmR0LnllYXIpIDw8IDE2KSB8ICgoKGludClkdDIuZHQubW9udGgpIDw8IDgpIHwgKGludClkdDIuZHQuZGF5Ow0KLQlpbnQgZDQgPSAoKChpbnQpZHQyLmR0LmhvdXIpIDw8IDE2KSB8ICgoKGludClkdDIuZHQubWludXRlKSA8PCA4KSB8IChpbnQpZHQyLmR0LnNlY29uZDsNCi0NCi0JaWYgKGQxIDw9IGQzKSByZXR1cm4gVFJVRTsNCi0JaWYgKGQyIDw9IGQ0KSByZXR1cm4gVFJVRTsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1DUERGU0RLX0RhdGVUaW1lOjpvcGVyYXRvciB0aW1lX3QoKQ0KLXsNCi0Jc3RydWN0IHRtIG5ld3RpbWU7DQotDQotCW5ld3RpbWUudG1feWVhciA9IGR0LnllYXIgLSAxOTAwOw0KLQluZXd0aW1lLnRtX21vbiA9IGR0Lm1vbnRoIC0gMTsNCi0JbmV3dGltZS50bV9tZGF5ID0gZHQuZGF5Ow0KLQluZXd0aW1lLnRtX2hvdXIgPSBkdC5ob3VyOw0KLQluZXd0aW1lLnRtX21pbiA9IGR0Lm1pbnV0ZTsNCi0JbmV3dGltZS50bV9zZWMgPSBkdC5zZWNvbmQ7DQotDQotCXJldHVybiBta3RpbWUoJm5ld3RpbWUpOw0KLX0NCi0NCi1DUERGU0RLX0RhdGVUaW1lJiBDUERGU0RLX0RhdGVUaW1lOjpGcm9tUERGRGF0ZVRpbWVTdHJpbmcoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIGR0U3RyKQ0KLXsNCi0JaW50IHN0ckxlbmd0aCA9IGR0U3RyLkdldExlbmd0aCgpOw0KLQlpZiAoc3RyTGVuZ3RoID4gMCkNCi0Jew0KLQkJaW50IGkgPSAwOw0KLQkJaW50IGosIGs7DQotCQlGWF9DSEFSIGNoOw0KLQkJd2hpbGUgKGkgPCBzdHJMZW5ndGgpDQotCQl7DQotCQkJY2ggPSBkdFN0cltpXTsNCi0JCQlpZiAoY2ggPj0gJzAnICYmIGNoIDw9ICc5JykgYnJlYWs7DQotCQkJaSArKzsNCi0JCX0NCi0JCWlmIChpID49IHN0ckxlbmd0aCkgcmV0dXJuICp0aGlzOw0KLQ0KLQkJaiA9IDA7DQotCQlrID0gMDsNCi0JCXdoaWxlIChpIDwgc3RyTGVuZ3RoICYmIGogPCA0KQ0KLQkJew0KLQkJCWNoID0gZHRTdHJbaV07DQotCQkJayA9IGsgKiAxMCArIGNoIC0gJzAnOw0KLQkJCWogKys7DQotCQkJaWYgKGNoIDwgJzAnIHx8IGNoID4gJzknKSBicmVhazsNCi0JCQlpICsrOw0KLQkJfQ0KLQkJZHQueWVhciA9IChGWF9TSE9SVClrOw0KLQkJaWYgKGkgPj0gc3RyTGVuZ3RoIHx8IGogPCA0KSByZXR1cm4gKnRoaXM7DQotDQotCQlqID0gMDsNCi0JCWsgPSAwOw0KLQkJd2hpbGUgKGkgPCBzdHJMZW5ndGggJiYgaiA8IDIpDQotCQl7DQotCQkJY2ggPSBkdFN0cltpXTsNCi0JCQlrID0gayAqIDEwICsgY2ggLSAnMCc7DQotCQkJaiArKzsNCi0JCQlpZiAoY2ggPCAnMCcgfHwgY2ggPiAnOScpIGJyZWFrOw0KLQkJCWkgKys7DQotCQl9DQotCQlkdC5tb250aCA9IChGWF9CWVRFKWs7DQotCQlpZiAoaSA+PSBzdHJMZW5ndGggfHwgaiA8IDIpIHJldHVybiAqdGhpczsNCi0NCi0JCWogPSAwOw0KLQkJayA9IDA7DQotCQl3aGlsZSAoaSA8IHN0ckxlbmd0aCAmJiBqIDwgMikNCi0JCXsNCi0JCQljaCA9IGR0U3RyW2ldOw0KLQkJCWsgPSBrICogMTAgKyBjaCAtICcwJzsNCi0JCQlqICsrOw0KLQkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7DQotCQkJaSArKzsNCi0JCX0NCi0JCWR0LmRheSA9IChGWF9CWVRFKWs7DQotCQlpZiAoaSA+PSBzdHJMZW5ndGggfHwgaiA8IDIpIHJldHVybiAqdGhpczsNCi0NCi0JCWogPSAwOw0KLQkJayA9IDA7DQotCQl3aGlsZSAoaSA8IHN0ckxlbmd0aCAmJiBqIDwgMikNCi0JCXsNCi0JCQljaCA9IGR0U3RyW2ldOw0KLQkJCWsgPSBrICogMTAgKyBjaCAtICcwJzsNCi0JCQlqICsrOw0KLQkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7DQotCQkJaSArKzsNCi0JCX0NCi0JCWR0LmhvdXIgPSAoRlhfQllURSlrOw0KLQkJaWYgKGkgPj0gc3RyTGVuZ3RoIHx8IGogPCAyKSByZXR1cm4gKnRoaXM7DQotDQotCQlqID0gMDsNCi0JCWsgPSAwOw0KLQkJd2hpbGUgKGkgPCBzdHJMZW5ndGggJiYgaiA8IDIpDQotCQl7DQotCQkJY2ggPSBkdFN0cltpXTsNCi0JCQlrID0gayAqIDEwICsgY2ggLSAnMCc7DQotCQkJaiArKzsNCi0JCQlpZiAoY2ggPCAnMCcgfHwgY2ggPiAnOScpIGJyZWFrOw0KLQkJCWkgKys7DQotCQl9DQotCQlkdC5taW51dGUgPSAoRlhfQllURSlrOw0KLQkJaWYgKGkgPj0gc3RyTGVuZ3RoIHx8IGogPCAyKSByZXR1cm4gKnRoaXM7DQotDQotCQlqID0gMDsNCi0JCWsgPSAwOw0KLQkJd2hpbGUgKGkgPCBzdHJMZW5ndGggJiYgaiA8IDIpDQotCQl7DQotCQkJY2ggPSBkdFN0cltpXTsNCi0JCQlrID0gayAqIDEwICsgY2ggLSAnMCc7DQotCQkJaiArKzsNCi0JCQlpZiAoY2ggPCAnMCcgfHwgY2ggPiAnOScpIGJyZWFrOw0KLQkJCWkgKys7DQotCQl9DQotCQlkdC5zZWNvbmQgPSAoRlhfQllURSlrOw0KLQkJaWYgKGkgPj0gc3RyTGVuZ3RoIHx8IGogPCAyKSByZXR1cm4gKnRoaXM7DQotDQotCQljaCA9IGR0U3RyW2kgKytdOw0KLQkJaWYgKGNoICE9ICctJyAmJiBjaCAhPSAnKycpIHJldHVybiAqdGhpczsNCi0JCWlmIChjaCA9PSAnLScpDQotCQkJZHQudHpIb3VyID0gLTE7DQotCQllbHNlDQotCQkJZHQudHpIb3VyID0gMTsNCi0JCWogPSAwOw0KLQkJayA9IDA7DQotCQl3aGlsZSAoaSA8IHN0ckxlbmd0aCAmJiBqIDwgMikNCi0JCXsNCi0JCQljaCA9IGR0U3RyW2ldOw0KLQkJCWsgPSBrICogMTAgKyBjaCAtICcwJzsNCi0JCQlqICsrOw0KLQkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7DQotCQkJaSArKzsNCi0JCX0NCi0JCWR0LnR6SG91ciAqPSAoRlhfQ0hBUilrOw0KLQkJaWYgKGkgPj0gc3RyTGVuZ3RoIHx8IGogPCAyKSByZXR1cm4gKnRoaXM7DQotDQotCQljaCA9IGR0U3RyW2kgKytdOw0KLQkJaWYgKGNoICE9ICdcJycpIHJldHVybiAqdGhpczsNCi0JCWogPSAwOw0KLQkJayA9IDA7DQotCQl3aGlsZSAoaSA8IHN0ckxlbmd0aCAmJiBqIDwgMikNCi0JCXsNCi0JCQljaCA9IGR0U3RyW2ldOw0KLQkJCWsgPSBrICogMTAgKyBjaCAtICcwJzsNCi0JCQlqICsrOw0KLQkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7DQotCQkJaSArKzsNCi0JCX0NCi0JCWR0LnR6TWludXRlID0gKEZYX0JZVEUpazsNCi0JCWlmIChpID49IHN0ckxlbmd0aCB8fCBqIDwgMikgcmV0dXJuICp0aGlzOw0KLQl9DQotDQotCXJldHVybiAgKnRoaXM7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQREZTREtfRGF0ZVRpbWU6OlRvQ29tbW9uRGF0ZVRpbWVTdHJpbmcoKQ0KLXsNCi0JQ0ZYX0J5dGVTdHJpbmcgc3RyMTsNCi0Jc3RyMS5Gb3JtYXQoIiUwNGQtJTAyZC0lMDJkICUwMmQ6JTAyZDolMDJkICIsIGR0LnllYXIsIGR0Lm1vbnRoLCBkdC5kYXksIGR0LmhvdXIsIGR0Lm1pbnV0ZSwgZHQuc2Vjb25kKTsNCi0JaWYgKGR0LnR6SG91ciA8IDApDQotCQlzdHIxICs9ICItIjsNCi0JZWxzZQ0KLQkJc3RyMSArPSAiKyI7DQotCUNGWF9CeXRlU3RyaW5nIHN0cjI7DQotCXN0cjIuRm9ybWF0KCIlMDJkOiUwMmQiLCBhYnMoZHQudHpIb3VyKSwgZHQudHpNaW51dGUpOw0KLQlyZXR1cm4gc3RyMSArIHN0cjI7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQREZTREtfRGF0ZVRpbWU6OlRvUERGRGF0ZVRpbWVTdHJpbmcoKQ0KLXsNCi0JQ0ZYX0J5dGVTdHJpbmcgZHRTdHI7DQotCWNoYXIgdGVtcFN0clszMl07DQotCXNwcmludGYodGVtcFN0ciwgIkQ6JTA0ZCUwMmQlMDJkJTAyZCUwMmQlMDJkIiwgZHQueWVhciwgZHQubW9udGgsIGR0LmRheSwgZHQuaG91ciwgZHQubWludXRlLCBkdC5zZWNvbmQpOw0KLQlkdFN0ciA9IENGWF9CeXRlU3RyaW5nKHRlbXBTdHIpOw0KLQlpZiAoZHQudHpIb3VyIDwgMCkNCi0JCWR0U3RyICs9IENGWF9CeXRlU3RyaW5nKCItIik7DQotCWVsc2UNCi0JCWR0U3RyICs9IENGWF9CeXRlU3RyaW5nKCIrIik7DQotCXNwcmludGYodGVtcFN0ciwgIiUwMmQnJTAyZCciLCBhYnMoZHQudHpIb3VyKSwgZHQudHpNaW51dGUpOw0KLQlkdFN0ciArPSBDRlhfQnl0ZVN0cmluZyh0ZW1wU3RyKTsNCi0JcmV0dXJuIGR0U3RyOw0KLX0NCi0NCi12b2lkIENQREZTREtfRGF0ZVRpbWU6OlRvU3lzdGVtVGltZShGWF9TWVNURU1USU1FJiBzdCkNCi17DQotCUNQREZTREtfRGF0ZVRpbWUgZHQgPSAqdGhpczsNCi0JdGltZV90IHQgPSAodGltZV90KWR0Ow0KLQlzdHJ1Y3QgdG0qIHBUaW1lID0gbG9jYWx0aW1lKCZ0KTsNCi0JaWYocFRpbWUpeyANCi0JCXN0LndZZWFyID0gKEZYX1dPUkQpcFRpbWUtPnRtX3llYXIgKyAxOTAwOw0KLQkJc3Qud01vbnRoID0gKEZYX1dPUkQpcFRpbWUtPnRtX21vbiArIDE7DQotCQlzdC53RGF5ID0gKEZYX1dPUkQpcFRpbWUtPnRtX21kYXk7DQotCQlzdC53RGF5T2ZXZWVrID0gKEZYX1dPUkQpcFRpbWUtPnRtX3dkYXk7DQotCQlzdC53SG91ciA9IChGWF9XT1JEKXBUaW1lLT50bV9ob3VyOw0KLQkJc3Qud01pbnV0ZSA9IChGWF9XT1JEKXBUaW1lLT50bV9taW47DQotCQlzdC53U2Vjb25kID0gKEZYX1dPUkQpcFRpbWUtPnRtX3NlYzsNCi0JCXN0LndNaWxsaXNlY29uZHMgPSAwOw0KLQl9DQotfQ0KLQ0KLUNQREZTREtfRGF0ZVRpbWUgQ1BERlNES19EYXRlVGltZTo6VG9HTVQoKQ0KLXsNCi0JQ1BERlNES19EYXRlVGltZSBkdCA9ICp0aGlzOw0KLQlkdC5BZGRTZWNvbmRzKC1fZ0FmeEdldFRpbWVab25lSW5TZWNvbmRzKGR0LmR0LnR6SG91ciwgZHQuZHQudHpNaW51dGUpKTsNCi0JZHQuZHQudHpIb3VyID0gMDsNCi0JZHQuZHQudHpNaW51dGUgPSAwOw0KLQlyZXR1cm4gZHQ7DQotfQ0KLQ0KLUNQREZTREtfRGF0ZVRpbWUmIENQREZTREtfRGF0ZVRpbWU6OkFkZERheXMoc2hvcnQgZGF5cykNCi17DQotCWlmIChkYXlzID09IDApIHJldHVybiAqdGhpczsNCi0NCi0JRlhfU0hPUlQJeSA9IGR0LnllYXIsIHl5Ow0KLQlGWF9CWVRFCQltID0gZHQubW9udGg7DQotCUZYX0JZVEUJCWQgPSBkdC5kYXk7DQotCWludAkJCW1kYXlzLCB5ZGF5cywgbGRheXM7DQotDQotCWxkYXlzID0gZGF5czsNCi0JaWYgKGxkYXlzID4gMCkNCi0Jew0KLQkJeXkgPSB5Ow0KLQkJaWYgKCgoRlhfV09SRCltICogMTAwICsgZCkgPiAzMDApIHl5ICsrOw0KLQkJeWRheXMgPSBfZ0FmeEdldFllYXJEYXlzKHl5KTsNCi0JCXdoaWxlIChsZGF5cyA+PSB5ZGF5cykNCi0JCXsNCi0JCQl5ICsrOw0KLQkJCWxkYXlzIC09IHlkYXlzOw0KLQkJCXl5ICsrOw0KLQkJCW1kYXlzID0gX2dBZnhHZXRNb250aERheXMoeSwgbSk7DQotCQkJaWYgKGQgPiBtZGF5cykNCi0JCQl7DQotCQkJCW0gKys7DQotCQkJCWQgLT0gbWRheXM7DQotCQkJfQ0KLQkJCXlkYXlzID0gX2dBZnhHZXRZZWFyRGF5cyh5eSk7DQotCQl9DQotCQltZGF5cyA9IF9nQWZ4R2V0TW9udGhEYXlzKHksIG0pIC0gZCArIDE7DQotCQl3aGlsZSAobGRheXMgPj0gbWRheXMpDQotCQl7DQotCQkJbGRheXMgLT0gbWRheXM7DQotCQkJbSArKzsNCi0JCQlkID0gMTsNCi0JCQltZGF5cyA9IF9nQWZ4R2V0TW9udGhEYXlzKHksIG0pOw0KLQkJfQ0KLQkJZCArPSBsZGF5czsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWxkYXlzICo9IC0xOw0KLQkJeXkgPSB5Ow0KLQkJaWYgKCgoRlhfV09SRCltICogMTAwICsgZCkgPCAzMDApIHl5IC0tOw0KLQkJeWRheXMgPSBfZ0FmeEdldFllYXJEYXlzKHl5KTsNCi0JCXdoaWxlIChsZGF5cyA+PSB5ZGF5cykNCi0JCXsNCi0JCQl5IC0tOw0KLQkJCWxkYXlzIC09IHlkYXlzOw0KLQkJCXl5IC0tOw0KLQkJCW1kYXlzID0gX2dBZnhHZXRNb250aERheXMoeSwgbSk7DQotCQkJaWYgKGQgPiBtZGF5cykNCi0JCQl7DQotCQkJCW0gKys7DQotCQkJCWQgLT0gbWRheXM7DQotCQkJfQ0KLQkJCXlkYXlzID0gX2dBZnhHZXRZZWFyRGF5cyh5eSk7DQotCQl9DQotCQl3aGlsZSAobGRheXMgPj0gZCkNCi0JCXsNCi0JCQlsZGF5cyAtPSBkOw0KLQkJCW0gLS07DQotCQkJbWRheXMgPSBfZ0FmeEdldE1vbnRoRGF5cyh5LCBtKTsNCi0JCQlkID0gbWRheXM7DQotCQl9DQotCQlkIC09IGxkYXlzOw0KLQl9DQotDQotCWR0LnllYXIgPSB5Ow0KLQlkdC5tb250aCA9IG07DQotCWR0LmRheSA9IGQ7DQotDQotCXJldHVybiAqdGhpczsNCi19DQotDQotQ1BERlNES19EYXRlVGltZSYgQ1BERlNES19EYXRlVGltZTo6QWRkU2Vjb25kcyhpbnQgc2Vjb25kcykNCi17DQotCWlmIChzZWNvbmRzID09IDApIHJldHVybiAqdGhpczsNCi0NCi0JaW50CW47DQotCWludAlkYXlzOw0KLQ0KLQluID0gZHQuaG91ciAqIDM2MDAgKyBkdC5taW51dGUgKiA2MCArIGR0LnNlY29uZCArIHNlY29uZHM7DQotCWlmIChuIDwgMCkNCi0Jew0KLQkJZGF5cyA9IChuIC0gODYzOTkpIC8gODY0MDA7DQotCQluIC09IGRheXMgKiA4NjQwMDsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWRheXMgPSBuIC8gODY0MDA7DQotCQluICU9IDg2NDAwOw0KLQl9DQotCWR0LmhvdXIgPSAoRlhfQllURSkobiAvIDM2MDApOw0KLQlkdC5ob3VyICU9IDI0Ow0KLQluICU9IDM2MDA7DQotCWR0Lm1pbnV0ZSA9IChGWF9CWVRFKShuIC8gNjApOw0KLQlkdC5zZWNvbmQgPSAoRlhfQllURSkobiAlIDYwKTsNCi0JaWYgKGRheXMgIT0gMCkgQWRkRGF5cyhkYXlzKTsNCi0NCi0JcmV0dXJuICp0aGlzOw0KLX0NCi0NCi0NCi0vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KLS8vCQkJCQkJCQlDUERGU0RLX0Fubm90CQ0KLS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQotQ1BERlNES19Bbm5vdDo6Q1BERlNES19Bbm5vdChDUERGX0Fubm90KiBwQW5ub3QsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykgOg0KLW1fcEFubm90KHBBbm5vdCksDQotbV9wUGFnZVZpZXcocFBhZ2VWaWV3KSwNCi1tX2JTZWxlY3RlZChGQUxTRSksDQotbV9uVGFiT3JkZXIoLTEpDQotew0KLX0NCi0NCi1DUERGU0RLX0Fubm90Ojp+Q1BERlNES19Bbm5vdCgpDQotew0KLQltX3BBbm5vdCA9IE5VTEw7DQotCW1fcFBhZ2VWaWV3ID0gTlVMTDsNCi19DQotDQotQ1BERl9Bbm5vdCoJQ1BERlNES19Bbm5vdDo6R2V0UERGQW5ub3QoKQ0KLXsNCi0JcmV0dXJuIG1fcEFubm90Ow0KLX0NCi0NCi1GWF9EV09SRCBDUERGU0RLX0Fubm90OjpHZXRGbGFncygpDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCQ0KLQlyZXR1cm4gbV9wQW5ub3QtPkdldEZsYWdzKCk7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6U2V0UGFnZShDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLQltX3BQYWdlVmlldyA9IHBQYWdlVmlldzsNCi19DQotDQotQ1BERlNES19QYWdlVmlldyogQ1BERlNES19Bbm5vdDo6R2V0UGFnZVZpZXcoKQ0KLXsNCi0JcmV0dXJuIG1fcFBhZ2VWaWV3Ow0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfQW5ub3Q6OklzU2VsZWN0ZWQoKQ0KLXsNCi0JcmV0dXJuIG1fYlNlbGVjdGVkOw0KLX0NCi0NCi12b2lkIENQREZTREtfQW5ub3Q6OlNldFNlbGVjdGVkKEZYX0JPT0wgYlNlbGVjdGVkKQ0KLXsNCi0JbV9iU2VsZWN0ZWQgPSBiU2VsZWN0ZWQ7DQotfQ0KLQ0KLS8vIFRhYiBPcmRlcgkNCi1pbnQgQ1BERlNES19Bbm5vdDo6R2V0VGFiT3JkZXIoKQ0KLXsNCi0JcmV0dXJuIG1fblRhYk9yZGVyOw0KLX0NCi0NCi12b2lkIENQREZTREtfQW5ub3Q6OlNldFRhYk9yZGVyKGludCBpVGFiT3JkZXIpDQotew0KLQltX25UYWJPcmRlciA9IGlUYWJPcmRlcjsNCi19DQotDQotQ1BERl9EaWN0aW9uYXJ5KiBDUERGU0RLX0Fubm90OjpHZXRBbm5vdERpY3QoKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIG1fcEFubm90LT5tX3BBbm5vdERpY3Q7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6U2V0UmVjdChjb25zdCBDUERGX1JlY3QmIHJlY3QpDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQlBU1NFUlQocmVjdC5yaWdodCAtIHJlY3QubGVmdCA+PSBHZXRNaW5XaWR0aCgpKTsNCi0JQVNTRVJUKHJlY3QudG9wIC0gcmVjdC5ib3R0b20gPj0gR2V0TWluSGVpZ2h0KCkpOw0KLQkNCi0JbV9wQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXRSZWN0KCJSZWN0IiwgcmVjdCk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUERGU0RLX0Fubm90OjpHZXRSZWN0KCkgY29uc3QNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JDQotCUNQREZfUmVjdCByZWN0Ow0KLQltX3BBbm5vdC0+R2V0UmVjdChyZWN0KTsNCi0JDQotCXJldHVybiByZWN0Ow0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUERGU0RLX0Fubm90OjpHZXRUeXBlKCkgY29uc3QNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBtX3BBbm5vdC0+R2V0U3ViVHlwZSgpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUERGU0RLX0Fubm90OjpHZXRTdWJUeXBlKCkgY29uc3QNCi17DQotCXJldHVybiAiIjsNCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90OjpSZXNldEFwcGVhcmFuY2UoKQ0KLXsNCi0JQVNTRVJUKEZBTFNFKTsNCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90OjpEcmF3QXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBjb25zdCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJCQkJCQkJICAgQ1BERl9Bbm5vdDo6QXBwZWFyYW5jZU1vZGUgbW9kZSwgY29uc3QgQ1BERl9SZW5kZXJPcHRpb25zKiBwT3B0aW9ucykJDQotew0KLQlBU1NFUlQobV9wUGFnZVZpZXcgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JDQotCW1fcEFubm90LT5EcmF3QXBwZWFyYW5jZShtX3BQYWdlVmlldy0+R2V0UERGUGFnZSgpLCBwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIG1vZGUsIHBPcHRpb25zKTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0Fubm90OjpJc0FwcGVhcmFuY2VWYWxpZCgpDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkFQIikgIT0gTlVMTDsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0Fubm90OjpJc0FwcGVhcmFuY2VWYWxpZChDUERGX0Fubm90OjpBcHBlYXJhbmNlTW9kZSBtb2RlKQ0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0JDQotCUNQREZfRGljdGlvbmFyeSogcEFQID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQVAiKTsNCi0JaWYgKHBBUCA9PSBOVUxMKSByZXR1cm4gRkFMU0U7DQotCQ0KLQkvLyBDaG9vc2UgdGhlIHJpZ2h0IHN1Yi1hcA0KLQljb25zdCBGWF9DSEFSKiBhcF9lbnRyeSA9ICJOIjsNCi0JaWYgKG1vZGUgPT0gQ1BERl9Bbm5vdDo6RG93bikNCi0JCWFwX2VudHJ5ID0gIkQiOw0KLQllbHNlIGlmIChtb2RlID09IENQREZfQW5ub3Q6OlJvbGxvdmVyKQ0KLQkJYXBfZW50cnkgPSAiUiI7DQotCWlmICghcEFQLT5LZXlFeGlzdChhcF9lbnRyeSkpDQotCQlhcF9lbnRyeSA9ICJOIjsNCi0JDQotCS8vIEdldCB0aGUgQVAgc3RyZWFtIG9yIHN1YmRpcmVjdG9yeQ0KLQlDUERGX09iamVjdCogcHN1YiA9IHBBUC0+R2V0RWxlbWVudFZhbHVlKGFwX2VudHJ5KTsNCi0JaWYgKHBzdWIgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOw0KLQkNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6RHJhd0JvcmRlcihDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBjb25zdCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJCQkJCSAgIGNvbnN0IENQREZfUmVuZGVyT3B0aW9ucyogcE9wdGlvbnMpDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCW1fcEFubm90LT5EcmF3Qm9yZGVyKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcE9wdGlvbnMpOyANCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90OjpDbGVhckNhY2hlZEFQKCkNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JbV9wQW5ub3QtPkNsZWFyQ2FjaGVkQVAoKTsNCi19ICAgIA0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6U2V0Q29udGVudHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNDb250ZW50cykNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotCQ0KLQlpZiAoc0NvbnRlbnRzLklzRW1wdHkoKSkNCi0JCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlJlbW92ZUF0KCJDb250ZW50cyIpOw0KLQllbHNlDQotCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdFN0cmluZygiQ29udGVudHMiLCBQREZfRW5jb2RlVGV4dChzQ29udGVudHMpKTsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ1BERlNES19Bbm5vdDo6R2V0Q29udGVudHMoKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXRVbmljb2RlVGV4dCgiQ29udGVudHMiKTsNCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90OjpTZXRBbm5vdE5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKQ0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0JDQotCWlmIChzTmFtZS5Jc0VtcHR5KCkpDQotCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5SZW1vdmVBdCgiTk0iKTsNCi0JZWxzZQ0KLQkJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXRTdHJpbmcoIk5NIiwgUERGX0VuY29kZVRleHQoc05hbWUpKTsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ1BERlNES19Bbm5vdDo6R2V0QW5ub3ROYW1lKCkgY29uc3QNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotCQ0KLQlyZXR1cm4gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0VW5pY29kZVRleHQoIk5NIik7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6U2V0TW9kaWZpZWREYXRlKGNvbnN0IEZYX1NZU1RFTVRJTUUmIHN0KQ0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0JDQotCUNQREZTREtfRGF0ZVRpbWUgZHQoc3QpOw0KLQlDRlhfQnl0ZVN0cmluZyBzdHIgPSBkdC5Ub1BERkRhdGVUaW1lU3RyaW5nKCk7DQotCQ0KLQlpZiAoc3RyLklzRW1wdHkoKSkNCi0JCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlJlbW92ZUF0KCJNIik7DQotCWVsc2UNCi0JCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0U3RyaW5nKCJNIiwgc3RyKTsNCi19DQotDQotRlhfU1lTVEVNVElNRSBDUERGU0RLX0Fubm90OjpHZXRNb2RpZmllZERhdGUoKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0JDQotCUZYX1NZU1RFTVRJTUUgc3lzdGltZTsJDQotCUNGWF9CeXRlU3RyaW5nIHN0ciA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldFN0cmluZygiTSIpOw0KLQkNCi0gCUNQREZTREtfRGF0ZVRpbWUgZHQoc3RyKTsNCi0gCWR0LlRvU3lzdGVtVGltZShzeXN0aW1lKTsNCi0JDQotCXJldHVybiBzeXN0aW1lOw0KLX0NCi0NCi12b2lkIENQREZTREtfQW5ub3Q6OlNldEZsYWdzKGludCBuRmxhZ3MpDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQkNCi0JbV9wQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXRJbnRlZ2VyKCJGIiwgbkZsYWdzKTsNCi19DQotDQotaW50IENQREZTREtfQW5ub3Q6OkdldEZsYWdzKCkgY29uc3QNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotCQ0KLQlyZXR1cm4gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0SW50ZWdlcigiRiIpOw0KLX0NCi0NCi12b2lkIENQREZTREtfQW5ub3Q6OlNldEFwcFN0YXRlKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHIpDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQ0KLQlpZiAoc3RyLklzRW1wdHkoKSkNCi0JCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlJlbW92ZUF0KCJBUyIpOw0KLQllbHNlDQotCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdFN0cmluZygiQVMiLCBzdHIpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUERGU0RLX0Fubm90OjpHZXRBcHBTdGF0ZSgpIGNvbnN0DQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQ0KLQlyZXR1cm4gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0U3RyaW5nKCJBUyIpOw0KLX0NCi0NCi12b2lkIENQREZTREtfQW5ub3Q6OlNldFN0cnVjdFBhcmVudChpbnQga2V5KQ0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0JDQotCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0SW50ZWdlcigiU3RydWN0UGFyZW50Iiwga2V5KTsNCi19DQotDQotaW50CUNQREZTREtfQW5ub3Q6OkdldFN0cnVjdFBhcmVudCgpIGNvbnN0DQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldEludGVnZXIoIlN0cnVjdFBhcmVudCIpOw0KLX0NCi0NCi0vL2JvcmRlcg0KLXZvaWQgQ1BERlNES19Bbm5vdDo6U2V0Qm9yZGVyV2lkdGgoaW50IG5XaWR0aCkNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotDQotCUNQREZfQXJyYXkqIHBCb3JkZXIgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXRBcnJheSgiQm9yZGVyIik7DQotDQotCWlmIChwQm9yZGVyKQ0KLQl7DQotCQlwQm9yZGVyLT5TZXRBdCgyLCBGWF9ORVcgQ1BERl9OdW1iZXIobldpZHRoKSk7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBCU0RpY3QgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJCUyIpOw0KLQ0KLQkJaWYgKCFwQlNEaWN0KQ0KLQkJew0KLQkJCXBCU0RpY3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5Ow0KLQkJCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0KCJCUyIsIHBCU0RpY3QpOw0KLQkJfQ0KLQ0KLQkJcEJTRGljdC0+U2V0QXRJbnRlZ2VyKCJXIiwgbldpZHRoKTsNCi0JfQ0KLX0NCi0NCi1pbnQJQ1BERlNES19Bbm5vdDo6R2V0Qm9yZGVyV2lkdGgoKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9BcnJheSogcEJvcmRlciA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldEFycmF5KCJCb3JkZXIiKTsNCi0NCi0JaWYgKHBCb3JkZXIpDQotCXsNCi0JCXJldHVybiBwQm9yZGVyLT5HZXRJbnRlZ2VyKDIpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwQlNEaWN0ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQlMiKTsNCi0NCi0JCWlmIChwQlNEaWN0KQ0KLQkJew0KLQkJCXJldHVybiBwQlNEaWN0LT5HZXRJbnRlZ2VyKCJXIiwgMSk7DQotCQl9DQotCX0NCi0JcmV0dXJuIDE7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6U2V0Qm9yZGVyU3R5bGUoaW50IG5TdHlsZSkNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotDQotCUNQREZfRGljdGlvbmFyeSogcEJTRGljdCA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkJTIik7DQotCWlmICghcEJTRGljdCkNCi0Jew0KLQkJcEJTRGljdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7DQotCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdCgiQlMiLCBwQlNEaWN0KTsNCi0JfQ0KLQ0KLQlzd2l0Y2ggKG5TdHlsZSkNCi0Jew0KLQljYXNlIEJCU19TT0xJRDoNCi0JCXBCU0RpY3QtPlNldEF0TmFtZSgiUyIsICJTIik7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfREFTSDoNCi0JCXBCU0RpY3QtPlNldEF0TmFtZSgiUyIsICJEIik7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfQkVWRUxFRDoNCi0JCXBCU0RpY3QtPlNldEF0TmFtZSgiUyIsICJCIik7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfSU5TRVQ6DQotCQlwQlNEaWN0LT5TZXRBdE5hbWUoIlMiLCAiSSIpOw0KLQkJYnJlYWs7DQotCWNhc2UgQkJTX1VOREVSTElORToNCi0JCXBCU0RpY3QtPlNldEF0TmFtZSgiUyIsICJVIik7DQotCQlicmVhazsNCi0JfQ0KLX0NCi0NCi1pbnQJQ1BERlNES19Bbm5vdDo6R2V0Qm9yZGVyU3R5bGUoKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwQlNEaWN0ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQlMiKTsNCi0JaWYgKHBCU0RpY3QpDQotCXsNCi0JCUNGWF9CeXRlU3RyaW5nIHNCb3JkZXJTdHlsZSA9IHBCU0RpY3QtPkdldFN0cmluZygiUyIsICJTIik7DQotCQlpZiAoc0JvcmRlclN0eWxlID09ICJTIikgcmV0dXJuIEJCU19TT0xJRDsNCi0JCWlmIChzQm9yZGVyU3R5bGUgPT0gIkQiKSByZXR1cm4gQkJTX0RBU0g7DQotCQlpZiAoc0JvcmRlclN0eWxlID09ICJCIikgcmV0dXJuIEJCU19CRVZFTEVEOw0KLQkJaWYgKHNCb3JkZXJTdHlsZSA9PSAiSSIpIHJldHVybiBCQlNfSU5TRVQ7DQotCQlpZiAoc0JvcmRlclN0eWxlID09ICJVIikgcmV0dXJuIEJCU19VTkRFUkxJTkU7DQotCX0NCi0NCi0JQ1BERl9BcnJheSogcEJvcmRlciA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldEFycmF5KCJCb3JkZXIiKTsNCi0JaWYgKHBCb3JkZXIpDQotCXsNCi0JCWlmIChwQm9yZGVyLT5HZXRDb3VudCgpID49IDQpIA0KLQkJeyANCi0JCQlDUERGX0FycmF5ICpwRFAgPSBwQm9yZGVyLT5HZXRBcnJheSgzKTsNCi0JCQlpZiAocERQICYmIHBEUC0+R2V0Q291bnQoKSA+IDApDQotCQkJCXJldHVybiBCQlNfREFTSDsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gQkJTX1NPTElEOw0KLX0NCi0NCi12b2lkIENQREZTREtfQW5ub3Q6OlNldEJvcmRlckRhc2goY29uc3QgQ0ZYX0ludEFycmF5JiBhcnJheSkNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotDQotCUNQREZfRGljdGlvbmFyeSogcEJTRGljdCA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkJTIik7DQotCWlmICghcEJTRGljdCkNCi0Jew0KLQkJcEJTRGljdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7DQotCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdCgiQlMiLCBwQlNEaWN0KTsNCi0JfQ0KLQ0KLQlDUERGX0FycmF5KiBwQXJyYXkgPSBGWF9ORVcgQ1BERl9BcnJheTsNCi0JZm9yIChpbnQgaT0wLHN6PWFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlwQXJyYXktPkFkZEludGVnZXIoYXJyYXlbaV0pOw0KLQl9DQotDQotCXBCU0RpY3QtPlNldEF0KCJEIiwgcEFycmF5KTsNCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90OjpHZXRCb3JkZXJEYXNoKENGWF9JbnRBcnJheSYgYXJyYXkpIGNvbnN0DQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQ0KLQlDUERGX0FycmF5KiBwRGFzaCA9IE5VTEw7DQotDQotCUNQREZfQXJyYXkqIHBCb3JkZXIgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXRBcnJheSgiQm9yZGVyIik7DQotCWlmIChwQm9yZGVyKQ0KLQl7DQotCQlwRGFzaCA9IHBCb3JkZXItPkdldEFycmF5KDMpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwQlNEaWN0ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQlMiKTsNCi0JCWlmIChwQlNEaWN0KQ0KLQkJew0KLQkJCXBEYXNoID0gcEJTRGljdC0+R2V0QXJyYXkoIkQiKTsNCi0JCX0NCi0JfQ0KLQ0KLQlpZiAocERhc2gpDQotCXsNCi0JCWZvciAoaW50IGk9MCxzej1wRGFzaC0+R2V0Q291bnQoKTsgaTxzejsgaSsrKQ0KLQkJew0KLQkJCWFycmF5LkFkZChwRGFzaC0+R2V0SW50ZWdlcihpKSk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDUERGU0RLX0Fubm90OjpTZXRDb2xvcihGWF9DT0xPUlJFRiBjb2xvcikNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotDQotCUNQREZfQXJyYXkqIHBBcnJheSA9IEZYX05FVyBDUERGX0FycmF5Ow0KLQlwQXJyYXktPkFkZE51bWJlcigoRlhfRkxPQVQpRlhTWVNfR2V0UlZhbHVlKGNvbG9yKSAvIDI1NS4wZik7DQotCXBBcnJheS0+QWRkTnVtYmVyKChGWF9GTE9BVClGWFNZU19HZXRHVmFsdWUoY29sb3IpIC8gMjU1LjBmKTsNCi0JcEFycmF5LT5BZGROdW1iZXIoKEZYX0ZMT0FUKUZYU1lTX0dldEJWYWx1ZShjb2xvcikgLyAyNTUuMGYpOw0KLQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdCgiQyIsIHBBcnJheSk7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6UmVtb3ZlQ29sb3IoKQ0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0NCi0JbV9wQW5ub3QtPm1fcEFubm90RGljdC0+UmVtb3ZlQXQoIkMiKSA7IA0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfQW5ub3Q6OkdldENvbG9yKEZYX0NPTE9SUkVGJiBjb2xvcikgY29uc3QNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotDQotCWlmIChDUERGX0FycmF5KiBwRW50cnkgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXRBcnJheSgiQyIpKQkJDQotCXsNCi0JCWludCBuQ291bnQgPSBwRW50cnktPkdldENvdW50KCk7DQotCQlpZiAobkNvdW50ID09IDEpDQotCQl7DQotCQkJRlhfRkxPQVQgZyA9IHBFbnRyeS0+R2V0TnVtYmVyKDApICogMjU1Ow0KLQ0KLQkJCWNvbG9yID0gRlhTWVNfUkdCKChpbnQpZywgKGludClnLCAoaW50KWcpOw0KLQ0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQkJZWxzZSBpZiAobkNvdW50ID09IDMpDQotCQl7DQotCQkJRlhfRkxPQVQgciA9IHBFbnRyeS0+R2V0TnVtYmVyKDApICogMjU1Ow0KLQkJCUZYX0ZMT0FUIGcgPSBwRW50cnktPkdldE51bWJlcigxKSAqIDI1NTsNCi0JCQlGWF9GTE9BVCBiID0gcEVudHJ5LT5HZXROdW1iZXIoMikgKiAyNTU7DQotDQotCQkJY29sb3IgPSBGWFNZU19SR0IoKGludClyLCAoaW50KWcsIChpbnQpYik7DQotDQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCQllbHNlIGlmIChuQ291bnQgPT0gNCkNCi0JCXsNCi0JCQlGWF9GTE9BVCBjID0gcEVudHJ5LT5HZXROdW1iZXIoMCk7DQotCQkJRlhfRkxPQVQgbSA9IHBFbnRyeS0+R2V0TnVtYmVyKDEpOw0KLQkJCUZYX0ZMT0FUIHkgPSBwRW50cnktPkdldE51bWJlcigyKTsNCi0JCQlGWF9GTE9BVCBrID0gcEVudHJ5LT5HZXROdW1iZXIoMyk7DQotDQotCQkJRlhfRkxPQVQgciA9IDEuMGYgLSBGWF9NSU4oMS4wZiwgYyArIGspOw0KLQkJCUZYX0ZMT0FUIGcgPSAxLjBmIC0gRlhfTUlOKDEuMGYsIG0gKyBrKTsNCi0JCQlGWF9GTE9BVCBiID0gMS4wZiAtIEZYX01JTigxLjBmLCB5ICsgayk7DQotDQotCQkJY29sb3IgPSBGWFNZU19SR0IoKGludCkociAqIDI1NSksIChpbnQpKGcgKiAyNTUpLCAoaW50KShiICogMjU1KSk7DQotDQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi0NCi12b2lkIENQREZTREtfQW5ub3Q6OldyaXRlQXBwZWFyYW5jZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FQVHlwZSwgY29uc3QgQ1BERl9SZWN0JiByY0JCb3gsIA0KLQkJCQkJCQkJY29uc3QgQ1BERl9NYXRyaXgmIG1hdHJpeCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNDb250ZW50cywNCi0JCQkJCQkJCWNvbnN0IENGWF9CeXRlU3RyaW5nJiBzQVBTdGF0ZSkNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotCQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBBUERpY3QgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJBUCIpOw0KLQkNCi0JaWYgKCFwQVBEaWN0KSANCi0Jew0KLQkJcEFQRGljdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7DQotCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdCgiQVAiLCBwQVBEaWN0KTsNCi0JfQ0KLQkNCi0JQ1BERl9TdHJlYW0qIHBTdHJlYW0gPSBOVUxMOw0KLQlDUERGX0RpY3Rpb25hcnkqIHBQYXJlbnREaWN0ID0gTlVMTDsNCi0JDQotCWlmIChzQVBTdGF0ZS5Jc0VtcHR5KCkpDQotCXsNCi0JCXBQYXJlbnREaWN0ID0gcEFQRGljdDsNCi0JCXBTdHJlYW0gPSBwQVBEaWN0LT5HZXRTdHJlYW0oc0FQVHlwZSk7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBBUFR5cGVEaWN0ID0gcEFQRGljdC0+R2V0RGljdChzQVBUeXBlKTsNCi0JCWlmICghcEFQVHlwZURpY3QpDQotCQl7DQotCQkJcEFQVHlwZURpY3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5Ow0KLQkJCXBBUERpY3QtPlNldEF0KHNBUFR5cGUsIHBBUFR5cGVEaWN0KTsNCi0JCX0NCi0JCQ0KLQkJcFBhcmVudERpY3QgPSBwQVBUeXBlRGljdDsNCi0JCXBTdHJlYW0gPSBwQVBUeXBlRGljdC0+R2V0U3RyZWFtKHNBUFN0YXRlKTsNCi0JfQ0KLQkNCi0JaWYgKCFwU3RyZWFtKSANCi0Jew0KLQkJQVNTRVJUKG1fcFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQkJQ1BERl9Eb2N1bWVudCogcERvYyA9IG1fcFBhZ2VWaWV3LT5HZXRQREZEb2N1bWVudCgpOw0KLQkJQVNTRVJUKHBEb2MgIT0gTlVMTCk7DQotCQkNCi0JCXBTdHJlYW0gPSBGWF9ORVcgQ1BERl9TdHJlYW0oTlVMTCwgMCwgTlVMTCk7DQotCQlGWF9JTlQzMiBvYmpudW0gPSBwRG9jLT5BZGRJbmRpcmVjdE9iamVjdChwU3RyZWFtKTsNCi0JCS8vcEFQRGljdC0+U2V0QXRSZWZlcmVuY2Uoc0FQVHlwZSwgcERvYywgb2JqbnVtKTsNCi0JCUFTU0VSVChwUGFyZW50RGljdCAhPSBOVUxMKTsNCi0JCXBQYXJlbnREaWN0LT5TZXRBdFJlZmVyZW5jZShzQVBUeXBlLCBwRG9jLCBvYmpudW0pOw0KLQl9DQotCQ0KLQlDUERGX0RpY3Rpb25hcnkgKiBwU3RyZWFtRGljdCA9IHBTdHJlYW0tPkdldERpY3QoKTsNCi0JDQotCWlmICghcFN0cmVhbURpY3QpDQotCXsNCi0JCXBTdHJlYW1EaWN0ID0gRlhfTkVXIENQREZfRGljdGlvbmFyeTsNCi0JCXBTdHJlYW1EaWN0LT5TZXRBdE5hbWUoIlR5cGUiLCAiWE9iamVjdCIpOw0KLQkJcFN0cmVhbURpY3QtPlNldEF0TmFtZSgiU3VidHlwZSIsICJGb3JtIik7DQotCQlwU3RyZWFtRGljdC0+U2V0QXRJbnRlZ2VyKCJGb3JtVHlwZSIsIDEpOw0KLQkJcFN0cmVhbS0+SW5pdFN0cmVhbShOVUxMLDAscFN0cmVhbURpY3QpOw0KLQl9DQotCQ0KLQlpZiAocFN0cmVhbURpY3QpDQotCXsNCi0JCXBTdHJlYW1EaWN0LT5TZXRBdE1hdHJpeCgiTWF0cml4IixtYXRyaXgpOwkNCi0JCXBTdHJlYW1EaWN0LT5TZXRBdFJlY3QoIkJCb3giLCByY0JCb3gpOwkJDQotCX0NCi0JDQotCXBTdHJlYW0tPlNldERhdGEoKEZYX0JZVEUqKShGWF9MUENTVFIpc0NvbnRlbnRzLCBzQ29udGVudHMuR2V0TGVuZ3RoKCksIEZBTFNFLCBGQUxTRSk7DQotfQ0KLQ0KLSNkZWZpbmUgQkFfQU5OT1RfTUlOV0lEVEgJCQkxDQotI2RlZmluZSBCQV9BTk5PVF9NSU5IRUlHSFQJCQkxDQotDQotRlhfRkxPQVQgQ1BERlNES19Bbm5vdDo6R2V0TWluV2lkdGgoKSBjb25zdA0KLXsNCi0JcmV0dXJuIEJBX0FOTk9UX01JTldJRFRIOw0KLX0NCi0NCi1GWF9GTE9BVCBDUERGU0RLX0Fubm90OjpHZXRNaW5IZWlnaHQoKSBjb25zdA0KLXsNCi0JcmV0dXJuIEJBX0FOTk9UX01JTkhFSUdIVDsNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0Fubm90OjpDcmVhdGVGb3JtRmlsbGVyKCkNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi1GWF9CT09MCUNQREZTREtfQW5ub3Q6OklzVmlzaWJsZSgpIGNvbnN0DQotew0KLQlpbnQgbkZsYWdzID0gR2V0RmxhZ3MoKTsNCi0JcmV0dXJuICEoKG5GbGFncyAmIEFOTk9URkxBR19JTlZJU0lCTEUpIHx8IChuRmxhZ3MgJiBBTk5PVEZMQUdfSElEREVOKSB8fCAobkZsYWdzICYgQU5OT1RGTEFHX05PVklFVykpOw0KLX0NCi0NCi1DUERGX0FjdGlvbiBDUERGU0RLX0Fubm90OjpHZXRBY3Rpb24oKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJBIik7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6U2V0QWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQkNCi0JQVNTRVJUKGFjdGlvbiAhPSBOVUxMKTsNCi0JDQotCWlmICgoQ1BERl9BY3Rpb24mKWFjdGlvbiAhPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJBIikpDQotCXsNCi0JCUNQREZfRG9jdW1lbnQqIHBEb2MgPSBtX3BQYWdlVmlldy0+R2V0UERGRG9jdW1lbnQoKTsNCi0JCUFTU0VSVChwRG9jICE9IE5VTEwpOw0KLQkJDQotCQlpZiAoYWN0aW9uLm1fcERpY3QgJiYgKGFjdGlvbi5tX3BEaWN0LT5HZXRPYmpOdW0oKSA9PSAwKSkNCi0JCQlwRG9jLT5BZGRJbmRpcmVjdE9iamVjdChhY3Rpb24ubV9wRGljdCk7IA0KLQkJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXRSZWZlcmVuY2UoIkEiLCBwRG9jLCBhY3Rpb24ubV9wRGljdC0+R2V0T2JqTnVtKCkpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6UmVtb3ZlQWN0aW9uKCkNCi17DQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7DQotCQ0KLQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5SZW1vdmVBdCgiQSIpOw0KLX0NCi0NCi1DUERGX0FBY3Rpb24gQ1BERlNES19Bbm5vdDo6R2V0QUFjdGlvbigpIGNvbnN0DQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkFBIik7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6U2V0QUFjdGlvbihjb25zdCBDUERGX0FBY3Rpb24mIGFhKQ0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0JQVNTRVJUKGFhICE9IE5VTEwpOw0KLQkNCi0JaWYgKChDUERGX0FBY3Rpb24mKWFhICE9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkFBIikpDQotCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdCgiQUEiLCAoQ1BERl9BQWN0aW9uJilhYSk7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19Bbm5vdDo6UmVtb3ZlQUFjdGlvbigpDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQkNCi0JbV9wQW5ub3QtPm1fcEFubm90RGljdC0+UmVtb3ZlQXQoIkFBIik7DQotfQ0KLQ0KLUNQREZfQWN0aW9uCUNQREZTREtfQW5ub3Q6OkdldEFBY3Rpb24oQ1BERl9BQWN0aW9uOjpBQWN0aW9uVHlwZSBlQUFUKQ0KLXsNCi0JQ1BERl9BQWN0aW9uIEFBY3Rpb24gPSBHZXRBQWN0aW9uKCk7DQotCQ0KLQlpZiAoQUFjdGlvbi5BY3Rpb25FeGlzdChlQUFUKSkNCi0Jew0KLQkJcmV0dXJuIEFBY3Rpb24uR2V0QWN0aW9uKGVBQVQpOw0KLQl9DQotCWVsc2UgaWYgKGVBQVQgPT0gQ1BERl9BQWN0aW9uOjpCdXR0b25VcCkNCi0Jew0KLQkJcmV0dXJuIEdldEFjdGlvbigpOw0KLQl9DQotCQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCAgQ1BERlNES19Bbm5vdDo6QW5ub3RfT25EcmF3KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsIENQREZfUmVuZGVyT3B0aW9ucyogcE9wdGlvbnMpDQotew0KLQkNCi0JbV9wQW5ub3QtPkdldEFQRm9ybShtX3BQYWdlVmlldy0+R2V0UERGUGFnZSgpLCBDUERGX0Fubm90OjpOb3JtYWwpOw0KLQltX3BBbm5vdC0+RHJhd0FwcGVhcmFuY2UobV9wUGFnZVZpZXctPkdldFBERlBhZ2UoKSwgcERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpOb3JtYWwsIE5VTEwpOw0KLQ0KLQlyZXR1cm4gOw0KLX0NCi0NCi1DUERGX1BhZ2UqIENQREZTREtfQW5ub3Q6OkdldFBERlBhZ2UoKQ0KLXsNCi0JaWYobV9wUGFnZVZpZXcpDQotCQlyZXR1cm4gbV9wUGFnZVZpZXctPkdldFBERlBhZ2UoKTsNCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfZGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX21nci5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19iYXNlYW5ub3QuaCIKKworCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8JCQkJCQkJCUNQREZTREtfRGF0ZVRpbWUJCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoraW50IF9nQWZ4R2V0VGltZVpvbmVJblNlY29uZHMoRlhfQ0hBUiB0emhvdXIsIEZYX0JZVEUgdHptaW51dGUpCit7CisJcmV0dXJuIChpbnQpdHpob3VyICogMzYwMCArIChpbnQpdHptaW51dGUgKiAodHpob3VyID49IDAgPyA2MCA6IC02MCk7Cit9CisKK0ZYX0JPT0wgX2dBZnhJc0xlYXBZZWFyKEZYX1NIT1JUIHllYXIpCit7CisJcmV0dXJuICgoeWVhciAlIDQwMCA9PSAwKSB8fCAoKHllYXIgJSA0ID09IDApICYmICh5ZWFyICUgMTAwICE9IDApKSk7Cit9CisKK0ZYX1dPUkQgX2dBZnhHZXRZZWFyRGF5cyhGWF9TSE9SVCB5ZWFyKQoreworCXJldHVybiAoX2dBZnhJc0xlYXBZZWFyKHllYXIpID09IFRSVUUgPyAzNjYgOiAzNjUpOworfQorCitGWF9CWVRFIF9nQWZ4R2V0TW9udGhEYXlzKEZYX1NIT1JUIHllYXIsIEZYX0JZVEUgbW9udGgpCit7CisJRlhfQllURQltRGF5czsKKwlzd2l0Y2ggKG1vbnRoKQorCXsKKwljYXNlIDE6CisJY2FzZSAzOgorCWNhc2UgNToKKwljYXNlIDc6CisJY2FzZSA4OgorCWNhc2UgMTA6CisJY2FzZSAxMjoKKwkJbURheXMgPSAzMTsKKwkJYnJlYWs7CisKKwljYXNlIDQ6CisJY2FzZSA2OgorCWNhc2UgOToKKwljYXNlIDExOgorCQltRGF5cyA9IDMwOworCQlicmVhazsKKworCWNhc2UgMjoKKwkJaWYgKF9nQWZ4SXNMZWFwWWVhcih5ZWFyKSA9PSBUUlVFKQorCQkJbURheXMgPSAyOTsKKwkJZWxzZQorCQkJbURheXMgPSAyODsKKwkJYnJlYWs7CisKKwlkZWZhdWx0OgorCQltRGF5cyA9IDA7CisJCWJyZWFrOworCX0KKworCXJldHVybiBtRGF5czsKK30KKworQ1BERlNES19EYXRlVGltZTo6Q1BERlNES19EYXRlVGltZSgpCit7CisJUmVzZXREYXRlVGltZSgpOworfQorCitDUERGU0RLX0RhdGVUaW1lOjpDUERGU0RLX0RhdGVUaW1lKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBkdFN0cikKK3sKKwlSZXNldERhdGVUaW1lKCk7CisKKwlGcm9tUERGRGF0ZVRpbWVTdHJpbmcoZHRTdHIpOworfQorCitDUERGU0RLX0RhdGVUaW1lOjpDUERGU0RLX0RhdGVUaW1lKGNvbnN0IENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKQoreworCW9wZXJhdG9yID0gKGRhdGV0aW1lKTsKK30KKworQ1BERlNES19EYXRlVGltZTo6Q1BERlNES19EYXRlVGltZShjb25zdCBGWF9TWVNURU1USU1FJiBzdCkKK3sKKwlvcGVyYXRvciA9IChzdCkgOworfQorCisKK3ZvaWQgQ1BERlNES19EYXRlVGltZTo6UmVzZXREYXRlVGltZSgpCit7CisJdHpzZXQoKTsKKworCXRpbWVfdAljdXJUaW1lOworCXRpbWUoJmN1clRpbWUpOworCXN0cnVjdCB0bSogbmV3dGltZTsKKwkvL25ld3RpbWUgPSBnbXRpbWUoJmN1clRpbWUpOworCW5ld3RpbWUgPSBsb2NhbHRpbWUoJmN1clRpbWUpOworCisJZHQueWVhciA9IG5ld3RpbWUtPnRtX3llYXIgKyAxOTAwOworCWR0Lm1vbnRoID0gbmV3dGltZS0+dG1fbW9uICsgMTsKKwlkdC5kYXkgPSBuZXd0aW1lLT50bV9tZGF5OworCWR0LmhvdXIgPSBuZXd0aW1lLT50bV9ob3VyOworCWR0Lm1pbnV0ZSA9IG5ld3RpbWUtPnRtX21pbjsKKwlkdC5zZWNvbmQgPSBuZXd0aW1lLT50bV9zZWM7CisvLyAJZHQudHpIb3VyID0gX3RpbWV6b25lIC8gMzYwMCAqIC0xOworLy8gCWR0LnR6TWludXRlID0gKGFicyhfdGltZXpvbmUpICUgMzYwMCkgLyA2MDsKK30KKworQ1BERlNES19EYXRlVGltZSYgQ1BERlNES19EYXRlVGltZTo6b3BlcmF0b3IgPSAoY29uc3QgQ1BERlNES19EYXRlVGltZSYgZGF0ZXRpbWUpCit7CisJRlhTWVNfbWVtY3B5KCZkdCwgJmRhdGV0aW1lLmR0LCBzaXplb2YoRlhfREFURVRJTUUpKTsKKwlyZXR1cm4gKnRoaXM7Cit9CisKK0NQREZTREtfRGF0ZVRpbWUmIENQREZTREtfRGF0ZVRpbWU6Om9wZXJhdG9yID0gKGNvbnN0IEZYX1NZU1RFTVRJTUUmIHN0KQoreworCXR6c2V0KCk7CisKKwlkdC55ZWFyID0gKEZYX1NIT1JUKXN0LndZZWFyOworCWR0Lm1vbnRoID0gKEZYX0JZVEUpc3Qud01vbnRoOworCWR0LmRheSA9IChGWF9CWVRFKXN0LndEYXk7CisJZHQuaG91ciA9IChGWF9CWVRFKXN0LndIb3VyOworCWR0Lm1pbnV0ZSA9IChGWF9CWVRFKXN0LndNaW51dGU7CisJZHQuc2Vjb25kID0gKEZYX0JZVEUpc3Qud1NlY29uZDsKKy8vIAlkdC50ekhvdXIgPSBfdGltZXpvbmUgLyAzNjAwICogLTE7CisvLyAJZHQudHpNaW51dGUgPSAoYWJzKF90aW1lem9uZSkgJSAzNjAwKSAvIDYwOworCXJldHVybiAqdGhpczsKK30KKworRlhfQk9PTCBDUERGU0RLX0RhdGVUaW1lOjpvcGVyYXRvciA9PSAoQ1BERlNES19EYXRlVGltZSYgZGF0ZXRpbWUpCit7CisJcmV0dXJuIChGWFNZU19tZW1jbXAoJmR0LCAmZGF0ZXRpbWUuZHQsIHNpemVvZihGWF9EQVRFVElNRSkpID09IDApOworfQorCitGWF9CT09MIENQREZTREtfRGF0ZVRpbWU6Om9wZXJhdG9yICE9IChDUERGU0RLX0RhdGVUaW1lJiBkYXRldGltZSkKK3sKKwlyZXR1cm4gKEZYU1lTX21lbWNtcCgmZHQsICZkYXRldGltZS5kdCwgc2l6ZW9mKEZYX0RBVEVUSU1FKSkgIT0gMCk7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19EYXRlVGltZTo6b3BlcmF0b3IgPiAoQ1BERlNES19EYXRlVGltZSYgZGF0ZXRpbWUpCit7CisJQ1BERlNES19EYXRlVGltZSBkdDEgPSBUb0dNVCgpOworCUNQREZTREtfRGF0ZVRpbWUgZHQyID0gZGF0ZXRpbWUuVG9HTVQoKTsKKwlpbnQgZDEgPSAoKChpbnQpZHQxLmR0LnllYXIpIDw8IDE2KSB8ICgoKGludClkdDEuZHQubW9udGgpIDw8IDgpIHwgKGludClkdDEuZHQuZGF5OworCWludCBkMiA9ICgoKGludClkdDEuZHQuaG91cikgPDwgMTYpIHwgKCgoaW50KWR0MS5kdC5taW51dGUpIDw8IDgpIHwgKGludClkdDEuZHQuc2Vjb25kOworCWludCBkMyA9ICgoKGludClkdDIuZHQueWVhcikgPDwgMTYpIHwgKCgoaW50KWR0Mi5kdC5tb250aCkgPDwgOCkgfCAoaW50KWR0Mi5kdC5kYXk7CisJaW50IGQ0ID0gKCgoaW50KWR0Mi5kdC5ob3VyKSA8PCAxNikgfCAoKChpbnQpZHQyLmR0Lm1pbnV0ZSkgPDwgOCkgfCAoaW50KWR0Mi5kdC5zZWNvbmQ7CisKKwlpZiAoZDEgPiBkMykgcmV0dXJuIFRSVUU7CisJaWYgKGQyID4gZDQpIHJldHVybiBUUlVFOworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDUERGU0RLX0RhdGVUaW1lOjpvcGVyYXRvciA+PSAoQ1BERlNES19EYXRlVGltZSYgZGF0ZXRpbWUpCit7CisJQ1BERlNES19EYXRlVGltZSBkdDEgPSBUb0dNVCgpOworCUNQREZTREtfRGF0ZVRpbWUgZHQyID0gZGF0ZXRpbWUuVG9HTVQoKTsKKwlpbnQgZDEgPSAoKChpbnQpZHQxLmR0LnllYXIpIDw8IDE2KSB8ICgoKGludClkdDEuZHQubW9udGgpIDw8IDgpIHwgKGludClkdDEuZHQuZGF5OworCWludCBkMiA9ICgoKGludClkdDEuZHQuaG91cikgPDwgMTYpIHwgKCgoaW50KWR0MS5kdC5taW51dGUpIDw8IDgpIHwgKGludClkdDEuZHQuc2Vjb25kOworCWludCBkMyA9ICgoKGludClkdDIuZHQueWVhcikgPDwgMTYpIHwgKCgoaW50KWR0Mi5kdC5tb250aCkgPDwgOCkgfCAoaW50KWR0Mi5kdC5kYXk7CisJaW50IGQ0ID0gKCgoaW50KWR0Mi5kdC5ob3VyKSA8PCAxNikgfCAoKChpbnQpZHQyLmR0Lm1pbnV0ZSkgPDwgOCkgfCAoaW50KWR0Mi5kdC5zZWNvbmQ7CisKKwlpZiAoZDEgPj0gZDMpIHJldHVybiBUUlVFOworCWlmIChkMiA+PSBkNCkgcmV0dXJuIFRSVUU7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENQREZTREtfRGF0ZVRpbWU6Om9wZXJhdG9yIDwgKENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKQoreworCUNQREZTREtfRGF0ZVRpbWUgZHQxID0gVG9HTVQoKTsKKwlDUERGU0RLX0RhdGVUaW1lIGR0MiA9IGRhdGV0aW1lLlRvR01UKCk7CisJaW50IGQxID0gKCgoaW50KWR0MS5kdC55ZWFyKSA8PCAxNikgfCAoKChpbnQpZHQxLmR0Lm1vbnRoKSA8PCA4KSB8IChpbnQpZHQxLmR0LmRheTsKKwlpbnQgZDIgPSAoKChpbnQpZHQxLmR0LmhvdXIpIDw8IDE2KSB8ICgoKGludClkdDEuZHQubWludXRlKSA8PCA4KSB8IChpbnQpZHQxLmR0LnNlY29uZDsKKwlpbnQgZDMgPSAoKChpbnQpZHQyLmR0LnllYXIpIDw8IDE2KSB8ICgoKGludClkdDIuZHQubW9udGgpIDw8IDgpIHwgKGludClkdDIuZHQuZGF5OworCWludCBkNCA9ICgoKGludClkdDIuZHQuaG91cikgPDwgMTYpIHwgKCgoaW50KWR0Mi5kdC5taW51dGUpIDw8IDgpIHwgKGludClkdDIuZHQuc2Vjb25kOworCisJaWYgKGQxIDwgZDMpIHJldHVybiBUUlVFOworCWlmIChkMiA8IGQ0KSByZXR1cm4gVFJVRTsKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19EYXRlVGltZTo6b3BlcmF0b3IgPD0gKENQREZTREtfRGF0ZVRpbWUmIGRhdGV0aW1lKQoreworCUNQREZTREtfRGF0ZVRpbWUgZHQxID0gVG9HTVQoKTsKKwlDUERGU0RLX0RhdGVUaW1lIGR0MiA9IGRhdGV0aW1lLlRvR01UKCk7CisJaW50IGQxID0gKCgoaW50KWR0MS5kdC55ZWFyKSA8PCAxNikgfCAoKChpbnQpZHQxLmR0Lm1vbnRoKSA8PCA4KSB8IChpbnQpZHQxLmR0LmRheTsKKwlpbnQgZDIgPSAoKChpbnQpZHQxLmR0LmhvdXIpIDw8IDE2KSB8ICgoKGludClkdDEuZHQubWludXRlKSA8PCA4KSB8IChpbnQpZHQxLmR0LnNlY29uZDsKKwlpbnQgZDMgPSAoKChpbnQpZHQyLmR0LnllYXIpIDw8IDE2KSB8ICgoKGludClkdDIuZHQubW9udGgpIDw8IDgpIHwgKGludClkdDIuZHQuZGF5OworCWludCBkNCA9ICgoKGludClkdDIuZHQuaG91cikgPDwgMTYpIHwgKCgoaW50KWR0Mi5kdC5taW51dGUpIDw8IDgpIHwgKGludClkdDIuZHQuc2Vjb25kOworCisJaWYgKGQxIDw9IGQzKSByZXR1cm4gVFJVRTsKKwlpZiAoZDIgPD0gZDQpIHJldHVybiBUUlVFOworCXJldHVybiBGQUxTRTsKK30KKworQ1BERlNES19EYXRlVGltZTo6b3BlcmF0b3IgdGltZV90KCkKK3sKKwlzdHJ1Y3QgdG0gbmV3dGltZTsKKworCW5ld3RpbWUudG1feWVhciA9IGR0LnllYXIgLSAxOTAwOworCW5ld3RpbWUudG1fbW9uID0gZHQubW9udGggLSAxOworCW5ld3RpbWUudG1fbWRheSA9IGR0LmRheTsKKwluZXd0aW1lLnRtX2hvdXIgPSBkdC5ob3VyOworCW5ld3RpbWUudG1fbWluID0gZHQubWludXRlOworCW5ld3RpbWUudG1fc2VjID0gZHQuc2Vjb25kOworCisJcmV0dXJuIG1rdGltZSgmbmV3dGltZSk7Cit9CisKK0NQREZTREtfRGF0ZVRpbWUmIENQREZTREtfRGF0ZVRpbWU6OkZyb21QREZEYXRlVGltZVN0cmluZyhjb25zdCBDRlhfQnl0ZVN0cmluZyYgZHRTdHIpCit7CisJaW50IHN0ckxlbmd0aCA9IGR0U3RyLkdldExlbmd0aCgpOworCWlmIChzdHJMZW5ndGggPiAwKQorCXsKKwkJaW50IGkgPSAwOworCQlpbnQgaiwgazsKKwkJRlhfQ0hBUiBjaDsKKwkJd2hpbGUgKGkgPCBzdHJMZW5ndGgpCisJCXsKKwkJCWNoID0gZHRTdHJbaV07CisJCQlpZiAoY2ggPj0gJzAnICYmIGNoIDw9ICc5JykgYnJlYWs7CisJCQlpICsrOworCQl9CisJCWlmIChpID49IHN0ckxlbmd0aCkgcmV0dXJuICp0aGlzOworCisJCWogPSAwOworCQlrID0gMDsKKwkJd2hpbGUgKGkgPCBzdHJMZW5ndGggJiYgaiA8IDQpCisJCXsKKwkJCWNoID0gZHRTdHJbaV07CisJCQlrID0gayAqIDEwICsgY2ggLSAnMCc7CisJCQlqICsrOworCQkJaWYgKGNoIDwgJzAnIHx8IGNoID4gJzknKSBicmVhazsKKwkJCWkgKys7CisJCX0KKwkJZHQueWVhciA9IChGWF9TSE9SVClrOworCQlpZiAoaSA+PSBzdHJMZW5ndGggfHwgaiA8IDQpIHJldHVybiAqdGhpczsKKworCQlqID0gMDsKKwkJayA9IDA7CisJCXdoaWxlIChpIDwgc3RyTGVuZ3RoICYmIGogPCAyKQorCQl7CisJCQljaCA9IGR0U3RyW2ldOworCQkJayA9IGsgKiAxMCArIGNoIC0gJzAnOworCQkJaiArKzsKKwkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7CisJCQlpICsrOworCQl9CisJCWR0Lm1vbnRoID0gKEZYX0JZVEUpazsKKwkJaWYgKGkgPj0gc3RyTGVuZ3RoIHx8IGogPCAyKSByZXR1cm4gKnRoaXM7CisKKwkJaiA9IDA7CisJCWsgPSAwOworCQl3aGlsZSAoaSA8IHN0ckxlbmd0aCAmJiBqIDwgMikKKwkJeworCQkJY2ggPSBkdFN0cltpXTsKKwkJCWsgPSBrICogMTAgKyBjaCAtICcwJzsKKwkJCWogKys7CisJCQlpZiAoY2ggPCAnMCcgfHwgY2ggPiAnOScpIGJyZWFrOworCQkJaSArKzsKKwkJfQorCQlkdC5kYXkgPSAoRlhfQllURSlrOworCQlpZiAoaSA+PSBzdHJMZW5ndGggfHwgaiA8IDIpIHJldHVybiAqdGhpczsKKworCQlqID0gMDsKKwkJayA9IDA7CisJCXdoaWxlIChpIDwgc3RyTGVuZ3RoICYmIGogPCAyKQorCQl7CisJCQljaCA9IGR0U3RyW2ldOworCQkJayA9IGsgKiAxMCArIGNoIC0gJzAnOworCQkJaiArKzsKKwkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7CisJCQlpICsrOworCQl9CisJCWR0LmhvdXIgPSAoRlhfQllURSlrOworCQlpZiAoaSA+PSBzdHJMZW5ndGggfHwgaiA8IDIpIHJldHVybiAqdGhpczsKKworCQlqID0gMDsKKwkJayA9IDA7CisJCXdoaWxlIChpIDwgc3RyTGVuZ3RoICYmIGogPCAyKQorCQl7CisJCQljaCA9IGR0U3RyW2ldOworCQkJayA9IGsgKiAxMCArIGNoIC0gJzAnOworCQkJaiArKzsKKwkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7CisJCQlpICsrOworCQl9CisJCWR0Lm1pbnV0ZSA9IChGWF9CWVRFKWs7CisJCWlmIChpID49IHN0ckxlbmd0aCB8fCBqIDwgMikgcmV0dXJuICp0aGlzOworCisJCWogPSAwOworCQlrID0gMDsKKwkJd2hpbGUgKGkgPCBzdHJMZW5ndGggJiYgaiA8IDIpCisJCXsKKwkJCWNoID0gZHRTdHJbaV07CisJCQlrID0gayAqIDEwICsgY2ggLSAnMCc7CisJCQlqICsrOworCQkJaWYgKGNoIDwgJzAnIHx8IGNoID4gJzknKSBicmVhazsKKwkJCWkgKys7CisJCX0KKwkJZHQuc2Vjb25kID0gKEZYX0JZVEUpazsKKwkJaWYgKGkgPj0gc3RyTGVuZ3RoIHx8IGogPCAyKSByZXR1cm4gKnRoaXM7CisKKwkJY2ggPSBkdFN0cltpICsrXTsKKwkJaWYgKGNoICE9ICctJyAmJiBjaCAhPSAnKycpIHJldHVybiAqdGhpczsKKwkJaWYgKGNoID09ICctJykKKwkJCWR0LnR6SG91ciA9IC0xOworCQllbHNlCisJCQlkdC50ekhvdXIgPSAxOworCQlqID0gMDsKKwkJayA9IDA7CisJCXdoaWxlIChpIDwgc3RyTGVuZ3RoICYmIGogPCAyKQorCQl7CisJCQljaCA9IGR0U3RyW2ldOworCQkJayA9IGsgKiAxMCArIGNoIC0gJzAnOworCQkJaiArKzsKKwkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7CisJCQlpICsrOworCQl9CisJCWR0LnR6SG91ciAqPSAoRlhfQ0hBUilrOworCQlpZiAoaSA+PSBzdHJMZW5ndGggfHwgaiA8IDIpIHJldHVybiAqdGhpczsKKworCQljaCA9IGR0U3RyW2kgKytdOworCQlpZiAoY2ggIT0gJ1wnJykgcmV0dXJuICp0aGlzOworCQlqID0gMDsKKwkJayA9IDA7CisJCXdoaWxlIChpIDwgc3RyTGVuZ3RoICYmIGogPCAyKQorCQl7CisJCQljaCA9IGR0U3RyW2ldOworCQkJayA9IGsgKiAxMCArIGNoIC0gJzAnOworCQkJaiArKzsKKwkJCWlmIChjaCA8ICcwJyB8fCBjaCA+ICc5JykgYnJlYWs7CisJCQlpICsrOworCQl9CisJCWR0LnR6TWludXRlID0gKEZYX0JZVEUpazsKKwkJaWYgKGkgPj0gc3RyTGVuZ3RoIHx8IGogPCAyKSByZXR1cm4gKnRoaXM7CisJfQorCisJcmV0dXJuICAqdGhpczsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BERlNES19EYXRlVGltZTo6VG9Db21tb25EYXRlVGltZVN0cmluZygpCit7CisJQ0ZYX0J5dGVTdHJpbmcgc3RyMTsKKwlzdHIxLkZvcm1hdCgiJTA0ZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQgIiwgZHQueWVhciwgZHQubW9udGgsIGR0LmRheSwgZHQuaG91ciwgZHQubWludXRlLCBkdC5zZWNvbmQpOworCWlmIChkdC50ekhvdXIgPCAwKQorCQlzdHIxICs9ICItIjsKKwllbHNlCisJCXN0cjEgKz0gIisiOworCUNGWF9CeXRlU3RyaW5nIHN0cjI7CisJc3RyMi5Gb3JtYXQoIiUwMmQ6JTAyZCIsIGFicyhkdC50ekhvdXIpLCBkdC50ek1pbnV0ZSk7CisJcmV0dXJuIHN0cjEgKyBzdHIyOworfQorCitDRlhfQnl0ZVN0cmluZyBDUERGU0RLX0RhdGVUaW1lOjpUb1BERkRhdGVUaW1lU3RyaW5nKCkKK3sKKwlDRlhfQnl0ZVN0cmluZyBkdFN0cjsKKwljaGFyIHRlbXBTdHJbMzJdOworCXNwcmludGYodGVtcFN0ciwgIkQ6JTA0ZCUwMmQlMDJkJTAyZCUwMmQlMDJkIiwgZHQueWVhciwgZHQubW9udGgsIGR0LmRheSwgZHQuaG91ciwgZHQubWludXRlLCBkdC5zZWNvbmQpOworCWR0U3RyID0gQ0ZYX0J5dGVTdHJpbmcodGVtcFN0cik7CisJaWYgKGR0LnR6SG91ciA8IDApCisJCWR0U3RyICs9IENGWF9CeXRlU3RyaW5nKCItIik7CisJZWxzZQorCQlkdFN0ciArPSBDRlhfQnl0ZVN0cmluZygiKyIpOworCXNwcmludGYodGVtcFN0ciwgIiUwMmQnJTAyZCciLCBhYnMoZHQudHpIb3VyKSwgZHQudHpNaW51dGUpOworCWR0U3RyICs9IENGWF9CeXRlU3RyaW5nKHRlbXBTdHIpOworCXJldHVybiBkdFN0cjsKK30KKwordm9pZCBDUERGU0RLX0RhdGVUaW1lOjpUb1N5c3RlbVRpbWUoRlhfU1lTVEVNVElNRSYgc3QpCit7CisJQ1BERlNES19EYXRlVGltZSBkdCA9ICp0aGlzOworCXRpbWVfdCB0ID0gKHRpbWVfdClkdDsKKwlzdHJ1Y3QgdG0qIHBUaW1lID0gbG9jYWx0aW1lKCZ0KTsKKwlpZihwVGltZSl7IAorCQlzdC53WWVhciA9IChGWF9XT1JEKXBUaW1lLT50bV95ZWFyICsgMTkwMDsKKwkJc3Qud01vbnRoID0gKEZYX1dPUkQpcFRpbWUtPnRtX21vbiArIDE7CisJCXN0LndEYXkgPSAoRlhfV09SRClwVGltZS0+dG1fbWRheTsKKwkJc3Qud0RheU9mV2VlayA9IChGWF9XT1JEKXBUaW1lLT50bV93ZGF5OworCQlzdC53SG91ciA9IChGWF9XT1JEKXBUaW1lLT50bV9ob3VyOworCQlzdC53TWludXRlID0gKEZYX1dPUkQpcFRpbWUtPnRtX21pbjsKKwkJc3Qud1NlY29uZCA9IChGWF9XT1JEKXBUaW1lLT50bV9zZWM7CisJCXN0LndNaWxsaXNlY29uZHMgPSAwOworCX0KK30KKworQ1BERlNES19EYXRlVGltZSBDUERGU0RLX0RhdGVUaW1lOjpUb0dNVCgpCit7CisJQ1BERlNES19EYXRlVGltZSBkdCA9ICp0aGlzOworCWR0LkFkZFNlY29uZHMoLV9nQWZ4R2V0VGltZVpvbmVJblNlY29uZHMoZHQuZHQudHpIb3VyLCBkdC5kdC50ek1pbnV0ZSkpOworCWR0LmR0LnR6SG91ciA9IDA7CisJZHQuZHQudHpNaW51dGUgPSAwOworCXJldHVybiBkdDsKK30KKworQ1BERlNES19EYXRlVGltZSYgQ1BERlNES19EYXRlVGltZTo6QWRkRGF5cyhzaG9ydCBkYXlzKQoreworCWlmIChkYXlzID09IDApIHJldHVybiAqdGhpczsKKworCUZYX1NIT1JUCXkgPSBkdC55ZWFyLCB5eTsKKwlGWF9CWVRFCQltID0gZHQubW9udGg7CisJRlhfQllURQkJZCA9IGR0LmRheTsKKwlpbnQJCQltZGF5cywgeWRheXMsIGxkYXlzOworCisJbGRheXMgPSBkYXlzOworCWlmIChsZGF5cyA+IDApCisJeworCQl5eSA9IHk7CisJCWlmICgoKEZYX1dPUkQpbSAqIDEwMCArIGQpID4gMzAwKSB5eSArKzsKKwkJeWRheXMgPSBfZ0FmeEdldFllYXJEYXlzKHl5KTsKKwkJd2hpbGUgKGxkYXlzID49IHlkYXlzKQorCQl7CisJCQl5ICsrOworCQkJbGRheXMgLT0geWRheXM7CisJCQl5eSArKzsKKwkJCW1kYXlzID0gX2dBZnhHZXRNb250aERheXMoeSwgbSk7CisJCQlpZiAoZCA+IG1kYXlzKQorCQkJeworCQkJCW0gKys7CisJCQkJZCAtPSBtZGF5czsKKwkJCX0KKwkJCXlkYXlzID0gX2dBZnhHZXRZZWFyRGF5cyh5eSk7CisJCX0KKwkJbWRheXMgPSBfZ0FmeEdldE1vbnRoRGF5cyh5LCBtKSAtIGQgKyAxOworCQl3aGlsZSAobGRheXMgPj0gbWRheXMpCisJCXsKKwkJCWxkYXlzIC09IG1kYXlzOworCQkJbSArKzsKKwkJCWQgPSAxOworCQkJbWRheXMgPSBfZ0FmeEdldE1vbnRoRGF5cyh5LCBtKTsKKwkJfQorCQlkICs9IGxkYXlzOworCX0KKwllbHNlCisJeworCQlsZGF5cyAqPSAtMTsKKwkJeXkgPSB5OworCQlpZiAoKChGWF9XT1JEKW0gKiAxMDAgKyBkKSA8IDMwMCkgeXkgLS07CisJCXlkYXlzID0gX2dBZnhHZXRZZWFyRGF5cyh5eSk7CisJCXdoaWxlIChsZGF5cyA+PSB5ZGF5cykKKwkJeworCQkJeSAtLTsKKwkJCWxkYXlzIC09IHlkYXlzOworCQkJeXkgLS07CisJCQltZGF5cyA9IF9nQWZ4R2V0TW9udGhEYXlzKHksIG0pOworCQkJaWYgKGQgPiBtZGF5cykKKwkJCXsKKwkJCQltICsrOworCQkJCWQgLT0gbWRheXM7CisJCQl9CisJCQl5ZGF5cyA9IF9nQWZ4R2V0WWVhckRheXMoeXkpOworCQl9CisJCXdoaWxlIChsZGF5cyA+PSBkKQorCQl7CisJCQlsZGF5cyAtPSBkOworCQkJbSAtLTsKKwkJCW1kYXlzID0gX2dBZnhHZXRNb250aERheXMoeSwgbSk7CisJCQlkID0gbWRheXM7CisJCX0KKwkJZCAtPSBsZGF5czsKKwl9CisKKwlkdC55ZWFyID0geTsKKwlkdC5tb250aCA9IG07CisJZHQuZGF5ID0gZDsKKworCXJldHVybiAqdGhpczsKK30KKworQ1BERlNES19EYXRlVGltZSYgQ1BERlNES19EYXRlVGltZTo6QWRkU2Vjb25kcyhpbnQgc2Vjb25kcykKK3sKKwlpZiAoc2Vjb25kcyA9PSAwKSByZXR1cm4gKnRoaXM7CisKKwlpbnQJbjsKKwlpbnQJZGF5czsKKworCW4gPSBkdC5ob3VyICogMzYwMCArIGR0Lm1pbnV0ZSAqIDYwICsgZHQuc2Vjb25kICsgc2Vjb25kczsKKwlpZiAobiA8IDApCisJeworCQlkYXlzID0gKG4gLSA4NjM5OSkgLyA4NjQwMDsKKwkJbiAtPSBkYXlzICogODY0MDA7CisJfQorCWVsc2UKKwl7CisJCWRheXMgPSBuIC8gODY0MDA7CisJCW4gJT0gODY0MDA7CisJfQorCWR0LmhvdXIgPSAoRlhfQllURSkobiAvIDM2MDApOworCWR0LmhvdXIgJT0gMjQ7CisJbiAlPSAzNjAwOworCWR0Lm1pbnV0ZSA9IChGWF9CWVRFKShuIC8gNjApOworCWR0LnNlY29uZCA9IChGWF9CWVRFKShuICUgNjApOworCWlmIChkYXlzICE9IDApIEFkZERheXMoZGF5cyk7CisKKwlyZXR1cm4gKnRoaXM7Cit9CisKKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCQkJCQkJCQlDUERGU0RLX0Fubm90CQorLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK0NQREZTREtfQW5ub3Q6OkNQREZTREtfQW5ub3QoQ1BERl9Bbm5vdCogcEFubm90LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpIDoKK21fcEFubm90KHBBbm5vdCksCittX3BQYWdlVmlldyhwUGFnZVZpZXcpLAorbV9iU2VsZWN0ZWQoRkFMU0UpLAorbV9uVGFiT3JkZXIoLTEpCit7Cit9CisKK0NQREZTREtfQW5ub3Q6On5DUERGU0RLX0Fubm90KCkKK3sKKwltX3BBbm5vdCA9IE5VTEw7CisJbV9wUGFnZVZpZXcgPSBOVUxMOworfQorCitDUERGX0Fubm90KglDUERGU0RLX0Fubm90OjpHZXRQREZBbm5vdCgpCit7CisJcmV0dXJuIG1fcEFubm90OworfQorCitGWF9EV09SRCBDUERGU0RLX0Fubm90OjpHZXRGbGFncygpCit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCQorCXJldHVybiBtX3BBbm5vdC0+R2V0RmxhZ3MoKTsKK30KKwordm9pZCBDUERGU0RLX0Fubm90OjpTZXRQYWdlKENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykKK3sKKwltX3BQYWdlVmlldyA9IHBQYWdlVmlldzsKK30KKworQ1BERlNES19QYWdlVmlldyogQ1BERlNES19Bbm5vdDo6R2V0UGFnZVZpZXcoKQoreworCXJldHVybiBtX3BQYWdlVmlldzsKK30KKworRlhfQk9PTCBDUERGU0RLX0Fubm90OjpJc1NlbGVjdGVkKCkKK3sKKwlyZXR1cm4gbV9iU2VsZWN0ZWQ7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6U2V0U2VsZWN0ZWQoRlhfQk9PTCBiU2VsZWN0ZWQpCit7CisJbV9iU2VsZWN0ZWQgPSBiU2VsZWN0ZWQ7Cit9CisKKy8vIFRhYiBPcmRlcgkKK2ludCBDUERGU0RLX0Fubm90OjpHZXRUYWJPcmRlcigpCit7CisJcmV0dXJuIG1fblRhYk9yZGVyOworfQorCit2b2lkIENQREZTREtfQW5ub3Q6OlNldFRhYk9yZGVyKGludCBpVGFiT3JkZXIpCit7CisJbV9uVGFiT3JkZXIgPSBpVGFiT3JkZXI7Cit9CisKK0NQREZfRGljdGlvbmFyeSogQ1BERlNES19Bbm5vdDo6R2V0QW5ub3REaWN0KCkgY29uc3QKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJCisJcmV0dXJuIG1fcEFubm90LT5tX3BBbm5vdERpY3Q7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6U2V0UmVjdChjb25zdCBDUERGX1JlY3QmIHJlY3QpCit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCUFTU0VSVChyZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0ID49IEdldE1pbldpZHRoKCkpOworCUFTU0VSVChyZWN0LnRvcCAtIHJlY3QuYm90dG9tID49IEdldE1pbkhlaWdodCgpKTsKKwkKKwltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdFJlY3QoIlJlY3QiLCByZWN0KTsKK30KKworQ1BERl9SZWN0IENQREZTREtfQW5ub3Q6OkdldFJlY3QoKSBjb25zdAoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwkKKwlDUERGX1JlY3QgcmVjdDsKKwltX3BBbm5vdC0+R2V0UmVjdChyZWN0KTsKKwkKKwlyZXR1cm4gcmVjdDsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BERlNES19Bbm5vdDo6R2V0VHlwZSgpIGNvbnN0Cit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCQorCXJldHVybiBtX3BBbm5vdC0+R2V0U3ViVHlwZSgpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUERGU0RLX0Fubm90OjpHZXRTdWJUeXBlKCkgY29uc3QKK3sKKwlyZXR1cm4gIiI7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6UmVzZXRBcHBlYXJhbmNlKCkKK3sKKwlBU1NFUlQoRkFMU0UpOworfQorCit2b2lkIENQREZTREtfQW5ub3Q6OkRyYXdBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIGNvbnN0IENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCQkJCSAgIENQREZfQW5ub3Q6OkFwcGVhcmFuY2VNb2RlIG1vZGUsIGNvbnN0IENQREZfUmVuZGVyT3B0aW9ucyogcE9wdGlvbnMpCQoreworCUFTU0VSVChtX3BQYWdlVmlldyAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJCisJbV9wQW5ub3QtPkRyYXdBcHBlYXJhbmNlKG1fcFBhZ2VWaWV3LT5HZXRQREZQYWdlKCksIHBEZXZpY2UsIHBVc2VyMkRldmljZSwgbW9kZSwgcE9wdGlvbnMpOworfQorCitGWF9CT09MCUNQREZTREtfQW5ub3Q6OklzQXBwZWFyYW5jZVZhbGlkKCkKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisJCisJcmV0dXJuIG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkFQIikgIT0gTlVMTDsKK30KKworRlhfQk9PTAlDUERGU0RLX0Fubm90OjpJc0FwcGVhcmFuY2VWYWxpZChDUERGX0Fubm90OjpBcHBlYXJhbmNlTW9kZSBtb2RlKQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlDUERGX0RpY3Rpb25hcnkqIHBBUCA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkFQIik7CisJaWYgKHBBUCA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CisJCisJLy8gQ2hvb3NlIHRoZSByaWdodCBzdWItYXAKKwljb25zdCBGWF9DSEFSKiBhcF9lbnRyeSA9ICJOIjsKKwlpZiAobW9kZSA9PSBDUERGX0Fubm90OjpEb3duKQorCQlhcF9lbnRyeSA9ICJEIjsKKwllbHNlIGlmIChtb2RlID09IENQREZfQW5ub3Q6OlJvbGxvdmVyKQorCQlhcF9lbnRyeSA9ICJSIjsKKwlpZiAoIXBBUC0+S2V5RXhpc3QoYXBfZW50cnkpKQorCQlhcF9lbnRyeSA9ICJOIjsKKwkKKwkvLyBHZXQgdGhlIEFQIHN0cmVhbSBvciBzdWJkaXJlY3RvcnkKKwlDUERGX09iamVjdCogcHN1YiA9IHBBUC0+R2V0RWxlbWVudFZhbHVlKGFwX2VudHJ5KTsKKwlpZiAocHN1YiA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CisJCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6RHJhd0JvcmRlcihDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBjb25zdCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQkJCQkJICAgY29uc3QgQ1BERl9SZW5kZXJPcHRpb25zKiBwT3B0aW9ucykKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJbV9wQW5ub3QtPkRyYXdCb3JkZXIocERldmljZSwgcFVzZXIyRGV2aWNlLCBwT3B0aW9ucyk7IAorfQorCit2b2lkIENQREZTREtfQW5ub3Q6OkNsZWFyQ2FjaGVkQVAoKQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwltX3BBbm5vdC0+Q2xlYXJDYWNoZWRBUCgpOworfSAgICAKKwordm9pZCBDUERGU0RLX0Fubm90OjpTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlpZiAoc0NvbnRlbnRzLklzRW1wdHkoKSkKKwkJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+UmVtb3ZlQXQoIkNvbnRlbnRzIik7CisJZWxzZQorCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdFN0cmluZygiQ29udGVudHMiLCBQREZfRW5jb2RlVGV4dChzQ29udGVudHMpKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BERlNES19Bbm5vdDo6R2V0Q29udGVudHMoKSBjb25zdAoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0VW5pY29kZVRleHQoIkNvbnRlbnRzIik7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6U2V0QW5ub3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisJCisJaWYgKHNOYW1lLklzRW1wdHkoKSkKKwkJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+UmVtb3ZlQXQoIk5NIik7CisJZWxzZQorCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdFN0cmluZygiTk0iLCBQREZfRW5jb2RlVGV4dChzTmFtZSkpOworfQorCitDRlhfV2lkZVN0cmluZyBDUERGU0RLX0Fubm90OjpHZXRBbm5vdE5hbWUoKSBjb25zdAoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0VW5pY29kZVRleHQoIk5NIik7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6U2V0TW9kaWZpZWREYXRlKGNvbnN0IEZYX1NZU1RFTVRJTUUmIHN0KQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlDUERGU0RLX0RhdGVUaW1lIGR0KHN0KTsKKwlDRlhfQnl0ZVN0cmluZyBzdHIgPSBkdC5Ub1BERkRhdGVUaW1lU3RyaW5nKCk7CisJCisJaWYgKHN0ci5Jc0VtcHR5KCkpCisJCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlJlbW92ZUF0KCJNIik7CisJZWxzZQorCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdFN0cmluZygiTSIsIHN0cik7Cit9CisKK0ZYX1NZU1RFTVRJTUUgQ1BERlNES19Bbm5vdDo6R2V0TW9kaWZpZWREYXRlKCkgY29uc3QKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisJCisJRlhfU1lTVEVNVElNRSBzeXN0aW1lOwkKKwlDRlhfQnl0ZVN0cmluZyBzdHIgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXRTdHJpbmcoIk0iKTsKKwkKKyAJQ1BERlNES19EYXRlVGltZSBkdChzdHIpOworIAlkdC5Ub1N5c3RlbVRpbWUoc3lzdGltZSk7CisJCisJcmV0dXJuIHN5c3RpbWU7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6U2V0RmxhZ3MoaW50IG5GbGFncykKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisJCisJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXRJbnRlZ2VyKCJGIiwgbkZsYWdzKTsKK30KKworaW50IENQREZTREtfQW5ub3Q6OkdldEZsYWdzKCkgY29uc3QKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisJCisJcmV0dXJuIG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldEludGVnZXIoIkYiKTsKK30KKwordm9pZCBDUERGU0RLX0Fubm90OjpTZXRBcHBTdGF0ZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyKQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKworCWlmIChzdHIuSXNFbXB0eSgpKQorCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5SZW1vdmVBdCgiQVMiKTsKKwllbHNlCisJCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0U3RyaW5nKCJBUyIsIHN0cik7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQREZTREtfQW5ub3Q6OkdldEFwcFN0YXRlKCkgY29uc3QKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisKKwlyZXR1cm4gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0U3RyaW5nKCJBUyIpOworfQorCit2b2lkIENQREZTREtfQW5ub3Q6OlNldFN0cnVjdFBhcmVudChpbnQga2V5KQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdEludGVnZXIoIlN0cnVjdFBhcmVudCIsIGtleSk7Cit9CisKK2ludAlDUERGU0RLX0Fubm90OjpHZXRTdHJ1Y3RQYXJlbnQoKSBjb25zdAoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0SW50ZWdlcigiU3RydWN0UGFyZW50Iik7Cit9CisKKy8vYm9yZGVyCit2b2lkIENQREZTREtfQW5ub3Q6OlNldEJvcmRlcldpZHRoKGludCBuV2lkdGgpCit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCisJQ1BERl9BcnJheSogcEJvcmRlciA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldEFycmF5KCJCb3JkZXIiKTsKKworCWlmIChwQm9yZGVyKQorCXsKKwkJcEJvcmRlci0+U2V0QXQoMiwgRlhfTkVXIENQREZfTnVtYmVyKG5XaWR0aCkpOworCX0KKwllbHNlCisJeworCQlDUERGX0RpY3Rpb25hcnkqIHBCU0RpY3QgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJCUyIpOworCisJCWlmICghcEJTRGljdCkKKwkJeworCQkJcEJTRGljdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7CisJCQltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5TZXRBdCgiQlMiLCBwQlNEaWN0KTsKKwkJfQorCisJCXBCU0RpY3QtPlNldEF0SW50ZWdlcigiVyIsIG5XaWR0aCk7CisJfQorfQorCitpbnQJQ1BERlNES19Bbm5vdDo6R2V0Qm9yZGVyV2lkdGgoKSBjb25zdAoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKworCUNQREZfQXJyYXkqIHBCb3JkZXIgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXRBcnJheSgiQm9yZGVyIik7CisKKwlpZiAocEJvcmRlcikKKwl7CisJCXJldHVybiBwQm9yZGVyLT5HZXRJbnRlZ2VyKDIpOworCX0KKwllbHNlCisJeworCQlDUERGX0RpY3Rpb25hcnkqIHBCU0RpY3QgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJCUyIpOworCisJCWlmIChwQlNEaWN0KQorCQl7CisJCQlyZXR1cm4gcEJTRGljdC0+R2V0SW50ZWdlcigiVyIsIDEpOworCQl9CisJfQorCXJldHVybiAxOworfQorCit2b2lkIENQREZTREtfQW5ub3Q6OlNldEJvcmRlclN0eWxlKGludCBuU3R5bGUpCit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwQlNEaWN0ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQlMiKTsKKwlpZiAoIXBCU0RpY3QpCisJeworCQlwQlNEaWN0ID0gRlhfTkVXIENQREZfRGljdGlvbmFyeTsKKwkJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXQoIkJTIiwgcEJTRGljdCk7CisJfQorCisJc3dpdGNoIChuU3R5bGUpCisJeworCWNhc2UgQkJTX1NPTElEOgorCQlwQlNEaWN0LT5TZXRBdE5hbWUoIlMiLCAiUyIpOworCQlicmVhazsKKwljYXNlIEJCU19EQVNIOgorCQlwQlNEaWN0LT5TZXRBdE5hbWUoIlMiLCAiRCIpOworCQlicmVhazsKKwljYXNlIEJCU19CRVZFTEVEOgorCQlwQlNEaWN0LT5TZXRBdE5hbWUoIlMiLCAiQiIpOworCQlicmVhazsKKwljYXNlIEJCU19JTlNFVDoKKwkJcEJTRGljdC0+U2V0QXROYW1lKCJTIiwgIkkiKTsKKwkJYnJlYWs7CisJY2FzZSBCQlNfVU5ERVJMSU5FOgorCQlwQlNEaWN0LT5TZXRBdE5hbWUoIlMiLCAiVSIpOworCQlicmVhazsKKwl9Cit9CisKK2ludAlDUERGU0RLX0Fubm90OjpHZXRCb3JkZXJTdHlsZSgpIGNvbnN0Cit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwQlNEaWN0ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQlMiKTsKKwlpZiAocEJTRGljdCkKKwl7CisJCUNGWF9CeXRlU3RyaW5nIHNCb3JkZXJTdHlsZSA9IHBCU0RpY3QtPkdldFN0cmluZygiUyIsICJTIik7CisJCWlmIChzQm9yZGVyU3R5bGUgPT0gIlMiKSByZXR1cm4gQkJTX1NPTElEOworCQlpZiAoc0JvcmRlclN0eWxlID09ICJEIikgcmV0dXJuIEJCU19EQVNIOworCQlpZiAoc0JvcmRlclN0eWxlID09ICJCIikgcmV0dXJuIEJCU19CRVZFTEVEOworCQlpZiAoc0JvcmRlclN0eWxlID09ICJJIikgcmV0dXJuIEJCU19JTlNFVDsKKwkJaWYgKHNCb3JkZXJTdHlsZSA9PSAiVSIpIHJldHVybiBCQlNfVU5ERVJMSU5FOworCX0KKworCUNQREZfQXJyYXkqIHBCb3JkZXIgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXRBcnJheSgiQm9yZGVyIik7CisJaWYgKHBCb3JkZXIpCisJeworCQlpZiAocEJvcmRlci0+R2V0Q291bnQoKSA+PSA0KSAKKwkJeyAKKwkJCUNQREZfQXJyYXkgKnBEUCA9IHBCb3JkZXItPkdldEFycmF5KDMpOworCQkJaWYgKHBEUCAmJiBwRFAtPkdldENvdW50KCkgPiAwKQorCQkJCXJldHVybiBCQlNfREFTSDsKKwkJfQorCX0KKworCXJldHVybiBCQlNfU09MSUQ7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6U2V0Qm9yZGVyRGFzaChjb25zdCBDRlhfSW50QXJyYXkmIGFycmF5KQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKworCUNQREZfRGljdGlvbmFyeSogcEJTRGljdCA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkJTIik7CisJaWYgKCFwQlNEaWN0KQorCXsKKwkJcEJTRGljdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7CisJCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0KCJCUyIsIHBCU0RpY3QpOworCX0KKworCUNQREZfQXJyYXkqIHBBcnJheSA9IEZYX05FVyBDUERGX0FycmF5OworCWZvciAoaW50IGk9MCxzej1hcnJheS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCXBBcnJheS0+QWRkSW50ZWdlcihhcnJheVtpXSk7CisJfQorCisJcEJTRGljdC0+U2V0QXQoIkQiLCBwQXJyYXkpOworfQorCit2b2lkIENQREZTREtfQW5ub3Q6OkdldEJvcmRlckRhc2goQ0ZYX0ludEFycmF5JiBhcnJheSkgY29uc3QKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisKKwlDUERGX0FycmF5KiBwRGFzaCA9IE5VTEw7CisKKwlDUERGX0FycmF5KiBwQm9yZGVyID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0QXJyYXkoIkJvcmRlciIpOworCWlmIChwQm9yZGVyKQorCXsKKwkJcERhc2ggPSBwQm9yZGVyLT5HZXRBcnJheSgzKTsKKwl9CisJZWxzZQorCXsKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwQlNEaWN0ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQlMiKTsKKwkJaWYgKHBCU0RpY3QpCisJCXsKKwkJCXBEYXNoID0gcEJTRGljdC0+R2V0QXJyYXkoIkQiKTsKKwkJfQorCX0KKworCWlmIChwRGFzaCkKKwl7CisJCWZvciAoaW50IGk9MCxzej1wRGFzaC0+R2V0Q291bnQoKTsgaTxzejsgaSsrKQorCQl7CisJCQlhcnJheS5BZGQocERhc2gtPkdldEludGVnZXIoaSkpOworCQl9CisJfQorfQorCit2b2lkIENQREZTREtfQW5ub3Q6OlNldENvbG9yKEZYX0NPTE9SUkVGIGNvbG9yKQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKworCUNQREZfQXJyYXkqIHBBcnJheSA9IEZYX05FVyBDUERGX0FycmF5OworCXBBcnJheS0+QWRkTnVtYmVyKChGWF9GTE9BVClGWFNZU19HZXRSVmFsdWUoY29sb3IpIC8gMjU1LjBmKTsKKwlwQXJyYXktPkFkZE51bWJlcigoRlhfRkxPQVQpRlhTWVNfR2V0R1ZhbHVlKGNvbG9yKSAvIDI1NS4wZik7CisJcEFycmF5LT5BZGROdW1iZXIoKEZYX0ZMT0FUKUZYU1lTX0dldEJWYWx1ZShjb2xvcikgLyAyNTUuMGYpOworCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0KCJDIiwgcEFycmF5KTsKK30KKwordm9pZCBDUERGU0RLX0Fubm90OjpSZW1vdmVDb2xvcigpCit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCisJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+UmVtb3ZlQXQoIkMiKSA7IAorfQorCitGWF9CT09MIENQREZTREtfQW5ub3Q6OkdldENvbG9yKEZYX0NPTE9SUkVGJiBjb2xvcikgY29uc3QKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisKKwlpZiAoQ1BERl9BcnJheSogcEVudHJ5ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0QXJyYXkoIkMiKSkJCQorCXsKKwkJaW50IG5Db3VudCA9IHBFbnRyeS0+R2V0Q291bnQoKTsKKwkJaWYgKG5Db3VudCA9PSAxKQorCQl7CisJCQlGWF9GTE9BVCBnID0gcEVudHJ5LT5HZXROdW1iZXIoMCkgKiAyNTU7CisKKwkJCWNvbG9yID0gRlhTWVNfUkdCKChpbnQpZywgKGludClnLCAoaW50KWcpOworCisJCQlyZXR1cm4gVFJVRTsKKwkJfQorCQllbHNlIGlmIChuQ291bnQgPT0gMykKKwkJeworCQkJRlhfRkxPQVQgciA9IHBFbnRyeS0+R2V0TnVtYmVyKDApICogMjU1OworCQkJRlhfRkxPQVQgZyA9IHBFbnRyeS0+R2V0TnVtYmVyKDEpICogMjU1OworCQkJRlhfRkxPQVQgYiA9IHBFbnRyeS0+R2V0TnVtYmVyKDIpICogMjU1OworCisJCQljb2xvciA9IEZYU1lTX1JHQigoaW50KXIsIChpbnQpZywgKGludCliKTsKKworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwkJZWxzZSBpZiAobkNvdW50ID09IDQpCisJCXsKKwkJCUZYX0ZMT0FUIGMgPSBwRW50cnktPkdldE51bWJlcigwKTsKKwkJCUZYX0ZMT0FUIG0gPSBwRW50cnktPkdldE51bWJlcigxKTsKKwkJCUZYX0ZMT0FUIHkgPSBwRW50cnktPkdldE51bWJlcigyKTsKKwkJCUZYX0ZMT0FUIGsgPSBwRW50cnktPkdldE51bWJlcigzKTsKKworCQkJRlhfRkxPQVQgciA9IDEuMGYgLSBGWF9NSU4oMS4wZiwgYyArIGspOworCQkJRlhfRkxPQVQgZyA9IDEuMGYgLSBGWF9NSU4oMS4wZiwgbSArIGspOworCQkJRlhfRkxPQVQgYiA9IDEuMGYgLSBGWF9NSU4oMS4wZiwgeSArIGspOworCisJCQljb2xvciA9IEZYU1lTX1JHQigoaW50KShyICogMjU1KSwgKGludCkoZyAqIDI1NSksIChpbnQpKGIgKiAyNTUpKTsKKworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKKwordm9pZCBDUERGU0RLX0Fubm90OjpXcml0ZUFwcGVhcmFuY2UoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFR5cGUsIGNvbnN0IENQREZfUmVjdCYgcmNCQm94LCAKKwkJCQkJCQkJY29uc3QgQ1BERl9NYXRyaXgmIG1hdHJpeCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNDb250ZW50cywKKwkJCQkJCQkJY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFN0YXRlKQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlDUERGX0RpY3Rpb25hcnkqIHBBUERpY3QgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJBUCIpOworCQorCWlmICghcEFQRGljdCkgCisJeworCQlwQVBEaWN0ID0gRlhfTkVXIENQREZfRGljdGlvbmFyeTsKKwkJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXQoIkFQIiwgcEFQRGljdCk7CisJfQorCQorCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gTlVMTDsKKwlDUERGX0RpY3Rpb25hcnkqIHBQYXJlbnREaWN0ID0gTlVMTDsKKwkKKwlpZiAoc0FQU3RhdGUuSXNFbXB0eSgpKQorCXsKKwkJcFBhcmVudERpY3QgPSBwQVBEaWN0OworCQlwU3RyZWFtID0gcEFQRGljdC0+R2V0U3RyZWFtKHNBUFR5cGUpOworCX0KKwllbHNlCisJeworCQlDUERGX0RpY3Rpb25hcnkqIHBBUFR5cGVEaWN0ID0gcEFQRGljdC0+R2V0RGljdChzQVBUeXBlKTsKKwkJaWYgKCFwQVBUeXBlRGljdCkKKwkJeworCQkJcEFQVHlwZURpY3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5OworCQkJcEFQRGljdC0+U2V0QXQoc0FQVHlwZSwgcEFQVHlwZURpY3QpOworCQl9CisJCQorCQlwUGFyZW50RGljdCA9IHBBUFR5cGVEaWN0OworCQlwU3RyZWFtID0gcEFQVHlwZURpY3QtPkdldFN0cmVhbShzQVBTdGF0ZSk7CisJfQorCQorCWlmICghcFN0cmVhbSkgCisJeworCQlBU1NFUlQobV9wUGFnZVZpZXcgIT0gTlVMTCk7CisJCUNQREZfRG9jdW1lbnQqIHBEb2MgPSBtX3BQYWdlVmlldy0+R2V0UERGRG9jdW1lbnQoKTsKKwkJQVNTRVJUKHBEb2MgIT0gTlVMTCk7CisJCQorCQlwU3RyZWFtID0gRlhfTkVXIENQREZfU3RyZWFtKE5VTEwsIDAsIE5VTEwpOworCQlGWF9JTlQzMiBvYmpudW0gPSBwRG9jLT5BZGRJbmRpcmVjdE9iamVjdChwU3RyZWFtKTsKKwkJLy9wQVBEaWN0LT5TZXRBdFJlZmVyZW5jZShzQVBUeXBlLCBwRG9jLCBvYmpudW0pOworCQlBU1NFUlQocFBhcmVudERpY3QgIT0gTlVMTCk7CisJCXBQYXJlbnREaWN0LT5TZXRBdFJlZmVyZW5jZShzQVBUeXBlLCBwRG9jLCBvYmpudW0pOworCX0KKwkKKwlDUERGX0RpY3Rpb25hcnkgKiBwU3RyZWFtRGljdCA9IHBTdHJlYW0tPkdldERpY3QoKTsKKwkKKwlpZiAoIXBTdHJlYW1EaWN0KQorCXsKKwkJcFN0cmVhbURpY3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5OworCQlwU3RyZWFtRGljdC0+U2V0QXROYW1lKCJUeXBlIiwgIlhPYmplY3QiKTsKKwkJcFN0cmVhbURpY3QtPlNldEF0TmFtZSgiU3VidHlwZSIsICJGb3JtIik7CisJCXBTdHJlYW1EaWN0LT5TZXRBdEludGVnZXIoIkZvcm1UeXBlIiwgMSk7CisJCXBTdHJlYW0tPkluaXRTdHJlYW0oTlVMTCwwLHBTdHJlYW1EaWN0KTsKKwl9CisJCisJaWYgKHBTdHJlYW1EaWN0KQorCXsKKwkJcFN0cmVhbURpY3QtPlNldEF0TWF0cml4KCJNYXRyaXgiLG1hdHJpeCk7CQorCQlwU3RyZWFtRGljdC0+U2V0QXRSZWN0KCJCQm94IiwgcmNCQm94KTsJCQorCX0KKwkKKwlwU3RyZWFtLT5TZXREYXRhKChGWF9CWVRFKikoRlhfTFBDU1RSKXNDb250ZW50cywgc0NvbnRlbnRzLkdldExlbmd0aCgpLCBGQUxTRSwgRkFMU0UpOworfQorCisjZGVmaW5lIEJBX0FOTk9UX01JTldJRFRICQkJMQorI2RlZmluZSBCQV9BTk5PVF9NSU5IRUlHSFQJCQkxCisKK0ZYX0ZMT0FUIENQREZTREtfQW5ub3Q6OkdldE1pbldpZHRoKCkgY29uc3QKK3sKKwlyZXR1cm4gQkFfQU5OT1RfTUlOV0lEVEg7Cit9CisKK0ZYX0ZMT0FUIENQREZTREtfQW5ub3Q6OkdldE1pbkhlaWdodCgpIGNvbnN0Cit7CisJcmV0dXJuIEJBX0FOTk9UX01JTkhFSUdIVDsKK30KKworRlhfQk9PTCBDUERGU0RLX0Fubm90OjpDcmVhdGVGb3JtRmlsbGVyKCkKK3sKKwlyZXR1cm4gVFJVRTsKK30KK0ZYX0JPT0wJQ1BERlNES19Bbm5vdDo6SXNWaXNpYmxlKCkgY29uc3QKK3sKKwlpbnQgbkZsYWdzID0gR2V0RmxhZ3MoKTsKKwlyZXR1cm4gISgobkZsYWdzICYgQU5OT1RGTEFHX0lOVklTSUJMRSkgfHwgKG5GbGFncyAmIEFOTk9URkxBR19ISURERU4pIHx8IChuRmxhZ3MgJiBBTk5PVEZMQUdfTk9WSUVXKSk7Cit9CisKK0NQREZfQWN0aW9uIENQREZTREtfQW5ub3Q6OkdldEFjdGlvbigpIGNvbnN0Cit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCQorCXJldHVybiBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJBIik7Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6U2V0QWN0aW9uKGNvbnN0IENQREZfQWN0aW9uJiBhY3Rpb24pCit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCQorCUFTU0VSVChhY3Rpb24gIT0gTlVMTCk7CisJCisJaWYgKChDUERGX0FjdGlvbiYpYWN0aW9uICE9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkEiKSkKKwl7CisJCUNQREZfRG9jdW1lbnQqIHBEb2MgPSBtX3BQYWdlVmlldy0+R2V0UERGRG9jdW1lbnQoKTsKKwkJQVNTRVJUKHBEb2MgIT0gTlVMTCk7CisJCQorCQlpZiAoYWN0aW9uLm1fcERpY3QgJiYgKGFjdGlvbi5tX3BEaWN0LT5HZXRPYmpOdW0oKSA9PSAwKSkKKwkJCXBEb2MtPkFkZEluZGlyZWN0T2JqZWN0KGFjdGlvbi5tX3BEaWN0KTsgCisJCW1fcEFubm90LT5tX3BBbm5vdERpY3QtPlNldEF0UmVmZXJlbmNlKCJBIiwgcERvYywgYWN0aW9uLm1fcERpY3QtPkdldE9iak51bSgpKTsKKwl9Cit9CisKK3ZvaWQgQ1BERlNES19Bbm5vdDo6UmVtb3ZlQWN0aW9uKCkKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisJCisJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+UmVtb3ZlQXQoIkEiKTsKK30KKworQ1BERl9BQWN0aW9uIENQREZTREtfQW5ub3Q6OkdldEFBY3Rpb24oKSBjb25zdAoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQUEiKTsKK30KKwordm9pZCBDUERGU0RLX0Fubm90OjpTZXRBQWN0aW9uKGNvbnN0IENQREZfQUFjdGlvbiYgYWEpCit7CisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCUFTU0VSVChhYSAhPSBOVUxMKTsKKwkKKwlpZiAoKENQREZfQUFjdGlvbiYpYWEgIT0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQUEiKSkKKwkJbV9wQW5ub3QtPm1fcEFubm90RGljdC0+U2V0QXQoIkFBIiwgKENQREZfQUFjdGlvbiYpYWEpOworfQorCit2b2lkIENQREZTREtfQW5ub3Q6OlJlbW92ZUFBY3Rpb24oKQoreworCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsKKwkKKwltX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5SZW1vdmVBdCgiQUEiKTsKK30KKworQ1BERl9BY3Rpb24JQ1BERlNES19Bbm5vdDo6R2V0QUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQpCit7CisJQ1BERl9BQWN0aW9uIEFBY3Rpb24gPSBHZXRBQWN0aW9uKCk7CisJCisJaWYgKEFBY3Rpb24uQWN0aW9uRXhpc3QoZUFBVCkpCisJeworCQlyZXR1cm4gQUFjdGlvbi5HZXRBY3Rpb24oZUFBVCk7CisJfQorCWVsc2UgaWYgKGVBQVQgPT0gQ1BERl9BQWN0aW9uOjpCdXR0b25VcCkKKwl7CisJCXJldHVybiBHZXRBY3Rpb24oKTsKKwl9CisJCisJcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgIENQREZTREtfQW5ub3Q6OkFubm90X09uRHJhdyhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLCBDUERGX1JlbmRlck9wdGlvbnMqIHBPcHRpb25zKQoreworCQorCW1fcEFubm90LT5HZXRBUEZvcm0obV9wUGFnZVZpZXctPkdldFBERlBhZ2UoKSwgQ1BERl9Bbm5vdDo6Tm9ybWFsKTsKKwltX3BBbm5vdC0+RHJhd0FwcGVhcmFuY2UobV9wUGFnZVZpZXctPkdldFBERlBhZ2UoKSwgcERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX0Fubm90OjpOb3JtYWwsIE5VTEwpOworCisJcmV0dXJuIDsKK30KKworQ1BERl9QYWdlKiBDUERGU0RLX0Fubm90OjpHZXRQREZQYWdlKCkKK3sKKwlpZihtX3BQYWdlVmlldykKKwkJcmV0dXJuIG1fcFBhZ2VWaWV3LT5HZXRQREZQYWdlKCk7CisJcmV0dXJuIE5VTEw7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2ZzZGtfYmFzZWZvcm0uY3BwIGIvZnBkZnNkay9zcmMvZnNka19iYXNlZm9ybS5jcHAKaW5kZXggMjNkOWVjOS4uYWUzYjYzNiAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnNka19iYXNlZm9ybS5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnNka19iYXNlZm9ybS5jcHAKQEAgLTEsMzExMSArMSwzMTExIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfbWdyLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19iYXNlYW5ub3QuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2Jhc2Vmb3JtLmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfYWN0aW9uaGFuZGxlci5oIg0KLQ0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCINCi0NCi0vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KLS8vKgkJCQkJCQkJCQlDUERGU0RLX1dpZGdldCANCi0vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KLQ0KLSNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMSAmJiAoZikgPiAtMC4wMSkNCi0jZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCSgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQ0KLSNkZWZpbmUgSXNGbG9hdFNtYWxsZXIoZmEsZmIpCQkJCSgoZmEpIDwgKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQ0KLSNkZWZpbmUgSXNGbG9hdEVxdWFsKGZhLGZiKQkJCQkJSXNGbG9hdFplcm8oKGZhKS0oZmIpKQ0KLQ0KLUNQREZTREtfV2lkZ2V0OjpDUERGU0RLX1dpZGdldChDUERGX0Fubm90KiBwQW5ub3QsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0pIDoNCi0JCQkJCUNQREZTREtfQW5ub3QocEFubm90LCBwUGFnZVZpZXcpLA0KLQkJCQkJbV9wSW50ZXJGb3JtKHBJbnRlckZvcm0pLA0KLQkJCQkJbV9uQXBwQWdlKDApLA0KLQkJCQkJbV9uVmFsdWVBZ2UoMCkNCi17DQotCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7DQotfQ0KLQ0KLUNQREZTREtfV2lkZ2V0Ojp+Q1BERlNES19XaWRnZXQoKQ0KLXsNCi0NCi19DQotDQotRlhfQk9PTAkJQ1BERlNES19XaWRnZXQ6OklzV2lkZ2V0QXBwZWFyYW5jZVZhbGlkKENQREZfQW5ub3Q6OkFwcGVhcmFuY2VNb2RlIG1vZGUpDQotew0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQkNCi0JQ1BERl9EaWN0aW9uYXJ5KiBwQVAgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJBUCIpOw0KLQlpZiAocEFQID09IE5VTEwpIHJldHVybiBGQUxTRTsNCi0JDQotCS8vIENob29zZSB0aGUgcmlnaHQgc3ViLWFwDQotCWNvbnN0IEZYX0NIQVIqIGFwX2VudHJ5ID0gIk4iOw0KLQlpZiAobW9kZSA9PSBDUERGX0Fubm90OjpEb3duKQ0KLQkJYXBfZW50cnkgPSAiRCI7DQotCWVsc2UgaWYgKG1vZGUgPT0gQ1BERl9Bbm5vdDo6Um9sbG92ZXIpDQotCQlhcF9lbnRyeSA9ICJSIjsNCi0JaWYgKCFwQVAtPktleUV4aXN0KGFwX2VudHJ5KSkNCi0JCWFwX2VudHJ5ID0gIk4iOw0KLQkNCi0JLy8gR2V0IHRoZSBBUCBzdHJlYW0gb3Igc3ViZGlyZWN0b3J5DQotCUNQREZfT2JqZWN0KiBwc3ViID0gcEFQLT5HZXRFbGVtZW50VmFsdWUoYXBfZW50cnkpOw0KLQlpZiAocHN1YiA9PSBOVUxMKSByZXR1cm4gRkFMU0U7DQotCQ0KLQlpbnQgbkZpZWxkVHlwZSA9IEdldEZpZWxkVHlwZSgpOw0KLQlzd2l0Y2ggKG5GaWVsZFR5cGUpDQotCXsNCi0JY2FzZSBGSUVMRFRZUEVfUFVTSEJVVFRPTjoNCi0JY2FzZSBGSUVMRFRZUEVfQ09NQk9CT1g6DQotCWNhc2UgRklFTERUWVBFX0xJU1RCT1g6DQotCWNhc2UgRklFTERUWVBFX1RFWFRGSUVMRDoNCi0JY2FzZSBGSUVMRFRZUEVfU0lHTkFUVVJFOg0KLQkJcmV0dXJuIHBzdWItPkdldFR5cGUoKSA9PSBQREZPQkpfU1RSRUFNOw0KLQljYXNlIEZJRUxEVFlQRV9DSEVDS0JPWDoNCi0JY2FzZSBGSUVMRFRZUEVfUkFESU9CVVRUT046DQotCQlpZiAocHN1Yi0+R2V0VHlwZSgpID09IFBERk9CSl9ESUNUSU9OQVJZKSANCi0JCXsNCi0JCQlDUERGX0RpY3Rpb25hcnkqIHBTdWJEaWN0ID0gKENQREZfRGljdGlvbmFyeSopcHN1YjsNCi0JCQkNCi0JCQlyZXR1cm4gcFN1YkRpY3QtPkdldFN0cmVhbSh0aGlzLT5HZXRBcHBTdGF0ZSgpKSAhPSBOVUxMOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJCXJldHVybiBGQUxTRTsNCi0JCWJyZWFrOw0KLQl9DQotCQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotaW50CUNQREZTREtfV2lkZ2V0OjpHZXRGaWVsZFR5cGUoKSBjb25zdA0KLXsNCi0JQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCA9IEdldEZvcm1GaWVsZCgpOw0KLQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIHBGaWVsZC0+R2V0RmllbGRUeXBlKCk7DQotfQ0KLQ0KLWludCBDUERGU0RLX1dpZGdldDo6R2V0RmllbGRGbGFncygpIGNvbnN0DQotew0KLQlDUERGX0ludGVyRm9ybSogcFBERkludGVyRm9ybSA9IG1fcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwUERGSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwUERGSW50ZXJGb3JtLT5HZXRDb250cm9sQnlEaWN0KG1fcEFubm90LT5tX3BBbm5vdERpY3QpOw0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IHBGb3JtQ29udHJvbC0+R2V0RmllbGQoKTsNCi0JcmV0dXJuIHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BERlNES19XaWRnZXQ6OkdldFN1YlR5cGUoKSBjb25zdA0KLXsNCi0JaW50IG5UeXBlID0gR2V0RmllbGRUeXBlKCk7DQotCQ0KLQlpZiAoblR5cGUgPT0gRklFTERUWVBFX1NJR05BVFVSRSkNCi0JCXJldHVybiBCRkZUX1NJR05BVFVSRTsNCi0JcmV0dXJuIENQREZTREtfQW5ub3Q6OkdldFN1YlR5cGUoKTsNCi19DQotDQotQ1BERl9Gb3JtRmllbGQqCUNQREZTREtfV2lkZ2V0OjpHZXRGb3JtRmllbGQoKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0JDQotCUNQREZfRm9ybUNvbnRyb2wqIHBDdHJsID0gR2V0Rm9ybUNvbnRyb2woKTsJDQotCUFTU0VSVChwQ3RybCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBwQ3RybC0+R2V0RmllbGQoKTsNCi19DQotDQotQ1BERl9Gb3JtQ29udHJvbCogQ1BERlNES19XaWRnZXQ6OkdldEZvcm1Db250cm9sKCkgY29uc3QNCi17DQotCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7DQotCQ0KLQlDUERGX0ludGVyRm9ybSogcFBERkludGVyRm9ybSA9IG1fcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwUERGSW50ZXJGb3JtICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIHBQREZJbnRlckZvcm0tPkdldENvbnRyb2xCeURpY3QoR2V0QW5ub3REaWN0KCkpOw0KLX0NCi1zdGF0aWMgQ1BERl9EaWN0aW9uYXJ5KiBCRl9HZXRGaWVsZChDUERGX0RpY3Rpb25hcnkqIHBGaWVsZERpY3QsIGNvbnN0IEZYX0NIQVIqIG5hbWUpDQotew0KLQlpZiAocEZpZWxkRGljdCA9PSBOVUxMKSByZXR1cm4gTlVMTDsNCi0JLy8gRmlyc3QgY2hlY2sgdGhlIGRpY3Rpb25hcnkgaXRzZWxmDQotCUNQREZfT2JqZWN0KiBwQXR0ciA9IHBGaWVsZERpY3QtPkdldEVsZW1lbnRWYWx1ZShuYW1lKTsNCi0JaWYgKHBBdHRyKSByZXR1cm4gcEZpZWxkRGljdDsNCi0JDQotCS8vIE5vdyB3ZSBuZWVkIHRvIHNlYXJjaCBmcm9tIHBhcmVudHMNCi0JQ1BERl9EaWN0aW9uYXJ5KiBwUGFyZW50ID0gcEZpZWxkRGljdC0+R2V0RGljdCgiUGFyZW50Iik7DQotCWlmIChwUGFyZW50ID09IE5VTEwpIHJldHVybiBOVUxMOw0KLQkNCi0JcmV0dXJuIEJGX0dldEZpZWxkKHBQYXJlbnQsIG5hbWUpOw0KLX0NCi0NCi1DUERGX0Zvcm1Db250cm9sKiBDUERGU0RLX1dpZGdldDo6R2V0Rm9ybUNvbnRyb2woQ1BERl9JbnRlckZvcm0qIHBJbnRlckZvcm0sIENQREZfRGljdGlvbmFyeSogcEFubm90RGljdCkNCi17DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQlBU1NFUlQocEFubm90RGljdCAhPSBOVUxMKTsNCi0JDQotCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gcEludGVyRm9ybS0+R2V0Q29udHJvbEJ5RGljdChwQW5ub3REaWN0KTsNCi0JDQotCXJldHVybiBwQ29udHJvbDsNCi19DQotDQotaW50IENQREZTREtfV2lkZ2V0OjpHZXRSb3RhdGUoKSBjb25zdA0KLXsNCi0JQ1BERl9Gb3JtQ29udHJvbCogcEN0cmwgPSB0aGlzLT5HZXRGb3JtQ29udHJvbCgpOw0KLQlBU1NFUlQocEN0cmwgIT0gTlVMTCk7DQotCQ0KLQlyZXR1cm4gcEN0cmwtPkdldFJvdGF0aW9uKCkgJSAzNjA7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19XaWRnZXQ6OkdldEZpbGxDb2xvcihGWF9DT0xPUlJFRiYgY29sb3IpIGNvbnN0DQotew0KLQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUN0cmwgPSBHZXRGb3JtQ29udHJvbCgpOw0KLQlBU1NFUlQocEZvcm1DdHJsICE9IE5VTEwpOw0KLQkNCi0JaW50IGlDb2xvclR5cGUgPSAwOwkNCi0JY29sb3IgPSBGWF9BUkdCVE9DT0xPUlJFRihwRm9ybUN0cmwtPkdldEJhY2tncm91bmRDb2xvcihpQ29sb3JUeXBlKSk7DQotCQ0KLQlyZXR1cm4gaUNvbG9yVHlwZSAhPSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQ7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19XaWRnZXQ6OkdldEJvcmRlckNvbG9yKEZYX0NPTE9SUkVGJiBjb2xvcikgY29uc3QNCi17DQotCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7DQotCUFTU0VSVChwRm9ybUN0cmwgIT0gTlVMTCk7DQotCQ0KLQlpbnQgaUNvbG9yVHlwZSA9IDA7CQ0KLQljb2xvciA9IEZYX0FSR0JUT0NPTE9SUkVGKHBGb3JtQ3RybC0+R2V0Qm9yZGVyQ29sb3IoaUNvbG9yVHlwZSkpOw0KLQkNCi0JcmV0dXJuIGlDb2xvclR5cGUgIT0gQ09MT1JUWVBFX1RSQU5TUEFSRU5UOw0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfV2lkZ2V0OjpHZXRUZXh0Q29sb3IoRlhfQ09MT1JSRUYmIGNvbG9yKSBjb25zdA0KLXsNCi0JQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gR2V0Rm9ybUNvbnRyb2woKTsNCi0JQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsNCi0JDQotCUNQREZfRGVmYXVsdEFwcGVhcmFuY2UgZGEgPSBwRm9ybUN0cmwtPkdldERlZmF1bHRBcHBlYXJhbmNlKCk7DQotCWlmIChkYS5IYXNDb2xvcigpKQ0KLQl7DQotCQlGWF9BUkdCIGFyZ2I7DQotCQlpbnQgaUNvbG9yVHlwZSA9IENPTE9SVFlQRV9UUkFOU1BBUkVOVDsJDQotCQlkYS5HZXRDb2xvcihhcmdiLCBpQ29sb3JUeXBlKTsNCi0JCWNvbG9yID0gRlhfQVJHQlRPQ09MT1JSRUYoYXJnYik7DQotCQkNCi0JCXJldHVybiBpQ29sb3JUeXBlICE9IENPTE9SVFlQRV9UUkFOU1BBUkVOVDsNCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9GTE9BVCBDUERGU0RLX1dpZGdldDo6R2V0Rm9udFNpemUoKSBjb25zdA0KLXsNCi0JQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gR2V0Rm9ybUNvbnRyb2woKTsNCi0JQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsNCi0JDQotCUNQREZfRGVmYXVsdEFwcGVhcmFuY2UgcERhID0gcEZvcm1DdHJsLT5HZXREZWZhdWx0QXBwZWFyYW5jZSgpOw0KLQlDRlhfQnl0ZVN0cmluZyBjc0ZvbnQgPSAiIjsNCi0JRlhfRkxPQVQgZkZvbnRTaXplID0gMC4wZjsNCi0JcERhLkdldEZvbnQoY3NGb250LCBmRm9udFNpemUpOw0KLQkNCi0JcmV0dXJuIGZGb250U2l6ZTsNCi19DQotDQotaW50CUNQREZTREtfV2lkZ2V0OjpHZXRTZWxlY3RlZEluZGV4KGludCBuSW5kZXgpIGNvbnN0DQotew0KLQlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBwRm9ybUZpZWxkLT5HZXRTZWxlY3RlZEluZGV4KG5JbmRleCk7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENQREZTREtfV2lkZ2V0OjpHZXRWYWx1ZSgpIGNvbnN0DQotew0KLQlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBwRm9ybUZpZWxkLT5HZXRWYWx1ZSgpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUERGU0RLX1dpZGdldDo6R2V0RGVmYXVsdFZhbHVlKCkgY29uc3QNCi17DQotCUNQREZfRm9ybUZpZWxkKglwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIHBGb3JtRmllbGQtPkdldERlZmF1bHRWYWx1ZSgpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUERGU0RLX1dpZGdldDo6R2V0T3B0aW9uTGFiZWwoaW50IG5JbmRleCkgY29uc3QNCi17DQotCUNQREZfRm9ybUZpZWxkKglwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIHBGb3JtRmllbGQtPkdldE9wdGlvbkxhYmVsKG5JbmRleCk7DQotfQ0KLQ0KLWludAlDUERGU0RLX1dpZGdldDo6Q291bnRPcHRpb25zKCkgY29uc3QNCi17DQotCUNQREZfRm9ybUZpZWxkKglwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIHBGb3JtRmllbGQtPkNvdW50T3B0aW9ucygpOw0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfV2lkZ2V0OjpJc09wdGlvblNlbGVjdGVkKGludCBuSW5kZXgpIGNvbnN0DQotew0KLQlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBwRm9ybUZpZWxkLT5Jc0l0ZW1TZWxlY3RlZChuSW5kZXgpOw0KLX0NCi0NCi1pbnQJQ1BERlNES19XaWRnZXQ6OkdldFRvcFZpc2libGVJbmRleCgpIGNvbnN0DQotew0KLQlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBwRm9ybUZpZWxkLT5HZXRUb3BWaXNpYmxlSW5kZXgoKTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX1dpZGdldDo6SXNDaGVja2VkKCkgY29uc3QNCi17DQotCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7DQotCUFTU0VSVChwRm9ybUN0cmwgIT0gTlVMTCk7DQotCQ0KLQlyZXR1cm4gcEZvcm1DdHJsLT5Jc0NoZWNrZWQoKTsNCi19DQotDQotaW50CUNQREZTREtfV2lkZ2V0OjpHZXRBbGlnbm1lbnQoKSBjb25zdA0KLXsNCi0JQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gR2V0Rm9ybUNvbnRyb2woKTsNCi0JQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBwRm9ybUN0cmwtPkdldENvbnRyb2xBbGlnbm1lbnQoKTsNCi19DQotDQotaW50CUNQREZTREtfV2lkZ2V0OjpHZXRNYXhMZW4oKSBjb25zdA0KLXsNCi0JQ1BERl9Gb3JtRmllbGQqCXBGb3JtRmllbGQgPSBHZXRGb3JtRmllbGQoKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotCQ0KLQlyZXR1cm4gcEZvcm1GaWVsZC0+R2V0TWF4TGVuKCk7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19XaWRnZXQ6OlNldENoZWNrKEZYX0JPT0wgYkNoZWNrZWQsIEZYX0JPT0wgYk5vdGlmeSkNCi17DQotCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7DQotCUFTU0VSVChwRm9ybUN0cmwgIT0gTlVMTCk7DQotCQ0KLQlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IHBGb3JtQ3RybC0+R2V0RmllbGQoKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotCQ0KLQlwRm9ybUZpZWxkLT5DaGVja0NvbnRyb2wocEZvcm1GaWVsZC0+R2V0Q29udHJvbEluZGV4KHBGb3JtQ3RybCksIGJDaGVja2VkLCBiTm90aWZ5KTsNCi19DQotDQotdm9pZCBDUERGU0RLX1dpZGdldDo6U2V0VmFsdWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNWYWx1ZSwgRlhfQk9PTCBiTm90aWZ5KQ0KLXsNCi0JQ1BERl9Gb3JtRmllbGQqCXBGb3JtRmllbGQgPSBHZXRGb3JtRmllbGQoKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotCQ0KLQlwRm9ybUZpZWxkLT5TZXRWYWx1ZShzVmFsdWUsIGJOb3RpZnkpOw0KLX0NCi0NCi12b2lkIENQREZTREtfV2lkZ2V0OjpTZXREZWZhdWx0VmFsdWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNWYWx1ZSkNCi17DQotfQ0KLXZvaWQgQ1BERlNES19XaWRnZXQ6OlNldE9wdGlvblNlbGVjdGlvbihpbnQgaW5kZXgsIEZYX0JPT0wgYlNlbGVjdGVkLCBGWF9CT09MIGJOb3RpZnkpDQotew0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0JDQotCXBGb3JtRmllbGQtPlNldEl0ZW1TZWxlY3Rpb24oaW5kZXgsIGJTZWxlY3RlZCwgYk5vdGlmeSk7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19XaWRnZXQ6OkNsZWFyU2VsZWN0aW9uKEZYX0JPT0wgYk5vdGlmeSkNCi17DQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQkNCi0JcEZvcm1GaWVsZC0+Q2xlYXJTZWxlY3Rpb24oYk5vdGlmeSk7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19XaWRnZXQ6OlNldFRvcFZpc2libGVJbmRleChpbnQgaW5kZXgpDQotew0KLX0NCi0NCi12b2lkIENQREZTREtfV2lkZ2V0OjpTZXRBcHBNb2RpZmllZCgpDQotew0KLQltX2JBcHBNb2RpZmllZCA9IFRSVUU7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19XaWRnZXQ6OkNsZWFyQXBwTW9kaWZpZWQoKQ0KLXsNCi0JbV9iQXBwTW9kaWZpZWQgPSBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX1dpZGdldDo6SXNBcHBNb2RpZmllZCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9iQXBwTW9kaWZpZWQ7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19XaWRnZXQ6OlJlc2V0QXBwZWFyYW5jZShGWF9MUENXU1RSIHNWYWx1ZSwgRlhfQk9PTCBiVmFsdWVDaGFuZ2VkKQ0KLXsNCi0JU2V0QXBwTW9kaWZpZWQoKTsNCi0NCi0JbV9uQXBwQWdlKys7DQotCWlmIChtX25BcHBBZ2UgPiA5OTk5OTkpDQotCQltX25BcHBBZ2UgPSAwOw0KLQlpZiAoYlZhbHVlQ2hhbmdlZCkNCi0JCW1fblZhbHVlQWdlKys7DQotDQotCWludCBuRmllbGRUeXBlID0gR2V0RmllbGRUeXBlKCk7DQotCQ0KLQlzd2l0Y2ggKG5GaWVsZFR5cGUpDQotCXsNCi0JY2FzZSBGSUVMRFRZUEVfUFVTSEJVVFRPTjoNCi0JCVJlc2V0QXBwZWFyYW5jZV9QdXNoQnV0dG9uKCk7DQotCQlicmVhazsNCi0JY2FzZSBGSUVMRFRZUEVfQ0hFQ0tCT1g6DQotCQlSZXNldEFwcGVhcmFuY2VfQ2hlY2tCb3goKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoNCi0JCVJlc2V0QXBwZWFyYW5jZV9SYWRpb0J1dHRvbigpOw0KLQkJYnJlYWs7DQotCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOg0KLQkJUmVzZXRBcHBlYXJhbmNlX0NvbWJvQm94KHNWYWx1ZSk7DQotCQlicmVhazsNCi0JY2FzZSBGSUVMRFRZUEVfTElTVEJPWDoNCi0JCVJlc2V0QXBwZWFyYW5jZV9MaXN0Qm94KCk7DQotCQlicmVhazsNCi0JY2FzZSBGSUVMRFRZUEVfVEVYVEZJRUxEOg0KLQkJUmVzZXRBcHBlYXJhbmNlX1RleHRGaWVsZChzVmFsdWUpOw0KLQkJYnJlYWs7DQotCX0NCi0JDQotCUFTU0VSVChtX3BBbm5vdCAhPSBOVUxMKTsNCi0JbV9wQW5ub3QtPkNsZWFyQ2FjaGVkQVAoKTsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ1BERlNES19XaWRnZXQ6Ok9uRm9ybWF0KGludCBuQ29tbWl0S2V5LCBGWF9CT09MJiBiRm9ybWF0ZWQpDQotew0KLSAJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBHZXRGb3JtRmllbGQoKTsNCi0gCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLSAJDQotIAlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIG1fcEludGVyRm9ybS0+T25Gb3JtYXQocEZvcm1GaWVsZCwgbkNvbW1pdEtleSwgYkZvcm1hdGVkKTsNCi0NCi19DQotDQotdm9pZCBDUERGU0RLX1dpZGdldDo6UmVzZXRGaWVsZEFwcGVhcmFuY2UoRlhfQk9PTCBiVmFsdWVDaGFuZ2VkKQ0KLXsNCi0JQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBHZXRGb3JtRmllbGQoKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotCQ0KLQlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQltX3BJbnRlckZvcm0tPlJlc2V0RmllbGRBcHBlYXJhbmNlKHBGb3JtRmllbGQsIE5VTEwsIGJWYWx1ZUNoYW5nZWQpOw0KLX0NCi0NCi12b2lkCUNQREZTREtfV2lkZ2V0OjpEcmF3QXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBjb25zdCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJQ1BERl9Bbm5vdDo6QXBwZWFyYW5jZU1vZGUgbW9kZSwgY29uc3QgQ1BERl9SZW5kZXJPcHRpb25zKiBwT3B0aW9ucykNCi17DQotCWludCBuRmllbGRUeXBlID0gR2V0RmllbGRUeXBlKCk7DQotCQ0KLQlpZiAoKG5GaWVsZFR5cGUgPT0gRklFTERUWVBFX0NIRUNLQk9YIHx8IG5GaWVsZFR5cGUgPT0gRklFTERUWVBFX1JBRElPQlVUVE9OKSAmJg0KLQkJbW9kZSA9PSBDUERGX0Fubm90OjpOb3JtYWwgJiYgDQotCQkhdGhpcy0+SXNXaWRnZXRBcHBlYXJhbmNlVmFsaWQoQ1BERl9Bbm5vdDo6Tm9ybWFsKSkNCi0Jew0KLQkJQ0ZYX1BhdGhEYXRhIHBhdGhEYXRhOw0KLQkJDQotCQlDUERGX1JlY3QgcmNBbm5vdCA9IHRoaXMtPkdldFJlY3QoKTsNCi0JCQ0KLQkJcGF0aERhdGEuQXBwZW5kUmVjdChyY0Fubm90LmxlZnQsIHJjQW5ub3QuYm90dG9tLA0KLQkJCXJjQW5ub3QucmlnaHQsIHJjQW5ub3QudG9wKTsNCi0JCQ0KLQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JCWdzZC5tX0xpbmVXaWR0aCA9IDAuMGY7DQotCQkNCi0JCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoRGF0YSwgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLCAweEZGQUFBQUFBLCBGWEZJTExfQUxURVJOQVRFKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNQREZTREtfQW5ub3Q6OkRyYXdBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgbW9kZSwgcE9wdGlvbnMpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19XaWRnZXQ6OlVwZGF0ZUZpZWxkKCkNCi17DQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQkNCi0JQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0JbV9wSW50ZXJGb3JtLT5VcGRhdGVGaWVsZChwRm9ybUZpZWxkKTsNCi19DQotDQotdm9pZCBDUERGU0RLX1dpZGdldDo6RHJhd1NoYWRvdyhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpDQotew0KLSAJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0gDQotCWludCBuRmllbGRUeXBlID0gR2V0RmllbGRUeXBlKCk7DQotIAlpZiAobV9wSW50ZXJGb3JtLT5Jc05lZWRIaWdoTGlnaHQobkZpZWxkVHlwZSkpDQotIAl7DQotIA0KLS8vICAJCWlmIChuRmllbGRUeXBlICE9IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQ0KLS8vICAJCXsNCi0JCQlDUERGX1JlY3QgcmMgID0gR2V0UmVjdCgpOw0KLQkJCUZYX0NPTE9SUkVGIGNvbG9yID0gbV9wSW50ZXJGb3JtLT5HZXRIaWdobGlnaHRDb2xvcihuRmllbGRUeXBlKTsNCi0JCQlGWF9CWVRFIGFscGhhID0gbV9wSW50ZXJGb3JtLT5HZXRIaWdobGlnaHRBbHBoYSgpOw0KLQ0KLQkJCUNGWF9GbG9hdFJlY3QgcmNEZXZpY2U7DQotCQkJQVNTRVJUKG1fcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKSk7DQotCQkJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKS0+R2V0RW52KCk7DQotCQkJaWYoIXBFbnYpDQotCQkJCXJldHVybjsNCi0JCQlDRlhfQWZmaW5lTWF0cml4IHBhZ2UyZGV2aWNlOw0KLQkJCXBQYWdlVmlldy0+R2V0Q3VycmVudE1hdHJpeChwYWdlMmRldmljZSk7DQotCQkJcGFnZTJkZXZpY2UuVHJhbnNmb3JtKCgoRlhfRkxPQVQpcmMubGVmdCksICgoRlhfRkxPQVQpcmMuYm90dG9tKSwgcmNEZXZpY2UubGVmdCwgcmNEZXZpY2UuYm90dG9tKTsNCi0vLyAJCQlwRW52LT5GRklfUGFnZVRvRGV2aWNlKG1fcFBhZ2VWaWV3LT5HZXRQREZQYWdlKCksIHJjLmxlZnQsIHJjLmJvdHRvbSwgJnJjRGV2aWNlLmxlZnQsICZyY0RldmljZS5ib3R0b20pOw0KLS8vIAkJCXBFbnYtPkZGSV9QYWdlVG9EZXZpY2UobV9wUGFnZVZpZXctPkdldFBERlBhZ2UoKSwgcmMucmlnaHQsIHJjLnRvcCwgJnJjRGV2aWNlLnJpZ2h0LCAmcmNEZXZpY2UudG9wKTsNCi0JCQlwYWdlMmRldmljZS5UcmFuc2Zvcm0oKChGWF9GTE9BVClyYy5yaWdodCksICgoRlhfRkxPQVQpcmMudG9wKSwgcmNEZXZpY2UucmlnaHQsIHJjRGV2aWNlLnRvcCk7DQotDQotCQkJcmNEZXZpY2UuTm9ybWFsaXplKCk7DQotDQotCQkJRlhfQVJHQiBhcmdiID0gQXJnYkVuY29kZSgoaW50KWFscGhhLCBjb2xvcik7DQotCQkJRlhfUkVDVCByY0RldigoaW50KXJjRGV2aWNlLmxlZnQsKGludClyY0RldmljZS50b3AsKGludClyY0RldmljZS5yaWdodCwoaW50KXJjRGV2aWNlLmJvdHRvbSk7DQotCQkJcERldmljZS0+RmlsbFJlY3QoJnJjRGV2LCBhcmdiKTsJDQotCQkJLyogCQl9Ki8NCi0JfQ0KLX0NCi0NCi12b2lkIENQREZTREtfV2lkZ2V0OjpSZXNldEFwcGVhcmFuY2VfUHVzaEJ1dHRvbigpDQotew0KLQlDUERGX0Zvcm1Db250cm9sKiBwQ29udHJvbCA9IEdldEZvcm1Db250cm9sKCk7DQotCUFTU0VSVChwQ29udHJvbCAhPSBOVUxMKTsNCi0NCi0NCi0JDQotCUNQREZfUmVjdCByY1dpbmRvdyA9IEdldFJvdGF0ZWRSZWN0KCk7CQ0KLQ0KLQlGWF9JTlQzMiBuTGF5b3V0ID0gMDsNCi0NCi0Jc3dpdGNoIChwQ29udHJvbC0+R2V0VGV4dFBvc2l0aW9uKCkpDQotCXsNCi0JY2FzZSBURVhUUE9TX0lDT046DQotCQluTGF5b3V0ID0gUFBCTF9JQ09OOw0KLQkJYnJlYWs7DQotCWNhc2UgVEVYVFBPU19CRUxPVzoNCi0JCW5MYXlvdXQgPSBQUEJMX0lDT05UT1BMQUJFTEJPVFRPTTsNCi0JCWJyZWFrOw0KLQljYXNlIFRFWFRQT1NfQUJPVkU6DQotCQluTGF5b3V0ID0gUFBCTF9MQUJFTFRPUElDT05CT1RUT007DQotCQlicmVhazsNCi0JY2FzZSBURVhUUE9TX1JJR0hUOg0KLQkJbkxheW91dCA9IFBQQkxfSUNPTkxFRlRMQUJFTFJJR0hUOw0KLQkJYnJlYWs7DQotCWNhc2UgVEVYVFBPU19MRUZUOg0KLQkJbkxheW91dCA9IFBQQkxfTEFCRUxMRUZUSUNPTlJJR0hUOw0KLQkJYnJlYWs7DQotCWNhc2UgVEVYVFBPU19PVkVSTEFJRDoNCi0JCW5MYXlvdXQgPSBQUEJMX0xBQkVMT1ZFUklDT047DQotCQlicmVhazsNCi0JZGVmYXVsdDoNCi0JCW5MYXlvdXQgPSBQUEJMX0xBQkVMOw0KLQkJYnJlYWs7DQotCX0NCi0NCi0JQ1BXTF9Db2xvciBjckJhY2tncm91bmQsIGNyQm9yZGVyOw0KLQ0KLQlpbnQgaUNvbG9yVHlwZTsNCi0JRlhfRkxPQVQgZmNbNF07DQotDQotCXBDb250cm9sLT5HZXRPcmlnaW5hbEJhY2tncm91bmRDb2xvcihpQ29sb3JUeXBlLCBmYyk7DQotCWlmIChpQ29sb3JUeXBlID4gMCkNCi0JCWNyQmFja2dyb3VuZCA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOw0KLQ0KLQlwQ29udHJvbC0+R2V0T3JpZ2luYWxCb3JkZXJDb2xvcihpQ29sb3JUeXBlLCBmYyk7DQotCWlmIChpQ29sb3JUeXBlID4gMCkNCi0JCWNyQm9yZGVyID0gQ1BXTF9Db2xvcihpQ29sb3JUeXBlLCBmY1swXSwgZmNbMV0sIGZjWzJdLCBmY1szXSk7DQotDQotCUZYX0ZMT0FUIGZCb3JkZXJXaWR0aCA9IChGWF9GTE9BVClHZXRCb3JkZXJXaWR0aCgpOw0KLQlGWF9JTlQzMiBuQm9yZGVyU3R5bGUgPSAwOw0KLQlDUFdMX0Rhc2ggZHNCb3JkZXIoMywwLDApOw0KLQlDUFdMX0NvbG9yIGNyTGVmdFRvcCxjclJpZ2h0Qm90dG9tOw0KLQ0KLQlzd2l0Y2ggKEdldEJvcmRlclN0eWxlKCkpDQotCXsNCi0JY2FzZSBCQlNfREFTSDoNCi0JCW5Cb3JkZXJTdHlsZSA9IFBCU19EQVNIOw0KLQkJZHNCb3JkZXIgPSBDUFdMX0Rhc2goMywgMywgMCk7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfQkVWRUxFRDoNCi0JCW5Cb3JkZXJTdHlsZSA9IFBCU19CRVZFTEVEOw0KLQkJZkJvcmRlcldpZHRoICo9IDI7DQotCQljckxlZnRUb3AgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOw0KLQkJY3JSaWdodEJvdHRvbSA9IENQV0xfVXRpbHM6OkRldmlkZUNvbG9yKGNyQmFja2dyb3VuZCwyKTsNCi0JCWJyZWFrOw0KLQljYXNlIEJCU19JTlNFVDoNCi0JCW5Cb3JkZXJTdHlsZSA9IFBCU19JTlNFVDsNCi0JCWZCb3JkZXJXaWR0aCAqPSAyOw0KLQkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwLjUpOw0KLQkJY3JSaWdodEJvdHRvbSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC43NSk7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfVU5ERVJMSU5FOg0KLQkJbkJvcmRlclN0eWxlID0gUEJTX1VOREVSTElORUQ7DQotCQlicmVhazsNCi0JZGVmYXVsdDogDQotCQluQm9yZGVyU3R5bGUgPSBQQlNfU09MSUQ7DQotCQlicmVhazsNCi0JfQ0KLQ0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChyY1dpbmRvdyxmQm9yZGVyV2lkdGgpOwkNCi0NCi0JQ1BXTF9Db2xvciBjclRleHQoQ09MT1JUWVBFX0dSQVksMCk7DQotDQotCUZYX0ZMT0FUIGZGb250U2l6ZSA9IDEyLjBmOw0KLQlDRlhfQnl0ZVN0cmluZyBjc05hbWVUYWc7DQotDQotCUNQREZfRGVmYXVsdEFwcGVhcmFuY2UgZGEgPSBwQ29udHJvbC0+R2V0RGVmYXVsdEFwcGVhcmFuY2UoKTsNCi0JaWYgKGRhLkhhc0NvbG9yKCkpDQotCXsNCi0JCWRhLkdldENvbG9yKGlDb2xvclR5cGUsIGZjKTsNCi0JCWNyVGV4dCA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOw0KLQl9DQotDQotCWlmIChkYS5IYXNGb250KCkpIA0KLQkJZGEuR2V0Rm9udChjc05hbWVUYWcsIGZGb250U2l6ZSk7DQotDQotCUNGWF9XaWRlU3RyaW5nIGNzV0NhcHRpb247DQotCUNGWF9XaWRlU3RyaW5nIGNzTm9ybWFsQ2FwdGlvbiwgY3NSb2xsb3ZlckNhcHRpb24sIGNzRG93bkNhcHRpb247DQotDQotCWlmIChwQ29udHJvbC0+SGFzTUtFbnRyeSgiQ0EiKSkNCi0Jew0KLQkJY3NOb3JtYWxDYXB0aW9uID0gcENvbnRyb2wtPkdldE5vcm1hbENhcHRpb24oKTsNCi0JfQ0KLQlpZiAocENvbnRyb2wtPkhhc01LRW50cnkoIlJDIikpDQotCXsNCi0JCWNzUm9sbG92ZXJDYXB0aW9uID0gcENvbnRyb2wtPkdldFJvbGxvdmVyQ2FwdGlvbigpOw0KLQl9DQotCWlmIChwQ29udHJvbC0+SGFzTUtFbnRyeSgiQUMiKSkNCi0Jew0KLQkJY3NEb3duQ2FwdGlvbiA9IHBDb250cm9sLT5HZXREb3duQ2FwdGlvbigpOw0KLQl9DQotDQotCUNQREZfU3RyZWFtKiBwTm9ybWFsSWNvbiA9IE5VTEw7DQotCUNQREZfU3RyZWFtKiBwUm9sbG92ZXJJY29uID0gTlVMTDsNCi0JQ1BERl9TdHJlYW0qIHBEb3duSWNvbiA9IE5VTEw7DQotDQotCWlmIChwQ29udHJvbC0+SGFzTUtFbnRyeSgiSSIpKQ0KLQl7DQotCQlwTm9ybWFsSWNvbiA9IHBDb250cm9sLT5HZXROb3JtYWxJY29uKCk7DQotCX0NCi0JaWYgKHBDb250cm9sLT5IYXNNS0VudHJ5KCJSSSIpKQ0KLQl7DQotCQlwUm9sbG92ZXJJY29uID0gcENvbnRyb2wtPkdldFJvbGxvdmVySWNvbigpOw0KLQl9DQotCWlmIChwQ29udHJvbC0+SGFzTUtFbnRyeSgiSVgiKSkNCi0Jew0KLQkJcERvd25JY29uID0gcENvbnRyb2wtPkdldERvd25JY29uKCk7DQotCX0NCi0NCi0JaWYgKHBOb3JtYWxJY29uKQ0KLQl7DQotCQlpZiAoQ1BERl9EaWN0aW9uYXJ5KiBwSW1hZ2VEaWN0ID0gcE5vcm1hbEljb24tPkdldERpY3QoKSkNCi0JCXsNCi0JCQlpZiAocEltYWdlRGljdC0+R2V0U3RyaW5nKCJOYW1lIikuSXNFbXB0eSgpKQ0KLQkJCQlwSW1hZ2VEaWN0LT5TZXRBdFN0cmluZygiTmFtZSIsICJJbWdBIik7DQotCQl9DQotCX0NCi0NCi0JaWYgKHBSb2xsb3Zlckljb24pDQotCXsNCi0JCWlmIChDUERGX0RpY3Rpb25hcnkqIHBJbWFnZURpY3QgPSBwUm9sbG92ZXJJY29uLT5HZXREaWN0KCkpDQotCQl7DQotCQkJaWYgKHBJbWFnZURpY3QtPkdldFN0cmluZygiTmFtZSIpLklzRW1wdHkoKSkNCi0JCQkJcEltYWdlRGljdC0+U2V0QXRTdHJpbmcoIk5hbWUiLCAiSW1nQiIpOw0KLQkJfQ0KLQl9DQotDQotCWlmIChwRG93bkljb24pDQotCXsNCi0JCWlmIChDUERGX0RpY3Rpb25hcnkqIHBJbWFnZURpY3QgPSBwRG93bkljb24tPkdldERpY3QoKSkNCi0JCXsNCi0JCQlpZiAocEltYWdlRGljdC0+R2V0U3RyaW5nKCJOYW1lIikuSXNFbXB0eSgpKQ0KLQkJCQlwSW1hZ2VEaWN0LT5TZXRBdFN0cmluZygiTmFtZSIsICJJbWdDIik7DQotCQl9DQotCX0NCi0NCi0JQ1BERl9JY29uRml0IGljb25GaXQgPSBwQ29udHJvbC0+R2V0SWNvbkZpdCgpOw0KLQ0KLS8vIAlBU1NFUlQodGhpcy0+bV9wQmFzZUZvcm0gIT0gTlVMTCk7DQotCUFTU0VSVCh0aGlzLT5tX3BJbnRlckZvcm0gIT0gTlVMTCk7DQotCUNQREZTREtfRG9jdW1lbnQqIHBEb2MgPSBtX3BJbnRlckZvcm0tPkdldERvY3VtZW50KCk7DQotCUFTU0VSVChwRG9jICE9IE5VTEwpOw0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcERvYy0+R2V0RW52KCk7DQotDQotIAlDQkFfRm9udE1hcCBGb250TWFwKHRoaXMscEVudi0+R2V0U3lzSGFuZGxlcigpKTsvLywgSVN5c3RlbUhhbmRsZTo6R2V0U3lzdGVtSGFuZGxlcihtX3BCYXNlRm9ybS0+R2V0RW52KCkpKTsNCi0JRm9udE1hcC5Jbml0aWFsKCk7DQotDQotCUZvbnRNYXAuU2V0QVBUeXBlKCJOIik7DQotDQotCUNGWF9CeXRlU3RyaW5nIGNzQVAgPSBDUFdMX1V0aWxzOjpHZXRSZWN0RmlsbEFwcFN0cmVhbShyY1dpbmRvdywgY3JCYWNrZ3JvdW5kKSArIA0KLQkJQ1BXTF9VdGlsczo6R2V0Qm9yZGVyQXBwU3RyZWFtKHJjV2luZG93LCBmQm9yZGVyV2lkdGgsIGNyQm9yZGVyLCBjckxlZnRUb3AsIGNyUmlnaHRCb3R0b20sIG5Cb3JkZXJTdHlsZSwgZHNCb3JkZXIpICsNCi0JCUNQV0xfVXRpbHM6OkdldFB1c2hCdXR0b25BcHBTdHJlYW0oaWNvbkZpdC5HZXRGaXR0aW5nQm91bmRzKCkgPyByY1dpbmRvdyA6IHJjQ2xpZW50LCAmRm9udE1hcCwgcE5vcm1hbEljb24sIGljb25GaXQsIGNzTm9ybWFsQ2FwdGlvbiwgY3JUZXh0LCBmRm9udFNpemUsIG5MYXlvdXQpOw0KLQ0KLQlXcml0ZUFwcGVhcmFuY2UoIk4iLCBHZXRSb3RhdGVkUmVjdCgpLCBHZXRNYXRyaXgoKSwgY3NBUCk7DQotCWlmIChwTm9ybWFsSWNvbikNCi0JCUFkZEltYWdlVG9BcHBlYXJhbmNlKCJOIiwgcE5vcm1hbEljb24pOw0KLQ0KLQlDUERGX0Zvcm1Db250cm9sOjpIaWdobGlnaHRpbmdNb2RlIGVITE0gPSBwQ29udHJvbC0+R2V0SGlnaGxpZ2h0aW5nTW9kZSgpOw0KLQlpZiAoZUhMTSA9PSBDUERGX0Zvcm1Db250cm9sOjpQdXNoIHx8IGVITE0gPT0gQ1BERl9Gb3JtQ29udHJvbDo6VG9nZ2xlKQ0KLQl7DQotCQlpZiAoY3NSb2xsb3ZlckNhcHRpb24uSXNFbXB0eSgpICYmICFwUm9sbG92ZXJJY29uKQkJCQ0KLQkJew0KLQkJCWNzUm9sbG92ZXJDYXB0aW9uID0gY3NOb3JtYWxDYXB0aW9uOw0KLQkJCXBSb2xsb3Zlckljb24gPSBwTm9ybWFsSWNvbjsNCi0JCX0NCi0NCi0JCUZvbnRNYXAuU2V0QVBUeXBlKCJSIik7DQotDQotCQljc0FQID0gQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0ocmNXaW5kb3csIGNyQmFja2dyb3VuZCkgKyANCi0JCQkJQ1BXTF9VdGlsczo6R2V0Qm9yZGVyQXBwU3RyZWFtKHJjV2luZG93LCBmQm9yZGVyV2lkdGgsIGNyQm9yZGVyLCBjckxlZnRUb3AsIGNyUmlnaHRCb3R0b20sIG5Cb3JkZXJTdHlsZSwgZHNCb3JkZXIpICsNCi0JCQkJQ1BXTF9VdGlsczo6R2V0UHVzaEJ1dHRvbkFwcFN0cmVhbShpY29uRml0LkdldEZpdHRpbmdCb3VuZHMoKSA/IHJjV2luZG93IDogcmNDbGllbnQsICZGb250TWFwLCBwUm9sbG92ZXJJY29uLCBpY29uRml0LCBjc1JvbGxvdmVyQ2FwdGlvbiwgY3JUZXh0LCBmRm9udFNpemUsIG5MYXlvdXQpOw0KLQ0KLQkJV3JpdGVBcHBlYXJhbmNlKCJSIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVApOw0KLQkJaWYgKHBSb2xsb3Zlckljb24pDQotCQkJQWRkSW1hZ2VUb0FwcGVhcmFuY2UoIlIiLCBwUm9sbG92ZXJJY29uKTsNCi0NCi0JCWlmIChjc0Rvd25DYXB0aW9uLklzRW1wdHkoKSAmJiAhcERvd25JY29uKQ0KLQkJew0KLQkJCWNzRG93bkNhcHRpb24gPSBjc05vcm1hbENhcHRpb247DQotCQkJcERvd25JY29uID0gcE5vcm1hbEljb247DQotCQl9DQotDQotCQlzd2l0Y2ggKG5Cb3JkZXJTdHlsZSkNCi0JCXsNCi0JCWNhc2UgUEJTX0JFVkVMRUQ6DQotCQkJew0KLQkJCQlDUFdMX0NvbG9yIGNyVGVtcCA9IGNyTGVmdFRvcDsNCi0JCQkJY3JMZWZ0VG9wID0gY3JSaWdodEJvdHRvbTsNCi0JCQkJY3JSaWdodEJvdHRvbSA9IGNyVGVtcDsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIFBCU19JTlNFVDoNCi0JCQljckxlZnRUb3AgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDApOw0KLQkJCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQkJDQotCQlGb250TWFwLlNldEFQVHlwZSgiRCIpOw0KLQ0KLQkJY3NBUCA9IENQV0xfVXRpbHM6OkdldFJlY3RGaWxsQXBwU3RyZWFtKHJjV2luZG93LCBDUFdMX1V0aWxzOjpTdWJzdHJhY3RDb2xvcihjckJhY2tncm91bmQsMC4yNWYpKSArIA0KLQkJCUNQV0xfVXRpbHM6OkdldEJvcmRlckFwcFN0cmVhbShyY1dpbmRvdywgZkJvcmRlcldpZHRoLCBjckJvcmRlciwgY3JMZWZ0VG9wLCBjclJpZ2h0Qm90dG9tLCBuQm9yZGVyU3R5bGUsIGRzQm9yZGVyKSArIA0KLQkJCUNQV0xfVXRpbHM6OkdldFB1c2hCdXR0b25BcHBTdHJlYW0oaWNvbkZpdC5HZXRGaXR0aW5nQm91bmRzKCkgPyByY1dpbmRvdyA6IHJjQ2xpZW50LCAmRm9udE1hcCwgcERvd25JY29uLCBpY29uRml0LCBjc0Rvd25DYXB0aW9uLCBjclRleHQsIGZGb250U2l6ZSwgbkxheW91dCk7DQotDQotCQlXcml0ZUFwcGVhcmFuY2UoIkQiLCBHZXRSb3RhdGVkUmVjdCgpLCBHZXRNYXRyaXgoKSwgY3NBUCk7DQotCQlpZiAocERvd25JY29uKQ0KLQkJCUFkZEltYWdlVG9BcHBlYXJhbmNlKCJEIiwgcERvd25JY29uKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCVJlbW92ZUFwcGVhcmFuY2UoIkQiKTsNCi0JCVJlbW92ZUFwcGVhcmFuY2UoIlIiKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQREZTREtfV2lkZ2V0OjpSZXNldEFwcGVhcmFuY2VfQ2hlY2tCb3goKQ0KLXsNCi0JQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wgPSBHZXRGb3JtQ29udHJvbCgpOw0KLQlBU1NFUlQocENvbnRyb2wgIT0gTlVMTCk7DQotDQotDQotDQotCUNQV0xfQ29sb3IgY3JCYWNrZ3JvdW5kLCBjckJvcmRlciwgY3JUZXh0Ow0KLQkNCi0JaW50IGlDb2xvclR5cGU7DQotCUZYX0ZMT0FUIGZjWzRdOw0KLQ0KLQlwQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoaUNvbG9yVHlwZSwgZmMpOw0KLQlpZiAoaUNvbG9yVHlwZSA+IDApDQotCQljckJhY2tncm91bmQgPSBDUFdMX0NvbG9yKGlDb2xvclR5cGUsIGZjWzBdLCBmY1sxXSwgZmNbMl0sIGZjWzNdKTsNCi0NCi0JcENvbnRyb2wtPkdldE9yaWdpbmFsQm9yZGVyQ29sb3IoaUNvbG9yVHlwZSwgZmMpOw0KLQlpZiAoaUNvbG9yVHlwZSA+IDApDQotCQljckJvcmRlciA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOw0KLQ0KLQlGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpR2V0Qm9yZGVyV2lkdGgoKTsNCi0JRlhfSU5UMzIgbkJvcmRlclN0eWxlID0gMDsNCi0JQ1BXTF9EYXNoIGRzQm9yZGVyKDMsMCwwKTsNCi0JQ1BXTF9Db2xvciBjckxlZnRUb3AsY3JSaWdodEJvdHRvbTsNCi0NCi0Jc3dpdGNoIChHZXRCb3JkZXJTdHlsZSgpKQ0KLQl7DQotCWNhc2UgQkJTX0RBU0g6DQotCQluQm9yZGVyU3R5bGUgPSBQQlNfREFTSDsNCi0JCWRzQm9yZGVyID0gQ1BXTF9EYXNoKDMsIDMsIDApOw0KLQkJYnJlYWs7DQotCWNhc2UgQkJTX0JFVkVMRUQ6DQotCQluQm9yZGVyU3R5bGUgPSBQQlNfQkVWRUxFRDsNCi0JCWZCb3JkZXJXaWR0aCAqPSAyOw0KLQkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwxKTsNCi0JCWNyUmlnaHRCb3R0b20gPSBDUFdMX1V0aWxzOjpEZXZpZGVDb2xvcihjckJhY2tncm91bmQsMik7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfSU5TRVQ6DQotCQluQm9yZGVyU3R5bGUgPSBQQlNfSU5TRVQ7DQotCQlmQm9yZGVyV2lkdGggKj0gMjsNCi0JCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC41KTsNCi0JCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDAuNzUpOw0KLQkJYnJlYWs7DQotCWNhc2UgQkJTX1VOREVSTElORToNCi0JCW5Cb3JkZXJTdHlsZSA9IFBCU19VTkRFUkxJTkVEOw0KLQkJYnJlYWs7DQotCWRlZmF1bHQ6IA0KLQkJbkJvcmRlclN0eWxlID0gUEJTX1NPTElEOw0KLQkJYnJlYWs7DQotCX0NCi0NCi0JQ1BERl9SZWN0IHJjV2luZG93ID0gR2V0Um90YXRlZFJlY3QoKTsNCi0JQ1BERl9SZWN0IHJjQ2xpZW50ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmNXaW5kb3csZkJvcmRlcldpZHRoKTsNCi0NCi0JQ1BERl9EZWZhdWx0QXBwZWFyYW5jZSBkYSA9IHBDb250cm9sLT5HZXREZWZhdWx0QXBwZWFyYW5jZSgpOw0KLQlpZiAoZGEuSGFzQ29sb3IoKSkNCi0Jew0KLQkJZGEuR2V0Q29sb3IoaUNvbG9yVHlwZSwgZmMpOw0KLQkJY3JUZXh0ID0gQ1BXTF9Db2xvcihpQ29sb3JUeXBlLCBmY1swXSwgZmNbMV0sIGZjWzJdLCBmY1szXSk7DQotCX0NCi0NCi0JRlhfSU5UMzIgblN0eWxlID0gMDsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgY3NXQ2FwdGlvbiA9IHBDb250cm9sLT5HZXROb3JtYWxDYXB0aW9uKCk7DQotCWlmIChjc1dDYXB0aW9uLkdldExlbmd0aCgpID4gMCkNCi0Jew0KLQkJc3dpdGNoIChjc1dDYXB0aW9uWzBdKQ0KLQkJew0KLQkJY2FzZSBMJ2wnOg0KLQkJCW5TdHlsZSA9IFBDU19DSVJDTEU7CQkJDQotCQkJYnJlYWs7DQotCQljYXNlIEwnOCc6DQotCQkJblN0eWxlID0gUENTX0NST1NTOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBMJ3UnOg0KLQkJCW5TdHlsZSA9IFBDU19ESUFNT05EOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBMJ24nOg0KLQkJCW5TdHlsZSA9IFBDU19TUVVBUkU7DQotCQkJYnJlYWs7DQotCQljYXNlIEwnSCc6DQotCQkJblN0eWxlID0gUENTX1NUQVI7DQotCQkJYnJlYWs7DQotCQlkZWZhdWx0OiAvL0wnNCcNCi0JCQluU3R5bGUgPSBQQ1NfQ0hFQ0s7DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQluU3R5bGUgPSBQQ1NfQ0hFQ0s7DQotCX0NCi0NCi0JQ0ZYX0J5dGVTdHJpbmcgY3NBUF9OX09OID0gQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0ocmNXaW5kb3csY3JCYWNrZ3JvdW5kKSArDQotCQlDUFdMX1V0aWxzOjpHZXRCb3JkZXJBcHBTdHJlYW0ocmNXaW5kb3csZkJvcmRlcldpZHRoLGNyQm9yZGVyLGNyTGVmdFRvcCxjclJpZ2h0Qm90dG9tLG5Cb3JkZXJTdHlsZSxkc0JvcmRlcik7DQotDQotCUNGWF9CeXRlU3RyaW5nIGNzQVBfTl9PRkYgPSBjc0FQX05fT047DQotDQotCXN3aXRjaCAobkJvcmRlclN0eWxlKQ0KLQl7DQotCWNhc2UgUEJTX0JFVkVMRUQ6DQotCQl7DQotCQkJQ1BXTF9Db2xvciBjclRlbXAgPSBjckxlZnRUb3A7DQotCQkJY3JMZWZ0VG9wID0gY3JSaWdodEJvdHRvbTsNCi0JCQljclJpZ2h0Qm90dG9tID0gY3JUZW1wOw0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgUEJTX0lOU0VUOg0KLQkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwKTsNCi0JCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOw0KLQkJYnJlYWs7DQotCX0NCi0NCi0JQ0ZYX0J5dGVTdHJpbmcgY3NBUF9EX09OID0gQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0ocmNXaW5kb3csQ1BXTF9VdGlsczo6U3Vic3RyYWN0Q29sb3IoY3JCYWNrZ3JvdW5kLDAuMjVmKSkgKyANCi0JCUNQV0xfVXRpbHM6OkdldEJvcmRlckFwcFN0cmVhbShyY1dpbmRvdyxmQm9yZGVyV2lkdGgsY3JCb3JkZXIsY3JMZWZ0VG9wLGNyUmlnaHRCb3R0b20sbkJvcmRlclN0eWxlLGRzQm9yZGVyKTsNCi0NCi0JQ0ZYX0J5dGVTdHJpbmcgY3NBUF9EX09GRiA9IGNzQVBfRF9PTjsNCi0NCi0JY3NBUF9OX09OICs9IENQV0xfVXRpbHM6OkdldENoZWNrQm94QXBwU3RyZWFtKHJjQ2xpZW50LG5TdHlsZSxjclRleHQpOw0KLQljc0FQX0RfT04gKz0gQ1BXTF9VdGlsczo6R2V0Q2hlY2tCb3hBcHBTdHJlYW0ocmNDbGllbnQsblN0eWxlLGNyVGV4dCk7DQotDQotCVdyaXRlQXBwZWFyYW5jZSgiTiIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBjc0FQX05fT04sIHBDb250cm9sLT5HZXRDaGVja2VkQVBTdGF0ZSgpKTsNCi0JV3JpdGVBcHBlYXJhbmNlKCJOIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVBfTl9PRkYsICJPZmYiKTsNCi0NCi0JV3JpdGVBcHBlYXJhbmNlKCJEIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVBfRF9PTiwgcENvbnRyb2wtPkdldENoZWNrZWRBUFN0YXRlKCkpOw0KLQlXcml0ZUFwcGVhcmFuY2UoIkQiLCBHZXRSb3RhdGVkUmVjdCgpLCBHZXRNYXRyaXgoKSwgY3NBUF9EX09GRiwgIk9mZiIpOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBjc0FTID0gR2V0QXBwU3RhdGUoKTsNCi0JaWYgKGNzQVMuSXNFbXB0eSgpKQ0KLQkJU2V0QXBwU3RhdGUoIk9mZiIpOw0KLX0NCi0NCi12b2lkIENQREZTREtfV2lkZ2V0OjpSZXNldEFwcGVhcmFuY2VfUmFkaW9CdXR0b24oKQ0KLXsNCi0JQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wgPSBHZXRGb3JtQ29udHJvbCgpOw0KLQlBU1NFUlQocENvbnRyb2wgIT0gTlVMTCk7DQotCQ0KLQ0KLQ0KLQlDUFdMX0NvbG9yIGNyQmFja2dyb3VuZCwgY3JCb3JkZXIsIGNyVGV4dDsNCi0JDQotCWludCBpQ29sb3JUeXBlOw0KLQlGWF9GTE9BVCBmY1s0XTsNCi0NCi0JcENvbnRyb2wtPkdldE9yaWdpbmFsQmFja2dyb3VuZENvbG9yKGlDb2xvclR5cGUsIGZjKTsNCi0JaWYgKGlDb2xvclR5cGUgPiAwKQ0KLQkJY3JCYWNrZ3JvdW5kID0gQ1BXTF9Db2xvcihpQ29sb3JUeXBlLCBmY1swXSwgZmNbMV0sIGZjWzJdLCBmY1szXSk7DQotDQotCXBDb250cm9sLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKGlDb2xvclR5cGUsIGZjKTsNCi0JaWYgKGlDb2xvclR5cGUgPiAwKQ0KLQkJY3JCb3JkZXIgPSBDUFdMX0NvbG9yKGlDb2xvclR5cGUsIGZjWzBdLCBmY1sxXSwgZmNbMl0sIGZjWzNdKTsNCi0NCi0JRlhfRkxPQVQgZkJvcmRlcldpZHRoID0gKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCk7DQotCUZYX0lOVDMyIG5Cb3JkZXJTdHlsZSA9IDA7DQotCUNQV0xfRGFzaCBkc0JvcmRlcigzLDAsMCk7DQotCUNQV0xfQ29sb3IgY3JMZWZ0VG9wLGNyUmlnaHRCb3R0b207DQotDQotCXN3aXRjaCAoR2V0Qm9yZGVyU3R5bGUoKSkNCi0Jew0KLQljYXNlIEJCU19EQVNIOg0KLQkJbkJvcmRlclN0eWxlID0gUEJTX0RBU0g7DQotCQlkc0JvcmRlciA9IENQV0xfRGFzaCgzLCAzLCAwKTsNCi0JCWJyZWFrOw0KLQljYXNlIEJCU19CRVZFTEVEOg0KLQkJbkJvcmRlclN0eWxlID0gUEJTX0JFVkVMRUQ7DQotCQlmQm9yZGVyV2lkdGggKj0gMjsNCi0JCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMSk7DQotCQljclJpZ2h0Qm90dG9tID0gQ1BXTF9VdGlsczo6RGV2aWRlQ29sb3IoY3JCYWNrZ3JvdW5kLDIpOw0KLQkJYnJlYWs7DQotCWNhc2UgQkJTX0lOU0VUOg0KLQkJbkJvcmRlclN0eWxlID0gUEJTX0lOU0VUOw0KLQkJZkJvcmRlcldpZHRoICo9IDI7DQotCQljckxlZnRUb3AgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDAuNSk7DQotCQljclJpZ2h0Qm90dG9tID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwLjc1KTsNCi0JCWJyZWFrOw0KLQljYXNlIEJCU19VTkRFUkxJTkU6DQotCQluQm9yZGVyU3R5bGUgPSBQQlNfVU5ERVJMSU5FRDsNCi0JCWJyZWFrOw0KLQlkZWZhdWx0OiANCi0JCW5Cb3JkZXJTdHlsZSA9IFBCU19TT0xJRDsNCi0JCWJyZWFrOw0KLQl9DQotDQotCUNQREZfUmVjdCByY1dpbmRvdyA9IEdldFJvdGF0ZWRSZWN0KCk7DQotCUNQREZfUmVjdCByY0NsaWVudCA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJjV2luZG93LCBmQm9yZGVyV2lkdGgpOw0KLQ0KLQlDUERGX0RlZmF1bHRBcHBlYXJhbmNlIGRhID0gcENvbnRyb2wtPkdldERlZmF1bHRBcHBlYXJhbmNlKCk7DQotCWlmIChkYS5IYXNDb2xvcigpKQ0KLQl7DQotCQlkYS5HZXRDb2xvcihpQ29sb3JUeXBlLCBmYyk7DQotCQljclRleHQgPSBDUFdMX0NvbG9yKGlDb2xvclR5cGUsIGZjWzBdLCBmY1sxXSwgZmNbMl0sIGZjWzNdKTsNCi0JfQ0KLQ0KLQlGWF9JTlQzMiBuU3R5bGUgPSAwOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBjc1dDYXB0aW9uID0gcENvbnRyb2wtPkdldE5vcm1hbENhcHRpb24oKTsNCi0JaWYgKGNzV0NhcHRpb24uR2V0TGVuZ3RoKCkgPiAwKQ0KLQl7DQotCQlzd2l0Y2ggKGNzV0NhcHRpb25bMF0pDQotCQl7DQotCQlkZWZhdWx0OiAvL0wnbCc6DQotCQkJblN0eWxlID0gUENTX0NJUkNMRTsJCQkNCi0JCQlicmVhazsNCi0JCWNhc2UgTCc4JzoNCi0JCQluU3R5bGUgPSBQQ1NfQ1JPU1M7DQotCQkJYnJlYWs7DQotCQljYXNlIEwndSc6DQotCQkJblN0eWxlID0gUENTX0RJQU1PTkQ7DQotCQkJYnJlYWs7DQotCQljYXNlIEwnbic6DQotCQkJblN0eWxlID0gUENTX1NRVUFSRTsNCi0JCQlicmVhazsNCi0JCWNhc2UgTCdIJzoNCi0JCQluU3R5bGUgPSBQQ1NfU1RBUjsNCi0JCQlicmVhazsNCi0JCWNhc2UgTCc0JzoNCi0JCQluU3R5bGUgPSBQQ1NfQ0hFQ0s7DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQluU3R5bGUgPSBQQ1NfQ0lSQ0xFOw0KLQl9DQotDQotCUNGWF9CeXRlU3RyaW5nIGNzQVBfTl9PTjsNCi0NCi0JQ1BERl9SZWN0IHJjQ2VudGVyID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QoQ1BXTF9VdGlsczo6R2V0Q2VudGVyU3F1YXJlKHJjV2luZG93KSwgMS4wZik7DQotCQ0KLQlpZiAoblN0eWxlID09IFBDU19DSVJDTEUpDQotCXsNCi0JCWlmIChuQm9yZGVyU3R5bGUgPT0gUEJTX0JFVkVMRUQpDQotCQl7DQotCQkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMSk7DQotCQkJY3JSaWdodEJvdHRvbSA9IENQV0xfVXRpbHM6OlN1YnN0cmFjdENvbG9yKGNyQmFja2dyb3VuZCwwLjI1Zik7DQotCQl9DQotCQllbHNlIGlmIChuQm9yZGVyU3R5bGUgPT0gUEJTX0lOU0VUKQ0KLQkJew0KLQkJCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC41Zik7DQotCQkJY3JSaWdodEJvdHRvbSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC43NWYpOw0KLQkJfQ0KLQ0KLQkJY3NBUF9OX09OID0gQ1BXTF9VdGlsczo6R2V0Q2lyY2xlRmlsbEFwcFN0cmVhbShyY0NlbnRlcixjckJhY2tncm91bmQpICsgDQotCQkJQ1BXTF9VdGlsczo6R2V0Q2lyY2xlQm9yZGVyQXBwU3RyZWFtKHJjQ2VudGVyLGZCb3JkZXJXaWR0aCxjckJvcmRlcixjckxlZnRUb3AsY3JSaWdodEJvdHRvbSxuQm9yZGVyU3R5bGUsZHNCb3JkZXIpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJY3NBUF9OX09OID0gQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0ocmNXaW5kb3csY3JCYWNrZ3JvdW5kKSArIA0KLQkJCUNQV0xfVXRpbHM6OkdldEJvcmRlckFwcFN0cmVhbShyY1dpbmRvdyxmQm9yZGVyV2lkdGgsY3JCb3JkZXIsY3JMZWZ0VG9wLGNyUmlnaHRCb3R0b20sbkJvcmRlclN0eWxlLGRzQm9yZGVyKTsNCi0JfQ0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBjc0FQX05fT0ZGID0gY3NBUF9OX09OOw0KLQ0KLQlzd2l0Y2ggKG5Cb3JkZXJTdHlsZSkNCi0Jew0KLQljYXNlIFBCU19CRVZFTEVEOg0KLQkJew0KLQkJCUNQV0xfQ29sb3IgY3JUZW1wID0gY3JMZWZ0VG9wOw0KLQkJCWNyTGVmdFRvcCA9IGNyUmlnaHRCb3R0b207DQotCQkJY3JSaWdodEJvdHRvbSA9IGNyVGVtcDsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIFBCU19JTlNFVDoNCi0JCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMCk7DQotCQljclJpZ2h0Qm90dG9tID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwxKTsNCi0JCWJyZWFrOw0KLQl9DQotDQotCUNGWF9CeXRlU3RyaW5nIGNzQVBfRF9PTjsNCi0NCi0JaWYgKG5TdHlsZSA9PSBQQ1NfQ0lSQ0xFKQ0KLQl7DQotCQlDUFdMX0NvbG9yIGNyQksgPSBDUFdMX1V0aWxzOjpTdWJzdHJhY3RDb2xvcihjckJhY2tncm91bmQsMC4yNWYpOw0KLQkJaWYgKG5Cb3JkZXJTdHlsZSA9PSBQQlNfQkVWRUxFRCkNCi0JCXsNCi0JCQljckxlZnRUb3AgPSBDUFdMX1V0aWxzOjpTdWJzdHJhY3RDb2xvcihjckJhY2tncm91bmQsMC4yNWYpOw0KLQkJCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLCAxKTsNCi0JCQljckJLID0gY3JCYWNrZ3JvdW5kOw0KLQkJfQ0KLQkJZWxzZSBpZiAobkJvcmRlclN0eWxlID09IFBCU19JTlNFVCkNCi0JCXsNCi0JCQljckxlZnRUb3AgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDApOw0KLQkJCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOw0KLQkJfQ0KLQ0KLQkJY3NBUF9EX09OID0gQ1BXTF9VdGlsczo6R2V0Q2lyY2xlRmlsbEFwcFN0cmVhbShyY0NlbnRlcixjckJLKQ0KLQkJCSsgQ1BXTF9VdGlsczo6R2V0Q2lyY2xlQm9yZGVyQXBwU3RyZWFtKHJjQ2VudGVyLGZCb3JkZXJXaWR0aCxjckJvcmRlcixjckxlZnRUb3AsY3JSaWdodEJvdHRvbSxuQm9yZGVyU3R5bGUsZHNCb3JkZXIpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJY3NBUF9EX09OID0gQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0ocmNXaW5kb3csQ1BXTF9VdGlsczo6U3Vic3RyYWN0Q29sb3IoY3JCYWNrZ3JvdW5kLDAuMjVmKSkgKyANCi0JCQlDUFdMX1V0aWxzOjpHZXRCb3JkZXJBcHBTdHJlYW0ocmNXaW5kb3csZkJvcmRlcldpZHRoLGNyQm9yZGVyLGNyTGVmdFRvcCxjclJpZ2h0Qm90dG9tLG5Cb3JkZXJTdHlsZSxkc0JvcmRlcik7CQkNCi0JfQ0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBjc0FQX0RfT0ZGID0gY3NBUF9EX09OOw0KLQ0KLQljc0FQX05fT04gKz0gQ1BXTF9VdGlsczo6R2V0UmFkaW9CdXR0b25BcHBTdHJlYW0ocmNDbGllbnQsblN0eWxlLGNyVGV4dCk7DQotCWNzQVBfRF9PTiArPSBDUFdMX1V0aWxzOjpHZXRSYWRpb0J1dHRvbkFwcFN0cmVhbShyY0NsaWVudCxuU3R5bGUsY3JUZXh0KTsNCi0NCi0JV3JpdGVBcHBlYXJhbmNlKCJOIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVBfTl9PTiwgcENvbnRyb2wtPkdldENoZWNrZWRBUFN0YXRlKCkpOw0KLQlXcml0ZUFwcGVhcmFuY2UoIk4iLCBHZXRSb3RhdGVkUmVjdCgpLCBHZXRNYXRyaXgoKSwgY3NBUF9OX09GRiwgIk9mZiIpOw0KLQ0KLQlXcml0ZUFwcGVhcmFuY2UoIkQiLCBHZXRSb3RhdGVkUmVjdCgpLCBHZXRNYXRyaXgoKSwgY3NBUF9EX09OLCBwQ29udHJvbC0+R2V0Q2hlY2tlZEFQU3RhdGUoKSk7DQotCVdyaXRlQXBwZWFyYW5jZSgiRCIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBjc0FQX0RfT0ZGLCAiT2ZmIik7DQotDQotCUNGWF9CeXRlU3RyaW5nIGNzQVMgPSBHZXRBcHBTdGF0ZSgpOw0KLQlpZiAoY3NBUy5Jc0VtcHR5KCkpDQotCQlTZXRBcHBTdGF0ZSgiT2ZmIik7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19XaWRnZXQ6OlJlc2V0QXBwZWFyYW5jZV9Db21ib0JveChGWF9MUENXU1RSIHNWYWx1ZSkNCi17DQotCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gR2V0Rm9ybUNvbnRyb2woKTsNCi0JQVNTRVJUKHBDb250cm9sICE9IE5VTEwpOw0KLQlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gcENvbnRyb2wtPkdldEZpZWxkKCk7DQotCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7DQotDQotCUNGWF9CeXRlVGV4dEJ1ZiBzQm9keSwgc0xpbmVzOw0KLQ0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotCUNQREZfUmVjdCByY0J1dHRvbiA9IHJjQ2xpZW50Ow0KLQlyY0J1dHRvbi5sZWZ0ID0gcmNCdXR0b24ucmlnaHQgLSAxMzsNCi0JcmNCdXR0b24uTm9ybWFsaXplKCk7DQotDQotCWlmIChJRlhfRWRpdCAqIHBFZGl0ID0gSUZYX0VkaXQ6Ok5ld0VkaXQoKSkNCi0Jew0KLQkJcEVkaXQtPkVuYWJsZVJlZnJlc2goRkFMU0UpOw0KLQ0KLQkJQVNTRVJUKHRoaXMtPm1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0JCUNQREZTREtfRG9jdW1lbnQqIHBEb2MgPSBtX3BJbnRlckZvcm0tPkdldERvY3VtZW50KCk7DQotCQlBU1NFUlQocERvYyAhPSBOVUxMKTsNCi0JCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jLT5HZXRFbnYoKTsNCi0JCUNCQV9Gb250TWFwIEZvbnRNYXAodGhpcyxwRW52LT5HZXRTeXNIYW5kbGVyKCkpOw0KLQkJRm9udE1hcC5Jbml0aWFsKCk7DQotCQlwRWRpdC0+U2V0Rm9udE1hcCgmRm9udE1hcCk7DQotDQotCQlDUERGX1JlY3QgcmNFZGl0ID0gcmNDbGllbnQ7DQotCQlyY0VkaXQucmlnaHQgPSByY0J1dHRvbi5sZWZ0Ow0KLQkJcmNFZGl0Lk5vcm1hbGl6ZSgpOw0KLQkJDQotCQlwRWRpdC0+U2V0UGxhdGVSZWN0KHJjRWRpdCk7DQotCQlwRWRpdC0+U2V0QWxpZ25tZW50VigxKTsNCi0NCi0JCUZYX0ZMT0FUIGZGb250U2l6ZSA9IHRoaXMtPkdldEZvbnRTaXplKCk7DQotCQlpZiAoSXNGbG9hdFplcm8oZkZvbnRTaXplKSkNCi0JCQlwRWRpdC0+U2V0QXV0b0ZvbnRTaXplKFRSVUUpOw0KLQkJZWxzZQ0KLQkJCXBFZGl0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOw0KLQkJDQotCQlwRWRpdC0+SW5pdGlhbGl6ZSgpOw0KLQkJDQotCQlpZiAoc1ZhbHVlKQ0KLQkJCXBFZGl0LT5TZXRUZXh0KHNWYWx1ZSk7DQotCQllbHNlDQotCQl7DQotCQkJRlhfSU5UMzIgbkN1clNlbCA9IHBGaWVsZC0+R2V0U2VsZWN0ZWRJbmRleCgwKTsNCi0NCi0JCQlpZiAobkN1clNlbCA8IDApDQotCQkJCXBFZGl0LT5TZXRUZXh0KChGWF9MUENXU1RSKXBGaWVsZC0+R2V0VmFsdWUoKSk7DQotCQkJZWxzZQ0KLQkJCQlwRWRpdC0+U2V0VGV4dCgoRlhfTFBDV1NUUilwRmllbGQtPkdldE9wdGlvbkxhYmVsKG5DdXJTZWwpKTsNCi0JCX0NCi0NCi0JCUNQREZfUmVjdCByY0NvbnRlbnQgPSBwRWRpdC0+R2V0Q29udGVudFJlY3QoKTsNCi0NCi0JCUNGWF9CeXRlU3RyaW5nIHNFZGl0ID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShwRWRpdCxDUERGX1BvaW50KDAuMGYsMC4wZikpOw0KLQkJaWYgKHNFZGl0LkdldExlbmd0aCgpID4gMCkNCi0JCXsNCi0JCQlzQm9keSA8PCAiL1R4IEJNQ1xuIiA8PCAicVxuIjsNCi0JCQlpZiAocmNDb250ZW50LldpZHRoKCkgPiByY0VkaXQuV2lkdGgoKSB8fA0KLQkJCQlyY0NvbnRlbnQuSGVpZ2h0KCkgPiByY0VkaXQuSGVpZ2h0KCkpDQotCQkJew0KLQkJCQlzQm9keSA8PCByY0VkaXQubGVmdCA8PCAiICIgPDwgcmNFZGl0LmJvdHRvbSA8PCAiICIgDQotCQkJCQk8PCByY0VkaXQuV2lkdGgoKSA8PCAiICIgPDwgcmNFZGl0LkhlaWdodCgpIDw8ICIgcmVcbldcbm5cbiI7DQotCQkJfQ0KLQ0KLQkJCUNQV0xfQ29sb3IgY3JUZXh0ID0gR2V0VGV4dFBXTENvbG9yKCk7CQ0KLQkJCXNCb2R5IDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclRleHQpIDw8IHNFZGl0IDw8ICJFVFxuIiA8PCAiUVxuRU1DXG4iOw0KLQkJfQ0KLQ0KLQkJSUZYX0VkaXQ6OkRlbEVkaXQocEVkaXQpOw0KLQl9DQotDQotCXNCb2R5IDw8IENQV0xfVXRpbHM6OkdldERyb3BCdXR0b25BcHBTdHJlYW0ocmNCdXR0b24pOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBzQVAgPSBHZXRCYWNrZ3JvdW5kQXBwU3RyZWFtKCkgKyBHZXRCb3JkZXJBcHBTdHJlYW0oKSArIHNMaW5lcy5HZXRCeXRlU3RyaW5nKCkgKyBzQm9keS5HZXRCeXRlU3RyaW5nKCk7DQotDQotCVdyaXRlQXBwZWFyYW5jZSgiTiIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBzQVApOw0KLX0NCi0NCi12b2lkIENQREZTREtfV2lkZ2V0OjpSZXNldEFwcGVhcmFuY2VfTGlzdEJveCgpDQotew0KLQlDUERGX0Zvcm1Db250cm9sKiBwQ29udHJvbCA9IEdldEZvcm1Db250cm9sKCk7DQotCUFTU0VSVChwQ29udHJvbCAhPSBOVUxMKTsNCi0JQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCA9IHBDb250cm9sLT5HZXRGaWVsZCgpOw0KLQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotDQotCUNGWF9CeXRlVGV4dEJ1ZiBzQm9keSwgc0xpbmVzOw0KLQ0KLQlpZiAoSUZYX0VkaXQgKiBwRWRpdCA9IElGWF9FZGl0OjpOZXdFZGl0KCkpDQotCXsNCi0JCXBFZGl0LT5FbmFibGVSZWZyZXNoKEZBTFNFKTsNCi0NCi0vLwkJQVNTRVJUKHRoaXMtPm1fcEJhc2VGb3JtICE9IE5VTEwpOw0KLQkJQVNTRVJUKHRoaXMtPm1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0JCUNQREZTREtfRG9jdW1lbnQqIHBEb2MgPSBtX3BJbnRlckZvcm0tPkdldERvY3VtZW50KCk7DQotCQlBU1NFUlQocERvYyAhPSBOVUxMKTsNCi0JCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jLT5HZXRFbnYoKTsNCi0NCi0JCUNCQV9Gb250TWFwIEZvbnRNYXAodGhpcyxwRW52LT5HZXRTeXNIYW5kbGVyKCkpOw0KLQkJRm9udE1hcC5Jbml0aWFsKCk7DQotCQlwRWRpdC0+U2V0Rm9udE1hcCgmRm9udE1hcCk7DQotDQotCQlwRWRpdC0+U2V0UGxhdGVSZWN0KENQREZfUmVjdChyY0NsaWVudC5sZWZ0LDAuMGYscmNDbGllbnQucmlnaHQsMC4wZikpOwkNCi0JCQ0KLQkJRlhfRkxPQVQgZkZvbnRTaXplID0gR2V0Rm9udFNpemUoKTsNCi0NCi0JCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQ0KLQkJCXBFZGl0LT5TZXRGb250U2l6ZSgxMi4wZik7DQotCQllbHNlDQotCQkJcEVkaXQtPlNldEZvbnRTaXplKGZGb250U2l6ZSk7DQotCQkNCi0JCXBFZGl0LT5Jbml0aWFsaXplKCk7DQotDQotCQlDRlhfQnl0ZVRleHRCdWYgc0xpc3Q7DQotCQlGWF9GTE9BVCBmeSA9IHJjQ2xpZW50LnRvcDsNCi0NCi0JCUZYX0lOVDMyIG5Ub3AgPSBwRmllbGQtPkdldFRvcFZpc2libGVJbmRleCgpOw0KLQkJRlhfSU5UMzIgbkNvdW50ID0gcEZpZWxkLT5Db3VudE9wdGlvbnMoKTsNCi0JCUZYX0lOVDMyIG5TZWxDb3VudCA9IHBGaWVsZC0+Q291bnRTZWxlY3RlZEl0ZW1zKCk7DQotDQotCQlmb3IgKEZYX0lOVDMyIGk9blRvcDsgaTxuQ291bnQ7IGkrKykNCi0JCXsNCi0JCQlGWF9CT09MIGJTZWxlY3RlZCA9IEZBTFNFOwkJCQkNCi0JCQlmb3IgKEZYX0lOVDMyIGo9MDsgajxuU2VsQ291bnQ7IGorKykNCi0JCQl7DQotCQkJCWlmIChwRmllbGQtPkdldFNlbGVjdGVkSW5kZXgoaikgPT0gaSkNCi0JCQkJew0KLQkJCQkJYlNlbGVjdGVkID0gVFJVRTsNCi0JCQkJCWJyZWFrOw0KLQkJCQl9DQotCQkJfQ0KLQ0KLQkJCXBFZGl0LT5TZXRUZXh0KChGWF9MUENXU1RSKXBGaWVsZC0+R2V0T3B0aW9uTGFiZWwoaSkpOw0KLQ0KLQkJCUNQREZfUmVjdCByY0NvbnRlbnQgPSBwRWRpdC0+R2V0Q29udGVudFJlY3QoKTsNCi0JCQlGWF9GTE9BVCBmSXRlbUhlaWdodCA9IHJjQ29udGVudC5IZWlnaHQoKTsNCi0NCi0JCQlpZiAoYlNlbGVjdGVkKQ0KLQkJCXsNCi0JCQkJQ1BERl9SZWN0IHJjSXRlbSA9IENQREZfUmVjdChyY0NsaWVudC5sZWZ0LGZ5LWZJdGVtSGVpZ2h0LHJjQ2xpZW50LnJpZ2h0LGZ5KTsNCi0JCQkJc0xpc3QgPDwgInFcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLDAsNTEuMGYvMjU1LjBmLDExMy4wZi8yNTUuMGYpLFRSVUUpDQotCQkJCQk8PCByY0l0ZW0ubGVmdCA8PCAiICIgPDwgcmNJdGVtLmJvdHRvbSA8PCAiICIgPDwgcmNJdGVtLldpZHRoKCkgPDwgIiAiIDw8IHJjSXRlbS5IZWlnaHQoKSA8PCAiIHJlIGZcbiIgPDwgIlFcbiI7DQotDQotCQkJCXNMaXN0IDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpLFRSVUUpIDw8IA0KLQkJCQkJQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShwRWRpdCxDUERGX1BvaW50KDAuMGYsZnkpKSA8PCAiRVRcbiI7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCUNQV0xfQ29sb3IgY3JUZXh0ID0gR2V0VGV4dFBXTENvbG9yKCk7DQotCQkJCXNMaXN0IDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclRleHQsVFJVRSkgPDwgDQotCQkJCUNQV0xfVXRpbHM6OkdldEVkaXRBcHBTdHJlYW0ocEVkaXQsQ1BERl9Qb2ludCgwLjBmLGZ5KSkgPDwgIkVUXG4iOw0KLQkJCX0NCi0NCi0JCQlmeSAtPSBmSXRlbUhlaWdodDsNCi0JCX0NCi0JCQkJCQ0KLQkJaWYgKHNMaXN0LkdldFNpemUoKSA+IDApDQotCQl7DQotCQkJc0JvZHkgPDwgIi9UeCBCTUNcbiIgPDwgInFcbiIgPDwgcmNDbGllbnQubGVmdCA8PCAiICIgPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgIiANCi0JCQkJCTw8IHJjQ2xpZW50LldpZHRoKCkgPDwgIiAiIDw8IHJjQ2xpZW50LkhlaWdodCgpIDw8ICIgcmVcbldcbm5cbiI7DQotCQkJc0JvZHkgPDwgc0xpc3QgPDwgIlFcbkVNQ1xuIjsNCi0JCX0NCi0NCi0JCUlGWF9FZGl0OjpEZWxFZGl0KHBFZGl0KTsNCi0JfQ0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBzQVAgPSBHZXRCYWNrZ3JvdW5kQXBwU3RyZWFtKCkgKyBHZXRCb3JkZXJBcHBTdHJlYW0oKSArIHNMaW5lcy5HZXRCeXRlU3RyaW5nKCkgKyBzQm9keS5HZXRCeXRlU3RyaW5nKCk7DQotDQotCVdyaXRlQXBwZWFyYW5jZSgiTiIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBzQVApOw0KLX0NCi0NCi12b2lkIENQREZTREtfV2lkZ2V0OjpSZXNldEFwcGVhcmFuY2VfVGV4dEZpZWxkKEZYX0xQQ1dTVFIgc1ZhbHVlKQ0KLXsNCi0JQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wgPSBHZXRGb3JtQ29udHJvbCgpOw0KLQlBU1NFUlQocENvbnRyb2wgIT0gTlVMTCk7DQotCUNQREZfRm9ybUZpZWxkKiBwRmllbGQgPSBwQ29udHJvbC0+R2V0RmllbGQoKTsNCi0JQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsNCi0NCi0JQ0ZYX0J5dGVUZXh0QnVmIHNCb2R5LCBzTGluZXM7DQotCQ0KLQlpZiAoSUZYX0VkaXQgKiBwRWRpdCA9IElGWF9FZGl0OjpOZXdFZGl0KCkpDQotCXsNCi0JCXBFZGl0LT5FbmFibGVSZWZyZXNoKEZBTFNFKTsNCi0NCi0vLwkJQVNTRVJUKHRoaXMtPm1fcEJhc2VGb3JtICE9IE5VTEwpOw0KLQkJQVNTRVJUKHRoaXMtPm1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0JCUNQREZTREtfRG9jdW1lbnQqIHBEb2MgPSBtX3BJbnRlckZvcm0tPkdldERvY3VtZW50KCk7DQotCQlBU1NFUlQocERvYyAhPSBOVUxMKTsNCi0JCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jLT5HZXRFbnYoKTsNCi0NCi0JCUNCQV9Gb250TWFwIEZvbnRNYXAodGhpcyxwRW52LT5HZXRTeXNIYW5kbGVyKCkpOy8vLCBJU3lzdGVtSGFuZGxlOjpHZXRTeXN0ZW1IYW5kbGVyKG1fcEJhc2VGb3JtLT5HZXRFbnYoKSkpOw0KLQkJRm9udE1hcC5Jbml0aWFsKCk7DQotCQlwRWRpdC0+U2V0Rm9udE1hcCgmRm9udE1hcCk7DQotDQotCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotCQlwRWRpdC0+U2V0UGxhdGVSZWN0KHJjQ2xpZW50KTsNCi0JCXBFZGl0LT5TZXRBbGlnbm1lbnRIKHBDb250cm9sLT5HZXRDb250cm9sQWxpZ25tZW50KCkpOw0KLQkJDQotCQlGWF9EV09SRCBkd0ZpZWxkRmxhZ3MgPSBwRmllbGQtPkdldEZpZWxkRmxhZ3MoKTsNCi0JCUZYX0JPT0wgYk11bHRpTGluZSA9IChkd0ZpZWxkRmxhZ3MgPj4gMTIpICYgMTsNCi0NCi0JCWlmIChiTXVsdGlMaW5lKQ0KLQkJew0KLQkJCXBFZGl0LT5TZXRNdWx0aUxpbmUoVFJVRSk7DQotCQkJcEVkaXQtPlNldEF1dG9SZXR1cm4oVFJVRSk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJcEVkaXQtPlNldEFsaWdubWVudFYoMSk7DQotCQl9DQotDQotCQlGWF9XT1JEIHN1YldvcmQgPSAwOw0KLQkJaWYgKChkd0ZpZWxkRmxhZ3MgPj4gMTMpICYgMSkNCi0JCXsNCi0JCQlzdWJXb3JkID0gJyonOw0KLQkJCXBFZGl0LT5TZXRQYXNzd29yZENoYXIoc3ViV29yZCk7DQotCQl9DQotDQotCQlpbnQgbk1heExlbiA9IHBGaWVsZC0+R2V0TWF4TGVuKCk7DQotCQlGWF9CT09MIGJDaGFyQXJyYXkgPSAoZHdGaWVsZEZsYWdzID4+IDI0KSAmIDE7DQotCQlGWF9GTE9BVCBmRm9udFNpemUgPSBHZXRGb250U2l6ZSgpOwkNCi0NCi0JCWlmIChuTWF4TGVuID4gMCkNCi0JCXsNCi0JCQlpZiAoYkNoYXJBcnJheSkNCi0JCQl7DQotCQkJCXBFZGl0LT5TZXRDaGFyQXJyYXkobk1heExlbik7DQotDQotCQkJCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQ0KLQkJCQl7DQotCQkJCQlmRm9udFNpemUgPSBDUFdMX0VkaXQ6OkdldENoYXJBcnJheUF1dG9Gb250U2l6ZShGb250TWFwLkdldFBERkZvbnQoMCkscmNDbGllbnQsbk1heExlbik7DQotCQkJCX0NCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJaWYgKHNWYWx1ZSkNCi0JCQkJCW5NYXhMZW4gPSB3Y3NsZW4oKGNvbnN0IHdjaGFyX3QqKXNWYWx1ZSk7IA0KLQkJCQlwRWRpdC0+U2V0TGltaXRDaGFyKG5NYXhMZW4pOw0KLQkJCX0NCi0JCX0NCi0NCi0JCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQ0KLQkJCXBFZGl0LT5TZXRBdXRvRm9udFNpemUoVFJVRSk7DQotCQllbHNlDQotCQkJcEVkaXQtPlNldEZvbnRTaXplKGZGb250U2l6ZSk7DQotDQotCQlwRWRpdC0+SW5pdGlhbGl6ZSgpOw0KLQkJDQotCQlpZiAoc1ZhbHVlKQ0KLQkJCXBFZGl0LT5TZXRUZXh0KHNWYWx1ZSk7DQotCQllbHNlDQotCQkJcEVkaXQtPlNldFRleHQoKEZYX0xQQ1dTVFIpcEZpZWxkLT5HZXRWYWx1ZSgpKTsNCi0NCi0JCUNQREZfUmVjdCByY0NvbnRlbnQgPSBwRWRpdC0+R2V0Q29udGVudFJlY3QoKTsNCi0NCi0JCUNGWF9CeXRlU3RyaW5nIHNFZGl0ID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShwRWRpdCxDUERGX1BvaW50KDAuMGYsMC4wZiksDQotCQkJCQkJCQkJCQkJCQkJCQlOVUxMLCFiQ2hhckFycmF5LHN1YldvcmQpOw0KLQ0KLQkJaWYgKHNFZGl0LkdldExlbmd0aCgpID4gMCkNCi0JCXsNCi0JCQlzQm9keSA8PCAiL1R4IEJNQ1xuIiA8PCAicVxuIjsNCi0JCQlpZiAocmNDb250ZW50LldpZHRoKCkgPiByY0NsaWVudC5XaWR0aCgpIHx8DQotCQkJCXJjQ29udGVudC5IZWlnaHQoKSA+IHJjQ2xpZW50LkhlaWdodCgpKQ0KLQkJCXsNCi0JCQkJc0JvZHkgPDwgcmNDbGllbnQubGVmdCA8PCAiICIgPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgIiANCi0JCQkJCTw8IHJjQ2xpZW50LldpZHRoKCkgPDwgIiAiIDw8IHJjQ2xpZW50LkhlaWdodCgpIDw8ICIgcmVcbldcbm5cbiI7DQotCQkJfQ0KLQkJCUNQV0xfQ29sb3IgY3JUZXh0ID0gR2V0VGV4dFBXTENvbG9yKCk7CQ0KLQkJCXNCb2R5IDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclRleHQpIDw8IHNFZGl0IDw8ICJFVFxuIiA8PCAiUVxuRU1DXG4iOw0KLQkJfQ0KLQ0KLQkJaWYgKGJDaGFyQXJyYXkpDQotCQl7DQotCQkJc3dpdGNoIChHZXRCb3JkZXJTdHlsZSgpKQ0KLQkJCXsNCi0JCQljYXNlIEJCU19TT0xJRDoNCi0JCQkJew0KLQkJCQkJQ0ZYX0J5dGVTdHJpbmcgc0NvbG9yID0gQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oR2V0Qm9yZGVyUFdMQ29sb3IoKSxGQUxTRSk7DQotCQkJCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkNCi0JCQkJCXsNCi0JCQkJCQlzTGluZXMgPDwgInFcbiIgPDwgR2V0Qm9yZGVyV2lkdGgoKSA8PCAiIHdcbiIgDQotCQkJCQkJCTw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldEJvcmRlclBXTENvbG9yKCksRkFMU0UpIDw8ICIgMiBKIDAgalxuIjsJCQkJCQ0KLQ0KLQkJCQkJCWZvciAoRlhfSU5UMzIgaT0xO2k8bk1heExlbjtpKyspDQotCQkJCQkJew0KLQkJCQkJCQlzTGluZXMgPDwgcmNDbGllbnQubGVmdCArICgocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0KS9uTWF4TGVuKSppIDw8ICIgIg0KLQkJCQkJCQkJPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgbVxuIg0KLQkJCQkJCQkJPDwgcmNDbGllbnQubGVmdCArICgocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0KS9uTWF4TGVuKSppIDw8ICIgIg0KLQkJCQkJCQkJPDwgcmNDbGllbnQudG9wIDw8ICIgbCBTXG4iOwkJCQkJCQ0KLQkJCQkJCX0NCi0NCi0JCQkJCQlzTGluZXMgPDwgIlFcbiI7CQkNCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCQlicmVhazsNCi0JCQljYXNlIEJCU19EQVNIOg0KLQkJCQl7DQotCQkJCQlDRlhfQnl0ZVN0cmluZyBzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShHZXRCb3JkZXJQV0xDb2xvcigpLEZBTFNFKTsNCi0JCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQkJew0KLQkJCQkJCUNQV0xfRGFzaCBkc0JvcmRlciA9IENQV0xfRGFzaCgzLCAzLCAwKTsNCi0NCi0JCQkJCQlzTGluZXMgPDwgInFcbiIgPDwgR2V0Qm9yZGVyV2lkdGgoKSA8PCAiIHdcbiIgDQotCQkJCQkJCTw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldEJvcmRlclBXTENvbG9yKCksRkFMU0UpDQotCQkJCQkJCTw8ICJbIiA8PCBkc0JvcmRlci5uRGFzaCA8PCAiICIgDQotCQkJCQkJCTw8IGRzQm9yZGVyLm5HYXAgPDwgIl0gIiANCi0JCQkJCQkJPDwgZHNCb3JkZXIublBoYXNlIDw8ICIgZFxuIjsNCi0NCi0JCQkJCQlmb3IgKEZYX0lOVDMyIGk9MTtpPG5NYXhMZW47aSsrKQkJCQkJDQotCQkJCQkJew0KLQkJCQkJCQlzTGluZXMgPDwgcmNDbGllbnQubGVmdCArICgocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0KS9uTWF4TGVuKSppIDw8ICIgIg0KLQkJCQkJCQkJPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgbVxuIg0KLQkJCQkJCQkJPDwgcmNDbGllbnQubGVmdCArICgocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0KS9uTWF4TGVuKSppIDw8ICIgIg0KLQkJCQkJCQkJPDwgcmNDbGllbnQudG9wIDw8ICIgbCBTXG4iOwkNCi0JCQkJCQl9DQotDQotCQkJCQkJc0xpbmVzIDw8ICJRXG4iOw0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJCWJyZWFrOw0KLQkJCX0NCi0JCX0NCi0NCi0JCUlGWF9FZGl0OjpEZWxFZGl0KHBFZGl0KTsNCi0JfQ0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBzQVAgPSBHZXRCYWNrZ3JvdW5kQXBwU3RyZWFtKCkgKyBHZXRCb3JkZXJBcHBTdHJlYW0oKSArIHNMaW5lcy5HZXRCeXRlU3RyaW5nKCkgKyBzQm9keS5HZXRCeXRlU3RyaW5nKCk7DQotCVdyaXRlQXBwZWFyYW5jZSgiTiIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBzQVApOw0KLX0NCi0NCi1DUERGX1JlY3QgQ1BERlNES19XaWRnZXQ6OkdldENsaWVudFJlY3QoKSBjb25zdA0KLXsNCi0JQ1BERl9SZWN0IHJjV2luZG93ID0gR2V0Um90YXRlZFJlY3QoKTsNCi0JRlhfRkxPQVQgZkJvcmRlcldpZHRoID0gKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCk7DQotCXN3aXRjaCAoR2V0Qm9yZGVyU3R5bGUoKSkNCi0Jew0KLQljYXNlIEJCU19CRVZFTEVEOg0KLQljYXNlIEJCU19JTlNFVDoNCi0JCWZCb3JkZXJXaWR0aCAqPSAyLjBmOw0KLQkJYnJlYWs7DQotCX0NCi0NCi0JcmV0dXJuIENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJjV2luZG93LCBmQm9yZGVyV2lkdGgpOw0KLX0NCi0NCi1DUERGX1JlY3QgQ1BERlNES19XaWRnZXQ6OkdldFJvdGF0ZWRSZWN0KCkgY29uc3QNCi17DQotCUNQREZfUmVjdCByZWN0QW5ub3QgPSBHZXRSZWN0KCk7DQotCUZYX0ZMT0FUIGZXaWR0aCA9IHJlY3RBbm5vdC5yaWdodCAtIHJlY3RBbm5vdC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gcmVjdEFubm90LnRvcCAtIHJlY3RBbm5vdC5ib3R0b207DQotDQotCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gR2V0Rm9ybUNvbnRyb2woKTsNCi0JQVNTRVJUKHBDb250cm9sICE9IE5VTEwpOw0KLQ0KLQlDUERGX1JlY3QgcmNQREZXaW5kb3c7DQotCXN3aXRjaChhYnMocENvbnRyb2wtPkdldFJvdGF0aW9uKCkgJSAzNjApKQ0KLQl7DQotCQljYXNlIDA6DQotCQljYXNlIDE4MDoNCi0JCWRlZmF1bHQ6DQotCQkJcmNQREZXaW5kb3cgPSBDUERGX1JlY3QoMCwgMCwgZldpZHRoLCBmSGVpZ2h0KTsJDQotCQkJYnJlYWs7DQotCQljYXNlIDkwOg0KLQkJY2FzZSAyNzA6DQotCQkJcmNQREZXaW5kb3cgPSBDUERGX1JlY3QoMCwgMCwgZkhlaWdodCwgZldpZHRoKTsNCi0JCQlicmVhazsNCi0JfQ0KLQ0KLQlyZXR1cm4gcmNQREZXaW5kb3c7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQREZTREtfV2lkZ2V0OjpHZXRCYWNrZ3JvdW5kQXBwU3RyZWFtKCkgY29uc3QNCi17DQotCUNQV0xfQ29sb3IgY3JCYWNrZ3JvdW5kID0gR2V0RmlsbFBXTENvbG9yKCk7DQotCWlmIChjckJhY2tncm91bmQubkNvbG9yVHlwZSAhPSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQpDQotCQlyZXR1cm4gQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0oR2V0Um90YXRlZFJlY3QoKSwgY3JCYWNrZ3JvdW5kKTsNCi0JZWxzZQ0KLQkJcmV0dXJuICIiOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUERGU0RLX1dpZGdldDo6R2V0Qm9yZGVyQXBwU3RyZWFtKCkgY29uc3QNCi17DQotCUNQREZfUmVjdCByY1dpbmRvdyA9IEdldFJvdGF0ZWRSZWN0KCk7DQotCUNQV0xfQ29sb3IgY3JCb3JkZXIgPSBHZXRCb3JkZXJQV0xDb2xvcigpOw0KLQlDUFdMX0NvbG9yIGNyQmFja2dyb3VuZCA9IEdldEZpbGxQV0xDb2xvcigpOw0KLQlDUFdMX0NvbG9yIGNyTGVmdFRvcCwgY3JSaWdodEJvdHRvbTsNCi0NCi0JRlhfRkxPQVQgZkJvcmRlcldpZHRoID0gKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCk7DQotCUZYX0lOVDMyIG5Cb3JkZXJTdHlsZSA9IDA7DQotCUNQV0xfRGFzaCBkc0JvcmRlcigzLDAsMCk7DQotDQotCXN3aXRjaCAoR2V0Qm9yZGVyU3R5bGUoKSkNCi0Jew0KLQljYXNlIEJCU19EQVNIOg0KLQkJbkJvcmRlclN0eWxlID0gUEJTX0RBU0g7DQotCQlkc0JvcmRlciA9IENQV0xfRGFzaCgzLCAzLCAwKTsNCi0JCWJyZWFrOw0KLQljYXNlIEJCU19CRVZFTEVEOg0KLQkJbkJvcmRlclN0eWxlID0gUEJTX0JFVkVMRUQ7DQotCQlmQm9yZGVyV2lkdGggKj0gMjsNCi0JCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDEpOw0KLQkJY3JSaWdodEJvdHRvbSA9IENQV0xfVXRpbHM6OkRldmlkZUNvbG9yKGNyQmFja2dyb3VuZCwgMik7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfSU5TRVQ6DQotCQluQm9yZGVyU3R5bGUgPSBQQlNfSU5TRVQ7DQotCQlmQm9yZGVyV2lkdGggKj0gMjsNCi0JCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDAuNSk7DQotCQljclJpZ2h0Qm90dG9tID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMC43NSk7DQotCQlicmVhazsNCi0JY2FzZSBCQlNfVU5ERVJMSU5FOg0KLQkJbkJvcmRlclN0eWxlID0gUEJTX1VOREVSTElORUQ7DQotCQlicmVhazsNCi0JZGVmYXVsdDogDQotCQluQm9yZGVyU3R5bGUgPSBQQlNfU09MSUQ7DQotCQlicmVhazsNCi0JfQ0KLQ0KLQlyZXR1cm4gQ1BXTF9VdGlsczo6R2V0Qm9yZGVyQXBwU3RyZWFtKHJjV2luZG93LCBmQm9yZGVyV2lkdGgsIGNyQm9yZGVyLCBjckxlZnRUb3AsIA0KLQkJY3JSaWdodEJvdHRvbSwgbkJvcmRlclN0eWxlLCBkc0JvcmRlcik7DQotfQ0KLQ0KLUNQREZfTWF0cml4IENQREZTREtfV2lkZ2V0OjpHZXRNYXRyaXgoKSBjb25zdA0KLXsNCi0JQ1BERl9NYXRyaXggbXQ7DQotCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gR2V0Rm9ybUNvbnRyb2woKTsNCi0JQVNTRVJUKHBDb250cm9sICE9IE5VTEwpOw0KLQ0KLQlDUERGX1JlY3QgcmNBbm5vdCA9IEdldFJlY3QoKTsNCi0JRlhfRkxPQVQgZldpZHRoID0gcmNBbm5vdC5yaWdodCAtIHJjQW5ub3QubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IHJjQW5ub3QudG9wIC0gcmNBbm5vdC5ib3R0b207DQotCQ0KLQ0KLQ0KLQlzd2l0Y2ggKGFicyhwQ29udHJvbC0+R2V0Um90YXRpb24oKSAlIDM2MCkpDQotCXsNCi0JCWNhc2UgMDoNCi0JCWRlZmF1bHQ6DQotCQkJbXQgPSBDUERGX01hdHJpeCgxLCAwLCAwLCAxLCAwLCAwKTsNCi0JCQlicmVhazsNCi0JCWNhc2UgOTA6DQotCQkJbXQgPSBDUERGX01hdHJpeCgwLCAxLCAtMSwgMCwgZldpZHRoLCAwKTsNCi0JCQlicmVhazsNCi0JCWNhc2UgMTgwOg0KLQkJCW10ID0gQ1BERl9NYXRyaXgoLTEsIDAsIDAsIC0xLCBmV2lkdGgsIGZIZWlnaHQpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSAyNzA6DQotCQkJbXQgPSBDUERGX01hdHJpeCgwLCAtMSwgMSwgMCwgMCwgZkhlaWdodCk7DQotCQkJYnJlYWs7DQotCX0NCi0NCi0JcmV0dXJuIG10Ow0KLX0NCi0NCi1DUFdMX0NvbG9yIENQREZTREtfV2lkZ2V0OjpHZXRUZXh0UFdMQ29sb3IoKSBjb25zdA0KLXsNCi0JQ1BXTF9Db2xvciBjclRleHQgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLCAwKTsNCi0NCi0JQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gR2V0Rm9ybUNvbnRyb2woKTsNCi0JQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EZWZhdWx0QXBwZWFyYW5jZSBkYSA9IHBGb3JtQ3RybC0+R2V0RGVmYXVsdEFwcGVhcmFuY2UoKTsNCi0JaWYgKGRhLkhhc0NvbG9yKCkpDQotCXsNCi0JCUZYX0lOVDMyIGlDb2xvclR5cGU7DQotCQlGWF9GTE9BVCBmY1s0XTsNCi0JCWRhLkdldENvbG9yKGlDb2xvclR5cGUsIGZjKTsNCi0JCWNyVGV4dCA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOw0KLQl9DQotDQotCXJldHVybiBjclRleHQ7DQotfQ0KLQ0KLUNQV0xfQ29sb3IgQ1BERlNES19XaWRnZXQ6OkdldEJvcmRlclBXTENvbG9yKCkgY29uc3QNCi17DQotCUNQV0xfQ29sb3IgY3JCb3JkZXI7DQotDQotCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7DQotCUFTU0VSVChwRm9ybUN0cmwgIT0gTlVMTCk7DQotDQotCUZYX0lOVDMyIGlDb2xvclR5cGU7DQotCUZYX0ZMT0FUIGZjWzRdOw0KLQlwRm9ybUN0cmwtPkdldE9yaWdpbmFsQm9yZGVyQ29sb3IoaUNvbG9yVHlwZSwgZmMpOw0KLQlpZiAoaUNvbG9yVHlwZSA+IDApDQotCQljckJvcmRlciA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOw0KLQ0KLQlyZXR1cm4gY3JCb3JkZXI7DQotfQ0KLQ0KLUNQV0xfQ29sb3IgQ1BERlNES19XaWRnZXQ6OkdldEZpbGxQV0xDb2xvcigpIGNvbnN0DQotew0KLQlDUFdMX0NvbG9yIGNyRmlsbDsNCi0NCi0JQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gR2V0Rm9ybUNvbnRyb2woKTsNCi0JQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsNCi0NCi0JRlhfSU5UMzIgaUNvbG9yVHlwZTsNCi0JRlhfRkxPQVQgZmNbNF07DQotCXBGb3JtQ3RybC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoaUNvbG9yVHlwZSwgZmMpOw0KLQlpZiAoaUNvbG9yVHlwZSA+IDApDQotCQljckZpbGwgPSBDUFdMX0NvbG9yKGlDb2xvclR5cGUsIGZjWzBdLCBmY1sxXSwgZmNbMl0sIGZjWzNdKTsNCi0NCi0JcmV0dXJuIGNyRmlsbDsNCi19DQotDQotdm9pZCBDUERGU0RLX1dpZGdldDo6QWRkSW1hZ2VUb0FwcGVhcmFuY2UoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNBUFR5cGUsIENQREZfU3RyZWFtKiBwSW1hZ2UpDQotew0KLQlBU1NFUlQocEltYWdlICE9IE5VTEwpOw0KLQ0KLQlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOw0KLQ0KLQlDUERGX0RvY3VtZW50KiBwRG9jID0gbV9wUGFnZVZpZXctPkdldFBERkRvY3VtZW50KCk7Ly9wRG9jdW1lbnQtPkdldERvY3VtZW50KCk7DQotCUFTU0VSVChwRG9jICE9IE5VTEwpOw0KLQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBBUERpY3QgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJBUCIpOw0KLQlBU1NFUlQocEFQRGljdCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9TdHJlYW0qIHBTdHJlYW0gPSBwQVBEaWN0LT5HZXRTdHJlYW0oc0FQVHlwZSk7DQotCUFTU0VSVChwU3RyZWFtICE9IE5VTEwpOw0KLQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBTdHJlYW1EaWN0ID0gcFN0cmVhbS0+R2V0RGljdCgpOw0KLQlBU1NFUlQocFN0cmVhbURpY3QgIT0gTlVMTCk7DQotDQotCUNGWF9CeXRlU3RyaW5nIHNJbWFnZUFsaWFzID0gIklNRyI7DQotDQotCWlmIChDUERGX0RpY3Rpb25hcnkqIHBJbWFnZURpY3QgPSBwSW1hZ2UtPkdldERpY3QoKSkNCi0Jew0KLQkJc0ltYWdlQWxpYXMgPSBwSW1hZ2VEaWN0LT5HZXRTdHJpbmcoIk5hbWUiKTsNCi0JCWlmIChzSW1hZ2VBbGlhcy5Jc0VtcHR5KCkpDQotCQkJc0ltYWdlQWxpYXMgPSAiSU1HIjsNCi0JfQkNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwU3RyZWFtUmVzTGlzdCA9IHBTdHJlYW1EaWN0LT5HZXREaWN0KCJSZXNvdXJjZXMiKTsNCi0JaWYgKCFwU3RyZWFtUmVzTGlzdCkNCi0Jew0KLQkJcFN0cmVhbVJlc0xpc3QgPSBGWF9ORVcgQ1BERl9EaWN0aW9uYXJ5KCk7DQotCQlwU3RyZWFtRGljdC0+U2V0QXQoIlJlc291cmNlcyIsIHBTdHJlYW1SZXNMaXN0KTsNCi0JfQ0KLQ0KLQlpZiAocFN0cmVhbVJlc0xpc3QpIA0KLQl7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBYT2JqZWN0ID0gRlhfTkVXIENQREZfRGljdGlvbmFyeTsJCQkNCi0JCXBYT2JqZWN0LT5TZXRBdFJlZmVyZW5jZShzSW1hZ2VBbGlhcywgcERvYywgcEltYWdlKTsNCi0JCXBTdHJlYW1SZXNMaXN0LT5TZXRBdCgiWE9iamVjdCIsIHBYT2JqZWN0KTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQREZTREtfV2lkZ2V0OjpSZW1vdmVBcHBlYXJhbmNlKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzQVBUeXBlKQ0KLXsNCi0JQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQW5ub3QtPm1fcEFubm90RGljdCAhPSBOVUxMKTsNCi0NCi0JaWYgKENQREZfRGljdGlvbmFyeSogcEFQRGljdCA9IG1fcEFubm90LT5tX3BBbm5vdERpY3QtPkdldERpY3QoIkFQIikpDQotCXsNCi0JCXBBUERpY3QtPlJlbW92ZUF0KHNBUFR5cGUpOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19XaWRnZXQ6Ok9uQUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIHR5cGUsIFBERlNES19GaWVsZEFjdGlvbiYgZGF0YSwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3KQ0KLXsNCi0JQ1BERl9BY3Rpb24gYWN0aW9uID0gR2V0QUFjdGlvbih0eXBlKTsNCi0NCi0JaWYgKGFjdGlvbiAmJiBhY3Rpb24uR2V0VHlwZSgpICE9IENQREZfQWN0aW9uOjpVbmtub3duKQ0KLQl7DQotIAkJQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50ID0gcFBhZ2VWaWV3LT5HZXRTREtEb2N1bWVudCgpOw0KLSAJCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotIA0KLSAJCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jdW1lbnQtPkdldEVudigpOw0KLSAJCUFTU0VSVChwRW52ICE9IE5VTEwpOw0KLQ0KLQkJQ1BERlNES19BY3Rpb25IYW5kbGVyKiBwQWN0aW9uSGFuZGxlciA9IHBFbnYtPkdldEFjdGlvbkhhbmRlcigpOy8qKENQREZTREtfQWN0aW9uSGFuZGxlciopcEFwcC0+R2V0QWN0aW9uSGFuZGxlcigpOyovDQotIAkJQVNTRVJUKHBBY3Rpb25IYW5kbGVyICE9IE5VTEwpOw0KLSANCi0gCQlyZXR1cm4gcEFjdGlvbkhhbmRsZXItPkRvQWN0aW9uX0ZpZWxkKGFjdGlvbiwgdHlwZSwgcERvY3VtZW50LCBHZXRGb3JtRmllbGQoKSwgZGF0YSk7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1DUERGX0FjdGlvbglDUERGU0RLX1dpZGdldDo6R2V0QUFjdGlvbihDUERGX0FBY3Rpb246OkFBY3Rpb25UeXBlIGVBQVQpDQotew0KLQlzd2l0Y2ggKGVBQVQpDQotCXsNCi0JY2FzZSBDUERGX0FBY3Rpb246OkN1cnNvckVudGVyOg0KLQljYXNlIENQREZfQUFjdGlvbjo6Q3Vyc29yRXhpdDoNCi0JY2FzZSBDUERGX0FBY3Rpb246OkJ1dHRvbkRvd246DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpCdXR0b25VcDoNCi0JY2FzZSBDUERGX0FBY3Rpb246OkdldEZvY3VzOg0KLQljYXNlIENQREZfQUFjdGlvbjo6TG9zZUZvY3VzOg0KLQljYXNlIENQREZfQUFjdGlvbjo6UGFnZU9wZW46DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpQYWdlQ2xvc2U6DQotCWNhc2UgQ1BERl9BQWN0aW9uOjpQYWdlVmlzaWJsZToNCi0JY2FzZSBDUERGX0FBY3Rpb246OlBhZ2VJbnZpc2libGU6DQotCQlyZXR1cm4gQ1BERlNES19Bbm5vdDo6R2V0QUFjdGlvbihlQUFUKTsNCi0JY2FzZSBDUERGX0FBY3Rpb246OktleVN0cm9rZToNCi0JY2FzZSBDUERGX0FBY3Rpb246OkZvcm1hdDoNCi0JY2FzZSBDUERGX0FBY3Rpb246OlZhbGlkYXRlOg0KLQljYXNlIENQREZfQUFjdGlvbjo6Q2FsY3VsYXRlOg0KLQkJew0KLQkJCUNQREZfRm9ybUZpZWxkKiBwRmllbGQgPSB0aGlzLT5HZXRGb3JtRmllbGQoKTsNCi0JCQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJCWlmIChDUERGX0FBY3Rpb24gYWEgPSBwRmllbGQtPkdldEFkZGl0aW9uYWxBY3Rpb24oKSkNCi0JCQkJcmV0dXJuIGFhLkdldEFjdGlvbihlQUFUKTsNCi0JCQllbHNlIA0KLQkJCQlyZXR1cm4gQ1BERlNES19Bbm5vdDo6R2V0QUFjdGlvbihlQUFUKTsNCi0JCX0NCi0JZGVmYXVsdDoNCi0JCXJldHVybiBOVUxMOw0KLQl9DQotDQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUERGU0RLX1dpZGdldDo6R2V0QWx0ZXJuYXRlTmFtZSgpIGNvbnN0DQotew0KLQlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIHBGb3JtRmllbGQtPkdldEFsdGVybmF0ZU5hbWUoKTsNCi19DQotDQotRlhfSU5UMzIJQ1BERlNES19XaWRnZXQ6OkdldEFwcGVhcmFuY2VBZ2UoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fbkFwcEFnZTsNCi19DQotDQotRlhfSU5UMzIgQ1BERlNES19XaWRnZXQ6OkdldFZhbHVlQWdlKCkgY29uc3QNCi17DQotCXJldHVybiBtX25WYWx1ZUFnZTsNCi19DQotDQotDQotRlhfQk9PTAlDUERGU0RLX1dpZGdldDo6SGl0VGVzdChGWF9GTE9BVCBwYWdlWCwgRlhfRkxPQVQgcGFnZVkpDQotew0KLQlDUERGX0Fubm90KiBwQW5ub3QgPSBHZXRQREZBbm5vdCgpOw0KLQlDRlhfRmxvYXRSZWN0IGFubm90UmVjdDsNCi0JcEFubm90LT5HZXRSZWN0KGFubm90UmVjdCk7DQotCWlmKGFubm90UmVjdC5Db250YWlucyhwYWdlWCwgcGFnZVkpKQ0KLQl7DQotCQlpZiAoIUlzVmlzaWJsZSgpKSByZXR1cm4gRkFMU0U7DQotCQkNCi0JCWludCBuRmllbGRGbGFncyA9IEdldEZpZWxkRmxhZ3MoKTsNCi0JCWlmICgobkZpZWxkRmxhZ3MgJiBGSUVMREZMQUdfUkVBRE9OTFkpID09IEZJRUxERkxBR19SRUFET05MWSkgDQotCQkJcmV0dXJuIEZBTFNFOw0KLQkJDQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUNQREZTREtfSW50ZXJGb3JtOjpDUERGU0RLX0ludGVyRm9ybShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQpDQotCTptX3BEb2N1bWVudChwRG9jdW1lbnQpLA0KLQltX3BJbnRlckZvcm0oTlVMTCksDQotCW1fYkNhbGN1bGF0ZShUUlVFKSwNCi0JbV9iQnVzeShGQUxTRSkNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0JbV9wSW50ZXJGb3JtID0gbmV3IENQREZfSW50ZXJGb3JtKG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLCBGQUxTRSk7DQotCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7DQotCW1fcEludGVyRm9ybS0+U2V0Rm9ybU5vdGlmeSh0aGlzKTsNCi0NCi0JZm9yKGludCBpPTA7IGk8NjsgaSsrKQ0KLQkJbV9iTmVlZEhpZ2h0bGlnaHRbaV0gPSBGQUxTRTsNCi0JbV9pSGlnaGxpZ2h0QWxwaGEgPSAwOw0KLX0NCi0NCi1DUERGU0RLX0ludGVyRm9ybTo6fkNQREZTREtfSW50ZXJGb3JtKCkNCi17DQotCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7DQotCWRlbGV0ZSBtX3BJbnRlckZvcm07DQotCW1fcEludGVyRm9ybSA9IE5VTEw7DQotDQotCW1fTWFwLlJlbW92ZUFsbCgpOw0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpEZXN0cm95KCkNCi17DQotCWRlbGV0ZSB0aGlzOw0KLX0NCi0NCi1DUERGX0ludGVyRm9ybSogQ1BERlNES19JbnRlckZvcm06OkdldEludGVyRm9ybSgpDQotew0KLQlyZXR1cm4gbV9wSW50ZXJGb3JtOw0KLX0NCi0NCi1DUERGU0RLX0RvY3VtZW50KiBDUERGU0RLX0ludGVyRm9ybTo6R2V0RG9jdW1lbnQoKQ0KLXsNCi0JcmV0dXJuIG1fcERvY3VtZW50Ow0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpIaWdobGlnaHRXaWRnZXRzKCkNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotQ1BERlNES19XaWRnZXQqIENQREZTREtfSW50ZXJGb3JtOjpHZXRTaWJsaW5nKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0LCBGWF9CT09MIGJOZXh0KSBjb25zdA0KLXsNCi0JQVNTRVJUKHBXaWRnZXQgIT0gTlVMTCk7DQotDQotCUNCQV9Bbm5vdEl0ZXJhdG9yKiBwSXRlcmF0b3IgPSBuZXcgQ0JBX0Fubm90SXRlcmF0b3IocFdpZGdldC0+R2V0UGFnZVZpZXcoKSwgIldpZGdldCIsICIiKTsNCi0JQVNTRVJUKHBJdGVyYXRvciAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19XaWRnZXQqIHBSZXQgPSBOVUxMOw0KLQ0KLQlpZiAoYk5leHQpDQotCQlwUmV0ID0gKENQREZTREtfV2lkZ2V0KilwSXRlcmF0b3ItPkdldE5leHRBbm5vdChwV2lkZ2V0KTsNCi0JZWxzZQ0KLQkJcFJldCA9IChDUERGU0RLX1dpZGdldCopcEl0ZXJhdG9yLT5HZXRQcmV2QW5ub3QocFdpZGdldCk7DQotDQotCXBJdGVyYXRvci0+UmVsZWFzZSgpOw0KLQkNCi0JcmV0dXJuIHBSZXQ7DQotDQotfQ0KLQ0KLUNQREZTREtfV2lkZ2V0KglDUERGU0RLX0ludGVyRm9ybTo6R2V0V2lkZ2V0KENQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sKSBjb25zdA0KLXsNCi0JaWYoIXBDb250cm9sIHx8ICFtX3BJbnRlckZvcm0pIHJldHVybiBOVUxMOw0KLQkNCi0JQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBOVUxMOw0KLQltX01hcC5Mb29rdXAocENvbnRyb2wsIHBXaWRnZXQpOw0KLQ0KLQlpZiAocFdpZGdldCkgcmV0dXJuIHBXaWRnZXQ7DQotDQotCUNQREZfRGljdGlvbmFyeSogcENvbnRyb2xEaWN0ID0gcENvbnRyb2wtPkdldFdpZGdldCgpOw0KLQlBU1NFUlQocENvbnRyb2xEaWN0ICE9IE5VTEwpOw0KLQ0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpOw0KLQ0KLQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZSA9IE5VTEw7DQotDQotCWlmIChDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBDb250cm9sRGljdC0+R2V0RGljdCgiUCIpKQ0KLQl7DQotCQlpbnQgblBhZ2VJbmRleCA9IHBEb2N1bWVudC0+R2V0UGFnZUluZGV4KHBQYWdlRGljdC0+R2V0T2JqTnVtKCkpOw0KLQkJaWYgKG5QYWdlSW5kZXggPj0gMCkNCi0JCXsNCi0JCQlwUGFnZSA9IG1fcERvY3VtZW50LT5HZXRQYWdlVmlldyhuUGFnZUluZGV4KTsNCi0JCX0NCi0JfQ0KLQ0KLQlpZiAoIXBQYWdlKSANCi0Jew0KLQkJaW50IG5QYWdlSW5kZXggPSBHZXRQYWdlSW5kZXhCeUFubm90RGljdChwRG9jdW1lbnQsIHBDb250cm9sRGljdCk7DQotCQlpZiAoblBhZ2VJbmRleCA+PSAwKQ0KLQkJew0KLQkJCXBQYWdlID0gbV9wRG9jdW1lbnQtPkdldFBhZ2VWaWV3KG5QYWdlSW5kZXgpOw0KLQkJfQ0KLQl9DQotDQotCWlmIChwUGFnZSkNCi0JCXJldHVybiAoQ1BERlNES19XaWRnZXQqKXBQYWdlLT5HZXRBbm5vdEJ5RGljdChwQ29udHJvbERpY3QpOw0KLQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCBDUERGU0RLX0ludGVyRm9ybTo6R2V0V2lkZ2V0cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpZWxkTmFtZSwgQ0ZYX1B0ckFycmF5JiB3aWRnZXRzKQ0KLXsNCi0JQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JZm9yIChpbnQgaT0wLHN6PW1fcEludGVyRm9ybS0+Q291bnRGaWVsZHMoc0ZpZWxkTmFtZSk7IGk8c3o7IGkrKykNCi0Jew0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBtX3BJbnRlckZvcm0tPkdldEZpZWxkKGksIHNGaWVsZE5hbWUpOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlHZXRXaWRnZXRzKHBGb3JtRmllbGQsIHdpZGdldHMpOwkNCi0JfQ0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpHZXRXaWRnZXRzKENQREZfRm9ybUZpZWxkKiBwRmllbGQsIENGWF9QdHJBcnJheSYgd2lkZ2V0cykNCi17DQotCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7DQotDQotCWZvciAoaW50IGk9MCxpc3o9cEZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGk8aXN6OyBpKyspDQotCXsNCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IHBGaWVsZC0+R2V0Q29udHJvbChpKTsNCi0JCUFTU0VSVChwRm9ybUN0cmwgIT0gTlVMTCk7DQotDQotCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IEdldFdpZGdldChwRm9ybUN0cmwpOw0KLQ0KLQkJaWYgKHBXaWRnZXQpDQotCQkJd2lkZ2V0cy5BZGQocFdpZGdldCk7DQotCX0NCi19DQotDQotaW50IENQREZTREtfSW50ZXJGb3JtOjpHZXRQYWdlSW5kZXhCeUFubm90RGljdChDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRGljdGlvbmFyeSogcEFubm90RGljdCkgY29uc3QNCi17DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotCUFTU0VSVChwQW5ub3REaWN0ICE9IE5VTEwpOw0KLQ0KLQlmb3IgKGludCBpPTAsc3o9cERvY3VtZW50LT5HZXRQYWdlQ291bnQoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ1BERl9EaWN0aW9uYXJ5KiBwUGFnZURpY3QgPSBwRG9jdW1lbnQtPkdldFBhZ2UoaSkpDQotCQl7CQkJDQotCQkJaWYgKENQREZfQXJyYXkqIHBBbm5vdHMgPSBwUGFnZURpY3QtPkdldEFycmF5KCJBbm5vdHMiKSkNCi0JCQl7DQotCQkJCWZvciAoaW50IGo9MCxqc3o9cEFubm90cy0+R2V0Q291bnQoKTsgajxqc3o7IGorKykNCi0JCQkJew0KLQkJCQkJQ1BERl9PYmplY3QqIHBEaWN0ID0gcEFubm90cy0+R2V0RWxlbWVudFZhbHVlKGopOw0KLQkJCQkJaWYgKHBBbm5vdERpY3QgPT0gcERpY3QpDQotCQkJCQl7DQotCQkJCQkJcmV0dXJuIGk7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIC0xOw0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpBZGRNYXAoQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wsIENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0KQ0KLXsNCi0JbV9NYXAuU2V0QXQocENvbnRyb2wsIHBXaWRnZXQpOw0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpSZW1vdmVNYXAoQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wpDQotew0KLQltX01hcC5SZW1vdmVLZXkocENvbnRyb2wpOw0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpFbmFibGVDYWxjdWxhdGUoRlhfQk9PTCBiRW5hYmxlZCkNCi17DQotCW1fYkNhbGN1bGF0ZSA9IGJFbmFibGVkOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpJc0NhbGN1bGF0ZUVuYWJsZWQoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fYkNhbGN1bGF0ZTsNCi19DQotDQotI2lmZGVmIF9XSU4zMg0KLUNQREZfU3RyZWFtKiBDUERGU0RLX0ludGVyRm9ybTo6TG9hZEltYWdlRnJvbUZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGaWxlKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQlDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKTsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9TdHJlYW0qIHBSZXRTdHJlYW0gPSBOVUxMOw0KLQ0KLQlpZiAoQ0ZYX0RJQml0bWFwKiBwQm1wID0gQ0ZYX1dpbmRvd3NESUI6OkxvYWRGcm9tRmlsZShzRmlsZSkpDQotCXsNCi0JCWludCBuV2lkdGggPSBwQm1wLT5HZXRXaWR0aCgpOw0KLQkJaW50IG5IZWlnaHQgPSBwQm1wLT5HZXRIZWlnaHQoKTsNCi0NCi0JCUNQREZfSW1hZ2UgSW1hZ2UocERvY3VtZW50KTsNCi0JCUltYWdlLlNldEltYWdlKHBCbXAsIEZBTFNFKTsNCi0JCUNQREZfU3RyZWFtKiBwSW1hZ2VTdHJlYW0gPSBJbWFnZS5HZXRTdHJlYW0oKTsNCi0JCWlmIChwSW1hZ2VTdHJlYW0pDQotCQl7DQotCQkJaWYgKHBJbWFnZVN0cmVhbS0+R2V0T2JqTnVtKCkgPT0gMCkNCi0JCQkJcERvY3VtZW50LT5BZGRJbmRpcmVjdE9iamVjdChwSW1hZ2VTdHJlYW0pOw0KLQ0KLQkJCUNQREZfRGljdGlvbmFyeSogcFN0cmVhbURpY3QgPSBuZXcgQ1BERl9EaWN0aW9uYXJ5KCk7DQotCQkJcFN0cmVhbURpY3QtPlNldEF0TmFtZSgiU3VidHlwZSIsICJGb3JtIik7DQotCQkJcFN0cmVhbURpY3QtPlNldEF0TmFtZSgiTmFtZSIsICJJTUciKTsNCi0JCQlDUERGX0FycmF5KiBwTWF0cml4ID0gbmV3IENQREZfQXJyYXkoKTsNCi0JCQlwU3RyZWFtRGljdC0+U2V0QXQoIk1hdHJpeCIsIHBNYXRyaXgpOw0KLQkJCXBNYXRyaXgtPkFkZEludGVnZXIoMSk7DQotCQkJcE1hdHJpeC0+QWRkSW50ZWdlcigwKTsNCi0JCQlwTWF0cml4LT5BZGRJbnRlZ2VyKDApOw0KLQkJCXBNYXRyaXgtPkFkZEludGVnZXIoMSk7DQotCQkJcE1hdHJpeC0+QWRkSW50ZWdlcigtbldpZHRoIC8gMik7DQotCQkJcE1hdHJpeC0+QWRkSW50ZWdlcigtbkhlaWdodCAvIDIpOw0KLQkJCUNQREZfRGljdGlvbmFyeSogcFJlc291cmNlID0gbmV3IENQREZfRGljdGlvbmFyeSgpOw0KLQkJCXBTdHJlYW1EaWN0LT5TZXRBdCgiUmVzb3VyY2VzIiwgcFJlc291cmNlKTsNCi0JCQlDUERGX0RpY3Rpb25hcnkqIHBYT2JqZWN0ID0gbmV3IENQREZfRGljdGlvbmFyeSgpOw0KLQkJCXBSZXNvdXJjZS0+U2V0QXQoIlhPYmplY3QiLCBwWE9iamVjdCk7DQotCQkJcFhPYmplY3QtPlNldEF0UmVmZXJlbmNlKCJJbWciLCBwRG9jdW1lbnQsIHBJbWFnZVN0cmVhbSk7DQotCQkJQ1BERl9BcnJheSogcFByb2NTZXQgPSBuZXcgQ1BERl9BcnJheSgpOw0KLQkJCXBSZXNvdXJjZS0+U2V0QXQoIlByb2NTZXQiLCBwUHJvY1NldCk7DQotCQkJcFByb2NTZXQtPkFkZE5hbWUoIlBERiIpOw0KLQkJCXBQcm9jU2V0LT5BZGROYW1lKCJJbWFnZUMiKTsNCi0JCQlwU3RyZWFtRGljdC0+U2V0QXROYW1lKCJUeXBlIiwgIlhPYmplY3QiKTsNCi0JCQlDUERGX0FycmF5KiBwQkJveCA9IG5ldyBDUERGX0FycmF5KCk7DQotCQkJcFN0cmVhbURpY3QtPlNldEF0KCJCQm94IiwgcEJCb3gpOw0KLQkJCXBCQm94LT5BZGRJbnRlZ2VyKDApOw0KLQkJCXBCQm94LT5BZGRJbnRlZ2VyKDApOw0KLQkJCXBCQm94LT5BZGRJbnRlZ2VyKG5XaWR0aCk7DQotCQkJcEJCb3gtPkFkZEludGVnZXIobkhlaWdodCk7DQotCQkJcFN0cmVhbURpY3QtPlNldEF0SW50ZWdlcigiRm9ybVR5cGUiLCAxKTsNCi0NCi0JCQlwUmV0U3RyZWFtID0gbmV3IENQREZfU3RyZWFtKE5VTEwsIDAsIE5VTEwpOw0KLQkJCUNGWF9CeXRlU3RyaW5nIGNzU3RyZWFtOw0KLQkJCWNzU3RyZWFtLkZvcm1hdCgicVxuJWQgMCAwICVkIDAgMCBjbVxuL0ltZyBEb1xuUSIsIG5XaWR0aCwgbkhlaWdodCk7DQotCQkJcFJldFN0cmVhbS0+SW5pdFN0cmVhbSgoRlhfQllURSopKEZYX0xQQ1NUUiljc1N0cmVhbSwgY3NTdHJlYW0uR2V0TGVuZ3RoKCksIHBTdHJlYW1EaWN0KTsNCi0JCQlwRG9jdW1lbnQtPkFkZEluZGlyZWN0T2JqZWN0KHBSZXRTdHJlYW0pOw0KLQkJfQ0KLQ0KLQkJZGVsZXRlIHBCbXA7DQotCX0NCi0NCi0JcmV0dXJuIHBSZXRTdHJlYW07DQotfQ0KLSNlbmRpZg0KLQ0KLXZvaWQgQ1BERlNES19JbnRlckZvcm06Ok9uQ2FsY3VsYXRlKENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOw0KLQlBU1NFUlQocEVudik7DQotCWlmKCFwRW52LT5Jc0pTSW5pdGlhdGVkKCkpDQotCQlyZXR1cm47DQotDQotCWlmIChtX2JCdXN5KSByZXR1cm47DQotDQotCW1fYkJ1c3kgPSBUUlVFOw0KLQ0KLQlpZiAodGhpcy0+SXNDYWxjdWxhdGVFbmFibGVkKCkpDQotCXsNCi0JCUlGWEpTX1J1bnRpbWUqIHBSdW50aW1lID0gbV9wRG9jdW1lbnQtPkdldEpzUnVudGltZSgpOw0KLQkJQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOw0KLQ0KLQkJcFJ1bnRpbWUtPlNldFJlYWRlckRvY3VtZW50KG1fcERvY3VtZW50KTsNCi0NCi0JCWludCBuU2l6ZSA9IG1fcEludGVyRm9ybS0+Q291bnRGaWVsZHNJbkNhbGN1bGF0aW9uT3JkZXIoKTsNCi0JCWZvciAoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQ0KLQkJew0KLQkJCWlmKENQREZfRm9ybUZpZWxkKiBwRmllbGQgPSBtX3BJbnRlckZvcm0tPkdldEZpZWxkSW5DYWxjdWxhdGlvbk9yZGVyKGkpKQ0KLQkJCXsNCi0vLwkJCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7DQotCQkJCWludCBuVHlwZSA9IHBGaWVsZC0+R2V0RmllbGRUeXBlKCk7DQotCQkJCWlmIChuVHlwZSA9PSBGSUVMRFRZUEVfQ09NQk9CT1ggfHwgblR5cGUgPT0gRklFTERUWVBFX1RFWFRGSUVMRCkNCi0JCQkJew0KLQkJCQkJQ1BERl9BQWN0aW9uIGFBY3Rpb24gPSBwRmllbGQtPkdldEFkZGl0aW9uYWxBY3Rpb24oKTsNCi0JCQkJCWlmIChhQWN0aW9uICYmIGFBY3Rpb24uQWN0aW9uRXhpc3QoQ1BERl9BQWN0aW9uOjpDYWxjdWxhdGUpKQ0KLQkJCQkJew0KLQkJCQkJCUNQREZfQWN0aW9uIGFjdGlvbiA9IGFBY3Rpb24uR2V0QWN0aW9uKENQREZfQUFjdGlvbjo6Q2FsY3VsYXRlKTsNCi0JCQkJCQlpZiAoYWN0aW9uKQ0KLQkJCQkJCXsNCi0JCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgY3NKUyA9IGFjdGlvbi5HZXRKYXZhU2NyaXB0KCk7DQotCQkJCQkJCWlmICghY3NKUy5Jc0VtcHR5KCkpDQotCQkJCQkJCXsNCi0JCQkJCQkJCUlGWEpTX0NvbnRleHQqIHBDb250ZXh0ID0gcFJ1bnRpbWUtPk5ld0NvbnRleHQoKTsNCi0JCQkJCQkJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JCQkJCQkJCQ0KLQkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc09sZFZhbHVlID0gcEZpZWxkLT5HZXRWYWx1ZSgpOw0KLQkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc1ZhbHVlID0gc09sZFZhbHVlOw0KLQkJCQkJCQkJRlhfQk9PTCBiUkMgPSBUUlVFOw0KLQkJCQkJCQkJcENvbnRleHQtPk9uRmllbGRfQ2FsY3VsYXRlKHBGb3JtRmllbGQsIHBGaWVsZCwgc1ZhbHVlLCBiUkMpOw0KLQkJCQkJCQkJDQotCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzSW5mbzsNCi0JCQkJCQkJCUZYX0JPT0wgYlJldCA9IHBDb250ZXh0LT5SdW5TY3JpcHQoY3NKUywgc0luZm8pOw0KLQkJCQkJCQkJcFJ1bnRpbWUtPlJlbGVhc2VDb250ZXh0KHBDb250ZXh0KTsNCi0JCQkJCQkJCQ0KLQkJCQkJCQkJaWYgKGJSZXQpDQotCQkJCQkJCQl7DQotCQkJCQkJCQkJaWYgKGJSQykNCi0JCQkJCQkJCQl7DQotCQkJCQkJCQkJCWlmIChzVmFsdWUuQ29tcGFyZShzT2xkVmFsdWUpICE9IDApDQotCQkJCQkJCQkJCQlwRmllbGQtPlNldFZhbHVlKHNWYWx1ZSwgVFJVRSk7DQotCQkJCQkJCQkJfQ0KLQkJCQkJCQkJfQ0KLQkJCQkJCQl9DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJDQotCX0NCi0NCi0JbV9iQnVzeSA9IEZBTFNFOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUERGU0RLX0ludGVyRm9ybTo6T25Gb3JtYXQoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIGludCBuQ29tbWl0S2V5LCBGWF9CT09MJiBiRm9ybWF0ZWQpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwRm9ybUZpZWxkLT5HZXRWYWx1ZSgpOw0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOw0KLQlBU1NFUlQocEVudik7DQotCWlmKCFwRW52LT5Jc0pTSW5pdGlhdGVkKCkpDQotCXsNCi0JCWJGb3JtYXRlZCA9IEZBTFNFOw0KLQkJcmV0dXJuIHNWYWx1ZTsNCi0JfSANCi0NCi0JSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSBtX3BEb2N1bWVudC0+R2V0SnNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0JDQotCXBSdW50aW1lLT5TZXRSZWFkZXJEb2N1bWVudChtX3BEb2N1bWVudCk7DQotDQotCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfQ09NQk9CT1gpDQotCXsNCi0JCWlmIChwRm9ybUZpZWxkLT5Db3VudFNlbGVjdGVkSXRlbXMoKSA+IDApDQotCQl7DQotCQkJaW50IGluZGV4ID0gcEZvcm1GaWVsZC0+R2V0U2VsZWN0ZWRJbmRleCgwKTsNCi0JCQlpZiAoaW5kZXggPj0gMCkNCi0JCQkJc1ZhbHVlID0gcEZvcm1GaWVsZC0+R2V0T3B0aW9uTGFiZWwoaW5kZXgpOw0KLQkJfQ0KLQl9DQotDQotCWJGb3JtYXRlZCA9IEZBTFNFOw0KLQ0KLQlDUERGX0FBY3Rpb24gYUFjdGlvbiA9IHBGb3JtRmllbGQtPkdldEFkZGl0aW9uYWxBY3Rpb24oKTsNCi0JaWYgKGFBY3Rpb24gIT0gTlVMTCAmJiBhQWN0aW9uLkFjdGlvbkV4aXN0KENQREZfQUFjdGlvbjo6Rm9ybWF0KSkgDQotCXsNCi0JCUNQREZfQWN0aW9uIGFjdGlvbiA9IGFBY3Rpb24uR2V0QWN0aW9uKENQREZfQUFjdGlvbjo6Rm9ybWF0KTsNCi0JCWlmIChhY3Rpb24pDQotCQl7CQkJDQotCQkJQ0ZYX1dpZGVTdHJpbmcgc2NyaXB0ID0gYWN0aW9uLkdldEphdmFTY3JpcHQoKTsNCi0JCQlpZiAoIXNjcmlwdC5Jc0VtcHR5KCkpDQotCQkJew0KLQkJCQlDRlhfV2lkZVN0cmluZyBWYWx1ZSA9IHNWYWx1ZTsNCi0NCi0JCQkJSUZYSlNfQ29udGV4dCogcENvbnRleHQgPSBwUnVudGltZS0+TmV3Q29udGV4dCgpOw0KLQkJCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotDQotCQkJCXBDb250ZXh0LT5PbkZpZWxkX0Zvcm1hdChuQ29tbWl0S2V5LCBwRm9ybUZpZWxkLCBWYWx1ZSwgVFJVRSk7DQotCQkJDQotCQkJCUNGWF9XaWRlU3RyaW5nIHNJbmZvOw0KLSAJCQkJRlhfQk9PTCBiUmV0ID0gcENvbnRleHQtPlJ1blNjcmlwdChzY3JpcHQsIHNJbmZvKTsNCi0JCQkJcFJ1bnRpbWUtPlJlbGVhc2VDb250ZXh0KHBDb250ZXh0KTsNCi0NCi0JCQkJaWYgKGJSZXQpDQotCQkJCXsNCi0JCQkJCXNWYWx1ZSA9IFZhbHVlOw0KLQkJCQkJYkZvcm1hdGVkID0gVFJVRTsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gc1ZhbHVlOw0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpSZXNldEZpZWxkQXBwZWFyYW5jZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgRlhfTFBDV1NUUiBzVmFsdWUsIEZYX0JPT0wgYlZhbHVlQ2hhbmdlZCkNCi17DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQlmb3IgKGludCBpPTAsc3o9cEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBpPHN6OyBpKyspDQotCXsNCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2woaSk7DQotCQlBU1NFUlQocEZvcm1DdHJsICE9IE5VTEwpOw0KLQ0KLQkJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0JCWlmKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gR2V0V2lkZ2V0KHBGb3JtQ3RybCkpDQotCQkJcFdpZGdldC0+UmVzZXRBcHBlYXJhbmNlKHNWYWx1ZSwgYlZhbHVlQ2hhbmdlZCk7DQotCX0NCi19DQotDQotdm9pZCBDUERGU0RLX0ludGVyRm9ybTo6VXBkYXRlRmllbGQoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQpDQotew0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JZm9yIChpbnQgaT0wLHN6PXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUN0cmwgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKGkpOw0KLQkJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsNCi0NCi0JCWlmKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gR2V0V2lkZ2V0KHBGb3JtQ3RybCkpDQotCQl7DQotCQkJQ1BERkRvY19FbnZpcm9ubWVudCAqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7DQotCQkJQ0ZGTF9JRm9ybUZpbGxlciogcElGb3JtRmlsbGVyID0gcEVudi0+R2V0SUZvcm1GaWxsZXIoKTsNCi0JCQkNCi0JCQlDUERGX1BhZ2UgKiBwUGFnZSA9IHBXaWRnZXQtPkdldFBERlBhZ2UoKTsNCi0JCQlDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3ID0gbV9wRG9jdW1lbnQtPkdldFBhZ2VWaWV3KHBQYWdlLEZBTFNFKTsNCi0NCi0JCQlGWF9SRUNUIHJjQkJveCA9IHBJRm9ybUZpbGxlci0+R2V0Vmlld0JCb3gocFBhZ2VWaWV3LCBwV2lkZ2V0KTsNCi0NCi0JCQlwRW52LT5GRklfSW52YWxpZGF0ZShwUGFnZSxyY0JCb3gubGVmdCwgcmNCQm94LnRvcCwgcmNCQm94LnJpZ2h0LCByY0JCb3guYm90dG9tKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpPbktleVN0cm9rZUNvbW1pdChDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIGNzVmFsdWUsIEZYX0JPT0wmIGJSQykNCi17DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLSAJQ1BERl9BQWN0aW9uIGFBY3Rpb24gPSBwRm9ybUZpZWxkLT5HZXRBZGRpdGlvbmFsQWN0aW9uKCk7DQotIAlpZiAoYUFjdGlvbiAhPSBOVUxMICYmIGFBY3Rpb24uQWN0aW9uRXhpc3QoQ1BERl9BQWN0aW9uOjpLZXlTdHJva2UpKSANCi0gCXsNCi0gCQlDUERGX0FjdGlvbiBhY3Rpb24gPSBhQWN0aW9uLkdldEFjdGlvbihDUERGX0FBY3Rpb246OktleVN0cm9rZSk7DQotIAkJaWYgKGFjdGlvbikNCi0gCQl7CQkJIA0KLSAJCQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotIAkJCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7DQotIAkJCUFTU0VSVChwRW52ICE9IE5VTEwpOw0KLQ0KLQkJCUNQREZTREtfQWN0aW9uSGFuZGxlciogcEFjdGlvbkhhbmRsZXIgPSBwRW52LT5HZXRBY3Rpb25IYW5kZXIoKTsNCi0JCQlBU1NFUlQocEFjdGlvbkhhbmRsZXIgIT0gTlVMTCk7DQotCQ0KLQkJCVBERlNES19GaWVsZEFjdGlvbiBmYTsNCi0JCQlmYS5iTW9kaWZpZXIgPSBwRW52LT5GRklfSXNDVFJMS2V5RG93bigwKTsNCi0gCQkJZmEuYlNoaWZ0ID0gcEVudi0+RkZJX0lzU0hJRlRLZXlEb3duKDApOw0KLQkJCWZhLnNWYWx1ZSA9IGNzVmFsdWU7DQotDQotICAgCQkJcEFjdGlvbkhhbmRsZXItPkRvQWN0aW9uX0ZpZWxkSmF2YVNjcmlwdChhY3Rpb24sIENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlLCANCi0gICAJCQkJbV9wRG9jdW1lbnQsIHBGb3JtRmllbGQsIGZhKTsNCi0gICAJCQliUkMgPSBmYS5iUkM7DQotIAkJfQ0KLSAJfQ0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpPblZhbGlkYXRlKENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCBDRlhfV2lkZVN0cmluZyYgY3NWYWx1ZSwgRlhfQk9PTCYgYlJDKQ0KLXsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotIAlDUERGX0FBY3Rpb24gYUFjdGlvbiA9IHBGb3JtRmllbGQtPkdldEFkZGl0aW9uYWxBY3Rpb24oKTsNCi0gCWlmIChhQWN0aW9uICE9IE5VTEwgJiYgYUFjdGlvbi5BY3Rpb25FeGlzdChDUERGX0FBY3Rpb246OlZhbGlkYXRlKSkgDQotIAl7DQotIAkJQ1BERl9BY3Rpb24gYWN0aW9uID0gYUFjdGlvbi5HZXRBY3Rpb24oQ1BERl9BQWN0aW9uOjpWYWxpZGF0ZSk7DQotCQlpZiAoYWN0aW9uKQ0KLSAJCXsJCQ0KLQkJCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0JCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOw0KLQkJCUFTU0VSVChwRW52ICE9IE5VTEwpOw0KLQkJCQ0KLQkJCUNQREZTREtfQWN0aW9uSGFuZGxlciogcEFjdGlvbkhhbmRsZXIgPSBwRW52LT5HZXRBY3Rpb25IYW5kZXIoKTsNCi0JCQlBU1NFUlQocEFjdGlvbkhhbmRsZXIgIT0gTlVMTCk7DQotDQotCQkJUERGU0RLX0ZpZWxkQWN0aW9uIGZhOw0KLQkJCWZhLmJNb2RpZmllciA9IHBFbnYtPkZGSV9Jc0NUUkxLZXlEb3duKDApOw0KLQkJCWZhLmJTaGlmdCA9IHBFbnYtPkZGSV9Jc1NISUZUS2V5RG93bigwKTsNCi0JCQlmYS5zVmFsdWUgPSBjc1ZhbHVlOw0KLQ0KLQkJCXBBY3Rpb25IYW5kbGVyLT5Eb0FjdGlvbl9GaWVsZEphdmFTY3JpcHQoYWN0aW9uLCBDUERGX0FBY3Rpb246OlZhbGlkYXRlLCBtX3BEb2N1bWVudCwgcEZvcm1GaWVsZCwgZmEpOw0KLQkJCWJSQyA9IGZhLmJSQzsNCi0gCSANCi0JCX0NCi0gCX0NCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gYWN0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotRlhfQk9PTCBDUERGU0RLX0ludGVyRm9ybTo6RG9BY3Rpb25fSGlkZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQ0KLXsNCi0JQVNTRVJUKGFjdGlvbiAhPSBOVUxMKTsNCi0NCi0JQ1BERl9BY3Rpb25GaWVsZHMgYWYgPSBhY3Rpb24uR2V0V2lkZ2V0cygpOw0KLQlDRlhfUHRyQXJyYXkgZmllbGRPYmplY3RzOw0KLQlhZi5HZXRBbGxGaWVsZHMoZmllbGRPYmplY3RzKTsNCi0JQ0ZYX1B0ckFycmF5IHdpZGdldEFycmF5Ow0KLQlDRlhfUHRyQXJyYXkgZmllbGRzOw0KLQlHZXRGaWVsZEZyb21PYmplY3RzKGZpZWxkT2JqZWN0cywgZmllbGRzKTsNCi0NCi0JRlhfQk9PTCBiSGlkZSA9IGFjdGlvbi5HZXRIaWRlU3RhdHVzKCk7DQotDQotCUZYX0JPT0wgYkNoYW5nZWQgPSBGQUxTRTsNCi0JDQotCWZvciAoaW50IGk9MCwgc3o9ZmllbGRzLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gKENQREZfRm9ybUZpZWxkKilmaWVsZHNbaV07DQotCQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQkNCi0JCWZvciAoaW50IGo9MCxqc3o9cEZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGo8anN6OyBqKyspDQotCQl7DQotCQkJQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wgPSBwRmllbGQtPkdldENvbnRyb2woaik7DQotCQkJQVNTRVJUKHBDb250cm9sICE9IE5VTEwpOw0KLQ0KLQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IEdldFdpZGdldChwQ29udHJvbCkpDQotCQkJew0KLQkJCQlpbnQgbkZsYWdzID0gcFdpZGdldC0+R2V0RmxhZ3MoKTsNCi0JCQkJaWYgKGJIaWRlKQ0KLQkJCQl7DQotCQkJCQluRmxhZ3MgJj0gKH5BTk5PVEZMQUdfSU5WSVNJQkxFKTsNCi0JCQkJCW5GbGFncyAmPSAofkFOTk9URkxBR19OT1ZJRVcpOw0KLQkJCQkJbkZsYWdzIHw9IChBTk5PVEZMQUdfSElEREVOKTsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsNCi0JCQkJCW5GbGFncyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOw0KLQkJCQkJbkZsYWdzICY9ICh+QU5OT1RGTEFHX0hJRERFTik7DQotCQkJCQluRmxhZ3MgJj0gKH5BTk5PVEZMQUdfTk9WSUVXKTsNCi0JCQkJfQ0KLQkJCQlwV2lkZ2V0LT5TZXRGbGFncyhuRmxhZ3MpOw0KLQ0KLSAJCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcFdpZGdldC0+R2V0UGFnZVZpZXcoKTsNCi0gCQkJCUFTU0VSVChwUGFnZVZpZXcgIT0gTlVMTCk7DQotIA0KLSAJCQkJcFBhZ2VWaWV3LT5VcGRhdGVWaWV3KHBXaWRnZXQpOw0KLQ0KLQkJCQliQ2hhbmdlZCA9IFRSVUU7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBiQ2hhbmdlZDsNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0ludGVyRm9ybTo6RG9BY3Rpb25fU3VibWl0Rm9ybShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQ0KLXsNCi0JQVNTRVJUKGFjdGlvbiAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc0Rlc3RpbmF0aW9uID0gYWN0aW9uLkdldEZpbGVQYXRoKCk7DQotCWlmIChzRGVzdGluYXRpb24uSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRGljdGlvbmFyeSogcEFjdGlvbkRpY3QgPSBhY3Rpb247DQotCWlmIChwQWN0aW9uRGljdC0+S2V5RXhpc3QoIkZpZWxkcyIpKQ0KLQl7DQotCQlDUERGX0FjdGlvbkZpZWxkcyBhZiA9IGFjdGlvbi5HZXRXaWRnZXRzKCk7DQotCQlGWF9EV09SRCBkd0ZsYWdzID0gYWN0aW9uLkdldEZsYWdzKCk7DQotCQkNCi0JCUNGWF9QdHJBcnJheSBmaWVsZE9iamVjdHM7DQotCQlhZi5HZXRBbGxGaWVsZHMoZmllbGRPYmplY3RzKTsNCi0JCUNGWF9QdHJBcnJheSBmaWVsZHM7DQotCQlHZXRGaWVsZEZyb21PYmplY3RzKGZpZWxkT2JqZWN0cywgZmllbGRzKTsNCi0JCQ0KLQkJaWYgKGZpZWxkcy5HZXRTaXplKCkgIT0gMCkNCi0JCXsNCi0JCQlGWF9CT09MIGJJbmNsdWRlT3JFeGNsdWRlID0gIShkd0ZsYWdzICYgMHgwMSk7DQotCQkJaWYgKG1fcEludGVyRm9ybS0+Q2hlY2tSZXF1aXJlZEZpZWxkcygmZmllbGRzLCBiSW5jbHVkZU9yRXhjbHVkZSkpDQotCQkJew0KLQkJCQlyZXR1cm4gRkFMU0U7DQotCQkJfQ0KLQkJCXJldHVybiBTdWJtaXRGaWVsZHMoc0Rlc3RpbmF0aW9uLCBmaWVsZHMsIGJJbmNsdWRlT3JFeGNsdWRlLCBGQUxTRSk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYgKCBtX3BJbnRlckZvcm0tPkNoZWNrUmVxdWlyZWRGaWVsZHMoKSkNCi0JCQl7DQotCQkJCXJldHVybiBGQUxTRTsNCi0JCQl9DQotDQotCQkJcmV0dXJuIFN1Ym1pdEZvcm0oc0Rlc3RpbmF0aW9uLCBGQUxTRSk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlpZiAoIG1fcEludGVyRm9ybS0+Q2hlY2tSZXF1aXJlZEZpZWxkcygpKQ0KLQkJew0KLQkJCXJldHVybiBGQUxTRTsNCi0JCX0NCi0NCi0JCXJldHVybiBTdWJtaXRGb3JtKHNEZXN0aW5hdGlvbiwgRkFMU0UpOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OlN1Ym1pdEZpZWxkcyhjb25zdCBDRlhfV2lkZVN0cmluZyYgY3NEZXN0aW5hdGlvbiwgY29uc3QgQ0ZYX1B0ckFycmF5JiBmaWVsZHMsDQotCQkJCQkJCQkJRlhfQk9PTCBiSW5jbHVkZU9yRXhjbHVkZSwgRlhfQk9PTCBiVXJsRW5jb2RlZCkNCi17DQotCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52ICE9IE5VTEwpOw0KLQ0KLQlDRlhfQnl0ZVRleHRCdWYgdGV4dEJ1ZjsNCi0JRXhwb3J0RmllbGRzVG9GREZUZXh0QnVmKGZpZWxkcywgYkluY2x1ZGVPckV4Y2x1ZGUsIHRleHRCdWYpOw0KLQ0KLQlGWF9MUEJZVEUgcEJ1ZmZlciA9IHRleHRCdWYuR2V0QnVmZmVyKCk7DQotCUZYX1NUUlNJWkUgbkJ1ZlNpemUgPSB0ZXh0QnVmLkdldExlbmd0aCgpOw0KLQkNCi0JaWYgKGJVcmxFbmNvZGVkKQ0KLQl7DQotCQlpZighRkRGVG9VUkxFbmNvZGVkRGF0YShwQnVmZmVyLCBuQnVmU2l6ZSkpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXBFbnYtPkpTX2RvY1N1Ym1pdEZvcm0ocEJ1ZmZlciwgbkJ1ZlNpemUsIChGWF9MUENXU1RSKWNzRGVzdGluYXRpb24pOw0KLQkNCi0JaWYgKGJVcmxFbmNvZGVkICYmIHBCdWZmZXIpDQotCXsNCi0JCUZYX0ZyZWUocEJ1ZmZlcik7DQotCQlwQnVmZmVyID0gTlVMTDsJDQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19JbnRlckZvcm06OkRvRkRGQnVmZmVyKENGWF9CeXRlU3RyaW5nIHNCdWZmZXIpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmIChDRkRGX0RvY3VtZW50ICpwRkRGRG9jdW1lbnQgPSBDRkRGX0RvY3VtZW50OjpQYXJzZU1lbW9yeSgoY29uc3QgdW5zaWduZWQgY2hhciAqKXNCdWZmZXIuR2V0QnVmZmVyKHNCdWZmZXIuR2V0TGVuZ3RoKCkpLCBzQnVmZmVyLkdldExlbmd0aCgpKSkNCi0JewkJCQkJCQ0KLQkJQ1BERl9EaWN0aW9uYXJ5KiBwUm9vdERpYyA9IHBGREZEb2N1bWVudC0+R2V0Um9vdCgpOw0KLQkJaWYocFJvb3REaWMpDQotCQl7DQotCQkJQ1BERl9EaWN0aW9uYXJ5ICogcEZERkRpY3Q9cFJvb3REaWMtPkdldERpY3QoIkZERiIpOw0KLQkJCWlmKHBGREZEaWN0KQ0KLQkJCXsJCQ0KLQkJCQlDUERGX0RpY3Rpb25hcnkgKiBwSlNEaWN0ID0gcEZERkRpY3QtPkdldERpY3QoIkphdmFTY3JpcHQiKTsNCi0JCQkJaWYocEpTRGljdCkNCi0JCQkJew0KLQkJCQkJQ0ZYX1dpZGVTdHJpbmcgY3NKUzsNCi0JCQkJDQotCQkJCQlDUERGX09iamVjdCogcEpTID0gcEpTRGljdC0+R2V0RWxlbWVudFZhbHVlKCJCZWZvcmUiKTsNCi0JCQkJCWlmIChwSlMgIT0gTlVMTCkNCi0JCQkJCXsNCi0JCQkJCQlpbnQgaVR5cGUgPSBwSlMtPkdldFR5cGUoKTsNCi0JCQkJCQlpZiAoaVR5cGUgPT0gUERGT0JKX1NUUklORykNCi0JCQkJCQkJY3NKUyA9IHBKU0RpY3QtPkdldFVuaWNvZGVUZXh0KCJCZWZvcmUiKTsNCi0JCQkJCQllbHNlIGlmIChpVHlwZSA9PSBQREZPQkpfU1RSRUFNKQ0KLQkJCQkJCQljc0pTID0gcEpTLT5HZXRVbmljb2RlVGV4dCgpOw0KLQkJCQkJfQ0KLQkJCQkJDQotCQkJCX0NCi0JCQl9DQotCQl9DQotCQlkZWxldGUgcEZERkRvY3VtZW50Ow0KLQl9DQotDQotCXNCdWZmZXIuUmVsZWFzZUJ1ZmZlcigpOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpGREZUb1VSTEVuY29kZWREYXRhKENGWF9XaWRlU3RyaW5nIGNzRkRGRmlsZSwgQ0ZYX1dpZGVTdHJpbmcgY3NUeHRGaWxlKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OkZERlRvVVJMRW5jb2RlZERhdGEoRlhfTFBCWVRFJiBwQnVmLCBGWF9TVFJTSVpFJiBuQnVmU2l6ZSkNCi17DQotIAlDRkRGX0RvY3VtZW50KiBwRkRGID0gQ0ZERl9Eb2N1bWVudDo6UGFyc2VNZW1vcnkocEJ1ZiwgbkJ1ZlNpemUpOw0KLSAJaWYgKHBGREYpDQotIAl7DQotIAkJQ1BERl9EaWN0aW9uYXJ5KiBwTWFpbkRpY3QgPSBwRkRGLT5HZXRSb290KCktPkdldERpY3QoIkZERiIpOw0KLSAJCWlmIChwTWFpbkRpY3QgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOw0KLSAJCQ0KLSAJCS8vIEdldCBmaWVsZHMNCi0gCQlDUERGX0FycmF5KiBwRmllbGRzID0gcE1haW5EaWN0LT5HZXRBcnJheSgiRmllbGRzIik7DQotIAkJaWYgKHBGaWVsZHMgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOw0KLQkJDQotCQlDRlhfQnl0ZVRleHRCdWYgZmRmRW5jb2RlZERhdGE7DQotDQotIAkJZm9yIChGWF9EV09SRCBpID0gMDsgaSA8IHBGaWVsZHMtPkdldENvdW50KCk7IGkgKyspIA0KLSAJCXsNCi0gCQkJQ1BERl9EaWN0aW9uYXJ5KiBwRmllbGQgPSBwRmllbGRzLT5HZXREaWN0KGkpOw0KLSAJCQlpZiAocEZpZWxkID09IE5VTEwpIGNvbnRpbnVlOw0KLSAJCQlDRlhfV2lkZVN0cmluZyBuYW1lOw0KLSAJCQluYW1lID0gcEZpZWxkLT5HZXRVbmljb2RlVGV4dCgiVCIpOw0KLSAJCQlDRlhfQnl0ZVN0cmluZyBuYW1lX2IgPSBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUobmFtZSk7DQotIAkJCUNGWF9CeXRlU3RyaW5nIGNzQlZhbHVlID0gcEZpZWxkLT5HZXRTdHJpbmcoIlYiKTsNCi0gCQkJQ0ZYX1dpZGVTdHJpbmcgY3NXVmFsdWUgPSBQREZfRGVjb2RlVGV4dChjc0JWYWx1ZSk7DQotIAkJCUNGWF9CeXRlU3RyaW5nIGNzVmFsdWVfYiA9IENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShjc1dWYWx1ZSk7DQotDQotCQkJZmRmRW5jb2RlZERhdGEgPSBmZGZFbmNvZGVkRGF0YTw8bmFtZV9iLkdldEJ1ZmZlcihuYW1lX2IuR2V0TGVuZ3RoKCkpOw0KLSAgCQkJbmFtZV9iLlJlbGVhc2VCdWZmZXIoKTsNCi0JCQlmZGZFbmNvZGVkRGF0YSA9IGZkZkVuY29kZWREYXRhPDwiPSI7DQotCQkJZmRmRW5jb2RlZERhdGEgPSBmZGZFbmNvZGVkRGF0YTw8Y3NWYWx1ZV9iLkdldEJ1ZmZlcihjc1ZhbHVlX2IuR2V0TGVuZ3RoKCkpOw0KLSAgCQkJY3NWYWx1ZV9iLlJlbGVhc2VCdWZmZXIoKTsNCi0gIAkJCWlmKGkgIT0gcEZpZWxkcy0+R2V0Q291bnQoKS0xKQ0KLSAgCQkJCWZkZkVuY29kZWREYXRhID0gZmRmRW5jb2RlZERhdGE8PCImIjsNCi0gCQl9DQotCQkNCi0JCW5CdWZTaXplID0gZmRmRW5jb2RlZERhdGEuR2V0TGVuZ3RoKCk7DQotCQlwQnVmID0gRlhfQWxsb2MoRlhfQllURSwgbkJ1ZlNpemUpOw0KLQkJaWYoIXBCdWYpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQkJRlhTWVNfbWVtY3B5KHBCdWYsIGZkZkVuY29kZWREYXRhLkdldEJ1ZmZlcigpLCBuQnVmU2l6ZSk7DQotIAkJDQotIAl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpFeHBvcnRGaWVsZHNUb0ZERkZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGREZGaWxlTmFtZSwgDQotCQkJCQkJCQkJCQkJIGNvbnN0IENGWF9QdHJBcnJheSYgZmllbGRzLCBGWF9CT09MIGJJbmNsdWRlT3JFeGNsdWRlKQ0KLXsNCi0JaWYgKHNGREZGaWxlTmFtZS5Jc0VtcHR5KCkpIHJldHVybiBGQUxTRTsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLSAJQ0ZERl9Eb2N1bWVudCogcEZERiA9IG1fcEludGVyRm9ybS0+RXhwb3J0VG9GREYobV9wRG9jdW1lbnQtPkdldFBhdGgoKSwoQ0ZYX1B0ckFycmF5JilmaWVsZHMsIGJJbmNsdWRlT3JFeGNsdWRlKTsNCi0gCWlmICghcEZERikgcmV0dXJuIEZBTFNFOw0KLSAJRlhfQk9PTCBiUmV0ID0gcEZERi0+V3JpdGVGaWxlKHNGREZGaWxlTmFtZS5VVEY4RW5jb2RlKCkpOyAvLyA9IEZBTFNFOy8vDQotCWRlbGV0ZSBwRkRGOw0KLQ0KLQlyZXR1cm4gYlJldDsNCi19DQotRlhfQk9PTCBDUERGU0RLX0ludGVyRm9ybTo6RXhwb3J0RmllbGRzVG9GREZUZXh0QnVmKGNvbnN0IENGWF9QdHJBcnJheSYgZmllbGRzLEZYX0JPT0wgYkluY2x1ZGVPckV4Y2x1ZGUsIENGWF9CeXRlVGV4dEJ1ZiYgdGV4dEJ1ZikNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0JDQotCUNGREZfRG9jdW1lbnQqIHBGREYgPSBtX3BJbnRlckZvcm0tPkV4cG9ydFRvRkRGKG1fcERvY3VtZW50LT5HZXRQYXRoKCksKENGWF9QdHJBcnJheSYpZmllbGRzLCBiSW5jbHVkZU9yRXhjbHVkZSk7DQotCWlmICghcEZERikgcmV0dXJuIEZBTFNFOw0KLQlGWF9CT09MIGJSZXQgPSBwRkRGLT5Xcml0ZUJ1Zih0ZXh0QnVmKTsgLy8gPSBGQUxTRTsvLw0KLQlkZWxldGUgcEZERjsNCi0JDQotCXJldHVybiBiUmV0Ow0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUERGU0RLX0ludGVyRm9ybTo6R2V0VGVtcG9yYXJ5RmlsZU5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGaWxlRXh0KQ0KLXsNCi0JQ0ZYX1dpZGVTdHJpbmcgc0ZpbGVOYW1lOw0KLQlyZXR1cm4gTCIiOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpTdWJtaXRGb3JtKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzRGVzdGluYXRpb24sIEZYX0JPT0wgYlVybEVuY29kZWQpDQotew0KLSAJaWYgKHNEZXN0aW5hdGlvbi5Jc0VtcHR5KCkpIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcERvY3VtZW50LT5HZXRFbnYoKTsNCi0JQVNTRVJUKHBFbnYgIT0gTlVMTCk7DQotDQotCWlmKE5VTEwgPT0gbV9wRG9jdW1lbnQpIHJldHVybiBGQUxTRTsNCi0JQ0ZYX1dpZGVTdHJpbmcgd3NQREZGaWxlUGF0aCA9IG1fcERvY3VtZW50LT5HZXRQYXRoKCk7DQotCQ0KLQlpZihOVUxMID09IG1fcEludGVyRm9ybSkgcmV0dXJuIEZBTFNFOw0KLQlDRkRGX0RvY3VtZW50KiBwRkRGRG9jID0gbV9wSW50ZXJGb3JtLT5FeHBvcnRUb0ZERih3c1BERkZpbGVQYXRoKTsNCi0JaWYgKE5VTEwgPT0gcEZERkRvYykgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDRlhfQnl0ZVRleHRCdWYgRmRmQnVmZmVyOw0KLQlGWF9CT09MIGJSZXQgPSBwRkRGRG9jLT5Xcml0ZUJ1ZihGZGZCdWZmZXIpOw0KLQlkZWxldGUgcEZERkRvYzsNCi0JaWYgKCFiUmV0KSByZXR1cm4gRkFMU0U7DQotDQotCUZYX0xQQllURSBwQnVmZmVyID0gRmRmQnVmZmVyLkdldEJ1ZmZlcigpOw0KLQlGWF9TVFJTSVpFIG5CdWZTaXplID0gRmRmQnVmZmVyLkdldExlbmd0aCgpOw0KLQkNCi0JaWYgKGJVcmxFbmNvZGVkKQ0KLQl7DQotCQlpZighRkRGVG9VUkxFbmNvZGVkRGF0YShwQnVmZmVyLCBuQnVmU2l6ZSkpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXBFbnYtPkpTX2RvY1N1Ym1pdEZvcm0ocEJ1ZmZlciwgbkJ1ZlNpemUsIChGWF9MUENXU1RSKXNEZXN0aW5hdGlvbik7DQotCQ0KLQlpZiAoYlVybEVuY29kZWQgJiYgcEJ1ZmZlcikNCi0Jew0KLQkJRlhfRnJlZShwQnVmZmVyKTsNCi0JCXBCdWZmZXIgPSBOVUxMOwkNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTAlDUERGU0RLX0ludGVyRm9ybTo6RXhwb3J0Rm9ybVRvRkRGRmlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZERkZpbGVOYW1lKQ0KLXsNCi0JaWYgKHNGREZGaWxlTmFtZS5Jc0VtcHR5KCkpIHJldHVybiBGQUxTRTsNCi0NCi0JQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDRkRGX0RvY3VtZW50KiBwRkRGID0gbV9wSW50ZXJGb3JtLT5FeHBvcnRUb0ZERihtX3BEb2N1bWVudC0+R2V0UGF0aCgpKTsNCi0JaWYgKCFwRkRGKSByZXR1cm4gRkFMU0U7DQotDQotCUZYX0JPT0wgYlJldCA9IHBGREYtPldyaXRlRmlsZShzRkRGRmlsZU5hbWUuVVRGOEVuY29kZSgpKTsNCi0JZGVsZXRlIHBGREY7DQotDQotCXJldHVybiBiUmV0Ow0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpFeHBvcnRGb3JtVG9GREZUZXh0QnVmKENGWF9CeXRlVGV4dEJ1ZiYgdGV4dEJ1ZikNCi17DQotDQotCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0JDQotCUNGREZfRG9jdW1lbnQqIHBGREYgPSBtX3BJbnRlckZvcm0tPkV4cG9ydFRvRkRGKG1fcERvY3VtZW50LT5HZXRQYXRoKCkpOw0KLQlpZiAoIXBGREYpIHJldHVybiBGQUxTRTsNCi0JDQotCUZYX0JPT0wgYlJldCA9IHBGREYtPldyaXRlQnVmKHRleHRCdWYpOw0KLQlkZWxldGUgcEZERjsNCi0JDQotCXJldHVybiBiUmV0Ow0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpFeHBvcnRGb3JtVG9UeHRGaWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVHh0RmlsZU5hbWUpDQotew0KLQlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzRmllbGROYW1lczsNCi0JQ0ZYX1dpZGVTdHJpbmcgc0ZpZWxkVmFsdWVzOw0KLQ0KLQlpbnQgblNpemUgPSBtX3BJbnRlckZvcm0tPkNvdW50RmllbGRzKCk7DQotDQotCWlmIChuU2l6ZSA+IDApDQotCXsNCi0JCWZvciAoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQ0KLQkJew0KLQkJCUNQREZfRm9ybUZpZWxkKiBwRmllbGQgPSBtX3BJbnRlckZvcm0tPkdldEZpZWxkKGkpOw0KLQkJCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7DQotDQotCQkJaWYgKGkgIT0gMCkNCi0JCQl7DQotCQkJCXNGaWVsZE5hbWVzICs9IEwiXHQiOw0KLQkJCQlzRmllbGRWYWx1ZXMgKz0gTCJcdCI7DQotCQkJfQ0KLQkJCXNGaWVsZE5hbWVzICs9IHBGaWVsZC0+R2V0RnVsbE5hbWUoKTsNCi0JCQlzRmllbGRWYWx1ZXMgKz0gcEZpZWxkLT5HZXRWYWx1ZSgpOw0KLQkJfQ0KLQ0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNQREZTREtfSW50ZXJGb3JtOjpJbXBvcnRGb3JtRnJvbVR4dEZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUeHRGaWxlTmFtZSkNCi17DQotCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpEb0FjdGlvbl9SZXNldEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbikNCi17DQotCUFTU0VSVChhY3Rpb24gIT0gTlVMTCk7DQotDQotCUNQREZfRGljdGlvbmFyeSogcEFjdGlvbkRpY3QgPSBhY3Rpb247DQotDQotCWlmIChwQWN0aW9uRGljdC0+S2V5RXhpc3QoIkZpZWxkcyIpKQ0KLQl7DQotCQlDUERGX0FjdGlvbkZpZWxkcyBhZiA9IGFjdGlvbi5HZXRXaWRnZXRzKCk7DQotCQlGWF9EV09SRCBkd0ZsYWdzID0gYWN0aW9uLkdldEZsYWdzKCk7DQotCQkNCi0JCUNGWF9QdHJBcnJheSBmaWVsZE9iamVjdHM7DQotCQlhZi5HZXRBbGxGaWVsZHMoZmllbGRPYmplY3RzKTsNCi0JCUNGWF9QdHJBcnJheSBmaWVsZHM7DQotCQlHZXRGaWVsZEZyb21PYmplY3RzKGZpZWxkT2JqZWN0cywgZmllbGRzKTsNCi0JCQ0KLQkJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JCXJldHVybiBtX3BJbnRlckZvcm0tPlJlc2V0Rm9ybShmaWVsZHMsICEoZHdGbGFncyAmIDB4MDEpLCBUUlVFKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7DQotCQlyZXR1cm4gbV9wSW50ZXJGb3JtLT5SZXNldEZvcm0oVFJVRSk7DQotCX0NCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0ludGVyRm9ybTo6RG9BY3Rpb25fSW1wb3J0RGF0YShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQ0KLXsNCi0JQVNTRVJUKGFjdGlvbiAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc0ZpbGVQYXRoID0gYWN0aW9uLkdldEZpbGVQYXRoKCk7DQotCWlmIChzRmlsZVBhdGguSXNFbXB0eSgpKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAoIUltcG9ydEZvcm1Gcm9tRkRGRmlsZShzRmlsZVBhdGgsIFRSVUUpKQ0KLQl7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19JbnRlckZvcm06OkltcG9ydEZvcm1Gcm9tRkRGRmlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgY3NGREZGaWxlTmFtZSwNCi0JCQkJCQkJCQkJCQkgRlhfQk9PTCBiTm90aWZ5KQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpHZXRGaWVsZEZyb21PYmplY3RzKGNvbnN0IENGWF9QdHJBcnJheSYgb2JqZWN0cywgQ0ZYX1B0ckFycmF5JiBmaWVsZHMpDQotew0KLQlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlpbnQgaUNvdW50ID0gb2JqZWN0cy5HZXRTaXplKCk7DQotCWZvciAoaW50IGkgPSAwOyBpIDwgaUNvdW50OyBpICsrKQ0KLQl7DQotCQlDUERGX09iamVjdCogcE9iamVjdCA9IChDUERGX09iamVjdCopb2JqZWN0c1tpXTsNCi0JCWlmIChwT2JqZWN0ID09IE5VTEwpIGNvbnRpbnVlOw0KLQkJDQotCQlpbnQgaVR5cGUgPSBwT2JqZWN0LT5HZXRUeXBlKCk7DQotCQlpZiAoaVR5cGUgPT0gUERGT0JKX1NUUklORykNCi0JCXsNCi0JCQlDRlhfV2lkZVN0cmluZyBjc05hbWUgPSBwT2JqZWN0LT5HZXRVbmljb2RlVGV4dCgpOw0KLQkJCUNQREZfRm9ybUZpZWxkKiBwRmllbGQgPSBtX3BJbnRlckZvcm0tPkdldEZpZWxkKDAsIGNzTmFtZSk7DQotCQkJaWYgKHBGaWVsZCAhPSBOVUxMKQ0KLQkJCQlmaWVsZHMuQWRkKHBGaWVsZCk7DQotCQl9DQotCQllbHNlIGlmIChpVHlwZSA9PSBQREZPQkpfRElDVElPTkFSWSkNCi0JCXsNCi0JCQlpZiAobV9wSW50ZXJGb3JtLT5Jc1ZhbGlkRm9ybUZpZWxkKHBPYmplY3QpKQ0KLQkJCQlmaWVsZHMuQWRkKHBPYmplY3QpOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQREZfRm9ybU5vdGlmeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLWludAlDUERGU0RLX0ludGVyRm9ybTo6QmVmb3JlVmFsdWVDaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIGNzVmFsdWUpDQotew0KLQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopcEZpZWxkOw0KLQ0KLQlpbnQgblR5cGUgPSBwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKTsNCi0JaWYgKG5UeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCB8fCBuVHlwZSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEKQ0KLQl7DQotCQlGWF9CT09MIGJSQyA9IFRSVUU7DQotCQlPbktleVN0cm9rZUNvbW1pdChwRm9ybUZpZWxkLCBjc1ZhbHVlLCBiUkMpOw0KLQkJaWYgKGJSQykgDQotCQl7DQotCQkJT25WYWxpZGF0ZShwRm9ybUZpZWxkLCBjc1ZhbHVlLCBiUkMpOw0KLQkJCWlmIChiUkMpDQotCQkJCXJldHVybiAxOw0KLQkJCWVsc2UNCi0JCQkJcmV0dXJuIC0xOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJCXJldHVybiAtMTsNCi0JfQ0KLQllbHNlDQotCQlyZXR1cm4gMDsNCi19DQotDQotaW50CUNQREZTREtfSW50ZXJGb3JtOjpBZnRlclZhbHVlQ2hhbmdlKGNvbnN0IENQREZfRm9ybUZpZWxkKiBwRmllbGQpDQotew0KLQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopcEZpZWxkOw0KLQlpbnQgblR5cGUgPSBwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKTsNCi0NCi0JaWYgKG5UeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCB8fCBuVHlwZSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEKQ0KLQl7DQotCQl0aGlzLT5PbkNhbGN1bGF0ZShwRm9ybUZpZWxkKTsNCi0JCUZYX0JPT0wgYkZvcm1hdGVkID0gRkFMU0U7DQotCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSB0aGlzLT5PbkZvcm1hdChwRm9ybUZpZWxkLCAwLCBiRm9ybWF0ZWQpOw0KLQkJaWYgKGJGb3JtYXRlZCkNCi0JCQl0aGlzLT5SZXNldEZpZWxkQXBwZWFyYW5jZShwRm9ybUZpZWxkLCBzVmFsdWUsIFRSVUUpOw0KLQkJZWxzZQ0KLQkJCXRoaXMtPlJlc2V0RmllbGRBcHBlYXJhbmNlKHBGb3JtRmllbGQsIE5VTEwsIFRSVUUpOw0KLQkJdGhpcy0+VXBkYXRlRmllbGQocEZvcm1GaWVsZCk7DQotCX0NCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLWludAlDUERGU0RLX0ludGVyRm9ybTo6QmVmb3JlU2VsZWN0aW9uQ2hhbmdlKGNvbnN0IENQREZfRm9ybUZpZWxkKiBwRmllbGQsIENGWF9XaWRlU3RyaW5nJiBjc1ZhbHVlKQ0KLXsNCi0JQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKXBGaWVsZDsNCi0NCi0JaW50IG5UeXBlID0gcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCk7DQotCWlmIChuVHlwZSA9PSBGSUVMRFRZUEVfTElTVEJPWCkNCi0Jew0KLQkJRlhfQk9PTCBiUkMgPSBUUlVFOw0KLQkJT25LZXlTdHJva2VDb21taXQocEZvcm1GaWVsZCwgY3NWYWx1ZSwgYlJDKTsNCi0JCWlmIChiUkMpIA0KLQkJew0KLQkJCU9uVmFsaWRhdGUocEZvcm1GaWVsZCwgY3NWYWx1ZSwgYlJDKTsNCi0JCQlpZiAoYlJDKQ0KLQkJCQlyZXR1cm4gMTsNCi0JCQllbHNlDQotCQkJCXJldHVybiAtMTsNCi0JCX0NCi0JCWVsc2UNCi0JCQlyZXR1cm4gLTE7DQotCX0NCi0JZWxzZQ0KLQkJcmV0dXJuIDA7DQotfQ0KLQ0KLWludAlDUERGU0RLX0ludGVyRm9ybTo6QWZ0ZXJTZWxlY3Rpb25DaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCkNCi17DQotCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilwRmllbGQ7DQotCWludCBuVHlwZSA9IHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpOw0KLQ0KLQlpZiAoblR5cGUgPT0gRklFTERUWVBFX0xJU1RCT1gpDQotCXsNCi0JCXRoaXMtPk9uQ2FsY3VsYXRlKHBGb3JtRmllbGQpOw0KLQkJdGhpcy0+UmVzZXRGaWVsZEFwcGVhcmFuY2UocEZvcm1GaWVsZCwgTlVMTCwgVFJVRSk7DQotCQl0aGlzLT5VcGRhdGVGaWVsZChwRm9ybUZpZWxkKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gMDsNCi19DQotDQotaW50CUNQREZTREtfSW50ZXJGb3JtOjpBZnRlckNoZWNrZWRTdGF0dXNDaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCwgY29uc3QgQ0ZYX0J5dGVBcnJheSYgc3RhdHVzQXJyYXkpDQotew0KLQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopcEZpZWxkOw0KLQlpbnQgblR5cGUgPSBwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKTsNCi0NCi0JaWYgKG5UeXBlID09IEZJRUxEVFlQRV9DSEVDS0JPWCB8fCBuVHlwZSA9PSBGSUVMRFRZUEVfUkFESU9CVVRUT04pDQotCXsNCi0JCXRoaXMtPk9uQ2FsY3VsYXRlKHBGb3JtRmllbGQpOw0KLQkJLy90aGlzLT5SZXNldEZpZWxkQXBwZWFyYW5jZShwRm9ybUZpZWxkLCBOVUxMKTsNCi0JCXRoaXMtPlVwZGF0ZUZpZWxkKHBGb3JtRmllbGQpOw0KLQl9DQotDQotCXJldHVybiAwOw0KLX0NCi0NCi1pbnQJQ1BERlNES19JbnRlckZvcm06OkJlZm9yZUZvcm1SZXNldChjb25zdCBDUERGX0ludGVyRm9ybSogcEZvcm0pDQotew0KLQlyZXR1cm4gMDsNCi19DQotDQotaW50CUNQREZTREtfSW50ZXJGb3JtOjpBZnRlckZvcm1SZXNldChjb25zdCBDUERGX0ludGVyRm9ybSogcEZvcm0pDQotew0KLQl0aGlzLT5PbkNhbGN1bGF0ZShOVUxMKTsNCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLWludAlDUERGU0RLX0ludGVyRm9ybTo6QmVmb3JlRm9ybUltcG9ydERhdGEoY29uc3QgQ1BERl9JbnRlckZvcm0qIHBGb3JtKQ0KLXsNCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLWludAlDUERGU0RLX0ludGVyRm9ybTo6QWZ0ZXJGb3JtSW1wb3J0RGF0YShjb25zdCBDUERGX0ludGVyRm9ybSogcEZvcm0pDQotew0KLQl0aGlzLT5PbkNhbGN1bGF0ZShOVUxMKTsNCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OklzTmVlZEhpZ2hMaWdodChpbnQgbkZpZWxkVHlwZSkNCi17DQotCWlmKG5GaWVsZFR5cGUgPDEgfHwgbkZpZWxkVHlwZSA+IDYpDQotCQlyZXR1cm4gRkFMU0U7DQotCXJldHVybiBtX2JOZWVkSGlnaHRsaWdodFtuRmllbGRUeXBlLTFdOw0KLX0NCi0NCi12b2lkIENQREZTREtfSW50ZXJGb3JtOjpSZW1vdmVBbGxIaWdoTGlnaHQoKQ0KLXsNCi0JbWVtc2V0KCh2b2lkKiltX2JOZWVkSGlnaHRsaWdodCwgMCwgNipzaXplb2YoRlhfQk9PTCkpOw0KLX0NCi12b2lkICAgQ1BERlNES19JbnRlckZvcm06OlNldEhpZ2hsaWdodENvbG9yKEZYX0NPTE9SUkVGIGNsciwgaW50IG5GaWVsZFR5cGUpDQotew0KLQlpZihuRmllbGRUeXBlIDwwIHx8IG5GaWVsZFR5cGUgPiA2KSByZXR1cm47DQotCXN3aXRjaChuRmllbGRUeXBlKQ0KLQl7DQotCWNhc2UgMDoNCi0JCXsNCi0JCQlmb3IoaW50IGk9MDsgaTw2OyBpKyspDQotCQkJew0KLQkJCQltX2FIaWdobGlnaHRDb2xvcltpXSA9IGNscjsNCi0JCQkJbV9iTmVlZEhpZ2h0bGlnaHRbaV0gPSBUUlVFOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCX0NCi0JZGVmYXVsdDoNCi0JCXsNCi0JCQltX2FIaWdobGlnaHRDb2xvcltuRmllbGRUeXBlLTFdID0gY2xyOw0KLQkJCW1fYk5lZWRIaWdodGxpZ2h0W25GaWVsZFR5cGUtMV0gPSBUUlVFOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotCQ0KLX0NCi0NCi1GWF9DT0xPUlJFRiBDUERGU0RLX0ludGVyRm9ybTo6R2V0SGlnaGxpZ2h0Q29sb3IoaW50IG5GaWVsZFR5cGUpDQotew0KLQlpZihuRmllbGRUeXBlIDwwIHx8IG5GaWVsZFR5cGUgPjYpIHJldHVybiBGWFNZU19SR0IoMjU1LDI1NSwyNTUpOw0KLQlpZihuRmllbGRUeXBlID09IDApDQotCQlyZXR1cm4gbV9hSGlnaGxpZ2h0Q29sb3JbMF07DQotCWVsc2UNCi0JCXJldHVybiBtX2FIaWdobGlnaHRDb2xvcltuRmllbGRUeXBlLTFdOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENCQV9Bbm5vdEl0ZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DQkFfQW5ub3RJdGVyYXRvcjo6Q0JBX0Fubm90SXRlcmF0b3IoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc1R5cGUsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzU3ViVHlwZSkNCi0JOm1fcFBhZ2VWaWV3KHBQYWdlVmlldyksDQotCW1fc1R5cGUoc1R5cGUpLA0KLQltX3NTdWJUeXBlKHNTdWJUeXBlKSwNCi0JbV9uVGFicyhCQUlfU1RSVUNUVVJFKQ0KLXsNCi0JQVNTRVJUKG1fcFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQ0KLQlDUERGX1BhZ2UqIHBQREZQYWdlID0gbV9wUGFnZVZpZXctPkdldFBERlBhZ2UoKTsNCi0JQVNTRVJUKHBQREZQYWdlICE9IE5VTEwpOw0KLQlBU1NFUlQocFBERlBhZ2UtPm1fcEZvcm1EaWN0ICE9IE5VTEwpOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBzVGFicyA9IHBQREZQYWdlLT5tX3BGb3JtRGljdC0+R2V0U3RyaW5nKCJUYWJzIik7DQotDQotCWlmIChzVGFicyA9PSAiUiIpDQotCXsNCi0JCW1fblRhYnMgPSBCQUlfUk9XOw0KLQl9DQotCWVsc2UgaWYgKHNUYWJzID09ICJDIikNCi0Jew0KLQkJbV9uVGFicyA9IEJBSV9DT0xVTU47DQotCX0NCi0JZWxzZQ0KLQl7DQotCQltX25UYWJzID0gQkFJX1NUUlVDVFVSRTsNCi0JfQ0KLQ0KLQlHZW5lcmF0ZVJlc3VsdHMoKTsNCi19DQotDQotQ0JBX0Fubm90SXRlcmF0b3I6On5DQkFfQW5ub3RJdGVyYXRvcigpDQotew0KLQltX0Fubm90cy5SZW1vdmVBbGwoKTsNCi19DQotDQotQ1BERlNES19Bbm5vdCogQ0JBX0Fubm90SXRlcmF0b3I6OkdldEZpcnN0QW5ub3QoKQ0KLXsNCi0JaWYgKG1fQW5ub3RzLkdldFNpemUoKSA+IDApDQotCQlyZXR1cm4gbV9Bbm5vdHNbMF07DQotCQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotQ1BERlNES19Bbm5vdCogQ0JBX0Fubm90SXRlcmF0b3I6OkdldExhc3RBbm5vdCgpDQotew0KLQlpZiAobV9Bbm5vdHMuR2V0U2l6ZSgpID4gMCkNCi0JCXJldHVybiBtX0Fubm90c1ttX0Fubm90cy5HZXRTaXplKCkgLSAxXTsNCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUNQREZTREtfQW5ub3QqIENCQV9Bbm5vdEl0ZXJhdG9yOjpHZXROZXh0QW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JZm9yIChpbnQgaT0wLHN6PW1fQW5ub3RzLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAobV9Bbm5vdHNbaV0gPT0gcEFubm90KQ0KLQkJew0KLQkJCWlmIChpKzEgPCBzeikNCi0JCQkJcmV0dXJuIG1fQW5ub3RzW2krMV07DQotCQkJZWxzZQ0KLQkJCQlyZXR1cm4gbV9Bbm5vdHNbMF07DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUNQREZTREtfQW5ub3QqIENCQV9Bbm5vdEl0ZXJhdG9yOjpHZXRQcmV2QW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JZm9yIChpbnQgaT0wLHN6PW1fQW5ub3RzLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAobV9Bbm5vdHNbaV0gPT0gcEFubm90KQ0KLQkJew0KLQkJCWlmIChpLTEgPj0gMCkNCi0JCQkJcmV0dXJuIG1fQW5ub3RzW2ktMV07DQotCQkJZWxzZQ0KLQkJCQlyZXR1cm4gbV9Bbm5vdHNbc3otMV07DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLWludCBDQkFfQW5ub3RJdGVyYXRvcjo6Q29tcGFyZUJ5TGVmdChDUERGU0RLX0Fubm90KiBwMSwgQ1BERlNES19Bbm5vdCogcDIpDQotew0KLQlBU1NFUlQocDEgIT0gTlVMTCk7DQotCUFTU0VSVChwMiAhPSBOVUxMKTsNCi0NCi0JQ1BERl9SZWN0IHJjQW5ub3QxID0gR2V0QW5ub3RSZWN0KHAxKTsNCi0JQ1BERl9SZWN0IHJjQW5ub3QyID0gR2V0QW5ub3RSZWN0KHAyKTsNCi0NCi0JaWYgKHJjQW5ub3QxLmxlZnQgPCByY0Fubm90Mi5sZWZ0KQ0KLQkJcmV0dXJuIC0xOw0KLQlpZiAocmNBbm5vdDEubGVmdCA+IHJjQW5ub3QyLmxlZnQpDQotCQlyZXR1cm4gMTsNCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLQ0KLWludCBDQkFfQW5ub3RJdGVyYXRvcjo6Q29tcGFyZUJ5VG9wKENQREZTREtfQW5ub3QqIHAxLCBDUERGU0RLX0Fubm90KiBwMikNCi17DQotCUFTU0VSVChwMSAhPSBOVUxMKTsNCi0JQVNTRVJUKHAyICE9IE5VTEwpOw0KLQ0KLQlDUERGX1JlY3QgcmNBbm5vdDEgPSBHZXRBbm5vdFJlY3QocDEpOw0KLQlDUERGX1JlY3QgcmNBbm5vdDIgPSBHZXRBbm5vdFJlY3QocDIpOw0KLQ0KLQlpZiAocmNBbm5vdDEudG9wIDwgcmNBbm5vdDIudG9wKQ0KLQkJcmV0dXJuIC0xOw0KLQlpZiAocmNBbm5vdDEudG9wID4gcmNBbm5vdDIudG9wKQ0KLQkJcmV0dXJuIDE7DQotCXJldHVybiAwOw0KLX0NCi0NCi12b2lkIENCQV9Bbm5vdEl0ZXJhdG9yOjpHZW5lcmF0ZVJlc3VsdHMoKQ0KLXsNCi0JQVNTRVJUKG1fcFBhZ2VWaWV3ICE9IE5VTEwpOw0KLQ0KLQlzd2l0Y2ggKG1fblRhYnMpDQotCXsNCi0JY2FzZSBCQUlfU1RSVUNUVVJFOg0KLQkJew0KLQkJCWZvciAoaW50IGk9MCxzej1tX3BQYWdlVmlldy0+Q291bnRBbm5vdHMoKTsgaTxzejsgaSsrKQ0KLQkJCXsNCi0JCQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gbV9wUGFnZVZpZXctPkdldEFubm90KGkpOw0KLQkJCQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQ0KLQkJCQlpZiAocEFubm90LT5HZXRUeXBlKCkgPT0gbV9zVHlwZSANCi0JCQkJCSYmIHBBbm5vdC0+R2V0U3ViVHlwZSgpID09IG1fc1N1YlR5cGUpDQotCQkJCQltX0Fubm90cy5BZGQocEFubm90KTsNCi0JCQl9DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBCQUlfUk9XOg0KLQkJew0KLQkJCUNQREZTREtfU29ydEFubm90cyBzYTsNCi0NCi0JCQl7DQotCQkJCQ0KLQkJCQlmb3IgKGludCBpPTAsc3o9bV9wUGFnZVZpZXctPkNvdW50QW5ub3RzKCk7IGk8c3o7IGkrKykNCi0JCQkJew0KLQkJCQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gbV9wUGFnZVZpZXctPkdldEFubm90KGkpOw0KLQkJCQkJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0NCi0JCQkJCWlmIChwQW5ub3QtPkdldFR5cGUoKSA9PSBtX3NUeXBlIA0KLQkJCQkJCSYmIHBBbm5vdC0+R2V0U3ViVHlwZSgpID09IG1fc1N1YlR5cGUpDQotCQkJCQkJc2EuQWRkKHBBbm5vdCk7DQotCQkJCX0NCi0JCQl9DQotDQotCQkJaWYgKHNhLkdldFNpemUoKSA+IDApDQotCQkJew0KLQkJCQlzYS5Tb3J0KENCQV9Bbm5vdEl0ZXJhdG9yOjpDb21wYXJlQnlMZWZ0KTsNCi0JCQl9DQotDQotCQkJd2hpbGUgKHNhLkdldFNpemUoKSA+IDApDQotCQkJew0KLQkJCQlpbnQgbkxlZnRUb3BJbmRleCA9IC0xOw0KLQ0KLQkJCQl7DQotCQkJCQlGWF9GTE9BVCBmVG9wID0gMC4wZjsNCi0NCi0JCQkJCWZvciAoaW50IGk9c2EuR2V0U2l6ZSgpLTE7IGk+PTA7IGktLSkNCi0JCQkJCXsNCi0JCQkJCQlDUERGU0RLX0Fubm90KiBwQW5ub3QgPSBzYS5HZXRBdChpKTsNCi0JCQkJCQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQ0KLQkJCQkJCUNQREZfUmVjdCByY0Fubm90ID0gR2V0QW5ub3RSZWN0KHBBbm5vdCk7DQotDQotCQkJCQkJaWYgKHJjQW5ub3QudG9wID4gZlRvcCkNCi0JCQkJCQl7DQotCQkJCQkJCW5MZWZ0VG9wSW5kZXggPSBpOw0KLQkJCQkJCQlmVG9wID0gcmNBbm5vdC50b3A7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotDQotCQkJCWlmIChuTGVmdFRvcEluZGV4ID49IDApDQotCQkJCXsNCi0JCQkJCUNQREZTREtfQW5ub3QqIHBMZWZ0VG9wQW5ub3QgPSBzYS5HZXRBdChuTGVmdFRvcEluZGV4KTsNCi0JCQkJCUFTU0VSVChwTGVmdFRvcEFubm90ICE9IE5VTEwpOw0KLQ0KLQkJCQkJQ1BERl9SZWN0IHJjTGVmdFRvcCA9IEdldEFubm90UmVjdChwTGVmdFRvcEFubm90KTsNCi0JCQkJCQ0KLQkJCQkJbV9Bbm5vdHMuQWRkKHBMZWZ0VG9wQW5ub3QpOw0KLQkJCQkJc2EuUmVtb3ZlQXQobkxlZnRUb3BJbmRleCk7DQotDQotCQkJCQlDRlhfQXJyYXlUZW1wbGF0ZTxpbnQ+IGFTZWxlY3Q7DQotDQotCQkJCQl7DQotCQkJCQkJZm9yIChpbnQgaT0wLHN6PXNhLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJCQkJCXsNCi0JCQkJCQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gc2EuR2V0QXQoaSk7DQotCQkJCQkJCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7DQotDQotCQkJCQkJCUNQREZfUmVjdCByY0Fubm90ID0gR2V0QW5ub3RSZWN0KHBBbm5vdCk7DQotDQotCQkJCQkJCUZYX0ZMT0FUIGZDZW50ZXJZID0gKHJjQW5ub3QudG9wICsgcmNBbm5vdC5ib3R0b20pIC8gMi4wZjsNCi0NCi0JCQkJCQkJaWYgKGZDZW50ZXJZID4gcmNMZWZ0VG9wLmJvdHRvbSAmJiBmQ2VudGVyWSA8IHJjTGVmdFRvcC50b3ApDQotCQkJCQkJCQlhU2VsZWN0LkFkZChpKTsNCi0JCQkJCQl9DQotCQkJCQl9DQotDQotCQkJCQl7DQotCQkJCQkJZm9yIChpbnQgaT0wLHN6PWFTZWxlY3QuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQkJCQkJew0KLQkJCQkJCQltX0Fubm90cy5BZGQoc2FbYVNlbGVjdFtpXV0pOw0KLQkJCQkJCX0NCi0JCQkJCX0NCi0NCi0JCQkJCXsNCi0JCQkJCQlmb3IgKGludCBpPWFTZWxlY3QuR2V0U2l6ZSgpLTE7IGk+PTA7IGktLSkNCi0JCQkJCQl7DQotCQkJCQkJCXNhLlJlbW92ZUF0KGFTZWxlY3RbaV0pOw0KLQkJCQkJCX0NCi0JCQkJCX0NCi0NCi0JCQkJCWFTZWxlY3QuUmVtb3ZlQWxsKCk7DQotCQkJCX0NCi0JCQl9DQotCQkJc2EuUmVtb3ZlQWxsKCk7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBCQUlfQ09MVU1OOg0KLQkJew0KLQkJCUNQREZTREtfU29ydEFubm90cyBzYTsNCi0NCi0JCQl7DQotCQkJCWZvciAoaW50IGk9MCxzej1tX3BQYWdlVmlldy0+Q291bnRBbm5vdHMoKTsgaTxzejsgaSsrKQ0KLQkJCQl7DQotCQkJCQlDUERGU0RLX0Fubm90KiBwQW5ub3QgPSBtX3BQYWdlVmlldy0+R2V0QW5ub3QoaSk7DQotCQkJCQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQ0KLQkJCQkJaWYgKHBBbm5vdC0+R2V0VHlwZSgpID09IG1fc1R5cGUgDQotCQkJCQkJJiYgcEFubm90LT5HZXRTdWJUeXBlKCkgPT0gbV9zU3ViVHlwZSkNCi0JCQkJCQlzYS5BZGQocEFubm90KTsNCi0JCQkJfQ0KLQkJCX0NCi0NCi0JCQlpZiAoc2EuR2V0U2l6ZSgpID4gMCkNCi0JCQl7DQotCQkJCXNhLlNvcnQoQ0JBX0Fubm90SXRlcmF0b3I6OkNvbXBhcmVCeVRvcCwgRkFMU0UpOw0KLQkJCX0NCi0NCi0JCQl3aGlsZSAoc2EuR2V0U2l6ZSgpID4gMCkNCi0JCQl7DQotCQkJCWludCBuTGVmdFRvcEluZGV4ID0gLTE7DQotDQotCQkJCXsNCi0JCQkJCUZYX0ZMT0FUIGZMZWZ0ID0gLTEuMGY7DQotDQotCQkJCQlmb3IgKGludCBpPXNhLkdldFNpemUoKS0xOyBpPj0wOyBpLS0pDQotCQkJCQl7DQotCQkJCQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gc2EuR2V0QXQoaSk7DQotCQkJCQkJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0NCi0JCQkJCQlDUERGX1JlY3QgcmNBbm5vdCA9IEdldEFubm90UmVjdChwQW5ub3QpOw0KLQ0KLQkJCQkJCWlmIChmTGVmdCA8IDApDQotCQkJCQkJew0KLQkJCQkJCQluTGVmdFRvcEluZGV4ID0gMDsNCi0JCQkJCQkJZkxlZnQgPSByY0Fubm90LmxlZnQ7DQotCQkJCQkJfQ0KLQkJCQkJCWVsc2UgaWYgKHJjQW5ub3QubGVmdCA8IGZMZWZ0KQ0KLQkJCQkJCXsNCi0JCQkJCQkJbkxlZnRUb3BJbmRleCA9IGk7DQotCQkJCQkJCWZMZWZ0ID0gcmNBbm5vdC5sZWZ0Ow0KLQkJCQkJCX0NCi0JCQkJCX0NCi0JCQkJfQ0KLQ0KLQkJCQlpZiAobkxlZnRUb3BJbmRleCA+PSAwKQ0KLQkJCQl7DQotCQkJCQlDUERGU0RLX0Fubm90KiBwTGVmdFRvcEFubm90ID0gc2EuR2V0QXQobkxlZnRUb3BJbmRleCk7DQotCQkJCQlBU1NFUlQocExlZnRUb3BBbm5vdCAhPSBOVUxMKTsNCi0NCi0JCQkJCUNQREZfUmVjdCByY0xlZnRUb3AgPSBHZXRBbm5vdFJlY3QocExlZnRUb3BBbm5vdCk7DQotCQkJCQkNCi0JCQkJCW1fQW5ub3RzLkFkZChwTGVmdFRvcEFubm90KTsNCi0JCQkJCXNhLlJlbW92ZUF0KG5MZWZ0VG9wSW5kZXgpOw0KLQ0KLQkJCQkJQ0ZYX0FycmF5VGVtcGxhdGU8aW50PiBhU2VsZWN0Ow0KLQ0KLQkJCQkJew0KLQkJCQkJCWZvciAoaW50IGk9MCxzej1zYS5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQkJCQl7DQotCQkJCQkJCUNQREZTREtfQW5ub3QqIHBBbm5vdCA9IHNhLkdldEF0KGkpOw0KLQkJCQkJCQlBU1NFUlQocEFubm90ICE9IE5VTEwpOw0KLQ0KLQkJCQkJCQlDUERGX1JlY3QgcmNBbm5vdCA9IEdldEFubm90UmVjdChwQW5ub3QpOw0KLQ0KLQkJCQkJCQlGWF9GTE9BVCBmQ2VudGVyWCA9IChyY0Fubm90LmxlZnQgKyByY0Fubm90LnJpZ2h0KSAvIDIuMGY7DQotDQotCQkJCQkJCWlmIChmQ2VudGVyWCA+IHJjTGVmdFRvcC5sZWZ0ICYmIGZDZW50ZXJYIDwgcmNMZWZ0VG9wLnJpZ2h0KQ0KLQkJCQkJCQkJYVNlbGVjdC5BZGQoaSk7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQ0KLQkJCQkJew0KLQkJCQkJCWZvciAoaW50IGk9MCxzej1hU2VsZWN0LkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJCQkJCXsNCi0JCQkJCQkJbV9Bbm5vdHMuQWRkKHNhW2FTZWxlY3RbaV1dKTsNCi0JCQkJCQl9DQotCQkJCQl9DQotDQotCQkJCQl7DQotCQkJCQkJZm9yIChpbnQgaT1hU2VsZWN0LkdldFNpemUoKS0xOyBpPj0wOyBpLS0pDQotCQkJCQkJew0KLQkJCQkJCQlzYS5SZW1vdmVBdChhU2VsZWN0W2ldKTsNCi0JCQkJCQl9DQotCQkJCQl9DQotDQotCQkJCQlhU2VsZWN0LlJlbW92ZUFsbCgpOw0KLQkJCQl9DQotCQkJfQ0KLQkJCXNhLlJlbW92ZUFsbCgpOw0KLQkJfQ0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotQ1BERl9SZWN0IENCQV9Bbm5vdEl0ZXJhdG9yOjpHZXRBbm5vdFJlY3QoQ1BERlNES19Bbm5vdCogcEFubm90KQ0KLXsNCi0JQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9Bbm5vdCogcFBERkFubm90ID0gcEFubm90LT5HZXRQREZBbm5vdCgpOw0KLQlBU1NFUlQocFBERkFubm90ICE9IE5VTEwpOw0KLQ0KLQlDUERGX1JlY3QgcmNBbm5vdDsNCi0JcFBERkFubm90LT5HZXRSZWN0KHJjQW5ub3QpOw0KLQ0KLQlyZXR1cm4gcmNBbm5vdDsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfbWdyLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX2Jhc2Vhbm5vdC5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19iYXNlZm9ybS5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19hY3Rpb25oYW5kbGVyLmgiCisKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vKgkJCQkJCQkJCQlDUERGU0RLX1dpZGdldCAKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMSAmJiAoZikgPiAtMC4wMSkKKyNkZWZpbmUgSXNGbG9hdEJpZ2dlcihmYSxmYikJCQkJKChmYSkgPiAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpCisjZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLGZiKQkJCQkoKGZhKSA8IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkKKyNkZWZpbmUgSXNGbG9hdEVxdWFsKGZhLGZiKQkJCQkJSXNGbG9hdFplcm8oKGZhKS0oZmIpKQorCitDUERGU0RLX1dpZGdldDo6Q1BERlNES19XaWRnZXQoQ1BERl9Bbm5vdCogcEFubm90LCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIENQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtKSA6CisJCQkJCUNQREZTREtfQW5ub3QocEFubm90LCBwUGFnZVZpZXcpLAorCQkJCQltX3BJbnRlckZvcm0ocEludGVyRm9ybSksCisJCQkJCW1fbkFwcEFnZSgwKSwKKwkJCQkJbV9uVmFsdWVBZ2UoMCkKK3sKKwlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOworfQorCitDUERGU0RLX1dpZGdldDo6fkNQREZTREtfV2lkZ2V0KCkKK3sKKworfQorCitGWF9CT09MCQlDUERGU0RLX1dpZGdldDo6SXNXaWRnZXRBcHBlYXJhbmNlVmFsaWQoQ1BERl9Bbm5vdDo6QXBwZWFyYW5jZU1vZGUgbW9kZSkKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisJCisJQ1BERl9EaWN0aW9uYXJ5KiBwQVAgPSBtX3BBbm5vdC0+bV9wQW5ub3REaWN0LT5HZXREaWN0KCJBUCIpOworCWlmIChwQVAgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOworCQorCS8vIENob29zZSB0aGUgcmlnaHQgc3ViLWFwCisJY29uc3QgRlhfQ0hBUiogYXBfZW50cnkgPSAiTiI7CisJaWYgKG1vZGUgPT0gQ1BERl9Bbm5vdDo6RG93bikKKwkJYXBfZW50cnkgPSAiRCI7CisJZWxzZSBpZiAobW9kZSA9PSBDUERGX0Fubm90OjpSb2xsb3ZlcikKKwkJYXBfZW50cnkgPSAiUiI7CisJaWYgKCFwQVAtPktleUV4aXN0KGFwX2VudHJ5KSkKKwkJYXBfZW50cnkgPSAiTiI7CisJCisJLy8gR2V0IHRoZSBBUCBzdHJlYW0gb3Igc3ViZGlyZWN0b3J5CisJQ1BERl9PYmplY3QqIHBzdWIgPSBwQVAtPkdldEVsZW1lbnRWYWx1ZShhcF9lbnRyeSk7CisJaWYgKHBzdWIgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOworCQorCWludCBuRmllbGRUeXBlID0gR2V0RmllbGRUeXBlKCk7CisJc3dpdGNoIChuRmllbGRUeXBlKQorCXsKKwljYXNlIEZJRUxEVFlQRV9QVVNIQlVUVE9OOgorCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOgorCWNhc2UgRklFTERUWVBFX0xJU1RCT1g6CisJY2FzZSBGSUVMRFRZUEVfVEVYVEZJRUxEOgorCWNhc2UgRklFTERUWVBFX1NJR05BVFVSRToKKwkJcmV0dXJuIHBzdWItPkdldFR5cGUoKSA9PSBQREZPQkpfU1RSRUFNOworCWNhc2UgRklFTERUWVBFX0NIRUNLQk9YOgorCWNhc2UgRklFTERUWVBFX1JBRElPQlVUVE9OOgorCQlpZiAocHN1Yi0+R2V0VHlwZSgpID09IFBERk9CSl9ESUNUSU9OQVJZKSAKKwkJeworCQkJQ1BERl9EaWN0aW9uYXJ5KiBwU3ViRGljdCA9IChDUERGX0RpY3Rpb25hcnkqKXBzdWI7CisJCQkKKwkJCXJldHVybiBwU3ViRGljdC0+R2V0U3RyZWFtKHRoaXMtPkdldEFwcFN0YXRlKCkpICE9IE5VTEw7CisJCX0KKwkJZWxzZQorCQkJcmV0dXJuIEZBTFNFOworCQlicmVhazsKKwl9CisJCisJcmV0dXJuIFRSVUU7Cit9CisKK2ludAlDUERGU0RLX1dpZGdldDo6R2V0RmllbGRUeXBlKCkgY29uc3QKK3sKKwlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7CisJQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gcEZpZWxkLT5HZXRGaWVsZFR5cGUoKTsKK30KKworaW50IENQREZTREtfV2lkZ2V0OjpHZXRGaWVsZEZsYWdzKCkgY29uc3QKK3sKKwlDUERGX0ludGVyRm9ybSogcFBERkludGVyRm9ybSA9IG1fcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBQREZJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwUERGSW50ZXJGb3JtLT5HZXRDb250cm9sQnlEaWN0KG1fcEFubm90LT5tX3BBbm5vdERpY3QpOworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gcEZvcm1Db250cm9sLT5HZXRGaWVsZCgpOworCXJldHVybiBwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQREZTREtfV2lkZ2V0OjpHZXRTdWJUeXBlKCkgY29uc3QKK3sKKwlpbnQgblR5cGUgPSBHZXRGaWVsZFR5cGUoKTsKKwkKKwlpZiAoblR5cGUgPT0gRklFTERUWVBFX1NJR05BVFVSRSkKKwkJcmV0dXJuIEJGRlRfU0lHTkFUVVJFOworCXJldHVybiBDUERGU0RLX0Fubm90OjpHZXRTdWJUeXBlKCk7Cit9CisKK0NQREZfRm9ybUZpZWxkKglDUERGU0RLX1dpZGdldDo6R2V0Rm9ybUZpZWxkKCkgY29uc3QKK3sKKwlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOworCQorCUNQREZfRm9ybUNvbnRyb2wqIHBDdHJsID0gR2V0Rm9ybUNvbnRyb2woKTsJCisJQVNTRVJUKHBDdHJsICE9IE5VTEwpOworCQorCXJldHVybiBwQ3RybC0+R2V0RmllbGQoKTsKK30KKworQ1BERl9Gb3JtQ29udHJvbCogQ1BERlNES19XaWRnZXQ6OkdldEZvcm1Db250cm9sKCkgY29uc3QKK3sKKwlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOworCQorCUNQREZfSW50ZXJGb3JtKiBwUERGSW50ZXJGb3JtID0gbV9wSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocFBERkludGVyRm9ybSAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gcFBERkludGVyRm9ybS0+R2V0Q29udHJvbEJ5RGljdChHZXRBbm5vdERpY3QoKSk7Cit9CitzdGF0aWMgQ1BERl9EaWN0aW9uYXJ5KiBCRl9HZXRGaWVsZChDUERGX0RpY3Rpb25hcnkqIHBGaWVsZERpY3QsIGNvbnN0IEZYX0NIQVIqIG5hbWUpCit7CisJaWYgKHBGaWVsZERpY3QgPT0gTlVMTCkgcmV0dXJuIE5VTEw7CisJLy8gRmlyc3QgY2hlY2sgdGhlIGRpY3Rpb25hcnkgaXRzZWxmCisJQ1BERl9PYmplY3QqIHBBdHRyID0gcEZpZWxkRGljdC0+R2V0RWxlbWVudFZhbHVlKG5hbWUpOworCWlmIChwQXR0cikgcmV0dXJuIHBGaWVsZERpY3Q7CisJCisJLy8gTm93IHdlIG5lZWQgdG8gc2VhcmNoIGZyb20gcGFyZW50cworCUNQREZfRGljdGlvbmFyeSogcFBhcmVudCA9IHBGaWVsZERpY3QtPkdldERpY3QoIlBhcmVudCIpOworCWlmIChwUGFyZW50ID09IE5VTEwpIHJldHVybiBOVUxMOworCQorCXJldHVybiBCRl9HZXRGaWVsZChwUGFyZW50LCBuYW1lKTsKK30KKworQ1BERl9Gb3JtQ29udHJvbCogQ1BERlNES19XaWRnZXQ6OkdldEZvcm1Db250cm9sKENQREZfSW50ZXJGb3JtKiBwSW50ZXJGb3JtLCBDUERGX0RpY3Rpb25hcnkqIHBBbm5vdERpY3QpCit7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisJQVNTRVJUKHBBbm5vdERpY3QgIT0gTlVMTCk7CisJCisJQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wgPSBwSW50ZXJGb3JtLT5HZXRDb250cm9sQnlEaWN0KHBBbm5vdERpY3QpOworCQorCXJldHVybiBwQ29udHJvbDsKK30KKworaW50IENQREZTREtfV2lkZ2V0OjpHZXRSb3RhdGUoKSBjb25zdAoreworCUNQREZfRm9ybUNvbnRyb2wqIHBDdHJsID0gdGhpcy0+R2V0Rm9ybUNvbnRyb2woKTsKKwlBU1NFUlQocEN0cmwgIT0gTlVMTCk7CisJCisJcmV0dXJuIHBDdHJsLT5HZXRSb3RhdGlvbigpICUgMzYwOworfQorCitGWF9CT09MCUNQREZTREtfV2lkZ2V0OjpHZXRGaWxsQ29sb3IoRlhfQ09MT1JSRUYmIGNvbG9yKSBjb25zdAoreworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsKKwkKKwlpbnQgaUNvbG9yVHlwZSA9IDA7CQorCWNvbG9yID0gRlhfQVJHQlRPQ09MT1JSRUYocEZvcm1DdHJsLT5HZXRCYWNrZ3JvdW5kQ29sb3IoaUNvbG9yVHlwZSkpOworCQorCXJldHVybiBpQ29sb3JUeXBlICE9IENPTE9SVFlQRV9UUkFOU1BBUkVOVDsKK30KKworRlhfQk9PTAlDUERGU0RLX1dpZGdldDo6R2V0Qm9yZGVyQ29sb3IoRlhfQ09MT1JSRUYmIGNvbG9yKSBjb25zdAoreworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsKKwkKKwlpbnQgaUNvbG9yVHlwZSA9IDA7CQorCWNvbG9yID0gRlhfQVJHQlRPQ09MT1JSRUYocEZvcm1DdHJsLT5HZXRCb3JkZXJDb2xvcihpQ29sb3JUeXBlKSk7CisJCisJcmV0dXJuIGlDb2xvclR5cGUgIT0gQ09MT1JUWVBFX1RSQU5TUEFSRU5UOworfQorCitGWF9CT09MCUNQREZTREtfV2lkZ2V0OjpHZXRUZXh0Q29sb3IoRlhfQ09MT1JSRUYmIGNvbG9yKSBjb25zdAoreworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsKKwkKKwlDUERGX0RlZmF1bHRBcHBlYXJhbmNlIGRhID0gcEZvcm1DdHJsLT5HZXREZWZhdWx0QXBwZWFyYW5jZSgpOworCWlmIChkYS5IYXNDb2xvcigpKQorCXsKKwkJRlhfQVJHQiBhcmdiOworCQlpbnQgaUNvbG9yVHlwZSA9IENPTE9SVFlQRV9UUkFOU1BBUkVOVDsJCisJCWRhLkdldENvbG9yKGFyZ2IsIGlDb2xvclR5cGUpOworCQljb2xvciA9IEZYX0FSR0JUT0NPTE9SUkVGKGFyZ2IpOworCQkKKwkJcmV0dXJuIGlDb2xvclR5cGUgIT0gQ09MT1JUWVBFX1RSQU5TUEFSRU5UOworCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0ZMT0FUIENQREZTREtfV2lkZ2V0OjpHZXRGb250U2l6ZSgpIGNvbnN0Cit7CisJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gR2V0Rm9ybUNvbnRyb2woKTsKKwlBU1NFUlQocEZvcm1DdHJsICE9IE5VTEwpOworCQorCUNQREZfRGVmYXVsdEFwcGVhcmFuY2UgcERhID0gcEZvcm1DdHJsLT5HZXREZWZhdWx0QXBwZWFyYW5jZSgpOworCUNGWF9CeXRlU3RyaW5nIGNzRm9udCA9ICIiOworCUZYX0ZMT0FUIGZGb250U2l6ZSA9IDAuMGY7CisJcERhLkdldEZvbnQoY3NGb250LCBmRm9udFNpemUpOworCQorCXJldHVybiBmRm9udFNpemU7Cit9CisKK2ludAlDUERGU0RLX1dpZGdldDo6R2V0U2VsZWN0ZWRJbmRleChpbnQgbkluZGV4KSBjb25zdAoreworCUNQREZfRm9ybUZpZWxkKglwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisJCisJcmV0dXJuIHBGb3JtRmllbGQtPkdldFNlbGVjdGVkSW5kZXgobkluZGV4KTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BERlNES19XaWRnZXQ6OkdldFZhbHVlKCkgY29uc3QKK3sKKwlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCQorCXJldHVybiBwRm9ybUZpZWxkLT5HZXRWYWx1ZSgpOworfQorCitDRlhfV2lkZVN0cmluZyBDUERGU0RLX1dpZGdldDo6R2V0RGVmYXVsdFZhbHVlKCkgY29uc3QKK3sKKwlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCQorCXJldHVybiBwRm9ybUZpZWxkLT5HZXREZWZhdWx0VmFsdWUoKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BERlNES19XaWRnZXQ6OkdldE9wdGlvbkxhYmVsKGludCBuSW5kZXgpIGNvbnN0Cit7CisJQ1BERl9Gb3JtRmllbGQqCXBGb3JtRmllbGQgPSBHZXRGb3JtRmllbGQoKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gcEZvcm1GaWVsZC0+R2V0T3B0aW9uTGFiZWwobkluZGV4KTsKK30KKworaW50CUNQREZTREtfV2lkZ2V0OjpDb3VudE9wdGlvbnMoKSBjb25zdAoreworCUNQREZfRm9ybUZpZWxkKglwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisJCisJcmV0dXJuIHBGb3JtRmllbGQtPkNvdW50T3B0aW9ucygpOworfQorCitGWF9CT09MCUNQREZTREtfV2lkZ2V0OjpJc09wdGlvblNlbGVjdGVkKGludCBuSW5kZXgpIGNvbnN0Cit7CisJQ1BERl9Gb3JtRmllbGQqCXBGb3JtRmllbGQgPSBHZXRGb3JtRmllbGQoKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gcEZvcm1GaWVsZC0+SXNJdGVtU2VsZWN0ZWQobkluZGV4KTsKK30KKworaW50CUNQREZTREtfV2lkZ2V0OjpHZXRUb3BWaXNpYmxlSW5kZXgoKSBjb25zdAoreworCUNQREZfRm9ybUZpZWxkKglwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisJCisJcmV0dXJuIHBGb3JtRmllbGQtPkdldFRvcFZpc2libGVJbmRleCgpOworfQorCitGWF9CT09MCUNQREZTREtfV2lkZ2V0OjpJc0NoZWNrZWQoKSBjb25zdAoreworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gcEZvcm1DdHJsLT5Jc0NoZWNrZWQoKTsKK30KKworaW50CUNQREZTREtfV2lkZ2V0OjpHZXRBbGlnbm1lbnQoKSBjb25zdAoreworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gcEZvcm1DdHJsLT5HZXRDb250cm9sQWxpZ25tZW50KCk7Cit9CisKK2ludAlDUERGU0RLX1dpZGdldDo6R2V0TWF4TGVuKCkgY29uc3QKK3sKKwlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCQorCXJldHVybiBwRm9ybUZpZWxkLT5HZXRNYXhMZW4oKTsKK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6U2V0Q2hlY2soRlhfQk9PTCBiQ2hlY2tlZCwgRlhfQk9PTCBiTm90aWZ5KQoreworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsKKwkKKwlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IHBGb3JtQ3RybC0+R2V0RmllbGQoKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKwkKKwlwRm9ybUZpZWxkLT5DaGVja0NvbnRyb2wocEZvcm1GaWVsZC0+R2V0Q29udHJvbEluZGV4KHBGb3JtQ3RybCksIGJDaGVja2VkLCBiTm90aWZ5KTsKK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6U2V0VmFsdWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNWYWx1ZSwgRlhfQk9PTCBiTm90aWZ5KQoreworCUNQREZfRm9ybUZpZWxkKglwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisJCisJcEZvcm1GaWVsZC0+U2V0VmFsdWUoc1ZhbHVlLCBiTm90aWZ5KTsKK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6U2V0RGVmYXVsdFZhbHVlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVmFsdWUpCit7Cit9Cit2b2lkIENQREZTREtfV2lkZ2V0OjpTZXRPcHRpb25TZWxlY3Rpb24oaW50IGluZGV4LCBGWF9CT09MIGJTZWxlY3RlZCwgRlhfQk9PTCBiTm90aWZ5KQoreworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisJCisJcEZvcm1GaWVsZC0+U2V0SXRlbVNlbGVjdGlvbihpbmRleCwgYlNlbGVjdGVkLCBiTm90aWZ5KTsKK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6Q2xlYXJTZWxlY3Rpb24oRlhfQk9PTCBiTm90aWZ5KQoreworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisJCisJcEZvcm1GaWVsZC0+Q2xlYXJTZWxlY3Rpb24oYk5vdGlmeSk7Cit9CisKK3ZvaWQgQ1BERlNES19XaWRnZXQ6OlNldFRvcFZpc2libGVJbmRleChpbnQgaW5kZXgpCit7Cit9CisKK3ZvaWQgQ1BERlNES19XaWRnZXQ6OlNldEFwcE1vZGlmaWVkKCkKK3sKKwltX2JBcHBNb2RpZmllZCA9IFRSVUU7Cit9CisKK3ZvaWQgQ1BERlNES19XaWRnZXQ6OkNsZWFyQXBwTW9kaWZpZWQoKQoreworCW1fYkFwcE1vZGlmaWVkID0gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19XaWRnZXQ6OklzQXBwTW9kaWZpZWQoKSBjb25zdAoreworCXJldHVybiBtX2JBcHBNb2RpZmllZDsKK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6UmVzZXRBcHBlYXJhbmNlKEZYX0xQQ1dTVFIgc1ZhbHVlLCBGWF9CT09MIGJWYWx1ZUNoYW5nZWQpCit7CisJU2V0QXBwTW9kaWZpZWQoKTsKKworCW1fbkFwcEFnZSsrOworCWlmIChtX25BcHBBZ2UgPiA5OTk5OTkpCisJCW1fbkFwcEFnZSA9IDA7CisJaWYgKGJWYWx1ZUNoYW5nZWQpCisJCW1fblZhbHVlQWdlKys7CisKKwlpbnQgbkZpZWxkVHlwZSA9IEdldEZpZWxkVHlwZSgpOworCQorCXN3aXRjaCAobkZpZWxkVHlwZSkKKwl7CisJY2FzZSBGSUVMRFRZUEVfUFVTSEJVVFRPTjoKKwkJUmVzZXRBcHBlYXJhbmNlX1B1c2hCdXR0b24oKTsKKwkJYnJlYWs7CisJY2FzZSBGSUVMRFRZUEVfQ0hFQ0tCT1g6CisJCVJlc2V0QXBwZWFyYW5jZV9DaGVja0JveCgpOworCQlicmVhazsKKwljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoKKwkJUmVzZXRBcHBlYXJhbmNlX1JhZGlvQnV0dG9uKCk7CisJCWJyZWFrOworCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOgorCQlSZXNldEFwcGVhcmFuY2VfQ29tYm9Cb3goc1ZhbHVlKTsKKwkJYnJlYWs7CisJY2FzZSBGSUVMRFRZUEVfTElTVEJPWDoKKwkJUmVzZXRBcHBlYXJhbmNlX0xpc3RCb3goKTsKKwkJYnJlYWs7CisJY2FzZSBGSUVMRFRZUEVfVEVYVEZJRUxEOgorCQlSZXNldEFwcGVhcmFuY2VfVGV4dEZpZWxkKHNWYWx1ZSk7CisJCWJyZWFrOworCX0KKwkKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJbV9wQW5ub3QtPkNsZWFyQ2FjaGVkQVAoKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BERlNES19XaWRnZXQ6Ok9uRm9ybWF0KGludCBuQ29tbWl0S2V5LCBGWF9CT09MJiBiRm9ybWF0ZWQpCit7CisgCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gR2V0Rm9ybUZpZWxkKCk7CisgCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworIAkKKyAJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gbV9wSW50ZXJGb3JtLT5PbkZvcm1hdChwRm9ybUZpZWxkLCBuQ29tbWl0S2V5LCBiRm9ybWF0ZWQpOworCit9CisKK3ZvaWQgQ1BERlNES19XaWRnZXQ6OlJlc2V0RmllbGRBcHBlYXJhbmNlKEZYX0JPT0wgYlZhbHVlQ2hhbmdlZCkKK3sKKwlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCQorCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7CisKKwltX3BJbnRlckZvcm0tPlJlc2V0RmllbGRBcHBlYXJhbmNlKHBGb3JtRmllbGQsIE5VTEwsIGJWYWx1ZUNoYW5nZWQpOworfQorCit2b2lkCUNQREZTREtfV2lkZ2V0OjpEcmF3QXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBjb25zdCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQlDUERGX0Fubm90OjpBcHBlYXJhbmNlTW9kZSBtb2RlLCBjb25zdCBDUERGX1JlbmRlck9wdGlvbnMqIHBPcHRpb25zKQoreworCWludCBuRmllbGRUeXBlID0gR2V0RmllbGRUeXBlKCk7CisJCisJaWYgKChuRmllbGRUeXBlID09IEZJRUxEVFlQRV9DSEVDS0JPWCB8fCBuRmllbGRUeXBlID09IEZJRUxEVFlQRV9SQURJT0JVVFRPTikgJiYKKwkJbW9kZSA9PSBDUERGX0Fubm90OjpOb3JtYWwgJiYgCisJCSF0aGlzLT5Jc1dpZGdldEFwcGVhcmFuY2VWYWxpZChDUERGX0Fubm90OjpOb3JtYWwpKQorCXsKKwkJQ0ZYX1BhdGhEYXRhIHBhdGhEYXRhOworCQkKKwkJQ1BERl9SZWN0IHJjQW5ub3QgPSB0aGlzLT5HZXRSZWN0KCk7CisJCQorCQlwYXRoRGF0YS5BcHBlbmRSZWN0KHJjQW5ub3QubGVmdCwgcmNBbm5vdC5ib3R0b20sCisJCQlyY0Fubm90LnJpZ2h0LCByY0Fubm90LnRvcCk7CisJCQorCQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOworCQlnc2QubV9MaW5lV2lkdGggPSAwLjBmOworCQkKKwkJcERldmljZS0+RHJhd1BhdGgoJnBhdGhEYXRhLCBwVXNlcjJEZXZpY2UsICZnc2QsIDAsIDB4RkZBQUFBQUEsIEZYRklMTF9BTFRFUk5BVEUpOworCX0KKwllbHNlCisJeworCQlDUERGU0RLX0Fubm90OjpEcmF3QXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIG1vZGUsIHBPcHRpb25zKTsKKwl9Cit9CisKK3ZvaWQgQ1BERlNES19XaWRnZXQ6OlVwZGF0ZUZpZWxkKCkKK3sKKwlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCQorCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7CisJbV9wSW50ZXJGb3JtLT5VcGRhdGVGaWVsZChwRm9ybUZpZWxkKTsKK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6RHJhd1NoYWRvdyhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisgCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7CisgCisJaW50IG5GaWVsZFR5cGUgPSBHZXRGaWVsZFR5cGUoKTsKKyAJaWYgKG1fcEludGVyRm9ybS0+SXNOZWVkSGlnaExpZ2h0KG5GaWVsZFR5cGUpKQorIAl7CisgCisvLyAgCQlpZiAobkZpZWxkVHlwZSAhPSBGSUVMRFRZUEVfUFVTSEJVVFRPTikKKy8vICAJCXsKKwkJCUNQREZfUmVjdCByYyAgPSBHZXRSZWN0KCk7CisJCQlGWF9DT0xPUlJFRiBjb2xvciA9IG1fcEludGVyRm9ybS0+R2V0SGlnaGxpZ2h0Q29sb3IobkZpZWxkVHlwZSk7CisJCQlGWF9CWVRFIGFscGhhID0gbV9wSW50ZXJGb3JtLT5HZXRIaWdobGlnaHRBbHBoYSgpOworCisJCQlDRlhfRmxvYXRSZWN0IHJjRGV2aWNlOworCQkJQVNTRVJUKG1fcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKSk7CisJCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wSW50ZXJGb3JtLT5HZXREb2N1bWVudCgpLT5HZXRFbnYoKTsKKwkJCWlmKCFwRW52KQorCQkJCXJldHVybjsKKwkJCUNGWF9BZmZpbmVNYXRyaXggcGFnZTJkZXZpY2U7CisJCQlwUGFnZVZpZXctPkdldEN1cnJlbnRNYXRyaXgocGFnZTJkZXZpY2UpOworCQkJcGFnZTJkZXZpY2UuVHJhbnNmb3JtKCgoRlhfRkxPQVQpcmMubGVmdCksICgoRlhfRkxPQVQpcmMuYm90dG9tKSwgcmNEZXZpY2UubGVmdCwgcmNEZXZpY2UuYm90dG9tKTsKKy8vIAkJCXBFbnYtPkZGSV9QYWdlVG9EZXZpY2UobV9wUGFnZVZpZXctPkdldFBERlBhZ2UoKSwgcmMubGVmdCwgcmMuYm90dG9tLCAmcmNEZXZpY2UubGVmdCwgJnJjRGV2aWNlLmJvdHRvbSk7CisvLyAJCQlwRW52LT5GRklfUGFnZVRvRGV2aWNlKG1fcFBhZ2VWaWV3LT5HZXRQREZQYWdlKCksIHJjLnJpZ2h0LCByYy50b3AsICZyY0RldmljZS5yaWdodCwgJnJjRGV2aWNlLnRvcCk7CisJCQlwYWdlMmRldmljZS5UcmFuc2Zvcm0oKChGWF9GTE9BVClyYy5yaWdodCksICgoRlhfRkxPQVQpcmMudG9wKSwgcmNEZXZpY2UucmlnaHQsIHJjRGV2aWNlLnRvcCk7CisKKwkJCXJjRGV2aWNlLk5vcm1hbGl6ZSgpOworCisJCQlGWF9BUkdCIGFyZ2IgPSBBcmdiRW5jb2RlKChpbnQpYWxwaGEsIGNvbG9yKTsKKwkJCUZYX1JFQ1QgcmNEZXYoKGludClyY0RldmljZS5sZWZ0LChpbnQpcmNEZXZpY2UudG9wLChpbnQpcmNEZXZpY2UucmlnaHQsKGludClyY0RldmljZS5ib3R0b20pOworCQkJcERldmljZS0+RmlsbFJlY3QoJnJjRGV2LCBhcmdiKTsJCisJCQkvKiAJCX0qLworCX0KK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6UmVzZXRBcHBlYXJhbmNlX1B1c2hCdXR0b24oKQoreworCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gR2V0Rm9ybUNvbnRyb2woKTsKKwlBU1NFUlQocENvbnRyb2wgIT0gTlVMTCk7CisKKworCQorCUNQREZfUmVjdCByY1dpbmRvdyA9IEdldFJvdGF0ZWRSZWN0KCk7CQorCisJRlhfSU5UMzIgbkxheW91dCA9IDA7CisKKwlzd2l0Y2ggKHBDb250cm9sLT5HZXRUZXh0UG9zaXRpb24oKSkKKwl7CisJY2FzZSBURVhUUE9TX0lDT046CisJCW5MYXlvdXQgPSBQUEJMX0lDT047CisJCWJyZWFrOworCWNhc2UgVEVYVFBPU19CRUxPVzoKKwkJbkxheW91dCA9IFBQQkxfSUNPTlRPUExBQkVMQk9UVE9NOworCQlicmVhazsKKwljYXNlIFRFWFRQT1NfQUJPVkU6CisJCW5MYXlvdXQgPSBQUEJMX0xBQkVMVE9QSUNPTkJPVFRPTTsKKwkJYnJlYWs7CisJY2FzZSBURVhUUE9TX1JJR0hUOgorCQluTGF5b3V0ID0gUFBCTF9JQ09OTEVGVExBQkVMUklHSFQ7CisJCWJyZWFrOworCWNhc2UgVEVYVFBPU19MRUZUOgorCQluTGF5b3V0ID0gUFBCTF9MQUJFTExFRlRJQ09OUklHSFQ7CisJCWJyZWFrOworCWNhc2UgVEVYVFBPU19PVkVSTEFJRDoKKwkJbkxheW91dCA9IFBQQkxfTEFCRUxPVkVSSUNPTjsKKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJbkxheW91dCA9IFBQQkxfTEFCRUw7CisJCWJyZWFrOworCX0KKworCUNQV0xfQ29sb3IgY3JCYWNrZ3JvdW5kLCBjckJvcmRlcjsKKworCWludCBpQ29sb3JUeXBlOworCUZYX0ZMT0FUIGZjWzRdOworCisJcENvbnRyb2wtPkdldE9yaWdpbmFsQmFja2dyb3VuZENvbG9yKGlDb2xvclR5cGUsIGZjKTsKKwlpZiAoaUNvbG9yVHlwZSA+IDApCisJCWNyQmFja2dyb3VuZCA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOworCisJcENvbnRyb2wtPkdldE9yaWdpbmFsQm9yZGVyQ29sb3IoaUNvbG9yVHlwZSwgZmMpOworCWlmIChpQ29sb3JUeXBlID4gMCkKKwkJY3JCb3JkZXIgPSBDUFdMX0NvbG9yKGlDb2xvclR5cGUsIGZjWzBdLCBmY1sxXSwgZmNbMl0sIGZjWzNdKTsKKworCUZYX0ZMT0FUIGZCb3JkZXJXaWR0aCA9IChGWF9GTE9BVClHZXRCb3JkZXJXaWR0aCgpOworCUZYX0lOVDMyIG5Cb3JkZXJTdHlsZSA9IDA7CisJQ1BXTF9EYXNoIGRzQm9yZGVyKDMsMCwwKTsKKwlDUFdMX0NvbG9yIGNyTGVmdFRvcCxjclJpZ2h0Qm90dG9tOworCisJc3dpdGNoIChHZXRCb3JkZXJTdHlsZSgpKQorCXsKKwljYXNlIEJCU19EQVNIOgorCQluQm9yZGVyU3R5bGUgPSBQQlNfREFTSDsKKwkJZHNCb3JkZXIgPSBDUFdMX0Rhc2goMywgMywgMCk7CisJCWJyZWFrOworCWNhc2UgQkJTX0JFVkVMRUQ6CisJCW5Cb3JkZXJTdHlsZSA9IFBCU19CRVZFTEVEOworCQlmQm9yZGVyV2lkdGggKj0gMjsKKwkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwxKTsKKwkJY3JSaWdodEJvdHRvbSA9IENQV0xfVXRpbHM6OkRldmlkZUNvbG9yKGNyQmFja2dyb3VuZCwyKTsKKwkJYnJlYWs7CisJY2FzZSBCQlNfSU5TRVQ6CisJCW5Cb3JkZXJTdHlsZSA9IFBCU19JTlNFVDsKKwkJZkJvcmRlcldpZHRoICo9IDI7CisJCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC41KTsKKwkJY3JSaWdodEJvdHRvbSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC43NSk7CisJCWJyZWFrOworCWNhc2UgQkJTX1VOREVSTElORToKKwkJbkJvcmRlclN0eWxlID0gUEJTX1VOREVSTElORUQ7CisJCWJyZWFrOworCWRlZmF1bHQ6IAorCQluQm9yZGVyU3R5bGUgPSBQQlNfU09MSUQ7CisJCWJyZWFrOworCX0KKworCUNQREZfUmVjdCByY0NsaWVudCA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJjV2luZG93LGZCb3JkZXJXaWR0aCk7CQorCisJQ1BXTF9Db2xvciBjclRleHQoQ09MT1JUWVBFX0dSQVksMCk7CisKKwlGWF9GTE9BVCBmRm9udFNpemUgPSAxMi4wZjsKKwlDRlhfQnl0ZVN0cmluZyBjc05hbWVUYWc7CisKKwlDUERGX0RlZmF1bHRBcHBlYXJhbmNlIGRhID0gcENvbnRyb2wtPkdldERlZmF1bHRBcHBlYXJhbmNlKCk7CisJaWYgKGRhLkhhc0NvbG9yKCkpCisJeworCQlkYS5HZXRDb2xvcihpQ29sb3JUeXBlLCBmYyk7CisJCWNyVGV4dCA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOworCX0KKworCWlmIChkYS5IYXNGb250KCkpIAorCQlkYS5HZXRGb250KGNzTmFtZVRhZywgZkZvbnRTaXplKTsKKworCUNGWF9XaWRlU3RyaW5nIGNzV0NhcHRpb247CisJQ0ZYX1dpZGVTdHJpbmcgY3NOb3JtYWxDYXB0aW9uLCBjc1JvbGxvdmVyQ2FwdGlvbiwgY3NEb3duQ2FwdGlvbjsKKworCWlmIChwQ29udHJvbC0+SGFzTUtFbnRyeSgiQ0EiKSkKKwl7CisJCWNzTm9ybWFsQ2FwdGlvbiA9IHBDb250cm9sLT5HZXROb3JtYWxDYXB0aW9uKCk7CisJfQorCWlmIChwQ29udHJvbC0+SGFzTUtFbnRyeSgiUkMiKSkKKwl7CisJCWNzUm9sbG92ZXJDYXB0aW9uID0gcENvbnRyb2wtPkdldFJvbGxvdmVyQ2FwdGlvbigpOworCX0KKwlpZiAocENvbnRyb2wtPkhhc01LRW50cnkoIkFDIikpCisJeworCQljc0Rvd25DYXB0aW9uID0gcENvbnRyb2wtPkdldERvd25DYXB0aW9uKCk7CisJfQorCisJQ1BERl9TdHJlYW0qIHBOb3JtYWxJY29uID0gTlVMTDsKKwlDUERGX1N0cmVhbSogcFJvbGxvdmVySWNvbiA9IE5VTEw7CisJQ1BERl9TdHJlYW0qIHBEb3duSWNvbiA9IE5VTEw7CisKKwlpZiAocENvbnRyb2wtPkhhc01LRW50cnkoIkkiKSkKKwl7CisJCXBOb3JtYWxJY29uID0gcENvbnRyb2wtPkdldE5vcm1hbEljb24oKTsKKwl9CisJaWYgKHBDb250cm9sLT5IYXNNS0VudHJ5KCJSSSIpKQorCXsKKwkJcFJvbGxvdmVySWNvbiA9IHBDb250cm9sLT5HZXRSb2xsb3Zlckljb24oKTsKKwl9CisJaWYgKHBDb250cm9sLT5IYXNNS0VudHJ5KCJJWCIpKQorCXsKKwkJcERvd25JY29uID0gcENvbnRyb2wtPkdldERvd25JY29uKCk7CisJfQorCisJaWYgKHBOb3JtYWxJY29uKQorCXsKKwkJaWYgKENQREZfRGljdGlvbmFyeSogcEltYWdlRGljdCA9IHBOb3JtYWxJY29uLT5HZXREaWN0KCkpCisJCXsKKwkJCWlmIChwSW1hZ2VEaWN0LT5HZXRTdHJpbmcoIk5hbWUiKS5Jc0VtcHR5KCkpCisJCQkJcEltYWdlRGljdC0+U2V0QXRTdHJpbmcoIk5hbWUiLCAiSW1nQSIpOworCQl9CisJfQorCisJaWYgKHBSb2xsb3Zlckljb24pCisJeworCQlpZiAoQ1BERl9EaWN0aW9uYXJ5KiBwSW1hZ2VEaWN0ID0gcFJvbGxvdmVySWNvbi0+R2V0RGljdCgpKQorCQl7CisJCQlpZiAocEltYWdlRGljdC0+R2V0U3RyaW5nKCJOYW1lIikuSXNFbXB0eSgpKQorCQkJCXBJbWFnZURpY3QtPlNldEF0U3RyaW5nKCJOYW1lIiwgIkltZ0IiKTsKKwkJfQorCX0KKworCWlmIChwRG93bkljb24pCisJeworCQlpZiAoQ1BERl9EaWN0aW9uYXJ5KiBwSW1hZ2VEaWN0ID0gcERvd25JY29uLT5HZXREaWN0KCkpCisJCXsKKwkJCWlmIChwSW1hZ2VEaWN0LT5HZXRTdHJpbmcoIk5hbWUiKS5Jc0VtcHR5KCkpCisJCQkJcEltYWdlRGljdC0+U2V0QXRTdHJpbmcoIk5hbWUiLCAiSW1nQyIpOworCQl9CisJfQorCisJQ1BERl9JY29uRml0IGljb25GaXQgPSBwQ29udHJvbC0+R2V0SWNvbkZpdCgpOworCisvLyAJQVNTRVJUKHRoaXMtPm1fcEJhc2VGb3JtICE9IE5VTEwpOworCUFTU0VSVCh0aGlzLT5tX3BJbnRlckZvcm0gIT0gTlVMTCk7CisJQ1BERlNES19Eb2N1bWVudCogcERvYyA9IG1fcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKTsKKwlBU1NFUlQocERvYyAhPSBOVUxMKTsKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcERvYy0+R2V0RW52KCk7CisKKyAJQ0JBX0ZvbnRNYXAgRm9udE1hcCh0aGlzLHBFbnYtPkdldFN5c0hhbmRsZXIoKSk7Ly8sIElTeXN0ZW1IYW5kbGU6OkdldFN5c3RlbUhhbmRsZXIobV9wQmFzZUZvcm0tPkdldEVudigpKSk7CisJRm9udE1hcC5Jbml0aWFsKCk7CisKKwlGb250TWFwLlNldEFQVHlwZSgiTiIpOworCisJQ0ZYX0J5dGVTdHJpbmcgY3NBUCA9IENQV0xfVXRpbHM6OkdldFJlY3RGaWxsQXBwU3RyZWFtKHJjV2luZG93LCBjckJhY2tncm91bmQpICsgCisJCUNQV0xfVXRpbHM6OkdldEJvcmRlckFwcFN0cmVhbShyY1dpbmRvdywgZkJvcmRlcldpZHRoLCBjckJvcmRlciwgY3JMZWZ0VG9wLCBjclJpZ2h0Qm90dG9tLCBuQm9yZGVyU3R5bGUsIGRzQm9yZGVyKSArCisJCUNQV0xfVXRpbHM6OkdldFB1c2hCdXR0b25BcHBTdHJlYW0oaWNvbkZpdC5HZXRGaXR0aW5nQm91bmRzKCkgPyByY1dpbmRvdyA6IHJjQ2xpZW50LCAmRm9udE1hcCwgcE5vcm1hbEljb24sIGljb25GaXQsIGNzTm9ybWFsQ2FwdGlvbiwgY3JUZXh0LCBmRm9udFNpemUsIG5MYXlvdXQpOworCisJV3JpdGVBcHBlYXJhbmNlKCJOIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVApOworCWlmIChwTm9ybWFsSWNvbikKKwkJQWRkSW1hZ2VUb0FwcGVhcmFuY2UoIk4iLCBwTm9ybWFsSWNvbik7CisKKwlDUERGX0Zvcm1Db250cm9sOjpIaWdobGlnaHRpbmdNb2RlIGVITE0gPSBwQ29udHJvbC0+R2V0SGlnaGxpZ2h0aW5nTW9kZSgpOworCWlmIChlSExNID09IENQREZfRm9ybUNvbnRyb2w6OlB1c2ggfHwgZUhMTSA9PSBDUERGX0Zvcm1Db250cm9sOjpUb2dnbGUpCisJeworCQlpZiAoY3NSb2xsb3ZlckNhcHRpb24uSXNFbXB0eSgpICYmICFwUm9sbG92ZXJJY29uKQkJCQorCQl7CisJCQljc1JvbGxvdmVyQ2FwdGlvbiA9IGNzTm9ybWFsQ2FwdGlvbjsKKwkJCXBSb2xsb3Zlckljb24gPSBwTm9ybWFsSWNvbjsKKwkJfQorCisJCUZvbnRNYXAuU2V0QVBUeXBlKCJSIik7CisKKwkJY3NBUCA9IENQV0xfVXRpbHM6OkdldFJlY3RGaWxsQXBwU3RyZWFtKHJjV2luZG93LCBjckJhY2tncm91bmQpICsgCisJCQkJQ1BXTF9VdGlsczo6R2V0Qm9yZGVyQXBwU3RyZWFtKHJjV2luZG93LCBmQm9yZGVyV2lkdGgsIGNyQm9yZGVyLCBjckxlZnRUb3AsIGNyUmlnaHRCb3R0b20sIG5Cb3JkZXJTdHlsZSwgZHNCb3JkZXIpICsKKwkJCQlDUFdMX1V0aWxzOjpHZXRQdXNoQnV0dG9uQXBwU3RyZWFtKGljb25GaXQuR2V0Rml0dGluZ0JvdW5kcygpID8gcmNXaW5kb3cgOiByY0NsaWVudCwgJkZvbnRNYXAsIHBSb2xsb3Zlckljb24sIGljb25GaXQsIGNzUm9sbG92ZXJDYXB0aW9uLCBjclRleHQsIGZGb250U2l6ZSwgbkxheW91dCk7CisKKwkJV3JpdGVBcHBlYXJhbmNlKCJSIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVApOworCQlpZiAocFJvbGxvdmVySWNvbikKKwkJCUFkZEltYWdlVG9BcHBlYXJhbmNlKCJSIiwgcFJvbGxvdmVySWNvbik7CisKKwkJaWYgKGNzRG93bkNhcHRpb24uSXNFbXB0eSgpICYmICFwRG93bkljb24pCisJCXsKKwkJCWNzRG93bkNhcHRpb24gPSBjc05vcm1hbENhcHRpb247CisJCQlwRG93bkljb24gPSBwTm9ybWFsSWNvbjsKKwkJfQorCisJCXN3aXRjaCAobkJvcmRlclN0eWxlKQorCQl7CisJCWNhc2UgUEJTX0JFVkVMRUQ6CisJCQl7CisJCQkJQ1BXTF9Db2xvciBjclRlbXAgPSBjckxlZnRUb3A7CisJCQkJY3JMZWZ0VG9wID0gY3JSaWdodEJvdHRvbTsKKwkJCQljclJpZ2h0Qm90dG9tID0gY3JUZW1wOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgUEJTX0lOU0VUOgorCQkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwKTsKKwkJCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOworCQkJYnJlYWs7CisJCX0KKwkJCisJCUZvbnRNYXAuU2V0QVBUeXBlKCJEIik7CisKKwkJY3NBUCA9IENQV0xfVXRpbHM6OkdldFJlY3RGaWxsQXBwU3RyZWFtKHJjV2luZG93LCBDUFdMX1V0aWxzOjpTdWJzdHJhY3RDb2xvcihjckJhY2tncm91bmQsMC4yNWYpKSArIAorCQkJQ1BXTF9VdGlsczo6R2V0Qm9yZGVyQXBwU3RyZWFtKHJjV2luZG93LCBmQm9yZGVyV2lkdGgsIGNyQm9yZGVyLCBjckxlZnRUb3AsIGNyUmlnaHRCb3R0b20sIG5Cb3JkZXJTdHlsZSwgZHNCb3JkZXIpICsgCisJCQlDUFdMX1V0aWxzOjpHZXRQdXNoQnV0dG9uQXBwU3RyZWFtKGljb25GaXQuR2V0Rml0dGluZ0JvdW5kcygpID8gcmNXaW5kb3cgOiByY0NsaWVudCwgJkZvbnRNYXAsIHBEb3duSWNvbiwgaWNvbkZpdCwgY3NEb3duQ2FwdGlvbiwgY3JUZXh0LCBmRm9udFNpemUsIG5MYXlvdXQpOworCisJCVdyaXRlQXBwZWFyYW5jZSgiRCIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBjc0FQKTsKKwkJaWYgKHBEb3duSWNvbikKKwkJCUFkZEltYWdlVG9BcHBlYXJhbmNlKCJEIiwgcERvd25JY29uKTsKKwl9CisJZWxzZQorCXsKKwkJUmVtb3ZlQXBwZWFyYW5jZSgiRCIpOworCQlSZW1vdmVBcHBlYXJhbmNlKCJSIik7CisJfQorfQorCit2b2lkIENQREZTREtfV2lkZ2V0OjpSZXNldEFwcGVhcmFuY2VfQ2hlY2tCb3goKQoreworCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gR2V0Rm9ybUNvbnRyb2woKTsKKwlBU1NFUlQocENvbnRyb2wgIT0gTlVMTCk7CisKKworCisJQ1BXTF9Db2xvciBjckJhY2tncm91bmQsIGNyQm9yZGVyLCBjclRleHQ7CisJCisJaW50IGlDb2xvclR5cGU7CisJRlhfRkxPQVQgZmNbNF07CisKKwlwQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoaUNvbG9yVHlwZSwgZmMpOworCWlmIChpQ29sb3JUeXBlID4gMCkKKwkJY3JCYWNrZ3JvdW5kID0gQ1BXTF9Db2xvcihpQ29sb3JUeXBlLCBmY1swXSwgZmNbMV0sIGZjWzJdLCBmY1szXSk7CisKKwlwQ29udHJvbC0+R2V0T3JpZ2luYWxCb3JkZXJDb2xvcihpQ29sb3JUeXBlLCBmYyk7CisJaWYgKGlDb2xvclR5cGUgPiAwKQorCQljckJvcmRlciA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOworCisJRlhfRkxPQVQgZkJvcmRlcldpZHRoID0gKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCk7CisJRlhfSU5UMzIgbkJvcmRlclN0eWxlID0gMDsKKwlDUFdMX0Rhc2ggZHNCb3JkZXIoMywwLDApOworCUNQV0xfQ29sb3IgY3JMZWZ0VG9wLGNyUmlnaHRCb3R0b207CisKKwlzd2l0Y2ggKEdldEJvcmRlclN0eWxlKCkpCisJeworCWNhc2UgQkJTX0RBU0g6CisJCW5Cb3JkZXJTdHlsZSA9IFBCU19EQVNIOworCQlkc0JvcmRlciA9IENQV0xfRGFzaCgzLCAzLCAwKTsKKwkJYnJlYWs7CisJY2FzZSBCQlNfQkVWRUxFRDoKKwkJbkJvcmRlclN0eWxlID0gUEJTX0JFVkVMRUQ7CisJCWZCb3JkZXJXaWR0aCAqPSAyOworCQljckxlZnRUb3AgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOworCQljclJpZ2h0Qm90dG9tID0gQ1BXTF9VdGlsczo6RGV2aWRlQ29sb3IoY3JCYWNrZ3JvdW5kLDIpOworCQlicmVhazsKKwljYXNlIEJCU19JTlNFVDoKKwkJbkJvcmRlclN0eWxlID0gUEJTX0lOU0VUOworCQlmQm9yZGVyV2lkdGggKj0gMjsKKwkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwLjUpOworCQljclJpZ2h0Qm90dG9tID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwLjc1KTsKKwkJYnJlYWs7CisJY2FzZSBCQlNfVU5ERVJMSU5FOgorCQluQm9yZGVyU3R5bGUgPSBQQlNfVU5ERVJMSU5FRDsKKwkJYnJlYWs7CisJZGVmYXVsdDogCisJCW5Cb3JkZXJTdHlsZSA9IFBCU19TT0xJRDsKKwkJYnJlYWs7CisJfQorCisJQ1BERl9SZWN0IHJjV2luZG93ID0gR2V0Um90YXRlZFJlY3QoKTsKKwlDUERGX1JlY3QgcmNDbGllbnQgPSBDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChyY1dpbmRvdyxmQm9yZGVyV2lkdGgpOworCisJQ1BERl9EZWZhdWx0QXBwZWFyYW5jZSBkYSA9IHBDb250cm9sLT5HZXREZWZhdWx0QXBwZWFyYW5jZSgpOworCWlmIChkYS5IYXNDb2xvcigpKQorCXsKKwkJZGEuR2V0Q29sb3IoaUNvbG9yVHlwZSwgZmMpOworCQljclRleHQgPSBDUFdMX0NvbG9yKGlDb2xvclR5cGUsIGZjWzBdLCBmY1sxXSwgZmNbMl0sIGZjWzNdKTsKKwl9CisKKwlGWF9JTlQzMiBuU3R5bGUgPSAwOworCisJQ0ZYX1dpZGVTdHJpbmcgY3NXQ2FwdGlvbiA9IHBDb250cm9sLT5HZXROb3JtYWxDYXB0aW9uKCk7CisJaWYgKGNzV0NhcHRpb24uR2V0TGVuZ3RoKCkgPiAwKQorCXsKKwkJc3dpdGNoIChjc1dDYXB0aW9uWzBdKQorCQl7CisJCWNhc2UgTCdsJzoKKwkJCW5TdHlsZSA9IFBDU19DSVJDTEU7CQkJCisJCQlicmVhazsKKwkJY2FzZSBMJzgnOgorCQkJblN0eWxlID0gUENTX0NST1NTOworCQkJYnJlYWs7CisJCWNhc2UgTCd1JzoKKwkJCW5TdHlsZSA9IFBDU19ESUFNT05EOworCQkJYnJlYWs7CisJCWNhc2UgTCduJzoKKwkJCW5TdHlsZSA9IFBDU19TUVVBUkU7CisJCQlicmVhazsKKwkJY2FzZSBMJ0gnOgorCQkJblN0eWxlID0gUENTX1NUQVI7CisJCQlicmVhazsKKwkJZGVmYXVsdDogLy9MJzQnCisJCQluU3R5bGUgPSBQQ1NfQ0hFQ0s7CisJCQlicmVhazsKKwkJfQorCX0KKwllbHNlCisJeworCQluU3R5bGUgPSBQQ1NfQ0hFQ0s7CisJfQorCisJQ0ZYX0J5dGVTdHJpbmcgY3NBUF9OX09OID0gQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0ocmNXaW5kb3csY3JCYWNrZ3JvdW5kKSArCisJCUNQV0xfVXRpbHM6OkdldEJvcmRlckFwcFN0cmVhbShyY1dpbmRvdyxmQm9yZGVyV2lkdGgsY3JCb3JkZXIsY3JMZWZ0VG9wLGNyUmlnaHRCb3R0b20sbkJvcmRlclN0eWxlLGRzQm9yZGVyKTsKKworCUNGWF9CeXRlU3RyaW5nIGNzQVBfTl9PRkYgPSBjc0FQX05fT047CisKKwlzd2l0Y2ggKG5Cb3JkZXJTdHlsZSkKKwl7CisJY2FzZSBQQlNfQkVWRUxFRDoKKwkJeworCQkJQ1BXTF9Db2xvciBjclRlbXAgPSBjckxlZnRUb3A7CisJCQljckxlZnRUb3AgPSBjclJpZ2h0Qm90dG9tOworCQkJY3JSaWdodEJvdHRvbSA9IGNyVGVtcDsKKwkJfQorCQlicmVhazsKKwljYXNlIFBCU19JTlNFVDoKKwkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwKTsKKwkJY3JSaWdodEJvdHRvbSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMSk7CisJCWJyZWFrOworCX0KKworCUNGWF9CeXRlU3RyaW5nIGNzQVBfRF9PTiA9IENQV0xfVXRpbHM6OkdldFJlY3RGaWxsQXBwU3RyZWFtKHJjV2luZG93LENQV0xfVXRpbHM6OlN1YnN0cmFjdENvbG9yKGNyQmFja2dyb3VuZCwwLjI1ZikpICsgCisJCUNQV0xfVXRpbHM6OkdldEJvcmRlckFwcFN0cmVhbShyY1dpbmRvdyxmQm9yZGVyV2lkdGgsY3JCb3JkZXIsY3JMZWZ0VG9wLGNyUmlnaHRCb3R0b20sbkJvcmRlclN0eWxlLGRzQm9yZGVyKTsKKworCUNGWF9CeXRlU3RyaW5nIGNzQVBfRF9PRkYgPSBjc0FQX0RfT047CisKKwljc0FQX05fT04gKz0gQ1BXTF9VdGlsczo6R2V0Q2hlY2tCb3hBcHBTdHJlYW0ocmNDbGllbnQsblN0eWxlLGNyVGV4dCk7CisJY3NBUF9EX09OICs9IENQV0xfVXRpbHM6OkdldENoZWNrQm94QXBwU3RyZWFtKHJjQ2xpZW50LG5TdHlsZSxjclRleHQpOworCisJV3JpdGVBcHBlYXJhbmNlKCJOIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVBfTl9PTiwgcENvbnRyb2wtPkdldENoZWNrZWRBUFN0YXRlKCkpOworCVdyaXRlQXBwZWFyYW5jZSgiTiIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBjc0FQX05fT0ZGLCAiT2ZmIik7CisKKwlXcml0ZUFwcGVhcmFuY2UoIkQiLCBHZXRSb3RhdGVkUmVjdCgpLCBHZXRNYXRyaXgoKSwgY3NBUF9EX09OLCBwQ29udHJvbC0+R2V0Q2hlY2tlZEFQU3RhdGUoKSk7CisJV3JpdGVBcHBlYXJhbmNlKCJEIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVBfRF9PRkYsICJPZmYiKTsKKworCUNGWF9CeXRlU3RyaW5nIGNzQVMgPSBHZXRBcHBTdGF0ZSgpOworCWlmIChjc0FTLklzRW1wdHkoKSkKKwkJU2V0QXBwU3RhdGUoIk9mZiIpOworfQorCit2b2lkIENQREZTREtfV2lkZ2V0OjpSZXNldEFwcGVhcmFuY2VfUmFkaW9CdXR0b24oKQoreworCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gR2V0Rm9ybUNvbnRyb2woKTsKKwlBU1NFUlQocENvbnRyb2wgIT0gTlVMTCk7CisJCisKKworCUNQV0xfQ29sb3IgY3JCYWNrZ3JvdW5kLCBjckJvcmRlciwgY3JUZXh0OworCQorCWludCBpQ29sb3JUeXBlOworCUZYX0ZMT0FUIGZjWzRdOworCisJcENvbnRyb2wtPkdldE9yaWdpbmFsQmFja2dyb3VuZENvbG9yKGlDb2xvclR5cGUsIGZjKTsKKwlpZiAoaUNvbG9yVHlwZSA+IDApCisJCWNyQmFja2dyb3VuZCA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOworCisJcENvbnRyb2wtPkdldE9yaWdpbmFsQm9yZGVyQ29sb3IoaUNvbG9yVHlwZSwgZmMpOworCWlmIChpQ29sb3JUeXBlID4gMCkKKwkJY3JCb3JkZXIgPSBDUFdMX0NvbG9yKGlDb2xvclR5cGUsIGZjWzBdLCBmY1sxXSwgZmNbMl0sIGZjWzNdKTsKKworCUZYX0ZMT0FUIGZCb3JkZXJXaWR0aCA9IChGWF9GTE9BVClHZXRCb3JkZXJXaWR0aCgpOworCUZYX0lOVDMyIG5Cb3JkZXJTdHlsZSA9IDA7CisJQ1BXTF9EYXNoIGRzQm9yZGVyKDMsMCwwKTsKKwlDUFdMX0NvbG9yIGNyTGVmdFRvcCxjclJpZ2h0Qm90dG9tOworCisJc3dpdGNoIChHZXRCb3JkZXJTdHlsZSgpKQorCXsKKwljYXNlIEJCU19EQVNIOgorCQluQm9yZGVyU3R5bGUgPSBQQlNfREFTSDsKKwkJZHNCb3JkZXIgPSBDUFdMX0Rhc2goMywgMywgMCk7CisJCWJyZWFrOworCWNhc2UgQkJTX0JFVkVMRUQ6CisJCW5Cb3JkZXJTdHlsZSA9IFBCU19CRVZFTEVEOworCQlmQm9yZGVyV2lkdGggKj0gMjsKKwkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwxKTsKKwkJY3JSaWdodEJvdHRvbSA9IENQV0xfVXRpbHM6OkRldmlkZUNvbG9yKGNyQmFja2dyb3VuZCwyKTsKKwkJYnJlYWs7CisJY2FzZSBCQlNfSU5TRVQ6CisJCW5Cb3JkZXJTdHlsZSA9IFBCU19JTlNFVDsKKwkJZkJvcmRlcldpZHRoICo9IDI7CisJCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC41KTsKKwkJY3JSaWdodEJvdHRvbSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC43NSk7CisJCWJyZWFrOworCWNhc2UgQkJTX1VOREVSTElORToKKwkJbkJvcmRlclN0eWxlID0gUEJTX1VOREVSTElORUQ7CisJCWJyZWFrOworCWRlZmF1bHQ6IAorCQluQm9yZGVyU3R5bGUgPSBQQlNfU09MSUQ7CisJCWJyZWFrOworCX0KKworCUNQREZfUmVjdCByY1dpbmRvdyA9IEdldFJvdGF0ZWRSZWN0KCk7CisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmNXaW5kb3csIGZCb3JkZXJXaWR0aCk7CisKKwlDUERGX0RlZmF1bHRBcHBlYXJhbmNlIGRhID0gcENvbnRyb2wtPkdldERlZmF1bHRBcHBlYXJhbmNlKCk7CisJaWYgKGRhLkhhc0NvbG9yKCkpCisJeworCQlkYS5HZXRDb2xvcihpQ29sb3JUeXBlLCBmYyk7CisJCWNyVGV4dCA9IENQV0xfQ29sb3IoaUNvbG9yVHlwZSwgZmNbMF0sIGZjWzFdLCBmY1syXSwgZmNbM10pOworCX0KKworCUZYX0lOVDMyIG5TdHlsZSA9IDA7CisKKwlDRlhfV2lkZVN0cmluZyBjc1dDYXB0aW9uID0gcENvbnRyb2wtPkdldE5vcm1hbENhcHRpb24oKTsKKwlpZiAoY3NXQ2FwdGlvbi5HZXRMZW5ndGgoKSA+IDApCisJeworCQlzd2l0Y2ggKGNzV0NhcHRpb25bMF0pCisJCXsKKwkJZGVmYXVsdDogLy9MJ2wnOgorCQkJblN0eWxlID0gUENTX0NJUkNMRTsJCQkKKwkJCWJyZWFrOworCQljYXNlIEwnOCc6CisJCQluU3R5bGUgPSBQQ1NfQ1JPU1M7CisJCQlicmVhazsKKwkJY2FzZSBMJ3UnOgorCQkJblN0eWxlID0gUENTX0RJQU1PTkQ7CisJCQlicmVhazsKKwkJY2FzZSBMJ24nOgorCQkJblN0eWxlID0gUENTX1NRVUFSRTsKKwkJCWJyZWFrOworCQljYXNlIEwnSCc6CisJCQluU3R5bGUgPSBQQ1NfU1RBUjsKKwkJCWJyZWFrOworCQljYXNlIEwnNCc6CisJCQluU3R5bGUgPSBQQ1NfQ0hFQ0s7CisJCQlicmVhazsKKwkJfQorCX0KKwllbHNlCisJeworCQluU3R5bGUgPSBQQ1NfQ0lSQ0xFOworCX0KKworCUNGWF9CeXRlU3RyaW5nIGNzQVBfTl9PTjsKKworCUNQREZfUmVjdCByY0NlbnRlciA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KENQV0xfVXRpbHM6OkdldENlbnRlclNxdWFyZShyY1dpbmRvdyksIDEuMGYpOworCQorCWlmIChuU3R5bGUgPT0gUENTX0NJUkNMRSkKKwl7CisJCWlmIChuQm9yZGVyU3R5bGUgPT0gUEJTX0JFVkVMRUQpCisJCXsKKwkJCWNyTGVmdFRvcCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDEpOworCQkJY3JSaWdodEJvdHRvbSA9IENQV0xfVXRpbHM6OlN1YnN0cmFjdENvbG9yKGNyQmFja2dyb3VuZCwwLjI1Zik7CisJCX0KKwkJZWxzZSBpZiAobkJvcmRlclN0eWxlID09IFBCU19JTlNFVCkKKwkJeworCQkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwLjVmKTsKKwkJCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDAuNzVmKTsKKwkJfQorCisJCWNzQVBfTl9PTiA9IENQV0xfVXRpbHM6OkdldENpcmNsZUZpbGxBcHBTdHJlYW0ocmNDZW50ZXIsY3JCYWNrZ3JvdW5kKSArIAorCQkJQ1BXTF9VdGlsczo6R2V0Q2lyY2xlQm9yZGVyQXBwU3RyZWFtKHJjQ2VudGVyLGZCb3JkZXJXaWR0aCxjckJvcmRlcixjckxlZnRUb3AsY3JSaWdodEJvdHRvbSxuQm9yZGVyU3R5bGUsZHNCb3JkZXIpOworCX0KKwllbHNlCisJeworCQljc0FQX05fT04gPSBDUFdMX1V0aWxzOjpHZXRSZWN0RmlsbEFwcFN0cmVhbShyY1dpbmRvdyxjckJhY2tncm91bmQpICsgCisJCQlDUFdMX1V0aWxzOjpHZXRCb3JkZXJBcHBTdHJlYW0ocmNXaW5kb3csZkJvcmRlcldpZHRoLGNyQm9yZGVyLGNyTGVmdFRvcCxjclJpZ2h0Qm90dG9tLG5Cb3JkZXJTdHlsZSxkc0JvcmRlcik7CisJfQorCisJQ0ZYX0J5dGVTdHJpbmcgY3NBUF9OX09GRiA9IGNzQVBfTl9PTjsKKworCXN3aXRjaCAobkJvcmRlclN0eWxlKQorCXsKKwljYXNlIFBCU19CRVZFTEVEOgorCQl7CisJCQlDUFdMX0NvbG9yIGNyVGVtcCA9IGNyTGVmdFRvcDsKKwkJCWNyTGVmdFRvcCA9IGNyUmlnaHRCb3R0b207CisJCQljclJpZ2h0Qm90dG9tID0gY3JUZW1wOworCQl9CisJCWJyZWFrOworCWNhc2UgUEJTX0lOU0VUOgorCQljckxlZnRUb3AgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDApOworCQljclJpZ2h0Qm90dG9tID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwxKTsKKwkJYnJlYWs7CisJfQorCisJQ0ZYX0J5dGVTdHJpbmcgY3NBUF9EX09OOworCisJaWYgKG5TdHlsZSA9PSBQQ1NfQ0lSQ0xFKQorCXsKKwkJQ1BXTF9Db2xvciBjckJLID0gQ1BXTF9VdGlsczo6U3Vic3RyYWN0Q29sb3IoY3JCYWNrZ3JvdW5kLDAuMjVmKTsKKwkJaWYgKG5Cb3JkZXJTdHlsZSA9PSBQQlNfQkVWRUxFRCkKKwkJeworCQkJY3JMZWZ0VG9wID0gQ1BXTF9VdGlsczo6U3Vic3RyYWN0Q29sb3IoY3JCYWNrZ3JvdW5kLDAuMjVmKTsKKwkJCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLCAxKTsKKwkJCWNyQksgPSBjckJhY2tncm91bmQ7CisJCX0KKwkJZWxzZSBpZiAobkJvcmRlclN0eWxlID09IFBCU19JTlNFVCkKKwkJeworCQkJY3JMZWZ0VG9wID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwKTsKKwkJCWNyUmlnaHRCb3R0b20gPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOworCQl9CisKKwkJY3NBUF9EX09OID0gQ1BXTF9VdGlsczo6R2V0Q2lyY2xlRmlsbEFwcFN0cmVhbShyY0NlbnRlcixjckJLKQorCQkJKyBDUFdMX1V0aWxzOjpHZXRDaXJjbGVCb3JkZXJBcHBTdHJlYW0ocmNDZW50ZXIsZkJvcmRlcldpZHRoLGNyQm9yZGVyLGNyTGVmdFRvcCxjclJpZ2h0Qm90dG9tLG5Cb3JkZXJTdHlsZSxkc0JvcmRlcik7CisJfQorCWVsc2UKKwl7CisJCWNzQVBfRF9PTiA9IENQV0xfVXRpbHM6OkdldFJlY3RGaWxsQXBwU3RyZWFtKHJjV2luZG93LENQV0xfVXRpbHM6OlN1YnN0cmFjdENvbG9yKGNyQmFja2dyb3VuZCwwLjI1ZikpICsgCisJCQlDUFdMX1V0aWxzOjpHZXRCb3JkZXJBcHBTdHJlYW0ocmNXaW5kb3csZkJvcmRlcldpZHRoLGNyQm9yZGVyLGNyTGVmdFRvcCxjclJpZ2h0Qm90dG9tLG5Cb3JkZXJTdHlsZSxkc0JvcmRlcik7CQkKKwl9CisKKwlDRlhfQnl0ZVN0cmluZyBjc0FQX0RfT0ZGID0gY3NBUF9EX09OOworCisJY3NBUF9OX09OICs9IENQV0xfVXRpbHM6OkdldFJhZGlvQnV0dG9uQXBwU3RyZWFtKHJjQ2xpZW50LG5TdHlsZSxjclRleHQpOworCWNzQVBfRF9PTiArPSBDUFdMX1V0aWxzOjpHZXRSYWRpb0J1dHRvbkFwcFN0cmVhbShyY0NsaWVudCxuU3R5bGUsY3JUZXh0KTsKKworCVdyaXRlQXBwZWFyYW5jZSgiTiIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBjc0FQX05fT04sIHBDb250cm9sLT5HZXRDaGVja2VkQVBTdGF0ZSgpKTsKKwlXcml0ZUFwcGVhcmFuY2UoIk4iLCBHZXRSb3RhdGVkUmVjdCgpLCBHZXRNYXRyaXgoKSwgY3NBUF9OX09GRiwgIk9mZiIpOworCisJV3JpdGVBcHBlYXJhbmNlKCJEIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIGNzQVBfRF9PTiwgcENvbnRyb2wtPkdldENoZWNrZWRBUFN0YXRlKCkpOworCVdyaXRlQXBwZWFyYW5jZSgiRCIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBjc0FQX0RfT0ZGLCAiT2ZmIik7CisKKwlDRlhfQnl0ZVN0cmluZyBjc0FTID0gR2V0QXBwU3RhdGUoKTsKKwlpZiAoY3NBUy5Jc0VtcHR5KCkpCisJCVNldEFwcFN0YXRlKCJPZmYiKTsKK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6UmVzZXRBcHBlYXJhbmNlX0NvbWJvQm94KEZYX0xQQ1dTVFIgc1ZhbHVlKQoreworCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gR2V0Rm9ybUNvbnRyb2woKTsKKwlBU1NFUlQocENvbnRyb2wgIT0gTlVMTCk7CisJQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCA9IHBDb250cm9sLT5HZXRGaWVsZCgpOworCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwlDRlhfQnl0ZVRleHRCdWYgc0JvZHksIHNMaW5lczsKKworCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKwlDUERGX1JlY3QgcmNCdXR0b24gPSByY0NsaWVudDsKKwlyY0J1dHRvbi5sZWZ0ID0gcmNCdXR0b24ucmlnaHQgLSAxMzsKKwlyY0J1dHRvbi5Ob3JtYWxpemUoKTsKKworCWlmIChJRlhfRWRpdCAqIHBFZGl0ID0gSUZYX0VkaXQ6Ok5ld0VkaXQoKSkKKwl7CisJCXBFZGl0LT5FbmFibGVSZWZyZXNoKEZBTFNFKTsKKworCQlBU1NFUlQodGhpcy0+bV9wSW50ZXJGb3JtICE9IE5VTEwpOworCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jID0gbV9wSW50ZXJGb3JtLT5HZXREb2N1bWVudCgpOworCQlBU1NFUlQocERvYyAhPSBOVUxMKTsKKwkJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2MtPkdldEVudigpOworCQlDQkFfRm9udE1hcCBGb250TWFwKHRoaXMscEVudi0+R2V0U3lzSGFuZGxlcigpKTsKKwkJRm9udE1hcC5Jbml0aWFsKCk7CisJCXBFZGl0LT5TZXRGb250TWFwKCZGb250TWFwKTsKKworCQlDUERGX1JlY3QgcmNFZGl0ID0gcmNDbGllbnQ7CisJCXJjRWRpdC5yaWdodCA9IHJjQnV0dG9uLmxlZnQ7CisJCXJjRWRpdC5Ob3JtYWxpemUoKTsKKwkJCisJCXBFZGl0LT5TZXRQbGF0ZVJlY3QocmNFZGl0KTsKKwkJcEVkaXQtPlNldEFsaWdubWVudFYoMSk7CisKKwkJRlhfRkxPQVQgZkZvbnRTaXplID0gdGhpcy0+R2V0Rm9udFNpemUoKTsKKwkJaWYgKElzRmxvYXRaZXJvKGZGb250U2l6ZSkpCisJCQlwRWRpdC0+U2V0QXV0b0ZvbnRTaXplKFRSVUUpOworCQllbHNlCisJCQlwRWRpdC0+U2V0Rm9udFNpemUoZkZvbnRTaXplKTsKKwkJCisJCXBFZGl0LT5Jbml0aWFsaXplKCk7CisJCQorCQlpZiAoc1ZhbHVlKQorCQkJcEVkaXQtPlNldFRleHQoc1ZhbHVlKTsKKwkJZWxzZQorCQl7CisJCQlGWF9JTlQzMiBuQ3VyU2VsID0gcEZpZWxkLT5HZXRTZWxlY3RlZEluZGV4KDApOworCisJCQlpZiAobkN1clNlbCA8IDApCisJCQkJcEVkaXQtPlNldFRleHQoKEZYX0xQQ1dTVFIpcEZpZWxkLT5HZXRWYWx1ZSgpKTsKKwkJCWVsc2UKKwkJCQlwRWRpdC0+U2V0VGV4dCgoRlhfTFBDV1NUUilwRmllbGQtPkdldE9wdGlvbkxhYmVsKG5DdXJTZWwpKTsKKwkJfQorCisJCUNQREZfUmVjdCByY0NvbnRlbnQgPSBwRWRpdC0+R2V0Q29udGVudFJlY3QoKTsKKworCQlDRlhfQnl0ZVN0cmluZyBzRWRpdCA9IENQV0xfVXRpbHM6OkdldEVkaXRBcHBTdHJlYW0ocEVkaXQsQ1BERl9Qb2ludCgwLjBmLDAuMGYpKTsKKwkJaWYgKHNFZGl0LkdldExlbmd0aCgpID4gMCkKKwkJeworCQkJc0JvZHkgPDwgIi9UeCBCTUNcbiIgPDwgInFcbiI7CisJCQlpZiAocmNDb250ZW50LldpZHRoKCkgPiByY0VkaXQuV2lkdGgoKSB8fAorCQkJCXJjQ29udGVudC5IZWlnaHQoKSA+IHJjRWRpdC5IZWlnaHQoKSkKKwkJCXsKKwkJCQlzQm9keSA8PCByY0VkaXQubGVmdCA8PCAiICIgPDwgcmNFZGl0LmJvdHRvbSA8PCAiICIgCisJCQkJCTw8IHJjRWRpdC5XaWR0aCgpIDw8ICIgIiA8PCByY0VkaXQuSGVpZ2h0KCkgPDwgIiByZVxuV1xublxuIjsKKwkJCX0KKworCQkJQ1BXTF9Db2xvciBjclRleHQgPSBHZXRUZXh0UFdMQ29sb3IoKTsJCisJCQlzQm9keSA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JUZXh0KSA8PCBzRWRpdCA8PCAiRVRcbiIgPDwgIlFcbkVNQ1xuIjsKKwkJfQorCisJCUlGWF9FZGl0OjpEZWxFZGl0KHBFZGl0KTsKKwl9CisKKwlzQm9keSA8PCBDUFdMX1V0aWxzOjpHZXREcm9wQnV0dG9uQXBwU3RyZWFtKHJjQnV0dG9uKTsKKworCUNGWF9CeXRlU3RyaW5nIHNBUCA9IEdldEJhY2tncm91bmRBcHBTdHJlYW0oKSArIEdldEJvcmRlckFwcFN0cmVhbSgpICsgc0xpbmVzLkdldEJ5dGVTdHJpbmcoKSArIHNCb2R5LkdldEJ5dGVTdHJpbmcoKTsKKworCVdyaXRlQXBwZWFyYW5jZSgiTiIsIEdldFJvdGF0ZWRSZWN0KCksIEdldE1hdHJpeCgpLCBzQVApOworfQorCit2b2lkIENQREZTREtfV2lkZ2V0OjpSZXNldEFwcGVhcmFuY2VfTGlzdEJveCgpCit7CisJQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wgPSBHZXRGb3JtQ29udHJvbCgpOworCUFTU0VSVChwQ29udHJvbCAhPSBOVUxMKTsKKwlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gcENvbnRyb2wtPkdldEZpZWxkKCk7CisJQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsKKworCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKworCUNGWF9CeXRlVGV4dEJ1ZiBzQm9keSwgc0xpbmVzOworCisJaWYgKElGWF9FZGl0ICogcEVkaXQgPSBJRlhfRWRpdDo6TmV3RWRpdCgpKQorCXsKKwkJcEVkaXQtPkVuYWJsZVJlZnJlc2goRkFMU0UpOworCisvLwkJQVNTRVJUKHRoaXMtPm1fcEJhc2VGb3JtICE9IE5VTEwpOworCQlBU1NFUlQodGhpcy0+bV9wSW50ZXJGb3JtICE9IE5VTEwpOworCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jID0gbV9wSW50ZXJGb3JtLT5HZXREb2N1bWVudCgpOworCQlBU1NFUlQocERvYyAhPSBOVUxMKTsKKwkJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2MtPkdldEVudigpOworCisJCUNCQV9Gb250TWFwIEZvbnRNYXAodGhpcyxwRW52LT5HZXRTeXNIYW5kbGVyKCkpOworCQlGb250TWFwLkluaXRpYWwoKTsKKwkJcEVkaXQtPlNldEZvbnRNYXAoJkZvbnRNYXApOworCisJCXBFZGl0LT5TZXRQbGF0ZVJlY3QoQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQsMC4wZixyY0NsaWVudC5yaWdodCwwLjBmKSk7CQorCQkKKwkJRlhfRkxPQVQgZkZvbnRTaXplID0gR2V0Rm9udFNpemUoKTsKKworCQlpZiAoSXNGbG9hdFplcm8oZkZvbnRTaXplKSkKKwkJCXBFZGl0LT5TZXRGb250U2l6ZSgxMi4wZik7CisJCWVsc2UKKwkJCXBFZGl0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOworCQkKKwkJcEVkaXQtPkluaXRpYWxpemUoKTsKKworCQlDRlhfQnl0ZVRleHRCdWYgc0xpc3Q7CisJCUZYX0ZMT0FUIGZ5ID0gcmNDbGllbnQudG9wOworCisJCUZYX0lOVDMyIG5Ub3AgPSBwRmllbGQtPkdldFRvcFZpc2libGVJbmRleCgpOworCQlGWF9JTlQzMiBuQ291bnQgPSBwRmllbGQtPkNvdW50T3B0aW9ucygpOworCQlGWF9JTlQzMiBuU2VsQ291bnQgPSBwRmllbGQtPkNvdW50U2VsZWN0ZWRJdGVtcygpOworCisJCWZvciAoRlhfSU5UMzIgaT1uVG9wOyBpPG5Db3VudDsgaSsrKQorCQl7CisJCQlGWF9CT09MIGJTZWxlY3RlZCA9IEZBTFNFOwkJCQkKKwkJCWZvciAoRlhfSU5UMzIgaj0wOyBqPG5TZWxDb3VudDsgaisrKQorCQkJeworCQkJCWlmIChwRmllbGQtPkdldFNlbGVjdGVkSW5kZXgoaikgPT0gaSkKKwkJCQl7CisJCQkJCWJTZWxlY3RlZCA9IFRSVUU7CisJCQkJCWJyZWFrOworCQkJCX0KKwkJCX0KKworCQkJcEVkaXQtPlNldFRleHQoKEZYX0xQQ1dTVFIpcEZpZWxkLT5HZXRPcHRpb25MYWJlbChpKSk7CisKKwkJCUNQREZfUmVjdCByY0NvbnRlbnQgPSBwRWRpdC0+R2V0Q29udGVudFJlY3QoKTsKKwkJCUZYX0ZMT0FUIGZJdGVtSGVpZ2h0ID0gcmNDb250ZW50LkhlaWdodCgpOworCisJCQlpZiAoYlNlbGVjdGVkKQorCQkJeworCQkJCUNQREZfUmVjdCByY0l0ZW0gPSBDUERGX1JlY3QocmNDbGllbnQubGVmdCxmeS1mSXRlbUhlaWdodCxyY0NsaWVudC5yaWdodCxmeSk7CisJCQkJc0xpc3QgPDwgInFcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLDAsNTEuMGYvMjU1LjBmLDExMy4wZi8yNTUuMGYpLFRSVUUpCisJCQkJCTw8IHJjSXRlbS5sZWZ0IDw8ICIgIiA8PCByY0l0ZW0uYm90dG9tIDw8ICIgIiA8PCByY0l0ZW0uV2lkdGgoKSA8PCAiICIgPDwgcmNJdGVtLkhlaWdodCgpIDw8ICIgcmUgZlxuIiA8PCAiUVxuIjsKKworCQkJCXNMaXN0IDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpLFRSVUUpIDw8IAorCQkJCQlDUFdMX1V0aWxzOjpHZXRFZGl0QXBwU3RyZWFtKHBFZGl0LENQREZfUG9pbnQoMC4wZixmeSkpIDw8ICJFVFxuIjsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlDUFdMX0NvbG9yIGNyVGV4dCA9IEdldFRleHRQV0xDb2xvcigpOworCQkJCXNMaXN0IDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclRleHQsVFJVRSkgPDwgCisJCQkJQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShwRWRpdCxDUERGX1BvaW50KDAuMGYsZnkpKSA8PCAiRVRcbiI7CisJCQl9CisKKwkJCWZ5IC09IGZJdGVtSGVpZ2h0OworCQl9CisJCQkJCQorCQlpZiAoc0xpc3QuR2V0U2l6ZSgpID4gMCkKKwkJeworCQkJc0JvZHkgPDwgIi9UeCBCTUNcbiIgPDwgInFcbiIgPDwgcmNDbGllbnQubGVmdCA8PCAiICIgPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgIiAKKwkJCQkJPDwgcmNDbGllbnQuV2lkdGgoKSA8PCAiICIgPDwgcmNDbGllbnQuSGVpZ2h0KCkgPDwgIiByZVxuV1xublxuIjsKKwkJCXNCb2R5IDw8IHNMaXN0IDw8ICJRXG5FTUNcbiI7CisJCX0KKworCQlJRlhfRWRpdDo6RGVsRWRpdChwRWRpdCk7CisJfQorCisJQ0ZYX0J5dGVTdHJpbmcgc0FQID0gR2V0QmFja2dyb3VuZEFwcFN0cmVhbSgpICsgR2V0Qm9yZGVyQXBwU3RyZWFtKCkgKyBzTGluZXMuR2V0Qnl0ZVN0cmluZygpICsgc0JvZHkuR2V0Qnl0ZVN0cmluZygpOworCisJV3JpdGVBcHBlYXJhbmNlKCJOIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIHNBUCk7Cit9CisKK3ZvaWQgQ1BERlNES19XaWRnZXQ6OlJlc2V0QXBwZWFyYW5jZV9UZXh0RmllbGQoRlhfTFBDV1NUUiBzVmFsdWUpCit7CisJQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wgPSBHZXRGb3JtQ29udHJvbCgpOworCUFTU0VSVChwQ29udHJvbCAhPSBOVUxMKTsKKwlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gcENvbnRyb2wtPkdldEZpZWxkKCk7CisJQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsKKworCUNGWF9CeXRlVGV4dEJ1ZiBzQm9keSwgc0xpbmVzOworCQorCWlmIChJRlhfRWRpdCAqIHBFZGl0ID0gSUZYX0VkaXQ6Ok5ld0VkaXQoKSkKKwl7CisJCXBFZGl0LT5FbmFibGVSZWZyZXNoKEZBTFNFKTsKKworLy8JCUFTU0VSVCh0aGlzLT5tX3BCYXNlRm9ybSAhPSBOVUxMKTsKKwkJQVNTRVJUKHRoaXMtPm1fcEludGVyRm9ybSAhPSBOVUxMKTsKKwkJQ1BERlNES19Eb2N1bWVudCogcERvYyA9IG1fcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKTsKKwkJQVNTRVJUKHBEb2MgIT0gTlVMTCk7CisJCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBwRG9jLT5HZXRFbnYoKTsKKworCQlDQkFfRm9udE1hcCBGb250TWFwKHRoaXMscEVudi0+R2V0U3lzSGFuZGxlcigpKTsvLywgSVN5c3RlbUhhbmRsZTo6R2V0U3lzdGVtSGFuZGxlcihtX3BCYXNlRm9ybS0+R2V0RW52KCkpKTsKKwkJRm9udE1hcC5Jbml0aWFsKCk7CisJCXBFZGl0LT5TZXRGb250TWFwKCZGb250TWFwKTsKKworCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisJCXBFZGl0LT5TZXRQbGF0ZVJlY3QocmNDbGllbnQpOworCQlwRWRpdC0+U2V0QWxpZ25tZW50SChwQ29udHJvbC0+R2V0Q29udHJvbEFsaWdubWVudCgpKTsKKwkJCisJCUZYX0RXT1JEIGR3RmllbGRGbGFncyA9IHBGaWVsZC0+R2V0RmllbGRGbGFncygpOworCQlGWF9CT09MIGJNdWx0aUxpbmUgPSAoZHdGaWVsZEZsYWdzID4+IDEyKSAmIDE7CisKKwkJaWYgKGJNdWx0aUxpbmUpCisJCXsKKwkJCXBFZGl0LT5TZXRNdWx0aUxpbmUoVFJVRSk7CisJCQlwRWRpdC0+U2V0QXV0b1JldHVybihUUlVFKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCXBFZGl0LT5TZXRBbGlnbm1lbnRWKDEpOworCQl9CisKKwkJRlhfV09SRCBzdWJXb3JkID0gMDsKKwkJaWYgKChkd0ZpZWxkRmxhZ3MgPj4gMTMpICYgMSkKKwkJeworCQkJc3ViV29yZCA9ICcqJzsKKwkJCXBFZGl0LT5TZXRQYXNzd29yZENoYXIoc3ViV29yZCk7CisJCX0KKworCQlpbnQgbk1heExlbiA9IHBGaWVsZC0+R2V0TWF4TGVuKCk7CisJCUZYX0JPT0wgYkNoYXJBcnJheSA9IChkd0ZpZWxkRmxhZ3MgPj4gMjQpICYgMTsKKwkJRlhfRkxPQVQgZkZvbnRTaXplID0gR2V0Rm9udFNpemUoKTsJCisKKwkJaWYgKG5NYXhMZW4gPiAwKQorCQl7CisJCQlpZiAoYkNoYXJBcnJheSkKKwkJCXsKKwkJCQlwRWRpdC0+U2V0Q2hhckFycmF5KG5NYXhMZW4pOworCisJCQkJaWYgKElzRmxvYXRaZXJvKGZGb250U2l6ZSkpCisJCQkJeworCQkJCQlmRm9udFNpemUgPSBDUFdMX0VkaXQ6OkdldENoYXJBcnJheUF1dG9Gb250U2l6ZShGb250TWFwLkdldFBERkZvbnQoMCkscmNDbGllbnQsbk1heExlbik7CisJCQkJfQorCQkJfQorCQkJZWxzZQorCQkJeworCQkJCWlmIChzVmFsdWUpCisJCQkJCW5NYXhMZW4gPSB3Y3NsZW4oKGNvbnN0IHdjaGFyX3QqKXNWYWx1ZSk7IAorCQkJCXBFZGl0LT5TZXRMaW1pdENoYXIobk1heExlbik7CisJCQl9CisJCX0KKworCQlpZiAoSXNGbG9hdFplcm8oZkZvbnRTaXplKSkKKwkJCXBFZGl0LT5TZXRBdXRvRm9udFNpemUoVFJVRSk7CisJCWVsc2UKKwkJCXBFZGl0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOworCisJCXBFZGl0LT5Jbml0aWFsaXplKCk7CisJCQorCQlpZiAoc1ZhbHVlKQorCQkJcEVkaXQtPlNldFRleHQoc1ZhbHVlKTsKKwkJZWxzZQorCQkJcEVkaXQtPlNldFRleHQoKEZYX0xQQ1dTVFIpcEZpZWxkLT5HZXRWYWx1ZSgpKTsKKworCQlDUERGX1JlY3QgcmNDb250ZW50ID0gcEVkaXQtPkdldENvbnRlbnRSZWN0KCk7CisKKwkJQ0ZYX0J5dGVTdHJpbmcgc0VkaXQgPSBDUFdMX1V0aWxzOjpHZXRFZGl0QXBwU3RyZWFtKHBFZGl0LENQREZfUG9pbnQoMC4wZiwwLjBmKSwKKwkJCQkJCQkJCQkJCQkJCQkJTlVMTCwhYkNoYXJBcnJheSxzdWJXb3JkKTsKKworCQlpZiAoc0VkaXQuR2V0TGVuZ3RoKCkgPiAwKQorCQl7CisJCQlzQm9keSA8PCAiL1R4IEJNQ1xuIiA8PCAicVxuIjsKKwkJCWlmIChyY0NvbnRlbnQuV2lkdGgoKSA+IHJjQ2xpZW50LldpZHRoKCkgfHwKKwkJCQlyY0NvbnRlbnQuSGVpZ2h0KCkgPiByY0NsaWVudC5IZWlnaHQoKSkKKwkJCXsKKwkJCQlzQm9keSA8PCByY0NsaWVudC5sZWZ0IDw8ICIgIiA8PCByY0NsaWVudC5ib3R0b20gPDwgIiAiIAorCQkJCQk8PCByY0NsaWVudC5XaWR0aCgpIDw8ICIgIiA8PCByY0NsaWVudC5IZWlnaHQoKSA8PCAiIHJlXG5XXG5uXG4iOworCQkJfQorCQkJQ1BXTF9Db2xvciBjclRleHQgPSBHZXRUZXh0UFdMQ29sb3IoKTsJCisJCQlzQm9keSA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JUZXh0KSA8PCBzRWRpdCA8PCAiRVRcbiIgPDwgIlFcbkVNQ1xuIjsKKwkJfQorCisJCWlmIChiQ2hhckFycmF5KQorCQl7CisJCQlzd2l0Y2ggKEdldEJvcmRlclN0eWxlKCkpCisJCQl7CisJCQljYXNlIEJCU19TT0xJRDoKKwkJCQl7CisJCQkJCUNGWF9CeXRlU3RyaW5nIHNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldEJvcmRlclBXTENvbG9yKCksRkFMU0UpOworCQkJCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkKKwkJCQkJeworCQkJCQkJc0xpbmVzIDw8ICJxXG4iIDw8IEdldEJvcmRlcldpZHRoKCkgPDwgIiB3XG4iIAorCQkJCQkJCTw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldEJvcmRlclBXTENvbG9yKCksRkFMU0UpIDw8ICIgMiBKIDAgalxuIjsJCQkJCQorCisJCQkJCQlmb3IgKEZYX0lOVDMyIGk9MTtpPG5NYXhMZW47aSsrKQorCQkJCQkJeworCQkJCQkJCXNMaW5lcyA8PCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25NYXhMZW4pKmkgPDwgIiAiCisJCQkJCQkJCTw8IHJjQ2xpZW50LmJvdHRvbSA8PCAiIG1cbiIKKwkJCQkJCQkJPDwgcmNDbGllbnQubGVmdCArICgocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0KS9uTWF4TGVuKSppIDw8ICIgIgorCQkJCQkJCQk8PCByY0NsaWVudC50b3AgPDwgIiBsIFNcbiI7CQkJCQkJCisJCQkJCQl9CisKKwkJCQkJCXNMaW5lcyA8PCAiUVxuIjsJCQorCQkJCQl9CisJCQkJfQorCQkJCWJyZWFrOworCQkJY2FzZSBCQlNfREFTSDoKKwkJCQl7CisJCQkJCUNGWF9CeXRlU3RyaW5nIHNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldEJvcmRlclBXTENvbG9yKCksRkFMU0UpOworCQkJCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkKKwkJCQkJeworCQkJCQkJQ1BXTF9EYXNoIGRzQm9yZGVyID0gQ1BXTF9EYXNoKDMsIDMsIDApOworCisJCQkJCQlzTGluZXMgPDwgInFcbiIgPDwgR2V0Qm9yZGVyV2lkdGgoKSA8PCAiIHdcbiIgCisJCQkJCQkJPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oR2V0Qm9yZGVyUFdMQ29sb3IoKSxGQUxTRSkKKwkJCQkJCQk8PCAiWyIgPDwgZHNCb3JkZXIubkRhc2ggPDwgIiAiIAorCQkJCQkJCTw8IGRzQm9yZGVyLm5HYXAgPDwgIl0gIiAKKwkJCQkJCQk8PCBkc0JvcmRlci5uUGhhc2UgPDwgIiBkXG4iOworCisJCQkJCQlmb3IgKEZYX0lOVDMyIGk9MTtpPG5NYXhMZW47aSsrKQkJCQkJCisJCQkJCQl7CisJCQkJCQkJc0xpbmVzIDw8IHJjQ2xpZW50LmxlZnQgKyAoKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCkvbk1heExlbikqaSA8PCAiICIKKwkJCQkJCQkJPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgbVxuIgorCQkJCQkJCQk8PCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25NYXhMZW4pKmkgPDwgIiAiCisJCQkJCQkJCTw8IHJjQ2xpZW50LnRvcCA8PCAiIGwgU1xuIjsJCisJCQkJCQl9CisKKwkJCQkJCXNMaW5lcyA8PCAiUVxuIjsKKwkJCQkJfQorCQkJCX0KKwkJCQlicmVhazsKKwkJCX0KKwkJfQorCisJCUlGWF9FZGl0OjpEZWxFZGl0KHBFZGl0KTsKKwl9CisKKwlDRlhfQnl0ZVN0cmluZyBzQVAgPSBHZXRCYWNrZ3JvdW5kQXBwU3RyZWFtKCkgKyBHZXRCb3JkZXJBcHBTdHJlYW0oKSArIHNMaW5lcy5HZXRCeXRlU3RyaW5nKCkgKyBzQm9keS5HZXRCeXRlU3RyaW5nKCk7CisJV3JpdGVBcHBlYXJhbmNlKCJOIiwgR2V0Um90YXRlZFJlY3QoKSwgR2V0TWF0cml4KCksIHNBUCk7Cit9CisKK0NQREZfUmVjdCBDUERGU0RLX1dpZGdldDo6R2V0Q2xpZW50UmVjdCgpIGNvbnN0Cit7CisJQ1BERl9SZWN0IHJjV2luZG93ID0gR2V0Um90YXRlZFJlY3QoKTsKKwlGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpR2V0Qm9yZGVyV2lkdGgoKTsKKwlzd2l0Y2ggKEdldEJvcmRlclN0eWxlKCkpCisJeworCWNhc2UgQkJTX0JFVkVMRUQ6CisJY2FzZSBCQlNfSU5TRVQ6CisJCWZCb3JkZXJXaWR0aCAqPSAyLjBmOworCQlicmVhazsKKwl9CisKKwlyZXR1cm4gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmNXaW5kb3csIGZCb3JkZXJXaWR0aCk7Cit9CisKK0NQREZfUmVjdCBDUERGU0RLX1dpZGdldDo6R2V0Um90YXRlZFJlY3QoKSBjb25zdAoreworCUNQREZfUmVjdCByZWN0QW5ub3QgPSBHZXRSZWN0KCk7CisJRlhfRkxPQVQgZldpZHRoID0gcmVjdEFubm90LnJpZ2h0IC0gcmVjdEFubm90LmxlZnQ7CisJRlhfRkxPQVQgZkhlaWdodCA9IHJlY3RBbm5vdC50b3AgLSByZWN0QW5ub3QuYm90dG9tOworCisJQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wgPSBHZXRGb3JtQ29udHJvbCgpOworCUFTU0VSVChwQ29udHJvbCAhPSBOVUxMKTsKKworCUNQREZfUmVjdCByY1BERldpbmRvdzsKKwlzd2l0Y2goYWJzKHBDb250cm9sLT5HZXRSb3RhdGlvbigpICUgMzYwKSkKKwl7CisJCWNhc2UgMDoKKwkJY2FzZSAxODA6CisJCWRlZmF1bHQ6CisJCQlyY1BERldpbmRvdyA9IENQREZfUmVjdCgwLCAwLCBmV2lkdGgsIGZIZWlnaHQpOwkKKwkJCWJyZWFrOworCQljYXNlIDkwOgorCQljYXNlIDI3MDoKKwkJCXJjUERGV2luZG93ID0gQ1BERl9SZWN0KDAsIDAsIGZIZWlnaHQsIGZXaWR0aCk7CisJCQlicmVhazsKKwl9CisKKwlyZXR1cm4gcmNQREZXaW5kb3c7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQREZTREtfV2lkZ2V0OjpHZXRCYWNrZ3JvdW5kQXBwU3RyZWFtKCkgY29uc3QKK3sKKwlDUFdMX0NvbG9yIGNyQmFja2dyb3VuZCA9IEdldEZpbGxQV0xDb2xvcigpOworCWlmIChjckJhY2tncm91bmQubkNvbG9yVHlwZSAhPSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQpCisJCXJldHVybiBDUFdMX1V0aWxzOjpHZXRSZWN0RmlsbEFwcFN0cmVhbShHZXRSb3RhdGVkUmVjdCgpLCBjckJhY2tncm91bmQpOworCWVsc2UKKwkJcmV0dXJuICIiOworfQorCitDRlhfQnl0ZVN0cmluZyBDUERGU0RLX1dpZGdldDo6R2V0Qm9yZGVyQXBwU3RyZWFtKCkgY29uc3QKK3sKKwlDUERGX1JlY3QgcmNXaW5kb3cgPSBHZXRSb3RhdGVkUmVjdCgpOworCUNQV0xfQ29sb3IgY3JCb3JkZXIgPSBHZXRCb3JkZXJQV0xDb2xvcigpOworCUNQV0xfQ29sb3IgY3JCYWNrZ3JvdW5kID0gR2V0RmlsbFBXTENvbG9yKCk7CisJQ1BXTF9Db2xvciBjckxlZnRUb3AsIGNyUmlnaHRCb3R0b207CisKKwlGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpR2V0Qm9yZGVyV2lkdGgoKTsKKwlGWF9JTlQzMiBuQm9yZGVyU3R5bGUgPSAwOworCUNQV0xfRGFzaCBkc0JvcmRlcigzLDAsMCk7CisKKwlzd2l0Y2ggKEdldEJvcmRlclN0eWxlKCkpCisJeworCWNhc2UgQkJTX0RBU0g6CisJCW5Cb3JkZXJTdHlsZSA9IFBCU19EQVNIOworCQlkc0JvcmRlciA9IENQV0xfRGFzaCgzLCAzLCAwKTsKKwkJYnJlYWs7CisJY2FzZSBCQlNfQkVWRUxFRDoKKwkJbkJvcmRlclN0eWxlID0gUEJTX0JFVkVMRUQ7CisJCWZCb3JkZXJXaWR0aCAqPSAyOworCQljckxlZnRUb3AgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLCAxKTsKKwkJY3JSaWdodEJvdHRvbSA9IENQV0xfVXRpbHM6OkRldmlkZUNvbG9yKGNyQmFja2dyb3VuZCwgMik7CisJCWJyZWFrOworCWNhc2UgQkJTX0lOU0VUOgorCQluQm9yZGVyU3R5bGUgPSBQQlNfSU5TRVQ7CisJCWZCb3JkZXJXaWR0aCAqPSAyOworCQljckxlZnRUb3AgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLCAwLjUpOworCQljclJpZ2h0Qm90dG9tID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMC43NSk7CisJCWJyZWFrOworCWNhc2UgQkJTX1VOREVSTElORToKKwkJbkJvcmRlclN0eWxlID0gUEJTX1VOREVSTElORUQ7CisJCWJyZWFrOworCWRlZmF1bHQ6IAorCQluQm9yZGVyU3R5bGUgPSBQQlNfU09MSUQ7CisJCWJyZWFrOworCX0KKworCXJldHVybiBDUFdMX1V0aWxzOjpHZXRCb3JkZXJBcHBTdHJlYW0ocmNXaW5kb3csIGZCb3JkZXJXaWR0aCwgY3JCb3JkZXIsIGNyTGVmdFRvcCwgCisJCWNyUmlnaHRCb3R0b20sIG5Cb3JkZXJTdHlsZSwgZHNCb3JkZXIpOworfQorCitDUERGX01hdHJpeCBDUERGU0RLX1dpZGdldDo6R2V0TWF0cml4KCkgY29uc3QKK3sKKwlDUERGX01hdHJpeCBtdDsKKwlDUERGX0Zvcm1Db250cm9sKiBwQ29udHJvbCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBDb250cm9sICE9IE5VTEwpOworCisJQ1BERl9SZWN0IHJjQW5ub3QgPSBHZXRSZWN0KCk7CisJRlhfRkxPQVQgZldpZHRoID0gcmNBbm5vdC5yaWdodCAtIHJjQW5ub3QubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gcmNBbm5vdC50b3AgLSByY0Fubm90LmJvdHRvbTsKKwkKKworCisJc3dpdGNoIChhYnMocENvbnRyb2wtPkdldFJvdGF0aW9uKCkgJSAzNjApKQorCXsKKwkJY2FzZSAwOgorCQlkZWZhdWx0OgorCQkJbXQgPSBDUERGX01hdHJpeCgxLCAwLCAwLCAxLCAwLCAwKTsKKwkJCWJyZWFrOworCQljYXNlIDkwOgorCQkJbXQgPSBDUERGX01hdHJpeCgwLCAxLCAtMSwgMCwgZldpZHRoLCAwKTsKKwkJCWJyZWFrOworCQljYXNlIDE4MDoKKwkJCW10ID0gQ1BERl9NYXRyaXgoLTEsIDAsIDAsIC0xLCBmV2lkdGgsIGZIZWlnaHQpOworCQkJYnJlYWs7CisJCWNhc2UgMjcwOgorCQkJbXQgPSBDUERGX01hdHJpeCgwLCAtMSwgMSwgMCwgMCwgZkhlaWdodCk7CisJCQlicmVhazsKKwl9CisKKwlyZXR1cm4gbXQ7Cit9CisKK0NQV0xfQ29sb3IgQ1BERlNES19XaWRnZXQ6OkdldFRleHRQV0xDb2xvcigpIGNvbnN0Cit7CisJQ1BXTF9Db2xvciBjclRleHQgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLCAwKTsKKworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsKKworCUNQREZfRGVmYXVsdEFwcGVhcmFuY2UgZGEgPSBwRm9ybUN0cmwtPkdldERlZmF1bHRBcHBlYXJhbmNlKCk7CisJaWYgKGRhLkhhc0NvbG9yKCkpCisJeworCQlGWF9JTlQzMiBpQ29sb3JUeXBlOworCQlGWF9GTE9BVCBmY1s0XTsKKwkJZGEuR2V0Q29sb3IoaUNvbG9yVHlwZSwgZmMpOworCQljclRleHQgPSBDUFdMX0NvbG9yKGlDb2xvclR5cGUsIGZjWzBdLCBmY1sxXSwgZmNbMl0sIGZjWzNdKTsKKwl9CisKKwlyZXR1cm4gY3JUZXh0OworfQorCitDUFdMX0NvbG9yIENQREZTREtfV2lkZ2V0OjpHZXRCb3JkZXJQV0xDb2xvcigpIGNvbnN0Cit7CisJQ1BXTF9Db2xvciBjckJvcmRlcjsKKworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IEdldEZvcm1Db250cm9sKCk7CisJQVNTRVJUKHBGb3JtQ3RybCAhPSBOVUxMKTsKKworCUZYX0lOVDMyIGlDb2xvclR5cGU7CisJRlhfRkxPQVQgZmNbNF07CisJcEZvcm1DdHJsLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKGlDb2xvclR5cGUsIGZjKTsKKwlpZiAoaUNvbG9yVHlwZSA+IDApCisJCWNyQm9yZGVyID0gQ1BXTF9Db2xvcihpQ29sb3JUeXBlLCBmY1swXSwgZmNbMV0sIGZjWzJdLCBmY1szXSk7CisKKwlyZXR1cm4gY3JCb3JkZXI7Cit9CisKK0NQV0xfQ29sb3IgQ1BERlNES19XaWRnZXQ6OkdldEZpbGxQV0xDb2xvcigpIGNvbnN0Cit7CisJQ1BXTF9Db2xvciBjckZpbGw7CisKKwlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUN0cmwgPSBHZXRGb3JtQ29udHJvbCgpOworCUFTU0VSVChwRm9ybUN0cmwgIT0gTlVMTCk7CisKKwlGWF9JTlQzMiBpQ29sb3JUeXBlOworCUZYX0ZMT0FUIGZjWzRdOworCXBGb3JtQ3RybC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoaUNvbG9yVHlwZSwgZmMpOworCWlmIChpQ29sb3JUeXBlID4gMCkKKwkJY3JGaWxsID0gQ1BXTF9Db2xvcihpQ29sb3JUeXBlLCBmY1swXSwgZmNbMV0sIGZjWzJdLCBmY1szXSk7CisKKwlyZXR1cm4gY3JGaWxsOworfQorCit2b2lkIENQREZTREtfV2lkZ2V0OjpBZGRJbWFnZVRvQXBwZWFyYW5jZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FQVHlwZSwgQ1BERl9TdHJlYW0qIHBJbWFnZSkKK3sKKwlBU1NFUlQocEltYWdlICE9IE5VTEwpOworCisJQVNTRVJUKG1fcEFubm90ICE9IE5VTEwpOworCUFTU0VSVChtX3BBbm5vdC0+bV9wQW5ub3REaWN0ICE9IE5VTEwpOworCisJQ1BERl9Eb2N1bWVudCogcERvYyA9IG1fcFBhZ2VWaWV3LT5HZXRQREZEb2N1bWVudCgpOy8vcERvY3VtZW50LT5HZXREb2N1bWVudCgpOworCUFTU0VSVChwRG9jICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwQVBEaWN0ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQVAiKTsKKwlBU1NFUlQocEFQRGljdCAhPSBOVUxMKTsKKworCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gcEFQRGljdC0+R2V0U3RyZWFtKHNBUFR5cGUpOworCUFTU0VSVChwU3RyZWFtICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwU3RyZWFtRGljdCA9IHBTdHJlYW0tPkdldERpY3QoKTsKKwlBU1NFUlQocFN0cmVhbURpY3QgIT0gTlVMTCk7CisKKwlDRlhfQnl0ZVN0cmluZyBzSW1hZ2VBbGlhcyA9ICJJTUciOworCisJaWYgKENQREZfRGljdGlvbmFyeSogcEltYWdlRGljdCA9IHBJbWFnZS0+R2V0RGljdCgpKQorCXsKKwkJc0ltYWdlQWxpYXMgPSBwSW1hZ2VEaWN0LT5HZXRTdHJpbmcoIk5hbWUiKTsKKwkJaWYgKHNJbWFnZUFsaWFzLklzRW1wdHkoKSkKKwkJCXNJbWFnZUFsaWFzID0gIklNRyI7CisJfQkKKworCUNQREZfRGljdGlvbmFyeSogcFN0cmVhbVJlc0xpc3QgPSBwU3RyZWFtRGljdC0+R2V0RGljdCgiUmVzb3VyY2VzIik7CisJaWYgKCFwU3RyZWFtUmVzTGlzdCkKKwl7CisJCXBTdHJlYW1SZXNMaXN0ID0gRlhfTkVXIENQREZfRGljdGlvbmFyeSgpOworCQlwU3RyZWFtRGljdC0+U2V0QXQoIlJlc291cmNlcyIsIHBTdHJlYW1SZXNMaXN0KTsKKwl9CisKKwlpZiAocFN0cmVhbVJlc0xpc3QpIAorCXsKKwkJQ1BERl9EaWN0aW9uYXJ5KiBwWE9iamVjdCA9IEZYX05FVyBDUERGX0RpY3Rpb25hcnk7CQkJCisJCXBYT2JqZWN0LT5TZXRBdFJlZmVyZW5jZShzSW1hZ2VBbGlhcywgcERvYywgcEltYWdlKTsKKwkJcFN0cmVhbVJlc0xpc3QtPlNldEF0KCJYT2JqZWN0IiwgcFhPYmplY3QpOworCX0KK30KKwordm9pZCBDUERGU0RLX1dpZGdldDo6UmVtb3ZlQXBwZWFyYW5jZShjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0FQVHlwZSkKK3sKKwlBU1NFUlQobV9wQW5ub3QgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEFubm90LT5tX3BBbm5vdERpY3QgIT0gTlVMTCk7CisKKwlpZiAoQ1BERl9EaWN0aW9uYXJ5KiBwQVBEaWN0ID0gbV9wQW5ub3QtPm1fcEFubm90RGljdC0+R2V0RGljdCgiQVAiKSkKKwl7CisJCXBBUERpY3QtPlJlbW92ZUF0KHNBUFR5cGUpOworCX0KK30KKworRlhfQk9PTCBDUERGU0RLX1dpZGdldDo6T25BQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgdHlwZSwgUERGU0RLX0ZpZWxkQWN0aW9uJiBkYXRhLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJQ1BERl9BY3Rpb24gYWN0aW9uID0gR2V0QUFjdGlvbih0eXBlKTsKKworCWlmIChhY3Rpb24gJiYgYWN0aW9uLkdldFR5cGUoKSAhPSBDUERGX0FjdGlvbjo6VW5rbm93bikKKwl7CisgCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBwUGFnZVZpZXctPkdldFNES0RvY3VtZW50KCk7CisgCQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworIAorIAkJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IHBEb2N1bWVudC0+R2V0RW52KCk7CisgCQlBU1NFUlQocEVudiAhPSBOVUxMKTsKKworCQlDUERGU0RLX0FjdGlvbkhhbmRsZXIqIHBBY3Rpb25IYW5kbGVyID0gcEVudi0+R2V0QWN0aW9uSGFuZGVyKCk7LyooQ1BERlNES19BY3Rpb25IYW5kbGVyKilwQXBwLT5HZXRBY3Rpb25IYW5kbGVyKCk7Ki8KKyAJCUFTU0VSVChwQWN0aW9uSGFuZGxlciAhPSBOVUxMKTsKKyAKKyAJCXJldHVybiBwQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fRmllbGQoYWN0aW9uLCB0eXBlLCBwRG9jdW1lbnQsIEdldEZvcm1GaWVsZCgpLCBkYXRhKTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0NQREZfQWN0aW9uCUNQREZTREtfV2lkZ2V0OjpHZXRBQWN0aW9uKENQREZfQUFjdGlvbjo6QUFjdGlvblR5cGUgZUFBVCkKK3sKKwlzd2l0Y2ggKGVBQVQpCisJeworCWNhc2UgQ1BERl9BQWN0aW9uOjpDdXJzb3JFbnRlcjoKKwljYXNlIENQREZfQUFjdGlvbjo6Q3Vyc29yRXhpdDoKKwljYXNlIENQREZfQUFjdGlvbjo6QnV0dG9uRG93bjoKKwljYXNlIENQREZfQUFjdGlvbjo6QnV0dG9uVXA6CisJY2FzZSBDUERGX0FBY3Rpb246OkdldEZvY3VzOgorCWNhc2UgQ1BERl9BQWN0aW9uOjpMb3NlRm9jdXM6CisJY2FzZSBDUERGX0FBY3Rpb246OlBhZ2VPcGVuOgorCWNhc2UgQ1BERl9BQWN0aW9uOjpQYWdlQ2xvc2U6CisJY2FzZSBDUERGX0FBY3Rpb246OlBhZ2VWaXNpYmxlOgorCWNhc2UgQ1BERl9BQWN0aW9uOjpQYWdlSW52aXNpYmxlOgorCQlyZXR1cm4gQ1BERlNES19Bbm5vdDo6R2V0QUFjdGlvbihlQUFUKTsKKwljYXNlIENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlOgorCWNhc2UgQ1BERl9BQWN0aW9uOjpGb3JtYXQ6CisJY2FzZSBDUERGX0FBY3Rpb246OlZhbGlkYXRlOgorCWNhc2UgQ1BERl9BQWN0aW9uOjpDYWxjdWxhdGU6CisJCXsKKwkJCUNQREZfRm9ybUZpZWxkKiBwRmllbGQgPSB0aGlzLT5HZXRGb3JtRmllbGQoKTsKKwkJCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwkJCWlmIChDUERGX0FBY3Rpb24gYWEgPSBwRmllbGQtPkdldEFkZGl0aW9uYWxBY3Rpb24oKSkKKwkJCQlyZXR1cm4gYWEuR2V0QWN0aW9uKGVBQVQpOworCQkJZWxzZSAKKwkJCQlyZXR1cm4gQ1BERlNES19Bbm5vdDo6R2V0QUFjdGlvbihlQUFUKTsKKwkJfQorCWRlZmF1bHQ6CisJCXJldHVybiBOVUxMOworCX0KKworCXJldHVybiBOVUxMOworfQorCisKK0NGWF9XaWRlU3RyaW5nIENQREZTREtfV2lkZ2V0OjpHZXRBbHRlcm5hdGVOYW1lKCkgY29uc3QKK3sKKwlDUERGX0Zvcm1GaWVsZCoJcEZvcm1GaWVsZCA9IEdldEZvcm1GaWVsZCgpOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJcmV0dXJuIHBGb3JtRmllbGQtPkdldEFsdGVybmF0ZU5hbWUoKTsKK30KKworRlhfSU5UMzIJQ1BERlNES19XaWRnZXQ6OkdldEFwcGVhcmFuY2VBZ2UoKSBjb25zdAoreworCXJldHVybiBtX25BcHBBZ2U7Cit9CisKK0ZYX0lOVDMyIENQREZTREtfV2lkZ2V0OjpHZXRWYWx1ZUFnZSgpIGNvbnN0Cit7CisJcmV0dXJuIG1fblZhbHVlQWdlOworfQorCisKK0ZYX0JPT0wJQ1BERlNES19XaWRnZXQ6OkhpdFRlc3QoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKQoreworCUNQREZfQW5ub3QqIHBBbm5vdCA9IEdldFBERkFubm90KCk7CisJQ0ZYX0Zsb2F0UmVjdCBhbm5vdFJlY3Q7CisJcEFubm90LT5HZXRSZWN0KGFubm90UmVjdCk7CisJaWYoYW5ub3RSZWN0LkNvbnRhaW5zKHBhZ2VYLCBwYWdlWSkpCisJeworCQlpZiAoIUlzVmlzaWJsZSgpKSByZXR1cm4gRkFMU0U7CisJCQorCQlpbnQgbkZpZWxkRmxhZ3MgPSBHZXRGaWVsZEZsYWdzKCk7CisJCWlmICgobkZpZWxkRmxhZ3MgJiBGSUVMREZMQUdfUkVBRE9OTFkpID09IEZJRUxERkxBR19SRUFET05MWSkgCisJCQlyZXR1cm4gRkFMU0U7CisJCQorCQlyZXR1cm4gVFJVRTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitDUERGU0RLX0ludGVyRm9ybTo6Q1BERlNES19JbnRlckZvcm0oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50KQorCTptX3BEb2N1bWVudChwRG9jdW1lbnQpLAorCW1fcEludGVyRm9ybShOVUxMKSwKKwltX2JDYWxjdWxhdGUoVFJVRSksCisJbV9iQnVzeShGQUxTRSkKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisJbV9wSW50ZXJGb3JtID0gbmV3IENQREZfSW50ZXJGb3JtKG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLCBGQUxTRSk7CisJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsKKwltX3BJbnRlckZvcm0tPlNldEZvcm1Ob3RpZnkodGhpcyk7CisKKwlmb3IoaW50IGk9MDsgaTw2OyBpKyspCisJCW1fYk5lZWRIaWdodGxpZ2h0W2ldID0gRkFMU0U7CisJbV9pSGlnaGxpZ2h0QWxwaGEgPSAwOworfQorCitDUERGU0RLX0ludGVyRm9ybTo6fkNQREZTREtfSW50ZXJGb3JtKCkKK3sKKwlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOworCWRlbGV0ZSBtX3BJbnRlckZvcm07CisJbV9wSW50ZXJGb3JtID0gTlVMTDsKKworCW1fTWFwLlJlbW92ZUFsbCgpOworfQorCit2b2lkIENQREZTREtfSW50ZXJGb3JtOjpEZXN0cm95KCkKK3sKKwlkZWxldGUgdGhpczsKK30KKworQ1BERl9JbnRlckZvcm0qIENQREZTREtfSW50ZXJGb3JtOjpHZXRJbnRlckZvcm0oKQoreworCXJldHVybiBtX3BJbnRlckZvcm07Cit9CisKK0NQREZTREtfRG9jdW1lbnQqIENQREZTREtfSW50ZXJGb3JtOjpHZXREb2N1bWVudCgpCit7CisJcmV0dXJuIG1fcERvY3VtZW50OworfQorCitGWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpIaWdobGlnaHRXaWRnZXRzKCkKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0NQREZTREtfV2lkZ2V0KiBDUERGU0RLX0ludGVyRm9ybTo6R2V0U2libGluZyhDUERGU0RLX1dpZGdldCogcFdpZGdldCwgRlhfQk9PTCBiTmV4dCkgY29uc3QKK3sKKwlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsKKworCUNCQV9Bbm5vdEl0ZXJhdG9yKiBwSXRlcmF0b3IgPSBuZXcgQ0JBX0Fubm90SXRlcmF0b3IocFdpZGdldC0+R2V0UGFnZVZpZXcoKSwgIldpZGdldCIsICIiKTsKKwlBU1NFUlQocEl0ZXJhdG9yICE9IE5VTEwpOworCisJQ1BERlNES19XaWRnZXQqIHBSZXQgPSBOVUxMOworCisJaWYgKGJOZXh0KQorCQlwUmV0ID0gKENQREZTREtfV2lkZ2V0KilwSXRlcmF0b3ItPkdldE5leHRBbm5vdChwV2lkZ2V0KTsKKwllbHNlCisJCXBSZXQgPSAoQ1BERlNES19XaWRnZXQqKXBJdGVyYXRvci0+R2V0UHJldkFubm90KHBXaWRnZXQpOworCisJcEl0ZXJhdG9yLT5SZWxlYXNlKCk7CisJCisJcmV0dXJuIHBSZXQ7CisKK30KKworQ1BERlNES19XaWRnZXQqCUNQREZTREtfSW50ZXJGb3JtOjpHZXRXaWRnZXQoQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wpIGNvbnN0Cit7CisJaWYoIXBDb250cm9sIHx8ICFtX3BJbnRlckZvcm0pIHJldHVybiBOVUxMOworCQorCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gTlVMTDsKKwltX01hcC5Mb29rdXAocENvbnRyb2wsIHBXaWRnZXQpOworCisJaWYgKHBXaWRnZXQpIHJldHVybiBwV2lkZ2V0OworCisJQ1BERl9EaWN0aW9uYXJ5KiBwQ29udHJvbERpY3QgPSBwQ29udHJvbC0+R2V0V2lkZ2V0KCk7CisJQVNTRVJUKHBDb250cm9sRGljdCAhPSBOVUxMKTsKKworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKwlDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKTsKKworCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlID0gTlVMTDsKKworCWlmIChDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBDb250cm9sRGljdC0+R2V0RGljdCgiUCIpKQorCXsKKwkJaW50IG5QYWdlSW5kZXggPSBwRG9jdW1lbnQtPkdldFBhZ2VJbmRleChwUGFnZURpY3QtPkdldE9iak51bSgpKTsKKwkJaWYgKG5QYWdlSW5kZXggPj0gMCkKKwkJeworCQkJcFBhZ2UgPSBtX3BEb2N1bWVudC0+R2V0UGFnZVZpZXcoblBhZ2VJbmRleCk7CisJCX0KKwl9CisKKwlpZiAoIXBQYWdlKSAKKwl7CisJCWludCBuUGFnZUluZGV4ID0gR2V0UGFnZUluZGV4QnlBbm5vdERpY3QocERvY3VtZW50LCBwQ29udHJvbERpY3QpOworCQlpZiAoblBhZ2VJbmRleCA+PSAwKQorCQl7CisJCQlwUGFnZSA9IG1fcERvY3VtZW50LT5HZXRQYWdlVmlldyhuUGFnZUluZGV4KTsKKwkJfQorCX0KKworCWlmIChwUGFnZSkKKwkJcmV0dXJuIChDUERGU0RLX1dpZGdldCopcFBhZ2UtPkdldEFubm90QnlEaWN0KHBDb250cm9sRGljdCk7CisKKwlyZXR1cm4gTlVMTDsKK30KKwordm9pZCBDUERGU0RLX0ludGVyRm9ybTo6R2V0V2lkZ2V0cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpZWxkTmFtZSwgQ0ZYX1B0ckFycmF5JiB3aWRnZXRzKQoreworCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlmb3IgKGludCBpPTAsc3o9bV9wSW50ZXJGb3JtLT5Db3VudEZpZWxkcyhzRmllbGROYW1lKTsgaTxzejsgaSsrKQorCXsKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBtX3BJbnRlckZvcm0tPkdldEZpZWxkKGksIHNGaWVsZE5hbWUpOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlHZXRXaWRnZXRzKHBGb3JtRmllbGQsIHdpZGdldHMpOwkKKwl9Cit9CisKK3ZvaWQgQ1BERlNES19JbnRlckZvcm06OkdldFdpZGdldHMoQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCwgQ0ZYX1B0ckFycmF5JiB3aWRnZXRzKQoreworCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwlmb3IgKGludCBpPTAsaXN6PXBGaWVsZC0+Q291bnRDb250cm9scygpOyBpPGlzejsgaSsrKQorCXsKKwkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gcEZpZWxkLT5HZXRDb250cm9sKGkpOworCQlBU1NFUlQocEZvcm1DdHJsICE9IE5VTEwpOworCisJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gR2V0V2lkZ2V0KHBGb3JtQ3RybCk7CisKKwkJaWYgKHBXaWRnZXQpCisJCQl3aWRnZXRzLkFkZChwV2lkZ2V0KTsKKwl9Cit9CisKK2ludCBDUERGU0RLX0ludGVyRm9ybTo6R2V0UGFnZUluZGV4QnlBbm5vdERpY3QoQ1BERl9Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0RpY3Rpb25hcnkqIHBBbm5vdERpY3QpIGNvbnN0Cit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKwlBU1NFUlQocEFubm90RGljdCAhPSBOVUxMKTsKKworCWZvciAoaW50IGk9MCxzej1wRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpOyBpPHN6OyBpKyspCisJeworCQlpZiAoQ1BERl9EaWN0aW9uYXJ5KiBwUGFnZURpY3QgPSBwRG9jdW1lbnQtPkdldFBhZ2UoaSkpCisJCXsJCQkKKwkJCWlmIChDUERGX0FycmF5KiBwQW5ub3RzID0gcFBhZ2VEaWN0LT5HZXRBcnJheSgiQW5ub3RzIikpCisJCQl7CisJCQkJZm9yIChpbnQgaj0wLGpzej1wQW5ub3RzLT5HZXRDb3VudCgpOyBqPGpzejsgaisrKQorCQkJCXsKKwkJCQkJQ1BERl9PYmplY3QqIHBEaWN0ID0gcEFubm90cy0+R2V0RWxlbWVudFZhbHVlKGopOworCQkJCQlpZiAocEFubm90RGljdCA9PSBwRGljdCkKKwkJCQkJeworCQkJCQkJcmV0dXJuIGk7CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCX0KKwl9CisKKwlyZXR1cm4gLTE7Cit9CisKK3ZvaWQgQ1BERlNES19JbnRlckZvcm06OkFkZE1hcChDUERGX0Zvcm1Db250cm9sKiBwQ29udHJvbCwgQ1BERlNES19XaWRnZXQqIHBXaWRnZXQpCit7CisJbV9NYXAuU2V0QXQocENvbnRyb2wsIHBXaWRnZXQpOworfQorCit2b2lkIENQREZTREtfSW50ZXJGb3JtOjpSZW1vdmVNYXAoQ1BERl9Gb3JtQ29udHJvbCogcENvbnRyb2wpCit7CisJbV9NYXAuUmVtb3ZlS2V5KHBDb250cm9sKTsKK30KKwordm9pZCBDUERGU0RLX0ludGVyRm9ybTo6RW5hYmxlQ2FsY3VsYXRlKEZYX0JPT0wgYkVuYWJsZWQpCit7CisJbV9iQ2FsY3VsYXRlID0gYkVuYWJsZWQ7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OklzQ2FsY3VsYXRlRW5hYmxlZCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fYkNhbGN1bGF0ZTsKK30KKworI2lmZGVmIF9XSU4zMgorQ1BERl9TdHJlYW0qIENQREZTREtfSW50ZXJGb3JtOjpMb2FkSW1hZ2VGcm9tRmlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpbGUpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpOworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDUERGX1N0cmVhbSogcFJldFN0cmVhbSA9IE5VTEw7CisKKwlpZiAoQ0ZYX0RJQml0bWFwKiBwQm1wID0gQ0ZYX1dpbmRvd3NESUI6OkxvYWRGcm9tRmlsZShzRmlsZSkpCisJeworCQlpbnQgbldpZHRoID0gcEJtcC0+R2V0V2lkdGgoKTsKKwkJaW50IG5IZWlnaHQgPSBwQm1wLT5HZXRIZWlnaHQoKTsKKworCQlDUERGX0ltYWdlIEltYWdlKHBEb2N1bWVudCk7CisJCUltYWdlLlNldEltYWdlKHBCbXAsIEZBTFNFKTsKKwkJQ1BERl9TdHJlYW0qIHBJbWFnZVN0cmVhbSA9IEltYWdlLkdldFN0cmVhbSgpOworCQlpZiAocEltYWdlU3RyZWFtKQorCQl7CisJCQlpZiAocEltYWdlU3RyZWFtLT5HZXRPYmpOdW0oKSA9PSAwKQorCQkJCXBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocEltYWdlU3RyZWFtKTsKKworCQkJQ1BERl9EaWN0aW9uYXJ5KiBwU3RyZWFtRGljdCA9IG5ldyBDUERGX0RpY3Rpb25hcnkoKTsKKwkJCXBTdHJlYW1EaWN0LT5TZXRBdE5hbWUoIlN1YnR5cGUiLCAiRm9ybSIpOworCQkJcFN0cmVhbURpY3QtPlNldEF0TmFtZSgiTmFtZSIsICJJTUciKTsKKwkJCUNQREZfQXJyYXkqIHBNYXRyaXggPSBuZXcgQ1BERl9BcnJheSgpOworCQkJcFN0cmVhbURpY3QtPlNldEF0KCJNYXRyaXgiLCBwTWF0cml4KTsKKwkJCXBNYXRyaXgtPkFkZEludGVnZXIoMSk7CisJCQlwTWF0cml4LT5BZGRJbnRlZ2VyKDApOworCQkJcE1hdHJpeC0+QWRkSW50ZWdlcigwKTsKKwkJCXBNYXRyaXgtPkFkZEludGVnZXIoMSk7CisJCQlwTWF0cml4LT5BZGRJbnRlZ2VyKC1uV2lkdGggLyAyKTsKKwkJCXBNYXRyaXgtPkFkZEludGVnZXIoLW5IZWlnaHQgLyAyKTsKKwkJCUNQREZfRGljdGlvbmFyeSogcFJlc291cmNlID0gbmV3IENQREZfRGljdGlvbmFyeSgpOworCQkJcFN0cmVhbURpY3QtPlNldEF0KCJSZXNvdXJjZXMiLCBwUmVzb3VyY2UpOworCQkJQ1BERl9EaWN0aW9uYXJ5KiBwWE9iamVjdCA9IG5ldyBDUERGX0RpY3Rpb25hcnkoKTsKKwkJCXBSZXNvdXJjZS0+U2V0QXQoIlhPYmplY3QiLCBwWE9iamVjdCk7CisJCQlwWE9iamVjdC0+U2V0QXRSZWZlcmVuY2UoIkltZyIsIHBEb2N1bWVudCwgcEltYWdlU3RyZWFtKTsKKwkJCUNQREZfQXJyYXkqIHBQcm9jU2V0ID0gbmV3IENQREZfQXJyYXkoKTsKKwkJCXBSZXNvdXJjZS0+U2V0QXQoIlByb2NTZXQiLCBwUHJvY1NldCk7CisJCQlwUHJvY1NldC0+QWRkTmFtZSgiUERGIik7CisJCQlwUHJvY1NldC0+QWRkTmFtZSgiSW1hZ2VDIik7CisJCQlwU3RyZWFtRGljdC0+U2V0QXROYW1lKCJUeXBlIiwgIlhPYmplY3QiKTsKKwkJCUNQREZfQXJyYXkqIHBCQm94ID0gbmV3IENQREZfQXJyYXkoKTsKKwkJCXBTdHJlYW1EaWN0LT5TZXRBdCgiQkJveCIsIHBCQm94KTsKKwkJCXBCQm94LT5BZGRJbnRlZ2VyKDApOworCQkJcEJCb3gtPkFkZEludGVnZXIoMCk7CisJCQlwQkJveC0+QWRkSW50ZWdlcihuV2lkdGgpOworCQkJcEJCb3gtPkFkZEludGVnZXIobkhlaWdodCk7CisJCQlwU3RyZWFtRGljdC0+U2V0QXRJbnRlZ2VyKCJGb3JtVHlwZSIsIDEpOworCisJCQlwUmV0U3RyZWFtID0gbmV3IENQREZfU3RyZWFtKE5VTEwsIDAsIE5VTEwpOworCQkJQ0ZYX0J5dGVTdHJpbmcgY3NTdHJlYW07CisJCQljc1N0cmVhbS5Gb3JtYXQoInFcbiVkIDAgMCAlZCAwIDAgY21cbi9JbWcgRG9cblEiLCBuV2lkdGgsIG5IZWlnaHQpOworCQkJcFJldFN0cmVhbS0+SW5pdFN0cmVhbSgoRlhfQllURSopKEZYX0xQQ1NUUiljc1N0cmVhbSwgY3NTdHJlYW0uR2V0TGVuZ3RoKCksIHBTdHJlYW1EaWN0KTsKKwkJCXBEb2N1bWVudC0+QWRkSW5kaXJlY3RPYmplY3QocFJldFN0cmVhbSk7CisJCX0KKworCQlkZWxldGUgcEJtcDsKKwl9CisKKwlyZXR1cm4gcFJldFN0cmVhbTsKK30KKyNlbmRpZgorCit2b2lkIENQREZTREtfSW50ZXJGb3JtOjpPbkNhbGN1bGF0ZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCkKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcERvY3VtZW50LT5HZXRFbnYoKTsKKwlBU1NFUlQocEVudik7CisJaWYoIXBFbnYtPklzSlNJbml0aWF0ZWQoKSkKKwkJcmV0dXJuOworCisJaWYgKG1fYkJ1c3kpIHJldHVybjsKKworCW1fYkJ1c3kgPSBUUlVFOworCisJaWYgKHRoaXMtPklzQ2FsY3VsYXRlRW5hYmxlZCgpKQorCXsKKwkJSUZYSlNfUnVudGltZSogcFJ1bnRpbWUgPSBtX3BEb2N1bWVudC0+R2V0SnNSdW50aW1lKCk7CisJCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCQlwUnVudGltZS0+U2V0UmVhZGVyRG9jdW1lbnQobV9wRG9jdW1lbnQpOworCisJCWludCBuU2l6ZSA9IG1fcEludGVyRm9ybS0+Q291bnRGaWVsZHNJbkNhbGN1bGF0aW9uT3JkZXIoKTsKKwkJZm9yIChpbnQgaT0wOyBpPG5TaXplOyBpKyspCisJCXsKKwkJCWlmKENQREZfRm9ybUZpZWxkKiBwRmllbGQgPSBtX3BJbnRlckZvcm0tPkdldEZpZWxkSW5DYWxjdWxhdGlvbk9yZGVyKGkpKQorCQkJeworLy8JCQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOworCQkJCWludCBuVHlwZSA9IHBGaWVsZC0+R2V0RmllbGRUeXBlKCk7CisJCQkJaWYgKG5UeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCB8fCBuVHlwZSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEKQorCQkJCXsKKwkJCQkJQ1BERl9BQWN0aW9uIGFBY3Rpb24gPSBwRmllbGQtPkdldEFkZGl0aW9uYWxBY3Rpb24oKTsKKwkJCQkJaWYgKGFBY3Rpb24gJiYgYUFjdGlvbi5BY3Rpb25FeGlzdChDUERGX0FBY3Rpb246OkNhbGN1bGF0ZSkpCisJCQkJCXsKKwkJCQkJCUNQREZfQWN0aW9uIGFjdGlvbiA9IGFBY3Rpb24uR2V0QWN0aW9uKENQREZfQUFjdGlvbjo6Q2FsY3VsYXRlKTsKKwkJCQkJCWlmIChhY3Rpb24pCisJCQkJCQl7CisJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgY3NKUyA9IGFjdGlvbi5HZXRKYXZhU2NyaXB0KCk7CisJCQkJCQkJaWYgKCFjc0pTLklzRW1wdHkoKSkKKwkJCQkJCQl7CisJCQkJCQkJCUlGWEpTX0NvbnRleHQqIHBDb250ZXh0ID0gcFJ1bnRpbWUtPk5ld0NvbnRleHQoKTsKKwkJCQkJCQkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCQkJCQkJCQkKKwkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc09sZFZhbHVlID0gcEZpZWxkLT5HZXRWYWx1ZSgpOworCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBzT2xkVmFsdWU7CisJCQkJCQkJCUZYX0JPT0wgYlJDID0gVFJVRTsKKwkJCQkJCQkJcENvbnRleHQtPk9uRmllbGRfQ2FsY3VsYXRlKHBGb3JtRmllbGQsIHBGaWVsZCwgc1ZhbHVlLCBiUkMpOworCQkJCQkJCQkKKwkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc0luZm87CisJCQkJCQkJCUZYX0JPT0wgYlJldCA9IHBDb250ZXh0LT5SdW5TY3JpcHQoY3NKUywgc0luZm8pOworCQkJCQkJCQlwUnVudGltZS0+UmVsZWFzZUNvbnRleHQocENvbnRleHQpOworCQkJCQkJCQkKKwkJCQkJCQkJaWYgKGJSZXQpCisJCQkJCQkJCXsKKwkJCQkJCQkJCWlmIChiUkMpCisJCQkJCQkJCQl7CisJCQkJCQkJCQkJaWYgKHNWYWx1ZS5Db21wYXJlKHNPbGRWYWx1ZSkgIT0gMCkKKwkJCQkJCQkJCQkJcEZpZWxkLT5TZXRWYWx1ZShzVmFsdWUsIFRSVUUpOworCQkJCQkJCQkJfQorCQkJCQkJCQl9CisJCQkJCQkJfQorCQkJCQkJfQorCQkJCQl9CisJCQkJfQorCQkJfQorCQl9CisKKwkJCisJfQorCisJbV9iQnVzeSA9IEZBTFNFOworfQorCitDRlhfV2lkZVN0cmluZyBDUERGU0RLX0ludGVyRm9ybTo6T25Gb3JtYXQoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIGludCBuQ29tbWl0S2V5LCBGWF9CT09MJiBiRm9ybWF0ZWQpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJQ0ZYX1dpZGVTdHJpbmcgc1ZhbHVlID0gcEZvcm1GaWVsZC0+R2V0VmFsdWUoKTsKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOworCUFTU0VSVChwRW52KTsKKwlpZighcEVudi0+SXNKU0luaXRpYXRlZCgpKQorCXsKKwkJYkZvcm1hdGVkID0gRkFMU0U7CisJCXJldHVybiBzVmFsdWU7CisJfSAKKworCUlGWEpTX1J1bnRpbWUqIHBSdW50aW1lID0gbV9wRG9jdW1lbnQtPkdldEpzUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKwkKKwlwUnVudGltZS0+U2V0UmVhZGVyRG9jdW1lbnQobV9wRG9jdW1lbnQpOworCisJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9DT01CT0JPWCkKKwl7CisJCWlmIChwRm9ybUZpZWxkLT5Db3VudFNlbGVjdGVkSXRlbXMoKSA+IDApCisJCXsKKwkJCWludCBpbmRleCA9IHBGb3JtRmllbGQtPkdldFNlbGVjdGVkSW5kZXgoMCk7CisJCQlpZiAoaW5kZXggPj0gMCkKKwkJCQlzVmFsdWUgPSBwRm9ybUZpZWxkLT5HZXRPcHRpb25MYWJlbChpbmRleCk7CisJCX0KKwl9CisKKwliRm9ybWF0ZWQgPSBGQUxTRTsKKworCUNQREZfQUFjdGlvbiBhQWN0aW9uID0gcEZvcm1GaWVsZC0+R2V0QWRkaXRpb25hbEFjdGlvbigpOworCWlmIChhQWN0aW9uICE9IE5VTEwgJiYgYUFjdGlvbi5BY3Rpb25FeGlzdChDUERGX0FBY3Rpb246OkZvcm1hdCkpIAorCXsKKwkJQ1BERl9BY3Rpb24gYWN0aW9uID0gYUFjdGlvbi5HZXRBY3Rpb24oQ1BERl9BQWN0aW9uOjpGb3JtYXQpOworCQlpZiAoYWN0aW9uKQorCQl7CQkJCisJCQlDRlhfV2lkZVN0cmluZyBzY3JpcHQgPSBhY3Rpb24uR2V0SmF2YVNjcmlwdCgpOworCQkJaWYgKCFzY3JpcHQuSXNFbXB0eSgpKQorCQkJeworCQkJCUNGWF9XaWRlU3RyaW5nIFZhbHVlID0gc1ZhbHVlOworCisJCQkJSUZYSlNfQ29udGV4dCogcENvbnRleHQgPSBwUnVudGltZS0+TmV3Q29udGV4dCgpOworCQkJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKworCQkJCXBDb250ZXh0LT5PbkZpZWxkX0Zvcm1hdChuQ29tbWl0S2V5LCBwRm9ybUZpZWxkLCBWYWx1ZSwgVFJVRSk7CisJCQkKKwkJCQlDRlhfV2lkZVN0cmluZyBzSW5mbzsKKyAJCQkJRlhfQk9PTCBiUmV0ID0gcENvbnRleHQtPlJ1blNjcmlwdChzY3JpcHQsIHNJbmZvKTsKKwkJCQlwUnVudGltZS0+UmVsZWFzZUNvbnRleHQocENvbnRleHQpOworCisJCQkJaWYgKGJSZXQpCisJCQkJeworCQkJCQlzVmFsdWUgPSBWYWx1ZTsKKwkJCQkJYkZvcm1hdGVkID0gVFJVRTsKKwkJCQl9CisJCQl9CisJCX0KKwl9CisKKwlyZXR1cm4gc1ZhbHVlOworfQorCit2b2lkIENQREZTREtfSW50ZXJGb3JtOjpSZXNldEZpZWxkQXBwZWFyYW5jZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgRlhfTFBDV1NUUiBzVmFsdWUsIEZYX0JPT0wgYlZhbHVlQ2hhbmdlZCkKK3sKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCWZvciAoaW50IGk9MCxzej1wRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGk8c3o7IGkrKykKKwl7CisJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2woaSk7CisJCUFTU0VSVChwRm9ybUN0cmwgIT0gTlVMTCk7CisKKwkJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsKKwkJaWYoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBHZXRXaWRnZXQocEZvcm1DdHJsKSkKKwkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShzVmFsdWUsIGJWYWx1ZUNoYW5nZWQpOworCX0KK30KKwordm9pZCBDUERGU0RLX0ludGVyRm9ybTo6VXBkYXRlRmllbGQoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQpCit7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwlmb3IgKGludCBpPTAsc3o9cEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBpPHN6OyBpKyspCisJeworCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUN0cmwgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKGkpOworCQlBU1NFUlQocEZvcm1DdHJsICE9IE5VTEwpOworCisJCWlmKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gR2V0V2lkZ2V0KHBGb3JtQ3RybCkpCisJCXsKKwkJCUNQREZEb2NfRW52aXJvbm1lbnQgKiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOworCQkJQ0ZGTF9JRm9ybUZpbGxlciogcElGb3JtRmlsbGVyID0gcEVudi0+R2V0SUZvcm1GaWxsZXIoKTsKKwkJCQorCQkJQ1BERl9QYWdlICogcFBhZ2UgPSBwV2lkZ2V0LT5HZXRQREZQYWdlKCk7CisJCQlDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3ID0gbV9wRG9jdW1lbnQtPkdldFBhZ2VWaWV3KHBQYWdlLEZBTFNFKTsKKworCQkJRlhfUkVDVCByY0JCb3ggPSBwSUZvcm1GaWxsZXItPkdldFZpZXdCQm94KHBQYWdlVmlldywgcFdpZGdldCk7CisKKwkJCXBFbnYtPkZGSV9JbnZhbGlkYXRlKHBQYWdlLHJjQkJveC5sZWZ0LCByY0JCb3gudG9wLCByY0JCb3gucmlnaHQsIHJjQkJveC5ib3R0b20pOworCQl9CisJfQorfQorCit2b2lkIENQREZTREtfSW50ZXJGb3JtOjpPbktleVN0cm9rZUNvbW1pdChDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIGNzVmFsdWUsIEZYX0JPT0wmIGJSQykKK3sKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworIAlDUERGX0FBY3Rpb24gYUFjdGlvbiA9IHBGb3JtRmllbGQtPkdldEFkZGl0aW9uYWxBY3Rpb24oKTsKKyAJaWYgKGFBY3Rpb24gIT0gTlVMTCAmJiBhQWN0aW9uLkFjdGlvbkV4aXN0KENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlKSkgCisgCXsKKyAJCUNQREZfQWN0aW9uIGFjdGlvbiA9IGFBY3Rpb24uR2V0QWN0aW9uKENQREZfQUFjdGlvbjo6S2V5U3Ryb2tlKTsKKyAJCWlmIChhY3Rpb24pCisgCQl7CQkJIAorIAkJCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKyAJCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOworIAkJCUFTU0VSVChwRW52ICE9IE5VTEwpOworCisJCQlDUERGU0RLX0FjdGlvbkhhbmRsZXIqIHBBY3Rpb25IYW5kbGVyID0gcEVudi0+R2V0QWN0aW9uSGFuZGVyKCk7CisJCQlBU1NFUlQocEFjdGlvbkhhbmRsZXIgIT0gTlVMTCk7CisJCisJCQlQREZTREtfRmllbGRBY3Rpb24gZmE7CisJCQlmYS5iTW9kaWZpZXIgPSBwRW52LT5GRklfSXNDVFJMS2V5RG93bigwKTsKKyAJCQlmYS5iU2hpZnQgPSBwRW52LT5GRklfSXNTSElGVEtleURvd24oMCk7CisJCQlmYS5zVmFsdWUgPSBjc1ZhbHVlOworCisgICAJCQlwQWN0aW9uSGFuZGxlci0+RG9BY3Rpb25fRmllbGRKYXZhU2NyaXB0KGFjdGlvbiwgQ1BERl9BQWN0aW9uOjpLZXlTdHJva2UsIAorICAgCQkJCW1fcERvY3VtZW50LCBwRm9ybUZpZWxkLCBmYSk7CisgICAJCQliUkMgPSBmYS5iUkM7CisgCQl9CisgCX0KK30KKwordm9pZCBDUERGU0RLX0ludGVyRm9ybTo6T25WYWxpZGF0ZShDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCwgQ0ZYX1dpZGVTdHJpbmcmIGNzVmFsdWUsIEZYX0JPT0wmIGJSQykKK3sKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworIAlDUERGX0FBY3Rpb24gYUFjdGlvbiA9IHBGb3JtRmllbGQtPkdldEFkZGl0aW9uYWxBY3Rpb24oKTsKKyAJaWYgKGFBY3Rpb24gIT0gTlVMTCAmJiBhQWN0aW9uLkFjdGlvbkV4aXN0KENQREZfQUFjdGlvbjo6VmFsaWRhdGUpKSAKKyAJeworIAkJQ1BERl9BY3Rpb24gYWN0aW9uID0gYUFjdGlvbi5HZXRBY3Rpb24oQ1BERl9BQWN0aW9uOjpWYWxpZGF0ZSk7CisJCWlmIChhY3Rpb24pCisgCQl7CQkKKwkJCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKwkJCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7CisJCQlBU1NFUlQocEVudiAhPSBOVUxMKTsKKwkJCQorCQkJQ1BERlNES19BY3Rpb25IYW5kbGVyKiBwQWN0aW9uSGFuZGxlciA9IHBFbnYtPkdldEFjdGlvbkhhbmRlcigpOworCQkJQVNTRVJUKHBBY3Rpb25IYW5kbGVyICE9IE5VTEwpOworCisJCQlQREZTREtfRmllbGRBY3Rpb24gZmE7CisJCQlmYS5iTW9kaWZpZXIgPSBwRW52LT5GRklfSXNDVFJMS2V5RG93bigwKTsKKwkJCWZhLmJTaGlmdCA9IHBFbnYtPkZGSV9Jc1NISUZUS2V5RG93bigwKTsKKwkJCWZhLnNWYWx1ZSA9IGNzVmFsdWU7CisKKwkJCXBBY3Rpb25IYW5kbGVyLT5Eb0FjdGlvbl9GaWVsZEphdmFTY3JpcHQoYWN0aW9uLCBDUERGX0FBY3Rpb246OlZhbGlkYXRlLCBtX3BEb2N1bWVudCwgcEZvcm1GaWVsZCwgZmEpOworCQkJYlJDID0gZmEuYlJDOworIAkgCisJCX0KKyAJfQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBhY3Rpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworRlhfQk9PTCBDUERGU0RLX0ludGVyRm9ybTo6RG9BY3Rpb25fSGlkZShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQoreworCUFTU0VSVChhY3Rpb24gIT0gTlVMTCk7CisKKwlDUERGX0FjdGlvbkZpZWxkcyBhZiA9IGFjdGlvbi5HZXRXaWRnZXRzKCk7CisJQ0ZYX1B0ckFycmF5IGZpZWxkT2JqZWN0czsKKwlhZi5HZXRBbGxGaWVsZHMoZmllbGRPYmplY3RzKTsKKwlDRlhfUHRyQXJyYXkgd2lkZ2V0QXJyYXk7CisJQ0ZYX1B0ckFycmF5IGZpZWxkczsKKwlHZXRGaWVsZEZyb21PYmplY3RzKGZpZWxkT2JqZWN0cywgZmllbGRzKTsKKworCUZYX0JPT0wgYkhpZGUgPSBhY3Rpb24uR2V0SGlkZVN0YXR1cygpOworCisJRlhfQk9PTCBiQ2hhbmdlZCA9IEZBTFNFOworCQorCWZvciAoaW50IGk9MCwgc3o9ZmllbGRzLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopZmllbGRzW2ldOworCQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOworCisJCisJCWZvciAoaW50IGo9MCxqc3o9cEZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGo8anN6OyBqKyspCisJCXsKKwkJCUNQREZfRm9ybUNvbnRyb2wqIHBDb250cm9sID0gcEZpZWxkLT5HZXRDb250cm9sKGopOworCQkJQVNTRVJUKHBDb250cm9sICE9IE5VTEwpOworCisJCQlpZiAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBHZXRXaWRnZXQocENvbnRyb2wpKQorCQkJeworCQkJCWludCBuRmxhZ3MgPSBwV2lkZ2V0LT5HZXRGbGFncygpOworCQkJCWlmIChiSGlkZSkKKwkJCQl7CisJCQkJCW5GbGFncyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOworCQkJCQluRmxhZ3MgJj0gKH5BTk5PVEZMQUdfTk9WSUVXKTsKKwkJCQkJbkZsYWdzIHw9IChBTk5PVEZMQUdfSElEREVOKTsKKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJbkZsYWdzICY9ICh+QU5OT1RGTEFHX0lOVklTSUJMRSk7CisJCQkJCW5GbGFncyAmPSAofkFOTk9URkxBR19ISURERU4pOworCQkJCQluRmxhZ3MgJj0gKH5BTk5PVEZMQUdfTk9WSUVXKTsKKwkJCQl9CisJCQkJcFdpZGdldC0+U2V0RmxhZ3MobkZsYWdzKTsKKworIAkJCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwV2lkZ2V0LT5HZXRQYWdlVmlldygpOworIAkJCQlBU1NFUlQocFBhZ2VWaWV3ICE9IE5VTEwpOworIAorIAkJCQlwUGFnZVZpZXctPlVwZGF0ZVZpZXcocFdpZGdldCk7CisKKwkJCQliQ2hhbmdlZCA9IFRSVUU7CisJCQl9CisJCX0KKwl9CisKKwlyZXR1cm4gYkNoYW5nZWQ7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OkRvQWN0aW9uX1N1Ym1pdEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbikKK3sKKwlBU1NFUlQoYWN0aW9uICE9IE5VTEwpOworCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlDRlhfV2lkZVN0cmluZyBzRGVzdGluYXRpb24gPSBhY3Rpb24uR2V0RmlsZVBhdGgoKTsKKwlpZiAoc0Rlc3RpbmF0aW9uLklzRW1wdHkoKSkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwQWN0aW9uRGljdCA9IGFjdGlvbjsKKwlpZiAocEFjdGlvbkRpY3QtPktleUV4aXN0KCJGaWVsZHMiKSkKKwl7CisJCUNQREZfQWN0aW9uRmllbGRzIGFmID0gYWN0aW9uLkdldFdpZGdldHMoKTsKKwkJRlhfRFdPUkQgZHdGbGFncyA9IGFjdGlvbi5HZXRGbGFncygpOworCQkKKwkJQ0ZYX1B0ckFycmF5IGZpZWxkT2JqZWN0czsKKwkJYWYuR2V0QWxsRmllbGRzKGZpZWxkT2JqZWN0cyk7CisJCUNGWF9QdHJBcnJheSBmaWVsZHM7CisJCUdldEZpZWxkRnJvbU9iamVjdHMoZmllbGRPYmplY3RzLCBmaWVsZHMpOworCQkKKwkJaWYgKGZpZWxkcy5HZXRTaXplKCkgIT0gMCkKKwkJeworCQkJRlhfQk9PTCBiSW5jbHVkZU9yRXhjbHVkZSA9ICEoZHdGbGFncyAmIDB4MDEpOworCQkJaWYgKG1fcEludGVyRm9ybS0+Q2hlY2tSZXF1aXJlZEZpZWxkcygmZmllbGRzLCBiSW5jbHVkZU9yRXhjbHVkZSkpCisJCQl7CisJCQkJcmV0dXJuIEZBTFNFOworCQkJfQorCQkJcmV0dXJuIFN1Ym1pdEZpZWxkcyhzRGVzdGluYXRpb24sIGZpZWxkcywgYkluY2x1ZGVPckV4Y2x1ZGUsIEZBTFNFKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCWlmICggbV9wSW50ZXJGb3JtLT5DaGVja1JlcXVpcmVkRmllbGRzKCkpCisJCQl7CisJCQkJcmV0dXJuIEZBTFNFOworCQkJfQorCisJCQlyZXR1cm4gU3VibWl0Rm9ybShzRGVzdGluYXRpb24sIEZBTFNFKTsKKwkJfQorCX0KKwllbHNlCisJeworCQlpZiAoIG1fcEludGVyRm9ybS0+Q2hlY2tSZXF1aXJlZEZpZWxkcygpKQorCQl7CisJCQlyZXR1cm4gRkFMU0U7CisJCX0KKworCQlyZXR1cm4gU3VibWl0Rm9ybShzRGVzdGluYXRpb24sIEZBTFNFKTsKKwl9Cit9CisKK0ZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OlN1Ym1pdEZpZWxkcyhjb25zdCBDRlhfV2lkZVN0cmluZyYgY3NEZXN0aW5hdGlvbiwgY29uc3QgQ0ZYX1B0ckFycmF5JiBmaWVsZHMsCisJCQkJCQkJCQlGWF9CT09MIGJJbmNsdWRlT3JFeGNsdWRlLCBGWF9CT09MIGJVcmxFbmNvZGVkKQoreworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7CisJQVNTRVJUKHBFbnYgIT0gTlVMTCk7CisKKwlDRlhfQnl0ZVRleHRCdWYgdGV4dEJ1ZjsKKwlFeHBvcnRGaWVsZHNUb0ZERlRleHRCdWYoZmllbGRzLCBiSW5jbHVkZU9yRXhjbHVkZSwgdGV4dEJ1Zik7CisKKwlGWF9MUEJZVEUgcEJ1ZmZlciA9IHRleHRCdWYuR2V0QnVmZmVyKCk7CisJRlhfU1RSU0laRSBuQnVmU2l6ZSA9IHRleHRCdWYuR2V0TGVuZ3RoKCk7CisJCisJaWYgKGJVcmxFbmNvZGVkKQorCXsKKwkJaWYoIUZERlRvVVJMRW5jb2RlZERhdGEocEJ1ZmZlciwgbkJ1ZlNpemUpKQorCQkJcmV0dXJuIEZBTFNFOworCX0KKworCXBFbnYtPkpTX2RvY1N1Ym1pdEZvcm0ocEJ1ZmZlciwgbkJ1ZlNpemUsIChGWF9MUENXU1RSKWNzRGVzdGluYXRpb24pOworCQorCWlmIChiVXJsRW5jb2RlZCAmJiBwQnVmZmVyKQorCXsKKwkJRlhfRnJlZShwQnVmZmVyKTsKKwkJcEJ1ZmZlciA9IE5VTEw7CQorCX0KKworCXJldHVybiBUUlVFOworfQorCit2b2lkIENQREZTREtfSW50ZXJGb3JtOjpEb0ZERkJ1ZmZlcihDRlhfQnl0ZVN0cmluZyBzQnVmZmVyKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmIChDRkRGX0RvY3VtZW50ICpwRkRGRG9jdW1lbnQgPSBDRkRGX0RvY3VtZW50OjpQYXJzZU1lbW9yeSgoY29uc3QgdW5zaWduZWQgY2hhciAqKXNCdWZmZXIuR2V0QnVmZmVyKHNCdWZmZXIuR2V0TGVuZ3RoKCkpLCBzQnVmZmVyLkdldExlbmd0aCgpKSkKKwl7CQkJCQkJCisJCUNQREZfRGljdGlvbmFyeSogcFJvb3REaWMgPSBwRkRGRG9jdW1lbnQtPkdldFJvb3QoKTsKKwkJaWYocFJvb3REaWMpCisJCXsKKwkJCUNQREZfRGljdGlvbmFyeSAqIHBGREZEaWN0PXBSb290RGljLT5HZXREaWN0KCJGREYiKTsKKwkJCWlmKHBGREZEaWN0KQorCQkJewkJCisJCQkJQ1BERl9EaWN0aW9uYXJ5ICogcEpTRGljdCA9IHBGREZEaWN0LT5HZXREaWN0KCJKYXZhU2NyaXB0Iik7CisJCQkJaWYocEpTRGljdCkKKwkJCQl7CisJCQkJCUNGWF9XaWRlU3RyaW5nIGNzSlM7CisJCQkJCisJCQkJCUNQREZfT2JqZWN0KiBwSlMgPSBwSlNEaWN0LT5HZXRFbGVtZW50VmFsdWUoIkJlZm9yZSIpOworCQkJCQlpZiAocEpTICE9IE5VTEwpCisJCQkJCXsKKwkJCQkJCWludCBpVHlwZSA9IHBKUy0+R2V0VHlwZSgpOworCQkJCQkJaWYgKGlUeXBlID09IFBERk9CSl9TVFJJTkcpCisJCQkJCQkJY3NKUyA9IHBKU0RpY3QtPkdldFVuaWNvZGVUZXh0KCJCZWZvcmUiKTsKKwkJCQkJCWVsc2UgaWYgKGlUeXBlID09IFBERk9CSl9TVFJFQU0pCisJCQkJCQkJY3NKUyA9IHBKUy0+R2V0VW5pY29kZVRleHQoKTsKKwkJCQkJfQorCQkJCQkKKwkJCQl9CisJCQl9CisJCX0KKwkJZGVsZXRlIHBGREZEb2N1bWVudDsKKwl9CisKKwlzQnVmZmVyLlJlbGVhc2VCdWZmZXIoKTsKK30KKworRlhfQk9PTCBDUERGU0RLX0ludGVyRm9ybTo6RkRGVG9VUkxFbmNvZGVkRGF0YShDRlhfV2lkZVN0cmluZyBjc0ZERkZpbGUsIENGWF9XaWRlU3RyaW5nIGNzVHh0RmlsZSkKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDUERGU0RLX0ludGVyRm9ybTo6RkRGVG9VUkxFbmNvZGVkRGF0YShGWF9MUEJZVEUmIHBCdWYsIEZYX1NUUlNJWkUmIG5CdWZTaXplKQoreworIAlDRkRGX0RvY3VtZW50KiBwRkRGID0gQ0ZERl9Eb2N1bWVudDo6UGFyc2VNZW1vcnkocEJ1ZiwgbkJ1ZlNpemUpOworIAlpZiAocEZERikKKyAJeworIAkJQ1BERl9EaWN0aW9uYXJ5KiBwTWFpbkRpY3QgPSBwRkRGLT5HZXRSb290KCktPkdldERpY3QoIkZERiIpOworIAkJaWYgKHBNYWluRGljdCA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CisgCQkKKyAJCS8vIEdldCBmaWVsZHMKKyAJCUNQREZfQXJyYXkqIHBGaWVsZHMgPSBwTWFpbkRpY3QtPkdldEFycmF5KCJGaWVsZHMiKTsKKyAJCWlmIChwRmllbGRzID09IE5VTEwpIHJldHVybiBGQUxTRTsKKwkJCisJCUNGWF9CeXRlVGV4dEJ1ZiBmZGZFbmNvZGVkRGF0YTsKKworIAkJZm9yIChGWF9EV09SRCBpID0gMDsgaSA8IHBGaWVsZHMtPkdldENvdW50KCk7IGkgKyspIAorIAkJeworIAkJCUNQREZfRGljdGlvbmFyeSogcEZpZWxkID0gcEZpZWxkcy0+R2V0RGljdChpKTsKKyAJCQlpZiAocEZpZWxkID09IE5VTEwpIGNvbnRpbnVlOworIAkJCUNGWF9XaWRlU3RyaW5nIG5hbWU7CisgCQkJbmFtZSA9IHBGaWVsZC0+R2V0VW5pY29kZVRleHQoIlQiKTsKKyAJCQlDRlhfQnl0ZVN0cmluZyBuYW1lX2IgPSBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUobmFtZSk7CisgCQkJQ0ZYX0J5dGVTdHJpbmcgY3NCVmFsdWUgPSBwRmllbGQtPkdldFN0cmluZygiViIpOworIAkJCUNGWF9XaWRlU3RyaW5nIGNzV1ZhbHVlID0gUERGX0RlY29kZVRleHQoY3NCVmFsdWUpOworIAkJCUNGWF9CeXRlU3RyaW5nIGNzVmFsdWVfYiA9IENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShjc1dWYWx1ZSk7CisKKwkJCWZkZkVuY29kZWREYXRhID0gZmRmRW5jb2RlZERhdGE8PG5hbWVfYi5HZXRCdWZmZXIobmFtZV9iLkdldExlbmd0aCgpKTsKKyAgCQkJbmFtZV9iLlJlbGVhc2VCdWZmZXIoKTsKKwkJCWZkZkVuY29kZWREYXRhID0gZmRmRW5jb2RlZERhdGE8PCI9IjsKKwkJCWZkZkVuY29kZWREYXRhID0gZmRmRW5jb2RlZERhdGE8PGNzVmFsdWVfYi5HZXRCdWZmZXIoY3NWYWx1ZV9iLkdldExlbmd0aCgpKTsKKyAgCQkJY3NWYWx1ZV9iLlJlbGVhc2VCdWZmZXIoKTsKKyAgCQkJaWYoaSAhPSBwRmllbGRzLT5HZXRDb3VudCgpLTEpCisgIAkJCQlmZGZFbmNvZGVkRGF0YSA9IGZkZkVuY29kZWREYXRhPDwiJiI7CisgCQl9CisJCQorCQluQnVmU2l6ZSA9IGZkZkVuY29kZWREYXRhLkdldExlbmd0aCgpOworCQlwQnVmID0gRlhfQWxsb2MoRlhfQllURSwgbkJ1ZlNpemUpOworCQlpZighcEJ1ZikKKwkJCXJldHVybiBGQUxTRTsKKwkJRlhTWVNfbWVtY3B5KHBCdWYsIGZkZkVuY29kZWREYXRhLkdldEJ1ZmZlcigpLCBuQnVmU2l6ZSk7CisgCQkKKyAJfQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpFeHBvcnRGaWVsZHNUb0ZERkZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGREZGaWxlTmFtZSwgCisJCQkJCQkJCQkJCQkgY29uc3QgQ0ZYX1B0ckFycmF5JiBmaWVsZHMsIEZYX0JPT0wgYkluY2x1ZGVPckV4Y2x1ZGUpCit7CisJaWYgKHNGREZGaWxlTmFtZS5Jc0VtcHR5KCkpIHJldHVybiBGQUxTRTsKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsKKworIAlDRkRGX0RvY3VtZW50KiBwRkRGID0gbV9wSW50ZXJGb3JtLT5FeHBvcnRUb0ZERihtX3BEb2N1bWVudC0+R2V0UGF0aCgpLChDRlhfUHRyQXJyYXkmKWZpZWxkcywgYkluY2x1ZGVPckV4Y2x1ZGUpOworIAlpZiAoIXBGREYpIHJldHVybiBGQUxTRTsKKyAJRlhfQk9PTCBiUmV0ID0gcEZERi0+V3JpdGVGaWxlKHNGREZGaWxlTmFtZS5VVEY4RW5jb2RlKCkpOyAvLyA9IEZBTFNFOy8vCisJZGVsZXRlIHBGREY7CisKKwlyZXR1cm4gYlJldDsKK30KK0ZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OkV4cG9ydEZpZWxkc1RvRkRGVGV4dEJ1Zihjb25zdCBDRlhfUHRyQXJyYXkmIGZpZWxkcyxGWF9CT09MIGJJbmNsdWRlT3JFeGNsdWRlLCBDRlhfQnl0ZVRleHRCdWYmIHRleHRCdWYpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCUFTU0VSVChtX3BJbnRlckZvcm0gIT0gTlVMTCk7CisJCisJQ0ZERl9Eb2N1bWVudCogcEZERiA9IG1fcEludGVyRm9ybS0+RXhwb3J0VG9GREYobV9wRG9jdW1lbnQtPkdldFBhdGgoKSwoQ0ZYX1B0ckFycmF5JilmaWVsZHMsIGJJbmNsdWRlT3JFeGNsdWRlKTsKKwlpZiAoIXBGREYpIHJldHVybiBGQUxTRTsKKwlGWF9CT09MIGJSZXQgPSBwRkRGLT5Xcml0ZUJ1Zih0ZXh0QnVmKTsgLy8gPSBGQUxTRTsvLworCWRlbGV0ZSBwRkRGOworCQorCXJldHVybiBiUmV0OworfQorCitDRlhfV2lkZVN0cmluZyBDUERGU0RLX0ludGVyRm9ybTo6R2V0VGVtcG9yYXJ5RmlsZU5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNGaWxlRXh0KQoreworCUNGWF9XaWRlU3RyaW5nIHNGaWxlTmFtZTsKKwlyZXR1cm4gTCIiOworfQorCitGWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpTdWJtaXRGb3JtKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzRGVzdGluYXRpb24sIEZYX0JPT0wgYlVybEVuY29kZWQpCit7CisgCWlmIChzRGVzdGluYXRpb24uSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7CisKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOworCUFTU0VSVChwRW52ICE9IE5VTEwpOworCisJaWYoTlVMTCA9PSBtX3BEb2N1bWVudCkgcmV0dXJuIEZBTFNFOworCUNGWF9XaWRlU3RyaW5nIHdzUERGRmlsZVBhdGggPSBtX3BEb2N1bWVudC0+R2V0UGF0aCgpOworCQorCWlmKE5VTEwgPT0gbV9wSW50ZXJGb3JtKSByZXR1cm4gRkFMU0U7CisJQ0ZERl9Eb2N1bWVudCogcEZERkRvYyA9IG1fcEludGVyRm9ybS0+RXhwb3J0VG9GREYod3NQREZGaWxlUGF0aCk7CisJaWYgKE5VTEwgPT0gcEZERkRvYykgcmV0dXJuIEZBTFNFOworCisJQ0ZYX0J5dGVUZXh0QnVmIEZkZkJ1ZmZlcjsKKwlGWF9CT09MIGJSZXQgPSBwRkRGRG9jLT5Xcml0ZUJ1ZihGZGZCdWZmZXIpOworCWRlbGV0ZSBwRkRGRG9jOworCWlmICghYlJldCkgcmV0dXJuIEZBTFNFOworCisJRlhfTFBCWVRFIHBCdWZmZXIgPSBGZGZCdWZmZXIuR2V0QnVmZmVyKCk7CisJRlhfU1RSU0laRSBuQnVmU2l6ZSA9IEZkZkJ1ZmZlci5HZXRMZW5ndGgoKTsKKwkKKwlpZiAoYlVybEVuY29kZWQpCisJeworCQlpZighRkRGVG9VUkxFbmNvZGVkRGF0YShwQnVmZmVyLCBuQnVmU2l6ZSkpCisJCQlyZXR1cm4gRkFMU0U7CisJfQorCisJcEVudi0+SlNfZG9jU3VibWl0Rm9ybShwQnVmZmVyLCBuQnVmU2l6ZSwgKEZYX0xQQ1dTVFIpc0Rlc3RpbmF0aW9uKTsKKwkKKwlpZiAoYlVybEVuY29kZWQgJiYgcEJ1ZmZlcikKKwl7CisJCUZYX0ZyZWUocEJ1ZmZlcik7CisJCXBCdWZmZXIgPSBOVUxMOwkKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDUERGU0RLX0ludGVyRm9ybTo6RXhwb3J0Rm9ybVRvRkRGRmlsZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZERkZpbGVOYW1lKQoreworCWlmIChzRkRGRmlsZU5hbWUuSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7CisKKwlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNGREZfRG9jdW1lbnQqIHBGREYgPSBtX3BJbnRlckZvcm0tPkV4cG9ydFRvRkRGKG1fcERvY3VtZW50LT5HZXRQYXRoKCkpOworCWlmICghcEZERikgcmV0dXJuIEZBTFNFOworCisJRlhfQk9PTCBiUmV0ID0gcEZERi0+V3JpdGVGaWxlKHNGREZGaWxlTmFtZS5VVEY4RW5jb2RlKCkpOworCWRlbGV0ZSBwRkRGOworCisJcmV0dXJuIGJSZXQ7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OkV4cG9ydEZvcm1Ub0ZERlRleHRCdWYoQ0ZYX0J5dGVUZXh0QnVmJiB0ZXh0QnVmKQoreworCisJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisJCisJQ0ZERl9Eb2N1bWVudCogcEZERiA9IG1fcEludGVyRm9ybS0+RXhwb3J0VG9GREYobV9wRG9jdW1lbnQtPkdldFBhdGgoKSk7CisJaWYgKCFwRkRGKSByZXR1cm4gRkFMU0U7CisJCisJRlhfQk9PTCBiUmV0ID0gcEZERi0+V3JpdGVCdWYodGV4dEJ1Zik7CisJZGVsZXRlIHBGREY7CisJCisJcmV0dXJuIGJSZXQ7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19JbnRlckZvcm06OkV4cG9ydEZvcm1Ub1R4dEZpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUeHRGaWxlTmFtZSkKK3sKKwlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ0ZYX1dpZGVTdHJpbmcgc0ZpZWxkTmFtZXM7CisJQ0ZYX1dpZGVTdHJpbmcgc0ZpZWxkVmFsdWVzOworCisJaW50IG5TaXplID0gbV9wSW50ZXJGb3JtLT5Db3VudEZpZWxkcygpOworCisJaWYgKG5TaXplID4gMCkKKwl7CisJCWZvciAoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQorCQl7CisJCQlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gbV9wSW50ZXJGb3JtLT5HZXRGaWVsZChpKTsKKwkJCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwkJCWlmIChpICE9IDApCisJCQl7CisJCQkJc0ZpZWxkTmFtZXMgKz0gTCJcdCI7CisJCQkJc0ZpZWxkVmFsdWVzICs9IEwiXHQiOworCQkJfQorCQkJc0ZpZWxkTmFtZXMgKz0gcEZpZWxkLT5HZXRGdWxsTmFtZSgpOworCQkJc0ZpZWxkVmFsdWVzICs9IHBGaWVsZC0+R2V0VmFsdWUoKTsKKwkJfQorCisJCXJldHVybiBUUlVFOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAlDUERGU0RLX0ludGVyRm9ybTo6SW1wb3J0Rm9ybUZyb21UeHRGaWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVHh0RmlsZU5hbWUpCit7CisJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpEb0FjdGlvbl9SZXNldEZvcm0oY29uc3QgQ1BERl9BY3Rpb24mIGFjdGlvbikKK3sKKwlBU1NFUlQoYWN0aW9uICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwQWN0aW9uRGljdCA9IGFjdGlvbjsKKworCWlmIChwQWN0aW9uRGljdC0+S2V5RXhpc3QoIkZpZWxkcyIpKQorCXsKKwkJQ1BERl9BY3Rpb25GaWVsZHMgYWYgPSBhY3Rpb24uR2V0V2lkZ2V0cygpOworCQlGWF9EV09SRCBkd0ZsYWdzID0gYWN0aW9uLkdldEZsYWdzKCk7CisJCQorCQlDRlhfUHRyQXJyYXkgZmllbGRPYmplY3RzOworCQlhZi5HZXRBbGxGaWVsZHMoZmllbGRPYmplY3RzKTsKKwkJQ0ZYX1B0ckFycmF5IGZpZWxkczsKKwkJR2V0RmllbGRGcm9tT2JqZWN0cyhmaWVsZE9iamVjdHMsIGZpZWxkcyk7CisJCQorCQlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOworCisJCXJldHVybiBtX3BJbnRlckZvcm0tPlJlc2V0Rm9ybShmaWVsZHMsICEoZHdGbGFncyAmIDB4MDEpLCBUUlVFKTsKKwl9CisJZWxzZQorCXsKKwkJQVNTRVJUKG1fcEludGVyRm9ybSAhPSBOVUxMKTsKKwkJcmV0dXJuIG1fcEludGVyRm9ybS0+UmVzZXRGb3JtKFRSVUUpOworCX0KK30KKworRlhfQk9PTCBDUERGU0RLX0ludGVyRm9ybTo6RG9BY3Rpb25fSW1wb3J0RGF0YShjb25zdCBDUERGX0FjdGlvbiYgYWN0aW9uKQoreworCUFTU0VSVChhY3Rpb24gIT0gTlVMTCk7CisKKwlDRlhfV2lkZVN0cmluZyBzRmlsZVBhdGggPSBhY3Rpb24uR2V0RmlsZVBhdGgoKTsKKwlpZiAoc0ZpbGVQYXRoLklzRW1wdHkoKSkKKwkJcmV0dXJuIEZBTFNFOworCisJaWYgKCFJbXBvcnRGb3JtRnJvbUZERkZpbGUoc0ZpbGVQYXRoLCBUUlVFKSkKKwl7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDUERGU0RLX0ludGVyRm9ybTo6SW1wb3J0Rm9ybUZyb21GREZGaWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBjc0ZERkZpbGVOYW1lLAorCQkJCQkJCQkJCQkJIEZYX0JPT0wgYk5vdGlmeSkKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ1BERlNES19JbnRlckZvcm06OkdldEZpZWxkRnJvbU9iamVjdHMoY29uc3QgQ0ZYX1B0ckFycmF5JiBvYmplY3RzLCBDRlhfUHRyQXJyYXkmIGZpZWxkcykKK3sKKwlBU1NFUlQobV9wSW50ZXJGb3JtICE9IE5VTEwpOworCisJaW50IGlDb3VudCA9IG9iamVjdHMuR2V0U2l6ZSgpOworCWZvciAoaW50IGkgPSAwOyBpIDwgaUNvdW50OyBpICsrKQorCXsKKwkJQ1BERl9PYmplY3QqIHBPYmplY3QgPSAoQ1BERl9PYmplY3QqKW9iamVjdHNbaV07CisJCWlmIChwT2JqZWN0ID09IE5VTEwpIGNvbnRpbnVlOworCQkKKwkJaW50IGlUeXBlID0gcE9iamVjdC0+R2V0VHlwZSgpOworCQlpZiAoaVR5cGUgPT0gUERGT0JKX1NUUklORykKKwkJeworCQkJQ0ZYX1dpZGVTdHJpbmcgY3NOYW1lID0gcE9iamVjdC0+R2V0VW5pY29kZVRleHQoKTsKKwkJCUNQREZfRm9ybUZpZWxkKiBwRmllbGQgPSBtX3BJbnRlckZvcm0tPkdldEZpZWxkKDAsIGNzTmFtZSk7CisJCQlpZiAocEZpZWxkICE9IE5VTEwpCisJCQkJZmllbGRzLkFkZChwRmllbGQpOworCQl9CisJCWVsc2UgaWYgKGlUeXBlID09IFBERk9CSl9ESUNUSU9OQVJZKQorCQl7CisJCQlpZiAobV9wSW50ZXJGb3JtLT5Jc1ZhbGlkRm9ybUZpZWxkKHBPYmplY3QpKQorCQkJCWZpZWxkcy5BZGQocE9iamVjdCk7CisJCX0KKwl9Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQREZfRm9ybU5vdGlmeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitpbnQJQ1BERlNES19JbnRlckZvcm06OkJlZm9yZVZhbHVlQ2hhbmdlKGNvbnN0IENQREZfRm9ybUZpZWxkKiBwRmllbGQsIENGWF9XaWRlU3RyaW5nJiBjc1ZhbHVlKQoreworCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopcEZpZWxkOworCisJaW50IG5UeXBlID0gcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCk7CisJaWYgKG5UeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCB8fCBuVHlwZSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEKQorCXsKKwkJRlhfQk9PTCBiUkMgPSBUUlVFOworCQlPbktleVN0cm9rZUNvbW1pdChwRm9ybUZpZWxkLCBjc1ZhbHVlLCBiUkMpOworCQlpZiAoYlJDKSAKKwkJeworCQkJT25WYWxpZGF0ZShwRm9ybUZpZWxkLCBjc1ZhbHVlLCBiUkMpOworCQkJaWYgKGJSQykKKwkJCQlyZXR1cm4gMTsKKwkJCWVsc2UKKwkJCQlyZXR1cm4gLTE7CisJCX0KKwkJZWxzZQorCQkJcmV0dXJuIC0xOworCX0KKwllbHNlCisJCXJldHVybiAwOworfQorCitpbnQJQ1BERlNES19JbnRlckZvcm06OkFmdGVyVmFsdWVDaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCkKK3sKKwlBU1NFUlQocEZpZWxkICE9IE5VTEwpOworCisJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKXBGaWVsZDsKKwlpbnQgblR5cGUgPSBwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKTsKKworCWlmIChuVHlwZSA9PSBGSUVMRFRZUEVfQ09NQk9CT1ggfHwgblR5cGUgPT0gRklFTERUWVBFX1RFWFRGSUVMRCkKKwl7CisJCXRoaXMtPk9uQ2FsY3VsYXRlKHBGb3JtRmllbGQpOworCQlGWF9CT09MIGJGb3JtYXRlZCA9IEZBTFNFOworCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSB0aGlzLT5PbkZvcm1hdChwRm9ybUZpZWxkLCAwLCBiRm9ybWF0ZWQpOworCQlpZiAoYkZvcm1hdGVkKQorCQkJdGhpcy0+UmVzZXRGaWVsZEFwcGVhcmFuY2UocEZvcm1GaWVsZCwgc1ZhbHVlLCBUUlVFKTsKKwkJZWxzZQorCQkJdGhpcy0+UmVzZXRGaWVsZEFwcGVhcmFuY2UocEZvcm1GaWVsZCwgTlVMTCwgVFJVRSk7CisJCXRoaXMtPlVwZGF0ZUZpZWxkKHBGb3JtRmllbGQpOworCX0KKworCXJldHVybiAwOworfQorCitpbnQJQ1BERlNES19JbnRlckZvcm06OkJlZm9yZVNlbGVjdGlvbkNoYW5nZShjb25zdCBDUERGX0Zvcm1GaWVsZCogcEZpZWxkLCBDRlhfV2lkZVN0cmluZyYgY3NWYWx1ZSkKK3sKKwlBU1NFUlQocEZpZWxkICE9IE5VTEwpOworCisJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKXBGaWVsZDsKKworCWludCBuVHlwZSA9IHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpOworCWlmIChuVHlwZSA9PSBGSUVMRFRZUEVfTElTVEJPWCkKKwl7CisJCUZYX0JPT0wgYlJDID0gVFJVRTsKKwkJT25LZXlTdHJva2VDb21taXQocEZvcm1GaWVsZCwgY3NWYWx1ZSwgYlJDKTsKKwkJaWYgKGJSQykgCisJCXsKKwkJCU9uVmFsaWRhdGUocEZvcm1GaWVsZCwgY3NWYWx1ZSwgYlJDKTsKKwkJCWlmIChiUkMpCisJCQkJcmV0dXJuIDE7CisJCQllbHNlCisJCQkJcmV0dXJuIC0xOworCQl9CisJCWVsc2UKKwkJCXJldHVybiAtMTsKKwl9CisJZWxzZQorCQlyZXR1cm4gMDsKK30KKworaW50CUNQREZTREtfSW50ZXJGb3JtOjpBZnRlclNlbGVjdGlvbkNoYW5nZShjb25zdCBDUERGX0Zvcm1GaWVsZCogcEZpZWxkKQoreworCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopcEZpZWxkOworCWludCBuVHlwZSA9IHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpOworCisJaWYgKG5UeXBlID09IEZJRUxEVFlQRV9MSVNUQk9YKQorCXsKKwkJdGhpcy0+T25DYWxjdWxhdGUocEZvcm1GaWVsZCk7CisJCXRoaXMtPlJlc2V0RmllbGRBcHBlYXJhbmNlKHBGb3JtRmllbGQsIE5VTEwsIFRSVUUpOworCQl0aGlzLT5VcGRhdGVGaWVsZChwRm9ybUZpZWxkKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworaW50CUNQREZTREtfSW50ZXJGb3JtOjpBZnRlckNoZWNrZWRTdGF0dXNDaGFuZ2UoY29uc3QgQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCwgY29uc3QgQ0ZYX0J5dGVBcnJheSYgc3RhdHVzQXJyYXkpCit7CisJQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsKKworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilwRmllbGQ7CisJaW50IG5UeXBlID0gcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCk7CisKKwlpZiAoblR5cGUgPT0gRklFTERUWVBFX0NIRUNLQk9YIHx8IG5UeXBlID09IEZJRUxEVFlQRV9SQURJT0JVVFRPTikKKwl7CisJCXRoaXMtPk9uQ2FsY3VsYXRlKHBGb3JtRmllbGQpOworCQkvL3RoaXMtPlJlc2V0RmllbGRBcHBlYXJhbmNlKHBGb3JtRmllbGQsIE5VTEwpOworCQl0aGlzLT5VcGRhdGVGaWVsZChwRm9ybUZpZWxkKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworaW50CUNQREZTREtfSW50ZXJGb3JtOjpCZWZvcmVGb3JtUmVzZXQoY29uc3QgQ1BERl9JbnRlckZvcm0qIHBGb3JtKQoreworCXJldHVybiAwOworfQorCitpbnQJQ1BERlNES19JbnRlckZvcm06OkFmdGVyRm9ybVJlc2V0KGNvbnN0IENQREZfSW50ZXJGb3JtKiBwRm9ybSkKK3sKKwl0aGlzLT5PbkNhbGN1bGF0ZShOVUxMKTsKKworCXJldHVybiAwOworfQorCitpbnQJQ1BERlNES19JbnRlckZvcm06OkJlZm9yZUZvcm1JbXBvcnREYXRhKGNvbnN0IENQREZfSW50ZXJGb3JtKiBwRm9ybSkKK3sKKwlyZXR1cm4gMDsKK30KKworaW50CUNQREZTREtfSW50ZXJGb3JtOjpBZnRlckZvcm1JbXBvcnREYXRhKGNvbnN0IENQREZfSW50ZXJGb3JtKiBwRm9ybSkKK3sKKwl0aGlzLT5PbkNhbGN1bGF0ZShOVUxMKTsKKworCXJldHVybiAwOworfQorCitGWF9CT09MIENQREZTREtfSW50ZXJGb3JtOjpJc05lZWRIaWdoTGlnaHQoaW50IG5GaWVsZFR5cGUpCit7CisJaWYobkZpZWxkVHlwZSA8MSB8fCBuRmllbGRUeXBlID4gNikKKwkJcmV0dXJuIEZBTFNFOworCXJldHVybiBtX2JOZWVkSGlnaHRsaWdodFtuRmllbGRUeXBlLTFdOworfQorCit2b2lkIENQREZTREtfSW50ZXJGb3JtOjpSZW1vdmVBbGxIaWdoTGlnaHQoKQoreworCW1lbXNldCgodm9pZCopbV9iTmVlZEhpZ2h0bGlnaHQsIDAsIDYqc2l6ZW9mKEZYX0JPT0wpKTsKK30KK3ZvaWQgICBDUERGU0RLX0ludGVyRm9ybTo6U2V0SGlnaGxpZ2h0Q29sb3IoRlhfQ09MT1JSRUYgY2xyLCBpbnQgbkZpZWxkVHlwZSkKK3sKKwlpZihuRmllbGRUeXBlIDwwIHx8IG5GaWVsZFR5cGUgPiA2KSByZXR1cm47CisJc3dpdGNoKG5GaWVsZFR5cGUpCisJeworCWNhc2UgMDoKKwkJeworCQkJZm9yKGludCBpPTA7IGk8NjsgaSsrKQorCQkJeworCQkJCW1fYUhpZ2hsaWdodENvbG9yW2ldID0gY2xyOworCQkJCW1fYk5lZWRIaWdodGxpZ2h0W2ldID0gVFJVRTsKKwkJCX0KKwkJCWJyZWFrOworCQl9CisJZGVmYXVsdDoKKwkJeworCQkJbV9hSGlnaGxpZ2h0Q29sb3JbbkZpZWxkVHlwZS0xXSA9IGNscjsKKwkJCW1fYk5lZWRIaWdodGxpZ2h0W25GaWVsZFR5cGUtMV0gPSBUUlVFOworCQkJYnJlYWs7CisJCX0KKwl9CisJCit9CisKK0ZYX0NPTE9SUkVGIENQREZTREtfSW50ZXJGb3JtOjpHZXRIaWdobGlnaHRDb2xvcihpbnQgbkZpZWxkVHlwZSkKK3sKKwlpZihuRmllbGRUeXBlIDwwIHx8IG5GaWVsZFR5cGUgPjYpIHJldHVybiBGWFNZU19SR0IoMjU1LDI1NSwyNTUpOworCWlmKG5GaWVsZFR5cGUgPT0gMCkKKwkJcmV0dXJuIG1fYUhpZ2hsaWdodENvbG9yWzBdOworCWVsc2UKKwkJcmV0dXJuIG1fYUhpZ2hsaWdodENvbG9yW25GaWVsZFR5cGUtMV07Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0JBX0Fubm90SXRlcmF0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDQkFfQW5ub3RJdGVyYXRvcjo6Q0JBX0Fubm90SXRlcmF0b3IoQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc1R5cGUsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzU3ViVHlwZSkKKwk6bV9wUGFnZVZpZXcocFBhZ2VWaWV3KSwKKwltX3NUeXBlKHNUeXBlKSwKKwltX3NTdWJUeXBlKHNTdWJUeXBlKSwKKwltX25UYWJzKEJBSV9TVFJVQ1RVUkUpCit7CisJQVNTRVJUKG1fcFBhZ2VWaWV3ICE9IE5VTEwpOworCisJQ1BERl9QYWdlKiBwUERGUGFnZSA9IG1fcFBhZ2VWaWV3LT5HZXRQREZQYWdlKCk7CisJQVNTRVJUKHBQREZQYWdlICE9IE5VTEwpOworCUFTU0VSVChwUERGUGFnZS0+bV9wRm9ybURpY3QgIT0gTlVMTCk7CisKKwlDRlhfQnl0ZVN0cmluZyBzVGFicyA9IHBQREZQYWdlLT5tX3BGb3JtRGljdC0+R2V0U3RyaW5nKCJUYWJzIik7CisKKwlpZiAoc1RhYnMgPT0gIlIiKQorCXsKKwkJbV9uVGFicyA9IEJBSV9ST1c7CisJfQorCWVsc2UgaWYgKHNUYWJzID09ICJDIikKKwl7CisJCW1fblRhYnMgPSBCQUlfQ09MVU1OOworCX0KKwllbHNlCisJeworCQltX25UYWJzID0gQkFJX1NUUlVDVFVSRTsKKwl9CisKKwlHZW5lcmF0ZVJlc3VsdHMoKTsKK30KKworQ0JBX0Fubm90SXRlcmF0b3I6On5DQkFfQW5ub3RJdGVyYXRvcigpCit7CisJbV9Bbm5vdHMuUmVtb3ZlQWxsKCk7Cit9CisKK0NQREZTREtfQW5ub3QqIENCQV9Bbm5vdEl0ZXJhdG9yOjpHZXRGaXJzdEFubm90KCkKK3sKKwlpZiAobV9Bbm5vdHMuR2V0U2l6ZSgpID4gMCkKKwkJcmV0dXJuIG1fQW5ub3RzWzBdOworCQorCXJldHVybiBOVUxMOworfQorCitDUERGU0RLX0Fubm90KiBDQkFfQW5ub3RJdGVyYXRvcjo6R2V0TGFzdEFubm90KCkKK3sKKwlpZiAobV9Bbm5vdHMuR2V0U2l6ZSgpID4gMCkKKwkJcmV0dXJuIG1fQW5ub3RzW21fQW5ub3RzLkdldFNpemUoKSAtIDFdOworCisJcmV0dXJuIE5VTEw7Cit9CisKK0NQREZTREtfQW5ub3QqIENCQV9Bbm5vdEl0ZXJhdG9yOjpHZXROZXh0QW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90KQoreworCWZvciAoaW50IGk9MCxzej1tX0Fubm90cy5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChtX0Fubm90c1tpXSA9PSBwQW5ub3QpCisJCXsKKwkJCWlmIChpKzEgPCBzeikKKwkJCQlyZXR1cm4gbV9Bbm5vdHNbaSsxXTsKKwkJCWVsc2UKKwkJCQlyZXR1cm4gbV9Bbm5vdHNbMF07CisJCX0KKwl9CisKKwlyZXR1cm4gTlVMTDsKK30KKworQ1BERlNES19Bbm5vdCogQ0JBX0Fubm90SXRlcmF0b3I6OkdldFByZXZBbm5vdChDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJZm9yIChpbnQgaT0wLHN6PW1fQW5ub3RzLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJaWYgKG1fQW5ub3RzW2ldID09IHBBbm5vdCkKKwkJeworCQkJaWYgKGktMSA+PSAwKQorCQkJCXJldHVybiBtX0Fubm90c1tpLTFdOworCQkJZWxzZQorCQkJCXJldHVybiBtX0Fubm90c1tzei0xXTsKKwkJfQorCX0KKworCXJldHVybiBOVUxMOworfQorCitpbnQgQ0JBX0Fubm90SXRlcmF0b3I6OkNvbXBhcmVCeUxlZnQoQ1BERlNES19Bbm5vdCogcDEsIENQREZTREtfQW5ub3QqIHAyKQoreworCUFTU0VSVChwMSAhPSBOVUxMKTsKKwlBU1NFUlQocDIgIT0gTlVMTCk7CisKKwlDUERGX1JlY3QgcmNBbm5vdDEgPSBHZXRBbm5vdFJlY3QocDEpOworCUNQREZfUmVjdCByY0Fubm90MiA9IEdldEFubm90UmVjdChwMik7CisKKwlpZiAocmNBbm5vdDEubGVmdCA8IHJjQW5ub3QyLmxlZnQpCisJCXJldHVybiAtMTsKKwlpZiAocmNBbm5vdDEubGVmdCA+IHJjQW5ub3QyLmxlZnQpCisJCXJldHVybiAxOworCXJldHVybiAwOworfQorCisKK2ludCBDQkFfQW5ub3RJdGVyYXRvcjo6Q29tcGFyZUJ5VG9wKENQREZTREtfQW5ub3QqIHAxLCBDUERGU0RLX0Fubm90KiBwMikKK3sKKwlBU1NFUlQocDEgIT0gTlVMTCk7CisJQVNTRVJUKHAyICE9IE5VTEwpOworCisJQ1BERl9SZWN0IHJjQW5ub3QxID0gR2V0QW5ub3RSZWN0KHAxKTsKKwlDUERGX1JlY3QgcmNBbm5vdDIgPSBHZXRBbm5vdFJlY3QocDIpOworCisJaWYgKHJjQW5ub3QxLnRvcCA8IHJjQW5ub3QyLnRvcCkKKwkJcmV0dXJuIC0xOworCWlmIChyY0Fubm90MS50b3AgPiByY0Fubm90Mi50b3ApCisJCXJldHVybiAxOworCXJldHVybiAwOworfQorCit2b2lkIENCQV9Bbm5vdEl0ZXJhdG9yOjpHZW5lcmF0ZVJlc3VsdHMoKQoreworCUFTU0VSVChtX3BQYWdlVmlldyAhPSBOVUxMKTsKKworCXN3aXRjaCAobV9uVGFicykKKwl7CisJY2FzZSBCQUlfU1RSVUNUVVJFOgorCQl7CisJCQlmb3IgKGludCBpPTAsc3o9bV9wUGFnZVZpZXctPkNvdW50QW5ub3RzKCk7IGk8c3o7IGkrKykKKwkJCXsKKwkJCQlDUERGU0RLX0Fubm90KiBwQW5ub3QgPSBtX3BQYWdlVmlldy0+R2V0QW5ub3QoaSk7CisJCQkJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKworCQkJCWlmIChwQW5ub3QtPkdldFR5cGUoKSA9PSBtX3NUeXBlIAorCQkJCQkmJiBwQW5ub3QtPkdldFN1YlR5cGUoKSA9PSBtX3NTdWJUeXBlKQorCQkJCQltX0Fubm90cy5BZGQocEFubm90KTsKKwkJCX0KKwkJfQorCQlicmVhazsKKwljYXNlIEJBSV9ST1c6CisJCXsKKwkJCUNQREZTREtfU29ydEFubm90cyBzYTsKKworCQkJeworCQkJCQorCQkJCWZvciAoaW50IGk9MCxzej1tX3BQYWdlVmlldy0+Q291bnRBbm5vdHMoKTsgaTxzejsgaSsrKQorCQkJCXsKKwkJCQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gbV9wUGFnZVZpZXctPkdldEFubm90KGkpOworCQkJCQlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCisJCQkJCWlmIChwQW5ub3QtPkdldFR5cGUoKSA9PSBtX3NUeXBlIAorCQkJCQkJJiYgcEFubm90LT5HZXRTdWJUeXBlKCkgPT0gbV9zU3ViVHlwZSkKKwkJCQkJCXNhLkFkZChwQW5ub3QpOworCQkJCX0KKwkJCX0KKworCQkJaWYgKHNhLkdldFNpemUoKSA+IDApCisJCQl7CisJCQkJc2EuU29ydChDQkFfQW5ub3RJdGVyYXRvcjo6Q29tcGFyZUJ5TGVmdCk7CisJCQl9CisKKwkJCXdoaWxlIChzYS5HZXRTaXplKCkgPiAwKQorCQkJeworCQkJCWludCBuTGVmdFRvcEluZGV4ID0gLTE7CisKKwkJCQl7CisJCQkJCUZYX0ZMT0FUIGZUb3AgPSAwLjBmOworCisJCQkJCWZvciAoaW50IGk9c2EuR2V0U2l6ZSgpLTE7IGk+PTA7IGktLSkKKwkJCQkJeworCQkJCQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gc2EuR2V0QXQoaSk7CisJCQkJCQlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCisJCQkJCQlDUERGX1JlY3QgcmNBbm5vdCA9IEdldEFubm90UmVjdChwQW5ub3QpOworCisJCQkJCQlpZiAocmNBbm5vdC50b3AgPiBmVG9wKQorCQkJCQkJeworCQkJCQkJCW5MZWZ0VG9wSW5kZXggPSBpOworCQkJCQkJCWZUb3AgPSByY0Fubm90LnRvcDsKKwkJCQkJCX0KKwkJCQkJfQorCQkJCX0KKworCQkJCWlmIChuTGVmdFRvcEluZGV4ID49IDApCisJCQkJeworCQkJCQlDUERGU0RLX0Fubm90KiBwTGVmdFRvcEFubm90ID0gc2EuR2V0QXQobkxlZnRUb3BJbmRleCk7CisJCQkJCUFTU0VSVChwTGVmdFRvcEFubm90ICE9IE5VTEwpOworCisJCQkJCUNQREZfUmVjdCByY0xlZnRUb3AgPSBHZXRBbm5vdFJlY3QocExlZnRUb3BBbm5vdCk7CisJCQkJCQorCQkJCQltX0Fubm90cy5BZGQocExlZnRUb3BBbm5vdCk7CisJCQkJCXNhLlJlbW92ZUF0KG5MZWZ0VG9wSW5kZXgpOworCisJCQkJCUNGWF9BcnJheVRlbXBsYXRlPGludD4gYVNlbGVjdDsKKworCQkJCQl7CisJCQkJCQlmb3IgKGludCBpPTAsc3o9c2EuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQkJCQl7CisJCQkJCQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gc2EuR2V0QXQoaSk7CisJCQkJCQkJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKworCQkJCQkJCUNQREZfUmVjdCByY0Fubm90ID0gR2V0QW5ub3RSZWN0KHBBbm5vdCk7CisKKwkJCQkJCQlGWF9GTE9BVCBmQ2VudGVyWSA9IChyY0Fubm90LnRvcCArIHJjQW5ub3QuYm90dG9tKSAvIDIuMGY7CisKKwkJCQkJCQlpZiAoZkNlbnRlclkgPiByY0xlZnRUb3AuYm90dG9tICYmIGZDZW50ZXJZIDwgcmNMZWZ0VG9wLnRvcCkKKwkJCQkJCQkJYVNlbGVjdC5BZGQoaSk7CisJCQkJCQl9CisJCQkJCX0KKworCQkJCQl7CisJCQkJCQlmb3IgKGludCBpPTAsc3o9YVNlbGVjdC5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJCQkJCXsKKwkJCQkJCQltX0Fubm90cy5BZGQoc2FbYVNlbGVjdFtpXV0pOworCQkJCQkJfQorCQkJCQl9CisKKwkJCQkJeworCQkJCQkJZm9yIChpbnQgaT1hU2VsZWN0LkdldFNpemUoKS0xOyBpPj0wOyBpLS0pCisJCQkJCQl7CisJCQkJCQkJc2EuUmVtb3ZlQXQoYVNlbGVjdFtpXSk7CisJCQkJCQl9CisJCQkJCX0KKworCQkJCQlhU2VsZWN0LlJlbW92ZUFsbCgpOworCQkJCX0KKwkJCX0KKwkJCXNhLlJlbW92ZUFsbCgpOworCQl9CisJCWJyZWFrOworCWNhc2UgQkFJX0NPTFVNTjoKKwkJeworCQkJQ1BERlNES19Tb3J0QW5ub3RzIHNhOworCisJCQl7CisJCQkJZm9yIChpbnQgaT0wLHN6PW1fcFBhZ2VWaWV3LT5Db3VudEFubm90cygpOyBpPHN6OyBpKyspCisJCQkJeworCQkJCQlDUERGU0RLX0Fubm90KiBwQW5ub3QgPSBtX3BQYWdlVmlldy0+R2V0QW5ub3QoaSk7CisJCQkJCUFTU0VSVChwQW5ub3QgIT0gTlVMTCk7CisKKwkJCQkJaWYgKHBBbm5vdC0+R2V0VHlwZSgpID09IG1fc1R5cGUgCisJCQkJCQkmJiBwQW5ub3QtPkdldFN1YlR5cGUoKSA9PSBtX3NTdWJUeXBlKQorCQkJCQkJc2EuQWRkKHBBbm5vdCk7CisJCQkJfQorCQkJfQorCisJCQlpZiAoc2EuR2V0U2l6ZSgpID4gMCkKKwkJCXsKKwkJCQlzYS5Tb3J0KENCQV9Bbm5vdEl0ZXJhdG9yOjpDb21wYXJlQnlUb3AsIEZBTFNFKTsKKwkJCX0KKworCQkJd2hpbGUgKHNhLkdldFNpemUoKSA+IDApCisJCQl7CisJCQkJaW50IG5MZWZ0VG9wSW5kZXggPSAtMTsKKworCQkJCXsKKwkJCQkJRlhfRkxPQVQgZkxlZnQgPSAtMS4wZjsKKworCQkJCQlmb3IgKGludCBpPXNhLkdldFNpemUoKS0xOyBpPj0wOyBpLS0pCisJCQkJCXsKKwkJCQkJCUNQREZTREtfQW5ub3QqIHBBbm5vdCA9IHNhLkdldEF0KGkpOworCQkJCQkJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKworCQkJCQkJQ1BERl9SZWN0IHJjQW5ub3QgPSBHZXRBbm5vdFJlY3QocEFubm90KTsKKworCQkJCQkJaWYgKGZMZWZ0IDwgMCkKKwkJCQkJCXsKKwkJCQkJCQluTGVmdFRvcEluZGV4ID0gMDsKKwkJCQkJCQlmTGVmdCA9IHJjQW5ub3QubGVmdDsKKwkJCQkJCX0KKwkJCQkJCWVsc2UgaWYgKHJjQW5ub3QubGVmdCA8IGZMZWZ0KQorCQkJCQkJeworCQkJCQkJCW5MZWZ0VG9wSW5kZXggPSBpOworCQkJCQkJCWZMZWZ0ID0gcmNBbm5vdC5sZWZ0OworCQkJCQkJfQorCQkJCQl9CisJCQkJfQorCisJCQkJaWYgKG5MZWZ0VG9wSW5kZXggPj0gMCkKKwkJCQl7CisJCQkJCUNQREZTREtfQW5ub3QqIHBMZWZ0VG9wQW5ub3QgPSBzYS5HZXRBdChuTGVmdFRvcEluZGV4KTsKKwkJCQkJQVNTRVJUKHBMZWZ0VG9wQW5ub3QgIT0gTlVMTCk7CisKKwkJCQkJQ1BERl9SZWN0IHJjTGVmdFRvcCA9IEdldEFubm90UmVjdChwTGVmdFRvcEFubm90KTsKKwkJCQkJCisJCQkJCW1fQW5ub3RzLkFkZChwTGVmdFRvcEFubm90KTsKKwkJCQkJc2EuUmVtb3ZlQXQobkxlZnRUb3BJbmRleCk7CisKKwkJCQkJQ0ZYX0FycmF5VGVtcGxhdGU8aW50PiBhU2VsZWN0OworCisJCQkJCXsKKwkJCQkJCWZvciAoaW50IGk9MCxzej1zYS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJCQkJCXsKKwkJCQkJCQlDUERGU0RLX0Fubm90KiBwQW5ub3QgPSBzYS5HZXRBdChpKTsKKwkJCQkJCQlBU1NFUlQocEFubm90ICE9IE5VTEwpOworCisJCQkJCQkJQ1BERl9SZWN0IHJjQW5ub3QgPSBHZXRBbm5vdFJlY3QocEFubm90KTsKKworCQkJCQkJCUZYX0ZMT0FUIGZDZW50ZXJYID0gKHJjQW5ub3QubGVmdCArIHJjQW5ub3QucmlnaHQpIC8gMi4wZjsKKworCQkJCQkJCWlmIChmQ2VudGVyWCA+IHJjTGVmdFRvcC5sZWZ0ICYmIGZDZW50ZXJYIDwgcmNMZWZ0VG9wLnJpZ2h0KQorCQkJCQkJCQlhU2VsZWN0LkFkZChpKTsKKwkJCQkJCX0KKwkJCQkJfQorCisJCQkJCXsKKwkJCQkJCWZvciAoaW50IGk9MCxzej1hU2VsZWN0LkdldFNpemUoKTsgaTxzejsgaSsrKQorCQkJCQkJeworCQkJCQkJCW1fQW5ub3RzLkFkZChzYVthU2VsZWN0W2ldXSk7CisJCQkJCQl9CisJCQkJCX0KKworCQkJCQl7CisJCQkJCQlmb3IgKGludCBpPWFTZWxlY3QuR2V0U2l6ZSgpLTE7IGk+PTA7IGktLSkKKwkJCQkJCXsKKwkJCQkJCQlzYS5SZW1vdmVBdChhU2VsZWN0W2ldKTsKKwkJCQkJCX0KKwkJCQkJfQorCisJCQkJCWFTZWxlY3QuUmVtb3ZlQWxsKCk7CisJCQkJfQorCQkJfQorCQkJc2EuUmVtb3ZlQWxsKCk7CisJCX0KKwkJYnJlYWs7CisJfQorfQorCitDUERGX1JlY3QgQ0JBX0Fubm90SXRlcmF0b3I6OkdldEFubm90UmVjdChDUERGU0RLX0Fubm90KiBwQW5ub3QpCit7CisJQVNTRVJUKHBBbm5vdCAhPSBOVUxMKTsKKworCUNQREZfQW5ub3QqIHBQREZBbm5vdCA9IHBBbm5vdC0+R2V0UERGQW5ub3QoKTsKKwlBU1NFUlQocFBERkFubm90ICE9IE5VTEwpOworCisJQ1BERl9SZWN0IHJjQW5ub3Q7CisJcFBERkFubm90LT5HZXRSZWN0KHJjQW5ub3QpOworCisJcmV0dXJuIHJjQW5ub3Q7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2ZzZGtfbWdyLmNwcCBiL2ZwZGZzZGsvc3JjL2ZzZGtfbWdyLmNwcAppbmRleCA5YTExOTI3Li45MDUyYzM3IDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9mc2RrX21nci5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnNka19tZ3IuY3BwCkBAIC0xLDEwNTUgKzEsMTA1NSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vaW5jbHVkZS9mc2RrX21nci5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2ZwZGZfZXh0LmgiDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIg0KLSNpbmNsdWRlICIuLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCINCi0NCi0jaWYgX0ZYX09TXyA9PSBfRlhfQU5EUk9JRF8NCi0jaW5jbHVkZSAidGltZS5oIg0KLSNlbHNlDQotI2luY2x1ZGUgPGN0aW1lPg0KLSNlbmRpZg0KLQ0KLS8vZXh0ZXJuIENQREZEb2NfRW52aXJvbm1lbnQqIGdfcEZvcm1GaWxsQXBwOw0KLWNsYXNzIENGWF9TeXN0ZW1IYW5kbGVyOnB1YmxpYyBJRlhfU3lzdGVtSGFuZGxlcg0KLXsNCi1wdWJsaWM6DQotCUNGWF9TeXN0ZW1IYW5kbGVyKENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYpOm1fcEVudihwRW52KSxtX25DaGFyU2V0KC0xKSB7fQ0KLXB1YmxpYzoNCi0JdmlydHVhbCB2b2lkCQkJCUludmFsaWRhdGVSZWN0KEZYX0hXTkQgaFduZCwgRlhfUkVDVCByZWN0KSA7DQotCXZpcnR1YWwgdm9pZAkJCQlPdXRwdXRTZWxlY3RlZFJlY3Qodm9pZCogcEZvcm1GaWxsZXIsIENQREZfUmVjdCYgcmVjdCk7DQotDQotCXZpcnR1YWwgRlhfQk9PTAkJCQlJc1NlbGVjdGlvbkltcGxlbWVudGVkKCk7DQotDQotCXZpcnR1YWwgQ0ZYX1dpZGVTdHJpbmcJCUdldENsaXBib2FyZFRleHQoRlhfSFdORCBoV25kKXtyZXR1cm4gTCIiO30NCi0JdmlydHVhbCBGWF9CT09MCQkJCVNldENsaXBib2FyZFRleHQoRlhfSFdORCBoV25kLCBDRlhfV2lkZVN0cmluZyBzdHJpbmcpIHtyZXR1cm4gRkFMU0U7fQ0KLQkNCi0JdmlydHVhbCB2b2lkCQkJCUNsaWVudFRvU2NyZWVuKEZYX0hXTkQgaFduZCwgRlhfSU5UMzImIHgsIEZYX0lOVDMyJiB5KSB7fQ0KLQl2aXJ0dWFsIHZvaWQJCQkJU2NyZWVuVG9DbGllbnQoRlhfSFdORCBoV25kLCBGWF9JTlQzMiYgeCwgRlhfSU5UMzImIHkpIHt9DQotDQotCS8qY3Vyc29yIHN0eWxlDQotCUZYQ1RfQVJST1cJDQotCUZYQ1RfTkVTVwkJDQotCUZYQ1RfTldTRQkJDQotCUZYQ1RfVkJFQU0JCQ0KLQlGWENUX0hCRUFNCQkNCi0JRlhDVF9IQU5EDQotCSovDQotCXZpcnR1YWwgdm9pZAkJCQlTZXRDdXJzb3IoRlhfSU5UMzIgbkN1cnNvclR5cGUpOw0KLQ0KLQl2aXJ0dWFsIEZYX0hNRU5VCQkJQ3JlYXRlUG9wdXBNZW51KCkge3JldHVybiBOVUxMO30NCi0JdmlydHVhbCBGWF9CT09MCQkJCUFwcGVuZE1lbnVJdGVtKEZYX0hNRU5VIGhNZW51LCBGWF9JTlQzMiBuSUROZXdJdGVtLCBDRlhfV2lkZVN0cmluZyBzdHJpbmcpIHtyZXR1cm4gRkFMU0U7fQ0KLQl2aXJ0dWFsIEZYX0JPT0wJCQkJRW5hYmxlTWVudUl0ZW0oRlhfSE1FTlUgaE1lbnUsIEZYX0lOVDMyIG5JREl0ZW0sIEZYX0JPT0wgYkVuYWJsZWQpIHtyZXR1cm4gRkFMU0U7fQ0KLQl2aXJ0dWFsIEZYX0lOVDMyCQkJVHJhY2tQb3B1cE1lbnUoRlhfSE1FTlUgaE1lbnUsIEZYX0lOVDMyIHgsIEZYX0lOVDMyIHksIEZYX0hXTkQgaFBhcmVudCkge3JldHVybiAtMTt9DQotCXZpcnR1YWwgdm9pZAkJCQlEZXN0cm95TWVudShGWF9ITUVOVSBoTWVudSkge30NCi0NCi0JdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0TmF0aXZlVHJ1ZVR5cGVGb250KEZYX0lOVDMyIG5DaGFyc2V0KTsNCi0JdmlydHVhbCBGWF9CT09MCQkJCUZpbmROYXRpdmVUcnVlVHlwZUZvbnQoRlhfSU5UMzIgbkNoYXJzZXQsIENGWF9CeXRlU3RyaW5nIHNGb250RmFjZU5hbWUpOw0KLQl2aXJ0dWFsIENQREZfRm9udCoJCQlBZGROYXRpdmVUcnVlVHlwZUZvbnRUb1BERihDUERGX0RvY3VtZW50KiBwRG9jLCBDRlhfQnl0ZVN0cmluZyBzRm9udEZhY2VOYW1lLCBGWF9CWVRFIG5DaGFyc2V0KTsNCi0NCi0JdmlydHVhbCBGWF9JTlQzMgkJCVNldFRpbWVyKEZYX0lOVDMyIHVFbGFwc2UsIFRpbWVyQ2FsbGJhY2sgbHBUaW1lckZ1bmMpIDsNCi0JdmlydHVhbCB2b2lkCQkJCUtpbGxUaW1lcihGWF9JTlQzMiBuSUQpIDsNCi0NCi0NCi0JdmlydHVhbCBGWF9CT09MCQkJCUlzU0hJRlRLZXlEb3duKEZYX0RXT1JEIG5GbGFnKSB7cmV0dXJuIG1fcEVudi0+RkZJX0lzU0hJRlRLZXlEb3duKG5GbGFnKTt9DQotCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0NUUkxLZXlEb3duKEZYX0RXT1JEIG5GbGFnKSB7cmV0dXJuIG1fcEVudi0+RkZJX0lzQ1RSTEtleURvd24obkZsYWcpO30NCi0JdmlydHVhbCBGWF9CT09MCQkJCUlzQUxUS2V5RG93bihGWF9EV09SRCBuRmxhZykge3JldHVybiBtX3BFbnYtPkZGSV9Jc0FMVEtleURvd24obkZsYWcpO30NCi0JdmlydHVhbCBGWF9CT09MCQkJCUlzSU5TRVJUS2V5RG93bihGWF9EV09SRCBuRmxhZykge3JldHVybiBtX3BFbnYtPkZGSV9Jc0lOU0VSVEtleURvd24obkZsYWcpO30NCi0NCi0JdmlydHVhbAlGWF9TWVNURU1USU1FCQlHZXRMb2NhbFRpbWUoKTsNCi0NCi0JdmlydHVhbCBGWF9JTlQzMgkJCUdldENoYXJTZXQoKSB7cmV0dXJuIG1fbkNoYXJTZXQ7fQ0KLQl2aXJ0dWFsIHZvaWQgCQkJCVNldENoYXJTZXQoRlhfSU5UMzIgbkNoYXJTZXQpIHttX25DaGFyU2V0ID0gbkNoYXJTZXQ7fQ0KLXByaXZhdGU6DQotCUNQREZEb2NfRW52aXJvbm1lbnQqIG1fcEVudjsNCi0JaW50CQltX25DaGFyU2V0Ow0KLX07DQotDQotdm9pZCBDRlhfU3lzdGVtSGFuZGxlcjo6U2V0Q3Vyc29yKEZYX0lOVDMyIG5DdXJzb3JUeXBlKQ0KLXsNCi0NCi0JbV9wRW52LT5GRklfU2V0Q3Vyc29yKG5DdXJzb3JUeXBlKTsNCi19DQotDQotdm9pZCBDRlhfU3lzdGVtSGFuZGxlcjo6SW52YWxpZGF0ZVJlY3QoRlhfSFdORCBoV25kLCBGWF9SRUNUIHJlY3QpDQotew0KLQkvL2dfcEZvcm1GaWxsQXBwLT5GRklfSW52YWxpZGF0ZSgpOw0KLQlDUERGU0RLX0Fubm90KiBwU0RLQW5ub3QgPSAoQ1BERlNES19Bbm5vdCopaFduZDsNCi0JQ1BERl9QYWdlKiBwUGFnZSA9IE5VTEw7DQotCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IE5VTEw7DQotCXBQYWdlVmlldyA9IHBTREtBbm5vdC0+R2V0UGFnZVZpZXcoKTsNCi0JcFBhZ2UgPSBwU0RLQW5ub3QtPkdldFBERlBhZ2UoKTsNCi0JaWYoIXBQYWdlIHx8ICFwUGFnZVZpZXcpDQotCQlyZXR1cm47DQotCUNQREZfTWF0cml4IHBhZ2UyZGV2aWNlOw0KLQlwUGFnZVZpZXctPkdldEN1cnJlbnRNYXRyaXgocGFnZTJkZXZpY2UpOw0KLQlDUERGX01hdHJpeCBkZXZpY2UycGFnZTsNCi0JZGV2aWNlMnBhZ2UuU2V0UmV2ZXJzZShwYWdlMmRldmljZSk7DQotCUZYX0ZMT0FUIGxlZnQsIHRvcCwgcmlnaHQsYm90dG9tOw0KLQlkZXZpY2UycGFnZS5UcmFuc2Zvcm0oKEZYX0ZMT0FUKXJlY3QubGVmdCwgKEZYX0ZMT0FUKXJlY3QudG9wLCBsZWZ0LCB0b3ApOw0KLQlkZXZpY2UycGFnZS5UcmFuc2Zvcm0oKEZYX0ZMT0FUKXJlY3QucmlnaHQsIChGWF9GTE9BVClyZWN0LmJvdHRvbSwgcmlnaHQsIGJvdHRvbSk7DQotLy8gCW1fcEVudi0+RkZJX0RldmljZVRvUGFnZShwUGFnZSwgcmVjdC5sZWZ0LCByZWN0LnRvcCwgKGRvdWJsZSopJmxlZnQsIChkb3VibGUqKSZ0b3ApOw0KLS8vIAltX3BFbnYtPkZGSV9EZXZpY2VUb1BhZ2UocFBhZ2UsIHJlY3QucmlnaHQsIHJlY3QuYm90dG9tLCAoZG91YmxlKikmcmlnaHQsIChkb3VibGUqKSZib3R0b20pOw0KLQlDUERGX1JlY3QgcmNQREYobGVmdCwgYm90dG9tLCByaWdodCwgdG9wKTsNCi0JcmNQREYuTm9ybWFsaXplKCk7DQotDQotCW1fcEVudi0+RkZJX0ludmFsaWRhdGUocFBhZ2UsIHJjUERGLmxlZnQsIHJjUERGLnRvcCwgcmNQREYucmlnaHQsIHJjUERGLmJvdHRvbSk7DQotfQ0KLXZvaWQgQ0ZYX1N5c3RlbUhhbmRsZXI6Ok91dHB1dFNlbGVjdGVkUmVjdCh2b2lkKiBwRm9ybUZpbGxlciwgQ1BERl9SZWN0JiByZWN0KQ0KLXsNCi0JQ0ZGTF9Gb3JtRmlsbGVyKiBwRkZMID0gKENGRkxfRm9ybUZpbGxlciopcEZvcm1GaWxsZXI7DQotCWlmKHBGRkwpDQotCXsNCi0JCUNQREZfUG9pbnQgbGVmdGJvdHRvbSA9IENQREZfUG9pbnQocmVjdC5sZWZ0LCByZWN0LmJvdHRvbSk7DQotCQlDUERGX1BvaW50IHJpZ2h0dG9wID0gQ1BERl9Qb2ludChyZWN0LnJpZ2h0LCByZWN0LnRvcCk7DQotCQlDUERGX1BvaW50IHB0QSA9IHBGRkwtPlBXTHRvRkZMKGxlZnRib3R0b20pOw0KLQkJQ1BERl9Qb2ludCBwdEIgPSBwRkZMLT5QV0x0b0ZGTChyaWdodHRvcCk7CQ0KLQ0KLQ0KLQkJQ1BERlNES19Bbm5vdCogcEFubm90ICA9IHBGRkwtPkdldFNES0Fubm90KCk7DQotCQlBU1NFUlQocEFubm90KTsNCi0JCUNQREZfUGFnZSogcFBhZ2UgPSBwQW5ub3QtPkdldFBERlBhZ2UoKTsNCi0JCUFTU0VSVChwUGFnZSk7DQotCQltX3BFbnYtPkZGSV9PdXRwdXRTZWxlY3RlZFJlY3QocFBhZ2UsIHB0QS54LCBwdEIueSwgcHRCLngsIHB0QS55KTsNCi0JfQ0KLQkNCi19DQotDQotRlhfQk9PTCBDRlhfU3lzdGVtSGFuZGxlcjo6SXNTZWxlY3Rpb25JbXBsZW1lbnRlZCgpDQotew0KLQlpZihtX3BFbnYpDQotCXsNCi0JCUZQREZfRk9STUZJTExJTkZPKiBwSW5mbyA9IG1fcEVudi0+R2V0Rm9ybUZpbGxJbmZvKCk7DQotCQlpZihwSW5mbyAmJiBwSW5mby0+RkZJX091dHB1dFNlbGVjdGVkUmVjdCkNCi0JCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENGWF9TeXN0ZW1IYW5kbGVyOjpHZXROYXRpdmVUcnVlVHlwZUZvbnQoRlhfSU5UMzIgbkNoYXJzZXQpDQotew0KLQlyZXR1cm4gIiI7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX1N5c3RlbUhhbmRsZXI6OkZpbmROYXRpdmVUcnVlVHlwZUZvbnQoRlhfSU5UMzIgbkNoYXJzZXQsIENGWF9CeXRlU3RyaW5nIHNGb250RmFjZU5hbWUpIA0KLXsNCi0JQ0ZYX0ZvbnRNZ3IqIHBGb250TWdyID0gQ0ZYX0dFTW9kdWxlOjpHZXQoKS0+R2V0Rm9udE1ncigpOw0KLS8vCUZYRlRfRmFjZSBuRmFjZSA9IHBGb250TWdyLT5GaW5kU3Vic3RGb250KHNGb250RmFjZU5hbWUsVFJVRSwwLDAsMCwwLE5VTEwpOw0KLS8vCUZYRlRfRmFjZSBuRmFjZSAgPSBwRm9udE1nci0+bV9wQnVpbHRpbk1hcHBlci0+RmluZFN1YnN0Rm9udChzRm9udEZhY2VOYW1lLFRSVUUsMCwwLDAsMCxOVUxMKTsNCi0NCi0JaWYocEZvbnRNZ3IpDQotCXsNCi0JCUNGWF9Gb250TWFwcGVyKglwRm9udE1hcHBlciA9IHBGb250TWdyLT5tX3BCdWlsdGluTWFwcGVyOw0KLQkJaWYocEZvbnRNYXBwZXIpDQotCQl7CQ0KLQkJCWludCBuU2l6ZSA9IHBGb250TWFwcGVyLT5tX0luc3RhbGxlZFRURm9udHMuR2V0U2l6ZSgpOw0KLQkJCWlmKG5TaXplID09MCkNCi0JCQl7DQotCQkJCXBGb250TWFwcGVyLT5Mb2FkSW5zdGFsbGVkRm9udHMoKTsNCi0JCQkJblNpemUgPSBwRm9udE1hcHBlci0+bV9JbnN0YWxsZWRUVEZvbnRzLkdldFNpemUoKTsNCi0JCQl9DQotCQkJDQotCQkJZm9yKGludCBpPTA7IGk8blNpemU7IGkrKykNCi0JCQl7DQotCQkJCWlmKHBGb250TWFwcGVyLT5tX0luc3RhbGxlZFRURm9udHNbaV0uQ29tcGFyZShzRm9udEZhY2VOYW1lKSkNCi0JCQkJCXJldHVybiBUUlVFOw0KLQkJCX0NCi0JCX0NCi0NCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotLy8gCXBGb250TWdyLT5tX0ZhY2VNYXAuTG9va3VwKHNGb250RmFjZU5hbWUscEZvbnQpOw0KLS8vIAlyZXR1cm4gKHBGb250IT1OVUxMKTsNCi19DQotDQotc3RhdGljIGludCBDaGFyU2V0MkNQKGludCBjaGFyc2V0KQ0KLXsNCi0JaWYoY2hhcnNldCA9PSAxMjgpDQotCQlyZXR1cm4gOTMyOw0KLQllbHNlIGlmKGNoYXJzZXQgPT0gMTM0KQ0KLQkJcmV0dXJuIDkzNjsNCi0JZWxzZSBpZihjaGFyc2V0ID09IDEyOSkNCi0JCXJldHVybiA5NDk7DQotCWVsc2UgaWYoY2hhcnNldCA9PSAxMzYpDQotCQlyZXR1cm4gOTUwOw0KLQlyZXR1cm4gMDsNCi19DQotQ1BERl9Gb250KiBDRlhfU3lzdGVtSGFuZGxlcjo6QWRkTmF0aXZlVHJ1ZVR5cGVGb250VG9QREYoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcgc0ZvbnRGYWNlTmFtZSwgDQotCQkJCQkJCQkJCQkJCQkgRlhfQllURSBuQ2hhcnNldCkgDQotew0KLQlpZihwRG9jKQ0KLQl7DQotCQlDRlhfRm9udCogcEZYRm9udCA9IG5ldyBDRlhfRm9udCgpOw0KLQkJcEZYRm9udC0+TG9hZFN1YnN0KHNGb250RmFjZU5hbWUsVFJVRSwwLDAsMCxDaGFyU2V0MkNQKG5DaGFyc2V0KSxGQUxTRSk7DQotCQlDUERGX0ZvbnQqIHBGb250ID0gcERvYy0+QWRkRm9udChwRlhGb250LG5DaGFyc2V0LEZBTFNFKTsNCi0JCWRlbGV0ZSBwRlhGb250Ow0KLQkJcmV0dXJuIHBGb250Ow0KLQl9DQotDQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi0NCi1GWF9JTlQzMiBDRlhfU3lzdGVtSGFuZGxlcjo6U2V0VGltZXIoRlhfSU5UMzIgdUVsYXBzZSwgVGltZXJDYWxsYmFjayBscFRpbWVyRnVuYykNCi17DQotCXJldHVybiBtX3BFbnYtPkZGSV9TZXRUaW1lcih1RWxhcHNlLCBscFRpbWVyRnVuYyk7DQotfQ0KLXZvaWQgQ0ZYX1N5c3RlbUhhbmRsZXI6OktpbGxUaW1lcihGWF9JTlQzMiBuSUQpDQotew0KLQltX3BFbnYtPkZGSV9LaWxsVGltZXIobklEKTsNCi19DQotDQotRlhfU1lTVEVNVElNRSBDRlhfU3lzdGVtSGFuZGxlcjo6R2V0TG9jYWxUaW1lKCkNCi17DQotCXJldHVybiBtX3BFbnYtPkZGSV9HZXRMb2NhbFRpbWUoKTsNCi19DQotDQotDQotQ0pTX1J1bnRpbWVGYWN0b3J5KiBHZXRKU1J1bnRpbWVGYWN0b3J5KCkNCi17DQotCXN0YXRpYyBDSlNfUnVudGltZUZhY3Rvcnkgc19KU1J1bnRpbWVGYWN0b3J5Ow0KLQlyZXR1cm4gJnNfSlNSdW50aW1lRmFjdG9yeTsNCi19DQotDQotQ1BERkRvY19FbnZpcm9ubWVudDo6Q1BERkRvY19FbnZpcm9ubWVudChDUERGX0RvY3VtZW50ICogcERvYyk6bV9wSW5mbyhOVUxMKSxtX3BJRm9ybUZpbGxlcihOVUxMKSwNCi0JCQkJCQkJCW1fcEFubm90SGFuZGxlck1ncihOVUxMKSxtX3BBY3Rpb25IYW5kbGVyKE5VTEwpLG1fcEpTUnVudGltZShOVUxMKSwNCi0JCQkJCQkJCW1fcFNES0RvYyhOVUxMKSwgbV9wUERGRG9jKHBEb2MpDQotew0KLQ0KLQltX3BTeXNIYW5kbGVyID0gTlVMTDsNCi0JbV9wU3lzSGFuZGxlciA9IG5ldyBDRlhfU3lzdGVtSGFuZGxlcih0aGlzKTsNCi0NCi0JDQotCW1fcEpTUnVudGltZUZhY3RvcnkgPSBOVUxMOw0KLQltX3BKU1J1bnRpbWVGYWN0b3J5ID0gR2V0SlNSdW50aW1lRmFjdG9yeSgpOw0KLQltX3BKU1J1bnRpbWVGYWN0b3J5LT5BZGRSZWYoKTsNCi19DQotDQotQ1BERkRvY19FbnZpcm9ubWVudDo6fkNQREZEb2NfRW52aXJvbm1lbnQoKQ0KLXsNCi0NCi0JaWYgKCBtX3BJRm9ybUZpbGxlciApDQotCXsNCi0JCWRlbGV0ZSBtX3BJRm9ybUZpbGxlcjsNCi0JCW1fcElGb3JtRmlsbGVyID0gTlVMTDsNCi0JfQ0KLQlpZihtX3BKU1J1bnRpbWUgJiYgbV9wSlNSdW50aW1lRmFjdG9yeSkNCi0JCW1fcEpTUnVudGltZUZhY3RvcnktPkRlbGV0ZUpTUnVudGltZShtX3BKU1J1bnRpbWUpOw0KLQltX3BKU1J1bnRpbWVGYWN0b3J5LT5SZWxlYXNlKCk7DQotDQotCWlmKG1fcFN5c0hhbmRsZXIpDQotCXsNCi0JCWRlbGV0ZSBtX3BTeXNIYW5kbGVyOw0KLQkJbV9wU3lzSGFuZGxlciA9IE5VTEw7DQotCX0NCi0NCi0JaWYobV9wQW5ub3RIYW5kbGVyTWdyKQ0KLQl7DQotCQlkZWxldGUgbV9wQW5ub3RIYW5kbGVyTWdyOw0KLQkJbV9wQW5ub3RIYW5kbGVyTWdyID0gTlVMTDsNCi0JfQ0KLQlpZihtX3BBY3Rpb25IYW5kbGVyKQ0KLQl7DQotCQlkZWxldGUgbV9wQWN0aW9uSGFuZGxlcjsNCi0JCW1fcEFjdGlvbkhhbmRsZXIgPSBOVUxMOw0KLQl9DQotDQotDQotfQ0KLQ0KLQ0KLUlGWEpTX1J1bnRpbWUqIENQREZEb2NfRW52aXJvbm1lbnQ6OkdldEpTUnVudGltZSgpDQotew0KLQlpZighSXNKU0luaXRpYXRlZCgpKQ0KLQkJcmV0dXJuIE5VTEw7DQotCWFzc2VydChtX3BKU1J1bnRpbWVGYWN0b3J5KTsNCi0JaWYoIW1fcEpTUnVudGltZSkNCi0JCW1fcEpTUnVudGltZSA9IG1fcEpTUnVudGltZUZhY3RvcnktPk5ld0pTUnVudGltZSh0aGlzKTsNCi0JcmV0dXJuIG1fcEpTUnVudGltZTsNCi19DQotDQotQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIENQREZEb2NfRW52aXJvbm1lbnQ6OkdldEFubm90SGFuZGxlck1ncigpDQotew0KLQlpZighbV9wQW5ub3RIYW5kbGVyTWdyKQ0KLQkJbV9wQW5ub3RIYW5kbGVyTWdyID0gbmV3IENQREZTREtfQW5ub3RIYW5kbGVyTWdyKHRoaXMpOw0KLQlyZXR1cm4gbV9wQW5ub3RIYW5kbGVyTWdyOw0KLX0NCi0NCi1DUERGU0RLX0FjdGlvbkhhbmRsZXIqIENQREZEb2NfRW52aXJvbm1lbnQ6OkdldEFjdGlvbkhhbmRlcigpDQotew0KLQlpZighbV9wQWN0aW9uSGFuZGxlcikNCi0JCW1fcEFjdGlvbkhhbmRsZXIgPSBuZXcgQ1BERlNES19BY3Rpb25IYW5kbGVyKHRoaXMpOw0KLQlyZXR1cm4gbV9wQWN0aW9uSGFuZGxlcjsNCi19DQotDQotaW50IENQREZEb2NfRW52aXJvbm1lbnQ6OlJlZ0FwcEhhbmRsZShGUERGX0ZPUk1GSUxMSU5GTyogcEZGaW5mbykNCi17DQotCW1fcEluZm8gID0gcEZGaW5mbzsgDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1DUERGU0RLX0RvY3VtZW50KiBDUERGRG9jX0Vudmlyb25tZW50OjpHZXRDdXJyZW50RG9jKCkNCi17DQotCXJldHVybiBtX3BTREtEb2M7DQotfQ0KLQ0KLUNGRkxfSUZvcm1GaWxsZXIqIENQREZEb2NfRW52aXJvbm1lbnQ6OkdldElGb3JtRmlsbGVyKCkNCi17DQotCWlmKCFtX3BJRm9ybUZpbGxlcikNCi0JCW1fcElGb3JtRmlsbGVyID0gbmV3IENGRkxfSUZvcm1GaWxsZXIodGhpcyk7DQotCXJldHVybiBtX3BJRm9ybUZpbGxlcjsNCi19DQotDQotRlhfQk9PTAlDUERGRG9jX0Vudmlyb25tZW50OjpJc0pTSW5pdGlhdGVkKCkNCi17DQotCWlmKG1fcEluZm8pDQotCXsNCi0JCWlmKG1fcEluZm8tPm1fcEpzUGxhdGZvcm0pDQotCQkJcmV0dXJuIFRSVUU7DQotCQllbHNlDQotCQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotQ1BERlNES19Eb2N1bWVudDo6Q1BERlNES19Eb2N1bWVudChDUERGX0RvY3VtZW50KiBwRG9jLENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYpOm1fcERvYyhwRG9jKSwNCi0JCQkJCQltX3BJbnRlckZvcm0oTlVMTCksbV9wRW52KHBFbnYpLG1fcE9jY29udGVudChOVUxMKSxtX2JDaGFuZ2VNYXNrKEZBTFNFKQ0KLXsNCi0JbV9wRm9jdXNBbm5vdCA9IE5VTEw7DQotfQ0KLQ0KLUNQREZTREtfRG9jdW1lbnQ6On5DUERGU0RLX0RvY3VtZW50KCkNCi17DQotCW1fcGFnZU1hcC5SZW1vdmVBbGwoKTsNCi0JaWYobV9wSW50ZXJGb3JtKQ0KLQl7DQotCQltX3BJbnRlckZvcm0tPkRlc3Ryb3koKTsNCi0JCW1fcEludGVyRm9ybSA9IE5VTEw7DQotCX0NCi0JaWYobV9wT2Njb250ZW50KQ0KLQl7DQotCQlkZWxldGUgbV9wT2Njb250ZW50Ow0KLQkJbV9wT2Njb250ZW50ID0gTlVMTDsNCi0JfQ0KLX0NCi0NCi12b2lkIENQREZTREtfRG9jdW1lbnQ6OkluaXRQYWdlVmlldygpDQotew0KLQlpbnQgbkNvdW50ID0gbV9wRG9jLT5HZXRQYWdlQ291bnQoKTsNCi0JZm9yKGludCBpPTA7IGk8bkNvdW50OyBpKyspDQotCXsNCi0JLy8gVG8gZG8NCi0vLwkJQ1BERl9EaWN0aW9uYXJ5KiBwRGljID0gbV9wRG9jLT5HZXRQYWdlKGkpOw0KLS8vCQltX3BhZ2VNYXAuU2V0QXQocERpYywgcFBhZ2VWaWV3KTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQREZTREtfRG9jdW1lbnQ6OkFkZFBhZ2VWaWV3KENQREZfUGFnZSogcFBERlBhZ2UsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldykNCi17DQotCW1fcGFnZU1hcC5TZXRBdChwUERGUGFnZSwgcFBhZ2VWaWV3KTsNCi19DQotDQotQ1BERlNES19QYWdlVmlldyogQ1BERlNES19Eb2N1bWVudDo6R2V0UGFnZVZpZXcoQ1BERl9QYWdlKiBwUERGUGFnZSwgRlhfQk9PTCBSZU5ldykNCi17DQotCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IChDUERGU0RLX1BhZ2VWaWV3KiltX3BhZ2VNYXAuR2V0VmFsdWVBdChwUERGUGFnZSk7DQotCWlmKHBQYWdlVmlldyAhPSBOVUxMKQ0KLQkJcmV0dXJuIHBQYWdlVmlldzsNCi0JaWYoUmVOZXcpDQotCXsNCi0JCXBQYWdlVmlldyA9IG5ldyBDUERGU0RLX1BhZ2VWaWV3KHRoaXMscFBERlBhZ2UpOw0KLQkJbV9wYWdlTWFwLlNldEF0KHBQREZQYWdlLCBwUGFnZVZpZXcpOw0KLQkJLy9EZWxheSB0byBsb2FkIGFsbCB0aGUgYW5ub3RhdGlvbnMsIHRvIGF2b2lkIGVuZGxlc3MgbG9vcC4NCi0JCXBQYWdlVmlldy0+TG9hZEZYQW5ub3RzKCk7DQotCX0NCi0JcmV0dXJuIHBQYWdlVmlldzsNCi0NCi19DQotDQotQ1BERlNES19QYWdlVmlldyogQ1BERlNES19Eb2N1bWVudDo6R2V0Q3VycmVudFZpZXcoKQ0KLXsNCi0JQ1BERl9QYWdlICogcFBhZ2UgPSAoQ1BERl9QYWdlICopbV9wRW52LT5GRklfR2V0Q3VycmVudFBhZ2UobV9wRG9jKTsNCi0JaWYocFBhZ2UpDQotCQlyZXR1cm4gdGhpcy0+R2V0UGFnZVZpZXcocFBhZ2UsIFRSVUUpOw0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotQ1BERlNES19QYWdlVmlldyogQ1BERlNES19Eb2N1bWVudDo6R2V0UGFnZVZpZXcoaW50IG5JbmRleCkNCi17DQotCUNQREZTREtfUGFnZVZpZXcgKiBwVGVtcFBhZ2VWaWV3ID0gTlVMTDsNCi0JQ1BERl9QYWdlICogcFRlbXBQYWdlID0gKENQREZfUGFnZSopbV9wRW52LT5GRklfR2V0UGFnZShtX3BEb2MsbkluZGV4KTsNCi0JaWYoIXBUZW1wUGFnZSkNCi0JCXJldHVybiBOVUxMOw0KLQ0KLQltX3BhZ2VNYXAuTG9va3VwKHBUZW1wUGFnZSwgcFRlbXBQYWdlVmlldyk7DQotCQ0KLQlBU1NFUlQocFRlbXBQYWdlVmlldyAhPSBOVUxMKTsNCi0JDQotCXJldHVybiBwVGVtcFBhZ2VWaWV3Ow0KLX0NCi0NCi12b2lkIENQREZTREtfRG9jdW1lbnQ6OiBQcm9jSmF2YXNjcmlwdEZ1bigpDQotew0KLQlDUERGX0RvY3VtZW50KiBwUERGRG9jID0gdGhpcy0+R2V0RG9jdW1lbnQoKTsNCi0JQ1BERl9Eb2NKU0FjdGlvbnMgZG9jSlMocFBERkRvYyk7DQotCWludCBpQ291bnQgPSBkb2NKUy5Db3VudEpTQWN0aW9ucygpOw0KLQlpZiAoaUNvdW50IDwgMSkgcmV0dXJuOw0KLQlmb3IgKGludCBpID0gMDsgaSA8IGlDb3VudDsgaSArKykNCi0Jew0KLQkJQ0ZYX0J5dGVTdHJpbmcgY3NKU05hbWU7DQotCQlDUERGX0FjdGlvbiBqc0FjdGlvbiA9IGRvY0pTLkdldEpTQWN0aW9uKGksIGNzSlNOYW1lKTsNCi0JCWlmKG1fcEVudi0+R2V0QWN0aW9uSGFuZGVyKCkpDQotCQkJbV9wRW52LT5HZXRBY3Rpb25IYW5kZXIoKS0+RG9BY3Rpb25fSmF2YVNjcmlwdChqc0FjdGlvbixDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNzSlNOYW1lKSx0aGlzKTsNCi0JfQ0KLQkNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0RvY3VtZW50OjpQcm9jT3BlbkFjdGlvbigpDQotew0KLQlpZighbV9wRG9jKSByZXR1cm4gRkFMU0U7DQotCQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBSb290ID0gbV9wRG9jLT5HZXRSb290KCk7CQ0KLQlpZiAoIXBSb290KQlyZXR1cm4gRkFMU0U7DQotCUNQREZfT2JqZWN0KiBwT3BlbkFjdGlvbiA9IHBSb290LT5HZXREaWN0KCJPcGVuQWN0aW9uIik7Ly8NCi0JaWYoIXBPcGVuQWN0aW9uKSBwT3BlbkFjdGlvbiA9IHBSb290LT5HZXRBcnJheSgiT3BlbkFjdGlvbiIpOy8vDQotCWlmKCFwT3BlbkFjdGlvbikgcmV0dXJuIEZBTFNFOw0KLQkNCi0JaWYocE9wZW5BY3Rpb24tPkdldFR5cGUoKT09UERGT0JKX0FSUkFZKQ0KLQl7CQ0KLQl9DQotCWVsc2UgaWYocE9wZW5BY3Rpb24tPkdldFR5cGUoKT09UERGT0JKX0RJQ1RJT05BUlkpDQotCXsJDQotCQlDUERGX0RpY3Rpb25hcnkgKiBwRGljdD0oQ1BERl9EaWN0aW9uYXJ5KilwT3BlbkFjdGlvbjsJDQotCQlDUERGX0FjdGlvbiBBY3Rpb24gPSBwRGljdDsNCi0JCQ0KLQkJaWYobV9wRW52LT5HZXRBY3Rpb25IYW5kZXIoKSkNCi0JCQltX3BFbnYtPkdldEFjdGlvbkhhbmRlcigpLT5Eb0FjdGlvbl9Eb2NPcGVuKEFjdGlvbix0aGlzKTsJCQ0KLQl9CQ0KLQllbHNlDQotCXsNCi0JCXJldHVybiBGQUxTRTsJCQkNCi0JfQkNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUNQREZfT0NDb250ZXh0KglDUERGU0RLX0RvY3VtZW50OjpHZXRPQ0NvbnRleHQoKQ0KLXsNCi0JaWYoIW1fcE9jY29udGVudCkNCi0JCW1fcE9jY29udGVudCA9IG5ldyBDUERGX09DQ29udGV4dChtX3BEb2MpOw0KLQlyZXR1cm4gbV9wT2Njb250ZW50Ow0KLX0NCi0NCi12b2lkIENQREZTREtfRG9jdW1lbnQ6OlJlTW92ZVBhZ2VWaWV3KENQREZfUGFnZSogcFBERlBhZ2UpDQotew0KLQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSAoQ1BERlNES19QYWdlVmlldyopbV9wYWdlTWFwLkdldFZhbHVlQXQocFBERlBhZ2UpOw0KLQlpZihwUGFnZVZpZXcpDQotCXsNCi0JCWRlbGV0ZSBwUGFnZVZpZXc7DQotCQltX3BhZ2VNYXAuUmVtb3ZlS2V5KHBQREZQYWdlKTsNCi0JfQ0KLX0NCi0NCi1DUERGX1BhZ2UgKiBDUERGU0RLX0RvY3VtZW50OjpHZXRQYWdlKGludCBuSW5kZXgpDQotew0KLQlDUERGX1BhZ2UgKiBwVGVtcFBhZ2UgPSAoQ1BERl9QYWdlKiltX3BFbnYtPkZGSV9HZXRQYWdlKG1fcERvYyxuSW5kZXgpOw0KLQlpZighcFRlbXBQYWdlKQ0KLQkJcmV0dXJuIE5VTEw7DQotCXJldHVybiBwVGVtcFBhZ2U7DQotfQ0KLQ0KLUNQREZTREtfSW50ZXJGb3JtKiBDUERGU0RLX0RvY3VtZW50OjpHZXRJbnRlckZvcm0oKQ0KLXsNCi0JaWYoIW1fcEludGVyRm9ybSkNCi0JCW1fcEludGVyRm9ybSA9IG5ldyBDUERGU0RLX0ludGVyRm9ybSh0aGlzKTsNCi0JcmV0dXJuIG1fcEludGVyRm9ybTsNCi19DQotDQotdm9pZCBDUERGU0RLX0RvY3VtZW50OjpVcGRhdGVBbGxWaWV3cyhDUERGU0RLX1BhZ2VWaWV3KiBwU2VuZGVyLCBDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLQkNCi0JRlhfUE9TSVRJT04gcG9zID0gbV9wYWdlTWFwLkdldFN0YXJ0UG9zaXRpb24oKTsNCi0JQ1BERl9QYWdlICogcFBhZ2UgPSBOVUxMOw0KLQlDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3ID0gTlVMTDsNCi0Jd2hpbGUocG9zKQ0KLQl7DQotCQltX3BhZ2VNYXAuR2V0TmV4dEFzc29jKHBvcywgcFBhZ2UsIHBQYWdlVmlldyk7DQotDQotCQlpZihwUGFnZVZpZXcgIT0gcFNlbmRlcikNCi0JCXsNCi0JCQlwUGFnZVZpZXctPlVwZGF0ZVZpZXcocEFubm90KTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi1DUERGU0RLX0Fubm90KiBDUERGU0RLX0RvY3VtZW50OjpHZXRGb2N1c0Fubm90KCkNCi17DQotCXJldHVybiB0aGlzLT5tX3BGb2N1c0Fubm90OwkNCi19DQotDQotRlhfQk9PTCBDUERGU0RLX0RvY3VtZW50OjpTZXRGb2N1c0Fubm90KENQREZTREtfQW5ub3QqIHBBbm5vdCxGWF9VSU5UIG5GbGFnKQ0KLXsNCi0NCi0JaWYobV9wRm9jdXNBbm5vdD09cEFubm90KSByZXR1cm4gVFJVRTsNCi0JDQotCWlmKG1fcEZvY3VzQW5ub3QpDQotCXsNCi0JCWlmKCF0aGlzLT5LaWxsRm9jdXNBbm5vdChuRmxhZykgKSByZXR1cm4gRkFMU0U7CQ0KLQl9DQotCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBBbm5vdC0+R2V0UGFnZVZpZXcoKTsNCi0JaWYocEFubm90ICYmIHBQYWdlVmlldy0+SXNWYWxpZCgpKQ0KLQl7DQotCQlDUERGU0RLX0Fubm90SGFuZGxlck1nciAqcEFubm90SGFuZGxlcj1tX3BFbnYtPkdldEFubm90SGFuZGxlck1ncigpOw0KLQ0KLQkJaWYocEFubm90SGFuZGxlciYmIW1fcEZvY3VzQW5ub3QpDQotCQl7DQotCQkJaWYgKCFwQW5ub3RIYW5kbGVyLT5Bbm5vdF9PblNldEZvY3VzKHBBbm5vdCxuRmxhZykpDQotCQkJCXJldHVybiBGQUxTRTsNCi0JCQlpZighbV9wRm9jdXNBbm5vdCkNCi0JCQl7DQotCQkJCXRoaXMtPm1fcEZvY3VzQW5ub3Q9cEFubm90Ow0KLQkJCQlyZXR1cm4gVFJVRTsNCi0JCQl9DQotCQl9CQkJDQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfRG9jdW1lbnQ6OktpbGxGb2N1c0Fubm90KEZYX1VJTlQgbkZsYWcpDQotew0KLQlpZihtX3BGb2N1c0Fubm90KQ0KLQl7DQotCQlDUERGU0RLX0Fubm90SGFuZGxlck1nciAqcEFubm90SGFuZGxlcj1tX3BFbnYtPkdldEFubm90SGFuZGxlck1ncigpOw0KLQkJaWYocEFubm90SGFuZGxlcikNCi0JCXsNCi0JCQlDUERGU0RLX0Fubm90KiBwRm9jdXNBbm5vdCA9IG1fcEZvY3VzQW5ub3Q7DQotCQkJbV9wRm9jdXNBbm5vdCA9IE5VTEw7DQotCQkJaWYocEFubm90SGFuZGxlci0+QW5ub3RfT25LaWxsRm9jdXMocEZvY3VzQW5ub3QsIG5GbGFnKSkNCi0JCQl7DQotCQkJCQ0KLQkJCQlpZihwRm9jdXNBbm5vdC0+R2V0VHlwZSgpID09IEZYX0JTVFJDKCJXaWRnZXQiKSkNCi0JCQkJew0KLQkJCQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXBGb2N1c0Fubm90Ow0KLQkJCQkJaW50IG5GaWVsZFR5cGUgPSBwV2lkZ2V0LT5HZXRGaWVsZFR5cGUoKTsNCi0JCQkJCWlmKEZJRUxEVFlQRV9URVhURklFTEQgPT0gbkZpZWxkVHlwZSB8fCBGSUVMRFRZUEVfQ09NQk9CT1ggPT0gbkZpZWxkVHlwZSkNCi0JCQkJCQltX3BFbnYtPkZGSV9PblNldEZpZWxkSW5wdXRGb2N1cyhOVUxMLCBOVUxMLCAwLCBGQUxTRSk7DQotCQkJCX0NCi0NCi0JCQkJaWYoIW1fcEZvY3VzQW5ub3QpDQotCQkJCQlyZXR1cm4gVFJVRTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJbV9wRm9jdXNBbm5vdCA9IHBGb2N1c0Fubm90Ow0KLQkJCX0NCi0JCX0NCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19Eb2N1bWVudDo6RGVsZXRlUGFnZXMoaW50IG5TdGFydCwgaW50ICBuQ291bnQpDQotew0KLQlpZiAoIG5TdGFydCA8IDAgfHwgblN0YXJ0ID49IEdldFBhZ2VDb3VudCgpIHx8IG5Db3VudCA8PSAwICkNCi0Jew0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCUNQREZfUGFnZSAqIHBUZW1wUGFnZSA9IE5VTEw7DQotCWZvciAoIGludCBpID0gbkNvdW50LTE7IGkgPj0gMDsgaS0tICkNCi0Jew0KLQkJcFRlbXBQYWdlID0gR2V0UGFnZShuU3RhcnQraSk7DQotCQlpZiAoIHBUZW1wUGFnZSAhPSBOVUxMICkNCi0JCXsNCi0JCQlSZU1vdmVQYWdlVmlldyhwVGVtcFBhZ2UpOw0KLQkJfQ0KLQl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIENQREZTREtfRG9jdW1lbnQ6Ok9uQ2xvc2VEb2N1bWVudCgpDQotew0KLQlLaWxsRm9jdXNBbm5vdCgpOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfRG9jdW1lbnQ6OkdldFBlcm1pc3Npb25zKGludCBuRmxhZykNCi17DQotCUZYX0RXT1JEIGR3UGVybWlzc2lvbnMgPSBtX3BEb2MtPkdldFVzZXJQZXJtaXNzaW9ucygpOw0KLQlyZXR1cm4gZHdQZXJtaXNzaW9ucyZuRmxhZzsNCi19DQotDQotSUZYSlNfUnVudGltZSAqIENQREZTREtfRG9jdW1lbnQ6OkdldEpzUnVudGltZSgpDQotew0KLQlBU1NFUlQobV9wRW52IT1OVUxMKTsNCi0JcmV0dXJuIG1fcEVudi0+R2V0SlNSdW50aW1lKCk7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nCUNQREZTREtfRG9jdW1lbnQ6OkdldFBhdGgoKSANCi17DQotCUFTU0VSVChtX3BFbnYgIT0gTlVMTCk7DQotCXJldHVybiBtX3BFbnYtPkpTX2RvY0dldEZpbGVQYXRoKCk7DQotfQ0KLQ0KLQ0KLUNQREZTREtfUGFnZVZpZXc6OkNQREZTREtfUGFnZVZpZXcoQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyxDUERGX1BhZ2UqIHBhZ2UpOm1fcFNES0RvYyhwU0RLRG9jKSxtX3BhZ2UocGFnZSkNCi17DQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gcFNES0RvYy0+R2V0SW50ZXJGb3JtKCk7DQotCWlmKHBJbnRlckZvcm0pDQotCXsNCi0JCUNQREZfSW50ZXJGb3JtKiBwUERGSW50ZXJGb3JtID0gcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCQlwUERGSW50ZXJGb3JtLT5GaXhQYWdlRmllbGRzKHBhZ2UpOw0KLQl9DQotDQotCW1fZnhBbm5vdEFycmF5LlJlbW92ZUFsbCgpOw0KLQ0KLQltX2JFbnRlcldpZGdldCA9IEZBTFNFOw0KLQltX2JFeGl0V2lkZ2V0ID0gRkFMU0U7DQotCW1fYk9uV2lkZ2V0ID0gRkFMU0U7DQotCW1fQ2FwdHVyZVdpZGdldCA9IE5VTEw7DQotCW1fYlZhbGlkID0gRkFMU0U7DQotfQ0KLQ0KLUNQREZTREtfUGFnZVZpZXc6On5DUERGU0RLX1BhZ2VWaWV3KCkNCi17DQotCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOwkNCi0JaW50IG5Bbm5vdENvdW50ID0gbV9meEFubm90QXJyYXkuR2V0U2l6ZSgpOw0KLQlmb3IgKGludCBpPTA7IGk8bkFubm90Q291bnQ7IGkrKykNCi0Jew0KLQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gKENQREZTREtfQW5ub3QqKW1fZnhBbm5vdEFycmF5LkdldEF0KGkpOw0KLQkJLy9pZiB0aGVyZSBpcyBhIGZvY3VzZWQgYW5ub3Qgb24gdGhlIHBhZ2UsIHdlIHNob3VsZCBraWxsIHRoZSBmb2N1cyBmaXJzdC4NCi0JCWlmKHBBbm5vdCA9PSBtX3BTREtEb2MtPkdldEZvY3VzQW5ub3QoKSkNCi0JCQlLaWxsRm9jdXNBbm5vdCgpOw0KLQkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIHBBbm5vdEhhbmRsZXJNZ3IgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsNCi0JCUFTU0VSVChwQW5ub3RIYW5kbGVyTWdyKTsNCi0JCXBBbm5vdEhhbmRsZXJNZ3ItPlJlbGVhc2VBbm5vdChwQW5ub3QpOw0KLQl9DQotCW1fZnhBbm5vdEFycmF5LlJlbW92ZUFsbCgpOw0KLQlpZihtX3BBbm5vdExpc3QpDQotCXsNCi0JCWRlbGV0ZSBtX3BBbm5vdExpc3Q7DQotCQltX3BBbm5vdExpc3QgPSBOVUxMOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19QYWdlVmlldzo6UGFnZVZpZXdfT25EcmF3KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsQ1BERl9SZW5kZXJPcHRpb25zKiBwT3B0aW9ucykNCi17DQotCW1fY3VyTWF0cml4ID0gKnBVc2VyMkRldmljZTsNCi0JDQotCS8vCW1fcEFubm90TGlzdC0+RGlzcGxheUFubm90cyhtX3BhZ2UsIHBEZXZpY2UsIHBVc2VyMkRldmljZSwgRkFMU0UsIHBPcHRpb25zKTsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQotCUNQREZTREtfQW5ub3RJdGVyYXRvciBhbm5vdEl0ZXJhdG9yKHRoaXMsIFRSVUUpOw0KLQlDUERGU0RLX0Fubm90ICogcFNES0Fubm90PU5VTEw7DQotCWludCBpbmRleD0tMTsNCi0Jd2hpbGUoKHBTREtBbm5vdCA9IGFubm90SXRlcmF0b3IuTmV4dChpbmRleCkpKQ0KLQl7DQotCQlDUERGU0RLX0Fubm90SGFuZGxlck1nciogcEFubm90SGFuZGxlck1nciA9IHBFbnYtPkdldEFubm90SGFuZGxlck1ncigpOw0KLQkJQVNTRVJUKHBBbm5vdEhhbmRsZXJNZ3IpOw0KLQkJcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25EcmF3KHRoaXMsIHBTREtBbm5vdCwgcERldmljZSwgcFVzZXIyRGV2aWNlLCAwKTsNCi0JfQ0KLQ0KLX0NCi0NCi1DUERGX0Fubm90KiBDUERGU0RLX1BhZ2VWaWV3OjpHZXRQREZBbm5vdEF0UG9pbnQoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKQ0KLXsNCi0JDQotCWludCBuQ291bnQgPSBtX3BBbm5vdExpc3QtPkNvdW50KCk7DQotCWZvcihpbnQgaSA9IDAgOyBpPG5Db3VudDsgaSsrKQ0KLQl7DQotCQlDUERGX0Fubm90KiBwQW5ub3QgPSBtX3BBbm5vdExpc3QtPkdldEF0KGkpOw0KLQkJQ0ZYX0Zsb2F0UmVjdCBhbm5vdFJlY3Q7DQotCQlwQW5ub3QtPkdldFJlY3QoYW5ub3RSZWN0KTsNCi0JCWlmKGFubm90UmVjdC5Db250YWlucyhwYWdlWCwgcGFnZVkpKQ0KLQkJCXJldHVybiBwQW5ub3Q7DQotCX0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUNQREZfQW5ub3QqIENQREZTREtfUGFnZVZpZXc6OkdldFBERldpZGdldEF0UG9pbnQoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKQ0KLXsNCi0JDQotCWludCBuQ291bnQgPSBtX3BBbm5vdExpc3QtPkNvdW50KCk7DQotCWZvcihpbnQgaSA9IDAgOyBpPG5Db3VudDsgaSsrKQ0KLQl7DQotCQlDUERGX0Fubm90KiBwQW5ub3QgPSBtX3BBbm5vdExpc3QtPkdldEF0KGkpOw0KLQkJaWYocEFubm90LT5HZXRTdWJUeXBlKCkgPT0gIldpZGdldCIpDQotCQl7DQotCQkJQ0ZYX0Zsb2F0UmVjdCBhbm5vdFJlY3Q7DQotCQkJcEFubm90LT5HZXRSZWN0KGFubm90UmVjdCk7DQotCQkJaWYoYW5ub3RSZWN0LkNvbnRhaW5zKHBhZ2VYLCBwYWdlWSkpDQotCQkJCXJldHVybiBwQW5ub3Q7DQotCQl9DQotCX0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUNQREZTREtfQW5ub3QqIENQREZTREtfUGFnZVZpZXc6OkdldEZYQW5ub3RBdFBvaW50KEZYX0ZMT0FUIHBhZ2VYLCBGWF9GTE9BVCBwYWdlWSkNCi17DQotDQotCUNQREZTREtfQW5ub3RJdGVyYXRvciBhbm5vdEl0ZXJhdG9yKHRoaXMsIEZBTFNFKTsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQotCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RNZ3IgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsNCi0JQ1BERlNES19Bbm5vdCogcFNES0Fubm90ID0gTlVMTDsNCi0JaW50IGluZGV4ID0gLTE7DQotCXdoaWxlKChwU0RLQW5ub3QgPSBhbm5vdEl0ZXJhdG9yLk5leHQoaW5kZXgpKSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjID0gcEFubm90TWdyLT5Bbm5vdF9PbkdldFZpZXdCQm94KHRoaXMsIHBTREtBbm5vdCk7DQotCQlpZihyYy5Db250YWlucyhwYWdlWCwgcGFnZVkpKQ0KLQkJCXJldHVybiBwU0RLQW5ub3Q7DQotCX0NCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUNQREZTREtfQW5ub3QqIENQREZTREtfUGFnZVZpZXc6OkdldEZYV2lkZ2V0QXRQb2ludChGWF9GTE9BVCBwYWdlWCwgRlhfRkxPQVQgcGFnZVkpDQotew0KLQ0KLQlDUERGU0RLX0Fubm90SXRlcmF0b3IgYW5ub3RJdGVyYXRvcih0aGlzLCBGQUxTRSk7DQotCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KLQlDUERGU0RLX0Fubm90SGFuZGxlck1nciogcEFubm90TWdyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7DQotCUNQREZTREtfQW5ub3QqIHBTREtBbm5vdCA9IE5VTEw7DQotCWludCBpbmRleCA9IC0xOw0KLQl3aGlsZSgocFNES0Fubm90ID0gYW5ub3RJdGVyYXRvci5OZXh0KGluZGV4KSkpDQotCXsNCi0JCWlmKHBTREtBbm5vdC0+R2V0VHlwZSgpID09ICJXaWRnZXQiKQ0KLQkJewkNCi0JCQlwQW5ub3RNZ3ItPkFubm90X09uR2V0Vmlld0JCb3godGhpcywgcFNES0Fubm90KTsNCi0JCQlDUERGX1BvaW50IHBvaW50KHBhZ2VYLCBwYWdlWSk7DQotCQkJaWYgKHBBbm5vdE1nci0+QW5ub3RfT25IaXRUZXN0KHRoaXMsIHBTREtBbm5vdCwgcG9pbnQpKQ0KLS8vCQkJaWYocmMuQ29udGFpbnMocGFnZVgsIHBhZ2VZKSkNCi0JCQkJcmV0dXJuIHBTREtBbm5vdDsNCi0JCX0NCi0JfQ0KLQkNCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19QYWdlVmlldzo6QW5ub3RfSGFzQXBwZWFyYW5jZShDUERGX0Fubm90KiBwQW5ub3QpDQotew0KLQlDUERGX0RpY3Rpb25hcnkqIHBBbm5vdERpYyA9IHBBbm5vdC0+bV9wQW5ub3REaWN0Ow0KLQlpZihwQW5ub3REaWMpDQotCQlyZXR1cm4JcEFubm90RGljLT5LZXlFeGlzdCgiQVMiKTsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1DUERGU0RLX0Fubm90KglDUERGU0RLX1BhZ2VWaWV3OjpBZGRBbm5vdChDUERGX0Fubm90ICogcFBERkFubm90KQ0KLXsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52KTsNCi0JQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IgKiBwQW5ub3RIYW5kbGVyPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsJDQotCQ0KLQlDUERGU0RLX0Fubm90KiBwU0RLQW5ub3QgPU5VTEw7DQotCQ0KLQlpZihwQW5ub3RIYW5kbGVyKQ0KLQl7DQotCQlwU0RLQW5ub3QgPSBwQW5ub3RIYW5kbGVyLT5OZXdBbm5vdChwUERGQW5ub3QsIHRoaXMpOw0KLQl9DQotCWlmKCFwU0RLQW5ub3QpCSANCi0JCXJldHVybiBOVUxMOw0KLQ0KLQltX2Z4QW5ub3RBcnJheS5BZGQocFNES0Fubm90KTsJDQotCQkNCi0JaWYocEFubm90SGFuZGxlcikNCi0JewkgCQkgCSANCi0JCXBBbm5vdEhhbmRsZXItPkFubm90X09uQ3JlYXRlKHBTREtBbm5vdCk7DQotCQkNCi0JfQ0KLQ0KLQkgcmV0dXJuIHBTREtBbm5vdDsNCi19DQotDQotQ1BERlNES19Bbm5vdCogQ1BERlNES19QYWdlVmlldzo6QWRkQW5ub3QoQ1BERl9EaWN0aW9uYXJ5ICogcERpY3QpDQotew0KLQlpZihwRGljdCkgIA0KLQkJcmV0dXJuIHRoaXMtPkFkZEFubm90KHBEaWN0LT5HZXRTdHJpbmcoIlN1YnR5cGUiKSxwRGljdCk7DQotCSByZXR1cm4gTlVMTDsNCi19DQotDQotQ1BERlNES19Bbm5vdCogQ1BERlNES19QYWdlVmlldzo6QWRkQW5ub3QoRlhfTFBDU1RSIGxwU3ViVHlwZSxDUERGX0RpY3Rpb25hcnkgKiBwRGljdCkNCi17DQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi1GWF9CT09MICBDUERGU0RLX1BhZ2VWaWV3OjpEZWxldGVBbm5vdChDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUNQREZfRG9jdW1lbnQqIENQREZTREtfUGFnZVZpZXc6OkdldFBERkRvY3VtZW50KCkNCi17DQotCWlmKG1fcGFnZSkNCi0Jew0KLQkJcmV0dXJuIG1fcGFnZS0+bV9wRG9jdW1lbnQ7DQotCX0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLWludAlDUERGU0RLX1BhZ2VWaWV3OjpDb3VudEFubm90cygpDQotew0KLQlyZXR1cm4gbV9wQW5ub3RMaXN0LT5Db3VudCgpOw0KLX0NCi0NCi1DUERGU0RLX0Fubm90KglDUERGU0RLX1BhZ2VWaWV3OjpHZXRBbm5vdChpbnQgbkluZGV4KQ0KLXsNCi0JaW50IG5Db3VudCA9IG1fZnhBbm5vdEFycmF5LkdldFNpemUoKTsNCi0JaWYgKCBuSW5kZXggPCAwIHx8IG5JbmRleCA+PSBuQ291bnQgKQ0KLQl7DQotCQlyZXR1cm4gTlVMTDsNCi0JfQ0KLQ0KLQlyZXR1cm4gKENQREZTREtfQW5ub3QqKW1fZnhBbm5vdEFycmF5LkdldEF0KG5JbmRleCk7DQotfQ0KLQ0KLUNQREZTREtfQW5ub3QqIENQREZTREtfUGFnZVZpZXc6OkdldEFubm90QnlEaWN0KENQREZfRGljdGlvbmFyeSAqIHBEaWN0KQ0KLXsNCi0JaW50IG5Db3VudCA9IG1fZnhBbm5vdEFycmF5LkdldFNpemUoKTsNCi0gCWZvcihpbnQgaT0wOyBpPG5Db3VudDsgaSsrKQ0KLSAJew0KLQkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gKENQREZTREtfQW5ub3QqKW1fZnhBbm5vdEFycmF5LkdldEF0KGkpOw0KLSAJCWlmKHBEaWN0PT1wQW5ub3QtPkdldFBERkFubm90KCktPm1fcEFubm90RGljdCkgDQotIAkJCXJldHVybiBwQW5ub3Q7DQotIAl9DQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi1GWF9CT09MIENQREZTREtfUGFnZVZpZXc6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9VSU5UIG5GbGFnKQ0KLXsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52KTsNCi0JQ1BERlNES19Bbm5vdCogcEZYQW5ub3QgPSBHZXRGWFdpZGdldEF0UG9pbnQocG9pbnQueCwgcG9pbnQueSk7DQotCWlmKCFwRlhBbm5vdCkNCi0Jew0KLQkJS2lsbEZvY3VzQW5ub3QobkZsYWcpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIHBBbm5vdEhhbmRsZXJNZ3IgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsNCi0JCUFTU0VSVChwQW5ub3RIYW5kbGVyTWdyKTsNCi0NCi0JCUZYX0JPT0wgYlJldCA9IHBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uTEJ1dHRvbkRvd24odGhpcywgcEZYQW5ub3QsIG5GbGFnLHBvaW50KTsNCi0gCQlpZihiUmV0KQ0KLSAJCXsNCi0gCQkJU2V0Rm9jdXNBbm5vdChwRlhBbm5vdCk7DQotIAkJfQ0KLQkJcmV0dXJuIGJSZXQ7DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi0NCi1GWF9CT09MIENQREZTREtfUGFnZVZpZXc6Ok9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfVUlOVCBuRmxhZykNCi17DQotCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KLQlBU1NFUlQocEVudik7DQotCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RIYW5kbGVyTWdyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7DQotCUFTU0VSVChwQW5ub3RIYW5kbGVyTWdyKTsNCi0JQ1BERlNES19Bbm5vdCogcEZYQW5ub3QgPSBHZXRGWFdpZGdldEF0UG9pbnQocG9pbnQueCwgcG9pbnQueSk7DQotCUNQREZTREtfQW5ub3QqIHBGb2N1c0Fubm90ID0gR2V0Rm9jdXNBbm5vdCgpOw0KLQlGWF9CT09MIGJSZXQgID0gRkFMU0U7DQotCWlmKHBGb2N1c0Fubm90ICYmIHBGb2N1c0Fubm90ICE9IHBGWEFubm90KQ0KLQl7DQotCQkvL0xhc3QgZm9jdXMgQW5ub3QgZ2V0cyBhIGNoYW5jZSB0byBoYW5kbGUgdGhlIGV2ZW50Lg0KLQkJYlJldCA9IHBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uTEJ1dHRvblVwKHRoaXMsIHBGb2N1c0Fubm90LCBuRmxhZyxwb2ludCk7DQotCX0NCi0JaWYocEZYQW5ub3QgJiYgIWJSZXQpDQotCXsNCi0JCWJSZXQgPSBwQW5ub3RIYW5kbGVyTWdyLT5Bbm5vdF9PbkxCdXR0b25VcCh0aGlzLCBwRlhBbm5vdCwgbkZsYWcscG9pbnQpOw0KLQkJcmV0dXJuIGJSZXQ7DQotCX0NCi0JcmV0dXJuIGJSZXQ7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19QYWdlVmlldzo6T25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBpbnQgbkZsYWcpDQotew0KLQ0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsNCi0JQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIHBBbm5vdEhhbmRsZXJNZ3IgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsNCi0JQVNTRVJUKHBBbm5vdEhhbmRsZXJNZ3IpOw0KLQlpZihDUERGU0RLX0Fubm90KiBwRlhBbm5vdCA9IEdldEZYV2lkZ2V0QXRQb2ludChwb2ludC54LCBwb2ludC55KSkNCi0Jew0KLQkJaWYobV9DYXB0dXJlV2lkZ2V0ICYmIG1fQ2FwdHVyZVdpZGdldCAhPSBwRlhBbm5vdCkNCi0JCXsNCi0JCQltX2JFeGl0V2lkZ2V0ID0gVFJVRTsNCi0JCQltX2JFbnRlcldpZGdldCA9IEZBTFNFOw0KLQkJCXBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uTW91c2VFeGl0KHRoaXMsIG1fQ2FwdHVyZVdpZGdldCwgbkZsYWcpOw0KLQkJfQ0KLQkJbV9DYXB0dXJlV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwRlhBbm5vdDsNCi0JCW1fYk9uV2lkZ2V0ID0gVFJVRTsNCi0JCWlmKCFtX2JFbnRlcldpZGdldCkNCi0JCXsNCi0JCQltX2JFbnRlcldpZGdldCA9IFRSVUU7DQotCQkJbV9iRXhpdFdpZGdldCA9IEZBTFNFOw0KLQkJCXBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uTW91c2VFbnRlcih0aGlzLCBwRlhBbm5vdCxuRmxhZyk7DQotCQl9DQotCQlwQW5ub3RIYW5kbGVyTWdyLT5Bbm5vdF9Pbk1vdXNlTW92ZSh0aGlzLCBwRlhBbm5vdCwgbkZsYWcsIHBvaW50KTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYobV9iT25XaWRnZXQpDQotCQl7CQ0KLQkJCW1fYk9uV2lkZ2V0ID0gRkFMU0U7DQotCQkJbV9iRXhpdFdpZGdldCA9IFRSVUU7DQotCQkJbV9iRW50ZXJXaWRnZXQgPSBGQUxTRTsNCi0JCQlpZihtX0NhcHR1cmVXaWRnZXQpDQotCQkJew0KLQkJCQlwQW5ub3RIYW5kbGVyTWdyLT5Bbm5vdF9Pbk1vdXNlRXhpdCh0aGlzLCBtX0NhcHR1cmVXaWRnZXQsIG5GbGFnKTsNCi0JCQkJbV9DYXB0dXJlV2lkZ2V0ID0gTlVMTDsNCi0JCQl9DQotCQl9DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTs7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19QYWdlVmlldzo6T25Nb3VzZVdoZWVsKGRvdWJsZSBkZWx0YVgsIGRvdWJsZSBkZWx0YVksY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIGludCBuRmxhZykNCi17DQotCWlmKENQREZTREtfQW5ub3QqIHBBbm5vdCA9IEdldEZYV2lkZ2V0QXRQb2ludChwb2ludC54LCBwb2ludC55KSkNCi0Jew0KLQkJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQotCQlDUERGU0RLX0Fubm90SGFuZGxlck1nciogcEFubm90SGFuZGxlck1nciA9IHBFbnYtPkdldEFubm90SGFuZGxlck1ncigpOw0KLQkJQVNTRVJUKHBBbm5vdEhhbmRsZXJNZ3IpOw0KLQkJcmV0dXJuIHBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uTW91c2VXaGVlbCh0aGlzLCBwQW5ub3QsIG5GbGFnLCAoaW50KWRlbHRhWSwgcG9pbnQpOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi0NCi19DQotDQotRlhfQk9PTCBDUERGU0RLX1BhZ2VWaWV3OjpPbkNoYXIoaW50IG5DaGFyLCBGWF9VSU5UIG5GbGFnKQ0KLXsNCi0JaWYoQ1BERlNES19Bbm5vdCogcEFubm90ID0gR2V0Rm9jdXNBbm5vdCgpKQ0KLQl7DQotCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsNCi0JCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RIYW5kbGVyTWdyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7DQotCQlBU1NFUlQocEFubm90SGFuZGxlck1ncik7DQotCQlyZXR1cm4gcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25DaGFyKHBBbm5vdCwgbkNoYXIsIG5GbGFnKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19QYWdlVmlldzo6T25LZXlEb3duKGludCBuS2V5Q29kZSwgaW50IG5GbGFnKQ0KLXsNCi0JaWYoQ1BERlNES19Bbm5vdCogcEFubm90ID0gR2V0Rm9jdXNBbm5vdCgpKQ0KLQl7DQotCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsNCi0JCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RIYW5kbGVyTWdyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7DQotCQlBU1NFUlQocEFubm90SGFuZGxlck1ncik7DQotCQlyZXR1cm4gcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25LZXlEb3duKHBBbm5vdCwgbktleUNvZGUsIG5GbGFnKTsNCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BERlNES19QYWdlVmlldzo6T25LZXlVcChpbnQgbktleUNvZGUsIGludCBuRmxhZykNCi17DQotLy8gCWlmKENQREZTREtfQW5ub3QqIHBBbm5vdCA9IEdldEZvY3VzQW5ub3QoKSkNCi0vLyAJew0KLS8vIAkJQ0ZGTF9JRm9ybUZpbGxlciogcElGb3JtRmlsbGVyID0gZ19wRm9ybUZpbGxBcHAtPkdldElGb3JtRmlsbGVyKCk7DQotLy8gCQlyZXR1cm4gcElGb3JtRmlsbGVyLT5PbktleVVwKHBBbm5vdCwgbktleUNvZGUsIG5GbGFnKTsNCi0vLyAJfQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLWV4dGVybiB2b2lkIENoZWNrVW5TdXBwb3J0QW5ub3QoQ1BERl9Eb2N1bWVudCAqIHBEb2MsIENQREZfQW5ub3QqIHBQREZBbm5vdCk7DQotDQotdm9pZCBDUERGU0RLX1BhZ2VWaWV3OjpMb2FkRlhBbm5vdHMoKQ0KLXsNCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7DQotDQotCUZYX0JPT0wgZW5hYmxlQVBVcGRhdGUgPSBDUERGX0ludGVyRm9ybTo6VXBkYXRpbmdBUEVuYWJsZWQoKTsNCi0JLy9EaXNhYmxlIHRoZSBkZWZhdWx0IEFQIGNvbnN0cnVjdGlvbi4NCi0JQ1BERl9JbnRlckZvcm06OkVuYWJsZVVwZGF0ZUFQKEZBTFNFKTsNCi0JbV9wQW5ub3RMaXN0ID0gbmV3IENQREZfQW5ub3RMaXN0KG1fcGFnZSk7DQotCUNQREZfSW50ZXJGb3JtOjpFbmFibGVVcGRhdGVBUChlbmFibGVBUFVwZGF0ZSk7DQotCWludCBuQ291bnQgPSBtX3BBbm5vdExpc3QtPkNvdW50KCk7DQotCWZvcihpbnQgaT0wOyBpPG5Db3VudDsgaSsrKQ0KLQl7DQotCQlDUERGX0Fubm90KiBwUERGQW5ub3QgPSBtX3BBbm5vdExpc3QtPkdldEF0KGkpOw0KLQkJQ1BERl9Eb2N1bWVudCAqIHBEb2MgPSB0aGlzLT5HZXRQREZEb2N1bWVudCgpOw0KLQkJDQotCQlDaGVja1VuU3VwcG9ydEFubm90KHBEb2MsIHBQREZBbm5vdCk7DQotDQotCQlDUERGU0RLX0Fubm90SGFuZGxlck1nciogcEFubm90SGFuZGxlck1nciA9IHBFbnYtPkdldEFubm90SGFuZGxlck1ncigpOw0KLQkJQVNTRVJUKHBBbm5vdEhhbmRsZXJNZ3IgIT0gTlVMTCk7DQotCQlpZihwQW5ub3RIYW5kbGVyTWdyKQ0KLQkJew0KLQkJCUNQREZTREtfQW5ub3QqIHBBbm5vdCA9IHBBbm5vdEhhbmRsZXJNZ3ItPk5ld0Fubm90KHBQREZBbm5vdCwgdGhpcyk7DQotCQkJaWYoIXBBbm5vdCkNCi0JCQkJY29udGludWU7DQotCQkJbV9meEFubm90QXJyYXkuQWRkKHBBbm5vdCk7DQotDQotCQkJcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25Mb2FkKHBBbm5vdCk7DQotCQl9DQotDQotCX0NCi19DQotDQotdm9pZAlDUERGU0RLX1BhZ2VWaWV3OjpVcGRhdGVSZWN0cyhDRlhfUmVjdEFycmF5JiByZWN0cykNCi17DQotCWZvcihpbnQgaT0wOyBpPHJlY3RzLkdldFNpemUoKTsgaSsrKQ0KLQl7DQotCQlDUERGX1JlY3QgcmMgPSByZWN0cy5HZXRBdChpKTsNCi0JCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOw0KLQkJcEVudi0+RkZJX0ludmFsaWRhdGUobV9wYWdlLCByYy5sZWZ0LCByYy50b3AsIHJjLnJpZ2h0LCByYy5ib3R0b20pOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BERlNES19QYWdlVmlldzo6VXBkYXRlVmlldyhDUERGU0RLX0Fubm90KiBwQW5ub3QpDQotew0KLQlDUERGX1JlY3QgcmNXaW5kb3c7DQotDQotIAlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsJDQotLy8gCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RIYW5kbGVyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7DQotCQ0KLQlyY1dpbmRvdyA9IHBBbm5vdC0+R2V0UmVjdCgpOy8vcEFubm90SGFuZGxlci0+QW5ub3RfT25HZXRWaWV3QkJveCh0aGlzLHBBbm5vdCk7CQ0KLQlwRW52LT5GRklfSW52YWxpZGF0ZShtX3BhZ2UsIHJjV2luZG93LmxlZnQsIHJjV2luZG93LnRvcCwgcmNXaW5kb3cucmlnaHQsIHJjV2luZG93LmJvdHRvbSk7DQotDQotfQ0KLQ0KLWludCBDUERGU0RLX1BhZ2VWaWV3OjpHZXRQYWdlSW5kZXgoKQ0KLXsNCi0JaWYobV9wYWdlKQ0KLQl7DQotCQlDUERGX0RpY3Rpb25hcnkqIHBEaWMgPSBtX3BhZ2UtPm1fcEZvcm1EaWN0Ow0KLQkJQ1BERl9Eb2N1bWVudCogcERvYyA9IG1fcFNES0RvYy0+R2V0RG9jdW1lbnQoKTsNCi0JCWlmKHBEb2MgJiYgcERpYykNCi0JCXsNCi0JCQlyZXR1cm4gcERvYy0+R2V0UGFnZUluZGV4KHBEaWMtPkdldE9iak51bSgpKTsNCi0JCX0NCi0JfQ0KLQlyZXR1cm4gLTE7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BERlNES19QYWdlVmlldzo6SXNWYWxpZEFubm90KEZYX0xQVk9JRCBwKQ0KLXsNCi0JaWYgKHAgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOw0KLQlpbnQgaUNvdW50ID0gbV9wQW5ub3RMaXN0LT5Db3VudCgpOw0KLQlmb3IgKGludCBpID0gMDsgaSA8IGlDb3VudDsgaSsrKQ0KLQl7DQotCQlpZiAobV9wQW5ub3RMaXN0LT5HZXRBdChpKSA9PSBwKQ0KLQkJCXJldHVybiBUUlVFOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotDQotQ1BERlNES19Bbm5vdCogQ1BERlNES19QYWdlVmlldzo6R2V0Rm9jdXNBbm5vdCgpDQotew0KLQlDUERGU0RLX0Fubm90KiBwRm9jdXNBbm5vdCA9IG1fcFNES0RvYy0+R2V0Rm9jdXNBbm5vdCgpOw0KLQlpZighcEZvY3VzQW5ub3QpDQotCQlyZXR1cm4gTlVMTDsNCi0JDQotCWZvcihpbnQgaT0wOyBpPG1fZnhBbm5vdEFycmF5LkdldFNpemUoKTsgaSsrKQ0KLQl7DQotCQlDUERGU0RLX0Fubm90KiBwQW5ub3QgPSAoQ1BERlNES19Bbm5vdCopbV9meEFubm90QXJyYXkuR2V0QXQoaSk7DQotCQlpZihwQW5ub3QgPT0gcEZvY3VzQW5ub3QpDQotCQkJcmV0dXJuIHBBbm5vdDsNCi0JfQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19kZWZpbmUuaCIKKyNpbmNsdWRlICIuLi9pbmNsdWRlL2ZzZGtfbWdyLmgiCisjaW5jbHVkZSAiLi4vaW5jbHVkZS9mcGRmX2V4dC5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvZm9ybWZpbGxlci9GRkxfRm9ybUZpbGxlci5oIgorI2luY2x1ZGUgIi4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorCisjaWYgX0ZYX09TXyA9PSBfRlhfQU5EUk9JRF8KKyNpbmNsdWRlICJ0aW1lLmgiCisjZWxzZQorI2luY2x1ZGUgPGN0aW1lPgorI2VuZGlmCisKKy8vZXh0ZXJuIENQREZEb2NfRW52aXJvbm1lbnQqIGdfcEZvcm1GaWxsQXBwOworY2xhc3MgQ0ZYX1N5c3RlbUhhbmRsZXI6cHVibGljIElGWF9TeXN0ZW1IYW5kbGVyCit7CitwdWJsaWM6CisJQ0ZYX1N5c3RlbUhhbmRsZXIoQ1BERkRvY19FbnZpcm9ubWVudCogcEVudik6bV9wRW52KHBFbnYpLG1fbkNoYXJTZXQoLTEpIHt9CitwdWJsaWM6CisJdmlydHVhbCB2b2lkCQkJCUludmFsaWRhdGVSZWN0KEZYX0hXTkQgaFduZCwgRlhfUkVDVCByZWN0KSA7CisJdmlydHVhbCB2b2lkCQkJCU91dHB1dFNlbGVjdGVkUmVjdCh2b2lkKiBwRm9ybUZpbGxlciwgQ1BERl9SZWN0JiByZWN0KTsKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlJc1NlbGVjdGlvbkltcGxlbWVudGVkKCk7CisKKwl2aXJ0dWFsIENGWF9XaWRlU3RyaW5nCQlHZXRDbGlwYm9hcmRUZXh0KEZYX0hXTkQgaFduZCl7cmV0dXJuIEwiIjt9CisJdmlydHVhbCBGWF9CT09MCQkJCVNldENsaXBib2FyZFRleHQoRlhfSFdORCBoV25kLCBDRlhfV2lkZVN0cmluZyBzdHJpbmcpIHtyZXR1cm4gRkFMU0U7fQorCQorCXZpcnR1YWwgdm9pZAkJCQlDbGllbnRUb1NjcmVlbihGWF9IV05EIGhXbmQsIEZYX0lOVDMyJiB4LCBGWF9JTlQzMiYgeSkge30KKwl2aXJ0dWFsIHZvaWQJCQkJU2NyZWVuVG9DbGllbnQoRlhfSFdORCBoV25kLCBGWF9JTlQzMiYgeCwgRlhfSU5UMzImIHkpIHt9CisKKwkvKmN1cnNvciBzdHlsZQorCUZYQ1RfQVJST1cJCisJRlhDVF9ORVNXCQkKKwlGWENUX05XU0UJCQorCUZYQ1RfVkJFQU0JCQorCUZYQ1RfSEJFQU0JCQorCUZYQ1RfSEFORAorCSovCisJdmlydHVhbCB2b2lkCQkJCVNldEN1cnNvcihGWF9JTlQzMiBuQ3Vyc29yVHlwZSk7CisKKwl2aXJ0dWFsIEZYX0hNRU5VCQkJQ3JlYXRlUG9wdXBNZW51KCkge3JldHVybiBOVUxMO30KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJQXBwZW5kTWVudUl0ZW0oRlhfSE1FTlUgaE1lbnUsIEZYX0lOVDMyIG5JRE5ld0l0ZW0sIENGWF9XaWRlU3RyaW5nIHN0cmluZykge3JldHVybiBGQUxTRTt9CisJdmlydHVhbCBGWF9CT09MCQkJCUVuYWJsZU1lbnVJdGVtKEZYX0hNRU5VIGhNZW51LCBGWF9JTlQzMiBuSURJdGVtLCBGWF9CT09MIGJFbmFibGVkKSB7cmV0dXJuIEZBTFNFO30KKwl2aXJ0dWFsIEZYX0lOVDMyCQkJVHJhY2tQb3B1cE1lbnUoRlhfSE1FTlUgaE1lbnUsIEZYX0lOVDMyIHgsIEZYX0lOVDMyIHksIEZYX0hXTkQgaFBhcmVudCkge3JldHVybiAtMTt9CisJdmlydHVhbCB2b2lkCQkJCURlc3Ryb3lNZW51KEZYX0hNRU5VIGhNZW51KSB7fQorCisJdmlydHVhbCBDRlhfQnl0ZVN0cmluZwkJR2V0TmF0aXZlVHJ1ZVR5cGVGb250KEZYX0lOVDMyIG5DaGFyc2V0KTsKKwl2aXJ0dWFsIEZYX0JPT0wJCQkJRmluZE5hdGl2ZVRydWVUeXBlRm9udChGWF9JTlQzMiBuQ2hhcnNldCwgQ0ZYX0J5dGVTdHJpbmcgc0ZvbnRGYWNlTmFtZSk7CisJdmlydHVhbCBDUERGX0ZvbnQqCQkJQWRkTmF0aXZlVHJ1ZVR5cGVGb250VG9QREYoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcgc0ZvbnRGYWNlTmFtZSwgRlhfQllURSBuQ2hhcnNldCk7CisKKwl2aXJ0dWFsIEZYX0lOVDMyCQkJU2V0VGltZXIoRlhfSU5UMzIgdUVsYXBzZSwgVGltZXJDYWxsYmFjayBscFRpbWVyRnVuYykgOworCXZpcnR1YWwgdm9pZAkJCQlLaWxsVGltZXIoRlhfSU5UMzIgbklEKSA7CisKKworCXZpcnR1YWwgRlhfQk9PTAkJCQlJc1NISUZUS2V5RG93bihGWF9EV09SRCBuRmxhZykge3JldHVybiBtX3BFbnYtPkZGSV9Jc1NISUZUS2V5RG93bihuRmxhZyk7fQorCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0NUUkxLZXlEb3duKEZYX0RXT1JEIG5GbGFnKSB7cmV0dXJuIG1fcEVudi0+RkZJX0lzQ1RSTEtleURvd24obkZsYWcpO30KKwl2aXJ0dWFsIEZYX0JPT0wJCQkJSXNBTFRLZXlEb3duKEZYX0RXT1JEIG5GbGFnKSB7cmV0dXJuIG1fcEVudi0+RkZJX0lzQUxUS2V5RG93bihuRmxhZyk7fQorCXZpcnR1YWwgRlhfQk9PTAkJCQlJc0lOU0VSVEtleURvd24oRlhfRFdPUkQgbkZsYWcpIHtyZXR1cm4gbV9wRW52LT5GRklfSXNJTlNFUlRLZXlEb3duKG5GbGFnKTt9CisKKwl2aXJ0dWFsCUZYX1NZU1RFTVRJTUUJCUdldExvY2FsVGltZSgpOworCisJdmlydHVhbCBGWF9JTlQzMgkJCUdldENoYXJTZXQoKSB7cmV0dXJuIG1fbkNoYXJTZXQ7fQorCXZpcnR1YWwgdm9pZCAJCQkJU2V0Q2hhclNldChGWF9JTlQzMiBuQ2hhclNldCkge21fbkNoYXJTZXQgPSBuQ2hhclNldDt9Citwcml2YXRlOgorCUNQREZEb2NfRW52aXJvbm1lbnQqIG1fcEVudjsKKwlpbnQJCW1fbkNoYXJTZXQ7Cit9OworCit2b2lkIENGWF9TeXN0ZW1IYW5kbGVyOjpTZXRDdXJzb3IoRlhfSU5UMzIgbkN1cnNvclR5cGUpCit7CisKKwltX3BFbnYtPkZGSV9TZXRDdXJzb3IobkN1cnNvclR5cGUpOworfQorCit2b2lkIENGWF9TeXN0ZW1IYW5kbGVyOjpJbnZhbGlkYXRlUmVjdChGWF9IV05EIGhXbmQsIEZYX1JFQ1QgcmVjdCkKK3sKKwkvL2dfcEZvcm1GaWxsQXBwLT5GRklfSW52YWxpZGF0ZSgpOworCUNQREZTREtfQW5ub3QqIHBTREtBbm5vdCA9IChDUERGU0RLX0Fubm90KiloV25kOworCUNQREZfUGFnZSogcFBhZ2UgPSBOVUxMOworCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IE5VTEw7CisJcFBhZ2VWaWV3ID0gcFNES0Fubm90LT5HZXRQYWdlVmlldygpOworCXBQYWdlID0gcFNES0Fubm90LT5HZXRQREZQYWdlKCk7CisJaWYoIXBQYWdlIHx8ICFwUGFnZVZpZXcpCisJCXJldHVybjsKKwlDUERGX01hdHJpeCBwYWdlMmRldmljZTsKKwlwUGFnZVZpZXctPkdldEN1cnJlbnRNYXRyaXgocGFnZTJkZXZpY2UpOworCUNQREZfTWF0cml4IGRldmljZTJwYWdlOworCWRldmljZTJwYWdlLlNldFJldmVyc2UocGFnZTJkZXZpY2UpOworCUZYX0ZMT0FUIGxlZnQsIHRvcCwgcmlnaHQsYm90dG9tOworCWRldmljZTJwYWdlLlRyYW5zZm9ybSgoRlhfRkxPQVQpcmVjdC5sZWZ0LCAoRlhfRkxPQVQpcmVjdC50b3AsIGxlZnQsIHRvcCk7CisJZGV2aWNlMnBhZ2UuVHJhbnNmb3JtKChGWF9GTE9BVClyZWN0LnJpZ2h0LCAoRlhfRkxPQVQpcmVjdC5ib3R0b20sIHJpZ2h0LCBib3R0b20pOworLy8gCW1fcEVudi0+RkZJX0RldmljZVRvUGFnZShwUGFnZSwgcmVjdC5sZWZ0LCByZWN0LnRvcCwgKGRvdWJsZSopJmxlZnQsIChkb3VibGUqKSZ0b3ApOworLy8gCW1fcEVudi0+RkZJX0RldmljZVRvUGFnZShwUGFnZSwgcmVjdC5yaWdodCwgcmVjdC5ib3R0b20sIChkb3VibGUqKSZyaWdodCwgKGRvdWJsZSopJmJvdHRvbSk7CisJQ1BERl9SZWN0IHJjUERGKGxlZnQsIGJvdHRvbSwgcmlnaHQsIHRvcCk7CisJcmNQREYuTm9ybWFsaXplKCk7CisKKwltX3BFbnYtPkZGSV9JbnZhbGlkYXRlKHBQYWdlLCByY1BERi5sZWZ0LCByY1BERi50b3AsIHJjUERGLnJpZ2h0LCByY1BERi5ib3R0b20pOworfQordm9pZCBDRlhfU3lzdGVtSGFuZGxlcjo6T3V0cHV0U2VsZWN0ZWRSZWN0KHZvaWQqIHBGb3JtRmlsbGVyLCBDUERGX1JlY3QmIHJlY3QpCit7CisJQ0ZGTF9Gb3JtRmlsbGVyKiBwRkZMID0gKENGRkxfRm9ybUZpbGxlciopcEZvcm1GaWxsZXI7CisJaWYocEZGTCkKKwl7CisJCUNQREZfUG9pbnQgbGVmdGJvdHRvbSA9IENQREZfUG9pbnQocmVjdC5sZWZ0LCByZWN0LmJvdHRvbSk7CisJCUNQREZfUG9pbnQgcmlnaHR0b3AgPSBDUERGX1BvaW50KHJlY3QucmlnaHQsIHJlY3QudG9wKTsKKwkJQ1BERl9Qb2ludCBwdEEgPSBwRkZMLT5QV0x0b0ZGTChsZWZ0Ym90dG9tKTsKKwkJQ1BERl9Qb2ludCBwdEIgPSBwRkZMLT5QV0x0b0ZGTChyaWdodHRvcCk7CQorCisKKwkJQ1BERlNES19Bbm5vdCogcEFubm90ICA9IHBGRkwtPkdldFNES0Fubm90KCk7CisJCUFTU0VSVChwQW5ub3QpOworCQlDUERGX1BhZ2UqIHBQYWdlID0gcEFubm90LT5HZXRQREZQYWdlKCk7CisJCUFTU0VSVChwUGFnZSk7CisJCW1fcEVudi0+RkZJX091dHB1dFNlbGVjdGVkUmVjdChwUGFnZSwgcHRBLngsIHB0Qi55LCBwdEIueCwgcHRBLnkpOworCX0KKwkKK30KKworRlhfQk9PTCBDRlhfU3lzdGVtSGFuZGxlcjo6SXNTZWxlY3Rpb25JbXBsZW1lbnRlZCgpCit7CisJaWYobV9wRW52KQorCXsKKwkJRlBERl9GT1JNRklMTElORk8qIHBJbmZvID0gbV9wRW52LT5HZXRGb3JtRmlsbEluZm8oKTsKKwkJaWYocEluZm8gJiYgcEluZm8tPkZGSV9PdXRwdXRTZWxlY3RlZFJlY3QpCisJCQlyZXR1cm4gVFJVRTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitDRlhfQnl0ZVN0cmluZyBDRlhfU3lzdGVtSGFuZGxlcjo6R2V0TmF0aXZlVHJ1ZVR5cGVGb250KEZYX0lOVDMyIG5DaGFyc2V0KQoreworCXJldHVybiAiIjsKK30KKworRlhfQk9PTAlDRlhfU3lzdGVtSGFuZGxlcjo6RmluZE5hdGl2ZVRydWVUeXBlRm9udChGWF9JTlQzMiBuQ2hhcnNldCwgQ0ZYX0J5dGVTdHJpbmcgc0ZvbnRGYWNlTmFtZSkgCit7CisJQ0ZYX0ZvbnRNZ3IqIHBGb250TWdyID0gQ0ZYX0dFTW9kdWxlOjpHZXQoKS0+R2V0Rm9udE1ncigpOworLy8JRlhGVF9GYWNlIG5GYWNlID0gcEZvbnRNZ3ItPkZpbmRTdWJzdEZvbnQoc0ZvbnRGYWNlTmFtZSxUUlVFLDAsMCwwLDAsTlVMTCk7CisvLwlGWEZUX0ZhY2UgbkZhY2UgID0gcEZvbnRNZ3ItPm1fcEJ1aWx0aW5NYXBwZXItPkZpbmRTdWJzdEZvbnQoc0ZvbnRGYWNlTmFtZSxUUlVFLDAsMCwwLDAsTlVMTCk7CisKKwlpZihwRm9udE1ncikKKwl7CisJCUNGWF9Gb250TWFwcGVyKglwRm9udE1hcHBlciA9IHBGb250TWdyLT5tX3BCdWlsdGluTWFwcGVyOworCQlpZihwRm9udE1hcHBlcikKKwkJewkKKwkJCWludCBuU2l6ZSA9IHBGb250TWFwcGVyLT5tX0luc3RhbGxlZFRURm9udHMuR2V0U2l6ZSgpOworCQkJaWYoblNpemUgPT0wKQorCQkJeworCQkJCXBGb250TWFwcGVyLT5Mb2FkSW5zdGFsbGVkRm9udHMoKTsKKwkJCQluU2l6ZSA9IHBGb250TWFwcGVyLT5tX0luc3RhbGxlZFRURm9udHMuR2V0U2l6ZSgpOworCQkJfQorCQkJCisJCQlmb3IoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQorCQkJeworCQkJCWlmKHBGb250TWFwcGVyLT5tX0luc3RhbGxlZFRURm9udHNbaV0uQ29tcGFyZShzRm9udEZhY2VOYW1lKSkKKwkJCQkJcmV0dXJuIFRSVUU7CisJCQl9CisJCX0KKworCX0KKworCXJldHVybiBGQUxTRTsKKy8vIAlwRm9udE1nci0+bV9GYWNlTWFwLkxvb2t1cChzRm9udEZhY2VOYW1lLHBGb250KTsKKy8vIAlyZXR1cm4gKHBGb250IT1OVUxMKTsKK30KKworc3RhdGljIGludCBDaGFyU2V0MkNQKGludCBjaGFyc2V0KQoreworCWlmKGNoYXJzZXQgPT0gMTI4KQorCQlyZXR1cm4gOTMyOworCWVsc2UgaWYoY2hhcnNldCA9PSAxMzQpCisJCXJldHVybiA5MzY7CisJZWxzZSBpZihjaGFyc2V0ID09IDEyOSkKKwkJcmV0dXJuIDk0OTsKKwllbHNlIGlmKGNoYXJzZXQgPT0gMTM2KQorCQlyZXR1cm4gOTUwOworCXJldHVybiAwOworfQorQ1BERl9Gb250KiBDRlhfU3lzdGVtSGFuZGxlcjo6QWRkTmF0aXZlVHJ1ZVR5cGVGb250VG9QREYoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcgc0ZvbnRGYWNlTmFtZSwgCisJCQkJCQkJCQkJCQkJCSBGWF9CWVRFIG5DaGFyc2V0KSAKK3sKKwlpZihwRG9jKQorCXsKKwkJQ0ZYX0ZvbnQqIHBGWEZvbnQgPSBuZXcgQ0ZYX0ZvbnQoKTsKKwkJcEZYRm9udC0+TG9hZFN1YnN0KHNGb250RmFjZU5hbWUsVFJVRSwwLDAsMCxDaGFyU2V0MkNQKG5DaGFyc2V0KSxGQUxTRSk7CisJCUNQREZfRm9udCogcEZvbnQgPSBwRG9jLT5BZGRGb250KHBGWEZvbnQsbkNoYXJzZXQsRkFMU0UpOworCQlkZWxldGUgcEZYRm9udDsKKwkJcmV0dXJuIHBGb250OworCX0KKworCXJldHVybiBOVUxMOworfQorCisKK0ZYX0lOVDMyIENGWF9TeXN0ZW1IYW5kbGVyOjpTZXRUaW1lcihGWF9JTlQzMiB1RWxhcHNlLCBUaW1lckNhbGxiYWNrIGxwVGltZXJGdW5jKQoreworCXJldHVybiBtX3BFbnYtPkZGSV9TZXRUaW1lcih1RWxhcHNlLCBscFRpbWVyRnVuYyk7Cit9Cit2b2lkIENGWF9TeXN0ZW1IYW5kbGVyOjpLaWxsVGltZXIoRlhfSU5UMzIgbklEKQoreworCW1fcEVudi0+RkZJX0tpbGxUaW1lcihuSUQpOworfQorCitGWF9TWVNURU1USU1FIENGWF9TeXN0ZW1IYW5kbGVyOjpHZXRMb2NhbFRpbWUoKQoreworCXJldHVybiBtX3BFbnYtPkZGSV9HZXRMb2NhbFRpbWUoKTsKK30KKworCitDSlNfUnVudGltZUZhY3RvcnkqIEdldEpTUnVudGltZUZhY3RvcnkoKQoreworCXN0YXRpYyBDSlNfUnVudGltZUZhY3Rvcnkgc19KU1J1bnRpbWVGYWN0b3J5OworCXJldHVybiAmc19KU1J1bnRpbWVGYWN0b3J5OworfQorCitDUERGRG9jX0Vudmlyb25tZW50OjpDUERGRG9jX0Vudmlyb25tZW50KENQREZfRG9jdW1lbnQgKiBwRG9jKTptX3BJbmZvKE5VTEwpLG1fcElGb3JtRmlsbGVyKE5VTEwpLAorCQkJCQkJCQltX3BBbm5vdEhhbmRsZXJNZ3IoTlVMTCksbV9wQWN0aW9uSGFuZGxlcihOVUxMKSxtX3BKU1J1bnRpbWUoTlVMTCksCisJCQkJCQkJCW1fcFNES0RvYyhOVUxMKSwgbV9wUERGRG9jKHBEb2MpCit7CisKKwltX3BTeXNIYW5kbGVyID0gTlVMTDsKKwltX3BTeXNIYW5kbGVyID0gbmV3IENGWF9TeXN0ZW1IYW5kbGVyKHRoaXMpOworCisJCisJbV9wSlNSdW50aW1lRmFjdG9yeSA9IE5VTEw7CisJbV9wSlNSdW50aW1lRmFjdG9yeSA9IEdldEpTUnVudGltZUZhY3RvcnkoKTsKKwltX3BKU1J1bnRpbWVGYWN0b3J5LT5BZGRSZWYoKTsKK30KKworQ1BERkRvY19FbnZpcm9ubWVudDo6fkNQREZEb2NfRW52aXJvbm1lbnQoKQoreworCisJaWYgKCBtX3BJRm9ybUZpbGxlciApCisJeworCQlkZWxldGUgbV9wSUZvcm1GaWxsZXI7CisJCW1fcElGb3JtRmlsbGVyID0gTlVMTDsKKwl9CisJaWYobV9wSlNSdW50aW1lICYmIG1fcEpTUnVudGltZUZhY3RvcnkpCisJCW1fcEpTUnVudGltZUZhY3RvcnktPkRlbGV0ZUpTUnVudGltZShtX3BKU1J1bnRpbWUpOworCW1fcEpTUnVudGltZUZhY3RvcnktPlJlbGVhc2UoKTsKKworCWlmKG1fcFN5c0hhbmRsZXIpCisJeworCQlkZWxldGUgbV9wU3lzSGFuZGxlcjsKKwkJbV9wU3lzSGFuZGxlciA9IE5VTEw7CisJfQorCisJaWYobV9wQW5ub3RIYW5kbGVyTWdyKQorCXsKKwkJZGVsZXRlIG1fcEFubm90SGFuZGxlck1ncjsKKwkJbV9wQW5ub3RIYW5kbGVyTWdyID0gTlVMTDsKKwl9CisJaWYobV9wQWN0aW9uSGFuZGxlcikKKwl7CisJCWRlbGV0ZSBtX3BBY3Rpb25IYW5kbGVyOworCQltX3BBY3Rpb25IYW5kbGVyID0gTlVMTDsKKwl9CisKKworfQorCisKK0lGWEpTX1J1bnRpbWUqIENQREZEb2NfRW52aXJvbm1lbnQ6OkdldEpTUnVudGltZSgpCit7CisJaWYoIUlzSlNJbml0aWF0ZWQoKSkKKwkJcmV0dXJuIE5VTEw7CisJYXNzZXJ0KG1fcEpTUnVudGltZUZhY3RvcnkpOworCWlmKCFtX3BKU1J1bnRpbWUpCisJCW1fcEpTUnVudGltZSA9IG1fcEpTUnVudGltZUZhY3RvcnktPk5ld0pTUnVudGltZSh0aGlzKTsKKwlyZXR1cm4gbV9wSlNSdW50aW1lOworfQorCitDUERGU0RLX0Fubm90SGFuZGxlck1nciogQ1BERkRvY19FbnZpcm9ubWVudDo6R2V0QW5ub3RIYW5kbGVyTWdyKCkKK3sKKwlpZighbV9wQW5ub3RIYW5kbGVyTWdyKQorCQltX3BBbm5vdEhhbmRsZXJNZ3IgPSBuZXcgQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IodGhpcyk7CisJcmV0dXJuIG1fcEFubm90SGFuZGxlck1ncjsKK30KKworQ1BERlNES19BY3Rpb25IYW5kbGVyKiBDUERGRG9jX0Vudmlyb25tZW50OjpHZXRBY3Rpb25IYW5kZXIoKQoreworCWlmKCFtX3BBY3Rpb25IYW5kbGVyKQorCQltX3BBY3Rpb25IYW5kbGVyID0gbmV3IENQREZTREtfQWN0aW9uSGFuZGxlcih0aGlzKTsKKwlyZXR1cm4gbV9wQWN0aW9uSGFuZGxlcjsKK30KKworaW50IENQREZEb2NfRW52aXJvbm1lbnQ6OlJlZ0FwcEhhbmRsZShGUERGX0ZPUk1GSUxMSU5GTyogcEZGaW5mbykKK3sKKwltX3BJbmZvICA9IHBGRmluZm87IAorCXJldHVybiBUUlVFOworfQorCitDUERGU0RLX0RvY3VtZW50KiBDUERGRG9jX0Vudmlyb25tZW50OjpHZXRDdXJyZW50RG9jKCkKK3sKKwlyZXR1cm4gbV9wU0RLRG9jOworfQorCitDRkZMX0lGb3JtRmlsbGVyKiBDUERGRG9jX0Vudmlyb25tZW50OjpHZXRJRm9ybUZpbGxlcigpCit7CisJaWYoIW1fcElGb3JtRmlsbGVyKQorCQltX3BJRm9ybUZpbGxlciA9IG5ldyBDRkZMX0lGb3JtRmlsbGVyKHRoaXMpOworCXJldHVybiBtX3BJRm9ybUZpbGxlcjsKK30KKworRlhfQk9PTAlDUERGRG9jX0Vudmlyb25tZW50OjpJc0pTSW5pdGlhdGVkKCkKK3sKKwlpZihtX3BJbmZvKQorCXsKKwkJaWYobV9wSW5mby0+bV9wSnNQbGF0Zm9ybSkKKwkJCXJldHVybiBUUlVFOworCQllbHNlCisJCQlyZXR1cm4gRkFMU0U7CisJfQorCXJldHVybiBGQUxTRTsKK30KKworQ1BERlNES19Eb2N1bWVudDo6Q1BERlNES19Eb2N1bWVudChDUERGX0RvY3VtZW50KiBwRG9jLENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYpOm1fcERvYyhwRG9jKSwKKwkJCQkJCW1fcEludGVyRm9ybShOVUxMKSxtX3BFbnYocEVudiksbV9wT2Njb250ZW50KE5VTEwpLG1fYkNoYW5nZU1hc2soRkFMU0UpCit7CisJbV9wRm9jdXNBbm5vdCA9IE5VTEw7Cit9CisKK0NQREZTREtfRG9jdW1lbnQ6On5DUERGU0RLX0RvY3VtZW50KCkKK3sKKwltX3BhZ2VNYXAuUmVtb3ZlQWxsKCk7CisJaWYobV9wSW50ZXJGb3JtKQorCXsKKwkJbV9wSW50ZXJGb3JtLT5EZXN0cm95KCk7CisJCW1fcEludGVyRm9ybSA9IE5VTEw7CisJfQorCWlmKG1fcE9jY29udGVudCkKKwl7CisJCWRlbGV0ZSBtX3BPY2NvbnRlbnQ7CisJCW1fcE9jY29udGVudCA9IE5VTEw7CisJfQorfQorCit2b2lkIENQREZTREtfRG9jdW1lbnQ6OkluaXRQYWdlVmlldygpCit7CisJaW50IG5Db3VudCA9IG1fcERvYy0+R2V0UGFnZUNvdW50KCk7CisJZm9yKGludCBpPTA7IGk8bkNvdW50OyBpKyspCisJeworCS8vIFRvIGRvCisvLwkJQ1BERl9EaWN0aW9uYXJ5KiBwRGljID0gbV9wRG9jLT5HZXRQYWdlKGkpOworLy8JCW1fcGFnZU1hcC5TZXRBdChwRGljLCBwUGFnZVZpZXcpOworCX0KK30KKwordm9pZCBDUERGU0RLX0RvY3VtZW50OjpBZGRQYWdlVmlldyhDUERGX1BhZ2UqIHBQREZQYWdlLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcpCit7CisJbV9wYWdlTWFwLlNldEF0KHBQREZQYWdlLCBwUGFnZVZpZXcpOworfQorCitDUERGU0RLX1BhZ2VWaWV3KiBDUERGU0RLX0RvY3VtZW50OjpHZXRQYWdlVmlldyhDUERGX1BhZ2UqIHBQREZQYWdlLCBGWF9CT09MIFJlTmV3KQoreworCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IChDUERGU0RLX1BhZ2VWaWV3KiltX3BhZ2VNYXAuR2V0VmFsdWVBdChwUERGUGFnZSk7CisJaWYocFBhZ2VWaWV3ICE9IE5VTEwpCisJCXJldHVybiBwUGFnZVZpZXc7CisJaWYoUmVOZXcpCisJeworCQlwUGFnZVZpZXcgPSBuZXcgQ1BERlNES19QYWdlVmlldyh0aGlzLHBQREZQYWdlKTsKKwkJbV9wYWdlTWFwLlNldEF0KHBQREZQYWdlLCBwUGFnZVZpZXcpOworCQkvL0RlbGF5IHRvIGxvYWQgYWxsIHRoZSBhbm5vdGF0aW9ucywgdG8gYXZvaWQgZW5kbGVzcyBsb29wLgorCQlwUGFnZVZpZXctPkxvYWRGWEFubm90cygpOworCX0KKwlyZXR1cm4gcFBhZ2VWaWV3OworCit9CisKK0NQREZTREtfUGFnZVZpZXcqIENQREZTREtfRG9jdW1lbnQ6OkdldEN1cnJlbnRWaWV3KCkKK3sKKwlDUERGX1BhZ2UgKiBwUGFnZSA9IChDUERGX1BhZ2UgKiltX3BFbnYtPkZGSV9HZXRDdXJyZW50UGFnZShtX3BEb2MpOworCWlmKHBQYWdlKQorCQlyZXR1cm4gdGhpcy0+R2V0UGFnZVZpZXcocFBhZ2UsIFRSVUUpOworCXJldHVybiBOVUxMOworfQorCitDUERGU0RLX1BhZ2VWaWV3KiBDUERGU0RLX0RvY3VtZW50OjpHZXRQYWdlVmlldyhpbnQgbkluZGV4KQoreworCUNQREZTREtfUGFnZVZpZXcgKiBwVGVtcFBhZ2VWaWV3ID0gTlVMTDsKKwlDUERGX1BhZ2UgKiBwVGVtcFBhZ2UgPSAoQ1BERl9QYWdlKiltX3BFbnYtPkZGSV9HZXRQYWdlKG1fcERvYyxuSW5kZXgpOworCWlmKCFwVGVtcFBhZ2UpCisJCXJldHVybiBOVUxMOworCisJbV9wYWdlTWFwLkxvb2t1cChwVGVtcFBhZ2UsIHBUZW1wUGFnZVZpZXcpOworCQorCUFTU0VSVChwVGVtcFBhZ2VWaWV3ICE9IE5VTEwpOworCQorCXJldHVybiBwVGVtcFBhZ2VWaWV3OworfQorCit2b2lkIENQREZTREtfRG9jdW1lbnQ6OiBQcm9jSmF2YXNjcmlwdEZ1bigpCit7CisJQ1BERl9Eb2N1bWVudCogcFBERkRvYyA9IHRoaXMtPkdldERvY3VtZW50KCk7CisJQ1BERl9Eb2NKU0FjdGlvbnMgZG9jSlMocFBERkRvYyk7CisJaW50IGlDb3VudCA9IGRvY0pTLkNvdW50SlNBY3Rpb25zKCk7CisJaWYgKGlDb3VudCA8IDEpIHJldHVybjsKKwlmb3IgKGludCBpID0gMDsgaSA8IGlDb3VudDsgaSArKykKKwl7CisJCUNGWF9CeXRlU3RyaW5nIGNzSlNOYW1lOworCQlDUERGX0FjdGlvbiBqc0FjdGlvbiA9IGRvY0pTLkdldEpTQWN0aW9uKGksIGNzSlNOYW1lKTsKKwkJaWYobV9wRW52LT5HZXRBY3Rpb25IYW5kZXIoKSkKKwkJCW1fcEVudi0+R2V0QWN0aW9uSGFuZGVyKCktPkRvQWN0aW9uX0phdmFTY3JpcHQoanNBY3Rpb24sQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChjc0pTTmFtZSksdGhpcyk7CisJfQorCQorfQorCitGWF9CT09MIENQREZTREtfRG9jdW1lbnQ6OlByb2NPcGVuQWN0aW9uKCkKK3sKKwlpZighbV9wRG9jKSByZXR1cm4gRkFMU0U7CisJCisJQ1BERl9EaWN0aW9uYXJ5KiBwUm9vdCA9IG1fcERvYy0+R2V0Um9vdCgpOwkKKwlpZiAoIXBSb290KQlyZXR1cm4gRkFMU0U7CisJQ1BERl9PYmplY3QqIHBPcGVuQWN0aW9uID0gcFJvb3QtPkdldERpY3QoIk9wZW5BY3Rpb24iKTsvLworCWlmKCFwT3BlbkFjdGlvbikgcE9wZW5BY3Rpb24gPSBwUm9vdC0+R2V0QXJyYXkoIk9wZW5BY3Rpb24iKTsvLworCWlmKCFwT3BlbkFjdGlvbikgcmV0dXJuIEZBTFNFOworCQorCWlmKHBPcGVuQWN0aW9uLT5HZXRUeXBlKCk9PVBERk9CSl9BUlJBWSkKKwl7CQorCX0KKwllbHNlIGlmKHBPcGVuQWN0aW9uLT5HZXRUeXBlKCk9PVBERk9CSl9ESUNUSU9OQVJZKQorCXsJCisJCUNQREZfRGljdGlvbmFyeSAqIHBEaWN0PShDUERGX0RpY3Rpb25hcnkqKXBPcGVuQWN0aW9uOwkKKwkJQ1BERl9BY3Rpb24gQWN0aW9uID0gcERpY3Q7CisJCQorCQlpZihtX3BFbnYtPkdldEFjdGlvbkhhbmRlcigpKQorCQkJbV9wRW52LT5HZXRBY3Rpb25IYW5kZXIoKS0+RG9BY3Rpb25fRG9jT3BlbihBY3Rpb24sdGhpcyk7CQkKKwl9CQorCWVsc2UKKwl7CisJCXJldHVybiBGQUxTRTsJCQkKKwl9CQorCXJldHVybiBUUlVFOworfQorCitDUERGX09DQ29udGV4dCoJQ1BERlNES19Eb2N1bWVudDo6R2V0T0NDb250ZXh0KCkKK3sKKwlpZighbV9wT2Njb250ZW50KQorCQltX3BPY2NvbnRlbnQgPSBuZXcgQ1BERl9PQ0NvbnRleHQobV9wRG9jKTsKKwlyZXR1cm4gbV9wT2Njb250ZW50OworfQorCit2b2lkIENQREZTREtfRG9jdW1lbnQ6OlJlTW92ZVBhZ2VWaWV3KENQREZfUGFnZSogcFBERlBhZ2UpCit7CisJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gKENQREZTREtfUGFnZVZpZXcqKW1fcGFnZU1hcC5HZXRWYWx1ZUF0KHBQREZQYWdlKTsKKwlpZihwUGFnZVZpZXcpCisJeworCQlkZWxldGUgcFBhZ2VWaWV3OworCQltX3BhZ2VNYXAuUmVtb3ZlS2V5KHBQREZQYWdlKTsKKwl9Cit9CisKK0NQREZfUGFnZSAqIENQREZTREtfRG9jdW1lbnQ6OkdldFBhZ2UoaW50IG5JbmRleCkKK3sKKwlDUERGX1BhZ2UgKiBwVGVtcFBhZ2UgPSAoQ1BERl9QYWdlKiltX3BFbnYtPkZGSV9HZXRQYWdlKG1fcERvYyxuSW5kZXgpOworCWlmKCFwVGVtcFBhZ2UpCisJCXJldHVybiBOVUxMOworCXJldHVybiBwVGVtcFBhZ2U7Cit9CisKK0NQREZTREtfSW50ZXJGb3JtKiBDUERGU0RLX0RvY3VtZW50OjpHZXRJbnRlckZvcm0oKQoreworCWlmKCFtX3BJbnRlckZvcm0pCisJCW1fcEludGVyRm9ybSA9IG5ldyBDUERGU0RLX0ludGVyRm9ybSh0aGlzKTsKKwlyZXR1cm4gbV9wSW50ZXJGb3JtOworfQorCit2b2lkIENQREZTREtfRG9jdW1lbnQ6OlVwZGF0ZUFsbFZpZXdzKENQREZTREtfUGFnZVZpZXcqIHBTZW5kZXIsIENQREZTREtfQW5ub3QqIHBBbm5vdCkKK3sKKwkKKwlGWF9QT1NJVElPTiBwb3MgPSBtX3BhZ2VNYXAuR2V0U3RhcnRQb3NpdGlvbigpOworCUNQREZfUGFnZSAqIHBQYWdlID0gTlVMTDsKKwlDUERGU0RLX1BhZ2VWaWV3ICogcFBhZ2VWaWV3ID0gTlVMTDsKKwl3aGlsZShwb3MpCisJeworCQltX3BhZ2VNYXAuR2V0TmV4dEFzc29jKHBvcywgcFBhZ2UsIHBQYWdlVmlldyk7CisKKwkJaWYocFBhZ2VWaWV3ICE9IHBTZW5kZXIpCisJCXsKKwkJCXBQYWdlVmlldy0+VXBkYXRlVmlldyhwQW5ub3QpOworCQl9CisJfQorfQorCitDUERGU0RLX0Fubm90KiBDUERGU0RLX0RvY3VtZW50OjpHZXRGb2N1c0Fubm90KCkKK3sKKwlyZXR1cm4gdGhpcy0+bV9wRm9jdXNBbm5vdDsJCit9CisKK0ZYX0JPT0wgQ1BERlNES19Eb2N1bWVudDo6U2V0Rm9jdXNBbm5vdChDUERGU0RLX0Fubm90KiBwQW5ub3QsRlhfVUlOVCBuRmxhZykKK3sKKworCWlmKG1fcEZvY3VzQW5ub3Q9PXBBbm5vdCkgcmV0dXJuIFRSVUU7CisJCisJaWYobV9wRm9jdXNBbm5vdCkKKwl7CisJCWlmKCF0aGlzLT5LaWxsRm9jdXNBbm5vdChuRmxhZykgKSByZXR1cm4gRkFMU0U7CQorCX0KKwlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBwQW5ub3QtPkdldFBhZ2VWaWV3KCk7CisJaWYocEFubm90ICYmIHBQYWdlVmlldy0+SXNWYWxpZCgpKQorCXsKKwkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IgKnBBbm5vdEhhbmRsZXI9bV9wRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsKKworCQlpZihwQW5ub3RIYW5kbGVyJiYhbV9wRm9jdXNBbm5vdCkKKwkJeworCQkJaWYgKCFwQW5ub3RIYW5kbGVyLT5Bbm5vdF9PblNldEZvY3VzKHBBbm5vdCxuRmxhZykpCisJCQkJcmV0dXJuIEZBTFNFOworCQkJaWYoIW1fcEZvY3VzQW5ub3QpCisJCQl7CisJCQkJdGhpcy0+bV9wRm9jdXNBbm5vdD1wQW5ub3Q7CisJCQkJcmV0dXJuIFRSVUU7CisJCQl9CisJCX0JCQkKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENQREZTREtfRG9jdW1lbnQ6OktpbGxGb2N1c0Fubm90KEZYX1VJTlQgbkZsYWcpCit7CisJaWYobV9wRm9jdXNBbm5vdCkKKwl7CisJCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyICpwQW5ub3RIYW5kbGVyPW1fcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7CisJCWlmKHBBbm5vdEhhbmRsZXIpCisJCXsKKwkJCUNQREZTREtfQW5ub3QqIHBGb2N1c0Fubm90ID0gbV9wRm9jdXNBbm5vdDsKKwkJCW1fcEZvY3VzQW5ub3QgPSBOVUxMOworCQkJaWYocEFubm90SGFuZGxlci0+QW5ub3RfT25LaWxsRm9jdXMocEZvY3VzQW5ub3QsIG5GbGFnKSkKKwkJCXsKKwkJCQkKKwkJCQlpZihwRm9jdXNBbm5vdC0+R2V0VHlwZSgpID09IEZYX0JTVFJDKCJXaWRnZXQiKSkKKwkJCQl7CisJCQkJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwRm9jdXNBbm5vdDsKKwkJCQkJaW50IG5GaWVsZFR5cGUgPSBwV2lkZ2V0LT5HZXRGaWVsZFR5cGUoKTsKKwkJCQkJaWYoRklFTERUWVBFX1RFWFRGSUVMRCA9PSBuRmllbGRUeXBlIHx8IEZJRUxEVFlQRV9DT01CT0JPWCA9PSBuRmllbGRUeXBlKQorCQkJCQkJbV9wRW52LT5GRklfT25TZXRGaWVsZElucHV0Rm9jdXMoTlVMTCwgTlVMTCwgMCwgRkFMU0UpOworCQkJCX0KKworCQkJCWlmKCFtX3BGb2N1c0Fubm90KQorCQkJCQlyZXR1cm4gVFJVRTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQltX3BGb2N1c0Fubm90ID0gcEZvY3VzQW5ub3Q7CisJCQl9CisJCX0KKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNQREZTREtfRG9jdW1lbnQ6OkRlbGV0ZVBhZ2VzKGludCBuU3RhcnQsIGludCAgbkNvdW50KQoreworCWlmICggblN0YXJ0IDwgMCB8fCBuU3RhcnQgPj0gR2V0UGFnZUNvdW50KCkgfHwgbkNvdW50IDw9IDAgKQorCXsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCUNQREZfUGFnZSAqIHBUZW1wUGFnZSA9IE5VTEw7CisJZm9yICggaW50IGkgPSBuQ291bnQtMTsgaSA+PSAwOyBpLS0gKQorCXsKKwkJcFRlbXBQYWdlID0gR2V0UGFnZShuU3RhcnQraSk7CisJCWlmICggcFRlbXBQYWdlICE9IE5VTEwgKQorCQl7CisJCQlSZU1vdmVQYWdlVmlldyhwVGVtcFBhZ2UpOworCQl9CisJfQorCXJldHVybiBUUlVFOworfQorCit2b2lkIENQREZTREtfRG9jdW1lbnQ6Ok9uQ2xvc2VEb2N1bWVudCgpCit7CisJS2lsbEZvY3VzQW5ub3QoKTsKK30KKworRlhfQk9PTCBDUERGU0RLX0RvY3VtZW50OjpHZXRQZXJtaXNzaW9ucyhpbnQgbkZsYWcpCit7CisJRlhfRFdPUkQgZHdQZXJtaXNzaW9ucyA9IG1fcERvYy0+R2V0VXNlclBlcm1pc3Npb25zKCk7CisJcmV0dXJuIGR3UGVybWlzc2lvbnMmbkZsYWc7Cit9CisKK0lGWEpTX1J1bnRpbWUgKiBDUERGU0RLX0RvY3VtZW50OjpHZXRKc1J1bnRpbWUoKQoreworCUFTU0VSVChtX3BFbnYhPU5VTEwpOworCXJldHVybiBtX3BFbnYtPkdldEpTUnVudGltZSgpOworfQorCitDRlhfV2lkZVN0cmluZwlDUERGU0RLX0RvY3VtZW50OjpHZXRQYXRoKCkgCit7CisJQVNTRVJUKG1fcEVudiAhPSBOVUxMKTsKKwlyZXR1cm4gbV9wRW52LT5KU19kb2NHZXRGaWxlUGF0aCgpOworfQorCisKK0NQREZTREtfUGFnZVZpZXc6OkNQREZTREtfUGFnZVZpZXcoQ1BERlNES19Eb2N1bWVudCogcFNES0RvYyxDUERGX1BhZ2UqIHBhZ2UpOm1fcFNES0RvYyhwU0RLRG9jKSxtX3BhZ2UocGFnZSkKK3sKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBTREtEb2MtPkdldEludGVyRm9ybSgpOworCWlmKHBJbnRlckZvcm0pCisJeworCQlDUERGX0ludGVyRm9ybSogcFBERkludGVyRm9ybSA9IHBJbnRlckZvcm0tPkdldEludGVyRm9ybSgpOworCQlwUERGSW50ZXJGb3JtLT5GaXhQYWdlRmllbGRzKHBhZ2UpOworCX0KKworCW1fZnhBbm5vdEFycmF5LlJlbW92ZUFsbCgpOworCisJbV9iRW50ZXJXaWRnZXQgPSBGQUxTRTsKKwltX2JFeGl0V2lkZ2V0ID0gRkFMU0U7CisJbV9iT25XaWRnZXQgPSBGQUxTRTsKKwltX0NhcHR1cmVXaWRnZXQgPSBOVUxMOworCW1fYlZhbGlkID0gRkFMU0U7Cit9CisKK0NQREZTREtfUGFnZVZpZXc6On5DUERGU0RLX1BhZ2VWaWV3KCkKK3sKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsJCisJaW50IG5Bbm5vdENvdW50ID0gbV9meEFubm90QXJyYXkuR2V0U2l6ZSgpOworCWZvciAoaW50IGk9MDsgaTxuQW5ub3RDb3VudDsgaSsrKQorCXsKKwkJQ1BERlNES19Bbm5vdCogcEFubm90ID0gKENQREZTREtfQW5ub3QqKW1fZnhBbm5vdEFycmF5LkdldEF0KGkpOworCQkvL2lmIHRoZXJlIGlzIGEgZm9jdXNlZCBhbm5vdCBvbiB0aGUgcGFnZSwgd2Ugc2hvdWxkIGtpbGwgdGhlIGZvY3VzIGZpcnN0LgorCQlpZihwQW5ub3QgPT0gbV9wU0RLRG9jLT5HZXRGb2N1c0Fubm90KCkpCisJCQlLaWxsRm9jdXNBbm5vdCgpOworCQlDUERGU0RLX0Fubm90SGFuZGxlck1nciogcEFubm90SGFuZGxlck1nciA9IHBFbnYtPkdldEFubm90SGFuZGxlck1ncigpOworCQlBU1NFUlQocEFubm90SGFuZGxlck1ncik7CisJCXBBbm5vdEhhbmRsZXJNZ3ItPlJlbGVhc2VBbm5vdChwQW5ub3QpOworCX0KKwltX2Z4QW5ub3RBcnJheS5SZW1vdmVBbGwoKTsKKwlpZihtX3BBbm5vdExpc3QpCisJeworCQlkZWxldGUgbV9wQW5ub3RMaXN0OworCQltX3BBbm5vdExpc3QgPSBOVUxMOworCX0KK30KKwordm9pZCBDUERGU0RLX1BhZ2VWaWV3OjpQYWdlVmlld19PbkRyYXcoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSxDUERGX1JlbmRlck9wdGlvbnMqIHBPcHRpb25zKQoreworCW1fY3VyTWF0cml4ID0gKnBVc2VyMkRldmljZTsKKwkKKwkvLwltX3BBbm5vdExpc3QtPkRpc3BsYXlBbm5vdHMobV9wYWdlLCBwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIEZBTFNFLCBwT3B0aW9ucyk7CisJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7CisJQ1BERlNES19Bbm5vdEl0ZXJhdG9yIGFubm90SXRlcmF0b3IodGhpcywgVFJVRSk7CisJQ1BERlNES19Bbm5vdCAqIHBTREtBbm5vdD1OVUxMOworCWludCBpbmRleD0tMTsKKwl3aGlsZSgocFNES0Fubm90ID0gYW5ub3RJdGVyYXRvci5OZXh0KGluZGV4KSkpCisJeworCQlDUERGU0RLX0Fubm90SGFuZGxlck1nciogcEFubm90SGFuZGxlck1nciA9IHBFbnYtPkdldEFubm90SGFuZGxlck1ncigpOworCQlBU1NFUlQocEFubm90SGFuZGxlck1ncik7CisJCXBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uRHJhdyh0aGlzLCBwU0RLQW5ub3QsIHBEZXZpY2UsIHBVc2VyMkRldmljZSwgMCk7CisJfQorCit9CisKK0NQREZfQW5ub3QqIENQREZTREtfUGFnZVZpZXc6OkdldFBERkFubm90QXRQb2ludChGWF9GTE9BVCBwYWdlWCwgRlhfRkxPQVQgcGFnZVkpCit7CisJCisJaW50IG5Db3VudCA9IG1fcEFubm90TGlzdC0+Q291bnQoKTsKKwlmb3IoaW50IGkgPSAwIDsgaTxuQ291bnQ7IGkrKykKKwl7CisJCUNQREZfQW5ub3QqIHBBbm5vdCA9IG1fcEFubm90TGlzdC0+R2V0QXQoaSk7CisJCUNGWF9GbG9hdFJlY3QgYW5ub3RSZWN0OworCQlwQW5ub3QtPkdldFJlY3QoYW5ub3RSZWN0KTsKKwkJaWYoYW5ub3RSZWN0LkNvbnRhaW5zKHBhZ2VYLCBwYWdlWSkpCisJCQlyZXR1cm4gcEFubm90OworCX0KKwlyZXR1cm4gTlVMTDsKK30KKworQ1BERl9Bbm5vdCogQ1BERlNES19QYWdlVmlldzo6R2V0UERGV2lkZ2V0QXRQb2ludChGWF9GTE9BVCBwYWdlWCwgRlhfRkxPQVQgcGFnZVkpCit7CisJCisJaW50IG5Db3VudCA9IG1fcEFubm90TGlzdC0+Q291bnQoKTsKKwlmb3IoaW50IGkgPSAwIDsgaTxuQ291bnQ7IGkrKykKKwl7CisJCUNQREZfQW5ub3QqIHBBbm5vdCA9IG1fcEFubm90TGlzdC0+R2V0QXQoaSk7CisJCWlmKHBBbm5vdC0+R2V0U3ViVHlwZSgpID09ICJXaWRnZXQiKQorCQl7CisJCQlDRlhfRmxvYXRSZWN0IGFubm90UmVjdDsKKwkJCXBBbm5vdC0+R2V0UmVjdChhbm5vdFJlY3QpOworCQkJaWYoYW5ub3RSZWN0LkNvbnRhaW5zKHBhZ2VYLCBwYWdlWSkpCisJCQkJcmV0dXJuIHBBbm5vdDsKKwkJfQorCX0KKwlyZXR1cm4gTlVMTDsKK30KKworQ1BERlNES19Bbm5vdCogQ1BERlNES19QYWdlVmlldzo6R2V0RlhBbm5vdEF0UG9pbnQoRlhfRkxPQVQgcGFnZVgsIEZYX0ZMT0FUIHBhZ2VZKQoreworCisJQ1BERlNES19Bbm5vdEl0ZXJhdG9yIGFubm90SXRlcmF0b3IodGhpcywgRkFMU0UpOworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOworCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RNZ3IgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsKKwlDUERGU0RLX0Fubm90KiBwU0RLQW5ub3QgPSBOVUxMOworCWludCBpbmRleCA9IC0xOworCXdoaWxlKChwU0RLQW5ub3QgPSBhbm5vdEl0ZXJhdG9yLk5leHQoaW5kZXgpKSkKKwl7CisJCUNQREZfUmVjdCByYyA9IHBBbm5vdE1nci0+QW5ub3RfT25HZXRWaWV3QkJveCh0aGlzLCBwU0RLQW5ub3QpOworCQlpZihyYy5Db250YWlucyhwYWdlWCwgcGFnZVkpKQorCQkJcmV0dXJuIHBTREtBbm5vdDsKKwl9CisKKwlyZXR1cm4gTlVMTDsKK30KKworQ1BERlNES19Bbm5vdCogQ1BERlNES19QYWdlVmlldzo6R2V0RlhXaWRnZXRBdFBvaW50KEZYX0ZMT0FUIHBhZ2VYLCBGWF9GTE9BVCBwYWdlWSkKK3sKKworCUNQREZTREtfQW5ub3RJdGVyYXRvciBhbm5vdEl0ZXJhdG9yKHRoaXMsIEZBTFNFKTsKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKKwlDUERGU0RLX0Fubm90SGFuZGxlck1nciogcEFubm90TWdyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7CisJQ1BERlNES19Bbm5vdCogcFNES0Fubm90ID0gTlVMTDsKKwlpbnQgaW5kZXggPSAtMTsKKwl3aGlsZSgocFNES0Fubm90ID0gYW5ub3RJdGVyYXRvci5OZXh0KGluZGV4KSkpCisJeworCQlpZihwU0RLQW5ub3QtPkdldFR5cGUoKSA9PSAiV2lkZ2V0IikKKwkJewkKKwkJCXBBbm5vdE1nci0+QW5ub3RfT25HZXRWaWV3QkJveCh0aGlzLCBwU0RLQW5ub3QpOworCQkJQ1BERl9Qb2ludCBwb2ludChwYWdlWCwgcGFnZVkpOworCQkJaWYgKHBBbm5vdE1nci0+QW5ub3RfT25IaXRUZXN0KHRoaXMsIHBTREtBbm5vdCwgcG9pbnQpKQorLy8JCQlpZihyYy5Db250YWlucyhwYWdlWCwgcGFnZVkpKQorCQkJCXJldHVybiBwU0RLQW5ub3Q7CisJCX0KKwl9CisJCisJcmV0dXJuIE5VTEw7Cit9CisKKworRlhfQk9PTCBDUERGU0RLX1BhZ2VWaWV3OjpBbm5vdF9IYXNBcHBlYXJhbmNlKENQREZfQW5ub3QqIHBBbm5vdCkKK3sKKwlDUERGX0RpY3Rpb25hcnkqIHBBbm5vdERpYyA9IHBBbm5vdC0+bV9wQW5ub3REaWN0OworCWlmKHBBbm5vdERpYykKKwkJcmV0dXJuCXBBbm5vdERpYy0+S2V5RXhpc3QoIkFTIik7CisJcmV0dXJuIEZBTFNFOworfQorCitDUERGU0RLX0Fubm90KglDUERGU0RLX1BhZ2VWaWV3OjpBZGRBbm5vdChDUERGX0Fubm90ICogcFBERkFubm90KQoreworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOworCUFTU0VSVChwRW52KTsKKwlDUERGU0RLX0Fubm90SGFuZGxlck1nciAqIHBBbm5vdEhhbmRsZXI9IHBFbnYtPkdldEFubm90SGFuZGxlck1ncigpOwkKKwkKKwlDUERGU0RLX0Fubm90KiBwU0RLQW5ub3QgPU5VTEw7CisJCisJaWYocEFubm90SGFuZGxlcikKKwl7CisJCXBTREtBbm5vdCA9IHBBbm5vdEhhbmRsZXItPk5ld0Fubm90KHBQREZBbm5vdCwgdGhpcyk7CisJfQorCWlmKCFwU0RLQW5ub3QpCSAKKwkJcmV0dXJuIE5VTEw7CisKKwltX2Z4QW5ub3RBcnJheS5BZGQocFNES0Fubm90KTsJCisJCQorCWlmKHBBbm5vdEhhbmRsZXIpCisJewkgCQkgCSAKKwkJcEFubm90SGFuZGxlci0+QW5ub3RfT25DcmVhdGUocFNES0Fubm90KTsKKwkJCisJfQorCisJIHJldHVybiBwU0RLQW5ub3Q7Cit9CisKK0NQREZTREtfQW5ub3QqIENQREZTREtfUGFnZVZpZXc6OkFkZEFubm90KENQREZfRGljdGlvbmFyeSAqIHBEaWN0KQoreworCWlmKHBEaWN0KSAgCisJCXJldHVybiB0aGlzLT5BZGRBbm5vdChwRGljdC0+R2V0U3RyaW5nKCJTdWJ0eXBlIikscERpY3QpOworCSByZXR1cm4gTlVMTDsKK30KKworQ1BERlNES19Bbm5vdCogQ1BERlNES19QYWdlVmlldzo6QWRkQW5ub3QoRlhfTFBDU1RSIGxwU3ViVHlwZSxDUERGX0RpY3Rpb25hcnkgKiBwRGljdCkKK3sKKwlyZXR1cm4gTlVMTDsKK30KKworRlhfQk9PTCAgQ1BERlNES19QYWdlVmlldzo6RGVsZXRlQW5ub3QoQ1BERlNES19Bbm5vdCogcEFubm90KQoreworCXJldHVybiBGQUxTRTsKK30KKworQ1BERl9Eb2N1bWVudCogQ1BERlNES19QYWdlVmlldzo6R2V0UERGRG9jdW1lbnQoKQoreworCWlmKG1fcGFnZSkKKwl7CisJCXJldHVybiBtX3BhZ2UtPm1fcERvY3VtZW50OworCX0KKwlyZXR1cm4gTlVMTDsKK30KKworaW50CUNQREZTREtfUGFnZVZpZXc6OkNvdW50QW5ub3RzKCkKK3sKKwlyZXR1cm4gbV9wQW5ub3RMaXN0LT5Db3VudCgpOworfQorCitDUERGU0RLX0Fubm90KglDUERGU0RLX1BhZ2VWaWV3OjpHZXRBbm5vdChpbnQgbkluZGV4KQoreworCWludCBuQ291bnQgPSBtX2Z4QW5ub3RBcnJheS5HZXRTaXplKCk7CisJaWYgKCBuSW5kZXggPCAwIHx8IG5JbmRleCA+PSBuQ291bnQgKQorCXsKKwkJcmV0dXJuIE5VTEw7CisJfQorCisJcmV0dXJuIChDUERGU0RLX0Fubm90KiltX2Z4QW5ub3RBcnJheS5HZXRBdChuSW5kZXgpOworfQorCitDUERGU0RLX0Fubm90KiBDUERGU0RLX1BhZ2VWaWV3OjpHZXRBbm5vdEJ5RGljdChDUERGX0RpY3Rpb25hcnkgKiBwRGljdCkKK3sKKwlpbnQgbkNvdW50ID0gbV9meEFubm90QXJyYXkuR2V0U2l6ZSgpOworIAlmb3IoaW50IGk9MDsgaTxuQ291bnQ7IGkrKykKKyAJeworCQlDUERGU0RLX0Fubm90KiBwQW5ub3QgPSAoQ1BERlNES19Bbm5vdCopbV9meEFubm90QXJyYXkuR2V0QXQoaSk7CisgCQlpZihwRGljdD09cEFubm90LT5HZXRQREZBbm5vdCgpLT5tX3BBbm5vdERpY3QpIAorIAkJCXJldHVybiBwQW5ub3Q7CisgCX0KKwlyZXR1cm4gTlVMTDsKK30KKworRlhfQk9PTCBDUERGU0RLX1BhZ2VWaWV3OjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfVUlOVCBuRmxhZykKK3sKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKKwlBU1NFUlQocEVudik7CisJQ1BERlNES19Bbm5vdCogcEZYQW5ub3QgPSBHZXRGWFdpZGdldEF0UG9pbnQocG9pbnQueCwgcG9pbnQueSk7CisJaWYoIXBGWEFubm90KQorCXsKKwkJS2lsbEZvY3VzQW5ub3QobkZsYWcpOworCX0KKwllbHNlCisJeworCQlDUERGU0RLX0Fubm90SGFuZGxlck1nciogcEFubm90SGFuZGxlck1nciA9IHBFbnYtPkdldEFubm90SGFuZGxlck1ncigpOworCQlBU1NFUlQocEFubm90SGFuZGxlck1ncik7CisKKwkJRlhfQk9PTCBiUmV0ID0gcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25MQnV0dG9uRG93bih0aGlzLCBwRlhBbm5vdCwgbkZsYWcscG9pbnQpOworIAkJaWYoYlJldCkKKyAJCXsKKyAJCQlTZXRGb2N1c0Fubm90KHBGWEFubm90KTsKKyAJCX0KKwkJcmV0dXJuIGJSZXQ7CisJfQorCXJldHVybiBGQUxTRTsKK30KKworCitGWF9CT09MIENQREZTREtfUGFnZVZpZXc6Ok9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfVUlOVCBuRmxhZykKK3sKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKKwlBU1NFUlQocEVudik7CisJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIHBBbm5vdEhhbmRsZXJNZ3IgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsKKwlBU1NFUlQocEFubm90SGFuZGxlck1ncik7CisJQ1BERlNES19Bbm5vdCogcEZYQW5ub3QgPSBHZXRGWFdpZGdldEF0UG9pbnQocG9pbnQueCwgcG9pbnQueSk7CisJQ1BERlNES19Bbm5vdCogcEZvY3VzQW5ub3QgPSBHZXRGb2N1c0Fubm90KCk7CisJRlhfQk9PTCBiUmV0ICA9IEZBTFNFOworCWlmKHBGb2N1c0Fubm90ICYmIHBGb2N1c0Fubm90ICE9IHBGWEFubm90KQorCXsKKwkJLy9MYXN0IGZvY3VzIEFubm90IGdldHMgYSBjaGFuY2UgdG8gaGFuZGxlIHRoZSBldmVudC4KKwkJYlJldCA9IHBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uTEJ1dHRvblVwKHRoaXMsIHBGb2N1c0Fubm90LCBuRmxhZyxwb2ludCk7CisJfQorCWlmKHBGWEFubm90ICYmICFiUmV0KQorCXsKKwkJYlJldCA9IHBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uTEJ1dHRvblVwKHRoaXMsIHBGWEFubm90LCBuRmxhZyxwb2ludCk7CisJCXJldHVybiBiUmV0OworCX0KKwlyZXR1cm4gYlJldDsKK30KKworRlhfQk9PTCBDUERGU0RLX1BhZ2VWaWV3OjpPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIGludCBuRmxhZykKK3sKKworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOworCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RIYW5kbGVyTWdyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7CisJQVNTRVJUKHBBbm5vdEhhbmRsZXJNZ3IpOworCWlmKENQREZTREtfQW5ub3QqIHBGWEFubm90ID0gR2V0RlhXaWRnZXRBdFBvaW50KHBvaW50LngsIHBvaW50LnkpKQorCXsKKwkJaWYobV9DYXB0dXJlV2lkZ2V0ICYmIG1fQ2FwdHVyZVdpZGdldCAhPSBwRlhBbm5vdCkKKwkJeworCQkJbV9iRXhpdFdpZGdldCA9IFRSVUU7CisJCQltX2JFbnRlcldpZGdldCA9IEZBTFNFOworCQkJcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25Nb3VzZUV4aXQodGhpcywgbV9DYXB0dXJlV2lkZ2V0LCBuRmxhZyk7CisJCX0KKwkJbV9DYXB0dXJlV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0KilwRlhBbm5vdDsKKwkJbV9iT25XaWRnZXQgPSBUUlVFOworCQlpZighbV9iRW50ZXJXaWRnZXQpCisJCXsKKwkJCW1fYkVudGVyV2lkZ2V0ID0gVFJVRTsKKwkJCW1fYkV4aXRXaWRnZXQgPSBGQUxTRTsKKwkJCXBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uTW91c2VFbnRlcih0aGlzLCBwRlhBbm5vdCxuRmxhZyk7CisJCX0KKwkJcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25Nb3VzZU1vdmUodGhpcywgcEZYQW5ub3QsIG5GbGFnLCBwb2ludCk7CisJCXJldHVybiBUUlVFOworCX0KKwllbHNlCisJeworCQlpZihtX2JPbldpZGdldCkKKwkJewkKKwkJCW1fYk9uV2lkZ2V0ID0gRkFMU0U7CisJCQltX2JFeGl0V2lkZ2V0ID0gVFJVRTsKKwkJCW1fYkVudGVyV2lkZ2V0ID0gRkFMU0U7CisJCQlpZihtX0NhcHR1cmVXaWRnZXQpCisJCQl7CisJCQkJcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25Nb3VzZUV4aXQodGhpcywgbV9DYXB0dXJlV2lkZ2V0LCBuRmxhZyk7CisJCQkJbV9DYXB0dXJlV2lkZ2V0ID0gTlVMTDsKKwkJCX0KKwkJfQorCQlyZXR1cm4gRkFMU0U7CisJfQorCQorCXJldHVybiBGQUxTRTs7Cit9CisKK0ZYX0JPT0wgQ1BERlNES19QYWdlVmlldzo6T25Nb3VzZVdoZWVsKGRvdWJsZSBkZWx0YVgsIGRvdWJsZSBkZWx0YVksY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIGludCBuRmxhZykKK3sKKwlpZihDUERGU0RLX0Fubm90KiBwQW5ub3QgPSBHZXRGWFdpZGdldEF0UG9pbnQocG9pbnQueCwgcG9pbnQueSkpCisJeworCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKKwkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIHBBbm5vdEhhbmRsZXJNZ3IgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsKKwkJQVNTRVJUKHBBbm5vdEhhbmRsZXJNZ3IpOworCQlyZXR1cm4gcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25Nb3VzZVdoZWVsKHRoaXMsIHBBbm5vdCwgbkZsYWcsIChpbnQpZGVsdGFZLCBwb2ludCk7CisJfQorCXJldHVybiBGQUxTRTsKKworfQorCitGWF9CT09MIENQREZTREtfUGFnZVZpZXc6Ok9uQ2hhcihpbnQgbkNoYXIsIEZYX1VJTlQgbkZsYWcpCit7CisJaWYoQ1BERlNES19Bbm5vdCogcEFubm90ID0gR2V0Rm9jdXNBbm5vdCgpKQorCXsKKwkJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcFNES0RvYy0+R2V0RW52KCk7CisJCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RIYW5kbGVyTWdyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7CisJCUFTU0VSVChwQW5ub3RIYW5kbGVyTWdyKTsKKwkJcmV0dXJuIHBBbm5vdEhhbmRsZXJNZ3ItPkFubm90X09uQ2hhcihwQW5ub3QsIG5DaGFyLCBuRmxhZyk7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENQREZTREtfUGFnZVZpZXc6Ok9uS2V5RG93bihpbnQgbktleUNvZGUsIGludCBuRmxhZykKK3sKKwlpZihDUERGU0RLX0Fubm90KiBwQW5ub3QgPSBHZXRGb2N1c0Fubm90KCkpCisJeworCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKKwkJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIHBBbm5vdEhhbmRsZXJNZ3IgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsKKwkJQVNTRVJUKHBBbm5vdEhhbmRsZXJNZ3IpOworCQlyZXR1cm4gcEFubm90SGFuZGxlck1nci0+QW5ub3RfT25LZXlEb3duKHBBbm5vdCwgbktleUNvZGUsIG5GbGFnKTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENQREZTREtfUGFnZVZpZXc6Ok9uS2V5VXAoaW50IG5LZXlDb2RlLCBpbnQgbkZsYWcpCit7CisvLyAJaWYoQ1BERlNES19Bbm5vdCogcEFubm90ID0gR2V0Rm9jdXNBbm5vdCgpKQorLy8gCXsKKy8vIAkJQ0ZGTF9JRm9ybUZpbGxlciogcElGb3JtRmlsbGVyID0gZ19wRm9ybUZpbGxBcHAtPkdldElGb3JtRmlsbGVyKCk7CisvLyAJCXJldHVybiBwSUZvcm1GaWxsZXItPk9uS2V5VXAocEFubm90LCBuS2V5Q29kZSwgbkZsYWcpOworLy8gCX0KKwlyZXR1cm4gRkFMU0U7Cit9CisKK2V4dGVybiB2b2lkIENoZWNrVW5TdXBwb3J0QW5ub3QoQ1BERl9Eb2N1bWVudCAqIHBEb2MsIENQREZfQW5ub3QqIHBQREZBbm5vdCk7CisKK3ZvaWQgQ1BERlNES19QYWdlVmlldzo6TG9hZEZYQW5ub3RzKCkKK3sKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsKKworCUZYX0JPT0wgZW5hYmxlQVBVcGRhdGUgPSBDUERGX0ludGVyRm9ybTo6VXBkYXRpbmdBUEVuYWJsZWQoKTsKKwkvL0Rpc2FibGUgdGhlIGRlZmF1bHQgQVAgY29uc3RydWN0aW9uLgorCUNQREZfSW50ZXJGb3JtOjpFbmFibGVVcGRhdGVBUChGQUxTRSk7CisJbV9wQW5ub3RMaXN0ID0gbmV3IENQREZfQW5ub3RMaXN0KG1fcGFnZSk7CisJQ1BERl9JbnRlckZvcm06OkVuYWJsZVVwZGF0ZUFQKGVuYWJsZUFQVXBkYXRlKTsKKwlpbnQgbkNvdW50ID0gbV9wQW5ub3RMaXN0LT5Db3VudCgpOworCWZvcihpbnQgaT0wOyBpPG5Db3VudDsgaSsrKQorCXsKKwkJQ1BERl9Bbm5vdCogcFBERkFubm90ID0gbV9wQW5ub3RMaXN0LT5HZXRBdChpKTsKKwkJQ1BERl9Eb2N1bWVudCAqIHBEb2MgPSB0aGlzLT5HZXRQREZEb2N1bWVudCgpOworCQkKKwkJQ2hlY2tVblN1cHBvcnRBbm5vdChwRG9jLCBwUERGQW5ub3QpOworCisJCUNQREZTREtfQW5ub3RIYW5kbGVyTWdyKiBwQW5ub3RIYW5kbGVyTWdyID0gcEVudi0+R2V0QW5ub3RIYW5kbGVyTWdyKCk7CisJCUFTU0VSVChwQW5ub3RIYW5kbGVyTWdyICE9IE5VTEwpOworCQlpZihwQW5ub3RIYW5kbGVyTWdyKQorCQl7CisJCQlDUERGU0RLX0Fubm90KiBwQW5ub3QgPSBwQW5ub3RIYW5kbGVyTWdyLT5OZXdBbm5vdChwUERGQW5ub3QsIHRoaXMpOworCQkJaWYoIXBBbm5vdCkKKwkJCQljb250aW51ZTsKKwkJCW1fZnhBbm5vdEFycmF5LkFkZChwQW5ub3QpOworCisJCQlwQW5ub3RIYW5kbGVyTWdyLT5Bbm5vdF9PbkxvYWQocEFubm90KTsKKwkJfQorCisJfQorfQorCit2b2lkCUNQREZTREtfUGFnZVZpZXc6OlVwZGF0ZVJlY3RzKENGWF9SZWN0QXJyYXkmIHJlY3RzKQoreworCWZvcihpbnQgaT0wOyBpPHJlY3RzLkdldFNpemUoKTsgaSsrKQorCXsKKwkJQ1BERl9SZWN0IHJjID0gcmVjdHMuR2V0QXQoaSk7CisJCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BTREtEb2MtPkdldEVudigpOworCQlwRW52LT5GRklfSW52YWxpZGF0ZShtX3BhZ2UsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQsIHJjLmJvdHRvbSk7CisJfQorfQorCit2b2lkIENQREZTREtfUGFnZVZpZXc6OlVwZGF0ZVZpZXcoQ1BERlNES19Bbm5vdCogcEFubm90KQoreworCUNQREZfUmVjdCByY1dpbmRvdzsKKworIAlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wU0RLRG9jLT5HZXRFbnYoKTsJCisvLyAJQ1BERlNES19Bbm5vdEhhbmRsZXJNZ3IqIHBBbm5vdEhhbmRsZXIgPSBwRW52LT5HZXRBbm5vdEhhbmRsZXJNZ3IoKTsKKwkKKwlyY1dpbmRvdyA9IHBBbm5vdC0+R2V0UmVjdCgpOy8vcEFubm90SGFuZGxlci0+QW5ub3RfT25HZXRWaWV3QkJveCh0aGlzLHBBbm5vdCk7CQorCXBFbnYtPkZGSV9JbnZhbGlkYXRlKG1fcGFnZSwgcmNXaW5kb3cubGVmdCwgcmNXaW5kb3cudG9wLCByY1dpbmRvdy5yaWdodCwgcmNXaW5kb3cuYm90dG9tKTsKKworfQorCitpbnQgQ1BERlNES19QYWdlVmlldzo6R2V0UGFnZUluZGV4KCkKK3sKKwlpZihtX3BhZ2UpCisJeworCQlDUERGX0RpY3Rpb25hcnkqIHBEaWMgPSBtX3BhZ2UtPm1fcEZvcm1EaWN0OworCQlDUERGX0RvY3VtZW50KiBwRG9jID0gbV9wU0RLRG9jLT5HZXREb2N1bWVudCgpOworCQlpZihwRG9jICYmIHBEaWMpCisJCXsKKwkJCXJldHVybiBwRG9jLT5HZXRQYWdlSW5kZXgocERpYy0+R2V0T2JqTnVtKCkpOworCQl9CisJfQorCXJldHVybiAtMTsKK30KKworRlhfQk9PTAlDUERGU0RLX1BhZ2VWaWV3OjpJc1ZhbGlkQW5ub3QoRlhfTFBWT0lEIHApCit7CisJaWYgKHAgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOworCWludCBpQ291bnQgPSBtX3BBbm5vdExpc3QtPkNvdW50KCk7CisJZm9yIChpbnQgaSA9IDA7IGkgPCBpQ291bnQ7IGkrKykKKwl7CisJCWlmIChtX3BBbm5vdExpc3QtPkdldEF0KGkpID09IHApCisJCQlyZXR1cm4gVFJVRTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCisKK0NQREZTREtfQW5ub3QqIENQREZTREtfUGFnZVZpZXc6OkdldEZvY3VzQW5ub3QoKQoreworCUNQREZTREtfQW5ub3QqIHBGb2N1c0Fubm90ID0gbV9wU0RLRG9jLT5HZXRGb2N1c0Fubm90KCk7CisJaWYoIXBGb2N1c0Fubm90KQorCQlyZXR1cm4gTlVMTDsKKwkKKwlmb3IoaW50IGk9MDsgaTxtX2Z4QW5ub3RBcnJheS5HZXRTaXplKCk7IGkrKykKKwl7CisJCUNQREZTREtfQW5ub3QqIHBBbm5vdCA9IChDUERGU0RLX0Fubm90KiltX2Z4QW5ub3RBcnJheS5HZXRBdChpKTsKKwkJaWYocEFubm90ID09IHBGb2N1c0Fubm90KQorCQkJcmV0dXJuIHBBbm5vdDsKKwl9CisJcmV0dXJuIE5VTEw7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2ZzZGtfcmVuZGVyY29udGV4dC5jcHAgYi9mcGRmc2RrL3NyYy9mc2RrX3JlbmRlcmNvbnRleHQuY3BwCmluZGV4IDU1MzgyZTEuLjg5YzYxNzkgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2ZzZGtfcmVuZGVyY29udGV4dC5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnNka19yZW5kZXJjb250ZXh0LmNwcApAQCAtMSw0OSArMSw0OSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19yZW5kZXJjb250ZXh0LmgiDQotDQotdm9pZCBDUmVuZGVyQ29udGV4dDo6Q2xlYXIoKQ0KLXsNCi0JbV9wRGV2aWNlID0gTlVMTDsNCi0JbV9wQ29udGV4dCA9IE5VTEw7DQotCW1fcFJlbmRlcmVyID0gTlVMTDsNCi0JbV9wQW5ub3RzID0gTlVMTDsNCi0JbV9wT3B0aW9ucwk9IE5VTEw7DQotI2lmZGVmIF9XSU4zMl9XQ0UNCi0JbV9wQml0bWFwID0gTlVMTDsNCi0JbV9oQml0bWFwID0gTlVMTDsNCi0jZW5kaWYNCi19DQotDQotQ1JlbmRlckNvbnRleHQ6On5DUmVuZGVyQ29udGV4dCgpDQotew0KLQlpZiAobV9wUmVuZGVyZXIpIGRlbGV0ZSBtX3BSZW5kZXJlcjsNCi0JaWYgKG1fcENvbnRleHQpIGRlbGV0ZSBtX3BDb250ZXh0Ow0KLQlpZiAobV9wRGV2aWNlKSBkZWxldGUgbV9wRGV2aWNlOw0KLQlpZiAobV9wQW5ub3RzKSBkZWxldGUgbV9wQW5ub3RzOw0KLQlpZiAobV9wT3B0aW9ucy0+bV9wT0NDb250ZXh0KSBkZWxldGUgbV9wT3B0aW9ucy0+bV9wT0NDb250ZXh0Ow0KLQlpZiAobV9wT3B0aW9ucykgZGVsZXRlIG1fcE9wdGlvbnM7DQotI2lmZGVmIF9XSU4zMl9XQ0UNCi0JaWYgKG1fcEJpdG1hcCkgZGVsZXRlIG1fcEJpdG1hcDsNCi0JaWYgKG1faEJpdG1hcCkgRGVsZXRlT2JqZWN0KG1faEJpdG1hcCk7DQotI2VuZGlmDQotfQ0KLQ0KLUlGU0RLX1BBVVNFX0FkYXB0ZXI6OklGU0RLX1BBVVNFX0FkYXB0ZXIoSUZTREtfUEFVU0UqIElQYXVzZSApDQotew0KLQltX0lQYXVzZSA9IElQYXVzZTsNCi19DQotDQotRlhfQk9PTCBJRlNES19QQVVTRV9BZGFwdGVyOjpOZWVkVG9QYXVzZU5vdygpDQotew0KLQlpZiAobV9JUGF1c2UtPk5lZWRUb1BhdXNlTm93KQ0KLQl7DQotCQlyZXR1cm4gbV9JUGF1c2UtPk5lZWRUb1BhdXNlTm93KG1fSVBhdXNlKTsNCi0JfWVsc2V7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi19DQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uL2luY2x1ZGUvZnNka19yZW5kZXJjb250ZXh0LmgiCisKK3ZvaWQgQ1JlbmRlckNvbnRleHQ6OkNsZWFyKCkKK3sKKwltX3BEZXZpY2UgPSBOVUxMOworCW1fcENvbnRleHQgPSBOVUxMOworCW1fcFJlbmRlcmVyID0gTlVMTDsKKwltX3BBbm5vdHMgPSBOVUxMOworCW1fcE9wdGlvbnMJPSBOVUxMOworI2lmZGVmIF9XSU4zMl9XQ0UKKwltX3BCaXRtYXAgPSBOVUxMOworCW1faEJpdG1hcCA9IE5VTEw7CisjZW5kaWYKK30KKworQ1JlbmRlckNvbnRleHQ6On5DUmVuZGVyQ29udGV4dCgpCit7CisJaWYgKG1fcFJlbmRlcmVyKSBkZWxldGUgbV9wUmVuZGVyZXI7CisJaWYgKG1fcENvbnRleHQpIGRlbGV0ZSBtX3BDb250ZXh0OworCWlmIChtX3BEZXZpY2UpIGRlbGV0ZSBtX3BEZXZpY2U7CisJaWYgKG1fcEFubm90cykgZGVsZXRlIG1fcEFubm90czsKKwlpZiAobV9wT3B0aW9ucy0+bV9wT0NDb250ZXh0KSBkZWxldGUgbV9wT3B0aW9ucy0+bV9wT0NDb250ZXh0OworCWlmIChtX3BPcHRpb25zKSBkZWxldGUgbV9wT3B0aW9uczsKKyNpZmRlZiBfV0lOMzJfV0NFCisJaWYgKG1fcEJpdG1hcCkgZGVsZXRlIG1fcEJpdG1hcDsKKwlpZiAobV9oQml0bWFwKSBEZWxldGVPYmplY3QobV9oQml0bWFwKTsKKyNlbmRpZgorfQorCitJRlNES19QQVVTRV9BZGFwdGVyOjpJRlNES19QQVVTRV9BZGFwdGVyKElGU0RLX1BBVVNFKiBJUGF1c2UgKQoreworCW1fSVBhdXNlID0gSVBhdXNlOworfQorCitGWF9CT09MIElGU0RLX1BBVVNFX0FkYXB0ZXI6Ok5lZWRUb1BhdXNlTm93KCkKK3sKKwlpZiAobV9JUGF1c2UtPk5lZWRUb1BhdXNlTm93KQorCXsKKwkJcmV0dXJuIG1fSVBhdXNlLT5OZWVkVG9QYXVzZU5vdyhtX0lQYXVzZSk7CisJfWVsc2V7CisJCXJldHVybiBGQUxTRTsKKwl9Cit9CmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9meGVkaXQvZnhldF9hcC5jcHAgYi9mcGRmc2RrL3NyYy9meGVkaXQvZnhldF9hcC5jcHAKaW5kZXggOTczMGQzNy4uOTJlNWJmYyAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnhlZGl0L2Z4ZXRfYXAuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2Z4ZWRpdC9meGV0X2FwLmNwcApAQCAtMSwyMjUgKzEsMjI1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9zdHViLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4X2VkaXQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9lZGl0LmgiDQotDQotQ0ZYX0J5dGVTdHJpbmcgR2V0UERGV29yZFN0cmluZyhJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAsIEZYX0lOVDMyIG5Gb250SW5kZXgsIEZYX1dPUkQgV29yZCwgRlhfV09SRCBTdWJXb3JkKSANCi17DQotCUFTU0VSVCAocEZvbnRNYXAgIT0gTlVMTCk7DQotDQotCUNGWF9CeXRlU3RyaW5nIHNXb3JkOw0KLQ0KLQlpZiAoQ1BERl9Gb250ICogcFBERkZvbnQgPSBwRm9udE1hcC0+R2V0UERGRm9udChuRm9udEluZGV4KSkNCi0Jew0KLQkJaWYgKFN1YldvcmQgPiAwKQ0KLQkJew0KLQkJCVdvcmQgPSBTdWJXb3JkOwkJDQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRlhfRFdPUkQgZHdDaGFyQ29kZSA9IC0xOw0KLQ0KLQkJCWlmIChwUERGRm9udC0+SXNVbmljb2RlQ29tcGF0aWJsZSgpKQ0KLQkJCQlkd0NoYXJDb2RlID0gcFBERkZvbnQtPkNoYXJDb2RlRnJvbVVuaWNvZGUoV29yZCk7DQotCQkJZWxzZQ0KLQkJCQlkd0NoYXJDb2RlID0gcEZvbnRNYXAtPkNoYXJDb2RlRnJvbVVuaWNvZGUobkZvbnRJbmRleCwgV29yZCk7DQotDQotCQkJaWYgKGR3Q2hhckNvZGUgPiAwICkNCi0JCQl7DQotCQkJCXBQREZGb250LT5BcHBlbmRDaGFyKHNXb3JkLCBkd0NoYXJDb2RlKTsNCi0JCQkJcmV0dXJuIHNXb3JkOw0KLQkJCX0NCi0JCX0NCi0NCi0JCXBQREZGb250LT5BcHBlbmRDaGFyKHNXb3JkLCBXb3JkKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gc1dvcmQ7DQotfQ0KLQ0KLXN0YXRpYyBDRlhfQnl0ZVN0cmluZyBHZXRXb3JkUmVuZGVyU3RyaW5nKGNvbnN0IENGWF9CeXRlU3RyaW5nICYgc3RyV29yZHMpDQotew0KLQlpZiAoc3RyV29yZHMuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJcmV0dXJuIFBERl9FbmNvZGVTdHJpbmcoc3RyV29yZHMpICsgIiBUalxuIjsNCi0NCi0JcmV0dXJuICIiOw0KLX0NCi0NCi1zdGF0aWMgQ0ZYX0J5dGVTdHJpbmcgR2V0Rm9udFNldFN0cmluZyhJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAsIEZYX0lOVDMyIG5Gb250SW5kZXgsIEZYX0ZMT0FUIGZGb250U2l6ZSkNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBzUmV0Ow0KLQ0KLQlpZiAocEZvbnRNYXApDQotCXsNCi0JCUNGWF9CeXRlU3RyaW5nIHNGb250QWxpYXMgPSBwRm9udE1hcC0+R2V0UERGRm9udEFsaWFzKG5Gb250SW5kZXgpOw0KLQ0KLQkJaWYgKHNGb250QWxpYXMuR2V0TGVuZ3RoKCkgPiAwICYmIGZGb250U2l6ZSA+IDAgKQ0KLQkJCXNSZXQgPDwgIi8iIDw8IHNGb250QWxpYXMgPDwgIiAiIDw8IGZGb250U2l6ZSA8PCAiIFRmXG4iOw0KLQl9DQotDQotCXJldHVybiBzUmV0LkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgSUZYX0VkaXQ6OkdldEVkaXRBcHBlYXJhbmNlU3RyZWFtKElGWF9FZGl0KiBwRWRpdCwgY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0LCANCi0JCQkJCQkJCQkJCQkgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UgLyogPSBOVUxMKi8sIEZYX0JPT0wgYkNvbnRpbnVvdXMvKiA9IFRSVUUqLywgRlhfV09SRCBTdWJXb3JkLyogPSAwKi8pDQotew0KLQlDRlhfQnl0ZVRleHRCdWYgc0VkaXRTdHJlYW0sIHNXb3JkczsNCi0NCi0JQ1BERl9Qb2ludCBwdE9sZCgwLjBmLDAuMGYpLHB0TmV3KDAuMGYsMC4wZik7DQotCUZYX0lOVDMyIG5DdXJGb250SW5kZXggPSAtMTsNCi0NCi0JaWYgKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBwRWRpdC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJaWYgKHBSYW5nZSkNCi0JCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOw0KLQkJZWxzZQ0KLQkJCXBJdGVyYXRvci0+U2V0QXQoMCk7DQotDQotCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZTsNCi0NCi0JCXdoaWxlIChwSXRlcmF0b3ItPk5leHRXb3JkKCkpDQotCQl7DQotCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotDQotCQkJaWYgKHBSYW5nZSAmJiBwbGFjZS5Xb3JkQ21wKHBSYW5nZS0+RW5kUG9zKSA+IDApIGJyZWFrOw0KLQ0KLQkJCWlmIChiQ29udGludW91cykJCQkNCi0JCQl7DQotCQkJCWlmIChwbGFjZS5MaW5lQ21wKG9sZHBsYWNlKSAhPSAwKQ0KLQkJCQl7DQotCQkJCQlpZiAoc1dvcmRzLkdldFNpemUoKSA+IDApDQotCQkJCQl7DQotCQkJCQkJc0VkaXRTdHJlYW0gPDwgR2V0V29yZFJlbmRlclN0cmluZyhzV29yZHMuR2V0Qnl0ZVN0cmluZygpKTsNCi0JCQkJCQlzV29yZHMuQ2xlYXIoKTsNCi0JCQkJCX0NCi0NCi0JCQkJCUNQVlRfV29yZCB3b3JkOw0KLQkJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJCXsNCi0JCQkJCQlwdE5ldyA9IENQREZfUG9pbnQod29yZC5wdFdvcmQueCArIHB0T2Zmc2V0LngsIHdvcmQucHRXb3JkLnkgKyBwdE9mZnNldC55KTsNCi0JCQkJCX0NCi0JCQkJCWVsc2UNCi0JCQkJCXsNCi0JCQkJCQlDUFZUX0xpbmUgbGluZTsNCi0JCQkJCQlwSXRlcmF0b3ItPkdldExpbmUobGluZSk7DQotCQkJCQkJcHROZXcgPSBDUERGX1BvaW50KGxpbmUucHRMaW5lLnggKyBwdE9mZnNldC54LCBsaW5lLnB0TGluZS55ICsgcHRPZmZzZXQueSk7DQotCQkJCQl9DQotDQotCQkJCQlpZiAocHROZXcueCAhPSBwdE9sZC54IHx8IHB0TmV3LnkgIT0gcHRPbGQueSkNCi0JCQkJCXsNCi0JCQkJCQlzRWRpdFN0cmVhbSA8PCBwdE5ldy54IC0gcHRPbGQueCA8PCAiICIgPDwgcHROZXcueSAtIHB0T2xkLnkgPDwgIiBUZFxuIjsNCi0NCi0JCQkJCQlwdE9sZCA9IHB0TmV3Ow0KLQkJCQkJfQ0KLQkJCQl9DQotDQotCQkJCUNQVlRfV29yZCB3b3JkOw0KLQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQ0KLQkJCQl7CQ0KLQkJCQkJaWYgKHdvcmQubkZvbnRJbmRleCAhPSBuQ3VyRm9udEluZGV4KQ0KLQkJCQkJew0KLQkJCQkJCWlmIChzV29yZHMuR2V0U2l6ZSgpID4gMCkNCi0JCQkJCQl7DQotCQkJCQkJCXNFZGl0U3RyZWFtIDw8IEdldFdvcmRSZW5kZXJTdHJpbmcoc1dvcmRzLkdldEJ5dGVTdHJpbmcoKSk7DQotCQkJCQkJCXNXb3Jkcy5DbGVhcigpOw0KLQkJCQkJCX0NCi0JCQkJCQlzRWRpdFN0cmVhbSA8PCBHZXRGb250U2V0U3RyaW5nKHBFZGl0LT5HZXRGb250TWFwKCksd29yZC5uRm9udEluZGV4LHdvcmQuZkZvbnRTaXplKTsNCi0JCQkJCQluQ3VyRm9udEluZGV4ID0gd29yZC5uRm9udEluZGV4Ow0KLQkJCQkJfQ0KLQ0KLQkJCQkJc1dvcmRzIDw8IEdldFBERldvcmRTdHJpbmcocEVkaXQtPkdldEZvbnRNYXAoKSxuQ3VyRm9udEluZGV4LHdvcmQuV29yZCxTdWJXb3JkKTsNCi0JCQkJfQ0KLQ0KLQkJCQlvbGRwbGFjZSA9IHBsYWNlOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlDUFZUX1dvcmQgd29yZDsNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJew0KLQkJCQkJcHROZXcgPSBDUERGX1BvaW50KHdvcmQucHRXb3JkLnggKyBwdE9mZnNldC54LCB3b3JkLnB0V29yZC55ICsgcHRPZmZzZXQueSk7DQotDQotCQkJCQlpZiAocHROZXcueCAhPSBwdE9sZC54IHx8IHB0TmV3LnkgIT0gcHRPbGQueSkNCi0JCQkJCXsNCi0JCQkJCQlzRWRpdFN0cmVhbSA8PCBwdE5ldy54IC0gcHRPbGQueCA8PCAiICIgPDwgcHROZXcueSAtIHB0T2xkLnkgPDwgIiBUZFxuIjsNCi0JCQkJCQlwdE9sZCA9IHB0TmV3Ow0KLQkJCQkJfQkNCi0NCi0JCQkJCWlmICh3b3JkLm5Gb250SW5kZXggIT0gbkN1ckZvbnRJbmRleCkNCi0JCQkJCXsNCi0JCQkJCQlzRWRpdFN0cmVhbSA8PCBHZXRGb250U2V0U3RyaW5nKHBFZGl0LT5HZXRGb250TWFwKCksd29yZC5uRm9udEluZGV4LHdvcmQuZkZvbnRTaXplKTsNCi0JCQkJCQluQ3VyRm9udEluZGV4ID0gd29yZC5uRm9udEluZGV4Ow0KLQkJCQkJfQ0KLQ0KLQkJCQkJc0VkaXRTdHJlYW0gPDwgR2V0V29yZFJlbmRlclN0cmluZyhHZXRQREZXb3JkU3RyaW5nKHBFZGl0LT5HZXRGb250TWFwKCksbkN1ckZvbnRJbmRleCx3b3JkLldvcmQsU3ViV29yZCkpOw0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJaWYgKHNXb3Jkcy5HZXRTaXplKCkgPiAwKQ0KLQkJew0KLQkJCXNFZGl0U3RyZWFtIDw8IEdldFdvcmRSZW5kZXJTdHJpbmcoc1dvcmRzLkdldEJ5dGVTdHJpbmcoKSk7DQotCQkJc1dvcmRzLkNsZWFyKCk7DQotCQl9DQotCX0NCi0NCi0JQ0ZYX0J5dGVUZXh0QnVmIHNBcHBTdHJlYW07DQotCWlmIChzRWRpdFN0cmVhbS5HZXRTaXplKCkgPiAwKQ0KLQl7DQotCQlGWF9JTlQzMiBuSG9yelNjYWxlID0gcEVkaXQtPkdldEhvcnpTY2FsZSgpOw0KLQkJaWYgKG5Ib3J6U2NhbGUgIT0gMTAwKQ0KLQkJew0KLQkJCXNBcHBTdHJlYW0gPDwgbkhvcnpTY2FsZSA8PCAiIFR6XG4iOw0KLQkJfQ0KLQ0KLQkJRlhfRkxPQVQgZkNoYXJTcGFjZSA9IHBFZGl0LT5HZXRDaGFyU3BhY2UoKTsNCi0JCWlmICghRlhfRURJVF9Jc0Zsb2F0WmVybyhmQ2hhclNwYWNlKSkNCi0JCXsNCi0JCQlzQXBwU3RyZWFtIDw8IGZDaGFyU3BhY2UgPDwgIiBUY1xuIjsNCi0JCX0NCi0NCi0JCXNBcHBTdHJlYW0gPDwgc0VkaXRTdHJlYW07DQotCX0JDQotDQotCXJldHVybiBzQXBwU3RyZWFtLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgSUZYX0VkaXQ6OkdldFNlbGVjdEFwcGVhcmFuY2VTdHJlYW0oSUZYX0VkaXQqIHBFZGl0LCBjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQsIA0KLQkJCQkJCQljb25zdCBDUFZUX1dvcmRSYW5nZSAqIHBSYW5nZSAvKj0gTlVMTCovKQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNSZXQ7DQotDQotCWlmIChwUmFuZ2UgJiYgcFJhbmdlLT5Jc0V4aXN0KCkpDQotCXsNCi0JCWlmIChJRlhfRWRpdF9JdGVyYXRvciogcEl0ZXJhdG9yID0gcEVkaXQtPkdldEl0ZXJhdG9yKCkpDQotCQl7DQotCQkJcEl0ZXJhdG9yLT5TZXRBdChwUmFuZ2UtPkJlZ2luUG9zKTsNCi0JCQkNCi0JCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQ0KLQkJCXsNCi0JCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotDQotCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsJCQkJDQotDQotCQkJCUNQVlRfV29yZCB3b3JkOw0KLQkJCQlDUFZUX0xpbmUgbGluZTsNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSAmJiBwSXRlcmF0b3ItPkdldExpbmUobGluZSkpDQotCQkJCXsJCQkNCi0JCQkJCS8vQ1BERl9SZWN0IHJjV29yZFNlbCA9IENQREZfUmVjdCh3b3JkLnB0V29yZC54LGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lRGVzY2VudCwNCi0JCQkJCS8vCQl3b3JkLnB0V29yZC54K3dvcmQuZldpZHRoLGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lQXNjZW50KTsNCi0NCi0JCQkJCXNSZXQgPDwgd29yZC5wdFdvcmQueCArIHB0T2Zmc2V0LnggPDwgIiAiIDw8IGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lRGVzY2VudA0KLQkJCQkJCTw8ICIgIiA8PCB3b3JkLmZXaWR0aCA8PCAiICIgPDwgbGluZS5mTGluZUFzY2VudCAtIGxpbmUuZkxpbmVEZXNjZW50IDw8ICIgcmVcbmZcbiI7CQkJCQ0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBzUmV0LkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfc3R1Yi5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4X2VkaXQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4ZWRpdC9meGV0X2VkaXQuaCIKKworQ0ZYX0J5dGVTdHJpbmcgR2V0UERGV29yZFN0cmluZyhJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAsIEZYX0lOVDMyIG5Gb250SW5kZXgsIEZYX1dPUkQgV29yZCwgRlhfV09SRCBTdWJXb3JkKSAKK3sKKwlBU1NFUlQgKHBGb250TWFwICE9IE5VTEwpOworCisJQ0ZYX0J5dGVTdHJpbmcgc1dvcmQ7CisKKwlpZiAoQ1BERl9Gb250ICogcFBERkZvbnQgPSBwRm9udE1hcC0+R2V0UERGRm9udChuRm9udEluZGV4KSkKKwl7CisJCWlmIChTdWJXb3JkID4gMCkKKwkJeworCQkJV29yZCA9IFN1YldvcmQ7CQkKKwkJfQorCQllbHNlCisJCXsKKwkJCUZYX0RXT1JEIGR3Q2hhckNvZGUgPSAtMTsKKworCQkJaWYgKHBQREZGb250LT5Jc1VuaWNvZGVDb21wYXRpYmxlKCkpCisJCQkJZHdDaGFyQ29kZSA9IHBQREZGb250LT5DaGFyQ29kZUZyb21Vbmljb2RlKFdvcmQpOworCQkJZWxzZQorCQkJCWR3Q2hhckNvZGUgPSBwRm9udE1hcC0+Q2hhckNvZGVGcm9tVW5pY29kZShuRm9udEluZGV4LCBXb3JkKTsKKworCQkJaWYgKGR3Q2hhckNvZGUgPiAwICkKKwkJCXsKKwkJCQlwUERGRm9udC0+QXBwZW5kQ2hhcihzV29yZCwgZHdDaGFyQ29kZSk7CisJCQkJcmV0dXJuIHNXb3JkOworCQkJfQorCQl9CisKKwkJcFBERkZvbnQtPkFwcGVuZENoYXIoc1dvcmQsIFdvcmQpOworCX0KKworCXJldHVybiBzV29yZDsKK30KKworc3RhdGljIENGWF9CeXRlU3RyaW5nIEdldFdvcmRSZW5kZXJTdHJpbmcoY29uc3QgQ0ZYX0J5dGVTdHJpbmcgJiBzdHJXb3JkcykKK3sKKwlpZiAoc3RyV29yZHMuR2V0TGVuZ3RoKCkgPiAwKQorCQlyZXR1cm4gUERGX0VuY29kZVN0cmluZyhzdHJXb3JkcykgKyAiIFRqXG4iOworCisJcmV0dXJuICIiOworfQorCitzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcgR2V0Rm9udFNldFN0cmluZyhJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAsIEZYX0lOVDMyIG5Gb250SW5kZXgsIEZYX0ZMT0FUIGZGb250U2l6ZSkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc1JldDsKKworCWlmIChwRm9udE1hcCkKKwl7CisJCUNGWF9CeXRlU3RyaW5nIHNGb250QWxpYXMgPSBwRm9udE1hcC0+R2V0UERGRm9udEFsaWFzKG5Gb250SW5kZXgpOworCisJCWlmIChzRm9udEFsaWFzLkdldExlbmd0aCgpID4gMCAmJiBmRm9udFNpemUgPiAwICkKKwkJCXNSZXQgPDwgIi8iIDw8IHNGb250QWxpYXMgPDwgIiAiIDw8IGZGb250U2l6ZSA8PCAiIFRmXG4iOworCX0KKworCXJldHVybiBzUmV0LkdldEJ5dGVTdHJpbmcoKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgSUZYX0VkaXQ6OkdldEVkaXRBcHBlYXJhbmNlU3RyZWFtKElGWF9FZGl0KiBwRWRpdCwgY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0LCAKKwkJCQkJCQkJCQkJCSBjb25zdCBDUFZUX1dvcmRSYW5nZSAqIHBSYW5nZSAvKiA9IE5VTEwqLywgRlhfQk9PTCBiQ29udGludW91cy8qID0gVFJVRSovLCBGWF9XT1JEIFN1YldvcmQvKiA9IDAqLykKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc0VkaXRTdHJlYW0sIHNXb3JkczsKKworCUNQREZfUG9pbnQgcHRPbGQoMC4wZiwwLjBmKSxwdE5ldygwLjBmLDAuMGYpOworCUZYX0lOVDMyIG5DdXJGb250SW5kZXggPSAtMTsKKworCWlmIChJRlhfRWRpdF9JdGVyYXRvciogcEl0ZXJhdG9yID0gcEVkaXQtPkdldEl0ZXJhdG9yKCkpCisJeworCQlpZiAocFJhbmdlKQorCQkJcEl0ZXJhdG9yLT5TZXRBdChwUmFuZ2UtPkJlZ2luUG9zKTsKKwkJZWxzZQorCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsKKworCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZTsKKworCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQorCQl7CisJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKworCQkJaWYgKHBSYW5nZSAmJiBwbGFjZS5Xb3JkQ21wKHBSYW5nZS0+RW5kUG9zKSA+IDApIGJyZWFrOworCisJCQlpZiAoYkNvbnRpbnVvdXMpCQkJCisJCQl7CisJCQkJaWYgKHBsYWNlLkxpbmVDbXAob2xkcGxhY2UpICE9IDApCisJCQkJeworCQkJCQlpZiAoc1dvcmRzLkdldFNpemUoKSA+IDApCisJCQkJCXsKKwkJCQkJCXNFZGl0U3RyZWFtIDw8IEdldFdvcmRSZW5kZXJTdHJpbmcoc1dvcmRzLkdldEJ5dGVTdHJpbmcoKSk7CisJCQkJCQlzV29yZHMuQ2xlYXIoKTsKKwkJCQkJfQorCisJCQkJCUNQVlRfV29yZCB3b3JkOworCQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQorCQkJCQl7CisJCQkJCQlwdE5ldyA9IENQREZfUG9pbnQod29yZC5wdFdvcmQueCArIHB0T2Zmc2V0LngsIHdvcmQucHRXb3JkLnkgKyBwdE9mZnNldC55KTsKKwkJCQkJfQorCQkJCQllbHNlCisJCQkJCXsKKwkJCQkJCUNQVlRfTGluZSBsaW5lOworCQkJCQkJcEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmUpOworCQkJCQkJcHROZXcgPSBDUERGX1BvaW50KGxpbmUucHRMaW5lLnggKyBwdE9mZnNldC54LCBsaW5lLnB0TGluZS55ICsgcHRPZmZzZXQueSk7CisJCQkJCX0KKworCQkJCQlpZiAocHROZXcueCAhPSBwdE9sZC54IHx8IHB0TmV3LnkgIT0gcHRPbGQueSkKKwkJCQkJeworCQkJCQkJc0VkaXRTdHJlYW0gPDwgcHROZXcueCAtIHB0T2xkLnggPDwgIiAiIDw8IHB0TmV3LnkgLSBwdE9sZC55IDw8ICIgVGRcbiI7CisKKwkJCQkJCXB0T2xkID0gcHROZXc7CisJCQkJCX0KKwkJCQl9CisKKwkJCQlDUFZUX1dvcmQgd29yZDsKKwkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQorCQkJCXsJCisJCQkJCWlmICh3b3JkLm5Gb250SW5kZXggIT0gbkN1ckZvbnRJbmRleCkKKwkJCQkJeworCQkJCQkJaWYgKHNXb3Jkcy5HZXRTaXplKCkgPiAwKQorCQkJCQkJeworCQkJCQkJCXNFZGl0U3RyZWFtIDw8IEdldFdvcmRSZW5kZXJTdHJpbmcoc1dvcmRzLkdldEJ5dGVTdHJpbmcoKSk7CisJCQkJCQkJc1dvcmRzLkNsZWFyKCk7CisJCQkJCQl9CisJCQkJCQlzRWRpdFN0cmVhbSA8PCBHZXRGb250U2V0U3RyaW5nKHBFZGl0LT5HZXRGb250TWFwKCksd29yZC5uRm9udEluZGV4LHdvcmQuZkZvbnRTaXplKTsKKwkJCQkJCW5DdXJGb250SW5kZXggPSB3b3JkLm5Gb250SW5kZXg7CisJCQkJCX0KKworCQkJCQlzV29yZHMgPDwgR2V0UERGV29yZFN0cmluZyhwRWRpdC0+R2V0Rm9udE1hcCgpLG5DdXJGb250SW5kZXgsd29yZC5Xb3JkLFN1YldvcmQpOworCQkJCX0KKworCQkJCW9sZHBsYWNlID0gcGxhY2U7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJQ1BWVF9Xb3JkIHdvcmQ7CisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCXB0TmV3ID0gQ1BERl9Qb2ludCh3b3JkLnB0V29yZC54ICsgcHRPZmZzZXQueCwgd29yZC5wdFdvcmQueSArIHB0T2Zmc2V0LnkpOworCisJCQkJCWlmIChwdE5ldy54ICE9IHB0T2xkLnggfHwgcHROZXcueSAhPSBwdE9sZC55KQorCQkJCQl7CisJCQkJCQlzRWRpdFN0cmVhbSA8PCBwdE5ldy54IC0gcHRPbGQueCA8PCAiICIgPDwgcHROZXcueSAtIHB0T2xkLnkgPDwgIiBUZFxuIjsKKwkJCQkJCXB0T2xkID0gcHROZXc7CisJCQkJCX0JCisKKwkJCQkJaWYgKHdvcmQubkZvbnRJbmRleCAhPSBuQ3VyRm9udEluZGV4KQorCQkJCQl7CisJCQkJCQlzRWRpdFN0cmVhbSA8PCBHZXRGb250U2V0U3RyaW5nKHBFZGl0LT5HZXRGb250TWFwKCksd29yZC5uRm9udEluZGV4LHdvcmQuZkZvbnRTaXplKTsKKwkJCQkJCW5DdXJGb250SW5kZXggPSB3b3JkLm5Gb250SW5kZXg7CisJCQkJCX0KKworCQkJCQlzRWRpdFN0cmVhbSA8PCBHZXRXb3JkUmVuZGVyU3RyaW5nKEdldFBERldvcmRTdHJpbmcocEVkaXQtPkdldEZvbnRNYXAoKSxuQ3VyRm9udEluZGV4LHdvcmQuV29yZCxTdWJXb3JkKSk7CisJCQkJfQorCQkJfQorCQl9CisKKwkJaWYgKHNXb3Jkcy5HZXRTaXplKCkgPiAwKQorCQl7CisJCQlzRWRpdFN0cmVhbSA8PCBHZXRXb3JkUmVuZGVyU3RyaW5nKHNXb3Jkcy5HZXRCeXRlU3RyaW5nKCkpOworCQkJc1dvcmRzLkNsZWFyKCk7CisJCX0KKwl9CisKKwlDRlhfQnl0ZVRleHRCdWYgc0FwcFN0cmVhbTsKKwlpZiAoc0VkaXRTdHJlYW0uR2V0U2l6ZSgpID4gMCkKKwl7CisJCUZYX0lOVDMyIG5Ib3J6U2NhbGUgPSBwRWRpdC0+R2V0SG9yelNjYWxlKCk7CisJCWlmIChuSG9yelNjYWxlICE9IDEwMCkKKwkJeworCQkJc0FwcFN0cmVhbSA8PCBuSG9yelNjYWxlIDw8ICIgVHpcbiI7CisJCX0KKworCQlGWF9GTE9BVCBmQ2hhclNwYWNlID0gcEVkaXQtPkdldENoYXJTcGFjZSgpOworCQlpZiAoIUZYX0VESVRfSXNGbG9hdFplcm8oZkNoYXJTcGFjZSkpCisJCXsKKwkJCXNBcHBTdHJlYW0gPDwgZkNoYXJTcGFjZSA8PCAiIFRjXG4iOworCQl9CisKKwkJc0FwcFN0cmVhbSA8PCBzRWRpdFN0cmVhbTsKKwl9CQorCisJcmV0dXJuIHNBcHBTdHJlYW0uR2V0Qnl0ZVN0cmluZygpOworfQorCitDRlhfQnl0ZVN0cmluZyBJRlhfRWRpdDo6R2V0U2VsZWN0QXBwZWFyYW5jZVN0cmVhbShJRlhfRWRpdCogcEVkaXQsIGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCwgCisJCQkJCQkJY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UgLyo9IE5VTEwqLykKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc1JldDsKKworCWlmIChwUmFuZ2UgJiYgcFJhbmdlLT5Jc0V4aXN0KCkpCisJeworCQlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQorCQl7CisJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOworCQkJCisJCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQorCQkJeworCQkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCisJCQkJaWYgKHBSYW5nZSAmJiBwbGFjZS5Xb3JkQ21wKHBSYW5nZS0+RW5kUG9zKSA+IDApIGJyZWFrOwkJCQkKKworCQkJCUNQVlRfV29yZCB3b3JkOworCQkJCUNQVlRfTGluZSBsaW5lOworCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkgJiYgcEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmUpKQorCQkJCXsJCQkKKwkJCQkJLy9DUERGX1JlY3QgcmNXb3JkU2VsID0gQ1BERl9SZWN0KHdvcmQucHRXb3JkLngsbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVEZXNjZW50LAorCQkJCQkvLwkJd29yZC5wdFdvcmQueCt3b3JkLmZXaWR0aCxsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZUFzY2VudCk7CisKKwkJCQkJc1JldCA8PCB3b3JkLnB0V29yZC54ICsgcHRPZmZzZXQueCA8PCAiICIgPDwgbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVEZXNjZW50CisJCQkJCQk8PCAiICIgPDwgd29yZC5mV2lkdGggPDwgIiAiIDw8IGxpbmUuZkxpbmVBc2NlbnQgLSBsaW5lLmZMaW5lRGVzY2VudCA8PCAiIHJlXG5mXG4iOwkJCQkKKwkJCQl9CisJCQl9CisJCX0KKwl9CisKKwlyZXR1cm4gc1JldC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2Z4ZWRpdC9meGV0X2VkaXQuY3BwIGIvZnBkZnNkay9zcmMvZnhlZGl0L2Z4ZXRfZWRpdC5jcHAKaW5kZXggNWE2ZDRkOC4uZWZjN2FjZCAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnhlZGl0L2Z4ZXRfZWRpdC5jcHAKKysrIGIvZnBkZnNkay9zcmMvZnhlZGl0L2Z4ZXRfZWRpdC5jcHAKQEAgLTEsMzYxMCArMSwzNjEwIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9zdHViLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfZWRpdC5oIg0KLQ0KLSNkZWZpbmUgRlhfRURJVF9VTkRPX01BWElURU0JCQkJMTAwMDANCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X0l0ZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DRlhfRWRpdF9JdGVyYXRvcjo6Q0ZYX0VkaXRfSXRlcmF0b3IoQ0ZYX0VkaXQgKiBwRWRpdCxJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBWVEl0ZXJhdG9yKSA6IA0KLQltX3BFZGl0KHBFZGl0KSwNCi0JbV9wVlRJdGVyYXRvcihwVlRJdGVyYXRvcikNCi17DQotfQ0KLQ0KLUNGWF9FZGl0X0l0ZXJhdG9yOjp+Q0ZYX0VkaXRfSXRlcmF0b3IoKQ0KLXsNCi19DQotDQotRlhfQk9PTAlDRlhfRWRpdF9JdGVyYXRvcjo6TmV4dFdvcmQoKQ0KLXsNCi0JQVNTRVJUKG1fcFZUSXRlcmF0b3IgIT0gTlVMTCk7DQotCQ0KLQlyZXR1cm4gbV9wVlRJdGVyYXRvci0+TmV4dFdvcmQoKTsNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdF9JdGVyYXRvcjo6TmV4dExpbmUoKQ0KLXsNCi0JQVNTRVJUKG1fcFZUSXRlcmF0b3IgIT0gTlVMTCk7DQotDQotCXJldHVybiBtX3BWVEl0ZXJhdG9yLT5OZXh0TGluZSgpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0X0l0ZXJhdG9yOjpOZXh0U2VjdGlvbigpDQotew0KLQlBU1NFUlQobV9wVlRJdGVyYXRvciAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIG1fcFZUSXRlcmF0b3ItPk5leHRTZWN0aW9uKCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX0VkaXRfSXRlcmF0b3I6OlByZXZXb3JkKCkNCi17DQotCUFTU0VSVChtX3BWVEl0ZXJhdG9yICE9IE5VTEwpOw0KLQkNCi0JcmV0dXJuIG1fcFZUSXRlcmF0b3ItPlByZXZXb3JkKCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX0VkaXRfSXRlcmF0b3I6OlByZXZMaW5lKCkNCi17DQotCUFTU0VSVChtX3BWVEl0ZXJhdG9yICE9IE5VTEwpOw0KLQ0KLQlyZXR1cm4gbV9wVlRJdGVyYXRvci0+UHJldkxpbmUoKTsNCi19DQotDQotRlhfQk9PTAlDRlhfRWRpdF9JdGVyYXRvcjo6UHJldlNlY3Rpb24oKQ0KLXsNCi0JQVNTRVJUKG1fcFZUSXRlcmF0b3IgIT0gTlVMTCk7DQotDQotCXJldHVybiBtX3BWVEl0ZXJhdG9yLT5QcmV2U2VjdGlvbigpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0X0l0ZXJhdG9yOjpHZXRXb3JkKENQVlRfV29yZCAmIHdvcmQpIGNvbnN0DQotew0KLQlBU1NFUlQobV9wRWRpdCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcFZUSXRlcmF0b3IgIT0gTlVMTCk7DQotDQotCWlmIChtX3BWVEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQ0KLQl7DQotCQl3b3JkLnB0V29yZCA9IG1fcEVkaXQtPlZUVG9FZGl0KHdvcmQucHRXb3JkKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdF9JdGVyYXRvcjo6R2V0TGluZShDUFZUX0xpbmUgJiBsaW5lKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEVkaXQgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BWVEl0ZXJhdG9yICE9IE5VTEwpOw0KLQ0KLQlpZiAobV9wVlRJdGVyYXRvci0+R2V0TGluZShsaW5lKSkNCi0JewkJDQotCQlsaW5lLnB0TGluZSA9IG1fcEVkaXQtPlZUVG9FZGl0KGxpbmUucHRMaW5lKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdF9JdGVyYXRvcjo6R2V0U2VjdGlvbihDUFZUX1NlY3Rpb24gJiBzZWN0aW9uKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcEVkaXQgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BWVEl0ZXJhdG9yICE9IE5VTEwpOw0KLQ0KLQlpZiAobV9wVlRJdGVyYXRvci0+R2V0U2VjdGlvbihzZWN0aW9uKSkNCi0Jew0KLQkJc2VjdGlvbi5yY1NlY3Rpb24gPSBtX3BFZGl0LT5WVFRvRWRpdChzZWN0aW9uLnJjU2VjdGlvbik7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXRfSXRlcmF0b3I6OlNldEF0KEZYX0lOVDMyIG5Xb3JkSW5kZXgpDQotew0KLQlBU1NFUlQobV9wVlRJdGVyYXRvciAhPSBOVUxMKTsNCi0NCi0JbV9wVlRJdGVyYXRvci0+U2V0QXQobldvcmRJbmRleCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXRfSXRlcmF0b3I6OlNldEF0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpDQotew0KLQlBU1NFUlQobV9wVlRJdGVyYXRvciAhPSBOVUxMKTsNCi0NCi0JbV9wVlRJdGVyYXRvci0+U2V0QXQocGxhY2UpOw0KLX0NCi0NCi1jb25zdCBDUFZUX1dvcmRQbGFjZSAmIENGWF9FZGl0X0l0ZXJhdG9yOjpHZXRBdCgpIGNvbnN0DQotew0KLQlBU1NFUlQobV9wVlRJdGVyYXRvciAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIG1fcFZUSXRlcmF0b3ItPkdldEF0KCk7DQotfQ0KLQ0KLUlGWF9FZGl0KiBDRlhfRWRpdF9JdGVyYXRvcjo6R2V0RWRpdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wRWRpdDsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X1Byb3ZpZGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DRlhfRWRpdF9Qcm92aWRlcjo6Q0ZYX0VkaXRfUHJvdmlkZXIoSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwKSA6IG1fcEZvbnRNYXAocEZvbnRNYXApDQotew0KLQlBU1NFUlQobV9wRm9udE1hcCAhPSBOVUxMKTsNCi19DQotDQotQ0ZYX0VkaXRfUHJvdmlkZXI6On5DRlhfRWRpdF9Qcm92aWRlcigpDQotew0KLX0NCi0NCi1JRlhfRWRpdF9Gb250TWFwKiBDRlhfRWRpdF9Qcm92aWRlcjo6R2V0Rm9udE1hcCgpDQotew0KLQlyZXR1cm4gbV9wRm9udE1hcDsNCi19DQotDQotRlhfSU5UMzIgQ0ZYX0VkaXRfUHJvdmlkZXI6OkdldENoYXJXaWR0aChGWF9JTlQzMiBuRm9udEluZGV4LCBGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIG5Xb3JkU3R5bGUpDQotew0KLQlpZiAoQ1BERl9Gb250KiBwUERGRm9udCA9IG1fcEZvbnRNYXAtPkdldFBERkZvbnQobkZvbnRJbmRleCkpDQotCXsNCi0JCUZYX0RXT1JEIGNoYXJjb2RlID0gd29yZDsNCi0NCi0JCWlmIChwUERGRm9udC0+SXNVbmljb2RlQ29tcGF0aWJsZSgpKQkJDQotCQkJY2hhcmNvZGUgPSBwUERGRm9udC0+Q2hhckNvZGVGcm9tVW5pY29kZSh3b3JkKTsJDQotCQllbHNlDQotCQkJY2hhcmNvZGUgPSBtX3BGb250TWFwLT5DaGFyQ29kZUZyb21Vbmljb2RlKG5Gb250SW5kZXgsIHdvcmQpOw0KLQ0KLQkJaWYgKGNoYXJjb2RlICE9IC0xKQkJCQ0KLQkJCXJldHVybiBwUERGRm9udC0+R2V0Q2hhcldpZHRoRihjaGFyY29kZSk7DQotCX0NCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLUZYX0lOVDMyIENGWF9FZGl0X1Byb3ZpZGVyOjpHZXRUeXBlQXNjZW50KEZYX0lOVDMyIG5Gb250SW5kZXgpDQotew0KLQlpZiAoQ1BERl9Gb250KiBwUERGRm9udCA9IG1fcEZvbnRNYXAtPkdldFBERkZvbnQobkZvbnRJbmRleCkpDQotCQlyZXR1cm4gcFBERkZvbnQtPkdldFR5cGVBc2NlbnQoKTsNCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLUZYX0lOVDMyIENGWF9FZGl0X1Byb3ZpZGVyOjpHZXRUeXBlRGVzY2VudChGWF9JTlQzMiBuRm9udEluZGV4KQ0KLXsNCi0JaWYgKENQREZfRm9udCogcFBERkZvbnQgPSBtX3BGb250TWFwLT5HZXRQREZGb250KG5Gb250SW5kZXgpKQ0KLQkJcmV0dXJuIHBQREZGb250LT5HZXRUeXBlRGVzY2VudCgpOw0KLQ0KLQlyZXR1cm4gMDsNCi19DQotDQotRlhfSU5UMzIgQ0ZYX0VkaXRfUHJvdmlkZXI6OkdldFdvcmRGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LCBGWF9JTlQzMiBuRm9udEluZGV4KQ0KLXsNCi0JcmV0dXJuIG1fcEZvbnRNYXAtPkdldFdvcmRGb250SW5kZXgod29yZCxjaGFyc2V0LG5Gb250SW5kZXgpOw0KLX0NCi0NCi1GWF9JTlQzMiBDRlhfRWRpdF9Qcm92aWRlcjo6R2V0RGVmYXVsdEZvbnRJbmRleCgpDQotew0KLQlyZXR1cm4gMDsNCi19DQotDQotRlhfQk9PTAlDRlhfRWRpdF9Qcm92aWRlcjo6SXNMYXRpbldvcmQoRlhfV09SRCB3b3JkKQ0KLXsNCi0JcmV0dXJuIEZYX0VESVRfSVNMQVRJTldPUkQod29yZCk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdF9SZWZyZXNoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGWF9FZGl0X1JlZnJlc2g6OkNGWF9FZGl0X1JlZnJlc2goKQ0KLXsNCi19DQotDQotQ0ZYX0VkaXRfUmVmcmVzaDo6fkNGWF9FZGl0X1JlZnJlc2goKQ0KLXsNCi19DQotDQotdm9pZCBDRlhfRWRpdF9SZWZyZXNoOjpCZWdpblJlZnJlc2goKQ0KLXsNCi0JbV9SZWZyZXNoUmVjdHMuRW1wdHkoKTsNCi0JbV9PbGRMaW5lUmVjdHMgPSBtX05ld0xpbmVSZWN0czsNCi19DQotDQotdm9pZCBDRlhfRWRpdF9SZWZyZXNoOjpQdXNoKGNvbnN0IENQVlRfV29yZFJhbmdlICYgbGluZXJhbmdlLGNvbnN0IENQREZfUmVjdCAmIHJlY3QpDQotew0KLQltX05ld0xpbmVSZWN0cy5BZGQobGluZXJhbmdlLHJlY3QpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0X1JlZnJlc2g6Ok5vQW5hbHlzZSgpDQotew0KLQl7DQotCQlmb3IgKEZYX0lOVDMyIGkgPSAwLCBzeiA9IG1fT2xkTGluZVJlY3RzLkdldFNpemUoKTsgaSA8IHN6OyBpKyspDQotCQkJaWYgKENGWF9FZGl0X0xpbmVSZWN0ICogcE9sZFJlY3QgPSBtX09sZExpbmVSZWN0cy5HZXRBdChpKSkNCi0JCQkJbV9SZWZyZXNoUmVjdHMuQWRkKHBPbGRSZWN0LT5tX3JjTGluZSk7DQotCX0NCi0NCi0Jew0KLQkJZm9yIChGWF9JTlQzMiBpID0gMCwgc3ogPSBtX05ld0xpbmVSZWN0cy5HZXRTaXplKCk7IGkgPCBzejsgaSsrKQ0KLQkJCWlmIChDRlhfRWRpdF9MaW5lUmVjdCAqIHBOZXdSZWN0ID0gbV9OZXdMaW5lUmVjdHMuR2V0QXQoaSkpDQotCQkJCW1fUmVmcmVzaFJlY3RzLkFkZChwTmV3UmVjdC0+bV9yY0xpbmUpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXRfUmVmcmVzaDo6QW5hbHlzZShGWF9JTlQzMiBuQWxpZ25tZW50KQ0KLXsNCi0JRlhfQk9PTCBiTGluZVRvcENoYW5nZWQgPSBGQUxTRTsNCi0JQ1BERl9SZWN0IHJjUmVzdWx0Ow0KLQlGWF9GTE9BVCBmV2lkdGhEaWZmOw0KLQ0KLQlGWF9JTlQzMiBzek1heCA9IEZYX0VESVRfTUFYKG1fT2xkTGluZVJlY3RzLkdldFNpemUoKSxtX05ld0xpbmVSZWN0cy5HZXRTaXplKCkpOw0KLQlGWF9JTlQzMiBpID0gMDsNCi0NCi0Jd2hpbGUgKGkgPCBzek1heCkNCi0Jew0KLQkJQ0ZYX0VkaXRfTGluZVJlY3QgKiBwT2xkUmVjdCA9IG1fT2xkTGluZVJlY3RzLkdldEF0KGkpOw0KLQkJQ0ZYX0VkaXRfTGluZVJlY3QgKiBwTmV3UmVjdCA9IG1fTmV3TGluZVJlY3RzLkdldEF0KGkpOw0KLQ0KLQkJaWYgKHBPbGRSZWN0KQ0KLQkJew0KLQkJCWlmIChwTmV3UmVjdCkNCi0JCQl7DQotCQkJCWlmIChiTGluZVRvcENoYW5nZWQpDQotCQkJCXsNCi0JCQkJCXJjUmVzdWx0ID0gcE9sZFJlY3QtPm1fcmNMaW5lOw0KLQkJCQkJcmNSZXN1bHQuVW5pb24ocE5ld1JlY3QtPm1fcmNMaW5lKTsNCi0JCQkJCW1fUmVmcmVzaFJlY3RzLkFkZChyY1Jlc3VsdCk7DQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQl7DQotCQkJCQlpZiAoKnBOZXdSZWN0ICE9ICpwT2xkUmVjdCkNCi0JCQkJCXsNCi0JCQkJCQlpZiAoIXBOZXdSZWN0LT5Jc1NhbWVUb3AoKnBPbGRSZWN0KSB8fCAhcE5ld1JlY3QtPklzU2FtZUhlaWdodCgqcE9sZFJlY3QpKQ0KLQkJCQkJCXsNCi0JCQkJCQkJYkxpbmVUb3BDaGFuZ2VkID0gVFJVRTsNCi0JCQkJCQkJY29udGludWU7DQotCQkJCQkJfQ0KLQ0KLQkJCQkJCWlmIChuQWxpZ25tZW50ID09IDApDQotCQkJCQkJew0KLQkJCQkJCQlpZiAocE5ld1JlY3QtPm1fd3JMaW5lLkJlZ2luUG9zICE9IHBPbGRSZWN0LT5tX3dyTGluZS5CZWdpblBvcykNCi0JCQkJCQkJew0KLQkJCQkJCQkJcmNSZXN1bHQgPSBwT2xkUmVjdC0+bV9yY0xpbmU7DQotCQkJCQkJCQlyY1Jlc3VsdC5VbmlvbihwTmV3UmVjdC0+bV9yY0xpbmUpOw0KLQkJCQkJCQkJbV9SZWZyZXNoUmVjdHMuQWRkKHJjUmVzdWx0KTsJDQotCQkJCQkJCX0NCi0JCQkJCQkJZWxzZQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlpZiAoIXBOZXdSZWN0LT5Jc1NhbWVMZWZ0KCpwT2xkUmVjdCkpIA0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCXJjUmVzdWx0ID0gcE9sZFJlY3QtPm1fcmNMaW5lOw0KLQkJCQkJCQkJCXJjUmVzdWx0LlVuaW9uKHBOZXdSZWN0LT5tX3JjTGluZSk7CQkJCQkJCQkJCQ0KLQkJCQkJCQkJfQ0KLQkJCQkJCQkJZWxzZQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCWZXaWR0aERpZmYgPSBwTmV3UmVjdC0+bV9yY0xpbmUuV2lkdGgoKSAtIHBPbGRSZWN0LT5tX3JjTGluZS5XaWR0aCgpOw0KLQkJCQkJCQkJCXJjUmVzdWx0ID0gcE5ld1JlY3QtPm1fcmNMaW5lOw0KLQkJCQkJCQkJCWlmIChmV2lkdGhEaWZmID4gMC4wZikNCi0JCQkJCQkJCQkJcmNSZXN1bHQubGVmdCA9IHJjUmVzdWx0LnJpZ2h0IC0gZldpZHRoRGlmZjsNCi0JCQkJCQkJCQllbHNlDQotCQkJCQkJCQkJew0KLQkJCQkJCQkJCQlyY1Jlc3VsdC5sZWZ0ID0gcmNSZXN1bHQucmlnaHQ7DQotCQkJCQkJCQkJCXJjUmVzdWx0LnJpZ2h0ICs9ICgtZldpZHRoRGlmZik7DQotCQkJCQkJCQkJfQ0KLQkJCQkJCQkJfQ0KLQkJCQkJCQkJbV9SZWZyZXNoUmVjdHMuQWRkKHJjUmVzdWx0KTsNCi0JCQkJCQkJfQ0KLQkJCQkJCX0NCi0JCQkJCQllbHNlDQotCQkJCQkJew0KLQkJCQkJCQlyY1Jlc3VsdCA9IHBPbGRSZWN0LT5tX3JjTGluZTsNCi0JCQkJCQkJcmNSZXN1bHQuVW5pb24ocE5ld1JlY3QtPm1fcmNMaW5lKTsNCi0JCQkJCQkJbV9SZWZyZXNoUmVjdHMuQWRkKHJjUmVzdWx0KTsNCi0JCQkJCQl9DQotCQkJCQl9DQotCQkJCQllbHNlDQotCQkJCQl7DQotCQkJCQkJLy9kb24ndCBuZWVkIHRvIGRvIGFueXRoaW5nDQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJbV9SZWZyZXNoUmVjdHMuQWRkKHBPbGRSZWN0LT5tX3JjTGluZSk7DQotCQkJfQ0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChwTmV3UmVjdCkNCi0JCQl7DQotCQkJCW1fUmVmcmVzaFJlY3RzLkFkZChwTmV3UmVjdC0+bV9yY0xpbmUpOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQkvL2Vycm9yDQotCQkJfQ0KLQkJfQ0KLQkJaSsrOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXRfUmVmcmVzaDo6QWRkUmVmcmVzaChjb25zdCBDUERGX1JlY3QgJiByZWN0KQ0KLXsNCi0JbV9SZWZyZXNoUmVjdHMuQWRkKHJlY3QpOw0KLX0NCi0NCi1jb25zdCBDRlhfRWRpdF9SZWN0QXJyYXkgKiBDRlhfRWRpdF9SZWZyZXNoOjpHZXRSZWZyZXNoUmVjdHMoKSBjb25zdA0KLXsNCi0JcmV0dXJuICZtX1JlZnJlc2hSZWN0czsNCi19DQotDQotdm9pZCBDRlhfRWRpdF9SZWZyZXNoOjpFbmRSZWZyZXNoKCkNCi17DQotCW1fUmVmcmVzaFJlY3RzLkVtcHR5KCk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0VkaXRfVW5kbyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0ZYX0VkaXRfVW5kbzo6Q0ZYX0VkaXRfVW5kbyhGWF9JTlQzMiBuQnVmc2l6ZSkgOiBtX25DdXJVbmRvUG9zKDApLA0KLQltX25CdWZTaXplKG5CdWZzaXplKSwNCi0JbV9iTW9kaWZpZWQoRkFMU0UpLA0KLQltX2JWaXJnaW4oVFJVRSksDQotCW1fYldvcmtpbmcoRkFMU0UpDQotew0KLX0NCi0NCi1DRlhfRWRpdF9VbmRvOjp+Q0ZYX0VkaXRfVW5kbygpDQotew0KLQlSZXNldCgpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0X1VuZG86OkNhblVuZG8oKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fbkN1clVuZG9Qb3MgPiAwOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0X1VuZG86OlVuZG8oKQ0KLXsNCi0JbV9iV29ya2luZyA9IFRSVUU7DQotDQotCWlmIChtX25DdXJVbmRvUG9zID4gMCkNCi0Jew0KLQkJSUZYX0VkaXRfVW5kb0l0ZW0gKiBwSXRlbSA9IG1fVW5kb0l0ZW1TdGFjay5HZXRBdChtX25DdXJVbmRvUG9zLTEpOw0KLQkJQVNTRVJUKHBJdGVtICE9IE5VTEwpOw0KLQ0KLQkJcEl0ZW0tPlVuZG8oKTsNCi0JDQotCQltX25DdXJVbmRvUG9zLS07DQotCQltX2JNb2RpZmllZCA9IChtX25DdXJVbmRvUG9zICE9IDApOwkJDQotCX0NCi0NCi0JbV9iV29ya2luZyA9IEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNGWF9FZGl0X1VuZG86OkNhblJlZG8oKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fbkN1clVuZG9Qb3MgPCBtX1VuZG9JdGVtU3RhY2suR2V0U2l6ZSgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0X1VuZG86OlJlZG8oKQ0KLXsNCi0JbV9iV29ya2luZyA9IFRSVUU7DQotDQotCUZYX0lOVDMyIG5TdGFja1NpemUgPSBtX1VuZG9JdGVtU3RhY2suR2V0U2l6ZSgpOw0KLQ0KLQlpZiAobV9uQ3VyVW5kb1BvcyA8IG5TdGFja1NpemUpDQotCXsNCi0JCUlGWF9FZGl0X1VuZG9JdGVtICogcEl0ZW0gPSBtX1VuZG9JdGVtU3RhY2suR2V0QXQobV9uQ3VyVW5kb1Bvcyk7DQotCQlBU1NFUlQocEl0ZW0gIT0gTlVMTCk7DQotDQotCQlwSXRlbS0+UmVkbygpOw0KLQ0KLQkJbV9uQ3VyVW5kb1BvcysrOw0KLQkJbV9iTW9kaWZpZWQgPSAobV9uQ3VyVW5kb1BvcyAhPSAwKTsJCQ0KLQl9DQotDQotCW1fYldvcmtpbmcgPSBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDRlhfRWRpdF9VbmRvOjpJc1dvcmtpbmcoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fYldvcmtpbmc7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXRfVW5kbzo6QWRkSXRlbShJRlhfRWRpdF9VbmRvSXRlbSogcEl0ZW0pDQotew0KLQlBU1NFUlQoIW1fYldvcmtpbmcpOw0KLQlBU1NFUlQocEl0ZW0gIT0gTlVMTCk7DQotCUFTU0VSVChtX25CdWZTaXplID4gMSk7DQotCQ0KLQlpZiAobV9uQ3VyVW5kb1BvcyA8IG1fVW5kb0l0ZW1TdGFjay5HZXRTaXplKCkpDQotCQlSZW1vdmVUYWlscygpOw0KLQ0KLQlpZiAobV9VbmRvSXRlbVN0YWNrLkdldFNpemUoKSA+PSBtX25CdWZTaXplKQ0KLQl7DQotCQlSZW1vdmVIZWFkcygpOwkNCi0JCW1fYlZpcmdpbiA9IEZBTFNFOw0KLQl9DQotDQotCW1fVW5kb0l0ZW1TdGFjay5BZGQocEl0ZW0pOwkNCi0JbV9uQ3VyVW5kb1BvcyA9IG1fVW5kb0l0ZW1TdGFjay5HZXRTaXplKCk7DQotDQotCW1fYk1vZGlmaWVkID0gKG1fbkN1clVuZG9Qb3MgIT0gMCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX0VkaXRfVW5kbzo6SXNNb2RpZmllZCgpIGNvbnN0DQotew0KLQlpZiAobV9iVmlyZ2luKQ0KLQkJcmV0dXJuIG1fYk1vZGlmaWVkOw0KLQllbHNlDQotCQlyZXR1cm4gVFJVRTsNCi19DQotDQotSUZYX0VkaXRfVW5kb0l0ZW0qIENGWF9FZGl0X1VuZG86OkdldEl0ZW0oRlhfSU5UMzIgbkluZGV4KQ0KLXsNCi0JaWYgKG5JbmRleD49MCAmJiBuSW5kZXggPCBtX1VuZG9JdGVtU3RhY2suR2V0U2l6ZSgpKQ0KLQkJcmV0dXJuIG1fVW5kb0l0ZW1TdGFjay5HZXRBdChuSW5kZXgpOw0KLQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCBDRlhfRWRpdF9VbmRvOjpSZW1vdmVIZWFkcygpDQotew0KLQlBU1NFUlQobV9VbmRvSXRlbVN0YWNrLkdldFNpemUoKSA+IDEpOw0KLQ0KLQlJRlhfRWRpdF9VbmRvSXRlbSogcEl0ZW0gPSBtX1VuZG9JdGVtU3RhY2suR2V0QXQoMCk7DQotCUFTU0VSVChwSXRlbSAhPSBOVUxMKTsNCi0NCi0JcEl0ZW0tPlJlbGVhc2UoKTsNCi0JbV9VbmRvSXRlbVN0YWNrLlJlbW92ZUF0KDApOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0X1VuZG86OlJlbW92ZVRhaWxzKCkNCi17DQotCWZvciAoRlhfSU5UMzIgaSA9IG1fVW5kb0l0ZW1TdGFjay5HZXRTaXplKCktMTsgaSA+PSBtX25DdXJVbmRvUG9zOyBpLS0pDQotCXsNCi0JCUlGWF9FZGl0X1VuZG9JdGVtKiBwSXRlbSA9IG1fVW5kb0l0ZW1TdGFjay5HZXRBdChpKTsNCi0JCUFTU0VSVChwSXRlbSAhPSBOVUxMKTsNCi0NCi0JCXBJdGVtLT5SZWxlYXNlKCk7DQotCQltX1VuZG9JdGVtU3RhY2suUmVtb3ZlQXQoaSk7DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdF9VbmRvOjpSZXNldCgpDQotew0KLQlmb3IgKEZYX0lOVDMyIGk9MCwgc3o9bV9VbmRvSXRlbVN0YWNrLkdldFNpemUoKTsgaSA8IHN6OyBpKyspDQotCXsNCi0JCUlGWF9FZGl0X1VuZG9JdGVtICogcEl0ZW0gPSBtX1VuZG9JdGVtU3RhY2suR2V0QXQoaSk7DQotCQlBU1NFUlQocEl0ZW0gIT0gTlVMTCk7DQotDQotCQlwSXRlbS0+UmVsZWFzZSgpOw0KLQl9DQotCW1fbkN1clVuZG9Qb3MgPSAwOw0KLQltX1VuZG9JdGVtU3RhY2suUmVtb3ZlQWxsKCk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X0dyb3VwVW5kb0l0ZW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DRlhfRWRpdF9Hcm91cFVuZG9JdGVtOjpDRlhfRWRpdF9Hcm91cFVuZG9JdGVtKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGl0bGUpIDogbV9zVGl0bGUoc1RpdGxlKQ0KLXsNCi19DQotDQotQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbTo6fkNGWF9FZGl0X0dyb3VwVW5kb0l0ZW0oKQ0KLXsNCi0JZm9yIChpbnQgaT0wLHN6PW1fSXRlbXMuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCUNGWF9FZGl0X1VuZG9JdGVtKiBwVW5kb0l0ZW0gPSBtX0l0ZW1zW2ldOw0KLQkJQVNTRVJUKHBVbmRvSXRlbSAhPSBOVUxMKTsNCi0NCi0JCXBVbmRvSXRlbS0+UmVsZWFzZSgpOw0KLQl9DQotDQotCW1fSXRlbXMuUmVtb3ZlQWxsKCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbTo6QWRkVW5kb0l0ZW0oQ0ZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSkNCi17DQotCUFTU0VSVChwVW5kb0l0ZW0gIT0gTlVMTCk7DQotDQotCXBVbmRvSXRlbS0+U2V0Rmlyc3QoRkFMU0UpOw0KLQlwVW5kb0l0ZW0tPlNldExhc3QoRkFMU0UpOw0KLQ0KLQltX0l0ZW1zLkFkZChwVW5kb0l0ZW0pOw0KLQ0KLQlpZiAobV9zVGl0bGUuSXNFbXB0eSgpKQ0KLQkJbV9zVGl0bGUgPSBwVW5kb0l0ZW0tPkdldFVuZG9UaXRsZSgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0X0dyb3VwVW5kb0l0ZW06OlVwZGF0ZUl0ZW1zKCkNCi17DQotCWlmIChtX0l0ZW1zLkdldFNpemUoKSA+IDApDQotCXsNCi0JCUNGWF9FZGl0X1VuZG9JdGVtKiBwRmlyc3RJdGVtID0gbV9JdGVtc1swXTsNCi0JCUFTU0VSVChwRmlyc3RJdGVtICE9IE5VTEwpOw0KLQkJcEZpcnN0SXRlbS0+U2V0Rmlyc3QoVFJVRSk7DQotDQotCQlDRlhfRWRpdF9VbmRvSXRlbSogcExhc3RJdGVtID0gbV9JdGVtc1ttX0l0ZW1zLkdldFNpemUoKSAtIDFdOw0KLQkJQVNTRVJUKHBMYXN0SXRlbSAhPSBOVUxMKTsNCi0JCXBMYXN0SXRlbS0+U2V0TGFzdChUUlVFKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0X0dyb3VwVW5kb0l0ZW06OlVuZG8oKQ0KLXsNCi0JZm9yIChpbnQgaT1tX0l0ZW1zLkdldFNpemUoKS0xOyBpPj0wOyBpLS0pDQotCXsNCi0JCUNGWF9FZGl0X1VuZG9JdGVtKiBwVW5kb0l0ZW0gPSBtX0l0ZW1zW2ldOw0KLQkJQVNTRVJUKHBVbmRvSXRlbSAhPSBOVUxMKTsNCi0NCi0JCXBVbmRvSXRlbS0+VW5kbygpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbTo6UmVkbygpDQotew0KLQlmb3IgKGludCBpPTAsc3o9bV9JdGVtcy5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJQ0ZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSA9IG1fSXRlbXNbaV07DQotCQlBU1NFUlQocFVuZG9JdGVtICE9IE5VTEwpOw0KLQ0KLQkJcFVuZG9JdGVtLT5SZWRvKCk7DQotCX0NCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbTo6R2V0VW5kb1RpdGxlKCkNCi17DQotCXJldHVybiBtX3NUaXRsZTsNCi19DQotDQotdm9pZCBDRlhfRWRpdF9Hcm91cFVuZG9JdGVtOjpSZWxlYXNlKCkNCi17DQotCWRlbGV0ZSB0aGlzOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X1VuZG9JdGVtIGRlcml2ZWQgY2xhc3NlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0ZYRVVfSW5zZXJ0V29yZDo6Q0ZYRVVfSW5zZXJ0V29yZChDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwT2xkUGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BOZXdQbGFjZSwNCi0JCQkJCQkJCSBGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIGNoYXJzZXQsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcykgDQotCTogbV9wRWRpdChwRWRpdCksIG1fd3BPbGQod3BPbGRQbGFjZSksIG1fd3BOZXcod3BOZXdQbGFjZSksIG1fV29yZCh3b3JkKSwgbV9uQ2hhcnNldChjaGFyc2V0KSwgbV9Xb3JkUHJvcHMoKQ0KLXsNCi0JaWYgKHBXb3JkUHJvcHMpDQotCQltX1dvcmRQcm9wcyA9ICpwV29yZFByb3BzOw0KLX0NCi0NCi1DRlhFVV9JbnNlcnRXb3JkOjp+Q0ZYRVVfSW5zZXJ0V29yZCgpDQotew0KLX0NCi0NCi12b2lkIENGWEVVX0luc2VydFdvcmQ6OlJlZG8oKQ0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCXsNCi0JCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JCW1fcEVkaXQtPlNldENhcmV0KG1fd3BPbGQpOwkJDQotCQltX3BFZGl0LT5JbnNlcnRXb3JkKG1fV29yZCxtX25DaGFyc2V0LCZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGWEVVX0luc2VydFdvcmQ6OlVuZG8oKQ0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCXsNCi0JCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JCW1fcEVkaXQtPlNldENhcmV0KG1fd3BOZXcpOw0KLQkJbV9wRWRpdC0+QmFja3NwYWNlKEZBTFNFLFRSVUUpOw0KLQl9DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0ZYRVVfSW5zZXJ0UmV0dXJuOjpDRlhFVV9JbnNlcnRSZXR1cm4oQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsDQotCQkJIGNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcykgOg0KLQkJCW1fcEVkaXQocEVkaXQpLA0KLQkJCW1fd3BPbGQod3BPbGRQbGFjZSksDQotCQkJbV93cE5ldyh3cE5ld1BsYWNlKSwNCi0JCQltX1NlY1Byb3BzKCksDQotCQkJbV9Xb3JkUHJvcHMoKQkJCQkJCQkJCSANCi17DQotCWlmIChwU2VjUHJvcHMpDQotCQltX1NlY1Byb3BzID0gKnBTZWNQcm9wczsNCi0JaWYgKHBXb3JkUHJvcHMpDQotCQltX1dvcmRQcm9wcyA9ICpwV29yZFByb3BzOw0KLX0NCi0NCi1DRlhFVV9JbnNlcnRSZXR1cm46On5DRlhFVV9JbnNlcnRSZXR1cm4oKQ0KLXsNCi19DQotDQotdm9pZCBDRlhFVV9JbnNlcnRSZXR1cm46OlJlZG8oKQ0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCXsNCi0JCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JCW1fcEVkaXQtPlNldENhcmV0KG1fd3BPbGQpOw0KLQkJbV9wRWRpdC0+SW5zZXJ0UmV0dXJuKCZtX1NlY1Byb3BzLCZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGWEVVX0luc2VydFJldHVybjo6VW5kbygpDQotew0KLQlpZiAobV9wRWRpdCkNCi0Jew0KLQkJbV9wRWRpdC0+U2VsZWN0Tm9uZSgpOw0KLQkJbV9wRWRpdC0+U2V0Q2FyZXQobV93cE5ldyk7DQotCQltX3BFZGl0LT5CYWNrc3BhY2UoRkFMU0UsVFJVRSk7DQotCX0NCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0vL0NGWEVVX0JhY2tzcGFjZQ0KLQ0KLUNGWEVVX0JhY2tzcGFjZTo6Q0ZYRVVfQmFja3NwYWNlKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLA0KLQkJCQkJCQkgICBGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIGNoYXJzZXQsDQotCQkJCQkJCSAgIGNvbnN0IENQVlRfU2VjUHJvcHMgJiBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBXb3JkUHJvcHMpIDoNCi0JCQltX3BFZGl0KHBFZGl0KSwNCi0JCQltX3dwT2xkKHdwT2xkUGxhY2UpLA0KLQkJCW1fd3BOZXcod3BOZXdQbGFjZSksDQotCQkJbV9Xb3JkKHdvcmQpLA0KLQkJCW1fbkNoYXJzZXQoY2hhcnNldCksDQotCQkJbV9TZWNQcm9wcyhTZWNQcm9wcyksDQotCQkJbV9Xb3JkUHJvcHMoV29yZFByb3BzKQkJCQkJCQkJCSANCi17DQotfQ0KLQ0KLUNGWEVVX0JhY2tzcGFjZTo6fkNGWEVVX0JhY2tzcGFjZSgpDQotew0KLX0NCi0NCi12b2lkIENGWEVVX0JhY2tzcGFjZTo6UmVkbygpDQotew0KLQlpZiAobV9wRWRpdCkNCi0Jew0KLQkJbV9wRWRpdC0+U2VsZWN0Tm9uZSgpOw0KLQkJbV9wRWRpdC0+U2V0Q2FyZXQobV93cE9sZCk7DQotCQltX3BFZGl0LT5CYWNrc3BhY2UoRkFMU0UsVFJVRSk7DQotCX0NCi19DQotDQotdm9pZCBDRlhFVV9CYWNrc3BhY2U6OlVuZG8oKQ0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCXsNCi0JCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JCW1fcEVkaXQtPlNldENhcmV0KG1fd3BOZXcpOw0KLQkJaWYgKG1fd3BOZXcuU2VjQ21wKG1fd3BPbGQpICE9IDApDQotCQl7DQotCQkJbV9wRWRpdC0+SW5zZXJ0UmV0dXJuKCZtX1NlY1Byb3BzLCZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQltX3BFZGl0LT5JbnNlcnRXb3JkKG1fV29yZCxtX25DaGFyc2V0LCZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLS8vQ0ZYRVVfRGVsZXRlDQotDQotQ0ZYRVVfRGVsZXRlOjpDRlhFVV9EZWxldGUoQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsDQotCQkJCQkJCSAgIEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgY2hhcnNldCwNCi0JCQkJCQkJICAgY29uc3QgQ1BWVF9TZWNQcm9wcyAmIFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIFdvcmRQcm9wcywgRlhfQk9PTCBiU2VjRW5kKSA6DQotCQkJbV9wRWRpdChwRWRpdCksDQotCQkJbV93cE9sZCh3cE9sZFBsYWNlKSwNCi0JCQltX3dwTmV3KHdwTmV3UGxhY2UpLA0KLQkJCW1fV29yZCh3b3JkKSwNCi0JCQltX25DaGFyc2V0KGNoYXJzZXQpLA0KLQkJCW1fU2VjUHJvcHMoU2VjUHJvcHMpLA0KLQkJCW1fV29yZFByb3BzKFdvcmRQcm9wcyksDQotCQkJbV9iU2VjRW5kKGJTZWNFbmQpDQotew0KLX0NCi0NCi1DRlhFVV9EZWxldGU6On5DRlhFVV9EZWxldGUoKQ0KLXsNCi19DQotDQotdm9pZCBDRlhFVV9EZWxldGU6OlJlZG8oKQ0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCXsNCi0JCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JCW1fcEVkaXQtPlNldENhcmV0KG1fd3BPbGQpOw0KLQkJbV9wRWRpdC0+RGVsZXRlKEZBTFNFLFRSVUUpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYRVVfRGVsZXRlOjpVbmRvKCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7DQotCQltX3BFZGl0LT5TZXRDYXJldChtX3dwTmV3KTsNCi0JCWlmIChtX2JTZWNFbmQpDQotCQl7DQotCQkJbV9wRWRpdC0+SW5zZXJ0UmV0dXJuKCZtX1NlY1Byb3BzLCZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQltX3BFZGl0LT5JbnNlcnRXb3JkKG1fV29yZCxtX25DaGFyc2V0LCZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLS8vQ0ZYRVVfQ2xlYXINCi0NCi1DRlhFVV9DbGVhcjo6Q0ZYRVVfQ2xlYXIoQ0ZYX0VkaXQgKiBwRWRpdCwgIGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3JTZWwsIGNvbnN0IENGWF9XaWRlU3RyaW5nICYgc3dUZXh0KSA6DQotCQkJbV9wRWRpdChwRWRpdCksDQotCQkJbV93clNlbCh3clNlbCksDQotCQkJbV9zd1RleHQoc3dUZXh0KQ0KLXsNCi19DQotDQotQ0ZYRVVfQ2xlYXI6On5DRlhFVV9DbGVhcigpDQotew0KLX0NCi0NCi12b2lkIENGWEVVX0NsZWFyOjpSZWRvKCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7DQotCQltX3BFZGl0LT5TZXRTZWwobV93clNlbC5CZWdpblBvcyxtX3dyU2VsLkVuZFBvcyk7DQotCQltX3BFZGl0LT5DbGVhcihGQUxTRSxUUlVFKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGWEVVX0NsZWFyOjpVbmRvKCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7DQotCQltX3BFZGl0LT5TZXRDYXJldChtX3dyU2VsLkJlZ2luUG9zKTsNCi0JCW1fcEVkaXQtPkluc2VydFRleHQobV9zd1RleHQsIERFRkFVTFRfQ0hBUlNFVCwgTlVMTCxOVUxMLEZBTFNFLFRSVUUpOw0KLQkJbV9wRWRpdC0+U2V0U2VsKG1fd3JTZWwuQmVnaW5Qb3MsbV93clNlbC5FbmRQb3MpOw0KLQl9DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotLy9DRlhFVV9DbGVhclJpY2gNCi0NCi1DRlhFVV9DbGVhclJpY2g6OkNGWEVVX0NsZWFyUmljaChDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwT2xkUGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BOZXdQbGFjZSwNCi0JCQkJCQkJICAgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3clNlbCwgRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LA0KLQkJCQkJCQkgICBjb25zdCBDUFZUX1NlY1Byb3BzICYgU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgV29yZFByb3BzKSA6DQotCQkJbV9wRWRpdChwRWRpdCksDQotCQkJbV93cE9sZCh3cE9sZFBsYWNlKSwNCi0JCQltX3dwTmV3KHdwTmV3UGxhY2UpLA0KLQkJCW1fd3JTZWwod3JTZWwpLA0KLQkJCW1fV29yZCh3b3JkKSwNCi0JCQltX25DaGFyc2V0KGNoYXJzZXQpLA0KLQkJCW1fU2VjUHJvcHMoU2VjUHJvcHMpLA0KLQkJCW1fV29yZFByb3BzKFdvcmRQcm9wcykJCQkJCQkJCQkgDQotew0KLX0NCi0NCi1DRlhFVV9DbGVhclJpY2g6On5DRlhFVV9DbGVhclJpY2goKQ0KLXsNCi19DQotDQotdm9pZCBDRlhFVV9DbGVhclJpY2g6OlJlZG8oKQ0KLXsNCi0JaWYgKG1fcEVkaXQgJiYgSXNMYXN0KCkpDQotCXsNCi0JCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JCW1fcEVkaXQtPlNldFNlbChtX3dyU2VsLkJlZ2luUG9zLG1fd3JTZWwuRW5kUG9zKTsNCi0JCW1fcEVkaXQtPkNsZWFyKEZBTFNFLFRSVUUpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYRVVfQ2xlYXJSaWNoOjpVbmRvKCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7DQotCQltX3BFZGl0LT5TZXRDYXJldChtX3dwT2xkKTsNCi0JCWlmIChtX3dwTmV3LlNlY0NtcChtX3dwT2xkKSAhPSAwKQ0KLQkJew0KLQkJCW1fcEVkaXQtPkluc2VydFJldHVybigmbV9TZWNQcm9wcywmbV9Xb3JkUHJvcHMsRkFMU0UsRkFMU0UpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCW1fcEVkaXQtPkluc2VydFdvcmQobV9Xb3JkLG1fbkNoYXJzZXQsJm1fV29yZFByb3BzLEZBTFNFLEZBTFNFKTsNCi0JCX0NCi0NCi0JCWlmIChJc0ZpcnN0KCkpDQotCQl7DQotCQkJbV9wRWRpdC0+UGFpbnRJbnNlcnRUZXh0KG1fd3JTZWwuQmVnaW5Qb3MsbV93clNlbC5FbmRQb3MpOw0KLQkJCW1fcEVkaXQtPlNldFNlbChtX3dyU2VsLkJlZ2luUG9zLG1fd3JTZWwuRW5kUG9zKTsNCi0JCX0NCi0JfQ0KLX0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLS8vQ0ZYRVVfSW5zZXJ0VGV4dA0KLQ0KLUNGWEVVX0luc2VydFRleHQ6OkNGWEVVX0luc2VydFRleHQoQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsDQotCQkJCQkJCSAgIGNvbnN0IENGWF9XaWRlU3RyaW5nICYgc3dUZXh0LCBGWF9JTlQzMiBjaGFyc2V0LA0KLQkJCQkJCQkgICBjb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpIDoNCi0JCQltX3BFZGl0KHBFZGl0KSwNCi0JCQltX3dwT2xkKHdwT2xkUGxhY2UpLA0KLQkJCW1fd3BOZXcod3BOZXdQbGFjZSksDQotCQkJbV9zd1RleHQoc3dUZXh0KSwNCi0JCQltX25DaGFyc2V0KGNoYXJzZXQpLA0KLQkJCW1fU2VjUHJvcHMoKSwNCi0JCQltX1dvcmRQcm9wcygpCQkJCQkJCQkJIA0KLXsNCi0JaWYgKHBTZWNQcm9wcykNCi0JCW1fU2VjUHJvcHMgPSAqcFNlY1Byb3BzOw0KLQlpZiAocFdvcmRQcm9wcykNCi0JCW1fV29yZFByb3BzID0gKnBXb3JkUHJvcHM7DQotfQ0KLQ0KLUNGWEVVX0luc2VydFRleHQ6On5DRlhFVV9JbnNlcnRUZXh0KCkNCi17DQotfQ0KLQ0KLXZvaWQgQ0ZYRVVfSW5zZXJ0VGV4dDo6UmVkbygpDQotew0KLQlpZiAobV9wRWRpdCAmJiBJc0xhc3QoKSkNCi0Jew0KLQkJbV9wRWRpdC0+U2VsZWN0Tm9uZSgpOw0KLQkJbV9wRWRpdC0+U2V0Q2FyZXQobV93cE9sZCk7DQotCQltX3BFZGl0LT5JbnNlcnRUZXh0KG1fc3dUZXh0LCBtX25DaGFyc2V0LCZtX1NlY1Byb3BzLCAmbV9Xb3JkUHJvcHMsRkFMU0UsVFJVRSk7DQotCX0NCi19DQotDQotdm9pZCBDRlhFVV9JbnNlcnRUZXh0OjpVbmRvKCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7DQotCQltX3BFZGl0LT5TZXRTZWwobV93cE9sZCxtX3dwTmV3KTsNCi0JCW1fcEVkaXQtPkNsZWFyKEZBTFNFLFRSVUUpOw0KLQl9DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0ZYRVVfU2V0U2VjUHJvcHM6OkNGWEVVX1NldFNlY1Byb3BzKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UsIEVESVRfUFJPUFNfRSBlcCwgDQotCQljb25zdCBDUFZUX1NlY1Byb3BzICYgb2xkc2VjcHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgb2xkd29yZHByb3BzLCANCi0JCWNvbnN0IENQVlRfU2VjUHJvcHMgJiBuZXdzZWNwcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBuZXd3b3JkcHJvcHMsIGNvbnN0IENQVlRfV29yZFJhbmdlICYgcmFuZ2UpDQotCQk6IG1fcEVkaXQocEVkaXQpLA0KLQkJbV93cFBsYWNlKHBsYWNlKSwNCi0JCW1fZVByb3BzKGVwKSwNCi0JCW1fT2xkU2VjUHJvcHMob2xkc2VjcHJvcHMpLA0KLQkJbV9OZXdTZWNQcm9wcyhuZXdzZWNwcm9wcyksDQotCQltX09sZFdvcmRQcm9wcyhvbGR3b3JkcHJvcHMpLA0KLQkJbV9OZXdXb3JkUHJvcHMobmV3d29yZHByb3BzKSwNCi0JCW1fd3JQbGFjZShyYW5nZSkNCi17DQotfQ0KLQ0KLUNGWEVVX1NldFNlY1Byb3BzOjp+Q0ZYRVVfU2V0U2VjUHJvcHMoKQ0KLXsNCi19DQotDQotdm9pZCBDRlhFVV9TZXRTZWNQcm9wczo6UmVkbygpDQotew0KLQlpZiAobV9wRWRpdCkNCi0Jew0KLQkJbV9wRWRpdC0+U2V0U2VjUHJvcHMobV9lUHJvcHMsbV93cFBsYWNlLCZtX05ld1NlY1Byb3BzLCZtX05ld1dvcmRQcm9wcyxtX3dyUGxhY2UsRkFMU0UpOw0KLQkJaWYgKElzTGFzdCgpKQ0KLQkJew0KLQkJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JCQltX3BFZGl0LT5QYWludFNldFByb3BzKG1fZVByb3BzLG1fd3JQbGFjZSk7DQotCQkJbV9wRWRpdC0+U2V0U2VsKG1fd3JQbGFjZS5CZWdpblBvcyxtX3dyUGxhY2UuRW5kUG9zKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENGWEVVX1NldFNlY1Byb3BzOjpVbmRvKCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5TZXRTZWNQcm9wcyhtX2VQcm9wcyxtX3dwUGxhY2UsJm1fT2xkU2VjUHJvcHMsJm1fT2xkV29yZFByb3BzLG1fd3JQbGFjZSxGQUxTRSk7DQotCQlpZiAoSXNGaXJzdCgpKQ0KLQkJew0KLQkJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JCQltX3BFZGl0LT5QYWludFNldFByb3BzKG1fZVByb3BzLG1fd3JQbGFjZSk7DQotCQkJbV9wRWRpdC0+U2V0U2VsKG1fd3JQbGFjZS5CZWdpblBvcyxtX3dyUGxhY2UuRW5kUG9zKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGWEVVX1NldFdvcmRQcm9wczo6Q0ZYRVVfU2V0V29yZFByb3BzKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UsIEVESVRfUFJPUFNfRSBlcCwgDQotCQljb25zdCBDUFZUX1dvcmRQcm9wcyAmIG9sZHByb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIG5ld3Byb3BzLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKQ0KLQkJOiBtX3BFZGl0KHBFZGl0KSwNCi0JCW1fd3BQbGFjZShwbGFjZSksDQotCQltX2VQcm9wcyhlcCksDQotCQltX09sZFdvcmRQcm9wcyhvbGRwcm9wcyksDQotCQltX05ld1dvcmRQcm9wcyhuZXdwcm9wcyksDQotCQltX3dyUGxhY2UocmFuZ2UpDQotew0KLX0NCi0NCi1DRlhFVV9TZXRXb3JkUHJvcHM6On5DRlhFVV9TZXRXb3JkUHJvcHMoKQ0KLXsNCi19DQotDQotdm9pZCBDRlhFVV9TZXRXb3JkUHJvcHM6OlJlZG8oKQ0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCXsNCi0JCW1fcEVkaXQtPlNldFdvcmRQcm9wcyhtX2VQcm9wcyxtX3dwUGxhY2UsJm1fTmV3V29yZFByb3BzLG1fd3JQbGFjZSxGQUxTRSk7DQotCQlpZiAoSXNMYXN0KCkpDQotCQl7DQotCQkJbV9wRWRpdC0+U2VsZWN0Tm9uZSgpOw0KLQkJCW1fcEVkaXQtPlBhaW50U2V0UHJvcHMobV9lUHJvcHMsbV93clBsYWNlKTsNCi0JCQltX3BFZGl0LT5TZXRTZWwobV93clBsYWNlLkJlZ2luUG9zLG1fd3JQbGFjZS5FbmRQb3MpOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYRVVfU2V0V29yZFByb3BzOjpVbmRvKCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5TZXRXb3JkUHJvcHMobV9lUHJvcHMsbV93cFBsYWNlLCZtX09sZFdvcmRQcm9wcyxtX3dyUGxhY2UsRkFMU0UpOw0KLQkJaWYgKElzRmlyc3QoKSkNCi0JCXsNCi0JCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7DQotCQkJbV9wRWRpdC0+UGFpbnRTZXRQcm9wcyhtX2VQcm9wcyxtX3dyUGxhY2UpOw0KLQkJCW1fcEVkaXQtPlNldFNlbChtX3dyUGxhY2UuQmVnaW5Qb3MsbV93clBsYWNlLkVuZFBvcyk7DQotCQl9DQotCX0NCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0ZYX0VkaXQ6OkNGWF9FZGl0KElQREZfVmFyaWFibGVUZXh0ICogcFZUKSA6DQotCW1fcFZUKHBWVCksDQotCW1fcE5vdGlmeShOVUxMKSwNCi0JbV9wT3ByTm90aWZ5KE5VTEwpLA0KLQltX3dwQ2FyZXQoLTEsLTEsLTEpLA0KLQltX3dwT2xkQ2FyZXQoLTEsLTEsLTEpLA0KLQltX3B0U2Nyb2xsUG9zKDAsMCksDQotCW1fcHRSZWZyZXNoU2Nyb2xsUG9zKDAsMCksDQotCW1fYkVuYWJsZVNjcm9sbChGQUxTRSksDQotCW1fYkVuYWJsZU92ZXJmbG93KEZBTFNFKSwNCi0JbV9wVlRQcm92aWRlKE5VTEwpLA0KLQltX3BJdGVyYXRvcihOVUxMKSwNCi0JbV9TZWxTdGF0ZSgpLA0KLQltX3B0Q2FyZXQoMC4wZiwwLjBmKSwNCi0JbV9VbmRvKEZYX0VESVRfVU5ET19NQVhJVEVNKSwNCi0JbV9uQWxpZ25tZW50KDApLA0KLQltX2JOb3RpZnlGbGFnKEZBTFNFKSwNCi0JbV9iRW5hYmxlUmVmcmVzaChUUlVFKSwNCi0JbV9yY09sZENvbnRlbnQoMC4wZiwwLjBmLDAuMGYsMC4wZiksDQotCW1fYkVuYWJsZVVuZG8oVFJVRSksDQotCW1fYk5vdGlmeShUUlVFKSwNCi0JbV9iT3ByTm90aWZ5KEZBTFNFKSwNCi0JbV9wR3JvdXBVbmRvSXRlbShOVUxMKQ0KLXsJDQotCUFTU0VSVChwVlQgIT0gTlVMTCk7DQotfQ0KLQ0KLUNGWF9FZGl0Ojp+Q0ZYX0VkaXQoKQ0KLXsNCi0JaWYgKG1fcFZUUHJvdmlkZSkNCi0Jew0KLQkJZGVsZXRlIG1fcFZUUHJvdmlkZTsNCi0JCW1fcFZUUHJvdmlkZSA9IE5VTEw7DQotCX0NCi0NCi0JaWYgKG1fcEl0ZXJhdG9yKQ0KLQl7DQotCQlkZWxldGUgbV9wSXRlcmF0b3I7DQotCQltX3BJdGVyYXRvciA9IE5VTEw7DQotCX0NCi0NCi0JQVNTRVJUKG1fcEdyb3VwVW5kb0l0ZW0gPT0gTlVMTCk7DQotfQ0KLQ0KLS8vIHB1YmxpYyBtZXRob2RzDQotDQotdm9pZCBDRlhfRWRpdDo6SW5pdGlhbGl6ZSgpDQotew0KLQltX3BWVC0+SW5pdGlhbGl6ZSgpOw0KLQlTZXRDYXJldChtX3BWVC0+R2V0QmVnaW5Xb3JkUGxhY2UoKSk7DQotCVNldENhcmV0T3JpZ2luKCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldEZvbnRNYXAoSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwKQ0KLXsNCi0JaWYgKG1fcFZUUHJvdmlkZSkgDQotCQlkZWxldGUgbV9wVlRQcm92aWRlOw0KLQ0KLQltX3BWVC0+U2V0UHJvdmlkZXIobV9wVlRQcm92aWRlID0gbmV3IENGWF9FZGl0X1Byb3ZpZGVyKHBGb250TWFwKSk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldFZUUHJvdmlkZXIoSVBERl9WYXJpYWJsZVRleHRfUHJvdmlkZXIqIHBQcm92aWRlcikNCi17DQotCW1fcFZULT5TZXRQcm92aWRlcihwUHJvdmlkZXIpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXROb3RpZnkoSUZYX0VkaXRfTm90aWZ5KiBwTm90aWZ5KQ0KLXsNCi0JbV9wTm90aWZ5ID0gcE5vdGlmeTsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0T3ByTm90aWZ5KElGWF9FZGl0X09wck5vdGlmeSogcE9wck5vdGlmeSkNCi17DQotCW1fcE9wck5vdGlmeSA9IHBPcHJOb3RpZnk7DQotfQ0KLQ0KLUlGWF9FZGl0X0l0ZXJhdG9yICogQ0ZYX0VkaXQ6OkdldEl0ZXJhdG9yKCkNCi17DQotCWlmICghbV9wSXRlcmF0b3IpDQotCQltX3BJdGVyYXRvciA9IG5ldyBDRlhfRWRpdF9JdGVyYXRvcih0aGlzLG1fcFZULT5HZXRJdGVyYXRvcigpKTsNCi0NCi0JcmV0dXJuIG1fcEl0ZXJhdG9yOw0KLX0NCi0NCi1JUERGX1ZhcmlhYmxlVGV4dCAqCUNGWF9FZGl0OjpHZXRWYXJpYWJsZVRleHQoKQ0KLXsNCi0JcmV0dXJuIG1fcFZUOw0KLX0NCi0NCi1JRlhfRWRpdF9Gb250TWFwKiBDRlhfRWRpdDo6R2V0Rm9udE1hcCgpDQotew0KLQlpZiAobV9wVlRQcm92aWRlKQ0KLQkJcmV0dXJuIG1fcFZUUHJvdmlkZS0+R2V0Rm9udE1hcCgpOw0KLQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0UGxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QsIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotewkNCi0JbV9wVlQtPlNldFBsYXRlUmVjdChyZWN0KTsNCi0JbV9wdFNjcm9sbFBvcyA9IENQREZfUG9pbnQocmVjdC5sZWZ0LHJlY3QudG9wKTsJCQkNCi0JaWYgKGJQYWludCkgUGFpbnQoKTsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0QWxpZ25tZW50SChGWF9JTlQzMiBuRm9ybWF0LyogPTAgKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BWVC0+U2V0QWxpZ25tZW50KG5Gb3JtYXQpOw0KLQlpZiAoYlBhaW50KSBQYWludCgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRBbGlnbm1lbnRWKEZYX0lOVDMyIG5Gb3JtYXQvKiA9MCAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykNCi17DQotCW1fbkFsaWdubWVudCA9IG5Gb3JtYXQ7DQotCWlmIChiUGFpbnQpIFBhaW50KCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldFBhc3N3b3JkQ2hhcihGWF9XT1JEIHdTdWJXb3JkLyogPScqJyAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykNCi17DQotCW1fcFZULT5TZXRQYXNzd29yZENoYXIod1N1YldvcmQpOw0KLQlpZiAoYlBhaW50KSBQYWludCgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRMaW1pdENoYXIoRlhfSU5UMzIgbkxpbWl0Q2hhci8qID0wICovLCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQ0KLXsNCi0JbV9wVlQtPlNldExpbWl0Q2hhcihuTGltaXRDaGFyKTsNCi0JaWYgKGJQYWludCkgUGFpbnQoKTsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0Q2hhckFycmF5KEZYX0lOVDMyIG5DaGFyQXJyYXkvKiA9MCAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykNCi17DQotCW1fcFZULT5TZXRDaGFyQXJyYXkobkNoYXJBcnJheSk7DQotCWlmIChiUGFpbnQpIFBhaW50KCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlLyogPTAuMGYgKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BWVC0+U2V0Q2hhclNwYWNlKGZDaGFyU3BhY2UpOw0KLQlpZiAoYlBhaW50KSBQYWludCgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRIb3J6U2NhbGUoRlhfSU5UMzIgbkhvcnpTY2FsZS8qID0xMDAgKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BWVC0+U2V0SG9yelNjYWxlKG5Ib3J6U2NhbGUpOw0KLQlpZiAoYlBhaW50KSBQYWludCgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRNdWx0aUxpbmUoRlhfQk9PTCBiTXVsdGlMaW5lLyogPVRSVUUgKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BWVC0+U2V0TXVsdGlMaW5lKGJNdWx0aUxpbmUpOw0KLQlpZiAoYlBhaW50KSBQYWludCgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRBdXRvUmV0dXJuKEZYX0JPT0wgYkF1dG8vKiA9VFJVRSAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykNCi17DQotCW1fcFZULT5TZXRBdXRvUmV0dXJuKGJBdXRvKTsNCi0JaWYgKGJQYWludCkgUGFpbnQoKTsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0TGluZUxlYWRpbmcoRlhfRkxPQVQgZkxpbmVMZWFkaW5nLyogPVRSVUUgKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BWVC0+U2V0TGluZUxlYWRpbmcoZkxpbmVMZWFkaW5nKTsNCi0JaWYgKGJQYWludCkgUGFpbnQoKTsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0QXV0b0ZvbnRTaXplKEZYX0JPT0wgYkF1dG8vKiA9VFJVRSAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykNCi17DQotCW1fcFZULT5TZXRBdXRvRm9udFNpemUoYkF1dG8pOw0KLQlpZiAoYlBhaW50KSBQYWludCgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUsIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BWVC0+U2V0Rm9udFNpemUoZkZvbnRTaXplKTsNCi0JaWYgKGJQYWludCkgUGFpbnQoKTsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0QXV0b1Njcm9sbChGWF9CT09MIGJBdXRvLyogPVRSVUUgKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX2JFbmFibGVTY3JvbGwgPSBiQXV0bzsNCi0JaWYgKGJQYWludCkgUGFpbnQoKTsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0VGV4dE92ZXJmbG93KEZYX0JPT0wgYkFsbG93ZWQgLyo9IEZBTFNFKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX2JFbmFibGVPdmVyZmxvdyA9IGJBbGxvd2VkOw0KLQlpZiAoYlBhaW50KSBQYWludCgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRTZWwoRlhfSU5UMzIgblN0YXJ0Q2hhcixGWF9JTlQzMiBuRW5kQ2hhcikNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAoblN0YXJ0Q2hhciA9PSAwICYmIG5FbmRDaGFyIDwgMCkNCi0JCXsNCi0JCQlTZWxlY3RBbGwoKTsNCi0JCX0NCi0JCWVsc2UgaWYgKG5TdGFydENoYXIgPCAwKQ0KLQkJewkNCi0JCQl0aGlzLT5TZWxlY3ROb25lKCk7DQotCQl9DQotCQllbHNlDQotCQl7CQkNCi0JCQlpZiAoblN0YXJ0Q2hhciA8IG5FbmRDaGFyKQ0KLQkJCXsNCi0JCQkJU2V0U2VsKG1fcFZULT5Xb3JkSW5kZXhUb1dvcmRQbGFjZShuU3RhcnRDaGFyKSxtX3BWVC0+V29yZEluZGV4VG9Xb3JkUGxhY2UobkVuZENoYXIpKTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJU2V0U2VsKG1fcFZULT5Xb3JkSW5kZXhUb1dvcmRQbGFjZShuRW5kQ2hhciksbV9wVlQtPldvcmRJbmRleFRvV29yZFBsYWNlKG5TdGFydENoYXIpKTsNCi0JCQl9DQotCQl9CQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldFNlbChjb25zdCBDUFZUX1dvcmRQbGFjZSAmIGJlZ2luLGNvbnN0IENQVlRfV29yZFBsYWNlICYgZW5kKQ0KLXsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCXsNCi0JCVNlbGVjdE5vbmUoKTsNCi0NCi0JCW1fU2VsU3RhdGUuU2V0KGJlZ2luLGVuZCk7DQotDQotCQlTZXRDYXJldChtX1NlbFN0YXRlLkVuZFBvcyk7DQotDQotCQlpZiAobV9TZWxTdGF0ZS5Jc0V4aXN0KCkpDQotCQl7DQotCQkJU2Nyb2xsVG9DYXJldCgpOw0KLQkJCUNQVlRfV29yZFJhbmdlIHdyKG1fU2VsU3RhdGUuQmVnaW5Qb3MsbV9TZWxTdGF0ZS5FbmRQb3MpOw0KLQkJCVJlZnJlc2goUlBfT1BUSU9OQUwsJndyKTsNCi0JCQlTZXRDYXJldEluZm8oKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsJCQ0KLQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCQlTZXRDYXJldEluZm8oKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpHZXRTZWwoRlhfSU5UMzIgJiBuU3RhcnRDaGFyLCBGWF9JTlQzMiAmIG5FbmRDaGFyKSBjb25zdA0KLXsNCi0JblN0YXJ0Q2hhciA9IC0xOw0KLQluRW5kQ2hhciA9IC0xOw0KLQ0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSkNCi0Jew0KLQkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQ0KLQkJew0KLQkJCWlmIChtX1NlbFN0YXRlLkJlZ2luUG9zLldvcmRDbXAobV9TZWxTdGF0ZS5FbmRQb3MpPDApDQotCQkJew0KLQkJCQluU3RhcnRDaGFyID0gbV9wVlQtPldvcmRQbGFjZVRvV29yZEluZGV4KG1fU2VsU3RhdGUuQmVnaW5Qb3MpOw0KLQkJCQluRW5kQ2hhciA9IG1fcFZULT5Xb3JkUGxhY2VUb1dvcmRJbmRleChtX1NlbFN0YXRlLkVuZFBvcyk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCW5TdGFydENoYXIgPSBtX3BWVC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgobV9TZWxTdGF0ZS5FbmRQb3MpOw0KLQkJCQluRW5kQ2hhciA9IG1fcFZULT5Xb3JkUGxhY2VUb1dvcmRJbmRleChtX1NlbFN0YXRlLkJlZ2luUG9zKTsNCi0JCQl9DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJblN0YXJ0Q2hhciA9IG1fcFZULT5Xb3JkUGxhY2VUb1dvcmRJbmRleChtX3dwQ2FyZXQpOw0KLQkJCW5FbmRDaGFyID0gbV9wVlQtPldvcmRQbGFjZVRvV29yZEluZGV4KG1fd3BDYXJldCk7DQotCQl9DQotCX0NCi19DQotDQotRlhfSU5UMzIgQ0ZYX0VkaXQ6OkdldENhcmV0KCkgY29uc3QNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQkJcmV0dXJuIG1fcFZULT5Xb3JkUGxhY2VUb1dvcmRJbmRleChtX3dwQ2FyZXQpOw0KLQ0KLQlyZXR1cm4gLTE7DQotfQ0KLQ0KLUNQVlRfV29yZFBsYWNlIENGWF9FZGl0OjpHZXRDYXJldFdvcmRQbGFjZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV93cENhcmV0Ow0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDRlhfRWRpdDo6R2V0VGV4dCgpIGNvbnN0DQotew0KLQlDRlhfV2lkZVN0cmluZyBzd1JldDsNCi0NCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCXsNCi0JCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQ0KLQkJew0KLQkJCUZYX0JPT0wgYlJpY2ggPSBtX3BWVC0+SXNSaWNoVGV4dCgpOw0KLQ0KLQkJCXBJdGVyYXRvci0+U2V0QXQoMCk7DQotDQotCQkJQ1BWVF9Xb3JkIHdvcmRpbmZvOwkNCi0JCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsNCi0JCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQ0KLQkJCXsNCi0JCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotDQotCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZGluZm8pKQ0KLQkJCQl7DQotCQkJCQlpZiAoYlJpY2gpDQotCQkJCQl7DQotCQkJCQkJc3dSZXQgKz0gd29yZGluZm8uV29yZDsNCi0JCQkJCX0NCi0JCQkJCWVsc2UNCi0JCQkJCXsNCi0JCQkJCQlzd1JldCArPSB3b3JkaW5mby5Xb3JkOw0KLQkJCQkJfQkJCQkJDQotCQkJCX0NCi0NCi0JCQkJaWYgKG9sZHBsYWNlLlNlY0NtcChwbGFjZSkgIT0gMCkNCi0JCQkJew0KLQkJCQkJc3dSZXQgKz0gMHgwRDsNCi0JCQkJCXN3UmV0ICs9IDB4MEE7DQotCQkJCX0NCi0JCQkJDQotCQkJCW9sZHBsYWNlID0gcGxhY2U7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBzd1JldDsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ0ZYX0VkaXQ6OkdldFJhbmdlVGV4dChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKSBjb25zdA0KLXsNCi0JQ0ZYX1dpZGVTdHJpbmcgc3dSZXQ7DQotDQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlGWF9CT09MIGJSaWNoID0gbV9wVlQtPklzUmljaFRleHQoKTsNCi0NCi0JCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQ0KLQkJewkJCQ0KLQkJCUNQVlRfV29yZFJhbmdlIHdyVGVtcCA9IHJhbmdlOw0KLQkJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2Uod3JUZW1wLkJlZ2luUG9zKTsNCi0JCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdyVGVtcC5FbmRQb3MpOw0KLQkJCXBJdGVyYXRvci0+U2V0QXQod3JUZW1wLkJlZ2luUG9zKTsNCi0NCi0JCQlDUFZUX1dvcmQgd29yZGluZm87CQ0KLQkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlID0gd3JUZW1wLkJlZ2luUG9zOw0KLQkJCXdoaWxlIChwSXRlcmF0b3ItPk5leHRXb3JkKCkpDQotCQkJew0KLQkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsNCi0JCQkJaWYgKHBsYWNlLldvcmRDbXAod3JUZW1wLkVuZFBvcykgPiAwKWJyZWFrOw0KLQ0KLQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKSkNCi0JCQkJew0KLQkJCQkJaWYgKGJSaWNoKQ0KLQkJCQkJew0KLQkJCQkJCXN3UmV0ICs9IHdvcmRpbmZvLldvcmQ7DQotCQkJCQl9DQotCQkJCQllbHNlDQotCQkJCQl7DQotCQkJCQkJc3dSZXQgKz0gd29yZGluZm8uV29yZDsNCi0JCQkJCX0JCQkJCQ0KLQkJCQl9DQotDQotCQkJCWlmIChvbGRwbGFjZS5TZWNDbXAocGxhY2UpICE9IDApDQotCQkJCXsNCi0JCQkJCXN3UmV0ICs9IDB4MEQ7DQotCQkJCQlzd1JldCArPSAweDBBOw0KLQkJCQl9DQotCQkJCQ0KLQkJCQlvbGRwbGFjZSA9IHBsYWNlOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gc3dSZXQ7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENGWF9FZGl0OjpHZXRTZWxUZXh0KCkgY29uc3QNCi17DQotCXJldHVybiBHZXRSYW5nZVRleHQobV9TZWxTdGF0ZS5Db252ZXJ0VG9Xb3JkUmFuZ2UoKSk7DQotfQ0KLQ0KLUZYX0lOVDMyIENGWF9FZGl0OjpHZXRUb3RhbFdvcmRzKCkgY29uc3QNCi17DQotCXJldHVybiBtX3BWVC0+R2V0VG90YWxXb3JkcygpOw0KLX0NCi0NCi1GWF9JTlQzMiBDRlhfRWRpdDo6R2V0VG90YWxMaW5lcygpIGNvbnN0DQotew0KLQlGWF9JTlQzMiBuTGluZXMgPSAwOw0KLQ0KLQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsNCi0JCXdoaWxlIChwSXRlcmF0b3ItPk5leHRMaW5lKCkpDQotCQkJbkxpbmVzKys7DQotCX0NCi0NCi0JcmV0dXJuIG5MaW5lcysxOw0KLX0NCi0NCi1DUFZUX1dvcmRSYW5nZSBDRlhfRWRpdDo6R2V0U2VsZWN0V29yZFJhbmdlKCkgY29uc3QNCi17DQotCXJldHVybiBtX1NlbFN0YXRlLkNvbnZlcnRUb1dvcmRSYW5nZSgpOw0KLX0NCi0NCi1DUFZUX1dvcmRSYW5nZSBDRlhfRWRpdDo6Q29tYmluZVdvcmRSYW5nZShjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyMSwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3cjIpDQotew0KLQlDUFZUX1dvcmRSYW5nZSB3clJldDsNCi0NCi0JaWYgKHdyMS5CZWdpblBvcy5Xb3JkQ21wKHdyMi5CZWdpblBvcykgPCAwKQ0KLQl7DQotCQl3clJldC5CZWdpblBvcyA9IHdyMS5CZWdpblBvczsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXdyUmV0LkJlZ2luUG9zID0gd3IyLkJlZ2luUG9zOw0KLQl9DQotDQotCWlmICh3cjEuRW5kUG9zLldvcmRDbXAod3IyLkVuZFBvcykgPCAwKQ0KLQl7DQotCQl3clJldC5FbmRQb3MgPSB3cjIuRW5kUG9zOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJd3JSZXQuRW5kUG9zID0gd3IxLkVuZFBvczsNCi0JfQ0KLQ0KLQlyZXR1cm4gd3JSZXQ7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX0VkaXQ6OklzUmljaFRleHQoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcFZULT5Jc1JpY2hUZXh0KCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldFJpY2hUZXh0KEZYX0JPT0wgYlJpY2hUZXh0LyogPVRSVUUgKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BWVC0+U2V0UmljaFRleHQoYlJpY2hUZXh0KTsNCi0JaWYgKGJQYWludCkgUGFpbnQoKTsNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaEZvbnRJbmRleChGWF9JTlQzMiBuRm9udEluZGV4KQ0KLXsNCi0JQ1BWVF9Xb3JkUHJvcHMgV29yZFByb3BzOw0KLQlXb3JkUHJvcHMubkZvbnRJbmRleCA9IG5Gb250SW5kZXg7DQotCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX0ZPTlRJTkRFWCxOVUxMLCZXb3JkUHJvcHMpOwkNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSkNCi17CQ0KLQlDUFZUX1dvcmRQcm9wcyBXb3JkUHJvcHM7DQotCVdvcmRQcm9wcy5mRm9udFNpemUgPSBmRm9udFNpemU7DQotCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX0ZPTlRTSVpFLE5VTEwsJldvcmRQcm9wcyk7CQ0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dENvbG9yKEZYX0NPTE9SUkVGIGR3Q29sb3IpDQotew0KLQlDUFZUX1dvcmRQcm9wcyBXb3JkUHJvcHM7DQotCVdvcmRQcm9wcy5kd1dvcmRDb2xvciA9IGR3Q29sb3I7DQotCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX1dPUkRDT0xPUixOVUxMLCZXb3JkUHJvcHMpOwkNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaFRleHRTY3JpcHQoRlhfSU5UMzIgblNjcmlwdFR5cGUpDQotew0KLQlDUFZUX1dvcmRQcm9wcyBXb3JkUHJvcHM7DQotCVdvcmRQcm9wcy5uU2NyaXB0VHlwZSA9IG5TY3JpcHRUeXBlOw0KLQlyZXR1cm4gU2V0UmljaFRleHRQcm9wcyhFUF9TQ1JJUFRUWVBFLE5VTEwsJldvcmRQcm9wcyk7CQ0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dEJvbGQoRlhfQk9PTCBiQm9sZCkNCi17DQotCUNQVlRfV29yZFByb3BzIFdvcmRQcm9wczsNCi0JaWYgKGJCb2xkKQ0KLQkJV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9CT0xEOw0KLQlyZXR1cm4gU2V0UmljaFRleHRQcm9wcyhFUF9CT0xELE5VTEwsJldvcmRQcm9wcyk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFJpY2hUZXh0SXRhbGljKEZYX0JPT0wgYkl0YWxpYykNCi17DQotCUNQVlRfV29yZFByb3BzIFdvcmRQcm9wczsNCi0JaWYgKGJJdGFsaWMpDQotCQlXb3JkUHJvcHMubldvcmRTdHlsZSB8PSBQVlRXT1JEX1NUWUxFX0lUQUxJQzsNCi0JcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfSVRBTElDLE5VTEwsJldvcmRQcm9wcyk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFJpY2hUZXh0VW5kZXJsaW5lKEZYX0JPT0wgYlVuZGVybGluZSkNCi17DQotCUNQVlRfV29yZFByb3BzIFdvcmRQcm9wczsNCi0JaWYgKGJVbmRlcmxpbmUpDQotCQlXb3JkUHJvcHMubldvcmRTdHlsZSB8PSBQVlRXT1JEX1NUWUxFX1VOREVSTElORTsNCi0JcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfVU5ERVJMSU5FLE5VTEwsJldvcmRQcm9wcyk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFJpY2hUZXh0Q3Jvc3NvdXQoRlhfQk9PTCBiQ3Jvc3NvdXQpDQotew0KLQlDUFZUX1dvcmRQcm9wcyBXb3JkUHJvcHM7DQotCWlmIChiQ3Jvc3NvdXQpDQotCQlXb3JkUHJvcHMubldvcmRTdHlsZSB8PSBQVlRXT1JEX1NUWUxFX0NST1NTT1VUOw0KLQlyZXR1cm4gU2V0UmljaFRleHRQcm9wcyhFUF9DUk9TU09VVCxOVUxMLCZXb3JkUHJvcHMpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlKQ0KLXsNCi0JQ1BWVF9Xb3JkUHJvcHMgV29yZFByb3BzOw0KLQlXb3JkUHJvcHMuZkNoYXJTcGFjZSA9IGZDaGFyU3BhY2U7DQotCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX0NIQVJTUEFDRSxOVUxMLCZXb3JkUHJvcHMpOwkNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaFRleHRIb3J6U2NhbGUoRlhfSU5UMzIgbkhvcnpTY2FsZSAvKj0gMTAwKi8pDQotew0KLQlDUFZUX1dvcmRQcm9wcyBXb3JkUHJvcHM7DQotCVdvcmRQcm9wcy5uSG9yelNjYWxlID0gbkhvcnpTY2FsZTsNCi0JcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfSE9SWlNDQUxFLE5VTEwsJldvcmRQcm9wcyk7CQ0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dExpbmVMZWFkaW5nKEZYX0ZMT0FUIGZMaW5lTGVhZGluZykNCi17DQotCUNQVlRfU2VjUHJvcHMgU2VjUHJvcHM7DQotCVNlY1Byb3BzLmZMaW5lTGVhZGluZyA9IGZMaW5lTGVhZGluZzsNCi0JcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfTElORUxFQURJTkcsJlNlY1Byb3BzLE5VTEwpOwkNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaFRleHRMaW5lSW5kZW50KEZYX0ZMT0FUIGZMaW5lSW5kZW50KQ0KLXsNCi0JQ1BWVF9TZWNQcm9wcyBTZWNQcm9wczsNCi0JU2VjUHJvcHMuZkxpbmVJbmRlbnQgPSBmTGluZUluZGVudDsNCi0JcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfTElORUlOREVOVCwmU2VjUHJvcHMsTlVMTCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX0VkaXQ6OlNldFJpY2hUZXh0QWxpZ25tZW50KEZYX0lOVDMyIG5BbGlnbm1lbnQpDQotew0KLQlDUFZUX1NlY1Byb3BzIFNlY1Byb3BzOw0KLQlTZWNQcm9wcy5uQWxpZ25tZW50ID0gbkFsaWdubWVudDsNCi0JcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfQUxJR05NRU5ULCZTZWNQcm9wcyxOVUxMKTsNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaFRleHRQcm9wcyhFRElUX1BST1BTX0UgZVByb3BzLCBjb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpDQotew0KLQlGWF9CT09MIGJTZXQgPSBGQUxTRTsNCi0JRlhfQk9PTCBiU2V0MSxiU2V0MjsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkgJiYgbV9wVlQtPklzUmljaFRleHQoKSkNCi0Jew0KLQkJaWYgKElQREZfVmFyaWFibGVUZXh0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wVlQtPkdldEl0ZXJhdG9yKCkpDQotCQl7DQotCQkJQ1BWVF9Xb3JkUmFuZ2Ugd3JUZW1wID0gbV9TZWxTdGF0ZS5Db252ZXJ0VG9Xb3JkUmFuZ2UoKTsNCi0JCQkNCi0JCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdyVGVtcC5CZWdpblBvcyk7DQotCQkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZSh3clRlbXAuRW5kUG9zKTsNCi0JCQlwSXRlcmF0b3ItPlNldEF0KHdyVGVtcC5CZWdpblBvcyk7DQotDQotCQkJQmVnaW5Hcm91cFVuZG8oTCIiKTs7DQotDQotCQkJYlNldCA9IFNldFNlY1Byb3BzKGVQcm9wcyx3clRlbXAuQmVnaW5Qb3MscFNlY1Byb3BzLHBXb3JkUHJvcHMsd3JUZW1wLFRSVUUpOw0KLQ0KLQkJCXdoaWxlIChwSXRlcmF0b3ItPk5leHRXb3JkKCkpDQotCQkJew0KLQkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsNCi0JCQkJaWYgKHBsYWNlLldvcmRDbXAod3JUZW1wLkVuZFBvcykgPiAwKSBicmVhazsNCi0JCQkJYlNldDEgPSBTZXRTZWNQcm9wcyhlUHJvcHMscGxhY2UscFNlY1Byb3BzLHBXb3JkUHJvcHMsd3JUZW1wLFRSVUUpOw0KLQkJCQliU2V0MiA9IFNldFdvcmRQcm9wcyhlUHJvcHMscGxhY2UscFdvcmRQcm9wcyx3clRlbXAsVFJVRSk7DQotCQkJCQ0KLQkJCQlpZiAoIWJTZXQpDQotCQkJCQliU2V0ID0gKGJTZXQxIHx8IGJTZXQyKTsNCi0JCQl9DQotDQotCQkJRW5kR3JvdXBVbmRvKCk7DQotDQotCQkJaWYgKGJTZXQpDQotCQkJew0KLQkJCQlQYWludFNldFByb3BzKGVQcm9wcyx3clRlbXApOw0KLQkJCX0NCi0JCX0NCi0JfQkNCi0NCi0JcmV0dXJuIGJTZXQ7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlBhaW50U2V0UHJvcHMoRURJVF9QUk9QU19FIGVQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3cikNCi17DQotCXN3aXRjaChlUHJvcHMpDQotCXsNCi0JY2FzZSBFUF9MSU5FTEVBRElORzoNCi0JY2FzZSBFUF9MSU5FSU5ERU5UOg0KLQljYXNlIEVQX0FMSUdOTUVOVDoNCi0JCVJlYXJyYW5nZVBhcnQod3IpOw0KLQkJU2Nyb2xsVG9DYXJldCgpOw0KLQkJUmVmcmVzaChSUF9BTkFMWVNFKTsNCi0JCVNldENhcmV0T3JpZ2luKCk7DQotCQlTZXRDYXJldEluZm8oKTsJDQotCQlicmVhazsJCQkJCQ0KLQljYXNlIEVQX1dPUkRDT0xPUjoNCi0JY2FzZSBFUF9VTkRFUkxJTkU6DQotCWNhc2UgRVBfQ1JPU1NPVVQ6DQotCQlSZWZyZXNoKFJQX09QVElPTkFMLCZ3cik7DQotCQlicmVhazsNCi0JY2FzZSBFUF9GT05USU5ERVg6DQotCWNhc2UgRVBfRk9OVFNJWkU6DQotCWNhc2UgRVBfU0NSSVBUVFlQRToJCQkJCQ0KLQljYXNlIEVQX0NIQVJTUEFDRToNCi0JY2FzZSBFUF9IT1JaU0NBTEU6DQotCWNhc2UgRVBfQk9MRDoNCi0JY2FzZSBFUF9JVEFMSUM6DQotCQlSZWFycmFuZ2VQYXJ0KHdyKTsNCi0JCVNjcm9sbFRvQ2FyZXQoKTsNCi0NCi0JCUNQVlRfV29yZFJhbmdlIHdyUmVmcmVzaChtX3BWVC0+R2V0U2VjdGlvbkJlZ2luUGxhY2Uod3IuQmVnaW5Qb3MpLA0KLQkJCW1fcFZULT5HZXRTZWN0aW9uRW5kUGxhY2Uod3IuRW5kUG9zKSk7DQotCQlSZWZyZXNoKFJQX0FOQUxZU0UsJndyUmVmcmVzaCk7DQotDQotCQlTZXRDYXJldE9yaWdpbigpOw0KLQkJU2V0Q2FyZXRJbmZvKCk7CQ0KLQkJYnJlYWs7DQotCX0JCQkJDQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFNlY1Byb3BzKEVESVRfUFJPUFNfRSBlUHJvcHMsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UsIA0KLQkJCQkJCQkgICBjb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsIA0KLQkJCQkJCQkgICBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyLCBGWF9CT09MIGJBZGRVbmRvKQ0KLXsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkgJiYgbV9wVlQtPklzUmljaFRleHQoKSkNCi0Jew0KLQkJaWYgKElQREZfVmFyaWFibGVUZXh0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wVlQtPkdldEl0ZXJhdG9yKCkpDQotCQl7DQotCQkJRlhfQk9PTCBiU2V0ID0gRkFMU0U7DQotCQkJQ1BWVF9TZWN0aW9uIHNlY2luZm87DQotCQkJQ1BWVF9TZWN0aW9uIE9sZFNlY2luZm87DQotDQotCQkJQ1BWVF9Xb3JkUGxhY2Ugb2xkcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotDQotCQkJaWYgKGVQcm9wcyA9PSBFUF9MSU5FTEVBRElORyB8fCBlUHJvcHMgPT0gRVBfTElORUlOREVOVCB8fCBlUHJvcHMgPT0gRVBfQUxJR05NRU5UKQ0KLQkJCXsNCi0JCQkJaWYgKHBTZWNQcm9wcykNCi0JCQkJew0KLQkJCQkJcEl0ZXJhdG9yLT5TZXRBdChwbGFjZSk7DQotCQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRTZWN0aW9uKHNlY2luZm8pKQ0KLQkJCQkJew0KLQkJCQkJCWlmIChiQWRkVW5kbykgT2xkU2VjaW5mbyA9IHNlY2luZm87DQotDQotCQkJCQkJc3dpdGNoKGVQcm9wcykNCi0JCQkJCQl7DQotCQkJCQkJY2FzZSBFUF9MSU5FTEVBRElORzoJCQkJDQotCQkJCQkJCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwoc2VjaW5mby5TZWNQcm9wcy5mTGluZUxlYWRpbmcscFNlY1Byb3BzLT5mTGluZUxlYWRpbmcpKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlzZWNpbmZvLlNlY1Byb3BzLmZMaW5lTGVhZGluZyA9IHBTZWNQcm9wcy0+ZkxpbmVMZWFkaW5nOwkJCQkJCQkNCi0JCQkJCQkJCWJTZXQgPSBUUlVFOw0KLQkJCQkJCQl9DQotCQkJCQkJCWJyZWFrOw0KLQkJCQkJCWNhc2UgRVBfTElORUlOREVOVDoNCi0JCQkJCQkJaWYgKCFGWF9FRElUX0lzRmxvYXRFcXVhbChzZWNpbmZvLlNlY1Byb3BzLmZMaW5lSW5kZW50LHBTZWNQcm9wcy0+ZkxpbmVJbmRlbnQpKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlzZWNpbmZvLlNlY1Byb3BzLmZMaW5lSW5kZW50ID0gcFNlY1Byb3BzLT5mTGluZUluZGVudDsNCi0JCQkJCQkJCWJTZXQgPSBUUlVFOw0KLQkJCQkJCQl9DQotCQkJCQkJCWJyZWFrOw0KLQkJCQkJCWNhc2UgRVBfQUxJR05NRU5UOg0KLQkJCQkJCQlpZiAoc2VjaW5mby5TZWNQcm9wcy5uQWxpZ25tZW50ICE9IHBTZWNQcm9wcy0+bkFsaWdubWVudCkNCi0JCQkJCQkJew0KLQkJCQkJCQkJc2VjaW5mby5TZWNQcm9wcy5uQWxpZ25tZW50ID0gcFNlY1Byb3BzLT5uQWxpZ25tZW50Ow0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJZGVmYXVsdDoNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCWlmIChwV29yZFByb3BzICYmIHBsYWNlID09IG1fcFZULT5HZXRTZWN0aW9uQmVnaW5QbGFjZShwbGFjZSkpDQotCQkJCXsNCi0JCQkJCXBJdGVyYXRvci0+U2V0QXQocGxhY2UpOw0KLQkJCQkJaWYgKHBJdGVyYXRvci0+R2V0U2VjdGlvbihzZWNpbmZvKSkNCi0JCQkJCXsNCi0JCQkJCQlpZiAoYkFkZFVuZG8pIE9sZFNlY2luZm8gPSBzZWNpbmZvOw0KLQ0KLQkJCQkJCXN3aXRjaChlUHJvcHMpDQotCQkJCQkJew0KLQkJCQkJCWNhc2UgRVBfRk9OVElOREVYOgkJCQkNCi0JCQkJCQkJaWYgKHNlY2luZm8uV29yZFByb3BzLm5Gb250SW5kZXggIT0gcFdvcmRQcm9wcy0+bkZvbnRJbmRleCkNCi0JCQkJCQkJew0KLQkJCQkJCQkJc2VjaW5mby5Xb3JkUHJvcHMubkZvbnRJbmRleCA9IHBXb3JkUHJvcHMtPm5Gb250SW5kZXg7DQotCQkJCQkJCQliU2V0ID0gVFJVRTsNCi0JCQkJCQkJfQ0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlIEVQX0ZPTlRTSVpFOg0KLQkJCQkJCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKHNlY2luZm8uV29yZFByb3BzLmZGb250U2l6ZSxwV29yZFByb3BzLT5mRm9udFNpemUpKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlzZWNpbmZvLldvcmRQcm9wcy5mRm9udFNpemUgPSBwV29yZFByb3BzLT5mRm9udFNpemU7DQotCQkJCQkJCQliU2V0ID0gVFJVRTsNCi0JCQkJCQkJfQ0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlIEVQX1dPUkRDT0xPUjoNCi0JCQkJCQkJaWYgKHNlY2luZm8uV29yZFByb3BzLmR3V29yZENvbG9yICE9IHBXb3JkUHJvcHMtPmR3V29yZENvbG9yKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlzZWNpbmZvLldvcmRQcm9wcy5kd1dvcmRDb2xvciA9IHBXb3JkUHJvcHMtPmR3V29yZENvbG9yOw0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSBFUF9TQ1JJUFRUWVBFOgkJCQkNCi0JCQkJCQkJaWYgKHNlY2luZm8uV29yZFByb3BzLm5TY3JpcHRUeXBlICE9IHBXb3JkUHJvcHMtPm5TY3JpcHRUeXBlKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlzZWNpbmZvLldvcmRQcm9wcy5uU2NyaXB0VHlwZSA9IHBXb3JkUHJvcHMtPm5TY3JpcHRUeXBlOw0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSBFUF9DSEFSU1BBQ0U6CQkJDQotCQkJCQkJCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwoc2VjaW5mby5Xb3JkUHJvcHMuZkNoYXJTcGFjZSxwV29yZFByb3BzLT5mQ2hhclNwYWNlKSkNCi0JCQkJCQkJew0KLQkJCQkJCQkJc2VjaW5mby5Xb3JkUHJvcHMuZkNoYXJTcGFjZSA9IHBXb3JkUHJvcHMtPmZDaGFyU3BhY2U7DQotCQkJCQkJCQliU2V0ID0gVFJVRTsNCi0JCQkJCQkJfQ0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlIEVQX0hPUlpTQ0FMRToJCQkJDQotCQkJCQkJCWlmIChzZWNpbmZvLldvcmRQcm9wcy5uSG9yelNjYWxlICE9IHBXb3JkUHJvcHMtPm5Ib3J6U2NhbGUpDQotCQkJCQkJCXsNCi0JCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Ib3J6U2NhbGUgPSBwV29yZFByb3BzLT5uSG9yelNjYWxlOw0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSBFUF9VTkRFUkxJTkU6DQotCQkJCQkJCWlmIChwV29yZFByb3BzLT5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpDQotCQkJCQkJCXsNCi0JCQkJCQkJCWlmICgoc2VjaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfVU5ERVJMSU5FKSA9PSAwKQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9VTkRFUkxJTkU7IA0KLQkJCQkJCQkJCWJTZXQgPSBUUlVFOw0KLQkJCQkJCQkJfQ0KLQkJCQkJCQl9DQotCQkJCQkJCWVsc2UNCi0JCQkJCQkJew0KLQkJCQkJCQkJaWYgKChzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpICE9IDApDQotCQkJCQkJCQl7DQotCQkJCQkJCQkJc2VjaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmPSB+UFZUV09SRF9TVFlMRV9VTkRFUkxJTkU7DQotCQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCQl9DQotCQkJCQkJCX0NCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSBFUF9DUk9TU09VVDoNCi0JCQkJCQkJaWYgKHBXb3JkUHJvcHMtPm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0NST1NTT1VUKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlpZiAoKHNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0NST1NTT1VUKSA9PSAwKQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9DUk9TU09VVDsgDQotCQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCQl9DQotCQkJCQkJCX0NCi0JCQkJCQkJZWxzZQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlpZiAoKHNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0NST1NTT1VUKSAhPSAwKQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJj0gflBWVFdPUkRfU1RZTEVfQ1JPU1NPVVQ7DQotCQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCQl9DQotCQkJCQkJCX0NCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSBFUF9CT0xEOg0KLQkJCQkJCQlpZiAocFdvcmRQcm9wcy0+bldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQk9MRCkNCi0JCQkJCQkJew0KLQkJCQkJCQkJaWYgKChzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9CT0xEKSA9PSAwKQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9CT0xEOyANCi0JCQkJCQkJCQliU2V0ID0gVFJVRTsNCi0JCQkJCQkJCX0NCi0JCQkJCQkJfQ0KLQkJCQkJCQllbHNlDQotCQkJCQkJCXsNCi0JCQkJCQkJCWlmICgoc2VjaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQk9MRCkgIT0gMCkNCi0JCQkJCQkJCXsNCi0JCQkJCQkJCQlzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICY9IH5QVlRXT1JEX1NUWUxFX0JPTEQ7DQotCQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCQl9DQotCQkJCQkJCX0NCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSBFUF9JVEFMSUM6DQotCQkJCQkJCWlmIChwV29yZFByb3BzLT5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9JVEFMSUMpDQotCQkJCQkJCXsNCi0JCQkJCQkJCWlmICgoc2VjaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfSVRBTElDKSA9PSAwKQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9JVEFMSUM7IA0KLQkJCQkJCQkJCWJTZXQgPSBUUlVFOw0KLQkJCQkJCQkJfQ0KLQkJCQkJCQl9DQotCQkJCQkJCWVsc2UNCi0JCQkJCQkJew0KLQkJCQkJCQkJaWYgKChzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9JVEFMSUMpICE9IDApDQotCQkJCQkJCQl7DQotCQkJCQkJCQkJc2VjaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmPSB+UFZUV09SRF9TVFlMRV9JVEFMSUM7DQotCQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCQl9DQotCQkJCQkJCX0NCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJZGVmYXVsdDoNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQ0KLQkJCWlmIChiU2V0KQ0KLQkJCXsNCi0JCQkJcEl0ZXJhdG9yLT5TZXRTZWN0aW9uKHNlY2luZm8pOw0KLQ0KLQkJCQlpZiAoYkFkZFVuZG8gJiYgbV9iRW5hYmxlVW5kbykNCi0JCQkJew0KLQkJCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9TZXRTZWNQcm9wcw0KLQkJCQkJCSh0aGlzLHBsYWNlLGVQcm9wcyxPbGRTZWNpbmZvLlNlY1Byb3BzLE9sZFNlY2luZm8uV29yZFByb3BzLHNlY2luZm8uU2VjUHJvcHMsc2VjaW5mby5Xb3JkUHJvcHMsd3IpKTsNCi0JCQkJfQ0KLQkJCX0NCi0NCi0JCQlwSXRlcmF0b3ItPlNldEF0KG9sZHBsYWNlKTsNCi0NCi0JCQlyZXR1cm4gYlNldDsNCi0JCX0NCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpTZXRXb3JkUHJvcHMoRURJVF9QUk9QU19FIGVQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSwgDQotCQkJCQkJCQljb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsIGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IsIEZYX0JPT0wgYkFkZFVuZG8pDQotew0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSAmJiBtX3BWVC0+SXNSaWNoVGV4dCgpKQ0KLQl7DQotCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkNCi0JCXsNCi0JCQlGWF9CT09MIGJTZXQgPSBGQUxTRTsNCi0JCQlDUFZUX1dvcmQgd29yZGluZm87DQotCQkJQ1BWVF9Xb3JkIE9sZFdvcmRpbmZvOw0KLQ0KLQkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOw0KLQ0KLQkJCWlmIChwV29yZFByb3BzKQ0KLQkJCXsNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdChwbGFjZSk7DQotCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZGluZm8pKQ0KLQkJCQl7DQotCQkJCQlpZiAoYkFkZFVuZG8pIE9sZFdvcmRpbmZvID0gd29yZGluZm87DQotDQotCQkJCQlzd2l0Y2goZVByb3BzKQ0KLQkJCQkJew0KLQkJCQkJY2FzZSBFUF9GT05USU5ERVg6CQkJCQ0KLQkJCQkJCWlmICh3b3JkaW5mby5Xb3JkUHJvcHMubkZvbnRJbmRleCAhPSBwV29yZFByb3BzLT5uRm9udEluZGV4KQ0KLQkJCQkJCXsNCi0JCQkJCQkJaWYgKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwID0gdGhpcy0+R2V0Rm9udE1hcCgpKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMubkZvbnRJbmRleCA9IHBGb250TWFwLT5HZXRXb3JkRm9udEluZGV4KHdvcmRpbmZvLldvcmQsd29yZGluZm8ubkNoYXJzZXQscFdvcmRQcm9wcy0+bkZvbnRJbmRleCk7DQotCQkJCQkJCX0NCi0JCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJfQ0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJY2FzZSBFUF9GT05UU0laRToNCi0JCQkJCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKHdvcmRpbmZvLldvcmRQcm9wcy5mRm9udFNpemUscFdvcmRQcm9wcy0+ZkZvbnRTaXplKSkNCi0JCQkJCQl7DQotCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5mRm9udFNpemUgPSBwV29yZFByb3BzLT5mRm9udFNpemU7DQotCQkJCQkJCWJTZXQgPSBUUlVFOw0KLQkJCQkJCX0NCi0JCQkJCQlicmVhazsNCi0JCQkJCWNhc2UgRVBfV09SRENPTE9SOg0KLQkJCQkJCWlmICh3b3JkaW5mby5Xb3JkUHJvcHMuZHdXb3JkQ29sb3IgIT0gcFdvcmRQcm9wcy0+ZHdXb3JkQ29sb3IpDQotCQkJCQkJew0KLQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMuZHdXb3JkQ29sb3IgPSBwV29yZFByb3BzLT5kd1dvcmRDb2xvcjsNCi0JCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJfQ0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJY2FzZSBFUF9TQ1JJUFRUWVBFOg0KLQkJCQkJCWlmICh3b3JkaW5mby5Xb3JkUHJvcHMublNjcmlwdFR5cGUgIT0gcFdvcmRQcm9wcy0+blNjcmlwdFR5cGUpDQotCQkJCQkJew0KLQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMublNjcmlwdFR5cGUgPSBwV29yZFByb3BzLT5uU2NyaXB0VHlwZTsNCi0JCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJfQ0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJY2FzZSBFUF9DSEFSU1BBQ0U6DQotCQkJCQkJaWYgKCFGWF9FRElUX0lzRmxvYXRFcXVhbCh3b3JkaW5mby5Xb3JkUHJvcHMuZkNoYXJTcGFjZSxwV29yZFByb3BzLT5mQ2hhclNwYWNlKSkNCi0JCQkJCQl7DQotCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5mQ2hhclNwYWNlID0gcFdvcmRQcm9wcy0+ZkNoYXJTcGFjZTsNCi0JCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJfQ0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJY2FzZSBFUF9IT1JaU0NBTEU6DQotCQkJCQkJaWYgKHdvcmRpbmZvLldvcmRQcm9wcy5uSG9yelNjYWxlICE9IHBXb3JkUHJvcHMtPm5Ib3J6U2NhbGUpDQotCQkJCQkJew0KLQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMubkhvcnpTY2FsZSA9IHBXb3JkUHJvcHMtPm5Ib3J6U2NhbGU7DQotCQkJCQkJCWJTZXQgPSBUUlVFOw0KLQkJCQkJCX0NCi0JCQkJCQlicmVhazsNCi0JCQkJCWNhc2UgRVBfVU5ERVJMSU5FOg0KLQkJCQkJCWlmIChwV29yZFByb3BzLT5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpDQotCQkJCQkJew0KLQkJCQkJCQlpZiAoKHdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpID09IDApDQotCQkJCQkJCXsNCi0JCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlIHw9IFBWVFdPUkRfU1RZTEVfVU5ERVJMSU5FOw0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQl9DQotCQkJCQkJZWxzZQ0KLQkJCQkJCXsNCi0JCQkJCQkJaWYgKCh3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfVU5ERVJMSU5FKSAhPSAwKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmPSB+UFZUV09SRF9TVFlMRV9VTkRFUkxJTkU7DQotCQkJCQkJCQliU2V0ID0gVFJVRTsNCi0JCQkJCQkJfQ0KLQkJCQkJCX0NCi0JCQkJCQlicmVhazsNCi0JCQkJCWNhc2UgRVBfQ1JPU1NPVVQ6DQotCQkJCQkJaWYgKHBXb3JkUHJvcHMtPm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0NST1NTT1VUKQ0KLQkJCQkJCXsNCi0JCQkJCQkJaWYgKCh3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQ1JPU1NPVVQpID09IDApDQotCQkJCQkJCXsNCi0JCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlIHw9IFBWVFdPUkRfU1RZTEVfQ1JPU1NPVVQ7IA0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQl9DQotCQkJCQkJZWxzZQ0KLQkJCQkJCXsNCi0JCQkJCQkJaWYgKCh3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQ1JPU1NPVVQpICE9IDApDQotCQkJCQkJCXsNCi0JCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICY9IH5QVlRXT1JEX1NUWUxFX0NST1NTT1VUOw0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQl9DQotCQkJCQkJYnJlYWs7DQotCQkJCQljYXNlIEVQX0JPTEQ6DQotCQkJCQkJaWYgKHBXb3JkUHJvcHMtPm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0JPTEQpDQotCQkJCQkJew0KLQkJCQkJCQlpZiAoKHdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9CT0xEKSA9PSAwKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSB8PSBQVlRXT1JEX1NUWUxFX0JPTEQ7IA0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQl9DQotCQkJCQkJZWxzZQ0KLQkJCQkJCXsNCi0JCQkJCQkJaWYgKCh3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQk9MRCkgIT0gMCkNCi0JCQkJCQkJew0KLQkJCQkJCQkJd29yZGluZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJj0gflBWVFdPUkRfU1RZTEVfQk9MRDsNCi0JCQkJCQkJCWJTZXQgPSBUUlVFOw0KLQkJCQkJCQl9DQotCQkJCQkJfQ0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJY2FzZSBFUF9JVEFMSUM6DQotCQkJCQkJaWYgKHBXb3JkUHJvcHMtPm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0lUQUxJQykNCi0JCQkJCQl7DQotCQkJCQkJCWlmICgod29yZGluZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0lUQUxJQykgPT0gMCkNCi0JCQkJCQkJew0KLQkJCQkJCQkJd29yZGluZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9JVEFMSUM7IA0KLQkJCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJCX0NCi0JCQkJCQl9DQotCQkJCQkJZWxzZQ0KLQkJCQkJCXsNCi0JCQkJCQkJaWYgKCh3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfSVRBTElDKSAhPSAwKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmPSB+UFZUV09SRF9TVFlMRV9JVEFMSUM7DQotCQkJCQkJCQliU2V0ID0gVFJVRTsNCi0JCQkJCQkJfQ0KLQkJCQkJCX0NCi0JCQkJCQlicmVhazsNCi0JCQkJCWRlZmF1bHQ6DQotCQkJCQkJYnJlYWs7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9CQ0KLQ0KLQkJCWlmIChiU2V0KQ0KLQkJCXsNCi0JCQkJcEl0ZXJhdG9yLT5TZXRXb3JkKHdvcmRpbmZvKTsNCi0NCi0JCQkJaWYgKGJBZGRVbmRvICYmIG1fYkVuYWJsZVVuZG8pDQotCQkJCXsNCi0JCQkJCUFkZEVkaXRVbmRvSXRlbShuZXcgQ0ZYRVVfU2V0V29yZFByb3BzDQotCQkJCQkJKHRoaXMscGxhY2UsZVByb3BzLE9sZFdvcmRpbmZvLldvcmRQcm9wcyx3b3JkaW5mby5Xb3JkUHJvcHMsd3IpKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCQkNCi0JCQlwSXRlcmF0b3ItPlNldEF0KG9sZHBsYWNlKTsNCi0JCQlyZXR1cm4gYlNldDsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldFRleHQoRlhfTFBDV1NUUiB0ZXh0LEZYX0lOVDMyIGNoYXJzZXQgLyo9IERFRkFVTFRfQ0hBUlNFVCovLA0KLQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMgLyo9IE5VTEwqLyxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMgLyo9IE5VTEwqLykNCi17DQotCVNldFRleHQodGV4dCxjaGFyc2V0LHBTZWNQcm9wcyxwV29yZFByb3BzLFRSVUUsVFJVRSk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0VkaXQ6Okluc2VydFdvcmQoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0IC8qPSBERUZBVUxUX0NIQVJTRVQqLywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzIC8qPSBOVUxMKi8pDQotew0KLQlyZXR1cm4gSW5zZXJ0V29yZCh3b3JkLGNoYXJzZXQscFdvcmRQcm9wcyxUUlVFLFRSVUUpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpJbnNlcnRSZXR1cm4oY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyAvKj0gTlVMTCovLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyAvKj0gTlVMTCovKQ0KLXsNCi0JcmV0dXJuIEluc2VydFJldHVybihwU2VjUHJvcHMscFdvcmRQcm9wcyxUUlVFLFRSVUUpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpCYWNrc3BhY2UoKQ0KLXsNCi0JcmV0dXJuIEJhY2tzcGFjZShUUlVFLFRSVUUpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpEZWxldGUoKQ0KLXsNCi0JcmV0dXJuIERlbGV0ZShUUlVFLFRSVUUpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpDbGVhcigpDQotew0KLQlyZXR1cm4gQ2xlYXIoVFJVRSxUUlVFKTsNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6SW5zZXJ0VGV4dChGWF9MUENXU1RSIHRleHQsIEZYX0lOVDMyIGNoYXJzZXQgLyo9IERFRkFVTFRfQ0hBUlNFVCovLA0KLQkJCQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyAvKj0gTlVMTCovLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyAvKj0gTlVMTCovKQ0KLXsNCi0JcmV0dXJuIEluc2VydFRleHQodGV4dCxjaGFyc2V0LHBTZWNQcm9wcyxwV29yZFByb3BzLFRSVUUsVFJVRSk7DQotfQ0KLQ0KLUZYX0ZMT0FUIENGWF9FZGl0OjpHZXRGb250U2l6ZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wVlQtPkdldEZvbnRTaXplKCk7DQotfQ0KLQ0KLUZYX1dPUkQgQ0ZYX0VkaXQ6OkdldFBhc3N3b3JkQ2hhcigpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wVlQtPkdldFBhc3N3b3JkQ2hhcigpOw0KLX0NCi0NCi1GWF9JTlQzMiBDRlhfRWRpdDo6R2V0Q2hhckFycmF5KCkgY29uc3QNCi17DQotCXJldHVybiBtX3BWVC0+R2V0Q2hhckFycmF5KCk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDRlhfRWRpdDo6R2V0UGxhdGVSZWN0KCkgY29uc3QNCi17DQotCXJldHVybiBtX3BWVC0+R2V0UGxhdGVSZWN0KCk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDRlhfRWRpdDo6R2V0Q29udGVudFJlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIFZUVG9FZGl0KG1fcFZULT5HZXRDb250ZW50UmVjdCgpKTsNCi19DQotDQotRlhfSU5UMzIgQ0ZYX0VkaXQ6OkdldEhvcnpTY2FsZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wVlQtPkdldEhvcnpTY2FsZSgpOw0KLX0NCi0NCi1GWF9GTE9BVCBDRlhfRWRpdDo6R2V0Q2hhclNwYWNlKCkgY29uc3QNCi17DQotCXJldHVybiBtX3BWVC0+R2V0Q2hhclNwYWNlKCk7DQotfQ0KLQ0KLS8vIGlubmVyIG1ldGhvZHMNCi0NCi1DUFZUX1dvcmRSYW5nZSBDRlhfRWRpdDo6R2V0V2hvbGVXb3JkUmFuZ2UoKSBjb25zdA0KLXsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCQlyZXR1cm4gQ1BWVF9Xb3JkUmFuZ2UobV9wVlQtPkdldEJlZ2luV29yZFBsYWNlKCksbV9wVlQtPkdldEVuZFdvcmRQbGFjZSgpKTsNCi0NCi0JcmV0dXJuIENQVlRfV29yZFJhbmdlKCk7DQotfQ0KLQ0KLUNQVlRfV29yZFJhbmdlIENGWF9FZGl0OjpHZXRWaXNpYmxlV29yZFJhbmdlKCkgY29uc3QNCi17DQotCWlmIChtX2JFbmFibGVPdmVyZmxvdykgcmV0dXJuIEdldFdob2xlV29yZFJhbmdlKCk7DQotDQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcFZULT5HZXRQbGF0ZVJlY3QoKTsNCi0NCi0JCUNQVlRfV29yZFBsYWNlIHBsYWNlMSA9IG1fcFZULT5TZWFyY2hXb3JkUGxhY2UoRWRpdFRvVlQoQ1BERl9Qb2ludChyY1BsYXRlLmxlZnQscmNQbGF0ZS50b3ApKSk7DQotCQlDUFZUX1dvcmRQbGFjZSBwbGFjZTIgPSBtX3BWVC0+U2VhcmNoV29yZFBsYWNlKEVkaXRUb1ZUKENQREZfUG9pbnQocmNQbGF0ZS5yaWdodCxyY1BsYXRlLmJvdHRvbSkpKTsNCi0NCi0JCXJldHVybiBDUFZUX1dvcmRSYW5nZShwbGFjZTEscGxhY2UyKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gQ1BWVF9Xb3JkUmFuZ2UoKTsNCi19DQotDQotQ1BWVF9Xb3JkUGxhY2UgQ0ZYX0VkaXQ6OlNlYXJjaFdvcmRQbGFjZShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3QNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlyZXR1cm4gbV9wVlQtPlNlYXJjaFdvcmRQbGFjZShFZGl0VG9WVChwb2ludCkpOw0KLQl9DQotDQotCXJldHVybiBDUFZUX1dvcmRQbGFjZSgpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpQYWludCgpDQotew0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSkNCi0Jew0KLQkJUmVhcnJhbmdlQWxsKCk7DQotCQlTY3JvbGxUb0NhcmV0KCk7DQotCQlSZWZyZXNoKFJQX05PQU5BTFlTRSk7DQotCQlTZXRDYXJldE9yaWdpbigpOw0KLQkJU2V0Q2FyZXRJbmZvKCk7DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6UmVhcnJhbmdlQWxsKCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKG1fd3BDYXJldCk7DQotCQltX3BWVC0+UmVhcnJhbmdlQWxsKCk7DQotCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKG1fd3BDYXJldCk7DQotCQlTZXRTY3JvbGxJbmZvKCk7DQotCQlTZXRDb250ZW50Q2hhbmdlZCgpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlJlYXJyYW5nZVBhcnQoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiByYW5nZSkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKG1fd3BDYXJldCk7DQotCQltX3BWVC0+UmVhcnJhbmdlUGFydChyYW5nZSk7DQotCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKG1fd3BDYXJldCk7DQotCQlTZXRTY3JvbGxJbmZvKCk7DQotCQlTZXRDb250ZW50Q2hhbmdlZCgpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldENvbnRlbnRDaGFuZ2VkKCkNCi17DQotCWlmIChtX2JOb3RpZnkgJiYgbV9wTm90aWZ5KQ0KLQl7DQotCQlDUERGX1JlY3QgcmNDb250ZW50ID0gbV9wVlQtPkdldENvbnRlbnRSZWN0KCk7DQotCQlpZiAocmNDb250ZW50LldpZHRoKCkgIT0gbV9yY09sZENvbnRlbnQuV2lkdGgoKSB8fA0KLQkJCXJjQ29udGVudC5IZWlnaHQoKSAhPSBtX3JjT2xkQ29udGVudC5IZWlnaHQoKSkNCi0JCXsNCi0JCQlpZiAoIW1fYk5vdGlmeUZsYWcpDQotCQkJew0KLQkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQkJbV9wTm90aWZ5LT5JT25Db250ZW50Q2hhbmdlKHJjQ29udGVudCk7DQotCQkJCW1fYk5vdGlmeUZsYWcgPSBGQUxTRTsNCi0JCQl9DQotCQkJbV9yY09sZENvbnRlbnQgPSByY0NvbnRlbnQ7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2VsZWN0QWxsKCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQltX1NlbFN0YXRlID0gR2V0V2hvbGVXb3JkUmFuZ2UoKTsJCQ0KLQkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5FbmRQb3MpOwkJDQotCQkNCi0JCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCUNQVlRfV29yZFJhbmdlIHdyVmlzaWJsZSA9IEdldFZpc2libGVXb3JkUmFuZ2UoKTsNCi0JCVJlZnJlc2goUlBfT1BUSU9OQUwsJndyVmlzaWJsZSk7DQotCQlTZXRDYXJldEluZm8oKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZWxlY3ROb25lKCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAobV9TZWxTdGF0ZS5Jc0V4aXN0KCkpDQotCQl7DQotCQkJQ1BWVF9Xb3JkUmFuZ2Ugd3JUZW1wID0gbV9TZWxTdGF0ZS5Db252ZXJ0VG9Xb3JkUmFuZ2UoKTsNCi0JCQltX1NlbFN0YXRlLkRlZmF1bHQoKTsNCi0JCQlSZWZyZXNoKFJQX09QVElPTkFMLCZ3clRlbXApOw0KLQkJfQ0KLQl9CQ0KLX0NCi0NCi1GWF9CT09MCUNGWF9FZGl0OjpJc1NlbGVjdGVkKCkgY29uc3QNCi17DQotCXJldHVybiBtX1NlbFN0YXRlLklzRXhpc3QoKTsNCi19DQotDQotQ1BERl9Qb2ludCBDRlhfRWRpdDo6VlRUb0VkaXQoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdA0KLXsNCi0JQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOw0KLQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcFZULT5HZXRQbGF0ZVJlY3QoKTsNCi0NCi0JRlhfRkxPQVQgZlBhZGRpbmcgPSAwLjBmOw0KLQ0KLQlzd2l0Y2ggKG1fbkFsaWdubWVudCkNCi0Jew0KLQljYXNlIDA6DQotCQlmUGFkZGluZyA9IDAuMGY7DQotCQlicmVhazsNCi0JY2FzZSAxOg0KLQkJZlBhZGRpbmcgPSAocmNQbGF0ZS5IZWlnaHQoKSAtIHJjQ29udGVudC5IZWlnaHQoKSkgKiAwLjVmOw0KLQkJYnJlYWs7DQotCWNhc2UgMjoNCi0JCWZQYWRkaW5nID0gcmNQbGF0ZS5IZWlnaHQoKSAtIHJjQ29udGVudC5IZWlnaHQoKTsNCi0JCWJyZWFrOw0KLQl9DQotCQ0KLQlyZXR1cm4gQ1BERl9Qb2ludChwb2ludC54IC0gKG1fcHRTY3JvbGxQb3MueCAtIHJjUGxhdGUubGVmdCksDQotCQlwb2ludC55IC0gKG1fcHRTY3JvbGxQb3MueSArIGZQYWRkaW5nIC0gcmNQbGF0ZS50b3ApKTsNCi19DQotDQotQ1BERl9Qb2ludCBDRlhfRWRpdDo6RWRpdFRvVlQoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdA0KLXsNCi0JQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOw0KLQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcFZULT5HZXRQbGF0ZVJlY3QoKTsNCi0NCi0JRlhfRkxPQVQgZlBhZGRpbmcgPSAwLjBmOw0KLQ0KLQlzd2l0Y2ggKG1fbkFsaWdubWVudCkNCi0Jew0KLQljYXNlIDA6DQotCQlmUGFkZGluZyA9IDAuMGY7DQotCQlicmVhazsNCi0JY2FzZSAxOg0KLQkJZlBhZGRpbmcgPSAocmNQbGF0ZS5IZWlnaHQoKSAtIHJjQ29udGVudC5IZWlnaHQoKSkgKiAwLjVmOw0KLQkJYnJlYWs7DQotCWNhc2UgMjoNCi0JCWZQYWRkaW5nID0gcmNQbGF0ZS5IZWlnaHQoKSAtIHJjQ29udGVudC5IZWlnaHQoKTsNCi0JCWJyZWFrOw0KLQl9DQotDQotCXJldHVybiBDUERGX1BvaW50KHBvaW50LnggKyAobV9wdFNjcm9sbFBvcy54IC0gcmNQbGF0ZS5sZWZ0KSwNCi0JCXBvaW50LnkgKyAobV9wdFNjcm9sbFBvcy55ICsgZlBhZGRpbmcgLSByY1BsYXRlLnRvcCkpOw0KLX0NCi0NCi1DUERGX1JlY3QgQ0ZYX0VkaXQ6OlZUVG9FZGl0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QpIGNvbnN0DQotew0KLQlDUERGX1BvaW50IHB0TGVmdEJvdHRvbSA9IFZUVG9FZGl0KENQREZfUG9pbnQocmVjdC5sZWZ0LHJlY3QuYm90dG9tKSk7DQotCUNQREZfUG9pbnQgcHRSaWdodFRvcCA9IFZUVG9FZGl0KENQREZfUG9pbnQocmVjdC5yaWdodCxyZWN0LnRvcCkpOw0KLQ0KLQlyZXR1cm4gQ1BERl9SZWN0KHB0TGVmdEJvdHRvbS54LHB0TGVmdEJvdHRvbS55LHB0UmlnaHRUb3AueCxwdFJpZ2h0VG9wLnkpOw0KLX0NCi0NCi1DUERGX1JlY3QgQ0ZYX0VkaXQ6OkVkaXRUb1ZUKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpIGNvbnN0DQotew0KLQlDUERGX1BvaW50IHB0TGVmdEJvdHRvbSA9IEVkaXRUb1ZUKENQREZfUG9pbnQocmVjdC5sZWZ0LHJlY3QuYm90dG9tKSk7DQotCUNQREZfUG9pbnQgcHRSaWdodFRvcCA9IEVkaXRUb1ZUKENQREZfUG9pbnQocmVjdC5yaWdodCxyZWN0LnRvcCkpOw0KLQ0KLQlyZXR1cm4gQ1BERl9SZWN0KHB0TGVmdEJvdHRvbS54LHB0TGVmdEJvdHRvbS55LHB0UmlnaHRUb3AueCxwdFJpZ2h0VG9wLnkpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRTY3JvbGxJbmZvKCkNCi17DQotCWlmIChtX2JOb3RpZnkgJiYgbV9wTm90aWZ5KQ0KLQl7DQotCQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcFZULT5HZXRQbGF0ZVJlY3QoKTsNCi0JCUNQREZfUmVjdCByY0NvbnRlbnQgPSBtX3BWVC0+R2V0Q29udGVudFJlY3QoKTsNCi0NCi0JCWlmICghbV9iTm90aWZ5RmxhZykNCi0JCXsNCi0JCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQltX3BOb3RpZnktPklPblNldFNjcm9sbEluZm9YKHJjUGxhdGUubGVmdCwgcmNQbGF0ZS5yaWdodCwgDQotCQkJCQkJCQlyY0NvbnRlbnQubGVmdCwgcmNDb250ZW50LnJpZ2h0LCByY1BsYXRlLldpZHRoKCkgLyAzLCByY1BsYXRlLldpZHRoKCkpOw0KLQkJCQ0KLQkJCW1fcE5vdGlmeS0+SU9uU2V0U2Nyb2xsSW5mb1kocmNQbGF0ZS5ib3R0b20sIHJjUGxhdGUudG9wLCANCi0JCQkJCXJjQ29udGVudC5ib3R0b20sIHJjQ29udGVudC50b3AsIHJjUGxhdGUuSGVpZ2h0KCkgLyAzLCByY1BsYXRlLkhlaWdodCgpKTsNCi0JCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0U2Nyb2xsUG9zWChGWF9GTE9BVCBmeCkNCi17DQotCWlmICghbV9iRW5hYmxlU2Nyb2xsKSByZXR1cm47DQotDQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKG1fcHRTY3JvbGxQb3MueCxmeCkpDQotCQl7DQotCQkJbV9wdFNjcm9sbFBvcy54ID0gZng7CQkJDQotCQkJUmVmcmVzaChSUF9OT0FOQUxZU0UpOw0KLQ0KLQkJCWlmIChtX2JOb3RpZnkgJiYgbV9wTm90aWZ5KQ0KLQkJCXsNCi0JCQkJaWYgKCFtX2JOb3RpZnlGbGFnKQ0KLQkJCQl7DQotCQkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQkJCW1fcE5vdGlmeS0+SU9uU2V0U2Nyb2xsUG9zWChmeCk7DQotCQkJCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0U2Nyb2xsUG9zWShGWF9GTE9BVCBmeSkNCi17DQotCWlmICghbV9iRW5hYmxlU2Nyb2xsKSByZXR1cm47DQotDQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKG1fcHRTY3JvbGxQb3MueSxmeSkpDQotCQl7CQkJCQ0KLQkJCW1fcHRTY3JvbGxQb3MueSA9IGZ5Ow0KLQkJCVJlZnJlc2goUlBfTk9BTkFMWVNFKTsNCi0NCi0JCQlpZiAobV9iTm90aWZ5ICYmIG1fcE5vdGlmeSkNCi0JCQl7DQotCQkJCWlmICghbV9iTm90aWZ5RmxhZykNCi0JCQkJew0KLQkJCQkJbV9iTm90aWZ5RmxhZyA9IFRSVUU7DQotCQkJCQltX3BOb3RpZnktPklPblNldFNjcm9sbFBvc1koZnkpOw0KLQkJCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOw0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpDQotew0KLQlTZXRTY3JvbGxQb3NYKHBvaW50LngpOw0KLQlTZXRTY3JvbGxQb3NZKHBvaW50LnkpOw0KLQlTZXRTY3JvbGxMaW1pdCgpOw0KLQlTZXRDYXJldEluZm8oKTsNCi19DQotDQotQ1BERl9Qb2ludCBDRlhfRWRpdDo6R2V0U2Nyb2xsUG9zKCkgY29uc3QNCi17DQotCXJldHVybiBtX3B0U2Nyb2xsUG9zOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpTZXRTY3JvbGxMaW1pdCgpDQotew0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOw0KLQkJQ1BERl9SZWN0IHJjUGxhdGUgPSBtX3BWVC0+R2V0UGxhdGVSZWN0KCk7DQotDQotCQlpZiAocmNQbGF0ZS5XaWR0aCgpID4gcmNDb250ZW50LldpZHRoKCkpDQotCQl7DQotCQkJU2V0U2Nyb2xsUG9zWChyY1BsYXRlLmxlZnQpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChGWF9FRElUX0lzRmxvYXRTbWFsbGVyKG1fcHRTY3JvbGxQb3MueCwgcmNDb250ZW50LmxlZnQpKQ0KLQkJCXsNCi0JCQkJU2V0U2Nyb2xsUG9zWChyY0NvbnRlbnQubGVmdCk7CQkJDQotCQkJfQ0KLQkJCWVsc2UgaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihtX3B0U2Nyb2xsUG9zLngsIHJjQ29udGVudC5yaWdodCAtIHJjUGxhdGUuV2lkdGgoKSkpDQotCQkJew0KLQkJCQlTZXRTY3JvbGxQb3NYKHJjQ29udGVudC5yaWdodCAtIHJjUGxhdGUuV2lkdGgoKSk7DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJaWYgKHJjUGxhdGUuSGVpZ2h0KCkgPiByY0NvbnRlbnQuSGVpZ2h0KCkpDQotCQl7DQotCQkJU2V0U2Nyb2xsUG9zWShyY1BsYXRlLnRvcCk7DQotCQl9DQotCQllbHNlCQkNCi0JCXsNCi0JCQlpZiAoRlhfRURJVF9Jc0Zsb2F0U21hbGxlcihtX3B0U2Nyb2xsUG9zLnksIHJjQ29udGVudC5ib3R0b20gKyByY1BsYXRlLkhlaWdodCgpKSkNCi0JCQl7DQotCQkJCVNldFNjcm9sbFBvc1kocmNDb250ZW50LmJvdHRvbSArIHJjUGxhdGUuSGVpZ2h0KCkpOw0KLQkJCX0NCi0JCQllbHNlIGlmIChGWF9FRElUX0lzRmxvYXRCaWdnZXIobV9wdFNjcm9sbFBvcy55LCByY0NvbnRlbnQudG9wKSkNCi0JCQl7DQotCQkJCVNldFNjcm9sbFBvc1kocmNDb250ZW50LnRvcCk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNjcm9sbFRvQ2FyZXQoKQ0KLXsNCi0JU2V0U2Nyb2xsTGltaXQoKTsNCi0NCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCXsNCi0JCUNQREZfUG9pbnQgcHRIZWFkKDAsMCk7DQotCQlDUERGX1BvaW50IHB0Rm9vdCgwLDApOw0KLQ0KLQkJaWYgKElQREZfVmFyaWFibGVUZXh0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wVlQtPkdldEl0ZXJhdG9yKCkpDQotCQl7DQotCQkJcEl0ZXJhdG9yLT5TZXRBdChtX3dwQ2FyZXQpOw0KLQ0KLQkJCUNQVlRfV29yZCB3b3JkOw0KLQkJCUNQVlRfTGluZSBsaW5lOw0KLQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpDQotCQkJew0KLQkJCQlwdEhlYWQueCA9IHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aDsNCi0JCQkJcHRIZWFkLnkgPSB3b3JkLnB0V29yZC55ICsgd29yZC5mQXNjZW50Ow0KLQkJCQlwdEZvb3QueCA9IHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aDsNCi0JCQkJcHRGb290LnkgPSB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudDsNCi0JCQl9DQotCQkJZWxzZSBpZiAocEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmUpKQ0KLQkJCXsJCQkJDQotCQkJCXB0SGVhZC54ID0gbGluZS5wdExpbmUueDsNCi0JCQkJcHRIZWFkLnkgPSBsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZUFzY2VudDsNCi0JCQkJcHRGb290LnggPSBsaW5lLnB0TGluZS54Ow0KLQkJCQlwdEZvb3QueSA9IGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lRGVzY2VudDsNCi0JCQl9DQotCQl9DQotDQotCQlDUERGX1BvaW50IHB0SGVhZEVkaXQgPSBWVFRvRWRpdChwdEhlYWQpOw0KLQkJQ1BERl9Qb2ludCBwdEZvb3RFZGl0ID0gVlRUb0VkaXQocHRGb290KTsNCi0NCi0JCUNQREZfUmVjdCByY1BsYXRlID0gbV9wVlQtPkdldFBsYXRlUmVjdCgpOw0KLQ0KLQkJaWYgKCFGWF9FRElUX0lzRmxvYXRFcXVhbChyY1BsYXRlLmxlZnQscmNQbGF0ZS5yaWdodCkpDQotCQl7DQotCQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocHRIZWFkRWRpdC54LCByY1BsYXRlLmxlZnQpIHx8DQotCQkJCUZYX0VESVRfSXNGbG9hdEVxdWFsKHB0SGVhZEVkaXQueCwgcmNQbGF0ZS5sZWZ0KSkNCi0JCQl7DQotCQkJCVNldFNjcm9sbFBvc1gocHRIZWFkLngpOw0KLQkJCX0NCi0JCQllbHNlIGlmIChGWF9FRElUX0lzRmxvYXRCaWdnZXIocHRIZWFkRWRpdC54LCByY1BsYXRlLnJpZ2h0KSkNCi0JCQl7DQotCQkJCVNldFNjcm9sbFBvc1gocHRIZWFkLnggLSByY1BsYXRlLldpZHRoKCkpOw0KLQkJCX0NCi0JCX0NCi0NCi0JCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwocmNQbGF0ZS50b3AscmNQbGF0ZS5ib3R0b20pKQ0KLQkJew0KLQkJCWlmIChGWF9FRElUX0lzRmxvYXRTbWFsbGVyKHB0Rm9vdEVkaXQueSwgcmNQbGF0ZS5ib3R0b20pIHx8DQotCQkJCUZYX0VESVRfSXNGbG9hdEVxdWFsKHB0Rm9vdEVkaXQueSwgcmNQbGF0ZS5ib3R0b20pKQ0KLQkJCXsNCi0JCQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocHRIZWFkRWRpdC55LCByY1BsYXRlLnRvcCkpDQotCQkJCXsNCi0JCQkJCVNldFNjcm9sbFBvc1kocHRGb290LnkgKyByY1BsYXRlLkhlaWdodCgpKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCQllbHNlIGlmIChGWF9FRElUX0lzRmxvYXRCaWdnZXIocHRIZWFkRWRpdC55LCByY1BsYXRlLnRvcCkpDQotCQkJew0KLQkJCQlpZiAoRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKHB0Rm9vdEVkaXQueSwgcmNQbGF0ZS5ib3R0b20pKQ0KLQkJCQl7DQotCQkJCQlTZXRTY3JvbGxQb3NZKHB0SGVhZC55KTsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpSZWZyZXNoKFJFRlJFU0hfUExBTl9FIGVQbGFuLGNvbnN0IENQVlRfV29yZFJhbmdlICogcFJhbmdlMSxjb25zdCBDUFZUX1dvcmRSYW5nZSAqIHBSYW5nZTIpDQotew0KLQlpZiAobV9iRW5hYmxlUmVmcmVzaCAmJiBtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQltX1JlZnJlc2guQmVnaW5SZWZyZXNoKCk7DQotCQlSZWZyZXNoUHVzaExpbmVSZWN0cyhHZXRWaXNpYmxlV29yZFJhbmdlKCkpOw0KLQ0KLS8vIAkJaWYgKCFGWF9FRElUX0lzRmxvYXRFcXVhbChtX3B0UmVmcmVzaFNjcm9sbFBvcy54LG1fcHRTY3JvbGxQb3MueCkgfHwgDQotLy8gCQkJIUZYX0VESVRfSXNGbG9hdEVxdWFsKG1fcHRSZWZyZXNoU2Nyb2xsUG9zLnksbV9wdFNjcm9sbFBvcy55KSkNCi0vLyAJCXsNCi0JCQltX1JlZnJlc2guTm9BbmFseXNlKCk7DQotCQkJbV9wdFJlZnJlc2hTY3JvbGxQb3MgPSBtX3B0U2Nyb2xsUG9zOw0KLS8vIAkJfQ0KLS8vIAkJZWxzZQ0KLS8vIAkJew0KLS8vIAkJCXN3aXRjaCAoZVBsYW4pDQotLy8gCQkJew0KLS8vIAkJCWNhc2UgUlBfQU5BTFlTRToNCi0vLyAJCQkJbV9SZWZyZXNoLkFuYWx5c2UobV9wVlQtPkdldEFsaWdubWVudCgpKTsNCi0vLyANCi0vLyAJCQkJaWYgKHBSYW5nZTEpIFJlZnJlc2hQdXNoUmFuZG9tUmVjdHMoKnBSYW5nZTEpOw0KLS8vIAkJCQlpZiAocFJhbmdlMikgUmVmcmVzaFB1c2hSYW5kb21SZWN0cygqcFJhbmdlMik7DQotLy8gCQkJCWJyZWFrOw0KLS8vIAkJCWNhc2UgUlBfTk9BTkFMWVNFOg0KLS8vIAkJCQltX1JlZnJlc2guTm9BbmFseXNlKCk7DQotLy8gCQkJCWJyZWFrOw0KLS8vIAkJCWNhc2UgUlBfT1BUSU9OQUw6DQotLy8gCQkJCWlmIChwUmFuZ2UxKSBSZWZyZXNoUHVzaFJhbmRvbVJlY3RzKCpwUmFuZ2UxKTsNCi0vLyAJCQkJaWYgKHBSYW5nZTIpIFJlZnJlc2hQdXNoUmFuZG9tUmVjdHMoKnBSYW5nZTIpOw0KLS8vIAkJCQlicmVhazsJDQotLy8gCQkJfQ0KLS8vIAkJfQkJDQotDQotCQlpZiAobV9iTm90aWZ5ICYmIG1fcE5vdGlmeSkNCi0JCXsNCi0JCQlpZiAoIW1fYk5vdGlmeUZsYWcpDQotCQkJew0KLQkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQkJaWYgKGNvbnN0IENGWF9FZGl0X1JlY3RBcnJheSAqIHBSZWN0cyA9IG1fUmVmcmVzaC5HZXRSZWZyZXNoUmVjdHMoKSkNCi0JCQkJew0KLQkJCQkJZm9yIChGWF9JTlQzMiBpID0gMCwgc3ogPSBwUmVjdHMtPkdldFNpemUoKTsgaSA8IHN6OyBpKyspDQotCQkJCQkJbV9wTm90aWZ5LT5JT25JbnZhbGlkYXRlUmVjdChwUmVjdHMtPkdldEF0KGkpKTsNCi0JCQkJfQ0KLQkJCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJbV9SZWZyZXNoLkVuZFJlZnJlc2goKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpSZWZyZXNoUHVzaExpbmVSZWN0cyhjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyKQ0KLXsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCXsNCi0JCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQ0KLQkJew0KLQkJCUNQVlRfV29yZFBsYWNlIHdwQmVnaW4gPSB3ci5CZWdpblBvczsNCi0JCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdwQmVnaW4pOw0KLQkJCUNQVlRfV29yZFBsYWNlIHdwRW5kID0gd3IuRW5kUG9zOw0KLQkJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2Uod3BFbmQpOw0KLQkJCXBJdGVyYXRvci0+U2V0QXQod3BCZWdpbik7DQotDQotCQkJQ1BWVF9MaW5lIGxpbmVpbmZvOwkNCi0JCQlkbw0KLQkJCXsNCi0JCQkJaWYgKCFwSXRlcmF0b3ItPkdldExpbmUobGluZWluZm8pKWJyZWFrOw0KLQkJCQlpZiAobGluZWluZm8ubGluZXBsYWNlLkxpbmVDbXAod3BFbmQpID4gMClicmVhazsNCi0NCi0JCQkJQ1BERl9SZWN0IHJjTGluZShsaW5laW5mby5wdExpbmUueCwNCi0JCQkJCQkJCQlsaW5laW5mby5wdExpbmUueSArIGxpbmVpbmZvLmZMaW5lRGVzY2VudCwNCi0JCQkJCQkJCQlsaW5laW5mby5wdExpbmUueCArIGxpbmVpbmZvLmZMaW5lV2lkdGgsDQotCQkJCQkJCQkJbGluZWluZm8ucHRMaW5lLnkgKyBsaW5laW5mby5mTGluZUFzY2VudCk7DQotDQotCQkJCW1fUmVmcmVzaC5QdXNoKENQVlRfV29yZFJhbmdlKGxpbmVpbmZvLmxpbmVwbGFjZSxsaW5laW5mby5saW5lRW5kKSxWVFRvRWRpdChyY0xpbmUpKTsNCi0NCi0JCQl9d2hpbGUgKHBJdGVyYXRvci0+TmV4dExpbmUoKSk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6UmVmcmVzaFB1c2hSYW5kb21SZWN0cyhjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyKQ0KLXsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCXsNCi0JCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQ0KLQkJew0KLQkJCUNQVlRfV29yZFJhbmdlIHdyVGVtcCA9IHdyOw0KLQ0KLQkJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2Uod3JUZW1wLkJlZ2luUG9zKTsNCi0JCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdyVGVtcC5FbmRQb3MpOw0KLQkJCXBJdGVyYXRvci0+U2V0QXQod3JUZW1wLkJlZ2luUG9zKTsNCi0NCi0JCQlDUFZUX1dvcmQgd29yZGluZm87CQ0KLQkJCUNQVlRfTGluZSBsaW5laW5mbzsJDQotCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2U7DQotDQotCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkNCi0JCQl7DQotCQkJCXBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOw0KLQkJCQlpZiAocGxhY2UuV29yZENtcCh3clRlbXAuRW5kUG9zKSA+IDApIGJyZWFrOw0KLQkJCQkJCQ0KLQkJCQlwSXRlcmF0b3ItPkdldFdvcmQod29yZGluZm8pOw0KLQkJCQlwSXRlcmF0b3ItPkdldExpbmUobGluZWluZm8pOw0KLQ0KLQkJCQlpZiAocGxhY2UuTGluZUNtcCh3clRlbXAuQmVnaW5Qb3MpID09IDAgfHwgcGxhY2UuTGluZUNtcCh3clRlbXAuRW5kUG9zKSA9PSAwKQ0KLQkJCQl7DQotCQkJCQlDUERGX1JlY3QgcmNXb3JkKHdvcmRpbmZvLnB0V29yZC54LA0KLQkJCQkJCQkJCQlsaW5laW5mby5wdExpbmUueSArIGxpbmVpbmZvLmZMaW5lRGVzY2VudCwNCi0JCQkJCQkJCQkJd29yZGluZm8ucHRXb3JkLnggKyB3b3JkaW5mby5mV2lkdGgsDQotCQkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS55ICsgbGluZWluZm8uZkxpbmVBc2NlbnQpOw0KLQ0KLQkJCQkJbV9SZWZyZXNoLkFkZFJlZnJlc2goVlRUb0VkaXQocmNXb3JkKSk7DQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQl7CQkNCi0JCQkJCUNQREZfUmVjdCByY0xpbmUobGluZWluZm8ucHRMaW5lLngsDQotCQkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS55ICsgbGluZWluZm8uZkxpbmVEZXNjZW50LA0KLQkJCQkJCQkJCQlsaW5laW5mby5wdExpbmUueCArIGxpbmVpbmZvLmZMaW5lV2lkdGgsDQotCQkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS55ICsgbGluZWluZm8uZkxpbmVBc2NlbnQpOw0KLQ0KLQkJCQkJbV9SZWZyZXNoLkFkZFJlZnJlc2goVlRUb0VkaXQocmNMaW5lKSk7DQotDQotCQkJCQlwSXRlcmF0b3ItPk5leHRMaW5lKCk7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6UmVmcmVzaFdvcmRSYW5nZShjb25zdCBDUFZUX1dvcmRSYW5nZSYgd3IpDQotew0KLQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJQ1BWVF9Xb3JkUmFuZ2Ugd3JUZW1wID0gd3I7DQotDQotCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdyVGVtcC5CZWdpblBvcyk7DQotCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdyVGVtcC5FbmRQb3MpOw0KLQkJcEl0ZXJhdG9yLT5TZXRBdCh3clRlbXAuQmVnaW5Qb3MpOw0KLQ0KLQkJQ1BWVF9Xb3JkIHdvcmRpbmZvOwkNCi0JCUNQVlRfTGluZSBsaW5laW5mbzsJDQotCQlDUFZUX1dvcmRQbGFjZSBwbGFjZTsNCi0NCi0JCXdoaWxlIChwSXRlcmF0b3ItPk5leHRXb3JkKCkpDQotCQl7DQotCQkJcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotCQkJaWYgKHBsYWNlLldvcmRDbXAod3JUZW1wLkVuZFBvcykgPiAwKSBicmVhazsNCi0JCQkJCQ0KLQkJCXBJdGVyYXRvci0+R2V0V29yZCh3b3JkaW5mbyk7DQotCQkJcEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmVpbmZvKTsNCi0NCi0JCQlpZiAocGxhY2UuTGluZUNtcCh3clRlbXAuQmVnaW5Qb3MpID09IDAgfHwgcGxhY2UuTGluZUNtcCh3clRlbXAuRW5kUG9zKSA9PSAwKQ0KLQkJCXsNCi0JCQkJQ1BERl9SZWN0IHJjV29yZCh3b3JkaW5mby5wdFdvcmQueCwNCi0JCQkJCQkJCQlsaW5laW5mby5wdExpbmUueSArIGxpbmVpbmZvLmZMaW5lRGVzY2VudCwNCi0JCQkJCQkJCQl3b3JkaW5mby5wdFdvcmQueCArIHdvcmRpbmZvLmZXaWR0aCwNCi0JCQkJCQkJCQlsaW5laW5mby5wdExpbmUueSArIGxpbmVpbmZvLmZMaW5lQXNjZW50KTsNCi0NCi0JCQkJaWYgKG1fYk5vdGlmeSAmJiBtX3BOb3RpZnkpDQotCQkJCXsNCi0JCQkJCWlmICghbV9iTm90aWZ5RmxhZykNCi0JCQkJCXsNCi0JCQkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQkJCQlDUERGX1JlY3QgcmNSZWZyZXNoID0gVlRUb0VkaXQocmNXb3JkKTsNCi0JCQkJCQltX3BOb3RpZnktPklPbkludmFsaWRhdGVSZWN0KCZyY1JlZnJlc2gpOw0KLQkJCQkJCW1fYk5vdGlmeUZsYWcgPSBGQUxTRTsNCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCX0NCi0JCQllbHNlDQotCQkJewkJDQotCQkJCUNQREZfUmVjdCByY0xpbmUobGluZWluZm8ucHRMaW5lLngsDQotCQkJCQkJCQkJbGluZWluZm8ucHRMaW5lLnkgKyBsaW5laW5mby5mTGluZURlc2NlbnQsDQotCQkJCQkJCQkJbGluZWluZm8ucHRMaW5lLnggKyBsaW5laW5mby5mTGluZVdpZHRoLA0KLQkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS55ICsgbGluZWluZm8uZkxpbmVBc2NlbnQpOw0KLQ0KLQkJCQlpZiAobV9iTm90aWZ5ICYmIG1fcE5vdGlmeSkNCi0JCQkJew0KLQkJCQkJaWYgKCFtX2JOb3RpZnlGbGFnKQ0KLQkJCQkJew0KLQkJCQkJCW1fYk5vdGlmeUZsYWcgPSBUUlVFOw0KLQkJCQkJCUNQREZfUmVjdCByY1JlZnJlc2ggPSBWVFRvRWRpdChyY0xpbmUpOw0KLQkJCQkJCW1fcE5vdGlmeS0+SU9uSW52YWxpZGF0ZVJlY3QoJnJjUmVmcmVzaCk7DQotCQkJCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOw0KLQkJCQkJfQ0KLQkJCQl9DQotDQotCQkJCXBJdGVyYXRvci0+TmV4dExpbmUoKTsNCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0Q2FyZXQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkNCi17DQotCW1fd3BPbGRDYXJldCA9IG1fd3BDYXJldDsgDQotCW1fd3BDYXJldCA9IHBsYWNlOwkNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0Q2FyZXRJbmZvKCkNCi17DQotCWlmIChtX2JOb3RpZnkgJiYgbV9wTm90aWZ5KQ0KLQl7DQotCQlpZiAoIW1fYk5vdGlmeUZsYWcpDQotCQl7DQotCQkJQ1BERl9Qb2ludCBwdEhlYWQoMC4wZiwwLjBmKSxwdEZvb3QoMC4wZiwwLjBmKTsNCi0NCi0JCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkNCi0JCQl7DQotCQkJCXBJdGVyYXRvci0+U2V0QXQobV93cENhcmV0KTsNCi0JCQkJQ1BWVF9Xb3JkIHdvcmQ7DQotCQkJCUNQVlRfTGluZSBsaW5lOw0KLQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQ0KLQkJCQl7DQotCQkJCQlwdEhlYWQueCA9IHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aDsNCi0JCQkJCXB0SGVhZC55ID0gd29yZC5wdFdvcmQueSArIHdvcmQuZkFzY2VudDsNCi0JCQkJCXB0Rm9vdC54ID0gd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoOw0KLQkJCQkJcHRGb290LnkgPSB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudDsNCi0JCQkJfQ0KLQkJCQllbHNlIGlmIChwSXRlcmF0b3ItPkdldExpbmUobGluZSkpDQotCQkJCXsJCQkJDQotCQkJCQlwdEhlYWQueCA9IGxpbmUucHRMaW5lLng7DQotCQkJCQlwdEhlYWQueSA9IGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lQXNjZW50Ow0KLQkJCQkJcHRGb290LnggPSBsaW5lLnB0TGluZS54Ow0KLQkJCQkJcHRGb290LnkgPSBsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZURlc2NlbnQ7DQotCQkJCX0NCi0JCQl9CQkNCi0NCi0JCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQltX3BOb3RpZnktPklPblNldENhcmV0KCFtX1NlbFN0YXRlLklzRXhpc3QoKSxWVFRvRWRpdChwdEhlYWQpLFZUVG9FZGl0KHB0Rm9vdCksIG1fd3BDYXJldCk7DQotCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOw0KLQkJfQ0KLQl9DQotDQotCVNldENhcmV0Q2hhbmdlKCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldENhcmV0Q2hhbmdlKCkNCi17DQotCWlmICh0aGlzLT5tX3dwQ2FyZXQgPT0gdGhpcy0+bV93cE9sZENhcmV0KSByZXR1cm47DQotDQotCWlmIChtX2JOb3RpZnkgJiYgbV9wVlQtPklzUmljaFRleHQoKSAmJiBtX3BOb3RpZnkpDQotCXsNCi0JCUNQVlRfU2VjUHJvcHMgU2VjUHJvcHM7DQotCQlDUFZUX1dvcmRQcm9wcyBXb3JkUHJvcHM7DQotDQotCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkNCi0JCXsNCi0JCQlwSXRlcmF0b3ItPlNldEF0KG1fd3BDYXJldCk7DQotCQkJQ1BWVF9Xb3JkIHdvcmQ7DQotCQkJQ1BWVF9TZWN0aW9uIHNlY3Rpb247DQotDQotCQkJaWYgKHBJdGVyYXRvci0+R2V0U2VjdGlvbihzZWN0aW9uKSkNCi0JCQl7DQotCQkJCVNlY1Byb3BzID0gc2VjdGlvbi5TZWNQcm9wczsNCi0JCQkJV29yZFByb3BzID0gc2VjdGlvbi5Xb3JkUHJvcHM7DQotCQkJfQ0KLQkJCQ0KLQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpDQotCQkJewkJCQkNCi0JCQkJV29yZFByb3BzID0gd29yZC5Xb3JkUHJvcHM7CQkJCQ0KLQkJCX0NCi0JCX0JCQ0KLQkJDQotCQlpZiAoIW1fYk5vdGlmeUZsYWcpDQotCQl7DQotCQkJbV9iTm90aWZ5RmxhZyA9IFRSVUU7DQotCQkJbV9wTm90aWZ5LT5JT25DYXJldENoYW5nZShTZWNQcm9wcyxXb3JkUHJvcHMpOw0KLQkJCW1fYk5vdGlmeUZsYWcgPSBGQUxTRTsNCi0JCX0NCi0JfQkNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6U2V0Q2FyZXQoRlhfSU5UMzIgblBvcykNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlTZWxlY3ROb25lKCk7CQkNCi0JCVNldENhcmV0KG1fcFZULT5Xb3JkSW5kZXhUb1dvcmRQbGFjZShuUG9zKSk7DQotCQltX1NlbFN0YXRlLlNldChtX3dwQ2FyZXQsbV93cENhcmV0KTsNCi0NCi0JCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCVNldENhcmV0T3JpZ2luKCk7DQotCQlTZXRDYXJldEluZm8oKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpPbk1vdXNlRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlTZWxlY3ROb25lKCk7CQkNCi0JCVNldENhcmV0KG1fcFZULT5TZWFyY2hXb3JkUGxhY2UoRWRpdFRvVlQocG9pbnQpKSk7DQotCQltX1NlbFN0YXRlLlNldChtX3dwQ2FyZXQsbV93cENhcmV0KTsNCi0NCi0JCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCVNldENhcmV0T3JpZ2luKCk7DQotCQlTZXRDYXJldEluZm8oKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlTZXRDYXJldChtX3BWVC0+U2VhcmNoV29yZFBsYWNlKEVkaXRUb1ZUKHBvaW50KSkpOw0KLQ0KLQkJaWYgKG1fd3BDYXJldCAhPSBtX3dwT2xkQ2FyZXQpDQotCQl7DQotCQkJbV9TZWxTdGF0ZS5TZXRFbmRQb3MobV93cENhcmV0KTsJCQ0KLQ0KLQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsbV93cENhcmV0KTsNCi0JCQlSZWZyZXNoKFJQX09QVElPTkFMLCZ3cik7DQotCQkJU2V0Q2FyZXRPcmlnaW4oKTsNCi0JCQlTZXRDYXJldEluZm8oKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpPblZLX1VQKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpDQotewkNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCXsNCi0JCVNldENhcmV0KG1fcFZULT5HZXRVcFdvcmRQbGFjZShtX3dwQ2FyZXQsbV9wdENhcmV0KSk7DQotDQotCQlpZiAoYlNoaWZ0KQ0KLQkJew0KLQkJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkNCi0JCQkJbV9TZWxTdGF0ZS5TZXRFbmRQb3MobV93cENhcmV0KTsNCi0JCQllbHNlDQotCQkJCW1fU2VsU3RhdGUuU2V0KG1fd3BPbGRDYXJldCxtX3dwQ2FyZXQpOw0KLQ0KLQkJCWlmIChtX3dwT2xkQ2FyZXQgIT0gbV93cENhcmV0KQ0KLQkJCXsNCi0JCQkJU2Nyb2xsVG9DYXJldCgpOw0KLQkJCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsIG1fd3BDYXJldCk7DQotCQkJCVJlZnJlc2goUlBfT1BUSU9OQUwsICZ3cik7DQotCQkJCVNldENhcmV0SW5mbygpOw0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlTZWxlY3ROb25lKCk7CQkNCi0JCQkNCi0JCQlTY3JvbGxUb0NhcmV0KCk7CQkJDQotCQkJU2V0Q2FyZXRJbmZvKCk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6T25WS19ET1dOKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpDQotew0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSkNCi0Jew0KLQkJU2V0Q2FyZXQobV9wVlQtPkdldERvd25Xb3JkUGxhY2UobV93cENhcmV0LG1fcHRDYXJldCkpOw0KLQ0KLQkJaWYgKGJTaGlmdCkNCi0JCXsNCi0JCQlpZiAobV9TZWxTdGF0ZS5Jc0V4aXN0KCkpDQotCQkJCW1fU2VsU3RhdGUuU2V0RW5kUG9zKG1fd3BDYXJldCk7DQotCQkJZWxzZQ0KLQkJCQltX1NlbFN0YXRlLlNldChtX3dwT2xkQ2FyZXQsbV93cENhcmV0KTsNCi0NCi0JCQlpZiAobV93cE9sZENhcmV0ICE9IG1fd3BDYXJldCkNCi0JCQl7DQotCQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCQkJQ1BWVF9Xb3JkUmFuZ2Ugd3IobV93cE9sZENhcmV0LG1fd3BDYXJldCk7DQotCQkJCVJlZnJlc2goUlBfT1BUSU9OQUwsICZ3cik7DQotCQkJCVNldENhcmV0SW5mbygpOw0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlTZWxlY3ROb25lKCk7DQotDQotCQkJU2Nyb2xsVG9DYXJldCgpOwkJDQotCQkJU2V0Q2FyZXRJbmZvKCk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfRWRpdDo6T25WS19MRUZUKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpDQotew0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSkNCi0Jew0KLQkJaWYgKGJTaGlmdCkNCi0JCXsNCi0JCQlpZiAobV93cENhcmV0ID09IG1fcFZULT5HZXRMaW5lQmVnaW5QbGFjZShtX3dwQ2FyZXQpICYmDQotCQkJCW1fd3BDYXJldCAhPSBtX3BWVC0+R2V0U2VjdGlvbkJlZ2luUGxhY2UobV93cENhcmV0KSkNCi0JCQkJU2V0Q2FyZXQobV9wVlQtPkdldFByZXZXb3JkUGxhY2UobV93cENhcmV0KSk7CQ0KLQ0KLQkJCVNldENhcmV0KG1fcFZULT5HZXRQcmV2V29yZFBsYWNlKG1fd3BDYXJldCkpOw0KLQ0KLQkJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkNCi0JCQkJbV9TZWxTdGF0ZS5TZXRFbmRQb3MobV93cENhcmV0KTsJCQkNCi0JCQllbHNlDQotCQkJCW1fU2VsU3RhdGUuU2V0KG1fd3BPbGRDYXJldCwgbV93cENhcmV0KTsNCi0NCi0JCQlpZiAobV93cE9sZENhcmV0ICE9IG1fd3BDYXJldCkNCi0JCQl7DQotCQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCQkJQ1BWVF9Xb3JkUmFuZ2Ugd3IobV93cE9sZENhcmV0LG1fd3BDYXJldCk7DQotCQkJCVJlZnJlc2goUlBfT1BUSU9OQUwsJndyKTsNCi0JCQkJU2V0Q2FyZXRJbmZvKCk7DQotCQkJfQ0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkNCi0JCQl7DQotCQkJCWlmIChtX1NlbFN0YXRlLkJlZ2luUG9zLldvcmRDbXAobV9TZWxTdGF0ZS5FbmRQb3MpPDApDQotCQkJCQlTZXRDYXJldChtX1NlbFN0YXRlLkJlZ2luUG9zKTsNCi0JCQkJZWxzZQ0KLQkJCQkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5FbmRQb3MpOw0KLQ0KLQkJCQlTZWxlY3ROb25lKCk7DQotCQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCQkJU2V0Q2FyZXRJbmZvKCk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCWlmIChtX3dwQ2FyZXQgPT0gbV9wVlQtPkdldExpbmVCZWdpblBsYWNlKG1fd3BDYXJldCkgJiYNCi0JCQkJCW1fd3BDYXJldCAhPSBtX3BWVC0+R2V0U2VjdGlvbkJlZ2luUGxhY2UobV93cENhcmV0KSkNCi0JCQkJCVNldENhcmV0KG1fcFZULT5HZXRQcmV2V29yZFBsYWNlKG1fd3BDYXJldCkpOwkNCi0NCi0JCQkJU2V0Q2FyZXQobV9wVlQtPkdldFByZXZXb3JkUGxhY2UobV93cENhcmV0KSk7DQotDQotCQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCQkJU2V0Q2FyZXRPcmlnaW4oKTsNCi0JCQkJU2V0Q2FyZXRJbmZvKCk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6Ok9uVktfUklHSFQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAoYlNoaWZ0KQ0KLQkJew0KLQkJCVNldENhcmV0KG1fcFZULT5HZXROZXh0V29yZFBsYWNlKG1fd3BDYXJldCkpOw0KLQ0KLQkJCWlmIChtX3dwQ2FyZXQgPT0gbV9wVlQtPkdldExpbmVFbmRQbGFjZShtX3dwQ2FyZXQpICYmDQotCQkJCW1fd3BDYXJldCAhPSBtX3BWVC0+R2V0U2VjdGlvbkVuZFBsYWNlKG1fd3BDYXJldCkpDQotCQkJCVNldENhcmV0KG1fcFZULT5HZXROZXh0V29yZFBsYWNlKG1fd3BDYXJldCkpOw0KLQ0KLQkJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkNCi0JCQkJbV9TZWxTdGF0ZS5TZXRFbmRQb3MobV93cENhcmV0KTsJCQkNCi0JCQllbHNlDQotCQkJCW1fU2VsU3RhdGUuU2V0KG1fd3BPbGRDYXJldCxtX3dwQ2FyZXQpOwkJCQ0KLQ0KLQkJCWlmIChtX3dwT2xkQ2FyZXQgIT0gbV93cENhcmV0KQ0KLQkJCXsJCQkNCi0JCQkJU2Nyb2xsVG9DYXJldCgpOw0KLQkJCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsbV93cENhcmV0KTsNCi0JCQkJUmVmcmVzaChSUF9PUFRJT05BTCwmd3IpOw0KLQkJCQlTZXRDYXJldEluZm8oKTsNCi0JCQl9DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQ0KLQkJCXsNCi0JCQkJaWYgKG1fU2VsU3RhdGUuQmVnaW5Qb3MuV29yZENtcChtX1NlbFN0YXRlLkVuZFBvcyk+MCkNCi0JCQkJCVNldENhcmV0KG1fU2VsU3RhdGUuQmVnaW5Qb3MpOw0KLQkJCQllbHNlDQotCQkJCQlTZXRDYXJldChtX1NlbFN0YXRlLkVuZFBvcyk7DQotDQotCQkJCVNlbGVjdE5vbmUoKTsNCi0JCQkJU2Nyb2xsVG9DYXJldCgpOw0KLQkJCQlTZXRDYXJldEluZm8oKTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJU2V0Q2FyZXQobV9wVlQtPkdldE5leHRXb3JkUGxhY2UobV93cENhcmV0KSk7DQotDQotCQkJCWlmIChtX3dwQ2FyZXQgPT0gbV9wVlQtPkdldExpbmVFbmRQbGFjZShtX3dwQ2FyZXQpICYmDQotCQkJCQltX3dwQ2FyZXQgIT0gbV9wVlQtPkdldFNlY3Rpb25FbmRQbGFjZShtX3dwQ2FyZXQpKQ0KLQkJCQkJU2V0Q2FyZXQobV9wVlQtPkdldE5leHRXb3JkUGxhY2UobV93cENhcmV0KSk7CQkJCQ0KLQ0KLQkJCQlTY3JvbGxUb0NhcmV0KCk7DQotCQkJCVNldENhcmV0T3JpZ2luKCk7DQotCQkJCVNldENhcmV0SW5mbygpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpPblZLX0hPTUUoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAoYlNoaWZ0KQ0KLQkJew0KLQkJCWlmIChiQ3RybCkNCi0JCQkJU2V0Q2FyZXQobV9wVlQtPkdldEJlZ2luV29yZFBsYWNlKCkpOw0KLQkJCWVsc2UNCi0JCQkJU2V0Q2FyZXQobV9wVlQtPkdldExpbmVCZWdpblBsYWNlKG1fd3BDYXJldCkpOw0KLQ0KLQkJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkNCi0JCQkJbV9TZWxTdGF0ZS5TZXRFbmRQb3MobV93cENhcmV0KTsJCQkNCi0JCQllbHNlDQotCQkJCW1fU2VsU3RhdGUuU2V0KG1fd3BPbGRDYXJldCxtX3dwQ2FyZXQpOw0KLQ0KLQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsIG1fd3BDYXJldCk7DQotCQkJUmVmcmVzaChSUF9PUFRJT05BTCwgJndyKTsNCi0JCQlTZXRDYXJldEluZm8oKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlpZiAobV9TZWxTdGF0ZS5Jc0V4aXN0KCkpDQotCQkJew0KLQkJCQlpZiAobV9TZWxTdGF0ZS5CZWdpblBvcy5Xb3JkQ21wKG1fU2VsU3RhdGUuRW5kUG9zKTwwKQ0KLQkJCQkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5CZWdpblBvcyk7DQotCQkJCWVsc2UNCi0JCQkJCVNldENhcmV0KG1fU2VsU3RhdGUuRW5kUG9zKTsNCi0NCi0JCQkJU2VsZWN0Tm9uZSgpOw0KLQkJCQlTY3JvbGxUb0NhcmV0KCk7DQotCQkJCVNldENhcmV0SW5mbygpOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlpZiAoYkN0cmwpDQotCQkJCQlTZXRDYXJldChtX3BWVC0+R2V0QmVnaW5Xb3JkUGxhY2UoKSk7DQotCQkJCWVsc2UNCi0JCQkJCVNldENhcmV0KG1fcFZULT5HZXRMaW5lQmVnaW5QbGFjZShtX3dwQ2FyZXQpKTsJDQotCQkJCQ0KLQkJCQlTY3JvbGxUb0NhcmV0KCk7DQotCQkJCVNldENhcmV0T3JpZ2luKCk7DQotCQkJCVNldENhcmV0SW5mbygpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpPblZLX0VORChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQ0KLXsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCXsNCi0JCWlmIChiU2hpZnQpDQotCQl7DQotCQkJaWYgKGJDdHJsKQ0KLQkJCQlTZXRDYXJldChtX3BWVC0+R2V0RW5kV29yZFBsYWNlKCkpOw0KLQkJCWVsc2UNCi0JCQkJU2V0Q2FyZXQobV9wVlQtPkdldExpbmVFbmRQbGFjZShtX3dwQ2FyZXQpKTsNCi0NCi0JCQlpZiAobV9TZWxTdGF0ZS5Jc0V4aXN0KCkpDQotCQkJCW1fU2VsU3RhdGUuU2V0RW5kUG9zKG1fd3BDYXJldCk7DQotCQkJZWxzZQ0KLQkJCQltX1NlbFN0YXRlLlNldChtX3dwT2xkQ2FyZXQsIG1fd3BDYXJldCk7DQotDQotCQkJU2Nyb2xsVG9DYXJldCgpOw0KLQkJCUNQVlRfV29yZFJhbmdlIHdyKG1fd3BPbGRDYXJldCwgbV93cENhcmV0KTsNCi0JCQlSZWZyZXNoKFJQX09QVElPTkFMLCAmd3IpOw0KLQkJCVNldENhcmV0SW5mbygpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkNCi0JCQl7DQotCQkJCWlmIChtX1NlbFN0YXRlLkJlZ2luUG9zLldvcmRDbXAobV9TZWxTdGF0ZS5FbmRQb3MpPjApDQotCQkJCQlTZXRDYXJldChtX1NlbFN0YXRlLkJlZ2luUG9zKTsNCi0JCQkJZWxzZQ0KLQkJCQkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5FbmRQb3MpOw0KLQ0KLQkJCQlTZWxlY3ROb25lKCk7DQotCQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0JCQkJU2V0Q2FyZXRJbmZvKCk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCWlmIChiQ3RybCkNCi0JCQkJCVNldENhcmV0KG1fcFZULT5HZXRFbmRXb3JkUGxhY2UoKSk7DQotCQkJCWVsc2UNCi0JCQkJCVNldENhcmV0KG1fcFZULT5HZXRMaW5lRW5kUGxhY2UobV93cENhcmV0KSk7DQotCQkJCQkJDQotCQkJCVNjcm9sbFRvQ2FyZXQoKTsJCQkNCi0JCQkJU2V0Q2FyZXRPcmlnaW4oKTsNCi0JCQkJU2V0Q2FyZXRJbmZvKCk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldFRleHQoRlhfTFBDV1NUUiB0ZXh0LEZYX0lOVDMyIGNoYXJzZXQsDQotCQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsIEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KQ0KLXsNCi0JRW1wdHkoKTsNCi0JRG9JbnNlcnRUZXh0KENQVlRfV29yZFBsYWNlKDAsMCwtMSksIHRleHQsIGNoYXJzZXQsIHBTZWNQcm9wcywgcFdvcmRQcm9wcyk7DQotCWlmIChiUGFpbnQpIFBhaW50KCk7DQotCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQ0KLQkJbV9wT3ByTm90aWZ5LT5PblNldFRleHQobV93cENhcmV0LCBtX3dwT2xkQ2FyZXQpOw0KLQkvL2lmIChiQWRkVW5kbykNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6SW5zZXJ0V29yZChGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIGNoYXJzZXQsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcywgRlhfQk9PTCBiQWRkVW5kbywgRlhfQk9PTCBiUGFpbnQpDQotew0KLQlpZiAoSXNUZXh0T3ZlcmZsb3coKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSkNCi0Jew0KLQkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZShtX3dwQ2FyZXQpOw0KLQ0KLQkJU2V0Q2FyZXQobV9wVlQtPkluc2VydFdvcmQobV93cENhcmV0LHdvcmQsR2V0Q2hhclNldEZyb21Vbmljb2RlKHdvcmQsIGNoYXJzZXQpLHBXb3JkUHJvcHMpKTsNCi0JCW1fU2VsU3RhdGUuU2V0KG1fd3BDYXJldCxtX3dwQ2FyZXQpOw0KLQ0KLQkJaWYgKG1fd3BDYXJldCAhPSBtX3dwT2xkQ2FyZXQpDQotCQl7DQotCQkJaWYgKGJBZGRVbmRvICYmIG1fYkVuYWJsZVVuZG8pDQotCQkJew0KLQkJCQlBZGRFZGl0VW5kb0l0ZW0obmV3IENGWEVVX0luc2VydFdvcmQodGhpcyxtX3dwT2xkQ2FyZXQsbV93cENhcmV0LHdvcmQsY2hhcnNldCxwV29yZFByb3BzKSk7DQotCQkJfQ0KLQ0KLQkJCWlmIChiUGFpbnQpDQotCQkJCVBhaW50SW5zZXJ0VGV4dChtX3dwT2xkQ2FyZXQsIG1fd3BDYXJldCk7DQotDQotCQkJaWYgKG1fYk9wck5vdGlmeSAmJiBtX3BPcHJOb3RpZnkpDQotCQkJCW1fcE9wck5vdGlmeS0+T25JbnNlcnRXb3JkKG1fd3BDYXJldCwgbV93cE9sZENhcmV0KTsNCi0NCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpJbnNlcnRSZXR1cm4oY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsIA0KLQkJCQkJCQkgICBGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCkNCi17DQotCWlmIChJc1RleHRPdmVyZmxvdygpKSByZXR1cm4gRkFMU0U7DQotDQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKG1fd3BDYXJldCk7DQotCQlTZXRDYXJldChtX3BWVC0+SW5zZXJ0U2VjdGlvbihtX3dwQ2FyZXQscFNlY1Byb3BzLHBXb3JkUHJvcHMpKTsNCi0JCW1fU2VsU3RhdGUuU2V0KG1fd3BDYXJldCxtX3dwQ2FyZXQpOw0KLQ0KLQkJaWYgKG1fd3BDYXJldCAhPSBtX3dwT2xkQ2FyZXQpDQotCQl7DQotCQkJaWYgKGJBZGRVbmRvICYmIG1fYkVuYWJsZVVuZG8pDQotCQkJew0KLQkJCQlBZGRFZGl0VW5kb0l0ZW0obmV3IENGWEVVX0luc2VydFJldHVybih0aGlzLG1fd3BPbGRDYXJldCxtX3dwQ2FyZXQscFNlY1Byb3BzLHBXb3JkUHJvcHMpKTsNCi0JCQl9DQotDQotCQkJaWYgKGJQYWludCkNCi0JCQl7DQotCQkJCVJlYXJyYW5nZVBhcnQoQ1BWVF9Xb3JkUmFuZ2UobV93cE9sZENhcmV0LCBtX3dwQ2FyZXQpKTsNCi0JCQkJU2Nyb2xsVG9DYXJldCgpOw0KLQkJCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsIEdldFZpc2libGVXb3JkUmFuZ2UoKS5FbmRQb3MpOw0KLQkJCQlSZWZyZXNoKFJQX0FOQUxZU0UsICZ3cik7CQkNCi0JCQkJU2V0Q2FyZXRPcmlnaW4oKTsNCi0JCQkJU2V0Q2FyZXRJbmZvKCk7CQkJDQotCQkJfQ0KLQ0KLQkJCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQ0KLQkJCQltX3BPcHJOb3RpZnktPk9uSW5zZXJ0UmV0dXJuKG1fd3BDYXJldCwgbV93cE9sZENhcmV0KTsNCi0NCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0VkaXQ6OkJhY2tzcGFjZShGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAobV93cENhcmV0ID09IG1fcFZULT5HZXRCZWdpbldvcmRQbGFjZSgpKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUFZUX1NlY3Rpb24gc2VjdGlvbjsNCi0JCUNQVlRfV29yZCB3b3JkOw0KLQ0KLQkJaWYgKGJBZGRVbmRvKQ0KLQkJew0KLQkJCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQ0KLQkJCXsJCQkJDQotCQkJCXBJdGVyYXRvci0+U2V0QXQobV93cENhcmV0KTsNCi0JCQkJcEl0ZXJhdG9yLT5HZXRTZWN0aW9uKHNlY3Rpb24pOw0KLQkJCQlwSXRlcmF0b3ItPkdldFdvcmQod29yZCk7DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZShtX3dwQ2FyZXQpOw0KLQkJU2V0Q2FyZXQobV9wVlQtPkJhY2tTcGFjZVdvcmQobV93cENhcmV0KSk7DQotCQltX1NlbFN0YXRlLlNldChtX3dwQ2FyZXQsbV93cENhcmV0KTsNCi0NCi0JCWlmIChtX3dwQ2FyZXQgIT0gbV93cE9sZENhcmV0KQ0KLQkJew0KLQkJCWlmIChiQWRkVW5kbyAmJiBtX2JFbmFibGVVbmRvKQ0KLQkJCXsNCi0JCQkJaWYgKG1fd3BDYXJldC5TZWNDbXAobV93cE9sZENhcmV0KSAhPSAwKQkJCQ0KLQkJCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9CYWNrc3BhY2UodGhpcyxtX3dwT2xkQ2FyZXQsbV93cENhcmV0LHdvcmQuV29yZCx3b3JkLm5DaGFyc2V0LA0KLQkJCQkJCXNlY3Rpb24uU2VjUHJvcHMsc2VjdGlvbi5Xb3JkUHJvcHMpKTsNCi0JCQkJZWxzZQ0KLQkJCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9CYWNrc3BhY2UodGhpcyxtX3dwT2xkQ2FyZXQsbV93cENhcmV0LHdvcmQuV29yZCx3b3JkLm5DaGFyc2V0LA0KLQkJCQkJCXNlY3Rpb24uU2VjUHJvcHMsd29yZC5Xb3JkUHJvcHMpKTsNCi0JCQl9DQotDQotCQkJaWYgKGJQYWludCkNCi0JCQl7DQotCQkJCVJlYXJyYW5nZVBhcnQoQ1BWVF9Xb3JkUmFuZ2UobV93cENhcmV0LG1fd3BPbGRDYXJldCkpOw0KLQkJCQlTY3JvbGxUb0NhcmV0KCk7DQotDQotCQkJCUNQVlRfV29yZFJhbmdlIHdyOw0KLQkJCQlpZiAobV93cENhcmV0LlNlY0NtcChtX3dwT2xkQ2FyZXQpICE9MCkNCi0JCQkJCXdyID0gQ1BWVF9Xb3JkUmFuZ2UobV9wVlQtPkdldFByZXZXb3JkUGxhY2UobV93cENhcmV0KSxHZXRWaXNpYmxlV29yZFJhbmdlKCkuRW5kUG9zKTsJDQotCQkJCWVsc2UgaWYgKG1fd3BDYXJldC5MaW5lQ21wKG1fd3BPbGRDYXJldCkgIT0wKQ0KLQkJCQkJd3IgPSBDUFZUX1dvcmRSYW5nZShtX3BWVC0+R2V0TGluZUJlZ2luUGxhY2UobV93cENhcmV0KSxtX3BWVC0+R2V0U2VjdGlvbkVuZFBsYWNlKG1fd3BDYXJldCkpOw0KLQkJCQllbHNlDQotCQkJCQl3ciA9IENQVlRfV29yZFJhbmdlKG1fcFZULT5HZXRQcmV2V29yZFBsYWNlKG1fd3BDYXJldCksbV9wVlQtPkdldFNlY3Rpb25FbmRQbGFjZShtX3dwQ2FyZXQpKTsNCi0NCi0JCQkJUmVmcmVzaChSUF9BTkFMWVNFLCAmd3IpOw0KLQ0KLQkJCQlTZXRDYXJldE9yaWdpbigpOw0KLQkJCQlTZXRDYXJldEluZm8oKTsNCi0JCQl9DQotDQotCQkJaWYgKG1fYk9wck5vdGlmeSAmJiBtX3BPcHJOb3RpZnkpDQotCQkJCW1fcE9wck5vdGlmeS0+T25CYWNrU3BhY2UobV93cENhcmV0LCBtX3dwT2xkQ2FyZXQpOw0KLQ0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6RGVsZXRlKEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KQ0KLXsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCXsNCi0JCWlmIChtX3dwQ2FyZXQgPT0gbV9wVlQtPkdldEVuZFdvcmRQbGFjZSgpKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUFZUX1NlY3Rpb24gc2VjdGlvbjsNCi0JCUNQVlRfV29yZCB3b3JkOw0KLQ0KLQkJaWYgKGJBZGRVbmRvKQ0KLQkJew0KLQkJCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQ0KLQkJCXsJCQkJDQotCQkJCXBJdGVyYXRvci0+U2V0QXQobV9wVlQtPkdldE5leHRXb3JkUGxhY2UobV93cENhcmV0KSk7DQotCQkJCXBJdGVyYXRvci0+R2V0U2VjdGlvbihzZWN0aW9uKTsNCi0JCQkJcEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpOw0KLQkJCX0NCi0JCX0NCi0NCi0JCW1fcFZULT5VcGRhdGVXb3JkUGxhY2UobV93cENhcmV0KTsNCi0JCUZYX0JPT0wgYlNlY0VuZCA9IChtX3dwQ2FyZXQgPT0gbV9wVlQtPkdldFNlY3Rpb25FbmRQbGFjZShtX3dwQ2FyZXQpKTsNCi0NCi0JCVNldENhcmV0KG1fcFZULT5EZWxldGVXb3JkKG1fd3BDYXJldCkpOw0KLQkJbV9TZWxTdGF0ZS5TZXQobV93cENhcmV0LG1fd3BDYXJldCk7DQotDQotCQlpZiAoYkFkZFVuZG8gJiYgbV9iRW5hYmxlVW5kbykNCi0JCXsNCi0JCQlpZiAoYlNlY0VuZCkJCQ0KLQkJCQlBZGRFZGl0VW5kb0l0ZW0obmV3IENGWEVVX0RlbGV0ZSh0aGlzLG1fd3BPbGRDYXJldCxtX3dwQ2FyZXQsd29yZC5Xb3JkLHdvcmQubkNoYXJzZXQsDQotCQkJCQlzZWN0aW9uLlNlY1Byb3BzLHNlY3Rpb24uV29yZFByb3BzLGJTZWNFbmQpKTsNCi0JCQllbHNlDQotCQkJCUFkZEVkaXRVbmRvSXRlbShuZXcgQ0ZYRVVfRGVsZXRlKHRoaXMsbV93cE9sZENhcmV0LG1fd3BDYXJldCx3b3JkLldvcmQsd29yZC5uQ2hhcnNldCwNCi0JCQkJCXNlY3Rpb24uU2VjUHJvcHMsd29yZC5Xb3JkUHJvcHMsYlNlY0VuZCkpOw0KLQkJfQ0KLQkJDQotCQlpZiAoYlBhaW50KQ0KLQkJew0KLQkJCVJlYXJyYW5nZVBhcnQoQ1BWVF9Xb3JkUmFuZ2UobV93cE9sZENhcmV0LG1fd3BDYXJldCkpOw0KLQkJCVNjcm9sbFRvQ2FyZXQoKTsNCi0NCi0JCQlDUFZUX1dvcmRSYW5nZSB3cjsNCi0JCQlpZiAoYlNlY0VuZCkNCi0JCQkJd3IgPSBDUFZUX1dvcmRSYW5nZShtX3BWVC0+R2V0UHJldldvcmRQbGFjZShtX3dwT2xkQ2FyZXQpLEdldFZpc2libGVXb3JkUmFuZ2UoKS5FbmRQb3MpOw0KLQkJCWVsc2UgaWYgKG1fd3BDYXJldC5MaW5lQ21wKG1fd3BPbGRDYXJldCkgIT0wKQ0KLQkJCQl3ciA9IENQVlRfV29yZFJhbmdlKG1fcFZULT5HZXRMaW5lQmVnaW5QbGFjZShtX3dwQ2FyZXQpLG1fcFZULT5HZXRTZWN0aW9uRW5kUGxhY2UobV93cENhcmV0KSk7DQotCQkJZWxzZQ0KLQkJCQl3ciA9IENQVlRfV29yZFJhbmdlKG1fcFZULT5HZXRQcmV2V29yZFBsYWNlKG1fd3BPbGRDYXJldCksbV9wVlQtPkdldFNlY3Rpb25FbmRQbGFjZShtX3dwQ2FyZXQpKTsJCQkNCi0NCi0JCQlSZWZyZXNoKFJQX0FOQUxZU0UsICZ3cik7DQotCQkJDQotCQkJU2V0Q2FyZXRPcmlnaW4oKTsNCi0JCQlTZXRDYXJldEluZm8oKTsNCi0JCX0NCi0NCi0JCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQ0KLQkJCW1fcE9wck5vdGlmeS0+T25EZWxldGUobV93cENhcmV0LCBtX3dwT2xkQ2FyZXQpOw0KLQ0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNGWF9FZGl0OjpFbXB0eSgpDQotew0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSkNCi0Jew0KLQkJbV9wVlQtPkRlbGV0ZVdvcmRzKEdldFdob2xlV29yZFJhbmdlKCkpOw0KLQkJU2V0Q2FyZXQobV9wVlQtPkdldEJlZ2luV29yZFBsYWNlKCkpOw0KLQ0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpDbGVhcihGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAobV9TZWxTdGF0ZS5Jc0V4aXN0KCkpDQotCQl7DQotCQkJQ1BWVF9Xb3JkUmFuZ2UgcmFuZ2UgPSBtX1NlbFN0YXRlLkNvbnZlcnRUb1dvcmRSYW5nZSgpOw0KLQ0KLQkJCWlmIChiQWRkVW5kbyAmJiBtX2JFbmFibGVVbmRvKQ0KLQkJCXsNCi0JCQkJaWYgKG1fcFZULT5Jc1JpY2hUZXh0KCkpDQotCQkJCXsNCi0JCQkJCUJlZ2luR3JvdXBVbmRvKEwiIik7DQotDQotCQkJCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkNCi0JCQkJCXsNCi0JCQkJCQlwSXRlcmF0b3ItPlNldEF0KHJhbmdlLkVuZFBvcyk7DQotDQotCQkJCQkJQ1BWVF9Xb3JkIHdvcmRpbmZvOwkNCi0JCQkJCQlDUFZUX1NlY3Rpb24gc2VjaW5mbzsJCQkJCQkNCi0JCQkJCQlkbw0KLQkJCQkJCXsJCQkJCQkJDQotCQkJCQkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOw0KLQkJCQkJCQlpZiAocGxhY2UuV29yZENtcChyYW5nZS5CZWdpblBvcykgPD0gMClicmVhazsNCi0NCi0JCQkJCQkJQ1BWVF9Xb3JkUGxhY2Ugb2xkcGxhY2UgPSBtX3BWVC0+R2V0UHJldldvcmRQbGFjZShwbGFjZSk7CQkJCQkJCQ0KLQ0KLQkJCQkJCQlpZiAob2xkcGxhY2UuU2VjQ21wKHBsYWNlKSAhPSAwKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRTZWN0aW9uKHNlY2luZm8pKQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCUFkZEVkaXRVbmRvSXRlbShuZXcgQ0ZYRVVfQ2xlYXJSaWNoKHRoaXMsb2xkcGxhY2UscGxhY2UscmFuZ2Usd29yZGluZm8uV29yZCwNCi0JCQkJCQkJCQkJd29yZGluZm8ubkNoYXJzZXQsc2VjaW5mby5TZWNQcm9wcyxzZWNpbmZvLldvcmRQcm9wcykpOw0KLQkJCQkJCQkJfQ0KLQkJCQkJCQl9DQotCQkJCQkJCWVsc2UNCi0JCQkJCQkJew0KLQkJCQkJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkaW5mbykpDQotCQkJCQkJCQl7CQkJCQkJCQkJDQotCQkJCQkJCQkJb2xkcGxhY2UgPSBtX3BWVC0+QWp1c3RMaW5lSGVhZGVyKG9sZHBsYWNlLFRSVUUpOw0KLQkJCQkJCQkJCXBsYWNlID0gbV9wVlQtPkFqdXN0TGluZUhlYWRlcihwbGFjZSxUUlVFKTsNCi0NCi0JCQkJCQkJCQlBZGRFZGl0VW5kb0l0ZW0obmV3IENGWEVVX0NsZWFyUmljaCh0aGlzLG9sZHBsYWNlLHBsYWNlLHJhbmdlLHdvcmRpbmZvLldvcmQsDQotCQkJCQkJCQkJCXdvcmRpbmZvLm5DaGFyc2V0LHNlY2luZm8uU2VjUHJvcHMsd29yZGluZm8uV29yZFByb3BzKSk7DQotCQkJCQkJCQl9DQotCQkJCQkJCX0NCi0JCQkJCQl9d2hpbGUgKHBJdGVyYXRvci0+UHJldldvcmQoKSk7DQotCQkJCQl9DQotCQkJCQlFbmRHcm91cFVuZG8oKTsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsJCQkJCQ0KLQkJCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9DbGVhcih0aGlzLHJhbmdlLEdldFNlbFRleHQoKSkpOwkJCQkJDQotCQkJCX0NCi0JCQl9DQotDQotCQkJU2VsZWN0Tm9uZSgpOwkJCQ0KLQkJCVNldENhcmV0KG1fcFZULT5EZWxldGVXb3JkcyhyYW5nZSkpOwkNCi0JCQltX1NlbFN0YXRlLlNldChtX3dwQ2FyZXQsbV93cENhcmV0KTsNCi0NCi0JCQlpZiAoYlBhaW50KQ0KLQkJCXsNCi0JCQkJUmVhcnJhbmdlUGFydChyYW5nZSk7CQ0KLQkJCQlTY3JvbGxUb0NhcmV0KCk7DQotDQotCQkJCUNQVlRfV29yZFJhbmdlIHdyKG1fd3BPbGRDYXJldCwgR2V0VmlzaWJsZVdvcmRSYW5nZSgpLkVuZFBvcyk7DQotCQkJCVJlZnJlc2goUlBfQU5BTFlTRSwgJndyKTsNCi0JCQkJDQotCQkJCVNldENhcmV0T3JpZ2luKCk7DQotCQkJCVNldENhcmV0SW5mbygpOw0KLQkJCX0NCi0NCi0JCQlpZiAobV9iT3ByTm90aWZ5ICYmIG1fcE9wck5vdGlmeSkNCi0JCQkJbV9wT3ByTm90aWZ5LT5PbkNsZWFyKG1fd3BDYXJldCwgbV93cE9sZENhcmV0KTsNCi0NCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0VkaXQ6Okluc2VydFRleHQoRlhfTFBDV1NUUiB0ZXh0LCBGWF9JTlQzMiBjaGFyc2V0LA0KLQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzLCBGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCkNCi17DQotCWlmIChJc1RleHRPdmVyZmxvdygpKSByZXR1cm4gRkFMU0U7DQotDQotCW1fcFZULT5VcGRhdGVXb3JkUGxhY2UobV93cENhcmV0KTsNCi0JU2V0Q2FyZXQoRG9JbnNlcnRUZXh0KG1fd3BDYXJldCwgdGV4dCwgY2hhcnNldCwgcFNlY1Byb3BzLCBwV29yZFByb3BzKSk7DQotCW1fU2VsU3RhdGUuU2V0KG1fd3BDYXJldCxtX3dwQ2FyZXQpOw0KLQ0KLQlpZiAobV93cENhcmV0ICE9IG1fd3BPbGRDYXJldCkNCi0Jew0KLQkJaWYgKGJBZGRVbmRvICYmIG1fYkVuYWJsZVVuZG8pDQotCQl7DQotCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9JbnNlcnRUZXh0KHRoaXMsbV93cE9sZENhcmV0LG1fd3BDYXJldCx0ZXh0LGNoYXJzZXQscFNlY1Byb3BzLHBXb3JkUHJvcHMpKTsNCi0JCX0NCi0NCi0JCWlmIChiUGFpbnQpDQotCQkJUGFpbnRJbnNlcnRUZXh0KG1fd3BPbGRDYXJldCwgbV93cENhcmV0KTsNCi0NCi0JCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQ0KLQkJCW1fcE9wck5vdGlmeS0+T25JbnNlcnRUZXh0KG1fd3BDYXJldCwgbV93cE9sZENhcmV0KTsNCi0NCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6UGFpbnRJbnNlcnRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BOZXcpDQotew0KLQlpZiAobV9wVlQtPklzVmFsaWQoKSkNCi0Jew0KLQkJUmVhcnJhbmdlUGFydChDUFZUX1dvcmRSYW5nZSh3cE9sZCx3cE5ldykpOw0KLQkJU2Nyb2xsVG9DYXJldCgpOw0KLQkJDQotCQlDUFZUX1dvcmRSYW5nZSB3cjsNCi0JCWlmIChtX3dwQ2FyZXQuTGluZUNtcCh3cE9sZCkgIT0wKQ0KLQkJCXdyID0gQ1BWVF9Xb3JkUmFuZ2UobV9wVlQtPkdldExpbmVCZWdpblBsYWNlKHdwT2xkKSxtX3BWVC0+R2V0U2VjdGlvbkVuZFBsYWNlKHdwTmV3KSk7CQ0KLQkJZWxzZQ0KLQkJCXdyID0gQ1BWVF9Xb3JkUmFuZ2Uod3BPbGQsbV9wVlQtPkdldFNlY3Rpb25FbmRQbGFjZSh3cE5ldykpOwkNCi0JCVJlZnJlc2goUlBfQU5BTFlTRSwgJndyKTsNCi0JCVNldENhcmV0T3JpZ2luKCk7DQotCQlTZXRDYXJldEluZm8oKTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIENGWF9FZGl0OjpSZWRvKCkNCi17DQotCWlmIChtX2JFbmFibGVVbmRvKQ0KLQl7DQotCQlpZiAobV9VbmRvLkNhblJlZG8oKSkNCi0JCXsNCi0JCQltX1VuZG8uUmVkbygpOw0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDRlhfRWRpdDo6VW5kbygpDQotew0KLQlpZiAobV9iRW5hYmxlVW5kbykNCi0Jew0KLQkJaWYgKG1fVW5kby5DYW5VbmRvKCkpDQotCQl7DQotCQkJbV9VbmRvLlVuZG8oKTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OlNldENhcmV0T3JpZ2luKCkNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkNCi0JCXsNCi0JCQlwSXRlcmF0b3ItPlNldEF0KG1fd3BDYXJldCk7DQotCQkJQ1BWVF9Xb3JkIHdvcmQ7DQotCQkJQ1BWVF9MaW5lIGxpbmU7DQotCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQl7DQotCQkJCW1fcHRDYXJldC54ID0gd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoOw0KLQkJCQltX3B0Q2FyZXQueSA9IHdvcmQucHRXb3JkLnk7DQotCQkJfQ0KLQkJCWVsc2UgaWYgKHBJdGVyYXRvci0+R2V0TGluZShsaW5lKSkNCi0JCQl7CQkJCQ0KLQkJCQltX3B0Q2FyZXQueCA9IGxpbmUucHRMaW5lLng7DQotCQkJCW1fcHRDYXJldC55ID0gbGluZS5wdExpbmUueTsNCi0JCQl9DQotCQl9CQkJCQ0KLQl9CQ0KLX0NCi0NCi1GWF9JTlQzMiBDRlhfRWRpdDo6V29yZFBsYWNlVG9Xb3JkSW5kZXgoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QNCi17DQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQkJcmV0dXJuIG1fcFZULT5Xb3JkUGxhY2VUb1dvcmRJbmRleChwbGFjZSk7DQotDQotCXJldHVybiAtMTsNCi19DQotDQotQ1BWVF9Xb3JkUGxhY2UgQ0ZYX0VkaXQ6OldvcmRJbmRleFRvV29yZFBsYWNlKEZYX0lOVDMyIGluZGV4KSBjb25zdA0KLXsNCi0JaWYgKG1fcFZULT5Jc1ZhbGlkKCkpDQotCQlyZXR1cm4gbV9wVlQtPldvcmRJbmRleFRvV29yZFBsYWNlKGluZGV4KTsNCi0NCi0JcmV0dXJuIENQVlRfV29yZFBsYWNlKCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX0VkaXQ6OklzVGV4dEZ1bGwoKSBjb25zdA0KLXsNCi0JRlhfSU5UMzIgblRvdGFsV29yZHMgPSBtX3BWVC0+R2V0VG90YWxXb3JkcygpOw0KLQlGWF9JTlQzMiBuTGltaXRDaGFyID0gbV9wVlQtPkdldExpbWl0Q2hhcigpOw0KLQlGWF9JTlQzMiBuQ2hhckFycmF5ID0gbV9wVlQtPkdldENoYXJBcnJheSgpOw0KLQ0KLQlyZXR1cm4gSXNUZXh0T3ZlcmZsb3coKSB8fCAobkxpbWl0Q2hhcj4wICYmIG5Ub3RhbFdvcmRzID49IG5MaW1pdENoYXIpDQotCQl8fCAobkNoYXJBcnJheT4wICYmIG5Ub3RhbFdvcmRzID49IG5DaGFyQXJyYXkpOw0KLX0NCi0NCi1GWF9CT09MCUNGWF9FZGl0OjpJc1RleHRPdmVyZmxvdygpIGNvbnN0DQotew0KLQlpZiAoIW1fYkVuYWJsZVNjcm9sbCAmJiAhbV9iRW5hYmxlT3ZlcmZsb3cpDQotCXsNCi0JCUNQREZfUmVjdCByY1BsYXRlID0gbV9wVlQtPkdldFBsYXRlUmVjdCgpOw0KLQkJQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOw0KLQ0KLQkJaWYgKG1fcFZULT5Jc011bHRpTGluZSgpICYmIEdldFRvdGFsTGluZXMoKSA+IDEpDQotCQl7DQotCQkJaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihyY0NvbnRlbnQuSGVpZ2h0KCkscmNQbGF0ZS5IZWlnaHQoKSkpIHJldHVybiBUUlVFOw0KLQkJfQ0KLQ0KLQkJaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihyY0NvbnRlbnQuV2lkdGgoKSxyY1BsYXRlLldpZHRoKCkpKSByZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUNQVlRfV29yZFBsYWNlIENGWF9FZGl0OjpHZXRMaW5lQmVnaW5QbGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcFZULT5HZXRMaW5lQmVnaW5QbGFjZShwbGFjZSk7DQotfQ0KLQ0KLUNQVlRfV29yZFBsYWNlIENGWF9FZGl0OjpHZXRMaW5lRW5kUGxhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QNCi17DQotCXJldHVybiBtX3BWVC0+R2V0TGluZUVuZFBsYWNlKHBsYWNlKTsNCi19DQotDQotQ1BWVF9Xb3JkUGxhY2UgQ0ZYX0VkaXQ6OkdldFNlY3Rpb25CZWdpblBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wVlQtPkdldFNlY3Rpb25CZWdpblBsYWNlKHBsYWNlKTsNCi19DQotDQotQ1BWVF9Xb3JkUGxhY2UgQ0ZYX0VkaXQ6OkdldFNlY3Rpb25FbmRQbGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcFZULT5HZXRTZWN0aW9uRW5kUGxhY2UocGxhY2UpOw0KLX0NCi0NCi1GWF9CT09MCUNGWF9FZGl0OjpDYW5VbmRvKCkgY29uc3QNCi17DQotCWlmIChtX2JFbmFibGVVbmRvKQ0KLQl7DQotCQlyZXR1cm4gbV9VbmRvLkNhblVuZG8oKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX0VkaXQ6OkNhblJlZG8oKSBjb25zdA0KLXsNCi0JaWYgKG1fYkVuYWJsZVVuZG8pDQotCXsNCi0JCXJldHVybiBtX1VuZG8uQ2FuUmVkbygpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDRlhfRWRpdDo6SXNNb2RpZmllZCgpIGNvbnN0DQotew0KLQlpZiAobV9iRW5hYmxlVW5kbykNCi0Jew0KLQkJcmV0dXJuIG1fVW5kby5Jc01vZGlmaWVkKCk7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpFbmFibGVSZWZyZXNoKEZYX0JPT0wgYlJlZnJlc2gpDQotew0KLQltX2JFbmFibGVSZWZyZXNoID0gYlJlZnJlc2g7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OkVuYWJsZVVuZG8oRlhfQk9PTCBiVW5kbykNCi17DQotCXRoaXMtPm1fYkVuYWJsZVVuZG8gPSBiVW5kbzsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6RW5hYmxlTm90aWZ5KEZYX0JPT0wgYk5vdGlmeSkNCi17DQotCXRoaXMtPm1fYk5vdGlmeSA9IGJOb3RpZnk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OkVuYWJsZU9wck5vdGlmeShGWF9CT09MIGJOb3RpZnkpDQotew0KLQl0aGlzLT5tX2JPcHJOb3RpZnkgPSBiTm90aWZ5Ow0KLX0NCi0NCi1GWF9GTE9BVCBDRlhfRWRpdDo6R2V0TGluZVRvcChjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UpIGNvbnN0DQotew0KLQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQ0KLQl7DQotCQlDUFZUX1dvcmRQbGFjZSB3cE9sZCA9IHBJdGVyYXRvci0+R2V0QXQoKTsNCi0NCi0JCXBJdGVyYXRvci0+U2V0QXQocGxhY2UpOw0KLQkJQ1BWVF9MaW5lIGxpbmU7DQotCQlwSXRlcmF0b3ItPkdldExpbmUobGluZSk7DQotDQotCQlwSXRlcmF0b3ItPlNldEF0KHdwT2xkKTsNCi0NCi0JCXJldHVybiBsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZUFzY2VudDsNCi0JfQ0KLQ0KLQlyZXR1cm4gMC4wZjsNCi19DQotDQotRlhfRkxPQVQgQ0ZYX0VkaXQ6OkdldExpbmVCb3R0b20oY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlKSBjb25zdA0KLXsNCi0JaWYgKElQREZfVmFyaWFibGVUZXh0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJQ1BWVF9Xb3JkUGxhY2Ugd3BPbGQgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotDQotCQlwSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsNCi0JCUNQVlRfTGluZSBsaW5lOw0KLQkJcEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmUpOw0KLQ0KLQkJcEl0ZXJhdG9yLT5TZXRBdCh3cE9sZCk7DQotDQotCQlyZXR1cm4gbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVEZXNjZW50Ow0KLQl9DQotDQotCXJldHVybiAwLjBmOw0KLX0NCi0NCi1DUFZUX1dvcmRQbGFjZSBDRlhfRWRpdDo6RG9JbnNlcnRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgRlhfTFBDV1NUUiB0ZXh0LCBGWF9JTlQzMiBjaGFyc2V0LCANCi0JCQkJCQkJCQkgIGNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcykNCi17DQotCUNQVlRfV29yZFBsYWNlIHdwID0gcGxhY2U7DQotDQotCWlmIChtX3BWVC0+SXNWYWxpZCgpKQ0KLQl7DQotCQlDRlhfV2lkZVN0cmluZyBzVGV4dCA9IHRleHQ7DQotDQotCQlmb3IgKEZYX0lOVDMyIGkgPSAwLCBzeiA9IHNUZXh0LkdldExlbmd0aCgpOyBpIDwgc3o7IGkrKykNCi0JCXsNCi0JCQlGWF9XT1JEIHdvcmQgPSBzVGV4dFtpXTsNCi0JCQlzd2l0Y2ggKHdvcmQpDQotCQkJew0KLQkJCWNhc2UgMHgwRDoNCi0JCQkJd3AgPSBtX3BWVC0+SW5zZXJ0U2VjdGlvbih3cCxwU2VjUHJvcHMscFdvcmRQcm9wcyk7DQotCQkJCWlmIChzVGV4dFtpKzFdID09IDB4MEEpDQotCQkJCQlpKys7DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgMHgwQToJDQotCQkJCXdwID0gbV9wVlQtPkluc2VydFNlY3Rpb24od3AscFNlY1Byb3BzLHBXb3JkUHJvcHMpOw0KLQkJCQlpZiAoc1RleHRbaSsxXSA9PSAweDBEKQ0KLQkJCQkJaSsrOw0KLQkJCQlicmVhazsNCi0JCQljYXNlIDB4MDk6DQotCQkJCXdvcmQgPSAweDIwOw0KLQkJCWRlZmF1bHQ6DQotCQkJCXdwID0gbV9wVlQtPkluc2VydFdvcmQod3Asd29yZCxHZXRDaGFyU2V0RnJvbVVuaWNvZGUod29yZCwgY2hhcnNldCkscFdvcmRQcm9wcyk7DQotCQkJCWJyZWFrOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gd3A7DQotfQ0KLQ0KLUZYX0lOVDMyIENGWF9FZGl0OjpHZXRDaGFyU2V0RnJvbVVuaWNvZGUoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuT2xkQ2hhcnNldCkNCi17DQotCWlmIChJRlhfRWRpdF9Gb250TWFwKiBwRm9udE1hcCA9IHRoaXMtPkdldEZvbnRNYXAoKSkNCi0JCXJldHVybiBwRm9udE1hcC0+Q2hhclNldEZyb21Vbmljb2RlKHdvcmQsIG5PbGRDaGFyc2V0KTsNCi0JZWxzZQ0KLQkJcmV0dXJuIG5PbGRDaGFyc2V0Ow0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpCZWdpbkdyb3VwVW5kbyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RpdGxlKQ0KLXsNCi0JQVNTRVJUKG1fcEdyb3VwVW5kb0l0ZW0gPT0gTlVMTCk7DQotDQotCW1fcEdyb3VwVW5kb0l0ZW0gPSBuZXcgQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbShzVGl0bGUpOw0KLX0NCi0NCi12b2lkIENGWF9FZGl0OjpFbmRHcm91cFVuZG8oKQ0KLXsNCi0JQVNTRVJUKG1fcEdyb3VwVW5kb0l0ZW0gIT0gTlVMTCk7DQotDQotCW1fcEdyb3VwVW5kb0l0ZW0tPlVwZGF0ZUl0ZW1zKCk7DQotCW1fVW5kby5BZGRJdGVtKG1fcEdyb3VwVW5kb0l0ZW0pOw0KLQlpZiAobV9iT3ByTm90aWZ5ICYmIG1fcE9wck5vdGlmeSkNCi0JCW1fcE9wck5vdGlmeS0+T25BZGRVbmRvKG1fcEdyb3VwVW5kb0l0ZW0pOw0KLQltX3BHcm91cFVuZG9JdGVtID0gTlVMTDsNCi19DQotDQotdm9pZCBDRlhfRWRpdDo6QWRkRWRpdFVuZG9JdGVtKENGWF9FZGl0X1VuZG9JdGVtKiBwRWRpdFVuZG9JdGVtKQ0KLXsNCi0JaWYgKG1fcEdyb3VwVW5kb0l0ZW0pDQotCQltX3BHcm91cFVuZG9JdGVtLT5BZGRVbmRvSXRlbShwRWRpdFVuZG9JdGVtKTsNCi0JZWxzZQ0KLQl7DQotCQltX1VuZG8uQWRkSXRlbShwRWRpdFVuZG9JdGVtKTsNCi0JCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQ0KLQkJCW1fcE9wck5vdGlmeS0+T25BZGRVbmRvKHBFZGl0VW5kb0l0ZW0pOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0VkaXQ6OkFkZFVuZG9JdGVtKElGWF9FZGl0X1VuZG9JdGVtKiBwVW5kb0l0ZW0pDQotew0KLQltX1VuZG8uQWRkSXRlbShwVW5kb0l0ZW0pOw0KLQlpZiAobV9iT3ByTm90aWZ5ICYmIG1fcE9wck5vdGlmeSkNCi0JCW1fcE9wck5vdGlmeS0+T25BZGRVbmRvKHBVbmRvSXRlbSk7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4ZWRpdC9meGV0X3N0dWIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4ZWRpdC9meGV0X2VkaXQuaCIKKworI2RlZmluZSBGWF9FRElUX1VORE9fTUFYSVRFTQkJCQkxMDAwMAorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X0l0ZXJhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0ZYX0VkaXRfSXRlcmF0b3I6OkNGWF9FZGl0X0l0ZXJhdG9yKENGWF9FZGl0ICogcEVkaXQsSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwVlRJdGVyYXRvcikgOiAKKwltX3BFZGl0KHBFZGl0KSwKKwltX3BWVEl0ZXJhdG9yKHBWVEl0ZXJhdG9yKQoreworfQorCitDRlhfRWRpdF9JdGVyYXRvcjo6fkNGWF9FZGl0X0l0ZXJhdG9yKCkKK3sKK30KKworRlhfQk9PTAlDRlhfRWRpdF9JdGVyYXRvcjo6TmV4dFdvcmQoKQoreworCUFTU0VSVChtX3BWVEl0ZXJhdG9yICE9IE5VTEwpOworCQorCXJldHVybiBtX3BWVEl0ZXJhdG9yLT5OZXh0V29yZCgpOworfQorCitGWF9CT09MIENGWF9FZGl0X0l0ZXJhdG9yOjpOZXh0TGluZSgpCit7CisJQVNTRVJUKG1fcFZUSXRlcmF0b3IgIT0gTlVMTCk7CisKKwlyZXR1cm4gbV9wVlRJdGVyYXRvci0+TmV4dExpbmUoKTsKK30KKworRlhfQk9PTCBDRlhfRWRpdF9JdGVyYXRvcjo6TmV4dFNlY3Rpb24oKQoreworCUFTU0VSVChtX3BWVEl0ZXJhdG9yICE9IE5VTEwpOworCisJcmV0dXJuIG1fcFZUSXRlcmF0b3ItPk5leHRTZWN0aW9uKCk7Cit9CisKK0ZYX0JPT0wJQ0ZYX0VkaXRfSXRlcmF0b3I6OlByZXZXb3JkKCkKK3sKKwlBU1NFUlQobV9wVlRJdGVyYXRvciAhPSBOVUxMKTsKKwkKKwlyZXR1cm4gbV9wVlRJdGVyYXRvci0+UHJldldvcmQoKTsKK30KKworRlhfQk9PTAlDRlhfRWRpdF9JdGVyYXRvcjo6UHJldkxpbmUoKQoreworCUFTU0VSVChtX3BWVEl0ZXJhdG9yICE9IE5VTEwpOworCisJcmV0dXJuIG1fcFZUSXRlcmF0b3ItPlByZXZMaW5lKCk7Cit9CisKK0ZYX0JPT0wJQ0ZYX0VkaXRfSXRlcmF0b3I6OlByZXZTZWN0aW9uKCkKK3sKKwlBU1NFUlQobV9wVlRJdGVyYXRvciAhPSBOVUxMKTsKKworCXJldHVybiBtX3BWVEl0ZXJhdG9yLT5QcmV2U2VjdGlvbigpOworfQorCitGWF9CT09MIENGWF9FZGl0X0l0ZXJhdG9yOjpHZXRXb3JkKENQVlRfV29yZCAmIHdvcmQpIGNvbnN0Cit7CisJQVNTRVJUKG1fcEVkaXQgIT0gTlVMTCk7CisJQVNTRVJUKG1fcFZUSXRlcmF0b3IgIT0gTlVMTCk7CisKKwlpZiAobV9wVlRJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwl7CisJCXdvcmQucHRXb3JkID0gbV9wRWRpdC0+VlRUb0VkaXQod29yZC5wdFdvcmQpOworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXRfSXRlcmF0b3I6OkdldExpbmUoQ1BWVF9MaW5lICYgbGluZSkgY29uc3QKK3sKKwlBU1NFUlQobV9wRWRpdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wVlRJdGVyYXRvciAhPSBOVUxMKTsKKworCWlmIChtX3BWVEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmUpKQorCXsJCQorCQlsaW5lLnB0TGluZSA9IG1fcEVkaXQtPlZUVG9FZGl0KGxpbmUucHRMaW5lKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENGWF9FZGl0X0l0ZXJhdG9yOjpHZXRTZWN0aW9uKENQVlRfU2VjdGlvbiAmIHNlY3Rpb24pIGNvbnN0Cit7CisJQVNTRVJUKG1fcEVkaXQgIT0gTlVMTCk7CisJQVNTRVJUKG1fcFZUSXRlcmF0b3IgIT0gTlVMTCk7CisKKwlpZiAobV9wVlRJdGVyYXRvci0+R2V0U2VjdGlvbihzZWN0aW9uKSkKKwl7CisJCXNlY3Rpb24ucmNTZWN0aW9uID0gbV9wRWRpdC0+VlRUb0VkaXQoc2VjdGlvbi5yY1NlY3Rpb24pOworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfSXRlcmF0b3I6OlNldEF0KEZYX0lOVDMyIG5Xb3JkSW5kZXgpCit7CisJQVNTRVJUKG1fcFZUSXRlcmF0b3IgIT0gTlVMTCk7CisKKwltX3BWVEl0ZXJhdG9yLT5TZXRBdChuV29yZEluZGV4KTsKK30KKwordm9pZCBDRlhfRWRpdF9JdGVyYXRvcjo6U2V0QXQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkKK3sKKwlBU1NFUlQobV9wVlRJdGVyYXRvciAhPSBOVUxMKTsKKworCW1fcFZUSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsKK30KKworY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBDRlhfRWRpdF9JdGVyYXRvcjo6R2V0QXQoKSBjb25zdAoreworCUFTU0VSVChtX3BWVEl0ZXJhdG9yICE9IE5VTEwpOworCisJcmV0dXJuIG1fcFZUSXRlcmF0b3ItPkdldEF0KCk7Cit9CisKK0lGWF9FZGl0KiBDRlhfRWRpdF9JdGVyYXRvcjo6R2V0RWRpdCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fcEVkaXQ7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdF9Qcm92aWRlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NGWF9FZGl0X1Byb3ZpZGVyOjpDRlhfRWRpdF9Qcm92aWRlcihJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApIDogbV9wRm9udE1hcChwRm9udE1hcCkKK3sKKwlBU1NFUlQobV9wRm9udE1hcCAhPSBOVUxMKTsKK30KKworQ0ZYX0VkaXRfUHJvdmlkZXI6On5DRlhfRWRpdF9Qcm92aWRlcigpCit7Cit9CisKK0lGWF9FZGl0X0ZvbnRNYXAqIENGWF9FZGl0X1Byb3ZpZGVyOjpHZXRGb250TWFwKCkKK3sKKwlyZXR1cm4gbV9wRm9udE1hcDsKK30KKworRlhfSU5UMzIgQ0ZYX0VkaXRfUHJvdmlkZXI6OkdldENoYXJXaWR0aChGWF9JTlQzMiBuRm9udEluZGV4LCBGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIG5Xb3JkU3R5bGUpCit7CisJaWYgKENQREZfRm9udCogcFBERkZvbnQgPSBtX3BGb250TWFwLT5HZXRQREZGb250KG5Gb250SW5kZXgpKQorCXsKKwkJRlhfRFdPUkQgY2hhcmNvZGUgPSB3b3JkOworCisJCWlmIChwUERGRm9udC0+SXNVbmljb2RlQ29tcGF0aWJsZSgpKQkJCisJCQljaGFyY29kZSA9IHBQREZGb250LT5DaGFyQ29kZUZyb21Vbmljb2RlKHdvcmQpOwkKKwkJZWxzZQorCQkJY2hhcmNvZGUgPSBtX3BGb250TWFwLT5DaGFyQ29kZUZyb21Vbmljb2RlKG5Gb250SW5kZXgsIHdvcmQpOworCisJCWlmIChjaGFyY29kZSAhPSAtMSkJCQkKKwkJCXJldHVybiBwUERGRm9udC0+R2V0Q2hhcldpZHRoRihjaGFyY29kZSk7CisJfQorCisJcmV0dXJuIDA7Cit9CisKK0ZYX0lOVDMyIENGWF9FZGl0X1Byb3ZpZGVyOjpHZXRUeXBlQXNjZW50KEZYX0lOVDMyIG5Gb250SW5kZXgpCit7CisJaWYgKENQREZfRm9udCogcFBERkZvbnQgPSBtX3BGb250TWFwLT5HZXRQREZGb250KG5Gb250SW5kZXgpKQorCQlyZXR1cm4gcFBERkZvbnQtPkdldFR5cGVBc2NlbnQoKTsKKworCXJldHVybiAwOworfQorCitGWF9JTlQzMiBDRlhfRWRpdF9Qcm92aWRlcjo6R2V0VHlwZURlc2NlbnQoRlhfSU5UMzIgbkZvbnRJbmRleCkKK3sKKwlpZiAoQ1BERl9Gb250KiBwUERGRm9udCA9IG1fcEZvbnRNYXAtPkdldFBERkZvbnQobkZvbnRJbmRleCkpCisJCXJldHVybiBwUERGRm9udC0+R2V0VHlwZURlc2NlbnQoKTsKKworCXJldHVybiAwOworfQorCitGWF9JTlQzMiBDRlhfRWRpdF9Qcm92aWRlcjo6R2V0V29yZEZvbnRJbmRleChGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIGNoYXJzZXQsIEZYX0lOVDMyIG5Gb250SW5kZXgpCit7CisJcmV0dXJuIG1fcEZvbnRNYXAtPkdldFdvcmRGb250SW5kZXgod29yZCxjaGFyc2V0LG5Gb250SW5kZXgpOworfQorCitGWF9JTlQzMiBDRlhfRWRpdF9Qcm92aWRlcjo6R2V0RGVmYXVsdEZvbnRJbmRleCgpCit7CisJcmV0dXJuIDA7Cit9CisKK0ZYX0JPT0wJQ0ZYX0VkaXRfUHJvdmlkZXI6OklzTGF0aW5Xb3JkKEZYX1dPUkQgd29yZCkKK3sKKwlyZXR1cm4gRlhfRURJVF9JU0xBVElOV09SRCh3b3JkKTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X1JlZnJlc2ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NGWF9FZGl0X1JlZnJlc2g6OkNGWF9FZGl0X1JlZnJlc2goKQoreworfQorCitDRlhfRWRpdF9SZWZyZXNoOjp+Q0ZYX0VkaXRfUmVmcmVzaCgpCit7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfUmVmcmVzaDo6QmVnaW5SZWZyZXNoKCkKK3sKKwltX1JlZnJlc2hSZWN0cy5FbXB0eSgpOworCW1fT2xkTGluZVJlY3RzID0gbV9OZXdMaW5lUmVjdHM7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfUmVmcmVzaDo6UHVzaChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIGxpbmVyYW5nZSxjb25zdCBDUERGX1JlY3QgJiByZWN0KQoreworCW1fTmV3TGluZVJlY3RzLkFkZChsaW5lcmFuZ2UscmVjdCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfUmVmcmVzaDo6Tm9BbmFseXNlKCkKK3sKKwl7CisJCWZvciAoRlhfSU5UMzIgaSA9IDAsIHN6ID0gbV9PbGRMaW5lUmVjdHMuR2V0U2l6ZSgpOyBpIDwgc3o7IGkrKykKKwkJCWlmIChDRlhfRWRpdF9MaW5lUmVjdCAqIHBPbGRSZWN0ID0gbV9PbGRMaW5lUmVjdHMuR2V0QXQoaSkpCisJCQkJbV9SZWZyZXNoUmVjdHMuQWRkKHBPbGRSZWN0LT5tX3JjTGluZSk7CisJfQorCisJeworCQlmb3IgKEZYX0lOVDMyIGkgPSAwLCBzeiA9IG1fTmV3TGluZVJlY3RzLkdldFNpemUoKTsgaSA8IHN6OyBpKyspCisJCQlpZiAoQ0ZYX0VkaXRfTGluZVJlY3QgKiBwTmV3UmVjdCA9IG1fTmV3TGluZVJlY3RzLkdldEF0KGkpKQorCQkJCW1fUmVmcmVzaFJlY3RzLkFkZChwTmV3UmVjdC0+bV9yY0xpbmUpOworCX0KK30KKwordm9pZCBDRlhfRWRpdF9SZWZyZXNoOjpBbmFseXNlKEZYX0lOVDMyIG5BbGlnbm1lbnQpCit7CisJRlhfQk9PTCBiTGluZVRvcENoYW5nZWQgPSBGQUxTRTsKKwlDUERGX1JlY3QgcmNSZXN1bHQ7CisJRlhfRkxPQVQgZldpZHRoRGlmZjsKKworCUZYX0lOVDMyIHN6TWF4ID0gRlhfRURJVF9NQVgobV9PbGRMaW5lUmVjdHMuR2V0U2l6ZSgpLG1fTmV3TGluZVJlY3RzLkdldFNpemUoKSk7CisJRlhfSU5UMzIgaSA9IDA7CisKKwl3aGlsZSAoaSA8IHN6TWF4KQorCXsKKwkJQ0ZYX0VkaXRfTGluZVJlY3QgKiBwT2xkUmVjdCA9IG1fT2xkTGluZVJlY3RzLkdldEF0KGkpOworCQlDRlhfRWRpdF9MaW5lUmVjdCAqIHBOZXdSZWN0ID0gbV9OZXdMaW5lUmVjdHMuR2V0QXQoaSk7CisKKwkJaWYgKHBPbGRSZWN0KQorCQl7CisJCQlpZiAocE5ld1JlY3QpCisJCQl7CisJCQkJaWYgKGJMaW5lVG9wQ2hhbmdlZCkKKwkJCQl7CisJCQkJCXJjUmVzdWx0ID0gcE9sZFJlY3QtPm1fcmNMaW5lOworCQkJCQlyY1Jlc3VsdC5VbmlvbihwTmV3UmVjdC0+bV9yY0xpbmUpOworCQkJCQltX1JlZnJlc2hSZWN0cy5BZGQocmNSZXN1bHQpOworCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQlpZiAoKnBOZXdSZWN0ICE9ICpwT2xkUmVjdCkKKwkJCQkJeworCQkJCQkJaWYgKCFwTmV3UmVjdC0+SXNTYW1lVG9wKCpwT2xkUmVjdCkgfHwgIXBOZXdSZWN0LT5Jc1NhbWVIZWlnaHQoKnBPbGRSZWN0KSkKKwkJCQkJCXsKKwkJCQkJCQliTGluZVRvcENoYW5nZWQgPSBUUlVFOworCQkJCQkJCWNvbnRpbnVlOworCQkJCQkJfQorCisJCQkJCQlpZiAobkFsaWdubWVudCA9PSAwKQorCQkJCQkJeworCQkJCQkJCWlmIChwTmV3UmVjdC0+bV93ckxpbmUuQmVnaW5Qb3MgIT0gcE9sZFJlY3QtPm1fd3JMaW5lLkJlZ2luUG9zKQorCQkJCQkJCXsKKwkJCQkJCQkJcmNSZXN1bHQgPSBwT2xkUmVjdC0+bV9yY0xpbmU7CisJCQkJCQkJCXJjUmVzdWx0LlVuaW9uKHBOZXdSZWN0LT5tX3JjTGluZSk7CisJCQkJCQkJCW1fUmVmcmVzaFJlY3RzLkFkZChyY1Jlc3VsdCk7CQorCQkJCQkJCX0KKwkJCQkJCQllbHNlCisJCQkJCQkJeworCQkJCQkJCQlpZiAoIXBOZXdSZWN0LT5Jc1NhbWVMZWZ0KCpwT2xkUmVjdCkpIAorCQkJCQkJCQl7CisJCQkJCQkJCQlyY1Jlc3VsdCA9IHBPbGRSZWN0LT5tX3JjTGluZTsKKwkJCQkJCQkJCXJjUmVzdWx0LlVuaW9uKHBOZXdSZWN0LT5tX3JjTGluZSk7CQkJCQkJCQkJCQorCQkJCQkJCQl9CisJCQkJCQkJCWVsc2UKKwkJCQkJCQkJeworCQkJCQkJCQkJZldpZHRoRGlmZiA9IHBOZXdSZWN0LT5tX3JjTGluZS5XaWR0aCgpIC0gcE9sZFJlY3QtPm1fcmNMaW5lLldpZHRoKCk7CisJCQkJCQkJCQlyY1Jlc3VsdCA9IHBOZXdSZWN0LT5tX3JjTGluZTsKKwkJCQkJCQkJCWlmIChmV2lkdGhEaWZmID4gMC4wZikKKwkJCQkJCQkJCQlyY1Jlc3VsdC5sZWZ0ID0gcmNSZXN1bHQucmlnaHQgLSBmV2lkdGhEaWZmOworCQkJCQkJCQkJZWxzZQorCQkJCQkJCQkJeworCQkJCQkJCQkJCXJjUmVzdWx0LmxlZnQgPSByY1Jlc3VsdC5yaWdodDsKKwkJCQkJCQkJCQlyY1Jlc3VsdC5yaWdodCArPSAoLWZXaWR0aERpZmYpOworCQkJCQkJCQkJfQorCQkJCQkJCQl9CisJCQkJCQkJCW1fUmVmcmVzaFJlY3RzLkFkZChyY1Jlc3VsdCk7CisJCQkJCQkJfQorCQkJCQkJfQorCQkJCQkJZWxzZQorCQkJCQkJeworCQkJCQkJCXJjUmVzdWx0ID0gcE9sZFJlY3QtPm1fcmNMaW5lOworCQkJCQkJCXJjUmVzdWx0LlVuaW9uKHBOZXdSZWN0LT5tX3JjTGluZSk7CisJCQkJCQkJbV9SZWZyZXNoUmVjdHMuQWRkKHJjUmVzdWx0KTsKKwkJCQkJCX0KKwkJCQkJfQorCQkJCQllbHNlCisJCQkJCXsKKwkJCQkJCS8vZG9uJ3QgbmVlZCB0byBkbyBhbnl0aGluZworCQkJCQl9CisJCQkJfQorCQkJfQorCQkJZWxzZQorCQkJeworCQkJCW1fUmVmcmVzaFJlY3RzLkFkZChwT2xkUmVjdC0+bV9yY0xpbmUpOworCQkJfQorCQl9CisJCWVsc2UKKwkJeworCQkJaWYgKHBOZXdSZWN0KQorCQkJeworCQkJCW1fUmVmcmVzaFJlY3RzLkFkZChwTmV3UmVjdC0+bV9yY0xpbmUpOworCQkJfQorCQkJZWxzZQorCQkJeworCQkJCS8vZXJyb3IKKwkJCX0KKwkJfQorCQlpKys7CisJfQorfQorCit2b2lkIENGWF9FZGl0X1JlZnJlc2g6OkFkZFJlZnJlc2goY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkKK3sKKwltX1JlZnJlc2hSZWN0cy5BZGQocmVjdCk7Cit9CisKK2NvbnN0IENGWF9FZGl0X1JlY3RBcnJheSAqIENGWF9FZGl0X1JlZnJlc2g6OkdldFJlZnJlc2hSZWN0cygpIGNvbnN0Cit7CisJcmV0dXJuICZtX1JlZnJlc2hSZWN0czsKK30KKwordm9pZCBDRlhfRWRpdF9SZWZyZXNoOjpFbmRSZWZyZXNoKCkKK3sKKwltX1JlZnJlc2hSZWN0cy5FbXB0eSgpOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9FZGl0X1VuZG8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRlhfRWRpdF9VbmRvOjpDRlhfRWRpdF9VbmRvKEZYX0lOVDMyIG5CdWZzaXplKSA6IG1fbkN1clVuZG9Qb3MoMCksCisJbV9uQnVmU2l6ZShuQnVmc2l6ZSksCisJbV9iTW9kaWZpZWQoRkFMU0UpLAorCW1fYlZpcmdpbihUUlVFKSwKKwltX2JXb3JraW5nKEZBTFNFKQoreworfQorCitDRlhfRWRpdF9VbmRvOjp+Q0ZYX0VkaXRfVW5kbygpCit7CisJUmVzZXQoKTsKK30KKworRlhfQk9PTCBDRlhfRWRpdF9VbmRvOjpDYW5VbmRvKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9uQ3VyVW5kb1BvcyA+IDA7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfVW5kbzo6VW5kbygpCit7CisJbV9iV29ya2luZyA9IFRSVUU7CisKKwlpZiAobV9uQ3VyVW5kb1BvcyA+IDApCisJeworCQlJRlhfRWRpdF9VbmRvSXRlbSAqIHBJdGVtID0gbV9VbmRvSXRlbVN0YWNrLkdldEF0KG1fbkN1clVuZG9Qb3MtMSk7CisJCUFTU0VSVChwSXRlbSAhPSBOVUxMKTsKKworCQlwSXRlbS0+VW5kbygpOworCQorCQltX25DdXJVbmRvUG9zLS07CisJCW1fYk1vZGlmaWVkID0gKG1fbkN1clVuZG9Qb3MgIT0gMCk7CQkKKwl9CisKKwltX2JXb3JraW5nID0gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZYX0VkaXRfVW5kbzo6Q2FuUmVkbygpIGNvbnN0Cit7CisJcmV0dXJuIG1fbkN1clVuZG9Qb3MgPCBtX1VuZG9JdGVtU3RhY2suR2V0U2l6ZSgpOworfQorCit2b2lkIENGWF9FZGl0X1VuZG86OlJlZG8oKQoreworCW1fYldvcmtpbmcgPSBUUlVFOworCisJRlhfSU5UMzIgblN0YWNrU2l6ZSA9IG1fVW5kb0l0ZW1TdGFjay5HZXRTaXplKCk7CisKKwlpZiAobV9uQ3VyVW5kb1BvcyA8IG5TdGFja1NpemUpCisJeworCQlJRlhfRWRpdF9VbmRvSXRlbSAqIHBJdGVtID0gbV9VbmRvSXRlbVN0YWNrLkdldEF0KG1fbkN1clVuZG9Qb3MpOworCQlBU1NFUlQocEl0ZW0gIT0gTlVMTCk7CisKKwkJcEl0ZW0tPlJlZG8oKTsKKworCQltX25DdXJVbmRvUG9zKys7CisJCW1fYk1vZGlmaWVkID0gKG1fbkN1clVuZG9Qb3MgIT0gMCk7CQkKKwl9CisKKwltX2JXb3JraW5nID0gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZYX0VkaXRfVW5kbzo6SXNXb3JraW5nKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9iV29ya2luZzsKK30KKwordm9pZCBDRlhfRWRpdF9VbmRvOjpBZGRJdGVtKElGWF9FZGl0X1VuZG9JdGVtKiBwSXRlbSkKK3sKKwlBU1NFUlQoIW1fYldvcmtpbmcpOworCUFTU0VSVChwSXRlbSAhPSBOVUxMKTsKKwlBU1NFUlQobV9uQnVmU2l6ZSA+IDEpOworCQorCWlmIChtX25DdXJVbmRvUG9zIDwgbV9VbmRvSXRlbVN0YWNrLkdldFNpemUoKSkKKwkJUmVtb3ZlVGFpbHMoKTsKKworCWlmIChtX1VuZG9JdGVtU3RhY2suR2V0U2l6ZSgpID49IG1fbkJ1ZlNpemUpCisJeworCQlSZW1vdmVIZWFkcygpOwkKKwkJbV9iVmlyZ2luID0gRkFMU0U7CisJfQorCisJbV9VbmRvSXRlbVN0YWNrLkFkZChwSXRlbSk7CQorCW1fbkN1clVuZG9Qb3MgPSBtX1VuZG9JdGVtU3RhY2suR2V0U2l6ZSgpOworCisJbV9iTW9kaWZpZWQgPSAobV9uQ3VyVW5kb1BvcyAhPSAwKTsKK30KKworRlhfQk9PTAlDRlhfRWRpdF9VbmRvOjpJc01vZGlmaWVkKCkgY29uc3QKK3sKKwlpZiAobV9iVmlyZ2luKQorCQlyZXR1cm4gbV9iTW9kaWZpZWQ7CisJZWxzZQorCQlyZXR1cm4gVFJVRTsKK30KKworSUZYX0VkaXRfVW5kb0l0ZW0qIENGWF9FZGl0X1VuZG86OkdldEl0ZW0oRlhfSU5UMzIgbkluZGV4KQoreworCWlmIChuSW5kZXg+PTAgJiYgbkluZGV4IDwgbV9VbmRvSXRlbVN0YWNrLkdldFNpemUoKSkKKwkJcmV0dXJuIG1fVW5kb0l0ZW1TdGFjay5HZXRBdChuSW5kZXgpOworCisJcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfVW5kbzo6UmVtb3ZlSGVhZHMoKQoreworCUFTU0VSVChtX1VuZG9JdGVtU3RhY2suR2V0U2l6ZSgpID4gMSk7CisKKwlJRlhfRWRpdF9VbmRvSXRlbSogcEl0ZW0gPSBtX1VuZG9JdGVtU3RhY2suR2V0QXQoMCk7CisJQVNTRVJUKHBJdGVtICE9IE5VTEwpOworCisJcEl0ZW0tPlJlbGVhc2UoKTsKKwltX1VuZG9JdGVtU3RhY2suUmVtb3ZlQXQoMCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfVW5kbzo6UmVtb3ZlVGFpbHMoKQoreworCWZvciAoRlhfSU5UMzIgaSA9IG1fVW5kb0l0ZW1TdGFjay5HZXRTaXplKCktMTsgaSA+PSBtX25DdXJVbmRvUG9zOyBpLS0pCisJeworCQlJRlhfRWRpdF9VbmRvSXRlbSogcEl0ZW0gPSBtX1VuZG9JdGVtU3RhY2suR2V0QXQoaSk7CisJCUFTU0VSVChwSXRlbSAhPSBOVUxMKTsKKworCQlwSXRlbS0+UmVsZWFzZSgpOworCQltX1VuZG9JdGVtU3RhY2suUmVtb3ZlQXQoaSk7CisJfQorfQorCit2b2lkIENGWF9FZGl0X1VuZG86OlJlc2V0KCkKK3sKKwlmb3IgKEZYX0lOVDMyIGk9MCwgc3o9bV9VbmRvSXRlbVN0YWNrLkdldFNpemUoKTsgaSA8IHN6OyBpKyspCisJeworCQlJRlhfRWRpdF9VbmRvSXRlbSAqIHBJdGVtID0gbV9VbmRvSXRlbVN0YWNrLkdldEF0KGkpOworCQlBU1NFUlQocEl0ZW0gIT0gTlVMTCk7CisKKwkJcEl0ZW0tPlJlbGVhc2UoKTsKKwl9CisJbV9uQ3VyVW5kb1BvcyA9IDA7CisJbV9VbmRvSXRlbVN0YWNrLlJlbW92ZUFsbCgpOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdF9Hcm91cFVuZG9JdGVtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NGWF9FZGl0X0dyb3VwVW5kb0l0ZW06OkNGWF9FZGl0X0dyb3VwVW5kb0l0ZW0oY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUaXRsZSkgOiBtX3NUaXRsZShzVGl0bGUpCit7Cit9CisKK0NGWF9FZGl0X0dyb3VwVW5kb0l0ZW06On5DRlhfRWRpdF9Hcm91cFVuZG9JdGVtKCkKK3sKKwlmb3IgKGludCBpPTAsc3o9bV9JdGVtcy5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCUNGWF9FZGl0X1VuZG9JdGVtKiBwVW5kb0l0ZW0gPSBtX0l0ZW1zW2ldOworCQlBU1NFUlQocFVuZG9JdGVtICE9IE5VTEwpOworCisJCXBVbmRvSXRlbS0+UmVsZWFzZSgpOworCX0KKworCW1fSXRlbXMuUmVtb3ZlQWxsKCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbTo6QWRkVW5kb0l0ZW0oQ0ZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSkKK3sKKwlBU1NFUlQocFVuZG9JdGVtICE9IE5VTEwpOworCisJcFVuZG9JdGVtLT5TZXRGaXJzdChGQUxTRSk7CisJcFVuZG9JdGVtLT5TZXRMYXN0KEZBTFNFKTsKKworCW1fSXRlbXMuQWRkKHBVbmRvSXRlbSk7CisKKwlpZiAobV9zVGl0bGUuSXNFbXB0eSgpKQorCQltX3NUaXRsZSA9IHBVbmRvSXRlbS0+R2V0VW5kb1RpdGxlKCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXRfR3JvdXBVbmRvSXRlbTo6VXBkYXRlSXRlbXMoKQoreworCWlmIChtX0l0ZW1zLkdldFNpemUoKSA+IDApCisJeworCQlDRlhfRWRpdF9VbmRvSXRlbSogcEZpcnN0SXRlbSA9IG1fSXRlbXNbMF07CisJCUFTU0VSVChwRmlyc3RJdGVtICE9IE5VTEwpOworCQlwRmlyc3RJdGVtLT5TZXRGaXJzdChUUlVFKTsKKworCQlDRlhfRWRpdF9VbmRvSXRlbSogcExhc3RJdGVtID0gbV9JdGVtc1ttX0l0ZW1zLkdldFNpemUoKSAtIDFdOworCQlBU1NFUlQocExhc3RJdGVtICE9IE5VTEwpOworCQlwTGFzdEl0ZW0tPlNldExhc3QoVFJVRSk7CisJfQorfQorCit2b2lkIENGWF9FZGl0X0dyb3VwVW5kb0l0ZW06OlVuZG8oKQoreworCWZvciAoaW50IGk9bV9JdGVtcy5HZXRTaXplKCktMTsgaT49MDsgaS0tKQorCXsKKwkJQ0ZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSA9IG1fSXRlbXNbaV07CisJCUFTU0VSVChwVW5kb0l0ZW0gIT0gTlVMTCk7CisKKwkJcFVuZG9JdGVtLT5VbmRvKCk7CisJfQorfQorCit2b2lkIENGWF9FZGl0X0dyb3VwVW5kb0l0ZW06OlJlZG8oKQoreworCWZvciAoaW50IGk9MCxzej1tX0l0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJQ0ZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSA9IG1fSXRlbXNbaV07CisJCUFTU0VSVChwVW5kb0l0ZW0gIT0gTlVMTCk7CisKKwkJcFVuZG9JdGVtLT5SZWRvKCk7CisJfQorfQorCitDRlhfV2lkZVN0cmluZyBDRlhfRWRpdF9Hcm91cFVuZG9JdGVtOjpHZXRVbmRvVGl0bGUoKQoreworCXJldHVybiBtX3NUaXRsZTsKK30KKwordm9pZCBDRlhfRWRpdF9Hcm91cFVuZG9JdGVtOjpSZWxlYXNlKCkKK3sKKwlkZWxldGUgdGhpczsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdF9VbmRvSXRlbSBkZXJpdmVkIGNsYXNzZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRlhFVV9JbnNlcnRXb3JkOjpDRlhFVV9JbnNlcnRXb3JkKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLAorCQkJCQkJCQkgRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpIAorCTogbV9wRWRpdChwRWRpdCksIG1fd3BPbGQod3BPbGRQbGFjZSksIG1fd3BOZXcod3BOZXdQbGFjZSksIG1fV29yZCh3b3JkKSwgbV9uQ2hhcnNldChjaGFyc2V0KSwgbV9Xb3JkUHJvcHMoKQoreworCWlmIChwV29yZFByb3BzKQorCQltX1dvcmRQcm9wcyA9ICpwV29yZFByb3BzOworfQorCitDRlhFVV9JbnNlcnRXb3JkOjp+Q0ZYRVVfSW5zZXJ0V29yZCgpCit7Cit9CisKK3ZvaWQgQ0ZYRVVfSW5zZXJ0V29yZDo6UmVkbygpCit7CisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7CisJCW1fcEVkaXQtPlNldENhcmV0KG1fd3BPbGQpOwkJCisJCW1fcEVkaXQtPkluc2VydFdvcmQobV9Xb3JkLG1fbkNoYXJzZXQsJm1fV29yZFByb3BzLEZBTFNFLFRSVUUpOworCX0KK30KKwordm9pZCBDRlhFVV9JbnNlcnRXb3JkOjpVbmRvKCkKK3sKKwlpZiAobV9wRWRpdCkKKwl7CisJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsKKwkJbV9wRWRpdC0+U2V0Q2FyZXQobV93cE5ldyk7CisJCW1fcEVkaXQtPkJhY2tzcGFjZShGQUxTRSxUUlVFKTsKKwl9Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NGWEVVX0luc2VydFJldHVybjo6Q0ZYRVVfSW5zZXJ0UmV0dXJuKENGWF9FZGl0ICogcEVkaXQsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BPbGRQbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE5ld1BsYWNlLAorCQkJIGNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcykgOgorCQkJbV9wRWRpdChwRWRpdCksCisJCQltX3dwT2xkKHdwT2xkUGxhY2UpLAorCQkJbV93cE5ldyh3cE5ld1BsYWNlKSwKKwkJCW1fU2VjUHJvcHMoKSwKKwkJCW1fV29yZFByb3BzKCkJCQkJCQkJCQkgCit7CisJaWYgKHBTZWNQcm9wcykKKwkJbV9TZWNQcm9wcyA9ICpwU2VjUHJvcHM7CisJaWYgKHBXb3JkUHJvcHMpCisJCW1fV29yZFByb3BzID0gKnBXb3JkUHJvcHM7Cit9CisKK0NGWEVVX0luc2VydFJldHVybjo6fkNGWEVVX0luc2VydFJldHVybigpCit7Cit9CisKK3ZvaWQgQ0ZYRVVfSW5zZXJ0UmV0dXJuOjpSZWRvKCkKK3sKKwlpZiAobV9wRWRpdCkKKwl7CisJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsKKwkJbV9wRWRpdC0+U2V0Q2FyZXQobV93cE9sZCk7CisJCW1fcEVkaXQtPkluc2VydFJldHVybigmbV9TZWNQcm9wcywmbV9Xb3JkUHJvcHMsRkFMU0UsVFJVRSk7CisJfQorfQorCit2b2lkIENGWEVVX0luc2VydFJldHVybjo6VW5kbygpCit7CisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7CisJCW1fcEVkaXQtPlNldENhcmV0KG1fd3BOZXcpOworCQltX3BFZGl0LT5CYWNrc3BhY2UoRkFMU0UsVFJVRSk7CisJfQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworLy9DRlhFVV9CYWNrc3BhY2UKKworQ0ZYRVVfQmFja3NwYWNlOjpDRlhFVV9CYWNrc3BhY2UoQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsCisJCQkJCQkJICAgRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LAorCQkJCQkJCSAgIGNvbnN0IENQVlRfU2VjUHJvcHMgJiBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBXb3JkUHJvcHMpIDoKKwkJCW1fcEVkaXQocEVkaXQpLAorCQkJbV93cE9sZCh3cE9sZFBsYWNlKSwKKwkJCW1fd3BOZXcod3BOZXdQbGFjZSksCisJCQltX1dvcmQod29yZCksCisJCQltX25DaGFyc2V0KGNoYXJzZXQpLAorCQkJbV9TZWNQcm9wcyhTZWNQcm9wcyksCisJCQltX1dvcmRQcm9wcyhXb3JkUHJvcHMpCQkJCQkJCQkJIAoreworfQorCitDRlhFVV9CYWNrc3BhY2U6On5DRlhFVV9CYWNrc3BhY2UoKQoreworfQorCit2b2lkIENGWEVVX0JhY2tzcGFjZTo6UmVkbygpCit7CisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7CisJCW1fcEVkaXQtPlNldENhcmV0KG1fd3BPbGQpOworCQltX3BFZGl0LT5CYWNrc3BhY2UoRkFMU0UsVFJVRSk7CisJfQorfQorCit2b2lkIENGWEVVX0JhY2tzcGFjZTo6VW5kbygpCit7CisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7CisJCW1fcEVkaXQtPlNldENhcmV0KG1fd3BOZXcpOworCQlpZiAobV93cE5ldy5TZWNDbXAobV93cE9sZCkgIT0gMCkKKwkJeworCQkJbV9wRWRpdC0+SW5zZXJ0UmV0dXJuKCZtX1NlY1Byb3BzLCZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCW1fcEVkaXQtPkluc2VydFdvcmQobV9Xb3JkLG1fbkNoYXJzZXQsJm1fV29yZFByb3BzLEZBTFNFLFRSVUUpOworCQl9CisJfQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworLy9DRlhFVV9EZWxldGUKKworQ0ZYRVVfRGVsZXRlOjpDRlhFVV9EZWxldGUoQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsCisJCQkJCQkJICAgRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LAorCQkJCQkJCSAgIGNvbnN0IENQVlRfU2VjUHJvcHMgJiBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBXb3JkUHJvcHMsIEZYX0JPT0wgYlNlY0VuZCkgOgorCQkJbV9wRWRpdChwRWRpdCksCisJCQltX3dwT2xkKHdwT2xkUGxhY2UpLAorCQkJbV93cE5ldyh3cE5ld1BsYWNlKSwKKwkJCW1fV29yZCh3b3JkKSwKKwkJCW1fbkNoYXJzZXQoY2hhcnNldCksCisJCQltX1NlY1Byb3BzKFNlY1Byb3BzKSwKKwkJCW1fV29yZFByb3BzKFdvcmRQcm9wcyksCisJCQltX2JTZWNFbmQoYlNlY0VuZCkKK3sKK30KKworQ0ZYRVVfRGVsZXRlOjp+Q0ZYRVVfRGVsZXRlKCkKK3sKK30KKwordm9pZCBDRlhFVV9EZWxldGU6OlJlZG8oKQoreworCWlmIChtX3BFZGl0KQorCXsKKwkJbV9wRWRpdC0+U2VsZWN0Tm9uZSgpOworCQltX3BFZGl0LT5TZXRDYXJldChtX3dwT2xkKTsKKwkJbV9wRWRpdC0+RGVsZXRlKEZBTFNFLFRSVUUpOworCX0KK30KKwordm9pZCBDRlhFVV9EZWxldGU6OlVuZG8oKQoreworCWlmIChtX3BFZGl0KQorCXsKKwkJbV9wRWRpdC0+U2VsZWN0Tm9uZSgpOworCQltX3BFZGl0LT5TZXRDYXJldChtX3dwTmV3KTsKKwkJaWYgKG1fYlNlY0VuZCkKKwkJeworCQkJbV9wRWRpdC0+SW5zZXJ0UmV0dXJuKCZtX1NlY1Byb3BzLCZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCW1fcEVkaXQtPkluc2VydFdvcmQobV9Xb3JkLG1fbkNoYXJzZXQsJm1fV29yZFByb3BzLEZBTFNFLFRSVUUpOworCQl9CisJfQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworLy9DRlhFVV9DbGVhcgorCitDRlhFVV9DbGVhcjo6Q0ZYRVVfQ2xlYXIoQ0ZYX0VkaXQgKiBwRWRpdCwgIGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3JTZWwsIGNvbnN0IENGWF9XaWRlU3RyaW5nICYgc3dUZXh0KSA6CisJCQltX3BFZGl0KHBFZGl0KSwKKwkJCW1fd3JTZWwod3JTZWwpLAorCQkJbV9zd1RleHQoc3dUZXh0KQoreworfQorCitDRlhFVV9DbGVhcjo6fkNGWEVVX0NsZWFyKCkKK3sKK30KKwordm9pZCBDRlhFVV9DbGVhcjo6UmVkbygpCit7CisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7CisJCW1fcEVkaXQtPlNldFNlbChtX3dyU2VsLkJlZ2luUG9zLG1fd3JTZWwuRW5kUG9zKTsKKwkJbV9wRWRpdC0+Q2xlYXIoRkFMU0UsVFJVRSk7CisJfQorfQorCit2b2lkIENGWEVVX0NsZWFyOjpVbmRvKCkKK3sKKwlpZiAobV9wRWRpdCkKKwl7CisJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsKKwkJbV9wRWRpdC0+U2V0Q2FyZXQobV93clNlbC5CZWdpblBvcyk7CisJCW1fcEVkaXQtPkluc2VydFRleHQobV9zd1RleHQsIERFRkFVTFRfQ0hBUlNFVCwgTlVMTCxOVUxMLEZBTFNFLFRSVUUpOworCQltX3BFZGl0LT5TZXRTZWwobV93clNlbC5CZWdpblBvcyxtX3dyU2VsLkVuZFBvcyk7CisJfQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworLy9DRlhFVV9DbGVhclJpY2gKKworQ0ZYRVVfQ2xlYXJSaWNoOjpDRlhFVV9DbGVhclJpY2goQ0ZYX0VkaXQgKiBwRWRpdCwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiB3cE9sZFBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3UGxhY2UsCisJCQkJCQkJICAgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3clNlbCwgRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LAorCQkJCQkJCSAgIGNvbnN0IENQVlRfU2VjUHJvcHMgJiBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgJiBXb3JkUHJvcHMpIDoKKwkJCW1fcEVkaXQocEVkaXQpLAorCQkJbV93cE9sZCh3cE9sZFBsYWNlKSwKKwkJCW1fd3BOZXcod3BOZXdQbGFjZSksCisJCQltX3dyU2VsKHdyU2VsKSwKKwkJCW1fV29yZCh3b3JkKSwKKwkJCW1fbkNoYXJzZXQoY2hhcnNldCksCisJCQltX1NlY1Byb3BzKFNlY1Byb3BzKSwKKwkJCW1fV29yZFByb3BzKFdvcmRQcm9wcykJCQkJCQkJCQkgCit7Cit9CisKK0NGWEVVX0NsZWFyUmljaDo6fkNGWEVVX0NsZWFyUmljaCgpCit7Cit9CisKK3ZvaWQgQ0ZYRVVfQ2xlYXJSaWNoOjpSZWRvKCkKK3sKKwlpZiAobV9wRWRpdCAmJiBJc0xhc3QoKSkKKwl7CisJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsKKwkJbV9wRWRpdC0+U2V0U2VsKG1fd3JTZWwuQmVnaW5Qb3MsbV93clNlbC5FbmRQb3MpOworCQltX3BFZGl0LT5DbGVhcihGQUxTRSxUUlVFKTsKKwl9Cit9CisKK3ZvaWQgQ0ZYRVVfQ2xlYXJSaWNoOjpVbmRvKCkKK3sKKwlpZiAobV9wRWRpdCkKKwl7CisJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsKKwkJbV9wRWRpdC0+U2V0Q2FyZXQobV93cE9sZCk7CisJCWlmIChtX3dwTmV3LlNlY0NtcChtX3dwT2xkKSAhPSAwKQorCQl7CisJCQltX3BFZGl0LT5JbnNlcnRSZXR1cm4oJm1fU2VjUHJvcHMsJm1fV29yZFByb3BzLEZBTFNFLEZBTFNFKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCW1fcEVkaXQtPkluc2VydFdvcmQobV9Xb3JkLG1fbkNoYXJzZXQsJm1fV29yZFByb3BzLEZBTFNFLEZBTFNFKTsKKwkJfQorCisJCWlmIChJc0ZpcnN0KCkpCisJCXsKKwkJCW1fcEVkaXQtPlBhaW50SW5zZXJ0VGV4dChtX3dyU2VsLkJlZ2luUG9zLG1fd3JTZWwuRW5kUG9zKTsKKwkJCW1fcEVkaXQtPlNldFNlbChtX3dyU2VsLkJlZ2luUG9zLG1fd3JTZWwuRW5kUG9zKTsKKwkJfQorCX0KK30KKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisvL0NGWEVVX0luc2VydFRleHQKKworQ0ZYRVVfSW5zZXJ0VGV4dDo6Q0ZYRVVfSW5zZXJ0VGV4dChDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwT2xkUGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlICYgd3BOZXdQbGFjZSwKKwkJCQkJCQkgICBjb25zdCBDRlhfV2lkZVN0cmluZyAmIHN3VGV4dCwgRlhfSU5UMzIgY2hhcnNldCwKKwkJCQkJCQkgICBjb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpIDoKKwkJCW1fcEVkaXQocEVkaXQpLAorCQkJbV93cE9sZCh3cE9sZFBsYWNlKSwKKwkJCW1fd3BOZXcod3BOZXdQbGFjZSksCisJCQltX3N3VGV4dChzd1RleHQpLAorCQkJbV9uQ2hhcnNldChjaGFyc2V0KSwKKwkJCW1fU2VjUHJvcHMoKSwKKwkJCW1fV29yZFByb3BzKCkJCQkJCQkJCQkgCit7CisJaWYgKHBTZWNQcm9wcykKKwkJbV9TZWNQcm9wcyA9ICpwU2VjUHJvcHM7CisJaWYgKHBXb3JkUHJvcHMpCisJCW1fV29yZFByb3BzID0gKnBXb3JkUHJvcHM7Cit9CisKK0NGWEVVX0luc2VydFRleHQ6On5DRlhFVV9JbnNlcnRUZXh0KCkKK3sKK30KKwordm9pZCBDRlhFVV9JbnNlcnRUZXh0OjpSZWRvKCkKK3sKKwlpZiAobV9wRWRpdCAmJiBJc0xhc3QoKSkKKwl7CisJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsKKwkJbV9wRWRpdC0+U2V0Q2FyZXQobV93cE9sZCk7CisJCW1fcEVkaXQtPkluc2VydFRleHQobV9zd1RleHQsIG1fbkNoYXJzZXQsJm1fU2VjUHJvcHMsICZtX1dvcmRQcm9wcyxGQUxTRSxUUlVFKTsKKwl9Cit9CisKK3ZvaWQgQ0ZYRVVfSW5zZXJ0VGV4dDo6VW5kbygpCit7CisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7CisJCW1fcEVkaXQtPlNldFNlbChtX3dwT2xkLG1fd3BOZXcpOworCQltX3BFZGl0LT5DbGVhcihGQUxTRSxUUlVFKTsKKwl9Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NGWEVVX1NldFNlY1Byb3BzOjpDRlhFVV9TZXRTZWNQcm9wcyhDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlLCBFRElUX1BST1BTX0UgZXAsIAorCQljb25zdCBDUFZUX1NlY1Byb3BzICYgb2xkc2VjcHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgb2xkd29yZHByb3BzLCAKKwkJY29uc3QgQ1BWVF9TZWNQcm9wcyAmIG5ld3NlY3Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIG5ld3dvcmRwcm9wcywgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiByYW5nZSkKKwkJOiBtX3BFZGl0KHBFZGl0KSwKKwkJbV93cFBsYWNlKHBsYWNlKSwKKwkJbV9lUHJvcHMoZXApLAorCQltX09sZFNlY1Byb3BzKG9sZHNlY3Byb3BzKSwKKwkJbV9OZXdTZWNQcm9wcyhuZXdzZWNwcm9wcyksCisJCW1fT2xkV29yZFByb3BzKG9sZHdvcmRwcm9wcyksCisJCW1fTmV3V29yZFByb3BzKG5ld3dvcmRwcm9wcyksCisJCW1fd3JQbGFjZShyYW5nZSkKK3sKK30KKworQ0ZYRVVfU2V0U2VjUHJvcHM6On5DRlhFVV9TZXRTZWNQcm9wcygpCit7Cit9CisKK3ZvaWQgQ0ZYRVVfU2V0U2VjUHJvcHM6OlJlZG8oKQoreworCWlmIChtX3BFZGl0KQorCXsKKwkJbV9wRWRpdC0+U2V0U2VjUHJvcHMobV9lUHJvcHMsbV93cFBsYWNlLCZtX05ld1NlY1Byb3BzLCZtX05ld1dvcmRQcm9wcyxtX3dyUGxhY2UsRkFMU0UpOworCQlpZiAoSXNMYXN0KCkpCisJCXsKKwkJCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsKKwkJCW1fcEVkaXQtPlBhaW50U2V0UHJvcHMobV9lUHJvcHMsbV93clBsYWNlKTsKKwkJCW1fcEVkaXQtPlNldFNlbChtX3dyUGxhY2UuQmVnaW5Qb3MsbV93clBsYWNlLkVuZFBvcyk7CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZYRVVfU2V0U2VjUHJvcHM6OlVuZG8oKQoreworCWlmIChtX3BFZGl0KQorCXsKKwkJbV9wRWRpdC0+U2V0U2VjUHJvcHMobV9lUHJvcHMsbV93cFBsYWNlLCZtX09sZFNlY1Byb3BzLCZtX09sZFdvcmRQcm9wcyxtX3dyUGxhY2UsRkFMU0UpOworCQlpZiAoSXNGaXJzdCgpKQorCQl7CisJCQltX3BFZGl0LT5TZWxlY3ROb25lKCk7CisJCQltX3BFZGl0LT5QYWludFNldFByb3BzKG1fZVByb3BzLG1fd3JQbGFjZSk7CisJCQltX3BFZGl0LT5TZXRTZWwobV93clBsYWNlLkJlZ2luUG9zLG1fd3JQbGFjZS5FbmRQb3MpOworCQl9CisJfQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRlhFVV9TZXRXb3JkUHJvcHM6OkNGWEVVX1NldFdvcmRQcm9wcyhDRlhfRWRpdCAqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlLCBFRElUX1BST1BTX0UgZXAsIAorCQljb25zdCBDUFZUX1dvcmRQcm9wcyAmIG9sZHByb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIG5ld3Byb3BzLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKQorCQk6IG1fcEVkaXQocEVkaXQpLAorCQltX3dwUGxhY2UocGxhY2UpLAorCQltX2VQcm9wcyhlcCksCisJCW1fT2xkV29yZFByb3BzKG9sZHByb3BzKSwKKwkJbV9OZXdXb3JkUHJvcHMobmV3cHJvcHMpLAorCQltX3dyUGxhY2UocmFuZ2UpCit7Cit9CisKK0NGWEVVX1NldFdvcmRQcm9wczo6fkNGWEVVX1NldFdvcmRQcm9wcygpCit7Cit9CisKK3ZvaWQgQ0ZYRVVfU2V0V29yZFByb3BzOjpSZWRvKCkKK3sKKwlpZiAobV9wRWRpdCkKKwl7CisJCW1fcEVkaXQtPlNldFdvcmRQcm9wcyhtX2VQcm9wcyxtX3dwUGxhY2UsJm1fTmV3V29yZFByb3BzLG1fd3JQbGFjZSxGQUxTRSk7CisJCWlmIChJc0xhc3QoKSkKKwkJeworCQkJbV9wRWRpdC0+U2VsZWN0Tm9uZSgpOworCQkJbV9wRWRpdC0+UGFpbnRTZXRQcm9wcyhtX2VQcm9wcyxtX3dyUGxhY2UpOworCQkJbV9wRWRpdC0+U2V0U2VsKG1fd3JQbGFjZS5CZWdpblBvcyxtX3dyUGxhY2UuRW5kUG9zKTsKKwkJfQorCX0KK30KKwordm9pZCBDRlhFVV9TZXRXb3JkUHJvcHM6OlVuZG8oKQoreworCWlmIChtX3BFZGl0KQorCXsKKwkJbV9wRWRpdC0+U2V0V29yZFByb3BzKG1fZVByb3BzLG1fd3BQbGFjZSwmbV9PbGRXb3JkUHJvcHMsbV93clBsYWNlLEZBTFNFKTsKKwkJaWYgKElzRmlyc3QoKSkKKwkJeworCQkJbV9wRWRpdC0+U2VsZWN0Tm9uZSgpOworCQkJbV9wRWRpdC0+UGFpbnRTZXRQcm9wcyhtX2VQcm9wcyxtX3dyUGxhY2UpOworCQkJbV9wRWRpdC0+U2V0U2VsKG1fd3JQbGFjZS5CZWdpblBvcyxtX3dyUGxhY2UuRW5kUG9zKTsKKwkJfQorCX0KK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfRWRpdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NGWF9FZGl0OjpDRlhfRWRpdChJUERGX1ZhcmlhYmxlVGV4dCAqIHBWVCkgOgorCW1fcFZUKHBWVCksCisJbV9wTm90aWZ5KE5VTEwpLAorCW1fcE9wck5vdGlmeShOVUxMKSwKKwltX3dwQ2FyZXQoLTEsLTEsLTEpLAorCW1fd3BPbGRDYXJldCgtMSwtMSwtMSksCisJbV9wdFNjcm9sbFBvcygwLDApLAorCW1fcHRSZWZyZXNoU2Nyb2xsUG9zKDAsMCksCisJbV9iRW5hYmxlU2Nyb2xsKEZBTFNFKSwKKwltX2JFbmFibGVPdmVyZmxvdyhGQUxTRSksCisJbV9wVlRQcm92aWRlKE5VTEwpLAorCW1fcEl0ZXJhdG9yKE5VTEwpLAorCW1fU2VsU3RhdGUoKSwKKwltX3B0Q2FyZXQoMC4wZiwwLjBmKSwKKwltX1VuZG8oRlhfRURJVF9VTkRPX01BWElURU0pLAorCW1fbkFsaWdubWVudCgwKSwKKwltX2JOb3RpZnlGbGFnKEZBTFNFKSwKKwltX2JFbmFibGVSZWZyZXNoKFRSVUUpLAorCW1fcmNPbGRDb250ZW50KDAuMGYsMC4wZiwwLjBmLDAuMGYpLAorCW1fYkVuYWJsZVVuZG8oVFJVRSksCisJbV9iTm90aWZ5KFRSVUUpLAorCW1fYk9wck5vdGlmeShGQUxTRSksCisJbV9wR3JvdXBVbmRvSXRlbShOVUxMKQorewkKKwlBU1NFUlQocFZUICE9IE5VTEwpOworfQorCitDRlhfRWRpdDo6fkNGWF9FZGl0KCkKK3sKKwlpZiAobV9wVlRQcm92aWRlKQorCXsKKwkJZGVsZXRlIG1fcFZUUHJvdmlkZTsKKwkJbV9wVlRQcm92aWRlID0gTlVMTDsKKwl9CisKKwlpZiAobV9wSXRlcmF0b3IpCisJeworCQlkZWxldGUgbV9wSXRlcmF0b3I7CisJCW1fcEl0ZXJhdG9yID0gTlVMTDsKKwl9CisKKwlBU1NFUlQobV9wR3JvdXBVbmRvSXRlbSA9PSBOVUxMKTsKK30KKworLy8gcHVibGljIG1ldGhvZHMKKwordm9pZCBDRlhfRWRpdDo6SW5pdGlhbGl6ZSgpCit7CisJbV9wVlQtPkluaXRpYWxpemUoKTsKKwlTZXRDYXJldChtX3BWVC0+R2V0QmVnaW5Xb3JkUGxhY2UoKSk7CisJU2V0Q2FyZXRPcmlnaW4oKTsKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApCit7CisJaWYgKG1fcFZUUHJvdmlkZSkgCisJCWRlbGV0ZSBtX3BWVFByb3ZpZGU7CisKKwltX3BWVC0+U2V0UHJvdmlkZXIobV9wVlRQcm92aWRlID0gbmV3IENGWF9FZGl0X1Byb3ZpZGVyKHBGb250TWFwKSk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldFZUUHJvdmlkZXIoSVBERl9WYXJpYWJsZVRleHRfUHJvdmlkZXIqIHBQcm92aWRlcikKK3sKKwltX3BWVC0+U2V0UHJvdmlkZXIocFByb3ZpZGVyKTsKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0Tm90aWZ5KElGWF9FZGl0X05vdGlmeSogcE5vdGlmeSkKK3sKKwltX3BOb3RpZnkgPSBwTm90aWZ5OworfQorCit2b2lkIENGWF9FZGl0OjpTZXRPcHJOb3RpZnkoSUZYX0VkaXRfT3ByTm90aWZ5KiBwT3ByTm90aWZ5KQoreworCW1fcE9wck5vdGlmeSA9IHBPcHJOb3RpZnk7Cit9CisKK0lGWF9FZGl0X0l0ZXJhdG9yICogQ0ZYX0VkaXQ6OkdldEl0ZXJhdG9yKCkKK3sKKwlpZiAoIW1fcEl0ZXJhdG9yKQorCQltX3BJdGVyYXRvciA9IG5ldyBDRlhfRWRpdF9JdGVyYXRvcih0aGlzLG1fcFZULT5HZXRJdGVyYXRvcigpKTsKKworCXJldHVybiBtX3BJdGVyYXRvcjsKK30KKworSVBERl9WYXJpYWJsZVRleHQgKglDRlhfRWRpdDo6R2V0VmFyaWFibGVUZXh0KCkKK3sKKwlyZXR1cm4gbV9wVlQ7Cit9CisKK0lGWF9FZGl0X0ZvbnRNYXAqIENGWF9FZGl0OjpHZXRGb250TWFwKCkKK3sKKwlpZiAobV9wVlRQcm92aWRlKQorCQlyZXR1cm4gbV9wVlRQcm92aWRlLT5HZXRGb250TWFwKCk7CisKKwlyZXR1cm4gTlVMTDsKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0UGxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QsIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pCit7CQorCW1fcFZULT5TZXRQbGF0ZVJlY3QocmVjdCk7CisJbV9wdFNjcm9sbFBvcyA9IENQREZfUG9pbnQocmVjdC5sZWZ0LHJlY3QudG9wKTsJCQkKKwlpZiAoYlBhaW50KSBQYWludCgpOworfQorCit2b2lkIENGWF9FZGl0OjpTZXRBbGlnbm1lbnRIKEZYX0lOVDMyIG5Gb3JtYXQvKiA9MCAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX3BWVC0+U2V0QWxpZ25tZW50KG5Gb3JtYXQpOworCWlmIChiUGFpbnQpIFBhaW50KCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldEFsaWdubWVudFYoRlhfSU5UMzIgbkZvcm1hdC8qID0wICovLCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQoreworCW1fbkFsaWdubWVudCA9IG5Gb3JtYXQ7CisJaWYgKGJQYWludCkgUGFpbnQoKTsKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0UGFzc3dvcmRDaGFyKEZYX1dPUkQgd1N1YldvcmQvKiA9JyonICovLCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQoreworCW1fcFZULT5TZXRQYXNzd29yZENoYXIod1N1YldvcmQpOworCWlmIChiUGFpbnQpIFBhaW50KCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldExpbWl0Q2hhcihGWF9JTlQzMiBuTGltaXRDaGFyLyogPTAgKi8sIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pCit7CisJbV9wVlQtPlNldExpbWl0Q2hhcihuTGltaXRDaGFyKTsKKwlpZiAoYlBhaW50KSBQYWludCgpOworfQorCit2b2lkIENGWF9FZGl0OjpTZXRDaGFyQXJyYXkoRlhfSU5UMzIgbkNoYXJBcnJheS8qID0wICovLCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQoreworCW1fcFZULT5TZXRDaGFyQXJyYXkobkNoYXJBcnJheSk7CisJaWYgKGJQYWludCkgUGFpbnQoKTsKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UvKiA9MC4wZiAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX3BWVC0+U2V0Q2hhclNwYWNlKGZDaGFyU3BhY2UpOworCWlmIChiUGFpbnQpIFBhaW50KCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldEhvcnpTY2FsZShGWF9JTlQzMiBuSG9yelNjYWxlLyogPTEwMCAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX3BWVC0+U2V0SG9yelNjYWxlKG5Ib3J6U2NhbGUpOworCWlmIChiUGFpbnQpIFBhaW50KCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldE11bHRpTGluZShGWF9CT09MIGJNdWx0aUxpbmUvKiA9VFJVRSAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX3BWVC0+U2V0TXVsdGlMaW5lKGJNdWx0aUxpbmUpOworCWlmIChiUGFpbnQpIFBhaW50KCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldEF1dG9SZXR1cm4oRlhfQk9PTCBiQXV0by8qID1UUlVFICovLCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQoreworCW1fcFZULT5TZXRBdXRvUmV0dXJuKGJBdXRvKTsKKwlpZiAoYlBhaW50KSBQYWludCgpOworfQorCit2b2lkIENGWF9FZGl0OjpTZXRMaW5lTGVhZGluZyhGWF9GTE9BVCBmTGluZUxlYWRpbmcvKiA9VFJVRSAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX3BWVC0+U2V0TGluZUxlYWRpbmcoZkxpbmVMZWFkaW5nKTsKKwlpZiAoYlBhaW50KSBQYWludCgpOworfQorCit2b2lkIENGWF9FZGl0OjpTZXRBdXRvRm9udFNpemUoRlhfQk9PTCBiQXV0by8qID1UUlVFICovLCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQoreworCW1fcFZULT5TZXRBdXRvRm9udFNpemUoYkF1dG8pOworCWlmIChiUGFpbnQpIFBhaW50KCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSwgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX3BWVC0+U2V0Rm9udFNpemUoZkZvbnRTaXplKTsKKwlpZiAoYlBhaW50KSBQYWludCgpOworfQorCit2b2lkIENGWF9FZGl0OjpTZXRBdXRvU2Nyb2xsKEZYX0JPT0wgYkF1dG8vKiA9VFJVRSAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX2JFbmFibGVTY3JvbGwgPSBiQXV0bzsKKwlpZiAoYlBhaW50KSBQYWludCgpOworfQorCit2b2lkIENGWF9FZGl0OjpTZXRUZXh0T3ZlcmZsb3coRlhfQk9PTCBiQWxsb3dlZCAvKj0gRkFMU0UqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX2JFbmFibGVPdmVyZmxvdyA9IGJBbGxvd2VkOworCWlmIChiUGFpbnQpIFBhaW50KCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldFNlbChGWF9JTlQzMiBuU3RhcnRDaGFyLEZYX0lOVDMyIG5FbmRDaGFyKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJaWYgKG5TdGFydENoYXIgPT0gMCAmJiBuRW5kQ2hhciA8IDApCisJCXsKKwkJCVNlbGVjdEFsbCgpOworCQl9CisJCWVsc2UgaWYgKG5TdGFydENoYXIgPCAwKQorCQl7CQorCQkJdGhpcy0+U2VsZWN0Tm9uZSgpOworCQl9CisJCWVsc2UKKwkJewkJCisJCQlpZiAoblN0YXJ0Q2hhciA8IG5FbmRDaGFyKQorCQkJeworCQkJCVNldFNlbChtX3BWVC0+V29yZEluZGV4VG9Xb3JkUGxhY2UoblN0YXJ0Q2hhciksbV9wVlQtPldvcmRJbmRleFRvV29yZFBsYWNlKG5FbmRDaGFyKSk7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJU2V0U2VsKG1fcFZULT5Xb3JkSW5kZXhUb1dvcmRQbGFjZShuRW5kQ2hhciksbV9wVlQtPldvcmRJbmRleFRvV29yZFBsYWNlKG5TdGFydENoYXIpKTsKKwkJCX0KKwkJfQkKKwl9Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldFNlbChjb25zdCBDUFZUX1dvcmRQbGFjZSAmIGJlZ2luLGNvbnN0IENQVlRfV29yZFBsYWNlICYgZW5kKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJU2VsZWN0Tm9uZSgpOworCisJCW1fU2VsU3RhdGUuU2V0KGJlZ2luLGVuZCk7CisKKwkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5FbmRQb3MpOworCisJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkKKwkJeworCQkJU2Nyb2xsVG9DYXJldCgpOworCQkJQ1BWVF9Xb3JkUmFuZ2Ugd3IobV9TZWxTdGF0ZS5CZWdpblBvcyxtX1NlbFN0YXRlLkVuZFBvcyk7CisJCQlSZWZyZXNoKFJQX09QVElPTkFMLCZ3cik7CisJCQlTZXRDYXJldEluZm8oKTsKKwkJfQorCQllbHNlCisJCXsJCQorCQkJU2Nyb2xsVG9DYXJldCgpOworCQkJU2V0Q2FyZXRJbmZvKCk7CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OkdldFNlbChGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIpIGNvbnN0Cit7CisJblN0YXJ0Q2hhciA9IC0xOworCW5FbmRDaGFyID0gLTE7CisKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkKKwkJeworCQkJaWYgKG1fU2VsU3RhdGUuQmVnaW5Qb3MuV29yZENtcChtX1NlbFN0YXRlLkVuZFBvcyk8MCkKKwkJCXsKKwkJCQluU3RhcnRDaGFyID0gbV9wVlQtPldvcmRQbGFjZVRvV29yZEluZGV4KG1fU2VsU3RhdGUuQmVnaW5Qb3MpOworCQkJCW5FbmRDaGFyID0gbV9wVlQtPldvcmRQbGFjZVRvV29yZEluZGV4KG1fU2VsU3RhdGUuRW5kUG9zKTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQluU3RhcnRDaGFyID0gbV9wVlQtPldvcmRQbGFjZVRvV29yZEluZGV4KG1fU2VsU3RhdGUuRW5kUG9zKTsKKwkJCQluRW5kQ2hhciA9IG1fcFZULT5Xb3JkUGxhY2VUb1dvcmRJbmRleChtX1NlbFN0YXRlLkJlZ2luUG9zKTsKKwkJCX0KKwkJfQorCQllbHNlCisJCXsKKwkJCW5TdGFydENoYXIgPSBtX3BWVC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgobV93cENhcmV0KTsKKwkJCW5FbmRDaGFyID0gbV9wVlQtPldvcmRQbGFjZVRvV29yZEluZGV4KG1fd3BDYXJldCk7CisJCX0KKwl9Cit9CisKK0ZYX0lOVDMyIENGWF9FZGl0OjpHZXRDYXJldCgpIGNvbnN0Cit7CisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJCXJldHVybiBtX3BWVC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgobV93cENhcmV0KTsKKworCXJldHVybiAtMTsKK30KKworQ1BWVF9Xb3JkUGxhY2UgQ0ZYX0VkaXQ6OkdldENhcmV0V29yZFBsYWNlKCkgY29uc3QKK3sKKwlyZXR1cm4gbV93cENhcmV0OworfQorCitDRlhfV2lkZVN0cmluZyBDRlhfRWRpdDo6R2V0VGV4dCgpIGNvbnN0Cit7CisJQ0ZYX1dpZGVTdHJpbmcgc3dSZXQ7CisKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQorCQl7CisJCQlGWF9CT09MIGJSaWNoID0gbV9wVlQtPklzUmljaFRleHQoKTsKKworCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsKKworCQkJQ1BWVF9Xb3JkIHdvcmRpbmZvOwkKKwkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkKKwkJCXsKKwkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKworCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZGluZm8pKQorCQkJCXsKKwkJCQkJaWYgKGJSaWNoKQorCQkJCQl7CisJCQkJCQlzd1JldCArPSB3b3JkaW5mby5Xb3JkOworCQkJCQl9CisJCQkJCWVsc2UKKwkJCQkJeworCQkJCQkJc3dSZXQgKz0gd29yZGluZm8uV29yZDsKKwkJCQkJfQkJCQkJCisJCQkJfQorCisJCQkJaWYgKG9sZHBsYWNlLlNlY0NtcChwbGFjZSkgIT0gMCkKKwkJCQl7CisJCQkJCXN3UmV0ICs9IDB4MEQ7CisJCQkJCXN3UmV0ICs9IDB4MEE7CisJCQkJfQorCQkJCQorCQkJCW9sZHBsYWNlID0gcGxhY2U7CisJCQl9CisJCX0KKwl9CisKKwlyZXR1cm4gc3dSZXQ7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENGWF9FZGl0OjpHZXRSYW5nZVRleHQoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiByYW5nZSkgY29uc3QKK3sKKwlDRlhfV2lkZVN0cmluZyBzd1JldDsKKworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJRlhfQk9PTCBiUmljaCA9IG1fcFZULT5Jc1JpY2hUZXh0KCk7CisKKwkJaWYgKElQREZfVmFyaWFibGVUZXh0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wVlQtPkdldEl0ZXJhdG9yKCkpCisJCXsJCQkKKwkJCUNQVlRfV29yZFJhbmdlIHdyVGVtcCA9IHJhbmdlOworCQkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZSh3clRlbXAuQmVnaW5Qb3MpOworCQkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZSh3clRlbXAuRW5kUG9zKTsKKwkJCXBJdGVyYXRvci0+U2V0QXQod3JUZW1wLkJlZ2luUG9zKTsKKworCQkJQ1BWVF9Xb3JkIHdvcmRpbmZvOwkKKwkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlID0gd3JUZW1wLkJlZ2luUG9zOworCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkKKwkJCXsKKwkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKwkJCQlpZiAocGxhY2UuV29yZENtcCh3clRlbXAuRW5kUG9zKSA+IDApYnJlYWs7CisKKwkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKSkKKwkJCQl7CisJCQkJCWlmIChiUmljaCkKKwkJCQkJeworCQkJCQkJc3dSZXQgKz0gd29yZGluZm8uV29yZDsKKwkJCQkJfQorCQkJCQllbHNlCisJCQkJCXsKKwkJCQkJCXN3UmV0ICs9IHdvcmRpbmZvLldvcmQ7CisJCQkJCX0JCQkJCQorCQkJCX0KKworCQkJCWlmIChvbGRwbGFjZS5TZWNDbXAocGxhY2UpICE9IDApCisJCQkJeworCQkJCQlzd1JldCArPSAweDBEOworCQkJCQlzd1JldCArPSAweDBBOworCQkJCX0KKwkJCQkKKwkJCQlvbGRwbGFjZSA9IHBsYWNlOworCQkJfQorCQl9CisJfQorCisJcmV0dXJuIHN3UmV0OworfQorCitDRlhfV2lkZVN0cmluZyBDRlhfRWRpdDo6R2V0U2VsVGV4dCgpIGNvbnN0Cit7CisJcmV0dXJuIEdldFJhbmdlVGV4dChtX1NlbFN0YXRlLkNvbnZlcnRUb1dvcmRSYW5nZSgpKTsKK30KKworRlhfSU5UMzIgQ0ZYX0VkaXQ6OkdldFRvdGFsV29yZHMoKSBjb25zdAoreworCXJldHVybiBtX3BWVC0+R2V0VG90YWxXb3JkcygpOworfQorCitGWF9JTlQzMiBDRlhfRWRpdDo6R2V0VG90YWxMaW5lcygpIGNvbnN0Cit7CisJRlhfSU5UMzIgbkxpbmVzID0gMDsKKworCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQorCXsKKwkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsKKwkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dExpbmUoKSkKKwkJCW5MaW5lcysrOworCX0KKworCXJldHVybiBuTGluZXMrMTsKK30KKworQ1BWVF9Xb3JkUmFuZ2UgQ0ZYX0VkaXQ6OkdldFNlbGVjdFdvcmRSYW5nZSgpIGNvbnN0Cit7CisJcmV0dXJuIG1fU2VsU3RhdGUuQ29udmVydFRvV29yZFJhbmdlKCk7Cit9CisKK0NQVlRfV29yZFJhbmdlIENGWF9FZGl0OjpDb21iaW5lV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IxLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyMikKK3sKKwlDUFZUX1dvcmRSYW5nZSB3clJldDsKKworCWlmICh3cjEuQmVnaW5Qb3MuV29yZENtcCh3cjIuQmVnaW5Qb3MpIDwgMCkKKwl7CisJCXdyUmV0LkJlZ2luUG9zID0gd3IxLkJlZ2luUG9zOworCX0KKwllbHNlCisJeworCQl3clJldC5CZWdpblBvcyA9IHdyMi5CZWdpblBvczsKKwl9CisKKwlpZiAod3IxLkVuZFBvcy5Xb3JkQ21wKHdyMi5FbmRQb3MpIDwgMCkKKwl7CisJCXdyUmV0LkVuZFBvcyA9IHdyMi5FbmRQb3M7CisJfQorCWVsc2UKKwl7CisJCXdyUmV0LkVuZFBvcyA9IHdyMS5FbmRQb3M7CisJfQorCisJcmV0dXJuIHdyUmV0OworfQorCitGWF9CT09MCUNGWF9FZGl0OjpJc1JpY2hUZXh0KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wVlQtPklzUmljaFRleHQoKTsKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0UmljaFRleHQoRlhfQk9PTCBiUmljaFRleHQvKiA9VFJVRSAqLywgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykKK3sKKwltX3BWVC0+U2V0UmljaFRleHQoYlJpY2hUZXh0KTsKKwlpZiAoYlBhaW50KSBQYWludCgpOworfQorCitGWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoRm9udEluZGV4KEZYX0lOVDMyIG5Gb250SW5kZXgpCit7CisJQ1BWVF9Xb3JkUHJvcHMgV29yZFByb3BzOworCVdvcmRQcm9wcy5uRm9udEluZGV4ID0gbkZvbnRJbmRleDsKKwlyZXR1cm4gU2V0UmljaFRleHRQcm9wcyhFUF9GT05USU5ERVgsTlVMTCwmV29yZFByb3BzKTsJCit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFJpY2hGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpCit7CQorCUNQVlRfV29yZFByb3BzIFdvcmRQcm9wczsKKwlXb3JkUHJvcHMuZkZvbnRTaXplID0gZkZvbnRTaXplOworCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX0ZPTlRTSVpFLE5VTEwsJldvcmRQcm9wcyk7CQorfQorCitGWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dENvbG9yKEZYX0NPTE9SUkVGIGR3Q29sb3IpCit7CisJQ1BWVF9Xb3JkUHJvcHMgV29yZFByb3BzOworCVdvcmRQcm9wcy5kd1dvcmRDb2xvciA9IGR3Q29sb3I7CisJcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfV09SRENPTE9SLE5VTEwsJldvcmRQcm9wcyk7CQorfQorCitGWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dFNjcmlwdChGWF9JTlQzMiBuU2NyaXB0VHlwZSkKK3sKKwlDUFZUX1dvcmRQcm9wcyBXb3JkUHJvcHM7CisJV29yZFByb3BzLm5TY3JpcHRUeXBlID0gblNjcmlwdFR5cGU7CisJcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfU0NSSVBUVFlQRSxOVUxMLCZXb3JkUHJvcHMpOwkKK30KKworRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaFRleHRCb2xkKEZYX0JPT0wgYkJvbGQpCit7CisJQ1BWVF9Xb3JkUHJvcHMgV29yZFByb3BzOworCWlmIChiQm9sZCkKKwkJV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9CT0xEOworCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX0JPTEQsTlVMTCwmV29yZFByb3BzKTsKK30KKworRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaFRleHRJdGFsaWMoRlhfQk9PTCBiSXRhbGljKQoreworCUNQVlRfV29yZFByb3BzIFdvcmRQcm9wczsKKwlpZiAoYkl0YWxpYykKKwkJV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9JVEFMSUM7CisJcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfSVRBTElDLE5VTEwsJldvcmRQcm9wcyk7Cit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFJpY2hUZXh0VW5kZXJsaW5lKEZYX0JPT0wgYlVuZGVybGluZSkKK3sKKwlDUFZUX1dvcmRQcm9wcyBXb3JkUHJvcHM7CisJaWYgKGJVbmRlcmxpbmUpCisJCVdvcmRQcm9wcy5uV29yZFN0eWxlIHw9IFBWVFdPUkRfU1RZTEVfVU5ERVJMSU5FOworCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX1VOREVSTElORSxOVUxMLCZXb3JkUHJvcHMpOworfQorCitGWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dENyb3Nzb3V0KEZYX0JPT0wgYkNyb3Nzb3V0KQoreworCUNQVlRfV29yZFByb3BzIFdvcmRQcm9wczsKKwlpZiAoYkNyb3Nzb3V0KQorCQlXb3JkUHJvcHMubldvcmRTdHlsZSB8PSBQVlRXT1JEX1NUWUxFX0NST1NTT1VUOworCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX0NST1NTT1VULE5VTEwsJldvcmRQcm9wcyk7Cit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFJpY2hUZXh0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UpCit7CisJQ1BWVF9Xb3JkUHJvcHMgV29yZFByb3BzOworCVdvcmRQcm9wcy5mQ2hhclNwYWNlID0gZkNoYXJTcGFjZTsKKwlyZXR1cm4gU2V0UmljaFRleHRQcm9wcyhFUF9DSEFSU1BBQ0UsTlVMTCwmV29yZFByb3BzKTsJCit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFJpY2hUZXh0SG9yelNjYWxlKEZYX0lOVDMyIG5Ib3J6U2NhbGUgLyo9IDEwMCovKQoreworCUNQVlRfV29yZFByb3BzIFdvcmRQcm9wczsKKwlXb3JkUHJvcHMubkhvcnpTY2FsZSA9IG5Ib3J6U2NhbGU7CisJcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfSE9SWlNDQUxFLE5VTEwsJldvcmRQcm9wcyk7CQorfQorCitGWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dExpbmVMZWFkaW5nKEZYX0ZMT0FUIGZMaW5lTGVhZGluZykKK3sKKwlDUFZUX1NlY1Byb3BzIFNlY1Byb3BzOworCVNlY1Byb3BzLmZMaW5lTGVhZGluZyA9IGZMaW5lTGVhZGluZzsKKwlyZXR1cm4gU2V0UmljaFRleHRQcm9wcyhFUF9MSU5FTEVBRElORywmU2VjUHJvcHMsTlVMTCk7CQorfQorCitGWF9CT09MIENGWF9FZGl0OjpTZXRSaWNoVGV4dExpbmVJbmRlbnQoRlhfRkxPQVQgZkxpbmVJbmRlbnQpCit7CisJQ1BWVF9TZWNQcm9wcyBTZWNQcm9wczsKKwlTZWNQcm9wcy5mTGluZUluZGVudCA9IGZMaW5lSW5kZW50OworCXJldHVybiBTZXRSaWNoVGV4dFByb3BzKEVQX0xJTkVJTkRFTlQsJlNlY1Byb3BzLE5VTEwpOworfQorCitGWF9CT09MCUNGWF9FZGl0OjpTZXRSaWNoVGV4dEFsaWdubWVudChGWF9JTlQzMiBuQWxpZ25tZW50KQoreworCUNQVlRfU2VjUHJvcHMgU2VjUHJvcHM7CisJU2VjUHJvcHMubkFsaWdubWVudCA9IG5BbGlnbm1lbnQ7CisJcmV0dXJuIFNldFJpY2hUZXh0UHJvcHMoRVBfQUxJR05NRU5ULCZTZWNQcm9wcyxOVUxMKTsKK30KKworRlhfQk9PTCBDRlhfRWRpdDo6U2V0UmljaFRleHRQcm9wcyhFRElUX1BST1BTX0UgZVByb3BzLCBjb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMpCit7CisJRlhfQk9PTCBiU2V0ID0gRkFMU0U7CisJRlhfQk9PTCBiU2V0MSxiU2V0MjsKKwlpZiAobV9wVlQtPklzVmFsaWQoKSAmJiBtX3BWVC0+SXNSaWNoVGV4dCgpKQorCXsKKwkJaWYgKElQREZfVmFyaWFibGVUZXh0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wVlQtPkdldEl0ZXJhdG9yKCkpCisJCXsKKwkJCUNQVlRfV29yZFJhbmdlIHdyVGVtcCA9IG1fU2VsU3RhdGUuQ29udmVydFRvV29yZFJhbmdlKCk7CisJCQkKKwkJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2Uod3JUZW1wLkJlZ2luUG9zKTsKKwkJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2Uod3JUZW1wLkVuZFBvcyk7CisJCQlwSXRlcmF0b3ItPlNldEF0KHdyVGVtcC5CZWdpblBvcyk7CisKKwkJCUJlZ2luR3JvdXBVbmRvKEwiIik7OworCisJCQliU2V0ID0gU2V0U2VjUHJvcHMoZVByb3BzLHdyVGVtcC5CZWdpblBvcyxwU2VjUHJvcHMscFdvcmRQcm9wcyx3clRlbXAsVFJVRSk7CisKKwkJCXdoaWxlIChwSXRlcmF0b3ItPk5leHRXb3JkKCkpCisJCQl7CisJCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7CisJCQkJaWYgKHBsYWNlLldvcmRDbXAod3JUZW1wLkVuZFBvcykgPiAwKSBicmVhazsKKwkJCQliU2V0MSA9IFNldFNlY1Byb3BzKGVQcm9wcyxwbGFjZSxwU2VjUHJvcHMscFdvcmRQcm9wcyx3clRlbXAsVFJVRSk7CisJCQkJYlNldDIgPSBTZXRXb3JkUHJvcHMoZVByb3BzLHBsYWNlLHBXb3JkUHJvcHMsd3JUZW1wLFRSVUUpOworCQkJCQorCQkJCWlmICghYlNldCkKKwkJCQkJYlNldCA9IChiU2V0MSB8fCBiU2V0Mik7CisJCQl9CisKKwkJCUVuZEdyb3VwVW5kbygpOworCisJCQlpZiAoYlNldCkKKwkJCXsKKwkJCQlQYWludFNldFByb3BzKGVQcm9wcyx3clRlbXApOworCQkJfQorCQl9CisJfQkKKworCXJldHVybiBiU2V0OworfQorCit2b2lkIENGWF9FZGl0OjpQYWludFNldFByb3BzKEVESVRfUFJPUFNfRSBlUHJvcHMsIGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IpCit7CisJc3dpdGNoKGVQcm9wcykKKwl7CisJY2FzZSBFUF9MSU5FTEVBRElORzoKKwljYXNlIEVQX0xJTkVJTkRFTlQ6CisJY2FzZSBFUF9BTElHTk1FTlQ6CisJCVJlYXJyYW5nZVBhcnQod3IpOworCQlTY3JvbGxUb0NhcmV0KCk7CisJCVJlZnJlc2goUlBfQU5BTFlTRSk7CisJCVNldENhcmV0T3JpZ2luKCk7CisJCVNldENhcmV0SW5mbygpOwkKKwkJYnJlYWs7CQkJCQkKKwljYXNlIEVQX1dPUkRDT0xPUjoKKwljYXNlIEVQX1VOREVSTElORToKKwljYXNlIEVQX0NST1NTT1VUOgorCQlSZWZyZXNoKFJQX09QVElPTkFMLCZ3cik7CisJCWJyZWFrOworCWNhc2UgRVBfRk9OVElOREVYOgorCWNhc2UgRVBfRk9OVFNJWkU6CisJY2FzZSBFUF9TQ1JJUFRUWVBFOgkJCQkJCisJY2FzZSBFUF9DSEFSU1BBQ0U6CisJY2FzZSBFUF9IT1JaU0NBTEU6CisJY2FzZSBFUF9CT0xEOgorCWNhc2UgRVBfSVRBTElDOgorCQlSZWFycmFuZ2VQYXJ0KHdyKTsKKwkJU2Nyb2xsVG9DYXJldCgpOworCisJCUNQVlRfV29yZFJhbmdlIHdyUmVmcmVzaChtX3BWVC0+R2V0U2VjdGlvbkJlZ2luUGxhY2Uod3IuQmVnaW5Qb3MpLAorCQkJbV9wVlQtPkdldFNlY3Rpb25FbmRQbGFjZSh3ci5FbmRQb3MpKTsKKwkJUmVmcmVzaChSUF9BTkFMWVNFLCZ3clJlZnJlc2gpOworCisJCVNldENhcmV0T3JpZ2luKCk7CisJCVNldENhcmV0SW5mbygpOwkKKwkJYnJlYWs7CisJfQkJCQkKK30KKworRlhfQk9PTCBDRlhfRWRpdDo6U2V0U2VjUHJvcHMoRURJVF9QUk9QU19FIGVQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSwgCisJCQkJCQkJICAgY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzLCAKKwkJCQkJCQkgICBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyLCBGWF9CT09MIGJBZGRVbmRvKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpICYmIG1fcFZULT5Jc1JpY2hUZXh0KCkpCisJeworCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkKKwkJeworCQkJRlhfQk9PTCBiU2V0ID0gRkFMU0U7CisJCQlDUFZUX1NlY3Rpb24gc2VjaW5mbzsKKwkJCUNQVlRfU2VjdGlvbiBPbGRTZWNpbmZvOworCisJCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKworCQkJaWYgKGVQcm9wcyA9PSBFUF9MSU5FTEVBRElORyB8fCBlUHJvcHMgPT0gRVBfTElORUlOREVOVCB8fCBlUHJvcHMgPT0gRVBfQUxJR05NRU5UKQorCQkJeworCQkJCWlmIChwU2VjUHJvcHMpCisJCQkJeworCQkJCQlwSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsKKwkJCQkJaWYgKHBJdGVyYXRvci0+R2V0U2VjdGlvbihzZWNpbmZvKSkKKwkJCQkJeworCQkJCQkJaWYgKGJBZGRVbmRvKSBPbGRTZWNpbmZvID0gc2VjaW5mbzsKKworCQkJCQkJc3dpdGNoKGVQcm9wcykKKwkJCQkJCXsKKwkJCQkJCWNhc2UgRVBfTElORUxFQURJTkc6CQkJCQorCQkJCQkJCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwoc2VjaW5mby5TZWNQcm9wcy5mTGluZUxlYWRpbmcscFNlY1Byb3BzLT5mTGluZUxlYWRpbmcpKQorCQkJCQkJCXsKKwkJCQkJCQkJc2VjaW5mby5TZWNQcm9wcy5mTGluZUxlYWRpbmcgPSBwU2VjUHJvcHMtPmZMaW5lTGVhZGluZzsJCQkJCQkJCisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCQlicmVhazsKKwkJCQkJCWNhc2UgRVBfTElORUlOREVOVDoKKwkJCQkJCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKHNlY2luZm8uU2VjUHJvcHMuZkxpbmVJbmRlbnQscFNlY1Byb3BzLT5mTGluZUluZGVudCkpCisJCQkJCQkJeworCQkJCQkJCQlzZWNpbmZvLlNlY1Byb3BzLmZMaW5lSW5kZW50ID0gcFNlY1Byb3BzLT5mTGluZUluZGVudDsKKwkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJfQorCQkJCQkJCWJyZWFrOworCQkJCQkJY2FzZSBFUF9BTElHTk1FTlQ6CisJCQkJCQkJaWYgKHNlY2luZm8uU2VjUHJvcHMubkFsaWdubWVudCAhPSBwU2VjUHJvcHMtPm5BbGlnbm1lbnQpCisJCQkJCQkJeworCQkJCQkJCQlzZWNpbmZvLlNlY1Byb3BzLm5BbGlnbm1lbnQgPSBwU2VjUHJvcHMtPm5BbGlnbm1lbnQ7CisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCQlicmVhazsKKwkJCQkJCWRlZmF1bHQ6CisJCQkJCQkJYnJlYWs7CisJCQkJCQl9CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJaWYgKHBXb3JkUHJvcHMgJiYgcGxhY2UgPT0gbV9wVlQtPkdldFNlY3Rpb25CZWdpblBsYWNlKHBsYWNlKSkKKwkJCQl7CisJCQkJCXBJdGVyYXRvci0+U2V0QXQocGxhY2UpOworCQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRTZWN0aW9uKHNlY2luZm8pKQorCQkJCQl7CisJCQkJCQlpZiAoYkFkZFVuZG8pIE9sZFNlY2luZm8gPSBzZWNpbmZvOworCisJCQkJCQlzd2l0Y2goZVByb3BzKQorCQkJCQkJeworCQkJCQkJY2FzZSBFUF9GT05USU5ERVg6CQkJCQorCQkJCQkJCWlmIChzZWNpbmZvLldvcmRQcm9wcy5uRm9udEluZGV4ICE9IHBXb3JkUHJvcHMtPm5Gb250SW5kZXgpCisJCQkJCQkJeworCQkJCQkJCQlzZWNpbmZvLldvcmRQcm9wcy5uRm9udEluZGV4ID0gcFdvcmRQcm9wcy0+bkZvbnRJbmRleDsKKwkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJfQorCQkJCQkJCWJyZWFrOworCQkJCQkJY2FzZSBFUF9GT05UU0laRToKKwkJCQkJCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKHNlY2luZm8uV29yZFByb3BzLmZGb250U2l6ZSxwV29yZFByb3BzLT5mRm9udFNpemUpKQorCQkJCQkJCXsKKwkJCQkJCQkJc2VjaW5mby5Xb3JkUHJvcHMuZkZvbnRTaXplID0gcFdvcmRQcm9wcy0+ZkZvbnRTaXplOworCQkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCQl9CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlIEVQX1dPUkRDT0xPUjoKKwkJCQkJCQlpZiAoc2VjaW5mby5Xb3JkUHJvcHMuZHdXb3JkQ29sb3IgIT0gcFdvcmRQcm9wcy0+ZHdXb3JkQ29sb3IpCisJCQkJCQkJeworCQkJCQkJCQlzZWNpbmZvLldvcmRQcm9wcy5kd1dvcmRDb2xvciA9IHBXb3JkUHJvcHMtPmR3V29yZENvbG9yOworCQkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCQl9CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlIEVQX1NDUklQVFRZUEU6CQkJCQorCQkJCQkJCWlmIChzZWNpbmZvLldvcmRQcm9wcy5uU2NyaXB0VHlwZSAhPSBwV29yZFByb3BzLT5uU2NyaXB0VHlwZSkKKwkJCQkJCQl7CisJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5TY3JpcHRUeXBlID0gcFdvcmRQcm9wcy0+blNjcmlwdFR5cGU7CisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCQlicmVhazsKKwkJCQkJCWNhc2UgRVBfQ0hBUlNQQUNFOgkJCQorCQkJCQkJCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwoc2VjaW5mby5Xb3JkUHJvcHMuZkNoYXJTcGFjZSxwV29yZFByb3BzLT5mQ2hhclNwYWNlKSkKKwkJCQkJCQl7CisJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLmZDaGFyU3BhY2UgPSBwV29yZFByb3BzLT5mQ2hhclNwYWNlOworCQkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCQl9CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlIEVQX0hPUlpTQ0FMRToJCQkJCisJCQkJCQkJaWYgKHNlY2luZm8uV29yZFByb3BzLm5Ib3J6U2NhbGUgIT0gcFdvcmRQcm9wcy0+bkhvcnpTY2FsZSkKKwkJCQkJCQl7CisJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Ib3J6U2NhbGUgPSBwV29yZFByb3BzLT5uSG9yelNjYWxlOworCQkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCQl9CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlIEVQX1VOREVSTElORToKKwkJCQkJCQlpZiAocFdvcmRQcm9wcy0+bldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfVU5ERVJMSU5FKQorCQkJCQkJCXsKKwkJCQkJCQkJaWYgKChzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpID09IDApCisJCQkJCQkJCXsKKwkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9VTkRFUkxJTkU7IAorCQkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJCX0KKwkJCQkJCQl9CisJCQkJCQkJZWxzZQorCQkJCQkJCXsKKwkJCQkJCQkJaWYgKChzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpICE9IDApCisJCQkJCQkJCXsKKwkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJj0gflBWVFdPUkRfU1RZTEVfVU5ERVJMSU5FOworCQkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJCX0KKwkJCQkJCQl9CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlIEVQX0NST1NTT1VUOgorCQkJCQkJCWlmIChwV29yZFByb3BzLT5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9DUk9TU09VVCkKKwkJCQkJCQl7CisJCQkJCQkJCWlmICgoc2VjaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQ1JPU1NPVVQpID09IDApCisJCQkJCQkJCXsKKwkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9DUk9TU09VVDsgCisJCQkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCQkJfQorCQkJCQkJCX0KKwkJCQkJCQllbHNlCisJCQkJCQkJeworCQkJCQkJCQlpZiAoKHNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0NST1NTT1VUKSAhPSAwKQorCQkJCQkJCQl7CisJCQkJCQkJCQlzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICY9IH5QVlRXT1JEX1NUWUxFX0NST1NTT1VUOworCQkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJCX0KKwkJCQkJCQl9CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlIEVQX0JPTEQ6CisJCQkJCQkJaWYgKHBXb3JkUHJvcHMtPm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0JPTEQpCisJCQkJCQkJeworCQkJCQkJCQlpZiAoKHNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0JPTEQpID09IDApCisJCQkJCQkJCXsKKwkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9CT0xEOyAKKwkJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCQl9CisJCQkJCQkJfQorCQkJCQkJCWVsc2UKKwkJCQkJCQl7CisJCQkJCQkJCWlmICgoc2VjaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQk9MRCkgIT0gMCkKKwkJCQkJCQkJeworCQkJCQkJCQkJc2VjaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmPSB+UFZUV09SRF9TVFlMRV9CT0xEOworCQkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJCX0KKwkJCQkJCQl9CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlIEVQX0lUQUxJQzoKKwkJCQkJCQlpZiAocFdvcmRQcm9wcy0+bldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfSVRBTElDKQorCQkJCQkJCXsKKwkJCQkJCQkJaWYgKChzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9JVEFMSUMpID09IDApCisJCQkJCQkJCXsKKwkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9JVEFMSUM7IAorCQkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJCX0KKwkJCQkJCQl9CisJCQkJCQkJZWxzZQorCQkJCQkJCXsKKwkJCQkJCQkJaWYgKChzZWNpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9JVEFMSUMpICE9IDApCisJCQkJCQkJCXsKKwkJCQkJCQkJCXNlY2luZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJj0gflBWVFdPUkRfU1RZTEVfSVRBTElDOworCQkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJCX0KKwkJCQkJCQl9CisJCQkJCQkJYnJlYWs7CisJCQkJCQlkZWZhdWx0OgorCQkJCQkJCWJyZWFrOworCQkJCQkJfQorCQkJCQl9CisJCQkJfQorCQkJfQorCisJCQlpZiAoYlNldCkKKwkJCXsKKwkJCQlwSXRlcmF0b3ItPlNldFNlY3Rpb24oc2VjaW5mbyk7CisKKwkJCQlpZiAoYkFkZFVuZG8gJiYgbV9iRW5hYmxlVW5kbykKKwkJCQl7CisJCQkJCUFkZEVkaXRVbmRvSXRlbShuZXcgQ0ZYRVVfU2V0U2VjUHJvcHMKKwkJCQkJCSh0aGlzLHBsYWNlLGVQcm9wcyxPbGRTZWNpbmZvLlNlY1Byb3BzLE9sZFNlY2luZm8uV29yZFByb3BzLHNlY2luZm8uU2VjUHJvcHMsc2VjaW5mby5Xb3JkUHJvcHMsd3IpKTsKKwkJCQl9CisJCQl9CisKKwkJCXBJdGVyYXRvci0+U2V0QXQob2xkcGxhY2UpOworCisJCQlyZXR1cm4gYlNldDsKKwkJfQorCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6OlNldFdvcmRQcm9wcyhFRElUX1BST1BTX0UgZVByb3BzLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlLCAKKwkJCQkJCQkJY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyLCBGWF9CT09MIGJBZGRVbmRvKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpICYmIG1fcFZULT5Jc1JpY2hUZXh0KCkpCisJeworCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkKKwkJeworCQkJRlhfQk9PTCBiU2V0ID0gRkFMU0U7CisJCQlDUFZUX1dvcmQgd29yZGluZm87CisJCQlDUFZUX1dvcmQgT2xkV29yZGluZm87CisKKwkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCisJCQlpZiAocFdvcmRQcm9wcykKKwkJCXsKKwkJCQlwSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsKKwkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKSkKKwkJCQl7CisJCQkJCWlmIChiQWRkVW5kbykgT2xkV29yZGluZm8gPSB3b3JkaW5mbzsKKworCQkJCQlzd2l0Y2goZVByb3BzKQorCQkJCQl7CisJCQkJCWNhc2UgRVBfRk9OVElOREVYOgkJCQkKKwkJCQkJCWlmICh3b3JkaW5mby5Xb3JkUHJvcHMubkZvbnRJbmRleCAhPSBwV29yZFByb3BzLT5uRm9udEluZGV4KQorCQkJCQkJeworCQkJCQkJCWlmIChJRlhfRWRpdF9Gb250TWFwKiBwRm9udE1hcCA9IHRoaXMtPkdldEZvbnRNYXAoKSkKKwkJCQkJCQl7CisJCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5uRm9udEluZGV4ID0gcEZvbnRNYXAtPkdldFdvcmRGb250SW5kZXgod29yZGluZm8uV29yZCx3b3JkaW5mby5uQ2hhcnNldCxwV29yZFByb3BzLT5uRm9udEluZGV4KTsKKwkJCQkJCQl9CisJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQl9CisJCQkJCQlicmVhazsKKwkJCQkJY2FzZSBFUF9GT05UU0laRToKKwkJCQkJCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwod29yZGluZm8uV29yZFByb3BzLmZGb250U2l6ZSxwV29yZFByb3BzLT5mRm9udFNpemUpKQorCQkJCQkJeworCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5mRm9udFNpemUgPSBwV29yZFByb3BzLT5mRm9udFNpemU7CisJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQl9CisJCQkJCQlicmVhazsKKwkJCQkJY2FzZSBFUF9XT1JEQ09MT1I6CisJCQkJCQlpZiAod29yZGluZm8uV29yZFByb3BzLmR3V29yZENvbG9yICE9IHBXb3JkUHJvcHMtPmR3V29yZENvbG9yKQorCQkJCQkJeworCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5kd1dvcmRDb2xvciA9IHBXb3JkUHJvcHMtPmR3V29yZENvbG9yOworCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJfQorCQkJCQkJYnJlYWs7CisJCQkJCWNhc2UgRVBfU0NSSVBUVFlQRToKKwkJCQkJCWlmICh3b3JkaW5mby5Xb3JkUHJvcHMublNjcmlwdFR5cGUgIT0gcFdvcmRQcm9wcy0+blNjcmlwdFR5cGUpCisJCQkJCQl7CisJCQkJCQkJd29yZGluZm8uV29yZFByb3BzLm5TY3JpcHRUeXBlID0gcFdvcmRQcm9wcy0+blNjcmlwdFR5cGU7CisJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQl9CisJCQkJCQlicmVhazsKKwkJCQkJY2FzZSBFUF9DSEFSU1BBQ0U6CisJCQkJCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKHdvcmRpbmZvLldvcmRQcm9wcy5mQ2hhclNwYWNlLHBXb3JkUHJvcHMtPmZDaGFyU3BhY2UpKQorCQkJCQkJeworCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5mQ2hhclNwYWNlID0gcFdvcmRQcm9wcy0+ZkNoYXJTcGFjZTsKKwkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCX0KKwkJCQkJCWJyZWFrOworCQkJCQljYXNlIEVQX0hPUlpTQ0FMRToKKwkJCQkJCWlmICh3b3JkaW5mby5Xb3JkUHJvcHMubkhvcnpTY2FsZSAhPSBwV29yZFByb3BzLT5uSG9yelNjYWxlKQorCQkJCQkJeworCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5uSG9yelNjYWxlID0gcFdvcmRQcm9wcy0+bkhvcnpTY2FsZTsKKwkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCX0KKwkJCQkJCWJyZWFrOworCQkJCQljYXNlIEVQX1VOREVSTElORToKKwkJCQkJCWlmIChwV29yZFByb3BzLT5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpCisJCQkJCQl7CisJCQkJCQkJaWYgKCh3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfVU5ERVJMSU5FKSA9PSAwKQorCQkJCQkJCXsKKwkJCQkJCQkJd29yZGluZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9VTkRFUkxJTkU7CisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCX0KKwkJCQkJCWVsc2UKKwkJCQkJCXsKKwkJCQkJCQlpZiAoKHdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpICE9IDApCisJCQkJCQkJeworCQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmPSB+UFZUV09SRF9TVFlMRV9VTkRFUkxJTkU7CisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCX0KKwkJCQkJCWJyZWFrOworCQkJCQljYXNlIEVQX0NST1NTT1VUOgorCQkJCQkJaWYgKHBXb3JkUHJvcHMtPm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0NST1NTT1VUKQorCQkJCQkJeworCQkJCQkJCWlmICgod29yZGluZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0NST1NTT1VUKSA9PSAwKQorCQkJCQkJCXsKKwkJCQkJCQkJd29yZGluZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgfD0gUFZUV09SRF9TVFlMRV9DUk9TU09VVDsgCisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCX0KKwkJCQkJCWVsc2UKKwkJCQkJCXsKKwkJCQkJCQlpZiAoKHdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9DUk9TU09VVCkgIT0gMCkKKwkJCQkJCQl7CisJCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICY9IH5QVlRXT1JEX1NUWUxFX0NST1NTT1VUOworCQkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCQl9CisJCQkJCQl9CisJCQkJCQlicmVhazsKKwkJCQkJY2FzZSBFUF9CT0xEOgorCQkJCQkJaWYgKHBXb3JkUHJvcHMtPm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0JPTEQpCisJCQkJCQl7CisJCQkJCQkJaWYgKCh3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQk9MRCkgPT0gMCkKKwkJCQkJCQl7CisJCQkJCQkJCXdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlIHw9IFBWVFdPUkRfU1RZTEVfQk9MRDsgCisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCX0KKwkJCQkJCWVsc2UKKwkJCQkJCXsKKwkJCQkJCQlpZiAoKHdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9CT0xEKSAhPSAwKQorCQkJCQkJCXsKKwkJCQkJCQkJd29yZGluZm8uV29yZFByb3BzLm5Xb3JkU3R5bGUgJj0gflBWVFdPUkRfU1RZTEVfQk9MRDsKKwkJCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCQkJfQorCQkJCQkJfQorCQkJCQkJYnJlYWs7CisJCQkJCWNhc2UgRVBfSVRBTElDOgorCQkJCQkJaWYgKHBXb3JkUHJvcHMtPm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0lUQUxJQykKKwkJCQkJCXsKKwkJCQkJCQlpZiAoKHdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9JVEFMSUMpID09IDApCisJCQkJCQkJeworCQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSB8PSBQVlRXT1JEX1NUWUxFX0lUQUxJQzsgCisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCX0KKwkJCQkJCWVsc2UKKwkJCQkJCXsKKwkJCQkJCQlpZiAoKHdvcmRpbmZvLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9JVEFMSUMpICE9IDApCisJCQkJCQkJeworCQkJCQkJCQl3b3JkaW5mby5Xb3JkUHJvcHMubldvcmRTdHlsZSAmPSB+UFZUV09SRF9TVFlMRV9JVEFMSUM7CisJCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJCX0KKwkJCQkJCX0KKwkJCQkJCWJyZWFrOworCQkJCQlkZWZhdWx0OgorCQkJCQkJYnJlYWs7CisJCQkJCX0KKwkJCQl9CisJCQl9CQorCisJCQlpZiAoYlNldCkKKwkJCXsKKwkJCQlwSXRlcmF0b3ItPlNldFdvcmQod29yZGluZm8pOworCisJCQkJaWYgKGJBZGRVbmRvICYmIG1fYkVuYWJsZVVuZG8pCisJCQkJeworCQkJCQlBZGRFZGl0VW5kb0l0ZW0obmV3IENGWEVVX1NldFdvcmRQcm9wcworCQkJCQkJKHRoaXMscGxhY2UsZVByb3BzLE9sZFdvcmRpbmZvLldvcmRQcm9wcyx3b3JkaW5mby5Xb3JkUHJvcHMsd3IpKTsKKwkJCQl9CisJCQl9CisJCQkKKwkJCXBJdGVyYXRvci0+U2V0QXQob2xkcGxhY2UpOworCQkJcmV0dXJuIGJTZXQ7CisJCX0KKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldFRleHQoRlhfTFBDV1NUUiB0ZXh0LEZYX0lOVDMyIGNoYXJzZXQgLyo9IERFRkFVTFRfQ0hBUlNFVCovLAorCQkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyAvKj0gTlVMTCovLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcyAvKj0gTlVMTCovKQoreworCVNldFRleHQodGV4dCxjaGFyc2V0LHBTZWNQcm9wcyxwV29yZFByb3BzLFRSVUUsVFJVRSk7Cit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6Okluc2VydFdvcmQoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0IC8qPSBERUZBVUxUX0NIQVJTRVQqLywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzIC8qPSBOVUxMKi8pCit7CisJcmV0dXJuIEluc2VydFdvcmQod29yZCxjaGFyc2V0LHBXb3JkUHJvcHMsVFJVRSxUUlVFKTsKK30KKworRlhfQk9PTCBDRlhfRWRpdDo6SW5zZXJ0UmV0dXJuKGNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMgLyo9IE5VTEwqLyxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMgLyo9IE5VTEwqLykKK3sKKwlyZXR1cm4gSW5zZXJ0UmV0dXJuKHBTZWNQcm9wcyxwV29yZFByb3BzLFRSVUUsVFJVRSk7Cit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6OkJhY2tzcGFjZSgpCit7CisJcmV0dXJuIEJhY2tzcGFjZShUUlVFLFRSVUUpOworfQorCitGWF9CT09MIENGWF9FZGl0OjpEZWxldGUoKQoreworCXJldHVybiBEZWxldGUoVFJVRSxUUlVFKTsKK30KKworRlhfQk9PTCBDRlhfRWRpdDo6Q2xlYXIoKQoreworCXJldHVybiBDbGVhcihUUlVFLFRSVUUpOworfQorCitGWF9CT09MIENGWF9FZGl0OjpJbnNlcnRUZXh0KEZYX0xQQ1dTVFIgdGV4dCwgRlhfSU5UMzIgY2hhcnNldCAvKj0gREVGQVVMVF9DSEFSU0VUKi8sCisJCQkJCQkJCWNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMgLyo9IE5VTEwqLyxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMgLyo9IE5VTEwqLykKK3sKKwlyZXR1cm4gSW5zZXJ0VGV4dCh0ZXh0LGNoYXJzZXQscFNlY1Byb3BzLHBXb3JkUHJvcHMsVFJVRSxUUlVFKTsKK30KKworRlhfRkxPQVQgQ0ZYX0VkaXQ6OkdldEZvbnRTaXplKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wVlQtPkdldEZvbnRTaXplKCk7Cit9CisKK0ZYX1dPUkQgQ0ZYX0VkaXQ6OkdldFBhc3N3b3JkQ2hhcigpIGNvbnN0Cit7CisJcmV0dXJuIG1fcFZULT5HZXRQYXNzd29yZENoYXIoKTsKK30KKworRlhfSU5UMzIgQ0ZYX0VkaXQ6OkdldENoYXJBcnJheSgpIGNvbnN0Cit7CisJcmV0dXJuIG1fcFZULT5HZXRDaGFyQXJyYXkoKTsKK30KKworQ1BERl9SZWN0IENGWF9FZGl0OjpHZXRQbGF0ZVJlY3QoKSBjb25zdAoreworCXJldHVybiBtX3BWVC0+R2V0UGxhdGVSZWN0KCk7Cit9CisKK0NQREZfUmVjdCBDRlhfRWRpdDo6R2V0Q29udGVudFJlY3QoKSBjb25zdAoreworCXJldHVybiBWVFRvRWRpdChtX3BWVC0+R2V0Q29udGVudFJlY3QoKSk7Cit9CisKK0ZYX0lOVDMyIENGWF9FZGl0OjpHZXRIb3J6U2NhbGUoKSBjb25zdAoreworCXJldHVybiBtX3BWVC0+R2V0SG9yelNjYWxlKCk7Cit9CisKK0ZYX0ZMT0FUIENGWF9FZGl0OjpHZXRDaGFyU3BhY2UoKSBjb25zdAoreworCXJldHVybiBtX3BWVC0+R2V0Q2hhclNwYWNlKCk7Cit9CisKKy8vIGlubmVyIG1ldGhvZHMKKworQ1BWVF9Xb3JkUmFuZ2UgQ0ZYX0VkaXQ6OkdldFdob2xlV29yZFJhbmdlKCkgY29uc3QKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwkJcmV0dXJuIENQVlRfV29yZFJhbmdlKG1fcFZULT5HZXRCZWdpbldvcmRQbGFjZSgpLG1fcFZULT5HZXRFbmRXb3JkUGxhY2UoKSk7CisKKwlyZXR1cm4gQ1BWVF9Xb3JkUmFuZ2UoKTsKK30KKworQ1BWVF9Xb3JkUmFuZ2UgQ0ZYX0VkaXQ6OkdldFZpc2libGVXb3JkUmFuZ2UoKSBjb25zdAoreworCWlmIChtX2JFbmFibGVPdmVyZmxvdykgcmV0dXJuIEdldFdob2xlV29yZFJhbmdlKCk7CisKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCUNQREZfUmVjdCByY1BsYXRlID0gbV9wVlQtPkdldFBsYXRlUmVjdCgpOworCisJCUNQVlRfV29yZFBsYWNlIHBsYWNlMSA9IG1fcFZULT5TZWFyY2hXb3JkUGxhY2UoRWRpdFRvVlQoQ1BERl9Qb2ludChyY1BsYXRlLmxlZnQscmNQbGF0ZS50b3ApKSk7CisJCUNQVlRfV29yZFBsYWNlIHBsYWNlMiA9IG1fcFZULT5TZWFyY2hXb3JkUGxhY2UoRWRpdFRvVlQoQ1BERl9Qb2ludChyY1BsYXRlLnJpZ2h0LHJjUGxhdGUuYm90dG9tKSkpOworCisJCXJldHVybiBDUFZUX1dvcmRSYW5nZShwbGFjZTEscGxhY2UyKTsKKwl9CisKKwlyZXR1cm4gQ1BWVF9Xb3JkUmFuZ2UoKTsKK30KKworQ1BWVF9Xb3JkUGxhY2UgQ0ZYX0VkaXQ6OlNlYXJjaFdvcmRQbGFjZShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3QKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCXJldHVybiBtX3BWVC0+U2VhcmNoV29yZFBsYWNlKEVkaXRUb1ZUKHBvaW50KSk7CisJfQorCisJcmV0dXJuIENQVlRfV29yZFBsYWNlKCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlBhaW50KCkKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCVJlYXJyYW5nZUFsbCgpOworCQlTY3JvbGxUb0NhcmV0KCk7CisJCVJlZnJlc2goUlBfTk9BTkFMWVNFKTsKKwkJU2V0Q2FyZXRPcmlnaW4oKTsKKwkJU2V0Q2FyZXRJbmZvKCk7CisJfQorfQorCit2b2lkIENGWF9FZGl0OjpSZWFycmFuZ2VBbGwoKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZShtX3dwQ2FyZXQpOworCQltX3BWVC0+UmVhcnJhbmdlQWxsKCk7CisJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2UobV93cENhcmV0KTsKKwkJU2V0U2Nyb2xsSW5mbygpOworCQlTZXRDb250ZW50Q2hhbmdlZCgpOworCX0KK30KKwordm9pZCBDRlhfRWRpdDo6UmVhcnJhbmdlUGFydChjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHJhbmdlKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZShtX3dwQ2FyZXQpOworCQltX3BWVC0+UmVhcnJhbmdlUGFydChyYW5nZSk7CisJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2UobV93cENhcmV0KTsKKwkJU2V0U2Nyb2xsSW5mbygpOworCQlTZXRDb250ZW50Q2hhbmdlZCgpOworCX0KK30KKwordm9pZCBDRlhfRWRpdDo6U2V0Q29udGVudENoYW5nZWQoKQoreworCWlmIChtX2JOb3RpZnkgJiYgbV9wTm90aWZ5KQorCXsKKwkJQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOworCQlpZiAocmNDb250ZW50LldpZHRoKCkgIT0gbV9yY09sZENvbnRlbnQuV2lkdGgoKSB8fAorCQkJcmNDb250ZW50LkhlaWdodCgpICE9IG1fcmNPbGRDb250ZW50LkhlaWdodCgpKQorCQl7CisJCQlpZiAoIW1fYk5vdGlmeUZsYWcpCisJCQl7CisJCQkJbV9iTm90aWZ5RmxhZyA9IFRSVUU7CisJCQkJbV9wTm90aWZ5LT5JT25Db250ZW50Q2hhbmdlKHJjQ29udGVudCk7CisJCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOworCQkJfQorCQkJbV9yY09sZENvbnRlbnQgPSByY0NvbnRlbnQ7CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNlbGVjdEFsbCgpCit7CisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJeworCQltX1NlbFN0YXRlID0gR2V0V2hvbGVXb3JkUmFuZ2UoKTsJCQorCQlTZXRDYXJldChtX1NlbFN0YXRlLkVuZFBvcyk7CQkKKwkJCisJCVNjcm9sbFRvQ2FyZXQoKTsKKwkJQ1BWVF9Xb3JkUmFuZ2Ugd3JWaXNpYmxlID0gR2V0VmlzaWJsZVdvcmRSYW5nZSgpOworCQlSZWZyZXNoKFJQX09QVElPTkFMLCZ3clZpc2libGUpOworCQlTZXRDYXJldEluZm8oKTsKKwl9Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNlbGVjdE5vbmUoKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQorCQl7CisJCQlDUFZUX1dvcmRSYW5nZSB3clRlbXAgPSBtX1NlbFN0YXRlLkNvbnZlcnRUb1dvcmRSYW5nZSgpOworCQkJbV9TZWxTdGF0ZS5EZWZhdWx0KCk7CisJCQlSZWZyZXNoKFJQX09QVElPTkFMLCZ3clRlbXApOworCQl9CisJfQkKK30KKworRlhfQk9PTAlDRlhfRWRpdDo6SXNTZWxlY3RlZCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fU2VsU3RhdGUuSXNFeGlzdCgpOworfQorCitDUERGX1BvaW50IENGWF9FZGl0OjpWVFRvRWRpdChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0Cit7CisJQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOworCUNQREZfUmVjdCByY1BsYXRlID0gbV9wVlQtPkdldFBsYXRlUmVjdCgpOworCisJRlhfRkxPQVQgZlBhZGRpbmcgPSAwLjBmOworCisJc3dpdGNoIChtX25BbGlnbm1lbnQpCisJeworCWNhc2UgMDoKKwkJZlBhZGRpbmcgPSAwLjBmOworCQlicmVhazsKKwljYXNlIDE6CisJCWZQYWRkaW5nID0gKHJjUGxhdGUuSGVpZ2h0KCkgLSByY0NvbnRlbnQuSGVpZ2h0KCkpICogMC41ZjsKKwkJYnJlYWs7CisJY2FzZSAyOgorCQlmUGFkZGluZyA9IHJjUGxhdGUuSGVpZ2h0KCkgLSByY0NvbnRlbnQuSGVpZ2h0KCk7CisJCWJyZWFrOworCX0KKwkKKwlyZXR1cm4gQ1BERl9Qb2ludChwb2ludC54IC0gKG1fcHRTY3JvbGxQb3MueCAtIHJjUGxhdGUubGVmdCksCisJCXBvaW50LnkgLSAobV9wdFNjcm9sbFBvcy55ICsgZlBhZGRpbmcgLSByY1BsYXRlLnRvcCkpOworfQorCitDUERGX1BvaW50IENGWF9FZGl0OjpFZGl0VG9WVChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0Cit7CisJQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOworCUNQREZfUmVjdCByY1BsYXRlID0gbV9wVlQtPkdldFBsYXRlUmVjdCgpOworCisJRlhfRkxPQVQgZlBhZGRpbmcgPSAwLjBmOworCisJc3dpdGNoIChtX25BbGlnbm1lbnQpCisJeworCWNhc2UgMDoKKwkJZlBhZGRpbmcgPSAwLjBmOworCQlicmVhazsKKwljYXNlIDE6CisJCWZQYWRkaW5nID0gKHJjUGxhdGUuSGVpZ2h0KCkgLSByY0NvbnRlbnQuSGVpZ2h0KCkpICogMC41ZjsKKwkJYnJlYWs7CisJY2FzZSAyOgorCQlmUGFkZGluZyA9IHJjUGxhdGUuSGVpZ2h0KCkgLSByY0NvbnRlbnQuSGVpZ2h0KCk7CisJCWJyZWFrOworCX0KKworCXJldHVybiBDUERGX1BvaW50KHBvaW50LnggKyAobV9wdFNjcm9sbFBvcy54IC0gcmNQbGF0ZS5sZWZ0KSwKKwkJcG9pbnQueSArIChtX3B0U2Nyb2xsUG9zLnkgKyBmUGFkZGluZyAtIHJjUGxhdGUudG9wKSk7Cit9CisKK0NQREZfUmVjdCBDRlhfRWRpdDo6VlRUb0VkaXQoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgY29uc3QKK3sKKwlDUERGX1BvaW50IHB0TGVmdEJvdHRvbSA9IFZUVG9FZGl0KENQREZfUG9pbnQocmVjdC5sZWZ0LHJlY3QuYm90dG9tKSk7CisJQ1BERl9Qb2ludCBwdFJpZ2h0VG9wID0gVlRUb0VkaXQoQ1BERl9Qb2ludChyZWN0LnJpZ2h0LHJlY3QudG9wKSk7CisKKwlyZXR1cm4gQ1BERl9SZWN0KHB0TGVmdEJvdHRvbS54LHB0TGVmdEJvdHRvbS55LHB0UmlnaHRUb3AueCxwdFJpZ2h0VG9wLnkpOworfQorCitDUERGX1JlY3QgQ0ZYX0VkaXQ6OkVkaXRUb1ZUKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpIGNvbnN0Cit7CisJQ1BERl9Qb2ludCBwdExlZnRCb3R0b20gPSBFZGl0VG9WVChDUERGX1BvaW50KHJlY3QubGVmdCxyZWN0LmJvdHRvbSkpOworCUNQREZfUG9pbnQgcHRSaWdodFRvcCA9IEVkaXRUb1ZUKENQREZfUG9pbnQocmVjdC5yaWdodCxyZWN0LnRvcCkpOworCisJcmV0dXJuIENQREZfUmVjdChwdExlZnRCb3R0b20ueCxwdExlZnRCb3R0b20ueSxwdFJpZ2h0VG9wLngscHRSaWdodFRvcC55KTsKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0U2Nyb2xsSW5mbygpCit7CisJaWYgKG1fYk5vdGlmeSAmJiBtX3BOb3RpZnkpCisJeworCQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcFZULT5HZXRQbGF0ZVJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOworCisJCWlmICghbV9iTm90aWZ5RmxhZykKKwkJeworCQkJbV9iTm90aWZ5RmxhZyA9IFRSVUU7CisJCQltX3BOb3RpZnktPklPblNldFNjcm9sbEluZm9YKHJjUGxhdGUubGVmdCwgcmNQbGF0ZS5yaWdodCwgCisJCQkJCQkJCXJjQ29udGVudC5sZWZ0LCByY0NvbnRlbnQucmlnaHQsIHJjUGxhdGUuV2lkdGgoKSAvIDMsIHJjUGxhdGUuV2lkdGgoKSk7CisJCQkKKwkJCW1fcE5vdGlmeS0+SU9uU2V0U2Nyb2xsSW5mb1kocmNQbGF0ZS5ib3R0b20sIHJjUGxhdGUudG9wLCAKKwkJCQkJcmNDb250ZW50LmJvdHRvbSwgcmNDb250ZW50LnRvcCwgcmNQbGF0ZS5IZWlnaHQoKSAvIDMsIHJjUGxhdGUuSGVpZ2h0KCkpOworCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOworCQl9CisJfQorfQorCit2b2lkIENGWF9FZGl0OjpTZXRTY3JvbGxQb3NYKEZYX0ZMT0FUIGZ4KQoreworCWlmICghbV9iRW5hYmxlU2Nyb2xsKSByZXR1cm47CisKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwobV9wdFNjcm9sbFBvcy54LGZ4KSkKKwkJeworCQkJbV9wdFNjcm9sbFBvcy54ID0gZng7CQkJCisJCQlSZWZyZXNoKFJQX05PQU5BTFlTRSk7CisKKwkJCWlmIChtX2JOb3RpZnkgJiYgbV9wTm90aWZ5KQorCQkJeworCQkJCWlmICghbV9iTm90aWZ5RmxhZykKKwkJCQl7CisJCQkJCW1fYk5vdGlmeUZsYWcgPSBUUlVFOworCQkJCQltX3BOb3RpZnktPklPblNldFNjcm9sbFBvc1goZngpOworCQkJCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7CisJCQkJfQorCQkJfQorCQl9CisJfQorfQorCit2b2lkIENGWF9FZGl0OjpTZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KQoreworCWlmICghbV9iRW5hYmxlU2Nyb2xsKSByZXR1cm47CisKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwobV9wdFNjcm9sbFBvcy55LGZ5KSkKKwkJewkJCQkKKwkJCW1fcHRTY3JvbGxQb3MueSA9IGZ5OworCQkJUmVmcmVzaChSUF9OT0FOQUxZU0UpOworCisJCQlpZiAobV9iTm90aWZ5ICYmIG1fcE5vdGlmeSkKKwkJCXsKKwkJCQlpZiAoIW1fYk5vdGlmeUZsYWcpCisJCQkJeworCQkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsKKwkJCQkJbV9wTm90aWZ5LT5JT25TZXRTY3JvbGxQb3NZKGZ5KTsKKwkJCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOworCQkJCX0KKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBDRlhfRWRpdDo6U2V0U2Nyb2xsUG9zKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkKK3sKKwlTZXRTY3JvbGxQb3NYKHBvaW50LngpOworCVNldFNjcm9sbFBvc1kocG9pbnQueSk7CisJU2V0U2Nyb2xsTGltaXQoKTsKKwlTZXRDYXJldEluZm8oKTsKK30KKworQ1BERl9Qb2ludCBDRlhfRWRpdDo6R2V0U2Nyb2xsUG9zKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wdFNjcm9sbFBvczsKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0U2Nyb2xsTGltaXQoKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOworCQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcFZULT5HZXRQbGF0ZVJlY3QoKTsKKworCQlpZiAocmNQbGF0ZS5XaWR0aCgpID4gcmNDb250ZW50LldpZHRoKCkpCisJCXsKKwkJCVNldFNjcm9sbFBvc1gocmNQbGF0ZS5sZWZ0KTsKKwkJfQorCQllbHNlCisJCXsKKwkJCWlmIChGWF9FRElUX0lzRmxvYXRTbWFsbGVyKG1fcHRTY3JvbGxQb3MueCwgcmNDb250ZW50LmxlZnQpKQorCQkJeworCQkJCVNldFNjcm9sbFBvc1gocmNDb250ZW50LmxlZnQpOwkJCQorCQkJfQorCQkJZWxzZSBpZiAoRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKG1fcHRTY3JvbGxQb3MueCwgcmNDb250ZW50LnJpZ2h0IC0gcmNQbGF0ZS5XaWR0aCgpKSkKKwkJCXsKKwkJCQlTZXRTY3JvbGxQb3NYKHJjQ29udGVudC5yaWdodCAtIHJjUGxhdGUuV2lkdGgoKSk7CisJCQl9CisJCX0KKworCQlpZiAocmNQbGF0ZS5IZWlnaHQoKSA+IHJjQ29udGVudC5IZWlnaHQoKSkKKwkJeworCQkJU2V0U2Nyb2xsUG9zWShyY1BsYXRlLnRvcCk7CisJCX0KKwkJZWxzZQkJCisJCXsKKwkJCWlmIChGWF9FRElUX0lzRmxvYXRTbWFsbGVyKG1fcHRTY3JvbGxQb3MueSwgcmNDb250ZW50LmJvdHRvbSArIHJjUGxhdGUuSGVpZ2h0KCkpKQorCQkJeworCQkJCVNldFNjcm9sbFBvc1kocmNDb250ZW50LmJvdHRvbSArIHJjUGxhdGUuSGVpZ2h0KCkpOworCQkJfQorCQkJZWxzZSBpZiAoRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKG1fcHRTY3JvbGxQb3MueSwgcmNDb250ZW50LnRvcCkpCisJCQl7CisJCQkJU2V0U2Nyb2xsUG9zWShyY0NvbnRlbnQudG9wKTsKKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBDRlhfRWRpdDo6U2Nyb2xsVG9DYXJldCgpCit7CisJU2V0U2Nyb2xsTGltaXQoKTsKKworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJQ1BERl9Qb2ludCBwdEhlYWQoMCwwKTsKKwkJQ1BERl9Qb2ludCBwdEZvb3QoMCwwKTsKKworCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkKKwkJeworCQkJcEl0ZXJhdG9yLT5TZXRBdChtX3dwQ2FyZXQpOworCisJCQlDUFZUX1dvcmQgd29yZDsKKwkJCUNQVlRfTGluZSBsaW5lOworCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCXsKKwkJCQlwdEhlYWQueCA9IHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aDsKKwkJCQlwdEhlYWQueSA9IHdvcmQucHRXb3JkLnkgKyB3b3JkLmZBc2NlbnQ7CisJCQkJcHRGb290LnggPSB3b3JkLnB0V29yZC54ICsgd29yZC5mV2lkdGg7CisJCQkJcHRGb290LnkgPSB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudDsKKwkJCX0KKwkJCWVsc2UgaWYgKHBJdGVyYXRvci0+R2V0TGluZShsaW5lKSkKKwkJCXsJCQkJCisJCQkJcHRIZWFkLnggPSBsaW5lLnB0TGluZS54OworCQkJCXB0SGVhZC55ID0gbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVBc2NlbnQ7CisJCQkJcHRGb290LnggPSBsaW5lLnB0TGluZS54OworCQkJCXB0Rm9vdC55ID0gbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVEZXNjZW50OworCQkJfQorCQl9CisKKwkJQ1BERl9Qb2ludCBwdEhlYWRFZGl0ID0gVlRUb0VkaXQocHRIZWFkKTsKKwkJQ1BERl9Qb2ludCBwdEZvb3RFZGl0ID0gVlRUb0VkaXQocHRGb290KTsKKworCQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcFZULT5HZXRQbGF0ZVJlY3QoKTsKKworCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKHJjUGxhdGUubGVmdCxyY1BsYXRlLnJpZ2h0KSkKKwkJeworCQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocHRIZWFkRWRpdC54LCByY1BsYXRlLmxlZnQpIHx8CisJCQkJRlhfRURJVF9Jc0Zsb2F0RXF1YWwocHRIZWFkRWRpdC54LCByY1BsYXRlLmxlZnQpKQorCQkJeworCQkJCVNldFNjcm9sbFBvc1gocHRIZWFkLngpOworCQkJfQorCQkJZWxzZSBpZiAoRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKHB0SGVhZEVkaXQueCwgcmNQbGF0ZS5yaWdodCkpCisJCQl7CisJCQkJU2V0U2Nyb2xsUG9zWChwdEhlYWQueCAtIHJjUGxhdGUuV2lkdGgoKSk7CisJCQl9CisJCX0KKworCQlpZiAoIUZYX0VESVRfSXNGbG9hdEVxdWFsKHJjUGxhdGUudG9wLHJjUGxhdGUuYm90dG9tKSkKKwkJeworCQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocHRGb290RWRpdC55LCByY1BsYXRlLmJvdHRvbSkgfHwKKwkJCQlGWF9FRElUX0lzRmxvYXRFcXVhbChwdEZvb3RFZGl0LnksIHJjUGxhdGUuYm90dG9tKSkKKwkJCXsKKwkJCQlpZiAoRlhfRURJVF9Jc0Zsb2F0U21hbGxlcihwdEhlYWRFZGl0LnksIHJjUGxhdGUudG9wKSkKKwkJCQl7CisJCQkJCVNldFNjcm9sbFBvc1kocHRGb290LnkgKyByY1BsYXRlLkhlaWdodCgpKTsKKwkJCQl9CisJCQl9CisJCQllbHNlIGlmIChGWF9FRElUX0lzRmxvYXRCaWdnZXIocHRIZWFkRWRpdC55LCByY1BsYXRlLnRvcCkpCisJCQl7CisJCQkJaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihwdEZvb3RFZGl0LnksIHJjUGxhdGUuYm90dG9tKSkKKwkJCQl7CisJCQkJCVNldFNjcm9sbFBvc1kocHRIZWFkLnkpOworCQkJCX0KKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBDRlhfRWRpdDo6UmVmcmVzaChSRUZSRVNIX1BMQU5fRSBlUGxhbixjb25zdCBDUFZUX1dvcmRSYW5nZSAqIHBSYW5nZTEsY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UyKQoreworCWlmIChtX2JFbmFibGVSZWZyZXNoICYmIG1fcFZULT5Jc1ZhbGlkKCkpCisJeworCQltX1JlZnJlc2guQmVnaW5SZWZyZXNoKCk7CisJCVJlZnJlc2hQdXNoTGluZVJlY3RzKEdldFZpc2libGVXb3JkUmFuZ2UoKSk7CisKKy8vIAkJaWYgKCFGWF9FRElUX0lzRmxvYXRFcXVhbChtX3B0UmVmcmVzaFNjcm9sbFBvcy54LG1fcHRTY3JvbGxQb3MueCkgfHwgCisvLyAJCQkhRlhfRURJVF9Jc0Zsb2F0RXF1YWwobV9wdFJlZnJlc2hTY3JvbGxQb3MueSxtX3B0U2Nyb2xsUG9zLnkpKQorLy8gCQl7CisJCQltX1JlZnJlc2guTm9BbmFseXNlKCk7CisJCQltX3B0UmVmcmVzaFNjcm9sbFBvcyA9IG1fcHRTY3JvbGxQb3M7CisvLyAJCX0KKy8vIAkJZWxzZQorLy8gCQl7CisvLyAJCQlzd2l0Y2ggKGVQbGFuKQorLy8gCQkJeworLy8gCQkJY2FzZSBSUF9BTkFMWVNFOgorLy8gCQkJCW1fUmVmcmVzaC5BbmFseXNlKG1fcFZULT5HZXRBbGlnbm1lbnQoKSk7CisvLyAKKy8vIAkJCQlpZiAocFJhbmdlMSkgUmVmcmVzaFB1c2hSYW5kb21SZWN0cygqcFJhbmdlMSk7CisvLyAJCQkJaWYgKHBSYW5nZTIpIFJlZnJlc2hQdXNoUmFuZG9tUmVjdHMoKnBSYW5nZTIpOworLy8gCQkJCWJyZWFrOworLy8gCQkJY2FzZSBSUF9OT0FOQUxZU0U6CisvLyAJCQkJbV9SZWZyZXNoLk5vQW5hbHlzZSgpOworLy8gCQkJCWJyZWFrOworLy8gCQkJY2FzZSBSUF9PUFRJT05BTDoKKy8vIAkJCQlpZiAocFJhbmdlMSkgUmVmcmVzaFB1c2hSYW5kb21SZWN0cygqcFJhbmdlMSk7CisvLyAJCQkJaWYgKHBSYW5nZTIpIFJlZnJlc2hQdXNoUmFuZG9tUmVjdHMoKnBSYW5nZTIpOworLy8gCQkJCWJyZWFrOwkKKy8vIAkJCX0KKy8vIAkJfQkJCisKKwkJaWYgKG1fYk5vdGlmeSAmJiBtX3BOb3RpZnkpCisJCXsKKwkJCWlmICghbV9iTm90aWZ5RmxhZykKKwkJCXsKKwkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsKKwkJCQlpZiAoY29uc3QgQ0ZYX0VkaXRfUmVjdEFycmF5ICogcFJlY3RzID0gbV9SZWZyZXNoLkdldFJlZnJlc2hSZWN0cygpKQorCQkJCXsKKwkJCQkJZm9yIChGWF9JTlQzMiBpID0gMCwgc3ogPSBwUmVjdHMtPkdldFNpemUoKTsgaSA8IHN6OyBpKyspCisJCQkJCQltX3BOb3RpZnktPklPbkludmFsaWRhdGVSZWN0KHBSZWN0cy0+R2V0QXQoaSkpOworCQkJCX0KKwkJCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7CisJCQl9CisJCX0KKworCQltX1JlZnJlc2guRW5kUmVmcmVzaCgpOworCX0KK30KKwordm9pZCBDRlhfRWRpdDo6UmVmcmVzaFB1c2hMaW5lUmVjdHMoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3cikKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQorCQl7CisJCQlDUFZUX1dvcmRQbGFjZSB3cEJlZ2luID0gd3IuQmVnaW5Qb3M7CisJCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdwQmVnaW4pOworCQkJQ1BWVF9Xb3JkUGxhY2Ugd3BFbmQgPSB3ci5FbmRQb3M7CisJCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdwRW5kKTsKKwkJCXBJdGVyYXRvci0+U2V0QXQod3BCZWdpbik7CisKKwkJCUNQVlRfTGluZSBsaW5laW5mbzsJCisJCQlkbworCQkJeworCQkJCWlmICghcEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmVpbmZvKSlicmVhazsKKwkJCQlpZiAobGluZWluZm8ubGluZXBsYWNlLkxpbmVDbXAod3BFbmQpID4gMClicmVhazsKKworCQkJCUNQREZfUmVjdCByY0xpbmUobGluZWluZm8ucHRMaW5lLngsCisJCQkJCQkJCQlsaW5laW5mby5wdExpbmUueSArIGxpbmVpbmZvLmZMaW5lRGVzY2VudCwKKwkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS54ICsgbGluZWluZm8uZkxpbmVXaWR0aCwKKwkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS55ICsgbGluZWluZm8uZkxpbmVBc2NlbnQpOworCisJCQkJbV9SZWZyZXNoLlB1c2goQ1BWVF9Xb3JkUmFuZ2UobGluZWluZm8ubGluZXBsYWNlLGxpbmVpbmZvLmxpbmVFbmQpLFZUVG9FZGl0KHJjTGluZSkpOworCisJCQl9d2hpbGUgKHBJdGVyYXRvci0+TmV4dExpbmUoKSk7CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlJlZnJlc2hQdXNoUmFuZG9tUmVjdHMoY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgJiB3cikKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQorCQl7CisJCQlDUFZUX1dvcmRSYW5nZSB3clRlbXAgPSB3cjsKKworCQkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZSh3clRlbXAuQmVnaW5Qb3MpOworCQkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZSh3clRlbXAuRW5kUG9zKTsKKwkJCXBJdGVyYXRvci0+U2V0QXQod3JUZW1wLkJlZ2luUG9zKTsKKworCQkJQ1BWVF9Xb3JkIHdvcmRpbmZvOwkKKwkJCUNQVlRfTGluZSBsaW5laW5mbzsJCisJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZTsKKworCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkKKwkJCXsKKwkJCQlwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKwkJCQlpZiAocGxhY2UuV29yZENtcCh3clRlbXAuRW5kUG9zKSA+IDApIGJyZWFrOworCQkJCQkJCisJCQkJcEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKTsKKwkJCQlwSXRlcmF0b3ItPkdldExpbmUobGluZWluZm8pOworCisJCQkJaWYgKHBsYWNlLkxpbmVDbXAod3JUZW1wLkJlZ2luUG9zKSA9PSAwIHx8IHBsYWNlLkxpbmVDbXAod3JUZW1wLkVuZFBvcykgPT0gMCkKKwkJCQl7CisJCQkJCUNQREZfUmVjdCByY1dvcmQod29yZGluZm8ucHRXb3JkLngsCisJCQkJCQkJCQkJbGluZWluZm8ucHRMaW5lLnkgKyBsaW5laW5mby5mTGluZURlc2NlbnQsCisJCQkJCQkJCQkJd29yZGluZm8ucHRXb3JkLnggKyB3b3JkaW5mby5mV2lkdGgsCisJCQkJCQkJCQkJbGluZWluZm8ucHRMaW5lLnkgKyBsaW5laW5mby5mTGluZUFzY2VudCk7CisKKwkJCQkJbV9SZWZyZXNoLkFkZFJlZnJlc2goVlRUb0VkaXQocmNXb3JkKSk7CisJCQkJfQorCQkJCWVsc2UKKwkJCQl7CQkKKwkJCQkJQ1BERl9SZWN0IHJjTGluZShsaW5laW5mby5wdExpbmUueCwKKwkJCQkJCQkJCQlsaW5laW5mby5wdExpbmUueSArIGxpbmVpbmZvLmZMaW5lRGVzY2VudCwKKwkJCQkJCQkJCQlsaW5laW5mby5wdExpbmUueCArIGxpbmVpbmZvLmZMaW5lV2lkdGgsCisJCQkJCQkJCQkJbGluZWluZm8ucHRMaW5lLnkgKyBsaW5laW5mby5mTGluZUFzY2VudCk7CisKKwkJCQkJbV9SZWZyZXNoLkFkZFJlZnJlc2goVlRUb0VkaXQocmNMaW5lKSk7CisKKwkJCQkJcEl0ZXJhdG9yLT5OZXh0TGluZSgpOworCQkJCX0KKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBDRlhfRWRpdDo6UmVmcmVzaFdvcmRSYW5nZShjb25zdCBDUFZUX1dvcmRSYW5nZSYgd3IpCit7CisJaWYgKElQREZfVmFyaWFibGVUZXh0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wVlQtPkdldEl0ZXJhdG9yKCkpCisJeworCQlDUFZUX1dvcmRSYW5nZSB3clRlbXAgPSB3cjsKKworCQltX3BWVC0+VXBkYXRlV29yZFBsYWNlKHdyVGVtcC5CZWdpblBvcyk7CisJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2Uod3JUZW1wLkVuZFBvcyk7CisJCXBJdGVyYXRvci0+U2V0QXQod3JUZW1wLkJlZ2luUG9zKTsKKworCQlDUFZUX1dvcmQgd29yZGluZm87CQorCQlDUFZUX0xpbmUgbGluZWluZm87CQorCQlDUFZUX1dvcmRQbGFjZSBwbGFjZTsKKworCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQorCQl7CisJCQlwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKwkJCWlmIChwbGFjZS5Xb3JkQ21wKHdyVGVtcC5FbmRQb3MpID4gMCkgYnJlYWs7CisJCQkJCQorCQkJcEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKTsKKwkJCXBJdGVyYXRvci0+R2V0TGluZShsaW5laW5mbyk7CisKKwkJCWlmIChwbGFjZS5MaW5lQ21wKHdyVGVtcC5CZWdpblBvcykgPT0gMCB8fCBwbGFjZS5MaW5lQ21wKHdyVGVtcC5FbmRQb3MpID09IDApCisJCQl7CisJCQkJQ1BERl9SZWN0IHJjV29yZCh3b3JkaW5mby5wdFdvcmQueCwKKwkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS55ICsgbGluZWluZm8uZkxpbmVEZXNjZW50LAorCQkJCQkJCQkJd29yZGluZm8ucHRXb3JkLnggKyB3b3JkaW5mby5mV2lkdGgsCisJCQkJCQkJCQlsaW5laW5mby5wdExpbmUueSArIGxpbmVpbmZvLmZMaW5lQXNjZW50KTsKKworCQkJCWlmIChtX2JOb3RpZnkgJiYgbV9wTm90aWZ5KQorCQkJCXsKKwkJCQkJaWYgKCFtX2JOb3RpZnlGbGFnKQorCQkJCQl7CisJCQkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsKKwkJCQkJCUNQREZfUmVjdCByY1JlZnJlc2ggPSBWVFRvRWRpdChyY1dvcmQpOworCQkJCQkJbV9wTm90aWZ5LT5JT25JbnZhbGlkYXRlUmVjdCgmcmNSZWZyZXNoKTsKKwkJCQkJCW1fYk5vdGlmeUZsYWcgPSBGQUxTRTsKKwkJCQkJfQorCQkJCX0KKwkJCX0KKwkJCWVsc2UKKwkJCXsJCQorCQkJCUNQREZfUmVjdCByY0xpbmUobGluZWluZm8ucHRMaW5lLngsCisJCQkJCQkJCQlsaW5laW5mby5wdExpbmUueSArIGxpbmVpbmZvLmZMaW5lRGVzY2VudCwKKwkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS54ICsgbGluZWluZm8uZkxpbmVXaWR0aCwKKwkJCQkJCQkJCWxpbmVpbmZvLnB0TGluZS55ICsgbGluZWluZm8uZkxpbmVBc2NlbnQpOworCisJCQkJaWYgKG1fYk5vdGlmeSAmJiBtX3BOb3RpZnkpCisJCQkJeworCQkJCQlpZiAoIW1fYk5vdGlmeUZsYWcpCisJCQkJCXsKKwkJCQkJCW1fYk5vdGlmeUZsYWcgPSBUUlVFOworCQkJCQkJQ1BERl9SZWN0IHJjUmVmcmVzaCA9IFZUVG9FZGl0KHJjTGluZSk7CisJCQkJCQltX3BOb3RpZnktPklPbkludmFsaWRhdGVSZWN0KCZyY1JlZnJlc2gpOworCQkJCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOworCQkJCQl9CisJCQkJfQorCisJCQkJcEl0ZXJhdG9yLT5OZXh0TGluZSgpOworCQkJfQorCQl9CisJfQorfQorCit2b2lkIENGWF9FZGl0OjpTZXRDYXJldChjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKQoreworCW1fd3BPbGRDYXJldCA9IG1fd3BDYXJldDsgCisJbV93cENhcmV0ID0gcGxhY2U7CQorfQorCit2b2lkIENGWF9FZGl0OjpTZXRDYXJldEluZm8oKQoreworCWlmIChtX2JOb3RpZnkgJiYgbV9wTm90aWZ5KQorCXsKKwkJaWYgKCFtX2JOb3RpZnlGbGFnKQorCQl7CisJCQlDUERGX1BvaW50IHB0SGVhZCgwLjBmLDAuMGYpLHB0Rm9vdCgwLjBmLDAuMGYpOworCisJCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkKKwkJCXsKKwkJCQlwSXRlcmF0b3ItPlNldEF0KG1fd3BDYXJldCk7CisJCQkJQ1BWVF9Xb3JkIHdvcmQ7CisJCQkJQ1BWVF9MaW5lIGxpbmU7CisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCXB0SGVhZC54ID0gd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoOworCQkJCQlwdEhlYWQueSA9IHdvcmQucHRXb3JkLnkgKyB3b3JkLmZBc2NlbnQ7CisJCQkJCXB0Rm9vdC54ID0gd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoOworCQkJCQlwdEZvb3QueSA9IHdvcmQucHRXb3JkLnkgKyB3b3JkLmZEZXNjZW50OworCQkJCX0KKwkJCQllbHNlIGlmIChwSXRlcmF0b3ItPkdldExpbmUobGluZSkpCisJCQkJewkJCQkKKwkJCQkJcHRIZWFkLnggPSBsaW5lLnB0TGluZS54OworCQkJCQlwdEhlYWQueSA9IGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lQXNjZW50OworCQkJCQlwdEZvb3QueCA9IGxpbmUucHRMaW5lLng7CisJCQkJCXB0Rm9vdC55ID0gbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVEZXNjZW50OworCQkJCX0KKwkJCX0JCQorCisJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsKKwkJCW1fcE5vdGlmeS0+SU9uU2V0Q2FyZXQoIW1fU2VsU3RhdGUuSXNFeGlzdCgpLFZUVG9FZGl0KHB0SGVhZCksVlRUb0VkaXQocHRGb290KSwgbV93cENhcmV0KTsKKwkJCW1fYk5vdGlmeUZsYWcgPSBGQUxTRTsKKwkJfQorCX0KKworCVNldENhcmV0Q2hhbmdlKCk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldENhcmV0Q2hhbmdlKCkKK3sKKwlpZiAodGhpcy0+bV93cENhcmV0ID09IHRoaXMtPm1fd3BPbGRDYXJldCkgcmV0dXJuOworCisJaWYgKG1fYk5vdGlmeSAmJiBtX3BWVC0+SXNSaWNoVGV4dCgpICYmIG1fcE5vdGlmeSkKKwl7CisJCUNQVlRfU2VjUHJvcHMgU2VjUHJvcHM7CisJCUNQVlRfV29yZFByb3BzIFdvcmRQcm9wczsKKworCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkKKwkJeworCQkJcEl0ZXJhdG9yLT5TZXRBdChtX3dwQ2FyZXQpOworCQkJQ1BWVF9Xb3JkIHdvcmQ7CisJCQlDUFZUX1NlY3Rpb24gc2VjdGlvbjsKKworCQkJaWYgKHBJdGVyYXRvci0+R2V0U2VjdGlvbihzZWN0aW9uKSkKKwkJCXsKKwkJCQlTZWNQcm9wcyA9IHNlY3Rpb24uU2VjUHJvcHM7CisJCQkJV29yZFByb3BzID0gc2VjdGlvbi5Xb3JkUHJvcHM7CisJCQl9CisJCQkKKwkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpCisJCQl7CQkJCQorCQkJCVdvcmRQcm9wcyA9IHdvcmQuV29yZFByb3BzOwkJCQkKKwkJCX0KKwkJfQkJCisJCQorCQlpZiAoIW1fYk5vdGlmeUZsYWcpCisJCXsKKwkJCW1fYk5vdGlmeUZsYWcgPSBUUlVFOworCQkJbV9wTm90aWZ5LT5JT25DYXJldENoYW5nZShTZWNQcm9wcyxXb3JkUHJvcHMpOworCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOworCQl9CisJfQkKK30KKwordm9pZCBDRlhfRWRpdDo6U2V0Q2FyZXQoRlhfSU5UMzIgblBvcykKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCVNlbGVjdE5vbmUoKTsJCQorCQlTZXRDYXJldChtX3BWVC0+V29yZEluZGV4VG9Xb3JkUGxhY2UoblBvcykpOworCQltX1NlbFN0YXRlLlNldChtX3dwQ2FyZXQsbV93cENhcmV0KTsKKworCQlTY3JvbGxUb0NhcmV0KCk7CisJCVNldENhcmV0T3JpZ2luKCk7CisJCVNldENhcmV0SW5mbygpOworCX0KK30KKwordm9pZCBDRlhfRWRpdDo6T25Nb3VzZURvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpCit7CisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJeworCQlTZWxlY3ROb25lKCk7CQkKKwkJU2V0Q2FyZXQobV9wVlQtPlNlYXJjaFdvcmRQbGFjZShFZGl0VG9WVChwb2ludCkpKTsKKwkJbV9TZWxTdGF0ZS5TZXQobV93cENhcmV0LG1fd3BDYXJldCk7CisKKwkJU2Nyb2xsVG9DYXJldCgpOworCQlTZXRDYXJldE9yaWdpbigpOworCQlTZXRDYXJldEluZm8oKTsKKwl9Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6Ok9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCxGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJU2V0Q2FyZXQobV9wVlQtPlNlYXJjaFdvcmRQbGFjZShFZGl0VG9WVChwb2ludCkpKTsKKworCQlpZiAobV93cENhcmV0ICE9IG1fd3BPbGRDYXJldCkKKwkJeworCQkJbV9TZWxTdGF0ZS5TZXRFbmRQb3MobV93cENhcmV0KTsJCQorCisJCQlTY3JvbGxUb0NhcmV0KCk7CisJCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsbV93cENhcmV0KTsKKwkJCVJlZnJlc2goUlBfT1BUSU9OQUwsJndyKTsKKwkJCVNldENhcmV0T3JpZ2luKCk7CisJCQlTZXRDYXJldEluZm8oKTsKKwkJfQorCX0KK30KKwordm9pZCBDRlhfRWRpdDo6T25WS19VUChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQorewkKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCVNldENhcmV0KG1fcFZULT5HZXRVcFdvcmRQbGFjZShtX3dwQ2FyZXQsbV9wdENhcmV0KSk7CisKKwkJaWYgKGJTaGlmdCkKKwkJeworCQkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQorCQkJCW1fU2VsU3RhdGUuU2V0RW5kUG9zKG1fd3BDYXJldCk7CisJCQllbHNlCisJCQkJbV9TZWxTdGF0ZS5TZXQobV93cE9sZENhcmV0LG1fd3BDYXJldCk7CisKKwkJCWlmIChtX3dwT2xkQ2FyZXQgIT0gbV93cENhcmV0KQorCQkJeworCQkJCVNjcm9sbFRvQ2FyZXQoKTsKKwkJCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsIG1fd3BDYXJldCk7CisJCQkJUmVmcmVzaChSUF9PUFRJT05BTCwgJndyKTsKKwkJCQlTZXRDYXJldEluZm8oKTsKKwkJCX0KKwkJfQorCQllbHNlCisJCXsKKwkJCVNlbGVjdE5vbmUoKTsJCQorCQkJCisJCQlTY3JvbGxUb0NhcmV0KCk7CQkJCisJCQlTZXRDYXJldEluZm8oKTsKKwkJfQorCX0KK30KKwordm9pZCBDRlhfRWRpdDo6T25WS19ET1dOKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpCit7CisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJeworCQlTZXRDYXJldChtX3BWVC0+R2V0RG93bldvcmRQbGFjZShtX3dwQ2FyZXQsbV9wdENhcmV0KSk7CisKKwkJaWYgKGJTaGlmdCkKKwkJeworCQkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQorCQkJCW1fU2VsU3RhdGUuU2V0RW5kUG9zKG1fd3BDYXJldCk7CisJCQllbHNlCisJCQkJbV9TZWxTdGF0ZS5TZXQobV93cE9sZENhcmV0LG1fd3BDYXJldCk7CisKKwkJCWlmIChtX3dwT2xkQ2FyZXQgIT0gbV93cENhcmV0KQorCQkJeworCQkJCVNjcm9sbFRvQ2FyZXQoKTsKKwkJCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsbV93cENhcmV0KTsKKwkJCQlSZWZyZXNoKFJQX09QVElPTkFMLCAmd3IpOworCQkJCVNldENhcmV0SW5mbygpOworCQkJfQorCQl9CisJCWVsc2UKKwkJeworCQkJU2VsZWN0Tm9uZSgpOworCisJCQlTY3JvbGxUb0NhcmV0KCk7CQkKKwkJCVNldENhcmV0SW5mbygpOworCQl9CisJfQorfQorCit2b2lkIENGWF9FZGl0OjpPblZLX0xFRlQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmIChiU2hpZnQpCisJCXsKKwkJCWlmIChtX3dwQ2FyZXQgPT0gbV9wVlQtPkdldExpbmVCZWdpblBsYWNlKG1fd3BDYXJldCkgJiYKKwkJCQltX3dwQ2FyZXQgIT0gbV9wVlQtPkdldFNlY3Rpb25CZWdpblBsYWNlKG1fd3BDYXJldCkpCisJCQkJU2V0Q2FyZXQobV9wVlQtPkdldFByZXZXb3JkUGxhY2UobV93cENhcmV0KSk7CQorCisJCQlTZXRDYXJldChtX3BWVC0+R2V0UHJldldvcmRQbGFjZShtX3dwQ2FyZXQpKTsKKworCQkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQorCQkJCW1fU2VsU3RhdGUuU2V0RW5kUG9zKG1fd3BDYXJldCk7CQkJCisJCQllbHNlCisJCQkJbV9TZWxTdGF0ZS5TZXQobV93cE9sZENhcmV0LCBtX3dwQ2FyZXQpOworCisJCQlpZiAobV93cE9sZENhcmV0ICE9IG1fd3BDYXJldCkKKwkJCXsKKwkJCQlTY3JvbGxUb0NhcmV0KCk7CisJCQkJQ1BWVF9Xb3JkUmFuZ2Ugd3IobV93cE9sZENhcmV0LG1fd3BDYXJldCk7CisJCQkJUmVmcmVzaChSUF9PUFRJT05BTCwmd3IpOworCQkJCVNldENhcmV0SW5mbygpOworCQkJfQorCQl9CisJCWVsc2UKKwkJeworCQkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQorCQkJeworCQkJCWlmIChtX1NlbFN0YXRlLkJlZ2luUG9zLldvcmRDbXAobV9TZWxTdGF0ZS5FbmRQb3MpPDApCisJCQkJCVNldENhcmV0KG1fU2VsU3RhdGUuQmVnaW5Qb3MpOworCQkJCWVsc2UKKwkJCQkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5FbmRQb3MpOworCisJCQkJU2VsZWN0Tm9uZSgpOworCQkJCVNjcm9sbFRvQ2FyZXQoKTsKKwkJCQlTZXRDYXJldEluZm8oKTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlpZiAobV93cENhcmV0ID09IG1fcFZULT5HZXRMaW5lQmVnaW5QbGFjZShtX3dwQ2FyZXQpICYmCisJCQkJCW1fd3BDYXJldCAhPSBtX3BWVC0+R2V0U2VjdGlvbkJlZ2luUGxhY2UobV93cENhcmV0KSkKKwkJCQkJU2V0Q2FyZXQobV9wVlQtPkdldFByZXZXb3JkUGxhY2UobV93cENhcmV0KSk7CQorCisJCQkJU2V0Q2FyZXQobV9wVlQtPkdldFByZXZXb3JkUGxhY2UobV93cENhcmV0KSk7CisKKwkJCQlTY3JvbGxUb0NhcmV0KCk7CisJCQkJU2V0Q2FyZXRPcmlnaW4oKTsKKwkJCQlTZXRDYXJldEluZm8oKTsKKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBDRlhfRWRpdDo6T25WS19SSUdIVChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJaWYgKGJTaGlmdCkKKwkJeworCQkJU2V0Q2FyZXQobV9wVlQtPkdldE5leHRXb3JkUGxhY2UobV93cENhcmV0KSk7CisKKwkJCWlmIChtX3dwQ2FyZXQgPT0gbV9wVlQtPkdldExpbmVFbmRQbGFjZShtX3dwQ2FyZXQpICYmCisJCQkJbV93cENhcmV0ICE9IG1fcFZULT5HZXRTZWN0aW9uRW5kUGxhY2UobV93cENhcmV0KSkKKwkJCQlTZXRDYXJldChtX3BWVC0+R2V0TmV4dFdvcmRQbGFjZShtX3dwQ2FyZXQpKTsKKworCQkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQorCQkJCW1fU2VsU3RhdGUuU2V0RW5kUG9zKG1fd3BDYXJldCk7CQkJCisJCQllbHNlCisJCQkJbV9TZWxTdGF0ZS5TZXQobV93cE9sZENhcmV0LG1fd3BDYXJldCk7CQkJCisKKwkJCWlmIChtX3dwT2xkQ2FyZXQgIT0gbV93cENhcmV0KQorCQkJewkJCQorCQkJCVNjcm9sbFRvQ2FyZXQoKTsKKwkJCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsbV93cENhcmV0KTsKKwkJCQlSZWZyZXNoKFJQX09QVElPTkFMLCZ3cik7CisJCQkJU2V0Q2FyZXRJbmZvKCk7CisJCQl9CisJCX0KKwkJZWxzZQorCQl7CisJCQlpZiAobV9TZWxTdGF0ZS5Jc0V4aXN0KCkpCisJCQl7CisJCQkJaWYgKG1fU2VsU3RhdGUuQmVnaW5Qb3MuV29yZENtcChtX1NlbFN0YXRlLkVuZFBvcyk+MCkKKwkJCQkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5CZWdpblBvcyk7CisJCQkJZWxzZQorCQkJCQlTZXRDYXJldChtX1NlbFN0YXRlLkVuZFBvcyk7CisKKwkJCQlTZWxlY3ROb25lKCk7CisJCQkJU2Nyb2xsVG9DYXJldCgpOworCQkJCVNldENhcmV0SW5mbygpOworCQkJfQorCQkJZWxzZQorCQkJeworCQkJCVNldENhcmV0KG1fcFZULT5HZXROZXh0V29yZFBsYWNlKG1fd3BDYXJldCkpOworCisJCQkJaWYgKG1fd3BDYXJldCA9PSBtX3BWVC0+R2V0TGluZUVuZFBsYWNlKG1fd3BDYXJldCkgJiYKKwkJCQkJbV93cENhcmV0ICE9IG1fcFZULT5HZXRTZWN0aW9uRW5kUGxhY2UobV93cENhcmV0KSkKKwkJCQkJU2V0Q2FyZXQobV9wVlQtPkdldE5leHRXb3JkUGxhY2UobV93cENhcmV0KSk7CQkJCQorCisJCQkJU2Nyb2xsVG9DYXJldCgpOworCQkJCVNldENhcmV0T3JpZ2luKCk7CisJCQkJU2V0Q2FyZXRJbmZvKCk7CisJCQl9CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6Ok9uVktfSE9NRShGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJaWYgKGJTaGlmdCkKKwkJeworCQkJaWYgKGJDdHJsKQorCQkJCVNldENhcmV0KG1fcFZULT5HZXRCZWdpbldvcmRQbGFjZSgpKTsKKwkJCWVsc2UKKwkJCQlTZXRDYXJldChtX3BWVC0+R2V0TGluZUJlZ2luUGxhY2UobV93cENhcmV0KSk7CisKKwkJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkKKwkJCQltX1NlbFN0YXRlLlNldEVuZFBvcyhtX3dwQ2FyZXQpOwkJCQorCQkJZWxzZQorCQkJCW1fU2VsU3RhdGUuU2V0KG1fd3BPbGRDYXJldCxtX3dwQ2FyZXQpOworCisJCQlTY3JvbGxUb0NhcmV0KCk7CisJCQlDUFZUX1dvcmRSYW5nZSB3cihtX3dwT2xkQ2FyZXQsIG1fd3BDYXJldCk7CisJCQlSZWZyZXNoKFJQX09QVElPTkFMLCAmd3IpOworCQkJU2V0Q2FyZXRJbmZvKCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlpZiAobV9TZWxTdGF0ZS5Jc0V4aXN0KCkpCisJCQl7CisJCQkJaWYgKG1fU2VsU3RhdGUuQmVnaW5Qb3MuV29yZENtcChtX1NlbFN0YXRlLkVuZFBvcyk8MCkKKwkJCQkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5CZWdpblBvcyk7CisJCQkJZWxzZQorCQkJCQlTZXRDYXJldChtX1NlbFN0YXRlLkVuZFBvcyk7CisKKwkJCQlTZWxlY3ROb25lKCk7CisJCQkJU2Nyb2xsVG9DYXJldCgpOworCQkJCVNldENhcmV0SW5mbygpOworCQkJfQorCQkJZWxzZQorCQkJeworCQkJCWlmIChiQ3RybCkKKwkJCQkJU2V0Q2FyZXQobV9wVlQtPkdldEJlZ2luV29yZFBsYWNlKCkpOworCQkJCWVsc2UKKwkJCQkJU2V0Q2FyZXQobV9wVlQtPkdldExpbmVCZWdpblBsYWNlKG1fd3BDYXJldCkpOwkKKwkJCQkKKwkJCQlTY3JvbGxUb0NhcmV0KCk7CisJCQkJU2V0Q2FyZXRPcmlnaW4oKTsKKwkJCQlTZXRDYXJldEluZm8oKTsKKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBDRlhfRWRpdDo6T25WS19FTkQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmIChiU2hpZnQpCisJCXsKKwkJCWlmIChiQ3RybCkKKwkJCQlTZXRDYXJldChtX3BWVC0+R2V0RW5kV29yZFBsYWNlKCkpOworCQkJZWxzZQorCQkJCVNldENhcmV0KG1fcFZULT5HZXRMaW5lRW5kUGxhY2UobV93cENhcmV0KSk7CisKKwkJCWlmIChtX1NlbFN0YXRlLklzRXhpc3QoKSkKKwkJCQltX1NlbFN0YXRlLlNldEVuZFBvcyhtX3dwQ2FyZXQpOworCQkJZWxzZQorCQkJCW1fU2VsU3RhdGUuU2V0KG1fd3BPbGRDYXJldCwgbV93cENhcmV0KTsKKworCQkJU2Nyb2xsVG9DYXJldCgpOworCQkJQ1BWVF9Xb3JkUmFuZ2Ugd3IobV93cE9sZENhcmV0LCBtX3dwQ2FyZXQpOworCQkJUmVmcmVzaChSUF9PUFRJT05BTCwgJndyKTsKKwkJCVNldENhcmV0SW5mbygpOworCQl9CisJCWVsc2UKKwkJeworCQkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQorCQkJeworCQkJCWlmIChtX1NlbFN0YXRlLkJlZ2luUG9zLldvcmRDbXAobV9TZWxTdGF0ZS5FbmRQb3MpPjApCisJCQkJCVNldENhcmV0KG1fU2VsU3RhdGUuQmVnaW5Qb3MpOworCQkJCWVsc2UKKwkJCQkJU2V0Q2FyZXQobV9TZWxTdGF0ZS5FbmRQb3MpOworCisJCQkJU2VsZWN0Tm9uZSgpOworCQkJCVNjcm9sbFRvQ2FyZXQoKTsKKwkJCQlTZXRDYXJldEluZm8oKTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlpZiAoYkN0cmwpCisJCQkJCVNldENhcmV0KG1fcFZULT5HZXRFbmRXb3JkUGxhY2UoKSk7CisJCQkJZWxzZQorCQkJCQlTZXRDYXJldChtX3BWVC0+R2V0TGluZUVuZFBsYWNlKG1fd3BDYXJldCkpOworCQkJCQkJCisJCQkJU2Nyb2xsVG9DYXJldCgpOwkJCQorCQkJCVNldENhcmV0T3JpZ2luKCk7CisJCQkJU2V0Q2FyZXRJbmZvKCk7CisJCQl9CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldFRleHQoRlhfTFBDV1NUUiB0ZXh0LEZYX0lOVDMyIGNoYXJzZXQsCisJCQkJCQljb25zdCBDUFZUX1NlY1Byb3BzICogcFNlY1Byb3BzLGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcywgRlhfQk9PTCBiQWRkVW5kbywgRlhfQk9PTCBiUGFpbnQpCit7CisJRW1wdHkoKTsKKwlEb0luc2VydFRleHQoQ1BWVF9Xb3JkUGxhY2UoMCwwLC0xKSwgdGV4dCwgY2hhcnNldCwgcFNlY1Byb3BzLCBwV29yZFByb3BzKTsKKwlpZiAoYlBhaW50KSBQYWludCgpOworCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQorCQltX3BPcHJOb3RpZnktPk9uU2V0VGV4dChtX3dwQ2FyZXQsIG1fd3BPbGRDYXJldCk7CisJLy9pZiAoYkFkZFVuZG8pCit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6Okluc2VydFdvcmQoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBjaGFyc2V0LCBjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsIEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KQoreworCWlmIChJc1RleHRPdmVyZmxvdygpKSByZXR1cm4gRkFMU0U7CisKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2UobV93cENhcmV0KTsKKworCQlTZXRDYXJldChtX3BWVC0+SW5zZXJ0V29yZChtX3dwQ2FyZXQsd29yZCxHZXRDaGFyU2V0RnJvbVVuaWNvZGUod29yZCwgY2hhcnNldCkscFdvcmRQcm9wcykpOworCQltX1NlbFN0YXRlLlNldChtX3dwQ2FyZXQsbV93cENhcmV0KTsKKworCQlpZiAobV93cENhcmV0ICE9IG1fd3BPbGRDYXJldCkKKwkJeworCQkJaWYgKGJBZGRVbmRvICYmIG1fYkVuYWJsZVVuZG8pCisJCQl7CisJCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9JbnNlcnRXb3JkKHRoaXMsbV93cE9sZENhcmV0LG1fd3BDYXJldCx3b3JkLGNoYXJzZXQscFdvcmRQcm9wcykpOworCQkJfQorCisJCQlpZiAoYlBhaW50KQorCQkJCVBhaW50SW5zZXJ0VGV4dChtX3dwT2xkQ2FyZXQsIG1fd3BDYXJldCk7CisKKwkJCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQorCQkJCW1fcE9wck5vdGlmeS0+T25JbnNlcnRXb3JkKG1fd3BDYXJldCwgbV93cE9sZENhcmV0KTsKKworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENGWF9FZGl0OjpJbnNlcnRSZXR1cm4oY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcyxjb25zdCBDUFZUX1dvcmRQcm9wcyAqIHBXb3JkUHJvcHMsIAorCQkJCQkJCSAgIEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KQoreworCWlmIChJc1RleHRPdmVyZmxvdygpKSByZXR1cm4gRkFMU0U7CisKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCW1fcFZULT5VcGRhdGVXb3JkUGxhY2UobV93cENhcmV0KTsKKwkJU2V0Q2FyZXQobV9wVlQtPkluc2VydFNlY3Rpb24obV93cENhcmV0LHBTZWNQcm9wcyxwV29yZFByb3BzKSk7CisJCW1fU2VsU3RhdGUuU2V0KG1fd3BDYXJldCxtX3dwQ2FyZXQpOworCisJCWlmIChtX3dwQ2FyZXQgIT0gbV93cE9sZENhcmV0KQorCQl7CisJCQlpZiAoYkFkZFVuZG8gJiYgbV9iRW5hYmxlVW5kbykKKwkJCXsKKwkJCQlBZGRFZGl0VW5kb0l0ZW0obmV3IENGWEVVX0luc2VydFJldHVybih0aGlzLG1fd3BPbGRDYXJldCxtX3dwQ2FyZXQscFNlY1Byb3BzLHBXb3JkUHJvcHMpKTsKKwkJCX0KKworCQkJaWYgKGJQYWludCkKKwkJCXsKKwkJCQlSZWFycmFuZ2VQYXJ0KENQVlRfV29yZFJhbmdlKG1fd3BPbGRDYXJldCwgbV93cENhcmV0KSk7CisJCQkJU2Nyb2xsVG9DYXJldCgpOworCQkJCUNQVlRfV29yZFJhbmdlIHdyKG1fd3BPbGRDYXJldCwgR2V0VmlzaWJsZVdvcmRSYW5nZSgpLkVuZFBvcyk7CisJCQkJUmVmcmVzaChSUF9BTkFMWVNFLCAmd3IpOwkJCisJCQkJU2V0Q2FyZXRPcmlnaW4oKTsKKwkJCQlTZXRDYXJldEluZm8oKTsJCQkKKwkJCX0KKworCQkJaWYgKG1fYk9wck5vdGlmeSAmJiBtX3BPcHJOb3RpZnkpCisJCQkJbV9wT3ByTm90aWZ5LT5Pbkluc2VydFJldHVybihtX3dwQ2FyZXQsIG1fd3BPbGRDYXJldCk7CisKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENGWF9FZGl0OjpCYWNrc3BhY2UoRlhfQk9PTCBiQWRkVW5kbywgRlhfQk9PTCBiUGFpbnQpCit7CisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJeworCQlpZiAobV93cENhcmV0ID09IG1fcFZULT5HZXRCZWdpbldvcmRQbGFjZSgpKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BWVF9TZWN0aW9uIHNlY3Rpb247CisJCUNQVlRfV29yZCB3b3JkOworCisJCWlmIChiQWRkVW5kbykKKwkJeworCQkJaWYgKElQREZfVmFyaWFibGVUZXh0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wVlQtPkdldEl0ZXJhdG9yKCkpCisJCQl7CQkJCQorCQkJCXBJdGVyYXRvci0+U2V0QXQobV93cENhcmV0KTsKKwkJCQlwSXRlcmF0b3ItPkdldFNlY3Rpb24oc2VjdGlvbik7CisJCQkJcEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpOworCQkJfQorCQl9CisKKwkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZShtX3dwQ2FyZXQpOworCQlTZXRDYXJldChtX3BWVC0+QmFja1NwYWNlV29yZChtX3dwQ2FyZXQpKTsKKwkJbV9TZWxTdGF0ZS5TZXQobV93cENhcmV0LG1fd3BDYXJldCk7CisKKwkJaWYgKG1fd3BDYXJldCAhPSBtX3dwT2xkQ2FyZXQpCisJCXsKKwkJCWlmIChiQWRkVW5kbyAmJiBtX2JFbmFibGVVbmRvKQorCQkJeworCQkJCWlmIChtX3dwQ2FyZXQuU2VjQ21wKG1fd3BPbGRDYXJldCkgIT0gMCkJCQkKKwkJCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9CYWNrc3BhY2UodGhpcyxtX3dwT2xkQ2FyZXQsbV93cENhcmV0LHdvcmQuV29yZCx3b3JkLm5DaGFyc2V0LAorCQkJCQkJc2VjdGlvbi5TZWNQcm9wcyxzZWN0aW9uLldvcmRQcm9wcykpOworCQkJCWVsc2UKKwkJCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9CYWNrc3BhY2UodGhpcyxtX3dwT2xkQ2FyZXQsbV93cENhcmV0LHdvcmQuV29yZCx3b3JkLm5DaGFyc2V0LAorCQkJCQkJc2VjdGlvbi5TZWNQcm9wcyx3b3JkLldvcmRQcm9wcykpOworCQkJfQorCisJCQlpZiAoYlBhaW50KQorCQkJeworCQkJCVJlYXJyYW5nZVBhcnQoQ1BWVF9Xb3JkUmFuZ2UobV93cENhcmV0LG1fd3BPbGRDYXJldCkpOworCQkJCVNjcm9sbFRvQ2FyZXQoKTsKKworCQkJCUNQVlRfV29yZFJhbmdlIHdyOworCQkJCWlmIChtX3dwQ2FyZXQuU2VjQ21wKG1fd3BPbGRDYXJldCkgIT0wKQorCQkJCQl3ciA9IENQVlRfV29yZFJhbmdlKG1fcFZULT5HZXRQcmV2V29yZFBsYWNlKG1fd3BDYXJldCksR2V0VmlzaWJsZVdvcmRSYW5nZSgpLkVuZFBvcyk7CQorCQkJCWVsc2UgaWYgKG1fd3BDYXJldC5MaW5lQ21wKG1fd3BPbGRDYXJldCkgIT0wKQorCQkJCQl3ciA9IENQVlRfV29yZFJhbmdlKG1fcFZULT5HZXRMaW5lQmVnaW5QbGFjZShtX3dwQ2FyZXQpLG1fcFZULT5HZXRTZWN0aW9uRW5kUGxhY2UobV93cENhcmV0KSk7CisJCQkJZWxzZQorCQkJCQl3ciA9IENQVlRfV29yZFJhbmdlKG1fcFZULT5HZXRQcmV2V29yZFBsYWNlKG1fd3BDYXJldCksbV9wVlQtPkdldFNlY3Rpb25FbmRQbGFjZShtX3dwQ2FyZXQpKTsKKworCQkJCVJlZnJlc2goUlBfQU5BTFlTRSwgJndyKTsKKworCQkJCVNldENhcmV0T3JpZ2luKCk7CisJCQkJU2V0Q2FyZXRJbmZvKCk7CisJCQl9CisKKwkJCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQorCQkJCW1fcE9wck5vdGlmeS0+T25CYWNrU3BhY2UobV93cENhcmV0LCBtX3dwT2xkQ2FyZXQpOworCisJCQlyZXR1cm4gVFJVRTsKKwkJfQorCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDRlhfRWRpdDo6RGVsZXRlKEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJaWYgKG1fd3BDYXJldCA9PSBtX3BWVC0+R2V0RW5kV29yZFBsYWNlKCkpIHJldHVybiBGQUxTRTsKKworCQlDUFZUX1NlY3Rpb24gc2VjdGlvbjsKKwkJQ1BWVF9Xb3JkIHdvcmQ7CisKKwkJaWYgKGJBZGRVbmRvKQorCQl7CisJCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkKKwkJCXsJCQkJCisJCQkJcEl0ZXJhdG9yLT5TZXRBdChtX3BWVC0+R2V0TmV4dFdvcmRQbGFjZShtX3dwQ2FyZXQpKTsKKwkJCQlwSXRlcmF0b3ItPkdldFNlY3Rpb24oc2VjdGlvbik7CisJCQkJcEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpOworCQkJfQorCQl9CisKKwkJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZShtX3dwQ2FyZXQpOworCQlGWF9CT09MIGJTZWNFbmQgPSAobV93cENhcmV0ID09IG1fcFZULT5HZXRTZWN0aW9uRW5kUGxhY2UobV93cENhcmV0KSk7CisKKwkJU2V0Q2FyZXQobV9wVlQtPkRlbGV0ZVdvcmQobV93cENhcmV0KSk7CisJCW1fU2VsU3RhdGUuU2V0KG1fd3BDYXJldCxtX3dwQ2FyZXQpOworCisJCWlmIChiQWRkVW5kbyAmJiBtX2JFbmFibGVVbmRvKQorCQl7CisJCQlpZiAoYlNlY0VuZCkJCQorCQkJCUFkZEVkaXRVbmRvSXRlbShuZXcgQ0ZYRVVfRGVsZXRlKHRoaXMsbV93cE9sZENhcmV0LG1fd3BDYXJldCx3b3JkLldvcmQsd29yZC5uQ2hhcnNldCwKKwkJCQkJc2VjdGlvbi5TZWNQcm9wcyxzZWN0aW9uLldvcmRQcm9wcyxiU2VjRW5kKSk7CisJCQllbHNlCisJCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9EZWxldGUodGhpcyxtX3dwT2xkQ2FyZXQsbV93cENhcmV0LHdvcmQuV29yZCx3b3JkLm5DaGFyc2V0LAorCQkJCQlzZWN0aW9uLlNlY1Byb3BzLHdvcmQuV29yZFByb3BzLGJTZWNFbmQpKTsKKwkJfQorCQkKKwkJaWYgKGJQYWludCkKKwkJeworCQkJUmVhcnJhbmdlUGFydChDUFZUX1dvcmRSYW5nZShtX3dwT2xkQ2FyZXQsbV93cENhcmV0KSk7CisJCQlTY3JvbGxUb0NhcmV0KCk7CisKKwkJCUNQVlRfV29yZFJhbmdlIHdyOworCQkJaWYgKGJTZWNFbmQpCisJCQkJd3IgPSBDUFZUX1dvcmRSYW5nZShtX3BWVC0+R2V0UHJldldvcmRQbGFjZShtX3dwT2xkQ2FyZXQpLEdldFZpc2libGVXb3JkUmFuZ2UoKS5FbmRQb3MpOworCQkJZWxzZSBpZiAobV93cENhcmV0LkxpbmVDbXAobV93cE9sZENhcmV0KSAhPTApCisJCQkJd3IgPSBDUFZUX1dvcmRSYW5nZShtX3BWVC0+R2V0TGluZUJlZ2luUGxhY2UobV93cENhcmV0KSxtX3BWVC0+R2V0U2VjdGlvbkVuZFBsYWNlKG1fd3BDYXJldCkpOworCQkJZWxzZQorCQkJCXdyID0gQ1BWVF9Xb3JkUmFuZ2UobV9wVlQtPkdldFByZXZXb3JkUGxhY2UobV93cE9sZENhcmV0KSxtX3BWVC0+R2V0U2VjdGlvbkVuZFBsYWNlKG1fd3BDYXJldCkpOwkJCQorCisJCQlSZWZyZXNoKFJQX0FOQUxZU0UsICZ3cik7CisJCQkKKwkJCVNldENhcmV0T3JpZ2luKCk7CisJCQlTZXRDYXJldEluZm8oKTsKKwkJfQorCisJCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQorCQkJbV9wT3ByTm90aWZ5LT5PbkRlbGV0ZShtX3dwQ2FyZXQsIG1fd3BPbGRDYXJldCk7CisKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MCUNGWF9FZGl0OjpFbXB0eSgpCit7CisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJeworCQltX3BWVC0+RGVsZXRlV29yZHMoR2V0V2hvbGVXb3JkUmFuZ2UoKSk7CisJCVNldENhcmV0KG1fcFZULT5HZXRCZWdpbldvcmRQbGFjZSgpKTsKKworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ0ZYX0VkaXQ6OkNsZWFyKEZYX0JPT0wgYkFkZFVuZG8sIEZYX0JPT0wgYlBhaW50KQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJaWYgKG1fU2VsU3RhdGUuSXNFeGlzdCgpKQorCQl7CisJCQlDUFZUX1dvcmRSYW5nZSByYW5nZSA9IG1fU2VsU3RhdGUuQ29udmVydFRvV29yZFJhbmdlKCk7CisKKwkJCWlmIChiQWRkVW5kbyAmJiBtX2JFbmFibGVVbmRvKQorCQkJeworCQkJCWlmIChtX3BWVC0+SXNSaWNoVGV4dCgpKQorCQkJCXsKKwkJCQkJQmVnaW5Hcm91cFVuZG8oTCIiKTsKKworCQkJCQlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BWVC0+R2V0SXRlcmF0b3IoKSkKKwkJCQkJeworCQkJCQkJcEl0ZXJhdG9yLT5TZXRBdChyYW5nZS5FbmRQb3MpOworCisJCQkJCQlDUFZUX1dvcmQgd29yZGluZm87CQorCQkJCQkJQ1BWVF9TZWN0aW9uIHNlY2luZm87CQkJCQkJCisJCQkJCQlkbworCQkJCQkJewkJCQkJCQkKKwkJCQkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKwkJCQkJCQlpZiAocGxhY2UuV29yZENtcChyYW5nZS5CZWdpblBvcykgPD0gMClicmVhazsKKworCQkJCQkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlID0gbV9wVlQtPkdldFByZXZXb3JkUGxhY2UocGxhY2UpOwkJCQkJCQkKKworCQkJCQkJCWlmIChvbGRwbGFjZS5TZWNDbXAocGxhY2UpICE9IDApCisJCQkJCQkJeworCQkJCQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRTZWN0aW9uKHNlY2luZm8pKQorCQkJCQkJCQl7CisJCQkJCQkJCQlBZGRFZGl0VW5kb0l0ZW0obmV3IENGWEVVX0NsZWFyUmljaCh0aGlzLG9sZHBsYWNlLHBsYWNlLHJhbmdlLHdvcmRpbmZvLldvcmQsCisJCQkJCQkJCQkJd29yZGluZm8ubkNoYXJzZXQsc2VjaW5mby5TZWNQcm9wcyxzZWNpbmZvLldvcmRQcm9wcykpOworCQkJCQkJCQl9CisJCQkJCQkJfQorCQkJCQkJCWVsc2UKKwkJCQkJCQl7CisJCQkJCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZGluZm8pKQorCQkJCQkJCQl7CQkJCQkJCQkJCisJCQkJCQkJCQlvbGRwbGFjZSA9IG1fcFZULT5BanVzdExpbmVIZWFkZXIob2xkcGxhY2UsVFJVRSk7CisJCQkJCQkJCQlwbGFjZSA9IG1fcFZULT5BanVzdExpbmVIZWFkZXIocGxhY2UsVFJVRSk7CisKKwkJCQkJCQkJCUFkZEVkaXRVbmRvSXRlbShuZXcgQ0ZYRVVfQ2xlYXJSaWNoKHRoaXMsb2xkcGxhY2UscGxhY2UscmFuZ2Usd29yZGluZm8uV29yZCwKKwkJCQkJCQkJCQl3b3JkaW5mby5uQ2hhcnNldCxzZWNpbmZvLlNlY1Byb3BzLHdvcmRpbmZvLldvcmRQcm9wcykpOworCQkJCQkJCQl9CisJCQkJCQkJfQorCQkJCQkJfXdoaWxlIChwSXRlcmF0b3ItPlByZXZXb3JkKCkpOworCQkJCQl9CisJCQkJCUVuZEdyb3VwVW5kbygpOworCQkJCX0KKwkJCQllbHNlCisJCQkJewkJCQkJCisJCQkJCUFkZEVkaXRVbmRvSXRlbShuZXcgQ0ZYRVVfQ2xlYXIodGhpcyxyYW5nZSxHZXRTZWxUZXh0KCkpKTsJCQkJCQorCQkJCX0KKwkJCX0KKworCQkJU2VsZWN0Tm9uZSgpOwkJCQorCQkJU2V0Q2FyZXQobV9wVlQtPkRlbGV0ZVdvcmRzKHJhbmdlKSk7CQorCQkJbV9TZWxTdGF0ZS5TZXQobV93cENhcmV0LG1fd3BDYXJldCk7CisKKwkJCWlmIChiUGFpbnQpCisJCQl7CisJCQkJUmVhcnJhbmdlUGFydChyYW5nZSk7CQorCQkJCVNjcm9sbFRvQ2FyZXQoKTsKKworCQkJCUNQVlRfV29yZFJhbmdlIHdyKG1fd3BPbGRDYXJldCwgR2V0VmlzaWJsZVdvcmRSYW5nZSgpLkVuZFBvcyk7CisJCQkJUmVmcmVzaChSUF9BTkFMWVNFLCAmd3IpOworCQkJCQorCQkJCVNldENhcmV0T3JpZ2luKCk7CisJCQkJU2V0Q2FyZXRJbmZvKCk7CisJCQl9CisKKwkJCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQorCQkJCW1fcE9wck5vdGlmeS0+T25DbGVhcihtX3dwQ2FyZXQsIG1fd3BPbGRDYXJldCk7CisKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENGWF9FZGl0OjpJbnNlcnRUZXh0KEZYX0xQQ1dTVFIgdGV4dCwgRlhfSU5UMzIgY2hhcnNldCwKKwkJCQkJY29uc3QgQ1BWVF9TZWNQcm9wcyAqIHBTZWNQcm9wcywgY29uc3QgQ1BWVF9Xb3JkUHJvcHMgKiBwV29yZFByb3BzLCBGWF9CT09MIGJBZGRVbmRvLCBGWF9CT09MIGJQYWludCkKK3sKKwlpZiAoSXNUZXh0T3ZlcmZsb3coKSkgcmV0dXJuIEZBTFNFOworCisJbV9wVlQtPlVwZGF0ZVdvcmRQbGFjZShtX3dwQ2FyZXQpOworCVNldENhcmV0KERvSW5zZXJ0VGV4dChtX3dwQ2FyZXQsIHRleHQsIGNoYXJzZXQsIHBTZWNQcm9wcywgcFdvcmRQcm9wcykpOworCW1fU2VsU3RhdGUuU2V0KG1fd3BDYXJldCxtX3dwQ2FyZXQpOworCisJaWYgKG1fd3BDYXJldCAhPSBtX3dwT2xkQ2FyZXQpCisJeworCQlpZiAoYkFkZFVuZG8gJiYgbV9iRW5hYmxlVW5kbykKKwkJeworCQkJQWRkRWRpdFVuZG9JdGVtKG5ldyBDRlhFVV9JbnNlcnRUZXh0KHRoaXMsbV93cE9sZENhcmV0LG1fd3BDYXJldCx0ZXh0LGNoYXJzZXQscFNlY1Byb3BzLHBXb3JkUHJvcHMpKTsKKwkJfQorCisJCWlmIChiUGFpbnQpCisJCQlQYWludEluc2VydFRleHQobV93cE9sZENhcmV0LCBtX3dwQ2FyZXQpOworCisJCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQorCQkJbV9wT3ByTm90aWZ5LT5Pbkluc2VydFRleHQobV93cENhcmV0LCBtX3dwT2xkQ2FyZXQpOworCisJCXJldHVybiBUUlVFOworCX0KKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlBhaW50SW5zZXJ0VGV4dChjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwT2xkLCBjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHdwTmV3KQoreworCWlmIChtX3BWVC0+SXNWYWxpZCgpKQorCXsKKwkJUmVhcnJhbmdlUGFydChDUFZUX1dvcmRSYW5nZSh3cE9sZCx3cE5ldykpOworCQlTY3JvbGxUb0NhcmV0KCk7CisJCQorCQlDUFZUX1dvcmRSYW5nZSB3cjsKKwkJaWYgKG1fd3BDYXJldC5MaW5lQ21wKHdwT2xkKSAhPTApCisJCQl3ciA9IENQVlRfV29yZFJhbmdlKG1fcFZULT5HZXRMaW5lQmVnaW5QbGFjZSh3cE9sZCksbV9wVlQtPkdldFNlY3Rpb25FbmRQbGFjZSh3cE5ldykpOwkKKwkJZWxzZQorCQkJd3IgPSBDUFZUX1dvcmRSYW5nZSh3cE9sZCxtX3BWVC0+R2V0U2VjdGlvbkVuZFBsYWNlKHdwTmV3KSk7CQorCQlSZWZyZXNoKFJQX0FOQUxZU0UsICZ3cik7CisJCVNldENhcmV0T3JpZ2luKCk7CisJCVNldENhcmV0SW5mbygpOworCX0KK30KKworRlhfQk9PTCBDRlhfRWRpdDo6UmVkbygpCit7CisJaWYgKG1fYkVuYWJsZVVuZG8pCisJeworCQlpZiAobV9VbmRvLkNhblJlZG8oKSkKKwkJeworCQkJbV9VbmRvLlJlZG8oKTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIENGWF9FZGl0OjpVbmRvKCkKK3sKKwlpZiAobV9iRW5hYmxlVW5kbykKKwl7CisJCWlmIChtX1VuZG8uQ2FuVW5kbygpKQorCQl7CisJCQltX1VuZG8uVW5kbygpOworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OlNldENhcmV0T3JpZ2luKCkKK3sKKwlpZiAobV9wVlQtPklzVmFsaWQoKSkKKwl7CisJCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQorCQl7CisJCQlwSXRlcmF0b3ItPlNldEF0KG1fd3BDYXJldCk7CisJCQlDUFZUX1dvcmQgd29yZDsKKwkJCUNQVlRfTGluZSBsaW5lOworCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCXsKKwkJCQltX3B0Q2FyZXQueCA9IHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aDsKKwkJCQltX3B0Q2FyZXQueSA9IHdvcmQucHRXb3JkLnk7CisJCQl9CisJCQllbHNlIGlmIChwSXRlcmF0b3ItPkdldExpbmUobGluZSkpCisJCQl7CQkJCQorCQkJCW1fcHRDYXJldC54ID0gbGluZS5wdExpbmUueDsKKwkJCQltX3B0Q2FyZXQueSA9IGxpbmUucHRMaW5lLnk7CisJCQl9CisJCX0JCQkJCisJfQkKK30KKworRlhfSU5UMzIgQ0ZYX0VkaXQ6OldvcmRQbGFjZVRvV29yZEluZGV4KGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0Cit7CisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJCXJldHVybiBtX3BWVC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgocGxhY2UpOworCisJcmV0dXJuIC0xOworfQorCitDUFZUX1dvcmRQbGFjZSBDRlhfRWRpdDo6V29yZEluZGV4VG9Xb3JkUGxhY2UoRlhfSU5UMzIgaW5kZXgpIGNvbnN0Cit7CisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJCXJldHVybiBtX3BWVC0+V29yZEluZGV4VG9Xb3JkUGxhY2UoaW5kZXgpOworCisJcmV0dXJuIENQVlRfV29yZFBsYWNlKCk7Cit9CisKK0ZYX0JPT0wJQ0ZYX0VkaXQ6OklzVGV4dEZ1bGwoKSBjb25zdAoreworCUZYX0lOVDMyIG5Ub3RhbFdvcmRzID0gbV9wVlQtPkdldFRvdGFsV29yZHMoKTsKKwlGWF9JTlQzMiBuTGltaXRDaGFyID0gbV9wVlQtPkdldExpbWl0Q2hhcigpOworCUZYX0lOVDMyIG5DaGFyQXJyYXkgPSBtX3BWVC0+R2V0Q2hhckFycmF5KCk7CisKKwlyZXR1cm4gSXNUZXh0T3ZlcmZsb3coKSB8fCAobkxpbWl0Q2hhcj4wICYmIG5Ub3RhbFdvcmRzID49IG5MaW1pdENoYXIpCisJCXx8IChuQ2hhckFycmF5PjAgJiYgblRvdGFsV29yZHMgPj0gbkNoYXJBcnJheSk7Cit9CisKK0ZYX0JPT0wJQ0ZYX0VkaXQ6OklzVGV4dE92ZXJmbG93KCkgY29uc3QKK3sKKwlpZiAoIW1fYkVuYWJsZVNjcm9sbCAmJiAhbV9iRW5hYmxlT3ZlcmZsb3cpCisJeworCQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcFZULT5HZXRQbGF0ZVJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjQ29udGVudCA9IG1fcFZULT5HZXRDb250ZW50UmVjdCgpOworCisJCWlmIChtX3BWVC0+SXNNdWx0aUxpbmUoKSAmJiBHZXRUb3RhbExpbmVzKCkgPiAxKQorCQl7CisJCQlpZiAoRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKHJjQ29udGVudC5IZWlnaHQoKSxyY1BsYXRlLkhlaWdodCgpKSkgcmV0dXJuIFRSVUU7CisJCX0KKworCQlpZiAoRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKHJjQ29udGVudC5XaWR0aCgpLHJjUGxhdGUuV2lkdGgoKSkpIHJldHVybiBUUlVFOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworQ1BWVF9Xb3JkUGxhY2UgQ0ZYX0VkaXQ6OkdldExpbmVCZWdpblBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0Cit7CisJcmV0dXJuIG1fcFZULT5HZXRMaW5lQmVnaW5QbGFjZShwbGFjZSk7Cit9CisKK0NQVlRfV29yZFBsYWNlIENGWF9FZGl0OjpHZXRMaW5lRW5kUGxhY2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QKK3sKKwlyZXR1cm4gbV9wVlQtPkdldExpbmVFbmRQbGFjZShwbGFjZSk7Cit9CisKK0NQVlRfV29yZFBsYWNlIENGWF9FZGl0OjpHZXRTZWN0aW9uQmVnaW5QbGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSAmIHBsYWNlKSBjb25zdAoreworCXJldHVybiBtX3BWVC0+R2V0U2VjdGlvbkJlZ2luUGxhY2UocGxhY2UpOworfQorCitDUFZUX1dvcmRQbGFjZSBDRlhfRWRpdDo6R2V0U2VjdGlvbkVuZFBsYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0Cit7CisJcmV0dXJuIG1fcFZULT5HZXRTZWN0aW9uRW5kUGxhY2UocGxhY2UpOworfQorCitGWF9CT09MCUNGWF9FZGl0OjpDYW5VbmRvKCkgY29uc3QKK3sKKwlpZiAobV9iRW5hYmxlVW5kbykKKwl7CisJCXJldHVybiBtX1VuZG8uQ2FuVW5kbygpOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAlDRlhfRWRpdDo6Q2FuUmVkbygpIGNvbnN0Cit7CisJaWYgKG1fYkVuYWJsZVVuZG8pCisJeworCQlyZXR1cm4gbV9VbmRvLkNhblJlZG8oKTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ0ZYX0VkaXQ6OklzTW9kaWZpZWQoKSBjb25zdAoreworCWlmIChtX2JFbmFibGVVbmRvKQorCXsKKwkJcmV0dXJuIG1fVW5kby5Jc01vZGlmaWVkKCk7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIENGWF9FZGl0OjpFbmFibGVSZWZyZXNoKEZYX0JPT0wgYlJlZnJlc2gpCit7CisJbV9iRW5hYmxlUmVmcmVzaCA9IGJSZWZyZXNoOworfQorCit2b2lkIENGWF9FZGl0OjpFbmFibGVVbmRvKEZYX0JPT0wgYlVuZG8pCit7CisJdGhpcy0+bV9iRW5hYmxlVW5kbyA9IGJVbmRvOworfQorCit2b2lkIENGWF9FZGl0OjpFbmFibGVOb3RpZnkoRlhfQk9PTCBiTm90aWZ5KQoreworCXRoaXMtPm1fYk5vdGlmeSA9IGJOb3RpZnk7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OkVuYWJsZU9wck5vdGlmeShGWF9CT09MIGJOb3RpZnkpCit7CisJdGhpcy0+bV9iT3ByTm90aWZ5ID0gYk5vdGlmeTsKK30KKworRlhfRkxPQVQgQ0ZYX0VkaXQ6OkdldExpbmVUb3AoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlKSBjb25zdAoreworCWlmIChJUERGX1ZhcmlhYmxlVGV4dF9JdGVyYXRvciogcEl0ZXJhdG9yID0gbV9wVlQtPkdldEl0ZXJhdG9yKCkpCisJeworCQlDUFZUX1dvcmRQbGFjZSB3cE9sZCA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKworCQlwSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsKKwkJQ1BWVF9MaW5lIGxpbmU7CisJCXBJdGVyYXRvci0+R2V0TGluZShsaW5lKTsKKworCQlwSXRlcmF0b3ItPlNldEF0KHdwT2xkKTsKKworCQlyZXR1cm4gbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVBc2NlbnQ7CisJfQorCisJcmV0dXJuIDAuMGY7Cit9CisKK0ZYX0ZMT0FUIENGWF9FZGl0OjpHZXRMaW5lQm90dG9tKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSkgY29uc3QKK3sKKwlpZiAoSVBERl9WYXJpYWJsZVRleHRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IG1fcFZULT5HZXRJdGVyYXRvcigpKQorCXsKKwkJQ1BWVF9Xb3JkUGxhY2Ugd3BPbGQgPSBwSXRlcmF0b3ItPkdldEF0KCk7CisKKwkJcEl0ZXJhdG9yLT5TZXRBdChwbGFjZSk7CisJCUNQVlRfTGluZSBsaW5lOworCQlwSXRlcmF0b3ItPkdldExpbmUobGluZSk7CisKKwkJcEl0ZXJhdG9yLT5TZXRBdCh3cE9sZCk7CisKKwkJcmV0dXJuIGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lRGVzY2VudDsKKwl9CisKKwlyZXR1cm4gMC4wZjsKK30KKworQ1BWVF9Xb3JkUGxhY2UgQ0ZYX0VkaXQ6OkRvSW5zZXJ0VGV4dChjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIEZYX0xQQ1dTVFIgdGV4dCwgRlhfSU5UMzIgY2hhcnNldCwgCisJCQkJCQkJCQkgIGNvbnN0IENQVlRfU2VjUHJvcHMgKiBwU2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICogcFdvcmRQcm9wcykKK3sKKwlDUFZUX1dvcmRQbGFjZSB3cCA9IHBsYWNlOworCisJaWYgKG1fcFZULT5Jc1ZhbGlkKCkpCisJeworCQlDRlhfV2lkZVN0cmluZyBzVGV4dCA9IHRleHQ7CisKKwkJZm9yIChGWF9JTlQzMiBpID0gMCwgc3ogPSBzVGV4dC5HZXRMZW5ndGgoKTsgaSA8IHN6OyBpKyspCisJCXsKKwkJCUZYX1dPUkQgd29yZCA9IHNUZXh0W2ldOworCQkJc3dpdGNoICh3b3JkKQorCQkJeworCQkJY2FzZSAweDBEOgorCQkJCXdwID0gbV9wVlQtPkluc2VydFNlY3Rpb24od3AscFNlY1Byb3BzLHBXb3JkUHJvcHMpOworCQkJCWlmIChzVGV4dFtpKzFdID09IDB4MEEpCisJCQkJCWkrKzsKKwkJCQlicmVhazsKKwkJCWNhc2UgMHgwQToJCisJCQkJd3AgPSBtX3BWVC0+SW5zZXJ0U2VjdGlvbih3cCxwU2VjUHJvcHMscFdvcmRQcm9wcyk7CisJCQkJaWYgKHNUZXh0W2krMV0gPT0gMHgwRCkKKwkJCQkJaSsrOworCQkJCWJyZWFrOworCQkJY2FzZSAweDA5OgorCQkJCXdvcmQgPSAweDIwOworCQkJZGVmYXVsdDoKKwkJCQl3cCA9IG1fcFZULT5JbnNlcnRXb3JkKHdwLHdvcmQsR2V0Q2hhclNldEZyb21Vbmljb2RlKHdvcmQsIGNoYXJzZXQpLHBXb3JkUHJvcHMpOworCQkJCWJyZWFrOworCQkJfQorCQl9CisJfQorCisJcmV0dXJuIHdwOworfQorCitGWF9JTlQzMiBDRlhfRWRpdDo6R2V0Q2hhclNldEZyb21Vbmljb2RlKEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgbk9sZENoYXJzZXQpCit7CisJaWYgKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwID0gdGhpcy0+R2V0Rm9udE1hcCgpKQorCQlyZXR1cm4gcEZvbnRNYXAtPkNoYXJTZXRGcm9tVW5pY29kZSh3b3JkLCBuT2xkQ2hhcnNldCk7CisJZWxzZQorCQlyZXR1cm4gbk9sZENoYXJzZXQ7Cit9CisKK3ZvaWQgQ0ZYX0VkaXQ6OkJlZ2luR3JvdXBVbmRvKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGl0bGUpCit7CisJQVNTRVJUKG1fcEdyb3VwVW5kb0l0ZW0gPT0gTlVMTCk7CisKKwltX3BHcm91cFVuZG9JdGVtID0gbmV3IENGWF9FZGl0X0dyb3VwVW5kb0l0ZW0oc1RpdGxlKTsKK30KKwordm9pZCBDRlhfRWRpdDo6RW5kR3JvdXBVbmRvKCkKK3sKKwlBU1NFUlQobV9wR3JvdXBVbmRvSXRlbSAhPSBOVUxMKTsKKworCW1fcEdyb3VwVW5kb0l0ZW0tPlVwZGF0ZUl0ZW1zKCk7CisJbV9VbmRvLkFkZEl0ZW0obV9wR3JvdXBVbmRvSXRlbSk7CisJaWYgKG1fYk9wck5vdGlmeSAmJiBtX3BPcHJOb3RpZnkpCisJCW1fcE9wck5vdGlmeS0+T25BZGRVbmRvKG1fcEdyb3VwVW5kb0l0ZW0pOworCW1fcEdyb3VwVW5kb0l0ZW0gPSBOVUxMOworfQorCit2b2lkIENGWF9FZGl0OjpBZGRFZGl0VW5kb0l0ZW0oQ0ZYX0VkaXRfVW5kb0l0ZW0qIHBFZGl0VW5kb0l0ZW0pCit7CisJaWYgKG1fcEdyb3VwVW5kb0l0ZW0pCisJCW1fcEdyb3VwVW5kb0l0ZW0tPkFkZFVuZG9JdGVtKHBFZGl0VW5kb0l0ZW0pOworCWVsc2UKKwl7CisJCW1fVW5kby5BZGRJdGVtKHBFZGl0VW5kb0l0ZW0pOworCQlpZiAobV9iT3ByTm90aWZ5ICYmIG1fcE9wck5vdGlmeSkKKwkJCW1fcE9wck5vdGlmeS0+T25BZGRVbmRvKHBFZGl0VW5kb0l0ZW0pOworCX0KK30KKwordm9pZCBDRlhfRWRpdDo6QWRkVW5kb0l0ZW0oSUZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSkKK3sKKwltX1VuZG8uQWRkSXRlbShwVW5kb0l0ZW0pOworCWlmIChtX2JPcHJOb3RpZnkgJiYgbV9wT3ByTm90aWZ5KQorCQltX3BPcHJOb3RpZnktPk9uQWRkVW5kbyhwVW5kb0l0ZW0pOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9meGVkaXQvZnhldF9saXN0LmNwcCBiL2ZwZGZzZGsvc3JjL2Z4ZWRpdC9meGV0X2xpc3QuY3BwCmluZGV4IGRkNzBlMGMuLjYzYWVlMWIgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2Z4ZWRpdC9meGV0X2xpc3QuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2Z4ZWRpdC9meGV0X2xpc3QuY3BwCkBAIC0xLDEwMTIgKzEsMTAxMiBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfc3R1Yi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4ZWRpdC9meGV0X2VkaXQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9saXN0LmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDRlhfTGlzdEl0ZW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNGWF9MaXN0SXRlbTo6Q0ZYX0xpc3RJdGVtKCkgOiBtX3BFZGl0KE5VTEwpLA0KLQltX2JTZWxlY3RlZChGQUxTRSksDQotCW1fYkNhcmV0KEZBTFNFKSwNCi0JbV9yY0xpc3RJdGVtKDAuMGYsMC4wZiwwLjBmLDAuMGYpDQotew0KLQltX3BFZGl0ID0gSUZYX0VkaXQ6Ok5ld0VkaXQoKTsNCi0JQVNTRVJUKG1fcEVkaXQgIT0gTlVMTCk7DQotDQotCW1fcEVkaXQtPlNldEFsaWdubWVudFYoMSk7DQotCW1fcEVkaXQtPkluaXRpYWxpemUoKTsNCi19DQotDQotQ0ZYX0xpc3RJdGVtOjp+Q0ZYX0xpc3RJdGVtKCkNCi17DQotCUlGWF9FZGl0OjpEZWxFZGl0KG1fcEVkaXQpOw0KLX0NCi0NCi12b2lkIENGWF9MaXN0SXRlbTo6U2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApDQotew0KLQlpZiAobV9wRWRpdCkNCi0JCW1fcEVkaXQtPlNldEZvbnRNYXAocEZvbnRNYXApOw0KLX0NCi0NCi1JRlhfRWRpdCogQ0ZYX0xpc3RJdGVtOjpHZXRFZGl0KCkgY29uc3QNCi17DQotCXJldHVybiBtX3BFZGl0Ow0KLX0NCi0NCi1JRlhfRWRpdF9JdGVyYXRvcioJQ0ZYX0xpc3RJdGVtOjpHZXRJdGVyYXRvcigpIGNvbnN0DQotew0KLQlpZiAobV9wRWRpdCkNCi0JCXJldHVybiBtX3BFZGl0LT5HZXRJdGVyYXRvcigpOw0KLQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCBDRlhfTGlzdEl0ZW06OlNldFJlY3QoY29uc3QgQ0xTVF9SZWN0ICYgcmVjdCkNCi17DQotCW1fcmNMaXN0SXRlbSA9IHJlY3Q7DQotfQ0KLQ0KLUNMU1RfUmVjdCBDRlhfTGlzdEl0ZW06OkdldFJlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcmNMaXN0SXRlbTsNCi19DQotDQotRlhfQk9PTCBDRlhfTGlzdEl0ZW06OklzU2VsZWN0ZWQoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fYlNlbGVjdGVkOw0KLX0NCi0NCi12b2lkIENGWF9MaXN0SXRlbTo6U2V0U2VsZWN0KEZYX0JPT0wgYlNlbGVjdGVkKQ0KLXsNCi0JbV9iU2VsZWN0ZWQgPSBiU2VsZWN0ZWQ7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0xpc3RJdGVtOjpJc0NhcmV0KCkgY29uc3QNCi17DQotCXJldHVybiBtX2JDYXJldDsNCi19DQotDQotdm9pZCBDRlhfTGlzdEl0ZW06OlNldENhcmV0KEZYX0JPT0wgYkNhcmV0KQ0KLXsNCi0JbV9iQ2FyZXQgPSBiQ2FyZXQ7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RJdGVtOjpTZXRUZXh0KEZYX0xQQ1dTVFIgdGV4dCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQkJbV9wRWRpdC0+U2V0VGV4dCh0ZXh0KTsNCi19DQotDQotdm9pZCBDRlhfTGlzdEl0ZW06OlNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQkJbV9wRWRpdC0+U2V0Rm9udFNpemUoZkZvbnRTaXplKTsNCi19DQotDQotRlhfRkxPQVQgQ0ZYX0xpc3RJdGVtOjpHZXRJdGVtSGVpZ2h0KCkgY29uc3QNCi17DQotCWlmIChtX3BFZGl0KQ0KLQkJcmV0dXJuIG1fcEVkaXQtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQotDQotCXJldHVybiAwLjBmOw0KLX0NCi0NCi1GWF9XT1JEIENGWF9MaXN0SXRlbTo6R2V0Rmlyc3RDaGFyKCkgY29uc3QNCi17DQotCUNQVlRfV29yZCB3b3JkOw0KLQ0KLQlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqCXBJdGVyYXRvciA9IEdldEl0ZXJhdG9yKCkpDQotCXsNCi0JCXBJdGVyYXRvci0+U2V0QXQoMSk7CQkNCi0JCXBJdGVyYXRvci0+R2V0V29yZCh3b3JkKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gd29yZC5Xb3JkOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDRlhfTGlzdEl0ZW06OkdldFRleHQoKSBjb25zdA0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCQlyZXR1cm4gbV9wRWRpdC0+R2V0VGV4dCgpOw0KLQ0KLQlyZXR1cm4gTCIiOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0xpc3QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0ZYX0xpc3Q6OkNGWF9MaXN0KCkgOiBtX3BGb250TWFwKE5VTEwpLCBtX2ZGb250U2l6ZSgwLjBmKSwgbV9iTXVsdGlwbGUoRkFMU0UpIA0KLXsNCi19DQotDQotQ0ZYX0xpc3Q6On5DRlhfTGlzdCgpDQotew0KLQlFbXB0eSgpOw0KLX0NCi0NCi12b2lkIENGWF9MaXN0OjpFbXB0eSgpDQotew0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FMaXN0SXRlbXMuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQlkZWxldGUgbV9hTGlzdEl0ZW1zLkdldEF0KGkpOw0KLQ0KLQltX2FMaXN0SXRlbXMuUmVtb3ZlQWxsKCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3Q6OlNldEZvbnRNYXAoSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwKQ0KLXsNCi0JbV9wRm9udE1hcCA9IHBGb250TWFwOw0KLX0NCi0NCi12b2lkIENGWF9MaXN0OjpTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpDQotew0KLQltX2ZGb250U2l6ZSA9IGZGb250U2l6ZTsNCi19DQotDQotdm9pZCBDRlhfTGlzdDo6QWRkSXRlbShGWF9MUENXU1RSIHN0cikNCi17CQ0KLQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbmV3IENGWF9MaXN0SXRlbSgpKQ0KLQl7DQotCQlwTGlzdEl0ZW0tPlNldEZvbnRNYXAobV9wRm9udE1hcCk7DQotCQlwTGlzdEl0ZW0tPlNldEZvbnRTaXplKG1fZkZvbnRTaXplKTsNCi0JCXBMaXN0SXRlbS0+U2V0VGV4dChzdHIpOw0KLQkJbV9hTGlzdEl0ZW1zLkFkZChwTGlzdEl0ZW0pOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3Q6OlJlQXJyYW5nZShGWF9JTlQzMiBuSXRlbUluZGV4KQ0KLXsNCi0JRlhfRkxPQVQgZlBvc1kgPSAwLjBmOw0KLQ0KLQlpZiAoQ0ZYX0xpc3RJdGVtICogcFByZXZJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KG5JdGVtSW5kZXggLSAxKSkNCi0JCWZQb3NZID0gcFByZXZJdGVtLT5HZXRSZWN0KCkuYm90dG9tOw0KLQkNCi0JZm9yIChGWF9JTlQzMiBpPW5JdGVtSW5kZXgsc3o9bV9hTGlzdEl0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KGkpKQ0KLQkJew0KLQkJCUZYX0ZMT0FUIGZMaXN0SXRlbUhlaWdodCA9IHBMaXN0SXRlbS0+R2V0SXRlbUhlaWdodCgpOw0KLQkJCXBMaXN0SXRlbS0+U2V0UmVjdChDTFNUX1JlY3QoMC4wZixmUG9zWSwwLjBmLGZQb3NZICsgZkxpc3RJdGVtSGVpZ2h0KSk7DQotCQkJZlBvc1kgKz0gZkxpc3RJdGVtSGVpZ2h0OwkJCQ0KLQkJfQ0KLQl9DQotDQotCVNldENvbnRlbnRSZWN0KENMU1RfUmVjdCgwLjBmLDAuMGYsMC4wZixmUG9zWSkpOwkNCi19DQotDQotSUZYX0VkaXQgKiBDRlhfTGlzdDo6R2V0SXRlbUVkaXQoRlhfSU5UMzIgbkluZGV4KSBjb25zdA0KLXsNCi0JaWYgKENGWF9MaXN0SXRlbSAqIHBMaXN0SXRlbSA9IG1fYUxpc3RJdGVtcy5HZXRBdChuSW5kZXgpKQ0KLQl7DQotCQlyZXR1cm4gcExpc3RJdGVtLT5HZXRFZGl0KCk7DQotCX0NCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUZYX0lOVDMyIENGWF9MaXN0OjpHZXRDb3VudCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9hTGlzdEl0ZW1zLkdldFNpemUoKTsNCi19DQotDQotQ1BERl9SZWN0IENGWF9MaXN0OjpHZXRQbGF0ZVJlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIENGWF9MaXN0Q29udGFpbmVyOjpHZXRQbGF0ZVJlY3QoKTsNCi19DQotDQotQ1BERl9SZWN0IENGWF9MaXN0OjpHZXRDb250ZW50UmVjdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gSW5uZXJUb091dGVyKENGWF9MaXN0Q29udGFpbmVyOjpHZXRDb250ZW50UmVjdCgpKTsNCi19DQotDQotRlhfRkxPQVQgQ0ZYX0xpc3Q6OkdldEZvbnRTaXplKCkgY29uc3QNCi17DQotCXJldHVybiBtX2ZGb250U2l6ZTsNCi19DQotDQotRlhfSU5UMzIgQ0ZYX0xpc3Q6OkdldEl0ZW1JbmRleChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0DQotew0KLQlDUERGX1BvaW50IHB0ID0gT3V0ZXJUb0lubmVyKHBvaW50KTsNCi0NCi0JRlhfQk9PTCBiRmlyc3QgPSBUUlVFOw0KLQlGWF9CT09MIGJMYXN0ID0gVFJVRTsNCi0NCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hTGlzdEl0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KGkpKQ0KLQkJew0KLQkJCUNMU1RfUmVjdCByY0xpc3RJdGVtID0gcExpc3RJdGVtLT5HZXRSZWN0KCk7DQotDQotCQkJaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihwdC55LCByY0xpc3RJdGVtLnRvcCkpDQotCQkJewkJCQ0KLQkJCQliRmlyc3QgPSBGQUxTRTsNCi0JCQl9DQotDQotCQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocHQueSwgcmNMaXN0SXRlbS5ib3R0b20pKQ0KLQkJCXsNCi0JCQkJYkxhc3QgPSBGQUxTRTsNCi0JCQl9DQotDQotCQkJaWYgKHB0LnkgPj0gcmNMaXN0SXRlbS50b3AgJiYgcHQueSA8IHJjTGlzdEl0ZW0uYm90dG9tKQ0KLQkJCXsNCi0JCQkJcmV0dXJuIGk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCWlmIChiRmlyc3QpIHJldHVybiAwOw0KLQlpZiAoYkxhc3QpIHJldHVybiBtX2FMaXN0SXRlbXMuR2V0U2l6ZSgpLTE7DQotDQotCXJldHVybiAtMTsNCi19DQotDQotRlhfRkxPQVQgQ0ZYX0xpc3Q6OkdldEZpcnN0SGVpZ2h0KCkgY29uc3QNCi17DQotCWlmIChDRlhfTGlzdEl0ZW0gKiBwTGlzdEl0ZW0gPSBtX2FMaXN0SXRlbXMuR2V0QXQoMCkpDQotCXsNCi0JCXJldHVybiBwTGlzdEl0ZW0tPkdldEl0ZW1IZWlnaHQoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gMS4wZjsNCi19DQotDQotRlhfSU5UMzIgQ0ZYX0xpc3Q6OkdldEZpcnN0U2VsZWN0ZWQoKSBjb25zdA0KLXsNCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hTGlzdEl0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KGkpKQ0KLQkJew0KLQkJCWlmIChwTGlzdEl0ZW0tPklzU2VsZWN0ZWQoKSkNCi0JCQkJcmV0dXJuIGk7DQotCQl9DQotCX0NCi0JcmV0dXJuIC0xOw0KLX0NCi0NCi1GWF9JTlQzMiBDRlhfTGlzdDo6R2V0TGFzdFNlbGVjdGVkKCkgY29uc3QNCi17DQotCWZvciAoRlhfSU5UMzIgaT1tX2FMaXN0SXRlbXMuR2V0U2l6ZSgpLTE7IGk+PTA7IGktLSkNCi0Jew0KLQkJaWYgKENGWF9MaXN0SXRlbSAqIHBMaXN0SXRlbSA9IG1fYUxpc3RJdGVtcy5HZXRBdChpKSkNCi0JCXsNCi0JCQlpZiAocExpc3RJdGVtLT5Jc1NlbGVjdGVkKCkpDQotCQkJCXJldHVybiBpOw0KLQkJfQ0KLQl9DQotCXJldHVybiAtMTsNCi19DQotDQotRlhfV0NIQVIgQ0ZYX0xpc3Q6OlRvdXBwZXIoRlhfV0NIQVIgYykgY29uc3QNCi17DQotCWlmICggKGMgPj0gJ2EnKSAmJiAoYyA8PSAneicpICkNCi0JCWMgPSBjIC0gKCdhJyAtICdBJyk7DQotCXJldHVybiBjOw0KLX0NCi0NCi1GWF9JTlQzMiBDRlhfTGlzdDo6RmluZE5leHQoRlhfSU5UMzIgbkluZGV4LEZYX1dDSEFSIG5DaGFyKSBjb25zdA0KLXsNCi0JRlhfSU5UMzIgbkNpcmNsZUluZGV4ID0gbkluZGV4Ow0KLQ0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FMaXN0SXRlbXMuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCW5DaXJjbGVJbmRleCArKzsNCi0JCWlmIChuQ2lyY2xlSW5kZXggPj0gc3opIG5DaXJjbGVJbmRleCA9IDA7DQotDQotCQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KG5DaXJjbGVJbmRleCkpDQotCQl7DQotCQkJaWYgKFRvdXBwZXIocExpc3RJdGVtLT5HZXRGaXJzdENoYXIoKSkgPT0gVG91cHBlcihuQ2hhcikpDQotCQkJCXJldHVybiBuQ2lyY2xlSW5kZXg7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIG5DaXJjbGVJbmRleDsNCi19DQotDQotQ1BERl9SZWN0IENGWF9MaXN0OjpHZXRJdGVtUmVjdChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0DQotew0KLQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KG5JbmRleCkpDQotCXsNCi0JCUNQREZfUmVjdCByY0l0ZW0gPSBwTGlzdEl0ZW0tPkdldFJlY3QoKTsNCi0JCXJjSXRlbS5sZWZ0ID0gMC4wZjsNCi0JCXJjSXRlbS5yaWdodCA9IEdldFBsYXRlUmVjdCgpLldpZHRoKCk7DQotCQlyZXR1cm4gSW5uZXJUb091dGVyKHJjSXRlbSk7DQotCX0NCi0NCi0JcmV0dXJuIENQREZfUmVjdCgpOw0KLX0NCi0NCi1GWF9CT09MIENGWF9MaXN0OjpJc0l0ZW1TZWxlY3RlZChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0DQotew0KLQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KG5JbmRleCkpDQotCXsNCi0JCXJldHVybiBwTGlzdEl0ZW0tPklzU2VsZWN0ZWQoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3Q6OlNldEl0ZW1TZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCwgRlhfQk9PTCBiU2VsZWN0ZWQpDQotew0KLQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KG5JdGVtSW5kZXgpKQ0KLQl7DQotCQlwTGlzdEl0ZW0tPlNldFNlbGVjdChiU2VsZWN0ZWQpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3Q6OlNldEl0ZW1DYXJldChGWF9JTlQzMiBuSXRlbUluZGV4LCBGWF9CT09MIGJDYXJldCkNCi17DQotCWlmIChDRlhfTGlzdEl0ZW0gKiBwTGlzdEl0ZW0gPSBtX2FMaXN0SXRlbXMuR2V0QXQobkl0ZW1JbmRleCkpDQotCXsNCi0JCXBMaXN0SXRlbS0+U2V0Q2FyZXQoYkNhcmV0KTsJCQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3Q6OlNldE11bHRpcGxlU2VsKEZYX0JPT0wgYk11bHRpcGxlKQ0KLXsNCi0JbV9iTXVsdGlwbGUgPSBiTXVsdGlwbGU7DQotfQ0KLQ0KLUZYX0JPT0wgQ0ZYX0xpc3Q6OklzTXVsdGlwbGVTZWwoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fYk11bHRpcGxlOw0KLX0NCi0NCi1GWF9CT09MIENGWF9MaXN0OjpJc1ZhbGlkKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0DQotew0KLQlyZXR1cm4gbkl0ZW1JbmRleCA+PSAwICYmIG5JdGVtSW5kZXggPCBtX2FMaXN0SXRlbXMuR2V0U2l6ZSgpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDRlhfTGlzdDo6R2V0SXRlbVRleHQoRlhfSU5UMzIgbkluZGV4KSBjb25zdA0KLXsNCi0JaWYgKENGWF9MaXN0SXRlbSAqIHBMaXN0SXRlbSA9IG1fYUxpc3RJdGVtcy5HZXRBdChuSW5kZXgpKQ0KLQl7DQotCQlyZXR1cm4gcExpc3RJdGVtLT5HZXRUZXh0KCk7DQotCX0NCi0NCi0JcmV0dXJuIEwiIjsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQTFNUX1NlbGVjdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BMU1RfU2VsZWN0OjpDUExTVF9TZWxlY3QoKQ0KLXsNCi19DQotDQotQ1BMU1RfU2VsZWN0Ojp+Q1BMU1RfU2VsZWN0KCkNCi17DQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUl0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJZGVsZXRlIG1fYUl0ZW1zLkdldEF0KGkpOw0KLQ0KLQltX2FJdGVtcy5SZW1vdmVBbGwoKTsNCi19DQotDQotdm9pZCBDUExTVF9TZWxlY3Q6OkFkZChGWF9JTlQzMiBuSXRlbUluZGV4KQ0KLXsNCi0JRlhfSU5UMzIgbkluZGV4ID0gRmluZChuSXRlbUluZGV4KTsNCi0NCi0JaWYgKG5JbmRleCA8IDApIA0KLQkJbV9hSXRlbXMuQWRkKG5ldyBDUExTVF9TZWxlY3RfSXRlbShuSXRlbUluZGV4LDEpKTsNCi0JZWxzZQ0KLQl7DQotCQlpZiAoQ1BMU1RfU2VsZWN0X0l0ZW0gKiBwSXRlbSA9IG1fYUl0ZW1zLkdldEF0KG5JbmRleCkpDQotCQl7DQotCQkJcEl0ZW0tPm5TdGF0ZSA9IDE7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDUExTVF9TZWxlY3Q6OkFkZChGWF9JTlQzMiBuQmVnaW5JbmRleCwgRlhfSU5UMzIgbkVuZEluZGV4KQ0KLXsNCi0JaWYgKG5CZWdpbkluZGV4ID4gbkVuZEluZGV4KQ0KLQl7DQotCQlGWF9JTlQzMiBuVGVtcCA9IG5FbmRJbmRleDsNCi0JCW5FbmRJbmRleCA9IG5CZWdpbkluZGV4Ow0KLQkJbkJlZ2luSW5kZXggPSBuVGVtcDsNCi0JfQ0KLQ0KLQlmb3IgKEZYX0lOVDMyIGk9bkJlZ2luSW5kZXg7IGk8PW5FbmRJbmRleDsgaSsrKQlBZGQoaSk7DQotfQ0KLQ0KLXZvaWQgQ1BMU1RfU2VsZWN0OjpTdWIoRlhfSU5UMzIgbkl0ZW1JbmRleCkNCi17DQotCWZvciAoRlhfSU5UMzIgaT1tX2FJdGVtcy5HZXRTaXplKCktMTsgaT49MDsgaS0tKQ0KLQl7DQotCQlpZiAoQ1BMU1RfU2VsZWN0X0l0ZW0gKiBwSXRlbSA9IG1fYUl0ZW1zLkdldEF0KGkpKQ0KLQkJCWlmIChwSXRlbS0+bkl0ZW1JbmRleCA9PSBuSXRlbUluZGV4KQ0KLQkJCQlwSXRlbS0+blN0YXRlID0gLTE7DQotCX0NCi19DQotDQotdm9pZCBDUExTVF9TZWxlY3Q6OlN1YihGWF9JTlQzMiBuQmVnaW5JbmRleCwgRlhfSU5UMzIgbkVuZEluZGV4KQ0KLXsNCi0JaWYgKG5CZWdpbkluZGV4ID4gbkVuZEluZGV4KQ0KLQl7DQotCQlGWF9JTlQzMiBuVGVtcCA9IG5FbmRJbmRleDsNCi0JCW5FbmRJbmRleCA9IG5CZWdpbkluZGV4Ow0KLQkJbkJlZ2luSW5kZXggPSBuVGVtcDsNCi0JfQ0KLQ0KLQlmb3IgKEZYX0lOVDMyIGk9bkJlZ2luSW5kZXg7IGk8PW5FbmRJbmRleDsgaSsrKQlTdWIoaSk7DQotfQ0KLQ0KLUZYX0lOVDMyIENQTFNUX1NlbGVjdDo6RmluZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdA0KLXsNCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hSXRlbXMuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCWlmIChDUExTVF9TZWxlY3RfSXRlbSAqIHBJdGVtID0gbV9hSXRlbXMuR2V0QXQoaSkpDQotCQl7DQotCQkJaWYgKHBJdGVtLT5uSXRlbUluZGV4ID09IG5JdGVtSW5kZXgpDQotCQkJCXJldHVybiBpOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiAtMTsNCi19DQotDQotRlhfQk9PTCBDUExTVF9TZWxlY3Q6OklzRXhpc3QoRlhfSU5UMzIgbkl0ZW1JbmRleCkgY29uc3QNCi17DQotCXJldHVybiBGaW5kKG5JdGVtSW5kZXgpID49IDA7DQotfQ0KLQ0KLUZYX0lOVDMyIENQTFNUX1NlbGVjdDo6R2V0Q291bnQoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fYUl0ZW1zLkdldFNpemUoKTsNCi19DQotDQotRlhfSU5UMzIgQ1BMU1RfU2VsZWN0OjpHZXRJdGVtSW5kZXgoRlhfSU5UMzIgbkluZGV4KSBjb25zdA0KLXsNCi0JaWYgKG5JbmRleCA+PSAwICYmIG5JbmRleCA8IG1fYUl0ZW1zLkdldFNpemUoKSkNCi0JCWlmIChDUExTVF9TZWxlY3RfSXRlbSAqIHBJdGVtID0gbV9hSXRlbXMuR2V0QXQobkluZGV4KSkNCi0JCQlyZXR1cm4gcEl0ZW0tPm5JdGVtSW5kZXg7DQotDQotCXJldHVybiAtMTsNCi19DQotDQotRlhfSU5UMzIgQ1BMU1RfU2VsZWN0OjpHZXRTdGF0ZShGWF9JTlQzMiBuSW5kZXgpIGNvbnN0DQotew0KLQlpZiAobkluZGV4ID49IDAgJiYgbkluZGV4IDwgbV9hSXRlbXMuR2V0U2l6ZSgpKQ0KLQkJaWYgKENQTFNUX1NlbGVjdF9JdGVtICogcEl0ZW0gPSBtX2FJdGVtcy5HZXRBdChuSW5kZXgpKQ0KLQkJCXJldHVybiBwSXRlbS0+blN0YXRlOw0KLQ0KLQlyZXR1cm4gMDsNCi19DQotDQotdm9pZCBDUExTVF9TZWxlY3Q6OkRlc2VsZWN0QWxsKCkNCi17DQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUl0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ1BMU1RfU2VsZWN0X0l0ZW0gKiBwSXRlbSA9IG1fYUl0ZW1zLkdldEF0KGkpKQ0KLQkJew0KLQkJCXBJdGVtLT5uU3RhdGUgPSAtMTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQTFNUX1NlbGVjdDo6RG9uZSgpDQotew0KLQlmb3IgKEZYX0lOVDMyIGk9bV9hSXRlbXMuR2V0U2l6ZSgpLTE7IGk+PTA7IGktLSkNCi0JewkNCi0JCWlmIChDUExTVF9TZWxlY3RfSXRlbSAqIHBJdGVtID0gbV9hSXRlbXMuR2V0QXQoaSkpDQotCQl7DQotCQkJaWYgKHBJdGVtLT5uU3RhdGUgPT0gLTEpDQotCQkJew0KLQkJCQlkZWxldGUgcEl0ZW07DQotCQkJCW1fYUl0ZW1zLlJlbW92ZUF0KGkpOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlwSXRlbS0+blN0YXRlID0gMDsNCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9MaXN0Q3RybCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DRlhfTGlzdEN0cmw6OkNGWF9MaXN0Q3RybCgpIDogbV9wTm90aWZ5KE5VTEwpLA0KLQltX3B0U2Nyb2xsUG9zKDAuMGYsMC4wZiksDQotCW1fblNlbEl0ZW0oLTEpLA0KLQltX25Gb290SW5kZXgoLTEpLA0KLQltX2JDdHJsU2VsKEZBTFNFKSwJDQotCW1fbkNhcmV0SW5kZXgoLTEpLA0KLQltX2JOb3RpZnlGbGFnKEZBTFNFKQ0KLXsNCi19DQotDQotQ0ZYX0xpc3RDdHJsOjp+Q0ZYX0xpc3RDdHJsKCkNCi17DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpTZXROb3RpZnkoSUZYX0xpc3RfTm90aWZ5ICogcE5vdGlmeSkNCi17DQotCW1fcE5vdGlmeSA9IHBOb3RpZnk7DQotfQ0KLQ0KLUNQREZfUG9pbnQgQ0ZYX0xpc3RDdHJsOjpJblRvT3V0KGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3QNCi17DQotCUNQREZfUmVjdCByY1BsYXRlID0gR2V0UGxhdGVSZWN0KCk7DQotDQotCXJldHVybiBDUERGX1BvaW50KHBvaW50LnggLSAobV9wdFNjcm9sbFBvcy54IC0gcmNQbGF0ZS5sZWZ0KSwNCi0JCXBvaW50LnkgLSAobV9wdFNjcm9sbFBvcy55IC0gcmNQbGF0ZS50b3ApKTsNCi19DQotDQotQ1BERl9Qb2ludCBDRlhfTGlzdEN0cmw6Ok91dFRvSW4oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdA0KLXsNCi0JQ1BERl9SZWN0IHJjUGxhdGUgPSBHZXRQbGF0ZVJlY3QoKTsNCi0NCi0JcmV0dXJuIENQREZfUG9pbnQocG9pbnQueCArIChtX3B0U2Nyb2xsUG9zLnggLSByY1BsYXRlLmxlZnQpLA0KLQkJcG9pbnQueSArIChtX3B0U2Nyb2xsUG9zLnkgLSByY1BsYXRlLnRvcCkpOw0KLX0NCi0NCi1DUERGX1JlY3QgQ0ZYX0xpc3RDdHJsOjpJblRvT3V0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QpIGNvbnN0DQotew0KLQlDUERGX1BvaW50IHB0TGVmdEJvdHRvbSA9IEluVG9PdXQoQ1BERl9Qb2ludChyZWN0LmxlZnQscmVjdC5ib3R0b20pKTsNCi0JQ1BERl9Qb2ludCBwdFJpZ2h0VG9wID0gSW5Ub091dChDUERGX1BvaW50KHJlY3QucmlnaHQscmVjdC50b3ApKTsNCi0NCi0JcmV0dXJuIENQREZfUmVjdChwdExlZnRCb3R0b20ueCxwdExlZnRCb3R0b20ueSxwdFJpZ2h0VG9wLngscHRSaWdodFRvcC55KTsNCi19DQotDQotQ1BERl9SZWN0IENGWF9MaXN0Q3RybDo6T3V0VG9Jbihjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdA0KLXsNCi0JQ1BERl9Qb2ludCBwdExlZnRCb3R0b20gPSBPdXRUb0luKENQREZfUG9pbnQocmVjdC5sZWZ0LHJlY3QuYm90dG9tKSk7DQotCUNQREZfUG9pbnQgcHRSaWdodFRvcCA9IE91dFRvSW4oQ1BERl9Qb2ludChyZWN0LnJpZ2h0LHJlY3QudG9wKSk7DQotDQotCXJldHVybiBDUERGX1JlY3QocHRMZWZ0Qm90dG9tLngscHRMZWZ0Qm90dG9tLnkscHRSaWdodFRvcC54LHB0UmlnaHRUb3AueSk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpPbk1vdXNlRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCUZYX0lOVDMyIG5IaXRJbmRleCA9IHRoaXMtPkdldEl0ZW1JbmRleChwb2ludCk7DQotDQotCWlmIChJc011bHRpcGxlU2VsKCkpDQotCXsNCi0JCWlmIChiQ3RybCkNCi0JCXsNCi0JCQlpZiAoSXNJdGVtU2VsZWN0ZWQobkhpdEluZGV4KSkNCi0JCQl7DQotCQkJCW1fYVNlbEl0ZW1zLlN1YihuSGl0SW5kZXgpOw0KLQkJCQlTZWxlY3RJdGVtcygpOw0KLQkJCQltX2JDdHJsU2VsID0gRkFMU0U7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCW1fYVNlbEl0ZW1zLkFkZChuSGl0SW5kZXgpOw0KLQkJCQlTZWxlY3RJdGVtcygpOw0KLQkJCQltX2JDdHJsU2VsID0gVFJVRTsNCi0JCQl9CQkNCi0JCQkNCi0JCQltX25Gb290SW5kZXggPSBuSGl0SW5kZXg7DQotCQl9DQotCQllbHNlIGlmIChiU2hpZnQpDQotCQl7DQotCQkJbV9hU2VsSXRlbXMuRGVzZWxlY3RBbGwoKTsNCi0JCQltX2FTZWxJdGVtcy5BZGQobV9uRm9vdEluZGV4LG5IaXRJbmRleCk7DQotCQkJU2VsZWN0SXRlbXMoKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQltX2FTZWxJdGVtcy5EZXNlbGVjdEFsbCgpOw0KLQkJCW1fYVNlbEl0ZW1zLkFkZChuSGl0SW5kZXgpOw0KLQkJCVNlbGVjdEl0ZW1zKCk7DQotDQotCQkJbV9uRm9vdEluZGV4ID0gbkhpdEluZGV4Ow0KLQkJfQ0KLQ0KLQkJU2V0Q2FyZXQobkhpdEluZGV4KTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCVNldFNpbmdsZVNlbGVjdChuSGl0SW5kZXgpOw0KLQl9DQotDQotCWlmICghdGhpcy0+SXNJdGVtVmlzaWJsZShuSGl0SW5kZXgpKQ0KLQkJdGhpcy0+U2Nyb2xsVG9MaXN0SXRlbShuSGl0SW5kZXgpOw0KLX0NCi0NCi12b2lkIENGWF9MaXN0Q3RybDo6T25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpDQotew0KLQlGWF9JTlQzMiBuSGl0SW5kZXggPSB0aGlzLT5HZXRJdGVtSW5kZXgocG9pbnQpOw0KLQ0KLQlpZiAoSXNNdWx0aXBsZVNlbCgpKQ0KLQl7CQkJDQotCQlpZiAoYkN0cmwpDQotCQl7DQotCQkJaWYgKG1fYkN0cmxTZWwpDQotCQkJCW1fYVNlbEl0ZW1zLkFkZChtX25Gb290SW5kZXgsbkhpdEluZGV4KTsNCi0JCQllbHNlDQotCQkJCW1fYVNlbEl0ZW1zLlN1YihtX25Gb290SW5kZXgsbkhpdEluZGV4KTsJCQkNCi0JCQkNCi0JCQlTZWxlY3RJdGVtcygpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCW1fYVNlbEl0ZW1zLkRlc2VsZWN0QWxsKCk7DQotCQkJbV9hU2VsSXRlbXMuQWRkKG1fbkZvb3RJbmRleCxuSGl0SW5kZXgpOw0KLQkJCVNlbGVjdEl0ZW1zKCk7DQotCQl9DQotDQotCQlTZXRDYXJldChuSGl0SW5kZXgpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJU2V0U2luZ2xlU2VsZWN0KG5IaXRJbmRleCk7DQotCX0NCi0NCi0JaWYgKCF0aGlzLT5Jc0l0ZW1WaXNpYmxlKG5IaXRJbmRleCkpDQotCQl0aGlzLT5TY3JvbGxUb0xpc3RJdGVtKG5IaXRJbmRleCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLKEZYX0lOVDMyIG5JdGVtSW5kZXgsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCWlmIChJc011bHRpcGxlU2VsKCkpDQotCXsNCi0JCWlmIChuSXRlbUluZGV4ID49IDAgJiYgbkl0ZW1JbmRleCA8IEdldENvdW50KCkpDQotCQl7DQotCQkJaWYgKGJDdHJsKQ0KLQkJCXsNCi0JCQl9DQotCQkJZWxzZSBpZiAoYlNoaWZ0KQ0KLQkJCXsNCi0JCQkJbV9hU2VsSXRlbXMuRGVzZWxlY3RBbGwoKTsNCi0JCQkJbV9hU2VsSXRlbXMuQWRkKG1fbkZvb3RJbmRleCxuSXRlbUluZGV4KTsNCi0JCQkJU2VsZWN0SXRlbXMoKTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJbV9hU2VsSXRlbXMuRGVzZWxlY3RBbGwoKTsNCi0JCQkJbV9hU2VsSXRlbXMuQWRkKG5JdGVtSW5kZXgpOw0KLQkJCQlTZWxlY3RJdGVtcygpOw0KLQkJCQltX25Gb290SW5kZXggPSBuSXRlbUluZGV4Ow0KLQkJCX0NCi0NCi0JCQlTZXRDYXJldChuSXRlbUluZGV4KTsJDQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlTZXRTaW5nbGVTZWxlY3Qobkl0ZW1JbmRleCk7DQotCX0NCi0NCi0JaWYgKCF0aGlzLT5Jc0l0ZW1WaXNpYmxlKG5JdGVtSW5kZXgpKQ0KLQkJdGhpcy0+U2Nyb2xsVG9MaXN0SXRlbShuSXRlbUluZGV4KTsNCi19DQotDQotdm9pZCBDRlhfTGlzdEN0cmw6Ok9uVktfVVAoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCU9uVksoSXNNdWx0aXBsZVNlbCgpID8gR2V0Q2FyZXQoKS0xIDogR2V0U2VsZWN0KCktMSwgYlNoaWZ0LCBiQ3RybCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLX0RPV04oRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCU9uVksoSXNNdWx0aXBsZVNlbCgpID8gR2V0Q2FyZXQoKSsxIDogR2V0U2VsZWN0KCkrMSwgYlNoaWZ0LCBiQ3RybCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLX0xFRlQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCU9uVksoMCwgYlNoaWZ0LCBiQ3RybCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLX1JJR0hUKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpDQotew0KLQlPblZLKEdldENvdW50KCktMSwgYlNoaWZ0LCBiQ3RybCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLX0hPTUUoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCU9uVksoMCwgYlNoaWZ0LCBiQ3RybCk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLX0VORChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQ0KLXsNCi0JT25WSyhHZXRDb3VudCgpLTEsIGJTaGlmdCwgYkN0cmwpOw0KLX0NCi0NCi1GWF9CT09MCUNGWF9MaXN0Q3RybDo6T25DaGFyKEZYX1dPUkQgbkNoYXIsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkNCi17DQotCUZYX0lOVDMyIG5JbmRleCA9IEdldExhc3RTZWxlY3RlZCgpOwkNCi0JRlhfSU5UMzIgbkZpbmRJbmRleCA9IEZpbmROZXh0KG5JbmRleCxuQ2hhcik7DQotDQotCWlmIChuRmluZEluZGV4ICE9IG5JbmRleCkNCi0Jew0KLQkJT25WSyhuRmluZEluZGV4LCBiU2hpZnQsIGJDdHJsKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotLyogLS0tLS0tLS0gaW5uZXIgbWV0aG9kcyAtLS0tLS0tICovDQotDQotdm9pZCBDRlhfTGlzdEN0cmw6OlNldFBsYXRlUmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0KQ0KLXsNCi0JQ0ZYX0xpc3RDb250YWluZXI6OlNldFBsYXRlUmVjdChyZWN0KTsNCi0JbV9wdFNjcm9sbFBvcy54ID0gcmVjdC5sZWZ0Ow0KLQlTZXRTY3JvbGxQb3MoQ1BERl9Qb2ludChyZWN0LmxlZnQscmVjdC50b3ApKTsJDQotCVJlQXJyYW5nZSgwKTsNCi0JSW52YWxpZGF0ZUl0ZW0oLTEpOw0KLX0NCi0NCi1DUERGX1JlY3QgQ0ZYX0xpc3RDdHJsOjpHZXRJdGVtUmVjdChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0DQotew0KLQlyZXR1cm4gSW5Ub091dChDRlhfTGlzdDo6R2V0SXRlbVJlY3QobkluZGV4KSk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpBZGRTdHJpbmcoRlhfTFBDV1NUUiBzdHJpbmcpDQotew0KLQlBZGRJdGVtKHN0cmluZyk7DQotCVJlQXJyYW5nZShHZXRDb3VudCgpIC0gMSk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpTZXRNdWx0aXBsZVNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4LCBGWF9CT09MIGJTZWxlY3RlZCkNCi17DQotCWlmICghSXNWYWxpZChuSXRlbUluZGV4KSkgcmV0dXJuOw0KLQ0KLQlpZiAoYlNlbGVjdGVkICE9IHRoaXMtPklzSXRlbVNlbGVjdGVkKG5JdGVtSW5kZXgpKQ0KLQl7DQotCQlpZiAoYlNlbGVjdGVkKQ0KLQkJew0KLQkJCVNldEl0ZW1TZWxlY3Qobkl0ZW1JbmRleCxUUlVFKTsNCi0JCQlJbnZhbGlkYXRlSXRlbShuSXRlbUluZGV4KTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlTZXRJdGVtU2VsZWN0KG5JdGVtSW5kZXgsRkFMU0UpOw0KLQkJCUludmFsaWRhdGVJdGVtKG5JdGVtSW5kZXgpOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpTZXRTaW5nbGVTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCkNCi17DQotCWlmICghSXNWYWxpZChuSXRlbUluZGV4KSkgcmV0dXJuOw0KLQ0KLQlpZiAobV9uU2VsSXRlbSAhPSBuSXRlbUluZGV4KQ0KLQl7DQotCQlpZiAobV9uU2VsSXRlbSA+PSAwKQ0KLQkJew0KLQkJCVNldEl0ZW1TZWxlY3QobV9uU2VsSXRlbSxGQUxTRSk7DQotCQkJSW52YWxpZGF0ZUl0ZW0obV9uU2VsSXRlbSk7DQotCQl9DQotCQkNCi0JCVNldEl0ZW1TZWxlY3Qobkl0ZW1JbmRleCxUUlVFKTsNCi0JCUludmFsaWRhdGVJdGVtKG5JdGVtSW5kZXgpOw0KLQkJbV9uU2VsSXRlbSA9IG5JdGVtSW5kZXg7CQkNCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9MaXN0Q3RybDo6U2V0Q2FyZXQoRlhfSU5UMzIgbkl0ZW1JbmRleCkNCi17DQotCWlmICghSXNWYWxpZChuSXRlbUluZGV4KSkgcmV0dXJuOw0KLQ0KLQlpZiAodGhpcy0+SXNNdWx0aXBsZVNlbCgpKQ0KLQl7CQkNCi0JCUZYX0lOVDMyIG5PbGRJbmRleCA9IG1fbkNhcmV0SW5kZXg7DQotDQotCQlpZiAobk9sZEluZGV4ICE9IG5JdGVtSW5kZXgpDQotCQl7DQotCQkJbV9uQ2FyZXRJbmRleCA9IG5JdGVtSW5kZXg7DQotDQotCQkJU2V0SXRlbUNhcmV0KG5PbGRJbmRleCwgRkFMU0UpOw0KLQkJCVNldEl0ZW1DYXJldChuSXRlbUluZGV4LFRSVUUpOw0KLQ0KLQkJCUludmFsaWRhdGVJdGVtKG5PbGRJbmRleCk7DQotCQkJSW52YWxpZGF0ZUl0ZW0obkl0ZW1JbmRleCk7CQkJDQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfTGlzdEN0cmw6OkludmFsaWRhdGVJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpDQotew0KLQlpZiAobV9wTm90aWZ5KQ0KLQl7DQotCQlpZiAobkl0ZW1JbmRleCA9PSAtMSkNCi0JCXsNCi0JCQlpZiAoIW1fYk5vdGlmeUZsYWcpDQotCQkJew0KLQkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQkJQ1BERl9SZWN0IHJjUmVmcmVzaCA9IEdldFBsYXRlUmVjdCgpOw0KLQkJCQltX3BOb3RpZnktPklPbkludmFsaWRhdGVSZWN0KCZyY1JlZnJlc2gpOw0KLQkJCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7DQotCQkJfQ0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmICghbV9iTm90aWZ5RmxhZykNCi0JCQl7DQotCQkJCW1fYk5vdGlmeUZsYWcgPSBUUlVFOw0KLQkJCQlDUERGX1JlY3QgcmNSZWZyZXNoID0gR2V0SXRlbVJlY3Qobkl0ZW1JbmRleCk7DQotCQkJCXJjUmVmcmVzaC5sZWZ0IC09IDEuMGY7DQotCQkJCXJjUmVmcmVzaC5yaWdodCArPSAxLjBmOw0KLQkJCQlyY1JlZnJlc2guYm90dG9tIC09IDEuMGY7DQotCQkJCXJjUmVmcmVzaC50b3AgKz0gMS4wZjsNCi0NCi0JCQkJbV9wTm90aWZ5LT5JT25JbnZhbGlkYXRlUmVjdCgmcmNSZWZyZXNoKTsNCi0JCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENGWF9MaXN0Q3RybDo6U2VsZWN0SXRlbXMoKQ0KLXsNCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hU2VsSXRlbXMuR2V0Q291bnQoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlGWF9JTlQzMiBuSXRlbUluZGV4ID0gbV9hU2VsSXRlbXMuR2V0SXRlbUluZGV4KGkpOw0KLQkJRlhfSU5UMzIgblN0YXRlID0gbV9hU2VsSXRlbXMuR2V0U3RhdGUoaSk7DQotDQotCQlzd2l0Y2goblN0YXRlKQ0KLQkJew0KLQkJY2FzZSAxOg0KLQkJCVNldE11bHRpcGxlU2VsZWN0KG5JdGVtSW5kZXgsIFRSVUUpOwkJCQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSAtMToNCi0JCQlTZXRNdWx0aXBsZVNlbGVjdChuSXRlbUluZGV4LCBGQUxTRSk7DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi0NCi0JbV9hU2VsSXRlbXMuRG9uZSgpOw0KLX0NCi0NCi12b2lkIENGWF9MaXN0Q3RybDo6U2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgpDQotew0KLQlpZiAoIUlzVmFsaWQobkl0ZW1JbmRleCkpIHJldHVybjsNCi0NCi0JaWYgKHRoaXMtPklzTXVsdGlwbGVTZWwoKSkNCi0Jew0KLQkJbV9hU2VsSXRlbXMuQWRkKG5JdGVtSW5kZXgpOw0KLQkJU2VsZWN0SXRlbXMoKTsNCi0JfQ0KLQllbHNlDQotCQlTZXRTaW5nbGVTZWxlY3Qobkl0ZW1JbmRleCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ0ZYX0xpc3RDdHJsOjpJc0l0ZW1WaXNpYmxlKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0DQotew0KLQlDUERGX1JlY3QgcmNQbGF0ZSA9IHRoaXMtPkdldFBsYXRlUmVjdCgpOw0KLQlDUERGX1JlY3QgcmNJdGVtID0gdGhpcy0+R2V0SXRlbVJlY3Qobkl0ZW1JbmRleCk7DQotDQotCXJldHVybiByY0l0ZW0uYm90dG9tID49IHJjUGxhdGUuYm90dG9tICYmIHJjSXRlbS50b3AgPD0gcmNQbGF0ZS50b3A7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpTY3JvbGxUb0xpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpDQotew0KLQlpZiAoIUlzVmFsaWQobkl0ZW1JbmRleCkpIHJldHVybjsNCi0NCi0JQ1BERl9SZWN0IHJjUGxhdGUgPSB0aGlzLT5HZXRQbGF0ZVJlY3QoKTsNCi0JQ1BERl9SZWN0IHJjSXRlbSA9IENGWF9MaXN0OjpHZXRJdGVtUmVjdChuSXRlbUluZGV4KTsNCi0JQ1BERl9SZWN0IHJjSXRlbUN0cmwgPSBHZXRJdGVtUmVjdChuSXRlbUluZGV4KTsNCi0NCi0JaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocmNJdGVtQ3RybC5ib3R0b20sIHJjUGxhdGUuYm90dG9tKSkNCi0Jew0KLQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocmNJdGVtQ3RybC50b3AsIHJjUGxhdGUudG9wKSkNCi0JCXsNCi0JCQlTZXRTY3JvbGxQb3NZKHJjSXRlbS5ib3R0b20gKyByY1BsYXRlLkhlaWdodCgpKTsNCi0JCX0NCi0JfQ0KLQllbHNlIGlmIChGWF9FRElUX0lzRmxvYXRCaWdnZXIocmNJdGVtQ3RybC50b3AsIHJjUGxhdGUudG9wKSkNCi0Jew0KLQkJaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihyY0l0ZW1DdHJsLmJvdHRvbSwgcmNQbGF0ZS5ib3R0b20pKQ0KLQkJew0KLQkJCVNldFNjcm9sbFBvc1kocmNJdGVtLnRvcCk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfTGlzdEN0cmw6OlNldFNjcm9sbEluZm8oKQ0KLXsNCi0JaWYgKG1fcE5vdGlmeSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjUGxhdGUgPSBHZXRQbGF0ZVJlY3QoKTsNCi0JCUNQREZfUmVjdCByY0NvbnRlbnQgPSBDRlhfTGlzdDo6R2V0Q29udGVudFJlY3QoKTsNCi0NCi0JCWlmICghbV9iTm90aWZ5RmxhZykNCi0JCXsNCi0JCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQltX3BOb3RpZnktPklPblNldFNjcm9sbEluZm9ZKHJjUGxhdGUuYm90dG9tLCByY1BsYXRlLnRvcCwgDQotCQkJCQlyY0NvbnRlbnQuYm90dG9tLCByY0NvbnRlbnQudG9wLCBHZXRGaXJzdEhlaWdodCgpLCByY1BsYXRlLkhlaWdodCgpKTsNCi0JCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDRlhfTGlzdEN0cmw6OlNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpDQotew0KLQlTZXRTY3JvbGxQb3NZKHBvaW50LnkpOw0KLX0NCi0NCi12b2lkIENGWF9MaXN0Q3RybDo6U2V0U2Nyb2xsUG9zWShGWF9GTE9BVCBmeSkNCi17DQotCWlmICghRlhfRURJVF9Jc0Zsb2F0RXF1YWwobV9wdFNjcm9sbFBvcy55LGZ5KSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjUGxhdGUgPSB0aGlzLT5HZXRQbGF0ZVJlY3QoKTsNCi0JCUNQREZfUmVjdCByY0NvbnRlbnQgPSBDRlhfTGlzdDo6R2V0Q29udGVudFJlY3QoKTsNCi0NCi0JCWlmIChyY1BsYXRlLkhlaWdodCgpID4gcmNDb250ZW50LkhlaWdodCgpKQ0KLQkJew0KLQkJCWZ5ID0gcmNQbGF0ZS50b3A7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIoZnkgLSByY1BsYXRlLkhlaWdodCgpLCByY0NvbnRlbnQuYm90dG9tKSkNCi0JCQl7DQotCQkJCWZ5ID0gcmNDb250ZW50LmJvdHRvbSArIHJjUGxhdGUuSGVpZ2h0KCk7DQotCQkJfQ0KLQkJCWVsc2UgaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihmeSwgcmNDb250ZW50LnRvcCkpDQotCQkJew0KLQkJCQlmeSA9IHJjQ29udGVudC50b3A7DQotCQkJfQ0KLQkJfQ0KLQ0KLQkJbV9wdFNjcm9sbFBvcy55ID0gZnk7DQotCQlJbnZhbGlkYXRlSXRlbSgtMSk7DQotDQotCQlpZiAobV9wTm90aWZ5KSANCi0JCXsNCi0JCQlpZiAoIW1fYk5vdGlmeUZsYWcpDQotCQkJew0KLQkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsNCi0JCQkJbV9wTm90aWZ5LT5JT25TZXRTY3JvbGxQb3NZKGZ5KTsNCi0JCQkJbV9iTm90aWZ5RmxhZyA9IEZBTFNFOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi1DUERGX1JlY3QgQ0ZYX0xpc3RDdHJsOjpHZXRDb250ZW50UmVjdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gSW5Ub091dChDRlhfTGlzdDo6R2V0Q29udGVudFJlY3QoKSk7DQotfQ0KLQ0KLXZvaWQgQ0ZYX0xpc3RDdHJsOjpSZUFycmFuZ2UoRlhfSU5UMzIgbkl0ZW1JbmRleCkNCi17DQotCUNGWF9MaXN0OjpSZUFycmFuZ2Uobkl0ZW1JbmRleCk7DQotCVNldFNjcm9sbEluZm8oKTsNCi19DQotDQotdm9pZCBDRlhfTGlzdEN0cmw6OlNldFRvcEl0ZW0oRlhfSU5UMzIgbkluZGV4KQ0KLXsNCi0JaWYgKElzVmFsaWQobkluZGV4KSkNCi0Jew0KLQkJdGhpcy0+R2V0UGxhdGVSZWN0KCk7DQotCQlDUERGX1JlY3QgcmNJdGVtID0gQ0ZYX0xpc3Q6OkdldEl0ZW1SZWN0KG5JbmRleCk7DQotCQlTZXRTY3JvbGxQb3NZKHJjSXRlbS50b3ApOw0KLQl9DQotfQ0KLQ0KLUZYX0lOVDMyIENGWF9MaXN0Q3RybDo6R2V0VG9wSXRlbSgpIGNvbnN0DQotew0KLQlGWF9JTlQzMiBuSXRlbUluZGV4ID0gdGhpcy0+R2V0SXRlbUluZGV4KHRoaXMtPkdldEJUUG9pbnQoKSk7DQotDQotCWlmICghSXNJdGVtVmlzaWJsZShuSXRlbUluZGV4KSAmJiBJc0l0ZW1WaXNpYmxlKG5JdGVtSW5kZXggKyAxKSkNCi0JCQluSXRlbUluZGV4ICs9IDE7DQotDQotCXJldHVybiBuSXRlbUluZGV4Ow0KLX0NCi0NCi12b2lkIENGWF9MaXN0Q3RybDo6RW1wdHkoKQ0KLXsNCi0JQ0ZYX0xpc3Q6OkVtcHR5KCk7DQotCUludmFsaWRhdGVJdGVtKC0xKTsNCi19DQotDQotdm9pZCBDRlhfTGlzdEN0cmw6OkNhbmNlbCgpDQotew0KLQltX2FTZWxJdGVtcy5EZXNlbGVjdEFsbCgpOw0KLX0NCi0NCi1GWF9JTlQzMiBDRlhfTGlzdEN0cmw6OkdldEl0ZW1JbmRleChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0DQotew0KLQlyZXR1cm4gQ0ZYX0xpc3Q6OkdldEl0ZW1JbmRleChPdXRUb0luKHBvaW50KSk7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENGWF9MaXN0Q3RybDo6R2V0VGV4dCgpIGNvbnN0DQotew0KLQlpZiAodGhpcy0+SXNNdWx0aXBsZVNlbCgpKQ0KLQkJcmV0dXJuIHRoaXMtPkdldEl0ZW1UZXh0KHRoaXMtPm1fbkNhcmV0SW5kZXgpOwkNCi0JZWxzZQ0KLQkJcmV0dXJuIHRoaXMtPkdldEl0ZW1UZXh0KHRoaXMtPm1fblNlbEl0ZW0pOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9zdHViLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9lZGl0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9saXN0LmgiCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0xpc3RJdGVtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0ZYX0xpc3RJdGVtOjpDRlhfTGlzdEl0ZW0oKSA6IG1fcEVkaXQoTlVMTCksCisJbV9iU2VsZWN0ZWQoRkFMU0UpLAorCW1fYkNhcmV0KEZBTFNFKSwKKwltX3JjTGlzdEl0ZW0oMC4wZiwwLjBmLDAuMGYsMC4wZikKK3sKKwltX3BFZGl0ID0gSUZYX0VkaXQ6Ok5ld0VkaXQoKTsKKwlBU1NFUlQobV9wRWRpdCAhPSBOVUxMKTsKKworCW1fcEVkaXQtPlNldEFsaWdubWVudFYoMSk7CisJbV9wRWRpdC0+SW5pdGlhbGl6ZSgpOworfQorCitDRlhfTGlzdEl0ZW06On5DRlhfTGlzdEl0ZW0oKQoreworCUlGWF9FZGl0OjpEZWxFZGl0KG1fcEVkaXQpOworfQorCit2b2lkIENGWF9MaXN0SXRlbTo6U2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApCit7CisJaWYgKG1fcEVkaXQpCisJCW1fcEVkaXQtPlNldEZvbnRNYXAocEZvbnRNYXApOworfQorCitJRlhfRWRpdCogQ0ZYX0xpc3RJdGVtOjpHZXRFZGl0KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wRWRpdDsKK30KKworSUZYX0VkaXRfSXRlcmF0b3IqCUNGWF9MaXN0SXRlbTo6R2V0SXRlcmF0b3IoKSBjb25zdAoreworCWlmIChtX3BFZGl0KQorCQlyZXR1cm4gbV9wRWRpdC0+R2V0SXRlcmF0b3IoKTsKKworCXJldHVybiBOVUxMOworfQorCit2b2lkIENGWF9MaXN0SXRlbTo6U2V0UmVjdChjb25zdCBDTFNUX1JlY3QgJiByZWN0KQoreworCW1fcmNMaXN0SXRlbSA9IHJlY3Q7Cit9CisKK0NMU1RfUmVjdCBDRlhfTGlzdEl0ZW06OkdldFJlY3QoKSBjb25zdAoreworCXJldHVybiBtX3JjTGlzdEl0ZW07Cit9CisKK0ZYX0JPT0wgQ0ZYX0xpc3RJdGVtOjpJc1NlbGVjdGVkKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9iU2VsZWN0ZWQ7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RJdGVtOjpTZXRTZWxlY3QoRlhfQk9PTCBiU2VsZWN0ZWQpCit7CisJbV9iU2VsZWN0ZWQgPSBiU2VsZWN0ZWQ7Cit9CisKK0ZYX0JPT0wgQ0ZYX0xpc3RJdGVtOjpJc0NhcmV0KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9iQ2FyZXQ7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RJdGVtOjpTZXRDYXJldChGWF9CT09MIGJDYXJldCkKK3sKKwltX2JDYXJldCA9IGJDYXJldDsKK30KKwordm9pZCBDRlhfTGlzdEl0ZW06OlNldFRleHQoRlhfTFBDV1NUUiB0ZXh0KQoreworCWlmIChtX3BFZGl0KQorCQltX3BFZGl0LT5TZXRUZXh0KHRleHQpOworfQorCit2b2lkIENGWF9MaXN0SXRlbTo6U2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKQoreworCWlmIChtX3BFZGl0KQorCQltX3BFZGl0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOworfQorCitGWF9GTE9BVCBDRlhfTGlzdEl0ZW06OkdldEl0ZW1IZWlnaHQoKSBjb25zdAoreworCWlmIChtX3BFZGl0KQorCQlyZXR1cm4gbV9wRWRpdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKKworCXJldHVybiAwLjBmOworfQorCitGWF9XT1JEIENGWF9MaXN0SXRlbTo6R2V0Rmlyc3RDaGFyKCkgY29uc3QKK3sKKwlDUFZUX1dvcmQgd29yZDsKKworCWlmIChJRlhfRWRpdF9JdGVyYXRvcioJcEl0ZXJhdG9yID0gR2V0SXRlcmF0b3IoKSkKKwl7CisJCXBJdGVyYXRvci0+U2V0QXQoMSk7CQkKKwkJcEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpOworCX0KKworCXJldHVybiB3b3JkLldvcmQ7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENGWF9MaXN0SXRlbTo6R2V0VGV4dCgpIGNvbnN0Cit7CisJaWYgKG1fcEVkaXQpCisJCXJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7CisKKwlyZXR1cm4gTCIiOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0ZYX0xpc3QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NGWF9MaXN0OjpDRlhfTGlzdCgpIDogbV9wRm9udE1hcChOVUxMKSwgbV9mRm9udFNpemUoMC4wZiksIG1fYk11bHRpcGxlKEZBTFNFKSAKK3sKK30KKworQ0ZYX0xpc3Q6On5DRlhfTGlzdCgpCit7CisJRW1wdHkoKTsKK30KKwordm9pZCBDRlhfTGlzdDo6RW1wdHkoKQoreworCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUxpc3RJdGVtcy5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJZGVsZXRlIG1fYUxpc3RJdGVtcy5HZXRBdChpKTsKKworCW1fYUxpc3RJdGVtcy5SZW1vdmVBbGwoKTsKK30KKwordm9pZCBDRlhfTGlzdDo6U2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApCit7CisJbV9wRm9udE1hcCA9IHBGb250TWFwOworfQorCit2b2lkIENGWF9MaXN0OjpTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpCit7CisJbV9mRm9udFNpemUgPSBmRm9udFNpemU7Cit9CisKK3ZvaWQgQ0ZYX0xpc3Q6OkFkZEl0ZW0oRlhfTFBDV1NUUiBzdHIpCit7CQorCWlmIChDRlhfTGlzdEl0ZW0gKiBwTGlzdEl0ZW0gPSBuZXcgQ0ZYX0xpc3RJdGVtKCkpCisJeworCQlwTGlzdEl0ZW0tPlNldEZvbnRNYXAobV9wRm9udE1hcCk7CisJCXBMaXN0SXRlbS0+U2V0Rm9udFNpemUobV9mRm9udFNpemUpOworCQlwTGlzdEl0ZW0tPlNldFRleHQoc3RyKTsKKwkJbV9hTGlzdEl0ZW1zLkFkZChwTGlzdEl0ZW0pOworCX0KK30KKwordm9pZCBDRlhfTGlzdDo6UmVBcnJhbmdlKEZYX0lOVDMyIG5JdGVtSW5kZXgpCit7CisJRlhfRkxPQVQgZlBvc1kgPSAwLjBmOworCisJaWYgKENGWF9MaXN0SXRlbSAqIHBQcmV2SXRlbSA9IG1fYUxpc3RJdGVtcy5HZXRBdChuSXRlbUluZGV4IC0gMSkpCisJCWZQb3NZID0gcFByZXZJdGVtLT5HZXRSZWN0KCkuYm90dG9tOworCQorCWZvciAoRlhfSU5UMzIgaT1uSXRlbUluZGV4LHN6PW1fYUxpc3RJdGVtcy5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChDRlhfTGlzdEl0ZW0gKiBwTGlzdEl0ZW0gPSBtX2FMaXN0SXRlbXMuR2V0QXQoaSkpCisJCXsKKwkJCUZYX0ZMT0FUIGZMaXN0SXRlbUhlaWdodCA9IHBMaXN0SXRlbS0+R2V0SXRlbUhlaWdodCgpOworCQkJcExpc3RJdGVtLT5TZXRSZWN0KENMU1RfUmVjdCgwLjBmLGZQb3NZLDAuMGYsZlBvc1kgKyBmTGlzdEl0ZW1IZWlnaHQpKTsKKwkJCWZQb3NZICs9IGZMaXN0SXRlbUhlaWdodDsJCQkKKwkJfQorCX0KKworCVNldENvbnRlbnRSZWN0KENMU1RfUmVjdCgwLjBmLDAuMGYsMC4wZixmUG9zWSkpOwkKK30KKworSUZYX0VkaXQgKiBDRlhfTGlzdDo6R2V0SXRlbUVkaXQoRlhfSU5UMzIgbkluZGV4KSBjb25zdAoreworCWlmIChDRlhfTGlzdEl0ZW0gKiBwTGlzdEl0ZW0gPSBtX2FMaXN0SXRlbXMuR2V0QXQobkluZGV4KSkKKwl7CisJCXJldHVybiBwTGlzdEl0ZW0tPkdldEVkaXQoKTsKKwl9CisKKwlyZXR1cm4gTlVMTDsKK30KKworRlhfSU5UMzIgQ0ZYX0xpc3Q6OkdldENvdW50KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9hTGlzdEl0ZW1zLkdldFNpemUoKTsKK30KKworQ1BERl9SZWN0IENGWF9MaXN0OjpHZXRQbGF0ZVJlY3QoKSBjb25zdAoreworCXJldHVybiBDRlhfTGlzdENvbnRhaW5lcjo6R2V0UGxhdGVSZWN0KCk7Cit9CisKK0NQREZfUmVjdCBDRlhfTGlzdDo6R2V0Q29udGVudFJlY3QoKSBjb25zdAoreworCXJldHVybiBJbm5lclRvT3V0ZXIoQ0ZYX0xpc3RDb250YWluZXI6OkdldENvbnRlbnRSZWN0KCkpOworfQorCitGWF9GTE9BVCBDRlhfTGlzdDo6R2V0Rm9udFNpemUoKSBjb25zdAoreworCXJldHVybiBtX2ZGb250U2l6ZTsKK30KKworRlhfSU5UMzIgQ0ZYX0xpc3Q6OkdldEl0ZW1JbmRleChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0Cit7CisJQ1BERl9Qb2ludCBwdCA9IE91dGVyVG9Jbm5lcihwb2ludCk7CisKKwlGWF9CT09MIGJGaXJzdCA9IFRSVUU7CisJRlhfQk9PTCBiTGFzdCA9IFRSVUU7CisKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FMaXN0SXRlbXMuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KGkpKQorCQl7CisJCQlDTFNUX1JlY3QgcmNMaXN0SXRlbSA9IHBMaXN0SXRlbS0+R2V0UmVjdCgpOworCisJCQlpZiAoRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKHB0LnksIHJjTGlzdEl0ZW0udG9wKSkKKwkJCXsJCQkKKwkJCQliRmlyc3QgPSBGQUxTRTsKKwkJCX0KKworCQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocHQueSwgcmNMaXN0SXRlbS5ib3R0b20pKQorCQkJeworCQkJCWJMYXN0ID0gRkFMU0U7CisJCQl9CisKKwkJCWlmIChwdC55ID49IHJjTGlzdEl0ZW0udG9wICYmIHB0LnkgPCByY0xpc3RJdGVtLmJvdHRvbSkKKwkJCXsKKwkJCQlyZXR1cm4gaTsKKwkJCX0KKwkJfQorCX0KKworCWlmIChiRmlyc3QpIHJldHVybiAwOworCWlmIChiTGFzdCkgcmV0dXJuIG1fYUxpc3RJdGVtcy5HZXRTaXplKCktMTsKKworCXJldHVybiAtMTsKK30KKworRlhfRkxPQVQgQ0ZYX0xpc3Q6OkdldEZpcnN0SGVpZ2h0KCkgY29uc3QKK3sKKwlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KDApKQorCXsKKwkJcmV0dXJuIHBMaXN0SXRlbS0+R2V0SXRlbUhlaWdodCgpOworCX0KKworCXJldHVybiAxLjBmOworfQorCitGWF9JTlQzMiBDRlhfTGlzdDo6R2V0Rmlyc3RTZWxlY3RlZCgpIGNvbnN0Cit7CisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hTGlzdEl0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJaWYgKENGWF9MaXN0SXRlbSAqIHBMaXN0SXRlbSA9IG1fYUxpc3RJdGVtcy5HZXRBdChpKSkKKwkJeworCQkJaWYgKHBMaXN0SXRlbS0+SXNTZWxlY3RlZCgpKQorCQkJCXJldHVybiBpOworCQl9CisJfQorCXJldHVybiAtMTsKK30KKworRlhfSU5UMzIgQ0ZYX0xpc3Q6OkdldExhc3RTZWxlY3RlZCgpIGNvbnN0Cit7CisJZm9yIChGWF9JTlQzMiBpPW1fYUxpc3RJdGVtcy5HZXRTaXplKCktMTsgaT49MDsgaS0tKQorCXsKKwkJaWYgKENGWF9MaXN0SXRlbSAqIHBMaXN0SXRlbSA9IG1fYUxpc3RJdGVtcy5HZXRBdChpKSkKKwkJeworCQkJaWYgKHBMaXN0SXRlbS0+SXNTZWxlY3RlZCgpKQorCQkJCXJldHVybiBpOworCQl9CisJfQorCXJldHVybiAtMTsKK30KKworRlhfV0NIQVIgQ0ZYX0xpc3Q6OlRvdXBwZXIoRlhfV0NIQVIgYykgY29uc3QKK3sKKwlpZiAoIChjID49ICdhJykgJiYgKGMgPD0gJ3onKSApCisJCWMgPSBjIC0gKCdhJyAtICdBJyk7CisJcmV0dXJuIGM7Cit9CisKK0ZYX0lOVDMyIENGWF9MaXN0OjpGaW5kTmV4dChGWF9JTlQzMiBuSW5kZXgsRlhfV0NIQVIgbkNoYXIpIGNvbnN0Cit7CisJRlhfSU5UMzIgbkNpcmNsZUluZGV4ID0gbkluZGV4OworCisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hTGlzdEl0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJbkNpcmNsZUluZGV4ICsrOworCQlpZiAobkNpcmNsZUluZGV4ID49IHN6KSBuQ2lyY2xlSW5kZXggPSAwOworCisJCWlmIChDRlhfTGlzdEl0ZW0gKiBwTGlzdEl0ZW0gPSBtX2FMaXN0SXRlbXMuR2V0QXQobkNpcmNsZUluZGV4KSkKKwkJeworCQkJaWYgKFRvdXBwZXIocExpc3RJdGVtLT5HZXRGaXJzdENoYXIoKSkgPT0gVG91cHBlcihuQ2hhcikpCisJCQkJcmV0dXJuIG5DaXJjbGVJbmRleDsKKwkJfQorCX0KKworCXJldHVybiBuQ2lyY2xlSW5kZXg7Cit9CisKK0NQREZfUmVjdCBDRlhfTGlzdDo6R2V0SXRlbVJlY3QoRlhfSU5UMzIgbkluZGV4KSBjb25zdAoreworCWlmIChDRlhfTGlzdEl0ZW0gKiBwTGlzdEl0ZW0gPSBtX2FMaXN0SXRlbXMuR2V0QXQobkluZGV4KSkKKwl7CisJCUNQREZfUmVjdCByY0l0ZW0gPSBwTGlzdEl0ZW0tPkdldFJlY3QoKTsKKwkJcmNJdGVtLmxlZnQgPSAwLjBmOworCQlyY0l0ZW0ucmlnaHQgPSBHZXRQbGF0ZVJlY3QoKS5XaWR0aCgpOworCQlyZXR1cm4gSW5uZXJUb091dGVyKHJjSXRlbSk7CisJfQorCisJcmV0dXJuIENQREZfUmVjdCgpOworfQorCitGWF9CT09MIENGWF9MaXN0OjpJc0l0ZW1TZWxlY3RlZChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0Cit7CisJaWYgKENGWF9MaXN0SXRlbSAqIHBMaXN0SXRlbSA9IG1fYUxpc3RJdGVtcy5HZXRBdChuSW5kZXgpKQorCXsKKwkJcmV0dXJuIHBMaXN0SXRlbS0+SXNTZWxlY3RlZCgpOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDRlhfTGlzdDo6U2V0SXRlbVNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4LCBGWF9CT09MIGJTZWxlY3RlZCkKK3sKKwlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KG5JdGVtSW5kZXgpKQorCXsKKwkJcExpc3RJdGVtLT5TZXRTZWxlY3QoYlNlbGVjdGVkKTsKKwl9Cit9CisKK3ZvaWQgQ0ZYX0xpc3Q6OlNldEl0ZW1DYXJldChGWF9JTlQzMiBuSXRlbUluZGV4LCBGWF9CT09MIGJDYXJldCkKK3sKKwlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KG5JdGVtSW5kZXgpKQorCXsKKwkJcExpc3RJdGVtLT5TZXRDYXJldChiQ2FyZXQpOwkJCisJfQorfQorCit2b2lkIENGWF9MaXN0OjpTZXRNdWx0aXBsZVNlbChGWF9CT09MIGJNdWx0aXBsZSkKK3sKKwltX2JNdWx0aXBsZSA9IGJNdWx0aXBsZTsKK30KKworRlhfQk9PTCBDRlhfTGlzdDo6SXNNdWx0aXBsZVNlbCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fYk11bHRpcGxlOworfQorCitGWF9CT09MIENGWF9MaXN0OjpJc1ZhbGlkKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Cit7CisJcmV0dXJuIG5JdGVtSW5kZXggPj0gMCAmJiBuSXRlbUluZGV4IDwgbV9hTGlzdEl0ZW1zLkdldFNpemUoKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ0ZYX0xpc3Q6OkdldEl0ZW1UZXh0KEZYX0lOVDMyIG5JbmRleCkgY29uc3QKK3sKKwlpZiAoQ0ZYX0xpc3RJdGVtICogcExpc3RJdGVtID0gbV9hTGlzdEl0ZW1zLkdldEF0KG5JbmRleCkpCisJeworCQlyZXR1cm4gcExpc3RJdGVtLT5HZXRUZXh0KCk7CisJfQorCisJcmV0dXJuIEwiIjsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQTFNUX1NlbGVjdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQTFNUX1NlbGVjdDo6Q1BMU1RfU2VsZWN0KCkKK3sKK30KKworQ1BMU1RfU2VsZWN0Ojp+Q1BMU1RfU2VsZWN0KCkKK3sKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FJdGVtcy5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJZGVsZXRlIG1fYUl0ZW1zLkdldEF0KGkpOworCisJbV9hSXRlbXMuUmVtb3ZlQWxsKCk7Cit9CisKK3ZvaWQgQ1BMU1RfU2VsZWN0OjpBZGQoRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlGWF9JTlQzMiBuSW5kZXggPSBGaW5kKG5JdGVtSW5kZXgpOworCisJaWYgKG5JbmRleCA8IDApIAorCQltX2FJdGVtcy5BZGQobmV3IENQTFNUX1NlbGVjdF9JdGVtKG5JdGVtSW5kZXgsMSkpOworCWVsc2UKKwl7CisJCWlmIChDUExTVF9TZWxlY3RfSXRlbSAqIHBJdGVtID0gbV9hSXRlbXMuR2V0QXQobkluZGV4KSkKKwkJeworCQkJcEl0ZW0tPm5TdGF0ZSA9IDE7CisJCX0KKwl9Cit9CisKK3ZvaWQgQ1BMU1RfU2VsZWN0OjpBZGQoRlhfSU5UMzIgbkJlZ2luSW5kZXgsIEZYX0lOVDMyIG5FbmRJbmRleCkKK3sKKwlpZiAobkJlZ2luSW5kZXggPiBuRW5kSW5kZXgpCisJeworCQlGWF9JTlQzMiBuVGVtcCA9IG5FbmRJbmRleDsKKwkJbkVuZEluZGV4ID0gbkJlZ2luSW5kZXg7CisJCW5CZWdpbkluZGV4ID0gblRlbXA7CisJfQorCisJZm9yIChGWF9JTlQzMiBpPW5CZWdpbkluZGV4OyBpPD1uRW5kSW5kZXg7IGkrKykJQWRkKGkpOworfQorCit2b2lkIENQTFNUX1NlbGVjdDo6U3ViKEZYX0lOVDMyIG5JdGVtSW5kZXgpCit7CisJZm9yIChGWF9JTlQzMiBpPW1fYUl0ZW1zLkdldFNpemUoKS0xOyBpPj0wOyBpLS0pCisJeworCQlpZiAoQ1BMU1RfU2VsZWN0X0l0ZW0gKiBwSXRlbSA9IG1fYUl0ZW1zLkdldEF0KGkpKQorCQkJaWYgKHBJdGVtLT5uSXRlbUluZGV4ID09IG5JdGVtSW5kZXgpCisJCQkJcEl0ZW0tPm5TdGF0ZSA9IC0xOworCX0KK30KKwordm9pZCBDUExTVF9TZWxlY3Q6OlN1YihGWF9JTlQzMiBuQmVnaW5JbmRleCwgRlhfSU5UMzIgbkVuZEluZGV4KQoreworCWlmIChuQmVnaW5JbmRleCA+IG5FbmRJbmRleCkKKwl7CisJCUZYX0lOVDMyIG5UZW1wID0gbkVuZEluZGV4OworCQluRW5kSW5kZXggPSBuQmVnaW5JbmRleDsKKwkJbkJlZ2luSW5kZXggPSBuVGVtcDsKKwl9CisKKwlmb3IgKEZYX0lOVDMyIGk9bkJlZ2luSW5kZXg7IGk8PW5FbmRJbmRleDsgaSsrKQlTdWIoaSk7Cit9CisKK0ZYX0lOVDMyIENQTFNUX1NlbGVjdDo6RmluZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdAoreworCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUl0ZW1zLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJaWYgKENQTFNUX1NlbGVjdF9JdGVtICogcEl0ZW0gPSBtX2FJdGVtcy5HZXRBdChpKSkKKwkJeworCQkJaWYgKHBJdGVtLT5uSXRlbUluZGV4ID09IG5JdGVtSW5kZXgpCisJCQkJcmV0dXJuIGk7CisJCX0KKwl9CisKKwlyZXR1cm4gLTE7Cit9CisKK0ZYX0JPT0wgQ1BMU1RfU2VsZWN0OjpJc0V4aXN0KEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Cit7CisJcmV0dXJuIEZpbmQobkl0ZW1JbmRleCkgPj0gMDsKK30KKworRlhfSU5UMzIgQ1BMU1RfU2VsZWN0OjpHZXRDb3VudCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fYUl0ZW1zLkdldFNpemUoKTsKK30KKworRlhfSU5UMzIgQ1BMU1RfU2VsZWN0OjpHZXRJdGVtSW5kZXgoRlhfSU5UMzIgbkluZGV4KSBjb25zdAoreworCWlmIChuSW5kZXggPj0gMCAmJiBuSW5kZXggPCBtX2FJdGVtcy5HZXRTaXplKCkpCisJCWlmIChDUExTVF9TZWxlY3RfSXRlbSAqIHBJdGVtID0gbV9hSXRlbXMuR2V0QXQobkluZGV4KSkKKwkJCXJldHVybiBwSXRlbS0+bkl0ZW1JbmRleDsKKworCXJldHVybiAtMTsKK30KKworRlhfSU5UMzIgQ1BMU1RfU2VsZWN0OjpHZXRTdGF0ZShGWF9JTlQzMiBuSW5kZXgpIGNvbnN0Cit7CisJaWYgKG5JbmRleCA+PSAwICYmIG5JbmRleCA8IG1fYUl0ZW1zLkdldFNpemUoKSkKKwkJaWYgKENQTFNUX1NlbGVjdF9JdGVtICogcEl0ZW0gPSBtX2FJdGVtcy5HZXRBdChuSW5kZXgpKQorCQkJcmV0dXJuIHBJdGVtLT5uU3RhdGU7CisKKwlyZXR1cm4gMDsKK30KKwordm9pZCBDUExTVF9TZWxlY3Q6OkRlc2VsZWN0QWxsKCkKK3sKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FJdGVtcy5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChDUExTVF9TZWxlY3RfSXRlbSAqIHBJdGVtID0gbV9hSXRlbXMuR2V0QXQoaSkpCisJCXsKKwkJCXBJdGVtLT5uU3RhdGUgPSAtMTsKKwkJfQorCX0KK30KKwordm9pZCBDUExTVF9TZWxlY3Q6OkRvbmUoKQoreworCWZvciAoRlhfSU5UMzIgaT1tX2FJdGVtcy5HZXRTaXplKCktMTsgaT49MDsgaS0tKQorCXsJCisJCWlmIChDUExTVF9TZWxlY3RfSXRlbSAqIHBJdGVtID0gbV9hSXRlbXMuR2V0QXQoaSkpCisJCXsKKwkJCWlmIChwSXRlbS0+blN0YXRlID09IC0xKQorCQkJeworCQkJCWRlbGV0ZSBwSXRlbTsKKwkJCQltX2FJdGVtcy5SZW1vdmVBdChpKTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlwSXRlbS0+blN0YXRlID0gMDsKKwkJCX0KKwkJfQorCX0KK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENGWF9MaXN0Q3RybCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0ZYX0xpc3RDdHJsOjpDRlhfTGlzdEN0cmwoKSA6IG1fcE5vdGlmeShOVUxMKSwKKwltX3B0U2Nyb2xsUG9zKDAuMGYsMC4wZiksCisJbV9uU2VsSXRlbSgtMSksCisJbV9uRm9vdEluZGV4KC0xKSwKKwltX2JDdHJsU2VsKEZBTFNFKSwJCisJbV9uQ2FyZXRJbmRleCgtMSksCisJbV9iTm90aWZ5RmxhZyhGQUxTRSkKK3sKK30KKworQ0ZYX0xpc3RDdHJsOjp+Q0ZYX0xpc3RDdHJsKCkKK3sKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OlNldE5vdGlmeShJRlhfTGlzdF9Ob3RpZnkgKiBwTm90aWZ5KQoreworCW1fcE5vdGlmeSA9IHBOb3RpZnk7Cit9CisKK0NQREZfUG9pbnQgQ0ZYX0xpc3RDdHJsOjpJblRvT3V0KGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3QKK3sKKwlDUERGX1JlY3QgcmNQbGF0ZSA9IEdldFBsYXRlUmVjdCgpOworCisJcmV0dXJuIENQREZfUG9pbnQocG9pbnQueCAtIChtX3B0U2Nyb2xsUG9zLnggLSByY1BsYXRlLmxlZnQpLAorCQlwb2ludC55IC0gKG1fcHRTY3JvbGxQb3MueSAtIHJjUGxhdGUudG9wKSk7Cit9CisKK0NQREZfUG9pbnQgQ0ZYX0xpc3RDdHJsOjpPdXRUb0luKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3QKK3sKKwlDUERGX1JlY3QgcmNQbGF0ZSA9IEdldFBsYXRlUmVjdCgpOworCisJcmV0dXJuIENQREZfUG9pbnQocG9pbnQueCArIChtX3B0U2Nyb2xsUG9zLnggLSByY1BsYXRlLmxlZnQpLAorCQlwb2ludC55ICsgKG1fcHRTY3JvbGxQb3MueSAtIHJjUGxhdGUudG9wKSk7Cit9CisKK0NQREZfUmVjdCBDRlhfTGlzdEN0cmw6OkluVG9PdXQoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgY29uc3QKK3sKKwlDUERGX1BvaW50IHB0TGVmdEJvdHRvbSA9IEluVG9PdXQoQ1BERl9Qb2ludChyZWN0LmxlZnQscmVjdC5ib3R0b20pKTsKKwlDUERGX1BvaW50IHB0UmlnaHRUb3AgPSBJblRvT3V0KENQREZfUG9pbnQocmVjdC5yaWdodCxyZWN0LnRvcCkpOworCisJcmV0dXJuIENQREZfUmVjdChwdExlZnRCb3R0b20ueCxwdExlZnRCb3R0b20ueSxwdFJpZ2h0VG9wLngscHRSaWdodFRvcC55KTsKK30KKworQ1BERl9SZWN0IENGWF9MaXN0Q3RybDo6T3V0VG9Jbihjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdAoreworCUNQREZfUG9pbnQgcHRMZWZ0Qm90dG9tID0gT3V0VG9JbihDUERGX1BvaW50KHJlY3QubGVmdCxyZWN0LmJvdHRvbSkpOworCUNQREZfUG9pbnQgcHRSaWdodFRvcCA9IE91dFRvSW4oQ1BERl9Qb2ludChyZWN0LnJpZ2h0LHJlY3QudG9wKSk7CisKKwlyZXR1cm4gQ1BERl9SZWN0KHB0TGVmdEJvdHRvbS54LHB0TGVmdEJvdHRvbS55LHB0UmlnaHRUb3AueCxwdFJpZ2h0VG9wLnkpOworfQorCit2b2lkIENGWF9MaXN0Q3RybDo6T25Nb3VzZURvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpCit7CisJRlhfSU5UMzIgbkhpdEluZGV4ID0gdGhpcy0+R2V0SXRlbUluZGV4KHBvaW50KTsKKworCWlmIChJc011bHRpcGxlU2VsKCkpCisJeworCQlpZiAoYkN0cmwpCisJCXsKKwkJCWlmIChJc0l0ZW1TZWxlY3RlZChuSGl0SW5kZXgpKQorCQkJeworCQkJCW1fYVNlbEl0ZW1zLlN1YihuSGl0SW5kZXgpOworCQkJCVNlbGVjdEl0ZW1zKCk7CisJCQkJbV9iQ3RybFNlbCA9IEZBTFNFOworCQkJfQorCQkJZWxzZQorCQkJeworCQkJCW1fYVNlbEl0ZW1zLkFkZChuSGl0SW5kZXgpOworCQkJCVNlbGVjdEl0ZW1zKCk7CisJCQkJbV9iQ3RybFNlbCA9IFRSVUU7CisJCQl9CQkKKwkJCQorCQkJbV9uRm9vdEluZGV4ID0gbkhpdEluZGV4OworCQl9CisJCWVsc2UgaWYgKGJTaGlmdCkKKwkJeworCQkJbV9hU2VsSXRlbXMuRGVzZWxlY3RBbGwoKTsKKwkJCW1fYVNlbEl0ZW1zLkFkZChtX25Gb290SW5kZXgsbkhpdEluZGV4KTsKKwkJCVNlbGVjdEl0ZW1zKCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQltX2FTZWxJdGVtcy5EZXNlbGVjdEFsbCgpOworCQkJbV9hU2VsSXRlbXMuQWRkKG5IaXRJbmRleCk7CisJCQlTZWxlY3RJdGVtcygpOworCisJCQltX25Gb290SW5kZXggPSBuSGl0SW5kZXg7CisJCX0KKworCQlTZXRDYXJldChuSGl0SW5kZXgpOworCX0KKwllbHNlCisJeworCQlTZXRTaW5nbGVTZWxlY3QobkhpdEluZGV4KTsKKwl9CisKKwlpZiAoIXRoaXMtPklzSXRlbVZpc2libGUobkhpdEluZGV4KSkKKwkJdGhpcy0+U2Nyb2xsVG9MaXN0SXRlbShuSGl0SW5kZXgpOworfQorCit2b2lkIENGWF9MaXN0Q3RybDo6T25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpCit7CisJRlhfSU5UMzIgbkhpdEluZGV4ID0gdGhpcy0+R2V0SXRlbUluZGV4KHBvaW50KTsKKworCWlmIChJc011bHRpcGxlU2VsKCkpCisJewkJCQorCQlpZiAoYkN0cmwpCisJCXsKKwkJCWlmIChtX2JDdHJsU2VsKQorCQkJCW1fYVNlbEl0ZW1zLkFkZChtX25Gb290SW5kZXgsbkhpdEluZGV4KTsKKwkJCWVsc2UKKwkJCQltX2FTZWxJdGVtcy5TdWIobV9uRm9vdEluZGV4LG5IaXRJbmRleCk7CQkJCisJCQkKKwkJCVNlbGVjdEl0ZW1zKCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQltX2FTZWxJdGVtcy5EZXNlbGVjdEFsbCgpOworCQkJbV9hU2VsSXRlbXMuQWRkKG1fbkZvb3RJbmRleCxuSGl0SW5kZXgpOworCQkJU2VsZWN0SXRlbXMoKTsKKwkJfQorCisJCVNldENhcmV0KG5IaXRJbmRleCk7CisJfQorCWVsc2UKKwl7CisJCVNldFNpbmdsZVNlbGVjdChuSGl0SW5kZXgpOworCX0KKworCWlmICghdGhpcy0+SXNJdGVtVmlzaWJsZShuSGl0SW5kZXgpKQorCQl0aGlzLT5TY3JvbGxUb0xpc3RJdGVtKG5IaXRJbmRleCk7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLKEZYX0lOVDMyIG5JdGVtSW5kZXgsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkKK3sKKwlpZiAoSXNNdWx0aXBsZVNlbCgpKQorCXsKKwkJaWYgKG5JdGVtSW5kZXggPj0gMCAmJiBuSXRlbUluZGV4IDwgR2V0Q291bnQoKSkKKwkJeworCQkJaWYgKGJDdHJsKQorCQkJeworCQkJfQorCQkJZWxzZSBpZiAoYlNoaWZ0KQorCQkJeworCQkJCW1fYVNlbEl0ZW1zLkRlc2VsZWN0QWxsKCk7CisJCQkJbV9hU2VsSXRlbXMuQWRkKG1fbkZvb3RJbmRleCxuSXRlbUluZGV4KTsKKwkJCQlTZWxlY3RJdGVtcygpOworCQkJfQorCQkJZWxzZQorCQkJeworCQkJCW1fYVNlbEl0ZW1zLkRlc2VsZWN0QWxsKCk7CisJCQkJbV9hU2VsSXRlbXMuQWRkKG5JdGVtSW5kZXgpOworCQkJCVNlbGVjdEl0ZW1zKCk7CisJCQkJbV9uRm9vdEluZGV4ID0gbkl0ZW1JbmRleDsKKwkJCX0KKworCQkJU2V0Q2FyZXQobkl0ZW1JbmRleCk7CQorCQl9CisJfQorCWVsc2UKKwl7CisJCVNldFNpbmdsZVNlbGVjdChuSXRlbUluZGV4KTsKKwl9CisKKwlpZiAoIXRoaXMtPklzSXRlbVZpc2libGUobkl0ZW1JbmRleCkpCisJCXRoaXMtPlNjcm9sbFRvTGlzdEl0ZW0obkl0ZW1JbmRleCk7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLX1VQKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpCit7CisJT25WSyhJc011bHRpcGxlU2VsKCkgPyBHZXRDYXJldCgpLTEgOiBHZXRTZWxlY3QoKS0xLCBiU2hpZnQsIGJDdHJsKTsKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6Ok9uVktfRE9XTihGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQoreworCU9uVksoSXNNdWx0aXBsZVNlbCgpID8gR2V0Q2FyZXQoKSsxIDogR2V0U2VsZWN0KCkrMSwgYlNoaWZ0LCBiQ3RybCk7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLX0xFRlQoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCkKK3sKKwlPblZLKDAsIGJTaGlmdCwgYkN0cmwpOworfQorCit2b2lkIENGWF9MaXN0Q3RybDo6T25WS19SSUdIVChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQoreworCU9uVksoR2V0Q291bnQoKS0xLCBiU2hpZnQsIGJDdHJsKTsKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6Ok9uVktfSE9NRShGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQoreworCU9uVksoMCwgYlNoaWZ0LCBiQ3RybCk7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpPblZLX0VORChGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKQoreworCU9uVksoR2V0Q291bnQoKS0xLCBiU2hpZnQsIGJDdHJsKTsKK30KKworRlhfQk9PTAlDRlhfTGlzdEN0cmw6Ok9uQ2hhcihGWF9XT1JEIG5DaGFyLEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpCit7CisJRlhfSU5UMzIgbkluZGV4ID0gR2V0TGFzdFNlbGVjdGVkKCk7CQorCUZYX0lOVDMyIG5GaW5kSW5kZXggPSBGaW5kTmV4dChuSW5kZXgsbkNoYXIpOworCisJaWYgKG5GaW5kSW5kZXggIT0gbkluZGV4KQorCXsKKwkJT25WSyhuRmluZEluZGV4LCBiU2hpZnQsIGJDdHJsKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCXJldHVybiBGQUxTRTsKK30KKworLyogLS0tLS0tLS0gaW5uZXIgbWV0aG9kcyAtLS0tLS0tICovCisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpTZXRQbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkKK3sKKwlDRlhfTGlzdENvbnRhaW5lcjo6U2V0UGxhdGVSZWN0KHJlY3QpOworCW1fcHRTY3JvbGxQb3MueCA9IHJlY3QubGVmdDsKKwlTZXRTY3JvbGxQb3MoQ1BERl9Qb2ludChyZWN0LmxlZnQscmVjdC50b3ApKTsJCisJUmVBcnJhbmdlKDApOworCUludmFsaWRhdGVJdGVtKC0xKTsKK30KKworQ1BERl9SZWN0IENGWF9MaXN0Q3RybDo6R2V0SXRlbVJlY3QoRlhfSU5UMzIgbkluZGV4KSBjb25zdAoreworCXJldHVybiBJblRvT3V0KENGWF9MaXN0OjpHZXRJdGVtUmVjdChuSW5kZXgpKTsKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OkFkZFN0cmluZyhGWF9MUENXU1RSIHN0cmluZykKK3sKKwlBZGRJdGVtKHN0cmluZyk7CisJUmVBcnJhbmdlKEdldENvdW50KCkgLSAxKTsKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OlNldE11bHRpcGxlU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYlNlbGVjdGVkKQoreworCWlmICghSXNWYWxpZChuSXRlbUluZGV4KSkgcmV0dXJuOworCisJaWYgKGJTZWxlY3RlZCAhPSB0aGlzLT5Jc0l0ZW1TZWxlY3RlZChuSXRlbUluZGV4KSkKKwl7CisJCWlmIChiU2VsZWN0ZWQpCisJCXsKKwkJCVNldEl0ZW1TZWxlY3Qobkl0ZW1JbmRleCxUUlVFKTsKKwkJCUludmFsaWRhdGVJdGVtKG5JdGVtSW5kZXgpOworCQl9CisJCWVsc2UKKwkJeworCQkJU2V0SXRlbVNlbGVjdChuSXRlbUluZGV4LEZBTFNFKTsKKwkJCUludmFsaWRhdGVJdGVtKG5JdGVtSW5kZXgpOworCQl9CisJfQorfQorCit2b2lkIENGWF9MaXN0Q3RybDo6U2V0U2luZ2xlU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgpCit7CisJaWYgKCFJc1ZhbGlkKG5JdGVtSW5kZXgpKSByZXR1cm47CisKKwlpZiAobV9uU2VsSXRlbSAhPSBuSXRlbUluZGV4KQorCXsKKwkJaWYgKG1fblNlbEl0ZW0gPj0gMCkKKwkJeworCQkJU2V0SXRlbVNlbGVjdChtX25TZWxJdGVtLEZBTFNFKTsKKwkJCUludmFsaWRhdGVJdGVtKG1fblNlbEl0ZW0pOworCQl9CisJCQorCQlTZXRJdGVtU2VsZWN0KG5JdGVtSW5kZXgsVFJVRSk7CisJCUludmFsaWRhdGVJdGVtKG5JdGVtSW5kZXgpOworCQltX25TZWxJdGVtID0gbkl0ZW1JbmRleDsJCQorCX0KK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OlNldENhcmV0KEZYX0lOVDMyIG5JdGVtSW5kZXgpCit7CisJaWYgKCFJc1ZhbGlkKG5JdGVtSW5kZXgpKSByZXR1cm47CisKKwlpZiAodGhpcy0+SXNNdWx0aXBsZVNlbCgpKQorCXsJCQorCQlGWF9JTlQzMiBuT2xkSW5kZXggPSBtX25DYXJldEluZGV4OworCisJCWlmIChuT2xkSW5kZXggIT0gbkl0ZW1JbmRleCkKKwkJeworCQkJbV9uQ2FyZXRJbmRleCA9IG5JdGVtSW5kZXg7CisKKwkJCVNldEl0ZW1DYXJldChuT2xkSW5kZXgsIEZBTFNFKTsKKwkJCVNldEl0ZW1DYXJldChuSXRlbUluZGV4LFRSVUUpOworCisJCQlJbnZhbGlkYXRlSXRlbShuT2xkSW5kZXgpOworCQkJSW52YWxpZGF0ZUl0ZW0obkl0ZW1JbmRleCk7CQkJCisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpJbnZhbGlkYXRlSXRlbShGWF9JTlQzMiBuSXRlbUluZGV4KQoreworCWlmIChtX3BOb3RpZnkpCisJeworCQlpZiAobkl0ZW1JbmRleCA9PSAtMSkKKwkJeworCQkJaWYgKCFtX2JOb3RpZnlGbGFnKQorCQkJeworCQkJCW1fYk5vdGlmeUZsYWcgPSBUUlVFOworCQkJCUNQREZfUmVjdCByY1JlZnJlc2ggPSBHZXRQbGF0ZVJlY3QoKTsKKwkJCQltX3BOb3RpZnktPklPbkludmFsaWRhdGVSZWN0KCZyY1JlZnJlc2gpOworCQkJCW1fYk5vdGlmeUZsYWcgPSBGQUxTRTsKKwkJCX0KKwkJfQorCQllbHNlCisJCXsKKwkJCWlmICghbV9iTm90aWZ5RmxhZykKKwkJCXsKKwkJCQltX2JOb3RpZnlGbGFnID0gVFJVRTsKKwkJCQlDUERGX1JlY3QgcmNSZWZyZXNoID0gR2V0SXRlbVJlY3Qobkl0ZW1JbmRleCk7CisJCQkJcmNSZWZyZXNoLmxlZnQgLT0gMS4wZjsKKwkJCQlyY1JlZnJlc2gucmlnaHQgKz0gMS4wZjsKKwkJCQlyY1JlZnJlc2guYm90dG9tIC09IDEuMGY7CisJCQkJcmNSZWZyZXNoLnRvcCArPSAxLjBmOworCisJCQkJbV9wTm90aWZ5LT5JT25JbnZhbGlkYXRlUmVjdCgmcmNSZWZyZXNoKTsKKwkJCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7CisJCQl9CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpTZWxlY3RJdGVtcygpCit7CisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hU2VsSXRlbXMuR2V0Q291bnQoKTsgaTxzejsgaSsrKQorCXsKKwkJRlhfSU5UMzIgbkl0ZW1JbmRleCA9IG1fYVNlbEl0ZW1zLkdldEl0ZW1JbmRleChpKTsKKwkJRlhfSU5UMzIgblN0YXRlID0gbV9hU2VsSXRlbXMuR2V0U3RhdGUoaSk7CisKKwkJc3dpdGNoKG5TdGF0ZSkKKwkJeworCQljYXNlIDE6CisJCQlTZXRNdWx0aXBsZVNlbGVjdChuSXRlbUluZGV4LCBUUlVFKTsJCQkKKwkJCWJyZWFrOworCQljYXNlIC0xOgorCQkJU2V0TXVsdGlwbGVTZWxlY3Qobkl0ZW1JbmRleCwgRkFMU0UpOworCQkJYnJlYWs7CisJCX0KKwl9CisKKwltX2FTZWxJdGVtcy5Eb25lKCk7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlpZiAoIUlzVmFsaWQobkl0ZW1JbmRleCkpIHJldHVybjsKKworCWlmICh0aGlzLT5Jc011bHRpcGxlU2VsKCkpCisJeworCQltX2FTZWxJdGVtcy5BZGQobkl0ZW1JbmRleCk7CisJCVNlbGVjdEl0ZW1zKCk7CisJfQorCWVsc2UKKwkJU2V0U2luZ2xlU2VsZWN0KG5JdGVtSW5kZXgpOworfQorCitGWF9CT09MCUNGWF9MaXN0Q3RybDo6SXNJdGVtVmlzaWJsZShGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdAoreworCUNQREZfUmVjdCByY1BsYXRlID0gdGhpcy0+R2V0UGxhdGVSZWN0KCk7CisJQ1BERl9SZWN0IHJjSXRlbSA9IHRoaXMtPkdldEl0ZW1SZWN0KG5JdGVtSW5kZXgpOworCisJcmV0dXJuIHJjSXRlbS5ib3R0b20gPj0gcmNQbGF0ZS5ib3R0b20gJiYgcmNJdGVtLnRvcCA8PSByY1BsYXRlLnRvcDsKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OlNjcm9sbFRvTGlzdEl0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlpZiAoIUlzVmFsaWQobkl0ZW1JbmRleCkpIHJldHVybjsKKworCUNQREZfUmVjdCByY1BsYXRlID0gdGhpcy0+R2V0UGxhdGVSZWN0KCk7CisJQ1BERl9SZWN0IHJjSXRlbSA9IENGWF9MaXN0OjpHZXRJdGVtUmVjdChuSXRlbUluZGV4KTsKKwlDUERGX1JlY3QgcmNJdGVtQ3RybCA9IEdldEl0ZW1SZWN0KG5JdGVtSW5kZXgpOworCisJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIocmNJdGVtQ3RybC5ib3R0b20sIHJjUGxhdGUuYm90dG9tKSkKKwl7CisJCWlmIChGWF9FRElUX0lzRmxvYXRTbWFsbGVyKHJjSXRlbUN0cmwudG9wLCByY1BsYXRlLnRvcCkpCisJCXsKKwkJCVNldFNjcm9sbFBvc1kocmNJdGVtLmJvdHRvbSArIHJjUGxhdGUuSGVpZ2h0KCkpOworCQl9CisJfQorCWVsc2UgaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihyY0l0ZW1DdHJsLnRvcCwgcmNQbGF0ZS50b3ApKQorCXsKKwkJaWYgKEZYX0VESVRfSXNGbG9hdEJpZ2dlcihyY0l0ZW1DdHJsLmJvdHRvbSwgcmNQbGF0ZS5ib3R0b20pKQorCQl7CisJCQlTZXRTY3JvbGxQb3NZKHJjSXRlbS50b3ApOworCQl9CisJfQorfQorCit2b2lkIENGWF9MaXN0Q3RybDo6U2V0U2Nyb2xsSW5mbygpCit7CisJaWYgKG1fcE5vdGlmeSkKKwl7CisJCUNQREZfUmVjdCByY1BsYXRlID0gR2V0UGxhdGVSZWN0KCk7CisJCUNQREZfUmVjdCByY0NvbnRlbnQgPSBDRlhfTGlzdDo6R2V0Q29udGVudFJlY3QoKTsKKworCQlpZiAoIW1fYk5vdGlmeUZsYWcpCisJCXsKKwkJCW1fYk5vdGlmeUZsYWcgPSBUUlVFOworCQkJbV9wTm90aWZ5LT5JT25TZXRTY3JvbGxJbmZvWShyY1BsYXRlLmJvdHRvbSwgcmNQbGF0ZS50b3AsIAorCQkJCQlyY0NvbnRlbnQuYm90dG9tLCByY0NvbnRlbnQudG9wLCBHZXRGaXJzdEhlaWdodCgpLCByY1BsYXRlLkhlaWdodCgpKTsKKwkJCW1fYk5vdGlmeUZsYWcgPSBGQUxTRTsKKwkJfQorCX0KK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OlNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CisJU2V0U2Nyb2xsUG9zWShwb2ludC55KTsKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OlNldFNjcm9sbFBvc1koRlhfRkxPQVQgZnkpCit7CisJaWYgKCFGWF9FRElUX0lzRmxvYXRFcXVhbChtX3B0U2Nyb2xsUG9zLnksZnkpKQorCXsKKwkJQ1BERl9SZWN0IHJjUGxhdGUgPSB0aGlzLT5HZXRQbGF0ZVJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjQ29udGVudCA9IENGWF9MaXN0OjpHZXRDb250ZW50UmVjdCgpOworCisJCWlmIChyY1BsYXRlLkhlaWdodCgpID4gcmNDb250ZW50LkhlaWdodCgpKQorCQl7CisJCQlmeSA9IHJjUGxhdGUudG9wOworCQl9CisJCWVsc2UKKwkJeworCQkJaWYgKEZYX0VESVRfSXNGbG9hdFNtYWxsZXIoZnkgLSByY1BsYXRlLkhlaWdodCgpLCByY0NvbnRlbnQuYm90dG9tKSkKKwkJCXsKKwkJCQlmeSA9IHJjQ29udGVudC5ib3R0b20gKyByY1BsYXRlLkhlaWdodCgpOworCQkJfQorCQkJZWxzZSBpZiAoRlhfRURJVF9Jc0Zsb2F0QmlnZ2VyKGZ5LCByY0NvbnRlbnQudG9wKSkKKwkJCXsKKwkJCQlmeSA9IHJjQ29udGVudC50b3A7CisJCQl9CisJCX0KKworCQltX3B0U2Nyb2xsUG9zLnkgPSBmeTsKKwkJSW52YWxpZGF0ZUl0ZW0oLTEpOworCisJCWlmIChtX3BOb3RpZnkpIAorCQl7CisJCQlpZiAoIW1fYk5vdGlmeUZsYWcpCisJCQl7CisJCQkJbV9iTm90aWZ5RmxhZyA9IFRSVUU7CisJCQkJbV9wTm90aWZ5LT5JT25TZXRTY3JvbGxQb3NZKGZ5KTsKKwkJCQltX2JOb3RpZnlGbGFnID0gRkFMU0U7CisJCQl9CisJCX0KKwl9Cit9CisKK0NQREZfUmVjdCBDRlhfTGlzdEN0cmw6OkdldENvbnRlbnRSZWN0KCkgY29uc3QKK3sKKwlyZXR1cm4gSW5Ub091dChDRlhfTGlzdDo6R2V0Q29udGVudFJlY3QoKSk7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpSZUFycmFuZ2UoRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlDRlhfTGlzdDo6UmVBcnJhbmdlKG5JdGVtSW5kZXgpOworCVNldFNjcm9sbEluZm8oKTsKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OlNldFRvcEl0ZW0oRlhfSU5UMzIgbkluZGV4KQoreworCWlmIChJc1ZhbGlkKG5JbmRleCkpCisJeworCQl0aGlzLT5HZXRQbGF0ZVJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjSXRlbSA9IENGWF9MaXN0OjpHZXRJdGVtUmVjdChuSW5kZXgpOworCQlTZXRTY3JvbGxQb3NZKHJjSXRlbS50b3ApOworCX0KK30KKworRlhfSU5UMzIgQ0ZYX0xpc3RDdHJsOjpHZXRUb3BJdGVtKCkgY29uc3QKK3sKKwlGWF9JTlQzMiBuSXRlbUluZGV4ID0gdGhpcy0+R2V0SXRlbUluZGV4KHRoaXMtPkdldEJUUG9pbnQoKSk7CisKKwlpZiAoIUlzSXRlbVZpc2libGUobkl0ZW1JbmRleCkgJiYgSXNJdGVtVmlzaWJsZShuSXRlbUluZGV4ICsgMSkpCisJCQluSXRlbUluZGV4ICs9IDE7CisKKwlyZXR1cm4gbkl0ZW1JbmRleDsKK30KKwordm9pZCBDRlhfTGlzdEN0cmw6OkVtcHR5KCkKK3sKKwlDRlhfTGlzdDo6RW1wdHkoKTsKKwlJbnZhbGlkYXRlSXRlbSgtMSk7Cit9CisKK3ZvaWQgQ0ZYX0xpc3RDdHJsOjpDYW5jZWwoKQoreworCW1fYVNlbEl0ZW1zLkRlc2VsZWN0QWxsKCk7Cit9CisKK0ZYX0lOVDMyIENGWF9MaXN0Q3RybDo6R2V0SXRlbUluZGV4KGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3QKK3sKKwlyZXR1cm4gQ0ZYX0xpc3Q6OkdldEl0ZW1JbmRleChPdXRUb0luKHBvaW50KSk7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENGWF9MaXN0Q3RybDo6R2V0VGV4dCgpIGNvbnN0Cit7CisJaWYgKHRoaXMtPklzTXVsdGlwbGVTZWwoKSkKKwkJcmV0dXJuIHRoaXMtPkdldEl0ZW1UZXh0KHRoaXMtPm1fbkNhcmV0SW5kZXgpOwkKKwllbHNlCisJCXJldHVybiB0aGlzLT5HZXRJdGVtVGV4dCh0aGlzLT5tX25TZWxJdGVtKTsKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnhlZGl0L2Z4ZXRfbW9kdWxlLmNwcCBiL2ZwZGZzZGsvc3JjL2Z4ZWRpdC9meGV0X21vZHVsZS5jcHAKaW5kZXggYjEzYWY4OS4uOWNhN2YyZSAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvZnhlZGl0L2Z4ZXRfbW9kdWxlLmNwcAorKysgYi9mcGRmc2RrL3NyYy9meGVkaXQvZnhldF9tb2R1bGUuY3BwCkBAIC0xLDQ2ICsxLDQ2IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9zdHViLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfZWRpdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4ZWRpdC9meGV0X2xpc3QuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tIElGWF9FZGl0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1JRlhfRWRpdCogSUZYX0VkaXQ6Ok5ld0VkaXQoKQ0KLXsNCi0JaWYgKElQREZfVmFyaWFibGVUZXh0ICogcFZUID0gSVBERl9WYXJpYWJsZVRleHQ6Ok5ld1ZhcmlhYmxlVGV4dCgpKQ0KLQl7DQotCQlyZXR1cm4gbmV3IENGWF9FZGl0KHBWVCk7DQotCX0NCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLXZvaWQgSUZYX0VkaXQ6OkRlbEVkaXQoSUZYX0VkaXQqIHBFZGl0KQ0KLXsNCi0JQVNTRVJUKHBFZGl0ICE9IE5VTEwpOw0KLQ0KLQlJUERGX1ZhcmlhYmxlVGV4dDo6RGVsVmFyaWFibGVUZXh0KHBFZGl0LT5HZXRWYXJpYWJsZVRleHQoKSk7DQotDQotCWRlbGV0ZSAoQ0ZYX0VkaXQqKXBFZGl0Ow0KLX0NCi0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tIElGWF9MaXN0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1JRlhfTGlzdCogSUZYX0xpc3Q6Ok5ld0xpc3QoKQ0KLXsNCi0JcmV0dXJuIG5ldyBDRlhfTGlzdEN0cmwoKTsNCi19DQotDQotdm9pZCBJRlhfTGlzdDo6RGVsTGlzdChJRlhfTGlzdCogcExpc3QpDQotew0KLQlBU1NFUlQocExpc3QgIT0gTlVMTCk7DQotDQotCWRlbGV0ZSAoQ0ZYX0xpc3RDdHJsKilwTGlzdDsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfc3R1Yi5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfZWRpdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfbGlzdC5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tIElGWF9FZGl0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworSUZYX0VkaXQqIElGWF9FZGl0OjpOZXdFZGl0KCkKK3sKKwlpZiAoSVBERl9WYXJpYWJsZVRleHQgKiBwVlQgPSBJUERGX1ZhcmlhYmxlVGV4dDo6TmV3VmFyaWFibGVUZXh0KCkpCisJeworCQlyZXR1cm4gbmV3IENGWF9FZGl0KHBWVCk7CisJfQorCisJcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgSUZYX0VkaXQ6OkRlbEVkaXQoSUZYX0VkaXQqIHBFZGl0KQoreworCUFTU0VSVChwRWRpdCAhPSBOVUxMKTsKKworCUlQREZfVmFyaWFibGVUZXh0OjpEZWxWYXJpYWJsZVRleHQocEVkaXQtPkdldFZhcmlhYmxlVGV4dCgpKTsKKworCWRlbGV0ZSAoQ0ZYX0VkaXQqKXBFZGl0OworfQorCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSUZYX0xpc3QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitJRlhfTGlzdCogSUZYX0xpc3Q6Ok5ld0xpc3QoKQoreworCXJldHVybiBuZXcgQ0ZYX0xpc3RDdHJsKCk7Cit9CisKK3ZvaWQgSUZYX0xpc3Q6OkRlbExpc3QoSUZYX0xpc3QqIHBMaXN0KQoreworCUFTU0VSVChwTGlzdCAhPSBOVUxMKTsKKworCWRlbGV0ZSAoQ0ZYX0xpc3RDdHJsKilwTGlzdDsKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvZnhlZGl0L2Z4ZXRfcGFnZW9ianMuY3BwIGIvZnBkZnNkay9zcmMvZnhlZGl0L2Z4ZXRfcGFnZW9ianMuY3BwCmluZGV4IDk5NTIwNjEuLjMzZDU3ZWQgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2Z4ZWRpdC9meGV0X3BhZ2VvYmpzLmNwcAorKysgYi9mcGRmc2RrL3NyYy9meGVkaXQvZnhldF9wYWdlb2Jqcy5jcHAKQEAgLTEsNjg3ICsxLDY4NyBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfc3R1Yi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4ZWRpdC9meF9lZGl0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvZnhlZGl0L2Z4ZXRfZWRpdC5oIg0KLQ0KLSNkZWZpbmUgRlhfRURJVF9VTkRFUkxJTkVIQUxGV0lEVEgJCQkJMC41Zg0KLSNkZWZpbmUgRlhfRURJVF9DUk9TU09VVEhBTEZXSURUSAkJCQkwLjVmDQotDQotZXh0ZXJuIENGWF9CeXRlU3RyaW5nIEdldFBERldvcmRTdHJpbmcoSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwLCBGWF9JTlQzMiBuRm9udEluZGV4LCBGWF9XT1JEIFdvcmQsIEZYX1dPUkQgU3ViV29yZCk7DQotDQotQ1BERl9SZWN0IEdldFVuZGVyTGluZVJlY3QoY29uc3QgQ1BWVF9Xb3JkJiB3b3JkKQ0KLXsNCi0JcmV0dXJuIENQREZfUmVjdCh3b3JkLnB0V29yZC54LCB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudCAqIDAuNWYsDQotCQkJCQkJd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoLCB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudCAqIDAuMjVmKTsNCi19DQotDQotQ1BERl9SZWN0IEdldENyb3Nzb3V0UmVjdChjb25zdCBDUFZUX1dvcmQmIHdvcmQpDQotew0KLQlyZXR1cm4gQ1BERl9SZWN0KHdvcmQucHRXb3JkLngsIHdvcmQucHRXb3JkLnkgKyAod29yZC5mQXNjZW50ICsgd29yZC5mRGVzY2VudCkgKiAwLjVmICsgd29yZC5mRGVzY2VudCAqIDAuMjVmLA0KLQkJCQkJCQl3b3JkLnB0V29yZC54ICsgd29yZC5mV2lkdGgsIHdvcmQucHRXb3JkLnkgKyAod29yZC5mQXNjZW50ICsgd29yZC5mRGVzY2VudCkgKiAwLjVmKTsNCi19DQotDQotc3RhdGljIHZvaWQgRHJhd1RleHRTdHJpbmcoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgY29uc3QgQ1BERl9Qb2ludCYgcHQsIENQREZfRm9udCogcEZvbnQsIEZYX0ZMT0FUIGZGb250U2l6ZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCQkJCSAgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0ciwgRlhfQVJHQiBjclRleHRGaWxsLCBGWF9BUkdCIGNyVGV4dFN0cm9rZSwgRlhfSU5UMzIgbkhvcnpTY2FsZSkNCi17DQotCUZYX0ZMT0FUIHggPSBwdC54LCB5ID0gcHQueTsNCi0JcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm0oeCwgeSk7DQotDQotCWlmIChwRm9udCkNCi0Jew0KLQkJaWYgKG5Ib3J6U2NhbGUgIT0gMTAwKQ0KLQkJew0KLQkJCUNQREZfTWF0cml4IG10KG5Ib3J6U2NhbGUvMTAwLjBmLDAsMCwxLDAsMCk7DQotCQkJbXQuQ29uY2F0KCpwVXNlcjJEZXZpY2UpOw0KLQ0KLQkJCUNQREZfUmVuZGVyT3B0aW9ucyBybzsNCi0JCQlyby5tX0ZsYWdzID0gUkVOREVSX0NMRUFSVFlQRTsNCi0JCQlyby5tX0NvbG9yTW9kZSA9IFJFTkRFUl9DT0xPUl9OT1JNQUw7DQotDQotCQkJaWYgKGNyVGV4dFN0cm9rZSAhPSAwKQ0KLQkJCXsNCi0JCQkJQ1BERl9Qb2ludCBwdDEoMCwwKSwgcHQyKDEsMCk7DQotCQkJCXBVc2VyMkRldmljZS0+VHJhbnNmb3JtKHB0MS54LCBwdDEueSk7DQotCQkJCXBVc2VyMkRldmljZS0+VHJhbnNmb3JtKHB0Mi54LCBwdDIueSk7DQotCQkJCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7DQotCQkJCWdzZC5tX0xpbmVXaWR0aCA9IChGWF9GTE9BVClGWFNZU19mYWJzKChwdDIueCArIHB0Mi55KSAtIChwdDEueCArIHB0MS55KSk7DQotDQotCQkJCUNQREZfVGV4dFJlbmRlcmVyOjpEcmF3VGV4dFN0cmluZyhwRGV2aWNlLHgsIHksIHBGb250LCBmRm9udFNpemUsICZtdCwgc3RyLCBjclRleHRGaWxsLCBjclRleHRTdHJva2UsICZnc2QsICZybyk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQkJQ1BERl9UZXh0UmVuZGVyZXI6OkRyYXdUZXh0U3RyaW5nKHBEZXZpY2UseCwgeSwgcEZvbnQsIGZGb250U2l6ZSwgJm10LCBzdHIsIGNyVGV4dEZpbGwsIDAsIE5VTEwsICZybyk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJQ1BERl9SZW5kZXJPcHRpb25zIHJvOw0KLQkJCXJvLm1fRmxhZ3MgPSBSRU5ERVJfQ0xFQVJUWVBFOw0KLQkJCXJvLm1fQ29sb3JNb2RlID0gUkVOREVSX0NPTE9SX05PUk1BTDsNCi0NCi0JCQlpZiAoY3JUZXh0U3Ryb2tlICE9IDApDQotCQkJew0KLQkJCQlDUERGX1BvaW50IHB0MSgwLDApLCBwdDIoMSwwKTsNCi0JCQkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm0ocHQxLngsIHB0MS55KTsNCi0JCQkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm0ocHQyLngsIHB0Mi55KTsNCi0JCQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JCQkJZ3NkLm1fTGluZVdpZHRoID0gKEZYX0ZMT0FUKUZYU1lTX2ZhYnMoKHB0Mi54ICsgcHQyLnkpIC0gKHB0MS54ICsgcHQxLnkpKTsNCi0NCi0JCQkJQ1BERl9UZXh0UmVuZGVyZXI6OkRyYXdUZXh0U3RyaW5nKHBEZXZpY2UseCwgeSwgcEZvbnQsIGZGb250U2l6ZSwgcFVzZXIyRGV2aWNlLCBzdHIsIGNyVGV4dEZpbGwsIGNyVGV4dFN0cm9rZSwgJmdzZCwgJnJvKTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCQlDUERGX1RleHRSZW5kZXJlcjo6RHJhd1RleHRTdHJpbmcocERldmljZSx4LCB5LCBwRm9udCwgZkZvbnRTaXplLCBwVXNlcjJEZXZpY2UsIHN0ciwgY3JUZXh0RmlsbCwgMCwgTlVMTCwgJnJvKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIElGWF9FZGl0OjpEcmF3VW5kZXJsaW5lKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsIElGWF9FZGl0KiBwRWRpdCwgRlhfQ09MT1JSRUYgY29sb3IsDQotCQkJCQkJCQljb25zdCBDUERGX1JlY3QmIHJjQ2xpcCwgY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UpDQotew0KLQlwRGV2aWNlLT5TYXZlU3RhdGUoKTsNCi0NCi0JaWYgKCFyY0NsaXAuSXNFbXB0eSgpKQ0KLQl7DQotCQlDUERGX1JlY3QgcmNUZW1wID0gcmNDbGlwOw0KLQkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm1SZWN0KHJjVGVtcCk7DQotCQlGWF9SRUNUIHJjRGV2Q2xpcDsNCi0JCXJjRGV2Q2xpcC5sZWZ0ID0gKEZYX0lOVDMyKXJjVGVtcC5sZWZ0Ow0KLQkJcmNEZXZDbGlwLnJpZ2h0ID0gKEZYX0lOVDMyKXJjVGVtcC5yaWdodDsNCi0JCXJjRGV2Q2xpcC50b3AgPSAoRlhfSU5UMzIpcmNUZW1wLnRvcDsNCi0JCXJjRGV2Q2xpcC5ib3R0b20gPSAoRlhfSU5UMzIpcmNUZW1wLmJvdHRvbTsNCi0JCXBEZXZpY2UtPlNldENsaXBfUmVjdCgmcmNEZXZDbGlwKTsNCi0JfQ0KLQ0KLQlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQ0KLQl7DQotCQlpZiAocEVkaXQtPkdldEZvbnRNYXAoKSkNCi0JCXsNCi0JCQlpZiAocFJhbmdlKQ0KLQkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOw0KLQkJCWVsc2UNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsNCi0NCi0JCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQ0KLQkJCXsNCi0JCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsNCi0NCi0JCQkJQ1BWVF9Xb3JkIHdvcmQ7CQkJCQ0KLQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQ0KLQkJCQl7DQotCQkJCQlDRlhfUGF0aERhdGEgcGF0aFVuZGVybGluZTsNCi0JCQkJCUNQREZfUmVjdCByY1VuZGVybGluZSA9IEdldFVuZGVyTGluZVJlY3Qod29yZCk7DQotCQkJCQlyY1VuZGVybGluZS5sZWZ0ICs9IHB0T2Zmc2V0Lng7DQotCQkJCQlyY1VuZGVybGluZS5yaWdodCArPSBwdE9mZnNldC54Ow0KLQkJCQkJcmNVbmRlcmxpbmUudG9wICs9IHB0T2Zmc2V0Lnk7DQotCQkJCQlyY1VuZGVybGluZS5ib3R0b20gKz0gcHRPZmZzZXQueTsNCi0JCQkJCXBhdGhVbmRlcmxpbmUuQXBwZW5kUmVjdChyY1VuZGVybGluZS5sZWZ0LCByY1VuZGVybGluZS5ib3R0b20sIHJjVW5kZXJsaW5lLnJpZ2h0LCByY1VuZGVybGluZS50b3ApOw0KLQ0KLQkJCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGhVbmRlcmxpbmUsIHBVc2VyMkRldmljZSwgTlVMTCwgY29sb3IsIDAsIEZYRklMTF9XSU5ESU5HKTsNCi0JCQkJfQ0KLQkJCX0JCQkNCi0JCX0NCi0JfQ0KLQkNCi0JcERldmljZS0+UmVzdG9yZVN0YXRlKCk7DQotfQ0KLQ0KLXZvaWQgSUZYX0VkaXQ6OkRyYXdFZGl0KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsIElGWF9FZGl0KiBwRWRpdCwgRlhfQ09MT1JSRUYgY3JUZXh0RmlsbCwgRlhfQ09MT1JSRUYgY3JUZXh0U3Ryb2tlLCANCi0JCQkJCQljb25zdCBDUERGX1JlY3QmIHJjQ2xpcCwgY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UsIElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlciwgdm9pZCogcEZGTERhdGEpDQotew0KLQkNCi0JRlhfQk9PTCBiQ29udGludW91cyA9IHBFZGl0LT5HZXRDaGFyQXJyYXkoKSA9PSAwOw0KLQlpZiAocEVkaXQtPkdldENoYXJTcGFjZSgpID4gMC4wZikNCi0JCWJDb250aW51b3VzID0gRkFMU0U7DQotDQotCUZYX1dPUkQgU3ViV29yZCA9IHBFZGl0LT5HZXRQYXNzd29yZENoYXIoKTsNCi0JRlhfRkxPQVQgZkZvbnRTaXplID0gcEVkaXQtPkdldEZvbnRTaXplKCk7DQotCUNQVlRfV29yZFJhbmdlIHdyU2VsZWN0ID0gcEVkaXQtPkdldFNlbGVjdFdvcmRSYW5nZSgpOw0KLQlGWF9JTlQzMiBuSG9yelNjYWxlID0gcEVkaXQtPkdldEhvcnpTY2FsZSgpOw0KLQ0KLQlGWF9DT0xPUlJFRiBjckN1ckZpbGwgPSBjclRleHRGaWxsOw0KLQlGWF9DT0xPUlJFRiBjck9sZEZpbGwgPSBjckN1ckZpbGw7DQotDQotCUZYX0JPT0wgYlNlbGVjdCA9IEZBTFNFOw0KLQljb25zdCBGWF9DT0xPUlJFRiBjcldoaXRlID0gQXJnYkVuY29kZSgyNTUsMjU1LDI1NSwyNTUpOw0KLQljb25zdCBGWF9DT0xPUlJFRiBjclNlbEJLID0gQXJnYkVuY29kZSgyNTUsMCw1MSwxMTMpOw0KLQ0KLQlDRlhfQnl0ZVRleHRCdWYgc1RleHRCdWY7DQotCUZYX0lOVDMyIG5Gb250SW5kZXggPSAtMTsNCi0JQ1BERl9Qb2ludCBwdEJUKDAuMGYsMC4wZik7DQotDQotCXBEZXZpY2UtPlNhdmVTdGF0ZSgpOw0KLQ0KLQlpZiAoIXJjQ2xpcC5Jc0VtcHR5KCkpDQotCXsNCi0JCUNQREZfUmVjdCByY1RlbXAgPSByY0NsaXA7DQotCQlwVXNlcjJEZXZpY2UtPlRyYW5zZm9ybVJlY3QocmNUZW1wKTsNCi0JCUZYX1JFQ1QgcmNEZXZDbGlwOw0KLQkJcmNEZXZDbGlwLmxlZnQgPSAoRlhfSU5UMzIpcmNUZW1wLmxlZnQ7DQotCQlyY0RldkNsaXAucmlnaHQgPSAoRlhfSU5UMzIpcmNUZW1wLnJpZ2h0Ow0KLQkJcmNEZXZDbGlwLnRvcCA9IChGWF9JTlQzMilyY1RlbXAudG9wOw0KLQkJcmNEZXZDbGlwLmJvdHRvbSA9IChGWF9JTlQzMilyY1RlbXAuYm90dG9tOw0KLQkJcERldmljZS0+U2V0Q2xpcF9SZWN0KCZyY0RldkNsaXApOw0KLQl9DQotDQotCWlmIChJRlhfRWRpdF9JdGVyYXRvciogcEl0ZXJhdG9yID0gcEVkaXQtPkdldEl0ZXJhdG9yKCkpDQotCXsNCi0JCWlmIChJRlhfRWRpdF9Gb250TWFwKiBwRm9udE1hcCA9IHBFZGl0LT5HZXRGb250TWFwKCkpDQotCQl7DQotCQkJaWYgKHBSYW5nZSkNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdChwUmFuZ2UtPkJlZ2luUG9zKTsNCi0JCQllbHNlDQotCQkJCXBJdGVyYXRvci0+U2V0QXQoMCk7DQotDQotCQkJQ1BWVF9Xb3JkUGxhY2Ugb2xkcGxhY2U7CQkJDQotDQotCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkNCi0JCQl7DQotCQkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOw0KLQkJCQlpZiAocFJhbmdlICYmIHBsYWNlLldvcmRDbXAocFJhbmdlLT5FbmRQb3MpID4gMCkgYnJlYWs7DQotDQotCQkJCWlmICh3clNlbGVjdC5Jc0V4aXN0KCkpDQotCQkJCXsNCi0JCQkJCWJTZWxlY3QgPSBwbGFjZS5Xb3JkQ21wKHdyU2VsZWN0LkJlZ2luUG9zKSA+IDAgJiYgcGxhY2UuV29yZENtcCh3clNlbGVjdC5FbmRQb3MpIDw9IDA7DQotCQkJCQlpZiAoYlNlbGVjdCkNCi0JCQkJCXsJCQkJCQkNCi0JCQkJCQljckN1ckZpbGwgPSBjcldoaXRlOwkJCQkJCQ0KLQkJCQkJfQ0KLQkJCQkJZWxzZQ0KLQkJCQkJew0KLQkJCQkJCWNyQ3VyRmlsbCA9IGNyVGV4dEZpbGw7DQotCQkJCQl9DQotCQkJCX0NCi0JCQkJaWYocFN5c3RlbUhhbmRsZXIgJiYgcFN5c3RlbUhhbmRsZXItPklzU2VsZWN0aW9uSW1wbGVtZW50ZWQoKSkJDQotCQkJCXsNCi0JCQkJCWNyQ3VyRmlsbCA9IGNyVGV4dEZpbGw7DQotIAkJCQkJY3JPbGRGaWxsID0gY3JDdXJGaWxsOw0KLQkJCQl9DQotCQkJCUNQVlRfV29yZCB3b3JkOwkJCQkNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJew0KLQ0KLQkJCQkJaWYgKGJTZWxlY3QpDQotCQkJCQl7DQotCQkJCQkJDQotCQkJCQkJQ1BWVF9MaW5lIGxpbmU7DQotCQkJCQkJcEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmUpOw0KLQ0KLQkJCQkJCWlmKHBTeXN0ZW1IYW5kbGVyICYmIHBTeXN0ZW1IYW5kbGVyLT5Jc1NlbGVjdGlvbkltcGxlbWVudGVkKCkpDQotCQkJCQkJew0KLQkJCQkJCQlDUERGX1JlY3QgcmMod29yZC5wdFdvcmQueCxsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZURlc2NlbnQsDQotCQkJCQkJCQl3b3JkLnB0V29yZC54K3dvcmQuZldpZHRoLGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lQXNjZW50KTsNCi0JCQkJCQkJcmMuSW50ZXJzZWN0KHJjQ2xpcCk7DQotCQkJCQkJCS8vQ0ZYX0VkaXQqIHBFdCA9IChDRlhfRWRpdCopcEVkaXQ7DQotCQkJCQkJCS8vQ1BERl9SZWN0IHJjRWRpdCA9IHBFdC0+VlRUb0VkaXQocmMpOw0KLQkJCQkJCQlwU3lzdGVtSGFuZGxlci0+T3V0cHV0U2VsZWN0ZWRSZWN0KHBGRkxEYXRhLHJjKTsNCi0JCQkJCQl9DQotCQkJCQkJZWxzZQ0KLQkJCQkJCXsJDQotIAkJCQkJCQlDRlhfUGF0aERhdGEgcGF0aFNlbEJLOw0KLSAJCQkJCQkJcGF0aFNlbEJLLkFwcGVuZFJlY3Qod29yZC5wdFdvcmQueCxsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZURlc2NlbnQsDQotIAkJCQkJCQkJd29yZC5wdFdvcmQueCt3b3JkLmZXaWR0aCxsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZUFzY2VudCk7DQotIAkJCQkJCQkNCi0gCQkJCQkJCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoU2VsQkssIHBVc2VyMkRldmljZSwgTlVMTCwgY3JTZWxCSywgMCwgRlhGSUxMX1dJTkRJTkcpOwkNCi0JCQkJCQl9DQotCQkJCQl9DQotDQotCQkJCQlpZiAoYkNvbnRpbnVvdXMpDQotCQkJCQl7DQotCQkJCQkJaWYgKHBsYWNlLkxpbmVDbXAob2xkcGxhY2UpICE9IDAgfHwgd29yZC5uRm9udEluZGV4ICE9IG5Gb250SW5kZXggfHwgDQotCQkJCQkJCWNyT2xkRmlsbCAhPSBjckN1ckZpbGwpDQotCQkJCQkJew0KLQkJCQkJCQlpZiAoc1RleHRCdWYuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQkJCQl7CQkJCQkJCQkNCi0JCQkJCQkJCURyYXdUZXh0U3RyaW5nKHBEZXZpY2UsIENQREZfUG9pbnQocHRCVC54K3B0T2Zmc2V0LngsIHB0QlQueStwdE9mZnNldC55KSwgcEZvbnRNYXAtPkdldFBERkZvbnQobkZvbnRJbmRleCksDQotCQkJCQkJCQkJZkZvbnRTaXplLCBwVXNlcjJEZXZpY2UsIHNUZXh0QnVmLkdldEJ5dGVTdHJpbmcoKSwgY3JPbGRGaWxsLCBjclRleHRTdHJva2UsIG5Ib3J6U2NhbGUpOw0KLQ0KLQkJCQkJCQkJc1RleHRCdWYuQ2xlYXIoKTsNCi0JCQkJCQkJfQ0KLQkJCQkJCQluRm9udEluZGV4ID0gd29yZC5uRm9udEluZGV4Ow0KLQkJCQkJCQlwdEJUID0gd29yZC5wdFdvcmQ7DQotCQkJCQkJCWNyT2xkRmlsbCA9IGNyQ3VyRmlsbDsNCi0JCQkJCQl9DQotDQotCQkJCQkJc1RleHRCdWYgPDwgR2V0UERGV29yZFN0cmluZyhwRm9udE1hcCwgd29yZC5uRm9udEluZGV4LCB3b3JkLldvcmQsIFN1YldvcmQpOwkJCQkJCQ0KLQkJCQkJfQ0KLQkJCQkJZWxzZQ0KLQkJCQkJew0KLQkJCQkJCURyYXdUZXh0U3RyaW5nKHBEZXZpY2UsQ1BERl9Qb2ludCh3b3JkLnB0V29yZC54K3B0T2Zmc2V0LngsIHdvcmQucHRXb3JkLnkrcHRPZmZzZXQueSksIHBGb250TWFwLT5HZXRQREZGb250KHdvcmQubkZvbnRJbmRleCksDQotCQkJCQkJCWZGb250U2l6ZSwgcFVzZXIyRGV2aWNlLCBHZXRQREZXb3JkU3RyaW5nKHBGb250TWFwLCB3b3JkLm5Gb250SW5kZXgsIHdvcmQuV29yZCwgU3ViV29yZCksIGNyQ3VyRmlsbCwgY3JUZXh0U3Ryb2tlLCBuSG9yelNjYWxlKTsNCi0NCi0JCQkJCX0NCi0JCQkJCW9sZHBsYWNlID0gcGxhY2U7DQotDQotDQotCQkJCX0NCi0JCQl9DQotDQotCQkJaWYgKHNUZXh0QnVmLkdldExlbmd0aCgpID4gMCkNCi0JCQl7CQkJCQ0KLQkJCQlEcmF3VGV4dFN0cmluZyhwRGV2aWNlLCBDUERGX1BvaW50KHB0QlQueCtwdE9mZnNldC54LCBwdEJULnkrcHRPZmZzZXQueSksIHBGb250TWFwLT5HZXRQREZGb250KG5Gb250SW5kZXgpLA0KLQkJCQkJZkZvbnRTaXplLCBwVXNlcjJEZXZpY2UsIHNUZXh0QnVmLkdldEJ5dGVTdHJpbmcoKSwgY3JPbGRGaWxsLCBjclRleHRTdHJva2UsIG5Ib3J6U2NhbGUpOw0KLQkJCX0JCQkNCi0JCX0NCi0JfQ0KLQkNCi0JcERldmljZS0+UmVzdG9yZVN0YXRlKCk7DQotfQ0KLQ0KLXZvaWQgSUZYX0VkaXQ6OkRyYXdSaWNoRWRpdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLCBJRlhfRWRpdCogcEVkaXQsICANCi0JCQkJCQljb25zdCBDUERGX1JlY3QmIHJjQ2xpcCwgY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UpDQotew0KLQkvL0ZYX0ZMT0FUIGZGb250U2l6ZSA9IHBFZGl0LT5HZXRGb250U2l6ZSgpOw0KLQlDUFZUX1dvcmRSYW5nZSB3clNlbGVjdCA9IHBFZGl0LT5HZXRTZWxlY3RXb3JkUmFuZ2UoKTsNCi0NCi0JRlhfQ09MT1JSRUYgY3JDdXJUZXh0ID0gQXJnYkVuY29kZSgyNTUsIDAsMCwwKTsNCi0JRlhfQ09MT1JSRUYgY3JPbGQgPSBjckN1clRleHQ7DQotCUZYX0JPT0wgYlNlbGVjdCA9IEZBTFNFOw0KLQljb25zdCBGWF9DT0xPUlJFRiBjcldoaXRlID0gQXJnYkVuY29kZSgyNTUsMjU1LDI1NSwyNTUpOw0KLQljb25zdCBGWF9DT0xPUlJFRiBjclNlbEJLID0gQXJnYkVuY29kZSgyNTUsMCw1MSwxMTMpOw0KLQ0KLQlDRlhfQnl0ZVRleHRCdWYgc1RleHRCdWY7DQotCUNQVlRfV29yZFByb3BzIHdwOw0KLQlDUERGX1BvaW50IHB0QlQoMC4wZiwwLjBmKTsNCi0NCi0JcERldmljZS0+U2F2ZVN0YXRlKCk7DQotDQotCWlmICghcmNDbGlwLklzRW1wdHkoKSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjVGVtcCA9IHJjQ2xpcDsNCi0JCXBVc2VyMkRldmljZS0+VHJhbnNmb3JtUmVjdChyY1RlbXApOw0KLQkJRlhfUkVDVCByY0RldkNsaXA7DQotCQlyY0RldkNsaXAubGVmdCA9IChGWF9JTlQzMilyY1RlbXAubGVmdDsNCi0JCXJjRGV2Q2xpcC5yaWdodCA9IChGWF9JTlQzMilyY1RlbXAucmlnaHQ7DQotCQlyY0RldkNsaXAudG9wID0gKEZYX0lOVDMyKXJjVGVtcC50b3A7DQotCQlyY0RldkNsaXAuYm90dG9tID0gKEZYX0lOVDMyKXJjVGVtcC5ib3R0b207DQotCQlwRGV2aWNlLT5TZXRDbGlwX1JlY3QoJnJjRGV2Q2xpcCk7DQotCX0NCi0NCi0JaWYgKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBwRWRpdC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJaWYgKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwID0gcEVkaXQtPkdldEZvbnRNYXAoKSkNCi0JCXsNCi0JCQlpZiAocFJhbmdlKQ0KLQkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOw0KLQkJCWVsc2UNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsNCi0NCi0JCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZTsJCQkNCi0NCi0JCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQ0KLQkJCXsNCi0JCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsNCi0JCQkJDQotCQkJCUNQVlRfV29yZCB3b3JkOwkJCQkNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJew0KLQkJCQkJd29yZC5Xb3JkUHJvcHMuZkZvbnRTaXplID0gd29yZC5mRm9udFNpemU7DQotDQotCQkJCQljckN1clRleHQgPSBBcmdiRW5jb2RlKDI1NSx3b3JkLldvcmRQcm9wcy5kd1dvcmRDb2xvcik7DQotDQotCQkJCQlpZiAod3JTZWxlY3QuSXNFeGlzdCgpKQ0KLQkJCQkJew0KLQkJCQkJCWJTZWxlY3QgPSBwbGFjZS5Xb3JkQ21wKHdyU2VsZWN0LkJlZ2luUG9zKSA+IDAgJiYgcGxhY2UuV29yZENtcCh3clNlbGVjdC5FbmRQb3MpIDw9IDA7DQotCQkJCQkJaWYgKGJTZWxlY3QpDQotCQkJCQkJewkJCQkJCQ0KLQkJCQkJCQljckN1clRleHQgPSBjcldoaXRlOw0KLQkJCQkJCX0NCi0JCQkJCX0NCi0NCi0JCQkJCWlmIChiU2VsZWN0KQ0KLQkJCQkJew0KLQkJCQkJCUNQVlRfTGluZSBsaW5lOw0KLQkJCQkJCXBJdGVyYXRvci0+R2V0TGluZShsaW5lKTsNCi0NCi0JCQkJCQlDRlhfUGF0aERhdGEgcGF0aFNlbEJLOw0KLQkJCQkJCXBhdGhTZWxCSy5BcHBlbmRSZWN0KHdvcmQucHRXb3JkLngJCSsgcHRPZmZzZXQueCwNCi0JCQkJCQkJbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVEZXNjZW50CSsgcHRPZmZzZXQueSwNCi0JCQkJCQkJd29yZC5wdFdvcmQueCt3b3JkLmZXaWR0aAkJCSsgcHRPZmZzZXQueCwNCi0JCQkJCQkJbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVBc2NlbnQJKyBwdE9mZnNldC55KTsNCi0NCi0JCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aFNlbEJLLCBwVXNlcjJEZXZpY2UsIE5VTEwsIGNyU2VsQkssIDAsIEZYRklMTF9XSU5ESU5HKTsJCQkJCQkJCQkJCQkNCi0JCQkJCX0NCi0NCi0JCQkJCWlmIChwbGFjZS5MaW5lQ21wKG9sZHBsYWNlKSAhPSAwIHx8IHdvcmQuV29yZFByb3BzLmZDaGFyU3BhY2UgPiAwLjBmIHx8IHdvcmQuV29yZFByb3BzLm5Ib3J6U2NhbGUgIT0gMTAwIHx8IA0KLQkJCQkJCUZYU1lTX21lbWNtcCgmd29yZC5Xb3JkUHJvcHMsICZ3cCwgc2l6ZW9mKENQVlRfV29yZFByb3BzKSkgIT0gMCB8fCANCi0JCQkJCQljck9sZCAhPSBjckN1clRleHQpDQotCQkJCQl7DQotCQkJCQkJaWYgKHNUZXh0QnVmLkdldExlbmd0aCgpID4gMCkNCi0JCQkJCQl7CQkJCQkJCQkNCi0JCQkJCQkJRHJhd1RleHRTdHJpbmcocERldmljZSwgQ1BERl9Qb2ludChwdEJULngrcHRPZmZzZXQueCwgcHRCVC55K3B0T2Zmc2V0LnkpLCBwRm9udE1hcC0+R2V0UERGRm9udCh3cC5uRm9udEluZGV4KSwNCi0JCQkJCQkJCXdwLmZGb250U2l6ZSwgcFVzZXIyRGV2aWNlLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCksIGNyT2xkLCAwLCB3cC5uSG9yelNjYWxlKTsNCi0NCi0JCQkJCQkJc1RleHRCdWYuQ2xlYXIoKTsNCi0JCQkJCQl9DQotCQkJCQkJd3AgPSB3b3JkLldvcmRQcm9wczsNCi0JCQkJCQlwdEJUID0gd29yZC5wdFdvcmQ7DQotCQkJCQkJY3JPbGQgPSBjckN1clRleHQ7DQotCQkJCQl9DQotDQotCQkJCQlzVGV4dEJ1ZiA8PCBHZXRQREZXb3JkU3RyaW5nKHBGb250TWFwLCB3b3JkLldvcmRQcm9wcy5uRm9udEluZGV4LCB3b3JkLldvcmQsIDApOwkNCi0JCQkJCQ0KLQkJCQkJaWYgKHdvcmQuV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX1VOREVSTElORSkNCi0JCQkJCXsNCi0JCQkJCQlDRlhfUGF0aERhdGEgcGF0aFVuZGVybGluZTsNCi0JCQkJCQlDUERGX1JlY3QgcmNVbmRlcmxpbmUgPSBHZXRVbmRlckxpbmVSZWN0KHdvcmQpOw0KLQkJCQkJCXBhdGhVbmRlcmxpbmUuQXBwZW5kUmVjdChyY1VuZGVybGluZS5sZWZ0LCByY1VuZGVybGluZS5ib3R0b20sIHJjVW5kZXJsaW5lLnJpZ2h0LCByY1VuZGVybGluZS50b3ApOw0KLQ0KLQkJCQkJCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoVW5kZXJsaW5lLCBwVXNlcjJEZXZpY2UsIE5VTEwsIGNyQ3VyVGV4dCwgMCwgRlhGSUxMX1dJTkRJTkcpOwkNCi0JCQkJCX0NCi0NCi0JCQkJCWlmICh3b3JkLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9DUk9TU09VVCkNCi0JCQkJCXsNCi0JCQkJCQlDRlhfUGF0aERhdGEgcGF0aENyb3Nzb3V0Ow0KLQkJCQkJCUNQREZfUmVjdCByY0Nyb3Nzb3V0ID0gR2V0Q3Jvc3NvdXRSZWN0KHdvcmQpOw0KLQkJCQkJCXBhdGhDcm9zc291dC5BcHBlbmRSZWN0KHJjQ3Jvc3NvdXQubGVmdCwgcmNDcm9zc291dC5ib3R0b20sIHJjQ3Jvc3NvdXQucmlnaHQsIHJjQ3Jvc3NvdXQudG9wKTsNCi0NCi0JCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aENyb3Nzb3V0LCBwVXNlcjJEZXZpY2UsIE5VTEwsIGNyQ3VyVGV4dCwgMCwgRlhGSUxMX1dJTkRJTkcpOw0KLQkJCQkJfQ0KLQ0KLQkJCQkJb2xkcGxhY2UgPSBwbGFjZTsJCQkJCQ0KLQkJCQl9DQotCQkJfQ0KLQ0KLQkJCWlmIChzVGV4dEJ1Zi5HZXRMZW5ndGgoKSA+IDApDQotCQkJewkJCQkNCi0JCQkJRHJhd1RleHRTdHJpbmcocERldmljZSwgQ1BERl9Qb2ludChwdEJULngrcHRPZmZzZXQueCwgcHRCVC55K3B0T2Zmc2V0LnkpLCBwRm9udE1hcC0+R2V0UERGRm9udCh3cC5uRm9udEluZGV4KSwNCi0JCQkJCXdwLmZGb250U2l6ZSwgcFVzZXIyRGV2aWNlLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCksIGNyT2xkLCAwLCB3cC5uSG9yelNjYWxlKTsNCi0JCQl9DQotCQl9DQotCX0NCi0JDQotCXBEZXZpY2UtPlJlc3RvcmVTdGF0ZSgpOw0KLX0NCi0NCi1zdGF0aWMgdm9pZCBBZGRMaW5lVG9QYWdlT2JqZWN0cyhDUERGX1BhZ2VPYmplY3RzKiBwUGFnZU9ianMsIEZYX0NPTE9SUkVGIGNyU3Ryb2tlLCANCi0JCQkJCQkJCSBjb25zdCBDUERGX1BvaW50JiBwdDEsIGNvbnN0IENQREZfUG9pbnQmIHB0MikNCi17DQotCUNQREZfUGF0aE9iamVjdCogcFBhdGhPYmogPSBuZXcgQ1BERl9QYXRoT2JqZWN0Ow0KLQlDUERGX1BhdGhEYXRhKiBwUGF0aERhdGEgPSBwUGF0aE9iai0+bV9QYXRoLkdldE1vZGlmeSgpOw0KLQ0KLQlwUGF0aERhdGEtPlNldFBvaW50Q291bnQoMik7DQotCXBQYXRoRGF0YS0+U2V0UG9pbnQoMCwgcHQxLngsIHB0MS55LCBGWFBUX01PVkVUTyk7DQotCXBQYXRoRGF0YS0+U2V0UG9pbnQoMSwgcHQyLngsIHB0Mi55LCBGWFBUX0xJTkVUTyk7DQotDQotCUZYX0ZMT0FUIHJnYlszXTsNCi0JcmdiWzBdID0gRlhBUkdCX1IoY3JTdHJva2UpIC8gMjU1LjBmOw0KLQlyZ2JbMV0gPSBGWEFSR0JfRyhjclN0cm9rZSkgLyAyNTUuMGY7DQotCXJnYlsyXSA9IEZYQVJHQl9CKGNyU3Ryb2tlKSAvIDI1NS4wZjsNCi0JcFBhdGhPYmotPm1fQ29sb3JTdGF0ZS5TZXRTdHJva2VDb2xvcihDUERGX0NvbG9yU3BhY2U6OkdldFN0b2NrQ1MoUERGQ1NfREVWSUNFUkdCKSwgcmdiLCAzKTsNCi0NCi0JQ0ZYX0dyYXBoU3RhdGVEYXRhKiBwRGF0YSA9IHBQYXRoT2JqLT5tX0dyYXBoU3RhdGUuR2V0TW9kaWZ5KCk7DQotCXBEYXRhLT5tX0xpbmVXaWR0aCA9IDE7DQotDQotCXBQYWdlT2Jqcy0+SW5zZXJ0T2JqZWN0KHBQYWdlT2Jqcy0+R2V0TGFzdE9iamVjdFBvc2l0aW9uKCkscFBhdGhPYmopOw0KLX0NCi0NCi1zdGF0aWMgdm9pZCBBZGRSZWN0VG9QYWdlT2JqZWN0cyhDUERGX1BhZ2VPYmplY3RzKiBwUGFnZU9ianMsIEZYX0NPTE9SUkVGIGNyRmlsbCwgY29uc3QgQ1BERl9SZWN0JiByY0ZpbGwpDQotew0KLQlDUERGX1BhdGhPYmplY3QqIHBQYXRoT2JqID0gbmV3IENQREZfUGF0aE9iamVjdDsNCi0JQ1BERl9QYXRoRGF0YSogcFBhdGhEYXRhID0gcFBhdGhPYmotPm1fUGF0aC5HZXRNb2RpZnkoKTsNCi0JcFBhdGhEYXRhLT5BcHBlbmRSZWN0KHJjRmlsbC5sZWZ0LHJjRmlsbC5ib3R0b20scmNGaWxsLnJpZ2h0LHJjRmlsbC50b3ApOwkNCi0JDQotCUZYX0ZMT0FUIHJnYlszXTsNCi0JcmdiWzBdID0gRlhBUkdCX1IoY3JGaWxsKSAvIDI1NS4wZiA7DQotCXJnYlsxXSA9IEZYQVJHQl9HKGNyRmlsbCkgLyAyNTUuMGY7DQotCXJnYlsyXSA9IEZYQVJHQl9CKGNyRmlsbCkgLyAyNTUuMGY7DQotCXBQYXRoT2JqLT5tX0NvbG9yU3RhdGUuU2V0RmlsbENvbG9yKENQREZfQ29sb3JTcGFjZTo6R2V0U3RvY2tDUyhQREZDU19ERVZJQ0VSR0IpLCByZ2IsIDMpOw0KLQ0KLQlwUGF0aE9iai0+bV9GaWxsVHlwZSA9IEZYRklMTF9BTFRFUk5BVEU7DQotCXBQYXRoT2JqLT5tX2JTdHJva2UgPSBGQUxTRTsNCi0NCi0JcFBhZ2VPYmpzLT5JbnNlcnRPYmplY3QocFBhZ2VPYmpzLT5HZXRMYXN0T2JqZWN0UG9zaXRpb24oKSxwUGF0aE9iaik7DQotfQ0KLQ0KLXN0YXRpYyBDUERGX1RleHRPYmplY3QqIEFkZFRleHRPYmpUb1BhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqcywgRlhfQ09MT1JSRUYgY3JUZXh0LCANCi0JCQkJCQkJIENQREZfRm9udCogcEZvbnQsIEZYX0ZMT0FUIGZGb250U2l6ZSwgRlhfRkxPQVQgZkNoYXJTcGFjZSwgRlhfSU5UMzIgbkhvcnpTY2FsZSwgDQotCQkJCQkJCSBjb25zdCBDUERGX1BvaW50JiBwb2ludCwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHRleHQpDQotew0KLQlDUERGX1RleHRPYmplY3QqIHBUeHRPYmogPSBuZXcgQ1BERl9UZXh0T2JqZWN0Ow0KLQkJCQ0KLQlDUERGX1RleHRTdGF0ZURhdGEqIHBUZXh0U3RhdGVEYXRhID0gcFR4dE9iai0+bV9UZXh0U3RhdGUuR2V0TW9kaWZ5KCk7DQotCXBUZXh0U3RhdGVEYXRhLT5tX3BGb250ID0gcEZvbnQ7DQotCXBUZXh0U3RhdGVEYXRhLT5tX0ZvbnRTaXplID0gZkZvbnRTaXplOw0KLQlwVGV4dFN0YXRlRGF0YS0+bV9DaGFyU3BhY2UgPSBmQ2hhclNwYWNlOw0KLQlwVGV4dFN0YXRlRGF0YS0+bV9Xb3JkU3BhY2UgPSAwOw0KLQlwVGV4dFN0YXRlRGF0YS0+bV9UZXh0TW9kZSAgPSAwOw0KLQlwVGV4dFN0YXRlRGF0YS0+bV9NYXRyaXhbMF0gPSBuSG9yelNjYWxlIC8gMTAwLjBmOw0KLQlwVGV4dFN0YXRlRGF0YS0+bV9NYXRyaXhbMV0gPSAwOw0KLQlwVGV4dFN0YXRlRGF0YS0+bV9NYXRyaXhbMl0gPSAwOw0KLQlwVGV4dFN0YXRlRGF0YS0+bV9NYXRyaXhbM10gPSAxOw0KLQ0KLQlGWF9GTE9BVCByZ2JbM107DQotCXJnYlswXSA9IEZYQVJHQl9SKGNyVGV4dCkgLyAyNTUuMGYgOw0KLQlyZ2JbMV0gPSBGWEFSR0JfRyhjclRleHQpIC8gMjU1LjBmOw0KLQlyZ2JbMl0gPSBGWEFSR0JfQihjclRleHQpIC8gMjU1LjBmOw0KLQlwVHh0T2JqLT5tX0NvbG9yU3RhdGUuU2V0RmlsbENvbG9yKENQREZfQ29sb3JTcGFjZTo6R2V0U3RvY2tDUyhQREZDU19ERVZJQ0VSR0IpLHJnYiwgMyk7DQotCXBUeHRPYmotPm1fQ29sb3JTdGF0ZS5TZXRTdHJva2VDb2xvcihDUERGX0NvbG9yU3BhY2U6OkdldFN0b2NrQ1MoUERGQ1NfREVWSUNFUkdCKSxyZ2IsIDMpOw0KLQ0KLQlwVHh0T2JqLT5TZXRQb3NpdGlvbihwb2ludC54LHBvaW50LnkpOw0KLQlwVHh0T2JqLT5TZXRUZXh0KHRleHQpOwkNCi0NCi0JcFBhZ2VPYmpzLT5JbnNlcnRPYmplY3QocFBhZ2VPYmpzLT5HZXRMYXN0T2JqZWN0UG9zaXRpb24oKSxwVHh0T2JqKTsNCi0NCi0JcmV0dXJuIHBUeHRPYmo7DQotfQ0KLQ0KLS8qDQotTGlzdCBvZiBjdXJyZW50bHkgc3VwcG9ydGVkIHN0YW5kYXJkIGZvbnRzOg0KLUNvdXJpZXIsIENvdXJpZXItQm9sZCwgQ291cmllci1Cb2xkT2JsaXF1ZSwgQ291cmllci1PYmxpcXVlDQotSGVsdmV0aWNhLCBIZWx2ZXRpY2EtQm9sZCwgSGVsdmV0aWNhLUJvbGRPYmxpcXVlLCBIZWx2ZXRpY2EtT2JsaXF1ZQ0KLVRpbWVzLVJvbWFuLCBUaW1lcy1Cb2xkLCBUaW1lcy1JdGFsaWMsIFRpbWVzLUJvbGRJdGFsaWMNCi1TeW1ib2wsIFphcGZEaW5nYmF0cw0KLSovDQotDQotY29uc3QgY2hhciogZ19zRlhFRElUU3RhbmRhcmRGb250TmFtZVtdID0geyJDb3VyaWVyIiwgIkNvdXJpZXItQm9sZCIsICJDb3VyaWVyLUJvbGRPYmxpcXVlIiwgIkNvdXJpZXItT2JsaXF1ZSIsDQotCSJIZWx2ZXRpY2EiLCAiSGVsdmV0aWNhLUJvbGQiLCAiSGVsdmV0aWNhLUJvbGRPYmxpcXVlIiwgIkhlbHZldGljYS1PYmxpcXVlIiwNCi0JIlRpbWVzLVJvbWFuIiwgIlRpbWVzLUJvbGQiLCAiVGltZXMtSXRhbGljIiwgIlRpbWVzLUJvbGRJdGFsaWMiLA0KLQkiU3ltYm9sIiwgIlphcGZEaW5nYmF0cyJ9Ow0KLQ0KLXN0YXRpYyBGWF9CT09MIEZYX0VESVRfSXNTdGFuZGFyZEZvbnQoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSkNCi17DQotCWZvciAoRlhfSU5UMzIgaT0wOyBpPDE0OyBpKyspDQotCXsNCi0JCWlmIChzRm9udE5hbWUgPT0gZ19zRlhFRElUU3RhbmRhcmRGb250TmFtZVtpXSkNCi0JCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgSUZYX0VkaXQ6OkdlbmVyYXRlUGFnZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmplY3RzLCBJRlhfRWRpdCogcEVkaXQsDQotCQkJCQkJCQkgICBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSwgRlhfQ09MT1JSRUYgY3JUZXh0LCBDRlhfQXJyYXlUZW1wbGF0ZTxDUERGX1RleHRPYmplY3QqPiYgT2JqQXJyYXkpDQotew0KLQlGWF9GTE9BVCBmRm9udFNpemUgPSBwRWRpdC0+R2V0Rm9udFNpemUoKTsNCi0NCi0JRlhfSU5UMzIgbk9sZEZvbnRJbmRleCA9IC0xOw0KLQ0KLQlDRlhfQnl0ZVRleHRCdWYgc1RleHRCdWY7DQotCUNQREZfUG9pbnQgcHRCVCgwLjBmLDAuMGYpOw0KLQ0KLQlPYmpBcnJheS5SZW1vdmVBbGwoKTsNCi0NCi0JaWYgKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBwRWRpdC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJaWYgKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwID0gcEVkaXQtPkdldEZvbnRNYXAoKSkNCi0JCXsNCi0JCQlpZiAocFJhbmdlKQ0KLQkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOw0KLQkJCWVsc2UNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsNCi0NCi0JCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZTsJCQkNCi0NCi0JCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQ0KLQkJCXsNCi0JCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsNCi0JCQkJDQotCQkJCUNQVlRfV29yZCB3b3JkOwkJCQkNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJew0KLQkJCQkJaWYgKHBsYWNlLkxpbmVDbXAob2xkcGxhY2UpICE9IDAgfHwgbk9sZEZvbnRJbmRleCAhPSB3b3JkLm5Gb250SW5kZXgpDQotCQkJCQl7DQotCQkJCQkJaWYgKHNUZXh0QnVmLkdldExlbmd0aCgpID4gMCkNCi0JCQkJCQl7DQotCQkJCQkJCU9iakFycmF5LkFkZChBZGRUZXh0T2JqVG9QYWdlT2JqZWN0cyhwUGFnZU9iamVjdHMsIGNyVGV4dCwgcEZvbnRNYXAtPkdldFBERkZvbnQobk9sZEZvbnRJbmRleCksIGZGb250U2l6ZSwgMC4wZiwgMTAwLA0KLQkJCQkJCQkJQ1BERl9Qb2ludChwdEJULngrcHRPZmZzZXQueCwgcHRCVC55K3B0T2Zmc2V0LnkpLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCkpKTsNCi0NCi0JCQkJCQkJc1RleHRCdWYuQ2xlYXIoKTsNCi0JCQkJCQl9DQotDQotCQkJCQkJcHRCVCA9IHdvcmQucHRXb3JkOw0KLQkJCQkJCW5PbGRGb250SW5kZXggPSB3b3JkLm5Gb250SW5kZXg7DQotCQkJCQl9DQotDQotCQkJCQlzVGV4dEJ1ZiA8PCBHZXRQREZXb3JkU3RyaW5nKHBGb250TWFwLCB3b3JkLm5Gb250SW5kZXgsIHdvcmQuV29yZCwgMCk7DQotCQkJCQlvbGRwbGFjZSA9IHBsYWNlOwkJCQkJDQotCQkJCX0NCi0JCQl9DQotDQotCQkJaWYgKHNUZXh0QnVmLkdldExlbmd0aCgpID4gMCkNCi0JCQl7CQkJCQ0KLQkJCQlPYmpBcnJheS5BZGQoQWRkVGV4dE9ialRvUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBjclRleHQsIHBGb250TWFwLT5HZXRQREZGb250KG5PbGRGb250SW5kZXgpLCBmRm9udFNpemUsIDAuMGYsIDEwMCwNCi0JCQkJCUNQREZfUG9pbnQocHRCVC54K3B0T2Zmc2V0LngsIHB0QlQueStwdE9mZnNldC55KSwgc1RleHRCdWYuR2V0Qnl0ZVN0cmluZygpKSk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgSUZYX0VkaXQ6OkdlbmVyYXRlUmljaFBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgSUZYX0VkaXQqIHBFZGl0LA0KLQkJCQkJCQkJICAgY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UsIENGWF9BcnJheVRlbXBsYXRlPENQREZfVGV4dE9iamVjdCo+JiBPYmpBcnJheSkNCi17DQotDQotDQotCUZYX0NPTE9SUkVGIGNyQ3VyVGV4dCA9IEFyZ2JFbmNvZGUoMjU1LCAwLCAwLCAwKTsNCi0JRlhfQ09MT1JSRUYgY3JPbGQgPSBjckN1clRleHQ7DQotDQotDQotCUNGWF9CeXRlVGV4dEJ1ZiBzVGV4dEJ1ZjsNCi0JQ1BWVF9Xb3JkUHJvcHMgd3A7DQotCUNQREZfUG9pbnQgcHRCVCgwLjBmLDAuMGYpOw0KLQ0KLQlPYmpBcnJheS5SZW1vdmVBbGwoKTsNCi0NCi0JaWYgKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBwRWRpdC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJaWYgKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwID0gcEVkaXQtPkdldEZvbnRNYXAoKSkNCi0JCXsNCi0JCQlpZiAocFJhbmdlKQ0KLQkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOw0KLQkJCWVsc2UNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsNCi0NCi0JCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZTsJCQkNCi0NCi0JCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQ0KLQkJCXsNCi0JCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsNCi0JCQkJDQotCQkJCUNQVlRfV29yZCB3b3JkOwkJCQkNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJew0KLQkJCQkJd29yZC5Xb3JkUHJvcHMuZkZvbnRTaXplID0gd29yZC5mRm9udFNpemU7DQotDQotCQkJCQljckN1clRleHQgPSBBcmdiRW5jb2RlKDI1NSx3b3JkLldvcmRQcm9wcy5kd1dvcmRDb2xvcik7DQotDQotCQkJCQlpZiAocGxhY2UuTGluZUNtcChvbGRwbGFjZSkgIT0gMCB8fCB3b3JkLldvcmRQcm9wcy5mQ2hhclNwYWNlID4gMC4wZiB8fCB3b3JkLldvcmRQcm9wcy5uSG9yelNjYWxlICE9IDEwMCB8fCANCi0JCQkJCQlGWFNZU19tZW1jbXAoJndvcmQuV29yZFByb3BzLCAmd3AsIHNpemVvZihDUFZUX1dvcmRQcm9wcykpICE9IDAgfHwgDQotCQkJCQkJY3JPbGQgIT0gY3JDdXJUZXh0KQ0KLQkJCQkJew0KLQkJCQkJCWlmIChzVGV4dEJ1Zi5HZXRMZW5ndGgoKSA+IDApDQotCQkJCQkJew0KLQkJCQkJCQlPYmpBcnJheS5BZGQoQWRkVGV4dE9ialRvUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBjck9sZCwgcEZvbnRNYXAtPkdldFBERkZvbnQod3AubkZvbnRJbmRleCksIHdwLmZGb250U2l6ZSwgd3AuZkNoYXJTcGFjZSwgd3AubkhvcnpTY2FsZSwNCi0JCQkJCQkJCUNQREZfUG9pbnQocHRCVC54K3B0T2Zmc2V0LngsIHB0QlQueStwdE9mZnNldC55KSwgc1RleHRCdWYuR2V0Qnl0ZVN0cmluZygpKSk7DQotDQotCQkJCQkJCXNUZXh0QnVmLkNsZWFyKCk7DQotCQkJCQkJfQ0KLQ0KLQkJCQkJCXdwID0gd29yZC5Xb3JkUHJvcHM7DQotCQkJCQkJcHRCVCA9IHdvcmQucHRXb3JkOw0KLQkJCQkJCWNyT2xkID0gY3JDdXJUZXh0Ow0KLQkNCi0JCQkJCX0NCi0NCi0JCQkJCXNUZXh0QnVmIDw8IEdldFBERldvcmRTdHJpbmcocEZvbnRNYXAsIHdvcmQuV29yZFByb3BzLm5Gb250SW5kZXgsIHdvcmQuV29yZCwgMCk7CQ0KLQkJCQkJDQotCQkJCQlpZiAod29yZC5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfVU5ERVJMSU5FKQ0KLQkJCQkJey8qDQotCQkJCQkJQWRkTGluZVRvUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBjckN1clRleHQsIA0KLQkJCQkJCQlDUERGX1BvaW50KHdvcmQucHRXb3JkLngsIHdvcmQucHRXb3JkLnkgKyB3b3JkLmZEZXNjZW50ICogMC40ZiksDQotCQkJCQkJCUNQREZfUG9pbnQod29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoLCB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudCAqIDAuNGYpKTsJCQkJCQkJDQotKi8NCi0JCQkJCQlDUERGX1JlY3QgcmNVbmRlcmxpbmUgPSBHZXRVbmRlckxpbmVSZWN0KHdvcmQpOw0KLQkJCQkJCXJjVW5kZXJsaW5lLmxlZnQgKz0gcHRPZmZzZXQueDsNCi0JCQkJCQlyY1VuZGVybGluZS5yaWdodCArPSBwdE9mZnNldC54Ow0KLQkJCQkJCXJjVW5kZXJsaW5lLnRvcCArPSBwdE9mZnNldC55Ow0KLQkJCQkJCXJjVW5kZXJsaW5lLmJvdHRvbSArPSBwdE9mZnNldC55Ow0KLQkJCQkJCQ0KLQkJCQkJCUFkZFJlY3RUb1BhZ2VPYmplY3RzKHBQYWdlT2JqZWN0cywgY3JDdXJUZXh0LCByY1VuZGVybGluZSk7CQkJCQkJCQ0KLQkJCQkJfQ0KLQ0KLQkJCQkJaWYgKHdvcmQuV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX0NST1NTT1VUKQ0KLQkJCQkJew0KLQkJCQkJCUNQREZfUmVjdCByY0Nyb3Nzb3V0ID0gR2V0Q3Jvc3NvdXRSZWN0KHdvcmQpOw0KLQkJCQkJCXJjQ3Jvc3NvdXQubGVmdCArPSBwdE9mZnNldC54Ow0KLQkJCQkJCXJjQ3Jvc3NvdXQucmlnaHQgKz0gcHRPZmZzZXQueDsNCi0JCQkJCQlyY0Nyb3Nzb3V0LnRvcCArPSBwdE9mZnNldC55Ow0KLQkJCQkJCXJjQ3Jvc3NvdXQuYm90dG9tICs9IHB0T2Zmc2V0Lnk7DQotDQotCQkJCQkJQWRkUmVjdFRvUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBjckN1clRleHQsIHJjQ3Jvc3NvdXQpOwkJCQkJCQ0KLQkJCQkJfQ0KLQ0KLQkJCQkJb2xkcGxhY2UgPSBwbGFjZTsJCQkJCQ0KLQkJCQl9DQotCQkJfQ0KLQ0KLQkJCWlmIChzVGV4dEJ1Zi5HZXRMZW5ndGgoKSA+IDApDQotCQkJewkJCQkNCi0JCQkJT2JqQXJyYXkuQWRkKEFkZFRleHRPYmpUb1BhZ2VPYmplY3RzKHBQYWdlT2JqZWN0cywgY3JPbGQsIHBGb250TWFwLT5HZXRQREZGb250KHdwLm5Gb250SW5kZXgpLCB3cC5mRm9udFNpemUsIHdwLmZDaGFyU3BhY2UsIHdwLm5Ib3J6U2NhbGUsDQotCQkJCQlDUERGX1BvaW50KHB0QlQueCtwdE9mZnNldC54LCBwdEJULnkrcHRPZmZzZXQueSksIHNUZXh0QnVmLkdldEJ5dGVTdHJpbmcoKSkpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIElGWF9FZGl0OjpHZW5lcmF0ZVVuZGVybGluZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmplY3RzLCBJRlhfRWRpdCogcEVkaXQsDQotCQkJCQkJCQkgICBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSwgRlhfQ09MT1JSRUYgY29sb3IpDQotew0KLQ0KLQ0KLQlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQ0KLQl7DQotCQlpZiAocEVkaXQtPkdldEZvbnRNYXAoKSkNCi0JCXsNCi0JCQlpZiAocFJhbmdlKQ0KLQkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOw0KLQkJCWVsc2UNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsNCi0NCi0JCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZTsJCQkNCi0NCi0JCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQ0KLQkJCXsNCi0JCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsNCi0JCQkJDQotCQkJCUNQVlRfV29yZCB3b3JkOwkJCQkNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJew0KLQkJCQkJQ1BERl9SZWN0IHJjVW5kZXJsaW5lID0gR2V0VW5kZXJMaW5lUmVjdCh3b3JkKTsNCi0JCQkJCXJjVW5kZXJsaW5lLmxlZnQgKz0gcHRPZmZzZXQueDsNCi0JCQkJCXJjVW5kZXJsaW5lLnJpZ2h0ICs9IHB0T2Zmc2V0Lng7DQotCQkJCQlyY1VuZGVybGluZS50b3AgKz0gcHRPZmZzZXQueTsNCi0JCQkJCXJjVW5kZXJsaW5lLmJvdHRvbSArPSBwdE9mZnNldC55Ow0KLQkJCQkJQWRkUmVjdFRvUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBjb2xvciwgcmNVbmRlcmxpbmUpOw0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4ZWRpdC9meGV0X3N0dWIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2Z4ZWRpdC9meF9lZGl0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9meGVkaXQvZnhldF9lZGl0LmgiCisKKyNkZWZpbmUgRlhfRURJVF9VTkRFUkxJTkVIQUxGV0lEVEgJCQkJMC41ZgorI2RlZmluZSBGWF9FRElUX0NST1NTT1VUSEFMRldJRFRICQkJCTAuNWYKKworZXh0ZXJuIENGWF9CeXRlU3RyaW5nIEdldFBERldvcmRTdHJpbmcoSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwLCBGWF9JTlQzMiBuRm9udEluZGV4LCBGWF9XT1JEIFdvcmQsIEZYX1dPUkQgU3ViV29yZCk7CisKK0NQREZfUmVjdCBHZXRVbmRlckxpbmVSZWN0KGNvbnN0IENQVlRfV29yZCYgd29yZCkKK3sKKwlyZXR1cm4gQ1BERl9SZWN0KHdvcmQucHRXb3JkLngsIHdvcmQucHRXb3JkLnkgKyB3b3JkLmZEZXNjZW50ICogMC41ZiwKKwkJCQkJCXdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aCwgd29yZC5wdFdvcmQueSArIHdvcmQuZkRlc2NlbnQgKiAwLjI1Zik7Cit9CisKK0NQREZfUmVjdCBHZXRDcm9zc291dFJlY3QoY29uc3QgQ1BWVF9Xb3JkJiB3b3JkKQoreworCXJldHVybiBDUERGX1JlY3Qod29yZC5wdFdvcmQueCwgd29yZC5wdFdvcmQueSArICh3b3JkLmZBc2NlbnQgKyB3b3JkLmZEZXNjZW50KSAqIDAuNWYgKyB3b3JkLmZEZXNjZW50ICogMC4yNWYsCisJCQkJCQkJd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoLCB3b3JkLnB0V29yZC55ICsgKHdvcmQuZkFzY2VudCArIHdvcmQuZkRlc2NlbnQpICogMC41Zik7Cit9CisKK3N0YXRpYyB2b2lkIERyYXdUZXh0U3RyaW5nKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIGNvbnN0IENQREZfUG9pbnQmIHB0LCBDUERGX0ZvbnQqIHBGb250LCBGWF9GTE9BVCBmRm9udFNpemUsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsCisJCQkJCSAgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0ciwgRlhfQVJHQiBjclRleHRGaWxsLCBGWF9BUkdCIGNyVGV4dFN0cm9rZSwgRlhfSU5UMzIgbkhvcnpTY2FsZSkKK3sKKwlGWF9GTE9BVCB4ID0gcHQueCwgeSA9IHB0Lnk7CisJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm0oeCwgeSk7CisKKwlpZiAocEZvbnQpCisJeworCQlpZiAobkhvcnpTY2FsZSAhPSAxMDApCisJCXsKKwkJCUNQREZfTWF0cml4IG10KG5Ib3J6U2NhbGUvMTAwLjBmLDAsMCwxLDAsMCk7CisJCQltdC5Db25jYXQoKnBVc2VyMkRldmljZSk7CisKKwkJCUNQREZfUmVuZGVyT3B0aW9ucyBybzsKKwkJCXJvLm1fRmxhZ3MgPSBSRU5ERVJfQ0xFQVJUWVBFOworCQkJcm8ubV9Db2xvck1vZGUgPSBSRU5ERVJfQ09MT1JfTk9STUFMOworCisJCQlpZiAoY3JUZXh0U3Ryb2tlICE9IDApCisJCQl7CisJCQkJQ1BERl9Qb2ludCBwdDEoMCwwKSwgcHQyKDEsMCk7CisJCQkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm0ocHQxLngsIHB0MS55KTsKKwkJCQlwVXNlcjJEZXZpY2UtPlRyYW5zZm9ybShwdDIueCwgcHQyLnkpOworCQkJCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CisJCQkJZ3NkLm1fTGluZVdpZHRoID0gKEZYX0ZMT0FUKUZYU1lTX2ZhYnMoKHB0Mi54ICsgcHQyLnkpIC0gKHB0MS54ICsgcHQxLnkpKTsKKworCQkJCUNQREZfVGV4dFJlbmRlcmVyOjpEcmF3VGV4dFN0cmluZyhwRGV2aWNlLHgsIHksIHBGb250LCBmRm9udFNpemUsICZtdCwgc3RyLCBjclRleHRGaWxsLCBjclRleHRTdHJva2UsICZnc2QsICZybyk7CisJCQl9CisJCQllbHNlCisJCQkJQ1BERl9UZXh0UmVuZGVyZXI6OkRyYXdUZXh0U3RyaW5nKHBEZXZpY2UseCwgeSwgcEZvbnQsIGZGb250U2l6ZSwgJm10LCBzdHIsIGNyVGV4dEZpbGwsIDAsIE5VTEwsICZybyk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlDUERGX1JlbmRlck9wdGlvbnMgcm87CisJCQlyby5tX0ZsYWdzID0gUkVOREVSX0NMRUFSVFlQRTsKKwkJCXJvLm1fQ29sb3JNb2RlID0gUkVOREVSX0NPTE9SX05PUk1BTDsKKworCQkJaWYgKGNyVGV4dFN0cm9rZSAhPSAwKQorCQkJeworCQkJCUNQREZfUG9pbnQgcHQxKDAsMCksIHB0MigxLDApOworCQkJCXBVc2VyMkRldmljZS0+VHJhbnNmb3JtKHB0MS54LCBwdDEueSk7CisJCQkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm0ocHQyLngsIHB0Mi55KTsKKwkJCQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOworCQkJCWdzZC5tX0xpbmVXaWR0aCA9IChGWF9GTE9BVClGWFNZU19mYWJzKChwdDIueCArIHB0Mi55KSAtIChwdDEueCArIHB0MS55KSk7CisKKwkJCQlDUERGX1RleHRSZW5kZXJlcjo6RHJhd1RleHRTdHJpbmcocERldmljZSx4LCB5LCBwRm9udCwgZkZvbnRTaXplLCBwVXNlcjJEZXZpY2UsIHN0ciwgY3JUZXh0RmlsbCwgY3JUZXh0U3Ryb2tlLCAmZ3NkLCAmcm8pOworCQkJfQorCQkJZWxzZQorCQkJCUNQREZfVGV4dFJlbmRlcmVyOjpEcmF3VGV4dFN0cmluZyhwRGV2aWNlLHgsIHksIHBGb250LCBmRm9udFNpemUsIHBVc2VyMkRldmljZSwgc3RyLCBjclRleHRGaWxsLCAwLCBOVUxMLCAmcm8pOworCQl9CisJfQorfQorCit2b2lkIElGWF9FZGl0OjpEcmF3VW5kZXJsaW5lKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsIElGWF9FZGl0KiBwRWRpdCwgRlhfQ09MT1JSRUYgY29sb3IsCisJCQkJCQkJCWNvbnN0IENQREZfUmVjdCYgcmNDbGlwLCBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSkKK3sKKwlwRGV2aWNlLT5TYXZlU3RhdGUoKTsKKworCWlmICghcmNDbGlwLklzRW1wdHkoKSkKKwl7CisJCUNQREZfUmVjdCByY1RlbXAgPSByY0NsaXA7CisJCXBVc2VyMkRldmljZS0+VHJhbnNmb3JtUmVjdChyY1RlbXApOworCQlGWF9SRUNUIHJjRGV2Q2xpcDsKKwkJcmNEZXZDbGlwLmxlZnQgPSAoRlhfSU5UMzIpcmNUZW1wLmxlZnQ7CisJCXJjRGV2Q2xpcC5yaWdodCA9IChGWF9JTlQzMilyY1RlbXAucmlnaHQ7CisJCXJjRGV2Q2xpcC50b3AgPSAoRlhfSU5UMzIpcmNUZW1wLnRvcDsKKwkJcmNEZXZDbGlwLmJvdHRvbSA9IChGWF9JTlQzMilyY1RlbXAuYm90dG9tOworCQlwRGV2aWNlLT5TZXRDbGlwX1JlY3QoJnJjRGV2Q2xpcCk7CisJfQorCisJaWYgKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBwRWRpdC0+R2V0SXRlcmF0b3IoKSkKKwl7CisJCWlmIChwRWRpdC0+R2V0Rm9udE1hcCgpKQorCQl7CisJCQlpZiAocFJhbmdlKQorCQkJCXBJdGVyYXRvci0+U2V0QXQocFJhbmdlLT5CZWdpblBvcyk7CisJCQllbHNlCisJCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsKKworCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkKKwkJCXsKKwkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKwkJCQlpZiAocFJhbmdlICYmIHBsYWNlLldvcmRDbXAocFJhbmdlLT5FbmRQb3MpID4gMCkgYnJlYWs7CisKKwkJCQlDUFZUX1dvcmQgd29yZDsJCQkJCisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCUNGWF9QYXRoRGF0YSBwYXRoVW5kZXJsaW5lOworCQkJCQlDUERGX1JlY3QgcmNVbmRlcmxpbmUgPSBHZXRVbmRlckxpbmVSZWN0KHdvcmQpOworCQkJCQlyY1VuZGVybGluZS5sZWZ0ICs9IHB0T2Zmc2V0Lng7CisJCQkJCXJjVW5kZXJsaW5lLnJpZ2h0ICs9IHB0T2Zmc2V0Lng7CisJCQkJCXJjVW5kZXJsaW5lLnRvcCArPSBwdE9mZnNldC55OworCQkJCQlyY1VuZGVybGluZS5ib3R0b20gKz0gcHRPZmZzZXQueTsKKwkJCQkJcGF0aFVuZGVybGluZS5BcHBlbmRSZWN0KHJjVW5kZXJsaW5lLmxlZnQsIHJjVW5kZXJsaW5lLmJvdHRvbSwgcmNVbmRlcmxpbmUucmlnaHQsIHJjVW5kZXJsaW5lLnRvcCk7CisKKwkJCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGhVbmRlcmxpbmUsIHBVc2VyMkRldmljZSwgTlVMTCwgY29sb3IsIDAsIEZYRklMTF9XSU5ESU5HKTsKKwkJCQl9CisJCQl9CQkJCisJCX0KKwl9CisJCisJcERldmljZS0+UmVzdG9yZVN0YXRlKCk7Cit9CisKK3ZvaWQgSUZYX0VkaXQ6OkRyYXdFZGl0KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsIElGWF9FZGl0KiBwRWRpdCwgRlhfQ09MT1JSRUYgY3JUZXh0RmlsbCwgRlhfQ09MT1JSRUYgY3JUZXh0U3Ryb2tlLCAKKwkJCQkJCWNvbnN0IENQREZfUmVjdCYgcmNDbGlwLCBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSwgSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyLCB2b2lkKiBwRkZMRGF0YSkKK3sKKwkKKwlGWF9CT09MIGJDb250aW51b3VzID0gcEVkaXQtPkdldENoYXJBcnJheSgpID09IDA7CisJaWYgKHBFZGl0LT5HZXRDaGFyU3BhY2UoKSA+IDAuMGYpCisJCWJDb250aW51b3VzID0gRkFMU0U7CisKKwlGWF9XT1JEIFN1YldvcmQgPSBwRWRpdC0+R2V0UGFzc3dvcmRDaGFyKCk7CisJRlhfRkxPQVQgZkZvbnRTaXplID0gcEVkaXQtPkdldEZvbnRTaXplKCk7CisJQ1BWVF9Xb3JkUmFuZ2Ugd3JTZWxlY3QgPSBwRWRpdC0+R2V0U2VsZWN0V29yZFJhbmdlKCk7CisJRlhfSU5UMzIgbkhvcnpTY2FsZSA9IHBFZGl0LT5HZXRIb3J6U2NhbGUoKTsKKworCUZYX0NPTE9SUkVGIGNyQ3VyRmlsbCA9IGNyVGV4dEZpbGw7CisJRlhfQ09MT1JSRUYgY3JPbGRGaWxsID0gY3JDdXJGaWxsOworCisJRlhfQk9PTCBiU2VsZWN0ID0gRkFMU0U7CisJY29uc3QgRlhfQ09MT1JSRUYgY3JXaGl0ZSA9IEFyZ2JFbmNvZGUoMjU1LDI1NSwyNTUsMjU1KTsKKwljb25zdCBGWF9DT0xPUlJFRiBjclNlbEJLID0gQXJnYkVuY29kZSgyNTUsMCw1MSwxMTMpOworCisJQ0ZYX0J5dGVUZXh0QnVmIHNUZXh0QnVmOworCUZYX0lOVDMyIG5Gb250SW5kZXggPSAtMTsKKwlDUERGX1BvaW50IHB0QlQoMC4wZiwwLjBmKTsKKworCXBEZXZpY2UtPlNhdmVTdGF0ZSgpOworCisJaWYgKCFyY0NsaXAuSXNFbXB0eSgpKQorCXsKKwkJQ1BERl9SZWN0IHJjVGVtcCA9IHJjQ2xpcDsKKwkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm1SZWN0KHJjVGVtcCk7CisJCUZYX1JFQ1QgcmNEZXZDbGlwOworCQlyY0RldkNsaXAubGVmdCA9IChGWF9JTlQzMilyY1RlbXAubGVmdDsKKwkJcmNEZXZDbGlwLnJpZ2h0ID0gKEZYX0lOVDMyKXJjVGVtcC5yaWdodDsKKwkJcmNEZXZDbGlwLnRvcCA9IChGWF9JTlQzMilyY1RlbXAudG9wOworCQlyY0RldkNsaXAuYm90dG9tID0gKEZYX0lOVDMyKXJjVGVtcC5ib3R0b207CisJCXBEZXZpY2UtPlNldENsaXBfUmVjdCgmcmNEZXZDbGlwKTsKKwl9CisKKwlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQorCXsKKwkJaWYgKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwID0gcEVkaXQtPkdldEZvbnRNYXAoKSkKKwkJeworCQkJaWYgKHBSYW5nZSkKKwkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOworCQkJZWxzZQorCQkJCXBJdGVyYXRvci0+U2V0QXQoMCk7CisKKwkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlOwkJCQorCisJCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQorCQkJeworCQkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsKKworCQkJCWlmICh3clNlbGVjdC5Jc0V4aXN0KCkpCisJCQkJeworCQkJCQliU2VsZWN0ID0gcGxhY2UuV29yZENtcCh3clNlbGVjdC5CZWdpblBvcykgPiAwICYmIHBsYWNlLldvcmRDbXAod3JTZWxlY3QuRW5kUG9zKSA8PSAwOworCQkJCQlpZiAoYlNlbGVjdCkKKwkJCQkJewkJCQkJCQorCQkJCQkJY3JDdXJGaWxsID0gY3JXaGl0ZTsJCQkJCQkKKwkJCQkJfQorCQkJCQllbHNlCisJCQkJCXsKKwkJCQkJCWNyQ3VyRmlsbCA9IGNyVGV4dEZpbGw7CisJCQkJCX0KKwkJCQl9CisJCQkJaWYocFN5c3RlbUhhbmRsZXIgJiYgcFN5c3RlbUhhbmRsZXItPklzU2VsZWN0aW9uSW1wbGVtZW50ZWQoKSkJCisJCQkJeworCQkJCQljckN1ckZpbGwgPSBjclRleHRGaWxsOworIAkJCQkJY3JPbGRGaWxsID0gY3JDdXJGaWxsOworCQkJCX0KKwkJCQlDUFZUX1dvcmQgd29yZDsJCQkJCisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisKKwkJCQkJaWYgKGJTZWxlY3QpCisJCQkJCXsKKwkJCQkJCQorCQkJCQkJQ1BWVF9MaW5lIGxpbmU7CisJCQkJCQlwSXRlcmF0b3ItPkdldExpbmUobGluZSk7CisKKwkJCQkJCWlmKHBTeXN0ZW1IYW5kbGVyICYmIHBTeXN0ZW1IYW5kbGVyLT5Jc1NlbGVjdGlvbkltcGxlbWVudGVkKCkpCisJCQkJCQl7CisJCQkJCQkJQ1BERl9SZWN0IHJjKHdvcmQucHRXb3JkLngsbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVEZXNjZW50LAorCQkJCQkJCQl3b3JkLnB0V29yZC54K3dvcmQuZldpZHRoLGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lQXNjZW50KTsKKwkJCQkJCQlyYy5JbnRlcnNlY3QocmNDbGlwKTsKKwkJCQkJCQkvL0NGWF9FZGl0KiBwRXQgPSAoQ0ZYX0VkaXQqKXBFZGl0OworCQkJCQkJCS8vQ1BERl9SZWN0IHJjRWRpdCA9IHBFdC0+VlRUb0VkaXQocmMpOworCQkJCQkJCXBTeXN0ZW1IYW5kbGVyLT5PdXRwdXRTZWxlY3RlZFJlY3QocEZGTERhdGEscmMpOworCQkJCQkJfQorCQkJCQkJZWxzZQorCQkJCQkJewkKKyAJCQkJCQkJQ0ZYX1BhdGhEYXRhIHBhdGhTZWxCSzsKKyAJCQkJCQkJcGF0aFNlbEJLLkFwcGVuZFJlY3Qod29yZC5wdFdvcmQueCxsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZURlc2NlbnQsCisgCQkJCQkJCQl3b3JkLnB0V29yZC54K3dvcmQuZldpZHRoLGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lQXNjZW50KTsKKyAJCQkJCQkJCisgCQkJCQkJCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoU2VsQkssIHBVc2VyMkRldmljZSwgTlVMTCwgY3JTZWxCSywgMCwgRlhGSUxMX1dJTkRJTkcpOwkKKwkJCQkJCX0KKwkJCQkJfQorCisJCQkJCWlmIChiQ29udGludW91cykKKwkJCQkJeworCQkJCQkJaWYgKHBsYWNlLkxpbmVDbXAob2xkcGxhY2UpICE9IDAgfHwgd29yZC5uRm9udEluZGV4ICE9IG5Gb250SW5kZXggfHwgCisJCQkJCQkJY3JPbGRGaWxsICE9IGNyQ3VyRmlsbCkKKwkJCQkJCXsKKwkJCQkJCQlpZiAoc1RleHRCdWYuR2V0TGVuZ3RoKCkgPiAwKQorCQkJCQkJCXsJCQkJCQkJCQorCQkJCQkJCQlEcmF3VGV4dFN0cmluZyhwRGV2aWNlLCBDUERGX1BvaW50KHB0QlQueCtwdE9mZnNldC54LCBwdEJULnkrcHRPZmZzZXQueSksIHBGb250TWFwLT5HZXRQREZGb250KG5Gb250SW5kZXgpLAorCQkJCQkJCQkJZkZvbnRTaXplLCBwVXNlcjJEZXZpY2UsIHNUZXh0QnVmLkdldEJ5dGVTdHJpbmcoKSwgY3JPbGRGaWxsLCBjclRleHRTdHJva2UsIG5Ib3J6U2NhbGUpOworCisJCQkJCQkJCXNUZXh0QnVmLkNsZWFyKCk7CisJCQkJCQkJfQorCQkJCQkJCW5Gb250SW5kZXggPSB3b3JkLm5Gb250SW5kZXg7CisJCQkJCQkJcHRCVCA9IHdvcmQucHRXb3JkOworCQkJCQkJCWNyT2xkRmlsbCA9IGNyQ3VyRmlsbDsKKwkJCQkJCX0KKworCQkJCQkJc1RleHRCdWYgPDwgR2V0UERGV29yZFN0cmluZyhwRm9udE1hcCwgd29yZC5uRm9udEluZGV4LCB3b3JkLldvcmQsIFN1YldvcmQpOwkJCQkJCQorCQkJCQl9CisJCQkJCWVsc2UKKwkJCQkJeworCQkJCQkJRHJhd1RleHRTdHJpbmcocERldmljZSxDUERGX1BvaW50KHdvcmQucHRXb3JkLngrcHRPZmZzZXQueCwgd29yZC5wdFdvcmQueStwdE9mZnNldC55KSwgcEZvbnRNYXAtPkdldFBERkZvbnQod29yZC5uRm9udEluZGV4KSwKKwkJCQkJCQlmRm9udFNpemUsIHBVc2VyMkRldmljZSwgR2V0UERGV29yZFN0cmluZyhwRm9udE1hcCwgd29yZC5uRm9udEluZGV4LCB3b3JkLldvcmQsIFN1YldvcmQpLCBjckN1ckZpbGwsIGNyVGV4dFN0cm9rZSwgbkhvcnpTY2FsZSk7CisKKwkJCQkJfQorCQkJCQlvbGRwbGFjZSA9IHBsYWNlOworCisKKwkJCQl9CisJCQl9CisKKwkJCWlmIChzVGV4dEJ1Zi5HZXRMZW5ndGgoKSA+IDApCisJCQl7CQkJCQorCQkJCURyYXdUZXh0U3RyaW5nKHBEZXZpY2UsIENQREZfUG9pbnQocHRCVC54K3B0T2Zmc2V0LngsIHB0QlQueStwdE9mZnNldC55KSwgcEZvbnRNYXAtPkdldFBERkZvbnQobkZvbnRJbmRleCksCisJCQkJCWZGb250U2l6ZSwgcFVzZXIyRGV2aWNlLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCksIGNyT2xkRmlsbCwgY3JUZXh0U3Ryb2tlLCBuSG9yelNjYWxlKTsKKwkJCX0JCQkKKwkJfQorCX0KKwkKKwlwRGV2aWNlLT5SZXN0b3JlU3RhdGUoKTsKK30KKwordm9pZCBJRlhfRWRpdDo6RHJhd1JpY2hFZGl0KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsIElGWF9FZGl0KiBwRWRpdCwgIAorCQkJCQkJY29uc3QgQ1BERl9SZWN0JiByY0NsaXAsIGNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlKQoreworCS8vRlhfRkxPQVQgZkZvbnRTaXplID0gcEVkaXQtPkdldEZvbnRTaXplKCk7CisJQ1BWVF9Xb3JkUmFuZ2Ugd3JTZWxlY3QgPSBwRWRpdC0+R2V0U2VsZWN0V29yZFJhbmdlKCk7CisKKwlGWF9DT0xPUlJFRiBjckN1clRleHQgPSBBcmdiRW5jb2RlKDI1NSwgMCwwLDApOworCUZYX0NPTE9SUkVGIGNyT2xkID0gY3JDdXJUZXh0OworCUZYX0JPT0wgYlNlbGVjdCA9IEZBTFNFOworCWNvbnN0IEZYX0NPTE9SUkVGIGNyV2hpdGUgPSBBcmdiRW5jb2RlKDI1NSwyNTUsMjU1LDI1NSk7CisJY29uc3QgRlhfQ09MT1JSRUYgY3JTZWxCSyA9IEFyZ2JFbmNvZGUoMjU1LDAsNTEsMTEzKTsKKworCUNGWF9CeXRlVGV4dEJ1ZiBzVGV4dEJ1ZjsKKwlDUFZUX1dvcmRQcm9wcyB3cDsKKwlDUERGX1BvaW50IHB0QlQoMC4wZiwwLjBmKTsKKworCXBEZXZpY2UtPlNhdmVTdGF0ZSgpOworCisJaWYgKCFyY0NsaXAuSXNFbXB0eSgpKQorCXsKKwkJQ1BERl9SZWN0IHJjVGVtcCA9IHJjQ2xpcDsKKwkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm1SZWN0KHJjVGVtcCk7CisJCUZYX1JFQ1QgcmNEZXZDbGlwOworCQlyY0RldkNsaXAubGVmdCA9IChGWF9JTlQzMilyY1RlbXAubGVmdDsKKwkJcmNEZXZDbGlwLnJpZ2h0ID0gKEZYX0lOVDMyKXJjVGVtcC5yaWdodDsKKwkJcmNEZXZDbGlwLnRvcCA9IChGWF9JTlQzMilyY1RlbXAudG9wOworCQlyY0RldkNsaXAuYm90dG9tID0gKEZYX0lOVDMyKXJjVGVtcC5ib3R0b207CisJCXBEZXZpY2UtPlNldENsaXBfUmVjdCgmcmNEZXZDbGlwKTsKKwl9CisKKwlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQorCXsKKwkJaWYgKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwID0gcEVkaXQtPkdldEZvbnRNYXAoKSkKKwkJeworCQkJaWYgKHBSYW5nZSkKKwkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOworCQkJZWxzZQorCQkJCXBJdGVyYXRvci0+U2V0QXQoMCk7CisKKwkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlOwkJCQorCisJCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQorCQkJeworCQkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsKKwkJCQkKKwkJCQlDUFZUX1dvcmQgd29yZDsJCQkJCisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCXdvcmQuV29yZFByb3BzLmZGb250U2l6ZSA9IHdvcmQuZkZvbnRTaXplOworCisJCQkJCWNyQ3VyVGV4dCA9IEFyZ2JFbmNvZGUoMjU1LHdvcmQuV29yZFByb3BzLmR3V29yZENvbG9yKTsKKworCQkJCQlpZiAod3JTZWxlY3QuSXNFeGlzdCgpKQorCQkJCQl7CisJCQkJCQliU2VsZWN0ID0gcGxhY2UuV29yZENtcCh3clNlbGVjdC5CZWdpblBvcykgPiAwICYmIHBsYWNlLldvcmRDbXAod3JTZWxlY3QuRW5kUG9zKSA8PSAwOworCQkJCQkJaWYgKGJTZWxlY3QpCisJCQkJCQl7CQkJCQkJCisJCQkJCQkJY3JDdXJUZXh0ID0gY3JXaGl0ZTsKKwkJCQkJCX0KKwkJCQkJfQorCisJCQkJCWlmIChiU2VsZWN0KQorCQkJCQl7CisJCQkJCQlDUFZUX0xpbmUgbGluZTsKKwkJCQkJCXBJdGVyYXRvci0+R2V0TGluZShsaW5lKTsKKworCQkJCQkJQ0ZYX1BhdGhEYXRhIHBhdGhTZWxCSzsKKwkJCQkJCXBhdGhTZWxCSy5BcHBlbmRSZWN0KHdvcmQucHRXb3JkLngJCSsgcHRPZmZzZXQueCwKKwkJCQkJCQlsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZURlc2NlbnQJKyBwdE9mZnNldC55LAorCQkJCQkJCXdvcmQucHRXb3JkLngrd29yZC5mV2lkdGgJCQkrIHB0T2Zmc2V0LngsCisJCQkJCQkJbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVBc2NlbnQJKyBwdE9mZnNldC55KTsKKworCQkJCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGhTZWxCSywgcFVzZXIyRGV2aWNlLCBOVUxMLCBjclNlbEJLLCAwLCBGWEZJTExfV0lORElORyk7CQkJCQkJCQkJCQkJCisJCQkJCX0KKworCQkJCQlpZiAocGxhY2UuTGluZUNtcChvbGRwbGFjZSkgIT0gMCB8fCB3b3JkLldvcmRQcm9wcy5mQ2hhclNwYWNlID4gMC4wZiB8fCB3b3JkLldvcmRQcm9wcy5uSG9yelNjYWxlICE9IDEwMCB8fCAKKwkJCQkJCUZYU1lTX21lbWNtcCgmd29yZC5Xb3JkUHJvcHMsICZ3cCwgc2l6ZW9mKENQVlRfV29yZFByb3BzKSkgIT0gMCB8fCAKKwkJCQkJCWNyT2xkICE9IGNyQ3VyVGV4dCkKKwkJCQkJeworCQkJCQkJaWYgKHNUZXh0QnVmLkdldExlbmd0aCgpID4gMCkKKwkJCQkJCXsJCQkJCQkJCQorCQkJCQkJCURyYXdUZXh0U3RyaW5nKHBEZXZpY2UsIENQREZfUG9pbnQocHRCVC54K3B0T2Zmc2V0LngsIHB0QlQueStwdE9mZnNldC55KSwgcEZvbnRNYXAtPkdldFBERkZvbnQod3AubkZvbnRJbmRleCksCisJCQkJCQkJCXdwLmZGb250U2l6ZSwgcFVzZXIyRGV2aWNlLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCksIGNyT2xkLCAwLCB3cC5uSG9yelNjYWxlKTsKKworCQkJCQkJCXNUZXh0QnVmLkNsZWFyKCk7CisJCQkJCQl9CisJCQkJCQl3cCA9IHdvcmQuV29yZFByb3BzOworCQkJCQkJcHRCVCA9IHdvcmQucHRXb3JkOworCQkJCQkJY3JPbGQgPSBjckN1clRleHQ7CisJCQkJCX0KKworCQkJCQlzVGV4dEJ1ZiA8PCBHZXRQREZXb3JkU3RyaW5nKHBGb250TWFwLCB3b3JkLldvcmRQcm9wcy5uRm9udEluZGV4LCB3b3JkLldvcmQsIDApOwkKKwkJCQkJCisJCQkJCWlmICh3b3JkLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9VTkRFUkxJTkUpCisJCQkJCXsKKwkJCQkJCUNGWF9QYXRoRGF0YSBwYXRoVW5kZXJsaW5lOworCQkJCQkJQ1BERl9SZWN0IHJjVW5kZXJsaW5lID0gR2V0VW5kZXJMaW5lUmVjdCh3b3JkKTsKKwkJCQkJCXBhdGhVbmRlcmxpbmUuQXBwZW5kUmVjdChyY1VuZGVybGluZS5sZWZ0LCByY1VuZGVybGluZS5ib3R0b20sIHJjVW5kZXJsaW5lLnJpZ2h0LCByY1VuZGVybGluZS50b3ApOworCisJCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aFVuZGVybGluZSwgcFVzZXIyRGV2aWNlLCBOVUxMLCBjckN1clRleHQsIDAsIEZYRklMTF9XSU5ESU5HKTsJCisJCQkJCX0KKworCQkJCQlpZiAod29yZC5Xb3JkUHJvcHMubldvcmRTdHlsZSAmIFBWVFdPUkRfU1RZTEVfQ1JPU1NPVVQpCisJCQkJCXsKKwkJCQkJCUNGWF9QYXRoRGF0YSBwYXRoQ3Jvc3NvdXQ7CisJCQkJCQlDUERGX1JlY3QgcmNDcm9zc291dCA9IEdldENyb3Nzb3V0UmVjdCh3b3JkKTsKKwkJCQkJCXBhdGhDcm9zc291dC5BcHBlbmRSZWN0KHJjQ3Jvc3NvdXQubGVmdCwgcmNDcm9zc291dC5ib3R0b20sIHJjQ3Jvc3NvdXQucmlnaHQsIHJjQ3Jvc3NvdXQudG9wKTsKKworCQkJCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGhDcm9zc291dCwgcFVzZXIyRGV2aWNlLCBOVUxMLCBjckN1clRleHQsIDAsIEZYRklMTF9XSU5ESU5HKTsKKwkJCQkJfQorCisJCQkJCW9sZHBsYWNlID0gcGxhY2U7CQkJCQkKKwkJCQl9CisJCQl9CisKKwkJCWlmIChzVGV4dEJ1Zi5HZXRMZW5ndGgoKSA+IDApCisJCQl7CQkJCQorCQkJCURyYXdUZXh0U3RyaW5nKHBEZXZpY2UsIENQREZfUG9pbnQocHRCVC54K3B0T2Zmc2V0LngsIHB0QlQueStwdE9mZnNldC55KSwgcEZvbnRNYXAtPkdldFBERkZvbnQod3AubkZvbnRJbmRleCksCisJCQkJCXdwLmZGb250U2l6ZSwgcFVzZXIyRGV2aWNlLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCksIGNyT2xkLCAwLCB3cC5uSG9yelNjYWxlKTsKKwkJCX0KKwkJfQorCX0KKwkKKwlwRGV2aWNlLT5SZXN0b3JlU3RhdGUoKTsKK30KKworc3RhdGljIHZvaWQgQWRkTGluZVRvUGFnZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmpzLCBGWF9DT0xPUlJFRiBjclN0cm9rZSwgCisJCQkJCQkJCSBjb25zdCBDUERGX1BvaW50JiBwdDEsIGNvbnN0IENQREZfUG9pbnQmIHB0MikKK3sKKwlDUERGX1BhdGhPYmplY3QqIHBQYXRoT2JqID0gbmV3IENQREZfUGF0aE9iamVjdDsKKwlDUERGX1BhdGhEYXRhKiBwUGF0aERhdGEgPSBwUGF0aE9iai0+bV9QYXRoLkdldE1vZGlmeSgpOworCisJcFBhdGhEYXRhLT5TZXRQb2ludENvdW50KDIpOworCXBQYXRoRGF0YS0+U2V0UG9pbnQoMCwgcHQxLngsIHB0MS55LCBGWFBUX01PVkVUTyk7CisJcFBhdGhEYXRhLT5TZXRQb2ludCgxLCBwdDIueCwgcHQyLnksIEZYUFRfTElORVRPKTsKKworCUZYX0ZMT0FUIHJnYlszXTsKKwlyZ2JbMF0gPSBGWEFSR0JfUihjclN0cm9rZSkgLyAyNTUuMGY7CisJcmdiWzFdID0gRlhBUkdCX0coY3JTdHJva2UpIC8gMjU1LjBmOworCXJnYlsyXSA9IEZYQVJHQl9CKGNyU3Ryb2tlKSAvIDI1NS4wZjsKKwlwUGF0aE9iai0+bV9Db2xvclN0YXRlLlNldFN0cm9rZUNvbG9yKENQREZfQ29sb3JTcGFjZTo6R2V0U3RvY2tDUyhQREZDU19ERVZJQ0VSR0IpLCByZ2IsIDMpOworCisJQ0ZYX0dyYXBoU3RhdGVEYXRhKiBwRGF0YSA9IHBQYXRoT2JqLT5tX0dyYXBoU3RhdGUuR2V0TW9kaWZ5KCk7CisJcERhdGEtPm1fTGluZVdpZHRoID0gMTsKKworCXBQYWdlT2Jqcy0+SW5zZXJ0T2JqZWN0KHBQYWdlT2Jqcy0+R2V0TGFzdE9iamVjdFBvc2l0aW9uKCkscFBhdGhPYmopOworfQorCitzdGF0aWMgdm9pZCBBZGRSZWN0VG9QYWdlT2JqZWN0cyhDUERGX1BhZ2VPYmplY3RzKiBwUGFnZU9ianMsIEZYX0NPTE9SUkVGIGNyRmlsbCwgY29uc3QgQ1BERl9SZWN0JiByY0ZpbGwpCit7CisJQ1BERl9QYXRoT2JqZWN0KiBwUGF0aE9iaiA9IG5ldyBDUERGX1BhdGhPYmplY3Q7CisJQ1BERl9QYXRoRGF0YSogcFBhdGhEYXRhID0gcFBhdGhPYmotPm1fUGF0aC5HZXRNb2RpZnkoKTsKKwlwUGF0aERhdGEtPkFwcGVuZFJlY3QocmNGaWxsLmxlZnQscmNGaWxsLmJvdHRvbSxyY0ZpbGwucmlnaHQscmNGaWxsLnRvcCk7CQorCQorCUZYX0ZMT0FUIHJnYlszXTsKKwlyZ2JbMF0gPSBGWEFSR0JfUihjckZpbGwpIC8gMjU1LjBmIDsKKwlyZ2JbMV0gPSBGWEFSR0JfRyhjckZpbGwpIC8gMjU1LjBmOworCXJnYlsyXSA9IEZYQVJHQl9CKGNyRmlsbCkgLyAyNTUuMGY7CisJcFBhdGhPYmotPm1fQ29sb3JTdGF0ZS5TZXRGaWxsQ29sb3IoQ1BERl9Db2xvclNwYWNlOjpHZXRTdG9ja0NTKFBERkNTX0RFVklDRVJHQiksIHJnYiwgMyk7CisKKwlwUGF0aE9iai0+bV9GaWxsVHlwZSA9IEZYRklMTF9BTFRFUk5BVEU7CisJcFBhdGhPYmotPm1fYlN0cm9rZSA9IEZBTFNFOworCisJcFBhZ2VPYmpzLT5JbnNlcnRPYmplY3QocFBhZ2VPYmpzLT5HZXRMYXN0T2JqZWN0UG9zaXRpb24oKSxwUGF0aE9iaik7Cit9CisKK3N0YXRpYyBDUERGX1RleHRPYmplY3QqIEFkZFRleHRPYmpUb1BhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqcywgRlhfQ09MT1JSRUYgY3JUZXh0LCAKKwkJCQkJCQkgQ1BERl9Gb250KiBwRm9udCwgRlhfRkxPQVQgZkZvbnRTaXplLCBGWF9GTE9BVCBmQ2hhclNwYWNlLCBGWF9JTlQzMiBuSG9yelNjYWxlLCAKKwkJCQkJCQkgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiB0ZXh0KQoreworCUNQREZfVGV4dE9iamVjdCogcFR4dE9iaiA9IG5ldyBDUERGX1RleHRPYmplY3Q7CisJCQkKKwlDUERGX1RleHRTdGF0ZURhdGEqIHBUZXh0U3RhdGVEYXRhID0gcFR4dE9iai0+bV9UZXh0U3RhdGUuR2V0TW9kaWZ5KCk7CisJcFRleHRTdGF0ZURhdGEtPm1fcEZvbnQgPSBwRm9udDsKKwlwVGV4dFN0YXRlRGF0YS0+bV9Gb250U2l6ZSA9IGZGb250U2l6ZTsKKwlwVGV4dFN0YXRlRGF0YS0+bV9DaGFyU3BhY2UgPSBmQ2hhclNwYWNlOworCXBUZXh0U3RhdGVEYXRhLT5tX1dvcmRTcGFjZSA9IDA7CisJcFRleHRTdGF0ZURhdGEtPm1fVGV4dE1vZGUgID0gMDsKKwlwVGV4dFN0YXRlRGF0YS0+bV9NYXRyaXhbMF0gPSBuSG9yelNjYWxlIC8gMTAwLjBmOworCXBUZXh0U3RhdGVEYXRhLT5tX01hdHJpeFsxXSA9IDA7CisJcFRleHRTdGF0ZURhdGEtPm1fTWF0cml4WzJdID0gMDsKKwlwVGV4dFN0YXRlRGF0YS0+bV9NYXRyaXhbM10gPSAxOworCisJRlhfRkxPQVQgcmdiWzNdOworCXJnYlswXSA9IEZYQVJHQl9SKGNyVGV4dCkgLyAyNTUuMGYgOworCXJnYlsxXSA9IEZYQVJHQl9HKGNyVGV4dCkgLyAyNTUuMGY7CisJcmdiWzJdID0gRlhBUkdCX0IoY3JUZXh0KSAvIDI1NS4wZjsKKwlwVHh0T2JqLT5tX0NvbG9yU3RhdGUuU2V0RmlsbENvbG9yKENQREZfQ29sb3JTcGFjZTo6R2V0U3RvY2tDUyhQREZDU19ERVZJQ0VSR0IpLHJnYiwgMyk7CisJcFR4dE9iai0+bV9Db2xvclN0YXRlLlNldFN0cm9rZUNvbG9yKENQREZfQ29sb3JTcGFjZTo6R2V0U3RvY2tDUyhQREZDU19ERVZJQ0VSR0IpLHJnYiwgMyk7CisKKwlwVHh0T2JqLT5TZXRQb3NpdGlvbihwb2ludC54LHBvaW50LnkpOworCXBUeHRPYmotPlNldFRleHQodGV4dCk7CQorCisJcFBhZ2VPYmpzLT5JbnNlcnRPYmplY3QocFBhZ2VPYmpzLT5HZXRMYXN0T2JqZWN0UG9zaXRpb24oKSxwVHh0T2JqKTsKKworCXJldHVybiBwVHh0T2JqOworfQorCisvKgorTGlzdCBvZiBjdXJyZW50bHkgc3VwcG9ydGVkIHN0YW5kYXJkIGZvbnRzOgorQ291cmllciwgQ291cmllci1Cb2xkLCBDb3VyaWVyLUJvbGRPYmxpcXVlLCBDb3VyaWVyLU9ibGlxdWUKK0hlbHZldGljYSwgSGVsdmV0aWNhLUJvbGQsIEhlbHZldGljYS1Cb2xkT2JsaXF1ZSwgSGVsdmV0aWNhLU9ibGlxdWUKK1RpbWVzLVJvbWFuLCBUaW1lcy1Cb2xkLCBUaW1lcy1JdGFsaWMsIFRpbWVzLUJvbGRJdGFsaWMKK1N5bWJvbCwgWmFwZkRpbmdiYXRzCisqLworCitjb25zdCBjaGFyKiBnX3NGWEVESVRTdGFuZGFyZEZvbnROYW1lW10gPSB7IkNvdXJpZXIiLCAiQ291cmllci1Cb2xkIiwgIkNvdXJpZXItQm9sZE9ibGlxdWUiLCAiQ291cmllci1PYmxpcXVlIiwKKwkiSGVsdmV0aWNhIiwgIkhlbHZldGljYS1Cb2xkIiwgIkhlbHZldGljYS1Cb2xkT2JsaXF1ZSIsICJIZWx2ZXRpY2EtT2JsaXF1ZSIsCisJIlRpbWVzLVJvbWFuIiwgIlRpbWVzLUJvbGQiLCAiVGltZXMtSXRhbGljIiwgIlRpbWVzLUJvbGRJdGFsaWMiLAorCSJTeW1ib2wiLCAiWmFwZkRpbmdiYXRzIn07CisKK3N0YXRpYyBGWF9CT09MIEZYX0VESVRfSXNTdGFuZGFyZEZvbnQoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSkKK3sKKwlmb3IgKEZYX0lOVDMyIGk9MDsgaTwxNDsgaSsrKQorCXsKKwkJaWYgKHNGb250TmFtZSA9PSBnX3NGWEVESVRTdGFuZGFyZEZvbnROYW1lW2ldKQorCQkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIElGWF9FZGl0OjpHZW5lcmF0ZVBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgSUZYX0VkaXQqIHBFZGl0LAorCQkJCQkJCQkgICBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSwgRlhfQ09MT1JSRUYgY3JUZXh0LCBDRlhfQXJyYXlUZW1wbGF0ZTxDUERGX1RleHRPYmplY3QqPiYgT2JqQXJyYXkpCit7CisJRlhfRkxPQVQgZkZvbnRTaXplID0gcEVkaXQtPkdldEZvbnRTaXplKCk7CisKKwlGWF9JTlQzMiBuT2xkRm9udEluZGV4ID0gLTE7CisKKwlDRlhfQnl0ZVRleHRCdWYgc1RleHRCdWY7CisJQ1BERl9Qb2ludCBwdEJUKDAuMGYsMC4wZik7CisKKwlPYmpBcnJheS5SZW1vdmVBbGwoKTsKKworCWlmIChJRlhfRWRpdF9JdGVyYXRvciogcEl0ZXJhdG9yID0gcEVkaXQtPkdldEl0ZXJhdG9yKCkpCisJeworCQlpZiAoSUZYX0VkaXRfRm9udE1hcCogcEZvbnRNYXAgPSBwRWRpdC0+R2V0Rm9udE1hcCgpKQorCQl7CisJCQlpZiAocFJhbmdlKQorCQkJCXBJdGVyYXRvci0+U2V0QXQocFJhbmdlLT5CZWdpblBvcyk7CisJCQllbHNlCisJCQkJcEl0ZXJhdG9yLT5TZXRBdCgwKTsKKworCQkJQ1BWVF9Xb3JkUGxhY2Ugb2xkcGxhY2U7CQkJCisKKwkJCXdoaWxlIChwSXRlcmF0b3ItPk5leHRXb3JkKCkpCisJCQl7CisJCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7CisJCQkJaWYgKHBSYW5nZSAmJiBwbGFjZS5Xb3JkQ21wKHBSYW5nZS0+RW5kUG9zKSA+IDApIGJyZWFrOworCQkJCQorCQkJCUNQVlRfV29yZCB3b3JkOwkJCQkKKwkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQorCQkJCXsKKwkJCQkJaWYgKHBsYWNlLkxpbmVDbXAob2xkcGxhY2UpICE9IDAgfHwgbk9sZEZvbnRJbmRleCAhPSB3b3JkLm5Gb250SW5kZXgpCisJCQkJCXsKKwkJCQkJCWlmIChzVGV4dEJ1Zi5HZXRMZW5ndGgoKSA+IDApCisJCQkJCQl7CisJCQkJCQkJT2JqQXJyYXkuQWRkKEFkZFRleHRPYmpUb1BhZ2VPYmplY3RzKHBQYWdlT2JqZWN0cywgY3JUZXh0LCBwRm9udE1hcC0+R2V0UERGRm9udChuT2xkRm9udEluZGV4KSwgZkZvbnRTaXplLCAwLjBmLCAxMDAsCisJCQkJCQkJCUNQREZfUG9pbnQocHRCVC54K3B0T2Zmc2V0LngsIHB0QlQueStwdE9mZnNldC55KSwgc1RleHRCdWYuR2V0Qnl0ZVN0cmluZygpKSk7CisKKwkJCQkJCQlzVGV4dEJ1Zi5DbGVhcigpOworCQkJCQkJfQorCisJCQkJCQlwdEJUID0gd29yZC5wdFdvcmQ7CisJCQkJCQluT2xkRm9udEluZGV4ID0gd29yZC5uRm9udEluZGV4OworCQkJCQl9CisKKwkJCQkJc1RleHRCdWYgPDwgR2V0UERGV29yZFN0cmluZyhwRm9udE1hcCwgd29yZC5uRm9udEluZGV4LCB3b3JkLldvcmQsIDApOworCQkJCQlvbGRwbGFjZSA9IHBsYWNlOwkJCQkJCisJCQkJfQorCQkJfQorCisJCQlpZiAoc1RleHRCdWYuR2V0TGVuZ3RoKCkgPiAwKQorCQkJewkJCQkKKwkJCQlPYmpBcnJheS5BZGQoQWRkVGV4dE9ialRvUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBjclRleHQsIHBGb250TWFwLT5HZXRQREZGb250KG5PbGRGb250SW5kZXgpLCBmRm9udFNpemUsIDAuMGYsIDEwMCwKKwkJCQkJQ1BERl9Qb2ludChwdEJULngrcHRPZmZzZXQueCwgcHRCVC55K3B0T2Zmc2V0LnkpLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCkpKTsKKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBJRlhfRWRpdDo6R2VuZXJhdGVSaWNoUGFnZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmplY3RzLCBJRlhfRWRpdCogcEVkaXQsCisJCQkJCQkJCSAgIGNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlLCBDRlhfQXJyYXlUZW1wbGF0ZTxDUERGX1RleHRPYmplY3QqPiYgT2JqQXJyYXkpCit7CisKKworCUZYX0NPTE9SUkVGIGNyQ3VyVGV4dCA9IEFyZ2JFbmNvZGUoMjU1LCAwLCAwLCAwKTsKKwlGWF9DT0xPUlJFRiBjck9sZCA9IGNyQ3VyVGV4dDsKKworCisJQ0ZYX0J5dGVUZXh0QnVmIHNUZXh0QnVmOworCUNQVlRfV29yZFByb3BzIHdwOworCUNQREZfUG9pbnQgcHRCVCgwLjBmLDAuMGYpOworCisJT2JqQXJyYXkuUmVtb3ZlQWxsKCk7CisKKwlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQorCXsKKwkJaWYgKElGWF9FZGl0X0ZvbnRNYXAqIHBGb250TWFwID0gcEVkaXQtPkdldEZvbnRNYXAoKSkKKwkJeworCQkJaWYgKHBSYW5nZSkKKwkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOworCQkJZWxzZQorCQkJCXBJdGVyYXRvci0+U2V0QXQoMCk7CisKKwkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlOwkJCQorCisJCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQorCQkJeworCQkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsKKwkJCQkKKwkJCQlDUFZUX1dvcmQgd29yZDsJCQkJCisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCXdvcmQuV29yZFByb3BzLmZGb250U2l6ZSA9IHdvcmQuZkZvbnRTaXplOworCisJCQkJCWNyQ3VyVGV4dCA9IEFyZ2JFbmNvZGUoMjU1LHdvcmQuV29yZFByb3BzLmR3V29yZENvbG9yKTsKKworCQkJCQlpZiAocGxhY2UuTGluZUNtcChvbGRwbGFjZSkgIT0gMCB8fCB3b3JkLldvcmRQcm9wcy5mQ2hhclNwYWNlID4gMC4wZiB8fCB3b3JkLldvcmRQcm9wcy5uSG9yelNjYWxlICE9IDEwMCB8fCAKKwkJCQkJCUZYU1lTX21lbWNtcCgmd29yZC5Xb3JkUHJvcHMsICZ3cCwgc2l6ZW9mKENQVlRfV29yZFByb3BzKSkgIT0gMCB8fCAKKwkJCQkJCWNyT2xkICE9IGNyQ3VyVGV4dCkKKwkJCQkJeworCQkJCQkJaWYgKHNUZXh0QnVmLkdldExlbmd0aCgpID4gMCkKKwkJCQkJCXsKKwkJCQkJCQlPYmpBcnJheS5BZGQoQWRkVGV4dE9ialRvUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBjck9sZCwgcEZvbnRNYXAtPkdldFBERkZvbnQod3AubkZvbnRJbmRleCksIHdwLmZGb250U2l6ZSwgd3AuZkNoYXJTcGFjZSwgd3AubkhvcnpTY2FsZSwKKwkJCQkJCQkJQ1BERl9Qb2ludChwdEJULngrcHRPZmZzZXQueCwgcHRCVC55K3B0T2Zmc2V0LnkpLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCkpKTsKKworCQkJCQkJCXNUZXh0QnVmLkNsZWFyKCk7CisJCQkJCQl9CisKKwkJCQkJCXdwID0gd29yZC5Xb3JkUHJvcHM7CisJCQkJCQlwdEJUID0gd29yZC5wdFdvcmQ7CisJCQkJCQljck9sZCA9IGNyQ3VyVGV4dDsKKwkKKwkJCQkJfQorCisJCQkJCXNUZXh0QnVmIDw8IEdldFBERldvcmRTdHJpbmcocEZvbnRNYXAsIHdvcmQuV29yZFByb3BzLm5Gb250SW5kZXgsIHdvcmQuV29yZCwgMCk7CQorCQkJCQkKKwkJCQkJaWYgKHdvcmQuV29yZFByb3BzLm5Xb3JkU3R5bGUgJiBQVlRXT1JEX1NUWUxFX1VOREVSTElORSkKKwkJCQkJey8qCisJCQkJCQlBZGRMaW5lVG9QYWdlT2JqZWN0cyhwUGFnZU9iamVjdHMsIGNyQ3VyVGV4dCwgCisJCQkJCQkJQ1BERl9Qb2ludCh3b3JkLnB0V29yZC54LCB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudCAqIDAuNGYpLAorCQkJCQkJCUNQREZfUG9pbnQod29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoLCB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudCAqIDAuNGYpKTsJCQkJCQkJCisqLworCQkJCQkJQ1BERl9SZWN0IHJjVW5kZXJsaW5lID0gR2V0VW5kZXJMaW5lUmVjdCh3b3JkKTsKKwkJCQkJCXJjVW5kZXJsaW5lLmxlZnQgKz0gcHRPZmZzZXQueDsKKwkJCQkJCXJjVW5kZXJsaW5lLnJpZ2h0ICs9IHB0T2Zmc2V0Lng7CisJCQkJCQlyY1VuZGVybGluZS50b3AgKz0gcHRPZmZzZXQueTsKKwkJCQkJCXJjVW5kZXJsaW5lLmJvdHRvbSArPSBwdE9mZnNldC55OworCQkJCQkJCisJCQkJCQlBZGRSZWN0VG9QYWdlT2JqZWN0cyhwUGFnZU9iamVjdHMsIGNyQ3VyVGV4dCwgcmNVbmRlcmxpbmUpOwkJCQkJCQkKKwkJCQkJfQorCisJCQkJCWlmICh3b3JkLldvcmRQcm9wcy5uV29yZFN0eWxlICYgUFZUV09SRF9TVFlMRV9DUk9TU09VVCkKKwkJCQkJeworCQkJCQkJQ1BERl9SZWN0IHJjQ3Jvc3NvdXQgPSBHZXRDcm9zc291dFJlY3Qod29yZCk7CisJCQkJCQlyY0Nyb3Nzb3V0LmxlZnQgKz0gcHRPZmZzZXQueDsKKwkJCQkJCXJjQ3Jvc3NvdXQucmlnaHQgKz0gcHRPZmZzZXQueDsKKwkJCQkJCXJjQ3Jvc3NvdXQudG9wICs9IHB0T2Zmc2V0Lnk7CisJCQkJCQlyY0Nyb3Nzb3V0LmJvdHRvbSArPSBwdE9mZnNldC55OworCisJCQkJCQlBZGRSZWN0VG9QYWdlT2JqZWN0cyhwUGFnZU9iamVjdHMsIGNyQ3VyVGV4dCwgcmNDcm9zc291dCk7CQkJCQkJCisJCQkJCX0KKworCQkJCQlvbGRwbGFjZSA9IHBsYWNlOwkJCQkJCisJCQkJfQorCQkJfQorCisJCQlpZiAoc1RleHRCdWYuR2V0TGVuZ3RoKCkgPiAwKQorCQkJewkJCQkKKwkJCQlPYmpBcnJheS5BZGQoQWRkVGV4dE9ialRvUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBjck9sZCwgcEZvbnRNYXAtPkdldFBERkZvbnQod3AubkZvbnRJbmRleCksIHdwLmZGb250U2l6ZSwgd3AuZkNoYXJTcGFjZSwgd3AubkhvcnpTY2FsZSwKKwkJCQkJQ1BERl9Qb2ludChwdEJULngrcHRPZmZzZXQueCwgcHRCVC55K3B0T2Zmc2V0LnkpLCBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCkpKTsKKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBJRlhfRWRpdDo6R2VuZXJhdGVVbmRlcmxpbmVPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgSUZYX0VkaXQqIHBFZGl0LAorCQkJCQkJCQkgICBjb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgY29uc3QgQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSwgRlhfQ09MT1JSRUYgY29sb3IpCit7CisKKworCWlmIChJRlhfRWRpdF9JdGVyYXRvciogcEl0ZXJhdG9yID0gcEVkaXQtPkdldEl0ZXJhdG9yKCkpCisJeworCQlpZiAocEVkaXQtPkdldEZvbnRNYXAoKSkKKwkJeworCQkJaWYgKHBSYW5nZSkKKwkJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOworCQkJZWxzZQorCQkJCXBJdGVyYXRvci0+U2V0QXQoMCk7CisKKwkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlOwkJCQorCisJCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0V29yZCgpKQorCQkJeworCQkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCQkJCWlmIChwUmFuZ2UgJiYgcGxhY2UuV29yZENtcChwUmFuZ2UtPkVuZFBvcykgPiAwKSBicmVhazsKKwkJCQkKKwkJCQlDUFZUX1dvcmQgd29yZDsJCQkJCisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCUNQREZfUmVjdCByY1VuZGVybGluZSA9IEdldFVuZGVyTGluZVJlY3Qod29yZCk7CisJCQkJCXJjVW5kZXJsaW5lLmxlZnQgKz0gcHRPZmZzZXQueDsKKwkJCQkJcmNVbmRlcmxpbmUucmlnaHQgKz0gcHRPZmZzZXQueDsKKwkJCQkJcmNVbmRlcmxpbmUudG9wICs9IHB0T2Zmc2V0Lnk7CisJCQkJCXJjVW5kZXJsaW5lLmJvdHRvbSArPSBwdE9mZnNldC55OworCQkJCQlBZGRSZWN0VG9QYWdlT2JqZWN0cyhwUGFnZU9iamVjdHMsIGNvbG9yLCByY1VuZGVybGluZSk7CisJCQkJfQorCQkJfQorCQl9CisJfQorfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0NvbnN0cy5jcHAgYi9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0NvbnN0cy5jcHAKaW5kZXggMDliOGY4ZS4uMjc4Y2Q3ZSAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9Db25zdHMuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvQ29uc3RzLmNwcApAQCAtMSwyNDcgKzEsMjQ3IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0NvbnN0cy5oIg0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBib3JkZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19Cb3JkZXIpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcocywJc29saWQpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoYiwJYmV2ZWxlZCkNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhkLAlkYXNoZWQpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoaSwJaW5zZXQpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcodSwJdW5kZXJsaW5lKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUlNUExFTUVOVF9KU19DTEFTU19DT05TVChDSlNfQm9yZGVyLGJvcmRlcikNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gZGlzcGxheSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1CRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX0Rpc3BsYXkpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIodmlzaWJsZSwJMCkNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUihoaWRkZW4sCTEpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIobm9QcmludCwJMikNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUihub1ZpZXcsCTMpDQotRU5EX0pTX1NUQVRJQ19DT05TVCgpDQotDQotSU1QTEVNRU5UX0pTX0NMQVNTX0NPTlNUKENKU19EaXNwbGF5LGRpc3BsYXkpDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvbnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19Gb250KQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKFRpbWVzLAkJVGltZXMtUm9tYW4pDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoVGltZXNCLAlUaW1lcy1Cb2xkKQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKFRpbWVzSSwJVGltZXMtSXRhbGljKQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKFRpbWVzQkksCVRpbWVzLUJvbGRJdGFsaWMpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoSGVsdiwJCUhlbHZldGljYSkNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhIZWx2QiwJCUhlbHZldGljYS1Cb2xkKQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKEhlbHZJLAkJSGVsdmV0aWNhLU9ibGlxdWUpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoSGVsdkJJLAlIZWx2ZXRpY2EtQm9sZE9ibGlxdWUpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoQ291ciwJCUNvdXJpZXIpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoQ291ckIsCQlDb3VyaWVyLUJvbGQpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoQ291ckksCQlDb3VyaWVyLU9ibGlxdWUpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoQ291ckJJLAlDb3VyaWVyLUJvbGRPYmxpcXVlKQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKFN5bWJvbCwJU3ltYm9sKQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKFphcGZELAkJWmFwZkRpbmdiYXRzKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUlNUExFTUVOVF9KU19DTEFTU19DT05TVChDSlNfRm9udCxmb250KQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBoaWdobGlnaHQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19IaWdobGlnaHQpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcobiwJbm9uZSkNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhpLAlpbnZlcnQpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcocCwJcHVzaCkNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhvLAlvdXRsaW5lKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUlNUExFTUVOVF9KU19DTEFTU19DT05TVChDSlNfSGlnaGxpZ2h0LGhpZ2hsaWdodCkNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcG9zaXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19Qb3NpdGlvbikNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUih0ZXh0T25seSwJCTApDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIoaWNvbk9ubHksCQkxKQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKGljb25UZXh0ViwJCTIpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIodGV4dEljb25WLAkJMykNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUihpY29uVGV4dEgsCQk0KQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKHRleHRJY29uSCwJCTUpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIob3ZlcmxheSwJCTYpDQotRU5EX0pTX1NUQVRJQ19DT05TVCgpDQotDQotSU1QTEVNRU5UX0pTX0NMQVNTX0NPTlNUKENKU19Qb3NpdGlvbixwb3NpdGlvbikNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gc2NhbGVIb3cgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19TY2FsZUhvdykNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUihwcm9wb3J0aW9uYWwsCTApDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIoYW5hbW9ycGhpYywJMSkNCi1FTkRfSlNfU1RBVElDX0NPTlNUKCkNCi0NCi1JTVBMRU1FTlRfSlNfQ0xBU1NfQ09OU1QoQ0pTX1NjYWxlSG93LHNjYWxlSG93KQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzY2FsZVdoZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19TY2FsZVdoZW4pDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIoYWx3YXlzLAkwKQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKG5ldmVyLAkJMSkNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUih0b29CaWcsCTIpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIodG9vU21hbGwsCTMpDQotRU5EX0pTX1NUQVRJQ19DT05TVCgpDQotDQotSU1QTEVNRU5UX0pTX0NMQVNTX0NPTlNUKENKU19TY2FsZVdoZW4sc2NhbGVXaGVuKQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzdHlsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1CRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX1N0eWxlKQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGNoLAljaGVjaykNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhjciwJY3Jvc3MpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoZGksCWRpYW1vbmQpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoY2ksCWNpcmNsZSkNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhzdCwJc3RhcikNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhzcSwJc3F1YXJlKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUlNUExFTUVOVF9KU19DTEFTU19DT05TVChDSlNfU3R5bGUsc3R5bGUpDQotDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHpvb210eXBlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19DT05TVChDSlNfWm9vbXR5cGUpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcobm9uZSwJTm9WYXJ5KQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGZpdFAsCUZpdFBhZ2UpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoZml0VywJRml0V2lkdGgpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoZml0SCwJRml0SGVpZ2h0KQ0KLQlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGZpdFYsCUZpdFZpc2libGVXaWR0aCkNCi0JSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhwcmVmLAlQcmVmZXJyZWQpDQotCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcocmVmVywJUmVmbG93V2lkdGgpDQotRU5EX0pTX1NUQVRJQ19DT05TVCgpDQotDQotSU1QTEVNRU5UX0pTX0NMQVNTX0NPTlNUKENKU19ab29tdHlwZSx6b29tdHlwZSkNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX0dsb2JhbENvbnN0cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1pbnQJQ0pTX0dsb2JhbENvbnN0czo6SW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUpDQotew0KLQlERUZJTkVfR0xPQkFMX0NPTlNUKHBSdW50aW1lLCBJRFNfR1JFQVRFUl9USEFOICwgSW52YWxpZCB2YWx1ZTogbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJXMuKTsNCi0JREVGSU5FX0dMT0JBTF9DT05TVChwUnVudGltZSwgSURTX0dUX0FORF9MVCxJbnZhbGlkIHZhbHVlOiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzLik7DQotCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19MRVNTX1RIQU4sSW52YWxpZCB2YWx1ZTogbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJXMuKTsNCi0JREVGSU5FX0dMT0JBTF9DT05TVChwUnVudGltZSwgSURTX0lOVkFMSURfTU9OVEgsKiogSW52YWxpZCAqKik7DQotCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19JTlZBTElEX0RBVEUsSW52YWxpZCBkYXRlL3RpbWU6IHBsZWFzZSBlbnN1cmUgdGhhdCB0aGUgZGF0ZS90aW1lIGV4aXN0cy4gRmllbGQpOw0KLQlERUZJTkVfR0xPQkFMX0NPTlNUKHBSdW50aW1lLCBJRFNfSU5WQUxJRF9WQUxVRSxUaGUgdmFsdWUgZW50ZXJlZCBkb2VzIG5vdCBtYXRjaCB0aGUgZm9ybWF0IG9mIHRoZSBmaWVsZCk7DQotCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19BTSxhbSk7DQotCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19QTSxwbSk7DQotCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19NT05USF9JTkZPLEphbnVhcnlbMV1GZWJydWFyeVsyXU1hcmNoWzNdQXByaWxbNF1NYXlbNV1KdW5lWzZdSnVseVs3XUF1Z3VzdFs4XVNlcHRlbWJlcls5XU9jdG9iZXJbMTBdTm92ZW1iZXJbMTFdRGVjZW1iZXJbMTJdU2VwdFs5XUphblsxXUZlYlsyXU1hclszXUFwcls0XUp1bls2XUp1bFs3XUF1Z1s4XVNlcFs5XU9jdFsxMF1Ob3ZbMTFdRGVjWzEyXSk7DQotCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19TVEFSVFVQX0NPTlNPTEVfTVNHLCAqKiBeX14gKiopOw0KLQ0KLQlyZXR1cm4gMDsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENKU19HbG9iYWxBcnJheXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotaW50CUNKU19HbG9iYWxBcnJheXM6OkluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lKQ0KLXsNCi0Jew0KLQkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX05VTUJFUl9FTlRSWV9ET1RfU0VQIjsNCi0JCUZYX0xQQ1dTVFIgQXJyYXlDb250ZW50W10gPSB7KEZYX0xQQ1dTVFIpTCJbKy1dP1xcZCpcXC4/XFxkKiJ9Ow0KLQkJREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSk7DQotCX0NCi0NCi0Jew0KLQkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX05VTUJFUl9DT01NSVRfRE9UX1NFUCI7DQotCQlGWF9MUENXU1RSIEFycmF5Q29udGVudFtdID0geyhGWF9MUENXU1RSKUwiWystXT9cXGQrKFxcLlxcZCspPyIsICAgICAgICAgICAgICAgIC8qIC0xLjAgb3IgLTEgKi8NCi0JCQkJCQkJCQkJKEZYX0xQQ1dTVFIpTCJbKy1dP1xcLlxcZCsiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAtLjEgKi8NCi0JCQkJCQkJCQkJKEZYX0xQQ1dTVFIpTCJbKy1dP1xcZCtcXC4iICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAtMS4gKi8NCi0JCQkJCQkJCQkJfTsNCi0JCURFRklORV9HTE9CQUxfQVJSQVkocFJ1bnRpbWUpOw0KLQl9DQotDQotCXsNCi0JCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9OVU1CRVJfRU5UUllfQ09NTUFfU0VQIjsNCi0JCUZYX0xQQ1dTVFIgQXJyYXlDb250ZW50W10gPSB7KEZYX0xQQ1dTVFIpTCJbKy1dP1xcZCosP1xcZCoifTsNCi0JCQ0KLQkJREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSk7DQotCX0NCi0NCi0Jew0KLQkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX05VTUJFUl9DT01NSVRfQ09NTUFfU0VQIjsNCi0JCUZYX0xQQ1dTVFIgQXJyYXlDb250ZW50W10gPSB7KEZYX0xQQ1dTVFIpTCJbKy1dP1xcZCsoWy4sXVxcZCspPyIsICAgICAgICAgICAgICAgLyogLTEsMCBvciAtMSAqLw0KLQkJCQkJCQkJCQkoRlhfTFBDV1NUUilMIlsrLV0/Wy4sXVxcZCsiLCAgICAgICAgICAgICAgICAgICAvKiAtLDEgKi8NCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEZYX0xQQ1dTVFIpTCJbKy1dP1xcZCtbLixdIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAtMSwgKi8NCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsNCi0JCURFRklORV9HTE9CQUxfQVJSQVkocFJ1bnRpbWUpOw0KLQl9DQotDQotCXsNCi0JCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9aSVBfRU5UUlkiOw0KLSAgICAgICAgRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsoRlhfTFBDV1NUUilMIlxcZHswLDV9In07DQotCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsNCi0JfQ0KLQ0KLQl7DQotCQlGWF9MUENXU1RSIEFycmF5TmFtZSA9IChGWF9MUENXU1RSKUwiUkVfWklQX0NPTU1JVCI7DQotCQlGWF9MUENXU1RSIEFycmF5Q29udGVudFtdID0geyhGWF9MUENXU1RSKUwiXFxkezV9In07DQotCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsNCi0JfQ0KLQ0KLQl7DQotCQlGWF9MUENXU1RSIEFycmF5TmFtZSA9IChGWF9MUENXU1RSKUwiUkVfWklQNF9FTlRSWSI7DQotCQlGWF9MUENXU1RSIEFycmF5Q29udGVudFtdID0geyhGWF9MUENXU1RSKUwiXFxkezAsNX0oXFwufFstIF0pP1xcZHswLDR9In07DQotCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsNCi0JfQ0KLQ0KLQl7DQotCQlGWF9MUENXU1RSIEFycmF5TmFtZSA9IChGWF9MUENXU1RSKUwiUkVfWklQNF9DT01NSVQiOw0KLQkJRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsoRlhfTFBDV1NUUilMIlxcZHs1fShcXC58Wy0gXSk/XFxkezR9In07DQotCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsNCi0JfQ0KLQ0KLQl7DQotCQlGWF9MUENXU1RSIEFycmF5TmFtZSA9IChGWF9MUENXU1RSKUwiUkVfUEhPTkVfRU5UUlkiOw0KLQkJRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsNCi0JCQkJKEZYX0xQQ1dTVFIpTCJcXGR7MCwzfShcXC58Wy0gXSk/XFxkezAsM30oXFwufFstIF0pP1xcZHswLDR9IiwJCS8qIDU1NS0xMjM0IG9yIDQwOCA1NTUtMTIzNCAqLw0KLQkJCQkoRlhfTFBDV1NUUilMIlxcKFxcZHswLDN9IiwJCQkJCQkJCQkJCS8qICg0MDggKi8NCi0JCQkJKEZYX0xQQ1dTVFIpTCJcXChcXGR7MCwzfVxcKShcXC58Wy0gXSk/XFxkezAsM30oXFwufFstIF0pP1xcZHswLDR9IiwJLyogKDQwOCkgNTU1LTEyMzQgKi8NCi0JCQkJCS8qIChhbGxvdyB0aGUgYWRkaXRpb24gb2YgcGFyZW5zIGFzIGFuIGFmdGVydGhvdWdodCkgKi8NCi0JCQkJKEZYX0xQQ1dTVFIpTCJcXChcXGR7MCwzfShcXC58Wy0gXSk/XFxkezAsM30oXFwufFstIF0pP1xcZHswLDR9IiwJLyogKDQwOCA1NTUtMTIzNCAqLw0KLQkJCQkoRlhfTFBDV1NUUilMIlxcZHswLDN9XFwpKFxcLnxbLSBdKT9cXGR7MCwzfShcXC58Wy0gXSk/XFxkezAsNH0iLAkvKiA0MDgpIDU1NS0xMjM0ICovDQotCQkJCShGWF9MUENXU1RSKUwiMDExKFxcLnxbLSBcXGRdKSoiCQkJCQkJCQkJCS8qIGludGVybmF0aW9uYWwgKi8NCi0JCQl9Ow0KLQkJREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSk7DQotCX0NCi0NCi0Jew0KLQkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX1BIT05FX0NPTU1JVCI7DQotCQlGWF9MUENXU1RSIEFycmF5Q29udGVudFtdID0gew0KLQkJCQkJKEZYX0xQQ1dTVFIpTCJcXGR7M30oXFwufFstIF0pP1xcZHs0fSIsCQkJCQkJCS8qIDU1NS0xMjM0ICovDQotCQkJCQkoRlhfTFBDV1NUUilMIlxcZHszfShcXC58Wy0gXSk/XFxkezN9KFxcLnxbLSBdKT9cXGR7NH0iLAkJCS8qIDQwOCA1NTUtMTIzNCAqLw0KLQkJCQkJKEZYX0xQQ1dTVFIpTCJcXChcXGR7M31cXCkoXFwufFstIF0pP1xcZHszfShcXC58Wy0gXSk/XFxkezR9IiwJLyogKDQwOCkgNTU1LTEyMzQgKi8NCi0JCQkJCShGWF9MUENXU1RSKUwiMDExKFxcLnxbLSBcXGRdKSoiCQkJCQkJCQkJLyogaW50ZXJuYXRpb25hbCAqLw0KLQkJCQl9Ow0KLQkJREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSk7DQotCX0NCi0NCi0Jew0KLQkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX1NTTl9FTlRSWSI7DQotCQlGWF9MUENXU1RSIEFycmF5Q29udGVudFtdID0geyhGWF9MUENXU1RSKUwiXFxkezAsM30oXFwufFstIF0pP1xcZHswLDJ9KFxcLnxbLSBdKT9cXGR7MCw0fSJ9Ow0KLQkJREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSk7DQotCX0NCi0NCi0Jew0KLQkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX1NTTl9DT01NSVQiOw0KLQkJRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsoRlhfTFBDV1NUUilMIlxcZHszfShcXC58Wy0gXSk/XFxkezJ9KFxcLnxbLSBdKT9cXGR7NH0ifTsNCi0JCURFRklORV9HTE9CQUxfQVJSQVkocFJ1bnRpbWUpOw0KLQl9DQotDQotCXJldHVybiAwOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9Db25zdHMuaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGJvcmRlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19Cb3JkZXIpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhzLAlzb2xpZCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGIsCWJldmVsZWQpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhkLAlkYXNoZWQpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhpLAlpbnNldCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKHUsCXVuZGVybGluZSkKK0VORF9KU19TVEFUSUNfQ09OU1QoKQorCitJTVBMRU1FTlRfSlNfQ0xBU1NfQ09OU1QoQ0pTX0JvcmRlcixib3JkZXIpCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBkaXNwbGF5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitCRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX0Rpc3BsYXkpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUih2aXNpYmxlLAkwKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIoaGlkZGVuLAkxKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIobm9QcmludCwJMikKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKG5vVmlldywJMykKK0VORF9KU19TVEFUSUNfQ09OU1QoKQorCitJTVBMRU1FTlRfSlNfQ0xBU1NfQ09OU1QoQ0pTX0Rpc3BsYXksZGlzcGxheSkKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGZvbnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0JFR0lOX0pTX1NUQVRJQ19DT05TVChDSlNfRm9udCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKFRpbWVzLAkJVGltZXMtUm9tYW4pCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhUaW1lc0IsCVRpbWVzLUJvbGQpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhUaW1lc0ksCVRpbWVzLUl0YWxpYykKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKFRpbWVzQkksCVRpbWVzLUJvbGRJdGFsaWMpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhIZWx2LAkJSGVsdmV0aWNhKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoSGVsdkIsCQlIZWx2ZXRpY2EtQm9sZCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKEhlbHZJLAkJSGVsdmV0aWNhLU9ibGlxdWUpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhIZWx2QkksCUhlbHZldGljYS1Cb2xkT2JsaXF1ZSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKENvdXIsCQlDb3VyaWVyKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoQ291ckIsCQlDb3VyaWVyLUJvbGQpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhDb3VySSwJCUNvdXJpZXItT2JsaXF1ZSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKENvdXJCSSwJQ291cmllci1Cb2xkT2JsaXF1ZSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKFN5bWJvbCwJU3ltYm9sKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoWmFwZkQsCQlaYXBmRGluZ2JhdHMpCitFTkRfSlNfU1RBVElDX0NPTlNUKCkKKworSU1QTEVNRU5UX0pTX0NMQVNTX0NPTlNUKENKU19Gb250LGZvbnQpCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBoaWdobGlnaHQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0JFR0lOX0pTX1NUQVRJQ19DT05TVChDSlNfSGlnaGxpZ2h0KQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcobiwJbm9uZSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGksCWludmVydCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKHAsCXB1c2gpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhvLAlvdXRsaW5lKQorRU5EX0pTX1NUQVRJQ19DT05TVCgpCisKK0lNUExFTUVOVF9KU19DTEFTU19DT05TVChDSlNfSGlnaGxpZ2h0LGhpZ2hsaWdodCkKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHBvc2l0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitCRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX1Bvc2l0aW9uKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIodGV4dE9ubHksCQkwKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIoaWNvbk9ubHksCQkxKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIoaWNvblRleHRWLAkJMikKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKHRleHRJY29uViwJCTMpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUihpY29uVGV4dEgsCQk0KQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9OVU1CRVIodGV4dEljb25ILAkJNSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKG92ZXJsYXksCQk2KQorRU5EX0pTX1NUQVRJQ19DT05TVCgpCisKK0lNUExFTUVOVF9KU19DTEFTU19DT05TVChDSlNfUG9zaXRpb24scG9zaXRpb24pCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzY2FsZUhvdyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19TY2FsZUhvdykKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKHByb3BvcnRpb25hbCwJMCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfTlVNQkVSKGFuYW1vcnBoaWMsCTEpCitFTkRfSlNfU1RBVElDX0NPTlNUKCkKKworSU1QTEVNRU5UX0pTX0NMQVNTX0NPTlNUKENKU19TY2FsZUhvdyxzY2FsZUhvdykKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHNjYWxlV2hlbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19TY2FsZVdoZW4pCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUihhbHdheXMsCTApCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUihuZXZlciwJCTEpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUih0b29CaWcsCTIpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX05VTUJFUih0b29TbWFsbCwJMykKK0VORF9KU19TVEFUSUNfQ09OU1QoKQorCitJTVBMRU1FTlRfSlNfQ0xBU1NfQ09OU1QoQ0pTX1NjYWxlV2hlbixzY2FsZVdoZW4pCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBzdHlsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19TdHlsZSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGNoLAljaGVjaykKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGNyLAljcm9zcykKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGRpLAlkaWFtb25kKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoY2ksCWNpcmNsZSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKHN0LAlzdGFyKQorCUpTX1NUQVRJQ19DT05TVF9FTlRSWV9TVFJJTkcoc3EsCXNxdWFyZSkKK0VORF9KU19TVEFUSUNfQ09OU1QoKQorCitJTVBMRU1FTlRfSlNfQ0xBU1NfQ09OU1QoQ0pTX1N0eWxlLHN0eWxlKQorCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB6b29tdHlwZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19ab29tdHlwZSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKG5vbmUsCU5vVmFyeSkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGZpdFAsCUZpdFBhZ2UpCisJSlNfU1RBVElDX0NPTlNUX0VOVFJZX1NUUklORyhmaXRXLAlGaXRXaWR0aCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGZpdEgsCUZpdEhlaWdodCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKGZpdFYsCUZpdFZpc2libGVXaWR0aCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKHByZWYsCVByZWZlcnJlZCkKKwlKU19TVEFUSUNfQ09OU1RfRU5UUllfU1RSSU5HKHJlZlcsCVJlZmxvd1dpZHRoKQorRU5EX0pTX1NUQVRJQ19DT05TVCgpCisKK0lNUExFTUVOVF9KU19DTEFTU19DT05TVChDSlNfWm9vbXR5cGUsem9vbXR5cGUpCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfR2xvYmFsQ29uc3RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitpbnQJQ0pTX0dsb2JhbENvbnN0czo6SW5pdChJSlNfUnVudGltZSogcFJ1bnRpbWUpCit7CisJREVGSU5FX0dMT0JBTF9DT05TVChwUnVudGltZSwgSURTX0dSRUFURVJfVEhBTiAsIEludmFsaWQgdmFsdWU6IG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICVzLik7CisJREVGSU5FX0dMT0JBTF9DT05TVChwUnVudGltZSwgSURTX0dUX0FORF9MVCxJbnZhbGlkIHZhbHVlOiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAlcyBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICVzLik7CisJREVGSU5FX0dMT0JBTF9DT05TVChwUnVudGltZSwgSURTX0xFU1NfVEhBTixJbnZhbGlkIHZhbHVlOiBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAlcy4pOworCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19JTlZBTElEX01PTlRILCoqIEludmFsaWQgKiopOworCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19JTlZBTElEX0RBVEUsSW52YWxpZCBkYXRlL3RpbWU6IHBsZWFzZSBlbnN1cmUgdGhhdCB0aGUgZGF0ZS90aW1lIGV4aXN0cy4gRmllbGQpOworCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19JTlZBTElEX1ZBTFVFLFRoZSB2YWx1ZSBlbnRlcmVkIGRvZXMgbm90IG1hdGNoIHRoZSBmb3JtYXQgb2YgdGhlIGZpZWxkKTsKKwlERUZJTkVfR0xPQkFMX0NPTlNUKHBSdW50aW1lLCBJRFNfQU0sYW0pOworCURFRklORV9HTE9CQUxfQ09OU1QocFJ1bnRpbWUsIElEU19QTSxwbSk7CisJREVGSU5FX0dMT0JBTF9DT05TVChwUnVudGltZSwgSURTX01PTlRIX0lORk8sSmFudWFyeVsxXUZlYnJ1YXJ5WzJdTWFyY2hbM11BcHJpbFs0XU1heVs1XUp1bmVbNl1KdWx5WzddQXVndXN0WzhdU2VwdGVtYmVyWzldT2N0b2JlclsxMF1Ob3ZlbWJlclsxMV1EZWNlbWJlclsxMl1TZXB0WzldSmFuWzFdRmViWzJdTWFyWzNdQXByWzRdSnVuWzZdSnVsWzddQXVnWzhdU2VwWzldT2N0WzEwXU5vdlsxMV1EZWNbMTJdKTsKKwlERUZJTkVfR0xPQkFMX0NPTlNUKHBSdW50aW1lLCBJRFNfU1RBUlRVUF9DT05TT0xFX01TRywgKiogXl9eICoqKTsKKworCXJldHVybiAwOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX0dsb2JhbEFycmF5cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworaW50CUNKU19HbG9iYWxBcnJheXM6OkluaXQoSUpTX1J1bnRpbWUqIHBSdW50aW1lKQoreworCXsKKwkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX05VTUJFUl9FTlRSWV9ET1RfU0VQIjsKKwkJRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsoRlhfTFBDV1NUUilMIlsrLV0/XFxkKlxcLj9cXGQqIn07CisJCURFRklORV9HTE9CQUxfQVJSQVkocFJ1bnRpbWUpOworCX0KKworCXsKKwkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX05VTUJFUl9DT01NSVRfRE9UX1NFUCI7CisJCUZYX0xQQ1dTVFIgQXJyYXlDb250ZW50W10gPSB7KEZYX0xQQ1dTVFIpTCJbKy1dP1xcZCsoXFwuXFxkKyk/IiwgICAgICAgICAgICAgICAgLyogLTEuMCBvciAtMSAqLworCQkJCQkJCQkJCShGWF9MUENXU1RSKUwiWystXT9cXC5cXGQrIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogLS4xICovCisJCQkJCQkJCQkJKEZYX0xQQ1dTVFIpTCJbKy1dP1xcZCtcXC4iICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAtMS4gKi8KKwkJCQkJCQkJCQl9OworCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsKKwl9CisKKwl7CisJCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9OVU1CRVJfRU5UUllfQ09NTUFfU0VQIjsKKwkJRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsoRlhfTFBDV1NUUilMIlsrLV0/XFxkKiw/XFxkKiJ9OworCQkKKwkJREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSk7CisJfQorCisJeworCQlGWF9MUENXU1RSIEFycmF5TmFtZSA9IChGWF9MUENXU1RSKUwiUkVfTlVNQkVSX0NPTU1JVF9DT01NQV9TRVAiOworCQlGWF9MUENXU1RSIEFycmF5Q29udGVudFtdID0geyhGWF9MUENXU1RSKUwiWystXT9cXGQrKFsuLF1cXGQrKT8iLCAgICAgICAgICAgICAgIC8qIC0xLDAgb3IgLTEgKi8KKwkJCQkJCQkJCQkoRlhfTFBDV1NUUilMIlsrLV0/Wy4sXVxcZCsiLCAgICAgICAgICAgICAgICAgICAvKiAtLDEgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRlhfTFBDV1NUUilMIlsrLV0/XFxkK1suLF0iICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIC0xLCAqLworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07CisJCURFRklORV9HTE9CQUxfQVJSQVkocFJ1bnRpbWUpOworCX0KKworCXsKKwkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX1pJUF9FTlRSWSI7CisgICAgICAgIEZYX0xQQ1dTVFIgQXJyYXlDb250ZW50W10gPSB7KEZYX0xQQ1dTVFIpTCJcXGR7MCw1fSJ9OworCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsKKwl9CisKKwl7CisJCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9aSVBfQ09NTUlUIjsKKwkJRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsoRlhfTFBDV1NUUilMIlxcZHs1fSJ9OworCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsKKwl9CisKKwl7CisJCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9aSVA0X0VOVFJZIjsKKwkJRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsoRlhfTFBDV1NUUilMIlxcZHswLDV9KFxcLnxbLSBdKT9cXGR7MCw0fSJ9OworCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsKKwl9CisKKwl7CisJCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9aSVA0X0NPTU1JVCI7CisJCUZYX0xQQ1dTVFIgQXJyYXlDb250ZW50W10gPSB7KEZYX0xQQ1dTVFIpTCJcXGR7NX0oXFwufFstIF0pP1xcZHs0fSJ9OworCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsKKwl9CisKKwl7CisJCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9QSE9ORV9FTlRSWSI7CisJCUZYX0xQQ1dTVFIgQXJyYXlDb250ZW50W10gPSB7CisJCQkJKEZYX0xQQ1dTVFIpTCJcXGR7MCwzfShcXC58Wy0gXSk/XFxkezAsM30oXFwufFstIF0pP1xcZHswLDR9IiwJCS8qIDU1NS0xMjM0IG9yIDQwOCA1NTUtMTIzNCAqLworCQkJCShGWF9MUENXU1RSKUwiXFwoXFxkezAsM30iLAkJCQkJCQkJCQkJLyogKDQwOCAqLworCQkJCShGWF9MUENXU1RSKUwiXFwoXFxkezAsM31cXCkoXFwufFstIF0pP1xcZHswLDN9KFxcLnxbLSBdKT9cXGR7MCw0fSIsCS8qICg0MDgpIDU1NS0xMjM0ICovCisJCQkJCS8qIChhbGxvdyB0aGUgYWRkaXRpb24gb2YgcGFyZW5zIGFzIGFuIGFmdGVydGhvdWdodCkgKi8KKwkJCQkoRlhfTFBDV1NUUilMIlxcKFxcZHswLDN9KFxcLnxbLSBdKT9cXGR7MCwzfShcXC58Wy0gXSk/XFxkezAsNH0iLAkvKiAoNDA4IDU1NS0xMjM0ICovCisJCQkJKEZYX0xQQ1dTVFIpTCJcXGR7MCwzfVxcKShcXC58Wy0gXSk/XFxkezAsM30oXFwufFstIF0pP1xcZHswLDR9IiwJLyogNDA4KSA1NTUtMTIzNCAqLworCQkJCShGWF9MUENXU1RSKUwiMDExKFxcLnxbLSBcXGRdKSoiCQkJCQkJCQkJCS8qIGludGVybmF0aW9uYWwgKi8KKwkJCX07CisJCURFRklORV9HTE9CQUxfQVJSQVkocFJ1bnRpbWUpOworCX0KKworCXsKKwkJRlhfTFBDV1NUUiBBcnJheU5hbWUgPSAoRlhfTFBDV1NUUilMIlJFX1BIT05FX0NPTU1JVCI7CisJCUZYX0xQQ1dTVFIgQXJyYXlDb250ZW50W10gPSB7CisJCQkJCShGWF9MUENXU1RSKUwiXFxkezN9KFxcLnxbLSBdKT9cXGR7NH0iLAkJCQkJCQkvKiA1NTUtMTIzNCAqLworCQkJCQkoRlhfTFBDV1NUUilMIlxcZHszfShcXC58Wy0gXSk/XFxkezN9KFxcLnxbLSBdKT9cXGR7NH0iLAkJCS8qIDQwOCA1NTUtMTIzNCAqLworCQkJCQkoRlhfTFBDV1NUUilMIlxcKFxcZHszfVxcKShcXC58Wy0gXSk/XFxkezN9KFxcLnxbLSBdKT9cXGR7NH0iLAkvKiAoNDA4KSA1NTUtMTIzNCAqLworCQkJCQkoRlhfTFBDV1NUUilMIjAxMShcXC58Wy0gXFxkXSkqIgkJCQkJCQkJCS8qIGludGVybmF0aW9uYWwgKi8KKwkJCQl9OworCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsKKwl9CisKKwl7CisJCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9TU05fRU5UUlkiOworCQlGWF9MUENXU1RSIEFycmF5Q29udGVudFtdID0geyhGWF9MUENXU1RSKUwiXFxkezAsM30oXFwufFstIF0pP1xcZHswLDJ9KFxcLnxbLSBdKT9cXGR7MCw0fSJ9OworCQlERUZJTkVfR0xPQkFMX0FSUkFZKHBSdW50aW1lKTsKKwl9CisKKwl7CisJCUZYX0xQQ1dTVFIgQXJyYXlOYW1lID0gKEZYX0xQQ1dTVFIpTCJSRV9TU05fQ09NTUlUIjsKKwkJRlhfTFBDV1NUUiBBcnJheUNvbnRlbnRbXSA9IHsoRlhfTFBDV1NUUilMIlxcZHszfShcXC58Wy0gXSk/XFxkezJ9KFxcLnxbLSBdKT9cXGR7NH0ifTsKKwkJREVGSU5FX0dMT0JBTF9BUlJBWShwUnVudGltZSk7CisJfQorCisJcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvRG9jdW1lbnQuY3BwIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9Eb2N1bWVudC5jcHAKaW5kZXggZWM5MzBiOC4uMGE2YWNmYSAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9Eb2N1bWVudC5jcHAKKysrIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9Eb2N1bWVudC5jcHAKQEAgLTEsMjUyNyArMSwyNTI3IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2FwcC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvRmllbGQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0ljb24uaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0ZpZWxkLmgiDQotDQotc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCXJldHVybiBwUnVudGltZS0+R2V0SXNvbGF0ZSgpOw0KLX0NCi0NCi1CRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX1ByaW50UGFyYW1zT2JqKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19QcmludFBhcmFtc09iaikNCi1FTkRfSlNfU1RBVElDX1BST1AoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19NRVRIT0QoQ0pTX1ByaW50UGFyYW1zT2JqKQ0KLUVORF9KU19TVEFUSUNfTUVUSE9EKCkNCi0NCi1JTVBMRU1FTlRfSlNfQ0xBU1MoQ0pTX1ByaW50UGFyYW1zT2JqLCBQcmludFBhcmFtc09iaikNCi0NCi1QcmludFBhcmFtc09iajo6UHJpbnRQYXJhbXNPYmooQ0pTX09iamVjdCogcEpTT2JqZWN0KQ0KLTogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCkNCi17DQotCWJVSSA9IFRSVUU7DQotCW5TdGFydCA9IDA7DQotCW5FbmQgPSAwOw0KLQliU2lsZW50ID0gRkFMU0U7DQotCWJTaHJpbmtUb0ZpdCA9IEZBTFNFOw0KLQliUHJpbnRBc0ltYWdlID0gRkFMU0U7DQotCWJSZXZlcnNlID0gRkFMU0U7DQotCWJBbm5vdGF0aW9ucyA9IFRSVUU7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRG9jdW1lbnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLSNkZWZpbmUgTUlOV0lEVEggIDUuMGYNCi0jZGVmaW5lIE1JTkhFSUdIVCA1LjBmDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19Eb2N1bWVudCkNCi1FTkRfSlNfU1RBVElDX0NPTlNUKCkNCi0NCi1CRUdJTl9KU19TVEFUSUNfUFJPUChDSlNfRG9jdW1lbnQpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKEFEQkUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGF1dGhvcikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoYmFzZVVSTCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoYm9va21hcmtSb290KQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShjYWxjdWxhdGUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKENvbGxhYikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoY3JlYXRpb25EYXRlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShjcmVhdG9yKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShkZWxheSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoZGlydHkpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGRvY3VtZW50RmlsZU5hbWUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGV4dGVybmFsKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShmaWxlc2l6ZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoaWNvbnMpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGluZm8pICAgDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGtleXdvcmRzKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShsYXlvdXQpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG1lZGlhKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShtb2REYXRlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShtb3VzZVgpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG1vdXNlWSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkobnVtRmllbGRzKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShudW1QYWdlcykNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkocGFnZU51bSkgICANCi0JSlNfU1RBVElDX1BST1BfRU5UUlkocGFnZVdpbmRvd1JlY3QpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHBhdGgpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHByb2R1Y2VyKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShzdWJqZWN0KQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWSh0aXRsZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoem9vbSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoem9vbVR5cGUpDQotRU5EX0pTX1NUQVRJQ19QUk9QKCkNCi0NCi1CRUdJTl9KU19TVEFUSUNfTUVUSE9EKENKU19Eb2N1bWVudCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShhZGRBbm5vdCwwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGFkZEZpZWxkLCA0KQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGFkZExpbmssIDApDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYWRkSWNvbiwgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShjYWxjdWxhdGVOb3csIDApDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoY2xvc2VEb2MsIDApDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoY3JlYXRlRGF0YU9iamVjdCwgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShkZWxldGVQYWdlcywgMikNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShleHBvcnRBc1RleHQsIDMpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZXhwb3J0QXNGREYsIDYpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZXhwb3J0QXNYRkRGLCA1KQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGV4dHJhY3RQYWdlcywgMykNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRBbm5vdCwgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRBbm5vdHMsIDIpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0QW5ub3QzRCwgMikNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRBbm5vdHMzRCwgMSkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRGaWVsZCwgMSkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRJY29uLCAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldExpbmtzLCAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldE50aEZpZWxkTmFtZSwgMSkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRPQ0dzLCAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldFBhZ2VCb3gsIDApDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0UGFnZU50aFdvcmQsIDMpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0UGFnZU50aFdvcmRRdWFkcywgMikNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRQYWdlTnVtV29yZHMsIDEpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0UHJpbnRQYXJhbXMsIDApDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0VVJMLCAyKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGltcG9ydEFuRkRGLCAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGltcG9ydEFuWEZERiwgMSkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShpbXBvcnRUZXh0RGF0YSwgMikNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShpbnNlcnRQYWdlcywgNCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShtYWlsRm9ybSwgNikNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShwcmludCwgOSkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShyZW1vdmVGaWVsZCwgMSkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShyZXBsYWNlUGFnZXMsIDQpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkocmVzZXRGb3JtLCAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHJlbW92ZUljb24sIDApDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoc2F2ZUFzLCA1KQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHN1Ym1pdEZvcm0sIDIzKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKG1haWxEb2MsIDApCQkNCi1FTkRfSlNfU1RBVElDX01FVEhPRCgpDQotDQotSU1QTEVNRU5UX0pTX0NMQVNTKENKU19Eb2N1bWVudCwgRG9jdW1lbnQpDQotDQotRlhfQk9PTAlDSlNfRG9jdW1lbnQ6OkluaXRJbnN0YW5jZShJRlhKU19Db250ZXh0KiBjYykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JRG9jdW1lbnQqIHBEb2MgPSAoRG9jdW1lbnQqKUdldEVtYmVkT2JqZWN0KCk7DQotCUFTU0VSVChwRG9jICE9IE5VTEwpOw0KLQkNCi0JcERvYy0+QXR0YWNoRG9jKHBDb250ZXh0LT5HZXRSZWFkZXJEb2N1bWVudCgpKTsNCi0JcERvYy0+U2V0SXNvbGF0ZShwQ29udGV4dC0+R2V0SlNSdW50aW1lKCktPkdldElzb2xhdGUoKSk7DQotCXJldHVybiBUUlVFOw0KLX07DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIERvY3VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLURvY3VtZW50OjpEb2N1bWVudChDSlNfT2JqZWN0KiBwSlNPYmplY3QpIDogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCksDQotCW1fY3dCYXNlVVJMKEwiIiksDQotCW1fcEljb25UcmVlKE5VTEwpLA0KLQltX3BEb2N1bWVudChOVUxMKSwNCi0JbV9iRGVsYXkoRkFMU0UpLA0KLQltX2lzb2xhdGUoTlVMTCkNCi17DQotfQ0KLQ0KLURvY3VtZW50Ojp+RG9jdW1lbnQoKQ0KLXsNCi0JaWYgKG1fcEljb25UcmVlKQ0KLQl7DQotCQltX3BJY29uVHJlZS0+RGVsZXRlSWNvblRyZWUoKTsNCi0JCWRlbGV0ZSBtX3BJY29uVHJlZTsNCi0JCW1fcEljb25UcmVlID0gTlVMTDsNCi0JfQ0KLQlmb3IgKGludCBpPTA7IGk8bV9EZWxheURhdGEuR2V0U2l6ZSgpOyBpKyspDQotCXsNCi0JCWlmIChDSlNfRGVsYXlEYXRhKiBwRGF0YSA9IG1fRGVsYXlEYXRhLkdldEF0KGkpKQ0KLQkJew0KLQkJCWRlbGV0ZSBwRGF0YTsNCi0JCQlwRGF0YSA9IE5VTEw7DQotCQkJbV9EZWxheURhdGEuU2V0QXQoaSwgTlVMTCk7DQotCQkJDQotCQl9DQotCX0NCi0NCi0JbV9EZWxheURhdGEuUmVtb3ZlQWxsKCk7DQotCW1fRGVsYXlBbm5vdERhdGEuUmVtb3ZlQWxsKCk7DQotfQ0KLQ0KLS8vdGhlIHRvdGFsIG51bWJlciBvZiBmaWxlZHMgaW4gZG9jdW1lbnQuDQotRlhfQk9PTCBEb2N1bWVudDo6bnVtRmllbGRzKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICghdnAuSXNHZXR0aW5nKCkpIHJldHVybiBGQUxTRTsNCi0NCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLSAgIAlDUERGU0RLX0ludGVyRm9ybSAqcEludGVyRm9ybSA9IG1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNQREZfSW50ZXJGb3JtICpwUERGRm9ybSA9IHBJbnRlckZvcm0tPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocFBERkZvcm0gIT0gTlVMTCk7DQotDQotCXZwIDw8IChpbnQpcFBERkZvcm0tPkNvdW50RmllbGRzKCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpkaXJ0eShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJaWYgKG1fcERvY3VtZW50LT5HZXRDaGFuZ2VNYXJrKCkpDQotCQkJdnAgPDwgdHJ1ZTsNCi0JCWVsc2UNCi0JCQl2cCA8PCBmYWxzZTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWJvb2wgYkNoYW5nZWQgPSBmYWxzZTsNCi0NCi0JCXZwID4+IGJDaGFuZ2VkOw0KLQ0KLQkJaWYgKGJDaGFuZ2VkKQ0KLQkJCW1fcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7DQotCQllbHNlDQotCQkJbV9wRG9jdW1lbnQtPkNsZWFyQ2hhbmdlTWFyaygpOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpBREJFKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzR2V0dGluZygpKQ0KLQl7DQotCQl2cC5TZXROdWxsKCk7DQotCX0NCi0JZWxzZQ0KLQl7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OnBhZ2VOdW0oT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsJCQkNCi0JCWlmIChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBtX3BEb2N1bWVudC0+R2V0Q3VycmVudFZpZXcoKSkNCi0JCXsNCi0JCQl2cCA8PCBwUGFnZVZpZXctPkdldFBhZ2VJbmRleCgpOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0JewkJDQotCQlpbnQgaVBhZ2VDb3VudCA9IG1fcERvY3VtZW50LT5HZXRQYWdlQ291bnQoKTsNCi0NCi0JCWludCBpUGFnZU51bSA9IDA7DQotCQl2cCA+PiBpUGFnZU51bTsNCi0NCi0JCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7DQotCQlpZighcEVudikNCi0JCQlyZXR1cm4gRkFMU0U7DQotDQotCQlpZiAoaVBhZ2VOdW0gPj0gMCAmJiBpUGFnZU51bSA8IGlQYWdlQ291bnQpDQotCQl7DQotCQkJIHBFbnYtPkpTX2RvY2dvdG9QYWdlKGlQYWdlTnVtKTsNCi0JCX0NCi0JCWVsc2UgaWYgKGlQYWdlTnVtID49IGlQYWdlQ291bnQpDQotCQl7DQotCQkJIHBFbnYtPkpTX2RvY2dvdG9QYWdlKGlQYWdlQ291bnQtMSk7DQotCQl9DQotCQllbHNlIGlmIChpUGFnZU51bSA8IDApDQotCQl7DQotCQkJIHBFbnYtPkpTX2RvY2dvdG9QYWdlKDApOw0KLQkJfQ0KLQl9DQotDQotIAlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6UGFyc2VyUGFyYW1zKEpTT2JqZWN0KiBwT2JqLENKU19Bbm5vdE9iaiYgYW5ub3RvYmopDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6YWRkQW5ub3QoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLSAJcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmFkZEZpZWxkKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JLy9Eb2Vzbid0IHN1cHBvcnQuDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0vL2V4cG9ydHMgZm9ybSBmaWVsZHMgYXMgYSB0YWItZGVsaW1pdGVkIHRleHQgZmlsZSB0byBhIGxvY2FsIGhhcmQgZGlzay4NCi0vL2NvbW1lbnQ6IG5lZWQgcmVhZGVyIHN1cHBvcnQNCi0vL25vdGUgOiB3YXRjaCB0aGUgdGhpcmQgcGFyYW1ldGVyOmNQYXRoLCBmb3Igd2hhdCBjYXNlIGl0IGNhbiBiZSBzYWZlbHkgc2F2ZWQ/DQotLy9pbnQgQ1BERlNES19JbnRlckZvcm06OkV4cG9ydEFzVGV4dChGWF9CT09MIGJOb1Bhc3N3b3JkLFN0cmluZ0FycmF5IGFGaWVsZHMsU3RyaW5nIGNQYXRoKTsNCi0vL3JldHVybiB2YWx1ZSwgaW50IHRoZSBpbmRleCBvZiB0aGUgcGFyYW1ldGVycyBpbGxlZ2FsLCB0aGUgaW5kZXggaXMgYmFzZWQgb24gMS4NCi0NCi1GWF9CT09MIERvY3VtZW50OjpleHBvcnRBc1RleHQoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpZiAoSXNTYWZlTW9kZShjYykpIHJldHVybiBUUlVFOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotLy9leHBvcnRzIGZvcm0gZmllbGRzIGFzIGEgZmRmIGZpbGUgdG8gdGhlIGxvY2FsIGhhcmQgZHJpdmUNCi0vL2NvbW1lbnQ6IG5lZWQgcmVhZGVyIHN1cHBvcnRzDQotLy9ub3RlOnRoZSBsYXN0IHBhcmFtZXRlciBoYXNuJ3QgYmVlbiBjb25maXJtZWQuYmVjYXVzZSB0aGUgcHJldmlvdXMgb25lIGJsb2NrcyB0aGUgd2F5Lg0KLS8vaW50IENQREZTREtfRG9jdW1lbnQ6OkV4cG9ydEFzRkRGKEZYX0JPT0wgYkFsbEZpZWxkcyxCT09MIGJOb1Bhc3N3b3JkLFN0cmluZ0FycmF5IGFGaWVsZHMsRlhfQk9PTCBiRmxhZ3MsU3RyaW5nIGNQYXRoLEZYX0JPT0wgYkFubm90YXRpb25zKTsNCi0NCi1GWF9CT09MIERvY3VtZW50OjpleHBvcnRBc0ZERihPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7DQotCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7DQotDQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fRVhUUkFDVF9BQ0NFU1MpKSByZXR1cm4gRkFMU0U7DQotDQotCUZYX0JPT0wgYkFsbEZpZWxkcyA9IHBhcmFtcy5zaXplKCkgPiAwID8gKEZYX0JPT0wpcGFyYW1zWzBdIDogRkFMU0U7DQotCUZYX0JPT0wgYk5vUGFzc1dvcmQgPSBwYXJhbXMuc2l6ZSgpID4gMSA/IChGWF9CT09MKXBhcmFtc1sxXSA6IFRSVUU7DQotCUZYX0JPT0wgYldob2xlID0gcGFyYW1zLnNpemUoKSA+IDIgPyAocGFyYW1zWzJdLkdldFR5cGUoKSA9PSBWVF9udWxsKSA6IFRSVUU7DQotCUNKU19BcnJheSBhcnJheUZpbGVkcyhpc29sYXRlKTsNCi0JaWYgKCFiV2hvbGUpDQotCQlhcnJheUZpbGVkcy5BdHRhY2gocGFyYW1zWzJdKTsNCi0JLy9GWF9CT09MIGJGbGFncyA9IHBhcmFtcy5zaXplKCkgPiAzID8gKEZYX0JPT0wpcGFyYW1zWzNdIDogRkFMU0U7DQotICAgIENGWF9XaWRlU3RyaW5nIHN3RmlsZVBhdGggPSBwYXJhbXMuc2l6ZSgpID4gNCA/IChGWF9MUENXU1RSKXBhcmFtc1s0XS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpIDogKEZYX0xQQ1dTVFIpTCIiOw0KLQ0KLQlpZiAoc3dGaWxlUGF0aC5Jc0VtcHR5KCkpDQotCXsNCi0JCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7DQotCQlzd0ZpbGVQYXRoID0gcEVudi0+SlNfZmllbGRCcm93c2UoKTsNCi0JCWlmKHN3RmlsZVBhdGguSXNFbXB0eSgpKQ0KLQkJCXJldHVybiBUUlVFOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJc3dGaWxlUGF0aCA9IGFwcDo6UERGUGF0aFRvU3lzUGF0aChzd0ZpbGVQYXRoKTsNCi0JfQ0KLSAgICANCi0JbV9wRG9jdW1lbnQtPlNldEZvY3VzQW5ub3QoTlVMTCk7DQotICAgDQotICAgIENQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNQREZfSW50ZXJGb3JtKiBwUERGRm9ybSA9IHBJbnRlckZvcm0tPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocFBERkZvcm0gIT0gTlVMTCk7DQotDQotCUNGWF9QdHJBcnJheSBhRmllbGRzOw0KLQ0KLQlpZiAoYldob2xlKQ0KLQl7DQotCQlmb3IgKGludCBqPTAsanN6PXBQREZGb3JtLT5Db3VudEZpZWxkcygpOyBqPGpzejsgaisrKQ0KLQkJew0KLQkJCWFGaWVsZHMuQWRkKHBQREZGb3JtLT5HZXRGaWVsZChqKSk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlmb3IgKGludCBpPTAsaXN6PWFycmF5RmlsZWRzLkdldExlbmd0aCgpOyBpPGlzejsgaSsrKQ0KLQkJew0KLQkJCUNKU19WYWx1ZSB2YWxOYW1lKGlzb2xhdGUpOw0KLQkJCWFycmF5RmlsZWRzLkdldEVsZW1lbnQoaSx2YWxOYW1lKTsNCi0JCQlDRlhfV2lkZVN0cmluZyBzd05hbWUgPSB2YWxOYW1lLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCQkJZm9yIChpbnQgaj0wLCBqc3o9cFBERkZvcm0tPkNvdW50RmllbGRzKHN3TmFtZSk7IGo8anN6OyBqKyspDQotCQkJew0KLQkJCQlhRmllbGRzLkFkZChwUERGRm9ybS0+R2V0RmllbGQoaiwgc3dOYW1lKSk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCUNGWF9QdHJBcnJheSBmaWVsZHM7DQotDQotCWZvciAoaW50IGk9MCxzej1hRmllbGRzLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCSAgICBDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gKENQREZfRm9ybUZpZWxkKilhRmllbGRzW2ldOw0KLQkJDQotCQlpZiAoIWJBbGxGaWVsZHMpDQotCQkJaWYgKHBGaWVsZC0+R2V0VmFsdWUoKSA9PSBMIiIpDQotCQkJCWNvbnRpbnVlOw0KLQ0KLQkJaWYgKGJOb1Bhc3NXb3JkKQ0KLQkJCWlmIChwRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIDB4MjAwMCkNCi0JCQkJY29udGludWU7DQotDQotICAgICAgICBmaWVsZHMuQWRkKCh2b2lkKilwRmllbGQpOw0KLQl9ICAgIA0KLQ0KLSAgICByZXR1cm4gcEludGVyRm9ybS0+RXhwb3J0RmllbGRzVG9GREZGaWxlKHN3RmlsZVBhdGgsIGZpZWxkcywgVFJVRSk7DQotfQ0KLQ0KLS8vZXhwb3J0cyBmb3JtIGZpZWxkcyBhbiBYRkRGIGZpbGUgdG8gdGhlIGxvY2FsIGhhcmQgZHJpdmUNCi0vL2NvbW1lbnQ6IG5lZWQgcmVkZXIgc3VwcG9ydHMNCi0vL25vdGU6dGhlIGxhc3QgcGFyYW1ldGVyIGNhbid0IGJlIHRlc3QNCi0vL2ludCBDUERGU0RLX0RvY3VtZW50OjpFeHBvcnRBc1hGREYoRlhfQk9PTCBiQWxsRmllbGRzLEZYX0JPT0wgIGJOb1Bhc3NXb3JkLFN0cmluZ0FycmF5IGFGaWVsZHMsU3RyaW5nIGNQYXRoLEZYX0JPT0wgYkFubm9hdGF0aW9ucyk7DQotDQotRlhfQk9PTCBEb2N1bWVudDo6ZXhwb3J0QXNYRkRGKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9FWFRSQUNUX0FDQ0VTUykpIHJldHVybiBGQUxTRTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8vTWFwcyBhIGZpZWxkIG9iamVjdCBpbiBQREYgZG9jdW1lbnQgdG8gYSBKYXZhU2NyaXB0IHZhcmlhYmxlDQotLy9jb21tZW50Og0KLS8vbm90ZTogdGhlIHBhcmVtdGVyIGNOYW1lLCB0aGlzIGlzIGNsdWUgaG93IHRvIHRyZWF0IGlmIHRoZSBjTmFtZSBpcyBub3QgYSB2YWxpYWJsZSBmaWxlZCBuYW1lIGluIHRoaXMgZG9jdW1lbnQNCi0NCi1GWF9CT09MIERvY3VtZW50OjpnZXRGaWVsZChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgPCAxKSByZXR1cm4gRkFMU0U7DQotDQotCUNGWF9XaWRlU3RyaW5nIHdpZGVOYW1lID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotICAgIENQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JQ1BERl9JbnRlckZvcm0qIHBQREZGb3JtID0gcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwUERGRm9ybSAhPSBOVUxMKTsNCi0NCi0JaWYgKHBQREZGb3JtLT5Db3VudEZpZWxkcyh3aWRlTmFtZSkgPD0gMCkgDQotCXsNCi0JCXZSZXQuU2V0TnVsbCgpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0NCi0JSlNGWE9iamVjdCAgcEZpZWxkT2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgcENvbnRleHQsIEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiRmllbGQiKSk7DQotDQotCUNKU19GaWVsZCAqIHBKU0ZpZWxkID0gKENKU19GaWVsZCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLHBGaWVsZE9iaik7DQotCUFTU0VSVChwSlNGaWVsZCAhPSBOVUxMKTsNCi0NCi0JRmllbGQgKiBwRmllbGQgPSAoRmllbGQgKilwSlNGaWVsZC0+R2V0RW1iZWRPYmplY3QoKTsgDQotCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7DQotDQotCXBGaWVsZC0+QXR0YWNoRmllbGQodGhpcywgd2lkZU5hbWUpOw0KLQl2UmV0ID0gcEpTRmllbGQ7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0vL0dldHMgdGhlIG5hbWUgb2YgdGhlIG50aCBmaWVsZCBpbiB0aGUgZG9jdW1lbnQgDQotLy9jb21tZW50Og0KLS8vbm90ZTogdGhlIHBhcmFtZXRlciBuSW5kZXgsIGlmIGl0IGlzIG5vdCBhdmFpbGFibGUNCi0NCi1GWF9CT09MIERvY3VtZW50OjpnZXROdGhGaWVsZE5hbWUoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWludCBuSW5kZXggPSBwYXJhbXMuc2l6ZSgpID4gMCA/IChpbnQpcGFyYW1zWzBdIDogLTE7DQotCWlmIChuSW5kZXggPT0gLTEpIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSBtX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDUERGX0ludGVyRm9ybSogcFBERkZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBQREZGb3JtICE9IE5VTEwpOw0KLQ0KLQlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gcFBERkZvcm0tPkdldEZpZWxkKG5JbmRleCk7DQotCWlmICghcEZpZWxkKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQl2UmV0ID0gcEZpZWxkLT5HZXRGdWxsTmFtZSgpOw0KLQlyZXR1cm4gVFJVRTsJDQotfQ0KLQ0KLS8vaW1wb3J0cyB0aGUgc3BlY2lmaWVkIGZkZiBmaWxlLg0KLS8vY29tbWVudHM6IG5lZWQgcmVhZGVyIHN1cHBwb3J0DQotLy9ub3RlOm9uY2UgdGhlIGNwYXRoIGlzIGlsbGlnbCAgdGhlbiBhIGZpbGUgZGlhbG9nIGJveCBwb3BzIHVwIGluIG9yZGVyIHRvIGFzayB1c2VyIHRvIGNob29vc2UgdGhlIGZpbGUNCi0vL2ludCBDUERGU0RLX0RvY3VtZW50OjppbXBvcnRBbkZERihTdHJpbmcgY1BhdGgpOw0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmltcG9ydEFuRkRGKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCANCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BTk5PVF9GT1JNKSB8fA0KLQkJbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0ZJTExfRk9STSkpKSByZXR1cm4gRkFMU0U7DQotDQotDQotCUNGWF9XaWRlU3RyaW5nIHN3UGF0aDsNCi0JDQotCWlmIChwYXJhbXMuc2l6ZSgpID4gMCkNCi0JCXN3UGF0aCA9IHBhcmFtc1swXTsNCi0gICAgDQotCWlmIChzd1BhdGguSXNFbXB0eSgpKQ0KLQl7DQotCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOw0KLQkJc3dQYXRoID0gcEVudi0+SlNfZmllbGRCcm93c2UoKTsNCi0JCWlmKHN3UGF0aC5Jc0VtcHR5KCkpDQotCQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlzd1BhdGggPSBhcHA6OlBERlBhdGhUb1N5c1BhdGgoc3dQYXRoKTsNCi0JfQ0KLQ0KLQltX3BEb2N1bWVudC0+U2V0Rm9jdXNBbm5vdChOVUxMKTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCWlmICghcEludGVyRm9ybS0+SW1wb3J0Rm9ybUZyb21GREZGaWxlKHN3UGF0aCwgVFJVRSkpDQotCQlyZXR1cm4gRkFMU0U7DQotDQotIAltX3BEb2N1bWVudC0+U2V0Q2hhbmdlTWFyaygpOw0KLS8vIAlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOw0KLS8vIAlBU1NFUlQocEVudiAhPSBOVUxMKTsNCi0vLyAJSVVuZG8qIHBVbmRvID0gSVVuZG86OkdldFVuZG8ocEVudik7DQotLy8gCUFTU0VSVChwVW5kbyAhPSBOVUxMKTsNCi0vLyAJcFVuZG8tPlJlc2V0KG1fcERvY3VtZW50KTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8vaW1wb3J0cyBhbmQgc3BlY2lmaWVkIFhGREYgZmlsZSBjb250YWluaW5nIFhNTCBmb3JtIGRhdGENCi0vL2NvbW1lbnQ6IG5lZWQgcmVhZGVyIHN1cHBvcnRzDQotLy9ub3RlOiBzYW1lIGFzIHVwDQotLy9pbnQgQ1BERlNES19Eb2N1bWVudDo6aW1wb3J0QW5GREYoU3RyaW5nIGNQYXRoKQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmltcG9ydEFuWEZERihPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKCEobV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkgfHwgDQotCQltX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fQU5OT1RfRk9STSkgfHwNCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9GSUxMX0ZPUk0pKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotLy9pbXBvcnRzIGFuZCBzcGVjaWZpZWQgdGV4dCBmaWxlIA0KLS8vY29tbW5ldDogbmVlZCByZWFkZXIgc3VwcG9ydHMNCi0vL25vdGU6IHNhbWUgYXMgdXAsd2hlbiBuUm93IGlzIG5vdCByYXRpb25hbCxhZG9iZSBpcyBkdW1iIGZvciBpdC4NCi0vL2ludCBDUERGU0RLX0RvY3VtZW50OjppbXBvcnRUZXh0RGF0YShTdHJpbmcgY1BhdGgsaW50IG5Sb3cpOw0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmltcG9ydFRleHREYXRhKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCANCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BTk5PVF9GT1JNKSB8fA0KLQkJbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0ZJTExfRk9STSkpKSByZXR1cm4gRkFMU0U7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0vL2V4cG9ydHMgdGhlIGZvcm0gZGF0YSBhbmQgbWFpbHMgdGhlIHJlc3VsdGluZyBmZGYgZmlsZSBhcyBhbiBhdHRhY2htZW50IHRvIGFsbCByZWNpcGllbnRzLg0KLS8vY29tbWVudDogbmVlZCByZWFkZXIgc3VwcG9ydHMNCi0vL25vdGU6DQotLy9pbnQgQ1BERlNES19Eb2N1bWVudDo6bWFpbEZvcm0oRlhfQk9PTCBiVUksU3RyaW5nIGN0byxzdHJpbmcgY2NjLHN0cmluZyBjYmNjLHN0cmluZyBjU3ViamVjdCxzdHJpbmcgY21zKTsNCi0NCi1GWF9CT09MIERvY3VtZW50OjptYWlsRm9ybShPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fRVhUUkFDVF9BQ0NFU1MpKSByZXR1cm4gRkFMU0U7DQotDQotCWludCBpTGVuZ3RoID0gcGFyYW1zLnNpemUoKTsNCi0NCi0JRlhfQk9PTCBiVUkgPSBpTGVuZ3RoID4gMCA/IChGWF9CT09MKXBhcmFtc1swXSA6IFRSVUU7DQotCUNGWF9XaWRlU3RyaW5nIGNUbyA9IGlMZW5ndGggPiAxID8gKEZYX0xQQ1dTVFIpcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkgOiAoRlhfTFBDV1NUUilMIiI7DQotCUNGWF9XaWRlU3RyaW5nIGNDYyA9IGlMZW5ndGggPiAyID8gKEZYX0xQQ1dTVFIpcGFyYW1zWzJdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkgOiAoRlhfTFBDV1NUUilMIiI7DQotCUNGWF9XaWRlU3RyaW5nIGNCY2MgPSBpTGVuZ3RoID4gMyA/IChGWF9MUENXU1RSKXBhcmFtc1szXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpIDogKEZYX0xQQ1dTVFIpTCIiOw0KLQlDRlhfV2lkZVN0cmluZyBjU3ViamVjdCA9IGlMZW5ndGggPiA0ID8gKEZYX0xQQ1dTVFIpcGFyYW1zWzRdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkgOiAoRlhfTFBDV1NUUilMIiI7DQotCUNGWF9XaWRlU3RyaW5nIGNNc2cgPSBpTGVuZ3RoID4gNSA/IChGWF9MUENXU1RSKXBhcmFtc1s1XS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpIDogKEZYX0xQQ1dTVFIpTCIiOw0KLQ0KLQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JQ0ZYX0J5dGVUZXh0QnVmIHRleHRCdWY7DQotCWlmICghcEludGVyRm9ybS0+RXhwb3J0Rm9ybVRvRkRGVGV4dEJ1Zih0ZXh0QnVmKSkNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcENvbnRleHQtPkdldFJlYWRlckFwcCgpOw0KLQlBU1NFUlQocEVudiAhPSBOVUxMKTsNCi0JQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCXBSdW50aW1lLT5CZWdpbkJsb2NrKCk7DQotICAgIHBFbnYtPkpTX2RvY21haWxGb3JtKHRleHRCdWYuR2V0QnVmZmVyKCksIHRleHRCdWYuR2V0TGVuZ3RoKCksIGJVSSwgKEZYX0xQQ1dTVFIpY1RvLCAoRlhfTFBDV1NUUiljU3ViamVjdCwgKEZYX0xQQ1dTVFIpY0NjLCAoRlhfTFBDV1NUUiljQmNjLCAoRlhfTFBDV1NUUiljTXNnKTsNCi0JcFJ1bnRpbWUtPkVuZEJsb2NrKCk7DQotIAlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6cHJpbnQoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsNCi0JQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOw0KLQ0KLQlGWF9CT09MIGJVSSA9IFRSVUU7DQotCWludCBuU3RhcnQgPSAwOw0KLQlpbnQgbkVuZCA9IDA7DQotCUZYX0JPT0wgYlNpbGVudCA9IEZBTFNFOw0KLQlGWF9CT09MIGJTaHJpbmtUb0ZpdCA9IEZBTFNFOw0KLQlGWF9CT09MIGJQcmludEFzSW1hZ2UgPSBGQUxTRTsNCi0JRlhfQk9PTCBiUmV2ZXJzZSA9IEZBTFNFOw0KLQlGWF9CT09MIGJBbm5vdGF0aW9ucyA9IEZBTFNFOw0KLQ0KLQlpbnQgbmxlbmd0aCA9IHBhcmFtcy5zaXplKCk7DQotCWlmKG5sZW5ndGggPT05KQ0KLQl7DQotCQlpZiAocGFyYW1zWzhdLkdldFR5cGUoKSA9PSBWVF9meG9iamVjdCkNCi0JCXsNCi0JCQlKU0ZYT2JqZWN0IHBPYmogPSAoSlNGWE9iamVjdClwYXJhbXNbOF07DQotCQkJew0KLQkJCQlpZiAoSlNfR2V0T2JqRGVmbklEKHBPYmopID09IEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiUHJpbnRQYXJhbXNPYmoiKSkNCi0JCQkJew0KLQkJCQkJaWYgKENKU19PYmplY3QqIHBKU09iaiA9IChDSlNfT2JqZWN0KilwYXJhbXNbOF0pDQotCQkJCQl7DQotCQkJCQkJCWlmIChQcmludFBhcmFtc09iaiogcHByaW50cGFyYW1zT2JqID0gKFByaW50UGFyYW1zT2JqKilwSlNPYmotPkdldEVtYmVkT2JqZWN0KCkpDQotCQkJCQkJCXsNCi0JCQkJCQkJCWJVSSA9IHBwcmludHBhcmFtc09iai0+YlVJOw0KLQkJCQkJCQkJblN0YXJ0ID0gcHByaW50cGFyYW1zT2JqLT5uU3RhcnQ7DQotCQkJCQkJCQluRW5kID0gcHByaW50cGFyYW1zT2JqLT5uRW5kOw0KLQkJCQkJCQkJYlNpbGVudCA9IHBwcmludHBhcmFtc09iai0+YlNpbGVudDsNCi0JCQkJCQkJCWJTaHJpbmtUb0ZpdCA9IHBwcmludHBhcmFtc09iai0+YlNocmlua1RvRml0Ow0KLQkJCQkJCQkJYlByaW50QXNJbWFnZSA9IHBwcmludHBhcmFtc09iai0+YlByaW50QXNJbWFnZTsNCi0JCQkJCQkJCWJSZXZlcnNlID0gcHByaW50cGFyYW1zT2JqLT5iUmV2ZXJzZTsNCi0JCQkJCQkJCWJBbm5vdGF0aW9ucyA9IHBwcmludHBhcmFtc09iai0+YkFubm90YXRpb25zOw0KLQkJCQkJCQl9DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9CQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYobmxlbmd0aCA+PSAxKQ0KLQkJCSBiVUkgPSBwYXJhbXNbMF07DQotCQlpZihubGVuZ3RoID49IDIpDQotCQkJIG5TdGFydCA9IChpbnQpcGFyYW1zWzFdOw0KLQkJaWYobmxlbmd0aCA+PSAzKQ0KLQkJICAgIG5FbmQgPSAoaW50KXBhcmFtc1syXTsNCi0JCWlmKG5sZW5ndGggPj0gNCkNCi0JCQliU2lsZW50ID0gcGFyYW1zWzNdOw0KLQkJaWYobmxlbmd0aCA+PSA1KQ0KLQkJICAgIGJTaHJpbmtUb0ZpdCA9IHBhcmFtc1s0XTsNCi0JCWlmKG5sZW5ndGggPj0gNikNCi0JCQliUHJpbnRBc0ltYWdlID0gcGFyYW1zWzVdOw0KLQkJaWYobmxlbmd0aCA+PSA3KQ0KLQkJCWJSZXZlcnNlID0gcGFyYW1zWzZdOw0KLQkJaWYobmxlbmd0aCA+PSA4KQ0KLQkJCWJBbm5vdGF0aW9ucyA9IHBhcmFtc1s3XTsNCi0JfQ0KLQ0KLSAJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLSANCi0gCWlmIChDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpKQ0KLSAJew0KLQkJcEVudi0+SlNfZG9jcHJpbnQoYlVJLCBuU3RhcnQsIG5FbmQsIGJTaWxlbnQsIGJTaHJpbmtUb0ZpdCwgYlByaW50QXNJbWFnZSwgYlJldmVyc2UsIGJBbm5vdGF0aW9ucyk7DQotIAkJcmV0dXJuIFRSVUU7DQotIAl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotLy9yZW1vdmVzIHRoZSBzcGVjaWZpZWQgZmllbGQgZnJvbSB0aGUgZG9jdW1lbnQuDQotLy9jb21tZW50Og0KLS8vbm90ZTogaWYgdGhlIGZpbGVkIG5hbWUgaXMgbm90IHJldGlvbmFsLCBhZG9iZSBpcyBkdW1iIGZvciBpdC4NCi0NCi1GWF9CT09MIERvY3VtZW50OjpyZW1vdmVGaWVsZChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKCEobV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkgfHwgDQotCQltX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fQU5OT1RfRk9STSkpKSByZXR1cm4gRkFMU0U7DQotDQotCWlmIChwYXJhbXMuc2l6ZSgpIDwgMSkNCi0JCXJldHVybiBUUlVFOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzRmllbGROYW1lID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDRlhfUHRyQXJyYXkgd2lkZ2V0czsNCi0JcEludGVyRm9ybS0+R2V0V2lkZ2V0cyhzRmllbGROYW1lLCB3aWRnZXRzKTsNCi0NCi0JaW50IG5TaXplID0gd2lkZ2V0cy5HZXRTaXplKCk7DQotDQotCWlmIChuU2l6ZSA+IDApDQotCXsNCi0JCWZvciAoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQ0KLQkJew0KLQkJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0Kil3aWRnZXRzW2ldOw0KLQkJCUFTU0VSVChwV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQkJCUNQREZfUmVjdCByY0Fubm90ID0gcFdpZGdldC0+R2V0UmVjdCgpOw0KLQkJCXJjQW5ub3QubGVmdCAtPSAxOw0KLQkJCXJjQW5ub3QuYm90dG9tIC09IDE7DQotCQkJcmNBbm5vdC5yaWdodCArPSAxOw0KLQkJCXJjQW5ub3QudG9wICs9IDE7DQotDQotCQkJQ0ZYX1JlY3RBcnJheSBhUmVmcmVzaDsNCi0JCQlhUmVmcmVzaC5BZGQocmNBbm5vdCk7DQotDQotCQkJQ1BERl9QYWdlKiBwUGFnZSA9IHBXaWRnZXQtPkdldFBERlBhZ2UoKTsNCi0JCQlBU1NFUlQocFBhZ2UgIT0gTlVMTCk7DQotCQkJDQotCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gbV9wRG9jdW1lbnQtPkdldFBhZ2VWaWV3KHBQYWdlKTsNCi0JCQlwUGFnZVZpZXctPkRlbGV0ZUFubm90KHBXaWRnZXQpOw0KLQ0KLQkJCXBQYWdlVmlldy0+VXBkYXRlUmVjdHMoYVJlZnJlc2gpOw0KLQkJfQ0KLQkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotLy9yZXNldCBmaWxlZCB2YWx1ZXMgd2l0aGluIGEgZG9jdW1lbnQuDQotLy9jb21tZW50Og0KLS8vbm90ZTogaWYgdGhlIGZpZWxkcyBuYW1lcyByIG5vdCByYXRpb25hbCwgYW9kYmUgaXMgZHVtYiBmb3IgaXQuDQotDQotRlhfQk9PTCBEb2N1bWVudDo6cmVzZXRGb3JtKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCANCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BTk5PVF9GT1JNKSB8fA0KLQkJbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0ZJTExfRk9STSkpKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDUERGX0ludGVyRm9ybSogcFBERkZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBQREZGb3JtICE9IE5VTEwpOw0KLQ0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOw0KLQlDSlNfQXJyYXkgYU5hbWUoaXNvbGF0ZSk7DQotDQotCWlmIChwYXJhbXMuc2l6ZSgpID4gMCkNCi0Jew0KLQkJc3dpdGNoIChwYXJhbXNbMF0uR2V0VHlwZSgpKQ0KLQkJew0KLQkJZGVmYXVsdDoNCi0JCQlhTmFtZS5BdHRhY2gocGFyYW1zWzBdKTsNCi0JCQlicmVhazsNCi0JCWNhc2UgVlRfc3RyaW5nOg0KLQkJCWFOYW1lLlNldEVsZW1lbnQoMCxwYXJhbXNbMF0pOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQ0KLQkJQ0ZYX1B0ckFycmF5IGFGaWVsZHM7DQotDQotCQlmb3IgKGludCBpPTAsaXN6PWFOYW1lLkdldExlbmd0aCgpOyBpPGlzejsgaSsrKQ0KLQkJew0KLQkJCUNKU19WYWx1ZSB2YWxFbGVtZW50KGlzb2xhdGUpOw0KLQkJCWFOYW1lLkdldEVsZW1lbnQoaSx2YWxFbGVtZW50KTsNCi0JCQlDRlhfV2lkZVN0cmluZyBzd1ZhbCA9IHZhbEVsZW1lbnQub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsJDQotCQkJDQotCQkJZm9yIChpbnQgaj0wLGpzej1wUERGRm9ybS0+Q291bnRGaWVsZHMoc3dWYWwpOyBqPGpzejsgaisrKQ0KLQkJCXsNCi0JCQkJYUZpZWxkcy5BZGQoKHZvaWQqKXBQREZGb3JtLT5HZXRGaWVsZChqLHN3VmFsKSk7DQotCQkJfQkJDQotCQl9DQotDQotCQlpZiAoYUZpZWxkcy5HZXRTaXplKCkgPiAwKQ0KLQkJew0KLSAJCQlwUERGRm9ybS0+UmVzZXRGb3JtKGFGaWVsZHMsIFRSVUUsIFRSVUUpOw0KLSAJCQltX3BEb2N1bWVudC0+U2V0Q2hhbmdlTWFyaygpOw0KLQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLSAJCXBQREZGb3JtLT5SZXNldEZvcm0oVFJVRSk7DQotIAkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi0NCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotDQotRlhfQk9PTCBEb2N1bWVudDo6c2F2ZUFzKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0NCi0JaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsNCi0NCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLS8vCW1fcERvY3VtZW50LT5Eb1NhdmVBcygpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotDQotRlhfQk9PTCBEb2N1bWVudDo6c3VibWl0Rm9ybShPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0vLwlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9FWFRSQUNUX0FDQ0VTUykpIHJldHVybiBGQUxTRTsNCi0NCi0JaW50IG5TaXplID0gcGFyYW1zLnNpemUoKTsNCi0JaWYgKG5TaXplIDwgMSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzdHJVUkw7DQotCUZYX0JPT0wgYkZERiA9IFRSVUU7DQotCUZYX0JPT0wgYkVtcHR5ID0gRkFMU0U7DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7DQotCUNKU19BcnJheSBhRmllbGRzKGlzb2xhdGUpOw0KLQ0KLQlDSlNfVmFsdWUgdiA9IHBhcmFtc1swXTsNCi0JaWYgKHYuR2V0VHlwZSgpID09IFZUX3N0cmluZykNCi0Jew0KLQkJc3RyVVJMID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotCQlpZiAoblNpemUgPiAxKQ0KLQkJCWJGREYgPSBwYXJhbXNbMV07DQotCQlpZiAoblNpemUgPiAyKQ0KLQkJCWJFbXB0eSA9IHBhcmFtc1syXTsNCi0JCWlmIChuU2l6ZSA+IDMpDQotCQkJYUZpZWxkcy5BdHRhY2gocGFyYW1zWzNdKTsNCi0JfQ0KLQllbHNlIGlmICh2LkdldFR5cGUoKSA9PSBWVF9vYmplY3QpDQotCXsNCi0JCUpTT2JqZWN0IHBPYmogPSAoSlNPYmplY3QpcGFyYW1zWzBdOw0KLQkJdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNVUkwiKTsNCi0JCWlmICghcFZhbHVlLklzRW1wdHkoKSkNCi0JCQlzdHJVUkwgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7DQotCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJiRkRGIik7DQotCQkJYkZERiA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSwgR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7DQotCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJiRW1wdHkiKTsNCi0JCQliRW1wdHkgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsIEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOw0KLQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosTCJhRmllbGRzIik7DQotCQkJYUZpZWxkcy5BdHRhY2goQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLCBHRVRfVkFMVUVfVFlQRShwVmFsdWUpKSk7DQotCX0JCQ0KLQ0KLQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0JQ1BERl9JbnRlckZvcm0qIHBQREZJbnRlckZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBQREZJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUZYX0JPT0wgYkFsbCA9IChhRmllbGRzLkdldExlbmd0aCgpID09IDApOw0KLQ0KLQlpZiAoYkFsbCAmJiBiRW1wdHkpDQotCXsNCi0JCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCQkNCi0JCWlmIChwUERGSW50ZXJGb3JtLT5DaGVja1JlcXVpcmVkRmllbGRzKCkpDQotCQl7DQotCQkJcFJ1bnRpbWUtPkJlZ2luQmxvY2soKTsNCi0JCQlwSW50ZXJGb3JtLT5TdWJtaXRGb3JtKHN0clVSTCwgRkFMU0UpOw0KLQkJCXBSdW50aW1lLT5FbmRCbG9jaygpOw0KLQkJfQ0KLQ0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JZWxzZQ0KLQl7CQ0KLQkJQ0ZYX1B0ckFycmF5IGZpZWxkT2JqZWN0czsNCi0NCi0JCWZvciAoaW50IGk9MCxzej1hRmllbGRzLkdldExlbmd0aCgpOyBpPHN6OyBpKyspDQotCQl7DQotCQkJQ0pTX1ZhbHVlIHZhbE5hbWUoaXNvbGF0ZSk7DQotCQkJYUZpZWxkcy5HZXRFbGVtZW50KGksIHZhbE5hbWUpOw0KLQkJCUNGWF9XaWRlU3RyaW5nIHNOYW1lID0gdmFsTmFtZS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJCUNQREZfSW50ZXJGb3JtKiBwUERGRm9ybSA9IHBJbnRlckZvcm0tPkdldEludGVyRm9ybSgpOw0KLQkJCUFTU0VSVChwUERGRm9ybSAhPSBOVUxMKTsNCi0NCi0JCQlmb3IgKGludCBqPTAsIGpzej1wUERGRm9ybS0+Q291bnRGaWVsZHMoc05hbWUpOyBqPGpzejsgaisrKQ0KLQkJCXsNCi0JCQkJQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCA9IHBQREZGb3JtLT5HZXRGaWVsZChqLCBzTmFtZSk7DQotCQkJCWlmICghYkVtcHR5ICYmIHBGaWVsZC0+R2V0VmFsdWUoKS5Jc0VtcHR5KCkpDQotCQkJCQljb250aW51ZTsNCi0NCi0JCQkJZmllbGRPYmplY3RzLkFkZChwRmllbGQpOw0KLQkJCX0NCi0JCX0NCi0NCi0JCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCQkNCi0JCWlmIChwUERGSW50ZXJGb3JtLT5DaGVja1JlcXVpcmVkRmllbGRzKCZmaWVsZE9iamVjdHMsIFRSVUUpKQ0KLQkJew0KLQkJCXBSdW50aW1lLT5CZWdpbkJsb2NrKCk7DQotCQkJcEludGVyRm9ybS0+U3VibWl0RmllbGRzKHN0clVSTCwgZmllbGRPYmplY3RzLCBUUlVFLCAhYkZERik7DQotCQkJcFJ1bnRpbWUtPkVuZEJsb2NrKCk7DQotCQl9DQotDQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLX0NCi0NCi0vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotDQotdm9pZCBEb2N1bWVudDo6QXR0YWNoRG9jKENQREZTREtfRG9jdW1lbnQgKnBEb2MpDQotew0KLQltX3BEb2N1bWVudCA9IHBEb2M7DQotfQ0KLQ0KLUNQREZTREtfRG9jdW1lbnQgKiBEb2N1bWVudDo6R2V0UmVhZGVyRG9jKCkNCi17DQotCXJldHVybiBtX3BEb2N1bWVudDsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6RXh0cmFjdEZpbGVOYW1lKENQREZTREtfRG9jdW1lbnQgKnBEb2MsQ0ZYX0J5dGVTdHJpbmcgJnN0ckZpbGVOYW1lKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpFeHRyYWN0Rm9sZGVyTmFtZShDUERGU0RLX0RvY3VtZW50ICpwRG9jLENGWF9CeXRlU3RyaW5nICZzdHJGb2xkZXJOYW1lKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50Ojpib29rbWFya1Jvb3QoT0JKX1BST1BfUEFSQU1TKQ0KLXsJDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjptYWlsRG9jKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlGWF9CT09MIGJVSSA9IFRSVUU7DQotCUNGWF9XaWRlU3RyaW5nIGNUbyA9IEwiIjsNCi0JQ0ZYX1dpZGVTdHJpbmcgY0NjID0gTCIiOw0KLQlDRlhfV2lkZVN0cmluZyBjQmNjID0gTCIiOw0KLQlDRlhfV2lkZVN0cmluZyBjU3ViamVjdCA9IEwiIjsNCi0JQ0ZYX1dpZGVTdHJpbmcgY01zZyA9IEwiIjsNCi0JDQotDQotCWJVSSA9IHBhcmFtcy5zaXplKCk+PTE/c3RhdGljX2Nhc3Q8RlhfQk9PTD4ocGFyYW1zWzBdKTpUUlVFOw0KLQljVG8gPSBwYXJhbXMuc2l6ZSgpPj0yPyhjb25zdCB3Y2hhcl90KilwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTpMIiI7DQotCWNDYyA9IHBhcmFtcy5zaXplKCk+PTM/KGNvbnN0IHdjaGFyX3QqKXBhcmFtc1syXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsNCi0JY0JjYyA9IHBhcmFtcy5zaXplKCk+PTQ/KGNvbnN0IHdjaGFyX3QqKXBhcmFtc1szXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsNCi0JY1N1YmplY3QgPSBwYXJhbXMuc2l6ZSgpPj01Pyhjb25zdCB3Y2hhcl90KilwYXJhbXNbNF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTpMIiI7DQotCWNNc2cgPSBwYXJhbXMuc2l6ZSgpPj02Pyhjb25zdCB3Y2hhcl90KilwYXJhbXNbNV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTpMIiI7DQotCQ0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOw0KLQ0KLQlpZihwYXJhbXMuc2l6ZSgpPj0xICYmIHBhcmFtc1swXS5HZXRUeXBlKCkgPT0gVlRfb2JqZWN0KQ0KLQl7DQotCQlKU09iamVjdCAgcE9iaiA9IChKU09iamVjdCApcGFyYW1zWzBdOw0KLQ0KLQkJdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImJVSSIpOw0KLQkJCWJVSSA9IChpbnQpQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOw0KLQ0KLQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiY1RvIik7DQotCQkJY1RvID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjQ2MiKTsNCi0JCQljQ2MgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0NCi0JCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNCY2MiKTsNCi0JCQljQmNjID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjU3ViamVjdCIpOw0KLQkJCWNTdWJqZWN0ID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjTXNnIik7DQotCQkJY01zZyA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQkNCi0JfQ0KLQ0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsNCi0JQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOw0KLQ0KLQlwUnVudGltZS0+QmVnaW5CbG9jaygpOw0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcFJ1bnRpbWUtPkdldFJlYWRlckFwcCgpOw0KLQlwRW52LT5KU19kb2NtYWlsRm9ybShOVUxMLCAwLCBiVUksIChGWF9MUENXU1RSKWNUbywgKEZYX0xQQ1dTVFIpY1N1YmplY3QsIChGWF9MUENXU1RSKWNDYywgKEZYX0xQQ1dTVFIpY0JjYywgKEZYX0xQQ1dTVFIpY01zZyk7DQotCXBSdW50aW1lLT5FbmRCbG9jaygpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6YXV0aG9yKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwRGljdGlvbmFyeSA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLT5HZXRJbmZvKCk7DQotCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiQXV0aG9yIik7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNGWF9XaWRlU3RyaW5nIGNzQXV0aG9yOw0KLQkJdnAgPj4gY3NBdXRob3I7DQotCQlwRGljdGlvbmFyeS0+U2V0QXRTdHJpbmcoIkF1dGhvciIsIFBERl9FbmNvZGVUZXh0KGNzQXV0aG9yKSk7DQotCQltX3BEb2N1bWVudC0+U2V0Q2hhbmdlTWFyaygpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6aW5mbyhPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUNQREZfRGljdGlvbmFyeSogcERpY3Rpb25hcnkgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKS0+R2V0SW5mbygpOw0KLQlpZiAoIXBEaWN0aW9uYXJ5KXJldHVybiBGQUxTRTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgY3dBdXRob3IJCQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiQXV0aG9yIik7DQotCUNGWF9XaWRlU3RyaW5nIGN3VGl0bGUJCQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiVGl0bGUiKTsNCi0JQ0ZYX1dpZGVTdHJpbmcgY3dTdWJqZWN0CQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiU3ViamVjdCIpOw0KLQlDRlhfV2lkZVN0cmluZyBjd0tleXdvcmRzCQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiS2V5d29yZHMiKTsNCi0JQ0ZYX1dpZGVTdHJpbmcgY3dDcmVhdG9yCQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiQ3JlYXRvciIpOw0KLQlDRlhfV2lkZVN0cmluZyBjd1Byb2R1Y2VyCQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiUHJvZHVjZXIiKTsNCi0JQ0ZYX1dpZGVTdHJpbmcgY3dDcmVhdGlvbkRhdGUJPSBwRGljdGlvbmFyeS0+R2V0VW5pY29kZVRleHQoIkNyZWF0aW9uRGF0ZSIpOw0KLQlDRlhfV2lkZVN0cmluZyBjd01vZERhdGUJCT0gcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJNb2REYXRlIik7DQotCUNGWF9XaWRlU3RyaW5nIGN3VHJhcHBlZAkJPSBwRGljdGlvbmFyeS0+R2V0VW5pY29kZVRleHQoIlRyYXBwZWQiKTsNCi0NCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsNCi0JaWYgKCF2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotDQotCQlKU0ZYT2JqZWN0ICBwT2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgcENvbnRleHQsIC0xKTsNCi0NCi0JCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIEwiQXV0aG9yIiwgY3dBdXRob3IpOw0KLQkJSlNfUHV0T2JqZWN0U3RyaW5nKGlzb2xhdGUscE9iaiwgTCJUaXRsZSIsIGN3VGl0bGUpOw0KLQkJSlNfUHV0T2JqZWN0U3RyaW5nKGlzb2xhdGUscE9iaiwgTCJTdWJqZWN0IiwgY3dTdWJqZWN0KTsNCi0JCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIEwiS2V5d29yZHMiLCBjd0tleXdvcmRzKTsNCi0JCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIEwiQ3JlYXRvciIsIGN3Q3JlYXRvcik7DQotCQlKU19QdXRPYmplY3RTdHJpbmcoaXNvbGF0ZSxwT2JqLCBMIlByb2R1Y2VyIiwgY3dQcm9kdWNlcik7DQotCQlKU19QdXRPYmplY3RTdHJpbmcoaXNvbGF0ZSxwT2JqLCBMIkNyZWF0aW9uRGF0ZSIsIGN3Q3JlYXRpb25EYXRlKTsNCi0JCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIEwiTW9kRGF0ZSIsIGN3TW9kRGF0ZSk7DQotCQlKU19QdXRPYmplY3RTdHJpbmcoaXNvbGF0ZSxwT2JqLCBMIlRyYXBwZWQiLCBjd1RyYXBwZWQpOw0KLQ0KLS8vIEl0J3MgdG8gYmUgY29tcGF0aWJsZSB0byBub24tc3RhbmRhcmQgaW5mbyBkaWN0aW9uYXJ5LgkNCi0JCUZYX1BPU0lUSU9OIHBvcyA9IHBEaWN0aW9uYXJ5LT5HZXRTdGFydFBvcygpOw0KLQkJd2hpbGUocG9zKQ0KLQkJew0KLQkJCUNGWF9CeXRlU3RyaW5nIGJzS2V5Ow0KLQkJCUNQREZfT2JqZWN0KiBwVmFsdWVPYmogPSBwRGljdGlvbmFyeS0+R2V0TmV4dEVsZW1lbnQocG9zLCBic0tleSk7DQotCQkJQ0ZYX1dpZGVTdHJpbmcgd3NLZXkgID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21VVEY4KGJzS2V5KTsNCi0JCQlpZigocFZhbHVlT2JqLT5HZXRUeXBlKCk9PVBERk9CSl9TVFJJTkcpIHx8IChwVmFsdWVPYmotPkdldFR5cGUoKT09UERGT0JKX05BTUUpICkNCi0JCQkJCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIHdzS2V5LCBwVmFsdWVPYmotPkdldFVuaWNvZGVUZXh0KCkpOw0KLQkJCWlmKHBWYWx1ZU9iai0+R2V0VHlwZSgpPT1QREZPQkpfTlVNQkVSKQ0KLQkJCQlKU19QdXRPYmplY3ROdW1iZXIoaXNvbGF0ZSxwT2JqLCB3c0tleSwgKGZsb2F0KXBWYWx1ZU9iai0+R2V0TnVtYmVyKCkpOw0KLQkJCWlmKHBWYWx1ZU9iai0+R2V0VHlwZSgpPT1QREZPQkpfQk9PTEVBTikNCi0JCQkJSlNfUHV0T2JqZWN0Qm9vbGVhbihpc29sYXRlLHBPYmosIHdzS2V5LCAoYm9vbClwVmFsdWVPYmotPkdldEludGVnZXIoKSk7DQotCQl9DQotDQotCQl2cCA8PCBwT2JqOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpjcmVhdGlvbkRhdGUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0aW9uYXJ5ID0gbV9wRG9jdW1lbnQtPkdldERvY3VtZW50KCktPkdldEluZm8oKTsNCi0JaWYgKCFwRGljdGlvbmFyeSlyZXR1cm4gRkFMU0U7DQotDQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJDcmVhdGlvbkRhdGUiKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgY3NDcmVhdGlvbkRhdGU7DQotCQl2cCA+PiBjc0NyZWF0aW9uRGF0ZTsNCi0JCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiQ3JlYXRpb25EYXRlIiwgUERGX0VuY29kZVRleHQoY3NDcmVhdGlvbkRhdGUpKTsNCi0JCW1fcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7DQotDQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpjcmVhdG9yKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwRGljdGlvbmFyeSA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLT5HZXRJbmZvKCk7DQotCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiQ3JlYXRvciIpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9NT0RJRlkpKSByZXR1cm4gRkFMU0U7DQotDQotCQlDRlhfV2lkZVN0cmluZyBjc0NyZWF0b3I7DQotCQl2cCA+PiBjc0NyZWF0b3I7DQotCQlwRGljdGlvbmFyeS0+U2V0QXRTdHJpbmcoIkNyZWF0b3IiLCBQREZfRW5jb2RlVGV4dChjc0NyZWF0b3IpKTsNCi0JCW1fcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpkZWxheShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IG1fYkRlbGF5Ow0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCQlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9NT0RJRlkpKSByZXR1cm4gRkFMU0U7DQotDQotCQlib29sIGI7DQotCQl2cCA+PiBiOw0KLQ0KLQkJbV9iRGVsYXkgPSBiOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KSANCi0JCXsNCi0JCQlmb3IgKGludCBpPTAsc3o9bV9EZWxheURhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQkJCWRlbGV0ZSBtX0RlbGF5RGF0YS5HZXRBdChpKTsNCi0NCi0JCQltX0RlbGF5RGF0YS5SZW1vdmVBbGwoKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlmb3IgKGludCBpPTAsc3o9bV9EZWxheURhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQkJew0KLQkJCQlpZiAoQ0pTX0RlbGF5RGF0YSogcERhdGEgPSBtX0RlbGF5RGF0YS5HZXRBdChpKSkNCi0JCQkJew0KLQkJCQkJRmllbGQ6OkRvRGVsYXkobV9wRG9jdW1lbnQsIHBEYXRhKTsNCi0JCQkJCWRlbGV0ZSBtX0RlbGF5RGF0YS5HZXRBdChpKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCQltX0RlbGF5RGF0YS5SZW1vdmVBbGwoKTsNCi0JCX0NCi0NCi0JCXJldHVybiBUUlVFOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmtleXdvcmRzKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwRGljdGlvbmFyeSA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLT5HZXRJbmZvKCk7DQotCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiS2V5d29yZHMiKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgY3NLZXl3b3JkczsNCi0JCXZwID4+IGNzS2V5d29yZHM7DQotCQlwRGljdGlvbmFyeS0+U2V0QXRTdHJpbmcoIktleXdvcmRzIiwgUERGX0VuY29kZVRleHQoY3NLZXl3b3JkcykpOw0KLQkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6Om1vZERhdGUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0aW9uYXJ5ID0gbV9wRG9jdW1lbnQtPkdldERvY3VtZW50KCktPkdldEluZm8oKTsNCi0JaWYgKCFwRGljdGlvbmFyeSlyZXR1cm4gRkFMU0U7DQotDQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJNb2REYXRlIik7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNGWF9XaWRlU3RyaW5nIGNzbW9kRGF0ZTsNCi0JCXZwID4+IGNzbW9kRGF0ZTsNCi0JCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiTW9kRGF0ZSIsIFBERl9FbmNvZGVUZXh0KGNzbW9kRGF0ZSkpOw0KLQkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OnByb2R1Y2VyKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwRGljdGlvbmFyeSA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLT5HZXRJbmZvKCk7DQotCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiUHJvZHVjZXIiKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgY3Nwcm9kdWNlcjsNCi0JCXZwID4+IGNzcHJvZHVjZXI7DQotCQlwRGljdGlvbmFyeS0+U2V0QXRTdHJpbmcoIlByb2R1Y2VyIiwgUERGX0VuY29kZVRleHQoY3Nwcm9kdWNlcikpOw0KLQkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OnN1YmplY3QoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBEaWN0aW9uYXJ5ID0gbV9wRG9jdW1lbnQtPkdldERvY3VtZW50KCktPkdldEluZm8oKTsNCi0JaWYgKCFwRGljdGlvbmFyeSlyZXR1cm4gRkFMU0U7DQotDQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJTdWJqZWN0Iik7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNGWF9XaWRlU3RyaW5nIGNzc3ViamVjdDsNCi0JCXZwID4+IGNzc3ViamVjdDsNCi0JCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiU3ViamVjdCIsIFBERl9FbmNvZGVUZXh0KGNzc3ViamVjdCkpOw0KLQkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OnRpdGxlKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKG1fcERvY3VtZW50ID09IE5VTEwgfHwgbV9wRG9jdW1lbnQtPkdldERvY3VtZW50KCkgPT0gTlVMTCkNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwRGljdGlvbmFyeSA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLT5HZXRJbmZvKCk7DQotCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiVGl0bGUiKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgY3N0aXRsZTsNCi0JCXZwID4+IGNzdGl0bGU7DQotCQlwRGljdGlvbmFyeS0+U2V0QXRTdHJpbmcoIlRpdGxlIiwgUERGX0VuY29kZVRleHQoY3N0aXRsZSkpOw0KLQkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6Om51bVBhZ2VzKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQkJdnAgPDwgbV9wRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6ZXh0ZXJuYWwoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JLy9JbiBDaHJvbWUgY2FzZSxzaG91bGQgYWx3YXlzIHJldHVybiB0cnVlLg0KLQl2cCA8PCBUUlVFOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6ZmlsZXNpemUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7DQotDQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0vLyAJQ0ZpbGUgZmlsZShtX3BEb2N1bWVudC0+R2V0UGF0aCgpLCBDRmlsZTo6bW9kZVJlYWQgfCBDRmlsZTo6dHlwZUJpbmFyeSB8IENGaWxlOjpzaGFyZURlbnlOb25lKTsNCi0vLyAJdnAgPDwgKGRvdWJsZSlmaWxlLkdldExlbmd0aCgpOw0KLS8vIAlmaWxlLkNsb3NlKCk7DQotDQotCWlmICggbV9wRG9jdW1lbnQtPkdldFBhdGgoKS5Jc0VtcHR5KCkgPT0gRkFMU0UpDQotCXsNCi0JCUNGWF9CeXRlU3RyaW5nIGJzU3RyID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKCBtX3BEb2N1bWVudC0+R2V0UGF0aCgpICk7DQotCQlGSUxFICogcEZpbGUgPSBOVUxMOw0KLQkJcEZpbGUgPSBmb3BlbiggYnNTdHIuR2V0QnVmZmVyKCBic1N0ci5HZXRMZW5ndGgoKSApLCAicmIiICk7DQotCQlpZiAoIHBGaWxlICkNCi0JCXsNCi0JCQlmc2VlayggcEZpbGUsIDAsIFNFRUtfRU5EICk7DQotCQkJbG9uZyBsU2l6ZSA9IGZ0ZWxsKCBwRmlsZSApOw0KLQkJCWZjbG9zZSggcEZpbGUgKTsNCi0JCQlwRmlsZSA9IE5VTEw7DQotDQotCQkJdnAgPDwgKEZYX0lOVDMyKShsU2l6ZSk7DQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0NCi0JdnAgPDwgMDsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6Om1vdXNlWChPQkpfUFJPUF9QQVJBTVMpDQotew0KLSAJcmV0dXJuIFRSVUU7CQ0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50Ojptb3VzZVkoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0gCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpiYXNlVVJMKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJdnAgPDwgbV9jd0Jhc2VVUkw7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXZwID4+IG1fY3dCYXNlVVJMOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6Y2FsY3VsYXRlKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJaWYgKHBJbnRlckZvcm0tPklzQ2FsY3VsYXRlRW5hYmxlZCgpKQ0KLQkJCXZwIDw8IHRydWU7DQotCQllbHNlDQotCQkJdnAgPDwgZmFsc2U7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlib29sIGJDYWxjdWxhdGU7DQotCQl2cCA+PiBiQ2FsY3VsYXRlOw0KLQ0KLQkJcEludGVyRm9ybS0+RW5hYmxlQ2FsY3VsYXRlKGJDYWxjdWxhdGUpOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50Ojpkb2N1bWVudEZpbGVOYW1lKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICghdnAuSXNHZXR0aW5nKCkpDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCUNGWF9XaWRlU3RyaW5nIHdzRmlsZVBhdGggPSBtX3BEb2N1bWVudC0+R2V0UGF0aCgpOw0KLQ0KLQlGWF9JTlQzMiBpID0gd3NGaWxlUGF0aC5HZXRMZW5ndGgoKSAtIDE7DQotCWZvciAoIDsgaSA+PSAwOyBpLS0gKQ0KLQl7DQotCQlpZiAoIHdzRmlsZVBhdGguR2V0QXQoIGkgKSA9PSBMJ1xcJyB8fCB3c0ZpbGVQYXRoLkdldEF0KCBpICkgPT0gTCcvJyApDQotCQkJYnJlYWs7DQotCX0NCi0JaWYgKCBpID49IDAgJiYgaSA8IHdzRmlsZVBhdGguR2V0TGVuZ3RoKCkgLSAxICkNCi0Jew0KLQkJdnAgPDwgKCB3c0ZpbGVQYXRoLkdldEJ1ZmZlciggd3NGaWxlUGF0aC5HZXRMZW5ndGgoKSApICsgaSArIDEgKTsNCi0JfWVsc2V7DQotCQl2cCA8PCBMIiI7DQotCX0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIERvY3VtZW50OjpSZXZlcnNhbFN0cihDRlhfV2lkZVN0cmluZyBjYkZyb20pDQotew0KLQl3Y2hhcl90KiBwRnJvbSA9IE5VTEw7DQotCWludCBpTGVudGggPSBjYkZyb20uR2V0TGVuZ3RoKCk7DQotCXdjaGFyX3QqIHBSZXN1bHQgPSAod2NoYXJfdCopbWFsbG9jKChpTGVudGgrMSkgKiBzaXplb2Yod2NoYXJfdCkpOw0KLQltZW1zZXQocFJlc3VsdCwgMCwgKGlMZW50aCsxKSk7DQotCXBGcm9tID0gKHdjaGFyX3QqKWNiRnJvbS5HZXRCdWZmZXIoaUxlbnRoKTsNCi0NCi0JZm9yIChpbnQgaSA9IDA7IGkgPCBpTGVudGg7IGkrKykNCi0Jew0KLQkJcFJlc3VsdFtpXSA9ICoocEZyb20gKyBpTGVudGggLSBpIC0gMSk7DQotCX0NCi0NCi0JY2JGcm9tLlJlbGVhc2VCdWZmZXIoKTsNCi0JQ0ZYX1dpZGVTdHJpbmcgY2JSZXQgPSBDRlhfV2lkZVN0cmluZyhwUmVzdWx0KTsNCi0JZnJlZShwUmVzdWx0KTsNCi0JcFJlc3VsdCA9IE5VTEw7DQotCXJldHVybiBjYlJldDsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgRG9jdW1lbnQ6OkN1dFN0cmluZyhDRlhfV2lkZVN0cmluZyBjYkZyb20pDQotew0KLQl3Y2hhcl90KiBwRnJvbSA9IE5VTEw7DQotCWludCBpTGVudGggPSBjYkZyb20uR2V0TGVuZ3RoKCk7DQotCXdjaGFyX3QqIHBSZXN1bHQgPSAod2NoYXJfdCopbWFsbG9jKChpTGVudGgrMSkgKiBzaXplb2Yod2NoYXJfdCkpOw0KLQltZW1zZXQocFJlc3VsdCwgMCwgKGlMZW50aCsxKSk7DQotCXBGcm9tID0gKHdjaGFyX3QqKWNiRnJvbS5HZXRCdWZmZXIoaUxlbnRoKTsNCi0NCi0JZm9yIChpbnQgaSA9IDA7IGkgPCBpTGVudGg7IGkrKykNCi0Jew0KLQkJaWYgKHBGcm9tW2ldID09IEwnXFwnIHx8IHBGcm9tW2ldID09IEwnLycpDQotCQkJYnJlYWs7DQotCQlwUmVzdWx0W2ldID0gcEZyb21baV07DQotCX0NCi0NCi0JY2JGcm9tLlJlbGVhc2VCdWZmZXIoKTsNCi0JQ0ZYX1dpZGVTdHJpbmcgY2JSZXQgPSBDRlhfV2lkZVN0cmluZyhwUmVzdWx0KTsNCi0JZnJlZShwUmVzdWx0KTsNCi0JcFJlc3VsdCA9IE5VTEw7DQotCXJldHVybiBjYlJldDsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6cGF0aChPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAoIXZwLklzR2V0dGluZygpKSByZXR1cm4gRkFMU0U7DQotDQotCXZwIDw8IGFwcDo6U3lzUGF0aFRvUERGUGF0aChtX3BEb2N1bWVudC0+R2V0UGF0aCgpKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OnBhZ2VXaW5kb3dSZWN0KE9CSl9QUk9QX1BBUkFNUykNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpsYXlvdXQoT0JKX1BST1BfUEFSQU1TKQ0KLXsJDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjphZGRMaW5rKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0gCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpjbG9zZURvYyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0NCi0JDQotCQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6Z2V0UGFnZUJveChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotIAlyZXR1cm4gVFJVRTsNCi19DQotDQotDQotRlhfQk9PTCBEb2N1bWVudDo6Z2V0QW5ub3QoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLSAJcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmdldEFubm90cyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXZSZXQuU2V0TnVsbCgpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6Z2V0QW5ub3QzRChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXZSZXQuU2V0TnVsbCgpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6Z2V0QW5ub3RzM0QoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQl2UmV0ID0gVlRfdW5kZWZpbmVkOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6Z2V0T0NHcyhPQkpfTUVUSE9EX1BBUkFNUykNCi17CQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6Z2V0TGlua3MoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotYm9vbCBEb2N1bWVudDo6SXNFbmNsb3NlZEluUmVjdChDRlhfRmxvYXRSZWN0IHJlY3QsIENGWF9GbG9hdFJlY3QgTGlua1JlY3QpDQotew0KLQlpZiAocmVjdC5sZWZ0IDw9IExpbmtSZWN0LmxlZnQNCi0JICAmJiByZWN0LnRvcCA8PSBMaW5rUmVjdC50b3ANCi0JICAmJiByZWN0LnJpZ2h0ID49IExpbmtSZWN0LnJpZ2h0DQotCSAgJiYgcmVjdC5ib3R0b20gPj0gTGlua1JlY3QuYm90dG9tKQ0KLQkJcmV0dXJuIHRydWU7DQotCWVsc2UNCi0JCXJldHVybiBmYWxzZTsNCi19DQotDQotdm9pZCBJY29uVHJlZTo6SW5zZXJ0SWNvbkVsZW1lbnQoSWNvbkVsZW1lbnQqIHBOZXdJY29uKQ0KLXsNCi0JaWYgKCFwTmV3SWNvbilyZXR1cm47DQotDQotCWlmIChtX3BIZWFkID09IE5VTEwgJiYgbV9wRW5kID09IE5VTEwpDQotCXsNCi0JCW1fcEhlYWQgPSBtX3BFbmQgPSBwTmV3SWNvbjsNCi0JCW1faUxlbmd0aCsrOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJbV9wRW5kLT5OZXh0SWNvbiA9IHBOZXdJY29uOw0KLQkJbV9wRW5kID0gcE5ld0ljb247DQotCQltX2lMZW5ndGgrKzsNCi0JfQ0KLX0NCi0NCi12b2lkIEljb25UcmVlOjpEZWxldGVJY29uVHJlZSgpDQotew0KLQlpZiAoIW1fcEhlYWQgfHwgIW1fcEVuZClyZXR1cm47DQotCQ0KLQlJY29uRWxlbWVudCogcFRlbXAgPSBOVUxMOw0KLQl3aGlsZShtX3BFbmQgIT0gbV9wSGVhZCkNCi0Jew0KLQkJcFRlbXAgPSBtX3BIZWFkOw0KLQkJbV9wSGVhZCA9IG1fcEhlYWQtPk5leHRJY29uOw0KLQkJZGVsZXRlIHBUZW1wOw0KLQl9DQotDQotCWRlbGV0ZSBtX3BFbmQ7DQotCW1fcEhlYWQgPSBOVUxMOw0KLQltX3BFbmQgPSBOVUxMOw0KLX0NCi0NCi1pbnQgSWNvblRyZWU6OkdldExlbmd0aCgpDQotew0KLQlyZXR1cm4gbV9pTGVuZ3RoOw0KLX0NCi0NCi1JY29uRWxlbWVudCogSWNvblRyZWU6Om9wZXJhdG9yIFtdKGludCBpSW5kZXgpDQotew0KLQlpZiAoaUluZGV4ID49IDAgJiYgaUluZGV4IDw9IG1faUxlbmd0aCkNCi0Jew0KLQkJSWNvbkVsZW1lbnQqIHBUZW1wID0gbV9wSGVhZDsNCi0JCWZvciAoaW50IGkgPSAwOyBpIDwgaUluZGV4OyBpKyspDQotCQl7DQotCQkJcFRlbXAgPSBwVGVtcC0+TmV4dEljb247DQotCQl9DQotCQlyZXR1cm4gcFRlbXA7DQotCX0NCi0JZWxzZQ0KLQkJcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLXZvaWQgSWNvblRyZWU6OkRlbGV0ZUljb25FbGVtZW50KENGWF9XaWRlU3RyaW5nIHN3SWNvbk5hbWUpDQotew0KLQlJY29uRWxlbWVudCogcFRlbXAgPSBtX3BIZWFkOw0KLQlpbnQgaUxvb3BDb3VudCA9IG1faUxlbmd0aDsgDQotCWZvciAoaW50IGkgPSAwOyBpIDwgaUxvb3BDb3VudCAtIDE7IGkrKykNCi0Jew0KLQkJaWYgKHBUZW1wID09IG1fcEVuZCkNCi0JCQlicmVhazsNCi0JDQotCQlpZiAobV9wSGVhZC0+SWNvbk5hbWUgPT0gc3dJY29uTmFtZSkNCi0JCXsNCi0JCQltX3BIZWFkID0gbV9wSGVhZC0+TmV4dEljb247DQotCQkJZGVsZXRlIHBUZW1wOw0KLQkJCW1faUxlbmd0aC0tOw0KLQkJCXBUZW1wID0gbV9wSGVhZDsNCi0JCX0NCi0JCWlmIChwVGVtcC0+TmV4dEljb24tPkljb25OYW1lID09IHN3SWNvbk5hbWUpDQotCQl7DQotCQkJaWYgKHBUZW1wLT5OZXh0SWNvbiA9PSBtX3BFbmQpDQotCQkJew0KLQkJCQltX3BFbmQgPSBwVGVtcDsNCi0JCQkJZGVsZXRlIHBUZW1wLT5OZXh0SWNvbjsNCi0JCQkJbV9pTGVuZ3RoLS07DQotCQkJCXBUZW1wLT5OZXh0SWNvbiA9IE5VTEw7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCUljb25FbGVtZW50KiBwRWxlbWVudCA9IHBUZW1wLT5OZXh0SWNvbjsNCi0JCQkJcFRlbXAtPk5leHRJY29uID0gcFRlbXAtPk5leHRJY29uLT5OZXh0SWNvbjsNCi0JCQkJZGVsZXRlIHBFbGVtZW50Ow0KLQkJCQltX2lMZW5ndGgtLTsNCi0JCQkJcEVsZW1lbnQgPSBOVUxMOw0KLQkJCX0NCi0NCi0JCQljb250aW51ZTsNCi0JCX0NCi0NCi0JCXBUZW1wID0gcFRlbXAtPk5leHRJY29uOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmFkZEljb24oT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSAyKXJldHVybiBGQUxTRTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc3dJY29uTmFtZSA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQkNCi0JSlNGWE9iamVjdCBwSlNJY29uID0gKEpTRlhPYmplY3QpcGFyYW1zWzFdOw0KLQlpZiAoSlNfR2V0T2JqRGVmbklEKHBKU0ljb24pICE9IEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiSWNvbiIpKSByZXR1cm4gRkFMU0U7DQotDQotCUNKU19FbWJlZE9iaiogcEVtYmVkT2JqID0gKChDSlNfT2JqZWN0KilwYXJhbXNbMV0pLT5HZXRFbWJlZE9iamVjdCgpOw0KLQlpZiAoIXBFbWJlZE9iailyZXR1cm4gRkFMU0U7DQotCUljb24qIHBJY29uID0gKEljb24qKXBFbWJlZE9iajsNCi0NCi0JaWYgKCFtX3BJY29uVHJlZSkNCi0JCW1fcEljb25UcmVlID0gbmV3IEljb25UcmVlKCk7DQotDQotCUljb25FbGVtZW50KiBwTmV3SWNvbiA9IG5ldyBJY29uRWxlbWVudCgpOw0KLQlwTmV3SWNvbi0+SWNvbk5hbWUgPSBzd0ljb25OYW1lOw0KLQlwTmV3SWNvbi0+TmV4dEljb24gPSBOVUxMOw0KLQlwTmV3SWNvbi0+SWNvblN0cmVhbSA9IHBJY29uOw0KLQltX3BJY29uVHJlZS0+SW5zZXJ0SWNvbkVsZW1lbnQocE5ld0ljb24pOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6aWNvbnMoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAoIW1fcEljb25UcmVlKQ0KLQl7DQotCQl2cC5TZXROdWxsKCk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlDSlNfQXJyYXkgSWNvbnMobV9pc29sYXRlKTsNCi0JSWNvbkVsZW1lbnQqIHBJY29uRWxlbWVudCA9IE5VTEw7DQotCWludCBpSWNvblRyZWVMZW5ndGggPSBtX3BJY29uVHJlZS0+R2V0TGVuZ3RoKCk7DQotDQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotDQotCWZvciAoaW50IGkgPSAwOyBpIDwgaUljb25UcmVlTGVuZ3RoOyBpKyspDQotCXsNCi0JCXBJY29uRWxlbWVudCA9ICgqbV9wSWNvblRyZWUpW2ldOw0KLQkJDQotCQlKU0ZYT2JqZWN0ICBwT2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgcENvbnRleHQsIEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiSWNvbiIpKTsNCi0JCWlmIChwT2JqLklzRW1wdHkoKSkgcmV0dXJuIEZBTFNFOw0KLQkJCQkNCi0JCUNKU19JY29uICogcEpTX0ljb24gPSAoQ0pTX0ljb24gKilKU19HZXRQcml2YXRlKHBPYmopOw0KLQkJaWYgKCFwSlNfSWNvbikgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJSWNvbiogcEljb24gPSAoSWNvbiopcEpTX0ljb24tPkdldEVtYmVkT2JqZWN0KCk7DQotCQlpZiAoIXBJY29uKXJldHVybiBGQUxTRTsNCi0NCi0JCXBJY29uLT5TZXRTdHJlYW0ocEljb25FbGVtZW50LT5JY29uU3RyZWFtLT5HZXRTdHJlYW0oKSk7DQotCQlwSWNvbi0+U2V0SWNvbk5hbWUocEljb25FbGVtZW50LT5JY29uTmFtZSk7DQotCQlJY29ucy5TZXRFbGVtZW50KGksIENKU19WYWx1ZShtX2lzb2xhdGUscEpTX0ljb24pKTsNCi0JfQ0KLQ0KLQl2cCA8PCBJY29uczsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmdldEljb24oT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSAxKXJldHVybiBGQUxTRTsNCi0JaWYoIW1fcEljb25UcmVlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfV2lkZVN0cmluZyBzd0ljb25OYW1lID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotCWludCBpSWNvbkNvdW50cyA9IG1fcEljb25UcmVlLT5HZXRMZW5ndGgoKTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsNCi0NCi0JZm9yIChpbnQgaSA9IDA7IGkgPCBpSWNvbkNvdW50czsgaSsrKQ0KLQl7DQotCQlpZiAoKCptX3BJY29uVHJlZSlbaV0tPkljb25OYW1lID09IHN3SWNvbk5hbWUpDQotCQl7DQotCQkJSWNvbiogcFJldEljb24gPSAoKm1fcEljb25UcmVlKVtpXS0+SWNvblN0cmVhbTsNCi0JCQkJDQotCQkJSlNGWE9iamVjdCAgcE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIkljb24iKSk7DQotCQkJaWYgKHBPYmouSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7DQotCQkJCQkNCi0JCQlDSlNfSWNvbiAqIHBKU19JY29uID0gKENKU19JY29uICopSlNfR2V0UHJpdmF0ZShwT2JqKTsNCi0JCQlpZiAoIXBKU19JY29uKSByZXR1cm4gRkFMU0U7DQotDQotCQkJSWNvbiogcEljb24gPSAoSWNvbiopcEpTX0ljb24tPkdldEVtYmVkT2JqZWN0KCk7DQotCQkJaWYgKCFwSWNvbilyZXR1cm4gRkFMU0U7DQotDQotCQkJcEljb24tPlNldEljb25OYW1lKHN3SWNvbk5hbWUpOw0KLQkJCXBJY29uLT5TZXRTdHJlYW0ocFJldEljb24tPkdldFN0cmVhbSgpKTsNCi0JCQl2UmV0ID0gcEpTX0ljb247DQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpyZW1vdmVJY29uKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMSlyZXR1cm4gRkFMU0U7DQotCWlmKCFtX3BJY29uVHJlZSkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ0ZYX1dpZGVTdHJpbmcgc3dJY29uTmFtZSA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLSNpZm5kZWYgRk9YSVRfQ0hST01FX0JVSUxEDQotCW1fcEljb25UcmVlLT5EZWxldGVJY29uRWxlbWVudChzd0ljb25OYW1lKTsNCi0jZW5kaWYNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmNyZWF0ZURhdGFPYmplY3QoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpZiAoSXNTYWZlTW9kZShjYykpIHJldHVybiBUUlVFOw0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUNGWF9XaWRlU3RyaW5nIHN3TmFtZSA9IEwiIjsNCi0JQ0ZYX0J5dGVTdHJpbmcgc2JOYW1lID0gIiI7DQotCUNGWF9XaWRlU3RyaW5nIHN3VmFsdWUgPSBMIiI7DQotCUNGWF9XaWRlU3RyaW5nIHN3TUlNRVR5cGUgPSBMIiI7DQotCUNGWF9XaWRlU3RyaW5nIHN3Q3J5cHRGaWx0ZXIgPSBMIiI7DQotCUNGWF9CeXRlU3RyaW5nIHNiRmlsZVZhbHVlID0gIiI7DQotCQ0KLQlpbnQgaVBhcmFtU2l6ZSA9IHBhcmFtcy5zaXplKCk7DQotCWZvciAoaW50IGkgPSAwOyBpIDwgaVBhcmFtU2l6ZTsgaSsrKQ0KLQl7DQotCQlpZiAoaSA9PSAwKQ0KLQkJCXN3TmFtZSA9IHBhcmFtc1swXTsNCi0JCWlmIChpID09IDEpDQotCQkJc3dWYWx1ZSA9IHBhcmFtc1sxXTsNCi0JCWlmIChpID09IDIpDQotCQkJc3dNSU1FVHlwZSA9IHBhcmFtc1syXTsNCi0JCWlmIChpID09IDMpDQotCQkJc3dDcnlwdEZpbHRlciA9IHBhcmFtc1s0XTsNCi0JfQ0KLQ0KLQlGSUxFKiBwRmlsZSA9IE5VTEw7DQotDQotCS8vQ0ZpbGVTdGF0dXMgZmlsZVN0YXR1czsNCi0JY29uc3QgaW50IEJVRlNJWkUgPSAxNzsNCi0JRlhfQllURSBidWZbQlVGU0laRV07DQotCUZYX0JZVEUgKnBCdWZmZXIgPSBOVUxMOw0KLQljaGFyKiBwQnVmID0gTlVMTDsNCi0JaW50IG5GaWxlU2l6ZSA9IDA7DQotCXNiRmlsZVZhbHVlID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHN3VmFsdWUpOw0KLQlzYk5hbWUgPSBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoc3dOYW1lKTsNCi0JaW50IGlCdWZMZW5ndGggPSBzYkZpbGVWYWx1ZS5HZXRMZW5ndGgoKTsNCi0JcEJ1ZiA9IChjaGFyKiltYWxsb2Moc2l6ZW9mKGNoYXIpICogaUJ1Zkxlbmd0aCk7DQotCXBCdWYgPSBzYkZpbGVWYWx1ZS5HZXRCdWZmZXIoaUJ1Zkxlbmd0aCk7DQotDQotCWlmICggTlVMTCA9PSAocEZpbGUgPSBGWFNZU19mb3Blbiggc2JOYW1lLkdldEJ1ZmZlcihzYk5hbWUuR2V0TGVuZ3RoKCkpLCAid2IrIiApKSApDQotCXsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlmd3JpdGUoIHBCdWYsIHNpemVvZihjaGFyKSwgaUJ1Zkxlbmd0aCwgcEZpbGUgKTsNCi0JZmNsb3NlKCBwRmlsZSApOw0KLQlwRmlsZSA9IE5VTEw7DQotDQotCXBGaWxlID0gRlhTWVNfZm9wZW4oIHNiTmFtZS5HZXRCdWZmZXIoc2JOYW1lLkdldExlbmd0aCgpKSwgInJiKyIgKTsNCi0JZnNlZWsoIHBGaWxlLCAwLCBTRUVLX0VORCApOw0KLQluRmlsZVNpemUgPSBmdGVsbCggcEZpbGUgKTsNCi0NCi0JcEJ1ZmZlciA9IG5ldyBGWF9CWVRFW25GaWxlU2l6ZV07DQotCWZzZWVrKCBwRmlsZSwgMCwgU0VFS19TRVQgKTsNCi0Jc2l6ZV90IHMgPSBmcmVhZCggcEJ1ZmZlciwgc2l6ZW9mKGNoYXIpLCBuRmlsZVNpemUsIHBGaWxlICk7DQotCWlmKHMgPT0gMCkNCi0Jew0KLQkJZGVsZXRlW10gcEJ1ZmZlcjsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlDUllQVF9NRDVHZW5lcmF0ZShwQnVmZmVyLCBuRmlsZVNpemUsIGJ1Zik7DQotCWJ1ZltCVUZTSVpFIC0gMV0gPSAwOw0KLQlDRlhfV2lkZVN0cmluZyBjc0NoZWNrU3VtKChGWF9MUENXU1RSKWJ1ZiwgMTYpOw0KLQlkZWxldGVbXSBwQnVmZmVyOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6bWVkaWEoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmNhbGN1bGF0ZU5vdyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKCEobV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkgfHwgDQotCQltX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fQU5OT1RfRk9STSkgfHwNCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9GSUxMX0ZPUk0pKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0JcEludGVyRm9ybS0+T25DYWxjdWxhdGUoKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OkNvbGxhYihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6Z2V0UGFnZU50aFdvcmQoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQkvL2lmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7DQotDQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fRVhUUkFDVF9BQ0NFU1MpKSByZXR1cm4gRkFMU0U7DQotDQotCWludCBuUGFnZU5vID0gcGFyYW1zLkdldFNpemUoKSA+IDAgPyAoaW50KXBhcmFtc1swXSA6IDA7DQotCWludCBuV29yZE5vID0gcGFyYW1zLkdldFNpemUoKSA+IDEgPyAoaW50KXBhcmFtc1sxXSA6IDA7DQotCWJvb2wgYlN0cmlwID0gcGFyYW1zLkdldFNpemUoKSA+IDIgPyAoYm9vbClwYXJhbXNbMl0gOiB0cnVlOw0KLQ0KLQlDUERGX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKTsNCi0JaWYgKCFwRG9jdW1lbnQpIHJldHVybiBGQUxTRTsNCi0NCi0JaWYgKG5QYWdlTm8gPCAwIHx8IG5QYWdlTm8gPj0gcERvY3VtZW50LT5HZXRQYWdlQ291bnQoKSkNCi0Jew0KLQkJLy9zRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JQ1BERl9EaWN0aW9uYXJ5KiBwUGFnZURpY3QgPSBwRG9jdW1lbnQtPkdldFBhZ2UoblBhZ2VObyk7DQotCWlmICghcFBhZ2VEaWN0KSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfUGFnZSBwYWdlOw0KLQlwYWdlLkxvYWQocERvY3VtZW50LCBwUGFnZURpY3QpOw0KLQlwYWdlLlN0YXJ0UGFyc2UoKTsNCi0JcGFnZS5QYXJzZUNvbnRlbnQoKTsNCi0NCi0JRlhfUE9TSVRJT04gcG9zID0gcGFnZS5HZXRGaXJzdE9iamVjdFBvc2l0aW9uKCk7DQotDQotCWludCBuV29yZHMgPSAwOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzd1JldDsNCi0NCi0Jd2hpbGUgKHBvcykNCi0Jew0KLQkJaWYgKENQREZfUGFnZU9iamVjdCogcFBhZ2VPYmogPSBwYWdlLkdldE5leHRPYmplY3QocG9zKSkNCi0JCXsNCi0JCQlpZiAocFBhZ2VPYmotPm1fVHlwZSA9PSBQREZQQUdFX1RFWFQpDQotCQkJew0KLQkJCQlpbnQgbk9ialdvcmRzID0gQ291bnRXb3JkcygoQ1BERl9UZXh0T2JqZWN0KilwUGFnZU9iaik7DQotDQotCQkJCWlmIChuV29yZHMgKyBuT2JqV29yZHMgPj0gbldvcmRObykNCi0JCQkJew0KLQkJCQkJc3dSZXQgPSBHZXRPYmpXb3JkU3RyKChDUERGX1RleHRPYmplY3QqKXBQYWdlT2JqLCBuV29yZE5vIC0gbldvcmRzKTsNCi0JCQkJCWJyZWFrOw0KLQkJCQl9DQotDQotCQkJCW5Xb3JkcyArPSBuT2JqV29yZHM7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCWlmIChiU3RyaXApDQotCXsNCi0JCXN3UmV0LlRyaW1MZWZ0KCk7DQotCQlzd1JldC5UcmltUmlnaHQoKTsNCi0JfQ0KLQ0KLQl2UmV0ID0gc3dSZXQ7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpnZXRQYWdlTnRoV29yZFF1YWRzKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JLy9pZiAoSXNTYWZlTW9kZShjYykpIHJldHVybiBUUlVFOw0KLQ0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0VYVFJBQ1RfQUNDRVNTKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmdldFBhZ2VOdW1Xb3JkcyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fRVhUUkFDVF9BQ0NFU1MpKSByZXR1cm4gRkFMU0U7DQotDQotCWludCBuUGFnZU5vID0gcGFyYW1zLkdldFNpemUoKSA+IDAgPyAoaW50KXBhcmFtc1swXSA6IDA7DQotDQotCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpOw0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoblBhZ2VObyA8IDAgfHwgblBhZ2VObyA+PSBwRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpKQ0KLQl7DQotCQkvL3NFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBEb2N1bWVudC0+R2V0UGFnZShuUGFnZU5vKTsNCi0JaWYgKCFwUGFnZURpY3QpIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BERl9QYWdlIHBhZ2U7DQotCXBhZ2UuTG9hZChwRG9jdW1lbnQsIHBQYWdlRGljdCk7DQotCXBhZ2UuU3RhcnRQYXJzZSgpOw0KLQlwYWdlLlBhcnNlQ29udGVudCgpOw0KLQ0KLQlGWF9QT1NJVElPTiBwb3MgPSBwYWdlLkdldEZpcnN0T2JqZWN0UG9zaXRpb24oKTsNCi0NCi0JaW50IG5Xb3JkcyA9IDA7DQotDQotCXdoaWxlIChwb3MpDQotCXsNCi0JCWlmIChDUERGX1BhZ2VPYmplY3QqIHBQYWdlT2JqID0gcGFnZS5HZXROZXh0T2JqZWN0KHBvcykpDQotCQl7DQotCQkJaWYgKHBQYWdlT2JqLT5tX1R5cGUgPT0gUERGUEFHRV9URVhUKQ0KLQkJCXsNCi0JCQkJQ1BERl9UZXh0T2JqZWN0KiBwVGV4dE9iaiA9IChDUERGX1RleHRPYmplY3QqKXBQYWdlT2JqOw0KLQkJCQluV29yZHMgKz0gQ291bnRXb3JkcyhwVGV4dE9iaik7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCXZSZXQgPSBuV29yZHM7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpnZXRQcmludFBhcmFtcyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotCUpTRlhPYmplY3QgcFJldE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIlByaW50UGFyYW1zT2JqIikpOw0KLQkvL25vdCBpbXBsZW1lbnRlZCB5ZXQuDQotCXZSZXQgPSBwUmV0T2JqOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotI2RlZmluZSBJU0xBVElOV09SRCh1KQkodSAhPSAweDIwICYmIHUgPD0gMHgyOEZGKQ0KLQ0KLWludAlEb2N1bWVudDo6Q291bnRXb3JkcyhDUERGX1RleHRPYmplY3QqIHBUZXh0T2JqKQ0KLXsNCi0JaWYgKCFwVGV4dE9iaikgcmV0dXJuIDA7DQotDQotCWludCBuV29yZHMgPSAwOw0KLQ0KLQlDUERGX0ZvbnQqIHBGb250ID0gcFRleHRPYmotPkdldEZvbnQoKTsNCi0JaWYgKCFwRm9udCkgcmV0dXJuIDA7DQotDQotCUZYX0JPT0wgYklzTGF0aW4gPSBGQUxTRTsNCi0NCi0JZm9yIChpbnQgaT0wLCBzej1wVGV4dE9iai0+Q291bnRDaGFycygpOyBpPHN6OyBpKyspDQotCXsNCi0JCUZYX0RXT1JEIGNoYXJjb2RlID0gLTE7DQotCQlGWF9GTE9BVCBrZXJuaW5nOw0KLQ0KLQkJcFRleHRPYmotPkdldENoYXJJbmZvKGksIGNoYXJjb2RlLCBrZXJuaW5nKTsNCi0JCUNGWF9XaWRlU3RyaW5nIHN3VW5pY29kZSA9IHBGb250LT5Vbmljb2RlRnJvbUNoYXJDb2RlKGNoYXJjb2RlKTsNCi0NCi0JCUZYX1dPUkQgdW5pY29kZSA9IDA7DQotCQlpZiAoc3dVbmljb2RlLkdldExlbmd0aCgpID4gMCkNCi0JCQl1bmljb2RlID0gc3dVbmljb2RlWzBdOw0KLQ0KLQkJaWYgKElTTEFUSU5XT1JEKHVuaWNvZGUpICYmIGJJc0xhdGluKQ0KLQkJCWNvbnRpbnVlOw0KLQkJDQotCQliSXNMYXRpbiA9IElTTEFUSU5XT1JEKHVuaWNvZGUpOw0KLQkJaWYgKHVuaWNvZGUgIT0gMHgyMCkNCi0JCQluV29yZHMrKzsNCi0JfQ0KLQ0KLQlyZXR1cm4gbldvcmRzOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBEb2N1bWVudDo6R2V0T2JqV29yZFN0cihDUERGX1RleHRPYmplY3QqIHBUZXh0T2JqLCBpbnQgbldvcmRJbmRleCkNCi17DQotCUFTU0VSVChwVGV4dE9iaiAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc3dSZXQ7DQotDQotCUNQREZfRm9udCogcEZvbnQgPSBwVGV4dE9iai0+R2V0Rm9udCgpOw0KLQlpZiAoIXBGb250KSByZXR1cm4gTCIiOw0KLQ0KLQlpbnQgbldvcmRzID0gMDsNCi0JRlhfQk9PTCBiSXNMYXRpbiA9IEZBTFNFOw0KLQ0KLQlmb3IgKGludCBpPTAsIHN6PXBUZXh0T2JqLT5Db3VudENoYXJzKCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJRlhfRFdPUkQgY2hhcmNvZGUgPSAtMTsNCi0JCUZYX0ZMT0FUIGtlcm5pbmc7DQotDQotCQlwVGV4dE9iai0+R2V0Q2hhckluZm8oaSwgY2hhcmNvZGUsIGtlcm5pbmcpOw0KLQkJQ0ZYX1dpZGVTdHJpbmcgc3dVbmljb2RlID0gcEZvbnQtPlVuaWNvZGVGcm9tQ2hhckNvZGUoY2hhcmNvZGUpOw0KLQ0KLQkJRlhfV09SRCB1bmljb2RlID0gMDsNCi0JCWlmIChzd1VuaWNvZGUuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCXVuaWNvZGUgPSBzd1VuaWNvZGVbMF07DQotDQotCQlpZiAoSVNMQVRJTldPUkQodW5pY29kZSkgJiYgYklzTGF0aW4pDQotCQl7DQotCQl9DQotCQllbHNlDQotCQl7CQkNCi0JCQliSXNMYXRpbiA9IElTTEFUSU5XT1JEKHVuaWNvZGUpOw0KLQkJCWlmICh1bmljb2RlICE9IDB4MjApDQotCQkJCW5Xb3JkcysrOwkNCi0JCX0NCi0NCi0JCWlmIChuV29yZHMtMSA9PSBuV29yZEluZGV4KQ0KLQkJCXN3UmV0ICs9IHVuaWNvZGU7DQotCX0NCi0NCi0JcmV0dXJuIHN3UmV0Ow0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50Ojp6b29tKE9CSl9QUk9QX1BBUkFNUykNCi17DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0vKioNCi0obm9uZSwJTm9WYXJ5KQ0KLShmaXRQLAlGaXRQYWdlKQ0KLShmaXRXLAlGaXRXaWR0aCkNCi0oZml0SCwJRml0SGVpZ2h0KQ0KLShmaXRWLAlGaXRWaXNpYmxlV2lkdGgpDQotKHByZWYsCVByZWZlcnJlZCkNCi0ocmVmVywJUmVmbG93V2lkdGgpDQotKi8NCi0NCi1GWF9CT09MIERvY3VtZW50Ojp6b29tVHlwZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6ZGVsZXRlUGFnZXMoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQkNCi0NCi0JDQotCQ0KLQ0KLQ0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOw0KLS8vIAlpZiAocEVudi0+R2V0QXBwTmFtZSgpLkNvbXBhcmUoUEhBTlRPTSkgIT0gMCkNCi0vLyAJCXJldHVybiBUUlVFOw0KLQ0KLQkvL2lmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7DQotDQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKCEobV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkgfHwgDQotCQltX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fQVNTRU1CTEUpKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOw0KLQkNCi0JaW50IG5TdGFydCA9IDA7DQotCWludCBuRW5kID0gMDsNCi0JDQotCWlmIChpU2l6ZSA8IDEpDQotCXsNCi0JfQ0KLQllbHNlIGlmIChpU2l6ZSA9PSAxKQ0KLQl7DQotCQlpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9vYmplY3QpDQotCQl7DQotCQkJSlNPYmplY3QgIHBPYmogPSAoSlNPYmplY3QgKXBhcmFtc1swXTsNCi0JCQl2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiblN0YXJ0Iik7DQotCQkJCW5TdGFydCA9IChpbnQpQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7DQotDQotCQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwibkVuZCIpOw0KLQkJCQluRW5kID0gKGludClDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQluU3RhcnQgPSAoaW50KXBhcmFtc1swXTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCW5TdGFydCA9IChpbnQpcGFyYW1zWzBdOw0KLQkJbkVuZCA9IChpbnQpcGFyYW1zWzFdOw0KLQl9DQotDQotCWludCBuVG90YWwgPSBtX3BEb2N1bWVudC0+R2V0UGFnZUNvdW50KCk7DQotDQotCWlmIChuU3RhcnQgPCAwKQluU3RhcnQgPSAwOw0KLQlpZiAoblN0YXJ0ID49IG5Ub3RhbCkgblN0YXJ0ID0gblRvdGFsIC0gMTsNCi0NCi0JaWYgKG5FbmQgPCAwKSBuRW5kID0gMDsNCi0JaWYgKG5FbmQgPj0gblRvdGFsKSBuRW5kID0gblRvdGFsIC0gMTsNCi0NCi0JaWYgKG5FbmQgPCBuU3RhcnQpIG5FbmQgPSBuU3RhcnQ7DQotDQotCQ0KLQ0KLSNpZm5kZWYgRk9YSVRfQ0hST01FX0JVSUxEDQotCXJldHVybiBtX3BEb2N1bWVudC0+RGVsZXRlUGFnZXMoblN0YXJ0LCBuRW5kIC0gblN0YXJ0ICsgMSk7DQotI2Vsc2UNCi0JcmV0dXJuIFRSVUU7DQotI2VuZGlmDQotfQ0KLQ0KLUZYX0JPT0wgRG9jdW1lbnQ6OmV4dHJhY3RQYWdlcyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCQ0KLQ0KLQkNCi0JDQotCQ0KLQ0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOw0KLQ0KLQlpZiAoSXNTYWZlTW9kZShjYykpIHJldHVybiBUUlVFOw0KLQ0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0VYVFJBQ1QpKSByZXR1cm4gRkFMU0U7DQotDQotCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7DQotCQ0KLQlpbnQgblRvdGFsID0gbV9wRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpOw0KLQlpbnQgblN0YXJ0ID0gMDsNCi0JaW50IG5FbmQgPSBuVG90YWwgLSAxOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzd0ZpbGVQYXRoOw0KLQkNCi0JaWYgKGlTaXplIDwgMSkNCi0Jew0KLQl9DQotCWVsc2UgaWYgKGlTaXplID09IDEpDQotCXsNCi0JCWlmIChwYXJhbXNbMF0uR2V0VHlwZSgpID09IFZUX29iamVjdCkNCi0JCXsNCi0JCQlKU09iamVjdCAgcE9iaiA9IChKU09iamVjdCApcGFyYW1zWzBdOw0KLQkJCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuU3RhcnQiKTsNCi0JCQkJblN0YXJ0ID0gKGludClDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsNCi0NCi0JCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuRW5kIik7DQotCQkJCW5FbmQgPSAoaW50KUNKU19WYWx1ZShtX2lzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOw0KLQ0KLQkJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNQYXRoIik7DQotCQkJCXN3RmlsZVBhdGggPSBDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCW5TdGFydCA9IChpbnQpcGFyYW1zWzBdOw0KLQkJfQ0KLQl9DQotCWVsc2UgaWYgKGlTaXplID09IDIpDQotCXsNCi0JCW5TdGFydCA9IChpbnQpcGFyYW1zWzBdOw0KLQkJbkVuZCA9IChpbnQpcGFyYW1zWzFdOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJblN0YXJ0ID0gKGludClwYXJhbXNbMF07DQotCQluRW5kID0gKGludClwYXJhbXNbMV07DQotCQlzd0ZpbGVQYXRoID0gcGFyYW1zWzJdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotCX0NCi0NCi0JaWYgKG5FbmQgPCBuU3RhcnQpDQotCQluRW5kID0gblN0YXJ0Ow0KLQ0KLQlDUERGX0RvY3VtZW50ICpwTmV3RG9jID0gbmV3IENQREZfRG9jdW1lbnQ7DQotCXBOZXdEb2MtPkNyZWF0ZU5ld0RvYygpOwkNCi0NCi0JQ0ZYX1dvcmRBcnJheSBhcnJheTsNCi0JZm9yIChpbnQgaT1uU3RhcnQ7IGk8PW5FbmQ7IGkrKykNCi0JCWFycmF5LkFkZChpKTsNCi0NCi0vLwltX3BEb2N1bWVudC0+RXh0cmFjdFBhZ2VzKGFycmF5LCBwTmV3RG9jKTsNCi0NCi0JaWYgKHN3RmlsZVBhdGguSXNFbXB0eSgpKQ0KLQl7DQotDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlzd0ZpbGVQYXRoID0gYXBwOjpQREZQYXRoVG9TeXNQYXRoKHN3RmlsZVBhdGgpOw0KLQkJQ1BERl9DcmVhdG9yIFBERkNyZWF0ZXIocE5ld0RvYyk7DQotCQlQREZDcmVhdGVyLkNyZWF0ZShzd0ZpbGVQYXRoKTsNCi0JCWRlbGV0ZSBwTmV3RG9jOw0KLS8vCQlwRW52LT5PcGVuRG9jdW1lbnQoc3dGaWxlUGF0aCk7DQotCQl2UmV0LlNldE51bGwoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBEb2N1bWVudDo6aW5zZXJ0UGFnZXMoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQ0KLQ0KLQkNCi0NCi0NCi0NCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsNCi0NCi0JaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsNCi0NCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCANCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BU1NFTUJMRSkpKSByZXR1cm4gRkFMU0U7DQotDQotCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7DQotCQ0KLQlpbnQgblN0YXJ0ID0gMDsNCi0JaW50IG5FbmQgPSAwOw0KLQlpbnQgblBhZ2UgPSAwOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzd0ZpbGVQYXRoOw0KLQkNCi0JaWYgKGlTaXplIDwgMSkNCi0Jew0KLQl9DQotCWVsc2UgaWYgKGlTaXplID09IDEpDQotCXsNCi0JCWlmIChwYXJhbXNbMF0uR2V0VHlwZSgpID09IFZUX29iamVjdCkNCi0JCXsNCi0JCQlKU09iamVjdCAgcE9iaiA9IChKU09iamVjdCApcGFyYW1zWzBdOw0KLQ0KLQkJCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuUGFnZSIpOw0KLQkJCQluUGFnZSA9IChpbnQpQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7DQotDQotCQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiY1BhdGgiKTsNCi0JCQkJc3dGaWxlUGF0aCA9IENKU19WYWx1ZShtX2lzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiblN0YXJ0Iik7DQotCQkJCW5TdGFydCA9IChpbnQpQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7DQotDQotCQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwibkVuZCIpOw0KLQkJCQluRW5kID0gKGludClDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQluUGFnZSA9IChpbnQpcGFyYW1zWzBdOw0KLQkJfQ0KLQl9DQotCWVsc2UgDQotCXsNCi0JCW5QYWdlID0gKGludClwYXJhbXNbMF07DQotDQotCQlpZiAoaVNpemUgPj0gMikNCi0JCQlzd0ZpbGVQYXRoID0gcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCQlpZiAoaVNpemUgPj0gMykNCi0JCQluU3RhcnQgPSAoaW50KXBhcmFtc1syXTsNCi0NCi0JCWlmIChpU2l6ZSA+PSA0KQ0KLQkJCW5FbmQgPSAoaW50KXBhcmFtc1szXTsNCi0JfQ0KLQ0KLQluUGFnZSsrOw0KLQ0KLQlpZiAoblBhZ2UgPCAwKQ0KLQkJblBhZ2UgPSAwOw0KLQ0KLQlpZiAoblBhZ2UgPiBtX3BEb2N1bWVudC0+R2V0UGFnZUNvdW50KCkpDQotCQluUGFnZSA9IG1fcERvY3VtZW50LT5HZXRQYWdlQ291bnQoKTsNCi0NCi0JaWYgKHN3RmlsZVBhdGguSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7DQotDQotCXN3RmlsZVBhdGggPSBhcHA6OlBERlBhdGhUb1N5c1BhdGgoc3dGaWxlUGF0aCk7DQotDQotCUNQREZfUGFyc2VyIHBkZlBhcnNlcjsNCi0JcGRmUGFyc2VyLlN0YXJ0UGFyc2Uoc3dGaWxlUGF0aCwgRkFMU0UpOw0KLQlDUERGX0RvY3VtZW50KiBwU3JjRG9jID0gcGRmUGFyc2VyLkdldERvY3VtZW50KCk7DQotDQotCWlmICghcFNyY0RvYykgDQotCXsNCi0JCXBkZlBhcnNlci5DbG9zZVBhcnNlcigpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCWludCBuVG90YWwgPSBwU3JjRG9jLT5HZXRQYWdlQ291bnQoKTsNCi0NCi0JaWYgKG5TdGFydCA8IDApCW5TdGFydCA9IDA7DQotCWlmIChuU3RhcnQgPj0gblRvdGFsKSBuU3RhcnQgPSBuVG90YWwgLSAxOw0KLQ0KLQlpZiAobkVuZCA8IDApIG5FbmQgPSAwOw0KLQlpZiAobkVuZCA+PSBuVG90YWwpIG5FbmQgPSBuVG90YWwgLSAxOw0KLQ0KLQlpZiAobkVuZCA8IG5TdGFydCkgbkVuZCA9IG5TdGFydDsNCi0NCi0JQ0ZYX1dvcmRBcnJheSBhcnJheTsNCi0JZm9yIChpbnQgaT1uU3RhcnQ7IGk8PW5FbmQ7IGkrKykNCi0JCWFycmF5LkFkZChpKTsNCi0NCi0vLwltX3BEb2N1bWVudC0+SW5zZXJ0UGFnZXMoblBhZ2UsIHBTcmNEb2MsIGFycmF5KTsNCi0NCi0JcGRmUGFyc2VyLkNsb3NlUGFyc2VyKCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpyZXBsYWNlUGFnZXMoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQ0KLQ0KLQkNCi0NCi0NCi0NCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsNCi0NCi0JaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsNCi0NCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCANCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BU1NFTUJMRSkpKSByZXR1cm4gRkFMU0U7DQotDQotCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7DQotCQ0KLQlpbnQgblN0YXJ0ID0gLTE7DQotCWludCBuRW5kID0gLTE7DQotCWludCBuUGFnZSA9IDA7DQotDQotCUNGWF9XaWRlU3RyaW5nIHN3RmlsZVBhdGg7DQotCQ0KLQlpZiAoaVNpemUgPCAxKQ0KLQl7DQotCX0NCi0JZWxzZSBpZiAoaVNpemUgPT0gMSkNCi0Jew0KLQkJaWYgKHBhcmFtc1swXS5HZXRUeXBlKCkgPT0gVlRfb2JqZWN0KQ0KLQkJew0KLQkJCUpTT2JqZWN0ICBwT2JqID0gKEpTT2JqZWN0IClwYXJhbXNbMF07DQotDQotCQkJdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMIm5QYWdlIik7DQotCQkJCW5QYWdlID0gKGludClDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsNCi0NCi0JCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjUGF0aCIpOw0KLQkJCQlzd0ZpbGVQYXRoID0gQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0NCi0JCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuU3RhcnQiKTsNCi0JCQkJblN0YXJ0ID0gKGludClDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsNCi0NCi0JCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuRW5kIik7DQotCQkJCW5FbmQgPSAoaW50KUNKU19WYWx1ZShtX2lzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCW5QYWdlID0gKGludClwYXJhbXNbMF07DQotCQl9DQotCX0NCi0JZWxzZSANCi0Jew0KLQkJblBhZ2UgPSAoaW50KXBhcmFtc1swXTsNCi0NCi0JCWlmIChpU2l6ZSA+PSAyKQ0KLQkJCXN3RmlsZVBhdGggPSBwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0NCi0JCWlmIChpU2l6ZSA+PSAzKQ0KLQkJCW5TdGFydCA9IChpbnQpcGFyYW1zWzJdOw0KLQ0KLQkJaWYgKGlTaXplID49IDQpDQotCQkJbkVuZCA9IChpbnQpcGFyYW1zWzNdOw0KLQl9DQotDQotCWlmIChuUGFnZSA8IDApDQotCQluUGFnZSA9IDA7DQotDQotCWlmIChuUGFnZSA+PSBtX3BEb2N1bWVudC0+R2V0UGFnZUNvdW50KCkpDQotCQluUGFnZSA9IG1fcERvY3VtZW50LT5HZXRQYWdlQ291bnQoKSAtIDE7DQotDQotCWlmIChzd0ZpbGVQYXRoLklzRW1wdHkoKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlzd0ZpbGVQYXRoID0gYXBwOjpQREZQYXRoVG9TeXNQYXRoKHN3RmlsZVBhdGgpOw0KLQ0KLQlDUERGX1BhcnNlciBwZGZQYXJzZXI7DQotCXBkZlBhcnNlci5TdGFydFBhcnNlKHN3RmlsZVBhdGgsIEZBTFNFKTsNCi0JQ1BERl9Eb2N1bWVudCogcFNyY0RvYyA9IHBkZlBhcnNlci5HZXREb2N1bWVudCgpOw0KLQ0KLQlpZiAoIXBTcmNEb2MpIA0KLQl7DQotCQlwZGZQYXJzZXIuQ2xvc2VQYXJzZXIoKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlpbnQgblRvdGFsID0gcFNyY0RvYy0+R2V0UGFnZUNvdW50KCk7DQotDQotCWlmIChuU3RhcnQgPCAwKQ0KLQl7DQotCQlpZiAobkVuZCA8IDApDQotCQl7DQotCQkJblN0YXJ0ID0gMDsNCi0JCQluRW5kID0gblRvdGFsIC0gMTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQluU3RhcnQgPSAwOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKG5FbmQgPCAwKQ0KLQkJew0KLQkJCW5FbmQgPSBuU3RhcnQ7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYgKG5TdGFydCA+PSBuVG90YWwpIG5TdGFydCA9IG5Ub3RhbCAtIDE7DQotCQkJaWYgKG5FbmQgPj0gblRvdGFsKSBuRW5kID0gblRvdGFsIC0gMTsNCi0NCi0JCQlpZiAobkVuZCA8IG5TdGFydCkgbkVuZCA9IG5TdGFydDsNCi0JCX0NCi0JfQ0KLQ0KLQlDRlhfV29yZEFycmF5IGFycmF5Ow0KLQlmb3IgKGludCBpPW5TdGFydDsgaTw9bkVuZDsgaSsrKQ0KLQkJYXJyYXkuQWRkKGkpOw0KLQ0KLS8vCW1fcERvY3VtZW50LT5SZXBsYWNlUGFnZXMoblBhZ2UsIHBTcmNEb2MsIGFycmF5KTsNCi0NCi0JcGRmUGFyc2VyLkNsb3NlUGFyc2VyKCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIERvY3VtZW50OjpnZXRVUkwoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpZiAoSXNTYWZlTW9kZShjYykpIHJldHVybiBUUlVFOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBEb2N1bWVudDo6QWRkRGVsYXlEYXRhKENKU19EZWxheURhdGEqIHBEYXRhKQ0KLXsNCi0JbV9EZWxheURhdGEuQWRkKHBEYXRhKTsNCi19DQotDQotdm9pZCBEb2N1bWVudDo6RG9GaWVsZERlbGF5KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzRmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCkNCi17DQotCUNGWF9EV29yZEFycmF5IERlbEFycmF5Ow0KLQ0KLQlmb3IgKGludCBpPTAsc3o9bV9EZWxheURhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCWlmIChDSlNfRGVsYXlEYXRhKiBwRGF0YSA9IG1fRGVsYXlEYXRhLkdldEF0KGkpKQ0KLQkJew0KLQkJCWlmIChwRGF0YS0+c0ZpZWxkTmFtZSA9PSBzRmllbGROYW1lICYmIHBEYXRhLT5uQ29udHJvbEluZGV4ID09IG5Db250cm9sSW5kZXgpDQotCQkJew0KLQkJCQlGaWVsZDo6RG9EZWxheShtX3BEb2N1bWVudCwgcERhdGEpOw0KLQkJCQlkZWxldGUgcERhdGE7DQotCQkJCW1fRGVsYXlEYXRhLlNldEF0KGksIE5VTEwpOw0KLQkJCQlEZWxBcnJheS5BZGQoaSk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCWZvciAoaW50IGo9RGVsQXJyYXkuR2V0U2l6ZSgpLTE7IGo+PTA7IGotLSkNCi0Jew0KLQkJbV9EZWxheURhdGEuUmVtb3ZlQXQoRGVsQXJyYXlbal0pOw0KLQl9DQotfQ0KLQ0KLXZvaWQgRG9jdW1lbnQ6OkFkZERlbGF5QW5ub3REYXRhKENKU19Bbm5vdE9iaiAqcERhdGEpDQotew0KLQltX0RlbGF5QW5ub3REYXRhLkFkZChwRGF0YSk7DQotfQ0KLQ0KLXZvaWQgRG9jdW1lbnQ6OkRvQW5ub3REZWxheSgpDQotew0KLQlDRlhfRFdvcmRBcnJheSBEZWxBcnJheTsNCi0JDQotCWZvciAoaW50IGo9RGVsQXJyYXkuR2V0U2l6ZSgpLTE7IGo+PTA7IGotLSkNCi0Jew0KLQkJbV9EZWxheURhdGEuUmVtb3ZlQXQoRGVsQXJyYXlbal0pOw0KLQl9DQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvYXBwLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0ZpZWxkLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0ljb24uaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvRmllbGQuaCIKKworc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQoreworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlyZXR1cm4gcFJ1bnRpbWUtPkdldElzb2xhdGUoKTsKK30KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19QcmludFBhcmFtc09iaikKK0VORF9KU19TVEFUSUNfQ09OU1QoKQorCitCRUdJTl9KU19TVEFUSUNfUFJPUChDSlNfUHJpbnRQYXJhbXNPYmopCitFTkRfSlNfU1RBVElDX1BST1AoKQorCitCRUdJTl9KU19TVEFUSUNfTUVUSE9EKENKU19QcmludFBhcmFtc09iaikKK0VORF9KU19TVEFUSUNfTUVUSE9EKCkKKworSU1QTEVNRU5UX0pTX0NMQVNTKENKU19QcmludFBhcmFtc09iaiwgUHJpbnRQYXJhbXNPYmopCisKK1ByaW50UGFyYW1zT2JqOjpQcmludFBhcmFtc09iaihDSlNfT2JqZWN0KiBwSlNPYmplY3QpCis6IENKU19FbWJlZE9iaihwSlNPYmplY3QpCit7CisJYlVJID0gVFJVRTsKKwluU3RhcnQgPSAwOworCW5FbmQgPSAwOworCWJTaWxlbnQgPSBGQUxTRTsKKwliU2hyaW5rVG9GaXQgPSBGQUxTRTsKKwliUHJpbnRBc0ltYWdlID0gRkFMU0U7CisJYlJldmVyc2UgPSBGQUxTRTsKKwliQW5ub3RhdGlvbnMgPSBUUlVFOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tIERvY3VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworI2RlZmluZSBNSU5XSURUSCAgNS4wZgorI2RlZmluZSBNSU5IRUlHSFQgNS4wZgorCitCRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX0RvY3VtZW50KQorRU5EX0pTX1NUQVRJQ19DT05TVCgpCisKK0JFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19Eb2N1bWVudCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShBREJFKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGF1dGhvcikKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShiYXNlVVJMKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGJvb2ttYXJrUm9vdCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShjYWxjdWxhdGUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoQ29sbGFiKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGNyZWF0aW9uRGF0ZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShjcmVhdG9yKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGRlbGF5KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGRpcnR5KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGRvY3VtZW50RmlsZU5hbWUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZXh0ZXJuYWwpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZmlsZXNpemUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoaWNvbnMpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoaW5mbykgICAKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShrZXl3b3JkcykKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShsYXlvdXQpCisJSlNfU1RBVElDX1BST1BfRU5UUlkobWVkaWEpCisJSlNfU1RBVElDX1BST1BfRU5UUlkobW9kRGF0ZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShtb3VzZVgpCisJSlNfU1RBVElDX1BST1BfRU5UUlkobW91c2VZKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG51bUZpZWxkcykKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShudW1QYWdlcykKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShwYWdlTnVtKSAgIAorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHBhZ2VXaW5kb3dSZWN0KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHBhdGgpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocHJvZHVjZXIpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoc3ViamVjdCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh0aXRsZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh6b29tKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHpvb21UeXBlKQorRU5EX0pTX1NUQVRJQ19QUk9QKCkKKworQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfRG9jdW1lbnQpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShhZGRBbm5vdCwwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYWRkRmllbGQsIDQpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShhZGRMaW5rLCAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYWRkSWNvbiwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGNhbGN1bGF0ZU5vdywgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGNsb3NlRG9jLCAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoY3JlYXRlRGF0YU9iamVjdCwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGRlbGV0ZVBhZ2VzLCAyKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZXhwb3J0QXNUZXh0LCAzKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZXhwb3J0QXNGREYsIDYpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShleHBvcnRBc1hGREYsIDUpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShleHRyYWN0UGFnZXMsIDMpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRBbm5vdCwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldEFubm90cywgMikKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldEFubm90M0QsIDIpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRBbm5vdHMzRCwgMSkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldEZpZWxkLCAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0SWNvbiwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldExpbmtzLCAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0TnRoRmllbGROYW1lLCAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0T0NHcywgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldFBhZ2VCb3gsIDApCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRQYWdlTnRoV29yZCwgMykKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldFBhZ2VOdGhXb3JkUXVhZHMsIDIpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRQYWdlTnVtV29yZHMsIDEpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRQcmludFBhcmFtcywgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldFVSTCwgMikKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGltcG9ydEFuRkRGLCAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoaW1wb3J0QW5YRkRGLCAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoaW1wb3J0VGV4dERhdGEsIDIpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShpbnNlcnRQYWdlcywgNCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKG1haWxGb3JtLCA2KQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkocHJpbnQsIDkpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShyZW1vdmVGaWVsZCwgMSkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHJlcGxhY2VQYWdlcywgNCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHJlc2V0Rm9ybSwgMSkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHJlbW92ZUljb24sIDApCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzYXZlQXMsIDUpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzdWJtaXRGb3JtLCAyMykKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKG1haWxEb2MsIDApCQkKK0VORF9KU19TVEFUSUNfTUVUSE9EKCkKKworSU1QTEVNRU5UX0pTX0NMQVNTKENKU19Eb2N1bWVudCwgRG9jdW1lbnQpCisKK0ZYX0JPT0wJQ0pTX0RvY3VtZW50OjpJbml0SW5zdGFuY2UoSUZYSlNfQ29udGV4dCogY2MpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwlEb2N1bWVudCogcERvYyA9IChEb2N1bWVudCopR2V0RW1iZWRPYmplY3QoKTsKKwlBU1NFUlQocERvYyAhPSBOVUxMKTsKKwkKKwlwRG9jLT5BdHRhY2hEb2MocENvbnRleHQtPkdldFJlYWRlckRvY3VtZW50KCkpOworCXBEb2MtPlNldElzb2xhdGUocENvbnRleHQtPkdldEpTUnVudGltZSgpLT5HZXRJc29sYXRlKCkpOworCXJldHVybiBUUlVFOworfTsKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIERvY3VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitEb2N1bWVudDo6RG9jdW1lbnQoQ0pTX09iamVjdCogcEpTT2JqZWN0KSA6IENKU19FbWJlZE9iaihwSlNPYmplY3QpLAorCW1fY3dCYXNlVVJMKEwiIiksCisJbV9wSWNvblRyZWUoTlVMTCksCisJbV9wRG9jdW1lbnQoTlVMTCksCisJbV9iRGVsYXkoRkFMU0UpLAorCW1faXNvbGF0ZShOVUxMKQoreworfQorCitEb2N1bWVudDo6fkRvY3VtZW50KCkKK3sKKwlpZiAobV9wSWNvblRyZWUpCisJeworCQltX3BJY29uVHJlZS0+RGVsZXRlSWNvblRyZWUoKTsKKwkJZGVsZXRlIG1fcEljb25UcmVlOworCQltX3BJY29uVHJlZSA9IE5VTEw7CisJfQorCWZvciAoaW50IGk9MDsgaTxtX0RlbGF5RGF0YS5HZXRTaXplKCk7IGkrKykKKwl7CisJCWlmIChDSlNfRGVsYXlEYXRhKiBwRGF0YSA9IG1fRGVsYXlEYXRhLkdldEF0KGkpKQorCQl7CisJCQlkZWxldGUgcERhdGE7CisJCQlwRGF0YSA9IE5VTEw7CisJCQltX0RlbGF5RGF0YS5TZXRBdChpLCBOVUxMKTsKKwkJCQorCQl9CisJfQorCisJbV9EZWxheURhdGEuUmVtb3ZlQWxsKCk7CisJbV9EZWxheUFubm90RGF0YS5SZW1vdmVBbGwoKTsKK30KKworLy90aGUgdG90YWwgbnVtYmVyIG9mIGZpbGVkcyBpbiBkb2N1bWVudC4KK0ZYX0JPT0wgRG9jdW1lbnQ6Om51bUZpZWxkcyhPQkpfUFJPUF9QQVJBTVMpCit7CisJaWYgKCF2cC5Jc0dldHRpbmcoKSkgcmV0dXJuIEZBTFNFOworCisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisgICAJQ1BERlNES19JbnRlckZvcm0gKnBJbnRlckZvcm0gPSBtX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlDUERGX0ludGVyRm9ybSAqcFBERkZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocFBERkZvcm0gIT0gTlVMTCk7CisKKwl2cCA8PCAoaW50KXBQREZGb3JtLT5Db3VudEZpZWxkcygpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmRpcnR5KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNHZXR0aW5nKCkpCisJeworCQlpZiAobV9wRG9jdW1lbnQtPkdldENoYW5nZU1hcmsoKSkKKwkJCXZwIDw8IHRydWU7CisJCWVsc2UKKwkJCXZwIDw8IGZhbHNlOworCX0KKwllbHNlCisJeworCQlib29sIGJDaGFuZ2VkID0gZmFsc2U7CisKKwkJdnAgPj4gYkNoYW5nZWQ7CisKKwkJaWYgKGJDaGFuZ2VkKQorCQkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsKKwkJZWxzZQorCQkJbV9wRG9jdW1lbnQtPkNsZWFyQ2hhbmdlTWFyaygpOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpBREJFKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNHZXR0aW5nKCkpCisJeworCQl2cC5TZXROdWxsKCk7CisJfQorCWVsc2UKKwl7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OnBhZ2VOdW0oT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc0dldHRpbmcoKSkKKwl7CQkJCisJCWlmIChDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBtX3BEb2N1bWVudC0+R2V0Q3VycmVudFZpZXcoKSkKKwkJeworCQkJdnAgPDwgcFBhZ2VWaWV3LT5HZXRQYWdlSW5kZXgoKTsKKwkJfQorCX0KKwllbHNlCisJewkJCisJCWludCBpUGFnZUNvdW50ID0gbV9wRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpOworCisJCWludCBpUGFnZU51bSA9IDA7CisJCXZwID4+IGlQYWdlTnVtOworCisJCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7CisJCWlmKCFwRW52KQorCQkJcmV0dXJuIEZBTFNFOworCisJCWlmIChpUGFnZU51bSA+PSAwICYmIGlQYWdlTnVtIDwgaVBhZ2VDb3VudCkKKwkJeworCQkJIHBFbnYtPkpTX2RvY2dvdG9QYWdlKGlQYWdlTnVtKTsKKwkJfQorCQllbHNlIGlmIChpUGFnZU51bSA+PSBpUGFnZUNvdW50KQorCQl7CisJCQkgcEVudi0+SlNfZG9jZ290b1BhZ2UoaVBhZ2VDb3VudC0xKTsKKwkJfQorCQllbHNlIGlmIChpUGFnZU51bSA8IDApCisJCXsKKwkJCSBwRW52LT5KU19kb2Nnb3RvUGFnZSgwKTsKKwkJfQorCX0KKworIAlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6UGFyc2VyUGFyYW1zKEpTT2JqZWN0KiBwT2JqLENKU19Bbm5vdE9iaiYgYW5ub3RvYmopCit7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmFkZEFubm90KE9CSl9NRVRIT0RfUEFSQU1TKQoreworIAlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6YWRkRmllbGQoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJLy9Eb2Vzbid0IHN1cHBvcnQuCisJcmV0dXJuIFRSVUU7Cit9CisKKy8vZXhwb3J0cyBmb3JtIGZpZWxkcyBhcyBhIHRhYi1kZWxpbWl0ZWQgdGV4dCBmaWxlIHRvIGEgbG9jYWwgaGFyZCBkaXNrLgorLy9jb21tZW50OiBuZWVkIHJlYWRlciBzdXBwb3J0CisvL25vdGUgOiB3YXRjaCB0aGUgdGhpcmQgcGFyYW1ldGVyOmNQYXRoLCBmb3Igd2hhdCBjYXNlIGl0IGNhbiBiZSBzYWZlbHkgc2F2ZWQ/CisvL2ludCBDUERGU0RLX0ludGVyRm9ybTo6RXhwb3J0QXNUZXh0KEZYX0JPT0wgYk5vUGFzc3dvcmQsU3RyaW5nQXJyYXkgYUZpZWxkcyxTdHJpbmcgY1BhdGgpOworLy9yZXR1cm4gdmFsdWUsIGludCB0aGUgaW5kZXggb2YgdGhlIHBhcmFtZXRlcnMgaWxsZWdhbCwgdGhlIGluZGV4IGlzIGJhc2VkIG9uIDEuCisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmV4cG9ydEFzVGV4dChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlpZiAoSXNTYWZlTW9kZShjYykpIHJldHVybiBUUlVFOworCXJldHVybiBUUlVFOworfQorCisvL2V4cG9ydHMgZm9ybSBmaWVsZHMgYXMgYSBmZGYgZmlsZSB0byB0aGUgbG9jYWwgaGFyZCBkcml2ZQorLy9jb21tZW50OiBuZWVkIHJlYWRlciBzdXBwb3J0cworLy9ub3RlOnRoZSBsYXN0IHBhcmFtZXRlciBoYXNuJ3QgYmVlbiBjb25maXJtZWQuYmVjYXVzZSB0aGUgcHJldmlvdXMgb25lIGJsb2NrcyB0aGUgd2F5LgorLy9pbnQgQ1BERlNES19Eb2N1bWVudDo6RXhwb3J0QXNGREYoRlhfQk9PTCBiQWxsRmllbGRzLEJPT0wgYk5vUGFzc3dvcmQsU3RyaW5nQXJyYXkgYUZpZWxkcyxGWF9CT09MIGJGbGFncyxTdHJpbmcgY1BhdGgsRlhfQk9PTCBiQW5ub3RhdGlvbnMpOworCitGWF9CT09MIERvY3VtZW50OjpleHBvcnRBc0ZERihPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOworCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9FWFRSQUNUX0FDQ0VTUykpIHJldHVybiBGQUxTRTsKKworCUZYX0JPT0wgYkFsbEZpZWxkcyA9IHBhcmFtcy5zaXplKCkgPiAwID8gKEZYX0JPT0wpcGFyYW1zWzBdIDogRkFMU0U7CisJRlhfQk9PTCBiTm9QYXNzV29yZCA9IHBhcmFtcy5zaXplKCkgPiAxID8gKEZYX0JPT0wpcGFyYW1zWzFdIDogVFJVRTsKKwlGWF9CT09MIGJXaG9sZSA9IHBhcmFtcy5zaXplKCkgPiAyID8gKHBhcmFtc1syXS5HZXRUeXBlKCkgPT0gVlRfbnVsbCkgOiBUUlVFOworCUNKU19BcnJheSBhcnJheUZpbGVkcyhpc29sYXRlKTsKKwlpZiAoIWJXaG9sZSkKKwkJYXJyYXlGaWxlZHMuQXR0YWNoKHBhcmFtc1syXSk7CisJLy9GWF9CT09MIGJGbGFncyA9IHBhcmFtcy5zaXplKCkgPiAzID8gKEZYX0JPT0wpcGFyYW1zWzNdIDogRkFMU0U7CisgICAgQ0ZYX1dpZGVTdHJpbmcgc3dGaWxlUGF0aCA9IHBhcmFtcy5zaXplKCkgPiA0ID8gKEZYX0xQQ1dTVFIpcGFyYW1zWzRdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkgOiAoRlhfTFBDV1NUUilMIiI7CisKKwlpZiAoc3dGaWxlUGF0aC5Jc0VtcHR5KCkpCisJeworCQlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOworCQlzd0ZpbGVQYXRoID0gcEVudi0+SlNfZmllbGRCcm93c2UoKTsKKwkJaWYoc3dGaWxlUGF0aC5Jc0VtcHR5KCkpCisJCQlyZXR1cm4gVFJVRTsKKwl9CisJZWxzZQorCXsKKwkJc3dGaWxlUGF0aCA9IGFwcDo6UERGUGF0aFRvU3lzUGF0aChzd0ZpbGVQYXRoKTsKKwl9CisgICAgCisJbV9wRG9jdW1lbnQtPlNldEZvY3VzQW5ub3QoTlVMTCk7CisgICAKKyAgICBDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybT0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlDUERGX0ludGVyRm9ybSogcFBERkZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocFBERkZvcm0gIT0gTlVMTCk7CisKKwlDRlhfUHRyQXJyYXkgYUZpZWxkczsKKworCWlmIChiV2hvbGUpCisJeworCQlmb3IgKGludCBqPTAsanN6PXBQREZGb3JtLT5Db3VudEZpZWxkcygpOyBqPGpzejsgaisrKQorCQl7CisJCQlhRmllbGRzLkFkZChwUERGRm9ybS0+R2V0RmllbGQoaikpOworCQl9CisJfQorCWVsc2UKKwl7CisJCWZvciAoaW50IGk9MCxpc3o9YXJyYXlGaWxlZHMuR2V0TGVuZ3RoKCk7IGk8aXN6OyBpKyspCisJCXsKKwkJCUNKU19WYWx1ZSB2YWxOYW1lKGlzb2xhdGUpOworCQkJYXJyYXlGaWxlZHMuR2V0RWxlbWVudChpLHZhbE5hbWUpOworCQkJQ0ZYX1dpZGVTdHJpbmcgc3dOYW1lID0gdmFsTmFtZS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJCQlmb3IgKGludCBqPTAsIGpzej1wUERGRm9ybS0+Q291bnRGaWVsZHMoc3dOYW1lKTsgajxqc3o7IGorKykKKwkJCXsKKwkJCQlhRmllbGRzLkFkZChwUERGRm9ybS0+R2V0RmllbGQoaiwgc3dOYW1lKSk7CisJCQl9CisJCX0KKwl9CisKKwlDRlhfUHRyQXJyYXkgZmllbGRzOworCisJZm9yIChpbnQgaT0wLHN6PWFGaWVsZHMuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCSAgICBDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gKENQREZfRm9ybUZpZWxkKilhRmllbGRzW2ldOworCQkKKwkJaWYgKCFiQWxsRmllbGRzKQorCQkJaWYgKHBGaWVsZC0+R2V0VmFsdWUoKSA9PSBMIiIpCisJCQkJY29udGludWU7CisKKwkJaWYgKGJOb1Bhc3NXb3JkKQorCQkJaWYgKHBGaWVsZC0+R2V0RmllbGRGbGFncygpICYgMHgyMDAwKQorCQkJCWNvbnRpbnVlOworCisgICAgICAgIGZpZWxkcy5BZGQoKHZvaWQqKXBGaWVsZCk7CisJfSAgICAKKworICAgIHJldHVybiBwSW50ZXJGb3JtLT5FeHBvcnRGaWVsZHNUb0ZERkZpbGUoc3dGaWxlUGF0aCwgZmllbGRzLCBUUlVFKTsKK30KKworLy9leHBvcnRzIGZvcm0gZmllbGRzIGFuIFhGREYgZmlsZSB0byB0aGUgbG9jYWwgaGFyZCBkcml2ZQorLy9jb21tZW50OiBuZWVkIHJlZGVyIHN1cHBvcnRzCisvL25vdGU6dGhlIGxhc3QgcGFyYW1ldGVyIGNhbid0IGJlIHRlc3QKKy8vaW50IENQREZTREtfRG9jdW1lbnQ6OkV4cG9ydEFzWEZERihGWF9CT09MIGJBbGxGaWVsZHMsRlhfQk9PTCAgYk5vUGFzc1dvcmQsU3RyaW5nQXJyYXkgYUZpZWxkcyxTdHJpbmcgY1BhdGgsRlhfQk9PTCBiQW5ub2F0YXRpb25zKTsKKworRlhfQk9PTCBEb2N1bWVudDo6ZXhwb3J0QXNYRkRGKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fRVhUUkFDVF9BQ0NFU1MpKSByZXR1cm4gRkFMU0U7CisKKwlyZXR1cm4gVFJVRTsKK30KKworLy9NYXBzIGEgZmllbGQgb2JqZWN0IGluIFBERiBkb2N1bWVudCB0byBhIEphdmFTY3JpcHQgdmFyaWFibGUKKy8vY29tbWVudDoKKy8vbm90ZTogdGhlIHBhcmVtdGVyIGNOYW1lLCB0aGlzIGlzIGNsdWUgaG93IHRvIHRyZWF0IGlmIHRoZSBjTmFtZSBpcyBub3QgYSB2YWxpYWJsZSBmaWxlZCBuYW1lIGluIHRoaXMgZG9jdW1lbnQKKworRlhfQk9PTCBEb2N1bWVudDo6Z2V0RmllbGQoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAocGFyYW1zLnNpemUoKSA8IDEpIHJldHVybiBGQUxTRTsKKworCUNGWF9XaWRlU3RyaW5nIHdpZGVOYW1lID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisKKyAgICBDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IG1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCUNQREZfSW50ZXJGb3JtKiBwUERGRm9ybSA9IHBJbnRlckZvcm0tPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwUERGRm9ybSAhPSBOVUxMKTsKKworCWlmIChwUERGRm9ybS0+Q291bnRGaWVsZHMod2lkZU5hbWUpIDw9IDApIAorCXsKKwkJdlJldC5TZXROdWxsKCk7CisJCXJldHVybiBUUlVFOworCX0KKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlKU0ZYT2JqZWN0ICBwRmllbGRPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBwQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJGaWVsZCIpKTsKKworCUNKU19GaWVsZCAqIHBKU0ZpZWxkID0gKENKU19GaWVsZCopSlNfR2V0UHJpdmF0ZShpc29sYXRlLHBGaWVsZE9iaik7CisJQVNTRVJUKHBKU0ZpZWxkICE9IE5VTEwpOworCisJRmllbGQgKiBwRmllbGQgPSAoRmllbGQgKilwSlNGaWVsZC0+R2V0RW1iZWRPYmplY3QoKTsgCisJQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsKKworCXBGaWVsZC0+QXR0YWNoRmllbGQodGhpcywgd2lkZU5hbWUpOworCXZSZXQgPSBwSlNGaWVsZDsKKworCXJldHVybiBUUlVFOworfQorCisvL0dldHMgdGhlIG5hbWUgb2YgdGhlIG50aCBmaWVsZCBpbiB0aGUgZG9jdW1lbnQgCisvL2NvbW1lbnQ6CisvL25vdGU6IHRoZSBwYXJhbWV0ZXIgbkluZGV4LCBpZiBpdCBpcyBub3QgYXZhaWxhYmxlCisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmdldE50aEZpZWxkTmFtZShPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpbnQgbkluZGV4ID0gcGFyYW1zLnNpemUoKSA+IDAgPyAoaW50KXBhcmFtc1swXSA6IC0xOworCWlmIChuSW5kZXggPT0gLTEpIHJldHVybiBGQUxTRTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ1BERl9JbnRlckZvcm0qIHBQREZGb3JtID0gcEludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBQREZGb3JtICE9IE5VTEwpOworCisJQ1BERl9Gb3JtRmllbGQqIHBGaWVsZCA9IHBQREZGb3JtLT5HZXRGaWVsZChuSW5kZXgpOworCWlmICghcEZpZWxkKQorCQlyZXR1cm4gRkFMU0U7CisKKwl2UmV0ID0gcEZpZWxkLT5HZXRGdWxsTmFtZSgpOworCXJldHVybiBUUlVFOwkKK30KKworLy9pbXBvcnRzIHRoZSBzcGVjaWZpZWQgZmRmIGZpbGUuCisvL2NvbW1lbnRzOiBuZWVkIHJlYWRlciBzdXBwcG9ydAorLy9ub3RlOm9uY2UgdGhlIGNwYXRoIGlzIGlsbGlnbCAgdGhlbiBhIGZpbGUgZGlhbG9nIGJveCBwb3BzIHVwIGluIG9yZGVyIHRvIGFzayB1c2VyIHRvIGNob29vc2UgdGhlIGZpbGUKKy8vaW50IENQREZTREtfRG9jdW1lbnQ6OmltcG9ydEFuRkRGKFN0cmluZyBjUGF0aCk7CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmltcG9ydEFuRkRGKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKCEobV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkgfHwgCisJCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BTk5PVF9GT1JNKSB8fAorCQltX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fRklMTF9GT1JNKSkpIHJldHVybiBGQUxTRTsKKworCisJQ0ZYX1dpZGVTdHJpbmcgc3dQYXRoOworCQorCWlmIChwYXJhbXMuc2l6ZSgpID4gMCkKKwkJc3dQYXRoID0gcGFyYW1zWzBdOworICAgIAorCWlmIChzd1BhdGguSXNFbXB0eSgpKQorCXsKKwkJQ1BERkRvY19FbnZpcm9ubWVudCogcEVudiA9IG1fcERvY3VtZW50LT5HZXRFbnYoKTsKKwkJc3dQYXRoID0gcEVudi0+SlNfZmllbGRCcm93c2UoKTsKKwkJaWYoc3dQYXRoLklzRW1wdHkoKSkKKwkJCXJldHVybiBUUlVFOworCX0KKwllbHNlCisJeworCQlzd1BhdGggPSBhcHA6OlBERlBhdGhUb1N5c1BhdGgoc3dQYXRoKTsKKwl9CisKKwltX3BEb2N1bWVudC0+U2V0Rm9jdXNBbm5vdChOVUxMKTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlpZiAoIXBJbnRlckZvcm0tPkltcG9ydEZvcm1Gcm9tRkRGRmlsZShzd1BhdGgsIFRSVUUpKQorCQlyZXR1cm4gRkFMU0U7CisKKyAJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsKKy8vIAlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOworLy8gCUFTU0VSVChwRW52ICE9IE5VTEwpOworLy8gCUlVbmRvKiBwVW5kbyA9IElVbmRvOjpHZXRVbmRvKHBFbnYpOworLy8gCUFTU0VSVChwVW5kbyAhPSBOVUxMKTsKKy8vIAlwVW5kby0+UmVzZXQobV9wRG9jdW1lbnQpOworCisJcmV0dXJuIFRSVUU7Cit9CisKKy8vaW1wb3J0cyBhbmQgc3BlY2lmaWVkIFhGREYgZmlsZSBjb250YWluaW5nIFhNTCBmb3JtIGRhdGEKKy8vY29tbWVudDogbmVlZCByZWFkZXIgc3VwcG9ydHMKKy8vbm90ZTogc2FtZSBhcyB1cAorLy9pbnQgQ1BERlNES19Eb2N1bWVudDo6aW1wb3J0QW5GREYoU3RyaW5nIGNQYXRoKQorCitGWF9CT09MIERvY3VtZW50OjppbXBvcnRBblhGREYoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCAKKwkJbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0FOTk9UX0ZPUk0pIHx8CisJCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9GSUxMX0ZPUk0pKSkgcmV0dXJuIEZBTFNFOworCisJcmV0dXJuIFRSVUU7Cit9CisKKy8vaW1wb3J0cyBhbmQgc3BlY2lmaWVkIHRleHQgZmlsZSAKKy8vY29tbW5ldDogbmVlZCByZWFkZXIgc3VwcG9ydHMKKy8vbm90ZTogc2FtZSBhcyB1cCx3aGVuIG5Sb3cgaXMgbm90IHJhdGlvbmFsLGFkb2JlIGlzIGR1bWIgZm9yIGl0LgorLy9pbnQgQ1BERlNES19Eb2N1bWVudDo6aW1wb3J0VGV4dERhdGEoU3RyaW5nIGNQYXRoLGludCBuUm93KTsKKworRlhfQk9PTCBEb2N1bWVudDo6aW1wb3J0VGV4dERhdGEoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCAKKwkJbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0FOTk9UX0ZPUk0pIHx8CisJCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9GSUxMX0ZPUk0pKSkgcmV0dXJuIEZBTFNFOworCisJcmV0dXJuIFRSVUU7Cit9CisKKy8vZXhwb3J0cyB0aGUgZm9ybSBkYXRhIGFuZCBtYWlscyB0aGUgcmVzdWx0aW5nIGZkZiBmaWxlIGFzIGFuIGF0dGFjaG1lbnQgdG8gYWxsIHJlY2lwaWVudHMuCisvL2NvbW1lbnQ6IG5lZWQgcmVhZGVyIHN1cHBvcnRzCisvL25vdGU6CisvL2ludCBDUERGU0RLX0RvY3VtZW50OjptYWlsRm9ybShGWF9CT09MIGJVSSxTdHJpbmcgY3RvLHN0cmluZyBjY2Msc3RyaW5nIGNiY2Msc3RyaW5nIGNTdWJqZWN0LHN0cmluZyBjbXMpOworCitGWF9CT09MIERvY3VtZW50OjptYWlsRm9ybShPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9FWFRSQUNUX0FDQ0VTUykpIHJldHVybiBGQUxTRTsKKworCWludCBpTGVuZ3RoID0gcGFyYW1zLnNpemUoKTsKKworCUZYX0JPT0wgYlVJID0gaUxlbmd0aCA+IDAgPyAoRlhfQk9PTClwYXJhbXNbMF0gOiBUUlVFOworCUNGWF9XaWRlU3RyaW5nIGNUbyA9IGlMZW5ndGggPiAxID8gKEZYX0xQQ1dTVFIpcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkgOiAoRlhfTFBDV1NUUilMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgY0NjID0gaUxlbmd0aCA+IDIgPyAoRlhfTFBDV1NUUilwYXJhbXNbMl0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSA6IChGWF9MUENXU1RSKUwiIjsKKwlDRlhfV2lkZVN0cmluZyBjQmNjID0gaUxlbmd0aCA+IDMgPyAoRlhfTFBDV1NUUilwYXJhbXNbM10ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSA6IChGWF9MUENXU1RSKUwiIjsKKwlDRlhfV2lkZVN0cmluZyBjU3ViamVjdCA9IGlMZW5ndGggPiA0ID8gKEZYX0xQQ1dTVFIpcGFyYW1zWzRdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkgOiAoRlhfTFBDV1NUUilMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgY01zZyA9IGlMZW5ndGggPiA1ID8gKEZYX0xQQ1dTVFIpcGFyYW1zWzVdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkgOiAoRlhfTFBDV1NUUilMIiI7CisKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ0ZYX0J5dGVUZXh0QnVmIHRleHRCdWY7CisJaWYgKCFwSW50ZXJGb3JtLT5FeHBvcnRGb3JtVG9GREZUZXh0QnVmKHRleHRCdWYpKQorCQlyZXR1cm4gRkFMU0U7CisKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcENvbnRleHQtPkdldFJlYWRlckFwcCgpOworCUFTU0VSVChwRW52ICE9IE5VTEwpOworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlwUnVudGltZS0+QmVnaW5CbG9jaygpOworICAgIHBFbnYtPkpTX2RvY21haWxGb3JtKHRleHRCdWYuR2V0QnVmZmVyKCksIHRleHRCdWYuR2V0TGVuZ3RoKCksIGJVSSwgKEZYX0xQQ1dTVFIpY1RvLCAoRlhfTFBDV1NUUiljU3ViamVjdCwgKEZYX0xQQ1dTVFIpY0NjLCAoRlhfTFBDV1NUUiljQmNjLCAoRlhfTFBDV1NUUiljTXNnKTsKKwlwUnVudGltZS0+RW5kQmxvY2soKTsKKyAJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OnByaW50KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlGWF9CT09MIGJVSSA9IFRSVUU7CisJaW50IG5TdGFydCA9IDA7CisJaW50IG5FbmQgPSAwOworCUZYX0JPT0wgYlNpbGVudCA9IEZBTFNFOworCUZYX0JPT0wgYlNocmlua1RvRml0ID0gRkFMU0U7CisJRlhfQk9PTCBiUHJpbnRBc0ltYWdlID0gRkFMU0U7CisJRlhfQk9PTCBiUmV2ZXJzZSA9IEZBTFNFOworCUZYX0JPT0wgYkFubm90YXRpb25zID0gRkFMU0U7CisKKwlpbnQgbmxlbmd0aCA9IHBhcmFtcy5zaXplKCk7CisJaWYobmxlbmd0aCA9PTkpCisJeworCQlpZiAocGFyYW1zWzhdLkdldFR5cGUoKSA9PSBWVF9meG9iamVjdCkKKwkJeworCQkJSlNGWE9iamVjdCBwT2JqID0gKEpTRlhPYmplY3QpcGFyYW1zWzhdOworCQkJeworCQkJCWlmIChKU19HZXRPYmpEZWZuSUQocE9iaikgPT0gSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJQcmludFBhcmFtc09iaiIpKQorCQkJCXsKKwkJCQkJaWYgKENKU19PYmplY3QqIHBKU09iaiA9IChDSlNfT2JqZWN0KilwYXJhbXNbOF0pCisJCQkJCXsKKwkJCQkJCQlpZiAoUHJpbnRQYXJhbXNPYmoqIHBwcmludHBhcmFtc09iaiA9IChQcmludFBhcmFtc09iaiopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpKQorCQkJCQkJCXsKKwkJCQkJCQkJYlVJID0gcHByaW50cGFyYW1zT2JqLT5iVUk7CisJCQkJCQkJCW5TdGFydCA9IHBwcmludHBhcmFtc09iai0+blN0YXJ0OworCQkJCQkJCQluRW5kID0gcHByaW50cGFyYW1zT2JqLT5uRW5kOworCQkJCQkJCQliU2lsZW50ID0gcHByaW50cGFyYW1zT2JqLT5iU2lsZW50OworCQkJCQkJCQliU2hyaW5rVG9GaXQgPSBwcHJpbnRwYXJhbXNPYmotPmJTaHJpbmtUb0ZpdDsKKwkJCQkJCQkJYlByaW50QXNJbWFnZSA9IHBwcmludHBhcmFtc09iai0+YlByaW50QXNJbWFnZTsKKwkJCQkJCQkJYlJldmVyc2UgPSBwcHJpbnRwYXJhbXNPYmotPmJSZXZlcnNlOworCQkJCQkJCQliQW5ub3RhdGlvbnMgPSBwcHJpbnRwYXJhbXNPYmotPmJBbm5vdGF0aW9uczsKKwkJCQkJCQl9CisJCQkJCX0KKwkJCQl9CisJCQl9CQorCQl9CisJfQorCWVsc2UKKwl7CisJCWlmKG5sZW5ndGggPj0gMSkKKwkJCSBiVUkgPSBwYXJhbXNbMF07CisJCWlmKG5sZW5ndGggPj0gMikKKwkJCSBuU3RhcnQgPSAoaW50KXBhcmFtc1sxXTsKKwkJaWYobmxlbmd0aCA+PSAzKQorCQkgICAgbkVuZCA9IChpbnQpcGFyYW1zWzJdOworCQlpZihubGVuZ3RoID49IDQpCisJCQliU2lsZW50ID0gcGFyYW1zWzNdOworCQlpZihubGVuZ3RoID49IDUpCisJCSAgICBiU2hyaW5rVG9GaXQgPSBwYXJhbXNbNF07CisJCWlmKG5sZW5ndGggPj0gNikKKwkJCWJQcmludEFzSW1hZ2UgPSBwYXJhbXNbNV07CisJCWlmKG5sZW5ndGggPj0gNykKKwkJCWJSZXZlcnNlID0gcGFyYW1zWzZdOworCQlpZihubGVuZ3RoID49IDgpCisJCQliQW5ub3RhdGlvbnMgPSBwYXJhbXNbN107CisJfQorCisgCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKyAKKyAJaWYgKENQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCkpCisgCXsKKwkJcEVudi0+SlNfZG9jcHJpbnQoYlVJLCBuU3RhcnQsIG5FbmQsIGJTaWxlbnQsIGJTaHJpbmtUb0ZpdCwgYlByaW50QXNJbWFnZSwgYlJldmVyc2UsIGJBbm5vdGF0aW9ucyk7CisgCQlyZXR1cm4gVFJVRTsKKyAJfQorCXJldHVybiBGQUxTRTsKK30KKworLy9yZW1vdmVzIHRoZSBzcGVjaWZpZWQgZmllbGQgZnJvbSB0aGUgZG9jdW1lbnQuCisvL2NvbW1lbnQ6CisvL25vdGU6IGlmIHRoZSBmaWxlZCBuYW1lIGlzIG5vdCByZXRpb25hbCwgYWRvYmUgaXMgZHVtYiBmb3IgaXQuCisKK0ZYX0JPT0wgRG9jdW1lbnQ6OnJlbW92ZUZpZWxkKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICghKG1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9NT0RJRlkpIHx8IAorCQltX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fQU5OT1RfRk9STSkpKSByZXR1cm4gRkFMU0U7CisKKwlpZiAocGFyYW1zLnNpemUoKSA8IDEpCisJCXJldHVybiBUUlVFOworCisJQ0ZYX1dpZGVTdHJpbmcgc0ZpZWxkTmFtZSA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCUNGWF9QdHJBcnJheSB3aWRnZXRzOworCXBJbnRlckZvcm0tPkdldFdpZGdldHMoc0ZpZWxkTmFtZSwgd2lkZ2V0cyk7CisKKwlpbnQgblNpemUgPSB3aWRnZXRzLkdldFNpemUoKTsKKworCWlmIChuU2l6ZSA+IDApCisJeworCQlmb3IgKGludCBpPTA7IGk8blNpemU7IGkrKykKKwkJeworCQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXdpZGdldHNbaV07CisJCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsKKworCQkJQ1BERl9SZWN0IHJjQW5ub3QgPSBwV2lkZ2V0LT5HZXRSZWN0KCk7CisJCQlyY0Fubm90LmxlZnQgLT0gMTsKKwkJCXJjQW5ub3QuYm90dG9tIC09IDE7CisJCQlyY0Fubm90LnJpZ2h0ICs9IDE7CisJCQlyY0Fubm90LnRvcCArPSAxOworCisJCQlDRlhfUmVjdEFycmF5IGFSZWZyZXNoOworCQkJYVJlZnJlc2guQWRkKHJjQW5ub3QpOworCisJCQlDUERGX1BhZ2UqIHBQYWdlID0gcFdpZGdldC0+R2V0UERGUGFnZSgpOworCQkJQVNTRVJUKHBQYWdlICE9IE5VTEwpOworCQkJCisJCQlDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcgPSBtX3BEb2N1bWVudC0+R2V0UGFnZVZpZXcocFBhZ2UpOworCQkJcFBhZ2VWaWV3LT5EZWxldGVBbm5vdChwV2lkZ2V0KTsKKworCQkJcFBhZ2VWaWV3LT5VcGRhdGVSZWN0cyhhUmVmcmVzaCk7CisJCX0KKwkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworLy9yZXNldCBmaWxlZCB2YWx1ZXMgd2l0aGluIGEgZG9jdW1lbnQuCisvL2NvbW1lbnQ6CisvL25vdGU6IGlmIHRoZSBmaWVsZHMgbmFtZXMgciBub3QgcmF0aW9uYWwsIGFvZGJlIGlzIGR1bWIgZm9yIGl0LgorCitGWF9CT09MIERvY3VtZW50OjpyZXNldEZvcm0oT0JKX01FVEhPRF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKCEobV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkgfHwgCisJCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BTk5PVF9GT1JNKSB8fAorCQltX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fRklMTF9GT1JNKSkpIHJldHVybiBGQUxTRTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlDUERGX0ludGVyRm9ybSogcFBERkZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocFBERkZvcm0gIT0gTlVMTCk7CisKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOworCUNKU19BcnJheSBhTmFtZShpc29sYXRlKTsKKworCWlmIChwYXJhbXMuc2l6ZSgpID4gMCkKKwl7CisJCXN3aXRjaCAocGFyYW1zWzBdLkdldFR5cGUoKSkKKwkJeworCQlkZWZhdWx0OgorCQkJYU5hbWUuQXR0YWNoKHBhcmFtc1swXSk7CisJCQlicmVhazsKKwkJY2FzZSBWVF9zdHJpbmc6CisJCQlhTmFtZS5TZXRFbGVtZW50KDAscGFyYW1zWzBdKTsKKwkJCWJyZWFrOworCQl9CisKKwkJQ0ZYX1B0ckFycmF5IGFGaWVsZHM7CisKKwkJZm9yIChpbnQgaT0wLGlzej1hTmFtZS5HZXRMZW5ndGgoKTsgaTxpc3o7IGkrKykKKwkJeworCQkJQ0pTX1ZhbHVlIHZhbEVsZW1lbnQoaXNvbGF0ZSk7CisJCQlhTmFtZS5HZXRFbGVtZW50KGksdmFsRWxlbWVudCk7CisJCQlDRlhfV2lkZVN0cmluZyBzd1ZhbCA9IHZhbEVsZW1lbnQub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsJCisJCQkKKwkJCWZvciAoaW50IGo9MCxqc3o9cFBERkZvcm0tPkNvdW50RmllbGRzKHN3VmFsKTsgajxqc3o7IGorKykKKwkJCXsKKwkJCQlhRmllbGRzLkFkZCgodm9pZCopcFBERkZvcm0tPkdldEZpZWxkKGosc3dWYWwpKTsKKwkJCX0JCQorCQl9CisKKwkJaWYgKGFGaWVsZHMuR2V0U2l6ZSgpID4gMCkKKwkJeworIAkJCXBQREZGb3JtLT5SZXNldEZvcm0oYUZpZWxkcywgVFJVRSwgVFJVRSk7CisgCQkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsKKworCQl9CisJfQorCWVsc2UKKwl7CisgCQlwUERGRm9ybS0+UmVzZXRGb3JtKFRSVUUpOworIAkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsKKworCX0KKworCXJldHVybiBUUlVFOworfQorCisKK0ZYX0JPT0wgRG9jdW1lbnQ6OnNhdmVBcyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKworCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKy8vCW1fcERvY3VtZW50LT5Eb1NhdmVBcygpOworCisJcmV0dXJuIFRSVUU7Cit9CisKKworRlhfQk9PTCBEb2N1bWVudDo6c3VibWl0Rm9ybShPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKy8vCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0VYVFJBQ1RfQUNDRVNTKSkgcmV0dXJuIEZBTFNFOworCisJaW50IG5TaXplID0gcGFyYW1zLnNpemUoKTsKKwlpZiAoblNpemUgPCAxKSByZXR1cm4gRkFMU0U7CisKKwlDRlhfV2lkZVN0cmluZyBzdHJVUkw7CisJRlhfQk9PTCBiRkRGID0gVFJVRTsKKwlGWF9CT09MIGJFbXB0eSA9IEZBTFNFOworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7CisJQ0pTX0FycmF5IGFGaWVsZHMoaXNvbGF0ZSk7CisKKwlDSlNfVmFsdWUgdiA9IHBhcmFtc1swXTsKKwlpZiAodi5HZXRUeXBlKCkgPT0gVlRfc3RyaW5nKQorCXsKKwkJc3RyVVJMID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJCWlmIChuU2l6ZSA+IDEpCisJCQliRkRGID0gcGFyYW1zWzFdOworCQlpZiAoblNpemUgPiAyKQorCQkJYkVtcHR5ID0gcGFyYW1zWzJdOworCQlpZiAoblNpemUgPiAzKQorCQkJYUZpZWxkcy5BdHRhY2gocGFyYW1zWzNdKTsKKwl9CisJZWxzZSBpZiAodi5HZXRUeXBlKCkgPT0gVlRfb2JqZWN0KQorCXsKKwkJSlNPYmplY3QgcE9iaiA9IChKU09iamVjdClwYXJhbXNbMF07CisJCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjVVJMIik7CisJCWlmICghcFZhbHVlLklzRW1wdHkoKSkKKwkJCXN0clVSTCA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsKKwkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiYkZERiIpOworCQkJYkZERiA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSwgR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7CisJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImJFbXB0eSIpOworCQkJYkVtcHR5ID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLCBHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsKKwkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosTCJhRmllbGRzIik7CisJCQlhRmllbGRzLkF0dGFjaChDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsIEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpKTsKKwl9CQkKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisJQ1BERl9JbnRlckZvcm0qIHBQREZJbnRlckZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocFBERkludGVyRm9ybSAhPSBOVUxMKTsKKworCUZYX0JPT0wgYkFsbCA9IChhRmllbGRzLkdldExlbmd0aCgpID09IDApOworCisJaWYgKGJBbGwgJiYgYkVtcHR5KQorCXsKKwkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7CisJCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCQkKKwkJaWYgKHBQREZJbnRlckZvcm0tPkNoZWNrUmVxdWlyZWRGaWVsZHMoKSkKKwkJeworCQkJcFJ1bnRpbWUtPkJlZ2luQmxvY2soKTsKKwkJCXBJbnRlckZvcm0tPlN1Ym1pdEZvcm0oc3RyVVJMLCBGQUxTRSk7CisJCQlwUnVudGltZS0+RW5kQmxvY2soKTsKKwkJfQorCisJCXJldHVybiBUUlVFOworCX0KKwllbHNlCisJewkKKwkJQ0ZYX1B0ckFycmF5IGZpZWxkT2JqZWN0czsKKworCQlmb3IgKGludCBpPTAsc3o9YUZpZWxkcy5HZXRMZW5ndGgoKTsgaTxzejsgaSsrKQorCQl7CisJCQlDSlNfVmFsdWUgdmFsTmFtZShpc29sYXRlKTsKKwkJCWFGaWVsZHMuR2V0RWxlbWVudChpLCB2YWxOYW1lKTsKKwkJCUNGWF9XaWRlU3RyaW5nIHNOYW1lID0gdmFsTmFtZS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJCQlDUERGX0ludGVyRm9ybSogcFBERkZvcm0gPSBwSW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwkJCUFTU0VSVChwUERGRm9ybSAhPSBOVUxMKTsKKworCQkJZm9yIChpbnQgaj0wLCBqc3o9cFBERkZvcm0tPkNvdW50RmllbGRzKHNOYW1lKTsgajxqc3o7IGorKykKKwkJCXsKKwkJCQlDUERGX0Zvcm1GaWVsZCogcEZpZWxkID0gcFBERkZvcm0tPkdldEZpZWxkKGosIHNOYW1lKTsKKwkJCQlpZiAoIWJFbXB0eSAmJiBwRmllbGQtPkdldFZhbHVlKCkuSXNFbXB0eSgpKQorCQkJCQljb250aW51ZTsKKworCQkJCWZpZWxkT2JqZWN0cy5BZGQocEZpZWxkKTsKKwkJCX0KKwkJfQorCisJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwkJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwkJCisJCWlmIChwUERGSW50ZXJGb3JtLT5DaGVja1JlcXVpcmVkRmllbGRzKCZmaWVsZE9iamVjdHMsIFRSVUUpKQorCQl7CisJCQlwUnVudGltZS0+QmVnaW5CbG9jaygpOworCQkJcEludGVyRm9ybS0+U3VibWl0RmllbGRzKHN0clVSTCwgZmllbGRPYmplY3RzLCBUUlVFLCAhYkZERik7CisJCQlwUnVudGltZS0+RW5kQmxvY2soKTsKKwkJfQorCisJCXJldHVybiBUUlVFOworCX0KKworfQorCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisKK3ZvaWQgRG9jdW1lbnQ6OkF0dGFjaERvYyhDUERGU0RLX0RvY3VtZW50ICpwRG9jKQoreworCW1fcERvY3VtZW50ID0gcERvYzsKK30KKworQ1BERlNES19Eb2N1bWVudCAqIERvY3VtZW50OjpHZXRSZWFkZXJEb2MoKQoreworCXJldHVybiBtX3BEb2N1bWVudDsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6RXh0cmFjdEZpbGVOYW1lKENQREZTREtfRG9jdW1lbnQgKnBEb2MsQ0ZYX0J5dGVTdHJpbmcgJnN0ckZpbGVOYW1lKQoreworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6RXh0cmFjdEZvbGRlck5hbWUoQ1BERlNES19Eb2N1bWVudCAqcERvYyxDRlhfQnl0ZVN0cmluZyAmc3RyRm9sZGVyTmFtZSkKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmJvb2ttYXJrUm9vdChPQkpfUFJPUF9QQVJBTVMpCit7CQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjptYWlsRG9jKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUZYX0JPT0wgYlVJID0gVFJVRTsKKwlDRlhfV2lkZVN0cmluZyBjVG8gPSBMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgY0NjID0gTCIiOworCUNGWF9XaWRlU3RyaW5nIGNCY2MgPSBMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgY1N1YmplY3QgPSBMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgY01zZyA9IEwiIjsKKwkKKworCWJVSSA9IHBhcmFtcy5zaXplKCk+PTE/c3RhdGljX2Nhc3Q8RlhfQk9PTD4ocGFyYW1zWzBdKTpUUlVFOworCWNUbyA9IHBhcmFtcy5zaXplKCk+PTI/KGNvbnN0IHdjaGFyX3QqKXBhcmFtc1sxXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsKKwljQ2MgPSBwYXJhbXMuc2l6ZSgpPj0zPyhjb25zdCB3Y2hhcl90KilwYXJhbXNbMl0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTpMIiI7CisJY0JjYyA9IHBhcmFtcy5zaXplKCk+PTQ/KGNvbnN0IHdjaGFyX3QqKXBhcmFtc1szXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsKKwljU3ViamVjdCA9IHBhcmFtcy5zaXplKCk+PTU/KGNvbnN0IHdjaGFyX3QqKXBhcmFtc1s0XS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsKKwljTXNnID0gcGFyYW1zLnNpemUoKT49Nj8oY29uc3Qgd2NoYXJfdCopcGFyYW1zWzVdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk6TCIiOworCQorCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7CisKKwlpZihwYXJhbXMuc2l6ZSgpPj0xICYmIHBhcmFtc1swXS5HZXRUeXBlKCkgPT0gVlRfb2JqZWN0KQorCXsKKwkJSlNPYmplY3QgIHBPYmogPSAoSlNPYmplY3QgKXBhcmFtc1swXTsKKworCQl2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiYlVJIik7CisJCQliVUkgPSAoaW50KUNKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsKKworCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjVG8iKTsKKwkJCWNUbyA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNDYyIpOworCQkJY0NjID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisKKwkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiY0JjYyIpOworCQkJY0JjYyA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNTdWJqZWN0Iik7CisJCQljU3ViamVjdCA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNNc2ciKTsKKwkJCWNNc2cgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKwkKKwl9CisKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7CisJQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOworCisJcFJ1bnRpbWUtPkJlZ2luQmxvY2soKTsKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gcFJ1bnRpbWUtPkdldFJlYWRlckFwcCgpOworCXBFbnYtPkpTX2RvY21haWxGb3JtKE5VTEwsIDAsIGJVSSwgKEZYX0xQQ1dTVFIpY1RvLCAoRlhfTFBDV1NUUiljU3ViamVjdCwgKEZYX0xQQ1dTVFIpY0NjLCAoRlhfTFBDV1NUUiljQmNjLCAoRlhfTFBDV1NUUiljTXNnKTsKKwlwUnVudGltZS0+RW5kQmxvY2soKTsKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjphdXRob3IoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZfRGljdGlvbmFyeSogcERpY3Rpb25hcnkgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKS0+R2V0SW5mbygpOworCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJBdXRob3IiKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCWVsc2UKKwl7CisJCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkpIHJldHVybiBGQUxTRTsKKworCQlDRlhfV2lkZVN0cmluZyBjc0F1dGhvcjsKKwkJdnAgPj4gY3NBdXRob3I7CisJCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiQXV0aG9yIiwgUERGX0VuY29kZVRleHQoY3NBdXRob3IpKTsKKwkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorfQorCitGWF9CT09MIERvY3VtZW50OjppbmZvKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDUERGX0RpY3Rpb25hcnkqIHBEaWN0aW9uYXJ5ID0gbV9wRG9jdW1lbnQtPkdldERvY3VtZW50KCktPkdldEluZm8oKTsKKwlpZiAoIXBEaWN0aW9uYXJ5KXJldHVybiBGQUxTRTsKKworCUNGWF9XaWRlU3RyaW5nIGN3QXV0aG9yCQkJPSBwRGljdGlvbmFyeS0+R2V0VW5pY29kZVRleHQoIkF1dGhvciIpOworCUNGWF9XaWRlU3RyaW5nIGN3VGl0bGUJCQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiVGl0bGUiKTsKKwlDRlhfV2lkZVN0cmluZyBjd1N1YmplY3QJCT0gcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJTdWJqZWN0Iik7CisJQ0ZYX1dpZGVTdHJpbmcgY3dLZXl3b3JkcwkJPSBwRGljdGlvbmFyeS0+R2V0VW5pY29kZVRleHQoIktleXdvcmRzIik7CisJQ0ZYX1dpZGVTdHJpbmcgY3dDcmVhdG9yCQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiQ3JlYXRvciIpOworCUNGWF9XaWRlU3RyaW5nIGN3UHJvZHVjZXIJCT0gcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJQcm9kdWNlciIpOworCUNGWF9XaWRlU3RyaW5nIGN3Q3JlYXRpb25EYXRlCT0gcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJDcmVhdGlvbkRhdGUiKTsKKwlDRlhfV2lkZVN0cmluZyBjd01vZERhdGUJCT0gcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJNb2REYXRlIik7CisJQ0ZYX1dpZGVTdHJpbmcgY3dUcmFwcGVkCQk9IHBEaWN0aW9uYXJ5LT5HZXRVbmljb2RlVGV4dCgiVHJhcHBlZCIpOworCisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsKKwlpZiAoIXZwLklzU2V0dGluZygpKQorCXsKKwkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CisJCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKworCQlKU0ZYT2JqZWN0ICBwT2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgcENvbnRleHQsIC0xKTsKKworCQlKU19QdXRPYmplY3RTdHJpbmcoaXNvbGF0ZSxwT2JqLCBMIkF1dGhvciIsIGN3QXV0aG9yKTsKKwkJSlNfUHV0T2JqZWN0U3RyaW5nKGlzb2xhdGUscE9iaiwgTCJUaXRsZSIsIGN3VGl0bGUpOworCQlKU19QdXRPYmplY3RTdHJpbmcoaXNvbGF0ZSxwT2JqLCBMIlN1YmplY3QiLCBjd1N1YmplY3QpOworCQlKU19QdXRPYmplY3RTdHJpbmcoaXNvbGF0ZSxwT2JqLCBMIktleXdvcmRzIiwgY3dLZXl3b3Jkcyk7CisJCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIEwiQ3JlYXRvciIsIGN3Q3JlYXRvcik7CisJCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIEwiUHJvZHVjZXIiLCBjd1Byb2R1Y2VyKTsKKwkJSlNfUHV0T2JqZWN0U3RyaW5nKGlzb2xhdGUscE9iaiwgTCJDcmVhdGlvbkRhdGUiLCBjd0NyZWF0aW9uRGF0ZSk7CisJCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIEwiTW9kRGF0ZSIsIGN3TW9kRGF0ZSk7CisJCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBPYmosIEwiVHJhcHBlZCIsIGN3VHJhcHBlZCk7CisKKy8vIEl0J3MgdG8gYmUgY29tcGF0aWJsZSB0byBub24tc3RhbmRhcmQgaW5mbyBkaWN0aW9uYXJ5LgkKKwkJRlhfUE9TSVRJT04gcG9zID0gcERpY3Rpb25hcnktPkdldFN0YXJ0UG9zKCk7CisJCXdoaWxlKHBvcykKKwkJeworCQkJQ0ZYX0J5dGVTdHJpbmcgYnNLZXk7CisJCQlDUERGX09iamVjdCogcFZhbHVlT2JqID0gcERpY3Rpb25hcnktPkdldE5leHRFbGVtZW50KHBvcywgYnNLZXkpOworCQkJQ0ZYX1dpZGVTdHJpbmcgd3NLZXkgID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21VVEY4KGJzS2V5KTsKKwkJCWlmKChwVmFsdWVPYmotPkdldFR5cGUoKT09UERGT0JKX1NUUklORykgfHwgKHBWYWx1ZU9iai0+R2V0VHlwZSgpPT1QREZPQkpfTkFNRSkgKQorCQkJCQlKU19QdXRPYmplY3RTdHJpbmcoaXNvbGF0ZSxwT2JqLCB3c0tleSwgcFZhbHVlT2JqLT5HZXRVbmljb2RlVGV4dCgpKTsKKwkJCWlmKHBWYWx1ZU9iai0+R2V0VHlwZSgpPT1QREZPQkpfTlVNQkVSKQorCQkJCUpTX1B1dE9iamVjdE51bWJlcihpc29sYXRlLHBPYmosIHdzS2V5LCAoZmxvYXQpcFZhbHVlT2JqLT5HZXROdW1iZXIoKSk7CisJCQlpZihwVmFsdWVPYmotPkdldFR5cGUoKT09UERGT0JKX0JPT0xFQU4pCisJCQkJSlNfUHV0T2JqZWN0Qm9vbGVhbihpc29sYXRlLHBPYmosIHdzS2V5LCAoYm9vbClwVmFsdWVPYmotPkdldEludGVnZXIoKSk7CisJCX0KKworCQl2cCA8PCBwT2JqOworCQlyZXR1cm4gVFJVRTsKKwl9CisJZWxzZQorCXsKKwkJcmV0dXJuIFRSVUU7CisJfQorfQorCitGWF9CT09MIERvY3VtZW50OjpjcmVhdGlvbkRhdGUoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZfRGljdGlvbmFyeSogcERpY3Rpb25hcnkgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKS0+R2V0SW5mbygpOworCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJDcmVhdGlvbkRhdGUiKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCWVsc2UKKwl7CisJCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkpIHJldHVybiBGQUxTRTsKKworCQlDRlhfV2lkZVN0cmluZyBjc0NyZWF0aW9uRGF0ZTsKKwkJdnAgPj4gY3NDcmVhdGlvbkRhdGU7CisJCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiQ3JlYXRpb25EYXRlIiwgUERGX0VuY29kZVRleHQoY3NDcmVhdGlvbkRhdGUpKTsKKwkJbV9wRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsKKworCQlyZXR1cm4gVFJVRTsKKwl9Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmNyZWF0b3IoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZfRGljdGlvbmFyeSogcERpY3Rpb25hcnkgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKS0+R2V0SW5mbygpOworCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJDcmVhdG9yIik7CisJCXJldHVybiBUUlVFOworCX0KKwllbHNlCisJeworCQlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9NT0RJRlkpKSByZXR1cm4gRkFMU0U7CisKKwkJQ0ZYX1dpZGVTdHJpbmcgY3NDcmVhdG9yOworCQl2cCA+PiBjc0NyZWF0b3I7CisJCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiQ3JlYXRvciIsIFBERl9FbmNvZGVUZXh0KGNzQ3JlYXRvcikpOworCQltX3BEb2N1bWVudC0+U2V0Q2hhbmdlTWFyaygpOworCQlyZXR1cm4gVFJVRTsKKwl9Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmRlbGF5KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAodnAuSXNHZXR0aW5nKCkpCisJeworCQl2cCA8PCBtX2JEZWxheTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCWVsc2UKKwl7CisJCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCQlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9NT0RJRlkpKSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiOworCQl2cCA+PiBiOworCisJCW1fYkRlbGF5ID0gYjsKKworCQlpZiAobV9iRGVsYXkpIAorCQl7CisJCQlmb3IgKGludCBpPTAsc3o9bV9EZWxheURhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQkJZGVsZXRlIG1fRGVsYXlEYXRhLkdldEF0KGkpOworCisJCQltX0RlbGF5RGF0YS5SZW1vdmVBbGwoKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCWZvciAoaW50IGk9MCxzej1tX0RlbGF5RGF0YS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJCXsKKwkJCQlpZiAoQ0pTX0RlbGF5RGF0YSogcERhdGEgPSBtX0RlbGF5RGF0YS5HZXRBdChpKSkKKwkJCQl7CisJCQkJCUZpZWxkOjpEb0RlbGF5KG1fcERvY3VtZW50LCBwRGF0YSk7CisJCQkJCWRlbGV0ZSBtX0RlbGF5RGF0YS5HZXRBdChpKTsKKwkJCQl9CisJCQl9CisJCQltX0RlbGF5RGF0YS5SZW1vdmVBbGwoKTsKKwkJfQorCisJCXJldHVybiBUUlVFOworCX0KK30KKworRlhfQk9PTCBEb2N1bWVudDo6a2V5d29yZHMoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZfRGljdGlvbmFyeSogcERpY3Rpb25hcnkgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKS0+R2V0SW5mbygpOworCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJLZXl3b3JkcyIpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJZWxzZQorCXsKKwkJaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSkgcmV0dXJuIEZBTFNFOworCisJCUNGWF9XaWRlU3RyaW5nIGNzS2V5d29yZHM7CisJCXZwID4+IGNzS2V5d29yZHM7CisJCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiS2V5d29yZHMiLCBQREZfRW5jb2RlVGV4dChjc0tleXdvcmRzKSk7CisJCW1fcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7CisJCXJldHVybiBUUlVFOworCX0KK30KKworRlhfQk9PTCBEb2N1bWVudDo6bW9kRGF0ZShPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwRGljdGlvbmFyeSA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLT5HZXRJbmZvKCk7CisJaWYgKCFwRGljdGlvbmFyeSlyZXR1cm4gRkFMU0U7CisKKwlpZiAodnAuSXNHZXR0aW5nKCkpCisJeworCQl2cCA8PCBwRGljdGlvbmFyeS0+R2V0VW5pY29kZVRleHQoIk1vZERhdGUiKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCWVsc2UKKwl7CisJCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkpIHJldHVybiBGQUxTRTsKKworCQlDRlhfV2lkZVN0cmluZyBjc21vZERhdGU7CisJCXZwID4+IGNzbW9kRGF0ZTsKKwkJcERpY3Rpb25hcnktPlNldEF0U3RyaW5nKCJNb2REYXRlIiwgUERGX0VuY29kZVRleHQoY3Ntb2REYXRlKSk7CisJCW1fcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7CisJCXJldHVybiBUUlVFOworCX0KK30KKworRlhfQk9PTCBEb2N1bWVudDo6cHJvZHVjZXIoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZfRGljdGlvbmFyeSogcERpY3Rpb25hcnkgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKS0+R2V0SW5mbygpOworCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJQcm9kdWNlciIpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJZWxzZQorCXsKKwkJaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSkgcmV0dXJuIEZBTFNFOworCisJCUNGWF9XaWRlU3RyaW5nIGNzcHJvZHVjZXI7CisJCXZwID4+IGNzcHJvZHVjZXI7CisJCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiUHJvZHVjZXIiLCBQREZfRW5jb2RlVGV4dChjc3Byb2R1Y2VyKSk7CisJCW1fcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7CisJCXJldHVybiBUUlVFOworCX0KK30KKworRlhfQk9PTCBEb2N1bWVudDo6c3ViamVjdChPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJQ1BERl9EaWN0aW9uYXJ5KiBwRGljdGlvbmFyeSA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpLT5HZXRJbmZvKCk7CisJaWYgKCFwRGljdGlvbmFyeSlyZXR1cm4gRkFMU0U7CisKKwlpZiAodnAuSXNHZXR0aW5nKCkpCisJeworCQl2cCA8PCBwRGljdGlvbmFyeS0+R2V0VW5pY29kZVRleHQoIlN1YmplY3QiKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCWVsc2UKKwl7CisJCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkpIHJldHVybiBGQUxTRTsKKworCQlDRlhfV2lkZVN0cmluZyBjc3N1YmplY3Q7CisJCXZwID4+IGNzc3ViamVjdDsKKwkJcERpY3Rpb25hcnktPlNldEF0U3RyaW5nKCJTdWJqZWN0IiwgUERGX0VuY29kZVRleHQoY3NzdWJqZWN0KSk7CisJCW1fcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7CisJCXJldHVybiBUUlVFOworCX0KK30KKworRlhfQk9PTCBEb2N1bWVudDo6dGl0bGUoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmIChtX3BEb2N1bWVudCA9PSBOVUxMIHx8IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpID09IE5VTEwpCisJCXJldHVybiBGQUxTRTsKKworCUNQREZfRGljdGlvbmFyeSogcERpY3Rpb25hcnkgPSBtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKS0+R2V0SW5mbygpOworCWlmICghcERpY3Rpb25hcnkpcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgcERpY3Rpb25hcnktPkdldFVuaWNvZGVUZXh0KCJUaXRsZSIpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJZWxzZQorCXsKKwkJaWYgKCFtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSkgcmV0dXJuIEZBTFNFOworCisJCUNGWF9XaWRlU3RyaW5nIGNzdGl0bGU7CisJCXZwID4+IGNzdGl0bGU7CisJCXBEaWN0aW9uYXJ5LT5TZXRBdFN0cmluZygiVGl0bGUiLCBQREZfRW5jb2RlVGV4dChjc3RpdGxlKSk7CisJCW1fcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7CisJCXJldHVybiBUUlVFOworCX0KK30KKworRlhfQk9PTCBEb2N1bWVudDo6bnVtUGFnZXMoT0JKX1BST1BfUEFSQU1TKQoreworCWlmICh2cC5Jc0dldHRpbmcoKSkKKwl7CisJCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKwkJdnAgPDwgbV9wRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJZWxzZQorCXsKKwkJcmV0dXJuIEZBTFNFOworCX0KK30KKworRlhfQk9PTCBEb2N1bWVudDo6ZXh0ZXJuYWwoT0JKX1BST1BfUEFSQU1TKQoreworCS8vSW4gQ2hyb21lIGNhc2Usc2hvdWxkIGFsd2F5cyByZXR1cm4gdHJ1ZS4KKwl2cCA8PCBUUlVFOworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpmaWxlc2l6ZShPQkpfUFJPUF9QQVJBTVMpCit7CisJaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7CisKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKy8vIAlDRmlsZSBmaWxlKG1fcERvY3VtZW50LT5HZXRQYXRoKCksIENGaWxlOjptb2RlUmVhZCB8IENGaWxlOjp0eXBlQmluYXJ5IHwgQ0ZpbGU6OnNoYXJlRGVueU5vbmUpOworLy8gCXZwIDw8IChkb3VibGUpZmlsZS5HZXRMZW5ndGgoKTsKKy8vIAlmaWxlLkNsb3NlKCk7CisKKwlpZiAoIG1fcERvY3VtZW50LT5HZXRQYXRoKCkuSXNFbXB0eSgpID09IEZBTFNFKQorCXsKKwkJQ0ZYX0J5dGVTdHJpbmcgYnNTdHIgPSBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoIG1fcERvY3VtZW50LT5HZXRQYXRoKCkgKTsKKwkJRklMRSAqIHBGaWxlID0gTlVMTDsKKwkJcEZpbGUgPSBmb3BlbiggYnNTdHIuR2V0QnVmZmVyKCBic1N0ci5HZXRMZW5ndGgoKSApLCAicmIiICk7CisJCWlmICggcEZpbGUgKQorCQl7CisJCQlmc2VlayggcEZpbGUsIDAsIFNFRUtfRU5EICk7CisJCQlsb25nIGxTaXplID0gZnRlbGwoIHBGaWxlICk7CisJCQlmY2xvc2UoIHBGaWxlICk7CisJCQlwRmlsZSA9IE5VTEw7CisKKwkJCXZwIDw8IChGWF9JTlQzMikobFNpemUpOworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisKKwl2cCA8PCAwOworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50Ojptb3VzZVgoT0JKX1BST1BfUEFSQU1TKQoreworIAlyZXR1cm4gVFJVRTsJCit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6Om1vdXNlWShPQkpfUFJPUF9QQVJBTVMpCit7CisgCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpiYXNlVVJMKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAodnAuSXNHZXR0aW5nKCkpCisJeworCQl2cCA8PCBtX2N3QmFzZVVSTDsKKwkJcmV0dXJuIFRSVUU7CisJfQorCWVsc2UKKwl7CisJCXZwID4+IG1fY3dCYXNlVVJMOworCQlyZXR1cm4gVFJVRTsKKwl9Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmNhbGN1bGF0ZShPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCWlmICh2cC5Jc0dldHRpbmcoKSkKKwl7CisJCWlmIChwSW50ZXJGb3JtLT5Jc0NhbGN1bGF0ZUVuYWJsZWQoKSkKKwkJCXZwIDw8IHRydWU7CisJCWVsc2UKKwkJCXZwIDw8IGZhbHNlOworCX0KKwllbHNlCisJeworCQlib29sIGJDYWxjdWxhdGU7CisJCXZwID4+IGJDYWxjdWxhdGU7CisKKwkJcEludGVyRm9ybS0+RW5hYmxlQ2FsY3VsYXRlKGJDYWxjdWxhdGUpOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50Ojpkb2N1bWVudEZpbGVOYW1lKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKQorCQlyZXR1cm4gRkFMU0U7CisKKwlDRlhfV2lkZVN0cmluZyB3c0ZpbGVQYXRoID0gbV9wRG9jdW1lbnQtPkdldFBhdGgoKTsKKworCUZYX0lOVDMyIGkgPSB3c0ZpbGVQYXRoLkdldExlbmd0aCgpIC0gMTsKKwlmb3IgKCA7IGkgPj0gMDsgaS0tICkKKwl7CisJCWlmICggd3NGaWxlUGF0aC5HZXRBdCggaSApID09IEwnXFwnIHx8IHdzRmlsZVBhdGguR2V0QXQoIGkgKSA9PSBMJy8nICkKKwkJCWJyZWFrOworCX0KKwlpZiAoIGkgPj0gMCAmJiBpIDwgd3NGaWxlUGF0aC5HZXRMZW5ndGgoKSAtIDEgKQorCXsKKwkJdnAgPDwgKCB3c0ZpbGVQYXRoLkdldEJ1ZmZlciggd3NGaWxlUGF0aC5HZXRMZW5ndGgoKSApICsgaSArIDEgKTsKKwl9ZWxzZXsKKwkJdnAgPDwgTCIiOworCX0KKwlyZXR1cm4gVFJVRTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgRG9jdW1lbnQ6OlJldmVyc2FsU3RyKENGWF9XaWRlU3RyaW5nIGNiRnJvbSkKK3sKKwl3Y2hhcl90KiBwRnJvbSA9IE5VTEw7CisJaW50IGlMZW50aCA9IGNiRnJvbS5HZXRMZW5ndGgoKTsKKwl3Y2hhcl90KiBwUmVzdWx0ID0gKHdjaGFyX3QqKW1hbGxvYygoaUxlbnRoKzEpICogc2l6ZW9mKHdjaGFyX3QpKTsKKwltZW1zZXQocFJlc3VsdCwgMCwgKGlMZW50aCsxKSk7CisJcEZyb20gPSAod2NoYXJfdCopY2JGcm9tLkdldEJ1ZmZlcihpTGVudGgpOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCBpTGVudGg7IGkrKykKKwl7CisJCXBSZXN1bHRbaV0gPSAqKHBGcm9tICsgaUxlbnRoIC0gaSAtIDEpOworCX0KKworCWNiRnJvbS5SZWxlYXNlQnVmZmVyKCk7CisJQ0ZYX1dpZGVTdHJpbmcgY2JSZXQgPSBDRlhfV2lkZVN0cmluZyhwUmVzdWx0KTsKKwlmcmVlKHBSZXN1bHQpOworCXBSZXN1bHQgPSBOVUxMOworCXJldHVybiBjYlJldDsKK30KKworQ0ZYX1dpZGVTdHJpbmcgRG9jdW1lbnQ6OkN1dFN0cmluZyhDRlhfV2lkZVN0cmluZyBjYkZyb20pCit7CisJd2NoYXJfdCogcEZyb20gPSBOVUxMOworCWludCBpTGVudGggPSBjYkZyb20uR2V0TGVuZ3RoKCk7CisJd2NoYXJfdCogcFJlc3VsdCA9ICh3Y2hhcl90KiltYWxsb2MoKGlMZW50aCsxKSAqIHNpemVvZih3Y2hhcl90KSk7CisJbWVtc2V0KHBSZXN1bHQsIDAsIChpTGVudGgrMSkpOworCXBGcm9tID0gKHdjaGFyX3QqKWNiRnJvbS5HZXRCdWZmZXIoaUxlbnRoKTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgaUxlbnRoOyBpKyspCisJeworCQlpZiAocEZyb21baV0gPT0gTCdcXCcgfHwgcEZyb21baV0gPT0gTCcvJykKKwkJCWJyZWFrOworCQlwUmVzdWx0W2ldID0gcEZyb21baV07CisJfQorCisJY2JGcm9tLlJlbGVhc2VCdWZmZXIoKTsKKwlDRlhfV2lkZVN0cmluZyBjYlJldCA9IENGWF9XaWRlU3RyaW5nKHBSZXN1bHQpOworCWZyZWUocFJlc3VsdCk7CisJcFJlc3VsdCA9IE5VTEw7CisJcmV0dXJuIGNiUmV0OworfQorCitGWF9CT09MIERvY3VtZW50OjpwYXRoKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKSByZXR1cm4gRkFMU0U7CisKKwl2cCA8PCBhcHA6OlN5c1BhdGhUb1BERlBhdGgobV9wRG9jdW1lbnQtPkdldFBhdGgoKSk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6cGFnZVdpbmRvd1JlY3QoT0JKX1BST1BfUEFSQU1TKQoreworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpsYXlvdXQoT0JKX1BST1BfUEFSQU1TKQorewkKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6YWRkTGluayhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKyAJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmNsb3NlRG9jKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCisJCisJCisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6Z2V0UGFnZUJveChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKyAJcmV0dXJuIFRSVUU7Cit9CisKKworRlhfQk9PTCBEb2N1bWVudDo6Z2V0QW5ub3QoT0JKX01FVEhPRF9QQVJBTVMpCit7CisgCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpnZXRBbm5vdHMoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJdlJldC5TZXROdWxsKCk7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmdldEFubm90M0QoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJdlJldC5TZXROdWxsKCk7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmdldEFubm90czNEKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXZSZXQgPSBWVF91bmRlZmluZWQ7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmdldE9DR3MoT0JKX01FVEhPRF9QQVJBTVMpCit7CQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpnZXRMaW5rcyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworYm9vbCBEb2N1bWVudDo6SXNFbmNsb3NlZEluUmVjdChDRlhfRmxvYXRSZWN0IHJlY3QsIENGWF9GbG9hdFJlY3QgTGlua1JlY3QpCit7CisJaWYgKHJlY3QubGVmdCA8PSBMaW5rUmVjdC5sZWZ0CisJICAmJiByZWN0LnRvcCA8PSBMaW5rUmVjdC50b3AKKwkgICYmIHJlY3QucmlnaHQgPj0gTGlua1JlY3QucmlnaHQKKwkgICYmIHJlY3QuYm90dG9tID49IExpbmtSZWN0LmJvdHRvbSkKKwkJcmV0dXJuIHRydWU7CisJZWxzZQorCQlyZXR1cm4gZmFsc2U7Cit9CisKK3ZvaWQgSWNvblRyZWU6Okluc2VydEljb25FbGVtZW50KEljb25FbGVtZW50KiBwTmV3SWNvbikKK3sKKwlpZiAoIXBOZXdJY29uKXJldHVybjsKKworCWlmIChtX3BIZWFkID09IE5VTEwgJiYgbV9wRW5kID09IE5VTEwpCisJeworCQltX3BIZWFkID0gbV9wRW5kID0gcE5ld0ljb247CisJCW1faUxlbmd0aCsrOworCX0KKwllbHNlCisJeworCQltX3BFbmQtPk5leHRJY29uID0gcE5ld0ljb247CisJCW1fcEVuZCA9IHBOZXdJY29uOworCQltX2lMZW5ndGgrKzsKKwl9Cit9CisKK3ZvaWQgSWNvblRyZWU6OkRlbGV0ZUljb25UcmVlKCkKK3sKKwlpZiAoIW1fcEhlYWQgfHwgIW1fcEVuZClyZXR1cm47CisJCisJSWNvbkVsZW1lbnQqIHBUZW1wID0gTlVMTDsKKwl3aGlsZShtX3BFbmQgIT0gbV9wSGVhZCkKKwl7CisJCXBUZW1wID0gbV9wSGVhZDsKKwkJbV9wSGVhZCA9IG1fcEhlYWQtPk5leHRJY29uOworCQlkZWxldGUgcFRlbXA7CisJfQorCisJZGVsZXRlIG1fcEVuZDsKKwltX3BIZWFkID0gTlVMTDsKKwltX3BFbmQgPSBOVUxMOworfQorCitpbnQgSWNvblRyZWU6OkdldExlbmd0aCgpCit7CisJcmV0dXJuIG1faUxlbmd0aDsKK30KKworSWNvbkVsZW1lbnQqIEljb25UcmVlOjpvcGVyYXRvciBbXShpbnQgaUluZGV4KQoreworCWlmIChpSW5kZXggPj0gMCAmJiBpSW5kZXggPD0gbV9pTGVuZ3RoKQorCXsKKwkJSWNvbkVsZW1lbnQqIHBUZW1wID0gbV9wSGVhZDsKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBpSW5kZXg7IGkrKykKKwkJeworCQkJcFRlbXAgPSBwVGVtcC0+TmV4dEljb247CisJCX0KKwkJcmV0dXJuIHBUZW1wOworCX0KKwllbHNlCisJCXJldHVybiBOVUxMOworfQorCit2b2lkIEljb25UcmVlOjpEZWxldGVJY29uRWxlbWVudChDRlhfV2lkZVN0cmluZyBzd0ljb25OYW1lKQoreworCUljb25FbGVtZW50KiBwVGVtcCA9IG1fcEhlYWQ7CisJaW50IGlMb29wQ291bnQgPSBtX2lMZW5ndGg7IAorCWZvciAoaW50IGkgPSAwOyBpIDwgaUxvb3BDb3VudCAtIDE7IGkrKykKKwl7CisJCWlmIChwVGVtcCA9PSBtX3BFbmQpCisJCQlicmVhazsKKwkKKwkJaWYgKG1fcEhlYWQtPkljb25OYW1lID09IHN3SWNvbk5hbWUpCisJCXsKKwkJCW1fcEhlYWQgPSBtX3BIZWFkLT5OZXh0SWNvbjsKKwkJCWRlbGV0ZSBwVGVtcDsKKwkJCW1faUxlbmd0aC0tOworCQkJcFRlbXAgPSBtX3BIZWFkOworCQl9CisJCWlmIChwVGVtcC0+TmV4dEljb24tPkljb25OYW1lID09IHN3SWNvbk5hbWUpCisJCXsKKwkJCWlmIChwVGVtcC0+TmV4dEljb24gPT0gbV9wRW5kKQorCQkJeworCQkJCW1fcEVuZCA9IHBUZW1wOworCQkJCWRlbGV0ZSBwVGVtcC0+TmV4dEljb247CisJCQkJbV9pTGVuZ3RoLS07CisJCQkJcFRlbXAtPk5leHRJY29uID0gTlVMTDsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlJY29uRWxlbWVudCogcEVsZW1lbnQgPSBwVGVtcC0+TmV4dEljb247CisJCQkJcFRlbXAtPk5leHRJY29uID0gcFRlbXAtPk5leHRJY29uLT5OZXh0SWNvbjsKKwkJCQlkZWxldGUgcEVsZW1lbnQ7CisJCQkJbV9pTGVuZ3RoLS07CisJCQkJcEVsZW1lbnQgPSBOVUxMOworCQkJfQorCisJCQljb250aW51ZTsKKwkJfQorCisJCXBUZW1wID0gcFRlbXAtPk5leHRJY29uOworCX0KK30KKworRlhfQk9PTCBEb2N1bWVudDo6YWRkSWNvbihPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlpZiAocGFyYW1zLnNpemUoKSAhPSAyKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlDRlhfV2lkZVN0cmluZyBzd0ljb25OYW1lID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJCisJSlNGWE9iamVjdCBwSlNJY29uID0gKEpTRlhPYmplY3QpcGFyYW1zWzFdOworCWlmIChKU19HZXRPYmpEZWZuSUQocEpTSWNvbikgIT0gSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJJY29uIikpIHJldHVybiBGQUxTRTsKKworCUNKU19FbWJlZE9iaiogcEVtYmVkT2JqID0gKChDSlNfT2JqZWN0KilwYXJhbXNbMV0pLT5HZXRFbWJlZE9iamVjdCgpOworCWlmICghcEVtYmVkT2JqKXJldHVybiBGQUxTRTsKKwlJY29uKiBwSWNvbiA9IChJY29uKilwRW1iZWRPYmo7CisKKwlpZiAoIW1fcEljb25UcmVlKQorCQltX3BJY29uVHJlZSA9IG5ldyBJY29uVHJlZSgpOworCisJSWNvbkVsZW1lbnQqIHBOZXdJY29uID0gbmV3IEljb25FbGVtZW50KCk7CisJcE5ld0ljb24tPkljb25OYW1lID0gc3dJY29uTmFtZTsKKwlwTmV3SWNvbi0+TmV4dEljb24gPSBOVUxMOworCXBOZXdJY29uLT5JY29uU3RyZWFtID0gcEljb247CisJbV9wSWNvblRyZWUtPkluc2VydEljb25FbGVtZW50KHBOZXdJY29uKTsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6aWNvbnMoT0JKX1BST1BfUEFSQU1TKQoreworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwkJcmV0dXJuIEZBTFNFOworCisJaWYgKCFtX3BJY29uVHJlZSkKKwl7CisJCXZwLlNldE51bGwoKTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJQ0pTX0FycmF5IEljb25zKG1faXNvbGF0ZSk7CisJSWNvbkVsZW1lbnQqIHBJY29uRWxlbWVudCA9IE5VTEw7CisJaW50IGlJY29uVHJlZUxlbmd0aCA9IG1fcEljb25UcmVlLT5HZXRMZW5ndGgoKTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKworCWZvciAoaW50IGkgPSAwOyBpIDwgaUljb25UcmVlTGVuZ3RoOyBpKyspCisJeworCQlwSWNvbkVsZW1lbnQgPSAoKm1fcEljb25UcmVlKVtpXTsKKwkJCisJCUpTRlhPYmplY3QgIHBPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBwQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJJY29uIikpOworCQlpZiAocE9iai5Jc0VtcHR5KCkpIHJldHVybiBGQUxTRTsKKwkJCQkKKwkJQ0pTX0ljb24gKiBwSlNfSWNvbiA9IChDSlNfSWNvbiAqKUpTX0dldFByaXZhdGUocE9iaik7CisJCWlmICghcEpTX0ljb24pIHJldHVybiBGQUxTRTsKKworCQlJY29uKiBwSWNvbiA9IChJY29uKilwSlNfSWNvbi0+R2V0RW1iZWRPYmplY3QoKTsKKwkJaWYgKCFwSWNvbilyZXR1cm4gRkFMU0U7CisKKwkJcEljb24tPlNldFN0cmVhbShwSWNvbkVsZW1lbnQtPkljb25TdHJlYW0tPkdldFN0cmVhbSgpKTsKKwkJcEljb24tPlNldEljb25OYW1lKHBJY29uRWxlbWVudC0+SWNvbk5hbWUpOworCQlJY29ucy5TZXRFbGVtZW50KGksIENKU19WYWx1ZShtX2lzb2xhdGUscEpTX0ljb24pKTsKKwl9CisKKwl2cCA8PCBJY29uczsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6Z2V0SWNvbihPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlpZiAocGFyYW1zLnNpemUoKSAhPSAxKXJldHVybiBGQUxTRTsKKwlpZighbV9wSWNvblRyZWUpCisJCXJldHVybiBGQUxTRTsKKwlDRlhfV2lkZVN0cmluZyBzd0ljb25OYW1lID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJaW50IGlJY29uQ291bnRzID0gbV9wSWNvblRyZWUtPkdldExlbmd0aCgpOworCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCisJZm9yIChpbnQgaSA9IDA7IGkgPCBpSWNvbkNvdW50czsgaSsrKQorCXsKKwkJaWYgKCgqbV9wSWNvblRyZWUpW2ldLT5JY29uTmFtZSA9PSBzd0ljb25OYW1lKQorCQl7CisJCQlJY29uKiBwUmV0SWNvbiA9ICgqbV9wSWNvblRyZWUpW2ldLT5JY29uU3RyZWFtOworCQkJCQorCQkJSlNGWE9iamVjdCAgcE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIkljb24iKSk7CisJCQlpZiAocE9iai5Jc0VtcHR5KCkpIHJldHVybiBGQUxTRTsKKwkJCQkJCisJCQlDSlNfSWNvbiAqIHBKU19JY29uID0gKENKU19JY29uICopSlNfR2V0UHJpdmF0ZShwT2JqKTsKKwkJCWlmICghcEpTX0ljb24pIHJldHVybiBGQUxTRTsKKworCQkJSWNvbiogcEljb24gPSAoSWNvbiopcEpTX0ljb24tPkdldEVtYmVkT2JqZWN0KCk7CisJCQlpZiAoIXBJY29uKXJldHVybiBGQUxTRTsKKworCQkJcEljb24tPlNldEljb25OYW1lKHN3SWNvbk5hbWUpOworCQkJcEljb24tPlNldFN0cmVhbShwUmV0SWNvbi0+R2V0U3RyZWFtKCkpOworCQkJdlJldCA9IHBKU19JY29uOworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OnJlbW92ZUljb24oT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSlyZXR1cm4gRkFMU0U7CisJaWYoIW1fcEljb25UcmVlKQorCQlyZXR1cm4gRkFMU0U7CisJQ0ZYX1dpZGVTdHJpbmcgc3dJY29uTmFtZSA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworI2lmbmRlZiBGT1hJVF9DSFJPTUVfQlVJTEQKKwltX3BJY29uVHJlZS0+RGVsZXRlSWNvbkVsZW1lbnQoc3dJY29uTmFtZSk7CisjZW5kaWYKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6Y3JlYXRlRGF0YU9iamVjdChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlpZiAoSXNTYWZlTW9kZShjYykpIHJldHVybiBUUlVFOworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNGWF9XaWRlU3RyaW5nIHN3TmFtZSA9IEwiIjsKKwlDRlhfQnl0ZVN0cmluZyBzYk5hbWUgPSAiIjsKKwlDRlhfV2lkZVN0cmluZyBzd1ZhbHVlID0gTCIiOworCUNGWF9XaWRlU3RyaW5nIHN3TUlNRVR5cGUgPSBMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgc3dDcnlwdEZpbHRlciA9IEwiIjsKKwlDRlhfQnl0ZVN0cmluZyBzYkZpbGVWYWx1ZSA9ICIiOworCQorCWludCBpUGFyYW1TaXplID0gcGFyYW1zLnNpemUoKTsKKwlmb3IgKGludCBpID0gMDsgaSA8IGlQYXJhbVNpemU7IGkrKykKKwl7CisJCWlmIChpID09IDApCisJCQlzd05hbWUgPSBwYXJhbXNbMF07CisJCWlmIChpID09IDEpCisJCQlzd1ZhbHVlID0gcGFyYW1zWzFdOworCQlpZiAoaSA9PSAyKQorCQkJc3dNSU1FVHlwZSA9IHBhcmFtc1syXTsKKwkJaWYgKGkgPT0gMykKKwkJCXN3Q3J5cHRGaWx0ZXIgPSBwYXJhbXNbNF07CisJfQorCisJRklMRSogcEZpbGUgPSBOVUxMOworCisJLy9DRmlsZVN0YXR1cyBmaWxlU3RhdHVzOworCWNvbnN0IGludCBCVUZTSVpFID0gMTc7CisJRlhfQllURSBidWZbQlVGU0laRV07CisJRlhfQllURSAqcEJ1ZmZlciA9IE5VTEw7CisJY2hhciogcEJ1ZiA9IE5VTEw7CisJaW50IG5GaWxlU2l6ZSA9IDA7CisJc2JGaWxlVmFsdWUgPSBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoc3dWYWx1ZSk7CisJc2JOYW1lID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHN3TmFtZSk7CisJaW50IGlCdWZMZW5ndGggPSBzYkZpbGVWYWx1ZS5HZXRMZW5ndGgoKTsKKwlwQnVmID0gKGNoYXIqKW1hbGxvYyhzaXplb2YoY2hhcikgKiBpQnVmTGVuZ3RoKTsKKwlwQnVmID0gc2JGaWxlVmFsdWUuR2V0QnVmZmVyKGlCdWZMZW5ndGgpOworCisJaWYgKCBOVUxMID09IChwRmlsZSA9IEZYU1lTX2ZvcGVuKCBzYk5hbWUuR2V0QnVmZmVyKHNiTmFtZS5HZXRMZW5ndGgoKSksICJ3YisiICkpICkKKwl7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlmd3JpdGUoIHBCdWYsIHNpemVvZihjaGFyKSwgaUJ1Zkxlbmd0aCwgcEZpbGUgKTsKKwlmY2xvc2UoIHBGaWxlICk7CisJcEZpbGUgPSBOVUxMOworCisJcEZpbGUgPSBGWFNZU19mb3Blbiggc2JOYW1lLkdldEJ1ZmZlcihzYk5hbWUuR2V0TGVuZ3RoKCkpLCAicmIrIiApOworCWZzZWVrKCBwRmlsZSwgMCwgU0VFS19FTkQgKTsKKwluRmlsZVNpemUgPSBmdGVsbCggcEZpbGUgKTsKKworCXBCdWZmZXIgPSBuZXcgRlhfQllURVtuRmlsZVNpemVdOworCWZzZWVrKCBwRmlsZSwgMCwgU0VFS19TRVQgKTsKKwlzaXplX3QgcyA9IGZyZWFkKCBwQnVmZmVyLCBzaXplb2YoY2hhciksIG5GaWxlU2l6ZSwgcEZpbGUgKTsKKwlpZihzID09IDApCisJeworCQlkZWxldGVbXSBwQnVmZmVyOworCQlyZXR1cm4gRkFMU0U7CisJfQorCisJQ1JZUFRfTUQ1R2VuZXJhdGUocEJ1ZmZlciwgbkZpbGVTaXplLCBidWYpOworCWJ1ZltCVUZTSVpFIC0gMV0gPSAwOworCUNGWF9XaWRlU3RyaW5nIGNzQ2hlY2tTdW0oKEZYX0xQQ1dTVFIpYnVmLCAxNik7CisJZGVsZXRlW10gcEJ1ZmZlcjsKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjptZWRpYShPQkpfUFJPUF9QQVJBTVMpCit7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmNhbGN1bGF0ZU5vdyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCAKKwkJbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0FOTk9UX0ZPUk0pIHx8CisJCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9GSUxMX0ZPUk0pKSkgcmV0dXJuIEZBTFNFOworCisJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKwlwSW50ZXJGb3JtLT5PbkNhbGN1bGF0ZSgpOworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpDb2xsYWIoT0JKX1BST1BfUEFSQU1TKQoreworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpnZXRQYWdlTnRoV29yZChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwkvL2lmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9FWFRSQUNUX0FDQ0VTUykpIHJldHVybiBGQUxTRTsKKworCWludCBuUGFnZU5vID0gcGFyYW1zLkdldFNpemUoKSA+IDAgPyAoaW50KXBhcmFtc1swXSA6IDA7CisJaW50IG5Xb3JkTm8gPSBwYXJhbXMuR2V0U2l6ZSgpID4gMSA/IChpbnQpcGFyYW1zWzFdIDogMDsKKwlib29sIGJTdHJpcCA9IHBhcmFtcy5HZXRTaXplKCkgPiAyID8gKGJvb2wpcGFyYW1zWzJdIDogdHJ1ZTsKKworCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpOworCWlmICghcERvY3VtZW50KSByZXR1cm4gRkFMU0U7CisKKwlpZiAoblBhZ2VObyA8IDAgfHwgblBhZ2VObyA+PSBwRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpKQorCXsKKwkJLy9zRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBEb2N1bWVudC0+R2V0UGFnZShuUGFnZU5vKTsKKwlpZiAoIXBQYWdlRGljdCkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9QYWdlIHBhZ2U7CisJcGFnZS5Mb2FkKHBEb2N1bWVudCwgcFBhZ2VEaWN0KTsKKwlwYWdlLlN0YXJ0UGFyc2UoKTsKKwlwYWdlLlBhcnNlQ29udGVudCgpOworCisJRlhfUE9TSVRJT04gcG9zID0gcGFnZS5HZXRGaXJzdE9iamVjdFBvc2l0aW9uKCk7CisKKwlpbnQgbldvcmRzID0gMDsKKworCUNGWF9XaWRlU3RyaW5nIHN3UmV0OworCisJd2hpbGUgKHBvcykKKwl7CisJCWlmIChDUERGX1BhZ2VPYmplY3QqIHBQYWdlT2JqID0gcGFnZS5HZXROZXh0T2JqZWN0KHBvcykpCisJCXsKKwkJCWlmIChwUGFnZU9iai0+bV9UeXBlID09IFBERlBBR0VfVEVYVCkKKwkJCXsKKwkJCQlpbnQgbk9ialdvcmRzID0gQ291bnRXb3JkcygoQ1BERl9UZXh0T2JqZWN0KilwUGFnZU9iaik7CisKKwkJCQlpZiAobldvcmRzICsgbk9ialdvcmRzID49IG5Xb3JkTm8pCisJCQkJeworCQkJCQlzd1JldCA9IEdldE9ialdvcmRTdHIoKENQREZfVGV4dE9iamVjdCopcFBhZ2VPYmosIG5Xb3JkTm8gLSBuV29yZHMpOworCQkJCQlicmVhazsKKwkJCQl9CisKKwkJCQluV29yZHMgKz0gbk9ialdvcmRzOworCQkJfQorCQl9CisJfQorCisJaWYgKGJTdHJpcCkKKwl7CisJCXN3UmV0LlRyaW1MZWZ0KCk7CisJCXN3UmV0LlRyaW1SaWdodCgpOworCX0KKworCXZSZXQgPSBzd1JldDsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6Z2V0UGFnZU50aFdvcmRRdWFkcyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwkvL2lmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9FWFRSQUNUX0FDQ0VTUykpIHJldHVybiBGQUxTRTsKKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6Z2V0UGFnZU51bVdvcmRzKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0VYVFJBQ1RfQUNDRVNTKSkgcmV0dXJuIEZBTFNFOworCisJaW50IG5QYWdlTm8gPSBwYXJhbXMuR2V0U2l6ZSgpID4gMCA/IChpbnQpcGFyYW1zWzBdIDogMDsKKworCUNQREZfRG9jdW1lbnQqIHBEb2N1bWVudCA9IG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpOworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoblBhZ2VObyA8IDAgfHwgblBhZ2VObyA+PSBwRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpKQorCXsKKwkJLy9zRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlDUERGX0RpY3Rpb25hcnkqIHBQYWdlRGljdCA9IHBEb2N1bWVudC0+R2V0UGFnZShuUGFnZU5vKTsKKwlpZiAoIXBQYWdlRGljdCkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9QYWdlIHBhZ2U7CisJcGFnZS5Mb2FkKHBEb2N1bWVudCwgcFBhZ2VEaWN0KTsKKwlwYWdlLlN0YXJ0UGFyc2UoKTsKKwlwYWdlLlBhcnNlQ29udGVudCgpOworCisJRlhfUE9TSVRJT04gcG9zID0gcGFnZS5HZXRGaXJzdE9iamVjdFBvc2l0aW9uKCk7CisKKwlpbnQgbldvcmRzID0gMDsKKworCXdoaWxlIChwb3MpCisJeworCQlpZiAoQ1BERl9QYWdlT2JqZWN0KiBwUGFnZU9iaiA9IHBhZ2UuR2V0TmV4dE9iamVjdChwb3MpKQorCQl7CisJCQlpZiAocFBhZ2VPYmotPm1fVHlwZSA9PSBQREZQQUdFX1RFWFQpCisJCQl7CisJCQkJQ1BERl9UZXh0T2JqZWN0KiBwVGV4dE9iaiA9IChDUERGX1RleHRPYmplY3QqKXBQYWdlT2JqOworCQkJCW5Xb3JkcyArPSBDb3VudFdvcmRzKHBUZXh0T2JqKTsKKwkJCX0KKwkJfQorCX0KKworCXZSZXQgPSBuV29yZHM7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6Z2V0UHJpbnRQYXJhbXMoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKwlKU0ZYT2JqZWN0IHBSZXRPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBwQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJQcmludFBhcmFtc09iaiIpKTsKKwkvL25vdCBpbXBsZW1lbnRlZCB5ZXQuCisJdlJldCA9IHBSZXRPYmo7CisKKwlyZXR1cm4gVFJVRTsKK30KKworI2RlZmluZSBJU0xBVElOV09SRCh1KQkodSAhPSAweDIwICYmIHUgPD0gMHgyOEZGKQorCitpbnQJRG9jdW1lbnQ6OkNvdW50V29yZHMoQ1BERl9UZXh0T2JqZWN0KiBwVGV4dE9iaikKK3sKKwlpZiAoIXBUZXh0T2JqKSByZXR1cm4gMDsKKworCWludCBuV29yZHMgPSAwOworCisJQ1BERl9Gb250KiBwRm9udCA9IHBUZXh0T2JqLT5HZXRGb250KCk7CisJaWYgKCFwRm9udCkgcmV0dXJuIDA7CisKKwlGWF9CT09MIGJJc0xhdGluID0gRkFMU0U7CisKKwlmb3IgKGludCBpPTAsIHN6PXBUZXh0T2JqLT5Db3VudENoYXJzKCk7IGk8c3o7IGkrKykKKwl7CisJCUZYX0RXT1JEIGNoYXJjb2RlID0gLTE7CisJCUZYX0ZMT0FUIGtlcm5pbmc7CisKKwkJcFRleHRPYmotPkdldENoYXJJbmZvKGksIGNoYXJjb2RlLCBrZXJuaW5nKTsKKwkJQ0ZYX1dpZGVTdHJpbmcgc3dVbmljb2RlID0gcEZvbnQtPlVuaWNvZGVGcm9tQ2hhckNvZGUoY2hhcmNvZGUpOworCisJCUZYX1dPUkQgdW5pY29kZSA9IDA7CisJCWlmIChzd1VuaWNvZGUuR2V0TGVuZ3RoKCkgPiAwKQorCQkJdW5pY29kZSA9IHN3VW5pY29kZVswXTsKKworCQlpZiAoSVNMQVRJTldPUkQodW5pY29kZSkgJiYgYklzTGF0aW4pCisJCQljb250aW51ZTsKKwkJCisJCWJJc0xhdGluID0gSVNMQVRJTldPUkQodW5pY29kZSk7CisJCWlmICh1bmljb2RlICE9IDB4MjApCisJCQluV29yZHMrKzsKKwl9CisKKwlyZXR1cm4gbldvcmRzOworfQorCitDRlhfV2lkZVN0cmluZyBEb2N1bWVudDo6R2V0T2JqV29yZFN0cihDUERGX1RleHRPYmplY3QqIHBUZXh0T2JqLCBpbnQgbldvcmRJbmRleCkKK3sKKwlBU1NFUlQocFRleHRPYmogIT0gTlVMTCk7CisKKwlDRlhfV2lkZVN0cmluZyBzd1JldDsKKworCUNQREZfRm9udCogcEZvbnQgPSBwVGV4dE9iai0+R2V0Rm9udCgpOworCWlmICghcEZvbnQpIHJldHVybiBMIiI7CisKKwlpbnQgbldvcmRzID0gMDsKKwlGWF9CT09MIGJJc0xhdGluID0gRkFMU0U7CisKKwlmb3IgKGludCBpPTAsIHN6PXBUZXh0T2JqLT5Db3VudENoYXJzKCk7IGk8c3o7IGkrKykKKwl7CisJCUZYX0RXT1JEIGNoYXJjb2RlID0gLTE7CisJCUZYX0ZMT0FUIGtlcm5pbmc7CisKKwkJcFRleHRPYmotPkdldENoYXJJbmZvKGksIGNoYXJjb2RlLCBrZXJuaW5nKTsKKwkJQ0ZYX1dpZGVTdHJpbmcgc3dVbmljb2RlID0gcEZvbnQtPlVuaWNvZGVGcm9tQ2hhckNvZGUoY2hhcmNvZGUpOworCisJCUZYX1dPUkQgdW5pY29kZSA9IDA7CisJCWlmIChzd1VuaWNvZGUuR2V0TGVuZ3RoKCkgPiAwKQorCQkJdW5pY29kZSA9IHN3VW5pY29kZVswXTsKKworCQlpZiAoSVNMQVRJTldPUkQodW5pY29kZSkgJiYgYklzTGF0aW4pCisJCXsKKwkJfQorCQllbHNlCisJCXsJCQorCQkJYklzTGF0aW4gPSBJU0xBVElOV09SRCh1bmljb2RlKTsKKwkJCWlmICh1bmljb2RlICE9IDB4MjApCisJCQkJbldvcmRzKys7CQorCQl9CisKKwkJaWYgKG5Xb3Jkcy0xID09IG5Xb3JkSW5kZXgpCisJCQlzd1JldCArPSB1bmljb2RlOworCX0KKworCXJldHVybiBzd1JldDsKK30KKworRlhfQk9PTCBEb2N1bWVudDo6em9vbShPQkpfUFJPUF9QQVJBTVMpCit7CisKKwlyZXR1cm4gVFJVRTsKK30KKworLyoqCisobm9uZSwJTm9WYXJ5KQorKGZpdFAsCUZpdFBhZ2UpCisoZml0VywJRml0V2lkdGgpCisoZml0SCwJRml0SGVpZ2h0KQorKGZpdFYsCUZpdFZpc2libGVXaWR0aCkKKyhwcmVmLAlQcmVmZXJyZWQpCisocmVmVywJUmVmbG93V2lkdGgpCisqLworCitGWF9CT09MIERvY3VtZW50Ojp6b29tVHlwZShPQkpfUFJPUF9QQVJBTVMpCit7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OmRlbGV0ZVBhZ2VzKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCQorCisJCisJCisKKworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7CisvLyAJaWYgKHBFbnYtPkdldEFwcE5hbWUoKS5Db21wYXJlKFBIQU5UT00pICE9IDApCisvLyAJCXJldHVybiBUUlVFOworCisJLy9pZiAoSXNTYWZlTW9kZShjYykpIHJldHVybiBUUlVFOworCisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKCEobV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX01PRElGWSkgfHwgCisJCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BU1NFTUJMRSkpKSByZXR1cm4gRkFMU0U7CisKKwlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOworCQorCWludCBuU3RhcnQgPSAwOworCWludCBuRW5kID0gMDsKKwkKKwlpZiAoaVNpemUgPCAxKQorCXsKKwl9CisJZWxzZSBpZiAoaVNpemUgPT0gMSkKKwl7CisJCWlmIChwYXJhbXNbMF0uR2V0VHlwZSgpID09IFZUX29iamVjdCkKKwkJeworCQkJSlNPYmplY3QgIHBPYmogPSAoSlNPYmplY3QgKXBhcmFtc1swXTsKKwkJCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuU3RhcnQiKTsKKwkJCQluU3RhcnQgPSAoaW50KUNKU19WYWx1ZShtX2lzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOworCisJCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuRW5kIik7CisJCQkJbkVuZCA9IChpbnQpQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7CisJCX0KKwkJZWxzZQorCQl7CisJCQluU3RhcnQgPSAoaW50KXBhcmFtc1swXTsKKwkJfQorCX0KKwllbHNlCisJeworCQluU3RhcnQgPSAoaW50KXBhcmFtc1swXTsKKwkJbkVuZCA9IChpbnQpcGFyYW1zWzFdOworCX0KKworCWludCBuVG90YWwgPSBtX3BEb2N1bWVudC0+R2V0UGFnZUNvdW50KCk7CisKKwlpZiAoblN0YXJ0IDwgMCkJblN0YXJ0ID0gMDsKKwlpZiAoblN0YXJ0ID49IG5Ub3RhbCkgblN0YXJ0ID0gblRvdGFsIC0gMTsKKworCWlmIChuRW5kIDwgMCkgbkVuZCA9IDA7CisJaWYgKG5FbmQgPj0gblRvdGFsKSBuRW5kID0gblRvdGFsIC0gMTsKKworCWlmIChuRW5kIDwgblN0YXJ0KSBuRW5kID0gblN0YXJ0OworCisJCisKKyNpZm5kZWYgRk9YSVRfQ0hST01FX0JVSUxECisJcmV0dXJuIG1fcERvY3VtZW50LT5EZWxldGVQYWdlcyhuU3RhcnQsIG5FbmQgLSBuU3RhcnQgKyAxKTsKKyNlbHNlCisJcmV0dXJuIFRSVUU7CisjZW5kaWYKK30KKworRlhfQk9PTCBEb2N1bWVudDo6ZXh0cmFjdFBhZ2VzKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCQorCisJCisJCisJCisKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOworCisJaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsKKworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICghbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0VYVFJBQ1QpKSByZXR1cm4gRkFMU0U7CisKKwlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOworCQorCWludCBuVG90YWwgPSBtX3BEb2N1bWVudC0+R2V0UGFnZUNvdW50KCk7CisJaW50IG5TdGFydCA9IDA7CisJaW50IG5FbmQgPSBuVG90YWwgLSAxOworCisJQ0ZYX1dpZGVTdHJpbmcgc3dGaWxlUGF0aDsKKwkKKwlpZiAoaVNpemUgPCAxKQorCXsKKwl9CisJZWxzZSBpZiAoaVNpemUgPT0gMSkKKwl7CisJCWlmIChwYXJhbXNbMF0uR2V0VHlwZSgpID09IFZUX29iamVjdCkKKwkJeworCQkJSlNPYmplY3QgIHBPYmogPSAoSlNPYmplY3QgKXBhcmFtc1swXTsKKwkJCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuU3RhcnQiKTsKKwkJCQluU3RhcnQgPSAoaW50KUNKU19WYWx1ZShtX2lzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOworCisJCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuRW5kIik7CisJCQkJbkVuZCA9IChpbnQpQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7CisKKwkJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNQYXRoIik7CisJCQkJc3dGaWxlUGF0aCA9IENKU19WYWx1ZShtX2lzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQluU3RhcnQgPSAoaW50KXBhcmFtc1swXTsKKwkJfQorCX0KKwllbHNlIGlmIChpU2l6ZSA9PSAyKQorCXsKKwkJblN0YXJ0ID0gKGludClwYXJhbXNbMF07CisJCW5FbmQgPSAoaW50KXBhcmFtc1sxXTsKKwl9CisJZWxzZQorCXsKKwkJblN0YXJ0ID0gKGludClwYXJhbXNbMF07CisJCW5FbmQgPSAoaW50KXBhcmFtc1sxXTsKKwkJc3dGaWxlUGF0aCA9IHBhcmFtc1syXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCX0KKworCWlmIChuRW5kIDwgblN0YXJ0KQorCQluRW5kID0gblN0YXJ0OworCisJQ1BERl9Eb2N1bWVudCAqcE5ld0RvYyA9IG5ldyBDUERGX0RvY3VtZW50OworCXBOZXdEb2MtPkNyZWF0ZU5ld0RvYygpOwkKKworCUNGWF9Xb3JkQXJyYXkgYXJyYXk7CisJZm9yIChpbnQgaT1uU3RhcnQ7IGk8PW5FbmQ7IGkrKykKKwkJYXJyYXkuQWRkKGkpOworCisvLwltX3BEb2N1bWVudC0+RXh0cmFjdFBhZ2VzKGFycmF5LCBwTmV3RG9jKTsKKworCWlmIChzd0ZpbGVQYXRoLklzRW1wdHkoKSkKKwl7CisKKwl9CisJZWxzZQorCXsKKwkJc3dGaWxlUGF0aCA9IGFwcDo6UERGUGF0aFRvU3lzUGF0aChzd0ZpbGVQYXRoKTsKKwkJQ1BERl9DcmVhdG9yIFBERkNyZWF0ZXIocE5ld0RvYyk7CisJCVBERkNyZWF0ZXIuQ3JlYXRlKHN3RmlsZVBhdGgpOworCQlkZWxldGUgcE5ld0RvYzsKKy8vCQlwRW52LT5PcGVuRG9jdW1lbnQoc3dGaWxlUGF0aCk7CisJCXZSZXQuU2V0TnVsbCgpOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjppbnNlcnRQYWdlcyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKworCisJCisKKworCisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsKKworCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCAKKwkJbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0FTU0VNQkxFKSkpIHJldHVybiBGQUxTRTsKKworCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7CisJCisJaW50IG5TdGFydCA9IDA7CisJaW50IG5FbmQgPSAwOworCWludCBuUGFnZSA9IDA7CisKKwlDRlhfV2lkZVN0cmluZyBzd0ZpbGVQYXRoOworCQorCWlmIChpU2l6ZSA8IDEpCisJeworCX0KKwllbHNlIGlmIChpU2l6ZSA9PSAxKQorCXsKKwkJaWYgKHBhcmFtc1swXS5HZXRUeXBlKCkgPT0gVlRfb2JqZWN0KQorCQl7CisJCQlKU09iamVjdCAgcE9iaiA9IChKU09iamVjdCApcGFyYW1zWzBdOworCisJCQl2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiblBhZ2UiKTsKKwkJCQluUGFnZSA9IChpbnQpQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7CisKKwkJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNQYXRoIik7CisJCQkJc3dGaWxlUGF0aCA9IENKU19WYWx1ZShtX2lzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisKKwkJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMIm5TdGFydCIpOworCQkJCW5TdGFydCA9IChpbnQpQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7CisKKwkJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMIm5FbmQiKTsKKwkJCQluRW5kID0gKGludClDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCW5QYWdlID0gKGludClwYXJhbXNbMF07CisJCX0KKwl9CisJZWxzZSAKKwl7CisJCW5QYWdlID0gKGludClwYXJhbXNbMF07CisKKwkJaWYgKGlTaXplID49IDIpCisJCQlzd0ZpbGVQYXRoID0gcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisKKwkJaWYgKGlTaXplID49IDMpCisJCQluU3RhcnQgPSAoaW50KXBhcmFtc1syXTsKKworCQlpZiAoaVNpemUgPj0gNCkKKwkJCW5FbmQgPSAoaW50KXBhcmFtc1szXTsKKwl9CisKKwluUGFnZSsrOworCisJaWYgKG5QYWdlIDwgMCkKKwkJblBhZ2UgPSAwOworCisJaWYgKG5QYWdlID4gbV9wRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpKQorCQluUGFnZSA9IG1fcERvY3VtZW50LT5HZXRQYWdlQ291bnQoKTsKKworCWlmIChzd0ZpbGVQYXRoLklzRW1wdHkoKSkgcmV0dXJuIEZBTFNFOworCisJc3dGaWxlUGF0aCA9IGFwcDo6UERGUGF0aFRvU3lzUGF0aChzd0ZpbGVQYXRoKTsKKworCUNQREZfUGFyc2VyIHBkZlBhcnNlcjsKKwlwZGZQYXJzZXIuU3RhcnRQYXJzZShzd0ZpbGVQYXRoLCBGQUxTRSk7CisJQ1BERl9Eb2N1bWVudCogcFNyY0RvYyA9IHBkZlBhcnNlci5HZXREb2N1bWVudCgpOworCisJaWYgKCFwU3JjRG9jKSAKKwl7CisJCXBkZlBhcnNlci5DbG9zZVBhcnNlcigpOworCQlyZXR1cm4gRkFMU0U7CisJfQorCisJaW50IG5Ub3RhbCA9IHBTcmNEb2MtPkdldFBhZ2VDb3VudCgpOworCisJaWYgKG5TdGFydCA8IDApCW5TdGFydCA9IDA7CisJaWYgKG5TdGFydCA+PSBuVG90YWwpIG5TdGFydCA9IG5Ub3RhbCAtIDE7CisKKwlpZiAobkVuZCA8IDApIG5FbmQgPSAwOworCWlmIChuRW5kID49IG5Ub3RhbCkgbkVuZCA9IG5Ub3RhbCAtIDE7CisKKwlpZiAobkVuZCA8IG5TdGFydCkgbkVuZCA9IG5TdGFydDsKKworCUNGWF9Xb3JkQXJyYXkgYXJyYXk7CisJZm9yIChpbnQgaT1uU3RhcnQ7IGk8PW5FbmQ7IGkrKykKKwkJYXJyYXkuQWRkKGkpOworCisvLwltX3BEb2N1bWVudC0+SW5zZXJ0UGFnZXMoblBhZ2UsIHBTcmNEb2MsIGFycmF5KTsKKworCXBkZlBhcnNlci5DbG9zZVBhcnNlcigpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRG9jdW1lbnQ6OnJlcGxhY2VQYWdlcyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKworCisJCisKKworCisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsKKworCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIShtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fTU9ESUZZKSB8fCAKKwkJbV9wRG9jdW1lbnQtPkdldFBlcm1pc3Npb25zKEZQREZQRVJNX0FTU0VNQkxFKSkpIHJldHVybiBGQUxTRTsKKworCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7CisJCisJaW50IG5TdGFydCA9IC0xOworCWludCBuRW5kID0gLTE7CisJaW50IG5QYWdlID0gMDsKKworCUNGWF9XaWRlU3RyaW5nIHN3RmlsZVBhdGg7CisJCisJaWYgKGlTaXplIDwgMSkKKwl7CisJfQorCWVsc2UgaWYgKGlTaXplID09IDEpCisJeworCQlpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9vYmplY3QpCisJCXsKKwkJCUpTT2JqZWN0ICBwT2JqID0gKEpTT2JqZWN0IClwYXJhbXNbMF07CisKKwkJCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJuUGFnZSIpOworCQkJCW5QYWdlID0gKGludClDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsKKworCQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiY1BhdGgiKTsKKwkJCQlzd0ZpbGVQYXRoID0gQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiblN0YXJ0Iik7CisJCQkJblN0YXJ0ID0gKGludClDSlNfVmFsdWUobV9pc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsKKworCQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwibkVuZCIpOworCQkJCW5FbmQgPSAoaW50KUNKU19WYWx1ZShtX2lzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOworCQl9CisJCWVsc2UKKwkJeworCQkJblBhZ2UgPSAoaW50KXBhcmFtc1swXTsKKwkJfQorCX0KKwllbHNlIAorCXsKKwkJblBhZ2UgPSAoaW50KXBhcmFtc1swXTsKKworCQlpZiAoaVNpemUgPj0gMikKKwkJCXN3RmlsZVBhdGggPSBwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQlpZiAoaVNpemUgPj0gMykKKwkJCW5TdGFydCA9IChpbnQpcGFyYW1zWzJdOworCisJCWlmIChpU2l6ZSA+PSA0KQorCQkJbkVuZCA9IChpbnQpcGFyYW1zWzNdOworCX0KKworCWlmIChuUGFnZSA8IDApCisJCW5QYWdlID0gMDsKKworCWlmIChuUGFnZSA+PSBtX3BEb2N1bWVudC0+R2V0UGFnZUNvdW50KCkpCisJCW5QYWdlID0gbV9wRG9jdW1lbnQtPkdldFBhZ2VDb3VudCgpIC0gMTsKKworCWlmIChzd0ZpbGVQYXRoLklzRW1wdHkoKSkgcmV0dXJuIEZBTFNFOworCisJc3dGaWxlUGF0aCA9IGFwcDo6UERGUGF0aFRvU3lzUGF0aChzd0ZpbGVQYXRoKTsKKworCUNQREZfUGFyc2VyIHBkZlBhcnNlcjsKKwlwZGZQYXJzZXIuU3RhcnRQYXJzZShzd0ZpbGVQYXRoLCBGQUxTRSk7CisJQ1BERl9Eb2N1bWVudCogcFNyY0RvYyA9IHBkZlBhcnNlci5HZXREb2N1bWVudCgpOworCisJaWYgKCFwU3JjRG9jKSAKKwl7CisJCXBkZlBhcnNlci5DbG9zZVBhcnNlcigpOworCQlyZXR1cm4gRkFMU0U7CisJfQorCisJaW50IG5Ub3RhbCA9IHBTcmNEb2MtPkdldFBhZ2VDb3VudCgpOworCisJaWYgKG5TdGFydCA8IDApCisJeworCQlpZiAobkVuZCA8IDApCisJCXsKKwkJCW5TdGFydCA9IDA7CisJCQluRW5kID0gblRvdGFsIC0gMTsKKwkJfQorCQllbHNlCisJCXsKKwkJCW5TdGFydCA9IDA7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJaWYgKG5FbmQgPCAwKQorCQl7CisJCQluRW5kID0gblN0YXJ0OworCQl9CisJCWVsc2UKKwkJeworCQkJaWYgKG5TdGFydCA+PSBuVG90YWwpIG5TdGFydCA9IG5Ub3RhbCAtIDE7CisJCQlpZiAobkVuZCA+PSBuVG90YWwpIG5FbmQgPSBuVG90YWwgLSAxOworCisJCQlpZiAobkVuZCA8IG5TdGFydCkgbkVuZCA9IG5TdGFydDsKKwkJfQorCX0KKworCUNGWF9Xb3JkQXJyYXkgYXJyYXk7CisJZm9yIChpbnQgaT1uU3RhcnQ7IGk8PW5FbmQ7IGkrKykKKwkJYXJyYXkuQWRkKGkpOworCisvLwltX3BEb2N1bWVudC0+UmVwbGFjZVBhZ2VzKG5QYWdlLCBwU3JjRG9jLCBhcnJheSk7CisKKwlwZGZQYXJzZXIuQ2xvc2VQYXJzZXIoKTsKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIERvY3VtZW50OjpnZXRVUkwoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsKKworCXJldHVybiBUUlVFOworfQorCit2b2lkIERvY3VtZW50OjpBZGREZWxheURhdGEoQ0pTX0RlbGF5RGF0YSogcERhdGEpCit7CisJbV9EZWxheURhdGEuQWRkKHBEYXRhKTsKK30KKwordm9pZCBEb2N1bWVudDo6RG9GaWVsZERlbGF5KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzRmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCkKK3sKKwlDRlhfRFdvcmRBcnJheSBEZWxBcnJheTsKKworCWZvciAoaW50IGk9MCxzej1tX0RlbGF5RGF0YS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChDSlNfRGVsYXlEYXRhKiBwRGF0YSA9IG1fRGVsYXlEYXRhLkdldEF0KGkpKQorCQl7CisJCQlpZiAocERhdGEtPnNGaWVsZE5hbWUgPT0gc0ZpZWxkTmFtZSAmJiBwRGF0YS0+bkNvbnRyb2xJbmRleCA9PSBuQ29udHJvbEluZGV4KQorCQkJeworCQkJCUZpZWxkOjpEb0RlbGF5KG1fcERvY3VtZW50LCBwRGF0YSk7CisJCQkJZGVsZXRlIHBEYXRhOworCQkJCW1fRGVsYXlEYXRhLlNldEF0KGksIE5VTEwpOworCQkJCURlbEFycmF5LkFkZChpKTsKKwkJCX0KKwkJfQorCX0KKworCWZvciAoaW50IGo9RGVsQXJyYXkuR2V0U2l6ZSgpLTE7IGo+PTA7IGotLSkKKwl7CisJCW1fRGVsYXlEYXRhLlJlbW92ZUF0KERlbEFycmF5W2pdKTsKKwl9Cit9CisKK3ZvaWQgRG9jdW1lbnQ6OkFkZERlbGF5QW5ub3REYXRhKENKU19Bbm5vdE9iaiAqcERhdGEpCit7CisJbV9EZWxheUFubm90RGF0YS5BZGQocERhdGEpOworfQorCit2b2lkIERvY3VtZW50OjpEb0Fubm90RGVsYXkoKQoreworCUNGWF9EV29yZEFycmF5IERlbEFycmF5OworCQorCWZvciAoaW50IGo9RGVsQXJyYXkuR2V0U2l6ZSgpLTE7IGo+PTA7IGotLSkKKwl7CisJCW1fRGVsYXlEYXRhLlJlbW92ZUF0KERlbEFycmF5W2pdKTsKKwl9Cit9CmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0ZpZWxkLmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvRmllbGQuY3BwCmluZGV4IDQ0YTc0NGYuLmY1ZjliZjAgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvRmllbGQuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvRmllbGQuY3BwCkBAIC0xLDQxMjggKzEsNDEyOCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRXZlbnRIYW5kbGVyLmgiDQotLy8jaW5jbHVkZSAiLi4vaW5jbHVkZS9KU19SZXNNZ3IuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9jb2xvci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvUHVibGljTWV0aG9kcy5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSWNvbi5oIg0KLQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmllbGQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19DT05TVChDSlNfRmllbGQpDQotRU5EX0pTX1NUQVRJQ19DT05TVCgpDQotDQotQkVHSU5fSlNfU1RBVElDX1BST1AoQ0pTX0ZpZWxkKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShhbGlnbm1lbnQpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGJvcmRlclN0eWxlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShidXR0b25BbGlnblgpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGJ1dHRvbkFsaWduWSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoYnV0dG9uRml0Qm91bmRzKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShidXR0b25Qb3NpdGlvbikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoYnV0dG9uU2NhbGVIb3cpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGJ1dHRvblNjYWxlV2hlbikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoY2FsY09yZGVySW5kZXgpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGNoYXJMaW1pdCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoY29tYikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoY29tbWl0T25TZWxDaGFuZ2UpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGN1cnJlbnRWYWx1ZUluZGljZXMpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGRlZmF1bHRTdHlsZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoZGVmYXVsdFZhbHVlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShkb05vdFNjcm9sbCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoZG9Ob3RTcGVsbENoZWNrKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShkZWxheSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoZGlzcGxheSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoZG9jKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShlZGl0YWJsZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoZXhwb3J0VmFsdWVzKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShoaWRkZW4pDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGZpbGVTZWxlY3QpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGZpbGxDb2xvcikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkobGluZVdpZHRoKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShoaWdobGlnaHQpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG11bHRpbGluZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkobXVsdGlwbGVTZWxlY3Rpb24pDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG5hbWUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG51bUl0ZW1zKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShwYWdlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShwYXNzd29yZCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkocHJpbnQpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHJhZGlvc0luVW5pc29uKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShyZWFkb25seSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkocmVjdCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkocmVxdWlyZWQpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHJpY2hUZXh0KQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShyaWNoVmFsdWUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHJvdGF0aW9uKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShzdHJva2VDb2xvcikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoc3R5bGUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHN1Ym1pdE5hbWUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHRleHRDb2xvcikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkodGV4dEZvbnQpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHRleHRTaXplKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWSh0eXBlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWSh1c2VyTmFtZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkodmFsdWUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHZhbHVlQXNTdHJpbmcpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHNvdXJjZSkNCi1FTkRfSlNfU1RBVElDX1BST1AoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19NRVRIT0QoQ0pTX0ZpZWxkKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJyb3dzZUZvckZpbGVUb1N1Ym1pdCwgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJ1dHRvbkdldENhcHRpb24sICAgICAgICAgICAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJ1dHRvbkdldEljb24sICAgICAgICAgICAgICAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJ1dHRvbkltcG9ydEljb24sICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJ1dHRvblNldENhcHRpb24sICAgICAgICAgICAyKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJ1dHRvblNldEljb24sICAgICAgICAgICAgICAyKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGNoZWNrVGhpc0JveCwgICAgICAgICAgICAgICAyKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGNsZWFySXRlbXMsICAgICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGRlZmF1bHRJc0NoZWNrZWQsICAgICAgICAgICAyKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGRlbGV0ZUl0ZW1BdCwgICAgICAgICAgICAgICAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldEFycmF5ICwgICAgICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldEl0ZW1BdCwgICAgICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldExvY2ssICAgICAgICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGluc2VydEl0ZW1BdCwgICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGlzQm94Q2hlY2tlZCwgICAgICAgICAgICAgICAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGlzRGVmYXVsdENoZWNrZWQsICAgICAgICAgICAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNldEFjdGlvbiwgICAgICAgICAgICAgICAgICAyKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNldEZvY3VzLCAgICAgICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNldEl0ZW1zLCAgICAgICAgICAgICAgICAgICAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNldExvY2ssICAgICAgICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNpZ25hdHVyZUdldE1vZGlmaWNhdGlvbnMsICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNpZ25hdHVyZUdldFNlZWRWYWx1ZSwgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNpZ25hdHVyZUluZm8sICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNpZ25hdHVyZVNldFNlZWRWYWx1ZSwgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNpZ25hdHVyZVNpZ24sICAgICAgICAgICAgICAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNpZ25hdHVyZVZhbGlkYXRlLCAgICAgICAgICAwKQ0KLUVORF9KU19TVEFUSUNfTUVUSE9EKCkNCi0NCi1JTVBMRU1FTlRfSlNfQ0xBU1MoQ0pTX0ZpZWxkLCBGaWVsZCkNCi0NCi1GWF9CT09MCUNKU19GaWVsZDo6SW5pdEluc3RhbmNlKElGWEpTX0NvbnRleHQqIGNjKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQlGaWVsZCogcEZpZWxkID0gKEZpZWxkKilHZXRFbWJlZE9iamVjdCgpOw0KLQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQlwRmllbGQtPlNldElzb2xhdGUocENvbnRleHQtPkdldEpTUnVudGltZSgpLT5HZXRJc29sYXRlKCkpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19Ow0KLQ0KLUZpZWxkOjpGaWVsZChDSlNfT2JqZWN0KiBwSlNPYmplY3QpOiBDSlNfRW1iZWRPYmoocEpTT2JqZWN0KSwNCi0JbV9wSlNEb2MoTlVMTCksDQotCW1fcERvY3VtZW50KE5VTEwpLA0KLQltX25Gb3JtQ29udHJvbEluZGV4KC0xKSwNCi0JbV9iQ2FuU2V0KEZBTFNFKSwNCi0JbV9iRGVsYXkoRkFMU0UpLA0KLQltX2lzb2xhdGUoTlVMTCkNCi17DQotfQ0KLQ0KLUZpZWxkOjp+RmllbGQoKQ0KLXsNCi19DQotDQotLy9ub3RlOiBpQ29udHJvbE5vID0gLTEsIG1lYW5zIG5vdCBhIHdpZGdldC4NCi12b2lkIEZpZWxkOjpQYXJzZUZpZWxkTmFtZShjb25zdCBzdGQ6OndzdHJpbmcgJnN0ckZpZWxkTmFtZVBhcnNlZCxzdGQ6OndzdHJpbmcgJnN0ckZpZWxkTmFtZSxpbnQgJiBpQ29udHJvbE5vKQ0KLXsNCi0JaW50IGlTdGFydCA9IHN0ckZpZWxkTmFtZVBhcnNlZC5maW5kX2xhc3Rfb2YoTCcuJyk7DQotCWlmIChpU3RhcnQgPT0gLTEpDQotCXsNCi0JCXN0ckZpZWxkTmFtZSA9IHN0ckZpZWxkTmFtZVBhcnNlZDsNCi0JCWlDb250cm9sTm8gPSAtMTsNCi0JCXJldHVybjsNCi0JfQ0KLQlzdGQ6OndzdHJpbmcgc3VmZml4YWwgPSBzdHJGaWVsZE5hbWVQYXJzZWQuc3Vic3RyKGlTdGFydCsxKTsNCi0JaUNvbnRyb2xObyA9IEZYU1lTX3d0b2koKEZYX0xQQ1dTVFIpc3VmZml4YWwuY19zdHIoKSk7DQotCWlmIChpQ29udHJvbE5vID09IDApDQotCXsNCi0JCWludCBpU3RhcnQ7DQotCQl3aGlsZSgoaVN0YXJ0ID0gc3VmZml4YWwuZmluZF9sYXN0X29mKEwiICIpKSAhPSAtMSkNCi0JCXsNCi0JCQlzdWZmaXhhbC5lcmFzZShpU3RhcnQsMSk7DQotCQl9DQotDQotCQlpZiAoc3VmZml4YWwuY29tcGFyZShMIjAiKSAhPSAwKQ0KLQkJew0KLQkJCXN0ckZpZWxkTmFtZSA9IHN0ckZpZWxkTmFtZVBhcnNlZDsNCi0JCQlpQ29udHJvbE5vID0gLTE7DQotCQkJcmV0dXJuOw0KLQkJfQ0KLQ0KLQl9DQotCXN0ckZpZWxkTmFtZSA9IHN0ckZpZWxkTmFtZVBhcnNlZC5zdWJzdHIoMCxpU3RhcnQpOyAgICANCi19DQotDQotRlhfQk9PTCBGaWVsZDo6QXR0YWNoRmllbGQoRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIGNzRmllbGROYW1lKQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0JbV9wSlNEb2MgPSBwRG9jdW1lbnQ7DQotDQotCW1fcERvY3VtZW50ID0gcERvY3VtZW50LT5HZXRSZWFkZXJEb2MoKTsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQltX2JDYW5TZXQgPSBtX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fRklMTF9GT1JNKSB8fCANCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9BTk5PVF9GT1JNKSB8fCANCi0JCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9NT0RJRlkpOw0KLQ0KLQlDUERGU0RLX0ludGVyRm9ybSogcFJESW50ZXJGb3JtID0gbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocFJESW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDUERGX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBSREludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzd0ZpZWxkTmFtZVRlbXAgPSBjc0ZpZWxkTmFtZTsNCi0Jc3dGaWVsZE5hbWVUZW1wLlJlcGxhY2UoKEZYX0xQQ1dTVFIpTCIuLiIsIChGWF9MUENXU1RSKUwiLiIpOw0KLQ0KLQlpZiAocEludGVyRm9ybS0+Q291bnRGaWVsZHMoc3dGaWVsZE5hbWVUZW1wKSA8PSAwKQ0KLQl7DQotCQlzdGQ6OndzdHJpbmcgc3RyRmllbGROYW1lOw0KLQkJaW50IGlDb250cm9sTm8gPSAtMTsNCi0JCVBhcnNlRmllbGROYW1lKCh3Y2hhcl90KikoRlhfTFBDV1NUUilzd0ZpZWxkTmFtZVRlbXAsIHN0ckZpZWxkTmFtZSwgaUNvbnRyb2xObyk7DQotCQlpZiAoaUNvbnRyb2xObyA9PSAtMSkgcmV0dXJuIEZBTFNFOw0KLQkJDQotCQltX0ZpZWxkTmFtZSA9IHN0ckZpZWxkTmFtZS5jX3N0cigpOw0KLQkJbV9uRm9ybUNvbnRyb2xJbmRleCA9IGlDb250cm9sTm87DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQltX0ZpZWxkTmFtZSA9IHN3RmllbGROYW1lVGVtcDsNCi0JbV9uRm9ybUNvbnRyb2xJbmRleCA9IC0xOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6R2V0Rm9ybUZpZWxkcyhDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBjc0ZpZWxkTmFtZSwgQ0ZYX1B0ckFycmF5JiBGaWVsZEFycmF5KQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBSZWFkZXJJbnRlckZvcm0gPSBwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocFJlYWRlckludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JQ1BERl9JbnRlckZvcm0qIHBJbnRlckZvcm0gPSBwUmVhZGVySW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUFTU0VSVChGaWVsZEFycmF5LkdldFNpemUoKSA9PSAwKTsNCi0NCi0JZm9yIChpbnQgaT0wLHN6PXBJbnRlckZvcm0tPkNvdW50RmllbGRzKGNzRmllbGROYW1lKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBwSW50ZXJGb3JtLT5HZXRGaWVsZChpLCBjc0ZpZWxkTmFtZSkpDQotCQkJRmllbGRBcnJheS5BZGQoKHZvaWQqKXBGb3JtRmllbGQpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OkdldEZvcm1GaWVsZHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIGNzRmllbGROYW1lLCBDRlhfUHRyQXJyYXkmIEZpZWxkQXJyYXkpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUZpZWxkOjpHZXRGb3JtRmllbGRzKG1fcERvY3VtZW50LCBjc0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlVwZGF0ZUZvcm1GaWVsZChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCANCi0JCQkJCQkJRlhfQk9PTCBiQ2hhbmdlTWFyaywgRlhfQk9PTCBiUmVzZXRBUCwgRlhfQk9PTCBiUmVmcmVzaCkNCi17DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNGWF9QdHJBcnJheSB3aWRnZXRzOw0KLQlwSW50ZXJGb3JtLT5HZXRXaWRnZXRzKHBGb3JtRmllbGQsIHdpZGdldHMpOw0KLQ0KLQlpZiAoYlJlc2V0QVApDQotCXsNCi0JCWludCBuRmllbGRUeXBlID0gcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCk7DQotCQlpZiAobkZpZWxkVHlwZSA9PSBGSUVMRFRZUEVfQ09NQk9CT1ggfHwgbkZpZWxkVHlwZSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEKQ0KLQkJew0KLQkJCWZvciAoaW50IGk9MCxzej13aWRnZXRzLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJCXsNCi0JCQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXdpZGdldHMuR2V0QXQoaSk7DQotCQkJCUFTU0VSVChwV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQkJCQlGWF9CT09MIGJGb3JtYXRlZCA9IEZBTFNFOw0KLQkJCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwV2lkZ2V0LT5PbkZvcm1hdCgwLCBiRm9ybWF0ZWQpOw0KLQkJCQlpZiAoYkZvcm1hdGVkKQ0KLQkJCQkJcFdpZGdldC0+UmVzZXRBcHBlYXJhbmNlKHNWYWx1ZSwgRkFMU0UpOw0KLQkJCQllbHNlDQotCQkJCQlwV2lkZ2V0LT5SZXNldEFwcGVhcmFuY2UoTlVMTCwgRkFMU0UpOw0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlmb3IgKGludCBpPTAsc3o9d2lkZ2V0cy5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQl7DQotCQkJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0Kil3aWRnZXRzLkdldEF0KGkpOw0KLQkJCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsNCi0NCi0JCQkJcFdpZGdldC0+UmVzZXRBcHBlYXJhbmNlKE5VTEwsIEZBTFNFKTsNCi0JCQl9DQotCQl9DQotCX0NCi0NCi0JaWYgKGJSZWZyZXNoKQ0KLQl7DQotCQlmb3IgKGludCBpPTAsc3o9d2lkZ2V0cy5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCXsNCi0JCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopd2lkZ2V0cy5HZXRBdChpKTsNCi0JCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsNCi0JCQkNCi0JCQlDUERGU0RLX0ludGVyRm9ybSAqIHBJbnRlckZvcm0gPSBwV2lkZ2V0LT5HZXRJbnRlckZvcm0oKTsNCi0JCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jID0gcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKTsNCi0vLyAJCQlDUmVhZGVyX1BhZ2UqIHBQYWdlID0gcFdpZGdldC0+R2V0UGFnZSgpOw0KLSAJCQlBU1NFUlQocERvYyAhPSBOVUxMKTsNCi0JCQlwRG9jLT5VcGRhdGVBbGxWaWV3cyhOVUxMLCBwV2lkZ2V0KTsNCi0JCX0NCi0JfQkJDQotCQ0KLQlpZiAoYkNoYW5nZU1hcmspDQotCQlwRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi19DQotDQotdm9pZCBGaWVsZDo6VXBkYXRlRm9ybUNvbnRyb2woQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wsIA0KLQkJCQkJCQlGWF9CT09MIGJDaGFuZ2VNYXJrLCBGWF9CT09MIGJSZXNldEFQLCBGWF9CT09MIGJSZWZyZXNoKQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBGb3JtQ29udHJvbCAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKXBEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpOw0KLQkNCi0JaWYgKHBXaWRnZXQpDQotCXsNCi0JCWlmIChiUmVzZXRBUCkNCi0JCXsNCi0JCQlpbnQgbkZpZWxkVHlwZSA9IHBXaWRnZXQtPkdldEZpZWxkVHlwZSgpOw0KLQkJCWlmIChuRmllbGRUeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCB8fCBuRmllbGRUeXBlID09IEZJRUxEVFlQRV9URVhURklFTEQpDQotCQkJew0KLQkJCQlGWF9CT09MIGJGb3JtYXRlZCA9IEZBTFNFOw0KLQkJCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwV2lkZ2V0LT5PbkZvcm1hdCgwLCBiRm9ybWF0ZWQpOw0KLQkJCQlpZiAoYkZvcm1hdGVkKQ0KLQkJCQkJcFdpZGdldC0+UmVzZXRBcHBlYXJhbmNlKHNWYWx1ZSwgRkFMU0UpOw0KLQkJCQllbHNlDQotCQkJCQlwV2lkZ2V0LT5SZXNldEFwcGVhcmFuY2UoTlVMTCwgRkFMU0UpOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlwV2lkZ2V0LT5SZXNldEFwcGVhcmFuY2UoTlVMTCwgRkFMU0UpOw0KLQkJCX0NCi0JCX0NCi0NCi0JCWlmIChiUmVmcmVzaCkNCi0JCXsNCi0JCQlDUERGU0RLX0ludGVyRm9ybSAqIHBJbnRlckZvcm0gPSBwV2lkZ2V0LT5HZXRJbnRlckZvcm0oKTsNCi0JCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jID0gcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKTsNCi0JCQlBU1NFUlQocERvYyAhPSBOVUxMKTsNCi0JCQlwRG9jLT5VcGRhdGVBbGxWaWV3cyhOVUxMLCBwV2lkZ2V0KTsNCi0JCX0NCi0NCi0JfQ0KLQ0KLQlpZiAoYkNoYW5nZU1hcmspDQotCQlwRG9jdW1lbnQtPlNldENoYW5nZU1hcmsoKTsNCi19DQotDQotQ1BERlNES19XaWRnZXQqIEZpZWxkOjpHZXRXaWRnZXQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQlBU1NFUlQocEZvcm1Db250cm9sICE9IE5VTEwpOw0KLQ0KLQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCXJldHVybiBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1Db250cm9sKTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6VmFsdWVJc09jY3VyKENQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkLCBDRlhfV2lkZVN0cmluZyBjc09wdExhYmVsKQ0KLXsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCWZvciAoaW50IGk9MCxzeiA9IHBGb3JtRmllbGQtPkNvdW50T3B0aW9ucygpOyBpIDwgc3o7IGkrKykNCi0Jew0KLQkJaWYgKGNzT3B0TGFiZWwuQ29tcGFyZShwRm9ybUZpZWxkLT5HZXRPcHRpb25MYWJlbChpKSkgPT0gMCkNCi0JCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUNQREZfRm9ybUNvbnRyb2wqIEZpZWxkOjpHZXRTbWFydEZpZWxkQ29udHJvbChDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCkNCi17DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQlpZighcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpIHx8IG1fbkZvcm1Db250cm9sSW5kZXg+PXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuIE5VTEw7DQotDQotCWlmIChtX25Gb3JtQ29udHJvbEluZGV4PDApDQotCQlyZXR1cm4gcEZvcm1GaWVsZC0+R2V0Q29udHJvbCgwKTsNCi0JZWxzZQ0KLQkJcmV0dXJuIHBGb3JtRmllbGQtPkdldENvbnRyb2wobV9uRm9ybUNvbnRyb2xJbmRleCk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcHJvcGVydHkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUZYX0JPT0wgRmllbGQ6OmFsaWdubWVudChPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNGWF9CeXRlU3RyaW5nIGFsaWduU3RyOw0KLQkJdnAgPj4gYWxpZ25TdHI7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfU3RyaW5nKEZQX0FMSUdOTUVOVCwgYWxpZ25TdHIpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXRBbGlnbm1lbnQobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBhbGlnblN0cik7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7DQotCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7DQotDQotCQlzd2l0Y2ggKHBGb3JtQ29udHJvbC0+R2V0Q29udHJvbEFsaWdubWVudCgpKQ0KLQkJew0KLQkJCWNhc2UgMToNCi0JCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJjZW50ZXIiOw0KLQkJCQlicmVhazsNCi0JCQljYXNlIDA6DQotCQkJCXZwIDw8IChGWF9MUENXU1RSKUwibGVmdCI7DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgMjoNCi0JCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJyaWdodCI7DQotCQkJCWJyZWFrOw0KLQkJCWRlZmF1bHQ6DQotCQkJCXZwIDw8IChGWF9MUENXU1RSKUwiIjsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0QWxpZ25tZW50KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgDQotCQkJCQkJIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmJvcmRlclN0eWxlKE9CSl9QUk9QX1BBUkFNUykNCi17CQ0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNGWF9CeXRlU3RyaW5nIHN0clR5cGUgPSAiIjsNCi0JCXZwID4+IHN0clR5cGU7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfU3RyaW5nKEZQX0JPUkRFUlNUWUxFLCBzdHJUeXBlKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0Qm9yZGVyU3R5bGUobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBzdHJUeXBlKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJaWYgKCFwRm9ybUZpZWxkKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IEdldFdpZGdldChtX3BEb2N1bWVudCwgR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCkpOw0KLQkJaWYgKCFwV2lkZ2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlpbnQgbkJvcmRlcnN0eWxlID0gcFdpZGdldC0+R2V0Qm9yZGVyU3R5bGUoKTsNCi0NCi0JCXN3aXRjaCAobkJvcmRlcnN0eWxlKQ0KLQkJew0KLQkJCWNhc2UgQkJTX1NPTElEOg0KLQkJCQl2cCA8PCAoRlhfTFBDV1NUUilMInNvbGlkIjsNCi0JCQkJYnJlYWs7DQotCQkJY2FzZSBCQlNfREFTSDoNCi0JCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJkYXNoZWQiOw0KLQkJCQlicmVhazsNCi0JCQljYXNlIEJCU19CRVZFTEVEOg0KLQkJCQl2cCA8PCAoRlhfTFBDV1NUUilMImJldmVsZWQiOw0KLQkJCQlicmVhazsNCi0JCQljYXNlIEJCU19JTlNFVDoNCi0JCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJpbnNldCI7DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgQkJTX1VOREVSTElORToNCi0JCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJ1bmRlcmxpbmUiOw0KLQkJCQlicmVhazsNCi0JCQlkZWZhdWx0Og0KLQkJCQl2cCA8PCAoRlhfTFBDV1NUUilMIiI7DQotCQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpTZXRCb3JkZXJTdHlsZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIA0KLQkJCQkJCSAgIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpbnQgbkJvcmRlclN0eWxlID0gMDsNCi0NCi0JaWYgKHN0cmluZyA9PSAic29saWQiKQ0KLQkJbkJvcmRlclN0eWxlID0gQkJTX1NPTElEOw0KLQllbHNlIGlmIChzdHJpbmcgPT0gImJldmVsZWQiKQ0KLQkJbkJvcmRlclN0eWxlID0gQkJTX0JFVkVMRUQ7DQotCWVsc2UgaWYgKHN0cmluZyA9PSAiZGFzaGVkIikNCi0JCW5Cb3JkZXJTdHlsZSA9IEJCU19EQVNIOw0KLQllbHNlIGlmIChzdHJpbmcgPT0gImluc2V0IikNCi0JCW5Cb3JkZXJTdHlsZSA9IEJCU19JTlNFVDsNCi0JZWxzZSBpZiAoc3RyaW5nID09ICJ1bmRlcmxpbmUiKQ0KLQkJbkJvcmRlclN0eWxlID0gQkJTX1VOREVSTElORTsNCi0JZWxzZSByZXR1cm47DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKHBEb2N1bWVudCwgc3dGaWVsZE5hbWUsIEZpZWxkQXJyYXkpOw0KLQ0KLQlmb3IgKGludCBpPTAsaXN6PUZpZWxkQXJyYXkuR2V0U2l6ZSgpOyBpPGlzejsgaSsrKQ0KLQl7DQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoaSk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChuQ29udHJvbEluZGV4IDwgMCkNCi0JCXsNCi0JCQlGWF9CT09MIGJTZXQgPSBGQUxTRTsNCi0JCQlmb3IgKGludCBqPTAsanN6ID0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBqPGpzejsgaisrKQ0KLQkJCXsNCi0JCQkJaWYgKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gR2V0V2lkZ2V0KHBEb2N1bWVudCwgcEZvcm1GaWVsZC0+R2V0Q29udHJvbChqKSkpDQotCQkJCXsNCi0JCQkJCWlmIChwV2lkZ2V0LT5HZXRCb3JkZXJTdHlsZSgpICE9IG5Cb3JkZXJTdHlsZSkNCi0JCQkJCXsNCi0JCQkJCQlwV2lkZ2V0LT5TZXRCb3JkZXJTdHlsZShuQm9yZGVyU3R5bGUpOw0KLQkJCQkJCWJTZXQgPSBUUlVFOw0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJCWlmIChiU2V0KSBVcGRhdGVGb3JtRmllbGQocERvY3VtZW50LCBwRm9ybUZpZWxkLCBUUlVFLCBUUlVFLCBUUlVFKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlpZihuQ29udHJvbEluZGV4ID49IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuOw0KLQkJCWlmIChDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKG5Db250cm9sSW5kZXgpKQ0KLQkJCXsNCi0JCQkJaWYgKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gR2V0V2lkZ2V0KHBEb2N1bWVudCwgcEZvcm1Db250cm9sKSkNCi0JCQkJew0KLQkJCQkJaWYgKHBXaWRnZXQtPkdldEJvcmRlclN0eWxlKCkgIT0gbkJvcmRlclN0eWxlKQ0KLQkJCQkJew0KLQkJCQkJCXBXaWRnZXQtPlNldEJvcmRlclN0eWxlKG5Cb3JkZXJTdHlsZSk7DQotCQkJCQkJVXBkYXRlRm9ybUNvbnRyb2wocERvY3VtZW50LCBwRm9ybUNvbnRyb2wsIFRSVUUsIFRSVUUsIFRSVUUpOw0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmJ1dHRvbkFsaWduWChPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWludCBuVlA7DQotCQl2cCA+PiBuVlA7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfSW50KEZQX0JVVFRPTkFMSUdOWCwgblZQKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0QnV0dG9uQWxpZ25YKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgblZQKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsJCQ0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOw0KLQkJaWYgKCFwRm9ybUNvbnRyb2wpcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9JY29uRml0IEljb25GaXQgPSBwRm9ybUNvbnRyb2wtPkdldEljb25GaXQoKTsNCi0NCi0JCUZYX0ZMT0FUIGZMZWZ0LGZCb3R0b207DQotCQlJY29uRml0LkdldEljb25Qb3NpdGlvbihmTGVmdCxmQm90dG9tKTsNCi0NCi0JCXZwIDw8IChGWF9JTlQzMilmTGVmdDsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0QnV0dG9uQWxpZ25YKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikNCi17DQotCS8vTm90IHN1cHBvcnRlZC4NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6YnV0dG9uQWxpZ25ZKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaW50IG5WUDsNCi0JCXZwID4+IG5WUDsNCi0NCi0JCWlmIChtX2JEZWxheSkNCi0JCXsNCi0JCQlBZGREZWxheV9JbnQoRlBfQlVUVE9OQUxJR05ZLCBuVlApOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXRCdXR0b25BbGlnblkobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOw0KLQkJaWYgKCFwRm9ybUNvbnRyb2wpcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9JY29uRml0IEljb25GaXQgPSBwRm9ybUNvbnRyb2wtPkdldEljb25GaXQoKTsNCi0NCi0JCUZYX0ZMT0FUIGZMZWZ0LGZCb3R0b207DQotCQlJY29uRml0LkdldEljb25Qb3NpdGlvbihmTGVmdCxmQm90dG9tKTsNCi0NCi0JCXZwIDw8ICAoRlhfSU5UMzIpZkJvdHRvbTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0QnV0dG9uQWxpZ25ZKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikNCi17DQotCS8vTm90IHN1cHBvcnRlZC4NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6YnV0dG9uRml0Qm91bmRzKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJYm9vbCBiVlA7DQotCQl2cCA+PiBiVlA7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfQm9vbChGUF9CVVRUT05GSVRCT1VORFMsIGJWUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldEJ1dHRvbkZpdEJvdW5kcyhtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGJWUCk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1BVU0hCVVRUT04pDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7DQotCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0ljb25GaXQgSWNvbkZpdCA9IHBGb3JtQ29udHJvbC0+R2V0SWNvbkZpdCgpOw0KLQkJdnAgPDwgSWNvbkZpdC5HZXRGaXR0aW5nQm91bmRzKCk7CQkNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0QnV0dG9uRml0Qm91bmRzKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpidXR0b25Qb3NpdGlvbihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWludCBuVlA7DQotCQl2cCA+PiBuVlA7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfSW50KEZQX0JVVFRPTlBPU0lUSU9OLCBuVlApOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXRCdXR0b25Qb3NpdGlvbihtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIG5WUCk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1BVU0hCVVRUT04pDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7DQotCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7DQotDQotCQl2cCA8PCAgcEZvcm1Db250cm9sLT5HZXRUZXh0UG9zaXRpb24oKTsNCi0JfQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0QnV0dG9uUG9zaXRpb24oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpidXR0b25TY2FsZUhvdyhPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWludCBuVlA7DQotCQl2cCA+PiBuVlA7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfSW50KEZQX0JVVFRPTlNDQUxFSE9XLCBuVlApOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXRCdXR0b25TY2FsZUhvdyhtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIG5WUCk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOw0KLQkJaWYgKCFwRm9ybUNvbnRyb2wpcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9JY29uRml0IEljb25GaXQgPSBwRm9ybUNvbnRyb2wtPkdldEljb25GaXQoKTsNCi0JCWlmIChJY29uRml0LklzUHJvcG9ydGlvbmFsU2NhbGUoKSkNCi0JCQl2cCA8PCAoRlhfSU5UMzIpMDsNCi0JCWVsc2UNCi0JCQl2cCA8PCAoRlhfSU5UMzIpMTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0QnV0dG9uU2NhbGVIb3coQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpidXR0b25TY2FsZVdoZW4oT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlpbnQgblZQOw0KLQkJdnAgPj4gblZQOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X0ludChGUF9CVVRUT05TQ0FMRVdIRU4sIG5WUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldEJ1dHRvblNjYWxlV2hlbihtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIG5WUCk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKSBGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOw0KLQkJaWYgKCFwRm9ybUNvbnRyb2wpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfSWNvbkZpdCBJY29uRml0ID0gcEZvcm1Db250cm9sLT5HZXRJY29uRml0KCk7DQotCQlpbnQgU2NhbGVNID0gSWNvbkZpdC5HZXRTY2FsZU1ldGhvZCgpOw0KLQkJc3dpdGNoIChTY2FsZU0pDQotCQl7DQotCQkJY2FzZSBDUERGX0ljb25GaXQ6OkFsd2F5cyA6DQotCQkJCXZwIDw8ICAoRlhfSU5UMzIpIENQREZfSWNvbkZpdDo6QWx3YXlzOw0KLQkJCQlicmVhazsNCi0JCQljYXNlIENQREZfSWNvbkZpdDo6QmlnZ2VyIDoNCi0JCQkJdnAgPDwgIChGWF9JTlQzMikgQ1BERl9JY29uRml0OjpCaWdnZXI7DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgQ1BERl9JY29uRml0OjpOZXZlciA6DQotCQkJCXZwIDw8ICAoRlhfSU5UMzIpIENQREZfSWNvbkZpdDo6TmV2ZXI7DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgQ1BERl9JY29uRml0OjpTbWFsbGVyIDoNCi0JCQkJdnAgPDwgIChGWF9JTlQzMikgQ1BERl9JY29uRml0OjpTbWFsbGVyOw0KLQkJCQlicmVhazsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0QnV0dG9uU2NhbGVXaGVuKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikNCi17DQotCS8vTm90IHN1cHBvcnRlZC4NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6Y2FsY09yZGVySW5kZXgoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsJDQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaW50IG5WUDsNCi0JCXZwID4+IG5WUDsNCi0NCi0JCWlmIChtX2JEZWxheSkNCi0JCXsNCi0JCQlBZGREZWxheV9JbnQoRlBfQ0FMQ09SREVSSU5ERVgsIG5WUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldENhbGNPcmRlckluZGV4KG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgblZQKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX0NPTUJPQk9YICYmIHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERlNES19JbnRlckZvcm0qIHBSREludGVyRm9ybSA9IG1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JCUFTU0VSVChwUkRJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCQlDUERGX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBSREludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JCXZwIDw8IChGWF9JTlQzMilwSW50ZXJGb3JtLT5GaW5kRmllbGRJbkNhbGN1bGF0aW9uT3JkZXIocEZvcm1GaWVsZCk7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldENhbGNPcmRlckluZGV4KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikNCi17DQotCS8vTm90IHN1cHBvcnRlZC4NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6Y2hhckxpbWl0KE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaW50IG5WUDsNCi0JCXZwID4+IG5WUDsNCi0NCi0JCWlmIChtX2JEZWxheSkNCi0JCXsNCi0JCQlBZGREZWxheV9JbnQoRlBfQ0hBUkxJTUlULCBuVlApOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXRDaGFyTGltaXQobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsNCi0JCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfVEVYVEZJRUxEKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCXZwIDw8IChGWF9JTlQzMilwRm9ybUZpZWxkLT5HZXRNYXhMZW4oKTsNCi0JfQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0Q2hhckxpbWl0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikNCi17DQotCS8vTm90IHN1cHBvcnRlZC4NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6Y29tYihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X0Jvb2woRlBfQ09NQiwgYlZQKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0Q29tYihtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGJWUCk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7CQ0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19DT01CKQ0KLQkJCXZwIDw8IHRydWU7DQotCQllbHNlDQotCQkJdnAgPDwgZmFsc2U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldENvbWIoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmNvbW1pdE9uU2VsQ2hhbmdlKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJYm9vbCBiVlA7DQotCQl2cCA+PiBiVlA7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfQm9vbChGUF9DT01NSVRPTlNFTENIQU5HRSwgYlZQKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0Q29tbWl0T25TZWxDaGFuZ2UobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBiVlApOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9DT01CT0JPWCAmJiBwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfTElTVEJPWCkNCi0JCQlyZXR1cm4gRkFMU0U7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX0NPTU1JVE9OU0VMQ0hBTkdFKQ0KLQkJCXZwIDw8IHRydWU7DQotCQllbHNlDQotCQkJdnAgPDwgZmFsc2U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldENvbW1pdE9uU2VsQ2hhbmdlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpjdXJyZW50VmFsdWVJbmRpY2VzKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0ZYX0RXb3JkQXJyYXkgYXJyYXk7DQotDQotCQlpZiAodnAuR2V0VHlwZSgpID09IFZUX251bWJlcikNCi0JCXsNCi0JCQlpbnQgaVNlbGVjdGluZyA9IDA7DQotCQkJdnAgPj4gaVNlbGVjdGluZzsNCi0JCQlhcnJheS5BZGQoaVNlbGVjdGluZyk7DQotCQl9DQotCQllbHNlIGlmICh2cC5Jc0FycmF5T2JqZWN0KCkpDQotCQl7DQotCQkJQ0pTX0FycmF5IFNlbEFycmF5KG1faXNvbGF0ZSk7DQotCQkJQ0pTX1ZhbHVlIFNlbFZhbHVlKG1faXNvbGF0ZSk7DQotCQkJaW50IGlTZWxlY3Rpbmc7DQotCQkJdnAgPj4gU2VsQXJyYXk7DQotCQkJZm9yIChpbnQgaT0wLHN6PVNlbEFycmF5LkdldExlbmd0aCgpOyBpPHN6OyBpKyspDQotCQkJew0KLQkJCQlTZWxBcnJheS5HZXRFbGVtZW50KGksU2VsVmFsdWUpOw0KLQkJCQlpU2VsZWN0aW5nID0gKEZYX0lOVDMyKVNlbFZhbHVlOw0KLQkJCQlhcnJheS5BZGQoaVNlbGVjdGluZyk7DQotCQkJfQ0KLQkJfQ0KLQkJDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfV29yZEFycmF5KEZQX0NVUlJFTlRWQUxVRUlORElDRVMsIGFycmF5KTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0Q3VycmVudFZhbHVlSW5kaWNlcyhtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGFycmF5KTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfQ09NQk9CT1ggJiYgcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX0xJU1RCT1gpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkNvdW50U2VsZWN0ZWRJdGVtcygpID09IDEpDQotCQkJdnAgPDwgcEZvcm1GaWVsZC0+R2V0U2VsZWN0ZWRJbmRleCgwKTsNCi0JCWVsc2UgaWYgKHBGb3JtRmllbGQtPkNvdW50U2VsZWN0ZWRJdGVtcygpID4gMSkNCi0JCXsNCi0JCQlDSlNfQXJyYXkgU2VsQXJyYXkobV9pc29sYXRlKTsNCi0JCQlmb3IgKGludCBpPTAsc3o9cEZvcm1GaWVsZC0+Q291bnRTZWxlY3RlZEl0ZW1zKCk7IGk8c3o7IGkrKykNCi0JCQl7DQotCQkJCVNlbEFycmF5LlNldEVsZW1lbnQoaSwgQ0pTX1ZhbHVlKG1faXNvbGF0ZSxwRm9ybUZpZWxkLT5HZXRTZWxlY3RlZEluZGV4KGkpKSk7DQotCQkJfQ0KLQkJCXZwIDw8IFNlbEFycmF5Ow0KLQkJfQ0KLQkJZWxzZQ0KLQkJCXZwIDw8IC0xOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpTZXRDdXJyZW50VmFsdWVJbmRpY2VzKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgDQotCQkJCQkJCQkgICBjb25zdCBDRlhfRFdvcmRBcnJheSYgYXJyYXkpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhwRG9jdW1lbnQsIHN3RmllbGROYW1lLCBGaWVsZEFycmF5KTsNCi0NCi0JZm9yIChpbnQgaT0wLGlzej1GaWVsZEFycmF5LkdldFNpemUoKTsgaTxpc3o7IGkrKykNCi0Jew0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KGkpOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpbnQgbkZpZWxkVHlwZSA9IHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpOw0KLQkJaWYgKG5GaWVsZFR5cGUgPT0gRklFTERUWVBFX0NPTUJPQk9YIHx8IG5GaWVsZFR5cGUgPT0gRklFTERUWVBFX0xJU1RCT1gpDQotCQl7DQotCQkJRlhfRFdPUkQgZHdGaWVsZEZsYWdzID0gcEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpOw0KLQkJCXBGb3JtRmllbGQtPkNsZWFyU2VsZWN0aW9uKFRSVUUpOw0KLQ0KLQkJCWZvciAoaW50IGk9MCxzej1hcnJheS5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQl7DQotCQkJCWlmIChpPjAgJiYgIShkd0ZpZWxkRmxhZ3MgJiAoMTw8MjEpKSkNCi0JCQkJew0KLQkJCQkJYnJlYWs7DQotCQkJCX0NCi0NCi0JCQkJaW50IGlTZWxlY3RpbmcgPSAoRlhfSU5UMzIpYXJyYXkuR2V0QXQoaSk7DQotCQkJCWlmIChpU2VsZWN0aW5nIDwgcEZvcm1GaWVsZC0+Q291bnRPcHRpb25zKCkgJiYgIXBGb3JtRmllbGQtPklzSXRlbVNlbGVjdGVkKGlTZWxlY3RpbmcpKQ0KLQkJCQkJcEZvcm1GaWVsZC0+U2V0SXRlbVNlbGVjdGlvbihpU2VsZWN0aW5nLCBUUlVFKTsNCi0NCi0JCQl9DQotCQkJVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgVFJVRSwgVFJVRSk7DQotCQl9DQotCX0NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6ZGVmYXVsdFN0eWxlKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCS8vIE1RRyBzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChJRFNfU1RSSU5HX05PVFNVUFBPUlQpOw0KLQlyZXR1cm4gRkFMU0U7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCTsJCQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJOw0KLQl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpTZXREZWZhdWx0U3R5bGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4KQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpkZWZhdWx0VmFsdWUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlDRlhfV2lkZVN0cmluZyBXaWRlU3RyOw0KLQkJdnAgPj4gV2lkZVN0cjsgDQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfV2lkZVN0cmluZyhGUF9ERUZBVUxUVkFMVUUsIFdpZGVTdHIpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXREZWZhdWx0VmFsdWUobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBXaWRlU3RyKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfUFVTSEJVVFRPTiB8fCANCi0JCQlwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfU0lHTkFUVVJFKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCXZwIDw8IHBGb3JtRmllbGQtPkdldERlZmF1bHRWYWx1ZSgpOw0KLQl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpTZXREZWZhdWx0VmFsdWUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LA0KLQkJCQkJCQljb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpkb05vdFNjcm9sbChPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X0Jvb2woRlBfRE9OT1RTQ1JPTEwsIGJWUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldERvTm90U2Nyb2xsKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYlZQKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfVEVYVEZJRUxEKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfRE9OT1RTQ1JPTEwpDQotCQkJdnAgPDwgdHJ1ZTsNCi0JCWVsc2UNCi0JCQl2cCA8PCBmYWxzZTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0RG9Ob3RTY3JvbGwoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmRvTm90U3BlbGxDaGVjayhPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQgJiYgDQotCQkJcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX0NPTUJPQk9YKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfRE9OT1RTUEVMTENIRUNLKQ0KLQkJCXZwIDw8IHRydWU7DQotCQllbHNlDQotCQkJdnAgPDwgZmFsc2U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldERlbGF5KEZYX0JPT0wgYkRlbGF5KQ0KLXsNCi0JbV9iRGVsYXkgPSBiRGVsYXk7DQotDQotCWlmICghbV9iRGVsYXkpDQotCXsNCi0JCWlmIChtX3BKU0RvYykNCi0JCQltX3BKU0RvYy0+RG9GaWVsZERlbGF5KG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4KTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpkZWxheShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotCQkNCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQ0KLQkJU2V0RGVsYXkoYlZQKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXZwIDw8IG1fYkRlbGF5Ow0KLQl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpkaXNwbGF5KE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaW50IG5WUDsNCi0JCXZwID4+IG5WUDsJDQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfSW50KEZQX0RJU1BMQVksIG5WUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldERpc3BsYXkobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQoR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCkpOw0KLQkJaWYgKCFwV2lkZ2V0KXJldHVybiBGQUxTRTsNCi0NCi0JCUZYX0RXT1JEIGR3RmxhZyA9IHBXaWRnZXQtPkdldEZsYWdzKCk7DQotDQotCQlpZiAoQU5OT1RGTEFHX0lOVklTSUJMRSAmIGR3RmxhZyB8fCBBTk5PVEZMQUdfSElEREVOICYgZHdGbGFnKSANCi0JCXsNCi0JCQl2cCA8PCAoRlhfSU5UMzIpMTsNCi0JCX0NCi0JCWVsc2UgDQotCQl7DQotCQkJaWYgKEFOTk9URkxBR19QUklOVCAmIGR3RmxhZykNCi0JCQl7DQotCQkJCWlmIChBTk5PVEZMQUdfTk9WSUVXICYgZHdGbGFnKQ0KLQkJCQl7DQotCQkJCQl2cCA8PCAoRlhfSU5UMzIpMzsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsNCi0JCQkJCXZwIDw8IChGWF9JTlQzMikwOw0KLQkJCQl9DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCXZwIDw8IChGWF9JTlQzMikyOw0KLQkJCX0JCQkJDQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldERpc3BsYXkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKQ0KLXsNCi0JQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKXBEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhwRG9jdW1lbnQsIHN3RmllbGROYW1lLCBGaWVsZEFycmF5KTsNCi0NCi0JZm9yIChpbnQgaT0wLGlzej1GaWVsZEFycmF5LkdldFNpemUoKTsgaTxpc3o7IGkrKykNCi0Jew0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KGkpOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpZiAobkNvbnRyb2xJbmRleCA8IDApDQotCQl7DQotCQkJRlhfQk9PTCBiU2V0ID0gRkFMU0U7DQotCQkJZm9yIChpbnQgaj0wLGpzeiA9IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgajxqc3o7IGorKykNCi0JCQl7DQotCQkJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2woaik7DQotCQkJCUFTU0VSVChwRm9ybUNvbnRyb2wgIT0gTlVMTCk7DQotDQotCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpKQ0KLQkJCQl7DQotCQkJCQlGWF9EV09SRCBkd0ZsYWcgPSBwV2lkZ2V0LT5HZXRGbGFncygpOw0KLQkJCQkJc3dpdGNoIChudW1iZXIpDQotCQkJCQl7DQotCQkJCQljYXNlIDA6DQotCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX0lOVklTSUJMRSk7DQotCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX0hJRERFTik7DQotCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX05PVklFVyk7DQotCQkJCQkJZHdGbGFnIHw9IEFOTk9URkxBR19QUklOVDsJCQkJCQkJDQotCQkJCQkJYnJlYWs7DQotCQkJCQljYXNlIDE6DQotCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX0lOVklTSUJMRSk7DQotCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX05PVklFVyk7DQotCQkJCQkJZHdGbGFnIHw9IChBTk5PVEZMQUdfSElEREVOIHwgQU5OT1RGTEFHX1BSSU5UKTsNCi0JCQkJCQlicmVhazsNCi0JCQkJCWNhc2UgMjoNCi0JCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfSU5WSVNJQkxFKTsNCi0JCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfUFJJTlQpOw0KLQkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19ISURERU4pOw0KLQkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19OT1ZJRVcpOw0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJY2FzZSAzOg0KLQkJCQkJCWR3RmxhZyB8PSBBTk5PVEZMQUdfTk9WSUVXOw0KLQkJCQkJCWR3RmxhZyB8PSBBTk5PVEZMQUdfUFJJTlQ7DQotCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX0hJRERFTik7DQotCQkJCQkJYnJlYWs7DQotCQkJCQl9CQ0KLQ0KLQkJCQkJaWYgKGR3RmxhZyAhPSBwV2lkZ2V0LT5HZXRGbGFncygpKQ0KLQkJCQkJew0KLQkJCQkJCXBXaWRnZXQtPlNldEZsYWdzKGR3RmxhZyk7DQotCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9CQkNCi0JCQkNCi0JCQlpZiAoYlNldCkgVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgRkFMU0UsIFRSVUUpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmKG5Db250cm9sSW5kZXggPj0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpKSByZXR1cm47DQotCQkJaWYgKENQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2wobkNvbnRyb2xJbmRleCkpDQotCQkJew0KLQkJCQlpZiAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1Db250cm9sKSkNCi0JCQkJew0KLQ0KLQkJCQkJRlhfRFdPUkQgZHdGbGFnID0gcFdpZGdldC0+R2V0RmxhZ3MoKTsNCi0JCQkJCXN3aXRjaCAobnVtYmVyKQ0KLQkJCQkJew0KLQkJCQkJY2FzZSAwOg0KLQkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOw0KLQkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19ISURERU4pOw0KLQkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19OT1ZJRVcpOw0KLQkJCQkJCWR3RmxhZyB8PSBBTk5PVEZMQUdfUFJJTlQ7CQkJCQkJCQ0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJY2FzZSAxOg0KLQkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOw0KLQkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19OT1ZJRVcpOw0KLQkJCQkJCWR3RmxhZyB8PSAoQU5OT1RGTEFHX0hJRERFTiB8IEFOTk9URkxBR19QUklOVCk7DQotCQkJCQkJYnJlYWs7DQotCQkJCQljYXNlIDI6DQotCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX0lOVklTSUJMRSk7DQotCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX1BSSU5UKTsNCi0JCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfSElEREVOKTsNCi0JCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfTk9WSUVXKTsNCi0JCQkJCQlicmVhazsNCi0JCQkJCWNhc2UgMzoNCi0JCQkJCQlkd0ZsYWcgfD0gQU5OT1RGTEFHX05PVklFVzsNCi0JCQkJCQlkd0ZsYWcgfD0gQU5OT1RGTEFHX1BSSU5UOw0KLQkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19ISURERU4pOw0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJfQkNCi0JCQkJCWlmIChkd0ZsYWcgIT0gcFdpZGdldC0+R2V0RmxhZ3MoKSkNCi0JCQkJCXsNCi0JCQkJCQlwV2lkZ2V0LT5TZXRGbGFncyhkd0ZsYWcpOw0KLQkJCQkJCVVwZGF0ZUZvcm1Db250cm9sKHBEb2N1bWVudCwgcEZvcm1Db250cm9sLCBUUlVFLCBGQUxTRSwgVFJVRSk7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6ZG9jKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BKU0RvYyAhPSBOVUxMKTsNCi0NCi0JaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7DQotDQotCXZwIDw8IChDSlNfT2JqZWN0KikoKm1fcEpTRG9jKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmVkaXRhYmxlKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJYm9vbCBiVlA7DQotCQl2cCA+PiBiVlA7DQotDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9DT01CT0JPWCkNCi0JCQlyZXR1cm4gRkFMU0U7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX0VESVQpDQotCQkJdnAgPDwgdHJ1ZTsNCi0JCWVsc2UNCi0JCQl2cCA8PCBmYWxzZTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6ZXhwb3J0VmFsdWVzKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfQ0hFQ0tCT1ggJiYgDQotCQlwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfUkFESU9CVVRUT04pDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0JewkNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotCQlpZiAoIXZwLklzQXJyYXlPYmplY3QoKSlyZXR1cm4gRkFMU0U7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDSlNfQXJyYXkgRXhwb3J0VmFsdXNBcnJheShtX2lzb2xhdGUpOw0KLQ0KLQkJaWYgKG1fbkZvcm1Db250cm9sSW5kZXggPCAwKQ0KLQkJew0KLQkJCWZvciAoaW50IGk9MCxzej1wRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGk8c3o7IGkrKykNCi0JCQl7DQotCQkJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2woaSk7DQotCQkJCUFTU0VSVChwRm9ybUNvbnRyb2wgIT0gTlVMTCk7DQotDQotCQkJCUV4cG9ydFZhbHVzQXJyYXkuU2V0RWxlbWVudChpLCBDSlNfVmFsdWUobV9pc29sYXRlLChGWF9MUENXU1RSKXBGb3JtQ29udHJvbC0+R2V0RXhwb3J0VmFsdWUoKSkpOw0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlpZihtX25Gb3JtQ29udHJvbEluZGV4ID49IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuIEZBTFNFOw0KLQkJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2wobV9uRm9ybUNvbnRyb2xJbmRleCk7DQotCQkJaWYgKCFwRm9ybUNvbnRyb2wpIHJldHVybiBGQUxTRTsNCi0NCi0JCQlFeHBvcnRWYWx1c0FycmF5LlNldEVsZW1lbnQoMCwgQ0pTX1ZhbHVlKG1faXNvbGF0ZSwoRlhfTFBDV1NUUilwRm9ybUNvbnRyb2wtPkdldEV4cG9ydFZhbHVlKCkpKTsNCi0JCX0NCi0NCi0JCXZwIDw8IEV4cG9ydFZhbHVzQXJyYXk7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmZpbGVTZWxlY3QoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfVEVYVEZJRUxEKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlib29sIGJWUDsNCi0JCXZwID4+IGJWUDsNCi0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfRklMRVNFTEVDVCkNCi0JCQl2cCA8PCB0cnVlOw0KLQkJZWxzZQ0KLQkJCXZwIDw8IGZhbHNlOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpmaWxsQ29sb3IoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDSlNfQXJyYXkgY3JBcnJheShtX2lzb2xhdGUpOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQkJaWYgKCF2cC5Jc0FycmF5T2JqZWN0KCkpIHJldHVybiBGQUxTRTsNCi0NCi0JCXZwID4+IGNyQXJyYXk7DQotDQotCQlDUFdMX0NvbG9yIGNvbG9yOw0KLQkJY29sb3I6OkNvbnZlcnRBcnJheVRvUFdMQ29sb3IoY3JBcnJheSwgY29sb3IpOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X0NvbG9yKEZQX0ZJTExDT0xPUiwgY29sb3IpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXRGaWxsQ29sb3IobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBjb2xvcik7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOw0KLQkJaWYgKCFwRm9ybUNvbnRyb2wpcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaW50IGlDb2xvclR5cGU7DQotCQlwRm9ybUNvbnRyb2wtPkdldEJhY2tncm91bmRDb2xvcihpQ29sb3JUeXBlKTsNCi0NCi0JCUNQV0xfQ29sb3IgY29sb3I7DQotDQotCQlpZiAoaUNvbG9yVHlwZSA9PSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQpDQotCQl7DQotCQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9UUkFOU1BBUkVOVCk7DQotCQl9DQotCQllbHNlIGlmIChpQ29sb3JUeXBlID09IENPTE9SVFlQRV9HUkFZKQ0KLQkJew0KLQkJCWNvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJhY2tncm91bmRDb2xvcigwKSk7DQotCQl9DQotCQllbHNlIGlmIChpQ29sb3JUeXBlID09IENPTE9SVFlQRV9SR0IpDQotCQl7DQotCQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIHBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMCksDQotCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMSksDQotCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMikpOw0KLQkJfQ0KLQkJZWxzZSBpZiAoaUNvbG9yVHlwZSA9PSBDT0xPUlRZUEVfQ01ZSykNCi0JCXsNCi0JCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0NNWUssIHBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMCksDQotCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMSksDQotCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMiksDQotCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMykpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCWNvbG9yOjpDb252ZXJ0UFdMQ29sb3JUb0FycmF5KGNvbG9yLCBjckFycmF5KTsNCi0gICAgICAgIHZwICA8PCAgY3JBcnJheTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0RmlsbENvbG9yKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmhpZGRlbihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X0Jvb2woRlBfSElEREVOLCBiVlApOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXRIaWRkZW4obV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBiVlApOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQoR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCkpOw0KLQkJaWYgKCFwV2lkZ2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlGWF9EV09SRCBkd0ZsYWdzID0gcFdpZGdldC0+R2V0RmxhZ3MoKTsNCi0NCi0JCWlmIChBTk5PVEZMQUdfSU5WSVNJQkxFICYgZHdGbGFncyB8fCBBTk5PVEZMQUdfSElEREVOICYgZHdGbGFncykgDQotCQl7DQotCQkJdnAgPDwgdHJ1ZTsNCi0JCX0NCi0JCWVsc2UgDQotCQkJdnAgPDwgZmFsc2U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldEhpZGRlbihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYikNCi17DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMocERvY3VtZW50LCBzd0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7DQotDQotCWZvciAoaW50IGk9MCxpc3o9RmllbGRBcnJheS5HZXRTaXplKCk7IGk8aXN6OyBpKyspDQotCXsNCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdChpKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKG5Db250cm9sSW5kZXggPCAwKQ0KLQkJew0KLQkJCUZYX0JPT0wgYlNldCA9IEZBTFNFOw0KLQkJCWZvciAoaW50IGo9MCxqc3ogPSBwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGo8anN6OyBqKyspDQotCQkJew0KLQkJCQlpZiAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1GaWVsZC0+R2V0Q29udHJvbChqKSkpDQotCQkJCXsJCQkJCQ0KLQkJCQkJRlhfRFdPUkQgZHdGbGFncyA9IHBXaWRnZXQtPkdldEZsYWdzKCk7DQotCQkJCQkNCi0JCQkJCWlmIChiKQ0KLQkJCQkJew0KLQkJCQkJCWR3RmxhZ3MgJj0gKH5BTk5PVEZMQUdfSU5WSVNJQkxFKTsNCi0JCQkJCQlkd0ZsYWdzICY9ICh+QU5OT1RGTEFHX05PVklFVyk7DQotCQkJCQkJZHdGbGFncyB8PSAoQU5OT1RGTEFHX0hJRERFTiB8IEFOTk9URkxBR19QUklOVCk7DQotCQkJCQl9DQotCQkJCQllbHNlDQotCQkJCQl7DQotCQkJCQkJZHdGbGFncyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOw0KLQkJCQkJCWR3RmxhZ3MgJj0gKH5BTk5PVEZMQUdfSElEREVOKTsNCi0JCQkJCQlkd0ZsYWdzICY9ICh+QU5OT1RGTEFHX05PVklFVyk7DQotCQkJCQkJZHdGbGFncyB8PSBBTk5PVEZMQUdfUFJJTlQ7CQ0KLQkJCQkJfQ0KLQ0KLQkJCQkJaWYgKGR3RmxhZ3MgIT0gcFdpZGdldC0+R2V0RmxhZ3MoKSkNCi0JCQkJCXsNCi0JCQkJCQlwV2lkZ2V0LT5TZXRGbGFncyhkd0ZsYWdzKTsJDQotCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotDQotCQkJaWYgKGJTZXQpDQotCQkJCVVwZGF0ZUZvcm1GaWVsZChwRG9jdW1lbnQsIHBGb3JtRmllbGQsIFRSVUUsIEZBTFNFLCBUUlVFKTsJDQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYobkNvbnRyb2xJbmRleCA+PSBwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpIHJldHVybjsNCi0JCQlpZiAoQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChuQ29udHJvbEluZGV4KSkNCi0JCQl7DQotCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpKQ0KLQkJCQl7DQotCQkJCQlGWF9EV09SRCBkd0ZsYWdzID0gcFdpZGdldC0+R2V0RmxhZ3MoKTsNCi0JCQkJCQ0KLQkJCQkJaWYgKGIpDQotCQkJCQl7DQotCQkJCQkJZHdGbGFncyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOw0KLQkJCQkJCWR3RmxhZ3MgJj0gKH5BTk5PVEZMQUdfTk9WSUVXKTsNCi0JCQkJCQlkd0ZsYWdzIHw9IChBTk5PVEZMQUdfSElEREVOIHwgQU5OT1RGTEFHX1BSSU5UKTsNCi0JCQkJCX0NCi0JCQkJCWVsc2UNCi0JCQkJCXsNCi0JCQkJCQlkd0ZsYWdzICY9ICh+QU5OT1RGTEFHX0lOVklTSUJMRSk7DQotCQkJCQkJZHdGbGFncyAmPSAofkFOTk9URkxBR19ISURERU4pOw0KLQkJCQkJCWR3RmxhZ3MgJj0gKH5BTk5PVEZMQUdfTk9WSUVXKTsNCi0JCQkJCQlkd0ZsYWdzIHw9IEFOTk9URkxBR19QUklOVDsJDQotCQkJCQl9DQotDQotCQkJCQlpZiAoZHdGbGFncyAhPSBwV2lkZ2V0LT5HZXRGbGFncygpKQ0KLQkJCQkJew0KLQkJCQkJCXBXaWRnZXQtPlNldEZsYWdzKGR3RmxhZ3MpOwkNCi0JCQkJCQlVcGRhdGVGb3JtQ29udHJvbChwRG9jdW1lbnQsIHBGb3JtQ29udHJvbCwgVFJVRSwgRkFMU0UsIFRSVUUpOwkNCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpoaWdobGlnaHQoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlDRlhfQnl0ZVN0cmluZyBzdHJNb2RlOw0KLQkJdnAgPj4gc3RyTW9kZTsNCi0NCi0JCWlmIChtX2JEZWxheSkNCi0JCXsNCi0JCQlBZGREZWxheV9TdHJpbmcoRlBfSElHSExJR0hULCBzdHJNb2RlKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0SGlnaGxpZ2h0KG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgc3RyTW9kZSk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1BVU0hCVVRUT04pDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7DQotCQlpZiAoIXBGb3JtQ29udHJvbCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaW50IGVITSA9IHBGb3JtQ29udHJvbC0+R2V0SGlnaGxpZ2h0aW5nTW9kZSgpOw0KLQkJc3dpdGNoIChlSE0pDQotCQl7DQotCQljYXNlIENQREZfRm9ybUNvbnRyb2w6Ok5vbmU6DQotCQkJdnAgIDw8ICAoRlhfTFBDV1NUUilMIm5vbmUiOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBDUERGX0Zvcm1Db250cm9sOjpQdXNoOg0KLQkJCXZwICA8PCAgKEZYX0xQQ1dTVFIpTCJwdXNoIjsNCi0JCQlicmVhazsNCi0JCWNhc2UgQ1BERl9Gb3JtQ29udHJvbDo6SW52ZXJ0Og0KLQkJCXZwICA8PCAgKEZYX0xQQ1dTVFIpTCJpbnZlcnQiOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBDUERGX0Zvcm1Db250cm9sOjpPdXRsaW5lOg0KLQkJCXZwICA8PCAgKEZYX0xQQ1dTVFIpTCJvdXRsaW5lIjsNCi0JCQlicmVhazsNCi0JCWNhc2UgQ1BERl9Gb3JtQ29udHJvbDo6VG9nZ2xlOg0KLQkJCSB2cCAgPDwgIChGWF9MUENXU1RSKUwidG9nZ2xlIjsNCi0JCQkgYnJlYWs7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldEhpZ2hsaWdodChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmxpbmVXaWR0aChPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWludCBpV2lkdGg7DQotCQl2cCA+PiBpV2lkdGg7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfSW50KEZQX0xJTkVXSURUSCwgaVdpZHRoKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0TGluZVdpZHRoKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgaVdpZHRoKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOw0KLQkJaWYgKCFwRm9ybUNvbnRyb2wpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7DQotCQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JCWlmKCFwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtRmllbGQtPkdldENvbnRyb2woMCkpOw0KLQkJaWYgKCFwV2lkZ2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQl2cCA8PCAoRlhfSU5UMzIpcFdpZGdldC0+R2V0Qm9yZGVyV2lkdGgoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0TGluZVdpZHRoKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikNCi17DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOw0KLQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMocERvY3VtZW50LCBzd0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7DQotDQotCWZvciAoaW50IGk9MCxpc3o9RmllbGRBcnJheS5HZXRTaXplKCk7IGk8aXN6OyBpKyspDQotCXsNCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdChpKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKG5Db250cm9sSW5kZXggPCAwKQ0KLQkJew0KLQkJCUZYX0JPT0wgYlNldCA9IEZBTFNFOw0KLQkJCWZvciAoaW50IGo9MCxqc3o9cEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBqPGpzejsgaisrKQ0KLQkJCXsNCi0JCQkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChqKTsNCi0JCQkJQVNTRVJUKHBGb3JtQ29udHJvbCAhPSBOVUxMKTsNCi0JCQkJDQotCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpKQ0KLQkJCQl7DQotCQkJCQlpZiAobnVtYmVyICE9IHBXaWRnZXQtPkdldEJvcmRlcldpZHRoKCkpDQotCQkJCQl7DQotCQkJCQkJcFdpZGdldC0+U2V0Qm9yZGVyV2lkdGgobnVtYmVyKTsNCi0JCQkJCQliU2V0ID0gVFJVRTsNCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCX0NCi0JCQlpZiAoYlNldCkgVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgVFJVRSwgVFJVRSk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYobkNvbnRyb2xJbmRleCA+PSBwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpIHJldHVybjsNCi0JCQlpZiAoQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChuQ29udHJvbEluZGV4KSkNCi0JCQl7DQotCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpKQ0KLQkJCQl7DQotCQkJCQlpZiAobnVtYmVyICE9IHBXaWRnZXQtPkdldEJvcmRlcldpZHRoKCkpDQotCQkJCQl7DQotCQkJCQkJcFdpZGdldC0+U2V0Qm9yZGVyV2lkdGgobnVtYmVyKTsNCi0JCQkJCQlVcGRhdGVGb3JtQ29udHJvbChwRG9jdW1lbnQsIHBGb3JtQ29udHJvbCwgVFJVRSwgVFJVRSwgVFJVRSk7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6bXVsdGlsaW5lKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJYm9vbCBiVlA7DQotCQl2cCA+PiBiVlA7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfQm9vbChGUF9NVUxUSUxJTkUsIGJWUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldE11bHRpbGluZShtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGJWUCk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19NVUxUSUxJTkUpDQotCQkJdnAgPDwgdHJ1ZTsNCi0JCWVsc2UNCi0JCQl2cCA8PCBmYWxzZTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0TXVsdGlsaW5lKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjptdWx0aXBsZVNlbGVjdGlvbihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X0Jvb2woRlBfTVVMVElQTEVTRUxFQ1RJT04sIGJWUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldE11bHRpcGxlU2VsZWN0aW9uKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYlZQKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfTElTVEJPWCkNCi0JCQlyZXR1cm4gRkFMU0U7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX01VTFRJU0VMRUNUKQ0KLQkJCXZwIDw8IHRydWU7DQotCQllbHNlDQotCQkJdnAgPDwgZmFsc2U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldE11bHRpcGxlU2VsZWN0aW9uKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpuYW1lKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICghdnAuSXNHZXR0aW5nKCkpIHJldHVybiBGQUxTRTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOw0KLQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLSAgIAl2cCA8PCBtX0ZpZWxkTmFtZTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6Om51bUl0ZW1zKE9CSl9QUk9QX1BBUkFNUykNCi17CQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfQ09NQk9CT1ggJiYNCi0JCXBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9MSVNUQk9YKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAoIXZwLklzR2V0dGluZygpKSByZXR1cm4gRkFMU0U7DQotDQotCXZwIDw8IChGWF9JTlQzMilwRm9ybUZpZWxkLT5Db3VudE9wdGlvbnMoKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnBhZ2UoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKCF2cC5Jc0dldHRpbmcoKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JaWYgKCFwRm9ybUZpZWxkKSByZXR1cm4gRkFMU0U7DQotDQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNGWF9QdHJBcnJheSB3aWRnZXRBcnJheTsNCi0JcEludGVyRm9ybS0+R2V0V2lkZ2V0cyhwRm9ybUZpZWxkLCB3aWRnZXRBcnJheSk7DQotDQotCWlmICh3aWRnZXRBcnJheS5HZXRTaXplKCkgPiAwKQ0KLQl7DQotCQlDSlNfQXJyYXkgUGFnZUFycmF5KG1faXNvbGF0ZSk7DQotDQotCQlmb3IgKGludCBpPTAsc3o9d2lkZ2V0QXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQl7DQotCQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXdpZGdldEFycmF5LkdldEF0KGkpOw0KLQkJCUFTU0VSVChwV2lkZ2V0ICE9IE5VTEwpOw0KLQ0KLQkJCUNQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldyA9IHBXaWRnZXQtPkdldFBhZ2VWaWV3KCk7DQotCQkJaWYoIXBQYWdlVmlldykNCi0JCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJCVBhZ2VBcnJheS5TZXRFbGVtZW50KGksIENKU19WYWx1ZShtX2lzb2xhdGUsKEZYX0lOVDMyKXBQYWdlVmlldy0+R2V0UGFnZUluZGV4KCkpKTsNCi0JCX0NCi0NCi0JCXZwIDw8IFBhZ2VBcnJheTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXZwIDw8IChGWF9JTlQzMikgLTE7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnBhc3N3b3JkKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJYm9vbCBiVlA7DQotCQl2cCA+PiBiVlA7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfQm9vbChGUF9QQVNTV09SRCwgYlZQKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0UGFzc3dvcmQobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBiVlApOw0KLQkJfQkNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfVEVYVEZJRUxEKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfUEFTU1dPUkQpDQotCQkJdnAgPDwgdHJ1ZTsNCi0JCWVsc2UNCi0JCQl2cCA8PCBmYWxzZTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0UGFzc3dvcmQoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnByaW50KE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsNCi0JaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJYm9vbCBiVlA7DQotCQl2cCA+PiBiVlA7DQotDQotCQlmb3IgKGludCBpPTAsaXN6PUZpZWxkQXJyYXkuR2V0U2l6ZSgpOyBpPGlzejsgaSsrKQ0KLQkJew0KLQkJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdChpKTsNCi0JCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCQlpZiAobV9uRm9ybUNvbnRyb2xJbmRleCA8IDApDQotCQkJew0KLQkJCQlGWF9CT09MIGJTZXQgPSBGQUxTRTsNCi0JCQkJZm9yIChpbnQgaj0wLGpzeiA9IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgajxqc3o7IGorKykNCi0JCQkJew0KLQkJCQkJaWYgKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtRmllbGQtPkdldENvbnRyb2woaikpKQ0KLQkJCQkJew0KLQkJCQkJCUZYX0RXT1JEIGR3RmxhZ3MgPSBwV2lkZ2V0LT5HZXRGbGFncygpOw0KLQkJCQkJCWlmIChiVlApDQotCQkJCQkJCWR3RmxhZ3MgfD0gQU5OT1RGTEFHX1BSSU5UOw0KLQkJCQkJCWVsc2UNCi0JCQkJCQkJZHdGbGFncyAmPSB+QU5OT1RGTEFHX1BSSU5UOw0KLQ0KLQkJCQkJCWlmIChkd0ZsYWdzICE9IHBXaWRnZXQtPkdldEZsYWdzKCkpDQotCQkJCQkJew0KLQkJCQkJCQlwV2lkZ2V0LT5TZXRGbGFncyhkd0ZsYWdzKTsNCi0JCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotDQotCQkJCWlmIChiU2V0KQ0KLQkJCQkJVXBkYXRlRm9ybUZpZWxkKG1fcERvY3VtZW50LCBwRm9ybUZpZWxkLCBUUlVFLCBGQUxTRSwgVFJVRSk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCWlmKG1fbkZvcm1Db250cm9sSW5kZXggPj0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpKSByZXR1cm4gRkFMU0U7DQotCQkJCWlmIChDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKG1fbkZvcm1Db250cm9sSW5kZXgpKQ0KLQkJCQl7DQotCQkJCQlpZiAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1Db250cm9sKSkNCi0JCQkJCXsNCi0JCQkJCQlGWF9EV09SRCBkd0ZsYWdzID0gcFdpZGdldC0+R2V0RmxhZ3MoKTsNCi0JCQkJCQlpZiAoYlZQKQ0KLQkJCQkJCQlkd0ZsYWdzIHw9IEFOTk9URkxBR19QUklOVDsNCi0JCQkJCQllbHNlDQotCQkJCQkJCWR3RmxhZ3MgJj0gfkFOTk9URkxBR19QUklOVDsNCi0NCi0JCQkJCQlpZiAoZHdGbGFncyAhPSBwV2lkZ2V0LT5HZXRGbGFncygpKQ0KLQkJCQkJCXsNCi0JCQkJCQkJcFdpZGdldC0+U2V0RmxhZ3MoZHdGbGFncyk7DQotCQkJCQkJCVVwZGF0ZUZvcm1Db250cm9sKG1fcERvY3VtZW50LCBwRm9ybUZpZWxkLT5HZXRDb250cm9sKG1fbkZvcm1Db250cm9sSW5kZXgpLCBUUlVFLCBGQUxTRSwgVFJVRSk7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotCQkNCi0JCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpKTsNCi0JCWlmICghcFdpZGdldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaWYgKHBXaWRnZXQtPkdldEZsYWdzKCkgJiBBTk5PVEZMQUdfUFJJTlQpDQotCQkJdnAgPDwgdHJ1ZTsNCi0JCWVsc2UNCi0JCQl2cCA8PCBmYWxzZTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6cmFkaW9zSW5Vbmlzb24oT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJYm9vbCBiVlA7DQotCQl2cCA+PiBiVlA7DQotDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfUkFESU9CVVRUT04pDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19SQURJT1NJTlVOSVNPTikNCi0JCQl2cCA8PCB0cnVlOw0KLQkJZWxzZQ0KLQkJCXZwIDw8IGZhbHNlOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpyZWFkb25seShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlib29sIGJWUDsNCi0JCXZwID4+IGJWUDsNCi0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19SRUFET05MWSkNCi0JCQl2cCA8PCB0cnVlOw0KLQkJZWxzZQ0KLQkJCXZwIDw8IGZhbHNlOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpyZWN0KE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQkJaWYgKCF2cC5Jc0FycmF5T2JqZWN0KCkpcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0pTX0FycmF5IHJjQXJyYXkobV9pc29sYXRlKTsNCi0JCXZwID4+IHJjQXJyYXk7DQotCQlDSlNfVmFsdWUgVXBwZXJfTGVmdHgobV9pc29sYXRlKSwgVXBwZXJfTGVmdHkobV9pc29sYXRlKSwgTG93ZXJfUmlnaHR4KG1faXNvbGF0ZSksIExvd2VyX1JpZ2h0eShtX2lzb2xhdGUpOw0KLQkJcmNBcnJheS5HZXRFbGVtZW50KDAsIFVwcGVyX0xlZnR4KTsNCi0JCXJjQXJyYXkuR2V0RWxlbWVudCgxLCBVcHBlcl9MZWZ0eSk7DQotCQlyY0FycmF5LkdldEVsZW1lbnQoMiwgTG93ZXJfUmlnaHR4KTsNCi0JCXJjQXJyYXkuR2V0RWxlbWVudCgzLCBMb3dlcl9SaWdodHkpOw0KLQ0KLQkJRlhfRkxPQVQgcEFycmF5WzRdID0gezAuMGYsMC4wZiwwLjBmLDAuMGZ9Ow0KLQkJcEFycmF5WzBdID0gKEZYX0ZMT0FUKShGWF9JTlQzMilVcHBlcl9MZWZ0eDsNCi0JCXBBcnJheVsxXSA9IChGWF9GTE9BVCkoRlhfSU5UMzIpTG93ZXJfUmlnaHR5Ow0KLQkJcEFycmF5WzJdID0gKEZYX0ZMT0FUKShGWF9JTlQzMilMb3dlcl9SaWdodHg7DQotCQlwQXJyYXlbM10gPSAoRlhfRkxPQVQpKEZYX0lOVDMyKVVwcGVyX0xlZnR5Ow0KLQ0KLQkJQ1BERl9SZWN0IGNyUmVjdChwQXJyYXkpOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X1JlY3QoRlBfUkVDVCwgY3JSZWN0KTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0UmVjdChtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGNyUmVjdCk7DQotCQl9CQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQoR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCkpOw0KLQkJaWYgKCFwV2lkZ2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlDRlhfRmxvYXRSZWN0IGNyUmVjdCA9IHBXaWRnZXQtPkdldFJlY3QoKTsNCi0JCUNKU19WYWx1ZSBVcHBlcl9MZWZ0eChtX2lzb2xhdGUpLFVwcGVyX0xlZnR5KG1faXNvbGF0ZSksTG93ZXJfUmlnaHR4KG1faXNvbGF0ZSksTG93ZXJfUmlnaHR5KG1faXNvbGF0ZSk7DQotCQlVcHBlcl9MZWZ0eCA9IChGWF9JTlQzMiljclJlY3QubGVmdDsNCi0JCVVwcGVyX0xlZnR5ID0gKEZYX0lOVDMyKWNyUmVjdC50b3A7DQotCQlMb3dlcl9SaWdodHggPSAoRlhfSU5UMzIpY3JSZWN0LnJpZ2h0Ow0KLQkJTG93ZXJfUmlnaHR5ID0gKEZYX0lOVDMyKWNyUmVjdC5ib3R0b207DQotDQotCQlDSlNfQXJyYXkgcmNBcnJheShtX2lzb2xhdGUpOw0KLQkJcmNBcnJheS5TZXRFbGVtZW50KDAsVXBwZXJfTGVmdHgpOw0KLQkJcmNBcnJheS5TZXRFbGVtZW50KDEsVXBwZXJfTGVmdHkpOw0KLQkJcmNBcnJheS5TZXRFbGVtZW50KDIsTG93ZXJfUmlnaHR4KTsNCi0JCXJjQXJyYXkuU2V0RWxlbWVudCgzLExvd2VyX1JpZ2h0eSk7DQotDQotCQl2cCAgPDwgIHJjQXJyYXk7CQkJDQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldFJlY3QoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDUERGX1JlY3QmIHJlY3QpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKHBEb2N1bWVudCwgc3dGaWVsZE5hbWUsIEZpZWxkQXJyYXkpOw0KLQ0KLQlmb3IgKGludCBpPTAsaXN6PUZpZWxkQXJyYXkuR2V0U2l6ZSgpOyBpPGlzejsgaSsrKQ0KLQl7DQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoaSk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCWlmIChuQ29udHJvbEluZGV4IDwgMCkNCi0JCXsNCi0JCQlGWF9CT09MIGJTZXQgPSBGQUxTRTsNCi0JCQlmb3IgKGludCBpPTAsIHN6PXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgaTxzejsgaSsrKQ0KLQkJCXsNCi0JCQkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChpKTsNCi0JCQkJQVNTRVJUKHBGb3JtQ29udHJvbCAhPSBOVUxMKTsNCi0NCi0JCQkJaWYgKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtQ29udHJvbCkpDQotCQkJCXsNCi0JCQkJCUNQREZfUmVjdCBjclJlY3QgPSByZWN0Ow0KLQ0KLQkJCQkJQ1BERl9QYWdlKiBwUERGUGFnZSA9IHBXaWRnZXQtPkdldFBERlBhZ2UoKTsNCi0JCQkJCUFTU0VSVChwUERGUGFnZSAhPSBOVUxMKTsNCi0NCi0vLyAJCQkJCUNQREZfUGFnZSogcFBERlBhZ2UgPSBwUGFnZS0+R2V0UGFnZSgpOw0KLS8vIAkJCQkJQVNTRVJUKHBQREZQYWdlICE9IE5VTEwpOw0KLQ0KLQkJCQkJY3JSZWN0LkludGVyc2VjdChwUERGUGFnZS0+R2V0UGFnZUJCb3goKSk7DQotDQotCQkJCQlpZiAoIWNyUmVjdC5Jc0VtcHR5KCkpDQotCQkJCQl7DQotCQkJCQkJQ1BERl9SZWN0IHJjT2xkID0gcFdpZGdldC0+R2V0UmVjdCgpOw0KLQkJCQkJCWlmIChjclJlY3QubGVmdCAhPSByY09sZC5sZWZ0IHx8DQotCQkJCQkJCWNyUmVjdC5yaWdodCAhPSByY09sZC5yaWdodCB8fA0KLQkJCQkJCQljclJlY3QudG9wICE9IHJjT2xkLnRvcCB8fA0KLQkJCQkJCQljclJlY3QuYm90dG9tICE9IHJjT2xkLmJvdHRvbSkNCi0JCQkJCQl7DQotCQkJCQkJCXBXaWRnZXQtPlNldFJlY3QoY3JSZWN0KTsNCi0JCQkJCQkJYlNldCA9IFRSVUU7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQ0KLQkJCWlmIChiU2V0KSBVcGRhdGVGb3JtRmllbGQocERvY3VtZW50LCBwRm9ybUZpZWxkLCBUUlVFLCBUUlVFLCBUUlVFKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlpZihuQ29udHJvbEluZGV4ID49IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuOw0KLQkJCWlmIChDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKG5Db250cm9sSW5kZXgpKQ0KLQkJCXsNCi0JCQkJaWYgKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtQ29udHJvbCkpDQotCQkJCXsNCi0JCQkJCUNQREZfUmVjdCBjclJlY3QgPSByZWN0Ow0KLQkJCQkJDQotCQkJCQlDUERGX1BhZ2UqIHBQREZQYWdlID0gcFdpZGdldC0+R2V0UERGUGFnZSgpOw0KLQkJCQkJQVNTRVJUKHBQREZQYWdlICE9IE5VTEwpOw0KLQ0KLS8vIAkJCQkJQ1BERl9QYWdlKiBwUERGUGFnZSA9IHBQYWdlLT5HZXRQYWdlKCk7DQotLy8gCQkJCQlBU1NFUlQocFBERlBhZ2UgIT0gTlVMTCk7DQotDQotCQkJCQljclJlY3QuSW50ZXJzZWN0KHBQREZQYWdlLT5HZXRQYWdlQkJveCgpKTsNCi0NCi0JCQkJCWlmICghY3JSZWN0LklzRW1wdHkoKSkNCi0JCQkJCXsNCi0JCQkJCQlDUERGX1JlY3QgcmNPbGQgPSBwV2lkZ2V0LT5HZXRSZWN0KCk7DQotCQkJCQkJaWYgKGNyUmVjdC5sZWZ0ICE9IHJjT2xkLmxlZnQgfHwNCi0JCQkJCQkJY3JSZWN0LnJpZ2h0ICE9IHJjT2xkLnJpZ2h0IHx8DQotCQkJCQkJCWNyUmVjdC50b3AgIT0gcmNPbGQudG9wIHx8DQotCQkJCQkJCWNyUmVjdC5ib3R0b20gIT0gcmNPbGQuYm90dG9tKQ0KLQkJCQkJCXsNCi0JCQkJCQkJcFdpZGdldC0+U2V0UmVjdChjclJlY3QpOw0KLQkJCQkJCQlVcGRhdGVGb3JtQ29udHJvbChwRG9jdW1lbnQsIHBGb3JtQ29udHJvbCwgVFJVRSwgVFJVRSwgVFJVRSk7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnJlcXVpcmVkKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0NCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX1BVU0hCVVRUT04pDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19SRVFVSVJFRCkNCi0JCQl2cCA8PCB0cnVlOw0KLQkJZWxzZQ0KLQkJCXZwIDw8IGZhbHNlOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpyaWNoVGV4dChPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X0Jvb2woRlBfUklDSFRFWFQsIGJWUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldFJpY2hUZXh0KG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYlZQKTsNCi0JCX0JDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1RFWFRGSUVMRCkNCi0JCQlyZXR1cm4gRkFMU0U7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX1JJQ0hURVhUKQ0KLQkJCXZwIDw8IHRydWU7DQotCQllbHNlDQotCQkJdnAgPDwgZmFsc2U7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldFJpY2hUZXh0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpyaWNoVmFsdWUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0JCTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCTsNCi0JfQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0UmljaFZhbHVlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCkNCi17DQotCS8vTm90IHN1cHBvcnRlZC4NCi19DQotDQotRlhfQk9PTCBGaWVsZDo6cm90YXRpb24oT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlpbnQgblZQOw0KLQkJdnAgPj4gblZQOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X0ludChGUF9ST1RBVElPTiwgblZQKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0Um90YXRpb24obV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOw0KLQkJfQkNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOw0KLQkJaWYgKCFwRm9ybUNvbnRyb2wpcmV0dXJuIEZBTFNFOw0KLQ0KLQkJdnAgPDwgKEZYX0lOVDMyKXBGb3JtQ29udHJvbC0+R2V0Um90YXRpb24oKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0Um90YXRpb24oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpzdHJva2VDb2xvcihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCWlmICghdnAuSXNBcnJheU9iamVjdCgpKXJldHVybiBGQUxTRTsNCi0NCi0JCUNKU19BcnJheSBjckFycmF5KG1faXNvbGF0ZSk7DQotCQl2cCA+PiBjckFycmF5Ow0KLQ0KLQkJQ1BXTF9Db2xvciBjb2xvcjsNCi0JCWNvbG9yOjpDb252ZXJ0QXJyYXlUb1BXTENvbG9yKGNyQXJyYXksIGNvbG9yKTsNCi0NCi0JCWlmIChtX2JEZWxheSkNCi0JCXsNCi0JCQlBZGREZWxheV9Db2xvcihGUF9TVFJPS0VDT0xPUiwgY29sb3IpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUZpZWxkOjpTZXRTdHJva2VDb2xvcihtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGNvbG9yKTsNCi0JCX0JDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBHZXRTbWFydEZpZWxkQ29udHJvbChwRm9ybUZpZWxkKTsNCi0JCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsNCi0NCi0JCWludCBpQ29sb3JUeXBlOw0KLQkJcEZvcm1Db250cm9sLT5HZXRCb3JkZXJDb2xvcihpQ29sb3JUeXBlKTsNCi0NCi0JCUNQV0xfQ29sb3IgY29sb3I7DQotDQotCQlpZiAoaUNvbG9yVHlwZSA9PSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQpDQotCQl7DQotCQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9UUkFOU1BBUkVOVCk7DQotCQl9DQotCQllbHNlIGlmIChpQ29sb3JUeXBlID09IENPTE9SVFlQRV9HUkFZKQ0KLQkJew0KLQkJCWNvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKDApKTsNCi0JCX0NCi0JCWVsc2UgaWYgKGlDb2xvclR5cGUgPT0gQ09MT1JUWVBFX1JHQikNCi0JCXsNCi0JCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKDApLA0KLQkJCQlwRm9ybUNvbnRyb2wtPkdldE9yaWdpbmFsQm9yZGVyQ29sb3IoMSksDQotCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCb3JkZXJDb2xvcigyKSk7DQotCQl9DQotCQllbHNlIGlmIChpQ29sb3JUeXBlID09IENPTE9SVFlQRV9DTVlLKQ0KLQkJew0KLQkJCWNvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfQ01ZSywgcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKDApLA0KLQkJCQlwRm9ybUNvbnRyb2wtPkdldE9yaWdpbmFsQm9yZGVyQ29sb3IoMSksDQotCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCb3JkZXJDb2xvcigyKSwNCi0JCQkJcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKDMpKTsNCi0JCX0NCi0JCWVsc2UNCi0JCQlyZXR1cm4gRkFMU0U7DQotDQotCQlDSlNfQXJyYXkgY3JBcnJheShtX2lzb2xhdGUpOw0KLQkJY29sb3I6OkNvbnZlcnRQV0xDb2xvclRvQXJyYXkoY29sb3IsIGNyQXJyYXkpOw0KLSAgICAgICAgdnAgIDw8ICBjckFycmF5Ow0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpTZXRTdHJva2VDb2xvcihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpzdHlsZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNGWF9CeXRlU3RyaW5nIGNzQkNhcHRpb247DQotCQl2cCA+PiBjc0JDYXB0aW9uOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X1N0cmluZyhGUF9TVFlMRSwgY3NCQ2FwdGlvbik7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldFN0eWxlKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgY3NCQ2FwdGlvbik7DQotCQl9CQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9SQURJT0JVVFRPTiAmJiANCi0JCQlwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfQ0hFQ0tCT1gpDQotCQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7DQotCQlpZiAoIXBGb3JtQ29udHJvbCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgY3NXQ2FwdGlvbiA9IHBGb3JtQ29udHJvbC0+R2V0Tm9ybWFsQ2FwdGlvbigpOw0KLQkJQ0ZYX0J5dGVTdHJpbmcgY3NCQ2FwdGlvbjsNCi0NCi0JCXN3aXRjaCAoY3NXQ2FwdGlvblswXSkNCi0JCXsNCi0JCQljYXNlIEwnbCc6DQotCQkJCWNzQkNhcHRpb24gPSAiY2lyY2xlIjsNCi0JCQkJYnJlYWs7DQotCQkJY2FzZSBMJzgnOg0KLQkJCQljc0JDYXB0aW9uID0gImNyb3NzIjsNCi0JCQkJYnJlYWs7DQotCQkJY2FzZSBMJ3UnOg0KLQkJCQljc0JDYXB0aW9uID0gImRpYW1vbmQiOw0KLQkJCQlicmVhazsNCi0JCQljYXNlIEwnbic6DQotCQkJCWNzQkNhcHRpb24gPSAic3F1YXJlIjsNCi0JCQkJYnJlYWs7DQotCQkJY2FzZSBMJ0gnOg0KLQkJCQljc0JDYXB0aW9uID0gInN0YXIiOw0KLQkJCQlicmVhazsNCi0JCQlkZWZhdWx0OiAvL0wnNCcNCi0JCQkJY3NCQ2FwdGlvbiA9ICJjaGVjayI7DQotCQkJCWJyZWFrOw0KLQkJfQ0KLQkJdnAgPDwgY3NCQ2FwdGlvbjsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0U3R5bGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCANCi0JCQkJCSBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyaW5nKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpzdWJtaXROYW1lKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjp0ZXh0Q29sb3IoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotDQotCQlDSlNfQXJyYXkgY3JBcnJheShtX2lzb2xhdGUpOw0KLQkJaWYgKCF2cC5Jc0FycmF5T2JqZWN0KCkpcmV0dXJuIEZBTFNFOw0KLQkJdnAgPj4gY3JBcnJheTsNCi0NCi0JCUNQV0xfQ29sb3IgY29sb3I7DQotCQljb2xvcjo6Q29udmVydEFycmF5VG9QV0xDb2xvcihjckFycmF5LCBjb2xvcik7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfQ29sb3IoRlBfVEVYVENPTE9SLCBjb2xvcik7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldFRleHRDb2xvcihtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGNvbG9yKTsNCi0JCX0JDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBHZXRTbWFydEZpZWxkQ29udHJvbChwRm9ybUZpZWxkKTsNCi0JCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsNCi0JCQ0KLQkJaW50IGlDb2xvclR5cGU7DQotCQlGWF9BUkdCIGNvbG9yOw0KLQkJQ1BERl9EZWZhdWx0QXBwZWFyYW5jZSBGaWVsZEFwcGVhcmFuY2UgPSBwRm9ybUNvbnRyb2wtPkdldERlZmF1bHRBcHBlYXJhbmNlKCk7DQotCQlGaWVsZEFwcGVhcmFuY2UuR2V0Q29sb3IoY29sb3IsIGlDb2xvclR5cGUpOw0KLQkJRlhfSU5UMzIgYSxyLGcsYjsNCi0JCUFyZ2JEZWNvZGUoY29sb3IsIGEsIHIsIGcsIGIpOw0KLQ0KLQkJQ1BXTF9Db2xvciBjclJldCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgciAvIDI1NS4wZiwNCi0JCQkJZyAvIDI1NS4wZiwNCi0JCQkJYiAvIDI1NS4wZik7DQotDQotCQlpZiAoaUNvbG9yVHlwZSA9PSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQpDQotCQkJY3JSZXQgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9UUkFOU1BBUkVOVCk7DQotDQotCQlDSlNfQXJyYXkgY3JBcnJheShtX2lzb2xhdGUpOw0KLQkJY29sb3I6OkNvbnZlcnRQV0xDb2xvclRvQXJyYXkoY3JSZXQsIGNyQXJyYXkpOw0KLSAgICAgICAgdnAgIDw8ICBjckFycmF5OwkJDQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldFRleHRDb2xvcihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjp0ZXh0Rm9udChPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsNCi0NCi0JCUNGWF9CeXRlU3RyaW5nIGNzRm9udE5hbWU7DQotCQl2cCA+PiBjc0ZvbnROYW1lOw0KLQkJaWYgKGNzRm9udE5hbWUuSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7DQotDQotCQlpZiAobV9iRGVsYXkpDQotCQl7DQotCQkJQWRkRGVsYXlfU3RyaW5nKEZQX1RFWFRGT05ULCBjc0ZvbnROYW1lKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0VGV4dEZvbnQobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBjc0ZvbnROYW1lKTsNCi0JCX0JDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBHZXRTbWFydEZpZWxkQ29udHJvbChwRm9ybUZpZWxkKTsNCi0JCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsNCi0NCi0JCWludCBuRmllbGRUeXBlID0gcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCk7DQotDQotCQlpZiAobkZpZWxkVHlwZSA9PSBGSUVMRFRZUEVfUFVTSEJVVFRPTiB8fCANCi0JCQluRmllbGRUeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCB8fCANCi0JCQluRmllbGRUeXBlID09IEZJRUxEVFlQRV9MSVNUQk9YIHx8DQotCQkJbkZpZWxkVHlwZSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEKQ0KLQkJew0KLQkJCUNQREZfRm9udCAqIHBGb250ID0gcEZvcm1Db250cm9sLT5HZXREZWZhdWx0Q29udHJvbEZvbnQoKTsNCi0JCQlpZiAoIXBGb250KSByZXR1cm4gRkFMU0U7DQotDQotCQkJdnAgPDwgcEZvbnQtPkdldEJhc2VGb250KCk7DQotCQl9DQotCQllbHNlDQotCQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpTZXRUZXh0Rm9udChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnRleHRTaXplKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJaW50IG5WUDsNCi0JCXZwID4+IG5WUDsNCi0NCi0JCWlmIChtX2JEZWxheSkNCi0JCXsNCi0JCQlBZGREZWxheV9JbnQoRlBfVEVYVFNJWkUsIG5WUCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldFRleHRTaXplKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgblZQKTsNCi0JCX0JDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBHZXRTbWFydEZpZWxkQ29udHJvbChwRm9ybUZpZWxkKTsNCi0JCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsNCi0NCi0JCUNQREZfRGVmYXVsdEFwcGVhcmFuY2UgRmllbGRBcHBlYXJhbmNlID0gcEZvcm1Db250cm9sLT5HZXREZWZhdWx0QXBwZWFyYW5jZSgpOw0KLQ0KLQkJQ0ZYX0J5dGVTdHJpbmcgY3NGb250TmFtZVRhZzsNCi0JCUZYX0ZMT0FUIGZGb250U2l6ZTsNCi0JCUZpZWxkQXBwZWFyYW5jZS5HZXRGb250KGNzRm9udE5hbWVUYWcsZkZvbnRTaXplKTsNCi0NCi0JCXZwIDw8IChpbnQpZkZvbnRTaXplOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpTZXRUZXh0U2l6ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnR5cGUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIXZwLklzR2V0dGluZygpKSByZXR1cm4gRkFMU0U7DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLSAJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0Jc3dpdGNoIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSkNCi0Jew0KLQkJY2FzZSBGSUVMRFRZUEVfVU5LTk9XTjoNCi0JCQl2cCA8PCAoRlhfTFBDV1NUUilMInVua25vd24iOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBGSUVMRFRZUEVfUFVTSEJVVFRPTjoNCi0JCQl2cCA8PCAoRlhfTFBDV1NUUilMImJ1dHRvbiI7DQotCQkJYnJlYWs7DQotCQljYXNlIEZJRUxEVFlQRV9DSEVDS0JPWDoNCi0JCQl2cCA8PCAoRlhfTFBDV1NUUilMImNoZWNrYm94IjsNCi0JCQlicmVhazsNCi0JCWNhc2UgRklFTERUWVBFX1JBRElPQlVUVE9OOg0KLQkJCXZwIDw8IChGWF9MUENXU1RSKUwicmFkaW9idXR0b24iOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBGSUVMRFRZUEVfQ09NQk9CT1g6DQotCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJjb21ib2JveCI7DQotCQkJYnJlYWs7DQotCQljYXNlIEZJRUxEVFlQRV9MSVNUQk9YOg0KLQkJCXZwIDw8IChGWF9MUENXU1RSKUwibGlzdGJveCI7DQotCQkJYnJlYWs7DQotCQljYXNlIEZJRUxEVFlQRV9URVhURklFTEQ6DQotCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJ0ZXh0IjsNCi0JCQlicmVhazsNCi0JCWNhc2UgRklFTERUWVBFX1NJR05BVFVSRToNCi0JCQl2cCA8PCAoRlhfTFBDV1NUUilMInNpZ25hdHVyZSI7DQotCQkJYnJlYWs7DQotCQlkZWZhdWx0IDoNCi0JCQl2cCA8PCAoRlhfTFBDV1NUUilMInVua25vd24iOw0KLQkJCWJyZWFrOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjp1c2VyTmFtZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotICAJaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgc3dOYW1lOw0KLQkJdnAgPj4gc3dOYW1lOw0KLQ0KLQkJaWYgKG1fYkRlbGF5KQ0KLQkJew0KLQkJCUFkZERlbGF5X1dpZGVTdHJpbmcoRlBfVVNFUk5BTUUsIHN3TmFtZSk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJRmllbGQ6OlNldFVzZXJOYW1lKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgc3dOYW1lKTsNCi0JCX0JDQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLSAJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJdnAgPDwgKENGWF9XaWRlU3RyaW5nKXBGb3JtRmllbGQtPkdldEFsdGVybmF0ZU5hbWUoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBGaWVsZDo6U2V0VXNlck5hbWUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKQ0KLXsNCi0JLy9Ob3Qgc3VwcG9ydGVkLg0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjp2YWx1ZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0JewkJDQotCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJQ0pTX1dpZGVTdHJpbmdBcnJheSBzdHJBcnJheTsNCi0NCi0JCWlmICh2cC5Jc0FycmF5T2JqZWN0KCkpDQotCQl7DQotCQkJQ0pTX0FycmF5IFZhbHVlQXJyYXkobV9pc29sYXRlKTsNCi0JCQl2cC5Db252ZXJ0VG9BcnJheShWYWx1ZUFycmF5KTsNCi0JCQlmb3IgKGludCBpID0gMCxzeiA9IFZhbHVlQXJyYXkuR2V0TGVuZ3RoKCk7IGkgPCBzejsgaSsrKQ0KLQkJCXsNCi0JCQkJQ0pTX1ZhbHVlIEVsZW1lbnRWYWx1ZShtX2lzb2xhdGUpOw0KLQkJCQlWYWx1ZUFycmF5LkdldEVsZW1lbnQoaSwgRWxlbWVudFZhbHVlKTsNCi0JCQkJc3RyQXJyYXkuQWRkKEVsZW1lbnRWYWx1ZS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsNCi0JCQl9DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJQ0ZYX1dpZGVTdHJpbmcgc3dWYWx1ZTsNCi0JCQl2cCA+PiBzd1ZhbHVlOw0KLQ0KLQkJCXN0ckFycmF5LkFkZChzd1ZhbHVlKTsNCi0JCX0NCi0NCi0JCWlmIChtX2JEZWxheSkNCi0JCXsNCi0JCQlBZGREZWxheV9XaWRlU3RyaW5nQXJyYXkoRlBfVkFMVUUsIHN0ckFycmF5KTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlGaWVsZDo6U2V0VmFsdWUobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBzdHJBcnJheSk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLSAJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQ0KLQ0KLQkJc3dpdGNoIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSkNCi0JCXsNCi0JCWNhc2UgRklFTERUWVBFX1BVU0hCVVRUT046DQotCQkJcmV0dXJuIEZBTFNFOw0KLQkJY2FzZSBGSUVMRFRZUEVfQ09NQk9CT1g6DQotCQljYXNlIEZJRUxEVFlQRV9URVhURklFTEQ6DQotCQkJew0KLQkJCQlDRlhfV2lkZVN0cmluZyBzd1ZhbHVlID0gcEZvcm1GaWVsZC0+R2V0VmFsdWUoKTsNCi0NCi0JCQkJZG91YmxlIGRSZXQ7DQotCQkJCUZYX0JPT0wgYkRvdDsNCi0JCQkJaWYgKENKU19QdWJsaWNNZXRob2RzOjpDb252ZXJ0U3RyaW5nVG9OdW1iZXIoc3dWYWx1ZSxkUmV0LGJEb3QpKQ0KLQkJCQl7DQotCQkJCQlpZiAoYkRvdCkNCi0JCQkJCQl2cCA8PCBkUmV0Ow0KLQkJCQkJZWxzZQ0KLQkJCQkJCXZwIDw8IGRSZXQ7DQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQkJdnAgPDwgc3dWYWx1ZTsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIEZJRUxEVFlQRV9MSVNUQk9YOg0KLQkJCXsNCi0JCQkJaWYgKHBGb3JtRmllbGQtPkNvdW50U2VsZWN0ZWRJdGVtcygpID4gMSkNCi0JCQkJew0KLQkJCQkJQ0pTX0FycmF5IFZhbHVlQXJyYXkobV9pc29sYXRlKTsNCi0JCQkJCUNKU19WYWx1ZSBFbGVtZW50VmFsdWUobV9pc29sYXRlKTsNCi0JCQkJCWludCBpSW5kZXg7DQotCQkJCQlmb3IgKGludCBpID0gMCwgc3ogPSBwRm9ybUZpZWxkLT5Db3VudFNlbGVjdGVkSXRlbXMoKTsgaSA8IHN6OyBpKyspDQotCQkJCQl7DQotCQkJCQkJaUluZGV4ID0gcEZvcm1GaWVsZC0+R2V0U2VsZWN0ZWRJbmRleChpKTsNCi0JCQkJCQlFbGVtZW50VmFsdWUgPSBwRm9ybUZpZWxkLT5HZXRPcHRpb25WYWx1ZShpSW5kZXgpOw0KLQkJCQkJCWlmIChGWFNZU193Y3NsZW4oKEZYX0xQQ1dTVFIpRWxlbWVudFZhbHVlLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpID09IDApDQotCQkJCQkJCUVsZW1lbnRWYWx1ZSA9IHBGb3JtRmllbGQtPkdldE9wdGlvbkxhYmVsKGlJbmRleCk7DQotCQkJCQkJVmFsdWVBcnJheS5TZXRFbGVtZW50KGksIEVsZW1lbnRWYWx1ZSk7DQotCQkJCQl9DQotCQkJCQl2cCA8PCBWYWx1ZUFycmF5Ow0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc3dWYWx1ZSA9IHBGb3JtRmllbGQtPkdldFZhbHVlKCk7DQotCQkJCQ0KLQkJCQkJZG91YmxlIGRSZXQ7DQotCQkJCQlGWF9CT09MIGJEb3Q7DQotCQkJCQlpZiAoQ0pTX1B1YmxpY01ldGhvZHM6OkNvbnZlcnRTdHJpbmdUb051bWJlcihzd1ZhbHVlLGRSZXQsYkRvdCkpDQotCQkJCQl7DQotCQkJCQkJaWYgKGJEb3QpDQotCQkJCQkJCXZwIDw8IGRSZXQ7DQotCQkJCQkJZWxzZQ0KLQkJCQkJCQl2cCA8PCBkUmV0Ow0KLQkJCQkJfQ0KLQkJCQkJZWxzZQ0KLQkJCQkJCXZwIDw8IHN3VmFsdWU7CQ0KLQkJCQl9DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBGSUVMRFRZUEVfQ0hFQ0tCT1g6DQotCQljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoNCi0JCQl7DQotCQkJCUZYX0JPT0wgYkZpbmQgPSBGQUxTRTsNCi0JCQkJZm9yIChpbnQgaSA9IDAgLCBzeiA9IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgaSA8IHN6OyBpKyspDQotCQkJCXsNCi0JCQkJCWlmIChwRm9ybUZpZWxkLT5HZXRDb250cm9sKGkpLT5Jc0NoZWNrZWQoKSkNCi0JCQkJCXsNCi0JCQkJCQlDRlhfV2lkZVN0cmluZyBzd1ZhbHVlID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChpKS0+R2V0RXhwb3J0VmFsdWUoKTsNCi0JCQkJCQkNCi0JCQkJCQlkb3VibGUgZFJldDsNCi0JCQkJCQlGWF9CT09MIGJEb3Q7DQotCQkJCQkJaWYgKENKU19QdWJsaWNNZXRob2RzOjpDb252ZXJ0U3RyaW5nVG9OdW1iZXIoc3dWYWx1ZSxkUmV0LGJEb3QpKQ0KLQkJCQkJCXsNCi0JCQkJCQkJaWYgKGJEb3QpDQotCQkJCQkJCQl2cCA8PCBkUmV0Ow0KLQkJCQkJCQllbHNlDQotCQkJCQkJCQl2cCA8PCBkUmV0Ow0KLQkJCQkJCX0NCi0JCQkJCQllbHNlDQotCQkJCQkJCXZwIDw8IHN3VmFsdWU7DQotDQotCQkJCQkJYkZpbmQgPSBUUlVFOw0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJfQ0KLQkJCQkJZWxzZQ0KLQkJCQkJCWNvbnRpbnVlOw0KLQkJCQl9DQotCQkJCWlmICghYkZpbmQpDQotCQkJCQl2cCA8PCAoRlhfTFBDV1NUUilMIk9mZiI7CQkJCQkNCi0JCQl9DQotCQkJYnJlYWs7DQotCQlkZWZhdWx0Og0KLQkJCXZwIDw8IHBGb3JtRmllbGQtPkdldFZhbHVlKCk7DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OlNldFZhbHVlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCANCi0JCQkJCSBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ0pTX1dpZGVTdHJpbmdBcnJheSYgc3RyQXJyYXkpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoc3RyQXJyYXkuR2V0U2l6ZSgpIDwgMSkgcmV0dXJuOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhwRG9jdW1lbnQsIHN3RmllbGROYW1lLCBGaWVsZEFycmF5KTsNCi0NCi0JZm9yIChpbnQgaT0wLGlzej1GaWVsZEFycmF5LkdldFNpemUoKTsgaTxpc3o7IGkrKykNCi0Jew0KLQkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KGkpOw0KLQkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCQlpZiAocEZvcm1GaWVsZC0+R2V0RnVsbE5hbWUoKS5Db21wYXJlKHN3RmllbGROYW1lKSAhPSAwKQ0KLQkJCWNvbnRpbnVlOw0KLQ0KLQkJc3dpdGNoIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSkNCi0JCXsNCi0JCWNhc2UgRklFTERUWVBFX1RFWFRGSUVMRDoNCi0JCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOg0KLQkJCWlmIChwRm9ybUZpZWxkLT5HZXRWYWx1ZSgpICE9IHN0ckFycmF5LkdldEF0KDApKQ0KLQkJCXsNCi0JCQkJQ0ZYX1dpZGVTdHJpbmcgV2lkZVN0cmluZyA9IHN0ckFycmF5LkdldEF0KDApOw0KLQkJCQlwRm9ybUZpZWxkLT5TZXRWYWx1ZShzdHJBcnJheS5HZXRBdCgwKSwgVFJVRSk7CQ0KLQkJCQlVcGRhdGVGb3JtRmllbGQocERvY3VtZW50LCBwRm9ybUZpZWxkLCBUUlVFLCBGQUxTRSwgVFJVRSk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBGSUVMRFRZUEVfQ0hFQ0tCT1g6IC8vbWFudGlzOiAwMDA0NDkzDQotCQljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoNCi0JCQl7DQotCQkJCWlmIChwRm9ybUZpZWxkLT5HZXRWYWx1ZSgpICE9IHN0ckFycmF5LkdldEF0KDApKQ0KLQkJCQl7DQotCQkJCQlwRm9ybUZpZWxkLT5TZXRWYWx1ZShzdHJBcnJheS5HZXRBdCgwKSwgVFJVRSk7CQ0KLQkJCQkJVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgRkFMU0UsIFRSVUUpOw0KLQkJCQl9DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBGSUVMRFRZUEVfTElTVEJPWDoNCi0JCQl7DQotCQkJCUZYX0JPT0wgYk1vZGlmaWVkID0gRkFMU0U7DQotDQotCQkJCWZvciAoaW50IGk9MCxzej1zdHJBcnJheS5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQkJew0KLQkJCQkJaW50IGlJbmRleCA9IHBGb3JtRmllbGQtPkZpbmRPcHRpb24oc3RyQXJyYXkuR2V0QXQoaSkpOw0KLQ0KLQkJCQkJaWYgKCFwRm9ybUZpZWxkLT5Jc0l0ZW1TZWxlY3RlZChpSW5kZXgpKQ0KLQkJCQkJew0KLQkJCQkJCWJNb2RpZmllZCA9IFRSVUU7DQotCQkJCQkJYnJlYWs7DQotCQkJCQl9DQotCQkJCX0NCi0NCi0JCQkJaWYgKGJNb2RpZmllZCkNCi0JCQkJew0KLQkJCQkJcEZvcm1GaWVsZC0+Q2xlYXJTZWxlY3Rpb24oVFJVRSk7DQotCQkJCQlmb3IgKGludCBpPTAsc3o9c3RyQXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQkJCQl7DQotCQkJCQkJaW50IGlJbmRleCA9IHBGb3JtRmllbGQtPkZpbmRPcHRpb24oc3RyQXJyYXkuR2V0QXQoaSkpOw0KLQkJCQkJCXBGb3JtRmllbGQtPlNldEl0ZW1TZWxlY3Rpb24oaUluZGV4LCBUUlVFLCBUUlVFKTsNCi0JCQkJCX0NCi0NCi0JCQkJCVVwZGF0ZUZvcm1GaWVsZChwRG9jdW1lbnQsIHBGb3JtRmllbGQsIFRSVUUsIEZBTFNFLCBUUlVFKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWRlZmF1bHQ6CQkJCQ0KLQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnZhbHVlQXNTdHJpbmcoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIXZwLklzR2V0dGluZygpKSByZXR1cm4gRkFMU0U7DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLSAgIAlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX1BVU0hCVVRUT04pDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfQ0hFQ0tCT1gpDQotCXsNCi0JCWlmKCFwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpIHJldHVybiBGQUxTRTsNCi0NCi0JCWlmIChwRm9ybUZpZWxkLT5HZXRDb250cm9sKDApLT5Jc0NoZWNrZWQoKSkNCi0JCQl2cCA8PCAoRlhfTFBDV1NUUilMIlllcyI7DQotCQllbHNlDQotCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJPZmYiOw0KLQl9DQotCWVsc2UgaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9SQURJT0JVVFRPTiAmJiAhKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19SQURJT1NJTlVOSVNPTikpDQotCXsNCi0JCWZvciAoaW50IGk9MCwgc3o9cEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBpPHN6OyBpKyspDQotCQl7DQotCQkJaWYgKHBGb3JtRmllbGQtPkdldENvbnRyb2woaSktPklzQ2hlY2tlZCgpKQ0KLQkJCXsNCi0JCQkJdnAgPDwgKEZYX0xQQ1dTVFIpcEZvcm1GaWVsZC0+R2V0Q29udHJvbChpKS0+R2V0RXhwb3J0VmFsdWUoKTsNCi0JCQkJYnJlYWs7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJPZmYiOw0KLQkJfQ0KLQl9DQotCWVsc2UgaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9MSVNUQk9YICYmIChwRm9ybUZpZWxkLT5Db3VudFNlbGVjdGVkSXRlbXMoKSA+IDEpKQ0KLQl7DQotCQl2cCA8PCAoRlhfTFBDV1NUUilMIiI7DQotCX0NCi0JZWxzZQ0KLQkJdnAgPDwgKEZYX0xQQ1dTVFIpcEZvcm1GaWVsZC0+R2V0VmFsdWUoKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUZYX0JPT0wgRmllbGQ6OmJyb3dzZUZvckZpbGVUb1N1Ym1pdChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOw0KLQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLSAJQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IG1fcERvY3VtZW50LT5HZXRFbnYoKTsNCi0gCUFTU0VSVChwQXBwICE9IE5VTEwpOw0KLQ0KLQlpZiAoKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19GSUxFU0VMRUNUKSAmJiANCi0JCShwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEKSkNCi0JewkJDQotCQlDRlhfV2lkZVN0cmluZyB3c0ZpbGVOYW1lID0gcEFwcC0+SlNfZmllbGRCcm93c2UoKTsNCi0JCWlmKCF3c0ZpbGVOYW1lLklzRW1wdHkoKSkNCi0JCXsNCi0gCQkJcEZvcm1GaWVsZC0+U2V0VmFsdWUod3NGaWxlTmFtZSk7DQotIAkJCVVwZGF0ZUZvcm1GaWVsZChtX3BEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgVFJVRSwgVFJVRSk7DQotICAgICAgICAgfQ0KLQl9DQotCWVsc2UgDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0NCi1GWF9CT09MIEZpZWxkOjpidXR0b25HZXRDYXB0aW9uKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpbnQgbmZhY2UgPSAwOw0KLQlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOw0KLQlpZiAoIGlTaXplID49IDEpDQotCQluZmFjZSA9IChGWF9JTlQzMikgcGFyYW1zWzBdOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0JDQotCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfUFVTSEJVVFRPTikNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7DQotCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsNCi0JDQotCWlmIChuZmFjZSA9PSAwKQ0KLQkJdlJldCA9IHBGb3JtQ29udHJvbC0+R2V0Tm9ybWFsQ2FwdGlvbigpOw0KLQllbHNlIGlmIChuZmFjZSA9PSAxKQ0KLQkJdlJldCA9IHBGb3JtQ29udHJvbC0+R2V0RG93bkNhcHRpb24oKTsNCi0JZWxzZSBpZiAobmZhY2UgPT0gMikNCi0JCXZSZXQgPSBwRm9ybUNvbnRyb2wtPkdldFJvbGxvdmVyQ2FwdGlvbigpOw0KLQllbHNlDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0vLyNwcmFnbWEgd2FybmluZyhkaXNhYmxlOiA0ODAwKQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmJ1dHRvbkdldEljb24oT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWludCBuZmFjZSA9IDA7DQotCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7DQotCWlmICggaVNpemUgPj0gMSkNCi0JCW5mYWNlID0gKEZYX0lOVDMyKSBwYXJhbXNbMF07DQotCQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0JDQotCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfUFVTSEJVVFRPTikNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7DQotCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0JDQotCUpTRlhPYmplY3QgcE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIkljb24iKSk7DQotCUFTU0VSVChwT2JqLklzRW1wdHkoKSA9PSBGQUxTRSk7DQotCQ0KLQlDSlNfSWNvbiogcEpTX0ljb24gPSAoQ0pTX0ljb24qKUpTX0dldFByaXZhdGUocE9iaik7DQotCUFTU0VSVChwSlNfSWNvbiAhPSBOVUxMKTsNCi0NCi0JSWNvbiogcEljb24gPSAoSWNvbiopcEpTX0ljb24tPkdldEVtYmVkT2JqZWN0KCk7DQotCUFTU0VSVChwSWNvbiAhPSBOVUxMKTsNCi0NCi0JQ1BERl9TdHJlYW0qIHBJY29uU3RyZWFtID0gTlVMTDsNCi0JaWYgKG5mYWNlID09IDApDQotCQlwSWNvblN0cmVhbSA9IHBGb3JtQ29udHJvbC0+R2V0Tm9ybWFsSWNvbigpOw0KLQllbHNlIGlmIChuZmFjZSA9PSAxKQ0KLQkJcEljb25TdHJlYW0gPSBwRm9ybUNvbnRyb2wtPkdldERvd25JY29uKCk7DQotCWVsc2UgaWYgKG5mYWNlID09IDIpDQotCQlwSWNvblN0cmVhbSA9IHBGb3JtQ29udHJvbC0+R2V0Um9sbG92ZXJJY29uKCk7DQotCWVsc2UNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JcEljb24tPlNldFN0cmVhbShwSWNvblN0cmVhbSk7DQotCXZSZXQgPSBwSlNfSWNvbjsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8vI3ByYWdtYSB3YXJuaW5nKGRlZmF1bHQ6IDQ4MDApDQotDQotRlhfQk9PTCBGaWVsZDo6YnV0dG9uSW1wb3J0SWNvbihPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotI2lmIDAgIA0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCWlmICghcEZvcm1GaWVsZClyZXR1cm4gRkFMU0U7DQotDQotCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7DQotCUFTU0VSVChwRW52KTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc0ljb25GaWxlTmFtZSA9IHBFbnYtPkpTX2ZpZWxkQnJvd3NlKCk7DQotCWlmIChzSWNvbkZpbGVOYW1lLklzRW1wdHkoKSkgDQotCXsNCi0JCXZSZXQgPSAxOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gcEludGVyRm9ybS0+TG9hZEltYWdlRnJvbUZpbGUoc0ljb25GaWxlTmFtZSk7DQotCWlmICghcFN0cmVhbSkgDQotCXsNCi0JCXZSZXQgPSAtMTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOw0KLQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7DQotDQotCXBGb3JtQ29udHJvbC0+U2V0Tm9ybWFsSWNvbihwU3RyZWFtKTsNCi0JVXBkYXRlRm9ybUNvbnRyb2wobV9wRG9jdW1lbnQsIHBGb3JtQ29udHJvbCwgVFJVRSwgVFJVRSwgVFJVRSk7DQotDQotCXZSZXQgPSAwOw0KLSNlbmRpZiAvLyAwDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpidXR0b25TZXRDYXB0aW9uKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpidXR0b25TZXRJY29uKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpjaGVja1RoaXNCb3goT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7DQotDQotCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7DQotCWludCBuV2lkZ2V0ID0gLTE7DQotCWlmICggaVNpemUgPj0gMSkNCi0JCW5XaWRnZXQ9IChGWF9JTlQzMikgcGFyYW1zWzBdOw0KLQllbHNlDQotCQlyZXR1cm4gRkFMU0U7DQotCUZYX0JPT0wgYkNoZWNraXQgPSBUUlVFOw0KLQlpZiAoIGlTaXplID49IDIpDQotCQliQ2hlY2tpdCA9IHBhcmFtc1sxXTsNCi0NCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotCQ0KLQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX0NIRUNLQk9YICYmIHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9SQURJT0JVVFRPTikNCi0JCXJldHVybiBGQUxTRTsJDQotCWlmKG5XaWRnZXQgPDAgfHwgbldpZGdldCA+PSBwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpDQotCQlyZXR1cm4gRkFMU0U7DQotCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfUkFESU9CVVRUT04pDQotCQlwRm9ybUZpZWxkLT5DaGVja0NvbnRyb2wobldpZGdldCwgYkNoZWNraXQsIFRSVUUpOw0KLQllbHNlDQotCQlwRm9ybUZpZWxkLT5DaGVja0NvbnRyb2wobldpZGdldCwgYkNoZWNraXQsIFRSVUUpOw0KLQ0KLQlVcGRhdGVGb3JtRmllbGQobV9wRG9jdW1lbnQsIHBGb3JtRmllbGQsIFRSVUUsIFRSVUUsIFRSVUUpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6Y2xlYXJJdGVtcyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpkZWZhdWx0SXNDaGVja2VkKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOw0KLQlpbnQgbldpZGdldCA9IC0xOw0KLQlpZiAoIGlTaXplID49IDEpDQotCQluV2lkZ2V0PSAoRlhfSU5UMzIpIHBhcmFtc1swXTsNCi0JZWxzZQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQkvL0ZYX0JPT0wgYklzRGVmYXVsdENoZWNrZWQgPSBUUlVFOw0KLQkvL2lmICggaVNpemUgPj0gMikNCi0JLy8JYklzRGVmYXVsdENoZWNrZWQgPSAgcGFyYW1zWzFdOw0KLQ0KLQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsNCi0JR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsNCi0JaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOw0KLQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsNCi0NCi0JaWYobldpZGdldCA8MCB8fCBuV2lkZ2V0ID49IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkNCi0Jew0KLQkJdlJldCA9IEZBTFNFOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCWlmICgocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX0NIRUNLQk9YKQ0KLQkJfHwgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9SQURJT0JVVFRPTikpDQotCXsNCi0NCi0JCXZSZXQgPSBUUlVFOw0KLQl9DQotCWVsc2UNCi0JCXZSZXQgPSBGQUxTRTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmRlbGV0ZUl0ZW1BdChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1pbnQgSlNfQ09NUEFSRVNUUklORyhDRlhfV2lkZVN0cmluZyogcHMxLCBDRlhfV2lkZVN0cmluZyogcHMyKQ0KLXsNCi0JQVNTRVJUKHBzMSAhPSBOVUxMKTsNCi0JQVNTRVJUKHBzMiAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIHBzMS0+Q29tcGFyZSgqcHMyKTsNCi19DQotDQotDQotRlhfQk9PTCBGaWVsZDo6Z2V0QXJyYXkoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDR1dfQXJyYXlUZW1wbGF0ZTxDRlhfV2lkZVN0cmluZyo+IHN3U29ydDsNCi0NCi0JZm9yIChpbnQgaT0wLHN6PUZpZWxkQXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdChpKTsNCi0JCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQkJc3dTb3J0LkFkZChuZXcgQ0ZYX1dpZGVTdHJpbmcocEZvcm1GaWVsZC0+R2V0RnVsbE5hbWUoKSkpOw0KLQkJDQotCX0NCi0Jc3dTb3J0LlNvcnQoSlNfQ09NUEFSRVNUUklORyk7DQotDQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCUNKU19BcnJheSBGb3JtRmllbGRBcnJheShtX2lzb2xhdGUpOw0KLQlmb3IgKGludCBqPTAsanN6ID0gc3dTb3J0LkdldFNpemUoKTsgajxqc3o7IGorKykNCi0Jew0KLQkJQ0ZYX1dpZGVTdHJpbmcqIHBTdHIgPSBzd1NvcnQuR2V0QXQoaik7DQotDQotCQlKU0ZYT2JqZWN0IHBPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBwQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJGaWVsZCIpKTsNCi0JCUFTU0VSVChwT2JqLklzRW1wdHkoKSA9PSBGQUxTRSk7DQotDQotCQlDSlNfRmllbGQqIHBKU0ZpZWxkID0gKENKU19GaWVsZCopSlNfR2V0UHJpdmF0ZShwT2JqKTsNCi0JCUFTU0VSVChwSlNGaWVsZCAhPSBOVUxMKTsNCi0NCi0JCUZpZWxkKiBwRmllbGQgPSAoRmllbGQqKXBKU0ZpZWxkLT5HZXRFbWJlZE9iamVjdCgpOyANCi0JCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7DQotDQotCQlwRmllbGQtPkF0dGFjaEZpZWxkKHRoaXMtPm1fcEpTRG9jLCAqcFN0cik7DQotCQ0KLQkJQ0pTX1ZhbHVlIEZvcm1GaWVsZFZhbHVlKG1faXNvbGF0ZSk7DQotCQlGb3JtRmllbGRWYWx1ZSA9IHBKU0ZpZWxkOw0KLQkJRm9ybUZpZWxkQXJyYXkuU2V0RWxlbWVudChqLCBGb3JtRmllbGRWYWx1ZSk7DQotDQotCQlkZWxldGUgcFN0cjsNCi0JfQ0KLQ0KLQl2UmV0ID0gRm9ybUZpZWxkQXJyYXk7DQotCXN3U29ydC5SZW1vdmVBbGwoKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQkNCi1GWF9CT09MIEZpZWxkOjpnZXRJdGVtQXQoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7DQotDQotCWludCBuSWR4ID0gLTE7DQotCWlmIChwYXJhbXMuc2l6ZSgpID49MSkNCi0JCW5JZHggPSAoRlhfSU5UMzIpIHBhcmFtc1swXTsNCi0JRlhfQk9PTCBiRXhwb3J0ID0gVFJVRTsNCi0JaW50IGlTaXplID0gcGFyYW1zLnNpemUoKTsNCi0JaWYgKCBpU2l6ZSA+PSAyKQ0KLQl7DQotCQliRXhwb3J0ID0oRlhfQk9PTCkgcGFyYW1zWzFdOw0KLQl9DQotDQotCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5Ow0KLQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOw0KLQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7DQotCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOw0KLQ0KLQlpZiAoKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9MSVNUQk9YKQ0KLQkJfHwgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9DT01CT0JPWCkpDQotCXsNCi0JCWlmIChuSWR4ID09IC0xIHx8IG5JZHggPiBwRm9ybUZpZWxkLT5Db3VudE9wdGlvbnMoKSkNCi0JCQluSWR4ID0gcEZvcm1GaWVsZC0+Q291bnRPcHRpb25zKCkgLTE7DQotCQlpZiAoYkV4cG9ydCkNCi0JCXsNCi0JCQlDRlhfV2lkZVN0cmluZyBzdHJ2YWwgPSBwRm9ybUZpZWxkLT5HZXRPcHRpb25WYWx1ZShuSWR4KTsNCi0JCQlpZiAoc3RydmFsLklzRW1wdHkoKSkNCi0JCQkJdlJldCA9IHBGb3JtRmllbGQtPkdldE9wdGlvbkxhYmVsKG5JZHgpOw0KLQkJCWVsc2UNCi0JCQkJdlJldCA9IHN0cnZhbDsNCi0JCX0NCi0JCWVsc2UNCi0JCQl2UmV0ID0gcEZvcm1GaWVsZC0+R2V0T3B0aW9uTGFiZWwobklkeCk7DQotCX0NCi0JZWxzZQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6Z2V0TG9jayhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6aW5zZXJ0SXRlbUF0KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OmlzQm94Q2hlY2tlZChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaW50IG5JbmRleCA9IC0xOw0KLQlpZiAocGFyYW1zLnNpemUoKSA+PTEpDQotCQluSW5kZXggPSAoRlhfSU5UMzIpIHBhcmFtc1swXTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCWlmKG5JbmRleCA8MCB8fCBuSW5kZXggPj0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpKQ0KLQl7DQotCQl2UmV0ID0gRkFMU0U7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JaWYgKChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfQ0hFQ0tCT1gpDQotCQl8fCAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX1JBRElPQlVUVE9OKSkNCi0Jew0KLQkJaWYgKHBGb3JtRmllbGQtPkdldENvbnRyb2wobkluZGV4KS0+SXNDaGVja2VkKCkgIT0wICkNCi0JCQl2UmV0ID0gVFJVRTsNCi0JCWVsc2UNCi0JCQl2UmV0ID0gRkFMU0U7DQotCX0NCi0JZWxzZQ0KLQkJdlJldCA9IEZBTFNFOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6aXNEZWZhdWx0Q2hlY2tlZChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JaW50IG5JbmRleCA9IC0xOw0KLQlpZiAocGFyYW1zLnNpemUoKSA+PTEpDQotCQluSW5kZXggPSAoRlhfSU5UMzIpIHBhcmFtc1swXTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCWlmKG5JbmRleCA8MCB8fCBuSW5kZXggPj0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpKQ0KLQl7DQotCQl2UmV0ID0gRkFMU0U7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0JaWYgKChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfQ0hFQ0tCT1gpDQotCQl8fCAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX1JBRElPQlVUVE9OKSkNCi0Jew0KLQkJaWYgKHBGb3JtRmllbGQtPkdldENvbnRyb2wobkluZGV4KS0+SXNEZWZhdWx0Q2hlY2tlZCgpICE9IDApDQotCQkJdlJldCA9IFRSVUU7DQotCQllbHNlDQotCQkJdlJldCA9IEZBTFNFOw0KLQl9DQotCWVsc2UNCi0JCXZSZXQgPSBGQUxTRTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnNldEFjdGlvbihPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpzZXRGb2N1cyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7DQotCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7DQotCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7DQotDQotCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsNCi0JQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7DQotDQotCUZYX0lOVDMyIG5Db3VudCA9IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsNCi0NCi0JaWYgKG5Db3VudCA8IDEpIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gTlVMTDsNCi0JaWYgKG5Db3VudCA9PSAxKQ0KLQl7CQ0KLQkJcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUZpZWxkLT5HZXRDb250cm9sKDApKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7DQotCQlBU1NFUlQocEVudik7DQotCQlDUERGX1BhZ2UqIHBQYWdlID0gKENQREZfUGFnZSopcEVudi0+RkZJX0dldEN1cnJlbnRQYWdlKG1fcERvY3VtZW50LT5HZXREb2N1bWVudCgpKTsNCi0JCWlmKCFwUGFnZSkNCi0JCQlyZXR1cm4gRkFMU0U7DQotCQlpZiAoQ1BERlNES19QYWdlVmlldyogcEN1clBhZ2VWaWV3ID0gbV9wRG9jdW1lbnQtPkdldFBhZ2VWaWV3KHBQYWdlKSkNCi0JCXsNCi0JCQlmb3IgKEZYX0lOVDMyIGk9MDsgaTxuQ291bnQ7IGkrKykNCi0JCQl7DQotCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFRlbXBXaWRnZXQgPSAgcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtRmllbGQtPkdldENvbnRyb2woaSkpKQ0KLQkJCQl7CQkJCQ0KLQkJCQkJaWYgKHBUZW1wV2lkZ2V0LT5HZXRQREZQYWdlKCkgPT0gcEN1clBhZ2VWaWV3LT5HZXRQREZQYWdlKCkpDQotCQkJCQl7DQotCQkJCQkJcFdpZGdldCA9IHBUZW1wV2lkZ2V0Ow0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCWlmIChwV2lkZ2V0KQ0KLQl7DQotCQltX3BEb2N1bWVudC0+U2V0Rm9jdXNBbm5vdChwV2lkZ2V0KTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6c2V0SXRlbXMoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6c2V0TG9jayhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6c2lnbmF0dXJlR2V0TW9kaWZpY2F0aW9ucyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBGaWVsZDo6c2lnbmF0dXJlR2V0U2VlZFZhbHVlKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpzaWduYXR1cmVJbmZvKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpzaWduYXR1cmVTZXRTZWVkVmFsdWUoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnNpZ25hdHVyZVNpZ24oT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgRmllbGQ6OnNpZ25hdHVyZVZhbGlkYXRlKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIEZpZWxkOjpzb3VyY2UoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKHZwLklzR2V0dGluZygpKQ0KLQl7DQotCQl2cCA8PCAoQ0pTX09iamVjdCopTlVMTDsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBkZWxheSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0NCi12b2lkIEZpZWxkOjpBZGREZWxheV9JbnQoZW51bSBGSUVMRF9QUk9QIHByb3AsIEZYX0lOVDMyIG4pDQotew0KLQlBU1NFUlQobV9wSlNEb2MgIT0gTlVMTCk7DQotDQotCUNKU19EZWxheURhdGEqIHBOZXdEYXRhID0gbmV3IENKU19EZWxheURhdGE7DQotCXBOZXdEYXRhLT5zRmllbGROYW1lID0gbV9GaWVsZE5hbWU7DQotCXBOZXdEYXRhLT5uQ29udHJvbEluZGV4ID0gbV9uRm9ybUNvbnRyb2xJbmRleDsNCi0JcE5ld0RhdGEtPmVQcm9wID0gcHJvcDsNCi0JcE5ld0RhdGEtPm51bSA9IG47DQotDQotCW1fcEpTRG9jLT5BZGREZWxheURhdGEocE5ld0RhdGEpOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpBZGREZWxheV9Cb29sKGVudW0gRklFTERfUFJPUCBwcm9wLGJvb2wgYikNCi17DQotCUFTU0VSVChtX3BKU0RvYyAhPSBOVUxMKTsNCi0NCi0JQ0pTX0RlbGF5RGF0YSogcE5ld0RhdGEgPSBuZXcgQ0pTX0RlbGF5RGF0YTsNCi0JcE5ld0RhdGEtPnNGaWVsZE5hbWUgPSBtX0ZpZWxkTmFtZTsNCi0JcE5ld0RhdGEtPm5Db250cm9sSW5kZXggPSBtX25Gb3JtQ29udHJvbEluZGV4Ow0KLQlwTmV3RGF0YS0+ZVByb3AgPSBwcm9wOw0KLQlwTmV3RGF0YS0+YiA9IGI7DQotDQotCW1fcEpTRG9jLT5BZGREZWxheURhdGEocE5ld0RhdGEpOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpBZGREZWxheV9TdHJpbmcoZW51bSBGSUVMRF9QUk9QIHByb3AsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpDQotew0KLQlBU1NFUlQobV9wSlNEb2MgIT0gTlVMTCk7DQotDQotCUNKU19EZWxheURhdGEqIHBOZXdEYXRhID0gbmV3IENKU19EZWxheURhdGE7DQotCXBOZXdEYXRhLT5zRmllbGROYW1lID0gbV9GaWVsZE5hbWU7DQotCXBOZXdEYXRhLT5uQ29udHJvbEluZGV4ID0gbV9uRm9ybUNvbnRyb2xJbmRleDsNCi0JcE5ld0RhdGEtPmVQcm9wID0gcHJvcDsNCi0JcE5ld0RhdGEtPnN0cmluZyA9IHN0cmluZzsNCi0NCi0JbV9wSlNEb2MtPkFkZERlbGF5RGF0YShwTmV3RGF0YSk7DQotfQ0KLQ0KLXZvaWQgRmllbGQ6OkFkZERlbGF5X1dpZGVTdHJpbmcoZW51bSBGSUVMRF9QUk9QIHByb3AsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpDQotew0KLQlBU1NFUlQobV9wSlNEb2MgIT0gTlVMTCk7DQotDQotCUNKU19EZWxheURhdGEqIHBOZXdEYXRhID0gbmV3IENKU19EZWxheURhdGE7DQotCXBOZXdEYXRhLT5zRmllbGROYW1lID0gbV9GaWVsZE5hbWU7DQotCXBOZXdEYXRhLT5uQ29udHJvbEluZGV4ID0gbV9uRm9ybUNvbnRyb2xJbmRleDsNCi0JcE5ld0RhdGEtPmVQcm9wID0gcHJvcDsNCi0JcE5ld0RhdGEtPndpZGVzdHJpbmcgPSBzdHJpbmc7DQotDQotCW1fcEpTRG9jLT5BZGREZWxheURhdGEocE5ld0RhdGEpOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpBZGREZWxheV9SZWN0KGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDUERGX1JlY3QmIHJlY3QpDQotew0KLQlBU1NFUlQobV9wSlNEb2MgIT0gTlVMTCk7DQotDQotCUNKU19EZWxheURhdGEqIHBOZXdEYXRhID0gbmV3IENKU19EZWxheURhdGE7DQotCXBOZXdEYXRhLT5zRmllbGROYW1lID0gbV9GaWVsZE5hbWU7DQotCXBOZXdEYXRhLT5uQ29udHJvbEluZGV4ID0gbV9uRm9ybUNvbnRyb2xJbmRleDsNCi0JcE5ld0RhdGEtPmVQcm9wID0gcHJvcDsNCi0JcE5ld0RhdGEtPnJlY3QgPSByZWN0Ow0KLQ0KLQltX3BKU0RvYy0+QWRkRGVsYXlEYXRhKHBOZXdEYXRhKTsNCi19DQotDQotdm9pZCBGaWVsZDo6QWRkRGVsYXlfQ29sb3IoZW51bSBGSUVMRF9QUk9QIHByb3AsIGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQ0KLXsNCi0JQVNTRVJUKG1fcEpTRG9jICE9IE5VTEwpOw0KLQ0KLQlDSlNfRGVsYXlEYXRhKiBwTmV3RGF0YSA9IG5ldyBDSlNfRGVsYXlEYXRhOw0KLQlwTmV3RGF0YS0+c0ZpZWxkTmFtZSA9IG1fRmllbGROYW1lOw0KLQlwTmV3RGF0YS0+bkNvbnRyb2xJbmRleCA9IG1fbkZvcm1Db250cm9sSW5kZXg7DQotCXBOZXdEYXRhLT5lUHJvcCA9IHByb3A7DQotCXBOZXdEYXRhLT5jb2xvciA9IGNvbG9yOw0KLQ0KLQltX3BKU0RvYy0+QWRkRGVsYXlEYXRhKHBOZXdEYXRhKTsNCi19DQotDQotdm9pZCBGaWVsZDo6QWRkRGVsYXlfV29yZEFycmF5KGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDRlhfRFdvcmRBcnJheSYgYXJyYXkpDQotew0KLQlBU1NFUlQobV9wSlNEb2MgIT0gTlVMTCk7DQotDQotCUNKU19EZWxheURhdGEqIHBOZXdEYXRhID0gbmV3IENKU19EZWxheURhdGE7DQotCXBOZXdEYXRhLT5zRmllbGROYW1lID0gbV9GaWVsZE5hbWU7DQotCXBOZXdEYXRhLT5uQ29udHJvbEluZGV4ID0gbV9uRm9ybUNvbnRyb2xJbmRleDsNCi0JcE5ld0RhdGEtPmVQcm9wID0gcHJvcDsNCi0NCi0JZm9yIChpbnQgaT0wLHN6PWFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJcE5ld0RhdGEtPndvcmRhcnJheS5BZGQoYXJyYXkuR2V0QXQoaSkpOw0KLQ0KLQltX3BKU0RvYy0+QWRkRGVsYXlEYXRhKHBOZXdEYXRhKTsNCi19DQotDQotdm9pZCBGaWVsZDo6QWRkRGVsYXlfV2lkZVN0cmluZ0FycmF5KGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDSlNfV2lkZVN0cmluZ0FycmF5JiBhcnJheSkNCi17DQotCUFTU0VSVChtX3BKU0RvYyAhPSBOVUxMKTsNCi0NCi0JQ0pTX0RlbGF5RGF0YSogcE5ld0RhdGEgPSBuZXcgQ0pTX0RlbGF5RGF0YTsNCi0JcE5ld0RhdGEtPnNGaWVsZE5hbWUgPSBtX0ZpZWxkTmFtZTsNCi0JcE5ld0RhdGEtPm5Db250cm9sSW5kZXggPSBtX25Gb3JtQ29udHJvbEluZGV4Ow0KLQlwTmV3RGF0YS0+ZVByb3AgPSBwcm9wOw0KLQlmb3IgKGludCBpPTAsc3o9YXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQlwTmV3RGF0YS0+d2lkZXN0cmluZ2FycmF5LkFkZChhcnJheS5HZXRBdChpKSk7DQotDQotCW1fcEpTRG9jLT5BZGREZWxheURhdGEocE5ld0RhdGEpOw0KLX0NCi0NCi12b2lkIEZpZWxkOjpEb0RlbGF5KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ0pTX0RlbGF5RGF0YSogcERhdGEpDQotew0KLQlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOw0KLQlBU1NFUlQocERhdGEgIT0gTlVMTCk7DQotDQotCXN3aXRjaCAocERhdGEtPmVQcm9wKQ0KLQl7DQotCWNhc2UgRlBfQUxJR05NRU5UOg0KLQkJRmllbGQ6OlNldEFsaWdubWVudChwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPnN0cmluZyk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9CT1JERVJTVFlMRToNCi0JCUZpZWxkOjpTZXRCb3JkZXJTdHlsZShwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPnN0cmluZyk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9CVVRUT05BTElHTlg6DQotCQlGaWVsZDo6U2V0QnV0dG9uQWxpZ25YKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+bnVtKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX0JVVFRPTkFMSUdOWToNCi0JCUZpZWxkOjpTZXRCdXR0b25BbGlnblkocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5udW0pOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfQlVUVE9ORklUQk9VTkRTOg0KLQkJRmllbGQ6OlNldEJ1dHRvbkZpdEJvdW5kcyhwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmIpOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfQlVUVE9OUE9TSVRJT046DQotCQlGaWVsZDo6U2V0QnV0dG9uUG9zaXRpb24ocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5udW0pOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfQlVUVE9OU0NBTEVIT1c6DQotCQlGaWVsZDo6U2V0QnV0dG9uU2NhbGVIb3cocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5udW0pOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfQlVUVE9OU0NBTEVXSEVOOg0KLQkJRmllbGQ6OlNldEJ1dHRvblNjYWxlV2hlbihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9DQUxDT1JERVJJTkRFWDoNCi0JCUZpZWxkOjpTZXRDYWxjT3JkZXJJbmRleChwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9DSEFSTElNSVQ6DQotCQlGaWVsZDo6U2V0Q2hhckxpbWl0KHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+bnVtKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX0NPTUI6DQotCQlGaWVsZDo6U2V0Q29tYihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmIpOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfQ09NTUlUT05TRUxDSEFOR0U6DQotCQlGaWVsZDo6U2V0Q29tbWl0T25TZWxDaGFuZ2UocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5iKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX0NVUlJFTlRWQUxVRUlORElDRVM6DQotCQlGaWVsZDo6U2V0Q3VycmVudFZhbHVlSW5kaWNlcyhwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPndvcmRhcnJheSk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9ERUZBVUxUVkFMVUU6DQotCQlGaWVsZDo6U2V0RGVmYXVsdFZhbHVlKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+d2lkZXN0cmluZyk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9ET05PVFNDUk9MTDoNCi0JCUZpZWxkOjpTZXREb05vdFNjcm9sbChwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmIpOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfRElTUExBWToNCi0JCUZpZWxkOjpTZXREaXNwbGF5KHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+bnVtKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX0ZJTExDT0xPUjoNCi0JCUZpZWxkOjpTZXRGaWxsQ29sb3IocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5jb2xvcik7DQotCQlicmVhazsNCi0JY2FzZSBGUF9ISURERU46DQotCQlGaWVsZDo6U2V0SGlkZGVuKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+Yik7DQotCQlicmVhazsNCi0JY2FzZSBGUF9ISUdITElHSFQ6DQotCQlGaWVsZDo6U2V0SGlnaGxpZ2h0KHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+c3RyaW5nKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX0xJTkVXSURUSDoNCi0JCUZpZWxkOjpTZXRMaW5lV2lkdGgocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5udW0pOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfTVVMVElMSU5FOg0KLQkJRmllbGQ6OlNldE11bHRpbGluZShwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmIpOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfTVVMVElQTEVTRUxFQ1RJT046DQotCQlGaWVsZDo6U2V0TXVsdGlwbGVTZWxlY3Rpb24ocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5iKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX1BBU1NXT1JEOg0KLQkJRmllbGQ6OlNldFBhc3N3b3JkKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+Yik7DQotCQlicmVhazsNCi0JY2FzZSBGUF9SRUNUOg0KLQkJRmllbGQ6OlNldFJlY3QocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5yZWN0KTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX1JJQ0hURVhUOg0KLQkJRmllbGQ6OlNldFJpY2hUZXh0KHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+Yik7DQotCQlicmVhazsNCi0JY2FzZSBGUF9SSUNIVkFMVUU6DQotCQlicmVhazsNCi0JY2FzZSBGUF9ST1RBVElPTjoNCi0JCUZpZWxkOjpTZXRSb3RhdGlvbihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9TVFJPS0VDT0xPUjoNCi0JCUZpZWxkOjpTZXRTdHJva2VDb2xvcihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmNvbG9yKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX1NUWUxFOg0KLQkJRmllbGQ6OlNldFN0eWxlKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+c3RyaW5nKTsNCi0JCWJyZWFrOw0KLQljYXNlIEZQX1RFWFRDT0xPUjoNCi0JCUZpZWxkOjpTZXRUZXh0Q29sb3IocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5jb2xvcik7DQotCQlicmVhazsNCi0JY2FzZSBGUF9URVhURk9OVDoNCi0JCUZpZWxkOjpTZXRUZXh0Rm9udChwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPnN0cmluZyk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9URVhUU0laRToNCi0JCUZpZWxkOjpTZXRUZXh0U2l6ZShwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7DQotCQlicmVhazsNCi0JY2FzZSBGUF9VU0VSTkFNRToNCi0JCUZpZWxkOjpTZXRVc2VyTmFtZShwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPndpZGVzdHJpbmcpOw0KLQkJYnJlYWs7DQotCWNhc2UgRlBfVkFMVUU6DQotCQlGaWVsZDo6U2V0VmFsdWUocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT53aWRlc3RyaW5nYXJyYXkpOw0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotI2RlZmluZSBKU19GSUVMRF9NSU5XSURUSAkxDQotI2RlZmluZSBKU19GSUVMRF9NSU5IRUlHSFQJMQ0KLQ0KLXZvaWQgRmllbGQ6OkFkZEZpZWxkKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgaW50IG5QYWdlSW5kZXgsIGludCBuRmllbGRUeXBlLA0KLQkJCQkJCQljb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUsIGNvbnN0IENQREZfUmVjdCYgcmNDb29yZHMpDQotew0KLQkvL05vdCBzdXBwb3J0ZWQuDQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0ZpZWxkLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIgorLy8jaW5jbHVkZSAiLi4vaW5jbHVkZS9KU19SZXNNZ3IuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19SdW50aW1lLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2NvbG9yLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSWNvbi5oIgorCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmllbGQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitCRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX0ZpZWxkKQorRU5EX0pTX1NUQVRJQ19DT05TVCgpCisKK0JFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19GaWVsZCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShhbGlnbm1lbnQpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoYm9yZGVyU3R5bGUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoYnV0dG9uQWxpZ25YKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGJ1dHRvbkFsaWduWSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShidXR0b25GaXRCb3VuZHMpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoYnV0dG9uUG9zaXRpb24pCisJSlNfU1RBVElDX1BST1BfRU5UUlkoYnV0dG9uU2NhbGVIb3cpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoYnV0dG9uU2NhbGVXaGVuKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGNhbGNPcmRlckluZGV4KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGNoYXJMaW1pdCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShjb21iKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGNvbW1pdE9uU2VsQ2hhbmdlKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGN1cnJlbnRWYWx1ZUluZGljZXMpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZGVmYXVsdFN0eWxlKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGRlZmF1bHRWYWx1ZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShkb05vdFNjcm9sbCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShkb05vdFNwZWxsQ2hlY2spCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZGVsYXkpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZGlzcGxheSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShkb2MpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZWRpdGFibGUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZXhwb3J0VmFsdWVzKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGhpZGRlbikKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShmaWxlU2VsZWN0KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGZpbGxDb2xvcikKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShsaW5lV2lkdGgpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoaGlnaGxpZ2h0KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG11bHRpbGluZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShtdWx0aXBsZVNlbGVjdGlvbikKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShuYW1lKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG51bUl0ZW1zKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHBhZ2UpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocGFzc3dvcmQpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocHJpbnQpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocmFkaW9zSW5Vbmlzb24pCisJSlNfU1RBVElDX1BST1BfRU5UUlkocmVhZG9ubHkpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocmVjdCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShyZXF1aXJlZCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShyaWNoVGV4dCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShyaWNoVmFsdWUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocm90YXRpb24pCisJSlNfU1RBVElDX1BST1BfRU5UUlkoc3Ryb2tlQ29sb3IpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoc3R5bGUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoc3VibWl0TmFtZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh0ZXh0Q29sb3IpCisJSlNfU1RBVElDX1BST1BfRU5UUlkodGV4dEZvbnQpCisJSlNfU1RBVElDX1BST1BfRU5UUlkodGV4dFNpemUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkodHlwZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh1c2VyTmFtZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh2YWx1ZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh2YWx1ZUFzU3RyaW5nKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHNvdXJjZSkKK0VORF9KU19TVEFUSUNfUFJPUCgpCisKK0JFR0lOX0pTX1NUQVRJQ19NRVRIT0QoQ0pTX0ZpZWxkKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYnJvd3NlRm9yRmlsZVRvU3VibWl0LCAgICAgIDApCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShidXR0b25HZXRDYXB0aW9uLCAgICAgICAgICAgMSkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJ1dHRvbkdldEljb24sICAgICAgICAgICAgICAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYnV0dG9uSW1wb3J0SWNvbiwgICAgICAgICAgIDApCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShidXR0b25TZXRDYXB0aW9uLCAgICAgICAgICAgMikKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJ1dHRvblNldEljb24sICAgICAgICAgICAgICAyKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoY2hlY2tUaGlzQm94LCAgICAgICAgICAgICAgIDIpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShjbGVhckl0ZW1zLCAgICAgICAgICAgICAgICAgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGRlZmF1bHRJc0NoZWNrZWQsICAgICAgICAgICAyKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZGVsZXRlSXRlbUF0LCAgICAgICAgICAgICAgIDEpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShnZXRBcnJheSAsICAgICAgICAgICAgICAgICAgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdldEl0ZW1BdCwgICAgICAgICAgICAgICAgICAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZ2V0TG9jaywgICAgICAgICAgICAgICAgICAgIDApCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShpbnNlcnRJdGVtQXQsICAgICAgICAgICAgICAgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGlzQm94Q2hlY2tlZCwgICAgICAgICAgICAgICAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoaXNEZWZhdWx0Q2hlY2tlZCwgICAgICAgICAgIDEpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzZXRBY3Rpb24sICAgICAgICAgICAgICAgICAgMikKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNldEZvY3VzLCAgICAgICAgICAgICAgICAgICAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoc2V0SXRlbXMsICAgICAgICAgICAgICAgICAgIDEpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzZXRMb2NrLCAgICAgICAgICAgICAgICAgICAgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNpZ25hdHVyZUdldE1vZGlmaWNhdGlvbnMsICAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoc2lnbmF0dXJlR2V0U2VlZFZhbHVlLCAgICAgIDApCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzaWduYXR1cmVJbmZvLCAgICAgICAgICAgICAgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNpZ25hdHVyZVNldFNlZWRWYWx1ZSwgICAgICAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoc2lnbmF0dXJlU2lnbiwgICAgICAgICAgICAgIDApCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzaWduYXR1cmVWYWxpZGF0ZSwgICAgICAgICAgMCkKK0VORF9KU19TVEFUSUNfTUVUSE9EKCkKKworSU1QTEVNRU5UX0pTX0NMQVNTKENKU19GaWVsZCwgRmllbGQpCisKK0ZYX0JPT0wJQ0pTX0ZpZWxkOjpJbml0SW5zdGFuY2UoSUZYSlNfQ29udGV4dCogY2MpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwlGaWVsZCogcEZpZWxkID0gKEZpZWxkKilHZXRFbWJlZE9iamVjdCgpOworCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwlwRmllbGQtPlNldElzb2xhdGUocENvbnRleHQtPkdldEpTUnVudGltZSgpLT5HZXRJc29sYXRlKCkpOworCisJcmV0dXJuIFRSVUU7Cit9OworCitGaWVsZDo6RmllbGQoQ0pTX09iamVjdCogcEpTT2JqZWN0KTogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCksCisJbV9wSlNEb2MoTlVMTCksCisJbV9wRG9jdW1lbnQoTlVMTCksCisJbV9uRm9ybUNvbnRyb2xJbmRleCgtMSksCisJbV9iQ2FuU2V0KEZBTFNFKSwKKwltX2JEZWxheShGQUxTRSksCisJbV9pc29sYXRlKE5VTEwpCit7Cit9CisKK0ZpZWxkOjp+RmllbGQoKQoreworfQorCisvL25vdGU6IGlDb250cm9sTm8gPSAtMSwgbWVhbnMgbm90IGEgd2lkZ2V0Lgordm9pZCBGaWVsZDo6UGFyc2VGaWVsZE5hbWUoY29uc3Qgc3RkOjp3c3RyaW5nICZzdHJGaWVsZE5hbWVQYXJzZWQsc3RkOjp3c3RyaW5nICZzdHJGaWVsZE5hbWUsaW50ICYgaUNvbnRyb2xObykKK3sKKwlpbnQgaVN0YXJ0ID0gc3RyRmllbGROYW1lUGFyc2VkLmZpbmRfbGFzdF9vZihMJy4nKTsKKwlpZiAoaVN0YXJ0ID09IC0xKQorCXsKKwkJc3RyRmllbGROYW1lID0gc3RyRmllbGROYW1lUGFyc2VkOworCQlpQ29udHJvbE5vID0gLTE7CisJCXJldHVybjsKKwl9CisJc3RkOjp3c3RyaW5nIHN1ZmZpeGFsID0gc3RyRmllbGROYW1lUGFyc2VkLnN1YnN0cihpU3RhcnQrMSk7CisJaUNvbnRyb2xObyA9IEZYU1lTX3d0b2koKEZYX0xQQ1dTVFIpc3VmZml4YWwuY19zdHIoKSk7CisJaWYgKGlDb250cm9sTm8gPT0gMCkKKwl7CisJCWludCBpU3RhcnQ7CisJCXdoaWxlKChpU3RhcnQgPSBzdWZmaXhhbC5maW5kX2xhc3Rfb2YoTCIgIikpICE9IC0xKQorCQl7CisJCQlzdWZmaXhhbC5lcmFzZShpU3RhcnQsMSk7CisJCX0KKworCQlpZiAoc3VmZml4YWwuY29tcGFyZShMIjAiKSAhPSAwKQorCQl7CisJCQlzdHJGaWVsZE5hbWUgPSBzdHJGaWVsZE5hbWVQYXJzZWQ7CisJCQlpQ29udHJvbE5vID0gLTE7CisJCQlyZXR1cm47CisJCX0KKworCX0KKwlzdHJGaWVsZE5hbWUgPSBzdHJGaWVsZE5hbWVQYXJzZWQuc3Vic3RyKDAsaVN0YXJ0KTsgICAgCit9CisKK0ZYX0JPT0wgRmllbGQ6OkF0dGFjaEZpZWxkKERvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBjc0ZpZWxkTmFtZSkKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCW1fcEpTRG9jID0gcERvY3VtZW50OworCisJbV9wRG9jdW1lbnQgPSBwRG9jdW1lbnQtPkdldFJlYWRlckRvYygpOworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCW1fYkNhblNldCA9IG1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9GSUxMX0ZPUk0pIHx8IAorCQltX3BEb2N1bWVudC0+R2V0UGVybWlzc2lvbnMoRlBERlBFUk1fQU5OT1RfRk9STSkgfHwgCisJCW1fcERvY3VtZW50LT5HZXRQZXJtaXNzaW9ucyhGUERGUEVSTV9NT0RJRlkpOworCisJQ1BERlNES19JbnRlckZvcm0qIHBSREludGVyRm9ybSA9IG1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocFJESW50ZXJGb3JtICE9IE5VTEwpOworCisJQ1BERl9JbnRlckZvcm0qIHBJbnRlckZvcm0gPSBwUkRJbnRlckZvcm0tPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ0ZYX1dpZGVTdHJpbmcgc3dGaWVsZE5hbWVUZW1wID0gY3NGaWVsZE5hbWU7CisJc3dGaWVsZE5hbWVUZW1wLlJlcGxhY2UoKEZYX0xQQ1dTVFIpTCIuLiIsIChGWF9MUENXU1RSKUwiLiIpOworCisJaWYgKHBJbnRlckZvcm0tPkNvdW50RmllbGRzKHN3RmllbGROYW1lVGVtcCkgPD0gMCkKKwl7CisJCXN0ZDo6d3N0cmluZyBzdHJGaWVsZE5hbWU7CisJCWludCBpQ29udHJvbE5vID0gLTE7CisJCVBhcnNlRmllbGROYW1lKCh3Y2hhcl90KikoRlhfTFBDV1NUUilzd0ZpZWxkTmFtZVRlbXAsIHN0ckZpZWxkTmFtZSwgaUNvbnRyb2xObyk7CisJCWlmIChpQ29udHJvbE5vID09IC0xKSByZXR1cm4gRkFMU0U7CisJCQorCQltX0ZpZWxkTmFtZSA9IHN0ckZpZWxkTmFtZS5jX3N0cigpOworCQltX25Gb3JtQ29udHJvbEluZGV4ID0gaUNvbnRyb2xObzsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJbV9GaWVsZE5hbWUgPSBzd0ZpZWxkTmFtZVRlbXA7CisJbV9uRm9ybUNvbnRyb2xJbmRleCA9IC0xOworCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OkdldEZvcm1GaWVsZHMoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgY3NGaWVsZE5hbWUsIENGWF9QdHJBcnJheSYgRmllbGRBcnJheSkKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJQ1BERlNES19JbnRlckZvcm0qIHBSZWFkZXJJbnRlckZvcm0gPSBwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwUmVhZGVySW50ZXJGb3JtICE9IE5VTEwpOworCisJQ1BERl9JbnRlckZvcm0qIHBJbnRlckZvcm0gPSBwUmVhZGVySW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCUFTU0VSVChGaWVsZEFycmF5LkdldFNpemUoKSA9PSAwKTsKKworCWZvciAoaW50IGk9MCxzej1wSW50ZXJGb3JtLT5Db3VudEZpZWxkcyhjc0ZpZWxkTmFtZSk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IHBJbnRlckZvcm0tPkdldEZpZWxkKGksIGNzRmllbGROYW1lKSkKKwkJCUZpZWxkQXJyYXkuQWRkKCh2b2lkKilwRm9ybUZpZWxkKTsKKwl9Cit9CisKK3ZvaWQgRmllbGQ6OkdldEZvcm1GaWVsZHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIGNzRmllbGROYW1lLCBDRlhfUHRyQXJyYXkmIEZpZWxkQXJyYXkpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJRmllbGQ6OkdldEZvcm1GaWVsZHMobV9wRG9jdW1lbnQsIGNzRmllbGROYW1lLCBGaWVsZEFycmF5KTsKK30KKwordm9pZCBGaWVsZDo6VXBkYXRlRm9ybUZpZWxkKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIAorCQkJCQkJCUZYX0JPT0wgYkNoYW5nZU1hcmssIEZYX0JPT0wgYlJlc2V0QVAsIEZYX0JPT0wgYlJlZnJlc2gpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ0ZYX1B0ckFycmF5IHdpZGdldHM7CisJcEludGVyRm9ybS0+R2V0V2lkZ2V0cyhwRm9ybUZpZWxkLCB3aWRnZXRzKTsKKworCWlmIChiUmVzZXRBUCkKKwl7CisJCWludCBuRmllbGRUeXBlID0gcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCk7CisJCWlmIChuRmllbGRUeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCB8fCBuRmllbGRUeXBlID09IEZJRUxEVFlQRV9URVhURklFTEQpCisJCXsKKwkJCWZvciAoaW50IGk9MCxzej13aWRnZXRzLkdldFNpemUoKTsgaTxzejsgaSsrKQorCQkJeworCQkJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gKENQREZTREtfV2lkZ2V0Kil3aWRnZXRzLkdldEF0KGkpOworCQkJCUFTU0VSVChwV2lkZ2V0ICE9IE5VTEwpOworCisJCQkJRlhfQk9PTCBiRm9ybWF0ZWQgPSBGQUxTRTsKKwkJCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwV2lkZ2V0LT5PbkZvcm1hdCgwLCBiRm9ybWF0ZWQpOworCQkJCWlmIChiRm9ybWF0ZWQpCisJCQkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShzVmFsdWUsIEZBTFNFKTsKKwkJCQllbHNlCisJCQkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShOVUxMLCBGQUxTRSk7CisJCQl9CisJCX0KKwkJZWxzZQorCQl7CisJCQlmb3IgKGludCBpPTAsc3o9d2lkZ2V0cy5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJCXsKKwkJCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopd2lkZ2V0cy5HZXRBdChpKTsKKwkJCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsKKworCQkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShOVUxMLCBGQUxTRSk7CisJCQl9CisJCX0KKwl9CisKKwlpZiAoYlJlZnJlc2gpCisJeworCQlmb3IgKGludCBpPTAsc3o9d2lkZ2V0cy5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJeworCQkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSAoQ1BERlNES19XaWRnZXQqKXdpZGdldHMuR2V0QXQoaSk7CisJCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsKKwkJCQorCQkJQ1BERlNES19JbnRlckZvcm0gKiBwSW50ZXJGb3JtID0gcFdpZGdldC0+R2V0SW50ZXJGb3JtKCk7CisJCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jID0gcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKTsKKy8vIAkJCUNSZWFkZXJfUGFnZSogcFBhZ2UgPSBwV2lkZ2V0LT5HZXRQYWdlKCk7CisgCQkJQVNTRVJUKHBEb2MgIT0gTlVMTCk7CisJCQlwRG9jLT5VcGRhdGVBbGxWaWV3cyhOVUxMLCBwV2lkZ2V0KTsKKwkJfQorCX0JCQorCQorCWlmIChiQ2hhbmdlTWFyaykKKwkJcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7Cit9CisKK3ZvaWQgRmllbGQ6OlVwZGF0ZUZvcm1Db250cm9sKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sLCAKKwkJCQkJCQlGWF9CT09MIGJDaGFuZ2VNYXJrLCBGWF9CT09MIGJSZXNldEFQLCBGWF9CT09MIGJSZWZyZXNoKQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisJQVNTRVJUKHBGb3JtQ29udHJvbCAhPSBOVUxMKTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1Db250cm9sKTsKKwkKKwlpZiAocFdpZGdldCkKKwl7CisJCWlmIChiUmVzZXRBUCkKKwkJeworCQkJaW50IG5GaWVsZFR5cGUgPSBwV2lkZ2V0LT5HZXRGaWVsZFR5cGUoKTsKKwkJCWlmIChuRmllbGRUeXBlID09IEZJRUxEVFlQRV9DT01CT0JPWCB8fCBuRmllbGRUeXBlID09IEZJRUxEVFlQRV9URVhURklFTEQpCisJCQl7CisJCQkJRlhfQk9PTCBiRm9ybWF0ZWQgPSBGQUxTRTsKKwkJCQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwV2lkZ2V0LT5PbkZvcm1hdCgwLCBiRm9ybWF0ZWQpOworCQkJCWlmIChiRm9ybWF0ZWQpCisJCQkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShzVmFsdWUsIEZBTFNFKTsKKwkJCQllbHNlCisJCQkJCXBXaWRnZXQtPlJlc2V0QXBwZWFyYW5jZShOVUxMLCBGQUxTRSk7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJcFdpZGdldC0+UmVzZXRBcHBlYXJhbmNlKE5VTEwsIEZBTFNFKTsKKwkJCX0KKwkJfQorCisJCWlmIChiUmVmcmVzaCkKKwkJeworCQkJQ1BERlNES19JbnRlckZvcm0gKiBwSW50ZXJGb3JtID0gcFdpZGdldC0+R2V0SW50ZXJGb3JtKCk7CisJCQlDUERGU0RLX0RvY3VtZW50KiBwRG9jID0gcEludGVyRm9ybS0+R2V0RG9jdW1lbnQoKTsKKwkJCUFTU0VSVChwRG9jICE9IE5VTEwpOworCQkJcERvYy0+VXBkYXRlQWxsVmlld3MoTlVMTCwgcFdpZGdldCk7CisJCX0KKworCX0KKworCWlmIChiQ2hhbmdlTWFyaykKKwkJcERvY3VtZW50LT5TZXRDaGFuZ2VNYXJrKCk7Cit9CisKK0NQREZTREtfV2lkZ2V0KiBGaWVsZDo6R2V0V2lkZ2V0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sKQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisJQVNTRVJUKHBGb3JtQ29udHJvbCAhPSBOVUxMKTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJcmV0dXJuIHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpOworfQorCitGWF9CT09MIEZpZWxkOjpWYWx1ZUlzT2NjdXIoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQsIENGWF9XaWRlU3RyaW5nIGNzT3B0TGFiZWwpCit7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwlmb3IgKGludCBpPTAsc3ogPSBwRm9ybUZpZWxkLT5Db3VudE9wdGlvbnMoKTsgaSA8IHN6OyBpKyspCisJeworCQlpZiAoY3NPcHRMYWJlbC5Db21wYXJlKHBGb3JtRmllbGQtPkdldE9wdGlvbkxhYmVsKGkpKSA9PSAwKQorCQkJcmV0dXJuIFRSVUU7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCitDUERGX0Zvcm1Db250cm9sKiBGaWVsZDo6R2V0U21hcnRGaWVsZENvbnRyb2woQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQpCit7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisJaWYoIXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSB8fCBtX25Gb3JtQ29udHJvbEluZGV4Pj1wRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpIHJldHVybiBOVUxMOworCisJaWYgKG1fbkZvcm1Db250cm9sSW5kZXg8MCkKKwkJcmV0dXJuIHBGb3JtRmllbGQtPkdldENvbnRyb2woMCk7CisJZWxzZQorCQlyZXR1cm4gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChtX25Gb3JtQ29udHJvbEluZGV4KTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBwcm9wZXJ0eSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0ZYX0JPT0wgRmllbGQ6OmFsaWdubWVudChPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlDRlhfQnl0ZVN0cmluZyBhbGlnblN0cjsKKwkJdnAgPj4gYWxpZ25TdHI7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9TdHJpbmcoRlBfQUxJR05NRU5ULCBhbGlnblN0cik7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0QWxpZ25tZW50KG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYWxpZ25TdHIpOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfVEVYVEZJRUxEKQorCQkJcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7CisKKwkJc3dpdGNoIChwRm9ybUNvbnRyb2wtPkdldENvbnRyb2xBbGlnbm1lbnQoKSkKKwkJeworCQkJY2FzZSAxOgorCQkJCXZwIDw8IChGWF9MUENXU1RSKUwiY2VudGVyIjsKKwkJCQlicmVhazsKKwkJCWNhc2UgMDoKKwkJCQl2cCA8PCAoRlhfTFBDV1NUUilMImxlZnQiOworCQkJCWJyZWFrOworCQkJY2FzZSAyOgorCQkJCXZwIDw8IChGWF9MUENXU1RSKUwicmlnaHQiOworCQkJCWJyZWFrOworCQkJZGVmYXVsdDoKKwkJCQl2cCA8PCAoRlhfTFBDV1NUUilMIiI7CisJCX0KKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0QWxpZ25tZW50KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgCisJCQkJCQkgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0cmluZykKK3sKKwkvL05vdCBzdXBwb3J0ZWQuCit9CisKK0ZYX0JPT0wgRmllbGQ6OmJvcmRlclN0eWxlKE9CSl9QUk9QX1BBUkFNUykKK3sJCisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlDRlhfQnl0ZVN0cmluZyBzdHJUeXBlID0gIiI7CisJCXZwID4+IHN0clR5cGU7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9TdHJpbmcoRlBfQk9SREVSU1RZTEUsIHN0clR5cGUpOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldEJvcmRlclN0eWxlKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgc3RyVHlwZSk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJaWYgKCFwRm9ybUZpZWxkKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBHZXRXaWRnZXQobV9wRG9jdW1lbnQsIEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpKTsKKwkJaWYgKCFwV2lkZ2V0KSByZXR1cm4gRkFMU0U7CisKKwkJaW50IG5Cb3JkZXJzdHlsZSA9IHBXaWRnZXQtPkdldEJvcmRlclN0eWxlKCk7CisKKwkJc3dpdGNoIChuQm9yZGVyc3R5bGUpCisJCXsKKwkJCWNhc2UgQkJTX1NPTElEOgorCQkJCXZwIDw8IChGWF9MUENXU1RSKUwic29saWQiOworCQkJCWJyZWFrOworCQkJY2FzZSBCQlNfREFTSDoKKwkJCQl2cCA8PCAoRlhfTFBDV1NUUilMImRhc2hlZCI7CisJCQkJYnJlYWs7CisJCQljYXNlIEJCU19CRVZFTEVEOgorCQkJCXZwIDw8IChGWF9MUENXU1RSKUwiYmV2ZWxlZCI7CisJCQkJYnJlYWs7CisJCQljYXNlIEJCU19JTlNFVDoKKwkJCQl2cCA8PCAoRlhfTFBDV1NUUilMImluc2V0IjsKKwkJCQlicmVhazsKKwkJCWNhc2UgQkJTX1VOREVSTElORToKKwkJCQl2cCA8PCAoRlhfTFBDV1NUUilMInVuZGVybGluZSI7CisJCQkJYnJlYWs7CisJCQlkZWZhdWx0OgorCQkJCXZwIDw8IChGWF9MUENXU1RSKUwiIjsKKwkJCQlicmVhazsKKwkJfQorCX0KKworCXJldHVybiBUUlVFOworfQorCit2b2lkIEZpZWxkOjpTZXRCb3JkZXJTdHlsZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIAorCQkJCQkJICAgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHN0cmluZykKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJaW50IG5Cb3JkZXJTdHlsZSA9IDA7CisKKwlpZiAoc3RyaW5nID09ICJzb2xpZCIpCisJCW5Cb3JkZXJTdHlsZSA9IEJCU19TT0xJRDsKKwllbHNlIGlmIChzdHJpbmcgPT0gImJldmVsZWQiKQorCQluQm9yZGVyU3R5bGUgPSBCQlNfQkVWRUxFRDsKKwllbHNlIGlmIChzdHJpbmcgPT0gImRhc2hlZCIpCisJCW5Cb3JkZXJTdHlsZSA9IEJCU19EQVNIOworCWVsc2UgaWYgKHN0cmluZyA9PSAiaW5zZXQiKQorCQluQm9yZGVyU3R5bGUgPSBCQlNfSU5TRVQ7CisJZWxzZSBpZiAoc3RyaW5nID09ICJ1bmRlcmxpbmUiKQorCQluQm9yZGVyU3R5bGUgPSBCQlNfVU5ERVJMSU5FOworCWVsc2UgcmV0dXJuOworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhwRG9jdW1lbnQsIHN3RmllbGROYW1lLCBGaWVsZEFycmF5KTsKKworCWZvciAoaW50IGk9MCxpc3o9RmllbGRBcnJheS5HZXRTaXplKCk7IGk8aXN6OyBpKyspCisJeworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoaSk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChuQ29udHJvbEluZGV4IDwgMCkKKwkJeworCQkJRlhfQk9PTCBiU2V0ID0gRkFMU0U7CisJCQlmb3IgKGludCBqPTAsanN6ID0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBqPGpzejsgaisrKQorCQkJeworCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IEdldFdpZGdldChwRG9jdW1lbnQsIHBGb3JtRmllbGQtPkdldENvbnRyb2woaikpKQorCQkJCXsKKwkJCQkJaWYgKHBXaWRnZXQtPkdldEJvcmRlclN0eWxlKCkgIT0gbkJvcmRlclN0eWxlKQorCQkJCQl7CisJCQkJCQlwV2lkZ2V0LT5TZXRCb3JkZXJTdHlsZShuQm9yZGVyU3R5bGUpOworCQkJCQkJYlNldCA9IFRSVUU7CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCQlpZiAoYlNldCkgVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgVFJVRSwgVFJVRSk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlpZihuQ29udHJvbEluZGV4ID49IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuOworCQkJaWYgKENQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2wobkNvbnRyb2xJbmRleCkpCisJCQl7CisJCQkJaWYgKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gR2V0V2lkZ2V0KHBEb2N1bWVudCwgcEZvcm1Db250cm9sKSkKKwkJCQl7CisJCQkJCWlmIChwV2lkZ2V0LT5HZXRCb3JkZXJTdHlsZSgpICE9IG5Cb3JkZXJTdHlsZSkKKwkJCQkJeworCQkJCQkJcFdpZGdldC0+U2V0Qm9yZGVyU3R5bGUobkJvcmRlclN0eWxlKTsKKwkJCQkJCVVwZGF0ZUZvcm1Db250cm9sKHBEb2N1bWVudCwgcEZvcm1Db250cm9sLCBUUlVFLCBUUlVFLCBUUlVFKTsKKwkJCQkJfQorCQkJCX0KKwkJCX0KKwkJfQorCX0KK30KKworRlhfQk9PTCBGaWVsZDo6YnV0dG9uQWxpZ25YKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJCWludCBuVlA7CisJCXZwID4+IG5WUDsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0ludChGUF9CVVRUT05BTElHTlgsIG5WUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0QnV0dG9uQWxpZ25YKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgblZQKTsKKwkJfQorCX0KKwllbHNlCisJewkJCisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQorCQkJcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9JY29uRml0IEljb25GaXQgPSBwRm9ybUNvbnRyb2wtPkdldEljb25GaXQoKTsKKworCQlGWF9GTE9BVCBmTGVmdCxmQm90dG9tOworCQlJY29uRml0LkdldEljb25Qb3NpdGlvbihmTGVmdCxmQm90dG9tKTsKKworCQl2cCA8PCAoRlhfSU5UMzIpZkxlZnQ7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldEJ1dHRvbkFsaWduWChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpidXR0b25BbGlnblkoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJaW50IG5WUDsKKwkJdnAgPj4gblZQOworCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfSW50KEZQX0JVVFRPTkFMSUdOWSwgblZQKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCUZpZWxkOjpTZXRCdXR0b25BbGlnblkobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQorCQkJcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9JY29uRml0IEljb25GaXQgPSBwRm9ybUNvbnRyb2wtPkdldEljb25GaXQoKTsKKworCQlGWF9GTE9BVCBmTGVmdCxmQm90dG9tOworCQlJY29uRml0LkdldEljb25Qb3NpdGlvbihmTGVmdCxmQm90dG9tKTsKKworCQl2cCA8PCAgKEZYX0lOVDMyKWZCb3R0b207CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldEJ1dHRvbkFsaWduWShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpidXR0b25GaXRCb3VuZHMoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0Jvb2woRlBfQlVUVE9ORklUQk9VTkRTLCBiVlApOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldEJ1dHRvbkZpdEJvdW5kcyhtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGJWUCk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1BVU0hCVVRUT04pCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7CisJCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsKKworCQlDUERGX0ljb25GaXQgSWNvbkZpdCA9IHBGb3JtQ29udHJvbC0+R2V0SWNvbkZpdCgpOworCQl2cCA8PCBJY29uRml0LkdldEZpdHRpbmdCb3VuZHMoKTsJCQorCX0KKworCXJldHVybiBUUlVFOworfQorCit2b2lkIEZpZWxkOjpTZXRCdXR0b25GaXRCb3VuZHMoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpidXR0b25Qb3NpdGlvbihPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlpbnQgblZQOworCQl2cCA+PiBuVlA7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9JbnQoRlBfQlVUVE9OUE9TSVRJT04sIG5WUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0QnV0dG9uUG9zaXRpb24obV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQorCQkJcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7CisKKwkJdnAgPDwgIHBGb3JtQ29udHJvbC0+R2V0VGV4dFBvc2l0aW9uKCk7CisJfQorCXJldHVybiBUUlVFOworfQorCit2b2lkIEZpZWxkOjpTZXRCdXR0b25Qb3NpdGlvbihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpidXR0b25TY2FsZUhvdyhPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlpbnQgblZQOworCQl2cCA+PiBuVlA7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9JbnQoRlBfQlVUVE9OU0NBTEVIT1csIG5WUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0QnV0dG9uU2NhbGVIb3cobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfUFVTSEJVVFRPTikKKwkJCXJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBHZXRTbWFydEZpZWxkQ29udHJvbChwRm9ybUZpZWxkKTsKKwkJaWYgKCFwRm9ybUNvbnRyb2wpcmV0dXJuIEZBTFNFOworCisJCUNQREZfSWNvbkZpdCBJY29uRml0ID0gcEZvcm1Db250cm9sLT5HZXRJY29uRml0KCk7CisJCWlmIChJY29uRml0LklzUHJvcG9ydGlvbmFsU2NhbGUoKSkKKwkJCXZwIDw8IChGWF9JTlQzMikwOworCQllbHNlCisJCQl2cCA8PCAoRlhfSU5UMzIpMTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0QnV0dG9uU2NhbGVIb3coQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKQoreworCS8vTm90IHN1cHBvcnRlZC4KK30KKworRlhfQk9PTCBGaWVsZDo6YnV0dG9uU2NhbGVXaGVuKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJCWludCBuVlA7CisJCXZwID4+IG5WUDsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0ludChGUF9CVVRUT05TQ0FMRVdIRU4sIG5WUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0QnV0dG9uU2NhbGVXaGVuKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgblZQKTsKKwkJfQorCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopIEZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1BVU0hCVVRUT04pCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7CisJCWlmICghcEZvcm1Db250cm9sKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9JY29uRml0IEljb25GaXQgPSBwRm9ybUNvbnRyb2wtPkdldEljb25GaXQoKTsKKwkJaW50IFNjYWxlTSA9IEljb25GaXQuR2V0U2NhbGVNZXRob2QoKTsKKwkJc3dpdGNoIChTY2FsZU0pCisJCXsKKwkJCWNhc2UgQ1BERl9JY29uRml0OjpBbHdheXMgOgorCQkJCXZwIDw8ICAoRlhfSU5UMzIpIENQREZfSWNvbkZpdDo6QWx3YXlzOworCQkJCWJyZWFrOworCQkJY2FzZSBDUERGX0ljb25GaXQ6OkJpZ2dlciA6CisJCQkJdnAgPDwgIChGWF9JTlQzMikgQ1BERl9JY29uRml0OjpCaWdnZXI7CisJCQkJYnJlYWs7CisJCQljYXNlIENQREZfSWNvbkZpdDo6TmV2ZXIgOgorCQkJCXZwIDw8ICAoRlhfSU5UMzIpIENQREZfSWNvbkZpdDo6TmV2ZXI7CisJCQkJYnJlYWs7CisJCQljYXNlIENQREZfSWNvbkZpdDo6U21hbGxlciA6CisJCQkJdnAgPDwgIChGWF9JTlQzMikgQ1BERl9JY29uRml0OjpTbWFsbGVyOworCQkJCWJyZWFrOworCQl9CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldEJ1dHRvblNjYWxlV2hlbihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGludCBudW1iZXIpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpjYWxjT3JkZXJJbmRleChPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsJCisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJaW50IG5WUDsKKwkJdnAgPj4gblZQOworCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfSW50KEZQX0NBTENPUkRFUklOREVYLCBuVlApOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldENhbGNPcmRlckluZGV4KG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgblZQKTsKKwkJfQorCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX0NPTUJPQk9YICYmIHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJQ1BERlNES19JbnRlckZvcm0qIHBSREludGVyRm9ybSA9IG1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwkJQVNTRVJUKHBSREludGVyRm9ybSAhPSBOVUxMKTsKKworCQlDUERGX0ludGVyRm9ybSogcEludGVyRm9ybSA9IHBSREludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7CisJCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJCXZwIDw8IChGWF9JTlQzMilwSW50ZXJGb3JtLT5GaW5kRmllbGRJbkNhbGN1bGF0aW9uT3JkZXIocEZvcm1GaWVsZCk7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldENhbGNPcmRlckluZGV4KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikKK3sKKwkvL05vdCBzdXBwb3J0ZWQuCit9CisKK0ZYX0JPT0wgRmllbGQ6OmNoYXJMaW1pdChPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlpbnQgblZQOworCQl2cCA+PiBuVlA7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9JbnQoRlBfQ0hBUkxJTUlULCBuVlApOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldENoYXJMaW1pdChtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIG5WUCk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJdnAgPDwgKEZYX0lOVDMyKXBGb3JtRmllbGQtPkdldE1heExlbigpOworCX0KKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0Q2hhckxpbWl0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikKK3sKKwkvL05vdCBzdXBwb3J0ZWQuCit9CisKK0ZYX0JPT0wgRmllbGQ6OmNvbWIoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0Jvb2woRlBfQ09NQiwgYlZQKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCUZpZWxkOjpTZXRDb21iKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYlZQKTsKKwkJfQorCX0KKwllbHNlCisJewkKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1RFWFRGSUVMRCkKKwkJCXJldHVybiBGQUxTRTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX0NPTUIpCisJCQl2cCA8PCB0cnVlOworCQllbHNlCisJCQl2cCA8PCBmYWxzZTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0Q29tYihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYikKK3sKKwkvL05vdCBzdXBwb3J0ZWQuCit9CisKK0ZYX0JPT0wgRmllbGQ6OmNvbW1pdE9uU2VsQ2hhbmdlKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJCWJvb2wgYlZQOworCQl2cCA+PiBiVlA7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9Cb29sKEZQX0NPTU1JVE9OU0VMQ0hBTkdFLCBiVlApOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldENvbW1pdE9uU2VsQ2hhbmdlKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYlZQKTsKKwkJfQorCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfQ09NQk9CT1ggJiYgcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX0xJU1RCT1gpCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19DT01NSVRPTlNFTENIQU5HRSkKKwkJCXZwIDw8IHRydWU7CisJCWVsc2UKKwkJCXZwIDw8IGZhbHNlOworCX0KKworCXJldHVybiBUUlVFOworfQorCit2b2lkIEZpZWxkOjpTZXRDb21taXRPblNlbENoYW5nZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYikKK3sKKwkvL05vdCBzdXBwb3J0ZWQuCit9CisKK0ZYX0JPT0wgRmllbGQ6OmN1cnJlbnRWYWx1ZUluZGljZXMoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJQ0ZYX0RXb3JkQXJyYXkgYXJyYXk7CisKKwkJaWYgKHZwLkdldFR5cGUoKSA9PSBWVF9udW1iZXIpCisJCXsKKwkJCWludCBpU2VsZWN0aW5nID0gMDsKKwkJCXZwID4+IGlTZWxlY3Rpbmc7CisJCQlhcnJheS5BZGQoaVNlbGVjdGluZyk7CisJCX0KKwkJZWxzZSBpZiAodnAuSXNBcnJheU9iamVjdCgpKQorCQl7CisJCQlDSlNfQXJyYXkgU2VsQXJyYXkobV9pc29sYXRlKTsKKwkJCUNKU19WYWx1ZSBTZWxWYWx1ZShtX2lzb2xhdGUpOworCQkJaW50IGlTZWxlY3Rpbmc7CisJCQl2cCA+PiBTZWxBcnJheTsKKwkJCWZvciAoaW50IGk9MCxzej1TZWxBcnJheS5HZXRMZW5ndGgoKTsgaTxzejsgaSsrKQorCQkJeworCQkJCVNlbEFycmF5LkdldEVsZW1lbnQoaSxTZWxWYWx1ZSk7CisJCQkJaVNlbGVjdGluZyA9IChGWF9JTlQzMilTZWxWYWx1ZTsKKwkJCQlhcnJheS5BZGQoaVNlbGVjdGluZyk7CisJCQl9CisJCX0KKwkJCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfV29yZEFycmF5KEZQX0NVUlJFTlRWQUxVRUlORElDRVMsIGFycmF5KTsKKwkJfQorCQllbHNlCisJCXsKKwkJCUZpZWxkOjpTZXRDdXJyZW50VmFsdWVJbmRpY2VzKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYXJyYXkpOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9DT01CT0JPWCAmJiBwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfTElTVEJPWCkKKwkJCXJldHVybiBGQUxTRTsKKworCQlpZiAocEZvcm1GaWVsZC0+Q291bnRTZWxlY3RlZEl0ZW1zKCkgPT0gMSkKKwkJCXZwIDw8IHBGb3JtRmllbGQtPkdldFNlbGVjdGVkSW5kZXgoMCk7CisJCWVsc2UgaWYgKHBGb3JtRmllbGQtPkNvdW50U2VsZWN0ZWRJdGVtcygpID4gMSkKKwkJeworCQkJQ0pTX0FycmF5IFNlbEFycmF5KG1faXNvbGF0ZSk7CisJCQlmb3IgKGludCBpPTAsc3o9cEZvcm1GaWVsZC0+Q291bnRTZWxlY3RlZEl0ZW1zKCk7IGk8c3o7IGkrKykKKwkJCXsKKwkJCQlTZWxBcnJheS5TZXRFbGVtZW50KGksIENKU19WYWx1ZShtX2lzb2xhdGUscEZvcm1GaWVsZC0+R2V0U2VsZWN0ZWRJbmRleChpKSkpOworCQkJfQorCQkJdnAgPDwgU2VsQXJyYXk7CisJCX0KKwkJZWxzZQorCQkJdnAgPDwgLTE7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldEN1cnJlbnRWYWx1ZUluZGljZXMoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCAKKwkJCQkJCQkJICAgY29uc3QgQ0ZYX0RXb3JkQXJyYXkmIGFycmF5KQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKHBEb2N1bWVudCwgc3dGaWVsZE5hbWUsIEZpZWxkQXJyYXkpOworCisJZm9yIChpbnQgaT0wLGlzej1GaWVsZEFycmF5LkdldFNpemUoKTsgaTxpc3o7IGkrKykKKwl7CisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdChpKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaW50IG5GaWVsZFR5cGUgPSBwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKTsKKwkJaWYgKG5GaWVsZFR5cGUgPT0gRklFTERUWVBFX0NPTUJPQk9YIHx8IG5GaWVsZFR5cGUgPT0gRklFTERUWVBFX0xJU1RCT1gpCisJCXsKKwkJCUZYX0RXT1JEIGR3RmllbGRGbGFncyA9IHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKTsKKwkJCXBGb3JtRmllbGQtPkNsZWFyU2VsZWN0aW9uKFRSVUUpOworCisJCQlmb3IgKGludCBpPTAsc3o9YXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQl7CisJCQkJaWYgKGk+MCAmJiAhKGR3RmllbGRGbGFncyAmICgxPDwyMSkpKQorCQkJCXsKKwkJCQkJYnJlYWs7CisJCQkJfQorCisJCQkJaW50IGlTZWxlY3RpbmcgPSAoRlhfSU5UMzIpYXJyYXkuR2V0QXQoaSk7CisJCQkJaWYgKGlTZWxlY3RpbmcgPCBwRm9ybUZpZWxkLT5Db3VudE9wdGlvbnMoKSAmJiAhcEZvcm1GaWVsZC0+SXNJdGVtU2VsZWN0ZWQoaVNlbGVjdGluZykpCisJCQkJCXBGb3JtRmllbGQtPlNldEl0ZW1TZWxlY3Rpb24oaVNlbGVjdGluZywgVFJVRSk7CisKKwkJCX0KKwkJCVVwZGF0ZUZvcm1GaWVsZChwRG9jdW1lbnQsIHBGb3JtRmllbGQsIFRSVUUsIFRSVUUsIFRSVUUpOworCQl9CisJfQorfQorCitGWF9CT09MIEZpZWxkOjpkZWZhdWx0U3R5bGUoT0JKX1BST1BfUEFSQU1TKQoreworCS8vIE1RRyBzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChJRFNfU1RSSU5HX05PVFNVUFBPUlQpOworCXJldHVybiBGQUxTRTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJOwkJCisJfQorCWVsc2UKKwl7CisJCTsKKwl9CisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldERlZmF1bHRTdHlsZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpkZWZhdWx0VmFsdWUoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJQ0ZYX1dpZGVTdHJpbmcgV2lkZVN0cjsKKwkJdnAgPj4gV2lkZVN0cjsgCisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9XaWRlU3RyaW5nKEZQX0RFRkFVTFRWQUxVRSwgV2lkZVN0cik7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0RGVmYXVsdFZhbHVlKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgV2lkZVN0cik7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX1BVU0hCVVRUT04gfHwgCisJCQlwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfU0lHTkFUVVJFKQorCQkJcmV0dXJuIEZBTFNFOworCisJCXZwIDw8IHBGb3JtRmllbGQtPkdldERlZmF1bHRWYWx1ZSgpOworCX0KKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0RGVmYXVsdFZhbHVlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwKKwkJCQkJCQljb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKQoreworCS8vTm90IHN1cHBvcnRlZC4KK30KKworRlhfQk9PTCBGaWVsZDo6ZG9Ob3RTY3JvbGwoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0Jvb2woRlBfRE9OT1RTQ1JPTEwsIGJWUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0RG9Ob3RTY3JvbGwobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBiVlApOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19ET05PVFNDUk9MTCkKKwkJCXZwIDw8IHRydWU7CisJCWVsc2UKKwkJCXZwIDw8IGZhbHNlOworCX0KKworCXJldHVybiBUUlVFOworfQorCit2b2lkIEZpZWxkOjpTZXREb05vdFNjcm9sbChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGJvb2wgYikKK3sKKwkvL05vdCBzdXBwb3J0ZWQuCit9CisKK0ZYX0JPT0wgRmllbGQ6OmRvTm90U3BlbGxDaGVjayhPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlib29sIGJWUDsKKwkJdnAgPj4gYlZQOworCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfVEVYVEZJRUxEICYmIAorCQkJcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX0NPTUJPQk9YKQorCQkJcmV0dXJuIEZBTFNFOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfRE9OT1RTUEVMTENIRUNLKQorCQkJdnAgPDwgdHJ1ZTsKKwkJZWxzZQorCQkJdnAgPDwgZmFsc2U7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldERlbGF5KEZYX0JPT0wgYkRlbGF5KQoreworCW1fYkRlbGF5ID0gYkRlbGF5OworCisJaWYgKCFtX2JEZWxheSkKKwl7CisJCWlmIChtX3BKU0RvYykKKwkJCW1fcEpTRG9jLT5Eb0ZpZWxkRGVsYXkobV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgpOworCX0KK30KKworRlhfQk9PTCBGaWVsZDo6ZGVsYXkoT0JKX1BST1BfUEFSQU1TKQoreworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisJCQorCQlib29sIGJWUDsKKwkJdnAgPj4gYlZQOworCisJCVNldERlbGF5KGJWUCk7CisJfQorCWVsc2UKKwl7CisJCXZwIDw8IG1fYkRlbGF5OworCX0KKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6ZGlzcGxheShPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlpbnQgblZQOworCQl2cCA+PiBuVlA7CQorCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfSW50KEZQX0RJU1BMQVksIG5WUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0RGlzcGxheShtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIG5WUCk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChHZXRTbWFydEZpZWxkQ29udHJvbChwRm9ybUZpZWxkKSk7CisJCWlmICghcFdpZGdldClyZXR1cm4gRkFMU0U7CisKKwkJRlhfRFdPUkQgZHdGbGFnID0gcFdpZGdldC0+R2V0RmxhZ3MoKTsKKworCQlpZiAoQU5OT1RGTEFHX0lOVklTSUJMRSAmIGR3RmxhZyB8fCBBTk5PVEZMQUdfSElEREVOICYgZHdGbGFnKSAKKwkJeworCQkJdnAgPDwgKEZYX0lOVDMyKTE7CisJCX0KKwkJZWxzZSAKKwkJeworCQkJaWYgKEFOTk9URkxBR19QUklOVCAmIGR3RmxhZykKKwkJCXsKKwkJCQlpZiAoQU5OT1RGTEFHX05PVklFVyAmIGR3RmxhZykKKwkJCQl7CisJCQkJCXZwIDw8IChGWF9JTlQzMikzOworCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQl2cCA8PCAoRlhfSU5UMzIpMDsKKwkJCQl9CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJdnAgPDwgKEZYX0lOVDMyKTI7CisJCQl9CQkJCQorCQl9CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldERpc3BsYXkoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMocERvY3VtZW50LCBzd0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7CisKKwlmb3IgKGludCBpPTAsaXN6PUZpZWxkQXJyYXkuR2V0U2l6ZSgpOyBpPGlzejsgaSsrKQorCXsKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KGkpOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAobkNvbnRyb2xJbmRleCA8IDApCisJCXsKKwkJCUZYX0JPT0wgYlNldCA9IEZBTFNFOworCQkJZm9yIChpbnQgaj0wLGpzeiA9IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgajxqc3o7IGorKykKKwkJCXsKKwkJCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKGopOworCQkJCUFTU0VSVChwRm9ybUNvbnRyb2wgIT0gTlVMTCk7CisKKwkJCQlpZiAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1Db250cm9sKSkKKwkJCQl7CisJCQkJCUZYX0RXT1JEIGR3RmxhZyA9IHBXaWRnZXQtPkdldEZsYWdzKCk7CisJCQkJCXN3aXRjaCAobnVtYmVyKQorCQkJCQl7CisJCQkJCWNhc2UgMDoKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOworCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX0hJRERFTik7CisJCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfTk9WSUVXKTsKKwkJCQkJCWR3RmxhZyB8PSBBTk5PVEZMQUdfUFJJTlQ7CQkJCQkJCQorCQkJCQkJYnJlYWs7CisJCQkJCWNhc2UgMToKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOworCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX05PVklFVyk7CisJCQkJCQlkd0ZsYWcgfD0gKEFOTk9URkxBR19ISURERU4gfCBBTk5PVEZMQUdfUFJJTlQpOworCQkJCQkJYnJlYWs7CisJCQkJCWNhc2UgMjoKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOworCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX1BSSU5UKTsKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19ISURERU4pOworCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX05PVklFVyk7CisJCQkJCQlicmVhazsKKwkJCQkJY2FzZSAzOgorCQkJCQkJZHdGbGFnIHw9IEFOTk9URkxBR19OT1ZJRVc7CisJCQkJCQlkd0ZsYWcgfD0gQU5OT1RGTEFHX1BSSU5UOworCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX0hJRERFTik7CisJCQkJCQlicmVhazsKKwkJCQkJfQkKKworCQkJCQlpZiAoZHdGbGFnICE9IHBXaWRnZXQtPkdldEZsYWdzKCkpCisJCQkJCXsKKwkJCQkJCXBXaWRnZXQtPlNldEZsYWdzKGR3RmxhZyk7CisJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJfQorCQkJCX0KKwkJCX0JCQorCQkJCisJCQlpZiAoYlNldCkgVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgRkFMU0UsIFRSVUUpOworCQl9CisJCWVsc2UKKwkJeworCQkJaWYobkNvbnRyb2xJbmRleCA+PSBwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpIHJldHVybjsKKwkJCWlmIChDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKG5Db250cm9sSW5kZXgpKQorCQkJeworCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpKQorCQkJCXsKKworCQkJCQlGWF9EV09SRCBkd0ZsYWcgPSBwV2lkZ2V0LT5HZXRGbGFncygpOworCQkJCQlzd2l0Y2ggKG51bWJlcikKKwkJCQkJeworCQkJCQljYXNlIDA6CisJCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfSU5WSVNJQkxFKTsKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19ISURERU4pOworCQkJCQkJZHdGbGFnICY9ICh+QU5OT1RGTEFHX05PVklFVyk7CisJCQkJCQlkd0ZsYWcgfD0gQU5OT1RGTEFHX1BSSU5UOwkJCQkJCQkKKwkJCQkJCWJyZWFrOworCQkJCQljYXNlIDE6CisJCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfSU5WSVNJQkxFKTsKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19OT1ZJRVcpOworCQkJCQkJZHdGbGFnIHw9IChBTk5PVEZMQUdfSElEREVOIHwgQU5OT1RGTEFHX1BSSU5UKTsKKwkJCQkJCWJyZWFrOworCQkJCQljYXNlIDI6CisJCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfSU5WSVNJQkxFKTsKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19QUklOVCk7CisJCQkJCQlkd0ZsYWcgJj0gKH5BTk5PVEZMQUdfSElEREVOKTsKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19OT1ZJRVcpOworCQkJCQkJYnJlYWs7CisJCQkJCWNhc2UgMzoKKwkJCQkJCWR3RmxhZyB8PSBBTk5PVEZMQUdfTk9WSUVXOworCQkJCQkJZHdGbGFnIHw9IEFOTk9URkxBR19QUklOVDsKKwkJCQkJCWR3RmxhZyAmPSAofkFOTk9URkxBR19ISURERU4pOworCQkJCQkJYnJlYWs7CisJCQkJCX0JCisJCQkJCWlmIChkd0ZsYWcgIT0gcFdpZGdldC0+R2V0RmxhZ3MoKSkKKwkJCQkJeworCQkJCQkJcFdpZGdldC0+U2V0RmxhZ3MoZHdGbGFnKTsKKwkJCQkJCVVwZGF0ZUZvcm1Db250cm9sKHBEb2N1bWVudCwgcEZvcm1Db250cm9sLCBUUlVFLCBGQUxTRSwgVFJVRSk7CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCX0KKwl9Cit9CisKK0ZYX0JPT0wgRmllbGQ6OmRvYyhPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcEpTRG9jICE9IE5VTEwpOworCisJaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7CisKKwl2cCA8PCAoQ0pTX09iamVjdCopKCptX3BKU0RvYyk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6ZWRpdGFibGUoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX0NPTUJPQk9YKQorCQkJcmV0dXJuIEZBTFNFOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfRURJVCkKKwkJCXZwIDw8IHRydWU7CisJCWVsc2UKKwkJCXZwIDw8IGZhbHNlOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIEZpZWxkOjpleHBvcnRWYWx1ZXMoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfQ0hFQ0tCT1ggJiYgCisJCXBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9SQURJT0JVVFRPTikKKwkJcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsJCisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisJCWlmICghdnAuSXNBcnJheU9iamVjdCgpKXJldHVybiBGQUxTRTsKKwl9CisJZWxzZQorCXsKKwkJQ0pTX0FycmF5IEV4cG9ydFZhbHVzQXJyYXkobV9pc29sYXRlKTsKKworCQlpZiAobV9uRm9ybUNvbnRyb2xJbmRleCA8IDApCisJCXsKKwkJCWZvciAoaW50IGk9MCxzej1wRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGk8c3o7IGkrKykKKwkJCXsKKwkJCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKGkpOworCQkJCUFTU0VSVChwRm9ybUNvbnRyb2wgIT0gTlVMTCk7CisKKwkJCQlFeHBvcnRWYWx1c0FycmF5LlNldEVsZW1lbnQoaSwgQ0pTX1ZhbHVlKG1faXNvbGF0ZSwoRlhfTFBDV1NUUilwRm9ybUNvbnRyb2wtPkdldEV4cG9ydFZhbHVlKCkpKTsKKwkJCX0KKwkJfQorCQllbHNlCisJCXsKKwkJCWlmKG1fbkZvcm1Db250cm9sSW5kZXggPj0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpKSByZXR1cm4gRkFMU0U7CisJCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKG1fbkZvcm1Db250cm9sSW5kZXgpOworCQkJaWYgKCFwRm9ybUNvbnRyb2wpIHJldHVybiBGQUxTRTsKKworCQkJRXhwb3J0VmFsdXNBcnJheS5TZXRFbGVtZW50KDAsIENKU19WYWx1ZShtX2lzb2xhdGUsKEZYX0xQQ1dTVFIpcEZvcm1Db250cm9sLT5HZXRFeHBvcnRWYWx1ZSgpKSk7CisJCX0KKworCQl2cCA8PCBFeHBvcnRWYWx1c0FycmF5OworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIEZpZWxkOjpmaWxlU2VsZWN0KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpCisJCXJldHVybiBGQUxTRTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCX0KKwllbHNlCisJeworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX0ZJTEVTRUxFQ1QpCisJCQl2cCA8PCB0cnVlOworCQllbHNlCisJCQl2cCA8PCBmYWxzZTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6ZmlsbENvbG9yKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDSlNfQXJyYXkgY3JBcnJheShtX2lzb2xhdGUpOworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKwkJaWYgKCF2cC5Jc0FycmF5T2JqZWN0KCkpIHJldHVybiBGQUxTRTsKKworCQl2cCA+PiBjckFycmF5OworCisJCUNQV0xfQ29sb3IgY29sb3I7CisJCWNvbG9yOjpDb252ZXJ0QXJyYXlUb1BXTENvbG9yKGNyQXJyYXksIGNvbG9yKTsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0NvbG9yKEZQX0ZJTExDT0xPUiwgY29sb3IpOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldEZpbGxDb2xvcihtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGNvbG9yKTsKKwkJfQorCX0KKwllbHNlCisJeworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7CisKKwkJaW50IGlDb2xvclR5cGU7CisJCXBGb3JtQ29udHJvbC0+R2V0QmFja2dyb3VuZENvbG9yKGlDb2xvclR5cGUpOworCisJCUNQV0xfQ29sb3IgY29sb3I7CisKKwkJaWYgKGlDb2xvclR5cGUgPT0gQ09MT1JUWVBFX1RSQU5TUEFSRU5UKQorCQl7CisJCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1RSQU5TUEFSRU5UKTsKKwkJfQorCQllbHNlIGlmIChpQ29sb3JUeXBlID09IENPTE9SVFlQRV9HUkFZKQorCQl7CisJCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIHBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMCkpOworCQl9CisJCWVsc2UgaWYgKGlDb2xvclR5cGUgPT0gQ09MT1JUWVBFX1JHQikKKwkJeworCQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIHBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMCksCisJCQkJcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJhY2tncm91bmRDb2xvcigxKSwKKwkJCQlwRm9ybUNvbnRyb2wtPkdldE9yaWdpbmFsQmFja2dyb3VuZENvbG9yKDIpKTsKKwkJfQorCQllbHNlIGlmIChpQ29sb3JUeXBlID09IENPTE9SVFlQRV9DTVlLKQorCQl7CisJCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0NNWUssIHBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMCksCisJCQkJcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJhY2tncm91bmRDb2xvcigxKSwKKwkJCQlwRm9ybUNvbnRyb2wtPkdldE9yaWdpbmFsQmFja2dyb3VuZENvbG9yKDIpLAorCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IoMykpOworCQl9CisJCWVsc2UKKwkJCXJldHVybiBGQUxTRTsKKworCQljb2xvcjo6Q29udmVydFBXTENvbG9yVG9BcnJheShjb2xvciwgY3JBcnJheSk7CisgICAgICAgIHZwICA8PCAgY3JBcnJheTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0RmlsbENvbG9yKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpoaWRkZW4oT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0Jvb2woRlBfSElEREVOLCBiVlApOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldEhpZGRlbihtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGJWUCk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCQlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChHZXRTbWFydEZpZWxkQ29udHJvbChwRm9ybUZpZWxkKSk7CisJCWlmICghcFdpZGdldCkgcmV0dXJuIEZBTFNFOworCisJCUZYX0RXT1JEIGR3RmxhZ3MgPSBwV2lkZ2V0LT5HZXRGbGFncygpOworCisJCWlmIChBTk5PVEZMQUdfSU5WSVNJQkxFICYgZHdGbGFncyB8fCBBTk5PVEZMQUdfSElEREVOICYgZHdGbGFncykgCisJCXsKKwkJCXZwIDw8IHRydWU7CisJCX0KKwkJZWxzZSAKKwkJCXZwIDw8IGZhbHNlOworCX0KKworCXJldHVybiBUUlVFOworfQorCit2b2lkIEZpZWxkOjpTZXRIaWRkZW4oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhwRG9jdW1lbnQsIHN3RmllbGROYW1lLCBGaWVsZEFycmF5KTsKKworCWZvciAoaW50IGk9MCxpc3o9RmllbGRBcnJheS5HZXRTaXplKCk7IGk8aXN6OyBpKyspCisJeworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoaSk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChuQ29udHJvbEluZGV4IDwgMCkKKwkJeworCQkJRlhfQk9PTCBiU2V0ID0gRkFMU0U7CisJCQlmb3IgKGludCBqPTAsanN6ID0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBqPGpzejsgaisrKQorCQkJeworCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUZpZWxkLT5HZXRDb250cm9sKGopKSkKKwkJCQl7CQkJCQkKKwkJCQkJRlhfRFdPUkQgZHdGbGFncyA9IHBXaWRnZXQtPkdldEZsYWdzKCk7CisJCQkJCQorCQkJCQlpZiAoYikKKwkJCQkJeworCQkJCQkJZHdGbGFncyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOworCQkJCQkJZHdGbGFncyAmPSAofkFOTk9URkxBR19OT1ZJRVcpOworCQkJCQkJZHdGbGFncyB8PSAoQU5OT1RGTEFHX0hJRERFTiB8IEFOTk9URkxBR19QUklOVCk7CisJCQkJCX0KKwkJCQkJZWxzZQorCQkJCQl7CisJCQkJCQlkd0ZsYWdzICY9ICh+QU5OT1RGTEFHX0lOVklTSUJMRSk7CisJCQkJCQlkd0ZsYWdzICY9ICh+QU5OT1RGTEFHX0hJRERFTik7CisJCQkJCQlkd0ZsYWdzICY9ICh+QU5OT1RGTEFHX05PVklFVyk7CisJCQkJCQlkd0ZsYWdzIHw9IEFOTk9URkxBR19QUklOVDsJCisJCQkJCX0KKworCQkJCQlpZiAoZHdGbGFncyAhPSBwV2lkZ2V0LT5HZXRGbGFncygpKQorCQkJCQl7CisJCQkJCQlwV2lkZ2V0LT5TZXRGbGFncyhkd0ZsYWdzKTsJCisJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJfQorCQkJCX0KKwkJCX0KKworCQkJaWYgKGJTZXQpCisJCQkJVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgRkFMU0UsIFRSVUUpOwkKKwkJfQorCQllbHNlCisJCXsKKwkJCWlmKG5Db250cm9sSW5kZXggPj0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpKSByZXR1cm47CisJCQlpZiAoQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChuQ29udHJvbEluZGV4KSkKKwkJCXsKKwkJCQlpZiAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1Db250cm9sKSkKKwkJCQl7CisJCQkJCUZYX0RXT1JEIGR3RmxhZ3MgPSBwV2lkZ2V0LT5HZXRGbGFncygpOworCQkJCQkKKwkJCQkJaWYgKGIpCisJCQkJCXsKKwkJCQkJCWR3RmxhZ3MgJj0gKH5BTk5PVEZMQUdfSU5WSVNJQkxFKTsKKwkJCQkJCWR3RmxhZ3MgJj0gKH5BTk5PVEZMQUdfTk9WSUVXKTsKKwkJCQkJCWR3RmxhZ3MgfD0gKEFOTk9URkxBR19ISURERU4gfCBBTk5PVEZMQUdfUFJJTlQpOworCQkJCQl9CisJCQkJCWVsc2UKKwkJCQkJeworCQkJCQkJZHdGbGFncyAmPSAofkFOTk9URkxBR19JTlZJU0lCTEUpOworCQkJCQkJZHdGbGFncyAmPSAofkFOTk9URkxBR19ISURERU4pOworCQkJCQkJZHdGbGFncyAmPSAofkFOTk9URkxBR19OT1ZJRVcpOworCQkJCQkJZHdGbGFncyB8PSBBTk5PVEZMQUdfUFJJTlQ7CQorCQkJCQl9CisKKwkJCQkJaWYgKGR3RmxhZ3MgIT0gcFdpZGdldC0+R2V0RmxhZ3MoKSkKKwkJCQkJeworCQkJCQkJcFdpZGdldC0+U2V0RmxhZ3MoZHdGbGFncyk7CQorCQkJCQkJVXBkYXRlRm9ybUNvbnRyb2wocERvY3VtZW50LCBwRm9ybUNvbnRyb2wsIFRSVUUsIEZBTFNFLCBUUlVFKTsJCisJCQkJCX0KKwkJCQl9CisJCQl9CisJCX0KKwl9Cit9CisKK0ZYX0JPT0wgRmllbGQ6OmhpZ2hsaWdodChPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlDRlhfQnl0ZVN0cmluZyBzdHJNb2RlOworCQl2cCA+PiBzdHJNb2RlOworCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfU3RyaW5nKEZQX0hJR0hMSUdIVCwgc3RyTW9kZSk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0SGlnaGxpZ2h0KG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgc3RyTW9kZSk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1BVU0hCVVRUT04pCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7CisJCWlmICghcEZvcm1Db250cm9sKSByZXR1cm4gRkFMU0U7CisKKwkJaW50IGVITSA9IHBGb3JtQ29udHJvbC0+R2V0SGlnaGxpZ2h0aW5nTW9kZSgpOworCQlzd2l0Y2ggKGVITSkKKwkJeworCQljYXNlIENQREZfRm9ybUNvbnRyb2w6Ok5vbmU6CisJCQl2cCAgPDwgIChGWF9MUENXU1RSKUwibm9uZSI7CisJCQlicmVhazsKKwkJY2FzZSBDUERGX0Zvcm1Db250cm9sOjpQdXNoOgorCQkJdnAgIDw8ICAoRlhfTFBDV1NUUilMInB1c2giOworCQkJYnJlYWs7CisJCWNhc2UgQ1BERl9Gb3JtQ29udHJvbDo6SW52ZXJ0OgorCQkJdnAgIDw8ICAoRlhfTFBDV1NUUilMImludmVydCI7CisJCQlicmVhazsKKwkJY2FzZSBDUERGX0Zvcm1Db250cm9sOjpPdXRsaW5lOgorCQkJdnAgIDw8ICAoRlhfTFBDV1NUUilMIm91dGxpbmUiOworCQkJYnJlYWs7CisJCWNhc2UgQ1BERl9Gb3JtQ29udHJvbDo6VG9nZ2xlOgorCQkJIHZwICA8PCAgKEZYX0xQQ1dTVFIpTCJ0b2dnbGUiOworCQkJIGJyZWFrOworCQl9CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldEhpZ2hsaWdodChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpsaW5lV2lkdGgoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJaW50IGlXaWR0aDsKKwkJdnAgPj4gaVdpZHRoOworCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfSW50KEZQX0xJTkVXSURUSCwgaVdpZHRoKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCUZpZWxkOjpTZXRMaW5lV2lkdGgobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBpV2lkdGgpOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7CisJCWlmICghcEZvcm1Db250cm9sKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwkJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwkJaWYoIXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuIEZBTFNFOworCisJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtRmllbGQtPkdldENvbnRyb2woMCkpOworCQlpZiAoIXBXaWRnZXQpIHJldHVybiBGQUxTRTsKKworCQl2cCA8PCAoRlhfSU5UMzIpcFdpZGdldC0+R2V0Qm9yZGVyV2lkdGgoKTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0TGluZVdpZHRoKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKXBEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKHBEb2N1bWVudCwgc3dGaWVsZE5hbWUsIEZpZWxkQXJyYXkpOworCisJZm9yIChpbnQgaT0wLGlzej1GaWVsZEFycmF5LkdldFNpemUoKTsgaTxpc3o7IGkrKykKKwl7CisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdChpKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKG5Db250cm9sSW5kZXggPCAwKQorCQl7CisJCQlGWF9CT09MIGJTZXQgPSBGQUxTRTsKKwkJCWZvciAoaW50IGo9MCxqc3o9cEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBqPGpzejsgaisrKQorCQkJeworCQkJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2woaik7CisJCQkJQVNTRVJUKHBGb3JtQ29udHJvbCAhPSBOVUxMKTsKKwkJCQkKKwkJCQlpZiAoQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1Db250cm9sKSkKKwkJCQl7CisJCQkJCWlmIChudW1iZXIgIT0gcFdpZGdldC0+R2V0Qm9yZGVyV2lkdGgoKSkKKwkJCQkJeworCQkJCQkJcFdpZGdldC0+U2V0Qm9yZGVyV2lkdGgobnVtYmVyKTsKKwkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQl9CisJCQkJfQorCQkJfQorCQkJaWYgKGJTZXQpIFVwZGF0ZUZvcm1GaWVsZChwRG9jdW1lbnQsIHBGb3JtRmllbGQsIFRSVUUsIFRSVUUsIFRSVUUpOworCQl9CisJCWVsc2UKKwkJeworCQkJaWYobkNvbnRyb2xJbmRleCA+PSBwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpIHJldHVybjsKKwkJCWlmIChDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKG5Db250cm9sSW5kZXgpKQorCQkJeworCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpKQorCQkJCXsKKwkJCQkJaWYgKG51bWJlciAhPSBwV2lkZ2V0LT5HZXRCb3JkZXJXaWR0aCgpKQorCQkJCQl7CisJCQkJCQlwV2lkZ2V0LT5TZXRCb3JkZXJXaWR0aChudW1iZXIpOworCQkJCQkJVXBkYXRlRm9ybUNvbnRyb2wocERvY3VtZW50LCBwRm9ybUNvbnRyb2wsIFRSVUUsIFRSVUUsIFRSVUUpOworCQkJCQl9CisJCQkJfQorCQkJfQorCQl9CisJfQorfQorCitGWF9CT09MIEZpZWxkOjptdWx0aWxpbmUoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0Jvb2woRlBfTVVMVElMSU5FLCBiVlApOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldE11bHRpbGluZShtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGJWUCk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9URVhURklFTEQpCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkRmxhZ3MoKSAmIEZJRUxERkxBR19NVUxUSUxJTkUpCisJCQl2cCA8PCB0cnVlOworCQllbHNlCisJCQl2cCA8PCBmYWxzZTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0TXVsdGlsaW5lKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKQoreworCS8vTm90IHN1cHBvcnRlZC4KK30KKworRlhfQk9PTCBGaWVsZDo6bXVsdGlwbGVTZWxlY3Rpb24oT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X0Jvb2woRlBfTVVMVElQTEVTRUxFQ1RJT04sIGJWUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0TXVsdGlwbGVTZWxlY3Rpb24obV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBiVlApOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9MSVNUQk9YKQorCQkJcmV0dXJuIEZBTFNFOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfTVVMVElTRUxFQ1QpCisJCQl2cCA8PCB0cnVlOworCQllbHNlCisJCQl2cCA8PCBmYWxzZTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0TXVsdGlwbGVTZWxlY3Rpb24oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBib29sIGIpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpuYW1lKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKSByZXR1cm4gRkFMU0U7CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisgICAJdnAgPDwgbV9GaWVsZE5hbWU7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6bnVtSXRlbXMoT0JKX1BST1BfUEFSQU1TKQorewkKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9DT01CT0JPWCAmJgorCQlwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfTElTVEJPWCkKKwkJcmV0dXJuIEZBTFNFOworCisJaWYgKCF2cC5Jc0dldHRpbmcoKSkgcmV0dXJuIEZBTFNFOworCisJdnAgPDwgKEZYX0lOVDMyKXBGb3JtRmllbGQtPkNvdW50T3B0aW9ucygpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnBhZ2UoT0JKX1BST1BfUEFSQU1TKQoreworCWlmICghdnAuSXNHZXR0aW5nKCkpIHJldHVybiBGQUxTRTsKKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsIEZpZWxkQXJyYXkpOworCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJaWYgKCFwRm9ybUZpZWxkKSByZXR1cm4gRkFMU0U7CisKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDUERGU0RLX0ludGVyRm9ybSogcEludGVyRm9ybSA9IChDUERGU0RLX0ludGVyRm9ybSopbV9wRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ0ZYX1B0ckFycmF5IHdpZGdldEFycmF5OworCXBJbnRlckZvcm0tPkdldFdpZGdldHMocEZvcm1GaWVsZCwgd2lkZ2V0QXJyYXkpOworCisJaWYgKHdpZGdldEFycmF5LkdldFNpemUoKSA+IDApCisJeworCQlDSlNfQXJyYXkgUGFnZUFycmF5KG1faXNvbGF0ZSk7CisKKwkJZm9yIChpbnQgaT0wLHN6PXdpZGdldEFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQorCQl7CisJCQlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IChDUERGU0RLX1dpZGdldCopd2lkZ2V0QXJyYXkuR2V0QXQoaSk7CisJCQlBU1NFUlQocFdpZGdldCAhPSBOVUxMKTsKKworCQkJQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3ID0gcFdpZGdldC0+R2V0UGFnZVZpZXcoKTsKKwkJCWlmKCFwUGFnZVZpZXcpCisJCQkJcmV0dXJuIEZBTFNFOworCisJCQlQYWdlQXJyYXkuU2V0RWxlbWVudChpLCBDSlNfVmFsdWUobV9pc29sYXRlLChGWF9JTlQzMilwUGFnZVZpZXctPkdldFBhZ2VJbmRleCgpKSk7CisJCX0KKworCQl2cCA8PCBQYWdlQXJyYXk7CisJfQorCWVsc2UKKwl7CisJCXZwIDw8IChGWF9JTlQzMikgLTE7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnBhc3N3b3JkKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJCWJvb2wgYlZQOworCQl2cCA+PiBiVlA7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9Cb29sKEZQX1BBU1NXT1JELCBiVlApOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldFBhc3N3b3JkKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYlZQKTsKKwkJfQkKKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1RFWFRGSUVMRCkKKwkJCXJldHVybiBGQUxTRTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX1BBU1NXT1JEKQorCQkJdnAgPDwgdHJ1ZTsKKwkJZWxzZQorCQkJdnAgPDwgZmFsc2U7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldFBhc3N3b3JkKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKQoreworCS8vTm90IHN1cHBvcnRlZC4KK30KKworRlhfQk9PTCBGaWVsZDo6cHJpbnQoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlib29sIGJWUDsKKwkJdnAgPj4gYlZQOworCisJCWZvciAoaW50IGk9MCxpc3o9RmllbGRBcnJheS5HZXRTaXplKCk7IGk8aXN6OyBpKyspCisJCXsKKwkJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdChpKTsKKwkJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCQlpZiAobV9uRm9ybUNvbnRyb2xJbmRleCA8IDApCisJCQl7CisJCQkJRlhfQk9PTCBiU2V0ID0gRkFMU0U7CisJCQkJZm9yIChpbnQgaj0wLGpzeiA9IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgajxqc3o7IGorKykKKwkJCQl7CisJCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUZpZWxkLT5HZXRDb250cm9sKGopKSkKKwkJCQkJeworCQkJCQkJRlhfRFdPUkQgZHdGbGFncyA9IHBXaWRnZXQtPkdldEZsYWdzKCk7CisJCQkJCQlpZiAoYlZQKQorCQkJCQkJCWR3RmxhZ3MgfD0gQU5OT1RGTEFHX1BSSU5UOworCQkJCQkJZWxzZQorCQkJCQkJCWR3RmxhZ3MgJj0gfkFOTk9URkxBR19QUklOVDsKKworCQkJCQkJaWYgKGR3RmxhZ3MgIT0gcFdpZGdldC0+R2V0RmxhZ3MoKSkKKwkJCQkJCXsKKwkJCQkJCQlwV2lkZ2V0LT5TZXRGbGFncyhkd0ZsYWdzKTsKKwkJCQkJCQliU2V0ID0gVFJVRTsKKwkJCQkJCX0KKwkJCQkJfQorCQkJCX0KKworCQkJCWlmIChiU2V0KQorCQkJCQlVcGRhdGVGb3JtRmllbGQobV9wRG9jdW1lbnQsIHBGb3JtRmllbGQsIFRSVUUsIEZBTFNFLCBUUlVFKTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlpZihtX25Gb3JtQ29udHJvbEluZGV4ID49IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuIEZBTFNFOworCQkJCWlmIChDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBwRm9ybUZpZWxkLT5HZXRDb250cm9sKG1fbkZvcm1Db250cm9sSW5kZXgpKQorCQkJCXsKKwkJCQkJaWYgKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtQ29udHJvbCkpCisJCQkJCXsKKwkJCQkJCUZYX0RXT1JEIGR3RmxhZ3MgPSBwV2lkZ2V0LT5HZXRGbGFncygpOworCQkJCQkJaWYgKGJWUCkKKwkJCQkJCQlkd0ZsYWdzIHw9IEFOTk9URkxBR19QUklOVDsKKwkJCQkJCWVsc2UKKwkJCQkJCQlkd0ZsYWdzICY9IH5BTk5PVEZMQUdfUFJJTlQ7CisKKwkJCQkJCWlmIChkd0ZsYWdzICE9IHBXaWRnZXQtPkdldEZsYWdzKCkpCisJCQkJCQl7CisJCQkJCQkJcFdpZGdldC0+U2V0RmxhZ3MoZHdGbGFncyk7CisJCQkJCQkJVXBkYXRlRm9ybUNvbnRyb2wobV9wRG9jdW1lbnQsIHBGb3JtRmllbGQtPkdldENvbnRyb2wobV9uRm9ybUNvbnRyb2xJbmRleCksIFRSVUUsIEZBTFNFLCBUUlVFKTsKKwkJCQkJCX0KKwkJCQkJfQorCQkJCX0KKwkJCX0KKwkJfQorCX0KKwllbHNlCisJeworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCQkKKwkJQ1BERlNES19XaWRnZXQqIHBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQoR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCkpOworCQlpZiAoIXBXaWRnZXQpIHJldHVybiBGQUxTRTsKKworCQlpZiAocFdpZGdldC0+R2V0RmxhZ3MoKSAmIEFOTk9URkxBR19QUklOVCkKKwkJCXZwIDw8IHRydWU7CisJCWVsc2UKKwkJCXZwIDw8IGZhbHNlOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIEZpZWxkOjpyYWRpb3NJblVuaXNvbihPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlib29sIGJWUDsKKwkJdnAgPj4gYlZQOworCisJfQorCWVsc2UKKwl7CisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpICE9IEZJRUxEVFlQRV9SQURJT0JVVFRPTikKKwkJCXJldHVybiBGQUxTRTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX1JBRElPU0lOVU5JU09OKQorCQkJdnAgPDwgdHJ1ZTsKKwkJZWxzZQorCQkJdnAgPDwgZmFsc2U7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnJlYWRvbmx5KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJCWJvb2wgYlZQOworCQl2cCA+PiBiVlA7CisKKwl9CisJZWxzZQorCXsKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX1JFQURPTkxZKQorCQkJdnAgPDwgdHJ1ZTsKKwkJZWxzZQorCQkJdnAgPDwgZmFsc2U7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnJlY3QoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisJCWlmICghdnAuSXNBcnJheU9iamVjdCgpKXJldHVybiBGQUxTRTsKKworCQlDSlNfQXJyYXkgcmNBcnJheShtX2lzb2xhdGUpOworCQl2cCA+PiByY0FycmF5OworCQlDSlNfVmFsdWUgVXBwZXJfTGVmdHgobV9pc29sYXRlKSwgVXBwZXJfTGVmdHkobV9pc29sYXRlKSwgTG93ZXJfUmlnaHR4KG1faXNvbGF0ZSksIExvd2VyX1JpZ2h0eShtX2lzb2xhdGUpOworCQlyY0FycmF5LkdldEVsZW1lbnQoMCwgVXBwZXJfTGVmdHgpOworCQlyY0FycmF5LkdldEVsZW1lbnQoMSwgVXBwZXJfTGVmdHkpOworCQlyY0FycmF5LkdldEVsZW1lbnQoMiwgTG93ZXJfUmlnaHR4KTsKKwkJcmNBcnJheS5HZXRFbGVtZW50KDMsIExvd2VyX1JpZ2h0eSk7CisKKwkJRlhfRkxPQVQgcEFycmF5WzRdID0gezAuMGYsMC4wZiwwLjBmLDAuMGZ9OworCQlwQXJyYXlbMF0gPSAoRlhfRkxPQVQpKEZYX0lOVDMyKVVwcGVyX0xlZnR4OworCQlwQXJyYXlbMV0gPSAoRlhfRkxPQVQpKEZYX0lOVDMyKUxvd2VyX1JpZ2h0eTsKKwkJcEFycmF5WzJdID0gKEZYX0ZMT0FUKShGWF9JTlQzMilMb3dlcl9SaWdodHg7CisJCXBBcnJheVszXSA9IChGWF9GTE9BVCkoRlhfSU5UMzIpVXBwZXJfTGVmdHk7CisKKwkJQ1BERl9SZWN0IGNyUmVjdChwQXJyYXkpOworCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfUmVjdChGUF9SRUNULCBjclJlY3QpOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldFJlY3QobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBjclJlY3QpOworCQl9CQorCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJCUNQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpKTsKKwkJaWYgKCFwV2lkZ2V0KSByZXR1cm4gRkFMU0U7CisKKwkJQ0ZYX0Zsb2F0UmVjdCBjclJlY3QgPSBwV2lkZ2V0LT5HZXRSZWN0KCk7CisJCUNKU19WYWx1ZSBVcHBlcl9MZWZ0eChtX2lzb2xhdGUpLFVwcGVyX0xlZnR5KG1faXNvbGF0ZSksTG93ZXJfUmlnaHR4KG1faXNvbGF0ZSksTG93ZXJfUmlnaHR5KG1faXNvbGF0ZSk7CisJCVVwcGVyX0xlZnR4ID0gKEZYX0lOVDMyKWNyUmVjdC5sZWZ0OworCQlVcHBlcl9MZWZ0eSA9IChGWF9JTlQzMiljclJlY3QudG9wOworCQlMb3dlcl9SaWdodHggPSAoRlhfSU5UMzIpY3JSZWN0LnJpZ2h0OworCQlMb3dlcl9SaWdodHkgPSAoRlhfSU5UMzIpY3JSZWN0LmJvdHRvbTsKKworCQlDSlNfQXJyYXkgcmNBcnJheShtX2lzb2xhdGUpOworCQlyY0FycmF5LlNldEVsZW1lbnQoMCxVcHBlcl9MZWZ0eCk7CisJCXJjQXJyYXkuU2V0RWxlbWVudCgxLFVwcGVyX0xlZnR5KTsKKwkJcmNBcnJheS5TZXRFbGVtZW50KDIsTG93ZXJfUmlnaHR4KTsKKwkJcmNBcnJheS5TZXRFbGVtZW50KDMsTG93ZXJfUmlnaHR5KTsKKworCQl2cCAgPDwgIHJjQXJyYXk7CQkJCisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldFJlY3QoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDUERGX1JlY3QmIHJlY3QpCit7CisJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jdW1lbnQtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhwRG9jdW1lbnQsIHN3RmllbGROYW1lLCBGaWVsZEFycmF5KTsKKworCWZvciAoaW50IGk9MCxpc3o9RmllbGRBcnJheS5HZXRTaXplKCk7IGk8aXN6OyBpKyspCisJeworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoaSk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChuQ29udHJvbEluZGV4IDwgMCkKKwkJeworCQkJRlhfQk9PTCBiU2V0ID0gRkFMU0U7CisJCQlmb3IgKGludCBpPTAsIHN6PXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgaTxzejsgaSsrKQorCQkJeworCQkJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2woaSk7CisJCQkJQVNTRVJUKHBGb3JtQ29udHJvbCAhPSBOVUxMKTsKKworCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IHBJbnRlckZvcm0tPkdldFdpZGdldChwRm9ybUNvbnRyb2wpKQorCQkJCXsKKwkJCQkJQ1BERl9SZWN0IGNyUmVjdCA9IHJlY3Q7CisKKwkJCQkJQ1BERl9QYWdlKiBwUERGUGFnZSA9IHBXaWRnZXQtPkdldFBERlBhZ2UoKTsKKwkJCQkJQVNTRVJUKHBQREZQYWdlICE9IE5VTEwpOworCisvLyAJCQkJCUNQREZfUGFnZSogcFBERlBhZ2UgPSBwUGFnZS0+R2V0UGFnZSgpOworLy8gCQkJCQlBU1NFUlQocFBERlBhZ2UgIT0gTlVMTCk7CisKKwkJCQkJY3JSZWN0LkludGVyc2VjdChwUERGUGFnZS0+R2V0UGFnZUJCb3goKSk7CisKKwkJCQkJaWYgKCFjclJlY3QuSXNFbXB0eSgpKQorCQkJCQl7CisJCQkJCQlDUERGX1JlY3QgcmNPbGQgPSBwV2lkZ2V0LT5HZXRSZWN0KCk7CisJCQkJCQlpZiAoY3JSZWN0LmxlZnQgIT0gcmNPbGQubGVmdCB8fAorCQkJCQkJCWNyUmVjdC5yaWdodCAhPSByY09sZC5yaWdodCB8fAorCQkJCQkJCWNyUmVjdC50b3AgIT0gcmNPbGQudG9wIHx8CisJCQkJCQkJY3JSZWN0LmJvdHRvbSAhPSByY09sZC5ib3R0b20pCisJCQkJCQl7CisJCQkJCQkJcFdpZGdldC0+U2V0UmVjdChjclJlY3QpOworCQkJCQkJCWJTZXQgPSBUUlVFOworCQkJCQkJfQorCQkJCQl9CisJCQkJfQorCQkJfQorCisJCQlpZiAoYlNldCkgVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgVFJVRSwgVFJVRSk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlpZihuQ29udHJvbEluZGV4ID49IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuOworCQkJaWYgKENQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2wobkNvbnRyb2xJbmRleCkpCisJCQl7CisJCQkJaWYgKENQREZTREtfV2lkZ2V0KiBwV2lkZ2V0ID0gcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtQ29udHJvbCkpCisJCQkJeworCQkJCQlDUERGX1JlY3QgY3JSZWN0ID0gcmVjdDsKKwkJCQkJCisJCQkJCUNQREZfUGFnZSogcFBERlBhZ2UgPSBwV2lkZ2V0LT5HZXRQREZQYWdlKCk7CisJCQkJCUFTU0VSVChwUERGUGFnZSAhPSBOVUxMKTsKKworLy8gCQkJCQlDUERGX1BhZ2UqIHBQREZQYWdlID0gcFBhZ2UtPkdldFBhZ2UoKTsKKy8vIAkJCQkJQVNTRVJUKHBQREZQYWdlICE9IE5VTEwpOworCisJCQkJCWNyUmVjdC5JbnRlcnNlY3QocFBERlBhZ2UtPkdldFBhZ2VCQm94KCkpOworCisJCQkJCWlmICghY3JSZWN0LklzRW1wdHkoKSkKKwkJCQkJeworCQkJCQkJQ1BERl9SZWN0IHJjT2xkID0gcFdpZGdldC0+R2V0UmVjdCgpOworCQkJCQkJaWYgKGNyUmVjdC5sZWZ0ICE9IHJjT2xkLmxlZnQgfHwKKwkJCQkJCQljclJlY3QucmlnaHQgIT0gcmNPbGQucmlnaHQgfHwKKwkJCQkJCQljclJlY3QudG9wICE9IHJjT2xkLnRvcCB8fAorCQkJCQkJCWNyUmVjdC5ib3R0b20gIT0gcmNPbGQuYm90dG9tKQorCQkJCQkJeworCQkJCQkJCXBXaWRnZXQtPlNldFJlY3QoY3JSZWN0KTsKKwkJCQkJCQlVcGRhdGVGb3JtQ29udHJvbChwRG9jdW1lbnQsIHBGb3JtQ29udHJvbCwgVFJVRSwgVFJVRSwgVFJVRSk7CisJCQkJCQl9CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCX0KKwl9Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnJlcXVpcmVkKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisKKwkJYm9vbCBiVlA7CisJCXZwID4+IGJWUDsKKworCX0KKwllbHNlCisJeworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfUFVTSEJVVFRPTikKKwkJCXJldHVybiBGQUxTRTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX1JFUVVJUkVEKQorCQkJdnAgPDwgdHJ1ZTsKKwkJZWxzZQorCQkJdnAgPDwgZmFsc2U7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnJpY2hUZXh0KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJCWJvb2wgYlZQOworCQl2cCA+PiBiVlA7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9Cb29sKEZQX1JJQ0hURVhULCBiVlApOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldFJpY2hUZXh0KG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgYlZQKTsKKwkJfQkKKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1RFWFRGSUVMRCkKKwkJCXJldHVybiBGQUxTRTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRGbGFncygpICYgRklFTERGTEFHX1JJQ0hURVhUKQorCQkJdnAgPDwgdHJ1ZTsKKwkJZWxzZQorCQkJdnAgPDwgZmFsc2U7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldFJpY2hUZXh0KENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgYm9vbCBiKQoreworCS8vTm90IHN1cHBvcnRlZC4KK30KKworRlhfQk9PTCBGaWVsZDo6cmljaFZhbHVlKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCQk7CisJfQorCWVsc2UKKwl7CisJCTsKKwl9CisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldFJpY2hWYWx1ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpyb3RhdGlvbihPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlpbnQgblZQOworCQl2cCA+PiBuVlA7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9JbnQoRlBfUk9UQVRJT04sIG5WUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0Um90YXRpb24obV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOworCQl9CQorCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7CisKKwkJdnAgPDwgKEZYX0lOVDMyKXBGb3JtQ29udHJvbC0+R2V0Um90YXRpb24oKTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0Um90YXRpb24oQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCBpbnQgbnVtYmVyKQoreworCS8vTm90IHN1cHBvcnRlZC4KK30KKworRlhfQk9PTCBGaWVsZDo6c3Ryb2tlQ29sb3IoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJaWYgKCF2cC5Jc0FycmF5T2JqZWN0KCkpcmV0dXJuIEZBTFNFOworCisJCUNKU19BcnJheSBjckFycmF5KG1faXNvbGF0ZSk7CisJCXZwID4+IGNyQXJyYXk7CisKKwkJQ1BXTF9Db2xvciBjb2xvcjsKKwkJY29sb3I6OkNvbnZlcnRBcnJheVRvUFdMQ29sb3IoY3JBcnJheSwgY29sb3IpOworCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfQ29sb3IoRlBfU1RST0tFQ09MT1IsIGNvbG9yKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCUZpZWxkOjpTZXRTdHJva2VDb2xvcihtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGNvbG9yKTsKKwkJfQkKKwl9CisJZWxzZQorCXsKKwkJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlDUERGX0Zvcm1Db250cm9sKiBwRm9ybUNvbnRyb2wgPSBHZXRTbWFydEZpZWxkQ29udHJvbChwRm9ybUZpZWxkKTsKKwkJaWYgKCFwRm9ybUNvbnRyb2wpcmV0dXJuIEZBTFNFOworCisJCWludCBpQ29sb3JUeXBlOworCQlwRm9ybUNvbnRyb2wtPkdldEJvcmRlckNvbG9yKGlDb2xvclR5cGUpOworCisJCUNQV0xfQ29sb3IgY29sb3I7CisKKwkJaWYgKGlDb2xvclR5cGUgPT0gQ09MT1JUWVBFX1RSQU5TUEFSRU5UKQorCQl7CisJCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1RSQU5TUEFSRU5UKTsKKwkJfQorCQllbHNlIGlmIChpQ29sb3JUeXBlID09IENPTE9SVFlQRV9HUkFZKQorCQl7CisJCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIHBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCb3JkZXJDb2xvcigwKSk7CisJCX0KKwkJZWxzZSBpZiAoaUNvbG9yVHlwZSA9PSBDT0xPUlRZUEVfUkdCKQorCQl7CisJCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKDApLAorCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCb3JkZXJDb2xvcigxKSwKKwkJCQlwRm9ybUNvbnRyb2wtPkdldE9yaWdpbmFsQm9yZGVyQ29sb3IoMikpOworCQl9CisJCWVsc2UgaWYgKGlDb2xvclR5cGUgPT0gQ09MT1JUWVBFX0NNWUspCisJCXsKKwkJCWNvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfQ01ZSywgcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKDApLAorCQkJCXBGb3JtQ29udHJvbC0+R2V0T3JpZ2luYWxCb3JkZXJDb2xvcigxKSwKKwkJCQlwRm9ybUNvbnRyb2wtPkdldE9yaWdpbmFsQm9yZGVyQ29sb3IoMiksCisJCQkJcEZvcm1Db250cm9sLT5HZXRPcmlnaW5hbEJvcmRlckNvbG9yKDMpKTsKKwkJfQorCQllbHNlCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJQ0pTX0FycmF5IGNyQXJyYXkobV9pc29sYXRlKTsKKwkJY29sb3I6OkNvbnZlcnRQV0xDb2xvclRvQXJyYXkoY29sb3IsIGNyQXJyYXkpOworICAgICAgICB2cCAgPDwgIGNyQXJyYXk7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldFN0cm9rZUNvbG9yKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpzdHlsZShPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlDRlhfQnl0ZVN0cmluZyBjc0JDYXB0aW9uOworCQl2cCA+PiBjc0JDYXB0aW9uOworCisJCWlmIChtX2JEZWxheSkKKwkJeworCQkJQWRkRGVsYXlfU3RyaW5nKEZQX1NUWUxFLCBjc0JDYXB0aW9uKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCUZpZWxkOjpTZXRTdHlsZShtX3BEb2N1bWVudCwgbV9GaWVsZE5hbWUsIG1fbkZvcm1Db250cm9sSW5kZXgsIGNzQkNhcHRpb24pOworCQl9CQorCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfUkFESU9CVVRUT04gJiYgCisJCQlwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfQ0hFQ0tCT1gpCisJCQlyZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7CisJCWlmICghcEZvcm1Db250cm9sKSByZXR1cm4gRkFMU0U7CisKKwkJQ0ZYX1dpZGVTdHJpbmcgY3NXQ2FwdGlvbiA9IHBGb3JtQ29udHJvbC0+R2V0Tm9ybWFsQ2FwdGlvbigpOworCQlDRlhfQnl0ZVN0cmluZyBjc0JDYXB0aW9uOworCisJCXN3aXRjaCAoY3NXQ2FwdGlvblswXSkKKwkJeworCQkJY2FzZSBMJ2wnOgorCQkJCWNzQkNhcHRpb24gPSAiY2lyY2xlIjsKKwkJCQlicmVhazsKKwkJCWNhc2UgTCc4JzoKKwkJCQljc0JDYXB0aW9uID0gImNyb3NzIjsKKwkJCQlicmVhazsKKwkJCWNhc2UgTCd1JzoKKwkJCQljc0JDYXB0aW9uID0gImRpYW1vbmQiOworCQkJCWJyZWFrOworCQkJY2FzZSBMJ24nOgorCQkJCWNzQkNhcHRpb24gPSAic3F1YXJlIjsKKwkJCQlicmVhazsKKwkJCWNhc2UgTCdIJzoKKwkJCQljc0JDYXB0aW9uID0gInN0YXIiOworCQkJCWJyZWFrOworCQkJZGVmYXVsdDogLy9MJzQnCisJCQkJY3NCQ2FwdGlvbiA9ICJjaGVjayI7CisJCQkJYnJlYWs7CisJCX0KKwkJdnAgPDwgY3NCQ2FwdGlvbjsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKwordm9pZCBGaWVsZDo6U2V0U3R5bGUoQ1BERlNES19Eb2N1bWVudCogcERvY3VtZW50LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dGaWVsZE5hbWUsIGludCBuQ29udHJvbEluZGV4LCAKKwkJCQkJIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjpzdWJtaXROYW1lKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6dGV4dENvbG9yKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJCUNKU19BcnJheSBjckFycmF5KG1faXNvbGF0ZSk7CisJCWlmICghdnAuSXNBcnJheU9iamVjdCgpKXJldHVybiBGQUxTRTsKKwkJdnAgPj4gY3JBcnJheTsKKworCQlDUFdMX0NvbG9yIGNvbG9yOworCQljb2xvcjo6Q29udmVydEFycmF5VG9QV0xDb2xvcihjckFycmF5LCBjb2xvcik7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9Db2xvcihGUF9URVhUQ09MT1IsIGNvbG9yKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCUZpZWxkOjpTZXRUZXh0Q29sb3IobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBjb2xvcik7CisJCX0JCisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7CisJCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsKKwkJCisJCWludCBpQ29sb3JUeXBlOworCQlGWF9BUkdCIGNvbG9yOworCQlDUERGX0RlZmF1bHRBcHBlYXJhbmNlIEZpZWxkQXBwZWFyYW5jZSA9IHBGb3JtQ29udHJvbC0+R2V0RGVmYXVsdEFwcGVhcmFuY2UoKTsKKwkJRmllbGRBcHBlYXJhbmNlLkdldENvbG9yKGNvbG9yLCBpQ29sb3JUeXBlKTsKKwkJRlhfSU5UMzIgYSxyLGcsYjsKKwkJQXJnYkRlY29kZShjb2xvciwgYSwgciwgZywgYik7CisKKwkJQ1BXTF9Db2xvciBjclJldCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgciAvIDI1NS4wZiwKKwkJCQlnIC8gMjU1LjBmLAorCQkJCWIgLyAyNTUuMGYpOworCisJCWlmIChpQ29sb3JUeXBlID09IENPTE9SVFlQRV9UUkFOU1BBUkVOVCkKKwkJCWNyUmV0ID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfVFJBTlNQQVJFTlQpOworCisJCUNKU19BcnJheSBjckFycmF5KG1faXNvbGF0ZSk7CisJCWNvbG9yOjpDb252ZXJ0UFdMQ29sb3JUb0FycmF5KGNyUmV0LCBjckFycmF5KTsKKyAgICAgICAgdnAgIDw8ICBjckFycmF5OwkJCisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldFRleHRDb2xvcihDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQoreworCS8vTm90IHN1cHBvcnRlZC4KK30KKworRlhfQk9PTCBGaWVsZDo6dGV4dEZvbnQoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICghbV9iQ2FuU2V0KSByZXR1cm4gRkFMU0U7CisKKwkJQ0ZYX0J5dGVTdHJpbmcgY3NGb250TmFtZTsKKwkJdnAgPj4gY3NGb250TmFtZTsKKwkJaWYgKGNzRm9udE5hbWUuSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9TdHJpbmcoRlBfVEVYVEZPTlQsIGNzRm9udE5hbWUpOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldFRleHRGb250KG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgY3NGb250TmFtZSk7CisJCX0JCisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwkJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwkJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7CisJCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsKKworCQlpbnQgbkZpZWxkVHlwZSA9IHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpOworCisJCWlmIChuRmllbGRUeXBlID09IEZJRUxEVFlQRV9QVVNIQlVUVE9OIHx8IAorCQkJbkZpZWxkVHlwZSA9PSBGSUVMRFRZUEVfQ09NQk9CT1ggfHwgCisJCQluRmllbGRUeXBlID09IEZJRUxEVFlQRV9MSVNUQk9YIHx8CisJCQluRmllbGRUeXBlID09IEZJRUxEVFlQRV9URVhURklFTEQpCisJCXsKKwkJCUNQREZfRm9udCAqIHBGb250ID0gcEZvcm1Db250cm9sLT5HZXREZWZhdWx0Q29udHJvbEZvbnQoKTsKKwkJCWlmICghcEZvbnQpIHJldHVybiBGQUxTRTsKKworCQkJdnAgPDwgcEZvbnQtPkdldEJhc2VGb250KCk7CisJCX0KKwkJZWxzZQorCQkJcmV0dXJuIEZBTFNFOworCX0KKworCXJldHVybiBUUlVFOworfQorCit2b2lkIEZpZWxkOjpTZXRUZXh0Rm9udChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzdHJpbmcpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjp0ZXh0U2l6ZShPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlpbnQgblZQOworCQl2cCA+PiBuVlA7CisKKwkJaWYgKG1fYkRlbGF5KQorCQl7CisJCQlBZGREZWxheV9JbnQoRlBfVEVYVFNJWkUsIG5WUCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0VGV4dFNpemUobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBuVlApOworCQl9CQorCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCQlpZiAoIXBGb3JtQ29udHJvbClyZXR1cm4gRkFMU0U7CisKKwkJQ1BERl9EZWZhdWx0QXBwZWFyYW5jZSBGaWVsZEFwcGVhcmFuY2UgPSBwRm9ybUNvbnRyb2wtPkdldERlZmF1bHRBcHBlYXJhbmNlKCk7CisKKwkJQ0ZYX0J5dGVTdHJpbmcgY3NGb250TmFtZVRhZzsKKwkJRlhfRkxPQVQgZkZvbnRTaXplOworCQlGaWVsZEFwcGVhcmFuY2UuR2V0Rm9udChjc0ZvbnROYW1lVGFnLGZGb250U2l6ZSk7CisKKwkJdnAgPDwgKGludClmRm9udFNpemU7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldFRleHRTaXplKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCBpbnQgbkNvbnRyb2xJbmRleCwgaW50IG51bWJlcikKK3sKKwkvL05vdCBzdXBwb3J0ZWQuCit9CisKK0ZYX0JPT0wgRmllbGQ6OnR5cGUoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCWlmICghdnAuSXNHZXR0aW5nKCkpIHJldHVybiBGQUxTRTsKKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworIAlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwlzd2l0Y2ggKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpKQorCXsKKwkJY2FzZSBGSUVMRFRZUEVfVU5LTk9XTjoKKwkJCXZwIDw8IChGWF9MUENXU1RSKUwidW5rbm93biI7CisJCQlicmVhazsKKwkJY2FzZSBGSUVMRFRZUEVfUFVTSEJVVFRPTjoKKwkJCXZwIDw8IChGWF9MUENXU1RSKUwiYnV0dG9uIjsKKwkJCWJyZWFrOworCQljYXNlIEZJRUxEVFlQRV9DSEVDS0JPWDoKKwkJCXZwIDw8IChGWF9MUENXU1RSKUwiY2hlY2tib3giOworCQkJYnJlYWs7CisJCWNhc2UgRklFTERUWVBFX1JBRElPQlVUVE9OOgorCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJyYWRpb2J1dHRvbiI7CisJCQlicmVhazsKKwkJY2FzZSBGSUVMRFRZUEVfQ09NQk9CT1g6CisJCQl2cCA8PCAoRlhfTFBDV1NUUilMImNvbWJvYm94IjsKKwkJCWJyZWFrOworCQljYXNlIEZJRUxEVFlQRV9MSVNUQk9YOgorCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJsaXN0Ym94IjsKKwkJCWJyZWFrOworCQljYXNlIEZJRUxEVFlQRV9URVhURklFTEQ6CisJCQl2cCA8PCAoRlhfTFBDV1NUUilMInRleHQiOworCQkJYnJlYWs7CisJCWNhc2UgRklFTERUWVBFX1NJR05BVFVSRToKKwkJCXZwIDw8IChGWF9MUENXU1RSKUwic2lnbmF0dXJlIjsKKwkJCWJyZWFrOworCQlkZWZhdWx0IDoKKwkJCXZwIDw8IChGWF9MUENXU1RSKUwidW5rbm93biI7CisJCQlicmVhazsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6dXNlck5hbWUoT0JKX1BST1BfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworICAJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJaWYgKCFtX2JDYW5TZXQpIHJldHVybiBGQUxTRTsKKworCQlDRlhfV2lkZVN0cmluZyBzd05hbWU7CisJCXZwID4+IHN3TmFtZTsKKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X1dpZGVTdHJpbmcoRlBfVVNFUk5BTUUsIHN3TmFtZSk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlGaWVsZDo6U2V0VXNlck5hbWUobV9wRG9jdW1lbnQsIG1fRmllbGROYW1lLCBtX25Gb3JtQ29udHJvbEluZGV4LCBzd05hbWUpOworCQl9CQorCX0KKwllbHNlCisJeworCQlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwkJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwkJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworIAkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQl2cCA8PCAoQ0ZYX1dpZGVTdHJpbmcpcEZvcm1GaWVsZC0+R2V0QWx0ZXJuYXRlTmFtZSgpOworCX0KKworCXJldHVybiBUUlVFOworfQorCit2b2lkIEZpZWxkOjpTZXRVc2VyTmFtZShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzd0ZpZWxkTmFtZSwgaW50IG5Db250cm9sSW5kZXgsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCitGWF9CT09MIEZpZWxkOjp2YWx1ZShPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHZwLklzU2V0dGluZygpKQorCXsJCQorCQlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJCUNKU19XaWRlU3RyaW5nQXJyYXkgc3RyQXJyYXk7CisKKwkJaWYgKHZwLklzQXJyYXlPYmplY3QoKSkKKwkJeworCQkJQ0pTX0FycmF5IFZhbHVlQXJyYXkobV9pc29sYXRlKTsKKwkJCXZwLkNvbnZlcnRUb0FycmF5KFZhbHVlQXJyYXkpOworCQkJZm9yIChpbnQgaSA9IDAsc3ogPSBWYWx1ZUFycmF5LkdldExlbmd0aCgpOyBpIDwgc3o7IGkrKykKKwkJCXsKKwkJCQlDSlNfVmFsdWUgRWxlbWVudFZhbHVlKG1faXNvbGF0ZSk7CisJCQkJVmFsdWVBcnJheS5HZXRFbGVtZW50KGksIEVsZW1lbnRWYWx1ZSk7CisJCQkJc3RyQXJyYXkuQWRkKEVsZW1lbnRWYWx1ZS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKKwkJCX0KKwkJfQorCQllbHNlCisJCXsKKwkJCUNGWF9XaWRlU3RyaW5nIHN3VmFsdWU7CisJCQl2cCA+PiBzd1ZhbHVlOworCisJCQlzdHJBcnJheS5BZGQoc3dWYWx1ZSk7CisJCX0KKworCQlpZiAobV9iRGVsYXkpCisJCXsKKwkJCUFkZERlbGF5X1dpZGVTdHJpbmdBcnJheShGUF9WQUxVRSwgc3RyQXJyYXkpOworCQl9CisJCWVsc2UKKwkJeworCQkJRmllbGQ6OlNldFZhbHVlKG1fcERvY3VtZW50LCBtX0ZpZWxkTmFtZSwgbV9uRm9ybUNvbnRyb2xJbmRleCwgc3RyQXJyYXkpOworCQl9CisJfQorCWVsc2UKKwl7CisJCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCQlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCQlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisgCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisKKworCQlzd2l0Y2ggKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpKQorCQl7CisJCWNhc2UgRklFTERUWVBFX1BVU0hCVVRUT046CisJCQlyZXR1cm4gRkFMU0U7CisJCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOgorCQljYXNlIEZJRUxEVFlQRV9URVhURklFTEQ6CisJCQl7CisJCQkJQ0ZYX1dpZGVTdHJpbmcgc3dWYWx1ZSA9IHBGb3JtRmllbGQtPkdldFZhbHVlKCk7CisKKwkJCQlkb3VibGUgZFJldDsKKwkJCQlGWF9CT09MIGJEb3Q7CisJCQkJaWYgKENKU19QdWJsaWNNZXRob2RzOjpDb252ZXJ0U3RyaW5nVG9OdW1iZXIoc3dWYWx1ZSxkUmV0LGJEb3QpKQorCQkJCXsKKwkJCQkJaWYgKGJEb3QpCisJCQkJCQl2cCA8PCBkUmV0OworCQkJCQllbHNlCisJCQkJCQl2cCA8PCBkUmV0OworCQkJCX0KKwkJCQllbHNlCisJCQkJCXZwIDw8IHN3VmFsdWU7CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBGSUVMRFRZUEVfTElTVEJPWDoKKwkJCXsKKwkJCQlpZiAocEZvcm1GaWVsZC0+Q291bnRTZWxlY3RlZEl0ZW1zKCkgPiAxKQorCQkJCXsKKwkJCQkJQ0pTX0FycmF5IFZhbHVlQXJyYXkobV9pc29sYXRlKTsKKwkJCQkJQ0pTX1ZhbHVlIEVsZW1lbnRWYWx1ZShtX2lzb2xhdGUpOworCQkJCQlpbnQgaUluZGV4OworCQkJCQlmb3IgKGludCBpID0gMCwgc3ogPSBwRm9ybUZpZWxkLT5Db3VudFNlbGVjdGVkSXRlbXMoKTsgaSA8IHN6OyBpKyspCisJCQkJCXsKKwkJCQkJCWlJbmRleCA9IHBGb3JtRmllbGQtPkdldFNlbGVjdGVkSW5kZXgoaSk7CisJCQkJCQlFbGVtZW50VmFsdWUgPSBwRm9ybUZpZWxkLT5HZXRPcHRpb25WYWx1ZShpSW5kZXgpOworCQkJCQkJaWYgKEZYU1lTX3djc2xlbigoRlhfTFBDV1NUUilFbGVtZW50VmFsdWUub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSkgPT0gMCkKKwkJCQkJCQlFbGVtZW50VmFsdWUgPSBwRm9ybUZpZWxkLT5HZXRPcHRpb25MYWJlbChpSW5kZXgpOworCQkJCQkJVmFsdWVBcnJheS5TZXRFbGVtZW50KGksIEVsZW1lbnRWYWx1ZSk7CisJCQkJCX0KKwkJCQkJdnAgPDwgVmFsdWVBcnJheTsKKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJQ0ZYX1dpZGVTdHJpbmcgc3dWYWx1ZSA9IHBGb3JtRmllbGQtPkdldFZhbHVlKCk7CisJCQkJCisJCQkJCWRvdWJsZSBkUmV0OworCQkJCQlGWF9CT09MIGJEb3Q7CisJCQkJCWlmIChDSlNfUHVibGljTWV0aG9kczo6Q29udmVydFN0cmluZ1RvTnVtYmVyKHN3VmFsdWUsZFJldCxiRG90KSkKKwkJCQkJeworCQkJCQkJaWYgKGJEb3QpCisJCQkJCQkJdnAgPDwgZFJldDsKKwkJCQkJCWVsc2UKKwkJCQkJCQl2cCA8PCBkUmV0OworCQkJCQl9CisJCQkJCWVsc2UKKwkJCQkJCXZwIDw8IHN3VmFsdWU7CQorCQkJCX0KKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIEZJRUxEVFlQRV9DSEVDS0JPWDoKKwkJY2FzZSBGSUVMRFRZUEVfUkFESU9CVVRUT046CisJCQl7CisJCQkJRlhfQk9PTCBiRmluZCA9IEZBTFNFOworCQkJCWZvciAoaW50IGkgPSAwICwgc3ogPSBwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGkgPCBzejsgaSsrKQorCQkJCXsKKwkJCQkJaWYgKHBGb3JtRmllbGQtPkdldENvbnRyb2woaSktPklzQ2hlY2tlZCgpKQorCQkJCQl7CisJCQkJCQlDRlhfV2lkZVN0cmluZyBzd1ZhbHVlID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChpKS0+R2V0RXhwb3J0VmFsdWUoKTsKKwkJCQkJCQorCQkJCQkJZG91YmxlIGRSZXQ7CisJCQkJCQlGWF9CT09MIGJEb3Q7CisJCQkJCQlpZiAoQ0pTX1B1YmxpY01ldGhvZHM6OkNvbnZlcnRTdHJpbmdUb051bWJlcihzd1ZhbHVlLGRSZXQsYkRvdCkpCisJCQkJCQl7CisJCQkJCQkJaWYgKGJEb3QpCisJCQkJCQkJCXZwIDw8IGRSZXQ7CisJCQkJCQkJZWxzZQorCQkJCQkJCQl2cCA8PCBkUmV0OworCQkJCQkJfQorCQkJCQkJZWxzZQorCQkJCQkJCXZwIDw8IHN3VmFsdWU7CisKKwkJCQkJCWJGaW5kID0gVFJVRTsKKwkJCQkJCWJyZWFrOworCQkJCQl9CisJCQkJCWVsc2UKKwkJCQkJCWNvbnRpbnVlOworCQkJCX0KKwkJCQlpZiAoIWJGaW5kKQorCQkJCQl2cCA8PCAoRlhfTFBDV1NUUilMIk9mZiI7CQkJCQkKKwkJCX0KKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJdnAgPDwgcEZvcm1GaWVsZC0+R2V0VmFsdWUoKTsKKwkJCWJyZWFrOworCQl9CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgRmllbGQ6OlNldFZhbHVlKENQREZTREtfRG9jdW1lbnQqIHBEb2N1bWVudCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3RmllbGROYW1lLCAKKwkJCQkJIGludCBuQ29udHJvbEluZGV4LCBjb25zdCBDSlNfV2lkZVN0cmluZ0FycmF5JiBzdHJBcnJheSkKK3sKKwlBU1NFUlQocERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKHN0ckFycmF5LkdldFNpemUoKSA8IDEpIHJldHVybjsKKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMocERvY3VtZW50LCBzd0ZpZWxkTmFtZSwgRmllbGRBcnJheSk7CisKKwlmb3IgKGludCBpPTAsaXN6PUZpZWxkQXJyYXkuR2V0U2l6ZSgpOyBpPGlzejsgaSsrKQorCXsKKwkJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KGkpOworCQlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCQlpZiAocEZvcm1GaWVsZC0+R2V0RnVsbE5hbWUoKS5Db21wYXJlKHN3RmllbGROYW1lKSAhPSAwKQorCQkJY29udGludWU7CisKKwkJc3dpdGNoIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSkKKwkJeworCQljYXNlIEZJRUxEVFlQRV9URVhURklFTEQ6CisJCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOgorCQkJaWYgKHBGb3JtRmllbGQtPkdldFZhbHVlKCkgIT0gc3RyQXJyYXkuR2V0QXQoMCkpCisJCQl7CisJCQkJQ0ZYX1dpZGVTdHJpbmcgV2lkZVN0cmluZyA9IHN0ckFycmF5LkdldEF0KDApOworCQkJCXBGb3JtRmllbGQtPlNldFZhbHVlKHN0ckFycmF5LkdldEF0KDApLCBUUlVFKTsJCisJCQkJVXBkYXRlRm9ybUZpZWxkKHBEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgRkFMU0UsIFRSVUUpOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgRklFTERUWVBFX0NIRUNLQk9YOiAvL21hbnRpczogMDAwNDQ5MworCQljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoKKwkJCXsKKwkJCQlpZiAocEZvcm1GaWVsZC0+R2V0VmFsdWUoKSAhPSBzdHJBcnJheS5HZXRBdCgwKSkKKwkJCQl7CisJCQkJCXBGb3JtRmllbGQtPlNldFZhbHVlKHN0ckFycmF5LkdldEF0KDApLCBUUlVFKTsJCisJCQkJCVVwZGF0ZUZvcm1GaWVsZChwRG9jdW1lbnQsIHBGb3JtRmllbGQsIFRSVUUsIEZBTFNFLCBUUlVFKTsKKwkJCQl9CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBGSUVMRFRZUEVfTElTVEJPWDoKKwkJCXsKKwkJCQlGWF9CT09MIGJNb2RpZmllZCA9IEZBTFNFOworCisJCQkJZm9yIChpbnQgaT0wLHN6PXN0ckFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQorCQkJCXsKKwkJCQkJaW50IGlJbmRleCA9IHBGb3JtRmllbGQtPkZpbmRPcHRpb24oc3RyQXJyYXkuR2V0QXQoaSkpOworCisJCQkJCWlmICghcEZvcm1GaWVsZC0+SXNJdGVtU2VsZWN0ZWQoaUluZGV4KSkKKwkJCQkJeworCQkJCQkJYk1vZGlmaWVkID0gVFJVRTsKKwkJCQkJCWJyZWFrOworCQkJCQl9CisJCQkJfQorCisJCQkJaWYgKGJNb2RpZmllZCkKKwkJCQl7CisJCQkJCXBGb3JtRmllbGQtPkNsZWFyU2VsZWN0aW9uKFRSVUUpOworCQkJCQlmb3IgKGludCBpPTAsc3o9c3RyQXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQkJCXsKKwkJCQkJCWludCBpSW5kZXggPSBwRm9ybUZpZWxkLT5GaW5kT3B0aW9uKHN0ckFycmF5LkdldEF0KGkpKTsKKwkJCQkJCXBGb3JtRmllbGQtPlNldEl0ZW1TZWxlY3Rpb24oaUluZGV4LCBUUlVFLCBUUlVFKTsKKwkJCQkJfQorCisJCQkJCVVwZGF0ZUZvcm1GaWVsZChwRG9jdW1lbnQsIHBGb3JtRmllbGQsIFRSVUUsIEZBTFNFLCBUUlVFKTsKKwkJCQl9CisJCQl9CisJCQlicmVhazsKKwkJZGVmYXVsdDoJCQkJCisJCQlicmVhazsKKwkJfQorCX0KK30KKworRlhfQk9PTCBGaWVsZDo6dmFsdWVBc1N0cmluZyhPQkpfUFJPUF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaWYgKCF2cC5Jc0dldHRpbmcoKSkgcmV0dXJuIEZBTFNFOworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisgICAJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9QVVNIQlVUVE9OKQorCQlyZXR1cm4gRkFMU0U7CisKKwlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX0NIRUNLQk9YKQorCXsKKwkJaWYoIXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkgcmV0dXJuIEZBTFNFOworCisJCWlmIChwRm9ybUZpZWxkLT5HZXRDb250cm9sKDApLT5Jc0NoZWNrZWQoKSkKKwkJCXZwIDw8IChGWF9MUENXU1RSKUwiWWVzIjsKKwkJZWxzZQorCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJPZmYiOworCX0KKwllbHNlIGlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfUkFESU9CVVRUT04gJiYgIShwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfUkFESU9TSU5VTklTT04pKQorCXsKKwkJZm9yIChpbnQgaT0wLCBzej1wRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCk7IGk8c3o7IGkrKykKKwkJeworCQkJaWYgKHBGb3JtRmllbGQtPkdldENvbnRyb2woaSktPklzQ2hlY2tlZCgpKQorCQkJeworCQkJCXZwIDw8IChGWF9MUENXU1RSKXBGb3JtRmllbGQtPkdldENvbnRyb2woaSktPkdldEV4cG9ydFZhbHVlKCk7CisJCQkJYnJlYWs7CisJCQl9CisJCQllbHNlCisJCQkJdnAgPDwgKEZYX0xQQ1dTVFIpTCJPZmYiOworCQl9CisJfQorCWVsc2UgaWYgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9MSVNUQk9YICYmIChwRm9ybUZpZWxkLT5Db3VudFNlbGVjdGVkSXRlbXMoKSA+IDEpKQorCXsKKwkJdnAgPDwgKEZYX0xQQ1dTVFIpTCIiOworCX0KKwllbHNlCisJCXZwIDw8IChGWF9MUENXU1RSKXBGb3JtRmllbGQtPkdldFZhbHVlKCk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0ZYX0JPT0wgRmllbGQ6OmJyb3dzZUZvckZpbGVUb1N1Ym1pdChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLCBGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisgCUNQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7CisgCUFTU0VSVChwQXBwICE9IE5VTEwpOworCisJaWYgKChwRm9ybUZpZWxkLT5HZXRGaWVsZEZsYWdzKCkgJiBGSUVMREZMQUdfRklMRVNFTEVDVCkgJiYgCisJCShwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfVEVYVEZJRUxEKSkKKwl7CQkKKwkJQ0ZYX1dpZGVTdHJpbmcgd3NGaWxlTmFtZSA9IHBBcHAtPkpTX2ZpZWxkQnJvd3NlKCk7CisJCWlmKCF3c0ZpbGVOYW1lLklzRW1wdHkoKSkKKwkJeworIAkJCXBGb3JtRmllbGQtPlNldFZhbHVlKHdzRmlsZU5hbWUpOworIAkJCVVwZGF0ZUZvcm1GaWVsZChtX3BEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgVFJVRSwgVFJVRSk7CisgICAgICAgICB9CisJfQorCWVsc2UgCisJCXJldHVybiBGQUxTRTsKKworCXJldHVybiBUUlVFOworfQorCisKK0ZYX0JPT0wgRmllbGQ6OmJ1dHRvbkdldENhcHRpb24oT0JKX01FVEhPRF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaW50IG5mYWNlID0gMDsKKwlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOworCWlmICggaVNpemUgPj0gMSkKKwkJbmZhY2UgPSAoRlhfSU5UMzIpIHBhcmFtc1swXTsKKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKwkKKwlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1BVU0hCVVRUT04pCisJCXJldHVybiBGQUxTRTsKKworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsKKwkKKwlpZiAobmZhY2UgPT0gMCkKKwkJdlJldCA9IHBGb3JtQ29udHJvbC0+R2V0Tm9ybWFsQ2FwdGlvbigpOworCWVsc2UgaWYgKG5mYWNlID09IDEpCisJCXZSZXQgPSBwRm9ybUNvbnRyb2wtPkdldERvd25DYXB0aW9uKCk7CisJZWxzZSBpZiAobmZhY2UgPT0gMikKKwkJdlJldCA9IHBGb3JtQ29udHJvbC0+R2V0Um9sbG92ZXJDYXB0aW9uKCk7CisJZWxzZQorCQlyZXR1cm4gRkFMU0U7CisKKwlyZXR1cm4gVFJVRTsKK30KKworLy8jcHJhZ21hIHdhcm5pbmcoZGlzYWJsZTogNDgwMCkKKworRlhfQk9PTCBGaWVsZDo6YnV0dG9uR2V0SWNvbihPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpbnQgbmZhY2UgPSAwOworCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7CisJaWYgKCBpU2l6ZSA+PSAxKQorCQluZmFjZSA9IChGWF9JTlQzMikgcGFyYW1zWzBdOworCQorCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKwkKKwlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1BVU0hCVVRUT04pCisJCXJldHVybiBGQUxTRTsKKworCUNQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ29udHJvbCA9IEdldFNtYXJ0RmllbGRDb250cm9sKHBGb3JtRmllbGQpOworCWlmICghcEZvcm1Db250cm9sKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKwkKKwlKU0ZYT2JqZWN0IHBPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBwQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJJY29uIikpOworCUFTU0VSVChwT2JqLklzRW1wdHkoKSA9PSBGQUxTRSk7CisJCisJQ0pTX0ljb24qIHBKU19JY29uID0gKENKU19JY29uKilKU19HZXRQcml2YXRlKHBPYmopOworCUFTU0VSVChwSlNfSWNvbiAhPSBOVUxMKTsKKworCUljb24qIHBJY29uID0gKEljb24qKXBKU19JY29uLT5HZXRFbWJlZE9iamVjdCgpOworCUFTU0VSVChwSWNvbiAhPSBOVUxMKTsKKworCUNQREZfU3RyZWFtKiBwSWNvblN0cmVhbSA9IE5VTEw7CisJaWYgKG5mYWNlID09IDApCisJCXBJY29uU3RyZWFtID0gcEZvcm1Db250cm9sLT5HZXROb3JtYWxJY29uKCk7CisJZWxzZSBpZiAobmZhY2UgPT0gMSkKKwkJcEljb25TdHJlYW0gPSBwRm9ybUNvbnRyb2wtPkdldERvd25JY29uKCk7CisJZWxzZSBpZiAobmZhY2UgPT0gMikKKwkJcEljb25TdHJlYW0gPSBwRm9ybUNvbnRyb2wtPkdldFJvbGxvdmVySWNvbigpOworCWVsc2UKKwkJcmV0dXJuIEZBTFNFOworCisJcEljb24tPlNldFN0cmVhbShwSWNvblN0cmVhbSk7CisJdlJldCA9IHBKU19JY29uOworCisJcmV0dXJuIFRSVUU7Cit9CisKKy8vI3ByYWdtYSB3YXJuaW5nKGRlZmF1bHQ6IDQ4MDApCisKK0ZYX0JPT0wgRmllbGQ6OmJ1dHRvbkltcG9ydEljb24oT0JKX01FVEhPRF9QQVJBTVMpCit7CisjaWYgMCAgCisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCWlmICghcEZvcm1GaWVsZClyZXR1cm4gRkFMU0U7CisKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwRW52ID0gbV9wRG9jdW1lbnQtPkdldEVudigpOworCUFTU0VSVChwRW52KTsKKworCUNGWF9XaWRlU3RyaW5nIHNJY29uRmlsZU5hbWUgPSBwRW52LT5KU19maWVsZEJyb3dzZSgpOworCWlmIChzSWNvbkZpbGVOYW1lLklzRW1wdHkoKSkgCisJeworCQl2UmV0ID0gMTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKW1fcERvY3VtZW50LT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCUNQREZfU3RyZWFtKiBwU3RyZWFtID0gcEludGVyRm9ybS0+TG9hZEltYWdlRnJvbUZpbGUoc0ljb25GaWxlTmFtZSk7CisJaWYgKCFwU3RyZWFtKSAKKwl7CisJCXZSZXQgPSAtMTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCisJQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1Db250cm9sID0gR2V0U21hcnRGaWVsZENvbnRyb2wocEZvcm1GaWVsZCk7CisJaWYgKCFwRm9ybUNvbnRyb2wpcmV0dXJuIEZBTFNFOworCisJcEZvcm1Db250cm9sLT5TZXROb3JtYWxJY29uKHBTdHJlYW0pOworCVVwZGF0ZUZvcm1Db250cm9sKG1fcERvY3VtZW50LCBwRm9ybUNvbnRyb2wsIFRSVUUsIFRSVUUsIFRSVUUpOworCisJdlJldCA9IDA7CisjZW5kaWYgLy8gMAorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIEZpZWxkOjpidXR0b25TZXRDYXB0aW9uKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBGaWVsZDo6YnV0dG9uU2V0SWNvbihPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OmNoZWNrVGhpc0JveChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJaW50IGlTaXplID0gcGFyYW1zLnNpemUoKTsKKwlpbnQgbldpZGdldCA9IC0xOworCWlmICggaVNpemUgPj0gMSkKKwkJbldpZGdldD0gKEZYX0lOVDMyKSBwYXJhbXNbMF07CisJZWxzZQorCQlyZXR1cm4gRkFMU0U7CisJRlhfQk9PTCBiQ2hlY2tpdCA9IFRSVUU7CisJaWYgKCBpU2l6ZSA+PSAyKQorCQliQ2hlY2tpdCA9IHBhcmFtc1sxXTsKKworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCQorCWlmIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSAhPSBGSUVMRFRZUEVfQ0hFQ0tCT1ggJiYgcEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgIT0gRklFTERUWVBFX1JBRElPQlVUVE9OKQorCQlyZXR1cm4gRkFMU0U7CQorCWlmKG5XaWRnZXQgPDAgfHwgbldpZGdldCA+PSBwRm9ybUZpZWxkLT5Db3VudENvbnRyb2xzKCkpCisJCXJldHVybiBGQUxTRTsKKwlpZiAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX1JBRElPQlVUVE9OKQorCQlwRm9ybUZpZWxkLT5DaGVja0NvbnRyb2wobldpZGdldCwgYkNoZWNraXQsIFRSVUUpOworCWVsc2UKKwkJcEZvcm1GaWVsZC0+Q2hlY2tDb250cm9sKG5XaWRnZXQsIGJDaGVja2l0LCBUUlVFKTsKKworCVVwZGF0ZUZvcm1GaWVsZChtX3BEb2N1bWVudCwgcEZvcm1GaWVsZCwgVFJVRSwgVFJVRSwgVFJVRSk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6Y2xlYXJJdGVtcyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6ZGVmYXVsdElzQ2hlY2tlZChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpZiAoIW1fYkNhblNldCkgcmV0dXJuIEZBTFNFOworCisJaW50IGlTaXplID0gcGFyYW1zLnNpemUoKTsKKwlpbnQgbldpZGdldCA9IC0xOworCWlmICggaVNpemUgPj0gMSkKKwkJbldpZGdldD0gKEZYX0lOVDMyKSBwYXJhbXNbMF07CisJZWxzZQorCQlyZXR1cm4gRkFMU0U7CisJLy9GWF9CT09MIGJJc0RlZmF1bHRDaGVja2VkID0gVFJVRTsKKwkvL2lmICggaVNpemUgPj0gMikKKwkvLwliSXNEZWZhdWx0Q2hlY2tlZCA9ICBwYXJhbXNbMV07CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwlpZihuV2lkZ2V0IDwwIHx8IG5XaWRnZXQgPj0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpKQorCXsKKwkJdlJldCA9IEZBTFNFOworCQlyZXR1cm4gRkFMU0U7CisJfQorCWlmICgocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX0NIRUNLQk9YKQorCQl8fCAocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX1JBRElPQlVUVE9OKSkKKwl7CisKKwkJdlJldCA9IFRSVUU7CisJfQorCWVsc2UKKwkJdlJldCA9IEZBTFNFOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OmRlbGV0ZUl0ZW1BdChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworaW50IEpTX0NPTVBBUkVTVFJJTkcoQ0ZYX1dpZGVTdHJpbmcqIHBzMSwgQ0ZYX1dpZGVTdHJpbmcqIHBzMikKK3sKKwlBU1NFUlQocHMxICE9IE5VTEwpOworCUFTU0VSVChwczIgIT0gTlVMTCk7CisKKwlyZXR1cm4gcHMxLT5Db21wYXJlKCpwczIpOworfQorCisKK0ZYX0JPT0wgRmllbGQ6OmdldEFycmF5KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUFTU0VSVChtX3BEb2N1bWVudCAhPSBOVUxMKTsKKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCUNHV19BcnJheVRlbXBsYXRlPENGWF9XaWRlU3RyaW5nKj4gc3dTb3J0OworCisJZm9yIChpbnQgaT0wLHN6PUZpZWxkQXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoaSk7CisJCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJCXN3U29ydC5BZGQobmV3IENGWF9XaWRlU3RyaW5nKHBGb3JtRmllbGQtPkdldEZ1bGxOYW1lKCkpKTsKKwkJCisJfQorCXN3U29ydC5Tb3J0KEpTX0NPTVBBUkVTVFJJTkcpOworCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCUNKU19BcnJheSBGb3JtRmllbGRBcnJheShtX2lzb2xhdGUpOworCWZvciAoaW50IGo9MCxqc3ogPSBzd1NvcnQuR2V0U2l6ZSgpOyBqPGpzejsgaisrKQorCXsKKwkJQ0ZYX1dpZGVTdHJpbmcqIHBTdHIgPSBzd1NvcnQuR2V0QXQoaik7CisKKwkJSlNGWE9iamVjdCBwT2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgcENvbnRleHQsIEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiRmllbGQiKSk7CisJCUFTU0VSVChwT2JqLklzRW1wdHkoKSA9PSBGQUxTRSk7CisKKwkJQ0pTX0ZpZWxkKiBwSlNGaWVsZCA9IChDSlNfRmllbGQqKUpTX0dldFByaXZhdGUocE9iaik7CisJCUFTU0VSVChwSlNGaWVsZCAhPSBOVUxMKTsKKworCQlGaWVsZCogcEZpZWxkID0gKEZpZWxkKilwSlNGaWVsZC0+R2V0RW1iZWRPYmplY3QoKTsgCisJCUFTU0VSVChwRmllbGQgIT0gTlVMTCk7CisKKwkJcEZpZWxkLT5BdHRhY2hGaWVsZCh0aGlzLT5tX3BKU0RvYywgKnBTdHIpOworCQorCQlDSlNfVmFsdWUgRm9ybUZpZWxkVmFsdWUobV9pc29sYXRlKTsKKwkJRm9ybUZpZWxkVmFsdWUgPSBwSlNGaWVsZDsKKwkJRm9ybUZpZWxkQXJyYXkuU2V0RWxlbWVudChqLCBGb3JtRmllbGRWYWx1ZSk7CisKKwkJZGVsZXRlIHBTdHI7CisJfQorCisJdlJldCA9IEZvcm1GaWVsZEFycmF5OworCXN3U29ydC5SZW1vdmVBbGwoKTsKKwlyZXR1cm4gVFJVRTsKK30KKwkKK0ZYX0JPT0wgRmllbGQ6OmdldEl0ZW1BdChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpbnQgbklkeCA9IC0xOworCWlmIChwYXJhbXMuc2l6ZSgpID49MSkKKwkJbklkeCA9IChGWF9JTlQzMikgcGFyYW1zWzBdOworCUZYX0JPT0wgYkV4cG9ydCA9IFRSVUU7CisJaW50IGlTaXplID0gcGFyYW1zLnNpemUoKTsKKwlpZiAoIGlTaXplID49IDIpCisJeworCQliRXhwb3J0ID0oRlhfQk9PTCkgcGFyYW1zWzFdOworCX0KKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCWlmICgocEZvcm1GaWVsZC0+R2V0RmllbGRUeXBlKCkgPT0gRklFTERUWVBFX0xJU1RCT1gpCisJCXx8IChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfQ09NQk9CT1gpKQorCXsKKwkJaWYgKG5JZHggPT0gLTEgfHwgbklkeCA+IHBGb3JtRmllbGQtPkNvdW50T3B0aW9ucygpKQorCQkJbklkeCA9IHBGb3JtRmllbGQtPkNvdW50T3B0aW9ucygpIC0xOworCQlpZiAoYkV4cG9ydCkKKwkJeworCQkJQ0ZYX1dpZGVTdHJpbmcgc3RydmFsID0gcEZvcm1GaWVsZC0+R2V0T3B0aW9uVmFsdWUobklkeCk7CisJCQlpZiAoc3RydmFsLklzRW1wdHkoKSkKKwkJCQl2UmV0ID0gcEZvcm1GaWVsZC0+R2V0T3B0aW9uTGFiZWwobklkeCk7CisJCQllbHNlCisJCQkJdlJldCA9IHN0cnZhbDsKKwkJfQorCQllbHNlCisJCQl2UmV0ID0gcEZvcm1GaWVsZC0+R2V0T3B0aW9uTGFiZWwobklkeCk7CisJfQorCWVsc2UKKwkJcmV0dXJuIEZBTFNFOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OmdldExvY2soT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIEZpZWxkOjppbnNlcnRJdGVtQXQoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OmlzQm94Q2hlY2tlZChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlBU1NFUlQobV9wRG9jdW1lbnQgIT0gTlVMTCk7CisKKwlpbnQgbkluZGV4ID0gLTE7CisJaWYgKHBhcmFtcy5zaXplKCkgPj0xKQorCQluSW5kZXggPSAoRlhfSU5UMzIpIHBhcmFtc1swXTsKKworCUNGWF9QdHJBcnJheSBGaWVsZEFycmF5OworCUdldEZvcm1GaWVsZHMobV9GaWVsZE5hbWUsRmllbGRBcnJheSk7CisJaWYgKEZpZWxkQXJyYXkuR2V0U2l6ZSgpIDw9IDApIHJldHVybiBGQUxTRTsKKworCUNQREZfRm9ybUZpZWxkKiBwRm9ybUZpZWxkID0gKENQREZfRm9ybUZpZWxkKilGaWVsZEFycmF5LkVsZW1lbnRBdCgwKTsKKwlBU1NFUlQocEZvcm1GaWVsZCAhPSBOVUxMKTsKKworCWlmKG5JbmRleCA8MCB8fCBuSW5kZXggPj0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpKQorCXsKKwkJdlJldCA9IEZBTFNFOworCQlyZXR1cm4gRkFMU0U7CisJfQorCisJaWYgKChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfQ0hFQ0tCT1gpCisJCXx8IChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSA9PSBGSUVMRFRZUEVfUkFESU9CVVRUT04pKQorCXsKKwkJaWYgKHBGb3JtRmllbGQtPkdldENvbnRyb2wobkluZGV4KS0+SXNDaGVja2VkKCkgIT0wICkKKwkJCXZSZXQgPSBUUlVFOworCQllbHNlCisJCQl2UmV0ID0gRkFMU0U7CisJfQorCWVsc2UKKwkJdlJldCA9IEZBTFNFOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OmlzRGVmYXVsdENoZWNrZWQoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJaW50IG5JbmRleCA9IC0xOworCWlmIChwYXJhbXMuc2l6ZSgpID49MSkKKwkJbkluZGV4ID0gKEZYX0lOVDMyKSBwYXJhbXNbMF07CisKKwlDRlhfUHRyQXJyYXkgRmllbGRBcnJheTsKKwlHZXRGb3JtRmllbGRzKG1fRmllbGROYW1lLEZpZWxkQXJyYXkpOworCWlmIChGaWVsZEFycmF5LkdldFNpemUoKSA8PSAwKSByZXR1cm4gRkFMU0U7CisKKwlDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IChDUERGX0Zvcm1GaWVsZCopRmllbGRBcnJheS5FbGVtZW50QXQoMCk7CisJQVNTRVJUKHBGb3JtRmllbGQgIT0gTlVMTCk7CisKKwlpZihuSW5kZXggPDAgfHwgbkluZGV4ID49IHBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKSkKKwl7CisJCXZSZXQgPSBGQUxTRTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKwlpZiAoKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9DSEVDS0JPWCkKKwkJfHwgKHBGb3JtRmllbGQtPkdldEZpZWxkVHlwZSgpID09IEZJRUxEVFlQRV9SQURJT0JVVFRPTikpCisJeworCQlpZiAocEZvcm1GaWVsZC0+R2V0Q29udHJvbChuSW5kZXgpLT5Jc0RlZmF1bHRDaGVja2VkKCkgIT0gMCkKKwkJCXZSZXQgPSBUUlVFOworCQllbHNlCisJCQl2UmV0ID0gRkFMU0U7CisJfQorCWVsc2UKKwkJdlJldCA9IEZBTFNFOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnNldEFjdGlvbihPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBGaWVsZDo6c2V0Rm9jdXMoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJQVNTRVJUKG1fcERvY3VtZW50ICE9IE5VTEwpOworCisJQ0ZYX1B0ckFycmF5IEZpZWxkQXJyYXk7CisJR2V0Rm9ybUZpZWxkcyhtX0ZpZWxkTmFtZSxGaWVsZEFycmF5KTsKKwlpZiAoRmllbGRBcnJheS5HZXRTaXplKCkgPD0gMCkgcmV0dXJuIEZBTFNFOworCisJQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSAoQ1BERl9Gb3JtRmllbGQqKUZpZWxkQXJyYXkuRWxlbWVudEF0KDApOworCUFTU0VSVChwRm9ybUZpZWxkICE9IE5VTEwpOworCisJRlhfSU5UMzIgbkNvdW50ID0gcEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOworCisJaWYgKG5Db3VudCA8IDEpIHJldHVybiBGQUxTRTsKKworCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKiltX3BEb2N1bWVudC0+R2V0SW50ZXJGb3JtKCk7CisJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7CisKKwlDUERGU0RLX1dpZGdldCogcFdpZGdldCA9IE5VTEw7CisJaWYgKG5Db3VudCA9PSAxKQorCXsJCisJCXBXaWRnZXQgPSBwSW50ZXJGb3JtLT5HZXRXaWRnZXQocEZvcm1GaWVsZC0+R2V0Q29udHJvbCgwKSk7CisJfQorCWVsc2UKKwl7CisJCUNQREZEb2NfRW52aXJvbm1lbnQqIHBFbnYgPSBtX3BEb2N1bWVudC0+R2V0RW52KCk7CisJCUFTU0VSVChwRW52KTsKKwkJQ1BERl9QYWdlKiBwUGFnZSA9IChDUERGX1BhZ2UqKXBFbnYtPkZGSV9HZXRDdXJyZW50UGFnZShtX3BEb2N1bWVudC0+R2V0RG9jdW1lbnQoKSk7CisJCWlmKCFwUGFnZSkKKwkJCXJldHVybiBGQUxTRTsKKwkJaWYgKENQREZTREtfUGFnZVZpZXcqIHBDdXJQYWdlVmlldyA9IG1fcERvY3VtZW50LT5HZXRQYWdlVmlldyhwUGFnZSkpCisJCXsKKwkJCWZvciAoRlhfSU5UMzIgaT0wOyBpPG5Db3VudDsgaSsrKQorCQkJeworCQkJCWlmIChDUERGU0RLX1dpZGdldCogcFRlbXBXaWRnZXQgPSAgcEludGVyRm9ybS0+R2V0V2lkZ2V0KHBGb3JtRmllbGQtPkdldENvbnRyb2woaSkpKQorCQkJCXsJCQkJCisJCQkJCWlmIChwVGVtcFdpZGdldC0+R2V0UERGUGFnZSgpID09IHBDdXJQYWdlVmlldy0+R2V0UERGUGFnZSgpKQorCQkJCQl7CisJCQkJCQlwV2lkZ2V0ID0gcFRlbXBXaWRnZXQ7CisJCQkJCQlicmVhazsKKwkJCQkJfQorCQkJCX0KKwkJCX0KKwkJfQorCX0KKworCWlmIChwV2lkZ2V0KQorCXsKKwkJbV9wRG9jdW1lbnQtPlNldEZvY3VzQW5ub3QocFdpZGdldCk7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnNldEl0ZW1zKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIEZpZWxkOjpzZXRMb2NrKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBGaWVsZDo6c2lnbmF0dXJlR2V0TW9kaWZpY2F0aW9ucyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnNpZ25hdHVyZUdldFNlZWRWYWx1ZShPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgRmllbGQ6OnNpZ25hdHVyZUluZm8oT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIEZpZWxkOjpzaWduYXR1cmVTZXRTZWVkVmFsdWUoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIEZpZWxkOjpzaWduYXR1cmVTaWduKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBGaWVsZDo6c2lnbmF0dXJlVmFsaWRhdGUoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIEZpZWxkOjpzb3VyY2UoT0JKX1BST1BfUEFSQU1TKQoreworCWlmICh2cC5Jc0dldHRpbmcoKSkKKwl7CisJCXZwIDw8IChDSlNfT2JqZWN0KilOVUxMOworCX0KKworCXJldHVybiBUUlVFOworfQorCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIGRlbGF5IC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCit2b2lkIEZpZWxkOjpBZGREZWxheV9JbnQoZW51bSBGSUVMRF9QUk9QIHByb3AsIEZYX0lOVDMyIG4pCit7CisJQVNTRVJUKG1fcEpTRG9jICE9IE5VTEwpOworCisJQ0pTX0RlbGF5RGF0YSogcE5ld0RhdGEgPSBuZXcgQ0pTX0RlbGF5RGF0YTsKKwlwTmV3RGF0YS0+c0ZpZWxkTmFtZSA9IG1fRmllbGROYW1lOworCXBOZXdEYXRhLT5uQ29udHJvbEluZGV4ID0gbV9uRm9ybUNvbnRyb2xJbmRleDsKKwlwTmV3RGF0YS0+ZVByb3AgPSBwcm9wOworCXBOZXdEYXRhLT5udW0gPSBuOworCisJbV9wSlNEb2MtPkFkZERlbGF5RGF0YShwTmV3RGF0YSk7Cit9CisKK3ZvaWQgRmllbGQ6OkFkZERlbGF5X0Jvb2woZW51bSBGSUVMRF9QUk9QIHByb3AsYm9vbCBiKQoreworCUFTU0VSVChtX3BKU0RvYyAhPSBOVUxMKTsKKworCUNKU19EZWxheURhdGEqIHBOZXdEYXRhID0gbmV3IENKU19EZWxheURhdGE7CisJcE5ld0RhdGEtPnNGaWVsZE5hbWUgPSBtX0ZpZWxkTmFtZTsKKwlwTmV3RGF0YS0+bkNvbnRyb2xJbmRleCA9IG1fbkZvcm1Db250cm9sSW5kZXg7CisJcE5ld0RhdGEtPmVQcm9wID0gcHJvcDsKKwlwTmV3RGF0YS0+YiA9IGI7CisKKwltX3BKU0RvYy0+QWRkRGVsYXlEYXRhKHBOZXdEYXRhKTsKK30KKwordm9pZCBGaWVsZDo6QWRkRGVsYXlfU3RyaW5nKGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc3RyaW5nKQoreworCUFTU0VSVChtX3BKU0RvYyAhPSBOVUxMKTsKKworCUNKU19EZWxheURhdGEqIHBOZXdEYXRhID0gbmV3IENKU19EZWxheURhdGE7CisJcE5ld0RhdGEtPnNGaWVsZE5hbWUgPSBtX0ZpZWxkTmFtZTsKKwlwTmV3RGF0YS0+bkNvbnRyb2xJbmRleCA9IG1fbkZvcm1Db250cm9sSW5kZXg7CisJcE5ld0RhdGEtPmVQcm9wID0gcHJvcDsKKwlwTmV3RGF0YS0+c3RyaW5nID0gc3RyaW5nOworCisJbV9wSlNEb2MtPkFkZERlbGF5RGF0YShwTmV3RGF0YSk7Cit9CisKK3ZvaWQgRmllbGQ6OkFkZERlbGF5X1dpZGVTdHJpbmcoZW51bSBGSUVMRF9QUk9QIHByb3AsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpCit7CisJQVNTRVJUKG1fcEpTRG9jICE9IE5VTEwpOworCisJQ0pTX0RlbGF5RGF0YSogcE5ld0RhdGEgPSBuZXcgQ0pTX0RlbGF5RGF0YTsKKwlwTmV3RGF0YS0+c0ZpZWxkTmFtZSA9IG1fRmllbGROYW1lOworCXBOZXdEYXRhLT5uQ29udHJvbEluZGV4ID0gbV9uRm9ybUNvbnRyb2xJbmRleDsKKwlwTmV3RGF0YS0+ZVByb3AgPSBwcm9wOworCXBOZXdEYXRhLT53aWRlc3RyaW5nID0gc3RyaW5nOworCisJbV9wSlNEb2MtPkFkZERlbGF5RGF0YShwTmV3RGF0YSk7Cit9CisKK3ZvaWQgRmllbGQ6OkFkZERlbGF5X1JlY3QoZW51bSBGSUVMRF9QUk9QIHByb3AsIGNvbnN0IENQREZfUmVjdCYgcmVjdCkKK3sKKwlBU1NFUlQobV9wSlNEb2MgIT0gTlVMTCk7CisKKwlDSlNfRGVsYXlEYXRhKiBwTmV3RGF0YSA9IG5ldyBDSlNfRGVsYXlEYXRhOworCXBOZXdEYXRhLT5zRmllbGROYW1lID0gbV9GaWVsZE5hbWU7CisJcE5ld0RhdGEtPm5Db250cm9sSW5kZXggPSBtX25Gb3JtQ29udHJvbEluZGV4OworCXBOZXdEYXRhLT5lUHJvcCA9IHByb3A7CisJcE5ld0RhdGEtPnJlY3QgPSByZWN0OworCisJbV9wSlNEb2MtPkFkZERlbGF5RGF0YShwTmV3RGF0YSk7Cit9CisKK3ZvaWQgRmllbGQ6OkFkZERlbGF5X0NvbG9yKGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikKK3sKKwlBU1NFUlQobV9wSlNEb2MgIT0gTlVMTCk7CisKKwlDSlNfRGVsYXlEYXRhKiBwTmV3RGF0YSA9IG5ldyBDSlNfRGVsYXlEYXRhOworCXBOZXdEYXRhLT5zRmllbGROYW1lID0gbV9GaWVsZE5hbWU7CisJcE5ld0RhdGEtPm5Db250cm9sSW5kZXggPSBtX25Gb3JtQ29udHJvbEluZGV4OworCXBOZXdEYXRhLT5lUHJvcCA9IHByb3A7CisJcE5ld0RhdGEtPmNvbG9yID0gY29sb3I7CisKKwltX3BKU0RvYy0+QWRkRGVsYXlEYXRhKHBOZXdEYXRhKTsKK30KKwordm9pZCBGaWVsZDo6QWRkRGVsYXlfV29yZEFycmF5KGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDRlhfRFdvcmRBcnJheSYgYXJyYXkpCit7CisJQVNTRVJUKG1fcEpTRG9jICE9IE5VTEwpOworCisJQ0pTX0RlbGF5RGF0YSogcE5ld0RhdGEgPSBuZXcgQ0pTX0RlbGF5RGF0YTsKKwlwTmV3RGF0YS0+c0ZpZWxkTmFtZSA9IG1fRmllbGROYW1lOworCXBOZXdEYXRhLT5uQ29udHJvbEluZGV4ID0gbV9uRm9ybUNvbnRyb2xJbmRleDsKKwlwTmV3RGF0YS0+ZVByb3AgPSBwcm9wOworCisJZm9yIChpbnQgaT0wLHN6PWFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQorCQlwTmV3RGF0YS0+d29yZGFycmF5LkFkZChhcnJheS5HZXRBdChpKSk7CisKKwltX3BKU0RvYy0+QWRkRGVsYXlEYXRhKHBOZXdEYXRhKTsKK30KKwordm9pZCBGaWVsZDo6QWRkRGVsYXlfV2lkZVN0cmluZ0FycmF5KGVudW0gRklFTERfUFJPUCBwcm9wLCBjb25zdCBDSlNfV2lkZVN0cmluZ0FycmF5JiBhcnJheSkKK3sKKwlBU1NFUlQobV9wSlNEb2MgIT0gTlVMTCk7CisKKwlDSlNfRGVsYXlEYXRhKiBwTmV3RGF0YSA9IG5ldyBDSlNfRGVsYXlEYXRhOworCXBOZXdEYXRhLT5zRmllbGROYW1lID0gbV9GaWVsZE5hbWU7CisJcE5ld0RhdGEtPm5Db250cm9sSW5kZXggPSBtX25Gb3JtQ29udHJvbEluZGV4OworCXBOZXdEYXRhLT5lUHJvcCA9IHByb3A7CisJZm9yIChpbnQgaT0wLHN6PWFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQorCQlwTmV3RGF0YS0+d2lkZXN0cmluZ2FycmF5LkFkZChhcnJheS5HZXRBdChpKSk7CisKKwltX3BKU0RvYy0+QWRkRGVsYXlEYXRhKHBOZXdEYXRhKTsKK30KKwordm9pZCBGaWVsZDo6RG9EZWxheShDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIENKU19EZWxheURhdGEqIHBEYXRhKQoreworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisJQVNTRVJUKHBEYXRhICE9IE5VTEwpOworCisJc3dpdGNoIChwRGF0YS0+ZVByb3ApCisJeworCWNhc2UgRlBfQUxJR05NRU5UOgorCQlGaWVsZDo6U2V0QWxpZ25tZW50KHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+c3RyaW5nKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9CT1JERVJTVFlMRToKKwkJRmllbGQ6OlNldEJvcmRlclN0eWxlKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+c3RyaW5nKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9CVVRUT05BTElHTlg6CisJCUZpZWxkOjpTZXRCdXR0b25BbGlnblgocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5udW0pOworCQlicmVhazsKKwljYXNlIEZQX0JVVFRPTkFMSUdOWToKKwkJRmllbGQ6OlNldEJ1dHRvbkFsaWduWShwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7CisJCWJyZWFrOworCWNhc2UgRlBfQlVUVE9ORklUQk9VTkRTOgorCQlGaWVsZDo6U2V0QnV0dG9uRml0Qm91bmRzKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+Yik7CisJCWJyZWFrOworCWNhc2UgRlBfQlVUVE9OUE9TSVRJT046CisJCUZpZWxkOjpTZXRCdXR0b25Qb3NpdGlvbihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7CisJCWJyZWFrOworCWNhc2UgRlBfQlVUVE9OU0NBTEVIT1c6CisJCUZpZWxkOjpTZXRCdXR0b25TY2FsZUhvdyhwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7CisJCWJyZWFrOworCWNhc2UgRlBfQlVUVE9OU0NBTEVXSEVOOgorCQlGaWVsZDo6U2V0QnV0dG9uU2NhbGVXaGVuKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+bnVtKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9DQUxDT1JERVJJTkRFWDoKKwkJRmllbGQ6OlNldENhbGNPcmRlckluZGV4KHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+bnVtKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9DSEFSTElNSVQ6CisJCUZpZWxkOjpTZXRDaGFyTGltaXQocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5udW0pOworCQlicmVhazsKKwljYXNlIEZQX0NPTUI6CisJCUZpZWxkOjpTZXRDb21iKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+Yik7CisJCWJyZWFrOworCWNhc2UgRlBfQ09NTUlUT05TRUxDSEFOR0U6CisJCUZpZWxkOjpTZXRDb21taXRPblNlbENoYW5nZShwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmIpOworCQlicmVhazsKKwljYXNlIEZQX0NVUlJFTlRWQUxVRUlORElDRVM6CisJCUZpZWxkOjpTZXRDdXJyZW50VmFsdWVJbmRpY2VzKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+d29yZGFycmF5KTsKKwkJYnJlYWs7CisJY2FzZSBGUF9ERUZBVUxUVkFMVUU6CisJCUZpZWxkOjpTZXREZWZhdWx0VmFsdWUocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT53aWRlc3RyaW5nKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9ET05PVFNDUk9MTDoKKwkJRmllbGQ6OlNldERvTm90U2Nyb2xsKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+Yik7CisJCWJyZWFrOworCWNhc2UgRlBfRElTUExBWToKKwkJRmllbGQ6OlNldERpc3BsYXkocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5udW0pOworCQlicmVhazsKKwljYXNlIEZQX0ZJTExDT0xPUjoKKwkJRmllbGQ6OlNldEZpbGxDb2xvcihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmNvbG9yKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9ISURERU46CisJCUZpZWxkOjpTZXRIaWRkZW4ocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5iKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9ISUdITElHSFQ6CisJCUZpZWxkOjpTZXRIaWdobGlnaHQocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5zdHJpbmcpOworCQlicmVhazsKKwljYXNlIEZQX0xJTkVXSURUSDoKKwkJRmllbGQ6OlNldExpbmVXaWR0aChwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7CisJCWJyZWFrOworCWNhc2UgRlBfTVVMVElMSU5FOgorCQlGaWVsZDo6U2V0TXVsdGlsaW5lKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+Yik7CisJCWJyZWFrOworCWNhc2UgRlBfTVVMVElQTEVTRUxFQ1RJT046CisJCUZpZWxkOjpTZXRNdWx0aXBsZVNlbGVjdGlvbihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmIpOworCQlicmVhazsKKwljYXNlIEZQX1BBU1NXT1JEOgorCQlGaWVsZDo6U2V0UGFzc3dvcmQocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5iKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9SRUNUOgorCQlGaWVsZDo6U2V0UmVjdChwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPnJlY3QpOworCQlicmVhazsKKwljYXNlIEZQX1JJQ0hURVhUOgorCQlGaWVsZDo6U2V0UmljaFRleHQocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5iKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9SSUNIVkFMVUU6CisJCWJyZWFrOworCWNhc2UgRlBfUk9UQVRJT046CisJCUZpZWxkOjpTZXRSb3RhdGlvbihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7CisJCWJyZWFrOworCWNhc2UgRlBfU1RST0tFQ09MT1I6CisJCUZpZWxkOjpTZXRTdHJva2VDb2xvcihwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPmNvbG9yKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9TVFlMRToKKwkJRmllbGQ6OlNldFN0eWxlKHBEb2N1bWVudCwgcERhdGEtPnNGaWVsZE5hbWUsIHBEYXRhLT5uQ29udHJvbEluZGV4LCBwRGF0YS0+c3RyaW5nKTsKKwkJYnJlYWs7CisJY2FzZSBGUF9URVhUQ09MT1I6CisJCUZpZWxkOjpTZXRUZXh0Q29sb3IocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT5jb2xvcik7CisJCWJyZWFrOworCWNhc2UgRlBfVEVYVEZPTlQ6CisJCUZpZWxkOjpTZXRUZXh0Rm9udChwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPnN0cmluZyk7CisJCWJyZWFrOworCWNhc2UgRlBfVEVYVFNJWkU6CisJCUZpZWxkOjpTZXRUZXh0U2l6ZShwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPm51bSk7CisJCWJyZWFrOworCWNhc2UgRlBfVVNFUk5BTUU6CisJCUZpZWxkOjpTZXRVc2VyTmFtZShwRG9jdW1lbnQsIHBEYXRhLT5zRmllbGROYW1lLCBwRGF0YS0+bkNvbnRyb2xJbmRleCwgcERhdGEtPndpZGVzdHJpbmcpOworCQlicmVhazsKKwljYXNlIEZQX1ZBTFVFOgorCQlGaWVsZDo6U2V0VmFsdWUocERvY3VtZW50LCBwRGF0YS0+c0ZpZWxkTmFtZSwgcERhdGEtPm5Db250cm9sSW5kZXgsIHBEYXRhLT53aWRlc3RyaW5nYXJyYXkpOworCQlicmVhazsKKwl9Cit9CisKKyNkZWZpbmUgSlNfRklFTERfTUlOV0lEVEgJMQorI2RlZmluZSBKU19GSUVMRF9NSU5IRUlHSFQJMQorCit2b2lkIEZpZWxkOjpBZGRGaWVsZChDUERGU0RLX0RvY3VtZW50KiBwRG9jdW1lbnQsIGludCBuUGFnZUluZGV4LCBpbnQgbkZpZWxkVHlwZSwKKwkJCQkJCQljb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUsIGNvbnN0IENQREZfUmVjdCYgcmNDb29yZHMpCit7CisJLy9Ob3Qgc3VwcG9ydGVkLgorfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0ljb24uY3BwIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9JY29uLmNwcAppbmRleCA0MThmY2Q1Li4yODY5ODBjIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0ljb24uY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSWNvbi5jcHAKQEAgLTEsNjcgKzEsNjcgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSWNvbi5oIg0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSWNvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19JY29uKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19JY29uKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShuYW1lKQ0KLUVORF9KU19TVEFUSUNfUFJPUCgpDQotDQotQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfSWNvbikgDQotRU5EX0pTX1NUQVRJQ19NRVRIT0QoKQ0KLQ0KLUlNUExFTUVOVF9KU19DTEFTUyhDSlNfSWNvbixJY29uKQ0KLQ0KLUljb246Okljb24oQ0pTX09iamVjdCogcEpTT2JqZWN0KSA6IENKU19FbWJlZE9iaihwSlNPYmplY3QpLA0KLQltX3BJY29uU3RyZWFtKE5VTEwpLA0KLQltX3N3SWNvbk5hbWUoTCIiKQ0KLXsNCi19DQotDQotSWNvbjo6fkljb24oKQ0KLXsNCi0NCi19DQotDQotdm9pZCBJY29uOjpTZXRTdHJlYW0oQ1BERl9TdHJlYW0qIHBJY29uU3RyZWFtKQ0KLXsNCi0JaWYocEljb25TdHJlYW0pDQotCQltX3BJY29uU3RyZWFtID0gcEljb25TdHJlYW07DQotfQ0KLQ0KLUNQREZfU3RyZWFtKiBJY29uOjpHZXRTdHJlYW0oKQ0KLXsNCi0JcmV0dXJuIG1fcEljb25TdHJlYW07DQotfQ0KLQ0KLXZvaWQgSWNvbjo6U2V0SWNvbk5hbWUoQ0ZYX1dpZGVTdHJpbmcgbmFtZSkNCi17DQotCW1fc3dJY29uTmFtZSA9IG5hbWU7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIEljb246OkdldEljb25OYW1lKCkNCi17DQotCXJldHVybiBtX3N3SWNvbk5hbWU7DQotfQ0KLQ0KLUZYX0JPT0wgSWNvbjo6bmFtZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZighdnAuSXNHZXR0aW5nKCkpcmV0dXJuIEZBTFNFOw0KLQ0KLQl2cCA8PCBtX3N3SWNvbk5hbWU7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JY29uLmgiCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSWNvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0JFR0lOX0pTX1NUQVRJQ19DT05TVChDSlNfSWNvbikKK0VORF9KU19TVEFUSUNfQ09OU1QoKQorCitCRUdJTl9KU19TVEFUSUNfUFJPUChDSlNfSWNvbikKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShuYW1lKQorRU5EX0pTX1NUQVRJQ19QUk9QKCkKKworQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfSWNvbikgCitFTkRfSlNfU1RBVElDX01FVEhPRCgpCisKK0lNUExFTUVOVF9KU19DTEFTUyhDSlNfSWNvbixJY29uKQorCitJY29uOjpJY29uKENKU19PYmplY3QqIHBKU09iamVjdCkgOiBDSlNfRW1iZWRPYmoocEpTT2JqZWN0KSwKKwltX3BJY29uU3RyZWFtKE5VTEwpLAorCW1fc3dJY29uTmFtZShMIiIpCit7Cit9CisKK0ljb246On5JY29uKCkKK3sKKworfQorCit2b2lkIEljb246OlNldFN0cmVhbShDUERGX1N0cmVhbSogcEljb25TdHJlYW0pCit7CisJaWYocEljb25TdHJlYW0pCisJCW1fcEljb25TdHJlYW0gPSBwSWNvblN0cmVhbTsKK30KKworQ1BERl9TdHJlYW0qIEljb246OkdldFN0cmVhbSgpCit7CisJcmV0dXJuIG1fcEljb25TdHJlYW07Cit9CisKK3ZvaWQgSWNvbjo6U2V0SWNvbk5hbWUoQ0ZYX1dpZGVTdHJpbmcgbmFtZSkKK3sKKwltX3N3SWNvbk5hbWUgPSBuYW1lOworfQorCitDRlhfV2lkZVN0cmluZyBJY29uOjpHZXRJY29uTmFtZSgpCit7CisJcmV0dXJuIG1fc3dJY29uTmFtZTsKK30KKworRlhfQk9PTCBJY29uOjpuYW1lKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZighdnAuSXNHZXR0aW5nKCkpcmV0dXJuIEZBTFNFOworCisJdnAgPDwgbV9zd0ljb25OYW1lOworCXJldHVybiBUUlVFOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX0NvbnRleHQuY3BwIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9KU19Db250ZXh0LmNwcAppbmRleCBjMGQ0ZTA4Li5lMzRmZmI1IDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX0NvbnRleHQuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSlNfQ29udGV4dC5jcHAKQEAgLTEsMzY0ICsxLDM2NCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIg0KLS8vI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19SZXNNZ3IuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvcmVzb3VyY2UuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfQ29udGV4dCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNKU19Db250ZXh0OjpDSlNfQ29udGV4dChDSlNfUnVudGltZSogcFJ1bnRpbWUpIDogCQ0KLQltX3BSdW50aW1lKHBSdW50aW1lKSwNCi0JbV9iQnVzeShGQUxTRSksDQotCW1fYk1zZ0JveEVuYWJsZShUUlVFKQ0KLXsNCi0JbV9wRXZlbnRIYW5kbGVyID0gbmV3IENKU19FdmVudEhhbmRsZXIodGhpcyk7DQotfQ0KLQ0KLUNKU19Db250ZXh0Ojp+Q0pTX0NvbnRleHQodm9pZCkNCi17DQotCWlmIChtX3BFdmVudEhhbmRsZXIpDQotCXsNCi0JCWRlbGV0ZSBtX3BFdmVudEhhbmRsZXI7DQotCQltX3BFdmVudEhhbmRsZXIgPSBOVUxMOw0KLQl9DQotfQ0KLQ0KLUNQREZTREtfRG9jdW1lbnQqIENKU19Db250ZXh0OjpHZXRSZWFkZXJEb2N1bWVudCgpDQotew0KLQlBU1NFUlQobV9wUnVudGltZSAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIG1fcFJ1bnRpbWUtPkdldFJlYWRlckRvY3VtZW50KCk7DQotfQ0KLQ0KLUNQREZEb2NfRW52aXJvbm1lbnQqIENKU19Db250ZXh0OjpHZXRSZWFkZXJBcHAoKQ0KLXsNCi0JQVNTRVJUKG1fcFJ1bnRpbWUgIT0gTlVMTCk7DQotCQ0KLQlyZXR1cm4gbV9wUnVudGltZS0+R2V0UmVhZGVyQXBwKCk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX0NvbnRleHQ6OkRvSm9iKGludCBuTW9kZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNjcmlwdCwgQ0ZYX1dpZGVTdHJpbmcmIGluZm8pDQotew0KLQlpZiAobV9iQnVzeSkNCi0JewkJDQotCQlpbmZvID0gSlNHZXRTdHJpbmdGcm9tSUQodGhpcywgSURTX1NUUklOR19KU0JVU1kpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9CQ0KLQ0KLQltX2JCdXN5ID0gVFJVRTsNCi0NCi0JQVNTRVJUKG1fcFJ1bnRpbWUgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXItPklzVmFsaWQoKSk7DQotDQotCWlmICghbV9wUnVudGltZS0+QWRkRXZlbnRUb0xvb3AobV9wRXZlbnRIYW5kbGVyLT5UYXJnZXROYW1lKCksIG1fcEV2ZW50SGFuZGxlci0+RXZlbnRUeXBlKCkpKQ0KLQl7DQotCQlpbmZvID0gSlNHZXRTdHJpbmdGcm9tSUQodGhpcywgSURTX1NUUklOR19KU0VWRU5UKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlGWEpTRXJyIGVycm9yID17TlVMTCxOVUxMLCAwfTsNCi0JaW50IG5SZXQgPSAwOwkNCi0NCi0JdHJ5DQotCXsJDQotCQlpZiAoc2NyaXB0LkdldExlbmd0aCgpID4gMCkNCi0JCXsNCi0JCQlpZiAobk1vZGUgPT0gMCkNCi0JCQl7CQkNCi0JCQkJblJldCA9IEpTX0V4ZWN1dGUoKm1fcFJ1bnRpbWUsIHRoaXMsIHNjcmlwdCwgc2NyaXB0LkdldExlbmd0aCgpLCAmZXJyb3IpOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQluUmV0ID0gSlNfUGFyc2UoKm1fcFJ1bnRpbWUsIHRoaXMsIHNjcmlwdCwgc2NyaXB0LkdldExlbmd0aCgpLCAmZXJyb3IpOw0KLQkJCX0NCi0JCX0NCi0NCi0JCWlmIChuUmV0IDwgMCkNCi0JCXsNCi0JCQlDRlhfV2lkZVN0cmluZyBzTGluZTsNCi0JCQlzTGluZS5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCJbIExpbmU6ICUwNWQgeyAlcyB9IF0gOiAlcyIsZXJyb3IubGlubnVtLTEsZXJyb3Iuc3JjbGluZSxlcnJvci5tZXNzYWdlKTsNCi0NCi0vLwkJCVRSQUNFKEwiLyogLS0tLS0tLS0tLS0tLS0gSlMgRXJyb3IgLS0tLS0tLS0tLS0tLS0gKi9cbiIpOw0KLS8vCQkJVFJBQ0Uoc0xpbmUpOw0KLS8vCQkJVFJBQ0UoTCJcbiIpOw0KLQkJCS8vQ0ZYX0J5dGVTdHJpbmcgc1RlbXAgPSBDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoZXJyb3IubWVzc2FnZSk7DQotCQkJaW5mbyArPSBzTGluZTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlpbmZvID0gSlNHZXRTdHJpbmdGcm9tSUQodGhpcywgSURTX1NUUklOR19SVU4pOw0KLQkJfQkJDQotDQotCX0NCi0JY2F0Y2ggKC4uLikNCi0Jew0KLQkJaW5mbyA9IEpTR2V0U3RyaW5nRnJvbUlEKHRoaXMsIElEU19TVFJJTkdfVU5IQU5ETEVEKTsNCi0JCW5SZXQgPSAtMTsNCi0JfQ0KLQ0KLQltX3BSdW50aW1lLT5SZW1vdmVFdmVudEluTG9vcChtX3BFdmVudEhhbmRsZXItPlRhcmdldE5hbWUoKSwgbV9wRXZlbnRIYW5kbGVyLT5FdmVudFR5cGUoKSk7DQotDQotCW1fcEV2ZW50SGFuZGxlci0+RGVzdHJveSgpOw0KLQltX2JCdXN5ID0gRkFMU0U7CQ0KLQ0KLQlyZXR1cm4gblJldCA+PSAwOw0KLX0NCi0NCi1GWF9CT09MIENKU19Db250ZXh0OjpSdW5TY3JpcHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNjcmlwdCwgQ0ZYX1dpZGVTdHJpbmcmIGluZm8pDQotew0KLQl2ODo6SXNvbGF0ZTo6U2NvcGUgaXNvbGF0ZV9zY29wZShtX3BSdW50aW1lLT5HZXRJc29sYXRlKCkpOw0KLQl2ODo6SGFuZGxlU2NvcGUgaGFuZGxlX3Njb3BlKG1fcFJ1bnRpbWUtPkdldElzb2xhdGUoKSk7DQotCXY4OjpMb2NhbDx2ODo6Q29udGV4dD4gY29udGV4dCA9IG1fcFJ1bnRpbWUtPk5ld0pTQ29udGV4dCgpOw0KLQl2ODo6Q29udGV4dDo6U2NvcGUgY29udGV4dF9zY29wZShjb250ZXh0KTsNCi0NCi0JcmV0dXJuIERvSm9iKDAsIHNjcmlwdCwgaW5mbyk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX0NvbnRleHQ6OkNvbXBpbGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNjcmlwdCwgQ0ZYX1dpZGVTdHJpbmcmIGluZm8pDQotew0KLQl2ODo6SXNvbGF0ZTo6U2NvcGUgaXNvbGF0ZV9zY29wZShtX3BSdW50aW1lLT5HZXRJc29sYXRlKCkpOw0KLQl2ODo6SGFuZGxlU2NvcGUgaGFuZGxlX3Njb3BlKG1fcFJ1bnRpbWUtPkdldElzb2xhdGUoKSk7DQotCXY4OjpMb2NhbDx2ODo6Q29udGV4dD4gY29udGV4dCA9IG1fcFJ1bnRpbWUtPk5ld0pTQ29udGV4dCgpOw0KLQl2ODo6Q29udGV4dDo6U2NvcGUgY29udGV4dF9zY29wZShjb250ZXh0KTsNCi0NCi0JcmV0dXJuIERvSm9iKDEsIHNjcmlwdCwgaW5mbyk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uQXBwX0luaXQoKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkFwcF9Jbml0KCk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uRG9jX09wZW4oQ1BERlNES19Eb2N1bWVudCogcERvYywgY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJnN0clRhcmdldE5hbWUpDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uRG9jX09wZW4ocERvYyxzdHJUYXJnZXROYW1lKTsNCi19DQotDQotdm9pZCBDSlNfQ29udGV4dDo6T25Eb2NfV2lsbFByaW50KENQREZTREtfRG9jdW1lbnQqIHBEb2MpDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uRG9jX1dpbGxQcmludChwRG9jKTsNCi19DQotDQotdm9pZCBDSlNfQ29udGV4dDo6T25Eb2NfRGlkUHJpbnQoQ1BERlNES19Eb2N1bWVudCogcERvYykNCi17DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7DQotCW1fcEV2ZW50SGFuZGxlci0+T25Eb2NfRGlkUHJpbnQocERvYyk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uRG9jX1dpbGxTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uRG9jX1dpbGxTYXZlKHBEb2MpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkRvY19EaWRTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uRG9jX0RpZFNhdmUocERvYyk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uRG9jX1dpbGxDbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkRvY19XaWxsQ2xvc2UocERvYyk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uUGFnZV9PcGVuKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uUGFnZV9PcGVuKHBUYXJnZXQpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPblBhZ2VfQ2xvc2UoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCkNCi17DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7DQotCW1fcEV2ZW50SGFuZGxlci0+T25QYWdlX0Nsb3NlKHBUYXJnZXQpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPblBhZ2VfSW5WaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uUGFnZV9JblZpZXcocFRhcmdldCk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uUGFnZV9PdXRWaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uUGFnZV9PdXRWaWV3KHBUYXJnZXQpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX01vdXNlRG93bihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX01vdXNlRG93bihiTW9kaWZpZXIsIGJTaGlmdCwgcFRhcmdldCk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uRmllbGRfTW91c2VFbnRlcihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX01vdXNlRW50ZXIoYk1vZGlmaWVyLCBiU2hpZnQsIHBUYXJnZXQpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX01vdXNlRXhpdChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX01vdXNlRXhpdChiTW9kaWZpZXIsIGJTaGlmdCwgcFRhcmdldCk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uRmllbGRfTW91c2VVcChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX01vdXNlVXAoYk1vZGlmaWVyLCBiU2hpZnQsIHBUYXJnZXQpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBWYWx1ZSkNCi17DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7DQotCW1fcEV2ZW50SGFuZGxlci0+T25GaWVsZF9Gb2N1cyhiTW9kaWZpZXIsIGJTaGlmdCwgcFRhcmdldCwgVmFsdWUpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX0JsdXIoYk1vZGlmaWVyLCBiU2hpZnQsIHBUYXJnZXQsIFZhbHVlKTsNCi19DQotDQotdm9pZCBDSlNfQ29udGV4dDo6T25GaWVsZF9DYWxjdWxhdGUoQ1BERl9Gb3JtRmllbGQqIHBTb3VyY2UsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wmIGJSYykNCi17DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7DQotCW1fcEV2ZW50SGFuZGxlci0+T25GaWVsZF9DYWxjdWxhdGUocFNvdXJjZSwgcFRhcmdldCwgVmFsdWUsIGJSYyk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uRmllbGRfRm9ybWF0KGludCBuQ29tbWl0S2V5LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0KQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX0Zvcm1hdChuQ29tbWl0S2V5LCBwVGFyZ2V0LCBWYWx1ZSwgYldpbGxDb21taXQpOw0KLX0NCi0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX0tleXN0cm9rZShpbnQgbkNvbW1pdEtleSwgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LA0KLQkJCQkJCQkJCUZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLCBpbnQgJm5TZWxFbmQsaW50ICZuU2VsU3RhcnQsDQotCQkJCQkJCQkJRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsDQotCQkJCQkJCQkJRlhfQk9PTCBiV2lsbENvbW1pdCwgRlhfQk9PTCBiRmllbGRGdWxsLCBGWF9CT09MJiBiUmMpDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uRmllbGRfS2V5c3Ryb2tlKG5Db21taXRLZXksIHN0ckNoYW5nZSwgc3RyQ2hhbmdlRXgsIGJLZXlEb3duLA0KLQkJYk1vZGlmaWVyLCBuU2VsRW5kLCBuU2VsU3RhcnQsIGJTaGlmdCwgcFRhcmdldCwgVmFsdWUsIGJXaWxsQ29tbWl0LCBiRmllbGRGdWxsLCBiUmMpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX1ZhbGlkYXRlKENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0ckNoYW5nZUV4LA0KLQkJCQkJCQkJICAgRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwNCi0JCQkJCQkJCSAgIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCYgYlJjKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX1ZhbGlkYXRlKHN0ckNoYW5nZSwgc3RyQ2hhbmdlRXgsIGJLZXlEb3duLCBiTW9kaWZpZXIsIGJTaGlmdCwgcFRhcmdldCwgVmFsdWUsIGJSYyk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uU2NyZWVuX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7DQotCW1fcEV2ZW50SGFuZGxlci0+T25TY3JlZW5fRm9jdXMoYk1vZGlmaWVyLCBiU2hpZnQsIHBTY3JlZW4pOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPblNjcmVlbl9CbHVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7DQotCW1fcEV2ZW50SGFuZGxlci0+T25TY3JlZW5fQmx1cihiTW9kaWZpZXIsIGJTaGlmdCwgcFNjcmVlbik7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uU2NyZWVuX09wZW4oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PblNjcmVlbl9PcGVuKGJNb2RpZmllciwgYlNoaWZ0LCBwU2NyZWVuKTsNCi19DQotDQotdm9pZCBDSlNfQ29udGV4dDo6T25TY3JlZW5fQ2xvc2UoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PblNjcmVlbl9DbG9zZShiTW9kaWZpZXIsIGJTaGlmdCwgcFNjcmVlbik7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uU2NyZWVuX01vdXNlRG93bihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uU2NyZWVuX01vdXNlRG93bihiTW9kaWZpZXIsIGJTaGlmdCwgcFNjcmVlbik7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uU2NyZWVuX01vdXNlVXAoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PblNjcmVlbl9Nb3VzZVVwKGJNb2RpZmllciwgYlNoaWZ0LCBwU2NyZWVuKTsNCi19DQotDQotdm9pZCBDSlNfQ29udGV4dDo6T25TY3JlZW5fTW91c2VFbnRlcihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uU2NyZWVuX01vdXNlRW50ZXIoYk1vZGlmaWVyLCBiU2hpZnQsIHBTY3JlZW4pOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPblNjcmVlbl9Nb3VzZUV4aXQoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PblNjcmVlbl9Nb3VzZUV4aXQoYk1vZGlmaWVyLCBiU2hpZnQsIHBTY3JlZW4pOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPblNjcmVlbl9JblZpZXcoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PblNjcmVlbl9JblZpZXcoYk1vZGlmaWVyLCBiU2hpZnQsIHBTY3JlZW4pOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPblNjcmVlbl9PdXRWaWV3KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7DQotCW1fcEV2ZW50SGFuZGxlci0+T25TY3JlZW5fT3V0VmlldyhiTW9kaWZpZXIsIGJTaGlmdCwgcFNjcmVlbik7DQotfQ0KLQ0KLXZvaWQgQ0pTX0NvbnRleHQ6Ok9uQm9va21hcmtfTW91c2VVcChDUERGX0Jvb2ttYXJrKiBwQm9va01hcmspDQotew0KLQlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOw0KLQltX3BFdmVudEhhbmRsZXItPk9uQm9va21hcmtfTW91c2VVcChwQm9va01hcmspOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkxpbmtfTW91c2VVcChDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkxpbmtfTW91c2VVcChwVGFyZ2V0KTsNCi19DQotDQotdm9pZCBDSlNfQ29udGV4dDo6T25Db25zb2xlX0V4ZWMoKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkNvbnNvbGVfRXhlYygpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbkV4dGVybmFsX0V4ZWMoKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5PbkV4dGVybmFsX0V4ZWMoKTsNCi19DQotDQotdm9pZCBDSlNfQ29udGV4dDo6T25CYXRjaEV4ZWMoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCkNCi17DQotCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CQ0KLQltX3BFdmVudEhhbmRsZXItPk9uQmF0Y2hFeGVjKHBUYXJnZXQpOw0KLX0NCi0NCi12b2lkIENKU19Db250ZXh0OjpPbk1lbnVfRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0LGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJUYXJnZXROYW1lKQ0KLXsNCi0JQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0JbV9wRXZlbnRIYW5kbGVyLT5Pbk1lbnVfRXhlYyhwVGFyZ2V0LCBzdHJUYXJnZXROYW1lKTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiCisvLyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUmVzTWdyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRXZlbnRIYW5kbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvcmVzb3VyY2UuaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX0NvbnRleHQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0pTX0NvbnRleHQ6OkNKU19Db250ZXh0KENKU19SdW50aW1lKiBwUnVudGltZSkgOiAJCisJbV9wUnVudGltZShwUnVudGltZSksCisJbV9iQnVzeShGQUxTRSksCisJbV9iTXNnQm94RW5hYmxlKFRSVUUpCit7CisJbV9wRXZlbnRIYW5kbGVyID0gbmV3IENKU19FdmVudEhhbmRsZXIodGhpcyk7Cit9CisKK0NKU19Db250ZXh0Ojp+Q0pTX0NvbnRleHQodm9pZCkKK3sKKwlpZiAobV9wRXZlbnRIYW5kbGVyKQorCXsKKwkJZGVsZXRlIG1fcEV2ZW50SGFuZGxlcjsKKwkJbV9wRXZlbnRIYW5kbGVyID0gTlVMTDsKKwl9Cit9CisKK0NQREZTREtfRG9jdW1lbnQqIENKU19Db250ZXh0OjpHZXRSZWFkZXJEb2N1bWVudCgpCit7CisJQVNTRVJUKG1fcFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlyZXR1cm4gbV9wUnVudGltZS0+R2V0UmVhZGVyRG9jdW1lbnQoKTsKK30KKworQ1BERkRvY19FbnZpcm9ubWVudCogQ0pTX0NvbnRleHQ6OkdldFJlYWRlckFwcCgpCit7CisJQVNTRVJUKG1fcFJ1bnRpbWUgIT0gTlVMTCk7CisJCisJcmV0dXJuIG1fcFJ1bnRpbWUtPkdldFJlYWRlckFwcCgpOworfQorCitGWF9CT09MIENKU19Db250ZXh0OjpEb0pvYihpbnQgbk1vZGUsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQsIENGWF9XaWRlU3RyaW5nJiBpbmZvKQoreworCWlmIChtX2JCdXN5KQorCXsJCQorCQlpbmZvID0gSlNHZXRTdHJpbmdGcm9tSUQodGhpcywgSURTX1NUUklOR19KU0JVU1kpOworCQlyZXR1cm4gRkFMU0U7CisJfQkKKworCW1fYkJ1c3kgPSBUUlVFOworCisJQVNTRVJUKG1fcFJ1bnRpbWUgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyLT5Jc1ZhbGlkKCkpOworCisJaWYgKCFtX3BSdW50aW1lLT5BZGRFdmVudFRvTG9vcChtX3BFdmVudEhhbmRsZXItPlRhcmdldE5hbWUoKSwgbV9wRXZlbnRIYW5kbGVyLT5FdmVudFR5cGUoKSkpCisJeworCQlpbmZvID0gSlNHZXRTdHJpbmdGcm9tSUQodGhpcywgSURTX1NUUklOR19KU0VWRU5UKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCUZYSlNFcnIgZXJyb3IgPXtOVUxMLE5VTEwsIDB9OworCWludCBuUmV0ID0gMDsJCisKKwl0cnkKKwl7CQorCQlpZiAoc2NyaXB0LkdldExlbmd0aCgpID4gMCkKKwkJeworCQkJaWYgKG5Nb2RlID09IDApCisJCQl7CQkKKwkJCQluUmV0ID0gSlNfRXhlY3V0ZSgqbV9wUnVudGltZSwgdGhpcywgc2NyaXB0LCBzY3JpcHQuR2V0TGVuZ3RoKCksICZlcnJvcik7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJblJldCA9IEpTX1BhcnNlKCptX3BSdW50aW1lLCB0aGlzLCBzY3JpcHQsIHNjcmlwdC5HZXRMZW5ndGgoKSwgJmVycm9yKTsKKwkJCX0KKwkJfQorCisJCWlmIChuUmV0IDwgMCkKKwkJeworCQkJQ0ZYX1dpZGVTdHJpbmcgc0xpbmU7CisJCQlzTGluZS5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCJbIExpbmU6ICUwNWQgeyAlcyB9IF0gOiAlcyIsZXJyb3IubGlubnVtLTEsZXJyb3Iuc3JjbGluZSxlcnJvci5tZXNzYWdlKTsKKworLy8JCQlUUkFDRShMIi8qIC0tLS0tLS0tLS0tLS0tIEpTIEVycm9yIC0tLS0tLS0tLS0tLS0tICovXG4iKTsKKy8vCQkJVFJBQ0Uoc0xpbmUpOworLy8JCQlUUkFDRShMIlxuIik7CisJCQkvL0NGWF9CeXRlU3RyaW5nIHNUZW1wID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKGVycm9yLm1lc3NhZ2UpOworCQkJaW5mbyArPSBzTGluZTsKKwkJfQorCQllbHNlCisJCXsKKwkJCWluZm8gPSBKU0dldFN0cmluZ0Zyb21JRCh0aGlzLCBJRFNfU1RSSU5HX1JVTik7CisJCX0JCQorCisJfQorCWNhdGNoICguLi4pCisJeworCQlpbmZvID0gSlNHZXRTdHJpbmdGcm9tSUQodGhpcywgSURTX1NUUklOR19VTkhBTkRMRUQpOworCQluUmV0ID0gLTE7CisJfQorCisJbV9wUnVudGltZS0+UmVtb3ZlRXZlbnRJbkxvb3AobV9wRXZlbnRIYW5kbGVyLT5UYXJnZXROYW1lKCksIG1fcEV2ZW50SGFuZGxlci0+RXZlbnRUeXBlKCkpOworCisJbV9wRXZlbnRIYW5kbGVyLT5EZXN0cm95KCk7CisJbV9iQnVzeSA9IEZBTFNFOwkKKworCXJldHVybiBuUmV0ID49IDA7Cit9CisKK0ZYX0JPT0wgQ0pTX0NvbnRleHQ6OlJ1blNjcmlwdChjb25zdCBDRlhfV2lkZVN0cmluZyYgc2NyaXB0LCBDRlhfV2lkZVN0cmluZyYgaW5mbykKK3sKKwl2ODo6SXNvbGF0ZTo6U2NvcGUgaXNvbGF0ZV9zY29wZShtX3BSdW50aW1lLT5HZXRJc29sYXRlKCkpOworCXY4OjpIYW5kbGVTY29wZSBoYW5kbGVfc2NvcGUobV9wUnVudGltZS0+R2V0SXNvbGF0ZSgpKTsKKwl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPSBtX3BSdW50aW1lLT5OZXdKU0NvbnRleHQoKTsKKwl2ODo6Q29udGV4dDo6U2NvcGUgY29udGV4dF9zY29wZShjb250ZXh0KTsKKworCXJldHVybiBEb0pvYigwLCBzY3JpcHQsIGluZm8pOworfQorCitGWF9CT09MIENKU19Db250ZXh0OjpDb21waWxlKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzY3JpcHQsIENGWF9XaWRlU3RyaW5nJiBpbmZvKQoreworCXY4OjpJc29sYXRlOjpTY29wZSBpc29sYXRlX3Njb3BlKG1fcFJ1bnRpbWUtPkdldElzb2xhdGUoKSk7CisJdjg6OkhhbmRsZVNjb3BlIGhhbmRsZV9zY29wZShtX3BSdW50aW1lLT5HZXRJc29sYXRlKCkpOworCXY4OjpMb2NhbDx2ODo6Q29udGV4dD4gY29udGV4dCA9IG1fcFJ1bnRpbWUtPk5ld0pTQ29udGV4dCgpOworCXY4OjpDb250ZXh0OjpTY29wZSBjb250ZXh0X3Njb3BlKGNvbnRleHQpOworCisJcmV0dXJuIERvSm9iKDEsIHNjcmlwdCwgaW5mbyk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uQXBwX0luaXQoKQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PbkFwcF9Jbml0KCk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uRG9jX09wZW4oQ1BERlNES19Eb2N1bWVudCogcERvYywgY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJnN0clRhcmdldE5hbWUpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uRG9jX09wZW4ocERvYyxzdHJUYXJnZXROYW1lKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25Eb2NfV2lsbFByaW50KENQREZTREtfRG9jdW1lbnQqIHBEb2MpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uRG9jX1dpbGxQcmludChwRG9jKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25Eb2NfRGlkUHJpbnQoQ1BERlNES19Eb2N1bWVudCogcERvYykKK3sKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOworCW1fcEV2ZW50SGFuZGxlci0+T25Eb2NfRGlkUHJpbnQocERvYyk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uRG9jX1dpbGxTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uRG9jX1dpbGxTYXZlKHBEb2MpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPbkRvY19EaWRTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uRG9jX0RpZFNhdmUocERvYyk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uRG9jX1dpbGxDbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PbkRvY19XaWxsQ2xvc2UocERvYyk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uUGFnZV9PcGVuKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uUGFnZV9PcGVuKHBUYXJnZXQpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPblBhZ2VfQ2xvc2UoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCkKK3sKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOworCW1fcEV2ZW50SGFuZGxlci0+T25QYWdlX0Nsb3NlKHBUYXJnZXQpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPblBhZ2VfSW5WaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uUGFnZV9JblZpZXcocFRhcmdldCk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uUGFnZV9PdXRWaWV3KENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uUGFnZV9PdXRWaWV3KHBUYXJnZXQpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX01vdXNlRG93bihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX01vdXNlRG93bihiTW9kaWZpZXIsIGJTaGlmdCwgcFRhcmdldCk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uRmllbGRfTW91c2VFbnRlcihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX01vdXNlRW50ZXIoYk1vZGlmaWVyLCBiU2hpZnQsIHBUYXJnZXQpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX01vdXNlRXhpdChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX01vdXNlRXhpdChiTW9kaWZpZXIsIGJTaGlmdCwgcFRhcmdldCk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uRmllbGRfTW91c2VVcChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkICpwVGFyZ2V0KQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX01vdXNlVXAoYk1vZGlmaWVyLCBiU2hpZnQsIHBUYXJnZXQpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBWYWx1ZSkKK3sKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOworCW1fcEV2ZW50SGFuZGxlci0+T25GaWVsZF9Gb2N1cyhiTW9kaWZpZXIsIGJTaGlmdCwgcFRhcmdldCwgVmFsdWUpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPbkZpZWxkX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlKQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX0JsdXIoYk1vZGlmaWVyLCBiU2hpZnQsIHBUYXJnZXQsIFZhbHVlKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25GaWVsZF9DYWxjdWxhdGUoQ1BERl9Gb3JtRmllbGQqIHBTb3VyY2UsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wmIGJSYykKK3sKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOworCW1fcEV2ZW50SGFuZGxlci0+T25GaWVsZF9DYWxjdWxhdGUocFNvdXJjZSwgcFRhcmdldCwgVmFsdWUsIGJSYyk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uRmllbGRfRm9ybWF0KGludCBuQ29tbWl0S2V5LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0KQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PbkZpZWxkX0Zvcm1hdChuQ29tbWl0S2V5LCBwVGFyZ2V0LCBWYWx1ZSwgYldpbGxDb21taXQpOworfQorCisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uRmllbGRfS2V5c3Ryb2tlKGludCBuQ29tbWl0S2V5LCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsCisJCQkJCQkJCQlGWF9CT09MIGJLZXlEb3duLCBGWF9CT09MIGJNb2RpZmllciwgaW50ICZuU2VsRW5kLGludCAmblNlbFN0YXJ0LAorCQkJCQkJCQkJRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCBDRlhfV2lkZVN0cmluZyYgVmFsdWUsCisJCQkJCQkJCQlGWF9CT09MIGJXaWxsQ29tbWl0LCBGWF9CT09MIGJGaWVsZEZ1bGwsIEZYX0JPT0wmIGJSYykKK3sKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOworCW1fcEV2ZW50SGFuZGxlci0+T25GaWVsZF9LZXlzdHJva2UobkNvbW1pdEtleSwgc3RyQ2hhbmdlLCBzdHJDaGFuZ2VFeCwgYktleURvd24sCisJCWJNb2RpZmllciwgblNlbEVuZCwgblNlbFN0YXJ0LCBiU2hpZnQsIHBUYXJnZXQsIFZhbHVlLCBiV2lsbENvbW1pdCwgYkZpZWxkRnVsbCwgYlJjKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25GaWVsZF9WYWxpZGF0ZShDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlLGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwKKwkJCQkJCQkJICAgRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwKKwkJCQkJCQkJICAgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MJiBiUmMpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uRmllbGRfVmFsaWRhdGUoc3RyQ2hhbmdlLCBzdHJDaGFuZ2VFeCwgYktleURvd24sIGJNb2RpZmllciwgYlNoaWZ0LCBwVGFyZ2V0LCBWYWx1ZSwgYlJjKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25TY3JlZW5fRm9jdXMoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PblNjcmVlbl9Gb2N1cyhiTW9kaWZpZXIsIGJTaGlmdCwgcFNjcmVlbik7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uU2NyZWVuX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PblNjcmVlbl9CbHVyKGJNb2RpZmllciwgYlNoaWZ0LCBwU2NyZWVuKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25TY3JlZW5fT3BlbihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uU2NyZWVuX09wZW4oYk1vZGlmaWVyLCBiU2hpZnQsIHBTY3JlZW4pOworfQorCit2b2lkIENKU19Db250ZXh0OjpPblNjcmVlbl9DbG9zZShGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uU2NyZWVuX0Nsb3NlKGJNb2RpZmllciwgYlNoaWZ0LCBwU2NyZWVuKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25TY3JlZW5fTW91c2VEb3duKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikKK3sKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOworCW1fcEV2ZW50SGFuZGxlci0+T25TY3JlZW5fTW91c2VEb3duKGJNb2RpZmllciwgYlNoaWZ0LCBwU2NyZWVuKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25TY3JlZW5fTW91c2VVcChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uU2NyZWVuX01vdXNlVXAoYk1vZGlmaWVyLCBiU2hpZnQsIHBTY3JlZW4pOworfQorCit2b2lkIENKU19Db250ZXh0OjpPblNjcmVlbl9Nb3VzZUVudGVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikKK3sKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOworCW1fcEV2ZW50SGFuZGxlci0+T25TY3JlZW5fTW91c2VFbnRlcihiTW9kaWZpZXIsIGJTaGlmdCwgcFNjcmVlbik7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uU2NyZWVuX01vdXNlRXhpdChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uU2NyZWVuX01vdXNlRXhpdChiTW9kaWZpZXIsIGJTaGlmdCwgcFNjcmVlbik7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uU2NyZWVuX0luVmlldyhGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uU2NyZWVuX0luVmlldyhiTW9kaWZpZXIsIGJTaGlmdCwgcFNjcmVlbik7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uU2NyZWVuX091dFZpZXcoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CisJbV9wRXZlbnRIYW5kbGVyLT5PblNjcmVlbl9PdXRWaWV3KGJNb2RpZmllciwgYlNoaWZ0LCBwU2NyZWVuKTsKK30KKwordm9pZCBDSlNfQ29udGV4dDo6T25Cb29rbWFya19Nb3VzZVVwKENQREZfQm9va21hcmsqIHBCb29rTWFyaykKK3sKKwlBU1NFUlQobV9wRXZlbnRIYW5kbGVyICE9IE5VTEwpOworCW1fcEV2ZW50SGFuZGxlci0+T25Cb29rbWFya19Nb3VzZVVwKHBCb29rTWFyayk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uTGlua19Nb3VzZVVwKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uTGlua19Nb3VzZVVwKHBUYXJnZXQpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPbkNvbnNvbGVfRXhlYygpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uQ29uc29sZV9FeGVjKCk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uRXh0ZXJuYWxfRXhlYygpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uRXh0ZXJuYWxfRXhlYygpOworfQorCit2b2lkIENKU19Db250ZXh0OjpPbkJhdGNoRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KQoreworCUFTU0VSVChtX3BFdmVudEhhbmRsZXIgIT0gTlVMTCk7CQorCW1fcEV2ZW50SGFuZGxlci0+T25CYXRjaEV4ZWMocFRhcmdldCk7Cit9CisKK3ZvaWQgQ0pTX0NvbnRleHQ6Ok9uTWVudV9FeGVjKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQsY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0clRhcmdldE5hbWUpCit7CisJQVNTRVJUKG1fcEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKwltX3BFdmVudEhhbmRsZXItPk9uTWVudV9FeGVjKHBUYXJnZXQsIHN0clRhcmdldE5hbWUpOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5jcHAgYi9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5jcHAKaW5kZXggY2U2OWU2Yi4uNzZjNmQzNyAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSlNfRXZlbnRIYW5kbGVyLmNwcApAQCAtMSw2NzYgKzEsNjc2IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCINCi0vLyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUmVzTWdyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19SdW50aW1lLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIg0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX0V2ZW50SGFuZGxlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0pTX0V2ZW50SGFuZGxlcjo6Q0pTX0V2ZW50SGFuZGxlcihDSlNfQ29udGV4dCAqIHBDb250ZXh0KQkgOg0KLQltX3BKU0NvbnRleHQocENvbnRleHQpLA0KLQltX2VFdmVudFR5cGUoSkVUX1VOS05PV04pLA0KLQltX2JWYWxpZChGQUxTRSksDQotCW1fcFdpZGVTdHJDaGFuZ2UoTlVMTCksDQotCW1fbkNvbW1pdEtleSgtMSksDQotCW1fYktleURvd24oRkFMU0UpLA0KLQltX2JNb2RpZmllcihGQUxTRSksDQotCW1fYlNoaWZ0KEZBTFNFKSwNCi0JbV9wSVNlbEVuZChOVUxMKSwNCi0JbV9uU2VsRW5kRHUoMCksDQotCW1fcElTZWxTdGFydChOVUxMKSwNCi0JbV9uU2VsU3RhcnREdSgwKSwNCi0JbV9iV2lsbENvbW1pdChGQUxTRSksDQotCW1fcFZhbHVlKE5VTEwpLA0KLQltX2JGaWVsZEZ1bGwoRkFMU0UpLA0KLQltX3BiUmMoTlVMTCksDQotCW1fYlJjRHUoRkFMU0UpLA0KLQltX3BTb3VyY2VEb2MoTlVMTCksDQotCW1fcFRhcmdldEJvb2tNYXJrKE5VTEwpLA0KLQltX3BUYXJnZXREb2MoTlVMTCksDQotCW1fcFRhcmdldEFubm90KE5VTEwpDQotew0KLX0NCi0NCi1DSlNfRXZlbnRIYW5kbGVyOjp+Q0pTX0V2ZW50SGFuZGxlcigpDQotew0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uQXBwX0luaXQoKQ0KLXsNCi0JSW5pdGlhbChKRVRfQVBQX0lOSVQpOw0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRG9jX09wZW4oQ1BERlNES19Eb2N1bWVudCogcERvYywgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0clRhcmdldE5hbWUpDQotew0KLQlJbml0aWFsKEpFVF9ET0NfT1BFTik7DQotDQotCW1fcFRhcmdldERvYyA9IHBEb2M7DQotCW1fc3RyVGFyZ2V0TmFtZSA9IHN0clRhcmdldE5hbWU7CQ0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRG9jX1dpbGxQcmludChDUERGU0RLX0RvY3VtZW50KiBwRG9jKQ0KLXsNCi0JSW5pdGlhbChKRVRfRE9DX1dJTExQUklOVCk7DQotDQotCW1fcFRhcmdldERvYyA9IHBEb2M7CQ0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRG9jX0RpZFByaW50KENQREZTREtfRG9jdW1lbnQqIHBEb2MpDQotew0KLQlJbml0aWFsKEpFVF9ET0NfRElEUFJJTlQpOw0KLQkNCi0JbV9wVGFyZ2V0RG9jID0gcERvYzsJCQ0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRG9jX1dpbGxTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpDQotew0KLQlJbml0aWFsKEpFVF9ET0NfV0lMTFNBVkUpOw0KLQltX3BUYXJnZXREb2MgPSBwRG9jOwkJDQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25Eb2NfRGlkU2F2ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKQ0KLXsNCi0JSW5pdGlhbChKRVRfRE9DX0RJRFNBVkUpOwkNCi0JDQotCW1fcFRhcmdldERvYyA9IHBEb2M7CQ0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRG9jX1dpbGxDbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKQ0KLXsNCi0JSW5pdGlhbChKRVRfRE9DX1dJTExDTE9TRSk7DQotDQotCW1fcFRhcmdldERvYyA9IHBEb2M7CQ0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uUGFnZV9PcGVuKENQREZTREtfRG9jdW1lbnQqIHBEb2MpDQotew0KLQlJbml0aWFsKEpFVF9QQUdFX09QRU4pOw0KLQ0KLQltX3BUYXJnZXREb2MgPSBwRG9jOw0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uUGFnZV9DbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKQ0KLXsNCi0JSW5pdGlhbChKRVRfUEFHRV9DTE9TRSk7DQotCQ0KLQltX3BUYXJnZXREb2MgPSBwRG9jOw0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uUGFnZV9JblZpZXcoQ1BERlNES19Eb2N1bWVudCogcERvYykNCi17DQotCUluaXRpYWwoSkVUX1BBR0VfSU5WSUVXKTsNCi0JDQotCW1fcFRhcmdldERvYyA9IHBEb2M7DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25QYWdlX091dFZpZXcoQ1BERlNES19Eb2N1bWVudCogcERvYykNCi17DQotCUluaXRpYWwoSkVUX1BBR0VfT1VUVklFVyk7DQotCQ0KLQltX3BUYXJnZXREb2MgPSBwRG9jOw0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRmllbGRfTW91c2VFbnRlcihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0KQ0KLXsNCi0JSW5pdGlhbChKRVRfRklFTERfTU9VU0VFTlRFUik7DQotDQotCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOw0KLQltX2JTaGlmdCA9IGJTaGlmdDsNCi0NCi0JQVNTRVJUKHBUYXJnZXQgIT0gTlVMTCk7DQotCW1fc3RyVGFyZ2V0TmFtZSA9IHBUYXJnZXQtPkdldEZ1bGxOYW1lKCk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25GaWVsZF9Nb3VzZUV4aXQoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCkNCi17DQotCUluaXRpYWwoSkVUX0ZJRUxEX01PVVNFRVhJVCk7DQotDQotCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOw0KLQltX2JTaGlmdCA9IGJTaGlmdDsNCi0JQVNTRVJUKHBUYXJnZXQgIT0gTlVMTCk7DQotCW1fc3RyVGFyZ2V0TmFtZSA9IHBUYXJnZXQtPkdldEZ1bGxOYW1lKCk7CQ0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRmllbGRfTW91c2VEb3duKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQpDQotew0KLQlJbml0aWFsKEpFVF9GSUVMRF9NT1VTRURPV04pOw0KLQltX2VFdmVudFR5cGUgPSBKRVRfRklFTERfTU9VU0VET1dOOw0KLQkNCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fYlNoaWZ0ID0gYlNoaWZ0OwkNCi0JQVNTRVJUKHBUYXJnZXQgIT0gTlVMTCk7DQotCW1fc3RyVGFyZ2V0TmFtZSA9IHBUYXJnZXQtPkdldEZ1bGxOYW1lKCk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25GaWVsZF9Nb3VzZVVwKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQpDQotew0KLQlJbml0aWFsKEpFVF9GSUVMRF9NT1VTRVVQKTsNCi0NCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fYlNoaWZ0ID0gYlNoaWZ0Ow0KLQlBU1NFUlQocFRhcmdldCAhPSBOVUxMKTsNCi0JbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsNCi19DQotDQotdm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkZpZWxkX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIA0KLQkJCQkJCQkJCSBjb25zdCBDRlhfV2lkZVN0cmluZyYgVmFsdWUpDQotew0KLQlJbml0aWFsKEpFVF9GSUVMRF9GT0NVUyk7DQotDQotCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOw0KLQltX2JTaGlmdCA9IGJTaGlmdDsgIA0KLQlBU1NFUlQocFRhcmdldCAhPSBOVUxMKTsNCi0JbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsNCi0JbV9wVmFsdWUgPSAoQ0ZYX1dpZGVTdHJpbmcqKSZWYWx1ZTsNCi19DQotDQotdm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkZpZWxkX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwNCi0JCQkJCQkJCQljb25zdCBDRlhfV2lkZVN0cmluZyYgVmFsdWUpDQotew0KLQlJbml0aWFsKEpFVF9GSUVMRF9CTFVSKTsNCi0NCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fYlNoaWZ0ID0gYlNoaWZ0Ow0KLQlBU1NFUlQocFRhcmdldCAhPSBOVUxMKTsNCi0JbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsNCi0JbV9wVmFsdWUgPSAoQ0ZYX1dpZGVTdHJpbmcqKSZWYWx1ZTsJDQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25GaWVsZF9LZXlzdHJva2UoaW50IG5Db21taXRLZXksIENGWF9XaWRlU3RyaW5nICZzdHJDaGFuZ2UsDQotCQkJCQkJCQkJCSBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsIEZYX0JPT0wgS2V5RG93biwNCi0JCQkJCQkJCQkJIEZYX0JPT0wgYk1vZGlmaWVyLCBpbnQmIG5TZWxFbmQsIGludCYgblNlbFN0YXJ0LA0KLQkJCQkJCQkJCQkgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LA0KLQkJCQkJCQkJCQkgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0LA0KLQkJCQkJCQkJCQkgIEZYX0JPT0wgYkZpZWxkRnVsbCwgRlhfQk9PTCYgYlJjKQ0KLXsNCi0JSW5pdGlhbChKRVRfRklFTERfS0VZU1RST0tFKTsNCi0JDQotCW1fbkNvbW1pdEtleSA9IG5Db21taXRLZXk7DQotCW1fcFdpZGVTdHJDaGFuZ2UgPSAmc3RyQ2hhbmdlOw0KLQltX1dpZGVTdHJDaGFuZ2VFeCA9IHN0ckNoYW5nZUV4Ow0KLQltX2JLZXlEb3duID0gS2V5RG93bjsNCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fcElTZWxFbmQgPSAmblNlbEVuZDsNCi0JbV9wSVNlbFN0YXJ0ID0gJm5TZWxTdGFydDsNCi0JbV9iU2hpZnQgPSBiU2hpZnQ7CQ0KLQlBU1NFUlQocFRhcmdldCAhPSBOVUxMKTsNCi0JbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsNCi0JbV9wVmFsdWUgPSAmVmFsdWU7DQotCW1fYldpbGxDb21taXQgPSBiV2lsbENvbW1pdDsJDQotCW1fcGJSYyA9ICZiUmM7DQotCW1fYkZpZWxkRnVsbCA9IGJGaWVsZEZ1bGw7DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25GaWVsZF9WYWxpZGF0ZShDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyQ2hhbmdlRXgsDQotCQkJCQkJCQkJCUZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwNCi0JCQkJCQkJCQkJQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCYgYlJjKQ0KLXsNCi0JSW5pdGlhbChKRVRfRklFTERfVkFMSURBVEUpOw0KLQkNCi0JbV9wV2lkZVN0ckNoYW5nZSA9ICZzdHJDaGFuZ2U7DQotCW1fV2lkZVN0ckNoYW5nZUV4ID0gc3RyQ2hhbmdlRXg7CQ0KLQltX2JLZXlEb3duID0gYktleURvd247DQotCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOw0KLQltX2JTaGlmdCA9IGJTaGlmdDsNCi0JQVNTRVJUKHBUYXJnZXQgIT0gTlVMTCk7DQotCW1fc3RyVGFyZ2V0TmFtZSA9IHBUYXJnZXQtPkdldEZ1bGxOYW1lKCk7DQotCW1fcFZhbHVlID0gJlZhbHVlOwkNCi0JbV9wYlJjID0gJmJSYzsJDQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25GaWVsZF9DYWxjdWxhdGUoQ1BERl9Gb3JtRmllbGQqIHBTb3VyY2UsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCANCi0JCQkJCQkJCQkJIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCYgYlJjKQ0KLXsNCi0JSW5pdGlhbChKRVRfRklFTERfQ0FMQ1VMQVRFKTsNCi0NCi0JaWYgKHBTb3VyY2UpDQotCQltX3N0clNvdXJjZU5hbWUgPSBwU291cmNlLT5HZXRGdWxsTmFtZSgpOw0KLQlBU1NFUlQocFRhcmdldCAhPSBOVUxMKTsNCi0JbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsNCi0gICAgbV9wVmFsdWUgPSAmVmFsdWU7DQotCW1fcGJSYyA9ICZiUmM7DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25GaWVsZF9Gb3JtYXQoaW50IG5Db21taXRLZXksIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LA0KLQkJCQkJCQkJCSAgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MIGJXaWxsQ29tbWl0KQ0KLXsNCi0JSW5pdGlhbChKRVRfRklFTERfRk9STUFUKTsNCi0JDQotCW1fbkNvbW1pdEtleSA9IG5Db21taXRLZXk7CSAgDQotCUFTU0VSVChwVGFyZ2V0ICE9IE5VTEwpOw0KLQltX3N0clRhcmdldE5hbWUgPSBwVGFyZ2V0LT5HZXRGdWxsTmFtZSgpOw0KLQltX3BWYWx1ZSA9ICZWYWx1ZTsNCi0JbV9iV2lsbENvbW1pdCA9IGJXaWxsQ29tbWl0Ow0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uU2NyZWVuX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUluaXRpYWwoSkVUX1NDUkVFTl9GT0NVUyk7DQotDQotCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOw0KLQltX2JTaGlmdCA9IGJTaGlmdDsNCi0JbV9wVGFyZ2V0QW5ub3QgPSBwU2NyZWVuOw0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uU2NyZWVuX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQ0KLXsNCi0JSW5pdGlhbChKRVRfU0NSRUVOX0JMVVIpOw0KLQ0KLQltX2JNb2RpZmllciA9IGJNb2RpZmllcjsNCi0JbV9iU2hpZnQgPSBiU2hpZnQ7DQotCW1fcFRhcmdldEFubm90ID0gcFNjcmVlbjsNCi19DQotDQotdm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPblNjcmVlbl9PcGVuKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUluaXRpYWwoSkVUX1NDUkVFTl9PUEVOKTsNCi0NCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fYlNoaWZ0ID0gYlNoaWZ0Ow0KLQltX3BUYXJnZXRBbm5vdCA9IHBTY3JlZW47DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25TY3JlZW5fQ2xvc2UoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQ0KLXsNCi0JSW5pdGlhbChKRVRfU0NSRUVOX0NMT1NFKTsNCi0NCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fYlNoaWZ0ID0gYlNoaWZ0Ow0KLQltX3BUYXJnZXRBbm5vdCA9IHBTY3JlZW47DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25TY3JlZW5fTW91c2VEb3duKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUluaXRpYWwoSkVUX1NDUkVFTl9NT1VTRURPV04pOw0KLQ0KLQltX2JNb2RpZmllciA9IGJNb2RpZmllcjsNCi0JbV9iU2hpZnQgPSBiU2hpZnQ7DQotCW1fcFRhcmdldEFubm90ID0gcFNjcmVlbjsNCi19DQotDQotdm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPblNjcmVlbl9Nb3VzZVVwKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUluaXRpYWwoSkVUX1NDUkVFTl9NT1VTRVVQKTsNCi0NCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fYlNoaWZ0ID0gYlNoaWZ0Ow0KLQltX3BUYXJnZXRBbm5vdCA9IHBTY3JlZW47DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25TY3JlZW5fTW91c2VFbnRlcihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pDQotew0KLQlJbml0aWFsKEpFVF9TQ1JFRU5fTU9VU0VFTlRFUik7DQotDQotCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOw0KLQltX2JTaGlmdCA9IGJTaGlmdDsNCi0JbV9wVGFyZ2V0QW5ub3QgPSBwU2NyZWVuOw0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uU2NyZWVuX01vdXNlRXhpdChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pDQotew0KLQlJbml0aWFsKEpFVF9TQ1JFRU5fTU9VU0VFWElUKTsNCi0NCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fYlNoaWZ0ID0gYlNoaWZ0Ow0KLQltX3BUYXJnZXRBbm5vdCA9IHBTY3JlZW47DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25TY3JlZW5fSW5WaWV3KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUluaXRpYWwoSkVUX1NDUkVFTl9JTlZJRVcpOw0KLQ0KLQltX2JNb2RpZmllciA9IGJNb2RpZmllcjsNCi0JbV9iU2hpZnQgPSBiU2hpZnQ7DQotCW1fcFRhcmdldEFubm90ID0gcFNjcmVlbjsNCi19DQotDQotdm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPblNjcmVlbl9PdXRWaWV3KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikNCi17DQotCUluaXRpYWwoSkVUX1NDUkVFTl9PVVRWSUVXKTsNCi0NCi0JbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7DQotCW1fYlNoaWZ0ID0gYlNoaWZ0Ow0KLQltX3BUYXJnZXRBbm5vdCA9IHBTY3JlZW47DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25MaW5rX01vdXNlVXAoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCkNCi17DQotCUluaXRpYWwoSkVUX0xJTktfTU9VU0VVUCk7DQotCQ0KLQltX3BUYXJnZXREb2MgPSBwVGFyZ2V0OwkNCi19DQotDQotdm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkJvb2ttYXJrX01vdXNlVXAoQ1BERl9Cb29rbWFyayogcEJvb2tNYXJrKQ0KLXsNCi0JSW5pdGlhbChKRVRfQk9PS01BUktfTU9VU0VVUCk7DQotDQotCW1fcFRhcmdldEJvb2tNYXJrID0gcEJvb2tNYXJrOwkNCi19DQotDQotdm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbk1lbnVfRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyVGFyZ2V0TmFtZSkNCi17DQotCUluaXRpYWwoSkVUX01FTlVfRVhFQyk7DQotDQotCW1fcFRhcmdldERvYyA9IHBUYXJnZXQ7DQotCW1fc3RyVGFyZ2V0TmFtZSA9IHN0clRhcmdldE5hbWU7DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25FeHRlcm5hbF9FeGVjKCkNCi17DQotCUluaXRpYWwoSkVUX0VYVEVSTkFMX0VYRUMpOw0KLX0NCi0NCi12b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uQmF0Y2hFeGVjKENQREZTREtfRG9jdW1lbnQqIHBUYXJnZXQpDQotew0KLQlJbml0aWFsKEpFVF9CQVRDSF9FWEVDKTsNCi0NCi0JbV9wVGFyZ2V0RG9jID0gcFRhcmdldDsJDQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25Db25zb2xlX0V4ZWMoKQ0KLXsNCi0JSW5pdGlhbChKRVRfQ09OU09MRV9FWEVDKTsNCi19DQotDQotDQotdm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpJbml0aWFsKEpTX0VWRU5UX1QgdHlwZSkNCi17DQotCW1fZUV2ZW50VHlwZSA9IHR5cGU7DQotDQotCW1fc3RyVGFyZ2V0TmFtZSA9IEwiIjsNCi0JbV9zdHJTb3VyY2VOYW1lID0gTCIiOw0KLQltX3BXaWRlU3RyQ2hhbmdlID0gTlVMTDsNCi0JbV9XaWRlU3RyQ2hhbmdlRHUgPSBMIiI7DQotCW1fV2lkZVN0ckNoYW5nZUV4ID0gTCIiOw0KLQltX25Db21taXRLZXkgPSAtMTsNCi0JbV9iS2V5RG93biA9IEZBTFNFOw0KLQltX2JNb2RpZmllciA9IEZBTFNFOw0KLQltX2JTaGlmdCA9IEZBTFNFOw0KLQltX3BJU2VsRW5kID0gTlVMTDsNCi0JbV9uU2VsRW5kRHUgPSAwOw0KLQltX3BJU2VsU3RhcnQgPSBOVUxMOw0KLQltX25TZWxTdGFydER1ID0gMDsNCi0JbV9iV2lsbENvbW1pdCA9IEZBTFNFOw0KLQltX3BWYWx1ZSA9IE5VTEw7DQotCW1fYkZpZWxkRnVsbCA9IEZBTFNFOw0KLQltX3BiUmMgPSBOVUxMOw0KLQltX2JSY0R1ID0gRkFMU0U7DQotDQotCW1fcFNvdXJjZURvYyA9IE5VTEw7DQotCW1fcFRhcmdldEJvb2tNYXJrID0gTlVMTDsNCi0JbV9wVGFyZ2V0RG9jID0gTlVMTDsNCi0JbV9wVGFyZ2V0QW5ub3QgPSBOVUxMOw0KLQ0KLQltX2JWYWxpZCA9IFRSVUU7DQotfQ0KLQ0KLXZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6RGVzdHJveSgpDQotew0KLQltX2JWYWxpZCA9IEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIENKU19FdmVudEhhbmRsZXI6OklzVmFsaWQoKQ0KLXsNCi0JcmV0dXJuIG1fYlZhbGlkOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyAmIENKU19FdmVudEhhbmRsZXI6OkNoYW5nZSgpDQotew0KLQlpZiAobV9wV2lkZVN0ckNoYW5nZSAhPSBOVUxMKQ0KLQkJcmV0dXJuICptX3BXaWRlU3RyQ2hhbmdlOw0KLQllbHNlDQotCXsNCi0JCXJldHVybiBtX1dpZGVTdHJDaGFuZ2VEdTsNCi0JfQ0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDSlNfRXZlbnRIYW5kbGVyOjpDaGFuZ2VFeCgpDQotew0KLQlyZXR1cm4gbV9XaWRlU3RyQ2hhbmdlRXg7DQotfQ0KLQ0KLWludCBDSlNfRXZlbnRIYW5kbGVyOjpDb21taXRLZXkoKQ0KLXsNCi0JcmV0dXJuIG1fbkNvbW1pdEtleTsNCi19DQotDQotRlhfQk9PTCBDSlNfRXZlbnRIYW5kbGVyOjpGaWVsZEZ1bGwoKQ0KLXsNCi0JcmV0dXJuIG1fYkZpZWxkRnVsbDsNCi19DQotDQotRlhfQk9PTCBDSlNfRXZlbnRIYW5kbGVyOjpLZXlEb3duKCkNCi17DQotCXJldHVybiBtX2JLZXlEb3duOw0KLX0NCi0NCi1GWF9CT09MIENKU19FdmVudEhhbmRsZXI6Ok1vZGlmaWVyKCkNCi17DQotCXJldHVybiBtX2JNb2RpZmllcjsNCi19DQotDQotRlhfTFBDV1NUUiBDSlNfRXZlbnRIYW5kbGVyOjpOYW1lKCkNCi17DQotCXN3aXRjaCAobV9lRXZlbnRUeXBlKQ0KLQl7DQotCWNhc2UgSkVUX0FQUF9JTklUOgkJCXJldHVybiAoRlhfTFBDV1NUUilMIkluaXQiOw0KLQljYXNlIEpFVF9CQVRDSF9FWEVDOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiRXhlYyI7DQotCWNhc2UgSkVUX0JPT0tNQVJLX01PVVNFVVA6CXJldHVybiAoRlhfTFBDV1NUUilMIk1vdXNlIFVwIjsNCi0JY2FzZSBKRVRfQ09OU09MRV9FWEVDOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiRXhlYyI7DQotCWNhc2UgSkVUX0RPQ19ESURQUklOVDoJCXJldHVybiAoRlhfTFBDV1NUUilMIkRpZFByaW50IjsNCi0JY2FzZSBKRVRfRE9DX0RJRFNBVkU6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJEaWRTYXZlIjsNCi0JY2FzZSBKRVRfRE9DX09QRU46CQkJcmV0dXJuIChGWF9MUENXU1RSKUwiT3BlbiI7DQotCWNhc2UgSkVUX0RPQ19XSUxMQ0xPU0U6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJXaWxsQ2xvc2UiOw0KLQljYXNlIEpFVF9ET0NfV0lMTFBSSU5UOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiV2lsbFByaW50IjsNCi0JY2FzZSBKRVRfRE9DX1dJTExTQVZFOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiV2lsbFNhdmUiOw0KLQljYXNlIEpFVF9FWFRFUk5BTF9FWEVDOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiRXhlYyI7DQotCWNhc2UgSkVUX0ZJRUxEX0ZPQ1VTOgkJDQotCWNhc2UgSkVUX1NDUkVFTl9GT0NVUzoJCXJldHVybiAoRlhfTFBDV1NUUilMIkZvY3VzIjsNCi0JY2FzZSBKRVRfRklFTERfQkxVUjoJCQ0KLQljYXNlIEpFVF9TQ1JFRU5fQkxVUjoJCXJldHVybiAoRlhfTFBDV1NUUilMIkJsdXIiOw0KLQljYXNlIEpFVF9GSUVMRF9NT1VTRURPV046DQotCWNhc2UgSkVUX1NDUkVFTl9NT1VTRURPV046CXJldHVybiAoRlhfTFBDV1NUUilMIk1vdXNlIERvd24iOw0KLQljYXNlIEpFVF9GSUVMRF9NT1VTRVVQOgkJDQotCWNhc2UgSkVUX1NDUkVFTl9NT1VTRVVQOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJNb3VzZSBVcCI7DQotCWNhc2UgSkVUX0ZJRUxEX01PVVNFRU5URVI6DQotCWNhc2UgSkVUX1NDUkVFTl9NT1VTRUVOVEVSOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJNb3VzZSBFbnRlciI7DQotCWNhc2UgSkVUX0ZJRUxEX01PVVNFRVhJVDoNCi0JY2FzZSBKRVRfU0NSRUVOX01PVVNFRVhJVDoJcmV0dXJuIChGWF9MUENXU1RSKUwiTW91c2UgRXhpdCI7DQotCWNhc2UgSkVUX0ZJRUxEX0NBTENVTEFURToJcmV0dXJuIChGWF9MUENXU1RSKUwiQ2FsY3VsYXRlIjsNCi0JY2FzZSBKRVRfRklFTERfRk9STUFUOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiRm9ybWF0IjsNCi0JY2FzZSBKRVRfRklFTERfS0VZU1RST0tFOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJLZXlzdHJva2UiOw0KLQljYXNlIEpFVF9GSUVMRF9WQUxJREFURToJcmV0dXJuIChGWF9MUENXU1RSKUwiVmFsaWRhdGUiOw0KLQljYXNlIEpFVF9MSU5LX01PVVNFVVA6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJNb3VzZSBVcCI7DQotCWNhc2UgSkVUX01FTlVfRVhFQzoJCQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJFeGVjIjsNCi0JY2FzZSBKRVRfUEFHRV9PUEVOOgkJDQotCWNhc2UgSkVUX1NDUkVFTl9PUEVOOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiT3BlbiI7DQotCWNhc2UgSkVUX1BBR0VfQ0xPU0U6DQotCWNhc2UgSkVUX1NDUkVFTl9DTE9TRToJCXJldHVybiAoRlhfTFBDV1NUUilMIkNsb3NlIjsNCi0JY2FzZSBKRVRfU0NSRUVOX0lOVklFVzoJDQotCWNhc2UgSkVUX1BBR0VfSU5WSUVXOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiSW5WaWV3IjsNCi0JY2FzZSBKRVRfUEFHRV9PVVRWSUVXOg0KLQljYXNlIEpFVF9TQ1JFRU5fT1VUVklFVzoJcmV0dXJuIChGWF9MUENXU1RSKUwiT3V0VmlldyI7DQotCWRlZmF1bHQ6DQotCQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCIiOw0KLQl9DQotDQotCXJldHVybiAoRlhfTFBDV1NUUilMIiI7DQotfQ0KLQ0KLUZYX0xQQ1dTVFIgQ0pTX0V2ZW50SGFuZGxlcjo6VHlwZSgpDQotew0KLQlzd2l0Y2ggKG1fZUV2ZW50VHlwZSkNCi0Jew0KLQljYXNlIEpFVF9BUFBfSU5JVDoJCQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJBcHAiOw0KLQljYXNlIEpFVF9CQVRDSF9FWEVDOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiQmF0Y2giOw0KLQljYXNlIEpFVF9CT09LTUFSS19NT1VTRVVQOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJCb29rTWFyayI7CQ0KLQljYXNlIEpFVF9DT05TT0xFX0VYRUM6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJDb25zb2xlIjsNCi0JY2FzZSBKRVRfRE9DX0RJRFBSSU5UOg0KLQljYXNlIEpFVF9ET0NfRElEU0FWRToNCi0JY2FzZSBKRVRfRE9DX09QRU46DQotCWNhc2UgSkVUX0RPQ19XSUxMQ0xPU0U6DQotCWNhc2UgSkVUX0RPQ19XSUxMUFJJTlQ6DQotCWNhc2UgSkVUX0RPQ19XSUxMU0FWRToJCXJldHVybiAoRlhfTFBDV1NUUilMIkRvYyI7DQotCWNhc2UgSkVUX0VYVEVSTkFMX0VYRUM6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJFeHRlcm5hbCI7DQotCWNhc2UgSkVUX0ZJRUxEX0JMVVI6DQotCWNhc2UgSkVUX0ZJRUxEX0ZPQ1VTOg0KLQljYXNlIEpFVF9GSUVMRF9NT1VTRURPV046DQotCWNhc2UgSkVUX0ZJRUxEX01PVVNFRU5URVI6DQotCWNhc2UgSkVUX0ZJRUxEX01PVVNFRVhJVDoNCi0JY2FzZSBKRVRfRklFTERfTU9VU0VVUDoNCi0JY2FzZSBKRVRfRklFTERfQ0FMQ1VMQVRFOg0KLQljYXNlIEpFVF9GSUVMRF9GT1JNQVQ6DQotCWNhc2UgSkVUX0ZJRUxEX0tFWVNUUk9LRToNCi0JY2FzZSBKRVRfRklFTERfVkFMSURBVEU6CXJldHVybiAoRlhfTFBDV1NUUilMIkZpZWxkIjsNCi0JY2FzZSBKRVRfU0NSRUVOX0ZPQ1VTOg0KLQljYXNlIEpFVF9TQ1JFRU5fQkxVUjoNCi0JY2FzZSBKRVRfU0NSRUVOX09QRU46DQotCWNhc2UgSkVUX1NDUkVFTl9DTE9TRToNCi0JY2FzZSBKRVRfU0NSRUVOX01PVVNFRE9XTjoNCi0JY2FzZSBKRVRfU0NSRUVOX01PVVNFVVA6DQotCWNhc2UgSkVUX1NDUkVFTl9NT1VTRUVOVEVSOg0KLQljYXNlIEpFVF9TQ1JFRU5fTU9VU0VFWElUOg0KLQljYXNlIEpFVF9TQ1JFRU5fSU5WSUVXOg0KLQljYXNlIEpFVF9TQ1JFRU5fT1VUVklFVzoJcmV0dXJuIChGWF9MUENXU1RSKUwiU2NyZWVuIjsNCi0JY2FzZSBKRVRfTElOS19NT1VTRVVQOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiTGluayI7CQ0KLQljYXNlIEpFVF9NRU5VX0VYRUM6CQkJcmV0dXJuIChGWF9MUENXU1RSKUwiTWVudSI7DQotCWNhc2UgSkVUX1BBR0VfT1BFTjoNCi0JY2FzZSBKRVRfUEFHRV9DTE9TRToNCi0JY2FzZSBKRVRfUEFHRV9JTlZJRVc6DQotCWNhc2UgSkVUX1BBR0VfT1VUVklFVzpyZXR1cm4gKEZYX0xQQ1dTVFIpTCJQYWdlIjsNCi0JZGVmYXVsdDoNCi0JCXJldHVybiAoRlhfTFBDV1NUUilMIiI7DQotCX0NCi0NCi0JcmV0dXJuIChGWF9MUENXU1RSKUwiIjsNCi19DQotDQotRlhfQk9PTCYgQ0pTX0V2ZW50SGFuZGxlcjo6UmMoKQ0KLXsNCi0JaWYgKG1fcGJSYyAhPSBOVUxMKQ0KLQkJcmV0dXJuICptX3BiUmM7DQotCWVsc2UNCi0JewkgICAgDQotCQlyZXR1cm4gbV9iUmNEdTsNCi0JfQ0KLX0NCi0NCi1pbnQgJiBDSlNfRXZlbnRIYW5kbGVyOjpTZWxFbmQoKQ0KLXsNCi0JaWYgKG1fcElTZWxFbmQgIT0gTlVMTCkNCi0Jew0KLQkJcmV0dXJuICptX3BJU2VsRW5kOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJcmV0dXJuIG1fblNlbEVuZER1Ow0KLQl9DQotfQ0KLQ0KLWludCAmIENKU19FdmVudEhhbmRsZXI6OlNlbFN0YXJ0KCkNCi17DQotCWlmIChtX3BJU2VsU3RhcnQgIT0gTlVMTCkNCi0JCXJldHVybiAqIG1fcElTZWxTdGFydDsNCi0JZWxzZQ0KLQl7DQotCQlyZXR1cm4gbV9uU2VsU3RhcnREdTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIENKU19FdmVudEhhbmRsZXI6OlNoaWZ0KCkNCi17DQotCXJldHVybiBtX2JTaGlmdDsNCi19DQotDQotRmllbGQqIENKU19FdmVudEhhbmRsZXI6OlNvdXJjZSgpDQotew0KLQlBU1NFUlQobV9wSlNDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBtX3BKU0NvbnRleHQtPkdldEpTUnVudGltZSgpOw0KLQ0KLQlKU0ZYT2JqZWN0ICBwRG9jT2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgbV9wSlNDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIkRvY3VtZW50IikpOw0KLQlBU1NFUlQocERvY09iai5Jc0VtcHR5KCkgPT0gRkFMU0UpOw0KLQlKU0ZYT2JqZWN0ICBwRmllbGRPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBtX3BKU0NvbnRleHQsIEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiRmllbGQiKSk7DQotCUFTU0VSVChwRmllbGRPYmouSXNFbXB0eSgpID09IEZBTFNFKTsNCi0NCi0JQ0pTX0RvY3VtZW50KiBwSlNEb2N1bWVudCA9IChDSlNfRG9jdW1lbnQqKUpTX0dldFByaXZhdGUocERvY09iaik7DQotCUFTU0VSVChwSlNEb2N1bWVudCAhPSBOVUxMKTsNCi0JRG9jdW1lbnQqIHBEb2N1bWVudCA9IChEb2N1bWVudCopcEpTRG9jdW1lbnQtPkdldEVtYmVkT2JqZWN0KCk7DQotCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotIAlpZiAobV9wVGFyZ2V0RG9jICE9IE5VTEwpDQotIAkJcERvY3VtZW50LT5BdHRhY2hEb2MobV9wVGFyZ2V0RG9jKTsNCi0gCWVsc2UNCi0gCQlwRG9jdW1lbnQtPkF0dGFjaERvYyhtX3BKU0NvbnRleHQtPkdldFJlYWRlckRvY3VtZW50KCkpOw0KLQkNCi0JLy9pZiAobV9wU291cmNlRmllbGQgPT0gTlVMTCkNCi0JLy8JcmV0dXJuIE5VTEw7DQotCS8vQ1JBT19XaWRnZXQgKnBXaWRnZXQgPSBJQkNMX1dpZGdldDo6R2V0V2lkZ2V0KG1fcFNvdXJjZUZpZWxkKTsNCi0JLy9DUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IHBXaWRnZXQtPkdldEZvcm1GaWVsZCgpOw0KLQkvL0FTU0VSVChwRm9ybUZpZWxkKTsNCi0JLy9DRlhfV2lkZVN0cmluZyBjc0ZpZWxkTmFtZSA9IHBGb3JtRmllbGQtPkdldEZ1bGxOYW1lKCk7DQotCUNKU19GaWVsZCAqIHBKU0ZpZWxkID0gKENKU19GaWVsZCopSlNfR2V0UHJpdmF0ZShwRmllbGRPYmopOw0KLQlBU1NFUlQocEpTRmllbGQgIT0gTlVMTCk7DQotCUZpZWxkICogcEZpZWxkID0gKEZpZWxkICopcEpTRmllbGQtPkdldEVtYmVkT2JqZWN0KCk7IA0KLQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQlwRmllbGQtPkF0dGFjaEZpZWxkKHBEb2N1bWVudCwgbV9zdHJTb3VyY2VOYW1lKTsNCi0JcmV0dXJuIHBGaWVsZDsJDQotfQ0KLQ0KLUZpZWxkKiBDSlNfRXZlbnRIYW5kbGVyOjpUYXJnZXRfRmllbGQoKQ0KLXsNCi0JQVNTRVJUKG1fcEpTQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gbV9wSlNDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsNCi0NCi0JSlNGWE9iamVjdCBwRG9jT2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgbV9wSlNDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIkRvY3VtZW50IikpOw0KLQlBU1NFUlQocERvY09iai5Jc0VtcHR5KCkgPT0gRkFMU0UpOw0KLQlKU0ZYT2JqZWN0IHBGaWVsZE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIG1fcEpTQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJGaWVsZCIpKTsNCi0JQVNTRVJUKHBGaWVsZE9iai5Jc0VtcHR5KCkgPT0gRkFMU0UpOw0KLQ0KLQlDSlNfRG9jdW1lbnQqIHBKU0RvY3VtZW50ID0gKENKU19Eb2N1bWVudCopSlNfR2V0UHJpdmF0ZShwRG9jT2JqKTsNCi0JQVNTRVJUKHBKU0RvY3VtZW50ICE9IE5VTEwpOw0KLQlEb2N1bWVudCogcERvY3VtZW50ID0gKERvY3VtZW50KilwSlNEb2N1bWVudC0+R2V0RW1iZWRPYmplY3QoKTsNCi0gCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7DQotIAlpZiAobV9wVGFyZ2V0RG9jICE9IE5VTEwpDQotIAkJcERvY3VtZW50LT5BdHRhY2hEb2MobV9wVGFyZ2V0RG9jKTsNCi0gCWVsc2UNCi0gCQlwRG9jdW1lbnQtPkF0dGFjaERvYyhtX3BKU0NvbnRleHQtPkdldFJlYWRlckRvY3VtZW50KCkpOw0KLQkNCi0JQ0pTX0ZpZWxkKiBwSlNGaWVsZCA9IChDSlNfRmllbGQqKUpTX0dldFByaXZhdGUocEZpZWxkT2JqKTsNCi0JQVNTRVJUKHBKU0ZpZWxkICE9IE5VTEwpOw0KLQ0KLQlGaWVsZCogcEZpZWxkID0gKEZpZWxkICopcEpTRmllbGQtPkdldEVtYmVkT2JqZWN0KCk7IA0KLQlBU1NFUlQocEZpZWxkICE9IE5VTEwpOw0KLQ0KLQlwRmllbGQtPkF0dGFjaEZpZWxkKHBEb2N1bWVudCwgbV9zdHJUYXJnZXROYW1lKTsNCi0JcmV0dXJuIHBGaWVsZDsJDQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nJiBDSlNfRXZlbnRIYW5kbGVyOjpWYWx1ZSgpDQotew0KLQlyZXR1cm4gKm1fcFZhbHVlOw0KLX0NCi0NCi1GWF9CT09MIENKU19FdmVudEhhbmRsZXI6OldpbGxDb21taXQoKQ0KLXsNCi0JcmV0dXJuIG1fYldpbGxDb21taXQ7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENKU19FdmVudEhhbmRsZXI6OlRhcmdldE5hbWUoKQ0KLXsNCi0JcmV0dXJuIG1fc3RyVGFyZ2V0TmFtZTsNCi19DQotDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIgorLy8jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1Jlc01nci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9Eb2N1bWVudC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENKU19FdmVudEhhbmRsZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDSlNfRXZlbnRIYW5kbGVyOjpDSlNfRXZlbnRIYW5kbGVyKENKU19Db250ZXh0ICogcENvbnRleHQpCSA6CisJbV9wSlNDb250ZXh0KHBDb250ZXh0KSwKKwltX2VFdmVudFR5cGUoSkVUX1VOS05PV04pLAorCW1fYlZhbGlkKEZBTFNFKSwKKwltX3BXaWRlU3RyQ2hhbmdlKE5VTEwpLAorCW1fbkNvbW1pdEtleSgtMSksCisJbV9iS2V5RG93bihGQUxTRSksCisJbV9iTW9kaWZpZXIoRkFMU0UpLAorCW1fYlNoaWZ0KEZBTFNFKSwKKwltX3BJU2VsRW5kKE5VTEwpLAorCW1fblNlbEVuZER1KDApLAorCW1fcElTZWxTdGFydChOVUxMKSwKKwltX25TZWxTdGFydER1KDApLAorCW1fYldpbGxDb21taXQoRkFMU0UpLAorCW1fcFZhbHVlKE5VTEwpLAorCW1fYkZpZWxkRnVsbChGQUxTRSksCisJbV9wYlJjKE5VTEwpLAorCW1fYlJjRHUoRkFMU0UpLAorCW1fcFNvdXJjZURvYyhOVUxMKSwKKwltX3BUYXJnZXRCb29rTWFyayhOVUxMKSwKKwltX3BUYXJnZXREb2MoTlVMTCksCisJbV9wVGFyZ2V0QW5ub3QoTlVMTCkKK3sKK30KKworQ0pTX0V2ZW50SGFuZGxlcjo6fkNKU19FdmVudEhhbmRsZXIoKQoreworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uQXBwX0luaXQoKQoreworCUluaXRpYWwoSkVUX0FQUF9JTklUKTsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkRvY19PcGVuKENQREZTREtfRG9jdW1lbnQqIHBEb2MsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJUYXJnZXROYW1lKQoreworCUluaXRpYWwoSkVUX0RPQ19PUEVOKTsKKworCW1fcFRhcmdldERvYyA9IHBEb2M7CisJbV9zdHJUYXJnZXROYW1lID0gc3RyVGFyZ2V0TmFtZTsJCit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25Eb2NfV2lsbFByaW50KENQREZTREtfRG9jdW1lbnQqIHBEb2MpCit7CisJSW5pdGlhbChKRVRfRE9DX1dJTExQUklOVCk7CisKKwltX3BUYXJnZXREb2MgPSBwRG9jOwkKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkRvY19EaWRQcmludChDUERGU0RLX0RvY3VtZW50KiBwRG9jKQoreworCUluaXRpYWwoSkVUX0RPQ19ESURQUklOVCk7CisJCisJbV9wVGFyZ2V0RG9jID0gcERvYzsJCQorfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRG9jX1dpbGxTYXZlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpCit7CisJSW5pdGlhbChKRVRfRE9DX1dJTExTQVZFKTsKKwltX3BUYXJnZXREb2MgPSBwRG9jOwkJCit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25Eb2NfRGlkU2F2ZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKQoreworCUluaXRpYWwoSkVUX0RPQ19ESURTQVZFKTsJCisJCisJbV9wVGFyZ2V0RG9jID0gcERvYzsJCit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25Eb2NfV2lsbENsb3NlKENQREZTREtfRG9jdW1lbnQqIHBEb2MpCit7CisJSW5pdGlhbChKRVRfRE9DX1dJTExDTE9TRSk7CisKKwltX3BUYXJnZXREb2MgPSBwRG9jOwkKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPblBhZ2VfT3BlbihDUERGU0RLX0RvY3VtZW50KiBwRG9jKQoreworCUluaXRpYWwoSkVUX1BBR0VfT1BFTik7CisKKwltX3BUYXJnZXREb2MgPSBwRG9jOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uUGFnZV9DbG9zZShDUERGU0RLX0RvY3VtZW50KiBwRG9jKQoreworCUluaXRpYWwoSkVUX1BBR0VfQ0xPU0UpOworCQorCW1fcFRhcmdldERvYyA9IHBEb2M7Cit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25QYWdlX0luVmlldyhDUERGU0RLX0RvY3VtZW50KiBwRG9jKQoreworCUluaXRpYWwoSkVUX1BBR0VfSU5WSUVXKTsKKwkKKwltX3BUYXJnZXREb2MgPSBwRG9jOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uUGFnZV9PdXRWaWV3KENQREZTREtfRG9jdW1lbnQqIHBEb2MpCit7CisJSW5pdGlhbChKRVRfUEFHRV9PVVRWSUVXKTsKKwkKKwltX3BUYXJnZXREb2MgPSBwRG9jOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRmllbGRfTW91c2VFbnRlcihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0KQoreworCUluaXRpYWwoSkVUX0ZJRUxEX01PVVNFRU5URVIpOworCisJbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7CisJbV9iU2hpZnQgPSBiU2hpZnQ7CisKKwlBU1NFUlQocFRhcmdldCAhPSBOVUxMKTsKKwltX3N0clRhcmdldE5hbWUgPSBwVGFyZ2V0LT5HZXRGdWxsTmFtZSgpOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRmllbGRfTW91c2VFeGl0KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQpCit7CisJSW5pdGlhbChKRVRfRklFTERfTU9VU0VFWElUKTsKKworCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOworCW1fYlNoaWZ0ID0gYlNoaWZ0OworCUFTU0VSVChwVGFyZ2V0ICE9IE5VTEwpOworCW1fc3RyVGFyZ2V0TmFtZSA9IHBUYXJnZXQtPkdldEZ1bGxOYW1lKCk7CQorfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRmllbGRfTW91c2VEb3duKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQpCit7CisJSW5pdGlhbChKRVRfRklFTERfTU9VU0VET1dOKTsKKwltX2VFdmVudFR5cGUgPSBKRVRfRklFTERfTU9VU0VET1dOOworCQorCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOworCW1fYlNoaWZ0ID0gYlNoaWZ0OwkKKwlBU1NFUlQocFRhcmdldCAhPSBOVUxMKTsKKwltX3N0clRhcmdldE5hbWUgPSBwVGFyZ2V0LT5HZXRGdWxsTmFtZSgpOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRmllbGRfTW91c2VVcChGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0KQoreworCUluaXRpYWwoSkVUX0ZJRUxEX01PVVNFVVApOworCisJbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7CisJbV9iU2hpZnQgPSBiU2hpZnQ7CisJQVNTRVJUKHBUYXJnZXQgIT0gTlVMTCk7CisJbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkZpZWxkX0ZvY3VzKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIAorCQkJCQkJCQkJIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBWYWx1ZSkKK3sKKwlJbml0aWFsKEpFVF9GSUVMRF9GT0NVUyk7CisKKwltX2JNb2RpZmllciA9IGJNb2RpZmllcjsKKwltX2JTaGlmdCA9IGJTaGlmdDsgIAorCUFTU0VSVChwVGFyZ2V0ICE9IE5VTEwpOworCW1fc3RyVGFyZ2V0TmFtZSA9IHBUYXJnZXQtPkdldEZ1bGxOYW1lKCk7CisJbV9wVmFsdWUgPSAoQ0ZYX1dpZGVTdHJpbmcqKSZWYWx1ZTsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkZpZWxkX0JsdXIoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGX0Zvcm1GaWVsZCogcFRhcmdldCwKKwkJCQkJCQkJCWNvbnN0IENGWF9XaWRlU3RyaW5nJiBWYWx1ZSkKK3sKKwlJbml0aWFsKEpFVF9GSUVMRF9CTFVSKTsKKworCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOworCW1fYlNoaWZ0ID0gYlNoaWZ0OworCUFTU0VSVChwVGFyZ2V0ICE9IE5VTEwpOworCW1fc3RyVGFyZ2V0TmFtZSA9IHBUYXJnZXQtPkdldEZ1bGxOYW1lKCk7CisJbV9wVmFsdWUgPSAoQ0ZYX1dpZGVTdHJpbmcqKSZWYWx1ZTsJCit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25GaWVsZF9LZXlzdHJva2UoaW50IG5Db21taXRLZXksIENGWF9XaWRlU3RyaW5nICZzdHJDaGFuZ2UsCisJCQkJCQkJCQkJIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwgRlhfQk9PTCBLZXlEb3duLAorCQkJCQkJCQkJCSBGWF9CT09MIGJNb2RpZmllciwgaW50JiBuU2VsRW5kLCBpbnQmIG5TZWxTdGFydCwKKwkJCQkJCQkJCQkgRlhfQk9PTCBiU2hpZnQsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LAorCQkJCQkJCQkJCSBDRlhfV2lkZVN0cmluZyYgVmFsdWUsIEZYX0JPT0wgYldpbGxDb21taXQsCisJCQkJCQkJCQkJICBGWF9CT09MIGJGaWVsZEZ1bGwsIEZYX0JPT0wmIGJSYykKK3sKKwlJbml0aWFsKEpFVF9GSUVMRF9LRVlTVFJPS0UpOworCQorCW1fbkNvbW1pdEtleSA9IG5Db21taXRLZXk7CisJbV9wV2lkZVN0ckNoYW5nZSA9ICZzdHJDaGFuZ2U7CisJbV9XaWRlU3RyQ2hhbmdlRXggPSBzdHJDaGFuZ2VFeDsKKwltX2JLZXlEb3duID0gS2V5RG93bjsKKwltX2JNb2RpZmllciA9IGJNb2RpZmllcjsKKwltX3BJU2VsRW5kID0gJm5TZWxFbmQ7CisJbV9wSVNlbFN0YXJ0ID0gJm5TZWxTdGFydDsKKwltX2JTaGlmdCA9IGJTaGlmdDsJCisJQVNTRVJUKHBUYXJnZXQgIT0gTlVMTCk7CisJbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsKKwltX3BWYWx1ZSA9ICZWYWx1ZTsKKwltX2JXaWxsQ29tbWl0ID0gYldpbGxDb21taXQ7CQorCW1fcGJSYyA9ICZiUmM7CisJbV9iRmllbGRGdWxsID0gYkZpZWxkRnVsbDsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkZpZWxkX1ZhbGlkYXRlKENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2UsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJDaGFuZ2VFeCwKKwkJCQkJCQkJCQlGWF9CT09MIGJLZXlEb3duLCBGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsCisJCQkJCQkJCQkJQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCYgYlJjKQoreworCUluaXRpYWwoSkVUX0ZJRUxEX1ZBTElEQVRFKTsKKwkKKwltX3BXaWRlU3RyQ2hhbmdlID0gJnN0ckNoYW5nZTsKKwltX1dpZGVTdHJDaGFuZ2VFeCA9IHN0ckNoYW5nZUV4OwkKKwltX2JLZXlEb3duID0gYktleURvd247CisJbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7CisJbV9iU2hpZnQgPSBiU2hpZnQ7CisJQVNTRVJUKHBUYXJnZXQgIT0gTlVMTCk7CisJbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsKKwltX3BWYWx1ZSA9ICZWYWx1ZTsJCisJbV9wYlJjID0gJmJSYzsJCit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25GaWVsZF9DYWxjdWxhdGUoQ1BERl9Gb3JtRmllbGQqIHBTb3VyY2UsIENQREZfRm9ybUZpZWxkKiBwVGFyZ2V0LCAKKwkJCQkJCQkJCQkgQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlLCBGWF9CT09MJiBiUmMpCit7CisJSW5pdGlhbChKRVRfRklFTERfQ0FMQ1VMQVRFKTsKKworCWlmIChwU291cmNlKQorCQltX3N0clNvdXJjZU5hbWUgPSBwU291cmNlLT5HZXRGdWxsTmFtZSgpOworCUFTU0VSVChwVGFyZ2V0ICE9IE5VTEwpOworCW1fc3RyVGFyZ2V0TmFtZSA9IHBUYXJnZXQtPkdldEZ1bGxOYW1lKCk7CisgICAgbV9wVmFsdWUgPSAmVmFsdWU7CisJbV9wYlJjID0gJmJSYzsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkZpZWxkX0Zvcm1hdChpbnQgbkNvbW1pdEtleSwgQ1BERl9Gb3JtRmllbGQqIHBUYXJnZXQsCisJCQkJCQkJCQkgIENGWF9XaWRlU3RyaW5nJiBWYWx1ZSwgRlhfQk9PTCBiV2lsbENvbW1pdCkKK3sKKwlJbml0aWFsKEpFVF9GSUVMRF9GT1JNQVQpOworCQorCW1fbkNvbW1pdEtleSA9IG5Db21taXRLZXk7CSAgCisJQVNTRVJUKHBUYXJnZXQgIT0gTlVMTCk7CisJbV9zdHJUYXJnZXROYW1lID0gcFRhcmdldC0+R2V0RnVsbE5hbWUoKTsKKwltX3BWYWx1ZSA9ICZWYWx1ZTsKKwltX2JXaWxsQ29tbWl0ID0gYldpbGxDb21taXQ7Cit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25TY3JlZW5fRm9jdXMoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUluaXRpYWwoSkVUX1NDUkVFTl9GT0NVUyk7CisKKwltX2JNb2RpZmllciA9IGJNb2RpZmllcjsKKwltX2JTaGlmdCA9IGJTaGlmdDsKKwltX3BUYXJnZXRBbm5vdCA9IHBTY3JlZW47Cit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25TY3JlZW5fQmx1cihGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pCit7CisJSW5pdGlhbChKRVRfU0NSRUVOX0JMVVIpOworCisJbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7CisJbV9iU2hpZnQgPSBiU2hpZnQ7CisJbV9wVGFyZ2V0QW5ub3QgPSBwU2NyZWVuOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uU2NyZWVuX09wZW4oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUluaXRpYWwoSkVUX1NDUkVFTl9PUEVOKTsKKworCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOworCW1fYlNoaWZ0ID0gYlNoaWZ0OworCW1fcFRhcmdldEFubm90ID0gcFNjcmVlbjsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPblNjcmVlbl9DbG9zZShGWF9CT09MIGJNb2RpZmllciwgRlhfQk9PTCBiU2hpZnQsIENQREZTREtfQW5ub3QqIHBTY3JlZW4pCit7CisJSW5pdGlhbChKRVRfU0NSRUVOX0NMT1NFKTsKKworCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOworCW1fYlNoaWZ0ID0gYlNoaWZ0OworCW1fcFRhcmdldEFubm90ID0gcFNjcmVlbjsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPblNjcmVlbl9Nb3VzZURvd24oRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUluaXRpYWwoSkVUX1NDUkVFTl9NT1VTRURPV04pOworCisJbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7CisJbV9iU2hpZnQgPSBiU2hpZnQ7CisJbV9wVGFyZ2V0QW5ub3QgPSBwU2NyZWVuOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uU2NyZWVuX01vdXNlVXAoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUluaXRpYWwoSkVUX1NDUkVFTl9NT1VTRVVQKTsKKworCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOworCW1fYlNoaWZ0ID0gYlNoaWZ0OworCW1fcFRhcmdldEFubm90ID0gcFNjcmVlbjsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPblNjcmVlbl9Nb3VzZUVudGVyKEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikKK3sKKwlJbml0aWFsKEpFVF9TQ1JFRU5fTU9VU0VFTlRFUik7CisKKwltX2JNb2RpZmllciA9IGJNb2RpZmllcjsKKwltX2JTaGlmdCA9IGJTaGlmdDsKKwltX3BUYXJnZXRBbm5vdCA9IHBTY3JlZW47Cit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25TY3JlZW5fTW91c2VFeGl0KEZYX0JPT0wgYk1vZGlmaWVyLCBGWF9CT09MIGJTaGlmdCwgQ1BERlNES19Bbm5vdCogcFNjcmVlbikKK3sKKwlJbml0aWFsKEpFVF9TQ1JFRU5fTU9VU0VFWElUKTsKKworCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOworCW1fYlNoaWZ0ID0gYlNoaWZ0OworCW1fcFRhcmdldEFubm90ID0gcFNjcmVlbjsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPblNjcmVlbl9JblZpZXcoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUluaXRpYWwoSkVUX1NDUkVFTl9JTlZJRVcpOworCisJbV9iTW9kaWZpZXIgPSBiTW9kaWZpZXI7CisJbV9iU2hpZnQgPSBiU2hpZnQ7CisJbV9wVGFyZ2V0QW5ub3QgPSBwU2NyZWVuOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uU2NyZWVuX091dFZpZXcoRlhfQk9PTCBiTW9kaWZpZXIsIEZYX0JPT0wgYlNoaWZ0LCBDUERGU0RLX0Fubm90KiBwU2NyZWVuKQoreworCUluaXRpYWwoSkVUX1NDUkVFTl9PVVRWSUVXKTsKKworCW1fYk1vZGlmaWVyID0gYk1vZGlmaWVyOworCW1fYlNoaWZ0ID0gYlNoaWZ0OworCW1fcFRhcmdldEFubm90ID0gcFNjcmVlbjsKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbkxpbmtfTW91c2VVcChDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0KQoreworCUluaXRpYWwoSkVUX0xJTktfTU9VU0VVUCk7CisJCisJbV9wVGFyZ2V0RG9jID0gcFRhcmdldDsJCit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25Cb29rbWFya19Nb3VzZVVwKENQREZfQm9va21hcmsqIHBCb29rTWFyaykKK3sKKwlJbml0aWFsKEpFVF9CT09LTUFSS19NT1VTRVVQKTsKKworCW1fcFRhcmdldEJvb2tNYXJrID0gcEJvb2tNYXJrOwkKK30KKwordm9pZCBDSlNfRXZlbnRIYW5kbGVyOjpPbk1lbnVfRXhlYyhDUERGU0RLX0RvY3VtZW50KiBwVGFyZ2V0LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyVGFyZ2V0TmFtZSkKK3sKKwlJbml0aWFsKEpFVF9NRU5VX0VYRUMpOworCisJbV9wVGFyZ2V0RG9jID0gcFRhcmdldDsKKwltX3N0clRhcmdldE5hbWUgPSBzdHJUYXJnZXROYW1lOworfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uRXh0ZXJuYWxfRXhlYygpCit7CisJSW5pdGlhbChKRVRfRVhURVJOQUxfRVhFQyk7Cit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6T25CYXRjaEV4ZWMoQ1BERlNES19Eb2N1bWVudCogcFRhcmdldCkKK3sKKwlJbml0aWFsKEpFVF9CQVRDSF9FWEVDKTsKKworCW1fcFRhcmdldERvYyA9IHBUYXJnZXQ7CQorfQorCit2b2lkIENKU19FdmVudEhhbmRsZXI6Ok9uQ29uc29sZV9FeGVjKCkKK3sKKwlJbml0aWFsKEpFVF9DT05TT0xFX0VYRUMpOworfQorCisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6SW5pdGlhbChKU19FVkVOVF9UIHR5cGUpCit7CisJbV9lRXZlbnRUeXBlID0gdHlwZTsKKworCW1fc3RyVGFyZ2V0TmFtZSA9IEwiIjsKKwltX3N0clNvdXJjZU5hbWUgPSBMIiI7CisJbV9wV2lkZVN0ckNoYW5nZSA9IE5VTEw7CisJbV9XaWRlU3RyQ2hhbmdlRHUgPSBMIiI7CisJbV9XaWRlU3RyQ2hhbmdlRXggPSBMIiI7CisJbV9uQ29tbWl0S2V5ID0gLTE7CisJbV9iS2V5RG93biA9IEZBTFNFOworCW1fYk1vZGlmaWVyID0gRkFMU0U7CisJbV9iU2hpZnQgPSBGQUxTRTsKKwltX3BJU2VsRW5kID0gTlVMTDsKKwltX25TZWxFbmREdSA9IDA7CisJbV9wSVNlbFN0YXJ0ID0gTlVMTDsKKwltX25TZWxTdGFydER1ID0gMDsKKwltX2JXaWxsQ29tbWl0ID0gRkFMU0U7CisJbV9wVmFsdWUgPSBOVUxMOworCW1fYkZpZWxkRnVsbCA9IEZBTFNFOworCW1fcGJSYyA9IE5VTEw7CisJbV9iUmNEdSA9IEZBTFNFOworCisJbV9wU291cmNlRG9jID0gTlVMTDsKKwltX3BUYXJnZXRCb29rTWFyayA9IE5VTEw7CisJbV9wVGFyZ2V0RG9jID0gTlVMTDsKKwltX3BUYXJnZXRBbm5vdCA9IE5VTEw7CisKKwltX2JWYWxpZCA9IFRSVUU7Cit9CisKK3ZvaWQgQ0pTX0V2ZW50SGFuZGxlcjo6RGVzdHJveSgpCit7CisJbV9iVmFsaWQgPSBGQUxTRTsKK30KKworRlhfQk9PTCBDSlNfRXZlbnRIYW5kbGVyOjpJc1ZhbGlkKCkKK3sKKwlyZXR1cm4gbV9iVmFsaWQ7Cit9CisKK0NGWF9XaWRlU3RyaW5nICYgQ0pTX0V2ZW50SGFuZGxlcjo6Q2hhbmdlKCkKK3sKKwlpZiAobV9wV2lkZVN0ckNoYW5nZSAhPSBOVUxMKQorCQlyZXR1cm4gKm1fcFdpZGVTdHJDaGFuZ2U7CisJZWxzZQorCXsKKwkJcmV0dXJuIG1fV2lkZVN0ckNoYW5nZUR1OworCX0KK30KKworQ0ZYX1dpZGVTdHJpbmcgQ0pTX0V2ZW50SGFuZGxlcjo6Q2hhbmdlRXgoKQoreworCXJldHVybiBtX1dpZGVTdHJDaGFuZ2VFeDsKK30KKworaW50IENKU19FdmVudEhhbmRsZXI6OkNvbW1pdEtleSgpCit7CisJcmV0dXJuIG1fbkNvbW1pdEtleTsKK30KKworRlhfQk9PTCBDSlNfRXZlbnRIYW5kbGVyOjpGaWVsZEZ1bGwoKQoreworCXJldHVybiBtX2JGaWVsZEZ1bGw7Cit9CisKK0ZYX0JPT0wgQ0pTX0V2ZW50SGFuZGxlcjo6S2V5RG93bigpCit7CisJcmV0dXJuIG1fYktleURvd247Cit9CisKK0ZYX0JPT0wgQ0pTX0V2ZW50SGFuZGxlcjo6TW9kaWZpZXIoKQoreworCXJldHVybiBtX2JNb2RpZmllcjsKK30KKworRlhfTFBDV1NUUiBDSlNfRXZlbnRIYW5kbGVyOjpOYW1lKCkKK3sKKwlzd2l0Y2ggKG1fZUV2ZW50VHlwZSkKKwl7CisJY2FzZSBKRVRfQVBQX0lOSVQ6CQkJcmV0dXJuIChGWF9MUENXU1RSKUwiSW5pdCI7CisJY2FzZSBKRVRfQkFUQ0hfRVhFQzoJCXJldHVybiAoRlhfTFBDV1NUUilMIkV4ZWMiOworCWNhc2UgSkVUX0JPT0tNQVJLX01PVVNFVVA6CXJldHVybiAoRlhfTFBDV1NUUilMIk1vdXNlIFVwIjsKKwljYXNlIEpFVF9DT05TT0xFX0VYRUM6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJFeGVjIjsKKwljYXNlIEpFVF9ET0NfRElEUFJJTlQ6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJEaWRQcmludCI7CisJY2FzZSBKRVRfRE9DX0RJRFNBVkU6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJEaWRTYXZlIjsKKwljYXNlIEpFVF9ET0NfT1BFTjoJCQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJPcGVuIjsKKwljYXNlIEpFVF9ET0NfV0lMTENMT1NFOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiV2lsbENsb3NlIjsKKwljYXNlIEpFVF9ET0NfV0lMTFBSSU5UOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiV2lsbFByaW50IjsKKwljYXNlIEpFVF9ET0NfV0lMTFNBVkU6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJXaWxsU2F2ZSI7CisJY2FzZSBKRVRfRVhURVJOQUxfRVhFQzoJCXJldHVybiAoRlhfTFBDV1NUUilMIkV4ZWMiOworCWNhc2UgSkVUX0ZJRUxEX0ZPQ1VTOgkJCisJY2FzZSBKRVRfU0NSRUVOX0ZPQ1VTOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiRm9jdXMiOworCWNhc2UgSkVUX0ZJRUxEX0JMVVI6CQkKKwljYXNlIEpFVF9TQ1JFRU5fQkxVUjoJCXJldHVybiAoRlhfTFBDV1NUUilMIkJsdXIiOworCWNhc2UgSkVUX0ZJRUxEX01PVVNFRE9XTjoKKwljYXNlIEpFVF9TQ1JFRU5fTU9VU0VET1dOOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJNb3VzZSBEb3duIjsKKwljYXNlIEpFVF9GSUVMRF9NT1VTRVVQOgkJCisJY2FzZSBKRVRfU0NSRUVOX01PVVNFVVA6CXJldHVybiAoRlhfTFBDV1NUUilMIk1vdXNlIFVwIjsKKwljYXNlIEpFVF9GSUVMRF9NT1VTRUVOVEVSOgorCWNhc2UgSkVUX1NDUkVFTl9NT1VTRUVOVEVSOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJNb3VzZSBFbnRlciI7CisJY2FzZSBKRVRfRklFTERfTU9VU0VFWElUOgorCWNhc2UgSkVUX1NDUkVFTl9NT1VTRUVYSVQ6CXJldHVybiAoRlhfTFBDV1NUUilMIk1vdXNlIEV4aXQiOworCWNhc2UgSkVUX0ZJRUxEX0NBTENVTEFURToJcmV0dXJuIChGWF9MUENXU1RSKUwiQ2FsY3VsYXRlIjsKKwljYXNlIEpFVF9GSUVMRF9GT1JNQVQ6CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJGb3JtYXQiOworCWNhc2UgSkVUX0ZJRUxEX0tFWVNUUk9LRToJcmV0dXJuIChGWF9MUENXU1RSKUwiS2V5c3Ryb2tlIjsKKwljYXNlIEpFVF9GSUVMRF9WQUxJREFURToJcmV0dXJuIChGWF9MUENXU1RSKUwiVmFsaWRhdGUiOworCWNhc2UgSkVUX0xJTktfTU9VU0VVUDoJCXJldHVybiAoRlhfTFBDV1NUUilMIk1vdXNlIFVwIjsKKwljYXNlIEpFVF9NRU5VX0VYRUM6CQkJcmV0dXJuIChGWF9MUENXU1RSKUwiRXhlYyI7CisJY2FzZSBKRVRfUEFHRV9PUEVOOgkJCisJY2FzZSBKRVRfU0NSRUVOX09QRU46CQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCJPcGVuIjsKKwljYXNlIEpFVF9QQUdFX0NMT1NFOgorCWNhc2UgSkVUX1NDUkVFTl9DTE9TRToJCXJldHVybiAoRlhfTFBDV1NUUilMIkNsb3NlIjsKKwljYXNlIEpFVF9TQ1JFRU5fSU5WSUVXOgkKKwljYXNlIEpFVF9QQUdFX0lOVklFVzoJCXJldHVybiAoRlhfTFBDV1NUUilMIkluVmlldyI7CisJY2FzZSBKRVRfUEFHRV9PVVRWSUVXOgorCWNhc2UgSkVUX1NDUkVFTl9PVVRWSUVXOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJPdXRWaWV3IjsKKwlkZWZhdWx0OgorCQlyZXR1cm4gKEZYX0xQQ1dTVFIpTCIiOworCX0KKworCXJldHVybiAoRlhfTFBDV1NUUilMIiI7Cit9CisKK0ZYX0xQQ1dTVFIgQ0pTX0V2ZW50SGFuZGxlcjo6VHlwZSgpCit7CisJc3dpdGNoIChtX2VFdmVudFR5cGUpCisJeworCWNhc2UgSkVUX0FQUF9JTklUOgkJCXJldHVybiAoRlhfTFBDV1NUUilMIkFwcCI7CisJY2FzZSBKRVRfQkFUQ0hfRVhFQzoJCXJldHVybiAoRlhfTFBDV1NUUilMIkJhdGNoIjsKKwljYXNlIEpFVF9CT09LTUFSS19NT1VTRVVQOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJCb29rTWFyayI7CQorCWNhc2UgSkVUX0NPTlNPTEVfRVhFQzoJCXJldHVybiAoRlhfTFBDV1NUUilMIkNvbnNvbGUiOworCWNhc2UgSkVUX0RPQ19ESURQUklOVDoKKwljYXNlIEpFVF9ET0NfRElEU0FWRToKKwljYXNlIEpFVF9ET0NfT1BFTjoKKwljYXNlIEpFVF9ET0NfV0lMTENMT1NFOgorCWNhc2UgSkVUX0RPQ19XSUxMUFJJTlQ6CisJY2FzZSBKRVRfRE9DX1dJTExTQVZFOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiRG9jIjsKKwljYXNlIEpFVF9FWFRFUk5BTF9FWEVDOgkJcmV0dXJuIChGWF9MUENXU1RSKUwiRXh0ZXJuYWwiOworCWNhc2UgSkVUX0ZJRUxEX0JMVVI6CisJY2FzZSBKRVRfRklFTERfRk9DVVM6CisJY2FzZSBKRVRfRklFTERfTU9VU0VET1dOOgorCWNhc2UgSkVUX0ZJRUxEX01PVVNFRU5URVI6CisJY2FzZSBKRVRfRklFTERfTU9VU0VFWElUOgorCWNhc2UgSkVUX0ZJRUxEX01PVVNFVVA6CisJY2FzZSBKRVRfRklFTERfQ0FMQ1VMQVRFOgorCWNhc2UgSkVUX0ZJRUxEX0ZPUk1BVDoKKwljYXNlIEpFVF9GSUVMRF9LRVlTVFJPS0U6CisJY2FzZSBKRVRfRklFTERfVkFMSURBVEU6CXJldHVybiAoRlhfTFBDV1NUUilMIkZpZWxkIjsKKwljYXNlIEpFVF9TQ1JFRU5fRk9DVVM6CisJY2FzZSBKRVRfU0NSRUVOX0JMVVI6CisJY2FzZSBKRVRfU0NSRUVOX09QRU46CisJY2FzZSBKRVRfU0NSRUVOX0NMT1NFOgorCWNhc2UgSkVUX1NDUkVFTl9NT1VTRURPV046CisJY2FzZSBKRVRfU0NSRUVOX01PVVNFVVA6CisJY2FzZSBKRVRfU0NSRUVOX01PVVNFRU5URVI6CisJY2FzZSBKRVRfU0NSRUVOX01PVVNFRVhJVDoKKwljYXNlIEpFVF9TQ1JFRU5fSU5WSUVXOgorCWNhc2UgSkVUX1NDUkVFTl9PVVRWSUVXOglyZXR1cm4gKEZYX0xQQ1dTVFIpTCJTY3JlZW4iOworCWNhc2UgSkVUX0xJTktfTU9VU0VVUDoJCXJldHVybiAoRlhfTFBDV1NUUilMIkxpbmsiOwkKKwljYXNlIEpFVF9NRU5VX0VYRUM6CQkJcmV0dXJuIChGWF9MUENXU1RSKUwiTWVudSI7CisJY2FzZSBKRVRfUEFHRV9PUEVOOgorCWNhc2UgSkVUX1BBR0VfQ0xPU0U6CisJY2FzZSBKRVRfUEFHRV9JTlZJRVc6CisJY2FzZSBKRVRfUEFHRV9PVVRWSUVXOnJldHVybiAoRlhfTFBDV1NUUilMIlBhZ2UiOworCWRlZmF1bHQ6CisJCXJldHVybiAoRlhfTFBDV1NUUilMIiI7CisJfQorCisJcmV0dXJuIChGWF9MUENXU1RSKUwiIjsKK30KKworRlhfQk9PTCYgQ0pTX0V2ZW50SGFuZGxlcjo6UmMoKQoreworCWlmIChtX3BiUmMgIT0gTlVMTCkKKwkJcmV0dXJuICptX3BiUmM7CisJZWxzZQorCXsJICAgIAorCQlyZXR1cm4gbV9iUmNEdTsKKwl9Cit9CisKK2ludCAmIENKU19FdmVudEhhbmRsZXI6OlNlbEVuZCgpCit7CisJaWYgKG1fcElTZWxFbmQgIT0gTlVMTCkKKwl7CisJCXJldHVybiAqbV9wSVNlbEVuZDsKKwl9CisJZWxzZQorCXsKKwkJcmV0dXJuIG1fblNlbEVuZER1OworCX0KK30KKworaW50ICYgQ0pTX0V2ZW50SGFuZGxlcjo6U2VsU3RhcnQoKQoreworCWlmIChtX3BJU2VsU3RhcnQgIT0gTlVMTCkKKwkJcmV0dXJuICogbV9wSVNlbFN0YXJ0OworCWVsc2UKKwl7CisJCXJldHVybiBtX25TZWxTdGFydER1OworCX0KK30KKworRlhfQk9PTCBDSlNfRXZlbnRIYW5kbGVyOjpTaGlmdCgpCit7CisJcmV0dXJuIG1fYlNoaWZ0OworfQorCitGaWVsZCogQ0pTX0V2ZW50SGFuZGxlcjo6U291cmNlKCkKK3sKKwlBU1NFUlQobV9wSlNDb250ZXh0ICE9IE5VTEwpOworCisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gbV9wSlNDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKworCUpTRlhPYmplY3QgIHBEb2NPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBtX3BKU0NvbnRleHQsIEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiRG9jdW1lbnQiKSk7CisJQVNTRVJUKHBEb2NPYmouSXNFbXB0eSgpID09IEZBTFNFKTsKKwlKU0ZYT2JqZWN0ICBwRmllbGRPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBtX3BKU0NvbnRleHQsIEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiRmllbGQiKSk7CisJQVNTRVJUKHBGaWVsZE9iai5Jc0VtcHR5KCkgPT0gRkFMU0UpOworCisJQ0pTX0RvY3VtZW50KiBwSlNEb2N1bWVudCA9IChDSlNfRG9jdW1lbnQqKUpTX0dldFByaXZhdGUocERvY09iaik7CisJQVNTRVJUKHBKU0RvY3VtZW50ICE9IE5VTEwpOworCURvY3VtZW50KiBwRG9jdW1lbnQgPSAoRG9jdW1lbnQqKXBKU0RvY3VtZW50LT5HZXRFbWJlZE9iamVjdCgpOworCUFTU0VSVChwRG9jdW1lbnQgIT0gTlVMTCk7CisgCWlmIChtX3BUYXJnZXREb2MgIT0gTlVMTCkKKyAJCXBEb2N1bWVudC0+QXR0YWNoRG9jKG1fcFRhcmdldERvYyk7CisgCWVsc2UKKyAJCXBEb2N1bWVudC0+QXR0YWNoRG9jKG1fcEpTQ29udGV4dC0+R2V0UmVhZGVyRG9jdW1lbnQoKSk7CisJCisJLy9pZiAobV9wU291cmNlRmllbGQgPT0gTlVMTCkKKwkvLwlyZXR1cm4gTlVMTDsKKwkvL0NSQU9fV2lkZ2V0ICpwV2lkZ2V0ID0gSUJDTF9XaWRnZXQ6OkdldFdpZGdldChtX3BTb3VyY2VGaWVsZCk7CisJLy9DUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IHBXaWRnZXQtPkdldEZvcm1GaWVsZCgpOworCS8vQVNTRVJUKHBGb3JtRmllbGQpOworCS8vQ0ZYX1dpZGVTdHJpbmcgY3NGaWVsZE5hbWUgPSBwRm9ybUZpZWxkLT5HZXRGdWxsTmFtZSgpOworCUNKU19GaWVsZCAqIHBKU0ZpZWxkID0gKENKU19GaWVsZCopSlNfR2V0UHJpdmF0ZShwRmllbGRPYmopOworCUFTU0VSVChwSlNGaWVsZCAhPSBOVUxMKTsKKwlGaWVsZCAqIHBGaWVsZCA9IChGaWVsZCAqKXBKU0ZpZWxkLT5HZXRFbWJlZE9iamVjdCgpOyAKKwlBU1NFUlQocEZpZWxkICE9IE5VTEwpOworCXBGaWVsZC0+QXR0YWNoRmllbGQocERvY3VtZW50LCBtX3N0clNvdXJjZU5hbWUpOworCXJldHVybiBwRmllbGQ7CQorfQorCitGaWVsZCogQ0pTX0V2ZW50SGFuZGxlcjo6VGFyZ2V0X0ZpZWxkKCkKK3sKKwlBU1NFUlQobV9wSlNDb250ZXh0ICE9IE5VTEwpOworCisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gbV9wSlNDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKworCUpTRlhPYmplY3QgcERvY09iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIG1fcEpTQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJEb2N1bWVudCIpKTsKKwlBU1NFUlQocERvY09iai5Jc0VtcHR5KCkgPT0gRkFMU0UpOworCUpTRlhPYmplY3QgcEZpZWxkT2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgbV9wSlNDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIkZpZWxkIikpOworCUFTU0VSVChwRmllbGRPYmouSXNFbXB0eSgpID09IEZBTFNFKTsKKworCUNKU19Eb2N1bWVudCogcEpTRG9jdW1lbnQgPSAoQ0pTX0RvY3VtZW50KilKU19HZXRQcml2YXRlKHBEb2NPYmopOworCUFTU0VSVChwSlNEb2N1bWVudCAhPSBOVUxMKTsKKwlEb2N1bWVudCogcERvY3VtZW50ID0gKERvY3VtZW50KilwSlNEb2N1bWVudC0+R2V0RW1iZWRPYmplY3QoKTsKKyAJQVNTRVJUKHBEb2N1bWVudCAhPSBOVUxMKTsKKyAJaWYgKG1fcFRhcmdldERvYyAhPSBOVUxMKQorIAkJcERvY3VtZW50LT5BdHRhY2hEb2MobV9wVGFyZ2V0RG9jKTsKKyAJZWxzZQorIAkJcERvY3VtZW50LT5BdHRhY2hEb2MobV9wSlNDb250ZXh0LT5HZXRSZWFkZXJEb2N1bWVudCgpKTsKKwkKKwlDSlNfRmllbGQqIHBKU0ZpZWxkID0gKENKU19GaWVsZCopSlNfR2V0UHJpdmF0ZShwRmllbGRPYmopOworCUFTU0VSVChwSlNGaWVsZCAhPSBOVUxMKTsKKworCUZpZWxkKiBwRmllbGQgPSAoRmllbGQgKilwSlNGaWVsZC0+R2V0RW1iZWRPYmplY3QoKTsgCisJQVNTRVJUKHBGaWVsZCAhPSBOVUxMKTsKKworCXBGaWVsZC0+QXR0YWNoRmllbGQocERvY3VtZW50LCBtX3N0clRhcmdldE5hbWUpOworCXJldHVybiBwRmllbGQ7CQorfQorCitDRlhfV2lkZVN0cmluZyYgQ0pTX0V2ZW50SGFuZGxlcjo6VmFsdWUoKQoreworCXJldHVybiAqbV9wVmFsdWU7Cit9CisKK0ZYX0JPT0wgQ0pTX0V2ZW50SGFuZGxlcjo6V2lsbENvbW1pdCgpCit7CisJcmV0dXJuIG1fYldpbGxDb21taXQ7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENKU19FdmVudEhhbmRsZXI6OlRhcmdldE5hbWUoKQoreworCXJldHVybiBtX3N0clRhcmdldE5hbWU7Cit9CisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9KU19HbG9iYWxEYXRhLmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSlNfR2xvYmFsRGF0YS5jcHAKaW5kZXggOTdiYmE4ZC4uMjIwNzcyNiAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9KU19HbG9iYWxEYXRhLmNwcAorKysgYi9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX0dsb2JhbERhdGEuY3BwCkBAIC0xLDU4MSArMSw1ODEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0dsb2JhbERhdGEuaCINCi0NCi0jZGVmaW5lIEpTX01BWEdMT0JBTERBVEEJCQkoMTAyNCAqIDQgLSA4KQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfR2xvYmFsVmFyaWFibGVBcnJheSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DSlNfR2xvYmFsVmFyaWFibGVBcnJheTo6Q0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkoKQ0KLXsNCi19DQotDQotQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk6On5DSlNfR2xvYmFsVmFyaWFibGVBcnJheSgpDQotew0KLQlFbXB0eSgpOw0KLX0NCi0NCi12b2lkIENKU19HbG9iYWxWYXJpYWJsZUFycmF5OjpDb3B5KGNvbnN0IENKU19HbG9iYWxWYXJpYWJsZUFycmF5JiBhcnJheSkNCi17DQotCUVtcHR5KCk7DQotCWZvciAoaW50IGk9MCxzej1hcnJheS5Db3VudCgpOyBpPHN6OyBpKyspDQotCXsNCi0JCUNKU19LZXlWYWx1ZSogcE9sZE9iakRhdGEgPSBhcnJheS5HZXRBdChpKTsNCi0JCUFTU0VSVChwT2xkT2JqRGF0YSAhPSBOVUxMKTsNCi0NCi0JCXN3aXRjaCAocE9sZE9iakRhdGEtPm5UeXBlKQ0KLQkJew0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOg0KLQkJCXsNCi0JCQkJQ0pTX0tleVZhbHVlKiBwTmV3T2JqRGF0YSA9IG5ldyBDSlNfS2V5VmFsdWU7DQotCQkJCXBOZXdPYmpEYXRhLT5zS2V5ID0gcE9sZE9iakRhdGEtPnNLZXk7DQotCQkJCXBOZXdPYmpEYXRhLT5uVHlwZSA9IHBPbGRPYmpEYXRhLT5uVHlwZTsNCi0JCQkJcE5ld09iakRhdGEtPmREYXRhID0gcE9sZE9iakRhdGEtPmREYXRhOw0KLQkJCQlBZGQocE5ld09iakRhdGEpOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46DQotCQkJew0KLQkJCQlDSlNfS2V5VmFsdWUqIHBOZXdPYmpEYXRhID0gbmV3IENKU19LZXlWYWx1ZTsNCi0JCQkJcE5ld09iakRhdGEtPnNLZXkgPSBwT2xkT2JqRGF0YS0+c0tleTsNCi0JCQkJcE5ld09iakRhdGEtPm5UeXBlID0gcE9sZE9iakRhdGEtPm5UeXBlOw0KLQkJCQlwTmV3T2JqRGF0YS0+YkRhdGEgPSBwT2xkT2JqRGF0YS0+YkRhdGE7DQotCQkJCUFkZChwTmV3T2JqRGF0YSk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOg0KLQkJCXsNCi0JCQkJQ0pTX0tleVZhbHVlKiBwTmV3T2JqRGF0YSA9IG5ldyBDSlNfS2V5VmFsdWU7DQotCQkJCXBOZXdPYmpEYXRhLT5zS2V5ID0gcE9sZE9iakRhdGEtPnNLZXk7DQotCQkJCXBOZXdPYmpEYXRhLT5uVHlwZSA9IHBPbGRPYmpEYXRhLT5uVHlwZTsNCi0JCQkJcE5ld09iakRhdGEtPnNEYXRhID0gcE9sZE9iakRhdGEtPnNEYXRhOw0KLQkJCQlBZGQocE5ld09iakRhdGEpOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDoNCi0JCQl7DQotCQkJCUNKU19LZXlWYWx1ZSogcE5ld09iakRhdGEgPSBuZXcgQ0pTX0tleVZhbHVlOw0KLQkJCQlwTmV3T2JqRGF0YS0+c0tleSA9IHBPbGRPYmpEYXRhLT5zS2V5Ow0KLQkJCQlwTmV3T2JqRGF0YS0+blR5cGUgPSBwT2xkT2JqRGF0YS0+blR5cGU7DQotCQkJCXBOZXdPYmpEYXRhLT5vYmpEYXRhLkNvcHkocE9sZE9iakRhdGEtPm9iakRhdGEpOw0KLQkJCQlBZGQocE5ld09iakRhdGEpOw0KLQkJCX0NCi0JCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTEw6DQotCQkJew0KLQkJCQlDSlNfS2V5VmFsdWUqIHBOZXdPYmpEYXRhID0gbmV3IENKU19LZXlWYWx1ZTsNCi0JCQkJcE5ld09iakRhdGEtPnNLZXkgPSBwT2xkT2JqRGF0YS0+c0tleTsNCi0JCQkJcE5ld09iakRhdGEtPm5UeXBlID0gcE9sZE9iakRhdGEtPm5UeXBlOw0KLQkJCQlBZGQocE5ld09iakRhdGEpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENKU19HbG9iYWxWYXJpYWJsZUFycmF5OjpBZGQoQ0pTX0tleVZhbHVlKiBwKQ0KLXsNCi0JYXJyYXkuQWRkKHApOw0KLX0NCi0NCi1pbnQgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk6OkNvdW50KCkgY29uc3QNCi17DQotCXJldHVybiBhcnJheS5HZXRTaXplKCk7DQotfQ0KLQ0KLUNKU19LZXlWYWx1ZSogQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk6OkdldEF0KGludCBpbmRleCkgY29uc3QNCi17DQotCXJldHVybiBhcnJheS5HZXRBdChpbmRleCk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk6OkVtcHR5KCkNCi17DQotCWZvciAoaW50IGk9MCxzej1hcnJheS5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCWRlbGV0ZSBhcnJheS5HZXRBdChpKTsNCi0JYXJyYXkuUmVtb3ZlQWxsKCk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENKU19HbG9iYWxEYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotI2RlZmluZSBSRUFERVJfSlNfR0xPQkFMREFUQV9GSUxFTkFNRQkJCQlMIlJlYWRlcl9Kc0dsb2JhbC5EYXRhIg0KLSNkZWZpbmUgUEhBTlRPTV9KU19HTE9CQUxEQVRBX0ZJTEVOQU1FCQkJCUwiUGhhbnRvbV9Kc0dsb2JhbC5EYXRhIg0KLSNkZWZpbmUgU0RLX0pTX0dMT0JBTERBVEFfRklMRU5BTUUJCQkJCUwiU0RLX0pzR2xvYmFsLkRhdGEiDQotDQotc3RhdGljIGNvbnN0IEZYX0JZVEUgSlNfUkM0S0VZW10gPSB7MHgxOSwweGE4LDB4ZTgsMHgwMSwweGY2LDB4YTgsMHhiNiwweDRkLDB4ODIsMHgwNCwNCi0JCQkJCQkJMHg0NSwweDZkLDB4YjQsMHhjZiwweGQ3LDB4NzcsMHg2NywweGY5LDB4NzUsMHg5ZiwNCi0JCQkJCQkJMHhmMCwweGUwLDB4MWUsMHg1MSwweGVlLDB4NDYsMHhmZCwweDBiLDB4YzksMHg5MywNCi0JCQkJCQkJMHgyNSwweDU1LDB4NGEsMHhlZSwweGUwLDB4MTYsMHhkMCwweGRmLDB4OGMsMHhmYSwNCi0JCQkJCQkJMHgyYSwweGE5LDB4NDksMHhmZCwweDk3LDB4MWMsMHgwZSwweDIyLDB4MTMsMHgyOCwNCi0JCQkJCQkJMHg3YywweGFmLDB4YzQsMHhmYywweDljLDB4MTIsMHg2NSwweDhjLDB4NGUsMHg1YiwNCi0JCQkJCQkJMHgwNCwweDc1LDB4ODksMHhjOSwweGIxLDB4ZWQsMHg1MCwweGNhLDB4OTYsMHg2ZiwNCi0JCQkJCQkJMHgxYSwweDdhLDB4ZmUsMHg1OCwweDVkLDB4ZWMsMHgxOSwweDRhLDB4ZjYsMHgzNSwNCi0JCQkJCQkJMHg2YSwweDk3LDB4MTQsMHgwMCwweDBlLDB4ZDAsMHg2YiwweGJiLDB4ZDUsMHg3NSwNCi0JCQkJCQkJMHg1NSwweDhiLDB4NmUsMHg2YiwweDE5LDB4YTAsMHhmOCwweDc3LDB4ZDUsMHhhMw0KLQkJCQkJCQl9Ow0KLQ0KLUNKU19HbG9iYWxEYXRhOjpDSlNfR2xvYmFsRGF0YShDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwKSA6IG1fcEFwcChwQXBwKQ0KLXsNCi0vLyAJSUJhc2VBbm5vdCogcEJhc2VBbm5vdCA9IElCYXNlQW5ub3Q6OkdldEJhc2VBbm5vdChtX3BBcHApOw0KLS8vIAlBU1NFUlQocEJhc2VBbm5vdCAhPSBOVUxMKTsNCi0vLyANCi0vLyAJbV9zRmlsZVBhdGggPSBwQmFzZUFubm90LT5HZXRVc2VyUGF0aCgpOw0KLQltX3NGaWxlUGF0aCArPSBTREtfSlNfR0xPQkFMREFUQV9GSUxFTkFNRTsNCi0NCi0JTG9hZEdsb2JhbFBlcnNpc3RlbnRWYXJpYWJsZXMoKTsNCi19DQotDQotQ0pTX0dsb2JhbERhdGE6On5DSlNfR2xvYmFsRGF0YSgpDQotew0KLQlTYXZlR2xvYmFsUGVyc2lzaXRlbnRWYXJpYWJsZXMoKTsNCi0NCi0JZm9yIChpbnQgaT0wLHN6PW1fYXJyYXlHbG9iYWxEYXRhLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJZGVsZXRlIG1fYXJyYXlHbG9iYWxEYXRhLkdldEF0KGkpOw0KLQ0KLQltX2FycmF5R2xvYmFsRGF0YS5SZW1vdmVBbGwoKTsNCi19DQotDQotaW50CUNKU19HbG9iYWxEYXRhOjpGaW5kR2xvYmFsVmFyaWFibGUoRlhfTFBDU1RSIHByb3BuYW1lKQ0KLXsNCi0JQVNTRVJUKHByb3BuYW1lICE9IE5VTEwpOw0KLQ0KLQlpbnQgblJldCA9IC0xOw0KLQ0KLQlmb3IgKGludCBpPTAsc3o9bV9hcnJheUdsb2JhbERhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCUNKU19HbG9iYWxEYXRhX0VsZW1lbnQqIHBUZW1wID0gbV9hcnJheUdsb2JhbERhdGEuR2V0QXQoaSk7DQotCQlpZiAocFRlbXAtPmRhdGEuc0tleVswXSA9PSAqcHJvcG5hbWUgJiYgcFRlbXAtPmRhdGEuc0tleSA9PSBwcm9wbmFtZSkNCi0JCXsNCi0JCQluUmV0ID0gaTsNCi0JCQlicmVhazsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gblJldDsNCi19DQotDQotQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogQ0pTX0dsb2JhbERhdGE6OkdldEdsb2JhbFZhcmlhYmxlKEZYX0xQQ1NUUiBwcm9wbmFtZSkNCi17DQotCUFTU0VSVChwcm9wbmFtZSAhPSBOVUxMKTsNCi0NCi0JaW50CW5GaW5kID0gRmluZEdsb2JhbFZhcmlhYmxlKHByb3BuYW1lKTsNCi0NCi0JaWYgKG5GaW5kID49IDApDQotCQlyZXR1cm4gbV9hcnJheUdsb2JhbERhdGEuR2V0QXQobkZpbmQpOw0KLQllbHNlDQotCQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCBDSlNfR2xvYmFsRGF0YTo6U2V0R2xvYmFsVmFyaWFibGVOdW1iZXIoRlhfTFBDU1RSIHByb3BuYW1lLCBkb3VibGUgZERhdGEpDQotew0KLQlBU1NFUlQocHJvcG5hbWUgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNQcm9wTmFtZSA9IHByb3BuYW1lOw0KLQ0KLQlzUHJvcE5hbWUuVHJpbUxlZnQoKTsNCi0Jc1Byb3BOYW1lLlRyaW1SaWdodCgpOw0KLQ0KLQlpZiAoc1Byb3BOYW1lLkdldExlbmd0aCgpID09IDApIHJldHVybjsNCi0NCi0JaWYgKENKU19HbG9iYWxEYXRhX0VsZW1lbnQqIHBEYXRhID0gR2V0R2xvYmFsVmFyaWFibGUoc1Byb3BOYW1lKSkNCi0Jew0KLQkJcERhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOw0KLQkJcERhdGEtPmRhdGEuZERhdGEgPSBkRGF0YTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNKU19HbG9iYWxEYXRhX0VsZW1lbnQqIHBOZXdEYXRhID0gbmV3IENKU19HbG9iYWxEYXRhX0VsZW1lbnQ7DQotCQlwTmV3RGF0YS0+ZGF0YS5zS2V5ID0gc1Byb3BOYW1lOw0KLQkJcE5ld0RhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOw0KLQkJcE5ld0RhdGEtPmRhdGEuZERhdGEgPSBkRGF0YTsNCi0NCi0JCW1fYXJyYXlHbG9iYWxEYXRhLkFkZChwTmV3RGF0YSk7DQotCX0NCi19DQotDQotdm9pZCBDSlNfR2xvYmFsRGF0YTo6U2V0R2xvYmFsVmFyaWFibGVCb29sZWFuKEZYX0xQQ1NUUiBwcm9wbmFtZSwgYm9vbCBiRGF0YSkNCi17DQotCUFTU0VSVChwcm9wbmFtZSAhPSBOVUxMKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gcHJvcG5hbWU7DQotDQotCXNQcm9wTmFtZS5UcmltTGVmdCgpOw0KLQlzUHJvcE5hbWUuVHJpbVJpZ2h0KCk7DQotDQotCWlmIChzUHJvcE5hbWUuR2V0TGVuZ3RoKCkgPT0gMCkgcmV0dXJuOw0KLQ0KLQlpZiAoQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcERhdGEgPSBHZXRHbG9iYWxWYXJpYWJsZShzUHJvcE5hbWUpKQ0KLQl7DQotCQlwRGF0YS0+ZGF0YS5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOw0KLQkJcERhdGEtPmRhdGEuYkRhdGEgPSBiRGF0YTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUNKU19HbG9iYWxEYXRhX0VsZW1lbnQqIHBOZXdEYXRhID0gbmV3IENKU19HbG9iYWxEYXRhX0VsZW1lbnQ7DQotCQlwTmV3RGF0YS0+ZGF0YS5zS2V5ID0gc1Byb3BOYW1lOw0KLQkJcE5ld0RhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTjsNCi0JCXBOZXdEYXRhLT5kYXRhLmJEYXRhID0gYkRhdGE7DQotDQotCQltX2FycmF5R2xvYmFsRGF0YS5BZGQocE5ld0RhdGEpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0pTX0dsb2JhbERhdGE6OlNldEdsb2JhbFZhcmlhYmxlU3RyaW5nKEZYX0xQQ1NUUiBwcm9wbmFtZSwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNEYXRhKQ0KLXsNCi0JQVNTRVJUKHByb3BuYW1lICE9IE5VTEwpOw0KLQlDRlhfQnl0ZVN0cmluZyBzUHJvcE5hbWUgPSBwcm9wbmFtZTsNCi0NCi0Jc1Byb3BOYW1lLlRyaW1MZWZ0KCk7DQotCXNQcm9wTmFtZS5UcmltUmlnaHQoKTsNCi0NCi0JaWYgKHNQcm9wTmFtZS5HZXRMZW5ndGgoKSA9PSAwKSByZXR1cm47DQotDQotCWlmIChDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwRGF0YSA9IEdldEdsb2JhbFZhcmlhYmxlKHNQcm9wTmFtZSkpDQotCXsNCi0JCXBEYXRhLT5kYXRhLm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORzsNCi0JCXBEYXRhLT5kYXRhLnNEYXRhID0gc0RhdGE7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwTmV3RGF0YSA9IG5ldyBDSlNfR2xvYmFsRGF0YV9FbGVtZW50Ow0KLQkJcE5ld0RhdGEtPmRhdGEuc0tleSA9IHNQcm9wTmFtZTsNCi0JCXBOZXdEYXRhLT5kYXRhLm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORzsNCi0JCXBOZXdEYXRhLT5kYXRhLnNEYXRhID0gc0RhdGE7DQotDQotCQltX2FycmF5R2xvYmFsRGF0YS5BZGQocE5ld0RhdGEpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ0pTX0dsb2JhbERhdGE6OlNldEdsb2JhbFZhcmlhYmxlT2JqZWN0KEZYX0xQQ1NUUiBwcm9wbmFtZSwgY29uc3QgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkmIGFycmF5KQ0KLXsNCi0JQVNTRVJUKHByb3BuYW1lICE9IE5VTEwpOw0KLQlDRlhfQnl0ZVN0cmluZyBzUHJvcE5hbWUgPSBwcm9wbmFtZTsNCi0NCi0Jc1Byb3BOYW1lLlRyaW1MZWZ0KCk7DQotCXNQcm9wTmFtZS5UcmltUmlnaHQoKTsNCi0NCi0JaWYgKHNQcm9wTmFtZS5HZXRMZW5ndGgoKSA9PSAwKSByZXR1cm47DQotDQotCWlmIChDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwRGF0YSA9IEdldEdsb2JhbFZhcmlhYmxlKHNQcm9wTmFtZSkpDQotCXsNCi0JCXBEYXRhLT5kYXRhLm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDsNCi0JCXBEYXRhLT5kYXRhLm9iakRhdGEuQ29weShhcnJheSk7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwTmV3RGF0YSA9IG5ldyBDSlNfR2xvYmFsRGF0YV9FbGVtZW50Ow0KLQkJcE5ld0RhdGEtPmRhdGEuc0tleSA9IHNQcm9wTmFtZTsNCi0JCXBOZXdEYXRhLT5kYXRhLm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDsNCi0JCXBOZXdEYXRhLT5kYXRhLm9iakRhdGEuQ29weShhcnJheSk7DQotCQkNCi0JCW1fYXJyYXlHbG9iYWxEYXRhLkFkZChwTmV3RGF0YSk7DQotCX0NCi19DQotDQotdm9pZCBDSlNfR2xvYmFsRGF0YTo6U2V0R2xvYmFsVmFyaWFibGVOdWxsKEZYX0xQQ1NUUiBwcm9wbmFtZSkNCi17DQotCUFTU0VSVChwcm9wbmFtZSAhPSBOVUxMKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gcHJvcG5hbWU7DQotCQ0KLQlzUHJvcE5hbWUuVHJpbUxlZnQoKTsNCi0Jc1Byb3BOYW1lLlRyaW1SaWdodCgpOw0KLQkNCi0JaWYgKHNQcm9wTmFtZS5HZXRMZW5ndGgoKSA9PSAwKSByZXR1cm47DQotCQ0KLQlpZiAoQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcERhdGEgPSBHZXRHbG9iYWxWYXJpYWJsZShzUHJvcE5hbWUpKQ0KLQl7DQotCQlwRGF0YS0+ZGF0YS5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcE5ld0RhdGEgPSBuZXcgQ0pTX0dsb2JhbERhdGFfRWxlbWVudDsNCi0JCXBOZXdEYXRhLT5kYXRhLnNLZXkgPSBzUHJvcE5hbWU7DQotCQlwTmV3RGF0YS0+ZGF0YS5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMOw0KLQkJDQotCQltX2FycmF5R2xvYmFsRGF0YS5BZGQocE5ld0RhdGEpOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX0dsb2JhbERhdGE6OlNldEdsb2JhbFZhcmlhYmxlUGVyc2lzdGVudChGWF9MUENTVFIgcHJvcG5hbWUsIEZYX0JPT0wgYlBlcnNpc3RlbnQpDQotew0KLQlBU1NFUlQocHJvcG5hbWUgIT0gTlVMTCk7DQotCUNGWF9CeXRlU3RyaW5nIHNQcm9wTmFtZSA9IHByb3BuYW1lOw0KLQ0KLQlzUHJvcE5hbWUuVHJpbUxlZnQoKTsNCi0Jc1Byb3BOYW1lLlRyaW1SaWdodCgpOw0KLQ0KLQlpZiAoc1Byb3BOYW1lLkdldExlbmd0aCgpID09IDApIHJldHVybiBGQUxTRTsNCi0NCi0JaWYgKENKU19HbG9iYWxEYXRhX0VsZW1lbnQqIHBEYXRhID0gR2V0R2xvYmFsVmFyaWFibGUoc1Byb3BOYW1lKSkNCi0Jew0KLQkJcERhdGEtPmJQZXJzaXN0ZW50ID0gYlBlcnNpc3RlbnQ7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX0dsb2JhbERhdGE6OkRlbGV0ZUdsb2JhbFZhcmlhYmxlKEZYX0xQQ1NUUiBwcm9wbmFtZSkNCi17DQotCUFTU0VSVChwcm9wbmFtZSAhPSBOVUxMKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gcHJvcG5hbWU7DQotDQotCXNQcm9wTmFtZS5UcmltTGVmdCgpOw0KLQlzUHJvcE5hbWUuVHJpbVJpZ2h0KCk7DQotDQotCWlmIChzUHJvcE5hbWUuR2V0TGVuZ3RoKCkgPT0gMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlpbnQJbkZpbmQgPSBGaW5kR2xvYmFsVmFyaWFibGUoc1Byb3BOYW1lKTsNCi0NCi0JaWYgKG5GaW5kID49IDApDQotCXsNCi0JCWRlbGV0ZSBtX2FycmF5R2xvYmFsRGF0YS5HZXRBdChuRmluZCk7DQotCQltX2FycmF5R2xvYmFsRGF0YS5SZW1vdmVBdChuRmluZCk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0lOVDMyIENKU19HbG9iYWxEYXRhOjpHZXRTaXplKCkgY29uc3QNCi17DQotCXJldHVybiBtX2FycmF5R2xvYmFsRGF0YS5HZXRTaXplKCk7DQotfQ0KLQ0KLUNKU19HbG9iYWxEYXRhX0VsZW1lbnQqIENKU19HbG9iYWxEYXRhOjpHZXRBdChpbnQgaW5kZXgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9hcnJheUdsb2JhbERhdGEuR2V0QXQoaW5kZXgpOw0KLX0NCi0NCi12b2lkIENKU19HbG9iYWxEYXRhOjpMb2FkR2xvYmFsUGVyc2lzdGVudFZhcmlhYmxlcygpDQotew0KLQlGWF9MUEJZVEUgcEJ1ZmZlciA9IE5VTEw7DQotCUZYX0lOVDMyIG5MZW5ndGggPSAwOw0KLQ0KLQlMb2FkRmlsZUJ1ZmZlcihtX3NGaWxlUGF0aCwgcEJ1ZmZlciwgbkxlbmd0aCk7DQotDQotCUNSWVBUX0FyY0ZvdXJDcnlwdEJsb2NrKHBCdWZmZXIsIG5MZW5ndGgsIEpTX1JDNEtFWSwgc2l6ZW9mKEpTX1JDNEtFWSkpOw0KLQ0KLQlpZiAocEJ1ZmZlcikNCi0Jew0KLQkJRlhfTFBCWVRFIHAgPSBwQnVmZmVyOw0KLQkJRlhfV09SRCB3VHlwZSA9ICooKEZYX1dPUkQqKXApOw0KLQkJcCArPSBzaXplb2YoRlhfV09SRCk7DQotDQotCQkvL0ZYX1dPUkQgd1RlbXAgPSAoRlhfV09SRCkoKCdYJyA8PCA4KSB8ICdGJyk7DQotDQotCQlpZiAod1R5cGUgPT0gKEZYX1dPUkQpKCgnWCcgPDwgOCkgfCAnRicpKQ0KLQkJew0KLQkJCUZYX1dPUkQgd1ZlcnNpb24gPSAqKChGWF9XT1JEKilwKTsNCi0JCQlwICs9IHNpemVvZihGWF9XT1JEKTsNCi0NCi0JCQlBU1NFUlQod1ZlcnNpb24gPD0gMik7DQotDQotCQkJRlhfRFdPUkQgZHdDb3VudCA9ICooKEZYX0RXT1JEKilwKTsNCi0JCQlwICs9IHNpemVvZihGWF9EV09SRCk7DQotDQotCQkJRlhfRFdPUkQgZHdTaXplID0gKigoRlhfRFdPUkQqKXApOw0KLQkJCXAgKz0gc2l6ZW9mKEZYX0RXT1JEKTsNCi0NCi0JCQlpZiAoZHdTaXplID09IG5MZW5ndGggLSBzaXplb2YoRlhfV09SRCkgKiAyIC0gc2l6ZW9mKEZYX0RXT1JEKSogMikNCi0JCQl7DQotCQkJCWZvciAoRlhfSU5UMzIgaT0wLHN6PWR3Q291bnQ7IGk8c3o7IGkrKykNCi0JCQkJew0KLQkJCQkJaWYgKHAgPiBwQnVmZmVyICsgbkxlbmd0aCkNCi0JCQkJCQlicmVhazsNCi0NCi0JCQkJCUZYX0RXT1JEIGR3TmFtZUxlbiA9ICooKEZYX0RXT1JEKilwKTsNCi0JCQkJCXAgKz0gc2l6ZW9mKEZYX0RXT1JEKTsNCi0NCi0JCQkJCWlmIChwICsgZHdOYW1lTGVuID4gcEJ1ZmZlciArIG5MZW5ndGgpDQotCQkJCQkJYnJlYWs7DQotDQotCQkJCQlDRlhfQnl0ZVN0cmluZyBzRW50cnkgPSBDRlhfQnl0ZVN0cmluZyhwLCBkd05hbWVMZW4pOw0KLQkJCQkJcCArPSBzaXplb2YoY2hhcikgKiBkd05hbWVMZW47DQotDQotCQkJCQlGWF9XT1JEIHdEYXRhVHlwZSA9ICooKEZYX1dPUkQqKXApOw0KLQkJCQkJcCArPSBzaXplb2YoRlhfV09SRCk7DQotDQotCQkJCQlzd2l0Y2ggKHdEYXRhVHlwZSkNCi0JCQkJCXsNCi0JCQkJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTUJFUjoNCi0JCQkJCQl7DQotCQkJCQkJCWRvdWJsZSBkRGF0YSA9IDA7DQotCQkJCQkJCXN3aXRjaCAod1ZlcnNpb24pDQotCQkJCQkJCXsNCi0JCQkJCQkJY2FzZSAxOg0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCUZYX0RXT1JEIGR3RGF0YSA9ICooKEZYX0RXT1JEKilwKTsNCi0JCQkJCQkJCQlwICs9IHNpemVvZihGWF9EV09SRCk7DQotCQkJCQkJCQkJZERhdGEgPSBkd0RhdGE7DQotCQkJCQkJCQl9DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJY2FzZSAyOg0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCWREYXRhID0gKigoZG91YmxlKilwKTsNCi0JCQkJCQkJCQlwICs9IHNpemVvZihkb3VibGUpOw0KLQkJCQkJCQkJfQ0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCX0NCi0JCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVOdW1iZXIoc0VudHJ5LCBkRGF0YSk7DQotCQkJCQkJCVNldEdsb2JhbFZhcmlhYmxlUGVyc2lzdGVudChzRW50cnksIFRSVUUpOw0KLQkJCQkJCX0NCi0JCQkJCQlicmVhazsNCi0JCQkJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46DQotCQkJCQkJew0KLQkJCQkJCQlGWF9XT1JEIHdEYXRhID0gKigoRlhfV09SRCopcCk7DQotCQkJCQkJCXAgKz0gc2l6ZW9mKEZYX1dPUkQpOw0KLQkJCQkJCQlTZXRHbG9iYWxWYXJpYWJsZUJvb2xlYW4oc0VudHJ5LCAoYm9vbCkod0RhdGEgPT0gMSkpOw0KLQkJCQkJCQlTZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQoc0VudHJ5LCBUUlVFKTsNCi0JCQkJCQl9DQotCQkJCQkJYnJlYWs7DQotCQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc6DQotCQkJCQkJew0KLQkJCQkJCQlGWF9EV09SRCBkd0xlbmd0aCA9ICooKEZYX0RXT1JEKilwKTsNCi0JCQkJCQkJcCArPSBzaXplb2YoRlhfRFdPUkQpOw0KLQ0KLQkJCQkJCQlpZiAocCArIGR3TGVuZ3RoID4gcEJ1ZmZlciArIG5MZW5ndGgpDQotCQkJCQkJCQlicmVhazsNCi0NCi0JCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVTdHJpbmcoc0VudHJ5LCBDRlhfQnl0ZVN0cmluZyhwLCBkd0xlbmd0aCkpOw0KLQkJCQkJCQlTZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQoc0VudHJ5LCBUUlVFKTsNCi0JCQkJCQkJcCArPSBzaXplb2YoY2hhcikgKiBkd0xlbmd0aDsNCi0JCQkJCQl9DQotCQkJCQkJYnJlYWs7DQotCQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMOg0KLQkJCQkJCXsNCi0JCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVOdWxsKHNFbnRyeSk7DQotCQkJCQkJCVNldEdsb2JhbFZhcmlhYmxlUGVyc2lzdGVudChzRW50cnksIFRSVUUpOw0KLQkJCQkJCX0NCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JCUZYX0ZyZWUocEJ1ZmZlcik7DQotCX0NCi19DQotDQotLyoNCi1zdHJ1Y3QganNfZ2xvYmFsX2RhdGFmaWxlX2hlYWRlcg0KLXsNCi0JRlhfV09SRCB0eXBlOyAvL0ZYICgnWCcgPDwgOCkgfCAnRicNCi0JRlhfV09SRCB2ZXJzaW9uOyAvLzEuMA0KLQlGWF9EV09SRCBkYXRhY291bnQ7DQotfTsNCi1zdHJ1Y3QganNfZ2xvYmFsX2RhdGFmaWxlX2RhdGENCi17DQotCUZYX1dPUkQgdHlwZTsNCi0JRlhfRFdPUkQgbkRhdGE7DQotCUZYX1dPUkQgYkRhdGE7DQotCUZYX0RXT1JEIG5TdHJMZW47DQotCWNoYXIqIHBTdHI7DQotfTsNCi0qLw0KLQ0KLXZvaWQgQ0pTX0dsb2JhbERhdGE6OlNhdmVHbG9iYWxQZXJzaXNpdGVudFZhcmlhYmxlcygpDQotew0KLQlGWF9EV09SRCBuQ291bnQgPSAwOw0KLQlDRlhfQmluYXJ5QnVmIHNEYXRhOw0KLQ0KLQlmb3IgKGludCBpPTAsc3o9bV9hcnJheUdsb2JhbERhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCUNKU19HbG9iYWxEYXRhX0VsZW1lbnQqIHBFbGVtZW50ID0gbV9hcnJheUdsb2JhbERhdGEuR2V0QXQoaSk7DQotCQlBU1NFUlQocEVsZW1lbnQgIT0gTlVMTCk7DQotDQotCQlpZiAocEVsZW1lbnQtPmJQZXJzaXN0ZW50KQ0KLQkJew0KLQkJCUNGWF9CaW5hcnlCdWYgc0VsZW1lbnQ7DQotCQkJTWFrZUJ5dGVTdHJpbmcocEVsZW1lbnQtPmRhdGEuc0tleSwgJnBFbGVtZW50LT5kYXRhLCBzRWxlbWVudCk7DQotDQotCQkJaWYgKHNEYXRhLkdldFNpemUoKSArIHNFbGVtZW50LkdldFNpemUoKSA+IEpTX01BWEdMT0JBTERBVEEpDQotCQkJCWJyZWFrOw0KLQ0KLQkJCXNEYXRhLkFwcGVuZEJsb2NrKHNFbGVtZW50LkdldEJ1ZmZlcigpLCBzRWxlbWVudC5HZXRTaXplKCkpOw0KLQkJCW5Db3VudCsrOw0KLQkJfQ0KLQl9DQotDQotCUNGWF9CaW5hcnlCdWYgc0ZpbGU7DQotDQotCUZYX1dPUkQgd1R5cGUgPSAoRlhfV09SRCkoKCdYJyA8PCA4KSB8ICdGJyk7DQotCXNGaWxlLkFwcGVuZEJsb2NrKCZ3VHlwZSwgc2l6ZW9mKEZYX1dPUkQpKTsNCi0JRlhfV09SRCB3VmVyc2lvbiA9IDI7DQotCXNGaWxlLkFwcGVuZEJsb2NrKCZ3VmVyc2lvbiwgc2l6ZW9mKEZYX1dPUkQpKTsNCi0Jc0ZpbGUuQXBwZW5kQmxvY2soJm5Db3VudCwgc2l6ZW9mKEZYX0RXT1JEKSk7DQotCUZYX0RXT1JEIGR3U2l6ZSA9IHNEYXRhLkdldFNpemUoKTsNCi0Jc0ZpbGUuQXBwZW5kQmxvY2soJmR3U2l6ZSwgc2l6ZW9mKEZYX0RXT1JEKSk7DQotDQotCXNGaWxlLkFwcGVuZEJsb2NrKHNEYXRhLkdldEJ1ZmZlcigpLCBzRGF0YS5HZXRTaXplKCkpOw0KLQ0KLQlDUllQVF9BcmNGb3VyQ3J5cHRCbG9jayhzRmlsZS5HZXRCdWZmZXIoKSwgc0ZpbGUuR2V0U2l6ZSgpLCBKU19SQzRLRVksIHNpemVvZihKU19SQzRLRVkpKTsNCi0JV3JpdGVGaWxlQnVmZmVyKG1fc0ZpbGVQYXRoLCAoRlhfTFBDU1RSKXNGaWxlLkdldEJ1ZmZlcigpLCBzRmlsZS5HZXRTaXplKCkpOw0KLX0NCi0NCi12b2lkIENKU19HbG9iYWxEYXRhOjpMb2FkRmlsZUJ1ZmZlcihGWF9MUENXU1RSIHNGaWxlUGF0aCwgRlhfTFBCWVRFJiBwQnVmZmVyLCBGWF9JTlQzMiYgbkxlbmd0aCkNCi17DQotLy9VblN1cHBvcnQuDQotfQ0KLQ0KLXZvaWQgQ0pTX0dsb2JhbERhdGE6OldyaXRlRmlsZUJ1ZmZlcihGWF9MUENXU1RSIHNGaWxlUGF0aCwgRlhfTFBDU1RSIHBCdWZmZXIsIEZYX0lOVDMyIG5MZW5ndGgpDQotew0KLS8vVW5TdXBwb3J0Lg0KLX0NCi0NCi12b2lkIENKU19HbG9iYWxEYXRhOjpNYWtlQnl0ZVN0cmluZyhjb25zdCBDRlhfQnl0ZVN0cmluZyYgbmFtZSwgQ0pTX0tleVZhbHVlKiBwRGF0YSwgQ0ZYX0JpbmFyeUJ1ZiYgc0RhdGEpDQotew0KLQlBU1NFUlQocERhdGEgIT0gTlVMTCk7DQotDQotCUZYX1dPUkQgd1R5cGUgPSAoRlhfV09SRClwRGF0YS0+blR5cGU7DQotDQotCXN3aXRjaCAod1R5cGUpDQotCXsNCi0JY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOg0KLQkJew0KLQkJCUZYX0RXT1JEIGR3TmFtZUxlbiA9IChGWF9EV09SRCluYW1lLkdldExlbmd0aCgpOw0KLQkJCXNEYXRhLkFwcGVuZEJsb2NrKCZkd05hbWVMZW4sIHNpemVvZihGWF9EV09SRCkpOw0KLQkJCXNEYXRhLkFwcGVuZFN0cmluZyhuYW1lKTsNCi0NCi0JCQlzRGF0YS5BcHBlbmRCbG9jaygmd1R5cGUsIHNpemVvZihGWF9XT1JEKSk7DQotCQkJZG91YmxlIGREYXRhID0gcERhdGEtPmREYXRhOw0KLQkJCXNEYXRhLkFwcGVuZEJsb2NrKCZkRGF0YSwgc2l6ZW9mKGRvdWJsZSkpOw0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46DQotCQl7DQotCQkJRlhfRFdPUkQgZHdOYW1lTGVuID0gKEZYX0RXT1JEKW5hbWUuR2V0TGVuZ3RoKCk7DQotCQkJc0RhdGEuQXBwZW5kQmxvY2soJmR3TmFtZUxlbiwgc2l6ZW9mKEZYX0RXT1JEKSk7DQotCQkJc0RhdGEuQXBwZW5kU3RyaW5nKG5hbWUpOw0KLQ0KLQkJCXNEYXRhLkFwcGVuZEJsb2NrKCZ3VHlwZSwgc2l6ZW9mKEZYX1dPUkQpKTsNCi0JCQlGWF9XT1JEIHdEYXRhID0gKEZYX1dPUkQpcERhdGEtPmJEYXRhOw0KLQkJCXNEYXRhLkFwcGVuZEJsb2NrKCZ3RGF0YSwgc2l6ZW9mKEZYX1dPUkQpKTsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc6DQotCQl7DQotCQkJRlhfRFdPUkQgZHdOYW1lTGVuID0gKEZYX0RXT1JEKW5hbWUuR2V0TGVuZ3RoKCk7DQotCQkJc0RhdGEuQXBwZW5kQmxvY2soJmR3TmFtZUxlbiwgc2l6ZW9mKEZYX0RXT1JEKSk7DQotCQkJc0RhdGEuQXBwZW5kU3RyaW5nKG5hbWUpOw0KLQ0KLQkJCXNEYXRhLkFwcGVuZEJsb2NrKCZ3VHlwZSwgc2l6ZW9mKEZYX1dPUkQpKTsNCi0NCi0JCQlGWF9EV09SRCBkd0RhdGFMZW4gPSAoRlhfRFdPUkQpcERhdGEtPnNEYXRhLkdldExlbmd0aCgpOw0KLQkJCXNEYXRhLkFwcGVuZEJsb2NrKCZkd0RhdGFMZW4sIHNpemVvZihGWF9EV09SRCkpOw0KLQkJCXNEYXRhLkFwcGVuZFN0cmluZyhwRGF0YS0+c0RhdGEpOw0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTEw6DQotCQl7DQotCQkJRlhfRFdPUkQgZHdOYW1lTGVuID0gKEZYX0RXT1JEKW5hbWUuR2V0TGVuZ3RoKCk7DQotCQkJc0RhdGEuQXBwZW5kQmxvY2soJmR3TmFtZUxlbiwgc2l6ZW9mKEZYX0RXT1JEKSk7DQotCQkJc0RhdGEuQXBwZW5kU3RyaW5nKG5hbWUpOw0KLQ0KLQkJCXNEYXRhLkFwcGVuZEJsb2NrKCZ3VHlwZSwgc2l6ZW9mKEZYX0RXT1JEKSk7DQotCQl9DQotCQlicmVhazsNCi0JZGVmYXVsdDoNCi0JCWJyZWFrOw0KLQl9DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19HbG9iYWxEYXRhLmgiCisKKyNkZWZpbmUgSlNfTUFYR0xPQkFMREFUQQkJCSgxMDI0ICogNCAtIDgpCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfR2xvYmFsVmFyaWFibGVBcnJheSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk6OkNKU19HbG9iYWxWYXJpYWJsZUFycmF5KCkKK3sKK30KKworQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk6On5DSlNfR2xvYmFsVmFyaWFibGVBcnJheSgpCit7CisJRW1wdHkoKTsKK30KKwordm9pZCBDSlNfR2xvYmFsVmFyaWFibGVBcnJheTo6Q29weShjb25zdCBDSlNfR2xvYmFsVmFyaWFibGVBcnJheSYgYXJyYXkpCit7CisJRW1wdHkoKTsKKwlmb3IgKGludCBpPTAsc3o9YXJyYXkuQ291bnQoKTsgaTxzejsgaSsrKQorCXsKKwkJQ0pTX0tleVZhbHVlKiBwT2xkT2JqRGF0YSA9IGFycmF5LkdldEF0KGkpOworCQlBU1NFUlQocE9sZE9iakRhdGEgIT0gTlVMTCk7CisKKwkJc3dpdGNoIChwT2xkT2JqRGF0YS0+blR5cGUpCisJCXsKKwkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOgorCQkJeworCQkJCUNKU19LZXlWYWx1ZSogcE5ld09iakRhdGEgPSBuZXcgQ0pTX0tleVZhbHVlOworCQkJCXBOZXdPYmpEYXRhLT5zS2V5ID0gcE9sZE9iakRhdGEtPnNLZXk7CisJCQkJcE5ld09iakRhdGEtPm5UeXBlID0gcE9sZE9iakRhdGEtPm5UeXBlOworCQkJCXBOZXdPYmpEYXRhLT5kRGF0YSA9IHBPbGRPYmpEYXRhLT5kRGF0YTsKKwkJCQlBZGQocE5ld09iakRhdGEpOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46CisJCQl7CisJCQkJQ0pTX0tleVZhbHVlKiBwTmV3T2JqRGF0YSA9IG5ldyBDSlNfS2V5VmFsdWU7CisJCQkJcE5ld09iakRhdGEtPnNLZXkgPSBwT2xkT2JqRGF0YS0+c0tleTsKKwkJCQlwTmV3T2JqRGF0YS0+blR5cGUgPSBwT2xkT2JqRGF0YS0+blR5cGU7CisJCQkJcE5ld09iakRhdGEtPmJEYXRhID0gcE9sZE9iakRhdGEtPmJEYXRhOworCQkJCUFkZChwTmV3T2JqRGF0YSk7CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOgorCQkJeworCQkJCUNKU19LZXlWYWx1ZSogcE5ld09iakRhdGEgPSBuZXcgQ0pTX0tleVZhbHVlOworCQkJCXBOZXdPYmpEYXRhLT5zS2V5ID0gcE9sZE9iakRhdGEtPnNLZXk7CisJCQkJcE5ld09iakRhdGEtPm5UeXBlID0gcE9sZE9iakRhdGEtPm5UeXBlOworCQkJCXBOZXdPYmpEYXRhLT5zRGF0YSA9IHBPbGRPYmpEYXRhLT5zRGF0YTsKKwkJCQlBZGQocE5ld09iakRhdGEpOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDoKKwkJCXsKKwkJCQlDSlNfS2V5VmFsdWUqIHBOZXdPYmpEYXRhID0gbmV3IENKU19LZXlWYWx1ZTsKKwkJCQlwTmV3T2JqRGF0YS0+c0tleSA9IHBPbGRPYmpEYXRhLT5zS2V5OworCQkJCXBOZXdPYmpEYXRhLT5uVHlwZSA9IHBPbGRPYmpEYXRhLT5uVHlwZTsKKwkJCQlwTmV3T2JqRGF0YS0+b2JqRGF0YS5Db3B5KHBPbGRPYmpEYXRhLT5vYmpEYXRhKTsKKwkJCQlBZGQocE5ld09iakRhdGEpOworCQkJfQorCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMOgorCQkJeworCQkJCUNKU19LZXlWYWx1ZSogcE5ld09iakRhdGEgPSBuZXcgQ0pTX0tleVZhbHVlOworCQkJCXBOZXdPYmpEYXRhLT5zS2V5ID0gcE9sZE9iakRhdGEtPnNLZXk7CisJCQkJcE5ld09iakRhdGEtPm5UeXBlID0gcE9sZE9iakRhdGEtPm5UeXBlOworCQkJCUFkZChwTmV3T2JqRGF0YSk7CisJCQl9CisJCX0KKwl9Cit9CisKK3ZvaWQgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk6OkFkZChDSlNfS2V5VmFsdWUqIHApCit7CisJYXJyYXkuQWRkKHApOworfQorCitpbnQgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXk6OkNvdW50KCkgY29uc3QKK3sKKwlyZXR1cm4gYXJyYXkuR2V0U2l6ZSgpOworfQorCitDSlNfS2V5VmFsdWUqIENKU19HbG9iYWxWYXJpYWJsZUFycmF5OjpHZXRBdChpbnQgaW5kZXgpIGNvbnN0Cit7CisJcmV0dXJuIGFycmF5LkdldEF0KGluZGV4KTsKK30KKwordm9pZCBDSlNfR2xvYmFsVmFyaWFibGVBcnJheTo6RW1wdHkoKQoreworCWZvciAoaW50IGk9MCxzej1hcnJheS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJZGVsZXRlIGFycmF5LkdldEF0KGkpOworCWFycmF5LlJlbW92ZUFsbCgpOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfR2xvYmFsRGF0YSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCisjZGVmaW5lIFJFQURFUl9KU19HTE9CQUxEQVRBX0ZJTEVOQU1FCQkJCUwiUmVhZGVyX0pzR2xvYmFsLkRhdGEiCisjZGVmaW5lIFBIQU5UT01fSlNfR0xPQkFMREFUQV9GSUxFTkFNRQkJCQlMIlBoYW50b21fSnNHbG9iYWwuRGF0YSIKKyNkZWZpbmUgU0RLX0pTX0dMT0JBTERBVEFfRklMRU5BTUUJCQkJCUwiU0RLX0pzR2xvYmFsLkRhdGEiCisKK3N0YXRpYyBjb25zdCBGWF9CWVRFIEpTX1JDNEtFWVtdID0gezB4MTksMHhhOCwweGU4LDB4MDEsMHhmNiwweGE4LDB4YjYsMHg0ZCwweDgyLDB4MDQsCisJCQkJCQkJMHg0NSwweDZkLDB4YjQsMHhjZiwweGQ3LDB4NzcsMHg2NywweGY5LDB4NzUsMHg5ZiwKKwkJCQkJCQkweGYwLDB4ZTAsMHgxZSwweDUxLDB4ZWUsMHg0NiwweGZkLDB4MGIsMHhjOSwweDkzLAorCQkJCQkJCTB4MjUsMHg1NSwweDRhLDB4ZWUsMHhlMCwweDE2LDB4ZDAsMHhkZiwweDhjLDB4ZmEsCisJCQkJCQkJMHgyYSwweGE5LDB4NDksMHhmZCwweDk3LDB4MWMsMHgwZSwweDIyLDB4MTMsMHgyOCwKKwkJCQkJCQkweDdjLDB4YWYsMHhjNCwweGZjLDB4OWMsMHgxMiwweDY1LDB4OGMsMHg0ZSwweDViLAorCQkJCQkJCTB4MDQsMHg3NSwweDg5LDB4YzksMHhiMSwweGVkLDB4NTAsMHhjYSwweDk2LDB4NmYsCisJCQkJCQkJMHgxYSwweDdhLDB4ZmUsMHg1OCwweDVkLDB4ZWMsMHgxOSwweDRhLDB4ZjYsMHgzNSwKKwkJCQkJCQkweDZhLDB4OTcsMHgxNCwweDAwLDB4MGUsMHhkMCwweDZiLDB4YmIsMHhkNSwweDc1LAorCQkJCQkJCTB4NTUsMHg4YiwweDZlLDB4NmIsMHgxOSwweGEwLDB4ZjgsMHg3NywweGQ1LDB4YTMKKwkJCQkJCQl9OworCitDSlNfR2xvYmFsRGF0YTo6Q0pTX0dsb2JhbERhdGEoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCkgOiBtX3BBcHAocEFwcCkKK3sKKy8vIAlJQmFzZUFubm90KiBwQmFzZUFubm90ID0gSUJhc2VBbm5vdDo6R2V0QmFzZUFubm90KG1fcEFwcCk7CisvLyAJQVNTRVJUKHBCYXNlQW5ub3QgIT0gTlVMTCk7CisvLyAKKy8vIAltX3NGaWxlUGF0aCA9IHBCYXNlQW5ub3QtPkdldFVzZXJQYXRoKCk7CisJbV9zRmlsZVBhdGggKz0gU0RLX0pTX0dMT0JBTERBVEFfRklMRU5BTUU7CisKKwlMb2FkR2xvYmFsUGVyc2lzdGVudFZhcmlhYmxlcygpOworfQorCitDSlNfR2xvYmFsRGF0YTo6fkNKU19HbG9iYWxEYXRhKCkKK3sKKwlTYXZlR2xvYmFsUGVyc2lzaXRlbnRWYXJpYWJsZXMoKTsKKworCWZvciAoaW50IGk9MCxzej1tX2FycmF5R2xvYmFsRGF0YS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJZGVsZXRlIG1fYXJyYXlHbG9iYWxEYXRhLkdldEF0KGkpOworCisJbV9hcnJheUdsb2JhbERhdGEuUmVtb3ZlQWxsKCk7Cit9CisKK2ludAlDSlNfR2xvYmFsRGF0YTo6RmluZEdsb2JhbFZhcmlhYmxlKEZYX0xQQ1NUUiBwcm9wbmFtZSkKK3sKKwlBU1NFUlQocHJvcG5hbWUgIT0gTlVMTCk7CisKKwlpbnQgblJldCA9IC0xOworCisJZm9yIChpbnQgaT0wLHN6PW1fYXJyYXlHbG9iYWxEYXRhLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcFRlbXAgPSBtX2FycmF5R2xvYmFsRGF0YS5HZXRBdChpKTsKKwkJaWYgKHBUZW1wLT5kYXRhLnNLZXlbMF0gPT0gKnByb3BuYW1lICYmIHBUZW1wLT5kYXRhLnNLZXkgPT0gcHJvcG5hbWUpCisJCXsKKwkJCW5SZXQgPSBpOworCQkJYnJlYWs7CisJCX0KKwl9CisKKwlyZXR1cm4gblJldDsKK30KKworQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogQ0pTX0dsb2JhbERhdGE6OkdldEdsb2JhbFZhcmlhYmxlKEZYX0xQQ1NUUiBwcm9wbmFtZSkKK3sKKwlBU1NFUlQocHJvcG5hbWUgIT0gTlVMTCk7CisKKwlpbnQJbkZpbmQgPSBGaW5kR2xvYmFsVmFyaWFibGUocHJvcG5hbWUpOworCisJaWYgKG5GaW5kID49IDApCisJCXJldHVybiBtX2FycmF5R2xvYmFsRGF0YS5HZXRBdChuRmluZCk7CisJZWxzZQorCQlyZXR1cm4gTlVMTDsKK30KKwordm9pZCBDSlNfR2xvYmFsRGF0YTo6U2V0R2xvYmFsVmFyaWFibGVOdW1iZXIoRlhfTFBDU1RSIHByb3BuYW1lLCBkb3VibGUgZERhdGEpCit7CisJQVNTRVJUKHByb3BuYW1lICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNQcm9wTmFtZSA9IHByb3BuYW1lOworCisJc1Byb3BOYW1lLlRyaW1MZWZ0KCk7CisJc1Byb3BOYW1lLlRyaW1SaWdodCgpOworCisJaWYgKHNQcm9wTmFtZS5HZXRMZW5ndGgoKSA9PSAwKSByZXR1cm47CisKKwlpZiAoQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcERhdGEgPSBHZXRHbG9iYWxWYXJpYWJsZShzUHJvcE5hbWUpKQorCXsKKwkJcERhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOworCQlwRGF0YS0+ZGF0YS5kRGF0YSA9IGREYXRhOworCX0KKwllbHNlCisJeworCQlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwTmV3RGF0YSA9IG5ldyBDSlNfR2xvYmFsRGF0YV9FbGVtZW50OworCQlwTmV3RGF0YS0+ZGF0YS5zS2V5ID0gc1Byb3BOYW1lOworCQlwTmV3RGF0YS0+ZGF0YS5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI7CisJCXBOZXdEYXRhLT5kYXRhLmREYXRhID0gZERhdGE7CisKKwkJbV9hcnJheUdsb2JhbERhdGEuQWRkKHBOZXdEYXRhKTsKKwl9Cit9CisKK3ZvaWQgQ0pTX0dsb2JhbERhdGE6OlNldEdsb2JhbFZhcmlhYmxlQm9vbGVhbihGWF9MUENTVFIgcHJvcG5hbWUsIGJvb2wgYkRhdGEpCit7CisJQVNTRVJUKHByb3BuYW1lICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNQcm9wTmFtZSA9IHByb3BuYW1lOworCisJc1Byb3BOYW1lLlRyaW1MZWZ0KCk7CisJc1Byb3BOYW1lLlRyaW1SaWdodCgpOworCisJaWYgKHNQcm9wTmFtZS5HZXRMZW5ndGgoKSA9PSAwKSByZXR1cm47CisKKwlpZiAoQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcERhdGEgPSBHZXRHbG9iYWxWYXJpYWJsZShzUHJvcE5hbWUpKQorCXsKKwkJcERhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTjsKKwkJcERhdGEtPmRhdGEuYkRhdGEgPSBiRGF0YTsKKwl9CisJZWxzZQorCXsKKwkJQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcE5ld0RhdGEgPSBuZXcgQ0pTX0dsb2JhbERhdGFfRWxlbWVudDsKKwkJcE5ld0RhdGEtPmRhdGEuc0tleSA9IHNQcm9wTmFtZTsKKwkJcE5ld0RhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTjsKKwkJcE5ld0RhdGEtPmRhdGEuYkRhdGEgPSBiRGF0YTsKKworCQltX2FycmF5R2xvYmFsRGF0YS5BZGQocE5ld0RhdGEpOworCX0KK30KKwordm9pZCBDSlNfR2xvYmFsRGF0YTo6U2V0R2xvYmFsVmFyaWFibGVTdHJpbmcoRlhfTFBDU1RSIHByb3BuYW1lLCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0RhdGEpCit7CisJQVNTRVJUKHByb3BuYW1lICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNQcm9wTmFtZSA9IHByb3BuYW1lOworCisJc1Byb3BOYW1lLlRyaW1MZWZ0KCk7CisJc1Byb3BOYW1lLlRyaW1SaWdodCgpOworCisJaWYgKHNQcm9wTmFtZS5HZXRMZW5ndGgoKSA9PSAwKSByZXR1cm47CisKKwlpZiAoQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcERhdGEgPSBHZXRHbG9iYWxWYXJpYWJsZShzUHJvcE5hbWUpKQorCXsKKwkJcERhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOworCQlwRGF0YS0+ZGF0YS5zRGF0YSA9IHNEYXRhOworCX0KKwllbHNlCisJeworCQlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwTmV3RGF0YSA9IG5ldyBDSlNfR2xvYmFsRGF0YV9FbGVtZW50OworCQlwTmV3RGF0YS0+ZGF0YS5zS2V5ID0gc1Byb3BOYW1lOworCQlwTmV3RGF0YS0+ZGF0YS5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc7CisJCXBOZXdEYXRhLT5kYXRhLnNEYXRhID0gc0RhdGE7CisKKwkJbV9hcnJheUdsb2JhbERhdGEuQWRkKHBOZXdEYXRhKTsKKwl9Cit9CisKK3ZvaWQgQ0pTX0dsb2JhbERhdGE6OlNldEdsb2JhbFZhcmlhYmxlT2JqZWN0KEZYX0xQQ1NUUiBwcm9wbmFtZSwgY29uc3QgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkmIGFycmF5KQoreworCUFTU0VSVChwcm9wbmFtZSAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzUHJvcE5hbWUgPSBwcm9wbmFtZTsKKworCXNQcm9wTmFtZS5UcmltTGVmdCgpOworCXNQcm9wTmFtZS5UcmltUmlnaHQoKTsKKworCWlmIChzUHJvcE5hbWUuR2V0TGVuZ3RoKCkgPT0gMCkgcmV0dXJuOworCisJaWYgKENKU19HbG9iYWxEYXRhX0VsZW1lbnQqIHBEYXRhID0gR2V0R2xvYmFsVmFyaWFibGUoc1Byb3BOYW1lKSkKKwl7CisJCXBEYXRhLT5kYXRhLm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDsKKwkJcERhdGEtPmRhdGEub2JqRGF0YS5Db3B5KGFycmF5KTsKKwl9CisJZWxzZQorCXsKKwkJQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcE5ld0RhdGEgPSBuZXcgQ0pTX0dsb2JhbERhdGFfRWxlbWVudDsKKwkJcE5ld0RhdGEtPmRhdGEuc0tleSA9IHNQcm9wTmFtZTsKKwkJcE5ld0RhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOworCQlwTmV3RGF0YS0+ZGF0YS5vYmpEYXRhLkNvcHkoYXJyYXkpOworCQkKKwkJbV9hcnJheUdsb2JhbERhdGEuQWRkKHBOZXdEYXRhKTsKKwl9Cit9CisKK3ZvaWQgQ0pTX0dsb2JhbERhdGE6OlNldEdsb2JhbFZhcmlhYmxlTnVsbChGWF9MUENTVFIgcHJvcG5hbWUpCit7CisJQVNTRVJUKHByb3BuYW1lICE9IE5VTEwpOworCUNGWF9CeXRlU3RyaW5nIHNQcm9wTmFtZSA9IHByb3BuYW1lOworCQorCXNQcm9wTmFtZS5UcmltTGVmdCgpOworCXNQcm9wTmFtZS5UcmltUmlnaHQoKTsKKwkKKwlpZiAoc1Byb3BOYW1lLkdldExlbmd0aCgpID09IDApIHJldHVybjsKKwkKKwlpZiAoQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcERhdGEgPSBHZXRHbG9iYWxWYXJpYWJsZShzUHJvcE5hbWUpKQorCXsKKwkJcERhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTDsKKwl9CisJZWxzZQorCXsKKwkJQ0pTX0dsb2JhbERhdGFfRWxlbWVudCogcE5ld0RhdGEgPSBuZXcgQ0pTX0dsb2JhbERhdGFfRWxlbWVudDsKKwkJcE5ld0RhdGEtPmRhdGEuc0tleSA9IHNQcm9wTmFtZTsKKwkJcE5ld0RhdGEtPmRhdGEublR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTDsKKwkJCisJCW1fYXJyYXlHbG9iYWxEYXRhLkFkZChwTmV3RGF0YSk7CisJfQorfQorCitGWF9CT09MIENKU19HbG9iYWxEYXRhOjpTZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQoRlhfTFBDU1RSIHByb3BuYW1lLCBGWF9CT09MIGJQZXJzaXN0ZW50KQoreworCUFTU0VSVChwcm9wbmFtZSAhPSBOVUxMKTsKKwlDRlhfQnl0ZVN0cmluZyBzUHJvcE5hbWUgPSBwcm9wbmFtZTsKKworCXNQcm9wTmFtZS5UcmltTGVmdCgpOworCXNQcm9wTmFtZS5UcmltUmlnaHQoKTsKKworCWlmIChzUHJvcE5hbWUuR2V0TGVuZ3RoKCkgPT0gMCkgcmV0dXJuIEZBTFNFOworCisJaWYgKENKU19HbG9iYWxEYXRhX0VsZW1lbnQqIHBEYXRhID0gR2V0R2xvYmFsVmFyaWFibGUoc1Byb3BOYW1lKSkKKwl7CisJCXBEYXRhLT5iUGVyc2lzdGVudCA9IGJQZXJzaXN0ZW50OworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ0pTX0dsb2JhbERhdGE6OkRlbGV0ZUdsb2JhbFZhcmlhYmxlKEZYX0xQQ1NUUiBwcm9wbmFtZSkKK3sKKwlBU1NFUlQocHJvcG5hbWUgIT0gTlVMTCk7CisJQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gcHJvcG5hbWU7CisKKwlzUHJvcE5hbWUuVHJpbUxlZnQoKTsKKwlzUHJvcE5hbWUuVHJpbVJpZ2h0KCk7CisKKwlpZiAoc1Byb3BOYW1lLkdldExlbmd0aCgpID09IDApIHJldHVybiBGQUxTRTsKKworCWludAluRmluZCA9IEZpbmRHbG9iYWxWYXJpYWJsZShzUHJvcE5hbWUpOworCisJaWYgKG5GaW5kID49IDApCisJeworCQlkZWxldGUgbV9hcnJheUdsb2JhbERhdGEuR2V0QXQobkZpbmQpOworCQltX2FycmF5R2xvYmFsRGF0YS5SZW1vdmVBdChuRmluZCk7CisJCXJldHVybiBUUlVFOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfSU5UMzIgQ0pTX0dsb2JhbERhdGE6OkdldFNpemUoKSBjb25zdAoreworCXJldHVybiBtX2FycmF5R2xvYmFsRGF0YS5HZXRTaXplKCk7Cit9CisKK0NKU19HbG9iYWxEYXRhX0VsZW1lbnQqIENKU19HbG9iYWxEYXRhOjpHZXRBdChpbnQgaW5kZXgpIGNvbnN0Cit7CisJcmV0dXJuIG1fYXJyYXlHbG9iYWxEYXRhLkdldEF0KGluZGV4KTsKK30KKwordm9pZCBDSlNfR2xvYmFsRGF0YTo6TG9hZEdsb2JhbFBlcnNpc3RlbnRWYXJpYWJsZXMoKQoreworCUZYX0xQQllURSBwQnVmZmVyID0gTlVMTDsKKwlGWF9JTlQzMiBuTGVuZ3RoID0gMDsKKworCUxvYWRGaWxlQnVmZmVyKG1fc0ZpbGVQYXRoLCBwQnVmZmVyLCBuTGVuZ3RoKTsKKworCUNSWVBUX0FyY0ZvdXJDcnlwdEJsb2NrKHBCdWZmZXIsIG5MZW5ndGgsIEpTX1JDNEtFWSwgc2l6ZW9mKEpTX1JDNEtFWSkpOworCisJaWYgKHBCdWZmZXIpCisJeworCQlGWF9MUEJZVEUgcCA9IHBCdWZmZXI7CisJCUZYX1dPUkQgd1R5cGUgPSAqKChGWF9XT1JEKilwKTsKKwkJcCArPSBzaXplb2YoRlhfV09SRCk7CisKKwkJLy9GWF9XT1JEIHdUZW1wID0gKEZYX1dPUkQpKCgnWCcgPDwgOCkgfCAnRicpOworCisJCWlmICh3VHlwZSA9PSAoRlhfV09SRCkoKCdYJyA8PCA4KSB8ICdGJykpCisJCXsKKwkJCUZYX1dPUkQgd1ZlcnNpb24gPSAqKChGWF9XT1JEKilwKTsKKwkJCXAgKz0gc2l6ZW9mKEZYX1dPUkQpOworCisJCQlBU1NFUlQod1ZlcnNpb24gPD0gMik7CisKKwkJCUZYX0RXT1JEIGR3Q291bnQgPSAqKChGWF9EV09SRCopcCk7CisJCQlwICs9IHNpemVvZihGWF9EV09SRCk7CisKKwkJCUZYX0RXT1JEIGR3U2l6ZSA9ICooKEZYX0RXT1JEKilwKTsKKwkJCXAgKz0gc2l6ZW9mKEZYX0RXT1JEKTsKKworCQkJaWYgKGR3U2l6ZSA9PSBuTGVuZ3RoIC0gc2l6ZW9mKEZYX1dPUkQpICogMiAtIHNpemVvZihGWF9EV09SRCkqIDIpCisJCQl7CisJCQkJZm9yIChGWF9JTlQzMiBpPTAsc3o9ZHdDb3VudDsgaTxzejsgaSsrKQorCQkJCXsKKwkJCQkJaWYgKHAgPiBwQnVmZmVyICsgbkxlbmd0aCkKKwkJCQkJCWJyZWFrOworCisJCQkJCUZYX0RXT1JEIGR3TmFtZUxlbiA9ICooKEZYX0RXT1JEKilwKTsKKwkJCQkJcCArPSBzaXplb2YoRlhfRFdPUkQpOworCisJCQkJCWlmIChwICsgZHdOYW1lTGVuID4gcEJ1ZmZlciArIG5MZW5ndGgpCisJCQkJCQlicmVhazsKKworCQkJCQlDRlhfQnl0ZVN0cmluZyBzRW50cnkgPSBDRlhfQnl0ZVN0cmluZyhwLCBkd05hbWVMZW4pOworCQkJCQlwICs9IHNpemVvZihjaGFyKSAqIGR3TmFtZUxlbjsKKworCQkJCQlGWF9XT1JEIHdEYXRhVHlwZSA9ICooKEZYX1dPUkQqKXApOworCQkJCQlwICs9IHNpemVvZihGWF9XT1JEKTsKKworCQkJCQlzd2l0Y2ggKHdEYXRhVHlwZSkKKwkJCQkJeworCQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI6CisJCQkJCQl7CisJCQkJCQkJZG91YmxlIGREYXRhID0gMDsKKwkJCQkJCQlzd2l0Y2ggKHdWZXJzaW9uKQorCQkJCQkJCXsKKwkJCQkJCQljYXNlIDE6CisJCQkJCQkJCXsKKwkJCQkJCQkJCUZYX0RXT1JEIGR3RGF0YSA9ICooKEZYX0RXT1JEKilwKTsKKwkJCQkJCQkJCXAgKz0gc2l6ZW9mKEZYX0RXT1JEKTsKKwkJCQkJCQkJCWREYXRhID0gZHdEYXRhOworCQkJCQkJCQl9CisJCQkJCQkJCWJyZWFrOworCQkJCQkJCWNhc2UgMjoKKwkJCQkJCQkJeworCQkJCQkJCQkJZERhdGEgPSAqKChkb3VibGUqKXApOworCQkJCQkJCQkJcCArPSBzaXplb2YoZG91YmxlKTsKKwkJCQkJCQkJfQorCQkJCQkJCQlicmVhazsKKwkJCQkJCQl9CisJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVOdW1iZXIoc0VudHJ5LCBkRGF0YSk7CisJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVQZXJzaXN0ZW50KHNFbnRyeSwgVFJVRSk7CisJCQkJCQl9CisJCQkJCQlicmVhazsKKwkJCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTjoKKwkJCQkJCXsKKwkJCQkJCQlGWF9XT1JEIHdEYXRhID0gKigoRlhfV09SRCopcCk7CisJCQkJCQkJcCArPSBzaXplb2YoRlhfV09SRCk7CisJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVCb29sZWFuKHNFbnRyeSwgKGJvb2wpKHdEYXRhID09IDEpKTsKKwkJCQkJCQlTZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQoc0VudHJ5LCBUUlVFKTsKKwkJCQkJCX0KKwkJCQkJCWJyZWFrOworCQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc6CisJCQkJCQl7CisJCQkJCQkJRlhfRFdPUkQgZHdMZW5ndGggPSAqKChGWF9EV09SRCopcCk7CisJCQkJCQkJcCArPSBzaXplb2YoRlhfRFdPUkQpOworCisJCQkJCQkJaWYgKHAgKyBkd0xlbmd0aCA+IHBCdWZmZXIgKyBuTGVuZ3RoKQorCQkJCQkJCQlicmVhazsKKworCQkJCQkJCVNldEdsb2JhbFZhcmlhYmxlU3RyaW5nKHNFbnRyeSwgQ0ZYX0J5dGVTdHJpbmcocCwgZHdMZW5ndGgpKTsKKwkJCQkJCQlTZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQoc0VudHJ5LCBUUlVFKTsKKwkJCQkJCQlwICs9IHNpemVvZihjaGFyKSAqIGR3TGVuZ3RoOworCQkJCQkJfQorCQkJCQkJYnJlYWs7CisJCQkJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTEw6CisJCQkJCQl7CisJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVOdWxsKHNFbnRyeSk7CisJCQkJCQkJU2V0R2xvYmFsVmFyaWFibGVQZXJzaXN0ZW50KHNFbnRyeSwgVFJVRSk7CisJCQkJCQl9CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCX0KKwkJRlhfRnJlZShwQnVmZmVyKTsKKwl9Cit9CisKKy8qCitzdHJ1Y3QganNfZ2xvYmFsX2RhdGFmaWxlX2hlYWRlcgoreworCUZYX1dPUkQgdHlwZTsgLy9GWCAoJ1gnIDw8IDgpIHwgJ0YnCisJRlhfV09SRCB2ZXJzaW9uOyAvLzEuMAorCUZYX0RXT1JEIGRhdGFjb3VudDsKK307CitzdHJ1Y3QganNfZ2xvYmFsX2RhdGFmaWxlX2RhdGEKK3sKKwlGWF9XT1JEIHR5cGU7CisJRlhfRFdPUkQgbkRhdGE7CisJRlhfV09SRCBiRGF0YTsKKwlGWF9EV09SRCBuU3RyTGVuOworCWNoYXIqIHBTdHI7Cit9OworKi8KKwordm9pZCBDSlNfR2xvYmFsRGF0YTo6U2F2ZUdsb2JhbFBlcnNpc2l0ZW50VmFyaWFibGVzKCkKK3sKKwlGWF9EV09SRCBuQ291bnQgPSAwOworCUNGWF9CaW5hcnlCdWYgc0RhdGE7CisKKwlmb3IgKGludCBpPTAsc3o9bV9hcnJheUdsb2JhbERhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwRWxlbWVudCA9IG1fYXJyYXlHbG9iYWxEYXRhLkdldEF0KGkpOworCQlBU1NFUlQocEVsZW1lbnQgIT0gTlVMTCk7CisKKwkJaWYgKHBFbGVtZW50LT5iUGVyc2lzdGVudCkKKwkJeworCQkJQ0ZYX0JpbmFyeUJ1ZiBzRWxlbWVudDsKKwkJCU1ha2VCeXRlU3RyaW5nKHBFbGVtZW50LT5kYXRhLnNLZXksICZwRWxlbWVudC0+ZGF0YSwgc0VsZW1lbnQpOworCisJCQlpZiAoc0RhdGEuR2V0U2l6ZSgpICsgc0VsZW1lbnQuR2V0U2l6ZSgpID4gSlNfTUFYR0xPQkFMREFUQSkKKwkJCQlicmVhazsKKworCQkJc0RhdGEuQXBwZW5kQmxvY2soc0VsZW1lbnQuR2V0QnVmZmVyKCksIHNFbGVtZW50LkdldFNpemUoKSk7CisJCQluQ291bnQrKzsKKwkJfQorCX0KKworCUNGWF9CaW5hcnlCdWYgc0ZpbGU7CisKKwlGWF9XT1JEIHdUeXBlID0gKEZYX1dPUkQpKCgnWCcgPDwgOCkgfCAnRicpOworCXNGaWxlLkFwcGVuZEJsb2NrKCZ3VHlwZSwgc2l6ZW9mKEZYX1dPUkQpKTsKKwlGWF9XT1JEIHdWZXJzaW9uID0gMjsKKwlzRmlsZS5BcHBlbmRCbG9jaygmd1ZlcnNpb24sIHNpemVvZihGWF9XT1JEKSk7CisJc0ZpbGUuQXBwZW5kQmxvY2soJm5Db3VudCwgc2l6ZW9mKEZYX0RXT1JEKSk7CisJRlhfRFdPUkQgZHdTaXplID0gc0RhdGEuR2V0U2l6ZSgpOworCXNGaWxlLkFwcGVuZEJsb2NrKCZkd1NpemUsIHNpemVvZihGWF9EV09SRCkpOworCisJc0ZpbGUuQXBwZW5kQmxvY2soc0RhdGEuR2V0QnVmZmVyKCksIHNEYXRhLkdldFNpemUoKSk7CisKKwlDUllQVF9BcmNGb3VyQ3J5cHRCbG9jayhzRmlsZS5HZXRCdWZmZXIoKSwgc0ZpbGUuR2V0U2l6ZSgpLCBKU19SQzRLRVksIHNpemVvZihKU19SQzRLRVkpKTsKKwlXcml0ZUZpbGVCdWZmZXIobV9zRmlsZVBhdGgsIChGWF9MUENTVFIpc0ZpbGUuR2V0QnVmZmVyKCksIHNGaWxlLkdldFNpemUoKSk7Cit9CisKK3ZvaWQgQ0pTX0dsb2JhbERhdGE6OkxvYWRGaWxlQnVmZmVyKEZYX0xQQ1dTVFIgc0ZpbGVQYXRoLCBGWF9MUEJZVEUmIHBCdWZmZXIsIEZYX0lOVDMyJiBuTGVuZ3RoKQoreworLy9VblN1cHBvcnQuCit9CisKK3ZvaWQgQ0pTX0dsb2JhbERhdGE6OldyaXRlRmlsZUJ1ZmZlcihGWF9MUENXU1RSIHNGaWxlUGF0aCwgRlhfTFBDU1RSIHBCdWZmZXIsIEZYX0lOVDMyIG5MZW5ndGgpCit7CisvL1VuU3VwcG9ydC4KK30KKwordm9pZCBDSlNfR2xvYmFsRGF0YTo6TWFrZUJ5dGVTdHJpbmcoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIG5hbWUsIENKU19LZXlWYWx1ZSogcERhdGEsIENGWF9CaW5hcnlCdWYmIHNEYXRhKQoreworCUFTU0VSVChwRGF0YSAhPSBOVUxMKTsKKworCUZYX1dPUkQgd1R5cGUgPSAoRlhfV09SRClwRGF0YS0+blR5cGU7CisKKwlzd2l0Y2ggKHdUeXBlKQorCXsKKwljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI6CisJCXsKKwkJCUZYX0RXT1JEIGR3TmFtZUxlbiA9IChGWF9EV09SRCluYW1lLkdldExlbmd0aCgpOworCQkJc0RhdGEuQXBwZW5kQmxvY2soJmR3TmFtZUxlbiwgc2l6ZW9mKEZYX0RXT1JEKSk7CisJCQlzRGF0YS5BcHBlbmRTdHJpbmcobmFtZSk7CisKKwkJCXNEYXRhLkFwcGVuZEJsb2NrKCZ3VHlwZSwgc2l6ZW9mKEZYX1dPUkQpKTsKKwkJCWRvdWJsZSBkRGF0YSA9IHBEYXRhLT5kRGF0YTsKKwkJCXNEYXRhLkFwcGVuZEJsb2NrKCZkRGF0YSwgc2l6ZW9mKGRvdWJsZSkpOworCQl9CisJCWJyZWFrOworCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46CisJCXsKKwkJCUZYX0RXT1JEIGR3TmFtZUxlbiA9IChGWF9EV09SRCluYW1lLkdldExlbmd0aCgpOworCQkJc0RhdGEuQXBwZW5kQmxvY2soJmR3TmFtZUxlbiwgc2l6ZW9mKEZYX0RXT1JEKSk7CisJCQlzRGF0YS5BcHBlbmRTdHJpbmcobmFtZSk7CisKKwkJCXNEYXRhLkFwcGVuZEJsb2NrKCZ3VHlwZSwgc2l6ZW9mKEZYX1dPUkQpKTsKKwkJCUZYX1dPUkQgd0RhdGEgPSAoRlhfV09SRClwRGF0YS0+YkRhdGE7CisJCQlzRGF0YS5BcHBlbmRCbG9jaygmd0RhdGEsIHNpemVvZihGWF9XT1JEKSk7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOgorCQl7CisJCQlGWF9EV09SRCBkd05hbWVMZW4gPSAoRlhfRFdPUkQpbmFtZS5HZXRMZW5ndGgoKTsKKwkJCXNEYXRhLkFwcGVuZEJsb2NrKCZkd05hbWVMZW4sIHNpemVvZihGWF9EV09SRCkpOworCQkJc0RhdGEuQXBwZW5kU3RyaW5nKG5hbWUpOworCisJCQlzRGF0YS5BcHBlbmRCbG9jaygmd1R5cGUsIHNpemVvZihGWF9XT1JEKSk7CisKKwkJCUZYX0RXT1JEIGR3RGF0YUxlbiA9IChGWF9EV09SRClwRGF0YS0+c0RhdGEuR2V0TGVuZ3RoKCk7CisJCQlzRGF0YS5BcHBlbmRCbG9jaygmZHdEYXRhTGVuLCBzaXplb2YoRlhfRFdPUkQpKTsKKwkJCXNEYXRhLkFwcGVuZFN0cmluZyhwRGF0YS0+c0RhdGEpOworCQl9CisJCWJyZWFrOworCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTEw6CisJCXsKKwkJCUZYX0RXT1JEIGR3TmFtZUxlbiA9IChGWF9EV09SRCluYW1lLkdldExlbmd0aCgpOworCQkJc0RhdGEuQXBwZW5kQmxvY2soJmR3TmFtZUxlbiwgc2l6ZW9mKEZYX0RXT1JEKSk7CisJCQlzRGF0YS5BcHBlbmRTdHJpbmcobmFtZSk7CisKKwkJCXNEYXRhLkFwcGVuZEJsb2NrKCZ3VHlwZSwgc2l6ZW9mKEZYX0RXT1JEKSk7CisJCX0KKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJYnJlYWs7CisJfQorfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX09iamVjdC5jcHAgYi9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX09iamVjdC5jcHAKaW5kZXggMzgzMGIyYS4uM2I3Nzc0ZCAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9KU19PYmplY3QuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSlNfT2JqZWN0LmNwcApAQCAtMSwxNDUgKzEsMTQ1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIg0KLS8vICNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfTXNnQm94LmgiDQotLy8gI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19SZXNNZ3IuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCINCi0NCi1pbnQgRlhKU19Nc2dCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LCBGWF9MUENXU1RSIHN3TXNnLCBGWF9MUENXU1RSIHN3VGl0bGUsIEZYX1VJTlQgblR5cGUsIEZYX1VJTlQgbkljb24pDQotew0KLQlpbnQgblJldCA9IDA7DQotDQotCWlmKHBBcHApDQotCXsNCi0JCUNQREZTREtfRG9jdW1lbnQqIHBEb2MgPSBwQXBwLT5HZXRDdXJyZW50RG9jKCk7DQotCQlpZihwRG9jKQ0KLQkJCXBEb2MtPktpbGxGb2N1c0Fubm90KCk7DQotCQluUmV0ID0gcEFwcC0+SlNfYXBwQWxlcnQoc3dNc2csIHN3VGl0bGUsIG5UeXBlLCBuSWNvbik7DQotCX0NCi0NCi0JcmV0dXJuIG5SZXQ7DQotfQ0KLQ0KLUNQREZTREtfUGFnZVZpZXcqIEZYSlNfR2V0UGFnZVZpZXcoSUZYSlNfQ29udGV4dCogY2MpDQotew0KLQlpZiAoQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2MpDQotCXsNCi0JCWlmIChwQ29udGV4dC0+R2V0UmVhZGVyRG9jdW1lbnQoKSkNCi0JCQlyZXR1cm4gTlVMTDsNCi0JfQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICBDSlNfRW1iZWRPYmogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0pTX0VtYmVkT2JqOjpDSlNfRW1iZWRPYmooQ0pTX09iamVjdCogcEpTT2JqZWN0KSA6IA0KLQltX3BKU09iamVjdChwSlNPYmplY3QpDQotew0KLX0NCi0NCi1DSlNfRW1iZWRPYmo6On5DSlNfRW1iZWRPYmooKQ0KLXsNCi0JbV9wSlNPYmplY3QgPSBOVUxMOw0KLQ0KLX0NCi0NCi1DUERGU0RLX1BhZ2VWaWV3KiBDSlNfRW1iZWRPYmo6OkpTR2V0UGFnZVZpZXcoSUZYSlNfQ29udGV4dCogY2MpDQotew0KLQlyZXR1cm4gRlhKU19HZXRQYWdlVmlldyhjYyk7DQotfQ0KLQ0KLWludCBDSlNfRW1iZWRPYmo6Ok1zZ0JveChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsRlhfTFBDV1NUUiBzd01zZyxGWF9MUENXU1RSIHN3VGl0bGUsRlhfVUlOVCBuVHlwZSxGWF9VSU5UIG5JY29uKQ0KLXsNCi0JcmV0dXJuIEZYSlNfTXNnQm94KHBBcHAsIHBQYWdlVmlldywgc3dNc2csIHN3VGl0bGUsIG5UeXBlLCBuSWNvbik7DQotfQ0KLQ0KLXZvaWQgQ0pTX0VtYmVkT2JqOjpBbGVydChDSlNfQ29udGV4dCogcENvbnRleHQsIEZYX0xQQ1dTVFIgc3dNc2cpDQotew0KLQlDSlNfT2JqZWN0OjpBbGVydChwQ29udGV4dCwgc3dNc2cpOw0KLX0NCi0NCi1DSlNfVGltZXIqIENKU19FbWJlZE9iajo6QmVnaW5UaW1lcihDUERGRG9jX0Vudmlyb25tZW50ICogcEFwcCxGWF9VSU5UIG5FbGFwc2UpDQotew0KLQlDSlNfVGltZXIqIHBUaW1lciA9IG5ldyBDSlNfVGltZXIodGhpcyxwQXBwKTsNCi0JcFRpbWVyLT5TZXRKU1RpbWVyKG5FbGFwc2UpOw0KLQkNCi0JcmV0dXJuIHBUaW1lcjsNCi19DQotDQotdm9pZCBDSlNfRW1iZWRPYmo6OkVuZFRpbWVyKENKU19UaW1lciogcFRpbWVyKQ0KLXsNCi0JQVNTRVJUKHBUaW1lciAhPSBOVUxMKTsNCi0JcFRpbWVyLT5LaWxsSlNUaW1lcigpOw0KLQlkZWxldGUgcFRpbWVyOw0KLX0NCi0NCi1GWF9CT09MCUNKU19FbWJlZE9iajo6SXNTYWZlTW9kZShJRlhKU19Db250ZXh0KiBjYykNCi17DQotCUFTU0VSVChjYyAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgQ0pTX09iamVjdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi12b2lkICBGcmVlT2JqZWN0KGNvbnN0IHY4OjpXZWFrQ2FsbGJhY2tEYXRhPHY4OjpPYmplY3QsIENKU19PYmplY3Q+JiBkYXRhKQ0KLXsNCi0JQ0pTX09iamVjdCogcEpTT2JqICA9IGRhdGEuR2V0UGFyYW1ldGVyKCk7DQotCWlmKHBKU09iaikNCi0Jew0KLQkJcEpTT2JqLT5FeGl0SW5zdGFuY2UoKTsNCi0JCWRlbGV0ZSBwSlNPYmo7DQotCX0NCi0Jdjg6OkxvY2FsPHY4OjpPYmplY3Q+IG9iaiA9IGRhdGEuR2V0VmFsdWUoKTsNCi0JSlNfRnJlZVByaXZhdGUob2JqKTsNCi19DQotDQotQ0pTX09iamVjdDo6Q0pTX09iamVjdChKU0ZYT2JqZWN0IHBPYmplY3QpIDptX3BFbWJlZE9iaihOVUxMKQ0KLXsNCi0Jdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gcE9iamVjdC0+Q3JlYXRpb25Db250ZXh0KCk7DQotCW1fcElzb2xhdGUgPSBjb250ZXh0LT5HZXRJc29sYXRlKCk7DQotCW1fcE9iamVjdC5SZXNldChtX3BJc29sYXRlLCBwT2JqZWN0KTsNCi19Ow0KLQ0KLUNKU19PYmplY3Q6On5DSlNfT2JqZWN0KHZvaWQpDQotew0KLQlkZWxldGUgbV9wRW1iZWRPYmo7DQotCW1fcEVtYmVkT2JqID0gTlVMTDsNCi0NCi0JbV9wT2JqZWN0LlJlc2V0KCk7DQotfTsNCi0NCi12b2lkCUNKU19PYmplY3Q6Ok1ha2VXZWFrKCkNCi17DQotCW1fcE9iamVjdC5TZXRXZWFrKHRoaXMsIEZyZWVPYmplY3QpOw0KLX0NCi0NCi1DUERGU0RLX1BhZ2VWaWV3KiBDSlNfT2JqZWN0OjpKU0dldFBhZ2VWaWV3KElGWEpTX0NvbnRleHQqIGNjKQ0KLXsNCi0JcmV0dXJuIEZYSlNfR2V0UGFnZVZpZXcoY2MpOw0KLX0NCi0NCi1pbnQgQ0pTX09iamVjdDo6TXNnQm94KENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfTFBDV1NUUiBzd01zZywgRlhfTFBDV1NUUiBzd1RpdGxlLCBGWF9VSU5UIG5UeXBlLCBGWF9VSU5UIG5JY29uKQ0KLXsNCi0JcmV0dXJuIEZYSlNfTXNnQm94KHBBcHAsIHBQYWdlVmlldywgc3dNc2csIHN3VGl0bGUsIG5UeXBlLCBuSWNvbik7DQotfQ0KLQ0KLXZvaWQgQ0pTX09iamVjdDo6QWxlcnQoQ0pTX0NvbnRleHQqIHBDb250ZXh0LCBGWF9MUENXU1RSIHN3TXNnKQ0KLXsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQlpZiAocENvbnRleHQtPklzTXNnQm94RW5hYmxlZCgpKQ0KLQl7DQotCQlDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwID0gcENvbnRleHQtPkdldFJlYWRlckFwcCgpOw0KLQkJaWYocEFwcCkNCi0JCQlwQXBwLT5KU19hcHBBbGVydChzd01zZywgTlVMTCwgMCwgMyk7DQotCX0NCi19DQotDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKKy8vICNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfTXNnQm94LmgiCisvLyAjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1Jlc01nci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgiCisKK2ludCBGWEpTX01zZ0JveChDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwLCBDUERGU0RLX1BhZ2VWaWV3KiBwUGFnZVZpZXcsIEZYX0xQQ1dTVFIgc3dNc2csIEZYX0xQQ1dTVFIgc3dUaXRsZSwgRlhfVUlOVCBuVHlwZSwgRlhfVUlOVCBuSWNvbikKK3sKKwlpbnQgblJldCA9IDA7CisKKwlpZihwQXBwKQorCXsKKwkJQ1BERlNES19Eb2N1bWVudCogcERvYyA9IHBBcHAtPkdldEN1cnJlbnREb2MoKTsKKwkJaWYocERvYykKKwkJCXBEb2MtPktpbGxGb2N1c0Fubm90KCk7CisJCW5SZXQgPSBwQXBwLT5KU19hcHBBbGVydChzd01zZywgc3dUaXRsZSwgblR5cGUsIG5JY29uKTsKKwl9CisKKwlyZXR1cm4gblJldDsKK30KKworQ1BERlNES19QYWdlVmlldyogRlhKU19HZXRQYWdlVmlldyhJRlhKU19Db250ZXh0KiBjYykKK3sKKwlpZiAoQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2MpCisJeworCQlpZiAocENvbnRleHQtPkdldFJlYWRlckRvY3VtZW50KCkpCisJCQlyZXR1cm4gTlVMTDsKKwl9CisJcmV0dXJuIE5VTEw7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgQ0pTX0VtYmVkT2JqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDSlNfRW1iZWRPYmo6OkNKU19FbWJlZE9iaihDSlNfT2JqZWN0KiBwSlNPYmplY3QpIDogCisJbV9wSlNPYmplY3QocEpTT2JqZWN0KQoreworfQorCitDSlNfRW1iZWRPYmo6On5DSlNfRW1iZWRPYmooKQoreworCW1fcEpTT2JqZWN0ID0gTlVMTDsKKworfQorCitDUERGU0RLX1BhZ2VWaWV3KiBDSlNfRW1iZWRPYmo6OkpTR2V0UGFnZVZpZXcoSUZYSlNfQ29udGV4dCogY2MpCit7CisJcmV0dXJuIEZYSlNfR2V0UGFnZVZpZXcoY2MpOworfQorCitpbnQgQ0pTX0VtYmVkT2JqOjpNc2dCb3goQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCwgQ1BERlNES19QYWdlVmlldyogcFBhZ2VWaWV3LEZYX0xQQ1dTVFIgc3dNc2csRlhfTFBDV1NUUiBzd1RpdGxlLEZYX1VJTlQgblR5cGUsRlhfVUlOVCBuSWNvbikKK3sKKwlyZXR1cm4gRlhKU19Nc2dCb3gocEFwcCwgcFBhZ2VWaWV3LCBzd01zZywgc3dUaXRsZSwgblR5cGUsIG5JY29uKTsKK30KKwordm9pZCBDSlNfRW1iZWRPYmo6OkFsZXJ0KENKU19Db250ZXh0KiBwQ29udGV4dCwgRlhfTFBDV1NUUiBzd01zZykKK3sKKwlDSlNfT2JqZWN0OjpBbGVydChwQ29udGV4dCwgc3dNc2cpOworfQorCitDSlNfVGltZXIqIENKU19FbWJlZE9iajo6QmVnaW5UaW1lcihDUERGRG9jX0Vudmlyb25tZW50ICogcEFwcCxGWF9VSU5UIG5FbGFwc2UpCit7CisJQ0pTX1RpbWVyKiBwVGltZXIgPSBuZXcgQ0pTX1RpbWVyKHRoaXMscEFwcCk7CisJcFRpbWVyLT5TZXRKU1RpbWVyKG5FbGFwc2UpOworCQorCXJldHVybiBwVGltZXI7Cit9CisKK3ZvaWQgQ0pTX0VtYmVkT2JqOjpFbmRUaW1lcihDSlNfVGltZXIqIHBUaW1lcikKK3sKKwlBU1NFUlQocFRpbWVyICE9IE5VTEwpOworCXBUaW1lci0+S2lsbEpTVGltZXIoKTsKKwlkZWxldGUgcFRpbWVyOworfQorCitGWF9CT09MCUNKU19FbWJlZE9iajo6SXNTYWZlTW9kZShJRlhKU19Db250ZXh0KiBjYykKK3sKKwlBU1NFUlQoY2MgIT0gTlVMTCk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICBDSlNfT2JqZWN0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwordm9pZCAgRnJlZU9iamVjdChjb25zdCB2ODo6V2Vha0NhbGxiYWNrRGF0YTx2ODo6T2JqZWN0LCBDSlNfT2JqZWN0PiYgZGF0YSkKK3sKKwlDSlNfT2JqZWN0KiBwSlNPYmogID0gZGF0YS5HZXRQYXJhbWV0ZXIoKTsKKwlpZihwSlNPYmopCisJeworCQlwSlNPYmotPkV4aXRJbnN0YW5jZSgpOworCQlkZWxldGUgcEpTT2JqOworCX0KKwl2ODo6TG9jYWw8djg6Ok9iamVjdD4gb2JqID0gZGF0YS5HZXRWYWx1ZSgpOworCUpTX0ZyZWVQcml2YXRlKG9iaik7Cit9CisKK0NKU19PYmplY3Q6OkNKU19PYmplY3QoSlNGWE9iamVjdCBwT2JqZWN0KSA6bV9wRW1iZWRPYmooTlVMTCkKK3sKKwl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPSBwT2JqZWN0LT5DcmVhdGlvbkNvbnRleHQoKTsKKwltX3BJc29sYXRlID0gY29udGV4dC0+R2V0SXNvbGF0ZSgpOworCW1fcE9iamVjdC5SZXNldChtX3BJc29sYXRlLCBwT2JqZWN0KTsKK307CisKK0NKU19PYmplY3Q6On5DSlNfT2JqZWN0KHZvaWQpCit7CisJZGVsZXRlIG1fcEVtYmVkT2JqOworCW1fcEVtYmVkT2JqID0gTlVMTDsKKworCW1fcE9iamVjdC5SZXNldCgpOworfTsKKwordm9pZAlDSlNfT2JqZWN0OjpNYWtlV2VhaygpCit7CisJbV9wT2JqZWN0LlNldFdlYWsodGhpcywgRnJlZU9iamVjdCk7Cit9CisKK0NQREZTREtfUGFnZVZpZXcqIENKU19PYmplY3Q6OkpTR2V0UGFnZVZpZXcoSUZYSlNfQ29udGV4dCogY2MpCit7CisJcmV0dXJuIEZYSlNfR2V0UGFnZVZpZXcoY2MpOworfQorCitpbnQgQ0pTX09iamVjdDo6TXNnQm94KENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAsIENQREZTREtfUGFnZVZpZXcqIHBQYWdlVmlldywgRlhfTFBDV1NUUiBzd01zZywgRlhfTFBDV1NUUiBzd1RpdGxlLCBGWF9VSU5UIG5UeXBlLCBGWF9VSU5UIG5JY29uKQoreworCXJldHVybiBGWEpTX01zZ0JveChwQXBwLCBwUGFnZVZpZXcsIHN3TXNnLCBzd1RpdGxlLCBuVHlwZSwgbkljb24pOworfQorCit2b2lkIENKU19PYmplY3Q6OkFsZXJ0KENKU19Db250ZXh0KiBwQ29udGV4dCwgRlhfTFBDV1NUUiBzd01zZykKK3sKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwlpZiAocENvbnRleHQtPklzTXNnQm94RW5hYmxlZCgpKQorCXsKKwkJQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBDb250ZXh0LT5HZXRSZWFkZXJBcHAoKTsKKwkJaWYocEFwcCkKKwkJCXBBcHAtPkpTX2FwcEFsZXJ0KHN3TXNnLCBOVUxMLCAwLCAzKTsKKwl9Cit9CisKKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9KU19SdW50aW1lLmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSlNfUnVudGltZS5jcHAKaW5kZXggNzc3OTY0My4uYzdhOTJlYiAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9KU19SdW50aW1lLmNwcAorKysgYi9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuY3BwCkBAIC0xLDQ3MCArMSw0NzAgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9Eb2N1bWVudC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvYXBwLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9jb2xvci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvQ29uc3RzLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9Eb2N1bWVudC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvZXZlbnQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0ZpZWxkLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JY29uLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9QdWJsaWNNZXRob2RzLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9yZXBvcnQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L3V0aWwuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0dsb2JhbERhdGEuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2dsb2JhbC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvY29uc29sZS5oIg0KLQ0KLUNKU19SdW50aW1lRmFjdG9yeTo6fkNKU19SdW50aW1lRmFjdG9yeSgpDQotew0KLX0NCi0NCi1JRlhKU19SdW50aW1lKgkJCQkJQ0pTX1J1bnRpbWVGYWN0b3J5OjpOZXdKU1J1bnRpbWUoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCkNCi17DQotCWlmICghbV9iSW5pdCkNCi0Jew0KLQkJSlNfSW5pdGlhbCgpOw0KLQkJDQotCQltX2JJbml0ID0gVFJVRTsNCi0JfQ0KLQlyZXR1cm4gbmV3IENKU19SdW50aW1lKHBBcHApOw0KLX0NCi12b2lkCQkJCQkJCUNKU19SdW50aW1lRmFjdG9yeTo6QWRkUmVmKCkNCi17DQotCS8vdG8gZG8uU2hvdWxkIGJlIGltcGxlbWVudGVkIGFzIGF0b20gbWFuaXB1bGF0aW9uLg0KLQltX25SZWYrKzsNCi19DQotdm9pZAkJCQkJCQlDSlNfUnVudGltZUZhY3Rvcnk6OlJlbGVhc2UoKQ0KLXsJDQotCWlmKG1fYkluaXQpDQotCXsNCi0JCS8vdG8gZG8uU2hvdWxkIGJlIGltcGxlbWVudGVkIGFzIGF0b20gbWFuaXB1bGF0aW9uLg0KLQkJaWYgKC0tbV9uUmVmID09IDApDQotCQl7DQotCQkJSlNfUmVsZWFzZSgpOw0KLQkJCVJlbGVhc2VHbG9iYWxEYXRhKCk7DQotCQkJbV9iSW5pdCA9IEZBTFNFOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQJCQkJCQkJQ0pTX1J1bnRpbWVGYWN0b3J5OjpEZWxldGVKU1J1bnRpbWUoSUZYSlNfUnVudGltZSogcFJ1bnRpbWUpDQotew0KLQlpZihwUnVudGltZSkNCi0JCWRlbGV0ZSAoQ0pTX1J1bnRpbWUqKXBSdW50aW1lOw0KLX0NCi0NCi1DSlNfR2xvYmFsRGF0YSoJQ0pTX1J1bnRpbWVGYWN0b3J5OjpOZXdHbG9iYWxEYXRhKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHApDQotew0KLQlpZiAobV9wR2xvYmFsRGF0YSkNCi0Jew0KLQkJbV9uR2xvYmFsRGF0YUNvdW50Kys7DQotCQlyZXR1cm4gbV9wR2xvYmFsRGF0YTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCW1fbkdsb2JhbERhdGFDb3VudCA9IDE7DQotCQltX3BHbG9iYWxEYXRhID0gbmV3IENKU19HbG9iYWxEYXRhKHBBcHApOw0KLQkJcmV0dXJuIG1fcEdsb2JhbERhdGE7DQotCX0NCi19DQotDQotdm9pZCBDSlNfUnVudGltZUZhY3Rvcnk6OlJlbGVhc2VHbG9iYWxEYXRhKCkNCi17DQotCW1fbkdsb2JhbERhdGFDb3VudC0tOw0KLQkNCi0JaWYgKG1fbkdsb2JhbERhdGFDb3VudCA8PSAwKQ0KLQl7DQotIAkJZGVsZXRlIG1fcEdsb2JhbERhdGE7DQotIAkJbV9wR2xvYmFsRGF0YSA9IE5VTEw7DQotCX0NCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENKU19SdW50aW1lIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNKU19SdW50aW1lOjpDSlNfUnVudGltZShDUERGRG9jX0Vudmlyb25tZW50ICogcEFwcCkgOiANCi0JbV9wQXBwKHBBcHApLA0KLQltX3BEb2N1bWVudChOVUxMKSwNCi0JbV9wRmllbGRFdmVudFBhdGgoTlVMTCksDQotCW1fYkJsb2NraW5nKEZBTFNFKSwNCi0JbV9iUmVnaXN0ZXJlZChGQUxTRSkNCi17DQotCW1faXNvbGF0ZSA9IHY4OjpJc29sYXRlOjpOZXcoKTsNCi0JLy9tX2lzb2xhdGUtPkVudGVyKCk7DQotDQotCUluaXRKU09iamVjdHMoKTsNCi0NCi0JQ0pTX0NvbnRleHQgKiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopTmV3Q29udGV4dCgpOw0KLQlKU19Jbml0aWFsUnVudGltZSgqdGhpcywgdGhpcywgcENvbnRleHQsIG1fY29udGV4dCk7DQotCVJlbGVhc2VDb250ZXh0KHBDb250ZXh0KTsNCi19DQotDQotQ0pTX1J1bnRpbWU6On5DSlNfUnVudGltZSgpDQotew0KLQlmb3IgKGludCBpPTAsIHN6PW1fQ29udGV4dEFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJZGVsZXRlIG1fQ29udGV4dEFycmF5LkdldEF0KGkpOw0KLQ0KLQltX0NvbnRleHRBcnJheS5SZW1vdmVBbGwoKTsNCi0NCi0JSlNfUmVsZWFzZVJ1bnRpbWUoKnRoaXMsIG1fY29udGV4dCk7DQotDQotCVJlbW92ZUV2ZW50c0luTG9vcChtX3BGaWVsZEV2ZW50UGF0aCk7DQotDQotCW1fcEFwcCA9IE5VTEw7DQotCW1fcERvY3VtZW50ID0gTlVMTDsNCi0JbV9wRmllbGRFdmVudFBhdGggPSBOVUxMOw0KLQltX2NvbnRleHQuUmVzZXQoKTsNCi0NCi0JLy9tX2lzb2xhdGUtPkV4aXQoKTsNCi0JbV9pc29sYXRlLT5EaXNwb3NlKCk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1J1bnRpbWU6OkluaXRKU09iamVjdHMoKQ0KLXsNCi0Jdjg6Oklzb2xhdGU6OlNjb3BlIGlzb2xhdGVfc2NvcGUoR2V0SXNvbGF0ZSgpKTsNCi0Jdjg6OkhhbmRsZVNjb3BlIGhhbmRsZV9zY29wZShHZXRJc29sYXRlKCkpOw0KLQl2ODo6SGFuZGxlPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gdjg6OkNvbnRleHQ6Ok5ldyhHZXRJc29sYXRlKCkpOw0KLQl2ODo6Q29udGV4dDo6U2NvcGUgY29udGV4dF9zY29wZShjb250ZXh0KTsNCi0JLy8wIC0gOA0KLQlpZiAoQ0pTX0JvcmRlcjo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsNCi0JaWYgKENKU19EaXNwbGF5OjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOw0KLQlpZiAoQ0pTX0ZvbnQ6OkluaXQoKnRoaXMsIEpTX1NUQVRJQykgPCAwKSByZXR1cm4gRkFMU0U7DQotCWlmIChDSlNfSGlnaGxpZ2h0OjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOw0KLQlpZiAoQ0pTX1Bvc2l0aW9uOjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOw0KLQlpZiAoQ0pTX1NjYWxlSG93OjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOw0KLQlpZiAoQ0pTX1NjYWxlV2hlbjo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsNCi0JaWYgKENKU19TdHlsZTo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsJDQotCWlmIChDSlNfWm9vbXR5cGU6OkluaXQoKnRoaXMsIEpTX1NUQVRJQykgPCAwKSByZXR1cm4gRkFMU0U7CQ0KLQ0KLQkvLzkgLSAxMQ0KLQlpZiAoQ0pTX0FwcDo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsNCi0JaWYgKENKU19Db2xvcjo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsgICANCi0JaWYgKENKU19Db25zb2xlOjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQkvLzEyIC0gMTQNCi0JaWYgKENKU19Eb2N1bWVudDo6SW5pdCgqdGhpcywgSlNfRFlOQU1JQykgPCAwKSByZXR1cm4gRkFMU0U7ICANCi0JaWYgKENKU19FdmVudDo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsJCQ0KLQlpZiAoQ0pTX0ZpZWxkOjpJbml0KCp0aGlzLCBKU19EWU5BTUlDKSA8IDApIHJldHVybiBGQUxTRTsgICAgDQotDQotCS8vMTUgLSAxNw0KLQlpZiAoQ0pTX0dsb2JhbDo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsJCQ0KLQlpZiAoQ0pTX0ljb246OkluaXQoKnRoaXMsIEpTX0RZTkFNSUMpIDwgMCkgcmV0dXJuIEZBTFNFOw0KLQlpZiAoQ0pTX1V0aWw6OkluaXQoKnRoaXMsIEpTX1NUQVRJQykgPCAwKSByZXR1cm4gRkFMU0U7DQotDQotCWlmIChDSlNfUHVibGljTWV0aG9kczo6SW5pdCgqdGhpcykgPCAwKSByZXR1cm4gRkFMU0U7DQotCWlmIChDSlNfR2xvYmFsQ29uc3RzOjpJbml0KCp0aGlzKSA8IDApIHJldHVybiBGQUxTRTsNCi0JaWYgKENKU19HbG9iYWxBcnJheXM6OkluaXQoKnRoaXMpIDwgMCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAoQ0pTX1RpbWVyT2JqOjpJbml0KCp0aGlzLCBKU19EWU5BTUlDKSA8IDApIHJldHVybiBGQUxTRTsNCi0JaWYgKENKU19QcmludFBhcmFtc09iajo6SW5pdCgqdGhpcywgSlNfRFlOQU1JQykgPDApIHJldHVybiBGQUxTRTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUlGWEpTX0NvbnRleHQqIENKU19SdW50aW1lOjpOZXdDb250ZXh0KCkNCi17DQotCUNKU19Db250ZXh0ICogcCA9IG5ldyBDSlNfQ29udGV4dCh0aGlzKTsNCi0JbV9Db250ZXh0QXJyYXkuQWRkKHApOw0KLQlyZXR1cm4gcDsNCi19DQotDQotdm9pZCBDSlNfUnVudGltZTo6UmVsZWFzZUNvbnRleHQoSUZYSlNfQ29udGV4dCAqIHBDb250ZXh0KQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBKU0NvbnRleHQgPSAoQ0pTX0NvbnRleHQqKXBDb250ZXh0Ow0KLQ0KLQlmb3IgKGludCBpPTAsIHN6PW1fQ29udGV4dEFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAocEpTQ29udGV4dCA9PSBtX0NvbnRleHRBcnJheS5HZXRBdChpKSkNCi0JCXsNCi0JCQlkZWxldGUgcEpTQ29udGV4dDsNCi0JCQltX0NvbnRleHRBcnJheS5SZW1vdmVBdChpKTsNCi0JCQlicmVhazsNCi0JCX0NCi0JfQ0KLX0NCi0NCi1JRlhKU19Db250ZXh0KglDSlNfUnVudGltZTo6R2V0Q3VycmVudENvbnRleHQoKQ0KLXsNCi0JaWYoIW1fQ29udGV4dEFycmF5LkdldFNpemUoKSkNCi0JCXJldHVybiBOVUxMOw0KLQlyZXR1cm4gbV9Db250ZXh0QXJyYXkuR2V0QXQobV9Db250ZXh0QXJyYXkuR2V0U2l6ZSgpLTEpOw0KLX0NCi0NCi12b2lkIENKU19SdW50aW1lOjpTZXRSZWFkZXJEb2N1bWVudChDUERGU0RLX0RvY3VtZW50KiBwUmVhZGVyRG9jKQ0KLXsNCi0JaWYgKG1fcERvY3VtZW50ICE9IHBSZWFkZXJEb2MpDQotCXsNCi0JCXY4OjpJc29sYXRlOjpTY29wZSBpc29sYXRlX3Njb3BlKG1faXNvbGF0ZSk7DQotCQl2ODo6SGFuZGxlU2NvcGUgaGFuZGxlX3Njb3BlKG1faXNvbGF0ZSk7DQotCQl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPXY4OjpMb2NhbDx2ODo6Q29udGV4dD46Ok5ldyhtX2lzb2xhdGUsIG1fY29udGV4dCk7DQotCQl2ODo6Q29udGV4dDo6U2NvcGUgY29udGV4dF9zY29wZShjb250ZXh0KTsNCi0NCi0JCW1fcERvY3VtZW50ID0gcFJlYWRlckRvYzsNCi0NCi0JCWlmIChwUmVhZGVyRG9jKQ0KLQkJew0KLQkJCUpTT2JqZWN0IHBUaGlzID0gSlNfR2V0VGhpc09iaigqdGhpcyk7DQotCQkJaWYoIXBUaGlzLklzRW1wdHkoKSkNCi0JCQl7DQotCQkJCWlmIChKU19HZXRPYmpEZWZuSUQocFRoaXMpID09IEpTX0dldE9iakRlZm5JRCgqdGhpcywgTCJEb2N1bWVudCIpKQ0KLQkJCQl7DQotCQkJCQlpZiAoQ0pTX0RvY3VtZW50KiBwSlNEb2N1bWVudCA9IChDSlNfRG9jdW1lbnQqKUpTX0dldFByaXZhdGUocFRoaXMpKQ0KLQkJCQkJew0KLQkJCQkJCWlmIChEb2N1bWVudCAqIHBEb2N1bWVudCA9IChEb2N1bWVudCopcEpTRG9jdW1lbnQtPkdldEVtYmVkT2JqZWN0KCkpDQotCQkJCQkJCXBEb2N1bWVudC0+QXR0YWNoRG9jKHBSZWFkZXJEb2MpOw0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJCUpTX1NldFRoaXNPYmooKnRoaXMsIEpTX0dldE9iakRlZm5JRCgqdGhpcywgTCJEb2N1bWVudCIpKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlKU19TZXRUaGlzT2JqKCp0aGlzLCBKU19HZXRPYmpEZWZuSUQoKnRoaXMsIEwiYXBwIikpOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wJQ0pTX1J1bnRpbWU6OkFkZEV2ZW50VG9Mb29wKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGFyZ2V0TmFtZSwgSlNfRVZFTlRfVCBlRXZlbnRUeXBlKQ0KLXsNCi0JaWYgKG1fcEZpZWxkRXZlbnRQYXRoID09IE5VTEwpDQotCXsNCi0JCW1fcEZpZWxkRXZlbnRQYXRoID0gbmV3IENKU19GaWVsZEV2ZW50Ow0KLQkJbV9wRmllbGRFdmVudFBhdGgtPnNUYXJnZXROYW1lID0gc1RhcmdldE5hbWU7DQotCQltX3BGaWVsZEV2ZW50UGF0aC0+ZUV2ZW50VHlwZSA9IGVFdmVudFR5cGU7DQotCQltX3BGaWVsZEV2ZW50UGF0aC0+cE5leHQgPSBOVUxMOw0KLQ0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JLy90byBzZWFyY2gNCi0JQ0pTX0ZpZWxkRXZlbnQqIHAgPSBtX3BGaWVsZEV2ZW50UGF0aDsNCi0JQ0pTX0ZpZWxkRXZlbnQqIHBMYXN0ID0gbV9wRmllbGRFdmVudFBhdGg7DQotCXdoaWxlIChwKQ0KLQl7DQotCQlpZiAocC0+ZUV2ZW50VHlwZSA9PSBlRXZlbnRUeXBlICYmIHAtPnNUYXJnZXROYW1lID09IHNUYXJnZXROYW1lKQ0KLQkJCXJldHVybiBGQUxTRTsNCi0NCi0JCXBMYXN0ID0gcDsNCi0JCXAgPSBwLT5wTmV4dDsNCi0JfQ0KLQ0KLQkvL3RvIGFkZA0KLQlDSlNfRmllbGRFdmVudCogcE5ldyA9IG5ldyBDSlNfRmllbGRFdmVudDsNCi0JcE5ldy0+c1RhcmdldE5hbWUgPSBzVGFyZ2V0TmFtZTsNCi0JcE5ldy0+ZUV2ZW50VHlwZSA9IGVFdmVudFR5cGU7DQotCXBOZXctPnBOZXh0ID0gTlVMTDsNCi0NCi0JcExhc3QtPnBOZXh0ID0gcE5ldzsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgQ0pTX1J1bnRpbWU6OlJlbW92ZUV2ZW50SW5Mb29wKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGFyZ2V0TmFtZSwgSlNfRVZFTlRfVCBlRXZlbnRUeXBlKQ0KLXsNCi0JRlhfQk9PTCBiRmluZCA9IEZBTFNFOw0KLQ0KLQlDSlNfRmllbGRFdmVudCogcCA9IG1fcEZpZWxkRXZlbnRQYXRoOw0KLQlDSlNfRmllbGRFdmVudCogcExhc3QgPSBOVUxMOw0KLQl3aGlsZSAocCkNCi0Jew0KLQkJaWYgKHAtPmVFdmVudFR5cGUgPT0gZUV2ZW50VHlwZSAmJiBwLT5zVGFyZ2V0TmFtZSA9PSBzVGFyZ2V0TmFtZSkNCi0JCXsNCi0JCQliRmluZCA9IFRSVUU7DQotCQkJYnJlYWs7DQotCQl9DQotDQotCQlwTGFzdCA9IHA7DQotCQlwID0gcC0+cE5leHQ7DQotCX0NCi0NCi0JaWYgKGJGaW5kKQ0KLQl7DQotCQlSZW1vdmVFdmVudHNJbkxvb3AocCk7DQotDQotCQlpZiAocCA9PSBtX3BGaWVsZEV2ZW50UGF0aCkNCi0JCQltX3BGaWVsZEV2ZW50UGF0aCA9IE5VTEw7DQotDQotCQlpZiAocExhc3QpDQotCQkJcExhc3QtPnBOZXh0ID0gTlVMTDsNCi0JfQ0KLX0NCi0NCi12b2lkIENKU19SdW50aW1lOjpSZW1vdmVFdmVudHNJbkxvb3AoQ0pTX0ZpZWxkRXZlbnQqIHBTdGFydCkNCi17DQotCUNKU19GaWVsZEV2ZW50KiBwID0gcFN0YXJ0Ow0KLQ0KLQl3aGlsZSAocCkNCi0Jew0KLQkJQ0pTX0ZpZWxkRXZlbnQqIHBPbGQgPSBwOw0KLQkJcCA9IHBPbGQtPnBOZXh0Ow0KLQ0KLQkJZGVsZXRlIHBPbGQ7DQotCX0NCi19DQotDQotdjg6OkhhbmRsZTx2ODo6Q29udGV4dD4JQ0pTX1J1bnRpbWU6Ok5ld0pTQ29udGV4dCgpDQotew0KLQlyZXR1cm4gdjg6OkxvY2FsPHY4OjpDb250ZXh0Pjo6TmV3KG1faXNvbGF0ZSwgbV9jb250ZXh0KTsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ2hhbmdlT2JqTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyKQ0KLXsNCi0JQ0ZYX1dpZGVTdHJpbmcgc1JldCA9IHN0cjsNCi0Jc1JldC5SZXBsYWNlKChGWF9MUENXU1RSKUwiXyIsIChGWF9MUENXU1RSKUwiLiIpOw0KLQlyZXR1cm4gc1JldDsNCi19DQotDQotdm9pZCBDSlNfUnVudGltZTo6R2V0T2JqZWN0TmFtZXMoQ0ZYX1dpZGVTdHJpbmdBcnJheSYgYXJyYXkpDQotew0KLQlhcnJheS5SZW1vdmVBbGwoKTsNCi0NCi0JYXJyYXkuQWRkKENKU19Cb3JkZXI6Om1fcENsYXNzTmFtZSk7DQotCWFycmF5LkFkZChDSlNfRGlzcGxheTo6bV9wQ2xhc3NOYW1lKTsNCi0JYXJyYXkuQWRkKENKU19Gb250OjptX3BDbGFzc05hbWUpOw0KLQlhcnJheS5BZGQoQ0pTX0hpZ2hsaWdodDo6bV9wQ2xhc3NOYW1lKTsNCi0JYXJyYXkuQWRkKENKU19Qb3NpdGlvbjo6bV9wQ2xhc3NOYW1lKTsNCi0JYXJyYXkuQWRkKENKU19TY2FsZUhvdzo6bV9wQ2xhc3NOYW1lKTsNCi0JYXJyYXkuQWRkKENKU19TY2FsZVdoZW46Om1fcENsYXNzTmFtZSk7DQotCWFycmF5LkFkZChDSlNfU3R5bGU6Om1fcENsYXNzTmFtZSk7DQotCWFycmF5LkFkZChDSlNfWm9vbXR5cGU6Om1fcENsYXNzTmFtZSk7DQotDQotCWFycmF5LkFkZChDSlNfQXBwOjptX3BDbGFzc05hbWUpOw0KLQlhcnJheS5BZGQoKEZYX0xQQ1dTVFIpInRoaXMiKTsgDQotCWFycmF5LkFkZChDSlNfRXZlbnQ6Om1fcENsYXNzTmFtZSk7CQ0KLQ0KLQlhcnJheS5BZGQoQ0pTX0dsb2JhbDo6bV9wQ2xhc3NOYW1lKTsJDQotCWFycmF5LkFkZChDSlNfVXRpbDo6bV9wQ2xhc3NOYW1lKTsNCi19DQotDQotdm9pZCBDSlNfUnVudGltZTo6R2V0T2JqZWN0Q29uc3RzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzT2JqTmFtZSwgQ0ZYX1dpZGVTdHJpbmdBcnJheSYgYXJyYXkpDQotew0KLQlKU0NvbnN0U3BlYyogcENvbnN0cyA9IE5VTEw7DQotCWludCBuU2l6ZSA9IDA7DQotDQotCWlmIChzT2JqTmFtZSA9PSBDSlNfQm9yZGVyOjptX3BDbGFzc05hbWUpDQotCQlDSlNfQm9yZGVyOjpHZXRDb25zdHMocENvbnN0cywgblNpemUpOw0KLQllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfRGlzcGxheTo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX0Rpc3BsYXk6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7DQotCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19Gb250OjptX3BDbGFzc05hbWUpDQotCQlDSlNfRm9udDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsNCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0hpZ2hsaWdodDo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX0hpZ2hsaWdodDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsNCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX1Bvc2l0aW9uOjptX3BDbGFzc05hbWUpDQotCQlDSlNfUG9zaXRpb246OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7DQotCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19TY2FsZUhvdzo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX1NjYWxlSG93OjpHZXRDb25zdHMocENvbnN0cywgblNpemUpOw0KLQllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfU2NhbGVXaGVuOjptX3BDbGFzc05hbWUpDQotCQlDSlNfU2NhbGVXaGVuOjpHZXRDb25zdHMocENvbnN0cywgblNpemUpOw0KLQllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfU3R5bGU6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19TdHlsZTo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsNCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX1pvb210eXBlOjptX3BDbGFzc05hbWUpDQotCQlDSlNfWm9vbXR5cGU6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7DQotDQotCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19BcHA6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19BcHA6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7DQotCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19Db2xvcjo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX0NvbG9yOjpHZXRDb25zdHMocENvbnN0cywgblNpemUpOwkNCi0NCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gTCJ0aGlzIikgDQotCXsNCi0JCWlmIChHZXRSZWFkZXJEb2N1bWVudCgpKQ0KLQkJCUNKU19Eb2N1bWVudDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsNCi0JCWVsc2UgDQotCQkJQ0pTX0FwcDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsNCi0JfQ0KLQ0KLQlpZiAoc09iak5hbWUgPT0gQ0pTX0V2ZW50OjptX3BDbGFzc05hbWUpDQotCQlDSlNfRXZlbnQ6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7CQ0KLQllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfRmllbGQ6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19GaWVsZDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsJDQotCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19HbG9iYWw6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19HbG9iYWw6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7CQ0KLQllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfVXRpbDo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX1V0aWw6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7DQotDQotCWZvciAoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQ0KLQkJYXJyYXkuQWRkKHBDb25zdHNbaV0ucE5hbWUpOw0KLX0NCi0NCi12b2lkIENKU19SdW50aW1lOjpHZXRPYmplY3RQcm9wcyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KQ0KLXsNCi0JSlNQcm9wZXJ0eVNwZWMqIHBQcm9wZXJ0aWVzID0gTlVMTDsNCi0JaW50IG5TaXplID0gMDsNCi0NCi0gCWlmIChzT2JqTmFtZSA9PSBDSlNfQXBwOjptX3BDbGFzc05hbWUpDQotCQlDSlNfQXBwOjpHZXRQcm9wZXJ0aWVzKHBQcm9wZXJ0aWVzLCBuU2l6ZSk7DQotCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19Db2xvcjo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX0NvbG9yOjpHZXRQcm9wZXJ0aWVzKHBQcm9wZXJ0aWVzLCBuU2l6ZSk7IA0KLQllbHNlIGlmIChzT2JqTmFtZSA9PSBMInRoaXMiKQ0KLQl7DQotCQlpZiAoR2V0UmVhZGVyRG9jdW1lbnQoKSkNCi0JCQlDSlNfRG9jdW1lbnQ6OkdldFByb3BlcnRpZXMocFByb3BlcnRpZXMsIG5TaXplKTsNCi0JCWVsc2UJDQotCQkJQ0pTX0FwcDo6R2V0UHJvcGVydGllcyhwUHJvcGVydGllcywgblNpemUpOw0KLQl9DQotCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19FdmVudDo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX0V2ZW50OjpHZXRQcm9wZXJ0aWVzKHBQcm9wZXJ0aWVzLCBuU2l6ZSk7CQ0KLQllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfRmllbGQ6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19GaWVsZDo6R2V0UHJvcGVydGllcyhwUHJvcGVydGllcywgblNpemUpOwkNCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0dsb2JhbDo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX0dsb2JhbDo6R2V0UHJvcGVydGllcyhwUHJvcGVydGllcywgblNpemUpOwkNCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX1V0aWw6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19VdGlsOjpHZXRQcm9wZXJ0aWVzKHBQcm9wZXJ0aWVzLCBuU2l6ZSk7DQotDQotCWZvciAoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQ0KLQkJYXJyYXkuQWRkKHBQcm9wZXJ0aWVzW2ldLnBOYW1lKTsNCi19DQotDQotdm9pZCBDSlNfUnVudGltZTo6R2V0T2JqZWN0TWV0aG9kcyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KQ0KLXsNCi0JSlNNZXRob2RTcGVjKiBwTWV0aG9kcyA9IE5VTEw7DQotCWludCBuU2l6ZSA9IDA7DQotDQotIAkgaWYgKHNPYmpOYW1lID09IENKU19BcHA6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19BcHA6OkdldE1ldGhvZHMocE1ldGhvZHMsIG5TaXplKTsNCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0NvbG9yOjptX3BDbGFzc05hbWUpDQotCQlDSlNfQ29sb3I6OkdldE1ldGhvZHMocE1ldGhvZHMsIG5TaXplKTsJDQotCWVsc2UgaWYgKHNPYmpOYW1lID09IEwidGhpcyIpIA0KLQl7DQotCQlpZiAoR2V0UmVhZGVyRG9jdW1lbnQoKSkNCi0JCQlDSlNfRG9jdW1lbnQ6OkdldE1ldGhvZHMocE1ldGhvZHMsIG5TaXplKTsNCi0JCWVsc2UJDQotCQkJQ0pTX0FwcDo6R2V0TWV0aG9kcyhwTWV0aG9kcywgblNpemUpOw0KLQl9DQotCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19FdmVudDo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX0V2ZW50OjpHZXRNZXRob2RzKHBNZXRob2RzLCBuU2l6ZSk7CQ0KLQllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfRmllbGQ6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19GaWVsZDo6R2V0TWV0aG9kcyhwTWV0aG9kcywgblNpemUpOwkNCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0dsb2JhbDo6bV9wQ2xhc3NOYW1lKQ0KLQkJQ0pTX0dsb2JhbDo6R2V0TWV0aG9kcyhwTWV0aG9kcywgblNpemUpOwkNCi0JZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX1V0aWw6Om1fcENsYXNzTmFtZSkNCi0JCUNKU19VdGlsOjpHZXRNZXRob2RzKHBNZXRob2RzLCBuU2l6ZSk7DQotDQotCWZvciAoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQ0KLQkJYXJyYXkuQWRkKHBNZXRob2RzW2ldLnBOYW1lKTsNCi19DQotDQotRlhfQk9PTCAgQ0pTX1J1bnRpbWU6OklzRW50ZXJlZCgpDQotew0KLQlyZXR1cm4gdjg6Oklzb2xhdGU6OkdldEN1cnJlbnQoKSA9PSBtX2lzb2xhdGU7DQotfQ0KLXZvaWQJQ0pTX1J1bnRpbWU6OkV4aXQoKQ0KLXsNCi0JaWYobV9pc29sYXRlKSBtX2lzb2xhdGUtPkV4aXQoKTsNCi19DQotdm9pZAlDSlNfUnVudGltZTo6RW50ZXIoKQ0KLXsNCi0JaWYobV9pc29sYXRlKSBtX2lzb2xhdGUtPkVudGVyKCk7DQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvRG9jdW1lbnQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvYXBwLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2NvbG9yLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0NvbnN0cy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9Eb2N1bWVudC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9ldmVudC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JY29uLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvcmVwb3J0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L3V0aWwuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfR2xvYmFsRGF0YS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9nbG9iYWwuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvY29uc29sZS5oIgorCitDSlNfUnVudGltZUZhY3Rvcnk6On5DSlNfUnVudGltZUZhY3RvcnkoKQoreworfQorCitJRlhKU19SdW50aW1lKgkJCQkJQ0pTX1J1bnRpbWVGYWN0b3J5OjpOZXdKU1J1bnRpbWUoQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCkKK3sKKwlpZiAoIW1fYkluaXQpCisJeworCQlKU19Jbml0aWFsKCk7CisJCQorCQltX2JJbml0ID0gVFJVRTsKKwl9CisJcmV0dXJuIG5ldyBDSlNfUnVudGltZShwQXBwKTsKK30KK3ZvaWQJCQkJCQkJQ0pTX1J1bnRpbWVGYWN0b3J5OjpBZGRSZWYoKQoreworCS8vdG8gZG8uU2hvdWxkIGJlIGltcGxlbWVudGVkIGFzIGF0b20gbWFuaXB1bGF0aW9uLgorCW1fblJlZisrOworfQordm9pZAkJCQkJCQlDSlNfUnVudGltZUZhY3Rvcnk6OlJlbGVhc2UoKQorewkKKwlpZihtX2JJbml0KQorCXsKKwkJLy90byBkby5TaG91bGQgYmUgaW1wbGVtZW50ZWQgYXMgYXRvbSBtYW5pcHVsYXRpb24uCisJCWlmICgtLW1fblJlZiA9PSAwKQorCQl7CisJCQlKU19SZWxlYXNlKCk7CisJCQlSZWxlYXNlR2xvYmFsRGF0YSgpOworCQkJbV9iSW5pdCA9IEZBTFNFOworCQl9CisJfQorfQorCit2b2lkCQkJCQkJCUNKU19SdW50aW1lRmFjdG9yeTo6RGVsZXRlSlNSdW50aW1lKElGWEpTX1J1bnRpbWUqIHBSdW50aW1lKQoreworCWlmKHBSdW50aW1lKQorCQlkZWxldGUgKENKU19SdW50aW1lKilwUnVudGltZTsKK30KKworQ0pTX0dsb2JhbERhdGEqCUNKU19SdW50aW1lRmFjdG9yeTo6TmV3R2xvYmFsRGF0YShDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwKQoreworCWlmIChtX3BHbG9iYWxEYXRhKQorCXsKKwkJbV9uR2xvYmFsRGF0YUNvdW50Kys7CisJCXJldHVybiBtX3BHbG9iYWxEYXRhOworCX0KKwllbHNlCisJeworCQltX25HbG9iYWxEYXRhQ291bnQgPSAxOworCQltX3BHbG9iYWxEYXRhID0gbmV3IENKU19HbG9iYWxEYXRhKHBBcHApOworCQlyZXR1cm4gbV9wR2xvYmFsRGF0YTsKKwl9Cit9CisKK3ZvaWQgQ0pTX1J1bnRpbWVGYWN0b3J5OjpSZWxlYXNlR2xvYmFsRGF0YSgpCit7CisJbV9uR2xvYmFsRGF0YUNvdW50LS07CisJCisJaWYgKG1fbkdsb2JhbERhdGFDb3VudCA8PSAwKQorCXsKKyAJCWRlbGV0ZSBtX3BHbG9iYWxEYXRhOworIAkJbV9wR2xvYmFsRGF0YSA9IE5VTEw7CisJfQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX1J1bnRpbWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NKU19SdW50aW1lOjpDSlNfUnVudGltZShDUERGRG9jX0Vudmlyb25tZW50ICogcEFwcCkgOiAKKwltX3BBcHAocEFwcCksCisJbV9wRG9jdW1lbnQoTlVMTCksCisJbV9wRmllbGRFdmVudFBhdGgoTlVMTCksCisJbV9iQmxvY2tpbmcoRkFMU0UpLAorCW1fYlJlZ2lzdGVyZWQoRkFMU0UpCit7CisJbV9pc29sYXRlID0gdjg6Oklzb2xhdGU6Ok5ldygpOworCS8vbV9pc29sYXRlLT5FbnRlcigpOworCisJSW5pdEpTT2JqZWN0cygpOworCisJQ0pTX0NvbnRleHQgKiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopTmV3Q29udGV4dCgpOworCUpTX0luaXRpYWxSdW50aW1lKCp0aGlzLCB0aGlzLCBwQ29udGV4dCwgbV9jb250ZXh0KTsKKwlSZWxlYXNlQ29udGV4dChwQ29udGV4dCk7Cit9CisKK0NKU19SdW50aW1lOjp+Q0pTX1J1bnRpbWUoKQoreworCWZvciAoaW50IGk9MCwgc3o9bV9Db250ZXh0QXJyYXkuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCWRlbGV0ZSBtX0NvbnRleHRBcnJheS5HZXRBdChpKTsKKworCW1fQ29udGV4dEFycmF5LlJlbW92ZUFsbCgpOworCisJSlNfUmVsZWFzZVJ1bnRpbWUoKnRoaXMsIG1fY29udGV4dCk7CisKKwlSZW1vdmVFdmVudHNJbkxvb3AobV9wRmllbGRFdmVudFBhdGgpOworCisJbV9wQXBwID0gTlVMTDsKKwltX3BEb2N1bWVudCA9IE5VTEw7CisJbV9wRmllbGRFdmVudFBhdGggPSBOVUxMOworCW1fY29udGV4dC5SZXNldCgpOworCisJLy9tX2lzb2xhdGUtPkV4aXQoKTsKKwltX2lzb2xhdGUtPkRpc3Bvc2UoKTsKK30KKworRlhfQk9PTCBDSlNfUnVudGltZTo6SW5pdEpTT2JqZWN0cygpCit7CisJdjg6Oklzb2xhdGU6OlNjb3BlIGlzb2xhdGVfc2NvcGUoR2V0SXNvbGF0ZSgpKTsKKwl2ODo6SGFuZGxlU2NvcGUgaGFuZGxlX3Njb3BlKEdldElzb2xhdGUoKSk7CisJdjg6OkhhbmRsZTx2ODo6Q29udGV4dD4gY29udGV4dCA9IHY4OjpDb250ZXh0OjpOZXcoR2V0SXNvbGF0ZSgpKTsKKwl2ODo6Q29udGV4dDo6U2NvcGUgY29udGV4dF9zY29wZShjb250ZXh0KTsKKwkvLzAgLSA4CisJaWYgKENKU19Cb3JkZXI6OkluaXQoKnRoaXMsIEpTX1NUQVRJQykgPCAwKSByZXR1cm4gRkFMU0U7CisJaWYgKENKU19EaXNwbGF5OjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOworCWlmIChDSlNfRm9udDo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsKKwlpZiAoQ0pTX0hpZ2hsaWdodDo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsKKwlpZiAoQ0pTX1Bvc2l0aW9uOjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOworCWlmIChDSlNfU2NhbGVIb3c6OkluaXQoKnRoaXMsIEpTX1NUQVRJQykgPCAwKSByZXR1cm4gRkFMU0U7CisJaWYgKENKU19TY2FsZVdoZW46OkluaXQoKnRoaXMsIEpTX1NUQVRJQykgPCAwKSByZXR1cm4gRkFMU0U7CisJaWYgKENKU19TdHlsZTo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsJCisJaWYgKENKU19ab29tdHlwZTo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsJCisKKwkvLzkgLSAxMQorCWlmIChDSlNfQXBwOjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOworCWlmIChDSlNfQ29sb3I6OkluaXQoKnRoaXMsIEpTX1NUQVRJQykgPCAwKSByZXR1cm4gRkFMU0U7ICAgCisJaWYgKENKU19Db25zb2xlOjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOworCisJLy8xMiAtIDE0CisJaWYgKENKU19Eb2N1bWVudDo6SW5pdCgqdGhpcywgSlNfRFlOQU1JQykgPCAwKSByZXR1cm4gRkFMU0U7ICAKKwlpZiAoQ0pTX0V2ZW50OjpJbml0KCp0aGlzLCBKU19TVEFUSUMpIDwgMCkgcmV0dXJuIEZBTFNFOwkJCisJaWYgKENKU19GaWVsZDo6SW5pdCgqdGhpcywgSlNfRFlOQU1JQykgPCAwKSByZXR1cm4gRkFMU0U7ICAgIAorCisJLy8xNSAtIDE3CisJaWYgKENKU19HbG9iYWw6OkluaXQoKnRoaXMsIEpTX1NUQVRJQykgPCAwKSByZXR1cm4gRkFMU0U7CQkKKwlpZiAoQ0pTX0ljb246OkluaXQoKnRoaXMsIEpTX0RZTkFNSUMpIDwgMCkgcmV0dXJuIEZBTFNFOworCWlmIChDSlNfVXRpbDo6SW5pdCgqdGhpcywgSlNfU1RBVElDKSA8IDApIHJldHVybiBGQUxTRTsKKworCWlmIChDSlNfUHVibGljTWV0aG9kczo6SW5pdCgqdGhpcykgPCAwKSByZXR1cm4gRkFMU0U7CisJaWYgKENKU19HbG9iYWxDb25zdHM6OkluaXQoKnRoaXMpIDwgMCkgcmV0dXJuIEZBTFNFOworCWlmIChDSlNfR2xvYmFsQXJyYXlzOjpJbml0KCp0aGlzKSA8IDApIHJldHVybiBGQUxTRTsKKworCWlmIChDSlNfVGltZXJPYmo6OkluaXQoKnRoaXMsIEpTX0RZTkFNSUMpIDwgMCkgcmV0dXJuIEZBTFNFOworCWlmIChDSlNfUHJpbnRQYXJhbXNPYmo6OkluaXQoKnRoaXMsIEpTX0RZTkFNSUMpIDwwKSByZXR1cm4gRkFMU0U7CisKKwlyZXR1cm4gVFJVRTsKK30KKworSUZYSlNfQ29udGV4dCogQ0pTX1J1bnRpbWU6Ok5ld0NvbnRleHQoKQoreworCUNKU19Db250ZXh0ICogcCA9IG5ldyBDSlNfQ29udGV4dCh0aGlzKTsKKwltX0NvbnRleHRBcnJheS5BZGQocCk7CisJcmV0dXJuIHA7Cit9CisKK3ZvaWQgQ0pTX1J1bnRpbWU6OlJlbGVhc2VDb250ZXh0KElGWEpTX0NvbnRleHQgKiBwQ29udGV4dCkKK3sKKwlDSlNfQ29udGV4dCogcEpTQ29udGV4dCA9IChDSlNfQ29udGV4dCopcENvbnRleHQ7CisKKwlmb3IgKGludCBpPTAsIHN6PW1fQ29udGV4dEFycmF5LkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJaWYgKHBKU0NvbnRleHQgPT0gbV9Db250ZXh0QXJyYXkuR2V0QXQoaSkpCisJCXsKKwkJCWRlbGV0ZSBwSlNDb250ZXh0OworCQkJbV9Db250ZXh0QXJyYXkuUmVtb3ZlQXQoaSk7CisJCQlicmVhazsKKwkJfQorCX0KK30KKworSUZYSlNfQ29udGV4dCoJQ0pTX1J1bnRpbWU6OkdldEN1cnJlbnRDb250ZXh0KCkKK3sKKwlpZighbV9Db250ZXh0QXJyYXkuR2V0U2l6ZSgpKQorCQlyZXR1cm4gTlVMTDsKKwlyZXR1cm4gbV9Db250ZXh0QXJyYXkuR2V0QXQobV9Db250ZXh0QXJyYXkuR2V0U2l6ZSgpLTEpOworfQorCit2b2lkIENKU19SdW50aW1lOjpTZXRSZWFkZXJEb2N1bWVudChDUERGU0RLX0RvY3VtZW50KiBwUmVhZGVyRG9jKQoreworCWlmIChtX3BEb2N1bWVudCAhPSBwUmVhZGVyRG9jKQorCXsKKwkJdjg6Oklzb2xhdGU6OlNjb3BlIGlzb2xhdGVfc2NvcGUobV9pc29sYXRlKTsKKwkJdjg6OkhhbmRsZVNjb3BlIGhhbmRsZV9zY29wZShtX2lzb2xhdGUpOworCQl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPXY4OjpMb2NhbDx2ODo6Q29udGV4dD46Ok5ldyhtX2lzb2xhdGUsIG1fY29udGV4dCk7CisJCXY4OjpDb250ZXh0OjpTY29wZSBjb250ZXh0X3Njb3BlKGNvbnRleHQpOworCisJCW1fcERvY3VtZW50ID0gcFJlYWRlckRvYzsKKworCQlpZiAocFJlYWRlckRvYykKKwkJeworCQkJSlNPYmplY3QgcFRoaXMgPSBKU19HZXRUaGlzT2JqKCp0aGlzKTsKKwkJCWlmKCFwVGhpcy5Jc0VtcHR5KCkpCisJCQl7CisJCQkJaWYgKEpTX0dldE9iakRlZm5JRChwVGhpcykgPT0gSlNfR2V0T2JqRGVmbklEKCp0aGlzLCBMIkRvY3VtZW50IikpCisJCQkJeworCQkJCQlpZiAoQ0pTX0RvY3VtZW50KiBwSlNEb2N1bWVudCA9IChDSlNfRG9jdW1lbnQqKUpTX0dldFByaXZhdGUocFRoaXMpKQorCQkJCQl7CisJCQkJCQlpZiAoRG9jdW1lbnQgKiBwRG9jdW1lbnQgPSAoRG9jdW1lbnQqKXBKU0RvY3VtZW50LT5HZXRFbWJlZE9iamVjdCgpKQorCQkJCQkJCXBEb2N1bWVudC0+QXR0YWNoRG9jKHBSZWFkZXJEb2MpOworCQkJCQl9CisJCQkJfQorCQkJfQorCQkJSlNfU2V0VGhpc09iaigqdGhpcywgSlNfR2V0T2JqRGVmbklEKCp0aGlzLCBMIkRvY3VtZW50IikpOworCQl9CisJCWVsc2UKKwkJeworCQkJSlNfU2V0VGhpc09iaigqdGhpcywgSlNfR2V0T2JqRGVmbklEKCp0aGlzLCBMImFwcCIpKTsKKwkJfQorCX0KK30KKworRlhfQk9PTAlDSlNfUnVudGltZTo6QWRkRXZlbnRUb0xvb3AoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUYXJnZXROYW1lLCBKU19FVkVOVF9UIGVFdmVudFR5cGUpCit7CisJaWYgKG1fcEZpZWxkRXZlbnRQYXRoID09IE5VTEwpCisJeworCQltX3BGaWVsZEV2ZW50UGF0aCA9IG5ldyBDSlNfRmllbGRFdmVudDsKKwkJbV9wRmllbGRFdmVudFBhdGgtPnNUYXJnZXROYW1lID0gc1RhcmdldE5hbWU7CisJCW1fcEZpZWxkRXZlbnRQYXRoLT5lRXZlbnRUeXBlID0gZUV2ZW50VHlwZTsKKwkJbV9wRmllbGRFdmVudFBhdGgtPnBOZXh0ID0gTlVMTDsKKworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwkvL3RvIHNlYXJjaAorCUNKU19GaWVsZEV2ZW50KiBwID0gbV9wRmllbGRFdmVudFBhdGg7CisJQ0pTX0ZpZWxkRXZlbnQqIHBMYXN0ID0gbV9wRmllbGRFdmVudFBhdGg7CisJd2hpbGUgKHApCisJeworCQlpZiAocC0+ZUV2ZW50VHlwZSA9PSBlRXZlbnRUeXBlICYmIHAtPnNUYXJnZXROYW1lID09IHNUYXJnZXROYW1lKQorCQkJcmV0dXJuIEZBTFNFOworCisJCXBMYXN0ID0gcDsKKwkJcCA9IHAtPnBOZXh0OworCX0KKworCS8vdG8gYWRkCisJQ0pTX0ZpZWxkRXZlbnQqIHBOZXcgPSBuZXcgQ0pTX0ZpZWxkRXZlbnQ7CisJcE5ldy0+c1RhcmdldE5hbWUgPSBzVGFyZ2V0TmFtZTsKKwlwTmV3LT5lRXZlbnRUeXBlID0gZUV2ZW50VHlwZTsKKwlwTmV3LT5wTmV4dCA9IE5VTEw7CisKKwlwTGFzdC0+cE5leHQgPSBwTmV3OworCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ0pTX1J1bnRpbWU6OlJlbW92ZUV2ZW50SW5Mb29wKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGFyZ2V0TmFtZSwgSlNfRVZFTlRfVCBlRXZlbnRUeXBlKQoreworCUZYX0JPT0wgYkZpbmQgPSBGQUxTRTsKKworCUNKU19GaWVsZEV2ZW50KiBwID0gbV9wRmllbGRFdmVudFBhdGg7CisJQ0pTX0ZpZWxkRXZlbnQqIHBMYXN0ID0gTlVMTDsKKwl3aGlsZSAocCkKKwl7CisJCWlmIChwLT5lRXZlbnRUeXBlID09IGVFdmVudFR5cGUgJiYgcC0+c1RhcmdldE5hbWUgPT0gc1RhcmdldE5hbWUpCisJCXsKKwkJCWJGaW5kID0gVFJVRTsKKwkJCWJyZWFrOworCQl9CisKKwkJcExhc3QgPSBwOworCQlwID0gcC0+cE5leHQ7CisJfQorCisJaWYgKGJGaW5kKQorCXsKKwkJUmVtb3ZlRXZlbnRzSW5Mb29wKHApOworCisJCWlmIChwID09IG1fcEZpZWxkRXZlbnRQYXRoKQorCQkJbV9wRmllbGRFdmVudFBhdGggPSBOVUxMOworCisJCWlmIChwTGFzdCkKKwkJCXBMYXN0LT5wTmV4dCA9IE5VTEw7CisJfQorfQorCit2b2lkIENKU19SdW50aW1lOjpSZW1vdmVFdmVudHNJbkxvb3AoQ0pTX0ZpZWxkRXZlbnQqIHBTdGFydCkKK3sKKwlDSlNfRmllbGRFdmVudCogcCA9IHBTdGFydDsKKworCXdoaWxlIChwKQorCXsKKwkJQ0pTX0ZpZWxkRXZlbnQqIHBPbGQgPSBwOworCQlwID0gcE9sZC0+cE5leHQ7CisKKwkJZGVsZXRlIHBPbGQ7CisJfQorfQorCit2ODo6SGFuZGxlPHY4OjpDb250ZXh0PglDSlNfUnVudGltZTo6TmV3SlNDb250ZXh0KCkKK3sKKwlyZXR1cm4gdjg6OkxvY2FsPHY4OjpDb250ZXh0Pjo6TmV3KG1faXNvbGF0ZSwgbV9jb250ZXh0KTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ2hhbmdlT2JqTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyKQoreworCUNGWF9XaWRlU3RyaW5nIHNSZXQgPSBzdHI7CisJc1JldC5SZXBsYWNlKChGWF9MUENXU1RSKUwiXyIsIChGWF9MUENXU1RSKUwiLiIpOworCXJldHVybiBzUmV0OworfQorCit2b2lkIENKU19SdW50aW1lOjpHZXRPYmplY3ROYW1lcyhDRlhfV2lkZVN0cmluZ0FycmF5JiBhcnJheSkKK3sKKwlhcnJheS5SZW1vdmVBbGwoKTsKKworCWFycmF5LkFkZChDSlNfQm9yZGVyOjptX3BDbGFzc05hbWUpOworCWFycmF5LkFkZChDSlNfRGlzcGxheTo6bV9wQ2xhc3NOYW1lKTsKKwlhcnJheS5BZGQoQ0pTX0ZvbnQ6Om1fcENsYXNzTmFtZSk7CisJYXJyYXkuQWRkKENKU19IaWdobGlnaHQ6Om1fcENsYXNzTmFtZSk7CisJYXJyYXkuQWRkKENKU19Qb3NpdGlvbjo6bV9wQ2xhc3NOYW1lKTsKKwlhcnJheS5BZGQoQ0pTX1NjYWxlSG93OjptX3BDbGFzc05hbWUpOworCWFycmF5LkFkZChDSlNfU2NhbGVXaGVuOjptX3BDbGFzc05hbWUpOworCWFycmF5LkFkZChDSlNfU3R5bGU6Om1fcENsYXNzTmFtZSk7CisJYXJyYXkuQWRkKENKU19ab29tdHlwZTo6bV9wQ2xhc3NOYW1lKTsKKworCWFycmF5LkFkZChDSlNfQXBwOjptX3BDbGFzc05hbWUpOworCWFycmF5LkFkZCgoRlhfTFBDV1NUUikidGhpcyIpOyAKKwlhcnJheS5BZGQoQ0pTX0V2ZW50OjptX3BDbGFzc05hbWUpOwkKKworCWFycmF5LkFkZChDSlNfR2xvYmFsOjptX3BDbGFzc05hbWUpOwkKKwlhcnJheS5BZGQoQ0pTX1V0aWw6Om1fcENsYXNzTmFtZSk7Cit9CisKK3ZvaWQgQ0pTX1J1bnRpbWU6OkdldE9iamVjdENvbnN0cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KQoreworCUpTQ29uc3RTcGVjKiBwQ29uc3RzID0gTlVMTDsKKwlpbnQgblNpemUgPSAwOworCisJaWYgKHNPYmpOYW1lID09IENKU19Cb3JkZXI6Om1fcENsYXNzTmFtZSkKKwkJQ0pTX0JvcmRlcjo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfRGlzcGxheTo6bV9wQ2xhc3NOYW1lKQorCQlDSlNfRGlzcGxheTo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfRm9udDo6bV9wQ2xhc3NOYW1lKQorCQlDSlNfRm9udDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfSGlnaGxpZ2h0OjptX3BDbGFzc05hbWUpCisJCUNKU19IaWdobGlnaHQ6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7CisJZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX1Bvc2l0aW9uOjptX3BDbGFzc05hbWUpCisJCUNKU19Qb3NpdGlvbjo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfU2NhbGVIb3c6Om1fcENsYXNzTmFtZSkKKwkJQ0pTX1NjYWxlSG93OjpHZXRDb25zdHMocENvbnN0cywgblNpemUpOworCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19TY2FsZVdoZW46Om1fcENsYXNzTmFtZSkKKwkJQ0pTX1NjYWxlV2hlbjo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfU3R5bGU6Om1fcENsYXNzTmFtZSkKKwkJQ0pTX1N0eWxlOjpHZXRDb25zdHMocENvbnN0cywgblNpemUpOworCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19ab29tdHlwZTo6bV9wQ2xhc3NOYW1lKQorCQlDSlNfWm9vbXR5cGU6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7CisKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfQXBwOjptX3BDbGFzc05hbWUpCisJCUNKU19BcHA6OkdldENvbnN0cyhwQ29uc3RzLCBuU2l6ZSk7CisJZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0NvbG9yOjptX3BDbGFzc05hbWUpCisJCUNKU19Db2xvcjo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsJCisKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBMInRoaXMiKSAKKwl7CisJCWlmIChHZXRSZWFkZXJEb2N1bWVudCgpKQorCQkJQ0pTX0RvY3VtZW50OjpHZXRDb25zdHMocENvbnN0cywgblNpemUpOworCQllbHNlIAorCQkJQ0pTX0FwcDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsKKwl9CisKKwlpZiAoc09iak5hbWUgPT0gQ0pTX0V2ZW50OjptX3BDbGFzc05hbWUpCisJCUNKU19FdmVudDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsJCisJZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0ZpZWxkOjptX3BDbGFzc05hbWUpCisJCUNKU19GaWVsZDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsJCisJZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0dsb2JhbDo6bV9wQ2xhc3NOYW1lKQorCQlDSlNfR2xvYmFsOjpHZXRDb25zdHMocENvbnN0cywgblNpemUpOwkKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfVXRpbDo6bV9wQ2xhc3NOYW1lKQorCQlDSlNfVXRpbDo6R2V0Q29uc3RzKHBDb25zdHMsIG5TaXplKTsKKworCWZvciAoaW50IGk9MDsgaTxuU2l6ZTsgaSsrKQorCQlhcnJheS5BZGQocENvbnN0c1tpXS5wTmFtZSk7Cit9CisKK3ZvaWQgQ0pTX1J1bnRpbWU6OkdldE9iamVjdFByb3BzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzT2JqTmFtZSwgQ0ZYX1dpZGVTdHJpbmdBcnJheSYgYXJyYXkpCit7CisJSlNQcm9wZXJ0eVNwZWMqIHBQcm9wZXJ0aWVzID0gTlVMTDsKKwlpbnQgblNpemUgPSAwOworCisgCWlmIChzT2JqTmFtZSA9PSBDSlNfQXBwOjptX3BDbGFzc05hbWUpCisJCUNKU19BcHA6OkdldFByb3BlcnRpZXMocFByb3BlcnRpZXMsIG5TaXplKTsKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfQ29sb3I6Om1fcENsYXNzTmFtZSkKKwkJQ0pTX0NvbG9yOjpHZXRQcm9wZXJ0aWVzKHBQcm9wZXJ0aWVzLCBuU2l6ZSk7IAorCWVsc2UgaWYgKHNPYmpOYW1lID09IEwidGhpcyIpCisJeworCQlpZiAoR2V0UmVhZGVyRG9jdW1lbnQoKSkKKwkJCUNKU19Eb2N1bWVudDo6R2V0UHJvcGVydGllcyhwUHJvcGVydGllcywgblNpemUpOworCQllbHNlCQorCQkJQ0pTX0FwcDo6R2V0UHJvcGVydGllcyhwUHJvcGVydGllcywgblNpemUpOworCX0KKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfRXZlbnQ6Om1fcENsYXNzTmFtZSkKKwkJQ0pTX0V2ZW50OjpHZXRQcm9wZXJ0aWVzKHBQcm9wZXJ0aWVzLCBuU2l6ZSk7CQorCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19GaWVsZDo6bV9wQ2xhc3NOYW1lKQorCQlDSlNfRmllbGQ6OkdldFByb3BlcnRpZXMocFByb3BlcnRpZXMsIG5TaXplKTsJCisJZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0dsb2JhbDo6bV9wQ2xhc3NOYW1lKQorCQlDSlNfR2xvYmFsOjpHZXRQcm9wZXJ0aWVzKHBQcm9wZXJ0aWVzLCBuU2l6ZSk7CQorCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19VdGlsOjptX3BDbGFzc05hbWUpCisJCUNKU19VdGlsOjpHZXRQcm9wZXJ0aWVzKHBQcm9wZXJ0aWVzLCBuU2l6ZSk7CisKKwlmb3IgKGludCBpPTA7IGk8blNpemU7IGkrKykKKwkJYXJyYXkuQWRkKHBQcm9wZXJ0aWVzW2ldLnBOYW1lKTsKK30KKwordm9pZCBDSlNfUnVudGltZTo6R2V0T2JqZWN0TWV0aG9kcyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc09iak5hbWUsIENGWF9XaWRlU3RyaW5nQXJyYXkmIGFycmF5KQoreworCUpTTWV0aG9kU3BlYyogcE1ldGhvZHMgPSBOVUxMOworCWludCBuU2l6ZSA9IDA7CisKKyAJIGlmIChzT2JqTmFtZSA9PSBDSlNfQXBwOjptX3BDbGFzc05hbWUpCisJCUNKU19BcHA6OkdldE1ldGhvZHMocE1ldGhvZHMsIG5TaXplKTsKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfQ29sb3I6Om1fcENsYXNzTmFtZSkKKwkJQ0pTX0NvbG9yOjpHZXRNZXRob2RzKHBNZXRob2RzLCBuU2l6ZSk7CQorCWVsc2UgaWYgKHNPYmpOYW1lID09IEwidGhpcyIpIAorCXsKKwkJaWYgKEdldFJlYWRlckRvY3VtZW50KCkpCisJCQlDSlNfRG9jdW1lbnQ6OkdldE1ldGhvZHMocE1ldGhvZHMsIG5TaXplKTsKKwkJZWxzZQkKKwkJCUNKU19BcHA6OkdldE1ldGhvZHMocE1ldGhvZHMsIG5TaXplKTsKKwl9CisJZWxzZSBpZiAoc09iak5hbWUgPT0gQ0pTX0V2ZW50OjptX3BDbGFzc05hbWUpCisJCUNKU19FdmVudDo6R2V0TWV0aG9kcyhwTWV0aG9kcywgblNpemUpOwkKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfRmllbGQ6Om1fcENsYXNzTmFtZSkKKwkJQ0pTX0ZpZWxkOjpHZXRNZXRob2RzKHBNZXRob2RzLCBuU2l6ZSk7CQorCWVsc2UgaWYgKHNPYmpOYW1lID09IENKU19HbG9iYWw6Om1fcENsYXNzTmFtZSkKKwkJQ0pTX0dsb2JhbDo6R2V0TWV0aG9kcyhwTWV0aG9kcywgblNpemUpOwkKKwllbHNlIGlmIChzT2JqTmFtZSA9PSBDSlNfVXRpbDo6bV9wQ2xhc3NOYW1lKQorCQlDSlNfVXRpbDo6R2V0TWV0aG9kcyhwTWV0aG9kcywgblNpemUpOworCisJZm9yIChpbnQgaT0wOyBpPG5TaXplOyBpKyspCisJCWFycmF5LkFkZChwTWV0aG9kc1tpXS5wTmFtZSk7Cit9CisKK0ZYX0JPT0wgIENKU19SdW50aW1lOjpJc0VudGVyZWQoKQoreworCXJldHVybiB2ODo6SXNvbGF0ZTo6R2V0Q3VycmVudCgpID09IG1faXNvbGF0ZTsKK30KK3ZvaWQJQ0pTX1J1bnRpbWU6OkV4aXQoKQoreworCWlmKG1faXNvbGF0ZSkgbV9pc29sYXRlLT5FeGl0KCk7Cit9Cit2b2lkCUNKU19SdW50aW1lOjpFbnRlcigpCit7CisJaWYobV9pc29sYXRlKSBtX2lzb2xhdGUtPkVudGVyKCk7Cit9CmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L0pTX1ZhbHVlLmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSlNfVmFsdWUuY3BwCmluZGV4IDAzN2Y2MTguLjAyMTdlYTEgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSlNfVmFsdWUuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvSlNfVmFsdWUuY3BwCkBAIC0xLDY0MyArMSw2NDMgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDSlNfVmFsdWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlKSA6IG1faXNvbGF0ZShpc29sYXRlKSxtX2VUeXBlKFZUX3Vua25vd24pDQotew0KLX0NCi1DSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSxGWEpTVkFMVUVUWVBFIHQpIDptX2lzb2xhdGUoaXNvbGF0ZSksIG1fcFZhbHVlKHBWYWx1ZSkgLCBtX2VUeXBlKHQpDQotew0KLX0NCi0NCi1DSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgY29uc3QgaW50ICZpVmFsdWUpOm1faXNvbGF0ZShpc29sYXRlKQ0KLXsNCi0Jb3BlcmF0b3IgPShpVmFsdWUpOw0KLX0NCi0NCi1DSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgY29uc3QgYm9vbCAmYlZhbHVlKTptX2lzb2xhdGUoaXNvbGF0ZSkNCi17DQotCW9wZXJhdG9yID0oYlZhbHVlKTsNCi19DQotDQotQ0pTX1ZhbHVlOjpDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIGNvbnN0IGZsb2F0ICZmVmFsdWUpOm1faXNvbGF0ZShpc29sYXRlKQ0KLXsNCi0Jb3BlcmF0b3IgPShmVmFsdWUpOw0KLX0NCi0NCi1DSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgY29uc3QgZG91YmxlICZkVmFsdWUpOm1faXNvbGF0ZShpc29sYXRlKSANCi17DQotCW9wZXJhdG9yID0oZFZhbHVlKTsNCi19DQotDQotQ0pTX1ZhbHVlOjpDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIEpTRlhPYmplY3QgIHBKc09iaik6bV9pc29sYXRlKGlzb2xhdGUpIA0KLXsNCi0Jb3BlcmF0b3IgPShwSnNPYmopOw0KLX0NCi0NCi1DSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgQ0pTX09iamVjdCAqIHBKc09iaik6bV9pc29sYXRlKGlzb2xhdGUpIA0KLXsNCi0Jb3BlcmF0b3IgPShwSnNPYmopOw0KLX0NCi0NCi1DSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgRlhfTFBDV1NUUiBwV3N0cik6bV9pc29sYXRlKGlzb2xhdGUpIA0KLXsNCi0Jb3BlcmF0b3IgPShwV3N0cik7DQotfQ0KLQ0KLUNKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBGWF9MUENTVFIgcFN0cik6bV9pc29sYXRlKGlzb2xhdGUpIA0KLXsNCi0Jb3BlcmF0b3IgPSAocFN0cik7DQotfQ0KLQ0KLUNKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBDSlNfQXJyYXkmIGFycmF5KTptX2lzb2xhdGUoaXNvbGF0ZSkgDQotew0KLQlvcGVyYXRvciA9IChhcnJheSk7DQotfQ0KLQ0KLUNKU19WYWx1ZTo6fkNKU19WYWx1ZSgpDQotew0KLX0NCi0NCi12b2lkIENKU19WYWx1ZTo6QXR0YWNoKHY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUsRlhKU1ZBTFVFVFlQRSB0KQ0KLXsNCi0JbV9wVmFsdWUgPSBwVmFsdWU7DQotCW1fZVR5cGUgPSB0Ow0KLX0NCi0NCi12b2lkIENKU19WYWx1ZTo6QXR0YWNoKENKU19WYWx1ZSAqcFZhbHVlKQ0KLXsNCi0JaWYgKHBWYWx1ZSkNCi0JCUF0dGFjaChwVmFsdWUtPlRvSlNWYWx1ZSgpLHBWYWx1ZS0+R2V0VHlwZSgpKTsNCi19DQotDQotdm9pZCBDSlNfVmFsdWU6OkRldGFjaCgpDQotew0KLQltX3BWYWx1ZSA9IHY4OjpIYW5kbGU8djg6OlZhbHVlPigpOw0KLQltX2VUeXBlID0gVlRfdW5rbm93bjsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNKU19WYWx1ZTo6b3BlcmF0b3IgaW50KCkgY29uc3QNCi17DQotDQotCXJldHVybiBKU19Ub0ludDMyKG1fcFZhbHVlKTsNCi0NCi19DQotDQotQ0pTX1ZhbHVlOjpvcGVyYXRvciBib29sKCkgY29uc3QNCi17DQotDQotCXJldHVybiBKU19Ub0Jvb2xlYW4obV9wVmFsdWUpOw0KLQkNCi19DQotDQotQ0pTX1ZhbHVlOjpvcGVyYXRvciBkb3VibGUoKSBjb25zdA0KLXsNCi0NCi0JcmV0dXJuIEpTX1RvTnVtYmVyKG1fcFZhbHVlKTsNCi0JDQotfQ0KLQ0KLUNKU19WYWx1ZTo6b3BlcmF0b3IgZmxvYXQoKSBjb25zdA0KLXsNCi0NCi0JcmV0dXJuIChmbG9hdClKU19Ub051bWJlcihtX3BWYWx1ZSk7DQotDQotfQ0KLQ0KLUNKU19WYWx1ZTo6b3BlcmF0b3IgQ0pTX09iamVjdCAqKCkgY29uc3QNCi17DQotDQotCXY4OjpIYW5kbGU8djg6Ok9iamVjdD4JcE9iaiA9IEpTX1RvT2JqZWN0KG1fcFZhbHVlKTsNCi0JcmV0dXJuIChDSlNfT2JqZWN0KilKU19HZXRQcml2YXRlKG1faXNvbGF0ZSwgcE9iaik7DQotfQ0KLQ0KLUNKU19WYWx1ZTo6b3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6T2JqZWN0PigpIGNvbnN0DQotew0KLQlyZXR1cm4gSlNfVG9PYmplY3QobV9wVmFsdWUpOw0KLX0NCi0NCi1DSlNfVmFsdWU6Om9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkgY29uc3QNCi17DQotCXJldHVybiBKU19Ub1N0cmluZyhtX3BWYWx1ZSk7DQotfQ0KLQ0KLUNKU19WYWx1ZTo6b3BlcmF0b3IgQ0ZYX0J5dGVTdHJpbmcoKSBjb25zdA0KLXsNCi0JcmV0dXJuIENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShvcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsNCi19DQotDQotdjg6OkhhbmRsZTx2ODo6VmFsdWU+IENKU19WYWx1ZTo6VG9KU1ZhbHVlKCkNCi17DQotCXJldHVybiBtX3BWYWx1ZTsNCi19DQotDQotDQotQ0pTX1ZhbHVlOjpvcGVyYXRvciB2ODo6SGFuZGxlPHY4OjpBcnJheT4oKSBjb25zdA0KLXsNCi0JaWYgKElzQXJyYXlPYmplY3QoKSkNCi0JCXJldHVybiB2ODo6SGFuZGxlPHY4OjpBcnJheT46OkNhc3QoSlNfVG9PYmplY3QobV9wVmFsdWUpKTsNCi0JcmV0dXJuIHY4OjpIYW5kbGU8djg6OkFycmF5PigpOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotdm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0oaW50IGlWYWx1ZSkNCi17DQotCW1fcFZhbHVlID0gSlNfTmV3TnVtYmVyKG1faXNvbGF0ZSwgaVZhbHVlKTsNCi0NCi0JbV9lVHlwZSA9IFZUX251bWJlcjsNCi19DQotDQotdm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0oYm9vbCBiVmFsdWUpDQotew0KLQltX3BWYWx1ZSA9IEpTX05ld0Jvb2xlYW4obV9pc29sYXRlLCBiVmFsdWUpOw0KLQ0KLQltX2VUeXBlID0gVlRfYm9vbGVhbjsNCi19DQotDQotdm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0oZG91YmxlIGRWYWx1ZSkNCi17DQotCW1fcFZhbHVlID0gSlNfTmV3TnVtYmVyKG1faXNvbGF0ZSxkVmFsdWUpOw0KLQ0KLQltX2VUeXBlID0gVlRfbnVtYmVyOw0KLX0NCi0NCi12b2lkIENKU19WYWx1ZTo6b3BlcmF0b3IgPSAoZmxvYXQgZlZhbHVlKQ0KLXsNCi0JbV9wVmFsdWUgPSBKU19OZXdOdW1iZXIobV9pc29sYXRlLGZWYWx1ZSk7DQotCW1fZVR5cGUgPSBWVF9udW1iZXI7DQotfQ0KLQ0KLXZvaWQgQ0pTX1ZhbHVlOjpvcGVyYXRvciA9KHY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaikNCi17DQotDQotCW1fcFZhbHVlID0gSlNfTmV3T2JqZWN0KG1faXNvbGF0ZSxwT2JqKTsNCi0NCi0JbV9lVHlwZSA9IFZUX2Z4b2JqZWN0Ow0KLX0NCi0NCi12b2lkIENKU19WYWx1ZTo6b3BlcmF0b3IgPShDSlNfT2JqZWN0ICogcE9iaikNCi17DQotCWlmIChwT2JqKQ0KLQkJb3BlcmF0b3IgPSAoKEpTRlhPYmplY3QpKnBPYmopOw0KLX0NCi0NCi12b2lkIENKU19WYWx1ZTo6b3BlcmF0b3IgPShGWF9MUENXU1RSIHBXc3RyKQ0KLXsNCi0JbV9wVmFsdWUgPSBKU19OZXdTdHJpbmcobV9pc29sYXRlLCh3Y2hhcl90ICopcFdzdHIpOw0KLQ0KLQltX2VUeXBlID0gVlRfc3RyaW5nOw0KLX0NCi0NCi12b2lkIENKU19WYWx1ZTo6U2V0TnVsbCgpDQotew0KLQltX3BWYWx1ZSA9IEpTX05ld051bGwoKTsNCi0NCi0JbV9lVHlwZSA9IFZUX251bGw7DQotfQ0KLQ0KLXZvaWQgQ0pTX1ZhbHVlOjpvcGVyYXRvciA9IChGWF9MUENTVFIgcFN0cikNCi17CQ0KLQlvcGVyYXRvciA9IChDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKHBTdHIpKTsNCi19DQotDQotdm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0gKENKU19BcnJheSAmIGFycmF5KQ0KLXsNCi0JbV9wVmFsdWUgPSBKU19OZXdPYmplY3QyKG1faXNvbGF0ZSwodjg6OkhhbmRsZTx2ODo6QXJyYXk+KWFycmF5KTsNCi0NCi0JbV9lVHlwZSA9IFZUX29iamVjdDsNCi19DQotDQotdm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0gKENKU19EYXRlICYgZGF0ZSkNCi17DQotCW1fcFZhbHVlID0gSlNfTmV3RGF0ZShtX2lzb2xhdGUsIChkb3VibGUpZGF0ZSk7DQotDQotCW1fZVR5cGUgPSBWVF9kYXRlOw0KLX0NCi0NCi12b2lkIENKU19WYWx1ZTo6b3BlcmF0b3IgPSAoQ0pTX1ZhbHVlIHZhbHVlKQ0KLXsNCi0JbV9wVmFsdWUgPSB2YWx1ZS5Ub0pTVmFsdWUoKTsNCi0NCi0JbV9lVHlwZSA9IHZhbHVlLm1fZVR5cGU7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1GWEpTVkFMVUVUWVBFIENKU19WYWx1ZTo6R2V0VHlwZSgpIGNvbnN0DQotew0KLQlpZihtX3BWYWx1ZS5Jc0VtcHR5KCkpIHJldHVybiBWVF91bmtub3duOw0KLQlpZihtX3BWYWx1ZS0+SXNTdHJpbmcoKSkgcmV0dXJuIFZUX3N0cmluZzsNCi0JaWYobV9wVmFsdWUtPklzTnVtYmVyKCkpIHJldHVybiBWVF9udW1iZXI7DQotCWlmKG1fcFZhbHVlLT5Jc0Jvb2xlYW4oKSkgcmV0dXJuIFZUX2Jvb2xlYW47DQotCWlmKG1fcFZhbHVlLT5Jc0RhdGUoKSkgcmV0dXJuIFZUX2RhdGU7DQotCWlmKG1fcFZhbHVlLT5Jc09iamVjdCgpKSByZXR1cm4gVlRfb2JqZWN0Ow0KLQlpZihtX3BWYWx1ZS0+SXNOdWxsKCkpIHJldHVybiBWVF9udWxsOw0KLQlpZihtX3BWYWx1ZS0+SXNVbmRlZmluZWQoKSkgcmV0dXJuIFZUX3VuZGVmaW5lZDsNCi0JcmV0dXJuIFZUX3Vua25vd247DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1ZhbHVlOjpJc0FycmF5T2JqZWN0KCkgY29uc3QgDQotew0KLQlpZihtX3BWYWx1ZS5Jc0VtcHR5KCkpIHJldHVybiBGQUxTRTsNCi0JcmV0dXJuIG1fcFZhbHVlLT5Jc0FycmF5KCk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1ZhbHVlOjpJc0RhdGVPYmplY3QoKSBjb25zdA0KLXsNCi0JaWYobV9wVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7DQotCXJldHVybiBtX3BWYWx1ZS0+SXNEYXRlKCk7DQotfQ0KLQ0KLS8vQ0pTX1ZhbHVlOjpvcGVyYXRvciBDSlNfQXJyYXkoKQ0KLUZYX0JPT0wgQ0pTX1ZhbHVlOjpDb252ZXJ0VG9BcnJheShDSlNfQXJyYXkgJmFycmF5KSBjb25zdA0KLXsNCi0JaWYgKElzQXJyYXlPYmplY3QoKSkNCi0Jew0KLQkJYXJyYXkuQXR0YWNoKEpTX1RvQXJyYXkobV9wVmFsdWUpKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDSlNfVmFsdWU6OkNvbnZlcnRUb0RhdGUoQ0pTX0RhdGUgJmRhdGUpIGNvbnN0DQotew0KLS8vIAlpZiAoR2V0VHlwZSgpID09IFZUX2RhdGUpDQotLy8gCXsNCi0vLyAJCWRhdGUgPSAoZG91YmxlKSgqdGhpcyk7DQotLy8gCQlyZXR1cm4gVFJVRTsNCi0vLyAJfQ0KLQ0KLQlpZiAoSXNEYXRlT2JqZWN0KCkpDQotCXsNCi0JCWRhdGUuQXR0YWNoKG1fcFZhbHVlKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsJDQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ0pTX1Byb3BWYWx1ZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0pTX1Byb3BWYWx1ZTo6Q0pTX1Byb3BWYWx1ZShjb25zdCBDSlNfVmFsdWUgJnZhbHVlKSA6IA0KLQlDSlNfVmFsdWUodmFsdWUpLA0KLQltX2JJc1NldHRpbmcoMCkNCi17DQotfQ0KLQ0KLUNKU19Qcm9wVmFsdWU6OkNKU19Qcm9wVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUpIDogQ0pTX1ZhbHVlKGlzb2xhdGUpLA0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1fYklzU2V0dGluZygwKQ0KLXsNCi19DQotDQotQ0pTX1Byb3BWYWx1ZTo6fkNKU19Qcm9wVmFsdWUoKQ0KLXsNCi19DQotDQotRlhfQk9PTCBDSlNfUHJvcFZhbHVlOjpJc1NldHRpbmcoKQ0KLXsNCi0JcmV0dXJuIG1fYklzU2V0dGluZzsNCi19DQotDQotRlhfQk9PTCBDSlNfUHJvcFZhbHVlOjpJc0dldHRpbmcoKQ0KLXsNCi0JcmV0dXJuICFtX2JJc1NldHRpbmc7DQotfQ0KLQ0KLXZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPDwoaW50IGlWYWx1ZSkNCi17DQotCUFTU0VSVCghbV9iSXNTZXR0aW5nKTsNCi0JQ0pTX1ZhbHVlOjpvcGVyYXRvciA9KGlWYWx1ZSk7DQotfQ0KLQ0KLXZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPj4oaW50ICYgaVZhbHVlKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fYklzU2V0dGluZyk7DQotCWlWYWx1ZSA9IENKU19WYWx1ZTo6b3BlcmF0b3IgaW50KCk7DQotfQ0KLQ0KLQ0KLXZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPDwoYm9vbCBiVmFsdWUpDQotew0KLQlBU1NFUlQoIW1fYklzU2V0dGluZyk7DQotCUNKU19WYWx1ZTo6b3BlcmF0b3IgPShiVmFsdWUpOw0KLX0NCi0NCi12b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yID4+KGJvb2wgJmJWYWx1ZSkgY29uc3QNCi17DQotCUFTU0VSVChtX2JJc1NldHRpbmcpOw0KLQliVmFsdWUgPSBDSlNfVmFsdWU6Om9wZXJhdG9yIGJvb2woKTsNCi0NCi19DQotDQotdm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvciA8PChkb3VibGUgZFZhbHVlKQ0KLXsNCi0JQVNTRVJUKCFtX2JJc1NldHRpbmcpOw0KLQlDSlNfVmFsdWU6Om9wZXJhdG9yID0oZFZhbHVlKTsNCi19DQotDQotdm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvciA+Pihkb3VibGUgJmRWYWx1ZSkgY29uc3QNCi17DQotCUFTU0VSVChtX2JJc1NldHRpbmcpOw0KLQlkVmFsdWUgPSBDSlNfVmFsdWU6Om9wZXJhdG9yIGRvdWJsZSgpOw0KLX0NCi0NCi12b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yIDw8KENKU19PYmplY3QgKnBPYmopDQotew0KLQlBU1NFUlQoIW1fYklzU2V0dGluZyk7DQotCUNKU19WYWx1ZTo6b3BlcmF0b3IgPSAocE9iaik7DQotfQ0KLQ0KLXZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPj4oQ0pTX09iamVjdCAqJnBwT2JqKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fYklzU2V0dGluZyk7DQotCXBwT2JqID0gQ0pTX1ZhbHVlOjpvcGVyYXRvciBDSlNfT2JqZWN0ICooKTsNCi19DQotDQotdm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvcjw8KEpTRlhPYmplY3QgcE9iaikNCi17DQotCUFTU0VSVCghbV9iSXNTZXR0aW5nKTsNCi0JQ0pTX1ZhbHVlOjpvcGVyYXRvciA9IChwT2JqKTsNCi19DQotDQotdm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvcj4+KEpTRlhPYmplY3QgJnBwT2JqKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fYklzU2V0dGluZyk7DQotCXBwT2JqID0gQ0pTX1ZhbHVlOjpvcGVyYXRvciBKU0ZYT2JqZWN0ICgpOw0KLX0NCi0NCi0NCi12b2lkIENKU19Qcm9wVmFsdWU6OlN0YXJ0U2V0dGluZygpDQotew0KLQltX2JJc1NldHRpbmcgPSAxOw0KLX0NCi0NCi12b2lkIENKU19Qcm9wVmFsdWU6OlN0YXJ0R2V0dGluZygpDQotew0KLQltX2JJc1NldHRpbmcgPSAwOw0KLX0NCi12b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yIDw8KENGWF9CeXRlU3RyaW5nIHN0cmluZykNCi17DQotCUFTU0VSVCghbV9iSXNTZXR0aW5nKTsNCi0JQ0pTX1ZhbHVlOjpvcGVyYXRvciA9KChGWF9MUENTVFIpc3RyaW5nKTsNCi19DQotDQotdm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvciA+PihDRlhfQnl0ZVN0cmluZyAmc3RyaW5nKSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fYklzU2V0dGluZyk7DQotCXN0cmluZyA9IENKU19WYWx1ZTo6b3BlcmF0b3IgQ0ZYX0J5dGVTdHJpbmcoKTsNCi19DQotDQotdm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvciA8PChGWF9MUENXU1RSIGNfc3RyaW5nKQ0KLXsNCi0JQVNTRVJUKCFtX2JJc1NldHRpbmcpOw0KLQlDSlNfVmFsdWU6Om9wZXJhdG9yID0oY19zdHJpbmcpOw0KLX0NCi0NCi12b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yID4+KENGWF9XaWRlU3RyaW5nICZ3aWRlX3N0cmluZykgY29uc3QNCi17DQotCUFTU0VSVChtX2JJc1NldHRpbmcpOw0KLQl3aWRlX3N0cmluZyA9IENKU19WYWx1ZTo6b3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi19DQotDQotdm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvciA8PChDRlhfV2lkZVN0cmluZyB3aWRlX3N0cmluZykNCi17DQotCUFTU0VSVCghbV9iSXNTZXR0aW5nKTsNCi0JQ0pTX1ZhbHVlOjpvcGVyYXRvciA9ICh3aWRlX3N0cmluZyk7DQotfQ0KLQ0KLXZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPj4oQ0pTX0FycmF5ICZhcnJheSkgY29uc3QNCi17DQotCUFTU0VSVChtX2JJc1NldHRpbmcpOw0KLQlDb252ZXJ0VG9BcnJheShhcnJheSk7DQotfQ0KLQ0KLXZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPDwoQ0pTX0FycmF5ICZhcnJheSkNCi17DQotCUFTU0VSVCghbV9iSXNTZXR0aW5nKTsNCi0JQ0pTX1ZhbHVlOjpvcGVyYXRvcj0oYXJyYXkpOw0KLX0NCi0NCi12b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yPj4oQ0pTX0RhdGUgJmRhdGUpIGNvbnN0DQotew0KLQlBU1NFUlQobV9iSXNTZXR0aW5nKTsNCi0JQ29udmVydFRvRGF0ZShkYXRlKTsNCi19DQotDQotdm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvcjw8KENKU19EYXRlICZkYXRlKQ0KLXsNCi0JQVNTRVJUKCFtX2JJc1NldHRpbmcpOw0KLQlDSlNfVmFsdWU6Om9wZXJhdG9yPShkYXRlKTsNCi19DQotDQotQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6VmFsdWU+KCkgY29uc3QNCi17DQotCXJldHVybiBtX3BWYWx1ZTsNCi19DQotDQotLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBDSlNfQXJyYXkgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCi1DSlNfQXJyYXk6OkNKU19BcnJheSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSk6bV9pc29sYXRlKGlzb2xhdGUpDQotew0KLX0NCi0NCi1DSlNfQXJyYXk6On5DSlNfQXJyYXkoKQ0KLXsJCQ0KLX0NCi0NCi12b2lkIENKU19BcnJheTo6QXR0YWNoKHY4OjpIYW5kbGU8djg6OkFycmF5PiBwQXJyYXkpDQotew0KLQltX3BBcnJheSA9IHBBcnJheTsNCi19DQotDQotRlhfQk9PTCBDSlNfQXJyYXk6OklzQXR0YWNoZWQoKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENKU19BcnJheTo6R2V0RWxlbWVudCh1bnNpZ25lZCBpbmRleCxDSlNfVmFsdWUgJnZhbHVlKQ0KLXsNCi0JaWYgKG1fcEFycmF5LklzRW1wdHkoKSkNCi0JCXJldHVybjsNCi0Jdjg6OkhhbmRsZTx2ODo6VmFsdWU+ICBwID0gSlNfR2V0QXJyYXlFbGVtbmV0KG1fcEFycmF5LGluZGV4KTsNCi0JdmFsdWUuQXR0YWNoKHAsVlRfb2JqZWN0KTsNCi19DQotDQotdm9pZCBDSlNfQXJyYXk6OlNldEVsZW1lbnQodW5zaWduZWQgaW5kZXgsQ0pTX1ZhbHVlIHZhbHVlKQ0KLXsNCi0JaWYgKG1fcEFycmF5LklzRW1wdHkoKSkNCi0JCW1fcEFycmF5ID0gSlNfTmV3QXJyYXkobV9pc29sYXRlKTsNCi0NCi0JSlNfUHV0QXJyYXlFbGVtZW50KG1fcEFycmF5LGluZGV4LHZhbHVlLlRvSlNWYWx1ZSgpLHZhbHVlLkdldFR5cGUoKSk7DQotfQ0KLQ0KLWludCBDSlNfQXJyYXk6OkdldExlbmd0aCgpDQotew0KLQlpZiAobV9wQXJyYXkuSXNFbXB0eSgpKQ0KLQkJcmV0dXJuIDA7DQotCXJldHVybiBKU19HZXRBcnJheUxlbmd0aChtX3BBcnJheSk7DQotfQ0KLQ0KLUNKU19BcnJheTo6IG9wZXJhdG9yIHY4OjpIYW5kbGU8djg6OkFycmF5PigpDQotew0KLQlpZiAobV9wQXJyYXkuSXNFbXB0eSgpKQ0KLQkJbV9wQXJyYXkgPSBKU19OZXdBcnJheShtX2lzb2xhdGUpOw0KLQ0KLQlyZXR1cm4gbV9wQXJyYXk7DQotfQ0KLQ0KLS8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gQ0pTX0RhdGUgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCi0NCi1DSlNfRGF0ZTo6Q0pTX0RhdGUodjg6Oklzb2xhdGUqIGlzb2xhdGUpIDptX2lzb2xhdGUoaXNvbGF0ZSkNCi17DQotfQ0KLQ0KLUNKU19EYXRlOjpDSlNfRGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSxkb3VibGUgZE1zZWNfdGltZSkgDQotew0KLQltX2lzb2xhdGUgPSBpc29sYXRlOw0KLQltX3BEYXRlID0gSlNfTmV3RGF0ZShpc29sYXRlLGRNc2VjX3RpbWUpOwkJDQotfQ0KLQ0KLUNKU19EYXRlOjpDSlNfRGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSxpbnQgeWVhciwgaW50IG1vbiwgaW50IGRheSxpbnQgaG91ciwgaW50IG1pbiwgaW50IHNlYykgDQotew0KLQltX2lzb2xhdGUgPSBpc29sYXRlOw0KLQltX3BEYXRlID0gSlNfTmV3RGF0ZShpc29sYXRlLE1ha2VEYXRlKHllYXIsbW9uLGRheSxob3VyLG1pbixzZWMsMCkpOwkNCi19DQotDQotZG91YmxlIENKU19EYXRlOjpNYWtlRGF0ZShpbnQgeWVhciwgaW50IG1vbiwgaW50IGRheSxpbnQgaG91ciwgaW50IG1pbiwgaW50IHNlYyxpbnQgbXMpDQotew0KLQlyZXR1cm4gSlNfTWFrZURhdGUoSlNfTWFrZURheSh5ZWFyLG1vbixkYXkpLCBKU19NYWtlVGltZShob3VyLG1pbixzZWMsbXMpKTsNCi19DQotDQotQ0pTX0RhdGU6On5DSlNfRGF0ZSgpDQotew0KLX0NCi0NCi1GWF9CT09MCUNKU19EYXRlOjpJc1ZhbGlkRGF0ZSgpDQotew0KLQlpZihtX3BEYXRlLklzRW1wdHkoKSkgcmV0dXJuIEZBTFNFOw0KLQlyZXR1cm4gIUpTX1BvcnRJc05hbihKU19Ub051bWJlcihtX3BEYXRlKSk7DQotfQ0KLQ0KLXZvaWQgQ0pTX0RhdGU6OkF0dGFjaCh2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcERhdGUpDQotew0KLQltX3BEYXRlID0gcERhdGU7DQotfQ0KLQ0KLWludCBDSlNfRGF0ZTo6R2V0WWVhcigpDQotew0KLQlpZiAoSXNWYWxpZERhdGUoKSkNCi0JCXJldHVybiBKU19HZXRZZWFyRnJvbVRpbWUoSlNfTG9jYWxUaW1lKEpTX1RvTnVtYmVyKG1fcERhdGUpKSk7DQotDQotCXJldHVybiAwOw0KLX0NCi0NCi12b2lkIENKU19EYXRlOjpTZXRZZWFyKGludCBpWWVhcikNCi17DQotCWRvdWJsZSBkYXRlID0gTWFrZURhdGUoaVllYXIsR2V0TW9udGgoKSxHZXREYXkoKSxHZXRIb3VycygpLEdldE1pbnV0ZXMoKSxHZXRTZWNvbmRzKCksMCk7DQotCUpTX1ZhbHVlQ29weShtX3BEYXRlLCBKU19OZXdEYXRlKG1faXNvbGF0ZSxkYXRlKSk7DQotfQ0KLQ0KLWludCBDSlNfRGF0ZTo6R2V0TW9udGgoKQ0KLXsNCi0JaWYgKElzVmFsaWREYXRlKCkpDQotCQlyZXR1cm4gSlNfR2V0TW9udGhGcm9tVGltZShKU19Mb2NhbFRpbWUoSlNfVG9OdW1iZXIobV9wRGF0ZSkpKTsNCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLXZvaWQgQ0pTX0RhdGU6OlNldE1vbnRoKGludCBpTW9udGgpDQotew0KLQ0KLQlkb3VibGUgZGF0ZSA9IE1ha2VEYXRlKEdldFllYXIoKSxpTW9udGgsR2V0RGF5KCksR2V0SG91cnMoKSxHZXRNaW51dGVzKCksR2V0U2Vjb25kcygpLDApOw0KLQlKU19WYWx1ZUNvcHkobV9wRGF0ZSwgSlNfTmV3RGF0ZShtX2lzb2xhdGUsZGF0ZSkpOw0KLQ0KLX0NCi0NCi1pbnQgQ0pTX0RhdGU6OkdldERheSgpDQotew0KLQlpZiAoSXNWYWxpZERhdGUoKSkNCi0JCXJldHVybiBKU19HZXREYXlGcm9tVGltZShKU19Mb2NhbFRpbWUoSlNfVG9OdW1iZXIobV9wRGF0ZSkpKTsNCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLXZvaWQgQ0pTX0RhdGU6OlNldERheShpbnQgaURheSkNCi17DQotDQotCWRvdWJsZSBkYXRlID0gTWFrZURhdGUoR2V0WWVhcigpLEdldE1vbnRoKCksaURheSxHZXRIb3VycygpLEdldE1pbnV0ZXMoKSxHZXRTZWNvbmRzKCksMCk7DQotCUpTX1ZhbHVlQ29weShtX3BEYXRlLEpTX05ld0RhdGUobV9pc29sYXRlLGRhdGUpKTsNCi0NCi19DQotDQotaW50IENKU19EYXRlOjpHZXRIb3VycygpDQotew0KLQlpZiAoSXNWYWxpZERhdGUoKSkNCi0JCXJldHVybiBKU19HZXRIb3VyRnJvbVRpbWUoSlNfTG9jYWxUaW1lKEpTX1RvTnVtYmVyKG1fcERhdGUpKSk7DQotDQotCXJldHVybiAwOw0KLX0NCi0NCi12b2lkIENKU19EYXRlOjpTZXRIb3VycyhpbnQgaUhvdXJzKQ0KLXsNCi0JZG91YmxlIGRhdGUgPSBNYWtlRGF0ZShHZXRZZWFyKCksR2V0TW9udGgoKSxHZXREYXkoKSxpSG91cnMsR2V0TWludXRlcygpLEdldFNlY29uZHMoKSwwKTsNCi0JSlNfVmFsdWVDb3B5KG1fcERhdGUsSlNfTmV3RGF0ZShtX2lzb2xhdGUsZGF0ZSkpOw0KLX0NCi0NCi1pbnQgQ0pTX0RhdGU6OkdldE1pbnV0ZXMoKQ0KLXsNCi0JaWYgKElzVmFsaWREYXRlKCkpDQotCQlyZXR1cm4gSlNfR2V0TWluRnJvbVRpbWUoSlNfTG9jYWxUaW1lKEpTX1RvTnVtYmVyKG1fcERhdGUpKSk7DQotDQotCXJldHVybiAwOw0KLX0NCi0NCi12b2lkIENKU19EYXRlOjpTZXRNaW51dGVzKGludCBtaW51dGVzKQ0KLXsNCi0JZG91YmxlIGRhdGUgPSBNYWtlRGF0ZShHZXRZZWFyKCksR2V0TW9udGgoKSxHZXREYXkoKSxHZXRIb3VycygpLG1pbnV0ZXMsR2V0U2Vjb25kcygpLDApOw0KLQlKU19WYWx1ZUNvcHkobV9wRGF0ZSxKU19OZXdEYXRlKG1faXNvbGF0ZSxkYXRlKSk7DQotfQ0KLQ0KLWludCBDSlNfRGF0ZTo6R2V0U2Vjb25kcygpDQotew0KLQlpZiAoSXNWYWxpZERhdGUoKSkNCi0JCXJldHVybiBKU19HZXRTZWNGcm9tVGltZShKU19Mb2NhbFRpbWUoSlNfVG9OdW1iZXIobV9wRGF0ZSkpKTsNCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLXZvaWQgQ0pTX0RhdGU6OlNldFNlY29uZHMoaW50IHNlY29uZHMpDQotew0KLQlkb3VibGUgZGF0ZSA9IE1ha2VEYXRlKEdldFllYXIoKSxHZXRNb250aCgpLEdldERheSgpLEdldEhvdXJzKCksR2V0TWludXRlcygpLHNlY29uZHMsMCk7DQotCUpTX1ZhbHVlQ29weShtX3BEYXRlLEpTX05ld0RhdGUobV9pc29sYXRlLGRhdGUpKTsNCi19DQotDQotQ0pTX0RhdGU6Om9wZXJhdG9yIHY4OjpIYW5kbGU8djg6OlZhbHVlPigpDQotew0KLQlyZXR1cm4gbV9wRGF0ZTsNCi19DQotDQotQ0pTX0RhdGU6Om9wZXJhdG9yIGRvdWJsZSgpIGNvbnN0DQotew0KLQlpZihtX3BEYXRlLklzRW1wdHkoKSkNCi0JCXJldHVybiAwLjA7DQotCXJldHVybiBKU19Ub051bWJlcihtX3BEYXRlKTsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ0pTX0RhdGU6OlRvU3RyaW5nKCkgY29uc3QNCi17DQotCWlmKG1fcERhdGUuSXNFbXB0eSgpKQ0KLQkJcmV0dXJuIEwiIjsNCi0JcmV0dXJuIEpTX1RvU3RyaW5nKG1fcERhdGUpOw0KLX0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENKU19WYWx1ZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlKSA6IG1faXNvbGF0ZShpc29sYXRlKSxtX2VUeXBlKFZUX3Vua25vd24pCit7Cit9CitDSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSxGWEpTVkFMVUVUWVBFIHQpIDptX2lzb2xhdGUoaXNvbGF0ZSksIG1fcFZhbHVlKHBWYWx1ZSkgLCBtX2VUeXBlKHQpCit7Cit9CisKK0NKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBjb25zdCBpbnQgJmlWYWx1ZSk6bV9pc29sYXRlKGlzb2xhdGUpCit7CisJb3BlcmF0b3IgPShpVmFsdWUpOworfQorCitDSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgY29uc3QgYm9vbCAmYlZhbHVlKTptX2lzb2xhdGUoaXNvbGF0ZSkKK3sKKwlvcGVyYXRvciA9KGJWYWx1ZSk7Cit9CisKK0NKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBjb25zdCBmbG9hdCAmZlZhbHVlKTptX2lzb2xhdGUoaXNvbGF0ZSkKK3sKKwlvcGVyYXRvciA9KGZWYWx1ZSk7Cit9CisKK0NKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBjb25zdCBkb3VibGUgJmRWYWx1ZSk6bV9pc29sYXRlKGlzb2xhdGUpIAoreworCW9wZXJhdG9yID0oZFZhbHVlKTsKK30KKworQ0pTX1ZhbHVlOjpDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIEpTRlhPYmplY3QgIHBKc09iaik6bV9pc29sYXRlKGlzb2xhdGUpIAoreworCW9wZXJhdG9yID0ocEpzT2JqKTsKK30KKworQ0pTX1ZhbHVlOjpDSlNfVmFsdWUodjg6Oklzb2xhdGUqIGlzb2xhdGUsIENKU19PYmplY3QgKiBwSnNPYmopOm1faXNvbGF0ZShpc29sYXRlKSAKK3sKKwlvcGVyYXRvciA9KHBKc09iaik7Cit9CisKK0NKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBGWF9MUENXU1RSIHBXc3RyKTptX2lzb2xhdGUoaXNvbGF0ZSkgCit7CisJb3BlcmF0b3IgPShwV3N0cik7Cit9CisKK0NKU19WYWx1ZTo6Q0pTX1ZhbHVlKHY4OjpJc29sYXRlKiBpc29sYXRlLCBGWF9MUENTVFIgcFN0cik6bV9pc29sYXRlKGlzb2xhdGUpIAoreworCW9wZXJhdG9yID0gKHBTdHIpOworfQorCitDSlNfVmFsdWU6OkNKU19WYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSwgQ0pTX0FycmF5JiBhcnJheSk6bV9pc29sYXRlKGlzb2xhdGUpIAoreworCW9wZXJhdG9yID0gKGFycmF5KTsKK30KKworQ0pTX1ZhbHVlOjp+Q0pTX1ZhbHVlKCkKK3sKK30KKwordm9pZCBDSlNfVmFsdWU6OkF0dGFjaCh2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcFZhbHVlLEZYSlNWQUxVRVRZUEUgdCkKK3sKKwltX3BWYWx1ZSA9IHBWYWx1ZTsKKwltX2VUeXBlID0gdDsKK30KKwordm9pZCBDSlNfVmFsdWU6OkF0dGFjaChDSlNfVmFsdWUgKnBWYWx1ZSkKK3sKKwlpZiAocFZhbHVlKQorCQlBdHRhY2gocFZhbHVlLT5Ub0pTVmFsdWUoKSxwVmFsdWUtPkdldFR5cGUoKSk7Cit9CisKK3ZvaWQgQ0pTX1ZhbHVlOjpEZXRhY2goKQoreworCW1fcFZhbHVlID0gdjg6OkhhbmRsZTx2ODo6VmFsdWU+KCk7CisJbV9lVHlwZSA9IFZUX3Vua25vd247Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ0pTX1ZhbHVlOjpvcGVyYXRvciBpbnQoKSBjb25zdAoreworCisJcmV0dXJuIEpTX1RvSW50MzIobV9wVmFsdWUpOworCit9CisKK0NKU19WYWx1ZTo6b3BlcmF0b3IgYm9vbCgpIGNvbnN0Cit7CisKKwlyZXR1cm4gSlNfVG9Cb29sZWFuKG1fcFZhbHVlKTsKKwkKK30KKworQ0pTX1ZhbHVlOjpvcGVyYXRvciBkb3VibGUoKSBjb25zdAoreworCisJcmV0dXJuIEpTX1RvTnVtYmVyKG1fcFZhbHVlKTsKKwkKK30KKworQ0pTX1ZhbHVlOjpvcGVyYXRvciBmbG9hdCgpIGNvbnN0Cit7CisKKwlyZXR1cm4gKGZsb2F0KUpTX1RvTnVtYmVyKG1fcFZhbHVlKTsKKworfQorCitDSlNfVmFsdWU6Om9wZXJhdG9yIENKU19PYmplY3QgKigpIGNvbnN0Cit7CisKKwl2ODo6SGFuZGxlPHY4OjpPYmplY3Q+CXBPYmogPSBKU19Ub09iamVjdChtX3BWYWx1ZSk7CisJcmV0dXJuIChDSlNfT2JqZWN0KilKU19HZXRQcml2YXRlKG1faXNvbGF0ZSwgcE9iaik7Cit9CisKK0NKU19WYWx1ZTo6b3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6T2JqZWN0PigpIGNvbnN0Cit7CisJcmV0dXJuIEpTX1RvT2JqZWN0KG1fcFZhbHVlKTsKK30KKworQ0pTX1ZhbHVlOjpvcGVyYXRvciBDRlhfV2lkZVN0cmluZygpIGNvbnN0Cit7CisJcmV0dXJuIEpTX1RvU3RyaW5nKG1fcFZhbHVlKTsKK30KKworQ0pTX1ZhbHVlOjpvcGVyYXRvciBDRlhfQnl0ZVN0cmluZygpIGNvbnN0Cit7CisJcmV0dXJuIENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShvcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKK30KKwordjg6OkhhbmRsZTx2ODo6VmFsdWU+IENKU19WYWx1ZTo6VG9KU1ZhbHVlKCkKK3sKKwlyZXR1cm4gbV9wVmFsdWU7Cit9CisKKworQ0pTX1ZhbHVlOjpvcGVyYXRvciB2ODo6SGFuZGxlPHY4OjpBcnJheT4oKSBjb25zdAoreworCWlmIChJc0FycmF5T2JqZWN0KCkpCisJCXJldHVybiB2ODo6SGFuZGxlPHY4OjpBcnJheT46OkNhc3QoSlNfVG9PYmplY3QobV9wVmFsdWUpKTsKKwlyZXR1cm4gdjg6OkhhbmRsZTx2ODo6QXJyYXk+KCk7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKwordm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0oaW50IGlWYWx1ZSkKK3sKKwltX3BWYWx1ZSA9IEpTX05ld051bWJlcihtX2lzb2xhdGUsIGlWYWx1ZSk7CisKKwltX2VUeXBlID0gVlRfbnVtYmVyOworfQorCit2b2lkIENKU19WYWx1ZTo6b3BlcmF0b3IgPShib29sIGJWYWx1ZSkKK3sKKwltX3BWYWx1ZSA9IEpTX05ld0Jvb2xlYW4obV9pc29sYXRlLCBiVmFsdWUpOworCisJbV9lVHlwZSA9IFZUX2Jvb2xlYW47Cit9CisKK3ZvaWQgQ0pTX1ZhbHVlOjpvcGVyYXRvciA9KGRvdWJsZSBkVmFsdWUpCit7CisJbV9wVmFsdWUgPSBKU19OZXdOdW1iZXIobV9pc29sYXRlLGRWYWx1ZSk7CisKKwltX2VUeXBlID0gVlRfbnVtYmVyOworfQorCit2b2lkIENKU19WYWx1ZTo6b3BlcmF0b3IgPSAoZmxvYXQgZlZhbHVlKQoreworCW1fcFZhbHVlID0gSlNfTmV3TnVtYmVyKG1faXNvbGF0ZSxmVmFsdWUpOworCW1fZVR5cGUgPSBWVF9udW1iZXI7Cit9CisKK3ZvaWQgQ0pTX1ZhbHVlOjpvcGVyYXRvciA9KHY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaikKK3sKKworCW1fcFZhbHVlID0gSlNfTmV3T2JqZWN0KG1faXNvbGF0ZSxwT2JqKTsKKworCW1fZVR5cGUgPSBWVF9meG9iamVjdDsKK30KKwordm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0oQ0pTX09iamVjdCAqIHBPYmopCit7CisJaWYgKHBPYmopCisJCW9wZXJhdG9yID0gKChKU0ZYT2JqZWN0KSpwT2JqKTsKK30KKwordm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0oRlhfTFBDV1NUUiBwV3N0cikKK3sKKwltX3BWYWx1ZSA9IEpTX05ld1N0cmluZyhtX2lzb2xhdGUsKHdjaGFyX3QgKilwV3N0cik7CisKKwltX2VUeXBlID0gVlRfc3RyaW5nOworfQorCit2b2lkIENKU19WYWx1ZTo6U2V0TnVsbCgpCit7CisJbV9wVmFsdWUgPSBKU19OZXdOdWxsKCk7CisKKwltX2VUeXBlID0gVlRfbnVsbDsKK30KKwordm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0gKEZYX0xQQ1NUUiBwU3RyKQorewkKKwlvcGVyYXRvciA9IChDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKHBTdHIpKTsKK30KKwordm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0gKENKU19BcnJheSAmIGFycmF5KQoreworCW1fcFZhbHVlID0gSlNfTmV3T2JqZWN0MihtX2lzb2xhdGUsKHY4OjpIYW5kbGU8djg6OkFycmF5PilhcnJheSk7CisKKwltX2VUeXBlID0gVlRfb2JqZWN0OworfQorCit2b2lkIENKU19WYWx1ZTo6b3BlcmF0b3IgPSAoQ0pTX0RhdGUgJiBkYXRlKQoreworCW1fcFZhbHVlID0gSlNfTmV3RGF0ZShtX2lzb2xhdGUsIChkb3VibGUpZGF0ZSk7CisKKwltX2VUeXBlID0gVlRfZGF0ZTsKK30KKwordm9pZCBDSlNfVmFsdWU6Om9wZXJhdG9yID0gKENKU19WYWx1ZSB2YWx1ZSkKK3sKKwltX3BWYWx1ZSA9IHZhbHVlLlRvSlNWYWx1ZSgpOworCisJbV9lVHlwZSA9IHZhbHVlLm1fZVR5cGU7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworRlhKU1ZBTFVFVFlQRSBDSlNfVmFsdWU6OkdldFR5cGUoKSBjb25zdAoreworCWlmKG1fcFZhbHVlLklzRW1wdHkoKSkgcmV0dXJuIFZUX3Vua25vd247CisJaWYobV9wVmFsdWUtPklzU3RyaW5nKCkpIHJldHVybiBWVF9zdHJpbmc7CisJaWYobV9wVmFsdWUtPklzTnVtYmVyKCkpIHJldHVybiBWVF9udW1iZXI7CisJaWYobV9wVmFsdWUtPklzQm9vbGVhbigpKSByZXR1cm4gVlRfYm9vbGVhbjsKKwlpZihtX3BWYWx1ZS0+SXNEYXRlKCkpIHJldHVybiBWVF9kYXRlOworCWlmKG1fcFZhbHVlLT5Jc09iamVjdCgpKSByZXR1cm4gVlRfb2JqZWN0OworCWlmKG1fcFZhbHVlLT5Jc051bGwoKSkgcmV0dXJuIFZUX251bGw7CisJaWYobV9wVmFsdWUtPklzVW5kZWZpbmVkKCkpIHJldHVybiBWVF91bmRlZmluZWQ7CisJcmV0dXJuIFZUX3Vua25vd247Cit9CisKK0ZYX0JPT0wgQ0pTX1ZhbHVlOjpJc0FycmF5T2JqZWN0KCkgY29uc3QgCit7CisJaWYobV9wVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gRkFMU0U7CisJcmV0dXJuIG1fcFZhbHVlLT5Jc0FycmF5KCk7Cit9CisKK0ZYX0JPT0wgQ0pTX1ZhbHVlOjpJc0RhdGVPYmplY3QoKSBjb25zdAoreworCWlmKG1fcFZhbHVlLklzRW1wdHkoKSkgcmV0dXJuIEZBTFNFOworCXJldHVybiBtX3BWYWx1ZS0+SXNEYXRlKCk7Cit9CisKKy8vQ0pTX1ZhbHVlOjpvcGVyYXRvciBDSlNfQXJyYXkoKQorRlhfQk9PTCBDSlNfVmFsdWU6OkNvbnZlcnRUb0FycmF5KENKU19BcnJheSAmYXJyYXkpIGNvbnN0Cit7CisJaWYgKElzQXJyYXlPYmplY3QoKSkKKwl7CisJCWFycmF5LkF0dGFjaChKU19Ub0FycmF5KG1fcFZhbHVlKSk7CisJCXJldHVybiBUUlVFOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDSlNfVmFsdWU6OkNvbnZlcnRUb0RhdGUoQ0pTX0RhdGUgJmRhdGUpIGNvbnN0Cit7CisvLyAJaWYgKEdldFR5cGUoKSA9PSBWVF9kYXRlKQorLy8gCXsKKy8vIAkJZGF0ZSA9IChkb3VibGUpKCp0aGlzKTsKKy8vIAkJcmV0dXJuIFRSVUU7CisvLyAJfQorCisJaWYgKElzRGF0ZU9iamVjdCgpKQorCXsKKwkJZGF0ZS5BdHRhY2gobV9wVmFsdWUpOworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7CQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENKU19Qcm9wVmFsdWUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDSlNfUHJvcFZhbHVlOjpDSlNfUHJvcFZhbHVlKGNvbnN0IENKU19WYWx1ZSAmdmFsdWUpIDogCisJQ0pTX1ZhbHVlKHZhbHVlKSwKKwltX2JJc1NldHRpbmcoMCkKK3sKK30KKworQ0pTX1Byb3BWYWx1ZTo6Q0pTX1Byb3BWYWx1ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSkgOiBDSlNfVmFsdWUoaXNvbGF0ZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtX2JJc1NldHRpbmcoMCkKK3sKK30KKworQ0pTX1Byb3BWYWx1ZTo6fkNKU19Qcm9wVmFsdWUoKQoreworfQorCitGWF9CT09MIENKU19Qcm9wVmFsdWU6OklzU2V0dGluZygpCit7CisJcmV0dXJuIG1fYklzU2V0dGluZzsKK30KKworRlhfQk9PTCBDSlNfUHJvcFZhbHVlOjpJc0dldHRpbmcoKQoreworCXJldHVybiAhbV9iSXNTZXR0aW5nOworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yIDw8KGludCBpVmFsdWUpCit7CisJQVNTRVJUKCFtX2JJc1NldHRpbmcpOworCUNKU19WYWx1ZTo6b3BlcmF0b3IgPShpVmFsdWUpOworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yID4+KGludCAmIGlWYWx1ZSkgY29uc3QKK3sKKwlBU1NFUlQobV9iSXNTZXR0aW5nKTsKKwlpVmFsdWUgPSBDSlNfVmFsdWU6Om9wZXJhdG9yIGludCgpOworfQorCisKK3ZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPDwoYm9vbCBiVmFsdWUpCit7CisJQVNTRVJUKCFtX2JJc1NldHRpbmcpOworCUNKU19WYWx1ZTo6b3BlcmF0b3IgPShiVmFsdWUpOworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yID4+KGJvb2wgJmJWYWx1ZSkgY29uc3QKK3sKKwlBU1NFUlQobV9iSXNTZXR0aW5nKTsKKwliVmFsdWUgPSBDSlNfVmFsdWU6Om9wZXJhdG9yIGJvb2woKTsKKworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yIDw8KGRvdWJsZSBkVmFsdWUpCit7CisJQVNTRVJUKCFtX2JJc1NldHRpbmcpOworCUNKU19WYWx1ZTo6b3BlcmF0b3IgPShkVmFsdWUpOworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yID4+KGRvdWJsZSAmZFZhbHVlKSBjb25zdAoreworCUFTU0VSVChtX2JJc1NldHRpbmcpOworCWRWYWx1ZSA9IENKU19WYWx1ZTo6b3BlcmF0b3IgZG91YmxlKCk7Cit9CisKK3ZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPDwoQ0pTX09iamVjdCAqcE9iaikKK3sKKwlBU1NFUlQoIW1fYklzU2V0dGluZyk7CisJQ0pTX1ZhbHVlOjpvcGVyYXRvciA9IChwT2JqKTsKK30KKwordm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvciA+PihDSlNfT2JqZWN0IComcHBPYmopIGNvbnN0Cit7CisJQVNTRVJUKG1fYklzU2V0dGluZyk7CisJcHBPYmogPSBDSlNfVmFsdWU6Om9wZXJhdG9yIENKU19PYmplY3QgKigpOworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yPDwoSlNGWE9iamVjdCBwT2JqKQoreworCUFTU0VSVCghbV9iSXNTZXR0aW5nKTsKKwlDSlNfVmFsdWU6Om9wZXJhdG9yID0gKHBPYmopOworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yPj4oSlNGWE9iamVjdCAmcHBPYmopIGNvbnN0Cit7CisJQVNTRVJUKG1fYklzU2V0dGluZyk7CisJcHBPYmogPSBDSlNfVmFsdWU6Om9wZXJhdG9yIEpTRlhPYmplY3QgKCk7Cit9CisKKwordm9pZCBDSlNfUHJvcFZhbHVlOjpTdGFydFNldHRpbmcoKQoreworCW1fYklzU2V0dGluZyA9IDE7Cit9CisKK3ZvaWQgQ0pTX1Byb3BWYWx1ZTo6U3RhcnRHZXR0aW5nKCkKK3sKKwltX2JJc1NldHRpbmcgPSAwOworfQordm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvciA8PChDRlhfQnl0ZVN0cmluZyBzdHJpbmcpCit7CisJQVNTRVJUKCFtX2JJc1NldHRpbmcpOworCUNKU19WYWx1ZTo6b3BlcmF0b3IgPSgoRlhfTFBDU1RSKXN0cmluZyk7Cit9CisKK3ZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPj4oQ0ZYX0J5dGVTdHJpbmcgJnN0cmluZykgY29uc3QKK3sKKwlBU1NFUlQobV9iSXNTZXR0aW5nKTsKKwlzdHJpbmcgPSBDSlNfVmFsdWU6Om9wZXJhdG9yIENGWF9CeXRlU3RyaW5nKCk7Cit9CisKK3ZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPDwoRlhfTFBDV1NUUiBjX3N0cmluZykKK3sKKwlBU1NFUlQoIW1fYklzU2V0dGluZyk7CisJQ0pTX1ZhbHVlOjpvcGVyYXRvciA9KGNfc3RyaW5nKTsKK30KKwordm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvciA+PihDRlhfV2lkZVN0cmluZyAmd2lkZV9zdHJpbmcpIGNvbnN0Cit7CisJQVNTRVJUKG1fYklzU2V0dGluZyk7CisJd2lkZV9zdHJpbmcgPSBDSlNfVmFsdWU6Om9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7Cit9CisKK3ZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3IgPDwoQ0ZYX1dpZGVTdHJpbmcgd2lkZV9zdHJpbmcpCit7CisJQVNTRVJUKCFtX2JJc1NldHRpbmcpOworCUNKU19WYWx1ZTo6b3BlcmF0b3IgPSAod2lkZV9zdHJpbmcpOworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yID4+KENKU19BcnJheSAmYXJyYXkpIGNvbnN0Cit7CisJQVNTRVJUKG1fYklzU2V0dGluZyk7CisJQ29udmVydFRvQXJyYXkoYXJyYXkpOworfQorCit2b2lkIENKU19Qcm9wVmFsdWU6Om9wZXJhdG9yIDw8KENKU19BcnJheSAmYXJyYXkpCit7CisJQVNTRVJUKCFtX2JJc1NldHRpbmcpOworCUNKU19WYWx1ZTo6b3BlcmF0b3I9KGFycmF5KTsKK30KKwordm9pZCBDSlNfUHJvcFZhbHVlOjpvcGVyYXRvcj4+KENKU19EYXRlICZkYXRlKSBjb25zdAoreworCUFTU0VSVChtX2JJc1NldHRpbmcpOworCUNvbnZlcnRUb0RhdGUoZGF0ZSk7Cit9CisKK3ZvaWQgQ0pTX1Byb3BWYWx1ZTo6b3BlcmF0b3I8PChDSlNfRGF0ZSAmZGF0ZSkKK3sKKwlBU1NFUlQoIW1fYklzU2V0dGluZyk7CisJQ0pTX1ZhbHVlOjpvcGVyYXRvcj0oZGF0ZSk7Cit9CisKK0NKU19Qcm9wVmFsdWU6Om9wZXJhdG9yIHY4OjpIYW5kbGU8djg6OlZhbHVlPigpIGNvbnN0Cit7CisJcmV0dXJuIG1fcFZhbHVlOworfQorCisvKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IENKU19BcnJheSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLworQ0pTX0FycmF5OjpDSlNfQXJyYXkodjg6Oklzb2xhdGUqIGlzb2xhdGUpOm1faXNvbGF0ZShpc29sYXRlKQoreworfQorCitDSlNfQXJyYXk6On5DSlNfQXJyYXkoKQorewkJCit9CisKK3ZvaWQgQ0pTX0FycmF5OjpBdHRhY2godjg6OkhhbmRsZTx2ODo6QXJyYXk+IHBBcnJheSkKK3sKKwltX3BBcnJheSA9IHBBcnJheTsKK30KKworRlhfQk9PTCBDSlNfQXJyYXk6OklzQXR0YWNoZWQoKQoreworCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDSlNfQXJyYXk6OkdldEVsZW1lbnQodW5zaWduZWQgaW5kZXgsQ0pTX1ZhbHVlICZ2YWx1ZSkKK3sKKwlpZiAobV9wQXJyYXkuSXNFbXB0eSgpKQorCQlyZXR1cm47CisJdjg6OkhhbmRsZTx2ODo6VmFsdWU+ICBwID0gSlNfR2V0QXJyYXlFbGVtbmV0KG1fcEFycmF5LGluZGV4KTsKKwl2YWx1ZS5BdHRhY2gocCxWVF9vYmplY3QpOworfQorCit2b2lkIENKU19BcnJheTo6U2V0RWxlbWVudCh1bnNpZ25lZCBpbmRleCxDSlNfVmFsdWUgdmFsdWUpCit7CisJaWYgKG1fcEFycmF5LklzRW1wdHkoKSkKKwkJbV9wQXJyYXkgPSBKU19OZXdBcnJheShtX2lzb2xhdGUpOworCisJSlNfUHV0QXJyYXlFbGVtZW50KG1fcEFycmF5LGluZGV4LHZhbHVlLlRvSlNWYWx1ZSgpLHZhbHVlLkdldFR5cGUoKSk7Cit9CisKK2ludCBDSlNfQXJyYXk6OkdldExlbmd0aCgpCit7CisJaWYgKG1fcEFycmF5LklzRW1wdHkoKSkKKwkJcmV0dXJuIDA7CisJcmV0dXJuIEpTX0dldEFycmF5TGVuZ3RoKG1fcEFycmF5KTsKK30KKworQ0pTX0FycmF5Ojogb3BlcmF0b3Igdjg6OkhhbmRsZTx2ODo6QXJyYXk+KCkKK3sKKwlpZiAobV9wQXJyYXkuSXNFbXB0eSgpKQorCQltX3BBcnJheSA9IEpTX05ld0FycmF5KG1faXNvbGF0ZSk7CisKKwlyZXR1cm4gbV9wQXJyYXk7Cit9CisKKy8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gQ0pTX0RhdGUgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KKworQ0pTX0RhdGU6OkNKU19EYXRlKHY4OjpJc29sYXRlKiBpc29sYXRlKSA6bV9pc29sYXRlKGlzb2xhdGUpCit7Cit9CisKK0NKU19EYXRlOjpDSlNfRGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSxkb3VibGUgZE1zZWNfdGltZSkgCit7CisJbV9pc29sYXRlID0gaXNvbGF0ZTsKKwltX3BEYXRlID0gSlNfTmV3RGF0ZShpc29sYXRlLGRNc2VjX3RpbWUpOwkJCit9CisKK0NKU19EYXRlOjpDSlNfRGF0ZSh2ODo6SXNvbGF0ZSogaXNvbGF0ZSxpbnQgeWVhciwgaW50IG1vbiwgaW50IGRheSxpbnQgaG91ciwgaW50IG1pbiwgaW50IHNlYykgCit7CisJbV9pc29sYXRlID0gaXNvbGF0ZTsKKwltX3BEYXRlID0gSlNfTmV3RGF0ZShpc29sYXRlLE1ha2VEYXRlKHllYXIsbW9uLGRheSxob3VyLG1pbixzZWMsMCkpOwkKK30KKworZG91YmxlIENKU19EYXRlOjpNYWtlRGF0ZShpbnQgeWVhciwgaW50IG1vbiwgaW50IGRheSxpbnQgaG91ciwgaW50IG1pbiwgaW50IHNlYyxpbnQgbXMpCit7CisJcmV0dXJuIEpTX01ha2VEYXRlKEpTX01ha2VEYXkoeWVhcixtb24sZGF5KSwgSlNfTWFrZVRpbWUoaG91cixtaW4sc2VjLG1zKSk7Cit9CisKK0NKU19EYXRlOjp+Q0pTX0RhdGUoKQoreworfQorCitGWF9CT09MCUNKU19EYXRlOjpJc1ZhbGlkRGF0ZSgpCit7CisJaWYobV9wRGF0ZS5Jc0VtcHR5KCkpIHJldHVybiBGQUxTRTsKKwlyZXR1cm4gIUpTX1BvcnRJc05hbihKU19Ub051bWJlcihtX3BEYXRlKSk7Cit9CisKK3ZvaWQgQ0pTX0RhdGU6OkF0dGFjaCh2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcERhdGUpCit7CisJbV9wRGF0ZSA9IHBEYXRlOworfQorCitpbnQgQ0pTX0RhdGU6OkdldFllYXIoKQoreworCWlmIChJc1ZhbGlkRGF0ZSgpKQorCQlyZXR1cm4gSlNfR2V0WWVhckZyb21UaW1lKEpTX0xvY2FsVGltZShKU19Ub051bWJlcihtX3BEYXRlKSkpOworCisJcmV0dXJuIDA7Cit9CisKK3ZvaWQgQ0pTX0RhdGU6OlNldFllYXIoaW50IGlZZWFyKQoreworCWRvdWJsZSBkYXRlID0gTWFrZURhdGUoaVllYXIsR2V0TW9udGgoKSxHZXREYXkoKSxHZXRIb3VycygpLEdldE1pbnV0ZXMoKSxHZXRTZWNvbmRzKCksMCk7CisJSlNfVmFsdWVDb3B5KG1fcERhdGUsIEpTX05ld0RhdGUobV9pc29sYXRlLGRhdGUpKTsKK30KKworaW50IENKU19EYXRlOjpHZXRNb250aCgpCit7CisJaWYgKElzVmFsaWREYXRlKCkpCisJCXJldHVybiBKU19HZXRNb250aEZyb21UaW1lKEpTX0xvY2FsVGltZShKU19Ub051bWJlcihtX3BEYXRlKSkpOworCisJcmV0dXJuIDA7Cit9CisKK3ZvaWQgQ0pTX0RhdGU6OlNldE1vbnRoKGludCBpTW9udGgpCit7CisKKwlkb3VibGUgZGF0ZSA9IE1ha2VEYXRlKEdldFllYXIoKSxpTW9udGgsR2V0RGF5KCksR2V0SG91cnMoKSxHZXRNaW51dGVzKCksR2V0U2Vjb25kcygpLDApOworCUpTX1ZhbHVlQ29weShtX3BEYXRlLCBKU19OZXdEYXRlKG1faXNvbGF0ZSxkYXRlKSk7CisKK30KKworaW50IENKU19EYXRlOjpHZXREYXkoKQoreworCWlmIChJc1ZhbGlkRGF0ZSgpKQorCQlyZXR1cm4gSlNfR2V0RGF5RnJvbVRpbWUoSlNfTG9jYWxUaW1lKEpTX1RvTnVtYmVyKG1fcERhdGUpKSk7CisKKwlyZXR1cm4gMDsKK30KKwordm9pZCBDSlNfRGF0ZTo6U2V0RGF5KGludCBpRGF5KQoreworCisJZG91YmxlIGRhdGUgPSBNYWtlRGF0ZShHZXRZZWFyKCksR2V0TW9udGgoKSxpRGF5LEdldEhvdXJzKCksR2V0TWludXRlcygpLEdldFNlY29uZHMoKSwwKTsKKwlKU19WYWx1ZUNvcHkobV9wRGF0ZSxKU19OZXdEYXRlKG1faXNvbGF0ZSxkYXRlKSk7CisKK30KKworaW50IENKU19EYXRlOjpHZXRIb3VycygpCit7CisJaWYgKElzVmFsaWREYXRlKCkpCisJCXJldHVybiBKU19HZXRIb3VyRnJvbVRpbWUoSlNfTG9jYWxUaW1lKEpTX1RvTnVtYmVyKG1fcERhdGUpKSk7CisKKwlyZXR1cm4gMDsKK30KKwordm9pZCBDSlNfRGF0ZTo6U2V0SG91cnMoaW50IGlIb3VycykKK3sKKwlkb3VibGUgZGF0ZSA9IE1ha2VEYXRlKEdldFllYXIoKSxHZXRNb250aCgpLEdldERheSgpLGlIb3VycyxHZXRNaW51dGVzKCksR2V0U2Vjb25kcygpLDApOworCUpTX1ZhbHVlQ29weShtX3BEYXRlLEpTX05ld0RhdGUobV9pc29sYXRlLGRhdGUpKTsKK30KKworaW50IENKU19EYXRlOjpHZXRNaW51dGVzKCkKK3sKKwlpZiAoSXNWYWxpZERhdGUoKSkKKwkJcmV0dXJuIEpTX0dldE1pbkZyb21UaW1lKEpTX0xvY2FsVGltZShKU19Ub051bWJlcihtX3BEYXRlKSkpOworCisJcmV0dXJuIDA7Cit9CisKK3ZvaWQgQ0pTX0RhdGU6OlNldE1pbnV0ZXMoaW50IG1pbnV0ZXMpCit7CisJZG91YmxlIGRhdGUgPSBNYWtlRGF0ZShHZXRZZWFyKCksR2V0TW9udGgoKSxHZXREYXkoKSxHZXRIb3VycygpLG1pbnV0ZXMsR2V0U2Vjb25kcygpLDApOworCUpTX1ZhbHVlQ29weShtX3BEYXRlLEpTX05ld0RhdGUobV9pc29sYXRlLGRhdGUpKTsKK30KKworaW50IENKU19EYXRlOjpHZXRTZWNvbmRzKCkKK3sKKwlpZiAoSXNWYWxpZERhdGUoKSkKKwkJcmV0dXJuIEpTX0dldFNlY0Zyb21UaW1lKEpTX0xvY2FsVGltZShKU19Ub051bWJlcihtX3BEYXRlKSkpOworCisJcmV0dXJuIDA7Cit9CisKK3ZvaWQgQ0pTX0RhdGU6OlNldFNlY29uZHMoaW50IHNlY29uZHMpCit7CisJZG91YmxlIGRhdGUgPSBNYWtlRGF0ZShHZXRZZWFyKCksR2V0TW9udGgoKSxHZXREYXkoKSxHZXRIb3VycygpLEdldE1pbnV0ZXMoKSxzZWNvbmRzLDApOworCUpTX1ZhbHVlQ29weShtX3BEYXRlLEpTX05ld0RhdGUobV9pc29sYXRlLGRhdGUpKTsKK30KKworQ0pTX0RhdGU6Om9wZXJhdG9yIHY4OjpIYW5kbGU8djg6OlZhbHVlPigpCit7CisJcmV0dXJuIG1fcERhdGU7Cit9CisKK0NKU19EYXRlOjpvcGVyYXRvciBkb3VibGUoKSBjb25zdAoreworCWlmKG1fcERhdGUuSXNFbXB0eSgpKQorCQlyZXR1cm4gMC4wOworCXJldHVybiBKU19Ub051bWJlcihtX3BEYXRlKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ0pTX0RhdGU6OlRvU3RyaW5nKCkgY29uc3QKK3sKKwlpZihtX3BEYXRlLklzRW1wdHkoKSkKKwkJcmV0dXJuIEwiIjsKKwlyZXR1cm4gSlNfVG9TdHJpbmcobV9wRGF0ZSk7Cit9CmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuY3BwIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9QdWJsaWNNZXRob2RzLmNwcAppbmRleCBjMzljOGEwLi5iZDRhY2FlIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvUHVibGljTWV0aG9kcy5jcHAKQEAgLTEsMjMzNSArMSwyMzM1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvcmVzb3VyY2UuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC91dGlsLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvY29sb3IuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCINCi0NCi1zdGF0aWMgdjg6Oklzb2xhdGUqIEdldElzb2xhdGUoSUZYSlNfQ29udGV4dCogY2MpDQotew0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0NCi0JcmV0dXJuIHBSdW50aW1lLT5HZXRJc29sYXRlKCk7DQotfQ0KLQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENKU19QdWJsaWNNZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotI2RlZmluZSBET1VCTEVfQ09SUkVDVAkwLjAwMDAwMDAwMDAwMDAwMQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19HTE9CQUxfRlVOKENKU19QdWJsaWNNZXRob2RzKQ0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk51bWJlcl9Gb3JtYXQsNikNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZOdW1iZXJfS2V5c3Ryb2tlLDYpDQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGUGVyY2VudF9Gb3JtYXQsMikNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0tleXN0cm9rZSwyKQ0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRkRhdGVfRm9ybWF0RXgsMSkNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZEYXRlX0tleXN0cm9rZUV4LDEpDQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRGF0ZV9Gb3JtYXQsMSkNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZEYXRlX0tleXN0cm9rZSwxKQ0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfRm9ybWF0RXgsMSkNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZUaW1lX0tleXN0cm9rZUV4LDEpDQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGVGltZV9Gb3JtYXQsMSkNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZUaW1lX0tleXN0cm9rZSwxKQ0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfRm9ybWF0LDEpDQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU3BlY2lhbF9LZXlzdHJva2UsMSkNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZTcGVjaWFsX0tleXN0cm9rZUV4LDEpDQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlLDMpDQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGTWFrZU51bWJlciwxKQ0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNpbXBsZV9DYWxjdWxhdGUsMikNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZSYW5nZV9WYWxpZGF0ZSw0KQ0KLQlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk1lcmdlQ2hhbmdlLDEpDQotCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGUGFyc2VEYXRlRXgsMikNCi0JSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZFeHRyYWN0TnVtcywxKQ0KLUVORF9KU19TVEFUSUNfR0xPQkFMX0ZVTigpDQotDQotSU1QTEVNRU5UX0pTX1NUQVRJQ19HTE9CQUxfRlVOKENKU19QdWJsaWNNZXRob2RzKQ0KLQ0KLXN0cnVjdCBzdHJ1X1RiQ29udmVydA0KLXsNCi0JRlhfTFBDU1RSIGxwc3pKU01hcms7DQotCUZYX0xQQ1NUUiBscHN6Q3BwTWFyazsNCi19Ow0KLQ0KLXN0YXRpYyBjb25zdCBzdHJ1X1RiQ29udmVydCBmY1RhYmxlW10gPSB7Im1tbW0iLCIlQiIsDQotCSJtbW0iLCAiJWIiLA0KLQkibW0iLCAgIiVtIiwNCi0JLy8ibSINCi0JImRkZGQiLCIlQSIsDQotCSJkZGQiLCAiJWEiLA0KLQkiZGQiLCAgIiVkIiwNCi0JLy8iZCIsICAgIiV3IiwNCi0JInl5eXkiLCIlWSIsDQotCSJ5eSIsICAiJXkiLA0KLQkiSEgiLCAgIiVIIiwNCi0JLy8iSCINCi0JImhoIiwgICIlSSIsDQotCS8vImgiDQotCSJNTSIsICAiJU0iLA0KLQkvLyJNIg0KLQkic3MiLCAgIiVTIiwNCi0JLy8icw0KLQkidHQiLCAgIiVwIg0KLQkvLyJ0Ig0KLX07DQotDQotc3RhdGljIEZYX0xQQ1dTVFIgbW9udGhzW10gPQ0KLXsNCi0JKEZYX0xQQ1dTVFIpTCJKYW4iLCAoRlhfTFBDV1NUUilMIkZlYiIsIChGWF9MUENXU1RSKUwiTWFyIiwgKEZYX0xQQ1dTVFIpTCJBcHIiLCAoRlhfTFBDV1NUUilMIk1heSIsIChGWF9MUENXU1RSKUwiSnVuIiwgKEZYX0xQQ1dTVFIpTCJKdWwiLCAoRlhfTFBDV1NUUilMIkF1ZyIsIChGWF9MUENXU1RSKUwiU2VwIiwgKEZYX0xQQ1dTVFIpTCJPY3QiLCAoRlhfTFBDV1NUUilMIk5vdiIsIChGWF9MUENXU1RSKUwiRGVjIg0KLX07DQotDQotc3RhdGljIEZYX0xQQ1dTVFIgZnVsbG1vbnRoc1tdID0gDQoteyANCi0JKEZYX0xQQ1dTVFIpTCJKYW51YXJ5IiwgKEZYX0xQQ1dTVFIpTCJGZWJydWFyeSIsIChGWF9MUENXU1RSKUwiTWFyY2giLCAoRlhfTFBDV1NUUilMIkFwcmlsIiwgKEZYX0xQQ1dTVFIpTCJNYXkiLCAoRlhfTFBDV1NUUilMIkp1bmUiLCAoRlhfTFBDV1NUUilMIkp1bHkiLCAoRlhfTFBDV1NUUilMIkF1Z3VzdCIsIChGWF9MUENXU1RSKUwiU2VwdGVtYmVyIiwgKEZYX0xQQ1dTVFIpTCJPY3RvYmVyIiwgKEZYX0xQQ1dTVFIpTCJOb3ZlbWJlciIsIChGWF9MUENXU1RSKUwiRGVjZW1iZXIiIA0KLX07DQotDQotRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNOdW1iZXIoRlhfTFBDV1NUUiBzdHJpbmcpDQotew0KLQlDRlhfV2lkZVN0cmluZyBzVHJpbSA9IFN0clRyaW0oc3RyaW5nKTsNCi0JRlhfTFBDV1NUUiBwVHJpbSA9IHNUcmltOw0KLQlGWF9MUENXU1RSIHAgPSBwVHJpbTsNCi0NCi0NCi0JRlhfQk9PTCBiRG90ID0gRkFMU0U7DQotCUZYX0JPT0wgYktYSlMgPSBGQUxTRTsNCi0NCi0Jd2NoYXJfdCBjOw0KLQl3aGlsZSAoKGMgPSAqcCkpDQotCXsNCi0JCWlmIChjID09ICcuJyB8fCBjID09ICcsJykNCi0JCXsNCi0JCQlpZiAoYkRvdCkgcmV0dXJuIEZBTFNFOw0KLQkJCWJEb3QgPSBUUlVFOw0KLQkJfQ0KLQkJZWxzZSBpZiAoYyA9PSAnLScgfHwgYyA9PSAnKycpDQotCQl7DQotCQkJaWYgKHAgIT0gcFRyaW0pDQotCQkJCXJldHVybiBGQUxTRTsNCi0JCX0NCi0JCWVsc2UgaWYgKGMgPT0gJ2UnIHx8IGMgPT0gJ0UnKQ0KLQkJew0KLQkJCWlmIChiS1hKUykgcmV0dXJuIEZBTFNFOw0KLQ0KLQkJCXArKzsNCi0JCQljID0gKnA7DQotCQkJaWYgKGMgPT0gJysnIHx8IGMgPT0gJy0nKQ0KLQkJCXsNCi0JCQkJYktYSlMgPSBUUlVFOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlyZXR1cm4gRkFMU0U7DQotCQkJfQ0KLQkJfQ0KLQkJZWxzZSBpZiAoIUlzRGlnaXQoYykpDQotCQl7DQotCQkJcmV0dXJuIEZBTFNFOw0KLQkJfQ0KLQkJcCsrOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpJc0RpZ2l0KHdjaGFyX3QgY2gpDQotew0KLQlyZXR1cm4gKGNoID49IEwnMCcgJiYgY2ggPD0gTCc5Jyk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzRGlnaXQoY2hhciBjaCkNCi17DQotCXJldHVybiAoY2ggPj0gJzAnICYmIGNoIDw9ICc5Jyk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzQWxwaGFiZXRpYyh3Y2hhcl90IGNoKQ0KLXsNCi0JcmV0dXJuICgoY2ggPj0gTCdhJyAmJiBjaCA8PSBMJ3onKSB8fCAoY2ggPj0gTCdBJyAmJiBjaCA8PSBMJ1onKSk7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzQWxwaGFOdW1lcmljKHdjaGFyX3QgY2gpDQotew0KLQlyZXR1cm4gKElzRGlnaXQoY2gpIHx8IElzQWxwaGFiZXRpYyhjaCkpOw0KLX0NCi0NCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjptYXNrU2F0aXNmaWVkKHdjaGFyX3QgY19DaGFuZ2Usd2NoYXJfdCBjX01hc2spDQotew0KLQlzd2l0Y2ggKGNfTWFzaykNCi0Jew0KLQljYXNlIEwnOSc6DQotICAgICAgICByZXR1cm4gSXNEaWdpdChjX0NoYW5nZSk7CQkNCi0gICAgY2FzZSBMJ0EnOg0KLSAgICAgICAgcmV0dXJuIElzQWxwaGFiZXRpYyhjX0NoYW5nZSk7CQkNCi0gICAgY2FzZSBMJ08nOg0KLSAgICAgICAgcmV0dXJuIElzQWxwaGFOdW1lcmljKGNfQ2hhbmdlKTsJCQ0KLSAgICBjYXNlIEwnWCc6DQotICAgICAgICByZXR1cm4gVFJVRTsJCQ0KLQlkZWZhdWx0Og0KLSAgICAgICAgcmV0dXJuIChjX0NoYW5nZSA9PSBjX01hc2spOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OmlzUmVzZXJ2ZWRNYXNrQ2hhcih3Y2hhcl90IGNoKQ0KLXsNCi0JcmV0dXJuIGNoID09IEwnOScgfHwgY2ggPT0gTCdBJyB8fCBjaCA9PSBMJ08nIHx8IGNoID09IEwnWCc7DQotfQ0KLQ0KLWRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6QUZfU2ltcGxlKEZYX0xQQ1dTVFIgc0Z1Y3Rpb24sIGRvdWJsZSBkVmFsdWUxLCBkb3VibGUgZFZhbHVlMikNCi17DQotCWlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiQVZHIikgPT0gMCB8fCBGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiU1VNIikgPT0gMCkNCi0Jew0KLQkJcmV0dXJuIGRWYWx1ZTEgKyBkVmFsdWUyOw0KLQl9DQotCWVsc2UgaWYgKEZYU1lTX3djc2ljbXAoc0Z1Y3Rpb24sIChGWF9MUENXU1RSKUwiUFJEIikgPT0gMCkNCi0Jew0KLQkJcmV0dXJuIGRWYWx1ZTEgKiBkVmFsdWUyOw0KLQl9DQotCWVsc2UgaWYgKEZYU1lTX3djc2ljbXAoc0Z1Y3Rpb24sKEZYX0xQQ1dTVFIpTCJNSU4iKSA9PSAwKQ0KLQl7DQotCQlyZXR1cm4gRlhfTUlOKGRWYWx1ZTEsIGRWYWx1ZTIpOw0KLQl9DQotCWVsc2UgaWYgKEZYU1lTX3djc2ljbXAoc0Z1Y3Rpb24sKEZYX0xQQ1dTVFIpTCJNQVgiKSA9PSAwKQ0KLQl7DQotCQlyZXR1cm4gRlhfTUFYKGRWYWx1ZTEsIGRWYWx1ZTIpOw0KLQl9DQotDQotCXJldHVybiBkVmFsdWUxOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyTFRyaW0oRlhfTFBDV1NUUiBwU3RyKQ0KLXsNCi0Jd2hpbGUgKCpwU3RyICYmICpwU3RyID09IEwnICcpIHBTdHIrKzsNCi0NCi0JcmV0dXJuIHBTdHI7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJSVHJpbShGWF9MUENXU1RSIHBTdHIpDQotew0KLQlGWF9MUENXU1RSIHAgPSBwU3RyOw0KLQ0KLQl3aGlsZSAoKnApIHArKzsNCi0JcC0tOw0KLQlpZiAocCA+PSBwU3RyKQ0KLQl7CQkNCi0JCXdoaWxlICgqcCAmJiAqcCA9PSBMJyAnKSBwLS07DQotCQlwKys7DQotCQlyZXR1cm4gQ0ZYX1dpZGVTdHJpbmcocFN0cixwLXBTdHIpOw0KLQl9DQotCXJldHVybiBMIiI7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJUcmltKEZYX0xQQ1dTVFIgcFN0cikNCi17DQotCXJldHVybiBTdHJSVHJpbShTdHJMVHJpbShwU3RyKSk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJMVHJpbShGWF9MUENTVFIgcFN0cikNCi17DQotCXdoaWxlICgqcFN0ciAmJiAqcFN0ciA9PSAnICcpIHBTdHIrKzsNCi0NCi0gICAgcmV0dXJuIHBTdHI7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJSVHJpbShGWF9MUENTVFIgcFN0cikNCi17DQotCUZYX0xQQ1NUUiBwID0gcFN0cjsNCi0NCi0Jd2hpbGUgKCpwKSBwKys7DQotCXAtLTsNCi0JaWYgKHAgPj0gcFN0cikNCi0JewkJDQotCQl3aGlsZSAoKnAgJiYgKnAgPT0gJyAnKSBwLS07DQotCQlwKys7DQotCQlyZXR1cm4gQ0ZYX0J5dGVTdHJpbmcocFN0cixwLXBTdHIpOw0KLQl9DQotCXJldHVybiAiIjsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlN0clRyaW0oRlhfTFBDU1RSIHBTdHIpDQotew0KLQlyZXR1cm4gU3RyUlRyaW0oU3RyTFRyaW0ocFN0cikpOw0KLX0NCi0NCi1kb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlTnVtYmVyKEZYX0xQQ1dTVFIgc3dTb3VyY2UsIEZYX0JPT0wmIGJBbGxEaWdpdHMsIEZYX0JPT0wmIGJEb3QsIEZYX0JPT0wmIGJTaWduLCBGWF9CT09MJiBiS1hKUykNCi17DQotCWJEb3QgPSBGQUxTRTsNCi0JYlNpZ24gPSBGQUxTRTsNCi0JYktYSlMgPSBGQUxTRTsNCi0NCi0JRlhfQk9PTCBiRGlnaXRFeGlzdCA9IEZBTFNFOw0KLQ0KLQlGWF9MUENXU1RSIHAgPSBzd1NvdXJjZTsNCi0Jd2NoYXJfdCBjOw0KLQ0KLQlGWF9MUENXU1RSIHBTdGFydCA9IE5VTEw7DQotCUZYX0xQQ1dTVFIgcEVuZCA9IE5VTEw7DQotDQotCXdoaWxlICgoYyA9ICpwKSkNCi0Jew0KLQkJaWYgKCFwU3RhcnQgJiYgYyAhPSBMJyAnKQ0KLQkJew0KLQkJCXBTdGFydCA9IHA7DQotCQl9DQotDQotCQlwRW5kID0gcDsNCi0JCXArKzsNCi0JfQ0KLQ0KLQlpZiAoIXBTdGFydCkNCi0Jew0KLQkJYkFsbERpZ2l0cyA9IEZBTFNFOw0KLQkJcmV0dXJuIDA7DQotCX0NCi0NCi0Jd2hpbGUgKHBFbmQgIT0gcFN0YXJ0KQ0KLQl7DQotCQlpZiAoKnBFbmQgPT0gTCcgJykNCi0JCQlwRW5kIC0tOw0KLQkJZWxzZQ0KLQkJCWJyZWFrOw0KLQl9DQotDQotCWRvdWJsZSBkUmV0ID0gMDsNCi0JcCA9IHBTdGFydDsNCi0JYkFsbERpZ2l0cyA9IFRSVUU7DQotCUNGWF9XaWRlU3RyaW5nIHN3RGlnaXRzOw0KLQ0KLQl3aGlsZSAocCA8PSBwRW5kKQ0KLQl7CQ0KLQkJYyA9ICpwOw0KLQ0KLQkJaWYgKElzRGlnaXQoYykpDQotCQl7DQotCQkJc3dEaWdpdHMgKz0gYzsNCi0JCQliRGlnaXRFeGlzdCA9IFRSVUU7DQotCQl9DQotCQllbHNlIA0KLQkJew0KLQkJCXN3aXRjaCAoYykNCi0JCQl7DQotCQkJY2FzZSBMJyAnOg0KLQkJCQliQWxsRGlnaXRzID0gRkFMU0U7DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgTCcuJzoNCi0JCQljYXNlIEwnLCc6DQotCQkJCWlmICghYkRvdCkNCi0JCQkJew0KLQkJCQkJaWYgKGJEaWdpdEV4aXN0KQ0KLQkJCQkJew0KLQkJCQkJCXN3RGlnaXRzICs9IEwnLic7DQotCQkJCQl9DQotCQkJCQllbHNlDQotCQkJCQl7DQotCQkJCQkJc3dEaWdpdHMgKz0gTCcwJzsNCi0JCQkJCQlzd0RpZ2l0cyArPSBMJy4nOw0KLQkJCQkJCWJEaWdpdEV4aXN0ID0gVFJVRTsNCi0JCQkJCX0NCi0NCi0JCQkJCWJEb3QgPSBUUlVFOw0KLQkJCQkJYnJlYWs7DQotCQkJCX0NCi0JCQljYXNlICdlJzoNCi0JCQljYXNlICdFJzoNCi0JCQkJaWYgKCFiS1hKUykNCi0JCQkJew0KLQkJCQkJcCsrOw0KLQkJCQkJYyA9ICpwOw0KLQkJCQkJaWYgKGMgPT0gJysnIHx8IGMgPT0gJy0nKQ0KLQkJCQkJew0KLQkJCQkJCWJLWEpTID0gVFJVRTsNCi0JCQkJCQlzd0RpZ2l0cyArPSAnZSc7DQotCQkJCQkJc3dEaWdpdHMgKz0gYzsNCi0JCQkJCX0NCi0JCQkJCWJyZWFrOw0KLQkJCQl9DQotCQkJY2FzZSBMJy0nOg0KLQkJCQlpZiAoIWJEaWdpdEV4aXN0ICYmICFiU2lnbikNCi0JCQkJew0KLQkJCQkJc3dEaWdpdHMgKz0gYzsNCi0JCQkJCWJTaWduID0gVFJVRTsNCi0JCQkJCWJyZWFrOw0KLQkJCQl9DQotCQkJZGVmYXVsdDoNCi0JCQkJYkFsbERpZ2l0cyA9IEZBTFNFOw0KLQ0KLQkJCQlpZiAocCAhPSBwU3RhcnQgJiYgIWJEb3QgJiYgYkRpZ2l0RXhpc3QpDQotCQkJCXsNCi0JCQkJCXN3RGlnaXRzICs9IEwnLic7DQotCQkJCQliRG90ID0gVFJVRTsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsNCi0JCQkJCWJEb3QgPSBGQUxTRTsNCi0JCQkJCWJEaWdpdEV4aXN0ID0gRkFMU0U7DQotCQkJCQlzd0RpZ2l0cyA9IEwiIjsNCi0JCQkJfQ0KLQkJCQlicmVhazsNCi0JCQl9DQotCQl9DQotDQotCQlwKys7DQotCX0NCi0NCi0JaWYgKHN3RGlnaXRzLkdldExlbmd0aCgpID4gMCAmJiBzd0RpZ2l0cy5HZXRMZW5ndGgoKSA8IDE3KQ0KLQl7DQotCQlDRlhfQnl0ZVN0cmluZyBzRGlnaXRzID0gc3dEaWdpdHMuVVRGOEVuY29kZSgpOw0KLQ0KLQkJaWYgKGJLWEpTKQ0KLQkJew0KLQkJCWRSZXQgPSBhdG9mKHNEaWdpdHMpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChiRG90KQ0KLQkJCXsNCi0JCQkJY2hhciogcFN0b3BTdHJpbmc7DQotCQkJCWRSZXQgPSA6OnN0cnRvZChzRGlnaXRzLCAmcFN0b3BTdHJpbmcpOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlkUmV0ID0gYXRvbChzRGlnaXRzKTsNCi0JCQl9DQotCQl9DQotDQotCX0NCi0NCi0JcmV0dXJuIGRSZXQ7DQotfQ0KLQ0KLWRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VTdHJpbmdUb051bWJlcihGWF9MUENXU1RSIHN3U291cmNlKQ0KLXsNCi0JRlhfQk9PTCBiQWxsRGlnaXRzID0gRkFMU0U7DQotCUZYX0JPT0wgYkRvdCA9IEZBTFNFOw0KLQlGWF9CT09MIGJTaWduID0gRkFMU0U7DQotCUZYX0JPT0wgYktYSlMgPSBGQUxTRTsNCi0NCi0JcmV0dXJuIFBhcnNlTnVtYmVyKHN3U291cmNlLCBiQWxsRGlnaXRzLCBiRG90LCBiU2lnbiwgYktYSlMpOw0KLX0NCi0NCi1GWF9CT09MCUNKU19QdWJsaWNNZXRob2RzOjpDb252ZXJ0U3RyaW5nVG9OdW1iZXIoRlhfTFBDV1NUUiBzd1NvdXJjZSwgZG91YmxlICYgZFJldCwgRlhfQk9PTCAmIGJEb3QpDQotew0KLQlGWF9CT09MIGJBbGxEaWdpdHMgPSBGQUxTRTsNCi0JRlhfQk9PTCBiU2lnbiA9IEZBTFNFOw0KLQlGWF9CT09MIGJLWEpTID0gRkFMU0U7DQotDQotCWRSZXQgPSBQYXJzZU51bWJlcihzd1NvdXJjZSwgYkFsbERpZ2l0cywgYkRvdCwgYlNpZ24sIGJLWEpTKTsNCi0NCi0JcmV0dXJuIGJBbGxEaWdpdHM7DQotfQ0KLQ0KLUNKU19BcnJheSBDSlNfUHVibGljTWV0aG9kczo6QUZfTWFrZUFycmF5RnJvbUxpc3Qodjg6Oklzb2xhdGUqIGlzb2xhdGUsIENKU19WYWx1ZSB2YWwpDQotew0KLQlDSlNfQXJyYXkgU3RyQXJyYXkoaXNvbGF0ZSk7DQotCWlmKHZhbC5Jc0FycmF5T2JqZWN0KCkpDQotCXsNCi0JCXZhbC5Db252ZXJ0VG9BcnJheShTdHJBcnJheSk7DQotCQlyZXR1cm4gU3RyQXJyYXk7DQotCX0NCi0JQ0ZYX1dpZGVTdHJpbmcgd3NTdHIgPSB2YWwub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgdCA9IENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZSh3c1N0cik7DQotCWNvbnN0IGNoYXIgKiBwID0gKGNvbnN0IGNoYXIgKil0Ow0KLQ0KLQ0KLQlpbnQgY2ggPSAnLCcgOw0KLQlpbnQgbkluZGV4ID0gMDsNCi0NCi0Jd2hpbGUgKCpwKQ0KLQl7DQotCQljb25zdCBjaGFyICogcFRlbXAgPSBzdHJjaHIocCwgY2gpOw0KLQkJaWYgKHBUZW1wID09IE5VTEwpDQotCQl7DQotCQkJU3RyQXJyYXkuU2V0RWxlbWVudChuSW5kZXgsIENKU19WYWx1ZShpc29sYXRlLChGWF9MUENTVFIpU3RyVHJpbShwKSkpOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWNoYXIgKiBwU3ViID0gbmV3IGNoYXJbcFRlbXAgLSBwICsgMV07DQotCQkJc3RybmNweShwU3ViLCBwLCBwVGVtcCAtIHApOw0KLQkJCSoocFN1YiArIChwVGVtcCAtIHApKSA9ICdcMCc7DQotDQotCQkJU3RyQXJyYXkuU2V0RWxlbWVudChuSW5kZXgsIENKU19WYWx1ZShpc29sYXRlLChGWF9MUENTVFIpU3RyVHJpbShwU3ViKSkpOw0KLQkJCWRlbGV0ZSBbXXBTdWI7DQotCQkJDQotCQkJbkluZGV4ICsrOw0KLQkJCXAgPSArK3BUZW1wOw0KLQkJfQ0KLQkJDQotCX0NCi0JcmV0dXJuIFN0ckFycmF5Ow0KLX0NCi0NCi1pbnQgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlU3RyaW5nSW50ZWdlcihjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nLGludCBuU3RhcnQsaW50JiBuU2tpcCwgaW50IG5NYXhTdGVwKQ0KLXsNCi0JaW50IG5SZXQgPSAwOw0KLQluU2tpcCA9IDA7DQotCWZvciAoaW50IGk9blN0YXJ0LCBzej1zdHJpbmcuR2V0TGVuZ3RoKCk7IGkgPCBzejsgaSsrKQ0KLQl7DQotCQlpZiAoaS1uU3RhcnQgPiAxMCkNCi0JCQlicmVhazsNCi0NCi0JCUZYX1dDSEFSIGMgPSBzdHJpbmcuR2V0QXQoaSk7DQotCQlpZiAoSXNEaWdpdCgod2NoYXJfdCljKSkNCi0JCXsNCi0JCQluUmV0ID0gblJldCAqIDEwICsgKGMgLSAnMCcpOw0KLQkJCW5Ta2lwID0gaSAtIG5TdGFydCArIDE7DQotCQkJaWYgKG5Ta2lwID49IG5NYXhTdGVwKSANCi0JCQkJYnJlYWs7DQotCQl9DQotCQllbHNlDQotCQkJYnJlYWs7DQotCX0NCi0NCi0JcmV0dXJuIG5SZXQ7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpQYXJzZVN0cmluZ1N0cmluZyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nLCBpbnQgblN0YXJ0LCBpbnQmIG5Ta2lwKQ0KLXsNCi0JQ0ZYX1dpZGVTdHJpbmcgc3dSZXQ7DQotCW5Ta2lwID0gMDsNCi0JZm9yIChpbnQgaT1uU3RhcnQsIHN6PXN0cmluZy5HZXRMZW5ndGgoKTsgaSA8IHN6OyBpKyspDQotCXsNCi0JCUZYX1dDSEFSIGMgPSBzdHJpbmcuR2V0QXQoaSk7DQotCQlpZiAoKGMgPj0gTCdhJyAmJiBjIDw9IEwneicpIHx8IChjID49IEwnQScgJiYgYyA8PSBMJ1onKSkNCi0JCXsNCi0JCQlzd1JldCArPSBjOw0KLQkJCW5Ta2lwID0gaSAtIG5TdGFydCArIDE7DQotCQl9DQotCQllbHNlDQotCQkJYnJlYWs7DQotCX0NCi0NCi0JcmV0dXJuIHN3UmV0Ow0KLX0NCi0NCi1kb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlTm9ybWFsRGF0ZShjb25zdCBDRlhfV2lkZVN0cmluZyAmIHZhbHVlLCBGWF9CT09MJiBiV3JvbmdGb3JtYXQpDQotew0KLQlkb3VibGUgZHQgPSBKU19HZXREYXRlVGltZSgpOw0KLQ0KLQlpbnQgblllYXIgPSBKU19HZXRZZWFyRnJvbVRpbWUoZHQpOw0KLQlpbnQgbk1vbnRoID0gSlNfR2V0TW9udGhGcm9tVGltZShkdCkgKyAxOw0KLQlpbnQgbkRheSA9IEpTX0dldERheUZyb21UaW1lKGR0KTsNCi0JaW50IG5Ib3VyID0gSlNfR2V0SG91ckZyb21UaW1lKGR0KTsNCi0JaW50IG5NaW4gPSBKU19HZXRNaW5Gcm9tVGltZShkdCk7DQotCWludCBuU2VjID0gSlNfR2V0U2VjRnJvbVRpbWUoZHQpOw0KLQ0KLQlpbnQgbnVtYmVyWzNdOw0KLQ0KLQlpbnQgblNraXAgPSAwOw0KLQlpbnQgbkxlbiA9IHZhbHVlLkdldExlbmd0aCgpOw0KLQlpbnQgbkluZGV4ID0gMDsNCi0JaW50IGkgPSAwOw0KLQl3aGlsZSAoaSA8IG5MZW4pDQotCXsNCi0JCWlmIChuSW5kZXggPiAyKSBicmVhazsNCi0NCi0JCUZYX1dDSEFSIGMgPSB2YWx1ZS5HZXRBdChpKTsNCi0JCWlmIChJc0RpZ2l0KCh3Y2hhcl90KWMpKQ0KLQkJew0KLQkJCW51bWJlcltuSW5kZXgrK10gPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGksIG5Ta2lwLCA0KTsNCi0JCQlpICs9IG5Ta2lwOwkJCQ0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWkgKys7DQotCQl9DQotCX0NCi0NCi0JaWYgKG5JbmRleCA9PSAyKQ0KLQl7DQotCQkvLyBjYXNlMjogbW9udGgvZGF5DQotCQkvLyBjYXNlMzogZGF5L21vbnRoDQotCQlpZiAoKG51bWJlclswXSA+PSAxICYmIG51bWJlclswXSA8PSAxMikgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAzMSkpDQotCQl7DQotCQkJbk1vbnRoID0gbnVtYmVyWzBdOw0KLQkJCW5EYXkgPSBudW1iZXJbMV07DQotCQl9DQotCQllbHNlIGlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDMxKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDEyKSkNCi0JCXsNCi0JCQluRGF5ID0gbnVtYmVyWzBdOw0KLQkJCW5Nb250aCA9IG51bWJlclsxXTsNCi0JCX0NCi0NCi0JCWJXcm9uZ0Zvcm1hdCA9IEZBTFNFOw0KLQl9DQotCWVsc2UgaWYgKG5JbmRleCA9PSAzKQ0KLQl7DQotCQkvLyBjYXNlMTogeWVhci9tb250aC9kYXkNCi0JCS8vIGNhc2UyOiBtb250aC9kYXkveWVhcg0KLQkJLy8gY2FzZTM6IGRheS9tb250aC95ZWFyDQotDQotCQlpZiAobnVtYmVyWzBdID4gMTIgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAxMikgJiYgKG51bWJlclsyXSA+PSAxICYmIG51bWJlclsyXSA8PSAzMSkpDQotCQl7DQotCQkJblllYXIgPSBudW1iZXJbMF07DQotCQkJbk1vbnRoID0gbnVtYmVyWzFdOw0KLQkJCW5EYXkgPSBudW1iZXJbMl07DQotCQl9DQotCQllbHNlIGlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDEyKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDMxKSAmJiBudW1iZXJbMl0gPiAzMSkNCi0JCXsNCi0JCQluTW9udGggPSBudW1iZXJbMF07DQotCQkJbkRheSA9IG51bWJlclsxXTsNCi0JCQluWWVhciA9IG51bWJlclsyXTsNCi0JCX0NCi0JCWVsc2UgaWYgKChudW1iZXJbMF0gPj0gMSAmJiBudW1iZXJbMF0gPD0gMzEpICYmIChudW1iZXJbMV0gPj0gMSAmJiBudW1iZXJbMV0gPD0gMTIpICYmIG51bWJlclsyXSA+IDMxKQ0KLQkJew0KLQkJCW5EYXkgPSBudW1iZXJbMF07DQotCQkJbk1vbnRoID0gbnVtYmVyWzFdOw0KLQkJCW5ZZWFyID0gbnVtYmVyWzJdOw0KLQkJfQ0KLQ0KLQkJYldyb25nRm9ybWF0ID0gRkFMU0U7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQliV3JvbmdGb3JtYXQgPSBUUlVFOw0KLQkJcmV0dXJuIGR0Ow0KLQl9DQotDQotCUNGWF9XaWRlU3RyaW5nIHN3VGVtcDsNCi0Jc3dUZW1wLkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkLyVkLyVkICVkOiVkOiVkIixuTW9udGgsbkRheSxuWWVhcixuSG91cixuTWluLG5TZWMpOw0KLQlyZXR1cm4gSlNfRGF0ZVBhcnNlKHN3VGVtcCk7DQotfQ0KLQ0KLWRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6TWFrZVJlZ3VsYXJEYXRlKGNvbnN0IENGWF9XaWRlU3RyaW5nICYgdmFsdWUsIGNvbnN0IENGWF9XaWRlU3RyaW5nICYgZm9ybWF0LCBGWF9CT09MJiBiV3JvbmdGb3JtYXQpDQotew0KLQlkb3VibGUgZHQgPSBKU19HZXREYXRlVGltZSgpOw0KLQ0KLQlpZiAoZm9ybWF0LklzRW1wdHkoKSB8fCB2YWx1ZS5Jc0VtcHR5KCkpDQotCQlyZXR1cm4gZHQ7DQotDQotCWludCBuWWVhciA9IEpTX0dldFllYXJGcm9tVGltZShkdCk7DQotCWludCBuTW9udGggPSBKU19HZXRNb250aEZyb21UaW1lKGR0KSArIDE7DQotCWludCBuRGF5ID0gSlNfR2V0RGF5RnJvbVRpbWUoZHQpOw0KLQlpbnQgbkhvdXIgPSBKU19HZXRIb3VyRnJvbVRpbWUoZHQpOw0KLQlpbnQgbk1pbiA9IEpTX0dldE1pbkZyb21UaW1lKGR0KTsNCi0JaW50IG5TZWMgPSBKU19HZXRTZWNGcm9tVGltZShkdCk7DQotDQotCWludCBuWWVhclN1YiA9IDk5OyAvL25ZZWFyIC0gMjAwMDsNCi0NCi0JRlhfQk9PTCBiUG0gPSBGQUxTRTsNCi0JRlhfQk9PTCBiRXhpdCA9IEZBTFNFOw0KLQliV3JvbmdGb3JtYXQgPSBGQUxTRTsNCi0JDQotCWludCBpPTA7DQotCWludCBqPTA7DQotDQotCXdoaWxlIChpIDwgZm9ybWF0LkdldExlbmd0aCgpKQ0KLQl7DQotCQlpZiAoYkV4aXQpIGJyZWFrOw0KLQ0KLQkJRlhfV0NIQVIgYyA9IGZvcm1hdC5HZXRBdChpKTsJCQ0KLQkJc3dpdGNoIChjKQ0KLQkJew0KLQkJCWNhc2UgJzonOg0KLQkJCWNhc2UgJy4nOg0KLQkJCWNhc2UgJy0nOg0KLQkJCWNhc2UgJ1xcJzoNCi0JCQljYXNlICcvJzoNCi0JCQkJaSsrOw0KLQkJCQlqKys7DQotCQkJCWJyZWFrOw0KLQkJCQkNCi0JCQljYXNlICd5JzoNCi0JCQljYXNlICdtJzoNCi0JCQljYXNlICdkJzoNCi0JCQljYXNlICdIJzoNCi0JCQljYXNlICdoJzoNCi0JCQljYXNlICdNJzoNCi0JCQljYXNlICdzJzoNCi0JCQljYXNlICd0JzoNCi0JCQkJew0KLQkJCQkJaW50IG9sZGogPSBqOw0KLQkJCQkJaW50IG5Ta2lwID0gMDsNCi0NCi0JCQkJCWlmIChmb3JtYXQuR2V0QXQoaSsxKSAhPSBjKQ0KLQkJCQkJew0KLQkJCQkJCXN3aXRjaCAoYykNCi0JCQkJCQl7DQotCQkJCQkJCWNhc2UgJ3knOg0KLQkJCQkJCQkJaSsrOw0KLQkJCQkJCQkJaisrOw0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCWNhc2UgJ20nOg0KLQkJCQkJCQkJbk1vbnRoID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7DQotCQkJCQkJCQlpKys7DQotCQkJCQkJCQlqICs9IG5Ta2lwOw0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCWNhc2UgJ2QnOg0KLQkJCQkJCQkJbkRheSA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOw0KLQkJCQkJCQkJaSsrOw0KLQkJCQkJCQkJaiArPSBuU2tpcDsNCi0JCQkJCQkJCWJyZWFrOw0KLQkJCQkJCQljYXNlICdIJzoNCi0JCQkJCQkJCW5Ib3VyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7DQotCQkJCQkJCQlpKys7DQotCQkJCQkJCQlqICs9IG5Ta2lwOw0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCWNhc2UgJ2gnOg0KLQkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsNCi0JCQkJCQkJCWkrKzsNCi0JCQkJCQkJCWogKz0gblNraXA7DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJY2FzZSAnTSc6DQotCQkJCQkJCQluTWluID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7DQotCQkJCQkJCQlpKys7DQotCQkJCQkJCQlqICs9IG5Ta2lwOw0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCWNhc2UgJ3MnOg0KLQkJCQkJCQkJblNlYyA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOw0KLQkJCQkJCQkJaSsrOw0KLQkJCQkJCQkJaiArPSBuU2tpcDsNCi0JCQkJCQkJCWJyZWFrOw0KLQkJCQkJCQljYXNlICd0JzoNCi0JCQkJCQkJCWJQbSA9IHZhbHVlLkdldEF0KGkpID09ICdwJzsNCi0JCQkJCQkJCWkrKzsNCi0JCQkJCQkJCWorKzsNCi0JCQkJCQkJCWJyZWFrOw0KLQkJCQkJCX0JCQkJCQ0KLQkJCQkJfQ0KLQkJCQkJZWxzZSBpZiAoZm9ybWF0LkdldEF0KGkrMSkgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSsyKSAhPSBjKQ0KLQkJCQkJew0KLQkJCQkJCXN3aXRjaCAoYykNCi0JCQkJCQl7DQotCQkJCQkJCWNhc2UgJ3knOg0KLQkJCQkJCQkJblllYXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCA0KTsNCi0JCQkJCQkJCWkgKz0gMjsNCi0JCQkJCQkJCWogKz0gblNraXA7DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJY2FzZSAnbSc6DQotCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsNCi0JCQkJCQkJCWkgKz0gMjsNCi0JCQkJCQkJCWogKz0gblNraXA7DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJY2FzZSAnZCc6DQotCQkJCQkJCQluRGF5ID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7DQotCQkJCQkJCQlpICs9IDI7DQotCQkJCQkJCQlqICs9IG5Ta2lwOw0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCWNhc2UgJ0gnOg0KLQkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsNCi0JCQkJCQkJCWkgKz0gMjsNCi0JCQkJCQkJCWogKz0gblNraXA7DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJY2FzZSAnaCc6DQotCQkJCQkJCQluSG91ciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOw0KLQkJCQkJCQkJaSArPSAyOw0KLQkJCQkJCQkJaiArPSBuU2tpcDsNCi0JCQkJCQkJCWJyZWFrOw0KLQkJCQkJCQljYXNlICdNJzoNCi0JCQkJCQkJCW5NaW4gPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsNCi0JCQkJCQkJCWkgKz0gMjsNCi0JCQkJCQkJCWogKz0gblNraXA7DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJY2FzZSAncyc6DQotCQkJCQkJCQluU2VjID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7DQotCQkJCQkJCQlpICs9IDI7DQotCQkJCQkJCQlqICs9IG5Ta2lwOw0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCWNhc2UgJ3QnOg0KLQkJCQkJCQkJYlBtID0gKHZhbHVlLkdldEF0KGopID09ICdwJyAmJiB2YWx1ZS5HZXRBdChqKzEpID09ICdtJyk7DQotCQkJCQkJCQlpICs9IDI7DQotCQkJCQkJCQlqICs9IDI7DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQl9DQotCQkJCQl9DQotCQkJCQllbHNlIGlmIChmb3JtYXQuR2V0QXQoaSsxKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzIpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrMykgIT0gYykNCi0JCQkJCXsNCi0JCQkJCQlzd2l0Y2ggKGMpDQotCQkJCQkJew0KLQkJCQkJCQljYXNlICdtJzoNCi0JCQkJCQkJCXsNCi0JCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzTW9udGggPSBQYXJzZVN0cmluZ1N0cmluZyh2YWx1ZSwgaiwgblNraXApOw0KLQkJCQkJCQkJCUZYX0JPT0wgYkZpbmQgPSBGQUxTRTsNCi0JCQkJCQkJCQlmb3IgKGludCBtID0gMDsgbSA8IDEyOyBtKyspDQotCQkJCQkJCQkJew0KLQkJCQkJCQkJCQlpZiAoc01vbnRoLkNvbXBhcmVOb0Nhc2UobW9udGhzW21dKSA9PSAwKQ0KLQkJCQkJCQkJCQl7DQotCQkJCQkJCQkJCQluTW9udGggPSBtICsgMTsNCi0JCQkJCQkJCQkJCWkrPTM7DQotCQkJCQkJCQkJCQlqKz1uU2tpcDsNCi0JCQkJCQkJCQkJCWJGaW5kID0gVFJVRTsNCi0JCQkJCQkJCQkJCWJyZWFrOw0KLQkJCQkJCQkJCQl9DQotCQkJCQkJCQkJfQ0KLQkJCQkJCQkJCQ0KLQkJCQkJCQkJCWlmICghYkZpbmQpDQotCQkJCQkJCQkJew0KLQkJCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAzKTsNCi0JCQkJCQkJCQkJaSs9MzsNCi0JCQkJCQkJCQkJaiArPSBuU2tpcDsNCi0JCQkJCQkJCQl9DQotCQkJCQkJCQl9DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJY2FzZSAneSc6DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJZGVmYXVsdDoNCi0JCQkJCQkJCWkrPTM7DQotCQkJCQkJCQlqKz0zOw0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQkJZWxzZSBpZiAoZm9ybWF0LkdldEF0KGkrMSkgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSsyKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzMpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrNCkgIT0gYykNCi0JCQkJCXsNCi0JCQkJCQlzd2l0Y2ggKGMpDQotCQkJCQkJew0KLQ0KLQ0KLQkJCQkJCQljYXNlICd5JzoNCi0JCQkJCQkJCW5ZZWFyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgNCk7DQotCQkJCQkJCQlqICs9IG5Ta2lwOw0KLQkJCQkJCQkJaSArPSA0Ow0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCWNhc2UgJ20nOg0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCUZYX0JPT0wgYkZpbmQgPSBGQUxTRTsNCi0NCi0JCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzTW9udGggPSBQYXJzZVN0cmluZ1N0cmluZyh2YWx1ZSwgaiwgblNraXApOw0KLQkJCQkJCQkJCXNNb250aC5NYWtlTG93ZXIoKTsNCi0NCi0JCQkJCQkJCQlmb3IgKGludCBtID0gMDsgbSA8IDEyOyBtKyspDQotCQkJCQkJCQkJew0KLQkJCQkJCQkJCQlDRlhfV2lkZVN0cmluZyBzRnVsbE1vbnRocyA9IGZ1bGxtb250aHNbbV07DQotCQkJCQkJCQkJCXNGdWxsTW9udGhzLk1ha2VMb3dlcigpOw0KLQ0KLQkJCQkJCQkJCQlpZiAoc0Z1bGxNb250aHMuRmluZChzTW9udGgsIDApICE9IC0xKQ0KLQkJCQkJCQkJCQl7DQotCQkJCQkJCQkJCQluTW9udGggPSBtICsgMTsNCi0JCQkJCQkJCQkJCWkgKz0gNDsNCi0JCQkJCQkJCQkJCWogKz0gblNraXA7DQotCQkJCQkJCQkJCQliRmluZCA9IFRSVUU7DQotCQkJCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJCQkJfQ0KLQkJCQkJCQkJCX0NCi0JCQkJCQkJCQkNCi0JCQkJCQkJCQlpZiAoIWJGaW5kKQ0KLQkJCQkJCQkJCXsNCi0JCQkJCQkJCQkJbk1vbnRoID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgNCk7DQotCQkJCQkJCQkJCWkrPTQ7DQotCQkJCQkJCQkJCWogKz0gblNraXA7DQotCQkJCQkJCQkJfQ0KLQkJCQkJCQkJfQ0KLQkJCQkJCQkJYnJlYWs7DQotCQkJCQkJCWRlZmF1bHQ6DQotCQkJCQkJCQlpICs9IDQ7DQotCQkJCQkJCQlqICs9IDQ7DQotCQkJCQkJCQlicmVhazsNCi0JCQkJCQl9CQkJCQkNCi0JCQkJCX0NCi0JCQkJCWVsc2UNCi0JCQkJCXsNCi0JCQkJCQlpZiAoZm9ybWF0LkdldEF0KGkpICE9IHZhbHVlLkdldEF0KGopKQ0KLQkJCQkJCXsNCi0JCQkJCQkJYldyb25nRm9ybWF0ID0gVFJVRTsNCi0JCQkJCQkJYkV4aXQgPSBUUlVFOw0KLQkJCQkJCX0NCi0JCQkJCQlpKys7DQotCQkJCQkJaisrOw0KLQkJCQkJfQ0KLQkJCQkJDQotCQkJCQlpZiAob2xkaiA9PSBqKQ0KLQkJCQkJew0KLQkJCQkJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7DQotCQkJCQkJYkV4aXQgPSBUUlVFOw0KLQkJCQkJfQ0KLQkJCQl9DQotDQotCQkJCWJyZWFrOwkJCQ0KLQkJCWRlZmF1bHQ6DQotCQkJCWlmICh2YWx1ZS5HZXRMZW5ndGgoKSA8PSBqKQ0KLQkJCQl7DQotCQkJCQliRXhpdCA9IFRSVUU7DQotCQkJCX0NCi0JCQkJZWxzZSBpZiAoZm9ybWF0LkdldEF0KGkpICE9IHZhbHVlLkdldEF0KGopKQ0KLQkJCQl7DQotCQkJCQliV3JvbmdGb3JtYXQgPSBUUlVFOw0KLQkJCQkJYkV4aXQgPSBUUlVFOw0KLQkJCQl9DQotDQotCQkJCWkrKzsNCi0JCQkJaisrOw0KLQkJCQlicmVhazsNCi0JCX0JCQ0KLQl9DQotDQotCWlmIChiUG0pIG5Ib3VyICs9IDEyOw0KLQ0KLQlpZiAoblllYXIgPj0gMCAmJiBuWWVhciA8PSBuWWVhclN1YikNCi0JCW5ZZWFyICs9IDIwMDA7DQotDQotCWlmIChuTW9udGggPCAxIHx8IG5Nb250aCA+IDEyKQ0KLQkJYldyb25nRm9ybWF0ID0gVFJVRTsNCi0NCi0JaWYgKG5EYXkgPCAxIHx8IG5EYXkgPiAzMSkNCi0JCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7DQotDQotCWlmIChuSG91ciA8IDAgfHwgbkhvdXIgPiAyNCkNCi0JCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7DQotDQotCWlmIChuTWluIDwgMCB8fCBuTWluID4gNjApDQotCQliV3JvbmdGb3JtYXQgPSBUUlVFOw0KLQ0KLQlpZiAoblNlYyA8IDAgfHwgblNlYyA+IDYwKQ0KLQkJYldyb25nRm9ybWF0ID0gVFJVRTsNCi0NCi0JZG91YmxlIGRSZXQgPSAwOw0KLQ0KLQlpZiAoYldyb25nRm9ybWF0KQ0KLQl7DQotCQlkUmV0ID0gUGFyc2VOb3JtYWxEYXRlKHZhbHVlLCBiV3JvbmdGb3JtYXQpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJZFJldCA9IEpTX01ha2VEYXRlKEpTX01ha2VEYXkoblllYXIsbk1vbnRoIC0gMSxuRGF5KSxKU19NYWtlVGltZShuSG91ciwgbk1pbiwgblNlYywgMCkpOw0KLQ0KLQkJaWYgKEpTX1BvcnRJc05hbihkUmV0KSkNCi0JCXsNCi0JCQlkUmV0ID0gSlNfRGF0ZVBhcnNlKHZhbHVlKTsNCi0JCX0NCi0JfQ0KLQ0KLQlpZiAoSlNfUG9ydElzTmFuKGRSZXQpKQ0KLQl7DQotCQlkUmV0ID0gUGFyc2VOb3JtYWxEYXRlKHZhbHVlLCBiV3JvbmdGb3JtYXQpOw0KLQl9DQotDQotCXJldHVybiBkUmV0Ow0KLQ0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6TWFrZUZvcm1hdERhdGUoZG91YmxlIGREYXRlLCBjb25zdCBDRlhfV2lkZVN0cmluZyAmIGZvcm1hdCkNCi17DQotCUNGWF9XaWRlU3RyaW5nIHNSZXQgPSBMIiIsc1BhcnQgPSBMIiI7DQotDQotCWludCBuWWVhciA9IEpTX0dldFllYXJGcm9tVGltZShkRGF0ZSk7DQotCWludCBuTW9udGggPSBKU19HZXRNb250aEZyb21UaW1lKGREYXRlKSArIDE7DQotCWludCBuRGF5ID0gSlNfR2V0RGF5RnJvbVRpbWUoZERhdGUpOw0KLQlpbnQgbkhvdXIgPSBKU19HZXRIb3VyRnJvbVRpbWUoZERhdGUpOw0KLQlpbnQgbk1pbiA9IEpTX0dldE1pbkZyb21UaW1lKGREYXRlKTsNCi0JaW50IG5TZWMgPSBKU19HZXRTZWNGcm9tVGltZShkRGF0ZSk7DQotDQotCWludCBpID0gMDsNCi0JRlhfV0NIQVIgYzsNCi0Jd2hpbGUgKGkgPCBmb3JtYXQuR2V0TGVuZ3RoKCkpDQotCXsNCi0JCWMgPSBmb3JtYXQuR2V0QXQoaSk7DQotCQlzUGFydCA9IEwiIjsNCi0JCXN3aXRjaCAoYykNCi0JCXsNCi0JCQljYXNlICd5JzoNCi0JCQljYXNlICdtJzoNCi0JCQljYXNlICdkJzoNCi0JCQljYXNlICdIJzoNCi0JCQljYXNlICdoJzoNCi0JCQljYXNlICdNJzoNCi0JCQljYXNlICdzJzoNCi0JCQljYXNlICd0JzoNCi0JCQkJaWYgKGZvcm1hdC5HZXRBdChpKzEpICE9IGMpDQotCQkJCXsNCi0JCQkJCXN3aXRjaCAoYykNCi0JCQkJCXsNCi0JCQkJCQljYXNlICd5JzoNCi0JCQkJCQkJc1BhcnQgKz0gYzsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSAnbSc6DQotCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuTW9udGgpOw0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlICdkJzoNCi0JCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5EYXkpOw0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlICdIJzoNCi0JCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5Ib3VyKTsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSAnaCc6DQotCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuSG91cj4xMj9uSG91ciAtIDEyOm5Ib3VyKTsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSAnTSc6DQotCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuTWluKTsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSAncyc6DQotCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuU2VjKTsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSAndCc6CQkJCQ0KLQkJCQkJCQlzUGFydCArPSBuSG91cj4xMj8ncCc6J2EnOw0KLQkJCQkJCQlicmVhazsNCi0JCQkJCX0JCQkJCQ0KLQkJCQkJaSsrOw0KLQkJCQl9DQotCQkJCWVsc2UgaWYgKGZvcm1hdC5HZXRBdChpKzEpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrMikgIT0gYykNCi0JCQkJew0KLQkJCQkJc3dpdGNoIChjKQ0KLQkJCQkJew0KLQkJCQkJCWNhc2UgJ3knOg0KLQkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuWWVhciAtIChuWWVhciAvIDEwMCkgKiAxMDApOw0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlICdtJzoNCi0JCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbk1vbnRoKTsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSAnZCc6DQotCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5EYXkpOw0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlICdIJzoNCi0JCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbkhvdXIpOw0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlICdoJzoNCi0JCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbkhvdXI+MTI/bkhvdXIgLSAxMjpuSG91cik7DQotCQkJCQkJCWJyZWFrOw0KLQkJCQkJCWNhc2UgJ00nOg0KLQkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuTWluKTsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJY2FzZSAncyc6DQotCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5TZWMpOw0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQljYXNlICd0JzoJCQkJCQkJDQotCQkJCQkJCXNQYXJ0ID0gbkhvdXI+MTI/IChGWF9MUENXU1RSKUwicG0iOiAoRlhfTFBDV1NUUilMImFtIjsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQl9CQkJDQotCQkJCQlpKz0yOw0KLQkJCQl9DQotCQkJCWVsc2UgaWYgKGZvcm1hdC5HZXRBdChpKzEpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrMikgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSszKSAhPSBjKQ0KLQkJCQl7CQkNCi0JCQkJCXN3aXRjaCAoYykNCi0JCQkJCXsNCi0JCQkJCQljYXNlICdtJzoNCi0JCQkJCQkJaSs9MzsNCi0JCQkJCQkJaWYgKG5Nb250aCA+IDAmJm5Nb250aCA8PSAxMikNCi0JCQkJCQkJCXNQYXJ0ICs9IG1vbnRoc1tuTW9udGggLSAxXTsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJZGVmYXVsdDoNCi0JCQkJCQkJaSs9MzsNCi0JCQkJCQkJc1BhcnQgKz0gYzsNCi0JCQkJCQkJc1BhcnQgKz0gYzsNCi0JCQkJCQkJc1BhcnQgKz0gYzsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQl9CQkJCQkNCi0JCQkJfQ0KLQkJCQllbHNlIGlmIChmb3JtYXQuR2V0QXQoaSsxKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzIpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrMykgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSs0KSAhPSBjKQ0KLQkJCQl7DQotCQkJCQlzd2l0Y2ggKGMpDQotCQkJCQl7DQotCQkJCQkJY2FzZSAneSc6DQotCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwNGQiLG5ZZWFyKTsNCi0JCQkJCQkJaSArPSA0Ow0KLQkJCQkJCQlicmVhazsJDQotCQkJCQkJY2FzZSAnbSc6DQotCQkJCQkJCWkrPTQ7DQotCQkJCQkJCWlmIChuTW9udGggPiAwJiZuTW9udGggPD0gMTIpDQotCQkJCQkJCQlzUGFydCArPSBmdWxsbW9udGhzW25Nb250aCAtIDFdOw0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQlkZWZhdWx0Og0KLQkJCQkJCQlpICs9IDQ7DQotCQkJCQkJCXNQYXJ0ICs9IGM7DQotCQkJCQkJCXNQYXJ0ICs9IGM7DQotCQkJCQkJCXNQYXJ0ICs9IGM7DQotCQkJCQkJCXNQYXJ0ICs9IGM7DQotCQkJCQkJCWJyZWFrOw0KLQkJCQkJfQkJCQkJDQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQl7DQotCQkJCQlpKys7DQotCQkJCQlzUGFydCArPSBjOw0KLQkJCQl9DQotCQkJCWJyZWFrOwkJCQ0KLQkJCWRlZmF1bHQ6DQotCQkJCWkrKzsNCi0JCQkJc1BhcnQgKz0gYzsNCi0JCQkJYnJlYWs7DQotCQl9DQotCQkNCi0JCXNSZXQgKz0gc1BhcnQ7DQotCX0NCi0NCi0JcmV0dXJuIHNSZXQ7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotLy9mdW5jdGlvbiBBRk51bWJlcl9Gb3JtYXQobkRlYywgc2VwU3R5bGUsIG5lZ1N0eWxlLCBjdXJyU3R5bGUsIHN0ckN1cnJlbmN5LCBiQ3VycmVuY3lQcmVwZW5kKQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTnVtYmVyX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotI2lmIF9GWF9PU18gIT0gX0ZYX0FORFJPSURfDQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSA2KQ0KLQl7DQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfV2lkZVN0cmluZyYgVmFsdWUgPSBwRXZlbnQtPlZhbHVlKCk7CQ0KLQlDRlhfQnl0ZVN0cmluZyBzdHJWYWx1ZSA9IFN0clRyaW0oQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKFZhbHVlKSk7DQotCQ0KLQlpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsNCi0JDQotCWludCBpRGVjID0gcGFyYW1zWzBdOw0KLQlpbnQgaVNlcFN0eWxlID0gcGFyYW1zWzFdOw0KLQlpbnQgaU5lZ1N0eWxlID0gcGFyYW1zWzJdOw0KLQlpbnQgaWN1cnJTdHlsZSA9IHBhcmFtc1szXTsgLy9pdCdzIG5vIHVzZSENCi0Jc3RkOjp3c3RyaW5nIHdzdHJDdXJyZW5jeShwYXJhbXNbNF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7DQotCUZYX0JPT0wgYkN1cnJlbmN5UHJlcGVuZCA9IHBhcmFtc1s1XTsNCi0JDQotCWlmIChpRGVjIDwgMCkgaURlYyA9IC1pRGVjOw0KLQkNCi0JaWYgKGlTZXBTdHlsZSA8IDAgfHwgaVNlcFN0eWxlID4gMykNCi0JCWlTZXBTdHlsZSA9IDA7DQotCQ0KLQlpZiAoaU5lZ1N0eWxlIDwgMCB8fCBpTmVnU3R5bGUgPiAzKQ0KLQkJaU5lZ1N0eWxlID0gMDsNCi0JDQotCQ0KLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0JLy9mb3IgcHJvY2Vzc2luZyBkZWNpbWFsIHBsYWNlcw0KLQlzdHJWYWx1ZS5SZXBsYWNlKCIsIiwgIi4iKTsNCi0JZG91YmxlIGRWYWx1ZSA9IGF0b2Yoc3RyVmFsdWUpOw0KLQlpZiAoaURlYyA+IDApDQotCQlkVmFsdWUgKz0gRE9VQkxFX0NPUlJFQ1Q7Ly8NCi0JCSAgICANCi0JaW50IGlEZWMyOw0KLQlGWF9CT09MIGJOYWdhdGl2ZSA9IEZBTFNFOw0KLQ0KLQlzdHJWYWx1ZSA9IGZjdnQoZFZhbHVlLGlEZWMsJmlEZWMyLCZiTmFnYXRpdmUpOw0KLQlpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKQ0KLQl7DQotCQlkVmFsdWUgPSAwOw0KLQkJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsNCi0JCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpDQotCQl7DQotCQkJc3RyVmFsdWUgPSAiMCI7DQotCQkJaURlYzIgPSAxOw0KLQkJfQ0KLQ0KLQl9DQotDQotCWlmIChpRGVjMiA8IDApDQotCXsNCi0JCWZvciAoaW50IGlOdW0gPSAwO2lOdW0gPCBhYnMoaURlYzIpO2lOdW0rKykNCi0JCXsNCi0JCQlzdHJWYWx1ZSA9ICIwIiArIHN0clZhbHVlOw0KLQkJfQ0KLQkJaURlYzIgPSAwOw0KLQkJDQotCX0NCi0JaW50IGlNYXggPSBzdHJWYWx1ZS5HZXRMZW5ndGgoKTsNCi0JaWYgKGlEZWMyID4gaU1heCkNCi0Jew0KLQkJZm9yIChpbnQgaU51bSA9IDA7aU51bSA8PSBpRGVjMiAtIGlNYXggO2lOdW0rKykNCi0JCXsNCi0JCQlzdHJWYWx1ZSArPSAiMCI7DQotCQl9DQotCQlpTWF4ID0gaURlYzIrMTsJCQkNCi0JfQ0KLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotICAgIC8vZm9yIHByb2Nlc3Npbmcgc2VwZXJhdG9yIHN0eWxlDQotCWlmIChpRGVjMiA8IGlNYXgpDQotCXsNCi0JCWlmIChpU2VwU3R5bGUgPT0gMCB8fCBpU2VwU3R5bGUgPT0gMSkNCi0JCXsNCi0JCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcuJyk7DQotCQkJaU1heCsrOw0KLQkJfQ0KLQkJZWxzZSBpZiAoaVNlcFN0eWxlID09IDIgfHwgaVNlcFN0eWxlID09IDMpDQotCQl7DQotCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnLCcpOw0KLQkJCWlNYXgrKzsNCi0JCX0NCi0JCQ0KLQkJaWYgKGlEZWMyID09IDApDQotCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnMCcpOw0KLQl9DQotCWlmIChpU2VwU3R5bGUgPT0gMCB8fCBpU2VwU3R5bGUgPT0gMikNCi0Jew0KLQkJY2hhciBjU2VwZXJhdG9yOw0KLQkJaWYgKGlTZXBTdHlsZSA9PSAwKQ0KLQkJCWNTZXBlcmF0b3IgPSAnLCc7DQotCQllbHNlDQotCQkJY1NlcGVyYXRvciA9ICcuJzsNCi0JCQ0KLQkJaW50IGlEZWNQb3NpdGl2ZSxpRGVjTmFnYXRpdmU7DQotCQlpRGVjUG9zaXRpdmUgPSBpRGVjMjsNCi0JCWlEZWNOYWdhdGl2ZSA9IGlEZWMyOwkJDQotCQkNCi0JCWZvciAoaURlY1Bvc2l0aXZlID0gaURlYzIgLTM7IGlEZWNQb3NpdGl2ZSA+IDA7aURlY1Bvc2l0aXZlIC09IDMpDQotCQl7DQotCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWNQb3NpdGl2ZSwgY1NlcGVyYXRvcik7DQotCQkJaU1heCsrOw0KLQkJfQ0KLQl9DQotCQ0KLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotICAgIC8vZm9yIHByb2Nlc3NpbmcgY3VycmVuY3kgc3RyaW5nDQotDQotCVZhbHVlID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChzdHJWYWx1ZSk7DQotCQ0KLQlzdGQ6OndzdHJpbmcgc3RyVmFsdWUyKFZhbHVlKTsNCi0NCi0JaWYgKGJDdXJyZW5jeVByZXBlbmQpDQotCQlzdHJWYWx1ZTIgPSB3c3RyQ3VycmVuY3kgKyBzdHJWYWx1ZTI7DQotCWVsc2UNCi0JCXN0clZhbHVlMiA9IHN0clZhbHVlMiArIHdzdHJDdXJyZW5jeTsNCi0JDQotCQ0KLQkNCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KLQkvL2ZvciBwcm9jZXNzaW5nIG5lZ2F0aXZlIHN0eWxlDQotCWlmIChiTmFnYXRpdmUpDQotCXsNCi0JCWlmIChpTmVnU3R5bGUgPT0gMCkNCi0JCXsNCi0JCQlzdHJWYWx1ZTIuaW5zZXJ0KDAsTCItIik7DQotCQl9DQotCQlpZiAoaU5lZ1N0eWxlID09IDIgfHwgaU5lZ1N0eWxlID09IDMpDQotCQl7DQotCQkJc3RyVmFsdWUyLmluc2VydCgwLEwiKCIpOw0KLQkJCXN0clZhbHVlMi5pbnNlcnQoc3RyVmFsdWUyLmxlbmd0aCgpLEwiKSIpOw0KLQkJfQ0KLQkJaWYgKGlOZWdTdHlsZSA9PSAxIHx8IGlOZWdTdHlsZSA9PSAzKQ0KLQkJew0KLQkJCWlmIChGaWVsZCAqIGZUYXJnZXQgPSBwRXZlbnQtPlRhcmdldF9GaWVsZCgpKQ0KLQkJCXsNCi0JCQkJQ0pTX0FycmF5IGFyQ29sb3IoaXNvbGF0ZSk7DQotCQkJCUNKU19WYWx1ZSB2Q29sRWxtKGlzb2xhdGUpOw0KLQkJCQl2Q29sRWxtID0gTCJSR0IiOw0KLQkJCQlhckNvbG9yLlNldEVsZW1lbnQoMCx2Q29sRWxtKTsNCi0JCQkJdkNvbEVsbSA9IDE7DQotCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgxLHZDb2xFbG0pOw0KLQkJCQl2Q29sRWxtID0gMDsNCi0JCQkJYXJDb2xvci5TZXRFbGVtZW50KDIsdkNvbEVsbSk7DQotCQkJCQ0KLQkJCQlhckNvbG9yLlNldEVsZW1lbnQoMyx2Q29sRWxtKTsNCi0JCQkJDQotCQkJCUNKU19Qcm9wVmFsdWUgdlByb3AoaXNvbGF0ZSk7DQotCQkJCXZQcm9wLlN0YXJ0R2V0dGluZygpOw0KLQkJCQl2UHJvcDw8YXJDb2xvcjsNCi0JCQkJdlByb3AuU3RhcnRTZXR0aW5nKCk7DQotCQkJCWZUYXJnZXQtPnRleHRDb2xvcihjYyx2UHJvcCxzRXJyb3IpOy8vIHJlZA0KLQkJCX0NCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChpTmVnU3R5bGUgPT0gMSB8fCBpTmVnU3R5bGUgPT0gMykNCi0JCXsNCi0JCQlpZiAoRmllbGQgKmZUYXJnZXQgPSBwRXZlbnQtPlRhcmdldF9GaWVsZCgpKQ0KLQkJCXsNCi0JCQkJQ0pTX0FycmF5IGFyQ29sb3IoaXNvbGF0ZSk7DQotCQkJCUNKU19WYWx1ZSB2Q29sRWxtKGlzb2xhdGUpOw0KLQkJCQl2Q29sRWxtID0gTCJSR0IiOw0KLQkJCQlhckNvbG9yLlNldEVsZW1lbnQoMCx2Q29sRWxtKTsNCi0JCQkJdkNvbEVsbSA9IDA7DQotCQkJCWFyQ29sb3IuU2V0RWxlbWVudCgxLHZDb2xFbG0pOw0KLQkJCQlhckNvbG9yLlNldEVsZW1lbnQoMix2Q29sRWxtKTsNCi0JCQkJYXJDb2xvci5TZXRFbGVtZW50KDMsdkNvbEVsbSk7DQotCQkJCQ0KLQkJCQlDSlNfUHJvcFZhbHVlIHZQcm9wKGlzb2xhdGUpOw0KLQkJCQl2UHJvcC5TdGFydEdldHRpbmcoKTsNCi0JCQkJZlRhcmdldC0+dGV4dENvbG9yKGNjLHZQcm9wLHNFcnJvcik7DQotCQkJCQ0KLQkJCQlDSlNfQXJyYXkgYVByb3AoaXNvbGF0ZSk7DQotCQkJCXZQcm9wLkNvbnZlcnRUb0FycmF5KGFQcm9wKTsNCi0NCi0JCQkJQ1BXTF9Db2xvciBjclByb3A7DQotCQkJCUNQV0xfQ29sb3IgY3JDb2xvcjsNCi0JCQkJY29sb3I6OkNvbnZlcnRBcnJheVRvUFdMQ29sb3IoYVByb3AsIGNyUHJvcCk7DQotCQkJCWNvbG9yOjpDb252ZXJ0QXJyYXlUb1BXTENvbG9yKGFyQ29sb3IsIGNyQ29sb3IpOw0KLQ0KLQkJCQlpZiAoY3JDb2xvciAhPSBjclByb3ApDQotCQkJCXsNCi0JCQkJCUNKU19Qcm9wVmFsdWUgdlByb3AyKGlzb2xhdGUpOw0KLQkJCQkJdlByb3AyLlN0YXJ0R2V0dGluZygpOw0KLQkJCQkJdlByb3AyPDxhckNvbG9yOw0KLQkJCQkJdlByb3AyLlN0YXJ0U2V0dGluZygpOw0KLSAgICAgCQkJCWZUYXJnZXQtPnRleHRDb2xvcihjYyx2UHJvcDIsc0Vycm9yKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLQlWYWx1ZSA9IHN0clZhbHVlMi5jX3N0cigpOw0KLSNlbmRpZg0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotLy9mdW5jdGlvbiBBRk51bWJlcl9LZXlzdHJva2UobkRlYywgc2VwU3R5bGUsIG5lZ1N0eWxlLCBjdXJyU3R5bGUsIHN0ckN1cnJlbmN5LCBiQ3VycmVuY3lQcmVwZW5kKQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTnVtYmVyX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsNCi0JQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsNCi0JDQotCWlmKHBhcmFtcy5zaXplKCkgPCAyKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlpbnQgaVNlcFN0eWxlID0gcGFyYW1zWzFdOw0KLQkNCi0JaWYgKGlTZXBTdHlsZSA8IDAgfHwgaVNlcFN0eWxlID4gMykNCi0JCWlTZXBTdHlsZSA9IDA7DQotCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfV2lkZVN0cmluZyAmIHZhbCA9IHBFdmVudC0+VmFsdWUoKTsJDQotCUNGWF9XaWRlU3RyaW5nICYgd19zdHJDaGFuZ2UgPSBwRXZlbnQtPkNoYW5nZSgpOw0KLSAgICBDRlhfV2lkZVN0cmluZyB3X3N0clZhbHVlID0gdmFsOw0KLQ0KLQlpZiAocEV2ZW50LT5XaWxsQ29tbWl0KCkpDQotCXsNCi0JCUNGWF9XaWRlU3RyaW5nIHdzdHJDaGFuZ2UgPSB3X3N0ckNoYW5nZTsNCi0JCUNGWF9XaWRlU3RyaW5nIHdzdHJWYWx1ZSA9IFN0ckxUcmltKHdfc3RyVmFsdWUpOw0KLQkJaWYgKHdzdHJWYWx1ZS5Jc0VtcHR5KCkpDQotCQkJcmV0dXJuIFRSVUU7DQotCQkNCi0JCUNGWF9XaWRlU3RyaW5nIHN3VGVtcCA9IHdzdHJWYWx1ZTsNCi0JCXN3VGVtcC5SZXBsYWNlKChGWF9MUENXU1RSKUwiLCIsIChGWF9MUENXU1RSKUwiLiIpOw0KLQkJaWYgKCFJc051bWJlcihzd1RlbXApKSAvLyEoSXNOdW1iZXIod3N0ckNoYW5nZSkgJiYgDQotCQl7DQotCQkJcEV2ZW50LT5SYygpID0gRkFMU0U7DQotCQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UpOw0KLQkJCUFsZXJ0KHBDb250ZXh0LCBzRXJyb3IpOw0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQkJcmV0dXJuIFRSVUU7IC8vIGl0IGhhcHBlbnMgYWZ0ZXIgdGhlIGxhc3Qga2V5c3Ryb2tlIGFuZCBiZWZvcmUgdmFsaWRhdGluZywNCi0JfQ0KLQkNCi0Jc3RkOjp3c3RyaW5nIHdfc3RyVmFsdWUyICh3X3N0clZhbHVlKTsNCi0Jc3RkOjp3c3RyaW5nIHdfc3RyQ2hhbmdlMih3X3N0ckNoYW5nZSk7DQotCQ0KLQlzdGQ6OndzdHJpbmcgd19zdHJTZWxlY3RlZDsNCi0JaWYoLTEgIT0gcEV2ZW50LT5TZWxTdGFydCgpKQ0KLQkJd19zdHJTZWxlY3RlZCA9IHdfc3RyVmFsdWUyLnN1YnN0cihwRXZlbnQtPlNlbFN0YXJ0KCksKHBFdmVudC0+U2VsRW5kKCkgLSBwRXZlbnQtPlNlbFN0YXJ0KCkpKTsNCi0JRlhfQk9PTCBiSGFzU2lnbiA9ICh3X3N0clZhbHVlMi5maW5kKCctJykgIT0gLTEpICYmICh3X3N0clNlbGVjdGVkLmZpbmQoJy0nKSA9PSAtMSk7DQotCWlmIChiSGFzU2lnbikNCi0Jew0KLQkJLy9jYW4ndCBpbnNlcnQgImNoYW5nZSIgaW4gZnJvbnQgdG8gc2lnbiBwb3N0aW9uLg0KLQkJaWYgKHBFdmVudC0+U2VsU3RhcnQoKSA9PSAwKQ0KLQkJew0KLSAgICAgICAgICAgIEZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsNCi0JCQliUmMgPSBGQUxTRTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JfQ0KLQ0KLQljaGFyIGNTZXAgPSBMJy4nOw0KLQ0KLQlzd2l0Y2ggKGlTZXBTdHlsZSkNCi0Jew0KLQljYXNlIDA6DQotCWNhc2UgMToNCi0JCWNTZXAgPSBMJy4nOw0KLQkJYnJlYWs7DQotCWNhc2UgMjoNCi0JY2FzZSAzOg0KLQkJY1NlcCA9IEwnLCc7DQotCQlicmVhazsNCi0JfQ0KLQkNCi0JRlhfQk9PTCBiSGFzU2VwID0gKHdfc3RyVmFsdWUyLmZpbmQoY1NlcCkgIT0gLTEpOw0KLQlmb3IgKHN0ZDo6d3N0cmluZzo6aXRlcmF0b3IgaXQgPSB3X3N0ckNoYW5nZTIuYmVnaW4oKTsgaXQgIT0gd19zdHJDaGFuZ2UyLmVuZCgpOyBpdCsrKQ0KLQl7DQotCQlpZiAoKml0ID09IGNTZXApDQotCQl7DQotCQkJaWYgKGJIYXNTZXApDQotCQkJew0KLQkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7DQotCQkJCWJSYyA9IEZBTFNFOw0KLQkJCQlyZXR1cm4gVFJVRTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJYkhhc1NlcCA9IFRSVUU7DQotCQkJCWNvbnRpbnVlOw0KLQkJCX0NCi0JCX0NCi0JCWlmICgqaXQgPT0gTCctJykNCi0JCXsNCi0JCQlpZiAoYkhhc1NpZ24pDQotCQkJew0KLQkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7DQotCQkJCWJSYyA9IEZBTFNFOw0KLQkJCQlyZXR1cm4gVFJVRTsNCi0JCQl9DQotCQkJZWxzZSBpZiAoaXQgIT0gd19zdHJDaGFuZ2UyLmJlZ2luKCkpIC8vc2lnbidzIHBvc2l0aW9uIGlzIG5vdCBjb3JyZWN0DQotCQkJew0KLQkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7DQotCQkJCWJSYyA9IEZBTFNFOw0KLQkJCQlyZXR1cm4gVFJVRTsNCi0JCQl9DQotCQkJZWxzZSBpZiAocEV2ZW50LT5TZWxTdGFydCgpICE9IDApDQotCQkJew0KLQkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7DQotCQkJCWJSYyA9IEZBTFNFOw0KLQkJCQlyZXR1cm4gVFJVRTsNCi0JCQl9DQotCQkJYkhhc1NpZ24gPSBUUlVFOw0KLQkJCWNvbnRpbnVlOw0KLQkJfQ0KLQkJDQotCQlpZiAoIUlzRGlnaXQoKml0KSkNCi0JCXsJCQkNCi0JCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7DQotCQkJYlJjID0gRkFMU0U7DQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0JDQotCQ0KLQlzdGQ6OndzdHJpbmcgd19wcmVmaXggPSB3X3N0clZhbHVlMi5zdWJzdHIoMCxwRXZlbnQtPlNlbFN0YXJ0KCkpOw0KLQlzdGQ6OndzdHJpbmcgd19wb3N0Zml4Ow0KLQlpZiAocEV2ZW50LT5TZWxFbmQoKTwoaW50KXdfc3RyVmFsdWUyLmxlbmd0aCgpKQ0KLQkJd19wb3N0Zml4ICA9IHdfc3RyVmFsdWUyLnN1YnN0cihwRXZlbnQtPlNlbEVuZCgpKTsNCi0Jd19zdHJWYWx1ZTIgPSB3X3ByZWZpeCArIHdfc3RyQ2hhbmdlMiArIHdfcG9zdGZpeDsNCi0Jd19zdHJWYWx1ZSA9IHdfc3RyVmFsdWUyLmNfc3RyKCk7DQotCXZhbCA9IHdfc3RyVmFsdWU7DQotCXJldHVybiBUUlVFOwkJDQotCQ0KLX0NCi0NCi0vL2Z1bmN0aW9uIEFGUGVyY2VudF9Gb3JtYXQobkRlYywgc2VwU3R5bGUpDQotRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZQZXJjZW50X0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotI2lmIF9GWF9PU18gIT0gX0ZYX0FORFJPSURfDQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsNCi0JQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsNCi0NCi0gICAgaWYgKHBhcmFtcy5zaXplKCkgIT0gMikNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQlpZighcEV2ZW50LT5tX3BWYWx1ZSkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ0ZYX1dpZGVTdHJpbmcmIFZhbHVlID0gcEV2ZW50LT5WYWx1ZSgpOw0KLQkNCi0vLyAgICAgSFdORCBoTWFpbkZyYW1lID0gTlVMTDsNCi0vLyAJDQotLy8gCUNQREZTREtfRm9ybUZpbGxBcHAgKnBBcHAgPSBwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCk7DQotLy8gCUFTU0VSVChwQXBwKTsNCi0vLyAJaE1haW5GcmFtZSA9IHBBcHAtPkdldE1haW5GcmFtZVduZCgpOw0KLQkJDQotCUNGWF9CeXRlU3RyaW5nIHN0clZhbHVlID0gU3RyVHJpbShDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoVmFsdWUpKTsNCi0JDQotCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpDQotCQlyZXR1cm4gVFJVRTsNCi0JDQotCWludCBpRGVjID0gcGFyYW1zWzBdOw0KLQlpbnQgaVNlcFN0eWxlID0gcGFyYW1zWzFdOw0KLQkNCi0JLy9BU1NFUlQoaURlYyA+IDApOw0KLQlpZiAoaURlYyA8IDApDQotCQlpRGVjID0gLWlEZWM7DQotCQ0KLQlpZiAoaVNlcFN0eWxlIDwgMCB8fCBpU2VwU3R5bGUgPiAzKQ0KLQkJaVNlcFN0eWxlID0gMDsNCi0JDQotCQ0KLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0JLy9mb3IgcHJvY2Vzc2luZyBkZWNpbWFsIHBsYWNlcw0KLQlkb3VibGUgZFZhbHVlID0gYXRvZihzdHJWYWx1ZSk7DQotCWRWYWx1ZSAqPSAxMDA7DQotCWlmIChpRGVjID4gMCkNCi0JCWRWYWx1ZSArPSBET1VCTEVfQ09SUkVDVDsvL9Cj1f0NCi0NCi0JaW50IGlEZWMyOw0KLQlGWF9CT09MIGJOYWdhdGl2ZSA9IEZBTFNFOw0KLQlzdHJWYWx1ZSA9IGZjdnQoZFZhbHVlLGlEZWMsJmlEZWMyLCZiTmFnYXRpdmUpOw0KLSAgICBpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKQ0KLQl7DQotCQlkVmFsdWUgPSAwOw0KLQkJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsNCi0JfQ0KLQ0KLQlpZiAoaURlYzIgPCAwKQ0KLQl7DQotCQlmb3IgKGludCBpTnVtID0gMDsgaU51bSA8IGFicyhpRGVjMik7IGlOdW0rKykNCi0JCXsNCi0JCQlzdHJWYWx1ZSA9ICIwIiArIHN0clZhbHVlOw0KLQkJfQ0KLQkJaURlYzIgPSAwOw0KLQkJDQotCX0NCi0JaW50IGlNYXggPSBzdHJWYWx1ZS5HZXRMZW5ndGgoKTsNCi0JaWYgKGlEZWMyID4gaU1heCkNCi0Jew0KLQkJZm9yIChpbnQgaU51bSA9IDA7IGlOdW0gPD0gaURlYzIgLSBpTWF4OyBpTnVtKyspDQotCQl7DQotCQkJc3RyVmFsdWUgKz0gIjAiOw0KLQkJfQ0KLQkJaU1heCA9IGlEZWMyKzE7CQkJDQotCX0NCi0JLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KLSAgICAvL2ZvciBwcm9jZXNzaW5nIHNlcGVyYXRvciBzdHlsZQ0KLQlpZiAoaURlYzIgPCBpTWF4KQ0KLQl7DQotCQlpZiAoaVNlcFN0eWxlID09IDAgfHwgaVNlcFN0eWxlID09IDEpDQotCQl7DQotCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnLicpOw0KLQkJCWlNYXgrKzsNCi0JCX0NCi0JCWVsc2UgaWYgKGlTZXBTdHlsZSA9PSAyIHx8IGlTZXBTdHlsZSA9PSAzKQ0KLQkJew0KLQkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJywnKTsNCi0JCQlpTWF4Kys7DQotCQl9DQotCQkNCi0JCWlmIChpRGVjMiA9PSAwKQ0KLQkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJzAnKTsNCi0JfQ0KLQlpZiAoaVNlcFN0eWxlID09IDAgfHwgaVNlcFN0eWxlID09IDIpDQotCXsNCi0JCWNoYXIgY1NlcGVyYXRvcjsNCi0JCWlmIChpU2VwU3R5bGUgPT0gMCkNCi0JCQljU2VwZXJhdG9yID0gJywnOw0KLQkJZWxzZQ0KLQkJCWNTZXBlcmF0b3IgPSAnLic7DQotCQkNCi0JCWludCBpRGVjUG9zaXRpdmUsaURlY05hZ2F0aXZlOw0KLQkJaURlY1Bvc2l0aXZlID0gaURlYzI7DQotCQlpRGVjTmFnYXRpdmUgPSBpRGVjMjsNCi0JCQkNCi0JCWZvciAoaURlY1Bvc2l0aXZlID0gaURlYzIgLTM7IGlEZWNQb3NpdGl2ZSA+IDA7IGlEZWNQb3NpdGl2ZSAtPSAzKQ0KLQkJew0KLQkJCXN0clZhbHVlLkluc2VydChpRGVjUG9zaXRpdmUsY1NlcGVyYXRvcik7DQotCQkJaU1heCsrOw0KLQkJfQ0KLQl9DQotCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vDQotCS8vbmFnYXRpdmUgbWFyaw0KLQlpZihiTmFnYXRpdmUpDQotCQlzdHJWYWx1ZSA9ICItIiArIHN0clZhbHVlOw0KLQlzdHJWYWx1ZSArPSAiJSI7DQotCVZhbHVlID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChzdHJWYWx1ZSk7DQotI2VuZGlmDQotCXJldHVybiBUUlVFOw0KLX0NCi0vL0FGUGVyY2VudF9LZXlzdHJva2UobkRlYywgc2VwU3R5bGUpDQotRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZQZXJjZW50X0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXJldHVybiBBRk51bWJlcl9LZXlzdHJva2UoY2MscGFyYW1zLHZSZXQsc0Vycm9yKTsNCi19DQotDQotLy9mdW5jdGlvbiBBRkRhdGVfRm9ybWF0RXgoY0Zvcm1hdCkNCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkRhdGVfRm9ybWF0RXgoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpDQotCXsNCi0JCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0JDQotCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfV2lkZVN0cmluZyYgdmFsID0gcEV2ZW50LT5WYWx1ZSgpOw0KLQkNCi0JQ0ZYX1dpZGVTdHJpbmcgc3RyVmFsdWUgPSB2YWw7CQ0KLQlpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsJCQ0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzRm9ybWF0ID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCUZYX0JPT0wgYldyb25nRm9ybWF0ID0gRkFMU0U7DQotCWRvdWJsZSBkRGF0ZSA9IDAuMGY7DQotDQotCWlmKHN0clZhbHVlLkZpbmQoTCJHTVQiKSAhPSAtMSkNCi0Jew0KLQkJLy9mb3IgR01UIGZvcm1hdCB0aW1lDQotCQkvL3N1Y2ggYXMgIlR1ZSBBdWcgMTEgMTQ6MjQ6MTYgR01UKzA4MDAyMDA5Ig0KLQkJZERhdGUgPSBNYWtlSW50ZXJEYXRlKHN0clZhbHVlKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWREYXRlID0gTWFrZVJlZ3VsYXJEYXRlKHN0clZhbHVlLHNGb3JtYXQsYldyb25nRm9ybWF0KTsNCi0JfQ0KLQ0KLQlpZiAoSlNfUG9ydElzTmFuKGREYXRlKSkNCi0Jew0KLQkJQ0ZYX1dpZGVTdHJpbmcgc3dNc2c7DQotCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJTRURBVEUpLCAoRlhfTFBDV1NUUilzRm9ybWF0KTsNCi0JCUFsZXJ0KHBDb250ZXh0LCBzd01zZyk7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0JDQotCXZhbCA9ICBNYWtlRm9ybWF0RGF0ZShkRGF0ZSxzRm9ybWF0KTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLWRvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6TWFrZUludGVyRGF0ZShDRlhfV2lkZVN0cmluZyBzdHJWYWx1ZSkNCi17DQotCWludCBuSG91cjsNCi0JaW50IG5NaW47DQotCWludCBuU2VjOw0KLQlpbnQgblllYXI7DQotCWludCBuTW9udGg7DQotCWludCBuRGF5Ow0KLQ0KLQlDRlhfV2lkZVN0cmluZ0FycmF5IHdzQXJyYXk7DQotCUNGWF9XaWRlU3RyaW5nIHNNb250aCA9IEwiIjsNCi0JQ0ZYX1dpZGVTdHJpbmcgc1RlbXAgPSBMIiI7DQotCWludCBuU2l6ZSA9IHN0clZhbHVlLkdldExlbmd0aCgpOw0KLQ0KLQlmb3IoaW50IGkgPSAwOyBpIDwgblNpemU7IGkrKykNCi0Jew0KLQkJRlhfV0NIQVIgYyA9IHN0clZhbHVlLkdldEF0KGkpOw0KLQkJaWYoYyA9PSBMJyAnIHx8IGMgPT0gTCc6JykNCi0JCXsJDQotCQkJd3NBcnJheS5BZGQoc1RlbXApOw0KLQkJCXNUZW1wID0gTCIiOw0KLQkJCWNvbnRpbnVlOw0KLQkJfQ0KLQ0KLQkJc1RlbXAgKz0gYzsNCi0JfQ0KLQkNCi0Jd3NBcnJheS5BZGQoc1RlbXApOw0KLQlpZih3c0FycmF5LkdldFNpemUoKSAhPSA4KXJldHVybiAwOw0KLQ0KLQlzVGVtcCA9IHdzQXJyYXlbMV07DQotCWlmKHNUZW1wLkNvbXBhcmUoTCJKYW4iKSA9PSAwKSBuTW9udGggPSAxOw0KLQlpZihzVGVtcC5Db21wYXJlKEwiRmViIikgPT0gMCkgbk1vbnRoID0gMjsNCi0JaWYoc1RlbXAuQ29tcGFyZShMIk1hciIpID09IDApIG5Nb250aCA9IDM7DQotCWlmKHNUZW1wLkNvbXBhcmUoTCJBcHIiKSA9PSAwKSBuTW9udGggPSA0Ow0KLQlpZihzVGVtcC5Db21wYXJlKEwiTWF5IikgPT0gMCkgbk1vbnRoID0gNTsNCi0JaWYoc1RlbXAuQ29tcGFyZShMIkp1biIpID09IDApIG5Nb250aCA9IDY7DQotCWlmKHNUZW1wLkNvbXBhcmUoTCJKdWwiKSA9PSAwKSBuTW9udGggPSA3Ow0KLQlpZihzVGVtcC5Db21wYXJlKEwiQXVnIikgPT0gMCkgbk1vbnRoID0gODsNCi0JaWYoc1RlbXAuQ29tcGFyZShMIlNlcCIpID09IDApIG5Nb250aCA9IDk7DQotCWlmKHNUZW1wLkNvbXBhcmUoTCJPY3QiKSA9PSAwKSBuTW9udGggPSAxMDsNCi0JaWYoc1RlbXAuQ29tcGFyZShMIk5vdiIpID09IDApIG5Nb250aCA9IDExOw0KLQlpZihzVGVtcC5Db21wYXJlKEwiRGVjIikgPT0gMCkgbk1vbnRoID0gMTI7DQotDQotCW5EYXkgPSAoaW50KVBhcnNlU3RyaW5nVG9OdW1iZXIod3NBcnJheVsyXSk7DQotCW5Ib3VyID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbM10pOw0KLQluTWluID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbNF0pOw0KLQluU2VjID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbNV0pOw0KLQluWWVhciA9IChpbnQpUGFyc2VTdHJpbmdUb051bWJlcih3c0FycmF5WzddKTsNCi0NCi0JZG91YmxlIGRSZXQgPSBKU19NYWtlRGF0ZShKU19NYWtlRGF5KG5ZZWFyLG5Nb250aCAtIDEsbkRheSksSlNfTWFrZVRpbWUobkhvdXIsIG5NaW4sIG5TZWMsIDApKTsNCi0NCi0JaWYgKEpTX1BvcnRJc05hbihkUmV0KSkNCi0Jew0KLQkJZFJldCA9IEpTX0RhdGVQYXJzZShzdHJWYWx1ZSk7DQotCX0NCi0JDQotCXJldHVybiBkUmV0Ow0KLX0NCi0NCi0vL0FGRGF0ZV9LZXlzdHJva2VFeChjRm9ybWF0KQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGRGF0ZV9LZXlzdHJva2VFeChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsNCi0JQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkNCi0Jew0KLQkJc0Vycm9yID0gTCJBRkRhdGVfS2V5c3Ryb2tlRXgncyBwYXJhbWV0ZXJzJyBzaXplIHIgbm90IGNvcnJlY3QiOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9CQ0KLQkNCi0JaWYgKHBFdmVudC0+V2lsbENvbW1pdCgpKQ0KLQl7DQotCQlpZighcEV2ZW50LT5tX3BWYWx1ZSkNCi0JCQlyZXR1cm4gRkFMU0U7DQotCQlDRlhfV2lkZVN0cmluZyBzdHJWYWx1ZSA9IHBFdmVudC0+VmFsdWUoKTsNCi0JCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpIHJldHVybiBUUlVFOw0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgc0Zvcm1hdCA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJRlhfQk9PTCBiV3JvbmdGb3JtYXQgPSBGQUxTRTsNCi0JCWRvdWJsZSBkUmV0ID0gTWFrZVJlZ3VsYXJEYXRlKHN0clZhbHVlLHNGb3JtYXQsYldyb25nRm9ybWF0KTsNCi0JCWlmIChiV3JvbmdGb3JtYXQgfHwgSlNfUG9ydElzTmFuKGRSZXQpKQ0KLQkJew0KLQkJCUNGWF9XaWRlU3RyaW5nIHN3TXNnOw0KLQkJCXN3TXNnLkZvcm1hdChKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUlNFREFURSksIChGWF9MUENXU1RSKXNGb3JtYXQpOw0KLQkJCUFsZXJ0KHBDb250ZXh0LCBzd01zZyk7DQotCQkJcEV2ZW50LT5SYygpID0gRkFMU0U7DQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGRGF0ZV9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7DQotDQotCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpDQotCXsNCi0JCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotDQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCWludCBpSW5kZXggPSBwYXJhbXNbMF07DQotCUZYX0xQQ1dTVFIgY0Zvcm1hdHNbXSA9ICB7KEZYX0xQQ1dTVFIpTCJtL2QiLCAoRlhfTFBDV1NUUilMIm0vZC95eSIsIChGWF9MUENXU1RSKUwibW0vZGQveXkiLCAoRlhfTFBDV1NUUilMIm1tL3l5IiwgKEZYX0xQQ1dTVFIpTCJkLW1tbSIsIChGWF9MUENXU1RSKUwiZC1tbW0teXkiLCAoRlhfTFBDV1NUUilMImRkLW1tbS15eSIsDQotCQkoRlhfTFBDV1NUUilMInl5LW1tLWRkIiwgKEZYX0xQQ1dTVFIpTCJtbW0teXkiLCAoRlhfTFBDV1NUUilMIm1tbW0teXkiLCAoRlhfTFBDV1NUUilMIm1tbSBkLCB5eXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW1tIGQsIHl5eXkiLA0KLQkJKEZYX0xQQ1dTVFIpTCJtL2QveXkgaDpNTSB0dCIsIChGWF9MUENXU1RSKUwibS9kL3l5IEhIOk1NIiB9Ow0KLQ0KLQlBU1NFUlQoaUluZGV4IDwgc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpOw0KLQ0KLQlpZiAoaUluZGV4IDwgMCkNCi0JCWlJbmRleCA9IDA7DQotCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpDQotCQlpSW5kZXggPSAwOw0KLQlDSlNfUGFyYW1ldGVycyBuZXdQYXJhbXM7DQotCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsNCi0JbmV3UGFyYW1zLnB1c2hfYmFjayh2YWwpOw0KLQlyZXR1cm4gQUZEYXRlX0Zvcm1hdEV4KGNjLG5ld1BhcmFtcyx2UmV0LHNFcnJvcik7DQotfQ0KLQ0KLS8vQUZEYXRlX0tleXN0cm9rZUV4KGNGb3JtYXQpDQotRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZEYXRlX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkNCi0Jew0KLQkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JaW50IGlJbmRleCA9IHBhcmFtc1swXTsNCi0JRlhfTFBDV1NUUiBjRm9ybWF0c1tdID0gIHsoRlhfTFBDV1NUUilMIm0vZCIsIChGWF9MUENXU1RSKUwibS9kL3l5IiwgKEZYX0xQQ1dTVFIpTCJtbS9kZC95eSIsIChGWF9MUENXU1RSKUwibW0veXkiLCAoRlhfTFBDV1NUUilMImQtbW1tIiwgKEZYX0xQQ1dTVFIpTCJkLW1tbS15eSIsIChGWF9MUENXU1RSKUwiZGQtbW1tLXl5IiwNCi0JCShGWF9MUENXU1RSKUwieXktbW0tZGQiLCAoRlhfTFBDV1NUUilMIm1tbS15eSIsIChGWF9MUENXU1RSKUwibW1tbS15eSIsIChGWF9MUENXU1RSKUwibW1tIGQsIHl5eXkiLCAoRlhfTFBDV1NUUilMIm1tbW0gZCwgeXl5eSIsDQotCQkoRlhfTFBDV1NUUilMIm0vZC95eSBoOk1NIHR0IiwgKEZYX0xQQ1dTVFIpTCJtL2QveXkgSEg6TU0iIH07DQotDQotCUFTU0VSVChpSW5kZXg8c2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpOw0KLQ0KLQlpZiAoaUluZGV4IDwgMCkNCi0JCWlJbmRleCA9IDA7DQotCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpDQotCQlpSW5kZXggPSAwOw0KLQlDSlNfUGFyYW1ldGVycyBuZXdQYXJhbXM7DQotCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsNCi0JbmV3UGFyYW1zLnB1c2hfYmFjayh2YWwpOw0KLQlyZXR1cm4gQUZEYXRlX0tleXN0cm9rZUV4KGNjLG5ld1BhcmFtcyx2UmV0LHNFcnJvcik7DQotfQ0KLQ0KLS8vZnVuY3Rpb24gQUZUaW1lX0Zvcm1hdChwdGYpDQotRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZUaW1lX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkNCi0Jew0KLQkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JaW50IGlJbmRleCA9IHBhcmFtc1swXTsNCi0JRlhfTFBDV1NUUiBjRm9ybWF0c1tdID0geyhGWF9MUENXU1RSKUwiSEg6TU0iLCAoRlhfTFBDV1NUUilMImg6TU0gdHQiLCAoRlhfTFBDV1NUUilMIkhIOk1NOnNzIiwgKEZYX0xQQ1dTVFIpTCJoOk1NOnNzIHR0In07DQotDQotCUFTU0VSVChpSW5kZXg8c2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpOw0KLQ0KLQlpZiAoaUluZGV4IDwgMCkNCi0JCWlJbmRleCA9IDA7DQotCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpDQotCQlpSW5kZXggPSAwOw0KLQlDSlNfUGFyYW1ldGVycyBuZXdQYXJhbXM7DQotCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsNCi0JbmV3UGFyYW1zLnB1c2hfYmFjayh2YWwpOw0KLQlyZXR1cm4gQUZEYXRlX0Zvcm1hdEV4KGNjLG5ld1BhcmFtcyx2UmV0LHNFcnJvcik7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGVGltZV9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7DQotCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpDQotCXsNCi0JCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCWludCBpSW5kZXggPSBwYXJhbXNbMF07DQotCUZYX0xQQ1dTVFIgY0Zvcm1hdHNbXSA9IHsoRlhfTFBDV1NUUilMIkhIOk1NIiwgKEZYX0xQQ1dTVFIpTCJoOk1NIHR0IiwgKEZYX0xQQ1dTVFIpTCJISDpNTTpzcyIsIChGWF9MUENXU1RSKUwiaDpNTTpzcyB0dCJ9Ow0KLQ0KLQlBU1NFUlQoaUluZGV4PHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKTsNCi0NCi0JaWYgKGlJbmRleCA8IDApDQotCQlpSW5kZXggPSAwOw0KLQlpZiAoaUluZGV4ID49IHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKQ0KLQkJaUluZGV4ID0gMDsNCi0JQ0pTX1BhcmFtZXRlcnMgbmV3UGFyYW1zOw0KLQlDSlNfVmFsdWUgdmFsKGlzb2xhdGUsY0Zvcm1hdHNbaUluZGV4XSk7DQotCW5ld1BhcmFtcy5wdXNoX2JhY2sodmFsKTsNCi0JcmV0dXJuIEFGRGF0ZV9LZXlzdHJva2VFeChjYyxuZXdQYXJhbXMsdlJldCxzRXJyb3IpOw0KLX0NCi0NCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlRpbWVfRm9ybWF0RXgoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gQUZEYXRlX0Zvcm1hdEV4KGNjLHBhcmFtcyx2UmV0LHNFcnJvcik7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGVGltZV9LZXlzdHJva2VFeChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXJldHVybiBBRkRhdGVfS2V5c3Ryb2tlRXgoY2MscGFyYW1zLHZSZXQsc0Vycm9yKTsNCi19DQotDQotLy9mdW5jdGlvbiBBRlNwZWNpYWxfRm9ybWF0KHBzZikNCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlNwZWNpYWxfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlzdGQ6OnN0cmluZyBjRm9ybWF0Ow0KLQlpbnQgaUluZGV4ID0gcGFyYW1zWzBdOw0KLQ0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfV2lkZVN0cmluZyYgVmFsdWUgPSBwRXZlbnQtPlZhbHVlKCk7CQ0KLQlzdGQ6OnN0cmluZyBzdHJTcmMgPSAoRlhfTFBDU1RSKUNGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShWYWx1ZSk7DQotCQ0KLQlzd2l0Y2ggKGlJbmRleCkgDQotCXsNCi0JY2FzZSAwOiAgICAgICAgICAgICAgICAgICAgICAgICANCi0JCWNGb3JtYXQgPSAiOTk5OTkiOw0KLQkJYnJlYWs7DQotCWNhc2UgMTogICAgICAgICAgICAgICAgICAgICAgICAgDQotCQljRm9ybWF0ID0gIjk5OTk5LTk5OTkiOw0KLQkJYnJlYWs7DQotCWNhc2UgMjogICAgICAgICAgICAgICAgICAgICAgICAgDQotCQl7DQotCQkJc3RkOjpzdHJpbmcgTnVtYmVyU3RyOw0KLQkJCXV0aWw6OnByaW50eCgiOTk5OTk5OTk5OSIsIHN0clNyYyxOdW1iZXJTdHIpOyANCi0JCQlpZiAoTnVtYmVyU3RyLmxlbmd0aCgpID49IDEwICkNCi0JCQkJY0Zvcm1hdCA9ICIoOTk5KSA5OTktOTk5OSI7DQotCQkJZWxzZSANCi0JCQkJY0Zvcm1hdCA9ICI5OTktOTk5OSI7DQotCQkJYnJlYWs7DQotCQl9DQotCWNhc2UgMzoNCi0JCWNGb3JtYXQgPSAiOTk5LTk5LTk5OTkiOw0KLQkJYnJlYWs7DQotCX0NCi0JDQotCXN0ZDo6c3RyaW5nIHN0ckRlczsNCi0JdXRpbDo6cHJpbnR4KGNGb3JtYXQsc3RyU3JjLHN0ckRlcyk7DQotCVZhbHVlID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbChzdHJEZXMuY19zdHIoKSk7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0NCi0vL2Z1bmN0aW9uIEFGU3BlY2lhbF9LZXlzdHJva2VFeChtYXNrKQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGU3BlY2lhbF9LZXlzdHJva2VFeChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsNCi0NCi0JQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgPCAxKQ0KLQl7DQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfV2lkZVN0cmluZyYgdmFsRXZlbnQgPSBwRXZlbnQtPlZhbHVlKCk7DQotDQotCUNGWF9XaWRlU3RyaW5nIHdzdHJNYXNrID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotCWlmICh3c3RyTWFzay5Jc0VtcHR5KCkpIHJldHVybiBUUlVFOw0KLQkNCi0Jc3RkOjp3c3RyaW5nIHdzdHJWYWx1ZSh2YWxFdmVudCk7DQotCQ0KLQlpZiAocEV2ZW50LT5XaWxsQ29tbWl0KCkpDQotCXsNCi0JCWlmICh3c3RyVmFsdWUuZW1wdHkoKSkNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCWludCBpSW5kZXhNYXNrID0gMDsNCi0JCWZvciAoc3RkOjp3c3RyaW5nOjppdGVyYXRvciBpdCA9IHdzdHJWYWx1ZS5iZWdpbigpOyBpdCAhPSB3c3RyVmFsdWUuZW5kKCk7IGl0KyspDQotCQl7DQotCQkJd2NoYXJfdCB3X1ZhbHVlID0gKml0Ow0KLSAgICAgICAgICAgIGlmICghbWFza1NhdGlzZmllZCh3X1ZhbHVlLHdzdHJNYXNrW2lJbmRleE1hc2tdKSkNCi0JCQkJYnJlYWs7DQotCQkJaUluZGV4TWFzaysrOw0KLQkJfQ0KLQ0KLQkJaWYgKGlJbmRleE1hc2sgIT0gd3N0ck1hc2suR2V0TGVuZ3RoKCkgfHwgKGlJbmRleE1hc2sgIT0gd3N0clZhbHVlLnNpemUoKSAmJiB3c3RyTWFzay5HZXRMZW5ndGgoKSAhPSAwKSkNCi0JCXsNCi0JCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UpKTsNCi0JCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsNCi0JCX0NCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCQ0KLQlDRlhfV2lkZVN0cmluZyAmd2lkZUNoYW5nZSA9IHBFdmVudC0+Q2hhbmdlKCk7DQotCXN0ZDo6d3N0cmluZyB3Q2hhbmdlKHdpZGVDaGFuZ2UpOw0KLQkNCi0JaWYgKHdDaGFuZ2UuZW1wdHkoKSkNCi0JCXJldHVybiBUUlVFOw0KLSAgICBpbnQgaUluZGV4TWFzayA9IHBFdmVudC0+U2VsU3RhcnQoKTsNCi0JLy9pSW5kZXhNYXNrKys7DQotCQ0KLQkNCi0JaWYgKHdzdHJWYWx1ZS5sZW5ndGgoKSAtIChwRXZlbnQtPlNlbEVuZCgpLXBFdmVudC0+U2VsU3RhcnQoKSkgKyB3Q2hhbmdlLmxlbmd0aCgpID4gKEZYX0RXT1JEKXdzdHJNYXNrLkdldExlbmd0aCgpKQ0KLQl7DQotCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HKSk7DQotCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCQ0KLQkNCi0JaWYgKGlJbmRleE1hc2sgPj0gd3N0ck1hc2suR2V0TGVuZ3RoKCkgJiYgKCF3Q2hhbmdlLmVtcHR5KCkpKQ0KLQl7DQotCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HKSk7DQotCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCQ0KLQlmb3IgKHN0ZDo6d3N0cmluZzo6aXRlcmF0b3IgaXQgPSB3Q2hhbmdlLmJlZ2luKCk7IGl0ICE9IHdDaGFuZ2UuZW5kKCk7IGl0KyspDQotCXsNCi0JCWlmIChpSW5kZXhNYXNrID49IHdzdHJNYXNrLkdldExlbmd0aCgpKQ0KLQkJew0KLQkJCUFsZXJ0KHBDb250ZXh0LCBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNX1RPT0xPTkcpKTsNCi0JCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JCXdjaGFyX3Qgd19NYXNrID0gd3N0ck1hc2tbaUluZGV4TWFza107DQotCQlpZiAoIWlzUmVzZXJ2ZWRNYXNrQ2hhcih3X01hc2spKQ0KLQkJew0KLQkJCS8vd0NoYW5nZS5pbnNlcnQoaXQsd19NYXNrKTsJCQkJDQotCQkJKml0ID0gd19NYXNrOw0KLQkJfQ0KLQkJd2NoYXJfdCB3X0NoYW5nZSA9ICppdDsNCi0JCQ0KLSAgICAgICAgaWYgKCFtYXNrU2F0aXNmaWVkKHdfQ2hhbmdlLHdfTWFzaykpDQotCQl7DQotCQkJcEV2ZW50LT5SYygpID0gRkFMU0U7DQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCQlpSW5kZXhNYXNrKys7DQotCX0NCi0JDQotCXdpZGVDaGFuZ2UgPSB3Q2hhbmdlLmNfc3RyKCk7CQ0KLQkNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLQ0KLS8vZnVuY3Rpb24gQUZTcGVjaWFsX0tleXN0cm9rZShwc2YpDQotRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTcGVjaWFsX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSAxKQ0KLQl7DQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCXN0ZDo6c3RyaW5nIGNGb3JtYXQ7DQotCWludCBpSW5kZXggPSAoaW50KXBhcmFtc1swXTsJDQotDQotCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQkvL0NKU19WYWx1ZSB2YWwgPSBwRXZlbnQtPlZhbHVlKCk7DQotCUNGWF9XaWRlU3RyaW5nJiB2YWwgPSBwRXZlbnQtPlZhbHVlKCk7DQotCXN0ZDo6c3RyaW5nIHN0clNyYyA9IChGWF9MUENTVFIpQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHZhbCk7DQotCXN0ZDo6d3N0cmluZyB3c3RyQ2hhbmdlKHBFdmVudC0+Q2hhbmdlKCkpOw0KLQkNCi0Jc3dpdGNoIChpSW5kZXgpIA0KLQl7DQotCWNhc2UgMDogICAgICAgICAgICAgICAgICAgICAgICAgDQotCQljRm9ybWF0ID0gIjk5OTk5IjsNCi0JCWJyZWFrOw0KLQljYXNlIDE6ICAgICAgICAgICAgICAgICAgICAgICAgIA0KLQkJLy9jRm9ybWF0ID0gIjk5OTk5LTk5OTkiOw0KLQkJY0Zvcm1hdCA9ICI5OTk5OTk5OTkiOw0KLQkJYnJlYWs7DQotCWNhc2UgMjogICAgICAgICAgICAgICAgICAgICAgICAgDQotCQl7DQotCQkJc3RkOjpzdHJpbmcgTnVtYmVyU3RyOw0KLQkJCXV0aWw6OnByaW50eCgiOTk5OTk5OTk5OSIsIHN0clNyYyxOdW1iZXJTdHIpOyANCi0JCQlpZiAoc3RyU3JjLmxlbmd0aCgpICsgd3N0ckNoYW5nZS5sZW5ndGgoKSA+IDcgKQ0KLQkJCQkvL2NGb3JtYXQgPSAiKDk5OSkgOTk5LTk5OTkiOw0KLQkJCQljRm9ybWF0ID0gIjk5OTk5OTk5OTkiOw0KLQkJCWVsc2UgDQotCQkJCS8vY0Zvcm1hdCA9ICI5OTktOTk5OSI7DQotCQkJCWNGb3JtYXQgPSAiOTk5OTk5OSI7DQotCQkJYnJlYWs7DQotCQl9DQotCWNhc2UgMzoNCi0JCS8vY0Zvcm1hdCA9ICI5OTktOTktOTk5OSI7DQotCQljRm9ybWF0ID0gIjk5OTk5OTk5OSI7DQotCQlicmVhazsNCi0JfQ0KLSAgICANCi0JQ0pTX1BhcmFtZXRlcnMgcGFyYW1zMjsNCi0JQ0pTX1ZhbHVlIHZNYXNrKGlzb2xhdGUsIGNGb3JtYXQuY19zdHIoKSk7DQotCXBhcmFtczIucHVzaF9iYWNrKHZNYXNrKTsNCi0JDQotICAgIHJldHVybiBBRlNwZWNpYWxfS2V5c3Ryb2tlRXgoY2MscGFyYW1zMix2UmV0LHNFcnJvcik7DQotfQ0KLQ0KLUZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTWVyZ2VDaGFuZ2UoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnRIYW5kbGVyID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50SGFuZGxlciAhPSBOVUxMKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzd1ZhbHVlOw0KLQlpZiAocEV2ZW50SGFuZGxlci0+bV9wVmFsdWUgIT0gTlVMTCkNCi0JCXN3VmFsdWUgPSBwRXZlbnRIYW5kbGVyLT5WYWx1ZSgpOw0KLQ0KLQlpZiAocEV2ZW50SGFuZGxlci0+V2lsbENvbW1pdCgpKQ0KLQl7DQotCQl2UmV0ID0gc3dWYWx1ZTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCUNGWF9XaWRlU3RyaW5nIHByZWZpeCxwb3N0Zml4Ow0KLQ0KLQlpZiAocEV2ZW50SGFuZGxlci0+U2VsU3RhcnQoKSA+PSAwKQ0KLQkJcHJlZml4ID0gc3dWYWx1ZS5NaWQoMCxwRXZlbnRIYW5kbGVyLT5TZWxTdGFydCgpKTsNCi0JZWxzZQ0KLQkJcHJlZml4ID0gTCIiOw0KLQ0KLQ0KLQlpZiAocEV2ZW50SGFuZGxlci0+U2VsRW5kKCkgPj0gMCAmJiBwRXZlbnRIYW5kbGVyLT5TZWxFbmQoKSA8PSBzd1ZhbHVlLkdldExlbmd0aCgpKQ0KLQkJcG9zdGZpeCA9IHN3VmFsdWUuTWlkKHBFdmVudEhhbmRsZXItPlNlbEVuZCgpLCBzd1ZhbHVlLkdldExlbmd0aCgpIC0gcEV2ZW50SGFuZGxlci0+U2VsRW5kKCkpOw0KLQllbHNlIHBvc3RmaXggPSBMIiI7DQotDQotCXZSZXQgPSBwcmVmaXggKyBwRXZlbnRIYW5kbGVyLT5DaGFuZ2UoKSArIHBvc3RmaXg7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlBhcnNlRGF0ZUV4KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMikNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzVmFsdWUgPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0JQ0ZYX1dpZGVTdHJpbmcgc0Zvcm1hdCA9IHBhcmFtc1sxXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQlGWF9CT09MIGJXcm9uZ0Zvcm1hdCA9IEZBTFNFOw0KLQlkb3VibGUgZERhdGUgPSBNYWtlUmVndWxhckRhdGUoc1ZhbHVlLHNGb3JtYXQsYldyb25nRm9ybWF0KTsNCi0NCi0JaWYgKEpTX1BvcnRJc05hbihkRGF0ZSkpDQotCXsNCi0JCUNGWF9XaWRlU3RyaW5nIHN3TXNnOw0KLQkJc3dNc2cuRm9ybWF0KEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSU0VEQVRFKSwgKEZYX0xQQ1dTVFIpc0Zvcm1hdCk7DQotCQlBbGVydCgoQ0pTX0NvbnRleHQgKiljYywgc3dNc2cpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCQ0KLQl2UmV0ID0gZERhdGU7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlNpbXBsZShPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCWlmIChwYXJhbXMuc2l6ZSgpICE9IDMpDQotCXsNCi0JCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQl2UmV0ID0gKGRvdWJsZSlBRl9TaW1wbGUocGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCksIChkb3VibGUpcGFyYW1zWzFdLCAoZG91YmxlKXBhcmFtc1syXSk7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRk1ha2VOdW1iZXIoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSAxKQ0KLQl7DQotCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsNCi0JCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0gICAgdlJldCA9IFBhcnNlU3RyaW5nVG9OdW1iZXIocGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTaW1wbGVfQ2FsY3VsYXRlKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOw0KLQ0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSAyKQ0KLQl7DQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOw0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCUNKU19WYWx1ZSBwYXJhbXMxID0gcGFyYW1zWzFdOw0KLQ0KLQlpZiAoIXBhcmFtczEuSXNBcnJheU9iamVjdCgpICYmIHBhcmFtczEuR2V0VHlwZSgpICE9IFZUX3N0cmluZykNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQkNCi0JQ1BERlNES19Eb2N1bWVudCogcFJlYWRlckRvYyA9IHBDb250ZXh0LT5HZXRSZWFkZXJEb2N1bWVudCgpOw0KLSAgICBBU1NFUlQocFJlYWRlckRvYyAhPSBOVUxMKTsNCi0NCi0JQ1BERlNES19JbnRlckZvcm0qIHBSZWFkZXJJbnRlckZvcm0gPSBwUmVhZGVyRG9jLT5HZXRJbnRlckZvcm0oKTsNCi0JQVNTRVJUKHBSZWFkZXJJbnRlckZvcm0gIT0gTlVMTCk7DQotDQotCUNQREZfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gcFJlYWRlckludGVyRm9ybS0+R2V0SW50ZXJGb3JtKCk7DQotCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOw0KLQ0KLQlkb3VibGUgZFZhbHVlOw0KLQlDRlhfV2lkZVN0cmluZyBzRnVuY3Rpb24gPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0JaWYgKHdjc2NtcChzRnVuY3Rpb24sIEwiUFJEIikgPT0gMCkNCi0gICAgCWRWYWx1ZSA9IDEuMDsNCi0JZWxzZQ0KLQkJZFZhbHVlID0gMC4wOw0KLQ0KLQlDSlNfQXJyYXkgRmllbGROYW1lQXJyYXkgPSBBRl9NYWtlQXJyYXlGcm9tTGlzdChpc29sYXRlLHBhcmFtczEpOw0KLQ0KLQlpbnQgbkZpZWxkc0NvdW50ID0gMDsNCi0NCi0JZm9yIChpbnQgaT0wLGlzej1GaWVsZE5hbWVBcnJheS5HZXRMZW5ndGgoKTsgaTxpc3o7IGkrKykNCi0Jew0KLQkJQ0pTX1ZhbHVlIGpzVmFsdWUoaXNvbGF0ZSk7DQotCQlGaWVsZE5hbWVBcnJheS5HZXRFbGVtZW50KGksanNWYWx1ZSk7DQotICAgICAgICBDRlhfV2lkZVN0cmluZyB3c0ZpZWxkTmFtZSA9IGpzVmFsdWUub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0NCi0gICAgICAgIGZvciAoaW50IGo9MCxqc3o9cEludGVyRm9ybS0+Q291bnRGaWVsZHMod3NGaWVsZE5hbWUpOyBqPGpzejsgaisrKQ0KLQkJew0KLQkJCWlmIChDUERGX0Zvcm1GaWVsZCogcEZvcm1GaWVsZCA9IHBJbnRlckZvcm0tPkdldEZpZWxkKGosIHdzRmllbGROYW1lKSkNCi0JCQl7DQotCQkJCWRvdWJsZSBkVGVtcCA9IDAuMDsNCi0NCi0JCQkJc3dpdGNoIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSkNCi0JCQkJew0KLQkJCQljYXNlIEZJRUxEVFlQRV9URVhURklFTEQ6DQotCQkJCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOg0KLQkJCQkJew0KLQkJCQkJCWRUZW1wID0gUGFyc2VTdHJpbmdUb051bWJlcihwRm9ybUZpZWxkLT5HZXRWYWx1ZSgpKTsNCi0JCQkJCQlicmVhazsNCi0JCQkJCX0NCi0JCQkJY2FzZSBGSUVMRFRZUEVfUFVTSEJVVFRPTjoNCi0JCQkJCXsNCi0JCQkJCQlkVGVtcCA9IDAuMDsNCi0JCQkJCQlicmVhazsNCi0JCQkJCX0NCi0JCQkJY2FzZSBGSUVMRFRZUEVfQ0hFQ0tCT1g6DQotCQkJCWNhc2UgRklFTERUWVBFX1JBRElPQlVUVE9OOg0KLQkJCQkJew0KLQkJCQkJCWRUZW1wID0gMC4wOw0KLQkJCQkJCWZvciAoaW50IGM9MCxjc3o9cEZvcm1GaWVsZC0+Q291bnRDb250cm9scygpOyBjPGNzejsgYysrKQ0KLQkJCQkJCXsNCi0JCQkJCQkJaWYgKENQREZfRm9ybUNvbnRyb2wqIHBGb3JtQ3RybCA9IHBGb3JtRmllbGQtPkdldENvbnRyb2woYykpDQotCQkJCQkJCXsNCi0JCQkJCQkJCWlmIChwRm9ybUN0cmwtPklzQ2hlY2tlZCgpKQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCWRUZW1wICs9IFBhcnNlU3RyaW5nVG9OdW1iZXIocEZvcm1DdHJsLT5HZXRFeHBvcnRWYWx1ZSgpKTsNCi0JCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJCX0NCi0JCQkJCQkJCWVsc2UNCi0JCQkJCQkJCQljb250aW51ZTsNCi0JCQkJCQkJfQ0KLQkJCQkJCX0NCi0JCQkJCQlicmVhazsNCi0JCQkJCX0NCi0JCQkJY2FzZSBGSUVMRFRZUEVfTElTVEJPWDoNCi0JCQkJCXsNCi0JCQkJCQlkVGVtcCA9IDAuMDsNCi0JCQkJCQlpZiAocEZvcm1GaWVsZC0+Q291bnRTZWxlY3RlZEl0ZW1zKCkgPiAxKQ0KLQkJCQkJCQlicmVhazsNCi0JCQkJCQllbHNlDQotCQkJCQkJew0KLQkJCQkJCQlkVGVtcCA9IFBhcnNlU3RyaW5nVG9OdW1iZXIocEZvcm1GaWVsZC0+R2V0VmFsdWUoKSk7DQotCQkJCQkJCWJyZWFrOw0KLQkJCQkJCX0NCi0JCQkJCX0NCi0JCQkJZGVmYXVsdDoNCi0JCQkJCWJyZWFrOw0KLQkJCQl9DQotDQotCQkJCWlmIChpID09IDAgJiYgaiA9PSAwICYmICh3Y3NjbXAoc0Z1bmN0aW9uLEwiTUlOIikgPT0gMCB8fCB3Y3NjbXAoc0Z1bmN0aW9uLCBMIk1BWCIpID09IDApKQ0KLQkJCQkJZFZhbHVlID0gZFRlbXA7DQotDQotCQkJCWRWYWx1ZSA9IEFGX1NpbXBsZShzRnVuY3Rpb24sIGRWYWx1ZSwgZFRlbXApOw0KLQ0KLQkJCQluRmllbGRzQ291bnQrKzsNCi0JCQl9DQotCQl9DQotCX0NCi0NCi0JaWYgKHdjc2NtcChzRnVuY3Rpb24sIEwiQVZHIikgPT0gMCAmJiBuRmllbGRzQ291bnQgPiAwKQ0KLQkJZFZhbHVlIC89IG5GaWVsZHNDb3VudDsNCi0NCi0JZFZhbHVlID0gKGRvdWJsZSlmbG9vcihkVmFsdWUgKiBGWFNZU19wb3coKGRvdWJsZSkxMCwoZG91YmxlKTYpICsgMC40OSkgLyBGWFNZU19wb3coKGRvdWJsZSkxMCwoZG91YmxlKTYpOw0KLQlDSlNfVmFsdWUganNWYWx1ZShpc29sYXRlLGRWYWx1ZSk7DQotCWlmKChDSlNfRXZlbnRIYW5kbGVyKilwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCktPm1fcFZhbHVlKQ0KLQkJKChDSlNfRXZlbnRIYW5kbGVyKilwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCkpLT5WYWx1ZSgpID0ganNWYWx1ZTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8qIFRoaXMgZnVuY3Rpb24gdmFsaWRhdGVzIHRoZSBjdXJyZW50IGV2ZW50IHRvIGVuc3VyZSB0aGF0IGl0cyB2YWx1ZSBpcyANCi0qKiB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZS4gKi8NCi0NCi1GWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlJhbmdlX1ZhbGlkYXRlKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSA0KSANCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlpZighcEV2ZW50LT5tX3BWYWx1ZSkNCi0JCXJldHVybiBGQUxTRTsNCi0JaWYgKHBFdmVudC0+VmFsdWUoKS5Jc0VtcHR5KCkgKQ0KLQkJcmV0dXJuIFRSVUU7DQotCWRvdWJsZSBkRWVudFZhbHVlID0gYXRvZihDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUocEV2ZW50LT5WYWx1ZSgpKSk7DQotCUZYX0JPT0wgYkdyZWF0ZXJUaGFuLCBiTGVzc1RoYW47DQotCWRvdWJsZSAgZEdyZWF0ZXJUaGFuLCBkTGVzc1RoYW47DQotICAgIGJHcmVhdGVyVGhhbiA9IChGWF9CT09MKXBhcmFtc1swXTsNCi0JQ0ZYX1dpZGVTdHJpbmcgc3dNc2c7DQotCWRHcmVhdGVyVGhhbiA9IChkb3VibGUpcGFyYW1zWzFdOw0KLQliTGVzc1RoYW4gPSAoRlhfQk9PTClwYXJhbXNbMl07DQotCWRMZXNzVGhhbiA9IChkb3VibGUpcGFyYW1zWzNdOw0KLQ0KLQlpZiAoYkdyZWF0ZXJUaGFuICYmIGJMZXNzVGhhbikNCi0Jew0KLQkJaWYgKGRFZW50VmFsdWUgPCBkR3JlYXRlclRoYW4gfHwgZEVlbnRWYWx1ZSA+IGRMZXNzVGhhbikNCi0JCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNSQU5HRTEpLChGWF9MUENXU1RSKXBhcmFtc1sxXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpLCAoRlhfTFBDV1NUUilwYXJhbXNbM10ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7DQotCX0NCi0JZWxzZSBpZiAoYkdyZWF0ZXJUaGFuKQ0KLQl7DQotCQlpZiAoZEVlbnRWYWx1ZSA8IGRHcmVhdGVyVGhhbikNCi0JCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNSQU5HRTIpLCAoRlhfTFBDV1NUUilwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7DQotCX0NCi0JZWxzZSBpZiAoYkxlc3NUaGFuKQ0KLQl7DQotCQlpZiAoZEVlbnRWYWx1ZSA+IGRMZXNzVGhhbikNCi0JCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNSQU5HRTMpLCAoRlhfTFBDV1NUUilwYXJhbXNbM10ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7DQotCX0NCi0NCi0JaWYgKCFzd01zZy5Jc0VtcHR5KCkpDQotCXsNCi0JCUFsZXJ0KHBDb250ZXh0LCBzd01zZyk7DQotCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsNCi0JfQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZFeHRyYWN0TnVtcyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSAxKSANCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQ0KLQlDSlNfQXJyYXkgbnVtcyhpc29sYXRlKTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc3RyID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotCUNGWF9XaWRlU3RyaW5nIHNQYXJ0Ow0KLQ0KLQlpZiAoc3RyLkdldEF0KDApID09IEwnLicgfHwgc3RyLkdldEF0KDApID09IEwnLCcpDQotCQlzdHIgPSBMIjAiICsgc3RyOw0KLQ0KLQlpbnQgbkluZGV4ID0gMDsNCi0JZm9yIChpbnQgaT0wLCBzej1zdHIuR2V0TGVuZ3RoKCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJRlhfV0NIQVIgd2MgPSBzdHIuR2V0QXQoaSk7DQotCQlpZiAoSXNEaWdpdCgod2NoYXJfdCl3YykpDQotCQl7DQotCQkJc1BhcnQgKz0gd2M7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYgKHNQYXJ0LkdldExlbmd0aCgpID4gMCkNCi0JCQl7DQotCQkJCW51bXMuU2V0RWxlbWVudChuSW5kZXgsQ0pTX1ZhbHVlKGlzb2xhdGUsKEZYX0xQQ1dTVFIpc1BhcnQpKTsNCi0JCQkJc1BhcnQgPSBMIiI7DQotCQkJCW5JbmRleCArKzsNCi0JCQl9DQotCQl9DQotCX0NCi0NCi0JaWYgKHNQYXJ0LkdldExlbmd0aCgpID4gMCkNCi0Jew0KLQkJbnVtcy5TZXRFbGVtZW50KG5JbmRleCxDSlNfVmFsdWUoaXNvbGF0ZSwoRlhfTFBDV1NUUilzUGFydCkpOwkNCi0JfQ0KLQ0KLQlpZiAobnVtcy5HZXRMZW5ndGgoKSA+IDApDQotCQl2UmV0ID0gbnVtczsNCi0JZWxzZQ0KLQkJdlJldC5TZXROdWxsKCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9QdWJsaWNNZXRob2RzLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9yZXNvdXJjZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L3V0aWwuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvRmllbGQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvY29sb3IuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIgorCitzdGF0aWMgdjg6Oklzb2xhdGUqIEdldElzb2xhdGUoSUZYSlNfQ29udGV4dCogY2MpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCXJldHVybiBwUnVudGltZS0+R2V0SXNvbGF0ZSgpOworfQorCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENKU19QdWJsaWNNZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKKyNkZWZpbmUgRE9VQkxFX0NPUlJFQ1QJMC4wMDAwMDAwMDAwMDAwMDEKKworQkVHSU5fSlNfU1RBVElDX0dMT0JBTF9GVU4oQ0pTX1B1YmxpY01ldGhvZHMpCisJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZOdW1iZXJfRm9ybWF0LDYpCisJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZOdW1iZXJfS2V5c3Ryb2tlLDYpCisJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQZXJjZW50X0Zvcm1hdCwyKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGUGVyY2VudF9LZXlzdHJva2UsMikKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRkRhdGVfRm9ybWF0RXgsMSkKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRkRhdGVfS2V5c3Ryb2tlRXgsMSkKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRkRhdGVfRm9ybWF0LDEpCisJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZEYXRlX0tleXN0cm9rZSwxKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGVGltZV9Gb3JtYXRFeCwxKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGVGltZV9LZXlzdHJva2VFeCwxKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGVGltZV9Gb3JtYXQsMSkKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlRpbWVfS2V5c3Ryb2tlLDEpCisJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZTcGVjaWFsX0Zvcm1hdCwxKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU3BlY2lhbF9LZXlzdHJva2UsMSkKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNwZWNpYWxfS2V5c3Ryb2tlRXgsMSkKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRlNpbXBsZSwzKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGTWFrZU51bWJlciwxKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGU2ltcGxlX0NhbGN1bGF0ZSwyKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGUmFuZ2VfVmFsaWRhdGUsNCkKKwlKU19TVEFUSUNfR0xPQkFMX0ZVTl9FTlRSWShBRk1lcmdlQ2hhbmdlLDEpCisJSlNfU1RBVElDX0dMT0JBTF9GVU5fRU5UUlkoQUZQYXJzZURhdGVFeCwyKQorCUpTX1NUQVRJQ19HTE9CQUxfRlVOX0VOVFJZKEFGRXh0cmFjdE51bXMsMSkKK0VORF9KU19TVEFUSUNfR0xPQkFMX0ZVTigpCisKK0lNUExFTUVOVF9KU19TVEFUSUNfR0xPQkFMX0ZVTihDSlNfUHVibGljTWV0aG9kcykKKworc3RydWN0IHN0cnVfVGJDb252ZXJ0Cit7CisJRlhfTFBDU1RSIGxwc3pKU01hcms7CisJRlhfTFBDU1RSIGxwc3pDcHBNYXJrOworfTsKKworc3RhdGljIGNvbnN0IHN0cnVfVGJDb252ZXJ0IGZjVGFibGVbXSA9IHsibW1tbSIsIiVCIiwKKwkibW1tIiwgIiViIiwKKwkibW0iLCAgIiVtIiwKKwkvLyJtIgorCSJkZGRkIiwiJUEiLAorCSJkZGQiLCAiJWEiLAorCSJkZCIsICAiJWQiLAorCS8vImQiLCAgICIldyIsCisJInl5eXkiLCIlWSIsCisJInl5IiwgICIleSIsCisJIkhIIiwgICIlSCIsCisJLy8iSCIKKwkiaGgiLCAgIiVJIiwKKwkvLyJoIgorCSJNTSIsICAiJU0iLAorCS8vIk0iCisJInNzIiwgICIlUyIsCisJLy8icworCSJ0dCIsICAiJXAiCisJLy8idCIKK307CisKK3N0YXRpYyBGWF9MUENXU1RSIG1vbnRoc1tdID0KK3sKKwkoRlhfTFBDV1NUUilMIkphbiIsIChGWF9MUENXU1RSKUwiRmViIiwgKEZYX0xQQ1dTVFIpTCJNYXIiLCAoRlhfTFBDV1NUUilMIkFwciIsIChGWF9MUENXU1RSKUwiTWF5IiwgKEZYX0xQQ1dTVFIpTCJKdW4iLCAoRlhfTFBDV1NUUilMIkp1bCIsIChGWF9MUENXU1RSKUwiQXVnIiwgKEZYX0xQQ1dTVFIpTCJTZXAiLCAoRlhfTFBDV1NUUilMIk9jdCIsIChGWF9MUENXU1RSKUwiTm92IiwgKEZYX0xQQ1dTVFIpTCJEZWMiCit9OworCitzdGF0aWMgRlhfTFBDV1NUUiBmdWxsbW9udGhzW10gPSAKK3sgCisJKEZYX0xQQ1dTVFIpTCJKYW51YXJ5IiwgKEZYX0xQQ1dTVFIpTCJGZWJydWFyeSIsIChGWF9MUENXU1RSKUwiTWFyY2giLCAoRlhfTFBDV1NUUilMIkFwcmlsIiwgKEZYX0xQQ1dTVFIpTCJNYXkiLCAoRlhfTFBDV1NUUilMIkp1bmUiLCAoRlhfTFBDV1NUUilMIkp1bHkiLCAoRlhfTFBDV1NUUilMIkF1Z3VzdCIsIChGWF9MUENXU1RSKUwiU2VwdGVtYmVyIiwgKEZYX0xQQ1dTVFIpTCJPY3RvYmVyIiwgKEZYX0xQQ1dTVFIpTCJOb3ZlbWJlciIsIChGWF9MUENXU1RSKUwiRGVjZW1iZXIiIAorfTsKKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNOdW1iZXIoRlhfTFBDV1NUUiBzdHJpbmcpCit7CisJQ0ZYX1dpZGVTdHJpbmcgc1RyaW0gPSBTdHJUcmltKHN0cmluZyk7CisJRlhfTFBDV1NUUiBwVHJpbSA9IHNUcmltOworCUZYX0xQQ1dTVFIgcCA9IHBUcmltOworCisKKwlGWF9CT09MIGJEb3QgPSBGQUxTRTsKKwlGWF9CT09MIGJLWEpTID0gRkFMU0U7CisKKwl3Y2hhcl90IGM7CisJd2hpbGUgKChjID0gKnApKQorCXsKKwkJaWYgKGMgPT0gJy4nIHx8IGMgPT0gJywnKQorCQl7CisJCQlpZiAoYkRvdCkgcmV0dXJuIEZBTFNFOworCQkJYkRvdCA9IFRSVUU7CisJCX0KKwkJZWxzZSBpZiAoYyA9PSAnLScgfHwgYyA9PSAnKycpCisJCXsKKwkJCWlmIChwICE9IHBUcmltKQorCQkJCXJldHVybiBGQUxTRTsKKwkJfQorCQllbHNlIGlmIChjID09ICdlJyB8fCBjID09ICdFJykKKwkJeworCQkJaWYgKGJLWEpTKSByZXR1cm4gRkFMU0U7CisKKwkJCXArKzsKKwkJCWMgPSAqcDsKKwkJCWlmIChjID09ICcrJyB8fCBjID09ICctJykKKwkJCXsKKwkJCQliS1hKUyA9IFRSVUU7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJcmV0dXJuIEZBTFNFOworCQkJfQorCQl9CisJCWVsc2UgaWYgKCFJc0RpZ2l0KGMpKQorCQl7CisJCQlyZXR1cm4gRkFMU0U7CisJCX0KKwkJcCsrOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpJc0RpZ2l0KHdjaGFyX3QgY2gpCit7CisJcmV0dXJuIChjaCA+PSBMJzAnICYmIGNoIDw9IEwnOScpOworfQorCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpJc0RpZ2l0KGNoYXIgY2gpCit7CisJcmV0dXJuIChjaCA+PSAnMCcgJiYgY2ggPD0gJzknKTsKK30KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6SXNBbHBoYWJldGljKHdjaGFyX3QgY2gpCit7CisJcmV0dXJuICgoY2ggPj0gTCdhJyAmJiBjaCA8PSBMJ3onKSB8fCAoY2ggPj0gTCdBJyAmJiBjaCA8PSBMJ1onKSk7Cit9CisKK0ZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OklzQWxwaGFOdW1lcmljKHdjaGFyX3QgY2gpCit7CisJcmV0dXJuIChJc0RpZ2l0KGNoKSB8fCBJc0FscGhhYmV0aWMoY2gpKTsKK30KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6bWFza1NhdGlzZmllZCh3Y2hhcl90IGNfQ2hhbmdlLHdjaGFyX3QgY19NYXNrKQoreworCXN3aXRjaCAoY19NYXNrKQorCXsKKwljYXNlIEwnOSc6CisgICAgICAgIHJldHVybiBJc0RpZ2l0KGNfQ2hhbmdlKTsJCQorICAgIGNhc2UgTCdBJzoKKyAgICAgICAgcmV0dXJuIElzQWxwaGFiZXRpYyhjX0NoYW5nZSk7CQkKKyAgICBjYXNlIEwnTyc6CisgICAgICAgIHJldHVybiBJc0FscGhhTnVtZXJpYyhjX0NoYW5nZSk7CQkKKyAgICBjYXNlIEwnWCc6CisgICAgICAgIHJldHVybiBUUlVFOwkJCisJZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIChjX0NoYW5nZSA9PSBjX01hc2spOworCX0KK30KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6aXNSZXNlcnZlZE1hc2tDaGFyKHdjaGFyX3QgY2gpCit7CisJcmV0dXJuIGNoID09IEwnOScgfHwgY2ggPT0gTCdBJyB8fCBjaCA9PSBMJ08nIHx8IGNoID09IEwnWCc7Cit9CisKK2RvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6QUZfU2ltcGxlKEZYX0xQQ1dTVFIgc0Z1Y3Rpb24sIGRvdWJsZSBkVmFsdWUxLCBkb3VibGUgZFZhbHVlMikKK3sKKwlpZiAoRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwoRlhfTFBDV1NUUilMIkFWRyIpID09IDAgfHwgRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwoRlhfTFBDV1NUUilMIlNVTSIpID09IDApCisJeworCQlyZXR1cm4gZFZhbHVlMSArIGRWYWx1ZTI7CisJfQorCWVsc2UgaWYgKEZYU1lTX3djc2ljbXAoc0Z1Y3Rpb24sIChGWF9MUENXU1RSKUwiUFJEIikgPT0gMCkKKwl7CisJCXJldHVybiBkVmFsdWUxICogZFZhbHVlMjsKKwl9CisJZWxzZSBpZiAoRlhTWVNfd2NzaWNtcChzRnVjdGlvbiwoRlhfTFBDV1NUUilMIk1JTiIpID09IDApCisJeworCQlyZXR1cm4gRlhfTUlOKGRWYWx1ZTEsIGRWYWx1ZTIpOworCX0KKwllbHNlIGlmIChGWFNZU193Y3NpY21wKHNGdWN0aW9uLChGWF9MUENXU1RSKUwiTUFYIikgPT0gMCkKKwl7CisJCXJldHVybiBGWF9NQVgoZFZhbHVlMSwgZFZhbHVlMik7CisJfQorCisJcmV0dXJuIGRWYWx1ZTE7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJMVHJpbShGWF9MUENXU1RSIHBTdHIpCit7CisJd2hpbGUgKCpwU3RyICYmICpwU3RyID09IEwnICcpIHBTdHIrKzsKKworCXJldHVybiBwU3RyOworfQorCitDRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyUlRyaW0oRlhfTFBDV1NUUiBwU3RyKQoreworCUZYX0xQQ1dTVFIgcCA9IHBTdHI7CisKKwl3aGlsZSAoKnApIHArKzsKKwlwLS07CisJaWYgKHAgPj0gcFN0cikKKwl7CQkKKwkJd2hpbGUgKCpwICYmICpwID09IEwnICcpIHAtLTsKKwkJcCsrOworCQlyZXR1cm4gQ0ZYX1dpZGVTdHJpbmcocFN0cixwLXBTdHIpOworCX0KKwlyZXR1cm4gTCIiOworfQorCitDRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyVHJpbShGWF9MUENXU1RSIHBTdHIpCit7CisJcmV0dXJuIFN0clJUcmltKFN0ckxUcmltKHBTdHIpKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ0pTX1B1YmxpY01ldGhvZHM6OlN0ckxUcmltKEZYX0xQQ1NUUiBwU3RyKQoreworCXdoaWxlICgqcFN0ciAmJiAqcFN0ciA9PSAnICcpIHBTdHIrKzsKKworICAgIHJldHVybiBwU3RyOworfQorCitDRlhfQnl0ZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6U3RyUlRyaW0oRlhfTFBDU1RSIHBTdHIpCit7CisJRlhfTFBDU1RSIHAgPSBwU3RyOworCisJd2hpbGUgKCpwKSBwKys7CisJcC0tOworCWlmIChwID49IHBTdHIpCisJewkJCisJCXdoaWxlICgqcCAmJiAqcCA9PSAnICcpIHAtLTsKKwkJcCsrOworCQlyZXR1cm4gQ0ZYX0J5dGVTdHJpbmcocFN0cixwLXBTdHIpOworCX0KKwlyZXR1cm4gIiI7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpTdHJUcmltKEZYX0xQQ1NUUiBwU3RyKQoreworCXJldHVybiBTdHJSVHJpbShTdHJMVHJpbShwU3RyKSk7Cit9CisKK2RvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VOdW1iZXIoRlhfTFBDV1NUUiBzd1NvdXJjZSwgRlhfQk9PTCYgYkFsbERpZ2l0cywgRlhfQk9PTCYgYkRvdCwgRlhfQk9PTCYgYlNpZ24sIEZYX0JPT0wmIGJLWEpTKQoreworCWJEb3QgPSBGQUxTRTsKKwliU2lnbiA9IEZBTFNFOworCWJLWEpTID0gRkFMU0U7CisKKwlGWF9CT09MIGJEaWdpdEV4aXN0ID0gRkFMU0U7CisKKwlGWF9MUENXU1RSIHAgPSBzd1NvdXJjZTsKKwl3Y2hhcl90IGM7CisKKwlGWF9MUENXU1RSIHBTdGFydCA9IE5VTEw7CisJRlhfTFBDV1NUUiBwRW5kID0gTlVMTDsKKworCXdoaWxlICgoYyA9ICpwKSkKKwl7CisJCWlmICghcFN0YXJ0ICYmIGMgIT0gTCcgJykKKwkJeworCQkJcFN0YXJ0ID0gcDsKKwkJfQorCisJCXBFbmQgPSBwOworCQlwKys7CisJfQorCisJaWYgKCFwU3RhcnQpCisJeworCQliQWxsRGlnaXRzID0gRkFMU0U7CisJCXJldHVybiAwOworCX0KKworCXdoaWxlIChwRW5kICE9IHBTdGFydCkKKwl7CisJCWlmICgqcEVuZCA9PSBMJyAnKQorCQkJcEVuZCAtLTsKKwkJZWxzZQorCQkJYnJlYWs7CisJfQorCisJZG91YmxlIGRSZXQgPSAwOworCXAgPSBwU3RhcnQ7CisJYkFsbERpZ2l0cyA9IFRSVUU7CisJQ0ZYX1dpZGVTdHJpbmcgc3dEaWdpdHM7CisKKwl3aGlsZSAocCA8PSBwRW5kKQorCXsJCisJCWMgPSAqcDsKKworCQlpZiAoSXNEaWdpdChjKSkKKwkJeworCQkJc3dEaWdpdHMgKz0gYzsKKwkJCWJEaWdpdEV4aXN0ID0gVFJVRTsKKwkJfQorCQllbHNlIAorCQl7CisJCQlzd2l0Y2ggKGMpCisJCQl7CisJCQljYXNlIEwnICc6CisJCQkJYkFsbERpZ2l0cyA9IEZBTFNFOworCQkJCWJyZWFrOworCQkJY2FzZSBMJy4nOgorCQkJY2FzZSBMJywnOgorCQkJCWlmICghYkRvdCkKKwkJCQl7CisJCQkJCWlmIChiRGlnaXRFeGlzdCkKKwkJCQkJeworCQkJCQkJc3dEaWdpdHMgKz0gTCcuJzsKKwkJCQkJfQorCQkJCQllbHNlCisJCQkJCXsKKwkJCQkJCXN3RGlnaXRzICs9IEwnMCc7CisJCQkJCQlzd0RpZ2l0cyArPSBMJy4nOworCQkJCQkJYkRpZ2l0RXhpc3QgPSBUUlVFOworCQkJCQl9CisKKwkJCQkJYkRvdCA9IFRSVUU7CisJCQkJCWJyZWFrOworCQkJCX0KKwkJCWNhc2UgJ2UnOgorCQkJY2FzZSAnRSc6CisJCQkJaWYgKCFiS1hKUykKKwkJCQl7CisJCQkJCXArKzsKKwkJCQkJYyA9ICpwOworCQkJCQlpZiAoYyA9PSAnKycgfHwgYyA9PSAnLScpCisJCQkJCXsKKwkJCQkJCWJLWEpTID0gVFJVRTsKKwkJCQkJCXN3RGlnaXRzICs9ICdlJzsKKwkJCQkJCXN3RGlnaXRzICs9IGM7CisJCQkJCX0KKwkJCQkJYnJlYWs7CisJCQkJfQorCQkJY2FzZSBMJy0nOgorCQkJCWlmICghYkRpZ2l0RXhpc3QgJiYgIWJTaWduKQorCQkJCXsKKwkJCQkJc3dEaWdpdHMgKz0gYzsKKwkJCQkJYlNpZ24gPSBUUlVFOworCQkJCQlicmVhazsKKwkJCQl9CisJCQlkZWZhdWx0OgorCQkJCWJBbGxEaWdpdHMgPSBGQUxTRTsKKworCQkJCWlmIChwICE9IHBTdGFydCAmJiAhYkRvdCAmJiBiRGlnaXRFeGlzdCkKKwkJCQl7CisJCQkJCXN3RGlnaXRzICs9IEwnLic7CisJCQkJCWJEb3QgPSBUUlVFOworCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQliRG90ID0gRkFMU0U7CisJCQkJCWJEaWdpdEV4aXN0ID0gRkFMU0U7CisJCQkJCXN3RGlnaXRzID0gTCIiOworCQkJCX0KKwkJCQlicmVhazsKKwkJCX0KKwkJfQorCisJCXArKzsKKwl9CisKKwlpZiAoc3dEaWdpdHMuR2V0TGVuZ3RoKCkgPiAwICYmIHN3RGlnaXRzLkdldExlbmd0aCgpIDwgMTcpCisJeworCQlDRlhfQnl0ZVN0cmluZyBzRGlnaXRzID0gc3dEaWdpdHMuVVRGOEVuY29kZSgpOworCisJCWlmIChiS1hKUykKKwkJeworCQkJZFJldCA9IGF0b2Yoc0RpZ2l0cyk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlpZiAoYkRvdCkKKwkJCXsKKwkJCQljaGFyKiBwU3RvcFN0cmluZzsKKwkJCQlkUmV0ID0gOjpzdHJ0b2Qoc0RpZ2l0cywgJnBTdG9wU3RyaW5nKTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlkUmV0ID0gYXRvbChzRGlnaXRzKTsKKwkJCX0KKwkJfQorCisJfQorCisJcmV0dXJuIGRSZXQ7Cit9CisKK2RvdWJsZSBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VTdHJpbmdUb051bWJlcihGWF9MUENXU1RSIHN3U291cmNlKQoreworCUZYX0JPT0wgYkFsbERpZ2l0cyA9IEZBTFNFOworCUZYX0JPT0wgYkRvdCA9IEZBTFNFOworCUZYX0JPT0wgYlNpZ24gPSBGQUxTRTsKKwlGWF9CT09MIGJLWEpTID0gRkFMU0U7CisKKwlyZXR1cm4gUGFyc2VOdW1iZXIoc3dTb3VyY2UsIGJBbGxEaWdpdHMsIGJEb3QsIGJTaWduLCBiS1hKUyk7Cit9CisKK0ZYX0JPT0wJQ0pTX1B1YmxpY01ldGhvZHM6OkNvbnZlcnRTdHJpbmdUb051bWJlcihGWF9MUENXU1RSIHN3U291cmNlLCBkb3VibGUgJiBkUmV0LCBGWF9CT09MICYgYkRvdCkKK3sKKwlGWF9CT09MIGJBbGxEaWdpdHMgPSBGQUxTRTsKKwlGWF9CT09MIGJTaWduID0gRkFMU0U7CisJRlhfQk9PTCBiS1hKUyA9IEZBTFNFOworCisJZFJldCA9IFBhcnNlTnVtYmVyKHN3U291cmNlLCBiQWxsRGlnaXRzLCBiRG90LCBiU2lnbiwgYktYSlMpOworCisJcmV0dXJuIGJBbGxEaWdpdHM7Cit9CisKK0NKU19BcnJheSBDSlNfUHVibGljTWV0aG9kczo6QUZfTWFrZUFycmF5RnJvbUxpc3Qodjg6Oklzb2xhdGUqIGlzb2xhdGUsIENKU19WYWx1ZSB2YWwpCit7CisJQ0pTX0FycmF5IFN0ckFycmF5KGlzb2xhdGUpOworCWlmKHZhbC5Jc0FycmF5T2JqZWN0KCkpCisJeworCQl2YWwuQ29udmVydFRvQXJyYXkoU3RyQXJyYXkpOworCQlyZXR1cm4gU3RyQXJyYXk7CisJfQorCUNGWF9XaWRlU3RyaW5nIHdzU3RyID0gdmFsLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJQ0ZYX0J5dGVTdHJpbmcgdCA9IENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZSh3c1N0cik7CisJY29uc3QgY2hhciAqIHAgPSAoY29uc3QgY2hhciAqKXQ7CisKKworCWludCBjaCA9ICcsJyA7CisJaW50IG5JbmRleCA9IDA7CisKKwl3aGlsZSAoKnApCisJeworCQljb25zdCBjaGFyICogcFRlbXAgPSBzdHJjaHIocCwgY2gpOworCQlpZiAocFRlbXAgPT0gTlVMTCkKKwkJeworCQkJU3RyQXJyYXkuU2V0RWxlbWVudChuSW5kZXgsIENKU19WYWx1ZShpc29sYXRlLChGWF9MUENTVFIpU3RyVHJpbShwKSkpOworCQkJYnJlYWs7CisJCX0KKwkJZWxzZQorCQl7CisJCQljaGFyICogcFN1YiA9IG5ldyBjaGFyW3BUZW1wIC0gcCArIDFdOworCQkJc3RybmNweShwU3ViLCBwLCBwVGVtcCAtIHApOworCQkJKihwU3ViICsgKHBUZW1wIC0gcCkpID0gJ1wwJzsKKworCQkJU3RyQXJyYXkuU2V0RWxlbWVudChuSW5kZXgsIENKU19WYWx1ZShpc29sYXRlLChGWF9MUENTVFIpU3RyVHJpbShwU3ViKSkpOworCQkJZGVsZXRlIFtdcFN1YjsKKwkJCQorCQkJbkluZGV4ICsrOworCQkJcCA9ICsrcFRlbXA7CisJCX0KKwkJCisJfQorCXJldHVybiBTdHJBcnJheTsKK30KKworaW50IENKU19QdWJsaWNNZXRob2RzOjpQYXJzZVN0cmluZ0ludGVnZXIoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZyxpbnQgblN0YXJ0LGludCYgblNraXAsIGludCBuTWF4U3RlcCkKK3sKKwlpbnQgblJldCA9IDA7CisJblNraXAgPSAwOworCWZvciAoaW50IGk9blN0YXJ0LCBzej1zdHJpbmcuR2V0TGVuZ3RoKCk7IGkgPCBzejsgaSsrKQorCXsKKwkJaWYgKGktblN0YXJ0ID4gMTApCisJCQlicmVhazsKKworCQlGWF9XQ0hBUiBjID0gc3RyaW5nLkdldEF0KGkpOworCQlpZiAoSXNEaWdpdCgod2NoYXJfdCljKSkKKwkJeworCQkJblJldCA9IG5SZXQgKiAxMCArIChjIC0gJzAnKTsKKwkJCW5Ta2lwID0gaSAtIG5TdGFydCArIDE7CisJCQlpZiAoblNraXAgPj0gbk1heFN0ZXApIAorCQkJCWJyZWFrOworCQl9CisJCWVsc2UKKwkJCWJyZWFrOworCX0KKworCXJldHVybiBuUmV0OworfQorCitDRlhfV2lkZVN0cmluZyBDSlNfUHVibGljTWV0aG9kczo6UGFyc2VTdHJpbmdTdHJpbmcoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZywgaW50IG5TdGFydCwgaW50JiBuU2tpcCkKK3sKKwlDRlhfV2lkZVN0cmluZyBzd1JldDsKKwluU2tpcCA9IDA7CisJZm9yIChpbnQgaT1uU3RhcnQsIHN6PXN0cmluZy5HZXRMZW5ndGgoKTsgaSA8IHN6OyBpKyspCisJeworCQlGWF9XQ0hBUiBjID0gc3RyaW5nLkdldEF0KGkpOworCQlpZiAoKGMgPj0gTCdhJyAmJiBjIDw9IEwneicpIHx8IChjID49IEwnQScgJiYgYyA8PSBMJ1onKSkKKwkJeworCQkJc3dSZXQgKz0gYzsKKwkJCW5Ta2lwID0gaSAtIG5TdGFydCArIDE7CisJCX0KKwkJZWxzZQorCQkJYnJlYWs7CisJfQorCisJcmV0dXJuIHN3UmV0OworfQorCitkb3VibGUgQ0pTX1B1YmxpY01ldGhvZHM6OlBhcnNlTm9ybWFsRGF0ZShjb25zdCBDRlhfV2lkZVN0cmluZyAmIHZhbHVlLCBGWF9CT09MJiBiV3JvbmdGb3JtYXQpCit7CisJZG91YmxlIGR0ID0gSlNfR2V0RGF0ZVRpbWUoKTsKKworCWludCBuWWVhciA9IEpTX0dldFllYXJGcm9tVGltZShkdCk7CisJaW50IG5Nb250aCA9IEpTX0dldE1vbnRoRnJvbVRpbWUoZHQpICsgMTsKKwlpbnQgbkRheSA9IEpTX0dldERheUZyb21UaW1lKGR0KTsKKwlpbnQgbkhvdXIgPSBKU19HZXRIb3VyRnJvbVRpbWUoZHQpOworCWludCBuTWluID0gSlNfR2V0TWluRnJvbVRpbWUoZHQpOworCWludCBuU2VjID0gSlNfR2V0U2VjRnJvbVRpbWUoZHQpOworCisJaW50IG51bWJlclszXTsKKworCWludCBuU2tpcCA9IDA7CisJaW50IG5MZW4gPSB2YWx1ZS5HZXRMZW5ndGgoKTsKKwlpbnQgbkluZGV4ID0gMDsKKwlpbnQgaSA9IDA7CisJd2hpbGUgKGkgPCBuTGVuKQorCXsKKwkJaWYgKG5JbmRleCA+IDIpIGJyZWFrOworCisJCUZYX1dDSEFSIGMgPSB2YWx1ZS5HZXRBdChpKTsKKwkJaWYgKElzRGlnaXQoKHdjaGFyX3QpYykpCisJCXsKKwkJCW51bWJlcltuSW5kZXgrK10gPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGksIG5Ta2lwLCA0KTsKKwkJCWkgKz0gblNraXA7CQkJCisJCX0KKwkJZWxzZQorCQl7CisJCQlpICsrOworCQl9CisJfQorCisJaWYgKG5JbmRleCA9PSAyKQorCXsKKwkJLy8gY2FzZTI6IG1vbnRoL2RheQorCQkvLyBjYXNlMzogZGF5L21vbnRoCisJCWlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDEyKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDMxKSkKKwkJeworCQkJbk1vbnRoID0gbnVtYmVyWzBdOworCQkJbkRheSA9IG51bWJlclsxXTsKKwkJfQorCQllbHNlIGlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDMxKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDEyKSkKKwkJeworCQkJbkRheSA9IG51bWJlclswXTsKKwkJCW5Nb250aCA9IG51bWJlclsxXTsKKwkJfQorCisJCWJXcm9uZ0Zvcm1hdCA9IEZBTFNFOworCX0KKwllbHNlIGlmIChuSW5kZXggPT0gMykKKwl7CisJCS8vIGNhc2UxOiB5ZWFyL21vbnRoL2RheQorCQkvLyBjYXNlMjogbW9udGgvZGF5L3llYXIKKwkJLy8gY2FzZTM6IGRheS9tb250aC95ZWFyCisKKwkJaWYgKG51bWJlclswXSA+IDEyICYmIChudW1iZXJbMV0gPj0gMSAmJiBudW1iZXJbMV0gPD0gMTIpICYmIChudW1iZXJbMl0gPj0gMSAmJiBudW1iZXJbMl0gPD0gMzEpKQorCQl7CisJCQluWWVhciA9IG51bWJlclswXTsKKwkJCW5Nb250aCA9IG51bWJlclsxXTsKKwkJCW5EYXkgPSBudW1iZXJbMl07CisJCX0KKwkJZWxzZSBpZiAoKG51bWJlclswXSA+PSAxICYmIG51bWJlclswXSA8PSAxMikgJiYgKG51bWJlclsxXSA+PSAxICYmIG51bWJlclsxXSA8PSAzMSkgJiYgbnVtYmVyWzJdID4gMzEpCisJCXsKKwkJCW5Nb250aCA9IG51bWJlclswXTsKKwkJCW5EYXkgPSBudW1iZXJbMV07CisJCQluWWVhciA9IG51bWJlclsyXTsKKwkJfQorCQllbHNlIGlmICgobnVtYmVyWzBdID49IDEgJiYgbnVtYmVyWzBdIDw9IDMxKSAmJiAobnVtYmVyWzFdID49IDEgJiYgbnVtYmVyWzFdIDw9IDEyKSAmJiBudW1iZXJbMl0gPiAzMSkKKwkJeworCQkJbkRheSA9IG51bWJlclswXTsKKwkJCW5Nb250aCA9IG51bWJlclsxXTsKKwkJCW5ZZWFyID0gbnVtYmVyWzJdOworCQl9CisKKwkJYldyb25nRm9ybWF0ID0gRkFMU0U7CisJfQorCWVsc2UKKwl7CisJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CisJCXJldHVybiBkdDsKKwl9CisKKwlDRlhfV2lkZVN0cmluZyBzd1RlbXA7CisJc3dUZW1wLkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkLyVkLyVkICVkOiVkOiVkIixuTW9udGgsbkRheSxuWWVhcixuSG91cixuTWluLG5TZWMpOworCXJldHVybiBKU19EYXRlUGFyc2Uoc3dUZW1wKTsKK30KKworZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpNYWtlUmVndWxhckRhdGUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiB2YWx1ZSwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBmb3JtYXQsIEZYX0JPT0wmIGJXcm9uZ0Zvcm1hdCkKK3sKKwlkb3VibGUgZHQgPSBKU19HZXREYXRlVGltZSgpOworCisJaWYgKGZvcm1hdC5Jc0VtcHR5KCkgfHwgdmFsdWUuSXNFbXB0eSgpKQorCQlyZXR1cm4gZHQ7CisKKwlpbnQgblllYXIgPSBKU19HZXRZZWFyRnJvbVRpbWUoZHQpOworCWludCBuTW9udGggPSBKU19HZXRNb250aEZyb21UaW1lKGR0KSArIDE7CisJaW50IG5EYXkgPSBKU19HZXREYXlGcm9tVGltZShkdCk7CisJaW50IG5Ib3VyID0gSlNfR2V0SG91ckZyb21UaW1lKGR0KTsKKwlpbnQgbk1pbiA9IEpTX0dldE1pbkZyb21UaW1lKGR0KTsKKwlpbnQgblNlYyA9IEpTX0dldFNlY0Zyb21UaW1lKGR0KTsKKworCWludCBuWWVhclN1YiA9IDk5OyAvL25ZZWFyIC0gMjAwMDsKKworCUZYX0JPT0wgYlBtID0gRkFMU0U7CisJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOworCWJXcm9uZ0Zvcm1hdCA9IEZBTFNFOworCQorCWludCBpPTA7CisJaW50IGo9MDsKKworCXdoaWxlIChpIDwgZm9ybWF0LkdldExlbmd0aCgpKQorCXsKKwkJaWYgKGJFeGl0KSBicmVhazsKKworCQlGWF9XQ0hBUiBjID0gZm9ybWF0LkdldEF0KGkpOwkJCisJCXN3aXRjaCAoYykKKwkJeworCQkJY2FzZSAnOic6CisJCQljYXNlICcuJzoKKwkJCWNhc2UgJy0nOgorCQkJY2FzZSAnXFwnOgorCQkJY2FzZSAnLyc6CisJCQkJaSsrOworCQkJCWorKzsKKwkJCQlicmVhazsKKwkJCQkKKwkJCWNhc2UgJ3knOgorCQkJY2FzZSAnbSc6CisJCQljYXNlICdkJzoKKwkJCWNhc2UgJ0gnOgorCQkJY2FzZSAnaCc6CisJCQljYXNlICdNJzoKKwkJCWNhc2UgJ3MnOgorCQkJY2FzZSAndCc6CisJCQkJeworCQkJCQlpbnQgb2xkaiA9IGo7CisJCQkJCWludCBuU2tpcCA9IDA7CisKKwkJCQkJaWYgKGZvcm1hdC5HZXRBdChpKzEpICE9IGMpCisJCQkJCXsKKwkJCQkJCXN3aXRjaCAoYykKKwkJCQkJCXsKKwkJCQkJCQljYXNlICd5JzoKKwkJCQkJCQkJaSsrOworCQkJCQkJCQlqKys7CisJCQkJCQkJCWJyZWFrOworCQkJCQkJCWNhc2UgJ20nOgorCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKKwkJCQkJCQkJaSsrOworCQkJCQkJCQlqICs9IG5Ta2lwOworCQkJCQkJCQlicmVhazsKKwkJCQkJCQljYXNlICdkJzoKKwkJCQkJCQkJbkRheSA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOworCQkJCQkJCQlpKys7CisJCQkJCQkJCWogKz0gblNraXA7CisJCQkJCQkJCWJyZWFrOworCQkJCQkJCWNhc2UgJ0gnOgorCQkJCQkJCQluSG91ciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOworCQkJCQkJCQlpKys7CisJCQkJCQkJCWogKz0gblNraXA7CisJCQkJCQkJCWJyZWFrOworCQkJCQkJCWNhc2UgJ2gnOgorCQkJCQkJCQluSG91ciA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOworCQkJCQkJCQlpKys7CisJCQkJCQkJCWogKz0gblNraXA7CisJCQkJCQkJCWJyZWFrOworCQkJCQkJCWNhc2UgJ00nOgorCQkJCQkJCQluTWluID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CisJCQkJCQkJCWkrKzsKKwkJCQkJCQkJaiArPSBuU2tpcDsKKwkJCQkJCQkJYnJlYWs7CisJCQkJCQkJY2FzZSAncyc6CisJCQkJCQkJCW5TZWMgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKKwkJCQkJCQkJaSsrOworCQkJCQkJCQlqICs9IG5Ta2lwOworCQkJCQkJCQlicmVhazsKKwkJCQkJCQljYXNlICd0JzoKKwkJCQkJCQkJYlBtID0gdmFsdWUuR2V0QXQoaSkgPT0gJ3AnOworCQkJCQkJCQlpKys7CisJCQkJCQkJCWorKzsKKwkJCQkJCQkJYnJlYWs7CisJCQkJCQl9CQkJCQkKKwkJCQkJfQorCQkJCQllbHNlIGlmIChmb3JtYXQuR2V0QXQoaSsxKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzIpICE9IGMpCisJCQkJCXsKKwkJCQkJCXN3aXRjaCAoYykKKwkJCQkJCXsKKwkJCQkJCQljYXNlICd5JzoKKwkJCQkJCQkJblllYXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCA0KTsKKwkJCQkJCQkJaSArPSAyOworCQkJCQkJCQlqICs9IG5Ta2lwOworCQkJCQkJCQlicmVhazsKKwkJCQkJCQljYXNlICdtJzoKKwkJCQkJCQkJbk1vbnRoID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CisJCQkJCQkJCWkgKz0gMjsKKwkJCQkJCQkJaiArPSBuU2tpcDsKKwkJCQkJCQkJYnJlYWs7CisJCQkJCQkJY2FzZSAnZCc6CisJCQkJCQkJCW5EYXkgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKKwkJCQkJCQkJaSArPSAyOworCQkJCQkJCQlqICs9IG5Ta2lwOworCQkJCQkJCQlicmVhazsKKwkJCQkJCQljYXNlICdIJzoKKwkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKKwkJCQkJCQkJaSArPSAyOworCQkJCQkJCQlqICs9IG5Ta2lwOworCQkJCQkJCQlicmVhazsKKwkJCQkJCQljYXNlICdoJzoKKwkJCQkJCQkJbkhvdXIgPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAyKTsKKwkJCQkJCQkJaSArPSAyOworCQkJCQkJCQlqICs9IG5Ta2lwOworCQkJCQkJCQlicmVhazsKKwkJCQkJCQljYXNlICdNJzoKKwkJCQkJCQkJbk1pbiA9IFBhcnNlU3RyaW5nSW50ZWdlcih2YWx1ZSwgaiwgblNraXAsIDIpOworCQkJCQkJCQlpICs9IDI7CisJCQkJCQkJCWogKz0gblNraXA7CisJCQkJCQkJCWJyZWFrOworCQkJCQkJCWNhc2UgJ3MnOgorCQkJCQkJCQluU2VjID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgMik7CisJCQkJCQkJCWkgKz0gMjsKKwkJCQkJCQkJaiArPSBuU2tpcDsKKwkJCQkJCQkJYnJlYWs7CisJCQkJCQkJY2FzZSAndCc6CisJCQkJCQkJCWJQbSA9ICh2YWx1ZS5HZXRBdChqKSA9PSAncCcgJiYgdmFsdWUuR2V0QXQoaisxKSA9PSAnbScpOworCQkJCQkJCQlpICs9IDI7CisJCQkJCQkJCWogKz0gMjsKKwkJCQkJCQkJYnJlYWs7CisJCQkJCQl9CisJCQkJCX0KKwkJCQkJZWxzZSBpZiAoZm9ybWF0LkdldEF0KGkrMSkgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSsyKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzMpICE9IGMpCisJCQkJCXsKKwkJCQkJCXN3aXRjaCAoYykKKwkJCQkJCXsKKwkJCQkJCQljYXNlICdtJzoKKwkJCQkJCQkJeworCQkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc01vbnRoID0gUGFyc2VTdHJpbmdTdHJpbmcodmFsdWUsIGosIG5Ta2lwKTsKKwkJCQkJCQkJCUZYX0JPT0wgYkZpbmQgPSBGQUxTRTsKKwkJCQkJCQkJCWZvciAoaW50IG0gPSAwOyBtIDwgMTI7IG0rKykKKwkJCQkJCQkJCXsKKwkJCQkJCQkJCQlpZiAoc01vbnRoLkNvbXBhcmVOb0Nhc2UobW9udGhzW21dKSA9PSAwKQorCQkJCQkJCQkJCXsKKwkJCQkJCQkJCQkJbk1vbnRoID0gbSArIDE7CisJCQkJCQkJCQkJCWkrPTM7CisJCQkJCQkJCQkJCWorPW5Ta2lwOworCQkJCQkJCQkJCQliRmluZCA9IFRSVUU7CisJCQkJCQkJCQkJCWJyZWFrOworCQkJCQkJCQkJCX0KKwkJCQkJCQkJCX0KKwkJCQkJCQkJCQorCQkJCQkJCQkJaWYgKCFiRmluZCkKKwkJCQkJCQkJCXsKKwkJCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCAzKTsKKwkJCQkJCQkJCQlpKz0zOworCQkJCQkJCQkJCWogKz0gblNraXA7CisJCQkJCQkJCQl9CisJCQkJCQkJCX0KKwkJCQkJCQkJYnJlYWs7CisJCQkJCQkJY2FzZSAneSc6CisJCQkJCQkJCWJyZWFrOworCQkJCQkJCWRlZmF1bHQ6CisJCQkJCQkJCWkrPTM7CisJCQkJCQkJCWorPTM7CisJCQkJCQkJCWJyZWFrOworCQkJCQkJfQorCQkJCQl9CisJCQkJCWVsc2UgaWYgKGZvcm1hdC5HZXRBdChpKzEpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrMikgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSszKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzQpICE9IGMpCisJCQkJCXsKKwkJCQkJCXN3aXRjaCAoYykKKwkJCQkJCXsKKworCisJCQkJCQkJY2FzZSAneSc6CisJCQkJCQkJCW5ZZWFyID0gUGFyc2VTdHJpbmdJbnRlZ2VyKHZhbHVlLCBqLCBuU2tpcCwgNCk7CisJCQkJCQkJCWogKz0gblNraXA7CisJCQkJCQkJCWkgKz0gNDsKKwkJCQkJCQkJYnJlYWs7CisJCQkJCQkJY2FzZSAnbSc6CisJCQkJCQkJCXsKKwkJCQkJCQkJCUZYX0JPT0wgYkZpbmQgPSBGQUxTRTsKKworCQkJCQkJCQkJQ0ZYX1dpZGVTdHJpbmcgc01vbnRoID0gUGFyc2VTdHJpbmdTdHJpbmcodmFsdWUsIGosIG5Ta2lwKTsKKwkJCQkJCQkJCXNNb250aC5NYWtlTG93ZXIoKTsKKworCQkJCQkJCQkJZm9yIChpbnQgbSA9IDA7IG0gPCAxMjsgbSsrKQorCQkJCQkJCQkJeworCQkJCQkJCQkJCUNGWF9XaWRlU3RyaW5nIHNGdWxsTW9udGhzID0gZnVsbG1vbnRoc1ttXTsKKwkJCQkJCQkJCQlzRnVsbE1vbnRocy5NYWtlTG93ZXIoKTsKKworCQkJCQkJCQkJCWlmIChzRnVsbE1vbnRocy5GaW5kKHNNb250aCwgMCkgIT0gLTEpCisJCQkJCQkJCQkJeworCQkJCQkJCQkJCQluTW9udGggPSBtICsgMTsKKwkJCQkJCQkJCQkJaSArPSA0OworCQkJCQkJCQkJCQlqICs9IG5Ta2lwOworCQkJCQkJCQkJCQliRmluZCA9IFRSVUU7CisJCQkJCQkJCQkJCWJyZWFrOworCQkJCQkJCQkJCX0KKwkJCQkJCQkJCX0KKwkJCQkJCQkJCQorCQkJCQkJCQkJaWYgKCFiRmluZCkKKwkJCQkJCQkJCXsKKwkJCQkJCQkJCQluTW9udGggPSBQYXJzZVN0cmluZ0ludGVnZXIodmFsdWUsIGosIG5Ta2lwLCA0KTsKKwkJCQkJCQkJCQlpKz00OworCQkJCQkJCQkJCWogKz0gblNraXA7CisJCQkJCQkJCQl9CisJCQkJCQkJCX0KKwkJCQkJCQkJYnJlYWs7CisJCQkJCQkJZGVmYXVsdDoKKwkJCQkJCQkJaSArPSA0OworCQkJCQkJCQlqICs9IDQ7CisJCQkJCQkJCWJyZWFrOworCQkJCQkJfQkJCQkJCisJCQkJCX0KKwkJCQkJZWxzZQorCQkJCQl7CisJCQkJCQlpZiAoZm9ybWF0LkdldEF0KGkpICE9IHZhbHVlLkdldEF0KGopKQorCQkJCQkJeworCQkJCQkJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CisJCQkJCQkJYkV4aXQgPSBUUlVFOworCQkJCQkJfQorCQkJCQkJaSsrOworCQkJCQkJaisrOworCQkJCQl9CisJCQkJCQorCQkJCQlpZiAob2xkaiA9PSBqKQorCQkJCQl7CisJCQkJCQliV3JvbmdGb3JtYXQgPSBUUlVFOworCQkJCQkJYkV4aXQgPSBUUlVFOworCQkJCQl9CisJCQkJfQorCisJCQkJYnJlYWs7CQkJCisJCQlkZWZhdWx0OgorCQkJCWlmICh2YWx1ZS5HZXRMZW5ndGgoKSA8PSBqKQorCQkJCXsKKwkJCQkJYkV4aXQgPSBUUlVFOworCQkJCX0KKwkJCQllbHNlIGlmIChmb3JtYXQuR2V0QXQoaSkgIT0gdmFsdWUuR2V0QXQoaikpCisJCQkJeworCQkJCQliV3JvbmdGb3JtYXQgPSBUUlVFOworCQkJCQliRXhpdCA9IFRSVUU7CisJCQkJfQorCisJCQkJaSsrOworCQkJCWorKzsKKwkJCQlicmVhazsKKwkJfQkJCisJfQorCisJaWYgKGJQbSkgbkhvdXIgKz0gMTI7CisKKwlpZiAoblllYXIgPj0gMCAmJiBuWWVhciA8PSBuWWVhclN1YikKKwkJblllYXIgKz0gMjAwMDsKKworCWlmIChuTW9udGggPCAxIHx8IG5Nb250aCA+IDEyKQorCQliV3JvbmdGb3JtYXQgPSBUUlVFOworCisJaWYgKG5EYXkgPCAxIHx8IG5EYXkgPiAzMSkKKwkJYldyb25nRm9ybWF0ID0gVFJVRTsKKworCWlmIChuSG91ciA8IDAgfHwgbkhvdXIgPiAyNCkKKwkJYldyb25nRm9ybWF0ID0gVFJVRTsKKworCWlmIChuTWluIDwgMCB8fCBuTWluID4gNjApCisJCWJXcm9uZ0Zvcm1hdCA9IFRSVUU7CisKKwlpZiAoblNlYyA8IDAgfHwgblNlYyA+IDYwKQorCQliV3JvbmdGb3JtYXQgPSBUUlVFOworCisJZG91YmxlIGRSZXQgPSAwOworCisJaWYgKGJXcm9uZ0Zvcm1hdCkKKwl7CisJCWRSZXQgPSBQYXJzZU5vcm1hbERhdGUodmFsdWUsIGJXcm9uZ0Zvcm1hdCk7CisJfQorCWVsc2UKKwl7CisJCWRSZXQgPSBKU19NYWtlRGF0ZShKU19NYWtlRGF5KG5ZZWFyLG5Nb250aCAtIDEsbkRheSksSlNfTWFrZVRpbWUobkhvdXIsIG5NaW4sIG5TZWMsIDApKTsKKworCQlpZiAoSlNfUG9ydElzTmFuKGRSZXQpKQorCQl7CisJCQlkUmV0ID0gSlNfRGF0ZVBhcnNlKHZhbHVlKTsKKwkJfQorCX0KKworCWlmIChKU19Qb3J0SXNOYW4oZFJldCkpCisJeworCQlkUmV0ID0gUGFyc2VOb3JtYWxEYXRlKHZhbHVlLCBiV3JvbmdGb3JtYXQpOworCX0KKworCXJldHVybiBkUmV0OworCit9CisKK0NGWF9XaWRlU3RyaW5nIENKU19QdWJsaWNNZXRob2RzOjpNYWtlRm9ybWF0RGF0ZShkb3VibGUgZERhdGUsIGNvbnN0IENGWF9XaWRlU3RyaW5nICYgZm9ybWF0KQoreworCUNGWF9XaWRlU3RyaW5nIHNSZXQgPSBMIiIsc1BhcnQgPSBMIiI7CisKKwlpbnQgblllYXIgPSBKU19HZXRZZWFyRnJvbVRpbWUoZERhdGUpOworCWludCBuTW9udGggPSBKU19HZXRNb250aEZyb21UaW1lKGREYXRlKSArIDE7CisJaW50IG5EYXkgPSBKU19HZXREYXlGcm9tVGltZShkRGF0ZSk7CisJaW50IG5Ib3VyID0gSlNfR2V0SG91ckZyb21UaW1lKGREYXRlKTsKKwlpbnQgbk1pbiA9IEpTX0dldE1pbkZyb21UaW1lKGREYXRlKTsKKwlpbnQgblNlYyA9IEpTX0dldFNlY0Zyb21UaW1lKGREYXRlKTsKKworCWludCBpID0gMDsKKwlGWF9XQ0hBUiBjOworCXdoaWxlIChpIDwgZm9ybWF0LkdldExlbmd0aCgpKQorCXsKKwkJYyA9IGZvcm1hdC5HZXRBdChpKTsKKwkJc1BhcnQgPSBMIiI7CisJCXN3aXRjaCAoYykKKwkJeworCQkJY2FzZSAneSc6CisJCQljYXNlICdtJzoKKwkJCWNhc2UgJ2QnOgorCQkJY2FzZSAnSCc6CisJCQljYXNlICdoJzoKKwkJCWNhc2UgJ00nOgorCQkJY2FzZSAncyc6CisJCQljYXNlICd0JzoKKwkJCQlpZiAoZm9ybWF0LkdldEF0KGkrMSkgIT0gYykKKwkJCQl7CisJCQkJCXN3aXRjaCAoYykKKwkJCQkJeworCQkJCQkJY2FzZSAneSc6CisJCQkJCQkJc1BhcnQgKz0gYzsKKwkJCQkJCQlicmVhazsKKwkJCQkJCWNhc2UgJ20nOgorCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuTW9udGgpOworCQkJCQkJCWJyZWFrOworCQkJCQkJY2FzZSAnZCc6CisJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5EYXkpOworCQkJCQkJCWJyZWFrOworCQkJCQkJY2FzZSAnSCc6CisJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLG5Ib3VyKTsKKwkJCQkJCQlicmVhazsKKwkJCQkJCWNhc2UgJ2gnOgorCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuSG91cj4xMj9uSG91ciAtIDEyOm5Ib3VyKTsKKwkJCQkJCQlicmVhazsKKwkJCQkJCWNhc2UgJ00nOgorCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuTWluKTsKKwkJCQkJCQlicmVhazsKKwkJCQkJCWNhc2UgJ3MnOgorCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixuU2VjKTsKKwkJCQkJCQlicmVhazsKKwkJCQkJCWNhc2UgJ3QnOgkJCQkKKwkJCQkJCQlzUGFydCArPSBuSG91cj4xMj8ncCc6J2EnOworCQkJCQkJCWJyZWFrOworCQkJCQl9CQkJCQkKKwkJCQkJaSsrOworCQkJCX0KKwkJCQllbHNlIGlmIChmb3JtYXQuR2V0QXQoaSsxKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzIpICE9IGMpCisJCQkJeworCQkJCQlzd2l0Y2ggKGMpCisJCQkJCXsKKwkJCQkJCWNhc2UgJ3knOgorCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5ZZWFyIC0gKG5ZZWFyIC8gMTAwKSAqIDEwMCk7CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlICdtJzoKKwkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuTW9udGgpOworCQkJCQkJCWJyZWFrOworCQkJCQkJY2FzZSAnZCc6CisJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsbkRheSk7CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlICdIJzoKKwkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuSG91cik7CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlICdoJzoKKwkJCQkJCQlzUGFydC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDJkIixuSG91cj4xMj9uSG91ciAtIDEyOm5Ib3VyKTsKKwkJCQkJCQlicmVhazsKKwkJCQkJCWNhc2UgJ00nOgorCQkJCQkJCXNQYXJ0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwMmQiLG5NaW4pOworCQkJCQkJCWJyZWFrOworCQkJCQkJY2FzZSAncyc6CisJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTAyZCIsblNlYyk7CisJCQkJCQkJYnJlYWs7CisJCQkJCQljYXNlICd0JzoJCQkJCQkJCisJCQkJCQkJc1BhcnQgPSBuSG91cj4xMj8gKEZYX0xQQ1dTVFIpTCJwbSI6IChGWF9MUENXU1RSKUwiYW0iOworCQkJCQkJCWJyZWFrOworCQkJCQl9CQkJCisJCQkJCWkrPTI7CisJCQkJfQorCQkJCWVsc2UgaWYgKGZvcm1hdC5HZXRBdChpKzEpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrMikgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSszKSAhPSBjKQorCQkJCXsJCQorCQkJCQlzd2l0Y2ggKGMpCisJCQkJCXsKKwkJCQkJCWNhc2UgJ20nOgorCQkJCQkJCWkrPTM7CisJCQkJCQkJaWYgKG5Nb250aCA+IDAmJm5Nb250aCA8PSAxMikKKwkJCQkJCQkJc1BhcnQgKz0gbW9udGhzW25Nb250aCAtIDFdOworCQkJCQkJCWJyZWFrOworCQkJCQkJZGVmYXVsdDoKKwkJCQkJCQlpKz0zOworCQkJCQkJCXNQYXJ0ICs9IGM7CisJCQkJCQkJc1BhcnQgKz0gYzsKKwkJCQkJCQlzUGFydCArPSBjOworCQkJCQkJCWJyZWFrOworCQkJCQl9CQkJCQkKKwkJCQl9CisJCQkJZWxzZSBpZiAoZm9ybWF0LkdldEF0KGkrMSkgPT0gYyAmJiBmb3JtYXQuR2V0QXQoaSsyKSA9PSBjICYmIGZvcm1hdC5HZXRBdChpKzMpID09IGMgJiYgZm9ybWF0LkdldEF0KGkrNCkgIT0gYykKKwkJCQl7CisJCQkJCXN3aXRjaCAoYykKKwkJCQkJeworCQkJCQkJY2FzZSAneSc6CisJCQkJCQkJc1BhcnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTA0ZCIsblllYXIpOworCQkJCQkJCWkgKz0gNDsKKwkJCQkJCQlicmVhazsJCisJCQkJCQljYXNlICdtJzoKKwkJCQkJCQlpKz00OworCQkJCQkJCWlmIChuTW9udGggPiAwJiZuTW9udGggPD0gMTIpCisJCQkJCQkJCXNQYXJ0ICs9IGZ1bGxtb250aHNbbk1vbnRoIC0gMV07CisJCQkJCQkJYnJlYWs7CisJCQkJCQlkZWZhdWx0OgorCQkJCQkJCWkgKz0gNDsKKwkJCQkJCQlzUGFydCArPSBjOworCQkJCQkJCXNQYXJ0ICs9IGM7CisJCQkJCQkJc1BhcnQgKz0gYzsKKwkJCQkJCQlzUGFydCArPSBjOworCQkJCQkJCWJyZWFrOworCQkJCQl9CQkJCQkKKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJaSsrOworCQkJCQlzUGFydCArPSBjOworCQkJCX0KKwkJCQlicmVhazsJCQkKKwkJCWRlZmF1bHQ6CisJCQkJaSsrOworCQkJCXNQYXJ0ICs9IGM7CisJCQkJYnJlYWs7CisJCX0KKwkJCisJCXNSZXQgKz0gc1BhcnQ7CisJfQorCisJcmV0dXJuIHNSZXQ7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKKy8vZnVuY3Rpb24gQUZOdW1iZXJfRm9ybWF0KG5EZWMsIHNlcFN0eWxlLCBuZWdTdHlsZSwgY3VyclN0eWxlLCBzdHJDdXJyZW5jeSwgYkN1cnJlbmN5UHJlcGVuZCkKK0ZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGTnVtYmVyX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKyNpZiBfRlhfT1NfICE9IF9GWF9BTkRST0lEXworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOworCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CisKKwlpZiAocGFyYW1zLnNpemUoKSAhPSA2KQorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKwlpZighcEV2ZW50LT5tX3BWYWx1ZSkKKwkJcmV0dXJuIEZBTFNFOworCUNGWF9XaWRlU3RyaW5nJiBWYWx1ZSA9IHBFdmVudC0+VmFsdWUoKTsJCisJQ0ZYX0J5dGVTdHJpbmcgc3RyVmFsdWUgPSBTdHJUcmltKENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShWYWx1ZSkpOworCQorCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpIHJldHVybiBUUlVFOworCQorCWludCBpRGVjID0gcGFyYW1zWzBdOworCWludCBpU2VwU3R5bGUgPSBwYXJhbXNbMV07CisJaW50IGlOZWdTdHlsZSA9IHBhcmFtc1syXTsKKwlpbnQgaWN1cnJTdHlsZSA9IHBhcmFtc1szXTsgLy9pdCdzIG5vIHVzZSEKKwlzdGQ6OndzdHJpbmcgd3N0ckN1cnJlbmN5KHBhcmFtc1s0XS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKKwlGWF9CT09MIGJDdXJyZW5jeVByZXBlbmQgPSBwYXJhbXNbNV07CisJCisJaWYgKGlEZWMgPCAwKSBpRGVjID0gLWlEZWM7CisJCisJaWYgKGlTZXBTdHlsZSA8IDAgfHwgaVNlcFN0eWxlID4gMykKKwkJaVNlcFN0eWxlID0gMDsKKwkKKwlpZiAoaU5lZ1N0eWxlIDwgMCB8fCBpTmVnU3R5bGUgPiAzKQorCQlpTmVnU3R5bGUgPSAwOworCQorCQorCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCS8vZm9yIHByb2Nlc3NpbmcgZGVjaW1hbCBwbGFjZXMKKwlzdHJWYWx1ZS5SZXBsYWNlKCIsIiwgIi4iKTsKKwlkb3VibGUgZFZhbHVlID0gYXRvZihzdHJWYWx1ZSk7CisJaWYgKGlEZWMgPiAwKQorCQlkVmFsdWUgKz0gRE9VQkxFX0NPUlJFQ1Q7Ly8KKwkJICAgIAorCWludCBpRGVjMjsKKwlGWF9CT09MIGJOYWdhdGl2ZSA9IEZBTFNFOworCisJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsKKwlpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKQorCXsKKwkJZFZhbHVlID0gMDsKKwkJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsKKwkJaWYgKHN0clZhbHVlLklzRW1wdHkoKSkKKwkJeworCQkJc3RyVmFsdWUgPSAiMCI7CisJCQlpRGVjMiA9IDE7CisJCX0KKworCX0KKworCWlmIChpRGVjMiA8IDApCisJeworCQlmb3IgKGludCBpTnVtID0gMDtpTnVtIDwgYWJzKGlEZWMyKTtpTnVtKyspCisJCXsKKwkJCXN0clZhbHVlID0gIjAiICsgc3RyVmFsdWU7CisJCX0KKwkJaURlYzIgPSAwOworCQkKKwl9CisJaW50IGlNYXggPSBzdHJWYWx1ZS5HZXRMZW5ndGgoKTsKKwlpZiAoaURlYzIgPiBpTWF4KQorCXsKKwkJZm9yIChpbnQgaU51bSA9IDA7aU51bSA8PSBpRGVjMiAtIGlNYXggO2lOdW0rKykKKwkJeworCQkJc3RyVmFsdWUgKz0gIjAiOworCQl9CisJCWlNYXggPSBpRGVjMisxOwkJCQorCX0KKwkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgICAgLy9mb3IgcHJvY2Vzc2luZyBzZXBlcmF0b3Igc3R5bGUKKwlpZiAoaURlYzIgPCBpTWF4KQorCXsKKwkJaWYgKGlTZXBTdHlsZSA9PSAwIHx8IGlTZXBTdHlsZSA9PSAxKQorCQl7CisJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcuJyk7CisJCQlpTWF4Kys7CisJCX0KKwkJZWxzZSBpZiAoaVNlcFN0eWxlID09IDIgfHwgaVNlcFN0eWxlID09IDMpCisJCXsKKwkJCXN0clZhbHVlLkluc2VydChpRGVjMiwgJywnKTsKKwkJCWlNYXgrKzsKKwkJfQorCQkKKwkJaWYgKGlEZWMyID09IDApCisJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcwJyk7CisJfQorCWlmIChpU2VwU3R5bGUgPT0gMCB8fCBpU2VwU3R5bGUgPT0gMikKKwl7CisJCWNoYXIgY1NlcGVyYXRvcjsKKwkJaWYgKGlTZXBTdHlsZSA9PSAwKQorCQkJY1NlcGVyYXRvciA9ICcsJzsKKwkJZWxzZQorCQkJY1NlcGVyYXRvciA9ICcuJzsKKwkJCisJCWludCBpRGVjUG9zaXRpdmUsaURlY05hZ2F0aXZlOworCQlpRGVjUG9zaXRpdmUgPSBpRGVjMjsKKwkJaURlY05hZ2F0aXZlID0gaURlYzI7CQkKKwkJCisJCWZvciAoaURlY1Bvc2l0aXZlID0gaURlYzIgLTM7IGlEZWNQb3NpdGl2ZSA+IDA7aURlY1Bvc2l0aXZlIC09IDMpCisJCXsKKwkJCXN0clZhbHVlLkluc2VydChpRGVjUG9zaXRpdmUsIGNTZXBlcmF0b3IpOworCQkJaU1heCsrOworCQl9CisJfQorCQorCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKyAgICAvL2ZvciBwcm9jZXNzaW5nIGN1cnJlbmN5IHN0cmluZworCisJVmFsdWUgPSBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKHN0clZhbHVlKTsKKwkKKwlzdGQ6OndzdHJpbmcgc3RyVmFsdWUyKFZhbHVlKTsKKworCWlmIChiQ3VycmVuY3lQcmVwZW5kKQorCQlzdHJWYWx1ZTIgPSB3c3RyQ3VycmVuY3kgKyBzdHJWYWx1ZTI7CisJZWxzZQorCQlzdHJWYWx1ZTIgPSBzdHJWYWx1ZTIgKyB3c3RyQ3VycmVuY3k7CisJCisJCisJCisJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCS8vZm9yIHByb2Nlc3NpbmcgbmVnYXRpdmUgc3R5bGUKKwlpZiAoYk5hZ2F0aXZlKQorCXsKKwkJaWYgKGlOZWdTdHlsZSA9PSAwKQorCQl7CisJCQlzdHJWYWx1ZTIuaW5zZXJ0KDAsTCItIik7CisJCX0KKwkJaWYgKGlOZWdTdHlsZSA9PSAyIHx8IGlOZWdTdHlsZSA9PSAzKQorCQl7CisJCQlzdHJWYWx1ZTIuaW5zZXJ0KDAsTCIoIik7CisJCQlzdHJWYWx1ZTIuaW5zZXJ0KHN0clZhbHVlMi5sZW5ndGgoKSxMIikiKTsKKwkJfQorCQlpZiAoaU5lZ1N0eWxlID09IDEgfHwgaU5lZ1N0eWxlID09IDMpCisJCXsKKwkJCWlmIChGaWVsZCAqIGZUYXJnZXQgPSBwRXZlbnQtPlRhcmdldF9GaWVsZCgpKQorCQkJeworCQkJCUNKU19BcnJheSBhckNvbG9yKGlzb2xhdGUpOworCQkJCUNKU19WYWx1ZSB2Q29sRWxtKGlzb2xhdGUpOworCQkJCXZDb2xFbG0gPSBMIlJHQiI7CisJCQkJYXJDb2xvci5TZXRFbGVtZW50KDAsdkNvbEVsbSk7CisJCQkJdkNvbEVsbSA9IDE7CisJCQkJYXJDb2xvci5TZXRFbGVtZW50KDEsdkNvbEVsbSk7CisJCQkJdkNvbEVsbSA9IDA7CisJCQkJYXJDb2xvci5TZXRFbGVtZW50KDIsdkNvbEVsbSk7CisJCQkJCisJCQkJYXJDb2xvci5TZXRFbGVtZW50KDMsdkNvbEVsbSk7CisJCQkJCisJCQkJQ0pTX1Byb3BWYWx1ZSB2UHJvcChpc29sYXRlKTsKKwkJCQl2UHJvcC5TdGFydEdldHRpbmcoKTsKKwkJCQl2UHJvcDw8YXJDb2xvcjsKKwkJCQl2UHJvcC5TdGFydFNldHRpbmcoKTsKKwkJCQlmVGFyZ2V0LT50ZXh0Q29sb3IoY2MsdlByb3Asc0Vycm9yKTsvLyByZWQKKwkJCX0KKwkJfQorCX0KKwllbHNlCisJeworCQlpZiAoaU5lZ1N0eWxlID09IDEgfHwgaU5lZ1N0eWxlID09IDMpCisJCXsKKwkJCWlmIChGaWVsZCAqZlRhcmdldCA9IHBFdmVudC0+VGFyZ2V0X0ZpZWxkKCkpCisJCQl7CisJCQkJQ0pTX0FycmF5IGFyQ29sb3IoaXNvbGF0ZSk7CisJCQkJQ0pTX1ZhbHVlIHZDb2xFbG0oaXNvbGF0ZSk7CisJCQkJdkNvbEVsbSA9IEwiUkdCIjsKKwkJCQlhckNvbG9yLlNldEVsZW1lbnQoMCx2Q29sRWxtKTsKKwkJCQl2Q29sRWxtID0gMDsKKwkJCQlhckNvbG9yLlNldEVsZW1lbnQoMSx2Q29sRWxtKTsKKwkJCQlhckNvbG9yLlNldEVsZW1lbnQoMix2Q29sRWxtKTsKKwkJCQlhckNvbG9yLlNldEVsZW1lbnQoMyx2Q29sRWxtKTsKKwkJCQkKKwkJCQlDSlNfUHJvcFZhbHVlIHZQcm9wKGlzb2xhdGUpOworCQkJCXZQcm9wLlN0YXJ0R2V0dGluZygpOworCQkJCWZUYXJnZXQtPnRleHRDb2xvcihjYyx2UHJvcCxzRXJyb3IpOworCQkJCQorCQkJCUNKU19BcnJheSBhUHJvcChpc29sYXRlKTsKKwkJCQl2UHJvcC5Db252ZXJ0VG9BcnJheShhUHJvcCk7CisKKwkJCQlDUFdMX0NvbG9yIGNyUHJvcDsKKwkJCQlDUFdMX0NvbG9yIGNyQ29sb3I7CisJCQkJY29sb3I6OkNvbnZlcnRBcnJheVRvUFdMQ29sb3IoYVByb3AsIGNyUHJvcCk7CisJCQkJY29sb3I6OkNvbnZlcnRBcnJheVRvUFdMQ29sb3IoYXJDb2xvciwgY3JDb2xvcik7CisKKwkJCQlpZiAoY3JDb2xvciAhPSBjclByb3ApCisJCQkJeworCQkJCQlDSlNfUHJvcFZhbHVlIHZQcm9wMihpc29sYXRlKTsKKwkJCQkJdlByb3AyLlN0YXJ0R2V0dGluZygpOworCQkJCQl2UHJvcDI8PGFyQ29sb3I7CisJCQkJCXZQcm9wMi5TdGFydFNldHRpbmcoKTsKKyAgICAgCQkJCWZUYXJnZXQtPnRleHRDb2xvcihjYyx2UHJvcDIsc0Vycm9yKTsKKwkJCQl9CisJCQl9CisJCX0KKwl9CisJVmFsdWUgPSBzdHJWYWx1ZTIuY19zdHIoKTsKKyNlbmRpZgorCXJldHVybiBUUlVFOworfQorCisvL2Z1bmN0aW9uIEFGTnVtYmVyX0tleXN0cm9rZShuRGVjLCBzZXBTdHlsZSwgbmVnU3R5bGUsIGN1cnJTdHlsZSwgc3RyQ3VycmVuY3ksIGJDdXJyZW5jeVByZXBlbmQpCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRk51bWJlcl9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCQorCWlmKHBhcmFtcy5zaXplKCkgPCAyKQorCQlyZXR1cm4gRkFMU0U7CisJaW50IGlTZXBTdHlsZSA9IHBhcmFtc1sxXTsKKwkKKwlpZiAoaVNlcFN0eWxlIDwgMCB8fCBpU2VwU3R5bGUgPiAzKQorCQlpU2VwU3R5bGUgPSAwOworCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQorCQlyZXR1cm4gRkFMU0U7CisJQ0ZYX1dpZGVTdHJpbmcgJiB2YWwgPSBwRXZlbnQtPlZhbHVlKCk7CQorCUNGWF9XaWRlU3RyaW5nICYgd19zdHJDaGFuZ2UgPSBwRXZlbnQtPkNoYW5nZSgpOworICAgIENGWF9XaWRlU3RyaW5nIHdfc3RyVmFsdWUgPSB2YWw7CisKKwlpZiAocEV2ZW50LT5XaWxsQ29tbWl0KCkpCisJeworCQlDRlhfV2lkZVN0cmluZyB3c3RyQ2hhbmdlID0gd19zdHJDaGFuZ2U7CisJCUNGWF9XaWRlU3RyaW5nIHdzdHJWYWx1ZSA9IFN0ckxUcmltKHdfc3RyVmFsdWUpOworCQlpZiAod3N0clZhbHVlLklzRW1wdHkoKSkKKwkJCXJldHVybiBUUlVFOworCQkKKwkJQ0ZYX1dpZGVTdHJpbmcgc3dUZW1wID0gd3N0clZhbHVlOworCQlzd1RlbXAuUmVwbGFjZSgoRlhfTFBDV1NUUilMIiwiLCAoRlhfTFBDV1NUUilMIi4iKTsKKwkJaWYgKCFJc051bWJlcihzd1RlbXApKSAvLyEoSXNOdW1iZXIod3N0ckNoYW5nZSkgJiYgCisJCXsKKwkJCXBFdmVudC0+UmMoKSA9IEZBTFNFOworCQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UpOworCQkJQWxlcnQocENvbnRleHQsIHNFcnJvcik7CisJCQlyZXR1cm4gVFJVRTsKKwkJfQorCQlyZXR1cm4gVFJVRTsgLy8gaXQgaGFwcGVucyBhZnRlciB0aGUgbGFzdCBrZXlzdHJva2UgYW5kIGJlZm9yZSB2YWxpZGF0aW5nLAorCX0KKwkKKwlzdGQ6OndzdHJpbmcgd19zdHJWYWx1ZTIgKHdfc3RyVmFsdWUpOworCXN0ZDo6d3N0cmluZyB3X3N0ckNoYW5nZTIod19zdHJDaGFuZ2UpOworCQorCXN0ZDo6d3N0cmluZyB3X3N0clNlbGVjdGVkOworCWlmKC0xICE9IHBFdmVudC0+U2VsU3RhcnQoKSkKKwkJd19zdHJTZWxlY3RlZCA9IHdfc3RyVmFsdWUyLnN1YnN0cihwRXZlbnQtPlNlbFN0YXJ0KCksKHBFdmVudC0+U2VsRW5kKCkgLSBwRXZlbnQtPlNlbFN0YXJ0KCkpKTsKKwlGWF9CT09MIGJIYXNTaWduID0gKHdfc3RyVmFsdWUyLmZpbmQoJy0nKSAhPSAtMSkgJiYgKHdfc3RyU2VsZWN0ZWQuZmluZCgnLScpID09IC0xKTsKKwlpZiAoYkhhc1NpZ24pCisJeworCQkvL2Nhbid0IGluc2VydCAiY2hhbmdlIiBpbiBmcm9udCB0byBzaWduIHBvc3Rpb24uCisJCWlmIChwRXZlbnQtPlNlbFN0YXJ0KCkgPT0gMCkKKwkJeworICAgICAgICAgICAgRlhfQk9PTCAmYlJjID0gcEV2ZW50LT5SYygpOworCQkJYlJjID0gRkFMU0U7CisJCQlyZXR1cm4gVFJVRTsKKwkJfQorCX0KKworCWNoYXIgY1NlcCA9IEwnLic7CisKKwlzd2l0Y2ggKGlTZXBTdHlsZSkKKwl7CisJY2FzZSAwOgorCWNhc2UgMToKKwkJY1NlcCA9IEwnLic7CisJCWJyZWFrOworCWNhc2UgMjoKKwljYXNlIDM6CisJCWNTZXAgPSBMJywnOworCQlicmVhazsKKwl9CisJCisJRlhfQk9PTCBiSGFzU2VwID0gKHdfc3RyVmFsdWUyLmZpbmQoY1NlcCkgIT0gLTEpOworCWZvciAoc3RkOjp3c3RyaW5nOjppdGVyYXRvciBpdCA9IHdfc3RyQ2hhbmdlMi5iZWdpbigpOyBpdCAhPSB3X3N0ckNoYW5nZTIuZW5kKCk7IGl0KyspCisJeworCQlpZiAoKml0ID09IGNTZXApCisJCXsKKwkJCWlmIChiSGFzU2VwKQorCQkJeworCQkJCUZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKKwkJCQliUmMgPSBGQUxTRTsKKwkJCQlyZXR1cm4gVFJVRTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQliSGFzU2VwID0gVFJVRTsKKwkJCQljb250aW51ZTsKKwkJCX0KKwkJfQorCQlpZiAoKml0ID09IEwnLScpCisJCXsKKwkJCWlmIChiSGFzU2lnbikKKwkJCXsKKwkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CisJCQkJYlJjID0gRkFMU0U7CisJCQkJcmV0dXJuIFRSVUU7CisJCQl9CisJCQllbHNlIGlmIChpdCAhPSB3X3N0ckNoYW5nZTIuYmVnaW4oKSkgLy9zaWduJ3MgcG9zaXRpb24gaXMgbm90IGNvcnJlY3QKKwkJCXsKKwkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CisJCQkJYlJjID0gRkFMU0U7CisJCQkJcmV0dXJuIFRSVUU7CisJCQl9CisJCQllbHNlIGlmIChwRXZlbnQtPlNlbFN0YXJ0KCkgIT0gMCkKKwkJCXsKKwkJCQlGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7CisJCQkJYlJjID0gRkFMU0U7CisJCQkJcmV0dXJuIFRSVUU7CisJCQl9CisJCQliSGFzU2lnbiA9IFRSVUU7CisJCQljb250aW51ZTsKKwkJfQorCQkKKwkJaWYgKCFJc0RpZ2l0KCppdCkpCisJCXsJCQkKKwkJCUZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKKwkJCWJSYyA9IEZBTFNFOworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisJCisJCisJc3RkOjp3c3RyaW5nIHdfcHJlZml4ID0gd19zdHJWYWx1ZTIuc3Vic3RyKDAscEV2ZW50LT5TZWxTdGFydCgpKTsKKwlzdGQ6OndzdHJpbmcgd19wb3N0Zml4OworCWlmIChwRXZlbnQtPlNlbEVuZCgpPChpbnQpd19zdHJWYWx1ZTIubGVuZ3RoKCkpCisJCXdfcG9zdGZpeCAgPSB3X3N0clZhbHVlMi5zdWJzdHIocEV2ZW50LT5TZWxFbmQoKSk7CisJd19zdHJWYWx1ZTIgPSB3X3ByZWZpeCArIHdfc3RyQ2hhbmdlMiArIHdfcG9zdGZpeDsKKwl3X3N0clZhbHVlID0gd19zdHJWYWx1ZTIuY19zdHIoKTsKKwl2YWwgPSB3X3N0clZhbHVlOworCXJldHVybiBUUlVFOwkJCisJCit9CisKKy8vZnVuY3Rpb24gQUZQZXJjZW50X0Zvcm1hdChuRGVjLCBzZXBTdHlsZSkKK0ZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGUGVyY2VudF9Gb3JtYXQoT0JKX01FVEhPRF9QQVJBTVMpCit7CisjaWYgX0ZYX09TXyAhPSBfRlhfQU5EUk9JRF8KKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOworCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CisKKyAgICBpZiAocGFyYW1zLnNpemUoKSAhPSAyKQorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKwlpZighcEV2ZW50LT5tX3BWYWx1ZSkKKwkJcmV0dXJuIEZBTFNFOworCUNGWF9XaWRlU3RyaW5nJiBWYWx1ZSA9IHBFdmVudC0+VmFsdWUoKTsKKwkKKy8vICAgICBIV05EIGhNYWluRnJhbWUgPSBOVUxMOworLy8gCQorLy8gCUNQREZTREtfRm9ybUZpbGxBcHAgKnBBcHAgPSBwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCk7CisvLyAJQVNTRVJUKHBBcHApOworLy8gCWhNYWluRnJhbWUgPSBwQXBwLT5HZXRNYWluRnJhbWVXbmQoKTsKKwkJCisJQ0ZYX0J5dGVTdHJpbmcgc3RyVmFsdWUgPSBTdHJUcmltKENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShWYWx1ZSkpOworCQorCWlmIChzdHJWYWx1ZS5Jc0VtcHR5KCkpCisJCXJldHVybiBUUlVFOworCQorCWludCBpRGVjID0gcGFyYW1zWzBdOworCWludCBpU2VwU3R5bGUgPSBwYXJhbXNbMV07CisJCisJLy9BU1NFUlQoaURlYyA+IDApOworCWlmIChpRGVjIDwgMCkKKwkJaURlYyA9IC1pRGVjOworCQorCWlmIChpU2VwU3R5bGUgPCAwIHx8IGlTZXBTdHlsZSA+IDMpCisJCWlTZXBTdHlsZSA9IDA7CisJCisJCisJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisJLy9mb3IgcHJvY2Vzc2luZyBkZWNpbWFsIHBsYWNlcworCWRvdWJsZSBkVmFsdWUgPSBhdG9mKHN0clZhbHVlKTsKKwlkVmFsdWUgKj0gMTAwOworCWlmIChpRGVjID4gMCkKKwkJZFZhbHVlICs9IERPVUJMRV9DT1JSRUNUOy8v0KPV/QorCisJaW50IGlEZWMyOworCUZYX0JPT0wgYk5hZ2F0aXZlID0gRkFMU0U7CisJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsKKyAgICBpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKQorCXsKKwkJZFZhbHVlID0gMDsKKwkJc3RyVmFsdWUgPSBmY3Z0KGRWYWx1ZSxpRGVjLCZpRGVjMiwmYk5hZ2F0aXZlKTsKKwl9CisKKwlpZiAoaURlYzIgPCAwKQorCXsKKwkJZm9yIChpbnQgaU51bSA9IDA7IGlOdW0gPCBhYnMoaURlYzIpOyBpTnVtKyspCisJCXsKKwkJCXN0clZhbHVlID0gIjAiICsgc3RyVmFsdWU7CisJCX0KKwkJaURlYzIgPSAwOworCQkKKwl9CisJaW50IGlNYXggPSBzdHJWYWx1ZS5HZXRMZW5ndGgoKTsKKwlpZiAoaURlYzIgPiBpTWF4KQorCXsKKwkJZm9yIChpbnQgaU51bSA9IDA7IGlOdW0gPD0gaURlYzIgLSBpTWF4OyBpTnVtKyspCisJCXsKKwkJCXN0clZhbHVlICs9ICIwIjsKKwkJfQorCQlpTWF4ID0gaURlYzIrMTsJCQkKKwl9CisJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworICAgIC8vZm9yIHByb2Nlc3Npbmcgc2VwZXJhdG9yIHN0eWxlCisJaWYgKGlEZWMyIDwgaU1heCkKKwl7CisJCWlmIChpU2VwU3R5bGUgPT0gMCB8fCBpU2VwU3R5bGUgPT0gMSkKKwkJeworCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnLicpOworCQkJaU1heCsrOworCQl9CisJCWVsc2UgaWYgKGlTZXBTdHlsZSA9PSAyIHx8IGlTZXBTdHlsZSA9PSAzKQorCQl7CisJCQlzdHJWYWx1ZS5JbnNlcnQoaURlYzIsICcsJyk7CisJCQlpTWF4Kys7CisJCX0KKwkJCisJCWlmIChpRGVjMiA9PSAwKQorCQkJc3RyVmFsdWUuSW5zZXJ0KGlEZWMyLCAnMCcpOworCX0KKwlpZiAoaVNlcFN0eWxlID09IDAgfHwgaVNlcFN0eWxlID09IDIpCisJeworCQljaGFyIGNTZXBlcmF0b3I7CisJCWlmIChpU2VwU3R5bGUgPT0gMCkKKwkJCWNTZXBlcmF0b3IgPSAnLCc7CisJCWVsc2UKKwkJCWNTZXBlcmF0b3IgPSAnLic7CisJCQorCQlpbnQgaURlY1Bvc2l0aXZlLGlEZWNOYWdhdGl2ZTsKKwkJaURlY1Bvc2l0aXZlID0gaURlYzI7CisJCWlEZWNOYWdhdGl2ZSA9IGlEZWMyOworCQkJCisJCWZvciAoaURlY1Bvc2l0aXZlID0gaURlYzIgLTM7IGlEZWNQb3NpdGl2ZSA+IDA7IGlEZWNQb3NpdGl2ZSAtPSAzKQorCQl7CisJCQlzdHJWYWx1ZS5JbnNlcnQoaURlY1Bvc2l0aXZlLGNTZXBlcmF0b3IpOworCQkJaU1heCsrOworCQl9CisJfQorCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisJLy9uYWdhdGl2ZSBtYXJrCisJaWYoYk5hZ2F0aXZlKQorCQlzdHJWYWx1ZSA9ICItIiArIHN0clZhbHVlOworCXN0clZhbHVlICs9ICIlIjsKKwlWYWx1ZSA9IENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoc3RyVmFsdWUpOworI2VuZGlmCisJcmV0dXJuIFRSVUU7Cit9CisvL0FGUGVyY2VudF9LZXlzdHJva2UobkRlYywgc2VwU3R5bGUpCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlBlcmNlbnRfS2V5c3Ryb2tlKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXJldHVybiBBRk51bWJlcl9LZXlzdHJva2UoY2MscGFyYW1zLHZSZXQsc0Vycm9yKTsKK30KKworLy9mdW5jdGlvbiBBRkRhdGVfRm9ybWF0RXgoY0Zvcm1hdCkKK0ZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGRGF0ZV9Gb3JtYXRFeChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOworCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CisKKwlpZiAocGFyYW1zLnNpemUoKSAhPSAxKQorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0JCisJaWYoIXBFdmVudC0+bV9wVmFsdWUpCisJCXJldHVybiBGQUxTRTsKKwlDRlhfV2lkZVN0cmluZyYgdmFsID0gcEV2ZW50LT5WYWx1ZSgpOworCQorCUNGWF9XaWRlU3RyaW5nIHN0clZhbHVlID0gdmFsOwkKKwlpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsJCQorCisJQ0ZYX1dpZGVTdHJpbmcgc0Zvcm1hdCA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJRlhfQk9PTCBiV3JvbmdGb3JtYXQgPSBGQUxTRTsKKwlkb3VibGUgZERhdGUgPSAwLjBmOworCisJaWYoc3RyVmFsdWUuRmluZChMIkdNVCIpICE9IC0xKQorCXsKKwkJLy9mb3IgR01UIGZvcm1hdCB0aW1lCisJCS8vc3VjaCBhcyAiVHVlIEF1ZyAxMSAxNDoyNDoxNiBHTVQrMDgwMDIwMDkiCisJCWREYXRlID0gTWFrZUludGVyRGF0ZShzdHJWYWx1ZSk7CisJfQorCWVsc2UKKwl7CisJCWREYXRlID0gTWFrZVJlZ3VsYXJEYXRlKHN0clZhbHVlLHNGb3JtYXQsYldyb25nRm9ybWF0KTsKKwl9CisKKwlpZiAoSlNfUG9ydElzTmFuKGREYXRlKSkKKwl7CisJCUNGWF9XaWRlU3RyaW5nIHN3TXNnOworCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJTRURBVEUpLCAoRlhfTFBDV1NUUilzRm9ybWF0KTsKKwkJQWxlcnQocENvbnRleHQsIHN3TXNnKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKwkKKwl2YWwgPSAgTWFrZUZvcm1hdERhdGUoZERhdGUsc0Zvcm1hdCk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworZG91YmxlIENKU19QdWJsaWNNZXRob2RzOjpNYWtlSW50ZXJEYXRlKENGWF9XaWRlU3RyaW5nIHN0clZhbHVlKQoreworCWludCBuSG91cjsKKwlpbnQgbk1pbjsKKwlpbnQgblNlYzsKKwlpbnQgblllYXI7CisJaW50IG5Nb250aDsKKwlpbnQgbkRheTsKKworCUNGWF9XaWRlU3RyaW5nQXJyYXkgd3NBcnJheTsKKwlDRlhfV2lkZVN0cmluZyBzTW9udGggPSBMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgc1RlbXAgPSBMIiI7CisJaW50IG5TaXplID0gc3RyVmFsdWUuR2V0TGVuZ3RoKCk7CisKKwlmb3IoaW50IGkgPSAwOyBpIDwgblNpemU7IGkrKykKKwl7CisJCUZYX1dDSEFSIGMgPSBzdHJWYWx1ZS5HZXRBdChpKTsKKwkJaWYoYyA9PSBMJyAnIHx8IGMgPT0gTCc6JykKKwkJewkKKwkJCXdzQXJyYXkuQWRkKHNUZW1wKTsKKwkJCXNUZW1wID0gTCIiOworCQkJY29udGludWU7CisJCX0KKworCQlzVGVtcCArPSBjOworCX0KKwkKKwl3c0FycmF5LkFkZChzVGVtcCk7CisJaWYod3NBcnJheS5HZXRTaXplKCkgIT0gOClyZXR1cm4gMDsKKworCXNUZW1wID0gd3NBcnJheVsxXTsKKwlpZihzVGVtcC5Db21wYXJlKEwiSmFuIikgPT0gMCkgbk1vbnRoID0gMTsKKwlpZihzVGVtcC5Db21wYXJlKEwiRmViIikgPT0gMCkgbk1vbnRoID0gMjsKKwlpZihzVGVtcC5Db21wYXJlKEwiTWFyIikgPT0gMCkgbk1vbnRoID0gMzsKKwlpZihzVGVtcC5Db21wYXJlKEwiQXByIikgPT0gMCkgbk1vbnRoID0gNDsKKwlpZihzVGVtcC5Db21wYXJlKEwiTWF5IikgPT0gMCkgbk1vbnRoID0gNTsKKwlpZihzVGVtcC5Db21wYXJlKEwiSnVuIikgPT0gMCkgbk1vbnRoID0gNjsKKwlpZihzVGVtcC5Db21wYXJlKEwiSnVsIikgPT0gMCkgbk1vbnRoID0gNzsKKwlpZihzVGVtcC5Db21wYXJlKEwiQXVnIikgPT0gMCkgbk1vbnRoID0gODsKKwlpZihzVGVtcC5Db21wYXJlKEwiU2VwIikgPT0gMCkgbk1vbnRoID0gOTsKKwlpZihzVGVtcC5Db21wYXJlKEwiT2N0IikgPT0gMCkgbk1vbnRoID0gMTA7CisJaWYoc1RlbXAuQ29tcGFyZShMIk5vdiIpID09IDApIG5Nb250aCA9IDExOworCWlmKHNUZW1wLkNvbXBhcmUoTCJEZWMiKSA9PSAwKSBuTW9udGggPSAxMjsKKworCW5EYXkgPSAoaW50KVBhcnNlU3RyaW5nVG9OdW1iZXIod3NBcnJheVsyXSk7CisJbkhvdXIgPSAoaW50KVBhcnNlU3RyaW5nVG9OdW1iZXIod3NBcnJheVszXSk7CisJbk1pbiA9IChpbnQpUGFyc2VTdHJpbmdUb051bWJlcih3c0FycmF5WzRdKTsKKwluU2VjID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbNV0pOworCW5ZZWFyID0gKGludClQYXJzZVN0cmluZ1RvTnVtYmVyKHdzQXJyYXlbN10pOworCisJZG91YmxlIGRSZXQgPSBKU19NYWtlRGF0ZShKU19NYWtlRGF5KG5ZZWFyLG5Nb250aCAtIDEsbkRheSksSlNfTWFrZVRpbWUobkhvdXIsIG5NaW4sIG5TZWMsIDApKTsKKworCWlmIChKU19Qb3J0SXNOYW4oZFJldCkpCisJeworCQlkUmV0ID0gSlNfRGF0ZVBhcnNlKHN0clZhbHVlKTsKKwl9CisJCisJcmV0dXJuIGRSZXQ7Cit9CisKKy8vQUZEYXRlX0tleXN0cm9rZUV4KGNGb3JtYXQpCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkRhdGVfS2V5c3Ryb2tlRXgoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKKwl7CisJCXNFcnJvciA9IEwiQUZEYXRlX0tleXN0cm9rZUV4J3MgcGFyYW1ldGVycycgc2l6ZSByIG5vdCBjb3JyZWN0IjsKKwkJcmV0dXJuIEZBTFNFOworCX0JCisJCisJaWYgKHBFdmVudC0+V2lsbENvbW1pdCgpKQorCXsKKwkJaWYoIXBFdmVudC0+bV9wVmFsdWUpCisJCQlyZXR1cm4gRkFMU0U7CisJCUNGWF9XaWRlU3RyaW5nIHN0clZhbHVlID0gcEV2ZW50LT5WYWx1ZSgpOworCQlpZiAoc3RyVmFsdWUuSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsKKworCQlDRlhfV2lkZVN0cmluZyBzRm9ybWF0ID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisKKwkJRlhfQk9PTCBiV3JvbmdGb3JtYXQgPSBGQUxTRTsKKwkJZG91YmxlIGRSZXQgPSBNYWtlUmVndWxhckRhdGUoc3RyVmFsdWUsc0Zvcm1hdCxiV3JvbmdGb3JtYXQpOworCQlpZiAoYldyb25nRm9ybWF0IHx8IEpTX1BvcnRJc05hbihkUmV0KSkKKwkJeworCQkJQ0ZYX1dpZGVTdHJpbmcgc3dNc2c7CisJCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJTRURBVEUpLCAoRlhfTFBDV1NUUilzRm9ybWF0KTsKKwkJCUFsZXJ0KHBDb250ZXh0LCBzd01zZyk7CisJCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkRhdGVfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKKworCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCisJeworCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCWludCBpSW5kZXggPSBwYXJhbXNbMF07CisJRlhfTFBDV1NUUiBjRm9ybWF0c1tdID0gIHsoRlhfTFBDV1NUUilMIm0vZCIsIChGWF9MUENXU1RSKUwibS9kL3l5IiwgKEZYX0xQQ1dTVFIpTCJtbS9kZC95eSIsIChGWF9MUENXU1RSKUwibW0veXkiLCAoRlhfTFBDV1NUUilMImQtbW1tIiwgKEZYX0xQQ1dTVFIpTCJkLW1tbS15eSIsIChGWF9MUENXU1RSKUwiZGQtbW1tLXl5IiwKKwkJKEZYX0xQQ1dTVFIpTCJ5eS1tbS1kZCIsIChGWF9MUENXU1RSKUwibW1tLXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW1tLXl5IiwgKEZYX0xQQ1dTVFIpTCJtbW0gZCwgeXl5eSIsIChGWF9MUENXU1RSKUwibW1tbSBkLCB5eXl5IiwKKwkJKEZYX0xQQ1dTVFIpTCJtL2QveXkgaDpNTSB0dCIsIChGWF9MUENXU1RSKUwibS9kL3l5IEhIOk1NIiB9OworCisJQVNTRVJUKGlJbmRleCA8IHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKTsKKworCWlmIChpSW5kZXggPCAwKQorCQlpSW5kZXggPSAwOworCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpCisJCWlJbmRleCA9IDA7CisJQ0pTX1BhcmFtZXRlcnMgbmV3UGFyYW1zOworCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsKKwluZXdQYXJhbXMucHVzaF9iYWNrKHZhbCk7CisJcmV0dXJuIEFGRGF0ZV9Gb3JtYXRFeChjYyxuZXdQYXJhbXMsdlJldCxzRXJyb3IpOworfQorCisvL0FGRGF0ZV9LZXlzdHJva2VFeChjRm9ybWF0KQorRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZEYXRlX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CisKKwlpZiAocGFyYW1zLnNpemUoKSAhPSAxKQorCXsKKwkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlpbnQgaUluZGV4ID0gcGFyYW1zWzBdOworCUZYX0xQQ1dTVFIgY0Zvcm1hdHNbXSA9ICB7KEZYX0xQQ1dTVFIpTCJtL2QiLCAoRlhfTFBDV1NUUilMIm0vZC95eSIsIChGWF9MUENXU1RSKUwibW0vZGQveXkiLCAoRlhfTFBDV1NUUilMIm1tL3l5IiwgKEZYX0xQQ1dTVFIpTCJkLW1tbSIsIChGWF9MUENXU1RSKUwiZC1tbW0teXkiLCAoRlhfTFBDV1NUUilMImRkLW1tbS15eSIsCisJCShGWF9MUENXU1RSKUwieXktbW0tZGQiLCAoRlhfTFBDV1NUUilMIm1tbS15eSIsIChGWF9MUENXU1RSKUwibW1tbS15eSIsIChGWF9MUENXU1RSKUwibW1tIGQsIHl5eXkiLCAoRlhfTFBDV1NUUilMIm1tbW0gZCwgeXl5eSIsCisJCShGWF9MUENXU1RSKUwibS9kL3l5IGg6TU0gdHQiLCAoRlhfTFBDV1NUUilMIm0vZC95eSBISDpNTSIgfTsKKworCUFTU0VSVChpSW5kZXg8c2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpOworCisJaWYgKGlJbmRleCA8IDApCisJCWlJbmRleCA9IDA7CisJaWYgKGlJbmRleCA+PSBzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSkKKwkJaUluZGV4ID0gMDsKKwlDSlNfUGFyYW1ldGVycyBuZXdQYXJhbXM7CisJQ0pTX1ZhbHVlIHZhbChpc29sYXRlLGNGb3JtYXRzW2lJbmRleF0pOworCW5ld1BhcmFtcy5wdXNoX2JhY2sodmFsKTsKKwlyZXR1cm4gQUZEYXRlX0tleXN0cm9rZUV4KGNjLG5ld1BhcmFtcyx2UmV0LHNFcnJvcik7Cit9CisKKy8vZnVuY3Rpb24gQUZUaW1lX0Zvcm1hdChwdGYpCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlRpbWVfRm9ybWF0KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKKworCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCisJeworCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlpbnQgaUluZGV4ID0gcGFyYW1zWzBdOworCUZYX0xQQ1dTVFIgY0Zvcm1hdHNbXSA9IHsoRlhfTFBDV1NUUilMIkhIOk1NIiwgKEZYX0xQQ1dTVFIpTCJoOk1NIHR0IiwgKEZYX0xQQ1dTVFIpTCJISDpNTTpzcyIsIChGWF9MUENXU1RSKUwiaDpNTTpzcyB0dCJ9OworCisJQVNTRVJUKGlJbmRleDxzaXplb2YoY0Zvcm1hdHMpL3NpemVvZihGWF9MUENXU1RSKSk7CisKKwlpZiAoaUluZGV4IDwgMCkKKwkJaUluZGV4ID0gMDsKKwlpZiAoaUluZGV4ID49IHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKQorCQlpSW5kZXggPSAwOworCUNKU19QYXJhbWV0ZXJzIG5ld1BhcmFtczsKKwlDSlNfVmFsdWUgdmFsKGlzb2xhdGUsY0Zvcm1hdHNbaUluZGV4XSk7CisJbmV3UGFyYW1zLnB1c2hfYmFjayh2YWwpOworCXJldHVybiBBRkRhdGVfRm9ybWF0RXgoY2MsbmV3UGFyYW1zLHZSZXQsc0Vycm9yKTsKK30KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZUaW1lX0tleXN0cm9rZShPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IDo6R2V0SXNvbGF0ZShjYyk7CisJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKKwl7CisJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCWludCBpSW5kZXggPSBwYXJhbXNbMF07CisJRlhfTFBDV1NUUiBjRm9ybWF0c1tdID0geyhGWF9MUENXU1RSKUwiSEg6TU0iLCAoRlhfTFBDV1NUUilMImg6TU0gdHQiLCAoRlhfTFBDV1NUUilMIkhIOk1NOnNzIiwgKEZYX0xQQ1dTVFIpTCJoOk1NOnNzIHR0In07CisKKwlBU1NFUlQoaUluZGV4PHNpemVvZihjRm9ybWF0cykvc2l6ZW9mKEZYX0xQQ1dTVFIpKTsKKworCWlmIChpSW5kZXggPCAwKQorCQlpSW5kZXggPSAwOworCWlmIChpSW5kZXggPj0gc2l6ZW9mKGNGb3JtYXRzKS9zaXplb2YoRlhfTFBDV1NUUikpCisJCWlJbmRleCA9IDA7CisJQ0pTX1BhcmFtZXRlcnMgbmV3UGFyYW1zOworCUNKU19WYWx1ZSB2YWwoaXNvbGF0ZSxjRm9ybWF0c1tpSW5kZXhdKTsKKwluZXdQYXJhbXMucHVzaF9iYWNrKHZhbCk7CisJcmV0dXJuIEFGRGF0ZV9LZXlzdHJva2VFeChjYyxuZXdQYXJhbXMsdlJldCxzRXJyb3IpOworfQorCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlRpbWVfRm9ybWF0RXgoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIEFGRGF0ZV9Gb3JtYXRFeChjYyxwYXJhbXMsdlJldCxzRXJyb3IpOworfQorCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlRpbWVfS2V5c3Ryb2tlRXgoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIEFGRGF0ZV9LZXlzdHJva2VFeChjYyxwYXJhbXMsdlJldCxzRXJyb3IpOworfQorCisvL2Z1bmN0aW9uIEFGU3BlY2lhbF9Gb3JtYXQocHNmKQorRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTcGVjaWFsX0Zvcm1hdChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwlpZiAocGFyYW1zLnNpemUoKSAhPSAxKQorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCXN0ZDo6c3RyaW5nIGNGb3JtYXQ7CisJaW50IGlJbmRleCA9IHBhcmFtc1swXTsKKworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJaWYoIXBFdmVudC0+bV9wVmFsdWUpCisJCXJldHVybiBGQUxTRTsKKwlDRlhfV2lkZVN0cmluZyYgVmFsdWUgPSBwRXZlbnQtPlZhbHVlKCk7CQorCXN0ZDo6c3RyaW5nIHN0clNyYyA9IChGWF9MUENTVFIpQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKFZhbHVlKTsKKwkKKwlzd2l0Y2ggKGlJbmRleCkgCisJeworCWNhc2UgMDogICAgICAgICAgICAgICAgICAgICAgICAgCisJCWNGb3JtYXQgPSAiOTk5OTkiOworCQlicmVhazsKKwljYXNlIDE6ICAgICAgICAgICAgICAgICAgICAgICAgIAorCQljRm9ybWF0ID0gIjk5OTk5LTk5OTkiOworCQlicmVhazsKKwljYXNlIDI6ICAgICAgICAgICAgICAgICAgICAgICAgIAorCQl7CisJCQlzdGQ6OnN0cmluZyBOdW1iZXJTdHI7CisJCQl1dGlsOjpwcmludHgoIjk5OTk5OTk5OTkiLCBzdHJTcmMsTnVtYmVyU3RyKTsgCisJCQlpZiAoTnVtYmVyU3RyLmxlbmd0aCgpID49IDEwICkKKwkJCQljRm9ybWF0ID0gIig5OTkpIDk5OS05OTk5IjsKKwkJCWVsc2UgCisJCQkJY0Zvcm1hdCA9ICI5OTktOTk5OSI7CisJCQlicmVhazsKKwkJfQorCWNhc2UgMzoKKwkJY0Zvcm1hdCA9ICI5OTktOTktOTk5OSI7CisJCWJyZWFrOworCX0KKwkKKwlzdGQ6OnN0cmluZyBzdHJEZXM7CisJdXRpbDo6cHJpbnR4KGNGb3JtYXQsc3RyU3JjLHN0ckRlcyk7CisJVmFsdWUgPSBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKHN0ckRlcy5jX3N0cigpKTsKKwlyZXR1cm4gVFJVRTsKK30KKworCisvL2Z1bmN0aW9uIEFGU3BlY2lhbF9LZXlzdHJva2VFeChtYXNrKQorRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTcGVjaWFsX0tleXN0cm9rZUV4KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CisKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJaWYgKHBhcmFtcy5zaXplKCkgPCAxKQorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCWlmKCFwRXZlbnQtPm1fcFZhbHVlKQorCQlyZXR1cm4gRkFMU0U7CisJQ0ZYX1dpZGVTdHJpbmcmIHZhbEV2ZW50ID0gcEV2ZW50LT5WYWx1ZSgpOworCisJQ0ZYX1dpZGVTdHJpbmcgd3N0ck1hc2sgPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKwlpZiAod3N0ck1hc2suSXNFbXB0eSgpKSByZXR1cm4gVFJVRTsKKwkKKwlzdGQ6OndzdHJpbmcgd3N0clZhbHVlKHZhbEV2ZW50KTsKKwkKKwlpZiAocEV2ZW50LT5XaWxsQ29tbWl0KCkpCisJeworCQlpZiAod3N0clZhbHVlLmVtcHR5KCkpCisJCQlyZXR1cm4gVFJVRTsKKwkJaW50IGlJbmRleE1hc2sgPSAwOworCQlmb3IgKHN0ZDo6d3N0cmluZzo6aXRlcmF0b3IgaXQgPSB3c3RyVmFsdWUuYmVnaW4oKTsgaXQgIT0gd3N0clZhbHVlLmVuZCgpOyBpdCsrKQorCQl7CisJCQl3Y2hhcl90IHdfVmFsdWUgPSAqaXQ7CisgICAgICAgICAgICBpZiAoIW1hc2tTYXRpc2ZpZWQod19WYWx1ZSx3c3RyTWFza1tpSW5kZXhNYXNrXSkpCisJCQkJYnJlYWs7CisJCQlpSW5kZXhNYXNrKys7CisJCX0KKworCQlpZiAoaUluZGV4TWFzayAhPSB3c3RyTWFzay5HZXRMZW5ndGgoKSB8fCAoaUluZGV4TWFzayAhPSB3c3RyVmFsdWUuc2l6ZSgpICYmIHdzdHJNYXNrLkdldExlbmd0aCgpICE9IDApKQorCQl7CisJCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UpKTsKKwkJCXBFdmVudC0+UmMoKSA9IEZBTFNFOworCQl9CisJCXJldHVybiBUUlVFOworCX0KKworCQorCUNGWF9XaWRlU3RyaW5nICZ3aWRlQ2hhbmdlID0gcEV2ZW50LT5DaGFuZ2UoKTsKKwlzdGQ6OndzdHJpbmcgd0NoYW5nZSh3aWRlQ2hhbmdlKTsKKwkKKwlpZiAod0NoYW5nZS5lbXB0eSgpKQorCQlyZXR1cm4gVFJVRTsKKyAgICBpbnQgaUluZGV4TWFzayA9IHBFdmVudC0+U2VsU3RhcnQoKTsKKwkvL2lJbmRleE1hc2srKzsKKwkKKwkKKwlpZiAod3N0clZhbHVlLmxlbmd0aCgpIC0gKHBFdmVudC0+U2VsRW5kKCktcEV2ZW50LT5TZWxTdGFydCgpKSArIHdDaGFuZ2UubGVuZ3RoKCkgPiAoRlhfRFdPUkQpd3N0ck1hc2suR2V0TGVuZ3RoKCkpCisJeworCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HKSk7CisJCXBFdmVudC0+UmMoKSA9IEZBTFNFOworCQlyZXR1cm4gVFJVRTsKKwl9CisJCisJCisJaWYgKGlJbmRleE1hc2sgPj0gd3N0ck1hc2suR2V0TGVuZ3RoKCkgJiYgKCF3Q2hhbmdlLmVtcHR5KCkpKQorCXsKKwkJQWxlcnQocENvbnRleHQsIEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1fVE9PTE9ORykpOworCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKKwkJcmV0dXJuIFRSVUU7CisJfQorCQorCWZvciAoc3RkOjp3c3RyaW5nOjppdGVyYXRvciBpdCA9IHdDaGFuZ2UuYmVnaW4oKTsgaXQgIT0gd0NoYW5nZS5lbmQoKTsgaXQrKykKKwl7CisJCWlmIChpSW5kZXhNYXNrID49IHdzdHJNYXNrLkdldExlbmd0aCgpKQorCQl7CisJCQlBbGVydChwQ29udGV4dCwgSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTV9UT09MT05HKSk7CisJCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJCXdjaGFyX3Qgd19NYXNrID0gd3N0ck1hc2tbaUluZGV4TWFza107CisJCWlmICghaXNSZXNlcnZlZE1hc2tDaGFyKHdfTWFzaykpCisJCXsKKwkJCS8vd0NoYW5nZS5pbnNlcnQoaXQsd19NYXNrKTsJCQkJCisJCQkqaXQgPSB3X01hc2s7CisJCX0KKwkJd2NoYXJfdCB3X0NoYW5nZSA9ICppdDsKKwkJCisgICAgICAgIGlmICghbWFza1NhdGlzZmllZCh3X0NoYW5nZSx3X01hc2spKQorCQl7CisJCQlwRXZlbnQtPlJjKCkgPSBGQUxTRTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJCWlJbmRleE1hc2srKzsKKwl9CisJCisJd2lkZUNoYW5nZSA9IHdDaGFuZ2UuY19zdHIoKTsJCisJCisJcmV0dXJuIFRSVUU7Cit9CisKKworLy9mdW5jdGlvbiBBRlNwZWNpYWxfS2V5c3Ryb2tlKHBzZikKK0ZYX0JPT0wgQ0pTX1B1YmxpY01ldGhvZHM6OkFGU3BlY2lhbF9LZXlzdHJva2UoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOworCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKKwl7CisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlzdGQ6OnN0cmluZyBjRm9ybWF0OworCWludCBpSW5kZXggPSAoaW50KXBhcmFtc1swXTsJCisKKwlpZighcEV2ZW50LT5tX3BWYWx1ZSkKKwkJcmV0dXJuIEZBTFNFOworCS8vQ0pTX1ZhbHVlIHZhbCA9IHBFdmVudC0+VmFsdWUoKTsKKwlDRlhfV2lkZVN0cmluZyYgdmFsID0gcEV2ZW50LT5WYWx1ZSgpOworCXN0ZDo6c3RyaW5nIHN0clNyYyA9IChGWF9MUENTVFIpQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHZhbCk7CisJc3RkOjp3c3RyaW5nIHdzdHJDaGFuZ2UocEV2ZW50LT5DaGFuZ2UoKSk7CisJCisJc3dpdGNoIChpSW5kZXgpIAorCXsKKwljYXNlIDA6ICAgICAgICAgICAgICAgICAgICAgICAgIAorCQljRm9ybWF0ID0gIjk5OTk5IjsKKwkJYnJlYWs7CisJY2FzZSAxOiAgICAgICAgICAgICAgICAgICAgICAgICAKKwkJLy9jRm9ybWF0ID0gIjk5OTk5LTk5OTkiOworCQljRm9ybWF0ID0gIjk5OTk5OTk5OSI7CisJCWJyZWFrOworCWNhc2UgMjogICAgICAgICAgICAgICAgICAgICAgICAgCisJCXsKKwkJCXN0ZDo6c3RyaW5nIE51bWJlclN0cjsKKwkJCXV0aWw6OnByaW50eCgiOTk5OTk5OTk5OSIsIHN0clNyYyxOdW1iZXJTdHIpOyAKKwkJCWlmIChzdHJTcmMubGVuZ3RoKCkgKyB3c3RyQ2hhbmdlLmxlbmd0aCgpID4gNyApCisJCQkJLy9jRm9ybWF0ID0gIig5OTkpIDk5OS05OTk5IjsKKwkJCQljRm9ybWF0ID0gIjk5OTk5OTk5OTkiOworCQkJZWxzZSAKKwkJCQkvL2NGb3JtYXQgPSAiOTk5LTk5OTkiOworCQkJCWNGb3JtYXQgPSAiOTk5OTk5OSI7CisJCQlicmVhazsKKwkJfQorCWNhc2UgMzoKKwkJLy9jRm9ybWF0ID0gIjk5OS05OS05OTk5IjsKKwkJY0Zvcm1hdCA9ICI5OTk5OTk5OTkiOworCQlicmVhazsKKwl9CisgICAgCisJQ0pTX1BhcmFtZXRlcnMgcGFyYW1zMjsKKwlDSlNfVmFsdWUgdk1hc2soaXNvbGF0ZSwgY0Zvcm1hdC5jX3N0cigpKTsKKwlwYXJhbXMyLnB1c2hfYmFjayh2TWFzayk7CisJCisgICAgcmV0dXJuIEFGU3BlY2lhbF9LZXlzdHJva2VFeChjYyxwYXJhbXMyLHZSZXQsc0Vycm9yKTsKK30KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZNZXJnZUNoYW5nZShPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50SGFuZGxlciA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50SGFuZGxlciAhPSBOVUxMKTsKKworCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCisJeworCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOworCQlyZXR1cm4gRkFMU0U7CisJfQorCisJQ0ZYX1dpZGVTdHJpbmcgc3dWYWx1ZTsKKwlpZiAocEV2ZW50SGFuZGxlci0+bV9wVmFsdWUgIT0gTlVMTCkKKwkJc3dWYWx1ZSA9IHBFdmVudEhhbmRsZXItPlZhbHVlKCk7CisKKwlpZiAocEV2ZW50SGFuZGxlci0+V2lsbENvbW1pdCgpKQorCXsKKwkJdlJldCA9IHN3VmFsdWU7CisJCXJldHVybiBUUlVFOworCX0KKworCUNGWF9XaWRlU3RyaW5nIHByZWZpeCxwb3N0Zml4OworCisJaWYgKHBFdmVudEhhbmRsZXItPlNlbFN0YXJ0KCkgPj0gMCkKKwkJcHJlZml4ID0gc3dWYWx1ZS5NaWQoMCxwRXZlbnRIYW5kbGVyLT5TZWxTdGFydCgpKTsKKwllbHNlCisJCXByZWZpeCA9IEwiIjsKKworCisJaWYgKHBFdmVudEhhbmRsZXItPlNlbEVuZCgpID49IDAgJiYgcEV2ZW50SGFuZGxlci0+U2VsRW5kKCkgPD0gc3dWYWx1ZS5HZXRMZW5ndGgoKSkKKwkJcG9zdGZpeCA9IHN3VmFsdWUuTWlkKHBFdmVudEhhbmRsZXItPlNlbEVuZCgpLCBzd1ZhbHVlLkdldExlbmd0aCgpIC0gcEV2ZW50SGFuZGxlci0+U2VsRW5kKCkpOworCWVsc2UgcG9zdGZpeCA9IEwiIjsKKworCXZSZXQgPSBwcmVmaXggKyBwRXZlbnRIYW5kbGVyLT5DaGFuZ2UoKSArIHBvc3RmaXg7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZQYXJzZURhdGVFeChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwlpZiAocGFyYW1zLnNpemUoKSAhPSAyKQorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCUNGWF9XaWRlU3RyaW5nIHNWYWx1ZSA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCUNGWF9XaWRlU3RyaW5nIHNGb3JtYXQgPSBwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCUZYX0JPT0wgYldyb25nRm9ybWF0ID0gRkFMU0U7CisJZG91YmxlIGREYXRlID0gTWFrZVJlZ3VsYXJEYXRlKHNWYWx1ZSxzRm9ybWF0LGJXcm9uZ0Zvcm1hdCk7CisKKwlpZiAoSlNfUG9ydElzTmFuKGREYXRlKSkKKwl7CisJCUNGWF9XaWRlU3RyaW5nIHN3TXNnOworCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJTRURBVEUpLCAoRlhfTFBDV1NUUilzRm9ybWF0KTsKKwkJQWxlcnQoKENKU19Db250ZXh0ICopY2MsIHN3TXNnKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKwkKKwl2UmV0ID0gZERhdGU7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZTaW1wbGUoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKHBhcmFtcy5zaXplKCkgIT0gMykKKwl7CisJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOworCQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCXZSZXQgPSAoZG91YmxlKUFGX1NpbXBsZShwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSwgKGRvdWJsZSlwYXJhbXNbMV0sIChkb3VibGUpcGFyYW1zWzJdKTsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZNYWtlTnVtYmVyKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCisJeworCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9CisgICAgdlJldCA9IFBhcnNlU3RyaW5nVG9OdW1iZXIocGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRlNpbXBsZV9DYWxjdWxhdGUoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSA6OkdldElzb2xhdGUoY2MpOworCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJaWYgKHBhcmFtcy5zaXplKCkgIT0gMikKKwl7CisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlDSlNfVmFsdWUgcGFyYW1zMSA9IHBhcmFtc1sxXTsKKworCWlmICghcGFyYW1zMS5Jc0FycmF5T2JqZWN0KCkgJiYgcGFyYW1zMS5HZXRUeXBlKCkgIT0gVlRfc3RyaW5nKQorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKwkKKwlDUERGU0RLX0RvY3VtZW50KiBwUmVhZGVyRG9jID0gcENvbnRleHQtPkdldFJlYWRlckRvY3VtZW50KCk7CisgICAgQVNTRVJUKHBSZWFkZXJEb2MgIT0gTlVMTCk7CisKKwlDUERGU0RLX0ludGVyRm9ybSogcFJlYWRlckludGVyRm9ybSA9IHBSZWFkZXJEb2MtPkdldEludGVyRm9ybSgpOworCUFTU0VSVChwUmVhZGVySW50ZXJGb3JtICE9IE5VTEwpOworCisJQ1BERl9JbnRlckZvcm0qIHBJbnRlckZvcm0gPSBwUmVhZGVySW50ZXJGb3JtLT5HZXRJbnRlckZvcm0oKTsKKwlBU1NFUlQocEludGVyRm9ybSAhPSBOVUxMKTsKKworCWRvdWJsZSBkVmFsdWU7CisJQ0ZYX1dpZGVTdHJpbmcgc0Z1bmN0aW9uID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJaWYgKHdjc2NtcChzRnVuY3Rpb24sIEwiUFJEIikgPT0gMCkKKyAgICAJZFZhbHVlID0gMS4wOworCWVsc2UKKwkJZFZhbHVlID0gMC4wOworCisJQ0pTX0FycmF5IEZpZWxkTmFtZUFycmF5ID0gQUZfTWFrZUFycmF5RnJvbUxpc3QoaXNvbGF0ZSxwYXJhbXMxKTsKKworCWludCBuRmllbGRzQ291bnQgPSAwOworCisJZm9yIChpbnQgaT0wLGlzej1GaWVsZE5hbWVBcnJheS5HZXRMZW5ndGgoKTsgaTxpc3o7IGkrKykKKwl7CisJCUNKU19WYWx1ZSBqc1ZhbHVlKGlzb2xhdGUpOworCQlGaWVsZE5hbWVBcnJheS5HZXRFbGVtZW50KGksanNWYWx1ZSk7CisgICAgICAgIENGWF9XaWRlU3RyaW5nIHdzRmllbGROYW1lID0ganNWYWx1ZS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisgICAgICAgIGZvciAoaW50IGo9MCxqc3o9cEludGVyRm9ybS0+Q291bnRGaWVsZHMod3NGaWVsZE5hbWUpOyBqPGpzejsgaisrKQorCQl7CisJCQlpZiAoQ1BERl9Gb3JtRmllbGQqIHBGb3JtRmllbGQgPSBwSW50ZXJGb3JtLT5HZXRGaWVsZChqLCB3c0ZpZWxkTmFtZSkpCisJCQl7CisJCQkJZG91YmxlIGRUZW1wID0gMC4wOworCisJCQkJc3dpdGNoIChwRm9ybUZpZWxkLT5HZXRGaWVsZFR5cGUoKSkKKwkJCQl7CisJCQkJY2FzZSBGSUVMRFRZUEVfVEVYVEZJRUxEOgorCQkJCWNhc2UgRklFTERUWVBFX0NPTUJPQk9YOgorCQkJCQl7CisJCQkJCQlkVGVtcCA9IFBhcnNlU3RyaW5nVG9OdW1iZXIocEZvcm1GaWVsZC0+R2V0VmFsdWUoKSk7CisJCQkJCQlicmVhazsKKwkJCQkJfQorCQkJCWNhc2UgRklFTERUWVBFX1BVU0hCVVRUT046CisJCQkJCXsKKwkJCQkJCWRUZW1wID0gMC4wOworCQkJCQkJYnJlYWs7CisJCQkJCX0KKwkJCQljYXNlIEZJRUxEVFlQRV9DSEVDS0JPWDoKKwkJCQljYXNlIEZJRUxEVFlQRV9SQURJT0JVVFRPTjoKKwkJCQkJeworCQkJCQkJZFRlbXAgPSAwLjA7CisJCQkJCQlmb3IgKGludCBjPTAsY3N6PXBGb3JtRmllbGQtPkNvdW50Q29udHJvbHMoKTsgYzxjc3o7IGMrKykKKwkJCQkJCXsKKwkJCQkJCQlpZiAoQ1BERl9Gb3JtQ29udHJvbCogcEZvcm1DdHJsID0gcEZvcm1GaWVsZC0+R2V0Q29udHJvbChjKSkKKwkJCQkJCQl7CisJCQkJCQkJCWlmIChwRm9ybUN0cmwtPklzQ2hlY2tlZCgpKQorCQkJCQkJCQl7CisJCQkJCQkJCQlkVGVtcCArPSBQYXJzZVN0cmluZ1RvTnVtYmVyKHBGb3JtQ3RybC0+R2V0RXhwb3J0VmFsdWUoKSk7CisJCQkJCQkJCQlicmVhazsKKwkJCQkJCQkJfQorCQkJCQkJCQllbHNlCisJCQkJCQkJCQljb250aW51ZTsKKwkJCQkJCQl9CisJCQkJCQl9CisJCQkJCQlicmVhazsKKwkJCQkJfQorCQkJCWNhc2UgRklFTERUWVBFX0xJU1RCT1g6CisJCQkJCXsKKwkJCQkJCWRUZW1wID0gMC4wOworCQkJCQkJaWYgKHBGb3JtRmllbGQtPkNvdW50U2VsZWN0ZWRJdGVtcygpID4gMSkKKwkJCQkJCQlicmVhazsKKwkJCQkJCWVsc2UKKwkJCQkJCXsKKwkJCQkJCQlkVGVtcCA9IFBhcnNlU3RyaW5nVG9OdW1iZXIocEZvcm1GaWVsZC0+R2V0VmFsdWUoKSk7CisJCQkJCQkJYnJlYWs7CisJCQkJCQl9CisJCQkJCX0KKwkJCQlkZWZhdWx0OgorCQkJCQlicmVhazsKKwkJCQl9CisKKwkJCQlpZiAoaSA9PSAwICYmIGogPT0gMCAmJiAod2NzY21wKHNGdW5jdGlvbixMIk1JTiIpID09IDAgfHwgd2NzY21wKHNGdW5jdGlvbiwgTCJNQVgiKSA9PSAwKSkKKwkJCQkJZFZhbHVlID0gZFRlbXA7CisKKwkJCQlkVmFsdWUgPSBBRl9TaW1wbGUoc0Z1bmN0aW9uLCBkVmFsdWUsIGRUZW1wKTsKKworCQkJCW5GaWVsZHNDb3VudCsrOworCQkJfQorCQl9CisJfQorCisJaWYgKHdjc2NtcChzRnVuY3Rpb24sIEwiQVZHIikgPT0gMCAmJiBuRmllbGRzQ291bnQgPiAwKQorCQlkVmFsdWUgLz0gbkZpZWxkc0NvdW50OworCisJZFZhbHVlID0gKGRvdWJsZSlmbG9vcihkVmFsdWUgKiBGWFNZU19wb3coKGRvdWJsZSkxMCwoZG91YmxlKTYpICsgMC40OSkgLyBGWFNZU19wb3coKGRvdWJsZSkxMCwoZG91YmxlKTYpOworCUNKU19WYWx1ZSBqc1ZhbHVlKGlzb2xhdGUsZFZhbHVlKTsKKwlpZigoQ0pTX0V2ZW50SGFuZGxlciopcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpLT5tX3BWYWx1ZSkKKwkJKChDSlNfRXZlbnRIYW5kbGVyKilwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCkpLT5WYWx1ZSgpID0ganNWYWx1ZTsKKworCXJldHVybiBUUlVFOworfQorCisvKiBUaGlzIGZ1bmN0aW9uIHZhbGlkYXRlcyB0aGUgY3VycmVudCBldmVudCB0byBlbnN1cmUgdGhhdCBpdHMgdmFsdWUgaXMgCisqKiB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZS4gKi8KKworRlhfQk9PTCBDSlNfUHVibGljTWV0aG9kczo6QUZSYW5nZV9WYWxpZGF0ZShPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOworCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CisKKwlpZiAocGFyYW1zLnNpemUoKSAhPSA0KSAKKwl7CisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlpZighcEV2ZW50LT5tX3BWYWx1ZSkKKwkJcmV0dXJuIEZBTFNFOworCWlmIChwRXZlbnQtPlZhbHVlKCkuSXNFbXB0eSgpICkKKwkJcmV0dXJuIFRSVUU7CisJZG91YmxlIGRFZW50VmFsdWUgPSBhdG9mKENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShwRXZlbnQtPlZhbHVlKCkpKTsKKwlGWF9CT09MIGJHcmVhdGVyVGhhbiwgYkxlc3NUaGFuOworCWRvdWJsZSAgZEdyZWF0ZXJUaGFuLCBkTGVzc1RoYW47CisgICAgYkdyZWF0ZXJUaGFuID0gKEZYX0JPT0wpcGFyYW1zWzBdOworCUNGWF9XaWRlU3RyaW5nIHN3TXNnOworCWRHcmVhdGVyVGhhbiA9IChkb3VibGUpcGFyYW1zWzFdOworCWJMZXNzVGhhbiA9IChGWF9CT09MKXBhcmFtc1syXTsKKwlkTGVzc1RoYW4gPSAoZG91YmxlKXBhcmFtc1szXTsKKworCWlmIChiR3JlYXRlclRoYW4gJiYgYkxlc3NUaGFuKQorCXsKKwkJaWYgKGRFZW50VmFsdWUgPCBkR3JlYXRlclRoYW4gfHwgZEVlbnRWYWx1ZSA+IGRMZXNzVGhhbikKKwkJCXN3TXNnLkZvcm1hdChKU0dldFN0cmluZ0Zyb21JRChwQ29udGV4dCwgSURTX1NUUklOR19KU1JBTkdFMSksKEZYX0xQQ1dTVFIpcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCksIChGWF9MUENXU1RSKXBhcmFtc1szXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsKKwl9CisJZWxzZSBpZiAoYkdyZWF0ZXJUaGFuKQorCXsKKwkJaWYgKGRFZW50VmFsdWUgPCBkR3JlYXRlclRoYW4pCisJCQlzd01zZy5Gb3JtYXQoSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNSQU5HRTIpLCAoRlhfTFBDV1NUUilwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7CisJfQorCWVsc2UgaWYgKGJMZXNzVGhhbikKKwl7CisJCWlmIChkRWVudFZhbHVlID4gZExlc3NUaGFuKQorCQkJc3dNc2cuRm9ybWF0KEpTR2V0U3RyaW5nRnJvbUlEKHBDb250ZXh0LCBJRFNfU1RSSU5HX0pTUkFOR0UzKSwgKEZYX0xQQ1dTVFIpcGFyYW1zWzNdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOworCX0KKworCWlmICghc3dNc2cuSXNFbXB0eSgpKQorCXsKKwkJQWxlcnQocENvbnRleHQsIHN3TXNnKTsKKwkJcEV2ZW50LT5SYygpID0gRkFMU0U7CisJfQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENKU19QdWJsaWNNZXRob2RzOjpBRkV4dHJhY3ROdW1zKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gOjpHZXRJc29sYXRlKGNjKTsKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKworCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpIAorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQocENvbnRleHQsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCUNKU19BcnJheSBudW1zKGlzb2xhdGUpOworCisJQ0ZYX1dpZGVTdHJpbmcgc3RyID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJQ0ZYX1dpZGVTdHJpbmcgc1BhcnQ7CisKKwlpZiAoc3RyLkdldEF0KDApID09IEwnLicgfHwgc3RyLkdldEF0KDApID09IEwnLCcpCisJCXN0ciA9IEwiMCIgKyBzdHI7CisKKwlpbnQgbkluZGV4ID0gMDsKKwlmb3IgKGludCBpPTAsIHN6PXN0ci5HZXRMZW5ndGgoKTsgaTxzejsgaSsrKQorCXsKKwkJRlhfV0NIQVIgd2MgPSBzdHIuR2V0QXQoaSk7CisJCWlmIChJc0RpZ2l0KCh3Y2hhcl90KXdjKSkKKwkJeworCQkJc1BhcnQgKz0gd2M7CisJCX0KKwkJZWxzZQorCQl7CisJCQlpZiAoc1BhcnQuR2V0TGVuZ3RoKCkgPiAwKQorCQkJeworCQkJCW51bXMuU2V0RWxlbWVudChuSW5kZXgsQ0pTX1ZhbHVlKGlzb2xhdGUsKEZYX0xQQ1dTVFIpc1BhcnQpKTsKKwkJCQlzUGFydCA9IEwiIjsKKwkJCQluSW5kZXggKys7CisJCQl9CisJCX0KKwl9CisKKwlpZiAoc1BhcnQuR2V0TGVuZ3RoKCkgPiAwKQorCXsKKwkJbnVtcy5TZXRFbGVtZW50KG5JbmRleCxDSlNfVmFsdWUoaXNvbGF0ZSwoRlhfTFBDV1NUUilzUGFydCkpOwkKKwl9CisKKwlpZiAobnVtcy5HZXRMZW5ndGgoKSA+IDApCisJCXZSZXQgPSBudW1zOworCWVsc2UKKwkJdlJldC5TZXROdWxsKCk7CisKKwlyZXR1cm4gVFJVRTsKK30KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvYXBwLmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvYXBwLmNwcAppbmRleCBjMWVmNzZjLi5hM2U2MWMwIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L2FwcC5jcHAKKysrIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9hcHAuY3BwCkBAIC0xLDExMzQgKzEsMTEzNCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9hcHAuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvcmVzb3VyY2UuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmgiDQotDQotDQotc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0JQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCXJldHVybiBwUnVudGltZS0+R2V0SXNvbGF0ZSgpOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFRpbWVyT2JqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1CRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX1RpbWVyT2JqKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19UaW1lck9iaikNCi1FTkRfSlNfU1RBVElDX1BST1AoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19NRVRIT0QoQ0pTX1RpbWVyT2JqKQ0KLUVORF9KU19TVEFUSUNfTUVUSE9EKCkNCi0NCi1JTVBMRU1FTlRfSlNfQ0xBU1MoQ0pTX1RpbWVyT2JqLCBUaW1lck9iaikNCi0NCi1UaW1lck9iajo6VGltZXJPYmooQ0pTX09iamVjdCogcEpTT2JqZWN0KQ0KLTogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCksDQotbV9wVGltZXIoTlVMTCkNCi17DQotCQ0KLX0NCi0NCi1UaW1lck9iajo6flRpbWVyT2JqKCkNCi17DQotfQ0KLQ0KLXZvaWQgVGltZXJPYmo6OlNldFRpbWVyKENKU19UaW1lciogcFRpbWVyKQ0KLXsNCi0JbV9wVGltZXIgPSBwVGltZXI7DQotfQ0KLQ0KLUNKU19UaW1lciogVGltZXJPYmo6OkdldFRpbWVyKCkgY29uc3QNCi17DQotCXJldHVybiBtX3BUaW1lcjsNCi19DQotDQotI2RlZmluZSBKU19TVFJfVklFV0VSVFlQRV9SRUFERVIJCUwiUmVhZGVyIg0KLSNkZWZpbmUgSlNfU1RSX1ZJRVdFUlRZUEVfU1RBTkRBUkQJCUwiRXhjaGFuZ2UiDQotI2RlZmluZSBKU19TVFJfVklFV0VSVkFSSUFUSU9OCQkJTCJGdWxsIg0KLSNkZWZpbmUgSlNfU1RSX1BMQVRGT1JNCQkJCQlMIldJTiINCi0jZGVmaW5lIEpTX1NUUl9MQU5HVUFOR0UJCQkJTCJFTlUiDQotI2RlZmluZSBKU19TVFJfVklFV0VSVkVSU0lPTgkJCTgNCi0jZGVmaW5lIEpTX05VTV9GT1JNU1ZFUlNJT04JCQkJNw0KLQ0KLSNkZWZpbmUgSlNfRklMRVBBVEhfTUFYTEVOCQkJCTIwMDANCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGFwcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19BcHApDQotRU5EX0pTX1NUQVRJQ19DT05TVCgpDQotDQotQkVHSU5fSlNfU1RBVElDX1BST1AoQ0pTX0FwcCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoYWN0aXZlRG9jcykNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoY2FsY3VsYXRlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShmb3Jtc1ZlcnNpb24pDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGZzKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShmdWxsc2NyZWVuKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShsYW5ndWFnZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkobWVkaWEpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHBsYXRmb3JtKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShydW50aW1lSGlnaGxpZ2h0KQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWSh2aWV3ZXJUeXBlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWSh2aWV3ZXJWYXJpYXRpb24pDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHZpZXdlclZlcnNpb24pCQ0KLUVORF9KU19TVEFUSUNfUFJPUCgpDQotDQotQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfQXBwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGFsZXJ0LCA2KQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGJlZXAsIDEpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYnJvd3NlRm9yRG9jLCAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGNsZWFySW50ZXJ2YWwsIDEpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoY2xlYXJUaW1lT3V0LCAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGV4ZWNEaWFsb2csIDMpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZXhlY01lbnVJdGVtLCAgMSkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShmaW5kQ29tcG9uZW50LCAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdvQmFjaywgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShnb0ZvcndhcmQsIDApDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkobGF1bmNoVVJMLCAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKG1haWxNc2csIDApCQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKG5ld0ZERiwgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShuZXdEb2MsIDApDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkob3BlbkRvYywgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShvcGVuRkRGLCA1KQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHBvcFVwTWVudUV4LCAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHBvcFVwTWVudSwgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShyZXNwb25zZSwgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShzZXRJbnRlcnZhbCwgMikNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShzZXRUaW1lT3V0LCAyKQ0KLUVORF9KU19TVEFUSUNfTUVUSE9EKCkNCi0NCi1JTVBMRU1FTlRfSlNfQ0xBU1MoQ0pTX0FwcCxhcHApDQotDQotYXBwOjphcHAoQ0pTX09iamVjdCAqIHBKU09iamVjdCkgOiBDSlNfRW1iZWRPYmoocEpTT2JqZWN0KSAsDQotCW1fYkNhbGN1bGF0ZSh0cnVlKSwNCi0JbV9wUnVudGltZShOVUxMKSwNCi0JbV9iUnVudGltZUhpZ2hMaWdodChmYWxzZSkNCi0vLwltX3BNZW51SGVhZChOVUxMKQ0KLXsNCi19DQotDQotYXBwOjp+YXBwKHZvaWQpDQotew0KLQlmb3IgKGludCBpPTAsc3o9bV9hVGltZXIuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQlkZWxldGUgbV9hVGltZXJbaV07DQotDQotCW1fYVRpbWVyLlJlbW92ZUFsbCgpOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6YWN0aXZlRG9jcyhPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0NCi0JCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQkJDQotCQlDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwID0gcENvbnRleHQtPkdldFJlYWRlckFwcCgpOw0KLQkJQVNTRVJUKHBBcHAgIT0gTlVMTCk7DQotDQotCQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotCQkNCi0JCUNQREZTREtfRG9jdW1lbnQqIHBDdXJEb2MgPSBwQ29udGV4dC0+R2V0UmVhZGVyRG9jdW1lbnQoKTsNCi0JCQ0KLQkJQ0pTX0FycmF5IGFEb2NzKHBSdW50aW1lLT5HZXRJc29sYXRlKCkpOw0KLS8vCQlpbnQgaU51bURvY3MgPSBwQXBwLT5Db3VudERvY3VtZW50cygpOw0KLQkJDQotLy8gCQlmb3IoaW50IGlJbmRleCA9IDA7IGlJbmRleDxpTnVtRG9jczsgaUluZGV4KyspDQotLy8gCQl7DQotCQkJQ1BERlNES19Eb2N1bWVudCogcERvYyA9IHBBcHAtPkdldEN1cnJlbnREb2MoKTsNCi0JCQlpZiAocERvYykNCi0JCQl7DQotCQkJCUNKU19Eb2N1bWVudCAqIHBKU0RvY3VtZW50ID0gTlVMTDsNCi0JCQkJDQotCQkJCWlmIChwRG9jID09IHBDdXJEb2MpDQotCQkJCXsNCi0JCQkJCUpTRlhPYmplY3QgcE9iaiA9IEpTX0dldFRoaXNPYmooKnBSdW50aW1lKTsNCi0JCQkJCQ0KLQkJCQkJaWYgKEpTX0dldE9iakRlZm5JRChwT2JqKSA9PSBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIkRvY3VtZW50IikpDQotCQkJCQl7DQotCQkJCQkJcEpTRG9jdW1lbnQgPSAoQ0pTX0RvY3VtZW50KilKU19HZXRQcml2YXRlKHBSdW50aW1lLT5HZXRJc29sYXRlKCkscE9iaik7DQotCQkJCQl9DQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQl7DQotCQkJCQlKU0ZYT2JqZWN0IHBPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBwQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSxMIkRvY3VtZW50IikpOw0KLQkJCQkJcEpTRG9jdW1lbnQgPSAoQ0pTX0RvY3VtZW50KilKU19HZXRQcml2YXRlKHBSdW50aW1lLT5HZXRJc29sYXRlKCkscE9iaik7DQotCQkJCQlBU1NFUlQocEpTRG9jdW1lbnQgIT0gTlVMTCk7DQotCQkJCQkNCi0JCQkJCQ0KLQkJCQkJLy8JCQlwRG9jdW1lbnQtPkF0dGFjaERvYyhwRG9jKTsNCi0JCQkJfQ0KLQkJCQkNCi0JCQkJYURvY3MuU2V0RWxlbWVudCgwLENKU19WYWx1ZShwUnVudGltZS0+R2V0SXNvbGF0ZSgpLHBKU0RvY3VtZW50KSk7DQotCQkJfQ0KLQkvLwkJfQ0KLQkJDQotCQlpZiAoYURvY3MuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCXZwIDw8IGFEb2NzOw0KLQkJZWxzZQ0KLQkJCXZwLlNldE51bGwoKTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OmNhbGN1bGF0ZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCWJvb2wgYlZQOw0KLQkJdnAgPj4gYlZQOw0KLQkJbV9iQ2FsY3VsYXRlID0gKEZYX0JPT0wpYlZQOw0KLQ0KLQkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JCQ0KLQkJQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBDb250ZXh0LT5HZXRSZWFkZXJBcHAoKTsNCi0JCUFTU0VSVChwQXBwICE9IE5VTEwpOw0KLQkJDQotCQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCQlDSlNfQXJyYXkgYURvY3MocFJ1bnRpbWUtPkdldElzb2xhdGUoKSk7DQotLy8gCQlpbnQgaU51bURvY3MgPSBwQXBwLT5Db3VudERvY3VtZW50cygpOw0KLS8vIAkJDQotLy8gCQlmb3IgKGludCBpSW5kZXggPSAwO2lJbmRleCA8IGlOdW1Eb2NzOyBpSW5kZXgrKykNCi0vLyAJCXsNCi0JCQlpZiAoQ1BERlNES19Eb2N1bWVudCogcERvYyA9IHBBcHAtPkdldEN1cnJlbnREb2MoKSkNCi0JCQl7DQotCQkJCUNQREZTREtfSW50ZXJGb3JtKiBwSW50ZXJGb3JtID0gKENQREZTREtfSW50ZXJGb3JtKilwRG9jLT5HZXRJbnRlckZvcm0oKTsNCi0JCQkJQVNTRVJUKHBJbnRlckZvcm0gIT0gTlVMTCk7DQotCQkJCXBJbnRlckZvcm0tPkVuYWJsZUNhbGN1bGF0ZSgoRlhfQk9PTCltX2JDYWxjdWxhdGUpOw0KLQkJCX0JCQkNCi0vLwkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJdnAgPDwgKGJvb2wpbV9iQ2FsY3VsYXRlOw0KLQl9DQotCQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OmZvcm1zVmVyc2lvbihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IEpTX05VTV9GT1JNU1ZFUlNJT047DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6dmlld2VyVHlwZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQ0KLQ0KLQkNCi0JDQotCQ0KLQ0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0vLyAJCWlmIChwQXBwLT5HZXRBcHBOYW1lKCkgPT0gUEhBTlRPTSkNCi0vLyAJCQl2cCA8PCBKU19TVFJfVklFV0VSVFlQRV9TVEFOREFSRDsNCi0vLyAJCWVsc2UNCi0vLyAJCQl2cCA8PCBKU19TVFJfVklFV0VSVFlQRV9SRUFERVI7DQotCQl2cCA8PCBMInVua25vd24iOw0KLQ0KLQkJLy92cCA8PCBwQXBwLT5HZXRBcHBUaXRsZSgpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OnZpZXdlclZhcmlhdGlvbihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IEpTX1NUUl9WSUVXRVJWQVJJQVRJT047DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQkNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6dmlld2VyVmVyc2lvbihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAodnAuSXNHZXR0aW5nKCkpDQotCXsNCi0JCXZwIDw8IEpTX1NUUl9WSUVXRVJWRVJTSU9OOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OnBsYXRmb3JtKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJdnAgPDwgSlNfU1RSX1BMQVRGT1JNOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBhcHA6Omxhbmd1YWdlKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICh2cC5Jc0dldHRpbmcoKSkNCi0Jew0KLQkJdnAgPDwgSlNfU1RSX0xBTkdVQU5HRTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLS8vY3JlYXRlcyBhIG5ldyBmZGYgb2JqZWN0IHRoYXQgY29udGFpbnMgbm8gZGF0YQ0KLS8vY29tbWVudDogbmVlZCByZWFkZXIgc3VwcG9ydA0KLS8vbm90ZToNCi0vL0NGREZfRG9jdW1lbnQgKiBDUERGRG9jX0Vudmlyb25tZW50OjpOZXdGREYoKTsNCi1GWF9CT09MIGFwcDo6bmV3RkRGKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLS8vb3BlbnMgYSBzcGVjaWZpZWQgcGRmIGRvY3VtZW50IGFuZCByZXR1cm5zIGl0cyBkb2N1bWVudCBvYmplY3QNCi0vL2NvbW1lbnQ6bmVlZCByZWFkZXIgc3VwcG9ydA0KLS8vbm90ZTogYXMgZGVmaW5lZCBpbiBqcyByZWZlcmVuY2UsIHRoZSBwcm90byBvZiB0aGlzIGZ1bmN0aW9uJ3MgZm91cnRoIHBhcm1ldGVycywgaG93IG9sZCBhbiBmZGYgZG9jdW1lbnQgd2hpbGUgZG8gbm90IHNob3cgaXQuDQotLy9DRkRGX0RvY3VtZW50ICogQ1BERkRvY19FbnZpcm9ubWVudDo6T3BlbkZERihzdHJpbmcgc3RyUGF0aCxib29sIGJVc2VyQ29udik7DQotDQotRlhfQk9PTCBhcHA6Om9wZW5GREYoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OmFsZXJ0KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JaW50IGlTaXplID0gcGFyYW1zLnNpemUoKTsNCi0JaWYgKGlTaXplIDwgMSkNCi0JCXJldHVybiBGQUxTRTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc3dNc2cgPSBMIiI7DQotCUNGWF9XaWRlU3RyaW5nIHN3VGl0bGUgPSBMIiI7DQotCWludCBpSWNvbiA9IDA7DQotCWludCBpVHlwZSA9IDA7DQotDQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7DQotDQotCWlmIChpU2l6ZSA9PSAxKQ0KLQl7DQotCQlpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9vYmplY3QpDQotCQl7DQotCQkJSlNPYmplY3QgcE9iaiA9IHBhcmFtc1swXTsNCi0JCQl7DQotCQkJCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUsIHBPYmosIEwiY01zZyIpOw0KLQkJCQlzd01zZyA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxWVF91bmtub3duKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaixMImNUaXRsZSIpOw0KLQkJCQlzd1RpdGxlID0gQ0pTX1ZhbHVlKGlzb2xhdGUsIHBWYWx1ZSxWVF91bmtub3duKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaixMIm5JY29uIik7DQotCQkJCWlJY29uID0gKGludClDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsVlRfdW5rbm93bik7DQotDQotCQkJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLEwiblR5cGUiKTsNCi0JCQkJaVR5cGUgPSAoaW50KUNKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxWVF91bmtub3duKTsNCi0JCQl9DQotDQotCQkJaWYgKHN3TXNnID09IEwiIikNCi0JCQl7DQotCQkJCUNKU19BcnJheSBjYXJyYXkoaXNvbGF0ZSk7DQotCQkJCWlmIChwYXJhbXNbMF0uQ29udmVydFRvQXJyYXkoY2FycmF5KSkNCi0JCQkJew0KLQkJCQkJaW50IGlMZW50aCA9IGNhcnJheS5HZXRMZW5ndGgoKTsNCi0JCQkJCUNKU19WYWx1ZSogcFZhbHVlID0gbmV3IENKU19WYWx1ZShpc29sYXRlKTsNCi0vLwkJCQkJaWYgKGlMZW50aCA9PSAxKQ0KLS8vCQkJCQkJcFZhbHVlID0gbmV3IENKU19WYWx1ZShpc29sYXRlKTsNCi0vLyAJCQkJCWVsc2UgaWYgKGlMZW50aCA+IDEpDQotLy8gCQkJCQkJcFZhbHVlID0gbmV3IENKU19WYWx1ZVtpTGVudGhdOw0KLQ0KLQkJCQkJZm9yKGludCBpID0gMDsgaSA8IGlMZW50aDsgaSsrKQ0KLQkJCQkJew0KLQkJCQkJCWNhcnJheS5HZXRFbGVtZW50KGksICpwVmFsdWUpOw0KLQkJCQkJCXN3TXNnICs9ICgqcFZhbHVlKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQkJCQkJCWlmIChpIDwgaUxlbnRoIC0gMSkNCi0JCQkJCQkJc3dNc2cgKz0gTCIsICAiOw0KLQkJCQkJfQ0KLQ0KLQkJCQkJaWYocFZhbHVlKSBkZWxldGUgcFZhbHVlOw0KLS8vIAkJCQkJaWYgKChpTGVudGggPiAxKSAmJiBwVmFsdWUpDQotLy8gCQkJCQl7DQotLy8gCQkJCQkJZGVsZXRlW11wVmFsdWU7DQotLy8gCQkJCQkJcFZhbHVlID0gTlVMTDsNCi0vLyAJCQkJCX0NCi0vLyAJCQkJCWVsc2UgaWYgKChpTGVudGggPT0gMSkgJiYgcFZhbHVlKQ0KLS8vIAkJCQkJew0KLS8vIAkJCQkJCWRlbGV0ZSBwVmFsdWU7DQotLy8gCQkJCQkJcFZhbHVlID0gTlVMTDsNCi0vLyAJCQkJCX0NCi0JCQkJfQ0KLQkJCX0NCi0NCi0JCQlpZiAoc3dUaXRsZSA9PSBMIiIpDQotCQkJCXN3VGl0bGUgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTQUxFUlQpOw0KLQkJfQ0KLQkJZWxzZSBpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9ib29sZWFuKQ0KLQkJew0KLQkJCUZYX0JPT0wgYkdldCA9IChGWF9CT09MKXBhcmFtc1swXTsNCi0JCQlpZiAoYkdldCkNCi0JCQkJc3dNc2cgPSBMInRydWUiOw0KLQkJCWVsc2UNCi0JCQkJc3dNc2cgPSBMImZhbHNlIjsNCi0NCi0JCQlzd1RpdGxlID0gSlNHZXRTdHJpbmdGcm9tSUQoKENKU19Db250ZXh0KiljYywgSURTX1NUUklOR19KU0FMRVJUKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlzd01zZyA9IHBhcmFtc1swXTsNCi0JCQlzd1RpdGxlID0gSlNHZXRTdHJpbmdGcm9tSUQoKENKU19Db250ZXh0KiljYywgSURTX1NUUklOR19KU0FMRVJUKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChwYXJhbXNbMF0uR2V0VHlwZSgpID09IFZUX2Jvb2xlYW4pDQotCQl7DQotCQkJRlhfQk9PTCBiR2V0ID0gKEZYX0JPT0wpcGFyYW1zWzBdOw0KLQkJCWlmIChiR2V0KQ0KLQkJCQlzd01zZyA9IEwidHJ1ZSI7DQotCQkJZWxzZQ0KLQkJCQlzd01zZyA9IEwiZmFsc2UiOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCXN3TXNnID0gcGFyYW1zWzBdOw0KLQkJfQ0KLQkJc3dUaXRsZSA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNBTEVSVCk7DQotCQkNCi0JCWZvcihpbnQgaSA9IDE7aTxpU2l6ZTtpKyspDQotCQl7DQotCQkJaWYgKGkgPT0gMSkNCi0JCQkJaUljb24gPSBpbnQocGFyYW1zW2ldKTsNCi0JCQlpZiAoaSA9PSAyKQ0KLQkJCQlpVHlwZSA9IGludChwYXJhbXNbaV0pOw0KLQkJCWlmIChpID09IDMpDQotCQkJCXN3VGl0bGUgPSBwYXJhbXNbaV07CQkJDQotCQl9DQotCX0NCi0NCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0JcFJ1bnRpbWUtPkJlZ2luQmxvY2soKTsNCi0JdlJldCA9IE1zZ0JveChwUnVudGltZS0+R2V0UmVhZGVyQXBwKCksIEpTR2V0UGFnZVZpZXcoY2MpLHN3TXNnLHN3VGl0bGUsaVR5cGUsaUljb24pOw0KLQlwUnVudGltZS0+RW5kQmxvY2soKTsNCi0JDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0NCi1GWF9CT09MIGFwcDo6YmVlcChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCWlmIChwYXJhbXMuc2l6ZSgpID09IDEpDQotCXsNCi0JCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCQlDUERGRG9jX0Vudmlyb25tZW50ICogcEVudiA9IHBSdW50aW1lLT5HZXRSZWFkZXJBcHAoKTsNCi0JCXBFbnYtPkpTX2FwcEJlZXAoKGludClwYXJhbXNbMF0pOw0KLQ0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi19DQotDQotRlhfQk9PTCBhcHA6OmZpbmRDb21wb25lbnQoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OnBvcFVwTWVudUV4KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsJDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OmZzKE9CSl9QUk9QX1BBUkFNUykNCi17DQotI2lmZGVmIEZPWElUX0NIUk9NRV9CVUlMRA0KLQlyZXR1cm4gRkFMU0U7DQotI2Vsc2UNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0NCi0JaWYgKHZwLklzR2V0dGluZygpKQ0KLQl7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotI2VuZGlmDQotfQ0KLQ0KLUZYX0JPT0wgYXBwOjpzZXRJbnRlcnZhbChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCWlmIChwYXJhbXMuc2l6ZSgpID4gMiB8fCBwYXJhbXMuc2l6ZSgpID09IDApIA0KLQl7DQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCQ0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsNCi0JQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzY3JpcHQgPSBwYXJhbXMuc2l6ZSgpID4gMCA/ICAoRlhfTFBDV1NUUikocGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpIDogKEZYX0xQQ1dTVFIpTCIiOw0KLQlpZiAoc2NyaXB0LklzRW1wdHkoKSkgDQotCXsNCi0JCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JRlhfRFdPUkQgZHdJbnRlcnZhbCA9IHBhcmFtcy5zaXplKCkgPiAxID8gKGludClwYXJhbXNbMV0gOiAxMDAwOw0KLQkNCi0JQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBSdW50aW1lLT5HZXRSZWFkZXJBcHAoKTsNCi0JQVNTRVJUKHBBcHApOw0KLQlDSlNfVGltZXIqIHBUaW1lciA9IG5ldyBDSlNfVGltZXIodGhpcywgcEFwcCk7DQotCW1fYVRpbWVyLkFkZChwVGltZXIpOw0KLQ0KLQlwVGltZXItPlNldFR5cGUoMCk7DQotCXBUaW1lci0+U2V0UnVudGltZShwUnVudGltZSk7DQotCXBUaW1lci0+U2V0SlNjcmlwdChzY3JpcHQpOw0KLQlwVGltZXItPlNldFRpbWVPdXQoMCk7DQotLy8JcFRpbWVyLT5TZXRTdGFydFRpbWUoR2V0VGlja0NvdW50KCkpOw0KLQlwVGltZXItPlNldEpTVGltZXIoZHdJbnRlcnZhbCk7DQotCQ0KLQlKU0ZYT2JqZWN0IHBSZXRPYmogPSBKU19OZXdGeER5bmFtaWNPYmooKnBSdW50aW1lLCBwQ29udGV4dCwgSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJUaW1lck9iaiIpKTsNCi0JDQotCUNKU19UaW1lck9iaiogcEpTX1RpbWVyT2JqID0gKENKU19UaW1lck9iaiopSlNfR2V0UHJpdmF0ZShwUnVudGltZS0+R2V0SXNvbGF0ZSgpLHBSZXRPYmopOw0KLQlBU1NFUlQocEpTX1RpbWVyT2JqICE9IE5VTEwpOw0KLQkNCi0JVGltZXJPYmoqIHBUaW1lck9iaiA9IChUaW1lck9iaiopcEpTX1RpbWVyT2JqLT5HZXRFbWJlZE9iamVjdCgpOw0KLQlBU1NFUlQocFRpbWVyT2JqICE9IE5VTEwpOw0KLQkNCi0JcFRpbWVyT2JqLT5TZXRUaW1lcihwVGltZXIpOyANCi0JDQotCXZSZXQgPSBwUmV0T2JqOw0KLQkNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgYXBwOjpzZXRUaW1lT3V0KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JaWYgKHBhcmFtcy5zaXplKCkgPiAyIHx8IHBhcmFtcy5zaXplKCkgPT0gMCkNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQoKENKU19Db250ZXh0KiljYywgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwkNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQkNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0JDQotCUNGWF9XaWRlU3RyaW5nIHNjcmlwdCA9IHBhcmFtcy5zaXplKCkgPiAwID8gIChGWF9MUENXU1RSKShwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSkgOiAoRlhfTFBDV1NUUilMIiI7DQotCWlmIChzY3JpcHQuSXNFbXB0eSgpKSANCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQoKENKU19Db250ZXh0KiljYywgSURTX1NUUklOR19KU0FGTlVNQkVSX0tFWVNUUk9LRSk7DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQkNCi0JRlhfRFdPUkQgZHdUaW1lT3V0ID0gcGFyYW1zLnNpemUoKSA+IDEgPyAoaW50KXBhcmFtc1sxXSA6IDEwMDA7DQotCQ0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwID0gcFJ1bnRpbWUtPkdldFJlYWRlckFwcCgpOw0KLQlBU1NFUlQocEFwcCk7DQotCUNKU19UaW1lciogcFRpbWVyID0gbmV3IENKU19UaW1lcih0aGlzLCBwQXBwKTsNCi0JbV9hVGltZXIuQWRkKHBUaW1lcik7DQotCQ0KLQlwVGltZXItPlNldFR5cGUoMSk7DQotCXBUaW1lci0+U2V0UnVudGltZShwUnVudGltZSk7DQotCXBUaW1lci0+U2V0SlNjcmlwdChzY3JpcHQpOw0KLQlwVGltZXItPlNldFRpbWVPdXQoZHdUaW1lT3V0KTsNCi0vLwlwVGltZXItPlNldFN0YXJ0VGltZShHZXRUaWNrQ291bnQoKSk7DQotLy8JcFRpbWVyLT5TZXRKU1RpbWVyKDEwMDApOw0KLQlwVGltZXItPlNldEpTVGltZXIoZHdUaW1lT3V0KTsNCi0JDQotCUpTRlhPYmplY3QgcFJldE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIlRpbWVyT2JqIikpOw0KLS8vCUFTU0VSVChwUmV0T2JqICE9IE5VTEwpOw0KLQkNCi0JQ0pTX1RpbWVyT2JqKiBwSlNfVGltZXJPYmogPSAoQ0pTX1RpbWVyT2JqKilKU19HZXRQcml2YXRlKHBSdW50aW1lLT5HZXRJc29sYXRlKCkscFJldE9iaik7DQotCUFTU0VSVChwSlNfVGltZXJPYmogIT0gTlVMTCk7DQotCQ0KLQlUaW1lck9iaiogcFRpbWVyT2JqID0gKFRpbWVyT2JqKilwSlNfVGltZXJPYmotPkdldEVtYmVkT2JqZWN0KCk7DQotCUFTU0VSVChwVGltZXJPYmogIT0gTlVMTCk7DQotCQ0KLQlwVGltZXJPYmotPlNldFRpbWVyKHBUaW1lcik7IA0KLQkNCi0JdlJldCA9IHBSZXRPYmo7DQotCQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OmNsZWFyVGltZU91dChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotCQ0KLQlpZiAocGFyYW1zLnNpemUoKSAhPSAxKQ0KLQl7DQotCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotCQ0KLQlpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9meG9iamVjdCkNCi0Jew0KLQkJSlNGWE9iamVjdCBwT2JqID0gKEpTRlhPYmplY3QpcGFyYW1zWzBdOw0KLQkJew0KLQkJCWlmIChKU19HZXRPYmpEZWZuSUQocE9iaikgPT0gSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJUaW1lck9iaiIpKQ0KLQkJCXsNCi0JCQkJaWYgKENKU19PYmplY3QqIHBKU09iaiA9IChDSlNfT2JqZWN0KilwYXJhbXNbMF0pDQotCQkJCXsNCi0JCQkJCWlmIChUaW1lck9iaiogcFRpbWVyT2JqID0gKFRpbWVyT2JqKilwSlNPYmotPkdldEVtYmVkT2JqZWN0KCkpDQotCQkJCQl7DQotCQkJCQkJaWYgKENKU19UaW1lciogcFRpbWVyID0gcFRpbWVyT2JqLT5HZXRUaW1lcigpKQ0KLQkJCQkJCXsNCi0JCQkJCQkJcFRpbWVyLT5LaWxsSlNUaW1lcigpOw0KLQkJCQkJCQkNCi0JCQkJCQkJZm9yIChpbnQgaT0wLHN6PW1fYVRpbWVyLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlpZiAobV9hVGltZXJbaV0gPT0gcFRpbWVyKQ0KLQkJCQkJCQkJew0KLQkJCQkJCQkJCW1fYVRpbWVyLlJlbW92ZUF0KGkpOw0KLQkJCQkJCQkJCWJyZWFrOw0KLQkJCQkJCQkJfQ0KLQkJCQkJCQl9DQotCQkJCQkJCQ0KLQkJCQkJCQlkZWxldGUgcFRpbWVyOw0KLQkJCQkJCQlwVGltZXJPYmotPlNldFRpbWVyKE5VTEwpOw0KLQkJCQkJCX0NCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLQkNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgYXBwOjpjbGVhckludGVydmFsKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0NCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQoKENKU19Db250ZXh0KiljYywgSURTX1NUUklOR19KU1BBUkFNRVJST1IpOwkNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLQkNCi0JaWYgKHBhcmFtc1swXS5HZXRUeXBlKCkgPT0gVlRfZnhvYmplY3QpDQotCXsNCi0JCUpTRlhPYmplY3QgcE9iaiA9IChKU0ZYT2JqZWN0KXBhcmFtc1swXTsNCi0JCXsNCi0JCQlpZiAoSlNfR2V0T2JqRGVmbklEKHBPYmopID09IEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiVGltZXJPYmoiKSkNCi0JCQl7DQotCQkJCWlmIChDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopcGFyYW1zWzBdKQ0KLQkJCQl7DQotCQkJCQlpZiAoVGltZXJPYmoqIHBUaW1lck9iaiA9IChUaW1lck9iaiopcEpTT2JqLT5HZXRFbWJlZE9iamVjdCgpKQ0KLQkJCQkJew0KLQkJCQkJCWlmIChDSlNfVGltZXIqIHBUaW1lciA9IHBUaW1lck9iai0+R2V0VGltZXIoKSkNCi0JCQkJCQl7DQotCQkJCQkJCXBUaW1lci0+S2lsbEpTVGltZXIoKTsNCi0JCQkJCQkJDQotCQkJCQkJCWZvciAoaW50IGk9MCxzej1tX2FUaW1lci5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQkJCQkJew0KLQkJCQkJCQkJaWYgKG1fYVRpbWVyW2ldID09IHBUaW1lcikNCi0JCQkJCQkJCXsNCi0JCQkJCQkJCQltX2FUaW1lci5SZW1vdmVBdChpKTsNCi0JCQkJCQkJCQlicmVhazsNCi0JCQkJCQkJCX0NCi0JCQkJCQkJfQ0KLQkJCQkJCQkNCi0JCQkJCQkJZGVsZXRlIHBUaW1lcjsNCi0JCQkJCQkJcFRpbWVyT2JqLT5TZXRUaW1lcihOVUxMKTsNCi0JCQkJCQl9DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0JDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6ZXhlY01lbnVJdGVtKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsJDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBhcHA6OlRpbWVyUHJvYyhDSlNfVGltZXIqIHBUaW1lcikNCi17DQotCUFTU0VSVChwVGltZXIgIT0gTlVMTCk7DQotDQotCXN3aXRjaCAocFRpbWVyLT5HZXRUeXBlKCkpDQotCXsNCi0JY2FzZSAwOiAvL2ludGVydmFsDQotCQlSdW5Kc1NjcmlwdChwVGltZXItPkdldFJ1bnRpbWUoKSwgcFRpbWVyLT5HZXRKU2NyaXB0KCkpOw0KLQkJYnJlYWs7DQotCWNhc2UgMToNCi0JCWlmIChwVGltZXItPkdldFRpbWVPdXQoKSA+IDApDQotCQl7DQotCQkJUnVuSnNTY3JpcHQocFRpbWVyLT5HZXRSdW50aW1lKCksIHBUaW1lci0+R2V0SlNjcmlwdCgpKTsNCi0JCQlwVGltZXItPktpbGxKU1RpbWVyKCk7DQotCQl9DQotCQlicmVhazsNCi0JfQ0KLQkNCi19DQotDQotdm9pZCBhcHA6OlJ1bkpzU2NyaXB0KENKU19SdW50aW1lKiBwUnVudGltZSxjb25zdCBDRlhfV2lkZVN0cmluZyYgd3NTY3JpcHQpDQotew0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCWlmICghcFJ1bnRpbWUtPklzQmxvY2tpbmcoKSkNCi0Jew0KLQkJSUZYSlNfQ29udGV4dCogcENvbnRleHQgPSBwUnVudGltZS0+TmV3Q29udGV4dCgpOw0KLQkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQkJcENvbnRleHQtPk9uRXh0ZXJuYWxfRXhlYygpOw0KLQkJQ0ZYX1dpZGVTdHJpbmcgd3RJbmZvOw0KLQkJcENvbnRleHQtPlJ1blNjcmlwdCh3c1NjcmlwdCx3dEluZm8pOw0KLQkJcFJ1bnRpbWUtPlJlbGVhc2VDb250ZXh0KHBDb250ZXh0KTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIGFwcDo6Z29CYWNrKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0NCi0NCi0JDQotCQ0KLQkNCi0JDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6Z29Gb3J3YXJkKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsJDQotDQotDQotDQotDQotDQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6bWFpbE1zZyhPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0NCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsNCi0NCi0JRlhfQk9PTCBiVUkgPSBUUlVFOw0KLQlDRlhfV2lkZVN0cmluZyBjVG8gPSBMIiI7DQotCUNGWF9XaWRlU3RyaW5nIGNDYyA9IEwiIjsNCi0JQ0ZYX1dpZGVTdHJpbmcgY0JjYyA9IEwiIjsNCi0JQ0ZYX1dpZGVTdHJpbmcgY1N1YmplY3QgPSBMIiI7DQotCUNGWF9XaWRlU3RyaW5nIGNNc2cgPSBMIiI7DQotCWlmKHBhcmFtcy5zaXplKCkgPCAyKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQ0KLQliVUkgPSBwYXJhbXMuc2l6ZSgpPj0xPyhpbnQpcGFyYW1zWzBdOlRSVUU7DQotCWNUbyA9IHBhcmFtcy5zaXplKCk+PTI/KGNvbnN0IHdjaGFyX3QqKShGWF9MUENXU1RSKXBhcmFtc1sxXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsNCi0JY0NjID0gcGFyYW1zLnNpemUoKT49Mz8oY29uc3Qgd2NoYXJfdCopKEZYX0xQQ1dTVFIpcGFyYW1zWzJdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk6TCIiOw0KLQljQmNjID0gcGFyYW1zLnNpemUoKT49ND8oY29uc3Qgd2NoYXJfdCopKEZYX0xQQ1dTVFIpcGFyYW1zWzNdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk6TCIiOw0KLQljU3ViamVjdCA9IHBhcmFtcy5zaXplKCk+PTU/KGNvbnN0IHdjaGFyX3QqKShGWF9MUENXU1RSKXBhcmFtc1s0XS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsNCi0JY01zZyA9IHBhcmFtcy5zaXplKCk+PTY/KGNvbnN0IHdjaGFyX3QqKShGWF9MUENXU1RSKXBhcmFtc1s1XS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsJCQ0KLQ0KLQ0KLQlpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9vYmplY3QpDQotCXsNCi0JCUpTT2JqZWN0IHBPYmogPSAoSlNPYmplY3QpcGFyYW1zWzBdOw0KLQ0KLQkJdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImJVSSIpOw0KLQkJCWJVSSA9IChpbnQpQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOw0KLQ0KLQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLCBwT2JqLCBMImNUbyIpOw0KLQkJCWNUbyA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiY0NjIik7DQotCQkJY0NjID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjQmNjIik7DQotCQkJY0JjYyA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiY1N1YmplY3QiKTsNCi0JCQljU3ViamVjdCA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiY01zZyIpOw0KLQkJCWNNc2cgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0JfQ0KLQkNCi0JDQotDQotCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsNCi0JQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOw0KLQ0KLQlDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwID0gcENvbnRleHQtPkdldFJlYWRlckFwcCgpOw0KLQlBU1NFUlQocEFwcCAhPSBOVUxMKTsNCi0NCi0JcFJ1bnRpbWUtPkJlZ2luQmxvY2soKTsNCi0JcEFwcC0+SlNfZG9jbWFpbEZvcm0oTlVMTCwgMCwgYlVJLCAoRlhfTFBDV1NUUiljVG8sIChGWF9MUENXU1RSKWNTdWJqZWN0LCAoRlhfTFBDV1NUUiljQ2MsIChGWF9MUENXU1RSKWNCY2MsIChGWF9MUENXU1RSKWNNc2cpOw0KLQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KLQlwUnVudGltZS0+RW5kQmxvY2soKTsNCi0NCi0JLy9yZXR1cm4gYlJldDsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6bGF1bmNoVVJMKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQkNCi0NCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc3dVUkwgPSBwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0NCi0JQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOw0KLQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7DQotDQotCXBSdW50aW1lLT5CZWdpbkJsb2NrKCk7DQotLy8JRlhfQk9PTCBiUmV0ID0gcEFwcC0+T3BlblVSTChzd1VSTCk7DQotCXBSdW50aW1lLT5FbmRCbG9jaygpOw0KLQ0KLS8vCXJldHVybiBiUmV0Ow0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgYXBwOjpydW50aW1lSGlnaGxpZ2h0KE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJdnA+Pm1fYlJ1bnRpbWVIaWdoTGlnaHQ7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQl2cDw8bV9iUnVudGltZUhpZ2hMaWdodDsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBhcHA6OmZ1bGxzY3JlZW4oT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6cG9wVXBNZW51KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi0NCi1GWF9CT09MIGFwcDo6YnJvd3NlRm9yRG9jKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JLy9UaGlzIG1ldGhvZCBtYXkgdHJpZ2dlciBhICJmaWxlIHNhdmUiIGRpYWxvZyx3aGlsZSBlbmFibGUgdXNlciB0byBzYXZlIGNvbnRlbnRzIG9mIHRoZSBkb2N1bWVudC4NCi0JLy9TdWNoIGFjdGlvbiBpcyBjb25zaWRlcmVkIHRvIGJlIHVuc2FmZS4NCi0JaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsNCi0NCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsNCi0NCi0JYm9vbCBiU2F2ZSA9IGZhbHNlOw0KLQlDRlhfQnl0ZVN0cmluZyBjRmlsZW5hbWVJbml0ID0gQ0ZYX0J5dGVTdHJpbmcoKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgY0ZTSW5pdCA9IENGWF9CeXRlU3RyaW5nKCk7DQotDQotCWlmKHBhcmFtcy5zaXplKCk+MCAmJiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9vYmplY3QpKQ0KLQl7DQotCQlKU09iamVjdCBwT2JqID0gKEpTT2JqZWN0IClwYXJhbXNbMF07DQotDQotIAkJdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLEwiYlNhdmUiKTsNCi0gCQkJYlNhdmUgPSAoYm9vbClDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7DQotIAkJDQotCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUsIHBPYmosTCJjRmlsZW5hbWVJbml0Iik7DQotCQl7DQotCQkJQ0pTX1ZhbHVlIHQgPSBDSlNfVmFsdWUoaXNvbGF0ZSwgcFZhbHVlLCBHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsNCi0gCQkJY0ZpbGVuYW1lSW5pdCA9IHQub3BlcmF0b3IgQ0ZYX0J5dGVTdHJpbmcoKTsNCi0JCX0NCi0gCQkNCi0JCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLEwiY0ZTSW5pdCIpOw0KLQkJew0KLQkJCUNKU19WYWx1ZSB0ID0gQ0pTX1ZhbHVlKGlzb2xhdGUsIHBWYWx1ZSwgR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7DQotCQkJY0ZTSW5pdCA9IHQub3BlcmF0b3IgQ0ZYX0J5dGVTdHJpbmcoKTsNCi0JCX0NCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmKHBhcmFtcy5zaXplKCkgPj0gMSkNCi0JCXsNCi0JCQliU2F2ZSA9IChib29sKXBhcmFtc1swXTsNCi0JCX0NCi0JCWlmKHBhcmFtcy5zaXplKCkgPj0gMikNCi0JCXsNCi0JCQlDSlNfVmFsdWUgdCA9IHBhcmFtc1sxXTsNCi0JCQljRmlsZW5hbWVJbml0ID0gdC5vcGVyYXRvciBDRlhfQnl0ZVN0cmluZygpOw0KLQkJfQ0KLQkJaWYocGFyYW1zLnNpemUoKSA+PSAzKQ0KLQkJew0KLQkJCUNKU19WYWx1ZSB0ID0gcGFyYW1zWzJdOw0KLQkJCWNGU0luaXQgPSB0Lm9wZXJhdG9yIENGWF9CeXRlU3RyaW5nKCk7DQotCQl9DQotCX0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JDQotCUNQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAgPSBwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCk7DQotCUFTU0VSVChwQXBwICE9IE5VTEwpOw0KLQ0KLQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7DQotCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgd3NGaWxlTmFtZUluaXQgPSBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNGaWxlbmFtZUluaXQpOw0KLQlDRlhfV2lkZVN0cmluZyB3c0ZTSW5pdCA9IENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY0ZTSW5pdCk7DQotCUNGWF9XaWRlU3RyaW5nIHdzRmlsZVBhdGggPSBwQXBwLT5KU19hcHBicm93c2VGb3JEb2MoYlNhdmUsIHdzRmlsZU5hbWVJbml0KTsNCi0JaWYod3NGaWxlUGF0aC5Jc0VtcHR5KCkpDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCUpTRlhPYmplY3QgcFJldE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCAtMSk7DQotDQotCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBSZXRPYmosIEwiY1BhdGgiLCBTeXNQYXRoVG9QREZQYXRoKHdzRmlsZVBhdGgpKTsJDQotCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBSZXRPYmosIEwiY1VSTCIsIFN5c1BhdGhUb1BERlBhdGgod3NGaWxlUGF0aCkpOw0KLQ0KLQlpZiAoIWNGU0luaXQuSXNFbXB0eSgpKQ0KLQl7DQotCQlKU19QdXRPYmplY3RTdHJpbmcoaXNvbGF0ZSxwUmV0T2JqLCBMImNGUyIsIENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY0ZTSW5pdC5HZXRCdWZmZXIoY0ZTSW5pdC5HZXRMZW5ndGgoKSkpKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBSZXRPYmosIEwiY0ZTIiwgQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbCgiRE9TIikpOw0KLQl9DQotCQ0KLQl2UmV0ID0gIHBSZXRPYmo7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBhcHA6OlN5c1BhdGhUb1BERlBhdGgoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNPbGRQYXRoKQ0KLXsNCi0JQ0ZYX1dpZGVTdHJpbmcgc1JldCA9IEwiLyI7DQotCQ0KLQlmb3IgKGludCBpPTAsc3o9c09sZFBhdGguR2V0TGVuZ3RoKCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJd2NoYXJfdCBjID0gc09sZFBhdGguR2V0QXQoaSk7DQotCQlpZiAoYyA9PSBMJzonKQ0KLQkJew0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChjID09IEwnXFwnKQ0KLQkJCXsNCi0JCQkJc1JldCArPSBMIi8iOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlzUmV0ICs9IGM7DQotCQkJfQ0KLQkJfQ0KLQl9DQotCQ0KLQlyZXR1cm4gc1JldDsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgYXBwOjpQREZQYXRoVG9TeXNQYXRoKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzT2xkUGF0aCkNCi17DQotCS8vc3RyTFBhdGggPSAiRDpcdGVtcG9yYXkuZmRmIjsNCi0JQ0ZYX1dpZGVTdHJpbmcgc3RyT1BhdGggPSBzT2xkUGF0aDsNCi0Jc3RyT1BhdGguVHJpbUxlZnQoKTsNCi0Jc3RyT1BhdGguVHJpbVJpZ2h0KCk7DQotCQ0KLQlpZiAoc3RyT1BhdGguR2V0QXQoMCkgPT0gTCcvJyAmJiBzdHJPUGF0aC5HZXRBdCgyKSA9PSBMJy8nKQ0KLQl7DQotCQl3Y2hhcl90IGNfRHJpdmUgPSBzdHJPUGF0aC5HZXRBdCgxKTsNCi0JCWlmICgoY19Ecml2ZSA+PSBMJ2EnICYmIGNfRHJpdmUgPD0gTCd6JyApfHwoIGNfRHJpdmUgPj0gTCdBJyAmJiBjX0RyaXZlIDw9IEwnWicpKQ0KLQkJew0KLQkJCXN0ck9QYXRoLlJlcGxhY2UoKEZYX0xQQ1dTVFIpTCIvIiwoRlhfTFBDV1NUUilMIlxcIik7DQotCQkJLy9zdHJPUGF0aC5TZXRBdCgwLCcnKTsNCi0JCQlzdHJPUGF0aC5JbnNlcnQoMiwnOicpOw0KLQkJCXN0ck9QYXRoLkRlbGV0ZSgwKTsNCi0JCX0NCi0JfQ0KLQkNCi0JcmV0dXJuIHN0ck9QYXRoOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBhcHA6OlJlbGF0aXZlUGF0aFRvU3lzUGF0aChjb25zdCBDRlhfV2lkZVN0cmluZyYgc09sZFBhdGgsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzRmlsZVBhdGgpDQotew0KLS8vCWlmICghUGF0aElzUmVsYXRpdmUoc09sZFBhdGgpKSByZXR1cm4gc09sZFBhdGg7DQotCQ0KLQlpbnQgblNwbGl0ID0gMDsNCi0JZm9yIChpbnQgaT1zRmlsZVBhdGguR2V0TGVuZ3RoKCktMTsgaT49MDsgaS0tKQ0KLQl7DQotCQlpZiAoc0ZpbGVQYXRoW2ldID09ICdcXCcgfHwgc0ZpbGVQYXRoW2ldID09ICcvJykNCi0JCXsNCi0JCQluU3BsaXQgPSBpOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotCQ0KLQlyZXR1cm4gc0ZpbGVQYXRoLkxlZnQoblNwbGl0KzEpICsgc09sZFBhdGg7DQotfQ0KLQ0KLUZYX0JPT0wgYXBwOjpuZXdEb2MoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgYXBwOjpvcGVuRG9jKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MIGFwcDo6cmVzcG9uc2UoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlDRlhfV2lkZVN0cmluZyBzd1F1ZXN0aW9uID0gTCIiOw0KLQlDRlhfV2lkZVN0cmluZyBzd0xhYmVsID0gTCIiOw0KLSNpZm5kZWYgRk9YSVRfQ0hST01FX0JVSUxEDQotCUNGWF9XaWRlU3RyaW5nIHN3VGl0bGUgPSBMIkZveGl0IjsNCi0jZWxzZQ0KLQlDRlhfV2lkZVN0cmluZyBzd1RpdGxlID0gTCJQREYiOw0KLSNlbmRpZg0KLQlDRlhfV2lkZVN0cmluZyBzd0RlZmF1bHQgPSBMIiI7DQotCUNGWF9XaWRlU3RyaW5nIHN3UmVzcG9uc2UgPSBMIiI7DQotCWJvb2wgYlBhc3NXb3JkID0gZmFsc2U7DQotCQ0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOw0KLQkNCi0JaW50IGlMZW5ndGggPSBwYXJhbXMuc2l6ZSgpOwkNCi0JaWYgKGlMZW5ndGggPiAwICYmIHBhcmFtc1swXS5HZXRUeXBlKCkgPT0gVlRfb2JqZWN0KQ0KLQl7DQotCQkNCi0JCUpTT2JqZWN0IHBPYmogPSAoSlNPYmplY3QgKXBhcmFtc1swXTsNCi0JCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaixMImNRdWVzdGlvbiIpOw0KLQkJCXN3UXVlc3Rpb24gPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsNCi0NCi0JCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLEwiY1RpdGxlIik7DQotCQkJc3dUaXRsZSA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosTCJjRGVmYXVsdCIpOw0KLQkJCXN3RGVmYXVsdCA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQ0KLQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosTCJjTGFiZWwiKTsNCi0JCQlzd0xhYmVsID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaixMImJQYXNzd29yZCIpOw0KLQkJCWJQYXNzV29yZCA9IChib29sKUNKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXN3aXRjaChpTGVuZ3RoKQ0KLQkJew0KLQkJY2FzZSAxOg0KLQkJCXN3UXVlc3Rpb24gPSBwYXJhbXNbMF07DQotCQkJYnJlYWs7DQotCQljYXNlIDI6DQotCQkJc3dRdWVzdGlvbiA9IHBhcmFtc1swXTsNCi0JCQlzd1RpdGxlID0gcGFyYW1zWzFdOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSAzOg0KLQkJCXN3UXVlc3Rpb24gPSBwYXJhbXNbMF07DQotCQkJc3dUaXRsZSA9IHBhcmFtc1sxXTsNCi0JCQlzd0RlZmF1bHQgPSBwYXJhbXNbMl07DQotCQkJYnJlYWs7DQotCQljYXNlIDQ6DQotCQkJc3dRdWVzdGlvbiA9IHBhcmFtc1swXTsNCi0JCQlzd1RpdGxlID0gcGFyYW1zWzFdOw0KLQkJCXN3RGVmYXVsdCA9IHBhcmFtc1syXTsNCi0JCQliUGFzc1dvcmQgPSBwYXJhbXNbM107DQotCQkJYnJlYWs7DQotCQljYXNlIDU6DQotCQkJc3dRdWVzdGlvbiA9IHBhcmFtc1swXTsNCi0JCQlzd1RpdGxlID0gcGFyYW1zWzFdOw0KLQkJCXN3RGVmYXVsdCA9IHBhcmFtc1syXTsNCi0JCQliUGFzc1dvcmQgPSBwYXJhbXNbM107DQotCQkJc3dMYWJlbCA9IHBhcmFtc1s0XTsNCi0JCQlicmVhazsNCi0JCWRlZmF1bHQ6DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7DQotIAlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotDQotCUNQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAgPSBwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCk7DQotIAlBU1NFUlQocEFwcCAhPSBOVUxMKTsNCi0JaW50IG5MZW5ndGggPSAyMDQ4Ow0KLQljaGFyKiBwQnVmZiA9IG5ldyBjaGFyW25MZW5ndGhdOw0KLQluTGVuZ3RoID0gcEFwcC0+SlNfYXBwUmVzcG9uc2Uoc3dRdWVzdGlvbiwgc3dUaXRsZSwgc3dEZWZhdWx0LCBzd0xhYmVsLCBiUGFzc1dvcmQsIHBCdWZmLCBuTGVuZ3RoKTsNCi0JaWYobkxlbmd0aDw9MCkNCi0Jew0KLQkJdlJldC5TZXROdWxsKCk7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQluTGVuZ3RoID0gbkxlbmd0aD4yMDQ2PzIwNDY6bkxlbmd0aDsNCi0gICAgcEJ1ZmZbbkxlbmd0aF0gPSAwOw0KLSAgICBwQnVmZltuTGVuZ3RoKzFdID0gMDsNCi0JCXN3UmVzcG9uc2UgPSBDRlhfV2lkZVN0cmluZzo6RnJvbVVURjE2TEUoKHVuc2lnbmVkIHNob3J0KilwQnVmZiwgbkxlbmd0aCk7DQotCQl2UmV0ID0gc3dSZXNwb25zZTsNCi0JfQ0KLQlkZWxldGVbXSBwQnVmZjsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgYXBwOjptZWRpYShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgYXBwOjpleGVjRGlhbG9nKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2FwcC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvcmVzb3VyY2UuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19SdW50aW1lLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0RvY3VtZW50LmgiCisKKworc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQoreworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlyZXR1cm4gcFJ1bnRpbWUtPkdldElzb2xhdGUoKTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBUaW1lck9iaiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0JFR0lOX0pTX1NUQVRJQ19DT05TVChDSlNfVGltZXJPYmopCitFTkRfSlNfU1RBVElDX0NPTlNUKCkKKworQkVHSU5fSlNfU1RBVElDX1BST1AoQ0pTX1RpbWVyT2JqKQorRU5EX0pTX1NUQVRJQ19QUk9QKCkKKworQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfVGltZXJPYmopCitFTkRfSlNfU1RBVElDX01FVEhPRCgpCisKK0lNUExFTUVOVF9KU19DTEFTUyhDSlNfVGltZXJPYmosIFRpbWVyT2JqKQorCitUaW1lck9iajo6VGltZXJPYmooQ0pTX09iamVjdCogcEpTT2JqZWN0KQorOiBDSlNfRW1iZWRPYmoocEpTT2JqZWN0KSwKK21fcFRpbWVyKE5VTEwpCit7CisJCit9CisKK1RpbWVyT2JqOjp+VGltZXJPYmooKQoreworfQorCit2b2lkIFRpbWVyT2JqOjpTZXRUaW1lcihDSlNfVGltZXIqIHBUaW1lcikKK3sKKwltX3BUaW1lciA9IHBUaW1lcjsKK30KKworQ0pTX1RpbWVyKiBUaW1lck9iajo6R2V0VGltZXIoKSBjb25zdAoreworCXJldHVybiBtX3BUaW1lcjsKK30KKworI2RlZmluZSBKU19TVFJfVklFV0VSVFlQRV9SRUFERVIJCUwiUmVhZGVyIgorI2RlZmluZSBKU19TVFJfVklFV0VSVFlQRV9TVEFOREFSRAkJTCJFeGNoYW5nZSIKKyNkZWZpbmUgSlNfU1RSX1ZJRVdFUlZBUklBVElPTgkJCUwiRnVsbCIKKyNkZWZpbmUgSlNfU1RSX1BMQVRGT1JNCQkJCQlMIldJTiIKKyNkZWZpbmUgSlNfU1RSX0xBTkdVQU5HRQkJCQlMIkVOVSIKKyNkZWZpbmUgSlNfU1RSX1ZJRVdFUlZFUlNJT04JCQk4CisjZGVmaW5lIEpTX05VTV9GT1JNU1ZFUlNJT04JCQkJNworCisjZGVmaW5lIEpTX0ZJTEVQQVRIX01BWExFTgkJCQkyMDAwCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gYXBwIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19BcHApCitFTkRfSlNfU1RBVElDX0NPTlNUKCkKKworQkVHSU5fSlNfU1RBVElDX1BST1AoQ0pTX0FwcCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShhY3RpdmVEb2NzKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGNhbGN1bGF0ZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShmb3Jtc1ZlcnNpb24pCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZnMpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZnVsbHNjcmVlbikKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShsYW5ndWFnZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShtZWRpYSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShwbGF0Zm9ybSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShydW50aW1lSGlnaGxpZ2h0KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHZpZXdlclR5cGUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkodmlld2VyVmFyaWF0aW9uKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHZpZXdlclZlcnNpb24pCQorRU5EX0pTX1NUQVRJQ19QUk9QKCkKKworQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfQXBwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYWxlcnQsIDYpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShiZWVwLCAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYnJvd3NlRm9yRG9jLCAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoY2xlYXJJbnRlcnZhbCwgMSkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGNsZWFyVGltZU91dCwgMSkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGV4ZWNEaWFsb2csIDMpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShleGVjTWVudUl0ZW0sICAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoZmluZENvbXBvbmVudCwgMSkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdvQmFjaywgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGdvRm9yd2FyZCwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGxhdW5jaFVSTCwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKG1haWxNc2csIDApCQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkobmV3RkRGLCAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkobmV3RG9jLCAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkob3BlbkRvYywgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKG9wZW5GREYsIDUpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShwb3BVcE1lbnVFeCwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHBvcFVwTWVudSwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHJlc3BvbnNlLCAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoc2V0SW50ZXJ2YWwsIDIpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzZXRUaW1lT3V0LCAyKQorRU5EX0pTX1NUQVRJQ19NRVRIT0QoKQorCitJTVBMRU1FTlRfSlNfQ0xBU1MoQ0pTX0FwcCxhcHApCisKK2FwcDo6YXBwKENKU19PYmplY3QgKiBwSlNPYmplY3QpIDogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCkgLAorCW1fYkNhbGN1bGF0ZSh0cnVlKSwKKwltX3BSdW50aW1lKE5VTEwpLAorCW1fYlJ1bnRpbWVIaWdoTGlnaHQoZmFsc2UpCisvLwltX3BNZW51SGVhZChOVUxMKQoreworfQorCithcHA6On5hcHAodm9pZCkKK3sKKwlmb3IgKGludCBpPTAsc3o9bV9hVGltZXIuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCWRlbGV0ZSBtX2FUaW1lcltpXTsKKworCW1fYVRpbWVyLlJlbW92ZUFsbCgpOworfQorCitGWF9CT09MIGFwcDo6YWN0aXZlRG9jcyhPQkpfUFJPUF9QQVJBTVMpCit7CisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKworCQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCQkKKwkJQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBDb250ZXh0LT5HZXRSZWFkZXJBcHAoKTsKKwkJQVNTRVJUKHBBcHAgIT0gTlVMTCk7CisKKwkJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCQlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisJCQorCQlDUERGU0RLX0RvY3VtZW50KiBwQ3VyRG9jID0gcENvbnRleHQtPkdldFJlYWRlckRvY3VtZW50KCk7CisJCQorCQlDSlNfQXJyYXkgYURvY3MocFJ1bnRpbWUtPkdldElzb2xhdGUoKSk7CisvLwkJaW50IGlOdW1Eb2NzID0gcEFwcC0+Q291bnREb2N1bWVudHMoKTsKKwkJCisvLyAJCWZvcihpbnQgaUluZGV4ID0gMDsgaUluZGV4PGlOdW1Eb2NzOyBpSW5kZXgrKykKKy8vIAkJeworCQkJQ1BERlNES19Eb2N1bWVudCogcERvYyA9IHBBcHAtPkdldEN1cnJlbnREb2MoKTsKKwkJCWlmIChwRG9jKQorCQkJeworCQkJCUNKU19Eb2N1bWVudCAqIHBKU0RvY3VtZW50ID0gTlVMTDsKKwkJCQkKKwkJCQlpZiAocERvYyA9PSBwQ3VyRG9jKQorCQkJCXsKKwkJCQkJSlNGWE9iamVjdCBwT2JqID0gSlNfR2V0VGhpc09iaigqcFJ1bnRpbWUpOworCQkJCQkKKwkJCQkJaWYgKEpTX0dldE9iakRlZm5JRChwT2JqKSA9PSBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIkRvY3VtZW50IikpCisJCQkJCXsKKwkJCQkJCXBKU0RvY3VtZW50ID0gKENKU19Eb2N1bWVudCopSlNfR2V0UHJpdmF0ZShwUnVudGltZS0+R2V0SXNvbGF0ZSgpLHBPYmopOworCQkJCQl9CisJCQkJfQorCQkJCWVsc2UKKwkJCQl7CisJCQkJCUpTRlhPYmplY3QgcE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLEwiRG9jdW1lbnQiKSk7CisJCQkJCXBKU0RvY3VtZW50ID0gKENKU19Eb2N1bWVudCopSlNfR2V0UHJpdmF0ZShwUnVudGltZS0+R2V0SXNvbGF0ZSgpLHBPYmopOworCQkJCQlBU1NFUlQocEpTRG9jdW1lbnQgIT0gTlVMTCk7CisJCQkJCQorCQkJCQkKKwkJCQkJLy8JCQlwRG9jdW1lbnQtPkF0dGFjaERvYyhwRG9jKTsKKwkJCQl9CisJCQkJCisJCQkJYURvY3MuU2V0RWxlbWVudCgwLENKU19WYWx1ZShwUnVudGltZS0+R2V0SXNvbGF0ZSgpLHBKU0RvY3VtZW50KSk7CisJCQl9CisJLy8JCX0KKwkJCisJCWlmIChhRG9jcy5HZXRMZW5ndGgoKSA+IDApCisJCQl2cCA8PCBhRG9jczsKKwkJZWxzZQorCQkJdnAuU2V0TnVsbCgpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIGFwcDo6Y2FsY3VsYXRlKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQlib29sIGJWUDsKKwkJdnAgPj4gYlZQOworCQltX2JDYWxjdWxhdGUgPSAoRlhfQk9PTCliVlA7CisKKwkJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCQkKKwkJQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBDb250ZXh0LT5HZXRSZWFkZXJBcHAoKTsKKwkJQVNTRVJUKHBBcHAgIT0gTlVMTCk7CisJCQorCQlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7CisJCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCQlDSlNfQXJyYXkgYURvY3MocFJ1bnRpbWUtPkdldElzb2xhdGUoKSk7CisvLyAJCWludCBpTnVtRG9jcyA9IHBBcHAtPkNvdW50RG9jdW1lbnRzKCk7CisvLyAJCQorLy8gCQlmb3IgKGludCBpSW5kZXggPSAwO2lJbmRleCA8IGlOdW1Eb2NzOyBpSW5kZXgrKykKKy8vIAkJeworCQkJaWYgKENQREZTREtfRG9jdW1lbnQqIHBEb2MgPSBwQXBwLT5HZXRDdXJyZW50RG9jKCkpCisJCQl7CisJCQkJQ1BERlNES19JbnRlckZvcm0qIHBJbnRlckZvcm0gPSAoQ1BERlNES19JbnRlckZvcm0qKXBEb2MtPkdldEludGVyRm9ybSgpOworCQkJCUFTU0VSVChwSW50ZXJGb3JtICE9IE5VTEwpOworCQkJCXBJbnRlckZvcm0tPkVuYWJsZUNhbGN1bGF0ZSgoRlhfQk9PTCltX2JDYWxjdWxhdGUpOworCQkJfQkJCQorLy8JCX0KKwl9CisJZWxzZQorCXsKKwkJdnAgPDwgKGJvb2wpbV9iQ2FsY3VsYXRlOworCX0KKwkKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBhcHA6OmZvcm1zVmVyc2lvbihPQkpfUFJPUF9QQVJBTVMpCit7CisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgSlNfTlVNX0ZPUk1TVkVSU0lPTjsKKwkJcmV0dXJuIFRSVUU7CisJfQorCQorCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBhcHA6OnZpZXdlclR5cGUoT0JKX1BST1BfUEFSQU1TKQoreworCisKKwkKKwkKKwkKKworCWlmICh2cC5Jc0dldHRpbmcoKSkKKwl7CisvLyAJCWlmIChwQXBwLT5HZXRBcHBOYW1lKCkgPT0gUEhBTlRPTSkKKy8vIAkJCXZwIDw8IEpTX1NUUl9WSUVXRVJUWVBFX1NUQU5EQVJEOworLy8gCQllbHNlCisvLyAJCQl2cCA8PCBKU19TVFJfVklFV0VSVFlQRV9SRUFERVI7CisJCXZwIDw8IEwidW5rbm93biI7CisKKwkJLy92cCA8PCBwQXBwLT5HZXRBcHBUaXRsZSgpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIGFwcDo6dmlld2VyVmFyaWF0aW9uKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAodnAuSXNHZXR0aW5nKCkpCisJeworCQl2cCA8PCBKU19TVFJfVklFV0VSVkFSSUFUSU9OOworCQlyZXR1cm4gVFJVRTsKKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIGFwcDo6dmlld2VyVmVyc2lvbihPQkpfUFJPUF9QQVJBTVMpCit7CisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgSlNfU1RSX1ZJRVdFUlZFUlNJT047CisJCXJldHVybiBUUlVFOworCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgYXBwOjpwbGF0Zm9ybShPQkpfUFJPUF9QQVJBTVMpCit7CisJaWYgKHZwLklzR2V0dGluZygpKQorCXsKKwkJdnAgPDwgSlNfU1RSX1BMQVRGT1JNOworCQlyZXR1cm4gVFJVRTsKKwl9CisJCisJcmV0dXJuIEZBTFNFOworfQorCitGWF9CT09MIGFwcDo6bGFuZ3VhZ2UoT0JKX1BST1BfUEFSQU1TKQoreworCWlmICh2cC5Jc0dldHRpbmcoKSkKKwl7CisJCXZwIDw8IEpTX1NUUl9MQU5HVUFOR0U7CisJCXJldHVybiBUUlVFOworCX0KKwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKKy8vY3JlYXRlcyBhIG5ldyBmZGYgb2JqZWN0IHRoYXQgY29udGFpbnMgbm8gZGF0YQorLy9jb21tZW50OiBuZWVkIHJlYWRlciBzdXBwb3J0CisvL25vdGU6CisvL0NGREZfRG9jdW1lbnQgKiBDUERGRG9jX0Vudmlyb25tZW50OjpOZXdGREYoKTsKK0ZYX0JPT0wgYXBwOjpuZXdGREYoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIFRSVUU7Cit9CisvL29wZW5zIGEgc3BlY2lmaWVkIHBkZiBkb2N1bWVudCBhbmQgcmV0dXJucyBpdHMgZG9jdW1lbnQgb2JqZWN0CisvL2NvbW1lbnQ6bmVlZCByZWFkZXIgc3VwcG9ydAorLy9ub3RlOiBhcyBkZWZpbmVkIGluIGpzIHJlZmVyZW5jZSwgdGhlIHByb3RvIG9mIHRoaXMgZnVuY3Rpb24ncyBmb3VydGggcGFybWV0ZXJzLCBob3cgb2xkIGFuIGZkZiBkb2N1bWVudCB3aGlsZSBkbyBub3Qgc2hvdyBpdC4KKy8vQ0ZERl9Eb2N1bWVudCAqIENQREZEb2NfRW52aXJvbm1lbnQ6Ok9wZW5GREYoc3RyaW5nIHN0clBhdGgsYm9vbCBiVXNlckNvbnYpOworCitGWF9CT09MIGFwcDo6b3BlbkZERihPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBhcHA6OmFsZXJ0KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7CisJaWYgKGlTaXplIDwgMSkKKwkJcmV0dXJuIEZBTFNFOworCisJQ0ZYX1dpZGVTdHJpbmcgc3dNc2cgPSBMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgc3dUaXRsZSA9IEwiIjsKKwlpbnQgaUljb24gPSAwOworCWludCBpVHlwZSA9IDA7CisKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOworCisJaWYgKGlTaXplID09IDEpCisJeworCQlpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9vYmplY3QpCisJCXsKKwkJCUpTT2JqZWN0IHBPYmogPSBwYXJhbXNbMF07CisJCQl7CisJCQkJdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSwgcE9iaiwgTCJjTXNnIik7CisJCQkJc3dNc2cgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsVlRfdW5rbm93bikub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQkJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLEwiY1RpdGxlIik7CisJCQkJc3dUaXRsZSA9IENKU19WYWx1ZShpc29sYXRlLCBwVmFsdWUsVlRfdW5rbm93bikub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQkJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLEwibkljb24iKTsKKwkJCQlpSWNvbiA9IChpbnQpQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLFZUX3Vua25vd24pOworCisJCQkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosTCJuVHlwZSIpOworCQkJCWlUeXBlID0gKGludClDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsVlRfdW5rbm93bik7CisJCQl9CisKKwkJCWlmIChzd01zZyA9PSBMIiIpCisJCQl7CisJCQkJQ0pTX0FycmF5IGNhcnJheShpc29sYXRlKTsKKwkJCQlpZiAocGFyYW1zWzBdLkNvbnZlcnRUb0FycmF5KGNhcnJheSkpCisJCQkJeworCQkJCQlpbnQgaUxlbnRoID0gY2FycmF5LkdldExlbmd0aCgpOworCQkJCQlDSlNfVmFsdWUqIHBWYWx1ZSA9IG5ldyBDSlNfVmFsdWUoaXNvbGF0ZSk7CisvLwkJCQkJaWYgKGlMZW50aCA9PSAxKQorLy8JCQkJCQlwVmFsdWUgPSBuZXcgQ0pTX1ZhbHVlKGlzb2xhdGUpOworLy8gCQkJCQllbHNlIGlmIChpTGVudGggPiAxKQorLy8gCQkJCQkJcFZhbHVlID0gbmV3IENKU19WYWx1ZVtpTGVudGhdOworCisJCQkJCWZvcihpbnQgaSA9IDA7IGkgPCBpTGVudGg7IGkrKykKKwkJCQkJeworCQkJCQkJY2FycmF5LkdldEVsZW1lbnQoaSwgKnBWYWx1ZSk7CisJCQkJCQlzd01zZyArPSAoKnBWYWx1ZSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKwkJCQkJCWlmIChpIDwgaUxlbnRoIC0gMSkKKwkJCQkJCQlzd01zZyArPSBMIiwgICI7CisJCQkJCX0KKworCQkJCQlpZihwVmFsdWUpIGRlbGV0ZSBwVmFsdWU7CisvLyAJCQkJCWlmICgoaUxlbnRoID4gMSkgJiYgcFZhbHVlKQorLy8gCQkJCQl7CisvLyAJCQkJCQlkZWxldGVbXXBWYWx1ZTsKKy8vIAkJCQkJCXBWYWx1ZSA9IE5VTEw7CisvLyAJCQkJCX0KKy8vIAkJCQkJZWxzZSBpZiAoKGlMZW50aCA9PSAxKSAmJiBwVmFsdWUpCisvLyAJCQkJCXsKKy8vIAkJCQkJCWRlbGV0ZSBwVmFsdWU7CisvLyAJCQkJCQlwVmFsdWUgPSBOVUxMOworLy8gCQkJCQl9CisJCQkJfQorCQkJfQorCisJCQlpZiAoc3dUaXRsZSA9PSBMIiIpCisJCQkJc3dUaXRsZSA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNBTEVSVCk7CisJCX0KKwkJZWxzZSBpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9ib29sZWFuKQorCQl7CisJCQlGWF9CT09MIGJHZXQgPSAoRlhfQk9PTClwYXJhbXNbMF07CisJCQlpZiAoYkdldCkKKwkJCQlzd01zZyA9IEwidHJ1ZSI7CisJCQllbHNlCisJCQkJc3dNc2cgPSBMImZhbHNlIjsKKworCQkJc3dUaXRsZSA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNBTEVSVCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlzd01zZyA9IHBhcmFtc1swXTsKKwkJCXN3VGl0bGUgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTQUxFUlQpOworCQl9CisJfQorCWVsc2UKKwl7CisJCWlmIChwYXJhbXNbMF0uR2V0VHlwZSgpID09IFZUX2Jvb2xlYW4pCisJCXsKKwkJCUZYX0JPT0wgYkdldCA9IChGWF9CT09MKXBhcmFtc1swXTsKKwkJCWlmIChiR2V0KQorCQkJCXN3TXNnID0gTCJ0cnVlIjsKKwkJCWVsc2UKKwkJCQlzd01zZyA9IEwiZmFsc2UiOworCQl9CisJCWVsc2UKKwkJeworCQkJc3dNc2cgPSBwYXJhbXNbMF07CisJCX0KKwkJc3dUaXRsZSA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNBTEVSVCk7CisJCQorCQlmb3IoaW50IGkgPSAxO2k8aVNpemU7aSsrKQorCQl7CisJCQlpZiAoaSA9PSAxKQorCQkJCWlJY29uID0gaW50KHBhcmFtc1tpXSk7CisJCQlpZiAoaSA9PSAyKQorCQkJCWlUeXBlID0gaW50KHBhcmFtc1tpXSk7CisJCQlpZiAoaSA9PSAzKQorCQkJCXN3VGl0bGUgPSBwYXJhbXNbaV07CQkJCisJCX0KKwl9CisKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisJcFJ1bnRpbWUtPkJlZ2luQmxvY2soKTsKKwl2UmV0ID0gTXNnQm94KHBSdW50aW1lLT5HZXRSZWFkZXJBcHAoKSwgSlNHZXRQYWdlVmlldyhjYyksc3dNc2csc3dUaXRsZSxpVHlwZSxpSWNvbik7CisJcFJ1bnRpbWUtPkVuZEJsb2NrKCk7CisJCisJcmV0dXJuIFRSVUU7Cit9CisKKworRlhfQk9PTCBhcHA6OmJlZXAoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKHBhcmFtcy5zaXplKCkgPT0gMSkKKwl7CisJCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwkJQ1BERkRvY19FbnZpcm9ubWVudCAqIHBFbnYgPSBwUnVudGltZS0+R2V0UmVhZGVyQXBwKCk7CisJCXBFbnYtPkpTX2FwcEJlZXAoKGludClwYXJhbXNbMF0pOworCisJCXJldHVybiBUUlVFOworCX0KKwllbHNlCisJeworCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CisJCXJldHVybiBGQUxTRTsKKwl9Cit9CisKK0ZYX0JPT0wgYXBwOjpmaW5kQ29tcG9uZW50KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGFwcDo6cG9wVXBNZW51RXgoT0JKX01FVEhPRF9QQVJBTVMpCit7CQorCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBhcHA6OmZzKE9CSl9QUk9QX1BBUkFNUykKK3sKKyNpZmRlZiBGT1hJVF9DSFJPTUVfQlVJTEQKKwlyZXR1cm4gRkFMU0U7CisjZWxzZQorCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlpZiAodnAuSXNHZXR0aW5nKCkpCisJeworCQlyZXR1cm4gVFJVRTsKKwl9CisJZWxzZQorCXsKKwkJcmV0dXJuIFRSVUU7CisJfQorI2VuZGlmCit9CisKK0ZYX0JPT0wgYXBwOjpzZXRJbnRlcnZhbChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlpZiAocGFyYW1zLnNpemUoKSA+IDIgfHwgcGFyYW1zLnNpemUoKSA9PSAwKSAKKwl7CisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsJCisJCXJldHVybiBGQUxTRTsKKwl9CisJCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCUNGWF9XaWRlU3RyaW5nIHNjcmlwdCA9IHBhcmFtcy5zaXplKCkgPiAwID8gIChGWF9MUENXU1RSKShwYXJhbXNbMF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSkgOiAoRlhfTFBDV1NUUilMIiI7CisJaWYgKHNjcmlwdC5Jc0VtcHR5KCkpIAorCXsKKwkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQoKENKU19Db250ZXh0KiljYywgSURTX1NUUklOR19KU0FGTlVNQkVSX0tFWVNUUk9LRSk7CisJCXJldHVybiBUUlVFOworCX0KKworCUZYX0RXT1JEIGR3SW50ZXJ2YWwgPSBwYXJhbXMuc2l6ZSgpID4gMSA/IChpbnQpcGFyYW1zWzFdIDogMTAwMDsKKwkKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwID0gcFJ1bnRpbWUtPkdldFJlYWRlckFwcCgpOworCUFTU0VSVChwQXBwKTsKKwlDSlNfVGltZXIqIHBUaW1lciA9IG5ldyBDSlNfVGltZXIodGhpcywgcEFwcCk7CisJbV9hVGltZXIuQWRkKHBUaW1lcik7CisKKwlwVGltZXItPlNldFR5cGUoMCk7CisJcFRpbWVyLT5TZXRSdW50aW1lKHBSdW50aW1lKTsKKwlwVGltZXItPlNldEpTY3JpcHQoc2NyaXB0KTsKKwlwVGltZXItPlNldFRpbWVPdXQoMCk7CisvLwlwVGltZXItPlNldFN0YXJ0VGltZShHZXRUaWNrQ291bnQoKSk7CisJcFRpbWVyLT5TZXRKU1RpbWVyKGR3SW50ZXJ2YWwpOworCQorCUpTRlhPYmplY3QgcFJldE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIlRpbWVyT2JqIikpOworCQorCUNKU19UaW1lck9iaiogcEpTX1RpbWVyT2JqID0gKENKU19UaW1lck9iaiopSlNfR2V0UHJpdmF0ZShwUnVudGltZS0+R2V0SXNvbGF0ZSgpLHBSZXRPYmopOworCUFTU0VSVChwSlNfVGltZXJPYmogIT0gTlVMTCk7CisJCisJVGltZXJPYmoqIHBUaW1lck9iaiA9IChUaW1lck9iaiopcEpTX1RpbWVyT2JqLT5HZXRFbWJlZE9iamVjdCgpOworCUFTU0VSVChwVGltZXJPYmogIT0gTlVMTCk7CisJCisJcFRpbWVyT2JqLT5TZXRUaW1lcihwVGltZXIpOyAKKwkKKwl2UmV0ID0gcFJldE9iajsKKwkKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBhcHA6OnNldFRpbWVPdXQoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKHBhcmFtcy5zaXplKCkgPiAyIHx8IHBhcmFtcy5zaXplKCkgPT0gMCkKKwl7CisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsJCisJCXJldHVybiBGQUxTRTsKKwl9CisJCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKwkKKwlDRlhfV2lkZVN0cmluZyBzY3JpcHQgPSBwYXJhbXMuc2l6ZSgpID4gMCA/ICAoRlhfTFBDV1NUUikocGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpIDogKEZYX0xQQ1dTVFIpTCIiOworCWlmIChzY3JpcHQuSXNFbXB0eSgpKSAKKwl7CisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNBRk5VTUJFUl9LRVlTVFJPS0UpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJCisJRlhfRFdPUkQgZHdUaW1lT3V0ID0gcGFyYW1zLnNpemUoKSA+IDEgPyAoaW50KXBhcmFtc1sxXSA6IDEwMDA7CisJCisJQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBSdW50aW1lLT5HZXRSZWFkZXJBcHAoKTsKKwlBU1NFUlQocEFwcCk7CisJQ0pTX1RpbWVyKiBwVGltZXIgPSBuZXcgQ0pTX1RpbWVyKHRoaXMsIHBBcHApOworCW1fYVRpbWVyLkFkZChwVGltZXIpOworCQorCXBUaW1lci0+U2V0VHlwZSgxKTsKKwlwVGltZXItPlNldFJ1bnRpbWUocFJ1bnRpbWUpOworCXBUaW1lci0+U2V0SlNjcmlwdChzY3JpcHQpOworCXBUaW1lci0+U2V0VGltZU91dChkd1RpbWVPdXQpOworLy8JcFRpbWVyLT5TZXRTdGFydFRpbWUoR2V0VGlja0NvdW50KCkpOworLy8JcFRpbWVyLT5TZXRKU1RpbWVyKDEwMDApOworCXBUaW1lci0+U2V0SlNUaW1lcihkd1RpbWVPdXQpOworCQorCUpTRlhPYmplY3QgcFJldE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaigqcFJ1bnRpbWUsIHBDb250ZXh0LCBKU19HZXRPYmpEZWZuSUQoKnBSdW50aW1lLCBMIlRpbWVyT2JqIikpOworLy8JQVNTRVJUKHBSZXRPYmogIT0gTlVMTCk7CisJCisJQ0pTX1RpbWVyT2JqKiBwSlNfVGltZXJPYmogPSAoQ0pTX1RpbWVyT2JqKilKU19HZXRQcml2YXRlKHBSdW50aW1lLT5HZXRJc29sYXRlKCkscFJldE9iaik7CisJQVNTRVJUKHBKU19UaW1lck9iaiAhPSBOVUxMKTsKKwkKKwlUaW1lck9iaiogcFRpbWVyT2JqID0gKFRpbWVyT2JqKilwSlNfVGltZXJPYmotPkdldEVtYmVkT2JqZWN0KCk7CisJQVNTRVJUKHBUaW1lck9iaiAhPSBOVUxMKTsKKwkKKwlwVGltZXJPYmotPlNldFRpbWVyKHBUaW1lcik7IAorCQorCXZSZXQgPSBwUmV0T2JqOworCQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGFwcDo6Y2xlYXJUaW1lT3V0KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisJCisJaWYgKHBhcmFtcy5zaXplKCkgIT0gMSkKKwl7CisJCXNFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKChDSlNfQ29udGV4dCopY2MsIElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsJCisJCXJldHVybiBGQUxTRTsKKwl9CisJCisJaWYgKHBhcmFtc1swXS5HZXRUeXBlKCkgPT0gVlRfZnhvYmplY3QpCisJeworCQlKU0ZYT2JqZWN0IHBPYmogPSAoSlNGWE9iamVjdClwYXJhbXNbMF07CisJCXsKKwkJCWlmIChKU19HZXRPYmpEZWZuSUQocE9iaikgPT0gSlNfR2V0T2JqRGVmbklEKCpwUnVudGltZSwgTCJUaW1lck9iaiIpKQorCQkJeworCQkJCWlmIChDSlNfT2JqZWN0KiBwSlNPYmogPSAoQ0pTX09iamVjdCopcGFyYW1zWzBdKQorCQkJCXsKKwkJCQkJaWYgKFRpbWVyT2JqKiBwVGltZXJPYmogPSAoVGltZXJPYmoqKXBKU09iai0+R2V0RW1iZWRPYmplY3QoKSkKKwkJCQkJeworCQkJCQkJaWYgKENKU19UaW1lciogcFRpbWVyID0gcFRpbWVyT2JqLT5HZXRUaW1lcigpKQorCQkJCQkJeworCQkJCQkJCXBUaW1lci0+S2lsbEpTVGltZXIoKTsKKwkJCQkJCQkKKwkJCQkJCQlmb3IgKGludCBpPTAsc3o9bV9hVGltZXIuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQkJCQkJeworCQkJCQkJCQlpZiAobV9hVGltZXJbaV0gPT0gcFRpbWVyKQorCQkJCQkJCQl7CisJCQkJCQkJCQltX2FUaW1lci5SZW1vdmVBdChpKTsKKwkJCQkJCQkJCWJyZWFrOworCQkJCQkJCQl9CisJCQkJCQkJfQorCQkJCQkJCQorCQkJCQkJCWRlbGV0ZSBwVGltZXI7CisJCQkJCQkJcFRpbWVyT2JqLT5TZXRUaW1lcihOVUxMKTsKKwkJCQkJCX0KKwkJCQkJfQorCQkJCX0KKwkJCX0KKwkJfQorCX0KKwkKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBhcHA6OmNsZWFySW50ZXJ2YWwoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCWlmIChwYXJhbXMuc2l6ZSgpICE9IDEpCisJeworCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CQorCQlyZXR1cm4gRkFMU0U7CisJfQorCQorCWlmIChwYXJhbXNbMF0uR2V0VHlwZSgpID09IFZUX2Z4b2JqZWN0KQorCXsKKwkJSlNGWE9iamVjdCBwT2JqID0gKEpTRlhPYmplY3QpcGFyYW1zWzBdOworCQl7CisJCQlpZiAoSlNfR2V0T2JqRGVmbklEKHBPYmopID09IEpTX0dldE9iakRlZm5JRCgqcFJ1bnRpbWUsIEwiVGltZXJPYmoiKSkKKwkJCXsKKwkJCQlpZiAoQ0pTX09iamVjdCogcEpTT2JqID0gKENKU19PYmplY3QqKXBhcmFtc1swXSkKKwkJCQl7CisJCQkJCWlmIChUaW1lck9iaiogcFRpbWVyT2JqID0gKFRpbWVyT2JqKilwSlNPYmotPkdldEVtYmVkT2JqZWN0KCkpCisJCQkJCXsKKwkJCQkJCWlmIChDSlNfVGltZXIqIHBUaW1lciA9IHBUaW1lck9iai0+R2V0VGltZXIoKSkKKwkJCQkJCXsKKwkJCQkJCQlwVGltZXItPktpbGxKU1RpbWVyKCk7CisJCQkJCQkJCisJCQkJCQkJZm9yIChpbnQgaT0wLHN6PW1fYVRpbWVyLkdldFNpemUoKTsgaTxzejsgaSsrKQorCQkJCQkJCXsKKwkJCQkJCQkJaWYgKG1fYVRpbWVyW2ldID09IHBUaW1lcikKKwkJCQkJCQkJeworCQkJCQkJCQkJbV9hVGltZXIuUmVtb3ZlQXQoaSk7CisJCQkJCQkJCQlicmVhazsKKwkJCQkJCQkJfQorCQkJCQkJCX0KKwkJCQkJCQkKKwkJCQkJCQlkZWxldGUgcFRpbWVyOworCQkJCQkJCXBUaW1lck9iai0+U2V0VGltZXIoTlVMTCk7CisJCQkJCQl9CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCX0KKwl9CisJCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgYXBwOjpleGVjTWVudUl0ZW0oT0JKX01FVEhPRF9QQVJBTVMpCit7CQorCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBhcHA6OlRpbWVyUHJvYyhDSlNfVGltZXIqIHBUaW1lcikKK3sKKwlBU1NFUlQocFRpbWVyICE9IE5VTEwpOworCisJc3dpdGNoIChwVGltZXItPkdldFR5cGUoKSkKKwl7CisJY2FzZSAwOiAvL2ludGVydmFsCisJCVJ1bkpzU2NyaXB0KHBUaW1lci0+R2V0UnVudGltZSgpLCBwVGltZXItPkdldEpTY3JpcHQoKSk7CisJCWJyZWFrOworCWNhc2UgMToKKwkJaWYgKHBUaW1lci0+R2V0VGltZU91dCgpID4gMCkKKwkJeworCQkJUnVuSnNTY3JpcHQocFRpbWVyLT5HZXRSdW50aW1lKCksIHBUaW1lci0+R2V0SlNjcmlwdCgpKTsKKwkJCXBUaW1lci0+S2lsbEpTVGltZXIoKTsKKwkJfQorCQlicmVhazsKKwl9CisJCit9CisKK3ZvaWQgYXBwOjpSdW5Kc1NjcmlwdChDSlNfUnVudGltZSogcFJ1bnRpbWUsY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHdzU2NyaXB0KQoreworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCWlmICghcFJ1bnRpbWUtPklzQmxvY2tpbmcoKSkKKwl7CisJCUlGWEpTX0NvbnRleHQqIHBDb250ZXh0ID0gcFJ1bnRpbWUtPk5ld0NvbnRleHQoKTsKKwkJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCQlwQ29udGV4dC0+T25FeHRlcm5hbF9FeGVjKCk7CisJCUNGWF9XaWRlU3RyaW5nIHd0SW5mbzsKKwkJcENvbnRleHQtPlJ1blNjcmlwdCh3c1NjcmlwdCx3dEluZm8pOworCQlwUnVudGltZS0+UmVsZWFzZUNvbnRleHQocENvbnRleHQpOworCX0KK30KKworRlhfQk9PTCBhcHA6OmdvQmFjayhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKworCisJCisJCisJCisJCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgYXBwOjpnb0ZvcndhcmQoT0JKX01FVEhPRF9QQVJBTVMpCit7CQorCisKKworCisKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGFwcDo6bWFpbE1zZyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7CisKKwlGWF9CT09MIGJVSSA9IFRSVUU7CisJQ0ZYX1dpZGVTdHJpbmcgY1RvID0gTCIiOworCUNGWF9XaWRlU3RyaW5nIGNDYyA9IEwiIjsKKwlDRlhfV2lkZVN0cmluZyBjQmNjID0gTCIiOworCUNGWF9XaWRlU3RyaW5nIGNTdWJqZWN0ID0gTCIiOworCUNGWF9XaWRlU3RyaW5nIGNNc2cgPSBMIiI7CisJaWYocGFyYW1zLnNpemUoKSA8IDIpCisJCXJldHVybiBGQUxTRTsKKworCWJVSSA9IHBhcmFtcy5zaXplKCk+PTE/KGludClwYXJhbXNbMF06VFJVRTsKKwljVG8gPSBwYXJhbXMuc2l6ZSgpPj0yPyhjb25zdCB3Y2hhcl90KikoRlhfTFBDV1NUUilwYXJhbXNbMV0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTpMIiI7CisJY0NjID0gcGFyYW1zLnNpemUoKT49Mz8oY29uc3Qgd2NoYXJfdCopKEZYX0xQQ1dTVFIpcGFyYW1zWzJdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk6TCIiOworCWNCY2MgPSBwYXJhbXMuc2l6ZSgpPj00Pyhjb25zdCB3Y2hhcl90KikoRlhfTFBDV1NUUilwYXJhbXNbM10ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTpMIiI7CisJY1N1YmplY3QgPSBwYXJhbXMuc2l6ZSgpPj01Pyhjb25zdCB3Y2hhcl90KikoRlhfTFBDV1NUUilwYXJhbXNbNF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTpMIiI7CisJY01zZyA9IHBhcmFtcy5zaXplKCk+PTY/KGNvbnN0IHdjaGFyX3QqKShGWF9MUENXU1RSKXBhcmFtc1s1XS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOkwiIjsJCQorCisKKwlpZiAocGFyYW1zWzBdLkdldFR5cGUoKSA9PSBWVF9vYmplY3QpCisJeworCQlKU09iamVjdCBwT2JqID0gKEpTT2JqZWN0KXBhcmFtc1swXTsKKworCQl2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosIEwiYlVJIik7CisJCQliVUkgPSAoaW50KUNKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsKKworCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUsIHBPYmosIEwiY1RvIik7CisJCQljVG8gPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjQ2MiKTsKKwkJCWNDYyA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLCBMImNCY2MiKTsKKwkJCWNCY2MgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjU3ViamVjdCIpOworCQkJY1N1YmplY3QgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaiwgTCJjTXNnIik7CisJCQljTXNnID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJfQorCQorCQorCisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCUNQREZEb2NfRW52aXJvbm1lbnQqIHBBcHAgPSBwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCk7CisJQVNTRVJUKHBBcHAgIT0gTlVMTCk7CisKKwlwUnVudGltZS0+QmVnaW5CbG9jaygpOworCXBBcHAtPkpTX2RvY21haWxGb3JtKE5VTEwsIDAsIGJVSSwgKEZYX0xQQ1dTVFIpY1RvLCAoRlhfTFBDV1NUUiljU3ViamVjdCwgKEZYX0xQQ1dTVFIpY0NjLCAoRlhfTFBDV1NUUiljQmNjLCAoRlhfTFBDV1NUUiljTXNnKTsKKwkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLworCXBSdW50aW1lLT5FbmRCbG9jaygpOworCisJLy9yZXR1cm4gYlJldDsKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgYXBwOjpsYXVuY2hVUkwoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKElzU2FmZU1vZGUoY2MpKSByZXR1cm4gVFJVRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJCisKKworCUNGWF9XaWRlU3RyaW5nIHN3VVJMID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisKKwlDSlNfUnVudGltZSogcFJ1bnRpbWUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCk7CisJQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOworCisJcFJ1bnRpbWUtPkJlZ2luQmxvY2soKTsKKy8vCUZYX0JPT0wgYlJldCA9IHBBcHAtPk9wZW5VUkwoc3dVUkwpOworCXBSdW50aW1lLT5FbmRCbG9jaygpOworCisvLwlyZXR1cm4gYlJldDsKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgYXBwOjpydW50aW1lSGlnaGxpZ2h0KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQl2cD4+bV9iUnVudGltZUhpZ2hMaWdodDsKKwl9CisJZWxzZQorCXsKKwkJdnA8PG1fYlJ1bnRpbWVIaWdoTGlnaHQ7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgYXBwOjpmdWxsc2NyZWVuKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgYXBwOjpwb3BVcE1lbnUoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJcmV0dXJuIEZBTFNFOworfQorCisKK0ZYX0JPT0wgYXBwOjpicm93c2VGb3JEb2MoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJLy9UaGlzIG1ldGhvZCBtYXkgdHJpZ2dlciBhICJmaWxlIHNhdmUiIGRpYWxvZyx3aGlsZSBlbmFibGUgdXNlciB0byBzYXZlIGNvbnRlbnRzIG9mIHRoZSBkb2N1bWVudC4KKwkvL1N1Y2ggYWN0aW9uIGlzIGNvbnNpZGVyZWQgdG8gYmUgdW5zYWZlLgorCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOworCisJYm9vbCBiU2F2ZSA9IGZhbHNlOworCUNGWF9CeXRlU3RyaW5nIGNGaWxlbmFtZUluaXQgPSBDRlhfQnl0ZVN0cmluZygpOworCUNGWF9CeXRlU3RyaW5nIGNGU0luaXQgPSBDRlhfQnl0ZVN0cmluZygpOworCisJaWYocGFyYW1zLnNpemUoKT4wICYmIChwYXJhbXNbMF0uR2V0VHlwZSgpID09IFZUX29iamVjdCkpCisJeworCQlKU09iamVjdCBwT2JqID0gKEpTT2JqZWN0IClwYXJhbXNbMF07CisKKyAJCXY4OjpIYW5kbGU8djg6OlZhbHVlPiBwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaixMImJTYXZlIik7CisgCQkJYlNhdmUgPSAoYm9vbClDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7CisgCQkKKwkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLCBwT2JqLEwiY0ZpbGVuYW1lSW5pdCIpOworCQl7CisJCQlDSlNfVmFsdWUgdCA9IENKU19WYWx1ZShpc29sYXRlLCBwVmFsdWUsIEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpOworIAkJCWNGaWxlbmFtZUluaXQgPSB0Lm9wZXJhdG9yIENGWF9CeXRlU3RyaW5nKCk7CisJCX0KKyAJCQorCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaixMImNGU0luaXQiKTsKKwkJeworCQkJQ0pTX1ZhbHVlIHQgPSBDSlNfVmFsdWUoaXNvbGF0ZSwgcFZhbHVlLCBHRVRfVkFMVUVfVFlQRShwVmFsdWUpKTsKKwkJCWNGU0luaXQgPSB0Lm9wZXJhdG9yIENGWF9CeXRlU3RyaW5nKCk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJaWYocGFyYW1zLnNpemUoKSA+PSAxKQorCQl7CisJCQliU2F2ZSA9IChib29sKXBhcmFtc1swXTsKKwkJfQorCQlpZihwYXJhbXMuc2l6ZSgpID49IDIpCisJCXsKKwkJCUNKU19WYWx1ZSB0ID0gcGFyYW1zWzFdOworCQkJY0ZpbGVuYW1lSW5pdCA9IHQub3BlcmF0b3IgQ0ZYX0J5dGVTdHJpbmcoKTsKKwkJfQorCQlpZihwYXJhbXMuc2l6ZSgpID49IDMpCisJCXsKKwkJCUNKU19WYWx1ZSB0ID0gcGFyYW1zWzJdOworCQkJY0ZTSW5pdCA9IHQub3BlcmF0b3IgQ0ZYX0J5dGVTdHJpbmcoKTsKKwkJfQorCX0KKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQgKiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJCisJQ1BERkRvY19FbnZpcm9ubWVudCogcEFwcCA9IHBDb250ZXh0LT5HZXRSZWFkZXJBcHAoKTsKKwlBU1NFUlQocEFwcCAhPSBOVUxMKTsKKworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlDRlhfV2lkZVN0cmluZyB3c0ZpbGVOYW1lSW5pdCA9IENGWF9XaWRlU3RyaW5nOjpGcm9tTG9jYWwoY0ZpbGVuYW1lSW5pdCk7CisJQ0ZYX1dpZGVTdHJpbmcgd3NGU0luaXQgPSBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNGU0luaXQpOworCUNGWF9XaWRlU3RyaW5nIHdzRmlsZVBhdGggPSBwQXBwLT5KU19hcHBicm93c2VGb3JEb2MoYlNhdmUsIHdzRmlsZU5hbWVJbml0KTsKKwlpZih3c0ZpbGVQYXRoLklzRW1wdHkoKSkKKwkJcmV0dXJuIEZBTFNFOworCisJSlNGWE9iamVjdCBwUmV0T2JqID0gSlNfTmV3RnhEeW5hbWljT2JqKCpwUnVudGltZSwgcENvbnRleHQsIC0xKTsKKworCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBSZXRPYmosIEwiY1BhdGgiLCBTeXNQYXRoVG9QREZQYXRoKHdzRmlsZVBhdGgpKTsJCisJSlNfUHV0T2JqZWN0U3RyaW5nKGlzb2xhdGUscFJldE9iaiwgTCJjVVJMIiwgU3lzUGF0aFRvUERGUGF0aCh3c0ZpbGVQYXRoKSk7CisKKwlpZiAoIWNGU0luaXQuSXNFbXB0eSgpKQorCXsKKwkJSlNfUHV0T2JqZWN0U3RyaW5nKGlzb2xhdGUscFJldE9iaiwgTCJjRlMiLCBDRlhfV2lkZVN0cmluZzo6RnJvbUxvY2FsKGNGU0luaXQuR2V0QnVmZmVyKGNGU0luaXQuR2V0TGVuZ3RoKCkpKSk7CisJfQorCWVsc2UKKwl7CisJCUpTX1B1dE9iamVjdFN0cmluZyhpc29sYXRlLHBSZXRPYmosIEwiY0ZTIiwgQ0ZYX1dpZGVTdHJpbmc6OkZyb21Mb2NhbCgiRE9TIikpOworCX0KKwkKKwl2UmV0ID0gIHBSZXRPYmo7CisKKwlyZXR1cm4gVFJVRTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgYXBwOjpTeXNQYXRoVG9QREZQYXRoKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzT2xkUGF0aCkKK3sKKwlDRlhfV2lkZVN0cmluZyBzUmV0ID0gTCIvIjsKKwkKKwlmb3IgKGludCBpPTAsc3o9c09sZFBhdGguR2V0TGVuZ3RoKCk7IGk8c3o7IGkrKykKKwl7CisJCXdjaGFyX3QgYyA9IHNPbGRQYXRoLkdldEF0KGkpOworCQlpZiAoYyA9PSBMJzonKQorCQl7CisJCX0KKwkJZWxzZQorCQl7CisJCQlpZiAoYyA9PSBMJ1xcJykKKwkJCXsKKwkJCQlzUmV0ICs9IEwiLyI7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJc1JldCArPSBjOworCQkJfQorCQl9CisJfQorCQorCXJldHVybiBzUmV0OworfQorCitDRlhfV2lkZVN0cmluZyBhcHA6OlBERlBhdGhUb1N5c1BhdGgoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNPbGRQYXRoKQoreworCS8vc3RyTFBhdGggPSAiRDpcdGVtcG9yYXkuZmRmIjsKKwlDRlhfV2lkZVN0cmluZyBzdHJPUGF0aCA9IHNPbGRQYXRoOworCXN0ck9QYXRoLlRyaW1MZWZ0KCk7CisJc3RyT1BhdGguVHJpbVJpZ2h0KCk7CisJCisJaWYgKHN0ck9QYXRoLkdldEF0KDApID09IEwnLycgJiYgc3RyT1BhdGguR2V0QXQoMikgPT0gTCcvJykKKwl7CisJCXdjaGFyX3QgY19Ecml2ZSA9IHN0ck9QYXRoLkdldEF0KDEpOworCQlpZiAoKGNfRHJpdmUgPj0gTCdhJyAmJiBjX0RyaXZlIDw9IEwneicgKXx8KCBjX0RyaXZlID49IEwnQScgJiYgY19Ecml2ZSA8PSBMJ1onKSkKKwkJeworCQkJc3RyT1BhdGguUmVwbGFjZSgoRlhfTFBDV1NUUilMIi8iLChGWF9MUENXU1RSKUwiXFwiKTsKKwkJCS8vc3RyT1BhdGguU2V0QXQoMCwnJyk7CisJCQlzdHJPUGF0aC5JbnNlcnQoMiwnOicpOworCQkJc3RyT1BhdGguRGVsZXRlKDApOworCQl9CisJfQorCQorCXJldHVybiBzdHJPUGF0aDsKK30KKworQ0ZYX1dpZGVTdHJpbmcgYXBwOjpSZWxhdGl2ZVBhdGhUb1N5c1BhdGgoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNPbGRQYXRoLCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc0ZpbGVQYXRoKQoreworLy8JaWYgKCFQYXRoSXNSZWxhdGl2ZShzT2xkUGF0aCkpIHJldHVybiBzT2xkUGF0aDsKKwkKKwlpbnQgblNwbGl0ID0gMDsKKwlmb3IgKGludCBpPXNGaWxlUGF0aC5HZXRMZW5ndGgoKS0xOyBpPj0wOyBpLS0pCisJeworCQlpZiAoc0ZpbGVQYXRoW2ldID09ICdcXCcgfHwgc0ZpbGVQYXRoW2ldID09ICcvJykKKwkJeworCQkJblNwbGl0ID0gaTsKKwkJCWJyZWFrOworCQl9CisJfQorCQorCXJldHVybiBzRmlsZVBhdGguTGVmdChuU3BsaXQrMSkgKyBzT2xkUGF0aDsKK30KKworRlhfQk9PTCBhcHA6Om5ld0RvYyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgYXBwOjpvcGVuRG9jKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBhcHA6OnJlc3BvbnNlKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCUNGWF9XaWRlU3RyaW5nIHN3UXVlc3Rpb24gPSBMIiI7CisJQ0ZYX1dpZGVTdHJpbmcgc3dMYWJlbCA9IEwiIjsKKyNpZm5kZWYgRk9YSVRfQ0hST01FX0JVSUxECisJQ0ZYX1dpZGVTdHJpbmcgc3dUaXRsZSA9IEwiRm94aXQiOworI2Vsc2UKKwlDRlhfV2lkZVN0cmluZyBzd1RpdGxlID0gTCJQREYiOworI2VuZGlmCisJQ0ZYX1dpZGVTdHJpbmcgc3dEZWZhdWx0ID0gTCIiOworCUNGWF9XaWRlU3RyaW5nIHN3UmVzcG9uc2UgPSBMIiI7CisJYm9vbCBiUGFzc1dvcmQgPSBmYWxzZTsKKwkKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOworCQorCWludCBpTGVuZ3RoID0gcGFyYW1zLnNpemUoKTsJCisJaWYgKGlMZW5ndGggPiAwICYmIHBhcmFtc1swXS5HZXRUeXBlKCkgPT0gVlRfb2JqZWN0KQorCXsKKwkJCisJCUpTT2JqZWN0IHBPYmogPSAoSlNPYmplY3QgKXBhcmFtc1swXTsKKwkJdjg6OkhhbmRsZTx2ODo6VmFsdWU+IHBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLEwiY1F1ZXN0aW9uIik7CisJCQlzd1F1ZXN0aW9uID0gQ0pTX1ZhbHVlKGlzb2xhdGUscFZhbHVlLEdFVF9WQUxVRV9UWVBFKHBWYWx1ZSkpLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisKKwkJcFZhbHVlID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLHBPYmosTCJjVGl0bGUiKTsKKwkJCXN3VGl0bGUgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaixMImNEZWZhdWx0Iik7CisJCQlzd0RlZmF1bHQgPSBDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSkub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKTsKKworCQlwVmFsdWUgPSBKU19HZXRPYmplY3RFbGVtZW50KGlzb2xhdGUscE9iaixMImNMYWJlbCIpOworCQkJc3dMYWJlbCA9IENKU19WYWx1ZShpc29sYXRlLHBWYWx1ZSxHRVRfVkFMVUVfVFlQRShwVmFsdWUpKS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCisJCXBWYWx1ZSA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSxwT2JqLEwiYlBhc3N3b3JkIik7CisJCQliUGFzc1dvcmQgPSAoYm9vbClDSlNfVmFsdWUoaXNvbGF0ZSxwVmFsdWUsR0VUX1ZBTFVFX1RZUEUocFZhbHVlKSk7CisJfQorCWVsc2UKKwl7CisJCXN3aXRjaChpTGVuZ3RoKQorCQl7CisJCWNhc2UgMToKKwkJCXN3UXVlc3Rpb24gPSBwYXJhbXNbMF07CisJCQlicmVhazsKKwkJY2FzZSAyOgorCQkJc3dRdWVzdGlvbiA9IHBhcmFtc1swXTsKKwkJCXN3VGl0bGUgPSBwYXJhbXNbMV07CisJCQlicmVhazsKKwkJY2FzZSAzOgorCQkJc3dRdWVzdGlvbiA9IHBhcmFtc1swXTsKKwkJCXN3VGl0bGUgPSBwYXJhbXNbMV07CisJCQlzd0RlZmF1bHQgPSBwYXJhbXNbMl07CisJCQlicmVhazsKKwkJY2FzZSA0OgorCQkJc3dRdWVzdGlvbiA9IHBhcmFtc1swXTsKKwkJCXN3VGl0bGUgPSBwYXJhbXNbMV07CisJCQlzd0RlZmF1bHQgPSBwYXJhbXNbMl07CisJCQliUGFzc1dvcmQgPSBwYXJhbXNbM107CisJCQlicmVhazsKKwkJY2FzZSA1OgorCQkJc3dRdWVzdGlvbiA9IHBhcmFtc1swXTsKKwkJCXN3VGl0bGUgPSBwYXJhbXNbMV07CisJCQlzd0RlZmF1bHQgPSBwYXJhbXNbMl07CisJCQliUGFzc1dvcmQgPSBwYXJhbXNbM107CisJCQlzd0xhYmVsID0gcGFyYW1zWzRdOworCQkJYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlicmVhazsKKwkJfQorCX0KKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOworIAlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwlDUERGRG9jX0Vudmlyb25tZW50KiBwQXBwID0gcENvbnRleHQtPkdldFJlYWRlckFwcCgpOworIAlBU1NFUlQocEFwcCAhPSBOVUxMKTsKKwlpbnQgbkxlbmd0aCA9IDIwNDg7CisJY2hhciogcEJ1ZmYgPSBuZXcgY2hhcltuTGVuZ3RoXTsKKwluTGVuZ3RoID0gcEFwcC0+SlNfYXBwUmVzcG9uc2Uoc3dRdWVzdGlvbiwgc3dUaXRsZSwgc3dEZWZhdWx0LCBzd0xhYmVsLCBiUGFzc1dvcmQsIHBCdWZmLCBuTGVuZ3RoKTsKKwlpZihuTGVuZ3RoPD0wKQorCXsKKwkJdlJldC5TZXROdWxsKCk7CisJCXJldHVybiBGQUxTRTsKKwl9CisJZWxzZQorCXsKKwkJbkxlbmd0aCA9IG5MZW5ndGg+MjA0Nj8yMDQ2Om5MZW5ndGg7CisgICAgcEJ1ZmZbbkxlbmd0aF0gPSAwOworICAgIHBCdWZmW25MZW5ndGgrMV0gPSAwOworCQlzd1Jlc3BvbnNlID0gQ0ZYX1dpZGVTdHJpbmc6OkZyb21VVEYxNkxFKCh1bnNpZ25lZCBzaG9ydCopcEJ1ZmYsIG5MZW5ndGgpOworCQl2UmV0ID0gc3dSZXNwb25zZTsKKwl9CisJZGVsZXRlW10gcEJ1ZmY7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBhcHA6Om1lZGlhKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgYXBwOjpleGVjRGlhbG9nKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXJldHVybiBUUlVFOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L2NvbG9yLmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvY29sb3IuY3BwCmluZGV4IGRlNWE1M2YuLjM4NDE3MDYgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvY29sb3IuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvY29sb3IuY3BwCkBAIC0xLDI1MyArMSwyNTMgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvY29sb3IuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIg0KLQ0KLXN0YXRpYyB2ODo6SXNvbGF0ZSogR2V0SXNvbGF0ZShJRlhKU19Db250ZXh0KiBjYykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotDQotCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsNCi0JQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOw0KLQ0KLQlyZXR1cm4gcFJ1bnRpbWUtPkdldElzb2xhdGUoKTsNCi19DQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29sb3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1CRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX0NvbG9yKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19Db2xvcikNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoYmxhY2spDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGJsdWUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGN5YW4pCQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShka0dyYXkpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGdyYXkpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGdyZWVuKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShsdEdyYXkpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG1hZ2VudGEpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHJlZCkJDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHRyYW5zcGFyZW50KQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWSh3aGl0ZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoeWVsbG93KQ0KLUVORF9KU19TVEFUSUNfUFJPUCgpDQotDQotQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfQ29sb3IpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoY29udmVydCwgMikNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShlcXVhbCwgMikNCi1FTkRfSlNfU1RBVElDX01FVEhPRCgpDQotDQotSU1QTEVNRU5UX0pTX0NMQVNTKENKU19Db2xvcixjb2xvcikNCi0NCi1jb2xvcjo6Y29sb3IoQ0pTX09iamVjdCogcEpTT2JqZWN0KTogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCkNCi17DQotCW1fY3JUcmFuc3BhcmVudCA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1RSQU5TUEFSRU5UKTsNCi0JbV9jckJsYWNrID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMCk7DQotCW1fY3JXaGl0ZSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDEpOw0KLQltX2NyUmVkID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLCAxLCAwICwwKTsNCi0JbV9jckdyZWVuID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLCAwLCAxICwwKTsNCi0JbV9jckJsdWUgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDAsIDAgLDEpOw0KLQltX2NyQ3lhbiA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0NNWUssIDEsIDAgLDAsIDApOw0KLQltX2NyTWFnZW50YSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0NNWUssIDAsIDEgLDAsIDApOw0KLQltX2NyWWVsbG93ID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfQ01ZSywgMCwgMCAsMSwgMCk7DQotCW1fY3JES0dyYXkgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLCAwLjI1KTsNCi0JbV9jckdyYXkgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLCAwLjUpOw0KLQltX2NyTFRHcmF5ID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMC43NSk7DQotfQ0KLQ0KLWNvbG9yOjp+Y29sb3Iodm9pZCkNCi17DQotfQ0KLQ0KLXZvaWQgY29sb3I6OkNvbnZlcnRQV0xDb2xvclRvQXJyYXkoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IsIENKU19BcnJheSYgYXJyYXkpDQotew0KLQlzd2l0Y2ggKGNvbG9yLm5Db2xvclR5cGUpDQotCXsNCi0JY2FzZSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQ6DQotCQlhcnJheS5TZXRFbGVtZW50KDAsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksICJUIikpOw0KLQkJYnJlYWs7DQotCWNhc2UgQ09MT1JUWVBFX0dSQVk6DQotCQlhcnJheS5TZXRFbGVtZW50KDAsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksIkciKSk7DQotCQlhcnJheS5TZXRFbGVtZW50KDEsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksY29sb3IuZkNvbG9yMSkpOw0KLQkJYnJlYWs7DQotCWNhc2UgQ09MT1JUWVBFX1JHQjoNCi0JCWFycmF5LlNldEVsZW1lbnQoMCwgQ0pTX1ZhbHVlKGFycmF5LkdldElzb2xhdGUoKSwiUkdCIikpOw0KLQkJYXJyYXkuU2V0RWxlbWVudCgxLCBDSlNfVmFsdWUoYXJyYXkuR2V0SXNvbGF0ZSgpLGNvbG9yLmZDb2xvcjEpKTsNCi0JCWFycmF5LlNldEVsZW1lbnQoMiwgQ0pTX1ZhbHVlKGFycmF5LkdldElzb2xhdGUoKSxjb2xvci5mQ29sb3IyKSk7DQotCQlhcnJheS5TZXRFbGVtZW50KDMsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksY29sb3IuZkNvbG9yMykpOw0KLQkJYnJlYWs7DQotCWNhc2UgQ09MT1JUWVBFX0NNWUs6DQotCQlhcnJheS5TZXRFbGVtZW50KDAsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksIkNNWUsiKSk7DQotCQlhcnJheS5TZXRFbGVtZW50KDEsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksY29sb3IuZkNvbG9yMSkpOw0KLQkJYXJyYXkuU2V0RWxlbWVudCgyLCBDSlNfVmFsdWUoYXJyYXkuR2V0SXNvbGF0ZSgpLGNvbG9yLmZDb2xvcjIpKTsNCi0JCWFycmF5LlNldEVsZW1lbnQoMywgQ0pTX1ZhbHVlKGFycmF5LkdldElzb2xhdGUoKSxjb2xvci5mQ29sb3IzKSk7DQotCQlhcnJheS5TZXRFbGVtZW50KDQsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksY29sb3IuZkNvbG9yNCkpOw0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotdm9pZCBjb2xvcjo6Q29udmVydEFycmF5VG9QV0xDb2xvcihDSlNfQXJyYXkmIGFycmF5LCBDUFdMX0NvbG9yJiBjb2xvcikNCi17DQotCWludCBuQXJyYXlMZW4gPSBhcnJheS5HZXRMZW5ndGgoKTsNCi0JaWYgKG5BcnJheUxlbiA8IDEpIHJldHVybjsNCi0NCi0JQ0pTX1ZhbHVlIHZhbHVlKGFycmF5LkdldElzb2xhdGUoKSk7DQotCUNGWF9CeXRlU3RyaW5nIHNTcGFjZTsNCi0JYXJyYXkuR2V0RWxlbWVudCgwLCB2YWx1ZSk7DQotCXNTcGFjZSA9IHZhbHVlOw0KLQ0KLQlkb3VibGUgZDEgPSAwOw0KLQlkb3VibGUgZDIgPSAwOw0KLQlkb3VibGUgZDMgPSAwOw0KLQlkb3VibGUgZDQgPSAwOw0KLQ0KLQlpZiAobkFycmF5TGVuID4gMSkNCi0Jew0KLQkJYXJyYXkuR2V0RWxlbWVudCgxLCB2YWx1ZSk7DQotCQlkMSA9IHZhbHVlOw0KLQl9DQotDQotCWlmIChuQXJyYXlMZW4gPiAyKQ0KLQl7DQotCQlhcnJheS5HZXRFbGVtZW50KDIsIHZhbHVlKTsNCi0JCWQyID0gdmFsdWU7DQotCX0NCi0NCi0JaWYgKG5BcnJheUxlbiA+IDMpDQotCXsNCi0JCWFycmF5LkdldEVsZW1lbnQoMywgdmFsdWUpOw0KLQkJZDMgPSB2YWx1ZTsNCi0JfQ0KLQ0KLQlpZiAobkFycmF5TGVuID4gNCkNCi0Jew0KLQkJYXJyYXkuR2V0RWxlbWVudCg0LCB2YWx1ZSk7DQotCQlkNCA9IHZhbHVlOw0KLQl9DQotDQotCWlmIChzU3BhY2UgPT0gIlQiKQ0KLQl7DQotCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1RSQU5TUEFSRU5UKTsNCi0JfQ0KLQllbHNlIGlmIChzU3BhY2UgPT0gIkciKQ0KLQl7DQotCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIChGWF9GTE9BVClkMSk7DQotCX0NCi0JZWxzZSBpZiAoc1NwYWNlID09ICJSR0IiKQ0KLQl7DQotCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgKEZYX0ZMT0FUKWQxLCAoRlhfRkxPQVQpZDIsIChGWF9GTE9BVClkMyk7DQotCX0NCi0JZWxzZSBpZiAoc1NwYWNlID09ICJDTVlLIikNCi0Jew0KLQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9DTVlLLCAoRlhfRkxPQVQpZDEsIChGWF9GTE9BVClkMiwgKEZYX0ZMT0FUKWQzLCAoRlhfRkxPQVQpZDQpOw0KLQl9DQotfQ0KLQ0KLSNkZWZpbmUgSlNfSU1QTEVNRU5UX0NPTE9SUFJPUChwcm9wLCB2YXIpXA0KLUZYX0JPT0wgY29sb3I6OnByb3AoT0JKX1BST1BfUEFSQU1TKVwNCi17XA0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjO1wNCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBwQ29udGV4dC0+R2V0SlNSdW50aW1lKCktPkdldElzb2xhdGUoKTtcDQotCWlmICh2cC5Jc0dldHRpbmcoKSlcDQotCXtcDQotCQlDSlNfQXJyYXkgYXJyYXkoaXNvbGF0ZSk7XA0KLQkJQ29udmVydFBXTENvbG9yVG9BcnJheSh2YXIsIGFycmF5KTtcDQotCQl2cCA8PCBhcnJheTtcDQotCX1cDQotCWVsc2VcDQotCXtcDQotCQlDSlNfQXJyYXkgYXJyYXkoaXNvbGF0ZSk7XA0KLQkJaWYgKCF2cC5Db252ZXJ0VG9BcnJheShhcnJheSkpIHJldHVybiBGQUxTRTtcDQotCQlDb252ZXJ0QXJyYXlUb1BXTENvbG9yKGFycmF5LCB2YXIpO1wNCi0JfVwNCi0JcmV0dXJuIFRSVUU7XA0KLX0NCi0NCi1KU19JTVBMRU1FTlRfQ09MT1JQUk9QKHRyYW5zcGFyZW50LCBtX2NyVHJhbnNwYXJlbnQpDQotSlNfSU1QTEVNRU5UX0NPTE9SUFJPUChibGFjaywgbV9jckJsYWNrKQ0KLUpTX0lNUExFTUVOVF9DT0xPUlBST1Aod2hpdGUsIG1fY3JXaGl0ZSkNCi1KU19JTVBMRU1FTlRfQ09MT1JQUk9QKHJlZCwgbV9jclJlZCkNCi1KU19JTVBMRU1FTlRfQ09MT1JQUk9QKGdyZWVuLCBtX2NyR3JlZW4pDQotSlNfSU1QTEVNRU5UX0NPTE9SUFJPUChibHVlLCBtX2NyQmx1ZSkNCi1KU19JTVBMRU1FTlRfQ09MT1JQUk9QKGN5YW4sIG1fY3JDeWFuKQ0KLUpTX0lNUExFTUVOVF9DT0xPUlBST1AobWFnZW50YSwgbV9jck1hZ2VudGEpDQotSlNfSU1QTEVNRU5UX0NPTE9SUFJPUCh5ZWxsb3csIG1fY3JZZWxsb3cpDQotSlNfSU1QTEVNRU5UX0NPTE9SUFJPUChka0dyYXksIG1fY3JES0dyYXkpDQotSlNfSU1QTEVNRU5UX0NPTE9SUFJPUChncmF5LCBtX2NyR3JheSkNCi1KU19JTVBMRU1FTlRfQ09MT1JQUk9QKGx0R3JheSwgbV9jckxUR3JheSkNCi0NCi1GWF9CT09MIGNvbG9yOjpjb252ZXJ0KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsNCi0JaW50IGlTaXplID0gcGFyYW1zLnNpemUoKTsNCi0JaWYgKGlTaXplIDwgMikgcmV0dXJuIEZBTFNFOw0KLQlDSlNfQXJyYXkgYVNvdXJjZShpc29sYXRlKTsNCi0JaWYgKCFwYXJhbXNbMF0uQ29udmVydFRvQXJyYXkoYVNvdXJjZSkpIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BXTF9Db2xvciBjclNvdXJjZTsNCi0JQ29udmVydEFycmF5VG9QV0xDb2xvcihhU291cmNlLCBjclNvdXJjZSk7DQotDQotCUNGWF9CeXRlU3RyaW5nIHNEZXN0U3BhY2UgPSBwYXJhbXNbMV07DQotDQotCWludCBuQ29sb3JUeXBlID0gQ09MT1JUWVBFX1RSQU5TUEFSRU5UOw0KLQkNCi0JaWYgKHNEZXN0U3BhY2UgPT0gIlQiKQ0KLQl7DQotCQluQ29sb3JUeXBlID0gQ09MT1JUWVBFX1RSQU5TUEFSRU5UOw0KLQl9DQotCWVsc2UgaWYgKHNEZXN0U3BhY2UgPT0gIkciKQ0KLQl7DQotCQluQ29sb3JUeXBlID0gQ09MT1JUWVBFX0dSQVk7DQotCX0NCi0JZWxzZSBpZiAoc0Rlc3RTcGFjZSA9PSAiUkdCIikNCi0Jew0KLQkJbkNvbG9yVHlwZSA9IENPTE9SVFlQRV9SR0I7DQotCX0NCi0JZWxzZSBpZiAoc0Rlc3RTcGFjZSA9PSAiQ01ZSyIpDQotCXsNCi0JCW5Db2xvclR5cGUgPSBDT0xPUlRZUEVfQ01ZSzsNCi0JfQ0KLQ0KLQlDSlNfQXJyYXkgYURlc3QoaXNvbGF0ZSk7DQotCUNQV0xfQ29sb3IgY3JEZXN0ID0gY3JTb3VyY2U7DQotCWNyRGVzdC5Db252ZXJ0Q29sb3JUeXBlKG5Db2xvclR5cGUpOw0KLQlDb252ZXJ0UFdMQ29sb3JUb0FycmF5KGNyRGVzdCwgYURlc3QpOw0KLQl2UmV0ID0gYURlc3Q7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGNvbG9yOjplcXVhbChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7DQotCWlmIChwYXJhbXMuc2l6ZSgpIDwgMikgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDSlNfQXJyYXkgYXJyYXkxKGlzb2xhdGUpLCBhcnJheTIoaXNvbGF0ZSk7DQotDQotCWlmICghcGFyYW1zWzBdLkNvbnZlcnRUb0FycmF5KGFycmF5MSkpIHJldHVybiBGQUxTRTsNCi0JaWYgKCFwYXJhbXNbMV0uQ29udmVydFRvQXJyYXkoYXJyYXkyKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlDUFdMX0NvbG9yIGNvbG9yMTsNCi0JQ1BXTF9Db2xvciBjb2xvcjI7DQotDQotCUNvbnZlcnRBcnJheVRvUFdMQ29sb3IoYXJyYXkxLCBjb2xvcjEpOw0KLQlDb252ZXJ0QXJyYXlUb1BXTENvbG9yKGFycmF5MiwgY29sb3IyKTsNCi0NCi0JY29sb3IxLkNvbnZlcnRDb2xvclR5cGUoY29sb3IyLm5Db2xvclR5cGUpOw0KLQ0KLQl2UmV0ID0gY29sb3IxID09IGNvbG9yMjsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2NvbG9yLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1J1bnRpbWUuaCIKKworc3RhdGljIHY4OjpJc29sYXRlKiBHZXRJc29sYXRlKElGWEpTX0NvbnRleHQqIGNjKQoreworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKworCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsKKwlBU1NFUlQocFJ1bnRpbWUgIT0gTlVMTCk7CisKKwlyZXR1cm4gcFJ1bnRpbWUtPkdldElzb2xhdGUoKTsKK30KKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0JFR0lOX0pTX1NUQVRJQ19DT05TVChDSlNfQ29sb3IpCitFTkRfSlNfU1RBVElDX0NPTlNUKCkKKworQkVHSU5fSlNfU1RBVElDX1BST1AoQ0pTX0NvbG9yKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGJsYWNrKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGJsdWUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoY3lhbikJCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZGtHcmF5KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGdyYXkpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoZ3JlZW4pCisJSlNfU1RBVElDX1BST1BfRU5UUlkobHRHcmF5KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG1hZ2VudGEpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocmVkKQkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh0cmFuc3BhcmVudCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh3aGl0ZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh5ZWxsb3cpCitFTkRfSlNfU1RBVElDX1BST1AoKQorCitCRUdJTl9KU19TVEFUSUNfTUVUSE9EKENKU19Db2xvcikKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGNvbnZlcnQsIDIpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShlcXVhbCwgMikKK0VORF9KU19TVEFUSUNfTUVUSE9EKCkKKworSU1QTEVNRU5UX0pTX0NMQVNTKENKU19Db2xvcixjb2xvcikKKworY29sb3I6OmNvbG9yKENKU19PYmplY3QqIHBKU09iamVjdCk6IENKU19FbWJlZE9iaihwSlNPYmplY3QpCit7CisJbV9jclRyYW5zcGFyZW50ID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfVFJBTlNQQVJFTlQpOworCW1fY3JCbGFjayA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDApOworCW1fY3JXaGl0ZSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDEpOworCW1fY3JSZWQgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDEsIDAgLDApOworCW1fY3JHcmVlbiA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMCwgMSAsMCk7CisJbV9jckJsdWUgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDAsIDAgLDEpOworCW1fY3JDeWFuID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfQ01ZSywgMSwgMCAsMCwgMCk7CisJbV9jck1hZ2VudGEgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9DTVlLLCAwLCAxICwwLCAwKTsKKwltX2NyWWVsbG93ID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfQ01ZSywgMCwgMCAsMSwgMCk7CisJbV9jckRLR3JheSA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDAuMjUpOworCW1fY3JHcmF5ID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMC41KTsKKwltX2NyTFRHcmF5ID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMC43NSk7Cit9CisKK2NvbG9yOjp+Y29sb3Iodm9pZCkKK3sKK30KKwordm9pZCBjb2xvcjo6Q29udmVydFBXTENvbG9yVG9BcnJheShjb25zdCBDUFdMX0NvbG9yJiBjb2xvciwgQ0pTX0FycmF5JiBhcnJheSkKK3sKKwlzd2l0Y2ggKGNvbG9yLm5Db2xvclR5cGUpCisJeworCWNhc2UgQ09MT1JUWVBFX1RSQU5TUEFSRU5UOgorCQlhcnJheS5TZXRFbGVtZW50KDAsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksICJUIikpOworCQlicmVhazsKKwljYXNlIENPTE9SVFlQRV9HUkFZOgorCQlhcnJheS5TZXRFbGVtZW50KDAsIENKU19WYWx1ZShhcnJheS5HZXRJc29sYXRlKCksIkciKSk7CisJCWFycmF5LlNldEVsZW1lbnQoMSwgQ0pTX1ZhbHVlKGFycmF5LkdldElzb2xhdGUoKSxjb2xvci5mQ29sb3IxKSk7CisJCWJyZWFrOworCWNhc2UgQ09MT1JUWVBFX1JHQjoKKwkJYXJyYXkuU2V0RWxlbWVudCgwLCBDSlNfVmFsdWUoYXJyYXkuR2V0SXNvbGF0ZSgpLCJSR0IiKSk7CisJCWFycmF5LlNldEVsZW1lbnQoMSwgQ0pTX1ZhbHVlKGFycmF5LkdldElzb2xhdGUoKSxjb2xvci5mQ29sb3IxKSk7CisJCWFycmF5LlNldEVsZW1lbnQoMiwgQ0pTX1ZhbHVlKGFycmF5LkdldElzb2xhdGUoKSxjb2xvci5mQ29sb3IyKSk7CisJCWFycmF5LlNldEVsZW1lbnQoMywgQ0pTX1ZhbHVlKGFycmF5LkdldElzb2xhdGUoKSxjb2xvci5mQ29sb3IzKSk7CisJCWJyZWFrOworCWNhc2UgQ09MT1JUWVBFX0NNWUs6CisJCWFycmF5LlNldEVsZW1lbnQoMCwgQ0pTX1ZhbHVlKGFycmF5LkdldElzb2xhdGUoKSwiQ01ZSyIpKTsKKwkJYXJyYXkuU2V0RWxlbWVudCgxLCBDSlNfVmFsdWUoYXJyYXkuR2V0SXNvbGF0ZSgpLGNvbG9yLmZDb2xvcjEpKTsKKwkJYXJyYXkuU2V0RWxlbWVudCgyLCBDSlNfVmFsdWUoYXJyYXkuR2V0SXNvbGF0ZSgpLGNvbG9yLmZDb2xvcjIpKTsKKwkJYXJyYXkuU2V0RWxlbWVudCgzLCBDSlNfVmFsdWUoYXJyYXkuR2V0SXNvbGF0ZSgpLGNvbG9yLmZDb2xvcjMpKTsKKwkJYXJyYXkuU2V0RWxlbWVudCg0LCBDSlNfVmFsdWUoYXJyYXkuR2V0SXNvbGF0ZSgpLGNvbG9yLmZDb2xvcjQpKTsKKwkJYnJlYWs7CisJfQorfQorCit2b2lkIGNvbG9yOjpDb252ZXJ0QXJyYXlUb1BXTENvbG9yKENKU19BcnJheSYgYXJyYXksIENQV0xfQ29sb3ImIGNvbG9yKQoreworCWludCBuQXJyYXlMZW4gPSBhcnJheS5HZXRMZW5ndGgoKTsKKwlpZiAobkFycmF5TGVuIDwgMSkgcmV0dXJuOworCisJQ0pTX1ZhbHVlIHZhbHVlKGFycmF5LkdldElzb2xhdGUoKSk7CisJQ0ZYX0J5dGVTdHJpbmcgc1NwYWNlOworCWFycmF5LkdldEVsZW1lbnQoMCwgdmFsdWUpOworCXNTcGFjZSA9IHZhbHVlOworCisJZG91YmxlIGQxID0gMDsKKwlkb3VibGUgZDIgPSAwOworCWRvdWJsZSBkMyA9IDA7CisJZG91YmxlIGQ0ID0gMDsKKworCWlmIChuQXJyYXlMZW4gPiAxKQorCXsKKwkJYXJyYXkuR2V0RWxlbWVudCgxLCB2YWx1ZSk7CisJCWQxID0gdmFsdWU7CisJfQorCisJaWYgKG5BcnJheUxlbiA+IDIpCisJeworCQlhcnJheS5HZXRFbGVtZW50KDIsIHZhbHVlKTsKKwkJZDIgPSB2YWx1ZTsKKwl9CisKKwlpZiAobkFycmF5TGVuID4gMykKKwl7CisJCWFycmF5LkdldEVsZW1lbnQoMywgdmFsdWUpOworCQlkMyA9IHZhbHVlOworCX0KKworCWlmIChuQXJyYXlMZW4gPiA0KQorCXsKKwkJYXJyYXkuR2V0RWxlbWVudCg0LCB2YWx1ZSk7CisJCWQ0ID0gdmFsdWU7CisJfQorCisJaWYgKHNTcGFjZSA9PSAiVCIpCisJeworCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1RSQU5TUEFSRU5UKTsKKwl9CisJZWxzZSBpZiAoc1NwYWNlID09ICJHIikKKwl7CisJCWNvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgKEZYX0ZMT0FUKWQxKTsKKwl9CisJZWxzZSBpZiAoc1NwYWNlID09ICJSR0IiKQorCXsKKwkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIChGWF9GTE9BVClkMSwgKEZYX0ZMT0FUKWQyLCAoRlhfRkxPQVQpZDMpOworCX0KKwllbHNlIGlmIChzU3BhY2UgPT0gIkNNWUsiKQorCXsKKwkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9DTVlLLCAoRlhfRkxPQVQpZDEsIChGWF9GTE9BVClkMiwgKEZYX0ZMT0FUKWQzLCAoRlhfRkxPQVQpZDQpOworCX0KK30KKworI2RlZmluZSBKU19JTVBMRU1FTlRfQ09MT1JQUk9QKHByb3AsIHZhcilcCitGWF9CT09MIGNvbG9yOjpwcm9wKE9CSl9QUk9QX1BBUkFNUylcCit7XAorCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7XAorCXY4OjpJc29sYXRlKiBpc29sYXRlID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpLT5HZXRJc29sYXRlKCk7XAorCWlmICh2cC5Jc0dldHRpbmcoKSlcCisJe1wKKwkJQ0pTX0FycmF5IGFycmF5KGlzb2xhdGUpO1wKKwkJQ29udmVydFBXTENvbG9yVG9BcnJheSh2YXIsIGFycmF5KTtcCisJCXZwIDw8IGFycmF5O1wKKwl9XAorCWVsc2VcCisJe1wKKwkJQ0pTX0FycmF5IGFycmF5KGlzb2xhdGUpO1wKKwkJaWYgKCF2cC5Db252ZXJ0VG9BcnJheShhcnJheSkpIHJldHVybiBGQUxTRTtcCisJCUNvbnZlcnRBcnJheVRvUFdMQ29sb3IoYXJyYXksIHZhcik7XAorCX1cCisJcmV0dXJuIFRSVUU7XAorfQorCitKU19JTVBMRU1FTlRfQ09MT1JQUk9QKHRyYW5zcGFyZW50LCBtX2NyVHJhbnNwYXJlbnQpCitKU19JTVBMRU1FTlRfQ09MT1JQUk9QKGJsYWNrLCBtX2NyQmxhY2spCitKU19JTVBMRU1FTlRfQ09MT1JQUk9QKHdoaXRlLCBtX2NyV2hpdGUpCitKU19JTVBMRU1FTlRfQ09MT1JQUk9QKHJlZCwgbV9jclJlZCkKK0pTX0lNUExFTUVOVF9DT0xPUlBST1AoZ3JlZW4sIG1fY3JHcmVlbikKK0pTX0lNUExFTUVOVF9DT0xPUlBST1AoYmx1ZSwgbV9jckJsdWUpCitKU19JTVBMRU1FTlRfQ09MT1JQUk9QKGN5YW4sIG1fY3JDeWFuKQorSlNfSU1QTEVNRU5UX0NPTE9SUFJPUChtYWdlbnRhLCBtX2NyTWFnZW50YSkKK0pTX0lNUExFTUVOVF9DT0xPUlBST1AoeWVsbG93LCBtX2NyWWVsbG93KQorSlNfSU1QTEVNRU5UX0NPTE9SUFJPUChka0dyYXksIG1fY3JES0dyYXkpCitKU19JTVBMRU1FTlRfQ09MT1JQUk9QKGdyYXksIG1fY3JHcmF5KQorSlNfSU1QTEVNRU5UX0NPTE9SUFJPUChsdEdyYXksIG1fY3JMVEdyYXkpCisKK0ZYX0JPT0wgY29sb3I6OmNvbnZlcnQoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBHZXRJc29sYXRlKGNjKTsKKwlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOworCWlmIChpU2l6ZSA8IDIpIHJldHVybiBGQUxTRTsKKwlDSlNfQXJyYXkgYVNvdXJjZShpc29sYXRlKTsKKwlpZiAoIXBhcmFtc1swXS5Db252ZXJ0VG9BcnJheShhU291cmNlKSkgcmV0dXJuIEZBTFNFOworCisJQ1BXTF9Db2xvciBjclNvdXJjZTsKKwlDb252ZXJ0QXJyYXlUb1BXTENvbG9yKGFTb3VyY2UsIGNyU291cmNlKTsKKworCUNGWF9CeXRlU3RyaW5nIHNEZXN0U3BhY2UgPSBwYXJhbXNbMV07CisKKwlpbnQgbkNvbG9yVHlwZSA9IENPTE9SVFlQRV9UUkFOU1BBUkVOVDsKKwkKKwlpZiAoc0Rlc3RTcGFjZSA9PSAiVCIpCisJeworCQluQ29sb3JUeXBlID0gQ09MT1JUWVBFX1RSQU5TUEFSRU5UOworCX0KKwllbHNlIGlmIChzRGVzdFNwYWNlID09ICJHIikKKwl7CisJCW5Db2xvclR5cGUgPSBDT0xPUlRZUEVfR1JBWTsKKwl9CisJZWxzZSBpZiAoc0Rlc3RTcGFjZSA9PSAiUkdCIikKKwl7CisJCW5Db2xvclR5cGUgPSBDT0xPUlRZUEVfUkdCOworCX0KKwllbHNlIGlmIChzRGVzdFNwYWNlID09ICJDTVlLIikKKwl7CisJCW5Db2xvclR5cGUgPSBDT0xPUlRZUEVfQ01ZSzsKKwl9CisKKwlDSlNfQXJyYXkgYURlc3QoaXNvbGF0ZSk7CisJQ1BXTF9Db2xvciBjckRlc3QgPSBjclNvdXJjZTsKKwljckRlc3QuQ29udmVydENvbG9yVHlwZShuQ29sb3JUeXBlKTsKKwlDb252ZXJ0UFdMQ29sb3JUb0FycmF5KGNyRGVzdCwgYURlc3QpOworCXZSZXQgPSBhRGVzdDsKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGNvbG9yOjplcXVhbChPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOworCWlmIChwYXJhbXMuc2l6ZSgpIDwgMikgcmV0dXJuIEZBTFNFOworCisJQ0pTX0FycmF5IGFycmF5MShpc29sYXRlKSwgYXJyYXkyKGlzb2xhdGUpOworCisJaWYgKCFwYXJhbXNbMF0uQ29udmVydFRvQXJyYXkoYXJyYXkxKSkgcmV0dXJuIEZBTFNFOworCWlmICghcGFyYW1zWzFdLkNvbnZlcnRUb0FycmF5KGFycmF5MikpIHJldHVybiBGQUxTRTsKKworCUNQV0xfQ29sb3IgY29sb3IxOworCUNQV0xfQ29sb3IgY29sb3IyOworCisJQ29udmVydEFycmF5VG9QV0xDb2xvcihhcnJheTEsIGNvbG9yMSk7CisJQ29udmVydEFycmF5VG9QV0xDb2xvcihhcnJheTIsIGNvbG9yMik7CisKKwljb2xvcjEuQ29udmVydENvbG9yVHlwZShjb2xvcjIubkNvbG9yVHlwZSk7CisKKwl2UmV0ID0gY29sb3IxID09IGNvbG9yMjsKKwlyZXR1cm4gVFJVRTsKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9jb25zb2xlLmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvY29uc29sZS5jcHAKaW5kZXggMjVlNTU1OS4uMzUwYjRlMSAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9jb25zb2xlLmNwcAorKysgYi9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L2NvbnNvbGUuY3BwCkBAIC0xLDc4ICsxLDc4IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L2NvbnNvbGUuaCINCi0vLyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfTW9kdWxlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCINCi0vLyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUmVzTWdyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19Db250ZXh0LmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGNvbnNvbGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19Db25zb2xlKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19Db25zb2xlKQ0KLUVORF9KU19TVEFUSUNfUFJPUCgpDQotDQotQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfQ29uc29sZSkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShjbGVhciwgMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShoaWRlLCAwKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHByaW50bG4sIDEpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoc2hvdywgMCkNCi1FTkRfSlNfU1RBVElDX01FVEhPRCgpDQotDQotSU1QTEVNRU5UX0pTX0NMQVNTKENKU19Db25zb2xlLGNvbnNvbGUpDQotDQotI2RlZmluZSBNQVhDT05TT0xFQ09OVEVOVFMJCQkxMDAwMA0KLQ0KLWNvbnNvbGU6OmNvbnNvbGUoQ0pTX09iamVjdCogcEpTT2JqZWN0KTogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCkNCi17DQotfQ0KLQ0KLWNvbnNvbGU6On5jb25zb2xlKCkNCi17DQotfQ0KLQ0KLUZYX0JPT0wgY29uc29sZTo6Y2xlYXIoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQ0KLQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBjb25zb2xlOjpoaWRlKE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0NCi0NCi0JDQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGNvbnNvbGU6OnByaW50bG4oT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpZiAocGFyYW1zLnNpemUoKSA8IDEpDQotCXsNCi0JCXJldHVybiBGQUxTRTsNCi0JfQ0KLSAgDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGNvbnNvbGU6OnNob3coT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvY29uc29sZS5oIgorLy8jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX01vZHVsZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCIKKy8vI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19SZXNNZ3IuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY29uc29sZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19Db25zb2xlKQorRU5EX0pTX1NUQVRJQ19DT05TVCgpCisKK0JFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19Db25zb2xlKQorRU5EX0pTX1NUQVRJQ19QUk9QKCkKKworQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfQ29uc29sZSkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKGNsZWFyLCAwKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoaGlkZSwgMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHByaW50bG4sIDEpCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzaG93LCAwKQorRU5EX0pTX1NUQVRJQ19NRVRIT0QoKQorCitJTVBMRU1FTlRfSlNfQ0xBU1MoQ0pTX0NvbnNvbGUsY29uc29sZSkKKworI2RlZmluZSBNQVhDT05TT0xFQ09OVEVOVFMJCQkxMDAwMAorCitjb25zb2xlOjpjb25zb2xlKENKU19PYmplY3QqIHBKU09iamVjdCk6IENKU19FbWJlZE9iaihwSlNPYmplY3QpCit7Cit9CisKK2NvbnNvbGU6On5jb25zb2xlKCkKK3sKK30KKworRlhfQk9PTCBjb25zb2xlOjpjbGVhcihPQkpfTUVUSE9EX1BBUkFNUykKK3sKKworCisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBjb25zb2xlOjpoaWRlKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCisKKwkKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGNvbnNvbGU6OnByaW50bG4oT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaWYgKHBhcmFtcy5zaXplKCkgPCAxKQorCXsKKwkJcmV0dXJuIEZBTFNFOworCX0KKyAgCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgY29uc29sZTo6c2hvdyhPQkpfTUVUSE9EX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKK30KKworCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvZXZlbnQuY3BwIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9ldmVudC5jcHAKaW5kZXggOTE2OGEyZS4uNTE4ODc2NSAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9ldmVudC5jcHAKKysrIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9ldmVudC5jcHAKQEAgLTEsMzc5ICsxLDM3OSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCINCi0vLyNpbmNsdWRlICIuLi9pbmNsdWRlL0pTX1Jlc01nci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvZXZlbnQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0ZpZWxkLmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gZXZlbnQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1CRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX0V2ZW50KQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19FdmVudCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoY2hhbmdlKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShjaGFuZ2VFeCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoY29tbWl0S2V5KQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShmaWVsZEZ1bGwpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGtleURvd24pDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG1vZGlmaWVyKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShuYW1lKQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShyYykNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkocmljaENoYW5nZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkocmljaENoYW5nZUV4KQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShyaWNoVmFsdWUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHNlbEVuZCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkoc2VsU3RhcnQpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHNoaWZ0KQ0KLQlKU19TVEFUSUNfUFJPUF9FTlRSWShzb3VyY2UpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHRhcmdldCkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkodGFyZ2V0TmFtZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkodHlwZSkNCi0JSlNfU1RBVElDX1BST1BfRU5UUlkodmFsdWUpDQotCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHdpbGxDb21taXQpDQotRU5EX0pTX1NUQVRJQ19QUk9QKCkNCi0NCi1CRUdJTl9KU19TVEFUSUNfTUVUSE9EKENKU19FdmVudCkgIA0KLUVORF9KU19TVEFUSUNfTUVUSE9EKCkNCi0NCi1JTVBMRU1FTlRfSlNfQ0xBU1MoQ0pTX0V2ZW50LGV2ZW50KQ0KLQ0KLWV2ZW50OjpldmVudChDSlNfT2JqZWN0ICogcEpzT2JqZWN0KSA6IENKU19FbWJlZE9iaihwSnNPYmplY3QpICAgICAgICAgICAgICAgICAgICAgICAgICAgDQotew0KLX0NCi0NCi1ldmVudDo6fmV2ZW50KHZvaWQpDQotew0KLX0NCi0NCi1GWF9CT09MIGV2ZW50OjpjaGFuZ2UoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCUNGWF9XaWRlU3RyaW5nICZ3Q2hhbmdlID0gcEV2ZW50LT5DaGFuZ2UoKTsNCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQlpZiAodnAuR2V0VHlwZSgpID09IFZUX3N0cmluZykNCi0JCQl2cCA+PiB3Q2hhbmdlOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJdnAgPDwgd0NoYW5nZTsNCi0JfQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBldmVudDo6Y2hhbmdlRXgoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7DQotDQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLQl2cCA8PCBwRXZlbnQtPkNoYW5nZUV4KCk7DQotCXJldHVybiBUUlVFOwkNCi19DQotDQotRlhfQk9PTCBldmVudDo6Y29tbWl0S2V5KE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICghdnAuSXNHZXR0aW5nKCkpcmV0dXJuIEZBTFNFOw0KLQ0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsNCi0JQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsNCi0NCi0JdnAgPDwgcEV2ZW50LT5Db21taXRLZXkoKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgZXZlbnQ6OmZpZWxkRnVsbChPQkpfUFJPUF9QQVJBTVMpDQotewkNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCWlmICghdnAuSXNHZXR0aW5nKCkgJiYgd2NzY21wKChjb25zdCB3Y2hhcl90KilwRXZlbnQtPk5hbWUoKSxMIktleXN0cm9rZSIpICE9IDApDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCWlmIChwRXZlbnQtPkZpZWxkRnVsbCgpKQ0KLQkJdnAgPDwgVFJVRTsNCi0JZWxzZQ0KLQkJdnAgPDwgRkFMU0U7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGV2ZW50OjprZXlEb3duKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCWlmICghdnAuSXNHZXR0aW5nKCkpcmV0dXJuIEZBTFNFOw0KLQ0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsNCi0JQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsNCi0NCi0JaWYgKHBFdmVudC0+S2V5RG93bigpKQ0KLQkJdnAgPDwgVFJVRTsNCi0JZWxzZQ0KLQkJdnAgPDwgRkFMU0U7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGV2ZW50Ojptb2RpZmllcihPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCWlmIChwRXZlbnQtPk1vZGlmaWVyKCkpDQotCQl2cCA8PCBUUlVFOw0KLQllbHNlDQotCQl2cCA8PCBGQUxTRTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgZXZlbnQ6Om5hbWUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7DQotDQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLQl2cCA8PCBwRXZlbnQtPk5hbWUoKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgZXZlbnQ6OnJjKE9CSl9QUk9QX1BBUkFNUykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLSAgICBGWF9CT09MICZiUmMgPSBwRXZlbnQtPlJjKCk7DQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJdnA+PmJSYzsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXZwPDxiUmM7DQotCX0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgZXZlbnQ6OnJpY2hDaGFuZ2UoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQl9DQotCWVsc2UNCi0Jew0KLQkJOw0KLQl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGV2ZW50OjpyaWNoQ2hhbmdlRXgoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQl9DQotCWVsc2UNCi0Jew0KLQkJOw0KLQl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0NCi1GWF9CT09MIGV2ZW50OjpyaWNoVmFsdWUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JcmV0dXJuIFRSVUU7DQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQl9DQotCWVsc2UNCi0Jew0KLQkJOw0KLQl9DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGV2ZW50OjpzZWxFbmQoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCWlmICh3Y3NjbXAoKGNvbnN0IHdjaGFyX3QqKXBFdmVudC0+TmFtZSgpLEwiS2V5c3Ryb2tlIikgIT0gMCkNCi0Jew0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0NCi0JaW50ICZpU2VsRW5kID0gcEV2ZW50LT5TZWxFbmQoKTsNCi0JaWYgKHZwLklzU2V0dGluZygpKQ0KLQl7DQotCQl2cCA+PiBpU2VsRW5kOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJdnAgPDwgaVNlbEVuZDsNCi0JfQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBldmVudDo6c2VsU3RhcnQoT0JKX1BST1BfUEFSQU1TKQ0KLXsJDQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAod2NzY21wKChjb25zdCB3Y2hhcl90KilwRXZlbnQtPk5hbWUoKSxMIktleXN0cm9rZSIpICE9IDApDQotCXsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCWludCAmaVNlbFN0YXJ0ID0gcEV2ZW50LT5TZWxTdGFydCgpOw0KLQlpZiAodnAuSXNTZXR0aW5nKCkpDQotCXsNCi0JCXZwID4+IGlTZWxTdGFydDsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXZwIDw8IGlTZWxTdGFydDsNCi0JfQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBldmVudDo6c2hpZnQoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7DQotDQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAocEV2ZW50LT5TaGlmdCgpKQ0KLQkJdnAgPDwgVFJVRTsNCi0JZWxzZQ0KLQkJdnAgPDwgRkFMU0U7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIGV2ZW50Ojpzb3VyY2UoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7CQ0KLQ0KLQlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsNCi0JQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsNCi0NCi0JdnAgPDwgcEV2ZW50LT5Tb3VyY2UoKS0+R2V0SlNPYmplY3QoKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgZXZlbnQ6OnRhcmdldChPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCXZwPDxwRXZlbnQtPlRhcmdldF9GaWVsZCgpLT5HZXRKU09iamVjdCgpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBldmVudDo6dGFyZ2V0TmFtZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCXZwIDw8IHBFdmVudC0+VGFyZ2V0TmFtZSgpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBldmVudDo6dHlwZShPQkpfUFJPUF9QQVJBTVMpDQotew0KLQlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsNCi0NCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCXZwIDw8IHBFdmVudC0+VHlwZSgpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBldmVudDo6dmFsdWUoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7DQotCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7DQotDQotCWlmICh3Y3NjbXAoKGNvbnN0IHdjaGFyX3QqKXBFdmVudC0+VHlwZSgpLEwiRmllbGQiKSAhPSAwKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlpZighcEV2ZW50LT5tX3BWYWx1ZSkNCi0JCXJldHVybiBGQUxTRTsNCi0JQ0ZYX1dpZGVTdHJpbmcgJiB2YWwgPSBwRXZlbnQtPlZhbHVlKCk7DQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJdmFsID0gdnA7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQl2cCA8PCB2YWw7DQotCX0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgZXZlbnQ6OndpbGxDb21taXQoT0JKX1BST1BfUEFSQU1TKQ0KLXsNCi0JaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7DQotDQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7DQotCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsNCi0JQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOw0KLQlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOw0KLQ0KLQlpZiAocEV2ZW50LT5XaWxsQ29tbWl0KCkpDQotCQl2cCA8PCBUUlVFOw0KLQllbHNlDQotCQl2cCA8PCBGQUxTRTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0V2ZW50SGFuZGxlci5oIgorLy8jaW5jbHVkZSAiLi4vaW5jbHVkZS9KU19SZXNNZ3IuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9ldmVudC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9GaWVsZC5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBldmVudCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitCRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX0V2ZW50KQorRU5EX0pTX1NUQVRJQ19DT05TVCgpCisKK0JFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19FdmVudCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShjaGFuZ2UpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoY2hhbmdlRXgpCisJSlNfU1RBVElDX1BST1BfRU5UUlkoY29tbWl0S2V5KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKGZpZWxkRnVsbCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShrZXlEb3duKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG1vZGlmaWVyKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKG5hbWUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocmMpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocmljaENoYW5nZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShyaWNoQ2hhbmdlRXgpCisJSlNfU1RBVElDX1BST1BfRU5UUlkocmljaFZhbHVlKQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHNlbEVuZCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShzZWxTdGFydCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShzaGlmdCkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWShzb3VyY2UpCisJSlNfU1RBVElDX1BST1BfRU5UUlkodGFyZ2V0KQorCUpTX1NUQVRJQ19QUk9QX0VOVFJZKHRhcmdldE5hbWUpCisJSlNfU1RBVElDX1BST1BfRU5UUlkodHlwZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh2YWx1ZSkKKwlKU19TVEFUSUNfUFJPUF9FTlRSWSh3aWxsQ29tbWl0KQorRU5EX0pTX1NUQVRJQ19QUk9QKCkKKworQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfRXZlbnQpICAKK0VORF9KU19TVEFUSUNfTUVUSE9EKCkKKworSU1QTEVNRU5UX0pTX0NMQVNTKENKU19FdmVudCxldmVudCkKKworZXZlbnQ6OmV2ZW50KENKU19PYmplY3QgKiBwSnNPYmplY3QpIDogQ0pTX0VtYmVkT2JqKHBKc09iamVjdCkgICAgICAgICAgICAgICAgICAgICAgICAgICAKK3sKK30KKworZXZlbnQ6On5ldmVudCh2b2lkKQoreworfQorCitGWF9CT09MIGV2ZW50OjpjaGFuZ2UoT0JKX1BST1BfUEFSQU1TKQoreworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJQ0ZYX1dpZGVTdHJpbmcgJndDaGFuZ2UgPSBwRXZlbnQtPkNoYW5nZSgpOworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCWlmICh2cC5HZXRUeXBlKCkgPT0gVlRfc3RyaW5nKQorCQkJdnAgPj4gd0NoYW5nZTsKKwl9CisJZWxzZQorCXsKKwkJdnAgPDwgd0NoYW5nZTsKKwl9CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgZXZlbnQ6OmNoYW5nZUV4KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJdnAgPDwgcEV2ZW50LT5DaGFuZ2VFeCgpOworCXJldHVybiBUUlVFOwkKK30KKworRlhfQk9PTCBldmVudDo6Y29tbWl0S2V5KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJdnAgPDwgcEV2ZW50LT5Db21taXRLZXkoKTsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBldmVudDo6ZmllbGRGdWxsKE9CSl9QUk9QX1BBUkFNUykKK3sJCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOworCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CisKKwlpZiAoIXZwLklzR2V0dGluZygpICYmIHdjc2NtcCgoY29uc3Qgd2NoYXJfdCopcEV2ZW50LT5OYW1lKCksTCJLZXlzdHJva2UiKSAhPSAwKQorCQlyZXR1cm4gRkFMU0U7CisKKwlpZiAocEV2ZW50LT5GaWVsZEZ1bGwoKSkKKwkJdnAgPDwgVFJVRTsKKwllbHNlCisJCXZwIDw8IEZBTFNFOworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGV2ZW50OjprZXlEb3duKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJaWYgKHBFdmVudC0+S2V5RG93bigpKQorCQl2cCA8PCBUUlVFOworCWVsc2UKKwkJdnAgPDwgRkFMU0U7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgZXZlbnQ6Om1vZGlmaWVyKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJaWYgKHBFdmVudC0+TW9kaWZpZXIoKSkKKwkJdnAgPDwgVFJVRTsKKwllbHNlCisJCXZwIDw8IEZBTFNFOworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGV2ZW50OjpuYW1lKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJdnAgPDwgcEV2ZW50LT5OYW1lKCk7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgZXZlbnQ6OnJjKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CisJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKKworICAgIEZYX0JPT0wgJmJSYyA9IHBFdmVudC0+UmMoKTsKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCQl2cD4+YlJjOworCX0KKwllbHNlCisJeworCQl2cDw8YlJjOworCX0KKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBldmVudDo6cmljaENoYW5nZShPQkpfUFJPUF9QQVJBTVMpCit7CisJcmV0dXJuIFRSVUU7CisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwl9CisJZWxzZQorCXsKKwkJOworCX0KKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBldmVudDo6cmljaENoYW5nZUV4KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlyZXR1cm4gVFJVRTsKKwlpZiAodnAuSXNTZXR0aW5nKCkpCisJeworCX0KKwllbHNlCisJeworCQk7CisJfQorCXJldHVybiBUUlVFOworfQorCisKK0ZYX0JPT0wgZXZlbnQ6OnJpY2hWYWx1ZShPQkpfUFJPUF9QQVJBTVMpCit7CisJcmV0dXJuIFRSVUU7CisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwl9CisJZWxzZQorCXsKKwkJOworCX0KKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBldmVudDo6c2VsRW5kKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CisJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKKworCWlmICh3Y3NjbXAoKGNvbnN0IHdjaGFyX3QqKXBFdmVudC0+TmFtZSgpLEwiS2V5c3Ryb2tlIikgIT0gMCkKKwl7CisJCXJldHVybiBUUlVFOworCX0KKworCWludCAmaVNlbEVuZCA9IHBFdmVudC0+U2VsRW5kKCk7CisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJdnAgPj4gaVNlbEVuZDsKKwl9CisJZWxzZQorCXsKKwkJdnAgPDwgaVNlbEVuZDsKKwl9CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgZXZlbnQ6OnNlbFN0YXJ0KE9CSl9QUk9QX1BBUkFNUykKK3sJCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOworCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CisKKwlpZiAod2NzY21wKChjb25zdCB3Y2hhcl90KilwRXZlbnQtPk5hbWUoKSxMIktleXN0cm9rZSIpICE9IDApCisJeworCQlyZXR1cm4gVFJVRTsKKwl9CisJaW50ICZpU2VsU3RhcnQgPSBwRXZlbnQtPlNlbFN0YXJ0KCk7CisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJdnAgPj4gaVNlbFN0YXJ0OworCX0KKwllbHNlCisJeworCQl2cCA8PCBpU2VsU3RhcnQ7CisJfQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGV2ZW50OjpzaGlmdChPQkpfUFJPUF9QQVJBTVMpCit7CisJaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7CisKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CisJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKKworCWlmIChwRXZlbnQtPlNoaWZ0KCkpCisJCXZwIDw8IFRSVUU7CisJZWxzZQorCQl2cCA8PCBGQUxTRTsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBldmVudDo6c291cmNlKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsJCisKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CisJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKKworCXZwIDw8IHBFdmVudC0+U291cmNlKCktPkdldEpTT2JqZWN0KCk7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgZXZlbnQ6OnRhcmdldChPQkpfUFJPUF9QQVJBTVMpCit7CisJaWYgKCF2cC5Jc0dldHRpbmcoKSlyZXR1cm4gRkFMU0U7CisKKwlDSlNfQ29udGV4dCogcENvbnRleHQgPSAoQ0pTX0NvbnRleHQqKWNjOworCUFTU0VSVChwQ29udGV4dCAhPSBOVUxMKTsKKwlDSlNfRXZlbnRIYW5kbGVyKiBwRXZlbnQgPSBwQ29udGV4dC0+R2V0RXZlbnRIYW5kbGVyKCk7CisJQVNTRVJUKHBFdmVudCAhPSBOVUxMKTsKKworCXZwPDxwRXZlbnQtPlRhcmdldF9GaWVsZCgpLT5HZXRKU09iamVjdCgpOworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGV2ZW50Ojp0YXJnZXROYW1lKE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJdnAgPDwgcEV2ZW50LT5UYXJnZXROYW1lKCk7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgZXZlbnQ6OnR5cGUoT0JKX1BST1BfUEFSQU1TKQoreworCWlmICghdnAuSXNHZXR0aW5nKCkpcmV0dXJuIEZBTFNFOworCisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisJQ0pTX0V2ZW50SGFuZGxlciogcEV2ZW50ID0gcENvbnRleHQtPkdldEV2ZW50SGFuZGxlcigpOworCUFTU0VSVChwRXZlbnQgIT0gTlVMTCk7CisKKwl2cCA8PCBwRXZlbnQtPlR5cGUoKTsKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBldmVudDo6dmFsdWUoT0JKX1BST1BfUEFSQU1TKQoreworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJaWYgKHdjc2NtcCgoY29uc3Qgd2NoYXJfdCopcEV2ZW50LT5UeXBlKCksTCJGaWVsZCIpICE9IDApCisJCXJldHVybiBGQUxTRTsKKwlpZighcEV2ZW50LT5tX3BWYWx1ZSkKKwkJcmV0dXJuIEZBTFNFOworCUNGWF9XaWRlU3RyaW5nICYgdmFsID0gcEV2ZW50LT5WYWx1ZSgpOworCWlmICh2cC5Jc1NldHRpbmcoKSkKKwl7CisJCXZhbCA9IHZwOworCX0KKwllbHNlCisJeworCQl2cCA8PCB2YWw7CisJfQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIGV2ZW50Ojp3aWxsQ29tbWl0KE9CSl9QUk9QX1BBUkFNUykKK3sKKwlpZiAoIXZwLklzR2V0dGluZygpKXJldHVybiBGQUxTRTsKKworCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCUNKU19FdmVudEhhbmRsZXIqIHBFdmVudCA9IHBDb250ZXh0LT5HZXRFdmVudEhhbmRsZXIoKTsKKwlBU1NFUlQocEV2ZW50ICE9IE5VTEwpOworCisJaWYgKHBFdmVudC0+V2lsbENvbW1pdCgpKQorCQl2cCA8PCBUUlVFOworCWVsc2UKKwkJdnAgPDwgRkFMU0U7CisJcmV0dXJuIFRSVUU7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvZ2xvYmFsLmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvZ2xvYmFsLmNwcAppbmRleCA5ODRiYTU1Li4yOTVhOGQ0IDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L2dsb2JhbC5jcHAKKysrIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9nbG9iYWwuY3BwCkBAIC0xLDU1MCArMSw1NTAgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfT2JqZWN0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfR2xvYmFsRGF0YS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvZ2xvYmFsLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGdsb2JhbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19HbG9iYWwpDQotRU5EX0pTX1NUQVRJQ19DT05TVCgpDQotDQotQkVHSU5fSlNfU1RBVElDX1BST1AoQ0pTX0dsb2JhbCkNCi1FTkRfSlNfU1RBVElDX1BST1AoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19NRVRIT0QoQ0pTX0dsb2JhbCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShzZXRQZXJzaXN0ZW50LCAyKQ0KLUVORF9KU19TVEFUSUNfTUVUSE9EKCkNCi0NCi1JTVBMRU1FTlRfU1BFQ0lBTF9KU19DTEFTUyhDSlNfR2xvYmFsLCBnbG9iYWxfYWx0ZXJuYXRlLCBnbG9iYWwpOw0KLQ0KLUZYX0JPT0wJQ0pTX0dsb2JhbDo6SW5pdEluc3RhbmNlKElGWEpTX0NvbnRleHQqIGNjKQ0KLXsNCi0JQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsNCi0JQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOw0KLQ0KLQlnbG9iYWxfYWx0ZXJuYXRlKiBwR2xvYmFsID0gKGdsb2JhbF9hbHRlcm5hdGUqKUdldEVtYmVkT2JqZWN0KCk7DQotCUFTU0VSVChwR2xvYmFsICE9IE5VTEwpOw0KLQkNCi0JcEdsb2JhbC0+SW5pdGlhbChwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCkpOw0KLQkNCi0JcmV0dXJuIFRSVUU7DQotfTsNCi0NCi1nbG9iYWxfYWx0ZXJuYXRlOjpnbG9iYWxfYWx0ZXJuYXRlKENKU19PYmplY3QqIHBKU09iamVjdCkNCi0JOiBDSlNfRW1iZWRPYmoocEpTT2JqZWN0KSwNCi0JbV9wQXBwKE5VTEwpDQotew0KLX0NCi0NCi1nbG9iYWxfYWx0ZXJuYXRlOjp+Z2xvYmFsX2FsdGVybmF0ZSh2b2lkKQ0KLXsNCi0JQVNTRVJUKG1fcEFwcCAhPSBOVUxMKTsNCi0NCi0vLwlDb21taXRHbG9iYWxQZXJzaXNpdGVudFZhcmlhYmxlcygpOw0KLQlEZXN0cm95R2xvYmFsUGVyc2lzaXRlbnRWYXJpYWJsZXMoKTsNCi0NCi0JQ0pTX1J1bnRpbWVGYWN0b3J5KiBwRmFjdG9yeSA9IG1fcEFwcC0+bV9wSlNSdW50aW1lRmFjdG9yeTsNCi0JQVNTRVJUKHBGYWN0b3J5KTsNCi0NCi0JcEZhY3RvcnktPlJlbGVhc2VHbG9iYWxEYXRhKCk7DQotfQ0KLSAgDQotdm9pZCBnbG9iYWxfYWx0ZXJuYXRlOjpJbml0aWFsKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHApDQotew0KLQltX3BBcHAgPSBwQXBwOw0KLQ0KLQlDSlNfUnVudGltZUZhY3RvcnkqIHBGYWN0b3J5ID0gcEFwcC0+bV9wSlNSdW50aW1lRmFjdG9yeTsNCi0JQVNTRVJUKHBGYWN0b3J5KTsNCi0JbV9wR2xvYmFsRGF0YSA9IHBGYWN0b3J5LT5OZXdHbG9iYWxEYXRhKHBBcHApOw0KLQlVcGRhdGVHbG9iYWxQZXJzaXN0ZW50VmFyaWFibGVzKCk7DQotfQ0KLQ0KLUZYX0JPT0wJZ2xvYmFsX2FsdGVybmF0ZTo6UXVlcnlQcm9wZXJ0eShGWF9MUENXU1RSIHByb3BuYW1lKQ0KLXsNCi0JcmV0dXJuIENGWF9XaWRlU3RyaW5nKHByb3BuYW1lKSAhPSBMInNldFBlcnNpc3RlbnQiOw0KLX0NCi0NCi1GWF9CT09MCWdsb2JhbF9hbHRlcm5hdGU6OkRlbFByb3BlcnR5KElGWEpTX0NvbnRleHQqIGNjLCBGWF9MUENXU1RSIHByb3BuYW1lLCBKU19FcnJvclN0cmluZyYgc0Vycm9yKQ0KLXsNCi0JanNfZ2xvYmFsX2RhdGEqIHBEYXRhID0gTlVMTDsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHByb3BuYW1lKTsNCi0NCi0JaWYgKG1fbWFwR2xvYmFsLkxvb2t1cChzUHJvcE5hbWUsIChGWF9MUFZPSUQmKXBEYXRhKSkNCi0Jew0KLQkJcERhdGEtPmJEZWxldGVkID0gVFJVRTsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBnbG9iYWxfYWx0ZXJuYXRlOjpEb1Byb3BlcnR5KElGWEpTX0NvbnRleHQqIGNjLCBGWF9MUENXU1RSIHByb3BuYW1lLCBDSlNfUHJvcFZhbHVlJiB2cCwgSlNfRXJyb3JTdHJpbmcmIHNFcnJvcikNCi17DQotCWlmICh2cC5Jc1NldHRpbmcoKSkNCi0Jew0KLQkJQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHByb3BuYW1lKTsNCi0JCXN3aXRjaCAodnAuR2V0VHlwZSgpKQ0KLQkJew0KLQkJY2FzZSBWVF9udW1iZXI6DQotCQkJew0KLQkJCQlkb3VibGUgZERhdGE7DQotCQkJCXZwID4+IGREYXRhOw0KLQkJCQlyZXR1cm4gU2V0R2xvYmFsVmFyaWFibGVzKHNQcm9wTmFtZSwgSlNfR0xPQkFMREFUQV9UWVBFX05VTUJFUiwgZERhdGEsIGZhbHNlLCAiIiwgdjg6OkhhbmRsZTx2ODo6T2JqZWN0PigpLCBGQUxTRSk7DQotCQkJfQ0KLQkJY2FzZSBWVF9ib29sZWFuOg0KLQkJCXsNCi0JCQkJYm9vbCBiRGF0YTsNCi0JCQkJdnAgPj4gYkRhdGE7DQotCQkJCXJldHVybiBTZXRHbG9iYWxWYXJpYWJsZXMoc1Byb3BOYW1lLCBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTiwgMCwgKGJvb2wpdnAsICIiLCB2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KCksIEZBTFNFKTsNCi0JCQl9DQotCQljYXNlIFZUX3N0cmluZzoNCi0JCQl7DQotCQkJCUNGWF9CeXRlU3RyaW5nIHNEYXRhOw0KLQkJCQl2cCA+PiBzRGF0YTsNCi0JCQkJcmV0dXJuIFNldEdsb2JhbFZhcmlhYmxlcyhzUHJvcE5hbWUsIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkcsIDAsIGZhbHNlLCBzRGF0YSwgdjg6OkhhbmRsZTx2ODo6T2JqZWN0PigpLCBGQUxTRSk7DQotCQkJfQ0KLQkJY2FzZSBWVF9vYmplY3Q6DQotCQkJew0KLQkJCQlKU09iamVjdCBwRGF0YSA9IChKU09iamVjdCl2cDsNCi0JCQkJcmV0dXJuIFNldEdsb2JhbFZhcmlhYmxlcyhzUHJvcE5hbWUsIEpTX0dMT0JBTERBVEFfVFlQRV9PQkpFQ1QsIDAsIGZhbHNlLCAiIiwgcERhdGEsIEZBTFNFKTsNCi0vLyAJCQkJZWxzZQ0KLS8vIAkJCQl7DQotLy8gCQkJCQlpZiAodnAuSXNBcnJheU9iamVjdCgpKQ0KLS8vIAkJCQkJew0KLS8vIAkJCQkJCUNKU19BcnJheSBhcnJheTsNCi0vLyAJCQkJCQl2cC5Db252ZXJ0VG9BcnJheShhcnJheSk7DQotLy8gCQkJCQkJcmV0dXJuIFNldEdsb2JhbFZhcmlhYmxlcyhzUHJvcE5hbWUsIEpTX0dMT0JBTERBVEFfVFlQRV9PQkpFQ1QsIDAsIGZhbHNlLCAiIiwgDQotLy8gCQkJCQkJCShEb2JqZWN0KikoRGFycmF5KilhcnJheSwgRkFMU0UpOw0KLS8vIAkJCQkJfQ0KLS8vIAkJCQkJZWxzZQ0KLS8vIAkJCQkJCXJldHVybiBGQUxTRTsNCi0vLyAJCQkJfQ0KLQkJCX0NCi0JCWNhc2UgVlRfbnVsbDoNCi0JCQl7DQotCQkJCXJldHVybiBTZXRHbG9iYWxWYXJpYWJsZXMoc1Byb3BOYW1lLCBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTCwgMCwgZmFsc2UsICIiLCB2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KCksIEZBTFNFKTsNCi0JCQl9DQotCQljYXNlIFZUX3VuZGVmaW5lZDoNCi0JCQl7DQotCQkJCURlbFByb3BlcnR5KGNjLCBwcm9wbmFtZSwgc0Vycm9yKTsNCi0JCQkJcmV0dXJuIFRSVUU7DQotCQkJfQ0KLQkJZGVmYXVsdDoNCi0JCQlyZXR1cm4gRkFMU0U7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlqc19nbG9iYWxfZGF0YSogcERhdGEgPSBOVUxMOw0KLQkJQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHByb3BuYW1lKTsNCi0NCi0JCWlmIChtX21hcEdsb2JhbC5Mb29rdXAoc1Byb3BOYW1lLCAoRlhfTFBWT0lEJilwRGF0YSkpDQotCQl7DQotCQkJaWYgKHBEYXRhKQ0KLQkJCXsNCi0JCQkJaWYgKCFwRGF0YS0+YkRlbGV0ZWQpDQotCQkJCXsNCi0JCQkJCXN3aXRjaCAocERhdGEtPm5UeXBlKQ0KLQkJCQkJew0KLQkJCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOg0KLQkJCQkJCXZwIDw8IHBEYXRhLT5kRGF0YTsNCi0JCQkJCQlicmVhazsNCi0JCQkJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46DQotCQkJCQkJdnAgPDwgcERhdGEtPmJEYXRhOw0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOg0KLQkJCQkJCXZwIDw8IHBEYXRhLT5zRGF0YTsNCi0JCQkJCQlicmVhazsNCi0JCQkJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDoNCi0JCQkJCQl7DQotCQkJCQkJCXY4OjpIYW5kbGU8djg6Ok9iamVjdD4gb2JqID0gdjg6OkxvY2FsPHY4OjpPYmplY3Q+OjpOZXcodnAuR2V0SXNvbGF0ZSgpLHBEYXRhLT5wRGF0YSk7DQotCQkJCQkJCXZwIDw8IG9iajsNCi0JCQkJCQkJYnJlYWs7DQotCQkJCQkJfQ0KLQkJCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTDoNCi0JCQkJCQl2cC5TZXROdWxsKCk7DQotCQkJCQkJYnJlYWs7DQotCQkJCQlkZWZhdWx0Og0KLQkJCQkJCXJldHVybiBGQUxTRTsNCi0JCQkJCX0NCi0JCQkJCXJldHVybiBUUlVFOw0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJcmV0dXJuIFRSVUU7DQotCQkJCX0NCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJdnAuU2V0TnVsbCgpOw0KLQkJCQlyZXR1cm4gVFJVRTsNCi0JCQl9DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJdnAuU2V0TnVsbCgpOw0KLQkJCXJldHVybiBUUlVFOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBnbG9iYWxfYWx0ZXJuYXRlOjpzZXRQZXJzaXN0ZW50KE9CSl9NRVRIT0RfUEFSQU1TKQ0KLXsNCi0JaWYgKHBhcmFtcy5zaXplKCkgIT0gMikNCi0Jew0KLQkJLy9zRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChJRFNfU1RSSU5HX0pTUEFSQU1FUlJPUik7CQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCUNGWF9CeXRlU3RyaW5nIHNOYW1lID0gcGFyYW1zWzBdOw0KLQ0KLQlqc19nbG9iYWxfZGF0YSogcERhdGEgPSBOVUxMOw0KLQlpZiAobV9tYXBHbG9iYWwuTG9va3VwKHNOYW1lLCAoRlhfTFBWT0lEJilwRGF0YSkpDQotCXsNCi0JCWlmIChwRGF0YSAmJiAhcERhdGEtPmJEZWxldGVkKQ0KLQkJew0KLQkJCXBEYXRhLT5iUGVyc2lzdGVudCA9IChib29sKXBhcmFtc1sxXTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCX0NCi0JfQ0KLQ0KLQkvL3NFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKElEU19KU1BBUkFNX0lOQ09SUkVDVCk7CQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgZ2xvYmFsX2FsdGVybmF0ZTo6VXBkYXRlR2xvYmFsUGVyc2lzdGVudFZhcmlhYmxlcygpDQotew0KLQlBU1NFUlQobV9wR2xvYmFsRGF0YSAhPSBOVUxMKTsNCi0NCi0JZm9yIChpbnQgaT0wLHN6PW1fcEdsb2JhbERhdGEtPkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwRGF0YSA9IG1fcEdsb2JhbERhdGEtPkdldEF0KGkpOw0KLQkJQVNTRVJUKHBEYXRhICE9IE5VTEwpOw0KLQ0KLQkJc3dpdGNoIChwRGF0YS0+ZGF0YS5uVHlwZSkNCi0JCXsNCi0JCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTUJFUjoNCi0JCQl0aGlzLT5TZXRHbG9iYWxWYXJpYWJsZXMocERhdGEtPmRhdGEuc0tleSwgSlNfR0xPQkFMREFUQV9UWVBFX05VTUJFUiwgcERhdGEtPmRhdGEuZERhdGEsIGZhbHNlLCAiIiwgdjg6OkhhbmRsZTx2ODo6T2JqZWN0PigpLCBwRGF0YS0+YlBlcnNpc3RlbnQgPT0gMSk7DQotCQkJSlNfUHV0T2JqZWN0TnVtYmVyKE5VTEwsKEpTRlhPYmplY3QpKCptX3BKU09iamVjdCksDQotCQkJCXBEYXRhLT5kYXRhLnNLZXkuVVRGOERlY29kZSgpLCBwRGF0YS0+ZGF0YS5kRGF0YSk7DQotCQkJYnJlYWs7DQotCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOg0KLQkJCXRoaXMtPlNldEdsb2JhbFZhcmlhYmxlcyhwRGF0YS0+ZGF0YS5zS2V5LCBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTiwgMCwgKGJvb2wpKHBEYXRhLT5kYXRhLmJEYXRhID09IDEpLCAiIiwgdjg6OkhhbmRsZTx2ODo6T2JqZWN0PigpLCBwRGF0YS0+YlBlcnNpc3RlbnQgPT0gMSk7DQotCQkJSlNfUHV0T2JqZWN0Qm9vbGVhbihOVUxMLChKU0ZYT2JqZWN0KSgqbV9wSlNPYmplY3QpLA0KLQkJCQlwRGF0YS0+ZGF0YS5zS2V5LlVURjhEZWNvZGUoKSwgKGJvb2wpKHBEYXRhLT5kYXRhLmJEYXRhID09IDEpKTsNCi0JCQlicmVhazsNCi0JCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORzoNCi0JCQl0aGlzLT5TZXRHbG9iYWxWYXJpYWJsZXMocERhdGEtPmRhdGEuc0tleSwgSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORywgMCwgZmFsc2UsIHBEYXRhLT5kYXRhLnNEYXRhLCB2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KCksIHBEYXRhLT5iUGVyc2lzdGVudCA9PSAxKTsNCi0JCQlKU19QdXRPYmplY3RTdHJpbmcoTlVMTCwoSlNGWE9iamVjdCkoKm1fcEpTT2JqZWN0KSwNCi0JCQkJcERhdGEtPmRhdGEuc0tleS5VVEY4RGVjb2RlKCksIA0KLQkJCQlwRGF0YS0+ZGF0YS5zRGF0YS5VVEY4RGVjb2RlKCkpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOg0KLQkJCXsNCi0JCQkJSUpTX1J1bnRpbWUqIHBSdW50aW1lID0gSlNfR2V0UnVudGltZSgoSlNGWE9iamVjdCkoKm1fcEpTT2JqZWN0KSk7DQotCQkJCXY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaihwUnVudGltZSwgTlVMTCwgLTEpOw0KLQ0KLQkJCQlQdXRPYmplY3RQcm9wZXJ0eShwT2JqLCAmcERhdGEtPmRhdGEpOw0KLQ0KLQkJCQl0aGlzLT5TZXRHbG9iYWxWYXJpYWJsZXMocERhdGEtPmRhdGEuc0tleSwgSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVCwgMCwgZmFsc2UsICIiLCANCi0JCQkJCShKU09iamVjdClwT2JqLCBwRGF0YS0+YlBlcnNpc3RlbnQgPT0gMSk7DQotCQkJCUpTX1B1dE9iamVjdE9iamVjdChOVUxMLChKU0ZYT2JqZWN0KSgqbV9wSlNPYmplY3QpLA0KLQkJCQkJcERhdGEtPmRhdGEuc0tleS5VVEY4RGVjb2RlKCksIChKU09iamVjdClwT2JqKTsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMOg0KLQkJCXRoaXMtPlNldEdsb2JhbFZhcmlhYmxlcyhwRGF0YS0+ZGF0YS5zS2V5LCBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTCwgMCwgZmFsc2UsICIiLCB2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KCksIHBEYXRhLT5iUGVyc2lzdGVudCA9PSAxKTsNCi0JCQlKU19QdXRPYmplY3ROdWxsKE5VTEwsKEpTRlhPYmplY3QpKCptX3BKU09iamVjdCksDQotCQkJCXBEYXRhLT5kYXRhLnNLZXkuVVRGOERlY29kZSgpKTsNCi0JCQlicmVhazsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIGdsb2JhbF9hbHRlcm5hdGU6OkNvbW1pdEdsb2JhbFBlcnNpc2l0ZW50VmFyaWFibGVzKCkNCi17DQotCUFTU0VSVChtX3BHbG9iYWxEYXRhICE9IE5VTEwpOw0KLQ0KLQlGWF9QT1NJVElPTgkgcG9zID0gbV9tYXBHbG9iYWwuR2V0U3RhcnRQb3NpdGlvbigpOw0KLQl3aGlsZSAocG9zKQ0KLQl7DQotCQlDRlhfQnl0ZVN0cmluZyBuYW1lOyANCi0JCWpzX2dsb2JhbF9kYXRhKiBwRGF0YSA9IE5VTEw7DQotCQltX21hcEdsb2JhbC5HZXROZXh0QXNzb2MocG9zLCBuYW1lLCAoRlhfTFBWT0lEJilwRGF0YSk7DQotCQkNCi0JCWlmIChwRGF0YSkNCi0JCXsNCi0JCQlpZiAocERhdGEtPmJEZWxldGVkKQ0KLQkJCXsNCi0JCQkJbV9wR2xvYmFsRGF0YS0+RGVsZXRlR2xvYmFsVmFyaWFibGUobmFtZSk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCXN3aXRjaCAocERhdGEtPm5UeXBlKQ0KLQkJCQl7DQotCQkJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTUJFUjoNCi0JCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlTnVtYmVyKG5hbWUsIHBEYXRhLT5kRGF0YSk7DQotCQkJCQltX3BHbG9iYWxEYXRhLT5TZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQobmFtZSwgcERhdGEtPmJQZXJzaXN0ZW50KTsNCi0JCQkJCWJyZWFrOw0KLQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOg0KLQkJCQkJbV9wR2xvYmFsRGF0YS0+U2V0R2xvYmFsVmFyaWFibGVCb29sZWFuKG5hbWUsIHBEYXRhLT5iRGF0YSk7DQotCQkJCQltX3BHbG9iYWxEYXRhLT5TZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQobmFtZSwgcERhdGEtPmJQZXJzaXN0ZW50KTsNCi0JCQkJCWJyZWFrOw0KLQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc6DQotCQkJCQltX3BHbG9iYWxEYXRhLT5TZXRHbG9iYWxWYXJpYWJsZVN0cmluZyhuYW1lLCBwRGF0YS0+c0RhdGEpOw0KLQkJCQkJbV9wR2xvYmFsRGF0YS0+U2V0R2xvYmFsVmFyaWFibGVQZXJzaXN0ZW50KG5hbWUsIHBEYXRhLT5iUGVyc2lzdGVudCk7DQotCQkJCQlicmVhazsNCi0JCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOg0KLQkJCQkJLy9pZiAocERhdGEtPnBEYXRhKQ0KLQkJCQkJew0KLQkJCQkJCUNKU19HbG9iYWxWYXJpYWJsZUFycmF5IGFycmF5Ow0KLQkJCQkJCXY4OjpIYW5kbGU8djg6Ok9iamVjdD4gb2JqID0gdjg6OkxvY2FsPHY4OjpPYmplY3Q+OjpOZXcoR2V0SlNPYmplY3QoKS0+R2V0SXNvbGF0ZSgpLHBEYXRhLT5wRGF0YSk7DQotCQkJCQkJT2JqZWN0VG9BcnJheShvYmosIGFycmF5KTsNCi0JCQkJCQltX3BHbG9iYWxEYXRhLT5TZXRHbG9iYWxWYXJpYWJsZU9iamVjdChuYW1lLCBhcnJheSk7DQotCQkJCQkJbV9wR2xvYmFsRGF0YS0+U2V0R2xvYmFsVmFyaWFibGVQZXJzaXN0ZW50KG5hbWUsIHBEYXRhLT5iUGVyc2lzdGVudCk7DQotCQkJCQl9DQotCQkJCQlicmVhazsNCi0JCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTDoNCi0JCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlTnVsbChuYW1lKTsNCi0JCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlUGVyc2lzdGVudChuYW1lLCBwRGF0YS0+YlBlcnNpc3RlbnQpOw0KLQkJCQkJYnJlYWs7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBnbG9iYWxfYWx0ZXJuYXRlOjpPYmplY3RUb0FycmF5KHY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaiwgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkmIGFycmF5KQ0KLXsNCi0Jdjg6OkhhbmRsZTx2ODo6QXJyYXk+IHBLZXlMaXN0ID0gSlNfR2V0T2JqZWN0RWxlbWVudE5hbWVzKHBPYmopOw0KLQlpbnQJbk9iakVsZW1lbnRzID0gcEtleUxpc3QtPkxlbmd0aCgpOw0KLQ0KLQl2ODo6TG9jYWw8djg6OkNvbnRleHQ+IGNvbnRleHQgPSBwT2JqLT5DcmVhdGlvbkNvbnRleHQoKTsNCi0Jdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBjb250ZXh0LT5HZXRJc29sYXRlKCk7DQotDQotCWZvciAoaW50IGk9MDsgaTxuT2JqRWxlbWVudHM7IGkrKykNCi0Jew0KLQkJDQotCQlDRlhfV2lkZVN0cmluZyB3cyA9IEpTX1RvU3RyaW5nKEpTX0dldEFycmF5RWxlbW5ldChwS2V5TGlzdCwgaSkpOw0KLQkJQ0ZYX0J5dGVTdHJpbmcgc0tleSA9IHdzLlVURjhFbmNvZGUoKTsNCi0NCi0JCXY4OjpIYW5kbGU8djg6OlZhbHVlPiB2ID0gSlNfR2V0T2JqZWN0RWxlbWVudChpc29sYXRlLCBwT2JqLCAoY29uc3Qgd2NoYXJfdCopKEZYX0xQQ1dTVFIpd3MpOw0KLQkJRlhKU1ZBTFVFVFlQRSB2dCA9IEdFVF9WQUxVRV9UWVBFKHYpOw0KLQkJc3dpdGNoICh2dCkNCi0JCXsNCi0JCWNhc2UgVlRfbnVtYmVyOg0KLQkJCXsNCi0JCQkJQ0pTX0tleVZhbHVlKiBwT2JqRWxlbWVudCA9IG5ldyBDSlNfS2V5VmFsdWU7DQotCQkJCXBPYmpFbGVtZW50LT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI7DQotCQkJCXBPYmpFbGVtZW50LT5zS2V5ID0gc0tleTsNCi0JCQkJcE9iakVsZW1lbnQtPmREYXRhID0gSlNfVG9OdW1iZXIodik7DQotCQkJCWFycmF5LkFkZChwT2JqRWxlbWVudCk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBWVF9ib29sZWFuOg0KLQkJCXsNCi0JCQkJQ0pTX0tleVZhbHVlKiBwT2JqRWxlbWVudCA9IG5ldyBDSlNfS2V5VmFsdWU7DQotCQkJCXBPYmpFbGVtZW50LT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOw0KLQkJCQlwT2JqRWxlbWVudC0+c0tleSA9IHNLZXk7DQotCQkJCXBPYmpFbGVtZW50LT5kRGF0YSA9IEpTX1RvQm9vbGVhbih2KTsNCi0JCQkJYXJyYXkuQWRkKHBPYmpFbGVtZW50KTsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIFZUX3N0cmluZzoNCi0JCQl7DQotCQkJCUNGWF9CeXRlU3RyaW5nIHNWYWx1ZSA9IENKU19WYWx1ZShpc29sYXRlLCB2LCBWVF9zdHJpbmcpOw0KLQkJCQlDSlNfS2V5VmFsdWUqIHBPYmpFbGVtZW50ID0gbmV3IENKU19LZXlWYWx1ZTsNCi0JCQkJcE9iakVsZW1lbnQtPm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORzsNCi0JCQkJcE9iakVsZW1lbnQtPnNLZXkgPSBzS2V5Ow0KLQkJCQlwT2JqRWxlbWVudC0+c0RhdGEgPSBzVmFsdWU7DQotCQkJCWFycmF5LkFkZChwT2JqRWxlbWVudCk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBWVF9vYmplY3Q6DQotCQkJew0KLQkJCQlDSlNfS2V5VmFsdWUqIHBPYmpFbGVtZW50ID0gbmV3IENKU19LZXlWYWx1ZTsNCi0JCQkJcE9iakVsZW1lbnQtPm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDsNCi0JCQkJcE9iakVsZW1lbnQtPnNLZXkgPSBzS2V5Ow0KLQkJCQlPYmplY3RUb0FycmF5KEpTX1RvT2JqZWN0KHYpLCBwT2JqRWxlbWVudC0+b2JqRGF0YSk7DQotCQkJCWFycmF5LkFkZChwT2JqRWxlbWVudCk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBWVF9udWxsOg0KLQkJCXsNCi0JCQkJQ0pTX0tleVZhbHVlKiBwT2JqRWxlbWVudCA9IG5ldyBDSlNfS2V5VmFsdWU7DQotCQkJCXBPYmpFbGVtZW50LT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMOw0KLQkJCQlwT2JqRWxlbWVudC0+c0tleSA9IHNLZXk7DQotCQkJCWFycmF5LkFkZChwT2JqRWxlbWVudCk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJZGVmYXVsdDoNCi0JCQlicmVhazsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIGdsb2JhbF9hbHRlcm5hdGU6OlB1dE9iamVjdFByb3BlcnR5KHY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaiwgQ0pTX0tleVZhbHVlKiBwRGF0YSkNCi17DQotCUFTU0VSVChwRGF0YSAhPSBOVUxMKTsNCi0NCi0JZm9yIChpbnQgaT0wLHN6PXBEYXRhLT5vYmpEYXRhLkNvdW50KCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJQ0pTX0tleVZhbHVlKiBwT2JqRGF0YSA9IHBEYXRhLT5vYmpEYXRhLkdldEF0KGkpOw0KLQkJQVNTRVJUKHBPYmpEYXRhICE9IE5VTEwpOw0KLQ0KLQkJc3dpdGNoIChwT2JqRGF0YS0+blR5cGUpDQotCQl7DQotCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI6DQotCQkJSlNfUHV0T2JqZWN0TnVtYmVyKE5VTEwsKEpTT2JqZWN0KXBPYmosIHBPYmpEYXRhLT5zS2V5LlVURjhEZWNvZGUoKSwgcE9iakRhdGEtPmREYXRhKTsNCi0JCQlicmVhazsNCi0JCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46DQotCQkJSlNfUHV0T2JqZWN0Qm9vbGVhbihOVUxMLChKU09iamVjdClwT2JqLCBwT2JqRGF0YS0+c0tleS5VVEY4RGVjb2RlKCksIChib29sKShwT2JqRGF0YS0+YkRhdGEgPT0gMSkpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOg0KLQkJCUpTX1B1dE9iamVjdFN0cmluZyhOVUxMLChKU09iamVjdClwT2JqLCBwT2JqRGF0YS0+c0tleS5VVEY4RGVjb2RlKCksIHBPYmpEYXRhLT5zRGF0YS5VVEY4RGVjb2RlKCkpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOg0KLQkJCXsNCi0JCQkJSUpTX1J1bnRpbWUqIHBSdW50aW1lID0gSlNfR2V0UnVudGltZSgoSlNGWE9iamVjdCkoKm1fcEpTT2JqZWN0KSk7DQotCQkJCXY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE5ld09iaiA9IEpTX05ld0Z4RHluYW1pY09iaihwUnVudGltZSwgTlVMTCwgLTEpOw0KLQkJCQlQdXRPYmplY3RQcm9wZXJ0eShwTmV3T2JqLCBwT2JqRGF0YSk7DQotCQkJCUpTX1B1dE9iamVjdE9iamVjdChOVUxMLCAoSlNPYmplY3QpcE9iaiwgcE9iakRhdGEtPnNLZXkuVVRGOERlY29kZSgpLCAoSlNPYmplY3QpcE5ld09iaik7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTDoNCi0JCQlKU19QdXRPYmplY3ROdWxsKE5VTEwsKEpTT2JqZWN0KXBPYmosIHBPYmpEYXRhLT5zS2V5LlVURjhEZWNvZGUoKSk7DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBnbG9iYWxfYWx0ZXJuYXRlOjpEZXN0cm95R2xvYmFsUGVyc2lzaXRlbnRWYXJpYWJsZXMoKQ0KLXsNCi0JRlhfUE9TSVRJT04JIHBvcyA9IG1fbWFwR2xvYmFsLkdldFN0YXJ0UG9zaXRpb24oKTsNCi0Jd2hpbGUgKHBvcykNCi0Jew0KLQkJQ0ZYX0J5dGVTdHJpbmcgbmFtZTsgDQotCQlqc19nbG9iYWxfZGF0YSogcERhdGEgPSBOVUxMOw0KLQkJbV9tYXBHbG9iYWwuR2V0TmV4dEFzc29jKHBvcywgbmFtZSwgKEZYX0xQVk9JRCYpcERhdGEpOw0KLQkJZGVsZXRlIHBEYXRhOw0KLQl9DQotDQotCW1fbWFwR2xvYmFsLlJlbW92ZUFsbCgpOw0KLX0NCi0NCi0NCi1GWF9CT09MIGdsb2JhbF9hbHRlcm5hdGU6OlNldEdsb2JhbFZhcmlhYmxlcyhGWF9MUENTVFIgcHJvcG5hbWUsIGludCBuVHlwZSwgDQotCQkJCWRvdWJsZSBkRGF0YSwgYm9vbCBiRGF0YSwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNEYXRhLCBKU09iamVjdCBwRGF0YSwgYm9vbCBiRGVmYXVsdFBlcnNpc3RlbnQpDQotew0KLQlpZiAocHJvcG5hbWUgPT0gTlVMTCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlqc19nbG9iYWxfZGF0YSogcFRlbXAgPSBOVUxMOw0KLQltX21hcEdsb2JhbC5Mb29rdXAocHJvcG5hbWUsIChGWF9MUFZPSUQmKXBUZW1wKTsNCi0NCi0JaWYgKHBUZW1wKQ0KLQl7DQotCQlpZiAocFRlbXAtPmJEZWxldGVkIHx8IHBUZW1wLT5uVHlwZSAhPSBuVHlwZSkNCi0JCXsNCi0JCQlwVGVtcC0+ZERhdGEgPSAwOw0KLQkJCXBUZW1wLT5iRGF0YSA9IDA7DQotCQkJcFRlbXAtPnNEYXRhID0gIiI7DQotCQkJcFRlbXAtPm5UeXBlID0gblR5cGU7DQotCQl9DQotDQotCQlwVGVtcC0+YkRlbGV0ZWQgPSBGQUxTRTsNCi0NCi0JCXN3aXRjaCAoblR5cGUpDQotCQl7DQotCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI6DQotCQkJew0KLQkJCQlwVGVtcC0+ZERhdGEgPSBkRGF0YTsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOg0KLQkJCXsNCi0JCQkJcFRlbXAtPmJEYXRhID0gYkRhdGE7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOg0KLQkJCXsNCi0JCQkJcFRlbXAtPnNEYXRhID0gc0RhdGE7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOg0KLQkJCXsNCi0JCQkJcFRlbXAtPnBEYXRhLlJlc2V0KEpTX0dldFJ1bnRpbWUocERhdGEpLCBwRGF0YSk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTDoNCi0JCQlicmVhazsNCi0JCWRlZmF1bHQ6DQotCQkJcmV0dXJuIEZBTFNFOw0KLQkJfQkNCi0NCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCWpzX2dsb2JhbF9kYXRhKiBwTmV3RGF0YSA9IE5VTEw7DQotDQotCXN3aXRjaCAoblR5cGUpDQotCXsNCi0JY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOg0KLQkJew0KLQkJCXBOZXdEYXRhID0gbmV3IGpzX2dsb2JhbF9kYXRhOw0KLQkJCXBOZXdEYXRhLT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI7DQotCQkJcE5ld0RhdGEtPmREYXRhID0gZERhdGE7DQotCQkJcE5ld0RhdGEtPmJQZXJzaXN0ZW50ID0gYkRlZmF1bHRQZXJzaXN0ZW50Ow0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46DQotCQl7DQotCQkJcE5ld0RhdGEgPSBuZXcganNfZ2xvYmFsX2RhdGE7DQotCQkJcE5ld0RhdGEtPm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU47DQotCQkJcE5ld0RhdGEtPmJEYXRhID0gYkRhdGE7DQotCQkJcE5ld0RhdGEtPmJQZXJzaXN0ZW50ID0gYkRlZmF1bHRQZXJzaXN0ZW50Ow0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORzoNCi0JCXsNCi0JCQlwTmV3RGF0YSA9IG5ldyBqc19nbG9iYWxfZGF0YTsNCi0JCQlwTmV3RGF0YS0+blR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOw0KLQkJCXBOZXdEYXRhLT5zRGF0YSA9IHNEYXRhOw0KLQkJCXBOZXdEYXRhLT5iUGVyc2lzdGVudCA9IGJEZWZhdWx0UGVyc2lzdGVudDsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9PQkpFQ1Q6DQotCQl7DQotCQkJcE5ld0RhdGEgPSBuZXcganNfZ2xvYmFsX2RhdGE7DQotCQkJcE5ld0RhdGEtPm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDsNCi0JCQlwTmV3RGF0YS0+cERhdGEuUmVzZXQoSlNfR2V0UnVudGltZShwRGF0YSksIHBEYXRhKTsNCi0JCQlwTmV3RGF0YS0+YlBlcnNpc3RlbnQgPSBiRGVmYXVsdFBlcnNpc3RlbnQ7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTDoNCi0JCXsNCi0JCQlwTmV3RGF0YSA9IG5ldyBqc19nbG9iYWxfZGF0YTsNCi0JCQlwTmV3RGF0YS0+blR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfTlVMTDsNCi0JCQlwTmV3RGF0YS0+YlBlcnNpc3RlbnQgPSBiRGVmYXVsdFBlcnNpc3RlbnQ7DQotCQl9DQotCQlicmVhazsNCi0JZGVmYXVsdDoNCi0JCXJldHVybiBGQUxTRTsNCi0JfQkNCi0NCi0JbV9tYXBHbG9iYWwuU2V0QXQocHJvcG5hbWUsIChGWF9MUFZPSUQpcE5ld0RhdGEpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfR2xvYmFsRGF0YS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9nbG9iYWwuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRXZlbnRIYW5kbGVyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0NvbnRleHQuaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBnbG9iYWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitCRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX0dsb2JhbCkKK0VORF9KU19TVEFUSUNfQ09OU1QoKQorCitCRUdJTl9KU19TVEFUSUNfUFJPUChDSlNfR2xvYmFsKQorRU5EX0pTX1NUQVRJQ19QUk9QKCkKKworQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfR2xvYmFsKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoc2V0UGVyc2lzdGVudCwgMikKK0VORF9KU19TVEFUSUNfTUVUSE9EKCkKKworSU1QTEVNRU5UX1NQRUNJQUxfSlNfQ0xBU1MoQ0pTX0dsb2JhbCwgZ2xvYmFsX2FsdGVybmF0ZSwgZ2xvYmFsKTsKKworRlhfQk9PTAlDSlNfR2xvYmFsOjpJbml0SW5zdGFuY2UoSUZYSlNfQ29udGV4dCogY2MpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0KiljYzsKKwlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7CisKKwlnbG9iYWxfYWx0ZXJuYXRlKiBwR2xvYmFsID0gKGdsb2JhbF9hbHRlcm5hdGUqKUdldEVtYmVkT2JqZWN0KCk7CisJQVNTRVJUKHBHbG9iYWwgIT0gTlVMTCk7CisJCisJcEdsb2JhbC0+SW5pdGlhbChwQ29udGV4dC0+R2V0UmVhZGVyQXBwKCkpOworCQorCXJldHVybiBUUlVFOworfTsKKworZ2xvYmFsX2FsdGVybmF0ZTo6Z2xvYmFsX2FsdGVybmF0ZShDSlNfT2JqZWN0KiBwSlNPYmplY3QpCisJOiBDSlNfRW1iZWRPYmoocEpTT2JqZWN0KSwKKwltX3BBcHAoTlVMTCkKK3sKK30KKworZ2xvYmFsX2FsdGVybmF0ZTo6fmdsb2JhbF9hbHRlcm5hdGUodm9pZCkKK3sKKwlBU1NFUlQobV9wQXBwICE9IE5VTEwpOworCisvLwlDb21taXRHbG9iYWxQZXJzaXNpdGVudFZhcmlhYmxlcygpOworCURlc3Ryb3lHbG9iYWxQZXJzaXNpdGVudFZhcmlhYmxlcygpOworCisJQ0pTX1J1bnRpbWVGYWN0b3J5KiBwRmFjdG9yeSA9IG1fcEFwcC0+bV9wSlNSdW50aW1lRmFjdG9yeTsKKwlBU1NFUlQocEZhY3RvcnkpOworCisJcEZhY3RvcnktPlJlbGVhc2VHbG9iYWxEYXRhKCk7Cit9CisgIAordm9pZCBnbG9iYWxfYWx0ZXJuYXRlOjpJbml0aWFsKENQREZEb2NfRW52aXJvbm1lbnQqIHBBcHApCit7CisJbV9wQXBwID0gcEFwcDsKKworCUNKU19SdW50aW1lRmFjdG9yeSogcEZhY3RvcnkgPSBwQXBwLT5tX3BKU1J1bnRpbWVGYWN0b3J5OworCUFTU0VSVChwRmFjdG9yeSk7CisJbV9wR2xvYmFsRGF0YSA9IHBGYWN0b3J5LT5OZXdHbG9iYWxEYXRhKHBBcHApOworCVVwZGF0ZUdsb2JhbFBlcnNpc3RlbnRWYXJpYWJsZXMoKTsKK30KKworRlhfQk9PTAlnbG9iYWxfYWx0ZXJuYXRlOjpRdWVyeVByb3BlcnR5KEZYX0xQQ1dTVFIgcHJvcG5hbWUpCit7CisJcmV0dXJuIENGWF9XaWRlU3RyaW5nKHByb3BuYW1lKSAhPSBMInNldFBlcnNpc3RlbnQiOworfQorCitGWF9CT09MCWdsb2JhbF9hbHRlcm5hdGU6OkRlbFByb3BlcnR5KElGWEpTX0NvbnRleHQqIGNjLCBGWF9MUENXU1RSIHByb3BuYW1lLCBKU19FcnJvclN0cmluZyYgc0Vycm9yKQoreworCWpzX2dsb2JhbF9kYXRhKiBwRGF0YSA9IE5VTEw7CisJQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHByb3BuYW1lKTsKKworCWlmIChtX21hcEdsb2JhbC5Mb29rdXAoc1Byb3BOYW1lLCAoRlhfTFBWT0lEJilwRGF0YSkpCisJeworCQlwRGF0YS0+YkRlbGV0ZWQgPSBUUlVFOworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgZ2xvYmFsX2FsdGVybmF0ZTo6RG9Qcm9wZXJ0eShJRlhKU19Db250ZXh0KiBjYywgRlhfTFBDV1NUUiBwcm9wbmFtZSwgQ0pTX1Byb3BWYWx1ZSYgdnAsIEpTX0Vycm9yU3RyaW5nJiBzRXJyb3IpCit7CisJaWYgKHZwLklzU2V0dGluZygpKQorCXsKKwkJQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHByb3BuYW1lKTsKKwkJc3dpdGNoICh2cC5HZXRUeXBlKCkpCisJCXsKKwkJY2FzZSBWVF9udW1iZXI6CisJCQl7CisJCQkJZG91YmxlIGREYXRhOworCQkJCXZwID4+IGREYXRhOworCQkJCXJldHVybiBTZXRHbG9iYWxWYXJpYWJsZXMoc1Byb3BOYW1lLCBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSLCBkRGF0YSwgZmFsc2UsICIiLCB2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KCksIEZBTFNFKTsKKwkJCX0KKwkJY2FzZSBWVF9ib29sZWFuOgorCQkJeworCQkJCWJvb2wgYkRhdGE7CisJCQkJdnAgPj4gYkRhdGE7CisJCQkJcmV0dXJuIFNldEdsb2JhbFZhcmlhYmxlcyhzUHJvcE5hbWUsIEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOLCAwLCAoYm9vbCl2cCwgIiIsIHY4OjpIYW5kbGU8djg6Ok9iamVjdD4oKSwgRkFMU0UpOworCQkJfQorCQljYXNlIFZUX3N0cmluZzoKKwkJCXsKKwkJCQlDRlhfQnl0ZVN0cmluZyBzRGF0YTsKKwkJCQl2cCA+PiBzRGF0YTsKKwkJCQlyZXR1cm4gU2V0R2xvYmFsVmFyaWFibGVzKHNQcm9wTmFtZSwgSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORywgMCwgZmFsc2UsIHNEYXRhLCB2ODo6SGFuZGxlPHY4OjpPYmplY3Q+KCksIEZBTFNFKTsKKwkJCX0KKwkJY2FzZSBWVF9vYmplY3Q6CisJCQl7CisJCQkJSlNPYmplY3QgcERhdGEgPSAoSlNPYmplY3QpdnA7CisJCQkJcmV0dXJuIFNldEdsb2JhbFZhcmlhYmxlcyhzUHJvcE5hbWUsIEpTX0dMT0JBTERBVEFfVFlQRV9PQkpFQ1QsIDAsIGZhbHNlLCAiIiwgcERhdGEsIEZBTFNFKTsKKy8vIAkJCQllbHNlCisvLyAJCQkJeworLy8gCQkJCQlpZiAodnAuSXNBcnJheU9iamVjdCgpKQorLy8gCQkJCQl7CisvLyAJCQkJCQlDSlNfQXJyYXkgYXJyYXk7CisvLyAJCQkJCQl2cC5Db252ZXJ0VG9BcnJheShhcnJheSk7CisvLyAJCQkJCQlyZXR1cm4gU2V0R2xvYmFsVmFyaWFibGVzKHNQcm9wTmFtZSwgSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVCwgMCwgZmFsc2UsICIiLCAKKy8vIAkJCQkJCQkoRG9iamVjdCopKERhcnJheSopYXJyYXksIEZBTFNFKTsKKy8vIAkJCQkJfQorLy8gCQkJCQllbHNlCisvLyAJCQkJCQlyZXR1cm4gRkFMU0U7CisvLyAJCQkJfQorCQkJfQorCQljYXNlIFZUX251bGw6CisJCQl7CisJCQkJcmV0dXJuIFNldEdsb2JhbFZhcmlhYmxlcyhzUHJvcE5hbWUsIEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMLCAwLCBmYWxzZSwgIiIsIHY4OjpIYW5kbGU8djg6Ok9iamVjdD4oKSwgRkFMU0UpOworCQkJfQorCQljYXNlIFZUX3VuZGVmaW5lZDoKKwkJCXsKKwkJCQlEZWxQcm9wZXJ0eShjYywgcHJvcG5hbWUsIHNFcnJvcik7CisJCQkJcmV0dXJuIFRSVUU7CisJCQl9CisJCWRlZmF1bHQ6CisJCQlyZXR1cm4gRkFMU0U7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJanNfZ2xvYmFsX2RhdGEqIHBEYXRhID0gTlVMTDsKKwkJQ0ZYX0J5dGVTdHJpbmcgc1Byb3BOYW1lID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHByb3BuYW1lKTsKKworCQlpZiAobV9tYXBHbG9iYWwuTG9va3VwKHNQcm9wTmFtZSwgKEZYX0xQVk9JRCYpcERhdGEpKQorCQl7CisJCQlpZiAocERhdGEpCisJCQl7CisJCQkJaWYgKCFwRGF0YS0+YkRlbGV0ZWQpCisJCQkJeworCQkJCQlzd2l0Y2ggKHBEYXRhLT5uVHlwZSkKKwkJCQkJeworCQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI6CisJCQkJCQl2cCA8PCBwRGF0YS0+ZERhdGE7CisJCQkJCQlicmVhazsKKwkJCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTjoKKwkJCQkJCXZwIDw8IHBEYXRhLT5iRGF0YTsKKwkJCQkJCWJyZWFrOworCQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc6CisJCQkJCQl2cCA8PCBwRGF0YS0+c0RhdGE7CisJCQkJCQlicmVhazsKKwkJCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOgorCQkJCQkJeworCQkJCQkJCXY4OjpIYW5kbGU8djg6Ok9iamVjdD4gb2JqID0gdjg6OkxvY2FsPHY4OjpPYmplY3Q+OjpOZXcodnAuR2V0SXNvbGF0ZSgpLHBEYXRhLT5wRGF0YSk7CisJCQkJCQkJdnAgPDwgb2JqOworCQkJCQkJCWJyZWFrOworCQkJCQkJfQorCQkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMOgorCQkJCQkJdnAuU2V0TnVsbCgpOworCQkJCQkJYnJlYWs7CisJCQkJCWRlZmF1bHQ6CisJCQkJCQlyZXR1cm4gRkFMU0U7CisJCQkJCX0KKwkJCQkJcmV0dXJuIFRSVUU7CisJCQkJfQorCQkJCWVsc2UKKwkJCQl7CisJCQkJCXJldHVybiBUUlVFOworCQkJCX0KKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQl2cC5TZXROdWxsKCk7CisJCQkJcmV0dXJuIFRSVUU7CisJCQl9CisJCX0KKwkJZWxzZQorCQl7CisJCQl2cC5TZXROdWxsKCk7CisJCQlyZXR1cm4gVFJVRTsKKwkJfQorCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBnbG9iYWxfYWx0ZXJuYXRlOjpzZXRQZXJzaXN0ZW50KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWlmIChwYXJhbXMuc2l6ZSgpICE9IDIpCisJeworCQkvL3NFcnJvciA9IEpTR2V0U3RyaW5nRnJvbUlEKElEU19TVFJJTkdfSlNQQVJBTUVSUk9SKTsJCisJCXJldHVybiBGQUxTRTsKKwl9CisKKwlDRlhfQnl0ZVN0cmluZyBzTmFtZSA9IHBhcmFtc1swXTsKKworCWpzX2dsb2JhbF9kYXRhKiBwRGF0YSA9IE5VTEw7CisJaWYgKG1fbWFwR2xvYmFsLkxvb2t1cChzTmFtZSwgKEZYX0xQVk9JRCYpcERhdGEpKQorCXsKKwkJaWYgKHBEYXRhICYmICFwRGF0YS0+YkRlbGV0ZWQpCisJCXsKKwkJCXBEYXRhLT5iUGVyc2lzdGVudCA9IChib29sKXBhcmFtc1sxXTsKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCisJLy9zRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRChJRFNfSlNQQVJBTV9JTkNPUlJFQ1QpOwkKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgZ2xvYmFsX2FsdGVybmF0ZTo6VXBkYXRlR2xvYmFsUGVyc2lzdGVudFZhcmlhYmxlcygpCit7CisJQVNTRVJUKG1fcEdsb2JhbERhdGEgIT0gTlVMTCk7CisKKwlmb3IgKGludCBpPTAsc3o9bV9wR2xvYmFsRGF0YS0+R2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlDSlNfR2xvYmFsRGF0YV9FbGVtZW50KiBwRGF0YSA9IG1fcEdsb2JhbERhdGEtPkdldEF0KGkpOworCQlBU1NFUlQocERhdGEgIT0gTlVMTCk7CisKKwkJc3dpdGNoIChwRGF0YS0+ZGF0YS5uVHlwZSkKKwkJeworCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI6CisJCQl0aGlzLT5TZXRHbG9iYWxWYXJpYWJsZXMocERhdGEtPmRhdGEuc0tleSwgSlNfR0xPQkFMREFUQV9UWVBFX05VTUJFUiwgcERhdGEtPmRhdGEuZERhdGEsIGZhbHNlLCAiIiwgdjg6OkhhbmRsZTx2ODo6T2JqZWN0PigpLCBwRGF0YS0+YlBlcnNpc3RlbnQgPT0gMSk7CisJCQlKU19QdXRPYmplY3ROdW1iZXIoTlVMTCwoSlNGWE9iamVjdCkoKm1fcEpTT2JqZWN0KSwKKwkJCQlwRGF0YS0+ZGF0YS5zS2V5LlVURjhEZWNvZGUoKSwgcERhdGEtPmRhdGEuZERhdGEpOworCQkJYnJlYWs7CisJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU46CisJCQl0aGlzLT5TZXRHbG9iYWxWYXJpYWJsZXMocERhdGEtPmRhdGEuc0tleSwgSlNfR0xPQkFMREFUQV9UWVBFX0JPT0xFQU4sIDAsIChib29sKShwRGF0YS0+ZGF0YS5iRGF0YSA9PSAxKSwgIiIsIHY4OjpIYW5kbGU8djg6Ok9iamVjdD4oKSwgcERhdGEtPmJQZXJzaXN0ZW50ID09IDEpOworCQkJSlNfUHV0T2JqZWN0Qm9vbGVhbihOVUxMLChKU0ZYT2JqZWN0KSgqbV9wSlNPYmplY3QpLAorCQkJCXBEYXRhLT5kYXRhLnNLZXkuVVRGOERlY29kZSgpLCAoYm9vbCkocERhdGEtPmRhdGEuYkRhdGEgPT0gMSkpOworCQkJYnJlYWs7CisJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORzoKKwkJCXRoaXMtPlNldEdsb2JhbFZhcmlhYmxlcyhwRGF0YS0+ZGF0YS5zS2V5LCBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HLCAwLCBmYWxzZSwgcERhdGEtPmRhdGEuc0RhdGEsIHY4OjpIYW5kbGU8djg6Ok9iamVjdD4oKSwgcERhdGEtPmJQZXJzaXN0ZW50ID09IDEpOworCQkJSlNfUHV0T2JqZWN0U3RyaW5nKE5VTEwsKEpTRlhPYmplY3QpKCptX3BKU09iamVjdCksCisJCQkJcERhdGEtPmRhdGEuc0tleS5VVEY4RGVjb2RlKCksIAorCQkJCXBEYXRhLT5kYXRhLnNEYXRhLlVURjhEZWNvZGUoKSk7CisJCQlicmVhazsKKwkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOgorCQkJeworCQkJCUlKU19SdW50aW1lKiBwUnVudGltZSA9IEpTX0dldFJ1bnRpbWUoKEpTRlhPYmplY3QpKCptX3BKU09iamVjdCkpOworCQkJCXY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaiA9IEpTX05ld0Z4RHluYW1pY09iaihwUnVudGltZSwgTlVMTCwgLTEpOworCisJCQkJUHV0T2JqZWN0UHJvcGVydHkocE9iaiwgJnBEYXRhLT5kYXRhKTsKKworCQkJCXRoaXMtPlNldEdsb2JhbFZhcmlhYmxlcyhwRGF0YS0+ZGF0YS5zS2V5LCBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNULCAwLCBmYWxzZSwgIiIsIAorCQkJCQkoSlNPYmplY3QpcE9iaiwgcERhdGEtPmJQZXJzaXN0ZW50ID09IDEpOworCQkJCUpTX1B1dE9iamVjdE9iamVjdChOVUxMLChKU0ZYT2JqZWN0KSgqbV9wSlNPYmplY3QpLAorCQkJCQlwRGF0YS0+ZGF0YS5zS2V5LlVURjhEZWNvZGUoKSwgKEpTT2JqZWN0KXBPYmopOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTEw6CisJCQl0aGlzLT5TZXRHbG9iYWxWYXJpYWJsZXMocERhdGEtPmRhdGEuc0tleSwgSlNfR0xPQkFMREFUQV9UWVBFX05VTEwsIDAsIGZhbHNlLCAiIiwgdjg6OkhhbmRsZTx2ODo6T2JqZWN0PigpLCBwRGF0YS0+YlBlcnNpc3RlbnQgPT0gMSk7CisJCQlKU19QdXRPYmplY3ROdWxsKE5VTEwsKEpTRlhPYmplY3QpKCptX3BKU09iamVjdCksCisJCQkJcERhdGEtPmRhdGEuc0tleS5VVEY4RGVjb2RlKCkpOworCQkJYnJlYWs7CisJCX0KKwl9Cit9CisKK3ZvaWQgZ2xvYmFsX2FsdGVybmF0ZTo6Q29tbWl0R2xvYmFsUGVyc2lzaXRlbnRWYXJpYWJsZXMoKQoreworCUFTU0VSVChtX3BHbG9iYWxEYXRhICE9IE5VTEwpOworCisJRlhfUE9TSVRJT04JIHBvcyA9IG1fbWFwR2xvYmFsLkdldFN0YXJ0UG9zaXRpb24oKTsKKwl3aGlsZSAocG9zKQorCXsKKwkJQ0ZYX0J5dGVTdHJpbmcgbmFtZTsgCisJCWpzX2dsb2JhbF9kYXRhKiBwRGF0YSA9IE5VTEw7CisJCW1fbWFwR2xvYmFsLkdldE5leHRBc3NvYyhwb3MsIG5hbWUsIChGWF9MUFZPSUQmKXBEYXRhKTsKKwkJCisJCWlmIChwRGF0YSkKKwkJeworCQkJaWYgKHBEYXRhLT5iRGVsZXRlZCkKKwkJCXsKKwkJCQltX3BHbG9iYWxEYXRhLT5EZWxldGVHbG9iYWxWYXJpYWJsZShuYW1lKTsKKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlzd2l0Y2ggKHBEYXRhLT5uVHlwZSkKKwkJCQl7CisJCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOgorCQkJCQltX3BHbG9iYWxEYXRhLT5TZXRHbG9iYWxWYXJpYWJsZU51bWJlcihuYW1lLCBwRGF0YS0+ZERhdGEpOworCQkJCQltX3BHbG9iYWxEYXRhLT5TZXRHbG9iYWxWYXJpYWJsZVBlcnNpc3RlbnQobmFtZSwgcERhdGEtPmJQZXJzaXN0ZW50KTsKKwkJCQkJYnJlYWs7CisJCQkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTjoKKwkJCQkJbV9wR2xvYmFsRGF0YS0+U2V0R2xvYmFsVmFyaWFibGVCb29sZWFuKG5hbWUsIHBEYXRhLT5iRGF0YSk7CisJCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlUGVyc2lzdGVudChuYW1lLCBwRGF0YS0+YlBlcnNpc3RlbnQpOworCQkJCQlicmVhazsKKwkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc6CisJCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlU3RyaW5nKG5hbWUsIHBEYXRhLT5zRGF0YSk7CisJCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlUGVyc2lzdGVudChuYW1lLCBwRGF0YS0+YlBlcnNpc3RlbnQpOworCQkJCQlicmVhazsKKwkJCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9PQkpFQ1Q6CisJCQkJCS8vaWYgKHBEYXRhLT5wRGF0YSkKKwkJCQkJeworCQkJCQkJQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkgYXJyYXk7CisJCQkJCQl2ODo6SGFuZGxlPHY4OjpPYmplY3Q+IG9iaiA9IHY4OjpMb2NhbDx2ODo6T2JqZWN0Pjo6TmV3KEdldEpTT2JqZWN0KCktPkdldElzb2xhdGUoKSxwRGF0YS0+cERhdGEpOworCQkJCQkJT2JqZWN0VG9BcnJheShvYmosIGFycmF5KTsKKwkJCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlT2JqZWN0KG5hbWUsIGFycmF5KTsKKwkJCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlUGVyc2lzdGVudChuYW1lLCBwRGF0YS0+YlBlcnNpc3RlbnQpOworCQkJCQl9CisJCQkJCWJyZWFrOworCQkJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTEw6CisJCQkJCW1fcEdsb2JhbERhdGEtPlNldEdsb2JhbFZhcmlhYmxlTnVsbChuYW1lKTsKKwkJCQkJbV9wR2xvYmFsRGF0YS0+U2V0R2xvYmFsVmFyaWFibGVQZXJzaXN0ZW50KG5hbWUsIHBEYXRhLT5iUGVyc2lzdGVudCk7CisJCQkJCWJyZWFrOworCQkJCX0KKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBnbG9iYWxfYWx0ZXJuYXRlOjpPYmplY3RUb0FycmF5KHY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaiwgQ0pTX0dsb2JhbFZhcmlhYmxlQXJyYXkmIGFycmF5KQoreworCXY4OjpIYW5kbGU8djg6OkFycmF5PiBwS2V5TGlzdCA9IEpTX0dldE9iamVjdEVsZW1lbnROYW1lcyhwT2JqKTsKKwlpbnQJbk9iakVsZW1lbnRzID0gcEtleUxpc3QtPkxlbmd0aCgpOworCisJdjg6OkxvY2FsPHY4OjpDb250ZXh0PiBjb250ZXh0ID0gcE9iai0+Q3JlYXRpb25Db250ZXh0KCk7CisJdjg6Oklzb2xhdGUqIGlzb2xhdGUgPSBjb250ZXh0LT5HZXRJc29sYXRlKCk7CisKKwlmb3IgKGludCBpPTA7IGk8bk9iakVsZW1lbnRzOyBpKyspCisJeworCQkKKwkJQ0ZYX1dpZGVTdHJpbmcgd3MgPSBKU19Ub1N0cmluZyhKU19HZXRBcnJheUVsZW1uZXQocEtleUxpc3QsIGkpKTsKKwkJQ0ZYX0J5dGVTdHJpbmcgc0tleSA9IHdzLlVURjhFbmNvZGUoKTsKKworCQl2ODo6SGFuZGxlPHY4OjpWYWx1ZT4gdiA9IEpTX0dldE9iamVjdEVsZW1lbnQoaXNvbGF0ZSwgcE9iaiwgKGNvbnN0IHdjaGFyX3QqKShGWF9MUENXU1RSKXdzKTsKKwkJRlhKU1ZBTFVFVFlQRSB2dCA9IEdFVF9WQUxVRV9UWVBFKHYpOworCQlzd2l0Y2ggKHZ0KQorCQl7CisJCWNhc2UgVlRfbnVtYmVyOgorCQkJeworCQkJCUNKU19LZXlWYWx1ZSogcE9iakVsZW1lbnQgPSBuZXcgQ0pTX0tleVZhbHVlOworCQkJCXBPYmpFbGVtZW50LT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI7CisJCQkJcE9iakVsZW1lbnQtPnNLZXkgPSBzS2V5OworCQkJCXBPYmpFbGVtZW50LT5kRGF0YSA9IEpTX1RvTnVtYmVyKHYpOworCQkJCWFycmF5LkFkZChwT2JqRWxlbWVudCk7CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBWVF9ib29sZWFuOgorCQkJeworCQkJCUNKU19LZXlWYWx1ZSogcE9iakVsZW1lbnQgPSBuZXcgQ0pTX0tleVZhbHVlOworCQkJCXBPYmpFbGVtZW50LT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOworCQkJCXBPYmpFbGVtZW50LT5zS2V5ID0gc0tleTsKKwkJCQlwT2JqRWxlbWVudC0+ZERhdGEgPSBKU19Ub0Jvb2xlYW4odik7CisJCQkJYXJyYXkuQWRkKHBPYmpFbGVtZW50KTsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFZUX3N0cmluZzoKKwkJCXsKKwkJCQlDRlhfQnl0ZVN0cmluZyBzVmFsdWUgPSBDSlNfVmFsdWUoaXNvbGF0ZSwgdiwgVlRfc3RyaW5nKTsKKwkJCQlDSlNfS2V5VmFsdWUqIHBPYmpFbGVtZW50ID0gbmV3IENKU19LZXlWYWx1ZTsKKwkJCQlwT2JqRWxlbWVudC0+blR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOworCQkJCXBPYmpFbGVtZW50LT5zS2V5ID0gc0tleTsKKwkJCQlwT2JqRWxlbWVudC0+c0RhdGEgPSBzVmFsdWU7CisJCQkJYXJyYXkuQWRkKHBPYmpFbGVtZW50KTsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFZUX29iamVjdDoKKwkJCXsKKwkJCQlDSlNfS2V5VmFsdWUqIHBPYmpFbGVtZW50ID0gbmV3IENKU19LZXlWYWx1ZTsKKwkJCQlwT2JqRWxlbWVudC0+blR5cGUgPSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOworCQkJCXBPYmpFbGVtZW50LT5zS2V5ID0gc0tleTsKKwkJCQlPYmplY3RUb0FycmF5KEpTX1RvT2JqZWN0KHYpLCBwT2JqRWxlbWVudC0+b2JqRGF0YSk7CisJCQkJYXJyYXkuQWRkKHBPYmpFbGVtZW50KTsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFZUX251bGw6CisJCQl7CisJCQkJQ0pTX0tleVZhbHVlKiBwT2JqRWxlbWVudCA9IG5ldyBDSlNfS2V5VmFsdWU7CisJCQkJcE9iakVsZW1lbnQtPm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX05VTEw7CisJCQkJcE9iakVsZW1lbnQtPnNLZXkgPSBzS2V5OworCQkJCWFycmF5LkFkZChwT2JqRWxlbWVudCk7CisJCQl9CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJCWJyZWFrOworCQl9CisJfQorfQorCit2b2lkIGdsb2JhbF9hbHRlcm5hdGU6OlB1dE9iamVjdFByb3BlcnR5KHY4OjpIYW5kbGU8djg6Ok9iamVjdD4gcE9iaiwgQ0pTX0tleVZhbHVlKiBwRGF0YSkKK3sKKwlBU1NFUlQocERhdGEgIT0gTlVMTCk7CisKKwlmb3IgKGludCBpPTAsc3o9cERhdGEtPm9iakRhdGEuQ291bnQoKTsgaTxzejsgaSsrKQorCXsKKwkJQ0pTX0tleVZhbHVlKiBwT2JqRGF0YSA9IHBEYXRhLT5vYmpEYXRhLkdldEF0KGkpOworCQlBU1NFUlQocE9iakRhdGEgIT0gTlVMTCk7CisKKwkJc3dpdGNoIChwT2JqRGF0YS0+blR5cGUpCisJCXsKKwkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOgorCQkJSlNfUHV0T2JqZWN0TnVtYmVyKE5VTEwsKEpTT2JqZWN0KXBPYmosIHBPYmpEYXRhLT5zS2V5LlVURjhEZWNvZGUoKSwgcE9iakRhdGEtPmREYXRhKTsKKwkJCWJyZWFrOworCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOgorCQkJSlNfUHV0T2JqZWN0Qm9vbGVhbihOVUxMLChKU09iamVjdClwT2JqLCBwT2JqRGF0YS0+c0tleS5VVEY4RGVjb2RlKCksIChib29sKShwT2JqRGF0YS0+YkRhdGEgPT0gMSkpOworCQkJYnJlYWs7CisJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX1NUUklORzoKKwkJCUpTX1B1dE9iamVjdFN0cmluZyhOVUxMLChKU09iamVjdClwT2JqLCBwT2JqRGF0YS0+c0tleS5VVEY4RGVjb2RlKCksIHBPYmpEYXRhLT5zRGF0YS5VVEY4RGVjb2RlKCkpOworCQkJYnJlYWs7CisJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDoKKwkJCXsKKwkJCQlJSlNfUnVudGltZSogcFJ1bnRpbWUgPSBKU19HZXRSdW50aW1lKChKU0ZYT2JqZWN0KSgqbV9wSlNPYmplY3QpKTsKKwkJCQl2ODo6SGFuZGxlPHY4OjpPYmplY3Q+IHBOZXdPYmogPSBKU19OZXdGeER5bmFtaWNPYmoocFJ1bnRpbWUsIE5VTEwsIC0xKTsKKwkJCQlQdXRPYmplY3RQcm9wZXJ0eShwTmV3T2JqLCBwT2JqRGF0YSk7CisJCQkJSlNfUHV0T2JqZWN0T2JqZWN0KE5VTEwsIChKU09iamVjdClwT2JqLCBwT2JqRGF0YS0+c0tleS5VVEY4RGVjb2RlKCksIChKU09iamVjdClwTmV3T2JqKTsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVUxMOgorCQkJSlNfUHV0T2JqZWN0TnVsbChOVUxMLChKU09iamVjdClwT2JqLCBwT2JqRGF0YS0+c0tleS5VVEY4RGVjb2RlKCkpOworCQkJYnJlYWs7CisJCX0KKwl9Cit9CisKK3ZvaWQgZ2xvYmFsX2FsdGVybmF0ZTo6RGVzdHJveUdsb2JhbFBlcnNpc2l0ZW50VmFyaWFibGVzKCkKK3sKKwlGWF9QT1NJVElPTgkgcG9zID0gbV9tYXBHbG9iYWwuR2V0U3RhcnRQb3NpdGlvbigpOworCXdoaWxlIChwb3MpCisJeworCQlDRlhfQnl0ZVN0cmluZyBuYW1lOyAKKwkJanNfZ2xvYmFsX2RhdGEqIHBEYXRhID0gTlVMTDsKKwkJbV9tYXBHbG9iYWwuR2V0TmV4dEFzc29jKHBvcywgbmFtZSwgKEZYX0xQVk9JRCYpcERhdGEpOworCQlkZWxldGUgcERhdGE7CisJfQorCisJbV9tYXBHbG9iYWwuUmVtb3ZlQWxsKCk7Cit9CisKKworRlhfQk9PTCBnbG9iYWxfYWx0ZXJuYXRlOjpTZXRHbG9iYWxWYXJpYWJsZXMoRlhfTFBDU1RSIHByb3BuYW1lLCBpbnQgblR5cGUsIAorCQkJCWRvdWJsZSBkRGF0YSwgYm9vbCBiRGF0YSwgY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNEYXRhLCBKU09iamVjdCBwRGF0YSwgYm9vbCBiRGVmYXVsdFBlcnNpc3RlbnQpCit7CisJaWYgKHByb3BuYW1lID09IE5VTEwpIHJldHVybiBGQUxTRTsKKworCWpzX2dsb2JhbF9kYXRhKiBwVGVtcCA9IE5VTEw7CisJbV9tYXBHbG9iYWwuTG9va3VwKHByb3BuYW1lLCAoRlhfTFBWT0lEJilwVGVtcCk7CisKKwlpZiAocFRlbXApCisJeworCQlpZiAocFRlbXAtPmJEZWxldGVkIHx8IHBUZW1wLT5uVHlwZSAhPSBuVHlwZSkKKwkJeworCQkJcFRlbXAtPmREYXRhID0gMDsKKwkJCXBUZW1wLT5iRGF0YSA9IDA7CisJCQlwVGVtcC0+c0RhdGEgPSAiIjsKKwkJCXBUZW1wLT5uVHlwZSA9IG5UeXBlOworCQl9CisKKwkJcFRlbXAtPmJEZWxldGVkID0gRkFMU0U7CisKKwkJc3dpdGNoIChuVHlwZSkKKwkJeworCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI6CisJCQl7CisJCQkJcFRlbXAtPmREYXRhID0gZERhdGE7CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfQk9PTEVBTjoKKwkJCXsKKwkJCQlwVGVtcC0+YkRhdGEgPSBiRGF0YTsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc6CisJCQl7CisJCQkJcFRlbXAtPnNEYXRhID0gc0RhdGE7CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfT0JKRUNUOgorCQkJeworCQkJCXBUZW1wLT5wRGF0YS5SZXNldChKU19HZXRSdW50aW1lKHBEYXRhKSwgcERhdGEpOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTEw6CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJCXJldHVybiBGQUxTRTsKKwkJfQkKKworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlqc19nbG9iYWxfZGF0YSogcE5ld0RhdGEgPSBOVUxMOworCisJc3dpdGNoIChuVHlwZSkKKwl7CisJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfTlVNQkVSOgorCQl7CisJCQlwTmV3RGF0YSA9IG5ldyBqc19nbG9iYWxfZGF0YTsKKwkJCXBOZXdEYXRhLT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9OVU1CRVI7CisJCQlwTmV3RGF0YS0+ZERhdGEgPSBkRGF0YTsKKwkJCXBOZXdEYXRhLT5iUGVyc2lzdGVudCA9IGJEZWZhdWx0UGVyc2lzdGVudDsKKwkJfQorCQlicmVhazsKKwljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOgorCQl7CisJCQlwTmV3RGF0YSA9IG5ldyBqc19nbG9iYWxfZGF0YTsKKwkJCXBOZXdEYXRhLT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9CT09MRUFOOworCQkJcE5ld0RhdGEtPmJEYXRhID0gYkRhdGE7CisJCQlwTmV3RGF0YS0+YlBlcnNpc3RlbnQgPSBiRGVmYXVsdFBlcnNpc3RlbnQ7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBKU19HTE9CQUxEQVRBX1RZUEVfU1RSSU5HOgorCQl7CisJCQlwTmV3RGF0YSA9IG5ldyBqc19nbG9iYWxfZGF0YTsKKwkJCXBOZXdEYXRhLT5uVHlwZSA9IEpTX0dMT0JBTERBVEFfVFlQRV9TVFJJTkc7CisJCQlwTmV3RGF0YS0+c0RhdGEgPSBzRGF0YTsKKwkJCXBOZXdEYXRhLT5iUGVyc2lzdGVudCA9IGJEZWZhdWx0UGVyc2lzdGVudDsKKwkJfQorCQlicmVhazsKKwljYXNlIEpTX0dMT0JBTERBVEFfVFlQRV9PQkpFQ1Q6CisJCXsKKwkJCXBOZXdEYXRhID0gbmV3IGpzX2dsb2JhbF9kYXRhOworCQkJcE5ld0RhdGEtPm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX09CSkVDVDsKKwkJCXBOZXdEYXRhLT5wRGF0YS5SZXNldChKU19HZXRSdW50aW1lKHBEYXRhKSwgcERhdGEpOworCQkJcE5ld0RhdGEtPmJQZXJzaXN0ZW50ID0gYkRlZmF1bHRQZXJzaXN0ZW50OworCQl9CisJCWJyZWFrOworCWNhc2UgSlNfR0xPQkFMREFUQV9UWVBFX05VTEw6CisJCXsKKwkJCXBOZXdEYXRhID0gbmV3IGpzX2dsb2JhbF9kYXRhOworCQkJcE5ld0RhdGEtPm5UeXBlID0gSlNfR0xPQkFMREFUQV9UWVBFX05VTEw7CisJCQlwTmV3RGF0YS0+YlBlcnNpc3RlbnQgPSBiRGVmYXVsdFBlcnNpc3RlbnQ7CisJCX0KKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJcmV0dXJuIEZBTFNFOworCX0JCisKKwltX21hcEdsb2JhbC5TZXRBdChwcm9wbmFtZSwgKEZYX0xQVk9JRClwTmV3RGF0YSk7CisKKwlyZXR1cm4gVFJVRTsKK30KZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvcmVwb3J0LmNwcCBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvcmVwb3J0LmNwcAppbmRleCA1MDYzYzY4Li45Y2I5ZGE1IDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L3JlcG9ydC5jcHAKKysrIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC9yZXBvcnQuY3BwCkBAIC0xLDUwICsxLDUwIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19EZWZpbmUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L3JlcG9ydC5oIg0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcmVwb3J0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1CRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX1JlcG9ydCkNCi1FTkRfSlNfU1RBVElDX0NPTlNUKCkNCi0NCi1CRUdJTl9KU19TVEFUSUNfUFJPUChDSlNfUmVwb3J0KQ0KLUVORF9KU19TVEFUSUNfUFJPUCgpDQotDQotQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfUmVwb3J0KSANCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShzYXZlLCAxKQ0KLQlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHdyaXRlVGV4dCwxKQ0KLUVORF9KU19TVEFUSUNfTUVUSE9EKCkNCi0NCi1JTVBMRU1FTlRfSlNfQ0xBU1MoQ0pTX1JlcG9ydCwgUmVwb3J0KQ0KLQkNCi1SZXBvcnQ6OlJlcG9ydChDSlNfT2JqZWN0KiBwSlNPYmplY3QpIDogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCkNCi17DQotDQotfQ0KLQ0KLVJlcG9ydDo6flJlcG9ydCgpDQotew0KLQkNCi19DQotDQotRlhfQk9PTCBSZXBvcnQ6OndyaXRlVGV4dChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIFJlcG9ydDo6c2F2ZShPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7DQotCXJldHVybiBUUlVFOwkNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0lKYXZhU2NyaXB0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX0RlZmluZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfVmFsdWUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvcmVwb3J0LmgiCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gcmVwb3J0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19SZXBvcnQpCitFTkRfSlNfU1RBVElDX0NPTlNUKCkKKworQkVHSU5fSlNfU1RBVElDX1BST1AoQ0pTX1JlcG9ydCkKK0VORF9KU19TVEFUSUNfUFJPUCgpCisKK0JFR0lOX0pTX1NUQVRJQ19NRVRIT0QoQ0pTX1JlcG9ydCkgCisJSlNfU1RBVElDX01FVEhPRF9FTlRSWShzYXZlLCAxKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkod3JpdGVUZXh0LDEpCitFTkRfSlNfU1RBVElDX01FVEhPRCgpCisKK0lNUExFTUVOVF9KU19DTEFTUyhDSlNfUmVwb3J0LCBSZXBvcnQpCisJCitSZXBvcnQ6OlJlcG9ydChDSlNfT2JqZWN0KiBwSlNPYmplY3QpIDogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCkKK3sKKworfQorCitSZXBvcnQ6On5SZXBvcnQoKQoreworCQorfQorCitGWF9CT09MIFJlcG9ydDo6d3JpdGVUZXh0KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgUmVwb3J0OjpzYXZlKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWlmIChJc1NhZmVNb2RlKGNjKSkgcmV0dXJuIFRSVUU7CisJcmV0dXJuIFRSVUU7CQorfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L3V0aWwuY3BwIGIvZnBkZnNkay9zcmMvamF2YXNjcmlwdC91dGlsLmNwcAppbmRleCBiNzMwM2E3Li5iYWZkYjIyIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9qYXZhc2NyaXB0L3V0aWwuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL2phdmFzY3JpcHQvdXRpbC5jcHAKQEAgLTEsNjQ5ICsxLDY0OSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KYXZhU2NyaXB0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9JSmF2YVNjcmlwdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19PYmplY3QuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX1ZhbHVlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC91dGlsLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9QdWJsaWNNZXRob2RzLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9yZXNvdXJjZS5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRXZlbnRIYW5kbGVyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19SdW50aW1lLmgiDQotDQotI2lmIF9GWF9PU18gID09IF9GWF9BTkRST0lEXw0KLSNpbmNsdWRlIDxjdHlwZS5oPg0KLSNlbmRpZg0KLQ0KLXN0YXRpYyB2ODo6SXNvbGF0ZSogR2V0SXNvbGF0ZShJRlhKU19Db250ZXh0KiBjYykNCi17DQotCUNKU19Db250ZXh0KiBwQ29udGV4dCA9IChDSlNfQ29udGV4dCAqKWNjOw0KLQlBU1NFUlQocENvbnRleHQgIT0gTlVMTCk7DQotDQotCUNKU19SdW50aW1lKiBwUnVudGltZSA9IHBDb250ZXh0LT5HZXRKU1J1bnRpbWUoKTsNCi0JQVNTRVJUKHBSdW50aW1lICE9IE5VTEwpOw0KLQ0KLQlyZXR1cm4gcFJ1bnRpbWUtPkdldElzb2xhdGUoKTsNCi19DQotDQotQkVHSU5fSlNfU1RBVElDX0NPTlNUKENKU19VdGlsKQ0KLUVORF9KU19TVEFUSUNfQ09OU1QoKQ0KLQ0KLUJFR0lOX0pTX1NUQVRJQ19QUk9QKENKU19VdGlsKQ0KLUVORF9KU19TVEFUSUNfUFJPUCgpDQotDQotQkVHSU5fSlNfU1RBVElDX01FVEhPRChDSlNfVXRpbCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShwcmludGQsIDMpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkocHJpbnRmLCAyMCkNCi0JSlNfU1RBVElDX01FVEhPRF9FTlRSWShwcmludHgsIDIpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoc2NhbmQsIDIpDQotCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYnl0ZVRvQ2hhciwgMSkNCi1FTkRfSlNfU1RBVElDX01FVEhPRCgpDQotDQotSU1QTEVNRU5UX0pTX0NMQVNTKENKU19VdGlsLHV0aWwpDQotDQotdXRpbDo6dXRpbChDSlNfT2JqZWN0ICpwSlNPYmplY3QpIDogQ0pTX0VtYmVkT2JqKHBKU09iamVjdCkNCi17DQotfQ0KLQ0KLXV0aWw6On51dGlsKHZvaWQpDQotew0KLX0NCi0NCi0NCi1zdHJ1Y3Qgc3RydV9UYkNvbnZlcnQNCi17DQotCUZYX0xQQ1dTVFIgbHBzekpTTWFyazsNCi0JRlhfTFBDV1NUUiBscHN6Q3BwTWFyazsNCi19Ow0KLQ0KLWNvbnN0IHN0cnVfVGJDb252ZXJ0IGZjVGFibGVbXSA9IHsNCi0JKEZYX0xQQ1dTVFIpTCJtbW1tIiwgKEZYX0xQQ1dTVFIpTCIlQiIsDQotCShGWF9MUENXU1RSKUwibW1tIiwgKEZYX0xQQ1dTVFIpTCIlYiIsDQotCShGWF9MUENXU1RSKUwibW0iLCAgKEZYX0xQQ1dTVFIpTCIlbSIsDQotCS8vIm0iDQotCShGWF9MUENXU1RSKUwiZGRkZCIsIChGWF9MUENXU1RSKUwiJUEiLA0KLQkoRlhfTFBDV1NUUilMImRkZCIsIChGWF9MUENXU1RSKUwiJWEiLA0KLQkoRlhfTFBDV1NUUilMImRkIiwgIChGWF9MUENXU1RSKUwiJWQiLA0KLQkvLyJkIiwgICAiJXciLA0KLQkoRlhfTFBDV1NUUilMInl5eXkiLCAoRlhfTFBDV1NUUilMIiVZIiwNCi0JKEZYX0xQQ1dTVFIpTCJ5eSIsICAoRlhfTFBDV1NUUilMIiV5IiwNCi0JKEZYX0xQQ1dTVFIpTCJISCIsICAoRlhfTFBDV1NUUilMIiVIIiwNCi0JLy8iSCINCi0JKEZYX0xQQ1dTVFIpTCJoaCIsICAoRlhfTFBDV1NUUilMIiVJIiwNCi0JLy8iaCINCi0JKEZYX0xQQ1dTVFIpTCJNTSIsICAoRlhfTFBDV1NUUilMIiVNIiwNCi0JLy8iTSINCi0JKEZYX0xQQ1dTVFIpTCJzcyIsICAoRlhfTFBDV1NUUilMIiVTIiwNCi0JLy8icw0KLQkoRlhfTFBDV1NUUilMIlRUIiwgIChGWF9MUENXU1RSKUwiJXAiLA0KLQkvLyJ0Ig0KLSNpZiBkZWZpbmVkKF9XSU4zMikNCi0JKEZYX0xQQ1dTVFIpTCJ0dCIsICAoRlhfTFBDV1NUUilMIiVwIiwNCi0JKEZYX0xQQ1dTVFIpTCJoIiwgIChGWF9MUENXU1RSKUwiJSNJIiwNCi0jZWxzZQ0KLQkoRlhfTFBDV1NUUilMInR0IiwgIChGWF9MUENXU1RSKUwiJVAiLA0KLQkoRlhfTFBDV1NUUilMImgiLCAgKEZYX0xQQ1dTVFIpTCIlbCIsDQotI2VuZGlmDQotfTsNCi0NCi0jZGVmaW5lIFVUSUxfSU5UCQkJMA0KLSNkZWZpbmUgVVRJTF9ET1VCTEUJCQkxDQotI2RlZmluZSBVVElMX1NUUklORwkJCTINCi0NCi1pbnQgdXRpbDo6UGFyc3REYXRhVHlwZShzdGQ6OndzdHJpbmcqIHNGb3JtYXQpDQotew0KLSAgICAgICAgc2l6ZV90IGkgPSAwOw0KLQlib29sIGJQZXJjZW50ID0gRkFMU0U7DQotCWZvciAoaT0wOyBpPHNGb3JtYXQtPmxlbmd0aCgpOyArK2kpDQotCXsNCi0JCXdjaGFyX3QgYyA9ICgqc0Zvcm1hdClbaV07DQotCQlpZiAoYyA9PSBMJyUnKQ0KLQkJew0KLQkJCWJQZXJjZW50ID0gdHJ1ZTsNCi0JCQljb250aW51ZTsNCi0JCX0NCi0NCi0JCWlmIChiUGVyY2VudCkNCi0JCXsNCi0JCQlpZiAoYyA9PSBMJ2MnIHx8IGMgPT0gTCdDJyB8fCBjID09IEwnZCcgfHwgYyA9PSBMJ2knIHx8IGMgPT0gTCdvJyB8fCBjID09IEwndScgfHwgYyA9PSBMJ3gnIHx8IGMgPT0gTCdYJykNCi0JCQl7DQotCQkJCXJldHVybiBVVElMX0lOVDsNCi0JCQl9DQotCQkJZWxzZSBpZiAoYyA9PSBMJ2UnIHx8IGMgPT0gTCdFJyB8fCBjID09IEwnZicgfHwgYyA9PSBMJ2cnIHx8IGMgPT0gTCdHJykNCi0JCQl7DQotCQkJCXJldHVybiBVVElMX0RPVUJMRTsNCi0JCQl9DQotCQkJZWxzZSBpZiAoYyA9PSBMJ3MnIHx8IGMgPT0gTCdTJykNCi0JCQl7DQotCQkJCS8vIE1hcCBzIHRvIFMgc2luY2Ugd2UgYWx3YXlzIGRlYWwgaW50ZXJuYWxseQ0KLQkJCQkvLyB3aXRoIHdjaGFyX3Qgc3RyaW5ncy4NCi0JCQkJKCpzRm9ybWF0KVtpXSA9IEwnUyc7DQotCQkJCXJldHVybiBVVElMX1NUUklORzsNCi0JCQl9DQotCQkJZWxzZSBpZiAoYyA9PSBMJy4nIHx8IGMgPT0gTCcrJyB8fCBjID09IEwnLScgfHwgYyA9PSBMJyMnIHx8IGMgPT0gTCcgJyB8fCBDSlNfUHVibGljTWV0aG9kczo6SXNEaWdpdChjKSkNCi0JCQl7DQotCQkJCWNvbnRpbnVlOw0KLQkJCX0NCi0JCQllbHNlIGJyZWFrOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiAtMTsNCi19DQotDQotRlhfQk9PTCB1dGlsOjpwcmludGYoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOw0KLQlpZiAoaVNpemUgPCAxKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlzdGQ6OndzdHJpbmcgIGNfQ29udkNoYXIoKGNvbnN0IHdjaGFyX3QqKShGWF9MUENXU1RSKXBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpKTsNCi0Jc3RkOjp2ZWN0b3I8c3RkOjp3c3RyaW5nPiBjX3N0ckNvbnZlcnM7DQotCWludCBpT2Zmc2V0ID0gMDsNCi0JaW50IGlPZmZlbmQgPSAwOw0KLQljX0NvbnZDaGFyLmluc2VydChjX0NvbnZDaGFyLmJlZ2luKCksTCdTJyk7DQotCXdoaWxlKGlPZmZzZXQgIT0gLTEpDQotCXsNCi0JCWlPZmZlbmQgPSBjX0NvbnZDaGFyLmZpbmQoTCIlIixpT2Zmc2V0KzEpOw0KLQkJc3RkOjp3c3RyaW5nIHN0clN1YjsNCi0JCWlmIChpT2ZmZW5kID09IC0xKQ0KLQkJCXN0clN1YiA9IGNfQ29udkNoYXIuc3Vic3RyKGlPZmZzZXQpOwkJCQ0KLQkJZWxzZQ0KLQkJCXN0clN1YiA9IGNfQ29udkNoYXIuc3Vic3RyKGlPZmZzZXQgLGlPZmZlbmQgLSBpT2Zmc2V0KTsNCi0JCWNfc3RyQ29udmVycy5wdXNoX2JhY2soc3RyU3ViKTsNCi0JCWlPZmZzZXQgPSBpT2ZmZW5kIDsNCi0JfQ0KLQ0KLQlzdGQ6OndzdHJpbmcgY19zdHJSZXN1bHQ7DQotDQotCS8vZm9yKGludCBpSW5kZXggPSAxO2lJbmRleCA8IHBhcmFtcy5zaXplKCk7aUluZGV4KyspDQotCXN0ZDo6d3N0cmluZyBjX3N0ckZvcm1hdDsNCi0JZm9yKGludCBpSW5kZXggPSAwO2lJbmRleCA8IChpbnQpY19zdHJDb252ZXJzLnNpemUoKTtpSW5kZXgrKykNCi0Jew0KLQkJY19zdHJGb3JtYXQgPSBjX3N0ckNvbnZlcnNbaUluZGV4XTsNCi0JCWlmIChpSW5kZXggPT0gMCkNCi0JCXsNCi0JCQljX3N0clJlc3VsdCA9IGNfc3RyRm9ybWF0Ow0KLQkJCWNvbnRpbnVlOw0KLQkJfQ0KLQ0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgc3RyU2VnbWVudDsNCi0JCWlmIChpSW5kZXggPj0gaVNpemUpIHsNCi0JCQljX3N0clJlc3VsdCArPSBjX3N0ckZvcm1hdDsNCi0JCQljb250aW51ZTsNCi0JCX0NCi0NCi0JCXN3aXRjaCAoUGFyc3REYXRhVHlwZSgmY19zdHJGb3JtYXQpKQ0KLQkJew0KLQkJCWNhc2UgVVRJTF9JTlQ6DQotCQkJCXN0clNlZ21lbnQuRm9ybWF0KChGWF9MUENXU1RSKWNfc3RyRm9ybWF0LmNfc3RyKCksKGludClwYXJhbXNbaUluZGV4XSk7DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgVVRJTF9ET1VCTEU6DQotCQkJCXN0clNlZ21lbnQuRm9ybWF0KChGWF9MUENXU1RSKWNfc3RyRm9ybWF0LmNfc3RyKCksKGRvdWJsZSlwYXJhbXNbaUluZGV4XSk7DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgVVRJTF9TVFJJTkc6DQotCQkJCXN0clNlZ21lbnQuRm9ybWF0KChGWF9MUENXU1RSKWNfc3RyRm9ybWF0LmNfc3RyKCksKEZYX0xQQ1dTVFIpcGFyYW1zW2lJbmRleF0ub3BlcmF0b3IgQ0ZYX1dpZGVTdHJpbmcoKSk7DQotCQkJCWJyZWFrOw0KLQkJCWRlZmF1bHQ6DQotCQkJCXN0clNlZ21lbnQuRm9ybWF0KChGWF9MUENXU1RSKUwiJVMiLCAoRlhfTFBDV1NUUiljX3N0ckZvcm1hdC5jX3N0cigpKTsNCi0JCQkJYnJlYWs7DQotCQl9DQotCQljX3N0clJlc3VsdCArPSAod2NoYXJfdCopc3RyU2VnbWVudC5HZXRCdWZmZXIoc3RyU2VnbWVudC5HZXRMZW5ndGgoKSsxKTsNCi0JfQ0KLQ0KLQljX3N0clJlc3VsdC5lcmFzZShjX3N0clJlc3VsdC5iZWdpbigpKTsNCi0JdlJldCA9IChGWF9MUENXU1RSKWNfc3RyUmVzdWx0LmNfc3RyKCk7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIHV0aWw6OnByaW50ZChPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7DQotDQotCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7DQotCWlmIChpU2l6ZSA8IDIpDQotCQlyZXR1cm4gRkFMU0U7DQotDQotCUNKU19WYWx1ZSBwMShpc29sYXRlKTsNCi0JcDEgPSBwYXJhbXNbMF07DQotDQotCUNKU19WYWx1ZSBwMiA9IHBhcmFtc1sxXTsNCi0JQ0pTX0RhdGUganNEYXRlKGlzb2xhdGUpOw0KLQlpZiAoIXAyLkNvbnZlcnRUb0RhdGUoanNEYXRlKSkNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQoKENKU19Db250ZXh0KiljYywgSURTX1NUUklOR19KU1BSSU5UMSk7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JaWYgKCFqc0RhdGUuSXNWYWxpZERhdGUoKSkNCi0Jew0KLQkJc0Vycm9yID0gSlNHZXRTdHJpbmdGcm9tSUQoKENKU19Db250ZXh0KiljYywgSURTX1NUUklOR19KU1BSSU5UMik7DQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0JaWYgKHAxLkdldFR5cGUoKSA9PSBWVF9udW1iZXIpDQotCXsNCi0JCWludCBuRm9ybWF0ID0gcDE7DQotDQotCQlDRlhfV2lkZVN0cmluZyBzd1Jlc3VsdDsNCi0NCi0JCXN3aXRjaCAobkZvcm1hdCkNCi0JCXsNCi0JCWNhc2UgMDoNCi0JCQlzd1Jlc3VsdC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCJEOiUwNGQlMDJkJTAyZCUwMmQlMDJkJTAyZCIsIA0KLQkJCQlqc0RhdGUuR2V0WWVhcigpLA0KLQkJCQlqc0RhdGUuR2V0TW9udGgoKSArIDEsDQotCQkJCWpzRGF0ZS5HZXREYXkoKSwNCi0JCQkJanNEYXRlLkdldEhvdXJzKCksDQotCQkJCWpzRGF0ZS5HZXRNaW51dGVzKCksDQotCQkJCWpzRGF0ZS5HZXRTZWNvbmRzKCkpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSAxOg0KLQkJCXN3UmVzdWx0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwNGQuJTAyZC4lMDJkICUwMmQ6JTAyZDolMDJkIiwgDQotCQkJCWpzRGF0ZS5HZXRZZWFyKCksDQotCQkJCWpzRGF0ZS5HZXRNb250aCgpICsgMSwNCi0JCQkJanNEYXRlLkdldERheSgpLA0KLQkJCQlqc0RhdGUuR2V0SG91cnMoKSwNCi0JCQkJanNEYXRlLkdldE1pbnV0ZXMoKSwNCi0JCQkJanNEYXRlLkdldFNlY29uZHMoKSk7DQotCQkJYnJlYWs7DQotCQljYXNlIDI6DQotCQkJc3dSZXN1bHQuRm9ybWF0KChGWF9MUENXU1RSKUwiJTA0ZC8lMDJkLyUwMmQgJTAyZDolMDJkOiUwMmQiLCANCi0JCQkJanNEYXRlLkdldFllYXIoKSwNCi0JCQkJanNEYXRlLkdldE1vbnRoKCkgKyAxLA0KLQkJCQlqc0RhdGUuR2V0RGF5KCksDQotCQkJCWpzRGF0ZS5HZXRIb3VycygpLA0KLQkJCQlqc0RhdGUuR2V0TWludXRlcygpLA0KLQkJCQlqc0RhdGUuR2V0U2Vjb25kcygpKTsNCi0JCQlicmVhazsNCi0JCWRlZmF1bHQ6DQotCQkJcmV0dXJuIEZBTFNFOw0KLQkJfQ0KLQ0KLQkJdlJldCA9IHN3UmVzdWx0Ow0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JZWxzZSBpZiAocDEuR2V0VHlwZSgpID09IFZUX3N0cmluZykNCi0Jew0KLQkJc3RkOjpiYXNpY19zdHJpbmc8d2NoYXJfdD4gY0Zvcm1hdCA9ICh3Y2hhcl90KikoRlhfTFBDV1NUUilwMS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOwkJDQotDQotCQlib29sIGJYRkFQaWN0dXJlID0gZmFsc2U7DQotCQlpZiAoaVNpemUgPiAyKQ0KLQkJew0KLQkJCS8vQ0pTX1ZhbHVlIHZhbHVlOw0KLQkJCWJYRkFQaWN0dXJlID0gcGFyYW1zWzJdOw0KLQkJfQ0KLQ0KLQkJaWYgKGJYRkFQaWN0dXJlKQ0KLQkJew0KLQkJCXJldHVybiBGQUxTRTsgLy9jdXJyZW50bHksIGl0IGRvZXNuJ3Qgc3VwcG9ydCBYRkFQaWN0dXJlLg0KLQkJfQ0KLQ0KLSAgICAgICAgaW50IGlJbmRleDsNCi0JCWZvcihpSW5kZXggPSAwO2lJbmRleDxzaXplb2YoZmNUYWJsZSkvc2l6ZW9mKHN0cnVfVGJDb252ZXJ0KTtpSW5kZXgrKykNCi0JCXsNCi0JCQlpbnQgaVN0YXJ0ID0gMDsNCi0JCQlpbnQgaUVuZDsNCi0JCQl3aGlsZSgoaUVuZCA9IGNGb3JtYXQuZmluZCgoQ0ZYX1dpZGVTdHJpbmcpZmNUYWJsZVtpSW5kZXhdLmxwc3pKU01hcmssIGlTdGFydCkpICE9IC0xKQ0KLQkJCXsNCi0JCQkJY0Zvcm1hdC5yZXBsYWNlKGlFbmQsIEZYU1lTX3djc2xlbihmY1RhYmxlW2lJbmRleF0ubHBzekpTTWFyayksIChDRlhfV2lkZVN0cmluZylmY1RhYmxlW2lJbmRleF0ubHBzekNwcE1hcmspOw0KLQkJCQlpU3RhcnQgPSBpRW5kOw0KLQkJCX0NCi0JCX0NCi0NCi0JCWludCBpWWVhcixpTW9udGgsaURheSxpSG91cixpTWluLGlTZWM7DQotCQlpWWVhciA9IGpzRGF0ZS5HZXRZZWFyKCk7DQotCQlpTW9udGggPSBqc0RhdGUuR2V0TW9udGgoKTsNCi0JCWlEYXkgPSBqc0RhdGUuR2V0RGF5KCk7DQotCQlpSG91ciA9IGpzRGF0ZS5HZXRIb3VycygpOw0KLQkJaU1pbiA9IGpzRGF0ZS5HZXRNaW51dGVzKCk7DQotCQlpU2VjID0ganNEYXRlLkdldFNlY29uZHMoKTsNCi0NCi0JCXN0cnVjdCB0bSB0aW1lID0gezB9Ow0KLQkJdGltZS50bV95ZWFyID0gaVllYXItMTkwMDsNCi0JCXRpbWUudG1fbW9uID0gaU1vbnRoOw0KLQkJdGltZS50bV9tZGF5ID0gaURheTsNCi0JCXRpbWUudG1faG91ciA9IGlIb3VyOw0KLQkJdGltZS50bV9taW4gPSBpTWluOw0KLQkJdGltZS50bV9zZWMgPSBpU2VjOw0KLQkJLy9DT2xlRGF0ZVRpbWUgY3BwVG0oaVllYXIsaU1vbnRoKzEsaURheSxpSG91cixpTWluLGlTZWMpOw0KLQkJLy9DU3RyaW5nIHN0ckZvcm1hdCA9IGNwcFRtLkZvcm1hdChjRm9ybWF0LmNfc3RyKCkpOw0KLQ0KLQkJc3RydWN0IHN0cnVfVGJDb252ZXJ0QWQNCi0JCXsNCi0JCQlGWF9MUENXU1RSIGxwc3pKU01hcms7DQotCQkJaW50ICAgICBpVmFsdWU7DQotCQl9Ow0KLQ0KLQkJc3RydV9UYkNvbnZlcnRBZCBjVGFibGVBZFtdID17DQotCQkJKEZYX0xQQ1dTVFIpTCJtIiwgaU1vbnRoKzEsDQotCQkJCShGWF9MUENXU1RSKUwiZCIsIGlEYXksDQotCQkJCShGWF9MUENXU1RSKUwiSCIsIGlIb3VyLA0KLQkJCQkoRlhfTFBDV1NUUilMImgiLCBpSG91cj4xMj9pSG91ci0xMjppSG91ciwNCi0JCQkJKEZYX0xQQ1dTVFIpTCJNIiwgaU1pbiwNCi0JCQkJKEZYX0xQQ1dTVFIpTCJzIiwgaVNlYw0KLQkJfTsNCi0NCi0JCS8vY0Zvcm1hdCA9IHN0ckZvcm1hdC5HZXRCdWZmZXIoc3RyRm9ybWF0LkdldExlbmd0aCgpKzEpOw0KLQkJZm9yKGlJbmRleCA9IDA7aUluZGV4PHNpemVvZihjVGFibGVBZCkvc2l6ZW9mKHN0cnVfVGJDb252ZXJ0QWQpO2lJbmRleCsrKQ0KLQkJew0KLQkJCXdjaGFyX3QgdHN6VmFsdWVbMTBdOw0KLQkJCS8vX2l0b3QoY1RhYmxlQWRbaUluZGV4XS5pVmFsdWUsdHN6VmFsdWUsMTApOw0KLQkJCUNGWF9XaWRlU3RyaW5nIHNWYWx1ZTsNCi0JCQlzVmFsdWUuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLGNUYWJsZUFkW2lJbmRleF0uaVZhbHVlKTsNCi0JCQltZW1jcHkodHN6VmFsdWUsICh3Y2hhcl90ICopc1ZhbHVlLkdldEJ1ZmZlcihzVmFsdWUuR2V0TGVuZ3RoKCkrMSksDQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzVmFsdWUuR2V0TGVuZ3RoKCkrMSkqc2l6ZW9mKHdjaGFyX3QpKTsNCi0NCi0JCQkvL3N0ckZvcm1hdC5SZXBsYWNlKGNUYWJsZUFkW2lJbmRleF0ubHBzekpTTWFyaywiJWQiKTsNCi0JCQkvL3N0ckZvcm1hdC5Gb3JtYXQoc3RyRm9ybWF0LGNUYWJsZUFkW2lJbmRleF0uaVZhbHVlKTsNCi0JCQlpbnQgaVN0YXJ0ID0gMDsNCi0JCQlpbnQgaUVuZDsNCi0JCQl3aGlsZSgoaUVuZCA9IGNGb3JtYXQuZmluZCgoQ0ZYX1dpZGVTdHJpbmcpY1RhYmxlQWRbaUluZGV4XS5scHN6SlNNYXJrLGlTdGFydCkpICE9IC0xKQ0KLQkJCXsNCi0JCQkJaWYgKGlFbmQgPiAwKQ0KLQkJCQl7DQotCQkJCQlpZiAoY0Zvcm1hdFtpRW5kLTFdID09IEwnJScpDQotCQkJCQl7DQotCQkJCQkJaVN0YXJ0ID0gaUVuZCsxOw0KLQkJCQkJCWNvbnRpbnVlOw0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJCWNGb3JtYXQucmVwbGFjZShpRW5kLCBGWFNZU193Y3NsZW4oY1RhYmxlQWRbaUluZGV4XS5scHN6SlNNYXJrKSwgdHN6VmFsdWUpOw0KLQkJCQlpU3RhcnQgPSBpRW5kOw0KLQkJCX0NCi0JCX0NCi0NCi0JCUNGWF9XaWRlU3RyaW5nIHN0ckZvcm1hdDsNCi0vLwkJc3RyRm9ybWF0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkLCVkLCVkLCVkLCVkLCVkIixpWWVhciwgaU1vbnRoLCBpRGF5LCBpSG91ciwgaU1pbiwgaVNlYyk7DQotLy8JCUNTdHJpbmcgc3RyRm9ybWF0ID0gY3BwVG0uRm9ybWF0KGNGb3JtYXQuY19zdHIoKSk7DQotCQl3Y2hhcl90IGJ1Zls2NF0gPSB7MH07DQotCQlzdHJGb3JtYXQgPSB3Y3NmdGltZShidWYsIDY0LCBjRm9ybWF0LmNfc3RyKCksICZ0aW1lKTsNCi0JCWNGb3JtYXQgPSBidWY7DQotCQl2UmV0ID0gKEZYX0xQQ1dTVFIpY0Zvcm1hdC5jX3N0cigpOw0KLQkJLy9ydFJldCA9IHN0ckZvcm1hdC5HZXRCdWZmZXIoc3RyRm9ybWF0LkdldExlbmd0aCgpKzEpOw0KLQkJcmV0dXJuIFRSVUU7DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIHV0aWw6OnByaW50ZChjb25zdCBzdGQ6OndzdHJpbmcgJmNGb3JtYXQyLCBDSlNfRGF0ZSBqc0RhdGUsIGJvb2wgYlhGQVBpY3R1cmUsIHN0ZDo6d3N0cmluZyAmY1B1cnBvc2UpDQotew0KLQlzdGQ6OndzdHJpbmcgY0Zvcm1hdCA9IGNGb3JtYXQyOw0KLQkgICAgDQotCWlmIChiWEZBUGljdHVyZSkNCi0Jew0KLQkJcmV0dXJuIDsgLy9jdXJyZW50bHksIGl0IGRvZXNuJ3Qgc3VwcG9ydCBYRkFQaWN0dXJlLg0KLQl9DQotDQotICAgIGludCBpSW5kZXg7DQotCWZvcihpSW5kZXggPSAwO2lJbmRleDxzaXplb2YoZmNUYWJsZSkvc2l6ZW9mKHN0cnVfVGJDb252ZXJ0KTtpSW5kZXgrKykNCi0Jew0KLQkJaW50IGlTdGFydCA9IDA7DQotCQlpbnQgaUVuZDsNCi0JCXdoaWxlKChpRW5kID0gY0Zvcm1hdC5maW5kKChDRlhfV2lkZVN0cmluZylmY1RhYmxlW2lJbmRleF0ubHBzekpTTWFyayxpU3RhcnQpKSAhPSAtMSkNCi0JCXsNCi0JCQljRm9ybWF0LnJlcGxhY2UoaUVuZCxGWFNZU193Y3NsZW4oZmNUYWJsZVtpSW5kZXhdLmxwc3pKU01hcmspLCAoQ0ZYX1dpZGVTdHJpbmcpZmNUYWJsZVtpSW5kZXhdLmxwc3pDcHBNYXJrKTsNCi0JCQlpU3RhcnQgPSBpRW5kOw0KLQkJfQ0KLQl9DQotDQotCWludCBpWWVhcixpTW9udGgsaURheSxpSG91cixpTWluLGlTZWM7DQotCWlZZWFyID0ganNEYXRlLkdldFllYXIoKTsNCi0JaU1vbnRoID0ganNEYXRlLkdldE1vbnRoKCk7DQotCWlEYXkgPSBqc0RhdGUuR2V0RGF5KCk7DQotCWlIb3VyID0ganNEYXRlLkdldEhvdXJzKCk7DQotCWlNaW4gPSBqc0RhdGUuR2V0TWludXRlcygpOw0KLQlpU2VjID0ganNEYXRlLkdldFNlY29uZHMoKTsNCi0NCi0Jc3RydWN0IHRtIHRpbWUgPSB7MH07DQotCXRpbWUudG1feWVhciA9IGlZZWFyLTE5MDA7DQotCXRpbWUudG1fbW9uID0gaU1vbnRoOw0KLQl0aW1lLnRtX21kYXkgPSBpRGF5Ow0KLQl0aW1lLnRtX2hvdXIgPSBpSG91cjsNCi0JdGltZS50bV9taW4gPSBpTWluOw0KLQl0aW1lLnRtX3NlYyA9IGlTZWM7DQotLy8JQ09sZURhdGVUaW1lIGNwcFRtKGlZZWFyLGlNb250aCsxLGlEYXksaUhvdXIsaU1pbixpU2VjKTsNCi0JLy9DU3RyaW5nIHN0ckZvcm1hdCA9IGNwcFRtLkZvcm1hdChjRm9ybWF0LmNfc3RyKCkpOw0KLQ0KLQlzdHJ1Y3Qgc3RydV9UYkNvbnZlcnRBZA0KLQl7DQotCQlGWF9MUENXU1RSIGxwc3pKU01hcms7DQotCQlpbnQgICAgIGlWYWx1ZTsNCi0JfTsNCi0NCi0Jc3RydV9UYkNvbnZlcnRBZCBjVGFibGVBZFtdID17DQotCQkoRlhfTFBDV1NUUilMIm0iLCBpTW9udGgrMSwNCi0JCQkoRlhfTFBDV1NUUilMImQiLCBpRGF5LA0KLQkJCShGWF9MUENXU1RSKUwiSCIsIGlIb3VyLA0KLQkJCShGWF9MUENXU1RSKUwiaCIsIGlIb3VyPjEyP2lIb3VyLTEyOmlIb3VyLA0KLQkJCShGWF9MUENXU1RSKUwiTSIsIGlNaW4sDQotCQkJKEZYX0xQQ1dTVFIpTCJzIiwgaVNlYw0KLQl9Ow0KLQ0KLQkvL2NGb3JtYXQgPSBzdHJGb3JtYXQuR2V0QnVmZmVyKHN0ckZvcm1hdC5HZXRMZW5ndGgoKSsxKTsNCi0JZm9yKGlJbmRleCA9IDA7aUluZGV4PHNpemVvZihjVGFibGVBZCkvc2l6ZW9mKHN0cnVfVGJDb252ZXJ0QWQpO2lJbmRleCsrKQ0KLQl7DQotCQl3Y2hhcl90IHRzelZhbHVlWzEwXTsNCi0JCS8vX2l0b3QoY1RhYmxlQWRbaUluZGV4XS5pVmFsdWUsdHN6VmFsdWUsMTApOw0KLQkJQ0ZYX1dpZGVTdHJpbmcgc1ZhbHVlOw0KLQkJc1ZhbHVlLkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixjVGFibGVBZFtpSW5kZXhdLmlWYWx1ZSk7DQotCQltZW1jcHkodHN6VmFsdWUsICh3Y2hhcl90ICopc1ZhbHVlLkdldEJ1ZmZlcihzVmFsdWUuR2V0TGVuZ3RoKCkrMSksc1ZhbHVlLkdldExlbmd0aCgpKnNpemVvZih3Y2hhcl90KSk7DQotDQotDQotCQkvL3N0ckZvcm1hdC5SZXBsYWNlKGNUYWJsZUFkW2lJbmRleF0ubHBzekpTTWFyaywiJWQiKTsNCi0JCS8vc3RyRm9ybWF0LkZvcm1hdChzdHJGb3JtYXQsY1RhYmxlQWRbaUluZGV4XS5pVmFsdWUpOw0KLQkJaW50IGlTdGFydCA9IDA7DQotCQlpbnQgaUVuZDsNCi0JCXdoaWxlKChpRW5kID0gY0Zvcm1hdC5maW5kKChDRlhfV2lkZVN0cmluZyljVGFibGVBZFtpSW5kZXhdLmxwc3pKU01hcmssaVN0YXJ0KSkgIT0gLTEpDQotCQl7DQotCQkJaWYgKGlFbmQgPiAwKQ0KLQkJCXsNCi0JCQkJaWYgKGNGb3JtYXRbaUVuZC0xXSA9PSBMJyUnKQ0KLQkJCQl7DQotCQkJCQlpU3RhcnQgPSBpRW5kKzE7DQotCQkJCQljb250aW51ZTsNCi0JCQkJfQ0KLQkJCX0NCi0JCQljRm9ybWF0LnJlcGxhY2UoaUVuZCxGWFNZU193Y3NsZW4oY1RhYmxlQWRbaUluZGV4XS5scHN6SlNNYXJrKSx0c3pWYWx1ZSk7DQotCQkJaVN0YXJ0ID0gaUVuZDsNCi0JCX0NCi0JfQ0KLQ0KLQkJQ0ZYX1dpZGVTdHJpbmcgc3RyRm9ybWF0Ow0KLS8vCQlzdHJGb3JtYXQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQsJWQsJWQsJWQsJWQsJWQiLGlZZWFyLCBpTW9udGgsIGlEYXksIGlIb3VyLCBpTWluLCBpU2VjKTsNCi0vLwkJQ1N0cmluZyBzdHJGb3JtYXQgPSBjcHBUbS5Gb3JtYXQoY0Zvcm1hdC5jX3N0cigpKTsNCi0JCXdjaGFyX3QgYnVmWzY0XSA9IHswfTsNCi0JCXN0ckZvcm1hdCA9IHdjc2Z0aW1lKGJ1ZiwgNjQsIGNGb3JtYXQuY19zdHIoKSwgJnRpbWUpOw0KLQkJY0Zvcm1hdCA9IGJ1ZjsNCi0JCWNQdXJwb3NlID0gY0Zvcm1hdDsNCi19DQotDQotRlhfQk9PTCB1dGlsOjpwcmludHgoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOw0KLQlpZiAoaVNpemU8MikNCi0JCXJldHVybiBGQUxTRTsNCi0JQ0ZYX1dpZGVTdHJpbmcgc0Zvcm1hdCA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOw0KLQlDRlhfV2lkZVN0cmluZyBzU291cmNlID0gcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotCXN0ZDo6c3RyaW5nIGNGb3JtYXQgPSAoRlhfTFBDU1RSKUNGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShzRm9ybWF0KTsNCi0Jc3RkOjpzdHJpbmcgY1NvdXJjZSA9IChGWF9MUENTVFIpQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHNTb3VyY2UpOw0KLQlzdGQ6OnN0cmluZyBjRGVzdDsNCi0JcHJpbnR4KGNGb3JtYXQsY1NvdXJjZSxjRGVzdCk7DQotCXZSZXQgPSBjRGVzdC5jX3N0cigpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCB1dGlsOjpwcmludHgoY29uc3Qgc3RkOjpzdHJpbmcgJmNGb3JtYXQsY29uc3Qgc3RkOjpzdHJpbmcgJmNTb3VyY2UyLHN0ZDo6c3RyaW5nICZjUHVycG9zZSkNCi17DQotCXN0ZDo6c3RyaW5nIGNTb3VyY2UoY1NvdXJjZTIpOw0KLQlpZiAoIWNQdXJwb3NlLmVtcHR5KCkpDQotCQkvL2NQdXJwb3NlLmNsZWFyKCk7DQotCQljUHVycG9zZS5lcmFzZSgpOw0KLQlpbnQgaXRTb3VyY2UgPSAwOw0KLQlpbnQgaVNpemUgPSBjU291cmNlLnNpemUoKTsNCi0JZm9yKGludCBpSW5kZXggPSAwOyBpSW5kZXggPCAoaW50KWNGb3JtYXQuc2l6ZSgpICYmIGl0U291cmNlPGlTaXplOyBpSW5kZXgrKykNCi0Jew0KLQkJY2hhciBsZXR0ZXIgPSBjRm9ybWF0W2lJbmRleF07DQotCQlzd2l0Y2gobGV0dGVyKQ0KLQkJew0KLQkJY2FzZSAnPyc6DQotCQkJLy9jUHVycG9zZS5wdXNoX2JhY2soY1NvdXJjZVtpdFNvdXJjZV0pOw0KLQkJCWNQdXJwb3NlICs9IGNTb3VyY2VbaXRTb3VyY2VdOw0KLQkJCWl0U291cmNlKys7DQotCQkJYnJlYWs7DQotCQljYXNlICdYJzoNCi0JCQl7DQotCQkJCXdoaWxlKGl0U291cmNlIDwgaVNpemUpDQotCQkJCXsNCi0JCQkJCWlmICgoY1NvdXJjZVtpdFNvdXJjZV0+PScwJyYmY1NvdXJjZVtpdFNvdXJjZV08PSc5JykgfHwgKGNTb3VyY2VbaXRTb3VyY2VdPj0nYScgJiYgY1NvdXJjZVtpdFNvdXJjZV08PSd6JykgfHwgKGNTb3VyY2VbaXRTb3VyY2VdPj0nQScgJiYgY1NvdXJjZVtpdFNvdXJjZV08PSdaJykpDQotCQkJCQl7DQotCQkJCQkJLy9jUHVycG9zZS5wdXNoX2JhY2soY1NvdXJjZVtpdFNvdXJjZV0pOw0KLQkJCQkJCWNQdXJwb3NlICs9IGNTb3VyY2VbaXRTb3VyY2VdOw0KLQkJCQkJCWl0U291cmNlKys7DQotCQkJCQkJYnJlYWs7DQotCQkJCQl9DQotCQkJCQlpdFNvdXJjZSsrOw0KLQkJCQl9DQotCQkJCWJyZWFrOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgJ0EnOg0KLQkJCXsNCi0JCQkJd2hpbGUoaXRTb3VyY2UgPCBpU2l6ZSkNCi0JCQkJew0KLQkJCQkJaWYgKChjU291cmNlW2l0U291cmNlXT49J2EnICYmIGNTb3VyY2VbaXRTb3VyY2VdPD0neicpIHx8IChjU291cmNlW2l0U291cmNlXT49J0EnICYmIGNTb3VyY2VbaXRTb3VyY2VdPD0nWicpKQ0KLQkJCQkJew0KLQkJCQkJCS8vY1B1cnBvc2UucHVzaF9iYWNrKGNTb3VyY2VbaXRTb3VyY2VdKTsNCi0JCQkJCQljUHVycG9zZSArPSBjU291cmNlW2l0U291cmNlXTsNCi0JCQkJCQlpdFNvdXJjZSsrOw0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJfQ0KLQkJCQkJaXRTb3VyY2UrKzsNCi0JCQkJfQ0KLQkJCQlicmVhazsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlICc5JzoNCi0JCQl7DQotCQkJCXdoaWxlKGl0U291cmNlIDwgaVNpemUpDQotCQkJCXsNCi0JCQkJCWlmIChjU291cmNlW2l0U291cmNlXT49JzAnJiZjU291cmNlW2l0U291cmNlXTw9JzknKQ0KLQkJCQkJew0KLQkJCQkJCS8vY1B1cnBvc2UucHVzaF9iYWNrKGNTb3VyY2VbaXRTb3VyY2VdKTsNCi0JCQkJCQljUHVycG9zZSArPSBjU291cmNlW2l0U291cmNlXTsNCi0JCQkJCQlpdFNvdXJjZSsrOw0KLQkJCQkJCWJyZWFrOw0KLQkJCQkJfQ0KLQkJCQkJaXRTb3VyY2UrKzsNCi0JCQkJfQ0KLQkJCQlicmVhazsNCi0JCQl9DQotCQljYXNlICcqJzoNCi0JCQl7DQotCQkJCWNQdXJwb3NlLmFwcGVuZChjU291cmNlLGl0U291cmNlLGlTaXplLWl0U291cmNlKTsNCi0JCQkJaXRTb3VyY2UgPSBpU2l6ZS0xOw0KLQkJCQlicmVhazsNCi0JCQl9DQotCQljYXNlICdcXCc6DQotCQkJYnJlYWs7DQotCQljYXNlICc+JzoNCi0JCQl7DQotCQkJCWZvcihzdGQ6OnN0cmluZzo6aXRlcmF0b3IgaXQgPSBjU291cmNlLmJlZ2luKCk7aXQgIT0gY1NvdXJjZS5lbmQoKTsgaXQrKykNCi0JCQkJew0KLQkJCQkJKml0ID0gdG91cHBlcigqaXQpOw0KLQkJCQl9DQotCQkJCWJyZWFrOw0KLQkJCX0NCi0JCWNhc2UgJzwnOg0KLQkJCXsNCi0JCQkJZm9yKHN0ZDo6c3RyaW5nOjppdGVyYXRvciBpdCA9IGNTb3VyY2UuYmVnaW4oKTtpdCAhPSBjU291cmNlLmVuZCgpOyBpdCsrKQ0KLQkJCQl7DQotCQkJCQkqaXQgPSB0b2xvd2VyKCppdCk7DQotCQkJCX0NCi0JCQkJYnJlYWs7DQotCQkJfQ0KLQkJY2FzZSAnPSc6DQotCQkJYnJlYWs7DQotCQlkZWZhdWx0Og0KLQkJCS8vY1B1cnBvc2UucHVzaF9iYWNrKGxldHRlcik7DQotCQkJY1B1cnBvc2UgKz0gbGV0dGVyOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgdXRpbDo6c2NhbmQoT0JKX01FVEhPRF9QQVJBTVMpDQotew0KLQl2ODo6SXNvbGF0ZSogaXNvbGF0ZSA9IEdldElzb2xhdGUoY2MpOw0KLQlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOw0KLQlpZiAoaVNpemUgPCAyKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlDRlhfV2lkZVN0cmluZyBzRm9ybWF0ID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotCUNGWF9XaWRlU3RyaW5nIHNEYXRlID0gcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7DQotDQotCWRvdWJsZSBkRGF0ZSA9IEpTX0dldERhdGVUaW1lKCk7DQotCWlmIChzRGF0ZS5HZXRMZW5ndGgoKSA+IDApDQotCXsNCi0JCUZYX0JPT0wgYldyb25nRm9ybWF0ID0gRkFMU0U7DQotCQlkRGF0ZSA9IENKU19QdWJsaWNNZXRob2RzOjpNYWtlUmVndWxhckRhdGUoc0RhdGUsc0Zvcm1hdCxiV3JvbmdGb3JtYXQpOw0KLQl9CQ0KLQkNCi0JaWYgKCFKU19Qb3J0SXNOYW4oZERhdGUpKQ0KLQl7DQotCQlDSlNfRGF0ZSBkYXRlKGlzb2xhdGUsZERhdGUpOw0KLQkJdlJldCA9IGRhdGU7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQl2UmV0LlNldE51bGwoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfSU5UNjQgRlhfYXRvaTY0KGNvbnN0IGNoYXIgKm5wdHIpDQotew0KLSAgICAgICAgaW50IGM7ICAgICAgICAgICAgICAvKiBjdXJyZW50IGNoYXIgKi8NCi0gICAgICAgIEZYX0lOVDY0IHRvdGFsOyAgICAgIC8qIGN1cnJlbnQgdG90YWwgKi8NCi0gICAgICAgIGludCBzaWduOyAgICAgICAgICAgLyogaWYgJy0nLCB0aGVuIG5lZ2F0aXZlLCBvdGhlcndpc2UgcG9zaXRpdmUgKi8NCi0NCi0gICAgICAgIC8qIHNraXAgd2hpdGVzcGFjZSAqLw0KLSAgICAgICAgd2hpbGUgKCBpc3NwYWNlKChpbnQpKHVuc2lnbmVkIGNoYXIpKm5wdHIpICkNCi0gICAgICAgICAgICArK25wdHI7DQotDQotICAgICAgICBjID0gKGludCkodW5zaWduZWQgY2hhcikqbnB0cisrOw0KLSAgICAgICAgc2lnbiA9IGM7ICAgICAgICAgICAvKiBzYXZlIHNpZ24gaW5kaWNhdGlvbiAqLw0KLSAgICAgICAgaWYgKGMgPT0gJy0nIHx8IGMgPT0gJysnKQ0KLSAgICAgICAgICAgIGMgPSAoaW50KSh1bnNpZ25lZCBjaGFyKSpucHRyKys7ICAgIC8qIHNraXAgc2lnbiAqLw0KLQ0KLSAgICAgICAgdG90YWwgPSAwOw0KLQ0KLSAgICAgICAgd2hpbGUgKGlzZGlnaXQoYykpIHsNCi0gICAgICAgICAgICB0b3RhbCA9IDEwICogdG90YWwgKyAoYyAtICcwJyk7ICAgICAvKiBhY2N1bXVsYXRlIGRpZ2l0ICovDQotICAgICAgICAgICAgYyA9IChpbnQpKHVuc2lnbmVkIGNoYXIpKm5wdHIrKzsgICAgLyogZ2V0IG5leHQgY2hhciAqLw0KLSAgICAgICAgfQ0KLQ0KLSAgICAgICAgaWYgKHNpZ24gPT0gJy0nKQ0KLSAgICAgICAgICAgIHJldHVybiAtdG90YWw7DQotICAgICAgICBlbHNlDQotICAgICAgICAgICAgcmV0dXJuIHRvdGFsOyAgIC8qIHJldHVybiByZXN1bHQsIG5lZ2F0ZWQgaWYgbmVjZXNzYXJ5ICovDQotfQ0KLQ0KLUZYX0JPT0wgdXRpbDo6Ynl0ZVRvQ2hhcihPQkpfTUVUSE9EX1BBUkFNUykNCi17DQotCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7DQotCWlmIChpU2l6ZSA9PSAwKQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQlpbnQgbkJ5dGUgPSAoaW50KXBhcmFtc1swXTsNCi0JdW5zaWduZWQgY2hhciBjQnl0ZSA9ICh1bnNpZ25lZCBjaGFyKW5CeXRlOw0KLQlDRlhfV2lkZVN0cmluZyBjc1ZhbHVlOw0KLQljc1ZhbHVlLkZvcm1hdCgoRlhfTFBDV1NUUilMIiVjIiwgY0J5dGUpOw0KLQl2UmV0ID0gY3NWYWx1ZTsgDQotCXJldHVybiBUUlVFOw0KLX0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0phdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSUphdmFTY3JpcHQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfRGVmaW5lLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L0pTX09iamVjdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19WYWx1ZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC91dGlsLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9qYXZhc2NyaXB0L1B1YmxpY01ldGhvZHMuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvcmVzb3VyY2UuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfQ29udGV4dC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvamF2YXNjcmlwdC9KU19FdmVudEhhbmRsZXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL2phdmFzY3JpcHQvSlNfUnVudGltZS5oIgorCisjaWYgX0ZYX09TXyAgPT0gX0ZYX0FORFJPSURfCisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNlbmRpZgorCitzdGF0aWMgdjg6Oklzb2xhdGUqIEdldElzb2xhdGUoSUZYSlNfQ29udGV4dCogY2MpCit7CisJQ0pTX0NvbnRleHQqIHBDb250ZXh0ID0gKENKU19Db250ZXh0ICopY2M7CisJQVNTRVJUKHBDb250ZXh0ICE9IE5VTEwpOworCisJQ0pTX1J1bnRpbWUqIHBSdW50aW1lID0gcENvbnRleHQtPkdldEpTUnVudGltZSgpOworCUFTU0VSVChwUnVudGltZSAhPSBOVUxMKTsKKworCXJldHVybiBwUnVudGltZS0+R2V0SXNvbGF0ZSgpOworfQorCitCRUdJTl9KU19TVEFUSUNfQ09OU1QoQ0pTX1V0aWwpCitFTkRfSlNfU1RBVElDX0NPTlNUKCkKKworQkVHSU5fSlNfU1RBVElDX1BST1AoQ0pTX1V0aWwpCitFTkRfSlNfU1RBVElDX1BST1AoKQorCitCRUdJTl9KU19TVEFUSUNfTUVUSE9EKENKU19VdGlsKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkocHJpbnRkLCAzKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkocHJpbnRmLCAyMCkKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHByaW50eCwgMikKKwlKU19TVEFUSUNfTUVUSE9EX0VOVFJZKHNjYW5kLCAyKQorCUpTX1NUQVRJQ19NRVRIT0RfRU5UUlkoYnl0ZVRvQ2hhciwgMSkKK0VORF9KU19TVEFUSUNfTUVUSE9EKCkKKworSU1QTEVNRU5UX0pTX0NMQVNTKENKU19VdGlsLHV0aWwpCisKK3V0aWw6OnV0aWwoQ0pTX09iamVjdCAqcEpTT2JqZWN0KSA6IENKU19FbWJlZE9iaihwSlNPYmplY3QpCit7Cit9CisKK3V0aWw6On51dGlsKHZvaWQpCit7Cit9CisKKworc3RydWN0IHN0cnVfVGJDb252ZXJ0Cit7CisJRlhfTFBDV1NUUiBscHN6SlNNYXJrOworCUZYX0xQQ1dTVFIgbHBzekNwcE1hcms7Cit9OworCitjb25zdCBzdHJ1X1RiQ29udmVydCBmY1RhYmxlW10gPSB7CisJKEZYX0xQQ1dTVFIpTCJtbW1tIiwgKEZYX0xQQ1dTVFIpTCIlQiIsCisJKEZYX0xQQ1dTVFIpTCJtbW0iLCAoRlhfTFBDV1NUUilMIiViIiwKKwkoRlhfTFBDV1NUUilMIm1tIiwgIChGWF9MUENXU1RSKUwiJW0iLAorCS8vIm0iCisJKEZYX0xQQ1dTVFIpTCJkZGRkIiwgKEZYX0xQQ1dTVFIpTCIlQSIsCisJKEZYX0xQQ1dTVFIpTCJkZGQiLCAoRlhfTFBDV1NUUilMIiVhIiwKKwkoRlhfTFBDV1NUUilMImRkIiwgIChGWF9MUENXU1RSKUwiJWQiLAorCS8vImQiLCAgICIldyIsCisJKEZYX0xQQ1dTVFIpTCJ5eXl5IiwgKEZYX0xQQ1dTVFIpTCIlWSIsCisJKEZYX0xQQ1dTVFIpTCJ5eSIsICAoRlhfTFBDV1NUUilMIiV5IiwKKwkoRlhfTFBDV1NUUilMIkhIIiwgIChGWF9MUENXU1RSKUwiJUgiLAorCS8vIkgiCisJKEZYX0xQQ1dTVFIpTCJoaCIsICAoRlhfTFBDV1NUUilMIiVJIiwKKwkvLyJoIgorCShGWF9MUENXU1RSKUwiTU0iLCAgKEZYX0xQQ1dTVFIpTCIlTSIsCisJLy8iTSIKKwkoRlhfTFBDV1NUUilMInNzIiwgIChGWF9MUENXU1RSKUwiJVMiLAorCS8vInMKKwkoRlhfTFBDV1NUUilMIlRUIiwgIChGWF9MUENXU1RSKUwiJXAiLAorCS8vInQiCisjaWYgZGVmaW5lZChfV0lOMzIpCisJKEZYX0xQQ1dTVFIpTCJ0dCIsICAoRlhfTFBDV1NUUilMIiVwIiwKKwkoRlhfTFBDV1NUUilMImgiLCAgKEZYX0xQQ1dTVFIpTCIlI0kiLAorI2Vsc2UKKwkoRlhfTFBDV1NUUilMInR0IiwgIChGWF9MUENXU1RSKUwiJVAiLAorCShGWF9MUENXU1RSKUwiaCIsICAoRlhfTFBDV1NUUilMIiVsIiwKKyNlbmRpZgorfTsKKworI2RlZmluZSBVVElMX0lOVAkJCTAKKyNkZWZpbmUgVVRJTF9ET1VCTEUJCQkxCisjZGVmaW5lIFVUSUxfU1RSSU5HCQkJMgorCitpbnQgdXRpbDo6UGFyc3REYXRhVHlwZShzdGQ6OndzdHJpbmcqIHNGb3JtYXQpCit7CisgICAgICAgIHNpemVfdCBpID0gMDsKKwlib29sIGJQZXJjZW50ID0gRkFMU0U7CisJZm9yIChpPTA7IGk8c0Zvcm1hdC0+bGVuZ3RoKCk7ICsraSkKKwl7CisJCXdjaGFyX3QgYyA9ICgqc0Zvcm1hdClbaV07CisJCWlmIChjID09IEwnJScpCisJCXsKKwkJCWJQZXJjZW50ID0gdHJ1ZTsKKwkJCWNvbnRpbnVlOworCQl9CisKKwkJaWYgKGJQZXJjZW50KQorCQl7CisJCQlpZiAoYyA9PSBMJ2MnIHx8IGMgPT0gTCdDJyB8fCBjID09IEwnZCcgfHwgYyA9PSBMJ2knIHx8IGMgPT0gTCdvJyB8fCBjID09IEwndScgfHwgYyA9PSBMJ3gnIHx8IGMgPT0gTCdYJykKKwkJCXsKKwkJCQlyZXR1cm4gVVRJTF9JTlQ7CisJCQl9CisJCQllbHNlIGlmIChjID09IEwnZScgfHwgYyA9PSBMJ0UnIHx8IGMgPT0gTCdmJyB8fCBjID09IEwnZycgfHwgYyA9PSBMJ0cnKQorCQkJeworCQkJCXJldHVybiBVVElMX0RPVUJMRTsKKwkJCX0KKwkJCWVsc2UgaWYgKGMgPT0gTCdzJyB8fCBjID09IEwnUycpCisJCQl7CisJCQkJLy8gTWFwIHMgdG8gUyBzaW5jZSB3ZSBhbHdheXMgZGVhbCBpbnRlcm5hbGx5CisJCQkJLy8gd2l0aCB3Y2hhcl90IHN0cmluZ3MuCisJCQkJKCpzRm9ybWF0KVtpXSA9IEwnUyc7CisJCQkJcmV0dXJuIFVUSUxfU1RSSU5HOworCQkJfQorCQkJZWxzZSBpZiAoYyA9PSBMJy4nIHx8IGMgPT0gTCcrJyB8fCBjID09IEwnLScgfHwgYyA9PSBMJyMnIHx8IGMgPT0gTCcgJyB8fCBDSlNfUHVibGljTWV0aG9kczo6SXNEaWdpdChjKSkKKwkJCXsKKwkJCQljb250aW51ZTsKKwkJCX0KKwkJCWVsc2UgYnJlYWs7CisJCX0KKwl9CisKKwlyZXR1cm4gLTE7Cit9CisKK0ZYX0JPT0wgdXRpbDo6cHJpbnRmKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7CisJaWYgKGlTaXplIDwgMSkKKwkJcmV0dXJuIEZBTFNFOworCXN0ZDo6d3N0cmluZyAgY19Db252Q2hhcigoY29uc3Qgd2NoYXJfdCopKEZYX0xQQ1dTVFIpcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOworCXN0ZDo6dmVjdG9yPHN0ZDo6d3N0cmluZz4gY19zdHJDb252ZXJzOworCWludCBpT2Zmc2V0ID0gMDsKKwlpbnQgaU9mZmVuZCA9IDA7CisJY19Db252Q2hhci5pbnNlcnQoY19Db252Q2hhci5iZWdpbigpLEwnUycpOworCXdoaWxlKGlPZmZzZXQgIT0gLTEpCisJeworCQlpT2ZmZW5kID0gY19Db252Q2hhci5maW5kKEwiJSIsaU9mZnNldCsxKTsKKwkJc3RkOjp3c3RyaW5nIHN0clN1YjsKKwkJaWYgKGlPZmZlbmQgPT0gLTEpCisJCQlzdHJTdWIgPSBjX0NvbnZDaGFyLnN1YnN0cihpT2Zmc2V0KTsJCQkKKwkJZWxzZQorCQkJc3RyU3ViID0gY19Db252Q2hhci5zdWJzdHIoaU9mZnNldCAsaU9mZmVuZCAtIGlPZmZzZXQpOworCQljX3N0ckNvbnZlcnMucHVzaF9iYWNrKHN0clN1Yik7CisJCWlPZmZzZXQgPSBpT2ZmZW5kIDsKKwl9CisKKwlzdGQ6OndzdHJpbmcgY19zdHJSZXN1bHQ7CisKKwkvL2ZvcihpbnQgaUluZGV4ID0gMTtpSW5kZXggPCBwYXJhbXMuc2l6ZSgpO2lJbmRleCsrKQorCXN0ZDo6d3N0cmluZyBjX3N0ckZvcm1hdDsKKwlmb3IoaW50IGlJbmRleCA9IDA7aUluZGV4IDwgKGludCljX3N0ckNvbnZlcnMuc2l6ZSgpO2lJbmRleCsrKQorCXsKKwkJY19zdHJGb3JtYXQgPSBjX3N0ckNvbnZlcnNbaUluZGV4XTsKKwkJaWYgKGlJbmRleCA9PSAwKQorCQl7CisJCQljX3N0clJlc3VsdCA9IGNfc3RyRm9ybWF0OworCQkJY29udGludWU7CisJCX0KKworCisJCUNGWF9XaWRlU3RyaW5nIHN0clNlZ21lbnQ7CisJCWlmIChpSW5kZXggPj0gaVNpemUpIHsKKwkJCWNfc3RyUmVzdWx0ICs9IGNfc3RyRm9ybWF0OworCQkJY29udGludWU7CisJCX0KKworCQlzd2l0Y2ggKFBhcnN0RGF0YVR5cGUoJmNfc3RyRm9ybWF0KSkKKwkJeworCQkJY2FzZSBVVElMX0lOVDoKKwkJCQlzdHJTZWdtZW50LkZvcm1hdCgoRlhfTFBDV1NUUiljX3N0ckZvcm1hdC5jX3N0cigpLChpbnQpcGFyYW1zW2lJbmRleF0pOworCQkJCWJyZWFrOworCQkJY2FzZSBVVElMX0RPVUJMRToKKwkJCQlzdHJTZWdtZW50LkZvcm1hdCgoRlhfTFBDV1NUUiljX3N0ckZvcm1hdC5jX3N0cigpLChkb3VibGUpcGFyYW1zW2lJbmRleF0pOworCQkJCWJyZWFrOworCQkJY2FzZSBVVElMX1NUUklORzoKKwkJCQlzdHJTZWdtZW50LkZvcm1hdCgoRlhfTFBDV1NUUiljX3N0ckZvcm1hdC5jX3N0cigpLChGWF9MUENXU1RSKXBhcmFtc1tpSW5kZXhdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCkpOworCQkJCWJyZWFrOworCQkJZGVmYXVsdDoKKwkJCQlzdHJTZWdtZW50LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVTIiwgKEZYX0xQQ1dTVFIpY19zdHJGb3JtYXQuY19zdHIoKSk7CisJCQkJYnJlYWs7CisJCX0KKwkJY19zdHJSZXN1bHQgKz0gKHdjaGFyX3QqKXN0clNlZ21lbnQuR2V0QnVmZmVyKHN0clNlZ21lbnQuR2V0TGVuZ3RoKCkrMSk7CisJfQorCisJY19zdHJSZXN1bHQuZXJhc2UoY19zdHJSZXN1bHQuYmVnaW4oKSk7CisJdlJldCA9IChGWF9MUENXU1RSKWNfc3RyUmVzdWx0LmNfc3RyKCk7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgdXRpbDo6cHJpbnRkKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7CisKKwlpbnQgaVNpemUgPSBwYXJhbXMuc2l6ZSgpOworCWlmIChpU2l6ZSA8IDIpCisJCXJldHVybiBGQUxTRTsKKworCUNKU19WYWx1ZSBwMShpc29sYXRlKTsKKwlwMSA9IHBhcmFtc1swXTsKKworCUNKU19WYWx1ZSBwMiA9IHBhcmFtc1sxXTsKKwlDSlNfRGF0ZSBqc0RhdGUoaXNvbGF0ZSk7CisJaWYgKCFwMi5Db252ZXJ0VG9EYXRlKGpzRGF0ZSkpCisJeworCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTUFJJTlQxKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCWlmICghanNEYXRlLklzVmFsaWREYXRlKCkpCisJeworCQlzRXJyb3IgPSBKU0dldFN0cmluZ0Zyb21JRCgoQ0pTX0NvbnRleHQqKWNjLCBJRFNfU1RSSU5HX0pTUFJJTlQyKTsKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCWlmIChwMS5HZXRUeXBlKCkgPT0gVlRfbnVtYmVyKQorCXsKKwkJaW50IG5Gb3JtYXQgPSBwMTsKKworCQlDRlhfV2lkZVN0cmluZyBzd1Jlc3VsdDsKKworCQlzd2l0Y2ggKG5Gb3JtYXQpCisJCXsKKwkJY2FzZSAwOgorCQkJc3dSZXN1bHQuRm9ybWF0KChGWF9MUENXU1RSKUwiRDolMDRkJTAyZCUwMmQlMDJkJTAyZCUwMmQiLCAKKwkJCQlqc0RhdGUuR2V0WWVhcigpLAorCQkJCWpzRGF0ZS5HZXRNb250aCgpICsgMSwKKwkJCQlqc0RhdGUuR2V0RGF5KCksCisJCQkJanNEYXRlLkdldEhvdXJzKCksCisJCQkJanNEYXRlLkdldE1pbnV0ZXMoKSwKKwkJCQlqc0RhdGUuR2V0U2Vjb25kcygpKTsKKwkJCWJyZWFrOworCQljYXNlIDE6CisJCQlzd1Jlc3VsdC5Gb3JtYXQoKEZYX0xQQ1dTVFIpTCIlMDRkLiUwMmQuJTAyZCAlMDJkOiUwMmQ6JTAyZCIsIAorCQkJCWpzRGF0ZS5HZXRZZWFyKCksCisJCQkJanNEYXRlLkdldE1vbnRoKCkgKyAxLAorCQkJCWpzRGF0ZS5HZXREYXkoKSwKKwkJCQlqc0RhdGUuR2V0SG91cnMoKSwKKwkJCQlqc0RhdGUuR2V0TWludXRlcygpLAorCQkJCWpzRGF0ZS5HZXRTZWNvbmRzKCkpOworCQkJYnJlYWs7CisJCWNhc2UgMjoKKwkJCXN3UmVzdWx0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiUwNGQvJTAyZC8lMDJkICUwMmQ6JTAyZDolMDJkIiwgCisJCQkJanNEYXRlLkdldFllYXIoKSwKKwkJCQlqc0RhdGUuR2V0TW9udGgoKSArIDEsCisJCQkJanNEYXRlLkdldERheSgpLAorCQkJCWpzRGF0ZS5HZXRIb3VycygpLAorCQkJCWpzRGF0ZS5HZXRNaW51dGVzKCksCisJCQkJanNEYXRlLkdldFNlY29uZHMoKSk7CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJCXJldHVybiBGQUxTRTsKKwkJfQorCisJCXZSZXQgPSBzd1Jlc3VsdDsKKwkJcmV0dXJuIFRSVUU7CisJfQorCWVsc2UgaWYgKHAxLkdldFR5cGUoKSA9PSBWVF9zdHJpbmcpCisJeworCQlzdGQ6OmJhc2ljX3N0cmluZzx3Y2hhcl90PiBjRm9ybWF0ID0gKHdjaGFyX3QqKShGWF9MUENXU1RSKXAxLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CQkKKworCQlib29sIGJYRkFQaWN0dXJlID0gZmFsc2U7CisJCWlmIChpU2l6ZSA+IDIpCisJCXsKKwkJCS8vQ0pTX1ZhbHVlIHZhbHVlOworCQkJYlhGQVBpY3R1cmUgPSBwYXJhbXNbMl07CisJCX0KKworCQlpZiAoYlhGQVBpY3R1cmUpCisJCXsKKwkJCXJldHVybiBGQUxTRTsgLy9jdXJyZW50bHksIGl0IGRvZXNuJ3Qgc3VwcG9ydCBYRkFQaWN0dXJlLgorCQl9CisKKyAgICAgICAgaW50IGlJbmRleDsKKwkJZm9yKGlJbmRleCA9IDA7aUluZGV4PHNpemVvZihmY1RhYmxlKS9zaXplb2Yoc3RydV9UYkNvbnZlcnQpO2lJbmRleCsrKQorCQl7CisJCQlpbnQgaVN0YXJ0ID0gMDsKKwkJCWludCBpRW5kOworCQkJd2hpbGUoKGlFbmQgPSBjRm9ybWF0LmZpbmQoKENGWF9XaWRlU3RyaW5nKWZjVGFibGVbaUluZGV4XS5scHN6SlNNYXJrLCBpU3RhcnQpKSAhPSAtMSkKKwkJCXsKKwkJCQljRm9ybWF0LnJlcGxhY2UoaUVuZCwgRlhTWVNfd2NzbGVuKGZjVGFibGVbaUluZGV4XS5scHN6SlNNYXJrKSwgKENGWF9XaWRlU3RyaW5nKWZjVGFibGVbaUluZGV4XS5scHN6Q3BwTWFyayk7CisJCQkJaVN0YXJ0ID0gaUVuZDsKKwkJCX0KKwkJfQorCisJCWludCBpWWVhcixpTW9udGgsaURheSxpSG91cixpTWluLGlTZWM7CisJCWlZZWFyID0ganNEYXRlLkdldFllYXIoKTsKKwkJaU1vbnRoID0ganNEYXRlLkdldE1vbnRoKCk7CisJCWlEYXkgPSBqc0RhdGUuR2V0RGF5KCk7CisJCWlIb3VyID0ganNEYXRlLkdldEhvdXJzKCk7CisJCWlNaW4gPSBqc0RhdGUuR2V0TWludXRlcygpOworCQlpU2VjID0ganNEYXRlLkdldFNlY29uZHMoKTsKKworCQlzdHJ1Y3QgdG0gdGltZSA9IHswfTsKKwkJdGltZS50bV95ZWFyID0gaVllYXItMTkwMDsKKwkJdGltZS50bV9tb24gPSBpTW9udGg7CisJCXRpbWUudG1fbWRheSA9IGlEYXk7CisJCXRpbWUudG1faG91ciA9IGlIb3VyOworCQl0aW1lLnRtX21pbiA9IGlNaW47CisJCXRpbWUudG1fc2VjID0gaVNlYzsKKwkJLy9DT2xlRGF0ZVRpbWUgY3BwVG0oaVllYXIsaU1vbnRoKzEsaURheSxpSG91cixpTWluLGlTZWMpOworCQkvL0NTdHJpbmcgc3RyRm9ybWF0ID0gY3BwVG0uRm9ybWF0KGNGb3JtYXQuY19zdHIoKSk7CisKKwkJc3RydWN0IHN0cnVfVGJDb252ZXJ0QWQKKwkJeworCQkJRlhfTFBDV1NUUiBscHN6SlNNYXJrOworCQkJaW50ICAgICBpVmFsdWU7CisJCX07CisKKwkJc3RydV9UYkNvbnZlcnRBZCBjVGFibGVBZFtdID17CisJCQkoRlhfTFBDV1NUUilMIm0iLCBpTW9udGgrMSwKKwkJCQkoRlhfTFBDV1NUUilMImQiLCBpRGF5LAorCQkJCShGWF9MUENXU1RSKUwiSCIsIGlIb3VyLAorCQkJCShGWF9MUENXU1RSKUwiaCIsIGlIb3VyPjEyP2lIb3VyLTEyOmlIb3VyLAorCQkJCShGWF9MUENXU1RSKUwiTSIsIGlNaW4sCisJCQkJKEZYX0xQQ1dTVFIpTCJzIiwgaVNlYworCQl9OworCisJCS8vY0Zvcm1hdCA9IHN0ckZvcm1hdC5HZXRCdWZmZXIoc3RyRm9ybWF0LkdldExlbmd0aCgpKzEpOworCQlmb3IoaUluZGV4ID0gMDtpSW5kZXg8c2l6ZW9mKGNUYWJsZUFkKS9zaXplb2Yoc3RydV9UYkNvbnZlcnRBZCk7aUluZGV4KyspCisJCXsKKwkJCXdjaGFyX3QgdHN6VmFsdWVbMTBdOworCQkJLy9faXRvdChjVGFibGVBZFtpSW5kZXhdLmlWYWx1ZSx0c3pWYWx1ZSwxMCk7CisJCQlDRlhfV2lkZVN0cmluZyBzVmFsdWU7CisJCQlzVmFsdWUuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQiLGNUYWJsZUFkW2lJbmRleF0uaVZhbHVlKTsKKwkJCW1lbWNweSh0c3pWYWx1ZSwgKHdjaGFyX3QgKilzVmFsdWUuR2V0QnVmZmVyKHNWYWx1ZS5HZXRMZW5ndGgoKSsxKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc1ZhbHVlLkdldExlbmd0aCgpKzEpKnNpemVvZih3Y2hhcl90KSk7CisKKwkJCS8vc3RyRm9ybWF0LlJlcGxhY2UoY1RhYmxlQWRbaUluZGV4XS5scHN6SlNNYXJrLCIlZCIpOworCQkJLy9zdHJGb3JtYXQuRm9ybWF0KHN0ckZvcm1hdCxjVGFibGVBZFtpSW5kZXhdLmlWYWx1ZSk7CisJCQlpbnQgaVN0YXJ0ID0gMDsKKwkJCWludCBpRW5kOworCQkJd2hpbGUoKGlFbmQgPSBjRm9ybWF0LmZpbmQoKENGWF9XaWRlU3RyaW5nKWNUYWJsZUFkW2lJbmRleF0ubHBzekpTTWFyayxpU3RhcnQpKSAhPSAtMSkKKwkJCXsKKwkJCQlpZiAoaUVuZCA+IDApCisJCQkJeworCQkJCQlpZiAoY0Zvcm1hdFtpRW5kLTFdID09IEwnJScpCisJCQkJCXsKKwkJCQkJCWlTdGFydCA9IGlFbmQrMTsKKwkJCQkJCWNvbnRpbnVlOworCQkJCQl9CisJCQkJfQorCQkJCWNGb3JtYXQucmVwbGFjZShpRW5kLCBGWFNZU193Y3NsZW4oY1RhYmxlQWRbaUluZGV4XS5scHN6SlNNYXJrKSwgdHN6VmFsdWUpOworCQkJCWlTdGFydCA9IGlFbmQ7CisJCQl9CisJCX0KKworCQlDRlhfV2lkZVN0cmluZyBzdHJGb3JtYXQ7CisvLwkJc3RyRm9ybWF0LkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkLCVkLCVkLCVkLCVkLCVkIixpWWVhciwgaU1vbnRoLCBpRGF5LCBpSG91ciwgaU1pbiwgaVNlYyk7CisvLwkJQ1N0cmluZyBzdHJGb3JtYXQgPSBjcHBUbS5Gb3JtYXQoY0Zvcm1hdC5jX3N0cigpKTsKKwkJd2NoYXJfdCBidWZbNjRdID0gezB9OworCQlzdHJGb3JtYXQgPSB3Y3NmdGltZShidWYsIDY0LCBjRm9ybWF0LmNfc3RyKCksICZ0aW1lKTsKKwkJY0Zvcm1hdCA9IGJ1ZjsKKwkJdlJldCA9IChGWF9MUENXU1RSKWNGb3JtYXQuY19zdHIoKTsKKwkJLy9ydFJldCA9IHN0ckZvcm1hdC5HZXRCdWZmZXIoc3RyRm9ybWF0LkdldExlbmd0aCgpKzEpOworCQlyZXR1cm4gVFJVRTsKKwl9CisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIHV0aWw6OnByaW50ZChjb25zdCBzdGQ6OndzdHJpbmcgJmNGb3JtYXQyLCBDSlNfRGF0ZSBqc0RhdGUsIGJvb2wgYlhGQVBpY3R1cmUsIHN0ZDo6d3N0cmluZyAmY1B1cnBvc2UpCit7CisJc3RkOjp3c3RyaW5nIGNGb3JtYXQgPSBjRm9ybWF0MjsKKwkgICAgCisJaWYgKGJYRkFQaWN0dXJlKQorCXsKKwkJcmV0dXJuIDsgLy9jdXJyZW50bHksIGl0IGRvZXNuJ3Qgc3VwcG9ydCBYRkFQaWN0dXJlLgorCX0KKworICAgIGludCBpSW5kZXg7CisJZm9yKGlJbmRleCA9IDA7aUluZGV4PHNpemVvZihmY1RhYmxlKS9zaXplb2Yoc3RydV9UYkNvbnZlcnQpO2lJbmRleCsrKQorCXsKKwkJaW50IGlTdGFydCA9IDA7CisJCWludCBpRW5kOworCQl3aGlsZSgoaUVuZCA9IGNGb3JtYXQuZmluZCgoQ0ZYX1dpZGVTdHJpbmcpZmNUYWJsZVtpSW5kZXhdLmxwc3pKU01hcmssaVN0YXJ0KSkgIT0gLTEpCisJCXsKKwkJCWNGb3JtYXQucmVwbGFjZShpRW5kLEZYU1lTX3djc2xlbihmY1RhYmxlW2lJbmRleF0ubHBzekpTTWFyayksIChDRlhfV2lkZVN0cmluZylmY1RhYmxlW2lJbmRleF0ubHBzekNwcE1hcmspOworCQkJaVN0YXJ0ID0gaUVuZDsKKwkJfQorCX0KKworCWludCBpWWVhcixpTW9udGgsaURheSxpSG91cixpTWluLGlTZWM7CisJaVllYXIgPSBqc0RhdGUuR2V0WWVhcigpOworCWlNb250aCA9IGpzRGF0ZS5HZXRNb250aCgpOworCWlEYXkgPSBqc0RhdGUuR2V0RGF5KCk7CisJaUhvdXIgPSBqc0RhdGUuR2V0SG91cnMoKTsKKwlpTWluID0ganNEYXRlLkdldE1pbnV0ZXMoKTsKKwlpU2VjID0ganNEYXRlLkdldFNlY29uZHMoKTsKKworCXN0cnVjdCB0bSB0aW1lID0gezB9OworCXRpbWUudG1feWVhciA9IGlZZWFyLTE5MDA7CisJdGltZS50bV9tb24gPSBpTW9udGg7CisJdGltZS50bV9tZGF5ID0gaURheTsKKwl0aW1lLnRtX2hvdXIgPSBpSG91cjsKKwl0aW1lLnRtX21pbiA9IGlNaW47CisJdGltZS50bV9zZWMgPSBpU2VjOworLy8JQ09sZURhdGVUaW1lIGNwcFRtKGlZZWFyLGlNb250aCsxLGlEYXksaUhvdXIsaU1pbixpU2VjKTsKKwkvL0NTdHJpbmcgc3RyRm9ybWF0ID0gY3BwVG0uRm9ybWF0KGNGb3JtYXQuY19zdHIoKSk7CisKKwlzdHJ1Y3Qgc3RydV9UYkNvbnZlcnRBZAorCXsKKwkJRlhfTFBDV1NUUiBscHN6SlNNYXJrOworCQlpbnQgICAgIGlWYWx1ZTsKKwl9OworCisJc3RydV9UYkNvbnZlcnRBZCBjVGFibGVBZFtdID17CisJCShGWF9MUENXU1RSKUwibSIsIGlNb250aCsxLAorCQkJKEZYX0xQQ1dTVFIpTCJkIiwgaURheSwKKwkJCShGWF9MUENXU1RSKUwiSCIsIGlIb3VyLAorCQkJKEZYX0xQQ1dTVFIpTCJoIiwgaUhvdXI+MTI/aUhvdXItMTI6aUhvdXIsCisJCQkoRlhfTFBDV1NUUilMIk0iLCBpTWluLAorCQkJKEZYX0xQQ1dTVFIpTCJzIiwgaVNlYworCX07CisKKwkvL2NGb3JtYXQgPSBzdHJGb3JtYXQuR2V0QnVmZmVyKHN0ckZvcm1hdC5HZXRMZW5ndGgoKSsxKTsKKwlmb3IoaUluZGV4ID0gMDtpSW5kZXg8c2l6ZW9mKGNUYWJsZUFkKS9zaXplb2Yoc3RydV9UYkNvbnZlcnRBZCk7aUluZGV4KyspCisJeworCQl3Y2hhcl90IHRzelZhbHVlWzEwXTsKKwkJLy9faXRvdChjVGFibGVBZFtpSW5kZXhdLmlWYWx1ZSx0c3pWYWx1ZSwxMCk7CisJCUNGWF9XaWRlU3RyaW5nIHNWYWx1ZTsKKwkJc1ZhbHVlLkZvcm1hdCgoRlhfTFBDV1NUUilMIiVkIixjVGFibGVBZFtpSW5kZXhdLmlWYWx1ZSk7CisJCW1lbWNweSh0c3pWYWx1ZSwgKHdjaGFyX3QgKilzVmFsdWUuR2V0QnVmZmVyKHNWYWx1ZS5HZXRMZW5ndGgoKSsxKSxzVmFsdWUuR2V0TGVuZ3RoKCkqc2l6ZW9mKHdjaGFyX3QpKTsKKworCisJCS8vc3RyRm9ybWF0LlJlcGxhY2UoY1RhYmxlQWRbaUluZGV4XS5scHN6SlNNYXJrLCIlZCIpOworCQkvL3N0ckZvcm1hdC5Gb3JtYXQoc3RyRm9ybWF0LGNUYWJsZUFkW2lJbmRleF0uaVZhbHVlKTsKKwkJaW50IGlTdGFydCA9IDA7CisJCWludCBpRW5kOworCQl3aGlsZSgoaUVuZCA9IGNGb3JtYXQuZmluZCgoQ0ZYX1dpZGVTdHJpbmcpY1RhYmxlQWRbaUluZGV4XS5scHN6SlNNYXJrLGlTdGFydCkpICE9IC0xKQorCQl7CisJCQlpZiAoaUVuZCA+IDApCisJCQl7CisJCQkJaWYgKGNGb3JtYXRbaUVuZC0xXSA9PSBMJyUnKQorCQkJCXsKKwkJCQkJaVN0YXJ0ID0gaUVuZCsxOworCQkJCQljb250aW51ZTsKKwkJCQl9CisJCQl9CisJCQljRm9ybWF0LnJlcGxhY2UoaUVuZCxGWFNZU193Y3NsZW4oY1RhYmxlQWRbaUluZGV4XS5scHN6SlNNYXJrKSx0c3pWYWx1ZSk7CisJCQlpU3RhcnQgPSBpRW5kOworCQl9CisJfQorCisJCUNGWF9XaWRlU3RyaW5nIHN0ckZvcm1hdDsKKy8vCQlzdHJGb3JtYXQuRm9ybWF0KChGWF9MUENXU1RSKUwiJWQsJWQsJWQsJWQsJWQsJWQiLGlZZWFyLCBpTW9udGgsIGlEYXksIGlIb3VyLCBpTWluLCBpU2VjKTsKKy8vCQlDU3RyaW5nIHN0ckZvcm1hdCA9IGNwcFRtLkZvcm1hdChjRm9ybWF0LmNfc3RyKCkpOworCQl3Y2hhcl90IGJ1Zls2NF0gPSB7MH07CisJCXN0ckZvcm1hdCA9IHdjc2Z0aW1lKGJ1ZiwgNjQsIGNGb3JtYXQuY19zdHIoKSwgJnRpbWUpOworCQljRm9ybWF0ID0gYnVmOworCQljUHVycG9zZSA9IGNGb3JtYXQ7Cit9CisKK0ZYX0JPT0wgdXRpbDo6cHJpbnR4KE9CSl9NRVRIT0RfUEFSQU1TKQoreworCWludCBpU2l6ZSA9IHBhcmFtcy5zaXplKCk7CisJaWYgKGlTaXplPDIpCisJCXJldHVybiBGQUxTRTsKKwlDRlhfV2lkZVN0cmluZyBzRm9ybWF0ID0gcGFyYW1zWzBdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisJQ0ZYX1dpZGVTdHJpbmcgc1NvdXJjZSA9IHBhcmFtc1sxXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCXN0ZDo6c3RyaW5nIGNGb3JtYXQgPSAoRlhfTFBDU1RSKUNGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShzRm9ybWF0KTsKKwlzdGQ6OnN0cmluZyBjU291cmNlID0gKEZYX0xQQ1NUUilDRlhfQnl0ZVN0cmluZzo6RnJvbVVuaWNvZGUoc1NvdXJjZSk7CisJc3RkOjpzdHJpbmcgY0Rlc3Q7CisJcHJpbnR4KGNGb3JtYXQsY1NvdXJjZSxjRGVzdCk7CisJdlJldCA9IGNEZXN0LmNfc3RyKCk7CisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgdXRpbDo6cHJpbnR4KGNvbnN0IHN0ZDo6c3RyaW5nICZjRm9ybWF0LGNvbnN0IHN0ZDo6c3RyaW5nICZjU291cmNlMixzdGQ6OnN0cmluZyAmY1B1cnBvc2UpCit7CisJc3RkOjpzdHJpbmcgY1NvdXJjZShjU291cmNlMik7CisJaWYgKCFjUHVycG9zZS5lbXB0eSgpKQorCQkvL2NQdXJwb3NlLmNsZWFyKCk7CisJCWNQdXJwb3NlLmVyYXNlKCk7CisJaW50IGl0U291cmNlID0gMDsKKwlpbnQgaVNpemUgPSBjU291cmNlLnNpemUoKTsKKwlmb3IoaW50IGlJbmRleCA9IDA7IGlJbmRleCA8IChpbnQpY0Zvcm1hdC5zaXplKCkgJiYgaXRTb3VyY2U8aVNpemU7IGlJbmRleCsrKQorCXsKKwkJY2hhciBsZXR0ZXIgPSBjRm9ybWF0W2lJbmRleF07CisJCXN3aXRjaChsZXR0ZXIpCisJCXsKKwkJY2FzZSAnPyc6CisJCQkvL2NQdXJwb3NlLnB1c2hfYmFjayhjU291cmNlW2l0U291cmNlXSk7CisJCQljUHVycG9zZSArPSBjU291cmNlW2l0U291cmNlXTsKKwkJCWl0U291cmNlKys7CisJCQlicmVhazsKKwkJY2FzZSAnWCc6CisJCQl7CisJCQkJd2hpbGUoaXRTb3VyY2UgPCBpU2l6ZSkKKwkJCQl7CisJCQkJCWlmICgoY1NvdXJjZVtpdFNvdXJjZV0+PScwJyYmY1NvdXJjZVtpdFNvdXJjZV08PSc5JykgfHwgKGNTb3VyY2VbaXRTb3VyY2VdPj0nYScgJiYgY1NvdXJjZVtpdFNvdXJjZV08PSd6JykgfHwgKGNTb3VyY2VbaXRTb3VyY2VdPj0nQScgJiYgY1NvdXJjZVtpdFNvdXJjZV08PSdaJykpCisJCQkJCXsKKwkJCQkJCS8vY1B1cnBvc2UucHVzaF9iYWNrKGNTb3VyY2VbaXRTb3VyY2VdKTsKKwkJCQkJCWNQdXJwb3NlICs9IGNTb3VyY2VbaXRTb3VyY2VdOworCQkJCQkJaXRTb3VyY2UrKzsKKwkJCQkJCWJyZWFrOworCQkJCQl9CisJCQkJCWl0U291cmNlKys7CisJCQkJfQorCQkJCWJyZWFrOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgJ0EnOgorCQkJeworCQkJCXdoaWxlKGl0U291cmNlIDwgaVNpemUpCisJCQkJeworCQkJCQlpZiAoKGNTb3VyY2VbaXRTb3VyY2VdPj0nYScgJiYgY1NvdXJjZVtpdFNvdXJjZV08PSd6JykgfHwgKGNTb3VyY2VbaXRTb3VyY2VdPj0nQScgJiYgY1NvdXJjZVtpdFNvdXJjZV08PSdaJykpCisJCQkJCXsKKwkJCQkJCS8vY1B1cnBvc2UucHVzaF9iYWNrKGNTb3VyY2VbaXRTb3VyY2VdKTsKKwkJCQkJCWNQdXJwb3NlICs9IGNTb3VyY2VbaXRTb3VyY2VdOworCQkJCQkJaXRTb3VyY2UrKzsKKwkJCQkJCWJyZWFrOworCQkJCQl9CisJCQkJCWl0U291cmNlKys7CisJCQkJfQorCQkJCWJyZWFrOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgJzknOgorCQkJeworCQkJCXdoaWxlKGl0U291cmNlIDwgaVNpemUpCisJCQkJeworCQkJCQlpZiAoY1NvdXJjZVtpdFNvdXJjZV0+PScwJyYmY1NvdXJjZVtpdFNvdXJjZV08PSc5JykKKwkJCQkJeworCQkJCQkJLy9jUHVycG9zZS5wdXNoX2JhY2soY1NvdXJjZVtpdFNvdXJjZV0pOworCQkJCQkJY1B1cnBvc2UgKz0gY1NvdXJjZVtpdFNvdXJjZV07CisJCQkJCQlpdFNvdXJjZSsrOworCQkJCQkJYnJlYWs7CisJCQkJCX0KKwkJCQkJaXRTb3VyY2UrKzsKKwkJCQl9CisJCQkJYnJlYWs7CisJCQl9CisJCWNhc2UgJyonOgorCQkJeworCQkJCWNQdXJwb3NlLmFwcGVuZChjU291cmNlLGl0U291cmNlLGlTaXplLWl0U291cmNlKTsKKwkJCQlpdFNvdXJjZSA9IGlTaXplLTE7CisJCQkJYnJlYWs7CisJCQl9CisJCWNhc2UgJ1xcJzoKKwkJCWJyZWFrOworCQljYXNlICc+JzoKKwkJCXsKKwkJCQlmb3Ioc3RkOjpzdHJpbmc6Oml0ZXJhdG9yIGl0ID0gY1NvdXJjZS5iZWdpbigpO2l0ICE9IGNTb3VyY2UuZW5kKCk7IGl0KyspCisJCQkJeworCQkJCQkqaXQgPSB0b3VwcGVyKCppdCk7CisJCQkJfQorCQkJCWJyZWFrOworCQkJfQorCQljYXNlICc8JzoKKwkJCXsKKwkJCQlmb3Ioc3RkOjpzdHJpbmc6Oml0ZXJhdG9yIGl0ID0gY1NvdXJjZS5iZWdpbigpO2l0ICE9IGNTb3VyY2UuZW5kKCk7IGl0KyspCisJCQkJeworCQkJCQkqaXQgPSB0b2xvd2VyKCppdCk7CisJCQkJfQorCQkJCWJyZWFrOworCQkJfQorCQljYXNlICc9JzoKKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJLy9jUHVycG9zZS5wdXNoX2JhY2sobGV0dGVyKTsKKwkJCWNQdXJwb3NlICs9IGxldHRlcjsKKwkJCWJyZWFrOworCQl9CisJfQorfQorCitGWF9CT09MIHV0aWw6OnNjYW5kKE9CSl9NRVRIT0RfUEFSQU1TKQoreworCXY4OjpJc29sYXRlKiBpc29sYXRlID0gR2V0SXNvbGF0ZShjYyk7CisJaW50IGlTaXplID0gcGFyYW1zLnNpemUoKTsKKwlpZiAoaVNpemUgPCAyKQorCQlyZXR1cm4gRkFMU0U7CisJQ0ZYX1dpZGVTdHJpbmcgc0Zvcm1hdCA9IHBhcmFtc1swXS5vcGVyYXRvciBDRlhfV2lkZVN0cmluZygpOworCUNGWF9XaWRlU3RyaW5nIHNEYXRlID0gcGFyYW1zWzFdLm9wZXJhdG9yIENGWF9XaWRlU3RyaW5nKCk7CisKKwlkb3VibGUgZERhdGUgPSBKU19HZXREYXRlVGltZSgpOworCWlmIChzRGF0ZS5HZXRMZW5ndGgoKSA+IDApCisJeworCQlGWF9CT09MIGJXcm9uZ0Zvcm1hdCA9IEZBTFNFOworCQlkRGF0ZSA9IENKU19QdWJsaWNNZXRob2RzOjpNYWtlUmVndWxhckRhdGUoc0RhdGUsc0Zvcm1hdCxiV3JvbmdGb3JtYXQpOworCX0JCisJCisJaWYgKCFKU19Qb3J0SXNOYW4oZERhdGUpKQorCXsKKwkJQ0pTX0RhdGUgZGF0ZShpc29sYXRlLGREYXRlKTsKKwkJdlJldCA9IGRhdGU7CisJfQorCWVsc2UKKwl7CisJCXZSZXQuU2V0TnVsbCgpOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9JTlQ2NCBGWF9hdG9pNjQoY29uc3QgY2hhciAqbnB0cikKK3sKKyAgICAgICAgaW50IGM7ICAgICAgICAgICAgICAvKiBjdXJyZW50IGNoYXIgKi8KKyAgICAgICAgRlhfSU5UNjQgdG90YWw7ICAgICAgLyogY3VycmVudCB0b3RhbCAqLworICAgICAgICBpbnQgc2lnbjsgICAgICAgICAgIC8qIGlmICctJywgdGhlbiBuZWdhdGl2ZSwgb3RoZXJ3aXNlIHBvc2l0aXZlICovCisKKyAgICAgICAgLyogc2tpcCB3aGl0ZXNwYWNlICovCisgICAgICAgIHdoaWxlICggaXNzcGFjZSgoaW50KSh1bnNpZ25lZCBjaGFyKSpucHRyKSApCisgICAgICAgICAgICArK25wdHI7CisKKyAgICAgICAgYyA9IChpbnQpKHVuc2lnbmVkIGNoYXIpKm5wdHIrKzsKKyAgICAgICAgc2lnbiA9IGM7ICAgICAgICAgICAvKiBzYXZlIHNpZ24gaW5kaWNhdGlvbiAqLworICAgICAgICBpZiAoYyA9PSAnLScgfHwgYyA9PSAnKycpCisgICAgICAgICAgICBjID0gKGludCkodW5zaWduZWQgY2hhcikqbnB0cisrOyAgICAvKiBza2lwIHNpZ24gKi8KKworICAgICAgICB0b3RhbCA9IDA7CisKKyAgICAgICAgd2hpbGUgKGlzZGlnaXQoYykpIHsKKyAgICAgICAgICAgIHRvdGFsID0gMTAgKiB0b3RhbCArIChjIC0gJzAnKTsgICAgIC8qIGFjY3VtdWxhdGUgZGlnaXQgKi8KKyAgICAgICAgICAgIGMgPSAoaW50KSh1bnNpZ25lZCBjaGFyKSpucHRyKys7ICAgIC8qIGdldCBuZXh0IGNoYXIgKi8KKyAgICAgICAgfQorCisgICAgICAgIGlmIChzaWduID09ICctJykKKyAgICAgICAgICAgIHJldHVybiAtdG90YWw7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiB0b3RhbDsgICAvKiByZXR1cm4gcmVzdWx0LCBuZWdhdGVkIGlmIG5lY2Vzc2FyeSAqLworfQorCitGWF9CT09MIHV0aWw6OmJ5dGVUb0NoYXIoT0JKX01FVEhPRF9QQVJBTVMpCit7CisJaW50IGlTaXplID0gcGFyYW1zLnNpemUoKTsKKwlpZiAoaVNpemUgPT0gMCkKKwkJcmV0dXJuIEZBTFNFOworCWludCBuQnl0ZSA9IChpbnQpcGFyYW1zWzBdOworCXVuc2lnbmVkIGNoYXIgY0J5dGUgPSAodW5zaWduZWQgY2hhciluQnl0ZTsKKwlDRlhfV2lkZVN0cmluZyBjc1ZhbHVlOworCWNzVmFsdWUuRm9ybWF0KChGWF9MUENXU1RSKUwiJWMiLCBjQnl0ZSk7CisJdlJldCA9IGNzVmFsdWU7IAorCXJldHVybiBUUlVFOworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9CdXR0b24uY3BwIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9CdXR0b24uY3BwCmluZGV4IGM3MWU1Y2M4Li5mOTU0NjlhIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5jcHAKKysrIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9CdXR0b24uY3BwCkBAIC0xLDUzICsxLDUzIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfQnV0dG9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0J1dHRvbjo6Q1BXTF9CdXR0b24oKSA6DQotCW1fYk1vdXNlRG93bihGQUxTRSkNCi17DQotfQ0KLQ0KLUNQV0xfQnV0dG9uOjp+Q1BXTF9CdXR0b24oKQ0KLXsNCi0vLwlQV0xfVFJBQ0UoIn5DUFdMX0J1dHRvblxuIik7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfQnV0dG9uOjpHZXRDbGFzc05hbWUoKSBjb25zdA0KLXsNCi0JcmV0dXJuICJDUFdMX0J1dHRvbiI7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9CdXR0b246Ok9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0KLXsNCi0JY3AuZUN1cnNvclR5cGUgPSBGWENUX0hBTkQ7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9CdXR0b246Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LCBuRmxhZyk7DQotDQotCW1fYk1vdXNlRG93biA9IFRSVUU7DQotCVNldENhcHR1cmUoKTsNCi0JDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfQnV0dG9uOjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JQ1BXTF9XbmQ6Ok9uTEJ1dHRvblVwKHBvaW50LCBuRmxhZyk7DQotDQotCVJlbGVhc2VDYXB0dXJlKCk7DQotCW1fYk1vdXNlRG93biA9IEZBTFNFOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQnV0dG9uLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1V0aWxzLmgiCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9CdXR0b24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0J1dHRvbjo6Q1BXTF9CdXR0b24oKSA6CisJbV9iTW91c2VEb3duKEZBTFNFKQoreworfQorCitDUFdMX0J1dHRvbjo6fkNQV0xfQnV0dG9uKCkKK3sKKy8vCVBXTF9UUkFDRSgifkNQV0xfQnV0dG9uXG4iKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9CdXR0b246OkdldENsYXNzTmFtZSgpIGNvbnN0Cit7CisJcmV0dXJuICJDUFdMX0J1dHRvbiI7Cit9CisKK3ZvaWQgQ1BXTF9CdXR0b246Ok9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKQoreworCWNwLmVDdXJzb3JUeXBlID0gRlhDVF9IQU5EOworfQorCitGWF9CT09MIENQV0xfQnV0dG9uOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsIG5GbGFnKTsKKworCW1fYk1vdXNlRG93biA9IFRSVUU7CisJU2V0Q2FwdHVyZSgpOworCQorCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENQV0xfQnV0dG9uOjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCUNQV0xfV25kOjpPbkxCdXR0b25VcChwb2ludCwgbkZsYWcpOworCisJUmVsZWFzZUNhcHR1cmUoKTsKKwltX2JNb3VzZURvd24gPSBGQUxTRTsKKworCXJldHVybiBUUlVFOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0NhcmV0LmNwcCBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfQ2FyZXQuY3BwCmluZGV4IGU1NDUzOGUuLmNkYzdkNTcgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfQ2FyZXQuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfQ2FyZXQuY3BwCkBAIC0xLDE5NyArMSwxOTcgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ2FyZXQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1V0aWxzLmgiDQotDQotI2RlZmluZSBQV0xfQ0FSRVRfRkxBU0hJTlRFUlZBTAkJNTAwDQotDQotLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLw0KLS8vIENvbnN0cnVjdGlvbi9EZXN0cnVjdGlvbg0KLS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8NCi0NCi1DUFdMX0NhcmV0OjpDUFdMX0NhcmV0KCkgOg0KLQltX2JGbGFzaChGQUxTRSksDQotCW1fcHRIZWFkKDAsMCksDQotCW1fcHRGb290KDAsMCksDQotCW1fZldpZHRoKDAuNGYpLA0KLQltX25EZWxheSgwKQ0KLXsNCi19DQotDQotQ1BXTF9DYXJldDo6fkNQV0xfQ2FyZXQoKQ0KLXsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9DYXJldDo6R2V0Q2xhc3NOYW1lKCkgY29uc3QNCi17DQotCXJldHVybiAiQ1BXTF9DYXJldCI7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9DYXJldDo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSkNCi17DQotCUdldENhcmV0QXBwKHNBcHBTdHJlYW0sQ1BERl9Qb2ludCgwLjBmLDAuMGYpKTsNCi19DQotDQotdm9pZCBDUFdMX0NhcmV0OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkNCi17DQotCWlmIChJc1Zpc2libGUoKSAmJiBtX2JGbGFzaCkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjUmVjdCA9IEdldENhcmV0UmVjdCgpOw0KLQkJQ1BERl9SZWN0IHJjQ2xpcCA9IEdldENsaXBSZWN0KCk7DQotDQotCQlDRlhfUGF0aERhdGEgcGF0aDsNCi0NCi0JCXBhdGguU2V0UG9pbnRDb3VudCgyKTsNCi0JCQ0KLQkJRlhfRkxPQVQgZkNhcmV0WCA9IHJjUmVjdC5sZWZ0ICsgbV9mV2lkdGggKiAwLjVmOw0KLQkJRlhfRkxPQVQgZkNhcmV0VG9wID0gcmNSZWN0LnRvcDsNCi0JCUZYX0ZMT0FUIGZDYXJldEJvdHRvbSA9IHJjUmVjdC5ib3R0b207DQotDQotCQlpZiAoIXJjQ2xpcC5Jc0VtcHR5KCkpDQotCQl7DQotCQkJcmNSZWN0LkludGVyc2VjdChyY0NsaXApOw0KLQkJCWlmICghcmNSZWN0LklzRW1wdHkoKSkNCi0JCQl7DQotCQkJCWZDYXJldFRvcCA9IHJjUmVjdC50b3A7DQotCQkJCWZDYXJldEJvdHRvbSA9IHJjUmVjdC5ib3R0b207DQotCQkJCXBhdGguU2V0UG9pbnQoMCwgZkNhcmV0WCwgZkNhcmV0Qm90dG9tLCBGWFBUX01PVkVUTyk7DQotCQkJCXBhdGguU2V0UG9pbnQoMSwgZkNhcmV0WCwgZkNhcmV0VG9wLCBGWFBUX0xJTkVUTyk7DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCXJldHVybjsNCi0JCQl9DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJcGF0aC5TZXRQb2ludCgwLCBmQ2FyZXRYLCBmQ2FyZXRCb3R0b20sIEZYUFRfTU9WRVRPKTsNCi0JCQlwYXRoLlNldFBvaW50KDEsIGZDYXJldFgsIGZDYXJldFRvcCwgRlhQVF9MSU5FVE8pOw0KLQkJfQ0KLQ0KLQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JCWdzZC5tX0xpbmVXaWR0aCA9IG1fZldpZHRoOw0KLQ0KLQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgJmdzZCwwLCAgQXJnYkVuY29kZSgyNTUsMCwwLDApLCBGWEZJTExfQUxURVJOQVRFKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfQ2FyZXQ6OkdldENhcmV0QXBwKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0sY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KQ0KLXsNCi0JaWYgKElzVmlzaWJsZSgpICYmIG1fYkZsYXNoKQ0KLQl7CQ0KLQkJQ0ZYX0J5dGVUZXh0QnVmIHNDYXJldDsNCi0NCi0JCUNQREZfUmVjdCByY1JlY3QgPSBHZXRDYXJldFJlY3QoKTsNCi0JCUNQREZfUmVjdCByY0NsaXAgPSBHZXRDbGlwUmVjdCgpOw0KLQ0KLQkJcmNSZWN0ID0gQ1BXTF9VdGlsczo6T2Zmc2V0UmVjdChyY1JlY3QscHRPZmZzZXQueCxwdE9mZnNldC55KTsNCi0JCXJjQ2xpcCA9IENQV0xfVXRpbHM6Ok9mZnNldFJlY3QocmNDbGlwLHB0T2Zmc2V0LngscHRPZmZzZXQueSk7DQotDQotCQlzQ2FyZXQgPDwgInFcbiI7DQotCQlpZiAoIXJjQ2xpcC5Jc0VtcHR5KCkpDQotCQl7DQotCQkJc0NhcmV0IDw8IHJjQ2xpcC5sZWZ0IDw8ICIgIiA8PCByY0NsaXAuYm90dG9tICsgMi41ZiA8PCAiICIgDQotCQkJCTw8IHJjQ2xpcC5yaWdodCAtIHJjQ2xpcC5sZWZ0IDw8ICIgIiA8PCByY0NsaXAudG9wIC0gcmNDbGlwLmJvdHRvbSAtIDQuNWYgPDwgIiByZSBXIG5cbiI7DQotCQl9DQotCQlzQ2FyZXQgPDwgbV9mV2lkdGggPDwgIiB3XG4wIEdcbiI7DQotCQlzQ2FyZXQgPDwgcmNSZWN0LmxlZnQgKyBtX2ZXaWR0aC8yIDw8ICIgIiA8PCByY1JlY3QuYm90dG9tIDw8ICIgbVxuIjsNCi0JCXNDYXJldCA8PCByY1JlY3QubGVmdCArIG1fZldpZHRoLzIgPDwgIiAiIDw8IHJjUmVjdC50b3AgPDwgIiBsIFNcblFcbiI7CQ0KLQ0KLQkJc0FwcFN0cmVhbSA8PCBzQ2FyZXQ7CQ0KLQl9DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfQ2FyZXQ6OkdldENhcmV0QXBwZWFyYW5jZVN0cmVhbShjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQpDQotew0KLQlDRlhfQnl0ZVRleHRCdWYgc0NhcmV0Ow0KLQlHZXRDYXJldEFwcChzQ2FyZXQscHRPZmZzZXQpOw0KLQlyZXR1cm4gc0NhcmV0LkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotdm9pZCBDUFdMX0NhcmV0OjpUaW1lclByb2MoKQ0KLXsNCi0JaWYgKG1fbkRlbGF5ID4gMCkNCi0Jew0KLQkJbV9uRGVsYXktLTsJDQotCX0NCi0JZWxzZQ0KLQl7DQotCQltX2JGbGFzaCA9ICFtX2JGbGFzaDsNCi0JCUludmFsaWRhdGVSZWN0KCk7DQotCX0NCi19DQotDQotQ1BERl9SZWN0IENQV0xfQ2FyZXQ6OkdldENhcmV0UmVjdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gQ1BERl9SZWN0KG1fcHRGb290LngsDQotCQkJbV9wdEZvb3QueSwNCi0JCQltX3B0SGVhZC54ICsgdGhpcy0+bV9mV2lkdGgsDQotCQkJbV9wdEhlYWQueSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9DYXJldDo6U2V0Q2FyZXQoRlhfQk9PTCBiVmlzaWJsZSwgY29uc3QgQ1BERl9Qb2ludCAmIHB0SGVhZCwgY29uc3QgQ1BERl9Qb2ludCAmIHB0Rm9vdCkNCi17DQotCWlmIChiVmlzaWJsZSkNCi0JewkNCi0JCWlmIChJc1Zpc2libGUoKSkNCi0JCXsNCi0JCQlpZiAobV9wdEhlYWQueCAhPSBwdEhlYWQueCB8fCBtX3B0SGVhZC55ICE9IHB0SGVhZC55IHx8IA0KLQkJCQkJbV9wdEZvb3QueCAhPSBwdEZvb3QueCB8fCBtX3B0Rm9vdC55ICE9IHB0Rm9vdC55KQ0KLQkJCXsNCi0JCQkJdGhpcy0+bV9wdEhlYWQgPSBwdEhlYWQ7DQotCQkJCXRoaXMtPm1fcHRGb290ID0gcHRGb290Ow0KLQ0KLQkJCQltX2JGbGFzaCA9IFRSVUU7DQotCQkJCS8vTW92ZShHZXRDYXJldFJlY3QoKSxGQUxTRSxUUlVFKTsNCi0JCQkJTW92ZShtX3JjSW52YWxpZCwgRkFMU0UsIFRSVUUpOw0KLQkJCX0NCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQl0aGlzLT5tX3B0SGVhZCA9IHB0SGVhZDsNCi0JCQl0aGlzLT5tX3B0Rm9vdCA9IHB0Rm9vdDsNCi0NCi0JCQlFbmRUaW1lcigpOw0KLQkJCUJlZ2luVGltZXIoUFdMX0NBUkVUX0ZMQVNISU5URVJWQUwpOw0KLQkJCQ0KLQkJCUNQV0xfV25kOjpTZXRWaXNpYmxlKFRSVUUpOw0KLQkJCW1fYkZsYXNoID0gVFJVRTsNCi0NCi0JCQkvL01vdmUoR2V0Q2FyZXRSZWN0KCksRkFMU0UsVFJVRSk7CQ0KLQkJCU1vdmUobV9yY0ludmFsaWQsIEZBTFNFLCBUUlVFKTsNCi0JCX0JCQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJdGhpcy0+bV9wdEhlYWQgPSBDUERGX1BvaW50KDAsMCk7DQotCQl0aGlzLT5tX3B0Rm9vdCA9IENQREZfUG9pbnQoMCwwKTsNCi0NCi0JCW1fYkZsYXNoID0gRkFMU0U7DQotCQlpZiAoSXNWaXNpYmxlKCkpDQotCQl7DQotCQkJRW5kVGltZXIoKTsNCi0JCQlDUFdMX1duZDo6U2V0VmlzaWJsZShGQUxTRSk7DQotCQl9CQkNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfQ2FyZXQ6OkludmFsaWRhdGVSZWN0KENQREZfUmVjdCAqIHBSZWN0KQ0KLXsNCi0JaWYgKHBSZWN0KQ0KLQl7DQotCQlDUERGX1JlY3QgcmNSZWZyZXNoID0gQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QoKnBSZWN0LDAuNWYpOw0KLQkJcmNSZWZyZXNoLnRvcCArPSAxOw0KLQkJcmNSZWZyZXNoLmJvdHRvbSAtPSAxOwkNCi0JCQ0KLQkJQ1BXTF9XbmQ6OkludmFsaWRhdGVSZWN0KCZyY1JlZnJlc2gpOw0KLQl9DQotCWVsc2UNCi0JCUNQV0xfV25kOjpJbnZhbGlkYXRlUmVjdChwUmVjdCk7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0NhcmV0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1V0aWxzLmgiCisKKyNkZWZpbmUgUFdMX0NBUkVUX0ZMQVNISU5URVJWQUwJCTUwMAorCisvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisvLyBDb25zdHJ1Y3Rpb24vRGVzdHJ1Y3Rpb24KKy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworQ1BXTF9DYXJldDo6Q1BXTF9DYXJldCgpIDoKKwltX2JGbGFzaChGQUxTRSksCisJbV9wdEhlYWQoMCwwKSwKKwltX3B0Rm9vdCgwLDApLAorCW1fZldpZHRoKDAuNGYpLAorCW1fbkRlbGF5KDApCit7Cit9CisKK0NQV0xfQ2FyZXQ6On5DUFdMX0NhcmV0KCkKK3sKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9DYXJldDo6R2V0Q2xhc3NOYW1lKCkgY29uc3QKK3sKKwlyZXR1cm4gIkNQV0xfQ2FyZXQiOworfQorCit2b2lkIENQV0xfQ2FyZXQ6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pCit7CisJR2V0Q2FyZXRBcHAoc0FwcFN0cmVhbSxDUERGX1BvaW50KDAuMGYsMC4wZikpOworfQorCit2b2lkIENQV0xfQ2FyZXQ6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQoreworCWlmIChJc1Zpc2libGUoKSAmJiBtX2JGbGFzaCkKKwl7CisJCUNQREZfUmVjdCByY1JlY3QgPSBHZXRDYXJldFJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjQ2xpcCA9IEdldENsaXBSZWN0KCk7CisKKwkJQ0ZYX1BhdGhEYXRhIHBhdGg7CisKKwkJcGF0aC5TZXRQb2ludENvdW50KDIpOworCQkKKwkJRlhfRkxPQVQgZkNhcmV0WCA9IHJjUmVjdC5sZWZ0ICsgbV9mV2lkdGggKiAwLjVmOworCQlGWF9GTE9BVCBmQ2FyZXRUb3AgPSByY1JlY3QudG9wOworCQlGWF9GTE9BVCBmQ2FyZXRCb3R0b20gPSByY1JlY3QuYm90dG9tOworCisJCWlmICghcmNDbGlwLklzRW1wdHkoKSkKKwkJeworCQkJcmNSZWN0LkludGVyc2VjdChyY0NsaXApOworCQkJaWYgKCFyY1JlY3QuSXNFbXB0eSgpKQorCQkJeworCQkJCWZDYXJldFRvcCA9IHJjUmVjdC50b3A7CisJCQkJZkNhcmV0Qm90dG9tID0gcmNSZWN0LmJvdHRvbTsKKwkJCQlwYXRoLlNldFBvaW50KDAsIGZDYXJldFgsIGZDYXJldEJvdHRvbSwgRlhQVF9NT1ZFVE8pOworCQkJCXBhdGguU2V0UG9pbnQoMSwgZkNhcmV0WCwgZkNhcmV0VG9wLCBGWFBUX0xJTkVUTyk7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJcmV0dXJuOworCQkJfQorCQl9CisJCWVsc2UKKwkJeworCQkJcGF0aC5TZXRQb2ludCgwLCBmQ2FyZXRYLCBmQ2FyZXRCb3R0b20sIEZYUFRfTU9WRVRPKTsKKwkJCXBhdGguU2V0UG9pbnQoMSwgZkNhcmV0WCwgZkNhcmV0VG9wLCBGWFBUX0xJTkVUTyk7CisJCX0KKworCQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOworCQlnc2QubV9MaW5lV2lkdGggPSBtX2ZXaWR0aDsKKworCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLDAsICBBcmdiRW5jb2RlKDI1NSwwLDAsMCksIEZYRklMTF9BTFRFUk5BVEUpOworCX0KK30KKwordm9pZCBDUFdMX0NhcmV0OjpHZXRDYXJldEFwcChDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtLGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCkKK3sKKwlpZiAoSXNWaXNpYmxlKCkgJiYgbV9iRmxhc2gpCisJewkKKwkJQ0ZYX0J5dGVUZXh0QnVmIHNDYXJldDsKKworCQlDUERGX1JlY3QgcmNSZWN0ID0gR2V0Q2FyZXRSZWN0KCk7CisJCUNQREZfUmVjdCByY0NsaXAgPSBHZXRDbGlwUmVjdCgpOworCisJCXJjUmVjdCA9IENQV0xfVXRpbHM6Ok9mZnNldFJlY3QocmNSZWN0LHB0T2Zmc2V0LngscHRPZmZzZXQueSk7CisJCXJjQ2xpcCA9IENQV0xfVXRpbHM6Ok9mZnNldFJlY3QocmNDbGlwLHB0T2Zmc2V0LngscHRPZmZzZXQueSk7CisKKwkJc0NhcmV0IDw8ICJxXG4iOworCQlpZiAoIXJjQ2xpcC5Jc0VtcHR5KCkpCisJCXsKKwkJCXNDYXJldCA8PCByY0NsaXAubGVmdCA8PCAiICIgPDwgcmNDbGlwLmJvdHRvbSArIDIuNWYgPDwgIiAiIAorCQkJCTw8IHJjQ2xpcC5yaWdodCAtIHJjQ2xpcC5sZWZ0IDw8ICIgIiA8PCByY0NsaXAudG9wIC0gcmNDbGlwLmJvdHRvbSAtIDQuNWYgPDwgIiByZSBXIG5cbiI7CisJCX0KKwkJc0NhcmV0IDw8IG1fZldpZHRoIDw8ICIgd1xuMCBHXG4iOworCQlzQ2FyZXQgPDwgcmNSZWN0LmxlZnQgKyBtX2ZXaWR0aC8yIDw8ICIgIiA8PCByY1JlY3QuYm90dG9tIDw8ICIgbVxuIjsKKwkJc0NhcmV0IDw8IHJjUmVjdC5sZWZ0ICsgbV9mV2lkdGgvMiA8PCAiICIgPDwgcmNSZWN0LnRvcCA8PCAiIGwgU1xuUVxuIjsJCisKKwkJc0FwcFN0cmVhbSA8PCBzQ2FyZXQ7CQorCX0KK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9DYXJldDo6R2V0Q2FyZXRBcHBlYXJhbmNlU3RyZWFtKGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc0NhcmV0OworCUdldENhcmV0QXBwKHNDYXJldCxwdE9mZnNldCk7CisJcmV0dXJuIHNDYXJldC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK3ZvaWQgQ1BXTF9DYXJldDo6VGltZXJQcm9jKCkKK3sKKwlpZiAobV9uRGVsYXkgPiAwKQorCXsKKwkJbV9uRGVsYXktLTsJCisJfQorCWVsc2UKKwl7CisJCW1fYkZsYXNoID0gIW1fYkZsYXNoOworCQlJbnZhbGlkYXRlUmVjdCgpOworCX0KK30KKworQ1BERl9SZWN0IENQV0xfQ2FyZXQ6OkdldENhcmV0UmVjdCgpIGNvbnN0Cit7CisJcmV0dXJuIENQREZfUmVjdChtX3B0Rm9vdC54LAorCQkJbV9wdEZvb3QueSwKKwkJCW1fcHRIZWFkLnggKyB0aGlzLT5tX2ZXaWR0aCwKKwkJCW1fcHRIZWFkLnkpOworfQorCit2b2lkIENQV0xfQ2FyZXQ6OlNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsIGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsIGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QpCit7CisJaWYgKGJWaXNpYmxlKQorCXsJCisJCWlmIChJc1Zpc2libGUoKSkKKwkJeworCQkJaWYgKG1fcHRIZWFkLnggIT0gcHRIZWFkLnggfHwgbV9wdEhlYWQueSAhPSBwdEhlYWQueSB8fCAKKwkJCQkJbV9wdEZvb3QueCAhPSBwdEZvb3QueCB8fCBtX3B0Rm9vdC55ICE9IHB0Rm9vdC55KQorCQkJeworCQkJCXRoaXMtPm1fcHRIZWFkID0gcHRIZWFkOworCQkJCXRoaXMtPm1fcHRGb290ID0gcHRGb290OworCisJCQkJbV9iRmxhc2ggPSBUUlVFOworCQkJCS8vTW92ZShHZXRDYXJldFJlY3QoKSxGQUxTRSxUUlVFKTsKKwkJCQlNb3ZlKG1fcmNJbnZhbGlkLCBGQUxTRSwgVFJVRSk7CisJCQl9CisJCX0KKwkJZWxzZQorCQl7CisJCQl0aGlzLT5tX3B0SGVhZCA9IHB0SGVhZDsKKwkJCXRoaXMtPm1fcHRGb290ID0gcHRGb290OworCisJCQlFbmRUaW1lcigpOworCQkJQmVnaW5UaW1lcihQV0xfQ0FSRVRfRkxBU0hJTlRFUlZBTCk7CisJCQkKKwkJCUNQV0xfV25kOjpTZXRWaXNpYmxlKFRSVUUpOworCQkJbV9iRmxhc2ggPSBUUlVFOworCisJCQkvL01vdmUoR2V0Q2FyZXRSZWN0KCksRkFMU0UsVFJVRSk7CQorCQkJTW92ZShtX3JjSW52YWxpZCwgRkFMU0UsIFRSVUUpOworCQl9CQkKKwl9CisJZWxzZQorCXsKKwkJdGhpcy0+bV9wdEhlYWQgPSBDUERGX1BvaW50KDAsMCk7CisJCXRoaXMtPm1fcHRGb290ID0gQ1BERl9Qb2ludCgwLDApOworCisJCW1fYkZsYXNoID0gRkFMU0U7CisJCWlmIChJc1Zpc2libGUoKSkKKwkJeworCQkJRW5kVGltZXIoKTsKKwkJCUNQV0xfV25kOjpTZXRWaXNpYmxlKEZBTFNFKTsKKwkJfQkJCisJfQorfQorCit2b2lkIENQV0xfQ2FyZXQ6OkludmFsaWRhdGVSZWN0KENQREZfUmVjdCAqIHBSZWN0KQoreworCWlmIChwUmVjdCkKKwl7CisJCUNQREZfUmVjdCByY1JlZnJlc2ggPSBDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdCgqcFJlY3QsMC41Zik7CisJCXJjUmVmcmVzaC50b3AgKz0gMTsKKwkJcmNSZWZyZXNoLmJvdHRvbSAtPSAxOwkKKwkJCisJCUNQV0xfV25kOjpJbnZhbGlkYXRlUmVjdCgmcmNSZWZyZXNoKTsKKwl9CisJZWxzZQorCQlDUFdMX1duZDo6SW52YWxpZGF0ZVJlY3QocFJlY3QpOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0NvbWJvQm94LmNwcCBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfQ29tYm9Cb3guY3BwCmluZGV4IDc2NTBhMjMuLjAyMDc2NWEgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfQ29tYm9Cb3guY3BwCisrKyBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfQ29tYm9Cb3guY3BwCkBAIC0xLDY2MiArMSw2NjIgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RCb3guaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0NvbWJvQm94LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIg0KLQ0KLSNkZWZpbmUgUFdMQ0JfREVGQVVMVEZPTlRTSVpFICAxMi4wZg0KLQ0KLSNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpDQotI2RlZmluZSBJc0Zsb2F0QmlnZ2VyKGZhLGZiKQkJCQkoKGZhKSA+IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCi0jZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLGZiKQkJCQkoKGZhKSA8IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCi0jZGVmaW5lIElzRmxvYXRFcXVhbChmYSxmYikJCQkJCUlzRmxvYXRaZXJvKChmYSktKGZiKSkNCi0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfQ0JMaXN0Qm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1GWF9CT09MCUNQV0xfQ0JMaXN0Qm94OjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JQ1BXTF9XbmQ6Ok9uTEJ1dHRvblVwKHBvaW50LG5GbGFnKTsNCi0NCi0JaWYgKG1fYk1vdXNlRG93bikNCi0Jew0KLQkJUmVsZWFzZUNhcHR1cmUoKTsNCi0JCW1fYk1vdXNlRG93biA9IEZBTFNFOwkNCi0NCi0JCWlmICh0aGlzLT5DbGllbnRIaXRUZXN0KHBvaW50KSkNCi0JCXsNCi0JCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpDQotCQkJew0KLQkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLFBOTV9MQlVUVE9OVVAsMCxQV0xfTUFLRURXT1JEKHBvaW50LngscG9pbnQueSkpOwkJCQ0KLQkJCX0NCi0JCQ0KLQkJCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsNCi0JCQlPbk5vdGlmeVNlbENoYW5nZWQoRkFMU0UsYkV4aXQsIG5GbGFnKTsNCi0JCQlpZiAoYkV4aXQpIHJldHVybiBGQUxTRTsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBDUFdMX0NCTGlzdEJveDo6T25LZXlEb3duKEZYX1dPUkQgbkNoYXIsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAoIW1fcExpc3QpIHJldHVybiBGQUxTRTsNCi0NCi0Jc3dpdGNoIChuQ2hhcikNCi0Jew0KLQlkZWZhdWx0Og0KLQkJcmV0dXJuIEZBTFNFOw0KLQljYXNlIEZXTF9WS0VZX1VwOg0KLQljYXNlIEZXTF9WS0VZX0Rvd246DQotCWNhc2UgRldMX1ZLRVlfSG9tZToNCi0JY2FzZSBGV0xfVktFWV9MZWZ0Og0KLQljYXNlIEZXTF9WS0VZX0VuZDoNCi0JY2FzZSBGV0xfVktFWV9SaWdodDoNCi0JCWJyZWFrOwkNCi0JfQ0KLQ0KLQlzd2l0Y2ggKG5DaGFyKQ0KLQl7DQotCWNhc2UgRldMX1ZLRVlfVXA6DQotCQltX3BMaXN0LT5PblZLX1VQKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9Eb3duOg0KLQkJbV9wTGlzdC0+T25WS19ET1dOKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9Ib21lOg0KLQkJbV9wTGlzdC0+T25WS19IT01FKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9MZWZ0Og0KLQkJbV9wTGlzdC0+T25WS19MRUZUKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9FbmQ6DQotCQltX3BMaXN0LT5PblZLX0VORChJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOw0KLQkJYnJlYWs7DQotCWNhc2UgRldMX1ZLRVlfUmlnaHQ6DQotCQltX3BMaXN0LT5PblZLX1JJR0hUKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9EZWxldGU6DQotCQlicmVhazsNCi0JfQ0KLQ0KLQlPbk5vdGlmeVNlbENoYW5nZWQoVFJVRSxiRXhpdCwgbkZsYWcpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTAlDUFdMX0NCTGlzdEJveDo6T25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAoIW1fcExpc3QpIHJldHVybiBGQUxTRTsNCi0NCi0JaWYgKCFtX3BMaXN0LT5PbkNoYXIobkNoYXIsSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlpZiAoQ1BXTF9Db21ib0JveCogcENvbWJvQm94ID0gKENQV0xfQ29tYm9Cb3gqKUdldFBhcmVudFdpbmRvdygpKQ0KLQl7DQotCQlwQ29tYm9Cb3gtPlNldFNlbGVjdFRleHQoKTsNCi0JfQ0KLQ0KLQlPbk5vdGlmeVNlbENoYW5nZWQoVFJVRSxiRXhpdCxuRmxhZyk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfQ0JCdXR0b24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLXZvaWQgQ1BXTF9DQkJ1dHRvbjo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSkNCi17DQotCUNQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsNCi0JDQotCUNQREZfUmVjdCByZWN0V25kID0gQ1BXTF9XbmQ6OkdldFdpbmRvd1JlY3QoKTsNCi0JDQotCWlmIChJc1Zpc2libGUoKSAmJiAhcmVjdFduZC5Jc0VtcHR5KCkpDQotCXsNCi0JCUNGWF9CeXRlVGV4dEJ1ZiBzQnV0dG9uOwkNCi0NCi0JCUNQREZfUG9pbnQgcHRDZW50ZXIgPSB0aGlzLT5HZXRDZW50ZXJQb2ludCgpOw0KLQ0KLQkJQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCAtIFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOLHB0Q2VudGVyLnkgKyBQV0xfQ0JCVVRUT05fVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOw0KLQkJQ1BERl9Qb2ludCBwdDIocHRDZW50ZXIueCArIFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOLHB0Q2VudGVyLnkgKyBQV0xfQ0JCVVRUT05fVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOw0KLQkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCxwdENlbnRlci55IC0gUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmKTsNCi0NCi0JCWlmIChJc0Zsb2F0QmlnZ2VyKHJlY3RXbmQucmlnaHQgLSByZWN0V25kLmxlZnQsUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4gKiAyKQ0KLQkJCSYmDQotCQkJSXNGbG9hdEJpZ2dlcihyZWN0V25kLnRvcCAtIHJlY3RXbmQuYm90dG9tLFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOKQ0KLQkJCSkNCi0JCXsNCi0JCQlzQnV0dG9uIDw8ICIwIGdcbiI7DQotCQkJc0J1dHRvbiA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBtXG4iOw0KLQkJCXNCdXR0b24gPDwgcHQyLnggPDwgIiAiIDw8IHB0Mi55IDw8ICIgbFxuIjsNCi0JCQlzQnV0dG9uIDw8IHB0My54IDw8ICIgIiA8PCBwdDMueSA8PCAiIGxcbiI7DQotCQkJc0J1dHRvbiA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBsIGZcbiI7DQotDQotCQkJc0FwcFN0cmVhbSA8PCAicVxuIiA8PCBzQnV0dG9uIDw8ICJRXG4iOw0KLQkJfQkNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfQ0JCdXR0b246OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0KLXsNCi0JQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLHBVc2VyMkRldmljZSk7DQotDQotCUNQREZfUmVjdCByZWN0V25kID0gQ1BXTF9XbmQ6OkdldFdpbmRvd1JlY3QoKTsNCi0JDQotCWlmIChJc1Zpc2libGUoKSAmJiAhcmVjdFduZC5Jc0VtcHR5KCkpDQotCXsNCi0JCUNQREZfUG9pbnQgcHRDZW50ZXIgPSB0aGlzLT5HZXRDZW50ZXJQb2ludCgpOw0KLQ0KLQkJQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCAtIFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOLHB0Q2VudGVyLnkgKyBQV0xfQ0JCVVRUT05fVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOw0KLQkJQ1BERl9Qb2ludCBwdDIocHRDZW50ZXIueCArIFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOLHB0Q2VudGVyLnkgKyBQV0xfQ0JCVVRUT05fVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOw0KLQkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCxwdENlbnRlci55IC0gUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmKTsNCi0NCi0JCWlmIChJc0Zsb2F0QmlnZ2VyKHJlY3RXbmQucmlnaHQgLSByZWN0V25kLmxlZnQsUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4gKiAyKQ0KLQkJCSYmDQotCQkJSXNGbG9hdEJpZ2dlcihyZWN0V25kLnRvcCAtIHJlY3RXbmQuYm90dG9tLFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOKQ0KLQkJCSkNCi0JCXsNCi0JCQlDRlhfUGF0aERhdGEgcGF0aDsNCi0NCi0JCQlwYXRoLlNldFBvaW50Q291bnQoNCk7DQotCQkJcGF0aC5TZXRQb2ludCgwLCBwdDEueCwgcHQxLnksIEZYUFRfTU9WRVRPKTsNCi0JCQlwYXRoLlNldFBvaW50KDEsIHB0Mi54LCBwdDIueSwgRlhQVF9MSU5FVE8pOw0KLQkJCXBhdGguU2V0UG9pbnQoMiwgcHQzLngsIHB0My55LCBGWFBUX0xJTkVUTyk7DQotCQkJcGF0aC5TZXRQb2ludCgzLCBwdDEueCwgcHQxLnksIEZYUFRfTElORVRPKTsNCi0NCi0JCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCANCi0JCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUixHZXRUcmFuc3BhcmVuY3koKSksIA0KLQkJCQkwLCBGWEZJTExfQUxURVJOQVRFKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi1GWF9CT09MCUNQV0xfQ0JCdXR0b246Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKTsNCi0NCi0JU2V0Q2FwdHVyZSgpOw0KLQ0KLQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpDQotCXsJCQ0KLQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcyxQTk1fTEJVVFRPTkRPV04sMCxQV0xfTUFLRURXT1JEKHBvaW50LngscG9pbnQueSkpOw0KLQl9DQotCQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTAlDUFdMX0NCQnV0dG9uOjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JQ1BXTF9XbmQ6Ok9uTEJ1dHRvblVwKHBvaW50LCBuRmxhZyk7DQotDQotCVJlbGVhc2VDYXB0dXJlKCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfQ29tYm9Cb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNQV0xfQ29tYm9Cb3g6OkNQV0xfQ29tYm9Cb3goKSA6IG1fcEVkaXQoTlVMTCksDQotCW1fcEJ1dHRvbihOVUxMKSwNCi0JbV9wTGlzdChOVUxMKSwNCi0JbV9iUG9wdXAoRkFMU0UpLA0KLQltX25Qb3B1cFdoZXJlKDApLA0KLQltX25TZWxlY3RJdGVtKC0xKSwNCi0JbV9wRmlsbGVyTm90aWZ5KE5VTEwpDQotew0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX0NvbWJvQm94OjpHZXRDbGFzc05hbWUoKSBjb25zdA0KLXsNCi0JcmV0dXJuICJDUFdMX0NvbWJvQm94IjsNCi19DQotDQotdm9pZCBDUFdMX0NvbWJvQm94OjpPbkNyZWF0ZShQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCi17DQotCWNwLmR3RmxhZ3MgJj0gflBXU19IU0NST0xMOw0KLQljcC5kd0ZsYWdzICY9IH5QV1NfVlNDUk9MTDsNCi19DQotDQotdm9pZCBDUFdMX0NvbWJvQm94OjpTZXRGb2N1cygpDQotew0KLQlpZiAobV9wRWRpdCkNCi0JCW1fcEVkaXQtPlNldEZvY3VzKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Db21ib0JveDo6S2lsbEZvY3VzKCkNCi17DQotCVNldFBvcHVwKEZBTFNFKTsNCi0JQ1BXTF9XbmQ6OktpbGxGb2N1cygpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUFdMX0NvbWJvQm94OjpHZXRUZXh0KCkgY29uc3QNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQlyZXR1cm4gbV9wRWRpdC0+R2V0VGV4dCgpOw0KLQl9DQotCXJldHVybiBDRlhfV2lkZVN0cmluZygpOw0KLX0NCi0NCi12b2lkIENQV0xfQ29tYm9Cb3g6OlNldFRleHQoRlhfTFBDV1NUUiB0ZXh0KQ0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCQltX3BFZGl0LT5TZXRUZXh0KHRleHQpOw0KLX0NCi0NCi12b2lkIENQV0xfQ29tYm9Cb3g6OkFkZFN0cmluZyhGWF9MUENXU1RSIHN0cmluZykNCi17DQotCWlmIChtX3BMaXN0KQ0KLQkJbV9wTGlzdC0+QWRkU3RyaW5nKHN0cmluZyk7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfQ29tYm9Cb3g6OkdldFNlbGVjdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9uU2VsZWN0SXRlbTsNCi19DQotDQotdm9pZCBDUFdMX0NvbWJvQm94OjpTZXRTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCkNCi17DQotCWlmIChtX3BMaXN0KQ0KLQkJbV9wTGlzdC0+U2VsZWN0KG5JdGVtSW5kZXgpOw0KLQ0KLQltX3BFZGl0LT5TZXRUZXh0KG1fcExpc3QtPkdldFRleHQoKSk7DQotDQotCW1fblNlbGVjdEl0ZW0gPSBuSXRlbUluZGV4Ow0KLX0NCi0NCi12b2lkIENQV0xfQ29tYm9Cb3g6OlNldEVkaXRTZWwoRlhfSU5UMzIgblN0YXJ0Q2hhcixGWF9JTlQzMiBuRW5kQ2hhcikNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5TZXRTZWwoblN0YXJ0Q2hhcixuRW5kQ2hhcik7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0NvbWJvQm94OjpHZXRFZGl0U2VsKEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhcikgY29uc3QNCi17DQotCW5TdGFydENoYXIgPSAtMTsNCi0JbkVuZENoYXIgPSAtMTsNCi0NCi0JaWYgKG1fcEVkaXQpDQotCXsNCi0JCW1fcEVkaXQtPkdldFNlbChuU3RhcnRDaGFyLG5FbmRDaGFyKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfQ29tYm9Cb3g6OkNsZWFyKCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5DbGVhcigpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Db21ib0JveDo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLQlDcmVhdGVFZGl0KGNwKTsNCi0JQ3JlYXRlQnV0dG9uKGNwKTsNCi0JQ3JlYXRlTGlzdEJveChjcCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Db21ib0JveDo6Q3JlYXRlRWRpdChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCi17DQotCWlmICghbV9wRWRpdCkNCi0Jew0KLQkJbV9wRWRpdCA9IG5ldyBDUFdMX0NCRWRpdDsNCi0JCW1fcEVkaXQtPkF0dGFjaEZGTERhdGEobV9wRm9ybUZpbGxlcik7DQotDQotCQlQV0xfQ1JFQVRFUEFSQU0gZWNwID0gY3A7DQotCQllY3AucFBhcmVudFduZCA9IHRoaXM7DQotCQllY3AuZHdGbGFncyA9ICBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVIgfCBQRVNfQ0VOVEVSIHwgUEVTX0FVVE9TQ1JPTEwgfCBQRVNfVU5ETzsNCi0NCi0JCWlmIChIYXNGbGFnKFBXU19BVVRPRk9OVFNJWkUpKQ0KLQkJCWVjcC5kd0ZsYWdzIHw9IFBXU19BVVRPRk9OVFNJWkU7DQotDQotCQlpZiAoIUhhc0ZsYWcoUENCU19BTExPV0NVU1RPTVRFWFQpKQ0KLQkJCWVjcC5kd0ZsYWdzIHw9IFBXU19SRUFET05MWTsNCi0NCi0JCWVjcC5yY1JlY3RXbmQgPSBDUERGX1JlY3QoMCwwLDAsMCk7DQotCQllY3AuZHdCb3JkZXJXaWR0aCA9IDA7DQotCQllY3AubkJvcmRlclN0eWxlID0gUEJTX1NPTElEOw0KLQ0KLQkJbV9wRWRpdC0+Q3JlYXRlKGVjcCk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0NvbWJvQm94OjpDcmVhdGVCdXR0b24oY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLQlpZiAoIW1fcEJ1dHRvbikNCi0Jew0KLQkJbV9wQnV0dG9uID0gbmV3IENQV0xfQ0JCdXR0b247CQ0KLQ0KLQkJUFdMX0NSRUFURVBBUkFNIGJjcCA9IGNwOw0KLQkJYmNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQkJYmNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVIgfCBQV1NfQkFDS0dST1VORDsJDQotCQliY3Auc0JhY2tncm91bmRDb2xvciA9IFBXTF9TQ1JPTExCQVJfQktDT0xPUjsNCi0JCWJjcC5zQm9yZGVyQ29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOw0KLQkJYmNwLmR3Qm9yZGVyV2lkdGggPSAyOw0KLQkJYmNwLm5Cb3JkZXJTdHlsZSA9IFBCU19CRVZFTEVEOw0KLQkJYmNwLmVDdXJzb3JUeXBlID0gRlhDVF9BUlJPVzsNCi0NCi0JCW1fcEJ1dHRvbi0+Q3JlYXRlKGJjcCk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0NvbWJvQm94OjpDcmVhdGVMaXN0Qm94KGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0KLXsNCi0JaWYgKCFtX3BMaXN0KQ0KLQl7DQotCQltX3BMaXN0ID0gbmV3IENQV0xfQ0JMaXN0Qm94Ow0KLQkJbV9wTGlzdC0+QXR0YWNoRkZMRGF0YShtX3BGb3JtRmlsbGVyKTsNCi0JCVBXTF9DUkVBVEVQQVJBTSBsY3AgPSBjcDsNCi0JCWxjcC5wUGFyZW50V25kID0gdGhpczsNCi0JCWxjcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX0JPUkRFUiB8IFBXU19CQUNLR1JPVU5EIHwgUExCU19IT1ZFUlNFTCB8IFBXU19WU0NST0xMOw0KLQkJbGNwLm5Cb3JkZXJTdHlsZSA9IFBCU19TT0xJRDsNCi0JCWxjcC5kd0JvcmRlcldpZHRoID0gMTsNCi0JCWxjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfQVJST1c7DQotCQlsY3AucmNSZWN0V25kID0gQ1BERl9SZWN0KDAsMCwwLDApOw0KLQ0KLQkJaWYgKGNwLmR3RmxhZ3MgJiBQV1NfQVVUT0ZPTlRTSVpFKQ0KLQkJCWxjcC5mRm9udFNpemUgPSBQV0xDQl9ERUZBVUxURk9OVFNJWkU7DQotCQllbHNlDQotCQkJbGNwLmZGb250U2l6ZSA9IGNwLmZGb250U2l6ZTsNCi0NCi0JCWlmIChjcC5zQm9yZGVyQ29sb3IubkNvbG9yVHlwZSA9PSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQpDQotCQkJbGNwLnNCb3JkZXJDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7DQotDQotCQlpZiAoY3Auc0JhY2tncm91bmRDb2xvci5uQ29sb3JUeXBlID09IENPTE9SVFlQRV9UUkFOU1BBUkVOVCkNCi0JCQlsY3Auc0JhY2tncm91bmRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CQkNCi0NCi0JCW1fcExpc3QtPkNyZWF0ZShsY3ApOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Db21ib0JveDo6UmVQb3NDaGlsZFduZCgpDQotew0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotDQotCWlmIChtX2JQb3B1cCkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotCQlDUERGX1JlY3QgcmNCdXR0b24gPSByY2xpZW50Ow0KLQkJQ1BERl9SZWN0IHJjRWRpdCA9IHJjQ2xpZW50Ow0KLQkJQ1BERl9SZWN0IHJjTGlzdCA9IENQV0xfV25kOjpHZXRXaW5kb3dSZWN0KCk7DQotDQotCQlGWF9GTE9BVCBmT2xkV2luZG93SGVpZ2h0ID0gbV9yY09sZFdpbmRvdy5IZWlnaHQoKTsNCi0JCUZYX0ZMT0FUIGZPbGRDbGllbnRIZWlnaHQgPSBmT2xkV2luZG93SGVpZ2h0IC0gR2V0Qm9yZGVyV2lkdGgoKSAqIDI7DQotCQkNCi0JCXN3aXRjaCAobV9uUG9wdXBXaGVyZSkNCi0JCXsNCi0JCWNhc2UgMDoNCi0JCQlyY0J1dHRvbi5sZWZ0ID0gcmNCdXR0b24ucmlnaHQgLSBQV0xfQ09NQk9CT1hfQlVUVE9OX1dJRFRIOw0KLQ0KLQkJCWlmIChyY0J1dHRvbi5sZWZ0IDwgcmNsaWVudC5sZWZ0KQ0KLQkJCQlyY0J1dHRvbi5sZWZ0ID0gcmNsaWVudC5sZWZ0Ow0KLQkJCQ0KLQkJCXJjQnV0dG9uLmJvdHRvbSA9IHJjQnV0dG9uLnRvcCAtIGZPbGRDbGllbnRIZWlnaHQ7DQotDQotCQkJcmNFZGl0LnJpZ2h0ID0gcmNCdXR0b24ubGVmdCAtIDEuMGY7DQotDQotCQkJaWYgKHJjRWRpdC5sZWZ0IDwgcmNsaWVudC5sZWZ0KQ0KLQkJCQlyY0VkaXQubGVmdCA9IHJjbGllbnQubGVmdDsNCi0NCi0JCQlpZiAocmNFZGl0LnJpZ2h0IDwgcmNFZGl0LmxlZnQpDQotCQkJCXJjRWRpdC5yaWdodCA9IHJjRWRpdC5sZWZ0Ow0KLQ0KLQkJCXJjRWRpdC5ib3R0b20gPSByY0VkaXQudG9wIC0gZk9sZENsaWVudEhlaWdodDsNCi0NCi0JCQlyY0xpc3QudG9wIC09IGZPbGRXaW5kb3dIZWlnaHQ7DQotDQotCQkJYnJlYWs7DQotCQljYXNlIDE6DQotCQkJcmNCdXR0b24ubGVmdCA9IHJjQnV0dG9uLnJpZ2h0IC0gUFdMX0NPTUJPQk9YX0JVVFRPTl9XSURUSDsNCi0NCi0JCQlpZiAocmNCdXR0b24ubGVmdCA8IHJjbGllbnQubGVmdCkNCi0JCQkJcmNCdXR0b24ubGVmdCA9IHJjbGllbnQubGVmdDsNCi0JCQkNCi0JCQlyY0J1dHRvbi50b3AgPSByY0J1dHRvbi5ib3R0b20gKyBmT2xkQ2xpZW50SGVpZ2h0Ow0KLQ0KLQkJCXJjRWRpdC5yaWdodCA9IHJjQnV0dG9uLmxlZnQgLSAxLjBmOw0KLQ0KLQkJCWlmIChyY0VkaXQubGVmdCA8IHJjbGllbnQubGVmdCkNCi0JCQkJcmNFZGl0LmxlZnQgPSByY2xpZW50LmxlZnQ7DQotDQotCQkJaWYgKHJjRWRpdC5yaWdodCA8IHJjRWRpdC5sZWZ0KQ0KLQkJCQlyY0VkaXQucmlnaHQgPSByY0VkaXQubGVmdDsNCi0NCi0JCQlyY0VkaXQudG9wID0gcmNFZGl0LmJvdHRvbSArIGZPbGRDbGllbnRIZWlnaHQ7DQotDQotCQkJcmNMaXN0LmJvdHRvbSArPSBmT2xkV2luZG93SGVpZ2h0Ow0KLQ0KLQkJCWJyZWFrOw0KLQkJfQkJDQotDQotCQlpZiAobV9wQnV0dG9uKQ0KLQkJCW1fcEJ1dHRvbi0+TW92ZShyY0J1dHRvbixUUlVFLEZBTFNFKTsNCi0NCi0JCWlmIChtX3BFZGl0KQ0KLQkJCW1fcEVkaXQtPk1vdmUocmNFZGl0LFRSVUUsRkFMU0UpOw0KLQ0KLQkJaWYgKG1fcExpc3QpDQotCQl7DQotCQkJbV9wTGlzdC0+U2V0VmlzaWJsZShUUlVFKTsJCQkNCi0JCQltX3BMaXN0LT5Nb3ZlKHJjTGlzdCxUUlVFLEZBTFNFKTsNCi0JCQltX3BMaXN0LT5TY3JvbGxUb0xpc3RJdGVtKG1fblNlbGVjdEl0ZW0pOw0KLQkJfQ0KLQl9DQotCWVsc2UNCi0JewkJDQotCQlDUERGX1JlY3QgcmNCdXR0b24gPSByY0NsaWVudDsNCi0NCi0JCXJjQnV0dG9uLmxlZnQgPSByY0J1dHRvbi5yaWdodCAtIFBXTF9DT01CT0JPWF9CVVRUT05fV0lEVEg7CQ0KLQkJDQotCQlpZiAocmNCdXR0b24ubGVmdCA8IHJjQ2xpZW50LmxlZnQpDQotCQkJcmNCdXR0b24ubGVmdCA9IHJjQ2xpZW50LmxlZnQ7DQotDQotCQlpZiAobV9wQnV0dG9uKQ0KLQkJCW1fcEJ1dHRvbi0+TW92ZShyY0J1dHRvbixUUlVFLEZBTFNFKTsNCi0NCi0JCUNQREZfUmVjdCByY0VkaXQgPSByY0NsaWVudDsNCi0JCXJjRWRpdC5yaWdodCA9IHJjQnV0dG9uLmxlZnQgLSAxLjBmOw0KLQ0KLQkJaWYgKHJjRWRpdC5sZWZ0IDwgcmNDbGllbnQubGVmdCkNCi0JCQlyY0VkaXQubGVmdCA9IHJjQ2xpZW50LmxlZnQ7DQotDQotCQlpZiAocmNFZGl0LnJpZ2h0IDwgcmNFZGl0LmxlZnQpDQotCQkJcmNFZGl0LnJpZ2h0ID0gcmNFZGl0LmxlZnQ7DQotDQotCQlpZiAobV9wRWRpdCkNCi0JCQltX3BFZGl0LT5Nb3ZlKHJjRWRpdCxUUlVFLEZBTFNFKTsNCi0NCi0JCWlmIChtX3BMaXN0KQ0KLQkJCW1fcExpc3QtPlNldFZpc2libGUoRkFMU0UpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Db21ib0JveDo6U2VsZWN0QWxsKCkNCi17DQotCWlmIChtX3BFZGl0ICYmIEhhc0ZsYWcoUENCU19BTExPV0NVU1RPTVRFWFQpKQ0KLQkJbV9wRWRpdC0+U2VsZWN0QWxsKCk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX0NvbWJvQm94OjpHZXRGb2N1c1JlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIENQREZfUmVjdCgpOw0KLX0NCi0NCi12b2lkIENQV0xfQ29tYm9Cb3g6OlNldFBvcHVwKEZYX0JPT0wgYlBvcHVwKQ0KLXsNCi0JaWYgKCFtX3BMaXN0KSByZXR1cm47DQotCWlmIChiUG9wdXAgPT0gbV9iUG9wdXApIHJldHVybjsNCi0JRlhfRkxPQVQgZkxpc3RIZWlnaHQgPSBtX3BMaXN0LT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOw0KLQlpZiAoIUlzRmxvYXRCaWdnZXIoZkxpc3RIZWlnaHQsMC4wZikpIHJldHVybjsNCi0NCi0JaWYgKGJQb3B1cCkNCi0Jew0KLQkJaWYgKG1fcEZpbGxlck5vdGlmeSkNCi0JCXsNCi0JCQlGWF9JTlQzMiBuV2hlcmUgPSAwOw0KLQkJCUZYX0ZMT0FUIGZQb3B1cFJldCA9IDAuMGY7DQotCQkJRlhfRkxPQVQgZlBvcHVwTWluID0gMC4wZjsNCi0JCQlpZiAobV9wTGlzdC0+R2V0Q291bnQoKSA+IDMpDQotCQkJCWZQb3B1cE1pbiA9IG1fcExpc3QtPkdldEZpcnN0SGVpZ2h0KCkgKiAzICsgbV9wTGlzdC0+R2V0Qm9yZGVyV2lkdGgoKSAqIDI7DQotCQkJRlhfRkxPQVQgZlBvcHVwTWF4ID0gZkxpc3RIZWlnaHQgKyBtX3BMaXN0LT5HZXRCb3JkZXJXaWR0aCgpICogMjsNCi0JCQltX3BGaWxsZXJOb3RpZnktPlF1ZXJ5V2hlcmVQb3B1cChHZXRBdHRhY2hlZERhdGEoKSwgZlBvcHVwTWluLGZQb3B1cE1heCxuV2hlcmUsZlBvcHVwUmV0KTsNCi0NCi0JCQlpZiAoSXNGbG9hdEJpZ2dlcihmUG9wdXBSZXQsMC4wZikpDQotCQkJew0KLQkJCQltX2JQb3B1cCA9IGJQb3B1cDsNCi0NCi0JCQkJQ1BERl9SZWN0IHJjV2luZG93ID0gQ1BXTF9XbmQ6OkdldFdpbmRvd1JlY3QoKTsNCi0JCQkJbV9yY09sZFdpbmRvdyA9IHJjV2luZG93Ow0KLQkJCQlzd2l0Y2ggKG5XaGVyZSkNCi0JCQkJew0KLQkJCQlkZWZhdWx0Og0KLQkJCQljYXNlIDA6DQotCQkJCQlyY1dpbmRvdy5ib3R0b20gLT0gZlBvcHVwUmV0Ow0KLQkJCQkJYnJlYWs7DQotCQkJCWNhc2UgMToNCi0JCQkJCXJjV2luZG93LnRvcCArPSBmUG9wdXBSZXQ7DQotCQkJCQlicmVhazsNCi0JCQkJfQ0KLQkJCQkNCi0JCQkJbV9uUG9wdXBXaGVyZSA9IG5XaGVyZTsNCi0JCQkJTW92ZShyY1dpbmRvdywgVFJVRSwgVFJVRSk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJbV9iUG9wdXAgPSBiUG9wdXA7DQotCQlNb3ZlKG1fcmNPbGRXaW5kb3csIFRSVUUsIFRSVUUpOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9Db21ib0JveDo6T25LZXlEb3duKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JaWYgKCFtX3BMaXN0KSByZXR1cm4gRkFMU0U7DQotCWlmICghbV9wRWRpdCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQltX25TZWxlY3RJdGVtID0gLTE7DQotDQotCXN3aXRjaCAobkNoYXIpDQotCXsNCi0JY2FzZSBGV0xfVktFWV9VcDoNCi0JCWlmIChtX3BMaXN0LT5HZXRDdXJTZWwoKSA+IDApDQotCQl7DQotCQkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOw0KLQkJCWlmIChtX3BMaXN0LT5PbktleURvd24obkNoYXIsYkV4aXQsbkZsYWcpKQ0KLQkJCXsNCi0JCQkJaWYgKGJFeGl0KSByZXR1cm4gRkFMU0U7DQotCQkJCVNldFNlbGVjdFRleHQoKTsJCQkJDQotCQkJfQ0KLQkJfQ0KLQkJcmV0dXJuIFRSVUU7DQotCWNhc2UgRldMX1ZLRVlfRG93bjoNCi0JCWlmIChtX3BMaXN0LT5HZXRDdXJTZWwoKSA8IG1fcExpc3QtPkdldENvdW50KCkgLSAxKQ0KLQkJew0KLQkJCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsNCi0JCQlpZiAobV9wTGlzdC0+T25LZXlEb3duKG5DaGFyLGJFeGl0LG5GbGFnKSkNCi0JCQl7DQotCQkJCWlmIChiRXhpdCkgcmV0dXJuIEZBTFNFOw0KLQkJCQlTZXRTZWxlY3RUZXh0KCk7CQkJCQ0KLQkJCX0NCi0JCX0NCi0JCXJldHVybiBUUlVFOw0KLQl9DQotDQotCWlmIChIYXNGbGFnKFBDQlNfQUxMT1dDVVNUT01URVhUKSkNCi0JCXJldHVybiBtX3BFZGl0LT5PbktleURvd24obkNoYXIsbkZsYWcpOw0KLQllbHNlDQotCQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9Db21ib0JveDo6T25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JaWYgKCFtX3BMaXN0KSByZXR1cm4gRkFMU0U7DQotCWlmICghbV9wRWRpdCkgcmV0dXJuIEZBTFNFOw0KLQ0KLQltX25TZWxlY3RJdGVtID0gLTE7DQotCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsNCi0NCi0JaWYgKEhhc0ZsYWcoUENCU19BTExPV0NVU1RPTVRFWFQpKQ0KLQl7DQotCQlyZXR1cm4gbV9wRWRpdC0+T25DaGFyKG5DaGFyLG5GbGFnKTsJCQkNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BMaXN0LT5PbkNoYXIobkNoYXIsYkV4aXQsbkZsYWcpKQ0KLQkJew0KLQkJCXJldHVybiBiRXhpdDsNCi0JCX0NCi0JCWVsc2UNCi0JCQlyZXR1cm4gRkFMU0U7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0NvbWJvQm94OjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQ0KLXsNCi0Jc3dpdGNoIChtc2cpDQotCXsNCi0JY2FzZSBQTk1fTEJVVFRPTkRPV046DQotCQlpZiAocFduZCA9PSBtX3BCdXR0b24pDQotCQl7DQotCQkJU2V0UG9wdXAoIW1fYlBvcHVwKTsNCi0JCQlyZXR1cm47DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBQTk1fTEJVVFRPTlVQOg0KLQkJaWYgKG1fcEVkaXQgJiYgbV9wTGlzdCkNCi0JCXsNCi0JCQlpZiAocFduZCA9PSBtX3BMaXN0KQ0KLQkJCXsJCQkNCi0JCQkJU2V0U2VsZWN0VGV4dCgpOw0KLQkJCQlTZWxlY3RBbGwoKTsNCi0JCQkJbV9wRWRpdC0+U2V0Rm9jdXMoKTsNCi0JCQkJU2V0UG9wdXAoRkFMU0UpOw0KLQkJCQlyZXR1cm47DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCUNQV0xfV25kOjpPbk5vdGlmeShwV25kLG1zZyx3UGFyYW0sbFBhcmFtKTsNCi19DQotDQotRlhfQk9PTCBDUFdMX0NvbWJvQm94OjpJc1BvcHVwKCkgY29uc3QNCi17DQotCXJldHVybiBtX2JQb3B1cDsNCi19DQotDQotdm9pZCBDUFdMX0NvbWJvQm94OjpTZXRTZWxlY3RUZXh0KCkNCi17DQotCUNGWF9XaWRlU3RyaW5nIHN3VGV4dCA9IG1fcExpc3QtPkdldFRleHQoKTsNCi0JbV9wRWRpdC0+U2VsZWN0QWxsKCk7DQotCW1fcEVkaXQtPlJlcGxhY2VTZWwobV9wTGlzdC0+R2V0VGV4dCgpKTsNCi0JbV9wRWRpdC0+U2VsZWN0QWxsKCk7DQotDQotCW1fblNlbGVjdEl0ZW0gPSBtX3BMaXN0LT5HZXRDdXJTZWwoKTsNCi19DQotDQotRlhfQk9PTCBDUFdMX0NvbWJvQm94OjpJc01vZGlmaWVkKCkgY29uc3QNCi17DQotCXJldHVybiBtX3BFZGl0LT5Jc01vZGlmaWVkKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Db21ib0JveDo6U2V0RmlsbGVyTm90aWZ5KElQV0xfRmlsbGVyX05vdGlmeSogcE5vdGlmeSkNCi17DQotCSBtX3BGaWxsZXJOb3RpZnkgPSBwTm90aWZ5Ow0KLQ0KLQkgaWYgKG1fcEVkaXQpDQotCQkgbV9wRWRpdC0+U2V0RmlsbGVyTm90aWZ5KHBOb3RpZnkpOw0KLQ0KLQkgaWYgKG1fcExpc3QpDQotCQkgbV9wTGlzdC0+U2V0RmlsbGVyTm90aWZ5KHBOb3RpZnkpOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9FZGl0Q3RybC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9FZGl0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RCb3guaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ29tYm9Cb3guaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCIKKworI2RlZmluZSBQV0xDQl9ERUZBVUxURk9OVFNJWkUgIDEyLjBmCisKKyNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpCisjZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCSgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQorI2RlZmluZSBJc0Zsb2F0U21hbGxlcihmYSxmYikJCQkJKChmYSkgPCAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpCisjZGVmaW5lIElzRmxvYXRFcXVhbChmYSxmYikJCQkJCUlzRmxvYXRaZXJvKChmYSktKGZiKSkKKworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfQ0JMaXN0Qm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworRlhfQk9PTAlDUFdMX0NCTGlzdEJveDo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKK3sKKwlDUFdMX1duZDo6T25MQnV0dG9uVXAocG9pbnQsbkZsYWcpOworCisJaWYgKG1fYk1vdXNlRG93bikKKwl7CisJCVJlbGVhc2VDYXB0dXJlKCk7CisJCW1fYk1vdXNlRG93biA9IEZBTFNFOwkKKworCQlpZiAodGhpcy0+Q2xpZW50SGl0VGVzdChwb2ludCkpCisJCXsKKwkJCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkKKwkJCXsKKwkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLFBOTV9MQlVUVE9OVVAsMCxQV0xfTUFLRURXT1JEKHBvaW50LngscG9pbnQueSkpOwkJCQorCQkJfQorCQkKKwkJCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsKKwkJCU9uTm90aWZ5U2VsQ2hhbmdlZChGQUxTRSxiRXhpdCwgbkZsYWcpOworCQkJaWYgKGJFeGl0KSByZXR1cm4gRkFMU0U7CisJCX0KKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDUFdMX0NCTGlzdEJveDo6T25LZXlEb3duKEZYX1dPUkQgbkNoYXIsIEZYX0JPT0wgJiBiRXhpdCwgRlhfRFdPUkQgbkZsYWcpCit7CisJaWYgKCFtX3BMaXN0KSByZXR1cm4gRkFMU0U7CisKKwlzd2l0Y2ggKG5DaGFyKQorCXsKKwlkZWZhdWx0OgorCQlyZXR1cm4gRkFMU0U7CisJY2FzZSBGV0xfVktFWV9VcDoKKwljYXNlIEZXTF9WS0VZX0Rvd246CisJY2FzZSBGV0xfVktFWV9Ib21lOgorCWNhc2UgRldMX1ZLRVlfTGVmdDoKKwljYXNlIEZXTF9WS0VZX0VuZDoKKwljYXNlIEZXTF9WS0VZX1JpZ2h0OgorCQlicmVhazsJCisJfQorCisJc3dpdGNoIChuQ2hhcikKKwl7CisJY2FzZSBGV0xfVktFWV9VcDoKKwkJbV9wTGlzdC0+T25WS19VUChJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCQlicmVhazsKKwljYXNlIEZXTF9WS0VZX0Rvd246CisJCW1fcExpc3QtPk9uVktfRE9XTihJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCQlicmVhazsKKwljYXNlIEZXTF9WS0VZX0hvbWU6CisJCW1fcExpc3QtPk9uVktfSE9NRShJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCQlicmVhazsKKwljYXNlIEZXTF9WS0VZX0xlZnQ6CisJCW1fcExpc3QtPk9uVktfTEVGVChJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCQlicmVhazsKKwljYXNlIEZXTF9WS0VZX0VuZDoKKwkJbV9wTGlzdC0+T25WS19FTkQoSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKTsKKwkJYnJlYWs7CisJY2FzZSBGV0xfVktFWV9SaWdodDoKKwkJbV9wTGlzdC0+T25WS19SSUdIVChJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCQlicmVhazsKKwljYXNlIEZXTF9WS0VZX0RlbGV0ZToKKwkJYnJlYWs7CisJfQorCisJT25Ob3RpZnlTZWxDaGFuZ2VkKFRSVUUsYkV4aXQsIG5GbGFnKTsKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MCUNQV0xfQ0JMaXN0Qm94OjpPbkNoYXIoRlhfV09SRCBuQ2hhciwgRlhfQk9PTCAmIGJFeGl0LCBGWF9EV09SRCBuRmxhZykKK3sKKwlpZiAoIW1fcExpc3QpIHJldHVybiBGQUxTRTsKKworCWlmICghbV9wTGlzdC0+T25DaGFyKG5DaGFyLElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSkpIHJldHVybiBGQUxTRTsKKworCWlmIChDUFdMX0NvbWJvQm94KiBwQ29tYm9Cb3ggPSAoQ1BXTF9Db21ib0JveCopR2V0UGFyZW50V2luZG93KCkpCisJeworCQlwQ29tYm9Cb3gtPlNldFNlbGVjdFRleHQoKTsKKwl9CisKKwlPbk5vdGlmeVNlbENoYW5nZWQoVFJVRSxiRXhpdCxuRmxhZyk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0NCQnV0dG9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKwordm9pZCBDUFdMX0NCQnV0dG9uOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKQoreworCUNQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsKKwkKKwlDUERGX1JlY3QgcmVjdFduZCA9IENQV0xfV25kOjpHZXRXaW5kb3dSZWN0KCk7CisJCisJaWYgKElzVmlzaWJsZSgpICYmICFyZWN0V25kLklzRW1wdHkoKSkKKwl7CisJCUNGWF9CeXRlVGV4dEJ1ZiBzQnV0dG9uOwkKKworCQlDUERGX1BvaW50IHB0Q2VudGVyID0gdGhpcy0+R2V0Q2VudGVyUG9pbnQoKTsKKworCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4scHRDZW50ZXIueSArIFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOICogMC41Zik7CisJCUNQREZfUG9pbnQgcHQyKHB0Q2VudGVyLnggKyBQV0xfQ0JCVVRUT05fVFJJQU5HTEVfSEFMRkxFTixwdENlbnRlci55ICsgUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmKTsKKwkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCxwdENlbnRlci55IC0gUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmKTsKKworCQlpZiAoSXNGbG9hdEJpZ2dlcihyZWN0V25kLnJpZ2h0IC0gcmVjdFduZC5sZWZ0LFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOICogMikKKwkJCSYmCisJCQlJc0Zsb2F0QmlnZ2VyKHJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20sUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4pCisJCQkpCisJCXsKKwkJCXNCdXR0b24gPDwgIjAgZ1xuIjsKKwkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsKKwkJCXNCdXR0b24gPDwgcHQyLnggPDwgIiAiIDw8IHB0Mi55IDw8ICIgbFxuIjsKKwkJCXNCdXR0b24gPDwgcHQzLnggPDwgIiAiIDw8IHB0My55IDw8ICIgbFxuIjsKKwkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbCBmXG4iOworCisJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IHNCdXR0b24gPDwgIlFcbiI7CisJCX0JCisJfQorfQorCit2b2lkIENQV0xfQ0JCdXR0b246OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQoreworCUNQV0xfV25kOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSxwVXNlcjJEZXZpY2UpOworCisJQ1BERl9SZWN0IHJlY3RXbmQgPSBDUFdMX1duZDo6R2V0V2luZG93UmVjdCgpOworCQorCWlmIChJc1Zpc2libGUoKSAmJiAhcmVjdFduZC5Jc0VtcHR5KCkpCisJeworCQlDUERGX1BvaW50IHB0Q2VudGVyID0gdGhpcy0+R2V0Q2VudGVyUG9pbnQoKTsKKworCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4scHRDZW50ZXIueSArIFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOICogMC41Zik7CisJCUNQREZfUG9pbnQgcHQyKHB0Q2VudGVyLnggKyBQV0xfQ0JCVVRUT05fVFJJQU5HTEVfSEFMRkxFTixwdENlbnRlci55ICsgUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmKTsKKwkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCxwdENlbnRlci55IC0gUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmKTsKKworCQlpZiAoSXNGbG9hdEJpZ2dlcihyZWN0V25kLnJpZ2h0IC0gcmVjdFduZC5sZWZ0LFBXTF9DQkJVVFRPTl9UUklBTkdMRV9IQUxGTEVOICogMikKKwkJCSYmCisJCQlJc0Zsb2F0QmlnZ2VyKHJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20sUFdMX0NCQlVUVE9OX1RSSUFOR0xFX0hBTEZMRU4pCisJCQkpCisJCXsKKwkJCUNGWF9QYXRoRGF0YSBwYXRoOworCisJCQlwYXRoLlNldFBvaW50Q291bnQoNCk7CisJCQlwYXRoLlNldFBvaW50KDAsIHB0MS54LCBwdDEueSwgRlhQVF9NT1ZFVE8pOworCQkJcGF0aC5TZXRQb2ludCgxLCBwdDIueCwgcHQyLnksIEZYUFRfTElORVRPKTsKKwkJCXBhdGguU2V0UG9pbnQoMiwgcHQzLngsIHB0My55LCBGWFBUX0xJTkVUTyk7CisJCQlwYXRoLlNldFBvaW50KDMsIHB0MS54LCBwdDEueSwgRlhQVF9MSU5FVE8pOworCisJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCAKKwkJCQlDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihQV0xfREVGQVVMVF9CTEFDS0NPTE9SLEdldFRyYW5zcGFyZW5jeSgpKSwgCisJCQkJMCwgRlhGSUxMX0FMVEVSTkFURSk7CisJCX0KKwl9Cit9CisKK0ZYX0JPT0wJQ1BXTF9DQkJ1dHRvbjo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCUNQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKTsKKworCVNldENhcHR1cmUoKTsKKworCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkKKwl7CQkKKwkJcFBhcmVudC0+T25Ob3RpZnkodGhpcyxQTk1fTEJVVFRPTkRPV04sMCxQV0xfTUFLRURXT1JEKHBvaW50LngscG9pbnQueSkpOworCX0KKwkKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDUFdMX0NCQnV0dG9uOjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCUNQV0xfV25kOjpPbkxCdXR0b25VcChwb2ludCwgbkZsYWcpOworCisJUmVsZWFzZUNhcHR1cmUoKTsKKworCXJldHVybiBUUlVFOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfQ29tYm9Cb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0NvbWJvQm94OjpDUFdMX0NvbWJvQm94KCkgOiBtX3BFZGl0KE5VTEwpLAorCW1fcEJ1dHRvbihOVUxMKSwKKwltX3BMaXN0KE5VTEwpLAorCW1fYlBvcHVwKEZBTFNFKSwKKwltX25Qb3B1cFdoZXJlKDApLAorCW1fblNlbGVjdEl0ZW0oLTEpLAorCW1fcEZpbGxlck5vdGlmeShOVUxMKQoreworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX0NvbWJvQm94OjpHZXRDbGFzc05hbWUoKSBjb25zdAoreworCXJldHVybiAiQ1BXTF9Db21ib0JveCI7Cit9CisKK3ZvaWQgQ1BXTF9Db21ib0JveDo6T25DcmVhdGUoUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJY3AuZHdGbGFncyAmPSB+UFdTX0hTQ1JPTEw7CisJY3AuZHdGbGFncyAmPSB+UFdTX1ZTQ1JPTEw7Cit9CisKK3ZvaWQgQ1BXTF9Db21ib0JveDo6U2V0Rm9jdXMoKQoreworCWlmIChtX3BFZGl0KQorCQltX3BFZGl0LT5TZXRGb2N1cygpOworfQorCit2b2lkIENQV0xfQ29tYm9Cb3g6OktpbGxGb2N1cygpCit7CisJU2V0UG9wdXAoRkFMU0UpOworCUNQV0xfV25kOjpLaWxsRm9jdXMoKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Db21ib0JveDo6R2V0VGV4dCgpIGNvbnN0Cit7CisJaWYgKG1fcEVkaXQpCisJeworCQlyZXR1cm4gbV9wRWRpdC0+R2V0VGV4dCgpOworCX0KKwlyZXR1cm4gQ0ZYX1dpZGVTdHJpbmcoKTsKK30KKwordm9pZCBDUFdMX0NvbWJvQm94OjpTZXRUZXh0KEZYX0xQQ1dTVFIgdGV4dCkKK3sKKwlpZiAobV9wRWRpdCkKKwkJbV9wRWRpdC0+U2V0VGV4dCh0ZXh0KTsKK30KKwordm9pZCBDUFdMX0NvbWJvQm94OjpBZGRTdHJpbmcoRlhfTFBDV1NUUiBzdHJpbmcpCit7CisJaWYgKG1fcExpc3QpCisJCW1fcExpc3QtPkFkZFN0cmluZyhzdHJpbmcpOworfQorCitGWF9JTlQzMiBDUFdMX0NvbWJvQm94OjpHZXRTZWxlY3QoKSBjb25zdAoreworCXJldHVybiBtX25TZWxlY3RJdGVtOworfQorCit2b2lkIENQV0xfQ29tYm9Cb3g6OlNldFNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4KQoreworCWlmIChtX3BMaXN0KQorCQltX3BMaXN0LT5TZWxlY3Qobkl0ZW1JbmRleCk7CisKKwltX3BFZGl0LT5TZXRUZXh0KG1fcExpc3QtPkdldFRleHQoKSk7CisKKwltX25TZWxlY3RJdGVtID0gbkl0ZW1JbmRleDsKK30KKwordm9pZCBDUFdMX0NvbWJvQm94OjpTZXRFZGl0U2VsKEZYX0lOVDMyIG5TdGFydENoYXIsRlhfSU5UMzIgbkVuZENoYXIpCit7CisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5TZXRTZWwoblN0YXJ0Q2hhcixuRW5kQ2hhcik7CisJfQorfQorCit2b2lkIENQV0xfQ29tYm9Cb3g6OkdldEVkaXRTZWwoRlhfSU5UMzIgJiBuU3RhcnRDaGFyLCBGWF9JTlQzMiAmIG5FbmRDaGFyKSBjb25zdAoreworCW5TdGFydENoYXIgPSAtMTsKKwluRW5kQ2hhciA9IC0xOworCisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5HZXRTZWwoblN0YXJ0Q2hhcixuRW5kQ2hhcik7CisJfQorfQorCit2b2lkIENQV0xfQ29tYm9Cb3g6OkNsZWFyKCkKK3sKKwlpZiAobV9wRWRpdCkKKwl7CisJCW1fcEVkaXQtPkNsZWFyKCk7CisJfQorfQorCit2b2lkIENQV0xfQ29tYm9Cb3g6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQoreworCUNyZWF0ZUVkaXQoY3ApOworCUNyZWF0ZUJ1dHRvbihjcCk7CisJQ3JlYXRlTGlzdEJveChjcCk7Cit9CisKK3ZvaWQgQ1BXTF9Db21ib0JveDo6Q3JlYXRlRWRpdChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKK3sKKwlpZiAoIW1fcEVkaXQpCisJeworCQltX3BFZGl0ID0gbmV3IENQV0xfQ0JFZGl0OworCQltX3BFZGl0LT5BdHRhY2hGRkxEYXRhKG1fcEZvcm1GaWxsZXIpOworCisJCVBXTF9DUkVBVEVQQVJBTSBlY3AgPSBjcDsKKwkJZWNwLnBQYXJlbnRXbmQgPSB0aGlzOworCQllY3AuZHdGbGFncyA9ICBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVIgfCBQRVNfQ0VOVEVSIHwgUEVTX0FVVE9TQ1JPTEwgfCBQRVNfVU5ETzsKKworCQlpZiAoSGFzRmxhZyhQV1NfQVVUT0ZPTlRTSVpFKSkKKwkJCWVjcC5kd0ZsYWdzIHw9IFBXU19BVVRPRk9OVFNJWkU7CisKKwkJaWYgKCFIYXNGbGFnKFBDQlNfQUxMT1dDVVNUT01URVhUKSkKKwkJCWVjcC5kd0ZsYWdzIHw9IFBXU19SRUFET05MWTsKKworCQllY3AucmNSZWN0V25kID0gQ1BERl9SZWN0KDAsMCwwLDApOworCQllY3AuZHdCb3JkZXJXaWR0aCA9IDA7CisJCWVjcC5uQm9yZGVyU3R5bGUgPSBQQlNfU09MSUQ7CisKKwkJbV9wRWRpdC0+Q3JlYXRlKGVjcCk7CisJfQorfQorCit2b2lkIENQV0xfQ29tYm9Cb3g6OkNyZWF0ZUJ1dHRvbihjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKK3sKKwlpZiAoIW1fcEJ1dHRvbikKKwl7CisJCW1fcEJ1dHRvbiA9IG5ldyBDUFdMX0NCQnV0dG9uOwkKKworCQlQV0xfQ1JFQVRFUEFSQU0gYmNwID0gY3A7CisJCWJjcC5wUGFyZW50V25kID0gdGhpczsKKwkJYmNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVIgfCBQV1NfQkFDS0dST1VORDsJCisJCWJjcC5zQmFja2dyb3VuZENvbG9yID0gUFdMX1NDUk9MTEJBUl9CS0NPTE9SOworCQliY3Auc0JvcmRlckNvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKKwkJYmNwLmR3Qm9yZGVyV2lkdGggPSAyOworCQliY3AubkJvcmRlclN0eWxlID0gUEJTX0JFVkVMRUQ7CisJCWJjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfQVJST1c7CisKKwkJbV9wQnV0dG9uLT5DcmVhdGUoYmNwKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9Db21ib0JveDo6Q3JlYXRlTGlzdEJveChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKK3sKKwlpZiAoIW1fcExpc3QpCisJeworCQltX3BMaXN0ID0gbmV3IENQV0xfQ0JMaXN0Qm94OworCQltX3BMaXN0LT5BdHRhY2hGRkxEYXRhKG1fcEZvcm1GaWxsZXIpOworCQlQV0xfQ1JFQVRFUEFSQU0gbGNwID0gY3A7CisJCWxjcC5wUGFyZW50V25kID0gdGhpczsKKwkJbGNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfQk9SREVSIHwgUFdTX0JBQ0tHUk9VTkQgfCBQTEJTX0hPVkVSU0VMIHwgUFdTX1ZTQ1JPTEw7CisJCWxjcC5uQm9yZGVyU3R5bGUgPSBQQlNfU09MSUQ7CisJCWxjcC5kd0JvcmRlcldpZHRoID0gMTsKKwkJbGNwLmVDdXJzb3JUeXBlID0gRlhDVF9BUlJPVzsKKwkJbGNwLnJjUmVjdFduZCA9IENQREZfUmVjdCgwLDAsMCwwKTsKKworCQlpZiAoY3AuZHdGbGFncyAmIFBXU19BVVRPRk9OVFNJWkUpCisJCQlsY3AuZkZvbnRTaXplID0gUFdMQ0JfREVGQVVMVEZPTlRTSVpFOworCQllbHNlCisJCQlsY3AuZkZvbnRTaXplID0gY3AuZkZvbnRTaXplOworCisJCWlmIChjcC5zQm9yZGVyQ29sb3IubkNvbG9yVHlwZSA9PSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQpCisJCQlsY3Auc0JvcmRlckNvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKKworCQlpZiAoY3Auc0JhY2tncm91bmRDb2xvci5uQ29sb3JUeXBlID09IENPTE9SVFlQRV9UUkFOU1BBUkVOVCkKKwkJCWxjcC5zQmFja2dyb3VuZENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsJCQorCisJCW1fcExpc3QtPkNyZWF0ZShsY3ApOworCX0KK30KKwordm9pZCBDUFdMX0NvbWJvQm94OjpSZVBvc0NoaWxkV25kKCkKK3sKKwlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisKKwlpZiAobV9iUG9wdXApCisJeworCQlDUERGX1JlY3QgcmNsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjQnV0dG9uID0gcmNsaWVudDsKKwkJQ1BERl9SZWN0IHJjRWRpdCA9IHJjQ2xpZW50OworCQlDUERGX1JlY3QgcmNMaXN0ID0gQ1BXTF9XbmQ6OkdldFdpbmRvd1JlY3QoKTsKKworCQlGWF9GTE9BVCBmT2xkV2luZG93SGVpZ2h0ID0gbV9yY09sZFdpbmRvdy5IZWlnaHQoKTsKKwkJRlhfRkxPQVQgZk9sZENsaWVudEhlaWdodCA9IGZPbGRXaW5kb3dIZWlnaHQgLSBHZXRCb3JkZXJXaWR0aCgpICogMjsKKwkJCisJCXN3aXRjaCAobV9uUG9wdXBXaGVyZSkKKwkJeworCQljYXNlIDA6CisJCQlyY0J1dHRvbi5sZWZ0ID0gcmNCdXR0b24ucmlnaHQgLSBQV0xfQ09NQk9CT1hfQlVUVE9OX1dJRFRIOworCisJCQlpZiAocmNCdXR0b24ubGVmdCA8IHJjbGllbnQubGVmdCkKKwkJCQlyY0J1dHRvbi5sZWZ0ID0gcmNsaWVudC5sZWZ0OworCQkJCisJCQlyY0J1dHRvbi5ib3R0b20gPSByY0J1dHRvbi50b3AgLSBmT2xkQ2xpZW50SGVpZ2h0OworCisJCQlyY0VkaXQucmlnaHQgPSByY0J1dHRvbi5sZWZ0IC0gMS4wZjsKKworCQkJaWYgKHJjRWRpdC5sZWZ0IDwgcmNsaWVudC5sZWZ0KQorCQkJCXJjRWRpdC5sZWZ0ID0gcmNsaWVudC5sZWZ0OworCisJCQlpZiAocmNFZGl0LnJpZ2h0IDwgcmNFZGl0LmxlZnQpCisJCQkJcmNFZGl0LnJpZ2h0ID0gcmNFZGl0LmxlZnQ7CisKKwkJCXJjRWRpdC5ib3R0b20gPSByY0VkaXQudG9wIC0gZk9sZENsaWVudEhlaWdodDsKKworCQkJcmNMaXN0LnRvcCAtPSBmT2xkV2luZG93SGVpZ2h0OworCisJCQlicmVhazsKKwkJY2FzZSAxOgorCQkJcmNCdXR0b24ubGVmdCA9IHJjQnV0dG9uLnJpZ2h0IC0gUFdMX0NPTUJPQk9YX0JVVFRPTl9XSURUSDsKKworCQkJaWYgKHJjQnV0dG9uLmxlZnQgPCByY2xpZW50LmxlZnQpCisJCQkJcmNCdXR0b24ubGVmdCA9IHJjbGllbnQubGVmdDsKKwkJCQorCQkJcmNCdXR0b24udG9wID0gcmNCdXR0b24uYm90dG9tICsgZk9sZENsaWVudEhlaWdodDsKKworCQkJcmNFZGl0LnJpZ2h0ID0gcmNCdXR0b24ubGVmdCAtIDEuMGY7CisKKwkJCWlmIChyY0VkaXQubGVmdCA8IHJjbGllbnQubGVmdCkKKwkJCQlyY0VkaXQubGVmdCA9IHJjbGllbnQubGVmdDsKKworCQkJaWYgKHJjRWRpdC5yaWdodCA8IHJjRWRpdC5sZWZ0KQorCQkJCXJjRWRpdC5yaWdodCA9IHJjRWRpdC5sZWZ0OworCisJCQlyY0VkaXQudG9wID0gcmNFZGl0LmJvdHRvbSArIGZPbGRDbGllbnRIZWlnaHQ7CisKKwkJCXJjTGlzdC5ib3R0b20gKz0gZk9sZFdpbmRvd0hlaWdodDsKKworCQkJYnJlYWs7CisJCX0JCQorCisJCWlmIChtX3BCdXR0b24pCisJCQltX3BCdXR0b24tPk1vdmUocmNCdXR0b24sVFJVRSxGQUxTRSk7CisKKwkJaWYgKG1fcEVkaXQpCisJCQltX3BFZGl0LT5Nb3ZlKHJjRWRpdCxUUlVFLEZBTFNFKTsKKworCQlpZiAobV9wTGlzdCkKKwkJeworCQkJbV9wTGlzdC0+U2V0VmlzaWJsZShUUlVFKTsJCQkKKwkJCW1fcExpc3QtPk1vdmUocmNMaXN0LFRSVUUsRkFMU0UpOworCQkJbV9wTGlzdC0+U2Nyb2xsVG9MaXN0SXRlbShtX25TZWxlY3RJdGVtKTsKKwkJfQorCX0KKwllbHNlCisJewkJCisJCUNQREZfUmVjdCByY0J1dHRvbiA9IHJjQ2xpZW50OworCisJCXJjQnV0dG9uLmxlZnQgPSByY0J1dHRvbi5yaWdodCAtIFBXTF9DT01CT0JPWF9CVVRUT05fV0lEVEg7CQorCQkKKwkJaWYgKHJjQnV0dG9uLmxlZnQgPCByY0NsaWVudC5sZWZ0KQorCQkJcmNCdXR0b24ubGVmdCA9IHJjQ2xpZW50LmxlZnQ7CisKKwkJaWYgKG1fcEJ1dHRvbikKKwkJCW1fcEJ1dHRvbi0+TW92ZShyY0J1dHRvbixUUlVFLEZBTFNFKTsKKworCQlDUERGX1JlY3QgcmNFZGl0ID0gcmNDbGllbnQ7CisJCXJjRWRpdC5yaWdodCA9IHJjQnV0dG9uLmxlZnQgLSAxLjBmOworCisJCWlmIChyY0VkaXQubGVmdCA8IHJjQ2xpZW50LmxlZnQpCisJCQlyY0VkaXQubGVmdCA9IHJjQ2xpZW50LmxlZnQ7CisKKwkJaWYgKHJjRWRpdC5yaWdodCA8IHJjRWRpdC5sZWZ0KQorCQkJcmNFZGl0LnJpZ2h0ID0gcmNFZGl0LmxlZnQ7CisKKwkJaWYgKG1fcEVkaXQpCisJCQltX3BFZGl0LT5Nb3ZlKHJjRWRpdCxUUlVFLEZBTFNFKTsKKworCQlpZiAobV9wTGlzdCkKKwkJCW1fcExpc3QtPlNldFZpc2libGUoRkFMU0UpOworCX0KK30KKwordm9pZCBDUFdMX0NvbWJvQm94OjpTZWxlY3RBbGwoKQoreworCWlmIChtX3BFZGl0ICYmIEhhc0ZsYWcoUENCU19BTExPV0NVU1RPTVRFWFQpKQorCQltX3BFZGl0LT5TZWxlY3RBbGwoKTsKK30KKworQ1BERl9SZWN0IENQV0xfQ29tYm9Cb3g6OkdldEZvY3VzUmVjdCgpIGNvbnN0Cit7CisJcmV0dXJuIENQREZfUmVjdCgpOworfQorCit2b2lkIENQV0xfQ29tYm9Cb3g6OlNldFBvcHVwKEZYX0JPT0wgYlBvcHVwKQoreworCWlmICghbV9wTGlzdCkgcmV0dXJuOworCWlmIChiUG9wdXAgPT0gbV9iUG9wdXApIHJldHVybjsKKwlGWF9GTE9BVCBmTGlzdEhlaWdodCA9IG1fcExpc3QtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CisJaWYgKCFJc0Zsb2F0QmlnZ2VyKGZMaXN0SGVpZ2h0LDAuMGYpKSByZXR1cm47CisKKwlpZiAoYlBvcHVwKQorCXsKKwkJaWYgKG1fcEZpbGxlck5vdGlmeSkKKwkJeworCQkJRlhfSU5UMzIgbldoZXJlID0gMDsKKwkJCUZYX0ZMT0FUIGZQb3B1cFJldCA9IDAuMGY7CisJCQlGWF9GTE9BVCBmUG9wdXBNaW4gPSAwLjBmOworCQkJaWYgKG1fcExpc3QtPkdldENvdW50KCkgPiAzKQorCQkJCWZQb3B1cE1pbiA9IG1fcExpc3QtPkdldEZpcnN0SGVpZ2h0KCkgKiAzICsgbV9wTGlzdC0+R2V0Qm9yZGVyV2lkdGgoKSAqIDI7CisJCQlGWF9GTE9BVCBmUG9wdXBNYXggPSBmTGlzdEhlaWdodCArIG1fcExpc3QtPkdldEJvcmRlcldpZHRoKCkgKiAyOworCQkJbV9wRmlsbGVyTm90aWZ5LT5RdWVyeVdoZXJlUG9wdXAoR2V0QXR0YWNoZWREYXRhKCksIGZQb3B1cE1pbixmUG9wdXBNYXgsbldoZXJlLGZQb3B1cFJldCk7CisKKwkJCWlmIChJc0Zsb2F0QmlnZ2VyKGZQb3B1cFJldCwwLjBmKSkKKwkJCXsKKwkJCQltX2JQb3B1cCA9IGJQb3B1cDsKKworCQkJCUNQREZfUmVjdCByY1dpbmRvdyA9IENQV0xfV25kOjpHZXRXaW5kb3dSZWN0KCk7CisJCQkJbV9yY09sZFdpbmRvdyA9IHJjV2luZG93OworCQkJCXN3aXRjaCAobldoZXJlKQorCQkJCXsKKwkJCQlkZWZhdWx0OgorCQkJCWNhc2UgMDoKKwkJCQkJcmNXaW5kb3cuYm90dG9tIC09IGZQb3B1cFJldDsKKwkJCQkJYnJlYWs7CisJCQkJY2FzZSAxOgorCQkJCQlyY1dpbmRvdy50b3AgKz0gZlBvcHVwUmV0OworCQkJCQlicmVhazsKKwkJCQl9CisJCQkJCisJCQkJbV9uUG9wdXBXaGVyZSA9IG5XaGVyZTsKKwkJCQlNb3ZlKHJjV2luZG93LCBUUlVFLCBUUlVFKTsKKwkJCX0KKwkJfQorCX0KKwllbHNlCisJeworCQltX2JQb3B1cCA9IGJQb3B1cDsKKwkJTW92ZShtX3JjT2xkV2luZG93LCBUUlVFLCBUUlVFKTsKKwl9Cit9CisKK0ZYX0JPT0wgQ1BXTF9Db21ib0JveDo6T25LZXlEb3duKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmICghbV9wTGlzdCkgcmV0dXJuIEZBTFNFOworCWlmICghbV9wRWRpdCkgcmV0dXJuIEZBTFNFOworCisJbV9uU2VsZWN0SXRlbSA9IC0xOworCisJc3dpdGNoIChuQ2hhcikKKwl7CisJY2FzZSBGV0xfVktFWV9VcDoKKwkJaWYgKG1fcExpc3QtPkdldEN1clNlbCgpID4gMCkKKwkJeworCQkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOworCQkJaWYgKG1fcExpc3QtPk9uS2V5RG93bihuQ2hhcixiRXhpdCxuRmxhZykpCisJCQl7CisJCQkJaWYgKGJFeGl0KSByZXR1cm4gRkFMU0U7CisJCQkJU2V0U2VsZWN0VGV4dCgpOwkJCQkKKwkJCX0KKwkJfQorCQlyZXR1cm4gVFJVRTsKKwljYXNlIEZXTF9WS0VZX0Rvd246CisJCWlmIChtX3BMaXN0LT5HZXRDdXJTZWwoKSA8IG1fcExpc3QtPkdldENvdW50KCkgLSAxKQorCQl7CisJCQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7CisJCQlpZiAobV9wTGlzdC0+T25LZXlEb3duKG5DaGFyLGJFeGl0LG5GbGFnKSkKKwkJCXsKKwkJCQlpZiAoYkV4aXQpIHJldHVybiBGQUxTRTsKKwkJCQlTZXRTZWxlY3RUZXh0KCk7CQkJCQorCQkJfQorCQl9CisJCXJldHVybiBUUlVFOworCX0KKworCWlmIChIYXNGbGFnKFBDQlNfQUxMT1dDVVNUT01URVhUKSkKKwkJcmV0dXJuIG1fcEVkaXQtPk9uS2V5RG93bihuQ2hhcixuRmxhZyk7CisJZWxzZQorCQlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wgQ1BXTF9Db21ib0JveDo6T25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmICghbV9wTGlzdCkgcmV0dXJuIEZBTFNFOworCWlmICghbV9wRWRpdCkgcmV0dXJuIEZBTFNFOworCisJbV9uU2VsZWN0SXRlbSA9IC0xOworCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsKKworCWlmIChIYXNGbGFnKFBDQlNfQUxMT1dDVVNUT01URVhUKSkKKwl7CisJCXJldHVybiBtX3BFZGl0LT5PbkNoYXIobkNoYXIsbkZsYWcpOwkJCQorCX0KKwllbHNlCisJeworCQlpZiAobV9wTGlzdC0+T25DaGFyKG5DaGFyLGJFeGl0LG5GbGFnKSkKKwkJeworCQkJcmV0dXJuIGJFeGl0OworCQl9CisJCWVsc2UKKwkJCXJldHVybiBGQUxTRTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9Db21ib0JveDo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKK3sKKwlzd2l0Y2ggKG1zZykKKwl7CisJY2FzZSBQTk1fTEJVVFRPTkRPV046CisJCWlmIChwV25kID09IG1fcEJ1dHRvbikKKwkJeworCQkJU2V0UG9wdXAoIW1fYlBvcHVwKTsKKwkJCXJldHVybjsKKwkJfQorCQlicmVhazsKKwljYXNlIFBOTV9MQlVUVE9OVVA6CisJCWlmIChtX3BFZGl0ICYmIG1fcExpc3QpCisJCXsKKwkJCWlmIChwV25kID09IG1fcExpc3QpCisJCQl7CQkJCisJCQkJU2V0U2VsZWN0VGV4dCgpOworCQkJCVNlbGVjdEFsbCgpOworCQkJCW1fcEVkaXQtPlNldEZvY3VzKCk7CisJCQkJU2V0UG9wdXAoRkFMU0UpOworCQkJCXJldHVybjsKKwkJCX0KKwkJfQorCX0KKworCUNQV0xfV25kOjpPbk5vdGlmeShwV25kLG1zZyx3UGFyYW0sbFBhcmFtKTsKK30KKworRlhfQk9PTCBDUFdMX0NvbWJvQm94OjpJc1BvcHVwKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9iUG9wdXA7Cit9CisKK3ZvaWQgQ1BXTF9Db21ib0JveDo6U2V0U2VsZWN0VGV4dCgpCit7CisJQ0ZYX1dpZGVTdHJpbmcgc3dUZXh0ID0gbV9wTGlzdC0+R2V0VGV4dCgpOworCW1fcEVkaXQtPlNlbGVjdEFsbCgpOworCW1fcEVkaXQtPlJlcGxhY2VTZWwobV9wTGlzdC0+R2V0VGV4dCgpKTsKKwltX3BFZGl0LT5TZWxlY3RBbGwoKTsKKworCW1fblNlbGVjdEl0ZW0gPSBtX3BMaXN0LT5HZXRDdXJTZWwoKTsKK30KKworRlhfQk9PTCBDUFdMX0NvbWJvQm94OjpJc01vZGlmaWVkKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wRWRpdC0+SXNNb2RpZmllZCgpOworfQorCit2b2lkIENQV0xfQ29tYm9Cb3g6OlNldEZpbGxlck5vdGlmeShJUFdMX0ZpbGxlcl9Ob3RpZnkqIHBOb3RpZnkpCit7CisJIG1fcEZpbGxlck5vdGlmeSA9IHBOb3RpZnk7CisKKwkgaWYgKG1fcEVkaXQpCisJCSBtX3BFZGl0LT5TZXRGaWxsZXJOb3RpZnkocE5vdGlmeSk7CisKKwkgaWYgKG1fcExpc3QpCisJCSBtX3BMaXN0LT5TZXRGaWxsZXJOb3RpZnkocE5vdGlmeSk7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfRWRpdC5jcHAgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0VkaXQuY3BwCmluZGV4IDg3ZGRkODcuLmRmNTljMmMgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfRWRpdC5jcHAKKysrIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9FZGl0LmNwcApAQCAtMSwxMzE2ICsxLDEzMTYgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0NhcmV0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Gb250TWFwLmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0VkaXQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BXTF9FZGl0OjpDUFdMX0VkaXQoKSA6IG1fcEZpbGxlck5vdGlmeShOVUxMKSwgDQotCW1fcFNwZWxsQ2hlY2soTlVMTCksDQotCW1fYkZvY3VzKEZBTFNFKQ0KLXsNCi0JbV9wRm9ybUZpbGxlciA9IE5VTEw7DQotfQ0KLQ0KLUNQV0xfRWRpdDo6fkNQV0xfRWRpdCgpDQotew0KLQlBU1NFUlQobV9iRm9jdXMgPT0gRkFMU0UpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX0VkaXQ6OkdldENsYXNzTmFtZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gUFdMX0NMQVNTTkFNRV9FRElUOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6T25EZXN0cm95KCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KQ0KLXsNCi0JQ0ZYX1dpZGVTdHJpbmcgc3dUZXh0ID0gY3NUZXh0Ow0KLQ0KLQlpZiAoSGFzRmxhZyhQRVNfUklDSCkpDQotCXsJCQ0KLQkJQ0ZYX0J5dGVTdHJpbmcgc1ZhbHVlID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHN3VGV4dCk7DQotCQkNCi0JCWlmIChDWE1MX0VsZW1lbnQgKiBwWE1MID0gQ1hNTF9FbGVtZW50OjpQYXJzZSgoRlhfTFBDU1RSKXNWYWx1ZSxzVmFsdWUuR2V0TGVuZ3RoKCkpKQ0KLQkJew0KLQkJCUZYX0lOVDMyIG5Db3VudCA9IHBYTUwtPkNvdW50Q2hpbGRyZW4oKTsNCi0JCQlGWF9CT09MIGJGaXJzdCA9IFRSVUU7DQotDQotCQkJc3dUZXh0LkVtcHR5KCk7DQotDQotCQkJZm9yIChGWF9JTlQzMiBpPTA7IGk8bkNvdW50OyBpKyspDQotCQkJew0KLQkJCQlpZiAoQ1hNTF9FbGVtZW50ICogcFN1YkVsZW1lbnQgPSBwWE1MLT5HZXRFbGVtZW50KGkpKQ0KLQkJCQl7DQotCQkJCQlDRlhfQnl0ZVN0cmluZyB0YWc9cFN1YkVsZW1lbnQtPkdldFRhZ05hbWUoKTsNCi0JCSAgIAkJCWlmICh0YWcuRXF1YWxOb0Nhc2UoInAiKSkNCi0JCQkJCXsNCi0JCQkJCQlpbnQgbkNoaWxkID0gcFN1YkVsZW1lbnQtPkNvdW50Q2hpbGRyZW4oKTsNCi0JCQkJCQlDRlhfV2lkZVN0cmluZyBzd1NlY3Rpb247DQotCQkJCQkJZm9yKEZYX0lOVDMyIGo9MDsgajxuQ2hpbGQ7IGorKykNCi0JCQkJCQl7DQotCQkJCQkJCXN3U2VjdGlvbiArPSBwU3ViRWxlbWVudC0+R2V0Q29udGVudChqKTsNCi0JCQkJCQl9DQotCQkJCQkJDQotCQkJCQkJaWYgKGJGaXJzdCliRmlyc3QgPSBGQUxTRTsNCi0JCQkJCQllbHNlDQotCQkJCQkJCXN3VGV4dCArPSBGV0xfVktFWV9SZXR1cm47DQotCQkJCQkJc3dUZXh0ICs9IHN3U2VjdGlvbjsNCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCX0NCi0NCi0JCQlkZWxldGUgcFhNTDsNCi0JCX0NCi0JfQkNCi0NCi0JbV9wRWRpdC0+U2V0VGV4dChzd1RleHQpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6UmVQb3NDaGlsZFduZCgpDQotew0KLQlpZiAoQ1BXTF9TY3JvbGxCYXIgKiBwVlNCID0gdGhpcy0+R2V0VlNjcm9sbEJhcigpKQ0KLQl7DQotCQkvL2lmIChwVlNCLT5Jc1Zpc2libGUoKSkNCi0JCXsNCi0JCQlDUERGX1JlY3QgcmNXaW5kb3cgPSBtX3JjT2xkV2luZG93OwkJDQotCQkJQ1BERl9SZWN0IHJjVlNjcm9sbCA9IENQREZfUmVjdChyY1dpbmRvdy5yaWdodCwNCi0JCQkJCQkJCXJjV2luZG93LmJvdHRvbSwNCi0JCQkJCQkJCXJjV2luZG93LnJpZ2h0ICsgUFdMX1NDUk9MTEJBUl9XSURUSCwNCi0JCQkJCQkJCXJjV2luZG93LnRvcCk7DQotCQkJcFZTQi0+TW92ZShyY1ZTY3JvbGwsIFRSVUUsIEZBTFNFKTsNCi0JCX0NCi0JfQ0KLQ0KLQlpZiAobV9wRWRpdENhcmV0ICYmICFIYXNGbGFnKFBFU19URVhUT1ZFUkZMT1cpKQ0KLQkJbV9wRWRpdENhcmV0LT5TZXRDbGlwUmVjdChDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdChHZXRDbGllbnRSZWN0KCksMS4wZikpOyAvLysxIGZvciBjYXJldCBiZXNpZGUgYm9yZGVyDQotDQotCUNQV0xfRWRpdEN0cmw6OlJlUG9zQ2hpbGRXbmQoKTsNCi19DQotDQotQ1BERl9SZWN0IENQV0xfRWRpdDo6R2V0Q2xpZW50UmVjdCgpIGNvbnN0DQotew0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChHZXRXaW5kb3dSZWN0KCksKEZYX0ZMT0FUKShHZXRCb3JkZXJXaWR0aCgpK0dldElubmVyQm9yZGVyV2lkdGgoKSkpOw0KLQkNCi0JaWYgKENQV0xfU2Nyb2xsQmFyICogcFZTQiA9IHRoaXMtPkdldFZTY3JvbGxCYXIoKSkNCi0Jew0KLQkJaWYgKHBWU0ItPklzVmlzaWJsZSgpKQ0KLQkJew0KLQkJCXJjQ2xpZW50LnJpZ2h0IC09IFBXTF9TQ1JPTExCQVJfV0lEVEg7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIHJjQ2xpZW50Ow0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6U2V0QWxpZ25Gb3JtYXRIKFBXTF9FRElUX0FMSUdORk9STUFUX0ggbkZvcm1hdCwgRlhfQk9PTCBiUGFpbnQvKiA9IFRSVUUqLykNCi17DQotCW1fcEVkaXQtPlNldEFsaWdubWVudEgoKEZYX0lOVDMyKW5Gb3JtYXQsIGJQYWludCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpTZXRBbGlnbkZvcm1hdFYoUFdMX0VESVRfQUxJR05GT1JNQVRfViBuRm9ybWF0LCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQ0KLXsNCi0JbV9wRWRpdC0+U2V0QWxpZ25tZW50VigoRlhfSU5UMzIpbkZvcm1hdCwgYlBhaW50KTsNCi19DQotDQotRlhfQk9PTAlDUFdMX0VkaXQ6OkNhblNlbGVjdEFsbCgpIGNvbnN0DQotew0KLQlyZXR1cm4gIEdldFNlbGVjdFdvcmRSYW5nZSgpICE9IG1fcEVkaXQtPkdldFdob2xlV29yZFJhbmdlKCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9FZGl0OjpDYW5DbGVhcigpIGNvbnN0DQotew0KLQlyZXR1cm4gIUlzUmVhZE9ubHkoKSAmJiBtX3BFZGl0LT5Jc1NlbGVjdGVkKCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9FZGl0OjpDYW5Db3B5KCkgY29uc3QNCi17DQotCXJldHVybiAJIUhhc0ZsYWcoUEVTX1BBU1NXT1JEKSAmJiAhSGFzRmxhZyhQRVNfTk9SRUFEKSAmJiBtX3BFZGl0LT5Jc1NlbGVjdGVkKCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9FZGl0OjpDYW5DdXQoKSBjb25zdA0KLXsNCi0JcmV0dXJuIAlDYW5Db3B5KCkgJiYgIUlzUmVhZE9ubHkoKTsNCi19DQotDQotRlhfQk9PTAlDUFdMX0VkaXQ6OkNhblBhc3RlKCkgY29uc3QNCi17DQotCWlmIChJc1JlYWRPbmx5KCkpIHJldHVybiBGQUxTRTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc3dDbGlwYm9hcmQ7DQotCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQ0KLQkJc3dDbGlwYm9hcmQgPSBwU0gtPkdldENsaXBib2FyZFRleHQoR2V0QXR0YWNoZWRIV25kKCkpOw0KLQ0KLQlyZXR1cm4gIXN3Q2xpcGJvYXJkLklzRW1wdHkoKTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXQ6OkNvcHlUZXh0KCkNCi17DQotCWlmICghQ2FuQ29weSgpKSByZXR1cm47DQotDQotCUNGWF9XaWRlU3RyaW5nIHN0ciA9IG1fcEVkaXQtPkdldFNlbFRleHQoKTsNCi0NCi0JaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpDQotCQlwU0gtPlNldENsaXBib2FyZFRleHQoR2V0QXR0YWNoZWRIV25kKCksIHN0cik7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpQYXN0ZVRleHQoKQ0KLXsNCi0JaWYgKCFDYW5QYXN0ZSgpKSByZXR1cm47DQotDQotCUNGWF9XaWRlU3RyaW5nIHN3Q2xpcGJvYXJkOw0KLQlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkNCi0JCXN3Q2xpcGJvYXJkID0gcFNILT5HZXRDbGlwYm9hcmRUZXh0KEdldEF0dGFjaGVkSFduZCgpKTsNCi0NCi0JaWYgKG1fcEZpbGxlck5vdGlmeSkNCi0Jew0KLQkJRlhfQk9PTCBiUkMgPSBUUlVFOw0KLQkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOw0KLQkJQ0ZYX1dpZGVTdHJpbmcgc3RyQ2hhbmdlRXg7DQotCQlpbnQgblNlbFN0YXJ0ID0gMDsNCi0JCWludCBuU2VsRW5kID0gMDsNCi0JCUdldFNlbChuU2VsU3RhcnQsIG5TZWxFbmQpOw0KLQkJbV9wRmlsbGVyTm90aWZ5LT5PbkJlZm9yZUtleVN0cm9rZShUUlVFLCBHZXRBdHRhY2hlZERhdGEoKSwgMCAsIHN3Q2xpcGJvYXJkLCBzdHJDaGFuZ2VFeCwgblNlbFN0YXJ0LCBuU2VsRW5kLCBUUlVFLCBiUkMsIGJFeGl0LCAwKTsNCi0JCWlmICghYlJDKSByZXR1cm47DQotCQlpZiAoYkV4aXQpIHJldHVybjsNCi0JfQ0KLQ0KLQlpZiAoc3dDbGlwYm9hcmQuR2V0TGVuZ3RoKCkgPiAwKQ0KLQl7DQotCQlDbGVhcigpOw0KLQkJSW5zZXJ0VGV4dChzd0NsaXBib2FyZCk7DQotCX0NCi0NCi0JaWYgKG1fcEZpbGxlck5vdGlmeSkNCi0Jew0KLQkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOw0KLQkJbV9wRmlsbGVyTm90aWZ5LT5PbkFmdGVyS2V5U3Ryb2tlKFRSVUUsIEdldEF0dGFjaGVkRGF0YSgpLCBiRXhpdCwwKTsNCi0JCWlmIChiRXhpdCkgcmV0dXJuOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpDdXRUZXh0KCkNCi17DQotCWlmICghQ2FuQ3V0KCkpIHJldHVybjsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc3RyID0gbV9wRWRpdC0+R2V0U2VsVGV4dCgpOw0KLQ0KLQlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkNCi0JCXBTSC0+U2V0Q2xpcGJvYXJkVGV4dChHZXRBdHRhY2hlZEhXbmQoKSwgc3RyKTsNCi0NCi0JbV9wRWRpdC0+Q2xlYXIoKTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXQ6Ok9uQ3JlYXRlZCgpDQotew0KLQlDUFdMX0VkaXRDdHJsOjpPbkNyZWF0ZWQoKTsNCi0NCi0JaWYgKENQV0xfU2Nyb2xsQmFyICogcFNjcm9sbCA9IEdldFZTY3JvbGxCYXIoKSkNCi0Jew0KLQkJcFNjcm9sbC0+UmVtb3ZlRmxhZyhQV1NfQVVUT1RSQU5TUEFSRU5UKTsNCi0JCXBTY3JvbGwtPlNldFRyYW5zcGFyZW5jeSgyNTUpOw0KLQl9DQotDQotCVNldFBhcmFtQnlGbGFnKCk7DQotDQotCW1fcmNPbGRXaW5kb3cgPSBHZXRXaW5kb3dSZWN0KCk7DQotDQotCW1fcEVkaXQtPlNldE9wck5vdGlmeSh0aGlzKTsNCi0JbV9wRWRpdC0+RW5hYmxlT3ByTm90aWZ5KFRSVUUpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6U2V0UGFyYW1CeUZsYWcoKQ0KLXsJDQotCWlmIChIYXNGbGFnKFBFU19SSUdIVCkpDQotCXsNCi0JCW1fcEVkaXQtPlNldEFsaWdubWVudEgoMiwgRkFMU0UpOw0KLQl9DQotCWVsc2UgaWYgKEhhc0ZsYWcoUEVTX01JRERMRSkpDQotCXsNCi0JCW1fcEVkaXQtPlNldEFsaWdubWVudEgoMSwgRkFMU0UpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJbV9wRWRpdC0+U2V0QWxpZ25tZW50SCgwLCBGQUxTRSk7DQotCX0NCi0NCi0JaWYgKEhhc0ZsYWcoUEVTX0JPVFRPTSkpDQotCXsNCi0JCW1fcEVkaXQtPlNldEFsaWdubWVudFYoMiwgRkFMU0UpOw0KLQl9DQotCWVsc2UgaWYgKEhhc0ZsYWcoUEVTX0NFTlRFUikpDQotCXsNCi0JCW1fcEVkaXQtPlNldEFsaWdubWVudFYoMSwgRkFMU0UpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJbV9wRWRpdC0+U2V0QWxpZ25tZW50VigwLCBGQUxTRSk7DQotCX0NCi0NCi0JaWYgKEhhc0ZsYWcoUEVTX1BBU1NXT1JEKSkNCi0Jew0KLQkJbV9wRWRpdC0+U2V0UGFzc3dvcmRDaGFyKCcqJywgRkFMU0UpOw0KLQl9DQotDQotCW1fcEVkaXQtPlNldE11bHRpTGluZShIYXNGbGFnKFBFU19NVUxUSUxJTkUpLCBGQUxTRSk7DQotCW1fcEVkaXQtPlNldEF1dG9SZXR1cm4oSGFzRmxhZyhQRVNfQVVUT1JFVFVSTiksIEZBTFNFKTsNCi0JbV9wRWRpdC0+U2V0QXV0b0ZvbnRTaXplKEhhc0ZsYWcoUFdTX0FVVE9GT05UU0laRSksIEZBTFNFKTsNCi0JbV9wRWRpdC0+U2V0QXV0b1Njcm9sbChIYXNGbGFnKFBFU19BVVRPU0NST0xMKSwgRkFMU0UpOw0KLQltX3BFZGl0LT5FbmFibGVVbmRvKEhhc0ZsYWcoUEVTX1VORE8pKTsNCi0NCi0JaWYgKEhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykpDQotCXsNCi0JCVNldENsaXBSZWN0KENQREZfUmVjdCgwLjBmLDAuMGYsMC4wZiwwLjBmKSk7DQotCQltX3BFZGl0LT5TZXRUZXh0T3ZlcmZsb3coVFJVRSwgRkFMU0UpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKG1fcEVkaXRDYXJldCkNCi0JCXsNCi0JCQltX3BFZGl0Q2FyZXQtPlNldENsaXBSZWN0KENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KEdldENsaWVudFJlY3QoKSwxLjBmKSk7IC8vKzEgZm9yIGNhcmV0IGJlc2lkZSBib3JkZXINCi0JCX0NCi0JfQ0KLQ0KLQlpZiAoSGFzRmxhZyhQRVNfU1BFTExDSEVDSykpDQotCXsNCi0JCW1fcFNwZWxsQ2hlY2sgPSBHZXRDcmVhdGlvblBhcmFtKCkucFNwZWxsQ2hlY2s7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0VkaXQ6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pDQotew0KLQlDUFdMX1duZDo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oc0FwcFN0cmVhbSk7DQotDQotCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNMaW5lOw0KLQ0KLQlGWF9JTlQzMiBuQ2hhckFycmF5ID0gbV9wRWRpdC0+R2V0Q2hhckFycmF5KCk7DQotDQotCWlmIChuQ2hhckFycmF5ID4gMCkNCi0Jew0KLQkJc3dpdGNoIChHZXRCb3JkZXJTdHlsZSgpKQ0KLQkJew0KLQkJY2FzZSBQQlNfU09MSUQ6DQotCQkJew0KLQkJCQlzTGluZSA8PCAicVxuIiA8PCBHZXRCb3JkZXJXaWR0aCgpIDw8ICIgd1xuIiANCi0JCQkJCTw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldEJvcmRlckNvbG9yKCksRkFMU0UpIDw8ICIgMiBKIDAgalxuIjsJCQkJCQ0KLQ0KLQkJCQlmb3IgKEZYX0lOVDMyIGk9MTtpPG5DaGFyQXJyYXk7aSsrKQ0KLQkJCQl7DQotCQkJCQlzTGluZSA8PCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25DaGFyQXJyYXkpKmkgPDwgIiAiDQotCQkJCQkJPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgbVxuIg0KLQkJCQkJCTw8IHJjQ2xpZW50LmxlZnQgKyAoKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCkvbkNoYXJBcnJheSkqaSA8PCAiICINCi0JCQkJCQk8PCByY0NsaWVudC50b3AgPDwgIiBsIFNcbiI7CQkJCQkJDQotCQkJCX0NCi0NCi0JCQkJc0xpbmUgPDwgIlFcbiI7CQkJCQkNCi0JCQl9DQotCQkJYnJlYWs7IA0KLQkJY2FzZSBQQlNfREFTSDoNCi0JCQl7DQotCQkJCXNMaW5lIDw8ICJxXG4iIDw8IEdldEJvcmRlcldpZHRoKCkgPDwgIiB3XG4iIA0KLQkJCQkJPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oR2V0Qm9yZGVyQ29sb3IoKSxGQUxTRSkgPDwgIiAyIEogMCBqXG4iDQotCQkJCQk8PCAiWyIgPDwgR2V0Qm9yZGVyRGFzaCgpLm5EYXNoIDw8ICIgIiANCi0JCQkJCTw8IEdldEJvcmRlckRhc2goKS5uR2FwIDw8ICJdICIgDQotCQkJCQk8PCBHZXRCb3JkZXJEYXNoKCkublBoYXNlIDw8ICIgZFxuIjsNCi0NCi0JCQkJZm9yIChGWF9JTlQzMiBpPTE7aTxuQ2hhckFycmF5O2krKykJCQkJCQ0KLQkJCQl7DQotCQkJCQlzTGluZSA8PCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25DaGFyQXJyYXkpKmkgPDwgIiAiDQotCQkJCQkJPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgbVxuIg0KLQkJCQkJCTw8IHJjQ2xpZW50LmxlZnQgKyAoKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCkvbkNoYXJBcnJheSkqaSA8PCAiICINCi0JCQkJCQk8PCByY0NsaWVudC50b3AgPDwgIiBsIFNcbiI7CQ0KLQkJCQl9DQotDQotCQkJCXNMaW5lIDw8ICJRXG4iOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCX0JCQ0KLQl9DQotDQotCXNBcHBTdHJlYW0gPDwgc0xpbmU7DQotDQotCUNGWF9CeXRlVGV4dEJ1ZiBzVGV4dDsNCi0NCi0JQ1BERl9Qb2ludCBwdE9mZnNldCA9IENQREZfUG9pbnQoMC4wZiwwLjBmKTsNCi0NCi0JQ1BWVF9Xb3JkUmFuZ2Ugd3JXaG9sZSA9IG1fcEVkaXQtPkdldFdob2xlV29yZFJhbmdlKCk7DQotCUNQVlRfV29yZFJhbmdlIHdyU2VsZWN0ID0gR2V0U2VsZWN0V29yZFJhbmdlKCk7DQotCUNQVlRfV29yZFJhbmdlIHdyVmlzaWJsZSA9IChIYXNGbGFnKFBFU19URVhUT1ZFUkZMT1cpID8gd3JXaG9sZSA6IG1fcEVkaXQtPkdldFZpc2libGVXb3JkUmFuZ2UoKSk7DQotCUNQVlRfV29yZFJhbmdlIHdyU2VsQmVmb3JlKHdyV2hvbGUuQmVnaW5Qb3Msd3JTZWxlY3QuQmVnaW5Qb3MpOw0KLQlDUFZUX1dvcmRSYW5nZSB3clNlbEFmdGVyKHdyU2VsZWN0LkVuZFBvcyx3cldob2xlLkVuZFBvcyk7DQotDQotCUNQVlRfV29yZFJhbmdlIHdyVGVtcCA9IENQV0xfVXRpbHM6Ok92ZXJsYXBXb3JkUmFuZ2UoR2V0U2VsZWN0V29yZFJhbmdlKCksd3JWaXNpYmxlKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc0VkaXRTZWwgPSBDUFdMX1V0aWxzOjpHZXRFZGl0U2VsQXBwU3RyZWFtKG1fcEVkaXQsIHB0T2Zmc2V0LA0KLQkJCSZ3clRlbXApOw0KLQ0KLQlpZiAoc0VkaXRTZWwuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJc1RleHQgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oUFdMX0RFRkFVTFRfU0VMQkFDS0NPTE9SKSA8PCBzRWRpdFNlbCA7DQotDQotCXdyVGVtcCA9IENQV0xfVXRpbHM6Ok92ZXJsYXBXb3JkUmFuZ2Uod3JWaXNpYmxlLHdyU2VsQmVmb3JlKTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc0VkaXRCZWZvcmUgPSBDUFdMX1V0aWxzOjpHZXRFZGl0QXBwU3RyZWFtKG1fcEVkaXQsIHB0T2Zmc2V0LCAgDQotCQkJJndyVGVtcCwgIUhhc0ZsYWcoUEVTX0NIQVJBUlJBWSksIG1fcEVkaXQtPkdldFBhc3N3b3JkQ2hhcigpKTsJCQkNCi0NCi0JaWYgKHNFZGl0QmVmb3JlLkdldExlbmd0aCgpID4gMCkNCi0JCXNUZXh0IDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShHZXRUZXh0Q29sb3IoKSkgPDwgc0VkaXRCZWZvcmUgPDwgIkVUXG4iOw0KLQ0KLQl3clRlbXAgPSBDUFdMX1V0aWxzOjpPdmVybGFwV29yZFJhbmdlKHdyVmlzaWJsZSx3clNlbGVjdCk7DQotCUNGWF9CeXRlU3RyaW5nIHNFZGl0TWlkID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShtX3BFZGl0LCBwdE9mZnNldCwgDQotCQkJJndyVGVtcCwgIUhhc0ZsYWcoUEVTX0NIQVJBUlJBWSksIG1fcEVkaXQtPkdldFBhc3N3b3JkQ2hhcigpKTsJCQkNCi0NCi0JaWYgKHNFZGl0TWlkLkdldExlbmd0aCgpID4gMCkNCi0JCXNUZXh0IDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpKSA8PCBzRWRpdE1pZCA8PCAiRVRcbiI7DQotDQotCXdyVGVtcCA9IENQV0xfVXRpbHM6Ok92ZXJsYXBXb3JkUmFuZ2Uod3JWaXNpYmxlLHdyU2VsQWZ0ZXIpOw0KLQlDRlhfQnl0ZVN0cmluZyBzRWRpdEFmdGVyID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShtX3BFZGl0LCBwdE9mZnNldCwgDQotCQkJJndyVGVtcCwgIUhhc0ZsYWcoUEVTX0NIQVJBUlJBWSksIG1fcEVkaXQtPkdldFBhc3N3b3JkQ2hhcigpKTsJCQkNCi0NCi0JaWYgKHNFZGl0QWZ0ZXIuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJc1RleHQgPDwgIkJUXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldFRleHRDb2xvcigpKSA8PCBzRWRpdEFmdGVyPDwgIkVUXG4iOw0KLQ0KLQlpZiAoSGFzRmxhZyhQRVNfU1BFTExDSEVDSykpDQotCXsNCi0JCUNGWF9CeXRlU3RyaW5nIHNTcGVsbENoZWNrID0gQ1BXTF9VdGlsczo6R2V0U3BlbGxDaGVja0FwcFN0cmVhbShtX3BFZGl0LCBtX3BTcGVsbENoZWNrLCBwdE9mZnNldCwgJndyVmlzaWJsZSk7DQotCQlpZiAoc1NwZWxsQ2hlY2suR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCXNUZXh0IDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwxLDAsMCksRkFMU0UpIDw8IHNTcGVsbENoZWNrOw0KLQl9DQotDQotCWlmIChzVGV4dC5HZXRMZW5ndGgoKSA+IDApDQotCXsNCi0JCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsNCi0JCXNBcHBTdHJlYW0gPDwgInFcbi9UeCBCTUNcbiI7DQotCQkNCi0JCWlmICghSGFzRmxhZyhQRVNfVEVYVE9WRVJGTE9XKSkNCi0JCQlzQXBwU3RyZWFtIDw8IHJjQ2xpZW50LmxlZnQgPDwgIiAiIDw8IHJjQ2xpZW50LmJvdHRvbSA8PCAiICINCi0JCQkJPDwgcmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0IDw8ICIgIiA8PCByY0NsaWVudC50b3AgLSByY0NsaWVudC5ib3R0b20gPDwgIiByZSBXIG5cbiI7DQotDQotCQlzQXBwU3RyZWFtIDw8IHNUZXh0Ow0KLQ0KLQkJc0FwcFN0cmVhbSA8PCAiRU1DXG5RXG4iOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkNCi17DQotCUNQV0xfV25kOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSxwVXNlcjJEZXZpY2UpOw0KLQ0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotCUNGWF9CeXRlVGV4dEJ1ZiBzTGluZTsNCi0NCi0JRlhfSU5UMzIgbkNoYXJBcnJheSA9IG1fcEVkaXQtPkdldENoYXJBcnJheSgpOw0KLQ0KLQlpZiAobkNoYXJBcnJheSA+IDApDQotCXsNCi0JCXN3aXRjaCAoR2V0Qm9yZGVyU3R5bGUoKSkNCi0JCXsNCi0JCWNhc2UgUEJTX1NPTElEOg0KLQkJCXsNCi0JCQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JCQkJZ3NkLm1fTGluZVdpZHRoID0gKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCk7DQotDQotCQkJCUNGWF9QYXRoRGF0YSBwYXRoOw0KLQkJCQlwYXRoLlNldFBvaW50Q291bnQoKG5DaGFyQXJyYXktMSkqMik7DQotCQkJCQ0KLQkJCQlmb3IgKEZYX0lOVDMyIGk9MDsgaTxuQ2hhckFycmF5LTE7IGkrKykNCi0JCQkJewkJCQkJDQotCQkJCQlwYXRoLlNldFBvaW50KGkqMiwgcmNDbGllbnQubGVmdCArICgocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0KS9uQ2hhckFycmF5KSooaSsxKSwgDQotCQkJCQkJcmNDbGllbnQuYm90dG9tLCBGWFBUX01PVkVUTyk7DQotCQkJCQlwYXRoLlNldFBvaW50KGkqMisxLCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25DaGFyQXJyYXkpKihpKzEpLA0KLQkJCQkJCXJjQ2xpZW50LnRvcCwgRlhQVF9MSU5FVE8pOwkJCQkJCQkJCQkJDQotCQkJCX0JCQkNCi0JCQkJaWYgKHBhdGguR2V0UG9pbnRDb3VudCgpID4gMCkNCi0JCQkJCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoLCBwVXNlcjJEZXZpY2UsICZnc2QsMCwgIA0KLQkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldEJvcmRlckNvbG9yKCksMjU1KSwgRlhGSUxMX0FMVEVSTkFURSk7DQotCQkJfQ0KLQkJCWJyZWFrOyANCi0JCWNhc2UgUEJTX0RBU0g6DQotCQkJew0KLQkJCQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOw0KLQkJCQlnc2QubV9MaW5lV2lkdGggPSAoRlhfRkxPQVQpR2V0Qm9yZGVyV2lkdGgoKTsNCi0NCi0JCQkJZ3NkLlNldERhc2hDb3VudCgyKTsNCi0JCQkJZ3NkLm1fRGFzaEFycmF5WzBdID0gKEZYX0ZMT0FUKUdldEJvcmRlckRhc2goKS5uRGFzaDsNCi0JCQkJZ3NkLm1fRGFzaEFycmF5WzFdID0gKEZYX0ZMT0FUKUdldEJvcmRlckRhc2goKS5uR2FwOw0KLQkJCQlnc2QubV9EYXNoUGhhc2UgPSAoRlhfRkxPQVQpR2V0Qm9yZGVyRGFzaCgpLm5QaGFzZTsNCi0NCi0JCQkJQ0ZYX1BhdGhEYXRhIHBhdGg7DQotCQkJCXBhdGguU2V0UG9pbnRDb3VudCgobkNoYXJBcnJheS0xKSoyKTsNCi0JCQkJDQotCQkJCWZvciAoRlhfSU5UMzIgaT0wOyBpPG5DaGFyQXJyYXktMTsgaSsrKQ0KLQkJCQl7CQkJCQkNCi0JCQkJCXBhdGguU2V0UG9pbnQoaSoyLCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25DaGFyQXJyYXkpKihpKzEpLCANCi0JCQkJCQlyY0NsaWVudC5ib3R0b20sIEZYUFRfTU9WRVRPKTsNCi0JCQkJCXBhdGguU2V0UG9pbnQoaSoyKzEsIHJjQ2xpZW50LmxlZnQgKyAoKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCkvbkNoYXJBcnJheSkqKGkrMSksDQotCQkJCQkJcmNDbGllbnQudG9wLCBGWFBUX0xJTkVUTyk7CQkJCQkJCQkJCQkNCi0JCQkJfQkJDQotCQkJCWlmIChwYXRoLkdldFBvaW50Q291bnQoKSA+IDApDQotCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLDAsICANCi0JCQkJCQlDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRCb3JkZXJDb2xvcigpLDI1NSksIEZYRklMTF9BTFRFUk5BVEUpOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCX0JCQ0KLQl9DQotDQotCUNQREZfUmVjdCByY0NsaXA7DQotCUNQVlRfV29yZFJhbmdlIHdyUmFuZ2UgPSBtX3BFZGl0LT5HZXRWaXNpYmxlV29yZFJhbmdlKCk7DQotCUNQVlRfV29yZFJhbmdlKiBwUmFuZ2UgPSBOVUxMOw0KLQ0KLQlpZiAoIUhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykpDQotCXsNCi0JCXJjQ2xpcCA9IEdldENsaWVudFJlY3QoKTsNCi0JCXBSYW5nZSA9ICZ3clJhbmdlOw0KLQl9DQotSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXNIYW5kbGVyID0gR2V0U3lzdGVtSGFuZGxlcigpOw0KLQlJRlhfRWRpdDo6RHJhd0VkaXQocERldmljZSxwVXNlcjJEZXZpY2UsbV9wRWRpdCwNCi0JCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSwNCi0JCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRTdHJva2VDb2xvcigpLHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSwNCi0JCXJjQ2xpcCxDUERGX1BvaW50KDAuMGYsMC4wZikscFJhbmdlLCBwU3lzSGFuZGxlciwgbV9wRm9ybUZpbGxlcik7DQotDQotCWlmIChIYXNGbGFnKFBFU19TUEVMTENIRUNLKSkNCi0Jew0KLQkJQ1BXTF9VdGlsczo6RHJhd0VkaXRTcGVsbENoZWNrKHBEZXZpY2UscFVzZXIyRGV2aWNlLG1fcEVkaXQscmNDbGlwLA0KLQkJCUNQREZfUG9pbnQoMC4wZiwwLjBmKSxwUmFuZ2UsIHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKS5wU3BlbGxDaGVjayk7DQotCX0NCi19DQotDQotRlhfQk9PTCBDUFdMX0VkaXQ6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKTsNCi0NCi0JaWYgKEhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykgfHwgQ2xpZW50SGl0VGVzdChwb2ludCkpDQotCXsNCi0JCWlmIChtX2JNb3VzZURvd24pDQotCQkJdGhpcy0+SW52YWxpZGF0ZVJlY3QoKTsNCi0NCi0JCW1fYk1vdXNlRG93biA9IFRSVUU7CQkNCi0JCVNldENhcHR1cmUoKTsNCi0NCi0JCW1fcEVkaXQtPk9uTW91c2VEb3duKHBvaW50LElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9FZGl0OjpPbkxCdXR0b25EYmxDbGsoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbkxCdXR0b25EYmxDbGsocG9pbnQsIG5GbGFnKTsNCi0NCi0JaWYgKEhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykgfHwgQ2xpZW50SGl0VGVzdChwb2ludCkpDQotCXsNCi0JCW1fcEVkaXQtPlNlbGVjdEFsbCgpOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi0jZGVmaW5lIFdNX1BXTEVESVRfVU5ETwkJCQkJMHgwMQ0KLSNkZWZpbmUgV01fUFdMRURJVF9SRURPCQkJCQkweDAyDQotI2RlZmluZSBXTV9QV0xFRElUX0NVVAkJCQkJMHgwMw0KLSNkZWZpbmUgV01fUFdMRURJVF9DT1BZCQkJCQkweDA0DQotI2RlZmluZSBXTV9QV0xFRElUX1BBU1RFCQkJCTB4MDUNCi0jZGVmaW5lIFdNX1BXTEVESVRfREVMRVRFCQkJCTB4MDYNCi0jZGVmaW5lIFdNX1BXTEVESVRfU0VMRUNUQUxMCQkJMHgwNw0KLSNkZWZpbmUgV01fUFdMRURJVF9TVUdHRVNUCQkJCTB4MDgNCi0NCi1GWF9CT09MIENQV0xfRWRpdDo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCWlmIChtX2JNb3VzZURvd24pIHJldHVybiBGQUxTRTsNCi0NCi0JQ1BXTF9XbmQ6Ok9uUkJ1dHRvblVwKHBvaW50LCBuRmxhZyk7DQotCQ0KLQlpZiAoIUhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykgJiYgIUNsaWVudEhpdFRlc3QocG9pbnQpKSByZXR1cm4gVFJVRTsNCi0NCi0JSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKTsNCi0JaWYgKCFwU0gpIHJldHVybiBGQUxTRTsNCi0NCi0JdGhpcy0+U2V0Rm9jdXMoKTsNCi0NCi0JQ1BWVF9Xb3JkUmFuZ2Ugd3JMYXRpbiA9IEdldExhdGluV29yZHNSYW5nZShwb2ludCk7DQotCUNGWF9XaWRlU3RyaW5nIHN3TGF0aW4gPSBtX3BFZGl0LT5HZXRSYW5nZVRleHQod3JMYXRpbik7DQotDQotCUZYX0hNRU5VIGhQb3B1cCA9IHBTSC0+Q3JlYXRlUG9wdXBNZW51KCk7DQotCWlmICghaFBvcHVwKSByZXR1cm4gRkFMU0U7DQotDQotCUNGWF9CeXRlU3RyaW5nQXJyYXkgc1N1Z2dlc3RXb3JkczsNCi0JQ1BERl9Qb2ludCBwdFBvcHVwID0gcG9pbnQ7DQotDQotCWlmICghSXNSZWFkT25seSgpKQ0KLQl7DQotCQlpZiAoSGFzRmxhZyhQRVNfU1BFTExDSEVDSykgJiYgIXN3TGF0aW4uSXNFbXB0eSgpKQ0KLQkJew0KLQkJCWlmIChtX3BTcGVsbENoZWNrKQ0KLQkJCXsNCi0JCQkJQ0ZYX0J5dGVTdHJpbmcgc0xhdGluID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHN3TGF0aW4pOw0KLQ0KLQkJCQlpZiAoIW1fcFNwZWxsQ2hlY2stPkNoZWNrV29yZChzTGF0aW4pKQ0KLQkJCQl7CQkJCQkJDQotCQkJCQltX3BTcGVsbENoZWNrLT5TdWdnZXN0V29yZHMoc0xhdGluLHNTdWdnZXN0V29yZHMpOw0KLQ0KLQkJCQkJRlhfSU5UMzIgblN1Z2dlc3QgPSBzU3VnZ2VzdFdvcmRzLkdldFNpemUoKTsNCi0NCi0JCQkJCWZvciAoRlhfSU5UMzIgbldvcmQ9MDsgbldvcmQ8blN1Z2dlc3Q7IG5Xb3JkKyspDQotCQkJCQl7CQ0KLQkJCQkJCXBTSC0+QXBwZW5kTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX1NVR0dFU1QrbldvcmQsIHNTdWdnZXN0V29yZHNbbldvcmRdLlVURjhEZWNvZGUoKSk7DQotCQkJCQl9DQotDQotCQkJCQlpZiAoblN1Z2dlc3QgPiAwKQ0KLQkJCQkJCXBTSC0+QXBwZW5kTWVudUl0ZW0oaFBvcHVwLCAwLCBMIiIpOw0KLQ0KLQkJCQkJcHRQb3B1cCA9IEdldFdvcmRSaWdodEJvdHRvbVBvaW50KHdyTGF0aW4uRW5kUG9zKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlJUFdMX1Byb3ZpZGVyKiBwUHJvdmlkZXIgPSB0aGlzLT5HZXRQcm92aWRlcigpOw0KLQ0KLQlpZiAoSGFzRmxhZyhQRVNfVU5ETykpDQotCXsNCi0JCXBTSC0+QXBwZW5kTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX1VORE8sIA0KLQkJCXBQcm92aWRlciA/IHBQcm92aWRlci0+TG9hZFBvcHVwTWVudVN0cmluZygwKSA6IEwiJlVuZG8iKTsNCi0JCXBTSC0+QXBwZW5kTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX1JFRE8sDQotCQkJcFByb3ZpZGVyID8gcFByb3ZpZGVyLT5Mb2FkUG9wdXBNZW51U3RyaW5nKDEpIDogTCImUmVkbyIpOw0KLQkJcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIDAsIEwiIik7DQotDQotCQlpZiAoIW1fcEVkaXQtPkNhblVuZG8oKSkNCi0JCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9VTkRPLCBGQUxTRSk7DQotCQlpZiAoIW1fcEVkaXQtPkNhblJlZG8oKSkNCi0JCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9SRURPLCBGQUxTRSk7DQotCX0NCi0NCi0JcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfQ1VULCANCi0JCXBQcm92aWRlciA/IHBQcm92aWRlci0+TG9hZFBvcHVwTWVudVN0cmluZygyKSA6IEwiQ3UmdCIpOw0KLQlwU0gtPkFwcGVuZE1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9DT1BZLCANCi0JCXBQcm92aWRlciA/IHBQcm92aWRlci0+TG9hZFBvcHVwTWVudVN0cmluZygzKSA6IEwiJkNvcHkiKTsNCi0JcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfUEFTVEUsIA0KLQkJcFByb3ZpZGVyID8gcFByb3ZpZGVyLT5Mb2FkUG9wdXBNZW51U3RyaW5nKDQpIDogTCImUGFzdGUiKTsNCi0JcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfREVMRVRFLCANCi0JCXBQcm92aWRlciA/IHBQcm92aWRlci0+TG9hZFBvcHVwTWVudVN0cmluZyg1KSA6IEwiJkRlbGV0ZSIpOw0KLQ0KLQlDRlhfV2lkZVN0cmluZyBzd1RleHQgPSBwU0gtPkdldENsaXBib2FyZFRleHQodGhpcy0+R2V0QXR0YWNoZWRIV25kKCkpOw0KLQlpZiAoc3dUZXh0LklzRW1wdHkoKSkNCi0JCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX1BBU1RFLCBGQUxTRSk7DQotDQotCWlmICghbV9wRWRpdC0+SXNTZWxlY3RlZCgpKQ0KLQl7DQotCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9DVVQsIEZBTFNFKTsNCi0JCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NPUFksIEZBTFNFKTsNCi0JCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0RFTEVURSwgRkFMU0UpOw0KLQl9DQotDQotCWlmIChJc1JlYWRPbmx5KCkpDQotCXsNCi0JCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NVVCwgRkFMU0UpOw0KLQkJcFNILT5FbmFibGVNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfREVMRVRFLCBGQUxTRSk7DQotCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9QQVNURSwgRkFMU0UpOwkJCQ0KLQl9DQotDQotCWlmIChIYXNGbGFnKFBFU19QQVNTV09SRCkpDQotCXsNCi0JCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NVVCwgRkFMU0UpOw0KLQkJcFNILT5FbmFibGVNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfQ09QWSwgRkFMU0UpOw0KLQl9DQotDQotCWlmIChIYXNGbGFnKFBFU19OT1JFQUQpKQ0KLQl7DQotCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9DVVQsIEZBTFNFKTsNCi0JCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NPUFksIEZBTFNFKTsNCi0JfQ0KLQ0KLQlwU0gtPkFwcGVuZE1lbnVJdGVtKGhQb3B1cCwgMCwgTCIiKTsNCi0JcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfU0VMRUNUQUxMLA0KLQkJcFByb3ZpZGVyID8gcFByb3ZpZGVyLT5Mb2FkUG9wdXBNZW51U3RyaW5nKDYpIDogTCImU2VsZWN0IEFsbCIpOw0KLQ0KLQlpZiAobV9wRWRpdC0+R2V0VG90YWxXb3JkcygpID09IDApDQotCXsNCi0JCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX1NFTEVDVEFMTCwgRkFMU0UpOw0KLQl9DQotDQotCUZYX0lOVDMyIHgsIHk7DQotCVBXTHRvV25kKHB0UG9wdXAsIHgsIHkpOw0KLQlwU0gtPkNsaWVudFRvU2NyZWVuKEdldEF0dGFjaGVkSFduZCgpLCB4LCB5KTsNCi0JcFNILT5TZXRDdXJzb3IoRlhDVF9BUlJPVyk7DQotCUZYX0lOVDMyIG5DbWQgPSBwU0gtPlRyYWNrUG9wdXBNZW51KGhQb3B1cCwNCi0JCQkJCSB4LA0KLQkJCQkJIHksDQotCQkJCQkgR2V0QXR0YWNoZWRIV25kKCkpOw0KLQ0KLQ0KLQlzd2l0Y2ggKG5DbWQpDQotCXsNCi0JY2FzZSBXTV9QV0xFRElUX1VORE86DQotCQlVbmRvKCk7DQotCQlicmVhazsNCi0JY2FzZSBXTV9QV0xFRElUX1JFRE86DQotCQlSZWRvKCk7DQotCQlicmVhazsNCi0JY2FzZSBXTV9QV0xFRElUX0NVVDoNCi0JCXRoaXMtPkN1dFRleHQoKTsNCi0JCWJyZWFrOw0KLQljYXNlIFdNX1BXTEVESVRfQ09QWToNCi0JCXRoaXMtPkNvcHlUZXh0KCk7DQotCQlicmVhazsNCi0JY2FzZSBXTV9QV0xFRElUX1BBU1RFOg0KLQkJdGhpcy0+UGFzdGVUZXh0KCk7DQotCQlicmVhazsNCi0JY2FzZSBXTV9QV0xFRElUX0RFTEVURToNCi0JCXRoaXMtPkNsZWFyKCk7DQotCQlicmVhazsNCi0JY2FzZSBXTV9QV0xFRElUX1NFTEVDVEFMTDoNCi0JCXRoaXMtPlNlbGVjdEFsbCgpOw0KLQkJYnJlYWs7DQotCWNhc2UgV01fUFdMRURJVF9TVUdHRVNUICsgMDoNCi0JCVNldFNlbChtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkJlZ2luUG9zKSxtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkVuZFBvcykpOw0KLQkJUmVwbGFjZVNlbChzU3VnZ2VzdFdvcmRzWzBdLlVURjhEZWNvZGUoKSk7DQotCQlicmVhazsNCi0JY2FzZSBXTV9QV0xFRElUX1NVR0dFU1QgKyAxOg0KLQkJU2V0U2VsKG1fcEVkaXQtPldvcmRQbGFjZVRvV29yZEluZGV4KHdyTGF0aW4uQmVnaW5Qb3MpLG1fcEVkaXQtPldvcmRQbGFjZVRvV29yZEluZGV4KHdyTGF0aW4uRW5kUG9zKSk7DQotCQlSZXBsYWNlU2VsKHNTdWdnZXN0V29yZHNbMV0uVVRGOERlY29kZSgpKTsNCi0JCWJyZWFrOw0KLQljYXNlIFdNX1BXTEVESVRfU1VHR0VTVCArIDI6DQotCQlTZXRTZWwobV9wRWRpdC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgod3JMYXRpbi5CZWdpblBvcyksbV9wRWRpdC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgod3JMYXRpbi5FbmRQb3MpKTsNCi0JCVJlcGxhY2VTZWwoc1N1Z2dlc3RXb3Jkc1syXS5VVEY4RGVjb2RlKCkpOw0KLQkJYnJlYWs7DQotCWNhc2UgV01fUFdMRURJVF9TVUdHRVNUICsgMzoNCi0JCVNldFNlbChtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkJlZ2luUG9zKSxtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkVuZFBvcykpOw0KLQkJUmVwbGFjZVNlbChzU3VnZ2VzdFdvcmRzWzNdLlVURjhEZWNvZGUoKSk7DQotCQlicmVhazsNCi0JY2FzZSBXTV9QV0xFRElUX1NVR0dFU1QgKyA0OgkJDQotCQlTZXRTZWwobV9wRWRpdC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgod3JMYXRpbi5CZWdpblBvcyksbV9wRWRpdC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgod3JMYXRpbi5FbmRQb3MpKTsNCi0JCVJlcGxhY2VTZWwoc1N1Z2dlc3RXb3Jkc1s0XS5VVEY4RGVjb2RlKCkpOw0KLQkJYnJlYWs7DQotCWRlZmF1bHQ6DQotCQlicmVhazsNCi0JfQ0KLQ0KLQlwU0gtPkRlc3Ryb3lNZW51KGhQb3B1cCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6T25TZXRGb2N1cygpDQotew0KLQlTZXRFZGl0Q2FyZXQoVFJVRSk7DQotDQotCWlmICghSXNSZWFkT25seSgpKQ0KLQl7DQotCQlpZiAoSVBXTF9Gb2N1c0hhbmRsZXIqIHBGb2N1c0hhbmRsZXIgPSBHZXRGb2N1c0hhbmRsZXIoKSkNCi0JCQlwRm9jdXNIYW5kbGVyLT5PblNldEZvY3VzKHRoaXMpOw0KLQl9DQotDQotCW1fYkZvY3VzID0gVFJVRTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXQ6Ok9uS2lsbEZvY3VzKCkNCi17DQotCVNob3dWU2Nyb2xsQmFyKEZBTFNFKTsNCi0JDQotCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsNCi0JU2V0Q2FyZXQoRkFMU0UsIENQREZfUG9pbnQoMC4wZiwwLjBmKSwgQ1BERl9Qb2ludCgwLjBmLDAuMGYpKTsNCi0JDQotCVNldENoYXJTZXQoMCk7DQotDQotCWlmICghSXNSZWFkT25seSgpKQ0KLQl7DQotCQlpZiAoSVBXTF9Gb2N1c0hhbmRsZXIqIHBGb2N1c0hhbmRsZXIgPSBHZXRGb2N1c0hhbmRsZXIoKSkNCi0JCQlwRm9jdXNIYW5kbGVyLT5PbktpbGxGb2N1cyh0aGlzKTsNCi0JfQ0KLQ0KLQltX2JGb2N1cyA9IEZBTFNFOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6U2V0SG9yelNjYWxlKEZYX0lOVDMyIG5Ib3J6U2NhbGUsIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BFZGl0LT5TZXRIb3J6U2NhbGUobkhvcnpTY2FsZSwgYlBhaW50KTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXQ6OlNldENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlLCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQ0KLXsNCi0JbV9wRWRpdC0+U2V0Q2hhclNwYWNlKGZDaGFyU3BhY2UsIGJQYWludCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpTZXRMaW5lTGVhZGluZyhGWF9GTE9BVCBmTGluZUxlYWRpbmcsIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pDQotew0KLQltX3BFZGl0LT5TZXRMaW5lTGVhZGluZyhmTGluZUxlYWRpbmcsIGJQYWludCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfRWRpdDo6R2V0U2VsZWN0QXBwZWFyYW5jZVN0cmVhbShjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQpIGNvbnN0DQotew0KLQlDUFZUX1dvcmRSYW5nZSB3ciA9IEdldFNlbGVjdFdvcmRSYW5nZSgpOw0KLQlyZXR1cm4gQ1BXTF9VdGlsczo6R2V0RWRpdFNlbEFwcFN0cmVhbShtX3BFZGl0LHB0T2Zmc2V0LCZ3cik7DQotfQ0KLQ0KLUNQVlRfV29yZFJhbmdlIENQV0xfRWRpdDo6R2V0U2VsZWN0V29yZFJhbmdlKCkgY29uc3QNCi17DQotCWlmIChtX3BFZGl0LT5Jc1NlbGVjdGVkKCkpDQotCXsNCi0JCUZYX0lOVDMyIG5TdGFydCA9IC0xOw0KLQkJRlhfSU5UMzIgbkVuZCA9IC0xOw0KLQ0KLQkJbV9wRWRpdC0+R2V0U2VsKG5TdGFydCwgbkVuZCk7DQotDQotCQlDUFZUX1dvcmRQbGFjZSB3cFN0YXJ0ID0gbV9wRWRpdC0+V29yZEluZGV4VG9Xb3JkUGxhY2UoblN0YXJ0KTsNCi0JCUNQVlRfV29yZFBsYWNlIHdwRW5kID0gbV9wRWRpdC0+V29yZEluZGV4VG9Xb3JkUGxhY2UobkVuZCk7DQotDQotCQlyZXR1cm4gQ1BWVF9Xb3JkUmFuZ2Uod3BTdGFydCx3cEVuZCk7DQotCX0NCi0NCi0JcmV0dXJuIENQVlRfV29yZFJhbmdlKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfRWRpdDo6R2V0VGV4dEFwcGVhcmFuY2VTdHJlYW0oY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KSBjb25zdA0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNSZXQ7DQotCUNGWF9CeXRlU3RyaW5nIHNFZGl0ID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShtX3BFZGl0LHB0T2Zmc2V0KTsNCi0JDQotCWlmIChzRWRpdC5HZXRMZW5ndGgoKSA+IDApDQotCXsNCi0JCXNSZXQgPDwgIkJUXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldFRleHRDb2xvcigpKSA8PCBzRWRpdCA8PCAiRVRcbiI7DQotCX0NCi0NCi0JcmV0dXJuIHNSZXQuR2V0Qnl0ZVN0cmluZygpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX0VkaXQ6OkdldENhcmV0QXBwZWFyYW5jZVN0cmVhbShjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQpIGNvbnN0DQotew0KLQlpZiAobV9wRWRpdENhcmV0KQ0KLQkJcmV0dXJuIG1fcEVkaXRDYXJldC0+R2V0Q2FyZXRBcHBlYXJhbmNlU3RyZWFtKHB0T2Zmc2V0KTsNCi0NCi0JcmV0dXJuIENGWF9CeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNQREZfUG9pbnQgQ1BXTF9FZGl0OjpHZXRXb3JkUmlnaHRCb3R0b21Qb2ludChjb25zdCBDUFZUX1dvcmRQbGFjZSYgd3BXb3JkKQ0KLXsNCi0JQ1BERl9Qb2ludCBwdCgwLjBmLCAwLjBmKTsNCi0NCi0JaWYgKElGWF9FZGl0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wRWRpdC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJQ1BWVF9Xb3JkUGxhY2Ugd3BPbGQgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotCQlwSXRlcmF0b3ItPlNldEF0KHdwV29yZCk7DQotCQlDUFZUX1dvcmQgd29yZDsNCi0JCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpDQotCQl7DQotCQkJcHQgPSBDUERGX1BvaW50KHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aCwgd29yZC5wdFdvcmQueSArIHdvcmQuZkRlc2NlbnQpOw0KLQkJfQ0KLQ0KLQkJcEl0ZXJhdG9yLT5TZXRBdCh3cE9sZCk7DQotCX0NCi0NCi0JcmV0dXJuIHB0Ow0KLX0NCi0NCi1GWF9CT09MCUNQV0xfRWRpdDo6SXNUZXh0RnVsbCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wRWRpdC0+SXNUZXh0RnVsbCgpOw0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX0VkaXQ6OkdldENoYXJBcnJheUF1dG9Gb250U2l6ZShDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDUERGX1JlY3QmIHJjUGxhdGUsIEZYX0lOVDMyIG5DaGFyQXJyYXkpDQotew0KLQlpZiAocEZvbnQgJiYgIXBGb250LT5Jc1N0YW5kYXJkRm9udCgpKQ0KLQl7DQotCQlGWF9SRUNUIHJjQkJveDsNCi0JCXBGb250LT5HZXRGb250QkJveChyY0JCb3gpOw0KLQ0KLQkJQ1BERl9SZWN0IHJjQ2VsbCA9IHJjUGxhdGU7DQotCQlGWF9GTE9BVCB4ZGl2ID0gcmNDZWxsLldpZHRoKCkgLyBuQ2hhckFycmF5ICogMTAwMC4wZiAvIHJjQkJveC5XaWR0aCgpOw0KLQkJRlhfRkxPQVQgeWRpdiA9IC0gcmNDZWxsLkhlaWdodCgpICogMTAwMC4wZiAvIHJjQkJveC5IZWlnaHQoKTsNCi0NCi0JCXJldHVybiB4ZGl2IDwgeWRpdiA/IHhkaXYgOiB5ZGl2Ow0KLQl9DQotDQotCXJldHVybiAwLjBmOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6U2V0Q2hhckFycmF5KEZYX0lOVDMyIG5DaGFyQXJyYXkpDQotew0KLQlpZiAoSGFzRmxhZyhQRVNfQ0hBUkFSUkFZKSAmJiBuQ2hhckFycmF5ID4gMCkNCi0Jew0KLQkJbV9wRWRpdC0+U2V0Q2hhckFycmF5KG5DaGFyQXJyYXkpOwkNCi0JCW1fcEVkaXQtPlNldFRleHRPdmVyZmxvdyhUUlVFKTsNCi0NCi0JCWlmIChIYXNGbGFnKFBXU19BVVRPRk9OVFNJWkUpKQ0KLQkJew0KLQkJCWlmIChJRlhfRWRpdF9Gb250TWFwKiBwRm9udE1hcCA9IHRoaXMtPkdldEZvbnRNYXAoKSkNCi0JCQl7DQotCQkJCUZYX0ZMT0FUIGZGb250U2l6ZSA9IEdldENoYXJBcnJheUF1dG9Gb250U2l6ZShwRm9udE1hcC0+R2V0UERGRm9udCgwKSwgR2V0Q2xpZW50UmVjdCgpLCBuQ2hhckFycmF5KTsNCi0JCQkJaWYgKGZGb250U2l6ZSA+IDAuMGYpDQotCQkJCXsNCi0JCQkJCW1fcEVkaXQtPlNldEF1dG9Gb250U2l6ZShGQUxTRSk7DQotCQkJCQltX3BFZGl0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOw0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpTZXRMaW1pdENoYXIoRlhfSU5UMzIgbkxpbWl0Q2hhcikNCi17DQotCW1fcEVkaXQtPlNldExpbWl0Q2hhcihuTGltaXRDaGFyKTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXQ6OlJlcGxhY2VTZWwoRlhfTFBDV1NUUiBjc1RleHQpDQotew0KLQltX3BFZGl0LT5DbGVhcigpOw0KLQltX3BFZGl0LT5JbnNlcnRUZXh0KGNzVGV4dCk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX0VkaXQ6OkdldEZvY3VzUmVjdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gQ1BERl9SZWN0KCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpTaG93VlNjcm9sbEJhcihGWF9CT09MIGJTaG93KQ0KLXsNCi0JaWYgKENQV0xfU2Nyb2xsQmFyICogcFNjcm9sbCA9IEdldFZTY3JvbGxCYXIoKSkNCi0Jew0KLQkJaWYgKGJTaG93KQ0KLQkJew0KLQkJCWlmICghcFNjcm9sbC0+SXNWaXNpYmxlKCkpDQotCQkJew0KLQkJCQlwU2Nyb2xsLT5TZXRWaXNpYmxlKFRSVUUpOw0KLQkJCQlDUERGX1JlY3QgcmNXaW5kb3cgPSBHZXRXaW5kb3dSZWN0KCk7DQotCQkJCW1fcmNPbGRXaW5kb3cgPSByY1dpbmRvdzsNCi0JCQkJcmNXaW5kb3cucmlnaHQgKz0gUFdMX1NDUk9MTEJBUl9XSURUSDsJCQkNCi0JCQkJTW92ZShyY1dpbmRvdywgVFJVRSwgVFJVRSk7DQotCQkJfQ0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCWlmIChwU2Nyb2xsLT5Jc1Zpc2libGUoKSkNCi0JCQl7DQotCQkJCXBTY3JvbGwtPlNldFZpc2libGUoRkFMU0UpOw0KLQkJCQlNb3ZlKG1fcmNPbGRXaW5kb3csIFRSVUUsIFRSVUUpOw0KLQkJCX0JDQotCQl9DQotCX0NCi19DQotDQotRlhfQk9PTAlDUFdMX0VkaXQ6OklzVlNjcm9sbEJhclZpc2libGUoKSBjb25zdA0KLXsNCi0JaWYgKENQV0xfU2Nyb2xsQmFyICogcFNjcm9sbCA9IEdldFZTY3JvbGxCYXIoKSkNCi0Jew0KLQkJcmV0dXJuIHBTY3JvbGwtPklzVmlzaWJsZSgpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXQ6OkVuYWJsZVNwZWxsQ2hlY2soRlhfQk9PTCBiRW5hYmxlZCkNCi17DQotCWlmIChiRW5hYmxlZCkNCi0JCUFkZEZsYWcoUEVTX1NQRUxMQ0hFQ0spOw0KLQllbHNlDQotCQlSZW1vdmVGbGFnKFBFU19TUEVMTENIRUNLKTsNCi19DQotDQotRlhfQk9PTCBDUFdMX0VkaXQ6Ok9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZykNCi17DQotCWlmIChtX2JNb3VzZURvd24pIHJldHVybiBUUlVFOw0KLQ0KLQlpZiAobkNoYXIgPT0gRldMX1ZLRVlfRGVsZXRlKQ0KLQl7DQotCQlpZiAobV9wRmlsbGVyTm90aWZ5KQ0KLQkJew0KLQkJCUZYX0JPT0wgYlJDID0gVFJVRTsNCi0JCQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7DQotCQkJQ0ZYX1dpZGVTdHJpbmcgc3RyQ2hhbmdlOw0KLQkJCUNGWF9XaWRlU3RyaW5nIHN0ckNoYW5nZUV4Ow0KLQ0KLQkJCWludCBuU2VsU3RhcnQgPSAwOw0KLQkJCWludCBuU2VsRW5kID0gMDsNCi0JCQlHZXRTZWwoblNlbFN0YXJ0LCBuU2VsRW5kKTsNCi0NCi0JCQlpZiAoblNlbFN0YXJ0ID09IG5TZWxFbmQpDQotCQkJCW5TZWxFbmQgPSBuU2VsU3RhcnQgKyAxOw0KLQkJCW1fcEZpbGxlck5vdGlmeS0+T25CZWZvcmVLZXlTdHJva2UoVFJVRSwgR2V0QXR0YWNoZWREYXRhKCksIEZXTF9WS0VZX0RlbGV0ZSwgc3RyQ2hhbmdlLCBzdHJDaGFuZ2VFeCwgblNlbFN0YXJ0LCBuU2VsRW5kLCBUUlVFLCBiUkMsIGJFeGl0LCBuRmxhZyk7DQotCQkJaWYgKCFiUkMpIHJldHVybiBGQUxTRTsJCQkJDQotCQkJaWYgKGJFeGl0KSByZXR1cm4gRkFMU0U7DQotCQl9DQotCX0NCi0NCi0JRlhfQk9PTCBiUmV0ID0gQ1BXTF9FZGl0Q3RybDo6T25LZXlEb3duKG5DaGFyLCAgbkZsYWcpOw0KLQ0KLQlpZiAobkNoYXIgPT0gRldMX1ZLRVlfRGVsZXRlKQ0KLQl7DQotCQlpZiAobV9wRmlsbGVyTm90aWZ5KQ0KLQkJew0KLQkJCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsNCi0JCQltX3BGaWxsZXJOb3RpZnktPk9uQWZ0ZXJLZXlTdHJva2UoVFJVRSwgR2V0QXR0YWNoZWREYXRhKCksIGJFeGl0LG5GbGFnKTsNCi0JCQlpZiAoYkV4aXQpIHJldHVybiBGQUxTRTsNCi0JCX0NCi0JfQ0KLQ0KLQkvL0luIGNhc2Ugb2YgaW1wbGVtZW50YXRpb24gc3dhbGxvdyB0aGUgT25LZXlEb3duIGV2ZW50Lg0KLQlpZihJc1Byb2NlZWR0b09uQ2hhcihuQ2hhciwgbkZsYWcpKQ0KLQkJCXJldHVybiBUUlVFOw0KLQ0KLQlyZXR1cm4gYlJldDsNCi19DQotDQotLyoqDQotKkluIGNhc2Ugb2YgaW1wbGVtZW50YXRpb24gc3dhbGxvdyB0aGUgT25LZXlEb3duIGV2ZW50LiANCi0qSWYgdGhlIGV2ZW50IGlzIHN3YWxsb3dlZCwgaW1wbGVtZW50YXRpb24gbWF5IGRvIG90aGVyIHVuZXhwZWN0ZWQgdGhpbmdzLCB3aGljaCBpcyBub3QgdGhlIGNvbnRyb2wgbWVhbnMgdG8gZG8uDQotKi8NCi1GWF9CT09MIENQV0xfRWRpdDo6SXNQcm9jZWVkdG9PbkNoYXIoRlhfV09SRCBuS2V5Q29kZSwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQ0KLQlGWF9CT09MIGJDdHJsID0gSXNDVFJMcHJlc3NlZChuRmxhZyk7DQotCUZYX0JPT0wgYkFsdCA9IElzQUxUcHJlc3NlZChuRmxhZyk7DQotCWlmKGJDdHJsICYmICFiQWx0KQ0KLQl7DQotCS8vaG90IGtleXMgZm9yIGVkaXQgY29udHJvbC4JDQotCQlzd2l0Y2gobktleUNvZGUpDQotCQl7DQotCQljYXNlICdDJzoNCi0JCWNhc2UgJ1YnOg0KLQkJY2FzZSAnWCc6DQotCQljYXNlICdBJzoNCi0JCWNhc2UgJ1onOg0KLQkJCXJldHVybiBUUlVFOw0KLQkJZGVmYXVsdDoNCi0JCQlicmVhazsNCi0JCX0NCi0JfQ0KLQkvL2NvbnRyb2wgY2hhcmFjdGVycy4NCi0Jc3dpdGNoKG5LZXlDb2RlKQ0KLQl7DQotCWNhc2UgRldMX1ZLRVlfRXNjYXBlOg0KLQljYXNlIEZXTF9WS0VZX0JhY2s6DQotCWNhc2UgRldMX1ZLRVlfUmV0dXJuOg0KLQljYXNlIEZXTF9WS0VZX1NwYWNlOg0KLQkJcmV0dXJuIFRSVUU7DQotCWRlZmF1bHQ6DQotCQlicmVhazsNCi0JfQ0KLQlyZXR1cm4gRkFMU0U7DQotDQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9FZGl0OjpPbkNoYXIoRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAobV9iTW91c2VEb3duKSByZXR1cm4gVFJVRTsNCi0NCi0JRlhfQk9PTCBiUkMgPSBUUlVFOw0KLQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7DQotDQotCUZYX0JPT0wgYkN0cmwgPSBJc0NUUkxwcmVzc2VkKG5GbGFnKTsNCi0JaWYgKCFiQ3RybCkNCi0Jew0KLQkJaWYgKG1fcEZpbGxlck5vdGlmeSkNCi0JCXsNCi0JCQlDRlhfV2lkZVN0cmluZyBzd0NoYW5nZTsNCi0JCQlGWF9JTlQzMiBuS2V5Q29kZTsNCi0NCi0JCQlpbnQgblNlbFN0YXJ0ID0gMDsNCi0JCQlpbnQgblNlbEVuZCA9IDA7DQotCQkJR2V0U2VsKG5TZWxTdGFydCwgblNlbEVuZCk7DQotDQotCQkJc3dpdGNoIChuQ2hhcikNCi0JCQl7DQotCQkJY2FzZSBGV0xfVktFWV9CYWNrOg0KLQkJCQluS2V5Q29kZSA9IG5DaGFyOw0KLQkJCQlpZiAoblNlbFN0YXJ0ID09IG5TZWxFbmQpDQotCQkJCQluU2VsU3RhcnQgPSBuU2VsRW5kIC0gMTsNCi0JCQkJYnJlYWs7DQotCQkJY2FzZSBGV0xfVktFWV9SZXR1cm46DQotCQkJCW5LZXlDb2RlID0gbkNoYXI7DQotCQkJCWJyZWFrOw0KLQkJCWRlZmF1bHQ6DQotCQkJCW5LZXlDb2RlID0gMDsNCi0JCQkJc3dDaGFuZ2UgKz0gbkNoYXI7DQotCQkJCWJyZWFrOw0KLQkJCX0NCi0JCQ0KLQkJCUNGWF9XaWRlU3RyaW5nIHN0ckNoYW5nZUV4Ow0KLQkJCW1fcEZpbGxlck5vdGlmeS0+T25CZWZvcmVLZXlTdHJva2UoVFJVRSwgR2V0QXR0YWNoZWREYXRhKCksIG5LZXlDb2RlLCBzd0NoYW5nZSwgc3RyQ2hhbmdlRXgsIG5TZWxTdGFydCwgblNlbEVuZCwgVFJVRSwgYlJDLCBiRXhpdCwgbkZsYWcpOw0KLQkJfQ0KLQl9DQotDQotCWlmICghYlJDKSByZXR1cm4gVFJVRTsNCi0JaWYgKGJFeGl0KSByZXR1cm4gRkFMU0U7DQotDQotCWlmIChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAgPSBHZXRGb250TWFwKCkpDQotCXsNCi0JCUZYX0lOVDMyIG5PbGRDaGFyU2V0ID0gR2V0Q2hhclNldCgpOw0KLQkJRlhfSU5UMzIgbk5ld0NoYXJTZXQgPSBwRm9udE1hcC0+Q2hhclNldEZyb21Vbmljb2RlKG5DaGFyLCBERUZBVUxUX0NIQVJTRVQpOw0KLQkJaWYobk9sZENoYXJTZXQgIT0gbk5ld0NoYXJTZXQpDQotCQl7DQotCQkJU2V0Q2hhclNldChuTmV3Q2hhclNldCk7DQotCQl9DQotCX0NCi0JRlhfQk9PTCBiUmV0ID0gQ1BXTF9FZGl0Q3RybDo6T25DaGFyKG5DaGFyLG5GbGFnKTsNCi0NCi0JaWYgKCFiQ3RybCkNCi0Jew0KLQkJaWYgKG1fcEZpbGxlck5vdGlmeSkNCi0JCXsNCi0JCQltX3BGaWxsZXJOb3RpZnktPk9uQWZ0ZXJLZXlTdHJva2UoVFJVRSwgR2V0QXR0YWNoZWREYXRhKCksIGJFeGl0LG5GbGFnKTsNCi0JCQlpZiAoYkV4aXQpIHJldHVybiBGQUxTRTsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gYlJldDsNCi19DQotDQotRlhfQk9PTAlDUFdMX0VkaXQ6Ok9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAoSGFzRmxhZyhQRVNfTVVMVElMSU5FKSkNCi0Jew0KLQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IEdldFNjcm9sbFBvcygpOw0KLQ0KLQkJaWYgKHpEZWx0YSA+IDApDQotCQl7DQotCQkJcHRTY3JvbGwueSArPSB0aGlzLT5HZXRGb250U2l6ZSgpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCXB0U2Nyb2xsLnkgLT0gdGhpcy0+R2V0Rm9udFNpemUoKTsNCi0JCX0NCi0JCXRoaXMtPlNldFNjcm9sbFBvcyhwdFNjcm9sbCk7DQotDQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpPbkluc2VydFJldHVybihjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkNCi17DQotCWlmIChIYXNGbGFnKFBFU19TUEVMTENIRUNLKSkNCi0Jew0KLQkJbV9wRWRpdC0+UmVmcmVzaFdvcmRSYW5nZShDb21iaW5lV29yZFJhbmdlKEdldExhdGluV29yZHNSYW5nZShvbGRwbGFjZSksR2V0TGF0aW5Xb3Jkc1JhbmdlKHBsYWNlKSkpOw0KLQl9DQotDQotCWlmIChtX3BFZGl0Tm90aWZ5KQ0KLQl7DQotCQltX3BFZGl0Tm90aWZ5LT5Pbkluc2VydFJldHVybihwbGFjZSwgb2xkcGxhY2UpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpPbkJhY2tTcGFjZShjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkNCi17DQotCWlmIChIYXNGbGFnKFBFU19TUEVMTENIRUNLKSkNCi0Jew0KLQkJbV9wRWRpdC0+UmVmcmVzaFdvcmRSYW5nZShDb21iaW5lV29yZFJhbmdlKEdldExhdGluV29yZHNSYW5nZShvbGRwbGFjZSksR2V0TGF0aW5Xb3Jkc1JhbmdlKHBsYWNlKSkpOw0KLQl9DQotDQotCWlmIChtX3BFZGl0Tm90aWZ5KQ0KLQl7DQotCQltX3BFZGl0Tm90aWZ5LT5PbkJhY2tTcGFjZShwbGFjZSwgb2xkcGxhY2UpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpPbkRlbGV0ZShjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkNCi17DQotCWlmIChIYXNGbGFnKFBFU19TUEVMTENIRUNLKSkNCi0Jew0KLQkJbV9wRWRpdC0+UmVmcmVzaFdvcmRSYW5nZShDb21iaW5lV29yZFJhbmdlKEdldExhdGluV29yZHNSYW5nZShvbGRwbGFjZSksR2V0TGF0aW5Xb3Jkc1JhbmdlKHBsYWNlKSkpOw0KLQl9DQotDQotCWlmIChtX3BFZGl0Tm90aWZ5KQ0KLQl7DQotCQltX3BFZGl0Tm90aWZ5LT5PbkRlbGV0ZShwbGFjZSwgb2xkcGxhY2UpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpPbkNsZWFyKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKQ0KLXsNCi0JaWYgKEhhc0ZsYWcoUEVTX1NQRUxMQ0hFQ0spKQ0KLQl7DQotCQltX3BFZGl0LT5SZWZyZXNoV29yZFJhbmdlKENvbWJpbmVXb3JkUmFuZ2UoR2V0TGF0aW5Xb3Jkc1JhbmdlKG9sZHBsYWNlKSxHZXRMYXRpbldvcmRzUmFuZ2UocGxhY2UpKSk7DQotCX0NCi0NCi0JaWYgKG1fcEVkaXROb3RpZnkpDQotCXsNCi0JCW1fcEVkaXROb3RpZnktPk9uQ2xlYXIocGxhY2UsIG9sZHBsYWNlKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6T25JbnNlcnRXb3JkKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKQ0KLXsNCi0JaWYgKEhhc0ZsYWcoUEVTX1NQRUxMQ0hFQ0spKQ0KLQl7DQotCQltX3BFZGl0LT5SZWZyZXNoV29yZFJhbmdlKENvbWJpbmVXb3JkUmFuZ2UoR2V0TGF0aW5Xb3Jkc1JhbmdlKG9sZHBsYWNlKSxHZXRMYXRpbldvcmRzUmFuZ2UocGxhY2UpKSk7DQotCX0NCi0NCi0JaWYgKG1fcEVkaXROb3RpZnkpDQotCXsNCi0JCW1fcEVkaXROb3RpZnktPk9uSW5zZXJ0V29yZChwbGFjZSwgb2xkcGxhY2UpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpPblNldFRleHQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpDQotew0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6T25JbnNlcnRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKQ0KLXsNCi0JaWYgKEhhc0ZsYWcoUEVTX1NQRUxMQ0hFQ0spKQ0KLQl7DQotCQltX3BFZGl0LT5SZWZyZXNoV29yZFJhbmdlKENvbWJpbmVXb3JkUmFuZ2UoR2V0TGF0aW5Xb3Jkc1JhbmdlKG9sZHBsYWNlKSxHZXRMYXRpbldvcmRzUmFuZ2UocGxhY2UpKSk7DQotCX0NCi0NCi0JaWYgKG1fcEVkaXROb3RpZnkpDQotCXsNCi0JCW1fcEVkaXROb3RpZnktPk9uSW5zZXJ0VGV4dChwbGFjZSwgb2xkcGxhY2UpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpPbkFkZFVuZG8oSUZYX0VkaXRfVW5kb0l0ZW0qIHBVbmRvSXRlbSkNCi17DQotCWlmIChtX3BFZGl0Tm90aWZ5KQ0KLQl7DQotCQltX3BFZGl0Tm90aWZ5LT5PbkFkZFVuZG8odGhpcyk7DQotCX0NCi19DQotDQotQ1BWVF9Xb3JkUmFuZ2UgQ1BXTF9FZGl0OjpDb21iaW5lV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjEsIGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjIpDQotew0KLQlDUFZUX1dvcmRSYW5nZSB3clJldDsNCi0NCi0JaWYgKHdyMS5CZWdpblBvcy5Xb3JkQ21wKHdyMi5CZWdpblBvcykgPCAwKQ0KLQl7DQotCQl3clJldC5CZWdpblBvcyA9IHdyMS5CZWdpblBvczsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCXdyUmV0LkJlZ2luUG9zID0gd3IyLkJlZ2luUG9zOw0KLQl9DQotDQotCWlmICh3cjEuRW5kUG9zLldvcmRDbXAod3IyLkVuZFBvcykgPCAwKQ0KLQl7DQotCQl3clJldC5FbmRQb3MgPSB3cjIuRW5kUG9zOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJd3JSZXQuRW5kUG9zID0gd3IxLkVuZFBvczsNCi0JfQ0KLQ0KLQlyZXR1cm4gd3JSZXQ7DQotfQ0KLQ0KLUNQVlRfV29yZFJhbmdlIENQV0xfRWRpdDo6R2V0TGF0aW5Xb3Jkc1JhbmdlKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdA0KLXsNCi0JcmV0dXJuIEdldFNhbWVXb3Jkc1JhbmdlKG1fcEVkaXQtPlNlYXJjaFdvcmRQbGFjZShwb2ludCksIFRSVUUsIEZBTFNFKTsNCi19DQotDQotQ1BWVF9Xb3JkUmFuZ2UgQ1BXTF9FZGl0OjpHZXRMYXRpbldvcmRzUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QNCi17DQotCXJldHVybiBHZXRTYW1lV29yZHNSYW5nZShwbGFjZSwgVFJVRSwgRkFMU0UpOw0KLX0NCi0NCi1DUFZUX1dvcmRSYW5nZSBDUFdMX0VkaXQ6OkdldEFyYWJpY1dvcmRzUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QNCi17DQotCXJldHVybiBHZXRTYW1lV29yZHNSYW5nZShwbGFjZSwgRkFMU0UsIFRSVUUpOw0KLX0NCi0NCi0jZGVmaW5lIFBXTF9JU0FSQUJJQ1dPUkQod29yZCkgKCh3b3JkID49IDB4MDYwMCAmJiB3b3JkIDw9IDB4MDZGRikgfHwgKHdvcmQgPj0gMHhGQjUwICYmIHdvcmQgPD0gMHhGRUZDKSkNCi0NCi1DUFZUX1dvcmRSYW5nZSBDUFdMX0VkaXQ6OkdldFNhbWVXb3Jkc1JhbmdlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UsIEZYX0JPT0wgYkxhdGluLCBGWF9CT09MIGJBcmFiaWMpIGNvbnN0DQotew0KLQlDUFZUX1dvcmRSYW5nZSByYW5nZTsNCi0NCi0JaWYgKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBtX3BFZGl0LT5HZXRJdGVyYXRvcigpKQ0KLQl7DQotCQlDUFZUX1dvcmQgd29yZGluZm87CQ0KLQkJQ1BWVF9Xb3JkUGxhY2Ugd3BTdGFydChwbGFjZSksd3BFbmQocGxhY2UpOwkJCQ0KLQkJcEl0ZXJhdG9yLT5TZXRBdChwbGFjZSk7CQkJDQotCQkNCi0JCWlmIChiTGF0aW4pDQotCQl7DQotCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkNCi0JCQl7DQotCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZGluZm8pICYmIEZYX0VESVRfSVNMQVRJTldPUkQod29yZGluZm8uV29yZCkpDQotCQkJCXsNCi0JCQkJCXdwRW5kID0gcEl0ZXJhdG9yLT5HZXRBdCgpOw0KLQkJCQkJY29udGludWU7DQotCQkJCX0NCi0JCQkJZWxzZSANCi0JCQkJCWJyZWFrOw0KLQkJCX07DQotCQl9DQotCQllbHNlIGlmIChiQXJhYmljKQ0KLQkJew0KLQkJCXdoaWxlIChwSXRlcmF0b3ItPk5leHRXb3JkKCkpDQotCQkJew0KLQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKSAmJiBQV0xfSVNBUkFCSUNXT1JEKHdvcmRpbmZvLldvcmQpKQ0KLQkJCQl7DQotCQkJCQl3cEVuZCA9IHBJdGVyYXRvci0+R2V0QXQoKTsNCi0JCQkJCWNvbnRpbnVlOw0KLQkJCQl9DQotCQkJCWVsc2UgDQotCQkJCQlicmVhazsNCi0JCQl9Ow0KLQkJfQ0KLQ0KLQkJcEl0ZXJhdG9yLT5TZXRBdChwbGFjZSk7DQotDQotCQlpZiAoYkxhdGluKQ0KLQkJew0KLQkJCWRvDQotCQkJew0KLQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKSAmJiBGWF9FRElUX0lTTEFUSU5XT1JEKHdvcmRpbmZvLldvcmQpKQ0KLQkJCQl7CQkJCQkNCi0JCQkJCWNvbnRpbnVlOw0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJd3BTdGFydCA9IHBJdGVyYXRvci0+R2V0QXQoKTsNCi0JCQkJCWJyZWFrOw0KLQkJCQl9DQotCQkJfQ0KLQkJCXdoaWxlIChwSXRlcmF0b3ItPlByZXZXb3JkKCkpOw0KLQkJfQ0KLQkJZWxzZSBpZiAoYkFyYWJpYykNCi0JCXsNCi0JCQlkbw0KLQkJCXsNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkaW5mbykgJiYgUFdMX0lTQVJBQklDV09SRCh3b3JkaW5mby5Xb3JkKSkNCi0JCQkJewkJCQkJDQotCQkJCQljb250aW51ZTsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsNCi0JCQkJCXdwU3RhcnQgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotCQkJCQlicmVhazsNCi0JCQkJfQ0KLQkJCX0NCi0JCQl3aGlsZSAocEl0ZXJhdG9yLT5QcmV2V29yZCgpKTsNCi0JCX0NCi0NCi0JCXJhbmdlLlNldCh3cFN0YXJ0LHdwRW5kKTsNCi0JfQkNCi0NCi0JcmV0dXJuIHJhbmdlOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6QWp1c3RBcmFiaWNXb3Jkcyhjb25zdCBDUFZUX1dvcmRSYW5nZSYgd3IpDQotew0KLX0NCi0NCi12b2lkIENQV0xfRWRpdDo6R2VuZXJhdGVQYWdlT2JqZWN0cyhDUERGX1BhZ2VPYmplY3RzKiBwUGFnZU9iamVjdHMsIA0KLQkJCQkJCQkJCQljb25zdCBDUERGX1BvaW50JiBwdE9mZnNldCwgQ0ZYX0FycmF5VGVtcGxhdGU8Q1BERl9UZXh0T2JqZWN0Kj4mIE9iakFycmF5KQ0KLXsNCi0JSUZYX0VkaXQ6OkdlbmVyYXRlUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBtX3BFZGl0LCBwdE9mZnNldCwgTlVMTCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksR2V0VHJhbnNwYXJlbmN5KCkpLCBPYmpBcnJheSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0OjpHZW5lcmF0ZVBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgDQotCQkJCQkJCQkJY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQpDQotew0KLQlDRlhfQXJyYXlUZW1wbGF0ZTxDUERGX1RleHRPYmplY3QqPiBPYmpBcnJheTsNCi0JSUZYX0VkaXQ6OkdlbmVyYXRlUGFnZU9iamVjdHMocFBhZ2VPYmplY3RzLCBtX3BFZGl0LCBwdE9mZnNldCwgTlVMTCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksR2V0VHJhbnNwYXJlbmN5KCkpLCBPYmpBcnJheSk7DQotfQ0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1V0aWxzLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0NhcmV0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0ZvbnRNYXAuaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0VkaXQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfRWRpdDo6Q1BXTF9FZGl0KCkgOiBtX3BGaWxsZXJOb3RpZnkoTlVMTCksIAorCW1fcFNwZWxsQ2hlY2soTlVMTCksCisJbV9iRm9jdXMoRkFMU0UpCit7CisJbV9wRm9ybUZpbGxlciA9IE5VTEw7Cit9CisKK0NQV0xfRWRpdDo6fkNQV0xfRWRpdCgpCit7CisJQVNTRVJUKG1fYkZvY3VzID09IEZBTFNFKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9FZGl0OjpHZXRDbGFzc05hbWUoKSBjb25zdAoreworCXJldHVybiBQV0xfQ0xBU1NOQU1FX0VESVQ7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpPbkRlc3Ryb3koKQoreworfQorCit2b2lkIENQV0xfRWRpdDo6U2V0VGV4dChGWF9MUENXU1RSIGNzVGV4dCkKK3sKKwlDRlhfV2lkZVN0cmluZyBzd1RleHQgPSBjc1RleHQ7CisKKwlpZiAoSGFzRmxhZyhQRVNfUklDSCkpCisJewkJCisJCUNGWF9CeXRlU3RyaW5nIHNWYWx1ZSA9IENGWF9CeXRlU3RyaW5nOjpGcm9tVW5pY29kZShzd1RleHQpOworCQkKKwkJaWYgKENYTUxfRWxlbWVudCAqIHBYTUwgPSBDWE1MX0VsZW1lbnQ6OlBhcnNlKChGWF9MUENTVFIpc1ZhbHVlLHNWYWx1ZS5HZXRMZW5ndGgoKSkpCisJCXsKKwkJCUZYX0lOVDMyIG5Db3VudCA9IHBYTUwtPkNvdW50Q2hpbGRyZW4oKTsKKwkJCUZYX0JPT0wgYkZpcnN0ID0gVFJVRTsKKworCQkJc3dUZXh0LkVtcHR5KCk7CisKKwkJCWZvciAoRlhfSU5UMzIgaT0wOyBpPG5Db3VudDsgaSsrKQorCQkJeworCQkJCWlmIChDWE1MX0VsZW1lbnQgKiBwU3ViRWxlbWVudCA9IHBYTUwtPkdldEVsZW1lbnQoaSkpCisJCQkJeworCQkJCQlDRlhfQnl0ZVN0cmluZyB0YWc9cFN1YkVsZW1lbnQtPkdldFRhZ05hbWUoKTsKKwkJICAgCQkJaWYgKHRhZy5FcXVhbE5vQ2FzZSgicCIpKQorCQkJCQl7CisJCQkJCQlpbnQgbkNoaWxkID0gcFN1YkVsZW1lbnQtPkNvdW50Q2hpbGRyZW4oKTsKKwkJCQkJCUNGWF9XaWRlU3RyaW5nIHN3U2VjdGlvbjsKKwkJCQkJCWZvcihGWF9JTlQzMiBqPTA7IGo8bkNoaWxkOyBqKyspCisJCQkJCQl7CisJCQkJCQkJc3dTZWN0aW9uICs9IHBTdWJFbGVtZW50LT5HZXRDb250ZW50KGopOworCQkJCQkJfQorCQkJCQkJCisJCQkJCQlpZiAoYkZpcnN0KWJGaXJzdCA9IEZBTFNFOworCQkJCQkJZWxzZQorCQkJCQkJCXN3VGV4dCArPSBGV0xfVktFWV9SZXR1cm47CisJCQkJCQlzd1RleHQgKz0gc3dTZWN0aW9uOworCQkJCQl9CisJCQkJfQorCQkJfQorCisJCQlkZWxldGUgcFhNTDsKKwkJfQorCX0JCisKKwltX3BFZGl0LT5TZXRUZXh0KHN3VGV4dCk7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpSZVBvc0NoaWxkV25kKCkKK3sKKwlpZiAoQ1BXTF9TY3JvbGxCYXIgKiBwVlNCID0gdGhpcy0+R2V0VlNjcm9sbEJhcigpKQorCXsKKwkJLy9pZiAocFZTQi0+SXNWaXNpYmxlKCkpCisJCXsKKwkJCUNQREZfUmVjdCByY1dpbmRvdyA9IG1fcmNPbGRXaW5kb3c7CQkKKwkJCUNQREZfUmVjdCByY1ZTY3JvbGwgPSBDUERGX1JlY3QocmNXaW5kb3cucmlnaHQsCisJCQkJCQkJCXJjV2luZG93LmJvdHRvbSwKKwkJCQkJCQkJcmNXaW5kb3cucmlnaHQgKyBQV0xfU0NST0xMQkFSX1dJRFRILAorCQkJCQkJCQlyY1dpbmRvdy50b3ApOworCQkJcFZTQi0+TW92ZShyY1ZTY3JvbGwsIFRSVUUsIEZBTFNFKTsKKwkJfQorCX0KKworCWlmIChtX3BFZGl0Q2FyZXQgJiYgIUhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykpCisJCW1fcEVkaXRDYXJldC0+U2V0Q2xpcFJlY3QoQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QoR2V0Q2xpZW50UmVjdCgpLDEuMGYpKTsgLy8rMSBmb3IgY2FyZXQgYmVzaWRlIGJvcmRlcgorCisJQ1BXTF9FZGl0Q3RybDo6UmVQb3NDaGlsZFduZCgpOworfQorCitDUERGX1JlY3QgQ1BXTF9FZGl0OjpHZXRDbGllbnRSZWN0KCkgY29uc3QKK3sKKwlDUERGX1JlY3QgcmNDbGllbnQgPSBDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChHZXRXaW5kb3dSZWN0KCksKEZYX0ZMT0FUKShHZXRCb3JkZXJXaWR0aCgpK0dldElubmVyQm9yZGVyV2lkdGgoKSkpOworCQorCWlmIChDUFdMX1Njcm9sbEJhciAqIHBWU0IgPSB0aGlzLT5HZXRWU2Nyb2xsQmFyKCkpCisJeworCQlpZiAocFZTQi0+SXNWaXNpYmxlKCkpCisJCXsKKwkJCXJjQ2xpZW50LnJpZ2h0IC09IFBXTF9TQ1JPTExCQVJfV0lEVEg7CisJCX0KKwl9CisKKwlyZXR1cm4gcmNDbGllbnQ7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpTZXRBbGlnbkZvcm1hdEgoUFdMX0VESVRfQUxJR05GT1JNQVRfSCBuRm9ybWF0LCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQoreworCW1fcEVkaXQtPlNldEFsaWdubWVudEgoKEZYX0lOVDMyKW5Gb3JtYXQsIGJQYWludCk7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpTZXRBbGlnbkZvcm1hdFYoUFdMX0VESVRfQUxJR05GT1JNQVRfViBuRm9ybWF0LCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQoreworCW1fcEVkaXQtPlNldEFsaWdubWVudFYoKEZYX0lOVDMyKW5Gb3JtYXQsIGJQYWludCk7Cit9CisKK0ZYX0JPT0wJQ1BXTF9FZGl0OjpDYW5TZWxlY3RBbGwoKSBjb25zdAoreworCXJldHVybiAgR2V0U2VsZWN0V29yZFJhbmdlKCkgIT0gbV9wRWRpdC0+R2V0V2hvbGVXb3JkUmFuZ2UoKTsKK30KKworRlhfQk9PTAlDUFdMX0VkaXQ6OkNhbkNsZWFyKCkgY29uc3QKK3sKKwlyZXR1cm4gIUlzUmVhZE9ubHkoKSAmJiBtX3BFZGl0LT5Jc1NlbGVjdGVkKCk7Cit9CisKK0ZYX0JPT0wJQ1BXTF9FZGl0OjpDYW5Db3B5KCkgY29uc3QKK3sKKwlyZXR1cm4gCSFIYXNGbGFnKFBFU19QQVNTV09SRCkgJiYgIUhhc0ZsYWcoUEVTX05PUkVBRCkgJiYgbV9wRWRpdC0+SXNTZWxlY3RlZCgpOworfQorCitGWF9CT09MCUNQV0xfRWRpdDo6Q2FuQ3V0KCkgY29uc3QKK3sKKwlyZXR1cm4gCUNhbkNvcHkoKSAmJiAhSXNSZWFkT25seSgpOworfQorCitGWF9CT09MCUNQV0xfRWRpdDo6Q2FuUGFzdGUoKSBjb25zdAoreworCWlmIChJc1JlYWRPbmx5KCkpIHJldHVybiBGQUxTRTsKKworCUNGWF9XaWRlU3RyaW5nIHN3Q2xpcGJvYXJkOworCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQorCQlzd0NsaXBib2FyZCA9IHBTSC0+R2V0Q2xpcGJvYXJkVGV4dChHZXRBdHRhY2hlZEhXbmQoKSk7CisKKwlyZXR1cm4gIXN3Q2xpcGJvYXJkLklzRW1wdHkoKTsKK30KKwordm9pZCBDUFdMX0VkaXQ6OkNvcHlUZXh0KCkKK3sKKwlpZiAoIUNhbkNvcHkoKSkgcmV0dXJuOworCisJQ0ZYX1dpZGVTdHJpbmcgc3RyID0gbV9wRWRpdC0+R2V0U2VsVGV4dCgpOworCisJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCisJCXBTSC0+U2V0Q2xpcGJvYXJkVGV4dChHZXRBdHRhY2hlZEhXbmQoKSwgc3RyKTsKK30KKwordm9pZCBDUFdMX0VkaXQ6OlBhc3RlVGV4dCgpCit7CisJaWYgKCFDYW5QYXN0ZSgpKSByZXR1cm47CisKKwlDRlhfV2lkZVN0cmluZyBzd0NsaXBib2FyZDsKKwlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKKwkJc3dDbGlwYm9hcmQgPSBwU0gtPkdldENsaXBib2FyZFRleHQoR2V0QXR0YWNoZWRIV25kKCkpOworCisJaWYgKG1fcEZpbGxlck5vdGlmeSkKKwl7CisJCUZYX0JPT0wgYlJDID0gVFJVRTsKKwkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOworCQlDRlhfV2lkZVN0cmluZyBzdHJDaGFuZ2VFeDsKKwkJaW50IG5TZWxTdGFydCA9IDA7CisJCWludCBuU2VsRW5kID0gMDsKKwkJR2V0U2VsKG5TZWxTdGFydCwgblNlbEVuZCk7CisJCW1fcEZpbGxlck5vdGlmeS0+T25CZWZvcmVLZXlTdHJva2UoVFJVRSwgR2V0QXR0YWNoZWREYXRhKCksIDAgLCBzd0NsaXBib2FyZCwgc3RyQ2hhbmdlRXgsIG5TZWxTdGFydCwgblNlbEVuZCwgVFJVRSwgYlJDLCBiRXhpdCwgMCk7CisJCWlmICghYlJDKSByZXR1cm47CisJCWlmIChiRXhpdCkgcmV0dXJuOworCX0KKworCWlmIChzd0NsaXBib2FyZC5HZXRMZW5ndGgoKSA+IDApCisJeworCQlDbGVhcigpOworCQlJbnNlcnRUZXh0KHN3Q2xpcGJvYXJkKTsKKwl9CisKKwlpZiAobV9wRmlsbGVyTm90aWZ5KQorCXsKKwkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOworCQltX3BGaWxsZXJOb3RpZnktPk9uQWZ0ZXJLZXlTdHJva2UoVFJVRSwgR2V0QXR0YWNoZWREYXRhKCksIGJFeGl0LDApOworCQlpZiAoYkV4aXQpIHJldHVybjsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpDdXRUZXh0KCkKK3sKKwlpZiAoIUNhbkN1dCgpKSByZXR1cm47CisKKwlDRlhfV2lkZVN0cmluZyBzdHIgPSBtX3BFZGl0LT5HZXRTZWxUZXh0KCk7CisKKwlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKKwkJcFNILT5TZXRDbGlwYm9hcmRUZXh0KEdldEF0dGFjaGVkSFduZCgpLCBzdHIpOworCisJbV9wRWRpdC0+Q2xlYXIoKTsKK30KKwordm9pZCBDUFdMX0VkaXQ6Ok9uQ3JlYXRlZCgpCit7CisJQ1BXTF9FZGl0Q3RybDo6T25DcmVhdGVkKCk7CisKKwlpZiAoQ1BXTF9TY3JvbGxCYXIgKiBwU2Nyb2xsID0gR2V0VlNjcm9sbEJhcigpKQorCXsKKwkJcFNjcm9sbC0+UmVtb3ZlRmxhZyhQV1NfQVVUT1RSQU5TUEFSRU5UKTsKKwkJcFNjcm9sbC0+U2V0VHJhbnNwYXJlbmN5KDI1NSk7CisJfQorCisJU2V0UGFyYW1CeUZsYWcoKTsKKworCW1fcmNPbGRXaW5kb3cgPSBHZXRXaW5kb3dSZWN0KCk7CisKKwltX3BFZGl0LT5TZXRPcHJOb3RpZnkodGhpcyk7CisJbV9wRWRpdC0+RW5hYmxlT3ByTm90aWZ5KFRSVUUpOworfQorCit2b2lkIENQV0xfRWRpdDo6U2V0UGFyYW1CeUZsYWcoKQorewkKKwlpZiAoSGFzRmxhZyhQRVNfUklHSFQpKQorCXsKKwkJbV9wRWRpdC0+U2V0QWxpZ25tZW50SCgyLCBGQUxTRSk7CisJfQorCWVsc2UgaWYgKEhhc0ZsYWcoUEVTX01JRERMRSkpCisJeworCQltX3BFZGl0LT5TZXRBbGlnbm1lbnRIKDEsIEZBTFNFKTsKKwl9CisJZWxzZQorCXsKKwkJbV9wRWRpdC0+U2V0QWxpZ25tZW50SCgwLCBGQUxTRSk7CisJfQorCisJaWYgKEhhc0ZsYWcoUEVTX0JPVFRPTSkpCisJeworCQltX3BFZGl0LT5TZXRBbGlnbm1lbnRWKDIsIEZBTFNFKTsKKwl9CisJZWxzZSBpZiAoSGFzRmxhZyhQRVNfQ0VOVEVSKSkKKwl7CisJCW1fcEVkaXQtPlNldEFsaWdubWVudFYoMSwgRkFMU0UpOworCX0KKwllbHNlCisJeworCQltX3BFZGl0LT5TZXRBbGlnbm1lbnRWKDAsIEZBTFNFKTsKKwl9CisKKwlpZiAoSGFzRmxhZyhQRVNfUEFTU1dPUkQpKQorCXsKKwkJbV9wRWRpdC0+U2V0UGFzc3dvcmRDaGFyKCcqJywgRkFMU0UpOworCX0KKworCW1fcEVkaXQtPlNldE11bHRpTGluZShIYXNGbGFnKFBFU19NVUxUSUxJTkUpLCBGQUxTRSk7CisJbV9wRWRpdC0+U2V0QXV0b1JldHVybihIYXNGbGFnKFBFU19BVVRPUkVUVVJOKSwgRkFMU0UpOworCW1fcEVkaXQtPlNldEF1dG9Gb250U2l6ZShIYXNGbGFnKFBXU19BVVRPRk9OVFNJWkUpLCBGQUxTRSk7CisJbV9wRWRpdC0+U2V0QXV0b1Njcm9sbChIYXNGbGFnKFBFU19BVVRPU0NST0xMKSwgRkFMU0UpOworCW1fcEVkaXQtPkVuYWJsZVVuZG8oSGFzRmxhZyhQRVNfVU5ETykpOworCisJaWYgKEhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykpCisJeworCQlTZXRDbGlwUmVjdChDUERGX1JlY3QoMC4wZiwwLjBmLDAuMGYsMC4wZikpOworCQltX3BFZGl0LT5TZXRUZXh0T3ZlcmZsb3coVFJVRSwgRkFMU0UpOworCX0KKwllbHNlCisJeworCQlpZiAobV9wRWRpdENhcmV0KQorCQl7CisJCQltX3BFZGl0Q2FyZXQtPlNldENsaXBSZWN0KENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KEdldENsaWVudFJlY3QoKSwxLjBmKSk7IC8vKzEgZm9yIGNhcmV0IGJlc2lkZSBib3JkZXIKKwkJfQorCX0KKworCWlmIChIYXNGbGFnKFBFU19TUEVMTENIRUNLKSkKKwl7CisJCW1fcFNwZWxsQ2hlY2sgPSBHZXRDcmVhdGlvblBhcmFtKCkucFNwZWxsQ2hlY2s7CisJfQorfQorCit2b2lkIENQV0xfRWRpdDo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSkKK3sKKwlDUFdMX1duZDo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oc0FwcFN0cmVhbSk7CisKKwlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisJQ0ZYX0J5dGVUZXh0QnVmIHNMaW5lOworCisJRlhfSU5UMzIgbkNoYXJBcnJheSA9IG1fcEVkaXQtPkdldENoYXJBcnJheSgpOworCisJaWYgKG5DaGFyQXJyYXkgPiAwKQorCXsKKwkJc3dpdGNoIChHZXRCb3JkZXJTdHlsZSgpKQorCQl7CisJCWNhc2UgUEJTX1NPTElEOgorCQkJeworCQkJCXNMaW5lIDw8ICJxXG4iIDw8IEdldEJvcmRlcldpZHRoKCkgPDwgIiB3XG4iIAorCQkJCQk8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShHZXRCb3JkZXJDb2xvcigpLEZBTFNFKSA8PCAiIDIgSiAwIGpcbiI7CQkJCQkKKworCQkJCWZvciAoRlhfSU5UMzIgaT0xO2k8bkNoYXJBcnJheTtpKyspCisJCQkJeworCQkJCQlzTGluZSA8PCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25DaGFyQXJyYXkpKmkgPDwgIiAiCisJCQkJCQk8PCByY0NsaWVudC5ib3R0b20gPDwgIiBtXG4iCisJCQkJCQk8PCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25DaGFyQXJyYXkpKmkgPDwgIiAiCisJCQkJCQk8PCByY0NsaWVudC50b3AgPDwgIiBsIFNcbiI7CQkJCQkJCisJCQkJfQorCisJCQkJc0xpbmUgPDwgIlFcbiI7CQkJCQkKKwkJCX0KKwkJCWJyZWFrOyAKKwkJY2FzZSBQQlNfREFTSDoKKwkJCXsKKwkJCQlzTGluZSA8PCAicVxuIiA8PCBHZXRCb3JkZXJXaWR0aCgpIDw8ICIgd1xuIiAKKwkJCQkJPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oR2V0Qm9yZGVyQ29sb3IoKSxGQUxTRSkgPDwgIiAyIEogMCBqXG4iCisJCQkJCTw8ICJbIiA8PCBHZXRCb3JkZXJEYXNoKCkubkRhc2ggPDwgIiAiIAorCQkJCQk8PCBHZXRCb3JkZXJEYXNoKCkubkdhcCA8PCAiXSAiIAorCQkJCQk8PCBHZXRCb3JkZXJEYXNoKCkublBoYXNlIDw8ICIgZFxuIjsKKworCQkJCWZvciAoRlhfSU5UMzIgaT0xO2k8bkNoYXJBcnJheTtpKyspCQkJCQkKKwkJCQl7CisJCQkJCXNMaW5lIDw8IHJjQ2xpZW50LmxlZnQgKyAoKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCkvbkNoYXJBcnJheSkqaSA8PCAiICIKKwkJCQkJCTw8IHJjQ2xpZW50LmJvdHRvbSA8PCAiIG1cbiIKKwkJCQkJCTw8IHJjQ2xpZW50LmxlZnQgKyAoKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCkvbkNoYXJBcnJheSkqaSA8PCAiICIKKwkJCQkJCTw8IHJjQ2xpZW50LnRvcCA8PCAiIGwgU1xuIjsJCisJCQkJfQorCisJCQkJc0xpbmUgPDwgIlFcbiI7CisJCQl9CisJCQlicmVhazsKKwkJfQkJCisJfQorCisJc0FwcFN0cmVhbSA8PCBzTGluZTsKKworCUNGWF9CeXRlVGV4dEJ1ZiBzVGV4dDsKKworCUNQREZfUG9pbnQgcHRPZmZzZXQgPSBDUERGX1BvaW50KDAuMGYsMC4wZik7CisKKwlDUFZUX1dvcmRSYW5nZSB3cldob2xlID0gbV9wRWRpdC0+R2V0V2hvbGVXb3JkUmFuZ2UoKTsKKwlDUFZUX1dvcmRSYW5nZSB3clNlbGVjdCA9IEdldFNlbGVjdFdvcmRSYW5nZSgpOworCUNQVlRfV29yZFJhbmdlIHdyVmlzaWJsZSA9IChIYXNGbGFnKFBFU19URVhUT1ZFUkZMT1cpID8gd3JXaG9sZSA6IG1fcEVkaXQtPkdldFZpc2libGVXb3JkUmFuZ2UoKSk7CisJQ1BWVF9Xb3JkUmFuZ2Ugd3JTZWxCZWZvcmUod3JXaG9sZS5CZWdpblBvcyx3clNlbGVjdC5CZWdpblBvcyk7CisJQ1BWVF9Xb3JkUmFuZ2Ugd3JTZWxBZnRlcih3clNlbGVjdC5FbmRQb3Msd3JXaG9sZS5FbmRQb3MpOworCisJQ1BWVF9Xb3JkUmFuZ2Ugd3JUZW1wID0gQ1BXTF9VdGlsczo6T3ZlcmxhcFdvcmRSYW5nZShHZXRTZWxlY3RXb3JkUmFuZ2UoKSx3clZpc2libGUpOworCUNGWF9CeXRlU3RyaW5nIHNFZGl0U2VsID0gQ1BXTF9VdGlsczo6R2V0RWRpdFNlbEFwcFN0cmVhbShtX3BFZGl0LCBwdE9mZnNldCwKKwkJCSZ3clRlbXApOworCisJaWYgKHNFZGl0U2VsLkdldExlbmd0aCgpID4gMCkKKwkJc1RleHQgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oUFdMX0RFRkFVTFRfU0VMQkFDS0NPTE9SKSA8PCBzRWRpdFNlbCA7CisKKwl3clRlbXAgPSBDUFdMX1V0aWxzOjpPdmVybGFwV29yZFJhbmdlKHdyVmlzaWJsZSx3clNlbEJlZm9yZSk7CisJQ0ZYX0J5dGVTdHJpbmcgc0VkaXRCZWZvcmUgPSBDUFdMX1V0aWxzOjpHZXRFZGl0QXBwU3RyZWFtKG1fcEVkaXQsIHB0T2Zmc2V0LCAgCisJCQkmd3JUZW1wLCAhSGFzRmxhZyhQRVNfQ0hBUkFSUkFZKSwgbV9wRWRpdC0+R2V0UGFzc3dvcmRDaGFyKCkpOwkJCQorCisJaWYgKHNFZGl0QmVmb3JlLkdldExlbmd0aCgpID4gMCkKKwkJc1RleHQgPDwgIkJUXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldFRleHRDb2xvcigpKSA8PCBzRWRpdEJlZm9yZSA8PCAiRVRcbiI7CisKKwl3clRlbXAgPSBDUFdMX1V0aWxzOjpPdmVybGFwV29yZFJhbmdlKHdyVmlzaWJsZSx3clNlbGVjdCk7CisJQ0ZYX0J5dGVTdHJpbmcgc0VkaXRNaWQgPSBDUFdMX1V0aWxzOjpHZXRFZGl0QXBwU3RyZWFtKG1fcEVkaXQsIHB0T2Zmc2V0LCAKKwkJCSZ3clRlbXAsICFIYXNGbGFnKFBFU19DSEFSQVJSQVkpLCBtX3BFZGl0LT5HZXRQYXNzd29yZENoYXIoKSk7CQkJCisKKwlpZiAoc0VkaXRNaWQuR2V0TGVuZ3RoKCkgPiAwKQorCQlzVGV4dCA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwxKSkgPDwgc0VkaXRNaWQgPDwgIkVUXG4iOworCisJd3JUZW1wID0gQ1BXTF9VdGlsczo6T3ZlcmxhcFdvcmRSYW5nZSh3clZpc2libGUsd3JTZWxBZnRlcik7CisJQ0ZYX0J5dGVTdHJpbmcgc0VkaXRBZnRlciA9IENQV0xfVXRpbHM6OkdldEVkaXRBcHBTdHJlYW0obV9wRWRpdCwgcHRPZmZzZXQsIAorCQkJJndyVGVtcCwgIUhhc0ZsYWcoUEVTX0NIQVJBUlJBWSksIG1fcEVkaXQtPkdldFBhc3N3b3JkQ2hhcigpKTsJCQkKKworCWlmIChzRWRpdEFmdGVyLkdldExlbmd0aCgpID4gMCkKKwkJc1RleHQgPDwgIkJUXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldFRleHRDb2xvcigpKSA8PCBzRWRpdEFmdGVyPDwgIkVUXG4iOworCisJaWYgKEhhc0ZsYWcoUEVTX1NQRUxMQ0hFQ0spKQorCXsKKwkJQ0ZYX0J5dGVTdHJpbmcgc1NwZWxsQ2hlY2sgPSBDUFdMX1V0aWxzOjpHZXRTcGVsbENoZWNrQXBwU3RyZWFtKG1fcEVkaXQsIG1fcFNwZWxsQ2hlY2ssIHB0T2Zmc2V0LCAmd3JWaXNpYmxlKTsKKwkJaWYgKHNTcGVsbENoZWNrLkdldExlbmd0aCgpID4gMCkKKwkJCXNUZXh0IDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwxLDAsMCksRkFMU0UpIDw8IHNTcGVsbENoZWNrOworCX0KKworCWlmIChzVGV4dC5HZXRMZW5ndGgoKSA+IDApCisJeworCQlDUERGX1JlY3QgcmNDbGllbnQgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7CisJCXNBcHBTdHJlYW0gPDwgInFcbi9UeCBCTUNcbiI7CisJCQorCQlpZiAoIUhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykpCisJCQlzQXBwU3RyZWFtIDw8IHJjQ2xpZW50LmxlZnQgPDwgIiAiIDw8IHJjQ2xpZW50LmJvdHRvbSA8PCAiICIKKwkJCQk8PCByY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQgPDwgIiAiIDw8IHJjQ2xpZW50LnRvcCAtIHJjQ2xpZW50LmJvdHRvbSA8PCAiIHJlIFcgblxuIjsKKworCQlzQXBwU3RyZWFtIDw8IHNUZXh0OworCisJCXNBcHBTdHJlYW0gPDwgIkVNQ1xuUVxuIjsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKK3sKKwlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UscFVzZXIyRGV2aWNlKTsKKworCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKwlDRlhfQnl0ZVRleHRCdWYgc0xpbmU7CisKKwlGWF9JTlQzMiBuQ2hhckFycmF5ID0gbV9wRWRpdC0+R2V0Q2hhckFycmF5KCk7CisKKwlpZiAobkNoYXJBcnJheSA+IDApCisJeworCQlzd2l0Y2ggKEdldEJvcmRlclN0eWxlKCkpCisJCXsKKwkJY2FzZSBQQlNfU09MSUQ6CisJCQl7CisJCQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKKwkJCQlnc2QubV9MaW5lV2lkdGggPSAoRlhfRkxPQVQpR2V0Qm9yZGVyV2lkdGgoKTsKKworCQkJCUNGWF9QYXRoRGF0YSBwYXRoOworCQkJCXBhdGguU2V0UG9pbnRDb3VudCgobkNoYXJBcnJheS0xKSoyKTsKKwkJCQkKKwkJCQlmb3IgKEZYX0lOVDMyIGk9MDsgaTxuQ2hhckFycmF5LTE7IGkrKykKKwkJCQl7CQkJCQkKKwkJCQkJcGF0aC5TZXRQb2ludChpKjIsIHJjQ2xpZW50LmxlZnQgKyAoKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCkvbkNoYXJBcnJheSkqKGkrMSksIAorCQkJCQkJcmNDbGllbnQuYm90dG9tLCBGWFBUX01PVkVUTyk7CisJCQkJCXBhdGguU2V0UG9pbnQoaSoyKzEsIHJjQ2xpZW50LmxlZnQgKyAoKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCkvbkNoYXJBcnJheSkqKGkrMSksCisJCQkJCQlyY0NsaWVudC50b3AsIEZYUFRfTElORVRPKTsJCQkJCQkJCQkJCQorCQkJCX0JCQkKKwkJCQlpZiAocGF0aC5HZXRQb2ludENvdW50KCkgPiAwKQorCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLDAsICAKKwkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldEJvcmRlckNvbG9yKCksMjU1KSwgRlhGSUxMX0FMVEVSTkFURSk7CisJCQl9CisJCQlicmVhazsgCisJCWNhc2UgUEJTX0RBU0g6CisJCQl7CisJCQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKKwkJCQlnc2QubV9MaW5lV2lkdGggPSAoRlhfRkxPQVQpR2V0Qm9yZGVyV2lkdGgoKTsKKworCQkJCWdzZC5TZXREYXNoQ291bnQoMik7CisJCQkJZ3NkLm1fRGFzaEFycmF5WzBdID0gKEZYX0ZMT0FUKUdldEJvcmRlckRhc2goKS5uRGFzaDsKKwkJCQlnc2QubV9EYXNoQXJyYXlbMV0gPSAoRlhfRkxPQVQpR2V0Qm9yZGVyRGFzaCgpLm5HYXA7CisJCQkJZ3NkLm1fRGFzaFBoYXNlID0gKEZYX0ZMT0FUKUdldEJvcmRlckRhc2goKS5uUGhhc2U7CisKKwkJCQlDRlhfUGF0aERhdGEgcGF0aDsKKwkJCQlwYXRoLlNldFBvaW50Q291bnQoKG5DaGFyQXJyYXktMSkqMik7CisJCQkJCisJCQkJZm9yIChGWF9JTlQzMiBpPTA7IGk8bkNoYXJBcnJheS0xOyBpKyspCisJCQkJewkJCQkJCisJCQkJCXBhdGguU2V0UG9pbnQoaSoyLCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25DaGFyQXJyYXkpKihpKzEpLCAKKwkJCQkJCXJjQ2xpZW50LmJvdHRvbSwgRlhQVF9NT1ZFVE8pOworCQkJCQlwYXRoLlNldFBvaW50KGkqMisxLCByY0NsaWVudC5sZWZ0ICsgKChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQpL25DaGFyQXJyYXkpKihpKzEpLAorCQkJCQkJcmNDbGllbnQudG9wLCBGWFBUX0xJTkVUTyk7CQkJCQkJCQkJCQkKKwkJCQl9CQkKKwkJCQlpZiAocGF0aC5HZXRQb2ludENvdW50KCkgPiAwKQorCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLDAsICAKKwkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldEJvcmRlckNvbG9yKCksMjU1KSwgRlhGSUxMX0FMVEVSTkFURSk7CisJCQl9CisJCQlicmVhazsKKwkJfQkJCisJfQorCisJQ1BERl9SZWN0IHJjQ2xpcDsKKwlDUFZUX1dvcmRSYW5nZSB3clJhbmdlID0gbV9wRWRpdC0+R2V0VmlzaWJsZVdvcmRSYW5nZSgpOworCUNQVlRfV29yZFJhbmdlKiBwUmFuZ2UgPSBOVUxMOworCisJaWYgKCFIYXNGbGFnKFBFU19URVhUT1ZFUkZMT1cpKQorCXsKKwkJcmNDbGlwID0gR2V0Q2xpZW50UmVjdCgpOworCQlwUmFuZ2UgPSAmd3JSYW5nZTsKKwl9CitJRlhfU3lzdGVtSGFuZGxlciogcFN5c0hhbmRsZXIgPSBHZXRTeXN0ZW1IYW5kbGVyKCk7CisJSUZYX0VkaXQ6OkRyYXdFZGl0KHBEZXZpY2UscFVzZXIyRGV2aWNlLG1fcEVkaXQsCisJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSwKKwkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dFN0cm9rZUNvbG9yKCksdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLAorCQlyY0NsaXAsQ1BERl9Qb2ludCgwLjBmLDAuMGYpLHBSYW5nZSwgcFN5c0hhbmRsZXIsIG1fcEZvcm1GaWxsZXIpOworCisJaWYgKEhhc0ZsYWcoUEVTX1NQRUxMQ0hFQ0spKQorCXsKKwkJQ1BXTF9VdGlsczo6RHJhd0VkaXRTcGVsbENoZWNrKHBEZXZpY2UscFVzZXIyRGV2aWNlLG1fcEVkaXQscmNDbGlwLAorCQkJQ1BERl9Qb2ludCgwLjBmLDAuMGYpLHBSYW5nZSwgdGhpcy0+R2V0Q3JlYXRpb25QYXJhbSgpLnBTcGVsbENoZWNrKTsKKwl9Cit9CisKK0ZYX0JPT0wgQ1BXTF9FZGl0OjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOworCisJaWYgKEhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykgfHwgQ2xpZW50SGl0VGVzdChwb2ludCkpCisJeworCQlpZiAobV9iTW91c2VEb3duKQorCQkJdGhpcy0+SW52YWxpZGF0ZVJlY3QoKTsKKworCQltX2JNb3VzZURvd24gPSBUUlVFOwkJCisJCVNldENhcHR1cmUoKTsKKworCQltX3BFZGl0LT5Pbk1vdXNlRG93bihwb2ludCxJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MCUNQV0xfRWRpdDo6T25MQnV0dG9uRGJsQ2xrKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRibENsayhwb2ludCwgbkZsYWcpOworCisJaWYgKEhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykgfHwgQ2xpZW50SGl0VGVzdChwb2ludCkpCisJeworCQltX3BFZGl0LT5TZWxlY3RBbGwoKTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworI2RlZmluZSBXTV9QV0xFRElUX1VORE8JCQkJCTB4MDEKKyNkZWZpbmUgV01fUFdMRURJVF9SRURPCQkJCQkweDAyCisjZGVmaW5lIFdNX1BXTEVESVRfQ1VUCQkJCQkweDAzCisjZGVmaW5lIFdNX1BXTEVESVRfQ09QWQkJCQkJMHgwNAorI2RlZmluZSBXTV9QV0xFRElUX1BBU1RFCQkJCTB4MDUKKyNkZWZpbmUgV01fUFdMRURJVF9ERUxFVEUJCQkJMHgwNgorI2RlZmluZSBXTV9QV0xFRElUX1NFTEVDVEFMTAkJCTB4MDcKKyNkZWZpbmUgV01fUFdMRURJVF9TVUdHRVNUCQkJCTB4MDgKKworRlhfQk9PTCBDUFdMX0VkaXQ6Ok9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJaWYgKG1fYk1vdXNlRG93bikgcmV0dXJuIEZBTFNFOworCisJQ1BXTF9XbmQ6Ok9uUkJ1dHRvblVwKHBvaW50LCBuRmxhZyk7CisJCisJaWYgKCFIYXNGbGFnKFBFU19URVhUT1ZFUkZMT1cpICYmICFDbGllbnRIaXRUZXN0KHBvaW50KSkgcmV0dXJuIFRSVUU7CisKKwlJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpOworCWlmICghcFNIKSByZXR1cm4gRkFMU0U7CisKKwl0aGlzLT5TZXRGb2N1cygpOworCisJQ1BWVF9Xb3JkUmFuZ2Ugd3JMYXRpbiA9IEdldExhdGluV29yZHNSYW5nZShwb2ludCk7CisJQ0ZYX1dpZGVTdHJpbmcgc3dMYXRpbiA9IG1fcEVkaXQtPkdldFJhbmdlVGV4dCh3ckxhdGluKTsKKworCUZYX0hNRU5VIGhQb3B1cCA9IHBTSC0+Q3JlYXRlUG9wdXBNZW51KCk7CisJaWYgKCFoUG9wdXApIHJldHVybiBGQUxTRTsKKworCUNGWF9CeXRlU3RyaW5nQXJyYXkgc1N1Z2dlc3RXb3JkczsKKwlDUERGX1BvaW50IHB0UG9wdXAgPSBwb2ludDsKKworCWlmICghSXNSZWFkT25seSgpKQorCXsKKwkJaWYgKEhhc0ZsYWcoUEVTX1NQRUxMQ0hFQ0spICYmICFzd0xhdGluLklzRW1wdHkoKSkKKwkJeworCQkJaWYgKG1fcFNwZWxsQ2hlY2spCisJCQl7CisJCQkJQ0ZYX0J5dGVTdHJpbmcgc0xhdGluID0gQ0ZYX0J5dGVTdHJpbmc6OkZyb21Vbmljb2RlKHN3TGF0aW4pOworCisJCQkJaWYgKCFtX3BTcGVsbENoZWNrLT5DaGVja1dvcmQoc0xhdGluKSkKKwkJCQl7CQkJCQkJCisJCQkJCW1fcFNwZWxsQ2hlY2stPlN1Z2dlc3RXb3JkcyhzTGF0aW4sc1N1Z2dlc3RXb3Jkcyk7CisKKwkJCQkJRlhfSU5UMzIgblN1Z2dlc3QgPSBzU3VnZ2VzdFdvcmRzLkdldFNpemUoKTsKKworCQkJCQlmb3IgKEZYX0lOVDMyIG5Xb3JkPTA7IG5Xb3JkPG5TdWdnZXN0OyBuV29yZCsrKQorCQkJCQl7CQorCQkJCQkJcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfU1VHR0VTVCtuV29yZCwgc1N1Z2dlc3RXb3Jkc1tuV29yZF0uVVRGOERlY29kZSgpKTsKKwkJCQkJfQorCisJCQkJCWlmIChuU3VnZ2VzdCA+IDApCisJCQkJCQlwU0gtPkFwcGVuZE1lbnVJdGVtKGhQb3B1cCwgMCwgTCIiKTsKKworCQkJCQlwdFBvcHVwID0gR2V0V29yZFJpZ2h0Qm90dG9tUG9pbnQod3JMYXRpbi5FbmRQb3MpOworCQkJCX0KKwkJCX0KKwkJfQorCX0KKworCUlQV0xfUHJvdmlkZXIqIHBQcm92aWRlciA9IHRoaXMtPkdldFByb3ZpZGVyKCk7CisKKwlpZiAoSGFzRmxhZyhQRVNfVU5ETykpCisJeworCQlwU0gtPkFwcGVuZE1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9VTkRPLCAKKwkJCXBQcm92aWRlciA/IHBQcm92aWRlci0+TG9hZFBvcHVwTWVudVN0cmluZygwKSA6IEwiJlVuZG8iKTsKKwkJcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfUkVETywKKwkJCXBQcm92aWRlciA/IHBQcm92aWRlci0+TG9hZFBvcHVwTWVudVN0cmluZygxKSA6IEwiJlJlZG8iKTsKKwkJcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIDAsIEwiIik7CisKKwkJaWYgKCFtX3BFZGl0LT5DYW5VbmRvKCkpCisJCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9VTkRPLCBGQUxTRSk7CisJCWlmICghbV9wRWRpdC0+Q2FuUmVkbygpKQorCQkJcFNILT5FbmFibGVNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfUkVETywgRkFMU0UpOworCX0KKworCXBTSC0+QXBwZW5kTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NVVCwgCisJCXBQcm92aWRlciA/IHBQcm92aWRlci0+TG9hZFBvcHVwTWVudVN0cmluZygyKSA6IEwiQ3UmdCIpOworCXBTSC0+QXBwZW5kTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NPUFksIAorCQlwUHJvdmlkZXIgPyBwUHJvdmlkZXItPkxvYWRQb3B1cE1lbnVTdHJpbmcoMykgOiBMIiZDb3B5Iik7CisJcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfUEFTVEUsIAorCQlwUHJvdmlkZXIgPyBwUHJvdmlkZXItPkxvYWRQb3B1cE1lbnVTdHJpbmcoNCkgOiBMIiZQYXN0ZSIpOworCXBTSC0+QXBwZW5kTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0RFTEVURSwgCisJCXBQcm92aWRlciA/IHBQcm92aWRlci0+TG9hZFBvcHVwTWVudVN0cmluZyg1KSA6IEwiJkRlbGV0ZSIpOworCisJQ0ZYX1dpZGVTdHJpbmcgc3dUZXh0ID0gcFNILT5HZXRDbGlwYm9hcmRUZXh0KHRoaXMtPkdldEF0dGFjaGVkSFduZCgpKTsKKwlpZiAoc3dUZXh0LklzRW1wdHkoKSkKKwkJcFNILT5FbmFibGVNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfUEFTVEUsIEZBTFNFKTsKKworCWlmICghbV9wRWRpdC0+SXNTZWxlY3RlZCgpKQorCXsKKwkJcFNILT5FbmFibGVNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfQ1VULCBGQUxTRSk7CisJCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NPUFksIEZBTFNFKTsKKwkJcFNILT5FbmFibGVNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfREVMRVRFLCBGQUxTRSk7CisJfQorCisJaWYgKElzUmVhZE9ubHkoKSkKKwl7CisJCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NVVCwgRkFMU0UpOworCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9ERUxFVEUsIEZBTFNFKTsKKwkJcFNILT5FbmFibGVNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfUEFTVEUsIEZBTFNFKTsJCQkKKwl9CisKKwlpZiAoSGFzRmxhZyhQRVNfUEFTU1dPUkQpKQorCXsKKwkJcFNILT5FbmFibGVNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfQ1VULCBGQUxTRSk7CisJCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NPUFksIEZBTFNFKTsKKwl9CisKKwlpZiAoSGFzRmxhZyhQRVNfTk9SRUFEKSkKKwl7CisJCXBTSC0+RW5hYmxlTWVudUl0ZW0oaFBvcHVwLCBXTV9QV0xFRElUX0NVVCwgRkFMU0UpOworCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9DT1BZLCBGQUxTRSk7CisJfQorCisJcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIDAsIEwiIik7CisJcFNILT5BcHBlbmRNZW51SXRlbShoUG9wdXAsIFdNX1BXTEVESVRfU0VMRUNUQUxMLAorCQlwUHJvdmlkZXIgPyBwUHJvdmlkZXItPkxvYWRQb3B1cE1lbnVTdHJpbmcoNikgOiBMIiZTZWxlY3QgQWxsIik7CisKKwlpZiAobV9wRWRpdC0+R2V0VG90YWxXb3JkcygpID09IDApCisJeworCQlwU0gtPkVuYWJsZU1lbnVJdGVtKGhQb3B1cCwgV01fUFdMRURJVF9TRUxFQ1RBTEwsIEZBTFNFKTsKKwl9CisKKwlGWF9JTlQzMiB4LCB5OworCVBXTHRvV25kKHB0UG9wdXAsIHgsIHkpOworCXBTSC0+Q2xpZW50VG9TY3JlZW4oR2V0QXR0YWNoZWRIV25kKCksIHgsIHkpOworCXBTSC0+U2V0Q3Vyc29yKEZYQ1RfQVJST1cpOworCUZYX0lOVDMyIG5DbWQgPSBwU0gtPlRyYWNrUG9wdXBNZW51KGhQb3B1cCwKKwkJCQkJIHgsCisJCQkJCSB5LAorCQkJCQkgR2V0QXR0YWNoZWRIV25kKCkpOworCisKKwlzd2l0Y2ggKG5DbWQpCisJeworCWNhc2UgV01fUFdMRURJVF9VTkRPOgorCQlVbmRvKCk7CisJCWJyZWFrOworCWNhc2UgV01fUFdMRURJVF9SRURPOgorCQlSZWRvKCk7CisJCWJyZWFrOworCWNhc2UgV01fUFdMRURJVF9DVVQ6CisJCXRoaXMtPkN1dFRleHQoKTsKKwkJYnJlYWs7CisJY2FzZSBXTV9QV0xFRElUX0NPUFk6CisJCXRoaXMtPkNvcHlUZXh0KCk7CisJCWJyZWFrOworCWNhc2UgV01fUFdMRURJVF9QQVNURToKKwkJdGhpcy0+UGFzdGVUZXh0KCk7CisJCWJyZWFrOworCWNhc2UgV01fUFdMRURJVF9ERUxFVEU6CisJCXRoaXMtPkNsZWFyKCk7CisJCWJyZWFrOworCWNhc2UgV01fUFdMRURJVF9TRUxFQ1RBTEw6CisJCXRoaXMtPlNlbGVjdEFsbCgpOworCQlicmVhazsKKwljYXNlIFdNX1BXTEVESVRfU1VHR0VTVCArIDA6CisJCVNldFNlbChtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkJlZ2luUG9zKSxtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkVuZFBvcykpOworCQlSZXBsYWNlU2VsKHNTdWdnZXN0V29yZHNbMF0uVVRGOERlY29kZSgpKTsKKwkJYnJlYWs7CisJY2FzZSBXTV9QV0xFRElUX1NVR0dFU1QgKyAxOgorCQlTZXRTZWwobV9wRWRpdC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgod3JMYXRpbi5CZWdpblBvcyksbV9wRWRpdC0+V29yZFBsYWNlVG9Xb3JkSW5kZXgod3JMYXRpbi5FbmRQb3MpKTsKKwkJUmVwbGFjZVNlbChzU3VnZ2VzdFdvcmRzWzFdLlVURjhEZWNvZGUoKSk7CisJCWJyZWFrOworCWNhc2UgV01fUFdMRURJVF9TVUdHRVNUICsgMjoKKwkJU2V0U2VsKG1fcEVkaXQtPldvcmRQbGFjZVRvV29yZEluZGV4KHdyTGF0aW4uQmVnaW5Qb3MpLG1fcEVkaXQtPldvcmRQbGFjZVRvV29yZEluZGV4KHdyTGF0aW4uRW5kUG9zKSk7CisJCVJlcGxhY2VTZWwoc1N1Z2dlc3RXb3Jkc1syXS5VVEY4RGVjb2RlKCkpOworCQlicmVhazsKKwljYXNlIFdNX1BXTEVESVRfU1VHR0VTVCArIDM6CisJCVNldFNlbChtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkJlZ2luUG9zKSxtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkVuZFBvcykpOworCQlSZXBsYWNlU2VsKHNTdWdnZXN0V29yZHNbM10uVVRGOERlY29kZSgpKTsKKwkJYnJlYWs7CisJY2FzZSBXTV9QV0xFRElUX1NVR0dFU1QgKyA0OgkJCisJCVNldFNlbChtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkJlZ2luUG9zKSxtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleCh3ckxhdGluLkVuZFBvcykpOworCQlSZXBsYWNlU2VsKHNTdWdnZXN0V29yZHNbNF0uVVRGOERlY29kZSgpKTsKKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJYnJlYWs7CisJfQorCisJcFNILT5EZXN0cm95TWVudShoUG9wdXApOworCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpPblNldEZvY3VzKCkKK3sKKwlTZXRFZGl0Q2FyZXQoVFJVRSk7CisKKwlpZiAoIUlzUmVhZE9ubHkoKSkKKwl7CisJCWlmIChJUFdMX0ZvY3VzSGFuZGxlciogcEZvY3VzSGFuZGxlciA9IEdldEZvY3VzSGFuZGxlcigpKQorCQkJcEZvY3VzSGFuZGxlci0+T25TZXRGb2N1cyh0aGlzKTsKKwl9CisKKwltX2JGb2N1cyA9IFRSVUU7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpPbktpbGxGb2N1cygpCit7CisJU2hvd1ZTY3JvbGxCYXIoRkFMU0UpOworCQorCW1fcEVkaXQtPlNlbGVjdE5vbmUoKTsKKwlTZXRDYXJldChGQUxTRSwgQ1BERl9Qb2ludCgwLjBmLDAuMGYpLCBDUERGX1BvaW50KDAuMGYsMC4wZikpOworCQorCVNldENoYXJTZXQoMCk7CisKKwlpZiAoIUlzUmVhZE9ubHkoKSkKKwl7CisJCWlmIChJUFdMX0ZvY3VzSGFuZGxlciogcEZvY3VzSGFuZGxlciA9IEdldEZvY3VzSGFuZGxlcigpKQorCQkJcEZvY3VzSGFuZGxlci0+T25LaWxsRm9jdXModGhpcyk7CisJfQorCisJbV9iRm9jdXMgPSBGQUxTRTsKK30KKwordm9pZCBDUFdMX0VkaXQ6OlNldEhvcnpTY2FsZShGWF9JTlQzMiBuSG9yelNjYWxlLCBGWF9CT09MIGJQYWludC8qID0gVFJVRSovKQoreworCW1fcEVkaXQtPlNldEhvcnpTY2FsZShuSG9yelNjYWxlLCBiUGFpbnQpOworfQorCit2b2lkIENQV0xfRWRpdDo6U2V0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UsIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pCit7CisJbV9wRWRpdC0+U2V0Q2hhclNwYWNlKGZDaGFyU3BhY2UsIGJQYWludCk7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpTZXRMaW5lTGVhZGluZyhGWF9GTE9BVCBmTGluZUxlYWRpbmcsIEZYX0JPT0wgYlBhaW50LyogPSBUUlVFKi8pCit7CisJbV9wRWRpdC0+U2V0TGluZUxlYWRpbmcoZkxpbmVMZWFkaW5nLCBiUGFpbnQpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX0VkaXQ6OkdldFNlbGVjdEFwcGVhcmFuY2VTdHJlYW0oY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KSBjb25zdAoreworCUNQVlRfV29yZFJhbmdlIHdyID0gR2V0U2VsZWN0V29yZFJhbmdlKCk7CisJcmV0dXJuIENQV0xfVXRpbHM6OkdldEVkaXRTZWxBcHBTdHJlYW0obV9wRWRpdCxwdE9mZnNldCwmd3IpOworfQorCitDUFZUX1dvcmRSYW5nZSBDUFdMX0VkaXQ6OkdldFNlbGVjdFdvcmRSYW5nZSgpIGNvbnN0Cit7CisJaWYgKG1fcEVkaXQtPklzU2VsZWN0ZWQoKSkKKwl7CisJCUZYX0lOVDMyIG5TdGFydCA9IC0xOworCQlGWF9JTlQzMiBuRW5kID0gLTE7CisKKwkJbV9wRWRpdC0+R2V0U2VsKG5TdGFydCwgbkVuZCk7CisKKwkJQ1BWVF9Xb3JkUGxhY2Ugd3BTdGFydCA9IG1fcEVkaXQtPldvcmRJbmRleFRvV29yZFBsYWNlKG5TdGFydCk7CisJCUNQVlRfV29yZFBsYWNlIHdwRW5kID0gbV9wRWRpdC0+V29yZEluZGV4VG9Xb3JkUGxhY2UobkVuZCk7CisKKwkJcmV0dXJuIENQVlRfV29yZFJhbmdlKHdwU3RhcnQsd3BFbmQpOworCX0KKworCXJldHVybiBDUFZUX1dvcmRSYW5nZSgpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX0VkaXQ6OkdldFRleHRBcHBlYXJhbmNlU3RyZWFtKGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCkgY29uc3QKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc1JldDsKKwlDRlhfQnl0ZVN0cmluZyBzRWRpdCA9IENQV0xfVXRpbHM6OkdldEVkaXRBcHBTdHJlYW0obV9wRWRpdCxwdE9mZnNldCk7CisJCisJaWYgKHNFZGl0LkdldExlbmd0aCgpID4gMCkKKwl7CisJCXNSZXQgPDwgIkJUXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldFRleHRDb2xvcigpKSA8PCBzRWRpdCA8PCAiRVRcbiI7CisJfQorCisJcmV0dXJuIHNSZXQuR2V0Qnl0ZVN0cmluZygpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX0VkaXQ6OkdldENhcmV0QXBwZWFyYW5jZVN0cmVhbShjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQpIGNvbnN0Cit7CisJaWYgKG1fcEVkaXRDYXJldCkKKwkJcmV0dXJuIG1fcEVkaXRDYXJldC0+R2V0Q2FyZXRBcHBlYXJhbmNlU3RyZWFtKHB0T2Zmc2V0KTsKKworCXJldHVybiBDRlhfQnl0ZVN0cmluZygpOworfQorCitDUERGX1BvaW50IENQV0xfRWRpdDo6R2V0V29yZFJpZ2h0Qm90dG9tUG9pbnQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHdwV29yZCkKK3sKKwlDUERGX1BvaW50IHB0KDAuMGYsIDAuMGYpOworCisJaWYgKElGWF9FZGl0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wRWRpdC0+R2V0SXRlcmF0b3IoKSkKKwl7CisJCUNQVlRfV29yZFBsYWNlIHdwT2xkID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCQlwSXRlcmF0b3ItPlNldEF0KHdwV29yZCk7CisJCUNQVlRfV29yZCB3b3JkOworCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQorCQl7CisJCQlwdCA9IENQREZfUG9pbnQod29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoLCB3b3JkLnB0V29yZC55ICsgd29yZC5mRGVzY2VudCk7CisJCX0KKworCQlwSXRlcmF0b3ItPlNldEF0KHdwT2xkKTsKKwl9CisKKwlyZXR1cm4gcHQ7Cit9CisKK0ZYX0JPT0wJQ1BXTF9FZGl0OjpJc1RleHRGdWxsKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wRWRpdC0+SXNUZXh0RnVsbCgpOworfQorCitGWF9GTE9BVCBDUFdMX0VkaXQ6OkdldENoYXJBcnJheUF1dG9Gb250U2l6ZShDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDUERGX1JlY3QmIHJjUGxhdGUsIEZYX0lOVDMyIG5DaGFyQXJyYXkpCit7CisJaWYgKHBGb250ICYmICFwRm9udC0+SXNTdGFuZGFyZEZvbnQoKSkKKwl7CisJCUZYX1JFQ1QgcmNCQm94OworCQlwRm9udC0+R2V0Rm9udEJCb3gocmNCQm94KTsKKworCQlDUERGX1JlY3QgcmNDZWxsID0gcmNQbGF0ZTsKKwkJRlhfRkxPQVQgeGRpdiA9IHJjQ2VsbC5XaWR0aCgpIC8gbkNoYXJBcnJheSAqIDEwMDAuMGYgLyByY0JCb3guV2lkdGgoKTsKKwkJRlhfRkxPQVQgeWRpdiA9IC0gcmNDZWxsLkhlaWdodCgpICogMTAwMC4wZiAvIHJjQkJveC5IZWlnaHQoKTsKKworCQlyZXR1cm4geGRpdiA8IHlkaXYgPyB4ZGl2IDogeWRpdjsKKwl9CisKKwlyZXR1cm4gMC4wZjsKK30KKwordm9pZCBDUFdMX0VkaXQ6OlNldENoYXJBcnJheShGWF9JTlQzMiBuQ2hhckFycmF5KQoreworCWlmIChIYXNGbGFnKFBFU19DSEFSQVJSQVkpICYmIG5DaGFyQXJyYXkgPiAwKQorCXsKKwkJbV9wRWRpdC0+U2V0Q2hhckFycmF5KG5DaGFyQXJyYXkpOwkKKwkJbV9wRWRpdC0+U2V0VGV4dE92ZXJmbG93KFRSVUUpOworCisJCWlmIChIYXNGbGFnKFBXU19BVVRPRk9OVFNJWkUpKQorCQl7CisJCQlpZiAoSUZYX0VkaXRfRm9udE1hcCogcEZvbnRNYXAgPSB0aGlzLT5HZXRGb250TWFwKCkpCisJCQl7CisJCQkJRlhfRkxPQVQgZkZvbnRTaXplID0gR2V0Q2hhckFycmF5QXV0b0ZvbnRTaXplKHBGb250TWFwLT5HZXRQREZGb250KDApLCBHZXRDbGllbnRSZWN0KCksIG5DaGFyQXJyYXkpOworCQkJCWlmIChmRm9udFNpemUgPiAwLjBmKQorCQkJCXsKKwkJCQkJbV9wRWRpdC0+U2V0QXV0b0ZvbnRTaXplKEZBTFNFKTsKKwkJCQkJbV9wRWRpdC0+U2V0Rm9udFNpemUoZkZvbnRTaXplKTsKKwkJCQl9CisJCQl9CisJCX0KKwl9Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpTZXRMaW1pdENoYXIoRlhfSU5UMzIgbkxpbWl0Q2hhcikKK3sKKwltX3BFZGl0LT5TZXRMaW1pdENoYXIobkxpbWl0Q2hhcik7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpSZXBsYWNlU2VsKEZYX0xQQ1dTVFIgY3NUZXh0KQoreworCW1fcEVkaXQtPkNsZWFyKCk7CisJbV9wRWRpdC0+SW5zZXJ0VGV4dChjc1RleHQpOworfQorCitDUERGX1JlY3QgQ1BXTF9FZGl0OjpHZXRGb2N1c1JlY3QoKSBjb25zdAoreworCXJldHVybiBDUERGX1JlY3QoKTsKK30KKwordm9pZCBDUFdMX0VkaXQ6OlNob3dWU2Nyb2xsQmFyKEZYX0JPT0wgYlNob3cpCit7CisJaWYgKENQV0xfU2Nyb2xsQmFyICogcFNjcm9sbCA9IEdldFZTY3JvbGxCYXIoKSkKKwl7CisJCWlmIChiU2hvdykKKwkJeworCQkJaWYgKCFwU2Nyb2xsLT5Jc1Zpc2libGUoKSkKKwkJCXsKKwkJCQlwU2Nyb2xsLT5TZXRWaXNpYmxlKFRSVUUpOworCQkJCUNQREZfUmVjdCByY1dpbmRvdyA9IEdldFdpbmRvd1JlY3QoKTsKKwkJCQltX3JjT2xkV2luZG93ID0gcmNXaW5kb3c7CisJCQkJcmNXaW5kb3cucmlnaHQgKz0gUFdMX1NDUk9MTEJBUl9XSURUSDsJCQkKKwkJCQlNb3ZlKHJjV2luZG93LCBUUlVFLCBUUlVFKTsKKwkJCX0KKwkJfQorCQllbHNlCisJCXsKKwkJCWlmIChwU2Nyb2xsLT5Jc1Zpc2libGUoKSkKKwkJCXsKKwkJCQlwU2Nyb2xsLT5TZXRWaXNpYmxlKEZBTFNFKTsKKwkJCQlNb3ZlKG1fcmNPbGRXaW5kb3csIFRSVUUsIFRSVUUpOworCQkJfQkKKwkJfQorCX0KK30KKworRlhfQk9PTAlDUFdMX0VkaXQ6OklzVlNjcm9sbEJhclZpc2libGUoKSBjb25zdAoreworCWlmIChDUFdMX1Njcm9sbEJhciAqIHBTY3JvbGwgPSBHZXRWU2Nyb2xsQmFyKCkpCisJeworCQlyZXR1cm4gcFNjcm9sbC0+SXNWaXNpYmxlKCk7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIENQV0xfRWRpdDo6RW5hYmxlU3BlbGxDaGVjayhGWF9CT09MIGJFbmFibGVkKQoreworCWlmIChiRW5hYmxlZCkKKwkJQWRkRmxhZyhQRVNfU1BFTExDSEVDSyk7CisJZWxzZQorCQlSZW1vdmVGbGFnKFBFU19TUEVMTENIRUNLKTsKK30KKworRlhfQk9PTCBDUFdMX0VkaXQ6Ok9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZykKK3sKKwlpZiAobV9iTW91c2VEb3duKSByZXR1cm4gVFJVRTsKKworCWlmIChuQ2hhciA9PSBGV0xfVktFWV9EZWxldGUpCisJeworCQlpZiAobV9wRmlsbGVyTm90aWZ5KQorCQl7CisJCQlGWF9CT09MIGJSQyA9IFRSVUU7CisJCQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7CisJCQlDRlhfV2lkZVN0cmluZyBzdHJDaGFuZ2U7CisJCQlDRlhfV2lkZVN0cmluZyBzdHJDaGFuZ2VFeDsKKworCQkJaW50IG5TZWxTdGFydCA9IDA7CisJCQlpbnQgblNlbEVuZCA9IDA7CisJCQlHZXRTZWwoblNlbFN0YXJ0LCBuU2VsRW5kKTsKKworCQkJaWYgKG5TZWxTdGFydCA9PSBuU2VsRW5kKQorCQkJCW5TZWxFbmQgPSBuU2VsU3RhcnQgKyAxOworCQkJbV9wRmlsbGVyTm90aWZ5LT5PbkJlZm9yZUtleVN0cm9rZShUUlVFLCBHZXRBdHRhY2hlZERhdGEoKSwgRldMX1ZLRVlfRGVsZXRlLCBzdHJDaGFuZ2UsIHN0ckNoYW5nZUV4LCBuU2VsU3RhcnQsIG5TZWxFbmQsIFRSVUUsIGJSQywgYkV4aXQsIG5GbGFnKTsKKwkJCWlmICghYlJDKSByZXR1cm4gRkFMU0U7CQkJCQorCQkJaWYgKGJFeGl0KSByZXR1cm4gRkFMU0U7CisJCX0KKwl9CisKKwlGWF9CT09MIGJSZXQgPSBDUFdMX0VkaXRDdHJsOjpPbktleURvd24obkNoYXIsICBuRmxhZyk7CisKKwlpZiAobkNoYXIgPT0gRldMX1ZLRVlfRGVsZXRlKQorCXsKKwkJaWYgKG1fcEZpbGxlck5vdGlmeSkKKwkJeworCQkJRlhfQk9PTCBiRXhpdCA9IEZBTFNFOworCQkJbV9wRmlsbGVyTm90aWZ5LT5PbkFmdGVyS2V5U3Ryb2tlKFRSVUUsIEdldEF0dGFjaGVkRGF0YSgpLCBiRXhpdCxuRmxhZyk7CisJCQlpZiAoYkV4aXQpIHJldHVybiBGQUxTRTsKKwkJfQorCX0KKworCS8vSW4gY2FzZSBvZiBpbXBsZW1lbnRhdGlvbiBzd2FsbG93IHRoZSBPbktleURvd24gZXZlbnQuCisJaWYoSXNQcm9jZWVkdG9PbkNoYXIobkNoYXIsIG5GbGFnKSkKKwkJCXJldHVybiBUUlVFOworCisJcmV0dXJuIGJSZXQ7Cit9CisKKy8qKgorKkluIGNhc2Ugb2YgaW1wbGVtZW50YXRpb24gc3dhbGxvdyB0aGUgT25LZXlEb3duIGV2ZW50LiAKKypJZiB0aGUgZXZlbnQgaXMgc3dhbGxvd2VkLCBpbXBsZW1lbnRhdGlvbiBtYXkgZG8gb3RoZXIgdW5leHBlY3RlZCB0aGluZ3MsIHdoaWNoIGlzIG5vdCB0aGUgY29udHJvbCBtZWFucyB0byBkby4KKyovCitGWF9CT09MIENQV0xfRWRpdDo6SXNQcm9jZWVkdG9PbkNoYXIoRlhfV09SRCBuS2V5Q29kZSwgRlhfRFdPUkQgbkZsYWcpCit7CisKKwlGWF9CT09MIGJDdHJsID0gSXNDVFJMcHJlc3NlZChuRmxhZyk7CisJRlhfQk9PTCBiQWx0ID0gSXNBTFRwcmVzc2VkKG5GbGFnKTsKKwlpZihiQ3RybCAmJiAhYkFsdCkKKwl7CisJLy9ob3Qga2V5cyBmb3IgZWRpdCBjb250cm9sLgkKKwkJc3dpdGNoKG5LZXlDb2RlKQorCQl7CisJCWNhc2UgJ0MnOgorCQljYXNlICdWJzoKKwkJY2FzZSAnWCc6CisJCWNhc2UgJ0EnOgorCQljYXNlICdaJzoKKwkJCXJldHVybiBUUlVFOworCQlkZWZhdWx0OgorCQkJYnJlYWs7CisJCX0KKwl9CisJLy9jb250cm9sIGNoYXJhY3RlcnMuCisJc3dpdGNoKG5LZXlDb2RlKQorCXsKKwljYXNlIEZXTF9WS0VZX0VzY2FwZToKKwljYXNlIEZXTF9WS0VZX0JhY2s6CisJY2FzZSBGV0xfVktFWV9SZXR1cm46CisJY2FzZSBGV0xfVktFWV9TcGFjZToKKwkJcmV0dXJuIFRSVUU7CisJZGVmYXVsdDoKKwkJYnJlYWs7CisJfQorCXJldHVybiBGQUxTRTsKKworfQorCitGWF9CT09MIENQV0xfRWRpdDo6T25DaGFyKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmIChtX2JNb3VzZURvd24pIHJldHVybiBUUlVFOworCisJRlhfQk9PTCBiUkMgPSBUUlVFOworCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsKKworCUZYX0JPT0wgYkN0cmwgPSBJc0NUUkxwcmVzc2VkKG5GbGFnKTsKKwlpZiAoIWJDdHJsKQorCXsKKwkJaWYgKG1fcEZpbGxlck5vdGlmeSkKKwkJeworCQkJQ0ZYX1dpZGVTdHJpbmcgc3dDaGFuZ2U7CisJCQlGWF9JTlQzMiBuS2V5Q29kZTsKKworCQkJaW50IG5TZWxTdGFydCA9IDA7CisJCQlpbnQgblNlbEVuZCA9IDA7CisJCQlHZXRTZWwoblNlbFN0YXJ0LCBuU2VsRW5kKTsKKworCQkJc3dpdGNoIChuQ2hhcikKKwkJCXsKKwkJCWNhc2UgRldMX1ZLRVlfQmFjazoKKwkJCQluS2V5Q29kZSA9IG5DaGFyOworCQkJCWlmIChuU2VsU3RhcnQgPT0gblNlbEVuZCkKKwkJCQkJblNlbFN0YXJ0ID0gblNlbEVuZCAtIDE7CisJCQkJYnJlYWs7CisJCQljYXNlIEZXTF9WS0VZX1JldHVybjoKKwkJCQluS2V5Q29kZSA9IG5DaGFyOworCQkJCWJyZWFrOworCQkJZGVmYXVsdDoKKwkJCQluS2V5Q29kZSA9IDA7CisJCQkJc3dDaGFuZ2UgKz0gbkNoYXI7CisJCQkJYnJlYWs7CisJCQl9CisJCQorCQkJQ0ZYX1dpZGVTdHJpbmcgc3RyQ2hhbmdlRXg7CisJCQltX3BGaWxsZXJOb3RpZnktPk9uQmVmb3JlS2V5U3Ryb2tlKFRSVUUsIEdldEF0dGFjaGVkRGF0YSgpLCBuS2V5Q29kZSwgc3dDaGFuZ2UsIHN0ckNoYW5nZUV4LCBuU2VsU3RhcnQsIG5TZWxFbmQsIFRSVUUsIGJSQywgYkV4aXQsIG5GbGFnKTsKKwkJfQorCX0KKworCWlmICghYlJDKSByZXR1cm4gVFJVRTsKKwlpZiAoYkV4aXQpIHJldHVybiBGQUxTRTsKKworCWlmIChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAgPSBHZXRGb250TWFwKCkpCisJeworCQlGWF9JTlQzMiBuT2xkQ2hhclNldCA9IEdldENoYXJTZXQoKTsKKwkJRlhfSU5UMzIgbk5ld0NoYXJTZXQgPSBwRm9udE1hcC0+Q2hhclNldEZyb21Vbmljb2RlKG5DaGFyLCBERUZBVUxUX0NIQVJTRVQpOworCQlpZihuT2xkQ2hhclNldCAhPSBuTmV3Q2hhclNldCkKKwkJeworCQkJU2V0Q2hhclNldChuTmV3Q2hhclNldCk7CisJCX0KKwl9CisJRlhfQk9PTCBiUmV0ID0gQ1BXTF9FZGl0Q3RybDo6T25DaGFyKG5DaGFyLG5GbGFnKTsKKworCWlmICghYkN0cmwpCisJeworCQlpZiAobV9wRmlsbGVyTm90aWZ5KQorCQl7CisJCQltX3BGaWxsZXJOb3RpZnktPk9uQWZ0ZXJLZXlTdHJva2UoVFJVRSwgR2V0QXR0YWNoZWREYXRhKCksIGJFeGl0LG5GbGFnKTsKKwkJCWlmIChiRXhpdCkgcmV0dXJuIEZBTFNFOworCQl9CisJfQorCisJcmV0dXJuIGJSZXQ7Cit9CisKK0ZYX0JPT0wJQ1BXTF9FZGl0OjpPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmIChIYXNGbGFnKFBFU19NVUxUSUxJTkUpKQorCXsKKwkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IEdldFNjcm9sbFBvcygpOworCisJCWlmICh6RGVsdGEgPiAwKQorCQl7CisJCQlwdFNjcm9sbC55ICs9IHRoaXMtPkdldEZvbnRTaXplKCk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlwdFNjcm9sbC55IC09IHRoaXMtPkdldEZvbnRTaXplKCk7CisJCX0KKwkJdGhpcy0+U2V0U2Nyb2xsUG9zKHB0U2Nyb2xsKTsKKworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpPbkluc2VydFJldHVybihjb25zdCBDUFZUX1dvcmRQbGFjZSYgcGxhY2UsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBvbGRwbGFjZSkKK3sKKwlpZiAoSGFzRmxhZyhQRVNfU1BFTExDSEVDSykpCisJeworCQltX3BFZGl0LT5SZWZyZXNoV29yZFJhbmdlKENvbWJpbmVXb3JkUmFuZ2UoR2V0TGF0aW5Xb3Jkc1JhbmdlKG9sZHBsYWNlKSxHZXRMYXRpbldvcmRzUmFuZ2UocGxhY2UpKSk7CisJfQorCisJaWYgKG1fcEVkaXROb3RpZnkpCisJeworCQltX3BFZGl0Tm90aWZ5LT5Pbkluc2VydFJldHVybihwbGFjZSwgb2xkcGxhY2UpOworCX0KK30KKwordm9pZCBDUFdMX0VkaXQ6Ok9uQmFja1NwYWNlKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKQoreworCWlmIChIYXNGbGFnKFBFU19TUEVMTENIRUNLKSkKKwl7CisJCW1fcEVkaXQtPlJlZnJlc2hXb3JkUmFuZ2UoQ29tYmluZVdvcmRSYW5nZShHZXRMYXRpbldvcmRzUmFuZ2Uob2xkcGxhY2UpLEdldExhdGluV29yZHNSYW5nZShwbGFjZSkpKTsKKwl9CisKKwlpZiAobV9wRWRpdE5vdGlmeSkKKwl7CisJCW1fcEVkaXROb3RpZnktPk9uQmFja1NwYWNlKHBsYWNlLCBvbGRwbGFjZSk7CisJfQorfQorCit2b2lkIENQV0xfRWRpdDo6T25EZWxldGUoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpCit7CisJaWYgKEhhc0ZsYWcoUEVTX1NQRUxMQ0hFQ0spKQorCXsKKwkJbV9wRWRpdC0+UmVmcmVzaFdvcmRSYW5nZShDb21iaW5lV29yZFJhbmdlKEdldExhdGluV29yZHNSYW5nZShvbGRwbGFjZSksR2V0TGF0aW5Xb3Jkc1JhbmdlKHBsYWNlKSkpOworCX0KKworCWlmIChtX3BFZGl0Tm90aWZ5KQorCXsKKwkJbV9wRWRpdE5vdGlmeS0+T25EZWxldGUocGxhY2UsIG9sZHBsYWNlKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpPbkNsZWFyKGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKQoreworCWlmIChIYXNGbGFnKFBFU19TUEVMTENIRUNLKSkKKwl7CisJCW1fcEVkaXQtPlJlZnJlc2hXb3JkUmFuZ2UoQ29tYmluZVdvcmRSYW5nZShHZXRMYXRpbldvcmRzUmFuZ2Uob2xkcGxhY2UpLEdldExhdGluV29yZHNSYW5nZShwbGFjZSkpKTsKKwl9CisKKwlpZiAobV9wRWRpdE5vdGlmeSkKKwl7CisJCW1fcEVkaXROb3RpZnktPk9uQ2xlYXIocGxhY2UsIG9sZHBsYWNlKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpPbkluc2VydFdvcmQoY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIHBsYWNlLCBjb25zdCBDUFZUX1dvcmRQbGFjZSYgb2xkcGxhY2UpCit7CisJaWYgKEhhc0ZsYWcoUEVTX1NQRUxMQ0hFQ0spKQorCXsKKwkJbV9wRWRpdC0+UmVmcmVzaFdvcmRSYW5nZShDb21iaW5lV29yZFJhbmdlKEdldExhdGluV29yZHNSYW5nZShvbGRwbGFjZSksR2V0TGF0aW5Xb3Jkc1JhbmdlKHBsYWNlKSkpOworCX0KKworCWlmIChtX3BFZGl0Tm90aWZ5KQorCXsKKwkJbV9wRWRpdE5vdGlmeS0+T25JbnNlcnRXb3JkKHBsYWNlLCBvbGRwbGFjZSk7CisJfQorfQorCit2b2lkIENQV0xfRWRpdDo6T25TZXRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKQoreworfQorCit2b2lkIENQV0xfRWRpdDo6T25JbnNlcnRUZXh0KGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSwgY29uc3QgQ1BWVF9Xb3JkUGxhY2UmIG9sZHBsYWNlKQoreworCWlmIChIYXNGbGFnKFBFU19TUEVMTENIRUNLKSkKKwl7CisJCW1fcEVkaXQtPlJlZnJlc2hXb3JkUmFuZ2UoQ29tYmluZVdvcmRSYW5nZShHZXRMYXRpbldvcmRzUmFuZ2Uob2xkcGxhY2UpLEdldExhdGluV29yZHNSYW5nZShwbGFjZSkpKTsKKwl9CisKKwlpZiAobV9wRWRpdE5vdGlmeSkKKwl7CisJCW1fcEVkaXROb3RpZnktPk9uSW5zZXJ0VGV4dChwbGFjZSwgb2xkcGxhY2UpOworCX0KK30KKwordm9pZCBDUFdMX0VkaXQ6Ok9uQWRkVW5kbyhJRlhfRWRpdF9VbmRvSXRlbSogcFVuZG9JdGVtKQoreworCWlmIChtX3BFZGl0Tm90aWZ5KQorCXsKKwkJbV9wRWRpdE5vdGlmeS0+T25BZGRVbmRvKHRoaXMpOworCX0KK30KKworQ1BWVF9Xb3JkUmFuZ2UgQ1BXTF9FZGl0OjpDb21iaW5lV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjEsIGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cjIpCit7CisJQ1BWVF9Xb3JkUmFuZ2Ugd3JSZXQ7CisKKwlpZiAod3IxLkJlZ2luUG9zLldvcmRDbXAod3IyLkJlZ2luUG9zKSA8IDApCisJeworCQl3clJldC5CZWdpblBvcyA9IHdyMS5CZWdpblBvczsKKwl9CisJZWxzZQorCXsKKwkJd3JSZXQuQmVnaW5Qb3MgPSB3cjIuQmVnaW5Qb3M7CisJfQorCisJaWYgKHdyMS5FbmRQb3MuV29yZENtcCh3cjIuRW5kUG9zKSA8IDApCisJeworCQl3clJldC5FbmRQb3MgPSB3cjIuRW5kUG9zOworCX0KKwllbHNlCisJeworCQl3clJldC5FbmRQb3MgPSB3cjEuRW5kUG9zOworCX0KKworCXJldHVybiB3clJldDsKK30KKworQ1BWVF9Xb3JkUmFuZ2UgQ1BXTF9FZGl0OjpHZXRMYXRpbldvcmRzUmFuZ2UoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0Cit7CisJcmV0dXJuIEdldFNhbWVXb3Jkc1JhbmdlKG1fcEVkaXQtPlNlYXJjaFdvcmRQbGFjZShwb2ludCksIFRSVUUsIEZBTFNFKTsKK30KKworQ1BWVF9Xb3JkUmFuZ2UgQ1BXTF9FZGl0OjpHZXRMYXRpbldvcmRzUmFuZ2UoY29uc3QgQ1BWVF9Xb3JkUGxhY2UgJiBwbGFjZSkgY29uc3QKK3sKKwlyZXR1cm4gR2V0U2FtZVdvcmRzUmFuZ2UocGxhY2UsIFRSVUUsIEZBTFNFKTsKK30KKworQ1BWVF9Xb3JkUmFuZ2UgQ1BXTF9FZGl0OjpHZXRBcmFiaWNXb3Jkc1JhbmdlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UpIGNvbnN0Cit7CisJcmV0dXJuIEdldFNhbWVXb3Jkc1JhbmdlKHBsYWNlLCBGQUxTRSwgVFJVRSk7Cit9CisKKyNkZWZpbmUgUFdMX0lTQVJBQklDV09SRCh3b3JkKSAoKHdvcmQgPj0gMHgwNjAwICYmIHdvcmQgPD0gMHgwNkZGKSB8fCAod29yZCA+PSAweEZCNTAgJiYgd29yZCA8PSAweEZFRkMpKQorCitDUFZUX1dvcmRSYW5nZSBDUFdMX0VkaXQ6OkdldFNhbWVXb3Jkc1JhbmdlKGNvbnN0IENQVlRfV29yZFBsYWNlICYgcGxhY2UsIEZYX0JPT0wgYkxhdGluLCBGWF9CT09MIGJBcmFiaWMpIGNvbnN0Cit7CisJQ1BWVF9Xb3JkUmFuZ2UgcmFuZ2U7CisKKwlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IG1fcEVkaXQtPkdldEl0ZXJhdG9yKCkpCisJeworCQlDUFZUX1dvcmQgd29yZGluZm87CQorCQlDUFZUX1dvcmRQbGFjZSB3cFN0YXJ0KHBsYWNlKSx3cEVuZChwbGFjZSk7CQkJCisJCXBJdGVyYXRvci0+U2V0QXQocGxhY2UpOwkJCQorCQkKKwkJaWYgKGJMYXRpbikKKwkJeworCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkKKwkJCXsKKwkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKSAmJiBGWF9FRElUX0lTTEFUSU5XT1JEKHdvcmRpbmZvLldvcmQpKQorCQkJCXsKKwkJCQkJd3BFbmQgPSBwSXRlcmF0b3ItPkdldEF0KCk7CisJCQkJCWNvbnRpbnVlOworCQkJCX0KKwkJCQllbHNlIAorCQkJCQlicmVhazsKKwkJCX07CisJCX0KKwkJZWxzZSBpZiAoYkFyYWJpYykKKwkJeworCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkKKwkJCXsKKwkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmRpbmZvKSAmJiBQV0xfSVNBUkFCSUNXT1JEKHdvcmRpbmZvLldvcmQpKQorCQkJCXsKKwkJCQkJd3BFbmQgPSBwSXRlcmF0b3ItPkdldEF0KCk7CisJCQkJCWNvbnRpbnVlOworCQkJCX0KKwkJCQllbHNlIAorCQkJCQlicmVhazsKKwkJCX07CisJCX0KKworCQlwSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsKKworCQlpZiAoYkxhdGluKQorCQl7CisJCQlkbworCQkJeworCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZGluZm8pICYmIEZYX0VESVRfSVNMQVRJTldPUkQod29yZGluZm8uV29yZCkpCisJCQkJewkJCQkJCisJCQkJCWNvbnRpbnVlOworCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQl3cFN0YXJ0ID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCQkJCQlicmVhazsKKwkJCQl9CisJCQl9CisJCQl3aGlsZSAocEl0ZXJhdG9yLT5QcmV2V29yZCgpKTsKKwkJfQorCQllbHNlIGlmIChiQXJhYmljKQorCQl7CisJCQlkbworCQkJeworCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZGluZm8pICYmIFBXTF9JU0FSQUJJQ1dPUkQod29yZGluZm8uV29yZCkpCisJCQkJewkJCQkJCisJCQkJCWNvbnRpbnVlOworCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQl3cFN0YXJ0ID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCQkJCQlicmVhazsKKwkJCQl9CisJCQl9CisJCQl3aGlsZSAocEl0ZXJhdG9yLT5QcmV2V29yZCgpKTsKKwkJfQorCisJCXJhbmdlLlNldCh3cFN0YXJ0LHdwRW5kKTsKKwl9CQorCisJcmV0dXJuIHJhbmdlOworfQorCit2b2lkIENQV0xfRWRpdDo6QWp1c3RBcmFiaWNXb3Jkcyhjb25zdCBDUFZUX1dvcmRSYW5nZSYgd3IpCit7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0OjpHZW5lcmF0ZVBhZ2VPYmplY3RzKENQREZfUGFnZU9iamVjdHMqIHBQYWdlT2JqZWN0cywgCisJCQkJCQkJCQkJY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIENGWF9BcnJheVRlbXBsYXRlPENQREZfVGV4dE9iamVjdCo+JiBPYmpBcnJheSkKK3sKKwlJRlhfRWRpdDo6R2VuZXJhdGVQYWdlT2JqZWN0cyhwUGFnZU9iamVjdHMsIG1fcEVkaXQsIHB0T2Zmc2V0LCBOVUxMLCBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSxHZXRUcmFuc3BhcmVuY3koKSksIE9iakFycmF5KTsKK30KKwordm9pZCBDUFdMX0VkaXQ6OkdlbmVyYXRlUGFnZU9iamVjdHMoQ1BERl9QYWdlT2JqZWN0cyogcFBhZ2VPYmplY3RzLCAKKwkJCQkJCQkJCWNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0KQoreworCUNGWF9BcnJheVRlbXBsYXRlPENQREZfVGV4dE9iamVjdCo+IE9iakFycmF5OworCUlGWF9FZGl0OjpHZW5lcmF0ZVBhZ2VPYmplY3RzKHBQYWdlT2JqZWN0cywgbV9wRWRpdCwgcHRPZmZzZXQsIE5VTEwsIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLEdldFRyYW5zcGFyZW5jeSgpKSwgT2JqQXJyYXkpOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmNwcCBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuY3BwCmluZGV4IDI1NjI4MjIuLjkwYTE5OGEgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuY3BwCkBAIC0xLDcyOCArMSw3MjggQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0NhcmV0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Gb250TWFwLmgiDQotDQotI2RlZmluZSBJc0Zsb2F0WmVybyhmKQkJCQkJCSgoZikgPCAwLjAwMDEgJiYgKGYpID4gLTAuMDAwMSkNCi0jZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCSgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQ0KLSNkZWZpbmUgSXNGbG9hdFNtYWxsZXIoZmEsZmIpCQkJCSgoZmEpIDwgKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQ0KLSNkZWZpbmUgSXNGbG9hdEVxdWFsKGZhLGZiKQkJCQkJSXNGbG9hdFplcm8oKGZhKS0oZmIpKQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9FZGl0Q3RybCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0VkaXRDdHJsOjpDUFdMX0VkaXRDdHJsKCkgOg0KLQltX3BFZGl0KE5VTEwpLA0KLQltX3BFZGl0Q2FyZXQoTlVMTCksDQotCW1fYk1vdXNlRG93bihGQUxTRSksDQotCW1fcEVkaXROb3RpZnkoTlVMTCksDQotCW1fbkNoYXJTZXQoREVGQVVMVF9DSEFSU0VUKSwNCi0JbV9uQ29kZVBhZ2UoMCkNCi17DQotCW1fcEVkaXQgPSBJRlhfRWRpdDo6TmV3RWRpdCgpOw0KLQlBU1NFUlQobV9wRWRpdCAhPSBOVUxMKTsNCi19DQotDQotQ1BXTF9FZGl0Q3RybDo6fkNQV0xfRWRpdEN0cmwoKQ0KLXsNCi0JSUZYX0VkaXQ6OkRlbEVkaXQobV9wRWRpdCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6T25DcmVhdGUoUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLQljcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfVkJFQU07DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6T25DcmVhdGVkKCkNCi17DQotCVNldEZvbnRTaXplKHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKS5mRm9udFNpemUpOw0KLQ0KLQltX3BFZGl0LT5TZXRGb250TWFwKHRoaXMtPkdldEZvbnRNYXAoKSk7DQotCW1fcEVkaXQtPlNldE5vdGlmeSh0aGlzKTsNCi0JbV9wRWRpdC0+SW5pdGlhbGl6ZSgpOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfRWRpdEN0cmw6OklzV25kSG9yVigpDQotew0KLQlDUERGX01hdHJpeCBtdCA9IEdldFdpbmRvd01hdHJpeCgpOw0KLQlDUERGX1BvaW50IHBvaW50MSgwLDEpOw0KLQlDUERGX1BvaW50IHBvaW50MigxLDEpOw0KLQ0KLQltdC5UcmFuc2Zvcm0ocG9pbnQxLngsIHBvaW50MS55KTsNCi0JbXQuVHJhbnNmb3JtKHBvaW50Mi54LCBwb2ludDIueSk7DQotDQotCXJldHVybiBwb2ludDIueSA9PSBwb2ludDEueTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpTZXRDdXJzb3IoKQ0KLXsNCi0JaWYgKElzVmFsaWQoKSkgDQotCXsNCi0JCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQ0KLQkJew0KLQkJCWlmIChJc1duZEhvclYoKSkNCi0JCQkJcFNILT5TZXRDdXJzb3IoRlhDVF9WQkVBTSk7DQotCQkJZWxzZQ0KLQkJCQlwU0gtPlNldEN1cnNvcihGWENUX0hCRUFNKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OlJlUG9zQ2hpbGRXbmQoKQ0KLXsNCi0JbV9wRWRpdC0+U2V0UGxhdGVSZWN0KEdldENsaWVudFJlY3QoKSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkNCi17DQotCUNQV0xfV25kOjpPbk5vdGlmeShwV25kLG1zZyx3UGFyYW0sbFBhcmFtKTsNCi0NCi0Jc3dpdGNoIChtc2cpDQotCXsNCi0JCWNhc2UgUE5NX1NFVFNDUk9MTElORk86DQotCQkJc3dpdGNoICh3UGFyYW0pDQotCQkJew0KLQkJCQljYXNlIFNCVF9WU0NST0xMOg0KLQkJCQkJaWYgKENQV0xfV25kICogcENoaWxkID0gR2V0VlNjcm9sbEJhcigpKQ0KLQkJCQkJew0KLQkJCQkJCXBDaGlsZC0+T25Ob3RpZnkocFduZCxQTk1fU0VUU0NST0xMSU5GTyx3UGFyYW0sbFBhcmFtKTsNCi0JCQkJCX0NCi0JCQkJCWJyZWFrOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgUE5NX1NFVFNDUk9MTFBPUzoJCQkNCi0JCQlzd2l0Y2ggKHdQYXJhbSkNCi0JCQl7DQotCQkJCWNhc2UgU0JUX1ZTQ1JPTEw6DQotCQkJCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBHZXRWU2Nyb2xsQmFyKCkpDQotCQkJCQl7DQotCQkJCQkJcENoaWxkLT5Pbk5vdGlmeShwV25kLFBOTV9TRVRTQ1JPTExQT1Msd1BhcmFtLGxQYXJhbSk7DQotCQkJCQl9DQotCQkJCQlicmVhazsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIFBOTV9TQ1JPTExXSU5ET1c6DQotCQkJew0KLQkJCQlGWF9GTE9BVCBmUG9zID0gKihGWF9GTE9BVCopbFBhcmFtOw0KLQkJCQlzd2l0Y2ggKHdQYXJhbSkNCi0JCQkJew0KLQkJCQkJY2FzZSBTQlRfVlNDUk9MTDoNCi0JCQkJCQltX3BFZGl0LT5TZXRTY3JvbGxQb3MoQ1BERl9Qb2ludChtX3BFZGl0LT5HZXRTY3JvbGxQb3MoKS54LGZQb3MpKTsNCi0JCQkJCQlicmVhazsNCi0JCQkJfQ0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoNCi0JCQl7DQotCQkJCWlmIChQV0xfQ0FSRVRfSU5GTyAqIHBDYXJldEluZm8gPSAoUFdMX0NBUkVUX0lORk8gKil3UGFyYW0pDQotCQkJCXsNCi0JCQkJCXRoaXMtPlNldENhcmV0KHBDYXJldEluZm8tPmJWaXNpYmxlLA0KLQkJCQkJCXBDYXJldEluZm8tPnB0SGVhZCwNCi0JCQkJCQlwQ2FyZXRJbmZvLT5wdEZvb3QpOwkJCQkJDQotCQkJCX0NCi0JCQl9DQotCQkJYnJlYWs7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCi17DQotCWlmICghSXNSZWFkT25seSgpKQ0KLQkJQ3JlYXRlRWRpdENhcmV0KGNwKTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpDcmVhdGVFZGl0Q2FyZXQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLQlpZiAoIW1fcEVkaXRDYXJldCkNCi0Jew0KLQkJbV9wRWRpdENhcmV0ID0gbmV3IENQV0xfQ2FyZXQ7CQ0KLQkJbV9wRWRpdENhcmV0LT5TZXRJbnZhbGlkUmVjdChHZXRDbGllbnRSZWN0KCkpOw0KLQ0KLQkJUFdMX0NSRUFURVBBUkFNCWVjcCA9IGNwOw0KLQkJZWNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQkJZWNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfTk9SRUZSRVNIQ0xJUDsNCi0JCWVjcC5kd0JvcmRlcldpZHRoID0gMDsNCi0JCWVjcC5uQm9yZGVyU3R5bGUgPSBQQlNfU09MSUQ7DQotCQllY3AucmNSZWN0V25kID0gQ1BERl9SZWN0KDAsMCwwLDApOw0KLQ0KLQkJbV9wRWRpdENhcmV0LT5DcmVhdGUoZWNwKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OlNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSkNCi17DQotCW1fcEVkaXQtPlNldEZvbnRTaXplKGZGb250U2l6ZSk7DQotfQ0KLQ0KLUZYX0ZMT0FUIENQV0xfRWRpdEN0cmw6OkdldEZvbnRTaXplKCkgY29uc3QNCi17DQotCXJldHVybiBtX3BFZGl0LT5HZXRGb250U2l6ZSgpOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfRWRpdEN0cmw6Ok9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZykNCi17DQotCWlmIChtX2JNb3VzZURvd24pIHJldHVybiBUUlVFOw0KLQ0KLQlGWF9CT09MIGJSZXQgPSBDUFdMX1duZDo6T25LZXlEb3duKG5DaGFyLG5GbGFnKTsNCi0NCi0JLy9GSUxURVINCi0Jc3dpdGNoIChuQ2hhcikNCi0Jew0KLQlkZWZhdWx0Og0KLQkJcmV0dXJuIEZBTFNFOw0KLQljYXNlIEZXTF9WS0VZX0RlbGV0ZToNCi0JY2FzZSBGV0xfVktFWV9VcDoNCi0JY2FzZSBGV0xfVktFWV9Eb3duOg0KLQljYXNlIEZXTF9WS0VZX0xlZnQ6DQotCWNhc2UgRldMX1ZLRVlfUmlnaHQ6DQotCWNhc2UgRldMX1ZLRVlfSG9tZToNCi0JY2FzZSBGV0xfVktFWV9FbmQ6DQotCWNhc2UgRldMX1ZLRVlfSW5zZXJ0Og0KLQljYXNlICdDJzoNCi0JY2FzZSAnVic6DQotCWNhc2UgJ1gnOg0KLQljYXNlICdBJzoNCi0JY2FzZSAnWic6DQotCWNhc2UgJ2MnOg0KLQljYXNlICd2JzoNCi0JY2FzZSAneCc6DQotCWNhc2UgJ2EnOg0KLQljYXNlICd6JzoNCi0JCWJyZWFrOw0KLQl9DQotDQotCWlmIChuQ2hhciA9PSBGV0xfVktFWV9EZWxldGUpDQotCXsNCi0JCWlmIChtX3BFZGl0LT5Jc1NlbGVjdGVkKCkpDQotCQkJbkNoYXIgPSBGV0xfVktFWV9Vbmtub3duOw0KLQl9DQotDQotCXN3aXRjaCAobkNoYXIpDQotCXsNCi0JCWNhc2UgRldMX1ZLRVlfRGVsZXRlOgkNCi0JCQlEZWxldGUoKTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCWNhc2UgRldMX1ZLRVlfSW5zZXJ0Og0KLQkJCWlmIChJc1NISUZUcHJlc3NlZChuRmxhZykpDQotCQkJCVBhc3RlVGV4dCgpOw0KLQkJCXJldHVybiBUUlVFOw0KLQkJY2FzZSBGV0xfVktFWV9VcDoNCi0JCQltX3BFZGl0LT5PblZLX1VQKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxGQUxTRSk7DQotCQkJcmV0dXJuIFRSVUU7DQotCQljYXNlIEZXTF9WS0VZX0Rvd246DQotCQkJbV9wRWRpdC0+T25WS19ET1dOKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxGQUxTRSk7DQotCQkJcmV0dXJuIFRSVUU7DQotCQljYXNlIEZXTF9WS0VZX0xlZnQ6DQotCQkJbV9wRWRpdC0+T25WS19MRUZUKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxGQUxTRSk7DQotCQkJcmV0dXJuIFRSVUU7DQotCQljYXNlIEZXTF9WS0VZX1JpZ2h0Og0KLQkJCW1fcEVkaXQtPk9uVktfUklHSFQoSXNTSElGVHByZXNzZWQobkZsYWcpLEZBTFNFKTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCWNhc2UgRldMX1ZLRVlfSG9tZToNCi0JCQltX3BFZGl0LT5PblZLX0hPTUUoSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKTsNCi0JCQlyZXR1cm4gVFJVRTsNCi0JCWNhc2UgRldMX1ZLRVlfRW5kOg0KLQkJCW1fcEVkaXQtPk9uVktfRU5EKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQkJcmV0dXJuIFRSVUU7DQotCQljYXNlIEZXTF9WS0VZX1Vua25vd246DQotCQkJaWYgKCFJc1NISUZUcHJlc3NlZChuRmxhZykpDQotCQkJCUNsZWFyKCk7DQotCQkJZWxzZQ0KLQkJCQlDdXRUZXh0KCk7DQotCQkJcmV0dXJuIFRSVUU7DQotCQlkZWZhdWx0Og0KLQkJCWJyZWFrOw0KLQl9DQotCQ0KLQlyZXR1cm4gYlJldDsNCi19DQotDQotRlhfQk9PTCBDUFdMX0VkaXRDdHJsOjpPbkNoYXIoRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAobV9iTW91c2VEb3duKSByZXR1cm4gVFJVRTsNCi0NCi0JQ1BXTF9XbmQ6Ok9uQ2hhcihuQ2hhcixuRmxhZyk7DQotDQotCS8vRklMVEVSDQotCXN3aXRjaCAobkNoYXIpDQotCXsNCi0JCWNhc2UgMHgwQToNCi0JCWNhc2UgMHgxQjoNCi0JCQlyZXR1cm4gRkFMU0U7CQkNCi0JCWRlZmF1bHQ6DQotCQkJYnJlYWs7DQotCX0NCi0NCi0JRlhfQk9PTCBiQ3RybCA9IElzQ1RSTHByZXNzZWQobkZsYWcpOw0KLQlGWF9CT09MIGJBbHQgPSBJc0FMVHByZXNzZWQobkZsYWcpOw0KLQlGWF9CT09MIGJTaGlmdCA9IElzU0hJRlRwcmVzc2VkKG5GbGFnKTsNCi0NCi0JRlhfV09SRCB3b3JkID0gbkNoYXI7DQotDQotCWlmIChiQ3RybCAmJiAhYkFsdCkNCi0Jew0KLQkJc3dpdGNoIChuQ2hhcikNCi0JCXsNCi0JCQljYXNlICdDJyAtICdBJyArIDE6DQotCQkJCXRoaXMtPkNvcHlUZXh0KCk7DQotCQkJCXJldHVybiBUUlVFOw0KLQkJCWNhc2UgJ1YnIC0gJ0EnICsgMToNCi0JCQkJdGhpcy0+UGFzdGVUZXh0KCk7DQotCQkJCXJldHVybiBUUlVFOw0KLQkJCWNhc2UgJ1gnIC0gJ0EnICsgMToNCi0JCQkJdGhpcy0+Q3V0VGV4dCgpOw0KLQkJCQlyZXR1cm4gVFJVRTsNCi0JCQljYXNlICdBJyAtICdBJyArIDE6DQotCQkJCXRoaXMtPlNlbGVjdEFsbCgpOw0KLQkJCQlyZXR1cm4gVFJVRTsNCi0JCQljYXNlICdaJyAtICdBJyArIDE6DQotCQkJCWlmIChiU2hpZnQpDQotCQkJCQlSZWRvKCk7DQotCQkJCWVsc2UNCi0JCQkJCVVuZG8oKTsNCi0JCQkJcmV0dXJuIFRSVUU7DQotCQkJZGVmYXVsdDoNCi0JCQkJaWYgKG5DaGFyIDwgMzIpDQotCQkJCQlyZXR1cm4gRkFMU0U7DQotCQl9DQotCX0NCi0NCi0JaWYgKElzUmVhZE9ubHkoKSkgcmV0dXJuIFRSVUU7DQotDQotCWlmIChtX3BFZGl0LT5Jc1NlbGVjdGVkKCkgJiYgd29yZCA9PSAgRldMX1ZLRVlfQmFjaykNCi0JCXdvcmQgPSBGV0xfVktFWV9Vbmtub3duOw0KLQ0KLQlDbGVhcigpOw0KLQ0KLQlzd2l0Y2ggKHdvcmQpDQotCXsNCi0JY2FzZSBGV0xfVktFWV9CYWNrOg0KLQkJQmFja3NwYWNlKCk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9SZXR1cm46CQ0KLQkJSW5zZXJ0UmV0dXJuKCk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9Vbmtub3duOg0KLQkJYnJlYWs7DQotCWRlZmF1bHQ6DQotCQlpZiAoSXNJTlNFUlRwcmVzc2VkKG5GbGFnKSkNCi0JCQlEZWxldGUoKTsNCi0JCUluc2VydFdvcmQod29yZCwgdGhpcy0+R2V0Q2hhclNldCgpKTsNCi0JCWJyZWFrOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfRWRpdEN0cmw6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKTsNCi0NCi0JaWYgKENsaWVudEhpdFRlc3QocG9pbnQpKQ0KLQl7CQkNCi0JCWlmIChtX2JNb3VzZURvd24pDQotCQkJdGhpcy0+SW52YWxpZGF0ZVJlY3QoKTsNCi0NCi0JCW1fYk1vdXNlRG93biA9IFRSVUU7CQkNCi0JCVNldENhcHR1cmUoKTsNCi0NCi0JCW1fcEVkaXQtPk9uTW91c2VEb3duKHBvaW50LElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9FZGl0Q3RybDo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbkxCdXR0b25VcChwb2ludCxuRmxhZyk7DQotDQotCWlmIChtX2JNb3VzZURvd24pDQotCXsNCi0JCS8vY2FuIHJlY2VpdmUga2V5Ym9yZCBtZXNzYWdlDQotCQlpZiAoQ2xpZW50SGl0VGVzdChwb2ludCkgJiYgIXRoaXMtPklzRm9jdXNlZCgpKQ0KLQkJCVNldEZvY3VzKCk7CQ0KLQ0KLQkJUmVsZWFzZUNhcHR1cmUoKTsNCi0JCW1fYk1vdXNlRG93biA9IEZBTFNFOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfRWRpdEN0cmw6Ok9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlDUFdMX1duZDo6T25Nb3VzZU1vdmUocG9pbnQsbkZsYWcpOw0KLQ0KLQlpZiAobV9iTW91c2VEb3duKQ0KLQkJbV9wRWRpdC0+T25Nb3VzZU1vdmUocG9pbnQsRkFMU0UsRkFMU0UpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotQ1BERl9SZWN0IENQV0xfRWRpdEN0cmw6OkdldENvbnRlbnRSZWN0KCkgY29uc3QNCi17DQotCXJldHVybiBtX3BFZGl0LT5HZXRDb250ZW50UmVjdCgpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OlNldEVkaXRDYXJldChGWF9CT09MIGJWaXNpYmxlKQ0KLXsNCi0JQ1BERl9Qb2ludCBwdEhlYWQoMCwwKSxwdEZvb3QoMCwwKTsNCi0NCi0JaWYgKGJWaXNpYmxlKQ0KLQl7DQotCQlHZXRDYXJldEluZm8ocHRIZWFkLHB0Rm9vdCk7DQotCX0NCi0NCi0JQ1BWVF9Xb3JkUGxhY2Ugd3BUZW1wID0gbV9wRWRpdC0+R2V0Q2FyZXRXb3JkUGxhY2UoKTsNCi0JdGhpcy0+SU9uU2V0Q2FyZXQoYlZpc2libGUscHRIZWFkLHB0Rm9vdCx3cFRlbXApOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OkdldENhcmV0SW5mbyhDUERGX1BvaW50ICYgcHRIZWFkLCBDUERGX1BvaW50ICYgcHRGb290KSBjb25zdA0KLXsNCi0JaWYgKElGWF9FZGl0X0l0ZXJhdG9yICogcEl0ZXJhdG9yID0gbV9wRWRpdC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJcEl0ZXJhdG9yLT5TZXRBdChtX3BFZGl0LT5HZXRDYXJldCgpKTsNCi0JCUNQVlRfV29yZCB3b3JkOw0KLQkJQ1BWVF9MaW5lIGxpbmU7DQotCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQ0KLQkJew0KLQkJCXB0SGVhZC54ID0gd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoOw0KLQkJCXB0SGVhZC55ID0gd29yZC5wdFdvcmQueSArIHdvcmQuZkFzY2VudDsNCi0JCQlwdEZvb3QueCA9IHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aDsNCi0JCQlwdEZvb3QueSA9IHdvcmQucHRXb3JkLnkgKyB3b3JkLmZEZXNjZW50Ow0KLQkJfQ0KLQkJZWxzZSBpZiAocEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmUpKQ0KLQkJewkJCQkNCi0JCQlwdEhlYWQueCA9IGxpbmUucHRMaW5lLng7DQotCQkJcHRIZWFkLnkgPSBsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZUFzY2VudDsNCi0JCQlwdEZvb3QueCA9IGxpbmUucHRMaW5lLng7DQotCQkJcHRGb290LnkgPSBsaW5lLnB0TGluZS55ICsgbGluZS5mTGluZURlc2NlbnQ7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpHZXRDYXJldFBvcyhGWF9JTlQzMiYgeCwgRlhfSU5UMzImIHkpIGNvbnN0DQotew0KLQlDUERGX1BvaW50IHB0SGVhZCgwLDApLCBwdEZvb3QoMCwwKTsNCi0NCi0JR2V0Q2FyZXRJbmZvKHB0SGVhZCxwdEZvb3QpOw0KLQ0KLQlQV0x0b1duZChwdEhlYWQsIHgsIHkpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OlNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsIGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsIGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QpDQotew0KLQlpZiAobV9wRWRpdENhcmV0KQ0KLQl7DQotCQlpZiAoIUlzRm9jdXNlZCgpIHx8IG1fcEVkaXQtPklzU2VsZWN0ZWQoKSkNCi0JCQliVmlzaWJsZSA9IEZBTFNFOw0KLQ0KLQkJbV9wRWRpdENhcmV0LT5TZXRDYXJldChiVmlzaWJsZSwgcHRIZWFkLCBwdEZvb3QpOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9FZGl0Q3RybDo6SXNNb2RpZmllZCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wRWRpdC0+SXNNb2RpZmllZCgpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUFdMX0VkaXRDdHJsOjpHZXRUZXh0KCkgY29uc3QNCi17DQotCXJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6U2V0U2VsKEZYX0lOVDMyIG5TdGFydENoYXIsRlhfSU5UMzIgbkVuZENoYXIpDQotew0KLQltX3BFZGl0LT5TZXRTZWwoblN0YXJ0Q2hhciwgbkVuZENoYXIpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OkdldFNlbChGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIgKSBjb25zdA0KLXsNCi0JbV9wRWRpdC0+R2V0U2VsKG5TdGFydENoYXIsIG5FbmRDaGFyKTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpDbGVhcigpDQotew0KLQlpZiAoIUlzUmVhZE9ubHkoKSkNCi0JCW1fcEVkaXQtPkNsZWFyKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6U2VsZWN0QWxsKCkNCi17DQotCW1fcEVkaXQtPlNlbGVjdEFsbCgpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OlBhaW50KCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQkJbV9wRWRpdC0+UGFpbnQoKTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpFbmFibGVSZWZyZXNoKEZYX0JPT0wgYlJlZnJlc2gpDQotew0KLQlpZiAobV9wRWRpdCkNCi0JCW1fcEVkaXQtPkVuYWJsZVJlZnJlc2goYlJlZnJlc2gpOw0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX0VkaXRDdHJsOjpHZXRDYXJldCgpIGNvbnN0DQotew0KLQlpZiAobV9wRWRpdCkNCi0JCXJldHVybiBtX3BFZGl0LT5HZXRDYXJldCgpOw0KLQ0KLQlyZXR1cm4gLTE7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6U2V0Q2FyZXQoRlhfSU5UMzIgblBvcykNCi17DQotCWlmIChtX3BFZGl0KQ0KLQkJbV9wRWRpdC0+U2V0Q2FyZXQoblBvcyk7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfRWRpdEN0cmw6OkdldFRvdGFsV29yZHMoKSBjb25zdA0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCQlyZXR1cm4gbV9wRWRpdC0+R2V0VG90YWxXb3JkcygpOw0KLQ0KLQlyZXR1cm4gMDsNCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpTZXRTY3JvbGxQb3MoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlpZiAobV9wRWRpdCkNCi0JCW1fcEVkaXQtPlNldFNjcm9sbFBvcyhwb2ludCk7DQotfQ0KLQ0KLUNQREZfUG9pbnQgQ1BXTF9FZGl0Q3RybDo6R2V0U2Nyb2xsUG9zKCkgY29uc3QNCi17DQotCWlmIChtX3BFZGl0KQ0KLQkJcmV0dXJuIG1fcEVkaXQtPkdldFNjcm9sbFBvcygpOw0KLQ0KLQlyZXR1cm4gQ1BERl9Qb2ludCgwLjBmLCAwLjBmKTsNCi19DQotDQotQ1BERl9Gb250ICogQ1BXTF9FZGl0Q3RybDo6R2V0Q2FyZXRGb250KCkgY29uc3QNCi17DQotCUZYX0lOVDMyIG5Gb250SW5kZXggPSAwOw0KLQ0KLQlpZiAoSUZYX0VkaXRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BFZGl0LT5HZXRJdGVyYXRvcigpKQ0KLQl7DQotCQlwSXRlcmF0b3ItPlNldEF0KG1fcEVkaXQtPkdldENhcmV0KCkpOw0KLQkJQ1BWVF9Xb3JkIHdvcmQ7DQotCQlDUFZUX1NlY3Rpb24gc2VjdGlvbjsNCi0JCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpDQotCQl7DQotCQkJbkZvbnRJbmRleCA9IHdvcmQubkZvbnRJbmRleDsNCi0JCX0NCi0JCWVsc2UgaWYgKEhhc0ZsYWcoUEVTX1JJQ0gpKQ0KLQkJew0KLQkJCWlmIChwSXRlcmF0b3ItPkdldFNlY3Rpb24oc2VjdGlvbikpDQotCQkJewkJCQkNCi0JCQkJbkZvbnRJbmRleCA9IHNlY3Rpb24uV29yZFByb3BzLm5Gb250SW5kZXg7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCWlmIChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAgPSBHZXRGb250TWFwKCkpDQotCQlyZXR1cm4gcEZvbnRNYXAtPkdldFBERkZvbnQobkZvbnRJbmRleCk7DQotCWVsc2UNCi0JCXJldHVybiBOVUxMOw0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX0VkaXRDdHJsOjpHZXRDYXJldEZvbnRTaXplKCkgY29uc3QNCi17DQotCUZYX0ZMT0FUIGZGb250U2l6ZSA9IEdldEZvbnRTaXplKCk7DQotDQotCWlmIChJRlhfRWRpdF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcEVkaXQtPkdldEl0ZXJhdG9yKCkpDQotCXsNCi0JCXBJdGVyYXRvci0+U2V0QXQobV9wRWRpdC0+R2V0Q2FyZXQoKSk7DQotCQlDUFZUX1dvcmQgd29yZDsNCi0JCUNQVlRfU2VjdGlvbiBzZWN0aW9uOw0KLQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCXsNCi0JCQlmRm9udFNpemUgPSB3b3JkLmZGb250U2l6ZTsNCi0JCX0NCi0JCWVsc2UgaWYgKEhhc0ZsYWcoUEVTX1JJQ0gpKQ0KLQkJew0KLQkJCWlmIChwSXRlcmF0b3ItPkdldFNlY3Rpb24oc2VjdGlvbikpDQotCQkJewkJCQkNCi0JCQkJZkZvbnRTaXplID0gc2VjdGlvbi5Xb3JkUHJvcHMuZkZvbnRTaXplOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gZkZvbnRTaXplOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OlNldFRleHQoRlhfTFBDV1NUUiBjc1RleHQpDQotew0KLQltX3BFZGl0LT5TZXRUZXh0KGNzVGV4dCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6Q29weVRleHQoKQ0KLXsNCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpQYXN0ZVRleHQoKQ0KLXsNCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpDdXRUZXh0KCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6U2hvd1ZTY3JvbGxCYXIoRlhfQk9PTCBiU2hvdykNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6SW5zZXJ0VGV4dChGWF9MUENXU1RSIGNzVGV4dCkNCi17DQotCWlmICghSXNSZWFkT25seSgpKQ0KLQkJbV9wRWRpdC0+SW5zZXJ0VGV4dChjc1RleHQpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6Okluc2VydFdvcmQoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuQ2hhcnNldCkNCi17DQotCWlmICghSXNSZWFkT25seSgpKQ0KLQkJbV9wRWRpdC0+SW5zZXJ0V29yZCh3b3JkLCBuQ2hhcnNldCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6SW5zZXJ0UmV0dXJuKCkNCi17DQotCWlmICghSXNSZWFkT25seSgpKQ0KLQkJbV9wRWRpdC0+SW5zZXJ0UmV0dXJuKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6RGVsZXRlKCkNCi17DQotCWlmICghSXNSZWFkT25seSgpKQ0KLQkJbV9wRWRpdC0+RGVsZXRlKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6QmFja3NwYWNlKCkNCi17DQotCWlmICghSXNSZWFkT25seSgpKQ0KLQkJbV9wRWRpdC0+QmFja3NwYWNlKCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9FZGl0Q3RybDo6Q2FuVW5kbygpIGNvbnN0DQotew0KLQlyZXR1cm4gIUlzUmVhZE9ubHkoKSAmJiBtX3BFZGl0LT5DYW5VbmRvKCk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9FZGl0Q3RybDo6Q2FuUmVkbygpIGNvbnN0DQotew0KLQlyZXR1cm4gIUlzUmVhZE9ubHkoKSAmJiBtX3BFZGl0LT5DYW5SZWRvKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6UmVkbygpDQotew0KLQlpZiAoQ2FuUmVkbygpKQ0KLQkJbV9wRWRpdC0+UmVkbygpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OlVuZG8oKQ0KLXsNCi0JaWYgKENhblVuZG8oKSkNCi0JCW1fcEVkaXQtPlVuZG8oKTsNCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpJT25TZXRTY3JvbGxJbmZvWShGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgDQotCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkNvbnRlbnRNaW4sIEZYX0ZMT0FUIGZDb250ZW50TWF4LCANCi0JCQkJCQkJCQkJCQlGWF9GTE9BVCBmU21hbGxTdGVwLCBGWF9GTE9BVCBmQmlnU3RlcCkNCi17DQotCVBXTF9TQ1JPTExfSU5GTyBJbmZvOw0KLQ0KLQlJbmZvLmZQbGF0ZVdpZHRoID0gZlBsYXRlTWF4IC0gZlBsYXRlTWluOw0KLQlJbmZvLmZDb250ZW50TWluID0gZkNvbnRlbnRNaW47DQotCUluZm8uZkNvbnRlbnRNYXggPSBmQ29udGVudE1heDsNCi0JSW5mby5mU21hbGxTdGVwID0gZlNtYWxsU3RlcDsNCi0JSW5mby5mQmlnU3RlcCA9IGZCaWdTdGVwOw0KLQ0KLQl0aGlzLT5Pbk5vdGlmeSh0aGlzLFBOTV9TRVRTQ1JPTExJTkZPLFNCVF9WU0NST0xMLChGWF9JTlRQVFIpJkluZm8pOw0KLQ0KLS8vCVBXTF9UUkFDRSgic2V0IHNjcm9sbCBpbmZvOiVmXG4iLGZDb250ZW50TWF4IC0gZkNvbnRlbnRNaW4pOw0KLQ0KLQlpZiAoSXNGbG9hdEJpZ2dlcihJbmZvLmZQbGF0ZVdpZHRoLEluZm8uZkNvbnRlbnRNYXgtSW5mby5mQ29udGVudE1pbikNCi0JCXx8IElzRmxvYXRFcXVhbChJbmZvLmZQbGF0ZVdpZHRoLEluZm8uZkNvbnRlbnRNYXgtSW5mby5mQ29udGVudE1pbikpDQotCXsNCi0JCXRoaXMtPlNob3dWU2Nyb2xsQmFyKEZBTFNFKTsJCQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJdGhpcy0+U2hvd1ZTY3JvbGxCYXIoVFJVRSk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0VkaXRDdHJsOjpJT25TZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KQ0KLXsNCi0vLwlQV0xfVFJBQ0UoInNldCBzY3JvbGwgcG9zaXRpb246JWZcbiIsZnkpOw0KLQl0aGlzLT5Pbk5vdGlmeSh0aGlzLFBOTV9TRVRTQ1JPTExQT1MsU0JUX1ZTQ1JPTEwsKEZYX0lOVFBUUikmZnkpOw0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OklPblNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsIGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsIGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSkNCi17DQotCVBXTF9DQVJFVF9JTkZPIGNJbmZvOw0KLQljSW5mby5iVmlzaWJsZSA9IGJWaXNpYmxlOw0KLQljSW5mby5wdEhlYWQgPSBwdEhlYWQ7DQotCWNJbmZvLnB0Rm9vdCA9IHB0Rm9vdDsNCi0NCi0JdGhpcy0+T25Ob3RpZnkodGhpcyxQTk1fU0VUQ0FSRVRJTkZPLChGWF9JTlRQVFIpJmNJbmZvLChGWF9JTlRQVFIpTlVMTCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6SU9uQ2FyZXRDaGFuZ2UoY29uc3QgQ1BWVF9TZWNQcm9wcyAmIHNlY1Byb3BzLCBjb25zdCBDUFZUX1dvcmRQcm9wcyAmIHdvcmRQcm9wcykNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6SU9uQ29udGVudENoYW5nZShjb25zdCBDUERGX1JlY3QmIHJjQ29udGVudCkNCi17DQotCWlmICh0aGlzLT5Jc1ZhbGlkKCkpDQotCXsNCi0JCWlmIChtX3BFZGl0Tm90aWZ5KQ0KLQkJew0KLQkJCW1fcEVkaXROb3RpZnktPk9uQ29udGVudENoYW5nZShyY0NvbnRlbnQpOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9FZGl0Q3RybDo6SU9uSW52YWxpZGF0ZVJlY3QoQ1BERl9SZWN0ICogcFJlY3QpDQotew0KLQl0aGlzLT5JbnZhbGlkYXRlUmVjdChwUmVjdCk7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfRWRpdEN0cmw6OkdldENoYXJTZXQoKSBjb25zdA0KLXsNCi0JaWYgKG1fbkNoYXJTZXQgPCAwKQ0KLQkJcmV0dXJuIERFRkFVTFRfQ0hBUlNFVDsgDQotCWVsc2UNCi0JCXJldHVybiBtX25DaGFyU2V0Ow0KLX0NCi0NCi12b2lkIENQV0xfRWRpdEN0cmw6OkdldFRleHRSYW5nZShjb25zdCBDUERGX1JlY3QmIHJlY3QsIEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhcikgY29uc3QNCi17DQotCW5TdGFydENoYXIgPSBtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleChtX3BFZGl0LT5TZWFyY2hXb3JkUGxhY2UoQ1BERl9Qb2ludChyZWN0LmxlZnQsIHJlY3QudG9wKSkpOw0KLQluRW5kQ2hhciA9IG1fcEVkaXQtPldvcmRQbGFjZVRvV29yZEluZGV4KG1fcEVkaXQtPlNlYXJjaFdvcmRQbGFjZShDUERGX1BvaW50KHJlY3QucmlnaHQsIHJlY3QuYm90dG9tKSkpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUFdMX0VkaXRDdHJsOjpHZXRUZXh0KEZYX0lOVDMyICYgblN0YXJ0Q2hhciwgRlhfSU5UMzIgJiBuRW5kQ2hhcikgY29uc3QNCi17DQotCUNQVlRfV29yZFBsYWNlIHdwU3RhcnQgPSBtX3BFZGl0LT5Xb3JkSW5kZXhUb1dvcmRQbGFjZShuU3RhcnRDaGFyKTsNCi0JQ1BWVF9Xb3JkUGxhY2Ugd3BFbmQgPSBtX3BFZGl0LT5Xb3JkSW5kZXhUb1dvcmRQbGFjZShuRW5kQ2hhcik7DQotCXJldHVybiBtX3BFZGl0LT5HZXRSYW5nZVRleHQoQ1BWVF9Xb3JkUmFuZ2Uod3BTdGFydCwgd3BFbmQpKTsNCi19DQotDQotdm9pZAlDUFdMX0VkaXRDdHJsOjpTZXRSZWFkeVRvSW5wdXQoKQ0KLXsNCi0JaWYgKG1fYk1vdXNlRG93bikNCi0Jew0KLQkJUmVsZWFzZUNhcHR1cmUoKTsNCi0JCW1fYk1vdXNlRG93biA9IEZBTFNFOw0KLQl9DQotfQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9DYXJldC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Gb250TWFwLmgiCisKKyNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpCisjZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCSgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQorI2RlZmluZSBJc0Zsb2F0U21hbGxlcihmYSxmYikJCQkJKChmYSkgPCAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpCisjZGVmaW5lIElzRmxvYXRFcXVhbChmYSxmYikJCQkJCUlzRmxvYXRaZXJvKChmYSktKGZiKSkKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0VkaXRDdHJsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0VkaXRDdHJsOjpDUFdMX0VkaXRDdHJsKCkgOgorCW1fcEVkaXQoTlVMTCksCisJbV9wRWRpdENhcmV0KE5VTEwpLAorCW1fYk1vdXNlRG93bihGQUxTRSksCisJbV9wRWRpdE5vdGlmeShOVUxMKSwKKwltX25DaGFyU2V0KERFRkFVTFRfQ0hBUlNFVCksCisJbV9uQ29kZVBhZ2UoMCkKK3sKKwltX3BFZGl0ID0gSUZYX0VkaXQ6Ok5ld0VkaXQoKTsKKwlBU1NFUlQobV9wRWRpdCAhPSBOVUxMKTsKK30KKworQ1BXTF9FZGl0Q3RybDo6fkNQV0xfRWRpdEN0cmwoKQoreworCUlGWF9FZGl0OjpEZWxFZGl0KG1fcEVkaXQpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6Ok9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKQoreworCWNwLmVDdXJzb3JUeXBlID0gRlhDVF9WQkVBTTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpPbkNyZWF0ZWQoKQoreworCVNldEZvbnRTaXplKHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKS5mRm9udFNpemUpOworCisJbV9wRWRpdC0+U2V0Rm9udE1hcCh0aGlzLT5HZXRGb250TWFwKCkpOworCW1fcEVkaXQtPlNldE5vdGlmeSh0aGlzKTsKKwltX3BFZGl0LT5Jbml0aWFsaXplKCk7Cit9CisKK0ZYX0JPT0wgQ1BXTF9FZGl0Q3RybDo6SXNXbmRIb3JWKCkKK3sKKwlDUERGX01hdHJpeCBtdCA9IEdldFdpbmRvd01hdHJpeCgpOworCUNQREZfUG9pbnQgcG9pbnQxKDAsMSk7CisJQ1BERl9Qb2ludCBwb2ludDIoMSwxKTsKKworCW10LlRyYW5zZm9ybShwb2ludDEueCwgcG9pbnQxLnkpOworCW10LlRyYW5zZm9ybShwb2ludDIueCwgcG9pbnQyLnkpOworCisJcmV0dXJuIHBvaW50Mi55ID09IHBvaW50MS55OworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OlNldEN1cnNvcigpCit7CisJaWYgKElzVmFsaWQoKSkgCisJeworCQlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKKwkJeworCQkJaWYgKElzV25kSG9yVigpKQorCQkJCXBTSC0+U2V0Q3Vyc29yKEZYQ1RfVkJFQU0pOworCQkJZWxzZQorCQkJCXBTSC0+U2V0Q3Vyc29yKEZYQ1RfSEJFQU0pOworCQl9CisJfQorfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OlJlUG9zQ2hpbGRXbmQoKQoreworCW1fcEVkaXQtPlNldFBsYXRlUmVjdChHZXRDbGllbnRSZWN0KCkpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pCit7CisJQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsbXNnLHdQYXJhbSxsUGFyYW0pOworCisJc3dpdGNoIChtc2cpCisJeworCQljYXNlIFBOTV9TRVRTQ1JPTExJTkZPOgorCQkJc3dpdGNoICh3UGFyYW0pCisJCQl7CisJCQkJY2FzZSBTQlRfVlNDUk9MTDoKKwkJCQkJaWYgKENQV0xfV25kICogcENoaWxkID0gR2V0VlNjcm9sbEJhcigpKQorCQkJCQl7CisJCQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHBXbmQsUE5NX1NFVFNDUk9MTElORk8sd1BhcmFtLGxQYXJhbSk7CisJCQkJCX0KKwkJCQkJYnJlYWs7CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBQTk1fU0VUU0NST0xMUE9TOgkJCQorCQkJc3dpdGNoICh3UGFyYW0pCisJCQl7CisJCQkJY2FzZSBTQlRfVlNDUk9MTDoKKwkJCQkJaWYgKENQV0xfV25kICogcENoaWxkID0gR2V0VlNjcm9sbEJhcigpKQorCQkJCQl7CisJCQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHBXbmQsUE5NX1NFVFNDUk9MTFBPUyx3UGFyYW0sbFBhcmFtKTsKKwkJCQkJfQorCQkJCQlicmVhazsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFBOTV9TQ1JPTExXSU5ET1c6CisJCQl7CisJCQkJRlhfRkxPQVQgZlBvcyA9ICooRlhfRkxPQVQqKWxQYXJhbTsKKwkJCQlzd2l0Y2ggKHdQYXJhbSkKKwkJCQl7CisJCQkJCWNhc2UgU0JUX1ZTQ1JPTEw6CisJCQkJCQltX3BFZGl0LT5TZXRTY3JvbGxQb3MoQ1BERl9Qb2ludChtX3BFZGl0LT5HZXRTY3JvbGxQb3MoKS54LGZQb3MpKTsKKwkJCQkJCWJyZWFrOworCQkJCX0KKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFBOTV9TRVRDQVJFVElORk86CisJCQl7CisJCQkJaWYgKFBXTF9DQVJFVF9JTkZPICogcENhcmV0SW5mbyA9IChQV0xfQ0FSRVRfSU5GTyAqKXdQYXJhbSkKKwkJCQl7CisJCQkJCXRoaXMtPlNldENhcmV0KHBDYXJldEluZm8tPmJWaXNpYmxlLAorCQkJCQkJcENhcmV0SW5mby0+cHRIZWFkLAorCQkJCQkJcENhcmV0SW5mby0+cHRGb290KTsJCQkJCQorCQkJCX0KKwkJCX0KKwkJCWJyZWFrOworCX0KK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKK3sKKwlpZiAoIUlzUmVhZE9ubHkoKSkKKwkJQ3JlYXRlRWRpdENhcmV0KGNwKTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpDcmVhdGVFZGl0Q2FyZXQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJaWYgKCFtX3BFZGl0Q2FyZXQpCisJeworCQltX3BFZGl0Q2FyZXQgPSBuZXcgQ1BXTF9DYXJldDsJCisJCW1fcEVkaXRDYXJldC0+U2V0SW52YWxpZFJlY3QoR2V0Q2xpZW50UmVjdCgpKTsKKworCQlQV0xfQ1JFQVRFUEFSQU0JZWNwID0gY3A7CisJCWVjcC5wUGFyZW50V25kID0gdGhpczsKKwkJZWNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfTk9SRUZSRVNIQ0xJUDsKKwkJZWNwLmR3Qm9yZGVyV2lkdGggPSAwOworCQllY3AubkJvcmRlclN0eWxlID0gUEJTX1NPTElEOworCQllY3AucmNSZWN0V25kID0gQ1BERl9SZWN0KDAsMCwwLDApOworCisJCW1fcEVkaXRDYXJldC0+Q3JlYXRlKGVjcCk7CisJfQorfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OlNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSkKK3sKKwltX3BFZGl0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOworfQorCitGWF9GTE9BVCBDUFdMX0VkaXRDdHJsOjpHZXRGb250U2l6ZSgpIGNvbnN0Cit7CisJcmV0dXJuIG1fcEVkaXQtPkdldEZvbnRTaXplKCk7Cit9CisKK0ZYX0JPT0wgQ1BXTF9FZGl0Q3RybDo6T25LZXlEb3duKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmIChtX2JNb3VzZURvd24pIHJldHVybiBUUlVFOworCisJRlhfQk9PTCBiUmV0ID0gQ1BXTF9XbmQ6Ok9uS2V5RG93bihuQ2hhcixuRmxhZyk7CisKKwkvL0ZJTFRFUgorCXN3aXRjaCAobkNoYXIpCisJeworCWRlZmF1bHQ6CisJCXJldHVybiBGQUxTRTsKKwljYXNlIEZXTF9WS0VZX0RlbGV0ZToKKwljYXNlIEZXTF9WS0VZX1VwOgorCWNhc2UgRldMX1ZLRVlfRG93bjoKKwljYXNlIEZXTF9WS0VZX0xlZnQ6CisJY2FzZSBGV0xfVktFWV9SaWdodDoKKwljYXNlIEZXTF9WS0VZX0hvbWU6CisJY2FzZSBGV0xfVktFWV9FbmQ6CisJY2FzZSBGV0xfVktFWV9JbnNlcnQ6CisJY2FzZSAnQyc6CisJY2FzZSAnVic6CisJY2FzZSAnWCc6CisJY2FzZSAnQSc6CisJY2FzZSAnWic6CisJY2FzZSAnYyc6CisJY2FzZSAndic6CisJY2FzZSAneCc6CisJY2FzZSAnYSc6CisJY2FzZSAneic6CisJCWJyZWFrOworCX0KKworCWlmIChuQ2hhciA9PSBGV0xfVktFWV9EZWxldGUpCisJeworCQlpZiAobV9wRWRpdC0+SXNTZWxlY3RlZCgpKQorCQkJbkNoYXIgPSBGV0xfVktFWV9Vbmtub3duOworCX0KKworCXN3aXRjaCAobkNoYXIpCisJeworCQljYXNlIEZXTF9WS0VZX0RlbGV0ZToJCisJCQlEZWxldGUoKTsKKwkJCXJldHVybiBUUlVFOworCQljYXNlIEZXTF9WS0VZX0luc2VydDoKKwkJCWlmIChJc1NISUZUcHJlc3NlZChuRmxhZykpCisJCQkJUGFzdGVUZXh0KCk7CisJCQlyZXR1cm4gVFJVRTsKKwkJY2FzZSBGV0xfVktFWV9VcDoKKwkJCW1fcEVkaXQtPk9uVktfVVAoSXNTSElGVHByZXNzZWQobkZsYWcpLEZBTFNFKTsKKwkJCXJldHVybiBUUlVFOworCQljYXNlIEZXTF9WS0VZX0Rvd246CisJCQltX3BFZGl0LT5PblZLX0RPV04oSXNTSElGVHByZXNzZWQobkZsYWcpLEZBTFNFKTsKKwkJCXJldHVybiBUUlVFOworCQljYXNlIEZXTF9WS0VZX0xlZnQ6CisJCQltX3BFZGl0LT5PblZLX0xFRlQoSXNTSElGVHByZXNzZWQobkZsYWcpLEZBTFNFKTsKKwkJCXJldHVybiBUUlVFOworCQljYXNlIEZXTF9WS0VZX1JpZ2h0OgorCQkJbV9wRWRpdC0+T25WS19SSUdIVChJc1NISUZUcHJlc3NlZChuRmxhZyksRkFMU0UpOworCQkJcmV0dXJuIFRSVUU7CisJCWNhc2UgRldMX1ZLRVlfSG9tZToKKwkJCW1fcEVkaXQtPk9uVktfSE9NRShJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCQkJcmV0dXJuIFRSVUU7CisJCWNhc2UgRldMX1ZLRVlfRW5kOgorCQkJbV9wRWRpdC0+T25WS19FTkQoSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKTsKKwkJCXJldHVybiBUUlVFOworCQljYXNlIEZXTF9WS0VZX1Vua25vd246CisJCQlpZiAoIUlzU0hJRlRwcmVzc2VkKG5GbGFnKSkKKwkJCQlDbGVhcigpOworCQkJZWxzZQorCQkJCUN1dFRleHQoKTsKKwkJCXJldHVybiBUUlVFOworCQlkZWZhdWx0OgorCQkJYnJlYWs7CisJfQorCQorCXJldHVybiBiUmV0OworfQorCitGWF9CT09MIENQV0xfRWRpdEN0cmw6Ok9uQ2hhcihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZykKK3sKKwlpZiAobV9iTW91c2VEb3duKSByZXR1cm4gVFJVRTsKKworCUNQV0xfV25kOjpPbkNoYXIobkNoYXIsbkZsYWcpOworCisJLy9GSUxURVIKKwlzd2l0Y2ggKG5DaGFyKQorCXsKKwkJY2FzZSAweDBBOgorCQljYXNlIDB4MUI6CisJCQlyZXR1cm4gRkFMU0U7CQkKKwkJZGVmYXVsdDoKKwkJCWJyZWFrOworCX0KKworCUZYX0JPT0wgYkN0cmwgPSBJc0NUUkxwcmVzc2VkKG5GbGFnKTsKKwlGWF9CT09MIGJBbHQgPSBJc0FMVHByZXNzZWQobkZsYWcpOworCUZYX0JPT0wgYlNoaWZ0ID0gSXNTSElGVHByZXNzZWQobkZsYWcpOworCisJRlhfV09SRCB3b3JkID0gbkNoYXI7CisKKwlpZiAoYkN0cmwgJiYgIWJBbHQpCisJeworCQlzd2l0Y2ggKG5DaGFyKQorCQl7CisJCQljYXNlICdDJyAtICdBJyArIDE6CisJCQkJdGhpcy0+Q29weVRleHQoKTsKKwkJCQlyZXR1cm4gVFJVRTsKKwkJCWNhc2UgJ1YnIC0gJ0EnICsgMToKKwkJCQl0aGlzLT5QYXN0ZVRleHQoKTsKKwkJCQlyZXR1cm4gVFJVRTsKKwkJCWNhc2UgJ1gnIC0gJ0EnICsgMToKKwkJCQl0aGlzLT5DdXRUZXh0KCk7CisJCQkJcmV0dXJuIFRSVUU7CisJCQljYXNlICdBJyAtICdBJyArIDE6CisJCQkJdGhpcy0+U2VsZWN0QWxsKCk7CisJCQkJcmV0dXJuIFRSVUU7CisJCQljYXNlICdaJyAtICdBJyArIDE6CisJCQkJaWYgKGJTaGlmdCkKKwkJCQkJUmVkbygpOworCQkJCWVsc2UKKwkJCQkJVW5kbygpOworCQkJCXJldHVybiBUUlVFOworCQkJZGVmYXVsdDoKKwkJCQlpZiAobkNoYXIgPCAzMikKKwkJCQkJcmV0dXJuIEZBTFNFOworCQl9CisJfQorCisJaWYgKElzUmVhZE9ubHkoKSkgcmV0dXJuIFRSVUU7CisKKwlpZiAobV9wRWRpdC0+SXNTZWxlY3RlZCgpICYmIHdvcmQgPT0gIEZXTF9WS0VZX0JhY2spCisJCXdvcmQgPSBGV0xfVktFWV9Vbmtub3duOworCisJQ2xlYXIoKTsKKworCXN3aXRjaCAod29yZCkKKwl7CisJY2FzZSBGV0xfVktFWV9CYWNrOgorCQlCYWNrc3BhY2UoKTsKKwkJYnJlYWs7CisJY2FzZSBGV0xfVktFWV9SZXR1cm46CQorCQlJbnNlcnRSZXR1cm4oKTsKKwkJYnJlYWs7CisJY2FzZSBGV0xfVktFWV9Vbmtub3duOgorCQlicmVhazsKKwlkZWZhdWx0OgorCQlpZiAoSXNJTlNFUlRwcmVzc2VkKG5GbGFnKSkKKwkJCURlbGV0ZSgpOworCQlJbnNlcnRXb3JkKHdvcmQsIHRoaXMtPkdldENoYXJTZXQoKSk7CisJCWJyZWFrOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENQV0xfRWRpdEN0cmw6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKK3sKKwlDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZyk7CisKKwlpZiAoQ2xpZW50SGl0VGVzdChwb2ludCkpCisJewkJCisJCWlmIChtX2JNb3VzZURvd24pCisJCQl0aGlzLT5JbnZhbGlkYXRlUmVjdCgpOworCisJCW1fYk1vdXNlRG93biA9IFRSVUU7CQkKKwkJU2V0Q2FwdHVyZSgpOworCisJCW1fcEVkaXQtPk9uTW91c2VEb3duKHBvaW50LElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgQ1BXTF9FZGl0Q3RybDo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKK3sKKwlDUFdMX1duZDo6T25MQnV0dG9uVXAocG9pbnQsbkZsYWcpOworCisJaWYgKG1fYk1vdXNlRG93bikKKwl7CisJCS8vY2FuIHJlY2VpdmUga2V5Ym9yZCBtZXNzYWdlCisJCWlmIChDbGllbnRIaXRUZXN0KHBvaW50KSAmJiAhdGhpcy0+SXNGb2N1c2VkKCkpCisJCQlTZXRGb2N1cygpOwkKKworCQlSZWxlYXNlQ2FwdHVyZSgpOworCQltX2JNb3VzZURvd24gPSBGQUxTRTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDUFdMX0VkaXRDdHJsOjpPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCUNQV0xfV25kOjpPbk1vdXNlTW92ZShwb2ludCxuRmxhZyk7CisKKwlpZiAobV9iTW91c2VEb3duKQorCQltX3BFZGl0LT5Pbk1vdXNlTW92ZShwb2ludCxGQUxTRSxGQUxTRSk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworQ1BERl9SZWN0IENQV0xfRWRpdEN0cmw6OkdldENvbnRlbnRSZWN0KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wRWRpdC0+R2V0Q29udGVudFJlY3QoKTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpTZXRFZGl0Q2FyZXQoRlhfQk9PTCBiVmlzaWJsZSkKK3sKKwlDUERGX1BvaW50IHB0SGVhZCgwLDApLHB0Rm9vdCgwLDApOworCisJaWYgKGJWaXNpYmxlKQorCXsKKwkJR2V0Q2FyZXRJbmZvKHB0SGVhZCxwdEZvb3QpOworCX0KKworCUNQVlRfV29yZFBsYWNlIHdwVGVtcCA9IG1fcEVkaXQtPkdldENhcmV0V29yZFBsYWNlKCk7CisJdGhpcy0+SU9uU2V0Q2FyZXQoYlZpc2libGUscHRIZWFkLHB0Rm9vdCx3cFRlbXApOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OkdldENhcmV0SW5mbyhDUERGX1BvaW50ICYgcHRIZWFkLCBDUERGX1BvaW50ICYgcHRGb290KSBjb25zdAoreworCWlmIChJRlhfRWRpdF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcEVkaXQtPkdldEl0ZXJhdG9yKCkpCisJeworCQlwSXRlcmF0b3ItPlNldEF0KG1fcEVkaXQtPkdldENhcmV0KCkpOworCQlDUFZUX1dvcmQgd29yZDsKKwkJQ1BWVF9MaW5lIGxpbmU7CisJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpCisJCXsKKwkJCXB0SGVhZC54ID0gd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoOworCQkJcHRIZWFkLnkgPSB3b3JkLnB0V29yZC55ICsgd29yZC5mQXNjZW50OworCQkJcHRGb290LnggPSB3b3JkLnB0V29yZC54ICsgd29yZC5mV2lkdGg7CisJCQlwdEZvb3QueSA9IHdvcmQucHRXb3JkLnkgKyB3b3JkLmZEZXNjZW50OworCQl9CisJCWVsc2UgaWYgKHBJdGVyYXRvci0+R2V0TGluZShsaW5lKSkKKwkJewkJCQkKKwkJCXB0SGVhZC54ID0gbGluZS5wdExpbmUueDsKKwkJCXB0SGVhZC55ID0gbGluZS5wdExpbmUueSArIGxpbmUuZkxpbmVBc2NlbnQ7CisJCQlwdEZvb3QueCA9IGxpbmUucHRMaW5lLng7CisJCQlwdEZvb3QueSA9IGxpbmUucHRMaW5lLnkgKyBsaW5lLmZMaW5lRGVzY2VudDsKKwkJfQorCX0KK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpHZXRDYXJldFBvcyhGWF9JTlQzMiYgeCwgRlhfSU5UMzImIHkpIGNvbnN0Cit7CisJQ1BERl9Qb2ludCBwdEhlYWQoMCwwKSwgcHRGb290KDAsMCk7CisKKwlHZXRDYXJldEluZm8ocHRIZWFkLHB0Rm9vdCk7CisKKwlQV0x0b1duZChwdEhlYWQsIHgsIHkpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OlNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsIGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsIGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QpCit7CisJaWYgKG1fcEVkaXRDYXJldCkKKwl7CisJCWlmICghSXNGb2N1c2VkKCkgfHwgbV9wRWRpdC0+SXNTZWxlY3RlZCgpKQorCQkJYlZpc2libGUgPSBGQUxTRTsKKworCQltX3BFZGl0Q2FyZXQtPlNldENhcmV0KGJWaXNpYmxlLCBwdEhlYWQsIHB0Rm9vdCk7CisJfQorfQorCitGWF9CT09MCUNQV0xfRWRpdEN0cmw6OklzTW9kaWZpZWQoKSBjb25zdAoreworCXJldHVybiBtX3BFZGl0LT5Jc01vZGlmaWVkKCk7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENQV0xfRWRpdEN0cmw6OkdldFRleHQoKSBjb25zdAoreworCXJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0Q3RybDo6U2V0U2VsKEZYX0lOVDMyIG5TdGFydENoYXIsRlhfSU5UMzIgbkVuZENoYXIpCit7CisJbV9wRWRpdC0+U2V0U2VsKG5TdGFydENoYXIsIG5FbmRDaGFyKTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpHZXRTZWwoRlhfSU5UMzIgJiBuU3RhcnRDaGFyLCBGWF9JTlQzMiAmIG5FbmRDaGFyICkgY29uc3QKK3sKKwltX3BFZGl0LT5HZXRTZWwoblN0YXJ0Q2hhciwgbkVuZENoYXIpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OkNsZWFyKCkKK3sKKwlpZiAoIUlzUmVhZE9ubHkoKSkKKwkJbV9wRWRpdC0+Q2xlYXIoKTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpTZWxlY3RBbGwoKQoreworCW1fcEVkaXQtPlNlbGVjdEFsbCgpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OlBhaW50KCkKK3sKKwlpZiAobV9wRWRpdCkKKwkJbV9wRWRpdC0+UGFpbnQoKTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpFbmFibGVSZWZyZXNoKEZYX0JPT0wgYlJlZnJlc2gpCit7CisJaWYgKG1fcEVkaXQpCisJCW1fcEVkaXQtPkVuYWJsZVJlZnJlc2goYlJlZnJlc2gpOworfQorCitGWF9JTlQzMiBDUFdMX0VkaXRDdHJsOjpHZXRDYXJldCgpIGNvbnN0Cit7CisJaWYgKG1fcEVkaXQpCisJCXJldHVybiBtX3BFZGl0LT5HZXRDYXJldCgpOworCisJcmV0dXJuIC0xOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OlNldENhcmV0KEZYX0lOVDMyIG5Qb3MpCit7CisJaWYgKG1fcEVkaXQpCisJCW1fcEVkaXQtPlNldENhcmV0KG5Qb3MpOworfQorCitGWF9JTlQzMiBDUFdMX0VkaXRDdHJsOjpHZXRUb3RhbFdvcmRzKCkgY29uc3QKK3sKKwlpZiAobV9wRWRpdCkKKwkJcmV0dXJuIG1fcEVkaXQtPkdldFRvdGFsV29yZHMoKTsKKworCXJldHVybiAwOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OlNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlpZiAobV9wRWRpdCkKKwkJbV9wRWRpdC0+U2V0U2Nyb2xsUG9zKHBvaW50KTsKK30KKworQ1BERl9Qb2ludCBDUFdMX0VkaXRDdHJsOjpHZXRTY3JvbGxQb3MoKSBjb25zdAoreworCWlmIChtX3BFZGl0KQorCQlyZXR1cm4gbV9wRWRpdC0+R2V0U2Nyb2xsUG9zKCk7CisKKwlyZXR1cm4gQ1BERl9Qb2ludCgwLjBmLCAwLjBmKTsKK30KKworQ1BERl9Gb250ICogQ1BXTF9FZGl0Q3RybDo6R2V0Q2FyZXRGb250KCkgY29uc3QKK3sKKwlGWF9JTlQzMiBuRm9udEluZGV4ID0gMDsKKworCWlmIChJRlhfRWRpdF9JdGVyYXRvciAqIHBJdGVyYXRvciA9IG1fcEVkaXQtPkdldEl0ZXJhdG9yKCkpCisJeworCQlwSXRlcmF0b3ItPlNldEF0KG1fcEVkaXQtPkdldENhcmV0KCkpOworCQlDUFZUX1dvcmQgd29yZDsKKwkJQ1BWVF9TZWN0aW9uIHNlY3Rpb247CisJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpCisJCXsKKwkJCW5Gb250SW5kZXggPSB3b3JkLm5Gb250SW5kZXg7CisJCX0KKwkJZWxzZSBpZiAoSGFzRmxhZyhQRVNfUklDSCkpCisJCXsKKwkJCWlmIChwSXRlcmF0b3ItPkdldFNlY3Rpb24oc2VjdGlvbikpCisJCQl7CQkJCQorCQkJCW5Gb250SW5kZXggPSBzZWN0aW9uLldvcmRQcm9wcy5uRm9udEluZGV4OworCQkJfQorCQl9CisJfQorCisJaWYgKElGWF9FZGl0X0ZvbnRNYXAgKiBwRm9udE1hcCA9IEdldEZvbnRNYXAoKSkKKwkJcmV0dXJuIHBGb250TWFwLT5HZXRQREZGb250KG5Gb250SW5kZXgpOworCWVsc2UKKwkJcmV0dXJuIE5VTEw7Cit9CisKK0ZYX0ZMT0FUIENQV0xfRWRpdEN0cmw6OkdldENhcmV0Rm9udFNpemUoKSBjb25zdAoreworCUZYX0ZMT0FUIGZGb250U2l6ZSA9IEdldEZvbnRTaXplKCk7CisKKwlpZiAoSUZYX0VkaXRfSXRlcmF0b3IgKiBwSXRlcmF0b3IgPSBtX3BFZGl0LT5HZXRJdGVyYXRvcigpKQorCXsKKwkJcEl0ZXJhdG9yLT5TZXRBdChtX3BFZGl0LT5HZXRDYXJldCgpKTsKKwkJQ1BWVF9Xb3JkIHdvcmQ7CisJCUNQVlRfU2VjdGlvbiBzZWN0aW9uOworCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQorCQl7CisJCQlmRm9udFNpemUgPSB3b3JkLmZGb250U2l6ZTsKKwkJfQorCQllbHNlIGlmIChIYXNGbGFnKFBFU19SSUNIKSkKKwkJeworCQkJaWYgKHBJdGVyYXRvci0+R2V0U2VjdGlvbihzZWN0aW9uKSkKKwkJCXsJCQkJCisJCQkJZkZvbnRTaXplID0gc2VjdGlvbi5Xb3JkUHJvcHMuZkZvbnRTaXplOworCQkJfQorCQl9CisJfQorCisJcmV0dXJuIGZGb250U2l6ZTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KQoreworCW1fcEVkaXQtPlNldFRleHQoY3NUZXh0KTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpDb3B5VGV4dCgpCit7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0Q3RybDo6UGFzdGVUZXh0KCkKK3sKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpDdXRUZXh0KCkKK3sKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpTaG93VlNjcm9sbEJhcihGWF9CT09MIGJTaG93KQoreworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6Okluc2VydFRleHQoRlhfTFBDV1NUUiBjc1RleHQpCit7CisJaWYgKCFJc1JlYWRPbmx5KCkpCisJCW1fcEVkaXQtPkluc2VydFRleHQoY3NUZXh0KTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpJbnNlcnRXb3JkKEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgbkNoYXJzZXQpCit7CisJaWYgKCFJc1JlYWRPbmx5KCkpCisJCW1fcEVkaXQtPkluc2VydFdvcmQod29yZCwgbkNoYXJzZXQpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6Okluc2VydFJldHVybigpCit7CisJaWYgKCFJc1JlYWRPbmx5KCkpCisJCW1fcEVkaXQtPkluc2VydFJldHVybigpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OkRlbGV0ZSgpCit7CisJaWYgKCFJc1JlYWRPbmx5KCkpCisJCW1fcEVkaXQtPkRlbGV0ZSgpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OkJhY2tzcGFjZSgpCit7CisJaWYgKCFJc1JlYWRPbmx5KCkpCisJCW1fcEVkaXQtPkJhY2tzcGFjZSgpOworfQorCitGWF9CT09MCUNQV0xfRWRpdEN0cmw6OkNhblVuZG8oKSBjb25zdAoreworCXJldHVybiAhSXNSZWFkT25seSgpICYmIG1fcEVkaXQtPkNhblVuZG8oKTsKK30KKworRlhfQk9PTAlDUFdMX0VkaXRDdHJsOjpDYW5SZWRvKCkgY29uc3QKK3sKKwlyZXR1cm4gIUlzUmVhZE9ubHkoKSAmJiBtX3BFZGl0LT5DYW5SZWRvKCk7Cit9CisKK3ZvaWQgQ1BXTF9FZGl0Q3RybDo6UmVkbygpCit7CisJaWYgKENhblJlZG8oKSkKKwkJbV9wRWRpdC0+UmVkbygpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OlVuZG8oKQoreworCWlmIChDYW5VbmRvKCkpCisJCW1fcEVkaXQtPlVuZG8oKTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpJT25TZXRTY3JvbGxJbmZvWShGWF9GTE9BVCBmUGxhdGVNaW4sIEZYX0ZMT0FUIGZQbGF0ZU1heCwgCisJCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIAorCQkJCQkJCQkJCQkJRlhfRkxPQVQgZlNtYWxsU3RlcCwgRlhfRkxPQVQgZkJpZ1N0ZXApCit7CisJUFdMX1NDUk9MTF9JTkZPIEluZm87CisKKwlJbmZvLmZQbGF0ZVdpZHRoID0gZlBsYXRlTWF4IC0gZlBsYXRlTWluOworCUluZm8uZkNvbnRlbnRNaW4gPSBmQ29udGVudE1pbjsKKwlJbmZvLmZDb250ZW50TWF4ID0gZkNvbnRlbnRNYXg7CisJSW5mby5mU21hbGxTdGVwID0gZlNtYWxsU3RlcDsKKwlJbmZvLmZCaWdTdGVwID0gZkJpZ1N0ZXA7CisKKwl0aGlzLT5Pbk5vdGlmeSh0aGlzLFBOTV9TRVRTQ1JPTExJTkZPLFNCVF9WU0NST0xMLChGWF9JTlRQVFIpJkluZm8pOworCisvLwlQV0xfVFJBQ0UoInNldCBzY3JvbGwgaW5mbzolZlxuIixmQ29udGVudE1heCAtIGZDb250ZW50TWluKTsKKworCWlmIChJc0Zsb2F0QmlnZ2VyKEluZm8uZlBsYXRlV2lkdGgsSW5mby5mQ29udGVudE1heC1JbmZvLmZDb250ZW50TWluKQorCQl8fCBJc0Zsb2F0RXF1YWwoSW5mby5mUGxhdGVXaWR0aCxJbmZvLmZDb250ZW50TWF4LUluZm8uZkNvbnRlbnRNaW4pKQorCXsKKwkJdGhpcy0+U2hvd1ZTY3JvbGxCYXIoRkFMU0UpOwkJCisJfQorCWVsc2UKKwl7CisJCXRoaXMtPlNob3dWU2Nyb2xsQmFyKFRSVUUpOworCX0KK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpJT25TZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KQoreworLy8JUFdMX1RSQUNFKCJzZXQgc2Nyb2xsIHBvc2l0aW9uOiVmXG4iLGZ5KTsKKwl0aGlzLT5Pbk5vdGlmeSh0aGlzLFBOTV9TRVRTQ1JPTExQT1MsU0JUX1ZTQ1JPTEwsKEZYX0lOVFBUUikmZnkpOworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OklPblNldENhcmV0KEZYX0JPT0wgYlZpc2libGUsIGNvbnN0IENQREZfUG9pbnQgJiBwdEhlYWQsIGNvbnN0IENQREZfUG9pbnQgJiBwdEZvb3QsIGNvbnN0IENQVlRfV29yZFBsYWNlJiBwbGFjZSkKK3sKKwlQV0xfQ0FSRVRfSU5GTyBjSW5mbzsKKwljSW5mby5iVmlzaWJsZSA9IGJWaXNpYmxlOworCWNJbmZvLnB0SGVhZCA9IHB0SGVhZDsKKwljSW5mby5wdEZvb3QgPSBwdEZvb3Q7CisKKwl0aGlzLT5Pbk5vdGlmeSh0aGlzLFBOTV9TRVRDQVJFVElORk8sKEZYX0lOVFBUUikmY0luZm8sKEZYX0lOVFBUUilOVUxMKTsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpJT25DYXJldENoYW5nZShjb25zdCBDUFZUX1NlY1Byb3BzICYgc2VjUHJvcHMsIGNvbnN0IENQVlRfV29yZFByb3BzICYgd29yZFByb3BzKQoreworfQorCit2b2lkIENQV0xfRWRpdEN0cmw6OklPbkNvbnRlbnRDaGFuZ2UoY29uc3QgQ1BERl9SZWN0JiByY0NvbnRlbnQpCit7CisJaWYgKHRoaXMtPklzVmFsaWQoKSkKKwl7CisJCWlmIChtX3BFZGl0Tm90aWZ5KQorCQl7CisJCQltX3BFZGl0Tm90aWZ5LT5PbkNvbnRlbnRDaGFuZ2UocmNDb250ZW50KTsKKwkJfQorCX0KK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpJT25JbnZhbGlkYXRlUmVjdChDUERGX1JlY3QgKiBwUmVjdCkKK3sKKwl0aGlzLT5JbnZhbGlkYXRlUmVjdChwUmVjdCk7Cit9CisKK0ZYX0lOVDMyIENQV0xfRWRpdEN0cmw6OkdldENoYXJTZXQoKSBjb25zdAoreworCWlmIChtX25DaGFyU2V0IDwgMCkKKwkJcmV0dXJuIERFRkFVTFRfQ0hBUlNFVDsgCisJZWxzZQorCQlyZXR1cm4gbV9uQ2hhclNldDsKK30KKwordm9pZCBDUFdMX0VkaXRDdHJsOjpHZXRUZXh0UmFuZ2UoY29uc3QgQ1BERl9SZWN0JiByZWN0LCBGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIpIGNvbnN0Cit7CisJblN0YXJ0Q2hhciA9IG1fcEVkaXQtPldvcmRQbGFjZVRvV29yZEluZGV4KG1fcEVkaXQtPlNlYXJjaFdvcmRQbGFjZShDUERGX1BvaW50KHJlY3QubGVmdCwgcmVjdC50b3ApKSk7CisJbkVuZENoYXIgPSBtX3BFZGl0LT5Xb3JkUGxhY2VUb1dvcmRJbmRleChtX3BFZGl0LT5TZWFyY2hXb3JkUGxhY2UoQ1BERl9Qb2ludChyZWN0LnJpZ2h0LCByZWN0LmJvdHRvbSkpKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9FZGl0Q3RybDo6R2V0VGV4dChGWF9JTlQzMiAmIG5TdGFydENoYXIsIEZYX0lOVDMyICYgbkVuZENoYXIpIGNvbnN0Cit7CisJQ1BWVF9Xb3JkUGxhY2Ugd3BTdGFydCA9IG1fcEVkaXQtPldvcmRJbmRleFRvV29yZFBsYWNlKG5TdGFydENoYXIpOworCUNQVlRfV29yZFBsYWNlIHdwRW5kID0gbV9wRWRpdC0+V29yZEluZGV4VG9Xb3JkUGxhY2UobkVuZENoYXIpOworCXJldHVybiBtX3BFZGl0LT5HZXRSYW5nZVRleHQoQ1BWVF9Xb3JkUmFuZ2Uod3BTdGFydCwgd3BFbmQpKTsKK30KKwordm9pZAlDUFdMX0VkaXRDdHJsOjpTZXRSZWFkeVRvSW5wdXQoKQoreworCWlmIChtX2JNb3VzZURvd24pCisJeworCQlSZWxlYXNlQ2FwdHVyZSgpOworCQltX2JNb3VzZURvd24gPSBGQUxTRTsKKwl9Cit9CmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0ZvbnRNYXAuY3BwIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9Gb250TWFwLmNwcAppbmRleCAxZTIyNTlmLi5jNjU2ZjBjIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0ZvbnRNYXAuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfRm9udE1hcC5jcHAKQEAgLTEsNjAxICsxLDYwMSBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Gb250TWFwLmgiDQotDQotI2RlZmluZSBERUZBVUxUX0ZPTlRfTkFNRQkJCSJIZWx2ZXRpY2EiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfRm9udE1hcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0ZvbnRNYXA6OkNQV0xfRm9udE1hcChJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIpIDogCQ0KLQltX3BQREZEb2MoTlVMTCksDQotCW1fcFN5c3RlbUhhbmRsZXIocFN5c3RlbUhhbmRsZXIpDQotew0KLQlBU1NFUlQobV9wU3lzdGVtSGFuZGxlciAhPSBOVUxMKTsNCi19DQotDQotQ1BXTF9Gb250TWFwOjp+Q1BXTF9Gb250TWFwKCkNCi17DQotCWlmIChtX3BQREZEb2MpDQotCXsNCi0JCWRlbGV0ZSBtX3BQREZEb2M7DQotCQltX3BQREZEb2MgPSBOVUxMOw0KLQl9DQotDQotCUVtcHR5KCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Gb250TWFwOjpTZXRTeXN0ZW1IYW5kbGVyKElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlcikNCi17DQotCW1fcFN5c3RlbUhhbmRsZXIgPSBwU3lzdGVtSGFuZGxlcjsNCi19DQotDQotQ1BERl9Eb2N1bWVudCogQ1BXTF9Gb250TWFwOjpHZXREb2N1bWVudCgpDQotew0KLQlpZiAoIW1fcFBERkRvYykNCi0Jew0KLQkJaWYgKENQREZfTW9kdWxlTWdyOjpHZXQoKSkNCi0JCXsNCi0JCQltX3BQREZEb2MgPSBGWF9ORVcgQ1BERl9Eb2N1bWVudDsNCi0JCQltX3BQREZEb2MtPkNyZWF0ZU5ld0RvYygpOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBtX3BQREZEb2M7DQotfQ0KLQ0KLUNQREZfRm9udCogQ1BXTF9Gb250TWFwOjpHZXRQREZGb250KEZYX0lOVDMyIG5Gb250SW5kZXgpDQotew0KLQlpZiAobkZvbnRJbmRleCA+PTAgJiYgbkZvbnRJbmRleCA8IG1fYURhdGEuR2V0U2l6ZSgpKQ0KLQl7DQotCQlpZiAoQ1BXTF9Gb250TWFwX0RhdGEqIHBEYXRhID0gbV9hRGF0YS5HZXRBdChuRm9udEluZGV4KSkNCi0JCXsNCi0JCQlyZXR1cm4gcERhdGEtPnBGb250Ow0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX0ZvbnRNYXA6OkdldFBERkZvbnRBbGlhcyhGWF9JTlQzMiBuRm9udEluZGV4KQ0KLXsNCi0JaWYgKG5Gb250SW5kZXggPj0wICYmIG5Gb250SW5kZXggPCBtX2FEYXRhLkdldFNpemUoKSkNCi0Jew0KLQkJaWYgKENQV0xfRm9udE1hcF9EYXRhKiBwRGF0YSA9IG1fYURhdGEuR2V0QXQobkZvbnRJbmRleCkpDQotCQl7DQotCQkJcmV0dXJuIHBEYXRhLT5zRm9udE5hbWU7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuICIiOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfRm9udE1hcDo6S25vd1dvcmQoRlhfSU5UMzIgbkZvbnRJbmRleCwgRlhfV09SRCB3b3JkKQ0KLXsNCi0JaWYgKG5Gb250SW5kZXggPj0wICYmIG5Gb250SW5kZXggPCBtX2FEYXRhLkdldFNpemUoKSkNCi0Jew0KLQkJaWYgKG1fYURhdGEuR2V0QXQobkZvbnRJbmRleCkpDQotCQl7CQ0KLQkJCXJldHVybiBDaGFyQ29kZUZyb21Vbmljb2RlKG5Gb250SW5kZXgsIHdvcmQpID49IDA7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX0ZvbnRNYXA6OkdldFdvcmRGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuQ2hhcnNldCwgRlhfSU5UMzIgbkZvbnRJbmRleCkNCi17DQotCWlmIChuRm9udEluZGV4ID4gMCkNCi0Jew0KLQkJaWYgKEtub3dXb3JkKG5Gb250SW5kZXgsIHdvcmQpKQ0KLQkJCXJldHVybiBuRm9udEluZGV4Ow0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKGNvbnN0IENQV0xfRm9udE1hcF9EYXRhKiBwRGF0YSA9IEdldEZvbnRNYXBEYXRhKDApKQ0KLQkJew0KLQkJCWlmIChuQ2hhcnNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgDQotCQkJCXBEYXRhLT5uQ2hhcnNldCA9PSBTWU1CT0xfQ0hBUlNFVCB8fCANCi0JCQkJbkNoYXJzZXQgPT0gcERhdGEtPm5DaGFyc2V0KQ0KLQkJCXsNCi0JCQkJaWYgKEtub3dXb3JkKDAsIHdvcmQpKQ0KLQkJCQl7DQotCQkJCQlyZXR1cm4gMDsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlGWF9JTlQzMiBuTmV3Rm9udEluZGV4ID0gLTE7DQotDQotCW5OZXdGb250SW5kZXggPSB0aGlzLT5HZXRGb250SW5kZXgoR2V0TmF0aXZlRm9udE5hbWUobkNoYXJzZXQpLCBuQ2hhcnNldCwgVFJVRSk7DQotCWlmIChuTmV3Rm9udEluZGV4ID49IDApDQotCXsNCi0JCWlmIChLbm93V29yZChuTmV3Rm9udEluZGV4LCB3b3JkKSkNCi0JCQlyZXR1cm4gbk5ld0ZvbnRJbmRleDsNCi0JfQ0KLQ0KLQluTmV3Rm9udEluZGV4ID0gdGhpcy0+R2V0Rm9udEluZGV4KCJBcmlhbCBVbmljb2RlIE1TIiwgREVGQVVMVF9DSEFSU0VULCBGQUxTRSk7DQotCWlmIChuTmV3Rm9udEluZGV4ID49IDApDQotCXsNCi0JCWlmIChLbm93V29yZChuTmV3Rm9udEluZGV4LCB3b3JkKSkNCi0JCXJldHVybiBuTmV3Rm9udEluZGV4Ow0KLQl9DQotDQotCXJldHVybiAtMTsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpDaGFyQ29kZUZyb21Vbmljb2RlKEZYX0lOVDMyIG5Gb250SW5kZXgsIEZYX1dPUkQgd29yZCkNCi17DQotCWlmIChDUFdMX0ZvbnRNYXBfRGF0YSogcERhdGEgPSBtX2FEYXRhLkdldEF0KG5Gb250SW5kZXgpKQ0KLQl7DQotCQlpZiAocERhdGEtPnBGb250KQ0KLQkJew0KLQkJCWlmIChwRGF0YS0+cEZvbnQtPklzVW5pY29kZUNvbXBhdGlibGUoKSkNCi0JCQl7DQotCQkJCWludCBuQ2hhckNvZGUgPSBwRGF0YS0+cEZvbnQtPkNoYXJDb2RlRnJvbVVuaWNvZGUod29yZCk7DQotCQkJCXBEYXRhLT5wRm9udC0+R2x5cGhGcm9tQ2hhckNvZGUobkNoYXJDb2RlKTsNCi0JCQkJcmV0dXJuIG5DaGFyQ29kZTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJaWYgKHdvcmQgPCAweEZGKQ0KLQkJCQkJcmV0dXJuIHdvcmQ7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCXJldHVybiAtMTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Gb250TWFwOjpHZXROYXRpdmVGb250TmFtZShGWF9JTlQzMiBuQ2hhcnNldCkNCi17DQotCS8vc2VhcmNoaW5nIG5hdGl2ZSBmb250IGlzIHNsb3csIHNvIHdlIG11c3Qgc2F2ZSB0aW1lDQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYU5hdGl2ZUZvbnQuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCWlmIChDUFdMX0ZvbnRNYXBfTmF0aXZlKiBwRGF0YSA9IG1fYU5hdGl2ZUZvbnQuR2V0QXQoaSkpDQotCQl7DQotCQkJaWYgKHBEYXRhLT5uQ2hhcnNldCA9PSBuQ2hhcnNldCkNCi0JCQkJcmV0dXJuIHBEYXRhLT5zRm9udE5hbWU7DQotCQl9DQotCX0NCi0NCi0JQ0ZYX0J5dGVTdHJpbmcgc05ldyA9IEdldE5hdGl2ZUZvbnQobkNoYXJzZXQpOw0KLQ0KLQlpZiAoIXNOZXcuSXNFbXB0eSgpKQ0KLQl7DQotCQlDUFdMX0ZvbnRNYXBfTmF0aXZlKiBwTmV3RGF0YSA9IG5ldyBDUFdMX0ZvbnRNYXBfTmF0aXZlOw0KLQkJcE5ld0RhdGEtPm5DaGFyc2V0ID0gbkNoYXJzZXQ7DQotCQlwTmV3RGF0YS0+c0ZvbnROYW1lID0gc05ldzsNCi0NCi0JCW1fYU5hdGl2ZUZvbnQuQWRkKHBOZXdEYXRhKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gc05ldzsNCi19DQotDQotdm9pZCBDUFdMX0ZvbnRNYXA6OkVtcHR5KCkNCi17DQotCXsNCi0JCWZvciAoRlhfSU5UMzIgaT0wLCBzej1tX2FEYXRhLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJCWRlbGV0ZSBtX2FEYXRhLkdldEF0KGkpOw0KLQ0KLQkJbV9hRGF0YS5SZW1vdmVBbGwoKTsNCi0JfQ0KLQl7DQotCQlmb3IgKEZYX0lOVDMyIGk9MCwgc3o9bV9hTmF0aXZlRm9udC5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQlkZWxldGUgbV9hTmF0aXZlRm9udC5HZXRBdChpKTsNCi0NCi0JCW1fYU5hdGl2ZUZvbnQuUmVtb3ZlQWxsKCk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0ZvbnRNYXA6OkluaXRpYWwoRlhfTFBDU1RSIGZvbnRuYW1lKQ0KLXsNCi0JQ0ZYX0J5dGVTdHJpbmcgc0ZvbnROYW1lID0gZm9udG5hbWU7DQotDQotCWlmIChzRm9udE5hbWUuSXNFbXB0eSgpKQ0KLQkJc0ZvbnROYW1lID0gREVGQVVMVF9GT05UX05BTUU7DQotDQotCUdldEZvbnRJbmRleChzRm9udE5hbWUsIEFOU0lfQ0hBUlNFVCwgRkFMU0UpOw0KLQ0KLQkvL0dldEZvbnRJbmRleCh0aGlzLT5HZXROYXRpdmVGb250TmFtZShuQ2hhcnNldCksIG5DaGFyc2V0KTsNCi19DQotCQ0KLQ0KLS8qDQotTGlzdCBvZiBjdXJyZW50bHkgc3VwcG9ydGVkIHN0YW5kYXJkIGZvbnRzOg0KLUNvdXJpZXIsIENvdXJpZXItQm9sZCwgQ291cmllci1Cb2xkT2JsaXF1ZSwgQ291cmllci1PYmxpcXVlDQotSGVsdmV0aWNhLCBIZWx2ZXRpY2EtQm9sZCwgSGVsdmV0aWNhLUJvbGRPYmxpcXVlLCBIZWx2ZXRpY2EtT2JsaXF1ZQ0KLVRpbWVzLVJvbWFuLCBUaW1lcy1Cb2xkLCBUaW1lcy1JdGFsaWMsIFRpbWVzLUJvbGRJdGFsaWMNCi1TeW1ib2wsIFphcGZEaW5nYmF0cw0KLSovDQotDQotY29uc3QgY2hhciogZ19zREVTdGFuZGFyZEZvbnROYW1lW10gPSB7IkNvdXJpZXIiLCAiQ291cmllci1Cb2xkIiwgIkNvdXJpZXItQm9sZE9ibGlxdWUiLCAiQ291cmllci1PYmxpcXVlIiwNCi0JIkhlbHZldGljYSIsICJIZWx2ZXRpY2EtQm9sZCIsICJIZWx2ZXRpY2EtQm9sZE9ibGlxdWUiLCAiSGVsdmV0aWNhLU9ibGlxdWUiLA0KLQkiVGltZXMtUm9tYW4iLCAiVGltZXMtQm9sZCIsICJUaW1lcy1JdGFsaWMiLCAiVGltZXMtQm9sZEl0YWxpYyIsDQotCSJTeW1ib2wiLCAiWmFwZkRpbmdiYXRzIn07DQotDQotRlhfQk9PTAlDUFdMX0ZvbnRNYXA6OklzU3RhbmRhcmRGb250KGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUpDQotew0KLQlmb3IgKEZYX0lOVDMyIGk9MDsgaTwxNDsgaSsrKQ0KLQl7DQotCQlpZiAoc0ZvbnROYW1lID09IGdfc0RFU3RhbmRhcmRGb250TmFtZVtpXSkNCi0JCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfRm9udE1hcDo6RmluZEZvbnQoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSwgRlhfSU5UMzIgbkNoYXJzZXQpDQotew0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FEYXRhLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ1BXTF9Gb250TWFwX0RhdGEqIHBEYXRhID0gbV9hRGF0YS5HZXRBdChpKSkNCi0JCXsNCi0JCQlpZiAobkNoYXJzZXQgPT0gREVGQVVMVF9DSEFSU0VUIHx8IG5DaGFyc2V0ID09IHBEYXRhLT5uQ2hhcnNldCkNCi0JCQl7DQotCQkJCWlmIChzRm9udE5hbWUuSXNFbXB0eSgpIHx8IHBEYXRhLT5zRm9udE5hbWUgPT0gc0ZvbnROYW1lKQ0KLQkJCQkJcmV0dXJuIGk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCXJldHVybiAtMTsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpHZXRGb250SW5kZXgoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSwgRlhfSU5UMzIgbkNoYXJzZXQsIEZYX0JPT0wgYkZpbmQpDQotew0KLQlGWF9JTlQzMiBuRm9udEluZGV4ID0gRmluZEZvbnQoRW5jb2RlRm9udEFsaWFzKHNGb250TmFtZSwgbkNoYXJzZXQpLCBuQ2hhcnNldCk7DQotCWlmIChuRm9udEluZGV4ID49IDApIHJldHVybiBuRm9udEluZGV4Ow0KLQ0KLS8vCW5Gb250SW5kZXggPSBGaW5kRm9udCgiIiwgbkNoYXJzZXQpOw0KLS8vCWlmIChuRm9udEluZGV4ID49IDApIHJldHVybiBuRm9udEluZGV4Ow0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBzQWxpYXM7DQotCUNQREZfRm9udCogcEZvbnQgPSBOVUxMOw0KLQ0KLQlpZiAoYkZpbmQpDQotCQlwRm9udCA9IEZpbmRGb250U2FtZUNoYXJzZXQoc0FsaWFzLCBuQ2hhcnNldCk7DQotDQotCWlmICghcEZvbnQpDQotCXsNCi0JCUNGWF9CeXRlU3RyaW5nIHNUZW1wID0gc0ZvbnROYW1lOw0KLQkJcEZvbnQgPSBBZGRGb250VG9Eb2N1bWVudChHZXREb2N1bWVudCgpLCBzVGVtcCwgbkNoYXJzZXQpOw0KLQ0KLQkJLyoNCi0JCWlmIChGaW5kRm9udChzQWxpYXMpKQ0KLQkJew0KLQkJCXNBbGlhcyA9IEVuY29kZUZvbnRBbGlhcyhzVGVtcCwgbkNoYXJzZXQpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJKi8NCi0JCXsNCi0JCQlzQWxpYXMgPSBFbmNvZGVGb250QWxpYXMoc1RlbXAsIG5DaGFyc2V0KTsNCi0JCX0JCQ0KLQl9DQotDQotCUFkZGVkRm9udChwRm9udCwgc0FsaWFzKTsNCi0NCi0JcmV0dXJuIEFkZEZvbnREYXRhKHBGb250LCBzQWxpYXMsIG5DaGFyc2V0KTsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpHZXRQV0xGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuQ2hhcnNldCkNCi17DQotCUZYX0lOVDMyIG5GaW5kID0gLTE7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYURhdGEuR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCWlmIChDUFdMX0ZvbnRNYXBfRGF0YSogcERhdGEgPSBtX2FEYXRhLkdldEF0KGkpKQ0KLQkJew0KLQkJCWlmIChwRGF0YS0+bkNoYXJzZXQgPT0gbkNoYXJzZXQpDQotCQkJew0KLQkJCQluRmluZCA9IGk7DQotCQkJCWJyZWFrOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlDUERGX0ZvbnQqIHBOZXdGb250ID0gR2V0UERGRm9udChuRmluZCk7DQotDQotCWlmICghcE5ld0ZvbnQpIHJldHVybiAtMTsNCi0NCi0JLyoNCi0JaWYgKENQREZfRm9udCogcEZvbnQgPSBHZXRQREZGb250KG5GaW5kKSkNCi0Jew0KLQkJUFdMRm9udC5BZGRXb3JkVG9Gb250RGljdChwRm9udERpY3QsIHdvcmQpOw0KLQl9DQotCSovDQotDQotI2lmZGVmIEZPWElUX0NIUk9NRV9CVUlMRA0KLSAgQ0ZYX0J5dGVTdHJpbmcgc0FsaWFzID0gRW5jb2RlRm9udEFsaWFzKCJBcmlhbF9DaHJvbWUiLCBuQ2hhcnNldCk7DQotI2Vsc2UNCi0JQ0ZYX0J5dGVTdHJpbmcgc0FsaWFzID0gRW5jb2RlRm9udEFsaWFzKCJBcmlhbF9Gb3hpdCIsIG5DaGFyc2V0KTsNCi0jZW5kaWYNCi0JQWRkZWRGb250KHBOZXdGb250LCBzQWxpYXMpOw0KLQ0KLQlyZXR1cm4gQWRkRm9udERhdGEocE5ld0ZvbnQsIHNBbGlhcywgbkNoYXJzZXQpOw0KLX0NCi0NCi1DUERGX0ZvbnQqIENQV0xfRm9udE1hcDo6RmluZEZvbnRTYW1lQ2hhcnNldChDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcywgRlhfSU5UMzIgbkNoYXJzZXQpDQotew0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpBZGRGb250RGF0YShDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcywgRlhfSU5UMzIgbkNoYXJzZXQpDQotew0KLQlDUFdMX0ZvbnRNYXBfRGF0YSogcE5ld0RhdGEgPSBuZXcgQ1BXTF9Gb250TWFwX0RhdGE7DQotCXBOZXdEYXRhLT5wRm9udCA9IHBGb250Ow0KLQlwTmV3RGF0YS0+c0ZvbnROYW1lID0gc0ZvbnRBbGlhczsNCi0JcE5ld0RhdGEtPm5DaGFyc2V0ID0gbkNoYXJzZXQ7DQotDQotCW1fYURhdGEuQWRkKHBOZXdEYXRhKTsNCi0NCi0JcmV0dXJuIG1fYURhdGEuR2V0U2l6ZSgpIC0xOw0KLX0NCi0NCi12b2lkIENQV0xfRm9udE1hcDo6QWRkZWRGb250KENQREZfRm9udCogcEZvbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzKQ0KLXsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Gb250TWFwOjpHZXRGb250TmFtZShGWF9JTlQzMiBuRm9udEluZGV4KQ0KLXsNCi0JaWYgKG5Gb250SW5kZXggPj0wICYmIG5Gb250SW5kZXggPCBtX2FEYXRhLkdldFNpemUoKSkNCi0Jew0KLQkJaWYgKENQV0xfRm9udE1hcF9EYXRhKiBwRGF0YSA9IG1fYURhdGEuR2V0QXQobkZvbnRJbmRleCkpDQotCQl7DQotCQkJcmV0dXJuIHBEYXRhLT5zRm9udE5hbWU7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuICIiOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX0ZvbnRNYXA6OkdldE5hdGl2ZUZvbnQoRlhfSU5UMzIgbkNoYXJzZXQpDQotew0KLQlDRlhfQnl0ZVN0cmluZyBzRm9udE5hbWU7DQotDQotCWlmIChuQ2hhcnNldCA9PSBERUZBVUxUX0NIQVJTRVQpDQotCQluQ2hhcnNldCA9IEdldE5hdGl2ZUNoYXJzZXQoKTsNCi0NCi0Jc0ZvbnROYW1lID0gR2V0RGVmYXVsdEZvbnRCeUNoYXJzZXQobkNoYXJzZXQpOw0KLQ0KLQlpZiAobV9wU3lzdGVtSGFuZGxlcikNCi0Jew0KLQkJaWYgKG1fcFN5c3RlbUhhbmRsZXItPkZpbmROYXRpdmVUcnVlVHlwZUZvbnQobkNoYXJzZXQsIHNGb250TmFtZSkpDQotCQkJcmV0dXJuIHNGb250TmFtZTsNCi0NCi0JCXNGb250TmFtZSA9IG1fcFN5c3RlbUhhbmRsZXItPkdldE5hdGl2ZVRydWVUeXBlRm9udChuQ2hhcnNldCk7DQotCX0NCi0NCi0JcmV0dXJuIHNGb250TmFtZTsNCi19DQotDQotQ1BERl9Gb250KiBDUFdMX0ZvbnRNYXA6OkFkZEZvbnRUb0RvY3VtZW50KENQREZfRG9jdW1lbnQqIHBEb2MsIENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUsIEZYX0JZVEUgbkNoYXJzZXQpDQotew0KLQlpZiAoSXNTdGFuZGFyZEZvbnQoc0ZvbnROYW1lKSkNCi0JCXJldHVybiBBZGRTdGFuZGFyZEZvbnQocERvYywgc0ZvbnROYW1lKTsNCi0JZWxzZQ0KLQkJcmV0dXJuIEFkZFN5c3RlbUZvbnQocERvYywgc0ZvbnROYW1lLCBuQ2hhcnNldCk7DQotfQ0KLQ0KLUNQREZfRm9udCogQ1BXTF9Gb250TWFwOjpBZGRTdGFuZGFyZEZvbnQoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSkNCi17DQotCWlmICghcERvYykgcmV0dXJuIE5VTEw7DQotDQotCUNQREZfRm9udCogcEZvbnQgPSBOVUxMOw0KLQ0KLQlpZiAoc0ZvbnROYW1lID09ICJaYXBmRGluZ2JhdHMiKQ0KLQkJcEZvbnQgPSBwRG9jLT5BZGRTdGFuZGFyZEZvbnQoc0ZvbnROYW1lLCBOVUxMKTsNCi0JZWxzZQ0KLQl7DQotCQlDUERGX0ZvbnRFbmNvZGluZyBmZShQREZGT05UX0VOQ09ESU5HX1dJTkFOU0kpOw0KLQkJcEZvbnQgPSBwRG9jLT5BZGRTdGFuZGFyZEZvbnQoc0ZvbnROYW1lLCAmZmUpOw0KLQl9DQotDQotCXJldHVybiBwRm9udDsNCi19DQotDQotQ1BERl9Gb250KiBDUFdMX0ZvbnRNYXA6OkFkZFN5c3RlbUZvbnQoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSwgRlhfQllURSBuQ2hhcnNldCkNCi17DQotCWlmICghcERvYykgcmV0dXJuIE5VTEw7DQotDQotCWlmIChzRm9udE5hbWUuSXNFbXB0eSgpKSBzRm9udE5hbWUgPSBHZXROYXRpdmVGb250KG5DaGFyc2V0KTsNCi0JaWYgKG5DaGFyc2V0ID09IERFRkFVTFRfQ0hBUlNFVCkgbkNoYXJzZXQgPSBHZXROYXRpdmVDaGFyc2V0KCk7DQotDQotCWlmIChtX3BTeXN0ZW1IYW5kbGVyKQ0KLQkJcmV0dXJuIG1fcFN5c3RlbUhhbmRsZXItPkFkZE5hdGl2ZVRydWVUeXBlRm9udFRvUERGKHBEb2MsIHNGb250TmFtZSwgbkNoYXJzZXQpOw0KLQkNCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfRm9udE1hcDo6RW5jb2RlRm9udEFsaWFzKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUsIEZYX0lOVDMyIG5DaGFyc2V0KQ0KLXsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1Bvc3RmaXg7DQotCXNQb3N0Zml4LkZvcm1hdCgiXyUwMlgiLCBuQ2hhcnNldCk7DQotCXJldHVybiBFbmNvZGVGb250QWxpYXMoc0ZvbnROYW1lKSArIHNQb3N0Zml4Ow0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX0ZvbnRNYXA6OkVuY29kZUZvbnRBbGlhcyhjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lKQ0KLXsNCi0JQ0ZYX0J5dGVTdHJpbmcgc1JldCA9IHNGb250TmFtZTsNCi0Jc1JldC5SZW1vdmUoJyAnKTsNCi0JcmV0dXJuIHNSZXQ7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfRm9udE1hcDo6R2V0Rm9udE1hcENvdW50KCkgY29uc3QNCi17DQotCXJldHVybiBtX2FEYXRhLkdldFNpemUoKTsNCi19DQotDQotY29uc3QgQ1BXTF9Gb250TWFwX0RhdGEqIENQV0xfRm9udE1hcDo6R2V0Rm9udE1hcERhdGEoRlhfSU5UMzIgbkluZGV4KSBjb25zdA0KLXsNCi0JaWYgKG5JbmRleCA+PTAgJiYgbkluZGV4IDwgbV9hRGF0YS5HZXRTaXplKCkpDQotCXsNCi0JCXJldHVybiBtX2FEYXRhLkdldEF0KG5JbmRleCk7DQotCX0NCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfRm9udE1hcDo6R2V0TmF0aXZlQ2hhcnNldCgpDQotew0KLQlGWF9CWVRFIG5DaGFyc2V0ID0gQU5TSV9DSEFSU0VUOw0KLQlGWF9JTlQzMiBpQ29kZVBhZ2UgPSBGWFNZU19HZXRBQ1AoKTsNCi0Jc3dpdGNoIChpQ29kZVBhZ2UpDQotCXsNCi0JY2FzZSA5MzI6Ly9KYXBhbg0KLQkJbkNoYXJzZXQgPSBTSElGVEpJU19DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgOTM2Oi8vQ2hpbmVzZSAoUFJDLCBTaW5nYXBvcmUpDQotCQluQ2hhcnNldCA9IEdCMjMxMl9DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgOTUwOi8vQ2hpbmVzZSAoVGFpd2FuOyBIb25nIEtvbmcgU0FSLCBQUkMpDQotCQluQ2hhcnNldCA9IEdCMjMxMl9DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgMTI1MjovL1dpbmRvd3MgMy4xIExhdGluIDEgKFVTLCBXZXN0ZXJuIEV1cm9wZSkNCi0JCW5DaGFyc2V0ID0gQU5TSV9DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgODc0Oi8vVGhhaQ0KLQkJbkNoYXJzZXQgPSBUSEFJX0NIQVJTRVQ7DQotCQlicmVhazsNCi0JY2FzZSA5NDk6Ly9Lb3JlYW4NCi0JCW5DaGFyc2V0ID0gSEFOR1VMX0NIQVJTRVQ7DQotCQlicmVhazsNCi0JY2FzZSAxMjAwOi8vVW5pY29kZSAoQk1QIG9mIElTTyAxMDY0NikNCi0JCW5DaGFyc2V0ID0gQU5TSV9DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgMTI1MDovL1dpbmRvd3MgMy4xIEVhc3Rlcm4gRXVyb3BlYW4NCi0JCW5DaGFyc2V0ID0gRUFTVEVVUk9QRV9DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgMTI1MTovL1dpbmRvd3MgMy4xIEN5cmlsbGljDQotCQluQ2hhcnNldCA9IFJVU1NJQU5fQ0hBUlNFVDsNCi0JCWJyZWFrOw0KLQljYXNlIDEyNTM6Ly9XaW5kb3dzIDMuMSBHcmVlaw0KLQkJbkNoYXJzZXQgPSBHUkVFS19DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgMTI1NDovL1dpbmRvd3MgMy4xIFR1cmtpc2gNCi0JCW5DaGFyc2V0ID0gVFVSS0lTSF9DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgMTI1NTovL0hlYnJldw0KLQkJbkNoYXJzZXQgPSBIRUJSRVdfQ0hBUlNFVDsNCi0JCWJyZWFrOw0KLQljYXNlIDEyNTY6Ly9BcmFiaWMNCi0JCW5DaGFyc2V0ID0gQVJBQklDX0NIQVJTRVQ7DQotCQlicmVhazsNCi0JY2FzZSAxMjU3Oi8vQmFsdGljDQotCQluQ2hhcnNldCA9IEJBTFRJQ19DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgMTI1ODovL1ZpZXRuYW1lc2UNCi0JCW5DaGFyc2V0ID0gVklFVE5BTUVTRV9DSEFSU0VUOw0KLQkJYnJlYWs7DQotCWNhc2UgMTM2MTovL0tvcmVhbihKb2hhYikNCi0JCW5DaGFyc2V0ID0gSk9IQUJfQ0hBUlNFVDsNCi0JCWJyZWFrOw0KLQl9DQotCXJldHVybiBuQ2hhcnNldDsNCi19DQotDQotY29uc3QgQ1BXTF9Gb250TWFwOjpDaGFyc2V0Rm9udE1hcCBDUFdMX0ZvbnRNYXA6OmRlZmF1bHRUVEZNYXBbXSA9IHsNCi0JeyBBTlNJX0NIQVJTRVQsICJIZWx2ZXRpY2EiIH0sDQotCXsgR0IyMzEyX0NIQVJTRVQsICJTaW1TdW4iIH0sDQotCXsgQ0hJTkVTRUJJRzVfQ0hBUlNFVCwgIk1pbmdMaVUiIH0sDQotCXsgU0hJRlRKSVNfQ0hBUlNFVCwgIk1TIEdvdGhpYyIgfSwNCi0JeyBIQU5HVUxfQ0hBUlNFVCwgIkJhdGFuZyIgfSwNCi0JeyBSVVNTSUFOX0NIQVJTRVQsICJBcmlhbCIgfSwNCi0JeyBFQVNURVVST1BFX0NIQVJTRVQsICJUYWhvbWEiIH0sDQotCXsgQVJBQklDX0NIQVJTRVQsICJBcmlhbCIgfSwNCi0JeyAtMSwgTlVMTCB9DQotfTsNCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX0ZvbnRNYXA6OkdldERlZmF1bHRGb250QnlDaGFyc2V0KEZYX0lOVDMyIG5DaGFyc2V0KQ0KLXsNCi0JaW50IGkgPSAwOw0KLQl3aGlsZSAoZGVmYXVsdFRURk1hcFtpXS5jaGFyc2V0ICE9IC0xKSB7DQotCQlpZiAobkNoYXJzZXQgPT0gZGVmYXVsdFRURk1hcFtpXS5jaGFyc2V0KQ0KLQkJCXJldHVybiBkZWZhdWx0VFRGTWFwW2ldLmZvbnRuYW1lOw0KLSAgICAgICAgKytpOw0KLQl9DQotCXJldHVybiAiIjsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpDaGFyU2V0RnJvbVVuaWNvZGUoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuT2xkQ2hhcnNldCkNCi17DQotCWlmKG1fcFN5c3RlbUhhbmRsZXIgJiYgKC0xICE9IG1fcFN5c3RlbUhhbmRsZXItPkdldENoYXJTZXQoKSkpDQotCQlyZXR1cm4gbV9wU3lzdGVtSGFuZGxlci0+R2V0Q2hhclNldCgpOw0KLQkvL3RvIGF2b2lkIENKSyBGb250IHRvIHNob3cgQVNDSUkNCi0JaWYgKHdvcmQgPCAweDdGKSByZXR1cm4gQU5TSV9DSEFSU0VUOw0KLQkvL2ZvbGxvdyB0aGUgb2xkIGNoYXJzZXQNCi0JaWYgKG5PbGRDaGFyc2V0ICE9IERFRkFVTFRfQ0hBUlNFVCkgcmV0dXJuIG5PbGRDaGFyc2V0Ow0KLQ0KLQkvL2ZpbmQgbmV3IGNoYXJzZXQNCi0JaWYgKCh3b3JkID49IDB4NEUwMCAmJiB3b3JkIDw9IDB4OUZBNSkgfHwgDQotCQkod29yZCA+PSAweEU3QzcgJiYgd29yZCA8PSAweEU3RjMpIHx8DQotCQkod29yZCA+PSAweDMwMDAgJiYgd29yZCA8PSAweDMwM0YpIHx8IC8vo6kiobYiICKhtyIgIqGjIiAioaIiIA0KLQkJKHdvcmQgPj0gMHgyMDAwICYmIHdvcmQgPD0gMHgyMDZGKSkNCi0Jew0KLQkJcmV0dXJuIEdCMjMxMl9DSEFSU0VUOw0KLQl9DQotDQotCWlmICgoKHdvcmQgPj0gMHgzMDQwKSAmJiAod29yZCA8PSAweDMwOUYpKSB8fA0KLQkJKCh3b3JkID49IDB4MzBBMCkgJiYgKHdvcmQgPD0gMHgzMEZGKSkgfHwNCi0JCSgod29yZCA+PSAweDMxRjApICYmICh3b3JkIDw9IDB4MzFGRikpIHx8DQotCQkoKHdvcmQgPj0gMHhGRjAwKSAmJiAod29yZCA8PSAweEZGRUYpKSApDQotCXsNCi0JCXJldHVybiBTSElGVEpJU19DSEFSU0VUOw0KLQl9DQotDQotCWlmICgoKHdvcmQgPj0gMHhBQzAwKSAmJiAod29yZCA8PSAweEQ3QUYpKSB8fA0KLQkJKCh3b3JkID49IDB4MTEwMCkgJiYgKHdvcmQgPD0gMHgxMUZGKSkgfHwNCi0JCSgod29yZCA+PSAweDMxMzApICYmICh3b3JkIDw9IDB4MzE4RikpKQ0KLQl7DQotCQlyZXR1cm4gSEFOR1VMX0NIQVJTRVQ7DQotCX0NCi0NCi0JaWYgKHdvcmQgPj0gMHgwRTAwICYmIHdvcmQgPD0gMHgwRTdGKQ0KLQkJcmV0dXJuIFRIQUlfQ0hBUlNFVDsNCi0NCi0JaWYgKCh3b3JkID49IDB4MDM3MCAmJiB3b3JkIDw9IDB4MDNGRikgfHwNCi0JCSh3b3JkID49IDB4MUYwMCAmJiB3b3JkIDw9IDB4MUZGRikpDQotCQlyZXR1cm4gR1JFRUtfQ0hBUlNFVDsNCi0NCi0JaWYgKCh3b3JkID49IDB4MDYwMCAmJiB3b3JkIDw9IDB4MDZGRikgfHwNCi0JCSh3b3JkID49IDB4RkI1MCAmJiB3b3JkIDw9IDB4RkVGQykpDQotCQlyZXR1cm4gQVJBQklDX0NIQVJTRVQ7DQotDQotCWlmICh3b3JkID49IDB4MDU5MCAmJiB3b3JkIDw9IDB4MDVGRikNCi0JCXJldHVybiBIRUJSRVdfQ0hBUlNFVDsNCi0NCi0JaWYgKHdvcmQgPj0gMHgwNDAwICYmIHdvcmQgPD0gMHgwNEZGKQ0KLQkJcmV0dXJuIFJVU1NJQU5fQ0hBUlNFVDsNCi0NCi0JaWYgKHdvcmQgPj0gMHgwMTAwICYmIHdvcmQgPD0gMHgwMjRGKQ0KLQkJcmV0dXJuIEVBU1RFVVJPUEVfQ0hBUlNFVDsNCi0NCi0JaWYgKHdvcmQgPj0gMHgxRTAwICYmIHdvcmQgPD0gMHgxRUZGKQ0KLQkJcmV0dXJuIFZJRVROQU1FU0VfQ0hBUlNFVDsNCi0NCi0JcmV0dXJuIEFOU0lfQ0hBUlNFVDsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfRG9jRm9udE1hcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0RvY0ZvbnRNYXA6OkNQV0xfRG9jRm9udE1hcChJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIsIENQREZfRG9jdW1lbnQqIHBBdHRhY2hlZERvYykgDQotCTogQ1BXTF9Gb250TWFwKHBTeXN0ZW1IYW5kbGVyKSwNCi0JbV9wQXR0YWNoZWREb2MocEF0dGFjaGVkRG9jKQ0KLXsNCi19DQotDQotQ1BXTF9Eb2NGb250TWFwOjp+Q1BXTF9Eb2NGb250TWFwKCkNCi17DQotfQ0KLQ0KLUNQREZfRG9jdW1lbnQqIENQV0xfRG9jRm9udE1hcDo6R2V0RG9jdW1lbnQoKQ0KLXsNCi0JcmV0dXJuIG1fcEF0dGFjaGVkRG9jOw0KLX0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Gb250TWFwLmgiCisKKyNkZWZpbmUgREVGQVVMVF9GT05UX05BTUUJCQkiSGVsdmV0aWNhIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Gb250TWFwIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0ZvbnRNYXA6OkNQV0xfRm9udE1hcChJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIpIDogCQorCW1fcFBERkRvYyhOVUxMKSwKKwltX3BTeXN0ZW1IYW5kbGVyKHBTeXN0ZW1IYW5kbGVyKQoreworCUFTU0VSVChtX3BTeXN0ZW1IYW5kbGVyICE9IE5VTEwpOworfQorCitDUFdMX0ZvbnRNYXA6On5DUFdMX0ZvbnRNYXAoKQoreworCWlmIChtX3BQREZEb2MpCisJeworCQlkZWxldGUgbV9wUERGRG9jOworCQltX3BQREZEb2MgPSBOVUxMOworCX0KKworCUVtcHR5KCk7Cit9CisKK3ZvaWQgQ1BXTF9Gb250TWFwOjpTZXRTeXN0ZW1IYW5kbGVyKElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlcikKK3sKKwltX3BTeXN0ZW1IYW5kbGVyID0gcFN5c3RlbUhhbmRsZXI7Cit9CisKK0NQREZfRG9jdW1lbnQqIENQV0xfRm9udE1hcDo6R2V0RG9jdW1lbnQoKQoreworCWlmICghbV9wUERGRG9jKQorCXsKKwkJaWYgKENQREZfTW9kdWxlTWdyOjpHZXQoKSkKKwkJeworCQkJbV9wUERGRG9jID0gRlhfTkVXIENQREZfRG9jdW1lbnQ7CisJCQltX3BQREZEb2MtPkNyZWF0ZU5ld0RvYygpOworCQl9CisJfQorCisJcmV0dXJuIG1fcFBERkRvYzsKK30KKworQ1BERl9Gb250KiBDUFdMX0ZvbnRNYXA6OkdldFBERkZvbnQoRlhfSU5UMzIgbkZvbnRJbmRleCkKK3sKKwlpZiAobkZvbnRJbmRleCA+PTAgJiYgbkZvbnRJbmRleCA8IG1fYURhdGEuR2V0U2l6ZSgpKQorCXsKKwkJaWYgKENQV0xfRm9udE1hcF9EYXRhKiBwRGF0YSA9IG1fYURhdGEuR2V0QXQobkZvbnRJbmRleCkpCisJCXsKKwkJCXJldHVybiBwRGF0YS0+cEZvbnQ7CisJCX0KKwl9CisKKwlyZXR1cm4gTlVMTDsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Gb250TWFwOjpHZXRQREZGb250QWxpYXMoRlhfSU5UMzIgbkZvbnRJbmRleCkKK3sKKwlpZiAobkZvbnRJbmRleCA+PTAgJiYgbkZvbnRJbmRleCA8IG1fYURhdGEuR2V0U2l6ZSgpKQorCXsKKwkJaWYgKENQV0xfRm9udE1hcF9EYXRhKiBwRGF0YSA9IG1fYURhdGEuR2V0QXQobkZvbnRJbmRleCkpCisJCXsKKwkJCXJldHVybiBwRGF0YS0+c0ZvbnROYW1lOworCQl9CisJfQorCisJcmV0dXJuICIiOworfQorCitGWF9CT09MIENQV0xfRm9udE1hcDo6S25vd1dvcmQoRlhfSU5UMzIgbkZvbnRJbmRleCwgRlhfV09SRCB3b3JkKQoreworCWlmIChuRm9udEluZGV4ID49MCAmJiBuRm9udEluZGV4IDwgbV9hRGF0YS5HZXRTaXplKCkpCisJeworCQlpZiAobV9hRGF0YS5HZXRBdChuRm9udEluZGV4KSkKKwkJewkKKwkJCXJldHVybiBDaGFyQ29kZUZyb21Vbmljb2RlKG5Gb250SW5kZXgsIHdvcmQpID49IDA7CisJCX0KKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0lOVDMyIENQV0xfRm9udE1hcDo6R2V0V29yZEZvbnRJbmRleChGWF9XT1JEIHdvcmQsIEZYX0lOVDMyIG5DaGFyc2V0LCBGWF9JTlQzMiBuRm9udEluZGV4KQoreworCWlmIChuRm9udEluZGV4ID4gMCkKKwl7CisJCWlmIChLbm93V29yZChuRm9udEluZGV4LCB3b3JkKSkKKwkJCXJldHVybiBuRm9udEluZGV4OworCX0KKwllbHNlCisJeworCQlpZiAoY29uc3QgQ1BXTF9Gb250TWFwX0RhdGEqIHBEYXRhID0gR2V0Rm9udE1hcERhdGEoMCkpCisJCXsKKwkJCWlmIChuQ2hhcnNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgCisJCQkJcERhdGEtPm5DaGFyc2V0ID09IFNZTUJPTF9DSEFSU0VUIHx8IAorCQkJCW5DaGFyc2V0ID09IHBEYXRhLT5uQ2hhcnNldCkKKwkJCXsKKwkJCQlpZiAoS25vd1dvcmQoMCwgd29yZCkpCisJCQkJeworCQkJCQlyZXR1cm4gMDsKKwkJCQl9CisJCQl9CisJCX0KKwl9CisKKwlGWF9JTlQzMiBuTmV3Rm9udEluZGV4ID0gLTE7CisKKwluTmV3Rm9udEluZGV4ID0gdGhpcy0+R2V0Rm9udEluZGV4KEdldE5hdGl2ZUZvbnROYW1lKG5DaGFyc2V0KSwgbkNoYXJzZXQsIFRSVUUpOworCWlmIChuTmV3Rm9udEluZGV4ID49IDApCisJeworCQlpZiAoS25vd1dvcmQobk5ld0ZvbnRJbmRleCwgd29yZCkpCisJCQlyZXR1cm4gbk5ld0ZvbnRJbmRleDsKKwl9CisKKwluTmV3Rm9udEluZGV4ID0gdGhpcy0+R2V0Rm9udEluZGV4KCJBcmlhbCBVbmljb2RlIE1TIiwgREVGQVVMVF9DSEFSU0VULCBGQUxTRSk7CisJaWYgKG5OZXdGb250SW5kZXggPj0gMCkKKwl7CisJCWlmIChLbm93V29yZChuTmV3Rm9udEluZGV4LCB3b3JkKSkKKwkJcmV0dXJuIG5OZXdGb250SW5kZXg7CisJfQorCisJcmV0dXJuIC0xOworfQorCitGWF9JTlQzMiBDUFdMX0ZvbnRNYXA6OkNoYXJDb2RlRnJvbVVuaWNvZGUoRlhfSU5UMzIgbkZvbnRJbmRleCwgRlhfV09SRCB3b3JkKQoreworCWlmIChDUFdMX0ZvbnRNYXBfRGF0YSogcERhdGEgPSBtX2FEYXRhLkdldEF0KG5Gb250SW5kZXgpKQorCXsKKwkJaWYgKHBEYXRhLT5wRm9udCkKKwkJeworCQkJaWYgKHBEYXRhLT5wRm9udC0+SXNVbmljb2RlQ29tcGF0aWJsZSgpKQorCQkJeworCQkJCWludCBuQ2hhckNvZGUgPSBwRGF0YS0+cEZvbnQtPkNoYXJDb2RlRnJvbVVuaWNvZGUod29yZCk7CisJCQkJcERhdGEtPnBGb250LT5HbHlwaEZyb21DaGFyQ29kZShuQ2hhckNvZGUpOworCQkJCXJldHVybiBuQ2hhckNvZGU7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJaWYgKHdvcmQgPCAweEZGKQorCQkJCQlyZXR1cm4gd29yZDsKKwkJCX0KKwkJfQorCX0KKworCXJldHVybiAtMTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Gb250TWFwOjpHZXROYXRpdmVGb250TmFtZShGWF9JTlQzMiBuQ2hhcnNldCkKK3sKKwkvL3NlYXJjaGluZyBuYXRpdmUgZm9udCBpcyBzbG93LCBzbyB3ZSBtdXN0IHNhdmUgdGltZQorCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYU5hdGl2ZUZvbnQuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlpZiAoQ1BXTF9Gb250TWFwX05hdGl2ZSogcERhdGEgPSBtX2FOYXRpdmVGb250LkdldEF0KGkpKQorCQl7CisJCQlpZiAocERhdGEtPm5DaGFyc2V0ID09IG5DaGFyc2V0KQorCQkJCXJldHVybiBwRGF0YS0+c0ZvbnROYW1lOworCQl9CisJfQorCisJQ0ZYX0J5dGVTdHJpbmcgc05ldyA9IEdldE5hdGl2ZUZvbnQobkNoYXJzZXQpOworCisJaWYgKCFzTmV3LklzRW1wdHkoKSkKKwl7CisJCUNQV0xfRm9udE1hcF9OYXRpdmUqIHBOZXdEYXRhID0gbmV3IENQV0xfRm9udE1hcF9OYXRpdmU7CisJCXBOZXdEYXRhLT5uQ2hhcnNldCA9IG5DaGFyc2V0OworCQlwTmV3RGF0YS0+c0ZvbnROYW1lID0gc05ldzsKKworCQltX2FOYXRpdmVGb250LkFkZChwTmV3RGF0YSk7CisJfQorCisJcmV0dXJuIHNOZXc7Cit9CisKK3ZvaWQgQ1BXTF9Gb250TWFwOjpFbXB0eSgpCit7CisJeworCQlmb3IgKEZYX0lOVDMyIGk9MCwgc3o9bV9hRGF0YS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJCWRlbGV0ZSBtX2FEYXRhLkdldEF0KGkpOworCisJCW1fYURhdGEuUmVtb3ZlQWxsKCk7CisJfQorCXsKKwkJZm9yIChGWF9JTlQzMiBpPTAsIHN6PW1fYU5hdGl2ZUZvbnQuR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQlkZWxldGUgbV9hTmF0aXZlRm9udC5HZXRBdChpKTsKKworCQltX2FOYXRpdmVGb250LlJlbW92ZUFsbCgpOworCX0KK30KKwordm9pZCBDUFdMX0ZvbnRNYXA6OkluaXRpYWwoRlhfTFBDU1RSIGZvbnRuYW1lKQoreworCUNGWF9CeXRlU3RyaW5nIHNGb250TmFtZSA9IGZvbnRuYW1lOworCisJaWYgKHNGb250TmFtZS5Jc0VtcHR5KCkpCisJCXNGb250TmFtZSA9IERFRkFVTFRfRk9OVF9OQU1FOworCisJR2V0Rm9udEluZGV4KHNGb250TmFtZSwgQU5TSV9DSEFSU0VULCBGQUxTRSk7CisKKwkvL0dldEZvbnRJbmRleCh0aGlzLT5HZXROYXRpdmVGb250TmFtZShuQ2hhcnNldCksIG5DaGFyc2V0KTsKK30KKwkKKworLyoKK0xpc3Qgb2YgY3VycmVudGx5IHN1cHBvcnRlZCBzdGFuZGFyZCBmb250czoKK0NvdXJpZXIsIENvdXJpZXItQm9sZCwgQ291cmllci1Cb2xkT2JsaXF1ZSwgQ291cmllci1PYmxpcXVlCitIZWx2ZXRpY2EsIEhlbHZldGljYS1Cb2xkLCBIZWx2ZXRpY2EtQm9sZE9ibGlxdWUsIEhlbHZldGljYS1PYmxpcXVlCitUaW1lcy1Sb21hbiwgVGltZXMtQm9sZCwgVGltZXMtSXRhbGljLCBUaW1lcy1Cb2xkSXRhbGljCitTeW1ib2wsIFphcGZEaW5nYmF0cworKi8KKworY29uc3QgY2hhciogZ19zREVTdGFuZGFyZEZvbnROYW1lW10gPSB7IkNvdXJpZXIiLCAiQ291cmllci1Cb2xkIiwgIkNvdXJpZXItQm9sZE9ibGlxdWUiLCAiQ291cmllci1PYmxpcXVlIiwKKwkiSGVsdmV0aWNhIiwgIkhlbHZldGljYS1Cb2xkIiwgIkhlbHZldGljYS1Cb2xkT2JsaXF1ZSIsICJIZWx2ZXRpY2EtT2JsaXF1ZSIsCisJIlRpbWVzLVJvbWFuIiwgIlRpbWVzLUJvbGQiLCAiVGltZXMtSXRhbGljIiwgIlRpbWVzLUJvbGRJdGFsaWMiLAorCSJTeW1ib2wiLCAiWmFwZkRpbmdiYXRzIn07CisKK0ZYX0JPT0wJQ1BXTF9Gb250TWFwOjpJc1N0YW5kYXJkRm9udChjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lKQoreworCWZvciAoRlhfSU5UMzIgaT0wOyBpPDE0OyBpKyspCisJeworCQlpZiAoc0ZvbnROYW1lID09IGdfc0RFU3RhbmRhcmRGb250TmFtZVtpXSkKKwkJCXJldHVybiBUUlVFOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpGaW5kRm9udChjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnROYW1lLCBGWF9JTlQzMiBuQ2hhcnNldCkKK3sKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FEYXRhLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJaWYgKENQV0xfRm9udE1hcF9EYXRhKiBwRGF0YSA9IG1fYURhdGEuR2V0QXQoaSkpCisJCXsKKwkJCWlmIChuQ2hhcnNldCA9PSBERUZBVUxUX0NIQVJTRVQgfHwgbkNoYXJzZXQgPT0gcERhdGEtPm5DaGFyc2V0KQorCQkJeworCQkJCWlmIChzRm9udE5hbWUuSXNFbXB0eSgpIHx8IHBEYXRhLT5zRm9udE5hbWUgPT0gc0ZvbnROYW1lKQorCQkJCQlyZXR1cm4gaTsKKwkJCX0KKwkJfQorCX0KKworCXJldHVybiAtMTsKK30KKworRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpHZXRGb250SW5kZXgoY29uc3QgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSwgRlhfSU5UMzIgbkNoYXJzZXQsIEZYX0JPT0wgYkZpbmQpCit7CisJRlhfSU5UMzIgbkZvbnRJbmRleCA9IEZpbmRGb250KEVuY29kZUZvbnRBbGlhcyhzRm9udE5hbWUsIG5DaGFyc2V0KSwgbkNoYXJzZXQpOworCWlmIChuRm9udEluZGV4ID49IDApIHJldHVybiBuRm9udEluZGV4OworCisvLwluRm9udEluZGV4ID0gRmluZEZvbnQoIiIsIG5DaGFyc2V0KTsKKy8vCWlmIChuRm9udEluZGV4ID49IDApIHJldHVybiBuRm9udEluZGV4OworCisJQ0ZYX0J5dGVTdHJpbmcgc0FsaWFzOworCUNQREZfRm9udCogcEZvbnQgPSBOVUxMOworCisJaWYgKGJGaW5kKQorCQlwRm9udCA9IEZpbmRGb250U2FtZUNoYXJzZXQoc0FsaWFzLCBuQ2hhcnNldCk7CisKKwlpZiAoIXBGb250KQorCXsKKwkJQ0ZYX0J5dGVTdHJpbmcgc1RlbXAgPSBzRm9udE5hbWU7CisJCXBGb250ID0gQWRkRm9udFRvRG9jdW1lbnQoR2V0RG9jdW1lbnQoKSwgc1RlbXAsIG5DaGFyc2V0KTsKKworCQkvKgorCQlpZiAoRmluZEZvbnQoc0FsaWFzKSkKKwkJeworCQkJc0FsaWFzID0gRW5jb2RlRm9udEFsaWFzKHNUZW1wLCBuQ2hhcnNldCk7CisJCX0KKwkJZWxzZQorCQkqLworCQl7CisJCQlzQWxpYXMgPSBFbmNvZGVGb250QWxpYXMoc1RlbXAsIG5DaGFyc2V0KTsKKwkJfQkJCisJfQorCisJQWRkZWRGb250KHBGb250LCBzQWxpYXMpOworCisJcmV0dXJuIEFkZEZvbnREYXRhKHBGb250LCBzQWxpYXMsIG5DaGFyc2V0KTsKK30KKworRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpHZXRQV0xGb250SW5kZXgoRlhfV09SRCB3b3JkLCBGWF9JTlQzMiBuQ2hhcnNldCkKK3sKKwlGWF9JTlQzMiBuRmluZCA9IC0xOworCisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hRGF0YS5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChDUFdMX0ZvbnRNYXBfRGF0YSogcERhdGEgPSBtX2FEYXRhLkdldEF0KGkpKQorCQl7CisJCQlpZiAocERhdGEtPm5DaGFyc2V0ID09IG5DaGFyc2V0KQorCQkJeworCQkJCW5GaW5kID0gaTsKKwkJCQlicmVhazsKKwkJCX0KKwkJfQorCX0KKworCUNQREZfRm9udCogcE5ld0ZvbnQgPSBHZXRQREZGb250KG5GaW5kKTsKKworCWlmICghcE5ld0ZvbnQpIHJldHVybiAtMTsKKworCS8qCisJaWYgKENQREZfRm9udCogcEZvbnQgPSBHZXRQREZGb250KG5GaW5kKSkKKwl7CisJCVBXTEZvbnQuQWRkV29yZFRvRm9udERpY3QocEZvbnREaWN0LCB3b3JkKTsKKwl9CisJKi8KKworI2lmZGVmIEZPWElUX0NIUk9NRV9CVUlMRAorICBDRlhfQnl0ZVN0cmluZyBzQWxpYXMgPSBFbmNvZGVGb250QWxpYXMoIkFyaWFsX0Nocm9tZSIsIG5DaGFyc2V0KTsKKyNlbHNlCisJQ0ZYX0J5dGVTdHJpbmcgc0FsaWFzID0gRW5jb2RlRm9udEFsaWFzKCJBcmlhbF9Gb3hpdCIsIG5DaGFyc2V0KTsKKyNlbmRpZgorCUFkZGVkRm9udChwTmV3Rm9udCwgc0FsaWFzKTsKKworCXJldHVybiBBZGRGb250RGF0YShwTmV3Rm9udCwgc0FsaWFzLCBuQ2hhcnNldCk7Cit9CisKK0NQREZfRm9udCogQ1BXTF9Gb250TWFwOjpGaW5kRm9udFNhbWVDaGFyc2V0KENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzLCBGWF9JTlQzMiBuQ2hhcnNldCkKK3sKKwlyZXR1cm4gTlVMTDsKK30KKworRlhfSU5UMzIgQ1BXTF9Gb250TWFwOjpBZGRGb250RGF0YShDUERGX0ZvbnQqIHBGb250LCBjb25zdCBDRlhfQnl0ZVN0cmluZyYgc0ZvbnRBbGlhcywgRlhfSU5UMzIgbkNoYXJzZXQpCit7CisJQ1BXTF9Gb250TWFwX0RhdGEqIHBOZXdEYXRhID0gbmV3IENQV0xfRm9udE1hcF9EYXRhOworCXBOZXdEYXRhLT5wRm9udCA9IHBGb250OworCXBOZXdEYXRhLT5zRm9udE5hbWUgPSBzRm9udEFsaWFzOworCXBOZXdEYXRhLT5uQ2hhcnNldCA9IG5DaGFyc2V0OworCisJbV9hRGF0YS5BZGQocE5ld0RhdGEpOworCisJcmV0dXJuIG1fYURhdGEuR2V0U2l6ZSgpIC0xOworfQorCit2b2lkIENQV0xfRm9udE1hcDo6QWRkZWRGb250KENQREZfRm9udCogcEZvbnQsIGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udEFsaWFzKQoreworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX0ZvbnRNYXA6OkdldEZvbnROYW1lKEZYX0lOVDMyIG5Gb250SW5kZXgpCit7CisJaWYgKG5Gb250SW5kZXggPj0wICYmIG5Gb250SW5kZXggPCBtX2FEYXRhLkdldFNpemUoKSkKKwl7CisJCWlmIChDUFdMX0ZvbnRNYXBfRGF0YSogcERhdGEgPSBtX2FEYXRhLkdldEF0KG5Gb250SW5kZXgpKQorCQl7CisJCQlyZXR1cm4gcERhdGEtPnNGb250TmFtZTsKKwkJfQorCX0KKworCXJldHVybiAiIjsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Gb250TWFwOjpHZXROYXRpdmVGb250KEZYX0lOVDMyIG5DaGFyc2V0KQoreworCUNGWF9CeXRlU3RyaW5nIHNGb250TmFtZTsKKworCWlmIChuQ2hhcnNldCA9PSBERUZBVUxUX0NIQVJTRVQpCisJCW5DaGFyc2V0ID0gR2V0TmF0aXZlQ2hhcnNldCgpOworCisJc0ZvbnROYW1lID0gR2V0RGVmYXVsdEZvbnRCeUNoYXJzZXQobkNoYXJzZXQpOworCisJaWYgKG1fcFN5c3RlbUhhbmRsZXIpCisJeworCQlpZiAobV9wU3lzdGVtSGFuZGxlci0+RmluZE5hdGl2ZVRydWVUeXBlRm9udChuQ2hhcnNldCwgc0ZvbnROYW1lKSkKKwkJCXJldHVybiBzRm9udE5hbWU7CisKKwkJc0ZvbnROYW1lID0gbV9wU3lzdGVtSGFuZGxlci0+R2V0TmF0aXZlVHJ1ZVR5cGVGb250KG5DaGFyc2V0KTsKKwl9CisKKwlyZXR1cm4gc0ZvbnROYW1lOworfQorCitDUERGX0ZvbnQqIENQV0xfRm9udE1hcDo6QWRkRm9udFRvRG9jdW1lbnQoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSwgRlhfQllURSBuQ2hhcnNldCkKK3sKKwlpZiAoSXNTdGFuZGFyZEZvbnQoc0ZvbnROYW1lKSkKKwkJcmV0dXJuIEFkZFN0YW5kYXJkRm9udChwRG9jLCBzRm9udE5hbWUpOworCWVsc2UKKwkJcmV0dXJuIEFkZFN5c3RlbUZvbnQocERvYywgc0ZvbnROYW1lLCBuQ2hhcnNldCk7Cit9CisKK0NQREZfRm9udCogQ1BXTF9Gb250TWFwOjpBZGRTdGFuZGFyZEZvbnQoQ1BERl9Eb2N1bWVudCogcERvYywgQ0ZYX0J5dGVTdHJpbmcmIHNGb250TmFtZSkKK3sKKwlpZiAoIXBEb2MpIHJldHVybiBOVUxMOworCisJQ1BERl9Gb250KiBwRm9udCA9IE5VTEw7CisKKwlpZiAoc0ZvbnROYW1lID09ICJaYXBmRGluZ2JhdHMiKQorCQlwRm9udCA9IHBEb2MtPkFkZFN0YW5kYXJkRm9udChzRm9udE5hbWUsIE5VTEwpOworCWVsc2UKKwl7CisJCUNQREZfRm9udEVuY29kaW5nIGZlKFBERkZPTlRfRU5DT0RJTkdfV0lOQU5TSSk7CisJCXBGb250ID0gcERvYy0+QWRkU3RhbmRhcmRGb250KHNGb250TmFtZSwgJmZlKTsKKwl9CisKKwlyZXR1cm4gcEZvbnQ7Cit9CisKK0NQREZfRm9udCogQ1BXTF9Gb250TWFwOjpBZGRTeXN0ZW1Gb250KENQREZfRG9jdW1lbnQqIHBEb2MsIENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUsIEZYX0JZVEUgbkNoYXJzZXQpCit7CisJaWYgKCFwRG9jKSByZXR1cm4gTlVMTDsKKworCWlmIChzRm9udE5hbWUuSXNFbXB0eSgpKSBzRm9udE5hbWUgPSBHZXROYXRpdmVGb250KG5DaGFyc2V0KTsKKwlpZiAobkNoYXJzZXQgPT0gREVGQVVMVF9DSEFSU0VUKSBuQ2hhcnNldCA9IEdldE5hdGl2ZUNoYXJzZXQoKTsKKworCWlmIChtX3BTeXN0ZW1IYW5kbGVyKQorCQlyZXR1cm4gbV9wU3lzdGVtSGFuZGxlci0+QWRkTmF0aXZlVHJ1ZVR5cGVGb250VG9QREYocERvYywgc0ZvbnROYW1lLCBuQ2hhcnNldCk7CisJCisJcmV0dXJuIE5VTEw7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfRm9udE1hcDo6RW5jb2RlRm9udEFsaWFzKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUsIEZYX0lOVDMyIG5DaGFyc2V0KQoreworCUNGWF9CeXRlU3RyaW5nIHNQb3N0Zml4OworCXNQb3N0Zml4LkZvcm1hdCgiXyUwMlgiLCBuQ2hhcnNldCk7CisJcmV0dXJuIEVuY29kZUZvbnRBbGlhcyhzRm9udE5hbWUpICsgc1Bvc3RmaXg7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfRm9udE1hcDo6RW5jb2RlRm9udEFsaWFzKGNvbnN0IENGWF9CeXRlU3RyaW5nJiBzRm9udE5hbWUpCit7CisJQ0ZYX0J5dGVTdHJpbmcgc1JldCA9IHNGb250TmFtZTsKKwlzUmV0LlJlbW92ZSgnICcpOworCXJldHVybiBzUmV0OworfQorCitGWF9JTlQzMiBDUFdMX0ZvbnRNYXA6OkdldEZvbnRNYXBDb3VudCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fYURhdGEuR2V0U2l6ZSgpOworfQorCitjb25zdCBDUFdMX0ZvbnRNYXBfRGF0YSogQ1BXTF9Gb250TWFwOjpHZXRGb250TWFwRGF0YShGWF9JTlQzMiBuSW5kZXgpIGNvbnN0Cit7CisJaWYgKG5JbmRleCA+PTAgJiYgbkluZGV4IDwgbV9hRGF0YS5HZXRTaXplKCkpCisJeworCQlyZXR1cm4gbV9hRGF0YS5HZXRBdChuSW5kZXgpOworCX0KKworCXJldHVybiBOVUxMOworfQorCitGWF9JTlQzMiBDUFdMX0ZvbnRNYXA6OkdldE5hdGl2ZUNoYXJzZXQoKQoreworCUZYX0JZVEUgbkNoYXJzZXQgPSBBTlNJX0NIQVJTRVQ7CisJRlhfSU5UMzIgaUNvZGVQYWdlID0gRlhTWVNfR2V0QUNQKCk7CisJc3dpdGNoIChpQ29kZVBhZ2UpCisJeworCWNhc2UgOTMyOi8vSmFwYW4KKwkJbkNoYXJzZXQgPSBTSElGVEpJU19DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDkzNjovL0NoaW5lc2UgKFBSQywgU2luZ2Fwb3JlKQorCQluQ2hhcnNldCA9IEdCMjMxMl9DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDk1MDovL0NoaW5lc2UgKFRhaXdhbjsgSG9uZyBLb25nIFNBUiwgUFJDKQorCQluQ2hhcnNldCA9IEdCMjMxMl9DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDEyNTI6Ly9XaW5kb3dzIDMuMSBMYXRpbiAxIChVUywgV2VzdGVybiBFdXJvcGUpCisJCW5DaGFyc2V0ID0gQU5TSV9DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDg3NDovL1RoYWkKKwkJbkNoYXJzZXQgPSBUSEFJX0NIQVJTRVQ7CisJCWJyZWFrOworCWNhc2UgOTQ5Oi8vS29yZWFuCisJCW5DaGFyc2V0ID0gSEFOR1VMX0NIQVJTRVQ7CisJCWJyZWFrOworCWNhc2UgMTIwMDovL1VuaWNvZGUgKEJNUCBvZiBJU08gMTA2NDYpCisJCW5DaGFyc2V0ID0gQU5TSV9DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDEyNTA6Ly9XaW5kb3dzIDMuMSBFYXN0ZXJuIEV1cm9wZWFuCisJCW5DaGFyc2V0ID0gRUFTVEVVUk9QRV9DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDEyNTE6Ly9XaW5kb3dzIDMuMSBDeXJpbGxpYworCQluQ2hhcnNldCA9IFJVU1NJQU5fQ0hBUlNFVDsKKwkJYnJlYWs7CisJY2FzZSAxMjUzOi8vV2luZG93cyAzLjEgR3JlZWsKKwkJbkNoYXJzZXQgPSBHUkVFS19DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDEyNTQ6Ly9XaW5kb3dzIDMuMSBUdXJraXNoCisJCW5DaGFyc2V0ID0gVFVSS0lTSF9DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDEyNTU6Ly9IZWJyZXcKKwkJbkNoYXJzZXQgPSBIRUJSRVdfQ0hBUlNFVDsKKwkJYnJlYWs7CisJY2FzZSAxMjU2Oi8vQXJhYmljCisJCW5DaGFyc2V0ID0gQVJBQklDX0NIQVJTRVQ7CisJCWJyZWFrOworCWNhc2UgMTI1NzovL0JhbHRpYworCQluQ2hhcnNldCA9IEJBTFRJQ19DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDEyNTg6Ly9WaWV0bmFtZXNlCisJCW5DaGFyc2V0ID0gVklFVE5BTUVTRV9DSEFSU0VUOworCQlicmVhazsKKwljYXNlIDEzNjE6Ly9Lb3JlYW4oSm9oYWIpCisJCW5DaGFyc2V0ID0gSk9IQUJfQ0hBUlNFVDsKKwkJYnJlYWs7CisJfQorCXJldHVybiBuQ2hhcnNldDsKK30KKworY29uc3QgQ1BXTF9Gb250TWFwOjpDaGFyc2V0Rm9udE1hcCBDUFdMX0ZvbnRNYXA6OmRlZmF1bHRUVEZNYXBbXSA9IHsKKwl7IEFOU0lfQ0hBUlNFVCwgIkhlbHZldGljYSIgfSwKKwl7IEdCMjMxMl9DSEFSU0VULCAiU2ltU3VuIiB9LAorCXsgQ0hJTkVTRUJJRzVfQ0hBUlNFVCwgIk1pbmdMaVUiIH0sCisJeyBTSElGVEpJU19DSEFSU0VULCAiTVMgR290aGljIiB9LAorCXsgSEFOR1VMX0NIQVJTRVQsICJCYXRhbmciIH0sCisJeyBSVVNTSUFOX0NIQVJTRVQsICJBcmlhbCIgfSwKKwl7IEVBU1RFVVJPUEVfQ0hBUlNFVCwgIlRhaG9tYSIgfSwKKwl7IEFSQUJJQ19DSEFSU0VULCAiQXJpYWwiIH0sCisJeyAtMSwgTlVMTCB9Cit9OworCitDRlhfQnl0ZVN0cmluZyBDUFdMX0ZvbnRNYXA6OkdldERlZmF1bHRGb250QnlDaGFyc2V0KEZYX0lOVDMyIG5DaGFyc2V0KQoreworCWludCBpID0gMDsKKwl3aGlsZSAoZGVmYXVsdFRURk1hcFtpXS5jaGFyc2V0ICE9IC0xKSB7CisJCWlmIChuQ2hhcnNldCA9PSBkZWZhdWx0VFRGTWFwW2ldLmNoYXJzZXQpCisJCQlyZXR1cm4gZGVmYXVsdFRURk1hcFtpXS5mb250bmFtZTsKKyAgICAgICAgKytpOworCX0KKwlyZXR1cm4gIiI7Cit9CisKK0ZYX0lOVDMyIENQV0xfRm9udE1hcDo6Q2hhclNldEZyb21Vbmljb2RlKEZYX1dPUkQgd29yZCwgRlhfSU5UMzIgbk9sZENoYXJzZXQpCit7CisJaWYobV9wU3lzdGVtSGFuZGxlciAmJiAoLTEgIT0gbV9wU3lzdGVtSGFuZGxlci0+R2V0Q2hhclNldCgpKSkKKwkJcmV0dXJuIG1fcFN5c3RlbUhhbmRsZXItPkdldENoYXJTZXQoKTsKKwkvL3RvIGF2b2lkIENKSyBGb250IHRvIHNob3cgQVNDSUkKKwlpZiAod29yZCA8IDB4N0YpIHJldHVybiBBTlNJX0NIQVJTRVQ7CisJLy9mb2xsb3cgdGhlIG9sZCBjaGFyc2V0CisJaWYgKG5PbGRDaGFyc2V0ICE9IERFRkFVTFRfQ0hBUlNFVCkgcmV0dXJuIG5PbGRDaGFyc2V0OworCisJLy9maW5kIG5ldyBjaGFyc2V0CisJaWYgKCh3b3JkID49IDB4NEUwMCAmJiB3b3JkIDw9IDB4OUZBNSkgfHwgCisJCSh3b3JkID49IDB4RTdDNyAmJiB3b3JkIDw9IDB4RTdGMykgfHwKKwkJKHdvcmQgPj0gMHgzMDAwICYmIHdvcmQgPD0gMHgzMDNGKSB8fCAvL6OpIqG2IiAiobciICKhoyIgIqGiIiAKKwkJKHdvcmQgPj0gMHgyMDAwICYmIHdvcmQgPD0gMHgyMDZGKSkKKwl7CisJCXJldHVybiBHQjIzMTJfQ0hBUlNFVDsKKwl9CisKKwlpZiAoKCh3b3JkID49IDB4MzA0MCkgJiYgKHdvcmQgPD0gMHgzMDlGKSkgfHwKKwkJKCh3b3JkID49IDB4MzBBMCkgJiYgKHdvcmQgPD0gMHgzMEZGKSkgfHwKKwkJKCh3b3JkID49IDB4MzFGMCkgJiYgKHdvcmQgPD0gMHgzMUZGKSkgfHwKKwkJKCh3b3JkID49IDB4RkYwMCkgJiYgKHdvcmQgPD0gMHhGRkVGKSkgKQorCXsKKwkJcmV0dXJuIFNISUZUSklTX0NIQVJTRVQ7CisJfQorCisJaWYgKCgod29yZCA+PSAweEFDMDApICYmICh3b3JkIDw9IDB4RDdBRikpIHx8CisJCSgod29yZCA+PSAweDExMDApICYmICh3b3JkIDw9IDB4MTFGRikpIHx8CisJCSgod29yZCA+PSAweDMxMzApICYmICh3b3JkIDw9IDB4MzE4RikpKQorCXsKKwkJcmV0dXJuIEhBTkdVTF9DSEFSU0VUOworCX0KKworCWlmICh3b3JkID49IDB4MEUwMCAmJiB3b3JkIDw9IDB4MEU3RikKKwkJcmV0dXJuIFRIQUlfQ0hBUlNFVDsKKworCWlmICgod29yZCA+PSAweDAzNzAgJiYgd29yZCA8PSAweDAzRkYpIHx8CisJCSh3b3JkID49IDB4MUYwMCAmJiB3b3JkIDw9IDB4MUZGRikpCisJCXJldHVybiBHUkVFS19DSEFSU0VUOworCisJaWYgKCh3b3JkID49IDB4MDYwMCAmJiB3b3JkIDw9IDB4MDZGRikgfHwKKwkJKHdvcmQgPj0gMHhGQjUwICYmIHdvcmQgPD0gMHhGRUZDKSkKKwkJcmV0dXJuIEFSQUJJQ19DSEFSU0VUOworCisJaWYgKHdvcmQgPj0gMHgwNTkwICYmIHdvcmQgPD0gMHgwNUZGKQorCQlyZXR1cm4gSEVCUkVXX0NIQVJTRVQ7CisKKwlpZiAod29yZCA+PSAweDA0MDAgJiYgd29yZCA8PSAweDA0RkYpCisJCXJldHVybiBSVVNTSUFOX0NIQVJTRVQ7CisKKwlpZiAod29yZCA+PSAweDAxMDAgJiYgd29yZCA8PSAweDAyNEYpCisJCXJldHVybiBFQVNURVVST1BFX0NIQVJTRVQ7CisKKwlpZiAod29yZCA+PSAweDFFMDAgJiYgd29yZCA8PSAweDFFRkYpCisJCXJldHVybiBWSUVUTkFNRVNFX0NIQVJTRVQ7CisKKwlyZXR1cm4gQU5TSV9DSEFSU0VUOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Eb2NGb250TWFwIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0RvY0ZvbnRNYXA6OkNQV0xfRG9jRm9udE1hcChJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIsIENQREZfRG9jdW1lbnQqIHBBdHRhY2hlZERvYykgCisJOiBDUFdMX0ZvbnRNYXAocFN5c3RlbUhhbmRsZXIpLAorCW1fcEF0dGFjaGVkRG9jKHBBdHRhY2hlZERvYykKK3sKK30KKworQ1BXTF9Eb2NGb250TWFwOjp+Q1BXTF9Eb2NGb250TWFwKCkKK3sKK30KKworQ1BERl9Eb2N1bWVudCogQ1BXTF9Eb2NGb250TWFwOjpHZXREb2N1bWVudCgpCit7CisJcmV0dXJuIG1fcEF0dGFjaGVkRG9jOworfQpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9JY29uLmNwcCBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfSWNvbi5jcHAKaW5kZXggYTg1OWE1Mi4uYjg1Yjg0NSAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9JY29uLmNwcAorKysgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0ljb24uY3BwCkBAIC0xLDI3MiArMSwyNzIgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfSWNvbi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfSW1hZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNQV0xfSW1hZ2U6OkNQV0xfSW1hZ2UoKSA6IG1fcFBERlN0cmVhbShOVUxMKQ0KLXsNCi19DQotDQotQ1BXTF9JbWFnZTo6fkNQV0xfSW1hZ2UoKQ0KLXsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9JbWFnZTo6R2V0SW1hZ2VBcHBTdHJlYW0oKQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNBcHBTdHJlYW07DQotDQotCUNGWF9CeXRlU3RyaW5nIHNBbGlhcyA9IHRoaXMtPkdldEltYWdlQWxpYXMoKTsNCi0JQ1BERl9SZWN0IHJjUGxhdGUgPSBHZXRDbGllbnRSZWN0KCk7DQotCUNQREZfTWF0cml4IG10Ow0KLQltdC5TZXRSZXZlcnNlKEdldEltYWdlTWF0cml4KCkpOw0KLQ0KLQlGWF9GTE9BVCBmSFNjYWxlID0gMS4wZjsNCi0JRlhfRkxPQVQgZlZTY2FsZSA9IDEuMGY7DQotCUdldFNjYWxlKGZIU2NhbGUsZlZTY2FsZSk7DQotDQotCUZYX0ZMT0FUIGZ4ID0gMC4wZjsNCi0JRlhfRkxPQVQgZnkgPSAwLjBmOw0KLQlHZXRJbWFnZU9mZnNldChmeCxmeSk7DQotDQotCWlmIChtX3BQREZTdHJlYW0gJiYgc0FsaWFzLkdldExlbmd0aCgpPjApDQotCXsNCi0JCXNBcHBTdHJlYW0gPDwgInFcbiI7DQotCQlzQXBwU3RyZWFtIDw8IHJjUGxhdGUubGVmdCA8PCAiICIgPDwgcmNQbGF0ZS5ib3R0b20gPDwgIiAiDQotCQkJPDwgcmNQbGF0ZS5yaWdodCAtIHJjUGxhdGUubGVmdCA8PCAiICIgPDwgcmNQbGF0ZS50b3AgLSByY1BsYXRlLmJvdHRvbSA8PCAiIHJlIFcgblxuIjsNCi0NCi0JCXNBcHBTdHJlYW0gPDwgZkhTY2FsZSA8PCAiIDAgMCAiIDw8IGZWU2NhbGUgPDwgIiAiIDw8IHJjUGxhdGUubGVmdCArIGZ4IDw8ICIgIiA8PCByY1BsYXRlLmJvdHRvbSArIGZ5IDw8ICIgY21cbiI7DQotCQlzQXBwU3RyZWFtIDw8IG10LkdldEEoKSA8PCAiICIgPDwgbXQuR2V0QigpIDw8ICIgIiA8PCBtdC5HZXRDKCkgPDwgIiAiIDw8IG10LkdldEQoKSA8PCAiICIgPDwgbXQuR2V0RSgpIDw8ICIgIiA8PCBtdC5HZXRGKCkgPDwgIiBjbVxuIjsNCi0NCi0JCXNBcHBTdHJlYW0gPDwgIjAgZyAwIEcgMSB3IC8iIDw8IHNBbGlhcyA8PCAiIERvXG4iIDw8ICJRXG4iOw0KLQl9DQotDQotCXJldHVybiBzQXBwU3RyZWFtLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotdm9pZCBDUFdMX0ltYWdlOjpTZXRQREZTdHJlYW0oQ1BERl9TdHJlYW0gKiBwU3RyZWFtKQ0KLXsNCi0JbV9wUERGU3RyZWFtID0gcFN0cmVhbTsNCi19DQotDQotQ1BERl9TdHJlYW0gKiBDUFdMX0ltYWdlOjpHZXRQREZTdHJlYW0oKQ0KLXsNCi0JcmV0dXJuIHRoaXMtPm1fcFBERlN0cmVhbTsNCi19DQotDQotdm9pZCBDUFdMX0ltYWdlOjpHZXRJbWFnZVNpemUoRlhfRkxPQVQgJiBmV2lkdGgsRlhfRkxPQVQgJiBmSGVpZ2h0KQ0KLXsNCi0JZldpZHRoID0gMC4wZjsNCi0JZkhlaWdodCA9IDAuMGY7DQotDQotCWlmIChtX3BQREZTdHJlYW0pDQotCXsNCi0JCWlmIChDUERGX0RpY3Rpb25hcnkgKiBwRGljdCA9IG1fcFBERlN0cmVhbS0+R2V0RGljdCgpKQ0KLQkJew0KLQkJCUNQREZfUmVjdCByZWN0ID0gcERpY3QtPkdldFJlY3QoIkJCb3giKTsNCi0NCi0JCQlmV2lkdGggPSByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0Ow0KLQkJCWZIZWlnaHQgPSByZWN0LnRvcCAtIHJlY3QuYm90dG9tOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUNQREZfTWF0cml4CUNQV0xfSW1hZ2U6OkdldEltYWdlTWF0cml4KCkNCi17DQotCWlmIChtX3BQREZTdHJlYW0pDQotCXsNCi0JCWlmIChDUERGX0RpY3Rpb25hcnkgKiBwRGljdCA9IG1fcFBERlN0cmVhbS0+R2V0RGljdCgpKQ0KLQkJew0KLQkJCXJldHVybiBwRGljdC0+R2V0TWF0cml4KCJNYXRyaXgiKTsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gQ1BERl9NYXRyaXgoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9JbWFnZTo6R2V0SW1hZ2VBbGlhcygpDQotew0KLQlpZiAobV9zSW1hZ2VBbGlhcy5Jc0VtcHR5KCkpDQotCXsNCi0JCWlmIChtX3BQREZTdHJlYW0pDQotCQl7DQotCQkJaWYgKENQREZfRGljdGlvbmFyeSAqIHBEaWN0ID0gbV9wUERGU3RyZWFtLT5HZXREaWN0KCkpCQkNCi0JCQl7DQotCQkJCXJldHVybiBwRGljdC0+R2V0U3RyaW5nKCJOYW1lIik7DQotCQkJfQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0JCXJldHVybiBtX3NJbWFnZUFsaWFzOw0KLQ0KLQlyZXR1cm4gQ0ZYX0J5dGVTdHJpbmcoKTsNCi19DQotDQotdm9pZCBDUFdMX0ltYWdlOjpTZXRJbWFnZUFsaWFzKEZYX0xQQ1NUUiBzSW1hZ2VBbGlhcykNCi17DQotCW1fc0ltYWdlQWxpYXMgPSBzSW1hZ2VBbGlhczsNCi19DQotDQotdm9pZCBDUFdMX0ltYWdlOjpHZXRTY2FsZShGWF9GTE9BVCAmIGZIU2NhbGUsRlhfRkxPQVQgJiBmVlNjYWxlKQ0KLXsNCi0JZkhTY2FsZSA9IDEuMGY7DQotCWZWU2NhbGUgPSAxLjBmOw0KLX0NCi0NCi0NCi12b2lkIENQV0xfSW1hZ2U6OkdldEltYWdlT2Zmc2V0KEZYX0ZMT0FUICYgeCxGWF9GTE9BVCAmIHkpDQotew0KLQl4ID0gMC4wZjsNCi0JeSA9IDAuMGY7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9JY29uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0ljb246OkNQV0xfSWNvbigpIDogbV9wSWNvbkZpdChOVUxMKQ0KLXsNCi19DQotDQotQ1BXTF9JY29uOjp+Q1BXTF9JY29uKCkNCi17DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfSWNvbjo6R2V0U2NhbGVNZXRob2QoKQ0KLXsNCi0JaWYgKG1fcEljb25GaXQpDQotCQlyZXR1cm4gbV9wSWNvbkZpdC0+R2V0U2NhbGVNZXRob2QoKTsNCi0NCi0JcmV0dXJuIDA7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9JY29uOjpJc1Byb3BvcnRpb25hbFNjYWxlKCkNCi17DQotCWlmIChtX3BJY29uRml0KQ0KLQkJcmV0dXJuIG1fcEljb25GaXQtPklzUHJvcG9ydGlvbmFsU2NhbGUoKTsNCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENQV0xfSWNvbjo6R2V0SWNvblBvc2l0aW9uKEZYX0ZMT0FUICYgZkxlZnQsIEZYX0ZMT0FUICYgZkJvdHRvbSkNCi17DQotCWlmIChtX3BJY29uRml0KQ0KLQl7DQotCQkvL21fcEljb25GaXQtPkdldEljb25Qb3NpdGlvbihmTGVmdCxmQm90dG9tKTsNCi0JCWZMZWZ0ID0gMC4wZjsNCi0JCWZCb3R0b20gPSAwLjBmOw0KLQkJQ1BERl9BcnJheSogcEEgPSBtX3BJY29uRml0LT5tX3BEaWN0LT5HZXRBcnJheSgiQSIpOw0KLQkJaWYgKHBBICE9IE5VTEwpDQotCQl7DQotCQkJRlhfRFdPUkQgZHdDb3VudCA9IHBBLT5HZXRDb3VudCgpOw0KLQkJCWlmIChkd0NvdW50ID4gMCkgZkxlZnQgPSBwQS0+R2V0TnVtYmVyKDApOw0KLQkJCWlmIChkd0NvdW50ID4gMSkgZkJvdHRvbSA9IHBBLT5HZXROdW1iZXIoMSk7DQotCQl9DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlmTGVmdCA9IDAuMGY7DQotCQlmQm90dG9tID0gMC4wZjsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIENQV0xfSWNvbjo6R2V0Rml0dGluZ0JvdW5kcygpDQotew0KLQlpZiAobV9wSWNvbkZpdCkNCi0JCXJldHVybiBtX3BJY29uRml0LT5HZXRGaXR0aW5nQm91bmRzKCk7DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBDUFdMX0ljb246OkdldFNjYWxlKEZYX0ZMT0FUICYgZkhTY2FsZSxGWF9GTE9BVCAmIGZWU2NhbGUpDQotew0KLQlmSFNjYWxlID0gMS4wZjsNCi0JZlZTY2FsZSA9IDEuMGY7DQotCQ0KLQlpZiAobV9wUERGU3RyZWFtKQ0KLQl7DQotCQlGWF9GTE9BVCBmSW1hZ2VXaWR0aCxmSW1hZ2VIZWlnaHQ7DQotCQlGWF9GTE9BVCBmUGxhdGVXaWR0aCxmUGxhdGVIZWlnaHQ7DQotDQotCQlDUERGX1JlY3QgcmNQbGF0ZSA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsJDQotCQlmUGxhdGVXaWR0aCA9IHJjUGxhdGUucmlnaHQgLSByY1BsYXRlLmxlZnQ7DQotCQlmUGxhdGVIZWlnaHQgPSByY1BsYXRlLnRvcCAtIHJjUGxhdGUuYm90dG9tOw0KLQ0KLQkJR2V0SW1hZ2VTaXplKGZJbWFnZVdpZHRoLGZJbWFnZUhlaWdodCk7DQotDQotCQlGWF9JTlQzMiBuU2NhbGVNZXRob2QgPSB0aGlzLT5HZXRTY2FsZU1ldGhvZCgpOw0KLQ0KLQkJLyoNCi0JCWVudW0gU2NhbGVNZXRob2QNCi0JCXsNCi0JCQlBbHdheXMgPSAwLAkvL0EsIEFsd2F5cyBzY2FsZQ0KLQkJCUJpZ2dlciwJCS8vQiwgU2NhbGUgb25seSB3aGVuIHRoZSBpY29uIGlzIGJpZ2dlciB0aGFuIHRoZSBhbm5vdGF0aW9uIHJlY3RhbmdsZQ0KLQkJCVNtYWxsZXIsCS8vUywgU2NhbGUgb25seSB3aGVuIHRoZSBpY29uIGlzIHNtYWxsZXIgdGhlbiB0aGUgYW5ub3RhdGlvbiByZWN0YW5nbGUNCi0JCQlOZXZlcgkJLy9OLCBOZXZlciBzY2FsZQ0KLQkJfTsNCi0JCSovDQotDQotCQlzd2l0Y2ggKG5TY2FsZU1ldGhvZCkNCi0JCXsNCi0JCWRlZmF1bHQ6DQotCQljYXNlIDA6DQotCQkJZkhTY2FsZSA9IGZQbGF0ZVdpZHRoIC8gUFdMX01BWChmSW1hZ2VXaWR0aCwxLjBmKTsNCi0JCQlmVlNjYWxlID0gZlBsYXRlSGVpZ2h0IC8gUFdMX01BWChmSW1hZ2VIZWlnaHQsMS4wZik7DQotCQkJYnJlYWs7DQotCQljYXNlIDE6DQotCQkJaWYgKGZQbGF0ZVdpZHRoIDwgZkltYWdlV2lkdGgpDQotCQkJCWZIU2NhbGUgPSBmUGxhdGVXaWR0aCAvIFBXTF9NQVgoZkltYWdlV2lkdGgsMS4wZik7DQotCQkJaWYgKGZQbGF0ZUhlaWdodCA8IGZJbWFnZUhlaWdodCkNCi0JCQkJZlZTY2FsZSA9IGZQbGF0ZUhlaWdodCAvIFBXTF9NQVgoZkltYWdlSGVpZ2h0LDEuMGYpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSAyOg0KLQkJCWlmIChmUGxhdGVXaWR0aCA+IGZJbWFnZVdpZHRoKQ0KLQkJCQlmSFNjYWxlID0gZlBsYXRlV2lkdGggLyBQV0xfTUFYKGZJbWFnZVdpZHRoLDEuMGYpOw0KLQkJCWlmIChmUGxhdGVIZWlnaHQgPiBmSW1hZ2VIZWlnaHQpDQotCQkJCWZWU2NhbGUgPSBmUGxhdGVIZWlnaHQgLyBQV0xfTUFYKGZJbWFnZUhlaWdodCwxLjBmKTsNCi0JCQlicmVhazsNCi0JCWNhc2UgMzoNCi0JCQlicmVhazsNCi0JCX0NCi0NCi0JCUZYX0ZMT0FUIGZNaW5TY2FsZTsNCi0JCWlmIChJc1Byb3BvcnRpb25hbFNjYWxlKCkpDQotCQl7DQotCQkJZk1pblNjYWxlID0gUFdMX01JTihmSFNjYWxlLGZWU2NhbGUpOw0KLQkJCWZIU2NhbGUgPSBmTWluU2NhbGU7DQotCQkJZlZTY2FsZSA9IGZNaW5TY2FsZTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfSWNvbjo6R2V0SW1hZ2VPZmZzZXQoRlhfRkxPQVQgJiB4LEZYX0ZMT0FUICYgeSkNCi17DQotCUZYX0ZMT0FUIGZMZWZ0LGZCb3R0b207DQotDQotCXRoaXMtPkdldEljb25Qb3NpdGlvbihmTGVmdCxmQm90dG9tKTsNCi0JeCA9IDAuMGY7DQotCXkgPSAwLjBmOw0KLQ0KLQlGWF9GTE9BVCBmSW1hZ2VXaWR0aCxmSW1hZ2VIZWlnaHQ7DQotCUdldEltYWdlU2l6ZShmSW1hZ2VXaWR0aCxmSW1hZ2VIZWlnaHQpOw0KLQ0KLQlGWF9GTE9BVCBmSFNjYWxlLGZWU2NhbGU7DQotCUdldFNjYWxlKGZIU2NhbGUsZlZTY2FsZSk7DQotDQotCUZYX0ZMT0FUIGZJbWFnZUZhY3RXaWR0aCA9IGZJbWFnZVdpZHRoICogZkhTY2FsZTsNCi0JRlhfRkxPQVQgZkltYWdlRmFjdEhlaWdodCA9IGZJbWFnZUhlaWdodCAqIGZWU2NhbGU7DQotDQotCUZYX0ZMT0FUIGZQbGF0ZVdpZHRoLGZQbGF0ZUhlaWdodDsNCi0JQ1BERl9SZWN0IHJjUGxhdGUgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7CQ0KLQlmUGxhdGVXaWR0aCA9IHJjUGxhdGUucmlnaHQgLSByY1BsYXRlLmxlZnQ7DQotCWZQbGF0ZUhlaWdodCA9IHJjUGxhdGUudG9wIC0gcmNQbGF0ZS5ib3R0b207DQotDQotCXggPSAoZlBsYXRlV2lkdGggLSBmSW1hZ2VGYWN0V2lkdGgpICogZkxlZnQ7DQotCXkgPSAoZlBsYXRlSGVpZ2h0IC0gZkltYWdlRmFjdEhlaWdodCkgICogZkJvdHRvbTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfSWNvbi5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfSW1hZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0ltYWdlOjpDUFdMX0ltYWdlKCkgOiBtX3BQREZTdHJlYW0oTlVMTCkKK3sKK30KKworQ1BXTF9JbWFnZTo6fkNQV0xfSW1hZ2UoKQoreworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX0ltYWdlOjpHZXRJbWFnZUFwcFN0cmVhbSgpCit7CisJQ0ZYX0J5dGVUZXh0QnVmIHNBcHBTdHJlYW07CisKKwlDRlhfQnl0ZVN0cmluZyBzQWxpYXMgPSB0aGlzLT5HZXRJbWFnZUFsaWFzKCk7CisJQ1BERl9SZWN0IHJjUGxhdGUgPSBHZXRDbGllbnRSZWN0KCk7CisJQ1BERl9NYXRyaXggbXQ7CisJbXQuU2V0UmV2ZXJzZShHZXRJbWFnZU1hdHJpeCgpKTsKKworCUZYX0ZMT0FUIGZIU2NhbGUgPSAxLjBmOworCUZYX0ZMT0FUIGZWU2NhbGUgPSAxLjBmOworCUdldFNjYWxlKGZIU2NhbGUsZlZTY2FsZSk7CisKKwlGWF9GTE9BVCBmeCA9IDAuMGY7CisJRlhfRkxPQVQgZnkgPSAwLjBmOworCUdldEltYWdlT2Zmc2V0KGZ4LGZ5KTsKKworCWlmIChtX3BQREZTdHJlYW0gJiYgc0FsaWFzLkdldExlbmd0aCgpPjApCisJeworCQlzQXBwU3RyZWFtIDw8ICJxXG4iOworCQlzQXBwU3RyZWFtIDw8IHJjUGxhdGUubGVmdCA8PCAiICIgPDwgcmNQbGF0ZS5ib3R0b20gPDwgIiAiCisJCQk8PCByY1BsYXRlLnJpZ2h0IC0gcmNQbGF0ZS5sZWZ0IDw8ICIgIiA8PCByY1BsYXRlLnRvcCAtIHJjUGxhdGUuYm90dG9tIDw8ICIgcmUgVyBuXG4iOworCisJCXNBcHBTdHJlYW0gPDwgZkhTY2FsZSA8PCAiIDAgMCAiIDw8IGZWU2NhbGUgPDwgIiAiIDw8IHJjUGxhdGUubGVmdCArIGZ4IDw8ICIgIiA8PCByY1BsYXRlLmJvdHRvbSArIGZ5IDw8ICIgY21cbiI7CisJCXNBcHBTdHJlYW0gPDwgbXQuR2V0QSgpIDw8ICIgIiA8PCBtdC5HZXRCKCkgPDwgIiAiIDw8IG10LkdldEMoKSA8PCAiICIgPDwgbXQuR2V0RCgpIDw8ICIgIiA8PCBtdC5HZXRFKCkgPDwgIiAiIDw8IG10LkdldEYoKSA8PCAiIGNtXG4iOworCisJCXNBcHBTdHJlYW0gPDwgIjAgZyAwIEcgMSB3IC8iIDw8IHNBbGlhcyA8PCAiIERvXG4iIDw8ICJRXG4iOworCX0KKworCXJldHVybiBzQXBwU3RyZWFtLkdldEJ5dGVTdHJpbmcoKTsKK30KKwordm9pZCBDUFdMX0ltYWdlOjpTZXRQREZTdHJlYW0oQ1BERl9TdHJlYW0gKiBwU3RyZWFtKQoreworCW1fcFBERlN0cmVhbSA9IHBTdHJlYW07Cit9CisKK0NQREZfU3RyZWFtICogQ1BXTF9JbWFnZTo6R2V0UERGU3RyZWFtKCkKK3sKKwlyZXR1cm4gdGhpcy0+bV9wUERGU3RyZWFtOworfQorCit2b2lkIENQV0xfSW1hZ2U6OkdldEltYWdlU2l6ZShGWF9GTE9BVCAmIGZXaWR0aCxGWF9GTE9BVCAmIGZIZWlnaHQpCit7CisJZldpZHRoID0gMC4wZjsKKwlmSGVpZ2h0ID0gMC4wZjsKKworCWlmIChtX3BQREZTdHJlYW0pCisJeworCQlpZiAoQ1BERl9EaWN0aW9uYXJ5ICogcERpY3QgPSBtX3BQREZTdHJlYW0tPkdldERpY3QoKSkKKwkJeworCQkJQ1BERl9SZWN0IHJlY3QgPSBwRGljdC0+R2V0UmVjdCgiQkJveCIpOworCisJCQlmV2lkdGggPSByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0OworCQkJZkhlaWdodCA9IHJlY3QudG9wIC0gcmVjdC5ib3R0b207CisJCX0KKwl9Cit9CisKK0NQREZfTWF0cml4CUNQV0xfSW1hZ2U6OkdldEltYWdlTWF0cml4KCkKK3sKKwlpZiAobV9wUERGU3RyZWFtKQorCXsKKwkJaWYgKENQREZfRGljdGlvbmFyeSAqIHBEaWN0ID0gbV9wUERGU3RyZWFtLT5HZXREaWN0KCkpCisJCXsKKwkJCXJldHVybiBwRGljdC0+R2V0TWF0cml4KCJNYXRyaXgiKTsKKwkJfQorCX0KKworCXJldHVybiBDUERGX01hdHJpeCgpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX0ltYWdlOjpHZXRJbWFnZUFsaWFzKCkKK3sKKwlpZiAobV9zSW1hZ2VBbGlhcy5Jc0VtcHR5KCkpCisJeworCQlpZiAobV9wUERGU3RyZWFtKQorCQl7CisJCQlpZiAoQ1BERl9EaWN0aW9uYXJ5ICogcERpY3QgPSBtX3BQREZTdHJlYW0tPkdldERpY3QoKSkJCQorCQkJeworCQkJCXJldHVybiBwRGljdC0+R2V0U3RyaW5nKCJOYW1lIik7CisJCQl9CisJCX0KKwl9CisJZWxzZQorCQlyZXR1cm4gbV9zSW1hZ2VBbGlhczsKKworCXJldHVybiBDRlhfQnl0ZVN0cmluZygpOworfQorCit2b2lkIENQV0xfSW1hZ2U6OlNldEltYWdlQWxpYXMoRlhfTFBDU1RSIHNJbWFnZUFsaWFzKQoreworCW1fc0ltYWdlQWxpYXMgPSBzSW1hZ2VBbGlhczsKK30KKwordm9pZCBDUFdMX0ltYWdlOjpHZXRTY2FsZShGWF9GTE9BVCAmIGZIU2NhbGUsRlhfRkxPQVQgJiBmVlNjYWxlKQoreworCWZIU2NhbGUgPSAxLjBmOworCWZWU2NhbGUgPSAxLjBmOworfQorCisKK3ZvaWQgQ1BXTF9JbWFnZTo6R2V0SW1hZ2VPZmZzZXQoRlhfRkxPQVQgJiB4LEZYX0ZMT0FUICYgeSkKK3sKKwl4ID0gMC4wZjsKKwl5ID0gMC4wZjsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0ljb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0ljb246OkNQV0xfSWNvbigpIDogbV9wSWNvbkZpdChOVUxMKQoreworfQorCitDUFdMX0ljb246On5DUFdMX0ljb24oKQoreworfQorCitGWF9JTlQzMiBDUFdMX0ljb246OkdldFNjYWxlTWV0aG9kKCkKK3sKKwlpZiAobV9wSWNvbkZpdCkKKwkJcmV0dXJuIG1fcEljb25GaXQtPkdldFNjYWxlTWV0aG9kKCk7CisKKwlyZXR1cm4gMDsKK30KKworRlhfQk9PTAlDUFdMX0ljb246OklzUHJvcG9ydGlvbmFsU2NhbGUoKQoreworCWlmIChtX3BJY29uRml0KQorCQlyZXR1cm4gbV9wSWNvbkZpdC0+SXNQcm9wb3J0aW9uYWxTY2FsZSgpOworCisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIENQV0xfSWNvbjo6R2V0SWNvblBvc2l0aW9uKEZYX0ZMT0FUICYgZkxlZnQsIEZYX0ZMT0FUICYgZkJvdHRvbSkKK3sKKwlpZiAobV9wSWNvbkZpdCkKKwl7CisJCS8vbV9wSWNvbkZpdC0+R2V0SWNvblBvc2l0aW9uKGZMZWZ0LGZCb3R0b20pOworCQlmTGVmdCA9IDAuMGY7CisJCWZCb3R0b20gPSAwLjBmOworCQlDUERGX0FycmF5KiBwQSA9IG1fcEljb25GaXQtPm1fcERpY3QtPkdldEFycmF5KCJBIik7CisJCWlmIChwQSAhPSBOVUxMKQorCQl7CisJCQlGWF9EV09SRCBkd0NvdW50ID0gcEEtPkdldENvdW50KCk7CisJCQlpZiAoZHdDb3VudCA+IDApIGZMZWZ0ID0gcEEtPkdldE51bWJlcigwKTsKKwkJCWlmIChkd0NvdW50ID4gMSkgZkJvdHRvbSA9IHBBLT5HZXROdW1iZXIoMSk7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJZkxlZnQgPSAwLjBmOworCQlmQm90dG9tID0gMC4wZjsKKwl9Cit9CisKK0ZYX0JPT0wgQ1BXTF9JY29uOjpHZXRGaXR0aW5nQm91bmRzKCkKK3sKKwlpZiAobV9wSWNvbkZpdCkKKwkJcmV0dXJuIG1fcEljb25GaXQtPkdldEZpdHRpbmdCb3VuZHMoKTsKKworCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDUFdMX0ljb246OkdldFNjYWxlKEZYX0ZMT0FUICYgZkhTY2FsZSxGWF9GTE9BVCAmIGZWU2NhbGUpCit7CisJZkhTY2FsZSA9IDEuMGY7CisJZlZTY2FsZSA9IDEuMGY7CisJCisJaWYgKG1fcFBERlN0cmVhbSkKKwl7CisJCUZYX0ZMT0FUIGZJbWFnZVdpZHRoLGZJbWFnZUhlaWdodDsKKwkJRlhfRkxPQVQgZlBsYXRlV2lkdGgsZlBsYXRlSGVpZ2h0OworCisJCUNQREZfUmVjdCByY1BsYXRlID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOwkKKwkJZlBsYXRlV2lkdGggPSByY1BsYXRlLnJpZ2h0IC0gcmNQbGF0ZS5sZWZ0OworCQlmUGxhdGVIZWlnaHQgPSByY1BsYXRlLnRvcCAtIHJjUGxhdGUuYm90dG9tOworCisJCUdldEltYWdlU2l6ZShmSW1hZ2VXaWR0aCxmSW1hZ2VIZWlnaHQpOworCisJCUZYX0lOVDMyIG5TY2FsZU1ldGhvZCA9IHRoaXMtPkdldFNjYWxlTWV0aG9kKCk7CisKKwkJLyoKKwkJZW51bSBTY2FsZU1ldGhvZAorCQl7CisJCQlBbHdheXMgPSAwLAkvL0EsIEFsd2F5cyBzY2FsZQorCQkJQmlnZ2VyLAkJLy9CLCBTY2FsZSBvbmx5IHdoZW4gdGhlIGljb24gaXMgYmlnZ2VyIHRoYW4gdGhlIGFubm90YXRpb24gcmVjdGFuZ2xlCisJCQlTbWFsbGVyLAkvL1MsIFNjYWxlIG9ubHkgd2hlbiB0aGUgaWNvbiBpcyBzbWFsbGVyIHRoZW4gdGhlIGFubm90YXRpb24gcmVjdGFuZ2xlCisJCQlOZXZlcgkJLy9OLCBOZXZlciBzY2FsZQorCQl9OworCQkqLworCisJCXN3aXRjaCAoblNjYWxlTWV0aG9kKQorCQl7CisJCWRlZmF1bHQ6CisJCWNhc2UgMDoKKwkJCWZIU2NhbGUgPSBmUGxhdGVXaWR0aCAvIFBXTF9NQVgoZkltYWdlV2lkdGgsMS4wZik7CisJCQlmVlNjYWxlID0gZlBsYXRlSGVpZ2h0IC8gUFdMX01BWChmSW1hZ2VIZWlnaHQsMS4wZik7CisJCQlicmVhazsKKwkJY2FzZSAxOgorCQkJaWYgKGZQbGF0ZVdpZHRoIDwgZkltYWdlV2lkdGgpCisJCQkJZkhTY2FsZSA9IGZQbGF0ZVdpZHRoIC8gUFdMX01BWChmSW1hZ2VXaWR0aCwxLjBmKTsKKwkJCWlmIChmUGxhdGVIZWlnaHQgPCBmSW1hZ2VIZWlnaHQpCisJCQkJZlZTY2FsZSA9IGZQbGF0ZUhlaWdodCAvIFBXTF9NQVgoZkltYWdlSGVpZ2h0LDEuMGYpOworCQkJYnJlYWs7CisJCWNhc2UgMjoKKwkJCWlmIChmUGxhdGVXaWR0aCA+IGZJbWFnZVdpZHRoKQorCQkJCWZIU2NhbGUgPSBmUGxhdGVXaWR0aCAvIFBXTF9NQVgoZkltYWdlV2lkdGgsMS4wZik7CisJCQlpZiAoZlBsYXRlSGVpZ2h0ID4gZkltYWdlSGVpZ2h0KQorCQkJCWZWU2NhbGUgPSBmUGxhdGVIZWlnaHQgLyBQV0xfTUFYKGZJbWFnZUhlaWdodCwxLjBmKTsKKwkJCWJyZWFrOworCQljYXNlIDM6CisJCQlicmVhazsKKwkJfQorCisJCUZYX0ZMT0FUIGZNaW5TY2FsZTsKKwkJaWYgKElzUHJvcG9ydGlvbmFsU2NhbGUoKSkKKwkJeworCQkJZk1pblNjYWxlID0gUFdMX01JTihmSFNjYWxlLGZWU2NhbGUpOworCQkJZkhTY2FsZSA9IGZNaW5TY2FsZTsKKwkJCWZWU2NhbGUgPSBmTWluU2NhbGU7CisJCX0KKwl9Cit9CisKK3ZvaWQgQ1BXTF9JY29uOjpHZXRJbWFnZU9mZnNldChGWF9GTE9BVCAmIHgsRlhfRkxPQVQgJiB5KQoreworCUZYX0ZMT0FUIGZMZWZ0LGZCb3R0b207CisKKwl0aGlzLT5HZXRJY29uUG9zaXRpb24oZkxlZnQsZkJvdHRvbSk7CisJeCA9IDAuMGY7CisJeSA9IDAuMGY7CisKKwlGWF9GTE9BVCBmSW1hZ2VXaWR0aCxmSW1hZ2VIZWlnaHQ7CisJR2V0SW1hZ2VTaXplKGZJbWFnZVdpZHRoLGZJbWFnZUhlaWdodCk7CisKKwlGWF9GTE9BVCBmSFNjYWxlLGZWU2NhbGU7CisJR2V0U2NhbGUoZkhTY2FsZSxmVlNjYWxlKTsKKworCUZYX0ZMT0FUIGZJbWFnZUZhY3RXaWR0aCA9IGZJbWFnZVdpZHRoICogZkhTY2FsZTsKKwlGWF9GTE9BVCBmSW1hZ2VGYWN0SGVpZ2h0ID0gZkltYWdlSGVpZ2h0ICogZlZTY2FsZTsKKworCUZYX0ZMT0FUIGZQbGF0ZVdpZHRoLGZQbGF0ZUhlaWdodDsKKwlDUERGX1JlY3QgcmNQbGF0ZSA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsJCisJZlBsYXRlV2lkdGggPSByY1BsYXRlLnJpZ2h0IC0gcmNQbGF0ZS5sZWZ0OworCWZQbGF0ZUhlaWdodCA9IHJjUGxhdGUudG9wIC0gcmNQbGF0ZS5ib3R0b207CisKKwl4ID0gKGZQbGF0ZVdpZHRoIC0gZkltYWdlRmFjdFdpZHRoKSAqIGZMZWZ0OworCXkgPSAoZlBsYXRlSGVpZ2h0IC0gZkltYWdlRmFjdEhlaWdodCkgICogZkJvdHRvbTsKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9JY29uTGlzdC5jcHAgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0ljb25MaXN0LmNwcAppbmRleCAwOWI2Njc4Li43MjMxNzkwIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0ljb25MaXN0LmNwcAorKysgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0ljb25MaXN0LmNwcApAQCAtMSw1OTIgKzEsNTkyIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9JY29uTGlzdC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGFiZWwuaCINCi0NCi0jZGVmaW5lIFBXTF9JY29uTGlzdF9JVEVNX0lDT05fTEVGVE1BUkdJTgkJMTAuMGYNCi0jZGVmaW5lIFBXTF9JY29uTGlzdF9JVEVNX1dJRFRICQkJCQkyMC4wZg0KLSNkZWZpbmUgUFdMX0ljb25MaXN0X0lURU1fSEVJR0hUCQkJCTIwLjBmDQotI2RlZmluZSBQV0xfSWNvbkxpc3RfSVRFTV9TUEFDRQkJCQkJNC4wZg0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0ljb25MaXN0X0l0ZW0gLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNQV0xfSWNvbkxpc3RfSXRlbTo6Q1BXTF9JY29uTGlzdF9JdGVtKCkgOiANCi0JbV9uSWNvbkluZGV4KC0xKSwgDQotCW1fcERhdGEoTlVMTCksDQotCW1fYlNlbGVjdGVkKEZBTFNFKSwNCi0JbV9wVGV4dChOVUxMKQ0KLXsNCi19DQotDQotQ1BXTF9JY29uTGlzdF9JdGVtOjp+Q1BXTF9JY29uTGlzdF9JdGVtKCkNCi17DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfSWNvbkxpc3RfSXRlbTo6R2V0Q2xhc3NOYW1lKCkgY29uc3QNCi17DQotCXJldHVybiAiQ1BXTF9JY29uTGlzdF9JdGVtIjsNCi19DQotDQotRlhfRkxPQVQgQ1BXTF9JY29uTGlzdF9JdGVtOjpHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKQ0KLXsNCi0JcmV0dXJuIFBXTF9JY29uTGlzdF9JVEVNX0hFSUdIVDsNCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0X0l0ZW06OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0KLXsNCi0JQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQlpZiAobV9iU2VsZWN0ZWQpDQotCXsNCi0JCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkNCi0JCXsNCi0JCQlDUFdMX1V0aWxzOjpEcmF3RmlsbFJlY3QocERldmljZSwgcFVzZXIyRGV2aWNlLCByY0NsaWVudCwgDQotCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKFBXTF9ERUZBVUxUX1NFTEJBQ0tDT0xPUix0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSkpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCUNQV0xfVXRpbHM6OkRyYXdGaWxsUmVjdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHJjQ2xpZW50LCANCi0JCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoUFdMX0RFRkFVTFRfTElHSFRHUkFZQ09MT1IsdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpKTsNCi0JCX0NCi0JfQ0KLQ0KLQlDUERGX1JlY3QgcmNJY29uID0gcmNDbGllbnQ7DQotCXJjSWNvbi5sZWZ0ICs9IFBXTF9JY29uTGlzdF9JVEVNX0lDT05fTEVGVE1BUkdJTjsNCi0JcmNJY29uLnJpZ2h0ID0gcmNJY29uLmxlZnQgKyBQV0xfSWNvbkxpc3RfSVRFTV9XSURUSDsNCi0NCi0JQ1BXTF9VdGlsczo6RHJhd0ljb25BcHBTdHJlYW0ocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX25JY29uSW5kZXgsIHJjSWNvbiwgDQotCQltX2NySWNvbiwgbV9wVGV4dC0+R2V0VGV4dENvbG9yKCksIHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKTsNCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0X0l0ZW06OlNldFNlbGVjdChGWF9CT09MIGJTZWxlY3RlZCkNCi17DQotCW1fYlNlbGVjdGVkID0gYlNlbGVjdGVkOw0KLQ0KLQlpZiAoYlNlbGVjdGVkKQ0KLQkJbV9wVGV4dC0+U2V0VGV4dENvbG9yKFBXTF9ERUZBVUxUX1dISVRFQ09MT1IpOw0KLQllbHNlDQotCQltX3BUZXh0LT5TZXRUZXh0Q29sb3IoUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUik7DQotDQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9JY29uTGlzdF9JdGVtOjpJc1NlbGVjdGVkKCkgY29uc3QNCi17DQotCXJldHVybiBtX2JTZWxlY3RlZDsNCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0X0l0ZW06OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0KLXsNCi0JbV9wVGV4dCA9IG5ldyBDUFdMX0xhYmVsOw0KLQ0KLQlQV0xfQ1JFQVRFUEFSQU0gbGNwID0gY3A7DQotCWxjcC5wUGFyZW50V25kID0gdGhpczsNCi0JbGNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBFU19MRUZUIHwgUEVTX0NFTlRFUjsNCi0JbGNwLnNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOw0KLQlsY3AuZkZvbnRTaXplID0gMTI7DQotCW1fcFRleHQtPkNyZWF0ZShsY3ApOw0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6U2V0RGF0YSh2b2lkKiBwRGF0YSkNCi17DQotCW1fcERhdGEgPSBwRGF0YTsNCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0X0l0ZW06OlNldEljb24oRlhfSU5UMzIgbkljb25JbmRleCkNCi17DQotCW1fbkljb25JbmRleCA9IG5JY29uSW5kZXg7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdF9JdGVtOjpTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHIpDQotew0KLQltX3BUZXh0LT5TZXRUZXh0KHN0cik7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENQV0xfSWNvbkxpc3RfSXRlbTo6R2V0VGV4dCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wVGV4dC0+R2V0VGV4dCgpOw0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6UmVQb3NDaGlsZFduZCgpDQotew0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotDQotCXJjQ2xpZW50LmxlZnQgKz0gKFBXTF9JY29uTGlzdF9JVEVNX0lDT05fTEVGVE1BUkdJTiArIFBXTF9JY29uTGlzdF9JVEVNX1dJRFRIICsgUFdMX0ljb25MaXN0X0lURU1fSUNPTl9MRUZUTUFSR0lOKTsNCi0NCi0JbV9wVGV4dC0+TW92ZShyY0NsaWVudCwgVFJVRSwgRkFMU0UpOw0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6U2V0SWNvbkZpbGxDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikNCi17DQotCW1fY3JJY29uID0gY29sb3I7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdF9JdGVtOjpPbkVuYWJsZWQoKQ0KLXsNCi0JaWYgKG1fYlNlbGVjdGVkKQ0KLQkJbV9wVGV4dC0+U2V0VGV4dENvbG9yKFBXTF9ERUZBVUxUX1dISVRFQ09MT1IpOw0KLQllbHNlDQotCQltX3BUZXh0LT5TZXRUZXh0Q29sb3IoUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUik7DQotDQotCXRoaXMtPkludmFsaWRhdGVSZWN0KCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdF9JdGVtOjpPbkRpc2FibGVkKCkNCi17DQotCW1fcFRleHQtPlNldFRleHRDb2xvcihQV0xfREVGQVVMVF9IRUFWWUdSQVlDT0xPUik7DQotDQotCXRoaXMtPkludmFsaWRhdGVSZWN0KCk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tIENQV0xfSWNvbkxpc3RfQ29udGVudCAtLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNQV0xfSWNvbkxpc3RfQ29udGVudDo6Q1BXTF9JY29uTGlzdF9Db250ZW50KEZYX0lOVDMyIG5MaXN0Q291bnQpIDogDQotCW1fblNlbGVjdEluZGV4KC0xKSwNCi0JbV9wTm90aWZ5KE5VTEwpLA0KLQltX2JFbmFibGVOb3RpZnkoVFJVRSksDQotCW1fYk1vdXNlRG93bihGQUxTRSksDQotCW1fbkxpc3RDb3VudChuTGlzdENvdW50KQ0KLXsNCi19DQotDQotQ1BXTF9JY29uTGlzdF9Db250ZW50Ojp+Q1BXTF9JY29uTGlzdF9Db250ZW50KCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCi17DQotCWZvciAoRlhfSU5UMzIgaT0wOyBpPG1fbkxpc3RDb3VudDsgaSsrKQ0KLQl7DQotCQlDUFdMX0ljb25MaXN0X0l0ZW0qIHBOZXdJdGVtID0gbmV3IENQV0xfSWNvbkxpc3RfSXRlbSgpOw0KLQ0KLQkJUFdMX0NSRUFURVBBUkFNIGljcCA9IGNwOw0KLQkJaWNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQkJaWNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19OT1JFRlJFU0hDTElQOw0KLQkJcE5ld0l0ZW0tPkNyZWF0ZShpY3ApOw0KLQl9DQotDQotCXRoaXMtPlNldEl0ZW1TcGFjZShQV0xfSWNvbkxpc3RfSVRFTV9TUEFDRSk7DQotCXRoaXMtPlJlc2V0Q29udGVudCgwKTsNCi0NCi0JaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQ0KLQl7DQotCQlDUERGX1JlY3QgcmNTY3JvbGwgPSB0aGlzLT5HZXRTY3JvbGxBcmVhKCk7DQotCQl0aGlzLT5HZXRTY3JvbGxQb3MoKTsNCi0NCi0JCVBXTF9TQ1JPTExfSU5GTyBzSW5mbzsNCi0JCXNJbmZvLmZDb250ZW50TWluID0gcmNTY3JvbGwuYm90dG9tOw0KLQkJc0luZm8uZkNvbnRlbnRNYXggPSByY1Njcm9sbC50b3A7DQotCQlzSW5mby5mUGxhdGVXaWR0aCA9IEdldENsaWVudFJlY3QoKS5IZWlnaHQoKTsNCi0JCXNJbmZvLmZTbWFsbFN0ZXAgPSAxMy4wZjsNCi0JCXNJbmZvLmZCaWdTdGVwID0gc0luZm8uZlBsYXRlV2lkdGg7DQotDQotCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMSU5GTywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnNJbmZvKTsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MCUNQV0xfSWNvbkxpc3RfQ29udGVudDo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpDQotew0KLQlTZXRGb2N1cygpOw0KLQ0KLQlTZXRDYXB0dXJlKCk7DQotCW1fYk1vdXNlRG93biA9IFRSVUU7DQotDQotCUZYX0lOVDMyIG5JdGVtSW5kZXggPSBGaW5kSXRlbUluZGV4KHBvaW50KTsNCi0JU2V0U2VsZWN0KG5JdGVtSW5kZXgpOw0KLQlTY3JvbGxUb0l0ZW0obkl0ZW1JbmRleCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNQV0xfSWNvbkxpc3RfQ29udGVudDo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQ0KLXsNCi0JbV9iTW91c2VEb3duID0gRkFMU0U7DQotCVJlbGVhc2VDYXB0dXJlKCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfSWNvbkxpc3RfQ29udGVudDo6T25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQ0KLXsNCi0JaWYgKG1fYk1vdXNlRG93bikNCi0Jew0KLQkJRlhfSU5UMzIgbkl0ZW1JbmRleCA9IEZpbmRJdGVtSW5kZXgocG9pbnQpOw0KLQkJU2V0U2VsZWN0KG5JdGVtSW5kZXgpOw0KLQkJU2Nyb2xsVG9JdGVtKG5JdGVtSW5kZXgpOw0KLQl9DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNQV0xfSWNvbkxpc3RfQ29udGVudDo6T25LZXlEb3duKEZYX1dPUkQgbkNoYXIpDQotew0KLQlzd2l0Y2ggKG5DaGFyKQ0KLQl7DQotCWNhc2UgRldMX1ZLRVlfVXA6DQotCQlpZiAobV9uU2VsZWN0SW5kZXggPiAwKQ0KLQkJew0KLQkJCUZYX0lOVDMyIG5JdGVtSW5kZXggPSBtX25TZWxlY3RJbmRleCAtIDE7DQotCQkJU2V0U2VsZWN0KG5JdGVtSW5kZXgpOw0KLQkJCVNjcm9sbFRvSXRlbShuSXRlbUluZGV4KTsNCi0JCX0NCi0JCXJldHVybiBUUlVFOw0KLQljYXNlIEZXTF9WS0VZX0Rvd246DQotCQlpZiAobV9uU2VsZWN0SW5kZXggPCBtX25MaXN0Q291bnQtMSkNCi0JCXsNCi0JCQlGWF9JTlQzMiBuSXRlbUluZGV4ID0gbV9uU2VsZWN0SW5kZXggKyAxOw0KLQkJCVNldFNlbGVjdChuSXRlbUluZGV4KTsNCi0JCQlTY3JvbGxUb0l0ZW0obkl0ZW1JbmRleCk7DQotCQl9DQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfSWNvbkxpc3RfQ29udGVudDo6RmluZEl0ZW1JbmRleChjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCUZYX0lOVDMyIG5JbmRleCA9IDA7DQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkNCi0JCXsNCi0JCQlDUERGX1JlY3QgcmNXbmQgPSBwQ2hpbGQtPkNoaWxkVG9QYXJlbnQocENoaWxkLT5HZXRXaW5kb3dSZWN0KCkpOw0KLQ0KLQkJCWlmIChwb2ludC55IDwgcmNXbmQudG9wKQ0KLQkJCXsNCi0JCQkJbkluZGV4ID0gaTsNCi0JCQl9DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIG5JbmRleDsNCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OlNjcm9sbFRvSXRlbShGWF9JTlQzMiBuSXRlbUluZGV4KQ0KLXsNCi0JQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQlpZiAoQ1BXTF9JY29uTGlzdF9JdGVtKiBwSXRlbSA9IEdldExpc3RJdGVtKG5JdGVtSW5kZXgpKQ0KLQl7DQotCQlDUERGX1JlY3QgcmNPcmlnaW4gPSBwSXRlbS0+R2V0V2luZG93UmVjdCgpOw0KLQkJQ1BERl9SZWN0IHJjV25kID0gcEl0ZW0tPkNoaWxkVG9QYXJlbnQocmNPcmlnaW4pOw0KLQ0KLQkJaWYgKCEocmNXbmQuYm90dG9tID4gcmNDbGllbnQuYm90dG9tICYmIHJjV25kLnRvcCA8IHJjQ2xpZW50LnRvcCkpDQotCQl7DQotCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IEdldFNjcm9sbFBvcygpOw0KLQ0KLQkJCWlmIChyY1duZC50b3AgPiByY0NsaWVudC50b3ApDQotCQkJew0KLQkJCQlwdFNjcm9sbC55ID0gcmNPcmlnaW4udG9wOw0KLQkJCX0NCi0JCQllbHNlIGlmIChyY1duZC5ib3R0b20gPCByY0NsaWVudC5ib3R0b20pDQotCQkJew0KLQkJCQlwdFNjcm9sbC55ID0gcmNPcmlnaW4uYm90dG9tICsgcmNDbGllbnQuSGVpZ2h0KCk7CQkJCQkNCi0JCQl9DQotDQotCQkJdGhpcy0+U2V0U2Nyb2xsUG9zKHB0U2Nyb2xsKTsNCi0JCQl0aGlzLT5SZXNldEZhY2UoKTsNCi0JCQl0aGlzLT5JbnZhbGlkYXRlUmVjdCgpOw0KLQkJCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQ0KLQkJCXsNCi0JCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0U2Nyb2xsLnkpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3RfQ29udGVudDo6U2V0U2VsZWN0KEZYX0lOVDMyIG5JbmRleCkNCi17DQotCWlmIChtX25TZWxlY3RJbmRleCAhPSBuSW5kZXgpDQotCXsNCi0JCVNlbGVjdEl0ZW0obV9uU2VsZWN0SW5kZXgsIEZBTFNFKTsNCi0JCVNlbGVjdEl0ZW0obkluZGV4LCBUUlVFKTsNCi0JCW1fblNlbGVjdEluZGV4ID0gbkluZGV4Ow0KLQ0KLQkJaWYgKElQV0xfSWNvbkxpc3RfTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90aWZ5KCkpDQotCQkJcE5vdGlmeS0+T25Ob3RlTGlzdFNlbENoYW5nZWQobkluZGV4KTsNCi0JfQ0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OkdldFNlbGVjdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9uU2VsZWN0SW5kZXg7DQotfQ0KLQ0KLUlQV0xfSWNvbkxpc3RfTm90aWZ5KiBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OkdldE5vdGlmeSgpIGNvbnN0DQotew0KLQlpZiAobV9iRW5hYmxlTm90aWZ5KQ0KLQkJcmV0dXJuIG1fcE5vdGlmeTsNCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpTZXROb3RpZnkoSVBXTF9JY29uTGlzdF9Ob3RpZnkqIHBOb3RpZnkpDQotew0KLQltX3BOb3RpZnkgPSBwTm90aWZ5Ow0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3RfQ29udGVudDo6RW5hYmxlTm90aWZ5KEZYX0JPT0wgYk5vdGlmeSkNCi17DQotCW1fYkVuYWJsZU5vdGlmeSA9IGJOb3RpZnk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpTZWxlY3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYlNlbGVjdCkNCi17DQotCWlmIChDUFdMX0ljb25MaXN0X0l0ZW0qIHBJdGVtID0gR2V0TGlzdEl0ZW0obkl0ZW1JbmRleCkpDQotCXsNCi0JCXBJdGVtLT5TZXRTZWxlY3QoYlNlbGVjdCk7DQotCQlwSXRlbS0+SW52YWxpZGF0ZVJlY3QoKTsJCQ0KLQl9DQotfQ0KLQ0KLUNQV0xfSWNvbkxpc3RfSXRlbSogQ1BXTF9JY29uTGlzdF9Db250ZW50OjpHZXRMaXN0SXRlbShGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdA0KLXsNCi0JaWYgKG5JdGVtSW5kZXggPj0gMCAmJiBuSXRlbUluZGV4PG1fYUNoaWxkcmVuLkdldFNpemUoKSkNCi0Jew0KLQkJaWYgKENQV0xfV25kICogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQobkl0ZW1JbmRleCkpDQotCQl7DQotCQkJaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfSWNvbkxpc3RfSXRlbSIpDQotCQkJew0KLQkJCQlyZXR1cm4gKENQV0xfSWNvbkxpc3RfSXRlbSopcENoaWxkOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OlNldExpc3REYXRhKEZYX0lOVDMyIG5JdGVtSW5kZXgsIHZvaWQqIHBEYXRhKQ0KLXsNCi0JaWYgKENQV0xfSWNvbkxpc3RfSXRlbSogcEl0ZW0gPSBHZXRMaXN0SXRlbShuSXRlbUluZGV4KSkNCi0JCXBJdGVtLT5TZXREYXRhKHBEYXRhKTsNCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OlNldExpc3RJY29uKEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0lOVDMyIG5JY29uSW5kZXgpDQotew0KLQlpZiAoQ1BXTF9JY29uTGlzdF9JdGVtKiBwSXRlbSA9IEdldExpc3RJdGVtKG5JdGVtSW5kZXgpKQ0KLQkJcEl0ZW0tPlNldEljb24obkljb25JbmRleCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpTZXRMaXN0U3RyaW5nKEZYX0lOVDMyIG5JdGVtSW5kZXgsIGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHIpDQotew0KLQlpZiAoQ1BXTF9JY29uTGlzdF9JdGVtKiBwSXRlbSA9IEdldExpc3RJdGVtKG5JdGVtSW5kZXgpKQ0KLQkJcEl0ZW0tPlNldFRleHQoc3RyKTsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpHZXRMaXN0U3RyaW5nKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0DQotew0KLQlpZiAoQ1BXTF9JY29uTGlzdF9JdGVtKiBwSXRlbSA9IEdldExpc3RJdGVtKG5JdGVtSW5kZXgpKQ0KLQkJcmV0dXJuIHBJdGVtLT5HZXRUZXh0KCk7DQotDQotCXJldHVybiBMIiI7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpTZXRJY29uRmlsbENvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQ0KLXsNCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQ0KLQkJew0KLQkJCWlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX0ljb25MaXN0X0l0ZW0iKQ0KLQkJCXsNCi0JCQkJQ1BXTF9JY29uTGlzdF9JdGVtKiBwSXRlbSA9IChDUFdMX0ljb25MaXN0X0l0ZW0qKXBDaGlsZDsNCi0JCQkJcEl0ZW0tPlNldEljb25GaWxsQ29sb3IoY29sb3IpOw0KLQkJCQlwSXRlbS0+SW52YWxpZGF0ZVJlY3QoKTsNCi0JCQl9DQotCQl9DQotCX0NCi0NCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9JY29uTGlzdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0ljb25MaXN0OjpDUFdMX0ljb25MaXN0KEZYX0lOVDMyIG5MaXN0Q291bnQpIDogDQotCW1fcExpc3RDb250ZW50KE5VTEwpLA0KLQltX25MaXN0Q291bnQobkxpc3RDb3VudCkNCi17DQotfQ0KLQ0KLUNQV0xfSWNvbkxpc3Q6On5DUFdMX0ljb25MaXN0KCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdDo6UmVQb3NDaGlsZFduZCgpDQotew0KLQlDUFdMX1duZDo6UmVQb3NDaGlsZFduZCgpOw0KLQ0KLQlpZiAobV9wTGlzdENvbnRlbnQpDQotCQltX3BMaXN0Q29udGVudC0+TW92ZShHZXRDbGllbnRSZWN0KCksIFRSVUUsIEZBTFNFKTsNCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0OjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCi17DQotCW1fcExpc3RDb250ZW50ID0gbmV3IENQV0xfSWNvbkxpc3RfQ29udGVudChtX25MaXN0Q291bnQpOw0KLQ0KLQlQV0xfQ1JFQVRFUEFSQU0gY2NwID0gY3A7DQotCWNjcC5wUGFyZW50V25kID0gdGhpczsNCi0JY2NwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRTsNCi0JbV9wTGlzdENvbnRlbnQtPkNyZWF0ZShjY3ApOw0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3Q6Ok9uQ3JlYXRlZCgpDQotew0KLQlpZiAoQ1BXTF9TY3JvbGxCYXIqIHBTY3JvbGxCYXIgPSB0aGlzLT5HZXRWU2Nyb2xsQmFyKCkpDQotCXsNCi0JCXBTY3JvbGxCYXItPlJlbW92ZUZsYWcoUFdTX0FVVE9UUkFOU1BBUkVOVCk7DQotCQlwU2Nyb2xsQmFyLT5TZXRUcmFuc3BhcmVuY3koMjU1KTsNCi0JCXBTY3JvbGxCYXItPlNldE5vdGlmeUZvcmV2ZXIoVFJVRSk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0ljb25MaXN0OjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQ0KLXsNCi0JQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOw0KLQ0KLQlpZiAod1BhcmFtID09IFNCVF9WU0NST0xMKQ0KLQl7CQkNCi0JCXN3aXRjaCAobXNnKQ0KLQkJew0KLQkJY2FzZSBQTk1fU0VUU0NST0xMSU5GTzoNCi0JCQlpZiAoUFdMX1NDUk9MTF9JTkZPKiBwSW5mbyA9IChQV0xfU0NST0xMX0lORk8qKWxQYXJhbSkNCi0JCQl7DQotCQkJCWlmIChDUFdMX1Njcm9sbEJhciogcFNjcm9sbEJhciA9IHRoaXMtPkdldFZTY3JvbGxCYXIoKSkNCi0JCQkJew0KLQkJCQkJaWYgKHBJbmZvLT5mQ29udGVudE1heCAtIHBJbmZvLT5mQ29udGVudE1pbiA+IHBJbmZvLT5mUGxhdGVXaWR0aCkNCi0JCQkJCXsNCi0JCQkJCQlpZiAoIXBTY3JvbGxCYXItPklzVmlzaWJsZSgpKQ0KLQkJCQkJCXsNCi0JCQkJCQkJcFNjcm9sbEJhci0+U2V0VmlzaWJsZShUUlVFKTsNCi0JCQkJCQkJUmVQb3NDaGlsZFduZCgpOwkJCQ0KLQkJCQkJCX0NCi0JCQkJCQllbHNlDQotCQkJCQkJew0KLQkJCQkJCX0NCi0JCQkJCX0NCi0JCQkJCWVsc2UNCi0JCQkJCXsNCi0JCQkJCQlpZiAocFNjcm9sbEJhci0+SXNWaXNpYmxlKCkpDQotCQkJCQkJew0KLQkJCQkJCQlwU2Nyb2xsQmFyLT5TZXRWaXNpYmxlKEZBTFNFKTsNCi0JCQkJCQkJUmVQb3NDaGlsZFduZCgpOw0KLQkJCQkJCX0NCi0NCi0JCQkJCQlpZiAobV9wTGlzdENvbnRlbnQpDQotCQkJCQkJCW1fcExpc3RDb250ZW50LT5TZXRTY3JvbGxQb3MoQ1BERl9Qb2ludCgwLjBmLDAuMGYpKTsNCi0JCQkJCX0NCi0JCQkJCQ0KLQkJCQkJcFNjcm9sbEJhci0+T25Ob3RpZnkocFduZCxQTk1fU0VUU0NST0xMSU5GTyx3UGFyYW0sbFBhcmFtKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCQlyZXR1cm47DQotCQljYXNlIFBOTV9TQ1JPTExXSU5ET1c6DQotCQkJaWYgKG1fcExpc3RDb250ZW50KQ0KLQkJCXsNCi0JCQkJbV9wTGlzdENvbnRlbnQtPlNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAuMGYsICooRlhfRkxPQVQqKWxQYXJhbSkpOw0KLQkJCQltX3BMaXN0Q29udGVudC0+UmVzZXRGYWNlKCk7DQotCQkJCW1fcExpc3RDb250ZW50LT5JbnZhbGlkYXRlUmVjdChOVUxMKTsNCi0JCQl9DQotCQkJcmV0dXJuOw0KLQkJY2FzZSBQTk1fU0VUU0NST0xMUE9TOg0KLQkJCWlmIChDUFdMX1Njcm9sbEJhciogcFNjcm9sbEJhciA9IHRoaXMtPkdldFZTY3JvbGxCYXIoKSkNCi0JCQkJcFNjcm9sbEJhci0+T25Ob3RpZnkocFduZCxQTk1fU0VUU0NST0xMUE9TLHdQYXJhbSxsUGFyYW0pOw0KLQkJCXJldHVybjsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3Q6OlNldFNlbGVjdChGWF9JTlQzMiBuSW5kZXgpDQotew0KLQltX3BMaXN0Q29udGVudC0+U2V0U2VsZWN0KG5JbmRleCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdDo6U2V0VG9wSXRlbShGWF9JTlQzMiBuSW5kZXgpDQotew0KLQltX3BMaXN0Q29udGVudC0+U2Nyb2xsVG9JdGVtKG5JbmRleCk7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfSWNvbkxpc3Q6OkdldFNlbGVjdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9wTGlzdENvbnRlbnQtPkdldFNlbGVjdCgpOw0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3Q6OlNldE5vdGlmeShJUFdMX0ljb25MaXN0X05vdGlmeSogcE5vdGlmeSkNCi17DQotCW1fcExpc3RDb250ZW50LT5TZXROb3RpZnkocE5vdGlmeSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdDo6RW5hYmxlTm90aWZ5KEZYX0JPT0wgYk5vdGlmeSkNCi17DQotCW1fcExpc3RDb250ZW50LT5FbmFibGVOb3RpZnkoYk5vdGlmeSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdDo6U2V0TGlzdERhdGEoRlhfSU5UMzIgbkl0ZW1JbmRleCwgdm9pZCogcERhdGEpDQotew0KLQltX3BMaXN0Q29udGVudC0+U2V0TGlzdERhdGEobkl0ZW1JbmRleCwgcERhdGEpOw0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3Q6OlNldExpc3RJY29uKEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0lOVDMyIG5JY29uSW5kZXgpDQotew0KLQltX3BMaXN0Q29udGVudC0+U2V0TGlzdEljb24obkl0ZW1JbmRleCwgbkljb25JbmRleCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9JY29uTGlzdDo6U2V0TGlzdFN0cmluZyhGWF9JTlQzMiBuSXRlbUluZGV4LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyKQ0KLXsNCi0JbV9wTGlzdENvbnRlbnQtPlNldExpc3RTdHJpbmcobkl0ZW1JbmRleCwgc3RyKTsNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9JY29uTGlzdDo6R2V0TGlzdFN0cmluZyhGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcExpc3RDb250ZW50LT5HZXRMaXN0U3RyaW5nKG5JdGVtSW5kZXgpOw0KLX0NCi0NCi12b2lkIENQV0xfSWNvbkxpc3Q6OlNldEljb25GaWxsQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpDQotew0KLQltX3BMaXN0Q29udGVudC0+U2V0SWNvbkZpbGxDb2xvcihjb2xvcik7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9JY29uTGlzdDo6T25Nb3VzZVdoZWVsKHNob3J0IHpEZWx0YSwgY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQ0KLXsNCi0JQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcExpc3RDb250ZW50LT5HZXRTY3JvbGxQb3MoKTsNCi0JQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wTGlzdENvbnRlbnQtPkdldFNjcm9sbEFyZWEoKTsNCi0JQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BMaXN0Q29udGVudC0+R2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQlpZiAocmNTY3JvbGwudG9wIC0gcmNTY3JvbGwuYm90dG9tID4gcmNDb250ZW50cy5IZWlnaHQoKSkNCi0Jew0KLQkJQ1BERl9Qb2ludCBwdE5ldyA9IHB0U2Nyb2xsOw0KLQ0KLQkJaWYgKHpEZWx0YSA+IDApDQotCQkJcHROZXcueSArPSAzMDsNCi0JCWVsc2UNCi0JCQlwdE5ldy55IC09IDMwOw0KLQ0KLQkJaWYgKHB0TmV3LnkgPiByY1Njcm9sbC50b3ApDQotCQkJcHROZXcueSA9IHJjU2Nyb2xsLnRvcDsNCi0JCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tICsgcmNDb250ZW50cy5IZWlnaHQoKSkNCi0JCQlwdE5ldy55ID0gcmNTY3JvbGwuYm90dG9tICsgcmNDb250ZW50cy5IZWlnaHQoKTsNCi0JCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tKQ0KLQkJCXB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b207DQotDQotCQlpZiAocHROZXcueSAhPSBwdFNjcm9sbC55KQ0KLQkJew0KLQkJCW1fcExpc3RDb250ZW50LT5TZXRTY3JvbGxQb3MocHROZXcpOw0KLQkJCW1fcExpc3RDb250ZW50LT5SZXNldEZhY2UoKTsNCi0JCQltX3BMaXN0Q29udGVudC0+SW52YWxpZGF0ZVJlY3QoTlVMTCk7DQotCQkJDQotCQkJaWYgKENQV0xfU2Nyb2xsQmFyKiBwU2Nyb2xsQmFyID0gdGhpcy0+R2V0VlNjcm9sbEJhcigpKQ0KLQkJCQlwU2Nyb2xsQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHROZXcueSk7DQotDQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MaXN0Q3RybC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9JY29uTGlzdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TY3JvbGxCYXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGFiZWwuaCIKKworI2RlZmluZSBQV0xfSWNvbkxpc3RfSVRFTV9JQ09OX0xFRlRNQVJHSU4JCTEwLjBmCisjZGVmaW5lIFBXTF9JY29uTGlzdF9JVEVNX1dJRFRICQkJCQkyMC4wZgorI2RlZmluZSBQV0xfSWNvbkxpc3RfSVRFTV9IRUlHSFQJCQkJMjAuMGYKKyNkZWZpbmUgUFdMX0ljb25MaXN0X0lURU1fU1BBQ0UJCQkJCTQuMGYKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfSWNvbkxpc3RfSXRlbSAtLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfSWNvbkxpc3RfSXRlbTo6Q1BXTF9JY29uTGlzdF9JdGVtKCkgOiAKKwltX25JY29uSW5kZXgoLTEpLCAKKwltX3BEYXRhKE5VTEwpLAorCW1fYlNlbGVjdGVkKEZBTFNFKSwKKwltX3BUZXh0KE5VTEwpCit7Cit9CisKK0NQV0xfSWNvbkxpc3RfSXRlbTo6fkNQV0xfSWNvbkxpc3RfSXRlbSgpCit7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfSWNvbkxpc3RfSXRlbTo6R2V0Q2xhc3NOYW1lKCkgY29uc3QKK3sKKwlyZXR1cm4gIkNQV0xfSWNvbkxpc3RfSXRlbSI7Cit9CisKK0ZYX0ZMT0FUIENQV0xfSWNvbkxpc3RfSXRlbTo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkKK3sKKwlyZXR1cm4gUFdMX0ljb25MaXN0X0lURU1fSEVJR0hUOworfQorCit2b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpCit7CisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOworCisJaWYgKG1fYlNlbGVjdGVkKQorCXsKKwkJaWYgKHRoaXMtPklzRW5hYmxlZCgpKQorCQl7CisJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbFJlY3QocERldmljZSwgcFVzZXIyRGV2aWNlLCByY0NsaWVudCwgCisJCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoUFdMX0RFRkFVTFRfU0VMQkFDS0NPTE9SLHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbFJlY3QocERldmljZSwgcFVzZXIyRGV2aWNlLCByY0NsaWVudCwgCisJCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoUFdMX0RFRkFVTFRfTElHSFRHUkFZQ09MT1IsdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpKTsKKwkJfQorCX0KKworCUNQREZfUmVjdCByY0ljb24gPSByY0NsaWVudDsKKwlyY0ljb24ubGVmdCArPSBQV0xfSWNvbkxpc3RfSVRFTV9JQ09OX0xFRlRNQVJHSU47CisJcmNJY29uLnJpZ2h0ID0gcmNJY29uLmxlZnQgKyBQV0xfSWNvbkxpc3RfSVRFTV9XSURUSDsKKworCUNQV0xfVXRpbHM6OkRyYXdJY29uQXBwU3RyZWFtKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgbV9uSWNvbkluZGV4LCByY0ljb24sIAorCQltX2NySWNvbiwgbV9wVGV4dC0+R2V0VGV4dENvbG9yKCksIHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKTsKK30KKwordm9pZCBDUFdMX0ljb25MaXN0X0l0ZW06OlNldFNlbGVjdChGWF9CT09MIGJTZWxlY3RlZCkKK3sKKwltX2JTZWxlY3RlZCA9IGJTZWxlY3RlZDsKKworCWlmIChiU2VsZWN0ZWQpCisJCW1fcFRleHQtPlNldFRleHRDb2xvcihQV0xfREVGQVVMVF9XSElURUNPTE9SKTsKKwllbHNlCisJCW1fcFRleHQtPlNldFRleHRDb2xvcihQV0xfREVGQVVMVF9CTEFDS0NPTE9SKTsKKworfQorCitGWF9CT09MCUNQV0xfSWNvbkxpc3RfSXRlbTo6SXNTZWxlY3RlZCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fYlNlbGVjdGVkOworfQorCit2b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJbV9wVGV4dCA9IG5ldyBDUFdMX0xhYmVsOworCisJUFdMX0NSRUFURVBBUkFNIGxjcCA9IGNwOworCWxjcC5wUGFyZW50V25kID0gdGhpczsKKwlsY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFIHwgUEVTX0xFRlQgfCBQRVNfQ0VOVEVSOworCWxjcC5zVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKKwlsY3AuZkZvbnRTaXplID0gMTI7CisJbV9wVGV4dC0+Q3JlYXRlKGxjcCk7Cit9CisKK3ZvaWQgQ1BXTF9JY29uTGlzdF9JdGVtOjpTZXREYXRhKHZvaWQqIHBEYXRhKQoreworCW1fcERhdGEgPSBwRGF0YTsKK30KKwordm9pZCBDUFdMX0ljb25MaXN0X0l0ZW06OlNldEljb24oRlhfSU5UMzIgbkljb25JbmRleCkKK3sKKwltX25JY29uSW5kZXggPSBuSWNvbkluZGV4OworfQorCit2b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6U2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyKQoreworCW1fcFRleHQtPlNldFRleHQoc3RyKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9JY29uTGlzdF9JdGVtOjpHZXRUZXh0KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wVGV4dC0+R2V0VGV4dCgpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6UmVQb3NDaGlsZFduZCgpCit7CisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOworCisJcmNDbGllbnQubGVmdCArPSAoUFdMX0ljb25MaXN0X0lURU1fSUNPTl9MRUZUTUFSR0lOICsgUFdMX0ljb25MaXN0X0lURU1fV0lEVEggKyBQV0xfSWNvbkxpc3RfSVRFTV9JQ09OX0xFRlRNQVJHSU4pOworCisJbV9wVGV4dC0+TW92ZShyY0NsaWVudCwgVFJVRSwgRkFMU0UpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6U2V0SWNvbkZpbGxDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikKK3sKKwltX2NySWNvbiA9IGNvbG9yOworfQorCit2b2lkIENQV0xfSWNvbkxpc3RfSXRlbTo6T25FbmFibGVkKCkKK3sKKwlpZiAobV9iU2VsZWN0ZWQpCisJCW1fcFRleHQtPlNldFRleHRDb2xvcihQV0xfREVGQVVMVF9XSElURUNPTE9SKTsKKwllbHNlCisJCW1fcFRleHQtPlNldFRleHRDb2xvcihQV0xfREVGQVVMVF9CTEFDS0NPTE9SKTsKKworCXRoaXMtPkludmFsaWRhdGVSZWN0KCk7Cit9CisKK3ZvaWQgQ1BXTF9JY29uTGlzdF9JdGVtOjpPbkRpc2FibGVkKCkKK3sKKwltX3BUZXh0LT5TZXRUZXh0Q29sb3IoUFdMX0RFRkFVTFRfSEVBVllHUkFZQ09MT1IpOworCisJdGhpcy0+SW52YWxpZGF0ZVJlY3QoKTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9JY29uTGlzdF9Db250ZW50IC0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfSWNvbkxpc3RfQ29udGVudDo6Q1BXTF9JY29uTGlzdF9Db250ZW50KEZYX0lOVDMyIG5MaXN0Q291bnQpIDogCisJbV9uU2VsZWN0SW5kZXgoLTEpLAorCW1fcE5vdGlmeShOVUxMKSwKKwltX2JFbmFibGVOb3RpZnkoVFJVRSksCisJbV9iTW91c2VEb3duKEZBTFNFKSwKKwltX25MaXN0Q291bnQobkxpc3RDb3VudCkKK3sKK30KKworQ1BXTF9JY29uTGlzdF9Db250ZW50Ojp+Q1BXTF9JY29uTGlzdF9Db250ZW50KCkKK3sKK30KKwordm9pZCBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQoreworCWZvciAoRlhfSU5UMzIgaT0wOyBpPG1fbkxpc3RDb3VudDsgaSsrKQorCXsKKwkJQ1BXTF9JY29uTGlzdF9JdGVtKiBwTmV3SXRlbSA9IG5ldyBDUFdMX0ljb25MaXN0X0l0ZW0oKTsKKworCQlQV0xfQ1JFQVRFUEFSQU0gaWNwID0gY3A7CisJCWljcC5wUGFyZW50V25kID0gdGhpczsKKwkJaWNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19OT1JFRlJFU0hDTElQOworCQlwTmV3SXRlbS0+Q3JlYXRlKGljcCk7CisJfQorCisJdGhpcy0+U2V0SXRlbVNwYWNlKFBXTF9JY29uTGlzdF9JVEVNX1NQQUNFKTsKKwl0aGlzLT5SZXNldENvbnRlbnQoMCk7CisKKwlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCisJeworCQlDUERGX1JlY3QgcmNTY3JvbGwgPSB0aGlzLT5HZXRTY3JvbGxBcmVhKCk7CisJCXRoaXMtPkdldFNjcm9sbFBvcygpOworCisJCVBXTF9TQ1JPTExfSU5GTyBzSW5mbzsKKwkJc0luZm8uZkNvbnRlbnRNaW4gPSByY1Njcm9sbC5ib3R0b207CisJCXNJbmZvLmZDb250ZW50TWF4ID0gcmNTY3JvbGwudG9wOworCQlzSW5mby5mUGxhdGVXaWR0aCA9IEdldENsaWVudFJlY3QoKS5IZWlnaHQoKTsKKwkJc0luZm8uZlNtYWxsU3RlcCA9IDEzLjBmOworCQlzSW5mby5mQmlnU3RlcCA9IHNJbmZvLmZQbGF0ZVdpZHRoOworCisJCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExJTkZPLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmc0luZm8pOworCX0KK30KKworRlhfQk9PTAlDUFdMX0ljb25MaXN0X0NvbnRlbnQ6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQoreworCVNldEZvY3VzKCk7CisKKwlTZXRDYXB0dXJlKCk7CisJbV9iTW91c2VEb3duID0gVFJVRTsKKworCUZYX0lOVDMyIG5JdGVtSW5kZXggPSBGaW5kSXRlbUluZGV4KHBvaW50KTsKKwlTZXRTZWxlY3Qobkl0ZW1JbmRleCk7CisJU2Nyb2xsVG9JdGVtKG5JdGVtSW5kZXgpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wJQ1BXTF9JY29uTGlzdF9Db250ZW50OjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CisJbV9iTW91c2VEb3duID0gRkFMU0U7CisJUmVsZWFzZUNhcHR1cmUoKTsKKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENQV0xfSWNvbkxpc3RfQ29udGVudDo6T25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQoreworCWlmIChtX2JNb3VzZURvd24pCisJeworCQlGWF9JTlQzMiBuSXRlbUluZGV4ID0gRmluZEl0ZW1JbmRleChwb2ludCk7CisJCVNldFNlbGVjdChuSXRlbUluZGV4KTsKKwkJU2Nyb2xsVG9JdGVtKG5JdGVtSW5kZXgpOworCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MCUNQV0xfSWNvbkxpc3RfQ29udGVudDo6T25LZXlEb3duKEZYX1dPUkQgbkNoYXIpCit7CisJc3dpdGNoIChuQ2hhcikKKwl7CisJY2FzZSBGV0xfVktFWV9VcDoKKwkJaWYgKG1fblNlbGVjdEluZGV4ID4gMCkKKwkJeworCQkJRlhfSU5UMzIgbkl0ZW1JbmRleCA9IG1fblNlbGVjdEluZGV4IC0gMTsKKwkJCVNldFNlbGVjdChuSXRlbUluZGV4KTsKKwkJCVNjcm9sbFRvSXRlbShuSXRlbUluZGV4KTsKKwkJfQorCQlyZXR1cm4gVFJVRTsKKwljYXNlIEZXTF9WS0VZX0Rvd246CisJCWlmIChtX25TZWxlY3RJbmRleCA8IG1fbkxpc3RDb3VudC0xKQorCQl7CisJCQlGWF9JTlQzMiBuSXRlbUluZGV4ID0gbV9uU2VsZWN0SW5kZXggKyAxOworCQkJU2V0U2VsZWN0KG5JdGVtSW5kZXgpOworCQkJU2Nyb2xsVG9JdGVtKG5JdGVtSW5kZXgpOworCQl9CisJCXJldHVybiBUUlVFOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfSU5UMzIgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpGaW5kSXRlbUluZGV4KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUZYX0lOVDMyIG5JbmRleCA9IDA7CisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKKwkJeworCQkJQ1BERl9SZWN0IHJjV25kID0gcENoaWxkLT5DaGlsZFRvUGFyZW50KHBDaGlsZC0+R2V0V2luZG93UmVjdCgpKTsKKworCQkJaWYgKHBvaW50LnkgPCByY1duZC50b3ApCisJCQl7CisJCQkJbkluZGV4ID0gaTsKKwkJCX0KKwkJfQorCX0KKworCXJldHVybiBuSW5kZXg7Cit9CisKK3ZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpTY3JvbGxUb0l0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisKKwlpZiAoQ1BXTF9JY29uTGlzdF9JdGVtKiBwSXRlbSA9IEdldExpc3RJdGVtKG5JdGVtSW5kZXgpKQorCXsKKwkJQ1BERl9SZWN0IHJjT3JpZ2luID0gcEl0ZW0tPkdldFdpbmRvd1JlY3QoKTsKKwkJQ1BERl9SZWN0IHJjV25kID0gcEl0ZW0tPkNoaWxkVG9QYXJlbnQocmNPcmlnaW4pOworCisJCWlmICghKHJjV25kLmJvdHRvbSA+IHJjQ2xpZW50LmJvdHRvbSAmJiByY1duZC50b3AgPCByY0NsaWVudC50b3ApKQorCQl7CisJCQlDUERGX1BvaW50IHB0U2Nyb2xsID0gR2V0U2Nyb2xsUG9zKCk7CisKKwkJCWlmIChyY1duZC50b3AgPiByY0NsaWVudC50b3ApCisJCQl7CisJCQkJcHRTY3JvbGwueSA9IHJjT3JpZ2luLnRvcDsKKwkJCX0KKwkJCWVsc2UgaWYgKHJjV25kLmJvdHRvbSA8IHJjQ2xpZW50LmJvdHRvbSkKKwkJCXsKKwkJCQlwdFNjcm9sbC55ID0gcmNPcmlnaW4uYm90dG9tICsgcmNDbGllbnQuSGVpZ2h0KCk7CQkJCQkKKwkJCX0KKworCQkJdGhpcy0+U2V0U2Nyb2xsUG9zKHB0U2Nyb2xsKTsKKwkJCXRoaXMtPlJlc2V0RmFjZSgpOworCQkJdGhpcy0+SW52YWxpZGF0ZVJlY3QoKTsKKwkJCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQorCQkJeworCQkJCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKKwkJCX0KKwkJfQorCX0KK30KKwordm9pZCBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OlNldFNlbGVjdChGWF9JTlQzMiBuSW5kZXgpCit7CisJaWYgKG1fblNlbGVjdEluZGV4ICE9IG5JbmRleCkKKwl7CisJCVNlbGVjdEl0ZW0obV9uU2VsZWN0SW5kZXgsIEZBTFNFKTsKKwkJU2VsZWN0SXRlbShuSW5kZXgsIFRSVUUpOworCQltX25TZWxlY3RJbmRleCA9IG5JbmRleDsKKworCQlpZiAoSVBXTF9JY29uTGlzdF9Ob3RpZnkqIHBOb3RpZnkgPSBHZXROb3RpZnkoKSkKKwkJCXBOb3RpZnktPk9uTm90ZUxpc3RTZWxDaGFuZ2VkKG5JbmRleCk7CisJfQorfQorCitGWF9JTlQzMiBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OkdldFNlbGVjdCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fblNlbGVjdEluZGV4OworfQorCitJUFdMX0ljb25MaXN0X05vdGlmeSogQ1BXTF9JY29uTGlzdF9Db250ZW50OjpHZXROb3RpZnkoKSBjb25zdAoreworCWlmIChtX2JFbmFibGVOb3RpZnkpCisJCXJldHVybiBtX3BOb3RpZnk7CisJcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpTZXROb3RpZnkoSVBXTF9JY29uTGlzdF9Ob3RpZnkqIHBOb3RpZnkpCit7CisJbV9wTm90aWZ5ID0gcE5vdGlmeTsKK30KKwordm9pZCBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OkVuYWJsZU5vdGlmeShGWF9CT09MIGJOb3RpZnkpCit7CisJbV9iRW5hYmxlTm90aWZ5ID0gYk5vdGlmeTsKK30KKwordm9pZCBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OlNlbGVjdEl0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCwgRlhfQk9PTCBiU2VsZWN0KQoreworCWlmIChDUFdMX0ljb25MaXN0X0l0ZW0qIHBJdGVtID0gR2V0TGlzdEl0ZW0obkl0ZW1JbmRleCkpCisJeworCQlwSXRlbS0+U2V0U2VsZWN0KGJTZWxlY3QpOworCQlwSXRlbS0+SW52YWxpZGF0ZVJlY3QoKTsJCQorCX0KK30KKworQ1BXTF9JY29uTGlzdF9JdGVtKiBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OkdldExpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Cit7CisJaWYgKG5JdGVtSW5kZXggPj0gMCAmJiBuSXRlbUluZGV4PG1fYUNoaWxkcmVuLkdldFNpemUoKSkKKwl7CisJCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KG5JdGVtSW5kZXgpKQorCQl7CisJCQlpZiAocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9JY29uTGlzdF9JdGVtIikKKwkJCXsKKwkJCQlyZXR1cm4gKENQV0xfSWNvbkxpc3RfSXRlbSopcENoaWxkOworCQkJfQorCQl9CisJfQorCisJcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpTZXRMaXN0RGF0YShGWF9JTlQzMiBuSXRlbUluZGV4LCB2b2lkKiBwRGF0YSkKK3sKKwlpZiAoQ1BXTF9JY29uTGlzdF9JdGVtKiBwSXRlbSA9IEdldExpc3RJdGVtKG5JdGVtSW5kZXgpKQorCQlwSXRlbS0+U2V0RGF0YShwRGF0YSk7Cit9CisKK3ZvaWQgQ1BXTF9JY29uTGlzdF9Db250ZW50OjpTZXRMaXN0SWNvbihGWF9JTlQzMiBuSXRlbUluZGV4LCBGWF9JTlQzMiBuSWNvbkluZGV4KQoreworCWlmIChDUFdMX0ljb25MaXN0X0l0ZW0qIHBJdGVtID0gR2V0TGlzdEl0ZW0obkl0ZW1JbmRleCkpCisJCXBJdGVtLT5TZXRJY29uKG5JY29uSW5kZXgpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3RfQ29udGVudDo6U2V0TGlzdFN0cmluZyhGWF9JTlQzMiBuSXRlbUluZGV4LCBjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyKQoreworCWlmIChDUFdMX0ljb25MaXN0X0l0ZW0qIHBJdGVtID0gR2V0TGlzdEl0ZW0obkl0ZW1JbmRleCkpCisJCXBJdGVtLT5TZXRUZXh0KHN0cik7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENQV0xfSWNvbkxpc3RfQ29udGVudDo6R2V0TGlzdFN0cmluZyhGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdAoreworCWlmIChDUFdMX0ljb25MaXN0X0l0ZW0qIHBJdGVtID0gR2V0TGlzdEl0ZW0obkl0ZW1JbmRleCkpCisJCXJldHVybiBwSXRlbS0+R2V0VGV4dCgpOworCisJcmV0dXJuIEwiIjsKK30KKwordm9pZCBDUFdMX0ljb25MaXN0X0NvbnRlbnQ6OlNldEljb25GaWxsQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpCit7CisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKKwkJeworCQkJaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfSWNvbkxpc3RfSXRlbSIpCisJCQl7CisJCQkJQ1BXTF9JY29uTGlzdF9JdGVtKiBwSXRlbSA9IChDUFdMX0ljb25MaXN0X0l0ZW0qKXBDaGlsZDsKKwkJCQlwSXRlbS0+U2V0SWNvbkZpbGxDb2xvcihjb2xvcik7CisJCQkJcEl0ZW0tPkludmFsaWRhdGVSZWN0KCk7CisJCQl9CisJCX0KKwl9CisKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9JY29uTGlzdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ1BXTF9JY29uTGlzdDo6Q1BXTF9JY29uTGlzdChGWF9JTlQzMiBuTGlzdENvdW50KSA6IAorCW1fcExpc3RDb250ZW50KE5VTEwpLAorCW1fbkxpc3RDb3VudChuTGlzdENvdW50KQoreworfQorCitDUFdMX0ljb25MaXN0Ojp+Q1BXTF9JY29uTGlzdCgpCit7Cit9CisKK3ZvaWQgQ1BXTF9JY29uTGlzdDo6UmVQb3NDaGlsZFduZCgpCit7CisJQ1BXTF9XbmQ6OlJlUG9zQ2hpbGRXbmQoKTsKKworCWlmIChtX3BMaXN0Q29udGVudCkKKwkJbV9wTGlzdENvbnRlbnQtPk1vdmUoR2V0Q2xpZW50UmVjdCgpLCBUUlVFLCBGQUxTRSk7Cit9CisKK3ZvaWQgQ1BXTF9JY29uTGlzdDo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJbV9wTGlzdENvbnRlbnQgPSBuZXcgQ1BXTF9JY29uTGlzdF9Db250ZW50KG1fbkxpc3RDb3VudCk7CisKKwlQV0xfQ1JFQVRFUEFSQU0gY2NwID0gY3A7CisJY2NwLnBQYXJlbnRXbmQgPSB0aGlzOworCWNjcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEU7CisJbV9wTGlzdENvbnRlbnQtPkNyZWF0ZShjY3ApOworfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6Ok9uQ3JlYXRlZCgpCit7CisJaWYgKENQV0xfU2Nyb2xsQmFyKiBwU2Nyb2xsQmFyID0gdGhpcy0+R2V0VlNjcm9sbEJhcigpKQorCXsKKwkJcFNjcm9sbEJhci0+UmVtb3ZlRmxhZyhQV1NfQVVUT1RSQU5TUEFSRU5UKTsKKwkJcFNjcm9sbEJhci0+U2V0VHJhbnNwYXJlbmN5KDI1NSk7CisJCXBTY3JvbGxCYXItPlNldE5vdGlmeUZvcmV2ZXIoVFJVRSk7CisJfQorfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pCit7CisJQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOworCisJaWYgKHdQYXJhbSA9PSBTQlRfVlNDUk9MTCkKKwl7CQkKKwkJc3dpdGNoIChtc2cpCisJCXsKKwkJY2FzZSBQTk1fU0VUU0NST0xMSU5GTzoKKwkJCWlmIChQV0xfU0NST0xMX0lORk8qIHBJbmZvID0gKFBXTF9TQ1JPTExfSU5GTyopbFBhcmFtKQorCQkJeworCQkJCWlmIChDUFdMX1Njcm9sbEJhciogcFNjcm9sbEJhciA9IHRoaXMtPkdldFZTY3JvbGxCYXIoKSkKKwkJCQl7CisJCQkJCWlmIChwSW5mby0+ZkNvbnRlbnRNYXggLSBwSW5mby0+ZkNvbnRlbnRNaW4gPiBwSW5mby0+ZlBsYXRlV2lkdGgpCisJCQkJCXsKKwkJCQkJCWlmICghcFNjcm9sbEJhci0+SXNWaXNpYmxlKCkpCisJCQkJCQl7CisJCQkJCQkJcFNjcm9sbEJhci0+U2V0VmlzaWJsZShUUlVFKTsKKwkJCQkJCQlSZVBvc0NoaWxkV25kKCk7CQkJCisJCQkJCQl9CisJCQkJCQllbHNlCisJCQkJCQl7CisJCQkJCQl9CisJCQkJCX0KKwkJCQkJZWxzZQorCQkJCQl7CisJCQkJCQlpZiAocFNjcm9sbEJhci0+SXNWaXNpYmxlKCkpCisJCQkJCQl7CisJCQkJCQkJcFNjcm9sbEJhci0+U2V0VmlzaWJsZShGQUxTRSk7CisJCQkJCQkJUmVQb3NDaGlsZFduZCgpOworCQkJCQkJfQorCisJCQkJCQlpZiAobV9wTGlzdENvbnRlbnQpCisJCQkJCQkJbV9wTGlzdENvbnRlbnQtPlNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAuMGYsMC4wZikpOworCQkJCQl9CisJCQkJCQorCQkJCQlwU2Nyb2xsQmFyLT5Pbk5vdGlmeShwV25kLFBOTV9TRVRTQ1JPTExJTkZPLHdQYXJhbSxsUGFyYW0pOworCQkJCX0KKwkJCX0KKwkJCXJldHVybjsKKwkJY2FzZSBQTk1fU0NST0xMV0lORE9XOgorCQkJaWYgKG1fcExpc3RDb250ZW50KQorCQkJeworCQkJCW1fcExpc3RDb250ZW50LT5TZXRTY3JvbGxQb3MoQ1BERl9Qb2ludCgwLjBmLCAqKEZYX0ZMT0FUKilsUGFyYW0pKTsKKwkJCQltX3BMaXN0Q29udGVudC0+UmVzZXRGYWNlKCk7CisJCQkJbV9wTGlzdENvbnRlbnQtPkludmFsaWRhdGVSZWN0KE5VTEwpOworCQkJfQorCQkJcmV0dXJuOworCQljYXNlIFBOTV9TRVRTQ1JPTExQT1M6CisJCQlpZiAoQ1BXTF9TY3JvbGxCYXIqIHBTY3JvbGxCYXIgPSB0aGlzLT5HZXRWU2Nyb2xsQmFyKCkpCisJCQkJcFNjcm9sbEJhci0+T25Ob3RpZnkocFduZCxQTk1fU0VUU0NST0xMUE9TLHdQYXJhbSxsUGFyYW0pOworCQkJcmV0dXJuOworCQl9CisJfQorfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6OlNldFNlbGVjdChGWF9JTlQzMiBuSW5kZXgpCit7CisJbV9wTGlzdENvbnRlbnQtPlNldFNlbGVjdChuSW5kZXgpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6OlNldFRvcEl0ZW0oRlhfSU5UMzIgbkluZGV4KQoreworCW1fcExpc3RDb250ZW50LT5TY3JvbGxUb0l0ZW0obkluZGV4KTsKK30KKworRlhfSU5UMzIgQ1BXTF9JY29uTGlzdDo6R2V0U2VsZWN0KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wTGlzdENvbnRlbnQtPkdldFNlbGVjdCgpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6OlNldE5vdGlmeShJUFdMX0ljb25MaXN0X05vdGlmeSogcE5vdGlmeSkKK3sKKwltX3BMaXN0Q29udGVudC0+U2V0Tm90aWZ5KHBOb3RpZnkpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6OkVuYWJsZU5vdGlmeShGWF9CT09MIGJOb3RpZnkpCit7CisJbV9wTGlzdENvbnRlbnQtPkVuYWJsZU5vdGlmeShiTm90aWZ5KTsKK30KKwordm9pZCBDUFdMX0ljb25MaXN0OjpTZXRMaXN0RGF0YShGWF9JTlQzMiBuSXRlbUluZGV4LCB2b2lkKiBwRGF0YSkKK3sKKwltX3BMaXN0Q29udGVudC0+U2V0TGlzdERhdGEobkl0ZW1JbmRleCwgcERhdGEpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6OlNldExpc3RJY29uKEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0lOVDMyIG5JY29uSW5kZXgpCit7CisJbV9wTGlzdENvbnRlbnQtPlNldExpc3RJY29uKG5JdGVtSW5kZXgsIG5JY29uSW5kZXgpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6OlNldExpc3RTdHJpbmcoRlhfSU5UMzIgbkl0ZW1JbmRleCwgY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cikKK3sKKwltX3BMaXN0Q29udGVudC0+U2V0TGlzdFN0cmluZyhuSXRlbUluZGV4LCBzdHIpOworfQorCitDRlhfV2lkZVN0cmluZyBDUFdMX0ljb25MaXN0OjpHZXRMaXN0U3RyaW5nKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Cit7CisJcmV0dXJuIG1fcExpc3RDb250ZW50LT5HZXRMaXN0U3RyaW5nKG5JdGVtSW5kZXgpOworfQorCit2b2lkIENQV0xfSWNvbkxpc3Q6OlNldEljb25GaWxsQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpCit7CisJbV9wTGlzdENvbnRlbnQtPlNldEljb25GaWxsQ29sb3IoY29sb3IpOworfQorCitGWF9CT09MCUNQV0xfSWNvbkxpc3Q6Ok9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkKK3sKKwlDUERGX1BvaW50IHB0U2Nyb2xsID0gbV9wTGlzdENvbnRlbnQtPkdldFNjcm9sbFBvcygpOworCUNQREZfUmVjdCByY1Njcm9sbCA9IG1fcExpc3RDb250ZW50LT5HZXRTY3JvbGxBcmVhKCk7CisJQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BMaXN0Q29udGVudC0+R2V0Q2xpZW50UmVjdCgpOworCisJaWYgKHJjU2Nyb2xsLnRvcCAtIHJjU2Nyb2xsLmJvdHRvbSA+IHJjQ29udGVudHMuSGVpZ2h0KCkpCisJeworCQlDUERGX1BvaW50IHB0TmV3ID0gcHRTY3JvbGw7CisKKwkJaWYgKHpEZWx0YSA+IDApCisJCQlwdE5ldy55ICs9IDMwOworCQllbHNlCisJCQlwdE5ldy55IC09IDMwOworCisJCWlmIChwdE5ldy55ID4gcmNTY3JvbGwudG9wKQorCQkJcHROZXcueSA9IHJjU2Nyb2xsLnRvcDsKKwkJaWYgKHB0TmV3LnkgPCByY1Njcm9sbC5ib3R0b20gKyByY0NvbnRlbnRzLkhlaWdodCgpKQorCQkJcHROZXcueSA9IHJjU2Nyb2xsLmJvdHRvbSArIHJjQ29udGVudHMuSGVpZ2h0KCk7CisJCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tKQorCQkJcHROZXcueSA9IHJjU2Nyb2xsLmJvdHRvbTsKKworCQlpZiAocHROZXcueSAhPSBwdFNjcm9sbC55KQorCQl7CisJCQltX3BMaXN0Q29udGVudC0+U2V0U2Nyb2xsUG9zKHB0TmV3KTsKKwkJCW1fcExpc3RDb250ZW50LT5SZXNldEZhY2UoKTsKKwkJCW1fcExpc3RDb250ZW50LT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKKwkJCQorCQkJaWYgKENQV0xfU2Nyb2xsQmFyKiBwU2Nyb2xsQmFyID0gdGhpcy0+R2V0VlNjcm9sbEJhcigpKQorCQkJCXBTY3JvbGxCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdE5ldy55KTsKKworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfTGFiZWwuY3BwIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9MYWJlbC5jcHAKaW5kZXggZTFiODUyMi4uMTg1ODBmMyAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9MYWJlbC5jcHAKKysrIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9MYWJlbC5jcHAKQEAgLTEsMTg3ICsxLDE4NyBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MYWJlbC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTGFiZWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BXTF9MYWJlbDo6Q1BXTF9MYWJlbCgpIDogbV9wRWRpdChOVUxMKQ0KLXsNCi0JbV9wRWRpdCA9IElGWF9FZGl0OjpOZXdFZGl0KCk7DQotDQotCUFTU0VSVChtX3BFZGl0ICE9IE5VTEwpOw0KLX0NCi0NCi1DUFdMX0xhYmVsOjp+Q1BXTF9MYWJlbCgpDQotew0KLQlJRlhfRWRpdDo6RGVsRWRpdChtX3BFZGl0KTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9MYWJlbDo6R2V0Q2xhc3NOYW1lKCkgY29uc3QNCi17DQotCXJldHVybiAiQ1BXTF9MYWJlbCI7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MYWJlbDo6T25DcmVhdGVkKCkNCi17DQotCVNldFBhcmFtQnlGbGFnKCk7DQotCVNldEZvbnRTaXplKHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKS5mRm9udFNpemUpOw0KLQ0KLQltX3BFZGl0LT5TZXRGb250TWFwKHRoaXMtPkdldEZvbnRNYXAoKSk7DQotCW1fcEVkaXQtPkluaXRpYWxpemUoKTsNCi0NCi0JaWYgKEhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykpDQotCXsNCi0JCVNldENsaXBSZWN0KENQREZfUmVjdCgwLjBmLDAuMGYsMC4wZiwwLjBmKSk7DQotCQltX3BFZGl0LT5TZXRUZXh0T3ZlcmZsb3coVFJVRSk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0xhYmVsOjpTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KQ0KLXsNCi0JbV9wRWRpdC0+U2V0VGV4dChjc1RleHQpOw0KLX0NCi0NCi12b2lkIENQV0xfTGFiZWw6OlJlUG9zQ2hpbGRXbmQoKQ0KLXsNCi0JbV9wRWRpdC0+U2V0UGxhdGVSZWN0KEdldENsaWVudFJlY3QoKSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MYWJlbDo6U2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKQ0KLXsNCi0JbV9wRWRpdC0+U2V0Rm9udFNpemUoZkZvbnRTaXplKTsNCi19DQotDQotRlhfRkxPQVQgQ1BXTF9MYWJlbDo6R2V0Rm9udFNpemUoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcEVkaXQtPkdldEZvbnRTaXplKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MYWJlbDo6U2V0UGFyYW1CeUZsYWcoKQ0KLXsJDQotCWlmIChIYXNGbGFnKFBFU19MRUZUKSkNCi0Jew0KLQkJbV9wRWRpdC0+U2V0QWxpZ25tZW50SCgwKTsNCi0JfQ0KLQllbHNlIGlmIChIYXNGbGFnKFBFU19NSURETEUpKQ0KLQl7DQotCQltX3BFZGl0LT5TZXRBbGlnbm1lbnRIKDEpOw0KLQl9DQotCWVsc2UgaWYgKEhhc0ZsYWcoUEVTX1JJR0hUKSkNCi0Jew0KLQkJbV9wRWRpdC0+U2V0QWxpZ25tZW50SCgyKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCW1fcEVkaXQtPlNldEFsaWdubWVudEgoMCk7DQotCX0NCi0NCi0JaWYgKEhhc0ZsYWcoUEVTX1RPUCkpDQotCXsNCi0JCW1fcEVkaXQtPlNldEFsaWdubWVudFYoMCk7DQotCX0NCi0JZWxzZSBpZiAoSGFzRmxhZyhQRVNfQ0VOVEVSKSkNCi0Jew0KLQkJbV9wRWRpdC0+U2V0QWxpZ25tZW50VigxKTsNCi0JfQ0KLQllbHNlIGlmIChIYXNGbGFnKFBFU19CT1RUT00pKQ0KLQl7DQotCQltX3BFZGl0LT5TZXRBbGlnbm1lbnRWKDIpOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJbV9wRWRpdC0+U2V0QWxpZ25tZW50VigwKTsNCi0JfQ0KLQ0KLQlpZiAoSGFzRmxhZyhQRVNfUEFTU1dPUkQpKQ0KLQl7DQotCQltX3BFZGl0LT5TZXRQYXNzd29yZENoYXIoJyonKTsNCi0JfQ0KLQ0KLQltX3BFZGl0LT5TZXRNdWx0aUxpbmUoSGFzRmxhZyhQRVNfTVVMVElMSU5FKSk7DQotCW1fcEVkaXQtPlNldEF1dG9SZXR1cm4oSGFzRmxhZyhQRVNfQVVUT1JFVFVSTikpOw0KLQltX3BFZGl0LT5TZXRBdXRvRm9udFNpemUoSGFzRmxhZyhQV1NfQVVUT0ZPTlRTSVpFKSk7DQotCW1fcEVkaXQtPlNldEF1dG9TY3JvbGwoSGFzRmxhZyhQRVNfQVVUT1NDUk9MTCkpOw0KLX0NCi0NCi12b2lkIENQV0xfTGFiZWw6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0KLXsNCi0JQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLHBVc2VyMkRldmljZSk7DQotDQotCUdldENsaWVudFJlY3QoKTsNCi0NCi0JQ1BERl9SZWN0IHJjQ2xpcDsNCi0JQ1BWVF9Xb3JkUmFuZ2Ugd3JSYW5nZSA9IG1fcEVkaXQtPkdldFZpc2libGVXb3JkUmFuZ2UoKTsNCi0JQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSA9IE5VTEw7DQotDQotCWlmICghSGFzRmxhZyhQRVNfVEVYVE9WRVJGTE9XKSkNCi0Jew0KLQkJcmNDbGlwID0gR2V0Q2xpZW50UmVjdCgpOw0KLQkJcFJhbmdlID0gJndyUmFuZ2U7DQotCX0NCi1JRlhfU3lzdGVtSGFuZGxlciogcFN5c0hhbmRsZXIgPSBHZXRTeXN0ZW1IYW5kbGVyKCk7DQotCUlGWF9FZGl0OjpEcmF3RWRpdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIG1fcEVkaXQsDQotCQlDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSwgdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLA0KLQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dFN0cm9rZUNvbG9yKCksIHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSwNCi0JCXJjQ2xpcCwgQ1BERl9Qb2ludCgwLjBmLDAuMGYpLCBwUmFuZ2UscFN5c0hhbmRsZXIsIE5VTEwpOw0KLX0NCi0NCi12b2lkIENQV0xfTGFiZWw6OlNldEhvcnpTY2FsZShGWF9JTlQzMiBuSG9yelNjYWxlKQ0KLXsNCi0JbV9wRWRpdC0+U2V0SG9yelNjYWxlKG5Ib3J6U2NhbGUpOw0KLX0NCi0NCi12b2lkIENQV0xfTGFiZWw6OlNldENoYXJTcGFjZShGWF9GTE9BVCBmQ2hhclNwYWNlKQ0KLXsNCi0JbV9wRWRpdC0+U2V0Q2hhclNwYWNlKGZDaGFyU3BhY2UpOw0KLX0NCi0NCi1DUERGX1JlY3QgQ1BXTF9MYWJlbDo6R2V0Q29udGVudFJlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcEVkaXQtPkdldENvbnRlbnRSZWN0KCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MYWJlbDo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSkNCi17DQotCUNQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsNCi0NCi0Jc0FwcFN0cmVhbSA8PCBHZXRUZXh0QXBwZWFyYW5jZVN0cmVhbShDUERGX1BvaW50KDAuMGYsIDAuMGYpKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9MYWJlbDo6R2V0VGV4dEFwcGVhcmFuY2VTdHJlYW0oY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KSBjb25zdA0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNSZXQ7DQotCUNGWF9CeXRlU3RyaW5nIHNFZGl0ID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShtX3BFZGl0LHB0T2Zmc2V0KTsNCi0JDQotCWlmIChzRWRpdC5HZXRMZW5ndGgoKSA+IDApDQotCXsNCi0JCXNSZXQgPDwgIkJUXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldFRleHRDb2xvcigpKSA8PCBzRWRpdCA8PCAiRVRcbiI7DQotCX0NCi0NCi0JcmV0dXJuIHNSZXQuR2V0Qnl0ZVN0cmluZygpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUFdMX0xhYmVsOjpHZXRUZXh0KCkgY29uc3QNCi17DQotCXJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MYWJlbDo6U2V0TGltaXRDaGFyKEZYX0lOVDMyIG5MaW1pdENoYXIpDQotew0KLQltX3BFZGl0LT5TZXRMaW1pdENoYXIobkxpbWl0Q2hhcik7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfTGFiZWw6OkdldFRvdGFsV29yZHMoKQ0KLXsNCi0JaWYgKG1fcEVkaXQpDQotCQlyZXR1cm4gbV9wRWRpdC0+R2V0VG90YWxXb3JkcygpOw0KLQ0KLQlyZXR1cm4gMDsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGFiZWwuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0xhYmVsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0xhYmVsOjpDUFdMX0xhYmVsKCkgOiBtX3BFZGl0KE5VTEwpCit7CisJbV9wRWRpdCA9IElGWF9FZGl0OjpOZXdFZGl0KCk7CisKKwlBU1NFUlQobV9wRWRpdCAhPSBOVUxMKTsKK30KKworQ1BXTF9MYWJlbDo6fkNQV0xfTGFiZWwoKQoreworCUlGWF9FZGl0OjpEZWxFZGl0KG1fcEVkaXQpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX0xhYmVsOjpHZXRDbGFzc05hbWUoKSBjb25zdAoreworCXJldHVybiAiQ1BXTF9MYWJlbCI7Cit9CisKK3ZvaWQgQ1BXTF9MYWJlbDo6T25DcmVhdGVkKCkKK3sKKwlTZXRQYXJhbUJ5RmxhZygpOworCVNldEZvbnRTaXplKHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKS5mRm9udFNpemUpOworCisJbV9wRWRpdC0+U2V0Rm9udE1hcCh0aGlzLT5HZXRGb250TWFwKCkpOworCW1fcEVkaXQtPkluaXRpYWxpemUoKTsKKworCWlmIChIYXNGbGFnKFBFU19URVhUT1ZFUkZMT1cpKQorCXsKKwkJU2V0Q2xpcFJlY3QoQ1BERl9SZWN0KDAuMGYsMC4wZiwwLjBmLDAuMGYpKTsKKwkJbV9wRWRpdC0+U2V0VGV4dE92ZXJmbG93KFRSVUUpOworCX0KK30KKwordm9pZCBDUFdMX0xhYmVsOjpTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KQoreworCW1fcEVkaXQtPlNldFRleHQoY3NUZXh0KTsKK30KKwordm9pZCBDUFdMX0xhYmVsOjpSZVBvc0NoaWxkV25kKCkKK3sKKwltX3BFZGl0LT5TZXRQbGF0ZVJlY3QoR2V0Q2xpZW50UmVjdCgpKTsKK30KKwordm9pZCBDUFdMX0xhYmVsOjpTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpCit7CisJbV9wRWRpdC0+U2V0Rm9udFNpemUoZkZvbnRTaXplKTsKK30KKworRlhfRkxPQVQgQ1BXTF9MYWJlbDo6R2V0Rm9udFNpemUoKSBjb25zdAoreworCXJldHVybiBtX3BFZGl0LT5HZXRGb250U2l6ZSgpOworfQorCit2b2lkIENQV0xfTGFiZWw6OlNldFBhcmFtQnlGbGFnKCkKK3sJCisJaWYgKEhhc0ZsYWcoUEVTX0xFRlQpKQorCXsKKwkJbV9wRWRpdC0+U2V0QWxpZ25tZW50SCgwKTsKKwl9CisJZWxzZSBpZiAoSGFzRmxhZyhQRVNfTUlERExFKSkKKwl7CisJCW1fcEVkaXQtPlNldEFsaWdubWVudEgoMSk7CisJfQorCWVsc2UgaWYgKEhhc0ZsYWcoUEVTX1JJR0hUKSkKKwl7CisJCW1fcEVkaXQtPlNldEFsaWdubWVudEgoMik7CisJfQorCWVsc2UKKwl7CisJCW1fcEVkaXQtPlNldEFsaWdubWVudEgoMCk7CisJfQorCisJaWYgKEhhc0ZsYWcoUEVTX1RPUCkpCisJeworCQltX3BFZGl0LT5TZXRBbGlnbm1lbnRWKDApOworCX0KKwllbHNlIGlmIChIYXNGbGFnKFBFU19DRU5URVIpKQorCXsKKwkJbV9wRWRpdC0+U2V0QWxpZ25tZW50VigxKTsKKwl9CisJZWxzZSBpZiAoSGFzRmxhZyhQRVNfQk9UVE9NKSkKKwl7CisJCW1fcEVkaXQtPlNldEFsaWdubWVudFYoMik7CisJfQorCWVsc2UKKwl7CisJCW1fcEVkaXQtPlNldEFsaWdubWVudFYoMCk7CisJfQorCisJaWYgKEhhc0ZsYWcoUEVTX1BBU1NXT1JEKSkKKwl7CisJCW1fcEVkaXQtPlNldFBhc3N3b3JkQ2hhcignKicpOworCX0KKworCW1fcEVkaXQtPlNldE11bHRpTGluZShIYXNGbGFnKFBFU19NVUxUSUxJTkUpKTsKKwltX3BFZGl0LT5TZXRBdXRvUmV0dXJuKEhhc0ZsYWcoUEVTX0FVVE9SRVRVUk4pKTsKKwltX3BFZGl0LT5TZXRBdXRvRm9udFNpemUoSGFzRmxhZyhQV1NfQVVUT0ZPTlRTSVpFKSk7CisJbV9wRWRpdC0+U2V0QXV0b1Njcm9sbChIYXNGbGFnKFBFU19BVVRPU0NST0xMKSk7Cit9CisKK3ZvaWQgQ1BXTF9MYWJlbDo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpCit7CisJQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLHBVc2VyMkRldmljZSk7CisKKwlHZXRDbGllbnRSZWN0KCk7CisKKwlDUERGX1JlY3QgcmNDbGlwOworCUNQVlRfV29yZFJhbmdlIHdyUmFuZ2UgPSBtX3BFZGl0LT5HZXRWaXNpYmxlV29yZFJhbmdlKCk7CisJQ1BWVF9Xb3JkUmFuZ2UqIHBSYW5nZSA9IE5VTEw7CisKKwlpZiAoIUhhc0ZsYWcoUEVTX1RFWFRPVkVSRkxPVykpCisJeworCQlyY0NsaXAgPSBHZXRDbGllbnRSZWN0KCk7CisJCXBSYW5nZSA9ICZ3clJhbmdlOworCX0KK0lGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzSGFuZGxlciA9IEdldFN5c3RlbUhhbmRsZXIoKTsKKwlJRlhfRWRpdDo6RHJhd0VkaXQocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX3BFZGl0LAorCQlDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSwgdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLAorCQlDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0U3Ryb2tlQ29sb3IoKSwgdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLAorCQlyY0NsaXAsIENQREZfUG9pbnQoMC4wZiwwLjBmKSwgcFJhbmdlLHBTeXNIYW5kbGVyLCBOVUxMKTsKK30KKwordm9pZCBDUFdMX0xhYmVsOjpTZXRIb3J6U2NhbGUoRlhfSU5UMzIgbkhvcnpTY2FsZSkKK3sKKwltX3BFZGl0LT5TZXRIb3J6U2NhbGUobkhvcnpTY2FsZSk7Cit9CisKK3ZvaWQgQ1BXTF9MYWJlbDo6U2V0Q2hhclNwYWNlKEZYX0ZMT0FUIGZDaGFyU3BhY2UpCit7CisJbV9wRWRpdC0+U2V0Q2hhclNwYWNlKGZDaGFyU3BhY2UpOworfQorCitDUERGX1JlY3QgQ1BXTF9MYWJlbDo6R2V0Q29udGVudFJlY3QoKSBjb25zdAoreworCXJldHVybiBtX3BFZGl0LT5HZXRDb250ZW50UmVjdCgpOworfQorCit2b2lkIENQV0xfTGFiZWw6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pCit7CisJQ1BXTF9XbmQ6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKHNBcHBTdHJlYW0pOworCisJc0FwcFN0cmVhbSA8PCBHZXRUZXh0QXBwZWFyYW5jZVN0cmVhbShDUERGX1BvaW50KDAuMGYsIDAuMGYpKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9MYWJlbDo6R2V0VGV4dEFwcGVhcmFuY2VTdHJlYW0oY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0KSBjb25zdAoreworCUNGWF9CeXRlVGV4dEJ1ZiBzUmV0OworCUNGWF9CeXRlU3RyaW5nIHNFZGl0ID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShtX3BFZGl0LHB0T2Zmc2V0KTsKKwkKKwlpZiAoc0VkaXQuR2V0TGVuZ3RoKCkgPiAwKQorCXsKKwkJc1JldCA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oR2V0VGV4dENvbG9yKCkpIDw8IHNFZGl0IDw8ICJFVFxuIjsKKwl9CisKKwlyZXR1cm4gc1JldC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENQV0xfTGFiZWw6OkdldFRleHQoKSBjb25zdAoreworCXJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7Cit9CisKK3ZvaWQgQ1BXTF9MYWJlbDo6U2V0TGltaXRDaGFyKEZYX0lOVDMyIG5MaW1pdENoYXIpCit7CisJbV9wRWRpdC0+U2V0TGltaXRDaGFyKG5MaW1pdENoYXIpOworfQorCitGWF9JTlQzMiBDUFdMX0xhYmVsOjpHZXRUb3RhbFdvcmRzKCkKK3sKKwlpZiAobV9wRWRpdCkKKwkJcmV0dXJuIG1fcEVkaXQtPkdldFRvdGFsV29yZHMoKTsKKworCXJldHVybiAwOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0xpc3RCb3guY3BwIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9MaXN0Qm94LmNwcAppbmRleCA5NTFlZDkzLi4wMzVkODE5NSAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9MaXN0Qm94LmNwcAorKysgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0xpc3RCb3guY3BwCkBAIC0xLDYzMiArMSw2MzIgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEJveC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCINCi0NCi0jZGVmaW5lIElzRmxvYXRaZXJvKGYpCQkJCQkJKChmKSA8IDAuMDAwMSAmJiAoZikgPiAtMC4wMDAxKQ0KLSNkZWZpbmUgSXNGbG9hdEJpZ2dlcihmYSxmYikJCQkJKChmYSkgPiAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpDQotI2RlZmluZSBJc0Zsb2F0U21hbGxlcihmYSxmYikJCQkJKChmYSkgPCAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpDQotI2RlZmluZSBJc0Zsb2F0RXF1YWwoZmEsZmIpCQkJCQlJc0Zsb2F0WmVybygoZmEpLShmYikpDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTGlzdF9Ob3RpZnkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0xpc3RfTm90aWZ5OjpDUFdMX0xpc3RfTm90aWZ5KENQV0xfTGlzdEJveCogcExpc3QpIDogbV9wTGlzdChwTGlzdCkNCi17DQotCUFTU0VSVChtX3BMaXN0ICE9IE5VTEwpOw0KLX0NCi0NCi1DUFdMX0xpc3RfTm90aWZ5Ojp+Q1BXTF9MaXN0X05vdGlmeSgpDQotew0KLX0NCi0NCi12b2lkIENQV0xfTGlzdF9Ob3RpZnk6OklPblNldFNjcm9sbEluZm9ZKEZYX0ZMT0FUIGZQbGF0ZU1pbiwgRlhfRkxPQVQgZlBsYXRlTWF4LCANCi0JCQkJCQkJCQkJCQlGWF9GTE9BVCBmQ29udGVudE1pbiwgRlhfRkxPQVQgZkNvbnRlbnRNYXgsIA0KLQkJCQkJCQkJCQkJCUZYX0ZMT0FUIGZTbWFsbFN0ZXAsIEZYX0ZMT0FUIGZCaWdTdGVwKQ0KLXsNCi0JUFdMX1NDUk9MTF9JTkZPIEluZm87DQotDQotCUluZm8uZlBsYXRlV2lkdGggPSBmUGxhdGVNYXggLSBmUGxhdGVNaW47DQotCUluZm8uZkNvbnRlbnRNaW4gPSBmQ29udGVudE1pbjsNCi0JSW5mby5mQ29udGVudE1heCA9IGZDb250ZW50TWF4Ow0KLQlJbmZvLmZTbWFsbFN0ZXAgPSBmU21hbGxTdGVwOw0KLQlJbmZvLmZCaWdTdGVwID0gZkJpZ1N0ZXA7DQotDQotCW1fcExpc3QtPk9uTm90aWZ5KG1fcExpc3QsUE5NX1NFVFNDUk9MTElORk8sU0JUX1ZTQ1JPTEwsKEZYX0lOVFBUUikmSW5mbyk7DQotDQotCWlmIChDUFdMX1Njcm9sbEJhciAqIHBTY3JvbGwgPSBtX3BMaXN0LT5HZXRWU2Nyb2xsQmFyKCkpDQotCXsNCi0JCWlmIChJc0Zsb2F0QmlnZ2VyKEluZm8uZlBsYXRlV2lkdGgsSW5mby5mQ29udGVudE1heC1JbmZvLmZDb250ZW50TWluKQ0KLQkJCXx8IElzRmxvYXRFcXVhbChJbmZvLmZQbGF0ZVdpZHRoLEluZm8uZkNvbnRlbnRNYXgtSW5mby5mQ29udGVudE1pbikpDQotCQl7DQotCQkJaWYgKHBTY3JvbGwtPklzVmlzaWJsZSgpKQ0KLQkJCXsNCi0JCQkJcFNjcm9sbC0+U2V0VmlzaWJsZShGQUxTRSk7DQotCQkJCW1fcExpc3QtPlJlUG9zQ2hpbGRXbmQoKTsNCi0JCQl9CQkJDQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJaWYgKCFwU2Nyb2xsLT5Jc1Zpc2libGUoKSkNCi0JCQl7DQotCQkJCXBTY3JvbGwtPlNldFZpc2libGUoVFJVRSk7CQ0KLQkJCQltX3BMaXN0LT5SZVBvc0NoaWxkV25kKCk7DQotCQkJfQ0KLQkJfQ0KLQl9CQ0KLX0NCi0NCi12b2lkIENQV0xfTGlzdF9Ob3RpZnk6OklPblNldFNjcm9sbFBvc1koRlhfRkxPQVQgZnkpDQotew0KLQltX3BMaXN0LT5Pbk5vdGlmeShtX3BMaXN0LFBOTV9TRVRTQ1JPTExQT1MsU0JUX1ZTQ1JPTEwsKEZYX0lOVFBUUikmZnkpOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdF9Ob3RpZnk6OklPbkludmFsaWRhdGVSZWN0KENQREZfUmVjdCAqIHBSZWN0KQ0KLXsNCi0JbV9wTGlzdC0+SW52YWxpZGF0ZVJlY3QocFJlY3QpOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9MaXN0Qm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0xpc3RCb3g6OkNQV0xfTGlzdEJveCgpIDoNCi0JbV9wTGlzdChOVUxMKSwNCi0JbV9wTGlzdE5vdGlmeShOVUxMKSwNCi0JbV9iTW91c2VEb3duKEZBTFNFKSwNCi0JbV9iSG92ZXJTZWwoRkFMU0UpLA0KLQltX3BGaWxsZXJOb3RpZnkoTlVMTCkNCi17DQotCW1fcExpc3QgPSBJRlhfTGlzdDo6TmV3TGlzdCgpOw0KLQ0KLQlBU1NFUlQobV9wTGlzdCAhPSBOVUxMKTsNCi19DQotDQotQ1BXTF9MaXN0Qm94Ojp+Q1BXTF9MaXN0Qm94KCkNCi17DQotCUlGWF9MaXN0OjpEZWxMaXN0KG1fcExpc3QpOw0KLQkNCi0JaWYgKG1fcExpc3ROb3RpZnkpDQotCXsNCi0JCWRlbGV0ZSBtX3BMaXN0Tm90aWZ5Ow0KLQkJbV9wTGlzdE5vdGlmeSA9IE5VTEw7DQotCX0NCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9MaXN0Qm94OjpHZXRDbGFzc05hbWUoKSBjb25zdA0KLXsJDQotCXJldHVybiAiQ1BXTF9MaXN0Qm94IjsNCi19DQotDQotdm9pZCBDUFdMX0xpc3RCb3g6Ok9uQ3JlYXRlZCgpDQotew0KLQlpZiAobV9wTGlzdCkNCi0Jew0KLQkJaWYgKG1fcExpc3ROb3RpZnkpIGRlbGV0ZSBtX3BMaXN0Tm90aWZ5Ow0KLQ0KLQkJbV9wTGlzdC0+U2V0Rm9udE1hcChHZXRGb250TWFwKCkpOw0KLQkJbV9wTGlzdC0+U2V0Tm90aWZ5KG1fcExpc3ROb3RpZnkgPSBuZXcgQ1BXTF9MaXN0X05vdGlmeSh0aGlzKSk7DQotCQ0KLQkJU2V0SG92ZXJTZWwoSGFzRmxhZyhQTEJTX0hPVkVSU0VMKSk7CQ0KLQkJbV9wTGlzdC0+U2V0TXVsdGlwbGVTZWwoSGFzRmxhZyhQTEJTX01VTFRJUExFU0VMKSk7DQotCQltX3BMaXN0LT5TZXRGb250U2l6ZSh0aGlzLT5HZXRDcmVhdGlvblBhcmFtKCkuZkZvbnRTaXplKTsJDQotDQotCQltX2JIb3ZlclNlbCA9IEhhc0ZsYWcoUExCU19IT1ZFUlNFTCk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0xpc3RCb3g6Ok9uRGVzdHJveSgpDQotew0KLQlpZiAobV9wTGlzdE5vdGlmeSkNCi0Jew0KLQkJZGVsZXRlIG1fcExpc3ROb3RpZnk7DQotCQltX3BMaXN0Tm90aWZ5ID0gTlVMTDsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEJveDo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSkNCi17DQotCUNQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsNCi0NCi0JQ0ZYX0J5dGVUZXh0QnVmIHNMaXN0SXRlbXM7DQotDQotCWlmIChtX3BMaXN0KQ0KLQl7DQotCQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcExpc3QtPkdldFBsYXRlUmVjdCgpOw0KLQkJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9wTGlzdC0+R2V0Q291bnQoKTsgaTxzejsgaSsrKQ0KLQkJew0KLQkJCUNQREZfUmVjdCByY0l0ZW0gPSBtX3BMaXN0LT5HZXRJdGVtUmVjdChpKTsNCi0NCi0JCQlpZiAocmNJdGVtLmJvdHRvbSA+IHJjUGxhdGUudG9wIHx8IHJjSXRlbS50b3AgPCByY1BsYXRlLmJvdHRvbSkgY29udGludWU7DQotCQkJDQotCQkJQ1BERl9Qb2ludCBwdE9mZnNldChyY0l0ZW0ubGVmdCwgKHJjSXRlbS50b3AgKyByY0l0ZW0uYm90dG9tKSAqIDAuNWYpOw0KLQkJCWlmIChtX3BMaXN0LT5Jc0l0ZW1TZWxlY3RlZChpKSkNCi0JCQl7DQotCQkJCXNMaXN0SXRlbXMgPDwgQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0ocmNJdGVtLFBXTF9ERUZBVUxUX1NFTEJBQ0tDT0xPUik7DQotCQkJCUNGWF9CeXRlU3RyaW5nIHNJdGVtID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShtX3BMaXN0LT5HZXRJdGVtRWRpdChpKSwgcHRPZmZzZXQpOw0KLQkJCQlpZiAoc0l0ZW0uR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQl7DQotCQkJCQlzTGlzdEl0ZW1zIDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShQV0xfREVGQVVMVF9TRUxURVhUQ09MT1IpIDw8IHNJdGVtIDw8ICJFVFxuIjsNCi0JCQkJfQ0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlDRlhfQnl0ZVN0cmluZyBzSXRlbSA9IENQV0xfVXRpbHM6OkdldEVkaXRBcHBTdHJlYW0obV9wTGlzdC0+R2V0SXRlbUVkaXQoaSksIHB0T2Zmc2V0KTsNCi0JCQkJaWYgKHNJdGVtLkdldExlbmd0aCgpID4gMCkNCi0JCQkJew0KLQkJCQkJc0xpc3RJdGVtcyA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oR2V0VGV4dENvbG9yKCkpIDw8IHNJdGVtIDw8ICJFVFxuIjsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlpZiAoc0xpc3RJdGVtcy5HZXRMZW5ndGgoKSA+IDApDQotCXsNCi0JCUNGWF9CeXRlVGV4dEJ1ZiBzQ2xpcDsJCQkNCi0JCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsNCi0NCi0JCXNDbGlwIDw8ICJxXG4iOw0KLQkJc0NsaXAgPDwgcmNDbGllbnQubGVmdCA8PCAiICIgPDwgcmNDbGllbnQuYm90dG9tIDw8ICIgIg0KLQkJCTw8IHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCA8PCAiICIgPDwJcmNDbGllbnQudG9wIC0gcmNDbGllbnQuYm90dG9tIDw8ICIgcmUgVyBuXG4iOw0KLQ0KLQkJc0NsaXAgPDwgc0xpc3RJdGVtcyA8PCAiUVxuIjsNCi0NCi0JCXNBcHBTdHJlYW0gPDwgIi9UeCBCTUNcbiIgPDwgc0NsaXAgPDwgIkVNQ1xuIjsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEJveDo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpDQotew0KLQlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UscFVzZXIyRGV2aWNlKTsNCi0NCi0JaWYgKG1fcExpc3QpDQotCXsNCi0JCUNQREZfUmVjdCByY1BsYXRlID0gbV9wTGlzdC0+R2V0UGxhdGVSZWN0KCk7DQotCQlDUERGX1JlY3QgcmNMaXN0ID0gR2V0TGlzdFJlY3QoKTsNCi0JCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0NCi0JCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fcExpc3QtPkdldENvdW50KCk7IGk8c3o7IGkrKykNCi0JCXsNCi0JCQlDUERGX1JlY3QgcmNJdGVtID0gbV9wTGlzdC0+R2V0SXRlbVJlY3QoaSk7DQotCQkJaWYgKHJjSXRlbS5ib3R0b20gPiByY1BsYXRlLnRvcCB8fCByY0l0ZW0udG9wIDwgcmNQbGF0ZS5ib3R0b20pIGNvbnRpbnVlOw0KLQkJCQ0KLQkJCUNQREZfUG9pbnQgcHRPZmZzZXQocmNJdGVtLmxlZnQsIChyY0l0ZW0udG9wICsgcmNJdGVtLmJvdHRvbSkgKiAwLjVmKTsNCi0JCQlpZiAoSUZYX0VkaXQqIHBFZGl0ID0gbV9wTGlzdC0+R2V0SXRlbUVkaXQoaSkpDQotCQkJew0KLQkJCQlDUERGX1JlY3QgcmNDb250ZW50ID0gcEVkaXQtPkdldENvbnRlbnRSZWN0KCk7DQotCQkJCWlmIChyY0NvbnRlbnQuV2lkdGgoKSA+IHJjQ2xpZW50LldpZHRoKCkpDQotCQkJCQlyY0l0ZW0uSW50ZXJzZWN0KHJjTGlzdCk7DQotCQkJCWVsc2UNCi0JCQkJCXJjSXRlbS5JbnRlcnNlY3QocmNDbGllbnQpOw0KLQkJCX0NCi0NCi0JCQlpZiAobV9wTGlzdC0+SXNJdGVtU2VsZWN0ZWQoaSkpDQotCQkJew0KLQkJCS8vCUNQV0xfVXRpbHM6OkRyYXdGaWxsUmVjdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHJjSXRlbSwgQXJnYkVuY29kZSgyNTUsMCw1MSwxMTMpKTsNCi0JCQkJSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXNIYW5kbGVyID0gR2V0U3lzdGVtSGFuZGxlcigpOw0KLQkJCQlpZihwU3lzSGFuZGxlciAmJiBwU3lzSGFuZGxlci0+SXNTZWxlY3Rpb25JbXBsZW1lbnRlZCgpKQ0KLQkJCQl7DQotCQkJCQlJRlhfRWRpdDo6RHJhd0VkaXQocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX3BMaXN0LT5HZXRJdGVtRWRpdChpKSwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCkpLCBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0U3Ryb2tlQ29sb3IoKSksDQotCQkJCQkJcmNMaXN0LCBwdE9mZnNldCwgTlVMTCxwU3lzSGFuZGxlciwgbV9wRm9ybUZpbGxlcik7DQotCQkJCQlwU3lzSGFuZGxlci0+T3V0cHV0U2VsZWN0ZWRSZWN0KG1fcEZvcm1GaWxsZXIsIHJjSXRlbSk7DQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQl7DQotCQkJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbFJlY3QocERldmljZSwgcFVzZXIyRGV2aWNlLCByY0l0ZW0sIEFyZ2JFbmNvZGUoMjU1LDAsNTEsMTEzKSk7DQotCQkJCQlJRlhfRWRpdDo6RHJhd0VkaXQocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX3BMaXN0LT5HZXRJdGVtRWRpdChpKSwgQXJnYkVuY29kZSgyNTUsMjU1LDI1NSwyNTUpLCAwLA0KLQkJCQkJCXJjTGlzdCwgcHRPZmZzZXQsIE5VTEwsIHBTeXNIYW5kbGVyLCBtX3BGb3JtRmlsbGVyKTsNCi0JCQkJfQ0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlJRlhfU3lzdGVtSGFuZGxlciogcFN5c0hhbmRsZXIgPSBHZXRTeXN0ZW1IYW5kbGVyKCk7DQotCQkJCUlGWF9FZGl0OjpEcmF3RWRpdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIG1fcExpc3QtPkdldEl0ZW1FZGl0KGkpLCANCi0JCQkJCQlDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSksDQotCQkJCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dFN0cm9rZUNvbG9yKCkpLA0KLQkJCQkJCXJjTGlzdCwgcHRPZmZzZXQsIE5VTEwscFN5c0hhbmRsZXIsIE5VTEwpOw0KLQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi1GWF9CT09MIENQV0xfTGlzdEJveDo6T25LZXlEb3duKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JQ1BXTF9XbmQ6Ok9uS2V5RG93bihuQ2hhciwgbkZsYWcpOw0KLQ0KLQlpZiAoIW1fcExpc3QpIHJldHVybiBGQUxTRTsNCi0NCi0Jc3dpdGNoIChuQ2hhcikNCi0Jew0KLQlkZWZhdWx0Og0KLQkJcmV0dXJuIEZBTFNFOw0KLQljYXNlIEZXTF9WS0VZX1VwOg0KLQljYXNlIEZXTF9WS0VZX0Rvd246DQotCWNhc2UgRldMX1ZLRVlfSG9tZToNCi0JY2FzZSBGV0xfVktFWV9MZWZ0Og0KLQljYXNlIEZXTF9WS0VZX0VuZDoNCi0JY2FzZSBGV0xfVktFWV9SaWdodDoNCi0JCWJyZWFrOwkNCi0JfQ0KLQ0KLQlzd2l0Y2ggKG5DaGFyKQ0KLQl7DQotCWNhc2UgRldMX1ZLRVlfVXA6DQotCQltX3BMaXN0LT5PblZLX1VQKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9Eb3duOg0KLQkJbV9wTGlzdC0+T25WS19ET1dOKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9Ib21lOg0KLQkJbV9wTGlzdC0+T25WS19IT01FKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9MZWZ0Og0KLQkJbV9wTGlzdC0+T25WS19MRUZUKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9FbmQ6DQotCQltX3BMaXN0LT5PblZLX0VORChJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOw0KLQkJYnJlYWs7DQotCWNhc2UgRldMX1ZLRVlfUmlnaHQ6DQotCQltX3BMaXN0LT5PblZLX1JJR0hUKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCQlicmVhazsNCi0JY2FzZSBGV0xfVktFWV9EZWxldGU6DQotCQlicmVhazsNCi0JfQ0KLQ0KLQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7DQotCU9uTm90aWZ5U2VsQ2hhbmdlZChUUlVFLGJFeGl0LG5GbGFnKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9MaXN0Qm94OjpPbkNoYXIoRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlDUFdMX1duZDo6T25DaGFyKG5DaGFyLG5GbGFnKTsNCi0NCi0JaWYgKCFtX3BMaXN0KSByZXR1cm4gRkFMU0U7DQotDQotCWlmICghbV9wTGlzdC0+T25DaGFyKG5DaGFyLElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSkpIHJldHVybiBGQUxTRTsNCi0NCi0JRlhfQk9PTCBiRXhpdCA9IEZBTFNFOw0KLQlPbk5vdGlmeVNlbENoYW5nZWQoVFJVRSxiRXhpdCwgbkZsYWcpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBDUFdMX0xpc3RCb3g6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKTsNCi0NCi0JaWYgKENsaWVudEhpdFRlc3QocG9pbnQpKQ0KLQl7DQotCQltX2JNb3VzZURvd24gPSBUUlVFOw0KLQkJU2V0Rm9jdXMoKTsNCi0JCVNldENhcHR1cmUoKTsNCi0NCi0JCWlmIChtX3BMaXN0KQ0KLQkJCW1fcExpc3QtPk9uTW91c2VEb3duKHBvaW50LElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9MaXN0Qm94OjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JQ1BXTF9XbmQ6Ok9uTEJ1dHRvblVwKHBvaW50LG5GbGFnKTsNCi0NCi0JaWYgKG1fYk1vdXNlRG93bikNCi0Jew0KLQkJUmVsZWFzZUNhcHR1cmUoKTsNCi0JCW1fYk1vdXNlRG93biA9IEZBTFNFOw0KLQl9DQotDQotCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsNCi0JT25Ob3RpZnlTZWxDaGFuZ2VkKEZBTFNFLGJFeGl0LG5GbGFnKTsNCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MaXN0Qm94OjpTZXRIb3ZlclNlbChGWF9CT09MIGJIb3ZlclNlbCkNCi17DQotCW1fYkhvdmVyU2VsID0gYkhvdmVyU2VsOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfTGlzdEJveDo6T25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbk1vdXNlTW92ZShwb2ludCwgbkZsYWcpOw0KLQ0KLQlpZiAobV9iSG92ZXJTZWwgJiYgIUlzQ2FwdHVyZU1vdXNlKCkgJiYgQ2xpZW50SGl0VGVzdChwb2ludCkpDQotCXsNCi0JCWlmIChtX3BMaXN0KQ0KLQkJCW1fcExpc3QtPlNlbGVjdChtX3BMaXN0LT5HZXRJdGVtSW5kZXgocG9pbnQpKTsNCi0JfQ0KLQ0KLQlpZiAobV9iTW91c2VEb3duKQ0KLQl7DQotCQlpZiAobV9wTGlzdCkNCi0JCQltX3BMaXN0LT5Pbk1vdXNlTW92ZShwb2ludCxJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOw0KLQl9CQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBDUFdMX0xpc3RCb3g6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pDQotew0KLQlDUFdMX1duZDo6T25Ob3RpZnkocFduZCxtc2csd1BhcmFtLGxQYXJhbSk7DQotDQotCUZYX0ZMT0FUIGZQb3M7CQ0KLQkNCi0Jc3dpdGNoIChtc2cpDQotCXsNCi0JY2FzZSBQTk1fU0VUU0NST0xMSU5GTzoNCi0JCXN3aXRjaCAod1BhcmFtKQ0KLQkJew0KLQkJY2FzZSBTQlRfVlNDUk9MTDoNCi0JCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBHZXRWU2Nyb2xsQmFyKCkpDQotCQkJew0KLQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHBXbmQsUE5NX1NFVFNDUk9MTElORk8sd1BhcmFtLGxQYXJhbSk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgUE5NX1NFVFNDUk9MTFBPUzoJCQkNCi0JCXN3aXRjaCAod1BhcmFtKQ0KLQkJew0KLQkJY2FzZSBTQlRfVlNDUk9MTDoNCi0JCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBHZXRWU2Nyb2xsQmFyKCkpDQotCQkJew0KLQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHBXbmQsUE5NX1NFVFNDUk9MTFBPUyx3UGFyYW0sbFBhcmFtKTsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBQTk1fU0NST0xMV0lORE9XOg0KLQkJZlBvcyA9ICooRlhfRkxPQVQqKWxQYXJhbTsNCi0JCXN3aXRjaCAod1BhcmFtKQ0KLQkJew0KLQkJY2FzZSBTQlRfVlNDUk9MTDoNCi0JCQlpZiAobV9wTGlzdCkNCi0JCQkJbV9wTGlzdC0+U2V0U2Nyb2xsUG9zKENQREZfUG9pbnQoMCxmUG9zKSk7DQotCQkJYnJlYWs7DQotCQl9DQotCQlicmVhazsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEJveDo6S2lsbEZvY3VzKCkNCi17DQotCUNQV0xfV25kOjpLaWxsRm9jdXMoKTsNCi0NCi0JLyoNCi0JaWYgKHRoaXMtPklzTXVsdGlwbGVTZWwoKSkNCi0Jew0KLQkJZm9yKEZYX0lOVDMyIGk9MDtpPHRoaXMtPkdldENvdW50KCk7aSsrKQ0KLQkJew0KLQkJCWlmICh0aGlzLT5Jc0xpc3RJdGVtU2VsZWN0ZWQoaSkpDQotCQkJew0KLQkJCQlpZiAoIUlzTGlzdEl0ZW1WaXNpYmxlKGkpKQ0KLQkJCQkJdGhpcy0+U2Nyb2xsVG9MaXN0SXRlbShpKTsNCi0JCQkJYnJlYWs7DQotCQkJfQ0KLQkJfQ0KLQl9DQotCWVsc2UNCi0Jew0KLQkJaWYgKCFJc0xpc3RJdGVtVmlzaWJsZSh0aGlzLT5HZXRDdXJTZWwoKSkpDQotCQkJdGhpcy0+U2Nyb2xsVG9MaXN0SXRlbSh0aGlzLT5HZXRDdXJTZWwoKSk7DQotCX0NCi0NCi0JU2V0TGlzdEl0ZW1DYXJldChtX25DYXJldEluZGV4LEZBTFNFKTsNCi0JKi8NCi19DQotDQotdm9pZCBDUFdMX0xpc3RCb3g6OlJlUG9zQ2hpbGRXbmQoKQ0KLXsNCi0JQ1BXTF9XbmQ6OlJlUG9zQ2hpbGRXbmQoKTsNCi0NCi0JaWYgKG1fcExpc3QpDQotCQltX3BMaXN0LT5TZXRQbGF0ZVJlY3QoR2V0TGlzdFJlY3QoKSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MaXN0Qm94OjpPbk5vdGlmeVNlbENoYW5nZWQoRlhfQk9PTCBiS2V5RG93biwgRlhfQk9PTCAmIGJFeGl0LCAgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAobV9wRmlsbGVyTm90aWZ5KQ0KLQl7CQkNCi0JCUZYX0JPT0wgYlJDID0gVFJVRTsNCi0JCUNGWF9XaWRlU3RyaW5nIHN3Q2hhbmdlID0gR2V0VGV4dCgpOw0KLQkJQ0ZYX1dpZGVTdHJpbmcgc3RyQ2hhbmdlRXg7DQotCQlpbnQgblNlbFN0YXJ0ID0gMDsNCi0JCWludCBuU2VsRW5kID0gc3dDaGFuZ2UuR2V0TGVuZ3RoKCk7DQotCQltX3BGaWxsZXJOb3RpZnktPk9uQmVmb3JlS2V5U3Ryb2tlKEZBTFNFLCBHZXRBdHRhY2hlZERhdGEoKSwgMCwgc3dDaGFuZ2UsIHN0ckNoYW5nZUV4LCBuU2VsU3RhcnQsIG5TZWxFbmQsIGJLZXlEb3duLCBiUkMsIGJFeGl0LCBuRmxhZyk7DQotCQlpZiAoYkV4aXQpIHJldHVybjsNCi0NCi0JCW1fcEZpbGxlck5vdGlmeS0+T25BZnRlcktleVN0cm9rZShGQUxTRSwgR2V0QXR0YWNoZWREYXRhKCksIGJFeGl0LG5GbGFnKTsNCi0JfQ0KLX0NCi0NCi1DUERGX1JlY3QgQ1BXTF9MaXN0Qm94OjpHZXRGb2N1c1JlY3QoKSBjb25zdA0KLXsNCi0JaWYgKG1fcExpc3QgJiYgbV9wTGlzdC0+SXNNdWx0aXBsZVNlbCgpKQ0KLQl7DQotCQlDUERGX1JlY3QgcmNDYXJldCA9IG1fcExpc3QtPkdldEl0ZW1SZWN0KG1fcExpc3QtPkdldENhcmV0KCkpOw0KLQkJcmNDYXJldC5JbnRlcnNlY3QoR2V0Q2xpZW50UmVjdCgpKTsNCi0JCXJldHVybiByY0NhcmV0Ow0KLQl9DQotCQ0KLQlyZXR1cm4gQ1BXTF9XbmQ6OkdldEZvY3VzUmVjdCgpOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEJveDo6QWRkU3RyaW5nKEZYX0xQQ1dTVFIgc3RyaW5nKQ0KLXsNCi0JaWYgKG1fcExpc3QpDQotCXsJCQ0KLQkJbV9wTGlzdC0+QWRkU3RyaW5nKHN0cmluZyk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0xpc3RCb3g6OlNldFRleHQoRlhfTFBDV1NUUiBjc1RleHQsRlhfQk9PTCBiUmVmcmVzaCkNCi17DQotCS8vcmV0dXJuIENQREZfTGlzdDo6U2V0VGV4dChjc1RleHQsYlJlZnJlc2gpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUFdMX0xpc3RCb3g6OkdldFRleHQoKSBjb25zdA0KLXsNCi0JaWYgKG1fcExpc3QpDQotCQlyZXR1cm4gbV9wTGlzdC0+R2V0VGV4dCgpOw0KLQ0KLQlyZXR1cm4gTCIiOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEJveDo6U2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKQ0KLXsNCi0JaWYgKG1fcExpc3QpDQotCQltX3BMaXN0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOw0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX0xpc3RCb3g6OkdldEZvbnRTaXplKCkgY29uc3QNCi17DQotCWlmIChtX3BMaXN0KQ0KLQkJcmV0dXJuIG1fcExpc3QtPkdldEZvbnRTaXplKCk7DQotCXJldHVybiAwLjBmOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEJveDo6U2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgpDQotew0KLQlpZiAobV9wTGlzdCkNCi0JCW1fcExpc3QtPlNlbGVjdChuSXRlbUluZGV4KTsNCi19DQotDQotdm9pZCBDUFdMX0xpc3RCb3g6OlNldENhcmV0KEZYX0lOVDMyIG5JdGVtSW5kZXgpDQotew0KLQlpZiAobV9wTGlzdCkNCi0JCW1fcExpc3QtPlNldENhcmV0KG5JdGVtSW5kZXgpOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEJveDo6U2V0VG9wVmlzaWJsZUluZGV4KEZYX0lOVDMyIG5JdGVtSW5kZXgpDQotew0KLQlpZiAobV9wTGlzdCkNCi0JCW1fcExpc3QtPlNldFRvcEl0ZW0obkl0ZW1JbmRleCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MaXN0Qm94OjpTY3JvbGxUb0xpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpDQotew0KLQlpZiAobV9wTGlzdCkNCi0JCW1fcExpc3QtPlNjcm9sbFRvTGlzdEl0ZW0obkl0ZW1JbmRleCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MaXN0Qm94OjpSZXNldENvbnRlbnQoKQ0KLXsNCi0JaWYgKG1fcExpc3QpDQotCQltX3BMaXN0LT5FbXB0eSgpOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEJveDo6UmVzZXQoKQ0KLXsNCi0JaWYgKG1fcExpc3QpDQotCQltX3BMaXN0LT5DYW5jZWwoKTsNCi19DQotDQotRlhfQk9PTCBDUFdMX0xpc3RCb3g6OklzTXVsdGlwbGVTZWwoKSBjb25zdA0KLXsNCi0JaWYgKG1fcExpc3QpDQotCQlyZXR1cm4gbV9wTGlzdC0+SXNNdWx0aXBsZVNlbCgpOw0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfTGlzdEJveDo6R2V0Q2FyZXRJbmRleCgpIGNvbnN0DQotew0KLQlpZiAobV9wTGlzdCkNCi0JCXJldHVybiBtX3BMaXN0LT5HZXRDYXJldCgpOw0KLQ0KLQlyZXR1cm4gLTE7DQotfQ0KLQ0KLUZYX0lOVDMyIENQV0xfTGlzdEJveDo6R2V0Q3VyU2VsKCkgY29uc3QNCi17DQotCWlmIChtX3BMaXN0KQ0KLQkJcmV0dXJuIG1fcExpc3QtPkdldFNlbGVjdCgpOw0KLQ0KLQlyZXR1cm4gLTE7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9MaXN0Qm94OjpJc0l0ZW1TZWxlY3RlZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdA0KLXsNCi0JaWYgKG1fcExpc3QpDQotCQlyZXR1cm4gbV9wTGlzdC0+SXNJdGVtU2VsZWN0ZWQobkl0ZW1JbmRleCk7DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9MaXN0Qm94OjpHZXRUb3BWaXNpYmxlSW5kZXgoKSBjb25zdA0KLXsNCi0JaWYgKG1fcExpc3QpDQotCXsNCi0JCW1fcExpc3QtPlNjcm9sbFRvTGlzdEl0ZW0obV9wTGlzdC0+R2V0Rmlyc3RTZWxlY3RlZCgpKTsNCi0JCXJldHVybiBtX3BMaXN0LT5HZXRUb3BJdGVtKCk7DQotCX0NCi0NCi0JcmV0dXJuIC0xOw0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX0xpc3RCb3g6OkdldENvdW50KCkgY29uc3QNCi17DQotCWlmIChtX3BMaXN0KQ0KLQkJcmV0dXJuIG1fcExpc3QtPkdldENvdW50KCk7DQotDQotCXJldHVybiAwOw0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX0xpc3RCb3g6OkZpbmROZXh0KEZYX0lOVDMyIG5JbmRleCxGWF9XQ0hBUiBuQ2hhcikgY29uc3QNCi17DQotCWlmIChtX3BMaXN0KQ0KLQkJcmV0dXJuIG1fcExpc3QtPkZpbmROZXh0KG5JbmRleCxuQ2hhcik7DQotDQotCXJldHVybiBuSW5kZXg7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX0xpc3RCb3g6OkdldENvbnRlbnRSZWN0KCkgY29uc3QNCi17DQotCWlmIChtX3BMaXN0KQ0KLQkJcmV0dXJuIG1fcExpc3QtPkdldENvbnRlbnRSZWN0KCk7DQotDQotCXJldHVybiBDUERGX1JlY3QoKTsNCi19DQotDQotRlhfRkxPQVQgQ1BXTF9MaXN0Qm94OjpHZXRGaXJzdEhlaWdodCgpIGNvbnN0DQotew0KLQlpZiAobV9wTGlzdCkNCi0JCXJldHVybiBtX3BMaXN0LT5HZXRGaXJzdEhlaWdodCgpOw0KLQ0KLQlyZXR1cm4gMC4wZjsNCi19DQotDQotQ1BERl9SZWN0IENQV0xfTGlzdEJveDo6R2V0TGlzdFJlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KEdldFdpbmRvd1JlY3QoKSwoRlhfRkxPQVQpKEdldEJvcmRlcldpZHRoKCkrR2V0SW5uZXJCb3JkZXJXaWR0aCgpKSk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9MaXN0Qm94OjpPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JaWYgKCFtX3BMaXN0KSByZXR1cm4gRkFMU0U7DQotDQotCWlmICh6RGVsdGEgPCAwKQ0KLQl7DQotCQltX3BMaXN0LT5PblZLX0RPV04oSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKTsNCi0JfQ0KLQllbHNlDQotCXsNCi0JCW1fcExpc3QtPk9uVktfVVAoSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKTsNCi0JfQ0KLQ0KLQlGWF9CT09MIGJFeGl0ID0gRkFMU0U7DQotCU9uTm90aWZ5U2VsQ2hhbmdlZChGQUxTRSxiRXhpdCwgbkZsYWcpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEJveC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TY3JvbGxCYXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdC5oIgorCisjZGVmaW5lIElzRmxvYXRaZXJvKGYpCQkJCQkJKChmKSA8IDAuMDAwMSAmJiAoZikgPiAtMC4wMDAxKQorI2RlZmluZSBJc0Zsb2F0QmlnZ2VyKGZhLGZiKQkJCQkoKGZhKSA+IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkKKyNkZWZpbmUgSXNGbG9hdFNtYWxsZXIoZmEsZmIpCQkJCSgoZmEpIDwgKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQorI2RlZmluZSBJc0Zsb2F0RXF1YWwoZmEsZmIpCQkJCQlJc0Zsb2F0WmVybygoZmEpLShmYikpCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0xpc3RfTm90aWZ5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfTGlzdF9Ob3RpZnk6OkNQV0xfTGlzdF9Ob3RpZnkoQ1BXTF9MaXN0Qm94KiBwTGlzdCkgOiBtX3BMaXN0KHBMaXN0KQoreworCUFTU0VSVChtX3BMaXN0ICE9IE5VTEwpOworfQorCitDUFdMX0xpc3RfTm90aWZ5Ojp+Q1BXTF9MaXN0X05vdGlmeSgpCit7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0X05vdGlmeTo6SU9uU2V0U2Nyb2xsSW5mb1koRlhfRkxPQVQgZlBsYXRlTWluLCBGWF9GTE9BVCBmUGxhdGVNYXgsIAorCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkNvbnRlbnRNaW4sIEZYX0ZMT0FUIGZDb250ZW50TWF4LCAKKwkJCQkJCQkJCQkJCUZYX0ZMT0FUIGZTbWFsbFN0ZXAsIEZYX0ZMT0FUIGZCaWdTdGVwKQoreworCVBXTF9TQ1JPTExfSU5GTyBJbmZvOworCisJSW5mby5mUGxhdGVXaWR0aCA9IGZQbGF0ZU1heCAtIGZQbGF0ZU1pbjsKKwlJbmZvLmZDb250ZW50TWluID0gZkNvbnRlbnRNaW47CisJSW5mby5mQ29udGVudE1heCA9IGZDb250ZW50TWF4OworCUluZm8uZlNtYWxsU3RlcCA9IGZTbWFsbFN0ZXA7CisJSW5mby5mQmlnU3RlcCA9IGZCaWdTdGVwOworCisJbV9wTGlzdC0+T25Ob3RpZnkobV9wTGlzdCxQTk1fU0VUU0NST0xMSU5GTyxTQlRfVlNDUk9MTCwoRlhfSU5UUFRSKSZJbmZvKTsKKworCWlmIChDUFdMX1Njcm9sbEJhciAqIHBTY3JvbGwgPSBtX3BMaXN0LT5HZXRWU2Nyb2xsQmFyKCkpCisJeworCQlpZiAoSXNGbG9hdEJpZ2dlcihJbmZvLmZQbGF0ZVdpZHRoLEluZm8uZkNvbnRlbnRNYXgtSW5mby5mQ29udGVudE1pbikKKwkJCXx8IElzRmxvYXRFcXVhbChJbmZvLmZQbGF0ZVdpZHRoLEluZm8uZkNvbnRlbnRNYXgtSW5mby5mQ29udGVudE1pbikpCisJCXsKKwkJCWlmIChwU2Nyb2xsLT5Jc1Zpc2libGUoKSkKKwkJCXsKKwkJCQlwU2Nyb2xsLT5TZXRWaXNpYmxlKEZBTFNFKTsKKwkJCQltX3BMaXN0LT5SZVBvc0NoaWxkV25kKCk7CisJCQl9CQkJCisJCX0KKwkJZWxzZQorCQl7CisJCQlpZiAoIXBTY3JvbGwtPklzVmlzaWJsZSgpKQorCQkJeworCQkJCXBTY3JvbGwtPlNldFZpc2libGUoVFJVRSk7CQorCQkJCW1fcExpc3QtPlJlUG9zQ2hpbGRXbmQoKTsKKwkJCX0KKwkJfQorCX0JCit9CisKK3ZvaWQgQ1BXTF9MaXN0X05vdGlmeTo6SU9uU2V0U2Nyb2xsUG9zWShGWF9GTE9BVCBmeSkKK3sKKwltX3BMaXN0LT5Pbk5vdGlmeShtX3BMaXN0LFBOTV9TRVRTQ1JPTExQT1MsU0JUX1ZTQ1JPTEwsKEZYX0lOVFBUUikmZnkpOworfQorCit2b2lkIENQV0xfTGlzdF9Ob3RpZnk6OklPbkludmFsaWRhdGVSZWN0KENQREZfUmVjdCAqIHBSZWN0KQoreworCW1fcExpc3QtPkludmFsaWRhdGVSZWN0KHBSZWN0KTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTGlzdEJveCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfTGlzdEJveDo6Q1BXTF9MaXN0Qm94KCkgOgorCW1fcExpc3QoTlVMTCksCisJbV9wTGlzdE5vdGlmeShOVUxMKSwKKwltX2JNb3VzZURvd24oRkFMU0UpLAorCW1fYkhvdmVyU2VsKEZBTFNFKSwKKwltX3BGaWxsZXJOb3RpZnkoTlVMTCkKK3sKKwltX3BMaXN0ID0gSUZYX0xpc3Q6Ok5ld0xpc3QoKTsKKworCUFTU0VSVChtX3BMaXN0ICE9IE5VTEwpOworfQorCitDUFdMX0xpc3RCb3g6On5DUFdMX0xpc3RCb3goKQoreworCUlGWF9MaXN0OjpEZWxMaXN0KG1fcExpc3QpOworCQorCWlmIChtX3BMaXN0Tm90aWZ5KQorCXsKKwkJZGVsZXRlIG1fcExpc3ROb3RpZnk7CisJCW1fcExpc3ROb3RpZnkgPSBOVUxMOworCX0KK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9MaXN0Qm94OjpHZXRDbGFzc05hbWUoKSBjb25zdAorewkKKwlyZXR1cm4gIkNQV0xfTGlzdEJveCI7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Qm94OjpPbkNyZWF0ZWQoKQoreworCWlmIChtX3BMaXN0KQorCXsKKwkJaWYgKG1fcExpc3ROb3RpZnkpIGRlbGV0ZSBtX3BMaXN0Tm90aWZ5OworCisJCW1fcExpc3QtPlNldEZvbnRNYXAoR2V0Rm9udE1hcCgpKTsKKwkJbV9wTGlzdC0+U2V0Tm90aWZ5KG1fcExpc3ROb3RpZnkgPSBuZXcgQ1BXTF9MaXN0X05vdGlmeSh0aGlzKSk7CisJCisJCVNldEhvdmVyU2VsKEhhc0ZsYWcoUExCU19IT1ZFUlNFTCkpOwkKKwkJbV9wTGlzdC0+U2V0TXVsdGlwbGVTZWwoSGFzRmxhZyhQTEJTX01VTFRJUExFU0VMKSk7CisJCW1fcExpc3QtPlNldEZvbnRTaXplKHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKS5mRm9udFNpemUpOwkKKworCQltX2JIb3ZlclNlbCA9IEhhc0ZsYWcoUExCU19IT1ZFUlNFTCk7CisJfQorfQorCit2b2lkIENQV0xfTGlzdEJveDo6T25EZXN0cm95KCkKK3sKKwlpZiAobV9wTGlzdE5vdGlmeSkKKwl7CisJCWRlbGV0ZSBtX3BMaXN0Tm90aWZ5OworCQltX3BMaXN0Tm90aWZ5ID0gTlVMTDsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Qm94OjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKQoreworCUNQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsKKworCUNGWF9CeXRlVGV4dEJ1ZiBzTGlzdEl0ZW1zOworCisJaWYgKG1fcExpc3QpCisJeworCQlDUERGX1JlY3QgcmNQbGF0ZSA9IG1fcExpc3QtPkdldFBsYXRlUmVjdCgpOworCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX3BMaXN0LT5HZXRDb3VudCgpOyBpPHN6OyBpKyspCisJCXsKKwkJCUNQREZfUmVjdCByY0l0ZW0gPSBtX3BMaXN0LT5HZXRJdGVtUmVjdChpKTsKKworCQkJaWYgKHJjSXRlbS5ib3R0b20gPiByY1BsYXRlLnRvcCB8fCByY0l0ZW0udG9wIDwgcmNQbGF0ZS5ib3R0b20pIGNvbnRpbnVlOworCQkJCisJCQlDUERGX1BvaW50IHB0T2Zmc2V0KHJjSXRlbS5sZWZ0LCAocmNJdGVtLnRvcCArIHJjSXRlbS5ib3R0b20pICogMC41Zik7CisJCQlpZiAobV9wTGlzdC0+SXNJdGVtU2VsZWN0ZWQoaSkpCisJCQl7CisJCQkJc0xpc3RJdGVtcyA8PCBDUFdMX1V0aWxzOjpHZXRSZWN0RmlsbEFwcFN0cmVhbShyY0l0ZW0sUFdMX0RFRkFVTFRfU0VMQkFDS0NPTE9SKTsKKwkJCQlDRlhfQnl0ZVN0cmluZyBzSXRlbSA9IENQV0xfVXRpbHM6OkdldEVkaXRBcHBTdHJlYW0obV9wTGlzdC0+R2V0SXRlbUVkaXQoaSksIHB0T2Zmc2V0KTsKKwkJCQlpZiAoc0l0ZW0uR2V0TGVuZ3RoKCkgPiAwKQorCQkJCXsKKwkJCQkJc0xpc3RJdGVtcyA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oUFdMX0RFRkFVTFRfU0VMVEVYVENPTE9SKSA8PCBzSXRlbSA8PCAiRVRcbiI7CisJCQkJfQorCQkJfQorCQkJZWxzZQorCQkJeworCQkJCUNGWF9CeXRlU3RyaW5nIHNJdGVtID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShtX3BMaXN0LT5HZXRJdGVtRWRpdChpKSwgcHRPZmZzZXQpOworCQkJCWlmIChzSXRlbS5HZXRMZW5ndGgoKSA+IDApCisJCQkJeworCQkJCQlzTGlzdEl0ZW1zIDw8ICJCVFxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShHZXRUZXh0Q29sb3IoKSkgPDwgc0l0ZW0gPDwgIkVUXG4iOworCQkJCX0KKwkJCX0KKwkJfQorCX0KKworCWlmIChzTGlzdEl0ZW1zLkdldExlbmd0aCgpID4gMCkKKwl7CisJCUNGWF9CeXRlVGV4dEJ1ZiBzQ2xpcDsJCQkKKwkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOworCisJCXNDbGlwIDw8ICJxXG4iOworCQlzQ2xpcCA8PCByY0NsaWVudC5sZWZ0IDw8ICIgIiA8PCByY0NsaWVudC5ib3R0b20gPDwgIiAiCisJCQk8PCByY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQgPDwgIiAiIDw8CXJjQ2xpZW50LnRvcCAtIHJjQ2xpZW50LmJvdHRvbSA8PCAiIHJlIFcgblxuIjsKKworCQlzQ2xpcCA8PCBzTGlzdEl0ZW1zIDw8ICJRXG4iOworCisJCXNBcHBTdHJlYW0gPDwgIi9UeCBCTUNcbiIgPDwgc0NsaXAgPDwgIkVNQ1xuIjsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Qm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKK3sKKwlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UscFVzZXIyRGV2aWNlKTsKKworCWlmIChtX3BMaXN0KQorCXsKKwkJQ1BERl9SZWN0IHJjUGxhdGUgPSBtX3BMaXN0LT5HZXRQbGF0ZVJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjTGlzdCA9IEdldExpc3RSZWN0KCk7CisJCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKworCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX3BMaXN0LT5HZXRDb3VudCgpOyBpPHN6OyBpKyspCisJCXsKKwkJCUNQREZfUmVjdCByY0l0ZW0gPSBtX3BMaXN0LT5HZXRJdGVtUmVjdChpKTsKKwkJCWlmIChyY0l0ZW0uYm90dG9tID4gcmNQbGF0ZS50b3AgfHwgcmNJdGVtLnRvcCA8IHJjUGxhdGUuYm90dG9tKSBjb250aW51ZTsKKwkJCQorCQkJQ1BERl9Qb2ludCBwdE9mZnNldChyY0l0ZW0ubGVmdCwgKHJjSXRlbS50b3AgKyByY0l0ZW0uYm90dG9tKSAqIDAuNWYpOworCQkJaWYgKElGWF9FZGl0KiBwRWRpdCA9IG1fcExpc3QtPkdldEl0ZW1FZGl0KGkpKQorCQkJeworCQkJCUNQREZfUmVjdCByY0NvbnRlbnQgPSBwRWRpdC0+R2V0Q29udGVudFJlY3QoKTsKKwkJCQlpZiAocmNDb250ZW50LldpZHRoKCkgPiByY0NsaWVudC5XaWR0aCgpKQorCQkJCQlyY0l0ZW0uSW50ZXJzZWN0KHJjTGlzdCk7CisJCQkJZWxzZQorCQkJCQlyY0l0ZW0uSW50ZXJzZWN0KHJjQ2xpZW50KTsKKwkJCX0KKworCQkJaWYgKG1fcExpc3QtPklzSXRlbVNlbGVjdGVkKGkpKQorCQkJeworCQkJLy8JQ1BXTF9VdGlsczo6RHJhd0ZpbGxSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNJdGVtLCBBcmdiRW5jb2RlKDI1NSwwLDUxLDExMykpOworCQkJCUlGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzSGFuZGxlciA9IEdldFN5c3RlbUhhbmRsZXIoKTsKKwkJCQlpZihwU3lzSGFuZGxlciAmJiBwU3lzSGFuZGxlci0+SXNTZWxlY3Rpb25JbXBsZW1lbnRlZCgpKQorCQkJCXsKKwkJCQkJSUZYX0VkaXQ6OkRyYXdFZGl0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgbV9wTGlzdC0+R2V0SXRlbUVkaXQoaSksIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpKSwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dFN0cm9rZUNvbG9yKCkpLAorCQkJCQkJcmNMaXN0LCBwdE9mZnNldCwgTlVMTCxwU3lzSGFuZGxlciwgbV9wRm9ybUZpbGxlcik7CisJCQkJCXBTeXNIYW5kbGVyLT5PdXRwdXRTZWxlY3RlZFJlY3QobV9wRm9ybUZpbGxlciwgcmNJdGVtKTsKKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJQ1BXTF9VdGlsczo6RHJhd0ZpbGxSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNJdGVtLCBBcmdiRW5jb2RlKDI1NSwwLDUxLDExMykpOworCQkJCQlJRlhfRWRpdDo6RHJhd0VkaXQocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX3BMaXN0LT5HZXRJdGVtRWRpdChpKSwgQXJnYkVuY29kZSgyNTUsMjU1LDI1NSwyNTUpLCAwLAorCQkJCQkJcmNMaXN0LCBwdE9mZnNldCwgTlVMTCwgcFN5c0hhbmRsZXIsIG1fcEZvcm1GaWxsZXIpOworCQkJCX0KKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlJRlhfU3lzdGVtSGFuZGxlciogcFN5c0hhbmRsZXIgPSBHZXRTeXN0ZW1IYW5kbGVyKCk7CisJCQkJSUZYX0VkaXQ6OkRyYXdFZGl0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgbV9wTGlzdC0+R2V0SXRlbUVkaXQoaSksIAorCQkJCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCkpLAorCQkJCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dFN0cm9rZUNvbG9yKCkpLAorCQkJCQkJcmNMaXN0LCBwdE9mZnNldCwgTlVMTCxwU3lzSGFuZGxlciwgTlVMTCk7CisKKwkJCX0KKwkJfQorCX0KK30KKworRlhfQk9PTCBDUFdMX0xpc3RCb3g6Ok9uS2V5RG93bihGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZykKK3sKKwlDUFdMX1duZDo6T25LZXlEb3duKG5DaGFyLCBuRmxhZyk7CisKKwlpZiAoIW1fcExpc3QpIHJldHVybiBGQUxTRTsKKworCXN3aXRjaCAobkNoYXIpCisJeworCWRlZmF1bHQ6CisJCXJldHVybiBGQUxTRTsKKwljYXNlIEZXTF9WS0VZX1VwOgorCWNhc2UgRldMX1ZLRVlfRG93bjoKKwljYXNlIEZXTF9WS0VZX0hvbWU6CisJY2FzZSBGV0xfVktFWV9MZWZ0OgorCWNhc2UgRldMX1ZLRVlfRW5kOgorCWNhc2UgRldMX1ZLRVlfUmlnaHQ6CisJCWJyZWFrOwkKKwl9CisKKwlzd2l0Y2ggKG5DaGFyKQorCXsKKwljYXNlIEZXTF9WS0VZX1VwOgorCQltX3BMaXN0LT5PblZLX1VQKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7CisJCWJyZWFrOworCWNhc2UgRldMX1ZLRVlfRG93bjoKKwkJbV9wTGlzdC0+T25WS19ET1dOKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7CisJCWJyZWFrOworCWNhc2UgRldMX1ZLRVlfSG9tZToKKwkJbV9wTGlzdC0+T25WS19IT01FKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7CisJCWJyZWFrOworCWNhc2UgRldMX1ZLRVlfTGVmdDoKKwkJbV9wTGlzdC0+T25WS19MRUZUKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7CisJCWJyZWFrOworCWNhc2UgRldMX1ZLRVlfRW5kOgorCQltX3BMaXN0LT5PblZLX0VORChJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCQlicmVhazsKKwljYXNlIEZXTF9WS0VZX1JpZ2h0OgorCQltX3BMaXN0LT5PblZLX1JJR0hUKElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSk7CisJCWJyZWFrOworCWNhc2UgRldMX1ZLRVlfRGVsZXRlOgorCQlicmVhazsKKwl9CisKKwlGWF9CT09MIGJFeGl0ID0gRkFMU0U7CisJT25Ob3RpZnlTZWxDaGFuZ2VkKFRSVUUsYkV4aXQsbkZsYWcpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgQ1BXTF9MaXN0Qm94OjpPbkNoYXIoRlhfV09SRCBuQ2hhciwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BXTF9XbmQ6Ok9uQ2hhcihuQ2hhcixuRmxhZyk7CisKKwlpZiAoIW1fcExpc3QpIHJldHVybiBGQUxTRTsKKworCWlmICghbV9wTGlzdC0+T25DaGFyKG5DaGFyLElzU0hJRlRwcmVzc2VkKG5GbGFnKSxJc0NUUkxwcmVzc2VkKG5GbGFnKSkpIHJldHVybiBGQUxTRTsKKworCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsKKwlPbk5vdGlmeVNlbENoYW5nZWQoVFJVRSxiRXhpdCwgbkZsYWcpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgQ1BXTF9MaXN0Qm94OjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOworCisJaWYgKENsaWVudEhpdFRlc3QocG9pbnQpKQorCXsKKwkJbV9iTW91c2VEb3duID0gVFJVRTsKKwkJU2V0Rm9jdXMoKTsKKwkJU2V0Q2FwdHVyZSgpOworCisJCWlmIChtX3BMaXN0KQorCQkJbV9wTGlzdC0+T25Nb3VzZURvd24ocG9pbnQsSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKTsKKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTCBDUFdMX0xpc3RCb3g6Ok9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BXTF9XbmQ6Ok9uTEJ1dHRvblVwKHBvaW50LG5GbGFnKTsKKworCWlmIChtX2JNb3VzZURvd24pCisJeworCQlSZWxlYXNlQ2FwdHVyZSgpOworCQltX2JNb3VzZURvd24gPSBGQUxTRTsKKwl9CisKKwlGWF9CT09MIGJFeGl0ID0gRkFMU0U7CisJT25Ob3RpZnlTZWxDaGFuZ2VkKEZBTFNFLGJFeGl0LG5GbGFnKTsKKworCXJldHVybiBUUlVFOworfQorCit2b2lkIENQV0xfTGlzdEJveDo6U2V0SG92ZXJTZWwoRlhfQk9PTCBiSG92ZXJTZWwpCit7CisJbV9iSG92ZXJTZWwgPSBiSG92ZXJTZWw7Cit9CisKK0ZYX0JPT0wgQ1BXTF9MaXN0Qm94OjpPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCUNQV0xfV25kOjpPbk1vdXNlTW92ZShwb2ludCwgbkZsYWcpOworCisJaWYgKG1fYkhvdmVyU2VsICYmICFJc0NhcHR1cmVNb3VzZSgpICYmIENsaWVudEhpdFRlc3QocG9pbnQpKQorCXsKKwkJaWYgKG1fcExpc3QpCisJCQltX3BMaXN0LT5TZWxlY3QobV9wTGlzdC0+R2V0SXRlbUluZGV4KHBvaW50KSk7CisJfQorCisJaWYgKG1fYk1vdXNlRG93bikKKwl7CisJCWlmIChtX3BMaXN0KQorCQkJbV9wTGlzdC0+T25Nb3VzZU1vdmUocG9pbnQsSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKTsKKwl9CQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Qm94OjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQoreworCUNQV0xfV25kOjpPbk5vdGlmeShwV25kLG1zZyx3UGFyYW0sbFBhcmFtKTsKKworCUZYX0ZMT0FUIGZQb3M7CQorCQorCXN3aXRjaCAobXNnKQorCXsKKwljYXNlIFBOTV9TRVRTQ1JPTExJTkZPOgorCQlzd2l0Y2ggKHdQYXJhbSkKKwkJeworCQljYXNlIFNCVF9WU0NST0xMOgorCQkJaWYgKENQV0xfV25kICogcENoaWxkID0gR2V0VlNjcm9sbEJhcigpKQorCQkJeworCQkJCXBDaGlsZC0+T25Ob3RpZnkocFduZCxQTk1fU0VUU0NST0xMSU5GTyx3UGFyYW0sbFBhcmFtKTsKKwkJCX0KKwkJCWJyZWFrOworCQl9CisJCWJyZWFrOworCWNhc2UgUE5NX1NFVFNDUk9MTFBPUzoJCQkKKwkJc3dpdGNoICh3UGFyYW0pCisJCXsKKwkJY2FzZSBTQlRfVlNDUk9MTDoKKwkJCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IEdldFZTY3JvbGxCYXIoKSkKKwkJCXsKKwkJCQlwQ2hpbGQtPk9uTm90aWZ5KHBXbmQsUE5NX1NFVFNDUk9MTFBPUyx3UGFyYW0sbFBhcmFtKTsKKwkJCX0KKwkJCWJyZWFrOworCQl9CisJCWJyZWFrOworCWNhc2UgUE5NX1NDUk9MTFdJTkRPVzoKKwkJZlBvcyA9ICooRlhfRkxPQVQqKWxQYXJhbTsKKwkJc3dpdGNoICh3UGFyYW0pCisJCXsKKwkJY2FzZSBTQlRfVlNDUk9MTDoKKwkJCWlmIChtX3BMaXN0KQorCQkJCW1fcExpc3QtPlNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAsZlBvcykpOworCQkJYnJlYWs7CisJCX0KKwkJYnJlYWs7CisJfQorfQorCit2b2lkIENQV0xfTGlzdEJveDo6S2lsbEZvY3VzKCkKK3sKKwlDUFdMX1duZDo6S2lsbEZvY3VzKCk7CisKKwkvKgorCWlmICh0aGlzLT5Jc011bHRpcGxlU2VsKCkpCisJeworCQlmb3IoRlhfSU5UMzIgaT0wO2k8dGhpcy0+R2V0Q291bnQoKTtpKyspCisJCXsKKwkJCWlmICh0aGlzLT5Jc0xpc3RJdGVtU2VsZWN0ZWQoaSkpCisJCQl7CisJCQkJaWYgKCFJc0xpc3RJdGVtVmlzaWJsZShpKSkKKwkJCQkJdGhpcy0+U2Nyb2xsVG9MaXN0SXRlbShpKTsKKwkJCQlicmVhazsKKwkJCX0KKwkJfQorCX0KKwllbHNlCisJeworCQlpZiAoIUlzTGlzdEl0ZW1WaXNpYmxlKHRoaXMtPkdldEN1clNlbCgpKSkKKwkJCXRoaXMtPlNjcm9sbFRvTGlzdEl0ZW0odGhpcy0+R2V0Q3VyU2VsKCkpOworCX0KKworCVNldExpc3RJdGVtQ2FyZXQobV9uQ2FyZXRJbmRleCxGQUxTRSk7CisJKi8KK30KKwordm9pZCBDUFdMX0xpc3RCb3g6OlJlUG9zQ2hpbGRXbmQoKQoreworCUNQV0xfV25kOjpSZVBvc0NoaWxkV25kKCk7CisKKwlpZiAobV9wTGlzdCkKKwkJbV9wTGlzdC0+U2V0UGxhdGVSZWN0KEdldExpc3RSZWN0KCkpOworfQorCit2b2lkIENQV0xfTGlzdEJveDo6T25Ob3RpZnlTZWxDaGFuZ2VkKEZYX0JPT0wgYktleURvd24sIEZYX0JPT0wgJiBiRXhpdCwgIEZYX0RXT1JEIG5GbGFnKQoreworCWlmIChtX3BGaWxsZXJOb3RpZnkpCisJewkJCisJCUZYX0JPT0wgYlJDID0gVFJVRTsKKwkJQ0ZYX1dpZGVTdHJpbmcgc3dDaGFuZ2UgPSBHZXRUZXh0KCk7CisJCUNGWF9XaWRlU3RyaW5nIHN0ckNoYW5nZUV4OworCQlpbnQgblNlbFN0YXJ0ID0gMDsKKwkJaW50IG5TZWxFbmQgPSBzd0NoYW5nZS5HZXRMZW5ndGgoKTsKKwkJbV9wRmlsbGVyTm90aWZ5LT5PbkJlZm9yZUtleVN0cm9rZShGQUxTRSwgR2V0QXR0YWNoZWREYXRhKCksIDAsIHN3Q2hhbmdlLCBzdHJDaGFuZ2VFeCwgblNlbFN0YXJ0LCBuU2VsRW5kLCBiS2V5RG93biwgYlJDLCBiRXhpdCwgbkZsYWcpOworCQlpZiAoYkV4aXQpIHJldHVybjsKKworCQltX3BGaWxsZXJOb3RpZnktPk9uQWZ0ZXJLZXlTdHJva2UoRkFMU0UsIEdldEF0dGFjaGVkRGF0YSgpLCBiRXhpdCxuRmxhZyk7CisJfQorfQorCitDUERGX1JlY3QgQ1BXTF9MaXN0Qm94OjpHZXRGb2N1c1JlY3QoKSBjb25zdAoreworCWlmIChtX3BMaXN0ICYmIG1fcExpc3QtPklzTXVsdGlwbGVTZWwoKSkKKwl7CisJCUNQREZfUmVjdCByY0NhcmV0ID0gbV9wTGlzdC0+R2V0SXRlbVJlY3QobV9wTGlzdC0+R2V0Q2FyZXQoKSk7CisJCXJjQ2FyZXQuSW50ZXJzZWN0KEdldENsaWVudFJlY3QoKSk7CisJCXJldHVybiByY0NhcmV0OworCX0KKwkKKwlyZXR1cm4gQ1BXTF9XbmQ6OkdldEZvY3VzUmVjdCgpOworfQorCit2b2lkIENQV0xfTGlzdEJveDo6QWRkU3RyaW5nKEZYX0xQQ1dTVFIgc3RyaW5nKQoreworCWlmIChtX3BMaXN0KQorCXsJCQorCQltX3BMaXN0LT5BZGRTdHJpbmcoc3RyaW5nKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Qm94OjpTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0LEZYX0JPT0wgYlJlZnJlc2gpCit7CisJLy9yZXR1cm4gQ1BERl9MaXN0OjpTZXRUZXh0KGNzVGV4dCxiUmVmcmVzaCk7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENQV0xfTGlzdEJveDo6R2V0VGV4dCgpIGNvbnN0Cit7CisJaWYgKG1fcExpc3QpCisJCXJldHVybiBtX3BMaXN0LT5HZXRUZXh0KCk7CisKKwlyZXR1cm4gTCIiOworfQorCit2b2lkIENQV0xfTGlzdEJveDo6U2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKQoreworCWlmIChtX3BMaXN0KQorCQltX3BMaXN0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOworfQorCitGWF9GTE9BVCBDUFdMX0xpc3RCb3g6OkdldEZvbnRTaXplKCkgY29uc3QKK3sKKwlpZiAobV9wTGlzdCkKKwkJcmV0dXJuIG1fcExpc3QtPkdldEZvbnRTaXplKCk7CisJcmV0dXJuIDAuMGY7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Qm94OjpTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlpZiAobV9wTGlzdCkKKwkJbV9wTGlzdC0+U2VsZWN0KG5JdGVtSW5kZXgpOworfQorCit2b2lkIENQV0xfTGlzdEJveDo6U2V0Q2FyZXQoRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlpZiAobV9wTGlzdCkKKwkJbV9wTGlzdC0+U2V0Q2FyZXQobkl0ZW1JbmRleCk7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Qm94OjpTZXRUb3BWaXNpYmxlSW5kZXgoRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlpZiAobV9wTGlzdCkKKwkJbV9wTGlzdC0+U2V0VG9wSXRlbShuSXRlbUluZGV4KTsKK30KKwordm9pZCBDUFdMX0xpc3RCb3g6OlNjcm9sbFRvTGlzdEl0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCkKK3sKKwlpZiAobV9wTGlzdCkKKwkJbV9wTGlzdC0+U2Nyb2xsVG9MaXN0SXRlbShuSXRlbUluZGV4KTsKK30KKwordm9pZCBDUFdMX0xpc3RCb3g6OlJlc2V0Q29udGVudCgpCit7CisJaWYgKG1fcExpc3QpCisJCW1fcExpc3QtPkVtcHR5KCk7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Qm94OjpSZXNldCgpCit7CisJaWYgKG1fcExpc3QpCisJCW1fcExpc3QtPkNhbmNlbCgpOworfQorCitGWF9CT09MIENQV0xfTGlzdEJveDo6SXNNdWx0aXBsZVNlbCgpIGNvbnN0Cit7CisJaWYgKG1fcExpc3QpCisJCXJldHVybiBtX3BMaXN0LT5Jc011bHRpcGxlU2VsKCk7CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0lOVDMyIENQV0xfTGlzdEJveDo6R2V0Q2FyZXRJbmRleCgpIGNvbnN0Cit7CisJaWYgKG1fcExpc3QpCisJCXJldHVybiBtX3BMaXN0LT5HZXRDYXJldCgpOworCisJcmV0dXJuIC0xOworfQorCitGWF9JTlQzMiBDUFdMX0xpc3RCb3g6OkdldEN1clNlbCgpIGNvbnN0Cit7CisJaWYgKG1fcExpc3QpCisJCXJldHVybiBtX3BMaXN0LT5HZXRTZWxlY3QoKTsKKworCXJldHVybiAtMTsKK30KKworRlhfQk9PTCBDUFdMX0xpc3RCb3g6OklzSXRlbVNlbGVjdGVkKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0Cit7CisJaWYgKG1fcExpc3QpCisJCXJldHVybiBtX3BMaXN0LT5Jc0l0ZW1TZWxlY3RlZChuSXRlbUluZGV4KTsKKworCXJldHVybiBGQUxTRTsKK30KKworRlhfSU5UMzIgQ1BXTF9MaXN0Qm94OjpHZXRUb3BWaXNpYmxlSW5kZXgoKSBjb25zdAoreworCWlmIChtX3BMaXN0KQorCXsKKwkJbV9wTGlzdC0+U2Nyb2xsVG9MaXN0SXRlbShtX3BMaXN0LT5HZXRGaXJzdFNlbGVjdGVkKCkpOworCQlyZXR1cm4gbV9wTGlzdC0+R2V0VG9wSXRlbSgpOworCX0KKworCXJldHVybiAtMTsKK30KKworRlhfSU5UMzIgQ1BXTF9MaXN0Qm94OjpHZXRDb3VudCgpIGNvbnN0Cit7CisJaWYgKG1fcExpc3QpCisJCXJldHVybiBtX3BMaXN0LT5HZXRDb3VudCgpOworCisJcmV0dXJuIDA7Cit9CisKK0ZYX0lOVDMyIENQV0xfTGlzdEJveDo6RmluZE5leHQoRlhfSU5UMzIgbkluZGV4LEZYX1dDSEFSIG5DaGFyKSBjb25zdAoreworCWlmIChtX3BMaXN0KQorCQlyZXR1cm4gbV9wTGlzdC0+RmluZE5leHQobkluZGV4LG5DaGFyKTsKKworCXJldHVybiBuSW5kZXg7Cit9CisKK0NQREZfUmVjdCBDUFdMX0xpc3RCb3g6OkdldENvbnRlbnRSZWN0KCkgY29uc3QKK3sKKwlpZiAobV9wTGlzdCkKKwkJcmV0dXJuIG1fcExpc3QtPkdldENvbnRlbnRSZWN0KCk7CisKKwlyZXR1cm4gQ1BERl9SZWN0KCk7Cit9CisKK0ZYX0ZMT0FUIENQV0xfTGlzdEJveDo6R2V0Rmlyc3RIZWlnaHQoKSBjb25zdAoreworCWlmIChtX3BMaXN0KQorCQlyZXR1cm4gbV9wTGlzdC0+R2V0Rmlyc3RIZWlnaHQoKTsKKworCXJldHVybiAwLjBmOworfQorCitDUERGX1JlY3QgQ1BXTF9MaXN0Qm94OjpHZXRMaXN0UmVjdCgpIGNvbnN0Cit7CisJcmV0dXJuIENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KEdldFdpbmRvd1JlY3QoKSwoRlhfRkxPQVQpKEdldEJvcmRlcldpZHRoKCkrR2V0SW5uZXJCb3JkZXJXaWR0aCgpKSk7Cit9CisKK0ZYX0JPT0wJQ1BXTF9MaXN0Qm94OjpPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmICghbV9wTGlzdCkgcmV0dXJuIEZBTFNFOworCisJaWYgKHpEZWx0YSA8IDApCisJeworCQltX3BMaXN0LT5PblZLX0RPV04oSXNTSElGVHByZXNzZWQobkZsYWcpLElzQ1RSTHByZXNzZWQobkZsYWcpKTsKKwl9CisJZWxzZQorCXsKKwkJbV9wTGlzdC0+T25WS19VUChJc1NISUZUcHJlc3NlZChuRmxhZyksSXNDVFJMcHJlc3NlZChuRmxhZykpOworCX0KKworCUZYX0JPT0wgYkV4aXQgPSBGQUxTRTsKKwlPbk5vdGlmeVNlbENoYW5nZWQoRkFMU0UsYkV4aXQsIG5GbGFnKTsKKwlyZXR1cm4gVFJVRTsKK30KKwpkaWZmIC0tZ2l0IGEvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9MaXN0Q3RybC5jcHAgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmNwcAppbmRleCA2MDNiYjRhLi45YWMxOGZkIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmNwcAorKysgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmNwcApAQCAtMSwyNDUgKzEsMjQ1IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0xpc3RDdHJsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0xpc3RDdHJsOjpDUFdMX0xpc3RDdHJsKCkgOiANCi0JbV9yY0NvbnRlbnQoMCwwLDAsMCksDQotCW1fcHRTY3JvbGwoMCwwKSwgDQotCW1fZkl0ZW1TcGFjZSgwLjBmKSwNCi0JbV9mVG9wU3BhY2UoMC4wZiksDQotCW1fZkJvdHRvbVNwYWNlKDAuMGYpDQotew0KLX0NCi0NCi1DUFdMX0xpc3RDdHJsOjp+Q1BXTF9MaXN0Q3RybCgpDQotew0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEN0cmw6OlNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50JiBwb2ludCkNCi17DQotCW1fcHRTY3JvbGwgPSBwb2ludDsNCi0NCi0JaWYgKG1fcHRTY3JvbGwueCA8IG1fcmNDb250ZW50LmxlZnQpDQotCQltX3B0U2Nyb2xsLnggPSBtX3JjQ29udGVudC5sZWZ0Ow0KLQ0KLQlpZiAobV9wdFNjcm9sbC54ID4gbV9yY0NvbnRlbnQucmlnaHQpDQotCQltX3B0U2Nyb2xsLnggPSBtX3JjQ29udGVudC5yaWdodDsNCi0NCi0JaWYgKG1fcHRTY3JvbGwueSA+IG1fcmNDb250ZW50LnRvcCkNCi0JCW1fcHRTY3JvbGwueSA9IG1fcmNDb250ZW50LnRvcDsNCi0NCi0JaWYgKG1fcHRTY3JvbGwueSA8IG1fcmNDb250ZW50LmJvdHRvbSkNCi0JCW1fcHRTY3JvbGwueSA9IG1fcmNDb250ZW50LmJvdHRvbTsJDQotfQ0KLQ0KLUNQREZfUG9pbnQgQ1BXTF9MaXN0Q3RybDo6R2V0U2Nyb2xsUG9zKCkgY29uc3QNCi17DQotCXJldHVybiBtX3B0U2Nyb2xsOw0KLX0NCi0NCi1DUERGX1JlY3QgQ1BXTF9MaXN0Q3RybDo6R2V0U2Nyb2xsQXJlYSgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9yY0NvbnRlbnQ7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MaXN0Q3RybDo6UmVzZXRGYWNlKCkNCi17DQotCVJlc2V0QWxsKEZBTFNFLCAwKTsNCi19DQotDQotdm9pZCBDUFdMX0xpc3RDdHJsOjpSZXNldENvbnRlbnQoRlhfSU5UMzIgblN0YXJ0KQ0KLXsNCi0JaWYgKG5TdGFydCA8IDApDQotCQluU3RhcnQgPSAwOw0KLQlpZiAoblN0YXJ0ID49IDAgJiYgblN0YXJ0IDwgbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpKQ0KLQkJUmVzZXRBbGwoVFJVRSwgblN0YXJ0KTsNCi19DQotDQotRlhfRkxPQVQgQ1BXTF9MaXN0Q3RybDo6R2V0Q29udGVudHNIZWlnaHQoRlhfRkxPQVQgZkxpbWl0V2lkdGgpDQotew0KLQlGWF9GTE9BVCBmUmV0ID0gbV9mVG9wU3BhY2U7DQotDQotCUZYX0ZMT0FUIGZCb3JkZXJXaWR0aCA9IChGWF9GTE9BVCl0aGlzLT5HZXRCb3JkZXJXaWR0aCgpOw0KLQ0KLQlpZiAoZkxpbWl0V2lkdGggPiBmQm9yZGVyV2lkdGgqIDIpDQotCXsNCi0JCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJew0KLQkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQkJew0KLQkJCQlGWF9GTE9BVCBmTGVmdCA9IHBDaGlsZC0+R2V0SXRlbUxlZnRNYXJnaW4oKTsNCi0JCQkJRlhfRkxPQVQgZlJpZ2h0ID0gcENoaWxkLT5HZXRJdGVtUmlnaHRNYXJnaW4oKTsNCi0NCi0JCQkJZlJldCArPSBwQ2hpbGQtPkdldEl0ZW1IZWlnaHQoZkxpbWl0V2lkdGggLSBmQm9yZGVyV2lkdGgqIDIgLSBmTGVmdCAtIGZSaWdodCk7DQotCQkJCWZSZXQgKz0gbV9mSXRlbVNwYWNlOw0KLQkJCX0NCi0JCX0NCi0NCi0JCWZSZXQgLT0gbV9mSXRlbVNwYWNlOw0KLQl9DQotDQotCWZSZXQgKz0gbV9mQm90dG9tU3BhY2U7DQotDQotCXJldHVybiBmUmV0Ow0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEN0cmw6OlJlc2V0QWxsKEZYX0JPT0wgYk1vdmUsIEZYX0lOVDMyIG5TdGFydCkNCi17DQotCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0NCi0JRlhfRkxPQVQgZldpZHRoID0gcmNDbGllbnQuV2lkdGgoKTsNCi0NCi0JRlhfRkxPQVQgZnkgPSAwLjBmIC0gbV9mVG9wU3BhY2U7DQotDQotCWlmIChuU3RhcnQtMSA+PSAwICYmIG5TdGFydC0xIDwgbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpKQ0KLQkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChuU3RhcnQtMSkpDQotCQkJZnkgPSBwQ2hpbGQtPkdldFdpbmRvd1JlY3QoKS5ib3R0b20gLSBtX2ZJdGVtU3BhY2U7DQotDQotCWZvciAoRlhfSU5UMzIgaT1uU3RhcnQsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQl7DQotCQkJRlhfRkxPQVQgZkxlZnQgPSBwQ2hpbGQtPkdldEl0ZW1MZWZ0TWFyZ2luKCk7DQotCQkJRlhfRkxPQVQgZlJpZ2h0ID0gcENoaWxkLT5HZXRJdGVtUmlnaHRNYXJnaW4oKTsNCi0NCi0JCQlwQ2hpbGQtPlNldENoaWxkTWF0cml4KA0KLQkJCQlDUERGX01hdHJpeCgxLDAsMCwxLCANCi0JCQkJcmNDbGllbnQubGVmdCAtIG1fcHRTY3JvbGwueCwgDQotCQkJCXJjQ2xpZW50LnRvcCAtIG1fcHRTY3JvbGwueSkNCi0JCQkJKTsNCi0NCi0JCQlpZiAoYk1vdmUpDQotCQkJew0KLQkJCQlGWF9GTE9BVCBmSXRlbUhlaWdodCA9IHBDaGlsZC0+R2V0SXRlbUhlaWdodChmV2lkdGggLSBmTGVmdCAtIGZSaWdodCk7DQotCQkJCXBDaGlsZC0+TW92ZShDUERGX1JlY3QoZkxlZnQsIGZ5LWZJdGVtSGVpZ2h0LCBmV2lkdGggLSBmUmlnaHQsIGZ5KSwgVFJVRSwgRkFMU0UpOw0KLQkJCQlmeSAtPSBmSXRlbUhlaWdodDsNCi0JCQkJZnkgLT0gbV9mSXRlbVNwYWNlOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlmeSArPSBtX2ZJdGVtU3BhY2U7DQotDQotCWZ5IC09IG1fZkJvdHRvbVNwYWNlOw0KLQ0KLQlpZiAoYk1vdmUpDQotCXsNCi0JCW1fcmNDb250ZW50LmxlZnQgPSAwOw0KLQkJbV9yY0NvbnRlbnQudG9wID0gMDsNCi0JCW1fcmNDb250ZW50LnJpZ2h0ID0gZldpZHRoOw0KLQkJbV9yY0NvbnRlbnQuYm90dG9tID0gZnk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX0xpc3RDdHJsOjpTZXRJdGVtU3BhY2UoRlhfRkxPQVQgZlNwYWNlKQ0KLXsNCi0JbV9mSXRlbVNwYWNlID0gZlNwYWNlOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEN0cmw6OlNldFRvcFNwYWNlKEZYX0ZMT0FUIGZTcGFjZSkNCi17DQotCW1fZlRvcFNwYWNlID0gZlNwYWNlOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEN0cmw6OlNldEJvdHRvbVNwYWNlKEZYX0ZMT0FUIGZTcGFjZSkNCi17DQotCW1fZkJvdHRvbVNwYWNlID0gZlNwYWNlOw0KLX0NCi0NCi12b2lkIENQV0xfTGlzdEN0cmw6OlJlUG9zQ2hpbGRXbmQoKQ0KLXsNCi0JUmVzZXRGYWNlKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9MaXN0Q3RybDo6RHJhd0NoaWxkQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0KLXsNCi0JcERldmljZS0+U2F2ZVN0YXRlKCk7DQotCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0JQ1BERl9SZWN0IHJjVGVtcCA9IHJjQ2xpZW50Ow0KLQlwVXNlcjJEZXZpY2UtPlRyYW5zZm9ybVJlY3QocmNUZW1wKTsNCi0JRlhfUkVDVCByY0NsaXAoKEZYX0lOVDMyKXJjVGVtcC5sZWZ0LA0KLQkJKEZYX0lOVDMyKXJjVGVtcC5ib3R0b20sDQotCQkoRlhfSU5UMzIpcmNUZW1wLnJpZ2h0LA0KLQkJKEZYX0lOVDMyKXJjVGVtcC50b3ApOw0KLQ0KLQlwRGV2aWNlLT5TZXRDbGlwX1JlY3QoJnJjQ2xpcCk7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkNCi0JCXsNCi0JCQlDUERGX1JlY3QgcmNDaGlsZCA9IHBDaGlsZC0+Q2hpbGRUb1BhcmVudChwQ2hpbGQtPkdldFdpbmRvd1JlY3QoKSk7DQotCQkJaWYgKCEocmNDaGlsZC50b3AgPCByY0NsaWVudC5ib3R0b20gfHwgcmNDaGlsZC5ib3R0b20gPiByY0NsaWVudC50b3ApKQ0KLQkJCXsNCi0JCQkJQ1BERl9NYXRyaXggbXQgPSBwQ2hpbGQtPkdldENoaWxkTWF0cml4KCk7DQotCQkJCWlmIChtdC5Jc0lkZW50aXR5KCkpDQotCQkJCXsNCi0JCQkJCXBDaGlsZC0+RHJhd0FwcGVhcmFuY2UocERldmljZSxwVXNlcjJEZXZpY2UpOw0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJbXQuQ29uY2F0KCpwVXNlcjJEZXZpY2UpOw0KLQkJCQkJcENoaWxkLT5EcmF3QXBwZWFyYW5jZShwRGV2aWNlLCZtdCk7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0JDQotCXBEZXZpY2UtPlJlc3RvcmVTdGF0ZSgpOw0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX0xpc3RDdHJsOjpHZXRJdGVtSW5kZXgoQ1BXTF9XbmQqIHBJdGVtKQ0KLXsNCi0JZm9yIChGWF9JTlQzMiBpPTAsIHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAocEl0ZW0gPT0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQkJcmV0dXJuIGk7DQotCX0NCi0NCi0JcmV0dXJuIC0xOw0KLX0NCi0NCi1DUERGX1BvaW50IENQV0xfTGlzdEN0cmw6OkluVG9PdXQoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0DQotew0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotDQotCXJldHVybiBDUERGX1BvaW50KHBvaW50LnggKyByY0NsaWVudC5sZWZ0IC0gbV9wdFNjcm9sbC54LCANCi0JCXBvaW50LnkgKyByY0NsaWVudC50b3AgLSBtX3B0U2Nyb2xsLnkpOw0KLX0NCi0NCi1DUERGX1BvaW50IENQV0xfTGlzdEN0cmw6Ok91dFRvSW4oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0DQotew0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotDQotCXJldHVybiBDUERGX1BvaW50KHBvaW50LnggLSByY0NsaWVudC5sZWZ0ICsgbV9wdFNjcm9sbC54LCANCi0JCXBvaW50LnkgLSByY0NsaWVudC50b3AgKyBtX3B0U2Nyb2xsLnkpOw0KLX0NCi0NCi1DUERGX1JlY3QgQ1BXTF9MaXN0Q3RybDo6SW5Ub091dChjb25zdCBDUERGX1JlY3QmIHJlY3QpIGNvbnN0DQotew0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotDQotCXJldHVybiBDUERGX1JlY3QocmVjdC5sZWZ0ICsgcmNDbGllbnQubGVmdCAtIG1fcHRTY3JvbGwueCwNCi0JCXJlY3QuYm90dG9tICsgcmNDbGllbnQudG9wIC0gbV9wdFNjcm9sbC55LA0KLQkJcmVjdC5yaWdodCArIHJjQ2xpZW50LmxlZnQgLSBtX3B0U2Nyb2xsLngsDQotCQlyZWN0LnRvcCArIHJjQ2xpZW50LnRvcCAtIG1fcHRTY3JvbGwueSk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX0xpc3RDdHJsOjpPdXRUb0luKGNvbnN0IENQREZfUmVjdCYgcmVjdCkgY29uc3QNCi17DQotCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0NCi0JcmV0dXJuIENQREZfUmVjdChyZWN0LmxlZnQgLSByY0NsaWVudC5sZWZ0ICsgbV9wdFNjcm9sbC54LA0KLQkJcmVjdC5ib3R0b20gLSByY0NsaWVudC50b3AgKyBtX3B0U2Nyb2xsLnksDQotCQlyZWN0LnJpZ2h0IC0gcmNDbGllbnQubGVmdCArIG1fcHRTY3JvbGwueCwNCi0JCXJlY3QudG9wIC0gcmNDbGllbnQudG9wICsgbV9wdFNjcm9sbC55KTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEN0cmwuaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0xpc3RDdHJsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ1BXTF9MaXN0Q3RybDo6Q1BXTF9MaXN0Q3RybCgpIDogCisJbV9yY0NvbnRlbnQoMCwwLDAsMCksCisJbV9wdFNjcm9sbCgwLDApLCAKKwltX2ZJdGVtU3BhY2UoMC4wZiksCisJbV9mVG9wU3BhY2UoMC4wZiksCisJbV9mQm90dG9tU3BhY2UoMC4wZikKK3sKK30KKworQ1BXTF9MaXN0Q3RybDo6fkNQV0xfTGlzdEN0cmwoKQoreworfQorCit2b2lkIENQV0xfTGlzdEN0cmw6OlNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwltX3B0U2Nyb2xsID0gcG9pbnQ7CisKKwlpZiAobV9wdFNjcm9sbC54IDwgbV9yY0NvbnRlbnQubGVmdCkKKwkJbV9wdFNjcm9sbC54ID0gbV9yY0NvbnRlbnQubGVmdDsKKworCWlmIChtX3B0U2Nyb2xsLnggPiBtX3JjQ29udGVudC5yaWdodCkKKwkJbV9wdFNjcm9sbC54ID0gbV9yY0NvbnRlbnQucmlnaHQ7CisKKwlpZiAobV9wdFNjcm9sbC55ID4gbV9yY0NvbnRlbnQudG9wKQorCQltX3B0U2Nyb2xsLnkgPSBtX3JjQ29udGVudC50b3A7CisKKwlpZiAobV9wdFNjcm9sbC55IDwgbV9yY0NvbnRlbnQuYm90dG9tKQorCQltX3B0U2Nyb2xsLnkgPSBtX3JjQ29udGVudC5ib3R0b207CQorfQorCitDUERGX1BvaW50IENQV0xfTGlzdEN0cmw6OkdldFNjcm9sbFBvcygpIGNvbnN0Cit7CisJcmV0dXJuIG1fcHRTY3JvbGw7Cit9CisKK0NQREZfUmVjdCBDUFdMX0xpc3RDdHJsOjpHZXRTY3JvbGxBcmVhKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9yY0NvbnRlbnQ7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Q3RybDo6UmVzZXRGYWNlKCkKK3sKKwlSZXNldEFsbChGQUxTRSwgMCk7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Q3RybDo6UmVzZXRDb250ZW50KEZYX0lOVDMyIG5TdGFydCkKK3sKKwlpZiAoblN0YXJ0IDwgMCkKKwkJblN0YXJ0ID0gMDsKKwlpZiAoblN0YXJ0ID49IDAgJiYgblN0YXJ0IDwgbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpKQorCQlSZXNldEFsbChUUlVFLCBuU3RhcnQpOworfQorCitGWF9GTE9BVCBDUFdMX0xpc3RDdHJsOjpHZXRDb250ZW50c0hlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkKK3sKKwlGWF9GTE9BVCBmUmV0ID0gbV9mVG9wU3BhY2U7CisKKwlGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpdGhpcy0+R2V0Qm9yZGVyV2lkdGgoKTsKKworCWlmIChmTGltaXRXaWR0aCA+IGZCb3JkZXJXaWR0aCogMikKKwl7CisJCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQorCQl7CisJCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQorCQkJeworCQkJCUZYX0ZMT0FUIGZMZWZ0ID0gcENoaWxkLT5HZXRJdGVtTGVmdE1hcmdpbigpOworCQkJCUZYX0ZMT0FUIGZSaWdodCA9IHBDaGlsZC0+R2V0SXRlbVJpZ2h0TWFyZ2luKCk7CisKKwkJCQlmUmV0ICs9IHBDaGlsZC0+R2V0SXRlbUhlaWdodChmTGltaXRXaWR0aCAtIGZCb3JkZXJXaWR0aCogMiAtIGZMZWZ0IC0gZlJpZ2h0KTsKKwkJCQlmUmV0ICs9IG1fZkl0ZW1TcGFjZTsKKwkJCX0KKwkJfQorCisJCWZSZXQgLT0gbV9mSXRlbVNwYWNlOworCX0KKworCWZSZXQgKz0gbV9mQm90dG9tU3BhY2U7CisKKwlyZXR1cm4gZlJldDsKK30KKwordm9pZCBDUFdMX0xpc3RDdHJsOjpSZXNldEFsbChGWF9CT09MIGJNb3ZlLCBGWF9JTlQzMiBuU3RhcnQpCit7CisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOworCisJRlhfRkxPQVQgZldpZHRoID0gcmNDbGllbnQuV2lkdGgoKTsKKworCUZYX0ZMT0FUIGZ5ID0gMC4wZiAtIG1fZlRvcFNwYWNlOworCisJaWYgKG5TdGFydC0xID49IDAgJiYgblN0YXJ0LTEgPCBtX2FDaGlsZHJlbi5HZXRTaXplKCkpCisJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoblN0YXJ0LTEpKQorCQkJZnkgPSBwQ2hpbGQtPkdldFdpbmRvd1JlY3QoKS5ib3R0b20gLSBtX2ZJdGVtU3BhY2U7CisKKwlmb3IgKEZYX0lOVDMyIGk9blN0YXJ0LHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKKwkJeworCQkJRlhfRkxPQVQgZkxlZnQgPSBwQ2hpbGQtPkdldEl0ZW1MZWZ0TWFyZ2luKCk7CisJCQlGWF9GTE9BVCBmUmlnaHQgPSBwQ2hpbGQtPkdldEl0ZW1SaWdodE1hcmdpbigpOworCisJCQlwQ2hpbGQtPlNldENoaWxkTWF0cml4KAorCQkJCUNQREZfTWF0cml4KDEsMCwwLDEsIAorCQkJCXJjQ2xpZW50LmxlZnQgLSBtX3B0U2Nyb2xsLngsIAorCQkJCXJjQ2xpZW50LnRvcCAtIG1fcHRTY3JvbGwueSkKKwkJCQkpOworCisJCQlpZiAoYk1vdmUpCisJCQl7CisJCQkJRlhfRkxPQVQgZkl0ZW1IZWlnaHQgPSBwQ2hpbGQtPkdldEl0ZW1IZWlnaHQoZldpZHRoIC0gZkxlZnQgLSBmUmlnaHQpOworCQkJCXBDaGlsZC0+TW92ZShDUERGX1JlY3QoZkxlZnQsIGZ5LWZJdGVtSGVpZ2h0LCBmV2lkdGggLSBmUmlnaHQsIGZ5KSwgVFJVRSwgRkFMU0UpOworCQkJCWZ5IC09IGZJdGVtSGVpZ2h0OworCQkJCWZ5IC09IG1fZkl0ZW1TcGFjZTsKKwkJCX0KKwkJfQorCX0KKworCWZ5ICs9IG1fZkl0ZW1TcGFjZTsKKworCWZ5IC09IG1fZkJvdHRvbVNwYWNlOworCisJaWYgKGJNb3ZlKQorCXsKKwkJbV9yY0NvbnRlbnQubGVmdCA9IDA7CisJCW1fcmNDb250ZW50LnRvcCA9IDA7CisJCW1fcmNDb250ZW50LnJpZ2h0ID0gZldpZHRoOworCQltX3JjQ29udGVudC5ib3R0b20gPSBmeTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Q3RybDo6U2V0SXRlbVNwYWNlKEZYX0ZMT0FUIGZTcGFjZSkKK3sKKwltX2ZJdGVtU3BhY2UgPSBmU3BhY2U7Cit9CisKK3ZvaWQgQ1BXTF9MaXN0Q3RybDo6U2V0VG9wU3BhY2UoRlhfRkxPQVQgZlNwYWNlKQoreworCW1fZlRvcFNwYWNlID0gZlNwYWNlOworfQorCit2b2lkIENQV0xfTGlzdEN0cmw6OlNldEJvdHRvbVNwYWNlKEZYX0ZMT0FUIGZTcGFjZSkKK3sKKwltX2ZCb3R0b21TcGFjZSA9IGZTcGFjZTsKK30KKwordm9pZCBDUFdMX0xpc3RDdHJsOjpSZVBvc0NoaWxkV25kKCkKK3sKKwlSZXNldEZhY2UoKTsKK30KKwordm9pZCBDUFdMX0xpc3RDdHJsOjpEcmF3Q2hpbGRBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpCit7CisJcERldmljZS0+U2F2ZVN0YXRlKCk7CisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOworCUNQREZfUmVjdCByY1RlbXAgPSByY0NsaWVudDsKKwlwVXNlcjJEZXZpY2UtPlRyYW5zZm9ybVJlY3QocmNUZW1wKTsKKwlGWF9SRUNUIHJjQ2xpcCgoRlhfSU5UMzIpcmNUZW1wLmxlZnQsCisJCShGWF9JTlQzMilyY1RlbXAuYm90dG9tLAorCQkoRlhfSU5UMzIpcmNUZW1wLnJpZ2h0LAorCQkoRlhfSU5UMzIpcmNUZW1wLnRvcCk7CisKKwlwRGV2aWNlLT5TZXRDbGlwX1JlY3QoJnJjQ2xpcCk7CisKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQorCQl7CisJCQlDUERGX1JlY3QgcmNDaGlsZCA9IHBDaGlsZC0+Q2hpbGRUb1BhcmVudChwQ2hpbGQtPkdldFdpbmRvd1JlY3QoKSk7CisJCQlpZiAoIShyY0NoaWxkLnRvcCA8IHJjQ2xpZW50LmJvdHRvbSB8fCByY0NoaWxkLmJvdHRvbSA+IHJjQ2xpZW50LnRvcCkpCisJCQl7CisJCQkJQ1BERl9NYXRyaXggbXQgPSBwQ2hpbGQtPkdldENoaWxkTWF0cml4KCk7CisJCQkJaWYgKG10LklzSWRlbnRpdHkoKSkKKwkJCQl7CisJCQkJCXBDaGlsZC0+RHJhd0FwcGVhcmFuY2UocERldmljZSxwVXNlcjJEZXZpY2UpOworCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQltdC5Db25jYXQoKnBVc2VyMkRldmljZSk7CisJCQkJCXBDaGlsZC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwmbXQpOworCQkJCX0KKwkJCX0KKwkJfQorCX0KKwkKKwlwRGV2aWNlLT5SZXN0b3JlU3RhdGUoKTsKK30KKworRlhfSU5UMzIgQ1BXTF9MaXN0Q3RybDo6R2V0SXRlbUluZGV4KENQV0xfV25kKiBwSXRlbSkKK3sKKwlmb3IgKEZYX0lOVDMyIGk9MCwgc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlpZiAocEl0ZW0gPT0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpCisJCQlyZXR1cm4gaTsKKwl9CisKKwlyZXR1cm4gLTE7Cit9CisKK0NQREZfUG9pbnQgQ1BXTF9MaXN0Q3RybDo6SW5Ub091dChjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3QKK3sKKwlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisKKwlyZXR1cm4gQ1BERl9Qb2ludChwb2ludC54ICsgcmNDbGllbnQubGVmdCAtIG1fcHRTY3JvbGwueCwgCisJCXBvaW50LnkgKyByY0NsaWVudC50b3AgLSBtX3B0U2Nyb2xsLnkpOworfQorCitDUERGX1BvaW50IENQV0xfTGlzdEN0cmw6Ok91dFRvSW4oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0Cit7CisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOworCisJcmV0dXJuIENQREZfUG9pbnQocG9pbnQueCAtIHJjQ2xpZW50LmxlZnQgKyBtX3B0U2Nyb2xsLngsIAorCQlwb2ludC55IC0gcmNDbGllbnQudG9wICsgbV9wdFNjcm9sbC55KTsKK30KKworQ1BERl9SZWN0IENQV0xfTGlzdEN0cmw6OkluVG9PdXQoY29uc3QgQ1BERl9SZWN0JiByZWN0KSBjb25zdAoreworCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKworCXJldHVybiBDUERGX1JlY3QocmVjdC5sZWZ0ICsgcmNDbGllbnQubGVmdCAtIG1fcHRTY3JvbGwueCwKKwkJcmVjdC5ib3R0b20gKyByY0NsaWVudC50b3AgLSBtX3B0U2Nyb2xsLnksCisJCXJlY3QucmlnaHQgKyByY0NsaWVudC5sZWZ0IC0gbV9wdFNjcm9sbC54LAorCQlyZWN0LnRvcCArIHJjQ2xpZW50LnRvcCAtIG1fcHRTY3JvbGwueSk7Cit9CisKK0NQREZfUmVjdCBDUFdMX0xpc3RDdHJsOjpPdXRUb0luKGNvbnN0IENQREZfUmVjdCYgcmVjdCkgY29uc3QKK3sKKwlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisKKwlyZXR1cm4gQ1BERl9SZWN0KHJlY3QubGVmdCAtIHJjQ2xpZW50LmxlZnQgKyBtX3B0U2Nyb2xsLngsCisJCXJlY3QuYm90dG9tIC0gcmNDbGllbnQudG9wICsgbV9wdFNjcm9sbC55LAorCQlyZWN0LnJpZ2h0IC0gcmNDbGllbnQubGVmdCArIG1fcHRTY3JvbGwueCwKKwkJcmVjdC50b3AgLSByY0NsaWVudC50b3AgKyBtX3B0U2Nyb2xsLnkpOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX05vdGUuY3BwIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9Ob3RlLmNwcAppbmRleCAzYzZkODY2Li41OTI5YTM1IDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX05vdGUuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfTm90ZS5jcHAKQEAgLTEsMTc3OSArMSwxNzc5IEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TY3JvbGxCYXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX05vdGUuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xhYmVsLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9FZGl0LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TY3JvbGxCYXIuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1V0aWxzLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9DYXJldC5oIg0KLQ0KLSNkZWZpbmUgUE9QVVBfSVRFTV9IRUFEX0JPVFRPTQkJCQkJMy4wZg0KLSNkZWZpbmUgUE9QVVBfSVRFTV9CT1RUT01XSURUSAkJCQkJMS4wZg0KLSNkZWZpbmUgUE9QVVBfSVRFTV9TSURFTUFSR0lOCQkJCQkzLjBmDQotI2RlZmluZSBQT1BVUF9JVEVNX1NQQUNFCQkJCQkJNC4wZg0KLSNkZWZpbmUgUE9QVVBfSVRFTV9URVhUX0lOREVOVAkJCQkJMi4wZg0KLSNkZWZpbmUgUE9QVVBfSVRFTV9CT1JERVJDT0xPUgkJCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLCA4MC8yNTUuMGYsIDgwLzI1NS4wZiwgODAvMjU1LjBmKQ0KLQ0KLSNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpDQotI2RlZmluZSBJc0Zsb2F0QmlnZ2VyKGZhLGZiKQkJCQkoKGZhKSA+IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCi0jZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLGZiKQkJCQkoKGZhKSA8IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCi0jZGVmaW5lIElzRmxvYXRFcXVhbChmYSxmYikJCQkJCUlzRmxvYXRaZXJvKChmYSktKGZiKSkNCi0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9PcHRpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX05vdGVfT3B0aW9uczo6Q1BXTF9Ob3RlX09wdGlvbnMoKSA6IG1fcFRleHQoTlVMTCkNCi17DQotfQ0KLQ0KLUNQV0xfTm90ZV9PcHRpb25zOjp+Q1BXTF9Ob3RlX09wdGlvbnMoKQ0KLXsNCi19DQotDQotdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6U2V0VGV4dENvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcikNCi17DQotCUNQV0xfV25kOjpTZXRUZXh0Q29sb3IoY29sb3IpOw0KLQ0KLQlpZiAobV9wVGV4dCkNCi0JCW1fcFRleHQtPlNldFRleHRDb2xvcihjb2xvcik7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX09wdGlvbnM6OlJlUG9zQ2hpbGRXbmQoKQ0KLXsNCi0JaWYgKHRoaXMtPklzVmFsaWQoKSkNCi0Jew0KLQkJQVNTRVJUKG1fcFRleHQgIT0gTlVMTCk7DQotDQotCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotDQotCQlpZiAocmNDbGllbnQuV2lkdGgoKSA+IDE1LjBmKQ0KLQkJew0KLQkJCXJjQ2xpZW50LnJpZ2h0IC09IDE1LjBmOw0KLQkJCW1fcFRleHQtPk1vdmUocmNDbGllbnQsIFRSVUUsIEZBTFNFKTsNCi0JCQltX3BUZXh0LT5TZXRWaXNpYmxlKFRSVUUpOw0KLQkJfQ0KLQkJZWxzZQ0KLQkJew0KLQkJCW1fcFRleHQtPk1vdmUoQ1BERl9SZWN0KDAsMCwwLDApLCBUUlVFLCBGQUxTRSk7DQotCQkJbV9wVGV4dC0+U2V0VmlzaWJsZShGQUxTRSk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLQltX3BUZXh0ID0gbmV3IENQV0xfTGFiZWw7DQotCVBXTF9DUkVBVEVQQVJBTSB0Y3AgPSBjcDsNCi0JdGNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQl0Y3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOw0KLQltX3BUZXh0LT5DcmVhdGUodGNwKTsNCi19DQotDQotdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6U2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpDQotew0KLQltX3BUZXh0LT5TZXRUZXh0KHNUZXh0KTsNCi19DQotDQotdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpDQotew0KLQlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7DQotDQotCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0JcmNDbGllbnQubGVmdCA9IHJjQ2xpZW50LnJpZ2h0IC0gMTUuMGY7DQotDQotCUNQREZfUG9pbnQgcHRDZW50ZXIgPSBDUERGX1BvaW50KChyY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQucmlnaHQpICogMC41ZiwgKHJjQ2xpZW50LnRvcCArIHJjQ2xpZW50LmJvdHRvbSkgKiAwLjVmKTsNCi0NCi0JQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCAtIDIuMGYsIHB0Q2VudGVyLnkgKyAyLjBmICogMC41Zik7DQotCUNQREZfUG9pbnQgcHQyKHB0Q2VudGVyLnggKyAyLjBmLCBwdENlbnRlci55ICsgMi4wZiAqIDAuNWYpOw0KLQlDUERGX1BvaW50IHB0MyhwdENlbnRlci54LCBwdENlbnRlci55IC0gMy4wZiAqIDAuNWYpOw0KLQ0KLQlDRlhfUGF0aERhdGEgcGF0aDsNCi0NCi0JcGF0aC5TZXRQb2ludENvdW50KDQpOw0KLQlwYXRoLlNldFBvaW50KDAsIHB0MS54LCBwdDEueSwgRlhQVF9NT1ZFVE8pOw0KLQlwYXRoLlNldFBvaW50KDEsIHB0Mi54LCBwdDIueSwgRlhQVF9MSU5FVE8pOw0KLQlwYXRoLlNldFBvaW50KDIsIHB0My54LCBwdDMueSwgRlhQVF9MSU5FVE8pOw0KLQlwYXRoLlNldFBvaW50KDMsIHB0MS54LCBwdDEueSwgRlhQVF9MSU5FVE8pOw0KLQ0KLQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCANCi0JCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLEdldFRyYW5zcGFyZW5jeSgpKSwgDQotCQkwLCBGWEZJTExfQUxURVJOQVRFKTsNCi19DQotDQotQ1BERl9SZWN0IENQV0xfTm90ZV9PcHRpb25zOjpHZXRDb250ZW50UmVjdCgpIGNvbnN0DQotew0KLQlBU1NFUlQobV9wVGV4dCAhPSBOVUxMKTsNCi0NCi0JQ1BERl9SZWN0IHJjVGV4dCA9IG1fcFRleHQtPkdldENvbnRlbnRSZWN0KCk7DQotCXJjVGV4dC5yaWdodCArPSAxNS4wZjsNCi0JcmV0dXJuIHJjVGV4dDsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfRWRpdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX05vdGVfRWRpdDo6Q1BXTF9Ob3RlX0VkaXQoKSA6IG1fYkVuYWJsZU5vdGlmeShUUlVFKSwNCi0JbV9mT2xkSXRlbUhlaWdodCgwLjBmKSwNCi0JbV9iU2l6ZUNoYW5nZWQoRkFMU0UpLA0KLQltX2ZPbGRNaW4oMC4wZiksDQotCW1fZk9sZE1heCgwLjBmKQ0KLXsNCi19DQotDQotQ1BXTF9Ob3RlX0VkaXQ6On5DUFdMX05vdGVfRWRpdCgpDQotew0KLX0NCi0NCi12b2lkIENQV0xfTm90ZV9FZGl0OjpSZVBvc0NoaWxkV25kKCkNCi17DQotCW1fYkVuYWJsZU5vdGlmeSA9IEZBTFNFOwkNCi0JQ1BXTF9FZGl0OjpSZVBvc0NoaWxkV25kKCk7DQotCW1fYkVuYWJsZU5vdGlmeSA9IFRSVUU7DQotDQotCW1fZk9sZEl0ZW1IZWlnaHQgPSB0aGlzLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZV9FZGl0OjpTZXRUZXh0KEZYX0xQQ1dTVFIgY3NUZXh0KQ0KLXsNCi0JbV9iRW5hYmxlTm90aWZ5ID0gRkFMU0U7DQotCUNQV0xfRWRpdDo6U2V0VGV4dChjc1RleHQpOw0KLQltX2JFbmFibGVOb3RpZnkgPSBUUlVFOwkNCi0JbV9mT2xkSXRlbUhlaWdodCA9IHRoaXMtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uU2V0Rm9jdXMoKQ0KLXsNCi0JbV9iRW5hYmxlTm90aWZ5ID0gRkFMU0U7CQ0KLQlDUFdMX0VkaXQ6Ok9uU2V0Rm9jdXMoKTsNCi0JbV9iRW5hYmxlTm90aWZ5ID0gVFJVRTsJDQotDQotCXRoaXMtPkVuYWJsZVNwZWxsQ2hlY2soVFJVRSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uS2lsbEZvY3VzKCkNCi17DQotCXRoaXMtPkVuYWJsZVNwZWxsQ2hlY2soRkFMU0UpOw0KLQ0KLQlpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkNCi0Jew0KLQkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkNCi0JCXsNCi0JCQlBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOw0KLQ0KLQkJCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwR3JhbmQ7DQotDQotCQkJcE5vdGVJdGVtLT5PbkNvbnRlbnRzVmFsaWRhdGUoKTsNCi0JCX0NCi0JfQ0KLQ0KLQlDUFdMX0VkaXQ6Ok9uS2lsbEZvY3VzKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pDQotew0KLQlpZiAobV9iRW5hYmxlTm90aWZ5KQ0KLQl7DQotCQlpZiAod1BhcmFtID09IFNCVF9WU0NST0xMKQ0KLQkJew0KLQkJCXN3aXRjaCAobXNnKQ0KLQkJCXsNCi0JCQljYXNlIFBOTV9TRVRTQ1JPTExJTkZPOgkNCi0JCQkJaWYgKFBXTF9TQ1JPTExfSU5GTyogcEluZm8gPSAoUFdMX1NDUk9MTF9JTkZPKilsUGFyYW0pDQotCQkJCXsJDQotCQkJCQlpZiAoIUlzRmxvYXRFcXVhbChwSW5mby0+ZkNvbnRlbnRNYXgsIG1fZk9sZE1heCkgfHwgDQotCQkJCQkJIUlzRmxvYXRFcXVhbChwSW5mby0+ZkNvbnRlbnRNaW4sIG1fZk9sZE1pbikpDQotCQkJCQl7DQotCQkJCQkJbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwkJCQkNCi0JCQkJCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQotCQkJCQkJew0KLQkJCQkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsNCi0JCQkJCQl9DQotDQotCQkJCQkJbV9mT2xkTWF4ID0gcEluZm8tPmZDb250ZW50TWF4Ow0KLQkJCQkJCW1fZk9sZE1pbiA9IHBJbmZvLT5mQ29udGVudE1pbjsNCi0JCQkJCQlyZXR1cm47DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9CQkNCi0JfQ0KLQ0KLQlDUFdMX0VkaXQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOw0KLQ0KLQlpZiAobV9iRW5hYmxlTm90aWZ5KQ0KLQl7DQotCQlzd2l0Y2ggKG1zZykNCi0JCXsNCi0JCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoNCi0JCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQ0KLQkJCXsNCi0JCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsNCi0JCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7DQotCQkJCW5ld0luZm8ucHRIZWFkID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRIZWFkKTsNCi0JCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOw0KLQ0KLQkJCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQotCQkJCXsNCi0JCQkJCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRDQVJFVElORk8sIChGWF9JTlRQVFIpJm5ld0luZm8sIDApOw0KLQkJCQl9DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLUZYX0ZMT0FUIENQV0xfTm90ZV9FZGl0OjpHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKQ0KLXsNCi0JaWYgKGZMaW1pdFdpZHRoID4gMCkNCi0Jew0KLQkJaWYgKCFtX2JTaXplQ2hhbmdlZCkNCi0JCQlyZXR1cm4gbV9mT2xkSXRlbUhlaWdodDsNCi0NCi0JCW1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CQ0KLQ0KLQkJdGhpcy0+RW5hYmxlTm90aWZ5KEZBTFNFKTsNCi0JCXRoaXMtPkVuYWJsZVJlZnJlc2goRkFMU0UpOw0KLQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsNCi0NCi0JCS8vQ1BERl9SZWN0IHJjT2xkID0gdGhpcy0+R2V0V2luZG93UmVjdCgpOw0KLQ0KLQkJdGhpcy0+TW92ZShDUERGX1JlY3QoMCwwLGZMaW1pdFdpZHRoLDApLCBUUlVFLCBGQUxTRSk7DQotCQlGWF9GTE9BVCBmUmV0ID0gdGhpcy0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsNCi0NCi0JCS8vdGhpcy0+TW92ZShyY09sZCwgVFJVRSwgRkFMU0UpOw0KLQ0KLQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOw0KLQkJdGhpcy0+RW5hYmxlTm90aWZ5KFRSVUUpOw0KLQkJdGhpcy0+RW5hYmxlUmVmcmVzaChUUlVFKTsNCi0NCi0JCXJldHVybiBmUmV0Ow0KLQl9DQotDQotCXJldHVybiAwOw0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbUxlZnRNYXJnaW4oKQ0KLXsNCi0JcmV0dXJuIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7DQotfQ0KLQ0KLUZYX0ZMT0FUIENQV0xfTm90ZV9FZGl0OjpHZXRJdGVtUmlnaHRNYXJnaW4oKQ0KLXsNCi0JcmV0dXJuIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9MQkJveCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQotDQotQ1BXTF9Ob3RlX0xCQm94OjpDUFdMX05vdGVfTEJCb3goKQ0KLXsNCi19DQotDQotQ1BXTF9Ob3RlX0xCQm94Ojp+Q1BXTF9Ob3RlX0xCQm94KCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0xCQm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkNCi17DQotCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsNCi0NCi0JQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JZ3NkLm1fTGluZVdpZHRoID0gMS4wZjsNCi0NCi0JQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsNCi0NCi0JcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7DQotCXBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsNCi0JcGF0aENyb3NzLlNldFBvaW50KDEsIHJjQ2xpZW50LnJpZ2h0LCByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsNCi0JcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSArIHJjQ2xpZW50LkhlaWdodCgpICogMC41ZiwgRlhQVF9NT1ZFVE8pOw0KLQlwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQubGVmdCArIHJjQ2xpZW50LldpZHRoKCkgKiAwLjVmLCByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsNCi0JDQotCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoQ3Jvc3MsIHBVc2VyMkRldmljZSwgJmdzZCwgDQotCQkwLCBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSx0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSksIEZYRklMTF9BTFRFUk5BVEUpOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfUkJCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KLQ0KLUNQV0xfTm90ZV9SQkJveDo6Q1BXTF9Ob3RlX1JCQm94KCkNCi17DQotfQ0KLQ0KLUNQV0xfTm90ZV9SQkJveDo6fkNQV0xfTm90ZV9SQkJveCgpDQotew0KLX0NCi0NCi12b2lkIENQV0xfTm90ZV9SQkJveDo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpDQotew0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7DQotDQotCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7DQotCWdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7DQotDQotCUNGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7DQotDQotCXBhdGhDcm9zcy5TZXRQb2ludENvdW50KDQpOw0KLQlwYXRoQ3Jvc3MuU2V0UG9pbnQoMCwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LnRvcCwgRlhQVF9NT1ZFVE8pOw0KLQlwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7DQotCXBhdGhDcm9zcy5TZXRQb2ludCgyLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tICsgcmNDbGllbnQuSGVpZ2h0KCkgKiAwLjVmLCBGWFBUX01PVkVUTyk7DQotCXBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQuV2lkdGgoKSAqIDAuNWYsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOw0KLQkNCi0JcERldmljZS0+RHJhd1BhdGgoJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCANCi0JCTAsIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKSwgRlhGSUxMX0FMVEVSTkFURSk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfSWNvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BXTF9Ob3RlX0ljb246OkNQV0xfTm90ZV9JY29uKCkgOiBtX25UeXBlKDApDQotew0KLX0NCi0NCi1DUFdMX05vdGVfSWNvbjo6fkNQV0xfTm90ZV9JY29uKCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0ljb246OlNldEljb25UeXBlKEZYX0lOVDMyIG5UeXBlKQ0KLXsNCi0JbV9uVHlwZSA9IG5UeXBlOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZV9JY29uOjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkNCi17DQotCUNQV0xfVXRpbHM6OkRyYXdJY29uQXBwU3RyZWFtKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgbV9uVHlwZSwgR2V0Q2xpZW50UmVjdCgpLCANCi0JCXRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpLCBQV0xfREVGQVVMVF9CTEFDS0NPTE9SLCB0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfQ2xvc2VCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNQV0xfTm90ZV9DbG9zZUJveDo6Q1BXTF9Ob3RlX0Nsb3NlQm94KCkgOiBtX2JNb3VzZURvd24oRkFMU0UpDQotew0KLX0NCi0NCi1DUFdMX05vdGVfQ2xvc2VCb3g6On5DUFdMX05vdGVfQ2xvc2VCb3goKQ0KLXsNCi19DQotDQotdm9pZCBDUFdMX05vdGVfQ2xvc2VCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0KLXsNCi0JQ1BXTF9CdXR0b246OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UpOw0KLQ0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7DQotCXJjQ2xpZW50ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmNDbGllbnQsIDIuMGYpOw0KLQ0KLQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOw0KLQlnc2QubV9MaW5lV2lkdGggPSAxLjBmOw0KLQ0KLQlDRlhfUGF0aERhdGEgcGF0aENyb3NzOw0KLQ0KLQlpZiAobV9iTW91c2VEb3duKQ0KLQl7DQotCQlyY0NsaWVudC5sZWZ0ICs9IDAuNWY7DQotCQlyY0NsaWVudC5yaWdodCArPSAwLjVmOw0KLQkJcmNDbGllbnQudG9wIC09IDAuNWY7DQotCQlyY0NsaWVudC5ib3R0b20gLT0gMC41ZjsNCi0JfQ0KLQ0KLQlwYXRoQ3Jvc3MuU2V0UG9pbnRDb3VudCg0KTsNCi0JcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9NT1ZFVE8pOw0KLQlwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LnRvcCwgRlhQVF9MSU5FVE8pOw0KLQlwYXRoQ3Jvc3MuU2V0UG9pbnQoMiwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQudG9wLCBGWFBUX01PVkVUTyk7DQotCXBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7DQotCQ0KLQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aENyb3NzLCBwVXNlcjJEZXZpY2UsICZnc2QsIA0KLQkJMCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLCBGWEZJTExfQUxURVJOQVRFKTsNCi19DQotDQotRlhfQk9PTCBDUFdMX05vdGVfQ2xvc2VCb3g6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCVNldEJvcmRlclN0eWxlKFBCU19JTlNFVCk7DQotCUludmFsaWRhdGVSZWN0KE5VTEwpOw0KLQ0KLQltX2JNb3VzZURvd24gPSBUUlVFOw0KLQ0KLQlyZXR1cm4gQ1BXTF9CdXR0b246Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOw0KLX0NCi0NCi1GWF9CT09MCUNQV0xfTm90ZV9DbG9zZUJveDo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCW1fYk1vdXNlRG93biA9IEZBTFNFOw0KLQ0KLQlTZXRCb3JkZXJTdHlsZShQQlNfQkVWRUxFRCk7DQotCUludmFsaWRhdGVSZWN0KE5VTEwpOw0KLQ0KLQlyZXR1cm4gQ1BXTF9CdXR0b246Ok9uTEJ1dHRvblVwKHBvaW50LG5GbGFnKTsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9Db250ZW50cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDUFdMX05vdGVfQ29udGVudHMoKSA6IG1fcEVkaXQoTlVMTCkNCi17DQotfQ0KLQ0KLUNQV0xfTm90ZV9Db250ZW50czo6fkNQV0xfTm90ZV9Db250ZW50cygpDQotew0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX05vdGVfQ29udGVudHM6OkdldENsYXNzTmFtZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gIkNQV0xfTm90ZV9Db250ZW50cyI7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCi17DQotCW1fcEVkaXQgPSBuZXcgQ1BXTF9Ob3RlX0VkaXQ7DQotCVBXTF9DUkVBVEVQQVJBTSBlY3AgPSBjcDsNCi0JZWNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQllY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX01VTFRJTElORSB8IFBFU19BVVRPUkVUVVJOIHwgUEVTX1RFWFRPVkVSRkxPVyB8IFBFU19VTkRPIHwgUEVTX1NQRUxMQ0hFQ0s7DQotDQotCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7DQotCW1fcEVkaXQtPkNyZWF0ZShlY3ApOw0KLQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkNCi17DQotCWlmIChtX3BFZGl0KQ0KLQl7DQotCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOw0KLQkJbV9wRWRpdC0+U2V0VGV4dChzVGV4dCk7DQotCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7DQotCQlPbk5vdGlmeShtX3BFZGl0LCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsJCQ0KLQl9DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZV9Db250ZW50czo6R2V0VGV4dCgpIGNvbnN0DQotew0KLQlpZiAobV9wRWRpdCkNCi0JCXJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7DQotDQotCXJldHVybiBMIiI7DQotfQ0KLQ0KLUNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6Q3JlYXRlU3ViSXRlbSgpDQotew0KLQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSBuZXcgQ1BXTF9Ob3RlSXRlbTsNCi0JUFdMX0NSRUFURVBBUkFNIGljcCA9IHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKTsNCi0JaWNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQlpY3AuZHdGbGFncyA9ICBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19CQUNLR1JPVU5EOw0KLQlwTm90ZUl0ZW0tPkNyZWF0ZShpY3ApOw0KLQ0KLQlwTm90ZUl0ZW0tPk9uQ3JlYXRlTm90ZUl0ZW0oKTsNCi0JDQotCXBOb3RlSXRlbS0+UmVzZXRTdWJqZWN0TmFtZShtX2FDaGlsZHJlbi5HZXRTaXplKCkgLSAxKTsNCi0NCi0JRlhfU1lTVEVNVElNRSBzdDsNCi0JaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSB0aGlzLT5HZXRTeXN0ZW1IYW5kbGVyKCkpDQotCQlzdCA9IHBTSC0+R2V0TG9jYWxUaW1lKCk7DQotCXBOb3RlSXRlbS0+U2V0RGF0ZVRpbWUoc3QpOw0KLQ0KLQlwTm90ZUl0ZW0tPlNldENvbnRlbnRzKEwiIik7DQotDQotCXRoaXMtPk9uTm90aWZ5KHBOb3RlSXRlbSwgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CQ0KLQ0KLQlyZXR1cm4gcE5vdGVJdGVtOw0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX05vdGVfQ29udGVudHM6OkNvdW50U3ViSXRlbXMoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fYUNoaWxkcmVuLkdldFNpemUoKSAtIDE7DQotfQ0KLQ0KLUlQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6R2V0U3ViSXRlbXMoRlhfSU5UMzIgaW5kZXgpIGNvbnN0DQotew0KLQlGWF9JTlQzMiBuSW5kZXggPSBpbmRleCArIDE7DQotDQotCWlmIChuSW5kZXggPiAwICYmIG5JbmRleCA8IG1fYUNoaWxkcmVuLkdldFNpemUoKSkNCi0JCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQobkluZGV4KSkNCi0JCXsNCi0JCQlBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOw0KLQkJCUNQV0xfTm90ZUl0ZW0qIHBJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsNCi0JCQlyZXR1cm4gcEl0ZW07DQotCQl9DQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZV9Db250ZW50czo6RGVsZXRlU3ViSXRlbShJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0pDQotew0KLQlGWF9JTlQzMiBuSW5kZXggPSB0aGlzLT5HZXRJdGVtSW5kZXgoKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSk7DQotDQotCWlmIChuSW5kZXggPiAwKQ0KLQl7DQotCQlpZiAoQ1BXTF9Ob3RlSXRlbSogcFBXTE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSkNCi0JCXsNCi0JCQlwUFdMTm90ZUl0ZW0tPktpbGxGb2N1cygpOw0KLQkJCXBQV0xOb3RlSXRlbS0+RGVzdHJveSgpOw0KLQkJCWRlbGV0ZSBwUFdMTm90ZUl0ZW07DQotCQl9DQotDQotCQlmb3IgKEZYX0lOVDMyIGk9bkluZGV4LHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQkJew0KLQkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQkJew0KLQkJCQlBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOw0KLQkJCQlDUFdMX05vdGVJdGVtKiBwSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7DQotCQkJCXBJdGVtLT5SZXNldFN1YmplY3ROYW1lKGkpOw0KLQkJCX0NCi0JCX0NCi0NCi0JCXRoaXMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOw0KLQl9DQotfQ0KLQ0KLUlQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6R2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlDUERGX1BvaW50IHB0ID0gdGhpcy0+UGFyZW50VG9DaGlsZChwb2ludCk7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQ0KLQkJew0KLQkJCWlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikNCi0JCQl7DQotCQkJCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7DQotCQkJCWlmIChJUFdMX05vdGVJdGVtKiBwUmV0ID0gcE5vdGVJdGVtLT5HZXRIaXROb3RlSXRlbShwdCkpDQotCQkJCQlyZXR1cm4gcFJldDsNCi0JCQl9DQotCQl9DQotCX0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQ0KLXsNCi0Jc3dpdGNoIChtc2cpDQotCXsNCi0JY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOg0KLQkJew0KLQkJCUZYX0lOVDMyIG5JbmRleCA9IHRoaXMtPkdldEl0ZW1JbmRleChwV25kKTsNCi0JCQlpZiAobkluZGV4IDwgMCkgbkluZGV4ID0gMDsNCi0NCi0JCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwkNCi0JCQl0aGlzLT5SZXNldENvbnRlbnQobkluZGV4KTsNCi0JCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7DQotDQotCQkJZm9yIChGWF9JTlQzMiBpPW5JbmRleCsxLCBzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQl7DQotCQkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOw0KLQkJCX0NCi0NCi0JCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQotCQkJew0KLQkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsNCi0JCQl9DQotCQl9DQotCQlyZXR1cm47DQotCWNhc2UgUE5NX1NDUk9MTFdJTkRPVzoNCi0JCXRoaXMtPlNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAuMGYsICooRlhfRkxPQVQqKWxQYXJhbSkpOw0KLQkJdGhpcy0+UmVzZXRGYWNlKCk7DQotCQlJbnZhbGlkYXRlUmVjdChOVUxMKTsNCi0JCXJldHVybjsJCQ0KLQljYXNlIFBOTV9TRVRDQVJFVElORk86DQotCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQ0KLQkJew0KLQkJCVBXTF9DQVJFVF9JTkZPIG5ld0luZm8gPSAqcEluZm87DQotCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7DQotCQkJbmV3SW5mby5wdEhlYWQgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEhlYWQpOw0KLQkJCW5ld0luZm8ucHRGb290ID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRGb290KTsNCi0NCi0JCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQotCQkJew0KLQkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoRlhfSU5UUFRSKSZuZXdJbmZvLCAwKTsNCi0JCQl9DQotCQl9DQotCQlyZXR1cm47DQotCWNhc2UgUE5NX05PVEVSRVNFVDoNCi0JCXsNCi0JCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwkNCi0JCQl0aGlzLT5SZXNldENvbnRlbnQoMCk7DQotCQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOw0KLQ0KLQkJCWZvciAoRlhfSU5UMzIgaT0xLCBzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCQl7DQotCQkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOw0KLQkJCX0JDQotDQotCQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsJDQotCQkJdGhpcy0+UmVzZXRDb250ZW50KDApOw0KLQkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsNCi0JCX0NCi0JCXJldHVybjsNCi0JfQ0KLQ0KLQlDUFdMX1duZDo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9Ob3RlX0NvbnRlbnRzOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAoQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpKSByZXR1cm4gVFJVRTsNCi0NCi0JaWYgKCFtX3BFZGl0LT5Jc0ZvY3VzZWQoKSkNCi0Jew0KLQkJbV9wRWRpdC0+U2V0Rm9jdXMoKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OlNldEVkaXRGb2N1cyhGWF9CT09MIGJMYXN0KQ0KLXsNCi0JaWYgKCFtX3BFZGl0LT5Jc0ZvY3VzZWQoKSkNCi0Jew0KLQkJbV9wRWRpdC0+U2V0Rm9jdXMoKTsNCi0JCW1fcEVkaXQtPlNldENhcmV0KGJMYXN0ID8gbV9wRWRpdC0+R2V0VG90YWxXb3JkcygpIDogMCk7DQotCX0NCi19DQotDQotQ1BXTF9FZGl0KiBDUFdMX05vdGVfQ29udGVudHM6OkdldEVkaXQoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcEVkaXQ7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCkNCi17DQotCWlmICghYkVuYWJsZWQpDQotCQltX3BFZGl0LT5BZGRGbGFnKFBXU19SRUFET05MWSk7DQotCWVsc2UNCi0JCW1fcEVkaXQtPlJlbW92ZUZsYWcoUFdTX1JFQURPTkxZKTsNCi0NCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQl7DQotCQkJaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKQ0KLQkJCXsNCi0JCQkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsNCi0JCQkJcE5vdGVJdGVtLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfTm90ZV9Db250ZW50czo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKQ0KLXsNCi0JaWYgKCFiRW5hYmxlZCkNCi0JCW1fcEVkaXQtPkFkZEZsYWcoUEVTX05PUkVBRCk7DQotCWVsc2UNCi0JCW1fcEVkaXQtPlJlbW92ZUZsYWcoUEVTX05PUkVBRCk7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQ0KLQl7DQotCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQ0KLQkJew0KLQkJCWlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikNCi0JCQl7DQotCQkJCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7DQotCQkJCXBOb3RlSXRlbS0+RW5hYmxlUmVhZChiRW5hYmxlZCk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlSXRlbSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BXTF9Ob3RlSXRlbTo6Q1BXTF9Ob3RlSXRlbSgpIDoNCi0JbV9wUHJpdmF0ZURhdGEoTlVMTCksDQotCW1fcFN1YmplY3QoTlVMTCksDQotCW1fcERhdGVUaW1lKE5VTEwpLA0KLQltX3BDb250ZW50cyhOVUxMKSwNCi0JbV9zQXV0aG9yKEwiIiksDQotCW1fZk9sZEl0ZW1IZWlnaHQoMC4wZiksDQotCW1fYlNpemVDaGFuZ2VkKEZBTFNFKSwNCi0JbV9iQWxsb3dNb2RpZnkoVFJVRSkNCi17DQotfQ0KLQ0KLUNQV0xfTm90ZUl0ZW06On5DUFdMX05vdGVJdGVtKCkNCi17DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldENsYXNzTmFtZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gIkNQV0xfTm90ZUl0ZW0iOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0KLXsNCi0JQ1BXTF9Db2xvciBzVGV4dENvbG9yOw0KLQ0KLQlpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUodGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCkpKQ0KLQkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7DQotCWVsc2UNCi0JCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOw0KLQ0KLQltX3BTdWJqZWN0ID0gbmV3IENQV0xfTGFiZWw7DQotCVBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsNCi0Jc2NwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQlzY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX0xFRlQgfCBQRVNfVE9QOw0KLQlzY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7DQotCW1fcFN1YmplY3QtPkNyZWF0ZShzY3ApOw0KLQ0KLQltX3BEYXRlVGltZSA9IG5ldyBDUFdMX0xhYmVsOw0KLQlQV0xfQ1JFQVRFUEFSQU0gZGNwID0gY3A7DQotCWRjcC5wUGFyZW50V25kID0gdGhpczsNCi0JZGNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19SSUdIVCB8IFBFU19UT1A7DQotCWRjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCi0JbV9wRGF0ZVRpbWUtPkNyZWF0ZShkY3ApOw0KLQ0KLQltX3BDb250ZW50cyA9IG5ldyBDUFdMX05vdGVfQ29udGVudHM7DQotCVBXTF9DUkVBVEVQQVJBTSBjY3AgPSBjcDsNCi0JY2NwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQkvL2NjcC5zQmFja2dyb3VuZENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsNCi0JY2NwLnNCYWNrZ3JvdW5kQ29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDI0MC8yNTUuMGYsIDI0MC8yNTUuMGYsIDI0MC8yNTUuMGYpOw0KLQljY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUFdTX0JBQ0tHUk9VTkQ7DQotCW1fcENvbnRlbnRzLT5DcmVhdGUoY2NwKTsNCi0JbV9wQ29udGVudHMtPlNldEl0ZW1TcGFjZShQT1BVUF9JVEVNX1NQQUNFKTsNCi0JbV9wQ29udGVudHMtPlNldFRvcFNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOw0KLQltX3BDb250ZW50cy0+U2V0Qm90dG9tU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlSXRlbTo6UmVQb3NDaGlsZFduZCgpDQotew0KLQlpZiAodGhpcy0+SXNWYWxpZCgpKQ0KLQl7DQotCQlBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsNCi0NCi0JCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0NCi0JCUNQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsNCi0JCXJjU3ViamVjdC5sZWZ0ICs9IFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7DQotCQlyY1N1YmplY3QudG9wID0gcmNDbGllbnQudG9wOw0KLQkJcmNTdWJqZWN0LnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsIHJjQ2xpZW50LnJpZ2h0KTsNCi0JCXJjU3ViamVjdC5ib3R0b20gPSByY1N1YmplY3QudG9wIC0gbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsNCi0JCXJjU3ViamVjdC5Ob3JtYWxpemUoKTsNCi0JCW1fcFN1YmplY3QtPk1vdmUocmNTdWJqZWN0LCBUUlVFLCBGQUxTRSk7DQotCQltX3BTdWJqZWN0LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNTdWJqZWN0KSk7DQotDQotCQlDUERGX1JlY3QgcmNEYXRlID0gcmNDbGllbnQ7DQotCQlyY0RhdGUucmlnaHQgLT0gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsNCi0JCXJjRGF0ZS5sZWZ0ID0gUFdMX01BWChyY0RhdGUucmlnaHQgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpIC0gMS4wZiwgcmNTdWJqZWN0LnJpZ2h0KTsNCi0JCXJjRGF0ZS5ib3R0b20gPSByY0RhdGUudG9wIC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQotCQlyY0RhdGUuTm9ybWFsaXplKCk7DQotCQltX3BEYXRlVGltZS0+TW92ZShyY0RhdGUsIFRSVUUsIEZBTFNFKTsNCi0JCW1fcERhdGVUaW1lLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNEYXRlKSk7DQotDQotCQlDUERGX1JlY3QgcmNDb250ZW50cyA9IHJjQ2xpZW50Ow0KLQkJcmNDb250ZW50cy5sZWZ0ICs9IDEuMGY7DQotCQlyY0NvbnRlbnRzLnJpZ2h0IC09IDEuMGY7DQotCQlyY0NvbnRlbnRzLnRvcCA9IHJjRGF0ZS5ib3R0b20gLSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NOw0KLQkJcmNDb250ZW50cy5ib3R0b20gKz0gUE9QVVBfSVRFTV9CT1RUT01XSURUSDsNCi0JCXJjQ29udGVudHMuTm9ybWFsaXplKCk7DQotCQltX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBUUlVFLCBGQUxTRSk7DQotCQltX3BDb250ZW50cy0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ29udGVudHMpKTsNCi0JfQ0KLQ0KLQlTZXRDbGlwUmVjdChDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdChHZXRXaW5kb3dSZWN0KCksMS4wZikpOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZUl0ZW06OlNldFByaXZhdGVEYXRhKHZvaWQqIHBEYXRhKQ0KLXsNCi0JbV9wUHJpdmF0ZURhdGEgPSBwRGF0YTsNCi19DQotDQotdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQ0KLXsNCi0JQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsNCi0JdGhpcy0+U2V0QmFja2dyb3VuZENvbG9yKHNCSyk7DQotDQotCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsNCi0NCi0JaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHNCSykpDQotCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsNCi0JZWxzZQ0KLQkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7DQotDQotCXRoaXMtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsNCi0JaWYgKG1fcFN1YmplY3QpDQotCQltX3BTdWJqZWN0LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQotCWlmIChtX3BEYXRlVGltZSkNCi0JCW1fcERhdGVUaW1lLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQotDQotCXRoaXMtPkludmFsaWRhdGVSZWN0KE5VTEwpOw0KLQ0KLQlpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQ0KLQl7DQotCQlwTm90aWZ5LT5PblNldEJrQ29sb3IodGhpcyk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpDQotew0KLQlpZiAobV9wU3ViamVjdCkNCi0Jew0KLQkJbV9wU3ViamVjdC0+U2V0VGV4dChzTmFtZSk7CQ0KLQl9DQotDQotCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpDQotCXsNCi0JCXBOb3RpZnktPk9uU2V0U3ViamVjdE5hbWUodGhpcyk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRBdXRob3JOYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkNCi17DQotCW1fc0F1dGhvciA9IHNOYW1lOw0KLQlSZXNldFN1YmplY3ROYW1lKC0xKTsJDQotDQotCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpDQotCXsNCi0JCXBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfTm90ZUl0ZW06OlJlc2V0U3ViamVjdE5hbWUoRlhfSU5UMzIgbkl0ZW1JbmRleCkNCi17DQotCWlmIChuSXRlbUluZGV4IDwgMCkNCi0Jew0KLQkJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQotCQl7DQotCQkJQVNTRVJUKHBQYXJlbnQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVfQ29udGVudHMiKTsNCi0NCi0JCQlDUFdMX05vdGVfQ29udGVudHMqIHBDb250ZW50cyA9IChDUFdMX05vdGVfQ29udGVudHMqKXBQYXJlbnQ7DQotCQkJbkl0ZW1JbmRleCA9IHBDb250ZW50cy0+R2V0SXRlbUluZGV4KHRoaXMpOw0KLQkJfQ0KLQl9DQotDQotCWNvbnN0IENQV0xfTm90ZSogcE5vdGUgPSBHZXROb3RlKCk7DQotCUFTU0VSVChwTm90ZSAhPSBOVUxMKTsNCi0NCi0JQ0ZYX1dpZGVTdHJpbmcgc1N1YmplY3Q7DQotCXNTdWJqZWN0LkZvcm1hdChwTm90ZS0+R2V0UmVwbHlTdHJpbmcoKSwgbkl0ZW1JbmRleCk7DQotDQotCWlmICghbV9zQXV0aG9yLklzRW1wdHkoKSkNCi0Jew0KLQkJDQotCQlzU3ViamVjdCArPSBMIiAtICI7DQotCQlzU3ViamVjdCArPSBtX3NBdXRob3I7DQotCX0NCi0JdGhpcy0+U2V0U3ViamVjdE5hbWUoc1N1YmplY3QpOw0KLQl0aGlzLT5SZVBvc0NoaWxkV25kKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0RGF0ZVRpbWUoRlhfU1lTVEVNVElNRSB0aW1lKQ0KLXsNCi0JbV9kdE5vdGUgPSB0aW1lOw0KLQkNCi0JQ0ZYX1dpZGVTdHJpbmcgc3dUaW1lOw0KLQlzd1RpbWUuRm9ybWF0KChGWF9MUENXU1RSKUwiJTA0ZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQiLCB0aW1lLndZZWFyLCB0aW1lLndNb250aCwgdGltZS53RGF5LCB0aW1lLndIb3VyLCB0aW1lLndNaW51dGUsIHRpbWUud1NlY29uZCk7DQotCWlmIChtX3BEYXRlVGltZSkNCi0Jew0KLQkJbV9wRGF0ZVRpbWUtPlNldFRleHQoc3dUaW1lKTsNCi0JfQ0KLQ0KLQl0aGlzLT5SZVBvc0NoaWxkV25kKCk7DQotDQotCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpDQotCXsNCi0JCXBOb3RpZnktPk9uU2V0RGF0ZVRpbWUodGhpcyk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKQ0KLXsNCi0JaWYgKG1fcENvbnRlbnRzKQ0KLQl7DQotCQltX3BDb250ZW50cy0+U2V0VGV4dChzQ29udGVudHMpOw0KLQl9DQotDQotCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpDQotCXsNCi0JCXBOb3RpZnktPk9uU2V0Q29udGVudHModGhpcyk7DQotCX0NCi19DQotDQotQ1BXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0UGFyZW50Tm90ZUl0ZW0oKSBjb25zdA0KLXsNCi0JaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQotCXsNCi0JCWlmIChDUFdMX1duZCogcEdyYW5kID0gcFBhcmVudC0+R2V0UGFyZW50V2luZG93KCkpDQotCQl7DQotCQkJQVNTRVJUKHBHcmFuZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsNCi0JCQlyZXR1cm4gKENQV0xfTm90ZUl0ZW0qKXBHcmFuZDsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0UGFyZW50SXRlbSgpIGNvbnN0DQotew0KLQlyZXR1cm4gR2V0UGFyZW50Tm90ZUl0ZW0oKTsNCi19DQotDQotQ1BXTF9FZGl0KiBDUFdMX05vdGVJdGVtOjpHZXRFZGl0KCkgY29uc3QNCi17DQotCWlmIChtX3BDb250ZW50cykNCi0JCXJldHVybiBtX3BDb250ZW50cy0+R2V0RWRpdCgpOw0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCogQ1BXTF9Ob3RlSXRlbTo6R2V0UHJpdmF0ZURhdGEoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcFByaXZhdGVEYXRhOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRBdXRob3JOYW1lKCkgY29uc3QNCi17DQotCXJldHVybiBtX3NBdXRob3I7IA0KLX0NCi0NCi1DUFdMX0NvbG9yIENQV0xfTm90ZUl0ZW06OkdldEJrQ29sb3IoKSBjb25zdA0KLXsNCi0JcmV0dXJuIHRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpOw0KLX0NCi0NCi1DRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRDb250ZW50cygpIGNvbnN0DQotew0KLQlpZiAobV9wQ29udGVudHMpDQotCQlyZXR1cm4gbV9wQ29udGVudHMtPkdldFRleHQoKTsNCi0NCi0JcmV0dXJuIEwiIjsNCi19DQotDQotRlhfU1lTVEVNVElNRSBDUFdMX05vdGVJdGVtOjpHZXREYXRlVGltZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9kdE5vdGU7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldFN1YmplY3ROYW1lKCkgY29uc3QNCi17DQotCWlmIChtX3BTdWJqZWN0KQ0KLQkJcmV0dXJuIG1fcFN1YmplY3QtPkdldFRleHQoKTsNCi0NCi0JcmV0dXJuIEwiIjsNCi19DQotDQotQ1BXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6Q3JlYXRlTm90ZUl0ZW0oKQ0KLXsNCi0JaWYgKG1fcENvbnRlbnRzKQ0KLQkJcmV0dXJuIG1fcENvbnRlbnRzLT5DcmVhdGVTdWJJdGVtKCk7DQotDQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi1JUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpDcmVhdGVTdWJJdGVtKCkNCi17DQotCXJldHVybiBDcmVhdGVOb3RlSXRlbSgpOw0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX05vdGVJdGVtOjpDb3VudFN1Ykl0ZW1zKCkgY29uc3QNCi17DQotCWlmIChtX3BDb250ZW50cykNCi0JCXJldHVybiBtX3BDb250ZW50cy0+Q291bnRTdWJJdGVtcygpOw0KLQ0KLQlyZXR1cm4gMDsNCi19DQotDQotSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0U3ViSXRlbXMoRlhfSU5UMzIgaW5kZXgpIGNvbnN0DQotew0KLQlpZiAobV9wQ29udGVudHMpDQotCQlyZXR1cm4gbV9wQ29udGVudHMtPkdldFN1Ykl0ZW1zKGluZGV4KTsNCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlSXRlbTo6RGVsZXRlU3ViSXRlbShJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0pDQotew0KLQl0aGlzLT5LaWxsRm9jdXMoKTsNCi0NCi0JaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkNCi0Jew0KLQkJcE5vdGlmeS0+T25JdGVtRGVsZXRlKHBOb3RlSXRlbSk7DQotCX0NCi0NCi0JaWYgKG1fcENvbnRlbnRzKQ0KLQkJbV9wQ29udGVudHMtPkRlbGV0ZVN1Ykl0ZW0ocE5vdGVJdGVtKTsNCi19DQotDQotSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlDUERGX1BvaW50IHB0ID0gdGhpcy0+UGFyZW50VG9DaGlsZChwb2ludCk7DQotDQotCWlmICh0aGlzLT5XbmRIaXRUZXN0KHB0KSkNCi0Jew0KLQkJaWYgKG1fcENvbnRlbnRzKQ0KLQkJew0KLQkJCWlmIChJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSBtX3BDb250ZW50cy0+R2V0SGl0Tm90ZUl0ZW0ocHQpKQ0KLQkJCQlyZXR1cm4gcE5vdGVJdGVtOw0KLQkJfQ0KLQ0KLQkJcmV0dXJuIHRoaXM7DQotCX0NCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLUlQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldEZvY3VzZWROb3RlSXRlbSgpIGNvbnN0DQotew0KLQlpZiAoY29uc3QgQ1BXTF9XbmQqIHBXbmQgPSB0aGlzLT5HZXRGb2N1c2VkKCkpDQotCXsNCi0JCWlmIChwV25kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9FZGl0IikNCi0JCXsNCi0JCQlpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBwV25kLT5HZXRQYXJlbnRXaW5kb3coKSkNCi0JCQl7DQotCQkJCUFTU0VSVChwUGFyZW50LT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlX0NvbnRlbnRzIik7DQotCQkJCQ0KLQkJCQlpZiAoQ1BXTF9XbmQqIHBHcmFuZCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpKQ0KLQkJCQl7DQotCQkJCQlBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwkJCQkJDQotCQkJCQlyZXR1cm4gKENQV0xfTm90ZUl0ZW0qKXBHcmFuZDsNCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkNCi17DQotCWlmIChmTGltaXRXaWR0aCA+IDApDQotCXsNCi0JCWlmICghbV9iU2l6ZUNoYW5nZWQpDQotCQkJcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQ7DQotDQotCQltX2JTaXplQ2hhbmdlZCA9IEZBTFNFOw0KLQ0KLQkJQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7DQotCQlBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7DQotCQlBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7DQotDQotCQlGWF9GTE9BVCBmUmV0ID0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQotCQlGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpdGhpcy0+R2V0Qm9yZGVyV2lkdGgoKTsNCi0JCWlmIChmTGltaXRXaWR0aCA+IGZCb3JkZXJXaWR0aCAqIDIpDQotCQkJZlJldCArPSBtX3BDb250ZW50cy0+R2V0Q29udGVudHNIZWlnaHQoZkxpbWl0V2lkdGggLSBmQm9yZGVyV2lkdGggKiAyKTsNCi0JCWZSZXQgKz0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTSArIFBPUFVQX0lURU1fQk9UVE9NV0lEVEggKyBmQm9yZGVyV2lkdGggKiAyOw0KLQ0KLQkJcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQgPSBmUmV0Ow0KLQl9DQotDQotCXJldHVybiAwOw0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX05vdGVJdGVtOjpHZXRJdGVtTGVmdE1hcmdpbigpDQotew0KLQlyZXR1cm4gUE9QVVBfSVRFTV9TSURFTUFSR0lOOw0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX05vdGVJdGVtOjpHZXRJdGVtUmlnaHRNYXJnaW4oKQ0KLXsNCi0JcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsNCi19DQotDQotRlhfQk9PTAlDUFdMX05vdGVJdGVtOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCWlmICghbV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkNCi0Jew0KLQkJU2V0Tm90ZUZvY3VzKEZBTFNFKTsNCi0JfQ0KLQ0KLQlDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZyk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MCUNQV0xfTm90ZUl0ZW06Ok9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlpZiAoIW1fcENvbnRlbnRzLT5XbmRIaXRUZXN0KG1fcENvbnRlbnRzLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpDQotCXsNCi0JCVNldE5vdGVGb2N1cyhGQUxTRSk7DQotCQlQb3B1cE5vdGVJdGVtTWVudShwb2ludCk7DQotDQotCQlyZXR1cm4gVFJVRTsNCi0JfQ0KLQ0KLQlyZXR1cm4gQ1BXTF9XbmQ6Ok9uUkJ1dHRvblVwKHBvaW50LG5GbGFnKTsNCi19DQotDQotdm9pZCBDUFdMX05vdGVJdGVtOjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQ0KLXsNCi0Jc3dpdGNoIChtc2cpDQotCXsNCi0JY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOgkNCi0JCW1fYlNpemVDaGFuZ2VkID0gVFJVRTsNCi0NCi0JCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQ0KLQkJew0KLQkJCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOw0KLQkJfQ0KLQkJcmV0dXJuOwkNCi0JY2FzZSBQTk1fU0VUQ0FSRVRJTkZPOg0KLQkJaWYgKFBXTF9DQVJFVF9JTkZPICogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkNCi0JCXsNCi0JCQlQV0xfQ0FSRVRfSU5GTyBuZXdJbmZvID0gKnBJbmZvOw0KLQkJCW5ld0luZm8uYlZpc2libGUgPSBUUlVFOw0KLQkJCW5ld0luZm8ucHRIZWFkID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRIZWFkKTsNCi0JCQluZXdJbmZvLnB0Rm9vdCA9IHRoaXMtPkNoaWxkVG9QYXJlbnQocEluZm8tPnB0Rm9vdCk7DQotDQotCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQ0KLQkJCXsNCi0JCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKEZYX0lOVFBUUikmbmV3SW5mbywgMCk7DQotCQkJfQ0KLQkJfQ0KLQkJcmV0dXJuOw0KLQljYXNlIFBOTV9OT1RFUkVTRVQ6DQotCQltX2JTaXplQ2hhbmdlZCA9IFRSVUU7DQotCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7DQotCQkNCi0JCXJldHVybjsNCi0JfQ0KLQ0KLQlDUFdMX1duZDo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlSXRlbTo6UG9wdXBOb3RlSXRlbU1lbnUoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpDQotew0KLQlpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQ0KLQl7DQotCQlGWF9JTlQzMiB4LHk7DQotCQlQV0x0b1duZChwb2ludCwgeCwgeSk7DQotCQlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkNCi0JCQlwU0gtPkNsaWVudFRvU2NyZWVuKEdldEF0dGFjaGVkSFduZCgpLCB4LCB5KTsNCi0JCXBOb3RpZnktPk9uUG9wdXBNZW51KHRoaXMsIHgsIHkpOw0KLQl9DQotfQ0KLQ0KLWNvbnN0IENQV0xfTm90ZSogQ1BXTF9Ob3RlSXRlbTo6R2V0Tm90ZSgpIGNvbnN0DQotew0KLQlpZiAoY29uc3QgQ1BXTF9XbmQqIHBSb290ID0gdGhpcy0+R2V0Um9vdFduZCgpKQ0KLQl7DQotCQlBU1NFUlQocFJvb3QtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7DQotCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcFJvb3Q7DQotCQlpZiAocE5vdGVJdGVtLT5Jc1RvcEl0ZW0oKSkNCi0JCXsNCi0JCQlyZXR1cm4gKENQV0xfTm90ZSopcE5vdGVJdGVtOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi1JUFdMX05vdGVOb3RpZnkqIENQV0xfTm90ZUl0ZW06OkdldE5vdGVOb3RpZnkoKSBjb25zdA0KLXsNCi0JaWYgKGNvbnN0IENQV0xfTm90ZSogcE5vdGUgPSBHZXROb3RlKCkpDQotCQlyZXR1cm4gcE5vdGUtPkdldE5vdGVOb3RpZnkoKTsNCi0NCi0JcmV0dXJuIE5VTEw7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25DcmVhdGVOb3RlSXRlbSgpDQotew0KLQlpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQ0KLQl7DQotCQlwTm90aWZ5LT5Pbkl0ZW1DcmVhdGUodGhpcyk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX05vdGVJdGVtOjpPbkNvbnRlbnRzVmFsaWRhdGUoKQ0KLXsNCi0JaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkNCi0Jew0KLQkJcE5vdGlmeS0+T25TZXRDb250ZW50cyh0aGlzKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfTm90ZUl0ZW06OlNldE5vdGVGb2N1cyhGWF9CT09MIGJMYXN0KQ0KLXsNCi0JbV9wQ29udGVudHMtPlNldEVkaXRGb2N1cyhiTGFzdCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlSXRlbTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpDQotew0KLQltX3BDb250ZW50cy0+RW5hYmxlTW9kaWZ5KGJFbmFibGVkKTsNCi0JbV9iQWxsb3dNb2RpZnkgPSBiRW5hYmxlZDsNCi19DQotDQotdm9pZCBDUFdMX05vdGVJdGVtOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpDQotew0KLQltX3BDb250ZW50cy0+RW5hYmxlUmVhZChiRW5hYmxlZCk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX05vdGU6OkNQV0xfTm90ZShJUG9wdXBfTm90ZSogcFBvcHVwTm90ZSwgSVBXTF9Ob3RlTm90aWZ5KiBwTm90ZU5vdGlmeSwgSVBXTF9Ob3RlSGFuZGxlciogcE5vdGVIYW5kbGVyKSA6IA0KLQltX3BBdXRob3IoTlVMTCksDQotCW1fcEljb24oTlVMTCksDQotCW1fcENsb3NlQm94KE5VTEwpLA0KLQltX3BDb250ZW50c0JhcihOVUxMKSwNCi0JbV9wTEJCb3goTlVMTCksDQotCW1fcFJCQm94KE5VTEwpLA0KLQltX3BPcHRpb25zKE5VTEwpLA0KLQltX2JSZXNpemluZyhGQUxTRSksDQotCW1fcmNDYXB0aW9uKDAsMCwwLDApLA0KLQltX3BOb3RlTm90aWZ5KHBOb3RlTm90aWZ5KSwNCi0JbV9iRW5hbGJsZU5vdGlmeShUUlVFKSwNCi0JbV9wUG9wdXBOb3RlKHBQb3B1cE5vdGUpLA0KLQltX3BOb3RlSGFuZGxlcihwTm90ZUhhbmRsZXIpDQotew0KLX0NCi0NCi1DUFdMX05vdGU6On5DUFdMX05vdGUoKQ0KLXsNCi19DQotDQotSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlOjpSZXBseSgpDQotew0KLQlyZXR1cm4gQ3JlYXRlTm90ZUl0ZW0oKTsNCi19DQotDQotdm9pZCBDUFdMX05vdGU6OkVuYWJsZU5vdGlmeShGWF9CT09MIGJFbmFibGVkKQ0KLXsNCi0JbV9iRW5hbGJsZU5vdGlmeSA9IGJFbmFibGVkOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZTo6UmVQb3NDaGlsZFduZCgpDQotew0KLQlSZVBvc05vdGVDaGlsZHJlbigpOw0KLQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7DQotCVJlc2V0U2Nyb2xsQmFyKCk7DQotCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsNCi0JdGhpcy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7DQotCS8vzayyvQ0KLQlpZiAoY29uc3QgQ1BXTF9XbmQqIHBXbmQgPSB0aGlzLT5HZXRGb2N1c2VkKCkpDQotCXsNCi0JCWlmIChwV25kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9FZGl0IikNCi0JCXsNCi0JCQlDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopcFduZDsNCi0JCQlwRWRpdC0+U2V0Q2FyZXQocEVkaXQtPkdldENhcmV0KCkpOw0KLQkJfQ0KLQl9DQotCS8vQ1BERl9Qb2ludCBwdE5ldyA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsNCi0JLy9tX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfTm90ZTo6UmVzZXRTY3JvbGxCYXIoKQ0KLXsNCi0JRlhfQk9PTCBiU2Nyb2xsQ2hhbmdlZCA9IEZBTFNFOw0KLQ0KLQlpZiAoU2Nyb2xsQmFyU2hvdWxkVmlzaWJsZSgpKQ0KLQl7DQotCQlpZiAoIW1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkNCi0JCXsNCi0JCQltX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShUUlVFKTsNCi0JCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQ0KLQkJCXsNCi0JCQkJbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOw0KLQkJCQliU2Nyb2xsQ2hhbmdlZCA9IFRSVUU7DQotCQkJfQ0KLQkJfQkNCi0JfQ0KLQllbHNlDQotCXsNCi0JCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpDQotCQl7DQotCQkJbV9wQ29udGVudHNCYXItPlNldFZpc2libGUoRkFMU0UpOw0KLQkJCW1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsNCi0NCi0JCQliU2Nyb2xsQ2hhbmdlZCA9IFRSVUU7DQotCQl9DQotCX0NCi0NCi0JaWYgKGJTY3JvbGxDaGFuZ2VkKQ0KLQl7DQotCQlDUERGX1JlY3QgcmNOb3RlID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOw0KLQkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0V2luZG93UmVjdCgpOw0KLQkJcmNDb250ZW50cy5yaWdodCA9IHJjTm90ZS5yaWdodCAtIDMuMGY7DQotCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQ0KLQkJCXJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsNCi0JCW1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIFRSVUUsIFRSVUUpOw0KLQkJbV9wQ29udGVudHMtPlNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAuMGYsMC4wZikpOw0KLQkJbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOw0KLQl9DQotDQotCXJldHVybiBiU2Nyb2xsQ2hhbmdlZDsNCi19DQotDQotRlhfQk9PTCBDUFdMX05vdGU6OlNjcm9sbEJhclNob3VsZFZpc2libGUoKQ0KLXsNCi0JQ1BERl9SZWN0IHJjQ29udGVudHNGYWN0ID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsNCi0JQ1BERl9SZWN0IHJjQ29udGVudHNDbGllbnQgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQlyZXR1cm4gcmNDb250ZW50c0ZhY3QuSGVpZ2h0KCkgPiByY0NvbnRlbnRzQ2xpZW50LkhlaWdodCgpOwkNCi19DQotDQotdm9pZCBDUFdMX05vdGU6OlNldE9wdGlvbnNUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkNCi17DQotCWlmIChtX3BPcHRpb25zKQ0KLQkJbV9wT3B0aW9ucy0+U2V0VGV4dChzVGV4dCk7DQotDQotCVJlUG9zTm90ZUNoaWxkcmVuKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlOjpSZVBvc05vdGVDaGlsZHJlbigpDQotew0KLQlpZiAobV9iUmVzaXppbmcpIHJldHVybjsNCi0NCi0JbV9iUmVzaXppbmcgPSBUUlVFOw0KLQ0KLQlpZiAodGhpcy0+SXNWYWxpZCgpKQ0KLQl7DQotCQlBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BBdXRob3IgIT0gTlVMTCk7DQotCQlBU1NFUlQobV9wQ2xvc2VCb3ggIT0gTlVMTCk7DQotCQlBU1NFUlQobV9wSWNvbiAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BSQkJveCAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BDb250ZW50c0JhciAhPSBOVUxMKTsNCi0JCUFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOw0KLQ0KLQkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQkJQ1BERl9SZWN0IHJjSWNvbiA9IHJjQ2xpZW50Ow0KLQkJcmNJY29uLnRvcCAtPSAyLjBmOw0KLQkJcmNJY29uLnJpZ2h0ID0gcmNJY29uLmxlZnQgKyAxNC4wZjsNCi0JCXJjSWNvbi5ib3R0b20gPSByY0ljb24udG9wIC0gMTQuMGY7DQotCQlyY0ljb24uTm9ybWFsaXplKCk7DQotCQltX3BJY29uLT5Nb3ZlKHJjSWNvbiwgVFJVRSwgRkFMU0UpOw0KLQkJbV9wSWNvbi0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjSWNvbikpOw0KLQ0KLQkJQ1BERl9SZWN0IHJjQ2xvc2VCb3ggPSByY0NsaWVudDsNCi0JCXJjQ2xvc2VCb3gucmlnaHQgLT0gMS4wZjsNCi0JCXJjQ2xvc2VCb3gudG9wIC09IDEuMGY7DQotCQlyY0Nsb3NlQm94LmxlZnQgPSByY0Nsb3NlQm94LnJpZ2h0IC0gMTQuMGY7DQotCQlyY0Nsb3NlQm94LmJvdHRvbSA9IHJjQ2xvc2VCb3gudG9wIC0gMTQuMGY7DQotCQlyY0Nsb3NlQm94Lk5vcm1hbGl6ZSgpOw0KLQkJbV9wQ2xvc2VCb3gtPk1vdmUocmNDbG9zZUJveCwgVFJVRSwgRkFMU0UpOw0KLQkJbV9wQ2xvc2VCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0Nsb3NlQm94KSk7DQotDQotCQlDUERGX1JlY3QgcmNEYXRlID0gcmNDbGllbnQ7DQotCQlyY0RhdGUucmlnaHQgPSByY0Nsb3NlQm94LmxlZnQgLSBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOw0KLQkJcmNEYXRlLmxlZnQgPSBQV0xfTUFYKHJjRGF0ZS5yaWdodCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgLSAxLjBmLCByY0ljb24ucmlnaHQgKyAxLjBmKTsNCi0JCXJjRGF0ZS50b3AgPSByY0NsaWVudC50b3AgLSAyLjBmOw0KLQkJcmNEYXRlLmJvdHRvbSA9IHJjRGF0ZS50b3AgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsNCi0JCXJjRGF0ZS5Ob3JtYWxpemUoKTsNCi0JCW1fcERhdGVUaW1lLT5Nb3ZlKHJjRGF0ZSwgVFJVRSwgRkFMU0UpOw0KLQkJbV9wRGF0ZVRpbWUtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0RhdGUpKTsNCi0NCi0JCUNQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsNCi0JCXJjU3ViamVjdC50b3AgPSByY0NsaWVudC50b3AgLSAyLjBmOw0KLQkJcmNTdWJqZWN0LmxlZnQgPSByY0ljb24ucmlnaHQgKyBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOw0KLQkJcmNTdWJqZWN0LnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsIHJjRGF0ZS5sZWZ0IC0gMS4wZik7DQotCQlyY1N1YmplY3QuYm90dG9tID0gcmNTdWJqZWN0LnRvcCAtIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQotCQlyY1N1YmplY3QuTm9ybWFsaXplKCk7DQotCQltX3BTdWJqZWN0LT5Nb3ZlKHJjU3ViamVjdCwgVFJVRSwgRkFMU0UpOwkNCi0JCW1fcFN1YmplY3QtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY1N1YmplY3QpKTsNCi0NCi0JCUNQREZfUmVjdCByY09wdGlvbnMgPSByY0NsaWVudDsNCi0JCXJjT3B0aW9ucy5sZWZ0ID0gUFdMX01BWChyY09wdGlvbnMucmlnaHQgLSBtX3BPcHRpb25zLT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCksIHJjSWNvbi5yaWdodCArIDEuMGYpOw0KLQkJcmNPcHRpb25zLnRvcCA9IHJjU3ViamVjdC5ib3R0b20gLSA0LjBmOw0KLQkJcmNPcHRpb25zLmJvdHRvbSA9IHJjT3B0aW9ucy50b3AgLSBtX3BPcHRpb25zLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOw0KLQkJcmNPcHRpb25zLk5vcm1hbGl6ZSgpOw0KLQkJbV9wT3B0aW9ucy0+TW92ZShyY09wdGlvbnMsIFRSVUUsIEZBTFNFKTsNCi0JCW1fcE9wdGlvbnMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY09wdGlvbnMpKTsNCi0NCi0JCUNQREZfUmVjdCByY0F1dGhvciA9IHJjQ2xpZW50Ow0KLQkJcmNBdXRob3IudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7DQotCQlyY0F1dGhvci5sZWZ0ID0gcmNTdWJqZWN0LmxlZnQ7DQotCQlyY0F1dGhvci5yaWdodCA9IFBXTF9NSU4ocmNTdWJqZWN0LmxlZnQgKyBtX3BBdXRob3ItPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsIHJjT3B0aW9ucy5sZWZ0IC0gMS4wZik7DQotCQlyY0F1dGhvci5ib3R0b20gPSByY0F1dGhvci50b3AgLSBtX3BBdXRob3ItPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7DQotCQlyY0F1dGhvci5Ob3JtYWxpemUoKTsNCi0JCW1fcEF1dGhvci0+TW92ZShyY0F1dGhvciwgVFJVRSwgRkFMU0UpOw0KLQkJbV9wQXV0aG9yLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNBdXRob3IpKTsNCi0NCi0JCUNQREZfUmVjdCByY0xCQm94ID0gcmNDbGllbnQ7DQotCQlyY0xCQm94LnRvcCA9IHJjTEJCb3guYm90dG9tICsgNy4wZjsNCi0JCXJjTEJCb3gucmlnaHQgPSByY0xCQm94LmxlZnQgKyA3LjBmOw0KLQkJcmNMQkJveC5Ob3JtYWxpemUoKTsNCi0JCW1fcExCQm94LT5Nb3ZlKHJjTEJCb3gsIFRSVUUsIEZBTFNFKTsNCi0JCW1fcExCQm94LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNMQkJveCkpOw0KLQ0KLQkJQ1BERl9SZWN0IHJjUkJCb3ggPSByY0NsaWVudDsNCi0JCXJjUkJCb3gudG9wID0gcmNSQkJveC5ib3R0b20gKyA3LjBmOw0KLQkJcmNSQkJveC5sZWZ0ID0gcmNSQkJveC5yaWdodCAtIDcuMGY7DQotCQlyY1JCQm94Lk5vcm1hbGl6ZSgpOw0KLQkJbV9wUkJCb3gtPk1vdmUocmNSQkJveCwgVFJVRSwgRkFMU0UpOw0KLQkJbV9wUkJCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY1JCQm94KSk7DQotDQotCQlDUERGX1JlY3QgcmNDb250ZW50cyA9IHJjQ2xpZW50Ow0KLQkJcmNDb250ZW50cy50b3AgPSByY0F1dGhvci5ib3R0b20gLSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NOw0KLQkJcmNDb250ZW50cy5sZWZ0ICs9IDMuMGY7DQotCQlyY0NvbnRlbnRzLnJpZ2h0IC09IDMuMGY7DQotCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQ0KLQkJCXJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsNCi0JCXJjQ29udGVudHMuYm90dG9tICs9IDE0LjBmOw0KLQkJcmNDb250ZW50cy5Ob3JtYWxpemUoKTsNCi0JCW1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIEZBTFNFLCBGQUxTRSk7DQotCQltX3BDb250ZW50cy0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ29udGVudHMpKTsNCi0NCi0JCUNQREZfUmVjdCByY0NvbnRlbnRzQmFyID0gcmNDb250ZW50czsNCi0JCXJjQ29udGVudHNCYXIucmlnaHQgPSByY0NsaWVudC5yaWdodCAtIDMuMGY7DQotCQlyY0NvbnRlbnRzQmFyLmxlZnQgPSByY0NvbnRlbnRzQmFyLnJpZ2h0IC0gUFdMX1NDUk9MTEJBUl9XSURUSDsNCi0JCXJjQ29udGVudHNCYXIuTm9ybWFsaXplKCk7DQotCQltX3BDb250ZW50c0Jhci0+TW92ZShyY0NvbnRlbnRzQmFyLCBUUlVFLCBGQUxTRSk7DQotCQkNCi0JCW1fcmNDYXB0aW9uID0gcmNDbGllbnQ7DQotCQltX3JjQ2FwdGlvbi5ib3R0b20gPSByY0NvbnRlbnRzLnRvcDsNCi0JfQ0KLQ0KLQltX2JSZXNpemluZyA9IEZBTFNFOw0KLX0NCi0NCi0vLzAtbm9ybWFsIC8gMS1jYXB0aW9uIC8gMi1sZWZ0Ym90dG9tIGNvcm5lciAvIDMtcmlnaHRib3R0b20gY29ybmVyIC8gNC1jbG9zZSAvIDUtb3B0aW9ucyANCi1GWF9JTlQzMiBDUFdMX05vdGU6Ok5vdGVIaXRUZXN0KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdA0KLXsNCi0JQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wQXV0aG9yICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wSWNvbiAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcENvbnRlbnRzQmFyICE9IE5VTEwpOw0KLQ0KLQlBU1NFUlQobV9wQ2xvc2VCb3ggIT0gTlVMTCk7DQotCUFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsNCi0JQVNTRVJUKG1fcFJCQm94ICE9IE5VTEwpOw0KLQlBU1NFUlQobV9wT3B0aW9ucyAhPSBOVUxMKTsNCi0NCi0JR2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQlpZiAobV9wU3ViamVjdC0+V25kSGl0VGVzdChtX3BTdWJqZWN0LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOw0KLQlpZiAobV9wRGF0ZVRpbWUtPlduZEhpdFRlc3QobV9wRGF0ZVRpbWUtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDE7DQotCWlmIChtX3BBdXRob3ItPlduZEhpdFRlc3QobV9wQXV0aG9yLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOw0KLQlpZiAobV9wSWNvbi0+V25kSGl0VGVzdChtX3BJY29uLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOw0KLQ0KLQlpZiAobV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDA7DQotCWlmIChtX3BDb250ZW50c0Jhci0+V25kSGl0VGVzdChtX3BDb250ZW50c0Jhci0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMDsNCi0NCi0JaWYgKG1fcENsb3NlQm94LT5XbmRIaXRUZXN0KG1fcENsb3NlQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiA0Ow0KLQlpZiAobV9wTEJCb3gtPlduZEhpdFRlc3QobV9wTEJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDI7DQotCWlmIChtX3BSQkJveC0+V25kSGl0VGVzdChtX3BSQkJveC0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMzsNCi0JaWYgKG1fcE9wdGlvbnMtPlduZEhpdFRlc3QobV9wT3B0aW9ucy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gNTsNCi0NCi0JcmV0dXJuIDE7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCi17DQotCUNQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNwKTsNCi0NCi0JQ1BXTF9Db2xvciBzVGV4dENvbG9yOw0KLQ0KLQlpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUodGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCkpKQ0KLQkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7DQotCWVsc2UNCi0JCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOw0KLQ0KLQltX3BBdXRob3IgPSBuZXcgQ1BXTF9MYWJlbDsNCi0JUFdMX0NSRUFURVBBUkFNIGFjcCA9IGNwOw0KLQlhY3AucFBhcmVudFduZCA9IHRoaXM7DQotCWFjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7DQotCWFjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCi0JbV9wQXV0aG9yLT5DcmVhdGUoYWNwKTsJIA0KLQ0KLQltX3BDbG9zZUJveCA9IG5ldyBDUFdMX05vdGVfQ2xvc2VCb3g7DQotCVBXTF9DUkVBVEVQQVJBTSBjY3AgPSBjcDsNCi0JY2NwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQljY3AuZHdCb3JkZXJXaWR0aCA9IDI7DQotCWNjcC5uQm9yZGVyU3R5bGUgPSBQQlNfQkVWRUxFRDsNCi0JY2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVI7DQotCWNjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCi0JbV9wQ2xvc2VCb3gtPkNyZWF0ZShjY3ApOw0KLQ0KLQltX3BJY29uID0gbmV3IENQV0xfTm90ZV9JY29uOw0KLQlQV0xfQ1JFQVRFUEFSQU0gaWNwID0gY3A7DQotCWljcC5wUGFyZW50V25kID0gdGhpczsNCi0JaWNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsNCi0JbV9wSWNvbi0+Q3JlYXRlKGljcCk7DQotDQotCW1fcE9wdGlvbnMgPSBuZXcgQ1BXTF9Ob3RlX09wdGlvbnM7DQotCVBXTF9DUkVBVEVQQVJBTSBvY3AgPSBjcDsNCi0Jb2NwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQlvY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOw0KLQlvY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7DQotCW1fcE9wdGlvbnMtPkNyZWF0ZShvY3ApOw0KLQ0KLQltX3BMQkJveCA9IG5ldyBDUFdMX05vdGVfTEJCb3g7DQotCVBXTF9DUkVBVEVQQVJBTSBsY3AgPSBjcDsNCi0JbGNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQlsY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOw0KLQlsY3AuZUN1cnNvclR5cGUgPSBGWENUX05FU1c7DQotCWxjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCi0JbV9wTEJCb3gtPkNyZWF0ZShsY3ApOw0KLQ0KLQltX3BSQkJveCA9IG5ldyBDUFdMX05vdGVfUkJCb3g7DQotCVBXTF9DUkVBVEVQQVJBTSByY3AgPSBjcDsNCi0JcmNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQlyY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOw0KLQlyY3AuZUN1cnNvclR5cGUgPSBGWENUX05XU0U7DQotCXJjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsNCi0JbV9wUkJCb3gtPkNyZWF0ZShyY3ApOw0KLQ0KLQltX3BDb250ZW50c0JhciA9IG5ldyBDUFdMX1Njcm9sbEJhcihTQlRfVlNDUk9MTCk7DQotCVBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsNCi0Jc2NwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQlzY3Auc0JhY2tncm91bmRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZik7DQotCXNjcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEUgfCBQV1NfQkFDS0dST1VORDsNCi0JbV9wQ29udGVudHNCYXItPkNyZWF0ZShzY3ApOw0KLQltX3BDb250ZW50c0Jhci0+U2V0Tm90aWZ5Rm9yZXZlcihUUlVFKTsNCi19DQotDQotdm9pZCBDUFdMX05vdGU6OlNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkNCi17DQotCUNQV0xfTm90ZUl0ZW06OlNldFN1YmplY3ROYW1lKHNOYW1lKTsNCi0JUmVQb3NDaGlsZFduZCgpOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpDQotew0KLQlpZiAobV9wQXV0aG9yKQ0KLQl7DQotCQltX3BBdXRob3ItPlNldFRleHQoc05hbWUpOw0KLQkJUmVQb3NDaGlsZFduZCgpOw0KLQl9DQotDQotCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpDQotCXsNCi0JCXBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsNCi0JfQkNCi19DQotDQotQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlOjpHZXRBdXRob3JOYW1lKCkgY29uc3QNCi17DQotCWlmIChtX3BBdXRob3IpDQotCQlyZXR1cm4gbV9wQXV0aG9yLT5HZXRUZXh0KCk7DQotDQotCXJldHVybiBMIiI7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9Ob3RlOjpPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsNCi0JQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsNCi0JQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQlpZiAocmNTY3JvbGwudG9wIC0gcmNTY3JvbGwuYm90dG9tID4gcmNDb250ZW50cy5IZWlnaHQoKSkNCi0Jew0KLQkJQ1BERl9Qb2ludCBwdE5ldyA9IHB0U2Nyb2xsOw0KLQ0KLQkJaWYgKHpEZWx0YSA+IDApDQotCQkJcHROZXcueSArPSAzMDsNCi0JCWVsc2UNCi0JCQlwdE5ldy55IC09IDMwOw0KLQ0KLQkJaWYgKHB0TmV3LnkgPiByY1Njcm9sbC50b3ApDQotCQkJcHROZXcueSA9IHJjU2Nyb2xsLnRvcDsNCi0JCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tICsgcmNDb250ZW50cy5IZWlnaHQoKSkNCi0JCQlwdE5ldy55ID0gcmNTY3JvbGwuYm90dG9tICsgcmNDb250ZW50cy5IZWlnaHQoKTsNCi0JCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tKQ0KLQkJCXB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b207DQotDQotCQlpZiAocHROZXcueSAhPSBwdFNjcm9sbC55KQ0KLQkJew0KLQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsNCi0JCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOwkJCQ0KLQkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHROZXcueSk7DQotDQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZTo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkNCi17DQotCXN3aXRjaCAobXNnKQ0KLQl7DQotCWNhc2UgUE5NX05PVEVFRElUQ0hBTkdFRDoNCi0JCXsNCi0JCQlDUERGX1JlY3QgcmNTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOw0KLQkJCQ0KLQ0KLQkJCVBXTF9TQ1JPTExfSU5GTyBzSW5mbzsNCi0JCQlzSW5mby5mQ29udGVudE1pbiA9IHJjU2Nyb2xsLmJvdHRvbTsNCi0JCQlzSW5mby5mQ29udGVudE1heCA9IHJjU2Nyb2xsLnRvcDsNCi0JCQlzSW5mby5mUGxhdGVXaWR0aCA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCkuSGVpZ2h0KCk7DQotCQkJc0luZm8uZlNtYWxsU3RlcCA9IDEzLjBmOw0KLQkJCXNJbmZvLmZCaWdTdGVwID0gc0luZm8uZlBsYXRlV2lkdGg7DQotDQotCQkJaWYgKEZYU1lTX21lbWNtcCgmbV9PbGRTY3JvbGxJbmZvLCAmc0luZm8sIHNpemVvZihQV0xfU0NST0xMX0lORk8pKSAhPSAwKQ0KLQkJCXsNCi0JCQkJRlhfQk9PTCBiU2Nyb2xsQ2hhbmdlZCA9IEZBTFNFOw0KLQ0KLQkJCQlpZiAobFBhcmFtIDwgMykgLy+3wNa5y8DRrbu3IG1hbnRpczoxNTc1OQ0KLQkJCQl7DQotCQkJCQliU2Nyb2xsQ2hhbmdlZCA9IFJlc2V0U2Nyb2xsQmFyKCk7DQotCQkJCQlpZiAoYlNjcm9sbENoYW5nZWQpDQotCQkJCQl7DQotCQkJCQkJbFBhcmFtKys7DQotCQkJCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOw0KLQkJCQkJCXRoaXMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIGxQYXJhbSk7DQotCQkJCQl9DQotCQkJCX0NCi0JCQkJDQotCQkJCWlmICghYlNjcm9sbENoYW5nZWQpDQotCQkJCXsNCi0JCQkJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpDQotCQkJCQl7DQotCQkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHBXbmQsIFBOTV9TRVRTQ1JPTExJTkZPLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmc0luZm8pOw0KLQkJCQkJCW1fT2xkU2Nyb2xsSW5mbyA9IHNJbmZvOw0KLQ0KLQkJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7DQotCQkJCQkJQ1BERl9Qb2ludCBwdE9sZCA9IHB0U2Nyb2xsOw0KLQ0KLQkJCQkJCWlmIChwdFNjcm9sbC55ID4gc0luZm8uZkNvbnRlbnRNYXgpDQotCQkJCQkJCXB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1heDsNCi0JCQkJCQlpZiAocHRTY3JvbGwueSA8IHNJbmZvLmZDb250ZW50TWluICsgc0luZm8uZlBsYXRlV2lkdGgpDQotCQkJCQkJCXB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbiArIHNJbmZvLmZQbGF0ZVdpZHRoOw0KLQkJCQkJCWlmIChwdFNjcm9sbC55IDwgc0luZm8uZkNvbnRlbnRNaW4pDQotCQkJCQkJCXB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbjsNCi0NCi0JCQkJCQlpZiAocHRPbGQueSAhPSBwdFNjcm9sbC55KQ0KLQkJCQkJCXsNCi0JCQkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsNCi0JCQkJCQkJbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOw0KLQkJCQkJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0U2Nyb2xsLnkpOw0KLQkJCQkJCX0NCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCX0NCi0JCX0NCi0NCi0JCW1fcENvbnRlbnRzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsNCi0NCi0JCXJldHVybjsNCi0JY2FzZSBQTk1fU0NST0xMV0lORE9XOg0KLQkJaWYgKG1fcENvbnRlbnRzKQ0KLQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsNCi0JCXJldHVybjsNCi0JY2FzZSBQTk1fU0VUU0NST0xMUE9TOg0KLQkJaWYgKG1fcENvbnRlbnRzQmFyKQ0KLQkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeShwV25kLFBOTV9TRVRTQ1JPTExQT1Msd1BhcmFtLGxQYXJhbSk7DQotCQlyZXR1cm47DQotCX0NCi0NCi0JaWYgKG1zZyA9PSBQTk1fU0VUQ0FSRVRJTkZPICYmIElzVmFsaWQoKSkNCi0Jew0KLQkJaWYgKFBXTF9DQVJFVF9JTkZPICogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkNCi0JCXsNCi0JCQlpZiAobV9wQ29udGVudHMpDQotCQkJew0KLQkJCQlDUERGX1JlY3QgcmNDbGllbnQgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOw0KLQkJCQlpZiAocEluZm8tPnB0SGVhZC55ID4gcmNDbGllbnQudG9wKQ0KLQkJCQl7DQotCQkJCQlDUERGX1BvaW50IHB0ID0gbV9wQ29udGVudHMtPk91dFRvSW4ocEluZm8tPnB0SGVhZCk7DQotCQkJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0LnkpOw0KLQ0KLQkJCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsNCi0JCQkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHRTY3JvbGwueSk7DQotDQotCQkJCQlyZXR1cm47DQotCQkJCX0NCi0JCQkJDQotCQkJCWlmIChwSW5mby0+cHRGb290LnkgPCByY0NsaWVudC5ib3R0b20pDQotCQkJCXsNCi0JCQkJCUNQREZfUG9pbnQgcHQgPSBtX3BDb250ZW50cy0+T3V0VG9JbihwSW5mby0+cHRGb290KTsNCi0JCQkJCXB0LnkgKz0gcmNDbGllbnQuSGVpZ2h0KCk7DQotCQkJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0LnkpOw0KLQ0KLQkJCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsNCi0JCQkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHRTY3JvbGwueSk7DQotDQotCQkJCQlyZXR1cm47DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0NCi0JQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlOjpTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQ0KLXsNCi0JQ1BXTF9Ob3RlSXRlbTo6U2V0QmtDb2xvcihjb2xvcik7DQotDQotCUNQV0xfQ29sb3Igc0JLID0gY29sb3I7DQotCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsNCi0JaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHNCSykpDQotCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsNCi0JZWxzZQ0KLQkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7DQotDQotCWlmIChtX3BDbG9zZUJveCkNCi0JCW1fcENsb3NlQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQotCWlmIChtX3BBdXRob3IpDQotCQltX3BBdXRob3ItPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsNCi0JaWYgKG1fcE9wdGlvbnMpDQotCQltX3BPcHRpb25zLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQotCWlmIChtX3BMQkJveCkNCi0JCW1fcExCQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQotCWlmIChtX3BSQkJveCkNCi0JCW1fcFJCQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9Ob3RlOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCWlmIChtX3BPcHRpb25zLT5XbmRIaXRUZXN0KG1fcE9wdGlvbnMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkNCi0Jew0KLQkJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IHRoaXMtPkdldE5vdGVOb3RpZnkoKSkNCi0JCXsNCi0JCQlGWF9JTlQzMiB4LCB5Ow0KLQkJCVBXTHRvV25kKHBvaW50LCB4LCB5KTsNCi0JCQlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkNCi0JCQkJcFNILT5DbGllbnRUb1NjcmVlbihHZXRBdHRhY2hlZEhXbmQoKSwgeCwgeSk7DQotCQkJdGhpcy0+S2lsbEZvY3VzKCk7DQotCQkJcE5vdGlmeS0+T25Qb3B1cE1lbnUoeCwgeSk7DQotDQotCQkJcmV0dXJuIFRSVUU7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIENQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKTsNCi19DQotDQotRlhfQk9PTAlDUFdMX05vdGU6Ok9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlyZXR1cm4gQ1BXTF9XbmQ6Ok9uUkJ1dHRvblVwKHBvaW50LG5GbGFnKTsNCi19DQotDQotY29uc3QgQ1BXTF9Ob3RlKiBDUFdMX05vdGU6OkdldE5vdGUoKSBjb25zdA0KLXsNCi0JcmV0dXJuIHRoaXM7DQotfQ0KLQ0KLUlQV0xfTm90ZU5vdGlmeSogQ1BXTF9Ob3RlOjpHZXROb3RlTm90aWZ5KCkgY29uc3QNCi17DQotCWlmIChtX2JFbmFsYmxlTm90aWZ5KQ0KLQkJcmV0dXJuIG1fcE5vdGVOb3RpZnk7DQotDQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZTo6U2V0SWNvblR5cGUoRlhfSU5UMzIgblR5cGUpDQotew0KLQlpZiAobV9wSWNvbikNCi0JCW1fcEljb24tPlNldEljb25UeXBlKG5UeXBlKTsNCi19DQotDQotdm9pZCBDUFdMX05vdGU6OkVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKQ0KLXsNCi0JbV9wQ29udGVudHMtPkVuYWJsZU1vZGlmeShiRW5hYmxlZCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpDQotew0KLQltX3BDb250ZW50cy0+RW5hYmxlUmVhZChiRW5hYmxlZCk7DQotfQ0KLQ0KLUNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZTo6R2V0UmVwbHlTdHJpbmcoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1JlcGx5U3RyaW5nOw0KLX0NCi0NCi12b2lkIENQV0xfTm90ZTo6U2V0UmVwbHlTdHJpbmcoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN0cmluZykNCi17DQotCW1fc1JlcGx5U3RyaW5nID0gc3RyaW5nOw0KLX0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9CdXR0b24uaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MaXN0Q3RybC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TY3JvbGxCYXIuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTm90ZS5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MYWJlbC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9FZGl0LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9DYXJldC5oIgorCisjZGVmaW5lIFBPUFVQX0lURU1fSEVBRF9CT1RUT00JCQkJCTMuMGYKKyNkZWZpbmUgUE9QVVBfSVRFTV9CT1RUT01XSURUSAkJCQkJMS4wZgorI2RlZmluZSBQT1BVUF9JVEVNX1NJREVNQVJHSU4JCQkJCTMuMGYKKyNkZWZpbmUgUE9QVVBfSVRFTV9TUEFDRQkJCQkJCTQuMGYKKyNkZWZpbmUgUE9QVVBfSVRFTV9URVhUX0lOREVOVAkJCQkJMi4wZgorI2RlZmluZSBQT1BVUF9JVEVNX0JPUkRFUkNPTE9SCQkJCQlDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDgwLzI1NS4wZiwgODAvMjU1LjBmLCA4MC8yNTUuMGYpCisKKyNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpCisjZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCSgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQorI2RlZmluZSBJc0Zsb2F0U21hbGxlcihmYSxmYikJCQkJKChmYSkgPCAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpCisjZGVmaW5lIElzRmxvYXRFcXVhbChmYSxmYikJCQkJCUlzRmxvYXRaZXJvKChmYSktKGZiKSkKKworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9PcHRpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ1BXTF9Ob3RlX09wdGlvbnM6OkNQV0xfTm90ZV9PcHRpb25zKCkgOiBtX3BUZXh0KE5VTEwpCit7Cit9CisKK0NQV0xfTm90ZV9PcHRpb25zOjp+Q1BXTF9Ob3RlX09wdGlvbnMoKQoreworfQorCit2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0Q29sb3IoY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yKQoreworCUNQV0xfV25kOjpTZXRUZXh0Q29sb3IoY29sb3IpOworCisJaWYgKG1fcFRleHQpCisJCW1fcFRleHQtPlNldFRleHRDb2xvcihjb2xvcik7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX09wdGlvbnM6OlJlUG9zQ2hpbGRXbmQoKQoreworCWlmICh0aGlzLT5Jc1ZhbGlkKCkpCisJeworCQlBU1NFUlQobV9wVGV4dCAhPSBOVUxMKTsKKworCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisKKwkJaWYgKHJjQ2xpZW50LldpZHRoKCkgPiAxNS4wZikKKwkJeworCQkJcmNDbGllbnQucmlnaHQgLT0gMTUuMGY7CisJCQltX3BUZXh0LT5Nb3ZlKHJjQ2xpZW50LCBUUlVFLCBGQUxTRSk7CisJCQltX3BUZXh0LT5TZXRWaXNpYmxlKFRSVUUpOworCQl9CisJCWVsc2UKKwkJeworCQkJbV9wVGV4dC0+TW92ZShDUERGX1JlY3QoMCwwLDAsMCksIFRSVUUsIEZBTFNFKTsKKwkJCW1fcFRleHQtPlNldFZpc2libGUoRkFMU0UpOworCQl9CisJfQorfQorCit2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKK3sKKwltX3BUZXh0ID0gbmV3IENQV0xfTGFiZWw7CisJUFdMX0NSRUFURVBBUkFNIHRjcCA9IGNwOworCXRjcC5wUGFyZW50V25kID0gdGhpczsKKwl0Y3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOworCW1fcFRleHQtPkNyZWF0ZSh0Y3ApOworfQorCit2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkKK3sKKwltX3BUZXh0LT5TZXRUZXh0KHNUZXh0KTsKK30KKwordm9pZCBDUFdMX05vdGVfT3B0aW9uczo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpCit7CisJQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UpOworCisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOworCXJjQ2xpZW50LmxlZnQgPSByY0NsaWVudC5yaWdodCAtIDE1LjBmOworCisJQ1BERl9Qb2ludCBwdENlbnRlciA9IENQREZfUG9pbnQoKHJjQ2xpZW50LmxlZnQgKyByY0NsaWVudC5yaWdodCkgKiAwLjVmLCAocmNDbGllbnQudG9wICsgcmNDbGllbnQuYm90dG9tKSAqIDAuNWYpOworCisJQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCAtIDIuMGYsIHB0Q2VudGVyLnkgKyAyLjBmICogMC41Zik7CisJQ1BERl9Qb2ludCBwdDIocHRDZW50ZXIueCArIDIuMGYsIHB0Q2VudGVyLnkgKyAyLjBmICogMC41Zik7CisJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCwgcHRDZW50ZXIueSAtIDMuMGYgKiAwLjVmKTsKKworCUNGWF9QYXRoRGF0YSBwYXRoOworCisJcGF0aC5TZXRQb2ludENvdW50KDQpOworCXBhdGguU2V0UG9pbnQoMCwgcHQxLngsIHB0MS55LCBGWFBUX01PVkVUTyk7CisJcGF0aC5TZXRQb2ludCgxLCBwdDIueCwgcHQyLnksIEZYUFRfTElORVRPKTsKKwlwYXRoLlNldFBvaW50KDIsIHB0My54LCBwdDMueSwgRlhQVF9MSU5FVE8pOworCXBhdGguU2V0UG9pbnQoMywgcHQxLngsIHB0MS55LCBGWFBUX0xJTkVUTyk7CisKKwlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCAKKwkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksR2V0VHJhbnNwYXJlbmN5KCkpLCAKKwkJMCwgRlhGSUxMX0FMVEVSTkFURSk7Cit9CisKK0NQREZfUmVjdCBDUFdMX05vdGVfT3B0aW9uczo6R2V0Q29udGVudFJlY3QoKSBjb25zdAoreworCUFTU0VSVChtX3BUZXh0ICE9IE5VTEwpOworCisJQ1BERl9SZWN0IHJjVGV4dCA9IG1fcFRleHQtPkdldENvbnRlbnRSZWN0KCk7CisJcmNUZXh0LnJpZ2h0ICs9IDE1LjBmOworCXJldHVybiByY1RleHQ7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0VkaXQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfTm90ZV9FZGl0OjpDUFdMX05vdGVfRWRpdCgpIDogbV9iRW5hYmxlTm90aWZ5KFRSVUUpLAorCW1fZk9sZEl0ZW1IZWlnaHQoMC4wZiksCisJbV9iU2l6ZUNoYW5nZWQoRkFMU0UpLAorCW1fZk9sZE1pbigwLjBmKSwKKwltX2ZPbGRNYXgoMC4wZikKK3sKK30KKworQ1BXTF9Ob3RlX0VkaXQ6On5DUFdMX05vdGVfRWRpdCgpCit7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX0VkaXQ6OlJlUG9zQ2hpbGRXbmQoKQoreworCW1fYkVuYWJsZU5vdGlmeSA9IEZBTFNFOwkKKwlDUFdMX0VkaXQ6OlJlUG9zQ2hpbGRXbmQoKTsKKwltX2JFbmFibGVOb3RpZnkgPSBUUlVFOworCisJbV9mT2xkSXRlbUhlaWdodCA9IHRoaXMtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX0VkaXQ6OlNldFRleHQoRlhfTFBDV1NUUiBjc1RleHQpCit7CisJbV9iRW5hYmxlTm90aWZ5ID0gRkFMU0U7CisJQ1BXTF9FZGl0OjpTZXRUZXh0KGNzVGV4dCk7CisJbV9iRW5hYmxlTm90aWZ5ID0gVFJVRTsJCisJbV9mT2xkSXRlbUhlaWdodCA9IHRoaXMtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uU2V0Rm9jdXMoKQoreworCW1fYkVuYWJsZU5vdGlmeSA9IEZBTFNFOwkKKwlDUFdMX0VkaXQ6Ok9uU2V0Rm9jdXMoKTsKKwltX2JFbmFibGVOb3RpZnkgPSBUUlVFOwkKKworCXRoaXMtPkVuYWJsZVNwZWxsQ2hlY2soVFJVRSk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uS2lsbEZvY3VzKCkKK3sKKwl0aGlzLT5FbmFibGVTcGVsbENoZWNrKEZBTFNFKTsKKworCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQorCXsKKwkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKKwkJeworCQkJQVNTRVJUKHBHcmFuZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKKworCQkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBHcmFuZDsKKworCQkJcE5vdGVJdGVtLT5PbkNvbnRlbnRzVmFsaWRhdGUoKTsKKwkJfQorCX0KKworCUNQV0xfRWRpdDo6T25LaWxsRm9jdXMoKTsKK30KKwordm9pZCBDUFdMX05vdGVfRWRpdDo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKK3sKKwlpZiAobV9iRW5hYmxlTm90aWZ5KQorCXsKKwkJaWYgKHdQYXJhbSA9PSBTQlRfVlNDUk9MTCkKKwkJeworCQkJc3dpdGNoIChtc2cpCisJCQl7CisJCQljYXNlIFBOTV9TRVRTQ1JPTExJTkZPOgkKKwkJCQlpZiAoUFdMX1NDUk9MTF9JTkZPKiBwSW5mbyA9IChQV0xfU0NST0xMX0lORk8qKWxQYXJhbSkKKwkJCQl7CQorCQkJCQlpZiAoIUlzRmxvYXRFcXVhbChwSW5mby0+ZkNvbnRlbnRNYXgsIG1fZk9sZE1heCkgfHwgCisJCQkJCQkhSXNGbG9hdEVxdWFsKHBJbmZvLT5mQ29udGVudE1pbiwgbV9mT2xkTWluKSkKKwkJCQkJeworCQkJCQkJbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwkJCQkKKwkJCQkJCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkKKwkJCQkJCXsKKwkJCQkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKKwkJCQkJCX0KKworCQkJCQkJbV9mT2xkTWF4ID0gcEluZm8tPmZDb250ZW50TWF4OworCQkJCQkJbV9mT2xkTWluID0gcEluZm8tPmZDb250ZW50TWluOworCQkJCQkJcmV0dXJuOworCQkJCQl9CisJCQkJfQorCQkJfQorCQl9CQkKKwl9CisKKwlDUFdMX0VkaXQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOworCisJaWYgKG1fYkVuYWJsZU5vdGlmeSkKKwl7CisJCXN3aXRjaCAobXNnKQorCQl7CisJCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoKKwkJCWlmIChQV0xfQ0FSRVRfSU5GTyAqIHBJbmZvID0gKFBXTF9DQVJFVF9JTkZPKil3UGFyYW0pCisJCQl7CisJCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKKwkJCQluZXdJbmZvLmJWaXNpYmxlID0gVFJVRTsKKwkJCQluZXdJbmZvLnB0SGVhZCA9IHRoaXMtPkNoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CisJCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOworCisJCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQorCQkJCXsKKwkJCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKEZYX0lOVFBUUikmbmV3SW5mbywgMCk7CisJCQkJfQorCQkJfQorCQkJYnJlYWs7CisJCX0KKwl9Cit9CisKK0ZYX0ZMT0FUIENQV0xfTm90ZV9FZGl0OjpHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKQoreworCWlmIChmTGltaXRXaWR0aCA+IDApCisJeworCQlpZiAoIW1fYlNpemVDaGFuZ2VkKQorCQkJcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQ7CisKKwkJbV9iU2l6ZUNoYW5nZWQgPSBGQUxTRTsJCisKKwkJdGhpcy0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKKwkJdGhpcy0+RW5hYmxlUmVmcmVzaChGQUxTRSk7CisJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CisKKwkJLy9DUERGX1JlY3QgcmNPbGQgPSB0aGlzLT5HZXRXaW5kb3dSZWN0KCk7CisKKwkJdGhpcy0+TW92ZShDUERGX1JlY3QoMCwwLGZMaW1pdFdpZHRoLDApLCBUUlVFLCBGQUxTRSk7CisJCUZYX0ZMT0FUIGZSZXQgPSB0aGlzLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOworCisJCS8vdGhpcy0+TW92ZShyY09sZCwgVFJVRSwgRkFMU0UpOworCisJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKKwkJdGhpcy0+RW5hYmxlTm90aWZ5KFRSVUUpOworCQl0aGlzLT5FbmFibGVSZWZyZXNoKFRSVUUpOworCisJCXJldHVybiBmUmV0OworCX0KKworCXJldHVybiAwOworfQorCitGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbUxlZnRNYXJnaW4oKQoreworCXJldHVybiBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOworfQorCitGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbVJpZ2h0TWFyZ2luKCkKK3sKKwlyZXR1cm4gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0xCQm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KKworQ1BXTF9Ob3RlX0xCQm94OjpDUFdMX05vdGVfTEJCb3goKQoreworfQorCitDUFdMX05vdGVfTEJCb3g6On5DUFdMX05vdGVfTEJCb3goKQoreworfQorCit2b2lkIENQV0xfTm90ZV9MQkJveDo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpCit7CisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOworCisJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKKwlnc2QubV9MaW5lV2lkdGggPSAxLjBmOworCisJQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsKKworCXBhdGhDcm9zcy5TZXRQb2ludENvdW50KDQpOworCXBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsKKwlwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOworCXBhdGhDcm9zcy5TZXRQb2ludCgyLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC5ib3R0b20gKyByY0NsaWVudC5IZWlnaHQoKSAqIDAuNWYsIEZYUFRfTU9WRVRPKTsKKwlwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQubGVmdCArIHJjQ2xpZW50LldpZHRoKCkgKiAwLjVmLCByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsKKwkKKwlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aENyb3NzLCBwVXNlcjJEZXZpY2UsICZnc2QsIAorCQkwLCBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSx0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSksIEZYRklMTF9BTFRFUk5BVEUpOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfUkJCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLworCitDUFdMX05vdGVfUkJCb3g6OkNQV0xfTm90ZV9SQkJveCgpCit7Cit9CisKK0NQV0xfTm90ZV9SQkJveDo6fkNQV0xfTm90ZV9SQkJveCgpCit7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX1JCQm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKK3sKKwlDUERGX1JlY3QgcmNDbGllbnQgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7CisKKwlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOworCWdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CisKKwlDRlhfUGF0aERhdGEgcGF0aENyb3NzOworCisJcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CisJcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LnJpZ2h0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsKKwlwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CisJcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LnJpZ2h0LCByY0NsaWVudC5ib3R0b20gKyByY0NsaWVudC5IZWlnaHQoKSAqIDAuNWYsIEZYUFRfTU9WRVRPKTsKKwlwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQubGVmdCArIHJjQ2xpZW50LldpZHRoKCkgKiAwLjVmLCByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsKKwkKKwlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aENyb3NzLCBwVXNlcjJEZXZpY2UsICZnc2QsIAorCQkwLCBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSx0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSksIEZYRklMTF9BTFRFUk5BVEUpOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0ljb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX05vdGVfSWNvbjo6Q1BXTF9Ob3RlX0ljb24oKSA6IG1fblR5cGUoMCkKK3sKK30KKworQ1BXTF9Ob3RlX0ljb246On5DUFdMX05vdGVfSWNvbigpCit7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX0ljb246OlNldEljb25UeXBlKEZYX0lOVDMyIG5UeXBlKQoreworCW1fblR5cGUgPSBuVHlwZTsKK30KKwordm9pZCBDUFdMX05vdGVfSWNvbjo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpCit7CisJQ1BXTF9VdGlsczo6RHJhd0ljb25BcHBTdHJlYW0ocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX25UeXBlLCBHZXRDbGllbnRSZWN0KCksIAorCQl0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKSwgUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUiwgdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0Nsb3NlQm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworQ1BXTF9Ob3RlX0Nsb3NlQm94OjpDUFdMX05vdGVfQ2xvc2VCb3goKSA6IG1fYk1vdXNlRG93bihGQUxTRSkKK3sKK30KKworQ1BXTF9Ob3RlX0Nsb3NlQm94Ojp+Q1BXTF9Ob3RlX0Nsb3NlQm94KCkKK3sKK30KKwordm9pZCBDUFdMX05vdGVfQ2xvc2VCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQoreworCUNQV0xfQnV0dG9uOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlKTsKKworCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsKKwlyY0NsaWVudCA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJjQ2xpZW50LCAyLjBmKTsKKworCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CisJZ3NkLm1fTGluZVdpZHRoID0gMS4wZjsKKworCUNGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7CisKKwlpZiAobV9iTW91c2VEb3duKQorCXsKKwkJcmNDbGllbnQubGVmdCArPSAwLjVmOworCQlyY0NsaWVudC5yaWdodCArPSAwLjVmOworCQlyY0NsaWVudC50b3AgLT0gMC41ZjsKKwkJcmNDbGllbnQuYm90dG9tIC09IDAuNWY7CisJfQorCisJcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CisJcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9NT1ZFVE8pOworCXBhdGhDcm9zcy5TZXRQb2ludCgxLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQudG9wLCBGWFBUX0xJTkVUTyk7CisJcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LnRvcCwgRlhQVF9NT1ZFVE8pOworCXBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CisJCisJcERldmljZS0+RHJhd1BhdGgoJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCAKKwkJMCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLCBGWEZJTExfQUxURVJOQVRFKTsKK30KKworRlhfQk9PTCBDUFdMX05vdGVfQ2xvc2VCb3g6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKK3sKKwlTZXRCb3JkZXJTdHlsZShQQlNfSU5TRVQpOworCUludmFsaWRhdGVSZWN0KE5VTEwpOworCisJbV9iTW91c2VEb3duID0gVFJVRTsKKworCXJldHVybiBDUFdMX0J1dHRvbjo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZyk7Cit9CisKK0ZYX0JPT0wJQ1BXTF9Ob3RlX0Nsb3NlQm94OjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCW1fYk1vdXNlRG93biA9IEZBTFNFOworCisJU2V0Qm9yZGVyU3R5bGUoUEJTX0JFVkVMRUQpOworCUludmFsaWRhdGVSZWN0KE5VTEwpOworCisJcmV0dXJuIENQV0xfQnV0dG9uOjpPbkxCdXR0b25VcChwb2ludCxuRmxhZyk7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfQ29udGVudHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX05vdGVfQ29udGVudHM6OkNQV0xfTm90ZV9Db250ZW50cygpIDogbV9wRWRpdChOVUxMKQoreworfQorCitDUFdMX05vdGVfQ29udGVudHM6On5DUFdMX05vdGVfQ29udGVudHMoKQoreworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX05vdGVfQ29udGVudHM6OkdldENsYXNzTmFtZSgpIGNvbnN0Cit7CisJcmV0dXJuICJDUFdMX05vdGVfQ29udGVudHMiOworfQorCit2b2lkIENQV0xfTm90ZV9Db250ZW50czo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJbV9wRWRpdCA9IG5ldyBDUFdMX05vdGVfRWRpdDsKKwlQV0xfQ1JFQVRFUEFSQU0gZWNwID0gY3A7CisJZWNwLnBQYXJlbnRXbmQgPSB0aGlzOworCWVjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTVVMVElMSU5FIHwgUEVTX0FVVE9SRVRVUk4gfCBQRVNfVEVYVE9WRVJGTE9XIHwgUEVTX1VORE8gfCBQRVNfU1BFTExDSEVDSzsKKworCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CisJbV9wRWRpdC0+Q3JlYXRlKGVjcCk7CisJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOworfQorCit2b2lkIENQV0xfTm90ZV9Db250ZW50czo6U2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpCit7CisJaWYgKG1fcEVkaXQpCisJeworCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOworCQltX3BFZGl0LT5TZXRUZXh0KHNUZXh0KTsKKwkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOworCQlPbk5vdGlmeShtX3BFZGl0LCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsJCQorCX0KK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRUZXh0KCkgY29uc3QKK3sKKwlpZiAobV9wRWRpdCkKKwkJcmV0dXJuIG1fcEVkaXQtPkdldFRleHQoKTsKKworCXJldHVybiBMIiI7Cit9CisKK0NQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6Q3JlYXRlU3ViSXRlbSgpCit7CisJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gbmV3IENQV0xfTm90ZUl0ZW07CisJUFdMX0NSRUFURVBBUkFNIGljcCA9IHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKTsKKwlpY3AucFBhcmVudFduZCA9IHRoaXM7CisJaWNwLmR3RmxhZ3MgPSAgUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEUgfCBQV1NfQkFDS0dST1VORDsKKwlwTm90ZUl0ZW0tPkNyZWF0ZShpY3ApOworCisJcE5vdGVJdGVtLT5PbkNyZWF0ZU5vdGVJdGVtKCk7CisJCisJcE5vdGVJdGVtLT5SZXNldFN1YmplY3ROYW1lKG1fYUNoaWxkcmVuLkdldFNpemUoKSAtIDEpOworCisJRlhfU1lTVEVNVElNRSBzdDsKKwlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IHRoaXMtPkdldFN5c3RlbUhhbmRsZXIoKSkKKwkJc3QgPSBwU0gtPkdldExvY2FsVGltZSgpOworCXBOb3RlSXRlbS0+U2V0RGF0ZVRpbWUoc3QpOworCisJcE5vdGVJdGVtLT5TZXRDb250ZW50cyhMIiIpOworCisJdGhpcy0+T25Ob3RpZnkocE5vdGVJdGVtLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsJCisKKwlyZXR1cm4gcE5vdGVJdGVtOworfQorCitGWF9JTlQzMiBDUFdMX05vdGVfQ29udGVudHM6OkNvdW50U3ViSXRlbXMoKSBjb25zdAoreworCXJldHVybiBtX2FDaGlsZHJlbi5HZXRTaXplKCkgLSAxOworfQorCitJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVfQ29udGVudHM6OkdldFN1Ykl0ZW1zKEZYX0lOVDMyIGluZGV4KSBjb25zdAoreworCUZYX0lOVDMyIG5JbmRleCA9IGluZGV4ICsgMTsKKworCWlmIChuSW5kZXggPiAwICYmIG5JbmRleCA8IG1fYUNoaWxkcmVuLkdldFNpemUoKSkKKwkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChuSW5kZXgpKQorCQl7CisJCQlBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOworCQkJQ1BXTF9Ob3RlSXRlbSogcEl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOworCQkJcmV0dXJuIHBJdGVtOworCQl9CisJcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkKK3sKKwlGWF9JTlQzMiBuSW5kZXggPSB0aGlzLT5HZXRJdGVtSW5kZXgoKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSk7CisKKwlpZiAobkluZGV4ID4gMCkKKwl7CisJCWlmIChDUFdMX05vdGVJdGVtKiBwUFdMTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcE5vdGVJdGVtKQorCQl7CisJCQlwUFdMTm90ZUl0ZW0tPktpbGxGb2N1cygpOworCQkJcFBXTE5vdGVJdGVtLT5EZXN0cm95KCk7CisJCQlkZWxldGUgcFBXTE5vdGVJdGVtOworCQl9CisKKwkJZm9yIChGWF9JTlQzMiBpPW5JbmRleCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJeworCQkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKKwkJCXsKKwkJCQlBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOworCQkJCUNQV0xfTm90ZUl0ZW0qIHBJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKKwkJCQlwSXRlbS0+UmVzZXRTdWJqZWN0TmFtZShpKTsKKwkJCX0KKwkJfQorCisJCXRoaXMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOworCX0KK30KKworSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRIaXROb3RlSXRlbShjb25zdCBDUERGX1BvaW50JiBwb2ludCkKK3sKKwlDUERGX1BvaW50IHB0ID0gdGhpcy0+UGFyZW50VG9DaGlsZChwb2ludCk7CisKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpCisJCXsKKwkJCWlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikKKwkJCXsKKwkJCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOworCQkJCWlmIChJUFdMX05vdGVJdGVtKiBwUmV0ID0gcE5vdGVJdGVtLT5HZXRIaXROb3RlSXRlbShwdCkpCisJCQkJCXJldHVybiBwUmV0OworCQkJfQorCQl9CisJfQorCXJldHVybiBOVUxMOworfQorCit2b2lkIENQV0xfTm90ZV9Db250ZW50czo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKK3sKKwlzd2l0Y2ggKG1zZykKKwl7CisJY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOgorCQl7CisJCQlGWF9JTlQzMiBuSW5kZXggPSB0aGlzLT5HZXRJdGVtSW5kZXgocFduZCk7CisJCQlpZiAobkluZGV4IDwgMCkgbkluZGV4ID0gMDsKKworCQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsJCisJCQl0aGlzLT5SZXNldENvbnRlbnQobkluZGV4KTsKKwkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKKworCQkJZm9yIChGWF9JTlQzMiBpPW5JbmRleCsxLCBzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJCXsKKwkJCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQorCQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOworCQkJfQorCisJCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCisJCQl7CisJCQkJcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CisJCQl9CisJCX0KKwkJcmV0dXJuOworCWNhc2UgUE5NX1NDUk9MTFdJTkRPVzoKKwkJdGhpcy0+U2V0U2Nyb2xsUG9zKENQREZfUG9pbnQoMC4wZiwgKihGWF9GTE9BVCopbFBhcmFtKSk7CisJCXRoaXMtPlJlc2V0RmFjZSgpOworCQlJbnZhbGlkYXRlUmVjdChOVUxMKTsKKwkJcmV0dXJuOwkJCisJY2FzZSBQTk1fU0VUQ0FSRVRJTkZPOgorCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQorCQl7CisJCQlQV0xfQ0FSRVRfSU5GTyBuZXdJbmZvID0gKnBJbmZvOworCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CisJCQluZXdJbmZvLnB0SGVhZCA9IHRoaXMtPkNoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CisJCQluZXdJbmZvLnB0Rm9vdCA9IHRoaXMtPkNoaWxkVG9QYXJlbnQocEluZm8tPnB0Rm9vdCk7CisKKwkJCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkKKwkJCXsKKwkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoRlhfSU5UUFRSKSZuZXdJbmZvLCAwKTsKKwkJCX0KKwkJfQorCQlyZXR1cm47CisJY2FzZSBQTk1fTk9URVJFU0VUOgorCQl7CisJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwkKKwkJCXRoaXMtPlJlc2V0Q29udGVudCgwKTsKKwkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKKworCQkJZm9yIChGWF9JTlQzMiBpPTEsIHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQorCQkJeworCQkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpCisJCQkJCXBDaGlsZC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CisJCQl9CQorCisJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwkKKwkJCXRoaXMtPlJlc2V0Q29udGVudCgwKTsKKwkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKKwkJfQorCQlyZXR1cm47CisJfQorCisJQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOworfQorCitGWF9CT09MCUNQV0xfTm90ZV9Db250ZW50czo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmIChDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZykpIHJldHVybiBUUlVFOworCisJaWYgKCFtX3BFZGl0LT5Jc0ZvY3VzZWQoKSkKKwl7CisJCW1fcEVkaXQtPlNldEZvY3VzKCk7CisJfQorCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpTZXRFZGl0Rm9jdXMoRlhfQk9PTCBiTGFzdCkKK3sKKwlpZiAoIW1fcEVkaXQtPklzRm9jdXNlZCgpKQorCXsKKwkJbV9wRWRpdC0+U2V0Rm9jdXMoKTsKKwkJbV9wRWRpdC0+U2V0Q2FyZXQoYkxhc3QgPyBtX3BFZGl0LT5HZXRUb3RhbFdvcmRzKCkgOiAwKTsKKwl9Cit9CisKK0NQV0xfRWRpdCogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRFZGl0KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wRWRpdDsKK30KKwordm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKQoreworCWlmICghYkVuYWJsZWQpCisJCW1fcEVkaXQtPkFkZEZsYWcoUFdTX1JFQURPTkxZKTsKKwllbHNlCisJCW1fcEVkaXQtPlJlbW92ZUZsYWcoUFdTX1JFQURPTkxZKTsKKworCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQorCXsKKwkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKKwkJeworCQkJaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKQorCQkJeworCQkJCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7CisJCQkJcE5vdGVJdGVtLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOworCQkJfQorCQl9CisJfQorfQorCit2b2lkIENQV0xfTm90ZV9Db250ZW50czo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKQoreworCWlmICghYkVuYWJsZWQpCisJCW1fcEVkaXQtPkFkZEZsYWcoUEVTX05PUkVBRCk7CisJZWxzZQorCQltX3BFZGl0LT5SZW1vdmVGbGFnKFBFU19OT1JFQUQpOworCisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQorCQl7CisJCQlpZiAocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpCisJCQl7CisJCQkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKKwkJCQlwTm90ZUl0ZW0tPkVuYWJsZVJlYWQoYkVuYWJsZWQpOworCQkJfQorCQl9CisJfQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZUl0ZW0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX05vdGVJdGVtOjpDUFdMX05vdGVJdGVtKCkgOgorCW1fcFByaXZhdGVEYXRhKE5VTEwpLAorCW1fcFN1YmplY3QoTlVMTCksCisJbV9wRGF0ZVRpbWUoTlVMTCksCisJbV9wQ29udGVudHMoTlVMTCksCisJbV9zQXV0aG9yKEwiIiksCisJbV9mT2xkSXRlbUhlaWdodCgwLjBmKSwKKwltX2JTaXplQ2hhbmdlZChGQUxTRSksCisJbV9iQWxsb3dNb2RpZnkoVFJVRSkKK3sKK30KKworQ1BXTF9Ob3RlSXRlbTo6fkNQV0xfTm90ZUl0ZW0oKQoreworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRDbGFzc05hbWUoKSBjb25zdAoreworCXJldHVybiAiQ1BXTF9Ob3RlSXRlbSI7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlSXRlbTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJQ1BXTF9Db2xvciBzVGV4dENvbG9yOworCisJaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpKSkKKwkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CisJZWxzZQorCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKKworCW1fcFN1YmplY3QgPSBuZXcgQ1BXTF9MYWJlbDsKKwlQV0xfQ1JFQVRFUEFSQU0gc2NwID0gY3A7CisJc2NwLnBQYXJlbnRXbmQgPSB0aGlzOworCXNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7CisJc2NwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOworCW1fcFN1YmplY3QtPkNyZWF0ZShzY3ApOworCisJbV9wRGF0ZVRpbWUgPSBuZXcgQ1BXTF9MYWJlbDsKKwlQV0xfQ1JFQVRFUEFSQU0gZGNwID0gY3A7CisJZGNwLnBQYXJlbnRXbmQgPSB0aGlzOworCWRjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfUklHSFQgfCBQRVNfVE9QOworCWRjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKKwltX3BEYXRlVGltZS0+Q3JlYXRlKGRjcCk7CisKKwltX3BDb250ZW50cyA9IG5ldyBDUFdMX05vdGVfQ29udGVudHM7CisJUFdMX0NSRUFURVBBUkFNIGNjcCA9IGNwOworCWNjcC5wUGFyZW50V25kID0gdGhpczsKKwkvL2NjcC5zQmFja2dyb3VuZENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKKwljY3Auc0JhY2tncm91bmRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZik7CisJY2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CQUNLR1JPVU5EOworCW1fcENvbnRlbnRzLT5DcmVhdGUoY2NwKTsKKwltX3BDb250ZW50cy0+U2V0SXRlbVNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOworCW1fcENvbnRlbnRzLT5TZXRUb3BTcGFjZShQT1BVUF9JVEVNX1NQQUNFKTsKKwltX3BDb250ZW50cy0+U2V0Qm90dG9tU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlSXRlbTo6UmVQb3NDaGlsZFduZCgpCit7CisJaWYgKHRoaXMtPklzVmFsaWQoKSkKKwl7CisJCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOworCQlBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7CisJCUFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsKKworCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisKKwkJQ1BERl9SZWN0IHJjU3ViamVjdCA9IHJjQ2xpZW50OworCQlyY1N1YmplY3QubGVmdCArPSBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOworCQlyY1N1YmplY3QudG9wID0gcmNDbGllbnQudG9wOworCQlyY1N1YmplY3QucmlnaHQgPSBQV0xfTUlOKHJjU3ViamVjdC5sZWZ0ICsgbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwgcmNDbGllbnQucmlnaHQpOworCQlyY1N1YmplY3QuYm90dG9tID0gcmNTdWJqZWN0LnRvcCAtIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CisJCXJjU3ViamVjdC5Ob3JtYWxpemUoKTsKKwkJbV9wU3ViamVjdC0+TW92ZShyY1N1YmplY3QsIFRSVUUsIEZBTFNFKTsKKwkJbV9wU3ViamVjdC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjU3ViamVjdCkpOworCisJCUNQREZfUmVjdCByY0RhdGUgPSByY0NsaWVudDsKKwkJcmNEYXRlLnJpZ2h0IC09IFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CisJCXJjRGF0ZS5sZWZ0ID0gUFdMX01BWChyY0RhdGUucmlnaHQgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpIC0gMS4wZiwgcmNTdWJqZWN0LnJpZ2h0KTsKKwkJcmNEYXRlLmJvdHRvbSA9IHJjRGF0ZS50b3AgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKKwkJcmNEYXRlLk5vcm1hbGl6ZSgpOworCQltX3BEYXRlVGltZS0+TW92ZShyY0RhdGUsIFRSVUUsIEZBTFNFKTsKKwkJbV9wRGF0ZVRpbWUtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0RhdGUpKTsKKworCQlDUERGX1JlY3QgcmNDb250ZW50cyA9IHJjQ2xpZW50OworCQlyY0NvbnRlbnRzLmxlZnQgKz0gMS4wZjsKKwkJcmNDb250ZW50cy5yaWdodCAtPSAxLjBmOworCQlyY0NvbnRlbnRzLnRvcCA9IHJjRGF0ZS5ib3R0b20gLSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NOworCQlyY0NvbnRlbnRzLmJvdHRvbSArPSBQT1BVUF9JVEVNX0JPVFRPTVdJRFRIOworCQlyY0NvbnRlbnRzLk5vcm1hbGl6ZSgpOworCQltX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBUUlVFLCBGQUxTRSk7CisJCW1fcENvbnRlbnRzLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDb250ZW50cykpOworCX0KKworCVNldENsaXBSZWN0KENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KEdldFdpbmRvd1JlY3QoKSwxLjBmKSk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0UHJpdmF0ZURhdGEodm9pZCogcERhdGEpCit7CisJbV9wUHJpdmF0ZURhdGEgPSBwRGF0YTsKK30KKwordm9pZCBDUFdMX05vdGVJdGVtOjpTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQoreworCUNQV0xfQ29sb3Igc0JLID0gY29sb3I7CisJdGhpcy0+U2V0QmFja2dyb3VuZENvbG9yKHNCSyk7CisKKwlDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CisKKwlpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUoc0JLKSkKKwkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CisJZWxzZQorCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKKworCXRoaXMtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKKwlpZiAobV9wU3ViamVjdCkKKwkJbV9wU3ViamVjdC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOworCWlmIChtX3BEYXRlVGltZSkKKwkJbV9wRGF0ZVRpbWUtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKKworCXRoaXMtPkludmFsaWRhdGVSZWN0KE5VTEwpOworCisJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkKKwl7CisJCXBOb3RpZnktPk9uU2V0QmtDb2xvcih0aGlzKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0U3ViamVjdE5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKQoreworCWlmIChtX3BTdWJqZWN0KQorCXsKKwkJbV9wU3ViamVjdC0+U2V0VGV4dChzTmFtZSk7CQorCX0KKworCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCisJeworCQlwTm90aWZ5LT5PblNldFN1YmplY3ROYW1lKHRoaXMpOworCX0KK30KKwordm9pZCBDUFdMX05vdGVJdGVtOjpTZXRBdXRob3JOYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkKK3sKKwltX3NBdXRob3IgPSBzTmFtZTsKKwlSZXNldFN1YmplY3ROYW1lKC0xKTsJCisKKwlpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQorCXsKKwkJcE5vdGlmeS0+T25TZXRBdXRob3JOYW1lKHRoaXMpOworCX0KK30KKwordm9pZCBDUFdMX05vdGVJdGVtOjpSZXNldFN1YmplY3ROYW1lKEZYX0lOVDMyIG5JdGVtSW5kZXgpCit7CisJaWYgKG5JdGVtSW5kZXggPCAwKQorCXsKKwkJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCisJCXsKKwkJCUFTU0VSVChwUGFyZW50LT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlX0NvbnRlbnRzIik7CisKKwkJCUNQV0xfTm90ZV9Db250ZW50cyogcENvbnRlbnRzID0gKENQV0xfTm90ZV9Db250ZW50cyopcFBhcmVudDsKKwkJCW5JdGVtSW5kZXggPSBwQ29udGVudHMtPkdldEl0ZW1JbmRleCh0aGlzKTsKKwkJfQorCX0KKworCWNvbnN0IENQV0xfTm90ZSogcE5vdGUgPSBHZXROb3RlKCk7CisJQVNTRVJUKHBOb3RlICE9IE5VTEwpOworCisJQ0ZYX1dpZGVTdHJpbmcgc1N1YmplY3Q7CisJc1N1YmplY3QuRm9ybWF0KHBOb3RlLT5HZXRSZXBseVN0cmluZygpLCBuSXRlbUluZGV4KTsKKworCWlmICghbV9zQXV0aG9yLklzRW1wdHkoKSkKKwl7CisJCQorCQlzU3ViamVjdCArPSBMIiAtICI7CisJCXNTdWJqZWN0ICs9IG1fc0F1dGhvcjsKKwl9CisJdGhpcy0+U2V0U3ViamVjdE5hbWUoc1N1YmplY3QpOworCXRoaXMtPlJlUG9zQ2hpbGRXbmQoKTsKK30KKwordm9pZCBDUFdMX05vdGVJdGVtOjpTZXREYXRlVGltZShGWF9TWVNURU1USU1FIHRpbWUpCit7CisJbV9kdE5vdGUgPSB0aW1lOworCQorCUNGWF9XaWRlU3RyaW5nIHN3VGltZTsKKwlzd1RpbWUuRm9ybWF0KChGWF9MUENXU1RSKUwiJTA0ZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQiLCB0aW1lLndZZWFyLCB0aW1lLndNb250aCwgdGltZS53RGF5LCB0aW1lLndIb3VyLCB0aW1lLndNaW51dGUsIHRpbWUud1NlY29uZCk7CisJaWYgKG1fcERhdGVUaW1lKQorCXsKKwkJbV9wRGF0ZVRpbWUtPlNldFRleHQoc3dUaW1lKTsKKwl9CisKKwl0aGlzLT5SZVBvc0NoaWxkV25kKCk7CisKKwlpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQorCXsKKwkJcE5vdGlmeS0+T25TZXREYXRlVGltZSh0aGlzKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0Q29udGVudHMoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNDb250ZW50cykKK3sKKwlpZiAobV9wQ29udGVudHMpCisJeworCQltX3BDb250ZW50cy0+U2V0VGV4dChzQ29udGVudHMpOworCX0KKworCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCisJeworCQlwTm90aWZ5LT5PblNldENvbnRlbnRzKHRoaXMpOworCX0KK30KKworQ1BXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0UGFyZW50Tm90ZUl0ZW0oKSBjb25zdAoreworCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQorCXsKKwkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKKwkJeworCQkJQVNTRVJUKHBHcmFuZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKKwkJCXJldHVybiAoQ1BXTF9Ob3RlSXRlbSopcEdyYW5kOworCQl9CisJfQorCisJcmV0dXJuIE5VTEw7Cit9CisKK0lQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudEl0ZW0oKSBjb25zdAoreworCXJldHVybiBHZXRQYXJlbnROb3RlSXRlbSgpOworfQorCitDUFdMX0VkaXQqIENQV0xfTm90ZUl0ZW06OkdldEVkaXQoKSBjb25zdAoreworCWlmIChtX3BDb250ZW50cykKKwkJcmV0dXJuIG1fcENvbnRlbnRzLT5HZXRFZGl0KCk7CisJcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQqIENQV0xfTm90ZUl0ZW06OkdldFByaXZhdGVEYXRhKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9wUHJpdmF0ZURhdGE7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldEF1dGhvck5hbWUoKSBjb25zdAoreworCXJldHVybiBtX3NBdXRob3I7IAorfQorCitDUFdMX0NvbG9yIENQV0xfTm90ZUl0ZW06OkdldEJrQ29sb3IoKSBjb25zdAoreworCXJldHVybiB0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKTsKK30KKworQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlSXRlbTo6R2V0Q29udGVudHMoKSBjb25zdAoreworCWlmIChtX3BDb250ZW50cykKKwkJcmV0dXJuIG1fcENvbnRlbnRzLT5HZXRUZXh0KCk7CisKKwlyZXR1cm4gTCIiOworfQorCitGWF9TWVNURU1USU1FIENQV0xfTm90ZUl0ZW06OkdldERhdGVUaW1lKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9kdE5vdGU7Cit9CisKK0NGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldFN1YmplY3ROYW1lKCkgY29uc3QKK3sKKwlpZiAobV9wU3ViamVjdCkKKwkJcmV0dXJuIG1fcFN1YmplY3QtPkdldFRleHQoKTsKKworCXJldHVybiBMIiI7Cit9CisKK0NQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkNyZWF0ZU5vdGVJdGVtKCkKK3sKKwlpZiAobV9wQ29udGVudHMpCisJCXJldHVybiBtX3BDb250ZW50cy0+Q3JlYXRlU3ViSXRlbSgpOworCisJcmV0dXJuIE5VTEw7Cit9CisKK0lQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkNyZWF0ZVN1Ykl0ZW0oKQoreworCXJldHVybiBDcmVhdGVOb3RlSXRlbSgpOworfQorCitGWF9JTlQzMiBDUFdMX05vdGVJdGVtOjpDb3VudFN1Ykl0ZW1zKCkgY29uc3QKK3sKKwlpZiAobV9wQ29udGVudHMpCisJCXJldHVybiBtX3BDb250ZW50cy0+Q291bnRTdWJJdGVtcygpOworCisJcmV0dXJuIDA7Cit9CisKK0lQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFN1Ykl0ZW1zKEZYX0lOVDMyIGluZGV4KSBjb25zdAoreworCWlmIChtX3BDb250ZW50cykKKwkJcmV0dXJuIG1fcENvbnRlbnRzLT5HZXRTdWJJdGVtcyhpbmRleCk7CisKKwlyZXR1cm4gTlVMTDsKK30KKwordm9pZCBDUFdMX05vdGVJdGVtOjpEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkKK3sKKwl0aGlzLT5LaWxsRm9jdXMoKTsKKworCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCisJeworCQlwTm90aWZ5LT5Pbkl0ZW1EZWxldGUocE5vdGVJdGVtKTsKKwl9CisKKwlpZiAobV9wQ29udGVudHMpCisJCW1fcENvbnRlbnRzLT5EZWxldGVTdWJJdGVtKHBOb3RlSXRlbSk7Cit9CisKK0lQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldEhpdE5vdGVJdGVtKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQoreworCUNQREZfUG9pbnQgcHQgPSB0aGlzLT5QYXJlbnRUb0NoaWxkKHBvaW50KTsKKworCWlmICh0aGlzLT5XbmRIaXRUZXN0KHB0KSkKKwl7CisJCWlmIChtX3BDb250ZW50cykKKwkJeworCQkJaWYgKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IG1fcENvbnRlbnRzLT5HZXRIaXROb3RlSXRlbShwdCkpCisJCQkJcmV0dXJuIHBOb3RlSXRlbTsKKwkJfQorCisJCXJldHVybiB0aGlzOworCX0KKworCXJldHVybiBOVUxMOworfQorCitJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpHZXRGb2N1c2VkTm90ZUl0ZW0oKSBjb25zdAoreworCWlmIChjb25zdCBDUFdMX1duZCogcFduZCA9IHRoaXMtPkdldEZvY3VzZWQoKSkKKwl7CisJCWlmIChwV25kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9FZGl0IikKKwkJeworCQkJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gcFduZC0+R2V0UGFyZW50V2luZG93KCkpCisJCQl7CisJCQkJQVNTRVJUKHBQYXJlbnQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVfQ29udGVudHMiKTsKKwkJCQkKKwkJCQlpZiAoQ1BXTF9XbmQqIHBHcmFuZCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpKQorCQkJCXsKKwkJCQkJQVNTRVJUKHBHcmFuZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsJCQkJCQorCQkJCQlyZXR1cm4gKENQV0xfTm90ZUl0ZW0qKXBHcmFuZDsKKwkJCQl9CisJCQl9CisJCX0KKwl9CisKKwlyZXR1cm4gTlVMTDsKK30KKworRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkKK3sKKwlpZiAoZkxpbWl0V2lkdGggPiAwKQorCXsKKwkJaWYgKCFtX2JTaXplQ2hhbmdlZCkKKwkJCXJldHVybiBtX2ZPbGRJdGVtSGVpZ2h0OworCisJCW1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CisKKwkJQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7CisJCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKKwkJQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOworCisJCUZYX0ZMT0FUIGZSZXQgPSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKKwkJRlhfRkxPQVQgZkJvcmRlcldpZHRoID0gKEZYX0ZMT0FUKXRoaXMtPkdldEJvcmRlcldpZHRoKCk7CisJCWlmIChmTGltaXRXaWR0aCA+IGZCb3JkZXJXaWR0aCAqIDIpCisJCQlmUmV0ICs9IG1fcENvbnRlbnRzLT5HZXRDb250ZW50c0hlaWdodChmTGltaXRXaWR0aCAtIGZCb3JkZXJXaWR0aCAqIDIpOworCQlmUmV0ICs9IFBPUFVQX0lURU1fSEVBRF9CT1RUT00gKyBQT1BVUF9JVEVNX0JPVFRPTVdJRFRIICsgZkJvcmRlcldpZHRoICogMjsKKworCQlyZXR1cm4gbV9mT2xkSXRlbUhlaWdodCA9IGZSZXQ7CisJfQorCisJcmV0dXJuIDA7Cit9CisKK0ZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1MZWZ0TWFyZ2luKCkKK3sKKwlyZXR1cm4gUE9QVVBfSVRFTV9TSURFTUFSR0lOOworfQorCitGWF9GTE9BVCBDUFdMX05vdGVJdGVtOjpHZXRJdGVtUmlnaHRNYXJnaW4oKQoreworCXJldHVybiBQT1BVUF9JVEVNX1NJREVNQVJHSU47Cit9CisKK0ZYX0JPT0wJQ1BXTF9Ob3RlSXRlbTo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJaWYgKCFtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQorCXsKKwkJU2V0Tm90ZUZvY3VzKEZBTFNFKTsKKwl9CisKKwlDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZyk7CisKKwlyZXR1cm4gVFJVRTsKK30KKworRlhfQk9PTAlDUFdMX05vdGVJdGVtOjpPblJCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCWlmICghbV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKKwl7CisJCVNldE5vdGVGb2N1cyhGQUxTRSk7CisJCVBvcHVwTm90ZUl0ZW1NZW51KHBvaW50KTsKKworCQlyZXR1cm4gVFJVRTsKKwl9CisKKwlyZXR1cm4gQ1BXTF9XbmQ6Ok9uUkJ1dHRvblVwKHBvaW50LG5GbGFnKTsKK30KKwordm9pZCBDUFdMX05vdGVJdGVtOjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQoreworCXN3aXRjaCAobXNnKQorCXsKKwljYXNlIFBOTV9OT1RFRURJVENIQU5HRUQ6CQorCQltX2JTaXplQ2hhbmdlZCA9IFRSVUU7CisKKwkJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCisJCXsKKwkJCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOworCQl9CisJCXJldHVybjsJCisJY2FzZSBQTk1fU0VUQ0FSRVRJTkZPOgorCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQorCQl7CisJCQlQV0xfQ0FSRVRfSU5GTyBuZXdJbmZvID0gKnBJbmZvOworCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CisJCQluZXdJbmZvLnB0SGVhZCA9IHRoaXMtPkNoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CisJCQluZXdJbmZvLnB0Rm9vdCA9IHRoaXMtPkNoaWxkVG9QYXJlbnQocEluZm8tPnB0Rm9vdCk7CisKKwkJCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkKKwkJCXsKKwkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoRlhfSU5UUFRSKSZuZXdJbmZvLCAwKTsKKwkJCX0KKwkJfQorCQlyZXR1cm47CisJY2FzZSBQTk1fTk9URVJFU0VUOgorCQltX2JTaXplQ2hhbmdlZCA9IFRSVUU7CisJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKKwkJCisJCXJldHVybjsKKwl9CisKKwlDUFdMX1duZDo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlSXRlbTo6UG9wdXBOb3RlSXRlbU1lbnUoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCit7CisJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkKKwl7CisJCUZYX0lOVDMyIHgseTsKKwkJUFdMdG9XbmQocG9pbnQsIHgsIHkpOworCQlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKKwkJCXBTSC0+Q2xpZW50VG9TY3JlZW4oR2V0QXR0YWNoZWRIV25kKCksIHgsIHkpOworCQlwTm90aWZ5LT5PblBvcHVwTWVudSh0aGlzLCB4LCB5KTsKKwl9Cit9CisKK2NvbnN0IENQV0xfTm90ZSogQ1BXTF9Ob3RlSXRlbTo6R2V0Tm90ZSgpIGNvbnN0Cit7CisJaWYgKGNvbnN0IENQV0xfV25kKiBwUm9vdCA9IHRoaXMtPkdldFJvb3RXbmQoKSkKKwl7CisJCUFTU0VSVChwUm9vdC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKKwkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBSb290OworCQlpZiAocE5vdGVJdGVtLT5Jc1RvcEl0ZW0oKSkKKwkJeworCQkJcmV0dXJuIChDUFdMX05vdGUqKXBOb3RlSXRlbTsKKwkJfQorCX0KKworCXJldHVybiBOVUxMOworfQorCitJUFdMX05vdGVOb3RpZnkqIENQV0xfTm90ZUl0ZW06OkdldE5vdGVOb3RpZnkoKSBjb25zdAoreworCWlmIChjb25zdCBDUFdMX05vdGUqIHBOb3RlID0gR2V0Tm90ZSgpKQorCQlyZXR1cm4gcE5vdGUtPkdldE5vdGVOb3RpZnkoKTsKKworCXJldHVybiBOVUxMOworfQorCit2b2lkIENQV0xfTm90ZUl0ZW06Ok9uQ3JlYXRlTm90ZUl0ZW0oKQoreworCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCisJeworCQlwTm90aWZ5LT5Pbkl0ZW1DcmVhdGUodGhpcyk7CisJfQorfQorCit2b2lkIENQV0xfTm90ZUl0ZW06Ok9uQ29udGVudHNWYWxpZGF0ZSgpCit7CisJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkKKwl7CisJCXBOb3RpZnktPk9uU2V0Q29udGVudHModGhpcyk7CisJfQorfQorCit2b2lkIENQV0xfTm90ZUl0ZW06OlNldE5vdGVGb2N1cyhGWF9CT09MIGJMYXN0KQoreworCW1fcENvbnRlbnRzLT5TZXRFZGl0Rm9jdXMoYkxhc3QpOworfQorCit2b2lkIENQV0xfTm90ZUl0ZW06OkVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKQoreworCW1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOworCW1fYkFsbG93TW9kaWZ5ID0gYkVuYWJsZWQ7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlSXRlbTo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKQoreworCW1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX05vdGU6OkNQV0xfTm90ZShJUG9wdXBfTm90ZSogcFBvcHVwTm90ZSwgSVBXTF9Ob3RlTm90aWZ5KiBwTm90ZU5vdGlmeSwgSVBXTF9Ob3RlSGFuZGxlciogcE5vdGVIYW5kbGVyKSA6IAorCW1fcEF1dGhvcihOVUxMKSwKKwltX3BJY29uKE5VTEwpLAorCW1fcENsb3NlQm94KE5VTEwpLAorCW1fcENvbnRlbnRzQmFyKE5VTEwpLAorCW1fcExCQm94KE5VTEwpLAorCW1fcFJCQm94KE5VTEwpLAorCW1fcE9wdGlvbnMoTlVMTCksCisJbV9iUmVzaXppbmcoRkFMU0UpLAorCW1fcmNDYXB0aW9uKDAsMCwwLDApLAorCW1fcE5vdGVOb3RpZnkocE5vdGVOb3RpZnkpLAorCW1fYkVuYWxibGVOb3RpZnkoVFJVRSksCisJbV9wUG9wdXBOb3RlKHBQb3B1cE5vdGUpLAorCW1fcE5vdGVIYW5kbGVyKHBOb3RlSGFuZGxlcikKK3sKK30KKworQ1BXTF9Ob3RlOjp+Q1BXTF9Ob3RlKCkKK3sKK30KKworSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlOjpSZXBseSgpCit7CisJcmV0dXJuIENyZWF0ZU5vdGVJdGVtKCk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVOb3RpZnkoRlhfQk9PTCBiRW5hYmxlZCkKK3sKKwltX2JFbmFsYmxlTm90aWZ5ID0gYkVuYWJsZWQ7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlOjpSZVBvc0NoaWxkV25kKCkKK3sKKwlSZVBvc05vdGVDaGlsZHJlbigpOworCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKKwlSZXNldFNjcm9sbEJhcigpOworCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKKwl0aGlzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKKwkvL82ssr0KKwlpZiAoY29uc3QgQ1BXTF9XbmQqIHBXbmQgPSB0aGlzLT5HZXRGb2N1c2VkKCkpCisJeworCQlpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpCisJCXsKKwkJCUNQV0xfRWRpdCogcEVkaXQgPSAoQ1BXTF9FZGl0KilwV25kOworCQkJcEVkaXQtPlNldENhcmV0KHBFZGl0LT5HZXRDYXJldCgpKTsKKwkJfQorCX0KKwkvL0NQREZfUG9pbnQgcHROZXcgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CisJLy9tX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOworfQorCitGWF9CT09MIENQV0xfTm90ZTo6UmVzZXRTY3JvbGxCYXIoKQoreworCUZYX0JPT0wgYlNjcm9sbENoYW5nZWQgPSBGQUxTRTsKKworCWlmIChTY3JvbGxCYXJTaG91bGRWaXNpYmxlKCkpCisJeworCQlpZiAoIW1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKKwkJeworCQkJbV9wQ29udGVudHNCYXItPlNldFZpc2libGUoVFJVRSk7CisJCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQorCQkJeworCQkJCW1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKKwkJCQliU2Nyb2xsQ2hhbmdlZCA9IFRSVUU7CisJCQl9CisJCX0JCisJfQorCWVsc2UKKwl7CisJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCisJCXsKKwkJCW1fcENvbnRlbnRzQmFyLT5TZXRWaXNpYmxlKEZBTFNFKTsKKwkJCW1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKKworCQkJYlNjcm9sbENoYW5nZWQgPSBUUlVFOworCQl9CisJfQorCisJaWYgKGJTY3JvbGxDaGFuZ2VkKQorCXsKKwkJQ1BERl9SZWN0IHJjTm90ZSA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0V2luZG93UmVjdCgpOworCQlyY0NvbnRlbnRzLnJpZ2h0ID0gcmNOb3RlLnJpZ2h0IC0gMy4wZjsKKwkJaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKKwkJCXJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsKKwkJbV9wQ29udGVudHMtPk1vdmUocmNDb250ZW50cywgVFJVRSwgVFJVRSk7CisJCW1fcENvbnRlbnRzLT5TZXRTY3JvbGxQb3MoQ1BERl9Qb2ludCgwLjBmLDAuMGYpKTsKKwkJbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOworCX0KKworCXJldHVybiBiU2Nyb2xsQ2hhbmdlZDsKK30KKworRlhfQk9PTCBDUFdMX05vdGU6OlNjcm9sbEJhclNob3VsZFZpc2libGUoKQoreworCUNQREZfUmVjdCByY0NvbnRlbnRzRmFjdCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxBcmVhKCk7CisJQ1BERl9SZWN0IHJjQ29udGVudHNDbGllbnQgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOworCisJcmV0dXJuIHJjQ29udGVudHNGYWN0LkhlaWdodCgpID4gcmNDb250ZW50c0NsaWVudC5IZWlnaHQoKTsJCit9CisKK3ZvaWQgQ1BXTF9Ob3RlOjpTZXRPcHRpb25zVGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpCit7CisJaWYgKG1fcE9wdGlvbnMpCisJCW1fcE9wdGlvbnMtPlNldFRleHQoc1RleHQpOworCisJUmVQb3NOb3RlQ2hpbGRyZW4oKTsKK30KKwordm9pZCBDUFdMX05vdGU6OlJlUG9zTm90ZUNoaWxkcmVuKCkKK3sKKwlpZiAobV9iUmVzaXppbmcpIHJldHVybjsKKworCW1fYlJlc2l6aW5nID0gVFJVRTsKKworCWlmICh0aGlzLT5Jc1ZhbGlkKCkpCisJeworCQlBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsKKwkJQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOworCQlBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CisJCUFTU0VSVChtX3BBdXRob3IgIT0gTlVMTCk7CisJCUFTU0VSVChtX3BDbG9zZUJveCAhPSBOVUxMKTsKKwkJQVNTRVJUKG1fcEljb24gIT0gTlVMTCk7CisJCUFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsKKwkJQVNTRVJUKG1fcFJCQm94ICE9IE5VTEwpOworCQlBU1NFUlQobV9wQ29udGVudHNCYXIgIT0gTlVMTCk7CisJCUFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOworCisJCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKworCQlDUERGX1JlY3QgcmNJY29uID0gcmNDbGllbnQ7CisJCXJjSWNvbi50b3AgLT0gMi4wZjsKKwkJcmNJY29uLnJpZ2h0ID0gcmNJY29uLmxlZnQgKyAxNC4wZjsKKwkJcmNJY29uLmJvdHRvbSA9IHJjSWNvbi50b3AgLSAxNC4wZjsKKwkJcmNJY29uLk5vcm1hbGl6ZSgpOworCQltX3BJY29uLT5Nb3ZlKHJjSWNvbiwgVFJVRSwgRkFMU0UpOworCQltX3BJY29uLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNJY29uKSk7CisKKwkJQ1BERl9SZWN0IHJjQ2xvc2VCb3ggPSByY0NsaWVudDsKKwkJcmNDbG9zZUJveC5yaWdodCAtPSAxLjBmOworCQlyY0Nsb3NlQm94LnRvcCAtPSAxLjBmOworCQlyY0Nsb3NlQm94LmxlZnQgPSByY0Nsb3NlQm94LnJpZ2h0IC0gMTQuMGY7CisJCXJjQ2xvc2VCb3guYm90dG9tID0gcmNDbG9zZUJveC50b3AgLSAxNC4wZjsKKwkJcmNDbG9zZUJveC5Ob3JtYWxpemUoKTsKKwkJbV9wQ2xvc2VCb3gtPk1vdmUocmNDbG9zZUJveCwgVFJVRSwgRkFMU0UpOworCQltX3BDbG9zZUJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ2xvc2VCb3gpKTsKKworCQlDUERGX1JlY3QgcmNEYXRlID0gcmNDbGllbnQ7CisJCXJjRGF0ZS5yaWdodCA9IHJjQ2xvc2VCb3gubGVmdCAtIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CisJCXJjRGF0ZS5sZWZ0ID0gUFdMX01BWChyY0RhdGUucmlnaHQgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpIC0gMS4wZiwgcmNJY29uLnJpZ2h0ICsgMS4wZik7CisJCXJjRGF0ZS50b3AgPSByY0NsaWVudC50b3AgLSAyLjBmOworCQlyY0RhdGUuYm90dG9tID0gcmNEYXRlLnRvcCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOworCQlyY0RhdGUuTm9ybWFsaXplKCk7CisJCW1fcERhdGVUaW1lLT5Nb3ZlKHJjRGF0ZSwgVFJVRSwgRkFMU0UpOworCQltX3BEYXRlVGltZS0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjRGF0ZSkpOworCisJCUNQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsKKwkJcmNTdWJqZWN0LnRvcCA9IHJjQ2xpZW50LnRvcCAtIDIuMGY7CisJCXJjU3ViamVjdC5sZWZ0ID0gcmNJY29uLnJpZ2h0ICsgUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKKwkJcmNTdWJqZWN0LnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsIHJjRGF0ZS5sZWZ0IC0gMS4wZik7CisJCXJjU3ViamVjdC5ib3R0b20gPSByY1N1YmplY3QudG9wIC0gbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKKwkJcmNTdWJqZWN0Lk5vcm1hbGl6ZSgpOworCQltX3BTdWJqZWN0LT5Nb3ZlKHJjU3ViamVjdCwgVFJVRSwgRkFMU0UpOwkKKwkJbV9wU3ViamVjdC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjU3ViamVjdCkpOworCisJCUNQREZfUmVjdCByY09wdGlvbnMgPSByY0NsaWVudDsKKwkJcmNPcHRpb25zLmxlZnQgPSBQV0xfTUFYKHJjT3B0aW9ucy5yaWdodCAtIG1fcE9wdGlvbnMtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSwgcmNJY29uLnJpZ2h0ICsgMS4wZik7CisJCXJjT3B0aW9ucy50b3AgPSByY1N1YmplY3QuYm90dG9tIC0gNC4wZjsKKwkJcmNPcHRpb25zLmJvdHRvbSA9IHJjT3B0aW9ucy50b3AgLSBtX3BPcHRpb25zLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOworCQlyY09wdGlvbnMuTm9ybWFsaXplKCk7CisJCW1fcE9wdGlvbnMtPk1vdmUocmNPcHRpb25zLCBUUlVFLCBGQUxTRSk7CisJCW1fcE9wdGlvbnMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY09wdGlvbnMpKTsKKworCQlDUERGX1JlY3QgcmNBdXRob3IgPSByY0NsaWVudDsKKwkJcmNBdXRob3IudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7CisJCXJjQXV0aG9yLmxlZnQgPSByY1N1YmplY3QubGVmdDsKKwkJcmNBdXRob3IucmlnaHQgPSBQV0xfTUlOKHJjU3ViamVjdC5sZWZ0ICsgbV9wQXV0aG9yLT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgKyAxLjBmLCByY09wdGlvbnMubGVmdCAtIDEuMGYpOworCQlyY0F1dGhvci5ib3R0b20gPSByY0F1dGhvci50b3AgLSBtX3BBdXRob3ItPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CisJCXJjQXV0aG9yLk5vcm1hbGl6ZSgpOworCQltX3BBdXRob3ItPk1vdmUocmNBdXRob3IsIFRSVUUsIEZBTFNFKTsKKwkJbV9wQXV0aG9yLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNBdXRob3IpKTsKKworCQlDUERGX1JlY3QgcmNMQkJveCA9IHJjQ2xpZW50OworCQlyY0xCQm94LnRvcCA9IHJjTEJCb3guYm90dG9tICsgNy4wZjsKKwkJcmNMQkJveC5yaWdodCA9IHJjTEJCb3gubGVmdCArIDcuMGY7CisJCXJjTEJCb3guTm9ybWFsaXplKCk7CisJCW1fcExCQm94LT5Nb3ZlKHJjTEJCb3gsIFRSVUUsIEZBTFNFKTsKKwkJbV9wTEJCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0xCQm94KSk7CisKKwkJQ1BERl9SZWN0IHJjUkJCb3ggPSByY0NsaWVudDsKKwkJcmNSQkJveC50b3AgPSByY1JCQm94LmJvdHRvbSArIDcuMGY7CisJCXJjUkJCb3gubGVmdCA9IHJjUkJCb3gucmlnaHQgLSA3LjBmOworCQlyY1JCQm94Lk5vcm1hbGl6ZSgpOworCQltX3BSQkJveC0+TW92ZShyY1JCQm94LCBUUlVFLCBGQUxTRSk7CisJCW1fcFJCQm94LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNSQkJveCkpOworCisJCUNQREZfUmVjdCByY0NvbnRlbnRzID0gcmNDbGllbnQ7CisJCXJjQ29udGVudHMudG9wID0gcmNBdXRob3IuYm90dG9tIC0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTTsKKwkJcmNDb250ZW50cy5sZWZ0ICs9IDMuMGY7CisJCXJjQ29udGVudHMucmlnaHQgLT0gMy4wZjsKKwkJaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKKwkJCXJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsKKwkJcmNDb250ZW50cy5ib3R0b20gKz0gMTQuMGY7CisJCXJjQ29udGVudHMuTm9ybWFsaXplKCk7CisJCW1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIEZBTFNFLCBGQUxTRSk7CisJCW1fcENvbnRlbnRzLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDb250ZW50cykpOworCisJCUNQREZfUmVjdCByY0NvbnRlbnRzQmFyID0gcmNDb250ZW50czsKKwkJcmNDb250ZW50c0Jhci5yaWdodCA9IHJjQ2xpZW50LnJpZ2h0IC0gMy4wZjsKKwkJcmNDb250ZW50c0Jhci5sZWZ0ID0gcmNDb250ZW50c0Jhci5yaWdodCAtIFBXTF9TQ1JPTExCQVJfV0lEVEg7CisJCXJjQ29udGVudHNCYXIuTm9ybWFsaXplKCk7CisJCW1fcENvbnRlbnRzQmFyLT5Nb3ZlKHJjQ29udGVudHNCYXIsIFRSVUUsIEZBTFNFKTsKKwkJCisJCW1fcmNDYXB0aW9uID0gcmNDbGllbnQ7CisJCW1fcmNDYXB0aW9uLmJvdHRvbSA9IHJjQ29udGVudHMudG9wOworCX0KKworCW1fYlJlc2l6aW5nID0gRkFMU0U7Cit9CisKKy8vMC1ub3JtYWwgLyAxLWNhcHRpb24gLyAyLWxlZnRib3R0b20gY29ybmVyIC8gMy1yaWdodGJvdHRvbSBjb3JuZXIgLyA0LWNsb3NlIC8gNS1vcHRpb25zIAorRlhfSU5UMzIgQ1BXTF9Ob3RlOjpOb3RlSGl0VGVzdChjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3QKK3sKKwlBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7CisJQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOworCUFTU0VSVChtX3BBdXRob3IgIT0gTlVMTCk7CisJQVNTRVJUKG1fcEljb24gIT0gTlVMTCk7CisJQVNTRVJUKG1fcENvbnRlbnRzQmFyICE9IE5VTEwpOworCisJQVNTRVJUKG1fcENsb3NlQm94ICE9IE5VTEwpOworCUFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsKKwlBU1NFUlQobV9wUkJCb3ggIT0gTlVMTCk7CisJQVNTRVJUKG1fcE9wdGlvbnMgIT0gTlVMTCk7CisKKwlHZXRDbGllbnRSZWN0KCk7CisKKwlpZiAobV9wU3ViamVjdC0+V25kSGl0VGVzdChtX3BTdWJqZWN0LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOworCWlmIChtX3BEYXRlVGltZS0+V25kSGl0VGVzdChtX3BEYXRlVGltZS0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMTsKKwlpZiAobV9wQXV0aG9yLT5XbmRIaXRUZXN0KG1fcEF1dGhvci0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMTsKKwlpZiAobV9wSWNvbi0+V25kSGl0VGVzdChtX3BJY29uLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOworCisJaWYgKG1fcENvbnRlbnRzLT5XbmRIaXRUZXN0KG1fcENvbnRlbnRzLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAwOworCWlmIChtX3BDb250ZW50c0Jhci0+V25kSGl0VGVzdChtX3BDb250ZW50c0Jhci0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMDsKKworCWlmIChtX3BDbG9zZUJveC0+V25kSGl0VGVzdChtX3BDbG9zZUJveC0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gNDsKKwlpZiAobV9wTEJCb3gtPlduZEhpdFRlc3QobV9wTEJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDI7CisJaWYgKG1fcFJCQm94LT5XbmRIaXRUZXN0KG1fcFJCQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAzOworCWlmIChtX3BPcHRpb25zLT5XbmRIaXRUZXN0KG1fcE9wdGlvbnMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDU7CisKKwlyZXR1cm4gMTsKK30KKwordm9pZCBDUFdMX05vdGU6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQoreworCUNQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNwKTsKKworCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsKKworCWlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZSh0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKSkpCisJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOworCWVsc2UKKwkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CisKKwltX3BBdXRob3IgPSBuZXcgQ1BXTF9MYWJlbDsKKwlQV0xfQ1JFQVRFUEFSQU0gYWNwID0gY3A7CisJYWNwLnBQYXJlbnRXbmQgPSB0aGlzOworCWFjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7CisJYWNwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOworCW1fcEF1dGhvci0+Q3JlYXRlKGFjcCk7CSAKKworCW1fcENsb3NlQm94ID0gbmV3IENQV0xfTm90ZV9DbG9zZUJveDsKKwlQV0xfQ1JFQVRFUEFSQU0gY2NwID0gY3A7CisJY2NwLnBQYXJlbnRXbmQgPSB0aGlzOworCWNjcC5kd0JvcmRlcldpZHRoID0gMjsKKwljY3AubkJvcmRlclN0eWxlID0gUEJTX0JFVkVMRUQ7CisJY2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVI7CisJY2NwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOworCW1fcENsb3NlQm94LT5DcmVhdGUoY2NwKTsKKworCW1fcEljb24gPSBuZXcgQ1BXTF9Ob3RlX0ljb247CisJUFdMX0NSRUFURVBBUkFNIGljcCA9IGNwOworCWljcC5wUGFyZW50V25kID0gdGhpczsKKwlpY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOworCW1fcEljb24tPkNyZWF0ZShpY3ApOworCisJbV9wT3B0aW9ucyA9IG5ldyBDUFdMX05vdGVfT3B0aW9uczsKKwlQV0xfQ1JFQVRFUEFSQU0gb2NwID0gY3A7CisJb2NwLnBQYXJlbnRXbmQgPSB0aGlzOworCW9jcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEU7CisJb2NwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOworCW1fcE9wdGlvbnMtPkNyZWF0ZShvY3ApOworCisJbV9wTEJCb3ggPSBuZXcgQ1BXTF9Ob3RlX0xCQm94OworCVBXTF9DUkVBVEVQQVJBTSBsY3AgPSBjcDsKKwlsY3AucFBhcmVudFduZCA9IHRoaXM7CisJbGNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsKKwlsY3AuZUN1cnNvclR5cGUgPSBGWENUX05FU1c7CisJbGNwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOworCW1fcExCQm94LT5DcmVhdGUobGNwKTsKKworCW1fcFJCQm94ID0gbmV3IENQV0xfTm90ZV9SQkJveDsKKwlQV0xfQ1JFQVRFUEFSQU0gcmNwID0gY3A7CisJcmNwLnBQYXJlbnRXbmQgPSB0aGlzOworCXJjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQ7CisJcmNwLmVDdXJzb3JUeXBlID0gRlhDVF9OV1NFOworCXJjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKKwltX3BSQkJveC0+Q3JlYXRlKHJjcCk7CisKKwltX3BDb250ZW50c0JhciA9IG5ldyBDUFdMX1Njcm9sbEJhcihTQlRfVlNDUk9MTCk7CisJUFdMX0NSRUFURVBBUkFNIHNjcCA9IGNwOworCXNjcC5wUGFyZW50V25kID0gdGhpczsKKwlzY3Auc0JhY2tncm91bmRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZik7CisJc2NwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19CQUNLR1JPVU5EOworCW1fcENvbnRlbnRzQmFyLT5DcmVhdGUoc2NwKTsKKwltX3BDb250ZW50c0Jhci0+U2V0Tm90aWZ5Rm9yZXZlcihUUlVFKTsKK30KKwordm9pZCBDUFdMX05vdGU6OlNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkKK3sKKwlDUFdMX05vdGVJdGVtOjpTZXRTdWJqZWN0TmFtZShzTmFtZSk7CisJUmVQb3NDaGlsZFduZCgpOworfQorCit2b2lkIENQV0xfTm90ZTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCit7CisJaWYgKG1fcEF1dGhvcikKKwl7CisJCW1fcEF1dGhvci0+U2V0VGV4dChzTmFtZSk7CisJCVJlUG9zQ2hpbGRXbmQoKTsKKwl9CisKKwlpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQorCXsKKwkJcE5vdGlmeS0+T25TZXRBdXRob3JOYW1lKHRoaXMpOworCX0JCit9CisKK0NGWF9XaWRlU3RyaW5nIENQV0xfTm90ZTo6R2V0QXV0aG9yTmFtZSgpIGNvbnN0Cit7CisJaWYgKG1fcEF1dGhvcikKKwkJcmV0dXJuIG1fcEF1dGhvci0+R2V0VGV4dCgpOworCisJcmV0dXJuIEwiIjsKK30KKworRlhfQk9PTCBDUFdMX05vdGU6Ok9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKKwlDUERGX1JlY3QgcmNTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOworCUNQREZfUmVjdCByY0NvbnRlbnRzID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsKKworCWlmIChyY1Njcm9sbC50b3AgLSByY1Njcm9sbC5ib3R0b20gPiByY0NvbnRlbnRzLkhlaWdodCgpKQorCXsKKwkJQ1BERl9Qb2ludCBwdE5ldyA9IHB0U2Nyb2xsOworCisJCWlmICh6RGVsdGEgPiAwKQorCQkJcHROZXcueSArPSAzMDsKKwkJZWxzZQorCQkJcHROZXcueSAtPSAzMDsKKworCQlpZiAocHROZXcueSA+IHJjU2Nyb2xsLnRvcCkKKwkJCXB0TmV3LnkgPSByY1Njcm9sbC50b3A7CisJCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tICsgcmNDb250ZW50cy5IZWlnaHQoKSkKKwkJCXB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b20gKyByY0NvbnRlbnRzLkhlaWdodCgpOworCQlpZiAocHROZXcueSA8IHJjU2Nyb2xsLmJvdHRvbSkKKwkJCXB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b207CisKKwkJaWYgKHB0TmV3LnkgIT0gcHRTY3JvbGwueSkKKwkJeworCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOworCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9TQ1JPTExXSU5ET1csIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdE5ldy55KTsJCQkKKwkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHROZXcueSk7CisKKwkJCXJldHVybiBUUlVFOworCQl9CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCit2b2lkIENQV0xfTm90ZTo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKK3sKKwlzd2l0Y2ggKG1zZykKKwl7CisJY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOgorCQl7CisJCQlDUERGX1JlY3QgcmNTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOworCQkJCisKKwkJCVBXTF9TQ1JPTExfSU5GTyBzSW5mbzsKKwkJCXNJbmZvLmZDb250ZW50TWluID0gcmNTY3JvbGwuYm90dG9tOworCQkJc0luZm8uZkNvbnRlbnRNYXggPSByY1Njcm9sbC50b3A7CisJCQlzSW5mby5mUGxhdGVXaWR0aCA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCkuSGVpZ2h0KCk7CisJCQlzSW5mby5mU21hbGxTdGVwID0gMTMuMGY7CisJCQlzSW5mby5mQmlnU3RlcCA9IHNJbmZvLmZQbGF0ZVdpZHRoOworCisJCQlpZiAoRlhTWVNfbWVtY21wKCZtX09sZFNjcm9sbEluZm8sICZzSW5mbywgc2l6ZW9mKFBXTF9TQ1JPTExfSU5GTykpICE9IDApCisJCQl7CisJCQkJRlhfQk9PTCBiU2Nyb2xsQ2hhbmdlZCA9IEZBTFNFOworCisJCQkJaWYgKGxQYXJhbSA8IDMpIC8vt8DWucvA0a27tyBtYW50aXM6MTU3NTkKKwkJCQl7CisJCQkJCWJTY3JvbGxDaGFuZ2VkID0gUmVzZXRTY3JvbGxCYXIoKTsKKwkJCQkJaWYgKGJTY3JvbGxDaGFuZ2VkKQorCQkJCQl7CisJCQkJCQlsUGFyYW0rKzsKKwkJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKKwkJCQkJCXRoaXMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIGxQYXJhbSk7CisJCQkJCX0KKwkJCQl9CisJCQkJCisJCQkJaWYgKCFiU2Nyb2xsQ2hhbmdlZCkKKwkJCQl7CisJCQkJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCisJCQkJCXsKKwkJCQkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeShwV25kLCBQTk1fU0VUU0NST0xMSU5GTywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnNJbmZvKTsKKwkJCQkJCW1fT2xkU2Nyb2xsSW5mbyA9IHNJbmZvOworCisJCQkJCQlDUERGX1BvaW50IHB0U2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOworCQkJCQkJQ1BERl9Qb2ludCBwdE9sZCA9IHB0U2Nyb2xsOworCisJCQkJCQlpZiAocHRTY3JvbGwueSA+IHNJbmZvLmZDb250ZW50TWF4KQorCQkJCQkJCXB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1heDsKKwkJCQkJCWlmIChwdFNjcm9sbC55IDwgc0luZm8uZkNvbnRlbnRNaW4gKyBzSW5mby5mUGxhdGVXaWR0aCkKKwkJCQkJCQlwdFNjcm9sbC55ID0gc0luZm8uZkNvbnRlbnRNaW4gKyBzSW5mby5mUGxhdGVXaWR0aDsKKwkJCQkJCWlmIChwdFNjcm9sbC55IDwgc0luZm8uZkNvbnRlbnRNaW4pCisJCQkJCQkJcHRTY3JvbGwueSA9IHNJbmZvLmZDb250ZW50TWluOworCisJCQkJCQlpZiAocHRPbGQueSAhPSBwdFNjcm9sbC55KQorCQkJCQkJeworCQkJCQkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHRTY3JvbGwueSk7CisJCQkJCQkJbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOworCQkJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHRTY3JvbGwueSk7CisJCQkJCQl9CisJCQkJCX0KKwkJCQl9CisJCQl9CisJCX0KKworCQltX3BDb250ZW50cy0+SW52YWxpZGF0ZVJlY3QoTlVMTCk7CisKKwkJcmV0dXJuOworCWNhc2UgUE5NX1NDUk9MTFdJTkRPVzoKKwkJaWYgKG1fcENvbnRlbnRzKQorCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOworCQlyZXR1cm47CisJY2FzZSBQTk1fU0VUU0NST0xMUE9TOgorCQlpZiAobV9wQ29udGVudHNCYXIpCisJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkocFduZCxQTk1fU0VUU0NST0xMUE9TLHdQYXJhbSxsUGFyYW0pOworCQlyZXR1cm47CisJfQorCisJaWYgKG1zZyA9PSBQTk1fU0VUQ0FSRVRJTkZPICYmIElzVmFsaWQoKSkKKwl7CisJCWlmIChQV0xfQ0FSRVRfSU5GTyAqIHBJbmZvID0gKFBXTF9DQVJFVF9JTkZPKil3UGFyYW0pCisJCXsKKwkJCWlmIChtX3BDb250ZW50cykKKwkJCXsKKwkJCQlDUERGX1JlY3QgcmNDbGllbnQgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOworCQkJCWlmIChwSW5mby0+cHRIZWFkLnkgPiByY0NsaWVudC50b3ApCisJCQkJeworCQkJCQlDUERGX1BvaW50IHB0ID0gbV9wQ29udGVudHMtPk91dFRvSW4ocEluZm8tPnB0SGVhZCk7CisJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHQueSk7CisKKwkJCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKKwkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKKworCQkJCQlyZXR1cm47CisJCQkJfQorCQkJCQorCQkJCWlmIChwSW5mby0+cHRGb290LnkgPCByY0NsaWVudC5ib3R0b20pCisJCQkJeworCQkJCQlDUERGX1BvaW50IHB0ID0gbV9wQ29udGVudHMtPk91dFRvSW4ocEluZm8tPnB0Rm9vdCk7CisJCQkJCXB0LnkgKz0gcmNDbGllbnQuSGVpZ2h0KCk7CisJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHQueSk7CisKKwkJCQkJQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKKwkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKKworCQkJCQlyZXR1cm47CisJCQkJfQorCQkJfQorCQl9CisJfQorCisJQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlOjpTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQoreworCUNQV0xfTm90ZUl0ZW06OlNldEJrQ29sb3IoY29sb3IpOworCisJQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsKKwlDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CisJaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHNCSykpCisJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOworCWVsc2UKKwkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CisKKwlpZiAobV9wQ2xvc2VCb3gpCisJCW1fcENsb3NlQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CisJaWYgKG1fcEF1dGhvcikKKwkJbV9wQXV0aG9yLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CisJaWYgKG1fcE9wdGlvbnMpCisJCW1fcE9wdGlvbnMtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKKwlpZiAobV9wTEJCb3gpCisJCW1fcExCQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CisJaWYgKG1fcFJCQm94KQorCQltX3BSQkJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOworfQorCitGWF9CT09MCUNQV0xfTm90ZTo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJaWYgKG1fcE9wdGlvbnMtPlduZEhpdFRlc3QobV9wT3B0aW9ucy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQorCXsKKwkJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IHRoaXMtPkdldE5vdGVOb3RpZnkoKSkKKwkJeworCQkJRlhfSU5UMzIgeCwgeTsKKwkJCVBXTHRvV25kKHBvaW50LCB4LCB5KTsKKwkJCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQorCQkJCXBTSC0+Q2xpZW50VG9TY3JlZW4oR2V0QXR0YWNoZWRIV25kKCksIHgsIHkpOworCQkJdGhpcy0+S2lsbEZvY3VzKCk7CisJCQlwTm90aWZ5LT5PblBvcHVwTWVudSh4LCB5KTsKKworCQkJcmV0dXJuIFRSVUU7CisJCX0KKwl9CisKKwlyZXR1cm4gQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOworfQorCitGWF9CT09MCUNQV0xfTm90ZTo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKK3sKKwlyZXR1cm4gQ1BXTF9XbmQ6Ok9uUkJ1dHRvblVwKHBvaW50LG5GbGFnKTsKK30KKworY29uc3QgQ1BXTF9Ob3RlKiBDUFdMX05vdGU6OkdldE5vdGUoKSBjb25zdAoreworCXJldHVybiB0aGlzOworfQorCitJUFdMX05vdGVOb3RpZnkqIENQV0xfTm90ZTo6R2V0Tm90ZU5vdGlmeSgpIGNvbnN0Cit7CisJaWYgKG1fYkVuYWxibGVOb3RpZnkpCisJCXJldHVybiBtX3BOb3RlTm90aWZ5OworCisJcmV0dXJuIE5VTEw7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlOjpTZXRJY29uVHlwZShGWF9JTlQzMiBuVHlwZSkKK3sKKwlpZiAobV9wSWNvbikKKwkJbV9wSWNvbi0+U2V0SWNvblR5cGUoblR5cGUpOworfQorCit2b2lkIENQV0xfTm90ZTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpCit7CisJbV9wQ29udGVudHMtPkVuYWJsZU1vZGlmeShiRW5hYmxlZCk7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpCit7CisJbV9wQ29udGVudHMtPkVuYWJsZVJlYWQoYkVuYWJsZWQpOworfQorCitDRlhfV2lkZVN0cmluZyBDUFdMX05vdGU6OkdldFJlcGx5U3RyaW5nKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9zUmVwbHlTdHJpbmc7Cit9CisKK3ZvaWQgQ1BXTF9Ob3RlOjpTZXRSZXBseVN0cmluZyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKQoreworCW1fc1JlcGx5U3RyaW5nID0gc3RyaW5nOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5jcHAgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5jcHAKaW5kZXggZDUxZGU0ZC4uNzcyZTE4NCAxMDA2NDQKLS0tIGEvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9TY3JvbGxCYXIuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmNwcApAQCAtMSwxMzUzICsxLDEzNTMgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIg0KLQ0KLSNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpDQotI2RlZmluZSBJc0Zsb2F0QmlnZ2VyKGZhLGZiKQkJCQkoKGZhKSA+IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCi0jZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLGZiKQkJCQkoKGZhKSA8IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCi0jZGVmaW5lIElzRmxvYXRFcXVhbChmYSxmYikJCQkJCUlzRmxvYXRaZXJvKChmYSktKGZiKSkNCi0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFBXTF9GTE9BVFJBTkdFIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1QV0xfRkxPQVRSQU5HRTo6UFdMX0ZMT0FUUkFOR0UoKQ0KLXsNCi0JRGVmYXVsdCgpOw0KLX0NCi0NCi1QV0xfRkxPQVRSQU5HRTo6UFdMX0ZMT0FUUkFOR0UoRlhfRkxPQVQgbWluLEZYX0ZMT0FUIG1heCkNCi17DQotCVNldChtaW4sbWF4KTsNCi19DQotDQotdm9pZCBQV0xfRkxPQVRSQU5HRTo6RGVmYXVsdCgpDQotew0KLQlmTWluID0gMDsNCi0JZk1heCA9IDA7DQotfQ0KLQ0KLXZvaWQgUFdMX0ZMT0FUUkFOR0U6OlNldChGWF9GTE9BVCBtaW4sRlhfRkxPQVQgbWF4KQ0KLXsNCi0JaWYgKG1pbiA+IG1heCkNCi0Jew0KLQkJZk1pbiA9IG1heDsNCi0JCWZNYXggPSBtaW47DQotCX0NCi0JZWxzZQ0KLQl7DQotCQlmTWluID0gbWluOw0KLQkJZk1heCA9IG1heDsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MCVBXTF9GTE9BVFJBTkdFOjpJbihGWF9GTE9BVCB4KSBjb25zdA0KLXsNCi0JcmV0dXJuIChJc0Zsb2F0QmlnZ2VyKHgsZk1pbikgfHwgSXNGbG9hdEVxdWFsKHgsIGZNaW4pKSAmJiANCi0JCShJc0Zsb2F0U21hbGxlcih4LCBmTWF4KSB8fCBJc0Zsb2F0RXF1YWwoeCwgZk1heCkpOw0KLX0NCi0NCi1GWF9GTE9BVCBQV0xfRkxPQVRSQU5HRTo6R2V0V2lkdGgoKSBjb25zdA0KLXsNCi0JcmV0dXJuIGZNYXggLSBmTWluOw0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFBXTF9TQ1JPTExfUFJJVkFURURBVEEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLVBXTF9TQ1JPTExfUFJJVkFURURBVEE6OlBXTF9TQ1JPTExfUFJJVkFURURBVEEoKQ0KLXsNCi0JRGVmYXVsdCgpOw0KLX0NCi0NCi12b2lkIFBXTF9TQ1JPTExfUFJJVkFURURBVEE6OkRlZmF1bHQoKQ0KLXsNCi0JU2Nyb2xsUmFuZ2UuRGVmYXVsdCgpOw0KLQlmU2Nyb2xsUG9zID0gU2Nyb2xsUmFuZ2UuZk1pbjsNCi0JZkNsaWVudFdpZHRoID0gMDsNCi0JZkJpZ1N0ZXAgPSAxMDsNCi0JZlNtYWxsU3RlcCA9IDE7DQotfQ0KLQ0KLXZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U2V0U2Nyb2xsUmFuZ2UoRlhfRkxPQVQgbWluLEZYX0ZMT0FUIG1heCkNCi17DQotCVNjcm9sbFJhbmdlLlNldChtaW4sbWF4KTsNCi0NCi0JaWYgKElzRmxvYXRTbWFsbGVyKGZTY3JvbGxQb3MsIFNjcm9sbFJhbmdlLmZNaW4pKQ0KLQkJZlNjcm9sbFBvcyA9IFNjcm9sbFJhbmdlLmZNaW47DQotCWlmIChJc0Zsb2F0QmlnZ2VyKGZTY3JvbGxQb3MsIFNjcm9sbFJhbmdlLmZNYXgpKQ0KLQkJZlNjcm9sbFBvcyA9IFNjcm9sbFJhbmdlLmZNYXg7CQkNCi19DQotDQotdm9pZCBQV0xfU0NST0xMX1BSSVZBVEVEQVRBOjpTZXRDbGllbnRXaWR0aChGWF9GTE9BVCB3aWR0aCkNCi17DQotCWZDbGllbnRXaWR0aCA9IHdpZHRoOw0KLX0NCi0NCi12b2lkIFBXTF9TQ1JPTExfUFJJVkFURURBVEE6OlNldFNtYWxsU3RlcChGWF9GTE9BVCBzdGVwKQ0KLXsNCi0JZlNtYWxsU3RlcCA9IHN0ZXA7DQotfQ0KLQ0KLXZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U2V0QmlnU3RlcChGWF9GTE9BVCBzdGVwKQ0KLXsNCi0JZkJpZ1N0ZXAgPSBzdGVwOw0KLX0NCi0NCi1GWF9CT09MIFBXTF9TQ1JPTExfUFJJVkFURURBVEE6OlNldFBvcyhGWF9GTE9BVCBwb3MpDQotew0KLQlpZiAoU2Nyb2xsUmFuZ2UuSW4ocG9zKSkNCi0Jew0KLQkJZlNjcm9sbFBvcyA9IHBvczsNCi0JCXJldHVybiBUUlVFOw0KLQl9DQotCXJldHVybiBGQUxTRTsNCi19DQotDQotdm9pZCBQV0xfU0NST0xMX1BSSVZBVEVEQVRBOjpBZGRTbWFsbCgpDQotew0KLQlpZiAoIVNldFBvcyhmU2Nyb2xsUG9zICsgZlNtYWxsU3RlcCkpDQotCQlTZXRQb3MoU2Nyb2xsUmFuZ2UuZk1heCk7DQotfQ0KLQ0KLXZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U3ViU21hbGwoKQ0KLXsNCi0JaWYgKCFTZXRQb3MoZlNjcm9sbFBvcyAtIGZTbWFsbFN0ZXApKQ0KLQkJU2V0UG9zKFNjcm9sbFJhbmdlLmZNaW4pOw0KLX0NCi0NCi12b2lkIFBXTF9TQ1JPTExfUFJJVkFURURBVEE6OkFkZEJpZygpDQotew0KLQlpZiAoIVNldFBvcyhmU2Nyb2xsUG9zICsgZkJpZ1N0ZXApKQ0KLQkJU2V0UG9zKFNjcm9sbFJhbmdlLmZNYXgpOwkJDQotfQ0KLQ0KLXZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U3ViQmlnKCkNCi17DQotCWlmICghU2V0UG9zKGZTY3JvbGxQb3MgLSBmQmlnU3RlcCkpDQotCQlTZXRQb3MoU2Nyb2xsUmFuZ2UuZk1pbik7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9TQkJ1dHRvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BXTF9TQkJ1dHRvbjo6Q1BXTF9TQkJ1dHRvbihQV0xfU0NST0xMQkFSX1RZUEUgZVNjcm9sbEJhclR5cGUsUFdMX1NCQlVUVE9OX1RZUEUgZUJ1dHRvblR5cGUpDQotew0KLQltX2VTY3JvbGxCYXJUeXBlID0gZVNjcm9sbEJhclR5cGU7DQotCW1fZVNCQnV0dG9uVHlwZSA9IGVCdXR0b25UeXBlOw0KLQ0KLQltX2JNb3VzZURvd24gPSBGQUxTRTsNCi19DQotDQotQ1BXTF9TQkJ1dHRvbjo6fkNQV0xfU0JCdXR0b24oKQ0KLXsNCi0NCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9TQkJ1dHRvbjo6R2V0Q2xhc3NOYW1lKCkgY29uc3QNCi17DQotCXJldHVybiAiQ1BXTF9TQkJ1dHRvbiI7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TQkJ1dHRvbjo6T25DcmVhdGUoUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLQljcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfQVJST1c7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TQkJ1dHRvbjo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSkNCi17DQotCUNQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsNCi0NCi0JaWYgKCFJc1Zpc2libGUoKSkgcmV0dXJuOw0KLQ0KLQlDRlhfQnl0ZVRleHRCdWYgc0J1dHRvbjsNCi0NCi0JQ1BERl9SZWN0IHJlY3RXbmQgPSBHZXRXaW5kb3dSZWN0KCk7DQotDQotCWlmIChyZWN0V25kLklzRW1wdHkoKSkgcmV0dXJuOw0KLQ0KLQlzQXBwU3RyZWFtIDw8ICJxXG4iOw0KLQ0KLQlDUERGX1BvaW50IHB0Q2VudGVyID0gdGhpcy0+R2V0Q2VudGVyUG9pbnQoKTsNCi0NCi0Jc3dpdGNoICh0aGlzLT5tX2VTY3JvbGxCYXJUeXBlKQ0KLQl7DQotCQljYXNlIFNCVF9IU0NST0xMOg0KLQkJCXN3aXRjaCAodGhpcy0+bV9lU0JCdXR0b25UeXBlKQ0KLQkJCXsNCi0JCQkJY2FzZSBQU0JUX01JTjoNCi0JCQkJCXsNCi0JCQkJCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkpOw0KLQkJCQkJCUNQREZfUG9pbnQgcHQyKHB0Q2VudGVyLnggKyBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYscHRDZW50ZXIueSArIFBXTF9UUklBTkdMRV9IQUxGTEVOKTsNCi0JCQkJCQlDUERGX1BvaW50IHB0MyhwdENlbnRlci54ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkgLSBQV0xfVFJJQU5HTEVfSEFMRkxFTik7DQotDQotCQkJCQkJaWYgKHJlY3RXbmQucmlnaHQgLSByZWN0V25kLmxlZnQgPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDIgJiYNCi0JCQkJCQkJcmVjdFduZC50b3AgLSByZWN0V25kLmJvdHRvbSA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICkNCi0JCQkJCQl7DQotCQkJCQkJCXNCdXR0b24gPDwgIjAgZ1xuIjsNCi0JCQkJCQkJc0J1dHRvbiA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBtXG4iOw0KLQkJCQkJCQlzQnV0dG9uIDw8IHB0Mi54IDw8ICIgIiA8PCBwdDIueSA8PCAiIGxcbiI7DQotCQkJCQkJCXNCdXR0b24gPDwgcHQzLnggPDwgIiAiIDw8IHB0My55IDw8ICIgbFxuIjsNCi0JCQkJCQkJc0J1dHRvbiA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBsIGZcbiI7DQotDQotCQkJCQkJCXNBcHBTdHJlYW0gPDwgc0J1dHRvbjsJDQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQkJYnJlYWs7DQotCQkJCWNhc2UgUFNCVF9NQVg6DQotCQkJCQl7DQotCQkJCQkJQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCArIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55KTsNCi0JCQkJCQlDUERGX1BvaW50IHB0MihwdENlbnRlci54IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkgKyBQV0xfVFJJQU5HTEVfSEFMRkxFTik7DQotCQkJCQkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4pOw0KLQ0KLQkJCQkJCWlmIChyZWN0V25kLnJpZ2h0IC0gcmVjdFduZC5sZWZ0ID4gUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAyICYmDQotCQkJCQkJCXJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiApDQotCQkJCQkJew0KLQkJCQkJCQlzQnV0dG9uIDw8ICIwIGdcbiI7DQotCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsNCi0JCQkJCQkJc0J1dHRvbiA8PCBwdDIueCA8PCAiICIgPDwgcHQyLnkgPDwgIiBsXG4iOw0KLQkJCQkJCQlzQnV0dG9uIDw8IHB0My54IDw8ICIgIiA8PCBwdDMueSA8PCAiIGxcbiI7DQotCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbCBmXG4iOw0KLQ0KLQkJCQkJCQlzQXBwU3RyZWFtIDw8IHNCdXR0b247CQ0KLQkJCQkJCX0NCi0JCQkJCX0NCi0JCQkJCWJyZWFrOw0KLQkJCQlkZWZhdWx0Og0KLQkJCQkJYnJlYWs7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBTQlRfVlNDUk9MTDoNCi0JCQlzd2l0Y2godGhpcy0+bV9lU0JCdXR0b25UeXBlKQ0KLQkJCXsNCi0JCQkJY2FzZSBQU0JUX01JTjoNCi0JCQkJCXsNCi0JCQkJCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4scHRDZW50ZXIueSAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41Zik7DQotCQkJCQkJQ1BERl9Qb2ludCBwdDIocHRDZW50ZXIueCArIFBXTF9UUklBTkdMRV9IQUxGTEVOLHB0Q2VudGVyLnkgLSBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOw0KLQkJCQkJCUNQREZfUG9pbnQgcHQzKHB0Q2VudGVyLngscHRDZW50ZXIueSArIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41Zik7DQotDQotCQkJCQkJaWYgKHJlY3RXbmQucmlnaHQgLSByZWN0V25kLmxlZnQgPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDIgJiYNCi0JCQkJCQkJcmVjdFduZC50b3AgLSByZWN0V25kLmJvdHRvbSA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICkNCi0JCQkJCQl7DQotCQkJCQkJCXNCdXR0b24gPDwgIjAgZ1xuIjsNCi0JCQkJCQkJc0J1dHRvbiA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBtXG4iOw0KLQkJCQkJCQlzQnV0dG9uIDw8IHB0Mi54IDw8ICIgIiA8PCBwdDIueSA8PCAiIGxcbiI7DQotCQkJCQkJCXNCdXR0b24gPDwgcHQzLnggPDwgIiAiIDw8IHB0My55IDw8ICIgbFxuIjsNCi0JCQkJCQkJc0J1dHRvbiA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBsIGZcbiI7DQotDQotCQkJCQkJCXNBcHBTdHJlYW0gPDwgc0J1dHRvbjsJDQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQkJYnJlYWs7DQotCQkJCWNhc2UgUFNCVF9NQVg6DQotCQkJCQl7DQotCQkJCQkJQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCAtIFBXTF9UUklBTkdMRV9IQUxGTEVOLHB0Q2VudGVyLnkgKyBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOw0KLQkJCQkJCUNQREZfUG9pbnQgcHQyKHB0Q2VudGVyLnggKyBQV0xfVFJJQU5HTEVfSEFMRkxFTixwdENlbnRlci55ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmKTsNCi0JCQkJCQlDUERGX1BvaW50IHB0MyhwdENlbnRlci54LHB0Q2VudGVyLnkgLSBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOw0KLQ0KLQkJCQkJCWlmIChyZWN0V25kLnJpZ2h0IC0gcmVjdFduZC5sZWZ0ID4gUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAyICYmDQotCQkJCQkJCXJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiApDQotCQkJCQkJew0KLQkJCQkJCQlzQnV0dG9uIDw8ICIwIGdcbiI7DQotCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsNCi0JCQkJCQkJc0J1dHRvbiA8PCBwdDIueCA8PCAiICIgPDwgcHQyLnkgPDwgIiBsXG4iOw0KLQkJCQkJCQlzQnV0dG9uIDw8IHB0My54IDw8ICIgIiA8PCBwdDMueSA8PCAiIGxcbiI7DQotCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbCBmXG4iOw0KLQ0KLQkJCQkJCQlzQXBwU3RyZWFtIDw8IHNCdXR0b247CQ0KLQkJCQkJCX0NCi0JCQkJCX0NCi0JCQkJCWJyZWFrOw0KLQkJCQlkZWZhdWx0Og0KLQkJCQkJYnJlYWs7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJZGVmYXVsdDoNCi0JCQlicmVhazsNCi0JfQ0KLQ0KLQlzQXBwU3RyZWFtIDw8ICJRXG4iOw0KLX0NCi0NCi12b2lkIENQV0xfU0JCdXR0b246OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0KLXsNCi0JaWYgKCFJc1Zpc2libGUoKSkgcmV0dXJuOw0KLQ0KLQlDUERGX1JlY3QgcmVjdFduZCA9IEdldFdpbmRvd1JlY3QoKTsNCi0JaWYgKHJlY3RXbmQuSXNFbXB0eSgpKSByZXR1cm47DQotDQotCUNQREZfUG9pbnQgcHRDZW50ZXIgPSB0aGlzLT5HZXRDZW50ZXJQb2ludCgpOw0KLQlGWF9JTlQzMiBuVHJhbnNwYXJhbmN5ID0gdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCk7DQotDQotCXN3aXRjaCAodGhpcy0+bV9lU2Nyb2xsQmFyVHlwZSkNCi0Jew0KLQljYXNlIFNCVF9IU0NST0xMOg0KLQkJQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLHBVc2VyMkRldmljZSk7DQotCQlzd2l0Y2ggKHRoaXMtPm1fZVNCQnV0dG9uVHlwZSkNCi0JCXsNCi0JCWNhc2UgUFNCVF9NSU46DQotCQkJew0KLQkJCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkpOw0KLQkJCQlDUERGX1BvaW50IHB0MihwdENlbnRlci54ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkgKyBQV0xfVFJJQU5HTEVfSEFMRkxFTik7DQotCQkJCUNQREZfUG9pbnQgcHQzKHB0Q2VudGVyLnggKyBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYscHRDZW50ZXIueSAtIFBXTF9UUklBTkdMRV9IQUxGTEVOKTsNCi0NCi0JCQkJaWYgKHJlY3RXbmQucmlnaHQgLSByZWN0V25kLmxlZnQgPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDIgJiYNCi0JCQkJCXJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiApDQotCQkJCXsNCi0JCQkJCUNGWF9QYXRoRGF0YSBwYXRoOw0KLQ0KLQkJCQkJcGF0aC5TZXRQb2ludENvdW50KDQpOw0KLQkJCQkJcGF0aC5TZXRQb2ludCgwLCBwdDEueCwgcHQxLnksIEZYUFRfTU9WRVRPKTsNCi0JCQkJCXBhdGguU2V0UG9pbnQoMSwgcHQyLngsIHB0Mi55LCBGWFBUX0xJTkVUTyk7DQotCQkJCQlwYXRoLlNldFBvaW50KDIsIHB0My54LCBwdDMueSwgRlhQVF9MSU5FVE8pOw0KLQkJCQkJcGF0aC5TZXRQb2ludCgzLCBwdDEueCwgcHQxLnksIEZYUFRfTElORVRPKTsNCi0NCi0JCQkJCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoLCBwVXNlcjJEZXZpY2UsIE5VTEwsIA0KLQkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IsblRyYW5zcGFyYW5jeSksIA0KLQkJCQkJCTAsIEZYRklMTF9BTFRFUk5BVEUpOw0KLQkJCQl9DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQU0JUX01BWDoNCi0JCQl7DQotCQkJCUNQREZfUG9pbnQgcHQxKHB0Q2VudGVyLnggKyBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYscHRDZW50ZXIueSk7DQotCQkJCUNQREZfUG9pbnQgcHQyKHB0Q2VudGVyLnggLSBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYscHRDZW50ZXIueSArIFBXTF9UUklBTkdMRV9IQUxGTEVOKTsNCi0JCQkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4pOw0KLQ0KLQkJCQlpZiAocmVjdFduZC5yaWdodCAtIHJlY3RXbmQubGVmdCA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICogMiAmJg0KLQkJCQkJcmVjdFduZC50b3AgLSByZWN0V25kLmJvdHRvbSA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICkNCi0JCQkJew0KLQkJCQkJQ0ZYX1BhdGhEYXRhIHBhdGg7DQotDQotCQkJCQlwYXRoLlNldFBvaW50Q291bnQoNCk7DQotCQkJCQlwYXRoLlNldFBvaW50KDAsIHB0MS54LCBwdDEueSwgRlhQVF9NT1ZFVE8pOw0KLQkJCQkJcGF0aC5TZXRQb2ludCgxLCBwdDIueCwgcHQyLnksIEZYUFRfTElORVRPKTsNCi0JCQkJCXBhdGguU2V0UG9pbnQoMiwgcHQzLngsIHB0My55LCBGWFBUX0xJTkVUTyk7DQotCQkJCQlwYXRoLlNldFBvaW50KDMsIHB0MS54LCBwdDEueSwgRlhQVF9MSU5FVE8pOw0KLQ0KLQkJCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgTlVMTCwgDQotCQkJCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUixuVHJhbnNwYXJhbmN5KSwgDQotCQkJCQkJMCwgRlhGSUxMX0FMVEVSTkFURSk7CQ0KLQkJCQl9DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJZGVmYXVsdDoNCi0JCQlicmVhazsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIFNCVF9WU0NST0xMOg0KLQkJc3dpdGNoKHRoaXMtPm1fZVNCQnV0dG9uVHlwZSkNCi0JCXsNCi0JCWNhc2UgUFNCVF9NSU46DQotCQkJew0KLQkJCQkvL2RyYXcgYm9yZGVyDQotCQkJCUNQREZfUmVjdCByY0RyYXcgPSByZWN0V25kOw0KLQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlUmVjdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHJjRHJhdywgDQotCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMTAwLDEwMCwxMDApLDAuMGYpOw0KLQ0KLQkJCQkvL2RyYXcgaW5uZXIgYm9yZGVyDQotCQkJCXJjRHJhdyA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3RXbmQsMC41Zik7DQotCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCANCi0JCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNTUsMjU1LDI1NSksMS4wZik7DQotDQotCQkJCS8vZHJhdyBiYWNrZ3JvdW5kDQotDQotCQkJCXJjRHJhdyA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3RXbmQsMS4wZik7DQotDQotCQkJCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkNCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdTaGFkb3cocERldmljZSwgcFVzZXIyRGV2aWNlLCBUUlVFLCBGQUxTRSwgcmNEcmF3LCBuVHJhbnNwYXJhbmN5LCA4MCwgMjIwKTsNCi0JCQkJZWxzZQ0KLQkJCQkJQ1BXTF9VdGlsczo6RHJhd0ZpbGxSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCBBcmdiRW5jb2RlKDI1NSwyNTUsMjU1LDI1NSkpOw0KLQ0KLQkJCQkvL2RyYXcgYXJyb3cNCi0NCi0JCQkJaWYgKHJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiA2LjBmICkNCi0JCQkJew0KLQkJCQkJRlhfRkxPQVQgZlggPSByZWN0V25kLmxlZnQgKyAxLjVmOw0KLQkJCQkJRlhfRkxPQVQgZlkgPSByZWN0V25kLmJvdHRvbTsNCi0JCQkJCUNQREZfUG9pbnQgcHRzWzddID0gew0KLQkJCQkJCQkJQ1BERl9Qb2ludChmWCsyLjVmLCBmWSs0LjBmKSwNCi0JCQkJCQkJCUNQREZfUG9pbnQoZlgrMi41ZiwgZlkrMy4wZiksDQotCQkJCQkJCQlDUERGX1BvaW50KGZYKzQuNWYsIGZZKzUuMGYpLA0KLQkJCQkJCQkJQ1BERl9Qb2ludChmWCs2LjVmLCBmWSszLjBmKSwNCi0JCQkJCQkJCUNQREZfUG9pbnQoZlgrNi41ZiwgZlkrNC4wZiksDQotCQkJCQkJCQlDUERGX1BvaW50KGZYKzQuNWYsIGZZKzYuMGYpLA0KLQkJCQkJCQkJQ1BERl9Qb2ludChmWCsyLjVmLCBmWSs0LjBmKX07DQotCQkJCQkNCi0NCi0JCQkJCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkNCi0JCQkJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbEFyZWEocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdHMsIDcsIEFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNTUsMjU1LDI1NSkpOw0KLQkJCQkJZWxzZQ0KLQkJCQkJCUNQV0xfVXRpbHM6OkRyYXdGaWxsQXJlYShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0cywgNywgDQotCQkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKFBXTF9ERUZBVUxUX0hFQVZZR1JBWUNPTE9SLDI1NSkpOw0KLQkJCQl9DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQU0JUX01BWDoNCi0JCQl7DQotCQkJCS8vZHJhdyBib3JkZXINCi0JCQkJQ1BERl9SZWN0IHJjRHJhdyA9IHJlY3RXbmQ7DQotCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCANCi0JCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwxMDAsMTAwLDEwMCksMC4wZik7DQotCQkJCQ0KLQkJCQkvL2RyYXcgaW5uZXIgYm9yZGVyDQotCQkJCXJjRHJhdyA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3RXbmQsMC41Zik7DQotCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCANCi0JCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNTUsMjU1LDI1NSksMS4wZik7DQotDQotCQkJCS8vZHJhdyBiYWNrZ3JvdW5kDQotCQkJCXJjRHJhdyA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3RXbmQsMS4wZik7DQotCQkJCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkNCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdTaGFkb3cocERldmljZSwgcFVzZXIyRGV2aWNlLCBUUlVFLCBGQUxTRSwgcmNEcmF3LCBuVHJhbnNwYXJhbmN5LCA4MCwgMjIwKTsNCi0JCQkJZWxzZQ0KLQkJCQkJQ1BXTF9VdGlsczo6RHJhd0ZpbGxSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCBBcmdiRW5jb2RlKDI1NSwyNTUsMjU1LDI1NSkpOw0KLQ0KLQkJCQkvL2RyYXcgYXJyb3cNCi0NCi0JCQkJaWYgKHJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiA2LjBmICkNCi0JCQkJew0KLQkJCQkJRlhfRkxPQVQgZlggPSByZWN0V25kLmxlZnQgKyAxLjVmOw0KLQkJCQkJRlhfRkxPQVQgZlkgPSByZWN0V25kLmJvdHRvbTsNCi0NCi0JCQkJCUNQREZfUG9pbnQgcHRzWzddID0gew0KLQkJCQkJCQkJQ1BERl9Qb2ludChmWCsyLjVmLCBmWSs1LjBmKSwNCi0JCQkJCQkJCUNQREZfUG9pbnQoZlgrMi41ZiwgZlkrNi4wZiksDQotCQkJCQkJCQlDUERGX1BvaW50KGZYKzQuNWYsIGZZKzQuMGYpLA0KLQkJCQkJCQkJQ1BERl9Qb2ludChmWCs2LjVmLCBmWSs2LjBmKSwNCi0JCQkJCQkJCUNQREZfUG9pbnQoZlgrNi41ZiwgZlkrNS4wZiksDQotCQkJCQkJCQlDUERGX1BvaW50KGZYKzQuNWYsIGZZKzMuMGYpLA0KLQkJCQkJCQkJQ1BERl9Qb2ludChmWCsyLjVmLCBmWSs1LjBmKX07DQotCQkJCQkNCi0NCi0JCQkJCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkNCi0JCQkJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbEFyZWEocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdHMsIDcsIEFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNTUsMjU1LDI1NSkpOw0KLQkJCQkJZWxzZQ0KLQkJCQkJCUNQV0xfVXRpbHM6OkRyYXdGaWxsQXJlYShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0cywgNywgDQotCQkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKFBXTF9ERUZBVUxUX0hFQVZZR1JBWUNPTE9SLDI1NSkpOw0KLQkJCQl9DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQU0JUX1BPUzoNCi0JCQl7DQotCQkJCS8vQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLHBVc2VyMkRldmljZSk7DQotDQotCQkJCS8vZHJhdyBib3JkZXINCi0JCQkJQ1BERl9SZWN0IHJjRHJhdyA9IHJlY3RXbmQ7DQotCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCANCi0JCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwxMDAsMTAwLDEwMCksMC4wZik7DQotCQkJCQ0KLQkJCQkvL2RyYXcgaW5uZXIgYm9yZGVyDQotCQkJCXJjRHJhdyA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3RXbmQsMC41Zik7DQotCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCANCi0JCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNTUsMjU1LDI1NSksMS4wZik7DQotDQotCQkJCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkNCi0JCQkJew0KLQkJCQkJLy9kcmF3IHNoYWRvdyBlZmZlY3QJCQkJCQkNCi0JCQkJCQ0KLQkJCQkJQ1BERl9Qb2ludCBwdFRvcCA9IENQREZfUG9pbnQocmVjdFduZC5sZWZ0LHJlY3RXbmQudG9wLTEuMGYpOw0KLQkJCQkJQ1BERl9Qb2ludCBwdEJvdHRvbSA9IENQREZfUG9pbnQocmVjdFduZC5sZWZ0LHJlY3RXbmQuYm90dG9tKzEuMGYpOw0KLQ0KLQkJCQkJcHRUb3AueCArPSAxLjVmOw0KLQkJCQkJcHRCb3R0b20ueCArPSAxLjVmOw0KLQkJCQkJDQotCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0VG9wLCBwdEJvdHRvbSwgDQotCQkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDIxMCwyMTAsMjEwKSwxLjBmKTsNCi0NCi0JCQkJCXB0VG9wLnggKz0gMS4wZjsNCi0JCQkJCXB0Qm90dG9tLnggKz0gMS4wZjsNCi0JCQkJCQ0KLQkJCQkJQ1BXTF9VdGlsczo6RHJhd1N0cm9rZUxpbmUocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdFRvcCwgcHRCb3R0b20sIA0KLQkJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyMjAsMjIwLDIyMCksMS4wZik7DQotDQotCQkJCQlwdFRvcC54ICs9IDEuMGY7DQotCQkJCQlwdEJvdHRvbS54ICs9IDEuMGY7DQotCQkJCQkNCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRUb3AsIHB0Qm90dG9tLCANCi0JCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMjQwLDI0MCwyNDApLDEuMGYpOw0KLQ0KLQkJCQkJcHRUb3AueCArPSAxLjBmOw0KLQkJCQkJcHRCb3R0b20ueCArPSAxLjBmOw0KLQkJCQkJDQotCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0VG9wLCBwdEJvdHRvbSwgDQotCQkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDI0MCwyNDAsMjQwKSwxLjBmKTsNCi0NCi0JCQkJCXB0VG9wLnggKz0gMS4wZjsNCi0JCQkJCXB0Qm90dG9tLnggKz0gMS4wZjsNCi0JCQkJCQ0KLQkJCQkJQ1BXTF9VdGlsczo6RHJhd1N0cm9rZUxpbmUocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdFRvcCwgcHRCb3R0b20sIA0KLQkJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyMTAsMjEwLDIxMCksMS4wZik7DQotDQotCQkJCQlwdFRvcC54ICs9IDEuMGY7DQotCQkJCQlwdEJvdHRvbS54ICs9IDEuMGY7DQotCQkJCQkNCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRUb3AsIHB0Qm90dG9tLCANCi0JCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMTgwLDE4MCwxODApLDEuMGYpOw0KLQ0KLQkJCQkJcHRUb3AueCArPSAxLjBmOw0KLQkJCQkJcHRCb3R0b20ueCArPSAxLjBmOw0KLQkJCQkJDQotCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0VG9wLCBwdEJvdHRvbSwgDQotCQkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDE1MCwxNTAsMTUwKSwxLjBmKTsNCi0NCi0JCQkJCXB0VG9wLnggKz0gMS4wZjsNCi0JCQkJCXB0Qm90dG9tLnggKz0gMS4wZjsNCi0JCQkJCQ0KLQkJCQkJQ1BXTF9VdGlsczo6RHJhd1N0cm9rZUxpbmUocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdFRvcCwgcHRCb3R0b20sIA0KLQkJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwxNTAsMTUwLDE1MCksMS4wZik7DQotDQotCQkJCQlwdFRvcC54ICs9IDEuMGY7DQotCQkJCQlwdEJvdHRvbS54ICs9IDEuMGY7DQotCQkJCQkNCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRUb3AsIHB0Qm90dG9tLCANCi0JCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMTgwLDE4MCwxODApLDEuMGYpOw0KLQ0KLQkJCQkJcHRUb3AueCArPSAxLjBmOw0KLQkJCQkJcHRCb3R0b20ueCArPSAxLjBmOw0KLQkJCQkJDQotCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0VG9wLCBwdEJvdHRvbSwgDQotCQkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDIxMCwyMTAsMjEwKSwxLjBmKTsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsNCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdGaWxsUmVjdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHJjRHJhdywgQXJnYkVuY29kZSgyNTUsMjU1LDI1NSwyNTUpKTsNCi0JCQkJfQ0KLQ0KLQkJCQkvL2RyYXcgZnJpY3Rpb24NCi0NCi0JCQkJaWYgKHJlY3RXbmQuSGVpZ2h0KCkgPiA4LjBmKQ0KLQkJCQl7DQotCQkJCQlGWF9DT0xPUlJFRiBjclN0cm9rZSA9IEFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwxMjAsMTIwLDEyMCk7DQotCQkJCQlpZiAoIXRoaXMtPklzRW5hYmxlZCgpKQ0KLQkJCQkJCWNyU3Ryb2tlID0gQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoUFdMX0RFRkFVTFRfSEVBVllHUkFZQ09MT1IsMjU1KTsNCi0NCi0JCQkJCUZYX0ZMT0FUIG5GcmljdGlvbldpZHRoID0gNS4wZjsNCi0JCQkJCUZYX0ZMT0FUIG5GcmljdGlvbkhlaWdodCA9IDUuNWY7DQotDQotCQkJCQlDUERGX1BvaW50IHB0TGVmdCA9IENQREZfUG9pbnQocHRDZW50ZXIueCAtIG5GcmljdGlvbldpZHRoIC8gMi4wZiwgcHRDZW50ZXIueSAtIG5GcmljdGlvbkhlaWdodCAvIDIuMGYgKyAwLjVmKTsNCi0JCQkJCUNQREZfUG9pbnQgcHRSaWdodCA9IENQREZfUG9pbnQocHRDZW50ZXIueCArIG5GcmljdGlvbldpZHRoIC8gMi4wZiwgcHRDZW50ZXIueSAtIG5GcmljdGlvbkhlaWdodCAvIDIuMGYgKyAwLjVmKTsNCi0NCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRMZWZ0LCBwdFJpZ2h0LCANCi0JCQkJCQljclN0cm9rZSwxLjBmKTsNCi0NCi0JCQkJCXB0TGVmdC55ICs9IDIuMGY7DQotCQkJCQlwdFJpZ2h0LnkgKz0gMi4wZjsNCi0NCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRMZWZ0LCBwdFJpZ2h0LCANCi0JCQkJCQljclN0cm9rZSwxLjBmKTsNCi0NCi0JCQkJCXB0TGVmdC55ICs9IDIuMGY7DQotCQkJCQlwdFJpZ2h0LnkgKz0gMi4wZjsNCi0NCi0JCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRMZWZ0LCBwdFJpZ2h0LCANCi0JCQkJCQljclN0cm9rZSwxLjBmKTsNCi0NCi0JCQkJCS8qDQotCQkJCQlwdExlZnQueSArPSAxLjVmOw0KLQkJCQkJcHRSaWdodC55ICs9IDEuNWY7DQotDQotCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0TGVmdCwgcHRSaWdodCwgDQotCQkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDE1MCwxNTAsMTUwKSwxLjBmKTsNCi0JCQkJCQkqLw0KLQkJCQl9DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJZGVmYXVsdDoNCi0JCQlicmVhazsNCi0JCX0NCi0JCWJyZWFrOw0KLQlkZWZhdWx0Og0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotRlhfQk9PTCBDUFdMX1NCQnV0dG9uOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCxuRmxhZyk7DQotDQotCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkNCi0JCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsUE5NX0xCVVRUT05ET1dOLDAsKEZYX0lOVFBUUikmcG9pbnQpOw0KLQ0KLQltX2JNb3VzZURvd24gPSBUUlVFOw0KLQlTZXRDYXB0dXJlKCk7DQotDQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfU0JCdXR0b246Ok9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpDQotew0KLQlDUFdMX1duZDo6T25MQnV0dG9uVXAocG9pbnQsbkZsYWcpOw0KLQ0KLQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpDQotCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLFBOTV9MQlVUVE9OVVAsMCwoRlhfSU5UUFRSKSZwb2ludCk7DQotDQotCW1fYk1vdXNlRG93biA9IEZBTFNFOw0KLQlSZWxlYXNlQ2FwdHVyZSgpOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBDUFdMX1NCQnV0dG9uOjpPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JQ1BXTF9XbmQ6Ok9uTW91c2VNb3ZlKHBvaW50LG5GbGFnKTsNCi0NCi0JaWYgKENQV0xfV25kICogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKQ0KLQl7CQkNCi0JCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsUE5NX01PVVNFTU9WRSwwLChGWF9JTlRQVFIpJnBvaW50KTsNCi0NCi0JCS8qDQotCQlpZiAobV9iTW91c2VEb3duICYmIChtX2VTQkJ1dHRvblR5cGUgPT0gUFNCVF9NSU4gfHwgbV9lU0JCdXR0b25UeXBlID09IFBTQlRfTUFYKSkNCi0JCXsNCi0JCQlpZiAoIXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsUE5NX0xCVVRUT05ET1dOLG5GbGFncywoRlhfSU5UUFRSKSZwb2ludCkpDQotCQkJCXJldHVybiBGQUxTRTsNCi0JCX0NCi0JCSovDQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9TY3JvbGxCYXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNQV0xfU2Nyb2xsQmFyOjpDUFdMX1Njcm9sbEJhcihQV0xfU0NST0xMQkFSX1RZUEUgc2JUeXBlKToNCi0JbV9zYlR5cGUoc2JUeXBlKSwNCi0JbV9wTWluQnV0dG9uKE5VTEwpLA0KLQltX3BNYXhCdXR0b24oTlVMTCksDQotCW1fcFBvc0J1dHRvbihOVUxMKSwNCi0JbV9iTW91c2VEb3duKEZBTFNFKSwNCi0JbV9iTWluT3JNYXgoRkFMU0UpLA0KLQltX2JOb3RpZnlGb3JldmVyKFRSVUUpDQotew0KLX0NCi0NCi1DUFdMX1Njcm9sbEJhcjo6fkNQV0xfU2Nyb2xsQmFyKCkNCi17DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfU2Nyb2xsQmFyOjpHZXRDbGFzc05hbWUoKSBjb25zdA0KLXsNCi0JcmV0dXJuICJDUFdMX1Njcm9sbEJhciI7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0KLXsNCi0JY3AuZUN1cnNvclR5cGUgPSBGWENUX0FSUk9XOw0KLX0NCi0NCi12b2lkIENQV0xfU2Nyb2xsQmFyOjpSZVBvc0NoaWxkV25kKCkNCi17DQotCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsNCi0NCi0vKg0KLQlzd2l0Y2gobV9zYlR5cGUpDQotCXsNCi0JCWNhc2UgU0JUX0hTQ1JPTEw6DQotCQkJaWYgKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCA8IFBXTF9TQ1JPTExCQVJfV0lEVEggfHwNCi0JCQkJcmNDbGllbnQudG9wIC0gcmNDbGllbnQuYm90dG9tIDwgUFdMX1NDUk9MTEJBUl9XSURUSCkNCi0JCQl7DQotCQkJCVNldFZpc2libGUoRkFMU0UpOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgU0JUX1ZTQ1JPTEw6DQotCQkJaWYgKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCA8IFBXTF9TQ1JPTExCQVJfV0lEVEggfHwNCi0JCQkJcmNDbGllbnQudG9wIC0gcmNDbGllbnQuYm90dG9tIDwgUFdMX1NDUk9MTEJBUl9XSURUSCkNCi0JCQl7DQotCQkJCVNldFZpc2libGUoRkFMU0UpOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JfQkNCi0qLw0KLQlDUERGX1JlY3QgcmNNaW5CdXR0b24scmNNYXhCdXR0b247DQotDQotCUZYX0ZMT0FUIGZCV2lkdGggPSAwOw0KLQ0KLQlzd2l0Y2ggKG1fc2JUeXBlKQ0KLQl7DQotCWNhc2UgU0JUX0hTQ1JPTEw6DQotCQlpZiAocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0ID4gUFdMX1NDUk9MTEJBUl9CVVRUT05fV0lEVEggKiAyICsgUFdMX1NDUk9MTEJBUl9QT1NCVVRUT05fTUlOV0lEVEggKyAyKQ0KLQkJew0KLQkJCXJjTWluQnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQuYm90dG9tLA0KLQkJCQlyY0NsaWVudC5sZWZ0ICsgUFdMX1NDUk9MTEJBUl9CVVRUT05fV0lEVEgscmNDbGllbnQudG9wKTsNCi0JCQlyY01heEJ1dHRvbiA9IENQREZfUmVjdChyY0NsaWVudC5yaWdodCAtIFBXTF9TQ1JPTExCQVJfQlVUVE9OX1dJRFRILHJjQ2xpZW50LmJvdHRvbSwNCi0JCQkJcmNDbGllbnQucmlnaHQscmNDbGllbnQudG9wKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlmQldpZHRoID0gKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCAtIFBXTF9TQ1JPTExCQVJfUE9TQlVUVE9OX01JTldJRFRIIC0gMikgLyAyOw0KLQ0KLQkJCWlmIChmQldpZHRoID4gMCkNCi0JCQl7DQotCQkJCXJjTWluQnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQuYm90dG9tLA0KLQkJCQkJcmNDbGllbnQubGVmdCArIGZCV2lkdGgscmNDbGllbnQudG9wKTsNCi0JCQkJcmNNYXhCdXR0b24gPSBDUERGX1JlY3QocmNDbGllbnQucmlnaHQgLSBmQldpZHRoLHJjQ2xpZW50LmJvdHRvbSwNCi0JCQkJCXJjQ2xpZW50LnJpZ2h0LHJjQ2xpZW50LnRvcCk7DQotCQkJfQ0KLQkJCWVsc2UgU2V0VmlzaWJsZShGQUxTRSk7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBTQlRfVlNDUk9MTDoNCi0JCWlmIChJc0Zsb2F0QmlnZ2VyKHJjQ2xpZW50LnRvcCAtIHJjQ2xpZW50LmJvdHRvbSwgUFdMX1NDUk9MTEJBUl9CVVRUT05fV0lEVEggKiAyICsgUFdMX1NDUk9MTEJBUl9QT1NCVVRUT05fTUlOV0lEVEggKyAyKSkNCi0JCXsNCi0JCQlyY01pbkJ1dHRvbiA9IENQREZfUmVjdChyY0NsaWVudC5sZWZ0LHJjQ2xpZW50LnRvcCAtIFBXTF9TQ1JPTExCQVJfQlVUVE9OX1dJRFRILA0KLQkJCQlyY0NsaWVudC5yaWdodCxyY0NsaWVudC50b3ApOw0KLQkJCXJjTWF4QnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQuYm90dG9tLA0KLQkJCQlyY0NsaWVudC5yaWdodCxyY0NsaWVudC5ib3R0b20gKyBQV0xfU0NST0xMQkFSX0JVVFRPTl9XSURUSCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJZkJXaWR0aCA9IChyY0NsaWVudC50b3AgLSByY0NsaWVudC5ib3R0b20gLSBQV0xfU0NST0xMQkFSX1BPU0JVVFRPTl9NSU5XSURUSCAtIDIpIC8gMjsNCi0NCi0JCQlpZiAoSXNGbG9hdEJpZ2dlcihmQldpZHRoLCAwKSkNCi0JCQl7DQotCQkJCXJjTWluQnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQudG9wIC0gZkJXaWR0aCwNCi0JCQkJCXJjQ2xpZW50LnJpZ2h0LHJjQ2xpZW50LnRvcCk7DQotCQkJCXJjTWF4QnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQuYm90dG9tLA0KLQkJCQkJcmNDbGllbnQucmlnaHQscmNDbGllbnQuYm90dG9tICsgZkJXaWR0aCk7DQotCQkJfQ0KLQkJCWVsc2UgU2V0VmlzaWJsZShGQUxTRSk7DQotCQl9DQotCQlicmVhazsNCi0JfQkNCi0JDQotLy8JaWYgKElzVmlzaWJsZSgpKQ0KLQl7DQotCQlpZiAobV9wTWluQnV0dG9uKQ0KLQkJCW1fcE1pbkJ1dHRvbi0+TW92ZShyY01pbkJ1dHRvbixUUlVFLEZBTFNFKTsNCi0JCQ0KLQkJaWYgKG1fcE1heEJ1dHRvbikNCi0JCQltX3BNYXhCdXR0b24tPk1vdmUocmNNYXhCdXR0b24sVFJVRSxGQUxTRSk7DQotDQotCQlNb3ZlUG9zQnV0dG9uKEZBTFNFKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfU2Nyb2xsQmFyOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKQ0KLXsNCi0JQ1BERl9SZWN0IHJlY3RXbmQgPSBHZXRXaW5kb3dSZWN0KCk7DQotDQotCWlmIChJc1Zpc2libGUoKSAmJiAhcmVjdFduZC5Jc0VtcHR5KCkpDQotCXsNCi0JCUNGWF9CeXRlVGV4dEJ1ZiBzQnV0dG9uOwkJDQotDQotCQlzQnV0dG9uIDw8ICJxXG4iOw0KLQkJc0J1dHRvbiA8PCAiMCB3XG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKEdldEJhY2tncm91bmRDb2xvcigpLFRSVUUpOw0KLQkJc0J1dHRvbiA8PCByZWN0V25kLmxlZnQgPDwgIiAiIDw8IHJlY3RXbmQuYm90dG9tIDw8ICIgIg0KLQkJCQk8PCByZWN0V25kLnJpZ2h0IC0gcmVjdFduZC5sZWZ0IDw8ICIgIiA8PCByZWN0V25kLnRvcCAtIHJlY3RXbmQuYm90dG9tIDw8ICIgcmUgYiBRXG4iOwkNCi0NCi0JCXNBcHBTdHJlYW0gPDwgc0J1dHRvbjsJDQotCX0NCi19DQotDQotdm9pZCBDUFdMX1Njcm9sbEJhcjo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpDQotew0KLS8vCUNQV0xfV25kOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSxwVXNlcjJEZXZpY2UpOw0KLQlDUERGX1JlY3QgcmVjdFduZCA9IEdldFdpbmRvd1JlY3QoKTsNCi0NCi0JaWYgKElzVmlzaWJsZSgpICYmICFyZWN0V25kLklzRW1wdHkoKSkNCi0Jew0KLQkJQ1BXTF9VdGlsczo6RHJhd0ZpbGxSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmVjdFduZCwgdGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCksIEdldFRyYW5zcGFyZW5jeSgpKTsNCi0NCi0JCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgDQotCQkJQ1BERl9Qb2ludChyZWN0V25kLmxlZnQrMi4wZixyZWN0V25kLnRvcC0yLjBmKSwgQ1BERl9Qb2ludChyZWN0V25kLmxlZnQrMi4wZixyZWN0V25kLmJvdHRvbSsyLjBmKSwgDQotCQkJQXJnYkVuY29kZSh0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSwxMDAsMTAwLDEwMCksMS4wZik7DQotDQotCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIA0KLQkJCUNQREZfUG9pbnQocmVjdFduZC5yaWdodC0yLjBmLHJlY3RXbmQudG9wLTIuMGYpLCBDUERGX1BvaW50KHJlY3RXbmQucmlnaHQtMi4wZixyZWN0V25kLmJvdHRvbSsyLjBmKSwgDQotCQkJQXJnYkVuY29kZSh0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSwxMDAsMTAwLDEwMCksMS4wZik7DQotCX0NCi19DQotDQotRlhfQk9PTCBDUFdMX1Njcm9sbEJhcjo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOw0KLQ0KLQkvL1NldEZvY3VzKCk7DQotDQotCWlmIChIYXNGbGFnKFBXU19BVVRPVFJBTlNQQVJFTlQpKQ0KLQl7DQotCQlpZiAoR2V0VHJhbnNwYXJlbmN5KCkgIT0gMjU1KQ0KLQkJew0KLQkJCVNldFRyYW5zcGFyZW5jeSgyNTUpOw0KLQkJCUludmFsaWRhdGVSZWN0KCk7DQotCQl9DQotCX0NCi0NCi0JQ1BERl9SZWN0IHJjTWluQXJlYSxyY01heEFyZWE7DQotDQotCWlmIChtX3BQb3NCdXR0b24gJiYgbV9wUG9zQnV0dG9uLT5Jc1Zpc2libGUoKSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOw0KLQkJQ1BERl9SZWN0IHJjUG9zQnV0dG9uID0gbV9wUG9zQnV0dG9uLT5HZXRXaW5kb3dSZWN0KCk7DQotDQotCQlzd2l0Y2ggKG1fc2JUeXBlKQ0KLQkJew0KLQkJY2FzZSBTQlRfSFNDUk9MTDoNCi0JCQlyY01pbkFyZWEgPSBDUERGX1JlY3QocmNDbGllbnQubGVmdCArIFBXTF9TQ1JPTExCQVJfQlVUVE9OX1dJRFRILHJjQ2xpZW50LmJvdHRvbSwNCi0JCQkJCQkJcmNQb3NCdXR0b24ubGVmdCxyY0NsaWVudC50b3ApOw0KLQkJCXJjTWF4QXJlYSA9IENQREZfUmVjdChyY1Bvc0J1dHRvbi5yaWdodCxyY0NsaWVudC5ib3R0b20sDQotCQkJCQkJCXJjQ2xpZW50LnJpZ2h0IC0gUFdMX1NDUk9MTEJBUl9CVVRUT05fV0lEVEgscmNDbGllbnQudG9wKTsNCi0NCi0JCQlicmVhazsNCi0JCWNhc2UgU0JUX1ZTQ1JPTEw6DQotCQkJcmNNaW5BcmVhID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNQb3NCdXR0b24udG9wLA0KLQkJCQkJCQlyY0NsaWVudC5yaWdodCxyY0NsaWVudC50b3AgLSBQV0xfU0NST0xMQkFSX0JVVFRPTl9XSURUSCk7DQotCQkJcmNNYXhBcmVhID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQuYm90dG9tICsgUFdMX1NDUk9MTEJBUl9CVVRUT05fV0lEVEgsDQotCQkJCQkJCXJjQ2xpZW50LnJpZ2h0LHJjUG9zQnV0dG9uLmJvdHRvbSk7DQotCQkJYnJlYWs7DQotCQl9DQotDQotCQlyY01pbkFyZWEuTm9ybWFsaXplKCk7DQotCQlyY01heEFyZWEuTm9ybWFsaXplKCk7DQotDQotCQlpZiAocmNNaW5BcmVhLkNvbnRhaW5zKHBvaW50LngscG9pbnQueSkpDQotCQl7DQotCQkJbV9zRGF0YS5TdWJCaWcoKTsNCi0JCQlNb3ZlUG9zQnV0dG9uKFRSVUUpOw0KLQkJCU5vdGlmeVNjcm9sbFdpbmRvdygpOw0KLQkJfQ0KLQ0KLQkJaWYgKHJjTWF4QXJlYS5Db250YWlucyhwb2ludC54LHBvaW50LnkpKQ0KLQkJew0KLQkJCW1fc0RhdGEuQWRkQmlnKCk7DQotCQkJTW92ZVBvc0J1dHRvbihUUlVFKTsNCi0JCQlOb3RpZnlTY3JvbGxXaW5kb3coKTsNCi0JCX0NCi0JfQ0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotRlhfQk9PTCBDUFdMX1Njcm9sbEJhcjo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykNCi17DQotCUNQV0xfV25kOjpPbkxCdXR0b25VcChwb2ludCxuRmxhZyk7DQotDQotCWlmIChIYXNGbGFnKFBXU19BVVRPVFJBTlNQQVJFTlQpKQ0KLQl7DQotCQlpZiAoR2V0VHJhbnNwYXJlbmN5KCkgIT0gUFdMX1NDUk9MTEJBUl9UUkFOU1BBUkFOQ1kpDQotCQl7DQotCQkJU2V0VHJhbnNwYXJlbmN5KFBXTF9TQ1JPTExCQVJfVFJBTlNQQVJBTkNZKTsNCi0JCQlJbnZhbGlkYXRlUmVjdCgpOw0KLQkJfQ0KLQl9DQotDQotCUVuZFRpbWVyKCk7DQotCW1fYk1vdXNlRG93biA9IEZBTFNFOw0KLQ0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQotdm9pZCBDUFdMX1Njcm9sbEJhcjo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkNCi17DQotCUNQV0xfV25kOjpPbk5vdGlmeShwV25kLG1zZyx3UGFyYW0sbFBhcmFtKTsNCi0NCi0Jc3dpdGNoIChtc2cpDQotCXsNCi0JY2FzZSBQTk1fTEJVVFRPTkRPV046CQkJDQotCQlpZiAocFduZCA9PSBtX3BNaW5CdXR0b24pDQotCQl7DQotCQkJT25NaW5CdXR0b25MQkRvd24oKihDUERGX1BvaW50KilsUGFyYW0pOw0KLQkJfQ0KLQ0KLQkJaWYgKHBXbmQgPT0gbV9wTWF4QnV0dG9uKQ0KLQkJew0KLQkJCU9uTWF4QnV0dG9uTEJEb3duKCooQ1BERl9Qb2ludCopbFBhcmFtKTsNCi0JCX0NCi0NCi0JCWlmIChwV25kID09IG1fcFBvc0J1dHRvbikNCi0JCXsNCi0JCQlPblBvc0J1dHRvbkxCRG93bigqKENQREZfUG9pbnQqKWxQYXJhbSk7CQkJCQ0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgUE5NX0xCVVRUT05VUDoNCi0JCWlmIChwV25kID09IG1fcE1pbkJ1dHRvbikNCi0JCXsNCi0JCQlPbk1pbkJ1dHRvbkxCVXAoKihDUERGX1BvaW50KilsUGFyYW0pOwkJDQotCQl9DQotDQotCQlpZiAocFduZCA9PSBtX3BNYXhCdXR0b24pDQotCQl7DQotCQkJT25NYXhCdXR0b25MQlVwKCooQ1BERl9Qb2ludCopbFBhcmFtKTsJCQkJDQotCQl9DQotDQotCQlpZiAocFduZCA9PSBtX3BQb3NCdXR0b24pDQotCQl7DQotCQkJT25Qb3NCdXR0b25MQlVwKCooQ1BERl9Qb2ludCopbFBhcmFtKTsJCQkNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIFBOTV9NT1VTRU1PVkU6DQotCQlpZiAocFduZCA9PSBtX3BNaW5CdXR0b24pDQotCQl7DQotCQkJT25NaW5CdXR0b25Nb3VzZU1vdmUoKihDUERGX1BvaW50KilsUGFyYW0pOw0KLQkJfQ0KLQ0KLQkJaWYgKHBXbmQgPT0gbV9wTWF4QnV0dG9uKQ0KLQkJew0KLQkJCU9uTWF4QnV0dG9uTW91c2VNb3ZlKCooQ1BERl9Qb2ludCopbFBhcmFtKTsJCQkJDQotCQl9DQotDQotCQlpZiAocFduZCA9PSBtX3BQb3NCdXR0b24pDQotCQl7DQotCQkJT25Qb3NCdXR0b25Nb3VzZU1vdmUoKihDUERGX1BvaW50KilsUGFyYW0pOwkJCQkNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIFBOTV9TRVRTQ1JPTExJTkZPOg0KLQkJew0KLQkJCWlmIChQV0xfU0NST0xMX0lORk8gKiBwSW5mbyA9IChQV0xfU0NST0xMX0lORk8qKWxQYXJhbSkNCi0JCQl7DQotCQkJCWlmIChGWFNZU19tZW1jbXAoJm1fT3JpZ2luSW5mbywgcEluZm8sIHNpemVvZihQV0xfU0NST0xMX0lORk8pKSAhPSAwKQ0KLQkJCQl7DQotCQkJCQltX09yaWdpbkluZm8gPSAqcEluZm87DQotCQkJCQlGWF9GTE9BVCBmTWF4ID0gcEluZm8tPmZDb250ZW50TWF4IC0gcEluZm8tPmZDb250ZW50TWluIC0gcEluZm8tPmZQbGF0ZVdpZHRoOw0KLQkJCQkJZk1heCA9IGZNYXggPiAwLjBmID8gZk1heCA6IDAuMGY7DQotCQkJCQl0aGlzLT5TZXRTY3JvbGxSYW5nZSgwLGZNYXgsIHBJbmZvLT5mUGxhdGVXaWR0aCk7DQotCQkJCQl0aGlzLT5TZXRTY3JvbGxTdGVwKHBJbmZvLT5mQmlnU3RlcCxwSW5mby0+ZlNtYWxsU3RlcCk7DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBQTk1fU0VUU0NST0xMUE9TOg0KLQkJew0KLQkJCUZYX0ZMT0FUIGZQb3MgPSAqKEZYX0ZMT0FUKilsUGFyYW07DQotCQkJc3dpdGNoICh0aGlzLT5tX3NiVHlwZSkNCi0JCQl7DQotCQkJY2FzZSBTQlRfSFNDUk9MTDoNCi0JCQkJZlBvcyA9IGZQb3MgLSBtX09yaWdpbkluZm8uZkNvbnRlbnRNaW47DQotCQkJCWJyZWFrOw0KLQkJCWNhc2UgU0JUX1ZTQ1JPTEw6DQotCQkJCWZQb3MgPSBtX09yaWdpbkluZm8uZkNvbnRlbnRNYXggLSBmUG9zOw0KLQkJCQlicmVhazsNCi0JCQl9DQotCQkJdGhpcy0+U2V0U2Nyb2xsUG9zKGZQb3MpOw0KLQkJfQ0KLQkJYnJlYWs7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX1Njcm9sbEJhcjo6Q3JlYXRlQnV0dG9ucyhjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkNCi17DQotCVBXTF9DUkVBVEVQQVJBTQlzY3AgPSBjcDsNCi0Jc2NwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQlzY3AuZHdCb3JkZXJXaWR0aCA9IDI7DQotCXNjcC5uQm9yZGVyU3R5bGUgPSBQQlNfQkVWRUxFRDsNCi0JDQotCXNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQV1NfQk9SREVSIHwgUFdTX0JBQ0tHUk9VTkQgfCBQV1NfTk9SRUZSRVNIQ0xJUDsNCi0NCi0JaWYgKCFtX3BNaW5CdXR0b24pIA0KLQl7DQotCQltX3BNaW5CdXR0b24gPSBuZXcgQ1BXTF9TQkJ1dHRvbihtX3NiVHlwZSxQU0JUX01JTik7DQotCQltX3BNaW5CdXR0b24tPkNyZWF0ZShzY3ApOw0KLQl9DQotDQotCWlmICghbV9wTWF4QnV0dG9uKQ0KLQl7DQotCQltX3BNYXhCdXR0b24gPSBuZXcgQ1BXTF9TQkJ1dHRvbihtX3NiVHlwZSxQU0JUX01BWCk7DQotCQltX3BNYXhCdXR0b24tPkNyZWF0ZShzY3ApOw0KLQl9DQotDQotCWlmICghbV9wUG9zQnV0dG9uKQ0KLQl7DQotCQltX3BQb3NCdXR0b24gPSBuZXcgQ1BXTF9TQkJ1dHRvbihtX3NiVHlwZSxQU0JUX1BPUyk7DQotCQltX3BQb3NCdXR0b24tPlNldFZpc2libGUoRkFMU0UpOw0KLQkJbV9wUG9zQnV0dG9uLT5DcmVhdGUoc2NwKTsNCi0JfQ0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX1Njcm9sbEJhcjo6R2V0U2Nyb2xsQmFyV2lkdGgoKSBjb25zdA0KLXsNCi0JaWYgKCFJc1Zpc2libGUoKSkgcmV0dXJuIDA7DQotDQotCXJldHVybiBQV0xfU0NST0xMQkFSX1dJRFRIOw0KLX0NCi0NCi12b2lkIENQV0xfU2Nyb2xsQmFyOjpTZXRTY3JvbGxSYW5nZShGWF9GTE9BVCBmTWluLEZYX0ZMT0FUIGZNYXgsRlhfRkxPQVQgZkNsaWVudFdpZHRoKQ0KLXsNCi0JaWYgKG1fcFBvc0J1dHRvbikNCi0Jew0KLQkJbV9zRGF0YS5TZXRTY3JvbGxSYW5nZShmTWluLGZNYXgpOw0KLQkJbV9zRGF0YS5TZXRDbGllbnRXaWR0aChmQ2xpZW50V2lkdGgpOw0KLQ0KLQkJaWYgKElzRmxvYXRTbWFsbGVyKG1fc0RhdGEuU2Nyb2xsUmFuZ2UuR2V0V2lkdGgoKSwgMC4wZikpDQotCQl7DQotCQkJbV9wUG9zQnV0dG9uLT5TZXRWaXNpYmxlKEZBTFNFKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQltX3BQb3NCdXR0b24tPlNldFZpc2libGUoVFJVRSk7CQ0KLQkJCU1vdmVQb3NCdXR0b24oVFJVRSk7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDUFdMX1Njcm9sbEJhcjo6U2V0U2Nyb2xsUG9zKEZYX0ZMT0FUIGZQb3MpDQotew0KLQlGWF9GTE9BVCBmT2xkUG9zID0gbV9zRGF0YS5mU2Nyb2xsUG9zOw0KLQ0KLQltX3NEYXRhLlNldFBvcyhmUG9zKTsNCi0NCi0JaWYgKCFJc0Zsb2F0RXF1YWwobV9zRGF0YS5mU2Nyb2xsUG9zLCBmT2xkUG9zKSkNCi0JCU1vdmVQb3NCdXR0b24oVFJVRSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6OlNldFNjcm9sbFN0ZXAoRlhfRkxPQVQgZkJpZ1N0ZXAsRlhfRkxPQVQgZlNtYWxsU3RlcCkNCi17DQotCW1fc0RhdGEuU2V0QmlnU3RlcChmQmlnU3RlcCk7DQotCW1fc0RhdGEuU2V0U21hbGxTdGVwKGZTbWFsbFN0ZXApOw0KLX0NCi0NCi12b2lkIENQV0xfU2Nyb2xsQmFyOjpNb3ZlUG9zQnV0dG9uKEZYX0JPT0wgYlJlZnJlc2gpDQotew0KLQlBU1NFUlQgKG1fcFBvc0J1dHRvbiAhPSBOVUxMKTsNCi0JQVNTRVJUIChtX3BNaW5CdXR0b24gIT0gTlVMTCk7DQotCUFTU0VSVCAobV9wTWF4QnV0dG9uICE9IE5VTEwpOw0KLQ0KLQlpZiAobV9wUG9zQnV0dG9uLT5Jc1Zpc2libGUoKSkNCi0Jew0KLQ0KLQ0KLQ0KLQ0KLQkJQ1BERl9SZWN0IHJjQ2xpZW50Ow0KLQkJQ1BERl9SZWN0IHJjUG9zQXJlYSxyY1Bvc0J1dHRvbjsJDQotDQotCQlyY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsNCi0JCXJjUG9zQXJlYSA9IEdldFNjcm9sbEFyZWEoKTsNCi0NCi0JCUZYX0ZMT0FUIGZMZWZ0LGZSaWdodCxmVG9wLGZCb3R0b207DQotDQotCQlzd2l0Y2ggKG1fc2JUeXBlKQ0KLQkJew0KLQkJY2FzZSBTQlRfSFNDUk9MTDoNCi0JCQlmTGVmdCA9IFRydWVUb0ZhY2UobV9zRGF0YS5mU2Nyb2xsUG9zKTsNCi0JCQlmUmlnaHQgPSBUcnVlVG9GYWNlKG1fc0RhdGEuZlNjcm9sbFBvcyArIG1fc0RhdGEuZkNsaWVudFdpZHRoKTsNCi0NCi0JCQlpZiAoZlJpZ2h0IC0gZkxlZnQgPCBQV0xfU0NST0xMQkFSX1BPU0JVVFRPTl9NSU5XSURUSCkNCi0JCQkJZlJpZ2h0ID0gZkxlZnQgKyBQV0xfU0NST0xMQkFSX1BPU0JVVFRPTl9NSU5XSURUSDsNCi0NCi0JCQlpZiAoZlJpZ2h0ID4gcmNQb3NBcmVhLnJpZ2h0KQ0KLQkJCXsNCi0JCQkJZlJpZ2h0ID0gcmNQb3NBcmVhLnJpZ2h0Ow0KLQkJCQlmTGVmdCA9IGZSaWdodCAtIFBXTF9TQ1JPTExCQVJfUE9TQlVUVE9OX01JTldJRFRIOw0KLQkJCX0NCi0NCi0JCQlyY1Bvc0J1dHRvbiA9IENQREZfUmVjdChmTGVmdCAsDQotCQkJCQkJCQlyY1Bvc0FyZWEuYm90dG9tLA0KLQkJCQkJCQkJZlJpZ2h0ICwNCi0JCQkJCQkJCXJjUG9zQXJlYS50b3ApOw0KLQkJCQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBTQlRfVlNDUk9MTDoNCi0JCQlmQm90dG9tID0gVHJ1ZVRvRmFjZShtX3NEYXRhLmZTY3JvbGxQb3MgKyBtX3NEYXRhLmZDbGllbnRXaWR0aCk7DQotCQkJZlRvcCA9IFRydWVUb0ZhY2UobV9zRGF0YS5mU2Nyb2xsUG9zKTsNCi0NCi0JCQlpZiAoSXNGbG9hdFNtYWxsZXIoZlRvcCAtIGZCb3R0b20sIFBXTF9TQ1JPTExCQVJfUE9TQlVUVE9OX01JTldJRFRIKSkNCi0JCQkJZkJvdHRvbSA9IGZUb3AgLSBQV0xfU0NST0xMQkFSX1BPU0JVVFRPTl9NSU5XSURUSDsNCi0JCQkNCi0JCQlpZiAoSXNGbG9hdFNtYWxsZXIoZkJvdHRvbSwgcmNQb3NBcmVhLmJvdHRvbSkpDQotCQkJew0KLQkJCQlmQm90dG9tID0gcmNQb3NBcmVhLmJvdHRvbTsNCi0JCQkJZlRvcCA9IGZCb3R0b20gKyBQV0xfU0NST0xMQkFSX1BPU0JVVFRPTl9NSU5XSURUSDsNCi0JCQl9DQotDQotCQkJcmNQb3NCdXR0b24gPSBDUERGX1JlY3QocmNQb3NBcmVhLmxlZnQsDQotCQkJCQkJCQlmQm90dG9tLAkJCQkJCQkJDQotCQkJCQkJCQlyY1Bvc0FyZWEucmlnaHQsDQotCQkJCQkJCQlmVG9wKTsNCi0JCQkNCi0JCQlicmVhazsNCi0JCX0NCi0NCi0JCW1fcFBvc0J1dHRvbi0+TW92ZShyY1Bvc0J1dHRvbixUUlVFLGJSZWZyZXNoKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfU2Nyb2xsQmFyOjpPbk1pbkJ1dHRvbkxCRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpDQotew0KLQltX3NEYXRhLlN1YlNtYWxsKCk7DQotCU1vdmVQb3NCdXR0b24oVFJVRSk7DQotCU5vdGlmeVNjcm9sbFdpbmRvdygpOw0KLQ0KLQltX2JNaW5Pck1heCA9IFRSVUU7DQotDQotCUVuZFRpbWVyKCk7DQotCUJlZ2luVGltZXIoMTAwKTsNCi19DQotDQotdm9pZCBDUFdMX1Njcm9sbEJhcjo6T25NaW5CdXR0b25MQlVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uTWluQnV0dG9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkNCi17CQ0KLX0NCi0NCi12b2lkIENQV0xfU2Nyb2xsQmFyOjpPbk1heEJ1dHRvbkxCRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpDQotew0KLQltX3NEYXRhLkFkZFNtYWxsKCk7DQotCU1vdmVQb3NCdXR0b24oVFJVRSk7DQotCU5vdGlmeVNjcm9sbFdpbmRvdygpOw0KLQ0KLQltX2JNaW5Pck1heCA9IEZBTFNFOw0KLQkNCi0JRW5kVGltZXIoKTsNCi0JQmVnaW5UaW1lcigxMDApOw0KLX0NCi0NCi12b2lkIENQV0xfU2Nyb2xsQmFyOjpPbk1heEJ1dHRvbkxCVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQ0KLXsNCi19DQotDQotdm9pZCBDUFdMX1Njcm9sbEJhcjo6T25NYXhCdXR0b25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQ0KLXsJDQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uUG9zQnV0dG9uTEJEb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkNCi17DQotCW1fYk1vdXNlRG93biA9IFRSVUU7DQotDQotCWlmIChtX3BQb3NCdXR0b24pDQotCXsNCi0JCUNQREZfUmVjdCByY1Bvc0J1dHRvbiA9IG1fcFBvc0J1dHRvbi0+R2V0V2luZG93UmVjdCgpOw0KLQ0KLQkJc3dpdGNoKG1fc2JUeXBlKQ0KLQkJew0KLQkJY2FzZSBTQlRfSFNDUk9MTDoNCi0JCQltX25PbGRQb3MgPSBwb2ludC54Ow0KLQkJCW1fZk9sZFBvc0J1dHRvbiA9IHJjUG9zQnV0dG9uLmxlZnQ7DQotCQkJYnJlYWs7DQotCQljYXNlIFNCVF9WU0NST0xMOg0KLQkJCW1fbk9sZFBvcyA9IHBvaW50Lnk7DQotCQkJbV9mT2xkUG9zQnV0dG9uID0gcmNQb3NCdXR0b24udG9wOw0KLQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uUG9zQnV0dG9uTEJVcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpDQotew0KLQlpZiAobV9iTW91c2VEb3duKQ0KLQl7DQotCQlpZiAoIW1fYk5vdGlmeUZvcmV2ZXIpDQotCQkJTm90aWZ5U2Nyb2xsV2luZG93KCk7DQotCX0NCi0JbV9iTW91c2VEb3duID0gRkFMU0U7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uUG9zQnV0dG9uTW91c2VNb3ZlKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkNCi17DQotCUZYX0ZMT0FUIGZPbGRTY3JvbGxQb3MgPSBtX3NEYXRhLmZTY3JvbGxQb3M7DQotDQotCUZYX0ZMT0FUIGZOZXdQb3MgPSAwOw0KLQ0KLQlzd2l0Y2ggKG1fc2JUeXBlKQ0KLQl7DQotCWNhc2UgU0JUX0hTQ1JPTEw6DQotCQlpZiAoRlhTWVNfZmFicyhwb2ludC54IC0gbV9uT2xkUG9zKSA8IDEpIHJldHVybjsNCi0JCWZOZXdQb3MgPSBGYWNlVG9UcnVlKG1fZk9sZFBvc0J1dHRvbiArIHBvaW50LnggLSBtX25PbGRQb3MpOw0KLQkJYnJlYWs7DQotCWNhc2UgU0JUX1ZTQ1JPTEw6DQotCQlpZiAoRlhTWVNfZmFicyhwb2ludC55IC0gbV9uT2xkUG9zKSA8IDEpIHJldHVybjsNCi0JCWZOZXdQb3MgPSBGYWNlVG9UcnVlKG1fZk9sZFBvc0J1dHRvbiArIHBvaW50LnkgLSBtX25PbGRQb3MpOw0KLQkJYnJlYWs7DQotCX0NCi0NCi0JaWYgKG1fYk1vdXNlRG93bikNCi0Jew0KLQkJc3dpdGNoIChtX3NiVHlwZSkNCi0JCXsNCi0JCWNhc2UgU0JUX0hTQ1JPTEw6DQotDQotCQkJaWYgKElzRmxvYXRTbWFsbGVyKGZOZXdQb3MsIG1fc0RhdGEuU2Nyb2xsUmFuZ2UuZk1pbikpDQotCQkJew0KLQkJCQlmTmV3UG9zID0gbV9zRGF0YS5TY3JvbGxSYW5nZS5mTWluOw0KLQkJCX0NCi0NCi0JCQlpZiAoSXNGbG9hdEJpZ2dlcihmTmV3UG9zLCBtX3NEYXRhLlNjcm9sbFJhbmdlLmZNYXgpKQ0KLQkJCXsNCi0JCQkJZk5ld1BvcyA9IG1fc0RhdGEuU2Nyb2xsUmFuZ2UuZk1heDsNCi0JCQl9DQotDQotCQkJbV9zRGF0YS5TZXRQb3MoZk5ld1Bvcyk7DQotCQkJDQotCQkJYnJlYWs7DQotCQljYXNlIFNCVF9WU0NST0xMOg0KLQkJDQotCQkJaWYgKElzRmxvYXRTbWFsbGVyKGZOZXdQb3MsIG1fc0RhdGEuU2Nyb2xsUmFuZ2UuZk1pbikpDQotCQkJew0KLQkJCQlmTmV3UG9zID0gbV9zRGF0YS5TY3JvbGxSYW5nZS5mTWluOw0KLQkJCX0NCi0NCi0JCQlpZiAoSXNGbG9hdEJpZ2dlcihmTmV3UG9zLCBtX3NEYXRhLlNjcm9sbFJhbmdlLmZNYXgpKQ0KLQkJCXsNCi0JCQkJZk5ld1BvcyA9IG1fc0RhdGEuU2Nyb2xsUmFuZ2UuZk1heDsNCi0JCQl9CQ0KLQ0KLQkJCW1fc0RhdGEuU2V0UG9zKGZOZXdQb3MpOw0KLQkJDQotCQkJYnJlYWs7DQotCQl9CQ0KLQkJDQotCQlpZiAoIUlzRmxvYXRFcXVhbChmT2xkU2Nyb2xsUG9zLCBtX3NEYXRhLmZTY3JvbGxQb3MpKQ0KLQkJewkJCQ0KLQkJCU1vdmVQb3NCdXR0b24oVFJVRSk7DQotDQotCQkJaWYgKG1fYk5vdGlmeUZvcmV2ZXIpDQotCQkJCU5vdGlmeVNjcm9sbFdpbmRvdygpOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok5vdGlmeVNjcm9sbFdpbmRvdygpDQotew0KLQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpDQotCXsNCi0JCUZYX0ZMT0FUIGZQb3M7DQotCQlzd2l0Y2ggKHRoaXMtPm1fc2JUeXBlKQ0KLQkJew0KLQkJY2FzZSBTQlRfSFNDUk9MTDoNCi0JCQlmUG9zID0gbV9PcmlnaW5JbmZvLmZDb250ZW50TWluICsgbV9zRGF0YS5mU2Nyb2xsUG9zOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBTQlRfVlNDUk9MTDoNCi0JCQlmUG9zID0gbV9PcmlnaW5JbmZvLmZDb250ZW50TWF4IC0gbV9zRGF0YS5mU2Nyb2xsUG9zOw0KLQkJCWJyZWFrOw0KLQkJfQkNCi0JCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsUE5NX1NDUk9MTFdJTkRPVywoRlhfSU5UUFRSKW1fc2JUeXBlLChGWF9JTlRQVFIpJmZQb3MpOw0KLQl9DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX1Njcm9sbEJhcjo6R2V0U2Nyb2xsQXJlYSgpIGNvbnN0DQotew0KLQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7DQotCUNQREZfUmVjdCByY0FyZWE7DQotDQotCWlmICghbV9wTWluQnV0dG9uIHx8ICFtX3BNYXhCdXR0b24pcmV0dXJuIHJjQ2xpZW50Ow0KLQ0KLQlDUERGX1JlY3QgcmNNaW4gPSBtX3BNaW5CdXR0b24tPkdldFdpbmRvd1JlY3QoKTsNCi0JQ1BERl9SZWN0IHJjTWF4ID0gbV9wTWF4QnV0dG9uLT5HZXRXaW5kb3dSZWN0KCk7DQotDQotCUZYX0ZMT0FUIGZNaW5XaWR0aCA9IHJjTWluLnJpZ2h0IC0gcmNNaW4ubGVmdDsNCi0JRlhfRkxPQVQgZk1pbkhlaWdodCA9IHJjTWluLnRvcCAtIHJjTWluLmJvdHRvbTsNCi0JRlhfRkxPQVQgZk1heFdpZHRoID0gcmNNYXgucmlnaHQgLSByY01heC5sZWZ0Ow0KLQlGWF9GTE9BVCBmTWF4SGVpZ2h0ID0gcmNNYXgudG9wIC0gcmNNYXguYm90dG9tOw0KLQ0KLQlzd2l0Y2gobV9zYlR5cGUpDQotCXsNCi0JY2FzZSBTQlRfSFNDUk9MTDoNCi0JCWlmIChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQgPiBmTWluV2lkdGggKyBmTWF4V2lkdGggKyAyKQ0KLQkJew0KLQkJCXJjQXJlYSA9IENQREZfUmVjdChyY0NsaWVudC5sZWZ0ICsgZk1pbldpZHRoICsgMSxyY0NsaWVudC5ib3R0b20sDQotCQkJCQkJcmNDbGllbnQucmlnaHQgLSBmTWF4V2lkdGggLSAxLHJjQ2xpZW50LnRvcCk7DQotCQl9DQotCQllbHNlDQotCQl7DQotCQkJcmNBcmVhID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQgKyBmTWluV2lkdGggKyAxLHJjQ2xpZW50LmJvdHRvbSwNCi0JCQkJCQlyY0NsaWVudC5sZWZ0ICsgZk1pbldpZHRoICsgMSxyY0NsaWVudC50b3ApOw0KLQkJfQ0KLQkJYnJlYWs7DQotCWNhc2UgU0JUX1ZTQ1JPTEw6DQotCQlpZiAocmNDbGllbnQudG9wIC0gcmNDbGllbnQuYm90dG9tID4gZk1pbkhlaWdodCArIGZNYXhIZWlnaHQgKyAyKQ0KLQkJew0KLQkJCXJjQXJlYSA9IENQREZfUmVjdChyY0NsaWVudC5sZWZ0LHJjQ2xpZW50LmJvdHRvbSArIGZNaW5IZWlnaHQgKyAxLA0KLQkJCQkJCXJjQ2xpZW50LnJpZ2h0LHJjQ2xpZW50LnRvcCAtIGZNYXhIZWlnaHQgLSAxKTsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlyY0FyZWEgPSBDUERGX1JlY3QocmNDbGllbnQubGVmdCxyY0NsaWVudC5ib3R0b20gKyBmTWluSGVpZ2h0ICsgMSwNCi0JCQkJCQlyY0NsaWVudC5yaWdodCxyY0NsaWVudC5ib3R0b20gKyBmTWluSGVpZ2h0ICsgMSk7DQotCQl9DQotCQlicmVhazsNCi0JfQ0KLQkNCi0JcmNBcmVhLk5vcm1hbGl6ZSgpOw0KLQ0KLQlyZXR1cm4gcmNBcmVhOw0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX1Njcm9sbEJhcjo6VHJ1ZVRvRmFjZShGWF9GTE9BVCBmVHJ1ZSkNCi17DQotCUNQREZfUmVjdCByY1Bvc0FyZWE7CQ0KLQlyY1Bvc0FyZWEgPSBHZXRTY3JvbGxBcmVhKCk7DQotDQotCUZYX0ZMT0FUIGZGYWN0V2lkdGggPSBtX3NEYXRhLlNjcm9sbFJhbmdlLkdldFdpZHRoKCkgKyBtX3NEYXRhLmZDbGllbnRXaWR0aDsNCi0JZkZhY3RXaWR0aCA9IGZGYWN0V2lkdGggPT0gMCA/IDEgOiBmRmFjdFdpZHRoOw0KLQ0KLQlGWF9GTE9BVCBmRmFjZSA9IDA7DQotDQotCXN3aXRjaChtX3NiVHlwZSkNCi0Jew0KLQljYXNlIFNCVF9IU0NST0xMOg0KLQkJZkZhY2UgPSByY1Bvc0FyZWEubGVmdCArIGZUcnVlICogKHJjUG9zQXJlYS5yaWdodCAtIHJjUG9zQXJlYS5sZWZ0KSAvIGZGYWN0V2lkdGg7DQotCQlicmVhazsNCi0JY2FzZSBTQlRfVlNDUk9MTDoNCi0JCWZGYWNlID0gcmNQb3NBcmVhLnRvcCAtIGZUcnVlICogKHJjUG9zQXJlYS50b3AgLSByY1Bvc0FyZWEuYm90dG9tKSAvIGZGYWN0V2lkdGg7DQotCQlicmVhazsNCi0JfQkNCi0NCi0JcmV0dXJuIGZGYWNlOw0KLX0NCi0NCi1GWF9GTE9BVCBDUFdMX1Njcm9sbEJhcjo6RmFjZVRvVHJ1ZShGWF9GTE9BVCBmRmFjZSkNCi17DQotCUNQREZfUmVjdCByY1Bvc0FyZWE7CQ0KLQlyY1Bvc0FyZWEgPSBHZXRTY3JvbGxBcmVhKCk7DQotDQotCUZYX0ZMT0FUIGZGYWN0V2lkdGggPSBtX3NEYXRhLlNjcm9sbFJhbmdlLkdldFdpZHRoKCkgKyBtX3NEYXRhLmZDbGllbnRXaWR0aDsNCi0JZkZhY3RXaWR0aCA9IGZGYWN0V2lkdGggPT0gMCA/IDEgOiBmRmFjdFdpZHRoOw0KLQ0KLQlGWF9GTE9BVCBmVHJ1ZSA9IDA7DQotDQotCXN3aXRjaChtX3NiVHlwZSkNCi0Jew0KLQljYXNlIFNCVF9IU0NST0xMOg0KLQkJZlRydWUgPSAgKGZGYWNlIC0gcmNQb3NBcmVhLmxlZnQpICogZkZhY3RXaWR0aCAvIChyY1Bvc0FyZWEucmlnaHQgLSByY1Bvc0FyZWEubGVmdCk7DQotCQlicmVhazsNCi0JY2FzZSBTQlRfVlNDUk9MTDoNCi0JCWZUcnVlID0gKHJjUG9zQXJlYS50b3AgLSBmRmFjZSkgKiBmRmFjdFdpZHRoIC8gKHJjUG9zQXJlYS50b3AgLSByY1Bvc0FyZWEuYm90dG9tKTsNCi0JCWJyZWFrOw0KLQl9CQ0KLQ0KLQlyZXR1cm4gZlRydWU7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0KLXsNCi0JQ3JlYXRlQnV0dG9ucyhjcCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TY3JvbGxCYXI6OlRpbWVyUHJvYygpDQotew0KLQlQV0xfU0NST0xMX1BSSVZBVEVEQVRBIHNUZW1wID0gbV9zRGF0YTsNCi0NCi0JaWYgKG1fYk1pbk9yTWF4KW1fc0RhdGEuU3ViU21hbGwoKTsJDQotCWVsc2UgbV9zRGF0YS5BZGRTbWFsbCgpOw0KLQ0KLQlpZiAoRlhTWVNfbWVtY21wKCZtX3NEYXRhLCAmc1RlbXAsIHNpemVvZihQV0xfU0NST0xMX1BSSVZBVEVEQVRBKSkgIT0gMCkNCi0Jew0KLQkJTW92ZVBvc0J1dHRvbihUUlVFKTsNCi0JCU5vdGlmeVNjcm9sbFdpbmRvdygpOw0KLQl9DQotfQ0KLQ0KLS8qDQotdm9pZCBDUFdMX1Njcm9sbEJhcjo6T25TZXRGb2N1cygpDQotew0KLQlpZiAoR2V0VHJhbnNwYXJlbmN5KCkgIT0gMjU1KQ0KLQl7DQotCQlTZXRUcmFuc3BhcmVuY3koMjU1KTsNCi0JCUludmFsaWRhdGVSZWN0KCk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX1Njcm9sbEJhcjo6T25LaWxsRm9jdXMoKQ0KLXsNCi0JaWYgKEdldFRyYW5zcGFyZW5jeSgpICE9IFBXTF9TQ1JPTExCQVJfVFJBTlNQQVJBTkNZKQ0KLQl7DQotCQlTZXRUcmFuc3BhcmVuY3koUFdMX1NDUk9MTEJBUl9UUkFOU1BBUkFOQ1kpOw0KLQkJSW52YWxpZGF0ZVJlY3QoKTsNCi0JfQ0KLX0NCi0qLw0KLQ0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgorCisjZGVmaW5lIElzRmxvYXRaZXJvKGYpCQkJCQkJKChmKSA8IDAuMDAwMSAmJiAoZikgPiAtMC4wMDAxKQorI2RlZmluZSBJc0Zsb2F0QmlnZ2VyKGZhLGZiKQkJCQkoKGZhKSA+IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkKKyNkZWZpbmUgSXNGbG9hdFNtYWxsZXIoZmEsZmIpCQkJCSgoZmEpIDwgKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQorI2RlZmluZSBJc0Zsb2F0RXF1YWwoZmEsZmIpCQkJCQlJc0Zsb2F0WmVybygoZmEpLShmYikpCisKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBQV0xfRkxPQVRSQU5HRSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK1BXTF9GTE9BVFJBTkdFOjpQV0xfRkxPQVRSQU5HRSgpCit7CisJRGVmYXVsdCgpOworfQorCitQV0xfRkxPQVRSQU5HRTo6UFdMX0ZMT0FUUkFOR0UoRlhfRkxPQVQgbWluLEZYX0ZMT0FUIG1heCkKK3sKKwlTZXQobWluLG1heCk7Cit9CisKK3ZvaWQgUFdMX0ZMT0FUUkFOR0U6OkRlZmF1bHQoKQoreworCWZNaW4gPSAwOworCWZNYXggPSAwOworfQorCit2b2lkIFBXTF9GTE9BVFJBTkdFOjpTZXQoRlhfRkxPQVQgbWluLEZYX0ZMT0FUIG1heCkKK3sKKwlpZiAobWluID4gbWF4KQorCXsKKwkJZk1pbiA9IG1heDsKKwkJZk1heCA9IG1pbjsKKwl9CisJZWxzZQorCXsKKwkJZk1pbiA9IG1pbjsKKwkJZk1heCA9IG1heDsKKwl9Cit9CisKK0ZYX0JPT0wJUFdMX0ZMT0FUUkFOR0U6OkluKEZYX0ZMT0FUIHgpIGNvbnN0Cit7CisJcmV0dXJuIChJc0Zsb2F0QmlnZ2VyKHgsZk1pbikgfHwgSXNGbG9hdEVxdWFsKHgsIGZNaW4pKSAmJiAKKwkJKElzRmxvYXRTbWFsbGVyKHgsIGZNYXgpIHx8IElzRmxvYXRFcXVhbCh4LCBmTWF4KSk7Cit9CisKK0ZYX0ZMT0FUIFBXTF9GTE9BVFJBTkdFOjpHZXRXaWR0aCgpIGNvbnN0Cit7CisJcmV0dXJuIGZNYXggLSBmTWluOworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFBXTF9TQ1JPTExfUFJJVkFURURBVEEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitQV0xfU0NST0xMX1BSSVZBVEVEQVRBOjpQV0xfU0NST0xMX1BSSVZBVEVEQVRBKCkKK3sKKwlEZWZhdWx0KCk7Cit9CisKK3ZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6RGVmYXVsdCgpCit7CisJU2Nyb2xsUmFuZ2UuRGVmYXVsdCgpOworCWZTY3JvbGxQb3MgPSBTY3JvbGxSYW5nZS5mTWluOworCWZDbGllbnRXaWR0aCA9IDA7CisJZkJpZ1N0ZXAgPSAxMDsKKwlmU21hbGxTdGVwID0gMTsKK30KKwordm9pZCBQV0xfU0NST0xMX1BSSVZBVEVEQVRBOjpTZXRTY3JvbGxSYW5nZShGWF9GTE9BVCBtaW4sRlhfRkxPQVQgbWF4KQoreworCVNjcm9sbFJhbmdlLlNldChtaW4sbWF4KTsKKworCWlmIChJc0Zsb2F0U21hbGxlcihmU2Nyb2xsUG9zLCBTY3JvbGxSYW5nZS5mTWluKSkKKwkJZlNjcm9sbFBvcyA9IFNjcm9sbFJhbmdlLmZNaW47CisJaWYgKElzRmxvYXRCaWdnZXIoZlNjcm9sbFBvcywgU2Nyb2xsUmFuZ2UuZk1heCkpCisJCWZTY3JvbGxQb3MgPSBTY3JvbGxSYW5nZS5mTWF4OwkJCit9CisKK3ZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U2V0Q2xpZW50V2lkdGgoRlhfRkxPQVQgd2lkdGgpCit7CisJZkNsaWVudFdpZHRoID0gd2lkdGg7Cit9CisKK3ZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U2V0U21hbGxTdGVwKEZYX0ZMT0FUIHN0ZXApCit7CisJZlNtYWxsU3RlcCA9IHN0ZXA7Cit9CisKK3ZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U2V0QmlnU3RlcChGWF9GTE9BVCBzdGVwKQoreworCWZCaWdTdGVwID0gc3RlcDsKK30KKworRlhfQk9PTCBQV0xfU0NST0xMX1BSSVZBVEVEQVRBOjpTZXRQb3MoRlhfRkxPQVQgcG9zKQoreworCWlmIChTY3JvbGxSYW5nZS5Jbihwb3MpKQorCXsKKwkJZlNjcm9sbFBvcyA9IHBvczsKKwkJcmV0dXJuIFRSVUU7CisJfQorCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBQV0xfU0NST0xMX1BSSVZBVEVEQVRBOjpBZGRTbWFsbCgpCit7CisJaWYgKCFTZXRQb3MoZlNjcm9sbFBvcyArIGZTbWFsbFN0ZXApKQorCQlTZXRQb3MoU2Nyb2xsUmFuZ2UuZk1heCk7Cit9CisKK3ZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U3ViU21hbGwoKQoreworCWlmICghU2V0UG9zKGZTY3JvbGxQb3MgLSBmU21hbGxTdGVwKSkKKwkJU2V0UG9zKFNjcm9sbFJhbmdlLmZNaW4pOworfQorCit2b2lkIFBXTF9TQ1JPTExfUFJJVkFURURBVEE6OkFkZEJpZygpCit7CisJaWYgKCFTZXRQb3MoZlNjcm9sbFBvcyArIGZCaWdTdGVwKSkKKwkJU2V0UG9zKFNjcm9sbFJhbmdlLmZNYXgpOwkJCit9CisKK3ZvaWQgUFdMX1NDUk9MTF9QUklWQVRFREFUQTo6U3ViQmlnKCkKK3sKKwlpZiAoIVNldFBvcyhmU2Nyb2xsUG9zIC0gZkJpZ1N0ZXApKQorCQlTZXRQb3MoU2Nyb2xsUmFuZ2UuZk1pbik7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9TQkJ1dHRvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfU0JCdXR0b246OkNQV0xfU0JCdXR0b24oUFdMX1NDUk9MTEJBUl9UWVBFIGVTY3JvbGxCYXJUeXBlLFBXTF9TQkJVVFRPTl9UWVBFIGVCdXR0b25UeXBlKQoreworCW1fZVNjcm9sbEJhclR5cGUgPSBlU2Nyb2xsQmFyVHlwZTsKKwltX2VTQkJ1dHRvblR5cGUgPSBlQnV0dG9uVHlwZTsKKworCW1fYk1vdXNlRG93biA9IEZBTFNFOworfQorCitDUFdMX1NCQnV0dG9uOjp+Q1BXTF9TQkJ1dHRvbigpCit7CisKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9TQkJ1dHRvbjo6R2V0Q2xhc3NOYW1lKCkgY29uc3QKK3sKKwlyZXR1cm4gIkNQV0xfU0JCdXR0b24iOworfQorCit2b2lkIENQV0xfU0JCdXR0b246Ok9uQ3JlYXRlKFBXTF9DUkVBVEVQQVJBTSAmIGNwKQoreworCWNwLmVDdXJzb3JUeXBlID0gRlhDVF9BUlJPVzsKK30KKwordm9pZCBDUFdMX1NCQnV0dG9uOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKQoreworCUNQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsKKworCWlmICghSXNWaXNpYmxlKCkpIHJldHVybjsKKworCUNGWF9CeXRlVGV4dEJ1ZiBzQnV0dG9uOworCisJQ1BERl9SZWN0IHJlY3RXbmQgPSBHZXRXaW5kb3dSZWN0KCk7CisKKwlpZiAocmVjdFduZC5Jc0VtcHR5KCkpIHJldHVybjsKKworCXNBcHBTdHJlYW0gPDwgInFcbiI7CisKKwlDUERGX1BvaW50IHB0Q2VudGVyID0gdGhpcy0+R2V0Q2VudGVyUG9pbnQoKTsKKworCXN3aXRjaCAodGhpcy0+bV9lU2Nyb2xsQmFyVHlwZSkKKwl7CisJCWNhc2UgU0JUX0hTQ1JPTEw6CisJCQlzd2l0Y2ggKHRoaXMtPm1fZVNCQnV0dG9uVHlwZSkKKwkJCXsKKwkJCQljYXNlIFBTQlRfTUlOOgorCQkJCQl7CisJCQkJCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkpOworCQkJCQkJQ1BERl9Qb2ludCBwdDIocHRDZW50ZXIueCArIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4pOworCQkJCQkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCArIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4pOworCisJCQkJCQlpZiAocmVjdFduZC5yaWdodCAtIHJlY3RXbmQubGVmdCA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICogMiAmJgorCQkJCQkJCXJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiApCisJCQkJCQl7CisJCQkJCQkJc0J1dHRvbiA8PCAiMCBnXG4iOworCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsKKwkJCQkJCQlzQnV0dG9uIDw8IHB0Mi54IDw8ICIgIiA8PCBwdDIueSA8PCAiIGxcbiI7CisJCQkJCQkJc0J1dHRvbiA8PCBwdDMueCA8PCAiICIgPDwgcHQzLnkgPDwgIiBsXG4iOworCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbCBmXG4iOworCisJCQkJCQkJc0FwcFN0cmVhbSA8PCBzQnV0dG9uOwkKKwkJCQkJCX0KKwkJCQkJfQorCQkJCQlicmVhazsKKwkJCQljYXNlIFBTQlRfTUFYOgorCQkJCQl7CisJCQkJCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkpOworCQkJCQkJQ1BERl9Qb2ludCBwdDIocHRDZW50ZXIueCAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4pOworCQkJCQkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4pOworCisJCQkJCQlpZiAocmVjdFduZC5yaWdodCAtIHJlY3RXbmQubGVmdCA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICogMiAmJgorCQkJCQkJCXJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiApCisJCQkJCQl7CisJCQkJCQkJc0J1dHRvbiA8PCAiMCBnXG4iOworCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsKKwkJCQkJCQlzQnV0dG9uIDw8IHB0Mi54IDw8ICIgIiA8PCBwdDIueSA8PCAiIGxcbiI7CisJCQkJCQkJc0J1dHRvbiA8PCBwdDMueCA8PCAiICIgPDwgcHQzLnkgPDwgIiBsXG4iOworCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbCBmXG4iOworCisJCQkJCQkJc0FwcFN0cmVhbSA8PCBzQnV0dG9uOwkKKwkJCQkJCX0KKwkJCQkJfQorCQkJCQlicmVhazsKKwkJCQlkZWZhdWx0OgorCQkJCQlicmVhazsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFNCVF9WU0NST0xMOgorCQkJc3dpdGNoKHRoaXMtPm1fZVNCQnV0dG9uVHlwZSkKKwkJCXsKKwkJCQljYXNlIFBTQlRfTUlOOgorCQkJCQl7CisJCQkJCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4scHRDZW50ZXIueSAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41Zik7CisJCQkJCQlDUERGX1BvaW50IHB0MihwdENlbnRlci54ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4scHRDZW50ZXIueSAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41Zik7CisJCQkJCQlDUERGX1BvaW50IHB0MyhwdENlbnRlci54LHB0Q2VudGVyLnkgKyBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOworCisJCQkJCQlpZiAocmVjdFduZC5yaWdodCAtIHJlY3RXbmQubGVmdCA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICogMiAmJgorCQkJCQkJCXJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiApCisJCQkJCQl7CisJCQkJCQkJc0J1dHRvbiA8PCAiMCBnXG4iOworCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsKKwkJCQkJCQlzQnV0dG9uIDw8IHB0Mi54IDw8ICIgIiA8PCBwdDIueSA8PCAiIGxcbiI7CisJCQkJCQkJc0J1dHRvbiA8PCBwdDMueCA8PCAiICIgPDwgcHQzLnkgPDwgIiBsXG4iOworCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbCBmXG4iOworCisJCQkJCQkJc0FwcFN0cmVhbSA8PCBzQnV0dG9uOwkKKwkJCQkJCX0KKwkJCQkJfQorCQkJCQlicmVhazsKKwkJCQljYXNlIFBTQlRfTUFYOgorCQkJCQl7CisJCQkJCQlDUERGX1BvaW50IHB0MShwdENlbnRlci54IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4scHRDZW50ZXIueSArIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41Zik7CisJCQkJCQlDUERGX1BvaW50IHB0MihwdENlbnRlci54ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4scHRDZW50ZXIueSArIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41Zik7CisJCQkJCQlDUERGX1BvaW50IHB0MyhwdENlbnRlci54LHB0Q2VudGVyLnkgLSBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDAuNWYpOworCisJCQkJCQlpZiAocmVjdFduZC5yaWdodCAtIHJlY3RXbmQubGVmdCA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICogMiAmJgorCQkJCQkJCXJlY3RXbmQudG9wIC0gcmVjdFduZC5ib3R0b20gPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiApCisJCQkJCQl7CisJCQkJCQkJc0J1dHRvbiA8PCAiMCBnXG4iOworCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsKKwkJCQkJCQlzQnV0dG9uIDw8IHB0Mi54IDw8ICIgIiA8PCBwdDIueSA8PCAiIGxcbiI7CisJCQkJCQkJc0J1dHRvbiA8PCBwdDMueCA8PCAiICIgPDwgcHQzLnkgPDwgIiBsXG4iOworCQkJCQkJCXNCdXR0b24gPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbCBmXG4iOworCisJCQkJCQkJc0FwcFN0cmVhbSA8PCBzQnV0dG9uOwkKKwkJCQkJCX0KKwkJCQkJfQorCQkJCQlicmVhazsKKwkJCQlkZWZhdWx0OgorCQkJCQlicmVhazsKKwkJCX0KKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJYnJlYWs7CisJfQorCisJc0FwcFN0cmVhbSA8PCAiUVxuIjsKK30KKwordm9pZCBDUFdMX1NCQnV0dG9uOjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKK3sKKwlpZiAoIUlzVmlzaWJsZSgpKSByZXR1cm47CisKKwlDUERGX1JlY3QgcmVjdFduZCA9IEdldFdpbmRvd1JlY3QoKTsKKwlpZiAocmVjdFduZC5Jc0VtcHR5KCkpIHJldHVybjsKKworCUNQREZfUG9pbnQgcHRDZW50ZXIgPSB0aGlzLT5HZXRDZW50ZXJQb2ludCgpOworCUZYX0lOVDMyIG5UcmFuc3BhcmFuY3kgPSB0aGlzLT5HZXRUcmFuc3BhcmVuY3koKTsKKworCXN3aXRjaCAodGhpcy0+bV9lU2Nyb2xsQmFyVHlwZSkKKwl7CisJY2FzZSBTQlRfSFNDUk9MTDoKKwkJQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLHBVc2VyMkRldmljZSk7CisJCXN3aXRjaCAodGhpcy0+bV9lU0JCdXR0b25UeXBlKQorCQl7CisJCWNhc2UgUFNCVF9NSU46CisJCQl7CisJCQkJQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55KTsKKwkJCQlDUERGX1BvaW50IHB0MihwdENlbnRlci54ICsgUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkgKyBQV0xfVFJJQU5HTEVfSEFMRkxFTik7CisJCQkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCArIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4pOworCisJCQkJaWYgKHJlY3RXbmQucmlnaHQgLSByZWN0V25kLmxlZnQgPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDIgJiYKKwkJCQkJcmVjdFduZC50b3AgLSByZWN0V25kLmJvdHRvbSA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICkKKwkJCQl7CisJCQkJCUNGWF9QYXRoRGF0YSBwYXRoOworCisJCQkJCXBhdGguU2V0UG9pbnRDb3VudCg0KTsKKwkJCQkJcGF0aC5TZXRQb2ludCgwLCBwdDEueCwgcHQxLnksIEZYUFRfTU9WRVRPKTsKKwkJCQkJcGF0aC5TZXRQb2ludCgxLCBwdDIueCwgcHQyLnksIEZYUFRfTElORVRPKTsKKwkJCQkJcGF0aC5TZXRQb2ludCgyLCBwdDMueCwgcHQzLnksIEZYUFRfTElORVRPKTsKKwkJCQkJcGF0aC5TZXRQb2ludCgzLCBwdDEueCwgcHQxLnksIEZYUFRfTElORVRPKTsKKworCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCAKKwkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IsblRyYW5zcGFyYW5jeSksIAorCQkJCQkJMCwgRlhGSUxMX0FMVEVSTkFURSk7CisJCQkJfQorCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgUFNCVF9NQVg6CisJCQl7CisJCQkJQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCArIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55KTsKKwkJCQlDUERGX1BvaW50IHB0MihwdENlbnRlci54IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4gKiAwLjVmLHB0Q2VudGVyLnkgKyBQV0xfVFJJQU5HTEVfSEFMRkxFTik7CisJCQkJQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCAtIFBXTF9UUklBTkdMRV9IQUxGTEVOICogMC41ZixwdENlbnRlci55IC0gUFdMX1RSSUFOR0xFX0hBTEZMRU4pOworCisJCQkJaWYgKHJlY3RXbmQucmlnaHQgLSByZWN0V25kLmxlZnQgPiBQV0xfVFJJQU5HTEVfSEFMRkxFTiAqIDIgJiYKKwkJCQkJcmVjdFduZC50b3AgLSByZWN0V25kLmJvdHRvbSA+IFBXTF9UUklBTkdMRV9IQUxGTEVOICkKKwkJCQl7CisJCQkJCUNGWF9QYXRoRGF0YSBwYXRoOworCisJCQkJCXBhdGguU2V0UG9pbnRDb3VudCg0KTsKKwkJCQkJcGF0aC5TZXRQb2ludCgwLCBwdDEueCwgcHQxLnksIEZYUFRfTU9WRVRPKTsKKwkJCQkJcGF0aC5TZXRQb2ludCgxLCBwdDIueCwgcHQyLnksIEZYUFRfTElORVRPKTsKKwkJCQkJcGF0aC5TZXRQb2ludCgyLCBwdDMueCwgcHQzLnksIEZYUFRfTElORVRPKTsKKwkJCQkJcGF0aC5TZXRQb2ludCgzLCBwdDEueCwgcHQxLnksIEZYUFRfTElORVRPKTsKKworCQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCAKKwkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IsblRyYW5zcGFyYW5jeSksIAorCQkJCQkJMCwgRlhGSUxMX0FMVEVSTkFURSk7CQorCQkJCX0KKwkJCX0KKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJYnJlYWs7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBTQlRfVlNDUk9MTDoKKwkJc3dpdGNoKHRoaXMtPm1fZVNCQnV0dG9uVHlwZSkKKwkJeworCQljYXNlIFBTQlRfTUlOOgorCQkJeworCQkJCS8vZHJhdyBib3JkZXIKKwkJCQlDUERGX1JlY3QgcmNEcmF3ID0gcmVjdFduZDsKKwkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlUmVjdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHJjRHJhdywgCisJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwxMDAsMTAwLDEwMCksMC4wZik7CisKKwkJCQkvL2RyYXcgaW5uZXIgYm9yZGVyCisJCQkJcmNEcmF3ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdFduZCwwLjVmKTsKKwkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlUmVjdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHJjRHJhdywgCisJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNTUsMjU1LDI1NSksMS4wZik7CisKKwkJCQkvL2RyYXcgYmFja2dyb3VuZAorCisJCQkJcmNEcmF3ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdFduZCwxLjBmKTsKKworCQkJCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkKKwkJCQkJQ1BXTF9VdGlsczo6RHJhd1NoYWRvdyhwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIFRSVUUsIEZBTFNFLCByY0RyYXcsIG5UcmFuc3BhcmFuY3ksIDgwLCAyMjApOworCQkJCWVsc2UKKwkJCQkJQ1BXTF9VdGlsczo6RHJhd0ZpbGxSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCBBcmdiRW5jb2RlKDI1NSwyNTUsMjU1LDI1NSkpOworCisJCQkJLy9kcmF3IGFycm93CisKKwkJCQlpZiAocmVjdFduZC50b3AgLSByZWN0V25kLmJvdHRvbSA+IDYuMGYgKQorCQkJCXsKKwkJCQkJRlhfRkxPQVQgZlggPSByZWN0V25kLmxlZnQgKyAxLjVmOworCQkJCQlGWF9GTE9BVCBmWSA9IHJlY3RXbmQuYm90dG9tOworCQkJCQlDUERGX1BvaW50IHB0c1s3XSA9IHsKKwkJCQkJCQkJQ1BERl9Qb2ludChmWCsyLjVmLCBmWSs0LjBmKSwKKwkJCQkJCQkJQ1BERl9Qb2ludChmWCsyLjVmLCBmWSszLjBmKSwKKwkJCQkJCQkJQ1BERl9Qb2ludChmWCs0LjVmLCBmWSs1LjBmKSwKKwkJCQkJCQkJQ1BERl9Qb2ludChmWCs2LjVmLCBmWSszLjBmKSwKKwkJCQkJCQkJQ1BERl9Qb2ludChmWCs2LjVmLCBmWSs0LjBmKSwKKwkJCQkJCQkJQ1BERl9Qb2ludChmWCs0LjVmLCBmWSs2LjBmKSwKKwkJCQkJCQkJQ1BERl9Qb2ludChmWCsyLjVmLCBmWSs0LjBmKX07CisJCQkJCQorCisJCQkJCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkKKwkJCQkJCUNQV0xfVXRpbHM6OkRyYXdGaWxsQXJlYShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0cywgNywgQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDI1NSwyNTUsMjU1KSk7CisJCQkJCWVsc2UKKwkJCQkJCUNQV0xfVXRpbHM6OkRyYXdGaWxsQXJlYShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0cywgNywgCisJCQkJCQkJQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoUFdMX0RFRkFVTFRfSEVBVllHUkFZQ09MT1IsMjU1KSk7CisJCQkJfQorCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgUFNCVF9NQVg6CisJCQl7CisJCQkJLy9kcmF3IGJvcmRlcgorCQkJCUNQREZfUmVjdCByY0RyYXcgPSByZWN0V25kOworCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCAKKwkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDEwMCwxMDAsMTAwKSwwLjBmKTsKKwkJCQkKKwkJCQkvL2RyYXcgaW5uZXIgYm9yZGVyCisJCQkJcmNEcmF3ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdFduZCwwLjVmKTsKKwkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlUmVjdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHJjRHJhdywgCisJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNTUsMjU1LDI1NSksMS4wZik7CisKKwkJCQkvL2RyYXcgYmFja2dyb3VuZAorCQkJCXJjRHJhdyA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3RXbmQsMS4wZik7CisJCQkJaWYgKHRoaXMtPklzRW5hYmxlZCgpKQorCQkJCQlDUFdMX1V0aWxzOjpEcmF3U2hhZG93KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgVFJVRSwgRkFMU0UsIHJjRHJhdywgblRyYW5zcGFyYW5jeSwgODAsIDIyMCk7CisJCQkJZWxzZQorCQkJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbFJlY3QocERldmljZSwgcFVzZXIyRGV2aWNlLCByY0RyYXcsIEFyZ2JFbmNvZGUoMjU1LDI1NSwyNTUsMjU1KSk7CisKKwkJCQkvL2RyYXcgYXJyb3cKKworCQkJCWlmIChyZWN0V25kLnRvcCAtIHJlY3RXbmQuYm90dG9tID4gNi4wZiApCisJCQkJeworCQkJCQlGWF9GTE9BVCBmWCA9IHJlY3RXbmQubGVmdCArIDEuNWY7CisJCQkJCUZYX0ZMT0FUIGZZID0gcmVjdFduZC5ib3R0b207CisKKwkJCQkJQ1BERl9Qb2ludCBwdHNbN10gPSB7CisJCQkJCQkJCUNQREZfUG9pbnQoZlgrMi41ZiwgZlkrNS4wZiksCisJCQkJCQkJCUNQREZfUG9pbnQoZlgrMi41ZiwgZlkrNi4wZiksCisJCQkJCQkJCUNQREZfUG9pbnQoZlgrNC41ZiwgZlkrNC4wZiksCisJCQkJCQkJCUNQREZfUG9pbnQoZlgrNi41ZiwgZlkrNi4wZiksCisJCQkJCQkJCUNQREZfUG9pbnQoZlgrNi41ZiwgZlkrNS4wZiksCisJCQkJCQkJCUNQREZfUG9pbnQoZlgrNC41ZiwgZlkrMy4wZiksCisJCQkJCQkJCUNQREZfUG9pbnQoZlgrMi41ZiwgZlkrNS4wZil9OworCQkJCQkKKworCQkJCQlpZiAodGhpcy0+SXNFbmFibGVkKCkpCisJCQkJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbEFyZWEocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdHMsIDcsIEFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNTUsMjU1LDI1NSkpOworCQkJCQllbHNlCisJCQkJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbEFyZWEocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdHMsIDcsIAorCQkJCQkJCUNQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKFBXTF9ERUZBVUxUX0hFQVZZR1JBWUNPTE9SLDI1NSkpOworCQkJCX0KKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFBTQlRfUE9TOgorCQkJeworCQkJCS8vQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShwRGV2aWNlLHBVc2VyMkRldmljZSk7CisKKwkJCQkvL2RyYXcgYm9yZGVyCisJCQkJQ1BERl9SZWN0IHJjRHJhdyA9IHJlY3RXbmQ7CisJCQkJQ1BXTF9VdGlsczo6RHJhd1N0cm9rZVJlY3QocERldmljZSwgcFVzZXIyRGV2aWNlLCByY0RyYXcsIAorCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMTAwLDEwMCwxMDApLDAuMGYpOworCQkJCQorCQkJCS8vZHJhdyBpbm5lciBib3JkZXIKKwkJCQlyY0RyYXcgPSBDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChyZWN0V25kLDAuNWYpOworCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcmNEcmF3LCAKKwkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDI1NSwyNTUsMjU1KSwxLjBmKTsKKworCQkJCWlmICh0aGlzLT5Jc0VuYWJsZWQoKSkKKwkJCQl7CisJCQkJCS8vZHJhdyBzaGFkb3cgZWZmZWN0CQkJCQkJCisJCQkJCQorCQkJCQlDUERGX1BvaW50IHB0VG9wID0gQ1BERl9Qb2ludChyZWN0V25kLmxlZnQscmVjdFduZC50b3AtMS4wZik7CisJCQkJCUNQREZfUG9pbnQgcHRCb3R0b20gPSBDUERGX1BvaW50KHJlY3RXbmQubGVmdCxyZWN0V25kLmJvdHRvbSsxLjBmKTsKKworCQkJCQlwdFRvcC54ICs9IDEuNWY7CisJCQkJCXB0Qm90dG9tLnggKz0gMS41ZjsKKwkJCQkJCisJCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRUb3AsIHB0Qm90dG9tLCAKKwkJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyMTAsMjEwLDIxMCksMS4wZik7CisKKwkJCQkJcHRUb3AueCArPSAxLjBmOworCQkJCQlwdEJvdHRvbS54ICs9IDEuMGY7CisJCQkJCQorCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0VG9wLCBwdEJvdHRvbSwgCisJCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMjIwLDIyMCwyMjApLDEuMGYpOworCisJCQkJCXB0VG9wLnggKz0gMS4wZjsKKwkJCQkJcHRCb3R0b20ueCArPSAxLjBmOworCQkJCQkKKwkJCQkJQ1BXTF9VdGlsczo6RHJhd1N0cm9rZUxpbmUocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdFRvcCwgcHRCb3R0b20sIAorCQkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDI0MCwyNDAsMjQwKSwxLjBmKTsKKworCQkJCQlwdFRvcC54ICs9IDEuMGY7CisJCQkJCXB0Qm90dG9tLnggKz0gMS4wZjsKKwkJCQkJCisJCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRUb3AsIHB0Qm90dG9tLCAKKwkJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyNDAsMjQwLDI0MCksMS4wZik7CisKKwkJCQkJcHRUb3AueCArPSAxLjBmOworCQkJCQlwdEJvdHRvbS54ICs9IDEuMGY7CisJCQkJCQorCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0VG9wLCBwdEJvdHRvbSwgCisJCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMjEwLDIxMCwyMTApLDEuMGYpOworCisJCQkJCXB0VG9wLnggKz0gMS4wZjsKKwkJCQkJcHRCb3R0b20ueCArPSAxLjBmOworCQkJCQkKKwkJCQkJQ1BXTF9VdGlsczo6RHJhd1N0cm9rZUxpbmUocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdFRvcCwgcHRCb3R0b20sIAorCQkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDE4MCwxODAsMTgwKSwxLjBmKTsKKworCQkJCQlwdFRvcC54ICs9IDEuMGY7CisJCQkJCXB0Qm90dG9tLnggKz0gMS4wZjsKKwkJCQkJCisJCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRUb3AsIHB0Qm90dG9tLCAKKwkJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwxNTAsMTUwLDE1MCksMS4wZik7CisKKwkJCQkJcHRUb3AueCArPSAxLjBmOworCQkJCQlwdEJvdHRvbS54ICs9IDEuMGY7CisJCQkJCQorCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0VG9wLCBwdEJvdHRvbSwgCisJCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMTUwLDE1MCwxNTApLDEuMGYpOworCisJCQkJCXB0VG9wLnggKz0gMS4wZjsKKwkJCQkJcHRCb3R0b20ueCArPSAxLjBmOworCQkJCQkKKwkJCQkJQ1BXTF9VdGlsczo6RHJhd1N0cm9rZUxpbmUocERldmljZSwgcFVzZXIyRGV2aWNlLCBwdFRvcCwgcHRCb3R0b20sIAorCQkJCQkJQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDE4MCwxODAsMTgwKSwxLjBmKTsKKworCQkJCQlwdFRvcC54ICs9IDEuMGY7CisJCQkJCXB0Qm90dG9tLnggKz0gMS4wZjsKKwkJCQkJCisJCQkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgcHRUb3AsIHB0Qm90dG9tLCAKKwkJCQkJCUFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwyMTAsMjEwLDIxMCksMS4wZik7CisJCQkJfQorCQkJCWVsc2UKKwkJCQl7CisJCQkJCUNQV0xfVXRpbHM6OkRyYXdGaWxsUmVjdChwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHJjRHJhdywgQXJnYkVuY29kZSgyNTUsMjU1LDI1NSwyNTUpKTsKKwkJCQl9CisKKwkJCQkvL2RyYXcgZnJpY3Rpb24KKworCQkJCWlmIChyZWN0V25kLkhlaWdodCgpID4gOC4wZikKKwkJCQl7CisJCQkJCUZYX0NPTE9SUkVGIGNyU3Ryb2tlID0gQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LDEyMCwxMjAsMTIwKTsKKwkJCQkJaWYgKCF0aGlzLT5Jc0VuYWJsZWQoKSkKKwkJCQkJCWNyU3Ryb2tlID0gQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoUFdMX0RFRkFVTFRfSEVBVllHUkFZQ09MT1IsMjU1KTsKKworCQkJCQlGWF9GTE9BVCBuRnJpY3Rpb25XaWR0aCA9IDUuMGY7CisJCQkJCUZYX0ZMT0FUIG5GcmljdGlvbkhlaWdodCA9IDUuNWY7CisKKwkJCQkJQ1BERl9Qb2ludCBwdExlZnQgPSBDUERGX1BvaW50KHB0Q2VudGVyLnggLSBuRnJpY3Rpb25XaWR0aCAvIDIuMGYsIHB0Q2VudGVyLnkgLSBuRnJpY3Rpb25IZWlnaHQgLyAyLjBmICsgMC41Zik7CisJCQkJCUNQREZfUG9pbnQgcHRSaWdodCA9IENQREZfUG9pbnQocHRDZW50ZXIueCArIG5GcmljdGlvbldpZHRoIC8gMi4wZiwgcHRDZW50ZXIueSAtIG5GcmljdGlvbkhlaWdodCAvIDIuMGYgKyAwLjVmKTsKKworCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0TGVmdCwgcHRSaWdodCwgCisJCQkJCQljclN0cm9rZSwxLjBmKTsKKworCQkJCQlwdExlZnQueSArPSAyLjBmOworCQkJCQlwdFJpZ2h0LnkgKz0gMi4wZjsKKworCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0TGVmdCwgcHRSaWdodCwgCisJCQkJCQljclN0cm9rZSwxLjBmKTsKKworCQkJCQlwdExlZnQueSArPSAyLjBmOworCQkJCQlwdFJpZ2h0LnkgKz0gMi4wZjsKKworCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0TGVmdCwgcHRSaWdodCwgCisJCQkJCQljclN0cm9rZSwxLjBmKTsKKworCQkJCQkvKgorCQkJCQlwdExlZnQueSArPSAxLjVmOworCQkJCQlwdFJpZ2h0LnkgKz0gMS41ZjsKKworCQkJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIHB0TGVmdCwgcHRSaWdodCwgCisJCQkJCQlBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksMTUwLDE1MCwxNTApLDEuMGYpOworCQkJCQkJKi8KKwkJCQl9CisJCQl9CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJCWJyZWFrOworCQl9CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCWJyZWFrOworCX0KK30KKworRlhfQk9PTCBDUFdMX1NCQnV0dG9uOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOworCisJaWYgKENQV0xfV25kICogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKQorCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLFBOTV9MQlVUVE9ORE9XTiwwLChGWF9JTlRQVFIpJnBvaW50KTsKKworCW1fYk1vdXNlRG93biA9IFRSVUU7CisJU2V0Q2FwdHVyZSgpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgQ1BXTF9TQkJ1dHRvbjo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKK3sKKwlDUFdMX1duZDo6T25MQnV0dG9uVXAocG9pbnQsbkZsYWcpOworCisJaWYgKENQV0xfV25kICogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKQorCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLFBOTV9MQlVUVE9OVVAsMCwoRlhfSU5UUFRSKSZwb2ludCk7CisKKwltX2JNb3VzZURvd24gPSBGQUxTRTsKKwlSZWxlYXNlQ2FwdHVyZSgpOworCisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgQ1BXTF9TQkJ1dHRvbjo6T25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKK3sKKwlDUFdMX1duZDo6T25Nb3VzZU1vdmUocG9pbnQsbkZsYWcpOworCisJaWYgKENQV0xfV25kICogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKQorCXsJCQorCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLFBOTV9NT1VTRU1PVkUsMCwoRlhfSU5UUFRSKSZwb2ludCk7CisKKwkJLyoKKwkJaWYgKG1fYk1vdXNlRG93biAmJiAobV9lU0JCdXR0b25UeXBlID09IFBTQlRfTUlOIHx8IG1fZVNCQnV0dG9uVHlwZSA9PSBQU0JUX01BWCkpCisJCXsKKwkJCWlmICghcFBhcmVudC0+T25Ob3RpZnkodGhpcyxQTk1fTEJVVFRPTkRPV04sbkZsYWdzLChGWF9JTlRQVFIpJnBvaW50KSkKKwkJCQlyZXR1cm4gRkFMU0U7CisJCX0KKwkJKi8KKwl9CisKKwlyZXR1cm4gVFJVRTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX1Njcm9sbEJhciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfU2Nyb2xsQmFyOjpDUFdMX1Njcm9sbEJhcihQV0xfU0NST0xMQkFSX1RZUEUgc2JUeXBlKToKKwltX3NiVHlwZShzYlR5cGUpLAorCW1fcE1pbkJ1dHRvbihOVUxMKSwKKwltX3BNYXhCdXR0b24oTlVMTCksCisJbV9wUG9zQnV0dG9uKE5VTEwpLAorCW1fYk1vdXNlRG93bihGQUxTRSksCisJbV9iTWluT3JNYXgoRkFMU0UpLAorCW1fYk5vdGlmeUZvcmV2ZXIoVFJVRSkKK3sKK30KKworQ1BXTF9TY3JvbGxCYXI6On5DUFdMX1Njcm9sbEJhcigpCit7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfU2Nyb2xsQmFyOjpHZXRDbGFzc05hbWUoKSBjb25zdAoreworCXJldHVybiAiQ1BXTF9TY3JvbGxCYXIiOworfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpPbkNyZWF0ZShQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKK3sKKwljcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfQVJST1c7Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6OlJlUG9zQ2hpbGRXbmQoKQoreworCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsKKworLyoKKwlzd2l0Y2gobV9zYlR5cGUpCisJeworCQljYXNlIFNCVF9IU0NST0xMOgorCQkJaWYgKHJjQ2xpZW50LnJpZ2h0IC0gcmNDbGllbnQubGVmdCA8IFBXTF9TQ1JPTExCQVJfV0lEVEggfHwKKwkJCQlyY0NsaWVudC50b3AgLSByY0NsaWVudC5ib3R0b20gPCBQV0xfU0NST0xMQkFSX1dJRFRIKQorCQkJeworCQkJCVNldFZpc2libGUoRkFMU0UpOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgU0JUX1ZTQ1JPTEw6CisJCQlpZiAocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0IDwgUFdMX1NDUk9MTEJBUl9XSURUSCB8fAorCQkJCXJjQ2xpZW50LnRvcCAtIHJjQ2xpZW50LmJvdHRvbSA8IFBXTF9TQ1JPTExCQVJfV0lEVEgpCisJCQl7CisJCQkJU2V0VmlzaWJsZShGQUxTRSk7CisJCQl9CisJCQlicmVhazsKKwl9CQorKi8KKwlDUERGX1JlY3QgcmNNaW5CdXR0b24scmNNYXhCdXR0b247CisKKwlGWF9GTE9BVCBmQldpZHRoID0gMDsKKworCXN3aXRjaCAobV9zYlR5cGUpCisJeworCWNhc2UgU0JUX0hTQ1JPTEw6CisJCWlmIChyY0NsaWVudC5yaWdodCAtIHJjQ2xpZW50LmxlZnQgPiBQV0xfU0NST0xMQkFSX0JVVFRPTl9XSURUSCAqIDIgKyBQV0xfU0NST0xMQkFSX1BPU0JVVFRPTl9NSU5XSURUSCArIDIpCisJCXsKKwkJCXJjTWluQnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQuYm90dG9tLAorCQkJCXJjQ2xpZW50LmxlZnQgKyBQV0xfU0NST0xMQkFSX0JVVFRPTl9XSURUSCxyY0NsaWVudC50b3ApOworCQkJcmNNYXhCdXR0b24gPSBDUERGX1JlY3QocmNDbGllbnQucmlnaHQgLSBQV0xfU0NST0xMQkFSX0JVVFRPTl9XSURUSCxyY0NsaWVudC5ib3R0b20sCisJCQkJcmNDbGllbnQucmlnaHQscmNDbGllbnQudG9wKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCWZCV2lkdGggPSAocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0IC0gUFdMX1NDUk9MTEJBUl9QT1NCVVRUT05fTUlOV0lEVEggLSAyKSAvIDI7CisKKwkJCWlmIChmQldpZHRoID4gMCkKKwkJCXsKKwkJCQlyY01pbkJ1dHRvbiA9IENQREZfUmVjdChyY0NsaWVudC5sZWZ0LHJjQ2xpZW50LmJvdHRvbSwKKwkJCQkJcmNDbGllbnQubGVmdCArIGZCV2lkdGgscmNDbGllbnQudG9wKTsKKwkJCQlyY01heEJ1dHRvbiA9IENQREZfUmVjdChyY0NsaWVudC5yaWdodCAtIGZCV2lkdGgscmNDbGllbnQuYm90dG9tLAorCQkJCQlyY0NsaWVudC5yaWdodCxyY0NsaWVudC50b3ApOworCQkJfQorCQkJZWxzZSBTZXRWaXNpYmxlKEZBTFNFKTsKKwkJfQorCQlicmVhazsKKwljYXNlIFNCVF9WU0NST0xMOgorCQlpZiAoSXNGbG9hdEJpZ2dlcihyY0NsaWVudC50b3AgLSByY0NsaWVudC5ib3R0b20sIFBXTF9TQ1JPTExCQVJfQlVUVE9OX1dJRFRIICogMiArIFBXTF9TQ1JPTExCQVJfUE9TQlVUVE9OX01JTldJRFRIICsgMikpCisJCXsKKwkJCXJjTWluQnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQudG9wIC0gUFdMX1NDUk9MTEJBUl9CVVRUT05fV0lEVEgsCisJCQkJcmNDbGllbnQucmlnaHQscmNDbGllbnQudG9wKTsKKwkJCXJjTWF4QnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQuYm90dG9tLAorCQkJCXJjQ2xpZW50LnJpZ2h0LHJjQ2xpZW50LmJvdHRvbSArIFBXTF9TQ1JPTExCQVJfQlVUVE9OX1dJRFRIKTsKKwkJfQorCQllbHNlCisJCXsKKwkJCWZCV2lkdGggPSAocmNDbGllbnQudG9wIC0gcmNDbGllbnQuYm90dG9tIC0gUFdMX1NDUk9MTEJBUl9QT1NCVVRUT05fTUlOV0lEVEggLSAyKSAvIDI7CisKKwkJCWlmIChJc0Zsb2F0QmlnZ2VyKGZCV2lkdGgsIDApKQorCQkJeworCQkJCXJjTWluQnV0dG9uID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQudG9wIC0gZkJXaWR0aCwKKwkJCQkJcmNDbGllbnQucmlnaHQscmNDbGllbnQudG9wKTsKKwkJCQlyY01heEJ1dHRvbiA9IENQREZfUmVjdChyY0NsaWVudC5sZWZ0LHJjQ2xpZW50LmJvdHRvbSwKKwkJCQkJcmNDbGllbnQucmlnaHQscmNDbGllbnQuYm90dG9tICsgZkJXaWR0aCk7CisJCQl9CisJCQllbHNlIFNldFZpc2libGUoRkFMU0UpOworCQl9CisJCWJyZWFrOworCX0JCisJCisvLwlpZiAoSXNWaXNpYmxlKCkpCisJeworCQlpZiAobV9wTWluQnV0dG9uKQorCQkJbV9wTWluQnV0dG9uLT5Nb3ZlKHJjTWluQnV0dG9uLFRSVUUsRkFMU0UpOworCQkKKwkJaWYgKG1fcE1heEJ1dHRvbikKKwkJCW1fcE1heEJ1dHRvbi0+TW92ZShyY01heEJ1dHRvbixUUlVFLEZBTFNFKTsKKworCQlNb3ZlUG9zQnV0dG9uKEZBTFNFKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pCit7CisJQ1BERl9SZWN0IHJlY3RXbmQgPSBHZXRXaW5kb3dSZWN0KCk7CisKKwlpZiAoSXNWaXNpYmxlKCkgJiYgIXJlY3RXbmQuSXNFbXB0eSgpKQorCXsKKwkJQ0ZYX0J5dGVUZXh0QnVmIHNCdXR0b247CQkKKworCQlzQnV0dG9uIDw8ICJxXG4iOworCQlzQnV0dG9uIDw8ICIwIHdcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oR2V0QmFja2dyb3VuZENvbG9yKCksVFJVRSk7CisJCXNCdXR0b24gPDwgcmVjdFduZC5sZWZ0IDw8ICIgIiA8PCByZWN0V25kLmJvdHRvbSA8PCAiICIKKwkJCQk8PCByZWN0V25kLnJpZ2h0IC0gcmVjdFduZC5sZWZ0IDw8ICIgIiA8PCByZWN0V25kLnRvcCAtIHJlY3RXbmQuYm90dG9tIDw8ICIgcmUgYiBRXG4iOwkKKworCQlzQXBwU3RyZWFtIDw8IHNCdXR0b247CQorCX0KK30KKwordm9pZCBDUFdMX1Njcm9sbEJhcjo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpCit7CisvLwlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UscFVzZXIyRGV2aWNlKTsKKwlDUERGX1JlY3QgcmVjdFduZCA9IEdldFdpbmRvd1JlY3QoKTsKKworCWlmIChJc1Zpc2libGUoKSAmJiAhcmVjdFduZC5Jc0VtcHR5KCkpCisJeworCQlDUFdMX1V0aWxzOjpEcmF3RmlsbFJlY3QocERldmljZSwgcFVzZXIyRGV2aWNlLCByZWN0V25kLCB0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKSwgR2V0VHJhbnNwYXJlbmN5KCkpOworCisJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgCisJCQlDUERGX1BvaW50KHJlY3RXbmQubGVmdCsyLjBmLHJlY3RXbmQudG9wLTIuMGYpLCBDUERGX1BvaW50KHJlY3RXbmQubGVmdCsyLjBmLHJlY3RXbmQuYm90dG9tKzIuMGYpLCAKKwkJCUFyZ2JFbmNvZGUodGhpcy0+R2V0VHJhbnNwYXJlbmN5KCksMTAwLDEwMCwxMDApLDEuMGYpOworCisJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgCisJCQlDUERGX1BvaW50KHJlY3RXbmQucmlnaHQtMi4wZixyZWN0V25kLnRvcC0yLjBmKSwgQ1BERl9Qb2ludChyZWN0V25kLnJpZ2h0LTIuMGYscmVjdFduZC5ib3R0b20rMi4wZiksIAorCQkJQXJnYkVuY29kZSh0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSwxMDAsMTAwLDEwMCksMS4wZik7CisJfQorfQorCitGWF9CT09MIENQV0xfU2Nyb2xsQmFyOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOworCisJLy9TZXRGb2N1cygpOworCisJaWYgKEhhc0ZsYWcoUFdTX0FVVE9UUkFOU1BBUkVOVCkpCisJeworCQlpZiAoR2V0VHJhbnNwYXJlbmN5KCkgIT0gMjU1KQorCQl7CisJCQlTZXRUcmFuc3BhcmVuY3koMjU1KTsKKwkJCUludmFsaWRhdGVSZWN0KCk7CisJCX0KKwl9CisKKwlDUERGX1JlY3QgcmNNaW5BcmVhLHJjTWF4QXJlYTsKKworCWlmIChtX3BQb3NCdXR0b24gJiYgbV9wUG9zQnV0dG9uLT5Jc1Zpc2libGUoKSkKKwl7CisJCUNQREZfUmVjdCByY0NsaWVudCA9IHRoaXMtPkdldENsaWVudFJlY3QoKTsKKwkJQ1BERl9SZWN0IHJjUG9zQnV0dG9uID0gbV9wUG9zQnV0dG9uLT5HZXRXaW5kb3dSZWN0KCk7CisKKwkJc3dpdGNoIChtX3NiVHlwZSkKKwkJeworCQljYXNlIFNCVF9IU0NST0xMOgorCQkJcmNNaW5BcmVhID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQgKyBQV0xfU0NST0xMQkFSX0JVVFRPTl9XSURUSCxyY0NsaWVudC5ib3R0b20sCisJCQkJCQkJcmNQb3NCdXR0b24ubGVmdCxyY0NsaWVudC50b3ApOworCQkJcmNNYXhBcmVhID0gQ1BERl9SZWN0KHJjUG9zQnV0dG9uLnJpZ2h0LHJjQ2xpZW50LmJvdHRvbSwKKwkJCQkJCQlyY0NsaWVudC5yaWdodCAtIFBXTF9TQ1JPTExCQVJfQlVUVE9OX1dJRFRILHJjQ2xpZW50LnRvcCk7CisKKwkJCWJyZWFrOworCQljYXNlIFNCVF9WU0NST0xMOgorCQkJcmNNaW5BcmVhID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNQb3NCdXR0b24udG9wLAorCQkJCQkJCXJjQ2xpZW50LnJpZ2h0LHJjQ2xpZW50LnRvcCAtIFBXTF9TQ1JPTExCQVJfQlVUVE9OX1dJRFRIKTsKKwkJCXJjTWF4QXJlYSA9IENQREZfUmVjdChyY0NsaWVudC5sZWZ0LHJjQ2xpZW50LmJvdHRvbSArIFBXTF9TQ1JPTExCQVJfQlVUVE9OX1dJRFRILAorCQkJCQkJCXJjQ2xpZW50LnJpZ2h0LHJjUG9zQnV0dG9uLmJvdHRvbSk7CisJCQlicmVhazsKKwkJfQorCisJCXJjTWluQXJlYS5Ob3JtYWxpemUoKTsKKwkJcmNNYXhBcmVhLk5vcm1hbGl6ZSgpOworCisJCWlmIChyY01pbkFyZWEuQ29udGFpbnMocG9pbnQueCxwb2ludC55KSkKKwkJeworCQkJbV9zRGF0YS5TdWJCaWcoKTsKKwkJCU1vdmVQb3NCdXR0b24oVFJVRSk7CisJCQlOb3RpZnlTY3JvbGxXaW5kb3coKTsKKwkJfQorCisJCWlmIChyY01heEFyZWEuQ29udGFpbnMocG9pbnQueCxwb2ludC55KSkKKwkJeworCQkJbV9zRGF0YS5BZGRCaWcoKTsKKwkJCU1vdmVQb3NCdXR0b24oVFJVRSk7CisJCQlOb3RpZnlTY3JvbGxXaW5kb3coKTsKKwkJfQorCX0KKworCXJldHVybiBUUlVFOworfQorCitGWF9CT09MIENQV0xfU2Nyb2xsQmFyOjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQoreworCUNQV0xfV25kOjpPbkxCdXR0b25VcChwb2ludCxuRmxhZyk7CisKKwlpZiAoSGFzRmxhZyhQV1NfQVVUT1RSQU5TUEFSRU5UKSkKKwl7CisJCWlmIChHZXRUcmFuc3BhcmVuY3koKSAhPSBQV0xfU0NST0xMQkFSX1RSQU5TUEFSQU5DWSkKKwkJeworCQkJU2V0VHJhbnNwYXJlbmN5KFBXTF9TQ1JPTExCQVJfVFJBTlNQQVJBTkNZKTsKKwkJCUludmFsaWRhdGVSZWN0KCk7CisJCX0KKwl9CisKKwlFbmRUaW1lcigpOworCW1fYk1vdXNlRG93biA9IEZBTFNFOworCisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pCit7CisJQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsbXNnLHdQYXJhbSxsUGFyYW0pOworCisJc3dpdGNoIChtc2cpCisJeworCWNhc2UgUE5NX0xCVVRUT05ET1dOOgkJCQorCQlpZiAocFduZCA9PSBtX3BNaW5CdXR0b24pCisJCXsKKwkJCU9uTWluQnV0dG9uTEJEb3duKCooQ1BERl9Qb2ludCopbFBhcmFtKTsKKwkJfQorCisJCWlmIChwV25kID09IG1fcE1heEJ1dHRvbikKKwkJeworCQkJT25NYXhCdXR0b25MQkRvd24oKihDUERGX1BvaW50KilsUGFyYW0pOworCQl9CisKKwkJaWYgKHBXbmQgPT0gbV9wUG9zQnV0dG9uKQorCQl7CisJCQlPblBvc0J1dHRvbkxCRG93bigqKENQREZfUG9pbnQqKWxQYXJhbSk7CQkJCQorCQl9CisJCWJyZWFrOworCWNhc2UgUE5NX0xCVVRUT05VUDoKKwkJaWYgKHBXbmQgPT0gbV9wTWluQnV0dG9uKQorCQl7CisJCQlPbk1pbkJ1dHRvbkxCVXAoKihDUERGX1BvaW50KilsUGFyYW0pOwkJCisJCX0KKworCQlpZiAocFduZCA9PSBtX3BNYXhCdXR0b24pCisJCXsKKwkJCU9uTWF4QnV0dG9uTEJVcCgqKENQREZfUG9pbnQqKWxQYXJhbSk7CQkJCQorCQl9CisKKwkJaWYgKHBXbmQgPT0gbV9wUG9zQnV0dG9uKQorCQl7CisJCQlPblBvc0J1dHRvbkxCVXAoKihDUERGX1BvaW50KilsUGFyYW0pOwkJCQorCQl9CisJCWJyZWFrOworCWNhc2UgUE5NX01PVVNFTU9WRToKKwkJaWYgKHBXbmQgPT0gbV9wTWluQnV0dG9uKQorCQl7CisJCQlPbk1pbkJ1dHRvbk1vdXNlTW92ZSgqKENQREZfUG9pbnQqKWxQYXJhbSk7CisJCX0KKworCQlpZiAocFduZCA9PSBtX3BNYXhCdXR0b24pCisJCXsKKwkJCU9uTWF4QnV0dG9uTW91c2VNb3ZlKCooQ1BERl9Qb2ludCopbFBhcmFtKTsJCQkJCisJCX0KKworCQlpZiAocFduZCA9PSBtX3BQb3NCdXR0b24pCisJCXsKKwkJCU9uUG9zQnV0dG9uTW91c2VNb3ZlKCooQ1BERl9Qb2ludCopbFBhcmFtKTsJCQkJCisJCX0KKwkJYnJlYWs7CisJY2FzZSBQTk1fU0VUU0NST0xMSU5GTzoKKwkJeworCQkJaWYgKFBXTF9TQ1JPTExfSU5GTyAqIHBJbmZvID0gKFBXTF9TQ1JPTExfSU5GTyopbFBhcmFtKQorCQkJeworCQkJCWlmIChGWFNZU19tZW1jbXAoJm1fT3JpZ2luSW5mbywgcEluZm8sIHNpemVvZihQV0xfU0NST0xMX0lORk8pKSAhPSAwKQorCQkJCXsKKwkJCQkJbV9PcmlnaW5JbmZvID0gKnBJbmZvOworCQkJCQlGWF9GTE9BVCBmTWF4ID0gcEluZm8tPmZDb250ZW50TWF4IC0gcEluZm8tPmZDb250ZW50TWluIC0gcEluZm8tPmZQbGF0ZVdpZHRoOworCQkJCQlmTWF4ID0gZk1heCA+IDAuMGYgPyBmTWF4IDogMC4wZjsKKwkJCQkJdGhpcy0+U2V0U2Nyb2xsUmFuZ2UoMCxmTWF4LCBwSW5mby0+ZlBsYXRlV2lkdGgpOworCQkJCQl0aGlzLT5TZXRTY3JvbGxTdGVwKHBJbmZvLT5mQmlnU3RlcCxwSW5mby0+ZlNtYWxsU3RlcCk7CisJCQkJfQorCQkJfQorCQl9CisJCWJyZWFrOworCWNhc2UgUE5NX1NFVFNDUk9MTFBPUzoKKwkJeworCQkJRlhfRkxPQVQgZlBvcyA9ICooRlhfRkxPQVQqKWxQYXJhbTsKKwkJCXN3aXRjaCAodGhpcy0+bV9zYlR5cGUpCisJCQl7CisJCQljYXNlIFNCVF9IU0NST0xMOgorCQkJCWZQb3MgPSBmUG9zIC0gbV9PcmlnaW5JbmZvLmZDb250ZW50TWluOworCQkJCWJyZWFrOworCQkJY2FzZSBTQlRfVlNDUk9MTDoKKwkJCQlmUG9zID0gbV9PcmlnaW5JbmZvLmZDb250ZW50TWF4IC0gZlBvczsKKwkJCQlicmVhazsKKwkJCX0KKwkJCXRoaXMtPlNldFNjcm9sbFBvcyhmUG9zKTsKKwkJfQorCQlicmVhazsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6OkNyZWF0ZUJ1dHRvbnMoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJUFdMX0NSRUFURVBBUkFNCXNjcCA9IGNwOworCXNjcC5wUGFyZW50V25kID0gdGhpczsKKwlzY3AuZHdCb3JkZXJXaWR0aCA9IDI7CisJc2NwLm5Cb3JkZXJTdHlsZSA9IFBCU19CRVZFTEVEOworCQorCXNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQV1NfQk9SREVSIHwgUFdTX0JBQ0tHUk9VTkQgfCBQV1NfTk9SRUZSRVNIQ0xJUDsKKworCWlmICghbV9wTWluQnV0dG9uKSAKKwl7CisJCW1fcE1pbkJ1dHRvbiA9IG5ldyBDUFdMX1NCQnV0dG9uKG1fc2JUeXBlLFBTQlRfTUlOKTsKKwkJbV9wTWluQnV0dG9uLT5DcmVhdGUoc2NwKTsKKwl9CisKKwlpZiAoIW1fcE1heEJ1dHRvbikKKwl7CisJCW1fcE1heEJ1dHRvbiA9IG5ldyBDUFdMX1NCQnV0dG9uKG1fc2JUeXBlLFBTQlRfTUFYKTsKKwkJbV9wTWF4QnV0dG9uLT5DcmVhdGUoc2NwKTsKKwl9CisKKwlpZiAoIW1fcFBvc0J1dHRvbikKKwl7CisJCW1fcFBvc0J1dHRvbiA9IG5ldyBDUFdMX1NCQnV0dG9uKG1fc2JUeXBlLFBTQlRfUE9TKTsKKwkJbV9wUG9zQnV0dG9uLT5TZXRWaXNpYmxlKEZBTFNFKTsKKwkJbV9wUG9zQnV0dG9uLT5DcmVhdGUoc2NwKTsKKwl9Cit9CisKK0ZYX0ZMT0FUIENQV0xfU2Nyb2xsQmFyOjpHZXRTY3JvbGxCYXJXaWR0aCgpIGNvbnN0Cit7CisJaWYgKCFJc1Zpc2libGUoKSkgcmV0dXJuIDA7CisKKwlyZXR1cm4gUFdMX1NDUk9MTEJBUl9XSURUSDsKK30KKwordm9pZCBDUFdMX1Njcm9sbEJhcjo6U2V0U2Nyb2xsUmFuZ2UoRlhfRkxPQVQgZk1pbixGWF9GTE9BVCBmTWF4LEZYX0ZMT0FUIGZDbGllbnRXaWR0aCkKK3sKKwlpZiAobV9wUG9zQnV0dG9uKQorCXsKKwkJbV9zRGF0YS5TZXRTY3JvbGxSYW5nZShmTWluLGZNYXgpOworCQltX3NEYXRhLlNldENsaWVudFdpZHRoKGZDbGllbnRXaWR0aCk7CisKKwkJaWYgKElzRmxvYXRTbWFsbGVyKG1fc0RhdGEuU2Nyb2xsUmFuZ2UuR2V0V2lkdGgoKSwgMC4wZikpCisJCXsKKwkJCW1fcFBvc0J1dHRvbi0+U2V0VmlzaWJsZShGQUxTRSk7CisJCX0KKwkJZWxzZQorCQl7CisJCQltX3BQb3NCdXR0b24tPlNldFZpc2libGUoVFJVRSk7CQorCQkJTW92ZVBvc0J1dHRvbihUUlVFKTsKKwkJfQorCX0KK30KKwordm9pZCBDUFdMX1Njcm9sbEJhcjo6U2V0U2Nyb2xsUG9zKEZYX0ZMT0FUIGZQb3MpCit7CisJRlhfRkxPQVQgZk9sZFBvcyA9IG1fc0RhdGEuZlNjcm9sbFBvczsKKworCW1fc0RhdGEuU2V0UG9zKGZQb3MpOworCisJaWYgKCFJc0Zsb2F0RXF1YWwobV9zRGF0YS5mU2Nyb2xsUG9zLCBmT2xkUG9zKSkKKwkJTW92ZVBvc0J1dHRvbihUUlVFKTsKK30KKwordm9pZCBDUFdMX1Njcm9sbEJhcjo6U2V0U2Nyb2xsU3RlcChGWF9GTE9BVCBmQmlnU3RlcCxGWF9GTE9BVCBmU21hbGxTdGVwKQoreworCW1fc0RhdGEuU2V0QmlnU3RlcChmQmlnU3RlcCk7CisJbV9zRGF0YS5TZXRTbWFsbFN0ZXAoZlNtYWxsU3RlcCk7Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok1vdmVQb3NCdXR0b24oRlhfQk9PTCBiUmVmcmVzaCkKK3sKKwlBU1NFUlQgKG1fcFBvc0J1dHRvbiAhPSBOVUxMKTsKKwlBU1NFUlQgKG1fcE1pbkJ1dHRvbiAhPSBOVUxMKTsKKwlBU1NFUlQgKG1fcE1heEJ1dHRvbiAhPSBOVUxMKTsKKworCWlmIChtX3BQb3NCdXR0b24tPklzVmlzaWJsZSgpKQorCXsKKworCisKKworCQlDUERGX1JlY3QgcmNDbGllbnQ7CisJCUNQREZfUmVjdCByY1Bvc0FyZWEscmNQb3NCdXR0b247CQorCisJCXJjQ2xpZW50ID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOworCQlyY1Bvc0FyZWEgPSBHZXRTY3JvbGxBcmVhKCk7CisKKwkJRlhfRkxPQVQgZkxlZnQsZlJpZ2h0LGZUb3AsZkJvdHRvbTsKKworCQlzd2l0Y2ggKG1fc2JUeXBlKQorCQl7CisJCWNhc2UgU0JUX0hTQ1JPTEw6CisJCQlmTGVmdCA9IFRydWVUb0ZhY2UobV9zRGF0YS5mU2Nyb2xsUG9zKTsKKwkJCWZSaWdodCA9IFRydWVUb0ZhY2UobV9zRGF0YS5mU2Nyb2xsUG9zICsgbV9zRGF0YS5mQ2xpZW50V2lkdGgpOworCisJCQlpZiAoZlJpZ2h0IC0gZkxlZnQgPCBQV0xfU0NST0xMQkFSX1BPU0JVVFRPTl9NSU5XSURUSCkKKwkJCQlmUmlnaHQgPSBmTGVmdCArIFBXTF9TQ1JPTExCQVJfUE9TQlVUVE9OX01JTldJRFRIOworCisJCQlpZiAoZlJpZ2h0ID4gcmNQb3NBcmVhLnJpZ2h0KQorCQkJeworCQkJCWZSaWdodCA9IHJjUG9zQXJlYS5yaWdodDsKKwkJCQlmTGVmdCA9IGZSaWdodCAtIFBXTF9TQ1JPTExCQVJfUE9TQlVUVE9OX01JTldJRFRIOworCQkJfQorCisJCQlyY1Bvc0J1dHRvbiA9IENQREZfUmVjdChmTGVmdCAsCisJCQkJCQkJCXJjUG9zQXJlYS5ib3R0b20sCisJCQkJCQkJCWZSaWdodCAsCisJCQkJCQkJCXJjUG9zQXJlYS50b3ApOworCQkJCisJCQlicmVhazsKKwkJY2FzZSBTQlRfVlNDUk9MTDoKKwkJCWZCb3R0b20gPSBUcnVlVG9GYWNlKG1fc0RhdGEuZlNjcm9sbFBvcyArIG1fc0RhdGEuZkNsaWVudFdpZHRoKTsKKwkJCWZUb3AgPSBUcnVlVG9GYWNlKG1fc0RhdGEuZlNjcm9sbFBvcyk7CisKKwkJCWlmIChJc0Zsb2F0U21hbGxlcihmVG9wIC0gZkJvdHRvbSwgUFdMX1NDUk9MTEJBUl9QT1NCVVRUT05fTUlOV0lEVEgpKQorCQkJCWZCb3R0b20gPSBmVG9wIC0gUFdMX1NDUk9MTEJBUl9QT1NCVVRUT05fTUlOV0lEVEg7CisJCQkKKwkJCWlmIChJc0Zsb2F0U21hbGxlcihmQm90dG9tLCByY1Bvc0FyZWEuYm90dG9tKSkKKwkJCXsKKwkJCQlmQm90dG9tID0gcmNQb3NBcmVhLmJvdHRvbTsKKwkJCQlmVG9wID0gZkJvdHRvbSArIFBXTF9TQ1JPTExCQVJfUE9TQlVUVE9OX01JTldJRFRIOworCQkJfQorCisJCQlyY1Bvc0J1dHRvbiA9IENQREZfUmVjdChyY1Bvc0FyZWEubGVmdCwKKwkJCQkJCQkJZkJvdHRvbSwJCQkJCQkJCQorCQkJCQkJCQlyY1Bvc0FyZWEucmlnaHQsCisJCQkJCQkJCWZUb3ApOworCQkJCisJCQlicmVhazsKKwkJfQorCisJCW1fcFBvc0J1dHRvbi0+TW92ZShyY1Bvc0J1dHRvbixUUlVFLGJSZWZyZXNoKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uTWluQnV0dG9uTEJEb3duKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkKK3sKKwltX3NEYXRhLlN1YlNtYWxsKCk7CisJTW92ZVBvc0J1dHRvbihUUlVFKTsKKwlOb3RpZnlTY3JvbGxXaW5kb3coKTsKKworCW1fYk1pbk9yTWF4ID0gVFJVRTsKKworCUVuZFRpbWVyKCk7CisJQmVnaW5UaW1lcigxMDApOworfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpPbk1pbkJ1dHRvbkxCVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQoreworfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpPbk1pbkJ1dHRvbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CQorfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpPbk1heEJ1dHRvbkxCRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CisJbV9zRGF0YS5BZGRTbWFsbCgpOworCU1vdmVQb3NCdXR0b24oVFJVRSk7CisJTm90aWZ5U2Nyb2xsV2luZG93KCk7CisKKwltX2JNaW5Pck1heCA9IEZBTFNFOworCQorCUVuZFRpbWVyKCk7CisJQmVnaW5UaW1lcigxMDApOworfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpPbk1heEJ1dHRvbkxCVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQoreworfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpPbk1heEJ1dHRvbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CQorfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpPblBvc0J1dHRvbkxCRG93bihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CisJbV9iTW91c2VEb3duID0gVFJVRTsKKworCWlmIChtX3BQb3NCdXR0b24pCisJeworCQlDUERGX1JlY3QgcmNQb3NCdXR0b24gPSBtX3BQb3NCdXR0b24tPkdldFdpbmRvd1JlY3QoKTsKKworCQlzd2l0Y2gobV9zYlR5cGUpCisJCXsKKwkJY2FzZSBTQlRfSFNDUk9MTDoKKwkJCW1fbk9sZFBvcyA9IHBvaW50Lng7CisJCQltX2ZPbGRQb3NCdXR0b24gPSByY1Bvc0J1dHRvbi5sZWZ0OworCQkJYnJlYWs7CisJCWNhc2UgU0JUX1ZTQ1JPTEw6CisJCQltX25PbGRQb3MgPSBwb2ludC55OworCQkJbV9mT2xkUG9zQnV0dG9uID0gcmNQb3NCdXR0b24udG9wOworCQkJYnJlYWs7CisJCX0KKwl9Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uUG9zQnV0dG9uTEJVcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CisJaWYgKG1fYk1vdXNlRG93bikKKwl7CisJCWlmICghbV9iTm90aWZ5Rm9yZXZlcikKKwkJCU5vdGlmeVNjcm9sbFdpbmRvdygpOworCX0KKwltX2JNb3VzZURvd24gPSBGQUxTRTsKK30KKwordm9pZCBDUFdMX1Njcm9sbEJhcjo6T25Qb3NCdXR0b25Nb3VzZU1vdmUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQoreworCUZYX0ZMT0FUIGZPbGRTY3JvbGxQb3MgPSBtX3NEYXRhLmZTY3JvbGxQb3M7CisKKwlGWF9GTE9BVCBmTmV3UG9zID0gMDsKKworCXN3aXRjaCAobV9zYlR5cGUpCisJeworCWNhc2UgU0JUX0hTQ1JPTEw6CisJCWlmIChGWFNZU19mYWJzKHBvaW50LnggLSBtX25PbGRQb3MpIDwgMSkgcmV0dXJuOworCQlmTmV3UG9zID0gRmFjZVRvVHJ1ZShtX2ZPbGRQb3NCdXR0b24gKyBwb2ludC54IC0gbV9uT2xkUG9zKTsKKwkJYnJlYWs7CisJY2FzZSBTQlRfVlNDUk9MTDoKKwkJaWYgKEZYU1lTX2ZhYnMocG9pbnQueSAtIG1fbk9sZFBvcykgPCAxKSByZXR1cm47CisJCWZOZXdQb3MgPSBGYWNlVG9UcnVlKG1fZk9sZFBvc0J1dHRvbiArIHBvaW50LnkgLSBtX25PbGRQb3MpOworCQlicmVhazsKKwl9CisKKwlpZiAobV9iTW91c2VEb3duKQorCXsKKwkJc3dpdGNoIChtX3NiVHlwZSkKKwkJeworCQljYXNlIFNCVF9IU0NST0xMOgorCisJCQlpZiAoSXNGbG9hdFNtYWxsZXIoZk5ld1BvcywgbV9zRGF0YS5TY3JvbGxSYW5nZS5mTWluKSkKKwkJCXsKKwkJCQlmTmV3UG9zID0gbV9zRGF0YS5TY3JvbGxSYW5nZS5mTWluOworCQkJfQorCisJCQlpZiAoSXNGbG9hdEJpZ2dlcihmTmV3UG9zLCBtX3NEYXRhLlNjcm9sbFJhbmdlLmZNYXgpKQorCQkJeworCQkJCWZOZXdQb3MgPSBtX3NEYXRhLlNjcm9sbFJhbmdlLmZNYXg7CisJCQl9CisKKwkJCW1fc0RhdGEuU2V0UG9zKGZOZXdQb3MpOworCQkJCisJCQlicmVhazsKKwkJY2FzZSBTQlRfVlNDUk9MTDoKKwkJCisJCQlpZiAoSXNGbG9hdFNtYWxsZXIoZk5ld1BvcywgbV9zRGF0YS5TY3JvbGxSYW5nZS5mTWluKSkKKwkJCXsKKwkJCQlmTmV3UG9zID0gbV9zRGF0YS5TY3JvbGxSYW5nZS5mTWluOworCQkJfQorCisJCQlpZiAoSXNGbG9hdEJpZ2dlcihmTmV3UG9zLCBtX3NEYXRhLlNjcm9sbFJhbmdlLmZNYXgpKQorCQkJeworCQkJCWZOZXdQb3MgPSBtX3NEYXRhLlNjcm9sbFJhbmdlLmZNYXg7CisJCQl9CQorCisJCQltX3NEYXRhLlNldFBvcyhmTmV3UG9zKTsKKwkJCisJCQlicmVhazsKKwkJfQkKKwkJCisJCWlmICghSXNGbG9hdEVxdWFsKGZPbGRTY3JvbGxQb3MsIG1fc0RhdGEuZlNjcm9sbFBvcykpCisJCXsJCQkKKwkJCU1vdmVQb3NCdXR0b24oVFJVRSk7CisKKwkJCWlmIChtX2JOb3RpZnlGb3JldmVyKQorCQkJCU5vdGlmeVNjcm9sbFdpbmRvdygpOworCQl9CisJfQorfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpOb3RpZnlTY3JvbGxXaW5kb3coKQoreworCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkKKwl7CisJCUZYX0ZMT0FUIGZQb3M7CisJCXN3aXRjaCAodGhpcy0+bV9zYlR5cGUpCisJCXsKKwkJY2FzZSBTQlRfSFNDUk9MTDoKKwkJCWZQb3MgPSBtX09yaWdpbkluZm8uZkNvbnRlbnRNaW4gKyBtX3NEYXRhLmZTY3JvbGxQb3M7CisJCQlicmVhazsKKwkJY2FzZSBTQlRfVlNDUk9MTDoKKwkJCWZQb3MgPSBtX09yaWdpbkluZm8uZkNvbnRlbnRNYXggLSBtX3NEYXRhLmZTY3JvbGxQb3M7CisJCQlicmVhazsKKwkJfQkKKwkJcFBhcmVudC0+T25Ob3RpZnkodGhpcyxQTk1fU0NST0xMV0lORE9XLChGWF9JTlRQVFIpbV9zYlR5cGUsKEZYX0lOVFBUUikmZlBvcyk7CisJfQorfQorCitDUERGX1JlY3QgQ1BXTF9TY3JvbGxCYXI6OkdldFNjcm9sbEFyZWEoKSBjb25zdAoreworCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKwlDUERGX1JlY3QgcmNBcmVhOworCisJaWYgKCFtX3BNaW5CdXR0b24gfHwgIW1fcE1heEJ1dHRvbilyZXR1cm4gcmNDbGllbnQ7CisKKwlDUERGX1JlY3QgcmNNaW4gPSBtX3BNaW5CdXR0b24tPkdldFdpbmRvd1JlY3QoKTsKKwlDUERGX1JlY3QgcmNNYXggPSBtX3BNYXhCdXR0b24tPkdldFdpbmRvd1JlY3QoKTsKKworCUZYX0ZMT0FUIGZNaW5XaWR0aCA9IHJjTWluLnJpZ2h0IC0gcmNNaW4ubGVmdDsKKwlGWF9GTE9BVCBmTWluSGVpZ2h0ID0gcmNNaW4udG9wIC0gcmNNaW4uYm90dG9tOworCUZYX0ZMT0FUIGZNYXhXaWR0aCA9IHJjTWF4LnJpZ2h0IC0gcmNNYXgubGVmdDsKKwlGWF9GTE9BVCBmTWF4SGVpZ2h0ID0gcmNNYXgudG9wIC0gcmNNYXguYm90dG9tOworCisJc3dpdGNoKG1fc2JUeXBlKQorCXsKKwljYXNlIFNCVF9IU0NST0xMOgorCQlpZiAocmNDbGllbnQucmlnaHQgLSByY0NsaWVudC5sZWZ0ID4gZk1pbldpZHRoICsgZk1heFdpZHRoICsgMikKKwkJeworCQkJcmNBcmVhID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQgKyBmTWluV2lkdGggKyAxLHJjQ2xpZW50LmJvdHRvbSwKKwkJCQkJCXJjQ2xpZW50LnJpZ2h0IC0gZk1heFdpZHRoIC0gMSxyY0NsaWVudC50b3ApOworCQl9CisJCWVsc2UKKwkJeworCQkJcmNBcmVhID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQgKyBmTWluV2lkdGggKyAxLHJjQ2xpZW50LmJvdHRvbSwKKwkJCQkJCXJjQ2xpZW50LmxlZnQgKyBmTWluV2lkdGggKyAxLHJjQ2xpZW50LnRvcCk7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBTQlRfVlNDUk9MTDoKKwkJaWYgKHJjQ2xpZW50LnRvcCAtIHJjQ2xpZW50LmJvdHRvbSA+IGZNaW5IZWlnaHQgKyBmTWF4SGVpZ2h0ICsgMikKKwkJeworCQkJcmNBcmVhID0gQ1BERl9SZWN0KHJjQ2xpZW50LmxlZnQscmNDbGllbnQuYm90dG9tICsgZk1pbkhlaWdodCArIDEsCisJCQkJCQlyY0NsaWVudC5yaWdodCxyY0NsaWVudC50b3AgLSBmTWF4SGVpZ2h0IC0gMSk7CisJCX0KKwkJZWxzZQorCQl7CisJCQlyY0FyZWEgPSBDUERGX1JlY3QocmNDbGllbnQubGVmdCxyY0NsaWVudC5ib3R0b20gKyBmTWluSGVpZ2h0ICsgMSwKKwkJCQkJCXJjQ2xpZW50LnJpZ2h0LHJjQ2xpZW50LmJvdHRvbSArIGZNaW5IZWlnaHQgKyAxKTsKKwkJfQorCQlicmVhazsKKwl9CisJCisJcmNBcmVhLk5vcm1hbGl6ZSgpOworCisJcmV0dXJuIHJjQXJlYTsKK30KKworRlhfRkxPQVQgQ1BXTF9TY3JvbGxCYXI6OlRydWVUb0ZhY2UoRlhfRkxPQVQgZlRydWUpCit7CisJQ1BERl9SZWN0IHJjUG9zQXJlYTsJCisJcmNQb3NBcmVhID0gR2V0U2Nyb2xsQXJlYSgpOworCisJRlhfRkxPQVQgZkZhY3RXaWR0aCA9IG1fc0RhdGEuU2Nyb2xsUmFuZ2UuR2V0V2lkdGgoKSArIG1fc0RhdGEuZkNsaWVudFdpZHRoOworCWZGYWN0V2lkdGggPSBmRmFjdFdpZHRoID09IDAgPyAxIDogZkZhY3RXaWR0aDsKKworCUZYX0ZMT0FUIGZGYWNlID0gMDsKKworCXN3aXRjaChtX3NiVHlwZSkKKwl7CisJY2FzZSBTQlRfSFNDUk9MTDoKKwkJZkZhY2UgPSByY1Bvc0FyZWEubGVmdCArIGZUcnVlICogKHJjUG9zQXJlYS5yaWdodCAtIHJjUG9zQXJlYS5sZWZ0KSAvIGZGYWN0V2lkdGg7CisJCWJyZWFrOworCWNhc2UgU0JUX1ZTQ1JPTEw6CisJCWZGYWNlID0gcmNQb3NBcmVhLnRvcCAtIGZUcnVlICogKHJjUG9zQXJlYS50b3AgLSByY1Bvc0FyZWEuYm90dG9tKSAvIGZGYWN0V2lkdGg7CisJCWJyZWFrOworCX0JCisKKwlyZXR1cm4gZkZhY2U7Cit9CisKK0ZYX0ZMT0FUIENQV0xfU2Nyb2xsQmFyOjpGYWNlVG9UcnVlKEZYX0ZMT0FUIGZGYWNlKQoreworCUNQREZfUmVjdCByY1Bvc0FyZWE7CQorCXJjUG9zQXJlYSA9IEdldFNjcm9sbEFyZWEoKTsKKworCUZYX0ZMT0FUIGZGYWN0V2lkdGggPSBtX3NEYXRhLlNjcm9sbFJhbmdlLkdldFdpZHRoKCkgKyBtX3NEYXRhLmZDbGllbnRXaWR0aDsKKwlmRmFjdFdpZHRoID0gZkZhY3RXaWR0aCA9PSAwID8gMSA6IGZGYWN0V2lkdGg7CisKKwlGWF9GTE9BVCBmVHJ1ZSA9IDA7CisKKwlzd2l0Y2gobV9zYlR5cGUpCisJeworCWNhc2UgU0JUX0hTQ1JPTEw6CisJCWZUcnVlID0gIChmRmFjZSAtIHJjUG9zQXJlYS5sZWZ0KSAqIGZGYWN0V2lkdGggLyAocmNQb3NBcmVhLnJpZ2h0IC0gcmNQb3NBcmVhLmxlZnQpOworCQlicmVhazsKKwljYXNlIFNCVF9WU0NST0xMOgorCQlmVHJ1ZSA9IChyY1Bvc0FyZWEudG9wIC0gZkZhY2UpICogZkZhY3RXaWR0aCAvIChyY1Bvc0FyZWEudG9wIC0gcmNQb3NBcmVhLmJvdHRvbSk7CisJCWJyZWFrOworCX0JCisKKwlyZXR1cm4gZlRydWU7Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQoreworCUNyZWF0ZUJ1dHRvbnMoY3ApOworfQorCit2b2lkIENQV0xfU2Nyb2xsQmFyOjpUaW1lclByb2MoKQoreworCVBXTF9TQ1JPTExfUFJJVkFURURBVEEgc1RlbXAgPSBtX3NEYXRhOworCisJaWYgKG1fYk1pbk9yTWF4KW1fc0RhdGEuU3ViU21hbGwoKTsJCisJZWxzZSBtX3NEYXRhLkFkZFNtYWxsKCk7CisKKwlpZiAoRlhTWVNfbWVtY21wKCZtX3NEYXRhLCAmc1RlbXAsIHNpemVvZihQV0xfU0NST0xMX1BSSVZBVEVEQVRBKSkgIT0gMCkKKwl7CisJCU1vdmVQb3NCdXR0b24oVFJVRSk7CisJCU5vdGlmeVNjcm9sbFdpbmRvdygpOworCX0KK30KKworLyoKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uU2V0Rm9jdXMoKQoreworCWlmIChHZXRUcmFuc3BhcmVuY3koKSAhPSAyNTUpCisJeworCQlTZXRUcmFuc3BhcmVuY3koMjU1KTsKKwkJSW52YWxpZGF0ZVJlY3QoKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9TY3JvbGxCYXI6Ok9uS2lsbEZvY3VzKCkKK3sKKwlpZiAoR2V0VHJhbnNwYXJlbmN5KCkgIT0gUFdMX1NDUk9MTEJBUl9UUkFOU1BBUkFOQ1kpCisJeworCQlTZXRUcmFuc3BhcmVuY3koUFdMX1NDUk9MTEJBUl9UUkFOU1BBUkFOQ1kpOworCQlJbnZhbGlkYXRlUmVjdCgpOworCX0KK30KKyovCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfU2lnbmF0dXJlLmNwcCBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfU2lnbmF0dXJlLmNwcAppbmRleCAzNjI5N2YzLi41ZDc5Y2U5IDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX1NpZ25hdHVyZS5jcHAKKysrIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9TaWduYXR1cmUuY3BwCkBAIC0xLDIyMCArMSwyMjAgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfSWNvbi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2lnbmF0dXJlLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MYWJlbC5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9TaWduYXR1cmVfSW1hZ2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BXTF9TaWduYXR1cmVfSW1hZ2U6OkNQV0xfU2lnbmF0dXJlX0ltYWdlKCkgOiBtX3BJbWFnZShOVUxMKQ0KLXsNCi19DQotDQotQ1BXTF9TaWduYXR1cmVfSW1hZ2U6On5DUFdMX1NpZ25hdHVyZV9JbWFnZSgpDQotew0KLX0NCi0NCi12b2lkIENQV0xfU2lnbmF0dXJlX0ltYWdlOjpTZXRJbWFnZShDRlhfRElCU291cmNlKiBwSW1hZ2UpDQotew0KLQltX3BJbWFnZSA9IHBJbWFnZTsNCi19DQotDQotQ0ZYX0RJQlNvdXJjZSogQ1BXTF9TaWduYXR1cmVfSW1hZ2U6OkdldEltYWdlKCkNCi17DQotCXJldHVybiBtX3BJbWFnZTsNCi19DQotDQotdm9pZCBDUFdMX1NpZ25hdHVyZV9JbWFnZTo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpDQotew0KLQlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7DQotDQotCWlmIChtX3BJbWFnZSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQkJRlhfRkxPQVQgeCwgeTsNCi0JCXBVc2VyMkRldmljZS0+VHJhbnNmb3JtKHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LnRvcCwgeCwgeSk7DQotDQotCQlwRGV2aWNlLT5TdHJldGNoRElCaXRzKG1fcEltYWdlLCAoRlhfSU5UMzIpeCwgKEZYX0lOVDMyKXksIA0KLQkJCShGWF9JTlQzMilyY0NsaWVudC5XaWR0aCgpLCAoRlhfSU5UMzIpcmNDbGllbnQuSGVpZ2h0KCkpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TaWduYXR1cmVfSW1hZ2U6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pDQotew0KLQlzQXBwU3RyZWFtIDw8IENQV0xfSW1hZ2U6OkdldEltYWdlQXBwU3RyZWFtKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TaWduYXR1cmVfSW1hZ2U6OkdldFNjYWxlKEZYX0ZMT0FUICYgZkhTY2FsZSxGWF9GTE9BVCAmIGZWU2NhbGUpDQotew0KLQlGWF9GTE9BVCBmSW1hZ2VXLCBmSW1hZ2VIOw0KLQ0KLQlHZXRJbWFnZVNpemUoZkltYWdlVywgZkltYWdlSCk7DQotDQotCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0NCi0JZkhTY2FsZSA9IHJjQ2xpZW50LldpZHRoKCkgLyBmSW1hZ2VXOw0KLQlmVlNjYWxlID0gcmNDbGllbnQuSGVpZ2h0KCkgLyBmSW1hZ2VIOwkNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfU2lnbmF0dXJlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNQV0xfU2lnbmF0dXJlOjpDUFdMX1NpZ25hdHVyZSgpIDogDQotCW1fcFRleHQoTlVMTCksDQotCW1fcERlc2NyaXB0aW9uKE5VTEwpLA0KLQltX3BJbWFnZShOVUxMKSwNCi0JbV9iVGV4dEV4aXN0KFRSVUUpLA0KLQltX2JJbWFnZUV4aXN0KEZBTFNFKSwNCi0JbV9iRmxhZ0V4aXN0KFRSVUUpDQotew0KLX0NCi0NCi1DUFdMX1NpZ25hdHVyZTo6fkNQV0xfU2lnbmF0dXJlKCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TaWduYXR1cmU6OlNldFRleHRGbGFnKEZYX0JPT0wgYlRleHRFeGlzdCkNCi17DQotCW1fYlRleHRFeGlzdCA9IGJUZXh0RXhpc3Q7DQotDQotCVJlUG9zQ2hpbGRXbmQoKTsNCi19DQotDQotdm9pZCBDUFdMX1NpZ25hdHVyZTo6U2V0SW1hZ2VGbGFnKEZYX0JPT0wgYkltYWdlRXhpc3QpDQotew0KLQltX2JJbWFnZUV4aXN0ID0gYkltYWdlRXhpc3Q7DQotDQotCVJlUG9zQ2hpbGRXbmQoKTsNCi19DQotDQotdm9pZCBDUFdMX1NpZ25hdHVyZTo6U2V0Rm94aXRGbGFnKEZYX0JPT0wgYkZsYWdFeGlzdCkNCi17DQotCW1fYkZsYWdFeGlzdCA9IGJGbGFnRXhpc3Q7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TaWduYXR1cmU6OlNldFRleHQoRlhfTFBDV1NUUiBzVGV4dCkNCi17DQotCW1fcFRleHQtPlNldFRleHQoc1RleHQpOw0KLQ0KLQlSZVBvc0NoaWxkV25kKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TaWduYXR1cmU6OlNldERlc2NyaXB0aW9uKEZYX0xQQ1dTVFIgc3RyaW5nKQ0KLXsNCi0JbV9wRGVzY3JpcHRpb24tPlNldFRleHQoc3RyaW5nKTsNCi0NCi0JUmVQb3NDaGlsZFduZCgpOw0KLX0NCi0NCi12b2lkIENQV0xfU2lnbmF0dXJlOjpTZXRJbWFnZShDRlhfRElCU291cmNlKiBwSW1hZ2UpDQotew0KLQltX3BJbWFnZS0+U2V0SW1hZ2UocEltYWdlKTsNCi0NCi0JUmVQb3NDaGlsZFduZCgpOw0KLX0NCi0NCi12b2lkIENQV0xfU2lnbmF0dXJlOjpTZXRJbWFnZVN0cmVhbShDUERGX1N0cmVhbSAqIHBTdHJlYW0sIEZYX0xQQ1NUUiBzSW1hZ2VBbGlhcykNCi17DQotCW1fcEltYWdlLT5TZXRQREZTdHJlYW0ocFN0cmVhbSk7DQotCW1fcEltYWdlLT5TZXRJbWFnZUFsaWFzKHNJbWFnZUFsaWFzKTsNCi0NCi0JUmVQb3NDaGlsZFduZCgpOw0KLX0NCi0NCi12b2lkIENQV0xfU2lnbmF0dXJlOjpSZVBvc0NoaWxkV25kKCkNCi17DQotCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsNCi0NCi0JQ1BERl9SZWN0IHJjVGV4dCA9IHJjQ2xpZW50Ow0KLQlDUERGX1JlY3QgcmNEZXNjcmlwdGlvbiA9IHJjQ2xpZW50Ow0KLQ0KLQlGWF9CT09MIGJUZXh0VmlzaWJsZSA9IG1fYlRleHRFeGlzdCAmJiBtX3BUZXh0LT5HZXRUZXh0KCkuR2V0TGVuZ3RoKCkgPiAwOw0KLQkNCi0JaWYgKChiVGV4dFZpc2libGUgfHwgbV9iSW1hZ2VFeGlzdCkgJiYNCi0JCW1fcERlc2NyaXB0aW9uLT5HZXRUZXh0KCkuR2V0TGVuZ3RoKCkgPiAwKQ0KLQl7DQotCQlpZiAocmNDbGllbnQuV2lkdGgoKSA+PSByY0NsaWVudC5IZWlnaHQoKSkNCi0JCXsNCi0JCQlyY1RleHQucmlnaHQgPSByY1RleHQubGVmdCArIHJjQ2xpZW50LldpZHRoKCkgLyAyLjBmOw0KLQkJCXJjRGVzY3JpcHRpb24ubGVmdCA9IHJjRGVzY3JpcHRpb24ucmlnaHQgLSByY0NsaWVudC5XaWR0aCgpIC8gMi4wZjsNCi0JCX0NCi0JCWVsc2UNCi0JCXsNCi0JCQlyY1RleHQuYm90dG9tID0gcmNUZXh0LnRvcCAtIHJjQ2xpZW50LkhlaWdodCgpIC8gMi4wZjsNCi0JCQlyY0Rlc2NyaXB0aW9uLnRvcCA9IHJjRGVzY3JpcHRpb24uYm90dG9tICsgcmNDbGllbnQuSGVpZ2h0KCkgLyAyLjBmOw0KLQkJfQ0KLQl9DQotDQotCW1fcFRleHQtPlNldFZpc2libGUoYlRleHRWaXNpYmxlKTsNCi0JbV9wSW1hZ2UtPlNldFZpc2libGUobV9iSW1hZ2VFeGlzdCk7DQotDQotCW1fcFRleHQtPk1vdmUocmNUZXh0LCBUUlVFLCBGQUxTRSk7DQotCW1fcEltYWdlLT5Nb3ZlKHJjVGV4dCwgVFJVRSwgRkFMU0UpOw0KLQltX3BEZXNjcmlwdGlvbi0+TW92ZShyY0Rlc2NyaXB0aW9uLCBUUlVFLCBGQUxTRSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9TaWduYXR1cmU6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0KLXsNCi0JbV9wSW1hZ2UgPSBuZXcgQ1BXTF9TaWduYXR1cmVfSW1hZ2U7DQotCVBXTF9DUkVBVEVQQVJBTSBpY3AgPSBjcDsNCi0JaWNwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQlpY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOw0KLQlpY3Auc1RleHRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDApOw0KLQltX3BJbWFnZS0+Q3JlYXRlKGljcCk7DQotDQotCW1fcFRleHQgPSBuZXcgQ1BXTF9MYWJlbDsNCi0JUFdMX0NSRUFURVBBUkFNIGFjcCA9IGNwOw0KLQlhY3AucFBhcmVudFduZCA9IHRoaXM7DQotCWFjcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEUgfCBQV1NfQVVUT0ZPTlRTSVpFIHwgUEVTX01VTFRJTElORSB8IFBFU19BVVRPUkVUVVJOIHwgUEVTX01JRERMRSB8IFBFU19DRU5URVI7DQotCWFjcC5zVGV4dENvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMCk7DQotCW1fcFRleHQtPkNyZWF0ZShhY3ApOw0KLQ0KLQltX3BEZXNjcmlwdGlvbiA9IG5ldyBDUFdMX0xhYmVsOw0KLQlQV0xfQ1JFQVRFUEFSQU0gZGNwID0gY3A7DQotCWRjcC5wUGFyZW50V25kID0gdGhpczsNCi0JZGNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19BVVRPRk9OVFNJWkUgfCBQRVNfTVVMVElMSU5FIHwgUEVTX0FVVE9SRVRVUk4gfCBQRVNfTEVGVCB8IFBFU19DRU5URVI7DQotCWRjcC5zVGV4dENvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMCk7DQotCW1fcERlc2NyaXB0aW9uLT5DcmVhdGUoZGNwKTsNCi19DQotDQotdm9pZCBDUFdMX1NpZ25hdHVyZTo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpDQotew0KLQlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7DQotDQotCWlmIChtX2JGbGFnRXhpc3QpDQotCQlDUFdMX1V0aWxzOjpEcmF3SWNvbkFwcFN0cmVhbShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIFBXTF9JQ09OVFlQRV9GT1hJVCwgQ1BXTF9VdGlsczo6R2V0Q2VudGVyU3F1YXJlKEdldENsaWVudFJlY3QoKSksDQotCQkJQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLDAuOTFmLDAuODU1ZiwwLjkyZiksIENQV0xfQ29sb3IoQ09MT1JUWVBFX1RSQU5TUEFSRU5UKSwgMjU1KTsNCi0NCi0JLyoNCi0JQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQlDRlhfUGF0aERhdGEgcGF0aDsNCi0NCi0JcGF0aC5TZXRQb2ludENvdW50KDIpOw0KLQlwYXRoLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIChyY0NsaWVudC50b3AgKyByY0NsaWVudC5ib3R0b20pICogMC41ZiwgRlhQVF9NT1ZFVE8pOw0KLQlwYXRoLlNldFBvaW50KDEsIHJjQ2xpZW50LnJpZ2h0LCAocmNDbGllbnQudG9wICsgcmNDbGllbnQuYm90dG9tKSAqIDAuNWYsIEZYUFRfTElORVRPKTsNCi0NCi0JQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JZ3NkLlNldERhc2hDb3VudCgyKTsJCQkJDQotCWdzZC5tX0Rhc2hBcnJheVswXSA9IDYuMGY7DQotCWdzZC5tX0Rhc2hBcnJheVsxXSA9IDYuMGY7DQotCWdzZC5tX0Rhc2hQaGFzZSA9IDA7CQ0KLQkNCi0JZ3NkLm1fTGluZVdpZHRoID0gMTAuMGY7DQotCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoLCBwVXNlcjJEZXZpY2UsICZnc2QsIDAsIEFyZ2JFbmNvZGUoMjU1LDI1NSwwLDApLCBGWEZJTExfQUxURVJOQVRFKTsNCi0JKi8NCi19DQotDQotdm9pZCBDUFdMX1NpZ25hdHVyZTo6R2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oQ0ZYX0J5dGVUZXh0QnVmICYgc0FwcFN0cmVhbSkNCi17DQotCUNQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsNCi19DQotDQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfSWNvbi5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TaWduYXR1cmUuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGFiZWwuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfU2lnbmF0dXJlX0ltYWdlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX1NpZ25hdHVyZV9JbWFnZTo6Q1BXTF9TaWduYXR1cmVfSW1hZ2UoKSA6IG1fcEltYWdlKE5VTEwpCit7Cit9CisKK0NQV0xfU2lnbmF0dXJlX0ltYWdlOjp+Q1BXTF9TaWduYXR1cmVfSW1hZ2UoKQoreworfQorCit2b2lkIENQV0xfU2lnbmF0dXJlX0ltYWdlOjpTZXRJbWFnZShDRlhfRElCU291cmNlKiBwSW1hZ2UpCit7CisJbV9wSW1hZ2UgPSBwSW1hZ2U7Cit9CisKK0NGWF9ESUJTb3VyY2UqIENQV0xfU2lnbmF0dXJlX0ltYWdlOjpHZXRJbWFnZSgpCit7CisJcmV0dXJuIG1fcEltYWdlOworfQorCit2b2lkIENQV0xfU2lnbmF0dXJlX0ltYWdlOjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKK3sKKwlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7CisKKwlpZiAobV9wSW1hZ2UpCisJeworCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisKKwkJRlhfRkxPQVQgeCwgeTsKKwkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm0ocmNDbGllbnQubGVmdCwgcmNDbGllbnQudG9wLCB4LCB5KTsKKworCQlwRGV2aWNlLT5TdHJldGNoRElCaXRzKG1fcEltYWdlLCAoRlhfSU5UMzIpeCwgKEZYX0lOVDMyKXksIAorCQkJKEZYX0lOVDMyKXJjQ2xpZW50LldpZHRoKCksIChGWF9JTlQzMilyY0NsaWVudC5IZWlnaHQoKSk7CisJfQorfQorCit2b2lkIENQV0xfU2lnbmF0dXJlX0ltYWdlOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKQoreworCXNBcHBTdHJlYW0gPDwgQ1BXTF9JbWFnZTo6R2V0SW1hZ2VBcHBTdHJlYW0oKTsKK30KKwordm9pZCBDUFdMX1NpZ25hdHVyZV9JbWFnZTo6R2V0U2NhbGUoRlhfRkxPQVQgJiBmSFNjYWxlLEZYX0ZMT0FUICYgZlZTY2FsZSkKK3sKKwlGWF9GTE9BVCBmSW1hZ2VXLCBmSW1hZ2VIOworCisJR2V0SW1hZ2VTaXplKGZJbWFnZVcsIGZJbWFnZUgpOworCisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOworCisJZkhTY2FsZSA9IHJjQ2xpZW50LldpZHRoKCkgLyBmSW1hZ2VXOworCWZWU2NhbGUgPSByY0NsaWVudC5IZWlnaHQoKSAvIGZJbWFnZUg7CQorfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9TaWduYXR1cmUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfU2lnbmF0dXJlOjpDUFdMX1NpZ25hdHVyZSgpIDogCisJbV9wVGV4dChOVUxMKSwKKwltX3BEZXNjcmlwdGlvbihOVUxMKSwKKwltX3BJbWFnZShOVUxMKSwKKwltX2JUZXh0RXhpc3QoVFJVRSksCisJbV9iSW1hZ2VFeGlzdChGQUxTRSksCisJbV9iRmxhZ0V4aXN0KFRSVUUpCit7Cit9CisKK0NQV0xfU2lnbmF0dXJlOjp+Q1BXTF9TaWduYXR1cmUoKQoreworfQorCit2b2lkIENQV0xfU2lnbmF0dXJlOjpTZXRUZXh0RmxhZyhGWF9CT09MIGJUZXh0RXhpc3QpCit7CisJbV9iVGV4dEV4aXN0ID0gYlRleHRFeGlzdDsKKworCVJlUG9zQ2hpbGRXbmQoKTsKK30KKwordm9pZCBDUFdMX1NpZ25hdHVyZTo6U2V0SW1hZ2VGbGFnKEZYX0JPT0wgYkltYWdlRXhpc3QpCit7CisJbV9iSW1hZ2VFeGlzdCA9IGJJbWFnZUV4aXN0OworCisJUmVQb3NDaGlsZFduZCgpOworfQorCit2b2lkIENQV0xfU2lnbmF0dXJlOjpTZXRGb3hpdEZsYWcoRlhfQk9PTCBiRmxhZ0V4aXN0KQoreworCW1fYkZsYWdFeGlzdCA9IGJGbGFnRXhpc3Q7Cit9CisKK3ZvaWQgQ1BXTF9TaWduYXR1cmU6OlNldFRleHQoRlhfTFBDV1NUUiBzVGV4dCkKK3sKKwltX3BUZXh0LT5TZXRUZXh0KHNUZXh0KTsKKworCVJlUG9zQ2hpbGRXbmQoKTsKK30KKwordm9pZCBDUFdMX1NpZ25hdHVyZTo6U2V0RGVzY3JpcHRpb24oRlhfTFBDV1NUUiBzdHJpbmcpCit7CisJbV9wRGVzY3JpcHRpb24tPlNldFRleHQoc3RyaW5nKTsKKworCVJlUG9zQ2hpbGRXbmQoKTsKK30KKwordm9pZCBDUFdMX1NpZ25hdHVyZTo6U2V0SW1hZ2UoQ0ZYX0RJQlNvdXJjZSogcEltYWdlKQoreworCW1fcEltYWdlLT5TZXRJbWFnZShwSW1hZ2UpOworCisJUmVQb3NDaGlsZFduZCgpOworfQorCit2b2lkIENQV0xfU2lnbmF0dXJlOjpTZXRJbWFnZVN0cmVhbShDUERGX1N0cmVhbSAqIHBTdHJlYW0sIEZYX0xQQ1NUUiBzSW1hZ2VBbGlhcykKK3sKKwltX3BJbWFnZS0+U2V0UERGU3RyZWFtKHBTdHJlYW0pOworCW1fcEltYWdlLT5TZXRJbWFnZUFsaWFzKHNJbWFnZUFsaWFzKTsKKworCVJlUG9zQ2hpbGRXbmQoKTsKK30KKwordm9pZCBDUFdMX1NpZ25hdHVyZTo6UmVQb3NDaGlsZFduZCgpCit7CisJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOworCisJQ1BERl9SZWN0IHJjVGV4dCA9IHJjQ2xpZW50OworCUNQREZfUmVjdCByY0Rlc2NyaXB0aW9uID0gcmNDbGllbnQ7CisKKwlGWF9CT09MIGJUZXh0VmlzaWJsZSA9IG1fYlRleHRFeGlzdCAmJiBtX3BUZXh0LT5HZXRUZXh0KCkuR2V0TGVuZ3RoKCkgPiAwOworCQorCWlmICgoYlRleHRWaXNpYmxlIHx8IG1fYkltYWdlRXhpc3QpICYmCisJCW1fcERlc2NyaXB0aW9uLT5HZXRUZXh0KCkuR2V0TGVuZ3RoKCkgPiAwKQorCXsKKwkJaWYgKHJjQ2xpZW50LldpZHRoKCkgPj0gcmNDbGllbnQuSGVpZ2h0KCkpCisJCXsKKwkJCXJjVGV4dC5yaWdodCA9IHJjVGV4dC5sZWZ0ICsgcmNDbGllbnQuV2lkdGgoKSAvIDIuMGY7CisJCQlyY0Rlc2NyaXB0aW9uLmxlZnQgPSByY0Rlc2NyaXB0aW9uLnJpZ2h0IC0gcmNDbGllbnQuV2lkdGgoKSAvIDIuMGY7CisJCX0KKwkJZWxzZQorCQl7CisJCQlyY1RleHQuYm90dG9tID0gcmNUZXh0LnRvcCAtIHJjQ2xpZW50LkhlaWdodCgpIC8gMi4wZjsKKwkJCXJjRGVzY3JpcHRpb24udG9wID0gcmNEZXNjcmlwdGlvbi5ib3R0b20gKyByY0NsaWVudC5IZWlnaHQoKSAvIDIuMGY7CisJCX0KKwl9CisKKwltX3BUZXh0LT5TZXRWaXNpYmxlKGJUZXh0VmlzaWJsZSk7CisJbV9wSW1hZ2UtPlNldFZpc2libGUobV9iSW1hZ2VFeGlzdCk7CisKKwltX3BUZXh0LT5Nb3ZlKHJjVGV4dCwgVFJVRSwgRkFMU0UpOworCW1fcEltYWdlLT5Nb3ZlKHJjVGV4dCwgVFJVRSwgRkFMU0UpOworCW1fcERlc2NyaXB0aW9uLT5Nb3ZlKHJjRGVzY3JpcHRpb24sIFRSVUUsIEZBTFNFKTsKK30KKwordm9pZCBDUFdMX1NpZ25hdHVyZTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJbV9wSW1hZ2UgPSBuZXcgQ1BXTF9TaWduYXR1cmVfSW1hZ2U7CisJUFdMX0NSRUFURVBBUkFNIGljcCA9IGNwOworCWljcC5wUGFyZW50V25kID0gdGhpczsKKwlpY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOworCWljcC5zVGV4dENvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMCk7CisJbV9wSW1hZ2UtPkNyZWF0ZShpY3ApOworCisJbV9wVGV4dCA9IG5ldyBDUFdMX0xhYmVsOworCVBXTF9DUkVBVEVQQVJBTSBhY3AgPSBjcDsKKwlhY3AucFBhcmVudFduZCA9IHRoaXM7CisJYWNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19BVVRPRk9OVFNJWkUgfCBQRVNfTVVMVElMSU5FIHwgUEVTX0FVVE9SRVRVUk4gfCBQRVNfTUlERExFIHwgUEVTX0NFTlRFUjsKKwlhY3Auc1RleHRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksIDApOworCW1fcFRleHQtPkNyZWF0ZShhY3ApOworCisJbV9wRGVzY3JpcHRpb24gPSBuZXcgQ1BXTF9MYWJlbDsKKwlQV0xfQ1JFQVRFUEFSQU0gZGNwID0gY3A7CisJZGNwLnBQYXJlbnRXbmQgPSB0aGlzOworCWRjcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEUgfCBQV1NfQVVUT0ZPTlRTSVpFIHwgUEVTX01VTFRJTElORSB8IFBFU19BVVRPUkVUVVJOIHwgUEVTX0xFRlQgfCBQRVNfQ0VOVEVSOworCWRjcC5zVGV4dENvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwgMCk7CisJbV9wRGVzY3JpcHRpb24tPkNyZWF0ZShkY3ApOworfQorCit2b2lkIENQV0xfU2lnbmF0dXJlOjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKK3sKKwlDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7CisKKwlpZiAobV9iRmxhZ0V4aXN0KQorCQlDUFdMX1V0aWxzOjpEcmF3SWNvbkFwcFN0cmVhbShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIFBXTF9JQ09OVFlQRV9GT1hJVCwgQ1BXTF9VdGlsczo6R2V0Q2VudGVyU3F1YXJlKEdldENsaWVudFJlY3QoKSksCisJCQlDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsMC45MWYsMC44NTVmLDAuOTJmKSwgQ1BXTF9Db2xvcihDT0xPUlRZUEVfVFJBTlNQQVJFTlQpLCAyNTUpOworCisJLyoKKwlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CisKKwlDRlhfUGF0aERhdGEgcGF0aDsKKworCXBhdGguU2V0UG9pbnRDb3VudCgyKTsKKwlwYXRoLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIChyY0NsaWVudC50b3AgKyByY0NsaWVudC5ib3R0b20pICogMC41ZiwgRlhQVF9NT1ZFVE8pOworCXBhdGguU2V0UG9pbnQoMSwgcmNDbGllbnQucmlnaHQsIChyY0NsaWVudC50b3AgKyByY0NsaWVudC5ib3R0b20pICogMC41ZiwgRlhQVF9MSU5FVE8pOworCisJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKKwlnc2QuU2V0RGFzaENvdW50KDIpOwkJCQkKKwlnc2QubV9EYXNoQXJyYXlbMF0gPSA2LjBmOworCWdzZC5tX0Rhc2hBcnJheVsxXSA9IDYuMGY7CisJZ3NkLm1fRGFzaFBoYXNlID0gMDsJCisJCisJZ3NkLm1fTGluZVdpZHRoID0gMTAuMGY7CisJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgJmdzZCwgMCwgQXJnYkVuY29kZSgyNTUsMjU1LDAsMCksIEZYRklMTF9BTFRFUk5BVEUpOworCSovCit9CisKK3ZvaWQgQ1BXTF9TaWduYXR1cmU6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pCit7CisJQ1BXTF9XbmQ6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKHNBcHBTdHJlYW0pOworfQorCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfU3BlY2lhbEJ1dHRvbi5jcHAgYi9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX1NwZWNpYWxCdXR0b24uY3BwCmluZGV4IGFhYmY1MDMuLjI4N2ZlYzEgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfU3BlY2lhbEJ1dHRvbi5jcHAKKysrIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9TcGVjaWFsQnV0dG9uLmNwcApAQCAtMSwxMTAgKzEsMTEwIEBACi0vLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCi0vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlDQotLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4NCi0gDQotLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20NCi0NCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCINCi0jaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU3BlY2lhbEJ1dHRvbi5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCINCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9QdXNoQnV0dG9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX1B1c2hCdXR0b246OkNQV0xfUHVzaEJ1dHRvbigpDQotew0KLX0NCi0NCi1DUFdMX1B1c2hCdXR0b246On5DUFdMX1B1c2hCdXR0b24oKQ0KLXsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9QdXNoQnV0dG9uOjpHZXRDbGFzc05hbWUoKSBjb25zdA0KLXsNCi0JcmV0dXJuICJDUFdMX1B1c2hCdXR0b24iOw0KLX0NCi0NCi1DUERGX1JlY3QgQ1BXTF9QdXNoQnV0dG9uOjpHZXRGb2N1c1JlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHRoaXMtPkdldFdpbmRvd1JlY3QoKSwoRlhfRkxPQVQpR2V0Qm9yZGVyV2lkdGgoKSk7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX0NoZWNrQm94IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX0NoZWNrQm94OjpDUFdMX0NoZWNrQm94KCkgOiBtX2JDaGVja2VkKEZBTFNFKQ0KLXsNCi19DQotDQotQ1BXTF9DaGVja0JveDo6fkNQV0xfQ2hlY2tCb3goKQ0KLXsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9DaGVja0JveDo6R2V0Q2xhc3NOYW1lKCkgY29uc3QNCi17DQotCXJldHVybiAiQ1BXTF9DaGVja0JveCI7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9DaGVja0JveDo6U2V0Q2hlY2soRlhfQk9PTCBiQ2hlY2spDQotew0KLQltX2JDaGVja2VkID0gYkNoZWNrOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfQ2hlY2tCb3g6OklzQ2hlY2tlZCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9iQ2hlY2tlZDsNCi19DQotDQotRlhfQk9PTCBDUFdMX0NoZWNrQm94OjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpDQotew0KLQlpZiAoSXNSZWFkT25seSgpKSByZXR1cm4gRkFMU0U7DQotDQotCVNldENoZWNrKCFJc0NoZWNrZWQoKSk7DQotCXJldHVybiBUUlVFOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfQ2hlY2tCb3g6Ok9uQ2hhcihGWF9XT1JEIG5DaGFyKQ0KLXsNCi0JU2V0Q2hlY2soIUlzQ2hlY2tlZCgpKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX1JhZGlvQnV0dG9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1DUFdMX1JhZGlvQnV0dG9uOjpDUFdMX1JhZGlvQnV0dG9uKCkgOiBtX2JDaGVja2VkKEZBTFNFKQ0KLXsNCi19DQotDQotQ1BXTF9SYWRpb0J1dHRvbjo6fkNQV0xfUmFkaW9CdXR0b24oKQ0KLXsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9SYWRpb0J1dHRvbjo6R2V0Q2xhc3NOYW1lKCkgY29uc3QNCi17DQotCXJldHVybiAiQ1BXTF9SYWRpb0J1dHRvbiI7DQotfQ0KLQ0KLUZYX0JPT0wJQ1BXTF9SYWRpb0J1dHRvbjo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQ0KLXsNCi0JaWYgKElzUmVhZE9ubHkoKSkgcmV0dXJuIEZBTFNFOw0KLQ0KLQlTZXRDaGVjayhUUlVFKTsNCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9SYWRpb0J1dHRvbjo6U2V0Q2hlY2soRlhfQk9PTCBiQ2hlY2spDQotew0KLQltX2JDaGVja2VkID0gYkNoZWNrOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfUmFkaW9CdXR0b246OklzQ2hlY2tlZCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9iQ2hlY2tlZDsNCi19DQotDQotRlhfQk9PTCBDUFdMX1JhZGlvQnV0dG9uOjpPbkNoYXIoRlhfV09SRCBuQ2hhcikNCi17DQotCVNldENoZWNrKFRSVUUpOw0KLQlyZXR1cm4gVFJVRTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQnV0dG9uLmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1NwZWNpYWxCdXR0b24uaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCIKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfUHVzaEJ1dHRvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfUHVzaEJ1dHRvbjo6Q1BXTF9QdXNoQnV0dG9uKCkKK3sKK30KKworQ1BXTF9QdXNoQnV0dG9uOjp+Q1BXTF9QdXNoQnV0dG9uKCkKK3sKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9QdXNoQnV0dG9uOjpHZXRDbGFzc05hbWUoKSBjb25zdAoreworCXJldHVybiAiQ1BXTF9QdXNoQnV0dG9uIjsKK30KKworQ1BERl9SZWN0IENQV0xfUHVzaEJ1dHRvbjo6R2V0Rm9jdXNSZWN0KCkgY29uc3QKK3sKKwlyZXR1cm4gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QodGhpcy0+R2V0V2luZG93UmVjdCgpLChGWF9GTE9BVClHZXRCb3JkZXJXaWR0aCgpKTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfQ2hlY2tCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX0NoZWNrQm94OjpDUFdMX0NoZWNrQm94KCkgOiBtX2JDaGVja2VkKEZBTFNFKQoreworfQorCitDUFdMX0NoZWNrQm94Ojp+Q1BXTF9DaGVja0JveCgpCit7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfQ2hlY2tCb3g6OkdldENsYXNzTmFtZSgpIGNvbnN0Cit7CisJcmV0dXJuICJDUFdMX0NoZWNrQm94IjsKK30KKwordm9pZCBDUFdMX0NoZWNrQm94OjpTZXRDaGVjayhGWF9CT09MIGJDaGVjaykKK3sKKwltX2JDaGVja2VkID0gYkNoZWNrOworfQorCitGWF9CT09MIENQV0xfQ2hlY2tCb3g6OklzQ2hlY2tlZCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fYkNoZWNrZWQ7Cit9CisKK0ZYX0JPT0wgQ1BXTF9DaGVja0JveDo6T25MQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KQoreworCWlmIChJc1JlYWRPbmx5KCkpIHJldHVybiBGQUxTRTsKKworCVNldENoZWNrKCFJc0NoZWNrZWQoKSk7CisJcmV0dXJuIFRSVUU7Cit9CisKK0ZYX0JPT0wgQ1BXTF9DaGVja0JveDo6T25DaGFyKEZYX1dPUkQgbkNoYXIpCit7CisJU2V0Q2hlY2soIUlzQ2hlY2tlZCgpKTsKKwlyZXR1cm4gVFJVRTsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfUmFkaW9CdXR0b24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDUFdMX1JhZGlvQnV0dG9uOjpDUFdMX1JhZGlvQnV0dG9uKCkgOiBtX2JDaGVja2VkKEZBTFNFKQoreworfQorCitDUFdMX1JhZGlvQnV0dG9uOjp+Q1BXTF9SYWRpb0J1dHRvbigpCit7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfUmFkaW9CdXR0b246OkdldENsYXNzTmFtZSgpIGNvbnN0Cit7CisJcmV0dXJuICJDUFdMX1JhZGlvQnV0dG9uIjsKK30KKworRlhfQk9PTAlDUFdMX1JhZGlvQnV0dG9uOjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpCit7CisJaWYgKElzUmVhZE9ubHkoKSkgcmV0dXJuIEZBTFNFOworCisJU2V0Q2hlY2soVFJVRSk7CisJcmV0dXJuIFRSVUU7Cit9CisKK3ZvaWQgQ1BXTF9SYWRpb0J1dHRvbjo6U2V0Q2hlY2soRlhfQk9PTCBiQ2hlY2spCit7CisJbV9iQ2hlY2tlZCA9IGJDaGVjazsKK30KKworRlhfQk9PTCBDUFdMX1JhZGlvQnV0dG9uOjpJc0NoZWNrZWQoKSBjb25zdAoreworCXJldHVybiBtX2JDaGVja2VkOworfQorCitGWF9CT09MIENQV0xfUmFkaW9CdXR0b246Ok9uQ2hhcihGWF9XT1JEIG5DaGFyKQoreworCVNldENoZWNrKFRSVUUpOworCXJldHVybiBUUlVFOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX1V0aWxzLmNwcCBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfVXRpbHMuY3BwCmluZGV4IGFlYzFkNGQuLjFkZTZiNTYgMTAwNjQ0Ci0tLSBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfVXRpbHMuY3BwCisrKyBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfVXRpbHMuY3BwCkBAIC0xLDI4NDQgKzEsMjg0NCBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfSWNvbi5oIg0KLQ0KLSNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpDQotI2RlZmluZSBJc0Zsb2F0QmlnZ2VyKGZhLGZiKQkJCQkoKGZhKSA+IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCi0jZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLGZiKQkJCQkoKGZhKSA8IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkNCi0jZGVmaW5lIElzRmxvYXRFcXVhbChmYSxmYikJCQkJCUlzRmxvYXRaZXJvKChmYSktKGZiKSkNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfVXRpbHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QXBwU3RyZWFtRnJvbUFycmF5KGNvbnN0IENQV0xfUGF0aERhdGEqIHBQYXRoRGF0YSwgRlhfSU5UMzIgbkNvdW50KQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIGNzQVA7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wOyBpPG5Db3VudDsgaSsrKQ0KLQl7DQotCQlzd2l0Y2ggKHBQYXRoRGF0YVtpXS50eXBlKQ0KLQkJew0KLQkJY2FzZSBQV0xQVF9NT1ZFVE86DQotCQkJY3NBUCA8PCBwUGF0aERhdGFbaV0ucG9pbnQueCA8PCAiICIgPDwgcFBhdGhEYXRhW2ldLnBvaW50LnkgPDwgIiBtXG4iOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQV0xQVF9MSU5FVE86DQotCQkJY3NBUCA8PCBwUGF0aERhdGFbaV0ucG9pbnQueCA8PCAiICIgPDwgcFBhdGhEYXRhW2ldLnBvaW50LnkgPDwgIiBsXG4iOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQV0xQVF9CRVpJRVJUTzoNCi0JCQljc0FQIDw8IHBQYXRoRGF0YVtpXS5wb2ludC54IDw8ICIgIiA8PCBwUGF0aERhdGFbaV0ucG9pbnQueSA8PCAiICINCi0JCQkJIDw8IHBQYXRoRGF0YVtpKzFdLnBvaW50LnggPDwgIiAiIDw8IHBQYXRoRGF0YVtpKzFdLnBvaW50LnkgPDwgIiAiDQotCQkJCSA8PCBwUGF0aERhdGFbaSsyXS5wb2ludC54IDw8ICIgIiA8PCBwUGF0aERhdGFbaSsyXS5wb2ludC55IDw8ICIgY1xuIjsNCi0NCi0JCQlpICs9IDI7DQotCQkJYnJlYWs7DQotCQlkZWZhdWx0Og0KLQkJCWJyZWFrOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpHZXRQYXRoRGF0YUZyb21BcnJheShDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQV0xfUGF0aERhdGEqIHBQYXRoRGF0YSwgRlhfSU5UMzIgbkNvdW50KQ0KLXsNCi0JcGF0aC5TZXRQb2ludENvdW50KG5Db3VudCk7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wOyBpPG5Db3VudDsgaSsrKQ0KLQl7DQotCQlzd2l0Y2ggKHBQYXRoRGF0YVtpXS50eXBlKQ0KLQkJew0KLQkJY2FzZSBQV0xQVF9NT1ZFVE86DQotCQkJcGF0aC5TZXRQb2ludChpLCBwUGF0aERhdGFbaV0ucG9pbnQueCwgcFBhdGhEYXRhW2ldLnBvaW50LnksIEZYUFRfTU9WRVRPKTsNCi0JCQlicmVhazsNCi0JCWNhc2UgUFdMUFRfTElORVRPOg0KLQkJCXBhdGguU2V0UG9pbnQoaSwgcFBhdGhEYXRhW2ldLnBvaW50LngsIHBQYXRoRGF0YVtpXS5wb2ludC55LCBGWFBUX0xJTkVUTyk7DQotCQkJYnJlYWs7DQotCQljYXNlIFBXTFBUX0JFWklFUlRPOg0KLQkJCXBhdGguU2V0UG9pbnQoaSwgcFBhdGhEYXRhW2ldLnBvaW50LngsIHBQYXRoRGF0YVtpXS5wb2ludC55LCBGWFBUX0JFWklFUlRPKTsNCi0JCQlicmVhazsNCi0JCWRlZmF1bHQ6DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi19DQotDQotDQotQ1BERl9SZWN0IENQV0xfVXRpbHM6Ok1heFJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdDEsY29uc3QgQ1BERl9SZWN0ICYgcmVjdDIpDQotew0KLQlDUERGX1JlY3QgcmNSZXQ7DQotDQotCXJjUmV0LmxlZnQgPSBQV0xfTUlOKHJlY3QxLmxlZnQscmVjdDIubGVmdCk7DQotCXJjUmV0LmJvdHRvbSA9IFBXTF9NSU4ocmVjdDEuYm90dG9tLHJlY3QyLmJvdHRvbSk7DQotCXJjUmV0LnJpZ2h0ID0gUFdMX01BWChyZWN0MS5yaWdodCxyZWN0Mi5yaWdodCk7DQotCXJjUmV0LnRvcCA9IFBXTF9NQVgocmVjdDEudG9wLHJlY3QyLnRvcCk7DQotDQotCXJldHVybiByY1JldDsNCi19DQotDQotQ1BERl9SZWN0IENQV0xfVXRpbHM6Ok9mZnNldFJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCxGWF9GTE9BVCB4LEZYX0ZMT0FUIHkpDQotew0KLQlyZXR1cm4gQ1BERl9SZWN0KHJlY3QubGVmdCArIHgscmVjdC5ib3R0b20gKyB5LA0KLQkJcmVjdC5yaWdodCArIHgscmVjdC50b3AgKyB5KTsNCi19DQotDQotRlhfQk9PTCBDUFdMX1V0aWxzOjpDb250YWluc1JlY3QoY29uc3QgQ1BERl9SZWN0JiByY1BhcmVudCwgY29uc3QgQ1BERl9SZWN0JiByY0NoaWxkKQ0KLXsNCi0JcmV0dXJuIHJjQ2hpbGQubGVmdCA+PSByY1BhcmVudC5sZWZ0ICYmIHJjQ2hpbGQuYm90dG9tID49IHJjUGFyZW50LmJvdHRvbSAmJg0KLQkJCXJjQ2hpbGQucmlnaHQgPD0gcmNQYXJlbnQucmlnaHQgJiYgcmNDaGlsZC50b3AgPD0gcmNQYXJlbnQudG9wOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfVXRpbHM6OkludGVyc2VjdFJlY3QoY29uc3QgQ1BERl9SZWN0JiByZWN0MSwgY29uc3QgQ1BERl9SZWN0JiByZWN0MikNCi17DQotCUZYX0ZMT0FUIGxlZnQgPSByZWN0MS5sZWZ0ID4gcmVjdDIubGVmdCA/IHJlY3QxLmxlZnQgOiByZWN0Mi5sZWZ0Ow0KLQlGWF9GTE9BVCByaWdodCA9IHJlY3QxLnJpZ2h0IDwgcmVjdDIucmlnaHQgPyByZWN0MS5yaWdodCA6IHJlY3QyLnJpZ2h0Ow0KLQlGWF9GTE9BVCBib3R0b20gPSByZWN0MS5ib3R0b20gPiByZWN0Mi5ib3R0b20gPyByZWN0MS5ib3R0b20gOiByZWN0Mi5ib3R0b207DQotCUZYX0ZMT0FUIHRvcCA9IHJlY3QxLnRvcCA8IHJlY3QyLnRvcCA/IHJlY3QxLnRvcCA6IHJlY3QyLnRvcDsNCi0NCi0JcmV0dXJuIGxlZnQgPCByaWdodCAmJiBib3R0b20gPCB0b3A7DQotfQ0KLQ0KLUNQREZfUG9pbnQgQ1BXTF9VdGlsczo6T2Zmc2V0UG9pbnQoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsRlhfRkxPQVQgeCxGWF9GTE9BVCB5KQ0KLXsNCi0JcmV0dXJuIENQREZfUG9pbnQocG9pbnQueCArIHgscG9pbnQueSArIHkpOw0KLX0NCi0NCi1DUFZUX1dvcmRSYW5nZSBDUFdMX1V0aWxzOjpPdmVybGFwV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IxLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyMikNCi17DQotCUNQVlRfV29yZFJhbmdlIHdyUmV0Ow0KLQ0KLQlpZiAod3IyLkVuZFBvcy5Xb3JkQ21wKHdyMS5CZWdpblBvcykgPCAwIHx8IHdyMi5CZWdpblBvcy5Xb3JkQ21wKHdyMS5FbmRQb3MpID4gMCkgcmV0dXJuIHdyUmV0Ow0KLQlpZiAod3IxLkVuZFBvcy5Xb3JkQ21wKHdyMi5CZWdpblBvcykgPCAwIHx8IHdyMS5CZWdpblBvcy5Xb3JkQ21wKHdyMi5FbmRQb3MpID4gMCkgcmV0dXJuIHdyUmV0Ow0KLQ0KLQlpZiAod3IxLkJlZ2luUG9zLldvcmRDbXAod3IyLkJlZ2luUG9zKSA8IDApDQotCXsNCi0JCXdyUmV0LkJlZ2luUG9zID0gd3IyLkJlZ2luUG9zOw0KLQl9DQotCWVsc2UNCi0Jew0KLQkJd3JSZXQuQmVnaW5Qb3MgPSB3cjEuQmVnaW5Qb3M7DQotCX0NCi0NCi0JaWYgKHdyMS5FbmRQb3MuV29yZENtcCh3cjIuRW5kUG9zKSA8IDApDQotCXsNCi0JCXdyUmV0LkVuZFBvcyA9IHdyMS5FbmRQb3M7DQotCX0NCi0JZWxzZQ0KLQl7DQotCQl3clJldC5FbmRQb3MgPSB3cjIuRW5kUG9zOw0KLQl9DQotDQotCXJldHVybiB3clJldDsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfQ2hlY2soY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIGNzQVA7DQotDQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCWNvbnN0IEZYX0lOVDMyIG51bSA9IDg7DQotDQotCUNQV0xfUG9pbnQgcHRzW251bSozXSA9IA0KLQl7DQotCQkvLzENCi0JCUNQV0xfUG9pbnQoMC4yOGYsIDAuNTJmKSwgDQotCQlDUFdMX1BvaW50KDAuMjdmLCAwLjQ4ZiksDQotCQlDUFdMX1BvaW50KDAuMjlmLCAwLjQwZiksDQotDQotCQkvLzINCi0JCUNQV0xfUG9pbnQoMC4zMGYsIDAuMzNmKSwgDQotCQlDUFdMX1BvaW50KDAuMzFmLCAwLjI5ZiksDQotCQlDUFdMX1BvaW50KDAuMzFmLCAwLjI4ZiksDQotDQotCQkvLzMNCi0JCUNQV0xfUG9pbnQoMC4zOWYsIDAuMjhmKSwgDQotCQlDUFdMX1BvaW50KDAuNDlmLCAwLjI5ZiksDQotCQlDUFdMX1BvaW50KDAuNzdmLCAwLjY3ZiksDQotDQotCQkvLzQNCi0JCUNQV0xfUG9pbnQoMC43NmYsIDAuNjhmKSwgDQotCQlDUFdMX1BvaW50KDAuNzhmLCAwLjY5ZiksDQotCQlDUFdMX1BvaW50KDAuNzZmLCAwLjc1ZiksDQotDQotCQkvLzUNCi0JCUNQV0xfUG9pbnQoMC43NmYsIDAuNzVmKSwgDQotCQlDUFdMX1BvaW50KDAuNzNmLCAwLjgwZiksDQotCQlDUFdMX1BvaW50KDAuNjhmLCAwLjc1ZiksDQotDQotCQkvLzYNCi0JCUNQV0xfUG9pbnQoMC42OGYsIDAuNzRmKSwgDQotCQlDUFdMX1BvaW50KDAuNjhmLCAwLjc0ZiksDQotCQlDUFdMX1BvaW50KDAuNDRmLCAwLjQ3ZiksDQotDQotCQkvLzcNCi0JCUNQV0xfUG9pbnQoMC40M2YsIDAuNDdmKSwgDQotCQlDUFdMX1BvaW50KDAuNDBmLCAwLjQ3ZiksDQotCQlDUFdMX1BvaW50KDAuNDFmLCAwLjU4ZiksDQotDQotCQkvLzgNCi0JCUNQV0xfUG9pbnQoMC40MGYsIDAuNjBmKSwgDQotCQlDUFdMX1BvaW50KDAuMjhmLCAwLjY2ZiksDQotCQlDUFdMX1BvaW50KDAuMzBmLCAwLjU2ZikNCi0JfTsNCi0NCi0JZm9yIChGWF9JTlQzMiBqPTA7IGo8bnVtKjM7IGorKykNCi0Jew0KLQkJcHRzW2pdLnggKj0gZldpZHRoOw0KLQkJcHRzW2pdLnggKz0gY3JCQm94LmxlZnQ7DQotDQotCQlwdHNbal0ueSAqPSBmSGVpZ2h0Ow0KLQkJcHRzW2pdLnkgKz0gY3JCQm94LmJvdHRvbTsNCi0JfQ0KLQ0KLQljc0FQIDw8IHB0c1swXS54IDw8ICIgIiA8PCBwdHNbMF0ueSA8PCAiIG1cbiI7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wOyBpPG51bTsgaSsrKQ0KLQl7DQotCQlGWF9JTlQzMiBuQ3VyID0gaSozOw0KLQkJRlhfSU5UMzIgbjEgPSBpKjMgKyAxOw0KLQkJRlhfSU5UMzIgbjIgPSBpKjMgKyAyOw0KLQkJRlhfSU5UMzIgbk5leHQgPSAoaSA8IG51bS0xID8gKGkrMSkqMyA6IDApOw0KLQ0KLQkJRlhfRkxPQVQgcHgxID0gcHRzW24xXS54IC0gcHRzW25DdXJdLng7DQotCQlGWF9GTE9BVCBweTEgPSBwdHNbbjFdLnkgLSBwdHNbbkN1cl0ueTsNCi0JCUZYX0ZMT0FUIHB4MiA9IHB0c1tuMl0ueCAtIHB0c1tuTmV4dF0ueDsNCi0JCUZYX0ZMT0FUIHB5MiA9IHB0c1tuMl0ueSAtIHB0c1tuTmV4dF0ueTsNCi0NCi0JCWNzQVAgPDwgcHRzW25DdXJdLnggKyBweDEgKiBQV0xfQkVaSUVSIDw8ICIgIiA8PCBwdHNbbkN1cl0ueSArIHB5MSAqIFBXTF9CRVpJRVIgPDwgIiAiIA0KLQkJCTw8IHB0c1tuTmV4dF0ueCArIHB4MiAqIFBXTF9CRVpJRVIgPDwgIiAiIDw8IHB0c1tuTmV4dF0ueSArIHB5MiAqIFBXTF9CRVpJRVIgPDwgIiAiDQotCQkJPDwgcHRzW25OZXh0XS54IDw8ICIgIiA8PCBwdHNbbk5leHRdLnkgPDwgIiBjXG4iOw0KLQl9DQotDQotCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfQ2lyY2xlKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCkNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBjc0FQOw0KLQ0KLQlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOw0KLQ0KLQlDUERGX1BvaW50IHB0MShjckJCb3gubGVmdCxjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDIpOw0KLQlDUERGX1BvaW50IHB0MihjckJCb3gubGVmdCArIGZXaWR0aCAvIDIsY3JCQm94LnRvcCk7DQotCUNQREZfUG9pbnQgcHQzKGNyQkJveC5yaWdodCxjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDIpOw0KLQlDUERGX1BvaW50IHB0NChjckJCb3gubGVmdCArIGZXaWR0aCAvIDIsY3JCQm94LmJvdHRvbSk7DQotDQotCWNzQVAgPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsNCi0NCi0JRlhfRkxPQVQgcHggPSBwdDIueCAtIHB0MS54Ow0KLQlGWF9GTE9BVCBweSA9IHB0Mi55IC0gcHQxLnk7DQotDQotCWNzQVAgPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55ICsgcHkgKiBQV0xfQkVaSUVSIDw8ICIgIiANCi0JCTw8IHB0Mi54IC0gcHggKiBQV0xfQkVaSUVSIDw8ICIgIiA8PCBwdDIueSA8PCAiICINCi0JCTw8IHB0Mi54IDw8ICIgIiA8PCBwdDIueSA8PCAiIGNcbiI7DQotDQotCXB4ID0gcHQzLnggLSBwdDIueDsNCi0JcHkgPSBwdDIueSAtIHB0My55Ow0KLQ0KLQljc0FQIDw8IHB0Mi54ICsgcHggKiBQV0xfQkVaSUVSIDw8ICIgIiA8PCBwdDIueSA8PCAiICIgDQotCQk8PCBwdDMueCA8PCAiICIgPDwgcHQzLnkgKyBweSAqIFBXTF9CRVpJRVIgPDwgIiAiDQotCQk8PCBwdDMueCA8PCAiICIgPDwgcHQzLnkgPDwgIiBjXG4iOw0KLQ0KLQlweCA9IHB0My54IC0gcHQ0Lng7DQotCXB5ID0gcHQzLnkgLSBwdDQueTsNCi0NCi0JY3NBUCA8PCBwdDMueCA8PCAiICIgPDwgcHQzLnkgLSBweSAqIFBXTF9CRVpJRVIgPDwgIiAiIA0KLQkJPDwgcHQ0LnggKyBweCAqIFBXTF9CRVpJRVIgPDwgIiAiIDw8IHB0NC55IDw8ICIgIg0KLQkJPDwgcHQ0LnggPDwgIiAiIDw8IHB0NC55IDw8ICIgY1xuIjsNCi0NCi0JcHggPSBwdDQueCAtIHB0MS54Ow0KLQlweSA9IHB0MS55IC0gcHQ0Lnk7DQotDQotCWNzQVAgPDwgcHQ0LnggLSBweCAqIFBXTF9CRVpJRVIgPDwgIiAiIDw8IHB0NC55IDw8ICIgIiANCi0JCTw8IHB0MS54IDw8ICIgIiA8PCBwdDEueSAtIHB5ICogUFdMX0JFWklFUiA8PCAiICINCi0JCTw8IHB0MS54IDw8ICIgIiA8PCBwdDEueSA8PCAiIGNcbiI7DQotDQotCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfQ3Jvc3MoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIGNzQVA7DQotDQotCWNzQVAgPDwgY3JCQm94LmxlZnQgPDwgIiAiIDw8IGNyQkJveC50b3AgPDwgIiBtXG4iOw0KLQljc0FQIDw8IGNyQkJveC5yaWdodCA8PCAiICIgPDwgY3JCQm94LmJvdHRvbSA8PCAiIGxcbiI7DQotCWNzQVAgPDwgY3JCQm94LmxlZnQgPDwgIiAiIDw8IGNyQkJveC5ib3R0b20gPDwgIiBtXG4iOw0KLQljc0FQIDw8IGNyQkJveC5yaWdodCA8PCAiICIgPDwgY3JCQm94LnRvcCA8PCAiIGxcbiI7DQotDQotCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfRGlhbW9uZChjb25zdCBDUERGX1JlY3QgJiBjckJCb3gpDQotew0KLQlDRlhfQnl0ZVRleHRCdWYgY3NBUDsNCi0NCi0JRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7DQotCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsNCi0NCi0JQ1BERl9Qb2ludCBwdDEoY3JCQm94LmxlZnQsY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgLyAyKTsNCi0JQ1BERl9Qb2ludCBwdDIoY3JCQm94LmxlZnQgKyBmV2lkdGggLyAyLGNyQkJveC50b3ApOw0KLQlDUERGX1BvaW50IHB0MyhjckJCb3gucmlnaHQsY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgLyAyKTsNCi0JQ1BERl9Qb2ludCBwdDQoY3JCQm94LmxlZnQgKyBmV2lkdGggLyAyLGNyQkJveC5ib3R0b20pOw0KLQkNCi0JY3NBUCA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBtXG4iOw0KLQljc0FQIDw8IHB0Mi54IDw8ICIgIiA8PCBwdDIueSA8PCAiIGxcbiI7DQotCWNzQVAgPDwgcHQzLnggPDwgIiAiIDw8IHB0My55IDw8ICIgbFxuIjsNCi0JY3NBUCA8PCBwdDQueCA8PCAiICIgPDwgcHQ0LnkgPDwgIiBsXG4iOw0KLQljc0FQIDw8IHB0MS54IDw8ICIgIiA8PCBwdDEueSA8PCAiIGxcbiI7DQotDQotCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfU3F1YXJlKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCkNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBjc0FQOw0KLQ0KLQljc0FQIDw8IGNyQkJveC5sZWZ0IDw8ICIgIiA8PCBjckJCb3gudG9wIDw8ICIgbVxuIjsNCi0JY3NBUCA8PCBjckJCb3gucmlnaHQgPDwgIiAiIDw8IGNyQkJveC50b3AgPDwgIiBsXG4iOw0KLQljc0FQIDw8IGNyQkJveC5yaWdodCA8PCAiICIgPDwgY3JCQm94LmJvdHRvbSA8PCAiIGxcbiI7DQotCWNzQVAgPDwgY3JCQm94LmxlZnQgPDwgIiAiIDw8IGNyQkJveC5ib3R0b20gPDwgIiBsXG4iOw0KLQljc0FQIDw8IGNyQkJveC5sZWZ0IDw8ICIgIiA8PCBjckJCb3gudG9wIDw8ICIgbFxuIjsNCi0NCi0JcmV0dXJuIGNzQVAuR2V0Qnl0ZVN0cmluZygpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRBUF9TdGFyKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCkNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBjc0FQOw0KLQ0KLQlGWF9GTE9BVCBmUmFkaXVzID0gKGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tKS8oMSsoRlhfRkxPQVQpY29zKFBXTF9QSS81LjBmKSk7DQotCUNQREZfUG9pbnQgcHRDZW50ZXIgPSBDUERGX1BvaW50KChjckJCb3gubGVmdCArIGNyQkJveC5yaWdodCkgLyAyLjBmLChjckJCb3gudG9wICsgY3JCQm94LmJvdHRvbSkgLyAyLjBmKTsNCi0JDQotCUZYX0ZMT0FUIHB4WzVdLHB5WzVdOw0KLQ0KLQlGWF9GTE9BVCBmQW5nZWwgPSBQV0xfUEkvMTAuMGY7DQotDQotCWZvciAoRlhfSU5UMzIgaT0wOyBpPDU7IGkrKykNCi0Jew0KLQkJcHhbaV0gPSBwdENlbnRlci54ICsgZlJhZGl1cyAqIChGWF9GTE9BVCljb3MoZkFuZ2VsKTsNCi0JCXB5W2ldID0gcHRDZW50ZXIueSArIGZSYWRpdXMgKiAoRlhfRkxPQVQpc2luKGZBbmdlbCk7DQotDQotCQlmQW5nZWwgKz0gUFdMX1BJICogMiAvIDUuMGY7DQotCX0NCi0NCi0JY3NBUCA8PCBweFswXSA8PCAiICIgPDwgcHlbMF0gPDwgIiBtXG4iOw0KLQ0KLQlGWF9JTlQzMiBuTmV4dCA9IDA7DQotCWZvciAoRlhfSU5UMzIgaj0wOyBqPDU7IGorKykNCi0Jew0KLQkJbk5leHQgKz0gMjsNCi0JCWlmIChuTmV4dCA+PSA1KSBuTmV4dCAtPSA1Ow0KLQkJY3NBUCA8PCBweFtuTmV4dF0gPDwgIiAiIDw8IHB5W25OZXh0XSA8PCAiIGxcbiI7DQotCX0NCi0NCi0JcmV0dXJuIGNzQVAuR2V0Qnl0ZVN0cmluZygpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRBUF9IYWxmQ2lyY2xlKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCxGWF9GTE9BVCBmUm90YXRlKQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIGNzQVA7DQotDQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCUNQREZfUG9pbnQgcHQxKC1mV2lkdGgvMiwwKTsNCi0JQ1BERl9Qb2ludCBwdDIoMCxmSGVpZ2h0LzIpOw0KLQlDUERGX1BvaW50IHB0MyhmV2lkdGgvMiwwKTsNCi0NCi0JRlhfRkxPQVQgcHgscHk7DQotDQotCWNzQVAgPDwgY29zKGZSb3RhdGUpIDw8ICIgIiA8PCBzaW4oZlJvdGF0ZSkgPDwgIiAiIDw8IC1zaW4oZlJvdGF0ZSkgPDwgIiAiIDw8IGNvcyhmUm90YXRlKSA8PCAiICIgDQotCQk8PCBjckJCb3gubGVmdCArIGZXaWR0aCAvIDIgPDwgIiAiIDw8IGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0IC8gMiA8PCAiIGNtXG4iOw0KLQ0KLQ0KLQljc0FQIDw8IHB0MS54IDw8ICIgIiA8PCBwdDEueSA8PCAiIG1cbiI7DQotDQotCXB4ID0gcHQyLnggLSBwdDEueDsNCi0JcHkgPSBwdDIueSAtIHB0MS55Ow0KLQ0KLQljc0FQIDw8IHB0MS54IDw8ICIgIiA8PCBwdDEueSArIHB5ICogUFdMX0JFWklFUiA8PCAiICIgDQotCQk8PCBwdDIueCAtIHB4ICogUFdMX0JFWklFUiA8PCAiICIgPDwgcHQyLnkgPDwgIiAiDQotCQk8PCBwdDIueCA8PCAiICIgPDwgcHQyLnkgPDwgIiBjXG4iOw0KLQ0KLQlweCA9IHB0My54IC0gcHQyLng7DQotCXB5ID0gcHQyLnkgLSBwdDMueTsNCi0NCi0JY3NBUCA8PCBwdDIueCArIHB4ICogUFdMX0JFWklFUiA8PCAiICIgPDwgcHQyLnkgPDwgIiAiIA0KLQkJPDwgcHQzLnggPDwgIiAiIDw8IHB0My55ICsgcHkgKiBQV0xfQkVaSUVSIDw8ICIgIg0KLQkJPDwgcHQzLnggPDwgIiAiIDw8IHB0My55IDw8ICIgY1xuIjsNCi0NCi0JcmV0dXJuIGNzQVAuR2V0Qnl0ZVN0cmluZygpOw0KLX0NCi0NCi0NCi1DUERGX1JlY3QgQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmNSZWN0LCBGWF9GTE9BVCBmU2l6ZSkNCi17DQotCWlmIChyY1JlY3QuSXNFbXB0eSgpKSByZXR1cm4gcmNSZWN0Ow0KLQ0KLQlDUERGX1JlY3QgcmNOZXcocmNSZWN0LmxlZnQgLSBmU2l6ZSwNCi0JCQkJCXJjUmVjdC5ib3R0b20gLSBmU2l6ZSwNCi0JCQkJCXJjUmVjdC5yaWdodCArIGZTaXplLA0KLQkJCQkJcmNSZWN0LnRvcCArIGZTaXplKTsNCi0JcmNOZXcuTm9ybWFsaXplKCk7DQotCXJldHVybiByY05ldzsNCi19DQotDQotQ1BERl9SZWN0IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJjUmVjdCwgRlhfRkxPQVQgZlNpemUpDQotew0KLQlpZiAocmNSZWN0LklzRW1wdHkoKSkgcmV0dXJuIHJjUmVjdDsNCi0NCi0JQ1BERl9SZWN0IHJjTmV3KHJjUmVjdC5sZWZ0ICsgZlNpemUsDQotCQkJCQlyY1JlY3QuYm90dG9tICsgZlNpemUsDQotCQkJCQlyY1JlY3QucmlnaHQgLSBmU2l6ZSwNCi0JCQkJCXJjUmVjdC50b3AgLSBmU2l6ZSk7DQotCXJjTmV3Lk5vcm1hbGl6ZSgpOw0KLQlyZXR1cm4gcmNOZXc7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX1V0aWxzOjpTY2FsZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmNSZWN0LEZYX0ZMT0FUIGZTY2FsZSkNCi17DQotCUZYX0ZMT0FUIGZIYWxmV2lkdGggPSAocmNSZWN0LnJpZ2h0IC0gcmNSZWN0LmxlZnQpIC8gMi4wZjsNCi0JRlhfRkxPQVQgZkhhbGZIZWlnaHQgPSAocmNSZWN0LnRvcCAtIHJjUmVjdC5ib3R0b20pIC8gMi4wZjsNCi0NCi0JQ1BERl9Qb2ludCBwdENlbnRlciA9IENQREZfUG9pbnQoKHJjUmVjdC5sZWZ0ICsgcmNSZWN0LnJpZ2h0KSAvIDIsKHJjUmVjdC50b3AgKyByY1JlY3QuYm90dG9tKSAvIDIpOw0KLQ0KLQlyZXR1cm4gQ1BERl9SZWN0KHB0Q2VudGVyLnggLSBmSGFsZldpZHRoICogZlNjYWxlLA0KLQkJCQlwdENlbnRlci55IC0gZkhhbGZIZWlnaHQgKiBmU2NhbGUsDQotCQkJCXB0Q2VudGVyLnggKyBmSGFsZldpZHRoICogZlNjYWxlLA0KLQkJCQlwdENlbnRlci55ICsgZkhhbGZIZWlnaHQgKiBmU2NhbGUpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRSZWN0RmlsbEFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByZWN0LGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcikNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBzQXBwU3RyZWFtOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBzQ29sb3IgPSBHZXRDb2xvckFwcFN0cmVhbShjb2xvcixUUlVFKTsNCi0JaWYgKHNDb2xvci5HZXRMZW5ndGgoKSA+IDApDQotCXsNCi0JCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgc0NvbG9yOw0KLQkJc0FwcFN0cmVhbSA8PCByZWN0LmxlZnQgPDwgIiAiIDw8IHJlY3QuYm90dG9tIDw8ICIgIg0KLQkJCTw8IHJlY3QucmlnaHQgLSByZWN0LmxlZnQgPDwgIiAiIDw8IHJlY3QudG9wIC0gcmVjdC5ib3R0b20gPDwgIiByZSBmXG5RXG4iOwkJDQotCX0NCi0JDQotCXJldHVybiBzQXBwU3RyZWFtLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0Q2lyY2xlRmlsbEFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByZWN0LGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcikNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBzQXBwU3RyZWFtOw0KLQ0KLQlDRlhfQnl0ZVN0cmluZyBzQ29sb3IgPSBHZXRDb2xvckFwcFN0cmVhbShjb2xvcixUUlVFKTsNCi0JaWYgKHNDb2xvci5HZXRMZW5ndGgoKSA+IDApDQotCXsNCi0JCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0NpcmNsZShyZWN0KSA8PCAiZlxuUVxuIjsJCQ0KLQl9DQotCQ0KLQlyZXR1cm4gc0FwcFN0cmVhbS5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX1V0aWxzOjpHZXRDZW50ZXJTcXVhcmUoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkNCi17DQotCUZYX0ZMT0FUIGZXaWR0aCA9IHJlY3QucmlnaHQgLSAgcmVjdC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gcmVjdC50b3AgLSByZWN0LmJvdHRvbTsNCi0NCi0JRlhfRkxPQVQgZkNlbnRlclggPSAocmVjdC5sZWZ0ICsgcmVjdC5yaWdodCkvMi4wZjsNCi0JRlhfRkxPQVQgZkNlbnRlclkgPSAocmVjdC50b3AgKyByZWN0LmJvdHRvbSkvMi4wZjsNCi0NCi0JRlhfRkxPQVQgZlJhZGl1cyA9IChmV2lkdGggPiBmSGVpZ2h0KSA/IGZIZWlnaHQgLyAyIDogZldpZHRoIC8gMjsNCi0NCi0JcmV0dXJuIENQREZfUmVjdChmQ2VudGVyWCAtIGZSYWRpdXMsZkNlbnRlclkgLSBmUmFkaXVzLGZDZW50ZXJYICsgZlJhZGl1cyxmQ2VudGVyWSArIGZSYWRpdXMpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRFZGl0QXBwU3RyZWFtKElGWF9FZGl0KiBwRWRpdCwgY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSAqIHBSYW5nZSwgDQotCQkJCQkJCQkJCQkJCQlGWF9CT09MIGJDb250aW51b3VzLCBGWF9XT1JEIFN1YldvcmQpDQotew0KLQlyZXR1cm4gSUZYX0VkaXQ6OkdldEVkaXRBcHBlYXJhbmNlU3RyZWFtKHBFZGl0LHB0T2Zmc2V0LHBSYW5nZSxiQ29udGludW91cyxTdWJXb3JkKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0RWRpdFNlbEFwcFN0cmVhbShJRlhfRWRpdCogcEVkaXQsIGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCwgDQotCQkJCQkJCQljb25zdCBDUFZUX1dvcmRSYW5nZSAqIHBSYW5nZSkNCi17DQotCXJldHVybiBJRlhfRWRpdDo6R2V0U2VsZWN0QXBwZWFyYW5jZVN0cmVhbShwRWRpdCxwdE9mZnNldCxwUmFuZ2UpOw0KLX0NCi0NCi1zdGF0aWMgQ0ZYX0J5dGVTdHJpbmcgR2V0U3F1aWdnbHlBcHBlYXJhbmNlU3RyZWFtKEZYX0ZMT0FUIGZTdGFydFgsIEZYX0ZMT0FUIGZFbmRYLCBGWF9GTE9BVCBmWSwgRlhfRkxPQVQgZlN0ZXApDQotew0KLQlDRlhfQnl0ZVRleHRCdWYgc1JldDsNCi0NCi0Jc1JldCA8PCAiMCB3XG4iIDw8IGZTdGFydFggPDwgIiAiIDw8IGZZIDw8ICIgbVxuIjsNCi0NCi0JRlhfRkxPQVQgZng7DQotCUZYX0lOVDMyIGk7DQotDQotCWZvciAoaT0xLGZ4PWZTdGFydFgrZlN0ZXA7IGZ4PGZFbmRYOyBmeCs9ZlN0ZXAsaSsrKQ0KLQl7DQotCQlzUmV0IDw8IGZ4IDw8ICIgIiA8PCBmWSArIChpJjEpKmZTdGVwIDw8ICIgbFxuIjsNCi0JfQ0KLQ0KLQlzUmV0IDw8ICJTXG4iOw0KLQ0KLQlyZXR1cm4gc1JldC5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLXN0YXRpYyBDRlhfQnl0ZVN0cmluZyBHZXRXb3JkU3BlbGxDaGVja0FwcGVhcmFuY2VTdHJlYW0oSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciwgY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0LA0KLQkJCQkJCQkJCQkJCQkJCQkgIGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3JXb3JkKQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNSZXQ7DQotDQotCUZYX0ZMT0FUIGZTdGFydFggPSAwLjBmOw0KLQlGWF9GTE9BVCBmRW5kWCA9IDAuMGY7DQotCUZYX0ZMT0FUIGZZID0gMC4wZjsNCi0JRlhfRkxPQVQgZlN0ZXAgPSAwLjBmOyANCi0NCi0JRlhfQk9PTCBiQnJlYWsgPSBGQUxTRTsNCi0NCi0JaWYgKHBJdGVyYXRvcikNCi0Jew0KLQkJcEl0ZXJhdG9yLT5TZXRBdCh3cldvcmQuQmVnaW5Qb3MpOw0KLQ0KLQkJZG8NCi0JCXsNCi0JCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsNCi0NCi0JCQlDUFZUX0xpbmUgbGluZTsJCQkJDQotCQkJaWYgKHBJdGVyYXRvci0+R2V0TGluZShsaW5lKSkNCi0JCQl7DQotCQkJCWZZID0gbGluZS5wdExpbmUueTsNCi0JCQkJZlN0ZXAgPSAobGluZS5mTGluZUFzY2VudCAtIGxpbmUuZkxpbmVEZXNjZW50KSAvIDE2LjBmOw0KLQkJCX0NCi0NCi0JCQlpZiAocGxhY2UuTGluZUNtcCh3cldvcmQuQmVnaW5Qb3MpID09IDApDQotCQkJew0KLQkJCQlwSXRlcmF0b3ItPlNldEF0KHdyV29yZC5CZWdpblBvcyk7DQotCQkJCUNQVlRfV29yZCB3b3JkOw0KLQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQ0KLQkJCQl7DQotCQkJCQlmU3RhcnRYID0gd29yZC5wdFdvcmQueDsNCi0JCQkJfQ0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlmU3RhcnRYID0gbGluZS5wdExpbmUueDsNCi0JCQl9DQotDQotCQkJaWYgKHBsYWNlLkxpbmVDbXAod3JXb3JkLkVuZFBvcykgPT0gMCkNCi0JCQl7DQotCQkJCXBJdGVyYXRvci0+U2V0QXQod3JXb3JkLkVuZFBvcyk7DQotCQkJCUNQVlRfV29yZCB3b3JkOw0KLQkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQ0KLQkJCQl7DQotCQkJCQlmRW5kWCA9IHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aDsNCi0JCQkJfQ0KLQ0KLQkJCQliQnJlYWsgPSBUUlVFOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQlmRW5kWCA9IGxpbmUucHRMaW5lLnggKyBsaW5lLmZMaW5lV2lkdGg7DQotCQkJfQ0KLQ0KLQkJCXNSZXQgPDwgR2V0U3F1aWdnbHlBcHBlYXJhbmNlU3RyZWFtKGZTdGFydFggKyBwdE9mZnNldC54LCBmRW5kWCArIHB0T2Zmc2V0LngsIGZZICsgcHRPZmZzZXQueSxmU3RlcCk7DQotDQotCQkJaWYgKGJCcmVhaykgYnJlYWs7DQotCQl9DQotCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0TGluZSgpKTsNCi0JfQ0KLQ0KLQlyZXR1cm4gc1JldC5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldFNwZWxsQ2hlY2tBcHBTdHJlYW0oSUZYX0VkaXQqIHBFZGl0LCBJUFdMX1NwZWxsQ2hlY2sqIHBTcGVsbENoZWNrLCBjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQsDQotCQkJCQkJCQljb25zdCBDUFZUX1dvcmRSYW5nZSAqIHBSYW5nZSkNCi17DQotCUFTU0VSVChwRWRpdCAhPSBOVUxMKTsNCi0JQVNTRVJUKHBTcGVsbENoZWNrICE9IE5VTEwpOw0KLQ0KLQlDRlhfQnl0ZVRleHRCdWYgc1JldDsNCi0NCi0JaWYgKHBSYW5nZSAmJiBwUmFuZ2UtPklzRXhpc3QoKSkNCi0Jew0KLQkJaWYgKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBwRWRpdC0+R2V0SXRlcmF0b3IoKSkNCi0JCXsNCi0JCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOw0KLQ0KLQkJCUZYX0JPT0wgYkxhdGluV29yZCA9IEZBTFNFOw0KLQkJCUNQVlRfV29yZFBsYWNlIHdwV29yZFN0YXJ0Ow0KLQkJCUNGWF9CeXRlU3RyaW5nIHNXb3JkOw0KLQ0KLQkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlOw0KLQkJCXdoaWxlIChwSXRlcmF0b3ItPk5leHRXb3JkKCkpDQotCQkJew0KLQkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsNCi0JCQkJaWYgKHBSYW5nZSAmJiBwbGFjZS5Xb3JkQ21wKHBSYW5nZS0+RW5kUG9zKSA+IDApIGJyZWFrOwkJCQkNCi0NCi0JCQkJQ1BWVF9Xb3JkIHdvcmQ7DQotCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpDQotCQkJCXsNCi0JCQkJCWlmIChGWF9FRElUX0lTTEFUSU5XT1JEKHdvcmQuV29yZCkpDQotCQkJCQl7DQotCQkJCQkJaWYgKCFiTGF0aW5Xb3JkKQ0KLQkJCQkJCXsNCi0JCQkJCQkJd3BXb3JkU3RhcnQgPSBwbGFjZTsNCi0JCQkJCQkJYkxhdGluV29yZCA9IFRSVUU7CQkJCQkJCQkNCi0JCQkJCQl9DQotDQotCQkJCQkJc1dvcmQgKz0gKGNoYXIpd29yZC5Xb3JkOw0KLQkJCQkJCW9sZHBsYWNlID0gcGxhY2U7DQotCQkJCQl9DQotCQkJCQllbHNlDQotCQkJCQl7DQotCQkJCQkJaWYgKGJMYXRpbldvcmQpDQotCQkJCQkJew0KLQkJCQkJCQlpZiAoIXBTcGVsbENoZWNrLT5DaGVja1dvcmQoc1dvcmQpKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlzUmV0IDw8IEdldFdvcmRTcGVsbENoZWNrQXBwZWFyYW5jZVN0cmVhbShwSXRlcmF0b3IscHRPZmZzZXQsQ1BWVF9Xb3JkUmFuZ2Uod3BXb3JkU3RhcnQsb2xkcGxhY2UpKTsNCi0JCQkJCQkJCXBJdGVyYXRvci0+U2V0QXQocGxhY2UpOw0KLQkJCQkJCQl9DQotCQkJCQkJCWJMYXRpbldvcmQgPSBGQUxTRTsNCi0JCQkJCQl9DQotDQotCQkJCQkJc1dvcmQuRW1wdHkoKTsNCi0JCQkJCX0NCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsNCi0JCQkJCWlmIChiTGF0aW5Xb3JkKQ0KLQkJCQkJew0KLQkJCQkJCWlmICghcFNwZWxsQ2hlY2stPkNoZWNrV29yZChzV29yZCkpDQotCQkJCQkJCXNSZXQgPDwgR2V0V29yZFNwZWxsQ2hlY2tBcHBlYXJhbmNlU3RyZWFtKHBJdGVyYXRvcixwdE9mZnNldCxDUFZUX1dvcmRSYW5nZSh3cFdvcmRTdGFydCxvbGRwbGFjZSkpOw0KLQkJCQkJCWJMYXRpbldvcmQgPSBGQUxTRTsNCi0JCQkJCQlzV29yZC5FbXB0eSgpOw0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQ0KLQkJCWlmIChiTGF0aW5Xb3JkKQ0KLQkJCXsNCi0JCQkJaWYgKCFwU3BlbGxDaGVjay0+Q2hlY2tXb3JkKHNXb3JkKSkNCi0JCQkJCXNSZXQgPDwgR2V0V29yZFNwZWxsQ2hlY2tBcHBlYXJhbmNlU3RyZWFtKHBJdGVyYXRvcixwdE9mZnNldCxDUFZUX1dvcmRSYW5nZSh3cFdvcmRTdGFydCxvbGRwbGFjZSkpOw0KLQ0KLQkJCQliTGF0aW5Xb3JkID0gRkFMU0U7DQotCQkJCXNXb3JkLkVtcHR5KCk7DQotCQkJfQ0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBzUmV0LkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0VGV4dEFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwLA0KLQkJCQkJCQkJCQkJCQkJY29uc3QgQ0ZYX1dpZGVTdHJpbmcgJiBzVGV4dCwgRlhfSU5UMzIgbkFsaWdubWVudEgsIEZYX0lOVDMyIG5BbGlnbm1lbnRWLA0KLQkJCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkZvbnRTaXplLCBGWF9CT09MIGJNdWx0aUxpbmUsIEZYX0JPT0wgYkF1dG9SZXR1cm4sIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpDQotew0KLQlDRlhfQnl0ZVRleHRCdWYgc1JldDsNCi0NCi0JaWYgKElGWF9FZGl0ICogcEVkaXQgPSBJRlhfRWRpdDo6TmV3RWRpdCgpKQ0KLQl7CQkJDQotCQlwRWRpdC0+U2V0Rm9udE1hcChwRm9udE1hcCk7DQotDQotCQlwRWRpdC0+U2V0UGxhdGVSZWN0KHJjQkJveCk7DQotCQlwRWRpdC0+U2V0QWxpZ25tZW50SChuQWxpZ25tZW50SCk7DQotCQlwRWRpdC0+U2V0QWxpZ25tZW50VihuQWxpZ25tZW50Vik7DQotCQlwRWRpdC0+U2V0TXVsdGlMaW5lKGJNdWx0aUxpbmUpOw0KLQkJcEVkaXQtPlNldEF1dG9SZXR1cm4oYkF1dG9SZXR1cm4pOw0KLQkJaWYgKElzRmxvYXRaZXJvKGZGb250U2l6ZSkpDQotCQkJcEVkaXQtPlNldEF1dG9Gb250U2l6ZShUUlVFKTsNCi0JCWVsc2UNCi0JCQlwRWRpdC0+U2V0Rm9udFNpemUoZkZvbnRTaXplKTsNCi0JCXBFZGl0LT5Jbml0aWFsaXplKCk7DQotDQotCQlwRWRpdC0+U2V0VGV4dChzVGV4dCk7DQotCQkNCi0JCUNGWF9CeXRlU3RyaW5nIHNFZGl0ID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShwRWRpdCwgQ1BERl9Qb2ludCgwLjBmLDAuMGYpKTsNCi0JCWlmIChzRWRpdC5HZXRMZW5ndGgoKSA+IDApDQotCQl7DQotCQkJc1JldCA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JUZXh0KSA8PCBzRWRpdCA8PCAiRVRcbiI7DQotCQl9DQotCQkNCi0JCUlGWF9FZGl0OjpEZWxFZGl0KHBFZGl0KTsNCi0JfQ0KLQ0KLQlyZXR1cm4gc1JldC5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldFB1c2hCdXR0b25BcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LA0KLQkJCQkJCQkJCQkJSUZYX0VkaXRfRm9udE1hcCAqIHBGb250TWFwLA0KLQkJCQkJCQkJCQkJQ1BERl9TdHJlYW0gKiBwSWNvblN0cmVhbSwNCi0JCQkJCQkJCQkJCUNQREZfSWNvbkZpdCAmIEljb25GaXQsDQotCQkJCQkJCQkJCQljb25zdCBDRlhfV2lkZVN0cmluZyAmIHNMYWJlbCwJCQkJCQkJCQkJCQ0KLQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCwNCi0JCQkJCQkJCQkJCUZYX0ZMT0FUIGZGb250U2l6ZSwNCi0JCQkJCQkJCQkJCUZYX0lOVDMyIG5MYXlPdXQpDQotew0KLQljb25zdCBGWF9GTE9BVCBmQXV0b0ZvbnRTY2FsZSA9IDEuMGYgLyAzLjBmOwkNCi0NCi0JaWYgKElGWF9FZGl0ICogcEVkaXQgPSBJRlhfRWRpdDo6TmV3RWRpdCgpKQ0KLQl7CQkJDQotCQlwRWRpdC0+U2V0Rm9udE1hcChwRm9udE1hcCk7DQotDQotCQlwRWRpdC0+U2V0QWxpZ25tZW50SCgxKTsNCi0JCXBFZGl0LT5TZXRBbGlnbm1lbnRWKDEpOw0KLQkJcEVkaXQtPlNldE11bHRpTGluZShGQUxTRSk7DQotCQlwRWRpdC0+U2V0QXV0b1JldHVybihGQUxTRSk7DQotCQlpZiAoSXNGbG9hdFplcm8oZkZvbnRTaXplKSkNCi0JCQlwRWRpdC0+U2V0QXV0b0ZvbnRTaXplKFRSVUUpOw0KLQkJZWxzZQ0KLQkJCXBFZGl0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOw0KLQkJcEVkaXQtPkluaXRpYWxpemUoKTsNCi0JCXBFZGl0LT5TZXRUZXh0KHNMYWJlbCk7DQotDQotCQlDUERGX1JlY3QgcmNMYWJlbENvbnRlbnQgPSBwRWRpdC0+R2V0Q29udGVudFJlY3QoKTsNCi0JCQ0KLQkJQ1BXTF9JY29uIEljb247DQotCQlQV0xfQ1JFQVRFUEFSQU0gY3A7DQotCQljcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEU7DQotCQlJY29uLkNyZWF0ZShjcCk7DQotCQlJY29uLlNldEljb25GaXQoJkljb25GaXQpOw0KLQkJSWNvbi5TZXRQREZTdHJlYW0ocEljb25TdHJlYW0pOw0KLQ0KLQkJQ1BERl9SZWN0IHJjTGFiZWwgPSBDUERGX1JlY3QoMCwwLDAsMCk7DQotCQlDUERGX1JlY3QgcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOw0KLQkJRlhfRkxPQVQgZldpZHRoID0gMC4wZjsNCi0JCUZYX0ZMT0FUIGZIZWlnaHQgPSAwLjBmOw0KLQ0KLQkJc3dpdGNoIChuTGF5T3V0KQ0KLQkJew0KLQkJY2FzZSBQUEJMX0xBQkVMOg0KLQkJCXJjTGFiZWwgPSByY0JCb3g7DQotCQkJcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQUEJMX0lDT046DQotCQkJcmNJY29uID0gcmNCQm94Ow0KLQkJCXJjTGFiZWwgPSBDUERGX1JlY3QoMCwwLDAsMCk7DQotCQkJYnJlYWs7DQotCQljYXNlIFBQQkxfSUNPTlRPUExBQkVMQk9UVE9NOg0KLQ0KLQkJCWlmIChwSWNvblN0cmVhbSkNCi0JCQl7DQotCQkJCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQ0KLQkJCQl7DQotCQkJCQlmSGVpZ2h0ID0gcmNCQm94LnRvcCAtIHJjQkJveC5ib3R0b207DQotCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNCQm94LnJpZ2h0LHJjQkJveC5ib3R0b20gKyBmSGVpZ2h0ICogZkF1dG9Gb250U2NhbGUpOw0KLQkJCQkJcmNJY29uID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjTGFiZWwudG9wLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsNCi0JCQkJCWZIZWlnaHQgPSByY0xhYmVsQ29udGVudC5IZWlnaHQoKTsNCi0NCi0JCQkJCWlmIChyY0JCb3guYm90dG9tICsgZkhlaWdodCA+IHJjQkJveC50b3ApDQotCQkJCQl7CQkJDQotCQkJCQkJcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOwkJCQkNCi0JCQkJCQlyY0xhYmVsID0gcmNCQm94Ow0KLQkJCQkJfQ0KLQkJCQkJZWxzZQ0KLQkJCQkJew0KLQkJCQkJCXJjTGFiZWwgPSBDUERGX1JlY3QocmNCQm94LmxlZnQscmNCQm94LmJvdHRvbSxyY0JCb3gucmlnaHQscmNCQm94LmJvdHRvbSArIGZIZWlnaHQpOw0KLQkJCQkJCXJjSWNvbiA9IENQREZfUmVjdChyY0JCb3gubGVmdCxyY0xhYmVsLnRvcCxyY0JCb3gucmlnaHQscmNCQm94LnRvcCk7CQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJfQ0KLQkJCWVsc2UNCi0JCQl7DQotCQkJCXJjTGFiZWwgPSByY0JCb3g7DQotCQkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsNCi0JCQl9DQotDQotCQkJYnJlYWs7DQotCQljYXNlIFBQQkxfTEFCRUxUT1BJQ09OQk9UVE9NOg0KLQ0KLQkJCWlmIChwSWNvblN0cmVhbSkNCi0JCQl7DQotCQkJCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQ0KLQkJCQl7DQotCQkJCQlmSGVpZ2h0ID0gcmNCQm94LnRvcCAtIHJjQkJveC5ib3R0b207DQotCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC50b3AgLSBmSGVpZ2h0ICogZkF1dG9Gb250U2NhbGUgLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsNCi0JCQkJCXJjSWNvbiA9IENQREZfUmVjdChyY0JCb3gubGVmdCxyY0JCb3guYm90dG9tLHJjQkJveC5yaWdodCxyY0xhYmVsLmJvdHRvbSk7DQotCQkJCX0NCi0JCQkJZWxzZQ0KLQkJCQl7DQotCQkJCQlmSGVpZ2h0ID0gcmNMYWJlbENvbnRlbnQuSGVpZ2h0KCk7DQotDQotCQkJCQlpZiAocmNCQm94LmJvdHRvbSArIGZIZWlnaHQgPiByY0JCb3gudG9wKQ0KLQkJCQkJewkJCQ0KLQkJCQkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsJCQkJDQotCQkJCQkJcmNMYWJlbCA9IHJjQkJveDsNCi0JCQkJCX0NCi0JCQkJCWVsc2UNCi0JCQkJCXsNCi0JCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC50b3AgLSBmSGVpZ2h0LHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsNCi0JCQkJCQlyY0ljb24gPSBDUERGX1JlY3QocmNCQm94LmxlZnQscmNCQm94LmJvdHRvbSxyY0JCb3gucmlnaHQscmNMYWJlbC5ib3R0b20pOwkJDQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJcmNMYWJlbCA9IHJjQkJveDsNCi0JCQkJcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOw0KLQkJCX0NCi0NCi0JCQlicmVhazsNCi0JCWNhc2UgUFBCTF9JQ09OTEVGVExBQkVMUklHSFQ6DQotDQotCQkJaWYgKHBJY29uU3RyZWFtKQ0KLQkJCXsNCi0JCQkJaWYgKElzRmxvYXRaZXJvKGZGb250U2l6ZSkpDQotCQkJCXsNCi0JCQkJCWZXaWR0aCA9IHJjQkJveC5yaWdodCAtIHJjQkJveC5sZWZ0Ow0KLQkJCQkJcmNMYWJlbCA9IENQREZfUmVjdChyY0JCb3gucmlnaHQgLSBmV2lkdGggKiBmQXV0b0ZvbnRTY2FsZSxyY0JCb3guYm90dG9tLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsNCi0JCQkJCXJjSWNvbiA9IENQREZfUmVjdChyY0JCb3gubGVmdCxyY0JCb3guYm90dG9tLHJjTGFiZWwubGVmdCxyY0JCb3gudG9wKTsNCi0NCi0JCQkJCWlmIChyY0xhYmVsQ29udGVudC5XaWR0aCgpIDwgZldpZHRoICogZkF1dG9Gb250U2NhbGUpDQotCQkJCQl7CQkJCQkJCQ0KLQkJCQkJfQ0KLQkJCQkJZWxzZSANCi0JCQkJCXsNCi0JCQkJCQlpZiAocmNMYWJlbENvbnRlbnQuV2lkdGgoKSA8IGZXaWR0aCkNCi0JCQkJCQl7DQotCQkJCQkJCXJjTGFiZWwgPSBDUERGX1JlY3QocmNCQm94LnJpZ2h0IC0gcmNMYWJlbENvbnRlbnQuV2lkdGgoKSxyY0JCb3guYm90dG9tLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsNCi0JCQkJCQkJcmNJY29uID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNMYWJlbC5sZWZ0LHJjQkJveC50b3ApOw0KLQkJCQkJCX0NCi0JCQkJCQllbHNlDQotCQkJCQkJew0KLQkJCQkJCQlyY0xhYmVsID0gcmNCQm94Ow0KLQkJCQkJCQlyY0ljb24gPSBDUERGX1JlY3QoMCwwLDAsMCk7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJZldpZHRoID0gcmNMYWJlbENvbnRlbnQuV2lkdGgoKTsNCi0NCi0JCQkJCWlmIChyY0JCb3gubGVmdCArIGZXaWR0aCA+IHJjQkJveC5yaWdodCkNCi0JCQkJCXsNCi0JCQkJCQlyY0xhYmVsID0gcmNCQm94Ow0KLQkJCQkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsNCi0JCQkJCX0NCi0JCQkJCWVsc2UNCi0JCQkJCXsNCi0JCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5yaWdodCAtIGZXaWR0aCxyY0JCb3guYm90dG9tLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsNCi0JCQkJCQlyY0ljb24gPSBDUERGX1JlY3QocmNCQm94LmxlZnQscmNCQm94LmJvdHRvbSxyY0xhYmVsLmxlZnQscmNCQm94LnRvcCk7CQkJDQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJcmNMYWJlbCA9IHJjQkJveDsNCi0JCQkJcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOw0KLQkJCX0NCi0NCi0JCQlicmVhazsNCi0JCWNhc2UgUFBCTF9MQUJFTExFRlRJQ09OUklHSFQ6DQotDQotCQkJaWYgKHBJY29uU3RyZWFtKQ0KLQkJCXsNCi0JCQkJaWYgKElzRmxvYXRaZXJvKGZGb250U2l6ZSkpDQotCQkJCXsNCi0JCQkJCWZXaWR0aCA9IHJjQkJveC5yaWdodCAtIHJjQkJveC5sZWZ0Ow0KLQkJCQkJcmNMYWJlbCA9IENQREZfUmVjdChyY0JCb3gubGVmdCxyY0JCb3guYm90dG9tLHJjQkJveC5sZWZ0ICsgZldpZHRoICogZkF1dG9Gb250U2NhbGUscmNCQm94LnRvcCk7DQotCQkJCQlyY0ljb24gPSBDUERGX1JlY3QocmNMYWJlbC5yaWdodCxyY0JCb3guYm90dG9tLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsNCi0NCi0JCQkJCWlmIChyY0xhYmVsQ29udGVudC5XaWR0aCgpIDwgZldpZHRoICogZkF1dG9Gb250U2NhbGUpDQotCQkJCQl7CQkJCQkJCQ0KLQkJCQkJfQ0KLQkJCQkJZWxzZSANCi0JCQkJCXsNCi0JCQkJCQlpZiAocmNMYWJlbENvbnRlbnQuV2lkdGgoKSA8IGZXaWR0aCkNCi0JCQkJCQl7DQotCQkJCQkJCXJjTGFiZWwgPSBDUERGX1JlY3QocmNCQm94LmxlZnQscmNCQm94LmJvdHRvbSxyY0JCb3gubGVmdCArIHJjTGFiZWxDb250ZW50LldpZHRoKCkscmNCQm94LnRvcCk7DQotCQkJCQkJCXJjSWNvbiA9IENQREZfUmVjdChyY0xhYmVsLnJpZ2h0LHJjQkJveC5ib3R0b20scmNCQm94LnJpZ2h0LHJjQkJveC50b3ApOw0KLQkJCQkJCX0NCi0JCQkJCQllbHNlDQotCQkJCQkJew0KLQkJCQkJCQlyY0xhYmVsID0gcmNCQm94Ow0KLQkJCQkJCQlyY0ljb24gPSBDUERGX1JlY3QoMCwwLDAsMCk7DQotCQkJCQkJfQ0KLQkJCQkJfQ0KLQkJCQl9DQotCQkJCWVsc2UNCi0JCQkJew0KLQkJCQkJZldpZHRoID0gcmNMYWJlbENvbnRlbnQuV2lkdGgoKTsNCi0NCi0JCQkJCWlmIChyY0JCb3gubGVmdCArIGZXaWR0aCA+IHJjQkJveC5yaWdodCkNCi0JCQkJCXsNCi0JCQkJCQlyY0xhYmVsID0gcmNCQm94Ow0KLQkJCQkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsNCi0JCQkJCX0NCi0JCQkJCWVsc2UNCi0JCQkJCXsNCi0JCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNCQm94LmxlZnQgKyBmV2lkdGgscmNCQm94LnRvcCk7DQotCQkJCQkJcmNJY29uID0gQ1BERl9SZWN0KHJjTGFiZWwucmlnaHQscmNCQm94LmJvdHRvbSxyY0JCb3gucmlnaHQscmNCQm94LnRvcCk7CQkNCi0JCQkJCX0JDQotCQkJCX0NCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJcmNMYWJlbCA9IHJjQkJveDsNCi0JCQkJcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOw0KLQkJCX0NCi0NCi0JCQlicmVhazsNCi0JCWNhc2UgUFBCTF9MQUJFTE9WRVJJQ09OOg0KLQkJCXJjTGFiZWwgPSByY0JCb3g7DQotCQkJcmNJY29uID0gcmNCQm94Ow0KLQkJCWJyZWFrOw0KLQkJfQ0KLQ0KLQkJQ0ZYX0J5dGVUZXh0QnVmIHNBcHBTdHJlYW0sc1RlbXA7DQotDQotCQlpZiAoIXJjSWNvbi5Jc0VtcHR5KCkpDQotCQl7DQotCQkJSWNvbi5Nb3ZlKHJjSWNvbiwgRkFMU0UsIEZBTFNFKTsNCi0JCQlzVGVtcCA8PCBJY29uLkdldEltYWdlQXBwU3RyZWFtKCk7DQotCQl9DQotDQotCQlJY29uLkRlc3Ryb3koKTsNCi0NCi0JCWlmICghcmNMYWJlbC5Jc0VtcHR5KCkpDQotCQl7DQotCQkJcEVkaXQtPlNldFBsYXRlUmVjdChyY0xhYmVsKTsNCi0JCQlDRlhfQnl0ZVN0cmluZyBzRWRpdCA9IENQV0xfVXRpbHM6OkdldEVkaXRBcHBTdHJlYW0ocEVkaXQsQ1BERl9Qb2ludCgwLjBmLDAuMGYpKTsNCi0JCQlpZiAoc0VkaXQuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCXsNCi0JCQkJc1RlbXAgPDwgIkJUXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyVGV4dCkgPDwgc0VkaXQgPDwgIkVUXG4iOw0KLQkJCX0NCi0JCX0NCi0NCi0JCUlGWF9FZGl0OjpEZWxFZGl0KHBFZGl0KTsNCi0NCi0JCWlmIChzVGVtcC5HZXRTaXplKCkgPiAwKQ0KLQkJew0KLQkJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgcmNCQm94LmxlZnQgPDwgIiAiIDw8IHJjQkJveC5ib3R0b20gPDwgIiAiDQotCQkJCTw8IHJjQkJveC5yaWdodCAtIHJjQkJveC5sZWZ0IDw8ICIgIiA8PCByY0JCb3gudG9wIC0gcmNCQm94LmJvdHRvbSA8PCAiIHJlIFcgblxuIjsNCi0JCQlzQXBwU3RyZWFtIDw8IHNUZW1wIDw8ICJRXG4iOw0KLQkJfQ0KLQ0KLQkJcmV0dXJuIHNBcHBTdHJlYW0uR2V0Qnl0ZVN0cmluZygpOw0KLQl9DQotDQotCXJldHVybiAiIjsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLGNvbnN0IEZYX0JPT0wgJiBiRmlsbE9yU3Ryb2tlKQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNDb2xvclN0cmVhbTsNCi0NCi0Jc3dpdGNoIChjb2xvci5uQ29sb3JUeXBlKQ0KLQl7CQkNCi0JY2FzZSBDT0xPUlRZUEVfUkdCOg0KLQkJc0NvbG9yU3RyZWFtIDw8IGNvbG9yLmZDb2xvcjEgPDwgIiAiIDw8IGNvbG9yLmZDb2xvcjIgPDwgIiAiIDw8IGNvbG9yLmZDb2xvcjMgPDwgIiAiIA0KLQkJCTw8IChiRmlsbE9yU3Ryb2tlID8gInJnIiA6ICJSRyIpIDw8ICJcbiI7DQotCQlicmVhazsNCi0JY2FzZSBDT0xPUlRZUEVfR1JBWToNCi0JCXNDb2xvclN0cmVhbSA8PCBjb2xvci5mQ29sb3IxIDw8ICIgIiA8PCAoYkZpbGxPclN0cm9rZSA/ICJnIiA6ICJHIikgPDwgIlxuIjsNCi0JCWJyZWFrOw0KLQljYXNlIENPTE9SVFlQRV9DTVlLOg0KLQkJc0NvbG9yU3RyZWFtIDw8IGNvbG9yLmZDb2xvcjEgPDwgIiAiIDw8IGNvbG9yLmZDb2xvcjIgPDwgIiAiIDw8IGNvbG9yLmZDb2xvcjMgPDwgIiAiIDw8IGNvbG9yLmZDb2xvcjQgPDwgIiAiIA0KLQkJCTw8IChiRmlsbE9yU3Ryb2tlID8gImsiIDogIksiKSA8PCAiXG4iOw0KLQkJYnJlYWs7DQotCX0NCi0NCi0JcmV0dXJuIHNDb2xvclN0cmVhbS5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEJvcmRlckFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByZWN0LCBGWF9GTE9BVCBmV2lkdGgsDQotCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLCBjb25zdCBDUFdMX0NvbG9yICYgY3JMZWZ0VG9wLCBjb25zdCBDUFdMX0NvbG9yICYgY3JSaWdodEJvdHRvbSwNCi0JCQkJCQkJCQkJCQlGWF9JTlQzMiBuU3R5bGUsIGNvbnN0IENQV0xfRGFzaCAmIGRhc2gpDQotew0KLQlDRlhfQnl0ZVRleHRCdWYgc0FwcFN0cmVhbTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc0NvbG9yOw0KLQ0KLQlGWF9GTE9BVCBmTGVmdCA9IHJlY3QubGVmdDsNCi0JRlhfRkxPQVQgZlJpZ2h0ID0gcmVjdC5yaWdodDsNCi0JRlhfRkxPQVQgZlRvcCA9IHJlY3QudG9wOw0KLQlGWF9GTE9BVCBmQm90dG9tID0gcmVjdC5ib3R0b207DQotDQotCWlmIChmV2lkdGggPiAwLjBmKQ0KLQl7DQotCQlGWF9GTE9BVCBmSGFsZldpZHRoID0gZldpZHRoIC8gMi4wZjsNCi0NCi0JCXNBcHBTdHJlYW0gPDwgInFcbiI7DQotDQotCQlzd2l0Y2ggKG5TdHlsZSkNCi0JCXsNCi0JCWRlZmF1bHQ6DQotCQljYXNlIFBCU19TT0xJRDoNCi0JCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjb2xvcixUUlVFKTsNCi0JCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkNCi0JCQl7DQotCQkJCXNBcHBTdHJlYW0gPDwgc0NvbG9yOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0IDw8ICIgIiA8PCBmQm90dG9tIDw8ICIgIiA8PCBmUmlnaHQgLSBmTGVmdCA8PCAiICIgPDwgZlRvcCAtIGZCb3R0b20gPDwgIiByZVxuIjsNCi0JCQkJc0FwcFN0cmVhbSA8PCBmTGVmdCArIGZXaWR0aCA8PCAiICIgPDwgZkJvdHRvbSArIGZXaWR0aCA8PCAiICIgDQotCQkJCQk8PCBmUmlnaHQgLSBmTGVmdCAtIGZXaWR0aCAqIDIgPDwgIiAiIDw8IGZUb3AgLSBmQm90dG9tIC0gZldpZHRoICogMiA8PCAiIHJlXG4iOw0KLQkJCQlzQXBwU3RyZWFtIDw8ICJmKlxuIjsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIFBCU19EQVNIOg0KLQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbG9yLEZBTFNFKTsNCi0JCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkNCi0JCQl7DQotCQkJCXNBcHBTdHJlYW0gPDwgc0NvbG9yOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZXaWR0aCA8PCAiIHciIDw8ICIgWyIgPDwgZGFzaC5uRGFzaCA8PCAiICIgPDwgZGFzaC5uR2FwIDw8ICJdICIgPDwgZGFzaC5uUGhhc2UgPDwgIiBkXG4iOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0ICsgZldpZHRoIC8gMiA8PCAiICIgPDwgZkJvdHRvbSArIGZXaWR0aCAvIDIgPDwgIiBtXG4iOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0ICsgZldpZHRoIC8gMiA8PCAiICIgPDwgZlRvcCAtIGZXaWR0aCAvIDIgPDwgIiBsXG4iOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZSaWdodCAtIGZXaWR0aCAvIDIgPDwgIiAiIDw8IGZUb3AgLSBmV2lkdGggLyAyIDw8ICIgbFxuIjsNCi0JCQkJc0FwcFN0cmVhbSA8PCBmUmlnaHQgLSBmV2lkdGggLyAyIDw8ICIgIiA8PCBmQm90dG9tICsgZldpZHRoIC8gMiA8PCAiIGxcbiI7DQotCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmV2lkdGggLyAyIDw8ICIgIiA8PCBmQm90dG9tICsgZldpZHRoIC8gMiA8PCAiIGwgU1xuIjsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIFBCU19CRVZFTEVEOg0KLQkJY2FzZSBQQlNfSU5TRVQ6DQotCQkJc0NvbG9yID0gQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JMZWZ0VG9wLFRSVUUpOw0KLQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCXsNCi0JCQkJc0FwcFN0cmVhbSA8PCBzQ29sb3I7DQotCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmSGFsZldpZHRoIDw8ICIgIiA8PCBmQm90dG9tICsgZkhhbGZXaWR0aCA8PCAiIG1cbiI7DQotCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmSGFsZldpZHRoIDw8ICIgIiA8PCBmVG9wIC0gZkhhbGZXaWR0aCA8PCAiIGxcbiI7DQotCQkJCXNBcHBTdHJlYW0gPDwgZlJpZ2h0IC0gZkhhbGZXaWR0aCA8PCAiICIgPDwgZlRvcCAtIGZIYWxmV2lkdGggPDwgIiBsXG4iOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZSaWdodCAtIGZIYWxmV2lkdGggKiAyIDw8ICIgIiA8PCBmVG9wIC0gZkhhbGZXaWR0aCAqIDIgPDwgIiBsXG4iOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0ICsgZkhhbGZXaWR0aCAqIDIgPDwgIiAiIDw8IGZUb3AgLSBmSGFsZldpZHRoICogMiA8PCAiIGxcbiI7DQotCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmSGFsZldpZHRoICogMiA8PCAiICIgPDwgZkJvdHRvbSArIGZIYWxmV2lkdGggKiAyIDw8ICIgbCBmXG4iOw0KLQkJCX0NCi0NCi0JCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclJpZ2h0Qm90dG9tLFRSVUUpOw0KLQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCXsNCi0JCQkJc0FwcFN0cmVhbSA8PCBzQ29sb3I7DQotCQkJCXNBcHBTdHJlYW0gPDwgZlJpZ2h0IC0gZkhhbGZXaWR0aCA8PCAiICIgPDwJZlRvcCAtIGZIYWxmV2lkdGggPDwgIiBtXG4iOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZSaWdodCAtIGZIYWxmV2lkdGggPDwgIiAiIDw8CWZCb3R0b20gKyBmSGFsZldpZHRoIDw8ICIgbFxuIjsNCi0JCQkJc0FwcFN0cmVhbSA8PCBmTGVmdCArIGZIYWxmV2lkdGggPDwgIiAiIDw8IAlmQm90dG9tICsgZkhhbGZXaWR0aCA8PCAiIGxcbiI7DQotCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmSGFsZldpZHRoICogMiA8PCAiICIgPDwgZkJvdHRvbSArIGZIYWxmV2lkdGggKiAyIDw8ICIgbFxuIjsNCi0JCQkJc0FwcFN0cmVhbSA8PCBmUmlnaHQgLSBmSGFsZldpZHRoICogMiA8PCAiICIgPDwgZkJvdHRvbSArIGZIYWxmV2lkdGggKiAyIDw8ICIgbFxuIjsNCi0JCQkJc0FwcFN0cmVhbSA8PCBmUmlnaHQgLSBmSGFsZldpZHRoICogMiA8PCAiICIgPDwgZlRvcCAtIGZIYWxmV2lkdGggKiAyIDw8ICIgbCBmXG4iOw0KLQkJCX0NCi0NCi0JCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjb2xvcixUUlVFKTsNCi0JCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkNCi0JCQl7DQotCQkJCXNBcHBTdHJlYW0gPDwgc0NvbG9yOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0IDw8ICIgIiA8PCBmQm90dG9tIDw8ICIgIiA8PAlmUmlnaHQgLSBmTGVmdCA8PCAiICIgPDwgZlRvcCAtIGZCb3R0b20gPDwgIiByZVxuIjsNCi0JCQkJc0FwcFN0cmVhbSA8PCBmTGVmdCArIGZIYWxmV2lkdGggPDwgIiAiIDw8IGZCb3R0b20gKyBmSGFsZldpZHRoIDw8ICIgIiANCi0JCQkJCTw8IGZSaWdodCAtIGZMZWZ0IC0gZkhhbGZXaWR0aCAqIDIgPDwgIiAiIDw8IGZUb3AgLSBmQm90dG9tIC0gZkhhbGZXaWR0aCAqIDIgPDwgIiByZSBmKlxuIjsJCQkJCQkNCi0JCQl9DQotCQkJYnJlYWs7DQotCQljYXNlIFBCU19VTkRFUkxJTkVEOg0KLQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbG9yLEZBTFNFKTsNCi0JCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkNCi0JCQl7DQotCQkJCXNBcHBTdHJlYW0gPDwgc0NvbG9yOw0KLQkJCQlzQXBwU3RyZWFtIDw8IGZXaWR0aCA8PCAiIHdcbiI7DQotCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgPDwgIiAiIDw8IGZCb3R0b20gKyBmV2lkdGggLyAyIDw8ICIgbVxuIjsNCi0JCQkJc0FwcFN0cmVhbSA8PCBmUmlnaHQgPDwgIiAiIDw8IGZCb3R0b20gKyBmV2lkdGggLyAyIDw8ICIgbCBTXG4iOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCX0NCi0JCQ0KLQkJc0FwcFN0cmVhbSA8PCAiUVxuIjsNCi0JfQ0KLQ0KLQlyZXR1cm4gc0FwcFN0cmVhbS5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldENpcmNsZUJvcmRlckFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByZWN0LCBGWF9GTE9BVCBmV2lkdGgsDQotCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLCBjb25zdCBDUFdMX0NvbG9yICYgY3JMZWZ0VG9wLCBjb25zdCBDUFdMX0NvbG9yICYgY3JSaWdodEJvdHRvbSwNCi0JCQkJCQkJCQkJCQlGWF9JTlQzMiBuU3R5bGUsIGNvbnN0IENQV0xfRGFzaCAmIGRhc2gpDQotew0KLQlDRlhfQnl0ZVRleHRCdWYgc0FwcFN0cmVhbTsNCi0JQ0ZYX0J5dGVTdHJpbmcgc0NvbG9yOw0KLQ0KLQkNCi0NCi0NCi0NCi0NCi0JaWYgKGZXaWR0aCA+IDAuMGYpDQotCXsNCi0JCXNBcHBTdHJlYW0gPDwgInFcbiI7DQotDQotCQlzd2l0Y2ggKG5TdHlsZSkNCi0JCXsNCi0JCWRlZmF1bHQ6DQotCQljYXNlIFBCU19TT0xJRDoNCi0JCWNhc2UgUEJTX1VOREVSTElORUQ6DQotCQkJew0KLQkJCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjb2xvcixGQUxTRSk7DQotCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQl7DQotCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZXaWR0aCA8PCAiIHdcbiIgPDwgc0NvbG9yIA0KLQkJCQkJCTw8IENQV0xfVXRpbHM6OkdldEFQX0NpcmNsZShDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChyZWN0LGZXaWR0aCAvIDIuMGYpKQ0KLQkJCQkJCTw8ICIgU1xuUVxuIjsNCi0JCQkJfQ0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgUEJTX0RBU0g6DQotCQkJew0KLQkJCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjb2xvcixGQUxTRSk7DQotCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQl7DQotCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZXaWR0aCA8PCAiIHdcbiIgDQotCQkJCQkJPDwgIlsiIDw8IGRhc2gubkRhc2ggPDwgIiAiIDw8IGRhc2gubkdhcCA8PCAiXSAiIDw8IGRhc2gublBoYXNlIDw8ICIgZFxuIiANCi0JCQkJCQk8PCBzQ29sb3IgPDwgQ1BXTF9VdGlsczo6R2V0QVBfQ2lyY2xlKENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3QsZldpZHRoIC8gMi4wZikpDQotCQkJCQkJPDwgIiBTXG5RXG4iOw0KLQkJCQl9CQkJCQkJDQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQQlNfQkVWRUxFRDoNCi0JCQl7DQotCQkJCUZYX0ZMT0FUIGZIYWxmV2lkdGggPSBmV2lkdGggLyAyLjBmOw0KLQ0KLQkJCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjb2xvcixGQUxTRSk7DQotCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQl7DQotCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZIYWxmV2lkdGggPDwgIiB3XG4iDQotCQkJCQkJPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0NpcmNsZShyZWN0KQ0KLQkJCQkJCTw8ICIgU1xuUVxuIjsNCi0JCQkJfQkJCQkJDQotDQotCQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyTGVmdFRvcCxGQUxTRSk7DQotCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQl7DQotCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZIYWxmV2lkdGggPDwgIiB3XG4iDQotCQkJCQkJPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0hhbGZDaXJjbGUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdCxmSGFsZldpZHRoICogMC43NWYpLFBXTF9QSS80LjBmKQ0KLQkJCQkJCTw8ICIgU1xuUVxuIjsNCi0JCQkJfQkNCi0NCi0JCQkJc0NvbG9yID0gQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JSaWdodEJvdHRvbSxGQUxTRSk7DQotCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQl7DQotCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZIYWxmV2lkdGggPDwgIiB3XG4iDQotCQkJCQkJPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0hhbGZDaXJjbGUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdCxmSGFsZldpZHRoICogMC43NWYpLFBXTF9QSSo1LzQuMGYpDQotCQkJCQkJPDwgIiBTXG5RXG4iOw0KLQkJCQl9CQ0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgUEJTX0lOU0VUOg0KLQkJCXsNCi0JCQkJRlhfRkxPQVQgZkhhbGZXaWR0aCA9IGZXaWR0aCAvIDIuMGY7DQotDQotCQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbG9yLEZBTFNFKTsNCi0JCQkJaWYgKHNDb2xvci5HZXRMZW5ndGgoKSA+IDApDQotCQkJCXsNCi0JCQkJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgZkhhbGZXaWR0aCA8PCAiIHdcbiINCi0JCQkJCQk8PCBzQ29sb3IgPDwgQ1BXTF9VdGlsczo6R2V0QVBfQ2lyY2xlKHJlY3QpDQotCQkJCQkJPDwgIiBTXG5RXG4iOw0KLQkJCQl9DQotDQotCQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyTGVmdFRvcCxGQUxTRSk7DQotCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQl7DQotCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZIYWxmV2lkdGggPDwgIiB3XG4iDQotCQkJCQkJPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0hhbGZDaXJjbGUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdCxmSGFsZldpZHRoICogMC43NWYpLFBXTF9QSS80LjBmKQ0KLQkJCQkJCTw8ICIgU1xuUVxuIjsNCi0JCQkJfQkNCi0NCi0JCQkJc0NvbG9yID0gQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JSaWdodEJvdHRvbSxGQUxTRSk7DQotCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQ0KLQkJCQl7DQotCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZIYWxmV2lkdGggPDwgIiB3XG4iDQotCQkJCQkJPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0hhbGZDaXJjbGUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdCxmSGFsZldpZHRoICogMC43NWYpLFBXTF9QSSo1LzQuMGYpDQotCQkJCQkJPDwgIiBTXG5RXG4iOw0KLQkJCQl9CQkJCQkJDQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJfQ0KLQkJDQotCQlzQXBwU3RyZWFtIDw8ICJRXG4iOw0KLQl9DQotDQotCXJldHVybiBzQXBwU3RyZWFtLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ1BXTF9Db2xvciBDUFdMX1V0aWxzOjpTdWJzdHJhY3RDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgc0NvbG9yLEZYX0ZMT0FUIGZDb2xvclN1YikNCi17DQotCUNQV0xfQ29sb3Igc1JldDsNCi0Jc1JldC5uQ29sb3JUeXBlID0gc0NvbG9yLm5Db2xvclR5cGU7DQotDQotCXN3aXRjaCAoc0NvbG9yLm5Db2xvclR5cGUpDQotCXsNCi0JY2FzZSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQ6DQotCQlzUmV0Lm5Db2xvclR5cGUgPSBDT0xPUlRZUEVfUkdCOw0KLQkJc1JldC5mQ29sb3IxID0gUFdMX01BWCgxIC0gZkNvbG9yU3ViLDAuMGYpOw0KLQkJc1JldC5mQ29sb3IyID0gUFdMX01BWCgxIC0gZkNvbG9yU3ViLDAuMGYpOw0KLQkJc1JldC5mQ29sb3IzID0gUFdMX01BWCgxIC0gZkNvbG9yU3ViLDAuMGYpOw0KLQkJYnJlYWs7DQotCWNhc2UgQ09MT1JUWVBFX1JHQjoNCi0JY2FzZSBDT0xPUlRZUEVfR1JBWToNCi0JY2FzZSBDT0xPUlRZUEVfQ01ZSzoNCi0JCXNSZXQuZkNvbG9yMSA9IFBXTF9NQVgoc0NvbG9yLmZDb2xvcjEgLSBmQ29sb3JTdWIsMC4wZik7DQotCQlzUmV0LmZDb2xvcjIgPSBQV0xfTUFYKHNDb2xvci5mQ29sb3IyIC0gZkNvbG9yU3ViLDAuMGYpOw0KLQkJc1JldC5mQ29sb3IzID0gUFdMX01BWChzQ29sb3IuZkNvbG9yMyAtIGZDb2xvclN1YiwwLjBmKTsNCi0JCXNSZXQuZkNvbG9yNCA9IFBXTF9NQVgoc0NvbG9yLmZDb2xvcjQgLSBmQ29sb3JTdWIsMC4wZik7DQotCQlicmVhazsNCi0JfQkNCi0NCi0JcmV0dXJuIHNSZXQ7DQotfQ0KLQ0KLUNQV0xfQ29sb3IgQ1BXTF9VdGlsczo6RGV2aWRlQ29sb3IoY29uc3QgQ1BXTF9Db2xvciAmIHNDb2xvcixGWF9GTE9BVCBmQ29sb3JEZXZpZGUpDQotew0KLQlDUFdMX0NvbG9yIHNSZXQ7DQotCXNSZXQubkNvbG9yVHlwZSA9IHNDb2xvci5uQ29sb3JUeXBlOw0KLQ0KLQlzd2l0Y2ggKHNDb2xvci5uQ29sb3JUeXBlKQ0KLQl7DQotCWNhc2UgQ09MT1JUWVBFX1RSQU5TUEFSRU5UOg0KLQkJc1JldC5uQ29sb3JUeXBlID0gQ09MT1JUWVBFX1JHQjsNCi0JCXNSZXQuZkNvbG9yMSA9IDEgLyBmQ29sb3JEZXZpZGU7DQotCQlzUmV0LmZDb2xvcjIgPSAxIC8gZkNvbG9yRGV2aWRlOw0KLQkJc1JldC5mQ29sb3IzID0gMSAvIGZDb2xvckRldmlkZTsNCi0JCWJyZWFrOw0KLQljYXNlIENPTE9SVFlQRV9SR0I6DQotCWNhc2UgQ09MT1JUWVBFX0dSQVk6DQotCWNhc2UgQ09MT1JUWVBFX0NNWUs6DQotCQlzUmV0ID0gc0NvbG9yOw0KLQkJc1JldC5mQ29sb3IxIC89IGZDb2xvckRldmlkZTsNCi0JCXNSZXQuZkNvbG9yMiAvPSBmQ29sb3JEZXZpZGU7DQotCQlzUmV0LmZDb2xvcjMgLz0gZkNvbG9yRGV2aWRlOw0KLQkJc1JldC5mQ29sb3I0IC89IGZDb2xvckRldmlkZTsNCi0JCWJyZWFrOw0KLQl9CQ0KLQ0KLQlyZXR1cm4gc1JldDsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QXBwU3RyZWFtX0NoZWNrKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCkNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBzQVA7DQotCXNBUCA8PCAicVxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclRleHQsVFJVRSkgPDwgQ1BXTF9VdGlsczo6R2V0QVBfQ2hlY2socmNCQm94KSA8PCAiZlxuUVxuIjsNCi0JcmV0dXJuIHNBUC5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFwcFN0cmVhbV9DaXJjbGUoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNBUDsNCi0Jc0FQIDw8ICJxXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyVGV4dCxUUlVFKSA8PCBDUFdMX1V0aWxzOjpHZXRBUF9DaXJjbGUocmNCQm94KSA8PCAiZlxuUVxuIjsNCi0JcmV0dXJuIHNBUC5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFwcFN0cmVhbV9Dcm9zcyhjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpDQotew0KLQlDRlhfQnl0ZVRleHRCdWYgc0FQOw0KLQlzQVAgPDwgInFcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JUZXh0LEZBTFNFKSA8PCBDUFdMX1V0aWxzOjpHZXRBUF9Dcm9zcyhyY0JCb3gpIDw8ICJTXG5RXG4iOw0KLQlyZXR1cm4gc0FQLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QXBwU3RyZWFtX0RpYW1vbmQoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNBUDsNCi0Jc0FQIDw8ICJxXG4xIHdcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JUZXh0LFRSVUUpIDw8IENQV0xfVXRpbHM6OkdldEFQX0RpYW1vbmQocmNCQm94KSA8PCAiZlxuUVxuIjsNCi0JcmV0dXJuIHNBUC5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFwcFN0cmVhbV9TcXVhcmUoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KQ0KLXsNCi0JQ0ZYX0J5dGVUZXh0QnVmIHNBUDsNCi0Jc0FQIDw8ICJxXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyVGV4dCxUUlVFKSA8PCBDUFdMX1V0aWxzOjpHZXRBUF9TcXVhcmUocmNCQm94KSA8PCAiZlxuUVxuIjsNCi0JcmV0dXJuIHNBUC5HZXRCeXRlU3RyaW5nKCk7DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFwcFN0cmVhbV9TdGFyKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCkNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBzQVA7DQotCXNBUCA8PCAicVxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclRleHQsVFJVRSkgPDwgQ1BXTF9VdGlsczo6R2V0QVBfU3RhcihyY0JCb3gpIDw8ICJmXG5RXG4iOw0KLQlyZXR1cm4gc0FQLkdldEJ5dGVTdHJpbmcoKTsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0Q2hlY2tCb3hBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LA0KLQkJCQkJCQkJCQkJCQlGWF9JTlQzMiBuU3R5bGUsDQotCQkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpDQotew0KLQlDUERGX1JlY3QgcmNDZW50ZXIgPSBHZXRDZW50ZXJTcXVhcmUocmNCQm94KTsNCi0Jc3dpdGNoIChuU3R5bGUpDQotCXsNCi0JZGVmYXVsdDoNCi0JY2FzZSBQQ1NfQ0hFQ0s6DQotCQlyZXR1cm4gR2V0QXBwU3RyZWFtX0NoZWNrKHJjQ2VudGVyLGNyVGV4dCk7DQotCWNhc2UgUENTX0NJUkNMRToNCi0JCXJldHVybiBHZXRBcHBTdHJlYW1fQ2lyY2xlKFNjYWxlUmVjdChyY0NlbnRlciwyLjBmLzMuMGYpLGNyVGV4dCk7DQotCWNhc2UgUENTX0NST1NTOg0KLQkJcmV0dXJuIEdldEFwcFN0cmVhbV9Dcm9zcyhyY0NlbnRlcixjclRleHQpOw0KLQljYXNlIFBDU19ESUFNT05EOg0KLQkJcmV0dXJuIEdldEFwcFN0cmVhbV9EaWFtb25kKFNjYWxlUmVjdChyY0NlbnRlciwyLjBmLzMuMGYpLGNyVGV4dCk7CQkNCi0JY2FzZSBQQ1NfU1FVQVJFOg0KLQkJcmV0dXJuIEdldEFwcFN0cmVhbV9TcXVhcmUoU2NhbGVSZWN0KHJjQ2VudGVyLDIuMGYvMy4wZiksY3JUZXh0KTsNCi0JY2FzZSBQQ1NfU1RBUjoNCi0JCXJldHVybiBHZXRBcHBTdHJlYW1fU3RhcihTY2FsZVJlY3QocmNDZW50ZXIsMi4wZi8zLjBmKSxjclRleHQpOw0KLQl9DQotfQ0KLQ0KLUNGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldFJhZGlvQnV0dG9uQXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwNCi0JCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLA0KLQkJCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KQ0KLXsNCi0JQ1BERl9SZWN0IHJjQ2VudGVyID0gR2V0Q2VudGVyU3F1YXJlKHJjQkJveCk7DQotCXN3aXRjaCAoblN0eWxlKQ0KLQl7DQotCWRlZmF1bHQ6DQotCWNhc2UgUENTX0NIRUNLOg0KLQkJcmV0dXJuIEdldEFwcFN0cmVhbV9DaGVjayhyY0NlbnRlcixjclRleHQpOw0KLQljYXNlIFBDU19DSVJDTEU6DQotCQlyZXR1cm4gR2V0QXBwU3RyZWFtX0NpcmNsZShTY2FsZVJlY3QocmNDZW50ZXIsMS4wZi8yLjBmKSxjclRleHQpOw0KLQljYXNlIFBDU19DUk9TUzoNCi0JCXJldHVybiBHZXRBcHBTdHJlYW1fQ3Jvc3MocmNDZW50ZXIsY3JUZXh0KTsNCi0JY2FzZSBQQ1NfRElBTU9ORDoNCi0JCXJldHVybiBHZXRBcHBTdHJlYW1fRGlhbW9uZChTY2FsZVJlY3QocmNDZW50ZXIsMi4wZi8zLjBmKSxjclRleHQpOwkJDQotCWNhc2UgUENTX1NRVUFSRToNCi0JCXJldHVybiBHZXRBcHBTdHJlYW1fU3F1YXJlKFNjYWxlUmVjdChyY0NlbnRlciwyLjBmLzMuMGYpLGNyVGV4dCk7DQotCWNhc2UgUENTX1NUQVI6DQotCQlyZXR1cm4gR2V0QXBwU3RyZWFtX1N0YXIoU2NhbGVSZWN0KHJjQ2VudGVyLDIuMGYvMy4wZiksY3JUZXh0KTsNCi0JfQ0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXREcm9wQnV0dG9uQXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCkNCi17DQotCUNGWF9CeXRlVGV4dEJ1ZiBzQXBwU3RyZWFtOw0KLQ0KLQlpZiAoIXJjQkJveC5Jc0VtcHR5KCkpDQotCXsNCi0JCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLDIyMC4wZi8yNTUuMGYsMjIwLjBmLzI1NS4wZiwyMjAuMGYvMjU1LjBmKSxUUlVFKTsNCi0JCXNBcHBTdHJlYW0gPDwgcmNCQm94LmxlZnQgPDwgIiAiIDw8IHJjQkJveC5ib3R0b20gPDwgIiAiIA0KLQkJCQk8PCByY0JCb3gucmlnaHQgLSByY0JCb3gubGVmdCA8PCAiICIgPDwgcmNCQm94LnRvcCAtIHJjQkJveC5ib3R0b20gPDwgIiByZSBmXG4iOw0KLQkJc0FwcFN0cmVhbSA8PCAiUVxuIjsNCi0NCi0JCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgDQotCQkJQ1BXTF9VdGlsczo6R2V0Qm9yZGVyQXBwU3RyZWFtKHJjQkJveCwyLENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMCksQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwxKSxDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDAuNSksUEJTX0JFVkVMRUQsQ1BXTF9EYXNoKDMsMCwwKSkgDQotCQkJPDwgIlFcbiI7DQotDQotCQlDUERGX1BvaW50IHB0Q2VudGVyID0gQ1BERl9Qb2ludCgocmNCQm94LmxlZnQgKyByY0JCb3gucmlnaHQpLzIsKHJjQkJveC50b3AgKyByY0JCb3guYm90dG9tKS8yKTsNCi0JCWlmIChJc0Zsb2F0QmlnZ2VyKHJjQkJveC5yaWdodCAtIHJjQkJveC5sZWZ0LDYpICYmIElzRmxvYXRCaWdnZXIocmNCQm94LnRvcCAtIHJjQkJveC5ib3R0b20sNikpDQotCQl7DQotCQkJc0FwcFN0cmVhbSA8PCAicVxuIiA8PCAiIDAgZ1xuIjsNCi0JCQlzQXBwU3RyZWFtIDw8IHB0Q2VudGVyLnggLSAzIDw8ICIgIiA8PCBwdENlbnRlci55ICsgMS41ZiA8PCAiIG1cbiI7DQotCQkJc0FwcFN0cmVhbSA8PCBwdENlbnRlci54ICsgMyA8PCAiICIgPDwgcHRDZW50ZXIueSArIDEuNWYgPDwgIiBsXG4iOw0KLQkJCXNBcHBTdHJlYW0gPDwgcHRDZW50ZXIueCA8PCAiICIgPDwgcHRDZW50ZXIueSAtIDEuNWYgPDwgIiBsXG4iOw0KLQkJCXNBcHBTdHJlYW0gPDwgcHRDZW50ZXIueCAtIDMgPDwgIiAiIDw8IHB0Q2VudGVyLnkgKyAxLjVmIDw8ICIgbCBmXG4iOw0KLQkJCXNBcHBTdHJlYW0gPDwgIlFcbiI7DQotCQl9DQotCX0NCi0NCi0JcmV0dXJuIHNBcHBTdHJlYW0uR2V0Qnl0ZVN0cmluZygpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkNvbnZlcnRDTVlLMkdSQVkoRlhfRkxPQVQgZEMsRlhfRkxPQVQgZE0sRlhfRkxPQVQgZFksRlhfRkxPQVQgZEssRlhfRkxPQVQgJmRHcmF5KQ0KLXsNCi0JaWYgKGRDPDAgfHwgZEM+MSB8fCBkTTwwIHx8IGRNPjEgfHwgZFkgPCAwIHx8IGRZID4xIHx8IGRLIDwgMCB8fCBkSyA+MSkNCi0JCXJldHVybjsNCi0JZEdyYXkgPSAxLjBmIC0gRlhfTUlOKDEuMGYsMC4zZipkQyswLjU5ZiAqIGRNICsgMC4xMWYqZFkrZEspOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkNvbnZlcnRHUkFZMkNNWUsoRlhfRkxPQVQgZEdyYXksRlhfRkxPQVQgICZkQyxGWF9GTE9BVCAmZE0sRlhfRkxPQVQgJmRZLEZYX0ZMT0FUICZkSykNCi17DQotCWlmIChkR3JheSA8MCB8fCBkR3JheSA+MSkNCi0JCXJldHVybjsNCi0JZEMgPSAwLjBmOw0KLQlkTSA9IDAuMGY7DQotCWRZID0gMC4wZjsNCi0JZEsgPSAxLjBmLWRHcmF5Ow0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkNvbnZlcnRHUkFZMlJHQihGWF9GTE9BVCBkR3JheSxGWF9GTE9BVCAmZFIsRlhfRkxPQVQgJmRHLEZYX0ZMT0FUICZkQikNCi17DQotCWlmIChkR3JheSA8MCB8fCBkR3JheSA+MSkNCi0JCXJldHVybjsNCi0JZFIgPSBkR3JheTsNCi0JZEcgPSBkR3JheTsNCi0JZEIgPSBkR3JheTsNCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpDb252ZXJ0UkdCMkdSQVkoRlhfRkxPQVQgZFIsRlhfRkxPQVQgZEcsRlhfRkxPQVQgZEIsRlhfRkxPQVQgJmRHcmF5KQ0KLXsNCi0JaWYgKGRSPDAgfHwgZFI+MSB8fCBkRzwwIHx8IGRHID4gMCB8fCBkQiA8IDAgfHwgZEIgPjEpDQotCQlyZXR1cm47DQotCWRHcmF5ID0gMC4zZipkUiswLjU5ZipkRyswLjExZipkQjsNCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpDb252ZXJ0Q01ZSzJSR0IoRlhfRkxPQVQgZEMsRlhfRkxPQVQgZE0sRlhfRkxPQVQgZFksRlhfRkxPQVQgZEssRlhfRkxPQVQgJmRSLEZYX0ZMT0FUICZkRyxGWF9GTE9BVCAmZEIpDQotew0KLQlpZiAoZEMgPDAgfHwgZEM+MSB8fCBkTSA8IDAgfHwgZE0gPiAxIHx8IGRZIDwgMCB8fCBkWSA+IDEgfHwgZEsgPCAwIHx8IGRLID4gMSApDQotCQlyZXR1cm47DQotCWRSID0gMS4wZiAtIEZYX01JTigxLjBmLCBkQyArIGRLKTsNCi0JZEcgPSAxLjBmIC0gRlhfTUlOKDEuMGYsIGRNICsgZEspOw0KLQlkQiA9IDEuMGYgLSBGWF9NSU4oMS4wZiwgZFkgKyBkSyk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9VdGlsczo6Q29udmVydFJHQjJDTVlLKEZYX0ZMT0FUIGRSLEZYX0ZMT0FUIGRHLEZYX0ZMT0FUIGRCLEZYX0ZMT0FUICZkQyxGWF9GTE9BVCAmZE0sRlhfRkxPQVQgJmRZLEZYX0ZMT0FUICZkSykNCi17DQotCWlmIChkUjwwIHx8IGRSPjEgfHwgZEc8MCB8fCBkRz4xIHx8IGRCPDAgfHwgZEI+MSkNCi0JCXJldHVybjsNCi0NCi0JZEMgPSAxLjBmIC0gZFI7DQotCWRNID0gMS4wZiAtIGRHOw0KLQlkWSA9IDEuMGYgLSBkQjsNCi0JZEsgPSBGWF9NSU4oZEMsIEZYX01JTihkTSwgZFkpKTsNCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpQV0xDb2xvclRvQVJHQihjb25zdCBDUFdMX0NvbG9yJiBjb2xvciwgRlhfSU5UMzImIGFscGhhLCBGWF9GTE9BVCYgcmVkLCBGWF9GTE9BVCYgZ3JlZW4sIEZYX0ZMT0FUJiBibHVlKQ0KLXsNCi0Jc3dpdGNoIChjb2xvci5uQ29sb3JUeXBlKQ0KLQl7DQotCWNhc2UgQ09MT1JUWVBFX1RSQU5TUEFSRU5UOg0KLQkJew0KLQkJCWFscGhhID0gMDsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIENPTE9SVFlQRV9HUkFZOg0KLQkJew0KLQkJCUNvbnZlcnRHUkFZMlJHQihjb2xvci5mQ29sb3IxLCByZWQsIGdyZWVuLCBibHVlKTsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIENPTE9SVFlQRV9SR0I6DQotCQl7DQotCQkJcmVkID0gY29sb3IuZkNvbG9yMTsNCi0JCQlncmVlbiA9IGNvbG9yLmZDb2xvcjI7DQotCQkJYmx1ZSA9IGNvbG9yLmZDb2xvcjM7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDT0xPUlRZUEVfQ01ZSzoNCi0JCXsNCi0JCQlDb252ZXJ0Q01ZSzJSR0IoY29sb3IuZkNvbG9yMSwgY29sb3IuZkNvbG9yMiwgY29sb3IuZkNvbG9yMywgY29sb3IuZkNvbG9yNCwNCi0JCQkJcmVkLCBncmVlbiwgYmx1ZSk7DQotCQl9DQotCQlicmVhazsNCi0JfQ0KLX0NCi0NCi1GWF9DT0xPUlJFRiBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvciwgRlhfSU5UMzIgblRyYW5zcGFyYW5jeSkNCi17DQotCUZYX0lOVDMyIG5BbHBoYSA9IG5UcmFuc3BhcmFuY3k7DQotCUZYX0ZMT0FUIGRSZWQgPSAwOw0KLQlGWF9GTE9BVCBkR3JlZW4gPSAwOw0KLQlGWF9GTE9BVCBkQmx1ZSA9IDA7DQotDQotCVBXTENvbG9yVG9BUkdCKGNvbG9yLCBuQWxwaGEsIGRSZWQsIGRHcmVlbiwgZEJsdWUpOw0KLQ0KLQlyZXR1cm4gQXJnYkVuY29kZShuQWxwaGEsIChGWF9JTlQzMikoZFJlZCoyNTUpLCAoRlhfSU5UMzIpKGRHcmVlbioyNTUpLCAoRlhfSU5UMzIpKGRCbHVlKjI1NSkpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkRyYXdGaWxsUmVjdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLGNvbnN0IENQREZfUmVjdCAmIHJlY3QsDQotCQkJCQkJCSAgY29uc3QgRlhfQ09MT1JSRUYgJiBjb2xvcikNCi17DQotCUNGWF9QYXRoRGF0YSBwYXRoOw0KLQlDUERGX1JlY3QgcmNUZW1wKHJlY3QpOwkNCi0JcGF0aC5BcHBlbmRSZWN0KHJjVGVtcC5sZWZ0LHJjVGVtcC5ib3R0b20scmNUZW1wLnJpZ2h0LHJjVGVtcC50b3ApOw0KLQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCBjb2xvciwgMCwgRlhGSUxMX1dJTkRJTkcpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkRyYXdGaWxsQXJlYShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLA0KLQkJCQkJCQljb25zdCBDUERGX1BvaW50KiBwUHRzLCBGWF9JTlQzMiBuQ291bnQsIGNvbnN0IEZYX0NPTE9SUkVGJiBjb2xvcikNCi17DQotCUNGWF9QYXRoRGF0YSBwYXRoOw0KLQlwYXRoLlNldFBvaW50Q291bnQobkNvdW50KTsNCi0NCi0JcGF0aC5TZXRQb2ludCgwLCBwUHRzWzBdLngsIHBQdHNbMF0ueSwgRlhQVF9NT1ZFVE8pOw0KLQlmb3IgKEZYX0lOVDMyIGk9MTsgaTxuQ291bnQ7IGkrKykNCi0JCXBhdGguU2V0UG9pbnQoaSwgcFB0c1tpXS54LCBwUHRzW2ldLnksIEZYUFRfTElORVRPKTsNCi0NCi0JcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgTlVMTCwgY29sb3IsIDAsIEZYRklMTF9BTFRFUk5BVEUpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwNCi0JCQkJCQkJICBjb25zdCBGWF9DT0xPUlJFRiAmIGNvbG9yLCBGWF9GTE9BVCBmV2lkdGgpDQotew0KLQlDRlhfUGF0aERhdGEgcGF0aDsNCi0JQ1BERl9SZWN0IHJjVGVtcChyZWN0KTsJDQotCXBhdGguQXBwZW5kUmVjdChyY1RlbXAubGVmdCxyY1RlbXAuYm90dG9tLHJjVGVtcC5yaWdodCxyY1RlbXAudG9wKTsNCi0JDQotCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7DQotCWdzZC5tX0xpbmVXaWR0aCA9IGZXaWR0aDsNCi0NCi0JcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgJmdzZCwgMCwgY29sb3IsIEZYRklMTF9BTFRFUk5BVEUpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCWNvbnN0IENQREZfUG9pbnQgJiBwdE1vdmVUbywgY29uc3QgQ1BERl9Qb2ludCAmIHB0TGluZVRvLCBjb25zdCBGWF9DT0xPUlJFRiAmIGNvbG9yLCBGWF9GTE9BVCBmV2lkdGgpDQotew0KLQlDRlhfUGF0aERhdGEgcGF0aDsNCi0JcGF0aC5TZXRQb2ludENvdW50KDIpOw0KLQlwYXRoLlNldFBvaW50KDAsIHB0TW92ZVRvLngsIHB0TW92ZVRvLnksIEZYUFRfTU9WRVRPKTsNCi0JcGF0aC5TZXRQb2ludCgxLCBwdExpbmVUby54LCBwdExpbmVUby55LCBGWFBUX0xJTkVUTyk7DQotDQotCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7DQotCWdzZC5tX0xpbmVXaWR0aCA9IGZXaWR0aDsNCi0NCi0JcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgJmdzZCwgMCwgY29sb3IsIEZYRklMTF9BTFRFUk5BVEUpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkRyYXdGaWxsUmVjdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLGNvbnN0IENQREZfUmVjdCAmIHJlY3QsDQotCQkJCQkJCSAgY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLCBGWF9JTlQzMiBuVHJhbnNwYXJhbmN5KQ0KLXsNCi0JQ1BXTF9VdGlsczo6RHJhd0ZpbGxSZWN0KHBEZXZpY2UscFVzZXIyRGV2aWNlLHJlY3QsUFdMQ29sb3JUb0ZYQ29sb3IoY29sb3IsblRyYW5zcGFyYW5jeSkpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkRyYXdTaGFkb3coQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCQkJCQkJCQkJCQkJCUZYX0JPT0wgYlZlcnRpY2FsLCBGWF9CT09MIGJIb3Jpem9udGFsLCBDUERGX1JlY3QgcmVjdCwNCi0JCQkJCQkJCQkJCQkJCUZYX0lOVDMyIG5UcmFuc3BhcmFuY3ksIEZYX0lOVDMyIG5TdGFydEdyYXksIEZYX0lOVDMyIG5FbmRHcmF5KQ0KLXsNCi0JRlhfRkxPQVQgZlN0ZXBHcmF5ID0gMS4wZjsNCi0NCi0JaWYgKGJWZXJ0aWNhbCkNCi0Jew0KLQkJZlN0ZXBHcmF5ID0gKG5FbmRHcmF5IC0gblN0YXJ0R3JheSkgLyByZWN0LkhlaWdodCgpOw0KLQ0KLQkJZm9yIChGWF9GTE9BVCBmeT1yZWN0LmJvdHRvbSswLjVmOyBmeTw9cmVjdC50b3AtMC41ZjsgZnkrPTEuMGYpDQotCQl7CQkJDQotCQkJRlhfSU5UMzIgbkdyYXkgPSBuU3RhcnRHcmF5ICsgKEZYX0lOVDMyKShmU3RlcEdyYXkgKiAoZnktcmVjdC5ib3R0b20pKTsNCi0JCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIENQREZfUG9pbnQocmVjdC5sZWZ0LCBmeSksDQotCQkJCUNQREZfUG9pbnQocmVjdC5yaWdodCwgZnkpLCBBcmdiRW5jb2RlKG5UcmFuc3BhcmFuY3ksIG5HcmF5LCBuR3JheSwgbkdyYXkpLCAxLjVmKTsNCi0JCX0NCi0JfQ0KLQ0KLQlpZiAoYkhvcml6b250YWwpDQotCXsNCi0JCWZTdGVwR3JheSA9IChuRW5kR3JheSAtIG5TdGFydEdyYXkpIC8gcmVjdC5XaWR0aCgpOw0KLQ0KLQkJZm9yIChGWF9GTE9BVCBmeD1yZWN0LmxlZnQrMC41ZjsgZng8PXJlY3QucmlnaHQtMC41ZjsgZngrPTEuMGYpDQotCQl7CQkJDQotCQkJRlhfSU5UMzIgbkdyYXkgPSBuU3RhcnRHcmF5ICsgKEZYX0lOVDMyKShmU3RlcEdyYXkgKiAoZngtcmVjdC5sZWZ0KSk7DQotCQkJQ1BXTF9VdGlsczo6RHJhd1N0cm9rZUxpbmUocERldmljZSwgcFVzZXIyRGV2aWNlLCBDUERGX1BvaW50KGZ4LCByZWN0LmJvdHRvbSksDQotCQkJCUNQREZfUG9pbnQoZngsIHJlY3QudG9wKSwgQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LCBuR3JheSwgbkdyYXksIG5HcmF5KSwgMS41Zik7DQotCQl9DQotCX0NCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpEcmF3Qm9yZGVyKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQkJCQkJY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgRlhfRkxPQVQgZldpZHRoLA0KLQkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3IgJiBjb2xvciwgY29uc3QgQ1BXTF9Db2xvciAmIGNyTGVmdFRvcCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyUmlnaHRCb3R0b20sDQotCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLCBjb25zdCBDUFdMX0Rhc2ggJiBkYXNoLCBGWF9JTlQzMiBuVHJhbnNwYXJhbmN5KQ0KLXsNCi0JRlhfRkxPQVQgZkxlZnQgPSByZWN0LmxlZnQ7DQotCUZYX0ZMT0FUIGZSaWdodCA9IHJlY3QucmlnaHQ7DQotCUZYX0ZMT0FUIGZUb3AgPSByZWN0LnRvcDsNCi0JRlhfRkxPQVQgZkJvdHRvbSA9IHJlY3QuYm90dG9tOw0KLQ0KLQlpZiAoZldpZHRoID4gMC4wZikNCi0Jew0KLQkJRlhfRkxPQVQgZkhhbGZXaWR0aCA9IGZXaWR0aCAvIDIuMGY7DQotDQotCQlzd2l0Y2ggKG5TdHlsZSkNCi0JCXsNCi0JCWRlZmF1bHQ6DQotCQljYXNlIFBCU19TT0xJRDoNCi0JCQl7DQotCQkJCUNGWF9QYXRoRGF0YSBwYXRoOw0KLQkJCQlwYXRoLkFwcGVuZFJlY3QoZkxlZnQsIGZCb3R0b20sIGZSaWdodCwgZlRvcCk7DQotCQkJCXBhdGguQXBwZW5kUmVjdChmTGVmdCArIGZXaWR0aCwgZkJvdHRvbSArIGZXaWR0aCwgZlJpZ2h0IC0gZldpZHRoLCBmVG9wIC0gZldpZHRoKTsNCi0JCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgTlVMTCwgUFdMQ29sb3JUb0ZYQ29sb3IoY29sb3IsblRyYW5zcGFyYW5jeSksIDAsIEZYRklMTF9BTFRFUk5BVEUpOw0KLQkJCX0NCi0JCQlicmVhazsNCi0JCWNhc2UgUEJTX0RBU0g6DQotCQkJew0KLQkJCQlDRlhfUGF0aERhdGEgcGF0aDsNCi0NCi0JCQkJcGF0aC5TZXRQb2ludENvdW50KDUpOw0KLQkJCQlwYXRoLlNldFBvaW50KDAsIGZMZWZ0ICsgZldpZHRoIC8gMi4wZiwgZkJvdHRvbSArIGZXaWR0aCAvIDIuMGYsIEZYUFRfTU9WRVRPKTsNCi0JCQkJcGF0aC5TZXRQb2ludCgxLCBmTGVmdCArIGZXaWR0aCAvIDIuMGYsIGZUb3AgLSBmV2lkdGggLyAyLjBmLCBGWFBUX0xJTkVUTyk7DQotCQkJCXBhdGguU2V0UG9pbnQoMiwgZlJpZ2h0IC0gZldpZHRoIC8gMi4wZiwgZlRvcCAtIGZXaWR0aCAvIDIuMGYsIEZYUFRfTElORVRPKTsNCi0JCQkJcGF0aC5TZXRQb2ludCgzLCBmUmlnaHQgLSBmV2lkdGggLyAyLjBmLCBmQm90dG9tICsgZldpZHRoIC8gMi4wZiwgRlhQVF9MSU5FVE8pOw0KLQkJCQlwYXRoLlNldFBvaW50KDQsIGZMZWZ0ICsgZldpZHRoIC8gMi4wZiwgZkJvdHRvbSArIGZXaWR0aCAvIDIuMGYsIEZYUFRfTElORVRPKTsNCi0NCi0JCQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JCQkJZ3NkLlNldERhc2hDb3VudCgyKTsJCQkJDQotCQkJCWdzZC5tX0Rhc2hBcnJheVswXSA9IDMuMGY7DQotCQkJCWdzZC5tX0Rhc2hBcnJheVsxXSA9IDMuMGY7DQotCQkJCWdzZC5tX0Rhc2hQaGFzZSA9IDA7CQ0KLQkJCQkNCi0JCQkJZ3NkLm1fTGluZVdpZHRoID0gZldpZHRoOw0KLQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLCBQV0xDb2xvclRvRlhDb2xvcihjb2xvcixuVHJhbnNwYXJhbmN5KSwgRlhGSUxMX1dJTkRJTkcpOwkJCQkNCi0JCQl9CQkJDQotCQkJYnJlYWs7DQotCQljYXNlIFBCU19CRVZFTEVEOg0KLQkJY2FzZSBQQlNfSU5TRVQ6CQ0KLQkJCXsNCi0JCQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JCQkJZ3NkLm1fTGluZVdpZHRoID0gZkhhbGZXaWR0aDsNCi0NCi0JCQkJQ0ZYX1BhdGhEYXRhIHBhdGhMVDsNCi0NCi0JCQkJcGF0aExULlNldFBvaW50Q291bnQoNyk7DQotCQkJCXBhdGhMVC5TZXRQb2ludCgwLCBmTGVmdCArIGZIYWxmV2lkdGgsIGZCb3R0b20gKyBmSGFsZldpZHRoLCBGWFBUX01PVkVUTyk7DQotCQkJCXBhdGhMVC5TZXRQb2ludCgxLCBmTGVmdCArIGZIYWxmV2lkdGgsIGZUb3AgLSBmSGFsZldpZHRoLCBGWFBUX0xJTkVUTyk7DQotCQkJCXBhdGhMVC5TZXRQb2ludCgyLCBmUmlnaHQgLSBmSGFsZldpZHRoLCBmVG9wIC0gZkhhbGZXaWR0aCwgRlhQVF9MSU5FVE8pOw0KLQkJCQlwYXRoTFQuU2V0UG9pbnQoMywgZlJpZ2h0IC0gZkhhbGZXaWR0aCAqIDIsIGZUb3AgLSBmSGFsZldpZHRoICogMiwgRlhQVF9MSU5FVE8pOw0KLQkJCQlwYXRoTFQuU2V0UG9pbnQoNCwgZkxlZnQgKyBmSGFsZldpZHRoICogMiwgZlRvcCAtIGZIYWxmV2lkdGggKiAyLCBGWFBUX0xJTkVUTyk7DQotCQkJCXBhdGhMVC5TZXRQb2ludCg1LCBmTGVmdCArIGZIYWxmV2lkdGggKiAyLCBmQm90dG9tICsgZkhhbGZXaWR0aCAqIDIsIEZYUFRfTElORVRPKTsNCi0JCQkJcGF0aExULlNldFBvaW50KDYsIGZMZWZ0ICsgZkhhbGZXaWR0aCwgZkJvdHRvbSArIGZIYWxmV2lkdGgsIEZYUFRfTElORVRPKTsNCi0NCi0JCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGhMVCwgcFVzZXIyRGV2aWNlLCAmZ3NkLCBQV0xDb2xvclRvRlhDb2xvcihjckxlZnRUb3AsblRyYW5zcGFyYW5jeSksIDAsIEZYRklMTF9BTFRFUk5BVEUpOw0KLQ0KLQkJCQlDRlhfUGF0aERhdGEgcGF0aFJCOw0KLQ0KLQkJCQlwYXRoUkIuU2V0UG9pbnRDb3VudCg3KTsNCi0JCQkJcGF0aFJCLlNldFBvaW50KDAsIGZSaWdodCAtIGZIYWxmV2lkdGgsIGZUb3AgLSBmSGFsZldpZHRoLCBGWFBUX01PVkVUTyk7DQotCQkJCXBhdGhSQi5TZXRQb2ludCgxLCBmUmlnaHQgLSBmSGFsZldpZHRoLCBmQm90dG9tICsgZkhhbGZXaWR0aCwgRlhQVF9MSU5FVE8pOw0KLQkJCQlwYXRoUkIuU2V0UG9pbnQoMiwgZkxlZnQgKyBmSGFsZldpZHRoLCBmQm90dG9tICsgZkhhbGZXaWR0aCwgRlhQVF9MSU5FVE8pOw0KLQkJCQlwYXRoUkIuU2V0UG9pbnQoMywgZkxlZnQgKyBmSGFsZldpZHRoICogMiwgZkJvdHRvbSArIGZIYWxmV2lkdGggKiAyLCBGWFBUX0xJTkVUTyk7DQotCQkJCXBhdGhSQi5TZXRQb2ludCg0LCBmUmlnaHQgLSBmSGFsZldpZHRoICogMiwgZkJvdHRvbSArIGZIYWxmV2lkdGggKiAyLCBGWFBUX0xJTkVUTyk7DQotCQkJCXBhdGhSQi5TZXRQb2ludCg1LCBmUmlnaHQgLSBmSGFsZldpZHRoICogMiwgZlRvcCAtIGZIYWxmV2lkdGggKiAyLCBGWFBUX0xJTkVUTyk7DQotCQkJCXBhdGhSQi5TZXRQb2ludCg2LCBmUmlnaHQgLSBmSGFsZldpZHRoLCBmVG9wIC0gZkhhbGZXaWR0aCwgRlhQVF9MSU5FVE8pOw0KLQ0KLQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aFJCLCBwVXNlcjJEZXZpY2UsICZnc2QsIFBXTENvbG9yVG9GWENvbG9yKGNyUmlnaHRCb3R0b20sblRyYW5zcGFyYW5jeSksIDAsIEZYRklMTF9BTFRFUk5BVEUpOw0KLQ0KLQkJCQlDRlhfUGF0aERhdGEgcGF0aDsNCi0NCi0JCQkJcGF0aC5BcHBlbmRSZWN0KGZMZWZ0LCBmQm90dG9tLCBmUmlnaHQsIGZUb3ApOw0KLQkJCQlwYXRoLkFwcGVuZFJlY3QoZkxlZnQgKyBmSGFsZldpZHRoLCBmQm90dG9tICsgZkhhbGZXaWR0aCwgZlJpZ2h0IC0gZkhhbGZXaWR0aCwgZlRvcCAtIGZIYWxmV2lkdGgpOw0KLQ0KLQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLCBQV0xDb2xvclRvRlhDb2xvcihjb2xvcixuVHJhbnNwYXJhbmN5KSwgMCwgRlhGSUxMX0FMVEVSTkFURSk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQQlNfVU5ERVJMSU5FRDoNCi0JCQl7DQotCQkJCUNGWF9QYXRoRGF0YSBwYXRoOw0KLQ0KLQkJCQlwYXRoLlNldFBvaW50Q291bnQoMik7DQotCQkJCXBhdGguU2V0UG9pbnQoMCwgZkxlZnQsIGZCb3R0b20gKyBmV2lkdGggLyAyLCBGWFBUX01PVkVUTyk7DQotCQkJCXBhdGguU2V0UG9pbnQoMSwgZlJpZ2h0LCBmQm90dG9tICsgZldpZHRoIC8gMiwgRlhQVF9MSU5FVE8pOw0KLQkJCQkNCi0JCQkJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsNCi0JCQkJZ3NkLm1fTGluZVdpZHRoID0gZldpZHRoOw0KLQ0KLQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLDAsICBQV0xDb2xvclRvRlhDb2xvcihjb2xvcixuVHJhbnNwYXJhbmN5KSwgRlhGSUxMX0FMVEVSTkFURSk7DQotCQkJfQ0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQQlNfU0hBRE9XOg0KLQkJCXsNCi0JCQkJQ0ZYX1BhdGhEYXRhIHBhdGg7DQotCQkJCXBhdGguQXBwZW5kUmVjdChmTGVmdCwgZkJvdHRvbSwgZlJpZ2h0LCBmVG9wKTsNCi0JCQkJcGF0aC5BcHBlbmRSZWN0KGZMZWZ0ICsgZldpZHRoLCBmQm90dG9tICsgZldpZHRoLCBmUmlnaHQgLSBmV2lkdGgsIGZUb3AgLSBmV2lkdGgpOw0KLQkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCBQV0xDb2xvclRvRlhDb2xvcihjb2xvcixuVHJhbnNwYXJhbmN5LzIpLCAwLCBGWEZJTExfQUxURVJOQVRFKTsNCi0JCQl9DQotCQkJYnJlYWs7DQotCQl9DQotCX0NCi19DQotDQotc3RhdGljIHZvaWQgQWRkU3F1aWdnbHlQYXRoKENGWF9QYXRoRGF0YSAmIFBhdGhEYXRhLCBGWF9GTE9BVCBmU3RhcnRYLCBGWF9GTE9BVCBmRW5kWCwgRlhfRkxPQVQgZlksIEZYX0ZMT0FUIGZTdGVwKQ0KLXsNCi0JUGF0aERhdGEuQWRkUG9pbnRDb3VudCgxKTsNCi0JUGF0aERhdGEuU2V0UG9pbnQoUGF0aERhdGEuR2V0UG9pbnRDb3VudCgpIC0gMSwgZlN0YXJ0WCwgZlksIEZYUFRfTU9WRVRPKTsNCi0NCi0JRlhfRkxPQVQgZng7DQotCUZYX0lOVDMyIGk7DQotDQotCWZvciAoaT0xLGZ4PWZTdGFydFgrZlN0ZXA7IGZ4PGZFbmRYOyBmeCs9ZlN0ZXAsaSsrKQ0KLQl7DQotCQlQYXRoRGF0YS5BZGRQb2ludENvdW50KDEpOw0KLQkJUGF0aERhdGEuU2V0UG9pbnQoUGF0aERhdGEuR2V0UG9pbnRDb3VudCgpIC0gMSwgZngsIGZZICsgKGkmMSkqZlN0ZXAsIEZYUFRfTElORVRPKTsNCi0JfQ0KLX0NCi0NCi1zdGF0aWMgdm9pZCBBZGRTcGVsbENoZWNrT2JqKENGWF9QYXRoRGF0YSAmIFBhdGhEYXRhLCBJRlhfRWRpdCogcEVkaXQsIGNvbnN0IENQVlRfV29yZFJhbmdlJiB3cldvcmQpDQotew0KLQlGWF9GTE9BVCBmU3RhcnRYID0gMC4wZjsNCi0JRlhfRkxPQVQgZkVuZFggPSAwLjBmOw0KLQlGWF9GTE9BVCBmWSA9IDAuMGY7DQotCUZYX0ZMT0FUIGZTdGVwID0gMC4wZjsgDQotDQotCUZYX0JPT0wgYkJyZWFrID0gRkFMU0U7DQotDQotCWlmIChJRlhfRWRpdF9JdGVyYXRvciogcEl0ZXJhdG9yID0gcEVkaXQtPkdldEl0ZXJhdG9yKCkpDQotCXsNCi0JCXBJdGVyYXRvci0+U2V0QXQod3JXb3JkLkJlZ2luUG9zKTsNCi0NCi0JCWRvDQotCQl7DQotCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7DQotDQotCQkJQ1BWVF9MaW5lIGxpbmU7CQkJCQ0KLQkJCWlmIChwSXRlcmF0b3ItPkdldExpbmUobGluZSkpDQotCQkJew0KLQkJCQlmWSA9IGxpbmUucHRMaW5lLnk7DQotCQkJCWZTdGVwID0gKGxpbmUuZkxpbmVBc2NlbnQgLSBsaW5lLmZMaW5lRGVzY2VudCkgLyAxNi4wZjsNCi0JCQl9DQotDQotCQkJaWYgKHBsYWNlLkxpbmVDbXAod3JXb3JkLkJlZ2luUG9zKSA9PSAwKQ0KLQkJCXsNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdCh3cldvcmQuQmVnaW5Qb3MpOw0KLQkJCQlDUFZUX1dvcmQgd29yZDsNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJew0KLQkJCQkJZlN0YXJ0WCA9IHdvcmQucHRXb3JkLng7DQotCQkJCX0NCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJZlN0YXJ0WCA9IGxpbmUucHRMaW5lLng7DQotCQkJfQ0KLQ0KLQkJCWlmIChwbGFjZS5MaW5lQ21wKHdyV29yZC5FbmRQb3MpID09IDApDQotCQkJew0KLQkJCQlwSXRlcmF0b3ItPlNldEF0KHdyV29yZC5FbmRQb3MpOw0KLQkJCQlDUFZUX1dvcmQgd29yZDsNCi0JCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkNCi0JCQkJew0KLQkJCQkJZkVuZFggPSB3b3JkLnB0V29yZC54ICsgd29yZC5mV2lkdGg7DQotCQkJCX0NCi0NCi0JCQkJYkJyZWFrID0gVFJVRTsNCi0JCQl9DQotCQkJZWxzZQ0KLQkJCXsNCi0JCQkJZkVuZFggPSBsaW5lLnB0TGluZS54ICsgbGluZS5mTGluZVdpZHRoOw0KLQkJCX0NCi0NCi0JCQlBZGRTcXVpZ2dseVBhdGgoUGF0aERhdGEsIGZTdGFydFgsIGZFbmRYLCBmWSwgZlN0ZXApOw0KLQ0KLQkJCWlmIChiQnJlYWspIGJyZWFrOw0KLQkJfQ0KLQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dExpbmUoKSk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpEcmF3RWRpdFNwZWxsQ2hlY2soQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwgSUZYX0VkaXQqIHBFZGl0LCANCi0JCQkJCQljb25zdCBDUERGX1JlY3QmIHJjQ2xpcCwgY29uc3QgQ1BERl9Qb2ludCYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlKiBwUmFuZ2UsIA0KLQkJCQkJCUlQV0xfU3BlbGxDaGVjayAqIHBTcGVsbENoZWNrKQ0KLXsNCi0JY29uc3QgRlhfQ09MT1JSRUYgY3JTcGVsbCA9IEFyZ2JFbmNvZGUoMjU1LDI1NSwwLDApOw0KLQ0KLQkvL2ZvciBzcGVsbGNoZWNrDQotCUZYX0JPT0wgYkxhdGluV29yZCA9IEZBTFNFOw0KLQlDUFZUX1dvcmRQbGFjZSB3cFdvcmRTdGFydDsNCi0JQ0ZYX0J5dGVTdHJpbmcgc0xhdGluV29yZDsNCi0NCi0JQ0ZYX1BhdGhEYXRhIHBhdGhTcGVsbDsNCi0NCi0JcERldmljZS0+U2F2ZVN0YXRlKCk7DQotDQotCWlmICghcmNDbGlwLklzRW1wdHkoKSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjVGVtcCA9IHJjQ2xpcDsNCi0JCXBVc2VyMkRldmljZS0+VHJhbnNmb3JtUmVjdChyY1RlbXApOw0KLQkJRlhfUkVDVCByY0RldkNsaXA7DQotCQlyY0RldkNsaXAubGVmdCA9IChGWF9JTlQzMilyY1RlbXAubGVmdDsNCi0JCXJjRGV2Q2xpcC5yaWdodCA9IChGWF9JTlQzMilyY1RlbXAucmlnaHQ7DQotCQlyY0RldkNsaXAudG9wID0gKEZYX0lOVDMyKXJjVGVtcC50b3A7DQotCQlyY0RldkNsaXAuYm90dG9tID0gKEZYX0lOVDMyKXJjVGVtcC5ib3R0b207DQotCQlwRGV2aWNlLT5TZXRDbGlwX1JlY3QoJnJjRGV2Q2xpcCk7DQotCX0NCi0NCi0JaWYgKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IgPSBwRWRpdC0+R2V0SXRlcmF0b3IoKSkNCi0Jew0KLQkJaWYgKHBFZGl0LT5HZXRGb250TWFwKCkpDQotCQl7DQotCQkJaWYgKHBSYW5nZSkNCi0JCQkJcEl0ZXJhdG9yLT5TZXRBdChwUmFuZ2UtPkJlZ2luUG9zKTsNCi0JCQllbHNlDQotCQkJCXBJdGVyYXRvci0+U2V0QXQoMCk7DQotDQotCQkJQ1BWVF9Xb3JkUGxhY2Ugb2xkcGxhY2U7CQkJDQotDQotCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkNCi0JCQl7DQotCQkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOw0KLQkJCQlpZiAocFJhbmdlICYmIHBsYWNlLldvcmRDbXAocFJhbmdlLT5FbmRQb3MpID4gMCkgYnJlYWs7CQkJCQ0KLQ0KLQkJCQlDUFZUX1dvcmQgd29yZDsJCQkJDQotCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpDQotCQkJCXsNCi0JCQkJCWlmIChGWF9FRElUX0lTTEFUSU5XT1JEKHdvcmQuV29yZCkpDQotCQkJCQl7DQotCQkJCQkJaWYgKCFiTGF0aW5Xb3JkKQ0KLQkJCQkJCXsNCi0JCQkJCQkJd3BXb3JkU3RhcnQgPSBwbGFjZTsNCi0JCQkJCQkJYkxhdGluV29yZCA9IFRSVUU7CQkJCQkJCQkNCi0JCQkJCQl9DQotDQotCQkJCQkJc0xhdGluV29yZCArPSAoY2hhcil3b3JkLldvcmQ7DQotCQkJCQl9DQotCQkJCQllbHNlDQotCQkJCQl7DQotCQkJCQkJaWYgKGJMYXRpbldvcmQpDQotCQkJCQkJew0KLQkJCQkJCQlpZiAoIXNMYXRpbldvcmQuSXNFbXB0eSgpKQ0KLQkJCQkJCQl7DQotCQkJCQkJCQlpZiAocFNwZWxsQ2hlY2sgJiYgIXBTcGVsbENoZWNrLT5DaGVja1dvcmQoc0xhdGluV29yZCkpDQotCQkJCQkJCQl7DQotCQkJCQkJCQkJQWRkU3BlbGxDaGVja09iaihwYXRoU3BlbGwscEVkaXQsQ1BWVF9Xb3JkUmFuZ2Uod3BXb3JkU3RhcnQsb2xkcGxhY2UpKTsJCQkJCQkJCQkNCi0JCQkJCQkJCQlwSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsNCi0JCQkJCQkJCX0NCi0JCQkJCQkJfQ0KLQkJCQkJCQliTGF0aW5Xb3JkID0gRkFMU0U7DQotCQkJCQkJfQ0KLQ0KLQkJCQkJCXNMYXRpbldvcmQuRW1wdHkoKTsNCi0JCQkJCX0NCi0JCQkJCQ0KLQkJCQkJb2xkcGxhY2UgPSBwbGFjZTsNCi0JCQkJfQ0KLQkJCQllbHNlDQotCQkJCXsNCi0JCQkJCWlmIChiTGF0aW5Xb3JkKQ0KLQkJCQkJew0KLQkJCQkJCWlmICghc0xhdGluV29yZC5Jc0VtcHR5KCkpDQotCQkJCQkJew0KLQkJCQkJCQlpZiAocFNwZWxsQ2hlY2sgJiYgIXBTcGVsbENoZWNrLT5DaGVja1dvcmQoc0xhdGluV29yZCkpDQotCQkJCQkJCXsNCi0JCQkJCQkJCUFkZFNwZWxsQ2hlY2tPYmoocGF0aFNwZWxsLHBFZGl0LENQVlRfV29yZFJhbmdlKHdwV29yZFN0YXJ0LG9sZHBsYWNlKSk7CQkJCQkJCQkJDQotCQkJCQkJCQlwSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsNCi0JCQkJCQkJfQ0KLQkJCQkJCX0NCi0JCQkJCQliTGF0aW5Xb3JkID0gRkFMU0U7DQotCQkJCQl9DQotDQotCQkJCQlzTGF0aW5Xb3JkLkVtcHR5KCk7DQotCQkJCX0NCi0JCQl9DQotDQotCQkJaWYgKCFzTGF0aW5Xb3JkLklzRW1wdHkoKSkgDQotCQkJew0KLQkJCQlpZiAocFNwZWxsQ2hlY2sgJiYgIXBTcGVsbENoZWNrLT5DaGVja1dvcmQoc0xhdGluV29yZCkpDQotCQkJCXsNCi0JCQkJCUFkZFNwZWxsQ2hlY2tPYmoocGF0aFNwZWxsLHBFZGl0LENQVlRfV29yZFJhbmdlKHdwV29yZFN0YXJ0LG9sZHBsYWNlKSk7CQ0KLQkJCQl9DQotCQkJfQ0KLQkJfQ0KLQl9DQotCQ0KLQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOw0KLQlnc2QubV9MaW5lV2lkdGggPSAwOw0KLQlpZiAocGF0aFNwZWxsLkdldFBvaW50Q291bnQoKSA+IDApDQotCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aFNwZWxsLCBwVXNlcjJEZXZpY2UsICZnc2QsIDAsIGNyU3BlbGwsIEZYRklMTF9BTFRFUk5BVEUpOw0KLQ0KLQlwRGV2aWNlLT5SZXN0b3JlU3RhdGUoKTsNCi19DQotDQotRlhfQk9PTCBDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikNCi17DQotCXN3aXRjaCAoY29sb3IubkNvbG9yVHlwZSkNCi0Jew0KLQljYXNlIENPTE9SVFlQRV9UUkFOU1BBUkVOVDoNCi0JCXJldHVybiBGQUxTRTsNCi0JY2FzZSBDT0xPUlRZUEVfR1JBWToNCi0JCXJldHVybiBjb2xvci5mQ29sb3IxIDwgMC41ZjsNCi0JY2FzZSBDT0xPUlRZUEVfUkdCOg0KLQkJcmV0dXJuIGNvbG9yLmZDb2xvcjEgKyBjb2xvci5mQ29sb3IyICsgY29sb3IuZkNvbG9yMyA8IDEuNWY7DQotCWNhc2UgQ09MT1JUWVBFX0NNWUs6DQotCQlyZXR1cm4gY29sb3IuZkNvbG9yMSArIGNvbG9yLmZDb2xvcjIgKyBjb2xvci5mQ29sb3IzICsgY29sb3IuZkNvbG9yNCA+IDIuMGY7DQotCX0NCi0NCi0JcmV0dXJuIFRSVUU7DQotfQ0KLQ0KLUNQV0xfQ29sb3IgQ1BXTF9VdGlsczo6R2V0UmV2ZXJzZUNvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQ0KLXsNCi0JQ1BXTF9Db2xvciBjclJldCA9IGNvbG9yOw0KLQ0KLQlzd2l0Y2ggKGNvbG9yLm5Db2xvclR5cGUpDQotCXsNCi0JY2FzZSBDT0xPUlRZUEVfR1JBWToNCi0JCWNyUmV0LmZDb2xvcjEgPSAxLjBmIC0gY3JSZXQuZkNvbG9yMTsNCi0JCWJyZWFrOw0KLQljYXNlIENPTE9SVFlQRV9SR0I6DQotCQljclJldC5mQ29sb3IxID0gMS4wZiAtIGNyUmV0LmZDb2xvcjE7DQotCQljclJldC5mQ29sb3IyID0gMS4wZiAtIGNyUmV0LmZDb2xvcjI7DQotCQljclJldC5mQ29sb3IzID0gMS4wZiAtIGNyUmV0LmZDb2xvcjM7DQotCQlicmVhazsNCi0JY2FzZSBDT0xPUlRZUEVfQ01ZSzoNCi0JCWNyUmV0LmZDb2xvcjEgPSAxLjBmIC0gY3JSZXQuZkNvbG9yMTsNCi0JCWNyUmV0LmZDb2xvcjIgPSAxLjBmIC0gY3JSZXQuZkNvbG9yMjsNCi0JCWNyUmV0LmZDb2xvcjMgPSAxLjBmIC0gY3JSZXQuZkNvbG9yMzsNCi0JCWNyUmV0LmZDb2xvcjQgPSAxLjBmIC0gY3JSZXQuZkNvbG9yNDsNCi0JCWJyZWFrOw0KLQl9DQotDQotCXJldHVybiBjclJldDsNCi19DQotDQotQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0SWNvbkFwcFN0cmVhbShGWF9JTlQzMiBuVHlwZSwgY29uc3QgQ1BERl9SZWN0JiByZWN0LCBjb25zdCBDUFdMX0NvbG9yJiBjckZpbGwsIA0KLQkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3ImIGNyU3Ryb2tlKQ0KLXsNCi0JQ0ZYX0J5dGVTdHJpbmcgc0FwcFN0cmVhbSA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyU3Ryb2tlLCBGQUxTRSk7DQotCXNBcHBTdHJlYW0gKz0gQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JGaWxsLCBUUlVFKTsNCi0NCi0JQ0ZYX0J5dGVTdHJpbmcgc1BhdGg7DQotCUNGWF9QYXRoRGF0YSBwYXRoOw0KLQ0KLQlzd2l0Y2ggKG5UeXBlKQ0KLQl7DQotCWNhc2UgUFdMX0lDT05UWVBFX0NIRUNLTUFSSzoNCi0JCUdldEdyYXBoaWNzX0NoZWNrbWFyayhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsJDQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfQ0lSQ0xFOg0KLQkJR2V0R3JhcGhpY3NfQ2lyY2xlKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX0NPTU1FTlQ6DQotCQlHZXRHcmFwaGljc19Db21tZW50KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX0NST1NTOg0KLQkJR2V0R3JhcGhpY3NfQ3Jvc3Moc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfSEVMUDoNCi0JCUdldEdyYXBoaWNzX0hlbHAoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfSU5TRVJUVEVYVDoNCi0JCUdldEdyYXBoaWNzX0luc2VydFRleHQoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfS0VZOg0KLQkJR2V0R3JhcGhpY3NfS2V5KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX05FV1BBUkFHUkFQSDoNCi0JCUdldEdyYXBoaWNzX05ld1BhcmFncmFwaChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9URVhUTk9URToNCi0JCUdldEdyYXBoaWNzX1RleHROb3RlKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX1BBUkFHUkFQSDoNCi0JCUdldEdyYXBoaWNzX1BhcmFncmFwaChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9SSUdIVEFSUk9XOg0KLQkJR2V0R3JhcGhpY3NfUmlnaHRBcnJvdyhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9SSUdIVFBPSU5URVI6DQotCQlHZXRHcmFwaGljc19SaWdodFBvaW50ZXIoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfU1RBUjoNCi0JCUdldEdyYXBoaWNzX1N0YXIoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfVVBBUlJPVzoNCi0JCUdldEdyYXBoaWNzX1VwQXJyb3coc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfVVBMRUZUQVJST1c6DQotCQlHZXRHcmFwaGljc19VcExlZnRBcnJvdyhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9HUkFQSDoNCi0JCUdldEdyYXBoaWNzX0dyYXBoKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX1BBUEVSQ0xJUDoNCi0JCUdldEdyYXBoaWNzX1BhcGVyY2xpcChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9BVFRBQ0hNRU5UOg0KLQkJR2V0R3JhcGhpY3NfQXR0YWNobWVudChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9UQUc6DQotCQlHZXRHcmFwaGljc19UYWcoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfRk9YSVQ6DQotCQlHZXRHcmFwaGljc19Gb3hpdChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsNCi0JCWJyZWFrOw0KLQl9DQotDQotCXNBcHBTdHJlYW0gKz0gc1BhdGg7DQotCWlmIChjclN0cm9rZS5uQ29sb3JUeXBlICE9IENPTE9SVFlQRV9UUkFOU1BBUkVOVCkNCi0JCXNBcHBTdHJlYW0gKz0gIkIqXG4iOw0KLQllbHNlDQotCQlzQXBwU3RyZWFtICs9ICJmKlxuIjsNCi0NCi0JcmV0dXJuIHNBcHBTdHJlYW07DQotfQ0KLQ0KLXZvaWQgQ1BXTF9VdGlsczo6RHJhd0ljb25BcHBTdHJlYW0oQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwNCi0JCQkJCQlGWF9JTlQzMiBuVHlwZSwgY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgY29uc3QgQ1BXTF9Db2xvciYgY3JGaWxsLCBjb25zdCBDUFdMX0NvbG9yJiBjclN0cm9rZSwgY29uc3QgRlhfSU5UMzIgblRyYW5zcGFyYW5jeSkNCi17DQotCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7DQotCWdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7DQotDQotCUNGWF9CeXRlU3RyaW5nIHNQYXRoOw0KLQlDRlhfUGF0aERhdGEgcGF0aDsNCi0NCi0Jc3dpdGNoIChuVHlwZSkNCi0Jew0KLQljYXNlIFBXTF9JQ09OVFlQRV9DSEVDS01BUks6DQotCQlHZXRHcmFwaGljc19DaGVja21hcmsoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9DSVJDTEU6DQotCQlHZXRHcmFwaGljc19DaXJjbGUoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9DT01NRU5UOg0KLQkJR2V0R3JhcGhpY3NfQ29tbWVudChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX0NST1NTOg0KLQkJR2V0R3JhcGhpY3NfQ3Jvc3Moc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9IRUxQOg0KLQkJR2V0R3JhcGhpY3NfSGVscChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX0lOU0VSVFRFWFQ6DQotCQlHZXRHcmFwaGljc19JbnNlcnRUZXh0KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfS0VZOg0KLQkJR2V0R3JhcGhpY3NfS2V5KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfTkVXUEFSQUdSQVBIOg0KLQkJR2V0R3JhcGhpY3NfTmV3UGFyYWdyYXBoKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfVEVYVE5PVEU6DQotCQlHZXRHcmFwaGljc19UZXh0Tm90ZShzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX1BBUkFHUkFQSDoNCi0JCUdldEdyYXBoaWNzX1BhcmFncmFwaChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX1JJR0hUQVJST1c6DQotCQlHZXRHcmFwaGljc19SaWdodEFycm93KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfUklHSFRQT0lOVEVSOg0KLQkJR2V0R3JhcGhpY3NfUmlnaHRQb2ludGVyKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfU1RBUjoNCi0JCUdldEdyYXBoaWNzX1N0YXIoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9VUEFSUk9XOg0KLQkJR2V0R3JhcGhpY3NfVXBBcnJvdyhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOw0KLQkJYnJlYWs7DQotCWNhc2UgUFdMX0lDT05UWVBFX1VQTEVGVEFSUk9XOg0KLQkJR2V0R3JhcGhpY3NfVXBMZWZ0QXJyb3coc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9HUkFQSDoNCi0JCUdldEdyYXBoaWNzX0dyYXBoKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfUEFQRVJDTElQOg0KLQkJR2V0R3JhcGhpY3NfUGFwZXJjbGlwKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7DQotCQlicmVhazsNCi0JY2FzZSBQV0xfSUNPTlRZUEVfQVRUQUNITUVOVDoNCi0JCUdldEdyYXBoaWNzX0F0dGFjaG1lbnQoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9UQUc6DQotCQlHZXRHcmFwaGljc19UYWcoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBXTF9JQ09OVFlQRV9GT1hJVDoNCi0JCUdldEdyYXBoaWNzX0ZveGl0KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7DQotCQlicmVhazsNCi0JZGVmYXVsdDoNCi0JCXJldHVybjsNCi0JfQ0KLQ0KLQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLCANCi0JCVBXTENvbG9yVG9GWENvbG9yKGNyRmlsbCxuVHJhbnNwYXJhbmN5KSwgUFdMQ29sb3JUb0ZYQ29sb3IoY3JTdHJva2UsblRyYW5zcGFyYW5jeSksIEZYRklMTF9BTFRFUk5BVEUpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0NoZWNrbWFyayhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpDQotew0KLQlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOw0KLQ0KLQlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gDQotCXsNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCAgKyBmV2lkdGggLyAxNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAyIC8gNS4wZiksUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCAgKyBmV2lkdGggLyAxNS4wZiArIFBXTF9CRVpJRVIqKGZXaWR0aCAvIDcuMGYgLSBmV2lkdGggLyAxNS4wZiksIA0KLQkJCQkJICBjckJCb3guYm90dG9tICsgZkhlaWdodCAqIDIgLyA1LjBmICsgUFdMX0JFWklFUiooZkhlaWdodCAqIDIgLyA3LjBmIC0gZkhlaWdodCAqIDIgLyA1LjBmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCAvIDQuNWYgKyBQV0xfQkVaSUVSKihmV2lkdGggLyA1LjBmIC0gZldpZHRoIC8gNC41ZiksDQotCQkJCQkgIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0IC8gMTYuMGYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0IC8gNS4wZiAtIGZIZWlnaHQgLyAxNi4wZikpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGggLyA0LjVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDE2LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gNC41ZiArIFBXTF9CRVpJRVIqKGZXaWR0aCAvIDQuNGYgLSBmV2lkdGggLyA0LjVmKSwNCi0JCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgLyAxNi4wZiAtIFBXTF9CRVpJRVIqZkhlaWdodCAvIDE2LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gMy4wZiArIFBXTF9CRVpJRVIqKGZXaWR0aCAvIDQuMGYgLSBmV2lkdGggLyAzLjBmKSwNCi0JCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCAvIDMuMGYsIGNyQkJveC5ib3R0b20pLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGggLyAzLjBmICsgUFdMX0JFWklFUipmV2lkdGgqKDEvNy4wZiArIDIvMTUuMGYpLA0KLQkJICAgICAgICAgICAgICBjckJCb3guYm90dG9tICsgUFdMX0JFWklFUipmSGVpZ2h0ICogNCAvIDUuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgICsgZldpZHRoICogMTQgLyAxNS4wZiArIFBXTF9CRVpJRVIqZldpZHRoKigxLzcuMGYgLSA3LzE1LjBmKSwNCi0JCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAxNS8xNi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQgKiA0LzUuMGYgLSBmSGVpZ2h0ICogMTUvMTYuMGYpKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICArIGZXaWR0aCAqIDE0IC8gMTUuMGYsY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAxNSAvIDE2LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICArIGZXaWR0aCAqIDE0IC8gMTUuMGYgKyBQV0xfQkVaSUVSKihmV2lkdGggKiA3IC8gMTUuMGYgLSBmV2lkdGggKiAxNCAvIDE1LjBmKSwNCi0JCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAxNSAvIDE2LjBmICsgUFdMX0JFWklFUiooZkhlaWdodCAqIDggLyA3LjBmIC0gZkhlaWdodCAqIDE1IC8gMTYuMGYpKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gMy42ZiArIFBXTF9CRVpJRVIqKGZXaWR0aCAvIDMuNGYgLSBmV2lkdGggLyAzLjZmKSwNCi0JCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgLyAzLjVmICsgUFdMX0JFWklFUiooZkhlaWdodCAvIDMuNWYgLSBmSGVpZ2h0IC8gMy41ZikpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGggLyAzLjZmLGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0IC8gMy41ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCAvIDMuNmYsDQotCQkgICAgICAgICAgICAgIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0IC8gMy41ZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQgLyA0LjBmIC0gZkhlaWdodCAvIDMuNWYpKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICArIGZXaWR0aCAvIDE1LjBmICsgUFdMX0JFWklFUiooZldpZHRoIC8gMy41ZiAtIGZXaWR0aCAvIDE1LjBmKSwNCi0JCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAyIC8gNS4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQgKiAzLjVmIC8gNS4wZiAtIGZIZWlnaHQgKiAyIC8gNS4wZikpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgICsgZldpZHRoIC8gMTUuMGYsY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAyIC8gNS4wZiksIFBXTFBUX0JFWklFUlRPKQ0KLQl9Ow0KLQ0KLQlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkNCi0JCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDE2KTsNCi0JZWxzZQ0KLQkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAxNik7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9VdGlsczo6R2V0R3JhcGhpY3NfQ2lyY2xlKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkNCi17DQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPQ0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTUuMGYsY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTUuMGYsDQotCQkgICAgICAgICAgICAgIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0KjE0LzE1LjBmIC0gZkhlaWdodC8yLjBmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmIC0gUFdMX0JFWklFUiooZldpZHRoLzIuMGYgLSBmV2lkdGgvMTUuMGYpLCBjckJCb3gudG9wIC0gZkhlaWdodC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYgKyBQV0xfQkVaSUVSKihmV2lkdGgqMTQvMTUuMGYgLSBmV2lkdGgvMi4wZiksIGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQqMTQvMTUuMGYgLSBmSGVpZ2h0LzIuMGYpKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgLSBQV0xfQkVaSUVSKihmSGVpZ2h0LzIuMGYgLSBmSGVpZ2h0LzE1LjBmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmICsgUFdMX0JFWklFUiooZldpZHRoKjE0LzE1LjBmIC0gZldpZHRoLzIuMGYpLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmIC0gUFdMX0JFWklFUiooZldpZHRoLzIuMGYgLSBmV2lkdGgvMTUuMGYpLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiAtIFBXTF9CRVpJRVIqKGZIZWlnaHQvMi4wZiAtIGZIZWlnaHQvMTUuMGYpKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzE1LjBmLGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMy8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMy8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQqNC81LjBmIC0gZkhlaWdodC8yLjBmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmIC0gUFdMX0JFWklFUiooZldpZHRoLzIuMGYgLSBmV2lkdGgqMy8xNS4wZiksIGNyQkJveC50b3AgLSBmSGVpZ2h0KjMvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMy8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmICsgUFdMX0JFWklFUiooZldpZHRoKjQvNS4wZiAtIGZXaWR0aC8yLjBmKSwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMy8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMy8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQqNC81LjBmIC0gZkhlaWdodC8yLjBmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMy8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMy8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiAtIFBXTF9CRVpJRVIqKGZIZWlnaHQqNC81LjBmIC0gZkhlaWdodC8yLjBmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmICsgUFdMX0JFWklFUiooZldpZHRoKjQvNS4wZiAtIGZXaWR0aC8yLjBmKSwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMy8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCozLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYgLSBQV0xfQkVaSUVSKihmV2lkdGgqNC81LjBmIC0gZldpZHRoLzIuMGYpLCBjckJCb3guYm90dG9tICsgZkhlaWdodCozLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjMvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgLSBQV0xfQkVaSUVSKihmSGVpZ2h0KjQvNS4wZiAtIGZIZWlnaHQvMi4wZikpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMy8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiksIFBXTFBUX0JFWklFUlRPKQ0KLQl9Ow0KLQ0KLQlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkNCi0JCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDI2KTsNCi0JZWxzZQ0KLQkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAyNik7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9VdGlsczo6R2V0R3JhcGhpY3NfQ29tbWVudChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpDQotew0KLQlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOw0KLQ0KLQlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gDQotCXsNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvNi4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzYuMGYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0LzYuMGYgLSBmSGVpZ2h0LzEwLjBmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCoyLzE1LjBmIC0gUFdMX0JFWklFUipmV2lkdGgvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCoyLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8xMC4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjIvMTUuMGYgKyBQV0xfQkVaSUVSKmZXaWR0aC8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTAuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC82ICsgUFdMX0JFWklFUiooZkhlaWdodC82LjBmIC0gZkhlaWdodC8xMC4wZikpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC82LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMy4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCo0LzE1LjBmICsgUFdMX0JFWklFUipmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCoyLzE1LjBmICsgUFdMX0JFWklFUipmV2lkdGgvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjIvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNS8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNS8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMi8xNSArIFBXTF9CRVpJRVIqZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjUvMTUuMGYgLSBQV0xfQkVaSUVSKmZXaWR0aCoyLzE1LjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjYvMzAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjIvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNy8zMC4wZiArIFBXTF9CRVpJRVIqZldpZHRoLzMwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjcvMzAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjIvMTUuMGYgKyBQV0xfQkVaSUVSKmZIZWlnaHQqMi8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCo3LzMwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCo0LzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUuMGYgLSBQV0xfQkVaSUVSKmZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMy4wZiAtIFBXTF9CRVpJRVIqZkhlaWdodC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMy4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvNi4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMi8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqOC8zMC4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjIvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjgvMzAuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjI1LzYwLjBmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMi8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMjUvNjAuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqNC8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMTcvMzAuMGYpLCBQV0xQVF9MSU5FVE8pDQotCX07DQotDQotCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQ0KLQkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMzApOw0KLQllbHNlDQotCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDMwKTsNCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19Dcm9zcyhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpDQotew0KLQlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOw0KLQkvL0ZYX0ZMT0FUIGZjYXRlcmNvcm5lciA9IChGWF9GTE9BVClzcXJ0KGZXaWR0aCpmV2lkdGggKyBmSGVpZ2h0KmZIZWlnaHQpOw0KLQlDUFdMX1BvaW50IGNlbnRlcl9wb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yKTsNCi0NCi0JQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IA0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY2VudGVyX3BvaW50LngsIGNlbnRlcl9wb2ludC55ICsgZkhlaWdodC8xMC4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY2VudGVyX3BvaW50LnggKyBmV2lkdGgqMC4zZiwgY2VudGVyX3BvaW50LnkgKyBmSGVpZ2h0LzEwLjBmICsgZldpZHRoKjAuM2YpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54ICsgZldpZHRoLzEwLjBmICsgZldpZHRoKjAuM2YsIGNlbnRlcl9wb2ludC55ICsgZkhlaWdodCowLjNmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjZW50ZXJfcG9pbnQueCArIGZXaWR0aC8xMC4wZiwgY2VudGVyX3BvaW50LnkpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54ICsgZldpZHRoLzEwLjBmICsgZldpZHRoKjAuM2YsIGNlbnRlcl9wb2ludC55IC0gZkhlaWdodCowLjNmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjZW50ZXJfcG9pbnQueCArIGZXaWR0aCowLjNmLCBjZW50ZXJfcG9pbnQueSAtIGZIZWlnaHQvMTAuMGYgLSBmSGVpZ2h0KjAuM2YpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54LCBjZW50ZXJfcG9pbnQueSAtIGZIZWlnaHQvMTAuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54IC0gZldpZHRoKjAuM2YsIGNlbnRlcl9wb2ludC55IC0gZkhlaWdodC8xMCAtIGZIZWlnaHQqMC4zZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY2VudGVyX3BvaW50LnggLSBmV2lkdGgvMTAuMGYgLSBmV2lkdGgqMC4zZiwgY2VudGVyX3BvaW50LnkgLSBmSGVpZ2h0KjAuM2YpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54IC0gZldpZHRoLzEwLCBjZW50ZXJfcG9pbnQueSksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY2VudGVyX3BvaW50LnggLSBmV2lkdGgvMTAgLSBmV2lkdGgqMC4zZiwgY2VudGVyX3BvaW50LnkgKyBmSGVpZ2h0KjAuM2YpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54IC0gZldpZHRoKjAuM2YsIGNlbnRlcl9wb2ludC55ICsgZkhlaWdodC8xMC4wZiArIGZIZWlnaHQqMC4zZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY2VudGVyX3BvaW50LngsIGNlbnRlcl9wb2ludC55ICsgZkhlaWdodC8xMC4wZiksIFBXTFBUX0xJTkVUTykNCi0JfTsNCi0NCi0JaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pDQotCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAxMyk7DQotCWVsc2UNCi0JCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMTMpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0hlbHAoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQ0KLXsNCi0JRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7DQotCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsNCi0NCi0JQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IA0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNjAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmICsgUFdMX0JFWklFUiooZkhlaWdodC82MC4wZiAtIGZIZWlnaHQvMi4wZikpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiAtIFBXTF9CRVpJRVIqKGZXaWR0aC8yLjBmIC0gZldpZHRoLzYwLjBmKSwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvNjAuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvNjAuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiArIFBXTF9CRVpJRVIqZldpZHRoKjI5LzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC82MC4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvNjAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0LzYwLjBmIC0gZkhlaWdodC8yLjBmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvNjAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmICsgUFdMX0JFWklFUipmSGVpZ2h0KjI5LzYwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYgKyBQV0xfQkVaSUVSKmZXaWR0aCoyOS82MC4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvNjAuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvNjAuMGYpLCBQV0xQVF9CRVpJRVJUTyksCQkNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmIC0gUFdMX0JFWklFUipmV2lkdGgqMjkvNjAuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzYwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmICArIFBXTF9CRVpJRVIqZkhlaWdodCoyOS82MC4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC82MC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjI3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjdmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjM2ZiArIFBXTF9CRVpJRVIqZkhlaWdodCowLjIzZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjVmIC0gUFdMX0JFWklFUipmV2lkdGgqMC4yM2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuODdmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuODdmKSwgUFdMUFRfQkVaSUVSVE8pLAkJDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiArIFBXTF9CRVpJRVIqZldpZHRoKjAuMjNmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjg3ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4yN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmICsgUFdMX0JFWklFUipmSGVpZ2h0KjAuMjNmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjI3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMjdmIC0gZldpZHRoKjAuMDhmKjAuMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmIC0gZkhlaWdodCowLjE1ZiowLjdmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjM1ZiArIGZXaWR0aCowLjA4ZiowLjJmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjUxZiArIGZIZWlnaHQqMC4xNWYqMC4yZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4zNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNTFmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjM1ZiAtIGZXaWR0aCowLjFmKjAuNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNTFmIC0gZkhlaWdodCowLjE1ZiowLjNmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjQ1ZiAtIGZXaWR0aCowLjFmKjAuNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNjhmICsgZkhlaWdodCowLjE1ZiowLjVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjQ1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC42OGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNDVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjMwZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNDVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjMwZiAtIGZXaWR0aCowLjFmKjAuN2YpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjMwZiAtIGZXaWR0aCowLjFmKjAuN2YpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjMwZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41NWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNjZmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41NWYgLSBmV2lkdGgqMC4xZiowLjA1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC42NmYgKyBmSGVpZ2h0KjAuMThmKjAuNWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNDVmIC0gZldpZHRoKjAuMWYqMC4wNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNDhmIC0gZkhlaWdodCowLjE4ZiowLjNmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjQ1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC40OGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNDVmICsgZldpZHRoKjAuMDhmKjAuMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNDhmICsgZkhlaWdodCowLjE4ZiowLjJmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjM3ZiAtIGZXaWR0aCowLjA4ZiowLjJmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjM2ZiAtIGZIZWlnaHQqMC4xOGYqMC43ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4zN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjM3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYgKyBQV0xfQkVaSUVSKmZIZWlnaHQqMC4xM2YpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiArIFBXTF9CRVpJRVIqZldpZHRoKjAuMTNmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjc3ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjc3ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjVmIC0gUFdMX0JFWklFUipmV2lkdGgqMC4xM2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuNzdmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMzdmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjM2ZiArIFBXTF9CRVpJRVIqZkhlaWdodCowLjEzZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjM3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYpLCBQV0xQVF9CRVpJRVJUTyksCQkNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjM3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYgLSBmV2lkdGgqMC4xZiowLjZmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjdmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjM2ZiAtIGZXaWR0aCowLjFmKjAuNmYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmKSwgUFdMUFRfQkVaSUVSVE8pLAkJDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTZmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjEzZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTZmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjEzZiArIFBXTF9CRVpJRVIqZkhlaWdodCowLjA1NWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTA1ZiAtIFBXTF9CRVpJRVIqZldpZHRoKjAuMDk1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4xODVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjUwNWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTg1ZiksIFBXTFBUX0JFWklFUlRPKSwJCQ0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjUwNWYgKyBQV0xfQkVaSUVSKmZXaWR0aCowLjA2NWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTg1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC40NGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTNmICsgUFdMX0JFWklFUipmSGVpZ2h0KjAuMDU1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC40NGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTNmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjQ0ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4xM2YgLSBQV0xfQkVaSUVSKmZIZWlnaHQqMC4wNTVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjUwNWYgKyBQV0xfQkVaSUVSKmZXaWR0aCowLjA2NWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMDc1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41MDVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjA3NWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTA1ZiAtIFBXTF9CRVpJRVIqZldpZHRoKjAuMDY1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wNzVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjU2ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4xM2YgLSBQV0xfQkVaSUVSKmZIZWlnaHQqMC4wNTVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjU2ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4xM2YpLCBQV0xQVF9CRVpJRVJUTykNCi0JfTsNCi0NCi0JaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pDQotCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCA1OSk7DQotCWVsc2UNCi0JCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgNTkpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0luc2VydFRleHQoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQ0KLXsNCi0JRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7DQotCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsNCi0NCi0JQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IA0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTAsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLCBjckJCb3gudG9wIC0gZkhlaWdodCoyLzE1KSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTAsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xMCwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTApLCBQV0xQVF9MSU5FVE8pDQotCX07DQotDQotCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQ0KLQkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgNCk7DQotCWVsc2UNCi0JCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgNCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9VdGlsczo6R2V0R3JhcGhpY3NfS2V5KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkNCi17DQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotCUZYX0ZMT0FUIGsgPSAtZkhlaWdodC9mV2lkdGg7DQotCUNQV0xfUG9pbnQgdGFpbDsNCi0JQ1BXTF9Qb2ludCBDaWNsZUNlbnRlcjsNCi0JdGFpbC54ID0gY3JCQm94LmxlZnQgKyBmV2lkdGgqMC45ZjsNCi0JdGFpbC55ID0gayoodGFpbC54IC0gY3JCQm94LnJpZ2h0KSArIGNyQkJveC5ib3R0b207DQotCUNpY2xlQ2VudGVyLnggPSBjckJCb3gubGVmdCArIGZXaWR0aCowLjE1ZjsNCi0JQ2ljbGVDZW50ZXIueSA9IGsqKENpY2xlQ2VudGVyLnggLSBjckJCb3gucmlnaHQpICsgY3JCQm94LmJvdHRvbTsNCi0NCi0JQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IA0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwLjBmLCAtZldpZHRoLzMwLjBmL2sgKyB0YWlsLnkpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMC4wZiAtIGZXaWR0aCowLjE4ZiwgLWsqZldpZHRoKjAuMThmIC0gZldpZHRoLzMwL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCAtIGZXaWR0aCowLjE4ZiArIGZXaWR0aCowLjA3ZiwNCi0JCSAgICAgICAgICAgICAgLWZXaWR0aCowLjA3Zi9rIC0gaypmV2lkdGgqMC4xOGYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwIC0gZldpZHRoKjAuMThmIC0gZldpZHRoLzIwICsgZldpZHRoKjAuMDdmLA0KLQkJICAgICAgICAgICAgICAtZldpZHRoKjAuMDdmL2sgLSBrKmZXaWR0aC8yMCAtIGsqZldpZHRoKjAuMThmIC0gZldpZHRoLzMwL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCAtIGZXaWR0aCowLjE4ZiAtIGZXaWR0aC8yMCwNCi0JCSAgICAgICAgICAgICAgLWsqZldpZHRoLzIwIC0gaypmV2lkdGgqMC4xOGYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwIC0gZldpZHRoKjAuMThmIC0gZldpZHRoLzIwIC0gZldpZHRoLzE1LA0KLQkJICAgICAgICAgICAgICAtaypmV2lkdGgvMTUgLSBrKmZXaWR0aC8yMCAtIGsqZldpZHRoKjAuMThmIC0gZldpZHRoLzMwL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCAtIGZXaWR0aCowLjE4ZiAtIGZXaWR0aC8yMCAtIGZXaWR0aC8xNSArIGZXaWR0aCowLjA3ZiwNCi0JCSAgICAgICAgICAgICAgLWZXaWR0aCowLjA3Zi9rIC0gaypmV2lkdGgvMTUgLSBrKmZXaWR0aC8yMCAtIGsqZldpZHRoKjAuMThmIC0gZldpZHRoLzMwL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCAtIGZXaWR0aCowLjE4ZiAtIGZXaWR0aC8yMCAtIGZXaWR0aC8xNSAtIGZXaWR0aC8yMCArIGZXaWR0aCowLjA3ZiwNCi0JCSAgICAgICAgICAgICAgLWZXaWR0aCowLjA3Zi9rICsgLWsqZldpZHRoLzIwICsgLWsqZldpZHRoLzE1IC0gaypmV2lkdGgvMjAgLSBrKmZXaWR0aCowLjE4ZiAtIGZXaWR0aC8zMC9rICsgdGFpbC55KSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludCh0YWlsLnggKyBmV2lkdGgvMzAgLSBmV2lkdGgqMC4xOGYgLSBmV2lkdGgvMjAgLSBmV2lkdGgvMTUgLSBmV2lkdGgvMjAsDQotCQkgICAgICAgICAgICAgIC1rKmZXaWR0aC8yMCArIC1rKmZXaWR0aC8xNSAtIGsqZldpZHRoLzIwIC0gaypmV2lkdGgqMC4xOGYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwIC0gZldpZHRoKjAuNDVmLCAtaypmV2lkdGgqMC40NWYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwIC0gZldpZHRoKjAuNDVmICsgZldpZHRoKjAuMmYsDQotCQkgICAgICAgICAgICAgIC1mV2lkdGgqMC40Zi9rIC0gaypmV2lkdGgqMC40NWYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54ICsgZldpZHRoKjAuMmYsIC0gZldpZHRoKjAuMWYvayArIENpY2xlQ2VudGVyLnkpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoQ2ljbGVDZW50ZXIueCwgQ2ljbGVDZW50ZXIueSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54IC0gZldpZHRoLzYwLjBmLCAtaypmV2lkdGgvNjAgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KENpY2xlQ2VudGVyLnggLSBmV2lkdGgvNjAsIC1rKmZXaWR0aC82MCArIENpY2xlQ2VudGVyLnkpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoQ2ljbGVDZW50ZXIueCwgQ2ljbGVDZW50ZXIueSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54IC0gZldpZHRoKjAuMjJmLCBmV2lkdGgqMC4zNWYvayArIENpY2xlQ2VudGVyLnkgLSBmSGVpZ2h0KjAuMDVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCAtIGZXaWR0aC8zMCAtIGZXaWR0aCowLjQ1ZiAtIGZXaWR0aCowLjE4ZiwgZldpZHRoKjAuMDVmL2sgLSBrKmZXaWR0aCowLjQ1ZiArIGZXaWR0aC8zMC9rICsgdGFpbC55IC0gZkhlaWdodCowLjA1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludCh0YWlsLnggLSBmV2lkdGgvMzAuMGYgLSBmV2lkdGgqMC40NWYsIC1rKmZXaWR0aCowLjQ1ZiArIGZXaWR0aC8zMC4wZi9rICsgdGFpbC55KSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCAtIGZXaWR0aC8zMC4wZiwgZldpZHRoLzMwLjBmL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCwgLWZXaWR0aC8zMC9rICsgdGFpbC55KSwgUFdMUFRfTElORVRPKSwJCQ0KLSAJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54ICsgZldpZHRoKjAuMDhmLCBrKmZXaWR0aCowLjA4ZiArIENpY2xlQ2VudGVyLnkpLCBQV0xQVF9NT1ZFVE8pLA0KLSAJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54ICsgZldpZHRoKjAuMDhmICsgZldpZHRoKjAuMWYsIC1mV2lkdGgqMC4xZi9rICsgaypmV2lkdGgqMC4wOGYgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfQkVaSUVSVE8pLA0KLSAJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54ICsgZldpZHRoKjAuMjJmICsgZldpZHRoKjAuMWYsIGsqZldpZHRoKjAuMjJmICsgQ2ljbGVDZW50ZXIueSAtIGZXaWR0aCowLjFmL2spLCBQV0xQVF9CRVpJRVJUTyksDQotIAkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KENpY2xlQ2VudGVyLnggKyBmV2lkdGgqMC4yMmYsIGsqZldpZHRoKjAuMjJmICsgQ2ljbGVDZW50ZXIueSksIFBXTFBUX0JFWklFUlRPKSwNCi0gCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoQ2ljbGVDZW50ZXIueCArIGZXaWR0aCowLjIyZiAtIGZXaWR0aCowLjFmLCBmV2lkdGgqMC4xZi9rICsgaypmV2lkdGgqMC4yMmYgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KENpY2xlQ2VudGVyLnggKyBmV2lkdGgqMC4wOGYgLSBmV2lkdGgqMC4xZiwgZldpZHRoKjAuMWYvayArIGsqZldpZHRoKjAuMDhmICsgQ2ljbGVDZW50ZXIueSksIFBXTFBUX0JFWklFUlRPKSwNCi0gCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoQ2ljbGVDZW50ZXIueCArIGZXaWR0aCowLjA4ZiwgaypmV2lkdGgqMC4wOGYgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfQkVaSUVSVE8pDQotCX07DQotDQotCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQ0KLQkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMjgpOw0KLQllbHNlDQotCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDI4KTsNCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19OZXdQYXJhZ3JhcGgoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQ0KLXsNCi0JRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7DQotCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsNCi0NCi0JQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IA0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMjAuMGYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzEwLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTAuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzIwLjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjEyZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMTcvMzAuMGYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMTJmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xMC4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yMmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjIyZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMTcvMzAuMGYgLSBmV2lkdGgqMC4xNGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMzhmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xMC4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40OGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjQ4ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMTcvMzAuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMzhmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4zOGYsIGNyQkJveC5ib3R0b20gKyBmV2lkdGgqMC4yNGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjJmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4xMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjZmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xMC4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTAuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuN2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwLjBmICsgZkhlaWdodC83LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjk3ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTAuMGYgKyBmSGVpZ2h0LzcuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC45N2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjZmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xMC4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvNyArIGZIZWlnaHQqMC4xOGYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuODVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC83ICsgZkhlaWdodCowLjE4ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjg1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMTcvMzAuMGYgLSBmSGVpZ2h0KjAuMDhmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmIC0gZkhlaWdodCowLjA4ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjdmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC83ICsgZkhlaWdodCowLjE4ZiksIFBXTFBUX0xJTkVUTykNCi0JfTsNCi0NCi0JaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pDQotCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAyOCk7DQotCWVsc2UNCi0JCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMjgpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1RleHROb3RlKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkNCi17DQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSANCi0Jew0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCozLzEwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNy8xMC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzEwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCo0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTAuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xMC4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzEwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjMvMTAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCozLzEwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjMvMTAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xMC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjcvMTUuMGYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC81LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodCo3LzE1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC81LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxMC8xNS4wZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjMvMTAuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjEwLzE1LjBmKSwgUFdMUFRfTElORVRPKQ0KLQl9Ow0KLQ0KLQlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkNCi0JCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDE3KTsNCi0JZWxzZQ0KLQkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAxNyk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9VdGlsczo6R2V0R3JhcGhpY3NfUGFyYWdyYXBoKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkNCi17DQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPQ0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjdmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42MzRmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42MzRmLCBjckJCb3gudG9wIC0gZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjU2NmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjIvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNTY2ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8xNS4wZiAtIGZIZWlnaHQqMC40ZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYgLSBmSGVpZ2h0KjAuNGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTykNCi0JfTsNCi0NCi0JaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pDQotCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAxMik7DQotCWVsc2UNCi0JCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMTIpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1JpZ2h0QXJyb3coQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQ0KLXsNCi0JRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7DQotCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsNCi0NCi0JQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IA0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmICsgZldpZHRoLzguMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiAtIGZXaWR0aCowLjE1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMi4wZiAtIGZXaWR0aC8yNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4xZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMi4wZiAtIGZXaWR0aC8yNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4xZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMi4wZiArIGZXaWR0aC8yNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmIC0gZldpZHRoKjAuMTVmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmICsgZldpZHRoLzI1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC81LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmICsgZldpZHRoLzguMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMi4wZiksIFBXTFBUX0xJTkVUTykNCi0JfTsNCi0NCi0JaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pDQotCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAxMCk7DQotCWVsc2UNCi0JCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMTApOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1JpZ2h0UG9pbnRlcihDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpDQotew0KLQlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOw0KLQ0KLQlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gDQotCXsNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMzAuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzMwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC82LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCo0LzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8zMC4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvNi4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzMwLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmKSwgUFdMUFRfTElORVRPKQ0KLQl9Ow0KLQ0KLQlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkNCi0JCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDUpOw0KLQllbHNlDQotCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDUpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1N0YXIoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQ0KLXsNCi0JRlhfRkxPQVQgZkxvbmdSYWRpdXMgPSAoY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b20pLygxKyhGWF9GTE9BVCljb3MoUFdMX1BJLzUuMGYpKTsNCi0JZkxvbmdSYWRpdXMgPSBmTG9uZ1JhZGl1cyAqIDAuN2Y7DQotCUZYX0ZMT0FUIGZTaG9ydFJhZGl1cyA9IGZMb25nUmFkaXVzICogMC41NWY7DQotCUNQREZfUG9pbnQgcHRDZW50ZXIgPSBDUERGX1BvaW50KChjckJCb3gubGVmdCArIGNyQkJveC5yaWdodCkgLyAyLjBmLChjckJCb3gudG9wICsgY3JCQm94LmJvdHRvbSkgLyAyLjBmKTsNCi0JDQotCUZYX0ZMT0FUIHB4MVs1XSwgcHkxWzVdOw0KLQlGWF9GTE9BVCBweDJbNV0sIHB5Mls1XTsNCi0NCi0JRlhfRkxPQVQgZkFuZ2VsID0gUFdMX1BJLzEwLjBmOw0KLQ0KLQlmb3IgKEZYX0lOVDMyIGk9MDsgaTw1OyBpKyspDQotCXsNCi0JCXB4MVtpXSA9IHB0Q2VudGVyLnggKyBmTG9uZ1JhZGl1cyAqIChGWF9GTE9BVCljb3MoZkFuZ2VsKTsNCi0JCXB5MVtpXSA9IHB0Q2VudGVyLnkgKyBmTG9uZ1JhZGl1cyAqIChGWF9GTE9BVClzaW4oZkFuZ2VsKTsNCi0NCi0JCWZBbmdlbCArPSBQV0xfUEkgKiAyIC8gNS4wZjsNCi0JfQ0KLQ0KLQlmQW5nZWwgPSBQV0xfUEkvNS4wZiArIFBXTF9QSS8xMC4wZjsNCi0NCi0JZm9yIChGWF9JTlQzMiBqPTA7IGo8NTsgaisrKQ0KLQl7DQotCQlweDJbal0gPSBwdENlbnRlci54ICsgZlNob3J0UmFkaXVzICogKEZYX0ZMT0FUKWNvcyhmQW5nZWwpOw0KLQkJcHkyW2pdID0gcHRDZW50ZXIueSArIGZTaG9ydFJhZGl1cyAqIChGWF9GTE9BVClzaW4oZkFuZ2VsKTsNCi0NCi0JCWZBbmdlbCArPSBQV0xfUEkgKiAyIC8gNS4wZjsNCi0JfQ0KLQ0KLQlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVsxMV07DQotCVBhdGhBcnJheVswXSA9IENQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChweDFbMF0sIHB5MVswXSksIFBXTFBUX01PVkVUTyk7DQotCVBhdGhBcnJheVsxXSA9IENQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChweDJbMF0sIHB5MlswXSksIFBXTFBUX0xJTkVUTyk7DQotDQotCWZvcihGWF9JTlQzMiBrID0gMDsgayA8IDQ7IGsrKykNCi0Jew0KLQkJUGF0aEFycmF5WyhrKzEpKjJdID0gQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHB4MVtrKzFdLCBweTFbaysxXSksIFBXTFBUX0xJTkVUTyk7DQotCQlQYXRoQXJyYXlbKGsrMSkqMiArIDFdID0gQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHB4MltrKzFdLCBweTJbaysxXSksIFBXTFBUX0xJTkVUTyk7DQotCX0NCi0NCi0JUGF0aEFycmF5WzEwXSA9IENQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChweDFbMF0sIHB5MVswXSksIFBXTFBUX0xJTkVUTyk7DQotDQotCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQ0KLQkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMTEpOw0KLQllbHNlDQotCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDExKTsNCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19VcEFycm93KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkNCi17DQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSANCi0Jew0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTAuMGYsIGNyQkJveC50b3AgLSBmV2lkdGgqMy81LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjZmLCBjckJCb3gudG9wIC0gZldpZHRoKjMvNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZldpZHRoKjMvNS4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTAsIGNyQkJveC50b3AgLSBmV2lkdGgqMy81LjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8xNS4wZiksIFBXTFBUX0xJTkVUTykNCi0JfTsNCi0NCi0JaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pDQotCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCA4KTsNCi0JZWxzZQ0KLQkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCA4KTsNCi19DQotDQotdm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19VcExlZnRBcnJvdyhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpDQotew0KLQlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOw0KLQlDUFdMX1BvaW50IGxlZnR1cChjckJCb3gubGVmdCwgY3JCQm94LnRvcCk7DQotCUNQV0xfUG9pbnQgcmlnaHRkb3duKGNyQkJveC5yaWdodCwgY3JCQm94LmJvdHRvbSk7DQotCUZYX0ZMT0FUIGsgPSAtZkhlaWdodC9mV2lkdGg7DQotCUNQV0xfUG9pbnQgdGFpbDsNCi0JdGFpbC54ID0gY3JCQm94LmxlZnQgKyBmV2lkdGgqNC81LjBmOw0KLQl0YWlsLnkgPSBrKih0YWlsLnggLSBjckJCb3gucmlnaHQpICsgcmlnaHRkb3duLnk7DQotDQotCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSANCi0Jew0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIwLjBmLCBrKihjckJCb3gubGVmdCArIGZXaWR0aC8yMC4wZiAtIHJpZ2h0ZG93bi54KSArIHJpZ2h0ZG93bi55KSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChmSGVpZ2h0KjE3LzYwLjBmL2sgKyB0YWlsLnggKyBmV2lkdGgvMTAuMGYgKyBmV2lkdGgvNS4wZiwNCi0JCSAgICAgICAgICAgICAgLWZXaWR0aC81LjBmL2sgKyB0YWlsLnkgLSBmV2lkdGgvMTAuMGYvayArIGZIZWlnaHQqMTcvNjAuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGZIZWlnaHQqMTcvNjAuMGYvayArIHRhaWwueCArIGZXaWR0aC8xMC4wZiwNCi0JCSAgICAgICAgICAgICAgdGFpbC55IC0gZldpZHRoLzEwLjBmL2sgKyBmSGVpZ2h0KjE3LzYwLjBmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludCh0YWlsLnggKyBmV2lkdGgvMTAuMGYsIHRhaWwueSAtIGZXaWR0aC8xMC4wZi9rKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludCh0YWlsLnggLSBmV2lkdGgvMTAuMGYsIHRhaWwueSArIGZXaWR0aC8xMC4wZi9rKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChmSGVpZ2h0KjE3LzYwLjBmL2sgKyB0YWlsLnggLSBmV2lkdGgvMTAuMGYsIHRhaWwueSArIGZXaWR0aC8xMC4wZi9rICsgZkhlaWdodCoxNy82MC4wZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoZkhlaWdodCoxNy82MC4wZi9rICsgdGFpbC54IC0gZldpZHRoLzEwLjBmIC0gZldpZHRoLzUuMGYsDQotCQkgICAgICAgICAgICAgIGZXaWR0aC81LjBmL2sgKyB0YWlsLnkgKyBmV2lkdGgvMTAuMGYvayArIGZIZWlnaHQqMTcvNjAuMGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIwLjBmLCBrKihjckJCb3gubGVmdCArIGZXaWR0aC8yMC4wZiAtIHJpZ2h0ZG93bi54KSArIHJpZ2h0ZG93bi55KSwgUFdMUFRfTElORVRPKQ0KLQl9Ow0KLQ0KLQlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkNCi0JCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDgpOw0KLQllbHNlDQotCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDgpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0dyYXBoKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkNCi17DQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSANCi0Jew0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMDVmLCBjckJCb3gudG9wIC0gZldpZHRoKjAuMTVmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjI1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4xNWYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjc1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMDVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjA4ZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4wNWYsIGNyQkJveC50b3AgLSBmV2lkdGgqMC4xNWYpLCBQV0xQVF9MSU5FVE8pLA0KLQ0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjc1ZiwgY3JCQm94LnRvcCAtIGZXaWR0aCowLjQ1ZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40NzVmLCBjckJCb3gudG9wIC0gZldpZHRoKjAuNDVmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjQ3NWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMDhmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjI3NWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMDhmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjI3NWYsIGNyQkJveC50b3AgLSBmV2lkdGgqMC40NWYpLCBQV0xQVF9MSU5FVE8pLA0KLQ0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMDVmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjdmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjA1ZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMDhmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjVmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjA1ZiksIFBXTFBUX0xJTkVUTyksDQotDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43MjVmLCBjckJCb3gudG9wIC0gZldpZHRoKjAuMzVmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjkyNWYsIGNyQkJveC50b3AgLSBmV2lkdGgqMC4zNWYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuOTI1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNzI1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNzI1ZiwgY3JCQm94LnRvcCAtIGZXaWR0aCowLjM1ZiksIFBXTFBUX0xJTkVUTykNCi0JfTsNCi0NCi0JaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pDQotCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAyMCk7DQotCWVsc2UNCi0JCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMjApOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1BhcGVyY2xpcChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpDQotew0KLQlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOw0KLQ0KLQlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gDQotCXsNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC82MCwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yNWYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjI1ZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNjAsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmIC0gZldpZHRoKjU3LzYwLjBmKjAuMzVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8zMCwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4yNWYgLSBmV2lkdGgqNTcvNjAuMGYqMC4zNWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzMwLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjI1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0NCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMzAsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzNmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMzAsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzNmICsgZkhlaWdodC8xNSowLjVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8zMCAtIGZXaWR0aCowLjEyZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zM2YgKyBmSGVpZ2h0LzE1KjAuNWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzMwIC0gZldpZHRoKjAuMTJmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjMzZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzMwIC0gZldpZHRoKjAuMTJmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjJmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMzAgLSBmV2lkdGgqMC4xMmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMmYgLSAoZldpZHRoKjU3LzYwLjBmIC0gZldpZHRoKjAuMjRmKSowLjI1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC82MCArIGZXaWR0aCowLjEyZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4yZiAtIChmV2lkdGgqNTcvNjAuMGYgLSBmV2lkdGgqMC4yNGYpKjAuMjVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwICsgZldpZHRoKjAuMTJmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjJmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQ0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwICsgZldpZHRoKjAuMTJmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjJmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC82MCArIGZXaWR0aCowLjEyZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yZiArIChmV2lkdGgqMTEvMTIuMGYgLSBmV2lkdGgqMC4zNmYpKjAuMjVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNSAtIGZXaWR0aCowLjI0ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yZiArIChmV2lkdGgqMTEvMTIuMGYgLSBmV2lkdGgqMC4zNmYpKjAuMjVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNSAtIGZXaWR0aCowLjI0ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yZiksIFBXTFBUX0JFWklFUlRPKSwNCi0NCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUgLSBmV2lkdGgqMC4yNGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUgLSBmV2lkdGgqMC4yNGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmIC0gKGZXaWR0aCoxNC8xNS4wZiAtIGZXaWR0aCowLjUzZikqMC4yNWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yOWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmIC0gKGZXaWR0aCoxNC8xNS4wZiAtIGZXaWR0aCowLjUzZikqMC4yNWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yOWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQ0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjlmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjMzZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yOWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzNmICsgZldpZHRoKjAuMTJmKjAuMzVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMTdmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjMzZiArIGZXaWR0aCowLjEyZiowLjM1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjE3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zM2YpLCBQV0xQVF9CRVpJRVJUTyksDQotDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4xN2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuM2YpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMTdmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjNmIC0gZldpZHRoKigxNC8xNS4wZiAtIDAuMjlmKSowLjM1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUgLSBmV2lkdGgqMC4xMmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuM2YgLSBmV2lkdGgqKDE0LzE1LjBmIC0gMC4yOWYpKjAuMzVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNSAtIGZXaWR0aCowLjEyZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4zZiksIFBXTFBUX0JFWklFUlRPKSwNCi0NCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUgLSBmV2lkdGgqMC4xMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMjVmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUgLSBmV2lkdGgqMC4xMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMjVmICsgZldpZHRoKjAuMzVmKigxMS8xMi4wZiAtIDAuMTJmKSksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC82MCwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yNWYgKyBmV2lkdGgqMC4zNWYqKDExLzEyLjBmIC0gMC4xMmYpKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjI1ZiksIFBXTFBUX0JFWklFUlRPKQ0KLQl9Ow0KLQ0KLQlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkNCi0JCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDMzKTsNCi0JZWxzZQ0KLQkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAzMyk7CQ0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0F0dGFjaG1lbnQoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQ0KLXsNCi0JRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7DQotCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsNCi0NCi0JQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IA0KLQl7DQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMWYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMjNmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmICsgZldpZHRoKjAuMDRmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYgKyBmV2lkdGgqMC4wNGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0NCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjZmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjIzZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMjVmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjFmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjI1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4xZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yM2YpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMjNmKSwgUFdMUFRfTElORVRPKSwNCi0NCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmIC0gZldpZHRoKjAuMjVmKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4xNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNjVmICsgZkhlaWdodCowLjE1ZiowLjRmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMTVmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjY1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0NCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4xNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNjVmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4xNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNjVmICsgZkhlaWdodCowLjE1ZiowLjRmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYgKyBmV2lkdGgqMC4yNWYqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjZmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQ0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYgKyBmV2lkdGgqMC4wNGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41ZiArIGZXaWR0aCowLjA0ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQ0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNjVmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjFmKSwgUFdMUFRfTElORVRPKQ0KLQl9Ow0KLQ0KLQlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkNCi0JCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDI0KTsNCi0JZWxzZQ0KLQkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAyNCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9VdGlsczo6R2V0R3JhcGhpY3NfVGFnKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkNCi17DQotCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSANCi0Jew0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMWYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuM2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMWYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjFmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjFmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4xZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4xZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4xZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zZiksIFBXTFBUX01PVkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuM2YpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYpLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjJmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjdmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4yZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC43ZiksIFBXTFBUX0xJTkVUTykNCi0JfTsNCi0NCi0JaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pDQotCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAxMik7DQotCWVsc2UNCi0JCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMTIpOw0KLX0NCi0NCi12b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0ZveGl0KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkNCi17DQotCUZYX0ZMT0FUIGZPdXRXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0Ow0KLQlGWF9GTE9BVCBmT3V0SGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207DQotDQotCUNQREZfUmVjdCBjckluQm94ID0gY3JCQm94Ow0KLQljckluQm94LmxlZnQgPSBjckJCb3gubGVmdCArIGZPdXRXaWR0aCowLjA4ZjsNCi0JY3JJbkJveC5yaWdodCA9IGNyQkJveC5yaWdodCAtIGZPdXRXaWR0aCowLjA4ZjsNCi0JY3JJbkJveC50b3AgPSBjckJCb3gudG9wIC0gZk91dEhlaWdodCowLjA4ZjsNCi0JY3JJbkJveC5ib3R0b20gPSBjckJCb3guYm90dG9tICsgZk91dEhlaWdodCowLjA4ZjsNCi0NCi0JRlhfRkxPQVQgZldpZHRoID0gY3JJbkJveC5yaWdodCAtIGNySW5Cb3gubGVmdDsNCi0JRlhfRkxPQVQgZkhlaWdodCA9IGNySW5Cb3gudG9wIC0gY3JJbkJveC5ib3R0b207DQotDQotCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSANCi0Jew0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCwgY3JJbkJveC50b3ApLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCArIGZXaWR0aCowLjQ1ZiwgY3JJbkJveC50b3ApLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCArIGZXaWR0aCowLjQ1ZiwgY3JJbkJveC50b3AgLSBQV0xfQkVaSUVSICogZkhlaWdodCAqIDAuNGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0ICsgZldpZHRoKjAuNDVmICAtIFBXTF9CRVpJRVIgKiBmV2lkdGggKiAwLjQ1ZiwgY3JJbkJveC50b3AgLSBmSGVpZ2h0KjAuNGYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0LCBjckluQm94LnRvcCAtIGZIZWlnaHQqMC40ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQsIGNySW5Cb3gudG9wKSwgUFdMUFRfTElORVRPKSwNCi0NCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC42MGYsIGNySW5Cb3gudG9wKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC43NWYsIGNySW5Cb3gudG9wKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC43NWYsIGNySW5Cb3gudG9wIC0gUFdMX0JFWklFUiAqIGZIZWlnaHQgKiAwLjdmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCArIGZXaWR0aCowLjc1ZiAgLSBQV0xfQkVaSUVSICogZldpZHRoICogMC43NWYsIGNySW5Cb3gudG9wIC0gZkhlaWdodCowLjdmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCwgY3JJbkJveC50b3AgLSBmSGVpZ2h0KjAuN2YpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0LCBjckluQm94LnRvcCAtIGZIZWlnaHQqMC41NWYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCArIFBXTF9CRVpJRVIgKiBmV2lkdGgqMC42MGYsIGNySW5Cb3gudG9wIC0gZkhlaWdodCowLjU1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGggKiAwLjYwZiwgY3JJbkJveC50b3AgLSBQV0xfQkVaSUVSICogZkhlaWdodCAqIDAuNTVmKSwgUFdMUFRfQkVaSUVSVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCArIGZXaWR0aCAqIDAuNjBmLCBjckluQm94LnRvcCksIFBXTFBUX0JFWklFUlRPKSwNCi0NCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC45MGYsIGNySW5Cb3gudG9wKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC45MGYsIGNySW5Cb3gudG9wIC0gUFdMX0JFWklFUiAqIGZIZWlnaHQgKiAwLjg1ZiksIFBXTFBUX0JFWklFUlRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC45MGYgIC0gUFdMX0JFWklFUiAqIGZXaWR0aCAqIDAuOTBmLCBjckluQm94LnRvcCAtIGZIZWlnaHQqMC44NWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0LCBjckluQm94LnRvcCAtIGZIZWlnaHQqMC44NWYpLCBQV0xQVF9CRVpJRVJUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0LCBjckluQm94LmJvdHRvbSksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5yaWdodCwgY3JJbkJveC5ib3R0b20pLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gucmlnaHQsIGNySW5Cb3gudG9wKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC45MGYsIGNySW5Cb3gudG9wKSwgUFdMUFRfTElORVRPKSwNCi0NCi0JCS8qDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQsIGNyQkJveC50b3ApLCBQV0xQVF9NT1ZFVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCwgY3JCQm94LnRvcCksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0LCBjckJCb3guYm90dG9tKSwgUFdMUFRfTElORVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCwgY3JCQm94LmJvdHRvbSksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQsIGNyQkJveC50b3ApLCBQV0xQVF9MSU5FVE8pLA0KLQ0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0K2ZPdXRXaWR0aCowLjA0ZiwgY3JCQm94LnRvcC1mT3V0SGVpZ2h0KjAuMDRmKSwgUFdMUFRfTU9WRVRPKSwNCi0JCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQtZk91dFdpZHRoKjAuMDRmLCBjckJCb3gudG9wLWZPdXRIZWlnaHQqMC4wNGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodC1mT3V0V2lkdGgqMC4wNGYsIGNyQkJveC5ib3R0b20rZk91dEhlaWdodCowLjA0ZiksIFBXTFBUX0xJTkVUTyksDQotCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQrZk91dFdpZHRoKjAuMDRmLCBjckJCb3guYm90dG9tK2ZPdXRIZWlnaHQqMC4wNGYpLCBQV0xQVF9MSU5FVE8pLA0KLQkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0K2ZPdXRXaWR0aCowLjA0ZiwgY3JCQm94LnRvcC1mT3V0SGVpZ2h0KjAuMDRmKSwgUFdMUFRfTElORVRPKSwNCi0JCSovDQotCX07DQotDQotCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQ0KLQkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMjMpOw0KLQllbHNlDQotCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDIzKTsNCi19DQotDQotdm9pZCBDUFdMX0NvbG9yOjpDb252ZXJ0Q29sb3JUeXBlKEZYX0lOVDMyIG5Db2xvclR5cGUpDQotew0KLQlzd2l0Y2ggKHRoaXMtPm5Db2xvclR5cGUpDQotCXsNCi0JY2FzZSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQ6DQotCQlicmVhazsNCi0JY2FzZSBDT0xPUlRZUEVfR1JBWToNCi0JCXN3aXRjaCAobkNvbG9yVHlwZSkNCi0JCXsNCi0JCWNhc2UgQ09MT1JUWVBFX1JHQjoNCi0JCQlDUFdMX1V0aWxzOjpDb252ZXJ0R1JBWTJSR0IodGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMiwgdGhpcy0+ZkNvbG9yMyk7DQotCQkJYnJlYWs7DQotCQljYXNlIENPTE9SVFlQRV9DTVlLOg0KLQkJCUNQV0xfVXRpbHM6OkNvbnZlcnRHUkFZMkNNWUsodGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMiwgdGhpcy0+ZkNvbG9yMywgdGhpcy0+ZkNvbG9yNCk7DQotCQkJYnJlYWs7DQotCQl9DQotCQlicmVhazsNCi0JY2FzZSBDT0xPUlRZUEVfUkdCOg0KLQkJc3dpdGNoIChuQ29sb3JUeXBlKQ0KLQkJew0KLQkJY2FzZSBDT0xPUlRZUEVfR1JBWToNCi0JCQlDUFdMX1V0aWxzOjpDb252ZXJ0UkdCMkdSQVkodGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMiwgdGhpcy0+ZkNvbG9yMywgdGhpcy0+ZkNvbG9yMSk7DQotCQkJYnJlYWs7DQotCQljYXNlIENPTE9SVFlQRV9DTVlLOg0KLQkJCUNQV0xfVXRpbHM6OkNvbnZlcnRSR0IyQ01ZSyh0aGlzLT5mQ29sb3IxLCB0aGlzLT5mQ29sb3IyLCB0aGlzLT5mQ29sb3IzLCB0aGlzLT5mQ29sb3IxLCB0aGlzLT5mQ29sb3IyLCB0aGlzLT5mQ29sb3IzLCB0aGlzLT5mQ29sb3I0KTsNCi0JCQlicmVhazsNCi0JCX0NCi0JCWJyZWFrOw0KLQljYXNlIENPTE9SVFlQRV9DTVlLOg0KLQkJc3dpdGNoIChuQ29sb3JUeXBlKQ0KLQkJew0KLQkJY2FzZSBDT0xPUlRZUEVfR1JBWToNCi0JCQlDUFdMX1V0aWxzOjpDb252ZXJ0Q01ZSzJHUkFZKHRoaXMtPmZDb2xvcjEsIHRoaXMtPmZDb2xvcjIsIHRoaXMtPmZDb2xvcjMsIHRoaXMtPmZDb2xvcjQsIHRoaXMtPmZDb2xvcjEpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBDT0xPUlRZUEVfUkdCOg0KLQkJCUNQV0xfVXRpbHM6OkNvbnZlcnRDTVlLMlJHQih0aGlzLT5mQ29sb3IxLCB0aGlzLT5mQ29sb3IyLCB0aGlzLT5mQ29sb3IzLCB0aGlzLT5mQ29sb3I0LCB0aGlzLT5mQ29sb3IxLCB0aGlzLT5mQ29sb3IyLCB0aGlzLT5mQ29sb3IzKTsNCi0JCQlicmVhazsNCi0JCX0NCi0JCWJyZWFrOw0KLQl9DQotCXRoaXMtPm5Db2xvclR5cGUgPSBuQ29sb3JUeXBlOw0KLX0NCi0NCi0NCisvLyBDb3B5cmlnaHQgMjAxNCBQREZpdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKy8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKKy8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCisgCisvLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQorCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiCisjaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9JY29uLmgiCisKKyNkZWZpbmUgSXNGbG9hdFplcm8oZikJCQkJCQkoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpCisjZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCSgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQorI2RlZmluZSBJc0Zsb2F0U21hbGxlcihmYSxmYikJCQkJKChmYSkgPCAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpCisjZGVmaW5lIElzRmxvYXRFcXVhbChmYSxmYikJCQkJCUlzRmxvYXRaZXJvKChmYSktKGZiKSkKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX1V0aWxzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitDRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoY29uc3QgQ1BXTF9QYXRoRGF0YSogcFBhdGhEYXRhLCBGWF9JTlQzMiBuQ291bnQpCit7CisJQ0ZYX0J5dGVUZXh0QnVmIGNzQVA7CisKKwlmb3IgKEZYX0lOVDMyIGk9MDsgaTxuQ291bnQ7IGkrKykKKwl7CisJCXN3aXRjaCAocFBhdGhEYXRhW2ldLnR5cGUpCisJCXsKKwkJY2FzZSBQV0xQVF9NT1ZFVE86CisJCQljc0FQIDw8IHBQYXRoRGF0YVtpXS5wb2ludC54IDw8ICIgIiA8PCBwUGF0aERhdGFbaV0ucG9pbnQueSA8PCAiIG1cbiI7CisJCQlicmVhazsKKwkJY2FzZSBQV0xQVF9MSU5FVE86CisJCQljc0FQIDw8IHBQYXRoRGF0YVtpXS5wb2ludC54IDw8ICIgIiA8PCBwUGF0aERhdGFbaV0ucG9pbnQueSA8PCAiIGxcbiI7CisJCQlicmVhazsKKwkJY2FzZSBQV0xQVF9CRVpJRVJUTzoKKwkJCWNzQVAgPDwgcFBhdGhEYXRhW2ldLnBvaW50LnggPDwgIiAiIDw8IHBQYXRoRGF0YVtpXS5wb2ludC55IDw8ICIgIgorCQkJCSA8PCBwUGF0aERhdGFbaSsxXS5wb2ludC54IDw8ICIgIiA8PCBwUGF0aERhdGFbaSsxXS5wb2ludC55IDw8ICIgIgorCQkJCSA8PCBwUGF0aERhdGFbaSsyXS5wb2ludC54IDw8ICIgIiA8PCBwUGF0aERhdGFbaSsyXS5wb2ludC55IDw8ICIgY1xuIjsKKworCQkJaSArPSAyOworCQkJYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlicmVhazsKKwkJfQorCX0KKworCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRQYXRoRGF0YUZyb21BcnJheShDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQV0xfUGF0aERhdGEqIHBQYXRoRGF0YSwgRlhfSU5UMzIgbkNvdW50KQoreworCXBhdGguU2V0UG9pbnRDb3VudChuQ291bnQpOworCisJZm9yIChGWF9JTlQzMiBpPTA7IGk8bkNvdW50OyBpKyspCisJeworCQlzd2l0Y2ggKHBQYXRoRGF0YVtpXS50eXBlKQorCQl7CisJCWNhc2UgUFdMUFRfTU9WRVRPOgorCQkJcGF0aC5TZXRQb2ludChpLCBwUGF0aERhdGFbaV0ucG9pbnQueCwgcFBhdGhEYXRhW2ldLnBvaW50LnksIEZYUFRfTU9WRVRPKTsKKwkJCWJyZWFrOworCQljYXNlIFBXTFBUX0xJTkVUTzoKKwkJCXBhdGguU2V0UG9pbnQoaSwgcFBhdGhEYXRhW2ldLnBvaW50LngsIHBQYXRoRGF0YVtpXS5wb2ludC55LCBGWFBUX0xJTkVUTyk7CisJCQlicmVhazsKKwkJY2FzZSBQV0xQVF9CRVpJRVJUTzoKKwkJCXBhdGguU2V0UG9pbnQoaSwgcFBhdGhEYXRhW2ldLnBvaW50LngsIHBQYXRoRGF0YVtpXS5wb2ludC55LCBGWFBUX0JFWklFUlRPKTsKKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJYnJlYWs7CisJCX0KKwl9Cit9CisKKworQ1BERl9SZWN0IENQV0xfVXRpbHM6Ok1heFJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdDEsY29uc3QgQ1BERl9SZWN0ICYgcmVjdDIpCit7CisJQ1BERl9SZWN0IHJjUmV0OworCisJcmNSZXQubGVmdCA9IFBXTF9NSU4ocmVjdDEubGVmdCxyZWN0Mi5sZWZ0KTsKKwlyY1JldC5ib3R0b20gPSBQV0xfTUlOKHJlY3QxLmJvdHRvbSxyZWN0Mi5ib3R0b20pOworCXJjUmV0LnJpZ2h0ID0gUFdMX01BWChyZWN0MS5yaWdodCxyZWN0Mi5yaWdodCk7CisJcmNSZXQudG9wID0gUFdMX01BWChyZWN0MS50b3AscmVjdDIudG9wKTsKKworCXJldHVybiByY1JldDsKK30KKworQ1BERl9SZWN0IENQV0xfVXRpbHM6Ok9mZnNldFJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCxGWF9GTE9BVCB4LEZYX0ZMT0FUIHkpCit7CisJcmV0dXJuIENQREZfUmVjdChyZWN0LmxlZnQgKyB4LHJlY3QuYm90dG9tICsgeSwKKwkJcmVjdC5yaWdodCArIHgscmVjdC50b3AgKyB5KTsKK30KKworRlhfQk9PTCBDUFdMX1V0aWxzOjpDb250YWluc1JlY3QoY29uc3QgQ1BERl9SZWN0JiByY1BhcmVudCwgY29uc3QgQ1BERl9SZWN0JiByY0NoaWxkKQoreworCXJldHVybiByY0NoaWxkLmxlZnQgPj0gcmNQYXJlbnQubGVmdCAmJiByY0NoaWxkLmJvdHRvbSA+PSByY1BhcmVudC5ib3R0b20gJiYKKwkJCXJjQ2hpbGQucmlnaHQgPD0gcmNQYXJlbnQucmlnaHQgJiYgcmNDaGlsZC50b3AgPD0gcmNQYXJlbnQudG9wOworfQorCitGWF9CT09MIENQV0xfVXRpbHM6OkludGVyc2VjdFJlY3QoY29uc3QgQ1BERl9SZWN0JiByZWN0MSwgY29uc3QgQ1BERl9SZWN0JiByZWN0MikKK3sKKwlGWF9GTE9BVCBsZWZ0ID0gcmVjdDEubGVmdCA+IHJlY3QyLmxlZnQgPyByZWN0MS5sZWZ0IDogcmVjdDIubGVmdDsKKwlGWF9GTE9BVCByaWdodCA9IHJlY3QxLnJpZ2h0IDwgcmVjdDIucmlnaHQgPyByZWN0MS5yaWdodCA6IHJlY3QyLnJpZ2h0OworCUZYX0ZMT0FUIGJvdHRvbSA9IHJlY3QxLmJvdHRvbSA+IHJlY3QyLmJvdHRvbSA/IHJlY3QxLmJvdHRvbSA6IHJlY3QyLmJvdHRvbTsKKwlGWF9GTE9BVCB0b3AgPSByZWN0MS50b3AgPCByZWN0Mi50b3AgPyByZWN0MS50b3AgOiByZWN0Mi50b3A7CisKKwlyZXR1cm4gbGVmdCA8IHJpZ2h0ICYmIGJvdHRvbSA8IHRvcDsKK30KKworQ1BERl9Qb2ludCBDUFdMX1V0aWxzOjpPZmZzZXRQb2ludChjb25zdCBDUERGX1BvaW50JiBwb2ludCxGWF9GTE9BVCB4LEZYX0ZMT0FUIHkpCit7CisJcmV0dXJuIENQREZfUG9pbnQocG9pbnQueCArIHgscG9pbnQueSArIHkpOworfQorCitDUFZUX1dvcmRSYW5nZSBDUFdMX1V0aWxzOjpPdmVybGFwV29yZFJhbmdlKGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3IxLCBjb25zdCBDUFZUX1dvcmRSYW5nZSAmIHdyMikKK3sKKwlDUFZUX1dvcmRSYW5nZSB3clJldDsKKworCWlmICh3cjIuRW5kUG9zLldvcmRDbXAod3IxLkJlZ2luUG9zKSA8IDAgfHwgd3IyLkJlZ2luUG9zLldvcmRDbXAod3IxLkVuZFBvcykgPiAwKSByZXR1cm4gd3JSZXQ7CisJaWYgKHdyMS5FbmRQb3MuV29yZENtcCh3cjIuQmVnaW5Qb3MpIDwgMCB8fCB3cjEuQmVnaW5Qb3MuV29yZENtcCh3cjIuRW5kUG9zKSA+IDApIHJldHVybiB3clJldDsKKworCWlmICh3cjEuQmVnaW5Qb3MuV29yZENtcCh3cjIuQmVnaW5Qb3MpIDwgMCkKKwl7CisJCXdyUmV0LkJlZ2luUG9zID0gd3IyLkJlZ2luUG9zOworCX0KKwllbHNlCisJeworCQl3clJldC5CZWdpblBvcyA9IHdyMS5CZWdpblBvczsKKwl9CisKKwlpZiAod3IxLkVuZFBvcy5Xb3JkQ21wKHdyMi5FbmRQb3MpIDwgMCkKKwl7CisJCXdyUmV0LkVuZFBvcyA9IHdyMS5FbmRQb3M7CisJfQorCWVsc2UKKwl7CisJCXdyUmV0LkVuZFBvcyA9IHdyMi5FbmRQb3M7CisJfQorCisJcmV0dXJuIHdyUmV0OworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRBUF9DaGVjayhjb25zdCBDUERGX1JlY3QgJiBjckJCb3gpCit7CisJQ0ZYX0J5dGVUZXh0QnVmIGNzQVA7CisKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisKKwljb25zdCBGWF9JTlQzMiBudW0gPSA4OworCisJQ1BXTF9Qb2ludCBwdHNbbnVtKjNdID0gCisJeworCQkvLzEKKwkJQ1BXTF9Qb2ludCgwLjI4ZiwgMC41MmYpLCAKKwkJQ1BXTF9Qb2ludCgwLjI3ZiwgMC40OGYpLAorCQlDUFdMX1BvaW50KDAuMjlmLCAwLjQwZiksCisKKwkJLy8yCisJCUNQV0xfUG9pbnQoMC4zMGYsIDAuMzNmKSwgCisJCUNQV0xfUG9pbnQoMC4zMWYsIDAuMjlmKSwKKwkJQ1BXTF9Qb2ludCgwLjMxZiwgMC4yOGYpLAorCisJCS8vMworCQlDUFdMX1BvaW50KDAuMzlmLCAwLjI4ZiksIAorCQlDUFdMX1BvaW50KDAuNDlmLCAwLjI5ZiksCisJCUNQV0xfUG9pbnQoMC43N2YsIDAuNjdmKSwKKworCQkvLzQKKwkJQ1BXTF9Qb2ludCgwLjc2ZiwgMC42OGYpLCAKKwkJQ1BXTF9Qb2ludCgwLjc4ZiwgMC42OWYpLAorCQlDUFdMX1BvaW50KDAuNzZmLCAwLjc1ZiksCisKKwkJLy81CisJCUNQV0xfUG9pbnQoMC43NmYsIDAuNzVmKSwgCisJCUNQV0xfUG9pbnQoMC43M2YsIDAuODBmKSwKKwkJQ1BXTF9Qb2ludCgwLjY4ZiwgMC43NWYpLAorCisJCS8vNgorCQlDUFdMX1BvaW50KDAuNjhmLCAwLjc0ZiksIAorCQlDUFdMX1BvaW50KDAuNjhmLCAwLjc0ZiksCisJCUNQV0xfUG9pbnQoMC40NGYsIDAuNDdmKSwKKworCQkvLzcKKwkJQ1BXTF9Qb2ludCgwLjQzZiwgMC40N2YpLCAKKwkJQ1BXTF9Qb2ludCgwLjQwZiwgMC40N2YpLAorCQlDUFdMX1BvaW50KDAuNDFmLCAwLjU4ZiksCisKKwkJLy84CisJCUNQV0xfUG9pbnQoMC40MGYsIDAuNjBmKSwgCisJCUNQV0xfUG9pbnQoMC4yOGYsIDAuNjZmKSwKKwkJQ1BXTF9Qb2ludCgwLjMwZiwgMC41NmYpCisJfTsKKworCWZvciAoRlhfSU5UMzIgaj0wOyBqPG51bSozOyBqKyspCisJeworCQlwdHNbal0ueCAqPSBmV2lkdGg7CisJCXB0c1tqXS54ICs9IGNyQkJveC5sZWZ0OworCisJCXB0c1tqXS55ICo9IGZIZWlnaHQ7CisJCXB0c1tqXS55ICs9IGNyQkJveC5ib3R0b207CisJfQorCisJY3NBUCA8PCBwdHNbMF0ueCA8PCAiICIgPDwgcHRzWzBdLnkgPDwgIiBtXG4iOworCisJZm9yIChGWF9JTlQzMiBpPTA7IGk8bnVtOyBpKyspCisJeworCQlGWF9JTlQzMiBuQ3VyID0gaSozOworCQlGWF9JTlQzMiBuMSA9IGkqMyArIDE7CisJCUZYX0lOVDMyIG4yID0gaSozICsgMjsKKwkJRlhfSU5UMzIgbk5leHQgPSAoaSA8IG51bS0xID8gKGkrMSkqMyA6IDApOworCisJCUZYX0ZMT0FUIHB4MSA9IHB0c1tuMV0ueCAtIHB0c1tuQ3VyXS54OworCQlGWF9GTE9BVCBweTEgPSBwdHNbbjFdLnkgLSBwdHNbbkN1cl0ueTsKKwkJRlhfRkxPQVQgcHgyID0gcHRzW24yXS54IC0gcHRzW25OZXh0XS54OworCQlGWF9GTE9BVCBweTIgPSBwdHNbbjJdLnkgLSBwdHNbbk5leHRdLnk7CisKKwkJY3NBUCA8PCBwdHNbbkN1cl0ueCArIHB4MSAqIFBXTF9CRVpJRVIgPDwgIiAiIDw8IHB0c1tuQ3VyXS55ICsgcHkxICogUFdMX0JFWklFUiA8PCAiICIgCisJCQk8PCBwdHNbbk5leHRdLnggKyBweDIgKiBQV0xfQkVaSUVSIDw8ICIgIiA8PCBwdHNbbk5leHRdLnkgKyBweTIgKiBQV0xfQkVaSUVSIDw8ICIgIgorCQkJPDwgcHRzW25OZXh0XS54IDw8ICIgIiA8PCBwdHNbbk5leHRdLnkgPDwgIiBjXG4iOworCX0KKworCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfQ2lyY2xlKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgY3NBUDsKKworCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0OworCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsKKworCUNQREZfUG9pbnQgcHQxKGNyQkJveC5sZWZ0LGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0IC8gMik7CisJQ1BERl9Qb2ludCBwdDIoY3JCQm94LmxlZnQgKyBmV2lkdGggLyAyLGNyQkJveC50b3ApOworCUNQREZfUG9pbnQgcHQzKGNyQkJveC5yaWdodCxjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDIpOworCUNQREZfUG9pbnQgcHQ0KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gMixjckJCb3guYm90dG9tKTsKKworCWNzQVAgPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbVxuIjsKKworCUZYX0ZMT0FUIHB4ID0gcHQyLnggLSBwdDEueDsKKwlGWF9GTE9BVCBweSA9IHB0Mi55IC0gcHQxLnk7CisKKwljc0FQIDw8IHB0MS54IDw8ICIgIiA8PCBwdDEueSArIHB5ICogUFdMX0JFWklFUiA8PCAiICIgCisJCTw8IHB0Mi54IC0gcHggKiBQV0xfQkVaSUVSIDw8ICIgIiA8PCBwdDIueSA8PCAiICIKKwkJPDwgcHQyLnggPDwgIiAiIDw8IHB0Mi55IDw8ICIgY1xuIjsKKworCXB4ID0gcHQzLnggLSBwdDIueDsKKwlweSA9IHB0Mi55IC0gcHQzLnk7CisKKwljc0FQIDw8IHB0Mi54ICsgcHggKiBQV0xfQkVaSUVSIDw8ICIgIiA8PCBwdDIueSA8PCAiICIgCisJCTw8IHB0My54IDw8ICIgIiA8PCBwdDMueSArIHB5ICogUFdMX0JFWklFUiA8PCAiICIKKwkJPDwgcHQzLnggPDwgIiAiIDw8IHB0My55IDw8ICIgY1xuIjsKKworCXB4ID0gcHQzLnggLSBwdDQueDsKKwlweSA9IHB0My55IC0gcHQ0Lnk7CisKKwljc0FQIDw8IHB0My54IDw8ICIgIiA8PCBwdDMueSAtIHB5ICogUFdMX0JFWklFUiA8PCAiICIgCisJCTw8IHB0NC54ICsgcHggKiBQV0xfQkVaSUVSIDw8ICIgIiA8PCBwdDQueSA8PCAiICIKKwkJPDwgcHQ0LnggPDwgIiAiIDw8IHB0NC55IDw8ICIgY1xuIjsKKworCXB4ID0gcHQ0LnggLSBwdDEueDsKKwlweSA9IHB0MS55IC0gcHQ0Lnk7CisKKwljc0FQIDw8IHB0NC54IC0gcHggKiBQV0xfQkVaSUVSIDw8ICIgIiA8PCBwdDQueSA8PCAiICIgCisJCTw8IHB0MS54IDw8ICIgIiA8PCBwdDEueSAtIHB5ICogUFdMX0JFWklFUiA8PCAiICIKKwkJPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgY1xuIjsKKworCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfQ3Jvc3MoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KQoreworCUNGWF9CeXRlVGV4dEJ1ZiBjc0FQOworCisJY3NBUCA8PCBjckJCb3gubGVmdCA8PCAiICIgPDwgY3JCQm94LnRvcCA8PCAiIG1cbiI7CisJY3NBUCA8PCBjckJCb3gucmlnaHQgPDwgIiAiIDw8IGNyQkJveC5ib3R0b20gPDwgIiBsXG4iOworCWNzQVAgPDwgY3JCQm94LmxlZnQgPDwgIiAiIDw8IGNyQkJveC5ib3R0b20gPDwgIiBtXG4iOworCWNzQVAgPDwgY3JCQm94LnJpZ2h0IDw8ICIgIiA8PCBjckJCb3gudG9wIDw8ICIgbFxuIjsKKworCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfRGlhbW9uZChjb25zdCBDUERGX1JlY3QgJiBjckJCb3gpCit7CisJQ0ZYX0J5dGVUZXh0QnVmIGNzQVA7CisKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisKKwlDUERGX1BvaW50IHB0MShjckJCb3gubGVmdCxjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDIpOworCUNQREZfUG9pbnQgcHQyKGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gMixjckJCb3gudG9wKTsKKwlDUERGX1BvaW50IHB0MyhjckJCb3gucmlnaHQsY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgLyAyKTsKKwlDUERGX1BvaW50IHB0NChjckJCb3gubGVmdCArIGZXaWR0aCAvIDIsY3JCQm94LmJvdHRvbSk7CisJCisJY3NBUCA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBtXG4iOworCWNzQVAgPDwgcHQyLnggPDwgIiAiIDw8IHB0Mi55IDw8ICIgbFxuIjsKKwljc0FQIDw8IHB0My54IDw8ICIgIiA8PCBwdDMueSA8PCAiIGxcbiI7CisJY3NBUCA8PCBwdDQueCA8PCAiICIgPDwgcHQ0LnkgPDwgIiBsXG4iOworCWNzQVAgPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55IDw8ICIgbFxuIjsKKworCXJldHVybiBjc0FQLkdldEJ5dGVTdHJpbmcoKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QVBfU3F1YXJlKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgY3NBUDsKKworCWNzQVAgPDwgY3JCQm94LmxlZnQgPDwgIiAiIDw8IGNyQkJveC50b3AgPDwgIiBtXG4iOworCWNzQVAgPDwgY3JCQm94LnJpZ2h0IDw8ICIgIiA8PCBjckJCb3gudG9wIDw8ICIgbFxuIjsKKwljc0FQIDw8IGNyQkJveC5yaWdodCA8PCAiICIgPDwgY3JCQm94LmJvdHRvbSA8PCAiIGxcbiI7CisJY3NBUCA8PCBjckJCb3gubGVmdCA8PCAiICIgPDwgY3JCQm94LmJvdHRvbSA8PCAiIGxcbiI7CisJY3NBUCA8PCBjckJCb3gubGVmdCA8PCAiICIgPDwgY3JCQm94LnRvcCA8PCAiIGxcbiI7CisKKwlyZXR1cm4gY3NBUC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFQX1N0YXIoY29uc3QgQ1BERl9SZWN0ICYgY3JCQm94KQoreworCUNGWF9CeXRlVGV4dEJ1ZiBjc0FQOworCisJRlhfRkxPQVQgZlJhZGl1cyA9IChjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbSkvKDErKEZYX0ZMT0FUKWNvcyhQV0xfUEkvNS4wZikpOworCUNQREZfUG9pbnQgcHRDZW50ZXIgPSBDUERGX1BvaW50KChjckJCb3gubGVmdCArIGNyQkJveC5yaWdodCkgLyAyLjBmLChjckJCb3gudG9wICsgY3JCQm94LmJvdHRvbSkgLyAyLjBmKTsKKwkKKwlGWF9GTE9BVCBweFs1XSxweVs1XTsKKworCUZYX0ZMT0FUIGZBbmdlbCA9IFBXTF9QSS8xMC4wZjsKKworCWZvciAoRlhfSU5UMzIgaT0wOyBpPDU7IGkrKykKKwl7CisJCXB4W2ldID0gcHRDZW50ZXIueCArIGZSYWRpdXMgKiAoRlhfRkxPQVQpY29zKGZBbmdlbCk7CisJCXB5W2ldID0gcHRDZW50ZXIueSArIGZSYWRpdXMgKiAoRlhfRkxPQVQpc2luKGZBbmdlbCk7CisKKwkJZkFuZ2VsICs9IFBXTF9QSSAqIDIgLyA1LjBmOworCX0KKworCWNzQVAgPDwgcHhbMF0gPDwgIiAiIDw8IHB5WzBdIDw8ICIgbVxuIjsKKworCUZYX0lOVDMyIG5OZXh0ID0gMDsKKwlmb3IgKEZYX0lOVDMyIGo9MDsgajw1OyBqKyspCisJeworCQluTmV4dCArPSAyOworCQlpZiAobk5leHQgPj0gNSkgbk5leHQgLT0gNTsKKwkJY3NBUCA8PCBweFtuTmV4dF0gPDwgIiAiIDw8IHB5W25OZXh0XSA8PCAiIGxcbiI7CisJfQorCisJcmV0dXJuIGNzQVAuR2V0Qnl0ZVN0cmluZygpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRBUF9IYWxmQ2lyY2xlKGNvbnN0IENQREZfUmVjdCAmIGNyQkJveCxGWF9GTE9BVCBmUm90YXRlKQoreworCUNGWF9CeXRlVGV4dEJ1ZiBjc0FQOworCisJRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7CisJRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOworCisJQ1BERl9Qb2ludCBwdDEoLWZXaWR0aC8yLDApOworCUNQREZfUG9pbnQgcHQyKDAsZkhlaWdodC8yKTsKKwlDUERGX1BvaW50IHB0MyhmV2lkdGgvMiwwKTsKKworCUZYX0ZMT0FUIHB4LHB5OworCisJY3NBUCA8PCBjb3MoZlJvdGF0ZSkgPDwgIiAiIDw8IHNpbihmUm90YXRlKSA8PCAiICIgPDwgLXNpbihmUm90YXRlKSA8PCAiICIgPDwgY29zKGZSb3RhdGUpIDw8ICIgIiAKKwkJPDwgY3JCQm94LmxlZnQgKyBmV2lkdGggLyAyIDw8ICIgIiA8PCBjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDIgPDwgIiBjbVxuIjsKKworCisJY3NBUCA8PCBwdDEueCA8PCAiICIgPDwgcHQxLnkgPDwgIiBtXG4iOworCisJcHggPSBwdDIueCAtIHB0MS54OworCXB5ID0gcHQyLnkgLSBwdDEueTsKKworCWNzQVAgPDwgcHQxLnggPDwgIiAiIDw8IHB0MS55ICsgcHkgKiBQV0xfQkVaSUVSIDw8ICIgIiAKKwkJPDwgcHQyLnggLSBweCAqIFBXTF9CRVpJRVIgPDwgIiAiIDw8IHB0Mi55IDw8ICIgIgorCQk8PCBwdDIueCA8PCAiICIgPDwgcHQyLnkgPDwgIiBjXG4iOworCisJcHggPSBwdDMueCAtIHB0Mi54OworCXB5ID0gcHQyLnkgLSBwdDMueTsKKworCWNzQVAgPDwgcHQyLnggKyBweCAqIFBXTF9CRVpJRVIgPDwgIiAiIDw8IHB0Mi55IDw8ICIgIiAKKwkJPDwgcHQzLnggPDwgIiAiIDw8IHB0My55ICsgcHkgKiBQV0xfQkVaSUVSIDw8ICIgIgorCQk8PCBwdDMueCA8PCAiICIgPDwgcHQzLnkgPDwgIiBjXG4iOworCisJcmV0dXJuIGNzQVAuR2V0Qnl0ZVN0cmluZygpOworfQorCisKK0NQREZfUmVjdCBDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdChjb25zdCBDUERGX1JlY3QgJiByY1JlY3QsIEZYX0ZMT0FUIGZTaXplKQoreworCWlmIChyY1JlY3QuSXNFbXB0eSgpKSByZXR1cm4gcmNSZWN0OworCisJQ1BERl9SZWN0IHJjTmV3KHJjUmVjdC5sZWZ0IC0gZlNpemUsCisJCQkJCXJjUmVjdC5ib3R0b20gLSBmU2l6ZSwKKwkJCQkJcmNSZWN0LnJpZ2h0ICsgZlNpemUsCisJCQkJCXJjUmVjdC50b3AgKyBmU2l6ZSk7CisJcmNOZXcuTm9ybWFsaXplKCk7CisJcmV0dXJuIHJjTmV3OworfQorCitDUERGX1JlY3QgQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmNSZWN0LCBGWF9GTE9BVCBmU2l6ZSkKK3sKKwlpZiAocmNSZWN0LklzRW1wdHkoKSkgcmV0dXJuIHJjUmVjdDsKKworCUNQREZfUmVjdCByY05ldyhyY1JlY3QubGVmdCArIGZTaXplLAorCQkJCQlyY1JlY3QuYm90dG9tICsgZlNpemUsCisJCQkJCXJjUmVjdC5yaWdodCAtIGZTaXplLAorCQkJCQlyY1JlY3QudG9wIC0gZlNpemUpOworCXJjTmV3Lk5vcm1hbGl6ZSgpOworCXJldHVybiByY05ldzsKK30KKworQ1BERl9SZWN0IENQV0xfVXRpbHM6OlNjYWxlUmVjdChjb25zdCBDUERGX1JlY3QgJiByY1JlY3QsRlhfRkxPQVQgZlNjYWxlKQoreworCUZYX0ZMT0FUIGZIYWxmV2lkdGggPSAocmNSZWN0LnJpZ2h0IC0gcmNSZWN0LmxlZnQpIC8gMi4wZjsKKwlGWF9GTE9BVCBmSGFsZkhlaWdodCA9IChyY1JlY3QudG9wIC0gcmNSZWN0LmJvdHRvbSkgLyAyLjBmOworCisJQ1BERl9Qb2ludCBwdENlbnRlciA9IENQREZfUG9pbnQoKHJjUmVjdC5sZWZ0ICsgcmNSZWN0LnJpZ2h0KSAvIDIsKHJjUmVjdC50b3AgKyByY1JlY3QuYm90dG9tKSAvIDIpOworCisJcmV0dXJuIENQREZfUmVjdChwdENlbnRlci54IC0gZkhhbGZXaWR0aCAqIGZTY2FsZSwKKwkJCQlwdENlbnRlci55IC0gZkhhbGZIZWlnaHQgKiBmU2NhbGUsCisJCQkJcHRDZW50ZXIueCArIGZIYWxmV2lkdGggKiBmU2NhbGUsCisJCQkJcHRDZW50ZXIueSArIGZIYWxmSGVpZ2h0ICogZlNjYWxlKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmVjdCxjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpCit7CisJQ0ZYX0J5dGVUZXh0QnVmIHNBcHBTdHJlYW07CisKKwlDRlhfQnl0ZVN0cmluZyBzQ29sb3IgPSBHZXRDb2xvckFwcFN0cmVhbShjb2xvcixUUlVFKTsKKwlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkKKwl7CisJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgc0NvbG9yOworCQlzQXBwU3RyZWFtIDw8IHJlY3QubGVmdCA8PCAiICIgPDwgcmVjdC5ib3R0b20gPDwgIiAiCisJCQk8PCByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0IDw8ICIgIiA8PCByZWN0LnRvcCAtIHJlY3QuYm90dG9tIDw8ICIgcmUgZlxuUVxuIjsJCQorCX0KKwkKKwlyZXR1cm4gc0FwcFN0cmVhbS5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldENpcmNsZUZpbGxBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmVjdCxjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpCit7CisJQ0ZYX0J5dGVUZXh0QnVmIHNBcHBTdHJlYW07CisKKwlDRlhfQnl0ZVN0cmluZyBzQ29sb3IgPSBHZXRDb2xvckFwcFN0cmVhbShjb2xvcixUUlVFKTsKKwlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkKKwl7CisJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0NpcmNsZShyZWN0KSA8PCAiZlxuUVxuIjsJCQorCX0KKwkKKwlyZXR1cm4gc0FwcFN0cmVhbS5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NQREZfUmVjdCBDUFdMX1V0aWxzOjpHZXRDZW50ZXJTcXVhcmUoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkKK3sKKwlGWF9GTE9BVCBmV2lkdGggPSByZWN0LnJpZ2h0IC0gIHJlY3QubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gcmVjdC50b3AgLSByZWN0LmJvdHRvbTsKKworCUZYX0ZMT0FUIGZDZW50ZXJYID0gKHJlY3QubGVmdCArIHJlY3QucmlnaHQpLzIuMGY7CisJRlhfRkxPQVQgZkNlbnRlclkgPSAocmVjdC50b3AgKyByZWN0LmJvdHRvbSkvMi4wZjsKKworCUZYX0ZMT0FUIGZSYWRpdXMgPSAoZldpZHRoID4gZkhlaWdodCkgPyBmSGVpZ2h0IC8gMiA6IGZXaWR0aCAvIDI7CisKKwlyZXR1cm4gQ1BERl9SZWN0KGZDZW50ZXJYIC0gZlJhZGl1cyxmQ2VudGVyWSAtIGZSYWRpdXMsZkNlbnRlclggKyBmUmFkaXVzLGZDZW50ZXJZICsgZlJhZGl1cyk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEVkaXRBcHBTdHJlYW0oSUZYX0VkaXQqIHBFZGl0LCBjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQsIGNvbnN0IENQVlRfV29yZFJhbmdlICogcFJhbmdlLCAKKwkJCQkJCQkJCQkJCQkJRlhfQk9PTCBiQ29udGludW91cywgRlhfV09SRCBTdWJXb3JkKQoreworCXJldHVybiBJRlhfRWRpdDo6R2V0RWRpdEFwcGVhcmFuY2VTdHJlYW0ocEVkaXQscHRPZmZzZXQscFJhbmdlLGJDb250aW51b3VzLFN1YldvcmQpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRFZGl0U2VsQXBwU3RyZWFtKElGWF9FZGl0KiBwRWRpdCwgY29uc3QgQ1BERl9Qb2ludCAmIHB0T2Zmc2V0LCAKKwkJCQkJCQkJY29uc3QgQ1BWVF9Xb3JkUmFuZ2UgKiBwUmFuZ2UpCit7CisJcmV0dXJuIElGWF9FZGl0OjpHZXRTZWxlY3RBcHBlYXJhbmNlU3RyZWFtKHBFZGl0LHB0T2Zmc2V0LHBSYW5nZSk7Cit9CisKK3N0YXRpYyBDRlhfQnl0ZVN0cmluZyBHZXRTcXVpZ2dseUFwcGVhcmFuY2VTdHJlYW0oRlhfRkxPQVQgZlN0YXJ0WCwgRlhfRkxPQVQgZkVuZFgsIEZYX0ZMT0FUIGZZLCBGWF9GTE9BVCBmU3RlcCkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc1JldDsKKworCXNSZXQgPDwgIjAgd1xuIiA8PCBmU3RhcnRYIDw8ICIgIiA8PCBmWSA8PCAiIG1cbiI7CisKKwlGWF9GTE9BVCBmeDsKKwlGWF9JTlQzMiBpOworCisJZm9yIChpPTEsZng9ZlN0YXJ0WCtmU3RlcDsgZng8ZkVuZFg7IGZ4Kz1mU3RlcCxpKyspCisJeworCQlzUmV0IDw8IGZ4IDw8ICIgIiA8PCBmWSArIChpJjEpKmZTdGVwIDw8ICIgbFxuIjsKKwl9CisKKwlzUmV0IDw8ICJTXG4iOworCisJcmV0dXJuIHNSZXQuR2V0Qnl0ZVN0cmluZygpOworfQorCitzdGF0aWMgQ0ZYX0J5dGVTdHJpbmcgR2V0V29yZFNwZWxsQ2hlY2tBcHBlYXJhbmNlU3RyZWFtKElGWF9FZGl0X0l0ZXJhdG9yKiBwSXRlcmF0b3IsIGNvbnN0IENQREZfUG9pbnQgJiBwdE9mZnNldCwKKwkJCQkJCQkJCQkJCQkJCQkgIGNvbnN0IENQVlRfV29yZFJhbmdlICYgd3JXb3JkKQoreworCUNGWF9CeXRlVGV4dEJ1ZiBzUmV0OworCisJRlhfRkxPQVQgZlN0YXJ0WCA9IDAuMGY7CisJRlhfRkxPQVQgZkVuZFggPSAwLjBmOworCUZYX0ZMT0FUIGZZID0gMC4wZjsKKwlGWF9GTE9BVCBmU3RlcCA9IDAuMGY7IAorCisJRlhfQk9PTCBiQnJlYWsgPSBGQUxTRTsKKworCWlmIChwSXRlcmF0b3IpCisJeworCQlwSXRlcmF0b3ItPlNldEF0KHdyV29yZC5CZWdpblBvcyk7CisKKwkJZG8KKwkJeworCQkJQ1BWVF9Xb3JkUGxhY2UgcGxhY2UgPSBwSXRlcmF0b3ItPkdldEF0KCk7CisKKwkJCUNQVlRfTGluZSBsaW5lOwkJCQkKKwkJCWlmIChwSXRlcmF0b3ItPkdldExpbmUobGluZSkpCisJCQl7CisJCQkJZlkgPSBsaW5lLnB0TGluZS55OworCQkJCWZTdGVwID0gKGxpbmUuZkxpbmVBc2NlbnQgLSBsaW5lLmZMaW5lRGVzY2VudCkgLyAxNi4wZjsKKwkJCX0KKworCQkJaWYgKHBsYWNlLkxpbmVDbXAod3JXb3JkLkJlZ2luUG9zKSA9PSAwKQorCQkJeworCQkJCXBJdGVyYXRvci0+U2V0QXQod3JXb3JkLkJlZ2luUG9zKTsKKwkJCQlDUFZUX1dvcmQgd29yZDsKKwkJCQlpZiAocEl0ZXJhdG9yLT5HZXRXb3JkKHdvcmQpKQorCQkJCXsKKwkJCQkJZlN0YXJ0WCA9IHdvcmQucHRXb3JkLng7CisJCQkJfQorCQkJfQorCQkJZWxzZQorCQkJeworCQkJCWZTdGFydFggPSBsaW5lLnB0TGluZS54OworCQkJfQorCisJCQlpZiAocGxhY2UuTGluZUNtcCh3cldvcmQuRW5kUG9zKSA9PSAwKQorCQkJeworCQkJCXBJdGVyYXRvci0+U2V0QXQod3JXb3JkLkVuZFBvcyk7CisJCQkJQ1BWVF9Xb3JkIHdvcmQ7CisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCWZFbmRYID0gd29yZC5wdFdvcmQueCArIHdvcmQuZldpZHRoOworCQkJCX0KKworCQkJCWJCcmVhayA9IFRSVUU7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJZkVuZFggPSBsaW5lLnB0TGluZS54ICsgbGluZS5mTGluZVdpZHRoOworCQkJfQorCisJCQlzUmV0IDw8IEdldFNxdWlnZ2x5QXBwZWFyYW5jZVN0cmVhbShmU3RhcnRYICsgcHRPZmZzZXQueCwgZkVuZFggKyBwdE9mZnNldC54LCBmWSArIHB0T2Zmc2V0LnksZlN0ZXApOworCisJCQlpZiAoYkJyZWFrKSBicmVhazsKKwkJfQorCQl3aGlsZSAocEl0ZXJhdG9yLT5OZXh0TGluZSgpKTsKKwl9CisKKwlyZXR1cm4gc1JldC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldFNwZWxsQ2hlY2tBcHBTdHJlYW0oSUZYX0VkaXQqIHBFZGl0LCBJUFdMX1NwZWxsQ2hlY2sqIHBTcGVsbENoZWNrLCBjb25zdCBDUERGX1BvaW50ICYgcHRPZmZzZXQsCisJCQkJCQkJCWNvbnN0IENQVlRfV29yZFJhbmdlICogcFJhbmdlKQoreworCUFTU0VSVChwRWRpdCAhPSBOVUxMKTsKKwlBU1NFUlQocFNwZWxsQ2hlY2sgIT0gTlVMTCk7CisKKwlDRlhfQnl0ZVRleHRCdWYgc1JldDsKKworCWlmIChwUmFuZ2UgJiYgcFJhbmdlLT5Jc0V4aXN0KCkpCisJeworCQlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQorCQl7CisJCQlwSXRlcmF0b3ItPlNldEF0KHBSYW5nZS0+QmVnaW5Qb3MpOworCisJCQlGWF9CT09MIGJMYXRpbldvcmQgPSBGQUxTRTsKKwkJCUNQVlRfV29yZFBsYWNlIHdwV29yZFN0YXJ0OworCQkJQ0ZYX0J5dGVTdHJpbmcgc1dvcmQ7CisKKwkJCUNQVlRfV29yZFBsYWNlIG9sZHBsYWNlOworCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkKKwkJCXsKKwkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKwkJCQlpZiAocFJhbmdlICYmIHBsYWNlLldvcmRDbXAocFJhbmdlLT5FbmRQb3MpID4gMCkgYnJlYWs7CQkJCQorCisJCQkJQ1BWVF9Xb3JkIHdvcmQ7CisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCWlmIChGWF9FRElUX0lTTEFUSU5XT1JEKHdvcmQuV29yZCkpCisJCQkJCXsKKwkJCQkJCWlmICghYkxhdGluV29yZCkKKwkJCQkJCXsKKwkJCQkJCQl3cFdvcmRTdGFydCA9IHBsYWNlOworCQkJCQkJCWJMYXRpbldvcmQgPSBUUlVFOwkJCQkJCQkJCisJCQkJCQl9CisKKwkJCQkJCXNXb3JkICs9IChjaGFyKXdvcmQuV29yZDsKKwkJCQkJCW9sZHBsYWNlID0gcGxhY2U7CisJCQkJCX0KKwkJCQkJZWxzZQorCQkJCQl7CisJCQkJCQlpZiAoYkxhdGluV29yZCkKKwkJCQkJCXsKKwkJCQkJCQlpZiAoIXBTcGVsbENoZWNrLT5DaGVja1dvcmQoc1dvcmQpKQorCQkJCQkJCXsKKwkJCQkJCQkJc1JldCA8PCBHZXRXb3JkU3BlbGxDaGVja0FwcGVhcmFuY2VTdHJlYW0ocEl0ZXJhdG9yLHB0T2Zmc2V0LENQVlRfV29yZFJhbmdlKHdwV29yZFN0YXJ0LG9sZHBsYWNlKSk7CisJCQkJCQkJCXBJdGVyYXRvci0+U2V0QXQocGxhY2UpOworCQkJCQkJCX0KKwkJCQkJCQliTGF0aW5Xb3JkID0gRkFMU0U7CisJCQkJCQl9CisKKwkJCQkJCXNXb3JkLkVtcHR5KCk7CisJCQkJCX0KKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJaWYgKGJMYXRpbldvcmQpCisJCQkJCXsKKwkJCQkJCWlmICghcFNwZWxsQ2hlY2stPkNoZWNrV29yZChzV29yZCkpCisJCQkJCQkJc1JldCA8PCBHZXRXb3JkU3BlbGxDaGVja0FwcGVhcmFuY2VTdHJlYW0ocEl0ZXJhdG9yLHB0T2Zmc2V0LENQVlRfV29yZFJhbmdlKHdwV29yZFN0YXJ0LG9sZHBsYWNlKSk7CisJCQkJCQliTGF0aW5Xb3JkID0gRkFMU0U7CisJCQkJCQlzV29yZC5FbXB0eSgpOworCQkJCQl9CisJCQkJfQorCQkJfQorCisJCQlpZiAoYkxhdGluV29yZCkKKwkJCXsKKwkJCQlpZiAoIXBTcGVsbENoZWNrLT5DaGVja1dvcmQoc1dvcmQpKQorCQkJCQlzUmV0IDw8IEdldFdvcmRTcGVsbENoZWNrQXBwZWFyYW5jZVN0cmVhbShwSXRlcmF0b3IscHRPZmZzZXQsQ1BWVF9Xb3JkUmFuZ2Uod3BXb3JkU3RhcnQsb2xkcGxhY2UpKTsKKworCQkJCWJMYXRpbldvcmQgPSBGQUxTRTsKKwkJCQlzV29yZC5FbXB0eSgpOworCQkJfQorCQl9CisJfQorCisJcmV0dXJuIHNSZXQuR2V0Qnl0ZVN0cmluZygpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRUZXh0QXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCxJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAsCisJCQkJCQkJCQkJCQkJCWNvbnN0IENGWF9XaWRlU3RyaW5nICYgc1RleHQsIEZYX0lOVDMyIG5BbGlnbm1lbnRILCBGWF9JTlQzMiBuQWxpZ25tZW50ViwKKwkJCQkJCQkJCQkJCQkJRlhfRkxPQVQgZkZvbnRTaXplLCBGWF9CT09MIGJNdWx0aUxpbmUsIEZYX0JPT0wgYkF1dG9SZXR1cm4sIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpCit7CisJQ0ZYX0J5dGVUZXh0QnVmIHNSZXQ7CisKKwlpZiAoSUZYX0VkaXQgKiBwRWRpdCA9IElGWF9FZGl0OjpOZXdFZGl0KCkpCisJewkJCQorCQlwRWRpdC0+U2V0Rm9udE1hcChwRm9udE1hcCk7CisKKwkJcEVkaXQtPlNldFBsYXRlUmVjdChyY0JCb3gpOworCQlwRWRpdC0+U2V0QWxpZ25tZW50SChuQWxpZ25tZW50SCk7CisJCXBFZGl0LT5TZXRBbGlnbm1lbnRWKG5BbGlnbm1lbnRWKTsKKwkJcEVkaXQtPlNldE11bHRpTGluZShiTXVsdGlMaW5lKTsKKwkJcEVkaXQtPlNldEF1dG9SZXR1cm4oYkF1dG9SZXR1cm4pOworCQlpZiAoSXNGbG9hdFplcm8oZkZvbnRTaXplKSkKKwkJCXBFZGl0LT5TZXRBdXRvRm9udFNpemUoVFJVRSk7CisJCWVsc2UKKwkJCXBFZGl0LT5TZXRGb250U2l6ZShmRm9udFNpemUpOworCQlwRWRpdC0+SW5pdGlhbGl6ZSgpOworCisJCXBFZGl0LT5TZXRUZXh0KHNUZXh0KTsKKwkJCisJCUNGWF9CeXRlU3RyaW5nIHNFZGl0ID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShwRWRpdCwgQ1BERl9Qb2ludCgwLjBmLDAuMGYpKTsKKwkJaWYgKHNFZGl0LkdldExlbmd0aCgpID4gMCkKKwkJeworCQkJc1JldCA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JUZXh0KSA8PCBzRWRpdCA8PCAiRVRcbiI7CisJCX0KKwkJCisJCUlGWF9FZGl0OjpEZWxFZGl0KHBFZGl0KTsKKwl9CisKKwlyZXR1cm4gc1JldC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldFB1c2hCdXR0b25BcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LAorCQkJCQkJCQkJCQlJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXAsCisJCQkJCQkJCQkJCUNQREZfU3RyZWFtICogcEljb25TdHJlYW0sCisJCQkJCQkJCQkJCUNQREZfSWNvbkZpdCAmIEljb25GaXQsCisJCQkJCQkJCQkJCWNvbnN0IENGWF9XaWRlU3RyaW5nICYgc0xhYmVsLAkJCQkJCQkJCQkJCisJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQsCisJCQkJCQkJCQkJCUZYX0ZMT0FUIGZGb250U2l6ZSwKKwkJCQkJCQkJCQkJRlhfSU5UMzIgbkxheU91dCkKK3sKKwljb25zdCBGWF9GTE9BVCBmQXV0b0ZvbnRTY2FsZSA9IDEuMGYgLyAzLjBmOwkKKworCWlmIChJRlhfRWRpdCAqIHBFZGl0ID0gSUZYX0VkaXQ6Ok5ld0VkaXQoKSkKKwl7CQkJCisJCXBFZGl0LT5TZXRGb250TWFwKHBGb250TWFwKTsKKworCQlwRWRpdC0+U2V0QWxpZ25tZW50SCgxKTsKKwkJcEVkaXQtPlNldEFsaWdubWVudFYoMSk7CisJCXBFZGl0LT5TZXRNdWx0aUxpbmUoRkFMU0UpOworCQlwRWRpdC0+U2V0QXV0b1JldHVybihGQUxTRSk7CisJCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQorCQkJcEVkaXQtPlNldEF1dG9Gb250U2l6ZShUUlVFKTsKKwkJZWxzZQorCQkJcEVkaXQtPlNldEZvbnRTaXplKGZGb250U2l6ZSk7CisJCXBFZGl0LT5Jbml0aWFsaXplKCk7CisJCXBFZGl0LT5TZXRUZXh0KHNMYWJlbCk7CisKKwkJQ1BERl9SZWN0IHJjTGFiZWxDb250ZW50ID0gcEVkaXQtPkdldENvbnRlbnRSZWN0KCk7CisJCQorCQlDUFdMX0ljb24gSWNvbjsKKwkJUFdMX0NSRUFURVBBUkFNIGNwOworCQljcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEU7CisJCUljb24uQ3JlYXRlKGNwKTsKKwkJSWNvbi5TZXRJY29uRml0KCZJY29uRml0KTsKKwkJSWNvbi5TZXRQREZTdHJlYW0ocEljb25TdHJlYW0pOworCisJCUNQREZfUmVjdCByY0xhYmVsID0gQ1BERl9SZWN0KDAsMCwwLDApOworCQlDUERGX1JlY3QgcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOworCQlGWF9GTE9BVCBmV2lkdGggPSAwLjBmOworCQlGWF9GTE9BVCBmSGVpZ2h0ID0gMC4wZjsKKworCQlzd2l0Y2ggKG5MYXlPdXQpCisJCXsKKwkJY2FzZSBQUEJMX0xBQkVMOgorCQkJcmNMYWJlbCA9IHJjQkJveDsKKwkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsKKwkJCWJyZWFrOworCQljYXNlIFBQQkxfSUNPTjoKKwkJCXJjSWNvbiA9IHJjQkJveDsKKwkJCXJjTGFiZWwgPSBDUERGX1JlY3QoMCwwLDAsMCk7CisJCQlicmVhazsKKwkJY2FzZSBQUEJMX0lDT05UT1BMQUJFTEJPVFRPTToKKworCQkJaWYgKHBJY29uU3RyZWFtKQorCQkJeworCQkJCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQorCQkJCXsKKwkJCQkJZkhlaWdodCA9IHJjQkJveC50b3AgLSByY0JCb3guYm90dG9tOworCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNCQm94LnJpZ2h0LHJjQkJveC5ib3R0b20gKyBmSGVpZ2h0ICogZkF1dG9Gb250U2NhbGUpOworCQkJCQlyY0ljb24gPSBDUERGX1JlY3QocmNCQm94LmxlZnQscmNMYWJlbC50b3AscmNCQm94LnJpZ2h0LHJjQkJveC50b3ApOworCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQlmSGVpZ2h0ID0gcmNMYWJlbENvbnRlbnQuSGVpZ2h0KCk7CisKKwkJCQkJaWYgKHJjQkJveC5ib3R0b20gKyBmSGVpZ2h0ID4gcmNCQm94LnRvcCkKKwkJCQkJewkJCQorCQkJCQkJcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOwkJCQkKKwkJCQkJCXJjTGFiZWwgPSByY0JCb3g7CisJCQkJCX0KKwkJCQkJZWxzZQorCQkJCQl7CisJCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNCQm94LnJpZ2h0LHJjQkJveC5ib3R0b20gKyBmSGVpZ2h0KTsKKwkJCQkJCXJjSWNvbiA9IENQREZfUmVjdChyY0JCb3gubGVmdCxyY0xhYmVsLnRvcCxyY0JCb3gucmlnaHQscmNCQm94LnRvcCk7CQorCQkJCQl9CisJCQkJfQorCQkJfQorCQkJZWxzZQorCQkJeworCQkJCXJjTGFiZWwgPSByY0JCb3g7CisJCQkJcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOworCQkJfQorCisJCQlicmVhazsKKwkJY2FzZSBQUEJMX0xBQkVMVE9QSUNPTkJPVFRPTToKKworCQkJaWYgKHBJY29uU3RyZWFtKQorCQkJeworCQkJCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQorCQkJCXsKKwkJCQkJZkhlaWdodCA9IHJjQkJveC50b3AgLSByY0JCb3guYm90dG9tOworCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC50b3AgLSBmSGVpZ2h0ICogZkF1dG9Gb250U2NhbGUgLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsKKwkJCQkJcmNJY29uID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNCQm94LnJpZ2h0LHJjTGFiZWwuYm90dG9tKTsKKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJZkhlaWdodCA9IHJjTGFiZWxDb250ZW50LkhlaWdodCgpOworCisJCQkJCWlmIChyY0JCb3guYm90dG9tICsgZkhlaWdodCA+IHJjQkJveC50b3ApCisJCQkJCXsJCQkKKwkJCQkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsJCQkJCisJCQkJCQlyY0xhYmVsID0gcmNCQm94OworCQkJCQl9CisJCQkJCWVsc2UKKwkJCQkJeworCQkJCQkJcmNMYWJlbCA9IENQREZfUmVjdChyY0JCb3gubGVmdCxyY0JCb3gudG9wIC0gZkhlaWdodCxyY0JCb3gucmlnaHQscmNCQm94LnRvcCk7CisJCQkJCQlyY0ljb24gPSBDUERGX1JlY3QocmNCQm94LmxlZnQscmNCQm94LmJvdHRvbSxyY0JCb3gucmlnaHQscmNMYWJlbC5ib3R0b20pOwkJCisJCQkJCX0KKwkJCQl9CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJcmNMYWJlbCA9IHJjQkJveDsKKwkJCQlyY0ljb24gPSBDUERGX1JlY3QoMCwwLDAsMCk7CisJCQl9CisKKwkJCWJyZWFrOworCQljYXNlIFBQQkxfSUNPTkxFRlRMQUJFTFJJR0hUOgorCisJCQlpZiAocEljb25TdHJlYW0pCisJCQl7CisJCQkJaWYgKElzRmxvYXRaZXJvKGZGb250U2l6ZSkpCisJCQkJeworCQkJCQlmV2lkdGggPSByY0JCb3gucmlnaHQgLSByY0JCb3gubGVmdDsKKwkJCQkJcmNMYWJlbCA9IENQREZfUmVjdChyY0JCb3gucmlnaHQgLSBmV2lkdGggKiBmQXV0b0ZvbnRTY2FsZSxyY0JCb3guYm90dG9tLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsKKwkJCQkJcmNJY29uID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNMYWJlbC5sZWZ0LHJjQkJveC50b3ApOworCisJCQkJCWlmIChyY0xhYmVsQ29udGVudC5XaWR0aCgpIDwgZldpZHRoICogZkF1dG9Gb250U2NhbGUpCisJCQkJCXsJCQkJCQkJCisJCQkJCX0KKwkJCQkJZWxzZSAKKwkJCQkJeworCQkJCQkJaWYgKHJjTGFiZWxDb250ZW50LldpZHRoKCkgPCBmV2lkdGgpCisJCQkJCQl7CisJCQkJCQkJcmNMYWJlbCA9IENQREZfUmVjdChyY0JCb3gucmlnaHQgLSByY0xhYmVsQ29udGVudC5XaWR0aCgpLHJjQkJveC5ib3R0b20scmNCQm94LnJpZ2h0LHJjQkJveC50b3ApOworCQkJCQkJCXJjSWNvbiA9IENQREZfUmVjdChyY0JCb3gubGVmdCxyY0JCb3guYm90dG9tLHJjTGFiZWwubGVmdCxyY0JCb3gudG9wKTsKKwkJCQkJCX0KKwkJCQkJCWVsc2UKKwkJCQkJCXsKKwkJCQkJCQlyY0xhYmVsID0gcmNCQm94OworCQkJCQkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsKKwkJCQkJCX0KKwkJCQkJfQorCQkJCX0KKwkJCQllbHNlCisJCQkJeworCQkJCQlmV2lkdGggPSByY0xhYmVsQ29udGVudC5XaWR0aCgpOworCisJCQkJCWlmIChyY0JCb3gubGVmdCArIGZXaWR0aCA+IHJjQkJveC5yaWdodCkKKwkJCQkJeworCQkJCQkJcmNMYWJlbCA9IHJjQkJveDsKKwkJCQkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsKKwkJCQkJfQorCQkJCQllbHNlCisJCQkJCXsKKwkJCQkJCXJjTGFiZWwgPSBDUERGX1JlY3QocmNCQm94LnJpZ2h0IC0gZldpZHRoLHJjQkJveC5ib3R0b20scmNCQm94LnJpZ2h0LHJjQkJveC50b3ApOworCQkJCQkJcmNJY29uID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNMYWJlbC5sZWZ0LHJjQkJveC50b3ApOwkJCQorCQkJCQl9CisJCQkJfQorCQkJfQorCQkJZWxzZQorCQkJeworCQkJCXJjTGFiZWwgPSByY0JCb3g7CisJCQkJcmNJY29uID0gQ1BERl9SZWN0KDAsMCwwLDApOworCQkJfQorCisJCQlicmVhazsKKwkJY2FzZSBQUEJMX0xBQkVMTEVGVElDT05SSUdIVDoKKworCQkJaWYgKHBJY29uU3RyZWFtKQorCQkJeworCQkJCWlmIChJc0Zsb2F0WmVybyhmRm9udFNpemUpKQorCQkJCXsKKwkJCQkJZldpZHRoID0gcmNCQm94LnJpZ2h0IC0gcmNCQm94LmxlZnQ7CisJCQkJCXJjTGFiZWwgPSBDUERGX1JlY3QocmNCQm94LmxlZnQscmNCQm94LmJvdHRvbSxyY0JCb3gubGVmdCArIGZXaWR0aCAqIGZBdXRvRm9udFNjYWxlLHJjQkJveC50b3ApOworCQkJCQlyY0ljb24gPSBDUERGX1JlY3QocmNMYWJlbC5yaWdodCxyY0JCb3guYm90dG9tLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsKKworCQkJCQlpZiAocmNMYWJlbENvbnRlbnQuV2lkdGgoKSA8IGZXaWR0aCAqIGZBdXRvRm9udFNjYWxlKQorCQkJCQl7CQkJCQkJCQorCQkJCQl9CisJCQkJCWVsc2UgCisJCQkJCXsKKwkJCQkJCWlmIChyY0xhYmVsQ29udGVudC5XaWR0aCgpIDwgZldpZHRoKQorCQkJCQkJeworCQkJCQkJCXJjTGFiZWwgPSBDUERGX1JlY3QocmNCQm94LmxlZnQscmNCQm94LmJvdHRvbSxyY0JCb3gubGVmdCArIHJjTGFiZWxDb250ZW50LldpZHRoKCkscmNCQm94LnRvcCk7CisJCQkJCQkJcmNJY29uID0gQ1BERl9SZWN0KHJjTGFiZWwucmlnaHQscmNCQm94LmJvdHRvbSxyY0JCb3gucmlnaHQscmNCQm94LnRvcCk7CisJCQkJCQl9CisJCQkJCQllbHNlCisJCQkJCQl7CisJCQkJCQkJcmNMYWJlbCA9IHJjQkJveDsKKwkJCQkJCQlyY0ljb24gPSBDUERGX1JlY3QoMCwwLDAsMCk7CisJCQkJCQl9CisJCQkJCX0KKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJZldpZHRoID0gcmNMYWJlbENvbnRlbnQuV2lkdGgoKTsKKworCQkJCQlpZiAocmNCQm94LmxlZnQgKyBmV2lkdGggPiByY0JCb3gucmlnaHQpCisJCQkJCXsKKwkJCQkJCXJjTGFiZWwgPSByY0JCb3g7CisJCQkJCQlyY0ljb24gPSBDUERGX1JlY3QoMCwwLDAsMCk7CisJCQkJCX0KKwkJCQkJZWxzZQorCQkJCQl7CisJCQkJCQlyY0xhYmVsID0gQ1BERl9SZWN0KHJjQkJveC5sZWZ0LHJjQkJveC5ib3R0b20scmNCQm94LmxlZnQgKyBmV2lkdGgscmNCQm94LnRvcCk7CisJCQkJCQlyY0ljb24gPSBDUERGX1JlY3QocmNMYWJlbC5yaWdodCxyY0JCb3guYm90dG9tLHJjQkJveC5yaWdodCxyY0JCb3gudG9wKTsJCQorCQkJCQl9CQorCQkJCX0KKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlyY0xhYmVsID0gcmNCQm94OworCQkJCXJjSWNvbiA9IENQREZfUmVjdCgwLDAsMCwwKTsKKwkJCX0KKworCQkJYnJlYWs7CisJCWNhc2UgUFBCTF9MQUJFTE9WRVJJQ09OOgorCQkJcmNMYWJlbCA9IHJjQkJveDsKKwkJCXJjSWNvbiA9IHJjQkJveDsKKwkJCWJyZWFrOworCQl9CisKKwkJQ0ZYX0J5dGVUZXh0QnVmIHNBcHBTdHJlYW0sc1RlbXA7CisKKwkJaWYgKCFyY0ljb24uSXNFbXB0eSgpKQorCQl7CisJCQlJY29uLk1vdmUocmNJY29uLCBGQUxTRSwgRkFMU0UpOworCQkJc1RlbXAgPDwgSWNvbi5HZXRJbWFnZUFwcFN0cmVhbSgpOworCQl9CisKKwkJSWNvbi5EZXN0cm95KCk7CisKKwkJaWYgKCFyY0xhYmVsLklzRW1wdHkoKSkKKwkJeworCQkJcEVkaXQtPlNldFBsYXRlUmVjdChyY0xhYmVsKTsKKwkJCUNGWF9CeXRlU3RyaW5nIHNFZGl0ID0gQ1BXTF9VdGlsczo6R2V0RWRpdEFwcFN0cmVhbShwRWRpdCxDUERGX1BvaW50KDAuMGYsMC4wZikpOworCQkJaWYgKHNFZGl0LkdldExlbmd0aCgpID4gMCkKKwkJCXsKKwkJCQlzVGVtcCA8PCAiQlRcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JUZXh0KSA8PCBzRWRpdCA8PCAiRVRcbiI7CisJCQl9CisJCX0KKworCQlJRlhfRWRpdDo6RGVsRWRpdChwRWRpdCk7CisKKwkJaWYgKHNUZW1wLkdldFNpemUoKSA+IDApCisJCXsKKwkJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgcmNCQm94LmxlZnQgPDwgIiAiIDw8IHJjQkJveC5ib3R0b20gPDwgIiAiCisJCQkJPDwgcmNCQm94LnJpZ2h0IC0gcmNCQm94LmxlZnQgPDwgIiAiIDw8IHJjQkJveC50b3AgLSByY0JCb3guYm90dG9tIDw8ICIgcmUgVyBuXG4iOworCQkJc0FwcFN0cmVhbSA8PCBzVGVtcCA8PCAiUVxuIjsKKwkJfQorCisJCXJldHVybiBzQXBwU3RyZWFtLkdldEJ5dGVTdHJpbmcoKTsKKwl9CisKKwlyZXR1cm4gIiI7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcixjb25zdCBGWF9CT09MICYgYkZpbGxPclN0cm9rZSkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc0NvbG9yU3RyZWFtOworCisJc3dpdGNoIChjb2xvci5uQ29sb3JUeXBlKQorCXsJCQorCWNhc2UgQ09MT1JUWVBFX1JHQjoKKwkJc0NvbG9yU3RyZWFtIDw8IGNvbG9yLmZDb2xvcjEgPDwgIiAiIDw8IGNvbG9yLmZDb2xvcjIgPDwgIiAiIDw8IGNvbG9yLmZDb2xvcjMgPDwgIiAiIAorCQkJPDwgKGJGaWxsT3JTdHJva2UgPyAicmciIDogIlJHIikgPDwgIlxuIjsKKwkJYnJlYWs7CisJY2FzZSBDT0xPUlRZUEVfR1JBWToKKwkJc0NvbG9yU3RyZWFtIDw8IGNvbG9yLmZDb2xvcjEgPDwgIiAiIDw8IChiRmlsbE9yU3Ryb2tlID8gImciIDogIkciKSA8PCAiXG4iOworCQlicmVhazsKKwljYXNlIENPTE9SVFlQRV9DTVlLOgorCQlzQ29sb3JTdHJlYW0gPDwgY29sb3IuZkNvbG9yMSA8PCAiICIgPDwgY29sb3IuZkNvbG9yMiA8PCAiICIgPDwgY29sb3IuZkNvbG9yMyA8PCAiICIgPDwgY29sb3IuZkNvbG9yNCA8PCAiICIgCisJCQk8PCAoYkZpbGxPclN0cm9rZSA/ICJrIiA6ICJLIikgPDwgIlxuIjsKKwkJYnJlYWs7CisJfQorCisJcmV0dXJuIHNDb2xvclN0cmVhbS5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEJvcmRlckFwcFN0cmVhbShjb25zdCBDUERGX1JlY3QgJiByZWN0LCBGWF9GTE9BVCBmV2lkdGgsCisJCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yICYgY29sb3IsIGNvbnN0IENQV0xfQ29sb3IgJiBjckxlZnRUb3AsIGNvbnN0IENQV0xfQ29sb3IgJiBjclJpZ2h0Qm90dG9tLAorCQkJCQkJCQkJCQkJRlhfSU5UMzIgblN0eWxlLCBjb25zdCBDUFdMX0Rhc2ggJiBkYXNoKQoreworCUNGWF9CeXRlVGV4dEJ1ZiBzQXBwU3RyZWFtOworCUNGWF9CeXRlU3RyaW5nIHNDb2xvcjsKKworCUZYX0ZMT0FUIGZMZWZ0ID0gcmVjdC5sZWZ0OworCUZYX0ZMT0FUIGZSaWdodCA9IHJlY3QucmlnaHQ7CisJRlhfRkxPQVQgZlRvcCA9IHJlY3QudG9wOworCUZYX0ZMT0FUIGZCb3R0b20gPSByZWN0LmJvdHRvbTsKKworCWlmIChmV2lkdGggPiAwLjBmKQorCXsKKwkJRlhfRkxPQVQgZkhhbGZXaWR0aCA9IGZXaWR0aCAvIDIuMGY7CisKKwkJc0FwcFN0cmVhbSA8PCAicVxuIjsKKworCQlzd2l0Y2ggKG5TdHlsZSkKKwkJeworCQlkZWZhdWx0OgorCQljYXNlIFBCU19TT0xJRDoKKwkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbG9yLFRSVUUpOworCQkJaWYgKHNDb2xvci5HZXRMZW5ndGgoKSA+IDApCisJCQl7CisJCQkJc0FwcFN0cmVhbSA8PCBzQ29sb3I7CisJCQkJc0FwcFN0cmVhbSA8PCBmTGVmdCA8PCAiICIgPDwgZkJvdHRvbSA8PCAiICIgPDwgZlJpZ2h0IC0gZkxlZnQgPDwgIiAiIDw8IGZUb3AgLSBmQm90dG9tIDw8ICIgcmVcbiI7CisJCQkJc0FwcFN0cmVhbSA8PCBmTGVmdCArIGZXaWR0aCA8PCAiICIgPDwgZkJvdHRvbSArIGZXaWR0aCA8PCAiICIgCisJCQkJCTw8IGZSaWdodCAtIGZMZWZ0IC0gZldpZHRoICogMiA8PCAiICIgPDwgZlRvcCAtIGZCb3R0b20gLSBmV2lkdGggKiAyIDw8ICIgcmVcbiI7CisJCQkJc0FwcFN0cmVhbSA8PCAiZipcbiI7CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBQQlNfREFTSDoKKwkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbG9yLEZBTFNFKTsKKwkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQorCQkJeworCQkJCXNBcHBTdHJlYW0gPDwgc0NvbG9yOworCQkJCXNBcHBTdHJlYW0gPDwgZldpZHRoIDw8ICIgdyIgPDwgIiBbIiA8PCBkYXNoLm5EYXNoIDw8ICIgIiA8PCBkYXNoLm5HYXAgPDwgIl0gIiA8PCBkYXNoLm5QaGFzZSA8PCAiIGRcbiI7CisJCQkJc0FwcFN0cmVhbSA8PCBmTGVmdCArIGZXaWR0aCAvIDIgPDwgIiAiIDw8IGZCb3R0b20gKyBmV2lkdGggLyAyIDw8ICIgbVxuIjsKKwkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0ICsgZldpZHRoIC8gMiA8PCAiICIgPDwgZlRvcCAtIGZXaWR0aCAvIDIgPDwgIiBsXG4iOworCQkJCXNBcHBTdHJlYW0gPDwgZlJpZ2h0IC0gZldpZHRoIC8gMiA8PCAiICIgPDwgZlRvcCAtIGZXaWR0aCAvIDIgPDwgIiBsXG4iOworCQkJCXNBcHBTdHJlYW0gPDwgZlJpZ2h0IC0gZldpZHRoIC8gMiA8PCAiICIgPDwgZkJvdHRvbSArIGZXaWR0aCAvIDIgPDwgIiBsXG4iOworCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmV2lkdGggLyAyIDw8ICIgIiA8PCBmQm90dG9tICsgZldpZHRoIC8gMiA8PCAiIGwgU1xuIjsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFBCU19CRVZFTEVEOgorCQljYXNlIFBCU19JTlNFVDoKKwkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyTGVmdFRvcCxUUlVFKTsKKwkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQorCQkJeworCQkJCXNBcHBTdHJlYW0gPDwgc0NvbG9yOworCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmSGFsZldpZHRoIDw8ICIgIiA8PCBmQm90dG9tICsgZkhhbGZXaWR0aCA8PCAiIG1cbiI7CisJCQkJc0FwcFN0cmVhbSA8PCBmTGVmdCArIGZIYWxmV2lkdGggPDwgIiAiIDw8IGZUb3AgLSBmSGFsZldpZHRoIDw8ICIgbFxuIjsKKwkJCQlzQXBwU3RyZWFtIDw8IGZSaWdodCAtIGZIYWxmV2lkdGggPDwgIiAiIDw8IGZUb3AgLSBmSGFsZldpZHRoIDw8ICIgbFxuIjsKKwkJCQlzQXBwU3RyZWFtIDw8IGZSaWdodCAtIGZIYWxmV2lkdGggKiAyIDw8ICIgIiA8PCBmVG9wIC0gZkhhbGZXaWR0aCAqIDIgPDwgIiBsXG4iOworCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmSGFsZldpZHRoICogMiA8PCAiICIgPDwgZlRvcCAtIGZIYWxmV2lkdGggKiAyIDw8ICIgbFxuIjsKKwkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0ICsgZkhhbGZXaWR0aCAqIDIgPDwgIiAiIDw8IGZCb3R0b20gKyBmSGFsZldpZHRoICogMiA8PCAiIGwgZlxuIjsKKwkJCX0KKworCQkJc0NvbG9yID0gQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JSaWdodEJvdHRvbSxUUlVFKTsKKwkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQorCQkJeworCQkJCXNBcHBTdHJlYW0gPDwgc0NvbG9yOworCQkJCXNBcHBTdHJlYW0gPDwgZlJpZ2h0IC0gZkhhbGZXaWR0aCA8PCAiICIgPDwJZlRvcCAtIGZIYWxmV2lkdGggPDwgIiBtXG4iOworCQkJCXNBcHBTdHJlYW0gPDwgZlJpZ2h0IC0gZkhhbGZXaWR0aCA8PCAiICIgPDwJZkJvdHRvbSArIGZIYWxmV2lkdGggPDwgIiBsXG4iOworCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmSGFsZldpZHRoIDw8ICIgIiA8PCAJZkJvdHRvbSArIGZIYWxmV2lkdGggPDwgIiBsXG4iOworCQkJCXNBcHBTdHJlYW0gPDwgZkxlZnQgKyBmSGFsZldpZHRoICogMiA8PCAiICIgPDwgZkJvdHRvbSArIGZIYWxmV2lkdGggKiAyIDw8ICIgbFxuIjsKKwkJCQlzQXBwU3RyZWFtIDw8IGZSaWdodCAtIGZIYWxmV2lkdGggKiAyIDw8ICIgIiA8PCBmQm90dG9tICsgZkhhbGZXaWR0aCAqIDIgPDwgIiBsXG4iOworCQkJCXNBcHBTdHJlYW0gPDwgZlJpZ2h0IC0gZkhhbGZXaWR0aCAqIDIgPDwgIiAiIDw8IGZUb3AgLSBmSGFsZldpZHRoICogMiA8PCAiIGwgZlxuIjsKKwkJCX0KKworCQkJc0NvbG9yID0gQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY29sb3IsVFJVRSk7CisJCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkKKwkJCXsKKwkJCQlzQXBwU3RyZWFtIDw8IHNDb2xvcjsKKwkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0IDw8ICIgIiA8PCBmQm90dG9tIDw8ICIgIiA8PAlmUmlnaHQgLSBmTGVmdCA8PCAiICIgPDwgZlRvcCAtIGZCb3R0b20gPDwgIiByZVxuIjsKKwkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0ICsgZkhhbGZXaWR0aCA8PCAiICIgPDwgZkJvdHRvbSArIGZIYWxmV2lkdGggPDwgIiAiIAorCQkJCQk8PCBmUmlnaHQgLSBmTGVmdCAtIGZIYWxmV2lkdGggKiAyIDw8ICIgIiA8PCBmVG9wIC0gZkJvdHRvbSAtIGZIYWxmV2lkdGggKiAyIDw8ICIgcmUgZipcbiI7CQkJCQkJCisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBQQlNfVU5ERVJMSU5FRDoKKwkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbG9yLEZBTFNFKTsKKwkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQorCQkJeworCQkJCXNBcHBTdHJlYW0gPDwgc0NvbG9yOworCQkJCXNBcHBTdHJlYW0gPDwgZldpZHRoIDw8ICIgd1xuIjsKKwkJCQlzQXBwU3RyZWFtIDw8IGZMZWZ0IDw8ICIgIiA8PCBmQm90dG9tICsgZldpZHRoIC8gMiA8PCAiIG1cbiI7CisJCQkJc0FwcFN0cmVhbSA8PCBmUmlnaHQgPDwgIiAiIDw8IGZCb3R0b20gKyBmV2lkdGggLyAyIDw8ICIgbCBTXG4iOworCQkJfQorCQkJYnJlYWs7CisJCX0KKwkJCisJCXNBcHBTdHJlYW0gPDwgIlFcbiI7CisJfQorCisJcmV0dXJuIHNBcHBTdHJlYW0uR2V0Qnl0ZVN0cmluZygpOworfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXRDaXJjbGVCb3JkZXJBcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwgRlhfRkxPQVQgZldpZHRoLAorCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yLCBjb25zdCBDUFdMX0NvbG9yICYgY3JMZWZ0VG9wLCBjb25zdCBDUFdMX0NvbG9yICYgY3JSaWdodEJvdHRvbSwKKwkJCQkJCQkJCQkJCUZYX0lOVDMyIG5TdHlsZSwgY29uc3QgQ1BXTF9EYXNoICYgZGFzaCkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc0FwcFN0cmVhbTsKKwlDRlhfQnl0ZVN0cmluZyBzQ29sb3I7CisKKwkKKworCisKKworCWlmIChmV2lkdGggPiAwLjBmKQorCXsKKwkJc0FwcFN0cmVhbSA8PCAicVxuIjsKKworCQlzd2l0Y2ggKG5TdHlsZSkKKwkJeworCQlkZWZhdWx0OgorCQljYXNlIFBCU19TT0xJRDoKKwkJY2FzZSBQQlNfVU5ERVJMSU5FRDoKKwkJCXsKKwkJCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjb2xvcixGQUxTRSk7CisJCQkJaWYgKHNDb2xvci5HZXRMZW5ndGgoKSA+IDApCisJCQkJeworCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZXaWR0aCA8PCAiIHdcbiIgPDwgc0NvbG9yIAorCQkJCQkJPDwgQ1BXTF9VdGlsczo6R2V0QVBfQ2lyY2xlKENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3QsZldpZHRoIC8gMi4wZikpCisJCQkJCQk8PCAiIFNcblFcbiI7CisJCQkJfQorCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgUEJTX0RBU0g6CisJCQl7CisJCQkJc0NvbG9yID0gQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY29sb3IsRkFMU0UpOworCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQorCQkJCXsKKwkJCQkJc0FwcFN0cmVhbSA8PCAicVxuIiA8PCBmV2lkdGggPDwgIiB3XG4iIAorCQkJCQkJPDwgIlsiIDw8IGRhc2gubkRhc2ggPDwgIiAiIDw8IGRhc2gubkdhcCA8PCAiXSAiIDw8IGRhc2gublBoYXNlIDw8ICIgZFxuIiAKKwkJCQkJCTw8IHNDb2xvciA8PCBDUFdMX1V0aWxzOjpHZXRBUF9DaXJjbGUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdCxmV2lkdGggLyAyLjBmKSkKKwkJCQkJCTw8ICIgU1xuUVxuIjsKKwkJCQl9CQkJCQkJCisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBQQlNfQkVWRUxFRDoKKwkJCXsKKwkJCQlGWF9GTE9BVCBmSGFsZldpZHRoID0gZldpZHRoIC8gMi4wZjsKKworCQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbG9yLEZBTFNFKTsKKwkJCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkKKwkJCQl7CisJCQkJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgZkhhbGZXaWR0aCA8PCAiIHdcbiIKKwkJCQkJCTw8IHNDb2xvciA8PCBDUFdMX1V0aWxzOjpHZXRBUF9DaXJjbGUocmVjdCkKKwkJCQkJCTw8ICIgU1xuUVxuIjsKKwkJCQl9CQkJCQkKKworCQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyTGVmdFRvcCxGQUxTRSk7CisJCQkJaWYgKHNDb2xvci5HZXRMZW5ndGgoKSA+IDApCisJCQkJeworCQkJCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IGZIYWxmV2lkdGggPDwgIiB3XG4iCisJCQkJCQk8PCBzQ29sb3IgPDwgQ1BXTF9VdGlsczo6R2V0QVBfSGFsZkNpcmNsZShDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChyZWN0LGZIYWxmV2lkdGggKiAwLjc1ZiksUFdMX1BJLzQuMGYpCisJCQkJCQk8PCAiIFNcblFcbiI7CisJCQkJfQkKKworCQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyUmlnaHRCb3R0b20sRkFMU0UpOworCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQorCQkJCXsKKwkJCQkJc0FwcFN0cmVhbSA8PCAicVxuIiA8PCBmSGFsZldpZHRoIDw8ICIgd1xuIgorCQkJCQkJPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0hhbGZDaXJjbGUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdCxmSGFsZldpZHRoICogMC43NWYpLFBXTF9QSSo1LzQuMGYpCisJCQkJCQk8PCAiIFNcblFcbiI7CisJCQkJfQkKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFBCU19JTlNFVDoKKwkJCXsKKwkJCQlGWF9GTE9BVCBmSGFsZldpZHRoID0gZldpZHRoIC8gMi4wZjsKKworCQkJCXNDb2xvciA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNvbG9yLEZBTFNFKTsKKwkJCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkKKwkJCQl7CisJCQkJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgZkhhbGZXaWR0aCA8PCAiIHdcbiIKKwkJCQkJCTw8IHNDb2xvciA8PCBDUFdMX1V0aWxzOjpHZXRBUF9DaXJjbGUocmVjdCkKKwkJCQkJCTw8ICIgU1xuUVxuIjsKKwkJCQl9CisKKwkJCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjckxlZnRUb3AsRkFMU0UpOworCQkJCWlmIChzQ29sb3IuR2V0TGVuZ3RoKCkgPiAwKQorCQkJCXsKKwkJCQkJc0FwcFN0cmVhbSA8PCAicVxuIiA8PCBmSGFsZldpZHRoIDw8ICIgd1xuIgorCQkJCQkJPDwgc0NvbG9yIDw8IENQV0xfVXRpbHM6OkdldEFQX0hhbGZDaXJjbGUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdCxmSGFsZldpZHRoICogMC43NWYpLFBXTF9QSS80LjBmKQorCQkJCQkJPDwgIiBTXG5RXG4iOworCQkJCX0JCisKKwkJCQlzQ29sb3IgPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclJpZ2h0Qm90dG9tLEZBTFNFKTsKKwkJCQlpZiAoc0NvbG9yLkdldExlbmd0aCgpID4gMCkKKwkJCQl7CisJCQkJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgZkhhbGZXaWR0aCA8PCAiIHdcbiIKKwkJCQkJCTw8IHNDb2xvciA8PCBDUFdMX1V0aWxzOjpHZXRBUF9IYWxmQ2lyY2xlKENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3QsZkhhbGZXaWR0aCAqIDAuNzVmKSxQV0xfUEkqNS80LjBmKQorCQkJCQkJPDwgIiBTXG5RXG4iOworCQkJCX0JCQkJCQkKKwkJCX0KKwkJCWJyZWFrOworCQl9CisJCQorCQlzQXBwU3RyZWFtIDw8ICJRXG4iOworCX0KKworCXJldHVybiBzQXBwU3RyZWFtLkdldEJ5dGVTdHJpbmcoKTsKK30KKworQ1BXTF9Db2xvciBDUFdMX1V0aWxzOjpTdWJzdHJhY3RDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgc0NvbG9yLEZYX0ZMT0FUIGZDb2xvclN1YikKK3sKKwlDUFdMX0NvbG9yIHNSZXQ7CisJc1JldC5uQ29sb3JUeXBlID0gc0NvbG9yLm5Db2xvclR5cGU7CisKKwlzd2l0Y2ggKHNDb2xvci5uQ29sb3JUeXBlKQorCXsKKwljYXNlIENPTE9SVFlQRV9UUkFOU1BBUkVOVDoKKwkJc1JldC5uQ29sb3JUeXBlID0gQ09MT1JUWVBFX1JHQjsKKwkJc1JldC5mQ29sb3IxID0gUFdMX01BWCgxIC0gZkNvbG9yU3ViLDAuMGYpOworCQlzUmV0LmZDb2xvcjIgPSBQV0xfTUFYKDEgLSBmQ29sb3JTdWIsMC4wZik7CisJCXNSZXQuZkNvbG9yMyA9IFBXTF9NQVgoMSAtIGZDb2xvclN1YiwwLjBmKTsKKwkJYnJlYWs7CisJY2FzZSBDT0xPUlRZUEVfUkdCOgorCWNhc2UgQ09MT1JUWVBFX0dSQVk6CisJY2FzZSBDT0xPUlRZUEVfQ01ZSzoKKwkJc1JldC5mQ29sb3IxID0gUFdMX01BWChzQ29sb3IuZkNvbG9yMSAtIGZDb2xvclN1YiwwLjBmKTsKKwkJc1JldC5mQ29sb3IyID0gUFdMX01BWChzQ29sb3IuZkNvbG9yMiAtIGZDb2xvclN1YiwwLjBmKTsKKwkJc1JldC5mQ29sb3IzID0gUFdMX01BWChzQ29sb3IuZkNvbG9yMyAtIGZDb2xvclN1YiwwLjBmKTsKKwkJc1JldC5mQ29sb3I0ID0gUFdMX01BWChzQ29sb3IuZkNvbG9yNCAtIGZDb2xvclN1YiwwLjBmKTsKKwkJYnJlYWs7CisJfQkKKworCXJldHVybiBzUmV0OworfQorCitDUFdMX0NvbG9yIENQV0xfVXRpbHM6OkRldmlkZUNvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBzQ29sb3IsRlhfRkxPQVQgZkNvbG9yRGV2aWRlKQoreworCUNQV0xfQ29sb3Igc1JldDsKKwlzUmV0Lm5Db2xvclR5cGUgPSBzQ29sb3IubkNvbG9yVHlwZTsKKworCXN3aXRjaCAoc0NvbG9yLm5Db2xvclR5cGUpCisJeworCWNhc2UgQ09MT1JUWVBFX1RSQU5TUEFSRU5UOgorCQlzUmV0Lm5Db2xvclR5cGUgPSBDT0xPUlRZUEVfUkdCOworCQlzUmV0LmZDb2xvcjEgPSAxIC8gZkNvbG9yRGV2aWRlOworCQlzUmV0LmZDb2xvcjIgPSAxIC8gZkNvbG9yRGV2aWRlOworCQlzUmV0LmZDb2xvcjMgPSAxIC8gZkNvbG9yRGV2aWRlOworCQlicmVhazsKKwljYXNlIENPTE9SVFlQRV9SR0I6CisJY2FzZSBDT0xPUlRZUEVfR1JBWToKKwljYXNlIENPTE9SVFlQRV9DTVlLOgorCQlzUmV0ID0gc0NvbG9yOworCQlzUmV0LmZDb2xvcjEgLz0gZkNvbG9yRGV2aWRlOworCQlzUmV0LmZDb2xvcjIgLz0gZkNvbG9yRGV2aWRlOworCQlzUmV0LmZDb2xvcjMgLz0gZkNvbG9yRGV2aWRlOworCQlzUmV0LmZDb2xvcjQgLz0gZkNvbG9yRGV2aWRlOworCQlicmVhazsKKwl9CQorCisJcmV0dXJuIHNSZXQ7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFwcFN0cmVhbV9DaGVjayhjb25zdCBDUERGX1JlY3QgJiByY0JCb3gsIGNvbnN0IENQV0xfQ29sb3IgJiBjclRleHQpCit7CisJQ0ZYX0J5dGVUZXh0QnVmIHNBUDsKKwlzQVAgPDwgInFcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oY3JUZXh0LFRSVUUpIDw8IENQV0xfVXRpbHM6OkdldEFQX0NoZWNrKHJjQkJveCkgPDwgImZcblFcbiI7CisJcmV0dXJuIHNBUC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFwcFN0cmVhbV9DaXJjbGUoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KQoreworCUNGWF9CeXRlVGV4dEJ1ZiBzQVA7CisJc0FQIDw8ICJxXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyVGV4dCxUUlVFKSA8PCBDUFdMX1V0aWxzOjpHZXRBUF9DaXJjbGUocmNCQm94KSA8PCAiZlxuUVxuIjsKKwlyZXR1cm4gc0FQLkdldEJ5dGVTdHJpbmcoKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QXBwU3RyZWFtX0Nyb3NzKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc0FQOworCXNBUCA8PCAicVxuIiA8PCBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjclRleHQsRkFMU0UpIDw8IENQV0xfVXRpbHM6OkdldEFQX0Nyb3NzKHJjQkJveCkgPDwgIlNcblFcbiI7CisJcmV0dXJuIHNBUC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFwcFN0cmVhbV9EaWFtb25kKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc0FQOworCXNBUCA8PCAicVxuMSB3XG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyVGV4dCxUUlVFKSA8PCBDUFdMX1V0aWxzOjpHZXRBUF9EaWFtb25kKHJjQkJveCkgPDwgImZcblFcbiI7CisJcmV0dXJuIHNBUC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldEFwcFN0cmVhbV9TcXVhcmUoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KQoreworCUNGWF9CeXRlVGV4dEJ1ZiBzQVA7CisJc0FQIDw8ICJxXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyVGV4dCxUUlVFKSA8PCBDUFdMX1V0aWxzOjpHZXRBUF9TcXVhcmUocmNCQm94KSA8PCAiZlxuUVxuIjsKKwlyZXR1cm4gc0FQLkdldEJ5dGVTdHJpbmcoKTsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0QXBwU3RyZWFtX1N0YXIoY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LCBjb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KQoreworCUNGWF9CeXRlVGV4dEJ1ZiBzQVA7CisJc0FQIDw8ICJxXG4iIDw8IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyVGV4dCxUUlVFKSA8PCBDUFdMX1V0aWxzOjpHZXRBUF9TdGFyKHJjQkJveCkgPDwgImZcblFcbiI7CisJcmV0dXJuIHNBUC5HZXRCeXRlU3RyaW5nKCk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfVXRpbHM6OkdldENoZWNrQm94QXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCwKKwkJCQkJCQkJCQkJCQlGWF9JTlQzMiBuU3R5bGUsCisJCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciAmIGNyVGV4dCkKK3sKKwlDUERGX1JlY3QgcmNDZW50ZXIgPSBHZXRDZW50ZXJTcXVhcmUocmNCQm94KTsKKwlzd2l0Y2ggKG5TdHlsZSkKKwl7CisJZGVmYXVsdDoKKwljYXNlIFBDU19DSEVDSzoKKwkJcmV0dXJuIEdldEFwcFN0cmVhbV9DaGVjayhyY0NlbnRlcixjclRleHQpOworCWNhc2UgUENTX0NJUkNMRToKKwkJcmV0dXJuIEdldEFwcFN0cmVhbV9DaXJjbGUoU2NhbGVSZWN0KHJjQ2VudGVyLDIuMGYvMy4wZiksY3JUZXh0KTsKKwljYXNlIFBDU19DUk9TUzoKKwkJcmV0dXJuIEdldEFwcFN0cmVhbV9Dcm9zcyhyY0NlbnRlcixjclRleHQpOworCWNhc2UgUENTX0RJQU1PTkQ6CisJCXJldHVybiBHZXRBcHBTdHJlYW1fRGlhbW9uZChTY2FsZVJlY3QocmNDZW50ZXIsMi4wZi8zLjBmKSxjclRleHQpOwkJCisJY2FzZSBQQ1NfU1FVQVJFOgorCQlyZXR1cm4gR2V0QXBwU3RyZWFtX1NxdWFyZShTY2FsZVJlY3QocmNDZW50ZXIsMi4wZi8zLjBmKSxjclRleHQpOworCWNhc2UgUENTX1NUQVI6CisJCXJldHVybiBHZXRBcHBTdHJlYW1fU3RhcihTY2FsZVJlY3QocmNDZW50ZXIsMi4wZi8zLjBmKSxjclRleHQpOworCX0KK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0UmFkaW9CdXR0b25BcHBTdHJlYW0oY29uc3QgQ1BERl9SZWN0ICYgcmNCQm94LAorCQkJCQkJCQkJCQkJCUZYX0lOVDMyIG5TdHlsZSwKKwkJCQkJCQkJCQkJCQljb25zdCBDUFdMX0NvbG9yICYgY3JUZXh0KQoreworCUNQREZfUmVjdCByY0NlbnRlciA9IEdldENlbnRlclNxdWFyZShyY0JCb3gpOworCXN3aXRjaCAoblN0eWxlKQorCXsKKwlkZWZhdWx0OgorCWNhc2UgUENTX0NIRUNLOgorCQlyZXR1cm4gR2V0QXBwU3RyZWFtX0NoZWNrKHJjQ2VudGVyLGNyVGV4dCk7CisJY2FzZSBQQ1NfQ0lSQ0xFOgorCQlyZXR1cm4gR2V0QXBwU3RyZWFtX0NpcmNsZShTY2FsZVJlY3QocmNDZW50ZXIsMS4wZi8yLjBmKSxjclRleHQpOworCWNhc2UgUENTX0NST1NTOgorCQlyZXR1cm4gR2V0QXBwU3RyZWFtX0Nyb3NzKHJjQ2VudGVyLGNyVGV4dCk7CisJY2FzZSBQQ1NfRElBTU9ORDoKKwkJcmV0dXJuIEdldEFwcFN0cmVhbV9EaWFtb25kKFNjYWxlUmVjdChyY0NlbnRlciwyLjBmLzMuMGYpLGNyVGV4dCk7CQkKKwljYXNlIFBDU19TUVVBUkU6CisJCXJldHVybiBHZXRBcHBTdHJlYW1fU3F1YXJlKFNjYWxlUmVjdChyY0NlbnRlciwyLjBmLzMuMGYpLGNyVGV4dCk7CisJY2FzZSBQQ1NfU1RBUjoKKwkJcmV0dXJuIEdldEFwcFN0cmVhbV9TdGFyKFNjYWxlUmVjdChyY0NlbnRlciwyLjBmLzMuMGYpLGNyVGV4dCk7CisJfQorfQorCitDRlhfQnl0ZVN0cmluZyBDUFdMX1V0aWxzOjpHZXREcm9wQnV0dG9uQXBwU3RyZWFtKGNvbnN0IENQREZfUmVjdCAmIHJjQkJveCkKK3sKKwlDRlhfQnl0ZVRleHRCdWYgc0FwcFN0cmVhbTsKKworCWlmICghcmNCQm94LklzRW1wdHkoKSkKKwl7CisJCXNBcHBTdHJlYW0gPDwgInFcbiIgPDwgQ1BXTF9VdGlsczo6R2V0Q29sb3JBcHBTdHJlYW0oQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLDIyMC4wZi8yNTUuMGYsMjIwLjBmLzI1NS4wZiwyMjAuMGYvMjU1LjBmKSxUUlVFKTsKKwkJc0FwcFN0cmVhbSA8PCByY0JCb3gubGVmdCA8PCAiICIgPDwgcmNCQm94LmJvdHRvbSA8PCAiICIgCisJCQkJPDwgcmNCQm94LnJpZ2h0IC0gcmNCQm94LmxlZnQgPDwgIiAiIDw8IHJjQkJveC50b3AgLSByY0JCb3guYm90dG9tIDw8ICIgcmUgZlxuIjsKKwkJc0FwcFN0cmVhbSA8PCAiUVxuIjsKKworCQlzQXBwU3RyZWFtIDw8ICJxXG4iIDw8IAorCQkJQ1BXTF9VdGlsczo6R2V0Qm9yZGVyQXBwU3RyZWFtKHJjQkJveCwyLENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMCksQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwxKSxDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDAuNSksUEJTX0JFVkVMRUQsQ1BXTF9EYXNoKDMsMCwwKSkgCisJCQk8PCAiUVxuIjsKKworCQlDUERGX1BvaW50IHB0Q2VudGVyID0gQ1BERl9Qb2ludCgocmNCQm94LmxlZnQgKyByY0JCb3gucmlnaHQpLzIsKHJjQkJveC50b3AgKyByY0JCb3guYm90dG9tKS8yKTsKKwkJaWYgKElzRmxvYXRCaWdnZXIocmNCQm94LnJpZ2h0IC0gcmNCQm94LmxlZnQsNikgJiYgSXNGbG9hdEJpZ2dlcihyY0JCb3gudG9wIC0gcmNCQm94LmJvdHRvbSw2KSkKKwkJeworCQkJc0FwcFN0cmVhbSA8PCAicVxuIiA8PCAiIDAgZ1xuIjsKKwkJCXNBcHBTdHJlYW0gPDwgcHRDZW50ZXIueCAtIDMgPDwgIiAiIDw8IHB0Q2VudGVyLnkgKyAxLjVmIDw8ICIgbVxuIjsKKwkJCXNBcHBTdHJlYW0gPDwgcHRDZW50ZXIueCArIDMgPDwgIiAiIDw8IHB0Q2VudGVyLnkgKyAxLjVmIDw8ICIgbFxuIjsKKwkJCXNBcHBTdHJlYW0gPDwgcHRDZW50ZXIueCA8PCAiICIgPDwgcHRDZW50ZXIueSAtIDEuNWYgPDwgIiBsXG4iOworCQkJc0FwcFN0cmVhbSA8PCBwdENlbnRlci54IC0gMyA8PCAiICIgPDwgcHRDZW50ZXIueSArIDEuNWYgPDwgIiBsIGZcbiI7CisJCQlzQXBwU3RyZWFtIDw8ICJRXG4iOworCQl9CisJfQorCisJcmV0dXJuIHNBcHBTdHJlYW0uR2V0Qnl0ZVN0cmluZygpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkNvbnZlcnRDTVlLMkdSQVkoRlhfRkxPQVQgZEMsRlhfRkxPQVQgZE0sRlhfRkxPQVQgZFksRlhfRkxPQVQgZEssRlhfRkxPQVQgJmRHcmF5KQoreworCWlmIChkQzwwIHx8IGRDPjEgfHwgZE08MCB8fCBkTT4xIHx8IGRZIDwgMCB8fCBkWSA+MSB8fCBkSyA8IDAgfHwgZEsgPjEpCisJCXJldHVybjsKKwlkR3JheSA9IDEuMGYgLSBGWF9NSU4oMS4wZiwwLjNmKmRDKzAuNTlmICogZE0gKyAwLjExZipkWStkSyk7Cit9CisKK3ZvaWQgQ1BXTF9VdGlsczo6Q29udmVydEdSQVkyQ01ZSyhGWF9GTE9BVCBkR3JheSxGWF9GTE9BVCAgJmRDLEZYX0ZMT0FUICZkTSxGWF9GTE9BVCAmZFksRlhfRkxPQVQgJmRLKQoreworCWlmIChkR3JheSA8MCB8fCBkR3JheSA+MSkKKwkJcmV0dXJuOworCWRDID0gMC4wZjsKKwlkTSA9IDAuMGY7CisJZFkgPSAwLjBmOworCWRLID0gMS4wZi1kR3JheTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpDb252ZXJ0R1JBWTJSR0IoRlhfRkxPQVQgZEdyYXksRlhfRkxPQVQgJmRSLEZYX0ZMT0FUICZkRyxGWF9GTE9BVCAmZEIpCit7CisJaWYgKGRHcmF5IDwwIHx8IGRHcmF5ID4xKQorCQlyZXR1cm47CisJZFIgPSBkR3JheTsKKwlkRyA9IGRHcmF5OworCWRCID0gZEdyYXk7Cit9CisKK3ZvaWQgQ1BXTF9VdGlsczo6Q29udmVydFJHQjJHUkFZKEZYX0ZMT0FUIGRSLEZYX0ZMT0FUIGRHLEZYX0ZMT0FUIGRCLEZYX0ZMT0FUICZkR3JheSkKK3sKKwlpZiAoZFI8MCB8fCBkUj4xIHx8IGRHPDAgfHwgZEcgPiAwIHx8IGRCIDwgMCB8fCBkQiA+MSkKKwkJcmV0dXJuOworCWRHcmF5ID0gMC4zZipkUiswLjU5ZipkRyswLjExZipkQjsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpDb252ZXJ0Q01ZSzJSR0IoRlhfRkxPQVQgZEMsRlhfRkxPQVQgZE0sRlhfRkxPQVQgZFksRlhfRkxPQVQgZEssRlhfRkxPQVQgJmRSLEZYX0ZMT0FUICZkRyxGWF9GTE9BVCAmZEIpCit7CisJaWYgKGRDIDwwIHx8IGRDPjEgfHwgZE0gPCAwIHx8IGRNID4gMSB8fCBkWSA8IDAgfHwgZFkgPiAxIHx8IGRLIDwgMCB8fCBkSyA+IDEgKQorCQlyZXR1cm47CisJZFIgPSAxLjBmIC0gRlhfTUlOKDEuMGYsIGRDICsgZEspOworCWRHID0gMS4wZiAtIEZYX01JTigxLjBmLCBkTSArIGRLKTsKKwlkQiA9IDEuMGYgLSBGWF9NSU4oMS4wZiwgZFkgKyBkSyk7Cit9CisKK3ZvaWQgQ1BXTF9VdGlsczo6Q29udmVydFJHQjJDTVlLKEZYX0ZMT0FUIGRSLEZYX0ZMT0FUIGRHLEZYX0ZMT0FUIGRCLEZYX0ZMT0FUICZkQyxGWF9GTE9BVCAmZE0sRlhfRkxPQVQgJmRZLEZYX0ZMT0FUICZkSykKK3sKKwlpZiAoZFI8MCB8fCBkUj4xIHx8IGRHPDAgfHwgZEc+MSB8fCBkQjwwIHx8IGRCPjEpCisJCXJldHVybjsKKworCWRDID0gMS4wZiAtIGRSOworCWRNID0gMS4wZiAtIGRHOworCWRZID0gMS4wZiAtIGRCOworCWRLID0gRlhfTUlOKGRDLCBGWF9NSU4oZE0sIGRZKSk7Cit9CisKK3ZvaWQgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0FSR0IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IsIEZYX0lOVDMyJiBhbHBoYSwgRlhfRkxPQVQmIHJlZCwgRlhfRkxPQVQmIGdyZWVuLCBGWF9GTE9BVCYgYmx1ZSkKK3sKKwlzd2l0Y2ggKGNvbG9yLm5Db2xvclR5cGUpCisJeworCWNhc2UgQ09MT1JUWVBFX1RSQU5TUEFSRU5UOgorCQl7CisJCQlhbHBoYSA9IDA7CisJCX0KKwkJYnJlYWs7CisJY2FzZSBDT0xPUlRZUEVfR1JBWToKKwkJeworCQkJQ29udmVydEdSQVkyUkdCKGNvbG9yLmZDb2xvcjEsIHJlZCwgZ3JlZW4sIGJsdWUpOworCQl9CisJCWJyZWFrOworCWNhc2UgQ09MT1JUWVBFX1JHQjoKKwkJeworCQkJcmVkID0gY29sb3IuZkNvbG9yMTsKKwkJCWdyZWVuID0gY29sb3IuZkNvbG9yMjsKKwkJCWJsdWUgPSBjb2xvci5mQ29sb3IzOworCQl9CisJCWJyZWFrOworCWNhc2UgQ09MT1JUWVBFX0NNWUs6CisJCXsKKwkJCUNvbnZlcnRDTVlLMlJHQihjb2xvci5mQ29sb3IxLCBjb2xvci5mQ29sb3IyLCBjb2xvci5mQ29sb3IzLCBjb2xvci5mQ29sb3I0LAorCQkJCXJlZCwgZ3JlZW4sIGJsdWUpOworCQl9CisJCWJyZWFrOworCX0KK30KKworRlhfQ09MT1JSRUYgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IsIEZYX0lOVDMyIG5UcmFuc3BhcmFuY3kpCit7CisJRlhfSU5UMzIgbkFscGhhID0gblRyYW5zcGFyYW5jeTsKKwlGWF9GTE9BVCBkUmVkID0gMDsKKwlGWF9GTE9BVCBkR3JlZW4gPSAwOworCUZYX0ZMT0FUIGRCbHVlID0gMDsKKworCVBXTENvbG9yVG9BUkdCKGNvbG9yLCBuQWxwaGEsIGRSZWQsIGRHcmVlbiwgZEJsdWUpOworCisJcmV0dXJuIEFyZ2JFbmNvZGUobkFscGhhLCAoRlhfSU5UMzIpKGRSZWQqMjU1KSwgKEZYX0lOVDMyKShkR3JlZW4qMjU1KSwgKEZYX0lOVDMyKShkQmx1ZSoyNTUpKTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpEcmF3RmlsbFJlY3QoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSxjb25zdCBDUERGX1JlY3QgJiByZWN0LAorCQkJCQkJCSAgY29uc3QgRlhfQ09MT1JSRUYgJiBjb2xvcikKK3sKKwlDRlhfUGF0aERhdGEgcGF0aDsKKwlDUERGX1JlY3QgcmNUZW1wKHJlY3QpOwkKKwlwYXRoLkFwcGVuZFJlY3QocmNUZW1wLmxlZnQscmNUZW1wLmJvdHRvbSxyY1RlbXAucmlnaHQscmNUZW1wLnRvcCk7CisJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgTlVMTCwgY29sb3IsIDAsIEZYRklMTF9XSU5ESU5HKTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpEcmF3RmlsbEFyZWEoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQljb25zdCBDUERGX1BvaW50KiBwUHRzLCBGWF9JTlQzMiBuQ291bnQsIGNvbnN0IEZYX0NPTE9SUkVGJiBjb2xvcikKK3sKKwlDRlhfUGF0aERhdGEgcGF0aDsKKwlwYXRoLlNldFBvaW50Q291bnQobkNvdW50KTsKKworCXBhdGguU2V0UG9pbnQoMCwgcFB0c1swXS54LCBwUHRzWzBdLnksIEZYUFRfTU9WRVRPKTsKKwlmb3IgKEZYX0lOVDMyIGk9MTsgaTxuQ291bnQ7IGkrKykKKwkJcGF0aC5TZXRQb2ludChpLCBwUHRzW2ldLngsIHBQdHNbaV0ueSwgRlhQVF9MSU5FVE8pOworCisJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgTlVMTCwgY29sb3IsIDAsIEZYRklMTF9BTFRFUk5BVEUpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkRyYXdTdHJva2VSZWN0KENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UsY29uc3QgQ1BERl9SZWN0ICYgcmVjdCwKKwkJCQkJCQkgIGNvbnN0IEZYX0NPTE9SUkVGICYgY29sb3IsIEZYX0ZMT0FUIGZXaWR0aCkKK3sKKwlDRlhfUGF0aERhdGEgcGF0aDsKKwlDUERGX1JlY3QgcmNUZW1wKHJlY3QpOwkKKwlwYXRoLkFwcGVuZFJlY3QocmNUZW1wLmxlZnQscmNUZW1wLmJvdHRvbSxyY1RlbXAucmlnaHQscmNUZW1wLnRvcCk7CisJCisJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKKwlnc2QubV9MaW5lV2lkdGggPSBmV2lkdGg7CisKKwlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLCBjb2xvciwgRlhGSUxMX0FMVEVSTkFURSk7Cit9CisKK3ZvaWQgQ1BXTF9VdGlsczo6RHJhd1N0cm9rZUxpbmUoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQljb25zdCBDUERGX1BvaW50ICYgcHRNb3ZlVG8sIGNvbnN0IENQREZfUG9pbnQgJiBwdExpbmVUbywgY29uc3QgRlhfQ09MT1JSRUYgJiBjb2xvciwgRlhfRkxPQVQgZldpZHRoKQoreworCUNGWF9QYXRoRGF0YSBwYXRoOworCXBhdGguU2V0UG9pbnRDb3VudCgyKTsKKwlwYXRoLlNldFBvaW50KDAsIHB0TW92ZVRvLngsIHB0TW92ZVRvLnksIEZYUFRfTU9WRVRPKTsKKwlwYXRoLlNldFBvaW50KDEsIHB0TGluZVRvLngsIHB0TGluZVRvLnksIEZYUFRfTElORVRPKTsKKworCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CisJZ3NkLm1fTGluZVdpZHRoID0gZldpZHRoOworCisJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgJmdzZCwgMCwgY29sb3IsIEZYRklMTF9BTFRFUk5BVEUpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkRyYXdGaWxsUmVjdChDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLGNvbnN0IENQREZfUmVjdCAmIHJlY3QsCisJCQkJCQkJICBjb25zdCBDUFdMX0NvbG9yICYgY29sb3IsIEZYX0lOVDMyIG5UcmFuc3BhcmFuY3kpCit7CisJQ1BXTF9VdGlsczo6RHJhd0ZpbGxSZWN0KHBEZXZpY2UscFVzZXIyRGV2aWNlLHJlY3QsUFdMQ29sb3JUb0ZYQ29sb3IoY29sb3IsblRyYW5zcGFyYW5jeSkpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkRyYXdTaGFkb3coQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQkJCQkJCQkJRlhfQk9PTCBiVmVydGljYWwsIEZYX0JPT0wgYkhvcml6b250YWwsIENQREZfUmVjdCByZWN0LAorCQkJCQkJCQkJCQkJCQlGWF9JTlQzMiBuVHJhbnNwYXJhbmN5LCBGWF9JTlQzMiBuU3RhcnRHcmF5LCBGWF9JTlQzMiBuRW5kR3JheSkKK3sKKwlGWF9GTE9BVCBmU3RlcEdyYXkgPSAxLjBmOworCisJaWYgKGJWZXJ0aWNhbCkKKwl7CisJCWZTdGVwR3JheSA9IChuRW5kR3JheSAtIG5TdGFydEdyYXkpIC8gcmVjdC5IZWlnaHQoKTsKKworCQlmb3IgKEZYX0ZMT0FUIGZ5PXJlY3QuYm90dG9tKzAuNWY7IGZ5PD1yZWN0LnRvcC0wLjVmOyBmeSs9MS4wZikKKwkJewkJCQorCQkJRlhfSU5UMzIgbkdyYXkgPSBuU3RhcnRHcmF5ICsgKEZYX0lOVDMyKShmU3RlcEdyYXkgKiAoZnktcmVjdC5ib3R0b20pKTsKKwkJCUNQV0xfVXRpbHM6OkRyYXdTdHJva2VMaW5lKHBEZXZpY2UsIHBVc2VyMkRldmljZSwgQ1BERl9Qb2ludChyZWN0LmxlZnQsIGZ5KSwKKwkJCQlDUERGX1BvaW50KHJlY3QucmlnaHQsIGZ5KSwgQXJnYkVuY29kZShuVHJhbnNwYXJhbmN5LCBuR3JheSwgbkdyYXksIG5HcmF5KSwgMS41Zik7CisJCX0KKwl9CisKKwlpZiAoYkhvcml6b250YWwpCisJeworCQlmU3RlcEdyYXkgPSAobkVuZEdyYXkgLSBuU3RhcnRHcmF5KSAvIHJlY3QuV2lkdGgoKTsKKworCQlmb3IgKEZYX0ZMT0FUIGZ4PXJlY3QubGVmdCswLjVmOyBmeDw9cmVjdC5yaWdodC0wLjVmOyBmeCs9MS4wZikKKwkJewkJCQorCQkJRlhfSU5UMzIgbkdyYXkgPSBuU3RhcnRHcmF5ICsgKEZYX0lOVDMyKShmU3RlcEdyYXkgKiAoZngtcmVjdC5sZWZ0KSk7CisJCQlDUFdMX1V0aWxzOjpEcmF3U3Ryb2tlTGluZShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIENQREZfUG9pbnQoZngsIHJlY3QuYm90dG9tKSwKKwkJCQlDUERGX1BvaW50KGZ4LCByZWN0LnRvcCksIEFyZ2JFbmNvZGUoblRyYW5zcGFyYW5jeSwgbkdyYXksIG5HcmF5LCBuR3JheSksIDEuNWYpOworCQl9CisJfQorfQorCit2b2lkIENQV0xfVXRpbHM6OkRyYXdCb3JkZXIoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSwKKwkJCQkJCQkJCQkJCWNvbnN0IENQREZfUmVjdCAmIHJlY3QsIEZYX0ZMT0FUIGZXaWR0aCwKKwkJCQkJCQkJCQkJCWNvbnN0IENQV0xfQ29sb3IgJiBjb2xvciwgY29uc3QgQ1BXTF9Db2xvciAmIGNyTGVmdFRvcCwgY29uc3QgQ1BXTF9Db2xvciAmIGNyUmlnaHRCb3R0b20sCisJCQkJCQkJCQkJCQlGWF9JTlQzMiBuU3R5bGUsIGNvbnN0IENQV0xfRGFzaCAmIGRhc2gsIEZYX0lOVDMyIG5UcmFuc3BhcmFuY3kpCit7CisJRlhfRkxPQVQgZkxlZnQgPSByZWN0LmxlZnQ7CisJRlhfRkxPQVQgZlJpZ2h0ID0gcmVjdC5yaWdodDsKKwlGWF9GTE9BVCBmVG9wID0gcmVjdC50b3A7CisJRlhfRkxPQVQgZkJvdHRvbSA9IHJlY3QuYm90dG9tOworCisJaWYgKGZXaWR0aCA+IDAuMGYpCisJeworCQlGWF9GTE9BVCBmSGFsZldpZHRoID0gZldpZHRoIC8gMi4wZjsKKworCQlzd2l0Y2ggKG5TdHlsZSkKKwkJeworCQlkZWZhdWx0OgorCQljYXNlIFBCU19TT0xJRDoKKwkJCXsKKwkJCQlDRlhfUGF0aERhdGEgcGF0aDsKKwkJCQlwYXRoLkFwcGVuZFJlY3QoZkxlZnQsIGZCb3R0b20sIGZSaWdodCwgZlRvcCk7CisJCQkJcGF0aC5BcHBlbmRSZWN0KGZMZWZ0ICsgZldpZHRoLCBmQm90dG9tICsgZldpZHRoLCBmUmlnaHQgLSBmV2lkdGgsIGZUb3AgLSBmV2lkdGgpOworCQkJCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoLCBwVXNlcjJEZXZpY2UsIE5VTEwsIFBXTENvbG9yVG9GWENvbG9yKGNvbG9yLG5UcmFuc3BhcmFuY3kpLCAwLCBGWEZJTExfQUxURVJOQVRFKTsKKwkJCX0KKwkJCWJyZWFrOworCQljYXNlIFBCU19EQVNIOgorCQkJeworCQkJCUNGWF9QYXRoRGF0YSBwYXRoOworCisJCQkJcGF0aC5TZXRQb2ludENvdW50KDUpOworCQkJCXBhdGguU2V0UG9pbnQoMCwgZkxlZnQgKyBmV2lkdGggLyAyLjBmLCBmQm90dG9tICsgZldpZHRoIC8gMi4wZiwgRlhQVF9NT1ZFVE8pOworCQkJCXBhdGguU2V0UG9pbnQoMSwgZkxlZnQgKyBmV2lkdGggLyAyLjBmLCBmVG9wIC0gZldpZHRoIC8gMi4wZiwgRlhQVF9MSU5FVE8pOworCQkJCXBhdGguU2V0UG9pbnQoMiwgZlJpZ2h0IC0gZldpZHRoIC8gMi4wZiwgZlRvcCAtIGZXaWR0aCAvIDIuMGYsIEZYUFRfTElORVRPKTsKKwkJCQlwYXRoLlNldFBvaW50KDMsIGZSaWdodCAtIGZXaWR0aCAvIDIuMGYsIGZCb3R0b20gKyBmV2lkdGggLyAyLjBmLCBGWFBUX0xJTkVUTyk7CisJCQkJcGF0aC5TZXRQb2ludCg0LCBmTGVmdCArIGZXaWR0aCAvIDIuMGYsIGZCb3R0b20gKyBmV2lkdGggLyAyLjBmLCBGWFBUX0xJTkVUTyk7CisKKwkJCQlDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOworCQkJCWdzZC5TZXREYXNoQ291bnQoMik7CQkJCQorCQkJCWdzZC5tX0Rhc2hBcnJheVswXSA9IDMuMGY7CisJCQkJZ3NkLm1fRGFzaEFycmF5WzFdID0gMy4wZjsKKwkJCQlnc2QubV9EYXNoUGhhc2UgPSAwOwkKKwkJCQkKKwkJCQlnc2QubV9MaW5lV2lkdGggPSBmV2lkdGg7CisJCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgJmdzZCwgMCwgUFdMQ29sb3JUb0ZYQ29sb3IoY29sb3IsblRyYW5zcGFyYW5jeSksIEZYRklMTF9XSU5ESU5HKTsJCQkJCisJCQl9CQkJCisJCQlicmVhazsKKwkJY2FzZSBQQlNfQkVWRUxFRDoKKwkJY2FzZSBQQlNfSU5TRVQ6CQorCQkJeworCQkJCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CisJCQkJZ3NkLm1fTGluZVdpZHRoID0gZkhhbGZXaWR0aDsKKworCQkJCUNGWF9QYXRoRGF0YSBwYXRoTFQ7CisKKwkJCQlwYXRoTFQuU2V0UG9pbnRDb3VudCg3KTsKKwkJCQlwYXRoTFQuU2V0UG9pbnQoMCwgZkxlZnQgKyBmSGFsZldpZHRoLCBmQm90dG9tICsgZkhhbGZXaWR0aCwgRlhQVF9NT1ZFVE8pOworCQkJCXBhdGhMVC5TZXRQb2ludCgxLCBmTGVmdCArIGZIYWxmV2lkdGgsIGZUb3AgLSBmSGFsZldpZHRoLCBGWFBUX0xJTkVUTyk7CisJCQkJcGF0aExULlNldFBvaW50KDIsIGZSaWdodCAtIGZIYWxmV2lkdGgsIGZUb3AgLSBmSGFsZldpZHRoLCBGWFBUX0xJTkVUTyk7CisJCQkJcGF0aExULlNldFBvaW50KDMsIGZSaWdodCAtIGZIYWxmV2lkdGggKiAyLCBmVG9wIC0gZkhhbGZXaWR0aCAqIDIsIEZYUFRfTElORVRPKTsKKwkJCQlwYXRoTFQuU2V0UG9pbnQoNCwgZkxlZnQgKyBmSGFsZldpZHRoICogMiwgZlRvcCAtIGZIYWxmV2lkdGggKiAyLCBGWFBUX0xJTkVUTyk7CisJCQkJcGF0aExULlNldFBvaW50KDUsIGZMZWZ0ICsgZkhhbGZXaWR0aCAqIDIsIGZCb3R0b20gKyBmSGFsZldpZHRoICogMiwgRlhQVF9MSU5FVE8pOworCQkJCXBhdGhMVC5TZXRQb2ludCg2LCBmTGVmdCArIGZIYWxmV2lkdGgsIGZCb3R0b20gKyBmSGFsZldpZHRoLCBGWFBUX0xJTkVUTyk7CisKKwkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aExULCBwVXNlcjJEZXZpY2UsICZnc2QsIFBXTENvbG9yVG9GWENvbG9yKGNyTGVmdFRvcCxuVHJhbnNwYXJhbmN5KSwgMCwgRlhGSUxMX0FMVEVSTkFURSk7CisKKwkJCQlDRlhfUGF0aERhdGEgcGF0aFJCOworCisJCQkJcGF0aFJCLlNldFBvaW50Q291bnQoNyk7CisJCQkJcGF0aFJCLlNldFBvaW50KDAsIGZSaWdodCAtIGZIYWxmV2lkdGgsIGZUb3AgLSBmSGFsZldpZHRoLCBGWFBUX01PVkVUTyk7CisJCQkJcGF0aFJCLlNldFBvaW50KDEsIGZSaWdodCAtIGZIYWxmV2lkdGgsIGZCb3R0b20gKyBmSGFsZldpZHRoLCBGWFBUX0xJTkVUTyk7CisJCQkJcGF0aFJCLlNldFBvaW50KDIsIGZMZWZ0ICsgZkhhbGZXaWR0aCwgZkJvdHRvbSArIGZIYWxmV2lkdGgsIEZYUFRfTElORVRPKTsKKwkJCQlwYXRoUkIuU2V0UG9pbnQoMywgZkxlZnQgKyBmSGFsZldpZHRoICogMiwgZkJvdHRvbSArIGZIYWxmV2lkdGggKiAyLCBGWFBUX0xJTkVUTyk7CisJCQkJcGF0aFJCLlNldFBvaW50KDQsIGZSaWdodCAtIGZIYWxmV2lkdGggKiAyLCBmQm90dG9tICsgZkhhbGZXaWR0aCAqIDIsIEZYUFRfTElORVRPKTsKKwkJCQlwYXRoUkIuU2V0UG9pbnQoNSwgZlJpZ2h0IC0gZkhhbGZXaWR0aCAqIDIsIGZUb3AgLSBmSGFsZldpZHRoICogMiwgRlhQVF9MSU5FVE8pOworCQkJCXBhdGhSQi5TZXRQb2ludCg2LCBmUmlnaHQgLSBmSGFsZldpZHRoLCBmVG9wIC0gZkhhbGZXaWR0aCwgRlhQVF9MSU5FVE8pOworCisJCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGhSQiwgcFVzZXIyRGV2aWNlLCAmZ3NkLCBQV0xDb2xvclRvRlhDb2xvcihjclJpZ2h0Qm90dG9tLG5UcmFuc3BhcmFuY3kpLCAwLCBGWEZJTExfQUxURVJOQVRFKTsKKworCQkJCUNGWF9QYXRoRGF0YSBwYXRoOworCisJCQkJcGF0aC5BcHBlbmRSZWN0KGZMZWZ0LCBmQm90dG9tLCBmUmlnaHQsIGZUb3ApOworCQkJCXBhdGguQXBwZW5kUmVjdChmTGVmdCArIGZIYWxmV2lkdGgsIGZCb3R0b20gKyBmSGFsZldpZHRoLCBmUmlnaHQgLSBmSGFsZldpZHRoLCBmVG9wIC0gZkhhbGZXaWR0aCk7CisKKwkJCQlwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCAmZ3NkLCBQV0xDb2xvclRvRlhDb2xvcihjb2xvcixuVHJhbnNwYXJhbmN5KSwgMCwgRlhGSUxMX0FMVEVSTkFURSk7CisJCQl9CisJCQlicmVhazsKKwkJY2FzZSBQQlNfVU5ERVJMSU5FRDoKKwkJCXsKKwkJCQlDRlhfUGF0aERhdGEgcGF0aDsKKworCQkJCXBhdGguU2V0UG9pbnRDb3VudCgyKTsKKwkJCQlwYXRoLlNldFBvaW50KDAsIGZMZWZ0LCBmQm90dG9tICsgZldpZHRoIC8gMiwgRlhQVF9NT1ZFVE8pOworCQkJCXBhdGguU2V0UG9pbnQoMSwgZlJpZ2h0LCBmQm90dG9tICsgZldpZHRoIC8gMiwgRlhQVF9MSU5FVE8pOworCQkJCQorCQkJCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CisJCQkJZ3NkLm1fTGluZVdpZHRoID0gZldpZHRoOworCisJCQkJcERldmljZS0+RHJhd1BhdGgoJnBhdGgsIHBVc2VyMkRldmljZSwgJmdzZCwwLCAgUFdMQ29sb3JUb0ZYQ29sb3IoY29sb3IsblRyYW5zcGFyYW5jeSksIEZYRklMTF9BTFRFUk5BVEUpOworCQkJfQorCQkJYnJlYWs7CisJCWNhc2UgUEJTX1NIQURPVzoKKwkJCXsKKwkJCQlDRlhfUGF0aERhdGEgcGF0aDsKKwkJCQlwYXRoLkFwcGVuZFJlY3QoZkxlZnQsIGZCb3R0b20sIGZSaWdodCwgZlRvcCk7CisJCQkJcGF0aC5BcHBlbmRSZWN0KGZMZWZ0ICsgZldpZHRoLCBmQm90dG9tICsgZldpZHRoLCBmUmlnaHQgLSBmV2lkdGgsIGZUb3AgLSBmV2lkdGgpOworCQkJCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoLCBwVXNlcjJEZXZpY2UsIE5VTEwsIFBXTENvbG9yVG9GWENvbG9yKGNvbG9yLG5UcmFuc3BhcmFuY3kvMiksIDAsIEZYRklMTF9BTFRFUk5BVEUpOworCQkJfQorCQkJYnJlYWs7CisJCX0KKwl9Cit9CisKK3N0YXRpYyB2b2lkIEFkZFNxdWlnZ2x5UGF0aChDRlhfUGF0aERhdGEgJiBQYXRoRGF0YSwgRlhfRkxPQVQgZlN0YXJ0WCwgRlhfRkxPQVQgZkVuZFgsIEZYX0ZMT0FUIGZZLCBGWF9GTE9BVCBmU3RlcCkKK3sKKwlQYXRoRGF0YS5BZGRQb2ludENvdW50KDEpOworCVBhdGhEYXRhLlNldFBvaW50KFBhdGhEYXRhLkdldFBvaW50Q291bnQoKSAtIDEsIGZTdGFydFgsIGZZLCBGWFBUX01PVkVUTyk7CisKKwlGWF9GTE9BVCBmeDsKKwlGWF9JTlQzMiBpOworCisJZm9yIChpPTEsZng9ZlN0YXJ0WCtmU3RlcDsgZng8ZkVuZFg7IGZ4Kz1mU3RlcCxpKyspCisJeworCQlQYXRoRGF0YS5BZGRQb2ludENvdW50KDEpOworCQlQYXRoRGF0YS5TZXRQb2ludChQYXRoRGF0YS5HZXRQb2ludENvdW50KCkgLSAxLCBmeCwgZlkgKyAoaSYxKSpmU3RlcCwgRlhQVF9MSU5FVE8pOworCX0KK30KKworc3RhdGljIHZvaWQgQWRkU3BlbGxDaGVja09iaihDRlhfUGF0aERhdGEgJiBQYXRoRGF0YSwgSUZYX0VkaXQqIHBFZGl0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSYgd3JXb3JkKQoreworCUZYX0ZMT0FUIGZTdGFydFggPSAwLjBmOworCUZYX0ZMT0FUIGZFbmRYID0gMC4wZjsKKwlGWF9GTE9BVCBmWSA9IDAuMGY7CisJRlhfRkxPQVQgZlN0ZXAgPSAwLjBmOyAKKworCUZYX0JPT0wgYkJyZWFrID0gRkFMU0U7CisKKwlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQorCXsKKwkJcEl0ZXJhdG9yLT5TZXRBdCh3cldvcmQuQmVnaW5Qb3MpOworCisJCWRvCisJCXsKKwkJCUNQVlRfV29yZFBsYWNlIHBsYWNlID0gcEl0ZXJhdG9yLT5HZXRBdCgpOworCisJCQlDUFZUX0xpbmUgbGluZTsJCQkJCisJCQlpZiAocEl0ZXJhdG9yLT5HZXRMaW5lKGxpbmUpKQorCQkJeworCQkJCWZZID0gbGluZS5wdExpbmUueTsKKwkJCQlmU3RlcCA9IChsaW5lLmZMaW5lQXNjZW50IC0gbGluZS5mTGluZURlc2NlbnQpIC8gMTYuMGY7CisJCQl9CisKKwkJCWlmIChwbGFjZS5MaW5lQ21wKHdyV29yZC5CZWdpblBvcykgPT0gMCkKKwkJCXsKKwkJCQlwSXRlcmF0b3ItPlNldEF0KHdyV29yZC5CZWdpblBvcyk7CisJCQkJQ1BWVF9Xb3JkIHdvcmQ7CisJCQkJaWYgKHBJdGVyYXRvci0+R2V0V29yZCh3b3JkKSkKKwkJCQl7CisJCQkJCWZTdGFydFggPSB3b3JkLnB0V29yZC54OworCQkJCX0KKwkJCX0KKwkJCWVsc2UKKwkJCXsKKwkJCQlmU3RhcnRYID0gbGluZS5wdExpbmUueDsKKwkJCX0KKworCQkJaWYgKHBsYWNlLkxpbmVDbXAod3JXb3JkLkVuZFBvcykgPT0gMCkKKwkJCXsKKwkJCQlwSXRlcmF0b3ItPlNldEF0KHdyV29yZC5FbmRQb3MpOworCQkJCUNQVlRfV29yZCB3b3JkOworCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpCisJCQkJeworCQkJCQlmRW5kWCA9IHdvcmQucHRXb3JkLnggKyB3b3JkLmZXaWR0aDsKKwkJCQl9CisKKwkJCQliQnJlYWsgPSBUUlVFOworCQkJfQorCQkJZWxzZQorCQkJeworCQkJCWZFbmRYID0gbGluZS5wdExpbmUueCArIGxpbmUuZkxpbmVXaWR0aDsKKwkJCX0KKworCQkJQWRkU3F1aWdnbHlQYXRoKFBhdGhEYXRhLCBmU3RhcnRYLCBmRW5kWCwgZlksIGZTdGVwKTsKKworCQkJaWYgKGJCcmVhaykgYnJlYWs7CisJCX0KKwkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dExpbmUoKSk7CisJfQorfQorCit2b2lkIENQV0xfVXRpbHM6OkRyYXdFZGl0U3BlbGxDaGVjayhDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLCBJRlhfRWRpdCogcEVkaXQsIAorCQkJCQkJY29uc3QgQ1BERl9SZWN0JiByY0NsaXAsIGNvbnN0IENQREZfUG9pbnQmIHB0T2Zmc2V0LCBjb25zdCBDUFZUX1dvcmRSYW5nZSogcFJhbmdlLCAKKwkJCQkJCUlQV0xfU3BlbGxDaGVjayAqIHBTcGVsbENoZWNrKQoreworCWNvbnN0IEZYX0NPTE9SUkVGIGNyU3BlbGwgPSBBcmdiRW5jb2RlKDI1NSwyNTUsMCwwKTsKKworCS8vZm9yIHNwZWxsY2hlY2sKKwlGWF9CT09MIGJMYXRpbldvcmQgPSBGQUxTRTsKKwlDUFZUX1dvcmRQbGFjZSB3cFdvcmRTdGFydDsKKwlDRlhfQnl0ZVN0cmluZyBzTGF0aW5Xb3JkOworCisJQ0ZYX1BhdGhEYXRhIHBhdGhTcGVsbDsKKworCXBEZXZpY2UtPlNhdmVTdGF0ZSgpOworCisJaWYgKCFyY0NsaXAuSXNFbXB0eSgpKQorCXsKKwkJQ1BERl9SZWN0IHJjVGVtcCA9IHJjQ2xpcDsKKwkJcFVzZXIyRGV2aWNlLT5UcmFuc2Zvcm1SZWN0KHJjVGVtcCk7CisJCUZYX1JFQ1QgcmNEZXZDbGlwOworCQlyY0RldkNsaXAubGVmdCA9IChGWF9JTlQzMilyY1RlbXAubGVmdDsKKwkJcmNEZXZDbGlwLnJpZ2h0ID0gKEZYX0lOVDMyKXJjVGVtcC5yaWdodDsKKwkJcmNEZXZDbGlwLnRvcCA9IChGWF9JTlQzMilyY1RlbXAudG9wOworCQlyY0RldkNsaXAuYm90dG9tID0gKEZYX0lOVDMyKXJjVGVtcC5ib3R0b207CisJCXBEZXZpY2UtPlNldENsaXBfUmVjdCgmcmNEZXZDbGlwKTsKKwl9CisKKwlpZiAoSUZYX0VkaXRfSXRlcmF0b3IqIHBJdGVyYXRvciA9IHBFZGl0LT5HZXRJdGVyYXRvcigpKQorCXsKKwkJaWYgKHBFZGl0LT5HZXRGb250TWFwKCkpCisJCXsKKwkJCWlmIChwUmFuZ2UpCisJCQkJcEl0ZXJhdG9yLT5TZXRBdChwUmFuZ2UtPkJlZ2luUG9zKTsKKwkJCWVsc2UKKwkJCQlwSXRlcmF0b3ItPlNldEF0KDApOworCisJCQlDUFZUX1dvcmRQbGFjZSBvbGRwbGFjZTsJCQkKKworCQkJd2hpbGUgKHBJdGVyYXRvci0+TmV4dFdvcmQoKSkKKwkJCXsKKwkJCQlDUFZUX1dvcmRQbGFjZSBwbGFjZSA9IHBJdGVyYXRvci0+R2V0QXQoKTsKKwkJCQlpZiAocFJhbmdlICYmIHBsYWNlLldvcmRDbXAocFJhbmdlLT5FbmRQb3MpID4gMCkgYnJlYWs7CQkJCQorCisJCQkJQ1BWVF9Xb3JkIHdvcmQ7CQkJCQorCQkJCWlmIChwSXRlcmF0b3ItPkdldFdvcmQod29yZCkpCisJCQkJeworCQkJCQlpZiAoRlhfRURJVF9JU0xBVElOV09SRCh3b3JkLldvcmQpKQorCQkJCQl7CisJCQkJCQlpZiAoIWJMYXRpbldvcmQpCisJCQkJCQl7CisJCQkJCQkJd3BXb3JkU3RhcnQgPSBwbGFjZTsKKwkJCQkJCQliTGF0aW5Xb3JkID0gVFJVRTsJCQkJCQkJCQorCQkJCQkJfQorCisJCQkJCQlzTGF0aW5Xb3JkICs9IChjaGFyKXdvcmQuV29yZDsKKwkJCQkJfQorCQkJCQllbHNlCisJCQkJCXsKKwkJCQkJCWlmIChiTGF0aW5Xb3JkKQorCQkJCQkJeworCQkJCQkJCWlmICghc0xhdGluV29yZC5Jc0VtcHR5KCkpCisJCQkJCQkJeworCQkJCQkJCQlpZiAocFNwZWxsQ2hlY2sgJiYgIXBTcGVsbENoZWNrLT5DaGVja1dvcmQoc0xhdGluV29yZCkpCisJCQkJCQkJCXsKKwkJCQkJCQkJCUFkZFNwZWxsQ2hlY2tPYmoocGF0aFNwZWxsLHBFZGl0LENQVlRfV29yZFJhbmdlKHdwV29yZFN0YXJ0LG9sZHBsYWNlKSk7CQkJCQkJCQkJCisJCQkJCQkJCQlwSXRlcmF0b3ItPlNldEF0KHBsYWNlKTsKKwkJCQkJCQkJfQorCQkJCQkJCX0KKwkJCQkJCQliTGF0aW5Xb3JkID0gRkFMU0U7CisJCQkJCQl9CisKKwkJCQkJCXNMYXRpbldvcmQuRW1wdHkoKTsKKwkJCQkJfQorCQkJCQkKKwkJCQkJb2xkcGxhY2UgPSBwbGFjZTsKKwkJCQl9CisJCQkJZWxzZQorCQkJCXsKKwkJCQkJaWYgKGJMYXRpbldvcmQpCisJCQkJCXsKKwkJCQkJCWlmICghc0xhdGluV29yZC5Jc0VtcHR5KCkpCisJCQkJCQl7CisJCQkJCQkJaWYgKHBTcGVsbENoZWNrICYmICFwU3BlbGxDaGVjay0+Q2hlY2tXb3JkKHNMYXRpbldvcmQpKQorCQkJCQkJCXsKKwkJCQkJCQkJQWRkU3BlbGxDaGVja09iaihwYXRoU3BlbGwscEVkaXQsQ1BWVF9Xb3JkUmFuZ2Uod3BXb3JkU3RhcnQsb2xkcGxhY2UpKTsJCQkJCQkJCQkKKwkJCQkJCQkJcEl0ZXJhdG9yLT5TZXRBdChwbGFjZSk7CisJCQkJCQkJfQorCQkJCQkJfQorCQkJCQkJYkxhdGluV29yZCA9IEZBTFNFOworCQkJCQl9CisKKwkJCQkJc0xhdGluV29yZC5FbXB0eSgpOworCQkJCX0KKwkJCX0KKworCQkJaWYgKCFzTGF0aW5Xb3JkLklzRW1wdHkoKSkgCisJCQl7CisJCQkJaWYgKHBTcGVsbENoZWNrICYmICFwU3BlbGxDaGVjay0+Q2hlY2tXb3JkKHNMYXRpbldvcmQpKQorCQkJCXsKKwkJCQkJQWRkU3BlbGxDaGVja09iaihwYXRoU3BlbGwscEVkaXQsQ1BWVF9Xb3JkUmFuZ2Uod3BXb3JkU3RhcnQsb2xkcGxhY2UpKTsJCisJCQkJfQorCQkJfQorCQl9CisJfQorCQorCUNGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CisJZ3NkLm1fTGluZVdpZHRoID0gMDsKKwlpZiAocGF0aFNwZWxsLkdldFBvaW50Q291bnQoKSA+IDApCisJCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoU3BlbGwsIHBVc2VyMkRldmljZSwgJmdzZCwgMCwgY3JTcGVsbCwgRlhGSUxMX0FMVEVSTkFURSk7CisKKwlwRGV2aWNlLT5SZXN0b3JlU3RhdGUoKTsKK30KKworRlhfQk9PTCBDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikKK3sKKwlzd2l0Y2ggKGNvbG9yLm5Db2xvclR5cGUpCisJeworCWNhc2UgQ09MT1JUWVBFX1RSQU5TUEFSRU5UOgorCQlyZXR1cm4gRkFMU0U7CisJY2FzZSBDT0xPUlRZUEVfR1JBWToKKwkJcmV0dXJuIGNvbG9yLmZDb2xvcjEgPCAwLjVmOworCWNhc2UgQ09MT1JUWVBFX1JHQjoKKwkJcmV0dXJuIGNvbG9yLmZDb2xvcjEgKyBjb2xvci5mQ29sb3IyICsgY29sb3IuZkNvbG9yMyA8IDEuNWY7CisJY2FzZSBDT0xPUlRZUEVfQ01ZSzoKKwkJcmV0dXJuIGNvbG9yLmZDb2xvcjEgKyBjb2xvci5mQ29sb3IyICsgY29sb3IuZkNvbG9yMyArIGNvbG9yLmZDb2xvcjQgPiAyLjBmOworCX0KKworCXJldHVybiBUUlVFOworfQorCitDUFdMX0NvbG9yIENQV0xfVXRpbHM6OkdldFJldmVyc2VDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikKK3sKKwlDUFdMX0NvbG9yIGNyUmV0ID0gY29sb3I7CisKKwlzd2l0Y2ggKGNvbG9yLm5Db2xvclR5cGUpCisJeworCWNhc2UgQ09MT1JUWVBFX0dSQVk6CisJCWNyUmV0LmZDb2xvcjEgPSAxLjBmIC0gY3JSZXQuZkNvbG9yMTsKKwkJYnJlYWs7CisJY2FzZSBDT0xPUlRZUEVfUkdCOgorCQljclJldC5mQ29sb3IxID0gMS4wZiAtIGNyUmV0LmZDb2xvcjE7CisJCWNyUmV0LmZDb2xvcjIgPSAxLjBmIC0gY3JSZXQuZkNvbG9yMjsKKwkJY3JSZXQuZkNvbG9yMyA9IDEuMGYgLSBjclJldC5mQ29sb3IzOworCQlicmVhazsKKwljYXNlIENPTE9SVFlQRV9DTVlLOgorCQljclJldC5mQ29sb3IxID0gMS4wZiAtIGNyUmV0LmZDb2xvcjE7CisJCWNyUmV0LmZDb2xvcjIgPSAxLjBmIC0gY3JSZXQuZkNvbG9yMjsKKwkJY3JSZXQuZkNvbG9yMyA9IDEuMGYgLSBjclJldC5mQ29sb3IzOworCQljclJldC5mQ29sb3I0ID0gMS4wZiAtIGNyUmV0LmZDb2xvcjQ7CisJCWJyZWFrOworCX0KKworCXJldHVybiBjclJldDsKK30KKworQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9VdGlsczo6R2V0SWNvbkFwcFN0cmVhbShGWF9JTlQzMiBuVHlwZSwgY29uc3QgQ1BERl9SZWN0JiByZWN0LCBjb25zdCBDUFdMX0NvbG9yJiBjckZpbGwsIAorCQkJCQkJCQkJCQkJY29uc3QgQ1BXTF9Db2xvciYgY3JTdHJva2UpCit7CisJQ0ZYX0J5dGVTdHJpbmcgc0FwcFN0cmVhbSA9IENQV0xfVXRpbHM6OkdldENvbG9yQXBwU3RyZWFtKGNyU3Ryb2tlLCBGQUxTRSk7CisJc0FwcFN0cmVhbSArPSBDUFdMX1V0aWxzOjpHZXRDb2xvckFwcFN0cmVhbShjckZpbGwsIFRSVUUpOworCisJQ0ZYX0J5dGVTdHJpbmcgc1BhdGg7CisJQ0ZYX1BhdGhEYXRhIHBhdGg7CisKKwlzd2l0Y2ggKG5UeXBlKQorCXsKKwljYXNlIFBXTF9JQ09OVFlQRV9DSEVDS01BUks6CisJCUdldEdyYXBoaWNzX0NoZWNrbWFyayhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsJCisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX0NJUkNMRToKKwkJR2V0R3JhcGhpY3NfQ2lyY2xlKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9DT01NRU5UOgorCQlHZXRHcmFwaGljc19Db21tZW50KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9DUk9TUzoKKwkJR2V0R3JhcGhpY3NfQ3Jvc3Moc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX0hFTFA6CisJCUdldEdyYXBoaWNzX0hlbHAoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX0lOU0VSVFRFWFQ6CisJCUdldEdyYXBoaWNzX0luc2VydFRleHQoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX0tFWToKKwkJR2V0R3JhcGhpY3NfS2V5KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9ORVdQQVJBR1JBUEg6CisJCUdldEdyYXBoaWNzX05ld1BhcmFncmFwaChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfVEVYVE5PVEU6CisJCUdldEdyYXBoaWNzX1RleHROb3RlKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9QQVJBR1JBUEg6CisJCUdldEdyYXBoaWNzX1BhcmFncmFwaChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfUklHSFRBUlJPVzoKKwkJR2V0R3JhcGhpY3NfUmlnaHRBcnJvdyhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfUklHSFRQT0lOVEVSOgorCQlHZXRHcmFwaGljc19SaWdodFBvaW50ZXIoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX1NUQVI6CisJCUdldEdyYXBoaWNzX1N0YXIoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX1VQQVJST1c6CisJCUdldEdyYXBoaWNzX1VwQXJyb3coc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX1VQTEVGVEFSUk9XOgorCQlHZXRHcmFwaGljc19VcExlZnRBcnJvdyhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfR1JBUEg6CisJCUdldEdyYXBoaWNzX0dyYXBoKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9TVFJFQU0pOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9QQVBFUkNMSVA6CisJCUdldEdyYXBoaWNzX1BhcGVyY2xpcChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfQVRUQUNITUVOVDoKKwkJR2V0R3JhcGhpY3NfQXR0YWNobWVudChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfVEFHOgorCQlHZXRHcmFwaGljc19UYWcoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1NUUkVBTSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX0ZPWElUOgorCQlHZXRHcmFwaGljc19Gb3hpdChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfU1RSRUFNKTsKKwkJYnJlYWs7CisJfQorCisJc0FwcFN0cmVhbSArPSBzUGF0aDsKKwlpZiAoY3JTdHJva2UubkNvbG9yVHlwZSAhPSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQpCisJCXNBcHBTdHJlYW0gKz0gIkIqXG4iOworCWVsc2UKKwkJc0FwcFN0cmVhbSArPSAiZipcbiI7CisKKwlyZXR1cm4gc0FwcFN0cmVhbTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpEcmF3SWNvbkFwcFN0cmVhbShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlLAorCQkJCQkJRlhfSU5UMzIgblR5cGUsIGNvbnN0IENQREZfUmVjdCAmIHJlY3QsIGNvbnN0IENQV0xfQ29sb3ImIGNyRmlsbCwgY29uc3QgQ1BXTF9Db2xvciYgY3JTdHJva2UsIGNvbnN0IEZYX0lOVDMyIG5UcmFuc3BhcmFuY3kpCit7CisJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKKwlnc2QubV9MaW5lV2lkdGggPSAxLjBmOworCisJQ0ZYX0J5dGVTdHJpbmcgc1BhdGg7CisJQ0ZYX1BhdGhEYXRhIHBhdGg7CisKKwlzd2l0Y2ggKG5UeXBlKQorCXsKKwljYXNlIFBXTF9JQ09OVFlQRV9DSEVDS01BUks6CisJCUdldEdyYXBoaWNzX0NoZWNrbWFyayhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9DSVJDTEU6CisJCUdldEdyYXBoaWNzX0NpcmNsZShzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9DT01NRU5UOgorCQlHZXRHcmFwaGljc19Db21tZW50KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX0NST1NTOgorCQlHZXRHcmFwaGljc19Dcm9zcyhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9IRUxQOgorCQlHZXRHcmFwaGljc19IZWxwKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX0lOU0VSVFRFWFQ6CisJCUdldEdyYXBoaWNzX0luc2VydFRleHQoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfS0VZOgorCQlHZXRHcmFwaGljc19LZXkoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfTkVXUEFSQUdSQVBIOgorCQlHZXRHcmFwaGljc19OZXdQYXJhZ3JhcGgoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfVEVYVE5PVEU6CisJCUdldEdyYXBoaWNzX1RleHROb3RlKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX1BBUkFHUkFQSDoKKwkJR2V0R3JhcGhpY3NfUGFyYWdyYXBoKHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX1JJR0hUQVJST1c6CisJCUdldEdyYXBoaWNzX1JpZ2h0QXJyb3coc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfUklHSFRQT0lOVEVSOgorCQlHZXRHcmFwaGljc19SaWdodFBvaW50ZXIoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfU1RBUjoKKwkJR2V0R3JhcGhpY3NfU3RhcihzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9VUEFSUk9XOgorCQlHZXRHcmFwaGljc19VcEFycm93KHNQYXRoLCBwYXRoLCByZWN0LCBQV0xQVF9QQVRIREFUQSk7CisJCWJyZWFrOworCWNhc2UgUFdMX0lDT05UWVBFX1VQTEVGVEFSUk9XOgorCQlHZXRHcmFwaGljc19VcExlZnRBcnJvdyhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9HUkFQSDoKKwkJR2V0R3JhcGhpY3NfR3JhcGgoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfUEFQRVJDTElQOgorCQlHZXRHcmFwaGljc19QYXBlcmNsaXAoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsKKwkJYnJlYWs7CisJY2FzZSBQV0xfSUNPTlRZUEVfQVRUQUNITUVOVDoKKwkJR2V0R3JhcGhpY3NfQXR0YWNobWVudChzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9UQUc6CisJCUdldEdyYXBoaWNzX1RhZyhzUGF0aCwgcGF0aCwgcmVjdCwgUFdMUFRfUEFUSERBVEEpOworCQlicmVhazsKKwljYXNlIFBXTF9JQ09OVFlQRV9GT1hJVDoKKwkJR2V0R3JhcGhpY3NfRm94aXQoc1BhdGgsIHBhdGgsIHJlY3QsIFBXTFBUX1BBVEhEQVRBKTsKKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJcmV0dXJuOworCX0KKworCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoLCBwVXNlcjJEZXZpY2UsICZnc2QsIAorCQlQV0xDb2xvclRvRlhDb2xvcihjckZpbGwsblRyYW5zcGFyYW5jeSksIFBXTENvbG9yVG9GWENvbG9yKGNyU3Ryb2tlLG5UcmFuc3BhcmFuY3kpLCBGWEZJTExfQUxURVJOQVRFKTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19DaGVja21hcmsoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQoreworCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0OworCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsKKworCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSAKKwl7CisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCAgKyBmV2lkdGggLyAxNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAyIC8gNS4wZiksUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICArIGZXaWR0aCAvIDE1LjBmICsgUFdMX0JFWklFUiooZldpZHRoIC8gNy4wZiAtIGZXaWR0aCAvIDE1LjBmKSwgCisJCQkJCSAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAyIC8gNS4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQgKiAyIC8gNy4wZiAtIGZIZWlnaHQgKiAyIC8gNS4wZikpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCAvIDQuNWYgKyBQV0xfQkVaSUVSKihmV2lkdGggLyA1LjBmIC0gZldpZHRoIC8gNC41ZiksCisJCQkJCSAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgLyAxNi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQgLyA1LjBmIC0gZkhlaWdodCAvIDE2LjBmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gNC41ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgLyAxNi4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gNC41ZiArIFBXTF9CRVpJRVIqKGZXaWR0aCAvIDQuNGYgLSBmV2lkdGggLyA0LjVmKSwKKwkJICAgICAgICAgICAgICBjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDE2LjBmIC0gUFdMX0JFWklFUipmSGVpZ2h0IC8gMTYuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCAvIDMuMGYgKyBQV0xfQkVaSUVSKihmV2lkdGggLyA0LjBmIC0gZldpZHRoIC8gMy4wZiksCisJCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gMy4wZiwgY3JCQm94LmJvdHRvbSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gMy4wZiArIFBXTF9CRVpJRVIqZldpZHRoKigxLzcuMGYgKyAyLzE1LjBmKSwKKwkJICAgICAgICAgICAgICBjckJCb3guYm90dG9tICsgUFdMX0JFWklFUipmSGVpZ2h0ICogNCAvIDUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCAgKyBmV2lkdGggKiAxNCAvIDE1LjBmICsgUFdMX0JFWklFUipmV2lkdGgqKDEvNy4wZiAtIDcvMTUuMGYpLAorCQkgICAgICAgICAgICAgIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0ICogMTUvMTYuMGYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0ICogNC81LjBmIC0gZkhlaWdodCAqIDE1LzE2LjBmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICArIGZXaWR0aCAqIDE0IC8gMTUuMGYsY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAxNSAvIDE2LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgICsgZldpZHRoICogMTQgLyAxNS4wZiArIFBXTF9CRVpJRVIqKGZXaWR0aCAqIDcgLyAxNS4wZiAtIGZXaWR0aCAqIDE0IC8gMTUuMGYpLAorCQkgICAgICAgICAgICAgIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0ICogMTUgLyAxNi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQgKiA4IC8gNy4wZiAtIGZIZWlnaHQgKiAxNSAvIDE2LjBmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gMy42ZiArIFBXTF9CRVpJRVIqKGZXaWR0aCAvIDMuNGYgLSBmV2lkdGggLyAzLjZmKSwKKwkJICAgICAgICAgICAgICBjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDMuNWYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0IC8gMy41ZiAtIGZIZWlnaHQgLyAzLjVmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoIC8gMy42ZixjckJCb3guYm90dG9tICsgZkhlaWdodCAvIDMuNWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCAvIDMuNmYsCisJCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgLyAzLjVmICsgUFdMX0JFWklFUiooZkhlaWdodCAvIDQuMGYgLSBmSGVpZ2h0IC8gMy41ZikpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCAgKyBmV2lkdGggLyAxNS4wZiArIFBXTF9CRVpJRVIqKGZXaWR0aCAvIDMuNWYgLSBmV2lkdGggLyAxNS4wZiksCisJCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQgKiAyIC8gNS4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQgKiAzLjVmIC8gNS4wZiAtIGZIZWlnaHQgKiAyIC8gNS4wZikpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCAgKyBmV2lkdGggLyAxNS4wZixjckJCb3guYm90dG9tICsgZkhlaWdodCAqIDIgLyA1LjBmKSwgUFdMUFRfQkVaSUVSVE8pCisJfTsKKworCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQorCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAxNik7CisJZWxzZQorCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDE2KTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19DaXJjbGUoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQoreworCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0OworCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsKKworCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPQorCXsKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzE1LjBmLGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTUuMGYsCisJCSAgICAgICAgICAgICAgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQqMTQvMTUuMGYgLSBmSGVpZ2h0LzIuMGYpKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiAtIFBXTF9CRVpJRVIqKGZXaWR0aC8yLjBmIC0gZldpZHRoLzE1LjBmKSwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiArIFBXTF9CRVpJRVIqKGZXaWR0aCoxNC8xNS4wZiAtIGZXaWR0aC8yLjBmKSwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0KjE0LzE1LjBmIC0gZkhlaWdodC8yLjBmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiAtIFBXTF9CRVpJRVIqKGZIZWlnaHQvMi4wZiAtIGZIZWlnaHQvMTUuMGYpKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiArIFBXTF9CRVpJRVIqKGZXaWR0aCoxNC8xNS4wZiAtIGZXaWR0aC8yLjBmKSwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYgLSBQV0xfQkVaSUVSKihmV2lkdGgvMi4wZiAtIGZXaWR0aC8xNS4wZiksIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgLSBQV0xfQkVaSUVSKihmSGVpZ2h0LzIuMGYgLSBmSGVpZ2h0LzE1LjBmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzE1LjBmLGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCozLzE1LjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjMvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0KjQvNS4wZiAtIGZIZWlnaHQvMi4wZikpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmIC0gUFdMX0JFWklFUiooZldpZHRoLzIuMGYgLSBmV2lkdGgqMy8xNS4wZiksIGNyQkJveC50b3AgLSBmSGVpZ2h0KjMvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodCozLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiArIFBXTF9CRVpJRVIqKGZXaWR0aCo0LzUuMGYgLSBmV2lkdGgvMi4wZiksIGNyQkJveC50b3AgLSBmSGVpZ2h0KjMvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMy8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQqNC81LjBmIC0gZkhlaWdodC8yLjBmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCozLzE1LjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjMvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgLSBQV0xfQkVaSUVSKihmSGVpZ2h0KjQvNS4wZiAtIGZIZWlnaHQvMi4wZikpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmICsgUFdMX0JFWklFUiooZldpZHRoKjQvNS4wZiAtIGZXaWR0aC8yLjBmKSwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMy8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjMvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmIC0gUFdMX0JFWklFUiooZldpZHRoKjQvNS4wZiAtIGZXaWR0aC8yLjBmKSwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMy8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjMvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgLSBQV0xfQkVaSUVSKihmSGVpZ2h0KjQvNS4wZiAtIGZIZWlnaHQvMi4wZikpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCozLzE1LjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmKSwgUFdMUFRfQkVaSUVSVE8pCisJfTsKKworCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQorCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAyNik7CisJZWxzZQorCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDI2KTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19Db21tZW50KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkKK3sKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisKKwlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gCisJeworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzYuMGYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzYuMGYgKyBQV0xfQkVaSUVSKihmSGVpZ2h0LzYuMGYgLSBmSGVpZ2h0LzEwLjBmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUuMGYgLSBQV0xfQkVaSUVSKmZXaWR0aC8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTAuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCoyLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8xMC4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCoyLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8xMC4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMi8xNS4wZiArIFBXTF9CRVpJRVIqZldpZHRoLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8xMC4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvNiArIFBXTF9CRVpJRVIqKGZIZWlnaHQvNi4wZiAtIGZIZWlnaHQvMTAuMGYpKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC82LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8zLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqNC8xNS4wZiArIFBXTF9CRVpJRVIqZkhlaWdodC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCoyLzE1LjBmICsgUFdMX0JFWklFUipmV2lkdGgvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMi8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjUvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNS8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMi8xNSArIFBXTF9CRVpJRVIqZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNS8xNS4wZiAtIFBXTF9CRVpJRVIqZldpZHRoKjIvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjIvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCo2LzMwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNy8zMC4wZiArIFBXTF9CRVpJRVIqZldpZHRoLzMwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNy8zMC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMi8xNS4wZiArIFBXTF9CRVpJRVIqZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqNy8zMC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMi8xNS4wZiAtIFBXTF9CRVpJRVIqZldpZHRoLzE1LjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCo0LzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTUuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzMuMGYgLSBQV0xfQkVaSUVSKmZIZWlnaHQvMTUuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xNS4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMy4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC82LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjgvMzAuMGYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjIvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjgvMzAuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMi8xNSwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMjUvNjAuMGYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjIvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjI1LzYwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjIvMTUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCo0LzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiksIFBXTFBUX0xJTkVUTykKKwl9OworCisJaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pCisJCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDMwKTsKKwllbHNlCisJCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMzApOworfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0Nyb3NzKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkKK3sKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisJLy9GWF9GTE9BVCBmY2F0ZXJjb3JuZXIgPSAoRlhfRkxPQVQpc3FydChmV2lkdGgqZldpZHRoICsgZkhlaWdodCpmSGVpZ2h0KTsKKwlDUFdMX1BvaW50IGNlbnRlcl9wb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yKTsKKworCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSAKKwl7CisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjZW50ZXJfcG9pbnQueCwgY2VudGVyX3BvaW50LnkgKyBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54ICsgZldpZHRoKjAuM2YsIGNlbnRlcl9wb2ludC55ICsgZkhlaWdodC8xMC4wZiArIGZXaWR0aCowLjNmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54ICsgZldpZHRoLzEwLjBmICsgZldpZHRoKjAuM2YsIGNlbnRlcl9wb2ludC55ICsgZkhlaWdodCowLjNmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54ICsgZldpZHRoLzEwLjBmLCBjZW50ZXJfcG9pbnQueSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjZW50ZXJfcG9pbnQueCArIGZXaWR0aC8xMC4wZiArIGZXaWR0aCowLjNmLCBjZW50ZXJfcG9pbnQueSAtIGZIZWlnaHQqMC4zZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjZW50ZXJfcG9pbnQueCArIGZXaWR0aCowLjNmLCBjZW50ZXJfcG9pbnQueSAtIGZIZWlnaHQvMTAuMGYgLSBmSGVpZ2h0KjAuM2YpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY2VudGVyX3BvaW50LngsIGNlbnRlcl9wb2ludC55IC0gZkhlaWdodC8xMC4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjZW50ZXJfcG9pbnQueCAtIGZXaWR0aCowLjNmLCBjZW50ZXJfcG9pbnQueSAtIGZIZWlnaHQvMTAgLSBmSGVpZ2h0KjAuM2YpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY2VudGVyX3BvaW50LnggLSBmV2lkdGgvMTAuMGYgLSBmV2lkdGgqMC4zZiwgY2VudGVyX3BvaW50LnkgLSBmSGVpZ2h0KjAuM2YpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY2VudGVyX3BvaW50LnggLSBmV2lkdGgvMTAsIGNlbnRlcl9wb2ludC55KSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54IC0gZldpZHRoLzEwIC0gZldpZHRoKjAuM2YsIGNlbnRlcl9wb2ludC55ICsgZkhlaWdodCowLjNmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNlbnRlcl9wb2ludC54IC0gZldpZHRoKjAuM2YsIGNlbnRlcl9wb2ludC55ICsgZkhlaWdodC8xMC4wZiArIGZIZWlnaHQqMC4zZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjZW50ZXJfcG9pbnQueCwgY2VudGVyX3BvaW50LnkgKyBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfTElORVRPKQorCX07CisKKwlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkKKwkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMTMpOworCWVsc2UKKwkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAxMyk7Cit9CisKK3ZvaWQgQ1BXTF9VdGlsczo6R2V0R3JhcGhpY3NfSGVscChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpCit7CisJRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7CisJRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOworCisJQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IAorCXsKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmICsgUFdMX0JFWklFUiooZkhlaWdodC82MC4wZiAtIGZIZWlnaHQvMi4wZikpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmIC0gUFdMX0JFWklFUiooZldpZHRoLzIuMGYgLSBmV2lkdGgvNjAuMGYpLCBjckJCb3guYm90dG9tICsgZkhlaWdodC82MC4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzYwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiArIFBXTF9CRVpJRVIqZldpZHRoKjI5LzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC82MC4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC82MC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMi4wZiArIFBXTF9CRVpJRVIqKGZIZWlnaHQvNjAuMGYgLSBmSGVpZ2h0LzIuMGYpKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzYwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8yLjBmICsgUFdMX0JFWklFUipmSGVpZ2h0KjI5LzYwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiArIFBXTF9CRVpJRVIqZldpZHRoKjI5LzYwLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC82MC4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzYwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLAkJCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmIC0gUFdMX0JFWklFUipmV2lkdGgqMjkvNjAuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzYwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNjAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYgICsgUFdMX0JFWklFUipmSGVpZ2h0KjI5LzYwLjBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNjAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjI3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmICsgUFdMX0JFWklFUipmSGVpZ2h0KjAuMjNmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiAtIFBXTF9CRVpJRVIqZldpZHRoKjAuMjNmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjg3ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuODdmKSwgUFdMUFRfQkVaSUVSVE8pLAkJCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjVmICsgUFdMX0JFWklFUipmV2lkdGgqMC4yM2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuODdmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMjdmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjM2ZiArIFBXTF9CRVpJRVIqZkhlaWdodCowLjIzZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjI3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4yN2YgLSBmV2lkdGgqMC4wOGYqMC4yZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYgLSBmSGVpZ2h0KjAuMTVmKjAuN2YpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4zNWYgKyBmV2lkdGgqMC4wOGYqMC4yZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41MWYgKyBmSGVpZ2h0KjAuMTVmKjAuMmYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4zNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNTFmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMzVmIC0gZldpZHRoKjAuMWYqMC41ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41MWYgLSBmSGVpZ2h0KjAuMTVmKjAuM2YpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC40NWYgLSBmV2lkdGgqMC4xZiowLjVmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjY4ZiArIGZIZWlnaHQqMC4xNWYqMC41ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjQ1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC42OGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC40NWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMzBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjQ1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4zMGYgLSBmV2lkdGgqMC4xZiowLjdmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjMwZiAtIGZXaWR0aCowLjFmKjAuN2YpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41NWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMzBmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTVmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjY2ZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41NWYgLSBmV2lkdGgqMC4xZiowLjA1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC42NmYgKyBmSGVpZ2h0KjAuMThmKjAuNWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC40NWYgLSBmV2lkdGgqMC4xZiowLjA1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC40OGYgLSBmSGVpZ2h0KjAuMThmKjAuM2YpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC40NWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNDhmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNDVmICsgZldpZHRoKjAuMDhmKjAuMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNDhmICsgZkhlaWdodCowLjE4ZiowLjJmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMzdmIC0gZldpZHRoKjAuMDhmKjAuMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmIC0gZkhlaWdodCowLjE4ZiowLjdmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMzdmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjM2ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjM3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYgKyBQV0xfQkVaSUVSKmZIZWlnaHQqMC4xM2YpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjVmICsgUFdMX0JFWklFUipmV2lkdGgqMC4xM2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuNzdmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC43N2YpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjVmIC0gUFdMX0JFWklFUipmV2lkdGgqMC4xM2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuNzdmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4zN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmICsgUFdMX0JFWklFUipmSGVpZ2h0KjAuMTNmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4zN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmKSwgUFdMUFRfQkVaSUVSVE8pLAkJCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjM3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zNmYgLSBmV2lkdGgqMC4xZiowLjZmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzZmIC0gZldpZHRoKjAuMWYqMC42ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjdmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjM2ZiksIFBXTFBUX0JFWklFUlRPKSwJCQorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTZmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjEzZiksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41NmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTNmICsgUFdMX0JFWklFUipmSGVpZ2h0KjAuMDU1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjUwNWYgLSBQV0xfQkVaSUVSKmZXaWR0aCowLjA5NWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTg1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjUwNWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTg1ZiksIFBXTFBUX0JFWklFUlRPKSwJCQorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNTA1ZiArIFBXTF9CRVpJRVIqZldpZHRoKjAuMDY1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4xODVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNDRmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjEzZiArIFBXTF9CRVpJRVIqZkhlaWdodCowLjA1NWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC40NGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTNmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuNDRmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjEzZiAtIFBXTF9CRVpJRVIqZkhlaWdodCowLjA1NWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41MDVmICsgUFdMX0JFWklFUipmV2lkdGgqMC4wNjVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjA3NWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41MDVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjA3NWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41MDVmIC0gUFdMX0JFWklFUipmV2lkdGgqMC4wNjVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjA3NWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC41NmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMTNmIC0gUFdMX0JFWklFUipmSGVpZ2h0KjAuMDU1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjU2ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4xM2YpLCBQV0xQVF9CRVpJRVJUTykKKwl9OworCisJaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pCisJCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDU5KTsKKwllbHNlCisJCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgNTkpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0luc2VydFRleHQoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQoreworCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0OworCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsKKworCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSAKKwl7CisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8xMCwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTApLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMi8xNSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTAsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzEwLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xMCksIFBXTFBUX0xJTkVUTykKKwl9OworCisJaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pCisJCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDQpOworCWVsc2UKKwkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCA0KTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19LZXkoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQoreworCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0OworCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsKKwlGWF9GTE9BVCBrID0gLWZIZWlnaHQvZldpZHRoOworCUNQV0xfUG9pbnQgdGFpbDsKKwlDUFdMX1BvaW50IENpY2xlQ2VudGVyOworCXRhaWwueCA9IGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuOWY7CisJdGFpbC55ID0gayoodGFpbC54IC0gY3JCQm94LnJpZ2h0KSArIGNyQkJveC5ib3R0b207CisJQ2ljbGVDZW50ZXIueCA9IGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMTVmOworCUNpY2xlQ2VudGVyLnkgPSBrKihDaWNsZUNlbnRlci54IC0gY3JCQm94LnJpZ2h0KSArIGNyQkJveC5ib3R0b207CisKKwlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gCisJeworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwLjBmLCAtZldpZHRoLzMwLjBmL2sgKyB0YWlsLnkpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwLjBmIC0gZldpZHRoKjAuMThmLCAtaypmV2lkdGgqMC4xOGYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludCh0YWlsLnggKyBmV2lkdGgvMzAgLSBmV2lkdGgqMC4xOGYgKyBmV2lkdGgqMC4wN2YsCisJCSAgICAgICAgICAgICAgLWZXaWR0aCowLjA3Zi9rIC0gaypmV2lkdGgqMC4xOGYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludCh0YWlsLnggKyBmV2lkdGgvMzAgLSBmV2lkdGgqMC4xOGYgLSBmV2lkdGgvMjAgKyBmV2lkdGgqMC4wN2YsCisJCSAgICAgICAgICAgICAgLWZXaWR0aCowLjA3Zi9rIC0gaypmV2lkdGgvMjAgLSBrKmZXaWR0aCowLjE4ZiAtIGZXaWR0aC8zMC9rICsgdGFpbC55KSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCAtIGZXaWR0aCowLjE4ZiAtIGZXaWR0aC8yMCwKKwkJICAgICAgICAgICAgICAtaypmV2lkdGgvMjAgLSBrKmZXaWR0aCowLjE4ZiAtIGZXaWR0aC8zMC9rICsgdGFpbC55KSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCAtIGZXaWR0aCowLjE4ZiAtIGZXaWR0aC8yMCAtIGZXaWR0aC8xNSwKKwkJICAgICAgICAgICAgICAtaypmV2lkdGgvMTUgLSBrKmZXaWR0aC8yMCAtIGsqZldpZHRoKjAuMThmIC0gZldpZHRoLzMwL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwIC0gZldpZHRoKjAuMThmIC0gZldpZHRoLzIwIC0gZldpZHRoLzE1ICsgZldpZHRoKjAuMDdmLAorCQkgICAgICAgICAgICAgIC1mV2lkdGgqMC4wN2YvayAtIGsqZldpZHRoLzE1IC0gaypmV2lkdGgvMjAgLSBrKmZXaWR0aCowLjE4ZiAtIGZXaWR0aC8zMC9rICsgdGFpbC55KSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCAtIGZXaWR0aCowLjE4ZiAtIGZXaWR0aC8yMCAtIGZXaWR0aC8xNSAtIGZXaWR0aC8yMCArIGZXaWR0aCowLjA3ZiwKKwkJICAgICAgICAgICAgICAtZldpZHRoKjAuMDdmL2sgKyAtaypmV2lkdGgvMjAgKyAtaypmV2lkdGgvMTUgLSBrKmZXaWR0aC8yMCAtIGsqZldpZHRoKjAuMThmIC0gZldpZHRoLzMwL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwIC0gZldpZHRoKjAuMThmIC0gZldpZHRoLzIwIC0gZldpZHRoLzE1IC0gZldpZHRoLzIwLAorCQkgICAgICAgICAgICAgIC1rKmZXaWR0aC8yMCArIC1rKmZXaWR0aC8xNSAtIGsqZldpZHRoLzIwIC0gaypmV2lkdGgqMC4xOGYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludCh0YWlsLnggKyBmV2lkdGgvMzAgLSBmV2lkdGgqMC40NWYsIC1rKmZXaWR0aCowLjQ1ZiAtIGZXaWR0aC8zMC9rICsgdGFpbC55KSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8zMCAtIGZXaWR0aCowLjQ1ZiArIGZXaWR0aCowLjJmLAorCQkgICAgICAgICAgICAgIC1mV2lkdGgqMC40Zi9rIC0gaypmV2lkdGgqMC40NWYgLSBmV2lkdGgvMzAvayArIHRhaWwueSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KENpY2xlQ2VudGVyLnggKyBmV2lkdGgqMC4yZiwgLSBmV2lkdGgqMC4xZi9rICsgQ2ljbGVDZW50ZXIueSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KENpY2xlQ2VudGVyLngsIENpY2xlQ2VudGVyLnkpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54IC0gZldpZHRoLzYwLjBmLCAtaypmV2lkdGgvNjAgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoQ2ljbGVDZW50ZXIueCAtIGZXaWR0aC82MCwgLWsqZldpZHRoLzYwICsgQ2ljbGVDZW50ZXIueSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KENpY2xlQ2VudGVyLngsIENpY2xlQ2VudGVyLnkpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54IC0gZldpZHRoKjAuMjJmLCBmV2lkdGgqMC4zNWYvayArIENpY2xlQ2VudGVyLnkgLSBmSGVpZ2h0KjAuMDVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54IC0gZldpZHRoLzMwIC0gZldpZHRoKjAuNDVmIC0gZldpZHRoKjAuMThmLCBmV2lkdGgqMC4wNWYvayAtIGsqZldpZHRoKjAuNDVmICsgZldpZHRoLzMwL2sgKyB0YWlsLnkgLSBmSGVpZ2h0KjAuMDVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54IC0gZldpZHRoLzMwLjBmIC0gZldpZHRoKjAuNDVmLCAtaypmV2lkdGgqMC40NWYgKyBmV2lkdGgvMzAuMGYvayArIHRhaWwueSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCAtIGZXaWR0aC8zMC4wZiwgZldpZHRoLzMwLjBmL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54ICsgZldpZHRoLzMwLCAtZldpZHRoLzMwL2sgKyB0YWlsLnkpLCBQV0xQVF9MSU5FVE8pLAkJCisgCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoQ2ljbGVDZW50ZXIueCArIGZXaWR0aCowLjA4ZiwgaypmV2lkdGgqMC4wOGYgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfTU9WRVRPKSwKKyAJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54ICsgZldpZHRoKjAuMDhmICsgZldpZHRoKjAuMWYsIC1mV2lkdGgqMC4xZi9rICsgaypmV2lkdGgqMC4wOGYgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfQkVaSUVSVE8pLAorIAkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KENpY2xlQ2VudGVyLnggKyBmV2lkdGgqMC4yMmYgKyBmV2lkdGgqMC4xZiwgaypmV2lkdGgqMC4yMmYgKyBDaWNsZUNlbnRlci55IC0gZldpZHRoKjAuMWYvayksIFBXTFBUX0JFWklFUlRPKSwKKyAJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChDaWNsZUNlbnRlci54ICsgZldpZHRoKjAuMjJmLCBrKmZXaWR0aCowLjIyZiArIENpY2xlQ2VudGVyLnkpLCBQV0xQVF9CRVpJRVJUTyksCisgCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoQ2ljbGVDZW50ZXIueCArIGZXaWR0aCowLjIyZiAtIGZXaWR0aCowLjFmLCBmV2lkdGgqMC4xZi9rICsgaypmV2lkdGgqMC4yMmYgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoQ2ljbGVDZW50ZXIueCArIGZXaWR0aCowLjA4ZiAtIGZXaWR0aCowLjFmLCBmV2lkdGgqMC4xZi9rICsgaypmV2lkdGgqMC4wOGYgKyBDaWNsZUNlbnRlci55KSwgUFdMUFRfQkVaSUVSVE8pLAorIAkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KENpY2xlQ2VudGVyLnggKyBmV2lkdGgqMC4wOGYsIGsqZldpZHRoKjAuMDhmICsgQ2ljbGVDZW50ZXIueSksIFBXTFBUX0JFWklFUlRPKQorCX07CisKKwlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkKKwkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMjgpOworCWVsc2UKKwkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAyOCk7Cit9CisKK3ZvaWQgQ1BXTF9VdGlsczo6R2V0R3JhcGhpY3NfTmV3UGFyYWdyYXBoKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkKK3sKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisKKwlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gCisJeworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMjAuMGYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTAuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzIuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzEwLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzIwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMTJmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjEyZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTAuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yMmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjJmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiAtIGZXaWR0aCowLjE0ZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjM4ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTAuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40OGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNDhmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjM4ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMTcvMzAuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4zOGYsIGNyQkJveC5ib3R0b20gKyBmV2lkdGgqMC4yNGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMTJmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjZmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xMC4wZiksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjdmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xMC4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjdmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xMC4wZiArIGZIZWlnaHQvNy4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjk3ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTAuMGYgKyBmSGVpZ2h0LzcuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjk3ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMTcvMzAuMGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjdmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjE3LzMwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzEwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuN2YsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzcgKyBmSGVpZ2h0KjAuMThmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuODVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC83ICsgZkhlaWdodCowLjE4ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuODVmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiAtIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjdmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxNy8zMC4wZiAtIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjdmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC83ICsgZkhlaWdodCowLjE4ZiksIFBXTFBUX0xJTkVUTykKKwl9OworCisJaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pCisJCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDI4KTsKKwllbHNlCisJCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMjgpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1RleHROb3RlKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkKK3sKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisKKwlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gCisJeworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjMvMTAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjcvMTAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzEwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCo0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xMC4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTAuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzEwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMy8xMC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzEwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCo0LzE1LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCozLzEwLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMy8xMC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTAuMGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqNC8xNS4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC81LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodCo3LzE1LjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC81LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodCo3LzE1LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzUuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjEwLzE1LjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCozLzEwLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodCoxMC8xNS4wZiksIFBXTFBUX0xJTkVUTykKKwl9OworCisJaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pCisJCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDE3KTsKKwllbHNlCisJCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMTcpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1BhcmFncmFwaChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpCit7CisJRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7CisJRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOworCisJQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9CisJeworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42MzRmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC8xNS4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjYzNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjIvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41NjZmLCBjckJCb3gudG9wIC0gZkhlaWdodCoyLzE1LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNTY2ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYgLSBmSGVpZ2h0KjAuNGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMTUuMGYgLSBmSGVpZ2h0KjAuNGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjJmLCBjckJCb3gudG9wIC0gZkhlaWdodC8xNS4wZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfQkVaSUVSVE8pCisJfTsKKworCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQorCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAxMik7CisJZWxzZQorCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDEyKTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19SaWdodEFycm93KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkKK3sKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisKKwlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gCisJeworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYgKyBmV2lkdGgvOC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvNS4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yLjBmLCBjckJCb3guYm90dG9tICsgZkhlaWdodC81LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiAtIGZXaWR0aCowLjE1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMi4wZiAtIGZXaWR0aC8yNS4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjFmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmIC0gZldpZHRoLzI1LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzIuMGYgKyBmV2lkdGgvMjUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1LjBmIC0gZldpZHRoKjAuMTVmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmICsgZldpZHRoLzI1LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMi4wZiArIGZXaWR0aC84LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC81LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNS4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMi4wZiksIFBXTFBUX0xJTkVUTykKKwl9OworCisJaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pCisJCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDEwKTsKKwllbHNlCisJCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMTApOworfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1JpZ2h0UG9pbnRlcihDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpCit7CisJRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7CisJRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOworCisJQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IAorCXsKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8zMC4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMi4wZiksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8zMC4wZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvNi4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCo0LzE1LjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC8yLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzMwLjBmLCBjckJCb3gudG9wIC0gZkhlaWdodC82LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8zMC4wZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQvMi4wZiksIFBXTFBUX0xJTkVUTykKKwl9OworCisJaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pCisJCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDUpOworCWVsc2UKKwkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCA1KTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19TdGFyKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkKK3sKKwlGWF9GTE9BVCBmTG9uZ1JhZGl1cyA9IChjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbSkvKDErKEZYX0ZMT0FUKWNvcyhQV0xfUEkvNS4wZikpOworCWZMb25nUmFkaXVzID0gZkxvbmdSYWRpdXMgKiAwLjdmOworCUZYX0ZMT0FUIGZTaG9ydFJhZGl1cyA9IGZMb25nUmFkaXVzICogMC41NWY7CisJQ1BERl9Qb2ludCBwdENlbnRlciA9IENQREZfUG9pbnQoKGNyQkJveC5sZWZ0ICsgY3JCQm94LnJpZ2h0KSAvIDIuMGYsKGNyQkJveC50b3AgKyBjckJCb3guYm90dG9tKSAvIDIuMGYpOworCQorCUZYX0ZMT0FUIHB4MVs1XSwgcHkxWzVdOworCUZYX0ZMT0FUIHB4Mls1XSwgcHkyWzVdOworCisJRlhfRkxPQVQgZkFuZ2VsID0gUFdMX1BJLzEwLjBmOworCisJZm9yIChGWF9JTlQzMiBpPTA7IGk8NTsgaSsrKQorCXsKKwkJcHgxW2ldID0gcHRDZW50ZXIueCArIGZMb25nUmFkaXVzICogKEZYX0ZMT0FUKWNvcyhmQW5nZWwpOworCQlweTFbaV0gPSBwdENlbnRlci55ICsgZkxvbmdSYWRpdXMgKiAoRlhfRkxPQVQpc2luKGZBbmdlbCk7CisKKwkJZkFuZ2VsICs9IFBXTF9QSSAqIDIgLyA1LjBmOworCX0KKworCWZBbmdlbCA9IFBXTF9QSS81LjBmICsgUFdMX1BJLzEwLjBmOworCisJZm9yIChGWF9JTlQzMiBqPTA7IGo8NTsgaisrKQorCXsKKwkJcHgyW2pdID0gcHRDZW50ZXIueCArIGZTaG9ydFJhZGl1cyAqIChGWF9GTE9BVCljb3MoZkFuZ2VsKTsKKwkJcHkyW2pdID0gcHRDZW50ZXIueSArIGZTaG9ydFJhZGl1cyAqIChGWF9GTE9BVClzaW4oZkFuZ2VsKTsKKworCQlmQW5nZWwgKz0gUFdMX1BJICogMiAvIDUuMGY7CisJfQorCisJQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbMTFdOworCVBhdGhBcnJheVswXSA9IENQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChweDFbMF0sIHB5MVswXSksIFBXTFBUX01PVkVUTyk7CisJUGF0aEFycmF5WzFdID0gQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHB4MlswXSwgcHkyWzBdKSwgUFdMUFRfTElORVRPKTsKKworCWZvcihGWF9JTlQzMiBrID0gMDsgayA8IDQ7IGsrKykKKwl7CisJCVBhdGhBcnJheVsoaysxKSoyXSA9IENQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChweDFbaysxXSwgcHkxW2srMV0pLCBQV0xQVF9MSU5FVE8pOworCQlQYXRoQXJyYXlbKGsrMSkqMiArIDFdID0gQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHB4MltrKzFdLCBweTJbaysxXSksIFBXTFBUX0xJTkVUTyk7CisJfQorCisJUGF0aEFycmF5WzEwXSA9IENQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChweDFbMF0sIHB5MVswXSksIFBXTFBUX0xJTkVUTyk7CisKKwlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkKKwkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMTEpOworCWVsc2UKKwkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAxMSk7Cit9CisKK3ZvaWQgQ1BXTF9VdGlsczo6R2V0R3JhcGhpY3NfVXBBcnJvdyhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpCit7CisJRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7CisJRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOworCisJQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IAorCXsKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xMC4wZiwgY3JCQm94LnRvcCAtIGZXaWR0aCozLzUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42ZiwgY3JCQm94LnRvcCAtIGZXaWR0aCozLzUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQvMTUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LnRvcCAtIGZXaWR0aCozLzUuMGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvMTAsIGNyQkJveC50b3AgLSBmV2lkdGgqMy81LjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIuMGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0LzE1LjBmKSwgUFdMUFRfTElORVRPKQorCX07CisKKwlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkKKwkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgOCk7CisJZWxzZQorCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDgpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1VwTGVmdEFycm93KENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkKK3sKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisJQ1BXTF9Qb2ludCBsZWZ0dXAoY3JCQm94LmxlZnQsIGNyQkJveC50b3ApOworCUNQV0xfUG9pbnQgcmlnaHRkb3duKGNyQkJveC5yaWdodCwgY3JCQm94LmJvdHRvbSk7CisJRlhfRkxPQVQgayA9IC1mSGVpZ2h0L2ZXaWR0aDsKKwlDUFdMX1BvaW50IHRhaWw7CisJdGFpbC54ID0gY3JCQm94LmxlZnQgKyBmV2lkdGgqNC81LjBmOworCXRhaWwueSA9IGsqKHRhaWwueCAtIGNyQkJveC5yaWdodCkgKyByaWdodGRvd24ueTsKKworCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSAKKwl7CisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC8yMC4wZiwgayooY3JCQm94LmxlZnQgKyBmV2lkdGgvMjAuMGYgLSByaWdodGRvd24ueCkgKyByaWdodGRvd24ueSksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChmSGVpZ2h0KjE3LzYwLjBmL2sgKyB0YWlsLnggKyBmV2lkdGgvMTAuMGYgKyBmV2lkdGgvNS4wZiwKKwkJICAgICAgICAgICAgICAtZldpZHRoLzUuMGYvayArIHRhaWwueSAtIGZXaWR0aC8xMC4wZi9rICsgZkhlaWdodCoxNy82MC4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChmSGVpZ2h0KjE3LzYwLjBmL2sgKyB0YWlsLnggKyBmV2lkdGgvMTAuMGYsCisJCSAgICAgICAgICAgICAgdGFpbC55IC0gZldpZHRoLzEwLjBmL2sgKyBmSGVpZ2h0KjE3LzYwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KHRhaWwueCArIGZXaWR0aC8xMC4wZiwgdGFpbC55IC0gZldpZHRoLzEwLjBmL2spLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQodGFpbC54IC0gZldpZHRoLzEwLjBmLCB0YWlsLnkgKyBmV2lkdGgvMTAuMGYvayksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChmSGVpZ2h0KjE3LzYwLjBmL2sgKyB0YWlsLnggLSBmV2lkdGgvMTAuMGYsIHRhaWwueSArIGZXaWR0aC8xMC4wZi9rICsgZkhlaWdodCoxNy82MC4wZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChmSGVpZ2h0KjE3LzYwLjBmL2sgKyB0YWlsLnggLSBmV2lkdGgvMTAuMGYgLSBmV2lkdGgvNS4wZiwKKwkJICAgICAgICAgICAgICBmV2lkdGgvNS4wZi9rICsgdGFpbC55ICsgZldpZHRoLzEwLjBmL2sgKyBmSGVpZ2h0KjE3LzYwLjBmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzIwLjBmLCBrKihjckJCb3gubGVmdCArIGZXaWR0aC8yMC4wZiAtIHJpZ2h0ZG93bi54KSArIHJpZ2h0ZG93bi55KSwgUFdMUFRfTElORVRPKQorCX07CisKKwlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkKKwkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgOCk7CisJZWxzZQorCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDgpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0dyYXBoKENGWF9CeXRlU3RyaW5nJiBzUGF0aERhdGEsIENGWF9QYXRoRGF0YSYgcGF0aCwgY29uc3QgQ1BERl9SZWN0JiBjckJCb3gsIGNvbnN0IFBXTF9QQVRIX1RZUEUgdHlwZSkKK3sKKwlGWF9GTE9BVCBmV2lkdGggPSBjckJCb3gucmlnaHQgLSBjckJCb3gubGVmdDsKKwlGWF9GTE9BVCBmSGVpZ2h0ID0gY3JCQm94LnRvcCAtIGNyQkJveC5ib3R0b207CisKKwlDUFdMX1BhdGhEYXRhIFBhdGhBcnJheVtdID0gCisJeworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4wNWYsIGNyQkJveC50b3AgLSBmV2lkdGgqMC4xNWYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yNWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMTVmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjc1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4wNWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMDhmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMDVmLCBjckJCb3gudG9wIC0gZldpZHRoKjAuMTVmKSwgUFdMUFRfTElORVRPKSwKKworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yNzVmLCBjckJCb3gudG9wIC0gZldpZHRoKjAuNDVmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNDc1ZiwgY3JCQm94LnRvcCAtIGZXaWR0aCowLjQ1ZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjQ3NWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMDhmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjc1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yNzVmLCBjckJCb3gudG9wIC0gZldpZHRoKjAuNDVmKSwgUFdMUFRfTElORVRPKSwKKworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4wNWYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4wNWYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4wNWYpLCBQV0xQVF9MSU5FVE8pLAorCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjcyNWYsIGNyQkJveC50b3AgLSBmV2lkdGgqMC4zNWYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC45MjVmLCBjckJCb3gudG9wIC0gZldpZHRoKjAuMzVmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuOTI1ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4wOGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC43MjVmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjA4ZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjcyNWYsIGNyQkJveC50b3AgLSBmV2lkdGgqMC4zNWYpLCBQV0xQVF9MSU5FVE8pCisJfTsKKworCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQorCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAyMCk7CisJZWxzZQorCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDIwKTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19QYXBlcmNsaXAoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQoreworCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0OworCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsKKworCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSAKKwl7CisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC82MCwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yNWYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNjAsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjI1ZiAtIGZXaWR0aCo1Ny82MC4wZiowLjM1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8zMCwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4yNWYgLSBmV2lkdGgqNTcvNjAuMGYqMC4zNWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMzAsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMzAsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzNmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8zMCwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zM2YgKyBmSGVpZ2h0LzE1KjAuNWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMzAgLSBmV2lkdGgqMC4xMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzNmICsgZkhlaWdodC8xNSowLjVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzMwIC0gZldpZHRoKjAuMTJmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjMzZiksIFBXTFBUX0JFWklFUlRPKSwKKwkKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8zMCAtIGZXaWR0aCowLjEyZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4yZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMzAgLSBmV2lkdGgqMC4xMmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMmYgLSAoZldpZHRoKjU3LzYwLjBmIC0gZldpZHRoKjAuMjRmKSowLjI1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwICsgZldpZHRoKjAuMTJmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjJmIC0gKGZXaWR0aCo1Ny82MC4wZiAtIGZXaWR0aCowLjI0ZikqMC4yNWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aC82MCArIGZXaWR0aCowLjEyZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4yZiksIFBXTFBUX0JFWklFUlRPKSwKKworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNjAgKyBmV2lkdGgqMC4xMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMmYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNjAgKyBmV2lkdGgqMC4xMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMmYgKyAoZldpZHRoKjExLzEyLjBmIC0gZldpZHRoKjAuMzZmKSowLjI1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNSAtIGZXaWR0aCowLjI0ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yZiArIChmV2lkdGgqMTEvMTIuMGYgLSBmV2lkdGgqMC4zNmYpKjAuMjVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1IC0gZldpZHRoKjAuMjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjJmKSwgUFdMUFRfQkVaSUVSVE8pLAorCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUgLSBmV2lkdGgqMC4yNGYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNSAtIGZXaWR0aCowLjI0ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4yNWYgLSAoZldpZHRoKjE0LzE1LjBmIC0gZldpZHRoKjAuNTNmKSowLjI1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjlmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjI1ZiAtIChmV2lkdGgqMTQvMTUuMGYgLSBmV2lkdGgqMC41M2YpKjAuMjVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yOWYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuMjVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjI5ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zM2YpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4yOWYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzNmICsgZldpZHRoKjAuMTJmKjAuMzVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4xN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzNmICsgZldpZHRoKjAuMTJmKjAuMzVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4xN2YsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMzNmKSwgUFdMUFRfQkVaSUVSVE8pLAorCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjE3ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4zZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjE3ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4zZiAtIGZXaWR0aCooMTQvMTUuMGYgLSAwLjI5ZikqMC4zNWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUgLSBmV2lkdGgqMC4xMmYsIGNyQkJveC5ib3R0b20gKyBmSGVpZ2h0KjAuM2YgLSBmV2lkdGgqKDE0LzE1LjBmIC0gMC4yOWYpKjAuMzVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoLzE1IC0gZldpZHRoKjAuMTJmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjNmKSwgUFdMUFRfQkVaSUVSVE8pLAorCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgvMTUgLSBmV2lkdGgqMC4xMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMjVmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aC8xNSAtIGZXaWR0aCowLjEyZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yNWYgKyBmV2lkdGgqMC4zNWYqKDExLzEyLjBmIC0gMC4xMmYpKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgvNjAsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMjVmICsgZldpZHRoKjAuMzVmKigxMS8xMi4wZiAtIDAuMTJmKSksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoLzYwLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjI1ZiksIFBXTFBUX0JFWklFUlRPKQorCX07CisKKwlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkKKwkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMzMpOworCWVsc2UKKwkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAzMyk7CQorfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX0F0dGFjaG1lbnQoQ0ZYX0J5dGVTdHJpbmcmIHNQYXRoRGF0YSwgQ0ZYX1BhdGhEYXRhJiBwYXRoLCBjb25zdCBDUERGX1JlY3QmIGNyQkJveCwgY29uc3QgUFdMX1BBVEhfVFlQRSB0eXBlKQoreworCUZYX0ZMT0FUIGZXaWR0aCA9IGNyQkJveC5yaWdodCAtIGNyQkJveC5sZWZ0OworCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckJCb3gudG9wIC0gY3JCQm94LmJvdHRvbTsKKworCUNQV0xfUGF0aERhdGEgUGF0aEFycmF5W10gPSAKKwl7CisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjI1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4xZiksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjIzZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYgKyBmV2lkdGgqMC4wNGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjZmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmICsgZldpZHRoKjAuMDRmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41ZiksIFBXTFBUX0JFWklFUlRPKSwKKworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC42ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4yM2YpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMjVmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjFmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuMjVmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjFmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMjNmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMjNmKSwgUFdMUFRfTElORVRPKSwKKworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41ZiksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmIC0gZldpZHRoKjAuMjVmKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjE1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC42NWYgKyBmSGVpZ2h0KjAuMTVmKjAuNGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjE1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC42NWYpLCBQV0xQVF9CRVpJRVJUTyksCisKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjE1ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC42NWYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMTVmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjY1ZiArIGZIZWlnaHQqMC4xNWYqMC40ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYgKyBmV2lkdGgqMC4yNWYqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYpLCBQV0xQVF9CRVpJRVJUTyksCisKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuNWYgKyBmV2lkdGgqMC4wNGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmICsgZldpZHRoKjAuMDRmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41ZiksIFBXTFBUX0JFWklFUlRPKSwKKworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC42NWYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC41ZiwgY3JCQm94LmJvdHRvbSArIGZIZWlnaHQqMC4xZiksIFBXTFBUX0xJTkVUTykKKwl9OworCisJaWYodHlwZSA9PSBQV0xQVF9TVFJFQU0pCisJCXNQYXRoRGF0YSA9IEdldEFwcFN0cmVhbUZyb21BcnJheShQYXRoQXJyYXksIDI0KTsKKwllbHNlCisJCUdldFBhdGhEYXRhRnJvbUFycmF5KHBhdGgsIFBhdGhBcnJheSwgMjQpOworfQorCit2b2lkIENQV0xfVXRpbHM6OkdldEdyYXBoaWNzX1RhZyhDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpCit7CisJRlhfRkxPQVQgZldpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7CisJRlhfRkxPQVQgZkhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOworCisJQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IAorCXsKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMWYpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC4xZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC41ZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjNmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjFmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjFmLCBjckJCb3guYm90dG9tICsgZkhlaWdodCowLjFmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjFmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjFmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuMWYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQgKyBmV2lkdGgqMC40ZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zZiksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQgLSBmV2lkdGgqMC4yZiwgY3JCQm94LnRvcCAtIGZIZWlnaHQqMC4zZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCArIGZXaWR0aCowLjRmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCAtIGZXaWR0aCowLjJmLCBjckJCb3gudG9wIC0gZkhlaWdodCowLjVmKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0ICsgZldpZHRoKjAuNGYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuN2YpLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0IC0gZldpZHRoKjAuMmYsIGNyQkJveC50b3AgLSBmSGVpZ2h0KjAuN2YpLCBQV0xQVF9MSU5FVE8pCisJfTsKKworCWlmKHR5cGUgPT0gUFdMUFRfU1RSRUFNKQorCQlzUGF0aERhdGEgPSBHZXRBcHBTdHJlYW1Gcm9tQXJyYXkoUGF0aEFycmF5LCAxMik7CisJZWxzZQorCQlHZXRQYXRoRGF0YUZyb21BcnJheShwYXRoLCBQYXRoQXJyYXksIDEyKTsKK30KKwordm9pZCBDUFdMX1V0aWxzOjpHZXRHcmFwaGljc19Gb3hpdChDRlhfQnl0ZVN0cmluZyYgc1BhdGhEYXRhLCBDRlhfUGF0aERhdGEmIHBhdGgsIGNvbnN0IENQREZfUmVjdCYgY3JCQm94LCBjb25zdCBQV0xfUEFUSF9UWVBFIHR5cGUpCit7CisJRlhfRkxPQVQgZk91dFdpZHRoID0gY3JCQm94LnJpZ2h0IC0gY3JCQm94LmxlZnQ7CisJRlhfRkxPQVQgZk91dEhlaWdodCA9IGNyQkJveC50b3AgLSBjckJCb3guYm90dG9tOworCisJQ1BERl9SZWN0IGNySW5Cb3ggPSBjckJCb3g7CisJY3JJbkJveC5sZWZ0ID0gY3JCQm94LmxlZnQgKyBmT3V0V2lkdGgqMC4wOGY7CisJY3JJbkJveC5yaWdodCA9IGNyQkJveC5yaWdodCAtIGZPdXRXaWR0aCowLjA4ZjsKKwljckluQm94LnRvcCA9IGNyQkJveC50b3AgLSBmT3V0SGVpZ2h0KjAuMDhmOworCWNySW5Cb3guYm90dG9tID0gY3JCQm94LmJvdHRvbSArIGZPdXRIZWlnaHQqMC4wOGY7CisKKwlGWF9GTE9BVCBmV2lkdGggPSBjckluQm94LnJpZ2h0IC0gY3JJbkJveC5sZWZ0OworCUZYX0ZMT0FUIGZIZWlnaHQgPSBjckluQm94LnRvcCAtIGNySW5Cb3guYm90dG9tOworCisJQ1BXTF9QYXRoRGF0YSBQYXRoQXJyYXlbXSA9IAorCXsKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCwgY3JJbkJveC50b3ApLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0ICsgZldpZHRoKjAuNDVmLCBjckluQm94LnRvcCksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC40NWYsIGNySW5Cb3gudG9wIC0gUFdMX0JFWklFUiAqIGZIZWlnaHQgKiAwLjRmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0ICsgZldpZHRoKjAuNDVmICAtIFBXTF9CRVpJRVIgKiBmV2lkdGggKiAwLjQ1ZiwgY3JJbkJveC50b3AgLSBmSGVpZ2h0KjAuNGYpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQsIGNySW5Cb3gudG9wIC0gZkhlaWdodCowLjRmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0LCBjckluQm94LnRvcCksIFBXTFBUX0xJTkVUTyksCisKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCArIGZXaWR0aCowLjYwZiwgY3JJbkJveC50b3ApLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0ICsgZldpZHRoKjAuNzVmLCBjckluQm94LnRvcCksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC43NWYsIGNySW5Cb3gudG9wIC0gUFdMX0JFWklFUiAqIGZIZWlnaHQgKiAwLjdmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0ICsgZldpZHRoKjAuNzVmICAtIFBXTF9CRVpJRVIgKiBmV2lkdGggKiAwLjc1ZiwgY3JJbkJveC50b3AgLSBmSGVpZ2h0KjAuN2YpLCBQV0xQVF9CRVpJRVJUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQsIGNySW5Cb3gudG9wIC0gZkhlaWdodCowLjdmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0LCBjckluQm94LnRvcCAtIGZIZWlnaHQqMC41NWYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0ICsgUFdMX0JFWklFUiAqIGZXaWR0aCowLjYwZiwgY3JJbkJveC50b3AgLSBmSGVpZ2h0KjAuNTVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0ICsgZldpZHRoICogMC42MGYsIGNySW5Cb3gudG9wIC0gUFdMX0JFWklFUiAqIGZIZWlnaHQgKiAwLjU1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCArIGZXaWR0aCAqIDAuNjBmLCBjckluQm94LnRvcCksIFBXTFBUX0JFWklFUlRPKSwKKworCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0ICsgZldpZHRoKjAuOTBmLCBjckluQm94LnRvcCksIFBXTFBUX01PVkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC45MGYsIGNySW5Cb3gudG9wIC0gUFdMX0JFWklFUiAqIGZIZWlnaHQgKiAwLjg1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCArIGZXaWR0aCowLjkwZiAgLSBQV0xfQkVaSUVSICogZldpZHRoICogMC45MGYsIGNySW5Cb3gudG9wIC0gZkhlaWdodCowLjg1ZiksIFBXTFBUX0JFWklFUlRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNySW5Cb3gubGVmdCwgY3JJbkJveC50b3AgLSBmSGVpZ2h0KjAuODVmKSwgUFdMUFRfQkVaSUVSVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JJbkJveC5sZWZ0LCBjckluQm94LmJvdHRvbSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LnJpZ2h0LCBjckluQm94LmJvdHRvbSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LnJpZ2h0LCBjckluQm94LnRvcCksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckluQm94LmxlZnQgKyBmV2lkdGgqMC45MGYsIGNySW5Cb3gudG9wKSwgUFdMUFRfTElORVRPKSwKKworCQkvKgorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQsIGNyQkJveC50b3ApLCBQV0xQVF9NT1ZFVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LnJpZ2h0LCBjckJCb3gudG9wKSwgUFdMUFRfTElORVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodCwgY3JCQm94LmJvdHRvbSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCwgY3JCQm94LmJvdHRvbSksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gubGVmdCwgY3JCQm94LnRvcCksIFBXTFBUX0xJTkVUTyksCisKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5sZWZ0K2ZPdXRXaWR0aCowLjA0ZiwgY3JCQm94LnRvcC1mT3V0SGVpZ2h0KjAuMDRmKSwgUFdMUFRfTU9WRVRPKSwKKwkJQ1BXTF9QYXRoRGF0YShDUFdMX1BvaW50KGNyQkJveC5yaWdodC1mT3V0V2lkdGgqMC4wNGYsIGNyQkJveC50b3AtZk91dEhlaWdodCowLjA0ZiksIFBXTFBUX0xJTkVUTyksCisJCUNQV0xfUGF0aERhdGEoQ1BXTF9Qb2ludChjckJCb3gucmlnaHQtZk91dFdpZHRoKjAuMDRmLCBjckJCb3guYm90dG9tK2ZPdXRIZWlnaHQqMC4wNGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQrZk91dFdpZHRoKjAuMDRmLCBjckJCb3guYm90dG9tK2ZPdXRIZWlnaHQqMC4wNGYpLCBQV0xQVF9MSU5FVE8pLAorCQlDUFdMX1BhdGhEYXRhKENQV0xfUG9pbnQoY3JCQm94LmxlZnQrZk91dFdpZHRoKjAuMDRmLCBjckJCb3gudG9wLWZPdXRIZWlnaHQqMC4wNGYpLCBQV0xQVF9MSU5FVE8pLAorCQkqLworCX07CisKKwlpZih0eXBlID09IFBXTFBUX1NUUkVBTSkKKwkJc1BhdGhEYXRhID0gR2V0QXBwU3RyZWFtRnJvbUFycmF5KFBhdGhBcnJheSwgMjMpOworCWVsc2UKKwkJR2V0UGF0aERhdGFGcm9tQXJyYXkocGF0aCwgUGF0aEFycmF5LCAyMyk7Cit9CisKK3ZvaWQgQ1BXTF9Db2xvcjo6Q29udmVydENvbG9yVHlwZShGWF9JTlQzMiBuQ29sb3JUeXBlKQoreworCXN3aXRjaCAodGhpcy0+bkNvbG9yVHlwZSkKKwl7CisJY2FzZSBDT0xPUlRZUEVfVFJBTlNQQVJFTlQ6CisJCWJyZWFrOworCWNhc2UgQ09MT1JUWVBFX0dSQVk6CisJCXN3aXRjaCAobkNvbG9yVHlwZSkKKwkJeworCQljYXNlIENPTE9SVFlQRV9SR0I6CisJCQlDUFdMX1V0aWxzOjpDb252ZXJ0R1JBWTJSR0IodGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMiwgdGhpcy0+ZkNvbG9yMyk7CisJCQlicmVhazsKKwkJY2FzZSBDT0xPUlRZUEVfQ01ZSzoKKwkJCUNQV0xfVXRpbHM6OkNvbnZlcnRHUkFZMkNNWUsodGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMiwgdGhpcy0+ZkNvbG9yMywgdGhpcy0+ZkNvbG9yNCk7CisJCQlicmVhazsKKwkJfQorCQlicmVhazsKKwljYXNlIENPTE9SVFlQRV9SR0I6CisJCXN3aXRjaCAobkNvbG9yVHlwZSkKKwkJeworCQljYXNlIENPTE9SVFlQRV9HUkFZOgorCQkJQ1BXTF9VdGlsczo6Q29udmVydFJHQjJHUkFZKHRoaXMtPmZDb2xvcjEsIHRoaXMtPmZDb2xvcjIsIHRoaXMtPmZDb2xvcjMsIHRoaXMtPmZDb2xvcjEpOworCQkJYnJlYWs7CisJCWNhc2UgQ09MT1JUWVBFX0NNWUs6CisJCQlDUFdMX1V0aWxzOjpDb252ZXJ0UkdCMkNNWUsodGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMiwgdGhpcy0+ZkNvbG9yMywgdGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMiwgdGhpcy0+ZkNvbG9yMywgdGhpcy0+ZkNvbG9yNCk7CisJCQlicmVhazsKKwkJfQorCQlicmVhazsKKwljYXNlIENPTE9SVFlQRV9DTVlLOgorCQlzd2l0Y2ggKG5Db2xvclR5cGUpCisJCXsKKwkJY2FzZSBDT0xPUlRZUEVfR1JBWToKKwkJCUNQV0xfVXRpbHM6OkNvbnZlcnRDTVlLMkdSQVkodGhpcy0+ZkNvbG9yMSwgdGhpcy0+ZkNvbG9yMiwgdGhpcy0+ZkNvbG9yMywgdGhpcy0+ZkNvbG9yNCwgdGhpcy0+ZkNvbG9yMSk7CisJCQlicmVhazsKKwkJY2FzZSBDT0xPUlRZUEVfUkdCOgorCQkJQ1BXTF9VdGlsczo6Q29udmVydENNWUsyUkdCKHRoaXMtPmZDb2xvcjEsIHRoaXMtPmZDb2xvcjIsIHRoaXMtPmZDb2xvcjMsIHRoaXMtPmZDb2xvcjQsIHRoaXMtPmZDb2xvcjEsIHRoaXMtPmZDb2xvcjIsIHRoaXMtPmZDb2xvcjMpOworCQkJYnJlYWs7CisJCX0KKwkJYnJlYWs7CisJfQorCXRoaXMtPm5Db2xvclR5cGUgPSBuQ29sb3JUeXBlOworfQorCisKZGlmZiAtLWdpdCBhL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfV25kLmNwcCBiL2ZwZGZzZGsvc3JjL3BkZndpbmRvdy9QV0xfV25kLmNwcAppbmRleCAwMzVmZmJiLi45YmI3ODRjIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9wZGZ3aW5kb3cvUFdMX1duZC5jcHAKKysrIGIvZnBkZnNkay9zcmMvcGRmd2luZG93L1BXTF9XbmQuY3BwCkBAIC0xLDEzNDIgKzEsMTM0MiBAQAotLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQotLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQ0KLS8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuDQotIA0KLS8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tDQotDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiDQotI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIg0KLSNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiDQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9UaW1lciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLXN0YXRpYyBDRlhfTWFwUHRyVGVtcGxhdGU8RlhfSU5UMzIsIENQV0xfVGltZXIqPglnX1RpbWVNYXA7DQotDQotQ1BXTF9UaW1lcjo6Q1BXTF9UaW1lcihDUFdMX1RpbWVySGFuZGxlciogcEF0dGFjaGVkLCBJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIpIDogDQotCW1fcEF0dGFjaGVkKHBBdHRhY2hlZCksDQotCW1fblRpbWVySUQoMCksDQotCW1fcFN5c3RlbUhhbmRsZXIocFN5c3RlbUhhbmRsZXIpDQotew0KLQlBU1NFUlQobV9wQXR0YWNoZWQgIT0gTlVMTCk7DQotCUFTU0VSVChtX3BTeXN0ZW1IYW5kbGVyICE9IE5VTEwpOw0KLX0NCi0NCi1DUFdMX1RpbWVyOjp+Q1BXTF9UaW1lcigpDQotew0KLQlLaWxsUFdMVGltZXIoKTsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9UaW1lcjo6U2V0UFdMVGltZXIoRlhfSU5UMzIgbkVsYXBzZSkNCi17CQ0KLQlpZiAobV9uVGltZXJJRCAhPSAwKSBLaWxsUFdMVGltZXIoKTsNCi0JbV9uVGltZXJJRCA9IG1fcFN5c3RlbUhhbmRsZXItPlNldFRpbWVyKG5FbGFwc2UsIFRpbWVyUHJvYyk7DQotCWdfVGltZU1hcC5TZXRBdChtX25UaW1lcklELCB0aGlzKTsNCi0JcmV0dXJuIG1fblRpbWVySUQ7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9UaW1lcjo6S2lsbFBXTFRpbWVyKCkNCi17DQotCWlmIChtX25UaW1lcklEICE9IDApDQotCXsNCi0JCW1fcFN5c3RlbUhhbmRsZXItPktpbGxUaW1lcihtX25UaW1lcklEKTsNCi0JCWdfVGltZU1hcC5SZW1vdmVLZXkobV9uVGltZXJJRCk7DQotCQltX25UaW1lcklEID0gMDsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfVGltZXI6OlRpbWVyUHJvYyhGWF9JTlQzMiBpZEV2ZW50KQ0KLXsNCi0JQ1BXTF9UaW1lciogcFRpbWVyID0gTlVMTDsNCi0JaWYgKGdfVGltZU1hcC5Mb29rdXAoaWRFdmVudCwgcFRpbWVyKSkNCi0Jew0KLQkJaWYgKHBUaW1lcikNCi0JCXsJCQkNCi0JCQlpZiAocFRpbWVyLT5tX3BBdHRhY2hlZCkgDQotCQkJCXBUaW1lci0+bV9wQXR0YWNoZWQtPlRpbWVyUHJvYygpOw0KLQkJfQ0KLQl9DQotfQ0KLQ0KLS8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfVGltZXJIYW5kbGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQotDQotQ1BXTF9UaW1lckhhbmRsZXI6OkNQV0xfVGltZXJIYW5kbGVyKCkgOiBtX3BUaW1lcihOVUxMKQ0KLXsNCi19DQotDQotQ1BXTF9UaW1lckhhbmRsZXI6On5DUFdMX1RpbWVySGFuZGxlcigpDQotew0KLQlpZiAobV9wVGltZXIpIGRlbGV0ZSBtX3BUaW1lcjsNCi19DQotDQotdm9pZCBDUFdMX1RpbWVySGFuZGxlcjo6QmVnaW5UaW1lcihGWF9JTlQzMiBuRWxhcHNlKQ0KLXsNCi0JaWYgKCFtX3BUaW1lcikNCi0JCW1fcFRpbWVyID0gbmV3IENQV0xfVGltZXIodGhpcywgR2V0U3lzdGVtSGFuZGxlcigpKTsNCi0NCi0JaWYgKG1fcFRpbWVyKQ0KLQkJbV9wVGltZXItPlNldFBXTFRpbWVyKG5FbGFwc2UpOw0KLX0NCi0NCi12b2lkIENQV0xfVGltZXJIYW5kbGVyOjpFbmRUaW1lcigpDQotew0KLQlpZiAobV9wVGltZXIpDQotCQltX3BUaW1lci0+S2lsbFBXTFRpbWVyKCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9UaW1lckhhbmRsZXI6OlRpbWVyUHJvYygpDQotew0KLX0NCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Nc2dDb250cm9sIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1jbGFzcyBDUFdMX01zZ0NvbnRyb2wNCi17DQotCWZyaWVuZCBjbGFzcyBDUFdMX1duZDsNCi0NCi1wdWJsaWM6DQotCUNQV0xfTXNnQ29udHJvbChDUFdMX1duZCAqIHBXbmQpDQotCXsNCi0vLwkJUFdMX1RSQUNFKCJuZXcgQ1BXTF9Nc2dDb250cm9sXG4iKTsNCi0JCW1fcENyZWF0ZWRXbmQgPSBwV25kOw0KLQkJRGVmYXVsdCgpOw0KLQl9DQotDQotCX5DUFdMX01zZ0NvbnRyb2woKQ0KLQl7DQotLy8JCVBXTF9UUkFDRSgifkNQV0xfTXNnQ29udHJvbFxuIik7DQotCQlEZWZhdWx0KCk7DQotCX0NCi0NCi0Jdm9pZCBEZWZhdWx0KCkNCi0Jew0KLQkJbV9hTW91c2VQYXRoLlJlbW92ZUFsbCgpOw0KLQkJbV9hS2V5Ym9hcmRQYXRoLlJlbW92ZUFsbCgpOw0KLQkJbV9wTWFpbk1vdXNlV25kID0gTlVMTDsNCi0JCW1fcE1haW5LZXlib2FyZFduZCA9IE5VTEw7DQotCX0NCi0NCi0JRlhfQk9PTCBJc1duZENyZWF0ZWQoY29uc3QgQ1BXTF9XbmQgKiBwV25kKSBjb25zdA0KLQl7DQotCQlyZXR1cm4gbV9wQ3JlYXRlZFduZCA9PSBwV25kOw0KLQl9DQotDQotCUZYX0JPT0wgSXNNYWluQ2FwdHVyZU1vdXNlKGNvbnN0IENQV0xfV25kICogcFduZCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIHBXbmQgPT0gbV9wTWFpbk1vdXNlV25kOw0KLQl9DQotDQotCUZYX0JPT0wgSXNXbmRDYXB0dXJlTW91c2UoY29uc3QgQ1BXTF9XbmQgKiBwV25kKSBjb25zdA0KLQl7DQotCQlpZiAocFduZCkNCi0JCQlmb3IoIEZYX0lOVDMyIGk9MCxzej1tX2FNb3VzZVBhdGguR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQkJCWlmIChtX2FNb3VzZVBhdGguR2V0QXQoaSkgPT0gcFduZCkNCi0JCQkJCXJldHVybiBUUlVFOw0KLQ0KLQkJcmV0dXJuIEZBTFNFOw0KLQl9DQotDQotCUZYX0JPT0wgSXNNYWluQ2FwdHVyZUtleWJvYXJkKGNvbnN0IENQV0xfV25kICogcFduZCkgY29uc3QNCi0Jew0KLQkJcmV0dXJuIHBXbmQgPT0gbV9wTWFpbktleWJvYXJkV25kOw0KLQl9DQotDQotDQotCUZYX0JPT0wgSXNXbmRDYXB0dXJlS2V5Ym9hcmQoY29uc3QgQ1BXTF9XbmQgKiBwV25kKSBjb25zdA0KLQl7DQotCQlpZiAocFduZCkNCi0JCQlmb3IoIEZYX0lOVDMyIGk9MCxzej1tX2FLZXlib2FyZFBhdGguR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQkJCWlmIChtX2FLZXlib2FyZFBhdGguR2V0QXQoaSkgPT0gcFduZCkNCi0JCQkJCXJldHVybiBUUlVFOw0KLQkJDQotCQlyZXR1cm4gRkFMU0U7DQotCX0NCi0NCi0Jdm9pZCBTZXRGb2N1cyhDUFdMX1duZCAqIHBXbmQpDQotCXsNCi0JCW1fYUtleWJvYXJkUGF0aC5SZW1vdmVBbGwoKTsNCi0NCi0JCWlmIChwV25kKQ0KLQkJew0KLQkJCW1fcE1haW5LZXlib2FyZFduZCA9IHBXbmQ7DQotDQotCQkJQ1BXTF9XbmQgKiBwUGFyZW50ID0gcFduZDsNCi0JCQl3aGlsZSAocFBhcmVudCkNCi0JCQl7DQotCQkJCW1fYUtleWJvYXJkUGF0aC5BZGQocFBhcmVudCk7DQotCQkJCXBQYXJlbnQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKTsNCi0JCQl9DQotDQotCQkJcFduZC0+T25TZXRGb2N1cygpOw0KLQkJfQ0KLQl9DQotDQotCXZvaWQgS2lsbEZvY3VzKCkNCi0Jew0KLQkJaWYgKG1fYUtleWJvYXJkUGF0aC5HZXRTaXplKCkgPiAwKQ0KLQkJCWlmIChDUFdMX1duZCogcFduZCA9IG1fYUtleWJvYXJkUGF0aC5HZXRBdCgwKSkNCi0JCQkJcFduZC0+T25LaWxsRm9jdXMoKTsNCi0NCi0JCW1fcE1haW5LZXlib2FyZFduZCA9IE5VTEw7DQotCQltX2FLZXlib2FyZFBhdGguUmVtb3ZlQWxsKCk7DQotCX0NCi0NCi0Jdm9pZCBTZXRDYXB0dXJlKENQV0xfV25kICogcFduZCkNCi0Jew0KLQkJbV9hTW91c2VQYXRoLlJlbW92ZUFsbCgpOw0KLQ0KLQkJaWYgKHBXbmQpDQotCQl7DQotCQkJbV9wTWFpbk1vdXNlV25kID0gcFduZDsNCi0NCi0JCQlDUFdMX1duZCAqIHBQYXJlbnQgPSBwV25kOw0KLQkJCXdoaWxlIChwUGFyZW50KQ0KLQkJCXsNCi0JCQkJbV9hTW91c2VQYXRoLkFkZChwUGFyZW50KTsNCi0JCQkJcFBhcmVudCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLQ0KLQl2b2lkIFJlbGVhc2VDYXB0dXJlKCkNCi0Jew0KLQkJbV9wTWFpbk1vdXNlV25kID0gTlVMTDsNCi0JCW1fYU1vdXNlUGF0aC5SZW1vdmVBbGwoKTsNCi0JfQ0KLQ0KLXByaXZhdGU6DQotCUNGWF9BcnJheVRlbXBsYXRlPENQV0xfV25kKj4JbV9hTW91c2VQYXRoOw0KLQlDRlhfQXJyYXlUZW1wbGF0ZTxDUFdMX1duZCo+CW1fYUtleWJvYXJkUGF0aDsNCi0JQ1BXTF9XbmQqCQkJCQkJbV9wQ3JlYXRlZFduZDsNCi0JQ1BXTF9XbmQqCQkJCQkJbV9wTWFpbk1vdXNlV25kOw0KLQlDUFdMX1duZCoJCQkJCQltX3BNYWluS2V5Ym9hcmRXbmQ7DQotfTsNCi0NCi0vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9XbmQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLQ0KLUNQV0xfV25kOjpDUFdMX1duZCgpIDoNCi0JbV9wVlNjcm9sbEJhcihOVUxMKSwNCi0JbV9yY1dpbmRvdygpLA0KLQltX3JjQ2xpcCgpLA0KLQltX2JDcmVhdGVkKEZBTFNFKSwJCQkNCi0JbV9iVmlzaWJsZShGQUxTRSksDQotCW1fYk5vdGlmeWluZyhGQUxTRSksDQotCW1fYkVuYWJsZWQoVFJVRSkNCi17DQotfQ0KLQ0KLUNQV0xfV25kOjp+Q1BXTF9XbmQoKQ0KLXsNCi0JQVNTRVJUKG1fYkNyZWF0ZWQgPT0gRkFMU0UpOw0KLX0NCi0NCi1DRlhfQnl0ZVN0cmluZyBDUFdMX1duZDo6R2V0Q2xhc3NOYW1lKCkgY29uc3QNCi17DQotCXJldHVybiAiQ1BXTF9XbmQiOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpDcmVhdGUoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLQlpZiAoIUlzVmFsaWQoKSkNCi0Jew0KLQkJbV9zUHJpdmF0ZVBhcmFtID0gY3A7DQotDQotCQlPbkNyZWF0ZShtX3NQcml2YXRlUGFyYW0pOw0KLQ0KLQkJbV9zUHJpdmF0ZVBhcmFtLnJjUmVjdFduZC5Ob3JtYWxpemUoKTsNCi0JCW1fcmNXaW5kb3cgPSBtX3NQcml2YXRlUGFyYW0ucmNSZWN0V25kOw0KLQkJbV9yY0NsaXAgPSBDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdChtX3JjV2luZG93LDEuMGYpOw0KLQ0KLQkJQ3JlYXRlTXNnQ29udHJvbCgpOw0KLQ0KLQkJaWYgKG1fc1ByaXZhdGVQYXJhbS5wUGFyZW50V25kKQ0KLQkJCW1fc1ByaXZhdGVQYXJhbS5wUGFyZW50V25kLT5Pbk5vdGlmeSh0aGlzLCBQTk1fQUREQ0hJTEQpOw0KLQ0KLQkJUFdMX0NSRUFURVBBUkFNIGNjcCA9IG1fc1ByaXZhdGVQYXJhbTsNCi0NCi0JCWNjcC5kd0ZsYWdzICY9IDB4RkZGRjAwMDBMOyAvL3JlbW92ZSBzdWIgc3R5bGVzDQotCQljY3AubXRDaGlsZCA9IENQREZfTWF0cml4KDEsMCwwLDEsMCwwKTsNCi0JCQ0KLQkJQ3JlYXRlU2Nyb2xsQmFyKGNjcCk7DQotCQlDcmVhdGVDaGlsZFduZChjY3ApOyANCi0NCi0JCW1fYlZpc2libGUgPSBIYXNGbGFnKFBXU19WSVNJQkxFKTsNCi0NCi0JCU9uQ3JlYXRlZCgpOw0KLQ0KLQkJUmVQb3NDaGlsZFduZCgpOw0KLQkJbV9iQ3JlYXRlZCA9IFRSVUU7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX1duZDo6T25DcmVhdGUoUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpPbkNyZWF0ZWQoKQ0KLXsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6T25EZXN0cm95KCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OkRlc3Ryb3koKQ0KLXsNCi0JS2lsbEZvY3VzKCk7DQotDQotCU9uRGVzdHJveSgpOw0KLQ0KLQlpZiAobV9iQ3JlYXRlZCkNCi0Jew0KLQkJZm9yIChGWF9JTlQzMiBpID0gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpLTE7IGkgPj0gMDsgaSAtLSkNCi0JCXsNCi0JCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbltpXSkNCi0JCQl7DQotCQkJCXBDaGlsZC0+RGVzdHJveSgpOw0KLQkJCQlkZWxldGUgcENoaWxkOw0KLQkJCQlwQ2hpbGQgPSBOVUxMOw0KLQkJCX0NCi0JCX0NCi0NCi0JCWlmIChtX3NQcml2YXRlUGFyYW0ucFBhcmVudFduZCkNCi0JCQltX3NQcml2YXRlUGFyYW0ucFBhcmVudFduZC0+T25Ob3RpZnkodGhpcywgUE5NX1JFTU9WRUNISUxEKTsNCi0JCW1fYkNyZWF0ZWQgPSBGQUxTRTsNCi0JfQ0KLQ0KLQlEZXN0cm95TXNnQ29udHJvbCgpOw0KLQ0KLQlGWFNZU19tZW1zZXQoJm1fc1ByaXZhdGVQYXJhbSwgMCwgc2l6ZW9mKFBXTF9DUkVBVEVQQVJBTSkpOw0KLQltX2FDaGlsZHJlbi5SZW1vdmVBbGwoKTsJDQotCW1fcFZTY3JvbGxCYXIgPSBOVUxMOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpNb3ZlKGNvbnN0IENQREZfUmVjdCAmIHJjTmV3LCBGWF9CT09MIGJSZXNldCxGWF9CT09MIGJSZWZyZXNoKQ0KLXsNCi0JaWYgKElzVmFsaWQoKSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjT2xkID0gdGhpcy0+R2V0V2luZG93UmVjdCgpOw0KLQ0KLQkJbV9yY1dpbmRvdyA9IHJjTmV3Ow0KLQkJbV9yY1dpbmRvdy5Ob3JtYWxpemUoKTsNCi0JCS8vbV9yY0NsaXAgPSBDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdChtX3JjV2luZG93LDEuMGYpOyAvL2ZvciBzcGVjaWFsIGNhcmV0IA0KLQ0KLQkJaWYgKHJjT2xkLmxlZnQgIT0gcmNOZXcubGVmdCB8fCByY09sZC5yaWdodCAhPSByY05ldy5yaWdodCB8fA0KLQkJCXJjT2xkLnRvcCAhPSByY05ldy50b3AgfHwgcmNPbGQuYm90dG9tICE9IHJjTmV3LmJvdHRvbSkNCi0JCXsNCi0JCQlpZiAoYlJlc2V0KQ0KLQkJCXsNCi0JCQkJUmVQb3NDaGlsZFduZCgpOwkNCi0JCQl9CQ0KLQ0KLQkJfQ0KLQkJaWYgKGJSZWZyZXNoKQ0KLQkJewkNCi0JCQlJbnZhbGlkYXRlUmVjdE1vdmUocmNPbGQscmNOZXcpOw0KLQkJfQ0KLQ0KLQkJbV9zUHJpdmF0ZVBhcmFtLnJjUmVjdFduZCA9IG1fcmNXaW5kb3c7DQotCX0NCi19DQotDQotdm9pZCAgQ1BXTF9XbmQ6OkludmFsaWRhdGVSZWN0TW92ZShjb25zdCBDUERGX1JlY3QgJiByY09sZCwgY29uc3QgQ1BERl9SZWN0ICYgcmNOZXcpDQotew0KLQlDUERGX1JlY3QgcmNVbmlvbiA9IHJjT2xkOw0KLQlyY1VuaW9uLlVuaW9uKHJjTmV3KTsNCi0NCi0JSW52YWxpZGF0ZVJlY3QoJnJjVW5pb24pOw0KLQ0KLQkvKg0KLQlDUERGX1JlY3QgU3ViQXJyYXlbNF07IA0KLQ0KLQlyY09sZC5TdWJzdHJhY3Q0KHJjTmV3LFN1YkFycmF5KTsNCi0JZm9yIChGWF9JTlQzMiBpPTA7aTw0O2krKykNCi0Jew0KLQkJaWYgKFN1YkFycmF5W2ldLmxlZnQgPT0gMCAmJg0KLQkJCVN1YkFycmF5W2ldLnJpZ2h0ID09IDAgJiYNCi0JCQlTdWJBcnJheVtpXS50b3AgPT0gMCAmJg0KLQkJCVN1YkFycmF5W2ldLmJvdHRvbSA9PSAwKWNvbnRpbnVlOw0KLQ0KLQkJSW52YWxpZGF0ZVJlY3QoJkNQV0xfVXRpbHM6OkluZmxhdGVSZWN0KFN1YkFycmF5W2ldLDIpKTsNCi0JfQ0KLQ0KLQlyY05ldy5TdWJzdHJhY3Q0KHJjT2xkLFN1YkFycmF5KTsNCi0JZm9yIChGWF9JTlQzMiBqPTA7ajw0O2orKykNCi0Jew0KLQkJaWYgKFN1YkFycmF5W2pdLmxlZnQgPT0gMCAmJg0KLQkJCVN1YkFycmF5W2pdLnJpZ2h0ID09IDAgJiYNCi0JCQlTdWJBcnJheVtqXS50b3AgPT0gMCAmJg0KLQkJCVN1YkFycmF5W2pdLmJvdHRvbSA9PSAwKWNvbnRpbnVlOw0KLQ0KLQkJSW52YWxpZGF0ZVJlY3QoJkNQV0xfVXRpbHM6OkluZmxhdGVSZWN0KFN1YkFycmF5W2pdLDIpKTsNCi0JfQ0KLQkqLw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpHZXRBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlU3RyaW5nICYgc0FwcFN0cmVhbSkNCi17DQotCWlmIChJc1ZhbGlkKCkpDQotCXsNCi0JCUNGWF9CeXRlVGV4dEJ1ZiBzVGV4dEJ1ZjsNCi0JCUdldEFwcGVhcmFuY2VTdHJlYW0oc1RleHRCdWYpOw0KLQkJc0FwcFN0cmVhbSArPSBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCk7DQotCX0NCi19DQotDQotdm9pZCBDUFdMX1duZDo6R2V0QXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKQ0KLXsNCi0JaWYgKElzVmFsaWQoKSAmJiBJc1Zpc2libGUoKSkNCi0Jew0KLQkJR2V0VGhpc0FwcGVhcmFuY2VTdHJlYW0oc0FwcFN0cmVhbSk7DQotCQlHZXRDaGlsZEFwcGVhcmFuY2VTdHJlYW0oc0FwcFN0cmVhbSk7DQotCX0NCi19DQotDQotLy9pZiBkb24ndCBzZXQsR2V0IGRlZmF1bHQgYXBwZXJhbmNlIHN0cmVhbQ0KLXZvaWQgQ1BXTF9XbmQ6OkdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pDQotew0KLQlDUERGX1JlY3QgcmVjdFduZCA9IEdldFdpbmRvd1JlY3QoKTsNCi0JaWYgKCFyZWN0V25kLklzRW1wdHkoKSkNCi0Jew0KLQkJQ0ZYX0J5dGVUZXh0QnVmIHNUaGlzOw0KLQ0KLQkJaWYgKEhhc0ZsYWcoUFdTX0JBQ0tHUk9VTkQpKQ0KLQkJCXNUaGlzIDw8IENQV0xfVXRpbHM6OkdldFJlY3RGaWxsQXBwU3RyZWFtKHJlY3RXbmQsdGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCkpOw0KLQ0KLQkJaWYgKEhhc0ZsYWcoUFdTX0JPUkRFUikpDQotCQkJc1RoaXMgPDwgQ1BXTF9VdGlsczo6R2V0Qm9yZGVyQXBwU3RyZWFtKHJlY3RXbmQsDQotCQkJCQkJCQkJKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCksDQotCQkJCQkJCQkJR2V0Qm9yZGVyQ29sb3IoKSwNCi0JCQkJCQkJCQl0aGlzLT5HZXRCb3JkZXJMZWZ0VG9wQ29sb3IodGhpcy0+R2V0Qm9yZGVyU3R5bGUoKSksDQotCQkJCQkJCQkJdGhpcy0+R2V0Qm9yZGVyUmlnaHRCb3R0b21Db2xvcih0aGlzLT5HZXRCb3JkZXJTdHlsZSgpKSwNCi0JCQkJCQkJCQl0aGlzLT5HZXRCb3JkZXJTdHlsZSgpLA0KLQkJCQkJCQkJCXRoaXMtPkdldEJvcmRlckRhc2goKSk7DQotDQotCQlzQXBwU3RyZWFtIDw8IHNUaGlzOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OkdldENoaWxkQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKQ0KLXsNCi0JZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCXsNCi0JCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQ0KLQkJew0KLQkJCXBDaGlsZC0+R2V0QXBwZWFyYW5jZVN0cmVhbShzQXBwU3RyZWFtKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpEcmF3QXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0KLXsNCi0JaWYgKElzVmFsaWQoKSAmJiBJc1Zpc2libGUoKSkNCi0Jew0KLQkJRHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UscFVzZXIyRGV2aWNlKTsNCi0JCURyYXdDaGlsZEFwcGVhcmFuY2UocERldmljZSxwVXNlcjJEZXZpY2UpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQ0KLXsNCi0JQ1BERl9SZWN0IHJlY3RXbmQgPSBHZXRXaW5kb3dSZWN0KCk7DQotCWlmICghcmVjdFduZC5Jc0VtcHR5KCkpDQotCXsJCQ0KLQkJaWYgKEhhc0ZsYWcoUFdTX0JBQ0tHUk9VTkQpKQ0KLQkJew0KLQkJCUNQREZfUmVjdCByY0NsaWVudCA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJlY3RXbmQsKEZYX0ZMT0FUKShHZXRCb3JkZXJXaWR0aCgpK0dldElubmVyQm9yZGVyV2lkdGgoKSkpOw0KLQkJCUNQV0xfVXRpbHM6OkRyYXdGaWxsUmVjdChwRGV2aWNlLHBVc2VyMkRldmljZSxyY0NsaWVudCx0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKSxHZXRUcmFuc3BhcmVuY3koKSk7DQotCQl9DQotDQotCQlpZiAoSGFzRmxhZyhQV1NfQk9SREVSKSkNCi0JCQlDUFdMX1V0aWxzOjpEcmF3Qm9yZGVyKHBEZXZpY2UsDQotCQkJCQkJCQlwVXNlcjJEZXZpY2UsDQotCQkJCQkJCQlyZWN0V25kLA0KLQkJCQkJCQkJKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCksDQotCQkJCQkJCQlHZXRCb3JkZXJDb2xvcigpLA0KLQkJCQkJCQkJdGhpcy0+R2V0Qm9yZGVyTGVmdFRvcENvbG9yKHRoaXMtPkdldEJvcmRlclN0eWxlKCkpLA0KLQkJCQkJCQkJdGhpcy0+R2V0Qm9yZGVyUmlnaHRCb3R0b21Db2xvcih0aGlzLT5HZXRCb3JkZXJTdHlsZSgpKSwNCi0JCQkJCQkJCXRoaXMtPkdldEJvcmRlclN0eWxlKCksDQotCQkJCQkJCQl0aGlzLT5HZXRCb3JkZXJEYXNoKCksDQotCQkJCQkJCQlHZXRUcmFuc3BhcmVuY3koKSk7CQkJCQkJCQkNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpEcmF3Q2hpbGRBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpDQotew0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJaWYgKENQV0xfV25kICogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQl7DQotCQkJQ1BERl9NYXRyaXggbXQgPSBwQ2hpbGQtPkdldENoaWxkTWF0cml4KCk7DQotCQkJaWYgKG10LklzSWRlbnRpdHkoKSkNCi0JCQl7DQotCQkJCXBDaGlsZC0+RHJhd0FwcGVhcmFuY2UocERldmljZSxwVXNlcjJEZXZpY2UpOw0KLQkJCX0NCi0JCQllbHNlDQotCQkJew0KLQkJCQltdC5Db25jYXQoKnBVc2VyMkRldmljZSk7DQotCQkJCXBDaGlsZC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwmbXQpOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpJbnZhbGlkYXRlUmVjdChDUERGX1JlY3QqIHBSZWN0KQ0KLXsNCi0JaWYgKElzVmFsaWQoKSkNCi0Jew0KLQkJQ1BERl9SZWN0IHJjUmVmcmVzaCA9IHBSZWN0ID8gKnBSZWN0IDogR2V0V2luZG93UmVjdCgpOw0KLQ0KLQkJaWYgKCFIYXNGbGFnKFBXU19OT1JFRlJFU0hDTElQKSkNCi0JCXsNCi0JCQlDUERGX1JlY3QgcmNDbGlwID0gR2V0Q2xpcFJlY3QoKTsJCQ0KLQkJCWlmICghcmNDbGlwLklzRW1wdHkoKSkNCi0JCQl7DQotCQkJCXJjUmVmcmVzaC5JbnRlcnNlY3QocmNDbGlwKTsNCi0JCQl9DQotCQl9DQotDQotCQlGWF9SRUNUIHJjV2luID0gUFdMdG9XbmQocmNSZWZyZXNoKTsNCi0JCXJjV2luLmxlZnQgLT0gUFdMX0lOVkFMSURBVEVfSU5GTEFURTsNCi0JCXJjV2luLnRvcCAtPSBQV0xfSU5WQUxJREFURV9JTkZMQVRFOw0KLQkJcmNXaW4ucmlnaHQgKz0gUFdMX0lOVkFMSURBVEVfSU5GTEFURTsNCi0JCXJjV2luLmJvdHRvbSArPSBQV0xfSU5WQUxJREFURV9JTkZMQVRFOw0KLQ0KLQkJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpDQotCQl7DQotCQkJaWYgKEZYX0hXTkQgaFduZCA9IEdldEF0dGFjaGVkSFduZCgpKQ0KLQkJCXsNCi0JCQkJcFNILT5JbnZhbGlkYXRlUmVjdChoV25kLCByY1dpbik7DQotCQkJfQ0KLQkJfQ0KLQl9DQotfQ0KLQ0KLSNkZWZpbmUgUFdMX0lNUExFTUVOVF9LRVlfTUVUSE9EKGtleV9tZXRob2RfbmFtZSlcDQotRlhfQk9PTCBDUFdMX1duZDo6a2V5X21ldGhvZF9uYW1lKEZYX1dPUkQgbkNoYXIsIEZYX0RXT1JEIG5GbGFnKVwNCi17XA0KLQlpZiAoSXNWYWxpZCgpICYmIElzVmlzaWJsZSgpICYmIElzRW5hYmxlZCgpKVwNCi0Je1wNCi0JCWlmIChJc1duZENhcHR1cmVLZXlib2FyZCh0aGlzKSlcDQotCQl7XA0KLQkJCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKVwNCi0JCQl7XA0KLQkJCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSlcDQotCQkJCXtcDQotCQkJCQlpZiAoSXNXbmRDYXB0dXJlS2V5Ym9hcmQocENoaWxkKSlcDQotCQkJCQl7XA0KLQkJCQkJCXJldHVybiBwQ2hpbGQtPmtleV9tZXRob2RfbmFtZShuQ2hhcixuRmxhZyk7XA0KLQkJCQkJfVwNCi0JCQkJfVwNCi0JCQl9XA0KLQkJfVwNCi0JfVwNCi0JcmV0dXJuIEZBTFNFO1wNCi19DQotDQotI2RlZmluZSBQV0xfSU1QTEVNRU5UX01PVVNFX01FVEhPRChtb3VzZV9tZXRob2RfbmFtZSlcDQotRlhfQk9PTCBDUFdMX1duZDo6bW91c2VfbWV0aG9kX25hbWUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZylcDQote1wNCi0JaWYgKElzVmFsaWQoKSAmJiBJc1Zpc2libGUoKSAmJiBJc0VuYWJsZWQoKSlcDQotCXtcDQotCQlpZiAoSXNXbmRDYXB0dXJlTW91c2UodGhpcykpXA0KLQkJe1wNCi0JCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKylcDQotCQkJe1wNCi0JCQkJaWYgKENQV0xfV25kICogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpXA0KLQkJCQl7XA0KLQkJCQkJaWYgKElzV25kQ2FwdHVyZU1vdXNlKHBDaGlsZCkpXA0KLQkJCQkJe1wNCi0JCQkJCQlyZXR1cm4gcENoaWxkLT5tb3VzZV9tZXRob2RfbmFtZShwQ2hpbGQtPlBhcmVudFRvQ2hpbGQocG9pbnQpLG5GbGFnKTtcDQotCQkJCQl9XA0KLQkJCQl9XA0KLQkJCX1cDQotCQkJU2V0Q3Vyc29yKCk7XA0KLQkJfVwNCi0JCWVsc2VcDQotCQl7XA0KLQkJCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKVwNCi0JCQl7XA0KLQkJCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSlcDQotCQkJCXtcDQotCQkJCQlpZiAocENoaWxkLT5XbmRIaXRUZXN0KHBDaGlsZC0+UGFyZW50VG9DaGlsZChwb2ludCkpKVwNCi0JCQkJCXtcDQotCQkJCQkJcmV0dXJuIHBDaGlsZC0+bW91c2VfbWV0aG9kX25hbWUocENoaWxkLT5QYXJlbnRUb0NoaWxkKHBvaW50KSxuRmxhZyk7XA0KLQkJCQkJfVwNCi0JCQkJfVwNCi0JCQl9XA0KLQkJCWlmICh0aGlzLT5XbmRIaXRUZXN0KHBvaW50KSlcDQotCQkJCVNldEN1cnNvcigpO1wNCi0JCX1cDQotCX1cDQotCXJldHVybiBGQUxTRTtcDQotfQ0KLQ0KLVBXTF9JTVBMRU1FTlRfS0VZX01FVEhPRChPbktleURvd24pDQotUFdMX0lNUExFTUVOVF9LRVlfTUVUSE9EKE9uS2V5VXApDQotUFdMX0lNUExFTUVOVF9LRVlfTUVUSE9EKE9uQ2hhcikNCi0NCi1QV0xfSU1QTEVNRU5UX01PVVNFX01FVEhPRChPbkxCdXR0b25EYmxDbGspDQotUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25MQnV0dG9uRG93bikNCi1QV0xfSU1QTEVNRU5UX01PVVNFX01FVEhPRChPbkxCdXR0b25VcCkNCi1QV0xfSU1QTEVNRU5UX01PVVNFX01FVEhPRChPbk1CdXR0b25EYmxDbGspDQotUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25NQnV0dG9uRG93bikNCi1QV0xfSU1QTEVNRU5UX01PVVNFX01FVEhPRChPbk1CdXR0b25VcCkNCi1QV0xfSU1QTEVNRU5UX01PVVNFX01FVEhPRChPblJCdXR0b25EYmxDbGspDQotUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25SQnV0dG9uRG93bikNCi1QV0xfSU1QTEVNRU5UX01PVVNFX01FVEhPRChPblJCdXR0b25VcCkNCi1QV0xfSU1QTEVNRU5UX01PVVNFX01FVEhPRChPbk1vdXNlTW92ZSkNCi0NCi1GWF9CT09MCUNQV0xfV25kOjpPbk1vdXNlV2hlZWwoc2hvcnQgekRlbHRhLCBjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKQ0KLXsNCi0JaWYgKElzVmFsaWQoKSAmJiBJc1Zpc2libGUoKSAmJiBJc0VuYWJsZWQoKSkNCi0Jew0KLQkJU2V0Q3Vyc29yKCk7DQotCQlpZiAoSXNXbmRDYXB0dXJlS2V5Ym9hcmQodGhpcykpDQotCQl7DQotCQkJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQkJew0KLQkJCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkNCi0JCQkJew0KLQkJCQkJaWYgKElzV25kQ2FwdHVyZUtleWJvYXJkKHBDaGlsZCkpDQotCQkJCQl7DQotCQkJCQkJcmV0dXJuIHBDaGlsZC0+T25Nb3VzZVdoZWVsKHpEZWx0YSxwQ2hpbGQtPlBhcmVudFRvQ2hpbGQocG9pbnQpLCBuRmxhZyk7DQotCQkJCQl9DQotCQkJCX0NCi0JCQl9DQotCQl9DQotCX0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpBZGRDaGlsZChDUFdMX1duZCAqIHBXbmQpDQotew0KLQltX2FDaGlsZHJlbi5BZGQocFduZCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OlJlbW92ZUNoaWxkKENQV0xfV25kICogcFduZCkNCi17DQotCWZvciAoRlhfSU5UMzIgaSA9IG1fYUNoaWxkcmVuLkdldFNpemUoKS0xOyBpID49IDA7IGkgLS0pDQotCXsNCi0JCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQl7DQotCQkJaWYgKHBDaGlsZCA9PSBwV25kKQ0KLQkJCXsNCi0JCQkJbV9hQ2hpbGRyZW4uUmVtb3ZlQXQoaSk7DQotCQkJCWJyZWFrOw0KLQkJCX0NCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQ0KLXsNCi0Jc3dpdGNoIChtc2cpDQotCXsNCi0JY2FzZSBQTk1fQUREQ0hJTEQ6DQotCQl0aGlzLT5BZGRDaGlsZChwV25kKTsNCi0JCWJyZWFrOw0KLQljYXNlIFBOTV9SRU1PVkVDSElMRDoNCi0JCXRoaXMtPlJlbW92ZUNoaWxkKHBXbmQpOw0KLQkJYnJlYWs7DQotCWRlZmF1bHQ6DQotCQlicmVhazsNCi0JfQ0KLX0NCi0NCi1GWF9CT09MIENQV0xfV25kOjpJc1ZhbGlkKCkgY29uc3QNCi17DQotCXJldHVybiBtX2JDcmVhdGVkOw0KLX0NCi0NCi1QV0xfQ1JFQVRFUEFSQU0gQ1BXTF9XbmQ6OkdldENyZWF0aW9uUGFyYW0oKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbTsNCi19DQotDQotQ1BXTF9XbmQqIENQV0xfV25kOjpHZXRQYXJlbnRXaW5kb3coKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5wUGFyZW50V25kOw0KLX0NCi0NCi1DUERGX1JlY3QgQ1BXTF9XbmQ6OkdldE9yaWdpbldpbmRvd1JlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5yY1JlY3RXbmQ7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX1duZDo6R2V0V2luZG93UmVjdCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9yY1dpbmRvdzsNCi19DQotDQotQ1BERl9SZWN0IENQV0xfV25kOjpHZXRDbGllbnRSZWN0KCkgY29uc3QNCi17DQotCUNQREZfUmVjdCByY1dpbmRvdyA9IEdldFdpbmRvd1JlY3QoKTsNCi0JQ1BERl9SZWN0IHJjQ2xpZW50ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmNXaW5kb3csKEZYX0ZMT0FUKShHZXRCb3JkZXJXaWR0aCgpK0dldElubmVyQm9yZGVyV2lkdGgoKSkpOw0KLQ0KLQlpZiAoQ1BXTF9TY3JvbGxCYXIgKiBwVlNCID0gdGhpcy0+R2V0VlNjcm9sbEJhcigpKQ0KLQkJcmNDbGllbnQucmlnaHQgLT0gcFZTQi0+R2V0U2Nyb2xsQmFyV2lkdGgoKTsNCi0NCi0JcmNDbGllbnQuTm9ybWFsaXplKCk7DQotDQotCWlmIChyY1dpbmRvdy5Db250YWlucyhyY0NsaWVudCkpDQotCQlyZXR1cm4gcmNDbGllbnQ7DQotCWVsc2UNCi0JCXJldHVybiBDUERGX1JlY3QoKTsNCi19DQotDQotQ1BERl9Qb2ludCBDUFdMX1duZDo6R2V0Q2VudGVyUG9pbnQoKSBjb25zdA0KLXsNCi0JQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOw0KLQ0KLQlyZXR1cm4gQ1BERl9Qb2ludCgocmNDbGllbnQubGVmdCArIHJjQ2xpZW50LnJpZ2h0KSAqIDAuNWYsDQotCQkocmNDbGllbnQudG9wICsgcmNDbGllbnQuYm90dG9tKSAqIDAuNWYpOw0KLX0NCi0NCi1DUERGX1JlY3QgQ1BXTF9XbmQ6OkdldENsaWVudENlbnRlclNxdWFyZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gQ1BXTF9VdGlsczo6R2V0Q2VudGVyU3F1YXJlKEdldENsaWVudFJlY3QoKSk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX1duZDo6R2V0V2luZG93Q2VudGVyU3F1YXJlKCkgY29uc3QNCi17DQotCXJldHVybiBDUFdMX1V0aWxzOjpHZXRDZW50ZXJTcXVhcmUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QoR2V0V2luZG93UmVjdCgpLDAuMWYpKTsNCi19DQotDQotRlhfQk9PTCBDUFdMX1duZDo6SGFzRmxhZyhGWF9EV09SRCBkd0ZsYWdzKSBjb25zdA0KLXsNCi0JcmV0dXJuIChtX3NQcml2YXRlUGFyYW0uZHdGbGFncyAmIGR3RmxhZ3MpICE9IDA7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OlJlbW92ZUZsYWcoRlhfRFdPUkQgZHdGbGFncykNCi17DQotCW1fc1ByaXZhdGVQYXJhbS5kd0ZsYWdzICY9IH5kd0ZsYWdzOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpBZGRGbGFnKEZYX0RXT1JEIGR3RmxhZ3MpDQotew0KLQltX3NQcml2YXRlUGFyYW0uZHdGbGFncyB8PSBkd0ZsYWdzOw0KLX0NCi0NCi1DUFdMX0NvbG9yIENQV0xfV25kOjpHZXRCYWNrZ3JvdW5kQ29sb3IoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5zQmFja2dyb3VuZENvbG9yOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpTZXRCYWNrZ3JvdW5kQ29sb3IoY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yKQ0KLXsNCi0JbV9zUHJpdmF0ZVBhcmFtLnNCYWNrZ3JvdW5kQ29sb3IgPSBjb2xvcjsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6U2V0VGV4dENvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcikNCi17DQotCW1fc1ByaXZhdGVQYXJhbS5zVGV4dENvbG9yID0gY29sb3I7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OlNldFRleHRTdHJva2VDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpDQotew0KLQltX3NQcml2YXRlUGFyYW0uc1RleHRTdHJva2VDb2xvciA9IGNvbG9yOw0KLX0NCi0NCi1DUFdMX0NvbG9yIENQV0xfV25kOjpHZXRUZXh0Q29sb3IoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5zVGV4dENvbG9yOw0KLX0NCi0NCi1DUFdMX0NvbG9yIENQV0xfV25kOjpHZXRUZXh0U3Ryb2tlQ29sb3IoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5zVGV4dFN0cm9rZUNvbG9yOw0KLX0NCi0NCi1GWF9JTlQzMiBDUFdMX1duZDo6R2V0Qm9yZGVyU3R5bGUoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5uQm9yZGVyU3R5bGU7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OlNldEJvcmRlclN0eWxlKEZYX0lOVDMyIG5Cb3JkZXJTdHlsZSkNCi17DQotCWlmIChIYXNGbGFnKFBXU19CT1JERVIpKQ0KLQkJbV9zUHJpdmF0ZVBhcmFtLm5Cb3JkZXJTdHlsZSA9IG5Cb3JkZXJTdHlsZTsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9XbmQ6OkdldEJvcmRlcldpZHRoKCkgY29uc3QNCi17DQotCWlmIChIYXNGbGFnKFBXU19CT1JERVIpKQ0KLQkJcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5kd0JvcmRlcldpZHRoOw0KLQ0KLQlyZXR1cm4gMDsNCi19DQotDQotRlhfSU5UMzIgQ1BXTF9XbmQ6OkdldElubmVyQm9yZGVyV2lkdGgoKSBjb25zdA0KLXsNCi0JLyoNCi0Jc3dpdGNoIChHZXRCb3JkZXJTdHlsZSgpKQ0KLQl7DQotCWNhc2UgUEJTX0JFVkVMRUQ6DQotCWNhc2UgUEJTX0lOU0VUOg0KLQkJcmV0dXJuIEdldEJvcmRlcldpZHRoKCkgLyAyOw0KLQl9DQotCSovDQotCXJldHVybiAwOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpTZXRCb3JkZXJXaWR0aChGWF9JTlQzMiBuQm9yZGVyV2lkdGgpDQotew0KLQlpZiAoSGFzRmxhZyhQV1NfQk9SREVSKSkNCi0JCW1fc1ByaXZhdGVQYXJhbS5kd0JvcmRlcldpZHRoID0gbkJvcmRlcldpZHRoOw0KLX0NCi0NCi1DUFdMX0NvbG9yIENQV0xfV25kOjpHZXRCb3JkZXJDb2xvcigpIGNvbnN0DQotew0KLQlpZiAoSGFzRmxhZyhQV1NfQk9SREVSKSkNCi0JCXJldHVybiBtX3NQcml2YXRlUGFyYW0uc0JvcmRlckNvbG9yOw0KLQ0KLQlyZXR1cm4gQ1BXTF9Db2xvcigpOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpTZXRCb3JkZXJDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpDQotew0KLQlpZiAoSGFzRmxhZyhQV1NfQk9SREVSKSkNCi0JCW1fc1ByaXZhdGVQYXJhbS5zQm9yZGVyQ29sb3IgPSBjb2xvcjsNCi19DQotDQotQ1BXTF9EYXNoIENQV0xfV25kOjpHZXRCb3JkZXJEYXNoKCkgY29uc3QNCi17DQotCXJldHVybiBtX3NQcml2YXRlUGFyYW0uc0Rhc2g7DQotfQ0KLQ0KLXZvaWQqIENQV0xfV25kOjpHZXRBdHRhY2hlZERhdGEoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5wQXR0YWNoZWREYXRhOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpTZXRCb3JkZXJEYXNoKGNvbnN0IENQV0xfRGFzaCAmIHNEYXNoKQ0KLXsNCi0JaWYgKEhhc0ZsYWcoUFdTX0JPUkRFUikpDQotCQltX3NQcml2YXRlUGFyYW0uc0Rhc2ggPSBzRGFzaDsNCi19DQotDQotQ1BXTF9TY3JvbGxCYXIqIENQV0xfV25kOjpHZXRWU2Nyb2xsQmFyKCkgY29uc3QNCi17DQotCWlmIChIYXNGbGFnKFBXU19WU0NST0xMKSkNCi0JCXJldHVybiBtX3BWU2Nyb2xsQmFyOw0KLQ0KLQlyZXR1cm4gTlVMTDsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6Q3JlYXRlU2Nyb2xsQmFyKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQ0KLXsNCi0JQ3JlYXRlVlNjcm9sbEJhcihjcCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OkNyZWF0ZVZTY3JvbGxCYXIoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLQlpZiAoIW1fcFZTY3JvbGxCYXIgJiYgSGFzRmxhZyhQV1NfVlNDUk9MTCkpDQotCXsNCi0JCVBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsNCi0NCi0JCS8vZmxhZ3MNCi0JCXNjcC5kd0ZsYWdzID0gUFdTX0NISUxEfCBQV1NfQkFDS0dST1VORCB8IFBXU19BVVRPVFJBTlNQQVJFTlQgfCBQV1NfTk9SRUZSRVNIQ0xJUDsNCi0JCQ0KLQkJc2NwLnBQYXJlbnRXbmQgPSB0aGlzOw0KLQkJc2NwLnNCYWNrZ3JvdW5kQ29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOw0KLQkJc2NwLmVDdXJzb3JUeXBlID0gRlhDVF9BUlJPVzsNCi0JCXNjcC5uVHJhbnNwYXJlbmN5ID0gUFdMX1NDUk9MTEJBUl9UUkFOU1BBUkFOQ1k7DQotDQotCQlpZiAoKG1fcFZTY3JvbGxCYXIgPSBuZXcgQ1BXTF9TY3JvbGxCYXIoU0JUX1ZTQ1JPTEwpKSkNCi0JCQltX3BWU2Nyb2xsQmFyLT5DcmVhdGUoc2NwKTsNCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpTZXRDYXB0dXJlKCkNCi17DQotCWlmIChDUFdMX01zZ0NvbnRyb2wgKiBwTXNnQ3RybCA9IEdldE1zZ0NvbnRyb2woKSkNCi0JCXBNc2dDdHJsLT5TZXRDYXB0dXJlKHRoaXMpOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpSZWxlYXNlQ2FwdHVyZSgpDQotew0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpDQotCQkJcENoaWxkLT5SZWxlYXNlQ2FwdHVyZSgpOw0KLQ0KLQlpZiAoQ1BXTF9Nc2dDb250cm9sICogcE1zZ0N0cmwgPSBHZXRNc2dDb250cm9sKCkpDQotCQlwTXNnQ3RybC0+UmVsZWFzZUNhcHR1cmUoKTsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6U2V0Rm9jdXMoKQ0KLXsNCi0JaWYgKENQV0xfTXNnQ29udHJvbCAqIHBNc2dDdHJsID0gR2V0TXNnQ29udHJvbCgpKQ0KLQl7DQotCQlpZiAoIXBNc2dDdHJsLT5Jc01haW5DYXB0dXJlS2V5Ym9hcmQodGhpcykpDQotCQkJcE1zZ0N0cmwtPktpbGxGb2N1cygpOw0KLQkJcE1zZ0N0cmwtPlNldEZvY3VzKHRoaXMpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OktpbGxGb2N1cygpDQotew0KLQlpZiAoQ1BXTF9Nc2dDb250cm9sICogcE1zZ0N0cmwgPSBHZXRNc2dDb250cm9sKCkpDQotCXsNCi0JCWlmIChwTXNnQ3RybC0+SXNXbmRDYXB0dXJlS2V5Ym9hcmQodGhpcykpDQotCQkJcE1zZ0N0cmwtPktpbGxGb2N1cygpOw0KLQl9DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6Ok9uU2V0Rm9jdXMoKQ0KLXsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6T25LaWxsRm9jdXMoKQ0KLXsNCi19DQotDQotRlhfQk9PTAlDUFdMX1duZDo6V25kSGl0VGVzdChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0DQotew0KLQlyZXR1cm4gSXNWYWxpZCgpICYmIElzVmlzaWJsZSgpICYmIEdldFdpbmRvd1JlY3QoKS5Db250YWlucyhwb2ludC54LHBvaW50LnkpOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfV25kOjpDbGllbnRIaXRUZXN0KGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3QNCi17DQotCXJldHVybiBJc1ZhbGlkKCkgJiYgSXNWaXNpYmxlKCkgJiYgR2V0Q2xpZW50UmVjdCgpLkNvbnRhaW5zKHBvaW50LngscG9pbnQueSk7DQotfQ0KLQ0KLWNvbnN0IENQV0xfV25kICogQ1BXTF9XbmQ6OkdldFJvb3RXbmQoKSBjb25zdA0KLXsNCi0JaWYgKG1fc1ByaXZhdGVQYXJhbS5wUGFyZW50V25kKQ0KLQkJcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5wUGFyZW50V25kLT5HZXRSb290V25kKCk7DQotCWVsc2UNCi0JCXJldHVybiB0aGlzOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpTZXRWaXNpYmxlKEZYX0JPT0wgYlZpc2libGUpDQotew0KLQlpZiAoSXNWYWxpZCgpKQ0KLQl7DQotCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0JCXsNCi0JCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQ0KLQkJCXsNCi0JCQkJcENoaWxkLT5TZXRWaXNpYmxlKGJWaXNpYmxlKTsNCi0JCQl9DQotCQl9DQotDQotCQlpZiAoYlZpc2libGUgIT0gbV9iVmlzaWJsZSkNCi0JCXsNCi0JCQltX2JWaXNpYmxlID0gYlZpc2libGU7DQotCQkJUmVQb3NDaGlsZFduZCgpOwkJDQotCQkJSW52YWxpZGF0ZVJlY3QoKTsNCi0JCX0JDQotCX0NCi19DQotDQotdm9pZCBDUFdMX1duZDo6U2V0Q2xpcFJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkNCi17DQotCW1fcmNDbGlwID0gcmVjdDsNCi0JbV9yY0NsaXAuTm9ybWFsaXplKCk7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX1duZDo6R2V0Q2xpcFJlY3QoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fcmNDbGlwOw0KLX0NCi0NCi1GWF9CT09MCUNQV0xfV25kOjpJc1JlYWRPbmx5KCkgY29uc3QNCi17DQotCXJldHVybiBIYXNGbGFnKFBXU19SRUFET05MWSk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OlJlUG9zQ2hpbGRXbmQoKQ0KLXsNCi0JQ1BERl9SZWN0IHJjQ29udGVudCA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KEdldFdpbmRvd1JlY3QoKSwoRlhfRkxPQVQpKEdldEJvcmRlcldpZHRoKCkrR2V0SW5uZXJCb3JkZXJXaWR0aCgpKSk7DQotDQotCUNQV0xfU2Nyb2xsQmFyICogcFZTQiA9IHRoaXMtPkdldFZTY3JvbGxCYXIoKTsNCi0NCi0JQ1BERl9SZWN0IHJjVlNjcm9sbCA9IENQREZfUmVjdChyY0NvbnRlbnQucmlnaHQgLSBQV0xfU0NST0xMQkFSX1dJRFRILA0KLQkJCQkJCQlyY0NvbnRlbnQuYm90dG9tLA0KLQkJCQkJCQlyY0NvbnRlbnQucmlnaHQtMS4wZiwNCi0JCQkJCQkJcmNDb250ZW50LnRvcCk7DQotDQotCWlmIChwVlNCKSBwVlNCLT5Nb3ZlKHJjVlNjcm9sbCxUUlVFLEZBTFNFKTsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApDQotew0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpTZXRDdXJzb3IoKQ0KLXsNCi0JaWYgKElzVmFsaWQoKSkgDQotCXsNCi0JCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQ0KLQkJew0KLQkJCUZYX0lOVDMyIG5DdXJzb3JUeXBlID0gdGhpcy0+R2V0Q3JlYXRpb25QYXJhbSgpLmVDdXJzb3JUeXBlOw0KLQkJCXBTSC0+U2V0Q3Vyc29yKG5DdXJzb3JUeXBlKTsNCi0JCX0NCi0JfQ0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpDcmVhdGVNc2dDb250cm9sKCkNCi17DQotCWlmICghbV9zUHJpdmF0ZVBhcmFtLnBNc2dDb250cm9sKQ0KLQkJbV9zUHJpdmF0ZVBhcmFtLnBNc2dDb250cm9sID0gbmV3IENQV0xfTXNnQ29udHJvbCh0aGlzKTsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6RGVzdHJveU1zZ0NvbnRyb2woKQ0KLXsNCi0JaWYgKENQV0xfTXNnQ29udHJvbCogcE1zZ0NvbnRyb2wgPSBHZXRNc2dDb250cm9sKCkpDQotCQlpZiAocE1zZ0NvbnRyb2wtPklzV25kQ3JlYXRlZCh0aGlzKSkNCi0JCQlkZWxldGUgcE1zZ0NvbnRyb2w7DQotfQ0KLQ0KLUNQV0xfTXNnQ29udHJvbCogQ1BXTF9XbmQ6OkdldE1zZ0NvbnRyb2woKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5wTXNnQ29udHJvbDsNCi19DQotDQotRlhfQk9PTCBDUFdMX1duZDo6SXNDYXB0dXJlTW91c2UoKSBjb25zdA0KLXsNCi0JcmV0dXJuIElzV25kQ2FwdHVyZU1vdXNlKHRoaXMpOw0KLX0NCi0NCi1GWF9CT09MIENQV0xfV25kOjpJc1duZENhcHR1cmVNb3VzZShjb25zdCBDUFdMX1duZCAqIHBXbmQpIGNvbnN0DQotew0KLQlpZiAoQ1BXTF9Nc2dDb250cm9sICogcEN0cmwgPSBHZXRNc2dDb250cm9sKCkpDQotCQlyZXR1cm4gcEN0cmwtPklzV25kQ2FwdHVyZU1vdXNlKHBXbmQpOw0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9XbmQ6OklzV25kQ2FwdHVyZUtleWJvYXJkKGNvbnN0IENQV0xfV25kICogcFduZCkgY29uc3QNCi17DQotCWlmIChDUFdMX01zZ0NvbnRyb2wgKiBwQ3RybCA9IEdldE1zZ0NvbnRyb2woKSkNCi0JCXJldHVybiBwQ3RybC0+SXNXbmRDYXB0dXJlS2V5Ym9hcmQocFduZCk7DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTCBDUFdMX1duZDo6SXNGb2N1c2VkKCkgY29uc3QNCi17DQotCWlmIChDUFdMX01zZ0NvbnRyb2wgKiBwQ3RybCA9IEdldE1zZ0NvbnRyb2woKSkNCi0JCXJldHVybiBwQ3RybC0+SXNNYWluQ2FwdHVyZUtleWJvYXJkKHRoaXMpOw0KLQ0KLQlyZXR1cm4gRkFMU0U7DQotfQ0KLQ0KLUNQREZfUmVjdCBDUFdMX1duZDo6R2V0Rm9jdXNSZWN0KCkgY29uc3QNCi17DQotCXJldHVybiBDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdCh0aGlzLT5HZXRXaW5kb3dSZWN0KCksMSk7DQotfQ0KLQ0KLUZYX0ZMT0FUIENQV0xfV25kOjpHZXRGb250U2l6ZSgpIGNvbnN0DQotew0KLQlyZXR1cm4gdGhpcy0+bV9zUHJpdmF0ZVBhcmFtLmZGb250U2l6ZTsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6U2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKQ0KLXsNCi0JdGhpcy0+bV9zUHJpdmF0ZVBhcmFtLmZGb250U2l6ZSA9IGZGb250U2l6ZTsNCi19DQotDQotSUZYX1N5c3RlbUhhbmRsZXIqIENQV0xfV25kOjpHZXRTeXN0ZW1IYW5kbGVyKCkgY29uc3QNCi17DQotCXJldHVybiBtX3NQcml2YXRlUGFyYW0ucFN5c3RlbUhhbmRsZXI7DQotfQ0KLQ0KLUlQV0xfRm9jdXNIYW5kbGVyKiBDUFdMX1duZDo6R2V0Rm9jdXNIYW5kbGVyKCkgY29uc3QNCi17DQotCXJldHVybiBtX3NQcml2YXRlUGFyYW0ucEZvY3VzSGFuZGxlcjsNCi19DQotDQotSVBXTF9Qcm92aWRlciogQ1BXTF9XbmQ6OkdldFByb3ZpZGVyKCkgY29uc3QNCi17DQotCXJldHVybiBtX3NQcml2YXRlUGFyYW0ucFByb3ZpZGVyOw0KLX0NCi0NCi1JRlhfRWRpdF9Gb250TWFwKiBDUFdMX1duZDo6R2V0Rm9udE1hcCgpIGNvbnN0DQotew0KLQlyZXR1cm4gbV9zUHJpdmF0ZVBhcmFtLnBGb250TWFwOw0KLX0NCi0NCi1DUFdMX0NvbG9yIENQV0xfV25kOjpHZXRCb3JkZXJMZWZ0VG9wQ29sb3IoRlhfSU5UMzIgbkJvcmRlclN0eWxlKSBjb25zdA0KLXsNCi0JQ1BXTF9Db2xvciBjb2xvcjsNCi0NCi0Jc3dpdGNoIChuQm9yZGVyU3R5bGUpDQotCXsNCi0JCWNhc2UgUEJTX1NPTElEOg0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQQlNfREFTSDoNCi0JCQlicmVhazsNCi0JCWNhc2UgUEJTX0JFVkVMRUQ6DQotCQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQQlNfSU5TRVQ6DQotCQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDAuNWYpOw0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQQlNfVU5ERVJMSU5FRDoNCi0JCQlicmVhazsNCi0JfQ0KLQ0KLQlyZXR1cm4gY29sb3I7DQotfQ0KLQ0KLUNQV0xfQ29sb3IgQ1BXTF9XbmQ6OkdldEJvcmRlclJpZ2h0Qm90dG9tQ29sb3IoRlhfSU5UMzIgbkJvcmRlclN0eWxlKSBjb25zdA0KLXsNCi0JQ1BXTF9Db2xvciBjb2xvcjsNCi0NCi0Jc3dpdGNoIChuQm9yZGVyU3R5bGUpDQotCXsNCi0JCWNhc2UgUEJTX1NPTElEOg0KLQkJCWJyZWFrOw0KLQkJY2FzZSBQQlNfREFTSDoNCi0JCQlicmVhazsNCi0JCWNhc2UgUEJTX0JFVkVMRUQ6DQotCQkJY29sb3IgPSBDUFdMX1V0aWxzOjpEZXZpZGVDb2xvcihHZXRCYWNrZ3JvdW5kQ29sb3IoKSwyKTsNCi0JCQlicmVhazsNCi0JCWNhc2UgUEJTX0lOU0VUOg0KLQkJCWNvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfR1JBWSwwLjc1Zik7DQotCQkJYnJlYWs7DQotCQljYXNlIFBCU19VTkRFUkxJTkVEOg0KLQkJCWJyZWFrOw0KLQl9DQotDQotCXJldHVybiBjb2xvcjsNCi19DQotDQotLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi0NCi1GWF9JTlQzMiBDUFdMX1duZDo6R2V0VHJhbnNwYXJlbmN5KCkNCi17DQotCXJldHVybiBtX3NQcml2YXRlUGFyYW0ublRyYW5zcGFyZW5jeTsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6U2V0VHJhbnNwYXJlbmN5KEZYX0lOVDMyIG5UcmFuc3BhcmVuY3kpDQotew0KLQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykNCi0Jew0KLQkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkNCi0JCXsNCi0JCQlwQ2hpbGQtPlNldFRyYW5zcGFyZW5jeShuVHJhbnNwYXJlbmN5KTsNCi0JCX0NCi0JfQ0KLQ0KLQltX3NQcml2YXRlUGFyYW0ublRyYW5zcGFyZW5jeSA9IG5UcmFuc3BhcmVuY3k7DQotfQ0KLQ0KLUNQREZfTWF0cml4CUNQV0xfV25kOjpHZXRXaW5kb3dNYXRyaXgoKSBjb25zdA0KLXsNCi0JQ1BERl9NYXRyaXggbXQgPSB0aGlzLT5HZXRDaGlsZFRvUm9vdCgpOw0KLQ0KLQlpZiAoSVBXTF9Qcm92aWRlciogcFByb3ZpZGVyID0gR2V0UHJvdmlkZXIoKSkNCi0Jew0KLQkJbXQuQ29uY2F0KHBQcm92aWRlci0+R2V0V2luZG93TWF0cml4KEdldEF0dGFjaGVkRGF0YSgpKSk7DQotCQlyZXR1cm4gbXQ7DQotCX0NCi0NCi0vKg0KLQlpZiAoQ1JlYWRlcl9BcHAqIHBBcHAgPSBDUFdMX01vZHVsZTo6R2V0UmVhZGVyQXBwKCkpDQotCQlpZiAoQ1JlYWRlcl9Eb2N1bWVudCogcERvY3VtZW50ID0gcEFwcC0+R2V0Q3VycmVudERvY3VtZW50KCkpDQotCQkJaWYgKENSZWFkZXJfRG9jVmlldyogcERvY1ZpZXcgPSBwRG9jdW1lbnQtPkdldEN1cnJlbnREb2NWaWV3KCkpDQotCQkJew0KLQkJCQlDUERGX01hdHJpeCBtdFBhZ2VWaWV3Ow0KLQkJCQlwRG9jVmlldy0+R2V0Q3VycmVudE1hdHJpeChtdFBhZ2VWaWV3KTsNCi0JCQkJbXQuQ29uY2F0KG10UGFnZVZpZXcpOw0KLQkJCQlyZXR1cm4gbXQ7DQotCQkJfQkJDQotCQkJDQotKi8NCi0NCi0JcmV0dXJuIG10Ow0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpQV0x0b1duZChjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfSU5UMzImIHgsIEZYX0lOVDMyJiB5KSBjb25zdA0KLXsNCi0JQ1BERl9NYXRyaXggbXQgPSBHZXRXaW5kb3dNYXRyaXgoKTsNCi0JQ1BERl9Qb2ludCBwdCA9IHBvaW50Ow0KLQltdC5UcmFuc2Zvcm0ocHQueCxwdC55KTsNCi0JeCA9IChGWF9JTlQzMikocHQueCswLjUpOw0KLQl5ID0gKEZYX0lOVDMyKShwdC55KzAuNSk7DQotfQ0KLQ0KLUZYX1JFQ1QgQ1BXTF9XbmQ6OlBXTHRvV25kKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpIGNvbnN0DQotew0KLQlDUERGX1JlY3QgcmNUZW1wID0gcmVjdDsNCi0JQ1BERl9NYXRyaXggbXQgPSBHZXRXaW5kb3dNYXRyaXgoKTsNCi0JbXQuVHJhbnNmb3JtUmVjdChyY1RlbXApOwkNCi0JcmV0dXJuIEZYX1JFQ1QoKEZYX0lOVDMyKShyY1RlbXAubGVmdCswLjUpLCAoRlhfSU5UMzIpKHJjVGVtcC5ib3R0b20rMC41KSwgKEZYX0lOVDMyKShyY1RlbXAucmlnaHQrMC41KSwgKEZYX0lOVDMyKShyY1RlbXAudG9wKzAuNSkpOw0KLX0NCi0NCi1GWF9IV05EIENQV0xfV25kOjpHZXRBdHRhY2hlZEhXbmQoKSBjb25zdA0KLXsNCi0JcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5oQXR0YWNoZWRXbmQ7DQotfQ0KLQ0KLUNQREZfUG9pbnQgQ1BXTF9XbmQ6OkNoaWxkVG9QYXJlbnQoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0DQotew0KLQlDUERGX01hdHJpeCBtdCA9IEdldENoaWxkTWF0cml4KCk7DQotCWlmIChtdC5Jc0lkZW50aXR5KCkpDQotCQlyZXR1cm4gcG9pbnQ7DQotCWVsc2UNCi0Jew0KLQkJQ1BERl9Qb2ludCBwdCA9IHBvaW50Ow0KLQkJbXQuVHJhbnNmb3JtKHB0LngscHQueSk7DQotCQlyZXR1cm4gcHQ7DQotCX0NCi19DQotDQotQ1BERl9SZWN0IENQV0xfV25kOjpDaGlsZFRvUGFyZW50KGNvbnN0IENQREZfUmVjdCYgcmVjdCkgY29uc3QNCi17DQotCUNQREZfTWF0cml4IG10ID0gR2V0Q2hpbGRNYXRyaXgoKTsNCi0JaWYgKG10LklzSWRlbnRpdHkoKSkNCi0JCXJldHVybiByZWN0Ow0KLQllbHNlDQotCXsNCi0JCUNQREZfUmVjdCByYyA9IHJlY3Q7DQotCQltdC5UcmFuc2Zvcm1SZWN0KHJjKTsNCi0JCXJldHVybiByYzsNCi0JfQ0KLX0NCi0NCi1DUERGX1BvaW50IENQV0xfV25kOjpQYXJlbnRUb0NoaWxkKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdA0KLXsNCi0JQ1BERl9NYXRyaXggbXQgPSBHZXRDaGlsZE1hdHJpeCgpOw0KLQlpZiAobXQuSXNJZGVudGl0eSgpKQ0KLQkJcmV0dXJuIHBvaW50Ow0KLQllbHNlDQotCXsNCi0JCW10LlNldFJldmVyc2UobXQpOw0KLQkJQ1BERl9Qb2ludCBwdCA9IHBvaW50Ow0KLQkJbXQuVHJhbnNmb3JtKHB0LngscHQueSk7DQotCQlyZXR1cm4gcHQ7DQotCX0NCi19DQotDQotQ1BERl9SZWN0IENQV0xfV25kOjpQYXJlbnRUb0NoaWxkKGNvbnN0IENQREZfUmVjdCYgcmVjdCkgY29uc3QNCi17DQotCUNQREZfTWF0cml4IG10ID0gR2V0Q2hpbGRNYXRyaXgoKTsNCi0JaWYgKG10LklzSWRlbnRpdHkoKSkNCi0JCXJldHVybiByZWN0Ow0KLQllbHNlDQotCXsNCi0JCW10LlNldFJldmVyc2UobXQpOw0KLQkJQ1BERl9SZWN0IHJjID0gcmVjdDsNCi0JCW10LlRyYW5zZm9ybVJlY3QocmMpOw0KLQkJcmV0dXJuIHJjOw0KLQl9DQotfQ0KLQ0KLUNQREZfTWF0cml4IENQV0xfV25kOjpHZXRDaGlsZFRvUm9vdCgpIGNvbnN0DQotew0KLQlDUERGX01hdHJpeCBtdCgxLDAsMCwxLDAsMCk7DQotCQ0KLQlpZiAoSGFzRmxhZyhQV1NfQ0hJTEQpKQ0KLQl7DQotCQljb25zdCBDUFdMX1duZCogcFBhcmVudCA9IHRoaXM7DQotCQl3aGlsZSAocFBhcmVudCkNCi0JCXsNCi0JCQltdC5Db25jYXQocFBhcmVudC0+R2V0Q2hpbGRNYXRyaXgoKSk7DQotCQkJcFBhcmVudCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpOw0KLQkJfQ0KLQl9DQotDQotCXJldHVybiBtdDsNCi19DQotDQotQ1BERl9NYXRyaXggQ1BXTF9XbmQ6OkdldENoaWxkTWF0cml4KCkgY29uc3QNCi17DQotCWlmIChIYXNGbGFnKFBXU19DSElMRCkpDQotCQlyZXR1cm4gbV9zUHJpdmF0ZVBhcmFtLm10Q2hpbGQ7DQotDQotCXJldHVybiBDUERGX01hdHJpeCgxLDAsMCwxLDAsMCk7DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6OlNldENoaWxkTWF0cml4KGNvbnN0IENQREZfTWF0cml4JiBtdCkNCi17DQotCW1fc1ByaXZhdGVQYXJhbS5tdENoaWxkID0gbXQ7DQotfQ0KLQ0KLWNvbnN0IENQV0xfV25kKglDUFdMX1duZDo6R2V0Rm9jdXNlZCgpIGNvbnN0DQotew0KLQlpZiAoQ1BXTF9Nc2dDb250cm9sICogcE1zZ0N0cmwgPSBHZXRNc2dDb250cm9sKCkpDQotCXsNCi0JCXJldHVybiBwTXNnQ3RybC0+bV9wTWFpbktleWJvYXJkV25kOw0KLQl9DQotDQotCXJldHVybiBOVUxMOw0KLX0NCi0NCi12b2lkIENQV0xfV25kOjpFbmFibGVXaW5kb3coRlhfQk9PTCBiRW5hYmxlKQ0KLXsNCi0JaWYgKG1fYkVuYWJsZWQgIT0gYkVuYWJsZSkNCi0Jew0KLQkJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspDQotCQl7DQotCQkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkNCi0JCQl7DQotCQkJCXBDaGlsZC0+RW5hYmxlV2luZG93KGJFbmFibGUpOw0KLQkJCX0NCi0JCX0NCi0NCi0JCXRoaXMtPm1fYkVuYWJsZWQgPSBiRW5hYmxlOw0KLQ0KLQkJaWYgKGJFbmFibGUpDQotCQkJdGhpcy0+T25FbmFibGVkKCk7DQotCQllbHNlDQotCQkJdGhpcy0+T25EaXNhYmxlZCgpOw0KLQl9DQotfQ0KLQ0KLUZYX0JPT0wgQ1BXTF9XbmQ6OklzRW5hYmxlZCgpDQotew0KLQlyZXR1cm4gbV9iRW5hYmxlZDsNCi19DQotDQotdm9pZCBDUFdMX1duZDo6T25FbmFibGVkKCkNCi17DQotfQ0KLQ0KLXZvaWQgQ1BXTF9XbmQ6Ok9uRGlzYWJsZWQoKQ0KLXsNCi19DQotDQotRlhfQk9PTCBDUFdMX1duZDo6SXNDVFJMcHJlc3NlZChGWF9EV09SRCBuRmxhZykgY29uc3QNCi17DQotCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIgPSBHZXRTeXN0ZW1IYW5kbGVyKCkpDQotCXsNCi0JCXJldHVybiBwU3lzdGVtSGFuZGxlci0+SXNDVFJMS2V5RG93bihuRmxhZyk7DQotCX0NCi0NCi0JcmV0dXJuIEZBTFNFOw0KLX0NCi0NCi1GWF9CT09MCUNQV0xfV25kOjpJc1NISUZUcHJlc3NlZChGWF9EV09SRCBuRmxhZykgY29uc3QNCi17DQotCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIgPSBHZXRTeXN0ZW1IYW5kbGVyKCkpDQotCXsNCi0JCXJldHVybiBwU3lzdGVtSGFuZGxlci0+SXNTSElGVEtleURvd24obkZsYWcpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDUFdMX1duZDo6SXNBTFRwcmVzc2VkKEZYX0RXT1JEIG5GbGFnKSBjb25zdA0KLXsNCi0JaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlciA9IEdldFN5c3RlbUhhbmRsZXIoKSkNCi0Jew0KLQkJcmV0dXJuIHBTeXN0ZW1IYW5kbGVyLT5Jc0FMVEtleURvd24obkZsYWcpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQotRlhfQk9PTAlDUFdMX1duZDo6SXNJTlNFUlRwcmVzc2VkKEZYX0RXT1JEIG5GbGFnKSBjb25zdA0KLXsNCi0JaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU3lzdGVtSGFuZGxlciA9IEdldFN5c3RlbUhhbmRsZXIoKSkNCi0Jew0KLQkJcmV0dXJuIHBTeXN0ZW1IYW5kbGVyLT5Jc0lOU0VSVEtleURvd24obkZsYWcpOw0KLQl9DQotDQotCXJldHVybiBGQUxTRTsNCi19DQotDQorLy8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisvLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgorIAorLy8gT3JpZ2luYWwgY29kZSBjb3B5cmlnaHQgMjAxNCBGb3hpdCBTb2Z0d2FyZSBJbmMuIGh0dHA6Ly93d3cuZm94aXRzb2Z0d2FyZS5jb20KKworI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgorI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9XbmQuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCIKKyNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiCisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfVGltZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworc3RhdGljIENGWF9NYXBQdHJUZW1wbGF0ZTxGWF9JTlQzMiwgQ1BXTF9UaW1lcio+CWdfVGltZU1hcDsKKworQ1BXTF9UaW1lcjo6Q1BXTF9UaW1lcihDUFdMX1RpbWVySGFuZGxlciogcEF0dGFjaGVkLCBJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIpIDogCisJbV9wQXR0YWNoZWQocEF0dGFjaGVkKSwKKwltX25UaW1lcklEKDApLAorCW1fcFN5c3RlbUhhbmRsZXIocFN5c3RlbUhhbmRsZXIpCit7CisJQVNTRVJUKG1fcEF0dGFjaGVkICE9IE5VTEwpOworCUFTU0VSVChtX3BTeXN0ZW1IYW5kbGVyICE9IE5VTEwpOworfQorCitDUFdMX1RpbWVyOjp+Q1BXTF9UaW1lcigpCit7CisJS2lsbFBXTFRpbWVyKCk7Cit9CisKK0ZYX0lOVDMyIENQV0xfVGltZXI6OlNldFBXTFRpbWVyKEZYX0lOVDMyIG5FbGFwc2UpCit7CQorCWlmIChtX25UaW1lcklEICE9IDApIEtpbGxQV0xUaW1lcigpOworCW1fblRpbWVySUQgPSBtX3BTeXN0ZW1IYW5kbGVyLT5TZXRUaW1lcihuRWxhcHNlLCBUaW1lclByb2MpOworCWdfVGltZU1hcC5TZXRBdChtX25UaW1lcklELCB0aGlzKTsKKwlyZXR1cm4gbV9uVGltZXJJRDsKK30KKwordm9pZCBDUFdMX1RpbWVyOjpLaWxsUFdMVGltZXIoKQoreworCWlmIChtX25UaW1lcklEICE9IDApCisJeworCQltX3BTeXN0ZW1IYW5kbGVyLT5LaWxsVGltZXIobV9uVGltZXJJRCk7CisJCWdfVGltZU1hcC5SZW1vdmVLZXkobV9uVGltZXJJRCk7CisJCW1fblRpbWVySUQgPSAwOworCX0KK30KKwordm9pZCBDUFdMX1RpbWVyOjpUaW1lclByb2MoRlhfSU5UMzIgaWRFdmVudCkKK3sKKwlDUFdMX1RpbWVyKiBwVGltZXIgPSBOVUxMOworCWlmIChnX1RpbWVNYXAuTG9va3VwKGlkRXZlbnQsIHBUaW1lcikpCisJeworCQlpZiAocFRpbWVyKQorCQl7CQkJCisJCQlpZiAocFRpbWVyLT5tX3BBdHRhY2hlZCkgCisJCQkJcFRpbWVyLT5tX3BBdHRhY2hlZC0+VGltZXJQcm9jKCk7CisJCX0KKwl9Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfVGltZXJIYW5kbGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfVGltZXJIYW5kbGVyOjpDUFdMX1RpbWVySGFuZGxlcigpIDogbV9wVGltZXIoTlVMTCkKK3sKK30KKworQ1BXTF9UaW1lckhhbmRsZXI6On5DUFdMX1RpbWVySGFuZGxlcigpCit7CisJaWYgKG1fcFRpbWVyKSBkZWxldGUgbV9wVGltZXI7Cit9CisKK3ZvaWQgQ1BXTF9UaW1lckhhbmRsZXI6OkJlZ2luVGltZXIoRlhfSU5UMzIgbkVsYXBzZSkKK3sKKwlpZiAoIW1fcFRpbWVyKQorCQltX3BUaW1lciA9IG5ldyBDUFdMX1RpbWVyKHRoaXMsIEdldFN5c3RlbUhhbmRsZXIoKSk7CisKKwlpZiAobV9wVGltZXIpCisJCW1fcFRpbWVyLT5TZXRQV0xUaW1lcihuRWxhcHNlKTsKK30KKwordm9pZCBDUFdMX1RpbWVySGFuZGxlcjo6RW5kVGltZXIoKQoreworCWlmIChtX3BUaW1lcikKKwkJbV9wVGltZXItPktpbGxQV0xUaW1lcigpOworfQorCit2b2lkIENQV0xfVGltZXJIYW5kbGVyOjpUaW1lclByb2MoKQoreworfQorCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Nc2dDb250cm9sIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworY2xhc3MgQ1BXTF9Nc2dDb250cm9sCit7CisJZnJpZW5kIGNsYXNzIENQV0xfV25kOworCitwdWJsaWM6CisJQ1BXTF9Nc2dDb250cm9sKENQV0xfV25kICogcFduZCkKKwl7CisvLwkJUFdMX1RSQUNFKCJuZXcgQ1BXTF9Nc2dDb250cm9sXG4iKTsKKwkJbV9wQ3JlYXRlZFduZCA9IHBXbmQ7CisJCURlZmF1bHQoKTsKKwl9CisKKwl+Q1BXTF9Nc2dDb250cm9sKCkKKwl7CisvLwkJUFdMX1RSQUNFKCJ+Q1BXTF9Nc2dDb250cm9sXG4iKTsKKwkJRGVmYXVsdCgpOworCX0KKworCXZvaWQgRGVmYXVsdCgpCisJeworCQltX2FNb3VzZVBhdGguUmVtb3ZlQWxsKCk7CisJCW1fYUtleWJvYXJkUGF0aC5SZW1vdmVBbGwoKTsKKwkJbV9wTWFpbk1vdXNlV25kID0gTlVMTDsKKwkJbV9wTWFpbktleWJvYXJkV25kID0gTlVMTDsKKwl9CisKKwlGWF9CT09MIElzV25kQ3JlYXRlZChjb25zdCBDUFdMX1duZCAqIHBXbmQpIGNvbnN0CisJeworCQlyZXR1cm4gbV9wQ3JlYXRlZFduZCA9PSBwV25kOworCX0KKworCUZYX0JPT0wgSXNNYWluQ2FwdHVyZU1vdXNlKGNvbnN0IENQV0xfV25kICogcFduZCkgY29uc3QKKwl7CisJCXJldHVybiBwV25kID09IG1fcE1haW5Nb3VzZVduZDsKKwl9CisKKwlGWF9CT09MIElzV25kQ2FwdHVyZU1vdXNlKGNvbnN0IENQV0xfV25kICogcFduZCkgY29uc3QKKwl7CisJCWlmIChwV25kKQorCQkJZm9yKCBGWF9JTlQzMiBpPTAsc3o9bV9hTW91c2VQYXRoLkdldFNpemUoKTsgaTxzejsgaSsrKQorCQkJCWlmIChtX2FNb3VzZVBhdGguR2V0QXQoaSkgPT0gcFduZCkKKwkJCQkJcmV0dXJuIFRSVUU7CisKKwkJcmV0dXJuIEZBTFNFOworCX0KKworCUZYX0JPT0wgSXNNYWluQ2FwdHVyZUtleWJvYXJkKGNvbnN0IENQV0xfV25kICogcFduZCkgY29uc3QKKwl7CisJCXJldHVybiBwV25kID09IG1fcE1haW5LZXlib2FyZFduZDsKKwl9CisKKworCUZYX0JPT0wgSXNXbmRDYXB0dXJlS2V5Ym9hcmQoY29uc3QgQ1BXTF9XbmQgKiBwV25kKSBjb25zdAorCXsKKwkJaWYgKHBXbmQpCisJCQlmb3IoIEZYX0lOVDMyIGk9MCxzej1tX2FLZXlib2FyZFBhdGguR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCQkJaWYgKG1fYUtleWJvYXJkUGF0aC5HZXRBdChpKSA9PSBwV25kKQorCQkJCQlyZXR1cm4gVFJVRTsKKwkJCisJCXJldHVybiBGQUxTRTsKKwl9CisKKwl2b2lkIFNldEZvY3VzKENQV0xfV25kICogcFduZCkKKwl7CisJCW1fYUtleWJvYXJkUGF0aC5SZW1vdmVBbGwoKTsKKworCQlpZiAocFduZCkKKwkJeworCQkJbV9wTWFpbktleWJvYXJkV25kID0gcFduZDsKKworCQkJQ1BXTF9XbmQgKiBwUGFyZW50ID0gcFduZDsKKwkJCXdoaWxlIChwUGFyZW50KQorCQkJeworCQkJCW1fYUtleWJvYXJkUGF0aC5BZGQocFBhcmVudCk7CisJCQkJcFBhcmVudCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpOworCQkJfQorCisJCQlwV25kLT5PblNldEZvY3VzKCk7CisJCX0KKwl9CisKKwl2b2lkIEtpbGxGb2N1cygpCisJeworCQlpZiAobV9hS2V5Ym9hcmRQYXRoLkdldFNpemUoKSA+IDApCisJCQlpZiAoQ1BXTF9XbmQqIHBXbmQgPSBtX2FLZXlib2FyZFBhdGguR2V0QXQoMCkpCisJCQkJcFduZC0+T25LaWxsRm9jdXMoKTsKKworCQltX3BNYWluS2V5Ym9hcmRXbmQgPSBOVUxMOworCQltX2FLZXlib2FyZFBhdGguUmVtb3ZlQWxsKCk7CisJfQorCisJdm9pZCBTZXRDYXB0dXJlKENQV0xfV25kICogcFduZCkKKwl7CisJCW1fYU1vdXNlUGF0aC5SZW1vdmVBbGwoKTsKKworCQlpZiAocFduZCkKKwkJeworCQkJbV9wTWFpbk1vdXNlV25kID0gcFduZDsKKworCQkJQ1BXTF9XbmQgKiBwUGFyZW50ID0gcFduZDsKKwkJCXdoaWxlIChwUGFyZW50KQorCQkJeworCQkJCW1fYU1vdXNlUGF0aC5BZGQocFBhcmVudCk7CisJCQkJcFBhcmVudCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpOworCQkJfQorCQl9CisJfQorCisJdm9pZCBSZWxlYXNlQ2FwdHVyZSgpCisJeworCQltX3BNYWluTW91c2VXbmQgPSBOVUxMOworCQltX2FNb3VzZVBhdGguUmVtb3ZlQWxsKCk7CisJfQorCitwcml2YXRlOgorCUNGWF9BcnJheVRlbXBsYXRlPENQV0xfV25kKj4JbV9hTW91c2VQYXRoOworCUNGWF9BcnJheVRlbXBsYXRlPENQV0xfV25kKj4JbV9hS2V5Ym9hcmRQYXRoOworCUNQV0xfV25kKgkJCQkJCW1fcENyZWF0ZWRXbmQ7CisJQ1BXTF9XbmQqCQkJCQkJbV9wTWFpbk1vdXNlV25kOworCUNQV0xfV25kKgkJCQkJCW1fcE1haW5LZXlib2FyZFduZDsKK307CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX1duZCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0NQV0xfV25kOjpDUFdMX1duZCgpIDoKKwltX3BWU2Nyb2xsQmFyKE5VTEwpLAorCW1fcmNXaW5kb3coKSwKKwltX3JjQ2xpcCgpLAorCW1fYkNyZWF0ZWQoRkFMU0UpLAkJCQorCW1fYlZpc2libGUoRkFMU0UpLAorCW1fYk5vdGlmeWluZyhGQUxTRSksCisJbV9iRW5hYmxlZChUUlVFKQoreworfQorCitDUFdMX1duZDo6fkNQV0xfV25kKCkKK3sKKwlBU1NFUlQobV9iQ3JlYXRlZCA9PSBGQUxTRSk7Cit9CisKK0NGWF9CeXRlU3RyaW5nIENQV0xfV25kOjpHZXRDbGFzc05hbWUoKSBjb25zdAoreworCXJldHVybiAiQ1BXTF9XbmQiOworfQorCit2b2lkIENQV0xfV25kOjpDcmVhdGUoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJaWYgKCFJc1ZhbGlkKCkpCisJeworCQltX3NQcml2YXRlUGFyYW0gPSBjcDsKKworCQlPbkNyZWF0ZShtX3NQcml2YXRlUGFyYW0pOworCisJCW1fc1ByaXZhdGVQYXJhbS5yY1JlY3RXbmQuTm9ybWFsaXplKCk7CisJCW1fcmNXaW5kb3cgPSBtX3NQcml2YXRlUGFyYW0ucmNSZWN0V25kOworCQltX3JjQ2xpcCA9IENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KG1fcmNXaW5kb3csMS4wZik7CisKKwkJQ3JlYXRlTXNnQ29udHJvbCgpOworCisJCWlmIChtX3NQcml2YXRlUGFyYW0ucFBhcmVudFduZCkKKwkJCW1fc1ByaXZhdGVQYXJhbS5wUGFyZW50V25kLT5Pbk5vdGlmeSh0aGlzLCBQTk1fQUREQ0hJTEQpOworCisJCVBXTF9DUkVBVEVQQVJBTSBjY3AgPSBtX3NQcml2YXRlUGFyYW07CisKKwkJY2NwLmR3RmxhZ3MgJj0gMHhGRkZGMDAwMEw7IC8vcmVtb3ZlIHN1YiBzdHlsZXMKKwkJY2NwLm10Q2hpbGQgPSBDUERGX01hdHJpeCgxLDAsMCwxLDAsMCk7CisJCQorCQlDcmVhdGVTY3JvbGxCYXIoY2NwKTsKKwkJQ3JlYXRlQ2hpbGRXbmQoY2NwKTsgCisKKwkJbV9iVmlzaWJsZSA9IEhhc0ZsYWcoUFdTX1ZJU0lCTEUpOworCisJCU9uQ3JlYXRlZCgpOworCisJCVJlUG9zQ2hpbGRXbmQoKTsKKwkJbV9iQ3JlYXRlZCA9IFRSVUU7CisJfQorfQorCit2b2lkIENQV0xfV25kOjpPbkNyZWF0ZShQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKK3sKK30KKwordm9pZCBDUFdMX1duZDo6T25DcmVhdGVkKCkKK3sKK30KKwordm9pZCBDUFdMX1duZDo6T25EZXN0cm95KCkKK3sKK30KKwordm9pZCBDUFdMX1duZDo6RGVzdHJveSgpCit7CisJS2lsbEZvY3VzKCk7CisKKwlPbkRlc3Ryb3koKTsKKworCWlmIChtX2JDcmVhdGVkKQorCXsKKwkJZm9yIChGWF9JTlQzMiBpID0gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpLTE7IGkgPj0gMDsgaSAtLSkKKwkJeworCQkJaWYgKENQV0xfV25kICogcENoaWxkID0gbV9hQ2hpbGRyZW5baV0pCisJCQl7CisJCQkJcENoaWxkLT5EZXN0cm95KCk7CisJCQkJZGVsZXRlIHBDaGlsZDsKKwkJCQlwQ2hpbGQgPSBOVUxMOworCQkJfQorCQl9CisKKwkJaWYgKG1fc1ByaXZhdGVQYXJhbS5wUGFyZW50V25kKQorCQkJbV9zUHJpdmF0ZVBhcmFtLnBQYXJlbnRXbmQtPk9uTm90aWZ5KHRoaXMsIFBOTV9SRU1PVkVDSElMRCk7CisJCW1fYkNyZWF0ZWQgPSBGQUxTRTsKKwl9CisKKwlEZXN0cm95TXNnQ29udHJvbCgpOworCisJRlhTWVNfbWVtc2V0KCZtX3NQcml2YXRlUGFyYW0sIDAsIHNpemVvZihQV0xfQ1JFQVRFUEFSQU0pKTsKKwltX2FDaGlsZHJlbi5SZW1vdmVBbGwoKTsJCisJbV9wVlNjcm9sbEJhciA9IE5VTEw7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6Ok1vdmUoY29uc3QgQ1BERl9SZWN0ICYgcmNOZXcsIEZYX0JPT0wgYlJlc2V0LEZYX0JPT0wgYlJlZnJlc2gpCit7CisJaWYgKElzVmFsaWQoKSkKKwl7CisJCUNQREZfUmVjdCByY09sZCA9IHRoaXMtPkdldFdpbmRvd1JlY3QoKTsKKworCQltX3JjV2luZG93ID0gcmNOZXc7CisJCW1fcmNXaW5kb3cuTm9ybWFsaXplKCk7CisJCS8vbV9yY0NsaXAgPSBDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdChtX3JjV2luZG93LDEuMGYpOyAvL2ZvciBzcGVjaWFsIGNhcmV0IAorCisJCWlmIChyY09sZC5sZWZ0ICE9IHJjTmV3LmxlZnQgfHwgcmNPbGQucmlnaHQgIT0gcmNOZXcucmlnaHQgfHwKKwkJCXJjT2xkLnRvcCAhPSByY05ldy50b3AgfHwgcmNPbGQuYm90dG9tICE9IHJjTmV3LmJvdHRvbSkKKwkJeworCQkJaWYgKGJSZXNldCkKKwkJCXsKKwkJCQlSZVBvc0NoaWxkV25kKCk7CQorCQkJfQkKKworCQl9CisJCWlmIChiUmVmcmVzaCkKKwkJewkKKwkJCUludmFsaWRhdGVSZWN0TW92ZShyY09sZCxyY05ldyk7CisJCX0KKworCQltX3NQcml2YXRlUGFyYW0ucmNSZWN0V25kID0gbV9yY1dpbmRvdzsKKwl9Cit9CisKK3ZvaWQgIENQV0xfV25kOjpJbnZhbGlkYXRlUmVjdE1vdmUoY29uc3QgQ1BERl9SZWN0ICYgcmNPbGQsIGNvbnN0IENQREZfUmVjdCAmIHJjTmV3KQoreworCUNQREZfUmVjdCByY1VuaW9uID0gcmNPbGQ7CisJcmNVbmlvbi5VbmlvbihyY05ldyk7CisKKwlJbnZhbGlkYXRlUmVjdCgmcmNVbmlvbik7CisKKwkvKgorCUNQREZfUmVjdCBTdWJBcnJheVs0XTsgCisKKwlyY09sZC5TdWJzdHJhY3Q0KHJjTmV3LFN1YkFycmF5KTsKKwlmb3IgKEZYX0lOVDMyIGk9MDtpPDQ7aSsrKQorCXsKKwkJaWYgKFN1YkFycmF5W2ldLmxlZnQgPT0gMCAmJgorCQkJU3ViQXJyYXlbaV0ucmlnaHQgPT0gMCAmJgorCQkJU3ViQXJyYXlbaV0udG9wID09IDAgJiYKKwkJCVN1YkFycmF5W2ldLmJvdHRvbSA9PSAwKWNvbnRpbnVlOworCisJCUludmFsaWRhdGVSZWN0KCZDUFdMX1V0aWxzOjpJbmZsYXRlUmVjdChTdWJBcnJheVtpXSwyKSk7CisJfQorCisJcmNOZXcuU3Vic3RyYWN0NChyY09sZCxTdWJBcnJheSk7CisJZm9yIChGWF9JTlQzMiBqPTA7ajw0O2orKykKKwl7CisJCWlmIChTdWJBcnJheVtqXS5sZWZ0ID09IDAgJiYKKwkJCVN1YkFycmF5W2pdLnJpZ2h0ID09IDAgJiYKKwkJCVN1YkFycmF5W2pdLnRvcCA9PSAwICYmCisJCQlTdWJBcnJheVtqXS5ib3R0b20gPT0gMCljb250aW51ZTsKKworCQlJbnZhbGlkYXRlUmVjdCgmQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QoU3ViQXJyYXlbal0sMikpOworCX0KKwkqLworfQorCit2b2lkIENQV0xfV25kOjpHZXRBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlU3RyaW5nICYgc0FwcFN0cmVhbSkKK3sKKwlpZiAoSXNWYWxpZCgpKQorCXsKKwkJQ0ZYX0J5dGVUZXh0QnVmIHNUZXh0QnVmOworCQlHZXRBcHBlYXJhbmNlU3RyZWFtKHNUZXh0QnVmKTsKKwkJc0FwcFN0cmVhbSArPSBzVGV4dEJ1Zi5HZXRCeXRlU3RyaW5nKCk7CisJfQorfQorCit2b2lkIENQV0xfV25kOjpHZXRBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pCit7CisJaWYgKElzVmFsaWQoKSAmJiBJc1Zpc2libGUoKSkKKwl7CisJCUdldFRoaXNBcHBlYXJhbmNlU3RyZWFtKHNBcHBTdHJlYW0pOworCQlHZXRDaGlsZEFwcGVhcmFuY2VTdHJlYW0oc0FwcFN0cmVhbSk7CisJfQorfQorCisvL2lmIGRvbid0IHNldCxHZXQgZGVmYXVsdCBhcHBlcmFuY2Ugc3RyZWFtCit2b2lkIENQV0xfV25kOjpHZXRUaGlzQXBwZWFyYW5jZVN0cmVhbShDRlhfQnl0ZVRleHRCdWYgJiBzQXBwU3RyZWFtKQoreworCUNQREZfUmVjdCByZWN0V25kID0gR2V0V2luZG93UmVjdCgpOworCWlmICghcmVjdFduZC5Jc0VtcHR5KCkpCisJeworCQlDRlhfQnl0ZVRleHRCdWYgc1RoaXM7CisKKwkJaWYgKEhhc0ZsYWcoUFdTX0JBQ0tHUk9VTkQpKQorCQkJc1RoaXMgPDwgQ1BXTF9VdGlsczo6R2V0UmVjdEZpbGxBcHBTdHJlYW0ocmVjdFduZCx0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKSk7CisKKwkJaWYgKEhhc0ZsYWcoUFdTX0JPUkRFUikpCisJCQlzVGhpcyA8PCBDUFdMX1V0aWxzOjpHZXRCb3JkZXJBcHBTdHJlYW0ocmVjdFduZCwKKwkJCQkJCQkJCShGWF9GTE9BVClHZXRCb3JkZXJXaWR0aCgpLAorCQkJCQkJCQkJR2V0Qm9yZGVyQ29sb3IoKSwKKwkJCQkJCQkJCXRoaXMtPkdldEJvcmRlckxlZnRUb3BDb2xvcih0aGlzLT5HZXRCb3JkZXJTdHlsZSgpKSwKKwkJCQkJCQkJCXRoaXMtPkdldEJvcmRlclJpZ2h0Qm90dG9tQ29sb3IodGhpcy0+R2V0Qm9yZGVyU3R5bGUoKSksCisJCQkJCQkJCQl0aGlzLT5HZXRCb3JkZXJTdHlsZSgpLAorCQkJCQkJCQkJdGhpcy0+R2V0Qm9yZGVyRGFzaCgpKTsKKworCQlzQXBwU3RyZWFtIDw8IHNUaGlzOworCX0KK30KKwordm9pZCBDUFdMX1duZDo6R2V0Q2hpbGRBcHBlYXJhbmNlU3RyZWFtKENGWF9CeXRlVGV4dEJ1ZiAmIHNBcHBTdHJlYW0pCit7CisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlpZiAoQ1BXTF9XbmQgKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKKwkJeworCQkJcENoaWxkLT5HZXRBcHBlYXJhbmNlU3RyZWFtKHNBcHBTdHJlYW0pOworCQl9CisJfQorfQorCit2b2lkIENQV0xfV25kOjpEcmF3QXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQoreworCWlmIChJc1ZhbGlkKCkgJiYgSXNWaXNpYmxlKCkpCisJeworCQlEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSxwVXNlcjJEZXZpY2UpOworCQlEcmF3Q2hpbGRBcHBlYXJhbmNlKHBEZXZpY2UscFVzZXIyRGV2aWNlKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQoreworCUNQREZfUmVjdCByZWN0V25kID0gR2V0V2luZG93UmVjdCgpOworCWlmICghcmVjdFduZC5Jc0VtcHR5KCkpCisJewkJCisJCWlmIChIYXNGbGFnKFBXU19CQUNLR1JPVU5EKSkKKwkJeworCQkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmVjdFduZCwoRlhfRkxPQVQpKEdldEJvcmRlcldpZHRoKCkrR2V0SW5uZXJCb3JkZXJXaWR0aCgpKSk7CisJCQlDUFdMX1V0aWxzOjpEcmF3RmlsbFJlY3QocERldmljZSxwVXNlcjJEZXZpY2UscmNDbGllbnQsdGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCksR2V0VHJhbnNwYXJlbmN5KCkpOworCQl9CisKKwkJaWYgKEhhc0ZsYWcoUFdTX0JPUkRFUikpCisJCQlDUFdMX1V0aWxzOjpEcmF3Qm9yZGVyKHBEZXZpY2UsCisJCQkJCQkJCXBVc2VyMkRldmljZSwKKwkJCQkJCQkJcmVjdFduZCwKKwkJCQkJCQkJKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCksCisJCQkJCQkJCUdldEJvcmRlckNvbG9yKCksCisJCQkJCQkJCXRoaXMtPkdldEJvcmRlckxlZnRUb3BDb2xvcih0aGlzLT5HZXRCb3JkZXJTdHlsZSgpKSwKKwkJCQkJCQkJdGhpcy0+R2V0Qm9yZGVyUmlnaHRCb3R0b21Db2xvcih0aGlzLT5HZXRCb3JkZXJTdHlsZSgpKSwKKwkJCQkJCQkJdGhpcy0+R2V0Qm9yZGVyU3R5bGUoKSwKKwkJCQkJCQkJdGhpcy0+R2V0Qm9yZGVyRGFzaCgpLAorCQkJCQkJCQlHZXRUcmFuc3BhcmVuY3koKSk7CQkJCQkJCQkKKwl9Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OkRyYXdDaGlsZEFwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkKK3sKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwl7CisJCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQorCQl7CisJCQlDUERGX01hdHJpeCBtdCA9IHBDaGlsZC0+R2V0Q2hpbGRNYXRyaXgoKTsKKwkJCWlmIChtdC5Jc0lkZW50aXR5KCkpCisJCQl7CisJCQkJcENoaWxkLT5EcmF3QXBwZWFyYW5jZShwRGV2aWNlLHBVc2VyMkRldmljZSk7CisJCQl9CisJCQllbHNlCisJCQl7CisJCQkJbXQuQ29uY2F0KCpwVXNlcjJEZXZpY2UpOworCQkJCXBDaGlsZC0+RHJhd0FwcGVhcmFuY2UocERldmljZSwmbXQpOworCQkJfQorCQl9CisJfQorfQorCit2b2lkIENQV0xfV25kOjpJbnZhbGlkYXRlUmVjdChDUERGX1JlY3QqIHBSZWN0KQoreworCWlmIChJc1ZhbGlkKCkpCisJeworCQlDUERGX1JlY3QgcmNSZWZyZXNoID0gcFJlY3QgPyAqcFJlY3QgOiBHZXRXaW5kb3dSZWN0KCk7CisKKwkJaWYgKCFIYXNGbGFnKFBXU19OT1JFRlJFU0hDTElQKSkKKwkJeworCQkJQ1BERl9SZWN0IHJjQ2xpcCA9IEdldENsaXBSZWN0KCk7CQkKKwkJCWlmICghcmNDbGlwLklzRW1wdHkoKSkKKwkJCXsKKwkJCQlyY1JlZnJlc2guSW50ZXJzZWN0KHJjQ2xpcCk7CisJCQl9CisJCX0KKworCQlGWF9SRUNUIHJjV2luID0gUFdMdG9XbmQocmNSZWZyZXNoKTsKKwkJcmNXaW4ubGVmdCAtPSBQV0xfSU5WQUxJREFURV9JTkZMQVRFOworCQlyY1dpbi50b3AgLT0gUFdMX0lOVkFMSURBVEVfSU5GTEFURTsKKwkJcmNXaW4ucmlnaHQgKz0gUFdMX0lOVkFMSURBVEVfSU5GTEFURTsKKwkJcmNXaW4uYm90dG9tICs9IFBXTF9JTlZBTElEQVRFX0lORkxBVEU7CisKKwkJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCisJCXsKKwkJCWlmIChGWF9IV05EIGhXbmQgPSBHZXRBdHRhY2hlZEhXbmQoKSkKKwkJCXsKKwkJCQlwU0gtPkludmFsaWRhdGVSZWN0KGhXbmQsIHJjV2luKTsKKwkJCX0KKwkJfQorCX0KK30KKworI2RlZmluZSBQV0xfSU1QTEVNRU5UX0tFWV9NRVRIT0Qoa2V5X21ldGhvZF9uYW1lKVwKK0ZYX0JPT0wgQ1BXTF9XbmQ6OmtleV9tZXRob2RfbmFtZShGWF9XT1JEIG5DaGFyLCBGWF9EV09SRCBuRmxhZylcCit7XAorCWlmIChJc1ZhbGlkKCkgJiYgSXNWaXNpYmxlKCkgJiYgSXNFbmFibGVkKCkpXAorCXtcCisJCWlmIChJc1duZENhcHR1cmVLZXlib2FyZCh0aGlzKSlcCisJCXtcCisJCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKylcCisJCQl7XAorCQkJCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKVwKKwkJCQl7XAorCQkJCQlpZiAoSXNXbmRDYXB0dXJlS2V5Ym9hcmQocENoaWxkKSlcCisJCQkJCXtcCisJCQkJCQlyZXR1cm4gcENoaWxkLT5rZXlfbWV0aG9kX25hbWUobkNoYXIsbkZsYWcpO1wKKwkJCQkJfVwKKwkJCQl9XAorCQkJfVwKKwkJfVwKKwl9XAorCXJldHVybiBGQUxTRTtcCit9CisKKyNkZWZpbmUgUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QobW91c2VfbWV0aG9kX25hbWUpXAorRlhfQk9PTCBDUFdMX1duZDo6bW91c2VfbWV0aG9kX25hbWUoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZylcCit7XAorCWlmIChJc1ZhbGlkKCkgJiYgSXNWaXNpYmxlKCkgJiYgSXNFbmFibGVkKCkpXAorCXtcCisJCWlmIChJc1duZENhcHR1cmVNb3VzZSh0aGlzKSlcCisJCXtcCisJCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKylcCisJCQl7XAorCQkJCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKVwKKwkJCQl7XAorCQkJCQlpZiAoSXNXbmRDYXB0dXJlTW91c2UocENoaWxkKSlcCisJCQkJCXtcCisJCQkJCQlyZXR1cm4gcENoaWxkLT5tb3VzZV9tZXRob2RfbmFtZShwQ2hpbGQtPlBhcmVudFRvQ2hpbGQocG9pbnQpLG5GbGFnKTtcCisJCQkJCX1cCisJCQkJfVwKKwkJCX1cCisJCQlTZXRDdXJzb3IoKTtcCisJCX1cCisJCWVsc2VcCisJCXtcCisJCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKylcCisJCQl7XAorCQkJCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKVwKKwkJCQl7XAorCQkJCQlpZiAocENoaWxkLT5XbmRIaXRUZXN0KHBDaGlsZC0+UGFyZW50VG9DaGlsZChwb2ludCkpKVwKKwkJCQkJe1wKKwkJCQkJCXJldHVybiBwQ2hpbGQtPm1vdXNlX21ldGhvZF9uYW1lKHBDaGlsZC0+UGFyZW50VG9DaGlsZChwb2ludCksbkZsYWcpO1wKKwkJCQkJfVwKKwkJCQl9XAorCQkJfVwKKwkJCWlmICh0aGlzLT5XbmRIaXRUZXN0KHBvaW50KSlcCisJCQkJU2V0Q3Vyc29yKCk7XAorCQl9XAorCX1cCisJcmV0dXJuIEZBTFNFO1wKK30KKworUFdMX0lNUExFTUVOVF9LRVlfTUVUSE9EKE9uS2V5RG93bikKK1BXTF9JTVBMRU1FTlRfS0VZX01FVEhPRChPbktleVVwKQorUFdMX0lNUExFTUVOVF9LRVlfTUVUSE9EKE9uQ2hhcikKKworUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25MQnV0dG9uRGJsQ2xrKQorUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25MQnV0dG9uRG93bikKK1BXTF9JTVBMRU1FTlRfTU9VU0VfTUVUSE9EKE9uTEJ1dHRvblVwKQorUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25NQnV0dG9uRGJsQ2xrKQorUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25NQnV0dG9uRG93bikKK1BXTF9JTVBMRU1FTlRfTU9VU0VfTUVUSE9EKE9uTUJ1dHRvblVwKQorUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25SQnV0dG9uRGJsQ2xrKQorUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25SQnV0dG9uRG93bikKK1BXTF9JTVBMRU1FTlRfTU9VU0VfTUVUSE9EKE9uUkJ1dHRvblVwKQorUFdMX0lNUExFTUVOVF9NT1VTRV9NRVRIT0QoT25Nb3VzZU1vdmUpCisKK0ZYX0JPT0wJQ1BXTF9XbmQ6Ok9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCit7CisJaWYgKElzVmFsaWQoKSAmJiBJc1Zpc2libGUoKSAmJiBJc0VuYWJsZWQoKSkKKwl7CisJCVNldEN1cnNvcigpOworCQlpZiAoSXNXbmRDYXB0dXJlS2V5Ym9hcmQodGhpcykpCisJCXsKKwkJCWZvciAoRlhfSU5UMzIgaT0wLHN6PW1fYUNoaWxkcmVuLkdldFNpemUoKTsgaTxzejsgaSsrKQorCQkJeworCQkJCWlmIChDUFdMX1duZCAqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQorCQkJCXsKKwkJCQkJaWYgKElzV25kQ2FwdHVyZUtleWJvYXJkKHBDaGlsZCkpCisJCQkJCXsKKwkJCQkJCXJldHVybiBwQ2hpbGQtPk9uTW91c2VXaGVlbCh6RGVsdGEscENoaWxkLT5QYXJlbnRUb0NoaWxkKHBvaW50KSwgbkZsYWcpOworCQkJCQl9CisJCQkJfQorCQkJfQorCQl9CisJfQorCXJldHVybiBGQUxTRTsKK30KKwordm9pZCBDUFdMX1duZDo6QWRkQ2hpbGQoQ1BXTF9XbmQgKiBwV25kKQoreworCW1fYUNoaWxkcmVuLkFkZChwV25kKTsKK30KKwordm9pZCBDUFdMX1duZDo6UmVtb3ZlQ2hpbGQoQ1BXTF9XbmQgKiBwV25kKQoreworCWZvciAoRlhfSU5UMzIgaSA9IG1fYUNoaWxkcmVuLkdldFNpemUoKS0xOyBpID49IDA7IGkgLS0pCisJeworCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQorCQl7CisJCQlpZiAocENoaWxkID09IHBXbmQpCisJCQl7CisJCQkJbV9hQ2hpbGRyZW4uUmVtb3ZlQXQoaSk7CisJCQkJYnJlYWs7CisJCQl9CisJCX0KKwl9Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pCit7CisJc3dpdGNoIChtc2cpCisJeworCWNhc2UgUE5NX0FERENISUxEOgorCQl0aGlzLT5BZGRDaGlsZChwV25kKTsKKwkJYnJlYWs7CisJY2FzZSBQTk1fUkVNT1ZFQ0hJTEQ6CisJCXRoaXMtPlJlbW92ZUNoaWxkKHBXbmQpOworCQlicmVhazsKKwlkZWZhdWx0OgorCQlicmVhazsKKwl9Cit9CisKK0ZYX0JPT0wgQ1BXTF9XbmQ6OklzVmFsaWQoKSBjb25zdAoreworCXJldHVybiBtX2JDcmVhdGVkOworfQorCitQV0xfQ1JFQVRFUEFSQU0gQ1BXTF9XbmQ6OkdldENyZWF0aW9uUGFyYW0oKSBjb25zdAoreworCXJldHVybiBtX3NQcml2YXRlUGFyYW07Cit9CisKK0NQV0xfV25kKiBDUFdMX1duZDo6R2V0UGFyZW50V2luZG93KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9zUHJpdmF0ZVBhcmFtLnBQYXJlbnRXbmQ7Cit9CisKK0NQREZfUmVjdCBDUFdMX1duZDo6R2V0T3JpZ2luV2luZG93UmVjdCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5yY1JlY3RXbmQ7Cit9CisKK0NQREZfUmVjdCBDUFdMX1duZDo6R2V0V2luZG93UmVjdCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fcmNXaW5kb3c7Cit9CisKK0NQREZfUmVjdCBDUFdMX1duZDo6R2V0Q2xpZW50UmVjdCgpIGNvbnN0Cit7CisJQ1BERl9SZWN0IHJjV2luZG93ID0gR2V0V2luZG93UmVjdCgpOworCUNQREZfUmVjdCByY0NsaWVudCA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJjV2luZG93LChGWF9GTE9BVCkoR2V0Qm9yZGVyV2lkdGgoKStHZXRJbm5lckJvcmRlcldpZHRoKCkpKTsKKworCWlmIChDUFdMX1Njcm9sbEJhciAqIHBWU0IgPSB0aGlzLT5HZXRWU2Nyb2xsQmFyKCkpCisJCXJjQ2xpZW50LnJpZ2h0IC09IHBWU0ItPkdldFNjcm9sbEJhcldpZHRoKCk7CisKKwlyY0NsaWVudC5Ob3JtYWxpemUoKTsKKworCWlmIChyY1dpbmRvdy5Db250YWlucyhyY0NsaWVudCkpCisJCXJldHVybiByY0NsaWVudDsKKwllbHNlCisJCXJldHVybiBDUERGX1JlY3QoKTsKK30KKworQ1BERl9Qb2ludCBDUFdMX1duZDo6R2V0Q2VudGVyUG9pbnQoKSBjb25zdAoreworCUNQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKKworCXJldHVybiBDUERGX1BvaW50KChyY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQucmlnaHQpICogMC41ZiwKKwkJKHJjQ2xpZW50LnRvcCArIHJjQ2xpZW50LmJvdHRvbSkgKiAwLjVmKTsKK30KKworQ1BERl9SZWN0IENQV0xfV25kOjpHZXRDbGllbnRDZW50ZXJTcXVhcmUoKSBjb25zdAoreworCXJldHVybiBDUFdMX1V0aWxzOjpHZXRDZW50ZXJTcXVhcmUoR2V0Q2xpZW50UmVjdCgpKTsKK30KKworQ1BERl9SZWN0IENQV0xfV25kOjpHZXRXaW5kb3dDZW50ZXJTcXVhcmUoKSBjb25zdAoreworCXJldHVybiBDUFdMX1V0aWxzOjpHZXRDZW50ZXJTcXVhcmUoQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QoR2V0V2luZG93UmVjdCgpLDAuMWYpKTsKK30KKworRlhfQk9PTCBDUFdMX1duZDo6SGFzRmxhZyhGWF9EV09SRCBkd0ZsYWdzKSBjb25zdAoreworCXJldHVybiAobV9zUHJpdmF0ZVBhcmFtLmR3RmxhZ3MgJiBkd0ZsYWdzKSAhPSAwOworfQorCit2b2lkIENQV0xfV25kOjpSZW1vdmVGbGFnKEZYX0RXT1JEIGR3RmxhZ3MpCit7CisJbV9zUHJpdmF0ZVBhcmFtLmR3RmxhZ3MgJj0gfmR3RmxhZ3M7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OkFkZEZsYWcoRlhfRFdPUkQgZHdGbGFncykKK3sKKwltX3NQcml2YXRlUGFyYW0uZHdGbGFncyB8PSBkd0ZsYWdzOworfQorCitDUFdMX0NvbG9yIENQV0xfV25kOjpHZXRCYWNrZ3JvdW5kQ29sb3IoKSBjb25zdAoreworCXJldHVybiBtX3NQcml2YXRlUGFyYW0uc0JhY2tncm91bmRDb2xvcjsKK30KKwordm9pZCBDUFdMX1duZDo6U2V0QmFja2dyb3VuZENvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcikKK3sKKwltX3NQcml2YXRlUGFyYW0uc0JhY2tncm91bmRDb2xvciA9IGNvbG9yOworfQorCit2b2lkIENQV0xfV25kOjpTZXRUZXh0Q29sb3IoY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yKQoreworCW1fc1ByaXZhdGVQYXJhbS5zVGV4dENvbG9yID0gY29sb3I7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OlNldFRleHRTdHJva2VDb2xvcihjb25zdCBDUFdMX0NvbG9yICYgY29sb3IpCit7CisJbV9zUHJpdmF0ZVBhcmFtLnNUZXh0U3Ryb2tlQ29sb3IgPSBjb2xvcjsKK30KKworQ1BXTF9Db2xvciBDUFdMX1duZDo6R2V0VGV4dENvbG9yKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9zUHJpdmF0ZVBhcmFtLnNUZXh0Q29sb3I7Cit9CisKK0NQV0xfQ29sb3IgQ1BXTF9XbmQ6OkdldFRleHRTdHJva2VDb2xvcigpIGNvbnN0Cit7CisJcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5zVGV4dFN0cm9rZUNvbG9yOworfQorCitGWF9JTlQzMiBDUFdMX1duZDo6R2V0Qm9yZGVyU3R5bGUoKSBjb25zdAoreworCXJldHVybiBtX3NQcml2YXRlUGFyYW0ubkJvcmRlclN0eWxlOworfQorCit2b2lkIENQV0xfV25kOjpTZXRCb3JkZXJTdHlsZShGWF9JTlQzMiBuQm9yZGVyU3R5bGUpCit7CisJaWYgKEhhc0ZsYWcoUFdTX0JPUkRFUikpCisJCW1fc1ByaXZhdGVQYXJhbS5uQm9yZGVyU3R5bGUgPSBuQm9yZGVyU3R5bGU7Cit9CisKK0ZYX0lOVDMyIENQV0xfV25kOjpHZXRCb3JkZXJXaWR0aCgpIGNvbnN0Cit7CisJaWYgKEhhc0ZsYWcoUFdTX0JPUkRFUikpCisJCXJldHVybiBtX3NQcml2YXRlUGFyYW0uZHdCb3JkZXJXaWR0aDsKKworCXJldHVybiAwOworfQorCitGWF9JTlQzMiBDUFdMX1duZDo6R2V0SW5uZXJCb3JkZXJXaWR0aCgpIGNvbnN0Cit7CisJLyoKKwlzd2l0Y2ggKEdldEJvcmRlclN0eWxlKCkpCisJeworCWNhc2UgUEJTX0JFVkVMRUQ6CisJY2FzZSBQQlNfSU5TRVQ6CisJCXJldHVybiBHZXRCb3JkZXJXaWR0aCgpIC8gMjsKKwl9CisJKi8KKwlyZXR1cm4gMDsKK30KKwordm9pZCBDUFdMX1duZDo6U2V0Qm9yZGVyV2lkdGgoRlhfSU5UMzIgbkJvcmRlcldpZHRoKQoreworCWlmIChIYXNGbGFnKFBXU19CT1JERVIpKQorCQltX3NQcml2YXRlUGFyYW0uZHdCb3JkZXJXaWR0aCA9IG5Cb3JkZXJXaWR0aDsKK30KKworQ1BXTF9Db2xvciBDUFdMX1duZDo6R2V0Qm9yZGVyQ29sb3IoKSBjb25zdAoreworCWlmIChIYXNGbGFnKFBXU19CT1JERVIpKQorCQlyZXR1cm4gbV9zUHJpdmF0ZVBhcmFtLnNCb3JkZXJDb2xvcjsKKworCXJldHVybiBDUFdMX0NvbG9yKCk7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OlNldEJvcmRlckNvbG9yKGNvbnN0IENQV0xfQ29sb3IgJiBjb2xvcikKK3sKKwlpZiAoSGFzRmxhZyhQV1NfQk9SREVSKSkKKwkJbV9zUHJpdmF0ZVBhcmFtLnNCb3JkZXJDb2xvciA9IGNvbG9yOworfQorCitDUFdMX0Rhc2ggQ1BXTF9XbmQ6OkdldEJvcmRlckRhc2goKSBjb25zdAoreworCXJldHVybiBtX3NQcml2YXRlUGFyYW0uc0Rhc2g7Cit9CisKK3ZvaWQqIENQV0xfV25kOjpHZXRBdHRhY2hlZERhdGEoKSBjb25zdAoreworCXJldHVybiBtX3NQcml2YXRlUGFyYW0ucEF0dGFjaGVkRGF0YTsKK30KKwordm9pZCBDUFdMX1duZDo6U2V0Qm9yZGVyRGFzaChjb25zdCBDUFdMX0Rhc2ggJiBzRGFzaCkKK3sKKwlpZiAoSGFzRmxhZyhQV1NfQk9SREVSKSkKKwkJbV9zUHJpdmF0ZVBhcmFtLnNEYXNoID0gc0Rhc2g7Cit9CisKK0NQV0xfU2Nyb2xsQmFyKiBDUFdMX1duZDo6R2V0VlNjcm9sbEJhcigpIGNvbnN0Cit7CisJaWYgKEhhc0ZsYWcoUFdTX1ZTQ1JPTEwpKQorCQlyZXR1cm4gbV9wVlNjcm9sbEJhcjsKKworCXJldHVybiBOVUxMOworfQorCit2b2lkIENQV0xfV25kOjpDcmVhdGVTY3JvbGxCYXIoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJQ3JlYXRlVlNjcm9sbEJhcihjcCk7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OkNyZWF0ZVZTY3JvbGxCYXIoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCit7CisJaWYgKCFtX3BWU2Nyb2xsQmFyICYmIEhhc0ZsYWcoUFdTX1ZTQ1JPTEwpKQorCXsKKwkJUFdMX0NSRUFURVBBUkFNIHNjcCA9IGNwOworCisJCS8vZmxhZ3MKKwkJc2NwLmR3RmxhZ3MgPSBQV1NfQ0hJTER8IFBXU19CQUNLR1JPVU5EIHwgUFdTX0FVVE9UUkFOU1BBUkVOVCB8IFBXU19OT1JFRlJFU0hDTElQOworCQkKKwkJc2NwLnBQYXJlbnRXbmQgPSB0aGlzOworCQlzY3Auc0JhY2tncm91bmRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CisJCXNjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfQVJST1c7CisJCXNjcC5uVHJhbnNwYXJlbmN5ID0gUFdMX1NDUk9MTEJBUl9UUkFOU1BBUkFOQ1k7CisKKwkJaWYgKChtX3BWU2Nyb2xsQmFyID0gbmV3IENQV0xfU2Nyb2xsQmFyKFNCVF9WU0NST0xMKSkpCisJCQltX3BWU2Nyb2xsQmFyLT5DcmVhdGUoc2NwKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OlNldENhcHR1cmUoKQoreworCWlmIChDUFdMX01zZ0NvbnRyb2wgKiBwTXNnQ3RybCA9IEdldE1zZ0NvbnRyb2woKSkKKwkJcE1zZ0N0cmwtPlNldENhcHR1cmUodGhpcyk7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OlJlbGVhc2VDYXB0dXJlKCkKK3sKKwlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKKwkJCXBDaGlsZC0+UmVsZWFzZUNhcHR1cmUoKTsKKworCWlmIChDUFdMX01zZ0NvbnRyb2wgKiBwTXNnQ3RybCA9IEdldE1zZ0NvbnRyb2woKSkKKwkJcE1zZ0N0cmwtPlJlbGVhc2VDYXB0dXJlKCk7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OlNldEZvY3VzKCkKK3sKKwlpZiAoQ1BXTF9Nc2dDb250cm9sICogcE1zZ0N0cmwgPSBHZXRNc2dDb250cm9sKCkpCisJeworCQlpZiAoIXBNc2dDdHJsLT5Jc01haW5DYXB0dXJlS2V5Ym9hcmQodGhpcykpCisJCQlwTXNnQ3RybC0+S2lsbEZvY3VzKCk7CisJCXBNc2dDdHJsLT5TZXRGb2N1cyh0aGlzKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OktpbGxGb2N1cygpCit7CisJaWYgKENQV0xfTXNnQ29udHJvbCAqIHBNc2dDdHJsID0gR2V0TXNnQ29udHJvbCgpKQorCXsKKwkJaWYgKHBNc2dDdHJsLT5Jc1duZENhcHR1cmVLZXlib2FyZCh0aGlzKSkKKwkJCXBNc2dDdHJsLT5LaWxsRm9jdXMoKTsKKwl9Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6Ok9uU2V0Rm9jdXMoKQoreworfQorCit2b2lkIENQV0xfV25kOjpPbktpbGxGb2N1cygpCit7Cit9CisKK0ZYX0JPT0wJQ1BXTF9XbmQ6OlduZEhpdFRlc3QoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdAoreworCXJldHVybiBJc1ZhbGlkKCkgJiYgSXNWaXNpYmxlKCkgJiYgR2V0V2luZG93UmVjdCgpLkNvbnRhaW5zKHBvaW50LngscG9pbnQueSk7Cit9CisKK0ZYX0JPT0wgQ1BXTF9XbmQ6OkNsaWVudEhpdFRlc3QoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdAoreworCXJldHVybiBJc1ZhbGlkKCkgJiYgSXNWaXNpYmxlKCkgJiYgR2V0Q2xpZW50UmVjdCgpLkNvbnRhaW5zKHBvaW50LngscG9pbnQueSk7Cit9CisKK2NvbnN0IENQV0xfV25kICogQ1BXTF9XbmQ6OkdldFJvb3RXbmQoKSBjb25zdAoreworCWlmIChtX3NQcml2YXRlUGFyYW0ucFBhcmVudFduZCkKKwkJcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5wUGFyZW50V25kLT5HZXRSb290V25kKCk7CisJZWxzZQorCQlyZXR1cm4gdGhpczsKK30KKwordm9pZCBDUFdMX1duZDo6U2V0VmlzaWJsZShGWF9CT09MIGJWaXNpYmxlKQoreworCWlmIChJc1ZhbGlkKCkpCisJeworCQlmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKKwkJeworCQkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKKwkJCXsKKwkJCQlwQ2hpbGQtPlNldFZpc2libGUoYlZpc2libGUpOworCQkJfQorCQl9CisKKwkJaWYgKGJWaXNpYmxlICE9IG1fYlZpc2libGUpCisJCXsKKwkJCW1fYlZpc2libGUgPSBiVmlzaWJsZTsKKwkJCVJlUG9zQ2hpbGRXbmQoKTsJCQorCQkJSW52YWxpZGF0ZVJlY3QoKTsKKwkJfQkKKwl9Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OlNldENsaXBSZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QpCit7CisJbV9yY0NsaXAgPSByZWN0OworCW1fcmNDbGlwLk5vcm1hbGl6ZSgpOworfQorCitDUERGX1JlY3QgQ1BXTF9XbmQ6OkdldENsaXBSZWN0KCkgY29uc3QKK3sKKwlyZXR1cm4gbV9yY0NsaXA7Cit9CisKK0ZYX0JPT0wJQ1BXTF9XbmQ6OklzUmVhZE9ubHkoKSBjb25zdAoreworCXJldHVybiBIYXNGbGFnKFBXU19SRUFET05MWSk7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OlJlUG9zQ2hpbGRXbmQoKQoreworCUNQREZfUmVjdCByY0NvbnRlbnQgPSBDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChHZXRXaW5kb3dSZWN0KCksKEZYX0ZMT0FUKShHZXRCb3JkZXJXaWR0aCgpK0dldElubmVyQm9yZGVyV2lkdGgoKSkpOworCisJQ1BXTF9TY3JvbGxCYXIgKiBwVlNCID0gdGhpcy0+R2V0VlNjcm9sbEJhcigpOworCisJQ1BERl9SZWN0IHJjVlNjcm9sbCA9IENQREZfUmVjdChyY0NvbnRlbnQucmlnaHQgLSBQV0xfU0NST0xMQkFSX1dJRFRILAorCQkJCQkJCXJjQ29udGVudC5ib3R0b20sCisJCQkJCQkJcmNDb250ZW50LnJpZ2h0LTEuMGYsCisJCQkJCQkJcmNDb250ZW50LnRvcCk7CisKKwlpZiAocFZTQikgcFZTQi0+TW92ZShyY1ZTY3JvbGwsVFJVRSxGQUxTRSk7Cit9CisKK3ZvaWQgQ1BXTF9XbmQ6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQoreworfQorCit2b2lkIENQV0xfV25kOjpTZXRDdXJzb3IoKQoreworCWlmIChJc1ZhbGlkKCkpIAorCXsKKwkJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCisJCXsKKwkJCUZYX0lOVDMyIG5DdXJzb3JUeXBlID0gdGhpcy0+R2V0Q3JlYXRpb25QYXJhbSgpLmVDdXJzb3JUeXBlOworCQkJcFNILT5TZXRDdXJzb3IobkN1cnNvclR5cGUpOworCQl9CisJfQorfQorCit2b2lkIENQV0xfV25kOjpDcmVhdGVNc2dDb250cm9sKCkKK3sKKwlpZiAoIW1fc1ByaXZhdGVQYXJhbS5wTXNnQ29udHJvbCkKKwkJbV9zUHJpdmF0ZVBhcmFtLnBNc2dDb250cm9sID0gbmV3IENQV0xfTXNnQ29udHJvbCh0aGlzKTsKK30KKwordm9pZCBDUFdMX1duZDo6RGVzdHJveU1zZ0NvbnRyb2woKQoreworCWlmIChDUFdMX01zZ0NvbnRyb2wqIHBNc2dDb250cm9sID0gR2V0TXNnQ29udHJvbCgpKQorCQlpZiAocE1zZ0NvbnRyb2wtPklzV25kQ3JlYXRlZCh0aGlzKSkKKwkJCWRlbGV0ZSBwTXNnQ29udHJvbDsKK30KKworQ1BXTF9Nc2dDb250cm9sKiBDUFdMX1duZDo6R2V0TXNnQ29udHJvbCgpIGNvbnN0Cit7CisJcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5wTXNnQ29udHJvbDsKK30KKworRlhfQk9PTCBDUFdMX1duZDo6SXNDYXB0dXJlTW91c2UoKSBjb25zdAoreworCXJldHVybiBJc1duZENhcHR1cmVNb3VzZSh0aGlzKTsKK30KKworRlhfQk9PTCBDUFdMX1duZDo6SXNXbmRDYXB0dXJlTW91c2UoY29uc3QgQ1BXTF9XbmQgKiBwV25kKSBjb25zdAoreworCWlmIChDUFdMX01zZ0NvbnRyb2wgKiBwQ3RybCA9IEdldE1zZ0NvbnRyb2woKSkKKwkJcmV0dXJuIHBDdHJsLT5Jc1duZENhcHR1cmVNb3VzZShwV25kKTsKKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDUFdMX1duZDo6SXNXbmRDYXB0dXJlS2V5Ym9hcmQoY29uc3QgQ1BXTF9XbmQgKiBwV25kKSBjb25zdAoreworCWlmIChDUFdMX01zZ0NvbnRyb2wgKiBwQ3RybCA9IEdldE1zZ0NvbnRyb2woKSkKKwkJcmV0dXJuIHBDdHJsLT5Jc1duZENhcHR1cmVLZXlib2FyZChwV25kKTsKKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTCBDUFdMX1duZDo6SXNGb2N1c2VkKCkgY29uc3QKK3sKKwlpZiAoQ1BXTF9Nc2dDb250cm9sICogcEN0cmwgPSBHZXRNc2dDb250cm9sKCkpCisJCXJldHVybiBwQ3RybC0+SXNNYWluQ2FwdHVyZUtleWJvYXJkKHRoaXMpOworCisJcmV0dXJuIEZBTFNFOworfQorCitDUERGX1JlY3QgQ1BXTF9XbmQ6OkdldEZvY3VzUmVjdCgpIGNvbnN0Cit7CisJcmV0dXJuIENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KHRoaXMtPkdldFdpbmRvd1JlY3QoKSwxKTsKK30KKworRlhfRkxPQVQgQ1BXTF9XbmQ6OkdldEZvbnRTaXplKCkgY29uc3QKK3sKKwlyZXR1cm4gdGhpcy0+bV9zUHJpdmF0ZVBhcmFtLmZGb250U2l6ZTsKK30KKwordm9pZCBDUFdMX1duZDo6U2V0Rm9udFNpemUoRlhfRkxPQVQgZkZvbnRTaXplKQoreworCXRoaXMtPm1fc1ByaXZhdGVQYXJhbS5mRm9udFNpemUgPSBmRm9udFNpemU7Cit9CisKK0lGWF9TeXN0ZW1IYW5kbGVyKiBDUFdMX1duZDo6R2V0U3lzdGVtSGFuZGxlcigpIGNvbnN0Cit7CisJcmV0dXJuIG1fc1ByaXZhdGVQYXJhbS5wU3lzdGVtSGFuZGxlcjsKK30KKworSVBXTF9Gb2N1c0hhbmRsZXIqIENQV0xfV25kOjpHZXRGb2N1c0hhbmRsZXIoKSBjb25zdAoreworCXJldHVybiBtX3NQcml2YXRlUGFyYW0ucEZvY3VzSGFuZGxlcjsKK30KKworSVBXTF9Qcm92aWRlciogQ1BXTF9XbmQ6OkdldFByb3ZpZGVyKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9zUHJpdmF0ZVBhcmFtLnBQcm92aWRlcjsKK30KKworSUZYX0VkaXRfRm9udE1hcCogQ1BXTF9XbmQ6OkdldEZvbnRNYXAoKSBjb25zdAoreworCXJldHVybiBtX3NQcml2YXRlUGFyYW0ucEZvbnRNYXA7Cit9CisKK0NQV0xfQ29sb3IgQ1BXTF9XbmQ6OkdldEJvcmRlckxlZnRUb3BDb2xvcihGWF9JTlQzMiBuQm9yZGVyU3R5bGUpIGNvbnN0Cit7CisJQ1BXTF9Db2xvciBjb2xvcjsKKworCXN3aXRjaCAobkJvcmRlclN0eWxlKQorCXsKKwkJY2FzZSBQQlNfU09MSUQ6CisJCQlicmVhazsKKwkJY2FzZSBQQlNfREFTSDoKKwkJCWJyZWFrOworCQljYXNlIFBCU19CRVZFTEVEOgorCQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDEpOworCQkJYnJlYWs7CisJCWNhc2UgUEJTX0lOU0VUOgorCQkJY29sb3IgPSBDUFdMX0NvbG9yKENPTE9SVFlQRV9HUkFZLDAuNWYpOworCQkJYnJlYWs7CisJCWNhc2UgUEJTX1VOREVSTElORUQ6CisJCQlicmVhazsKKwl9CisKKwlyZXR1cm4gY29sb3I7Cit9CisKK0NQV0xfQ29sb3IgQ1BXTF9XbmQ6OkdldEJvcmRlclJpZ2h0Qm90dG9tQ29sb3IoRlhfSU5UMzIgbkJvcmRlclN0eWxlKSBjb25zdAoreworCUNQV0xfQ29sb3IgY29sb3I7CisKKwlzd2l0Y2ggKG5Cb3JkZXJTdHlsZSkKKwl7CisJCWNhc2UgUEJTX1NPTElEOgorCQkJYnJlYWs7CisJCWNhc2UgUEJTX0RBU0g6CisJCQlicmVhazsKKwkJY2FzZSBQQlNfQkVWRUxFRDoKKwkJCWNvbG9yID0gQ1BXTF9VdGlsczo6RGV2aWRlQ29sb3IoR2V0QmFja2dyb3VuZENvbG9yKCksMik7CisJCQlicmVhazsKKwkJY2FzZSBQQlNfSU5TRVQ6CisJCQljb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX0dSQVksMC43NWYpOworCQkJYnJlYWs7CisJCWNhc2UgUEJTX1VOREVSTElORUQ6CisJCQlicmVhazsKKwl9CisKKwlyZXR1cm4gY29sb3I7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK0ZYX0lOVDMyIENQV0xfV25kOjpHZXRUcmFuc3BhcmVuY3koKQoreworCXJldHVybiBtX3NQcml2YXRlUGFyYW0ublRyYW5zcGFyZW5jeTsKK30KKwordm9pZCBDUFdMX1duZDo6U2V0VHJhbnNwYXJlbmN5KEZYX0lOVDMyIG5UcmFuc3BhcmVuY3kpCit7CisJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJeworCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQorCQl7CisJCQlwQ2hpbGQtPlNldFRyYW5zcGFyZW5jeShuVHJhbnNwYXJlbmN5KTsKKwkJfQorCX0KKworCW1fc1ByaXZhdGVQYXJhbS5uVHJhbnNwYXJlbmN5ID0gblRyYW5zcGFyZW5jeTsKK30KKworQ1BERl9NYXRyaXgJQ1BXTF9XbmQ6OkdldFdpbmRvd01hdHJpeCgpIGNvbnN0Cit7CisJQ1BERl9NYXRyaXggbXQgPSB0aGlzLT5HZXRDaGlsZFRvUm9vdCgpOworCisJaWYgKElQV0xfUHJvdmlkZXIqIHBQcm92aWRlciA9IEdldFByb3ZpZGVyKCkpCisJeworCQltdC5Db25jYXQocFByb3ZpZGVyLT5HZXRXaW5kb3dNYXRyaXgoR2V0QXR0YWNoZWREYXRhKCkpKTsKKwkJcmV0dXJuIG10OworCX0KKworLyoKKwlpZiAoQ1JlYWRlcl9BcHAqIHBBcHAgPSBDUFdMX01vZHVsZTo6R2V0UmVhZGVyQXBwKCkpCisJCWlmIChDUmVhZGVyX0RvY3VtZW50KiBwRG9jdW1lbnQgPSBwQXBwLT5HZXRDdXJyZW50RG9jdW1lbnQoKSkKKwkJCWlmIChDUmVhZGVyX0RvY1ZpZXcqIHBEb2NWaWV3ID0gcERvY3VtZW50LT5HZXRDdXJyZW50RG9jVmlldygpKQorCQkJeworCQkJCUNQREZfTWF0cml4IG10UGFnZVZpZXc7CisJCQkJcERvY1ZpZXctPkdldEN1cnJlbnRNYXRyaXgobXRQYWdlVmlldyk7CisJCQkJbXQuQ29uY2F0KG10UGFnZVZpZXcpOworCQkJCXJldHVybiBtdDsKKwkJCX0JCQorCQkJCisqLworCisJcmV0dXJuIG10OworfQorCit2b2lkIENQV0xfV25kOjpQV0x0b1duZChjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfSU5UMzImIHgsIEZYX0lOVDMyJiB5KSBjb25zdAoreworCUNQREZfTWF0cml4IG10ID0gR2V0V2luZG93TWF0cml4KCk7CisJQ1BERl9Qb2ludCBwdCA9IHBvaW50OworCW10LlRyYW5zZm9ybShwdC54LHB0LnkpOworCXggPSAoRlhfSU5UMzIpKHB0LngrMC41KTsKKwl5ID0gKEZYX0lOVDMyKShwdC55KzAuNSk7Cit9CisKK0ZYX1JFQ1QgQ1BXTF9XbmQ6OlBXTHRvV25kKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpIGNvbnN0Cit7CisJQ1BERl9SZWN0IHJjVGVtcCA9IHJlY3Q7CisJQ1BERl9NYXRyaXggbXQgPSBHZXRXaW5kb3dNYXRyaXgoKTsKKwltdC5UcmFuc2Zvcm1SZWN0KHJjVGVtcCk7CQorCXJldHVybiBGWF9SRUNUKChGWF9JTlQzMikocmNUZW1wLmxlZnQrMC41KSwgKEZYX0lOVDMyKShyY1RlbXAuYm90dG9tKzAuNSksIChGWF9JTlQzMikocmNUZW1wLnJpZ2h0KzAuNSksIChGWF9JTlQzMikocmNUZW1wLnRvcCswLjUpKTsKK30KKworRlhfSFdORCBDUFdMX1duZDo6R2V0QXR0YWNoZWRIV25kKCkgY29uc3QKK3sKKwlyZXR1cm4gbV9zUHJpdmF0ZVBhcmFtLmhBdHRhY2hlZFduZDsKK30KKworQ1BERl9Qb2ludCBDUFdMX1duZDo6Q2hpbGRUb1BhcmVudChjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3QKK3sKKwlDUERGX01hdHJpeCBtdCA9IEdldENoaWxkTWF0cml4KCk7CisJaWYgKG10LklzSWRlbnRpdHkoKSkKKwkJcmV0dXJuIHBvaW50OworCWVsc2UKKwl7CisJCUNQREZfUG9pbnQgcHQgPSBwb2ludDsKKwkJbXQuVHJhbnNmb3JtKHB0LngscHQueSk7CisJCXJldHVybiBwdDsKKwl9Cit9CisKK0NQREZfUmVjdCBDUFdMX1duZDo6Q2hpbGRUb1BhcmVudChjb25zdCBDUERGX1JlY3QmIHJlY3QpIGNvbnN0Cit7CisJQ1BERl9NYXRyaXggbXQgPSBHZXRDaGlsZE1hdHJpeCgpOworCWlmIChtdC5Jc0lkZW50aXR5KCkpCisJCXJldHVybiByZWN0OworCWVsc2UKKwl7CisJCUNQREZfUmVjdCByYyA9IHJlY3Q7CisJCW10LlRyYW5zZm9ybVJlY3QocmMpOworCQlyZXR1cm4gcmM7CisJfQorfQorCitDUERGX1BvaW50IENQV0xfV25kOjpQYXJlbnRUb0NoaWxkKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdAoreworCUNQREZfTWF0cml4IG10ID0gR2V0Q2hpbGRNYXRyaXgoKTsKKwlpZiAobXQuSXNJZGVudGl0eSgpKQorCQlyZXR1cm4gcG9pbnQ7CisJZWxzZQorCXsKKwkJbXQuU2V0UmV2ZXJzZShtdCk7CisJCUNQREZfUG9pbnQgcHQgPSBwb2ludDsKKwkJbXQuVHJhbnNmb3JtKHB0LngscHQueSk7CisJCXJldHVybiBwdDsKKwl9Cit9CisKK0NQREZfUmVjdCBDUFdMX1duZDo6UGFyZW50VG9DaGlsZChjb25zdCBDUERGX1JlY3QmIHJlY3QpIGNvbnN0Cit7CisJQ1BERl9NYXRyaXggbXQgPSBHZXRDaGlsZE1hdHJpeCgpOworCWlmIChtdC5Jc0lkZW50aXR5KCkpCisJCXJldHVybiByZWN0OworCWVsc2UKKwl7CisJCW10LlNldFJldmVyc2UobXQpOworCQlDUERGX1JlY3QgcmMgPSByZWN0OworCQltdC5UcmFuc2Zvcm1SZWN0KHJjKTsKKwkJcmV0dXJuIHJjOworCX0KK30KKworQ1BERl9NYXRyaXggQ1BXTF9XbmQ6OkdldENoaWxkVG9Sb290KCkgY29uc3QKK3sKKwlDUERGX01hdHJpeCBtdCgxLDAsMCwxLDAsMCk7CisJCisJaWYgKEhhc0ZsYWcoUFdTX0NISUxEKSkKKwl7CisJCWNvbnN0IENQV0xfV25kKiBwUGFyZW50ID0gdGhpczsKKwkJd2hpbGUgKHBQYXJlbnQpCisJCXsKKwkJCW10LkNvbmNhdChwUGFyZW50LT5HZXRDaGlsZE1hdHJpeCgpKTsKKwkJCXBQYXJlbnQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKTsKKwkJfQorCX0KKworCXJldHVybiBtdDsKK30KKworQ1BERl9NYXRyaXggQ1BXTF9XbmQ6OkdldENoaWxkTWF0cml4KCkgY29uc3QKK3sKKwlpZiAoSGFzRmxhZyhQV1NfQ0hJTEQpKQorCQlyZXR1cm4gbV9zUHJpdmF0ZVBhcmFtLm10Q2hpbGQ7CisKKwlyZXR1cm4gQ1BERl9NYXRyaXgoMSwwLDAsMSwwLDApOworfQorCit2b2lkIENQV0xfV25kOjpTZXRDaGlsZE1hdHJpeChjb25zdCBDUERGX01hdHJpeCYgbXQpCit7CisJbV9zUHJpdmF0ZVBhcmFtLm10Q2hpbGQgPSBtdDsKK30KKworY29uc3QgQ1BXTF9XbmQqCUNQV0xfV25kOjpHZXRGb2N1c2VkKCkgY29uc3QKK3sKKwlpZiAoQ1BXTF9Nc2dDb250cm9sICogcE1zZ0N0cmwgPSBHZXRNc2dDb250cm9sKCkpCisJeworCQlyZXR1cm4gcE1zZ0N0cmwtPm1fcE1haW5LZXlib2FyZFduZDsKKwl9CisKKwlyZXR1cm4gTlVMTDsKK30KKwordm9pZCBDUFdMX1duZDo6RW5hYmxlV2luZG93KEZYX0JPT0wgYkVuYWJsZSkKK3sKKwlpZiAobV9iRW5hYmxlZCAhPSBiRW5hYmxlKQorCXsKKwkJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCisJCXsKKwkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpCisJCQl7CisJCQkJcENoaWxkLT5FbmFibGVXaW5kb3coYkVuYWJsZSk7CisJCQl9CisJCX0KKworCQl0aGlzLT5tX2JFbmFibGVkID0gYkVuYWJsZTsKKworCQlpZiAoYkVuYWJsZSkKKwkJCXRoaXMtPk9uRW5hYmxlZCgpOworCQllbHNlCisJCQl0aGlzLT5PbkRpc2FibGVkKCk7CisJfQorfQorCitGWF9CT09MIENQV0xfV25kOjpJc0VuYWJsZWQoKQoreworCXJldHVybiBtX2JFbmFibGVkOworfQorCit2b2lkIENQV0xfV25kOjpPbkVuYWJsZWQoKQoreworfQorCit2b2lkIENQV0xfV25kOjpPbkRpc2FibGVkKCkKK3sKK30KKworRlhfQk9PTCBDUFdMX1duZDo6SXNDVFJMcHJlc3NlZChGWF9EV09SRCBuRmxhZykgY29uc3QKK3sKKwlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyID0gR2V0U3lzdGVtSGFuZGxlcigpKQorCXsKKwkJcmV0dXJuIHBTeXN0ZW1IYW5kbGVyLT5Jc0NUUkxLZXlEb3duKG5GbGFnKTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ1BXTF9XbmQ6OklzU0hJRlRwcmVzc2VkKEZYX0RXT1JEIG5GbGFnKSBjb25zdAoreworCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIgPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCisJeworCQlyZXR1cm4gcFN5c3RlbUhhbmRsZXItPklzU0hJRlRLZXlEb3duKG5GbGFnKTsKKwl9CisKKwlyZXR1cm4gRkFMU0U7Cit9CisKK0ZYX0JPT0wJQ1BXTF9XbmQ6OklzQUxUcHJlc3NlZChGWF9EV09SRCBuRmxhZykgY29uc3QKK3sKKwlpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTeXN0ZW1IYW5kbGVyID0gR2V0U3lzdGVtSGFuZGxlcigpKQorCXsKKwkJcmV0dXJuIHBTeXN0ZW1IYW5kbGVyLT5Jc0FMVEtleURvd24obkZsYWcpOworCX0KKworCXJldHVybiBGQUxTRTsKK30KKworRlhfQk9PTAlDUFdMX1duZDo6SXNJTlNFUlRwcmVzc2VkKEZYX0RXT1JEIG5GbGFnKSBjb25zdAoreworCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFN5c3RlbUhhbmRsZXIgPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCisJeworCQlyZXR1cm4gcFN5c3RlbUhhbmRsZXItPklzSU5TRVJUS2V5RG93bihuRmxhZyk7CisJfQorCisJcmV0dXJuIEZBTFNFOworfQorCmRpZmYgLS1naXQgYS9mcGRmc2RrL3NyYy9yZXNvdXJjZS5oIGIvZnBkZnNkay9zcmMvcmVzb3VyY2UuaAppbmRleCBlOTdkMWQ1Li5iNThmMDkyIDEwMDY0NAotLS0gYS9mcGRmc2RrL3NyYy9yZXNvdXJjZS5oCisrKyBiL2ZwZGZzZGsvc3JjL3Jlc291cmNlLmgKQEAgLTEsMjEgKzEsMjEgQEAKLS8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLg0KLS8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUNCi0vLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLg0KLSANCi0vLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQ0KLQ0KLS8ve3tOT19ERVBFTkRFTkNJRVN9fQ0KLS8vIE1pY3Jvc29mdCBEZXZlbG9wZXIgU3R1ZGlvIGdlbmVyYXRlZCBpbmNsdWRlIGZpbGUuDQotLy8gVXNlZCBieSBmcGRmc2RrZGxsLnJjDQotLy8NCi0NCi0vLyBOZXh0IGRlZmF1bHQgdmFsdWVzIGZvciBuZXcgb2JqZWN0cw0KLS8vIA0KLSNpZmRlZiBBUFNUVURJT19JTlZPS0VEDQotI2lmbmRlZiBBUFNUVURJT19SRUFET05MWV9TWU1CT0xTDQotI2RlZmluZSBfQVBTX05FWFRfUkVTT1VSQ0VfVkFMVUUgICAgICAgIDEwNA0KLSNkZWZpbmUgX0FQU19ORVhUX0NPTU1BTkRfVkFMVUUgICAgICAgICA0MDAwMQ0KLSNkZWZpbmUgX0FQU19ORVhUX0NPTlRST0xfVkFMVUUgICAgICAgICAxMDAwDQotI2RlZmluZSBfQVBTX05FWFRfU1lNRURfVkFMVUUgICAgICAgICAgIDEwMQ0KLSNlbmRpZg0KLSNlbmRpZg0KKy8vIENvcHlyaWdodCAyMDE0IFBERml1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQorLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KKyAKKy8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCisKKy8ve3tOT19ERVBFTkRFTkNJRVN9fQorLy8gTWljcm9zb2Z0IERldmVsb3BlciBTdHVkaW8gZ2VuZXJhdGVkIGluY2x1ZGUgZmlsZS4KKy8vIFVzZWQgYnkgZnBkZnNka2RsbC5yYworLy8KKworLy8gTmV4dCBkZWZhdWx0IHZhbHVlcyBmb3IgbmV3IG9iamVjdHMKKy8vIAorI2lmZGVmIEFQU1RVRElPX0lOVk9LRUQKKyNpZm5kZWYgQVBTVFVESU9fUkVBRE9OTFlfU1lNQk9MUworI2RlZmluZSBfQVBTX05FWFRfUkVTT1VSQ0VfVkFMVUUgICAgICAgIDEwNAorI2RlZmluZSBfQVBTX05FWFRfQ09NTUFORF9WQUxVRSAgICAgICAgIDQwMDAxCisjZGVmaW5lIF9BUFNfTkVYVF9DT05UUk9MX1ZBTFVFICAgICAgICAgMTAwMAorI2RlZmluZSBfQVBTX05FWFRfU1lNRURfVkFMVUUgICAgICAgICAgIDEwMQorI2VuZGlmCisjZW5kaWYK