LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfYXV0b21hdGlvbi5oeHgiCgovKiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvZGV2dG9vbHMvWElTZXJ2ZXJQcm94eS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvZGV2dG9vbHMvWEluZm9ybWF0aW9uQ2xpZW50LmhwcD4KdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjpkZXZ0b29sczsKKi8KI2lmZGVmIE9TMgojZGVmaW5lIElOQ0xfRE9TCi8vI2luY2x1ZGUgPHZjbC9zeXNkZXAuaHh4PgojaWZuZGVmIF9TVlBNX0gKI2luY2x1ZGUgPHN2cG0uaD4KI2VuZGlmCiNlbmRpZgoKI2luY2x1ZGUgInN5c2Rpcl93aW4uaHh4IgojaW5jbHVkZSAicmVnaXN0cnlfd2luLmh4eCIKI2luY2x1ZGUgInN0dHJlc2lkLmh4eCIKI2luY2x1ZGUgPG9zbC9maWxlLmh4eD4KI2lmbmRlZiBfTVNHQk9YX0hYWCAvL2F1dG9nZW4KI2luY2x1ZGUgPHZjbC9tc2dib3guaHh4PgojZW5kaWYKI2lmbmRlZiBfU09VTkRfSFhYIC8vYXV0b2dlbgojaW5jbHVkZSA8dmNsL3NvdW5kLmh4eD4KI2VuZGlmCiNpbmNsdWRlIDx0b29scy9jb25maWcuaHh4PgojaWZuZGVmIF9BUFBfSFhYIC8vYXV0b2dlbgojaW5jbHVkZSA8dmNsL3N2YXBwLmh4eD4KI2VuZGlmCiNpbmNsdWRlIDxzdnRvb2xzL3N0cmluZ3RyYW5zZmVyLmh4eD4KI2luY2x1ZGUgPHN2bC9icmRjc3QuaHh4PgovLyNpZm5kZWYgX1NCWENMQVNTX0hYWCAvL2F1dG9nZW4KI2luY2x1ZGUgPGJhc2ljL3NieC5oeHg+Ci8vI2VuZGlmCiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvdW5vL0FueS5oeHg+CiNpZm5kZWYgX0NPTV9TVU5fU1RBUl9GUkFNRV9YREVTS1RPUF9IWFhfCiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvZnJhbWUvWERlc2t0b3AuaHBwPgojZW5kaWYKI2luY2x1ZGUgPGNvbXBoZWxwZXIvcHJvY2Vzc2ZhY3RvcnkuaHh4PgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JyaWRnZS9YQnJpZGdlRmFjdG9yeS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvY29ubmVjdGlvbi9YQ29ubmVjdG9yLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jb25uZWN0aW9uL1hDb25uZWN0aW9uLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9sYW5nL1hNdWx0aVNlcnZpY2VGYWN0b3J5LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9sYW5nL1hNdWx0aVNlcnZpY2VGYWN0b3J5LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci91bm8vWE5hbWluZ1NlcnZpY2UuaHBwPgoKI2luY2x1ZGUgPGNwcHVoZWxwZXIvc2VydmljZWZhY3RvcnkuaHh4PgoKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjp1bm87CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6bGFuZzsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjpmcmFtZTsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjpicmlkZ2U7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6Y29ubmVjdGlvbjsKdXNpbmcgbmFtZXNwYWNlIHJ0bDsKCgojaW5jbHVkZSA8c3Z0b29scy9zdm1lZGl0Lmh4eD4KCiNpZmRlZiBVTlgKI2luY2x1ZGUgPHVuaXN0ZC5oPiAvLyByZWFkbGluawojaW5jbHVkZSA8ZXJybm8uaD4KI2VuZGlmCgojaW5jbHVkZSA8YmFzaWMvc2J1bm8uaHh4PgoKLy8jaW5jbHVkZSA8YmFzaWMvYmFzcmlkLmh4eD4KI2luY2x1ZGUgPGJhc2ljL2Jhc2ljcnQuaHh4PgojaWZuZGVmIF9CQVNJQ19UVFJFU0hMUF9IWFgKI2luY2x1ZGUgPGJhc2ljL3R0c3RyaGxwLmh4eD4KI2VuZGlmCiNpbmNsdWRlICJ0Y29tbXVuaS5oeHgiCiNpbmNsdWRlICJjb21tX2Jhcy5oeHgiCiNpbmNsdWRlIDxjcmV0c3RybS5oeHg+CgojaW5jbHVkZSAib2JqdGVzdC5oeHgiCiNpbmNsdWRlICJyY29udHJvbC5oeHgiCgojaW5jbHVkZSA8YmFzaWMvdGVzdHRvb2wuaHJjPgojaW5jbHVkZSA8YmFzaWMvdHRtc2cuaHJjPgoKI2luY2x1ZGUgPGJhc2ljL215YmFzaWMuaHh4PgojaW5jbHVkZSA8YmFzaWMvdGVzdHRvb2wuaHh4PgojaW5jbHVkZSA8YmFzaWMvc2JzdGFyLmh4eD4KCiNpbmNsdWRlIDxhbGdvcml0aG0+CgojaWZuZGVmIFNCWF9WQUxVRV9ERUNMX0RFRklORUQKI2RlZmluZSBTQlhfVkFMVUVfREVDTF9ERUZJTkVEClNWX0RFQ0xfUkVGKFNieFZhbHVlKQojZW5kaWYKU1ZfSU1QTF9SRUYoU2J4VmFsdWUpCgpzdGF0aWMgQ29tbXVuaWNhdGlvbkZhY3RvcnkgYUNvbU1hbkZhYzsKCiNkZWZpbmUgY015RGVsaW0gJyAnCiNkZWZpbmUgUF9GRUhMRVJMSVNURSBwRmVobGVyTGlzdGUKI2RlZmluZSBLRUVQX1NFUVVFTkNFUwkJMTAwCQkJLy8gS2VlcCBOYW1lcyBvZiBsYXN0IDEwMCBDYWxscwoKCkNvbnRyb2xEZWZMb2FkIF9fUkVBRE9OTFlfREFUQSBDb250cm9sczo6YXJDbGFzc2VzIFtdID0KI2luY2x1ZGUgImNsYXNzZXMuaHh4IgpDTmFtZXMgKkNvbnRyb2xzOjpwQ2xhc3NlcyA9IE5VTEw7CgpDb250cm9sRGVmTG9hZCBfX1JFQURPTkxZX0RBVEEgVGVzdFRvb2xPYmo6OmFyUl9DbWRzIFtdID0KI2luY2x1ZGUgInJfY21kcy5oeHgiCkNOYW1lcyAqVGVzdFRvb2xPYmo6OnBSQ29tbWFuZHMgPSBOVUxMOwpDRXJyb3JzICpUZXN0VG9vbE9iajo6cEZlaGxlckxpc3RlID0gTlVMTDsJCS8vIEhpZXIgd2VyZGVuIGRpZSBGZWhsZXIgZGVzIFRlc3R0b29scyBnZXNwZWljaGVydAoKCkRCR19OQU1FKCBDb250cm9sSXRlbSApCkRCR19OQU1FKCBDb250cm9sRGVmICkKCkNvbnRyb2xJdGVtOjpDb250cm9sSXRlbSggY29uc3Qgc2FsX0NoYXIgKk5hbWUsIHJ0bDo6T1N0cmluZyBhVUlkUCApCnsKREJHX0NUT1IoQ29udHJvbEl0ZW0sMCk7CglJbml0RGF0YSgpOwoJcERhdGEtPkt1cnpuYW1lLkFzc2lnbkFzY2lpKCBOYW1lICk7CglwRGF0YS0+YVVJZCA9IGFVSWRQOwp9CgpDb250cm9sSXRlbTo6Q29udHJvbEl0ZW0oIGNvbnN0IFN0cmluZyAmTmFtZSwgcnRsOjpPU3RyaW5nIGFVSWRQICkKewpEQkdfQ1RPUihDb250cm9sSXRlbSwwKTsKCUluaXREYXRhKCk7CglwRGF0YS0+S3Vyem5hbWUgPSBOYW1lOwoJcERhdGEtPmFVSWQgPSBhVUlkUDsKfQoKLypDb250cm9sSXRlbTo6Q29udHJvbEl0ZW0oIGNvbnN0IFN0cmluZyAmTmFtZSwgY29uc3QgU3RyaW5nICZVUkwsIGNvbnN0IFVSTFR5cGUgYVR5cGUgKQp7CkRCR19DVE9SKENvbnRyb2xJdGVtLDApOwoJSW5pdERhdGEoKTsKCXBEYXRhLT5LdXJ6bmFtZSA9IE5hbWU7CglwRGF0YS0+YVVSTCA9IFVSTDsKCXBEYXRhLT5uVUlkID0gYVR5cGU7Cn0KCkNvbnRyb2xJdGVtOjpDb250cm9sSXRlbSggY29uc3QgU3RyaW5nICZOYW1lLCBjb25zdCBTdHJpbmcgJlVSTCwgY29uc3Qgc2FsX3VMb25nIG5VSWQgKQp7CkRCR19DVE9SKENvbnRyb2xJdGVtLDApOwoJSW5pdERhdGEoKTsKCXBEYXRhLT5LdXJ6bmFtZSA9IE5hbWU7CglwRGF0YS0+YVVSTCA9IFVSTDsKCXBEYXRhLT5uVUlkID0gblVJZDsKfQoKQ29udHJvbEl0ZW06OkNvbnRyb2xJdGVtKCBjb25zdCBjaGFyICpOYW1lLCBjb25zdCBTdHJpbmcgJlVSTCwgY29uc3Qgc2FsX3VMb25nIG5VSWQgKQp7CkRCR19DVE9SKENvbnRyb2xJdGVtLDApOwoJSW5pdERhdGEoKTsKCXBEYXRhLT5LdXJ6bmFtZS5Bc3NpZ25Bc2NpaSggTmFtZSApOwoJcERhdGEtPmFVUkwgPSBVUkw7CglwRGF0YS0+blVJZCA9IG5VSWQ7Cn0gKi8KCgpDb250cm9sSXRlbTo6Q29udHJvbEl0ZW0oIENvbnRyb2xEYXRhICpwRGF0YVAgKQp7CkRCR19DVE9SKENvbnRyb2xJdGVtLDApOwoJcERhdGEgPSBwRGF0YVA7Cn0KCkNvbnRyb2xTb246On5Db250cm9sU29uKCkKewoJaWYgKHBTb25zKQoJewogICAgCWRlbGV0ZSBwU29uczsKICAgIAlwU29ucyA9IE5VTEw7Cgl9Cn0KCkNvbnRyb2xJdGVtU29uOjpDb250cm9sSXRlbVNvbihjb25zdCBTdHJpbmcgJk5hbWUsIHJ0bDo6T1N0cmluZyBhVUlkUCApCjogQ29udHJvbEl0ZW0oIE5hbWUsIGFVSWRQICkKe30KCi8qQ29udHJvbEl0ZW1Tb246OkNvbnRyb2xJdGVtU29uKGNvbnN0IFN0cmluZyAmTmFtZSwgY29uc3QgU3RyaW5nICZVUkwsIGNvbnN0IFVSTFR5cGUgYVR5cGUgKQo6IENvbnRyb2xJdGVtKCBOYW1lLCBVUkwsIGFUeXBlICkKe30KCkNvbnRyb2xJdGVtU29uOjpDb250cm9sSXRlbVNvbihjb25zdCBTdHJpbmcgJk5hbWUsIGNvbnN0IFN0cmluZyAmVVJMLCBjb25zdCBzYWxfdUxvbmcgblVJZCApCjogQ29udHJvbEl0ZW0oIE5hbWUsIFVSTCwgblVJZCApCnt9CgpDb250cm9sSXRlbVNvbjo6Q29udHJvbEl0ZW1Tb24oY29uc3QgY2hhciAqTmFtZSwgY29uc3QgU3RyaW5nICZVUkwsIGNvbnN0IHNhbF91TG9uZyBuVUlkICkKOiBDb250cm9sSXRlbSggTmFtZSwgVVJMLCBuVUlkICkKe30qLwoKCgpzYWxfQm9vbCBDb250cm9sRGVmOjpvcGVyYXRvciA8IChjb25zdCBDb250cm9sSXRlbSAmclBhcikKewoJcmV0dXJuIHBEYXRhLT5LdXJ6bmFtZS5Db21wYXJlSWdub3JlQ2FzZVRvQXNjaWkoclBhci5wRGF0YS0+S3Vyem5hbWUpID09IENPTVBBUkVfTEVTUzsKfQoKc2FsX0Jvb2wgQ29udHJvbERlZjo6b3BlcmF0b3IgPT0gKGNvbnN0IENvbnRyb2xJdGVtICZyUGFyKQp7CglyZXR1cm4gcERhdGEtPkt1cnpuYW1lLkNvbXBhcmVJZ25vcmVDYXNlVG9Bc2NpaShyUGFyLnBEYXRhLT5LdXJ6bmFtZSkgPT0gQ09NUEFSRV9FUVVBTDsKfQoKdm9pZCBDb250cm9sRGVmOjpXcml0ZSggU3ZTdHJlYW0gJmFTdHJlYW0gKQp7CiAgICAvLyBGSVhNRTogSEVMUElECiAgICAjaWYgMAoJaWYgKCBwU29ucyApCiAgICAJYVN0cmVhbS5Xcml0ZUJ5dGVTdHJpbmcoIFN0cmluZygnKicpLkFwcGVuZCggcERhdGEtPkt1cnpuYW1lICksIFJUTF9URVhURU5DT0RJTkdfVVRGOCApOwoJZWxzZQoJCWFTdHJlYW0uV3JpdGVCeXRlU3RyaW5nKCBwRGF0YS0+S3Vyem5hbWUsIFJUTF9URVhURU5DT0RJTkdfVVRGOCApOwoJYVN0cmVhbSA8PCAoKHNhbF91SW50MTYpcERhdGEtPmFVSWQuSGFzTnVtZXJpYygpKTsKCWlmICggcERhdGEtPmFVSWQuSGFzU3RyaW5nKCkgKQogICAgCWFTdHJlYW0uV3JpdGVCeXRlU3RyaW5nKCBwRGF0YS0+YVVJZC5HZXRTdHIoKSwgUlRMX1RFWFRFTkNPRElOR19VVEY4ICk7CgllbHNlCiAgICAJYVN0cmVhbSA8PCBzdGF0aWNfY2FzdDxjb21tX1VMT05HPihwRGF0YS0+YVVJZC5HZXROdW0oKSk7IC8vR2V0TnVtKCkgc2FsX3VMb25nICE9IGNvbW1fVUxPTkcgb24gNjRiaXQKCWlmICggcFNvbnMgKQogICAgICAgIGZvciAoIHNhbF91SW50MTYgaSA9IDAgOyBwU29ucy0+Q291bnQoKSA+IGkgOyBpKysgKQogICAgCQkoKENvbnRyb2xEZWYqKSgqcFNvbnMpW2ldKS0+V3JpdGUoYVN0cmVhbSk7CiAgICAjZWxzZQogICAgKHZvaWQpYVN0cmVhbTsKICAgICNlbmRpZgp9CgpDb250cm9sRGVmOjpDb250cm9sRGVmKGNvbnN0IFN0cmluZyAmTmFtZSwgcnRsOjpPU3RyaW5nIGFVSWRQICkKOiBDb250cm9sSXRlbVNvbiggTmFtZSwgYVVJZFApCnsKCURCR19DVE9SKENvbnRyb2xEZWYsMCk7Cn0KCi8qQ29udHJvbERlZjo6Q29udHJvbERlZihjb25zdCBTdHJpbmcgJk5hbWUsIGNvbnN0IFN0cmluZyAmVVJMLCBjb25zdCBVUkxUeXBlIGFUeXBlICkKOiBDb250cm9sSXRlbVNvbiggTmFtZSwgVVJMLCBhVHlwZSApCnsKCURCR19DVE9SKENvbnRyb2xEZWYsMCk7Cn0gKi8KCkNvbnRyb2xEZWY6OkNvbnRyb2xEZWYoY29uc3QgU3RyaW5nICZhT2xkTmFtZSwgY29uc3QgU3RyaW5nICZhTmV3TmFtZSwgQ29udHJvbERlZiAqcE9yaWdpbmFsLCBzYWxfQm9vbCBiV2l0aFNvbnMgKQo6IENvbnRyb2xJdGVtU29uKCIiLCBwT3JpZ2luYWwtPnBEYXRhLT5hVUlkKQp7CglEQkdfQ1RPUihDb250cm9sRGVmLDApOwoJaWYgKCBwT3JpZ2luYWwtPnBEYXRhLT5LdXJ6bmFtZSA9PSBhT2xkTmFtZSApCiAgICAJcERhdGEtPkt1cnpuYW1lID0gYU5ld05hbWU7CgllbHNlCiAgICAJcERhdGEtPkt1cnpuYW1lID0gcE9yaWdpbmFsLT5wRGF0YS0+S3Vyem5hbWU7CgoJaWYgKCBiV2l0aFNvbnMgJiYgcE9yaWdpbmFsLT5wU29ucyApCgl7CiAgICAJcFNvbnMgPSBuZXcgQ05hbWVzKCk7CiAgICAJZm9yICggc2FsX3VJbnQxNiBpID0gMDsgaSA8IHBPcmlnaW5hbC0+cFNvbnMtPkNvdW50KCkgOyBpKyspCiAgICAJewogICAgCQlDb250cm9sRGVmICpwTmV3RGVmOwogICAgCQlwTmV3RGVmID0gbmV3IENvbnRyb2xEZWYoIGFPbGROYW1lLCBhTmV3TmFtZSwgcE9yaWdpbmFsLT5Tb25HZXRPYmplY3QoaSkgLHNhbF9UcnVlICk7CiAgICAJCWlmICghIFNvbkluc2VydChwTmV3RGVmKSkKICAgIAkJewogICAgCQkJREJHX0VSUk9SKCJOYW1lIERvcHBlbHQgaW0gQ29weUNvbnN0cnVjdG9yLiBOZXVlciBOYW1lID0gQ29udHJvbG5hbWUhISIpOwogICAgCQkJZGVsZXRlIHBOZXdEZWY7CiAgICAJCX0KICAgIAl9CgoJfQoJZWxzZQogICAgCXBTb25zID0gTlVMTDsKfQoKc2FsX0Jvb2wgQ29udHJvbEl0ZW1VSWQ6Om9wZXJhdG9yIDwgKGNvbnN0IENvbnRyb2xJdGVtICZyUGFyKQp7CglyZXR1cm4gcERhdGEtPmFVSWQgPCByUGFyLnBEYXRhLT5hVUlkOwp9CgpzYWxfQm9vbCBDb250cm9sSXRlbVVJZDo6b3BlcmF0b3IgPT0gKGNvbnN0IENvbnRyb2xJdGVtICZyUGFyKQp7CglyZXR1cm4gcERhdGEtPmFVSWQgPT0gclBhci5wRGF0YS0+YVVJZDsKfQoKU1ZfSU1QTF9PUF9QVFJBUlJfU09SVCggQ05hbWVzLCBDb250cm9sSXRlbSogKQoKdm9pZCBDUmV2TmFtZXM6Okluc2VydCggU3RyaW5nIGFOYW1lLCBydGw6Ok9TdHJpbmcgYVVJZCwgc2FsX3VMb25nIG5TZXEgKQp7CglDb250cm9sSXRlbSAqcFJOID0gbmV3IFJldmVyc2VOYW1lKGFOYW1lLGFVSWQsblNlcSk7CglzYWxfdUludDE2IG5Qb3M7CglpZiAoIFNlZWtfRW50cnkocFJOLCZuUG9zKSApCiAgICAJRGVsZXRlQW5kRGVzdHJveShuUG9zKTsKCglpZiAoICFDTmFtZXM6OkM0MF9QVFJfSU5TRVJUKCBDb250cm9sSXRlbSwgcFJOKSApCgl7CiAgICAJREJHX0VSUk9SKCJJbnRlcm5lciBGZWhsZXIgYmVpbSBTcGVpY2hlcm4gZGVyIExva2FsZW4gS3Vyek5hbWVuIik7CiAgICAJZGVsZXRlIHBSTjsKCX0KCn0KClN0cmluZyBDUmV2TmFtZXM6OkdldE5hbWUoIHJ0bDo6T1N0cmluZyBhVUlkICkKewoJUmV2ZXJzZU5hbWUgKnBSTiA9IG5ldyBSZXZlcnNlTmFtZShVbmlTdHJpbmcoKSxhVUlkLDApOwoJc2FsX3VJbnQxNiBuUG9zOwoJc2FsX0Jvb2wgYlNlZWtPSyA9IFNlZWtfRW50cnkocFJOLCZuUG9zKTsKCglkZWxldGUgcFJOOwoJaWYgKCBiU2Vla09LICkKICAgIAlyZXR1cm4gR2V0T2JqZWN0KG5Qb3MpLT5wRGF0YS0+S3Vyem5hbWU7CgllbHNlCgl7CgkgICAgLy8gRklYTUU6IEhFTFBJRAoJICAgICNpZiAwCiAgICAJaWYgKCBhVUlkLk1hdGNoZXMoIFVJRF9BQ1RJVkUgKSApCiAgICAJCXJldHVybiBDVW5pU3RyaW5nKCJBY3RpdmUiKTsKICAgIAllbHNlCiAgICAJCXJldHVybiBHRU5fUkVTX1NUUjEoIFNfTkFNRV9OT1RfVEhFUkUsIGFVSWQuR2V0VGV4dCgpICk7CiAgICAJI2Vsc2UKICAgICAgICByZXR1cm4gU3RyaW5nKCk7CiAgICAgICAgI2VuZGlmCgl9Cn0KCnZvaWQgQ1Jldk5hbWVzOjpJbnZhbGlkYXRlICggc2FsX3VMb25nIG5TZXEgKQp7CglzYWxfdUludDE2IGk7Cglmb3IgKGkgPSAwOyBpIDwgQ291bnQoKSA7KQoJewogICAgCWlmICgoKFJldmVyc2VOYW1lKilHZXRPYmplY3QoaSkpLT5MYXN0U2VxdWVuY2UgPCBuU2VxKQogICAgCQlEZWxldGVBbmREZXN0cm95KGkpOwogICAgCWVsc2UKICAgIAkJaSsrOwoJfQp9CgoKU1ZfSU1QTF9QVFJBUlIoQ0Vycm9ycywgRXJyb3JFbnRyeSopCgoKU2J4VHJhbnNwb3J0TWV0aG9kOjpTYnhUcmFuc3BvcnRNZXRob2QoIFNieERhdGFUeXBlIERUICkKOiBTYnhNZXRob2QoQ1VuaVN0cmluZygiRHVtbXkiKSxEVCkKewoJblZhbHVlID0gMDsKfQoKClRlc3RUb29sT2JqOjpUZXN0VG9vbE9iaiggU3RyaW5nIGFOYW1lLCBTdHJpbmcgYUZpbGVQYXRoICkgICAgICAgICAgICAgIC8vIEludGVybmVyIEF1ZnJ1Zgo6IFNieE9iamVjdCggYU5hbWUgKQosIGJVc2VJUEMoc2FsX0ZhbHNlKQosIGJSZXR1cm5PSyhzYWxfVHJ1ZSkKLCBuU2VxdWVuY2UoS0VFUF9TRVFVRU5DRVMpCiwgUHJvZ1BhdGgoKQosIElzQmxvY2soc2FsX0ZhbHNlKQosIFNpbmdsZUNvbW1hbmRCbG9jayhzYWxfVHJ1ZSkKLCBtX3BDb250cm9scyhOVUxMKQosIG1fcE5hbWVLb250ZXh0KE5VTEwpCiwgbV9wU0lkcyhOVUxMKQosIG1fcFJldmVyc2VTbG90cyhOVUxMKQosIG1fcFJldmVyc2VDb250cm9scyhOVUxMKQosIG1fcFJldmVyc2VDb250cm9sc1NvbihOVUxMKQosIG1fcFJldmVyc2VVSWRzKE5VTEwpCiwgcENvbW11bmljYXRpb25NYW5hZ2VyKE5VTEwpCiwgYURpYWxvZ0hhbmRsZXJOYW1lKCkKLCBuV2luZG93SGFuZGxlckNhbGxMZXZlbCgwKQosIG5JZGxlQ291bnQoMCkKewoJcEltcGwgPSBuZXcgSW1wbFRlc3RUb29sT2JqOwoJcEltcGwtPlByb2dQYXJhbSA9IFN0cmluZygpOwoJcEltcGwtPmFGaWxlQmFzZSA9IERpckVudHJ5KGFGaWxlUGF0aCk7Ci8vCXBJbXBsLT5hTG9nRmlsZUJhc2UgPSBEaXJFbnRyeSgpOwoJcEltcGwtPmFISUREaXIgPSBEaXJFbnRyeShhRmlsZVBhdGgpOwogICAgcEltcGwtPmJJc1N0YXJ0ID0gc2FsX0ZhbHNlOwogICAgcEltcGwtPnBNeUJhc2ljID0gTlVMTDsKCglwSW1wbC0+YVNlcnZlclRpbWVvdXQgPSBUaW1lKDAsMSwwMCk7ICAgICAgICAgICAvLyAxOjAwIE1pbnV0ZW4gZmVzdAoJSW5pdFRlc3RUb29sT2JqKCk7Cn0KClRlc3RUb29sT2JqOjpUZXN0VG9vbE9iaiggU3RyaW5nIGFOYW1lLCBNeUJhc2ljKiBwQmFzICkgICAgICAgICAgICAgICAgLy8gQXVmcnVmIGltIFRlc3R0b29sCjogU2J4T2JqZWN0KCBhTmFtZSApCiwgYlVzZUlQQyhzYWxfVHJ1ZSkKLCBiUmV0dXJuT0soc2FsX1RydWUpCiwgblNlcXVlbmNlKEtFRVBfU0VRVUVOQ0VTKQosIFByb2dQYXRoKCkKLCBJc0Jsb2NrKHNhbF9GYWxzZSkKLCBTaW5nbGVDb21tYW5kQmxvY2soc2FsX1RydWUpCiwgbV9wQ29udHJvbHMoTlVMTCkKLCBtX3BOYW1lS29udGV4dChOVUxMKQosIG1fcFNJZHMoTlVMTCkKLCBtX3BSZXZlcnNlU2xvdHMoTlVMTCkKLCBtX3BSZXZlcnNlQ29udHJvbHMoTlVMTCkKLCBtX3BSZXZlcnNlQ29udHJvbHNTb24oTlVMTCkKLCBtX3BSZXZlcnNlVUlkcyhOVUxMKQosIHBDb21tdW5pY2F0aW9uTWFuYWdlcihOVUxMKQosIGFEaWFsb2dIYW5kbGVyTmFtZSgpCiwgbldpbmRvd0hhbmRsZXJDYWxsTGV2ZWwoMCkKLCBuSWRsZUNvdW50KDApCnsKCXBJbXBsID0gbmV3IEltcGxUZXN0VG9vbE9iajsKCXBJbXBsLT5Qcm9nUGFyYW0gPSBTdHJpbmcoKTsKICAgIHBJbXBsLT5iSXNTdGFydCA9IHNhbF9GYWxzZTsKICAgIHBJbXBsLT5wTXlCYXNpYyA9IHBCYXM7CgoJTG9hZEluaUZpbGUoKTsKCUluaXRUZXN0VG9vbE9iaigpOwoKCXBDb21tdW5pY2F0aW9uTWFuYWdlciA9IG5ldyBDb21tdW5pY2F0aW9uTWFuYWdlckNsaWVudFZpYVNvY2tldFRUKCk7CglwQ29tbXVuaWNhdGlvbk1hbmFnZXItPlNldERhdGFSZWNlaXZlZEhkbCggTElOSyggdGhpcywgVGVzdFRvb2xPYmosIFJldHVyblJlc3VsdHNMaW5rICkpOwp9Cgp2b2lkIFRlc3RUb29sT2JqOjpMb2FkSW5pRmlsZSgpCQkJCS8vIExhZGVuIGRlciBJbmlFaW5zdGVsbHVuZ2VuLCBkaWUgZHVyY2ggZGVuIENvbmZpZ0RpYWxvZyBnZe+/vW5kZXJ0IHdlcmRlbiBr77+9bm5lbgp7CiNkZWZpbmUgR0VUU0VUKGFWYXIsIEtleU5hbWUsIERhZmF1bHQpCQkJCQkJCVwKCXsJCQkJCQkJCQkJCQkJCQlcCiAgICAJQnl0ZVN0cmluZyBfXyMjYVZhciMjX187CQkJCQkJCQlcCiAgICAJX18jI2FWYXIjI19fID0gYUNvbmYuUmVhZEtleShLZXlOYW1lKTsJCVwKICAgIAlpZiAoICFfXyMjYVZhciMjX18uTGVuKCkgKQkJCQkJXAogICAgCXsJCQkJCQkJCQkJCQkJCVwKICAgIAkJX18jI2FWYXIjI19fID0gRGFmYXVsdDsJCQkJCQkJCVwKICAgIAkJYUNvbmYuV3JpdGVLZXkoS2V5TmFtZSwgX18jI2FWYXIjI19fKTsJCQkJXAogICAgCX0JCQkJCQkJCQkJCQkJCVwKICAgIAlhVmFyID0gVW5pU3RyaW5nKCBfXyMjYVZhciMjX18sIFJUTF9URVhURU5DT0RJTkdfVVRGOCApO1wKCX0KCiNkZWZpbmUgTkVXT0xEKCBOZXdLZXksIE9sZEtleSApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIEJ5dGVTdHJpbmcgYVZhbHVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgaWYgKCAoIChhVmFsdWUgPSBhQ29uZi5SZWFkS2V5KCBPbGRLZXkgKSkuTGVuKCkgKSAmJiAhYUNvbmYuUmVhZEtleSggTmV3S2V5ICkuTGVuKCkgKSAgIFwKICAgICAgICAgICAgYUNvbmYuV3JpdGVLZXkoIE5ld0tleSwgYVZhbHVlICk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgfQoKCglDb25maWcgYUNvbmYoQ29uZmlnOjpHZXRDb25maWdOYW1lKCBDb25maWc6OkdldERlZkRpcmVjdG9yeSgpLCBDVW5pU3RyaW5nKCJ0ZXN0dG9vbCIpICkpOwoJYUNvbmYuU2V0R3JvdXAoIk1pc2MiKTsKICAgIEJ5dGVTdHJpbmcgYUN1cnJlbnRQcm9maWxlID0gYUNvbmYuUmVhZEtleSggIkN1cnJlbnRQcm9maWxlIiwgIlBhdGgiICk7CiAgICBhQ29uZi5TZXRHcm91cCggYUN1cnJlbnRQcm9maWxlICk7CgogICAgTkVXT0xEKCAiQmFzZURpciIsICJCYXNpc3ZlcnplaWNobmlzIiApCglTdHJpbmcgYUZCOwoJR0VUU0VUKCBhRkIsICJCYXNlRGlyIiwgIiIgKTsKCXBJbXBsLT5hRmlsZUJhc2UgPSBEaXJFbnRyeShhRkIpOwoKICAgIC8vIHJlbW92ZSBvbGQga2V5cwoJaWYgKCBhQ29uZi5SZWFkS2V5KCJLZXlDb2RlcyArIENsYXNzZXMiKS5MZW4oKSAhPSAwIHx8CiAgICAJIGFDb25mLlJlYWRLZXkoIktleUNvZGVzICsgQ2xhc3NlcyArIFJlc19UeXBlIikuTGVuKCkgIT0gMCApCgl7CiAgICAJYUNvbmYuRGVsZXRlS2V5KCJLZXlDb2RlcyArIENsYXNzZXMgKyBSZXNfVHlwZSIpOwogICAgCWFDb25mLkRlbGV0ZUtleSgiS2V5Q29kZXMgKyBDbGFzc2VzIik7Cgl9CgogICAgTkVXT0xEKCAiTG9nQmFzZURpciIsICJMb2dCYXNpc3ZlcnplaWNobmlzIiApCglTdHJpbmcgYUxGQjsKCUdFVFNFVCggYUxGQiwgIkxvZ0Jhc2VEaXIiLCBCeXRlU3RyaW5nKCBhRkIsIFJUTF9URVhURU5DT0RJTkdfVVRGOCApICk7CglwSW1wbC0+YUxvZ0ZpbGVCYXNlID0gRGlyRW50cnkoYUxGQik7CgogICAgTkVXT0xEKCAiSElERGlyIiwgIkhJRFZlcnplaWNobmlzIiApCiAgICBTdHJpbmcgYUhJRDsKCUdFVFNFVCggYUhJRCwgIkhJRERpciIsICIiICk7CglwSW1wbC0+YUhJRERpciA9IERpckVudHJ5KGFISUQpOwoKCglhQ29uZi5TZXRHcm91cCgiTWlzYyIpOwoKCVN0cmluZyBhU1Q7CglHRVRTRVQoIGFTVCwgIlNlcnZlclRpbWVvdXQiLCBCeXRlU3RyaW5nOjpDcmVhdGVGcm9tSW50NjQoVGltZSgwLDAsNDUpLkdldFRpbWUoKSkgKTsgICAgIC8vIDQ1IFNla3VuZGVuIEluaXRpYWwKCXBJbXBsLT5hU2VydmVyVGltZW91dCA9IFRpbWUoc2FsX3VMb25nKGFTVC5Ub0ludDY0KCkpKTsKCglTdHJpbmcgYVNPU0U7CiAgICBhQ3VycmVudFByb2ZpbGUgPSBhQ29uZi5SZWFkS2V5KCAiQ3VycmVudFByb2ZpbGUiLCAiTWlzYyIgKTsKICAgIGFDb25mLlNldEdyb3VwKCBhQ3VycmVudFByb2ZpbGUgKTsKCUdFVFNFVCggYVNPU0UsICJTdG9wT25TeW50YXhFcnJvciIsICIwIiApOwoJcEltcGwtPmJTdG9wT25TeW50YXhFcnJvciA9IGFTT1NFLkVxdWFsc0FzY2lpKCIxIik7CgoKCWFDb25mLlNldEdyb3VwKCJHVUkgUGxhdGZvcm0iKTsKCglTdHJpbmcgYUdQOwoJQnl0ZVN0cmluZyBhYkdQOwojaWZkZWYgV05UCiAgICBhYkdQLkFwcGVuZCggIjUwMSIgKTsgIC8vIFdpblhQCiNlbGlmIGRlZmluZWQgU09MQVJJUyAmJiBkZWZpbmVkIFNQQVJDCiAgICBhYkdQLkFwcGVuZCggIjAxIiApOyAgLy8gU29sYXJpcyBTUEFSQwojZWxpZiBkZWZpbmVkIFNDTwogICAgYWJHUC5BcHBlbmQoICIwMiIgKTsgIC8vIFNDTyBVTklYCiNlbGlmIGRlZmluZWQgTElOVVggJiYgZGVmaW5lZCBJTlRFTAogICAgYWJHUC5BcHBlbmQoICIwMyIgKTsgIC8vIExpbnV4CiNlbGlmIGRlZmluZWQgQUlYCiAgICBhYkdQLkFwcGVuZCggIjA0IiApOwojZWxpZiBkZWZpbmVkIFNPTEFSSVMgJiYgZGVmaW5lZCBJTlRFTAogICAgYWJHUC5BcHBlbmQoICIwNSIgKTsgIC8vIFNvbGFyaXMgeDg2CiNlbGlmIGRlZmluZWQgSFBVWAogICAgYWJHUC5BcHBlbmQoICIwNyIgKTsKI2VsaWYgZGVmaW5lZCBGUkVFQlNECiAgICBhYkdQLkFwcGVuZCggIjA4IiApOwojZWxpZiBkZWZpbmVkIE1BQ09TWAogICAgYWJHUC5BcHBlbmQoICIxMiIgKTsKI2VsaWYgZGVmaW5lZCBMSU5VWCAmJiBkZWZpbmVkIFBQQwogICAgYWJHUC5BcHBlbmQoICIxMyIgKTsKI2VsaWYgZGVmaW5lZCBORVRCU0QKICAgIGFiR1AuQXBwZW5kKCAiMTQiICk7CiNlbGlmIGRlZmluZWQgTElOVVggJiYgZGVmaW5lZCBYODZfNjQKICAgIGFiR1AuQXBwZW5kKCAiMTUiICk7ICAvLyBMaW51eCB4ODYtNjQKI2VsaWYgZGVmaW5lZCBMSU5VWCAmJiBkZWZpbmVkIFNQQVJDCiAgICBhYkdQLkFwcGVuZCggIjE2IiApOyAgLy8gTGludXggU1BBUkMKI2VsaWYgZGVmaW5lZCBPUzIKICAgIGFiR1AuQXBwZW5kKCAiMTciICk7CiNlbGlmIGRlZmluZWQgTElOVVggJiYgZGVmaW5lZCBNSVBTCiAgICBhYkdQLkFwcGVuZCggIjE4IiApOyAgLy8gTGludXggTUlQUwojZWxpZiBkZWZpbmVkIExJTlVYICYmIGRlZmluZWQgQVJNCiAgICBhYkdQLkFwcGVuZCggIjE5IiApOyAgLy8gTGludXggQVJNCiNlbGlmIGRlZmluZWQgTElOVVggJiYgZGVmaW5lZCBJQTY0CiAgICBhYkdQLkFwcGVuZCggIjIwIiApOyAgLy8gTGludXggaWE2NAojZWxpZiBkZWZpbmVkIExJTlVYICYmIGRlZmluZWQgUzM5MAogICAgYWJHUC5BcHBlbmQoICIyMSIgKTsgIC8vIExpbnV4IFMzOTAKI2VsaWYgZGVmaW5lZCBMSU5VWCAmJiBkZWZpbmVkIEhQUEEKICAgIGFiR1AuQXBwZW5kKCAiMjIiICk7ICAvLyBMaW51eCBQQS1SSVNDCiNlbGlmIGRlZmluZWQgTElOVVggJiYgZGVmaW5lZCBBWFAKICAgIGFiR1AuQXBwZW5kKCAiMjMiICk7ICAvLyBMaW51eCBBTFBIQQojZWxzZQojZXJyb3IgKCJ1bmtub3duIHBsYXRmb3JtLiBwbGVhc2UgcmVxdWVzdCBhbiBJRCBmb3IgeW91ciBwbGF0Zm9ybSBvbiBxYS9kZXYiKQojZW5kaWYKICAgIEdFVFNFVCggYUdQLCAiQ3VycmVudCIsIGFiR1AgKTsKCi8vICNpNjg4MDQjIFdyaXRlIGRlZmF1bHQgQ29tbXVuaWNhdGlvbiBzZWN0aW9uIHRvIHRlc3R0b29scmMvLmluaQovLyAgdGhpcyBpcyBub3QgZmFzdGVzdCBidXQgdG9vIGtlZXAgZGVmYXVsdHNldHRpbmdzIGluIG9uZSBwbGFjZSBpbiB0aGUgY29kZQogICAgR2V0SG9zdENvbmZpZygpOwogICAgR2V0VFRQb3J0Q29uZmlnKCk7CiAgICBHZXRVbm9Qb3J0Q29uZmlnKCk7Cn0KCiNkZWZpbmUgTUFLRV9UVF9LRVlXT1JEKCBjTmFtZSwgYVR5cGUsIGFSZXN1bHRUeXBlLCBuSUQgKSAgICAgICAgICAgICAgICAgICAgICAgXAp7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKCVNieFZhcmlhYmxlUmVmIHBNZXRoOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCglwTWV0aCA9IE1ha2UoIENVbmlTdHJpbmcoY05hbWUpLCBhVHlwZSwgYVJlc3VsdFR5cGUgKTsgICAgICAgICAgICAgICAgICAgICAgXAoJcE1ldGgtPlNldFVzZXJEYXRhKCBuSUQgKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKfQoKLy8gU2V0VXNlckRhdGEgbXXfIGlyZ2VuZHdhcyBzZWluLCBzb25zdCB3aXJkIGVzIGltIEZpbmQgcmF1c2dlZmlsdGVydCEhIQojZGVmaW5lIE1BS0VfVVNIT1JUX0NPTlNUQU5UKGNOYW1lLCBuVmFsdWUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKCXsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAJU2J4UHJvcGVydHkgKnBWYWwgPSBuZXcgU2J4UHJvcGVydHkoIENVbmlTdHJpbmcoIGNOYW1lKSAsIFNieElOVEVHRVIgKTsgXAogICAgCXBWYWwtPlB1dEludGVnZXIoIG5WYWx1ZSApIDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIAlwVmFsLT5TZXRVc2VyRGF0YSggMzIwMDAgKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAJSW5zZXJ0KCBwVmFsICk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoJfQoKI2RlZmluZSBSVExOQU1FICJAU0JSVEwiICAgIC8vIGNvcGllZCBmcm9tIGJhc2ljL3NvdXJjZS9jbGFzc2VzL3NiLmN4eAoKdm9pZCBUZXN0VG9vbE9iajo6SW5pdFRlc3RUb29sT2JqKCkKewoJcEltcGwtPm5OdW1Cb3JkZXJzID0gMDsJCQkJCS8vIEbvv71yIFByb2ZpbGluZyBtaXQga++/vXN0Y2hlbgoKCXBJbXBsLT5uTWluUmVtb3RlQ29tbWFuZERlbGF5ID0gMDsKCXBJbXBsLT5uTWF4UmVtb3RlQ29tbWFuZERlbGF5ID0gMDsKCXBJbXBsLT5iRG9SZW1vdGVDb21tYW5kRGVsYXkgPSBzYWxfRmFsc2U7CgoJcEltcGwtPmJMbmFndWFnZUV4dGVuc2lvbkxvYWRlZD0gc2FsX0ZhbHNlOwoJcEltcGwtPnBUVFNmeEJyb2FkY2FzdGVyID0gTlVMTDsKCglwSW1wbC0+bkVycm9yQ291bnQgPSAwOwoJcEltcGwtPm5XYXJuaW5nQ291bnQgPSAwOwogICAgcEltcGwtPm5RQUVycm9yQ291bnQgPSAwOwoJcEltcGwtPm5JbmNsdWRlRmlsZVdhcm5pbmdDb3VudCA9IDA7CgogICAgcEltcGwtPnhFcnJvckxpc3QgPSBuZXcgU2J4RGltQXJyYXkoIFNieFNUUklORyApOwogICAgcEltcGwtPnhXYXJuaW5nTGlzdCA9IG5ldyBTYnhEaW1BcnJheSggU2J4U1RSSU5HICk7CiAgICBwSW1wbC0+eFFBRXJyb3JMaXN0ID0gbmV3IFNieERpbUFycmF5KCBTYnhTVFJJTkcgKTsKICAgIHBJbXBsLT54SW5jbHVkZUZpbGVXYXJuaW5nTGlzdCA9IG5ldyBTYnhEaW1BcnJheSggU2J4U1RSSU5HICk7CgogICAgcEltcGwtPm5UZXN0Q2FzZUxpbmVOciA9IDA7CgogICAgcEltcGwtPmJFbmFibGVRYUVycm9ycyA9IHNhbF9UcnVlOwogICAgcEltcGwtPmJEZWJ1Z0ZpbmROb0Vycm9ycyA9IHNhbF9GYWxzZTsKCiAgICBwSW1wbC0+cENoaWxkRW52ID0gbmV3IEVudmlyb25tZW50OwoKICAgIGlmICghcEZlaGxlckxpc3RlKQoJICAgIHBGZWhsZXJMaXN0ZSA9IG5ldyBDRXJyb3JzOyAgICAgICAgICAgICAvLyBWb3IgYWxsZW0gYW5kZXJlbi4gV2VyIHdlaXNzLCB3ZXIgYWxsZXMgZWluZW4gRmVobGVyIGF1c2zvv71zdC4KCglJbiA9IG5ldyBDbWRTdHJlYW0oKTsKCglwU2hvcnROYW1lcyA9IG5ldyBDUmV2TmFtZXM7CgogICAgcEltcGwtPnBIdHRwUmVxdWVzdCA9IE5VTEw7CgovLyBvdmVyd3JpdGUgc3RhbmRhcmQgIndhaXQiIG1ldGhvZCwgY2F1c2Ugd2UgY2FuIGRvIGJldHRlciB0aGFuIHRoYXQhIQovLyBJbnNlcnQgT2JqZWN0IGludG8gU2JpU3RkT2JqZWN0IGJ1dCBjaGFuZ2UgbGlzdGVuaW5nLgoJU2J4VmFyaWFibGUqIHBSVEwgPSBwSW1wbC0+cE15QmFzaWMtPkZpbmQoIENVbmlTdHJpbmcoUlRMTkFNRSksIFNieENMQVNTX0RPTlRDQVJFICk7CiAgICBTYnhPYmplY3QqIHBSVExPYmplY3QgPSBQVFJfQ0FTVCggU2J4T2JqZWN0LCBwUlRMICk7CiAgICBpZiAoIHBSVExPYmplY3QgKQogICAgewogICAgICAgIFNieFZhcmlhYmxlUmVmIHBXYWl0OwoJICAgIHBXYWl0ID0gcFJUTE9iamVjdC0+TWFrZSggQ1VuaVN0cmluZygiV2FpdCIpLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwgKTsKCSAgICBwV2FpdC0+U2V0VXNlckRhdGEoIElEX1dhaXQgKTsKICAgIC8vIGNoYW5nZSBsaXN0ZW5lciBoZXJlCiAgICAgICAgcFJUTE9iamVjdC0+RW5kTGlzdGVuaW5nKCBwV2FpdC0+R2V0QnJvYWRjYXN0ZXIoKSwgc2FsX1RydWUgKTsKICAgICAgICBTdGFydExpc3RlbmluZyggcFdhaXQtPkdldEJyb2FkY2FzdGVyKCksIHNhbF9UcnVlICk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgREJHX0VSUk9SKCJUZXN0dG9vbDogQ291bGQgbm90IHJlcGxhY2UgV2FpdCBtZXRob2QiKTsKICAgIH0KCiAgICBNQUtFX1RUX0tFWVdPUkQoICJLb250ZXh0IiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhOVUxMLCBJRF9Lb250ZXh0ICk7CglNQUtFX1RUX0tFWVdPUkQoICJHZXROZXh0RXJyb3IiLCBTYnhDTEFTU19WQVJJQUJMRSwgU2J4VkFSSUFOVCwgSURfR2V0RXJyb3IgKTsKCU1BS0VfVFRfS0VZV09SRCggIlN0YXJ0IiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhTVFJJTkcsIElEX1N0YXJ0ICk7Ci8vCQlwTWV0aCA9IE1ha2UoICJLaWxsIiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhOVUxMICk7Ci8vCQlwTWV0aC0+U2V0VXNlckRhdGEoIElEX0tpbGwgKTsKCS8qICAgICAgcE1ldGggPSBNYWtlKCAiVGVzdFJlc2V0IiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhOVUxMICk7CiAgICAJcE1ldGgtPlNldFVzZXJEYXRhKCBJRF9SZXNldCApOyovCglNQUtFX1RUX0tFWVdPUkQoICJVc2UiLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwsIElEX1VzZSApOwoJTUFLRV9UVF9LRVlXT1JEKCAiU3RhcnRVc2UiLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwsIElEX1N0YXJ0VXNlICk7CglNQUtFX1RUX0tFWVdPUkQoICJGaW5pc2hVc2UiLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwsIElEX0ZpbmlzaFVzZSApOwoKCU1BS0VfVFRfS0VZV09SRCggIkNhc2VMb2ciLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwsIElEX0Nhc2VMb2cgKTsKCU1BS0VfVFRfS0VZV09SRCggIkV4Y2VwdExvZyIsIFNieENMQVNTX01FVEhPRCwgU2J4TlVMTCwgSURfRXhjZXB0TG9nICk7CglNQUtFX1RUX0tFWVdPUkQoICJQcmludExvZyIsIFNieENMQVNTX01FVEhPRCwgU2J4TlVMTCwgSURfUHJpbnRMb2cgKTsKCU1BS0VfVFRfS0VZV09SRCggIldhcm5Mb2ciLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwsIElEX1dhcm5Mb2cgKTsKCU1BS0VfVFRfS0VZV09SRCggIkVycm9yTG9nIiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhOVUxMLCBJRF9FcnJvckxvZyApOwoJTUFLRV9UVF9LRVlXT1JEKCAiUUFFcnJvckxvZyIsIFNieENMQVNTX01FVEhPRCwgU2J4TlVMTCwgSURfUUFFcnJvckxvZyApOwoJTUFLRV9UVF9LRVlXT1JEKCAiRW5hYmxlUWFFcnJvcnMiLCBTYnhDTEFTU19QUk9QRVJUWSwgU2J4Qk9PTCwgSURfRW5hYmxlUWFFcnJvcnMgKTsKICAgIE1BS0VfVFRfS0VZV09SRCggIk1heWJlQWRkRXJyIiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhOVUxMLCBJRF9NYXliZUFkZEVyciApOwoJTUFLRV9UVF9LRVlXT1JEKCAiQ2xlYXJFcnJvciIsIFNieENMQVNTX01FVEhPRCwgU2J4TlVMTCwgSURfQ2xlYXJFcnJvciApOwoJTUFLRV9UVF9LRVlXT1JEKCAiU2F2ZUlEcyIsIFNieENMQVNTX01FVEhPRCwgU2J4Qk9PTCwgSURfU2F2ZUlEcyApOwoJTUFLRV9UVF9LRVlXT1JEKCAiQXV0b0V4ZWN1dGUiLCBTYnhDTEFTU19QUk9QRVJUWSwgU2J4Qk9PTCwgSURfQXV0b0V4ZWN1dGUgKTsJLy8gQWNodHVuZyEgUFJPUEVSVFkgQWxzbyBlaW5lIFZhcmlhYmxlCglNQUtFX1RUX0tFWVdPUkQoICJFeGVjdXRlIiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhOVUxMLCBJRF9FeGVjdXRlICk7CglNQUtFX1RUX0tFWVdPUkQoICJTdG9wT25TeW50YXhFcnJvciIsIFNieENMQVNTX1BST1BFUlRZLCBTYnhCT09MLCBJRF9TdG9wT25TeW50YXhFcnJvciApOwoKLyoJRGlhbG9nIEhhbmRsZXIgd2VyZGVuIGdlYnJhdWNodCwgd2VubiBpbSBpbnRlcm5lbiBUZXN0dG9vbCBlaW4gRGlhbG9nCglob2NoZ2VyaXNzZW4gd2lyZC4gTmFjaCB2ZXJzZW5kZW4gZGVyIFJlbW90ZS1Lb21tYW5kb3Mgd2lyZCBJZGxlSGFuZGxlciBha3RpdmllcnQuCglFciB0ZXN0ZXQsIG9iIGRhcyBSZXNjaGVkdWxlIHp1bSBXYWl0Rm9yQW5zd2VyIHp1cu+/vWNra2VocnQuIEJsZWlidCBkYXMgYXVzLCBzbwoJd2lyZCBlcnN0IGRlciBSZW1vdGVIYW5kbGVyIHp1cu+/vWNrZ2VzZXR6dCB1bmQgZGFubiBkaWUgSGFuZGxlci1TdWIgaW0gQmFzaWMKCWdlcnVmZW4uKEVudGtvcHBlbHQg77+9YmVyIFBvc3RVc2VyRXZlbnQuKQoKCUluIHJldHVybmRhdGVuX3ZlcmFyYmVpdGVuIHdpcmQgZmxhZyBm77+9ciBhdXNm77+9aHJ1bmcgZGVzIG7vv71jaHN0ZW4gcmVtb3RlLWJlZmVobHMKCXLvv71ja2dlc2V0enQuIERlciBIYW5kbGVyIHdpcmQgZGFtaXQgYXVjaCBlbnR3ZXJ0ZXQuIEVyIGdpbHQgYWxzbyBudXIgZu+/vXIgZGVuCglu77+9Y2hzdGVuIFJlbW90ZWJlZmVobC4KKi8KCU1BS0VfVFRfS0VZV09SRCggIkRpYWxvZ0hhbmRsZXIiLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwsIElEX0RpYWxvZ0hhbmRsZXIgKTsKCglNQUtFX1RUX0tFWVdPUkQoICJHZXRVbm9BcHAiLCBTYnhDTEFTU19NRVRIT0QsIFNieE9CSkVDVCwgSURfR2V0VW5vQXBwICk7CglNQUtFX1RUX0tFWVdPUkQoICJHZXRJU2VydmVyIiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhPQkpFQ1QsIElEX0dldElTZXJ2ZXIgKTsKCglNQUtFX1RUX0tFWVdPUkQoICJSZW1vdGVDb21tYW5kRGVsYXkiLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwsIElEX1JlbW90ZUNvbW1hbmREZWxheSApOwoKICAgCU1BS0VfVFRfS0VZV09SRCggIkdldEFwcGxpY2F0aW9uUGF0aCIsIFNieENMQVNTX01FVEhPRCwgU2J4U1RSSU5HLCBJRF9HZXRBcHBsaWNhdGlvblBhdGggKTsKICAgCU1BS0VfVFRfS0VZV09SRCggIkdldENvbW1vbkFwcGxpY2F0aW9uUGF0aCIsIFNieENMQVNTX01FVEhPRCwgU2J4U1RSSU5HLCBJRF9HZXRDb21tb25BcHBsaWNhdGlvblBhdGggKTsKICAgCU1BS0VfVFRfS0VZV09SRCggIk1ha2VJbmlGaWxlTmFtZSIsIFNieENMQVNTX01FVEhPRCwgU2J4U1RSSU5HLCBJRF9NYWtlSW5pRmlsZU5hbWUgKTsKCi8vLyBhY3RpdmUgY29uc3RhbnRzIHJldHVybmluZyBlcnJvciBhbmQgd2FybmluZyBjb3VudAoJTUFLRV9UVF9LRVlXT1JEKCAiR2V0RXJyb3JDb3VudCIsIFNieENMQVNTX01FVEhPRCwgU2J4VUxPTkcsIElEX0dldEVycm9yQ291bnQgKTsKCU1BS0VfVFRfS0VZV09SRCggIkdldFdhcm5pbmdDb3VudCIsIFNieENMQVNTX01FVEhPRCwgU2J4VUxPTkcsIElEX0dldFdhcm5pbmdDb3VudCApOwoJTUFLRV9UVF9LRVlXT1JEKCAiR2V0UUFFcnJvckNvdW50IiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhVTE9ORywgSURfR2V0UUFFcnJvckNvdW50ICk7CglNQUtFX1RUX0tFWVdPUkQoICJHZXRVc2VGaWxlV2FybmluZ0NvdW50IiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhVTE9ORywgSURfR2V0VXNlRmlsZVdhcm5pbmdDb3VudCApOwoKCU1BS0VfVFRfS0VZV09SRCggIkdldEVycm9yTGlzdCIsIFNieENMQVNTX01FVEhPRCwgU2J4T0JKRUNULCBJRF9HZXRFcnJvckxpc3QgKTsKCU1BS0VfVFRfS0VZV09SRCggIkdldFdhcm5pbmdMaXN0IiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhPQkpFQ1QsIElEX0dldFdhcm5pbmdMaXN0ICk7CglNQUtFX1RUX0tFWVdPUkQoICJHZXRRQUVycm9yTGlzdCIsIFNieENMQVNTX01FVEhPRCwgU2J4T0JKRUNULCBJRF9HZXRRQUVycm9yTGlzdCApOwoJTUFLRV9UVF9LRVlXT1JEKCAiR2V0VXNlRmlsZVdhcm5pbmdMaXN0IiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhPQkpFQ1QsIElEX0dldFVzZUZpbGVXYXJuaW5nTGlzdCApOwoKCU1BS0VfVFRfS0VZV09SRCggIkdldFRlc3RDYXNlTmFtZSIsIFNieENMQVNTX01FVEhPRCwgU2J4U1RSSU5HLCBJRF9HZXRUZXN0Q2FzZU5hbWUgKTsKCU1BS0VfVFRfS0VZV09SRCggIkdldFRlc3RDYXNlRmlsZU5hbWUiLCBTYnhDTEFTU19NRVRIT0QsIFNieFNUUklORywgSURfR2V0VGVzdENhc2VGaWxlTmFtZSApOwoJTUFLRV9UVF9LRVlXT1JEKCAiR2V0VGVzdENhc2VMaW5lTnIiLCBTYnhDTEFTU19NRVRIT0QsIFNieFVTSE9SVCwgSURfR2V0VGVzdENhc2VMaW5lTnIgKTsKCglNQUtFX1RUX0tFWVdPUkQoICJTZXRDaGlsZEVudiIsIFNieENMQVNTX01FVEhPRCwgU2J4TlVMTCwgSURfU2V0Q2hpbGRFbnYgKTsKCU1BS0VfVFRfS0VZV09SRCggIkdldENoaWxkRW52IiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhTVFJJTkcsIElEX0dldENoaWxkRW52ICk7CgoJTUFLRV9UVF9LRVlXT1JEKCAiR2V0TGlua0Rlc3RpbmF0aW9uIiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhTVFJJTkcsIElEX0dldExpbmtEZXN0aW5hdGlvbiApOwogICAgTUFLRV9UVF9LRVlXT1JEKCAiR2V0UmVnaXN0cnlWYWx1ZSIsIFNieENMQVNTX01FVEhPRCwgU2J4U1RSSU5HLCBJRF9HZXRSZWdpc3RyeVZhbHVlICk7CgogICAgTUFLRV9UVF9LRVlXT1JEKCAiS2lsbEFwcCIsIFNieENMQVNTX01FVEhPRCwgU2J4TlVMTCwgSURfS2lsbEFwcCApOwoKICAgIE1BS0VfVFRfS0VZV09SRCggIkhUVFBTZW5kIiwgU2J4Q0xBU1NfTUVUSE9ELCBTYnhVU0hPUlQsIElEX0hUVFBTZW5kICk7CiAgICBNQUtFX1RUX0tFWVdPUkQoICJIVFRQU2V0UHJveHkiLCBTYnhDTEFTU19NRVRIT0QsIFNieE5VTEwsIElEX0hUVFBTZXRQcm94eSApOwoKICAgIC8vIExvYWQgdGhlIFJlbW90ZSBDb21tYW5kcyBmcm9tIGxpc3QKICAgIGlmICggIXBSQ29tbWFuZHMgKSAgICAgICAgICAgICAgICAgLy8gSXN0IHN0YXRpYywgd2lyZCBhbHNvIG51ciBlaW5tYWwgZ2VsYWRlbgogICAgCVJlYWRGbGF0QXJyYXkoIGFyUl9DbWRzLCBwUkNvbW1hbmRzICk7CglzYWxfdUludDE2IGk7Cglmb3IgKCBpID0gMCA7IGkgPCBwUkNvbW1hbmRzLT5Db3VudCgpIDsgaSsrICkKCXsKICAgIAlTYnhUcmFuc3BvcnRNZXRob2QgKnBNZXRoID0gbmV3IFNieFRyYW5zcG9ydE1ldGhvZCggU2J4VkFSSUFOVCApOwogICAgCXBNZXRoLT5TZXROYW1lKCBwUkNvbW1hbmRzLT5HZXRPYmplY3QoIGkgKS0+cERhdGEtPkt1cnpuYW1lICk7CiAgICAJcE1ldGgtPlNldFVzZXJEYXRhKCBJRF9SZW1vdGVDb21tYW5kICk7CiAgICAJLy8gRklYTUU6IEhFTFBJRAogICAgCSNpZiAwCiAgICAJcE1ldGgtPm5WYWx1ZSA9IHBSQ29tbWFuZHMtPkdldE9iamVjdCggaSApLT5wRGF0YS0+YVVJZC5HZXROdW0oKTsKICAgIAkjZWxzZQogICAgCXBNZXRoLT5uVmFsdWUgPSAwOwogICAgCSNlbmRpZgogICAgCUluc2VydCggcE1ldGggKTsKICAgIAlTdGFydExpc3RlbmluZyggcE1ldGgtPkdldEJyb2FkY2FzdGVyKCksIHNhbF9UcnVlICk7Cgl9CgovLyBLb25zdGFudGVuIGbvv71yIFNldENvbnRyb2xUeXBlCglNQUtFX1VTSE9SVF9DT05TVEFOVCgiQ1RCcm93c2VCb3giLENPTlNUX0NUQnJvd3NlQm94KTsKCU1BS0VfVVNIT1JUX0NPTlNUQU5UKCJDVFZhbHVlU2V0IixDT05TVF9DVFZhbHVlU2V0KTsKCi8vIEtvbnN0YW50ZW4gZu+/vXIgZGFzIEFsaWdubWVudCBkZXMgZ2VzdWNodGVuIFNwbGl0dGVycwoJTUFLRV9VU0hPUlRfQ09OU1RBTlQoIkFsaWduTGVmdCIsQ09OU1RfQUxJR05fTEVGVCk7CglNQUtFX1VTSE9SVF9DT05TVEFOVCgiQWxpZ25Ub3AiLENPTlNUX0FMSUdOX1RPUCk7CglNQUtFX1VTSE9SVF9DT05TVEFOVCgiQWxpZ25SaWdodCIsQ09OU1RfQUxJR05fUklHSFQpOwoJTUFLRV9VU0hPUlRfQ09OU1RBTlQoIkFsaWduQm90dG9tIixDT05TVF9BTElHTl9CT1RUT00pOwoKLy8vIFdoYXQgZGlhbG9nIHRvIHVzZSBpbiBSQ19DbG9zZVN5c0RpYWxvZyBvciBSQ19FeGlzdHNTeXNEaWFsb2cKCU1BS0VfVVNIT1JUX0NPTlNUQU5UKCJGaWxlUGlja2VyIixDT05TVF9GaWxlUGlja2VyKTsKCU1BS0VfVVNIT1JUX0NPTlNUQU5UKCJGb2xkZXJQaWNrZXIiLENPTlNUX0ZvbGRlclBpY2tlcik7CgovLy8gTm9kZVR5cGVzIG9mIHRoZSBTQVggUGFyc2VyCglNQUtFX1VTSE9SVF9DT05TVEFOVCgiTm9kZVR5cGVDaGFyYWN0ZXIiLENPTlNUX05vZGVUeXBlQ2hhcmFjdGVyKTsKCU1BS0VfVVNIT1JUX0NPTlNUQU5UKCJOb2RlVHlwZUVsZW1lbnQiLENPTlNUX05vZGVUeXBlRWxlbWVudCk7CglNQUtFX1VTSE9SVF9DT05TVEFOVCgiTm9kZVR5cGVDb21tZW50IixDT05TVF9Ob2RlVHlwZUNvbW1lbnQpOwoKCi8vLyBJdGVtVHlwZXMgZm9yIFRyZWVMaXN0Qm94IGFuZCBtYXliZSBvdGhlcnMKCU1BS0VfVVNIT1JUX0NPTlNUQU5UKCJJdGVtVHlwZVRleHQiLENPTlNUX0l0ZW1UeXBlVGV4dCk7CglNQUtFX1VTSE9SVF9DT05TVEFOVCgiSXRlbVR5cGVCTVAiLENPTlNUX0l0ZW1UeXBlQk1QKTsKCU1BS0VfVVNIT1JUX0NPTlNUQU5UKCJJdGVtVHlwZUNoZWNrYm94IixDT05TVF9JdGVtVHlwZUNoZWNrYm94KTsKCU1BS0VfVVNIT1JUX0NPTlNUQU5UKCJJdGVtVHlwZUNvbnRleHRCTVAiLENPTlNUX0l0ZW1UeXBlQ29udGV4dEJNUCk7CglNQUtFX1VTSE9SVF9DT05TVEFOVCgiSXRlbVR5cGVVbmtub3duIixDT05TVF9JdGVtVHlwZVVua25vd24pOwoKCi8vLyBSZXR1cm4gdmFsdWVzIGZvciBXYWl0U2xvdAoJTUFLRV9VU0hPUlRfQ09OU1RBTlQoIldTVGltZW91dCIsQ09OU1RfV1NUaW1lb3V0KTsKCU1BS0VfVVNIT1JUX0NPTlNUQU5UKCJXU0Fib3J0ZWQiLENPTlNUX1dTQWJvcnRlZCk7CglNQUtFX1VTSE9SVF9DT05TVEFOVCgiV1NGaW5pc2hlZCIsQ09OU1RfV1NGaW5pc2hlZCk7CgoKCXBJbXBsLT5wQ29udHJvbHNPYmogPSBuZXcgQ29udHJvbHMoIENVbmlTdHJpbmcoIkdldE5leHRDbG9zZVdpbmRvdyIpICk7CglwSW1wbC0+cENvbnRyb2xzT2JqLT5TZXRUeXBlKCBTYnhWQVJJQU5UICk7CiAgICBJbnNlcnQoIHBJbXBsLT5wQ29udHJvbHNPYmogKTsKICAgIHBJbXBsLT5wQ29udHJvbHNPYmotPlNldFVzZXJEYXRhKCBJRF9HZXROZXh0Q2xvc2VXaW5kb3cgKTsKCXBJbXBsLT5wQ29udHJvbHNPYmotPkNoYW5nZUxpc3RlbmVyKCB0aGlzICk7CgoJZm9yICggaT0wO2k8VkFSX1BPT0xfU0laRTtpKyspCgl7Ci8qICAgICAgICAgICAgICBwTXlWYXIgPSBuZXcgU2J4T2JqZWN0KCAiRHVtbXkiICk7CiAgICAJcE15VmFyLT5TZXRUeXBlKCBTYnhWQVJJQU5UICk7Ki8KCi8vICAgICAgICAgICBwTXlWYXIgPSBuZXcgU2J4TWV0aG9kKCAiRHVtbXkiLCBTYnhWQVJJQU5UICk7CgogICAgCXBJbXBsLT5wTXlWYXJzW2ldID0gbmV3IFNieFRyYW5zcG9ydE1ldGhvZCggU2J4VkFSSUFOVCApOwogICAgCXBJbXBsLT5wTXlWYXJzW2ldLT5TZXROYW1lKCBDVW5pU3RyaW5nKCJWYXJEdW1teSIpLkFwcGVuZChTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMihpKSApICk7CgogICAgCUluc2VydCggcEltcGwtPnBNeVZhcnNbaV0gKTsKLy8gICAgICAgICAgICAgIFN0YXJ0TGlzdGVuaW5nKCBwTXlWYXJzW2ldLT5HZXRCcm9hZGNhc3RlcigpLCBzYWxfVHJ1ZSApOwoKCX0KCgltX3BDb250cm9scyA9IG5ldyBDTmFtZXMoKTsKCW1fcFNJZHMgPSBuZXcgQ05hbWVzKCk7CgltX3BOYW1lS29udGV4dCA9IG1fcENvbnRyb2xzOwoKCW5NeVZhciA9IDA7CgoJcEltcGwtPnBNeUJhc2ljLT5BZGRGYWN0b3J5KCAmYUNvbU1hbkZhYyApOwoKCi8vIERhcyBpc3QgenVtIHRlc3RlbiBkZXMgSVBDCgovKiAgICAgIGludCBzZW50ID0gMDsKCglNb2RlbGVzc0RpYWxvZyAqcERsZyA9IG5ldyBNb2RlbGVzc0RpYWxvZyhOVUxMKTsKCXBEbGctPlNldE91dHB1dFNpemVQaXhlbChTaXplKDEwMCwzMCkpOwoKCUVkaXQgKnBNeUVkID0gbmV3IEVkaXQocERsZyxXQl9DRU5URVIgfCBXQl9CT1JERVIpOwoJcE15RWQtPlNldFNpemVQaXhlbChTaXplKDEwMCwzMCkpOwoJcERsZy0+U2hvdygpOwoJcE15RWQtPlNob3coKTsKCVRpbWUgYVRpbWU7CgoJU3RyaW5nIFZvbGxlUGFja3VuZzsKCVZvbGxlUGFja3VuZy5GaWxsKDMyNzYwLCcqJyk7CgoJQmVnaW5CbG9jaygpOyAgIC8vIHp1bSB3YXJtIHdlcmRlbgoJRW5kQmxvY2soKTsKCVJlc2V0RXJyb3IoKTsKCgl3aGlsZSAoIHBEbGctPklzVmlzaWJsZSgpICYmICFJc0Vycm9yKCkgKQoJewogICAgCUJlZ2luQmxvY2soKTsKICAgIAlJbi0+R2VuQ21kRmxvdyAoMTI0LFZvbGxlUGFja3VuZyk7CiAgICAJRW5kQmxvY2soKTsKICAgIAlwTXlFZC0+U2V0VGV4dChTdHJpbmcoIlRlc3QgTnIuICIpICsgU3RyaW5nKCsrc2VudCkpOwogICAgCXdoaWxlICggYVRpbWUuR2V0MTAwU2VjKCkgLyAxMCA9PSBUaW1lKCkuR2V0MTAwU2VjKCkgLyAxMCApOwogICAgCWFUaW1lID0gVGltZSgpOwoJfQoKCWRlbGV0ZSBwTXlFZDsKCWRlbGV0ZSBwRGxnOwoqLwovLyBUZXN0IGVuZGUKCgp9CgpUZXN0VG9vbE9iajo6flRlc3RUb29sT2JqKCkKewoJcEltcGwtPnBNeUJhc2ljLT5SZW1vdmVGYWN0b3J5KCAmYUNvbU1hbkZhYyApOwoJRW5kTGlzdGVuaW5nKCAoKFN0YXJCQVNJQyopR2V0UGFyZW50KCkpLT5HZXRCcm9hZGNhc3RlcigpICk7CglwSW1wbC0+cE5leHRSZXR1cm4uQ2xlYXIoKTsKCglwSW1wbC0+cENvbnRyb2xzT2JqLkNsZWFyKCk7CgoJZm9yICggaW50IGkgPSAwIDsgaSA8IFZBUl9QT09MX1NJWkUgOyBpKysgKQoJewogICAgCXBJbXBsLT5wTXlWYXJzW2ldLkNsZWFyKCk7Cgl9CgoJaWYgKG1fcENvbnRyb2xzKQogICAgCWRlbGV0ZSBtX3BDb250cm9sczsKCWlmIChtX3BSZXZlcnNlU2xvdHMpCiAgICAJZGVsZXRlIG1fcFJldmVyc2VTbG90czsKCWlmIChtX3BSZXZlcnNlQ29udHJvbHMpCiAgICAJZGVsZXRlIG1fcFJldmVyc2VDb250cm9sczsKCWlmIChtX3BSZXZlcnNlQ29udHJvbHNTb24pCiAgICAJZGVsZXRlIG1fcFJldmVyc2VDb250cm9sc1NvbjsKCWlmIChtX3BSZXZlcnNlVUlkcykKICAgIAlkZWxldGUgbV9wUmV2ZXJzZVVJZHM7CglpZiAobV9wU0lkcykKICAgIAlkZWxldGUgbV9wU0lkczsKCWlmIChwRmVobGVyTGlzdGUpCgl7CiAgICAJZGVsZXRlIHBGZWhsZXJMaXN0ZTsKICAgIAlwRmVobGVyTGlzdGUgPSBOVUxMOyAgICAvLyBkYSBwRmVobGVyTGlzdGUgc3RhdGljIGlzdCEhCgl9CglpZiAoIHBDb21tdW5pY2F0aW9uTWFuYWdlciApCgl7CiAgICAJcENvbW11bmljYXRpb25NYW5hZ2VyLT5TdG9wQ29tbXVuaWNhdGlvbigpOwogICAgCWRlbGV0ZSBwQ29tbXVuaWNhdGlvbk1hbmFnZXI7Cgl9CglkZWxldGUgSW47CglpZiAoIHBJbXBsLT5wVFRTZnhCcm9hZGNhc3RlciApCiAgICAJZGVsZXRlIHBJbXBsLT5wVFRTZnhCcm9hZGNhc3RlcjsKICAgIGRlbGV0ZSBwSW1wbC0+cENoaWxkRW52OwoKICAgIHBJbXBsLT54RXJyb3JMaXN0LkNsZWFyKCk7CiAgICBwSW1wbC0+eFdhcm5pbmdMaXN0LkNsZWFyKCk7CiAgICBwSW1wbC0+eFFBRXJyb3JMaXN0LkNsZWFyKCk7CiAgICBwSW1wbC0+eEluY2x1ZGVGaWxlV2FybmluZ0xpc3QuQ2xlYXIoKTsKCglkZWxldGUgcEltcGw7CgogICAgZGVsZXRlIHBTaG9ydE5hbWVzOwp9CgpTZnhCcm9hZGNhc3RlciYgVGVzdFRvb2xPYmo6OkdldFRUQnJvYWRjYXN0ZXIoKQp7CglpZiAoICFwSW1wbC0+cFRUU2Z4QnJvYWRjYXN0ZXIgKQogICAgCXBJbXBsLT5wVFRTZnhCcm9hZGNhc3RlciA9IG5ldyBTZnhCcm9hZGNhc3RlcjsKCXJldHVybiAqcEltcGwtPnBUVFNmeEJyb2FkY2FzdGVyOwp9Cgp2b2lkIFRlc3RUb29sT2JqOjpSZWFkTmFtZXMoIFN0cmluZyBGaWxlbmFtZSwgQ05hbWVzIComcE5hbWVzLCBDTmFtZXMgKiZwVUlkcywgc2FsX0Jvb2wgYklzRmxhdCApCnsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKioKKiogICAgICAgICAgICAgICBGb2xnZW5kZSBEYXRlaWVuZHVuZ2VuIHNpbmQgdm9yaGFuZGVuCioqCioqICAgICAgICAgICAgICAgaGlkLmxzdCAgICAgICAgICAgICAgICBMYW5nbmFtZSBVSWQKKiogICAgICAgICAgICAgICAqLnNpZCAgICAgICAgICAgICAgICAgIFNsb3QgSWRzIEt1cnpuYW1lIExhbmduYW1lIERhdGVpIGlzdCBmbGFjaAoqKiAgICAgICAgICAgICAgICoud2luICAgICAgICAgICAgICAgICAgQ29udHJvbG5hbWUgTGFuZ25hbWUgRGF0ZWkgbWl0ICpuYW1lIHVuZCArbmFtZSBOb3RhdGlvbgoqKgoqKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCglTdkZpbGVTdHJlYW0gU3RyZWFtOwoJU3RyaW5nICAgICAgIGFMaW5lLGFTaG9ydG5hbWUsYUxvbmduYW1lOwoJcnRsOjpPU3RyaW5nICAgICAgYVVJZDsKCXh1Yl9TdHJMZW4gICBuTGluZU5yOwoJc2FsX3VJbnQxNiAgICAgICBuRWxlbWVudDsKCUNvbnRyb2xEZWYgICAqcE5ld0RlZiwgKnBOZXdEZWYyOwoJQ29udHJvbERlZiAgICpwRmF0aGVyRGVmID0gTlVMTDsKCgluTGluZU5yID0gMDsgICAgLy8gV2lyIHNpbmQgamEgbm9jaCB2b3IgZGVyIERhdGVpCgoJaWYgKCEgcFVJZHMpCgl7CiAgICAJU3RyaW5nIGFGaWxlTmFtZSA9IChwSW1wbC0+YUhJRERpciArIERpckVudHJ5KENVbmlTdHJpbmcoImhpZC5sc3QiKSkpLkdldEZ1bGwoKTsKICAgIAl7CiAgICAJCVRURXhlY3V0aW9uU3RhdHVzSGludCBhSGludCggVFRfRVhFQ1VUSU9OX1NIT1dfQUNUSU9OLCBTdHJpbmcoU3R0UmVzSWQoU19SRUFESU5HX0xPTkdOQU1FUykpLCBhRmlsZU5hbWUgKTsKICAgIAkJR2V0VFRCcm9hZGNhc3RlcigpLkJyb2FkY2FzdCggYUhpbnQgKTsKICAgIAl9CiAgICAJUmVhZEZsYXQoIGFGaWxlTmFtZSAscFVJZHMsIHNhbF9UcnVlICk7CiAgICAJaWYgKCAhcFVJZHMgKQogICAgCQlyZXR1cm47CiAgICAJcE5ld0RlZiA9IG5ldyBDb250cm9sRGVmKCJBY3RpdmUiLHJ0bDo6T1N0cmluZygpKTsKICAgIAljb25zdCBDb250cm9sSXRlbSAqcEl0ZW0gPSBwTmV3RGVmOwogICAgCWlmICghIHBVSWRzLT5JbnNlcnQocEl0ZW0pKQogICAgCXsKICAgIAkJQUREX1dBUk5JTkdfTE9HMiggR0VOX1JFU19TVFIxYyggU19ET1VCTEVfTkFNRSwgIkFjdGl2ZSIgKSwgRmlsZW5hbWUsIG5MaW5lTnIgKTsKICAgIAkJZGVsZXRlIHBOZXdEZWY7CiAgICAJfQoKCX0KCglBRERfTUVTU0FHRV9MT0coIEZpbGVuYW1lICk7CgoJU3RyZWFtLk9wZW4oRmlsZW5hbWUsIFNUUkVBTV9TVERfUkVBRCk7CglpZiAoIVN0cmVhbS5Jc09wZW4oKSkKCXsKICAgIAlBRERfRVJST1IoRVJSX05PX0ZJTEUsR0VOX1JFU19TVFIxKFNfQ0FOTk9UX09QRU5fRklMRSwgRmlsZW5hbWUpKTsKICAgIAlyZXR1cm47Cgl9CgoJaWYgKCBiSXNGbGF0ICYmICFwTmFtZXMgKQoJewogICAgCVRURXhlY3V0aW9uU3RhdHVzSGludCBhSGludCggVFRfRVhFQ1VUSU9OX1NIT1dfQUNUSU9OLCBTdHJpbmcoU3R0UmVzSWQoU19SRUFESU5HX1NMT1RfSURTKSksIEZpbGVuYW1lICk7CiAgICAJR2V0VFRCcm9hZGNhc3RlcigpLkJyb2FkY2FzdCggYUhpbnQgKTsKCX0KCWVsc2UKCXsKICAgIAlUVEV4ZWN1dGlvblN0YXR1c0hpbnQgYUhpbnQoIFRUX0VYRUNVVElPTl9TSE9XX0FDVElPTiwgU3RyaW5nKFN0dFJlc0lkKFNfUkVBRElOR19DT05UUk9MUykpLCBGaWxlbmFtZSApOwogICAgCUdldFRUQnJvYWRjYXN0ZXIoKS5Ccm9hZGNhc3QoIGFIaW50ICk7Cgl9CgoJaWYgKCAhcE5hbWVzICkKICAgIAlwTmFtZXMgPSBuZXcgQ05hbWVzKCk7CgoJewogICAgCVRURXhlY3V0aW9uU3RhdHVzSGludCBhSGludCggVFRfRVhFQ1VUSU9OX0VOVEVSV0FJVCApOwogICAgCUdldFRUQnJvYWRjYXN0ZXIoKS5Ccm9hZGNhc3QoIGFIaW50ICk7Cgl9Cgl3aGlsZSAoIVN0cmVhbS5Jc0VvZigpKQoJewogICAgCW5MaW5lTnIrKzsKCiAgICAJU3RyZWFtLlJlYWRCeXRlU3RyaW5nTGluZShhTGluZSwgUlRMX1RFWFRFTkNPRElOR19JQk1fODUwKTsKICAgIAlhTGluZS5FcmFzZUxlYWRpbmdDaGFycygpOwogICAgCWFMaW5lLkVyYXNlVHJhaWxpbmdDaGFycygpOwogICAgCXdoaWxlICggYUxpbmUuU2VhcmNoQXNjaWkoIiAgIikgIT0gU1RSSU5HX05PVEZPVU5EICkKICAgIAkJYUxpbmUuU2VhcmNoQW5kUmVwbGFjZUFsbEFzY2lpKCIgICIsVW5pU3RyaW5nKCcgJykpOwogICAgCWlmIChhTGluZS5MZW4oKSA9PSAwKSBjb250aW51ZTsKICAgIAlpZiAoYUxpbmUuQ29weSgwLDQpLkNvbXBhcmVJZ25vcmVDYXNlVG9Bc2NpaSgiUmVtICIpID09IENPTVBBUkVfRVFVQUwpIGNvbnRpbnVlOwogICAgCWlmIChhTGluZS5Db3B5KDAsMSkuQ29tcGFyZVRvQXNjaWkoIiciKSA9PSBDT01QQVJFX0VRVUFMKSBjb250aW51ZTsKCiAgICAJaWYgKCAoYUxpbmUuR2V0VG9rZW5Db3VudChjTXlEZWxpbSkgPCAyIHx8IGFMaW5lLkdldFRva2VuQ291bnQoY015RGVsaW0pID4gMykgJiYgYUxpbmUuQ29tcGFyZUlnbm9yZUNhc2VUb0FzY2lpKCIqQWN0aXZlIikgIT0gQ09NUEFSRV9FUVVBTCApCiAgICAJewogICAgCQlBRERfV0FSTklOR19MT0cyKCBHRU5fUkVTX1NUUjEoIFNfSU5WQUxJRF9MSU5FLCBhTGluZSApLCBGaWxlbmFtZSwgbkxpbmVOciApOwogICAgCQljb250aW51ZTsKICAgIAl9CgogICAgCWFTaG9ydG5hbWUgPSBhTGluZS5HZXRUb2tlbigwLGNNeURlbGltKTsKICAgIAlhTG9uZ25hbWUgPSBhTGluZS5HZXRUb2tlbigxLGNNeURlbGltKTsKCiAgICAJU3RyaW5nIGFGaXJzdEFsbG93ZWRFeHRyYSwgYUFsbG93ZWQ7CiAgICAJYUZpcnN0QWxsb3dlZEV4dHJhLkFzc2lnbkFzY2lpKCIrKiIpOwogICAgCWFBbGxvd2VkLkFzc2lnbkFzY2lpKCJfIik7CiAgICAJeHViX1N0ckxlbiBuSW5kZXggPSAwOwogICAgCXNhbF9Cb29sIGJPSyA9IHNhbF9UcnVlOwoKICAgIAl3aGlsZSAoIGJPSyAmJiBuSW5kZXggPCBhU2hvcnRuYW1lLkxlbigpICkKICAgIAl7CiAgICAJCXNhbF9Vbmljb2RlIGFDaGFyID0gYVNob3J0bmFtZS5HZXRDaGFyKCBuSW5kZXggKTsKICAgIAkJc2FsX0Jvb2wgYk9LVGhpcyA9IHNhbF9GYWxzZTsKICAgIAkJYk9LVGhpcyB8PSAoIGFBbGxvd2VkLlNlYXJjaCggYUNoYXIgKSAhPSBTVFJJTkdfTk9URk9VTkQgKTsKICAgIAkJaWYgKCAhbkluZGV4ICkKICAgIAkJCWJPS1RoaXMgfD0gKCBhRmlyc3RBbGxvd2VkRXh0cmEuU2VhcmNoKCBhQ2hhciApICE9IFNUUklOR19OT1RGT1VORCApOwogICAgCQliT0tUaGlzIHw9ICggYUNoYXIgPj0gJ0EnICYmIGFDaGFyIDw9ICdaJyApOwogICAgCQliT0tUaGlzIHw9ICggYUNoYXIgPj0gJ2EnICYmIGFDaGFyIDw9ICd6JyApOwogICAgCQliT0tUaGlzIHw9ICggYUNoYXIgPj0gJzAnICYmIGFDaGFyIDw9ICc5JyApOwoKICAgIAkJYk9LICY9IGJPS1RoaXM7CiAgICAJCW5JbmRleCsrOwogICAgCX0KICAgIAlpZiAoICFiT0sgKQogICAgCXsKICAgIAkJQUREX1dBUk5JTkdfTE9HMiggQ1VuaVN0cmluZygiWmVpbGUgXCIiKS5BcHBlbmQoYUxpbmUpLkFwcGVuZEFzY2lpKCJcIiBlbnRo77+9bHQgdW5n77+9bHRpZ2UgWmVpY2hlbi4iKSwgRmlsZW5hbWUsIG5MaW5lTnIgKTsKICAgIAkJY29udGludWU7CiAgICAJfQoKICAgICAgICBzYWxfQm9vbCBiVW5vTmFtZSA9ICggYUxvbmduYW1lLkNvcHkoIDAsIDUgKS5FcXVhbHNJZ25vcmVDYXNlQXNjaWkoICIudW5vOiIgKQogICAgCQl8fCBhTG9uZ25hbWUuQ29weSggMCwgNCApLkVxdWFsc0lnbm9yZUNhc2VBc2NpaSggImh0dHAiICkKICAgIAkJfHwgYUxvbmduYW1lLkNvcHkoIDAsIDE1ICkuRXF1YWxzSWdub3JlQ2FzZUFzY2lpKCAicHJpdmF0ZTpmYWN0b3J5IiApCiAgICAJCXx8IGFMb25nbmFtZS5Db3B5KCAwLCA4ICkuRXF1YWxzSWdub3JlQ2FzZUFzY2lpKCAic2VydmljZToiICkKICAgIAkJfHwgYUxvbmduYW1lLkNvcHkoIDAsIDYgKS5FcXVhbHNJZ25vcmVDYXNlQXNjaWkoICJtYWNybzoiICkKICAgIAkJfHwgYUxvbmduYW1lLkNvcHkoIDAsIDggKS5FcXVhbHNJZ25vcmVDYXNlQXNjaWkoICIuSGVscElkOiIgKSApOwogICAgICAgIC8vIGdlbmVyaWMgbWV0aG9kIHRvIG1hcmsgbG9uZ25hbWVzIGFzIHN5bWJvbGljCiAgICAgICAgaWYgKCBhTG9uZ25hbWUuQ29weSggMCwgNCApLkVxdWFsc0lnbm9yZUNhc2VBc2NpaSggInN5bToiICkgKQogICAgICAgIHsKICAgICAgICAgICAgYlVub05hbWUgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgYUxvbmduYW1lLkVyYXNlKCAwLCA0ICk7CiAgICAgICAgfQogICAgCXNhbF9Cb29sIGJNb3ppbGxhTmFtZSA9ICggIWJJc0ZsYXQgJiYgYUxvbmduYW1lLkNvcHkoIDAsIDQgKS5FcXVhbHNJZ25vcmVDYXNlQXNjaWkoICIubW96IiApICk7CgogICAgCWlmICggYVNob3J0bmFtZS5HZXRDaGFyKDApID09ICcrJyApICAgICAgICAgIC8vIEtvbXBsZXR0ZW4gRWludHJhZyBrb3BpZXJlbgogICAgCXsKICAgIAkJYVNob3J0bmFtZS5FcmFzZSgwLDEpOwogICAgCQlDb250cm9sRGVmIFdoYXROYW1lKGFMb25nbmFtZSxydGw6Ok9TdHJpbmcoKSk7CiAgICAJCUNvbnRyb2xEZWYgKk9sZFRyZWU7CiAgICAJCWlmIChwTmFtZXMtPlNlZWtfRW50cnkoJldoYXROYW1lLCZuRWxlbWVudCkpCiAgICAJCXsKICAgIAkJCU9sZFRyZWUgPSAoQ29udHJvbERlZiopcE5hbWVzLT5HZXRPYmplY3QobkVsZW1lbnQpOwogICAgCQkJcE5ld0RlZiA9IG5ldyBDb250cm9sRGVmKGFMb25nbmFtZSxhU2hvcnRuYW1lLE9sZFRyZWUsc2FsX1RydWUpOwoKICAgIAkJCWNvbnN0IENvbnRyb2xJdGVtICpwSXRlbSA9IHBOZXdEZWY7CiAgICAJCQlpZiAoISBwTmFtZXMtPkluc2VydChwSXRlbSkpCiAgICAJCQl7CiAgICAJCQkJQUREX1dBUk5JTkdfTE9HMiggR0VOX1JFU19TVFIxKCBTX0RPVUJMRV9OQU1FLCBhTGluZSApLCBGaWxlbmFtZSwgbkxpbmVOciApOwogICAgCQkJCWRlbGV0ZSBwTmV3RGVmOwogICAgCQkJCXBGYXRoZXJEZWYgPSBOVUxMOwogICAgCQkJfQogICAgCQkJZWxzZQogICAgCQkJewogICAgCQkJCXBGYXRoZXJEZWYgPSBwTmV3RGVmOwogICAgCQkJfQogICAgCQl9CiAgICAJCWVsc2UKICAgIAkJewogICAgCQkJQUREX1dBUk5JTkdfTE9HMiggR0VOX1JFU19TVFIxKCBTX1NIT1JUTkFNRV9VTktOT1dOLCBhTGluZSApLCBGaWxlbmFtZSwgbkxpbmVOciApOwogICAgCQkJY29udGludWU7CiAgICAJCX0KCiAgICAJfQogICAgCWVsc2UKICAgIAl7CgogICAgCSAgICAvLyBGSVhNRTogSEVMUElECiAgICAJICAgICNpZiAwCiAgICAJCWlmIChhU2hvcnRuYW1lLkNvbXBhcmVJZ25vcmVDYXNlVG9Bc2NpaSgiKkFjdGl2ZSIpID09IENPTVBBUkVfRVFVQUwpCiAgICAJCQlhVUlkID0gcnRsOjpPU3RyaW5nKCBVSURfQUNUSVZFICk7CiAgICAJCWVsc2UKICAgICAgICAgICAgI2VuZGlmCiAgICAJCSAgICBpZiAoICFiVW5vTmFtZSAmJiAhYk1vemlsbGFOYW1lICkKICAgIAkJewkvLyBCZXN0aW1tZW4gZGVyIElEIGF1cyBkZXIgSGlkLkxzdAogICAgCQkJQ29udHJvbERlZiBXaGF0TmFtZShhTG9uZ25hbWUscnRsOjpPU3RyaW5nKCkpOwogICAgCQkJaWYgKHBVSWRzLT5TZWVrX0VudHJ5KCZXaGF0TmFtZSwmbkVsZW1lbnQpKQogICAgCQkJCWFVSWQgPSBwVUlkcy0+R2V0T2JqZWN0KG5FbGVtZW50KS0+cERhdGEtPmFVSWQ7CiAgICAJCQllbHNlCiAgICAJCQl7CiAgICAJCQkJQUREX1dBUk5JTkdfTE9HMiggR0VOX1JFU19TVFIxKCBTX0xPTkdOQU1FX1VOS05PV04sIGFMaW5lICksIEZpbGVuYW1lLCBuTGluZU5yICk7CiAgICAJCQkJY29udGludWU7CiAgICAJCQl9CiAgICAJCX0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBGSVhNRTogSEVMUElECiAgICAgICAgICAgICAgICAjaWYgMAogICAgCQkJaWYgKCBiVW5vTmFtZSApCiAgICAJCQkJYVVJZCA9IHJ0bDo6T1N0cmluZyggYUxvbmduYW1lICk7CiAgICAJCQllbHNlIGlmICggYk1vemlsbGFOYW1lICkKICAgIAkJCQlhVUlkID0gcnRsOjpPU3RyaW5nKCBhTG9uZ25hbWUgKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBEQkdfRVJST1IoIlVua25vd24gVVJMIHNjaGVtYSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgI2VuZGlmCiAgICAgICAgICAgIH0KCgoKICAgIAkJaWYgKGFTaG9ydG5hbWUuR2V0Q2hhcigwKSA9PSAnKicgfHwgYklzRmxhdCkgICAgIC8vIEdsb2JhbGVyIEt1cnpuYW1lIChEaWFsb2duYW1lIG9kZXIgU0lkKQogICAgCQl7CiAgICAJCQlpZiAoIWJJc0ZsYXQpCiAgICAJCQkJYVNob3J0bmFtZS5FcmFzZSgwLDEpOwoKICAgCQkJCXBOZXdEZWYgPSBuZXcgQ29udHJvbERlZihhU2hvcnRuYW1lLGFVSWQpOwoKICAgIAkJCWlmICghYklzRmxhdCkKICAgIAkJCXsKICAgIAkJCQlwTmV3RGVmLT5Tb25zKCBuZXcgQ05hbWVzKCkgKTsKCiAgIAkJCQkgICAgcE5ld0RlZjIgPSBuZXcgQ29udHJvbERlZihhU2hvcnRuYW1lLGFVSWQpOwogICAgCQkJCWlmICghcE5ld0RlZi0+U29uSW5zZXJ0KCBwTmV3RGVmMiApKSAgICAgICAgIC8vIERpYWxvZyBpbiBlaWdlbmVuIE5hbWVzcGFjZSBlaW50cmFnZW4KICAgIAkJCQl7CiAgICAJCQkJCWRlbGV0ZSBwTmV3RGVmMjsKICAgIAkJCQkJREJHX0VSUk9SKCIgISEhISBBQ0hUVU5HICEhISEgIEZlaGxlciBiZWltIGVpbmbvv71nZW4gaW4gbGVlcmUgTGlzdGUhIik7CiAgICAJCQkJfQogICAgCQkJfQoKICAgIAkJCWNvbnN0IENvbnRyb2xJdGVtICpwSXRlbSA9IHBOZXdEZWY7CiAgICAJCQlpZiAoISBwTmFtZXMtPkluc2VydChwSXRlbSkpCiAgICAJCQl7CiAgICAJCQkJQUREX1dBUk5JTkdfTE9HMiggR0VOX1JFU19TVFIxKCBTX0RPVUJMRV9OQU1FLCBhTGluZSApLCBGaWxlbmFtZSwgbkxpbmVOciApOwogICAgCQkJCWRlbGV0ZSBwTmV3RGVmOwogICAgCQkJCXBGYXRoZXJEZWYgPSBOVUxMOwogICAgCQkJfQogICAgCQkJZWxzZQogICAgCQkJewogICAgCQkJCXBGYXRoZXJEZWYgPSBwTmV3RGVmOwogICAgCQkJfQogICAgCQl9CiAgICAJCWVsc2UKICAgIAkJewogICAgCQkJaWYgKCFwRmF0aGVyRGVmKQogICAgCQkJewogICAgCQkJCUFERF9XQVJOSU5HX0xPRzIoIEdFTl9SRVNfU1RSMCggU19GSVJTVF9TSE9SVE5BTUVfUkVRX0FTVFJYICksIEZpbGVuYW1lLCBuTGluZU5yICk7CiAgICAJCQl9CiAgICAJCQllbHNlCiAgICAJCQl7CgkJCQkgICAgcE5ld0RlZiA9IG5ldyBDb250cm9sRGVmKGFTaG9ydG5hbWUsYVVJZCk7CiAgICAJCQkJaWYgKCEgcEZhdGhlckRlZi0+U29uSW5zZXJ0KHBOZXdEZWYpKQogICAgCQkJCXsKICAgIAkJCQkJQUREX1dBUk5JTkdfTE9HMiggR0VOX1JFU19TVFIxKCBTX0RPVUJMRV9OQU1FLCBhTGluZSApLCBGaWxlbmFtZSwgbkxpbmVOciApOwogICAgCQkJCQlkZWxldGUgcE5ld0RlZjsKICAgIAkJCQl9CiAgICAJCQl9CiAgICAJCX0KICAgIAl9CiAgICAJR2V0cEFwcCgpLT5SZXNjaGVkdWxlKCk7Cgl9Cgl7CiAgICAJVFRFeGVjdXRpb25TdGF0dXNIaW50IGFIaW50KCBUVF9FWEVDVVRJT05fTEVBVkVXQUlUICk7CiAgICAJR2V0VFRCcm9hZGNhc3RlcigpLkJyb2FkY2FzdCggYUhpbnQgKTsKCX0KCXsKICAgIAlUVEV4ZWN1dGlvblN0YXR1c0hpbnQgYUhpbnQoIFRUX0VYRUNVVElPTl9ISURFX0FDVElPTiApOwogICAgCUdldFRUQnJvYWRjYXN0ZXIoKS5Ccm9hZGNhc3QoIGFIaW50ICk7CiAgICB9CgoJU3RyZWFtLkNsb3NlKCk7Cn0KCgp2b2lkIFRlc3RUb29sT2JqOjpBZGROYW1lKFN0cmluZyAmYUJpc2hlciwgU3RyaW5nICZhTmV1ICkKewoJU3RyaW5nIGFTbCggJy8nICk7CglpZiAoIFVuaVN0cmluZyhhU2wpLkFwcGVuZChhQmlzaGVyKS5BcHBlbmQoYVNsKS5Ub1VwcGVyQXNjaWkoKS5TZWFyY2goIFVuaVN0cmluZyhhU2wpLkFwcGVuZChhTmV1KS5BcHBlbmQoYVNsKS5Ub1VwcGVyQXNjaWkoKSApID09IFNUUklOR19OT1RGT1VORCApCgl7CiAgICAJYUJpc2hlciArPSBhU2w7CiAgICAJYUJpc2hlciArPSBhTmV1OwoJfQp9CgoKdm9pZCBUZXN0VG9vbE9iajo6UmVhZEZsYXQoIFN0cmluZyBGaWxlbmFtZSwgQ05hbWVzIComcE5hbWVzLCBzYWxfQm9vbCBiU29ydEJ5TmFtZSApCi8vICBXZW5uIGJTb3J0QnlOYW1lID09IHNhbF9GYWxzZSwgZGFubiBuYWNoIFVJZCBTb3J0aWVyZW4gKENvbnRyb2xJdGVtVUlkIHN0YXR0IENvbnRyb2xEZWYpCnsKCVN2RmlsZVN0cmVhbSBTdHJlYW07CglTdHJpbmcgICAgICAgYUxpbmUsYUxvbmduYW1lOwoJcnRsOjpPU3RyaW5nICAgICAgYVVJZDsKCXh1Yl9TdHJMZW4gICBuTGluZU5yOwoJQ29udHJvbEl0ZW0gICpwTmV3SXRlbTsKCXNhbF91SW50MTYgICAgICAgbkRvdWJsZUNvdW50ID0gMDsKCglTdHJlYW0uT3BlbihGaWxlbmFtZSwgU1RSRUFNX1NURF9SRUFEKTsKCglpZiAoIVN0cmVhbS5Jc09wZW4oKSkKCXsKICAgIAlBRERfRVJST1IoRVJSX05PX0ZJTEUsR0VOX1JFU19TVFIxKFNfQ0FOTk9UX09QRU5fRklMRSwgRmlsZW5hbWUpKTsKICAgIAlyZXR1cm47Cgl9CgoJbkxpbmVOciA9IDA7ICAgIC8vIFdpciBzaW5kIGphIG5vY2ggdm9yIGRlciBEYXRlaQoKCWlmICggIXBOYW1lcyApCiAgICAJcE5hbWVzID0gbmV3IENOYW1lcygpOwoKCXsKICAgIAlUVEV4ZWN1dGlvblN0YXR1c0hpbnQgYUhpbnQoIFRUX0VYRUNVVElPTl9FTlRFUldBSVQgKTsKICAgIAlHZXRUVEJyb2FkY2FzdGVyKCkuQnJvYWRjYXN0KCBhSGludCApOwoJfQoJQUREX01FU1NBR0VfTE9HKCBGaWxlbmFtZSApOwoJd2hpbGUgKCFTdHJlYW0uSXNFb2YoKSkKCXsKICAgIAluTGluZU5yKys7CgogICAgCVN0cmVhbS5SZWFkQnl0ZVN0cmluZ0xpbmUoYUxpbmUsIFJUTF9URVhURU5DT0RJTkdfSUJNXzg1MCk7CiAgICAJYUxpbmUuRXJhc2VMZWFkaW5nQ2hhcnMoKTsKICAgIAlhTGluZS5FcmFzZVRyYWlsaW5nQ2hhcnMoKTsKICAgIAl3aGlsZSAoIGFMaW5lLlNlYXJjaEFzY2lpKCIgICIpICE9IFNUUklOR19OT1RGT1VORCApCiAgICAJCWFMaW5lLlNlYXJjaEFuZFJlcGxhY2VBbGxBc2NpaSgiICAiLFVuaVN0cmluZygnICcpKTsKICAgIAlpZiAoYUxpbmUuTGVuKCkgPT0gMCkgY29udGludWU7CgogICAgCWlmICggKGFMaW5lLkdldFRva2VuQ291bnQoY015RGVsaW0pIDwgMiB8fCBhTGluZS5HZXRUb2tlbkNvdW50KGNNeURlbGltKSA+IDMpICYmIGFMaW5lLkNvbXBhcmVJZ25vcmVDYXNlVG9Bc2NpaSgiKkFjdGl2ZSIpICE9IENPTVBBUkVfRVFVQUwgKQogICAgCXsKICAgIAkJQUREX1dBUk5JTkdfTE9HMiggR0VOX1JFU19TVFIxKCBTX0lOVkFMSURfTElORSwgYUxpbmUgKSwgRmlsZW5hbWUsIG5MaW5lTnIgKTsKICAgIAkJY29udGludWU7CiAgICAJfQoKICAgIAlhTG9uZ25hbWUgPSBhTGluZS5HZXRUb2tlbigwLGNNeURlbGltKTsKICAgICAgICAvLyBGSVhNRTogSEVMUElECiAgICAJYVVJZCA9IHJ0bDo6T1VTdHJpbmdUb09TdHJpbmcoIGFMaW5lLkdldFRva2VuKDEsY015RGVsaW0pLCBSVExfVEVYVEVOQ09ESU5HX1VURjggKTsKCiAgICAJaWYgKCBiU29ydEJ5TmFtZSApCiAgICAJCXBOZXdJdGVtID0gbmV3IENvbnRyb2xEZWYoIGFMb25nbmFtZSwgYVVJZCApOwogICAgCWVsc2UKICAgIAkJcE5ld0l0ZW0gPSBuZXcgQ29udHJvbEl0ZW1VSWQoIGFMb25nbmFtZSwgYVVJZCApOwogICAgCWlmICggIXBOYW1lcy0+QzQwX1BUUl9JTlNFUlQoIENvbnRyb2xJdGVtLCBwTmV3SXRlbSApICkKICAgIAl7CiAgICAJCWlmICggYlNvcnRCeU5hbWUgKQogICAgCQl7CiAgICAJCQlpZiAoIG5Eb3VibGVDb3VudCsrIDwgMTAgKQogICAgCQkJewogICAgCQkJCUFERF9XQVJOSU5HX0xPRzIoIEdFTl9SRVNfU1RSMSggU19ET1VCTEVfTkFNRSwgYUxpbmUgKSwgRmlsZW5hbWUsIG5MaW5lTnIgKTsKICAgIAkJCX0KICAgIAkJfQogICAgCQllbHNlCiAgICAJCXsKICAgIAkJCXNhbF91SW50MTYgbk5yOwogICAgCQkJcE5hbWVzLT5TZWVrX0VudHJ5KCBwTmV3SXRlbSwgJm5OciApOwogICAgCQkJQWRkTmFtZSggcE5hbWVzLT5HZXRPYmplY3Qobk5yKS0+cERhdGEtPkt1cnpuYW1lLCBwTmV3SXRlbS0+cERhdGEtPkt1cnpuYW1lICk7CiAgICAJCX0KICAgIAkJZGVsZXRlIHBOZXdJdGVtOwogICAgCX0KICAgIAlHZXRwQXBwKCktPlJlc2NoZWR1bGUoKTsKCX0KCXsKICAgIAlUVEV4ZWN1dGlvblN0YXR1c0hpbnQgYUhpbnQoIFRUX0VYRUNVVElPTl9MRUFWRVdBSVQgKTsKICAgIAlHZXRUVEJyb2FkY2FzdGVyKCkuQnJvYWRjYXN0KCBhSGludCApOwoJfQoKCVN0cmVhbS5DbG9zZSgpOwojaWZkZWYgREJHX1VUSUwKLy8gICAgICBpbnQgaTsKLy8gICAgICBmb3IgKCBpID0gMCA7IGkgPCBwTmFtZXMtPkNvdW50KCkgOyBpKysgKQovLyAgICAgIHsKLy8gICAgICAgICAgICAgIERCR19FUlJPUiggcE5hbWVzLT5HZXRPYmplY3QoaSktPnBEYXRhLT5LdXJ6bmFtZSApOwovLyAgICAgIH0KI2VuZGlmCn0KCnZvaWQgUmVhZEZsYXRBcnJheSggY29uc3QgQ29udHJvbERlZkxvYWQgYXJXYXMgW10sIENOYW1lcyAqJnBOYW1lcyApCnsKCXNhbF91SW50MTYgbkluZGV4ID0gMDsKCglpZiAoICFwTmFtZXMgKQogICAgCXBOYW1lcyA9IG5ldyBDTmFtZXMoKTsKCgl3aGlsZSAoIFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKGFyV2FzW25JbmRleF0uS3Vyem5hbWUpLkxlbigpID4gMCApCgl7CiAgICAgICAgLy8gRklYTUU6IEhFTFBJRAogICAgICAgIHJ0bDo6T1N0cmluZyBhVUlkOy8vIChhcldhc1tuSW5kZXhdLm5VSWQpOwogICAgCWNvbnN0IENvbnRyb2xJdGVtICpwWCA9IG5ldyBDb250cm9sRGVmKCBhcldhc1tuSW5kZXhdLkt1cnpuYW1lLCBhVUlkKTsKICAgIAlwTmFtZXMtPkM0MF9QVFJfSU5TRVJUKENvbnRyb2xJdGVtLCBwWCk7CiAgICAJbkluZGV4Kys7Cgl9Cn0KCnZvaWQgVGVzdFRvb2xPYmo6OldhaXRGb3JBbnN3ZXIgKCkKewoJaWYgKCBiVXNlSVBDICkKCXsKCSNpZmRlZiBEQkdfVVRJTHgKICAgIAlzYWxfdUludDE2IG5TeXNXaW5Nb2RlTWVtbyA9IEdldHBBcHAoKS0+R2V0U3lzdGVtV2luZG93TW9kZSgpOwogICAgCUdldHBBcHAoKS0+U2V0U3lzdGVtV2luZG93TW9kZSggMCApOwogICAgCU1vZGVsZXNzRGlhbG9nIGFEbGcoTlVMTCk7CiAgICAJYURsZy5TZXRPdXRwdXRTaXplUGl4ZWwoU2l6ZSgyMDAsMCkpOwogICAgCWFEbGcuU2V0VGV4dChDVW5pU3RyaW5nKCJXYWl0aW5nIGZvciBBbnN3ZXIiKSk7CiAgICAJYURsZy5TaG93KCBzYWxfVHJ1ZSwgU0hPV19OT0ZPQ1VTQ0hBTkdFIHwgU0hPV19OT0FDVElWQVRFICk7CiAgICAJR2V0cEFwcCgpLT5TZXRTeXN0ZW1XaW5kb3dNb2RlKCBuU3lzV2luTW9kZU1lbW8gKTsKCSNlbmRpZgogICAgCXNhbF9Cb29sIGJXYXNSZWFsV2FpdCA9ICFiUmV0dXJuT0s7CiAgICAgICAgQmFzaWNSdW50aW1lIGFSdW4oIE5VTEwgKTsKICAgICAgICBpZiAoIEJhc2ljUnVudGltZUFjY2Vzczo6SGFzUnVudGltZSgpICkKICAgICAgICAgICAgYVJ1biA9IEJhc2ljUnVudGltZUFjY2Vzczo6R2V0UnVudGltZSgpOwoKICAgICAgICAvLyB0aGlzIHRpbWVyIHRvIHRlcm1pbmF0ZSBZaWVsZCBiZWxvdwogICAgICAgIFRpbWVyIGFUaW1lcjsKICAgICAgICBhVGltZXIuU2V0VGltZW91dCggcEltcGwtPmFTZXJ2ZXJUaW1lb3V0LkdldE1TRnJvbVRpbWUoKSApOwogICAgICAgIGFUaW1lci5TdGFydCgpOwogICAgICAgIHdoaWxlICggIWJSZXR1cm5PSyAmJiBhVGltZXIuSXNBY3RpdmUoKSAmJiBwQ29tbXVuaWNhdGlvbk1hbmFnZXItPklzQ29tbXVuaWNhdGlvblJ1bm5pbmcoKQogICAgICAgICAgICAgICAgJiYgYVJ1bi5Jc1ZhbGlkKCkgJiYgYVJ1bi5Jc1J1bigpICkKICAgIAl7CiAgICAJCSNpZmRlZiBPUzIKICAgIAkJRG9zU2xlZXAoMTAwKTsKICAgIAkJI2VuZGlmCiAgICAJCUdldHBBcHAoKS0+WWllbGQoKTsKICAgICAgICAgICAgaWYgKCBCYXNpY1J1bnRpbWVBY2Nlc3M6Okhhc1J1bnRpbWUoKSApCiAgICAgICAgICAgICAgICBhUnVuID0gQmFzaWNSdW50aW1lQWNjZXNzOjpHZXRSdW50aW1lKCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGFSdW4gPSBCYXNpY1J1bnRpbWUoIE5VTEwgKTsKICAgIAl9CiAgICAJaWYgKCBiV2FzUmVhbFdhaXQgJiYgYURpYWxvZ0hhbmRsZXJOYW1lLkxlbigpID4gMCApICAgICAvLyBEYW1pdCBkYXMgZ2FuemUgYXVjaCBpbSBUZXN0dG9vbCBs77+9dWZ0CiAgICAJCUNhbGxEaWFsb2dIYW5kbGVyKEdldHBBcHAoKSk7Cgl9CgllbHNlCgl7CiAgICAgICAgVGltZSBFbmRlOwoKICAgIAlFbmRlICs9IHBJbXBsLT5hU2VydmVyVGltZW91dDsKICAgIAlTdlN0cmVhbSAqcFRlbXAgPSBOVUxMOwoKICAgIAl3aGlsZSAoICFiUmV0dXJuT0sgJiYgRW5kZSA+IFRpbWUoKSApCiAgICAJewovLwkJCXBUZW1wID0gUGx1Z0luQXBwbGljYXRpb246OkdldFBsdWdJbkFwcCgpLT5HZXRSZXR1cm5Gcm9tRXhlY3V0ZSgpOwogICAgCQlpZiAoIHBUZW1wICkKICAgIAkJewogICAgCQkJUmV0dXJuUmVzdWx0cyggcFRlbXAgKTsKICAgIAkJCWJSZXR1cm5PSyA9IHNhbF9UcnVlOwogICAgCQl9CiAgICAJCWVsc2UKICAgIAkJewogICAgCQkJR2V0cEFwcCgpLT5SZXNjaGVkdWxlKCk7CiAgICAJCX0KICAgIAkJbklkbGVDb3VudCA9IDA7CiAgICAJfQoJfQoKCglpZiAoICFiUmV0dXJuT0sgKQoJewogICAgICAgIEFERF9FUlJPUihFUlJfRVhFQ19USU1FT1VULEdFTl9SRVNfU1RSMShTX1RJTU9VVF9XQUlUSU5HLCBTdHJpbmc6OkNyZWF0ZUZyb21JbnQ2NChuU2VxdWVuY2UpKSk7CiAgICAJYlJldHVybk9LID0gc2FsX1RydWU7CiAgICAJblNlcXVlbmNlKys7Cgl9Cn0KCgpJTVBMX0xJTksoIFRlc3RUb29sT2JqLCBJZGxlSGRsLCBBcHBsaWNhdGlvbiosIEVNUFRZQVJHICkKewoJaWYgKCAhYlJldHVybk9LICkKICAgIAluSWRsZUNvdW50Kys7CglpZiAoIG5JZGxlQ291bnQgPiAxMCApICAvLyBkLmguIFNjaG9uIDEwIG1hbCBoaWVyIGdld2VzZW4gdW5kIG5vY2gga2Vpbm1hbCBpbSBXYWl0Rm9yQW5zd2VyCgl7CiAgICAgICAgR2V0cEFwcCgpLT5SZW1vdmVJZGxlSGRsKCBMSU5LKCB0aGlzLCBUZXN0VG9vbE9iaiwgSWRsZUhkbCApICk7CiAgICAgICAgR2V0cEFwcCgpLT5Qb3N0VXNlckV2ZW50KCBMSU5LKCB0aGlzLCBUZXN0VG9vbE9iaiwgQ2FsbERpYWxvZ0hhbmRsZXIgKSApOwoJfQoJcmV0dXJuIDA7Cn0KCklNUExfTElOSyggVGVzdFRvb2xPYmosIENhbGxEaWFsb2dIYW5kbGVyLCBBcHBsaWNhdGlvbiosIEVNUFRZQVJHICkKewoJbldpbmRvd0hhbmRsZXJDYWxsTGV2ZWwrKzsKCVN0cmluZyBhSGFuZGxlck5hbWUoYURpYWxvZ0hhbmRsZXJOYW1lKTsKCWFEaWFsb2dIYW5kbGVyTmFtZS5FcmFzZSgpOwoKCXNhbF91TG9uZyBuUmVtZW1iZXJTZXF1ZW5jZSA9IG5TZXF1ZW5jZTsgLy8gRGEgc2ljaCBkaWUgU2VxdWVuY2UgaW0gRGlhbG9nSGFuZGxlciDvv71uZGVydAoJKChTdGFyQkFTSUMqKUdldFBhcmVudCgpKS0+Q2FsbCggYUhhbmRsZXJOYW1lICk7CgluU2VxdWVuY2UgPSBuUmVtZW1iZXJTZXF1ZW5jZTsKCS8vIERpZSBTZXF1ZW56bnVtbWVybiB3ZXJkZW4gZGFubiB6d2FyIGRvcHBlbHQgdmVyZ2ViZW4sIGFiZXIgd2VuIGvvv71tbWVydHMuCgoJbldpbmRvd0hhbmRsZXJDYWxsTGV2ZWwtLTsKCXJldHVybiAwOwp9CgoKdm9pZCBUZXN0VG9vbE9iajo6QmVnaW5CbG9jaygpCnsKCVdhaXRGb3JBbnN3ZXIoKTsKCWlmICggSXNFcnJvcigpICkKICAgIAlyZXR1cm47CgoJREJHX0FTU0VSVCghSXNCbG9jaywiQmVnaW5CbG9jayBpbm5lcmhhbGIgZWluZXMgQmxvY2tlcyIpOwoJSW4tPlJlc2V0KG5TZXF1ZW5jZSk7CglJc0Jsb2NrID0gc2FsX1RydWU7Cn0KCgp2b2lkIFRlc3RUb29sT2JqOjpTZW5kVmlhU29ja2V0KCkKewoJaWYgKCAhcENvbW11bmljYXRpb25NYW5hZ2VyICkKCXsKICAgIAlEQkdfRVJST1IoIktlaW4gQ29tbXVuaWNhdGlvbk1hbmFnZXIgdm9yaGFuZGVuISEiKTsKICAgIAlyZXR1cm47Cgl9CgoJaWYgKCAhcENvbW11bmljYXRpb25NYW5hZ2VyLT5Jc0NvbW11bmljYXRpb25SdW5uaW5nKCkgKQogICAgewogICAgICAgIC8vIGZpcnN0IHRyeSB0byBydW4gYmFzaWMgc3ViICJzdGFydFRoZU9mZmljZSIgc2VlIGk4NjU0MCAKICAgICAgICBTYnhWYXJpYWJsZSogcE1ldGggPSBwSW1wbC0+cE15QmFzaWMtPkZpbmQoIENVbmlTdHJpbmcoICJzdGFydFRoZU9mZmljZSIgKSwgU2J4Q0xBU1NfRE9OVENBUkUpOwogICAgICAgIGlmKCAhcEltcGwtPmJJc1N0YXJ0ICYmIHBNZXRoICYmIHBNZXRoLT5JU0EoU2J4TWV0aG9kKSApCiAgICAgICAgewogICAgICAgICAgICBwSW1wbC0+cE15QmFzaWMtPkNhbGwoIENVbmlTdHJpbmcoICJzdGFydFRoZU9mZmljZSIgKSApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwSW1wbC0+cE15QmFzaWMtPlJlc2V0RXJyb3IoKTsgIC8vIHJlc2V0IGVycm9yIHByb2R1Y2VkIGJ5IGZhaWxlZCBGaW5kIGFib3ZlCiAgICAJICAgIGlmICggIXBDb21tdW5pY2F0aW9uTWFuYWdlci0+U3RhcnRDb21tdW5pY2F0aW9uKCBQcm9nUGF0aCwgcEltcGwtPlByb2dQYXJhbSwgcEltcGwtPnBDaGlsZEVudiApICkKICAgIAkgICAgewogICAgCQkgICAgQUREX0VSUk9SKEVSUl9SRVNUQVJUX0ZBSUwsR0VOX1JFU19TVFIxKFNfQVBQTElDQVRJT05fU1RBUlRfRkFJTEVELCBQcm9nUGF0aCkpOwogICAgCSAgICB9CiAgICAJICAgIGVsc2UKICAgIAkgICAgewogICAgICAgICAgICAgICAgaWYgKCAhcEltcGwtPmJJc1N0YXJ0ICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAJCSAgICBBRERfRVJST1IoRVJSX1JFU1RBUlQsR0VOX1JFU19TVFIwKFNfQVBQTElDQVRJT05fUkVTVEFSVEVEKSk7CiAgICAgICAgICAgICAgICB9CiAgICAJICAgIH0KICAgICAgICB9CiAgICB9CgoJYlJldHVybk9LID0gc2FsX0ZhbHNlOwoJaWYgKCBwQ29tbXVuaWNhdGlvbk1hbmFnZXItPkdldExhc3ROZXdMaW5rKCkgKQoJewogICAgCWlmICggIXBDb21tdW5pY2F0aW9uTWFuYWdlci0+R2V0TGFzdE5ld0xpbmsoKS0+VHJhbnNmZXJEYXRhU3RyZWFtKCBJbi0+R2V0U3RyZWFtKCkgKSApCiAgICAJewogICAgCQlBRERfRVJST1IoRVJSX1NFTkRfVElNRU9VVCxHRU5fUkVTX1NUUjEoU19USU1PVVRfU0VORElORywgU3RyaW5nOjpDcmVhdGVGcm9tSW50NjQoblNlcXVlbmNlKSkpOwogICAgCQluU2VxdWVuY2UrKzsKICAgIAkJYlJldHVybk9LID0gc2FsX1RydWU7ICAgICAgICAgICAgICAgLy8gS2VpbiBSZXR1cm4genUgZXJ3YXJ0ZW4KICAgIAl9Cgl9CgllbHNlCgl7CiAgICAJQUREX0VSUk9SKEVSUl9TRU5EX1RJTUVPVVQsR0VOX1JFU19TVFIxKFNfTk9fQ09OTkVDVElPTiwgU3RyaW5nOjpDcmVhdGVGcm9tSW50NjQoblNlcXVlbmNlKSkpOwogICAgCW5TZXF1ZW5jZSsrOwogICAgCWJSZXR1cm5PSyA9IHNhbF9UcnVlOyAgICAgICAgICAgICAgIC8vIEtlaW4gUmV0dXJuIHp1IGVyd2FydGVuCgl9Cgp9Cgp2b2lkIFRlc3RUb29sT2JqOjpFbmRCbG9jaygpCnsKCWlmIChJc0Jsb2NrKQoJewogICAgCXBJbXBsLT5Mb2NhbFN0YXJ0dGltZSA9IFRpbWU6OkdldFN5c3RlbVRpY2tzKCk7CS8vIFNldHplbiBkZXIgQW5mYW5nc3plaXQgZu+/vXIgUGVyZm9ybWFuY2VtZXNzdW5nCgogICAgCUluLT5HZW5DbWRGbG93IChGX0VuZENvbW1hbmRCbG9jayk7CgogICAgCWlmICggcEltcGwtPmJEb1JlbW90ZUNvbW1hbmREZWxheSApCiAgICAJewogICAgCQlzYWxfdUxvbmcgblRpbWVXYWl0ID0gcEltcGwtPm5NaW5SZW1vdGVDb21tYW5kRGVsYXk7CiAgICAJCWlmICggcEltcGwtPm5NYXhSZW1vdGVDb21tYW5kRGVsYXkgIT0gcEltcGwtPm5NaW5SZW1vdGVDb21tYW5kRGVsYXkgKQogICAgCQkJblRpbWVXYWl0ICs9IFRpbWU6OkdldFN5c3RlbVRpY2tzKCkgJSAoIHBJbXBsLT5uTWF4UmVtb3RlQ29tbWFuZERlbGF5IC0gcEltcGwtPm5NaW5SZW1vdGVDb21tYW5kRGVsYXkgKTsKICAgIAkJVGltZXIgYVRpbWVyOwogICAgCQlhVGltZXIuU2V0VGltZW91dCggblRpbWVXYWl0ICk7CiAgICAJCWFUaW1lci5TdGFydCgpOwogICAgCQl3aGlsZSAoIGFUaW1lci5Jc0FjdGl2ZSgpICYmIHBDb21tdW5pY2F0aW9uTWFuYWdlci0+SXNDb21tdW5pY2F0aW9uUnVubmluZygpICkKICAgIAkJewogICAgCQkJI2lmZGVmIE9TMgogICAgCQkJRG9zU2xlZXAoMTAwKTsKICAgIAkJCSNlbmRpZgogICAgCQkJR2V0cEFwcCgpLT5ZaWVsZCgpOwogICAgCQl9CiAgICAJfQoKICAgIAlpZiAoIGJVc2VJUEMgKQogICAgCQlTZW5kVmlhU29ja2V0KCk7CiAgICAJZWxzZQogICAgCXsKLy8JCQlQbHVnSW5BcHBsaWNhdGlvbjo6R2V0UGx1Z0luQXBwKCktPkV4ZWN1dGVSZW1vdGVTdGF0ZW1lbnRzKCBJbi0+R2V0U3RyZWFtKCkgKTsKICAgIAkJYlJldHVybk9LID0gc2FsX0ZhbHNlOwogICAgCQlpZiAoIGFEaWFsb2dIYW5kbGVyTmFtZS5MZW4oKSA+IDAgKQogICAgCQkJR2V0cEFwcCgpLT5JbnNlcnRJZGxlSGRsKCBMSU5LKCB0aGlzLCBUZXN0VG9vbE9iaiwgSWRsZUhkbCApLCAxICk7CiAgICAJfQogICAgCUlzQmxvY2sgPSBzYWxfRmFsc2U7Cgl9CgllbHNlCgl7CiAgICAJREJHX0VSUk9SKCJFbmRCbG9jayBhde+/vWVyaGFsYiBlaW5lcyBCbG9ja2VzIik7Cgl9Cn0KCgpzYWxfQm9vbCBUZXN0VG9vbE9iajo6TG9hZCggU3RyaW5nIGFGaWxlTmFtZSwgU2JNb2R1bGUgKnBNb2QgKQp7CglzYWxfQm9vbCBiT2sgPSBzYWxfVHJ1ZTsKCVN2RmlsZVN0cmVhbSBhU3RybSggYUZpbGVOYW1lLCBTVFJFQU1fU1REX1JFQUQgKTsKCWlmKCBhU3RybS5Jc09wZW4oKSApCgl7CiAgICAJU3RyaW5nIGFUZXh0LCBhTGluZTsKICAgIAlzYWxfQm9vbCBiSXNGaXJzdExpbmUgPSBzYWxfVHJ1ZTsKICAgIAlydGxfVGV4dEVuY29kaW5nIGFGaWxlRW5jb2RpbmcgPSBSVExfVEVYVEVOQ09ESU5HX0lCTV84NTA7CiAgICAJd2hpbGUoICFhU3RybS5Jc0VvZigpICYmIGJPayApCiAgICAJewogICAgCQlhU3RybS5SZWFkQnl0ZVN0cmluZ0xpbmUoIGFMaW5lLCBhRmlsZUVuY29kaW5nICk7CiAgICAJCWlmICggYklzRmlyc3RMaW5lICYmIElzVFRTaWduYXR1cmVGb3JVbmljb2RlVGV4dGZpbGUoIGFMaW5lICkgKQogICAgCQkJYUZpbGVFbmNvZGluZyA9IFJUTF9URVhURU5DT0RJTkdfVVRGODsKICAgIAkJZWxzZQogICAgCQl7CiAgICAJCQlpZiAoICFiSXNGaXJzdExpbmUgKQogICAgCQkJCWFUZXh0ICs9ICdcbic7CiAgICAJCQlhVGV4dCArPSBhTGluZTsKICAgIAkJCWJJc0ZpcnN0TGluZSA9IHNhbF9GYWxzZTsKICAgIAkJfQogICAgCQlpZiggYVN0cm0uR2V0RXJyb3IoKSAhPSBTVlNUUkVBTV9PSyApCiAgICAJCQliT2sgPSBzYWxfRmFsc2U7CiAgICAJfQogICAgCWFUZXh0LkNvbnZlcnRMaW5lRW5kKCk7CiAgICAJcE1vZC0+U2V0TmFtZShDVW5pU3RyaW5nKCItLSIpLkFwcGVuZChhRmlsZU5hbWUpKTsKCiAgICAJcE1vZC0+U2V0Q29tbWVudCggR2V0UmV2aXNpb24oIGFUZXh0ICkgKTsKCiAgICAgICAgU2JNb2R1bGUqIHBPbGRNb2R1bGUgPSBNeUJhc2ljOjpHZXRDb21waWxlTW9kdWxlKCk7CiAgICAJTXlCYXNpYzo6U2V0Q29tcGlsZU1vZHVsZSggcE1vZCApOwoKICAgIAlwTW9kLT5TZXRTb3VyY2UoIFByZUNvbXBpbGUoIGFUZXh0ICkgKTsKCiAgICAJTXlCYXNpYzo6U2V0Q29tcGlsZU1vZHVsZSggcE9sZE1vZHVsZSApOwogICAgCWlmICggV2FzUHJlY29tcGlsZXJFcnJvcigpICkKICAgIAkJYk9rID0gc2FsX0ZhbHNlOwoKCX0KCWVsc2UKICAgIAliT2sgPSBzYWxfRmFsc2U7CglyZXR1cm4gYk9rOwp9CgoKc2FsX0Jvb2wgVGVzdFRvb2xPYmo6OlJlYWROYW1lc0JpbiggU3RyaW5nIEZpbGVuYW1lLCBDTmFtZXMgKiZwU0lkcywgQ05hbWVzIComcENvbnRyb2xzICkKewoJU3ZGaWxlU3RyZWFtIGFTdHJlYW07CglTdHJpbmcgICAgICAgYU5hbWUsYVVSTDsKCXJ0bDo6T1N0cmluZyAgICAgIGFVSWQ7CglDb250cm9sRGVmICAgKnBOZXdEZWYsICpwTmV3RGVmMjsKCUNvbnRyb2xEZWYgICAqcEZhdGhlckRlZiA9IE5VTEw7CgoKCWFTdHJlYW0uT3BlbihGaWxlbmFtZSwgU1RSRUFNX1NURF9SRUFEKTsKCWlmICghYVN0cmVhbS5Jc09wZW4oKSkKCXsKICAgIAlBRERfRVJST1IoRVJSX05PX0ZJTEUsR0VOX1JFU19TVFIxKFNfQ0FOTk9UX09QRU5fRklMRSwgRmlsZW5hbWUpKTsKICAgIAlyZXR1cm4gc2FsX0ZhbHNlOwoJfQoKCWlmICggIXBTSWRzICkKICAgIAlwU0lkcyA9IG5ldyBDTmFtZXMoKTsKCWlmICggIXBDb250cm9scyApCiAgICAJcENvbnRyb2xzID0gbmV3IENOYW1lcygpOwoKCXsKICAgIAlUVEV4ZWN1dGlvblN0YXR1c0hpbnQgYUhpbnQoIFRUX0VYRUNVVElPTl9FTlRFUldBSVQgKTsKICAgIAlHZXRUVEJyb2FkY2FzdGVyKCkuQnJvYWRjYXN0KCBhSGludCApOwoJfQoKICAgIHNhbF91SW50MTYgbkFuejsKICAgIGFTdHJlYW0gPj4gbkFuejsKCUNOYW1lcyAqcE5hbWVzID0gcFNJZHM7IC8vIGZpcnN0IHJlYWQgYWxsIHRoZSBzbG90cwogICAgc2FsX0Jvb2wgYklzRmxhdCA9IHNhbF9UcnVlOyAgICAvLyBTbG90cyBkbyBub3QgaGF2ZSBjaGlsZHJlbgoKICAgIHdoaWxlICggbkFueiAmJiAhYVN0cmVhbS5Jc0VvZigpICkKCXsKCiAgICAJYVN0cmVhbS5SZWFkQnl0ZVN0cmluZyggYU5hbWUsIFJUTF9URVhURU5DT0RJTkdfVVRGOCApOwoKICAgICAgICBzYWxfdUludDE2IG5UeXBlOwogICAgIAlhU3RyZWFtID4+IG5UeXBlOwogICAgICAgIGlmICggIW5UeXBlIC8qIEhhc051bWVyaWMoKSAqLykKICAgICAgICB7CiAgICAgICAgICAgIFN0cmluZyBhU3RySWQ7CiAgICAJICAgIGFTdHJlYW0uUmVhZEJ5dGVTdHJpbmcoIGFTdHJJZCwgUlRMX1RFWFRFTkNPRElOR19VVEY4ICk7CiAgICAJICAgIC8vIEZJWE1FOiBIRUxQSUQKICAgIAkgICAgI2lmIDAKICAgICAgICAgICAgYVVJZCA9IHJ0bDo6T1N0cmluZyggYVN0cklkICk7CiAgICAgICAgICAgICNlbmRpZgogICAgICAgIH0KCSAgICBlbHNlCiAgICAgICAgewogICAgICAgIAljb21tX1VMT05HIG5VSWQ7CiAgICAJICAgIGFTdHJlYW0gPj4gblVJZDsKICAgICAgICAgICAgYVVJZCA9IHJ0bDo6T1N0cmluZygpOy8vIG5VSWQ7CiAgICAgICAgfQoKICAgIAlpZiAoYU5hbWUuR2V0Q2hhcigwKSA9PSAnKicgfHwgYklzRmxhdCApICAgICAvLyBHbG9iYWxlciBLdXJ6bmFtZSAoRGlhbG9nbmFtZSBvZGVyIFNJZCkKICAgIAl7CiAgICAJCWlmICghYklzRmxhdCkKICAgIAkJCWFOYW1lLkVyYXNlKDAsMSk7CiAgCQkJcE5ld0RlZiA9IG5ldyBDb250cm9sRGVmKGFOYW1lLGFVSWQpOwoKICAgIAkJaWYgKCFiSXNGbGF0KQogICAgCQl7CiAgICAJCQlwTmV3RGVmLT5Tb25zKG5ldyBDTmFtZXMoKSk7CgoJCQkJcE5ld0RlZjIgPSBuZXcgQ29udHJvbERlZihhTmFtZSxhVUlkKTsJCS8vIE5vY2ggZWluZW4gbWFjaGVuCiAgICAJCQlpZiAoIXBOZXdEZWYtPlNvbkluc2VydChwTmV3RGVmMikpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGlhbG9nIGluIGVpZ2VuZW4gTmFtZXNwYWNlIGVpbnRyYWdlbgogICAgCQkJewogICAgCQkJCWRlbGV0ZSBwTmV3RGVmMjsKICAgIAkJCQlEQkdfRVJST1IoIiAhISEhIEFDSFRVTkcgISEhISAgRmVobGVyIGJlaW0gZWluZu+/vWdlbiBpbiBsZWVyZSBMaXN0ZSEiKTsKICAgIAkJCX0KICAgIAkJfQoKICAgIAkJY29uc3QgQ29udHJvbEl0ZW0gKnBJdGVtID0gcE5ld0RlZjsKICAgIAkJaWYgKCEgcE5hbWVzLT5JbnNlcnQocEl0ZW0pKQogICAgCQl7CiAgICAgICAgICAgICAgICBEQkdfRVJST1IoIiAhISEhIEFDSFRVTkcgISEhISAgRmVobGVyIGJlaW0gZWluZu+/vWdlbiBlaW5lcyBuYW1lbnMhIik7CiAgICAJCQlkZWxldGUgcE5ld0RlZjsKICAgIAkJCXBGYXRoZXJEZWYgPSBOVUxMOwogICAgCQl9CiAgICAJCWVsc2UKICAgIAkJewogICAgCQkJcEZhdGhlckRlZiA9IHBOZXdEZWY7CiAgICAJCX0KICAgIAl9CiAgICAJZWxzZQogICAgCXsKICAgIAkJaWYgKCFwRmF0aGVyRGVmKQogICAgCQl7CiAgICAJCQlEQkdfRVJST1IoICJJbnRlcm5hbCBFcnJvcjogRXJzdGVyIEt1cnpuYW1lIG1177+9IG1pdCAqIGJlZ2lubmVuLiDvv71iZXJzcHJpbmdlLiIgKTsKICAgIAkJfQogICAgCQllbHNlCiAgICAJCXsKICAgCQkJCXBOZXdEZWYgPSBuZXcgQ29udHJvbERlZihhTmFtZSxhVUlkKTsKICAgIAkJCWlmICghIHBGYXRoZXJEZWYtPlNvbkluc2VydChwTmV3RGVmKSkKICAgIAkJCXsKICAgIAkJCQlkZWxldGUgcE5ld0RlZjsKICAgIAkJCQlEQkdfRVJST1IoIiAhISEhIEFDSFRVTkcgISEhISAgRmVobGVyIGJlaW0gZWluZu+/vWdlbiBlaW5lcyBuYW1lbnMhIik7CiAgICAJCQl9CiAgICAJCX0KICAgIAl9CgoKICAgICAgICBuQW56LS07CiAgICAgICAgaWYgKCAhbkFueiAmJiBiSXNGbGF0ICkgICAgIC8vIFdlIGhhdmUgcmVhZCBhbGwgc2xvdHMKICAgICAgICB7CiAgICAgICAgICAgIGFTdHJlYW0gPj4gbkFuejsKCSAgICAgICAgcE5hbWVzID0gcENvbnRyb2xzOyAvLyBOb3cgcmVhZCB0aGUgY29udHJvbHMKICAgICAgICAgICAgYklzRmxhdCA9IHNhbF9GYWxzZTsgICAgLy8gQ29udHJvbHMgKmRvKiBoYXZlIGNoaWxkcmVuCiAgICAgICAgfQoKCiAgICAgICAgR2V0cEFwcCgpLT5SZXNjaGVkdWxlKCk7Cgl9Cgl7CiAgICAJVFRFeGVjdXRpb25TdGF0dXNIaW50IGFIaW50KCBUVF9FWEVDVVRJT05fTEVBVkVXQUlUICk7CiAgICAJR2V0VFRCcm9hZGNhc3RlcigpLkJyb2FkY2FzdCggYUhpbnQgKTsKCX0KCglhU3RyZWFtLkNsb3NlKCk7CglyZXR1cm4gc2FsX1RydWU7Cn0KCgpzYWxfQm9vbCBUZXN0VG9vbE9iajo6V3JpdGVOYW1lc0JpbiggU3RyaW5nIEZpbGVuYW1lLCBDTmFtZXMgKnBTSWRzLCBDTmFtZXMgKnBDb250cm9scyApCnsKCXNhbF9Cb29sIGJPayA9IHNhbF9UcnVlOwoJU3ZGaWxlU3RyZWFtIGFTdHJtKCBTdHJpbmcoRmlsZW5hbWUpLkFwcGVuZEFzY2lpKCIuYmluIiksIFNUUkVBTV9TVERfV1JJVEUgKTsKCWlmKCBhU3RybS5Jc09wZW4oKSApCgl7CiAgICAJc2FsX3VJbnQxNiBpOwogICAgCWlmICggcFNJZHMgKQogICAgICAgIHsKICAgICAgICAgICAgYVN0cm0gPDwgcFNJZHMtPkNvdW50KCk7CiAgICAJCWZvciAoIGkgPSAwIDsgcFNJZHMtPkNvdW50KCkgPiBpICYmIGJPayA7IGkrKyApCiAgICAJCXsKICAgIAkJCSgoQ29udHJvbERlZiopKCpwU0lkcylbaV0pLT5Xcml0ZShhU3RybSk7CiAgICAJCQlpZiggYVN0cm0uR2V0RXJyb3IoKSAhPSBTVlNUUkVBTV9PSyApCiAgICAJCQkJYk9rID0gc2FsX0ZhbHNlOwogICAgCQl9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgYVN0cm0gPDwgc2FsX3VJbnQxNiggMCApOwoKICAgIAlpZiAoIHBDb250cm9scyApCiAgICAgICAgewogICAgICAgICAgICBhU3RybSA8PCBwQ29udHJvbHMtPkNvdW50KCk7CiAgICAJCWZvciAoIGkgPSAwIDsgcENvbnRyb2xzLT5Db3VudCgpID4gaSAmJiBiT2sgOyBpKysgKQogICAgCQl7CiAgICAJCQkoKENvbnRyb2xEZWYqKSgqcENvbnRyb2xzKVtpXSktPldyaXRlKGFTdHJtKTsKICAgIAkJCWlmKCBhU3RybS5HZXRFcnJvcigpICE9IFNWU1RSRUFNX09LICkKICAgIAkJCQliT2sgPSBzYWxfRmFsc2U7CiAgICAJCX0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBhU3RybSA8PCBzYWxfdUludDE2KCAwICk7Cgl9CiAgICBlbHNlCiAgICAgICAgYk9rID0gc2FsX0ZhbHNlOwoJcmV0dXJuIGJPazsKfQoKCnZvaWQgVGVzdFRvb2xPYmo6OlNGWF9OT1RJRlkoIFNmeEJyb2FkY2FzdGVyJiwgY29uc3QgVHlwZUlkJiwKICAgIAkJCQkJCWNvbnN0IFNmeEhpbnQmIHJIaW50LCBjb25zdCBUeXBlSWQmICkKewoJc3RhdGljIENOYW1lcyAqcFVJZHMgPSBOVUxMOyAgICAvLyBIYWx0ZW4gZGVyIGhpZC5sc3QKCgljb25zdCBTYnhIaW50KiBwID0gUFRSX0NBU1QoU2J4SGludCwmckhpbnQpOwoJaWYoIHAgKQoJewogICAgCVNieFZhcmlhYmxlKiBwVmFyID0gcC0+R2V0VmFyKCk7CiAgICAJU2J4QXJyYXkqIHJQYXIgPSBwVmFyLT5HZXRQYXJhbWV0ZXJzKCk7CgogICAgCXNhbF91TG9uZyBuSGludElkID0gcC0+R2V0SWQoKTsKICAgIAlzYWxfdUxvbmcgbkhpbnRVc2VyRGF0YSA9IHBWYXItPkdldFVzZXJEYXRhKCk7CiAgICAJaWYoIG5IaW50SWQgPT0gU0JYX0hJTlRfREFUQVdBTlRFRCApCiAgICAJewogICAgCQluTXlWYXIgPSAwOwogICAgCQlzd2l0Y2goIG5IaW50VXNlckRhdGEgKQogICAgCQl7CiAgICAJCQljYXNlIElEX0tvbnRleHQ6CiAgICAJCQkJaWYgKCAhclBhciApCiAgICAJCQkJewogICAgCQkJCQltX3BOYW1lS29udGV4dCA9IG1fcENvbnRyb2xzOwoKICAgIAkJCQkJLy8gU28gZGHvv70gbmljaHQgaW1tZXIgbWFsIHdpZWRlciB3YXMgYXVzIGVpbmVtIGFsdGVuIEtvbnRleHQgZGF6d2lzY2hlbmhhdXQKICAgIAkJCQkJZm9yIChzYWxfdUludDE2IGk9MDtpPFZBUl9QT09MX1NJWkU7aSsrKQogICAgCQkJCQl7CiAgICAJCQkJCQlwSW1wbC0+cE15VmFyc1tpXS0+U2V0TmFtZSggQ1VuaVN0cmluZygiVmFyRHVtbXkiKS5BcHBlbmQoVW5pU3RyaW5nOjpDcmVhdGVGcm9tSW50MzIoaSkpICk7CiAgICAJCQkJCX0KICAgIAkJCQl9CiAgICAJCQkJZWxzZSBpZiAoIHJQYXIgJiYgclBhci0+Q291bnQoKSA9PSAyICkKICAgIAkJCQl7CiAgICAJCQkJCXNhbF91SW50MTYgbkVsZW1lbnQ7CiAgICAJCQkJCVNieFZhcmlhYmxlUmVmIHBBcmcgPSByUGFyLT5HZXQoIDEgKTsKICAgIAkJCQkJU3RyaW5nIGFLb250ZXh0ID0gcEFyZy0+R2V0U3RyaW5nKCk7CiAgICAJCQkJCUNvbnRyb2xEZWYgV2hhdE5hbWUoYUtvbnRleHQscnRsOjpPU3RyaW5nKCkpOwogICAgCQkJCQlpZiAobV9wQ29udHJvbHMgJiYgbV9wQ29udHJvbHMtPlNlZWtfRW50cnkoJldoYXROYW1lLCZuRWxlbWVudCkpCiAgICAJCQkJCXsKICAgIAkJCQkJCW1fcE5hbWVLb250ZXh0ID0gKChDb250cm9sRGVmKiltX3BDb250cm9scy0+R2V0T2JqZWN0KG5FbGVtZW50KSktPkdldFNvbnMoKTsKCiAgICAJCQkJCQkvLyBTbyBkYe+/vSBuaWNodCBpbW1lciBtYWwgd2llZGVyIHdhcyBhdXMgZWluZW0gYWx0ZW4gS29udGV4dCBkYXp3aXNjaGVuaGF1dAogICAgCQkJCQkJZm9yIChzYWxfdUludDE2IGk9MDtpPFZBUl9QT09MX1NJWkU7aSsrKQogICAgCQkJCQkJewogICAgCQkJCQkJCXBJbXBsLT5wTXlWYXJzW2ldLT5TZXROYW1lKCBDVW5pU3RyaW5nKCJWYXJEdW1teSIpLkFwcGVuZChVbmlTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMihpKSkgKTsKICAgIAkJCQkJCX0KICAgIAkJCQkJfQogICAgCQkJCX0KICAgIAkJCQllbHNlCiAgICAJCQkJCVNldEVycm9yKCBTYnhFUlJfV1JPTkdfQVJHUyApOwogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9TdGFydDoKICAgIAkJCQlpZiAoIHJQYXIgJiYgclBhci0+Q291bnQoKSA+PSAyICkKICAgIAkJCQl7CiAgICAJCQkJCVNieFZhcmlhYmxlUmVmIHBBcmcgPSByUGFyLT5HZXQoIDEgKTsKICAgIAkJCQkJUHJvZ1BhdGggPSBwQXJnLT5HZXRTdHJpbmcoKTsKICAgIAkJCQkJaWYgKCByUGFyICYmIHJQYXItPkNvdW50KCkgPj0gMyApCiAgICAJCQkJCXsKICAgIAkJCQkJCXBBcmcgPSByUGFyLT5HZXQoIDIgKTsKICAgIAkJCQkJCXBJbXBsLT5Qcm9nUGFyYW0gPSBwQXJnLT5HZXRTdHJpbmcoKTsKICAgIAkJCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+UHJvZ1BhcmFtLkVyYXNlKCk7CgogICAgCQkJCQlTdHJpbmcgYVRtcFN0cihQcm9nUGF0aCk7CiAgICAJCQkJCWFUbXBTdHIgKz0gJyAnOwogICAgCQkJCQlhVG1wU3RyICs9IHBJbXBsLT5Qcm9nUGFyYW07CgkgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAJCQkJCVRURXhlY3V0aW9uU3RhdHVzSGludCBhSGludCggVFRfRVhFQ1VUSU9OX1NIT1dfQUNUSU9OLCBTdHJpbmcoU3R0UmVzSWQoU19TVEFSVElOR19BUFBMSUNBVElPTikpLCBhVG1wU3RyICk7CiAgICAgICAgCQkJCQlHZXRUVEJyb2FkY2FzdGVyKCkuQnJvYWRjYXN0KCBhSGludCApOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+YklzU3RhcnQgPSBzYWxfVHJ1ZTsKICAgIAkJCQkJQmVnaW5CbG9jaygpOwogICAgCQkJCQlFbmRCbG9jaygpOwogICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+YklzU3RhcnQgPSBzYWxfRmFsc2U7CgkgICAgICAgICAgICAgICAgICAgIHsKICAgIAkgICAgICAgICAgICAgICAgICAgIFRURXhlY3V0aW9uU3RhdHVzSGludCBhSGludCggVFRfRVhFQ1VUSU9OX0hJREVfQUNUSU9OICk7CiAgICAJICAgICAgICAgICAgICAgICAgICBHZXRUVEJyb2FkY2FzdGVyKCkuQnJvYWRjYXN0KCBhSGludCApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJfQogICAgCQkJCWJyZWFrOwoJCQkJY2FzZSBJRF9LaWxsQXBwOgogICAgICAgICAgICAgICAgICAgIHBDb21tdW5pY2F0aW9uTWFuYWdlci0+S2lsbEFwcGxpY2F0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAJCQljYXNlIElEX1NhdmVJRHM6CiAgICAJCQkJaWYgKCByUGFyICYmIHJQYXItPkNvdW50KCkgPj0gMiApICAvLyBHZW5hdSBlaW4gUGFyYW1ldGVyCiAgICAJCQkJewogICAgCQkJCQlTYnhWYXJpYWJsZVJlZiBwQXJnID0gclBhci0+R2V0KCAxICk7CiAgICAJCQkJCURpckVudHJ5IEZpbGVQYXRoID0gcEltcGwtPmFGaWxlQmFzZSArIERpckVudHJ5KHBBcmctPkdldFN0cmluZygpLEZTWVNfU1RZTEVfVkZBVCk7CiAgICAJCQkJCVdyaXRlTmFtZXNCaW4oIEZpbGVQYXRoLkdldEZ1bGwoKSwgbV9wU0lkcywgbV9wQ29udHJvbHMgKTsKICAgIAkJCQl9CiAgICAJCQkJZWxzZQogICAgCQkJCQlTZXRFcnJvciggU2J4RVJSX1dST05HX0FSR1MgKTsKICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfQXV0b0V4ZWN1dGU6CiAgICAJCQkJaWYgKCAhclBhciApICAvLyByUGFyID0gTlVMTCAgPD0+ICBLZWluIFBhcmFtZXRlcgogICAgCQkJCXsKICAgIAkJCQkJcFZhci0+UHV0Qm9vbChTaW5nbGVDb21tYW5kQmxvY2spOwogICAgCQkJCX0KICAgIAkJCQllbHNlCiAgICAJCQkJCVNldEVycm9yKCBTYnhFUlJfV1JPTkdfQVJHUyApOwogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9FeGVjdXRlOgogICAgCQkJCWlmICggIXJQYXIgKSAgLy8gclBhciA9IE5VTEwgIDw9PiAgS2VpbiBQYXJhbWV0ZXIKICAgIAkJCQl7CiAgICAJCQkJCUVuZEJsb2NrKCk7CiAgICAJCQkJCUJlZ2luQmxvY2soKTsKICAgIAkJCQl9CiAgICAJCQkJZWxzZQogICAgCQkJCQlTZXRFcnJvciggU2J4RVJSX1dST05HX0FSR1MgKTsKICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfRGlhbG9nSGFuZGxlcjoKICAgIAkJCQlpZiAoIHJQYXIgJiYgclBhci0+Q291bnQoKSA+PSAyICkgIC8vIEdlbmF1IGVpbiBQYXJhbWV0ZXIKICAgIAkJCQl7CiAgICAJCQkJCVNieFZhcmlhYmxlUmVmIHBBcmcgPSByUGFyLT5HZXQoIDEgKTsKICAgIAkJCQkJYURpYWxvZ0hhbmRsZXJOYW1lID0gcEFyZy0+R2V0U3RyaW5nKCk7CiAgICAJCQkJfQogICAgCQkJCWVsc2UKICAgIAkJCQkJU2V0RXJyb3IoIFNieEVSUl9XUk9OR19BUkdTICk7CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0dldEVycm9yOgogICAgCQkJCWlmICggIXJQYXIgKSAgLy8gclBhciA9IE5VTEwgIDw9PiAgS2VpbiBQYXJhbWV0ZXIKICAgIAkJCQl7CiAgICAJCQkJCVdhaXRGb3JBbnN3ZXIoKTsKICAgIAkJCQkJaWYgKCBJU19FUlJPUigpICkKICAgIAkJCQkJewovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dFVMb25nKCBHRVRfRVJST1IoKS0+bkVycm9yICk7CiAgICAJCQkJCQlwVmFyLT5QdXRTdHJpbmcoIEdFVF9FUlJPUigpLT5hVGV4dCApOwogICAgCQkJCQkJUE9QX0VSUk9SKCk7CiAgICAJCQkJCX0KICAgIAkJCQkJZWxzZQogICAgCQkJCQl7Ci8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFZhci0+UHV0VUxvbmcoIDAgKTsKICAgIAkJCQkJCXBWYXItPlB1dFN0cmluZyggU3RyaW5nKCkgKTsKICAgIAkJCQkJfQogICAgCQkJCX0KICAgIAkJCQllbHNlCiAgICAJCQkJCVNldEVycm9yKCBTYnhFUlJfV1JPTkdfQVJHUyApOwogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9TdGFydFVzZToKICAgIAkJCQlpZiAoICFyUGFyICkgIC8vIHJQYXIgPSBOVUxMICA8PT4gIEtlaW4gUGFyYW1ldGVyCiAgICAJCQkJewogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAJCQkJCSAgICBCYXNpY1J1bnRpbWUgYVJ1biA9IEJhc2ljUnVudGltZUFjY2Vzczo6R2V0UnVudGltZSgpOwogICAgCQkJCQkgICAgYUxvZ0ZpbGVOYW1lID0gRGlyRW50cnkoYVJ1bi5HZXRNb2R1bGVOYW1lKFNieE5BTUVfTk9ORSkpLkdldEJhc2UoKS5BcHBlbmRBc2NpaSgiLnJlcyIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgCQkJCQlBRERfUlVOX0xPRygpOwogICAgCQkJCQlBRERfQ0FTRV9MT0coR0VOX1JFU19TVFIwKFNfUkVBRElOR19GSUxFKSk7CgogICAgCQkJCQlwQ29tbXVuaWNhdGlvbk1hbmFnZXItPlN0b3BDb21tdW5pY2F0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdhaXQgZm9yIGFzeW5jaHJvbm91cyBldmVudHMgdG8gYmUgcHJvY2Vzc2VkLCBzbyBjb21tdW5pY2F0aW9uIHdpbGwgYmUgcmVzdGFydGVkIHByb3Blcmx5CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICggcENvbW11bmljYXRpb25NYW5hZ2VyLT5Jc0NvbW11bmljYXRpb25SdW5uaW5nKCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgQXBwbGljYXRpb246OlJlc2NoZWR1bGUoKTsKCiAgICAJCQkJCVNpbmdsZUNvbW1hbmRCbG9jayA9IHNhbF9UcnVlOwkJLy8gQnVnIDU3MTg4CiAgICAJCQkJCUlzQmxvY2sgPSBzYWxfRmFsc2U7CgovLwkJCQkJCXBDb21tdW5pY2F0aW9uTWFuYWdlci0+U3RhcnRDb21tdW5pY2F0aW9uKCk7CgogICAgCQkJCQlmb3IgKHNhbF91SW50MTYgaT0wO2k8VkFSX1BPT0xfU0laRTtpKyspCiAgICAJCQkJCXsKICAgIAkJCQkJCXBJbXBsLT5wTXlWYXJzW2ldLT5TZXROYW1lKCBDVW5pU3RyaW5nKCJWYXJEdW1teSIpLkFwcGVuZChVbmlTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMihpKSkgKTsKICAgIAkJCQkJfQogICAgCQkJCQluTXlWYXIgPSAwOwoKICAgIAkJCQkJaWYgKG1fcENvbnRyb2xzKQogICAgCQkJCQl7CiAgICAJCQkJCQlkZWxldGUgbV9wQ29udHJvbHM7CiAgICAJCQkJCQltX3BDb250cm9scyA9IE5VTEw7CiAgICAJCQkJCX0KICAgIAkJCQkJaWYgKG1fcFJldmVyc2VTbG90cykKICAgIAkJCQkJewogICAgCQkJCQkJZGVsZXRlIG1fcFJldmVyc2VTbG90czsKICAgIAkJCQkJCW1fcFJldmVyc2VTbG90cyA9IE5VTEw7CiAgICAJCQkJCX0KICAgIAkJCQkJaWYgKG1fcFJldmVyc2VDb250cm9scykKICAgIAkJCQkJewogICAgCQkJCQkJZGVsZXRlIG1fcFJldmVyc2VDb250cm9sczsKICAgIAkJCQkJCW1fcFJldmVyc2VDb250cm9scyA9IE5VTEw7CiAgICAJCQkJCX0KICAgIAkJCQkJaWYgKG1fcFJldmVyc2VDb250cm9sc1NvbikKICAgIAkJCQkJewogICAgCQkJCQkJZGVsZXRlIG1fcFJldmVyc2VDb250cm9sc1NvbjsKICAgIAkJCQkJCW1fcFJldmVyc2VDb250cm9sc1NvbiA9IE5VTEw7CiAgICAJCQkJCX0KICAgIAkJCQkJaWYgKG1fcFNJZHMpCiAgICAJCQkJCXsKICAgIAkJCQkJCWRlbGV0ZSBtX3BTSWRzOwogICAgCQkJCQkJbV9wU0lkcyA9IE5VTEw7CiAgICAJCQkJCX0KICAgIAkJCQkJaWYgKHBVSWRzKQogICAgCQkJCQl7CiAgICAJCQkJCQlkZWxldGUgcFVJZHM7CiAgICAJCQkJCQlwVUlkcyA9IE5VTEw7CiAgICAJCQkJCX0KICAgIAkJCQkJaWYgKG1fcFJldmVyc2VVSWRzKQogICAgCQkJCQl7CiAgICAJCQkJCQlkZWxldGUgbV9wUmV2ZXJzZVVJZHM7CiAgICAJCQkJCQltX3BSZXZlcnNlVUlkcyA9IE5VTEw7CiAgICAJCQkJCX0KICAgIAkJCQkJbV9wTmFtZUtvbnRleHQgPSBtX3BDb250cm9sczsKICAgIAkJCQkJcEltcGwtPmJMbmFndWFnZUV4dGVuc2lvbkxvYWRlZCA9IHNhbF9GYWxzZTsKICAgIAkJCQkJU2Z4U2ltcGxlSGludCBhSGludCggU0JYX0hJTlRfTEFOR1VBR0VfRVhURU5TSU9OX0xPQURFRCApOwogICAgCQkJCQlHZXRUVEJyb2FkY2FzdGVyKCkuQnJvYWRjYXN0KCBhSGludCApOwoKICAgIAkJCQkJcEltcGwtPm5NaW5SZW1vdGVDb21tYW5kRGVsYXkgPSAwOwogICAgCQkJCQlwSW1wbC0+bk1heFJlbW90ZUNvbW1hbmREZWxheSA9IDA7CiAgICAJCQkJCXBJbXBsLT5iRG9SZW1vdGVDb21tYW5kRGVsYXkgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5hVGVzdENhc2VOYW1lLkVyYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5hVGVzdENhc2VGaWxlTmFtZS5FcmFzZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+blRlc3RDYXNlTGluZU5yID0gMDsKCiAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5iRW5hYmxlUWFFcnJvcnMgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgcEltcGwtPmJEZWJ1Z0ZpbmROb0Vycm9ycyA9IHNhbF9GYWxzZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5wQ2hpbGRFbnYtPmNsZWFyKCk7CgogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYU5hbWUoIENVbmlTdHJpbmcoICJTdG9wT25TeW50YXhFcnJvciIgKSApOwogICAgICAgICAgICAgICAgICAgIAlTYnhWYXJpYWJsZVJlZiB4U3RvcE9uU3ludGF4RXJyb3IgPSBTYnhPYmplY3Q6OkZpbmQoIGFOYW1lLCBTYnhDTEFTU19QUk9QRVJUWSApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHhTdG9wT25TeW50YXhFcnJvci5JcygpICkKICAgIAkJCSAgICAgICAgICAgIHhTdG9wT25TeW50YXhFcnJvci0+UHV0Qm9vbCggcEltcGwtPmJTdG9wT25TeW50YXhFcnJvciApOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRFcnJvciggU2J4RVJSX0JBRF9BQ1RJT04gKTsKICAgIAkJCQl9CiAgICAJCQkJZWxzZQogICAgCQkJCQlTZXRFcnJvciggU2J4RVJSX1dST05HX0FSR1MgKTsKICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfVXNlOgogICAgCQkJCWlmICggclBhciAmJiByUGFyLT5Db3VudCgpID49IDIgKQogICAgCQkJCXsKICAgIAkJCQkJU2J4VmFyaWFibGVSZWYgcEFyZyA9IHJQYXItPkdldCggMSApOwogICAgICAgICAgICAgICAgICAgICAgICBEaXJFbnRyeSBGaWxlUGF0aChwQXJnLT5HZXRTdHJpbmcoKSxGU1lTX1NUWUxFX1ZGQVQpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFGaWxlUGF0aC5Jc0FicygpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVQYXRoID0gcEltcGwtPmFGaWxlQmFzZSArIEZpbGVQYXRoOwogICAgCQkJCQlTdHJpbmcgRXh0ID0gRmlsZVBhdGguR2V0RXh0ZW5zaW9uKCk7CiAgICAJCQkJCWlmICggRXh0LkNvbXBhcmVJZ25vcmVDYXNlVG9Bc2NpaSgiV2luIikgPT0gQ09NUEFSRV9FUVVBTCApCiAgICAJCQkJCXsKICAgIAkJCQkJCVJlYWROYW1lcyggRmlsZVBhdGguR2V0RnVsbCgpLG1fcENvbnRyb2xzLHBVSWRzKTsKICAgIAkJCQkJCXBJbXBsLT5iTG5hZ3VhZ2VFeHRlbnNpb25Mb2FkZWQgPSBzYWxfVHJ1ZTsKICAgIAkJCQkJCVNmeFNpbXBsZUhpbnQgYUhpbnQoIFNCWF9ISU5UX0xBTkdVQUdFX0VYVEVOU0lPTl9MT0FERUQgKTsKICAgIAkJCQkJCUdldFRUQnJvYWRjYXN0ZXIoKS5Ccm9hZGNhc3QoIGFIaW50ICk7CiAgICAJCQkJCX0KICAgIAkJCQkJZWxzZSBpZiAoIEV4dC5Db21wYXJlSWdub3JlQ2FzZVRvQXNjaWkoIlNpZCIpID09IENPTVBBUkVfRVFVQUwgKQogICAgCQkJCQl7CiAgICAJCQkJCQlSZWFkTmFtZXMoIEZpbGVQYXRoLkdldEZ1bGwoKSxtX3BTSWRzLHBVSWRzLEZMQVQpOwogICAgCQkJCQkJcEltcGwtPmJMbmFndWFnZUV4dGVuc2lvbkxvYWRlZCA9IHNhbF9UcnVlOwogICAgCQkJCQkJU2Z4U2ltcGxlSGludCBhSGludCggU0JYX0hJTlRfTEFOR1VBR0VfRVhURU5TSU9OX0xPQURFRCApOwogICAgCQkJCQkJR2V0VFRCcm9hZGNhc3RlcigpLkJyb2FkY2FzdCggYUhpbnQgKTsKICAgIAkJCQkJfQogICAgCQkJCQllbHNlIGlmICggRXh0LkNvbXBhcmVJZ25vcmVDYXNlVG9Bc2NpaSgiQmluIikgPT0gQ09NUEFSRV9FUVVBTCApCiAgICAJCQkJCXsKICAgIAkJCQkJCVJlYWROYW1lc0JpbiggRmlsZVBhdGguR2V0RnVsbCgpLCBtX3BTSWRzLCBtX3BDb250cm9scyApOwogICAgCQkJCQkJcEltcGwtPmJMbmFndWFnZUV4dGVuc2lvbkxvYWRlZCA9IHNhbF9UcnVlOwogICAgCQkJCQkJU2Z4U2ltcGxlSGludCBhSGludCggU0JYX0hJTlRfTEFOR1VBR0VfRVhURU5TSU9OX0xPQURFRCApOwogICAgCQkJCQkJR2V0VFRCcm9hZGNhc3RlcigpLkJyb2FkY2FzdCggYUhpbnQgKTsKICAgIAkJCQkJfQogICAgCQkJCQllbHNlIGlmICggRXh0LkNvbXBhcmVJZ25vcmVDYXNlVG9Bc2NpaSgiSW5jIikgPT0gQ09NUEFSRV9FUVVBTCApCiAgICAJCQkJCXsKICAgIAkJCQkJCXsKICAgIAkJCQkJCQlUVEV4ZWN1dGlvblN0YXR1c0hpbnQgYUhpbnQoIFRUX0VYRUNVVElPTl9TSE9XX0FDVElPTiwgU3RyaW5nKFN0dFJlc0lkKFNfUkVBRElOR19CQVNJQ19NT0RVTEUpKSwgRmlsZVBhdGguR2V0RnVsbCgpICk7CiAgICAJCQkJCQkJR2V0VFRCcm9hZGNhc3RlcigpLkJyb2FkY2FzdCggYUhpbnQgKTsKICAgIAkJCQkJCX0KICAgIAkJCQkJCVN0cmluZyBhRnVsbFBhdGhuYW1lID0gRmlsZVBhdGguR2V0RnVsbCgpOwogICAgCQkJCQkJU3RhckJBU0lDICpwQmFzaWMgPSAoU3RhckJBU0lDKilHZXRQYXJlbnQoKTsKICAgIAkJCQkJCWlmICggIWFNb2R1bGVXaW5FeGlzdHNIZGwuQ2FsbCggJmFGdWxsUGF0aG5hbWUgKSAmJgogICAgCQkJCQkJCSAhcEJhc2ljLT5GaW5kTW9kdWxlKCBDVW5pU3RyaW5nKCAiLS0iICkuQXBwZW5kKGFGdWxsUGF0aG5hbWUpICkgKQogICAgCQkJCQkJewogICAgCQkJCQkJCVNiTW9kdWxlICpwTW9kOwogICAgCQkJCQkJCXBNb2QgPSBwQmFzaWMtPk1ha2VNb2R1bGUoIENVbmlTdHJpbmcoIi0tIiksIFN0cmluZygpICk7CiAgICAJCQkJCQkJcE1vZC0+Q2xlYXIoKTsKICAgIAkJCQkJCQlpZiAoIExvYWQoIGFGdWxsUGF0aG5hbWUsIHBNb2QgKSApCiAgICAJCQkJCQkJewogICAgCQkJCQkJCQlpZiAoICFJU19FUlJPUigpICkKICAgIAkJCQkJCQkJewogICAgCQkJCQkJCQkJcEJhc2ljLT5Db21waWxlKCBwTW9kICk7CiAgICAJCQkJCQkJCQlwTW9kLT5SdW5Jbml0KCk7CiAgICAJCQkJCQkJCX0KICAgIAkJCQkJCQl9CiAgICAJCQkJCQkJZWxzZQogICAgCQkJCQkJCXsKICAgIAkJCQkJCQkJQUREX0VSUk9SKCBTYnhFUlJfQ0FOTk9UX0xPQUQsIEZpbGVQYXRoLkdldEZ1bGwoKSApOwogICAgCQkJCQkJCX0KICAgIAkJCQkJCX0KCSAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgIAkgICAgICAgICAgICAgICAgICAgICAgICBUVEV4ZWN1dGlvblN0YXR1c0hpbnQgYUhpbnQoIFRUX0VYRUNVVElPTl9ISURFX0FDVElPTiApOwogICAgCSAgICAgICAgICAgICAgICAgICAgICAgIEdldFRUQnJvYWRjYXN0ZXIoKS5Ccm9hZGNhc3QoIGFIaW50ICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJCX0KICAgIAkJCQkJZWxzZQogICAgCQkJCQl7CiAgICAJCQkJCQlBRERfRVJST1IoU2J4RVJSX0NBTk5PVF9MT0FELEZpbGVQYXRoLkdldEZ1bGwoKSk7CiAgICAJCQkJCX0KICAgIAkJCQl9CiAgICAJCQkJZWxzZQogICAgCQkJCQlTZXRFcnJvciggU2J4RVJSX1dST05HX0FSR1MgKTsKICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfRmluaXNoVXNlOgogICAgCQkJCWlmICggIXJQYXIgKSAgLy8gclBhciA9IE5VTEwgIDw9PiAgS2VpbiBQYXJhbWV0ZXIKICAgIAkJCQl7CiAgICAJCQkJCUFERF9DQVNFX0xPRyggU3RyaW5nKCkgKTsgICAgICAgLy8gQ2FzZSBhYnNjaGxpZXNzZW4KICAgIAkJCQkJaWYgKCFtX3BDb250cm9scykKICAgIAkJCQkJCW1fcENvbnRyb2xzID0gbmV3IENOYW1lcygpOwoKICAgIAkJCQkJaWYgKCFtX3BTSWRzKQogICAgCQkJCQkJbV9wU0lkcyA9IG5ldyBDTmFtZXMoKTsKCiAgICAJCQkJCWlmIChwVUlkcykKICAgIAkJCQkJeyAgIC8vIHNhdmUgc29tZSBtZW1vcnkKICAgIAkJCQkJCWRlbGV0ZSBwVUlkczsKICAgIAkJCQkJCXBVSWRzID0gTlVMTDsKICAgIAkJCQkJfQoKICAgIAkJCQkJbV9wTmFtZUtvbnRleHQgPSBtX3BDb250cm9sczsKCiAgICAJCQkJCWlmICggcEltcGwtPmJMbmFndWFnZUV4dGVuc2lvbkxvYWRlZCApCiAgICAJCQkJCXsKICAgIAkJCQkJCVNmeFNpbXBsZUhpbnQgYUhpbnQoIFNCWF9ISU5UX0xBTkdVQUdFX0VYVEVOU0lPTl9MT0FERUQgKTsKICAgIAkJCQkJCUdldFRUQnJvYWRjYXN0ZXIoKS5Ccm9hZGNhc3QoIGFIaW50ICk7CiAgICAJCQkJCX0KCiAgICAJCQkJCXBJbXBsLT5uSW5jbHVkZUZpbGVXYXJuaW5nQ291bnQgPSBwSW1wbC0+bldhcm5pbmdDb3VudDsKICAgIAkJCQkJcEltcGwtPm5XYXJuaW5nQ291bnQgPSAwOwoKICAgICAgICAgICAgICAgICAgICAgICAgKnBJbXBsLT54SW5jbHVkZUZpbGVXYXJuaW5nTGlzdCA9ICpwSW1wbC0+eFdhcm5pbmdMaXN0OwogICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+eFdhcm5pbmdMaXN0LT5TYnhBcnJheTo6Q2xlYXIoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJZWxzZQogICAgCQkJCQlTZXRFcnJvciggU2J4RVJSX1dST05HX0FSR1MgKTsKICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfQ2FzZUxvZzoKICAgIAkJCQlpZiAoIHJQYXIgKSAgLy8gclBhciAhPSBOVUxMICA8PT4gIEVzIGdpYnQgUGFyYW1ldGVyCiAgICAJCQkJewogICAgCQkJCQlzYWxfdUludDE2IG47CiAgICAJCQkJCVN0cmluZyBhWDsKICAgIAkJCQkJZm9yICggbiA9IDE7IG4gPCByUGFyLT5Db3VudCgpOyBuKysgKQogICAgCQkJCQl7CiAgICAJCQkJCQlTYnhWYXJpYWJsZVJlZiBwQXJnID0gclBhci0+R2V0KCBuICk7CiAgICAJCQkJCQlhWCArPSBwQXJnLT5HZXRTdHJpbmcoKTsKICAgIAkJCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+YVRlc3RDYXNlTmFtZSA9IGFYOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHBJbXBsLT5hVGVzdENhc2VOYW1lLkxlbigpICYmIEJhc2ljUnVudGltZUFjY2Vzczo6SGFzUnVudGltZSgpICkKICAgICAgICAgICAgICAgICAgICAgICAgewoJCSAgICAgICAgICAgICAgICAgICAgQmFzaWNSdW50aW1lIGFSdW4gPSBCYXNpY1J1bnRpbWVBY2Nlc3M6OkdldFJ1bnRpbWUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5hVGVzdENhc2VGaWxlTmFtZSA9IGFSdW4uR2V0TW9kdWxlTmFtZShTYnhOQU1FX1NIT1JUX1RZUEVTKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIGlmICggcEltcGwtPmFUZXN0Q2FzZUZpbGVOYW1lLkNvcHkoMCwyKS5Db21wYXJlVG9Bc2NpaSggIi0tIiApID09IENPTVBBUkVfRVFVQUwgKQoJCSAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5hVGVzdENhc2VGaWxlTmFtZS5FcmFzZSgwLDIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcEltcGwtPm5UZXN0Q2FzZUxpbmVOciA9IGFSdW4uR2V0TGluZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcEltcGwtPmFUZXN0Q2FzZUZpbGVOYW1lLkVyYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+blRlc3RDYXNlTGluZU5yID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCQlBRERfQ0FTRV9MT0coIGFYICk7CiAgICAJCQkJfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9FeGNlcHRMb2c6CiAgICAJCQkJaWYgKCBJU19FUlJPUigpICkKICAgIAkJCQl7CiAgICAJCQkJCUJhc2ljUnVudGltZSBhUnVuID0gQmFzaWNSdW50aW1lQWNjZXNzOjpHZXRSdW50aW1lKCk7CiAgICAJCQkJCXNhbF9Cb29sIGJXYXNOZXdFcnJvciA9IHNhbF9GYWxzZTsKCiAgICAJCQkJCWlmICggQmFzaWNSdW50aW1lQWNjZXNzOjpIYXNTdGFjaygpICkKICAgIAkJCQkJewogICAgCQkJCQkJZm9yICggc2FsX3VJbnQxNiBpID0gMCA7IGkgPCBCYXNpY1J1bnRpbWVBY2Nlc3M6OkdldFN0YWNrRW50cnlDb3VudCgpIC0xIDsgaSsrICkKICAgIAkJCQkJCXsKICAgIAkJCQkJCQlCYXNpY0Vycm9yU3RhY2tFbnRyeSBhVGhpc0VudHJ5ID0gQmFzaWNSdW50aW1lQWNjZXNzOjpHZXRTdGFja0VudHJ5KGkpOwogICAgCQkJCQkJCWlmICggIWJXYXNOZXdFcnJvciApCiAgICAJCQkJCQkJewogICAgCQkJCQkJCQliV2FzTmV3RXJyb3IgPSBzYWxfVHJ1ZTsKICAgIAkJCQkJCQkJQUREX0VSUk9SX0xPRyggR0VUX0VSUk9SKCktPmFUZXh0LCBhVGhpc0VudHJ5LkdldE1vZHVsZU5hbWUoU2J4TkFNRV9TSE9SVF9UWVBFUyksCiAgICAJCQkJCQkJCQlhVGhpc0VudHJ5LkdldExpbmUoKSwgYVRoaXNFbnRyeS5HZXRDb2wxKCksIGFUaGlzRW50cnkuR2V0Q29sMigpLCBhVGhpc0VudHJ5LkdldFNvdXJjZVJldmlzaW9uKCkgKTsKICAgIAkJCQkJCQl9CiAgICAJCQkJCQkJQUREX0NBTExfU1RBQ0tfTE9HKCBTdHJpbmcoYVRoaXNFbnRyeS5HZXRNb2R1bGVOYW1lKFNieE5BTUVfU0hPUlRfVFlQRVMpKQogICAgCQkJCQkJCQkuQXBwZW5kQXNjaWkoIjogIikuQXBwZW5kKGFUaGlzRW50cnkuR2V0TWV0aG9kTmFtZShTYnhOQU1FX1NIT1JUX1RZUEVTKSksCiAgICAJCQkJCQkJCWFUaGlzRW50cnkuR2V0TW9kdWxlTmFtZShTYnhOQU1FX1NIT1JUX1RZUEVTKSwKICAgIAkJCQkJCQkJYVRoaXNFbnRyeS5HZXRMaW5lKCksIGFUaGlzRW50cnkuR2V0Q29sMSgpLCBhVGhpc0VudHJ5LkdldENvbDIoKSApOwoKICAgIAkJCQkJCX0KICAgIAkJCQkJCUJhc2ljUnVudGltZUFjY2Vzczo6RGVsZXRlU3RhY2soKTsKICAgIAkJCQkJfQoKICAgIAkJCQkJc2FsX0Jvb2wgYklzRmlyc3QgPSBzYWxfVHJ1ZTsKICAgIAkJCQkJd2hpbGUgKCBhUnVuLklzVmFsaWQoKSApCiAgICAJCQkJCXsKICAgIAkJCQkJCXh1Yl9TdHJMZW4gbkVyckxuOwogICAgCQkJCQkJeHViX1N0ckxlbiBuQ29sMTsKICAgIAkJCQkJCXh1Yl9TdHJMZW4gbkNvbDI7CiAgICAJCQkJCQlpZiAoIGJJc0ZpcnN0ICkKICAgIAkJCQkJCXsKICAgIAkJCQkJCQliSXNGaXJzdCA9IHNhbF9GYWxzZTsKICAgIAkJCQkJCQluRXJyTG4gPSBHRVRfRVJST1IoKS0+bkxpbmU7CiAgICAJCQkJCQkJbkNvbDEgPSBHRVRfRVJST1IoKS0+bkNvbDE7CiAgICAJCQkJCQkJbkNvbDIgPSBHRVRfRVJST1IoKS0+bkNvbDI7CiAgICAJCQkJCQl9CiAgICAJCQkJCQllbHNlCiAgICAJCQkJCQl7CiAgICAJCQkJCQkJbkVyckxuID0gYVJ1bi5HZXRMaW5lKCk7CiAgICAJCQkJCQkJbkNvbDEgPSBhUnVuLkdldENvbDEoKTsKICAgIAkJCQkJCQluQ29sMiA9IGFSdW4uR2V0Q29sMigpOwogICAgCQkJCQkJfQoKICAgIAkJCQkJCWlmICggIWJXYXNOZXdFcnJvciApCiAgICAJCQkJCQl7CiAgICAJCQkJCQkJYldhc05ld0Vycm9yID0gc2FsX1RydWU7CiAgICAJCQkJCQkJQUREX0VSUk9SX0xPRyggR0VUX0VSUk9SKCktPmFUZXh0LCBhUnVuLkdldE1vZHVsZU5hbWUoU2J4TkFNRV9TSE9SVF9UWVBFUyksCiAgICAJCQkJCQkJCW5FcnJMbiwgbkNvbDEsIG5Db2wyLCBhUnVuLkdldFNvdXJjZVJldmlzaW9uKCkgKTsKICAgIAkJCQkJCX0KICAgIAkJCQkJCUFERF9DQUxMX1NUQUNLX0xPRyggU3RyaW5nKGFSdW4uR2V0TW9kdWxlTmFtZShTYnhOQU1FX1NIT1JUX1RZUEVTKSkKICAgIAkJCQkJCQkuQXBwZW5kQXNjaWkoIjogIikuQXBwZW5kKGFSdW4uR2V0TWV0aG9kTmFtZShTYnhOQU1FX1NIT1JUX1RZUEVTKSksCiAgICAJCQkJCQkJYVJ1bi5HZXRNb2R1bGVOYW1lKFNieE5BTUVfU0hPUlRfVFlQRVMpLAogICAgCQkJCQkJCW5FcnJMbiwgbkNvbDEsIG5Db2wyICk7CiAgICAJCQkJCQlhUnVuID0gYVJ1bi5HZXROZXh0UnVudGltZSgpOwogICAgCQkJCQl9CiAgICAJCQkJfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9FcnJvckxvZzoKICAgIAkJCQlpZiAoIElTX0VSUk9SKCkgKQogICAgCQkJCXsKICAgIAkJCQkJQmFzaWNSdW50aW1lIGFSdW4gPSBCYXNpY1J1bnRpbWVBY2Nlc3M6OkdldFJ1bnRpbWUoKTsKICAgIAkJCQkJaWYgKCBCYXNpY1J1bnRpbWVBY2Nlc3M6Okhhc1N0YWNrKCkgKQogICAgCQkJCQl7CiAgICAJCQkJCQlCYXNpY0Vycm9yU3RhY2tFbnRyeSBhVGhpc0VudHJ5ID0gQmFzaWNSdW50aW1lQWNjZXNzOjpHZXRTdGFja0VudHJ5KCAwICk7CiAgICAJCQkJCQlBRERfRVJST1JfTE9HKCBHRVRfRVJST1IoKS0+YVRleHQsIGFUaGlzRW50cnkuR2V0TW9kdWxlTmFtZShTYnhOQU1FX1NIT1JUX1RZUEVTKSwKICAgIAkJCQkJCQlhVGhpc0VudHJ5LkdldExpbmUoKSwgYVRoaXNFbnRyeS5HZXRDb2wxKCksIGFUaGlzRW50cnkuR2V0Q29sMigpLCBhVGhpc0VudHJ5LkdldFNvdXJjZVJldmlzaW9uKCkgKTsKICAgIAkJCQkJCUJhc2ljUnVudGltZUFjY2Vzczo6RGVsZXRlU3RhY2soKTsKICAgIAkJCQkJfQogICAgCQkJCQllbHNlCiAgICAJCQkJCXsKICAgIAkJCQkJCUFERF9FUlJPUl9MT0coIEdFVF9FUlJPUigpLT5hVGV4dCwgYVJ1bi5HZXRNb2R1bGVOYW1lKFNieE5BTUVfU0hPUlRfVFlQRVMpLAogICAgCQkJCQkJCVN0YXJCQVNJQzo6R2V0RXJsKCksIGFSdW4uR2V0Q29sMSgpLCBhUnVuLkdldENvbDIoKSwgYVJ1bi5HZXRTb3VyY2VSZXZpc2lvbigpICk7CiAgICAJCQkJCX0KICAgIAkJCQl9CiAgICAJCQkJYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIElEX1FBRXJyb3JMb2c6CiAgICAJCQkJaWYgKCByUGFyICkgIC8vIHJQYXIgIT0gTlVMTCAgPD0+ICBFcyBnaWJ0IFBhcmFtZXRlcgogICAgCQkJCXsKICAgIAkJCQkJc2FsX3VJbnQxNiBuOwogICAgCQkJCQlTdHJpbmcgYVNhbW1lbDsKICAgIAkJCQkJZm9yICggbiA9IDE7IG4gPCByUGFyLT5Db3VudCgpOyBuKysgKQogICAgCQkJCQl7CiAgICAJCQkJCQlTYnhWYXJpYWJsZVJlZiBwQXJnID0gclBhci0+R2V0KCBuICk7CiAgICAJCQkJCQlhU2FtbWVsICs9IHBBcmctPkdldFN0cmluZygpOwogICAgCQkJCQl9CiAgICAJCQkJCUFERF9RQV9FUlJPUl9MT0coIGFTYW1tZWwgKTsKICAgIAkJCQl9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX1ByaW50TG9nOgogICAgCQkJCWlmICggclBhciApICAvLyByUGFyICE9IE5VTEwgIDw9PiAgRXMgZ2lidCBQYXJhbWV0ZXIKICAgIAkJCQl7CiAgICAJCQkJCXNhbF91SW50MTYgbjsKICAgIAkJCQkJU3RyaW5nIGFTYW1tZWw7CiAgICAJCQkJCWZvciAoIG4gPSAxOyBuIDwgclBhci0+Q291bnQoKTsgbisrICkKICAgIAkJCQkJewogICAgCQkJCQkJU2J4VmFyaWFibGVSZWYgcEFyZyA9IHJQYXItPkdldCggbiApOwogICAgCQkJCQkJYVNhbW1lbCArPSBwQXJnLT5HZXRTdHJpbmcoKTsKICAgIAkJCQkJfQogICAgCQkJCQlBRERfTUVTU0FHRV9MT0coIGFTYW1tZWwgKTsKICAgIAkJCQl9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX1dhcm5Mb2c6CiAgICAJCQkJaWYgKCByUGFyICkgIC8vIHJQYXIgIT0gTlVMTCAgPD0+ICBFcyBnaWJ0IFBhcmFtZXRlcgogICAgCQkJCXsKICAgIAkJCQkJc2FsX3VJbnQxNiBuOwogICAgCQkJCQlTdHJpbmcgYVNhbW1lbDsKICAgIAkJCQkJZm9yICggbiA9IDE7IG4gPCByUGFyLT5Db3VudCgpOyBuKysgKQogICAgCQkJCQl7CiAgICAJCQkJCQlTYnhWYXJpYWJsZVJlZiBwQXJnID0gclBhci0+R2V0KCBuICk7CiAgICAJCQkJCQlhU2FtbWVsICs9IHBBcmctPkdldFN0cmluZygpOwogICAgCQkJCQl9CiAgICAJCQkJCUFERF9XQVJOSU5HX0xPRyggYVNhbW1lbCApOwoKICAgIAkJCQl9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0NsZWFyRXJyb3I6CiAgICAJCQkJd2hpbGUgKCBJU19FUlJPUigpICkKICAgIAkJCQl7CiAgICAJCQkJCVBPUF9FUlJPUigpOwogICAgCQkJCX0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfTWF5YmVBZGRFcnI6CiAgICAJCQkJaWYgKCAoKFN0YXJCQVNJQyopR2V0UGFyZW50KCkpLT5HZXRFcnJCYXNpYygpICYmICggIUlTX0VSUk9SKCkgfHwKICAgIAkJCQkJIHBGZWhsZXJMaXN0ZS0+R2V0T2JqZWN0KHBGZWhsZXJMaXN0ZS0+Q291bnQoKS0xKS0+bkVycm9yICE9ICgoU3RhckJBU0lDKilHZXRQYXJlbnQoKSktPkdldEVyckJhc2ljKCkgKSApCiAgICAJCQkJewogICAgCQkJCQkoKFN0YXJCQVNJQyopR2V0UGFyZW50KCkpLT5NYWtlRXJyb3JUZXh0KCgoU3RhckJBU0lDKilHZXRQYXJlbnQoKSktPkdldEVyckJhc2ljKCksU3RyaW5nKCkpOwogICAgCQkJCQlBRERfRVJST1JfUVVJRVQoKChTdGFyQkFTSUMqKUdldFBhcmVudCgpKS0+R2V0RXJyQmFzaWMoKSAsICgoU3RhckJBU0lDKilHZXRQYXJlbnQoKSktPkdldEVycm9yVGV4dCgpKQogICAgCQkJCX0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfR2V0TmV4dENsb3NlV2luZG93OgogICAgCQkJCWlmICggIXJQYXIgKSAgLy8gclBhciA9IE5VTEwgIDw9PiAgS2VpbiBQYXJhbWV0ZXIKICAgIAkJCQl7CiAgICAJCQkJCVNldEVycm9yKCBTYnhFUlJfTk9USU1QICk7CiAgICAJCQkJCWJyZWFrOwoKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGFzIGlzdCB0b3RhbCByb3R0ZW4gdW5kIG1177+9IHdvaGwga29tcGxldHQgbmV1ISEKCgovKiAgICAJCQkJCXNhbF9Cb29sIGJXYXNCbG9jayA9IElzQmxvY2s7CiAgICAJCQkJCWlmICggIUlzQmxvY2sgKSAgICAgICAgICAgICAgICAgLy8gSW1wbGl6aXRlciBjYWxsIGJlaSBBdWZydWYgbWl0IE1ldGhvZGUKICAgIAkJCQkJCWlmICggU2luZ2xlQ29tbWFuZEJsb2NrICkKICAgIAkJCQkJCQlCZWdpbkJsb2NrKCk7Ci8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIUlzRXJyb3IoKSApCi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW4tPkdlbkNtZFNsb3QgKDEyOCxyUGFyKTsKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChDb250cm9scyopcFZhciktPnBNZXRob2RWYXItPm5WYWx1ZSA9IDEyODsKCiAgICAJCQkJCXNhbF91TG9uZyBuT2xkVmFsdWUgPSAoKENvbnRyb2xzKilwVmFyKS0+R2V0VUxvbmcoKTsKICAgIAkJCQkJLy8gU2V0emVuLCBzbyBkYe+/vSBiZWltIFJldHVybiBkZXIgV2VydCBzdGltbXQKICAgIAkJCQkJKChDb250cm9scyopcFZhciktPlB1dFVMb25nKCAxMjggKTsKICAgIAkJCQkJcEltcGwtPnBOZXh0UmV0dXJuID0gKChDb250cm9scyopcFZhciktPnBNZXRob2RWYXI7CiAgICAJCQkJCWlmICggU2luZ2xlQ29tbWFuZEJsb2NrICkKICAgIAkJCQkJCUVuZEJsb2NrKCk7CiAgICAJCQkJCVdhaXRGb3JBbnN3ZXIoKTsKICAgIAkJCQkJaWYgKCBiV2FzQmxvY2sgKQogICAgCQkJCQkJaWYgKCBTaW5nbGVDb21tYW5kQmxvY2sgKQogICAgCQkJCQkJCUJlZ2luQmxvY2soKTsKICAgIAkJCQkJKChDb250cm9scyopcFZhciktPlB1dFVMb25nKCBuT2xkVmFsdWUgKTsKCiAgICAJCQkJCS8vIFLvv71ja3NldHplbiwgc28gZGHvv70gYmVpbSBu77+9Y2hzdGVuIEF1ZnJ1ZiBhbGxlcyBrbGFwcHQKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChDb250cm9scyopcFZhciktPlNldFVzZXJEYXRhKCAxMjggKTsKCgovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKENvbnRyb2xzKilwVmFyKS0+U2V0TmFtZSgieHh4Iik7CgkJCQkJCS8vIFNldHplbiB1bmQgcu+/vWNrc2V0emVuIGRlciBJRCwgc28gZGFzcyBkZXIgTm90aWZ5IG9obmUgV2lya3VuZyBibGVpYnQuCgkJCQkJCSgoQ29udHJvbHMqKXBWYXIpLT5wTWV0aG9kVmFyLT5TZXRVc2VyRGF0YShJRF9FcnJvckR1bW15KTsKCQkJCQkJKChDb250cm9scyopcFZhciktPlB1dFVMb25nKCAoKENvbnRyb2xzKilwVmFyKS0+cE1ldGhvZFZhci0+R2V0VUxvbmcoKSApOwoJCQkJCQkoKENvbnRyb2xzKilwVmFyKS0+cE1ldGhvZFZhci0+U2V0VXNlckRhdGEoSURfQ29udHJvbCk7CgoJCQkJCQlwU2hvcnROYW1lcy0+SW5zZXJ0KCBDVW5pU3RyaW5nKCJ4eHgiKSwgcnRsOjpPU3RyaW5nKCAoKENvbnRyb2xzKilwVmFyKS0+cE1ldGhvZFZhci0+blZhbHVlICksIG5TZXF1ZW5jZSApOwoKCQkJCQkJbk9sZFZhbHVlID0gKChDb250cm9scyopcFZhciktPkdldFVMb25nKCk7CgoJCQkJCQlTYnhWYXJpYWJsZSAqcE1lbWJlcjsKCQkJCQkJaWYgKCAhIChwTWVtYmVyID0gKChDb250cm9scyopcFZhciktPkZpbmQoQ1VuaVN0cmluZygiSUQiKSxTYnhDTEFTU19ET05UQ0FSRSkpICkKCQkJCQkJewoJCQkJCQkJcE1lbWJlciA9IG5ldyBTYnhQcm9wZXJ0eShDVW5pU3RyaW5nKCJJRCIpLFNieFZBUklBTlQpOwoJCQkJCQkJKChDb250cm9scyopcFZhciktPkluc2VydChwTWVtYmVyKTsKCQkJCQkJfQoJCQkJCQlwTWVtYmVyLT5QdXRVTG9uZygoKENvbnRyb2xzKilwVmFyKS0+cE1ldGhvZFZhci0+blZhbHVlKTsKCgkJCQkJCWlmICggISAocE1lbWJlciA9ICgoQ29udHJvbHMqKXBWYXIpLT5GaW5kKENVbmlTdHJpbmcoIm5hbWUiKSxTYnhDTEFTU19ET05UQ0FSRSkpICkKCQkJCQkJewoJCQkJCQkJcE1lbWJlciA9IE5VTEw7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQkJcE1lbWJlci0+UHV0U3RyaW5nKENVbmlTdHJpbmcoInh4eCIpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCgkJCQkJfQoJCQkJCWVsc2UKCQkJCQkJU2V0RXJyb3IoIFNieEVSUl9XUk9OR19BUkdTICk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIElEX1JlbW90ZUNvbW1hbmQ6CgkJCQkJewoJCQkJCQlpZiAoIFNpbmdsZUNvbW1hbmRCbG9jayApCgkJCQkJCQlCZWdpbkJsb2NrKCk7CgkJCQkJCWVsc2UKCQkJCQkJCWlmICggKChTYnhUcmFuc3BvcnRNZXRob2QqKXBWYXIpLT5uVmFsdWUgJiBNX1dJVEhfUkVUVVJOICkKCQkJCQkJCXsKCQkJCQkJCQlTZXRFcnJvciggU2J4RVJSX05PVElNUCApOwoJCQkJCQkJfQoJCQkJCQlpZiAoICFJc0Vycm9yKCkgKQoJCQkJCQkJSW4tPkdlbkNtZENvbW1hbmQgKChzYWxfdUludDE2KSgoKFNieFRyYW5zcG9ydE1ldGhvZCopcFZhciktPm5WYWx1ZSksclBhcik7CgkJCQkJCWlmICggIUlzRXJyb3IoKSAmJiAoKFNieFRyYW5zcG9ydE1ldGhvZCopcFZhciktPm5WYWx1ZSAmIE1fV0lUSF9SRVRVUk4gKQoJCQkJCQl7CgkJCQkJCQlwSW1wbC0+cE5leHRSZXR1cm4gPSAoKFNieFRyYW5zcG9ydE1ldGhvZCopcFZhcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRklYTUU6IEhFTFBJRAoJCQkJCQkJYU5leHRSZXR1cm5JZCA9IHJ0bDo6T1N0cmluZygpOy8vICgoU2J4VHJhbnNwb3J0TWV0aG9kKilwVmFyKS0+blZhbHVlICk7CgkJCQkJCX0KCQkJCQkJaWYgKCBTaW5nbGVDb21tYW5kQmxvY2sgKQoJCQkJCQkJRW5kQmxvY2soKTsKCQkJCQkJaWYgKCAhSXNFcnJvcigpICYmIChzYWxfdUludDE2KSgoU2J4VHJhbnNwb3J0TWV0aG9kKilwVmFyKS0+blZhbHVlICYgTV9XSVRIX1JFVFVSTiApCgkJCQkJCXsKCQkJCQkJCVdhaXRGb3JBbnN3ZXIoKTsKCQkJCQkJfQoJCQkJCQkvLyBm77+9ciBlaW5pZ2Ugbm9jaCBldHdhcyBOYWNoYmVoYW5kbHVuZwoJCQkJCQlzd2l0Y2ggKCAoKFNieFRyYW5zcG9ydE1ldGhvZCopcFZhciktPm5WYWx1ZSApCgkJCQkJCXsKCQkJCQkJCWNhc2UgUkNfV2luVHJlZToKLy8JCQkJCQkJCTo6c3Z0OjpPU3RyaW5nVHJhbnNmZXI6OkNvcHlTdHJpbmcocFZhci0+R2V0U3RyaW5nKCksIHBTb21lV2luZG93SURvbnRIYXZlICk7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSBJRF9EaXNwYXRjaDoKCQkJCQlpZiAoICFyUGFyIHx8IChyUGFyLT5Db3VudCgpICUgMikgPT0gMSApICAvLyByUGFyID0gTlVMTCAgPD0+ICBLZWluIFBhcmFtZXRlciBhbnNvbnN0ZW4gR2VyYWRlIEFuemFobChVbmdlcmFkZSwgZGEgaW1tZXIgQW56YWhsKzEKCQkJCQl7CgkJCQkJCWlmICggU2luZ2xlQ29tbWFuZEJsb2NrICkKCQkJCQkJCUJlZ2luQmxvY2soKTsKCQkJCQkJaWYgKCAhSXNFcnJvcigpICkKCQkJCQkJCUluLT5HZW5DbWRTbG90ICggKHNhbF91SW50MTYpKChTYnhUcmFuc3BvcnRNZXRob2QqKXBWYXIpLT5uVmFsdWUsIHJQYXIgKTsKCQkJCQkJcFZhci0+UHV0SW50ZWdlciggKHNhbF91SW50MTYpKChTYnhUcmFuc3BvcnRNZXRob2QqKXBWYXIpLT5uVmFsdWUgKTsKCQkJCQkJaWYgKCBTaW5nbGVDb21tYW5kQmxvY2sgKQoJCQkJCQkJRW5kQmxvY2soKTsKCQkJCQl9CgkJCQkJZWxzZQoJCQkJCQlTZXRFcnJvciggU2J4RVJSX1dST05HX0FSR1MgKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgSURfVU5PRGlzcGF0Y2g6CgkJCQkJaWYgKCAhclBhciApICAvLyByUGFyID0gTlVMTCAgPD0+ICBLZWluIFBhcmFtZXRlciBhbnNvbnN0ZW4gR2VyYWRlIEFuemFobChVbmdlcmFkZSwgZGEgaW1tZXIgQW56YWhsKzEKCQkJCQl7CgkJCQkJCWlmICggU2luZ2xlQ29tbWFuZEJsb2NrICkKCQkJCQkJCUJlZ2luQmxvY2soKTsKCQkJCQkJaWYgKCAhSXNFcnJvcigpICkKCQkJCQkJCUluLT5HZW5DbWRVTk9TbG90ICggKChTYnhUcmFuc3BvcnRNZXRob2QqKXBWYXIpLT5hVW5vU2xvdCApOwoJCQkJCQlwVmFyLT5QdXRTdHJpbmcoICgoU2J4VHJhbnNwb3J0TWV0aG9kKilwVmFyKS0+YVVub1Nsb3QgKTsKCQkJCQkJaWYgKCBTaW5nbGVDb21tYW5kQmxvY2sgKQoJCQkJCQkJRW5kQmxvY2soKTsKCQkJCQl9CgkJCQkJZWxzZQoJCQkJCQlTZXRFcnJvciggU2J4RVJSX1dST05HX0FSR1MgKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgSURfQ29udHJvbDoKCQkJCWNhc2UgSURfU3RyaW5nQ29udHJvbDoKICAgICAgICAgICAgICAgICAgICAvLyBpZiBvbmx5IHRoZSBvYmplY3QgaXMgZ2l2ZW4gaW4gdGhlIHNjcmlwdCB3ZSBkb24ndCBoYXZlIHRvIGRvIGFueXRoaW5nIChvYmplY3Qgc3RhbmRzIGZvciBpdHNlbGYpCiAgICAgICAgICAgICAgICAgICAgaWYgKCAhcFZhci0+SVNBKCBTYnhPYmplY3QgKSApCiAgICAgICAgICAgICAgICAgICAgewoJCQkJCSAgICBpZiAoIFNpbmdsZUNvbW1hbmRCbG9jayApCgkJCQkJCSAgICBCZWdpbkJsb2NrKCk7CgkJCQkJICAgIGVsc2UKCQkJCQkJICAgIGlmICggKChTYnhUcmFuc3BvcnRNZXRob2QqKXBWYXIpLT5uVmFsdWUgJiBNX1dJVEhfUkVUVVJOICkKCQkJCQkJICAgIHsKCQkJCQkJCSAgICBTZXRFcnJvciggU2J4RVJSX05PVElNUCApOwoJCQkJCQkgICAgfQoJCQkJCSAgICBpZiAoICFJc0Vycm9yKCkgKQoJCQkJCSAgICB7CiAgICAJCSAgICAgICAgICAgICAgICBTYnhWYXJpYWJsZSAqcE1lbWJlciA9IE5VTEw7CiAgICAJCSAgICAgICAgICAgICAgICBpZiAoIHBWYXItPkdldFBhcmVudCgpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWVtYmVyID0gcFZhci0+R2V0UGFyZW50KCktPkZpbmQoQ1VuaVN0cmluZygiSUQiKSxTYnhDTEFTU19ET05UQ0FSRSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHBNZW1iZXIgPT0gTlVMTCApCiAgICAJCSAgICAgICAgICAgICAgICB7CiAgICAJCQkgICAgICAgICAgICAgICAgU2V0RXJyb3IoIFNieEVSUl9OQU1FRF9OT1RfRk9VTkQgKTsKICAgIAkJICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIG5IaW50VXNlckRhdGEgPT0gSURfQ29udHJvbCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewoJCQkJCQkgICAgICAgICAgICBJbi0+R2VuQ21kQ29udHJvbCAocE1lbWJlci0+R2V0VUxvbmcoKSwKCQkJCQkJCSAgICAgICAgICAgIChzYWxfdUludDE2KSgoU2J4VHJhbnNwb3J0TWV0aG9kKilwVmFyKS0+blZhbHVlLCByUGFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBIRUxQSUQKCQkJCQkJCSAgICAgICAgYU5leHRSZXR1cm5JZCA9IHJ0bDo6T1N0cmluZygpOy8vIHBNZW1iZXItPkdldFVMb25nKCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKCQkJCQkJICAgICAgICAgICAgSW4tPkdlbkNtZENvbnRyb2wgKHBNZW1iZXItPkdldFN0cmluZygpLAoJCQkJCQkJICAgICAgICAgICAgKHNhbF91SW50MTYpKChTYnhUcmFuc3BvcnRNZXRob2QqKXBWYXIpLT5uVmFsdWUsIHJQYXIpOwoJCQkJCQkJICAgICAgICAvLyBGSVhNRTogSEVMUElECgkJCQkJCQkgICAgICAgICNpZiAwCgkJCQkJCQkgICAgICAgIGFOZXh0UmV0dXJuSWQgPSBydGw6Ok9TdHJpbmcoIHBNZW1iZXItPkdldFN0cmluZygpICk7CgkJCQkJCQkgICAgICAgICNlbmRpZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCgkJCQkJCSAgICBpZiAoICFJc0Vycm9yKCkgJiYgKChTYnhUcmFuc3BvcnRNZXRob2QqKXBWYXIpLT5uVmFsdWUgJiBNX1dJVEhfUkVUVVJOICkKCQkJCQkJICAgIHsKCQkJCQkJCSAgICBwSW1wbC0+cE5leHRSZXR1cm4gPSAoKFNieFRyYW5zcG9ydE1ldGhvZCopcFZhcik7CgkJCQkJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEltcGwtPnBOZXh0UmV0dXJuID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhTmV4dFJldHVybklkID0gcnRsOjpPU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgoJCQkJCSAgICB9CgkJCQkJICAgIGlmICggU2luZ2xlQ29tbWFuZEJsb2NrICkKCQkJCQkJICAgIEVuZEJsb2NrKCk7CgkJCQkJICAgIGlmICggIUlzRXJyb3IoKSAmJiAoc2FsX3VJbnQxNikoKFNieFRyYW5zcG9ydE1ldGhvZCopcFZhciktPm5WYWx1ZSAmIE1fV0lUSF9SRVRVUk4gKQoJCQkJCSAgICB7CgkJCQkJCSAgICBXYWl0Rm9yQW5zd2VyKCk7CgkJCQkJICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgoJCQkJCWJyZWFrOwoJCQkJY2FzZSBJRF9HZXRVbm9BcHA6CgkJCQkJewoJCQkJCQkvLyBIaWVyIHdpcmQgZGVyIFJlbW90ZSBVTk8gS3JhbSBnZXN0YXJ0ZXQKCQkJCQkJLy8gRWludHJhZyBpbiBkaWUgS29uZmlndXJhdGlvbiB1bnRlcgoJCQkJCQkvLyBvcmcub3Blbm9mZmljZS5PZmZpY2UuQ29tbW9uL1N0YXJ0L0Nvbm5lY3Rpb24KCQkJCQkJLy8Jc29ja2V0LGhvc3Q9MCxwb3J0PTEyMzQ1O2lpb3A7WEJsYQoJCQkJCQkvLyBvZGVyCgkJCQkJCS8vCXNvY2tldCxob3N0PTAscG9ydD0xMjM0NTt1cnA7O1hCbGEKCgkJCQkJCVN0cmluZyBhU3RyaW5nOwoJCQkJCQlhU3RyaW5nLkFwcGVuZEFzY2lpKCAic29ja2V0LGhvc3Q9IiApOwoJCQkJCQlhU3RyaW5nICs9IEdldEhvc3RDb25maWcoKTsKCQkJCQkJYVN0cmluZy5BcHBlbmRBc2NpaSggIixwb3J0PSIgKTsKCQkJCQkJYVN0cmluZyArPSBTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMiggR2V0VW5vUG9ydENvbmZpZygpICk7CgogICAJCQkJCSAgICBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4gc21ncl94TXVsdGlzZXJ2aWNlRmFjdG9yeTsKCQkJCQkJdHJ5CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiB4U01nciA9IGNvbXBoZWxwZXI6OmdldFByb2Nlc3NTZXJ2aWNlRmFjdG9yeSgpOwovLyBpcyBhbGx3YXlzIHRoZXJlCi8qCQkJCQkJICAgIGlmICggISB4U01nci5pcygpICkKCQkJCQkJICAgIHsKCQkJCQkJCSAgICB4U01nciA9IDo6Y3BwdTo6Y3JlYXRlUmVnaXN0cnlTZXJ2aWNlRmFjdG9yeShPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oImFwcGxpY2F0LnJkYiIpKSwgc2FsX1RydWUgKTsKICAgIAkJCQkJCSAgICBpZiAoIHhTTWdyLmlzKCkgKQogICAgCQkJCQkJCSAgICBjb21waGVscGVyOjpzZXRQcm9jZXNzU2VydmljZUZhY3RvcnkoIHhTTWdyICk7CiAgICAJCQkJCSAgICB9Ki8KCiAgICAJCQkJCSAgICBPVVN0cmluZyBhVVJMKCBhU3RyaW5nICk7CiAgICAJCQkJCSAgICBSZWZlcmVuY2U8IFhDb25uZWN0b3IgPiB4Q29ubmVjdG9yKCB4U01nci0+Y3JlYXRlSW5zdGFuY2UoCiAgICAJCQkJCQkgICAgT1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiY29tLnN1bi5zdGFyLmNvbm5lY3Rpb24uQ29ubmVjdG9yIikgKSApLCBVTk9fUVVFUlkgKTsKICAgIAkJCQkJICAgIFJlZmVyZW5jZTwgWENvbm5lY3Rpb24gPiB4Q29ubmVjdGlvbiggeENvbm5lY3Rvci0+Y29ubmVjdCggYVVSTCApICk7CgogICAgCQkJCQkgICAgUmVmZXJlbmNlPCBYQnJpZGdlRmFjdG9yeSA+IHhCcmlkZ2VGYWN0b3J5KCB4U01nci0+Y3JlYXRlSW5zdGFuY2UoCiAgICAJCQkJCQkgICAgT1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiY29tLnN1bi5zdGFyLmJyaWRnZS5CcmlkZ2VGYWN0b3J5IikgKSApLCBVTk9fUVVFUlkgKTsKICAgIAkJCQkJICAgIFJlZmVyZW5jZTwgWEJyaWRnZSA+IHhCcmlkZ2UoIHhCcmlkZ2VGYWN0b3J5LT5jcmVhdGVCcmlkZ2UoCiAgICAJCQkJCQkgICAgT1VTdHJpbmcoKSwgT1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgidXJwIikgKSwKICAgIAkJCQkJCSAgICB4Q29ubmVjdGlvbiwgUmVmZXJlbmNlPCBYSW5zdGFuY2VQcm92aWRlciA+KCkgKSApOwoKICAgIC8vCQkJCQkJUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4geFJldCggeEJyaWRnZS0+Z2V0SW5zdGFuY2UoIE9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oImNvbS5zdW4uc3Rhci5mcmFtZS5EZXNrdG9wIikpICkgKTsKICAgIAkJCQkJICAgIFJlZmVyZW5jZTwgWEludGVyZmFjZSA+IHhSZXQoIHhCcmlkZ2UtPmdldEluc3RhbmNlKCBPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJTdGFyT2ZmaWNlLlNlcnZpY2VNYW5hZ2VyIikpICkgKTsKCiAgICAvLwkJCQkJCVJlZmVyZW5jZTwgWE5hbWluZ1NlcnZpY2UgPiB4TmFtaW5nU2VydmljZSh4UmV0LCBVTk9fUVVFUlkpOwoKICAgIC8vCQkJICAgICAgICAgICAgUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4gc21nciA9IHhOYW1pbmdTZXJ2aWNlLT5nZXRSZWdpc3RlcmVkT2JqZWN0KCBPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJTdGFyT2ZmaWNlLlNlcnZpY2VNYW5hZ2VyIiApICkgKTsKCiAgICAJCQkJCSAgICBzbWdyX3hNdWx0aXNlcnZpY2VGYWN0b3J5ID0gUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+KHhSZXQsIFVOT19RVUVSWSk7CiAgICAvL01CQSBmcmFnZW4hIQogICAgICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIGNhdGNoKCBjbGFzcyBFeGNlcHRpb24gJiByRXgpCgkgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgCUFERF9FUlJPUihTYnhFUlJfQkFEX0FDVElPTiwgU3RyaW5nKCByRXguTWVzc2FnZSApICk7CgkgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAJY2F0Y2goIC4uLiApCgkgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgCUFERF9FUlJPUihTYnhFUlJfQkFEX0FDVElPTiwgQ1VuaVN0cmluZyggIlVua25vd24gRXJyb3IiICkgKTsKCSAgICAgICAgICAgICAgICAgICAgfQoKICAgIAkJCQkJaWYoIHNtZ3JfeE11bHRpc2VydmljZUZhY3RvcnkuaXMoKSApCiAgICAJCQkJCXsKICAgIAkJCQkJCUFueSBhQW55OwovLwkJCQkJCQlhQW55IDw8PSB4QnJpZGdlOwogICAgCQkJCQkJYUFueSA8PD0gc21ncl94TXVsdGlzZXJ2aWNlRmFjdG9yeTsKCiAgICAJCQkJCQlTYnhPYmplY3RSZWYgeE15U2J4T2JqID0gR2V0U2JVbm9PYmplY3QoIENVbmlTdHJpbmcoIlJlbW90ZVVub0FwcEZ1ZXJUZXN0dG9vbCIpLCBhQW55ICk7CiAgICAJCQkJCQlpZiAoIHhNeVNieE9iai5JcygpICkKICAgIAkJCQkJCQlwVmFyLT5QdXRPYmplY3QoIHhNeVNieE9iaiApOwogICAgCQkJCQl9CiAgICAJCQkJfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9HZXRJU2VydmVyOgogICAgCQkJCXsKICAgIAkJCQkJLy8gSGllciB3aXJkIGRlciBSZW1vdGUgVU5PIEtyYW0gZ2VzdGFydGV0CgogICAgCQkJCQlTdHJpbmcgYVN0cmluZzsKLy8JCQkJCQlhU3RyaW5nICs9IEdldEhvc3RDb25maWcoKTsKLy8JCQkJCQlhU3RyaW5nLkFwcGVuZEFzY2lpKCAiOiIgKTsKLy8JCQkJCQlhU3RyaW5nICs9IFN0cmluZzo6Q3JlYXRlRnJvbUludDMyKCBHZXRVbm9Qb3J0Q29uZmlnKCkgKTsKCiAgICAJCQkJCVJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiB4U01nciAvKiA9IGNvbXBoZWxwZXI6OmdldFByb2Nlc3NTZXJ2aWNlRmFjdG9yeSgpKi87Ci8vCQkJCQkJaWYgKCAhIHhTTWdyLmlzKCkgKQogICAgCQkJCQl7CiAgICAJCQkJCQl4U01nciA9IDo6Y3BwdTo6Y3JlYXRlUmVnaXN0cnlTZXJ2aWNlRmFjdG9yeShPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oImc6XFxpc2VydmVycHJveHkucmRiIikpLCBzYWxfVHJ1ZSk7Ci8vCQkJCQkJCWNvbXBoZWxwZXI6OnNldFByb2Nlc3NTZXJ2aWNlRmFjdG9yeSggeFNNZ3IgKTsKICAgIAkJCQkJfQoKICAgIAkJCQkJT1VTdHJpbmcgYVVSTCggYVN0cmluZyApOwogICAgCQkJCQlSZWZlcmVuY2U8IFhDb25uZWN0b3IgPiB4Q29ubmVjdG9yKCB4U01nci0+Y3JlYXRlSW5zdGFuY2UoCiAgICAJCQkJCQlPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJjb20uc3VuLnN0YXIuY29ubmVjdGlvbi5Db25uZWN0b3IiKSApICksIFVOT19RVUVSWSApOwogICAgCQkJCQlSZWZlcmVuY2U8IFhDb25uZWN0aW9uID4geENvbm5lY3Rpb24oIHhDb25uZWN0b3ItPmNvbm5lY3QoIE9VU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oInNvY2tldCxob3N0PWdyYW5kZSxwb3J0PTc0NTMiKSkgKSApOwoKICAgIAkJCQkJUmVmZXJlbmNlPCBYQnJpZGdlRmFjdG9yeSA+IHhCcmlkZ2VGYWN0b3J5KCB4U01nci0+Y3JlYXRlSW5zdGFuY2UoCiAgICAJCQkJCQlPVVN0cmluZyggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJjb20uc3VuLnN0YXIuYnJpZGdlLkJyaWRnZUZhY3RvcnkiKSApICksIFVOT19RVUVSWSApOwogICAgCQkJCQlSZWZlcmVuY2U8IFhCcmlkZ2UgPiB4QnJpZGdlKCB4QnJpZGdlRmFjdG9yeS0+Y3JlYXRlQnJpZGdlKAogICAgCQkJCQkJT1VTdHJpbmcoKSwgT1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgidXJwIikgKSwKICAgIAkJCQkJCXhDb25uZWN0aW9uLCBSZWZlcmVuY2U8IFhJbnN0YW5jZVByb3ZpZGVyID4oKSApICk7CgogICAgCQkJCQlSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiB4UmV0KCB4QnJpZGdlLT5nZXRJbnN0YW5jZSggT1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiWElTZXJ2ZXJQcm94eSIpKSApICk7CgoKLyogICAgCQkJCQlSZWZlcmVuY2U8IFhJU2VydmVyUHJveHkgPiB4SVMoIHhSZXQsIFVOT19RVUVSWSApOwoJCQkJCQlpZiAoIHhJUy5pcygpICkKCQkJCQkJewoJCQkJCQkJU3RyaW5nIGFIb3N0KCB4SVMtPmdldElTZXJ2ZXJIb3N0KCkgKTsKCi8vCQkJCQkJCVJlZmVyZW5jZSA8IFhJbmZvcm1hdGlvbkNsaWVudCA+IHhJQyA9IHhJUy0+Y3JlYXRlSVNlcnZlckNsaWVudCggIlhJbmZvcm1hdGlvbkNsaWVudCIgKTsKCQkJCQkJCVJlZmVyZW5jZSA8IFhJbmZvcm1hdGlvbkNsaWVudCA+IHhJQyA9IHhJUy0+Y3JlYXRlSW5mb3JtYXRpb25DbGllbnQoKTsKCQkJCQkJCXhJQy0+Z2V0VHJlZShPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJyOlxcYl9zZXJ2ZXJcXGNvbmZpZ1xcc3RhbmQubHN0IiksIE9VU3RyaW5nKCkgKTsKCgoJICAgIAkJCQkJUmVmZXJlbmNlPCBYVHlwZVByb3ZpZGVyID4geFRQKCB4UmV0LCBVTk9fUVVFUlkgKTsKCQkJCQkJCVNlcXVlbmNlIDwgY29tOjpzdW46OnN0YXI6OnVubzo6VHlwZSA+IHMgPSB4VFAtPmdldFR5cGVzKCk7CgkJCQkJCX0KICAqLwoKCQkJCQkJaWYoIHhSZXQuaXMoKSApCiAgICAJCQkJCXsKICAgIAkJCQkJCUFueSBhQW55OwogICAgCQkJCQkJYUFueSA8PD0geFJldDsKCiAgICAJCQkJCQlTYnhPYmplY3RSZWYgeE15U2J4T2JqID0gR2V0U2JVbm9PYmplY3QoIENVbmlTdHJpbmcoIklTZXJ2ZXJQcm94eSIpLCBhQW55ICk7CiAgICAJCQkJCQlpZiAoIHhNeVNieE9iai5JcygpICkKICAgIAkJCQkJCQlwVmFyLT5QdXRPYmplY3QoIHhNeVNieE9iaiApOwogICAgCQkJCQl9CiAgICAJCQkJCS8vIEluIEJhc2ljOgogICAgCQkJCQkvLyBtc2dib3ggZGJnX1N1cHBvcnRlZEludGVyZmFjZXMKICAgIAkJCQkJLy8gbXNnYm94IGRiZ19Qcm9wZXJ0aWVzCiAgICAJCQkJCS8vIG1zZ2JveCBkYmdfTWV0aG9kcwogICAgCQkJCX0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfUmVtb3RlQ29tbWFuZERlbGF5OgogICAgCQkJCWlmICggclBhciAmJiByUGFyLT5Db3VudCgpID49IDIgJiYgclBhci0+Q291bnQoKSA8PTMgKQogICAgCQkJCXsKICAgIAkJCQkJc3dpdGNoIChyUGFyLT5HZXQoIDEgKS0+R2V0VHlwZSgpKQogICAgCQkJCQl7CiAgICAJCQkJCQljYXNlIFNieExPTkc6CQkvLyBhbGxlcyBpbW1lciBhbHMgU2hvcnQg77+9YmVydHJhZ2VuCiAgICAJCQkJCQljYXNlIFNieFVMT05HOgogICAgCQkJCQkJY2FzZSBTYnhMT05HNjQ6CiAgICAJCQkJCQljYXNlIFNieFVMT05HNjQ6CiAgICAJCQkJCQljYXNlIFNieERPVUJMRToKICAgIAkJCQkJCWNhc2UgU2J4SU5URUdFUjoKICAgIAkJCQkJCWNhc2UgU2J4QllURToKICAgIAkJCQkJCWNhc2UgU2J4VVNIT1JUOgogICAgCQkJCQkJY2FzZSBTYnhJTlQ6CiAgICAJCQkJCQljYXNlIFNieFVJTlQ6CiAgICAJCQkJCQljYXNlIFNieFNJTkdMRToKICAgIAkJCQkJCQlwSW1wbC0+bk1pblJlbW90ZUNvbW1hbmREZWxheSA9IHJQYXItPkdldCggMSApLT5HZXRVTG9uZygpOwogICAgCQkJCQkJCWlmICggclBhci0+Q291bnQoKSA9PSAzICkKICAgIAkJCQkJCQkJcEltcGwtPm5NYXhSZW1vdGVDb21tYW5kRGVsYXkgPSByUGFyLT5HZXQoIDIgKS0+R2V0VUxvbmcoKTsKICAgIAkJCQkJCQllbHNlCiAgICAJCQkJCQkJCXBJbXBsLT5uTWF4UmVtb3RlQ29tbWFuZERlbGF5ID0gcEltcGwtPm5NaW5SZW1vdGVDb21tYW5kRGVsYXk7CiAgICAJCQkJCQkJYnJlYWs7CiAgICAJCQkJCQljYXNlIFNieEJPT0w6CiAgICAJCQkJCQkJcEltcGwtPmJEb1JlbW90ZUNvbW1hbmREZWxheSA9IHJQYXItPkdldCggMSApLT5HZXRCb29sKCk7CiAgICAJCQkJCQkJYnJlYWs7CiAgICAJCQkJCQlkZWZhdWx0OgogICAgCQkJCQkJCVNieEJhc2U6OlNldEVycm9yKCBTYnhFUlJfV1JPTkdfQVJHUyApOwogICAgCQkJCQkJCWJyZWFrOwogICAgCQkJCQl9CiAgICAJCQkJfQogICAgCQkJCWVsc2UKICAgIAkJCQkJU2V0RXJyb3IoIFNieEVSUl9XUk9OR19BUkdTICk7CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0dldEFwcGxpY2F0aW9uUGF0aDoKICAgIAkJCQlpZiAoICFyUGFyICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIE9VU3RyaW5nIGFVcmwgPSBDb25maWc6OkdldERlZkRpcmVjdG9yeSgpOwogICAgICAgICAgICAgICAgICAgICAgICBPVVN0cmluZyBhUGF0aDsKICAgICAgICAgICAgICAgICAgICAgICAgb3NsOjpGaWxlQmFzZTo6Z2V0U3lzdGVtUGF0aEZyb21GaWxlVVJMKCBhVXJsLCBhUGF0aCApOwogICAgICAgICAgICAgICAgICAgICAgICBwVmFyLT5QdXRTdHJpbmcoIFN0cmluZyggYVBhdGggKSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQllbHNlCiAgICAJCQkJCVNldEVycm9yKCBTYnhFUlJfV1JPTkdfQVJHUyApOwogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9HZXRDb21tb25BcHBsaWNhdGlvblBhdGg6CiAgICAJCQkJaWYgKCAhclBhciApCiAgICAgICAgICAgICAgICAgICAgewojaWZkZWYgV05UCiAgICAgICAgICAgICAgICAgICAgICAgIC8vLy8vLy8vICBhZGFwdGVkIHRoaXMgZnJvbSBzZXR1cDJcd2luXHNvdXJjZVxzeXN0ZW1cd2lub3MuY3h4CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhU3lzUGF0aDsKICAgICAgICAgICAgICAgICAgICAgICAgYVN5c1BhdGggPSBfU0hHZXRTcGVjaWFsRm9sZGVyX0NPTU1PTl9BUFBEQVRBKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggYVN5c1BhdGguTGVuKCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwVmFyLT5QdXRTdHJpbmcoIGFTeXNQYXRoICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSAgICAvLyBkZWZhdWx0IHRvIElEX0dldEFwcGxpY2F0aW9uUGF0aCAoc2FtZSBhcyBpbiBzZXR1cCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgT1VTdHJpbmcgYVVybCA9IENvbmZpZzo6R2V0RGVmRGlyZWN0b3J5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPVVN0cmluZyBhUGF0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9zbDo6RmlsZUJhc2U6OmdldFN5c3RlbVBhdGhGcm9tRmlsZVVSTCggYVVybCwgYVBhdGggKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dFN0cmluZyggU3RyaW5nKCBhUGF0aCApICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KI2VsaWYgZGVmaW5lZCBPUzIKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciogZXRjID0gZ2V0ZW52KCJFVEMiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldGMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwVmFyLT5QdXRTdHJpbmcoIENVbmlTdHJpbmcoIGV0YyApICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwVmFyLT5QdXRTdHJpbmcoIENVbmlTdHJpbmcoICIvZXRjIiApICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KI2Vsc2UKI2lmIFVOWAogICAgICAgICAgICAgICAgICAgICAgICBwVmFyLT5QdXRTdHJpbmcoIENVbmlTdHJpbmcoICIvZXRjIiApICk7CiNlbHNlCiNlcnJvciBub3QgaW1wbGVtZW50ZWQKI2VuZGlmCiNlbmRpZgogICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQllbHNlCiAgICAJCQkJCVNldEVycm9yKCBTYnhFUlJfV1JPTkdfQVJHUyApOwogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9NYWtlSW5pRmlsZU5hbWU6CiAgICAJCQkJaWYgKCByUGFyICYmIHJQYXItPkNvdW50KCkgPT0gMiApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBPVVN0cmluZyBhVXJsID0gQ29uZmlnOjpHZXRDb25maWdOYW1lKCBTdHJpbmcoKSwgclBhci0+R2V0KCAxICktPkdldFN0cmluZygpICk7CiAgICAgICAgICAgICAgICAgICAgICAgIE9VU3RyaW5nIGFQYXRoOwogICAgICAgICAgICAgICAgICAgICAgICBvc2w6OkZpbGVCYXNlOjpnZXRTeXN0ZW1QYXRoRnJvbUZpbGVVUkwoIGFVcmwsIGFQYXRoICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dFN0cmluZyggU3RyaW5nKCBhUGF0aCApICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCWVsc2UKICAgIAkJCQkJU2V0RXJyb3IoIFNieEVSUl9XUk9OR19BUkdTICk7CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX1dhaXQ6CiAgICAgICAgICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgICAgICBpZiggclBhciAmJiByUGFyLT5Db3VudCgpID09IDIgKQoJICAgICAgICAgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgICAgICAgICBsb25nIG5XYWl0ID0gclBhci0+R2V0KDEpLT5HZXRMb25nKCk7CgkgICAgICAgICAgICAgICAgICAgICAgICBpZiggbldhaXQgPj0gMCApCgkgICAgICAgICAgICAgICAgICAgICAgICB7CiNpZmRlZiBERUJVRwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWUgYVN0YXJ0OwojZW5kaWYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lciBhVGltZXI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVRpbWVyLlNldFRpbWVvdXQoIG5XYWl0ICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVRpbWVyLlN0YXJ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCBhVGltZXIuSXNBY3RpdmUoKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwcGxpY2F0aW9uOjpZaWVsZCgpOwojaWZkZWYgREVCVUcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lIGFFbmQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZSBhRGlmZiA9IGFFbmQgLSBhU3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBhTVMgPSBsb25nKCBhRGlmZi5HZXRNU0Zyb21UaW1lKCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIEFicyggYU1TIC0gbldhaXQgKSA+IDEwMCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQkdfRVJST1IxKCJXYWl0IHdhcyBvZmYgbGltaXQgYnkgJWkiLCBhRGlmZi5HZXRNU0Zyb21UaW1lKCkgLSBuV2FpdCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KI2VuZGlmCgkgICAgICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQkgICAgZWxzZQoJCSAgICAgICAgICAgICAgICAgICAgU2V0RXJyb3IoIFNiRVJSX0JBRF9OVU1CRVJfT0ZfQVJHUyApOwogICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfR2V0RXJyb3JDb3VudDoKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dFVMb25nKCBwSW1wbC0+bkVycm9yQ291bnQgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0dldFdhcm5pbmdDb3VudDoKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dFVMb25nKCBwSW1wbC0+bldhcm5pbmdDb3VudCApOwogICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfR2V0UUFFcnJvckNvdW50OgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcFZhci0+UHV0VUxvbmcoIHBJbXBsLT5uUUFFcnJvckNvdW50ICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9HZXRVc2VGaWxlV2FybmluZ0NvdW50OgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcFZhci0+UHV0VUxvbmcoIHBJbXBsLT5uSW5jbHVkZUZpbGVXYXJuaW5nQ291bnQgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0dldEVycm9yTGlzdDoKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggISBwSW1wbC0+eEVycm9yTGlzdC0+R2V0RGltcygpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT54RXJyb3JMaXN0LT5BZGREaW0oIDEsIDMyMDAwICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dE9iamVjdCggcEltcGwtPnhFcnJvckxpc3QgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0dldFdhcm5pbmdMaXN0OgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhIHBJbXBsLT54V2FybmluZ0xpc3QtPkdldERpbXMoKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+eFdhcm5pbmdMaXN0LT5BZGREaW0oIDEsIDMyMDAwICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dE9iamVjdCggcEltcGwtPnhXYXJuaW5nTGlzdCApOwogICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfR2V0UUFFcnJvckxpc3Q6CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoICEgcEltcGwtPnhRQUVycm9yTGlzdC0+R2V0RGltcygpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT54UUFFcnJvckxpc3QtPkFkZERpbSggMSwgMzIwMDAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgcFZhci0+UHV0T2JqZWN0KCBwSW1wbC0+eFFBRXJyb3JMaXN0ICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9HZXRVc2VGaWxlV2FybmluZ0xpc3Q6CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoICEgcEltcGwtPnhJbmNsdWRlRmlsZVdhcm5pbmdMaXN0LT5HZXREaW1zKCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcEltcGwtPnhJbmNsdWRlRmlsZVdhcm5pbmdMaXN0LT5BZGREaW0oIDEsIDMyMDAwICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dE9iamVjdCggcEltcGwtPnhJbmNsdWRlRmlsZVdhcm5pbmdMaXN0ICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9HZXRUZXN0Q2FzZU5hbWU6CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwVmFyLT5QdXRTdHJpbmcoIHBJbXBsLT5hVGVzdENhc2VOYW1lICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9HZXRUZXN0Q2FzZUZpbGVOYW1lOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcFZhci0+UHV0U3RyaW5nKCBwSW1wbC0+YVRlc3RDYXNlRmlsZU5hbWUgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0dldFRlc3RDYXNlTGluZU5yOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcFZhci0+UHV0VVNob3J0KCBwSW1wbC0+blRlc3RDYXNlTGluZU5yICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9TZXRDaGlsZEVudjoKICAgICAgICAgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgICAgIGlmKCByUGFyICYmIHJQYXItPkNvdW50KCkgPT0gMyApCgkgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5wQ2hpbGRFbnYtPmVyYXNlKCByUGFyLT5HZXQoMSktPkdldFN0cmluZygpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+cENoaWxkRW52LT5pbnNlcnQoIEVudmlyb25tZW50VmFyaWFibGUoIHJQYXItPkdldCgxKS0+R2V0U3RyaW5nKCksIHJQYXItPkdldCgyKS0+R2V0U3RyaW5nKCkgKSApOwoJICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJICAgIGVsc2UKCQkgICAgICAgICAgICAgICAgICAgIFNldEVycm9yKCBTYkVSUl9CQURfTlVNQkVSX09GX0FSR1MgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0dldENoaWxkRW52OgogICAgICAgICAgICAgICAgICAgIHsKCSAgICAgICAgICAgICAgICAgICAgaWYoIHJQYXIgJiYgclBhci0+Q291bnQoKSA9PSAyICkKCSAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRW52aXJvbm1lbnQ6OmNvbnN0X2l0ZXJhdG9yIGFJdGVyID0gcEltcGwtPnBDaGlsZEVudi0+ZmluZCggclBhci0+R2V0KDEpLT5HZXRTdHJpbmcoKSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBhSXRlciAhPSBwSW1wbC0+cENoaWxkRW52LT5lbmQoKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFZhci0+UHV0U3RyaW5nKCAoKmFJdGVyKS5zZWNvbmQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwVmFyLT5QdXRTdHJpbmcoIFN0cmluZygpICk7CgkgICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQkgICAgZWxzZQoJCSAgICAgICAgICAgICAgICAgICAgU2V0RXJyb3IoIFNiRVJSX0JBRF9OVU1CRVJfT0ZfQVJHUyApOwogICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgSURfR2V0TGlua0Rlc3RpbmF0aW9uOgogICAgICAgICAgICAgICAgICAgIHsKCSAgICAgICAgICAgICAgICAgICAgaWYoIHJQYXIgJiYgclBhci0+Q291bnQoKSA9PSAyICkKCSAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFTb3VyY2UsYURlc3Q7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhU291cmNlID0gclBhci0+R2V0KDEpLT5HZXRTdHJpbmcoKTsKI2lmZGVmIFVOWAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQnl0ZVN0cmluZyBhQnl0ZVNvdXJjZSggYVNvdXJjZSwgb3NsX2dldFRocmVhZFRleHRFbmNvZGluZygpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGNEZXN0WzEwMjRdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5MZW4gPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAoIG5MZW4gPSByZWFkbGluayggYUJ5dGVTb3VyY2UuR2V0QnVmZmVyKCksIGNEZXN0LCBzaXplb2YoY0Rlc3QpICkgKSA+PSAwICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhRGVzdCA9IFN0cmluZyggY0Rlc3QsIG5MZW4sIG9zbF9nZXRUaHJlYWRUZXh0RW5jb2RpbmcoKSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBuRXJyID0gZXJybm87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICggbkVyciApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEVJTlZBTDogYURlc3QgPSBhU291cmNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRFcnJvciggU2JFUlJfQUNDRVNTX0VSUk9SICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQojZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYURlc3QgPSBhU291cmNlOwojZW5kaWYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBWYXItPlB1dFN0cmluZyggYURlc3QgKTsKCSAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCSAgICBlbHNlCgkJICAgICAgICAgICAgICAgICAgICBTZXRFcnJvciggU2JFUlJfQkFEX05VTUJFUl9PRl9BUkdTICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9HZXRSZWdpc3RyeVZhbHVlOgogICAgICAgICAgICAgICAgICAgIHsKCSAgICAgICAgICAgICAgICAgICAgaWYoIHJQYXIgJiYgclBhci0+Q291bnQoKSA9PSAzICkKCSAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFWYWx1ZTsKI2lmZGVmIFdOVAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYVZhbHVlID0gUmVhZFJlZ2lzdHJ5KCByUGFyLT5HZXQoMSktPkdldFN0cmluZygpLCByUGFyLT5HZXQoMiktPkdldFN0cmluZygpICk7CiNlbmRpZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFZhci0+UHV0U3RyaW5nKCBhVmFsdWUgKTsKCSAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCSAgICBlbHNlCgkJICAgICAgICAgICAgICAgICAgICBTZXRFcnJvciggU2JFUlJfQkFEX05VTUJFUl9PRl9BUkdTICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9IVFRQU2VuZDoKICAgICAgICAgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgICAgIGlmKCByUGFyICYmICggclBhci0+Q291bnQoKSA9PSA0IHx8IHJQYXItPkNvdW50KCkgPT0gNSApICkKCSAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhcEltcGwtPnBIdHRwUmVxdWVzdCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEltcGwtPnBIdHRwUmVxdWVzdCA9IG5ldyBIdHRwUmVxdWVzdDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5wSHR0cFJlcXVlc3QtPlNldFJlcXVlc3QoIEJ5dGVTdHJpbmcoIHJQYXItPkdldCgxKS0+R2V0U3RyaW5nKCksIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKSwgQnl0ZVN0cmluZyggclBhci0+R2V0KDIpLT5HZXRTdHJpbmcoKSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApLCByUGFyLT5HZXQoMyktPkdldFVTaG9ydCgpICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBwSW1wbC0+cEh0dHBSZXF1ZXN0LT5FeGVjdXRlKCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggclBhci0+Q291bnQoKSA9PSA1ICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgLy8gZmlsZW5hbWUgaXMgZ2l2ZW4KCQkJICAgICAgICAgICAgICAgICAgICAgICAgU3ZGaWxlU3RyZWFtIGFEZXN0aW5hdGlvbiggclBhci0+R2V0KDQpLT5HZXRTdHJpbmcoKSwgU1RSRUFNX1NURF9SRUFEV1JJVEUgfCBTVFJFQU1fVFJVTkMgKTsKCQkJICAgICAgICAgICAgICAgICAgICAgICAgKCoocEltcGwtPnBIdHRwUmVxdWVzdC0+R2V0Qm9keSgpKSkgPj4gYURlc3RpbmF0aW9uOwoJCQkgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFEZXN0aW5hdGlvbi5HZXRFcnJvcigpICE9IEVSUkNPREVfTk9ORSApCgkJCQkgICAgICAgICAgICAgICAgICAgICAgICBTZXRFcnJvciggU2JFUlJfQUNDRVNTX0VSUk9SICk7CgkJCSAgICAgICAgICAgICAgICAgICAgICAgIGFEZXN0aW5hdGlvbi5DbG9zZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwVmFyLT5QdXRVU2hvcnQoIHBJbXBsLT5wSHR0cFJlcXVlc3QtPkdldFJlc3VsdElkKCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgIAkJICAgICAgICAgICAgICAgICAgICBTZXRFcnJvciggU2JFUlJfQUNDRVNTX0VSUk9SICk7CgkgICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQkgICAgZWxzZQoJCSAgICAgICAgICAgICAgICAgICAgU2V0RXJyb3IoIFNiRVJSX0JBRF9OVU1CRVJfT0ZfQVJHUyAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIElEX0hUVFBTZXRQcm94eToKICAgICAgICAgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgICAgIGlmKCByUGFyICYmIHJQYXItPkNvdW50KCkgPT0gMyApCgkgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIXBJbXBsLT5wSHR0cFJlcXVlc3QgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5wSHR0cFJlcXVlc3QgPSBuZXcgSHR0cFJlcXVlc3Q7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+cEh0dHBSZXF1ZXN0LT5TZXRQcm94eSggQnl0ZVN0cmluZyggclBhci0+R2V0KDEpLT5HZXRTdHJpbmcoKSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApLCByUGFyLT5HZXQoMiktPkdldFVTaG9ydCgpICk7CgkgICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQkgICAgZWxzZQoJCSAgICAgICAgICAgICAgICAgICAgU2V0RXJyb3IoIFNiRVJSX0JBRF9OVU1CRVJfT0ZfQVJHUyApOwogICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQlicmVhazsKICAgIAkJfSAgLy8gIHN3aXRjaCggbkhpbnRVc2VyRGF0YSApCiAgICAJfSAgLy8gaWYoIG5IaW50SWQgPT0gU0JYX0hJTlRfREFUQVdBTlRFRCApCiAgICAJZWxzZSBpZiggbkhpbnRJZCA9PSBTQlhfSElOVF9EQVRBQ0hBTkdFRCApCiAgICAJewogICAgCQlzd2l0Y2goIG5IaW50VXNlckRhdGEgKQogICAgCQl7CiAgICAJCQljYXNlIElEX0F1dG9FeGVjdXRlOgogICAgCQkJCWlmICggIXJQYXIgKSAgLy8gclBhciA9IE5VTEwgIDw9PiAgS2VpbiBQYXJhbWV0ZXIKICAgIAkJCQl7CiAgICAJCQkJCVNpbmdsZUNvbW1hbmRCbG9jayA9IHBWYXItPkdldEJvb2woKTsKICAgIAkJCQkJaWYgKCBTaW5nbGVDb21tYW5kQmxvY2sgKQogICAgCQkJCQkJRW5kQmxvY2soKTsKICAgIAkJCQkJZWxzZQogICAgCQkJCQkJQmVnaW5CbG9jaygpOwogICAgCQkJCX0KICAgIAkJCQllbHNlCiAgICAJCQkJCVNldEVycm9yKCBTYnhFUlJfV1JPTkdfQVJHUyApOwogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBJRF9FbmFibGVRYUVycm9yczoKICAgIAkJCQlpZiAoICFyUGFyICkgIC8vIHJQYXIgPSBOVUxMICA8PT4gIEtlaW4gUGFyYW1ldGVyCiAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5iRW5hYmxlUWFFcnJvcnMgPSBwVmFyLT5HZXRCb29sKCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgCQkJCQlTZXRFcnJvciggU2J4RVJSX1dST05HX0FSR1MgKTsKICAgIAkJCQlicmVhazsKICAgIAkJfQogICAgCX0gIC8vIGlmKCBuSGludElkID09IFNCWF9ISU5UX0RBVEFDSEFOR0VEICkKICAgIAllbHNlIGlmKCBuSGludElkID09IFNCWF9ISU5UX0JBU0lDU1RBUlQgKQogICAgCXsKICAgIAkJcEltcGwtPm5FcnJvckNvdW50ID0gMDsKICAgIAkJcEltcGwtPm5XYXJuaW5nQ291bnQgPSAwOwogICAgCQlwSW1wbC0+blFBRXJyb3JDb3VudCA9IDA7CiAgICAJCXBJbXBsLT5uSW5jbHVkZUZpbGVXYXJuaW5nQ291bnQgPSAwOwoKICAgICAgICAgICAgcEltcGwtPnhFcnJvckxpc3QtPlNieEFycmF5OjpDbGVhcigpOyAgIC8vIGNhbGwgU2J4QXJyYXk6OkNsZWFyIGJlY2F1c2UgU2J4VmFyQXJyYXk6OkNsZWFyIG9ubHkgY2xlYXJzIGRpbWVuc2lvbnMgYnV0IG5vIGNvbnRlbnQKICAgICAgICAgICAgcEltcGwtPnhXYXJuaW5nTGlzdC0+U2J4QXJyYXk6OkNsZWFyKCk7IC8vIGNhbGwgU2J4QXJyYXk6OkNsZWFyIGJlY2F1c2UgU2J4VmFyQXJyYXk6OkNsZWFyIG9ubHkgY2xlYXJzIGRpbWVuc2lvbnMgYnV0IG5vIGNvbnRlbnQKICAgICAgICAgICAgcEltcGwtPnhRQUVycm9yTGlzdC0+U2J4QXJyYXk6OkNsZWFyKCk7ICAgLy8gY2FsbCBTYnhBcnJheTo6Q2xlYXIgYmVjYXVzZSBTYnhWYXJBcnJheTo6Q2xlYXIgb25seSBjbGVhcnMgZGltZW5zaW9ucyBidXQgbm8gY29udGVudAogICAgICAgICAgICBwSW1wbC0+eEluY2x1ZGVGaWxlV2FybmluZ0xpc3QtPlNieEFycmF5OjpDbGVhcigpOyAgLy8gY2FsbCBTYnhBcnJheTo6Q2xlYXIgYmVjYXVzZSBTYnhWYXJBcnJheTo6Q2xlYXIgb25seSBjbGVhcnMgZGltZW5zaW9ucyBidXQgbm8gY29udGVudAoKICAgICAgICAgICAgaWYgKHBGZWhsZXJMaXN0ZSkKICAgIAkJCWRlbGV0ZSBwRmVobGVyTGlzdGU7CiAgICAJCXBGZWhsZXJMaXN0ZSA9IG5ldyBDRXJyb3JzOwoKICAgIAkJZm9yIChzYWxfdUludDE2IGk9MDtpPFZBUl9QT09MX1NJWkU7aSsrKQogICAgCQl7CiAgICAJCQlwSW1wbC0+cE15VmFyc1tpXS0+U2V0TmFtZSggQ1VuaVN0cmluZygiVmFyRHVtbXkiKS5BcHBlbmQoVW5pU3RyaW5nOjpDcmVhdGVGcm9tSW50MzIoaSkpICk7CiAgICAJCX0KICAgIAkJbk15VmFyID0gMDsKCiAgICAJfSAgLy8gaWYoIG5IaW50SWQgPT0gU0JYX0hJTlRfQkFTSUNTVEFSVCApCiAgICAJZWxzZSBpZiggbkhpbnRJZCA9PSBTQlhfSElOVF9CQVNJQ1NUT1AgKQogICAgCXsKICAgIAkJLy8gTG9nIHN1bW1hcnkgdG8gam91cm5hbAogICAgCQlBRERfQ0FTRV9MT0coIFN0cmluZygpICk7ICAgICAgIC8vIENhc2UgYWJzY2hsaWVzc2VuCiAgICAJCUFERF9NRVNTQUdFX0xPRyggQ1VuaVN0cmluZygiKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqIikgKTsKICAgIAkJaWYgKCBwSW1wbC0+bkVycm9yQ291bnQgKQogICAgCQl7CiAgICAJCQlBRERfV0FSTklOR19MT0coIEdFTl9SRVNfU1RSMSggU19FUlJPUlNfREVURUNURUQsIFN0cmluZzo6Q3JlYXRlRnJvbUludDMyKCBwSW1wbC0+bkVycm9yQ291bnQgKSApICk7CiAgICAJCQlwSW1wbC0+bldhcm5pbmdDb3VudC0tOwkJLy8gQW5wYXNzZW4sIGRhIGRpZXNlIFdhcm51bmcgbmljaHQgaW4gZGllIFN0YXRpc3RpayBzb2xsCiAgICAJCX0KICAgIAkJZWxzZQogICAgCQkJQUREX01FU1NBR0VfTE9HKCBHRU5fUkVTX1NUUjAoIFNfTk9fRVJST1JTX0RFVEVDVEVEICkgKTsKCiAgICAJCWlmICggcEltcGwtPm5XYXJuaW5nQ291bnQgKQogICAgCQkJQUREX1dBUk5JTkdfTE9HKCBHRU5fUkVTX1NUUjEoIFNfV0FSTklOR1NfREVURUNURUQsIFN0cmluZzo6Q3JlYXRlRnJvbUludDMyKCBwSW1wbC0+bldhcm5pbmdDb3VudCApICkgKQogICAgCQllbHNlCiAgICAJCQlBRERfTUVTU0FHRV9MT0coIEdFTl9SRVNfU1RSMCggU19OT19XQVJOSU5HU19ERVRFQ1RFRCApICk7CgogICAgCQlpZiAoIHBJbXBsLT5uSW5jbHVkZUZpbGVXYXJuaW5nQ291bnQgKQogICAgCQkJQUREX1dBUk5JTkdfTE9HKCBHRU5fUkVTX1NUUjEoIFNfSU5DTFVERV9GSUxFX1dBUk5JTkdTX0RFVEVDVEVELCBTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMiggcEltcGwtPm5JbmNsdWRlRmlsZVdhcm5pbmdDb3VudCApICkgKQogICAgCQllbHNlCiAgICAJCQlBRERfTUVTU0FHRV9MT0coIEdFTl9SRVNfU1RSMCggU19OT19JTkNMVURFX0ZJTEVfV0FSTklOR1NfREVURUNURUQgKSApOwogICAgCQlBRERfTUVTU0FHRV9MT0coIENVbmlTdHJpbmcoIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiIpICk7CgogICAgCQlwSW1wbC0+bkVycm9yQ291bnQgPSAwOwogICAgCQlwSW1wbC0+bldhcm5pbmdDb3VudCA9IDA7CiAgICAJCXBJbXBsLT5uUUFFcnJvckNvdW50ID0gMDsKICAgIAkJcEltcGwtPm5JbmNsdWRlRmlsZVdhcm5pbmdDb3VudCA9IDA7CgogICAgICAgICAgICBwSW1wbC0+eEVycm9yTGlzdC0+U2J4QXJyYXk6OkNsZWFyKCk7ICAgLy8gY2FsbCBTYnhBcnJheTo6Q2xlYXIgYmVjYXVzZSBTYnhWYXJBcnJheTo6Q2xlYXIgb25seSBjbGVhcnMgZGltZW5zaW9ucyBidXQgbm8gY29udGVudAogICAgICAgICAgICBwSW1wbC0+eFdhcm5pbmdMaXN0LT5TYnhBcnJheTo6Q2xlYXIoKTsgLy8gY2FsbCBTYnhBcnJheTo6Q2xlYXIgYmVjYXVzZSBTYnhWYXJBcnJheTo6Q2xlYXIgb25seSBjbGVhcnMgZGltZW5zaW9ucyBidXQgbm8gY29udGVudAogICAgICAgICAgICBwSW1wbC0+eFFBRXJyb3JMaXN0LT5TYnhBcnJheTo6Q2xlYXIoKTsgICAvLyBjYWxsIFNieEFycmF5OjpDbGVhciBiZWNhdXNlIFNieFZhckFycmF5OjpDbGVhciBvbmx5IGNsZWFycyBkaW1lbnNpb25zIGJ1dCBubyBjb250ZW50CiAgICAgICAgICAgIHBJbXBsLT54SW5jbHVkZUZpbGVXYXJuaW5nTGlzdC0+U2J4QXJyYXk6OkNsZWFyKCk7ICAvLyBjYWxsIFNieEFycmF5OjpDbGVhciBiZWNhdXNlIFNieFZhckFycmF5OjpDbGVhciBvbmx5IGNsZWFycyBkaW1lbnNpb25zIGJ1dCBubyBjb250ZW50CiAgICAgICAgfSAgLy8gaWYoIG5IaW50SWQgPT0gU0JYX0hJTlRfQkFTSUNTVE9QICkKICAgIAlXYWl0Rm9yQW5zd2VyKCk7CiAgICAJaWYgKCBJc0Vycm9yKCkgJiYgKCAhSVNfRVJST1IoKSB8fCBHRVRfRVJST1IoKS0+bkVycm9yICE9IEdldEVycm9yKCkgKSApCiAgICAJewogICAgCQkoKFN0YXJCQVNJQyopR2V0UGFyZW50KCkpLT5NYWtlRXJyb3JUZXh0KEdldEVycm9yKCksU3RyaW5nKCkpOwogICAgCQlBRERfRVJST1JfUVVJRVQoR2V0RXJyb3IoKSxTdHJpbmcocFZhci0+R2V0TmFtZSgpKS5BcHBlbmRBc2NpaSgiOiAiKS4KICAgIAkJCUFwcGVuZCgoKFN0YXJCQVNJQyopR2V0UGFyZW50KCkpLT5HZXRFcnJvclRleHQoKSkpOwogICAgCX0KCX0KfQoKdm9pZCBUZXN0VG9vbE9iajo6RGVidWdGaW5kTm9FcnJvcnMoIHNhbF9Cb29sIGJEZWJ1Z0ZpbmROb0Vycm9ycyApCnsKCXBJbXBsLT5iRGVidWdGaW5kTm9FcnJvcnMgPSBiRGVidWdGaW5kTm9FcnJvcnM7Cn0KClNieFZhcmlhYmxlKiBUZXN0VG9vbE9iajo6RmluZCggY29uc3QgU3RyaW5nJiBhU3RyLCBTYnhDbGFzc1R5cGUgYVR5cGUpCnsKCWlmICggQmFzaWNSdW50aW1lQWNjZXNzOjpJc1J1bkluaXQoKSApICAgICAgICAgICAgLy8gd2VnZW4gRmluZCBpbSAiR2xvYmFsIiBCZWZlaGwgZGVzIEJhc2ljCiAgICAJcmV0dXJuIE5VTEw7CgoJU2J4VmFyaWFibGVSZWYgT2xkID0gU2J4T2JqZWN0OjpGaW5kKGFTdHIsIGFUeXBlICk7CiAgICAvLyBkbyBub3QgcmV0dXJuIGFueSBvYmplY3RzIGZyb20gcE15VmFyc1tdCglpZiAoT2xkICYmIE9sZC0+R2V0VXNlckRhdGEoKSAhPSBJRF9EaXNwYXRjaAogICAgICAgICAgICAmJiBPbGQtPkdldFVzZXJEYXRhKCkgIT0gSURfVU5PRGlzcGF0Y2gKICAgICAgICAgICAgJiYgT2xkLT5HZXRVc2VyRGF0YSgpICE9IElEX0Vycm9yRHVtbXkKICAgICAgICAgICAgJiYgT2xkLT5HZXRVc2VyRGF0YSgpICE9IDAgKQogICAgCXJldHVybiBPbGQ7CgllbHNlIGlmICggYVN0ci5TZWFyY2hBc2NpaSgiOiIpICE9IFNUUklOR19OT1RGT1VORCApCiAgICB7ICAgLy8gaWdub3JlIHF1YWxpZmllZCBuYW1lcyBlLmcuICBtYWluOkZvcm1XaXphcmQgICAgIElmIHRoaXMgd2FzIHJlbW92ZWQgYW4gZXJyb3Igd291bGQgYmUgZ2VuZXJhdGVkCiAgICB9CgllbHNlCgl7CgogICAgCXNhbF91SW50MTYgbkVsZW1lbnQ7CiAgICAJQ29udHJvbERlZiAqcFdoYXROYW1lID0gbmV3IENvbnRyb2xEZWYoYVN0cixydGw6Ok9TdHJpbmcoKSk7CgogICAgCS8vLyBuYWNoIENvbnRyb2xzIHN1Y2hlbgogICAgCWlmIChtX3BOYW1lS29udGV4dCAmJiBtX3BOYW1lS29udGV4dC0+U2Vla19FbnRyeShwV2hhdE5hbWUsJm5FbGVtZW50KSkKICAgIAl7CiAgICAJCWRlbGV0ZSBwV2hhdE5hbWU7CiAgICAJCXBXaGF0TmFtZSA9ICgoQ29udHJvbERlZiopbV9wTmFtZUtvbnRleHQtPkdldE9iamVjdChuRWxlbWVudCkpOwoKLy8vLyBuZXcgQ29udHJvbHMgT2JqZWN0IGV2ZXJ5IHRpbWUKICAgIAkgICAgcEltcGwtPnBDb250cm9sc09iaiA9IG5ldyBDb250cm9scyggcFdoYXROYW1lLT5wRGF0YS0+S3Vyem5hbWUgKTsKICAgIAkgICAgcEltcGwtPnBDb250cm9sc09iai0+U2V0VHlwZSggU2J4T0JKRUNUICk7CiAgICAJICAgIHBJbXBsLT5wQ29udHJvbHNPYmotPkNoYW5nZUxpc3RlbmVyKCB0aGlzICk7CgoKICAgICAgICAgICAgLy8gV2lsbCBiZSBzZXQgb24gbWV0aG9kLWNoaWxkIGZ1cnRoZXIgZG93bgogICAgICAgICAgICAvLyBGSVhNRTogSEVMUElECiAgICAgICAgICAgICNpZiAwCiAgICAJCWlmICggcFdoYXROYW1lLT5wRGF0YS0+YVVJZC5IYXNOdW1lcmljKCkgKQogICAgCQkgICAgcEltcGwtPnBDb250cm9sc09iai0+U2V0VXNlckRhdGEoIElEX0NvbnRyb2wgKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAjZW5kaWYKICAgICAgICAgICAgICAgIHBJbXBsLT5wQ29udHJvbHNPYmotPlNldFVzZXJEYXRhKCBJRF9TdHJpbmdDb250cm9sICk7CgogICAgCQlwU2hvcnROYW1lcy0+SW5zZXJ0KHBXaGF0TmFtZS0+cERhdGEtPkt1cnpuYW1lLHBXaGF0TmFtZS0+cERhdGEtPmFVSWQsblNlcXVlbmNlKTsKCiAgICAJCVNieFZhcmlhYmxlICpwTWVtYmVyID0gcEltcGwtPnBDb250cm9sc09iai0+RmluZChDVW5pU3RyaW5nKCJJRCIpLFNieENMQVNTX0RPTlRDQVJFKTsKICAgIAkJaWYgKCBwTWVtYmVyID09IE5VTEwgKQogICAgCQl7CiAgICAJCQlTYnhQcm9wZXJ0eSogcElEID0gbmV3IFNieFByb3BlcnR5KENVbmlTdHJpbmcoIklEIiksU2J4VkFSSUFOVCk7CiAgICAJCQlwSW1wbC0+cENvbnRyb2xzT2JqLT5JbnNlcnQocElEKTsKICAgICAgICAgICAgICAgIHBJbXBsLT5wQ29udHJvbHNPYmotPlNldERmbHRQcm9wZXJ0eShwSUQpOwogICAgICAgICAgICAgICAgcE1lbWJlciA9IHBJRDsKICAgIAkJfQogICAgCQkvLyBGSVhNRTogSEVMUElECiAgICAJCSNpZiAwCiAgICAgICAgICAgIGlmICggcFdoYXROYW1lLT5wRGF0YS0+YVVJZC5IYXNOdW1lcmljKCkgKQogICAgCQkgICAgcE1lbWJlci0+UHV0VUxvbmcocFdoYXROYW1lLT5wRGF0YS0+YVVJZC5HZXROdW0oKSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBNZW1iZXItPlB1dFN0cmluZyhwV2hhdE5hbWUtPnBEYXRhLT5hVUlkLkdldFN0cigpKTsKICAgICAgICAgICAgI2VuZGlmCgogICAgICAgICAgICBwTWVtYmVyID0gcEltcGwtPnBDb250cm9sc09iai0+RmluZChDVW5pU3RyaW5nKCJuYW1lIiksU2J4Q0xBU1NfRE9OVENBUkUpOwogICAgCQlpZiAoIHBNZW1iZXIgIT0gTlVMTCApCiAgICAJCQlwTWVtYmVyLT5QdXRTdHJpbmcocFdoYXROYW1lLT5wRGF0YS0+S3Vyem5hbWUpOwoKICAgIAkJcmV0dXJuIHBJbXBsLT5wQ29udHJvbHNPYmo7CiAgICAJfQoKICAgIAkvLy8gTmFjaCBzbG90cyBzdWNoZW4KICAgIAlpZiAobV9wU0lkcyAmJiBtX3BTSWRzLT5TZWVrX0VudHJ5KHBXaGF0TmFtZSwmbkVsZW1lbnQpKQogICAgCXsKICAgIAkJU2J4VHJhbnNwb3J0TWV0aG9kUmVmIHBNeVZhcjsKICAgIAkJcE15VmFyID0gcEltcGwtPnBNeVZhcnNbbk15VmFyKytdOwogICAgCQlpZiAoIG5NeVZhciA+PSBWQVJfUE9PTF9TSVpFICkKICAgIAkJCW5NeVZhciA9IDA7CiAgICAJCWRlbGV0ZSBwV2hhdE5hbWU7CiAgICAJCXBXaGF0TmFtZSA9ICggKENvbnRyb2xEZWYqKW1fcFNJZHMtPkdldE9iamVjdCggbkVsZW1lbnQgKSApOwogICAgCQlwTXlWYXItPlNldE5hbWUoIHBXaGF0TmFtZS0+cERhdGEtPkt1cnpuYW1lICk7CgogICAgCQkvLyBGSVhNRTogSEVMUElECiAgICAJCSNpZiAwCiAgICAgICAgICAgIGlmICggcFdoYXROYW1lLT5wRGF0YS0+YVVJZC5IYXNOdW1lcmljKCkgKQogICAgCQl7CiAgICAJCQlwTXlWYXItPlNldFVzZXJEYXRhKCBJRF9EaXNwYXRjaCApOwogICAgCQkJcE15VmFyLT5uVmFsdWUgPSBwV2hhdE5hbWUtPnBEYXRhLT5hVUlkLkdldE51bSgpOwogICAgCQkJcFNob3J0TmFtZXMtPkluc2VydCggYVN0ciwgcFdoYXROYW1lLT5wRGF0YS0+YVVJZCwgblNlcXVlbmNlICk7CiAgICAJCX0KICAgIAkJZWxzZQogICAgCQl7CiAgICAJCQlwTXlWYXItPlNldFVzZXJEYXRhKCBJRF9VTk9EaXNwYXRjaCApOwogICAgCQkJcE15VmFyLT5hVW5vU2xvdCA9IHBXaGF0TmFtZS0+cERhdGEtPmFVSWQuR2V0U3RyKCk7CiAgICAJCX0KICAgIAkJI2VuZGlmCiAgICAJCXJldHVybiBwTXlWYXI7CiAgICAJfQoKICAgIAkvLy8gZXMga2FubiBzaWNoIG5vY2ggdW0gZWluZSBTbG90SUQgaGFuZGVsbiwgZGllIG51bWVyaXNjaCBhYmdlZnJhZ3Qgd2lyZCwgc3RhdHQgYXVzZ2Vm77+9aHJ0IHp1IHdlcmRlbgogICAgCWlmICggYVN0ci5Db3B5KCBhU3RyLkxlbigpLTMsIDMgKS5Db21wYXJlSWdub3JlQ2FzZVRvQXNjaWkoIl9JRCIpID09IENPTVBBUkVfRVFVQUwgJiYgbV9wU0lkcyApCiAgICAJewogICAgCQlkZWxldGUgcFdoYXROYW1lOwogICAgCQlwV2hhdE5hbWUgPSBuZXcgQ29udHJvbERlZiggYVN0ci5Db3B5KCAwLCBhU3RyLkxlbigpLTMgKSwgcnRsOjpPU3RyaW5nKCkgKTsKICAgIAkJaWYgKCBtX3BTSWRzLT5TZWVrX0VudHJ5KCBwV2hhdE5hbWUsICZuRWxlbWVudCApICkKICAgIAkJewkvLyBOYWNoIHNsb3RzIHN1Y2hlbgogICAgCQkJU2J4VmFyaWFibGUgKnBSZXR1cm4gPSBuZXcgU2J4VmFyaWFibGU7CiAgICAJCQlkZWxldGUgcFdoYXROYW1lOwogICAgCQkJcFdoYXROYW1lID0gKCAoQ29udHJvbERlZiopbV9wU0lkcy0+R2V0T2JqZWN0KCBuRWxlbWVudCApICk7CiAgICAJCQlwUmV0dXJuLT5TZXROYW1lKCBwV2hhdE5hbWUtPnBEYXRhLT5LdXJ6bmFtZSApOwoKICAgIAkJCS8vIEZJWE1FOiBIRUxQSUQKICAgIAkJCSNpZiAwCiAgICAgICAgICAgICAgICBpZiAoIHBXaGF0TmFtZS0+cERhdGEtPmFVSWQuSGFzTnVtZXJpYygpICkKICAgIAkJICAgICAgICBwUmV0dXJuLT5QdXRVTG9uZyhwV2hhdE5hbWUtPnBEYXRhLT5hVUlkLkdldE51bSgpKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBwUmV0dXJuLT5QdXRTdHJpbmcocFdoYXROYW1lLT5wRGF0YS0+YVVJZC5HZXRTdHIoKSk7CiAgICAgICAgICAgICAgICAjZW5kaWYKICAgIAkJCXJldHVybiBwUmV0dXJuOwogICAgCQl9CiAgICAJfQogICAgICAgIGlmICggIXBJbXBsLT5iRGVidWdGaW5kTm9FcnJvcnMgKQogICAgICAgIHsKICAgIAkgICAgQUREX0VSUk9SKFNieEVSUl9QUk9DX1VOREVGSU5FRCxHRU5fUkVTX1NUUjEoU19VTktOT1dOX1NMT1RfQ09OVFJPTCwgYVN0cikgKTsKICAgICAgICB9Cgl9CglyZXR1cm4gTlVMTDsKfQoKU3RyaW5nIFRlc3RUb29sT2JqOjpHZXRSZXZpc2lvbiggU3RyaW5nIGNvbnN0ICZhU291cmNlSW4gKQp7CiAgICAvLyBzZWFyY2ggJFJldmlzaW9uOiAxLjQwICQKICAgIHh1Yl9TdHJMZW4gblBvczsKICAgIGlmICggKCBuUG9zID0gYVNvdXJjZUluLlNlYXJjaEFzY2lpKCAiJFJldmlzaW9uOiIgKSApICE9IFNUUklOR19OT1RGT1VORCApCiAgICAgICAgcmV0dXJuIGFTb3VyY2VJbi5Db3B5KCBuUG9zKyAxMCwgYVNvdXJjZUluLlNlYXJjaEFzY2lpKCAiJCIsIG5Qb3MrMTAgKSAtblBvcy0xMCk7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJObyBSZXZpc2lvbiBmb3VuZCIpOwp9CgpzYWxfQm9vbCBUZXN0VG9vbE9iajo6Q0Vycm9yKCBzYWxfdUxvbmcgY29kZSwgY29uc3QgU3RyaW5nJiByTXNnLCB4dWJfU3RyTGVuIGwsIHh1Yl9TdHJMZW4gYzEsIHh1Yl9TdHJMZW4gYzIgKQp7CgliV2FzUHJlY29tcGlsZXJFcnJvciA9IHNhbF9UcnVlOwoJaWYgKCBhQ0Vycm9ySGRsLklzU2V0KCkgKQoJewogICAgCUVycm9yRW50cnkgYUVycm9yRW50cnkoIGNvZGUsIHJNc2csIGwsIGMxLCBjMiApOwogICAgCXJldHVybiAoc2FsX0Jvb2wpYUNFcnJvckhkbC5DYWxsKCAmYUVycm9yRW50cnkgKTsKCX0KCWVsc2UKCXsKICAgIAlBRERfRVJST1IoIGNvZGUsIHJNc2cgKQogICAgCXJldHVybiBzYWxfVHJ1ZTsKCX0KfQoKdm9pZCBUZXN0VG9vbE9iajo6Q2FsY1Bvc2l0aW9uKCBTdHJpbmcgY29uc3QgJmFTb3VyY2UsIHh1Yl9TdHJMZW4gblBvcywgeHViX1N0ckxlbiAmbCwgeHViX1N0ckxlbiAmYyApCnsKCWwgPSAxOwoJeHViX1N0ckxlbiBuQWt0ID0gMDsKCXh1Yl9TdHJMZW4gbk5leHQ7Cgl3aGlsZSAoIChuTmV4dCA9IGFTb3VyY2UuU2VhcmNoKCAnXG4nLCBuQWt0ICkpICE9IFNUUklOR19OT1RGT1VORCAmJiBuTmV4dCA8IG5Qb3MgKQoJewogICAgCWwrKzsKICAgIAluQWt0ID0gbk5leHQrMTsKCX0KCWMgPSBuUG9zIC0gbkFrdDsKfQoKCiNkZWZpbmUgQ0FUQ0hfTEFCRUwJCQlDVW5pU3RyaW5nKCAiY3RjaCIgKQojZGVmaW5lIENBVENIUkVTX0xBQkVMCQlDVW5pU3RyaW5nKCAiY3RjaHJlcyIgKQojZGVmaW5lIEVORENBVENIX0xBQkVMCQlDVW5pU3RyaW5nKCAiZW5kY3RjaCIgKQoKc2FsX0Jvb2wgSXNBbHBoYUNoYXIoIHNhbF9Vbmljb2RlIGNDaGFyICkKewoJcmV0dXJuCSggY0NoYXIgPj0gJ2EnICYmIGNDaGFyIDw9ICd6JyApIHx8CiAgICAJCSggY0NoYXIgPj0gJ0EnICYmIGNDaGFyIDw9ICdaJyApOwp9CgpzYWxfQm9vbCBJc0luc2lkZVN0cmluZyggY29uc3QgU3RyaW5nJiBhU291cmNlLCBjb25zdCB4dWJfU3RyTGVuIG5TdGFydCApCnsKICAgIHNhbF9Cb29sIGJJbnNpZGUgPSBzYWxfRmFsc2U7CiAgICB4dWJfU3RyTGVuIG5Qb3MgPSBuU3RhcnQtMTsKCgl3aGlsZSAoIG5Qb3MgJiYgYVNvdXJjZS5HZXRDaGFyKG5Qb3MpICE9IF9DUiAmJiBhU291cmNlLkdldENoYXIoblBvcykgIT0gX0xGICkKICAgIHsKICAgICAgICBpZiAoIGFTb3VyY2UuR2V0Q2hhcihuUG9zKSA9PSAnIicgKQogICAgICAgICAgICBiSW5zaWRlID0gIWJJbnNpZGU7CiAgICAJblBvcy0tOwogICAgfQogICAgcmV0dXJuIGJJbnNpZGU7Cn0KCnNhbF9Cb29sIElzVmFsaWRIaXQoIGNvbnN0IFN0cmluZyYgYVNvdXJjZSwgY29uc3QgeHViX1N0ckxlbiBuU3RhcnQsIGNvbnN0IHh1Yl9TdHJMZW4gbkVuZCApCnsKICAgIHJldHVybiAhSXNBbHBoYUNoYXIoIGFTb3VyY2UuR2V0Q2hhcihuU3RhcnQtMSkgKSAmJiAhSXNBbHBoYUNoYXIoIGFTb3VyY2UuR2V0Q2hhcihuRW5kKzEpKQogICAgICAgICYmICFJc0luc2lkZVN0cmluZyggYVNvdXJjZSwgblN0YXJ0ICk7Cn0KCgp4dWJfU3RyTGVuIFRlc3RUb29sT2JqOjpJbXBsU2VhcmNoKCBjb25zdCBTdHJpbmcgJmFTb3VyY2UsIGNvbnN0IHh1Yl9TdHJMZW4gblN0YXJ0LCBjb25zdCB4dWJfU3RyTGVuIG5FbmQsIGNvbnN0IFN0cmluZyAmYVNlYXJjaCwgY29uc3QgeHViX1N0ckxlbiBuU2VhcmNoU3RhcnQgKQp7CiAgICB4dWJfU3RyTGVuIG5Qb3MgPSBhU291cmNlLlNlYXJjaCggYVNlYXJjaCwgc3RkOjptYXgoIG5TZWFyY2hTdGFydCwgblN0YXJ0ICkgKTsKCWlmICggblBvcyA+IG5FbmQgLSBhU2VhcmNoLkxlbigpIHx8IG5Qb3MgPT0gU1RSSU5HX05PVEZPVU5EICkKICAgIAlyZXR1cm4gU1RSSU5HX05PVEZPVU5EOwoJZWxzZQoJewogICAgCWlmICggSXNWYWxpZEhpdCggYVNvdXJjZSwgblBvcywgblBvcythU2VhcmNoLkxlbigpLTEgKSApCiAgICAJCXJldHVybiBuUG9zOwogICAgCWVsc2UKICAgIAkJcmV0dXJuIEltcGxTZWFyY2goIGFTb3VyY2UsIG5TdGFydCwgbkVuZCwgYVNlYXJjaCwgblBvcythU2VhcmNoLkxlbigpICk7Cgl9Cn0KCnh1Yl9TdHJMZW4gVGVzdFRvb2xPYmo6OlByZUNvbXBpbGVQYXJ0KCBTdHJpbmcgJmFTb3VyY2UsIHh1Yl9TdHJMZW4gblN0YXJ0LCB4dWJfU3RyTGVuIG5FbmQsIFN0cmluZyBhRmluYWxFcnJvckxhYmVsLCBzYWxfdUludDE2ICZuTGFiZWxDb3VudCApCnsKCXh1Yl9TdHJMZW4gblRyeSxuQ2F0Y2gsbkVuZGNhdGNoOwoJaWYoIChuVHJ5ID0gSW1wbFNlYXJjaCggYVNvdXJjZSwgblN0YXJ0LCBuRW5kLCBDVW5pU3RyaW5nKCJ0cnkiKSwgblN0YXJ0ICkpID09IFNUUklOR19OT1RGT1VORCApCiAgICAJcmV0dXJuIG5FbmQ7CglpZiAoIChuQ2F0Y2ggPSBJbXBsU2VhcmNoKCBhU291cmNlLCBuU3RhcnQsIG5FbmQsIENVbmlTdHJpbmcoImNhdGNoIiksIG5UcnkgKSkgPT0gU1RSSU5HX05PVEZPVU5EICkKCXsKICAgIAl4dWJfU3RyTGVuIGwsYzsKICAgIAlDYWxjUG9zaXRpb24oIGFTb3VyY2UsIG5UcnksIGwsIGMgKTsKICAgIAlDRXJyb3IoIFNiRVJSX0JBRF9CTE9DSywgQ1VuaVN0cmluZygiY2F0Y2giKSwgbCwgYywgYysyICk7CiAgICAJcmV0dXJuIG5FbmQ7Cgl9CglpZiAoIChuRW5kY2F0Y2ggPSBJbXBsU2VhcmNoKCBhU291cmNlLCBuU3RhcnQsIG5FbmQsIENVbmlTdHJpbmcoImVuZGNhdGNoIiksIG5DYXRjaCApKSA9PSBTVFJJTkdfTk9URk9VTkQgKQoJewogICAgCXh1Yl9TdHJMZW4gbCxjOwogICAgCUNhbGNQb3NpdGlvbiggYVNvdXJjZSwgbkNhdGNoLCBsLCBjICk7CiAgICAJQ0Vycm9yKCBTYkVSUl9CQURfQkxPQ0ssIENVbmlTdHJpbmcoImVuZGNhdGNoIiksIGwsIGMsIGMrNCApOwogICAgCXJldHVybiBuRW5kOwoJfQoKCW5MYWJlbENvdW50Kys7CglTdHJpbmcgYVN0ciA9IFN0cmluZzo6Q3JlYXRlRnJvbUludDMyKCBuTGFiZWxDb3VudCApOwoJU3RyaW5nIGFDYXRjaExhYmVsKENBVENIX0xBQkVMKTsKCWFDYXRjaExhYmVsICs9IGFTdHI7CglTdHJpbmcgYUNhdGNocmVzTGFiZWwoQ0FUQ0hSRVNfTEFCRUwpOwoJYUNhdGNocmVzTGFiZWwgKz0gYVN0cjsKCVN0cmluZyBhRW5kY2F0Y2hMYWJlbCggRU5EQ0FUQ0hfTEFCRUwpOwoJYUVuZGNhdGNoTGFiZWwgKz0gYVN0cjsKCiAgICB4dWJfU3RyTGVuIG5UcnkyID0gMDsKICAgIHdoaWxlICggIVdhc1ByZWNvbXBpbGVyRXJyb3IoKSAmJiAoblRyeTIgPSBJbXBsU2VhcmNoKCBhU291cmNlLCBuU3RhcnQsIG5FbmQsIENVbmlTdHJpbmcoInRyeSIpLCBuVHJ5KzEgKSkgIT0gU1RSSU5HX05PVEZPVU5EICkKCXsJLy8gV2lyIHJla3Vyc2llcmVuIGVyc3RtYWwgbWl0IGRlbSAyLiBUcnkKICAgIAlpZiAoIG5UcnkyIDwgbkNhdGNoICkKICAgIAkJbkVuZCArPSBQcmVDb21waWxlUGFydCggYVNvdXJjZSwgblRyeTIsIG5FbmRjYXRjaCs4LCBhQ2F0Y2hMYWJlbCwgbkxhYmVsQ291bnQgKSAtIG5FbmRjYXRjaC04OwogICAgCWVsc2UKICAgIAkJbkVuZCA9IFByZUNvbXBpbGVQYXJ0KCBhU291cmNlLCBuVHJ5MiwgbkVuZCwgYUZpbmFsRXJyb3JMYWJlbCwgbkxhYmVsQ291bnQgKTsKCiAgICAJaWYgKCAobkNhdGNoID0gSW1wbFNlYXJjaCggYVNvdXJjZSwgblN0YXJ0LCBuRW5kLCBDVW5pU3RyaW5nKCJjYXRjaCIpLCBuVHJ5ICkpID09IFNUUklOR19OT1RGT1VORCApCiAgICAJewogICAgCQl4dWJfU3RyTGVuIGwsYzsKICAgIAkJQ2FsY1Bvc2l0aW9uKCBhU291cmNlLCBuVHJ5LCBsLCBjICk7CiAgICAJCUNFcnJvciggU2JFUlJfQkFEX0JMT0NLLCBDVW5pU3RyaW5nKCJjYXRjaCIpLCBsLCBjLCBjKzIgKTsKICAgIAkJcmV0dXJuIG5FbmQ7CiAgICAJfQogICAgCWlmICggKG5FbmRjYXRjaCA9IEltcGxTZWFyY2goIGFTb3VyY2UsIG5TdGFydCwgbkVuZCwgQ1VuaVN0cmluZygiZW5kY2F0Y2giKSwgbkNhdGNoICkpID09IFNUUklOR19OT1RGT1VORCApCiAgICAJewogICAgCQl4dWJfU3RyTGVuIGwsYzsKICAgIAkJQ2FsY1Bvc2l0aW9uKCBhU291cmNlLCBuQ2F0Y2gsIGwsIGMgKTsKICAgIAkJQ0Vycm9yKCBTYkVSUl9CQURfQkxPQ0ssIENVbmlTdHJpbmcoImVuZGNhdGNoIiksIGwsIGMsIGMrNCApOwogICAgCQlyZXR1cm4gbkVuZDsKICAgIAl9Cgl9CgoJU3RyaW5nIGFSZXBsYWNlbWVudDsKCWludCBuVG90YWxMZW5ndGggPSAtMyAtNSAtODsJLy8gdHJ5LCBjYXRjaCB1bmQgZW5kY2F0Y2ggZmFsbGVuIHJhdXMKCglhUmVwbGFjZW1lbnQuQXBwZW5kQXNjaWkoICJvbiBlcnJvciBnb3RvICIgKTsKCWFSZXBsYWNlbWVudCArPSBhQ2F0Y2hMYWJlbDsKCWFTb3VyY2UuU2VhcmNoQW5kUmVwbGFjZUFzY2lpKCAidHJ5IiwgYVJlcGxhY2VtZW50LCBuVHJ5ICk7CgluVG90YWxMZW5ndGggKz0gYVJlcGxhY2VtZW50LkxlbigpOwoKCi8vCQkJb24gZXJyb3IgZ290byBlbmRjc2UKLy8JCQlnb3RvIGVuZGN0Y2hYWAovLwkJCWN0Y2hYWDoKLy8JCQlpZiBlcnIgPSAzNSBvciBlcnIgPSAxOCB0aGVuIDogcmVzdW1lIDogZW5kaWYgOgovLwkJCU1heWJlQWRkRXJyCi8vCQkJb24gZXJyb3IgZ290byBlbmRjc2UKLy8JCQlyZXN1bWUgY3RjaHJlc1hYCi8vCQkJY3RjaHJlc1hYOgoJYVJlcGxhY2VtZW50LkVyYXNlKCk7CglhUmVwbGFjZW1lbnQuQXBwZW5kQXNjaWkoICJvbiBlcnJvciBnb3RvICIgKTsKCWFSZXBsYWNlbWVudCArPSBhRmluYWxFcnJvckxhYmVsOwoJYVJlcGxhY2VtZW50LkFwcGVuZEFzY2lpKCAiIDogZ290byAiICk7CglhUmVwbGFjZW1lbnQgKz0gYUVuZGNhdGNoTGFiZWw7CglhUmVwbGFjZW1lbnQuQXBwZW5kQXNjaWkoICIgOiAiICk7CglhUmVwbGFjZW1lbnQgKz0gYUNhdGNoTGFiZWw7CglhUmVwbGFjZW1lbnQuQXBwZW5kQXNjaWkoICI6IGlmIGVyciA9IDM1IG9yIGVyciA9IDE4IHRoZW4gOiBvbiBlcnJvciBnb3RvIDAgOiByZXN1bWUgOiBlbmRpZiIgKTsKCWFSZXBsYWNlbWVudC5BcHBlbmRBc2NpaSggIiA6IE1heWJlQWRkRXJyIDogb24gZXJyb3IgZ290byAiICk7CglhUmVwbGFjZW1lbnQgKz0gYUZpbmFsRXJyb3JMYWJlbDsKCWFSZXBsYWNlbWVudC5BcHBlbmRBc2NpaSggIiA6IHJlc3VtZSAiICk7CglhUmVwbGFjZW1lbnQgKz0gYUNhdGNocmVzTGFiZWw7CglhUmVwbGFjZW1lbnQuQXBwZW5kQXNjaWkoICIgOiAiICk7CglhUmVwbGFjZW1lbnQgKz0gYUNhdGNocmVzTGFiZWw7CglhUmVwbGFjZW1lbnQuQXBwZW5kQXNjaWkoICI6ICIgKTsKCWFTb3VyY2UuU2VhcmNoQW5kUmVwbGFjZUFzY2lpKCAiY2F0Y2giLCBhUmVwbGFjZW1lbnQsIG5DYXRjaCApOwoJblRvdGFsTGVuZ3RoICs9IGFSZXBsYWNlbWVudC5MZW4oKTsKCgoJYVJlcGxhY2VtZW50LkVyYXNlKCk7CglhUmVwbGFjZW1lbnQuQXBwZW5kQXNjaWkoIkNsZWFyRXJyb3IgOiAiKTsKCWFSZXBsYWNlbWVudCArPSBhRW5kY2F0Y2hMYWJlbDsKCWFSZXBsYWNlbWVudC5BcHBlbmRBc2NpaSgiOiAiKTsKCWFTb3VyY2UuU2VhcmNoQW5kUmVwbGFjZUFzY2lpKCAiZW5kY2F0Y2giLCBhUmVwbGFjZW1lbnQsIG5FbmRjYXRjaCApOwoJblRvdGFsTGVuZ3RoICs9IGFSZXBsYWNlbWVudC5MZW4oKTsKCglpZiAoIGFTb3VyY2UuTGVuKCkgPj0gU1RSSU5HX01BWExFTiApCgl7CiAgICAJeHViX1N0ckxlbiBsLGM7CiAgICAJQ2FsY1Bvc2l0aW9uKCBhU291cmNlLCBuRW5kY2F0Y2gsIGwsIGMgKTsKICAgIAlDRXJyb3IoIFNiRVJSX1BST0dfVE9PX0xBUkdFLCBDVW5pU3RyaW5nKCJlbmRjYXRjaCIpLCBsLCBjLCBjKzIgKTsKCX0KCglyZXR1cm4geHViX1N0ckxlbiggbkVuZCArIG5Ub3RhbExlbmd0aCApOwp9CgoKdm9pZCBUZXN0VG9vbE9iajo6UHJlQ29tcGlsZURpc3BhdGNoUGFydHMoIFN0cmluZyAmYVNvdXJjZSwgU3RyaW5nIGFTdGFydCwgU3RyaW5nIGFFbmQsIFN0cmluZyBhRmluYWxMYWJsZSApCnsKCXNhbF91SW50MTYgbkxhYmVsQ291bnQgPSAwOwoJeHViX1N0ckxlbiBuUGFydFBvcyA9IDA7CgoJd2hpbGUgKCAhV2FzUHJlY29tcGlsZXJFcnJvcigpICYmIChuUGFydFBvcyA9IEltcGxTZWFyY2goIGFTb3VyY2UsIG5QYXJ0UG9zLCBhU291cmNlLkxlbigpLCBhU3RhcnQgKSkgIT0gU1RSSU5HX05PVEZPVU5EICkKCXsKICAgIAl4dWJfU3RyTGVuIG5FbmRQYXJ0ID0gSW1wbFNlYXJjaCggYVNvdXJjZSwgblBhcnRQb3MsIGFTb3VyY2UuTGVuKCksIGFFbmQgKTsKICAgIAlpZiAoIG5FbmRQYXJ0ID09IFNUUklOR19OT1RGT1VORCApCiAgICAJCXJldHVybjsKICAgIAluUGFydFBvcyA9IFByZUNvbXBpbGVQYXJ0KCBhU291cmNlLCBuUGFydFBvcywgbkVuZFBhcnQsIGFGaW5hbExhYmxlLCBuTGFiZWxDb3VudCApOwogICAgCW5QYXJ0UG9zID0gblBhcnRQb3MgKyBhRW5kLkxlbigpOwoJfQp9CgoKc2FsX0Jvb2wgVGVzdFRvb2xPYmo6Oldhc1ByZWNvbXBpbGVyRXJyb3IoKQp7CglyZXR1cm4gYldhc1ByZWNvbXBpbGVyRXJyb3I7Cn0KClN0cmluZyBUZXN0VG9vbE9iajo6UHJlQ29tcGlsZSggU3RyaW5nIGNvbnN0ICZhU291cmNlSW4gKQp7CgkvLyBJbSBDVE9SIHp1IGZy77+9aCwgdW5kIGhpZXIgZ3JhZGUgbmljZyByZWNodHplaXRpZy4gU3RhcnQgdW5kIFN0b3Agdm9uIFByb2dyYW1tYXVzZu+/vWhydW5nCglTdGFydExpc3RlbmluZyggKChTdGFyQkFTSUMqKUdldFBhcmVudCgpKS0+R2V0QnJvYWRjYXN0ZXIoKSwgc2FsX1RydWUgKTsKCgl4dWJfU3RyTGVuIG5UZXN0Q2FzZTsKCXh1Yl9TdHJMZW4gbkVuZENhc2U7Cgl4dWJfU3RyTGVuIG5TdGFydFBvcyA9IDA7CglTdHJpbmcgYVNvdXJjZShhU291cmNlSW4pOwoJYldhc1ByZWNvbXBpbGVyRXJyb3IgPSBzYWxfRmFsc2U7CgpIQUNLKCJJY2ggZ2VzdGVoZSBhbGxlczogSWNoIHdhciB6dSBmYXVsIGRhcyByaWNodGlnIHp1IG1hY2hlbi4iKQoJYVNvdXJjZSA9IFN0cmluZygnICcpLkFwcGVuZCggYVNvdXJjZSApOyAgICAgICAgLy8gRGEgU2NobO+/vXNzZWx3b3J0ZSBhbiBQb3NpdGlvbiAwIHNvbnN0IG5pY2h0IGdlZnVuZGVuIHdlcmRlbgoKCi8vICAgICAgRXJzdG1hbCBhbGxlICInIiBLb21tZW50YXJlIHJhdXMKCgl4dWJfU3RyTGVuIG5Db21tZW50OwoJd2hpbGUgKCAobkNvbW1lbnQgPSBhU291cmNlLlNlYXJjaEFzY2lpKCInIixuU3RhcnRQb3MpKSAhPSBTVFJJTkdfTk9URk9VTkQgKQoJewogICAgCXNhbF91SW50MTYgblN0cmluZ0VuZENvdW50ID0gMDsKICAgIAl4dWJfU3RyTGVuIG5JbmRleCA9IG5Db21tZW50OwogICAgCXdoaWxlICggbkluZGV4ICYmIGFTb3VyY2UuR2V0Q2hhcihuSW5kZXgpICE9ICdcbicgKQogICAgCXsKICAgIAkJaWYgKCBhU291cmNlLkdldENoYXIobkluZGV4KSA9PSAnIicgKQogICAgCQkJblN0cmluZ0VuZENvdW50Kys7CiAgICAJCW5JbmRleC0tOwogICAgCX0KICAgIAlpZiAoIChuU3RyaW5nRW5kQ291bnQgJiAxKSA9PSAwICkgICAgICAgLy8gV2lyIHdhcmVuIGFsc28gbmljaHQgaW5uZXJoYWxiIGVpbmVzIFN0cmluZ3MKICAgIAl7CiAgICAJCXh1Yl9TdHJMZW4gbkNvbUVuZCA9IGFTb3VyY2UuU2VhcmNoQXNjaWkoIlxuIixuQ29tbWVudCk7CgogICAgCQl3aGlsZSAoIGFTb3VyY2UuR2V0Q2hhcihuQ29tRW5kKSA9PSBfQ1IgfHwgYVNvdXJjZS5HZXRDaGFyKG5Db21FbmQpID09IF9MRiApCiAgICAJCQluQ29tRW5kLS07CgogICAgCQluQ29tRW5kKys7CgogICAgCQlhU291cmNlLkVyYXNlKG5Db21tZW50LG5Db21FbmQtbkNvbW1lbnQpOwogICAgCX0KICAgIAllbHNlCiAgICAJCW5Db21tZW50Kys7CiAgICAJblN0YXJ0UG9zID0gbkNvbW1lbnQ7Cgl9CgoKCVByZUNvbXBpbGVEaXNwYXRjaFBhcnRzKCBhU291cmNlLCBDVW5pU3RyaW5nKCJzdWIiKSwgQ1VuaVN0cmluZygiZW5kIHN1YiIpLCBDVW5pU3RyaW5nKCIwIikgKTsKCVByZUNvbXBpbGVEaXNwYXRjaFBhcnRzKCBhU291cmNlLCBDVW5pU3RyaW5nKCJmdW5jdGlvbiIpLCBDVW5pU3RyaW5nKCJlbmQgZnVuY3Rpb24iKSwgQ1VuaVN0cmluZygiMCIpICk7CglQcmVDb21waWxlRGlzcGF0Y2hQYXJ0cyggYVNvdXJjZSwgQ1VuaVN0cmluZygidGVzdGNhc2UiKSwgQ1VuaVN0cmluZygiZW5kY2FzZSIpLCBDVW5pU3RyaW5nKCJlbmRjc2UiKSApOwoKCgl4dWJfU3RyTGVuIG5NYWluUG9zID0gSW1wbFNlYXJjaCggYVNvdXJjZSwgMCwgYVNvdXJjZS5MZW4oKSwgQ1VuaVN0cmluZygic3ViIG1haW4iKSApOwoJYVNvdXJjZS5TZWFyY2hBbmRSZXBsYWNlQXNjaWkoInN1YiBtYWluIixDVW5pU3RyaW5nKCJTdWIgTWFpbiBTdGFydFVzZSA6IExvYWRJbmNsdWRlRmlsZXMgOiBGaW5pc2hVc2UgIiksIG5NYWluUG9zICk7CglpZiAoIGFTb3VyY2UuTGVuKCkgPj0gU1RSSU5HX01BWExFTiApCgl7CiAgICAJeHViX1N0ckxlbiBsLGM7CiAgICAJQ2FsY1Bvc2l0aW9uKCBhU291cmNlLCBuTWFpblBvcywgbCwgYyApOwogICAgCUNFcnJvciggU2JFUlJfUFJPR19UT09fTEFSR0UsIENVbmlTdHJpbmcoImVuZGNhdGNoIiksIGwsIGMsIGMrMiApOwoJfQoKCXdoaWxlICggKG5UZXN0Q2FzZSA9IEltcGxTZWFyY2goIGFTb3VyY2UsIDAsIGFTb3VyY2UuTGVuKCksIENVbmlTdHJpbmcoInRlc3RjYXNlIikgKSApICE9IFNUUklOR19OT1RGT1VORCApCgl7CiAgICAJeHViX1N0ckxlbiBuVGNFbmQgPSBhU291cmNlLlNlYXJjaEFzY2lpKCJcbiIsblRlc3RDYXNlKTsKCgkgICAgd2hpbGUgKCBhU291cmNlLkdldENoYXIoblRjRW5kKSA9PSBfQ1IgfHwgYVNvdXJjZS5HZXRDaGFyKG5UY0VuZCkgPT0gX0xGICkKICAgIAkgICAgblRjRW5kLS07CgoJICAgIG5UY0VuZCsrOwoKICAgIAlpZiAoIGFTb3VyY2UuU2VhcmNoQXNjaWkoIjoiLG5UZXN0Q2FzZSkgPCBuVGNFbmQgKQogICAgCQluVGNFbmQgPSBhU291cmNlLlNlYXJjaEFzY2lpKCI6IixuVGVzdENhc2UpIC0xOwogICAgCVN0cmluZyBhU3VmZml4ID0gYVNvdXJjZS5Db3B5KG5UZXN0Q2FzZSs4LG5UY0VuZC1uVGVzdENhc2UtOCk7CiAgICAgICAgc2FsX3VJbnQxNiBuT2xkTGVuOwogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBuT2xkTGVuID0gYVN1ZmZpeC5MZW4oKTsKICAgICAgICAgICAgYVN1ZmZpeC5FcmFzZUxlYWRpbmdBbmRUcmFpbGluZ0NoYXJzKCAnICcgKTsKICAgICAgICAgICAgYVN1ZmZpeC5FcmFzZUxlYWRpbmdBbmRUcmFpbGluZ0NoYXJzKCAweDA5ICk7CiAgICAgICAgfSB3aGlsZSAoIG5PbGRMZW4gIT0gYVN1ZmZpeC5MZW4oKSApOwogICAgCWFTb3VyY2UuRXJhc2UoblRlc3RDYXNlLG5UY0VuZC1uVGVzdENhc2UpOwogICAgCWFTb3VyY2UuSW5zZXJ0KENVbmlTdHJpbmcoIlN1YiAiKS5BcHBlbmQoYVN1ZmZpeCkuQXBwZW5kQXNjaWkoIiBDYXNlTG9nIFwiIikuQXBwZW5kKGFTdWZmaXgpLkFwcGVuZEFzY2lpKCJcIiA6IG9uIGVycm9yIGdvdG8gZW5kY3NlIDogVGVzdEVudGVyICIpLG5UZXN0Q2FzZSk7Cgl9CgogICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAvLyBBdHRlbnRpb24hISEgVGhlIGxhYmxlIGVuZHN1YiBpcyBvZmZpY2lhbGx5IHVzZWQgdG8gZXhpdCBhIHN1YiBpbnN0ZWFkIG9mIHVzaW5nICdleGl0IHN1Yicgb3IgJ3JldHVybicKICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgd2hpbGUgKCAobkVuZENhc2UgPSBJbXBsU2VhcmNoKCBhU291cmNlLCAwLCBhU291cmNlLkxlbigpLCBDVW5pU3RyaW5nKCJlbmRjYXNlIikgKSApICE9IFNUUklOR19OT1RGT1VORCApCiAgICAJYVNvdXJjZS5TZWFyY2hBbmRSZXBsYWNlQXNjaWkoImVuZGNhc2UiLENVbmlTdHJpbmcoImdvdG8gZW5kc3ViIDogZW5kY3NlOiBpZiAoIGVyciA9IDM1IGFuZCBTdG9wT25TeW50YXhFcnJvciApIG9yIGVyciA9IDE4IHRoZW4gOiBvbiBlcnJvciBnb3RvIDAgOiByZXN1bWUgOiBlbmRpZiA6IE1heWJlQWRkRXJyIDogRXhjZXB0TG9nIDogcmVzdW1lIGVuZGNzZV9yZXMgOiBlbmRjc2VfcmVzOiBvbiBlcnJvciBnb3RvIDAgOiBlbmRzdWI6IFRlc3RFeGl0IDogQ2xlYXJFcnJvciA6IENhc2VMb2cgXCJcIiA6IGVuZCBzdWIgIiksIG5FbmRDYXNlICk7CgogICAgaWYgKCBhU291cmNlLkxlbigpID49IFNUUklOR19NQVhMRU4gKQoJewogICAgCXh1Yl9TdHJMZW4gbCxjOwogICAgCUNhbGNQb3NpdGlvbiggYVNvdXJjZSwgMCwgbCwgYyApOwogICAgCUNFcnJvciggU2JFUlJfUFJPR19UT09fTEFSR0UsIENVbmlTdHJpbmcoImVuZGNhdGNoIiksIGwsIGMsIGMrMiApOwoJfQoJcmV0dXJuIGFTb3VyY2U7Cn0KCnZvaWQgVGVzdFRvb2xPYmo6OkFkZFRvTGlzdEJ5TnIoIENOYW1lcyAqJnBDb250cm9scywgQ29udHJvbEl0ZW1VSWQgKiZwTmV3SXRlbSApCnsKCXNhbF91SW50MTYgbk5yOwoJaWYgKCBwQ29udHJvbHMtPlNlZWtfRW50cnkoIHBOZXdJdGVtLCAmbk5yICkgKQoJewogICAgCUFkZE5hbWUoIHBDb250cm9scy0+R2V0T2JqZWN0KG5OciktPnBEYXRhLT5LdXJ6bmFtZSwgcE5ld0l0ZW0tPnBEYXRhLT5LdXJ6bmFtZSApOwogICAgCWRlbGV0ZSBwTmV3SXRlbTsKICAgIAlwTmV3SXRlbSA9IChDb250cm9sSXRlbVVJZCopcENvbnRyb2xzLT5HZXRPYmplY3Qobk5yKTsgIC8vIGbvv71yIGVpbmbvv71nZW4gZGVyIFPvv71obmUKCX0KCWVsc2UKCXsKICAgIAlDb250cm9sSXRlbSogcE5JID0gcE5ld0l0ZW07CiAgICAJcENvbnRyb2xzLT5DNDBfUFRSX0lOU0VSVChDb250cm9sSXRlbSxwTkkpOwoJfQp9CgpJTVBMX0xJTksoIFRlc3RUb29sT2JqLCBSZXR1cm5SZXN1bHRzTGluaywgQ29tbXVuaWNhdGlvbkxpbmsqLCBwQ29tbUxpbmsgKQp7CglyZXR1cm4gUmV0dXJuUmVzdWx0cyggcENvbW1MaW5rLT5HZXRTZXJ2aWNlRGF0YSgpICk7Cn0KCnZvaWQgVGVzdFRvb2xPYmo6OlJlYWRIaWRMc3RCeU51bWJlcigpCnsKICAgIC8vIERpZSBIaWQuTHN0IG5hY2ggTnVtbWVybiBzb3J0aWVydCBlaW5sZXNlbgogICAgaWYgKCAhbV9wUmV2ZXJzZVVJZHMgKQogICAgewogICAgCVN0cmluZyBhTmFtZSA9IChwSW1wbC0+YUhJRERpciArIERpckVudHJ5KENVbmlTdHJpbmcoImhpZC5sc3QiKSkpLkdldEZ1bGwoKTsKCiAgICAgICAgewogICAgCSAgICBUVEV4ZWN1dGlvblN0YXR1c0hpbnQgYUhpbnQoIFRUX0VYRUNVVElPTl9TSE9XX0FDVElPTiwgU3RyaW5nKFN0dFJlc0lkKFNfUkVBRElOR19MT05HTkFNRVMpKSwgYU5hbWUgKTsKICAgIAkgICAgR2V0VFRCcm9hZGNhc3RlcigpLkJyb2FkY2FzdCggYUhpbnQgKTsKICAgICAgICB9CgogICAgCVJlYWRGbGF0KCBhTmFtZSwgbV9wUmV2ZXJzZVVJZHMsIHNhbF9GYWxzZSApOwoKICAgICAgICB7CiAgICAJICAgIFRURXhlY3V0aW9uU3RhdHVzSGludCBhSGludCggVFRfRVhFQ1VUSU9OX0hJREVfQUNUSU9OICk7CiAgICAJICAgIEdldFRUQnJvYWRjYXN0ZXIoKS5Ccm9hZGNhc3QoIGFIaW50ICk7CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIFRlc3RUb29sT2JqOjpTb3J0Q29udHJvbHNCeU51bWJlciggc2FsX0Jvb2wgYkluY2x1ZGVBY3RpdmUgKQp7CiAgICAvLyBEaWUgQ29udHJvbHMgZWlubWFsIGhpcmFyY2hpc2NoIHVuZCBlaW5tYWwgYWxsZSBmbGFjaCBuYWNoIG51bW1lciBzb3J0aWVydAogICAgaWYgKCAhbV9wUmV2ZXJzZUNvbnRyb2xzICYmICFtX3BSZXZlcnNlQ29udHJvbHNTb24gJiYgbV9wQ29udHJvbHMgKQogICAgewogICAgCW1fcFJldmVyc2VDb250cm9scyA9IG5ldyBDTmFtZXM7CiAgICAJbV9wUmV2ZXJzZUNvbnRyb2xzU29uID0gbmV3IENOYW1lczsKICAgIAlzYWxfdUludDE2IG5XaW4sbkNvbnQ7CiAgICAJY29uc3QgU3RyaW5nIGFTbCgnLycpOwogICAgCWZvciAoIG5XaW4gPSAwIDsgbldpbiA8IG1fcENvbnRyb2xzLT5Db3VudCgpIDsgbldpbisrICkKICAgIAl7CiAgICAgICAgICAgIFN0cmluZyBhRmF0aGVyTmFtZSggbV9wQ29udHJvbHMtPkdldE9iamVjdChuV2luKS0+cERhdGEtPkt1cnpuYW1lICk7CiAgICAJCUNvbnRyb2xJdGVtVUlkICpwTmV3RmF0aGVyID0gbmV3IENvbnRyb2xJdGVtVUlkU29uKGFGYXRoZXJOYW1lLG1fcENvbnRyb2xzLT5HZXRPYmplY3QobldpbiktPnBEYXRhLT5hVUlkKTsKICAgIAkJQWRkVG9MaXN0QnlOciggbV9wUmV2ZXJzZUNvbnRyb2xzU29uLCBwTmV3RmF0aGVyICk7CiAgICAJCWlmICghICgoQ29udHJvbEl0ZW1VSWRTb24qKXBOZXdGYXRoZXIpLT5HZXRTb25zKCkgKQogICAgCQkJKChDb250cm9sSXRlbVVJZFNvbiopcE5ld0ZhdGhlciktPlNvbnMoIG5ldyBDTmFtZXMgKTsKCiAgICAJCS8vIEV4aXN0aWVyZW4gU++/vWhuZSwgZGllc2UgaW4gYmVpZGUgTGlzdGVuIGVpbnRyYWdlbgogICAgCQlDTmFtZXMgKnBDb250cm9sTGlzdCA9ICgoQ29udHJvbEl0ZW1Tb24qKW1fcENvbnRyb2xzLT5HZXRPYmplY3QobldpbikpLT5HZXRTb25zKCk7CiAgICAJCWlmICggcENvbnRyb2xMaXN0ICkKICAgIAkJCWZvciAoIG5Db250ID0gMCA7IG5Db250IDwgcENvbnRyb2xMaXN0LT5Db3VudCgpIDsgbkNvbnQrKyApCiAgICAJCQl7CiAgICAJCQkJQ29udHJvbEl0ZW1VSWQgKnBOZXdJdGVtOwoKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYUNvbWJpbmVkTmFtZSggYUZhdGhlck5hbWUgKTsKICAgICAgICAgICAgICAgICAgICBhQ29tYmluZWROYW1lLkFwcGVuZEFzY2lpKCAiOiIgKTsKICAgICAgICAgICAgICAgICAgICBhQ29tYmluZWROYW1lLkFwcGVuZCggcENvbnRyb2xMaXN0LT5HZXRPYmplY3QobkNvbnQpLT5wRGF0YS0+S3Vyem5hbWUgKTsKICAgICAgICAgICAgICAgICAgICBwTmV3SXRlbSA9IG5ldyBDb250cm9sSXRlbVVJZCggYUNvbWJpbmVkTmFtZSwgcENvbnRyb2xMaXN0LT5HZXRPYmplY3QobkNvbnQpLT5wRGF0YS0+YVVJZCApOwogICAgCQkJCUFkZFRvTGlzdEJ5TnIoIG1fcFJldmVyc2VDb250cm9scywgcE5ld0l0ZW0gKTsKCiAgICAJCQkJcE5ld0l0ZW0gPSBuZXcgQ29udHJvbEl0ZW1VSWQoIHBDb250cm9sTGlzdC0+R2V0T2JqZWN0KG5Db250KS0+cERhdGEtPkt1cnpuYW1lLCBwQ29udHJvbExpc3QtPkdldE9iamVjdChuQ29udCktPnBEYXRhLT5hVUlkICk7CiAgICAJCQkJQWRkVG9MaXN0QnlOciggKChDb250cm9sSXRlbVVJZFNvbiopcE5ld0ZhdGhlciktPkdldFNvbnMoKSwgcE5ld0l0ZW0gKTsKICAgIAkJCX0KICAgIAl9CiAgICAgICAgaWYgKCAhYkluY2x1ZGVBY3RpdmUgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gRklYTUU6IEhFTFBJRAogICAgCSAgICBDb250cm9sSXRlbSAqcFplcm9JdGVtID0gbmV3IENvbnRyb2xJdGVtVUlkKCBVbmlTdHJpbmcoKSwgcnRsOjpPU3RyaW5nKCkgKTsKICAgIAkgICAgc2FsX3VJbnQxNiBuTnI7CiAgICAJICAgIGlmICggbV9wUmV2ZXJzZUNvbnRyb2xzLT5TZWVrX0VudHJ5KCBwWmVyb0l0ZW0sICZuTnIgKSApCiAgICAJICAgIHsKICAgIAkJICAgIG1fcFJldmVyc2VDb250cm9scy0+RGVsZXRlQW5kRGVzdHJveSggbk5yICk7Ci8vIHVtIFZvcmxhZ2VuTGFkZW4vVW50ZXJnZW9yZG5ldGVJbmlEYXRlaS9TcGVpY2hlcm5EbGcvT3JkbmVyRGxnL09lZmZuZW5EbGcvTWVzc2FnZUJveC9MZXR6dGVWZXJzaW9uL0dyYWZpa0VpbmZ1ZWdlbkRsZy9GYXJiZURsZy9FeHBvcnRpZXJlbkRsZy9EcnVja2VyRWlucmljaHRlbi9EcnVja2VuRGxnL0RhdGVpRWluZnVlZ2VuRGxnL0FjdGl2ZSB6dSB2ZXJoaW5kZXJuCiAgICAJICAgIH0KLyogICAgCSAgICBpZiAoIG1fcFJldmVyc2VDb250cm9sc1Nvbi0+U2Vla19FbnRyeSggcFplcm9JdGVtLCAmbk5yICkgKQogICAgCSAgICB7CiAgICAJCSAgICBtX3BSZXZlcnNlQ29udHJvbHNTb24tPkRlbGV0ZUFuZERlc3Ryb3koIG5OciApOwovLyB1bSBWb3JsYWdlbkxhZGVuL1VudGVyZ2VvcmRuZXRlSW5pRGF0ZWkvU3BlaWNoZXJuRGxnL09yZG5lckRsZy9PZWZmbmVuRGxnL01lc3NhZ2VCb3gvTGV0enRlVmVyc2lvbi9HcmFmaWtFaW5mdWVnZW5EbGcvRmFyYmVEbGcvRXhwb3J0aWVyZW5EbGcvRHJ1Y2tlckVpbnJpY2h0ZW4vRHJ1Y2tlbkRsZy9EYXRlaUVpbmZ1ZWdlbkRsZy9BY3RpdmUgenUgdmVyaGluZGVybgogICAgCSAgICB9Ki8KICAgIAkgICAgZGVsZXRlIHBaZXJvSXRlbTsKICAgICAgICB9CiAgICB9Cn0KCgpzYWxfQm9vbCBUZXN0VG9vbE9iajo6UmV0dXJuUmVzdWx0cyggU3ZTdHJlYW0gKnBJbiApCnsKCglzYWxfdUludDE2IG5JZDsKCXNhbF91TG9uZyBuQ2xlYXJTZXF1ZW5jZSA9IDA7CglzYWxfQm9vbCBiU2VxdWVuY2VPSyA9IHNhbF9UcnVlOwoJQ05hbWVzICpwUmV2ZXJzZUNvbnRyb2xzS29udGV4dCA9IE5VTEw7CgoJQ1JldFN0cmVhbSAqcFJldFN0cmVhbSA9IG5ldyBDUmV0U3RyZWFtKHBJbik7CgoJcFJldFN0cmVhbS0+UmVhZCggbklkICk7Cgl3aGlsZSggIXBJbi0+SXNFb2YoKSApCgl7Cglzd2l0Y2goIG5JZCApCgl7CiAgICAJY2FzZSBTSVJldHVybjoKICAgIAl7CiAgICAJCXNhbF91SW50MTYgblJldCxuUGFyYW1zOwogICAgCQlydGw6Ok9TdHJpbmcgYVVJZDsKICAgIAkJcFJldFN0cmVhbS0+UmVhZChuUmV0KTsKICAgICAgICAgICAgaWYgKCBwUmV0U3RyZWFtLT5HZXROZXh0VHlwZSgpID09IEJpblN0cmluZyApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFN0cmluZyBhVVN0cklkOyAgICAgLy8gVW5pcXVlU3RyaW5nSUQgVXNlZCBmb3IgTW96aWxsYSBJbnRlZ3JhdGlvbgogICAgICAgICAgICAgICAgcFJldFN0cmVhbS0+UmVhZCggYVVTdHJJZCApOwogICAgICAgICAgICAgICAgLy8gRklYTUU6IEhFTFBJRAogICAgICAgICAgICAgICAgI2lmIDAKICAgICAgICAgICAgICAgIGFVSWQgPSBydGw6Ok9TdHJpbmcoIGFVU3RySWQgKTsKICAgICAgICAgICAgICAgICNlbmRpZgogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgIAkJY29tbV9VTE9ORyBuVUlkOwogICAgCQkgICAgcFJldFN0cmVhbS0+UmVhZCggblVJZCApOyAgICAgICAgIC8vIGJlaSBTZXF1ZW5jZSBlaW5mYWNoIGRpZSBTZXF1ZW5jZQogICAgCQkgICAgLy8gRklYTUU6IEhFTFBJRAogICAgCQkgICAgI2lmIDAKICAgICAgICAgICAgICAgIGFVSWQgPSBydGw6Ok9TdHJpbmcoIG5VSWQgKTsKICAgICAgICAgICAgICAgICNlbmRpZgogICAgICAgICAgICB9CiAgICAJCXBSZXRTdHJlYW0tPlJlYWQoblBhcmFtcyk7CgogICAgCQlzYWxfdUludDE2IG5OcjEgPSAwOwogICAgCQljb21tX1VMT05HIG5MTnIxID0gMDsKICAgIAkJU3RyaW5nIGFTdHJpbmcxOwogICAgCQlzYWxfQm9vbCBiQm9vbDEgPSBzYWxfRmFsc2U7CiAgICAJCVNieFZhbHVlUmVmIHhWYWx1ZTEgPSBuZXcgU2J4VmFsdWU7CgogICAgCQlpZiggblBhcmFtcyAmIFBBUkFNX1VTSE9SVF8xICkKICAgIAkJCXBSZXRTdHJlYW0tPlJlYWQoIG5OcjEgKTsKICAgIAkJaWYoIG5QYXJhbXMgJiBQQVJBTV9VTE9OR18xICkKICAgIAkJCXBSZXRTdHJlYW0tPlJlYWQoIG5MTnIxICk7CiAgICAJCWlmKCBuUGFyYW1zICYgUEFSQU1fU1RSXzEgKQogICAgCQl7CiAgICAJCQlwUmV0U3RyZWFtLT5SZWFkKCBhU3RyaW5nMSApOwogICAgCQkJUmVwbGFjZU51bWJlcnMgKCBhU3RyaW5nMSApOwogICAgCQl9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGFTdHJpbmcxLkVyYXNlKCk7CiAgICAJCWlmKCBuUGFyYW1zICYgUEFSQU1fQk9PTF8xICkKICAgIAkJCXBSZXRTdHJlYW0tPlJlYWQoIGJCb29sMSApOwogICAgCQlpZiggblBhcmFtcyAmIFBBUkFNX1NCWFZBTFVFXzEgKQogICAgCQkJcFJldFN0cmVhbS0+UmVhZCggKnhWYWx1ZTEgKTsKICAgIAkJc3dpdGNoIChuUmV0KQogICAgCQl7CiAgICAJCQljYXNlIFJFVF9TZXF1ZW5jZToKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBIRUxQSUQKICAgICAgICAgICAgICAgICAgICAgICAgI2lmIDAKICAgICAgICAgICAgICAgICAgICAgICAgc2FsX3VMb25nIG5VSWQgPSBhVUlkLkdldE51bSgpOwogICAgCQkJCSAgICBpZiAoIG5TZXF1ZW5jZSAhPSBuVUlkICkKICAgIAkJCQkgICAgewogICAgCQkJCQkgICAgYlNlcXVlbmNlT0sgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRERfRVJST1IoU2J4RVJSX0JBRF9BQ1RJT04sIEdFTl9SRVNfU1RSMihTX1JFVFVSTl9TRVFVRU5DRV9NSVNTTUFUQ0gsIFN0cmluZzo6Q3JlYXRlRnJvbUludDY0KG5VSWQpLCBTdHJpbmc6OkNyZWF0ZUZyb21JbnQ2NChuU2VxdWVuY2UpKSApOwogICAgCQkJCSAgICB9CiAgICAJCQkJICAgIGVsc2UKICAgIAkJCQkgICAgewogICAgCQkJCQkgICAgbkNsZWFyU2VxdWVuY2UgPSBuVUlkOwogICAgCQkJCSAgICB9CiAgICAJCQkJICAgICNlbmRpZgogICAgICAgICAgICAgICAgICAgIH0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgUkVUX1ZhbHVlOgogICAgCQkJCWlmICggcEltcGwtPnBOZXh0UmV0dXJuICkKICAgIAkJCQl7Ci8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbF91TG9uZyBuSGludFVzZXJEYXRhID0gcEltcGwtPnBOZXh0UmV0dXJuLT5HZXRQYXJlbnQoKS0+R2V0VXNlckRhdGEoKTsKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEltcGwtPnBOZXh0UmV0dXJuLT5HZXRQYXJlbnQoKS0+U2V0VXNlckRhdGEoMCk7Ci8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggblVJZCA9PSBwSW1wbC0+cE5leHRSZXR1cm4tPkdldFBhcmVudCgpLT5HZXRVTG9uZygpICkKICAgIAkJCQkJaWYgKCBhTmV4dFJldHVybklkLmVxdWFscyggYVVJZCApICkKICAgIAkJCQkJewogICAgCQkJCQkJaWYoIG5QYXJhbXMgJiBQQVJBTV9VTE9OR18xICkgICAvLyBGSVhNRSB0aGlzIGlzIHRvIGFsbG93IG5lZ2F0aXZlIG51bWJlcnMsIGhvcGluZyB0aGF0IG5vIGxhcmdlIG51bWJlcnMgYXJlIGludGVycHJldGVkIHdyb25nLiBzaG91bGQgaGF2ZSBuZXcgUEFSQU1fTE9OR18xIGluc3RlYWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIG5MTnIxID4gMHg3ZmZmZmZmZiApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5wTmV4dFJldHVybi0+UHV0TG9uZyggbG9uZyhuTE5yMSAtIDB4ZmZmZmZmZmYpIC0xICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW1wbC0+cE5leHRSZXR1cm4tPlB1dFVMb25nKCBuTE5yMSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgCQkJCQkJaWYoIG5QYXJhbXMgJiBQQVJBTV9VU0hPUlRfMSApCQlwSW1wbC0+cE5leHRSZXR1cm4tPlB1dFVTaG9ydCggbk5yMSApOwogICAgCQkJCQkJaWYoIG5QYXJhbXMgJiBQQVJBTV9TVFJfMSApCQkJcEltcGwtPnBOZXh0UmV0dXJuLT5QdXRTdHJpbmcoIGFTdHJpbmcxICk7CiAgICAJCQkJCQlpZiggblBhcmFtcyAmIFBBUkFNX0JPT0xfMSApCQlwSW1wbC0+cE5leHRSZXR1cm4tPlB1dEJvb2woIGJCb29sMSApOwogICAgCQkJCQkJaWYoIG5QYXJhbXMgJiBQQVJBTV9TQlhWQUxVRV8xICkgICAgLy8gRklYTUU6IGFsbG93IGdlbmVyaWMgZGF0YXR5cGUKICAgIAkJCQkJCXsKICAgIAkJCQkJCQlTYnhWYWx1ZXMgYVZhbHVlcyggU2J4REFURSApOwogICAgCQkJCQkJCXhWYWx1ZTEtPkdldCggYVZhbHVlcyApOwogICAgCQkJCQkJCXBJbXBsLT5wTmV4dFJldHVybi0+UHV0KCBhVmFsdWVzICk7CiAgICAJCQkJCQl9CiAgICAJCQkJCX0KICAgIAkJCQkJZWxzZQogICAgCQkJCQl7CiAgICAJCQkJCQlBRERfRVJST1IoU2J4RVJSX0JBRF9BQ1RJT04sIEdFTl9SRVNfU1RSMChTX1JFVFVSTkVEX1ZBTFVFX0lEX01JU1NNQVRDSCkgKQogICAgCQkJCQl9Ci8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbXBsLT5wTmV4dFJldHVybi0+R2V0UGFyZW50KCktPlNldFVzZXJEYXRhKG5IaW50VXNlckRhdGEpOwogICAgCQkJCQlwSW1wbC0+cE5leHRSZXR1cm4gPSBOVUxMOwogICAgCQkJCX0KICAgIAkJCQllbHNlCiAgICAJCQkJewogICAgCQkJCQlBRERfRVJST1IoU2J4RVJSX0JBRF9BQ1RJT04sIEdFTl9SRVNfU1RSMChTX1JFVFVSTkVEX1ZBTFVFX05PX1JFQ0VJVkVSKSApCiAgICAJCQkJfQogICAgCQkJCWJyZWFrOwogICAgCQkJY2FzZSBSRVRfV2luSW5mbzoKICAgIAkJCQl7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIW1fcFJldmVyc2VDb250cm9scyAmJiAhbV9wUmV2ZXJzZUNvbnRyb2xzU29uICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBSZXZlcnNlQ29udHJvbHNLb250ZXh0ID0gTlVMTDsKCiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRIaWRMc3RCeU51bWJlcigpOwogICAgICAgICAgICAgICAgICAgICAgICBTb3J0Q29udHJvbHNCeU51bWJlcigpOwoKICAgIAkJCQkJLy8gQWxsZSBTbG90cyBuYWNoIE51bW1lciBTb3J0aWVydAogICAgCQkJCQlpZiAoICFtX3BSZXZlcnNlU2xvdHMgJiYgbV9wU0lkcyApCiAgICAJCQkJCXsKICAgIAkJCQkJCW1fcFJldmVyc2VTbG90cyA9IG5ldyBDTmFtZXM7CiAgICAJCQkJCQlzYWxfdUludDE2IG5XaW47CiAgICAJCQkJCQljb25zdCBTdHJpbmcgYVNsKCcvJyk7CiAgICAJCQkJCQlmb3IgKCBuV2luID0gMCA7IG5XaW4gPCBtX3BTSWRzLT5Db3VudCgpIDsgbldpbisrICkKICAgIAkJCQkJCXsKICAgIAkJCQkJCQlDb250cm9sSXRlbVVJZCAqcE5ld0l0ZW0gPSBuZXcgQ29udHJvbEl0ZW1VSWQobV9wU0lkcy0+R2V0T2JqZWN0KG5XaW4pLT5wRGF0YS0+S3Vyem5hbWUsbV9wU0lkcy0+R2V0T2JqZWN0KG5XaW4pLT5wRGF0YS0+YVVJZCk7CiAgICAJCQkJCQkJQWRkVG9MaXN0QnlOciggbV9wUmV2ZXJzZVNsb3RzLCBwTmV3SXRlbSApOwogICAgCQkJCQkJfQogICAgCQkJCQl9CgogICAgCQkJCQlXaW5JbmZvUmVjICpwV2luSW5mbyA9IG5ldyBXaW5JbmZvUmVjOwogICAgCQkJCQkvLyBGSVhNRTogSEVMUElECiAgICAJCQkJCSNpZiAwCiAgICAJCQkJCXBXaW5JbmZvLT5hVUlkID0gYVVJZC5HZXRUZXh0KCk7CiAgICAJCQkJCSNlbmRpZgogICAgCQkJCQlwV2luSW5mby0+blJUeXBlID0gKHNhbF91SW50MTYpbkxOcjE7ICAgLy8ganVzdCBzYWxfdUxvbmcgZm9yIFRyYW5zcG9ydCwgZGF0YSBpcyBhbHdheXMgVVNIT1JUCiAgICAJCQkJCXBXaW5JbmZvLT5hUk5hbWUgPSBhU3RyaW5nMTsKICAgIAkJCQkJcFdpbkluZm8tPmJJc1Jlc2V0ID0gYkJvb2wxOwogICAgCQkJCQlwV2luSW5mby0+YUt1cnpuYW1lLkVyYXNlKCk7CiAgICAJCQkJCXBXaW5JbmZvLT5hU2xvdG5hbWUuRXJhc2UoKTsKCiAgICAJCQkJCS8vIGV2ZW50dWVsbCBkZW4gS29udGV4dCBmZXN0c3RlbGxlbi4gUGFzc2llcnQgbnVyIGJlaW0gZXJzdGVuIEVpbnRyYWcgbmFjaCByZXNldAogICAgCQkJCQlpZiAoICFwUmV2ZXJzZUNvbnRyb2xzS29udGV4dCAmJiBtX3BSZXZlcnNlQ29udHJvbHNTb24gKQogICAgCQkJCQl7CiAgICAJCQkJCQlzYWxfdUludDE2IG5OcjsKICAgIAkJCQkJCUNvbnRyb2xJdGVtICpwTmV3SXRlbSA9IG5ldyBDb250cm9sSXRlbVVJZCggU3RyaW5nKCksIGFVSWQgKTsKICAgIAkJCQkJCWlmICggbV9wUmV2ZXJzZUNvbnRyb2xzU29uLT5TZWVrX0VudHJ5KHBOZXdJdGVtLCZuTnIpICkKICAgIAkJCQkJCXsKICAgIAkJCQkJCQlwUmV2ZXJzZUNvbnRyb2xzS29udGV4dCA9ICgoQ29udHJvbEl0ZW1VSWRTb24qKW1fcFJldmVyc2VDb250cm9sc1Nvbi0+R2V0T2JqZWN0KG5OcikpLT5HZXRTb25zKCk7CiAgICAJCQkJCQkJcFdpbkluZm8tPmFLdXJ6bmFtZSA9IENVbmlTdHJpbmcoIioiKTsKICAgIAkJCQkJCX0KICAgIAkJCQkJCWVsc2UKICAgIAkJCQkJCQlwUmV2ZXJzZUNvbnRyb2xzS29udGV4dCA9IG1fcFJldmVyc2VDb250cm9sczsKCiAgICAJCQkJCQlkZWxldGUgcE5ld0l0ZW07CiAgICAJCQkJCX0KCiAgICAJCQkJCS8vIFJlc2V0LiBNde+/vSBuYWNoIGJlc3RpbW1lbiBkZXMgS29udGV4dCBzdGVoZW4sIGRhIHNvbnN0IG1pdCBkZW0gcmVzZXQtcmVjb3JkCiAgICAJCQkJCS8vIGRlciBLb250ZXh0IGZhbHNjaCBnZXNldHp0IHdpcmQuCiAgICAJCQkJCWlmICggcFdpbkluZm8tPmJJc1Jlc2V0ICkKICAgIAkJCQkJCXBSZXZlcnNlQ29udHJvbHNLb250ZXh0ID0gTlVMTDsgLy8gUmVpaGVuZm9sZ2Ugd2ljaHRpZyEKCgogICAgCQkJCQkvLyBLdXJ6bmFtZSBmZXN0c3RlbGxlbgogICAgCQkJCQlpZiAoIHBSZXZlcnNlQ29udHJvbHNLb250ZXh0ICkKICAgIAkJCQkJewogICAgCQkJCQkJc2FsX3VJbnQxNiBuTnI7CiAgICAJCQkJCQlDb250cm9sSXRlbSAqcE5ld0l0ZW0gPSBuZXcgQ29udHJvbEl0ZW1VSWQoIFN0cmluZygpLCBhVUlkICk7CiAgICAJCQkJCQlpZiAoIHBSZXZlcnNlQ29udHJvbHNLb250ZXh0LT5TZWVrX0VudHJ5KHBOZXdJdGVtLCZuTnIpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ0bDo6T1N0cmluZyBhSUQgPSBwUmV2ZXJzZUNvbnRyb2xzS29udGV4dC0+R2V0T2JqZWN0KG5OciktPnBEYXRhLT5hVUlkOwogICAgCQkJCQkJCXBXaW5JbmZvLT5hS3Vyem5hbWUgKz0gcFJldmVyc2VDb250cm9sc0tvbnRleHQtPkdldE9iamVjdChuTnIpLT5wRGF0YS0+S3Vyem5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAJCQkJCQlkZWxldGUgcE5ld0l0ZW07CiAgICAJCQkJCX0KCiAgICAJCQkJCS8vIFNsb3RuYW1lIGZlc3RzdGVsbGVuCiAgICAJCQkJCWlmICggbV9wUmV2ZXJzZVNsb3RzICkKICAgIAkJCQkJewogICAgCQkJCQkJc2FsX3VJbnQxNiBuTnI7CiAgICAJCQkJCQlDb250cm9sSXRlbSAqcE5ld0l0ZW0gPSBuZXcgQ29udHJvbEl0ZW1VSWQoIFN0cmluZygpLCBhVUlkICk7CiAgICAJCQkJCQlpZiAoIG1fcFJldmVyc2VTbG90cy0+U2Vla19FbnRyeShwTmV3SXRlbSwmbk5yKSApCiAgICAJCQkJCQkJcFdpbkluZm8tPmFTbG90bmFtZSA9IG1fcFJldmVyc2VTbG90cy0+R2V0T2JqZWN0KG5OciktPnBEYXRhLT5LdXJ6bmFtZTsKICAgIAkJCQkJCWRlbGV0ZSBwTmV3SXRlbTsKICAgIAkJCQkJfQoKICAgIAkJCQkJLy8gTGFuZ25hbWUgZmVzdHN0ZWxsZW4KICAgIAkJCQkJLy8gRklYTUU6IEhFTFBJRAogICAgCQkJCQkjaWYgMAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFVSWQuSGFzU3RyaW5nKCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7ICAgLy8gdXNlIHRoZSBTdHJpbmcgSUQgc2luY2UgdGhlcmUgaXMgbm8gTG9uZ05hbWUgaW4gaGlkLmxzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFdpbkluZm8tPmFMYW5nbmFtZSA9IGFVSWQuR2V0U3RyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIG1fcFJldmVyc2VVSWRzICkKICAgIAkJCQkJICAgIHsKICAgIAkJCQkJCSAgICBzYWxfdUludDE2IG5OcjsKICAgIAkJCQkJCSAgICBDb250cm9sSXRlbSAqcE5ld0l0ZW0gPSBuZXcgQ29udHJvbEl0ZW1VSWQoIFN0cmluZygpLCBhVUlkICk7CiAgICAJCQkJCQkgICAgaWYgKCBtX3BSZXZlcnNlVUlkcy0+U2Vla19FbnRyeShwTmV3SXRlbSwmbk5yKSApCiAgICAJCQkJCQkJICAgIHBXaW5JbmZvLT5hTGFuZ25hbWUgPSBtX3BSZXZlcnNlVUlkcy0+R2V0T2JqZWN0KG5OciktPnBEYXRhLT5LdXJ6bmFtZTsKICAgIAkJCQkJCSAgICBkZWxldGUgcE5ld0l0ZW07CiAgICAJCQkJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgI2VuZGlmCgogICAgCQkJCQlhV2luSW5mb0hkbC5DYWxsKCBwV2luSW5mbyApOwoKICAgIAkJCQkJZGVsZXRlIHBXaW5JbmZvOwogICAgCQkJCX0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgUkVUX1Byb2ZpbGVJbmZvOgogICAgCQkJCXsKICAgIAkJCQkgICAgLy8gRklYTUU6IEhFTFBJRAogICAgCQkJCSAgICAjaWYgMAogICAgICAgICAgICAgICAgICAgICAgICBzYWxfdUxvbmcgblVJZCA9IGFVSWQuR2V0TnVtKCk7CiAgICAJCQkJCWlmICggblBhcmFtcyAmIFBBUkFNX1NUUl8xICkKICAgIAkJCQkJewogICAgCQkJCQkJRGlyRW50cnkgRmlsZVBhdGggPSBwSW1wbC0+YUxvZ0ZpbGVCYXNlICsgRGlyRW50cnkoRGlyRW50cnkoYUxvZ0ZpbGVOYW1lKS5HZXRCYXNlKCkuQXBwZW5kQXNjaWkoIi5wcmYiKSk7CiAgICAJCQkJCQlTdkZpbGVTdHJlYW0gYVN0cm0oIEZpbGVQYXRoLkdldEZ1bGwoKSwgU1RSRUFNX1NURF9XUklURSApOwogICAgCQkJCQkJaWYoIGFTdHJtLklzT3BlbigpICkKICAgIAkJCQkJCXsKICAgIAkJCQkJCQlhU3RyaW5nMS5Db252ZXJ0TGluZUVuZChMSU5FRU5EX0NSTEYpOwogICAgCQkJCQkJCWFTdHJtLlNlZWsoU1RSRUFNX1NFRUtfVE9fRU5EKTsKICAgIAkJCQkJCQlhU3RybSA8PCBCeXRlU3RyaW5nKCBhU3RyaW5nMSwgUlRMX1RFWFRFTkNPRElOR19VVEY4ICkuR2V0QnVmZmVyKCk7CiAgICAJCQkJCQkJYVN0cm0uQ2xvc2UoKTsKICAgIAkJCQkJCX0KICAgIAkJCQkJfQogICAgCQkJCQlpZiAoIG5QYXJhbXMgJiBQQVJBTV9VTE9OR18xICkKICAgIAkJCQkJewogICAgCQkJCQkJc3dpdGNoICggblVJZCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAJCQkJCQkgICAgY2FzZSBTX1Byb2ZpbGVSZXNldDoJLy8gbkxOcjEgPSBBbnphaGwgQm9yZGVycwogICAgCQkJCQkJICAgIHsKICAgIAkJCQkJCQkgICAgcEltcGwtPm5OdW1Cb3JkZXJzID0gKHNhbF91SW50MTYpbkxOcjE7ICAgICAvLyBCb3JkZXJzIGFyZSAwIHRvIDQKICAgIAkJCQkJCQkgICAgc2FsX3VJbnQxNiBpOwogICAgCQkJCQkJCSAgICBmb3IgKCBpPTAgOyBpPDQgOyBpKysgKQogICAgCQkJCQkJCQkgICAgcEltcGwtPm5hVmFsQm9yZGVyc1tpXSA9IDA7CgogICAgCQkJCQkJCSAgICBmb3IgKCBpPTAgOyBpPDUgOyBpKysgKQogICAgCQkJCQkJCSAgICB7CiAgICAJCQkJCQkJCSAgICBwSW1wbC0+bmFOdW1FbnRyaWVzW2ldID0gMDsKICAgIAkJCQkJCQkJICAgIHBJbXBsLT5uYVJlbW90ZVRpbWVbaV0gPSAwOwogICAgCQkJCQkJCQkgICAgcEltcGwtPm5hTG9jYWxUaW1lW2ldID0gMDsKICAgIAkJCQkJCQkgICAgfQogICAgCQkJCQkJCSAgICBicmVhazsKICAgIAkJCQkJCSAgICB9CiAgICAJCQkJCQkgICAgY2FzZSBTX1Byb2ZpbGVCb3JkZXIxOgkvLyBuTE5yMSA9IEJvcmRlcjEgaW4gbXMKICAgIAkJCQkJCSAgICBjYXNlIFNfUHJvZmlsZUJvcmRlcjI6CS8vIG5MTnIxID0gQm9yZGVyMiBpbiBtcwogICAgCQkJCQkJICAgIGNhc2UgU19Qcm9maWxlQm9yZGVyMzoJLy8gbkxOcjEgPSBCb3JkZXIzIGluIG1zCiAgICAJCQkJCQkgICAgY2FzZSBTX1Byb2ZpbGVCb3JkZXI0OgkvLyBuTE5yMSA9IEJvcmRlcjQgaW4gbXMKICAgIAkJCQkJCSAgICB7CiAgICAJCQkJCQkJICAgIHBJbXBsLT5uYVZhbEJvcmRlcnNbIG5VSWQgLSBTX1Byb2ZpbGVCb3JkZXIxIF0gPSBuTE5yMTsKICAgIAkJCQkJCQkgICAgYnJlYWs7CiAgICAJCQkJCQkgICAgfQogICAgCQkJCQkJICAgIGNhc2UgU19Qcm9maWxlVGltZToJCS8vIG5MTnIxID0gcmVtb3RlIFplaXQgZGVzIEJlZmVobHMKICAgIAkJCQkJCSAgICB7CiAgICAJCQkJCQkJICAgIHNhbF91SW50MTYgaTsKICAgIAkJCQkJCQkgICAgZm9yICggaT0wIDsgaTxwSW1wbC0+bk51bUJvcmRlcnMgJiYKICAgIAkJCQkJCQkJICAgIHBJbXBsLT5uYVZhbEJvcmRlcnNbaV0gPD0gbkxOcjEgOyBpKysgKSB7fTsKCiAgICAJCQkJCQkJICAgIHBJbXBsLT5uYU51bUVudHJpZXNbIGkgXSsrOwogICAgCQkJCQkJCSAgICBwSW1wbC0+bmFSZW1vdGVUaW1lWyBpIF0gKz0gbkxOcjE7CiAgICAJCQkJCQkJICAgIHBJbXBsLT5uYUxvY2FsVGltZVsgaSBdICs9IFRpbWU6OkdldFN5c3RlbVRpY2tzKCkgLSBwSW1wbC0+TG9jYWxTdGFydHRpbWU7CgogICAgI2lmIE9TTF9ERUJVR19MRVZFTCA+IDEKICAgIAkJCQkJCQkgICAgaWYgKCBuTE5yMSA+IChUaW1lOjpHZXRTeXN0ZW1UaWNrcygpIC0gcEltcGwtPkxvY2FsU3RhcnR0aW1lKSApCiAgICAJCQkJCQkJICAgIHsKICAgIAkJCQkJCQkJICAgIFN0cmluZyBhTGluZSA9IENVbmlTdHJpbmcoIlRlc3R0b29semVpdCgiKS5BcHBlbmQoU3RyaW5nOjpDcmVhdGVGcm9tSW50NjQoVGltZTo6R2V0U3lzdGVtVGlja3MoKSAtIHBJbXBsLT5Mb2NhbFN0YXJ0dGltZSkpLkFwcGVuZEFzY2lpKCIpIGtsZWluZXIgT2ZmaWNlemVpdCgiKS5BcHBlbmQoU3RyaW5nOjpDcmVhdGVGcm9tSW50NjQobkxOcjEpKS5BcHBlbmRBc2NpaSgiKVxuIik7CiAgICAJCQkJCQkJCSAgICBEaXJFbnRyeSBGaWxlUGF0aCA9IHBJbXBsLT5hTG9nRmlsZUJhc2UgKyBEaXJFbnRyeShEaXJFbnRyeShhTG9nRmlsZU5hbWUpLkdldEJhc2UoKS5BcHBlbmRBc2NpaSgiLnByZiIpKTsKICAgIAkJCQkJCQkJICAgIFN2RmlsZVN0cmVhbSBhU3RybSggRmlsZVBhdGguR2V0RnVsbCgpLCBTVFJFQU1fU1REX1dSSVRFICk7CiAgICAJCQkJCQkJCSAgICBpZiggYVN0cm0uSXNPcGVuKCkgKQogICAgCQkJCQkJCQkgICAgewogICAgCQkJCQkJCQkJICAgIGFMaW5lLkNvbnZlcnRMaW5lRW5kKExJTkVFTkRfQ1JMRik7CiAgICAJCQkJCQkJCQkgICAgYVN0cm0uU2VlayhTVFJFQU1fU0VFS19UT19FTkQpOwogICAgCQkJCQkJCQkJICAgIGFTdHJtIDw8IEJ5dGVTdHJpbmcoIGFMaW5lLCBSVExfVEVYVEVOQ09ESU5HX1VURjggKS5HZXRCdWZmZXIoKTsKICAgIAkJCQkJCQkJCSAgICBhU3RybS5DbG9zZSgpOwogICAgCQkJCQkJCQkgICAgfQogICAgCQkJCQkJCSAgICB9CiAgICAjZW5kaWYKCiAgICAJCQkJCQkJICAgIGJyZWFrOwogICAgCQkJCQkJICAgIH0KICAgIAkJCQkJCSAgICBjYXNlIFNfUHJvZmlsZUR1bXA6CQkvLyBHaWJ0IGRpZSBkYXRlbiBhdXMuCiAgICAJCQkJCQkgICAgewogICAgCQkJCQkJCSAgICBpZiAoIHBJbXBsLT5uTnVtQm9yZGVycyA9PSAwICkJLy8gQWxzbyBrZWluZSBhbHRlIFLvv71ja21lbGR1bmcgdm9tIE9mZmljZQogICAgCQkJCQkJCQkgICAgYnJlYWs7CiAgICAJCQkJCQkJICAgIERpckVudHJ5IEZpbGVQYXRoID0gcEltcGwtPmFMb2dGaWxlQmFzZSArIERpckVudHJ5KERpckVudHJ5KGFMb2dGaWxlTmFtZSkuR2V0QmFzZSgpLkFwcGVuZEFzY2lpKCIucHJmIikpOwogICAgCQkJCQkJCSAgICBTdkZpbGVTdHJlYW0gYVN0cm0oIEZpbGVQYXRoLkdldEZ1bGwoKSwgU1RSRUFNX1NURF9XUklURSApOwogICAgCQkJCQkJCSAgICBpZiggYVN0cm0uSXNPcGVuKCkgKQogICAgCQkJCQkJCSAgICB7CiAgICAJCQkJCQkJCSAgICBTdHJpbmcgYVByb2ZpbGU7CiAgICAJCQkJCQkJCSAgICBzYWxfdUludDE2IGk7CgogICAgCQkJCQkJCQkgICAgYVByb2ZpbGUgKz0gU3RyaW5nKCkuRXhwYW5kKDE1KTsKICAgIAkJCQkJCQkJICAgIGZvciAoIGk9MCA7IGk8cEltcGwtPm5OdW1Cb3JkZXJzIDsgaSsrICkKICAgIAkJCQkJCQkJCSAgICBhUHJvZmlsZSArPSAoQ1VuaVN0cmluZygiPCAiKS5BcHBlbmQoU3RyaW5nOjpDcmVhdGVGcm9tSW50NjQocEltcGwtPm5hVmFsQm9yZGVyc1tpXSkpKS5FeHBhbmQoMjApOwoKICAgIAkJCQkJCQkJICAgIGFQcm9maWxlICs9IChDVW5pU3RyaW5nKCI+PSAiKS5BcHBlbmQoVFRGb3JtYXQ6Om1zMnMocEltcGwtPm5hVmFsQm9yZGVyc1twSW1wbC0+bk51bUJvcmRlcnMtMV0pKSk7CgogICAgCQkJCQkJCQkgICAgYVByb2ZpbGUgKz0gJ1xuJzsKCiAgICAJCQkJCQkJCSAgICBhUHJvZmlsZSArPSBDVW5pU3RyaW5nKCJFcmVpZ25pc3NlIikuRXhwYW5kKDE1KTsKICAgIAkJCQkJCQkJICAgIGZvciAoIGk9MCA7IGk8PXBJbXBsLT5uTnVtQm9yZGVycyA7IGkrKyApCiAgICAJCQkJCQkJCQkgICAgYVByb2ZpbGUgKz0gVFRGb3JtYXQ6Om1zMnMocEltcGwtPm5hTnVtRW50cmllc1tpXSkuRXhwYW5kKDIwKTsKCiAgICAJCQkJCQkJCSAgICBhUHJvZmlsZSArPSAnXG4nOwoKICAgIAkJCQkJCQkJICAgIGFQcm9maWxlICs9IENVbmlTdHJpbmcoIlNlcnZlciBaZWl0IikuRXhwYW5kKDE1KTsKICAgIAkJCQkJCQkJICAgIGZvciAoIGk9MCA7IGk8PXBJbXBsLT5uTnVtQm9yZGVycyA7IGkrKyApCiAgICAJCQkJCQkJCQkgICAgYVByb2ZpbGUgKz0gVFRGb3JtYXQ6Om1zMnMocEltcGwtPm5hUmVtb3RlVGltZVtpXSkuRXhwYW5kKDIwKTsKCiAgICAJCQkJCQkJCSAgICBhUHJvZmlsZSArPSAnXG4nOwoKICAgIAkJCQkJCQkJICAgIGFQcm9maWxlICs9IENVbmlTdHJpbmcoIlRlc3R0b29sIFplaXQiKS5FeHBhbmQoMTUpOwogICAgCQkJCQkJCQkgICAgZm9yICggaT0wIDsgaTw9cEltcGwtPm5OdW1Cb3JkZXJzIDsgaSsrICkKICAgIAkJCQkJCQkJCSAgICBhUHJvZmlsZSArPSBUVEZvcm1hdDo6bXMycyhwSW1wbC0+bmFMb2NhbFRpbWVbaV0pLkV4cGFuZCgyMCk7CgogICAgCQkJCQkJCQkgICAgYVByb2ZpbGUgKz0gJ1xuJzsKCiAgICAJCQkJCQkJCSAgICBhUHJvZmlsZSArPSBDVW5pU3RyaW5nKCJPdmVyaGVhZCBwLmUuIikuRXhwYW5kKDE1KTsKICAgIAkJCQkJCQkJICAgIGZvciAoIGk9MCA7IGk8PXBJbXBsLT5uTnVtQm9yZGVycyA7IGkrKyApCiAgICAJCQkJCQkJCSAgICB7CiAgICAJCQkJCQkJCQkgICAgaWYgKCBwSW1wbC0+bmFOdW1FbnRyaWVzW2ldID4gMCApCiAgICAJCQkJCQkJCQkJICAgIGFQcm9maWxlICs9IFRURm9ybWF0OjptczJzKChwSW1wbC0+bmFMb2NhbFRpbWVbaV0tcEltcGwtPm5hUmVtb3RlVGltZVtpXSkvcEltcGwtPm5hTnVtRW50cmllc1tpXSkuRXhwYW5kKDIwKTsKICAgIAkJCQkJCQkJCSAgICBlbHNlCiAgICAJCQkJCQkJCQkJICAgIGFQcm9maWxlICs9IENVbmlTdHJpbmcoICI/PyIgKS5FeHBhbmQoMjApOwogICAgCQkJCQkJCQkgICAgfQoKICAgIAkJCQkJCQkJICAgIGFQcm9maWxlICs9ICdcbic7CgogICAgCQkJCQkJCQkgICAgYVByb2ZpbGUuQ29udmVydExpbmVFbmQoTElORUVORF9DUkxGKTsKICAgIAkJCQkJCQkJICAgIGFTdHJtLlNlZWsoU1RSRUFNX1NFRUtfVE9fRU5EKTsKICAgIAkJCQkJCQkJICAgIGFTdHJtIDw8IEJ5dGVTdHJpbmcoIGFQcm9maWxlLCBSVExfVEVYVEVOQ09ESU5HX1VURjggKS5HZXRCdWZmZXIoKTsKICAgIAkJCQkJCQkJICAgIGFTdHJtLkNsb3NlKCk7CiAgICAJCQkJCQkJICAgIH0KICAgIAkJCQkJCQkgICAgYnJlYWs7CiAgICAJCQkJCQkgICAgfQogICAgCQkJCQkJICAgIGRlZmF1bHQ6CiAgICAJCQkJCQkJICAgIERCR19FUlJPUjEoIlVuYmVrYW5udGVyIFN1YiBSZXR1cm4gQ29kZSBiZWkgUHJvZmlsZTogJWh1IiwgblVJZCApOwogICAgCQkJCQkJCSAgICBicmVhazsKICAgIAkJCQkJCX0KICAgIAkJCQkJfQogICAgCQkJCQkjZW5kaWYKICAgIAkJCQl9CiAgICAJCQkJYnJlYWs7CiAgICAJCQljYXNlIFJFVF9EaXJlY3RMb2dpbmc6CiAgICAJCQkJewogICAgCQkJCSAgICAvLyBGSVhNRTogSEVMUElECiAgICAJCQkJICAgICNpZiAwCiAgICAgICAgICAgICAgICAgICAgICAgIHNhbF91TG9uZyBuVUlkID0gYVVJZC5HZXROdW0oKTsKICAgIAkJCQkJc3dpdGNoICggblVJZCApCiAgICAJCQkJCXsKICAgIAkJCQkJY2FzZSBTX0Fzc2VydEVycm9yOgogICAgCQkJCQkJewogICAgCQkJCQkJCUFERF9BU1NFUlRJT05fTE9HKCBhU3RyaW5nMSApOwovLwkJCQkJCQkJQUREX0VSUk9SX0xPRyggYVN0cmluZzEsIGFSdW4uR2V0TW9kdWxlTmFtZShTYnhOQU1FX1NIT1JUX1RZUEVTKSwKLy8JCQkJCQkJCQlhUnVuLkdldExpbmUoKSwgYVJ1bi5HZXRDb2wxKCksIGFSdW4uR2V0Q29sMigpICk7CiAgICAJCQkJCQl9CiAgICAJCQkJCQlicmVhazsKICAgIAkJCQkJY2FzZSBTX1FBRXJyb3I6CiAgICAJCQkJCQl7CiAgICAJCQkJCQkJQUREX1FBX0VSUk9SX0xPRyggYVN0cmluZzEgKTsKICAgIAkJCQkJCX0KICAgIAkJCQkJCWJyZWFrOwogICAgCQkJCQlkZWZhdWx0OgogICAgCQkJCQkJOwogICAgCQkJCQl9CiAgICAJCQkJCSNlbmRpZgogICAgCQkJCX0KICAgIAkJCQlicmVhazsKICAgIAkJCWNhc2UgUkVUX01hY3JvUmVjb3JkZXI6CiAgICAJCQkJewogICAgICAgICAgICAgICAgICAgICAgICBTb3J0Q29udHJvbHNCeU51bWJlciggc2FsX1RydWUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFDb21tYW5kLGFDb250cm9scyxhQ29udHJvbCxhVUxvbmdOYW1lcyxhVUxvbmdOYW1lOwogICAgICAgICAgICAgICAgICAgICAgICBzYWxfQm9vbCBiV3JpdGVOZXdLb250ZXh0ID0gc2FsX0ZhbHNlOwoKICAgICAgICAgICAgICAgICAgICAgICAgYUNvbnRyb2xzLkVyYXNlKCk7CiAgICAJCQkJCS8vIEt1cnpuYW1lIGZlc3RzdGVsbGVuCiAgICAJCQkJCWlmICggbV9wUmV2ZXJzZUNvbnRyb2xzICkKICAgIAkJCQkJewogICAgCQkJCQkJc2FsX3VJbnQxNiBuTnI7CiAgICAJCQkJCQlDb250cm9sSXRlbSAqcE5ld0l0ZW0gPSBuZXcgQ29udHJvbEl0ZW1VSWQoIFN0cmluZygpLCBhVUlkICk7CiAgICAJCQkJCQlpZiAoIG1fcFJldmVyc2VDb250cm9scy0+U2Vla19FbnRyeShwTmV3SXRlbSwmbk5yKSApCiAgICAJCQkJCQkJYUNvbnRyb2xzID0gbV9wUmV2ZXJzZUNvbnRyb2xzLT5HZXRPYmplY3Qobk5yKS0+cERhdGEtPkt1cnpuYW1lOwogICAgCQkJCQkJZGVsZXRlIHBOZXdJdGVtOwogICAgCQkJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWFDb250cm9scy5MZW4oKSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb250cm9scyA9IFN0cmluZzo6Q3JlYXRlRnJvbUFzY2lpKCJVbmtub3duQ29udHJvbDpVbmtub3duQ29udHJvbCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgU291bmQ6OkJlZXAoIFNPVU5EX1dBUk5JTkcgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgYVVMb25nTmFtZXMuRXJhc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIChuUGFyYW1zICYgUEFSQU1fVUxPTkdfMSkgJiYgKG5OcjEgJiBNX1JFVF9OVU1fQ09OVFJPTCkgKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAJCQkJCSAgICBpZiAoIG1fcFJldmVyc2VDb250cm9scyApCiAgICAJCQkJCSAgICB7CiAgICAJCQkJCQkgICAgc2FsX3VJbnQxNiBuTnI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGSVhNRTogSEVMUElECiAgICAJCQkJCQkgICAgQ29udHJvbEl0ZW0gKnBOZXdJdGVtID0gbmV3IENvbnRyb2xJdGVtVUlkKCBTdHJpbmcoKSwgcnRsOjpPU3RyaW5nKCAvKm5MTnIxKi8gKSApOwogICAgCQkJCQkJICAgIGlmICggbV9wUmV2ZXJzZUNvbnRyb2xzLT5TZWVrX0VudHJ5KHBOZXdJdGVtLCZuTnIpICkKICAgIAkJCQkJCQkgICAgYVVMb25nTmFtZXMgPSBtX3BSZXZlcnNlQ29udHJvbHMtPkdldE9iamVjdChuTnIpLT5wRGF0YS0+S3Vyem5hbWU7CiAgICAJCQkJCQkgICAgZGVsZXRlIHBOZXdJdGVtOwogICAgCQkJCQkgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhYVVMb25nTmFtZXMuTGVuKCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFVTG9uZ05hbWVzID0gU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoIlVua25vd246VW5rbm93biIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvdW5kOjpCZWVwKCBTT1VORF9XQVJOSU5HICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm93IGRldGVybWluIHRoZSBiZXN0IGNvbW1vbiBrb250ZXh0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxfdUludDE2IGksajsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbF9Cb29sIGJGb3VuZFVsb25nTmFtZSA9IHNhbF9GYWxzZSwgYkZvdW5kQ29udHJvbCA9IHNhbF9GYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGZvciBjdXJyZW50IGtvbnRleHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoIGkgPSAwIDsgIWJGb3VuZFVsb25nTmFtZSAmJiBpIDwgYVVMb25nTmFtZXMuR2V0VG9rZW5Db3VudCgnLycpIDsgaSsrICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiRm91bmRVbG9uZ05hbWUgPSBhTGFzdFJlY29yZGVkS29udGV4dC5FcXVhbHMoIGFVTG9uZ05hbWVzLkdldFRva2VuKGksJy8nKS5HZXRUb2tlbiggMCwnOicpICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICggaiA9IDAgOyAhYkZvdW5kQ29udHJvbCAmJiBqIDwgYUNvbnRyb2xzLkdldFRva2VuQ291bnQoJy8nKSA7IGorKyApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkZvdW5kQ29udHJvbCA9IGFMYXN0UmVjb3JkZWRLb250ZXh0LkVxdWFscyggYUNvbnRyb2xzLkdldFRva2VuKGosJy8nKS5HZXRUb2tlbiggMCwnOicpICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBiRm91bmRVbG9uZ05hbWUgJiYgYkZvdW5kQ29udHJvbCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVVMb25nTmFtZSA9IGFVTG9uZ05hbWVzLkdldFRva2VuKGktMSwnLycpLkdldFRva2VuKCAxLCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbnRyb2wgPSBhQ29udHJvbHMuR2V0VG9rZW4oai0xLCcvJykuR2V0VG9rZW4oIDEsJzonKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgICAvLyBzZWUgaWYgd2UgY2FuIGZpbmQgY29tbW9uIGtvbnRleHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxfQm9vbCBiRm91bmQgPSBzYWxfRmFsc2U7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhQ3VycmVudEtvbnRleHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICggaSA9IDAgOyAhYkZvdW5kICYmIGkgPCBhVUxvbmdOYW1lcy5HZXRUb2tlbkNvdW50KCcvJykgOyBpKysgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUN1cnJlbnRLb250ZXh0ID0gYVVMb25nTmFtZXMuR2V0VG9rZW4oaSwnLycpLkdldFRva2VuKCAwLCc6Jyk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKCBqID0gMCA7ICFiRm91bmQgJiYgaiA8IGFDb250cm9scy5HZXRUb2tlbkNvdW50KCcvJykgOyBqKysgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFDdXJyZW50S29udGV4dC5FcXVhbHMoIGFDb250cm9scy5HZXRUb2tlbihqLCcvJykuR2V0VG9rZW4oIDAsJzonKSApICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiRm91bmQgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhVUxvbmdOYW1lID0gYVVMb25nTmFtZXMuR2V0VG9rZW4oaSwnLycpLkdldFRva2VuKCAxLCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbnRyb2wgPSBhQ29udHJvbHMuR2V0VG9rZW4oaiwnLycpLkdldFRva2VuKCAxLCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUxhc3RSZWNvcmRlZEtvbnRleHQgPSBhQ3VycmVudEtvbnRleHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYldyaXRlTmV3S29udGV4dCA9IHNhbF9UcnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWJGb3VuZCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBib3RoIGNvbnRhaW4gdG9wbGV2ZWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkZvdW5kVWxvbmdOYW1lID0gc2FsX0ZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiRm91bmRDb250cm9sID0gc2FsX0ZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKCBpID0gMCA7ICFiRm91bmRVbG9uZ05hbWUgJiYgaSA8IGFVTG9uZ05hbWVzLkdldFRva2VuQ291bnQoJy8nKSA7IGkrKyApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiRm91bmRVbG9uZ05hbWUgPSBhVUxvbmdOYW1lcy5HZXRUb2tlbihpLCcvJykuR2V0VG9rZW4oIDAsJzonKS5FcXVhbHMoIGFVTG9uZ05hbWVzLkdldFRva2VuKGksJy8nKS5HZXRUb2tlbiggMSwnOicpICk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKCBqID0gMCA7ICFiRm91bmRDb250cm9sICYmIGogPCBhQ29udHJvbHMuR2V0VG9rZW5Db3VudCgnLycpIDsgaisrICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJGb3VuZENvbnRyb2wgPSBhQ29udHJvbHMuR2V0VG9rZW4oaiwnLycpLkdldFRva2VuKCAwLCc6JykuRXF1YWxzKCBhQ29udHJvbHMuR2V0VG9rZW4oaiwnLycpLkdldFRva2VuKCAxLCc6JykgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggYkZvdW5kVWxvbmdOYW1lICYmIGJGb3VuZENvbnRyb2wgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhVUxvbmdOYW1lID0gYVVMb25nTmFtZXMuR2V0VG9rZW4oaS0xLCcvJykuR2V0VG9rZW4oIDEsJzonKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb250cm9sID0gYUNvbnRyb2xzLkdldFRva2VuKGotMSwnLycpLkdldFRva2VuKCAxLCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFMYXN0UmVjb3JkZWRLb250ZXh0LkxlbigpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhTGFzdFJlY29yZGVkS29udGV4dC5FcmFzZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJXcml0ZU5ld0tvbnRleHQgPSBzYWxfVHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhQ29tbWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb21tZW50ID0gQ1VuaVN0cmluZyggIidjb3VsZCBub3QgRGV0ZXJtaW4gY29tbW9uIGtvbnRleHRcbiIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvdW5kOjpCZWVwKCBTT1VORF9XQVJOSU5HICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhV3JpdGVTdHJpbmdIZGwuQ2FsbCggJmFDb21tZW50ICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhVUxvbmdOYW1lID0gYVVMb25nTmFtZXMuR2V0VG9rZW4oaSwnLycpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbnRyb2wgPSBhQ29udHJvbHMuR2V0VG9rZW4oaiwnLycpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsgICAvLyB3ZSBvbmx5IGhhdmUgYSBDb250cm9sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxfdUludDE2IGk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxfQm9vbCBiRm91bmRDb250cm9sID0gc2FsX0ZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGN1cnJlbnQga29udGV4dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICggaSA9IDAgOyAhYkZvdW5kQ29udHJvbCAmJiBpIDwgYUNvbnRyb2xzLkdldFRva2VuQ291bnQoJy8nKSA7IGkrKyApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkZvdW5kQ29udHJvbCA9IGFMYXN0UmVjb3JkZWRLb250ZXh0LkVxdWFscyggYUNvbnRyb2xzLkdldFRva2VuKGksJy8nKS5HZXRUb2tlbiggMCwnOicpICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGJGb3VuZENvbnRyb2wgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb250cm9sID0gYUNvbnRyb2xzLkdldFRva2VuKGktMSwnLycpLkdldFRva2VuKCAxLCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUxhc3RSZWNvcmRlZEtvbnRleHQgPSBhQ29udHJvbHMuR2V0VG9rZW4oMCwnLycpLkdldFRva2VuKCAwLCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYldyaXRlTmV3S29udGV4dCA9IHNhbF9UcnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb250cm9sID0gYUNvbnRyb2xzLkdldFRva2VuKDAsJy8nKS5HZXRUb2tlbiggMSwnOicpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggYldyaXRlTmV3S29udGV4dCApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhS29udGV4dENvbW1hbmQgPSBDVW5pU3RyaW5nKCAiS29udGV4dCIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggYUxhc3RSZWNvcmRlZEtvbnRleHQuTGVuKCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFLb250ZXh0Q29tbWFuZC5BcHBlbmRBc2NpaSAoICIgXCIiICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUtvbnRleHRDb21tYW5kICs9IGFMYXN0UmVjb3JkZWRLb250ZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFLb250ZXh0Q29tbWFuZC5BcHBlbmRBc2NpaSAoICJcIiIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFLb250ZXh0Q29tbWFuZC5BcHBlbmRBc2NpaSggIlxuIiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYVdyaXRlU3RyaW5nSGRsLkNhbGwoICZhS29udGV4dENvbW1hbmQgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQgPSBhQ29udHJvbDsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBNZXRob2QgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYU1ldGhvZCA9IEdldE1ldGhvZE5hbWUoIG5OcjEgJiB+TV9SRVRfTlVNX0NPTlRST0wgKTsKICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQgKz0gJy4nOwogICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZCArPSBhTWV0aG9kOwoKICAgICAgICAgICAgICAgICAgICAgICAgc2FsX0Jvb2wgYldhc1BhcmFtID0gc2FsX0ZhbHNlOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIG5QYXJhbXMgJiBQQVJBTV9TVFJfMSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJXYXNQYXJhbSA9IHNhbF9UcnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQuQXBwZW5kQXNjaWkoICIgXCIiICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIG5OcjEgJiBNX0tFWV9TVFJJTkcgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbF91SW50MTYgbk1vZGlmeSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsX0Jvb2wgYklzUHJvc2EgPSBzYWxfRmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeHViX1N0ckxlbiBpOwoJCQkJCSAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgYVN0cmluZzEuTGVuKCk7IGkrKyApCgkJCQkJICAgICAgICAgICAgewoJCQkJCQkgICAgICAgICAgICBpZiAoICgoc2FsX3VJbnQxNilhU3RyaW5nMS5HZXRDaGFyKGkpKSA9PSAxICkgICAvLyB3ZSBoYXZlIGEgc3BlY2hpYWwgY2hhcgoJCQkJCQkgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFiSXNQcm9zYSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQuQXBwZW5kQXNjaWkoICI8IiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJJc1Byb3NhID0gc2FsX1RydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQuQXBwZW5kQXNjaWkoICIgIiApOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbF91SW50MTYgbktleUNvZGUgPSAoc2FsX3VJbnQxNilhU3RyaW5nMS5HZXRDaGFyKGkpICYgS0VZX0NPREU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxfdUludDE2IG5OZXdNb2RpZnkgPSAoc2FsX3VJbnQxNilhU3RyaW5nMS5HZXRDaGFyKGkpICYgS0VZX01PRFRZUEU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIG5OZXdNb2RpZnkgIT0gbk1vZGlmeSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ICAgLy8gZ2VuZXJhdGUgbW9kaWZpZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsX3VJbnQxNiBuQ2hhbmdlZCA9ICggbk5ld01vZGlmeSBeIG5Nb2RpZnkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIG5DaGFuZ2VkICYgS0VZX1NISUZUICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb21tYW5kICs9IEdldEtleU5hbWUoIEtFWV9TSElGVCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZC5BcHBlbmRBc2NpaSggIiAiICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggbkNoYW5nZWQgJiBLRVlfTU9EMSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZCArPSBHZXRLZXlOYW1lKCBLRVlfTU9EMSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZC5BcHBlbmRBc2NpaSggIiAiICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggbkNoYW5nZWQgJiBLRVlfTU9EMiApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZCArPSBHZXRLZXlOYW1lKCBLRVlfTU9EMiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZC5BcHBlbmRBc2NpaSggIiAiICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQgKz0gR2V0S2V5TmFtZSggbktleUNvZGUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Nb2RpZnkgPSBuTmV3TW9kaWZ5OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBiSXNQcm9zYSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQuQXBwZW5kQXNjaWkoICI+IiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJJc1Byb3NhID0gc2FsX0ZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQgKz0gYVN0cmluZzEuR2V0Q2hhcihpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Nb2RpZnkgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggYklzUHJvc2EgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQuQXBwZW5kQXNjaWkoICI+IiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiSXNQcm9zYSA9IHNhbF9GYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbW1hbmQgKz0gYVN0cmluZzE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZC5BcHBlbmRBc2NpaSggIlwiIiApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBuUGFyYW1zICYgUEFSQU1fVUxPTkdfMSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggYldhc1BhcmFtICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZC5BcHBlbmRBc2NpaSggIiwgIiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb21tYW5kLkFwcGVuZEFzY2lpKCAiICIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJXYXNQYXJhbSA9IHNhbF9UcnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBuTnIxICYgTV9SRVRfTlVNX0NPTlRST0wgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgCQkJCQkgICAgICAgIGFDb21tYW5kLkFwcGVuZCggYVVMb25nTmFtZSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb21tYW5kLkFwcGVuZCggU3RyaW5nOjpDcmVhdGVGcm9tSW50NjQoIG5MTnIxICkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiggblBhcmFtcyAmIFBBUkFNX0JPT0xfMSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggYldhc1BhcmFtICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZC5BcHBlbmRBc2NpaSggIiwgIiApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb21tYW5kLkFwcGVuZEFzY2lpKCAiICIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJXYXNQYXJhbSA9IHNhbF9UcnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBiQm9vbDEgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb21tYW5kLkFwcGVuZEFzY2lpKCAidHJ1ZSIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZC5BcHBlbmRBc2NpaSggImZhbHNlIiApOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBhQ29tbWFuZC5BcHBlbmRBc2NpaSggIlxuIiApOwoKICAgICAgIAkJCQkJYVdyaXRlU3RyaW5nSGRsLkNhbGwoICZhQ29tbWFuZCApOwogICAgCQkJCX0KICAgIAkJCQlicmVhazsKICAgIAkJCWRlZmF1bHQ6CiAgICAJCQkJREJHX0VSUk9SMSggIlVuYmVrYW5udGVyIFJldHVybiBDb2RlOiAlaXUiLCBuUmV0ICk7CiAgICAJCQkJYnJlYWs7CiAgICAJCX0KCiAgICAJCWJyZWFrOwogICAgCX0KICAgIAljYXNlIFNJUmV0dXJuRXJyb3I6CiAgICAJewogICAgCQlTdHJpbmcgYVN0cmluZzsKICAgIAkJcnRsOjpPU3RyaW5nIGFVSWQ7CiAgICAgICAgICAgIGlmICggcFJldFN0cmVhbS0+R2V0TmV4dFR5cGUoKSA9PSBCaW5TdHJpbmcgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTdHJpbmcgYVVTdHJJZDsgICAgIC8vIFVuaXF1ZVN0cmluZ0lEIFVzZWQgZm9yIE1vemlsbGEgSW50ZWdyYXRpb24KICAgICAgICAgICAgICAgIHBSZXRTdHJlYW0tPlJlYWQoIGFVU3RySWQgKTsKICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBIRUxQSUQKICAgICAgICAgICAgICAgICNpZiAwCiAgICAgICAgICAgICAgICBhVUlkID0gcnRsOjpPU3RyaW5nKCBhVVN0cklkICk7CiAgICAgICAgICAgICAgICAjZW5kaWYKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAJCWNvbW1fVUxPTkcgblVJZDsKICAgIAkJICAgIHBSZXRTdHJlYW0tPlJlYWQoIG5VSWQgKTsgICAgICAgICAvLyBiZWkgU2VxdWVuY2UgZWluZmFjaCBkaWUgU2VxdWVuY2UKICAgIAkJICAgIC8vIEZJWE1FOiBIRUxQSUQKICAgIAkJICAgICNpZiAwCiAgICAgICAgICAgICAgICBhVUlkID0gcnRsOjpPU3RyaW5nKCBuVUlkICk7CiAgICAgICAgICAgICAgICAjZW5kaWYKICAgICAgICAgICAgfQogICAgCQlwUmV0U3RyZWFtLT5SZWFkKCBhU3RyaW5nICk7CiAgICAJCVJlcGxhY2VOdW1iZXJzIChhU3RyaW5nKTsKCiAgICAJCVN0cmluZyBhU2hvcnROYW1lOwogICAgCQlhU2hvcnROYW1lID0gcFNob3J0TmFtZXMtPkdldE5hbWUoYVVJZCk7CiAgICAJCWFTaG9ydE5hbWUuQXBwZW5kQXNjaWkoICIgOiAiICk7CgogICAgCQlTdHJpbmcgYVRtcFN0cihhU2hvcnROYW1lKTsKICAgIAkJYVRtcFN0ciArPSBhU3RyaW5nOwogICAgCQlBRERfRVJST1IoU2J4RVJSX0JBRF9BQ1RJT04sIGFUbXBTdHIvKiwgbk5yKi8pOwogICAgCQlicmVhazsKICAgIAl9CiAgICAJZGVmYXVsdDoKICAgIAkJREJHX0VSUk9SMSggIlVuYmVrYW5udGVyIFJlcXVlc3QgaW0gUmV0dXJuIFN0cmVhbSBOcjogJWl1IiwgbklkICk7CiAgICAJYnJlYWs7Cgl9CiAgICAJaWYoICFwSW4tPklzRW9mKCkgKQogICAgCQlwUmV0U3RyZWFtLT5SZWFkKCBuSWQgKTsKICAgIAllbHNlCiAgICAJewogICAgCQlEQkdfRVJST1IoICJ0cnVuY2F0ZWQgaW5wdXQgc3RyZWFtIiApOwogICAgCX0KCgl9CgoJZGVsZXRlIHBSZXRTdHJlYW07CglpZiAoIGJTZXF1ZW5jZU9LICkKCXsKICAgIAluU2VxdWVuY2UrKzsKICAgIAlwU2hvcnROYW1lcy0+SW52YWxpZGF0ZSggbkNsZWFyU2VxdWVuY2UgLSBLRUVQX1NFUVVFTkNFUyApOwoJfQoKCWJSZXR1cm5PSyA9IHNhbF9UcnVlOwoKCXJldHVybiBzYWxfVHJ1ZTsKfSAvLyBSZXRTZXJ2aWNlOjpSZXF1ZXN0KCkKClN0cmluZyBUZXN0VG9vbE9iajo6R2V0TWV0aG9kTmFtZSggc2FsX3VMb25nIG5NZXRob2RJZCApCnsKICAgIHNhbF91SW50MTYgbkVsZW1lbnQ7CiAgICBpZiAoICFDb250cm9sczo6cENsYXNzZXMgKSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElzdCBzdGF0aWMsIHdpcmQgYWxzbyBudXIgZWlubWFsIGdlbGFkZW4KICAgIAlSZWFkRmxhdEFycmF5KCBDb250cm9sczo6YXJDbGFzc2VzLCBDb250cm9sczo6cENsYXNzZXMgKTsKICAgIGlmICggQ29udHJvbHM6OnBDbGFzc2VzICkKICAgIHsKICAgICAgICAvLyBGSVhNRTogSEVMUElECiAgICAgICAgI2lmIDAKICAgIAlmb3IgKCBuRWxlbWVudCA9IDAgOyBuRWxlbWVudCA8IENvbnRyb2xzOjpwQ2xhc3Nlcy0+Q291bnQoKSA7IG5FbGVtZW50KysgKQogICAgCQlpZiAoIENvbnRyb2xzOjpwQ2xhc3Nlcy0+R2V0T2JqZWN0KG5FbGVtZW50KS0+cERhdGEtPmFVSWQuTWF0Y2hlcyggbk1ldGhvZElkICkgKQogICAgCQkJcmV0dXJuIENvbnRyb2xzOjpwQ2xhc3Nlcy0+R2V0T2JqZWN0KG5FbGVtZW50KS0+cERhdGEtPkt1cnpuYW1lOwogICAgICAgICNlbHNlCiAgICAgICAgKHZvaWQpbkVsZW1lbnQ7CiAgICAgICAgKHZvaWQpbk1ldGhvZElkOwogICAgICAgICNlbmRpZgogICAgfQogICAgcmV0dXJuIFN0cmluZygpOwp9CgpTdHJpbmcgVGVzdFRvb2xPYmo6OkdldEtleU5hbWUoIHNhbF91SW50MTYgbktleUNvZGUgKQp7CiAgICBzYWxfdUludDE2IG5FbGVtZW50OwogICAgaWYgKCAhQ21kU3RyZWFtOjpwS2V5Q29kZXMgKSAgICAgICAgICAgICAgICAgICAgICAgIC8vIElzdCBzdGF0aWMsIHdpcmQgYWxzbyBudXIgZWlubWFsIGdlbGFkZW4KICAgIAlSZWFkRmxhdEFycmF5KCBDbWRTdHJlYW06OmFyS2V5Q29kZXMsIENtZFN0cmVhbTo6cEtleUNvZGVzICk7CiAgICBpZiAoIENtZFN0cmVhbTo6cEtleUNvZGVzICkKICAgIHsKICAgICAgICAvLyBGSVhNRTogSEVMUElECiAgICAgICAgI2lmIDAKICAgIAlmb3IgKCBuRWxlbWVudCA9IDAgOyBuRWxlbWVudCA8IENtZFN0cmVhbTo6cEtleUNvZGVzLT5Db3VudCgpIDsgbkVsZW1lbnQrKyApCiAgICAJCWlmICggQ21kU3RyZWFtOjpwS2V5Q29kZXMtPkdldE9iamVjdChuRWxlbWVudCktPnBEYXRhLT5hVUlkLk1hdGNoZXMoIG5LZXlDb2RlICkgKQogICAgCQkJcmV0dXJuIENtZFN0cmVhbTo6cEtleUNvZGVzLT5HZXRPYmplY3QobkVsZW1lbnQpLT5wRGF0YS0+S3Vyem5hbWU7CiAgICAgICAgI2Vsc2UKICAgICAgICAodm9pZCluRWxlbWVudDsKICAgICAgICAodm9pZCluS2V5Q29kZTsKICAgICAgICAjZW5kaWYKICAgIH0KICAgIHJldHVybiBDVW5pU3RyaW5nKCAiVW5rbm93bktleUNvZGUiICk7Cn0KCnZvaWQgVGVzdFRvb2xPYmo6OlJlcGxhY2VOdW1iZXJzKFN0cmluZyAmYVRleHQpCnsKc3RhdGljIENvbnRyb2xEZWZMb2FkIF9fUkVBRE9OTFlfREFUQSBhclJlc19UeXBlIFtdID0KI2luY2x1ZGUgInJlc190eXBlLmh4eCIKCglzdGF0aWMgQ05hbWVzICpwUlR5cGVzID0gTlVMTDsKCXh1Yl9TdHJMZW4gblN0YXJ0ID0gU1RSSU5HX05PVEZPVU5EOwoJeHViX1N0ckxlbiBuR2xlaWNoID0gU1RSSU5HX05PVEZPVU5EOwoJeHViX1N0ckxlbiBuRW5kID0gU1RSSU5HX05PVEZPVU5EOwoJeHViX1N0ckxlbiBuU3RhcnRQb3MgPSAwOwoJc2FsX3VMb25nIG5OdW1iZXI7CglTdHJpbmcgYVR5cGU7CglTdHJpbmcgYVJlc3VsdDsKCXNhbF9Cb29sIGJGb3VuZDsKCgl3aGlsZSAoIChuU3RhcnQgPSBhVGV4dC5TZWFyY2goU3RhcnRLZW5uLG5TdGFydFBvcykpICE9IFNUUklOR19OT1RGT1VORCAmJgogICAgCQkobkdsZWljaCA9IGFUZXh0LlNlYXJjaEFzY2lpKCI9IixuU3RhcnQrU3RhcnRLZW5uLkxlbigpKSkgIT0gU1RSSU5HX05PVEZPVU5EICYmCiAgICAJCShuRW5kID0gYVRleHQuU2VhcmNoKEVuZEtlbm4sbkdsZWljaCsxKSkgIT0gU1RSSU5HX05PVEZPVU5EKQoJewogICAgCWFUeXBlID0gYVRleHQuQ29weShuU3RhcnQsbkdsZWljaC1uU3RhcnQpOwogICAgCW5OdW1iZXIgPSAoc2FsX3VMb25nKWFUZXh0LkNvcHkobkdsZWljaCsxLG5FbmQtbkdsZWljaC0xKS5Ub0ludDY0KCk7CiAgICAJYkZvdW5kID0gc2FsX0ZhbHNlOwogICAgCWlmICggYVR5cGUuQ29tcGFyZVRvKFVJZEtlbm4pID09IENPTVBBUkVfRVFVQUwgKQogICAgCXsKICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBIRUxQSUQKICAgIAkJYVJlc3VsdCA9IHBTaG9ydE5hbWVzLT5HZXROYW1lKHJ0bDo6T1N0cmluZygvKm5OdW1iZXIqLykpOwogICAgCQliRm91bmQgPSBzYWxfVHJ1ZTsKICAgIAl9CiAgICAJaWYgKCBhVHlwZS5Db21wYXJlVG8oTWV0aG9kS2VubiApID09IENPTVBBUkVfRVFVQUwgKQogICAgCXsKICAgIAkJYkZvdW5kID0gc2FsX1RydWU7CiAgICAgICAgICAgIGFSZXN1bHQgPSBHZXRNZXRob2ROYW1lKCBuTnVtYmVyICk7CiAgICAJfQogICAgCWlmICggYVR5cGUuQ29tcGFyZVRvKFJjS2VubiApID09IENPTVBBUkVfRVFVQUwgKQogICAgCXsKICAgIAkJYkZvdW5kID0gc2FsX1RydWU7CiAgICAJCWlmICggIXBSQ29tbWFuZHMgKSAgICAgICAgICAgICAgICAgLy8gSXN0IHN0YXRpYywgd2lyZCBhbHNvIG51ciBlaW5tYWwgZ2VsYWRlbgogICAgCQkJUmVhZEZsYXRBcnJheSggYXJSX0NtZHMsIHBSQ29tbWFuZHMgKTsKCiAgICAJCXNhbF91SW50MTYgbkVsZW1lbnQ7CiAgICAJCWlmICggcFJDb21tYW5kcyApCiAgICAJCXsKICAgIAkJICAgIC8vIEZJWE1FOiBIRUxQSUQKICAgIAkJICAgICNpZiAwCiAgICAJCQlmb3IgKCBuRWxlbWVudCA9IDAgOyBuRWxlbWVudCA8IHBSQ29tbWFuZHMtPkNvdW50KCkgOyBuRWxlbWVudCsrICkKICAgIAkJCQlpZiAoIHBSQ29tbWFuZHMtPkdldE9iamVjdChuRWxlbWVudCktPnBEYXRhLT5hVUlkLk1hdGNoZXMoIG5OdW1iZXIgKSApCiAgICAJCQkJewogICAgCQkJCQlhUmVzdWx0ID0gcFJDb21tYW5kcy0+R2V0T2JqZWN0KG5FbGVtZW50KS0+cERhdGEtPkt1cnpuYW1lOwogICAgCQkJCQluRWxlbWVudCA9IHBSQ29tbWFuZHMtPkNvdW50KCk7CiAgICAJCQkJfQogICAgICAgICAgICAgICAgI2Vsc2UKICAgICAgICAgICAgICAgICh2b2lkKW5FbGVtZW50OwogICAgICAgICAgICAgICAgI2VuZGlmCiAgICAJCX0KICAgIAl9CiAgICAJaWYgKCBhVHlwZS5Db21wYXJlVG8oVHlwZUtlbm4gKSA9PSBDT01QQVJFX0VRVUFMICkKICAgIAl7CiAgICAJCWJGb3VuZCA9IHNhbF9UcnVlOwogICAgCQlpZiAoICFwUlR5cGVzICkgICAgICAgICAgICAgICAgIC8vIElzdCBzdGF0aWMsIHdpcmQgYWxzbyBudXIgZWlubWFsIGdlbGFkZW4KICAgIAkJCVJlYWRGbGF0QXJyYXkoIGFyUmVzX1R5cGUsIHBSVHlwZXMgKTsKCiAgICAJCXNhbF91SW50MTYgbkVsZW1lbnQ7CiAgICAJCWlmICggcFJUeXBlcyApCiAgICAJCXsKICAgIAkJICAgIC8vIEZJWE1FOiBIRUxQSUQKICAgIAkJICAgICNpZiAwCiAgICAJCQlmb3IgKCBuRWxlbWVudCA9IDAgOyBuRWxlbWVudCA8IHBSVHlwZXMtPkNvdW50KCkgOyBuRWxlbWVudCsrICkKICAgIAkJCQlpZiAoIHBSVHlwZXMtPkdldE9iamVjdChuRWxlbWVudCktPnBEYXRhLT5hVUlkLk1hdGNoZXMoIG5OdW1iZXIgKSApCiAgICAJCQkJewogICAgCQkJCQlhUmVzdWx0ID0gcFJUeXBlcy0+R2V0T2JqZWN0KG5FbGVtZW50KS0+cERhdGEtPkt1cnpuYW1lOwogICAgCQkJCQluRWxlbWVudCA9IHBSVHlwZXMtPkNvdW50KCk7CiAgICAJCQkJfQogICAgICAgICAgICAgICAgI2Vsc2UKICAgICAgICAgICAgICAgICh2b2lkKW5FbGVtZW50OwogICAgICAgICAgICAgICAgI2VuZGlmCiAgICAJCX0KICAgIAl9CiAgICAJaWYgKCBhVHlwZS5Db21wYXJlVG8oU2xvdEtlbm4gKSA9PSBDT01QQVJFX0VRVUFMICkKICAgIAl7CiAgICAgICAgICAgICAgICAvLyBGSVhNRTogSEVMUElECiAgICAJCWFSZXN1bHQgPSBwU2hvcnROYW1lcy0+R2V0TmFtZShydGw6Ok9TdHJpbmcoLypuTnVtYmVyKi8pKTsKICAgIAkJYkZvdW5kID0gc2FsX1RydWU7CiAgICAJfQogICAgCWlmICggYVR5cGUuQ29tcGFyZVRvKFRhYktlbm4gKSA9PSBDT01QQVJFX0VRVUFMICkKICAgIAl7CiAgICAJCWlmICggbk51bWJlciA+IG5TdGFydCApCiAgICAJCQlhUmVzdWx0LkZpbGwoIChzYWxfdUludDE2KW5OdW1iZXIgLSBuU3RhcnQgKzEgKTsKICAgIAkJZWxzZQogICAgCQkJYVJlc3VsdCA9IENVbmlTdHJpbmcoIiAiKTsKICAgIAkJYkZvdW5kID0gc2FsX1RydWU7CiAgICAJfQoKICAgIAluU3RhcnRQb3MgPSBuU3RhcnQ7CiAgICAJaWYgKCBiRm91bmQgKQogICAgCXsKICAgIAkJYVRleHQuRXJhc2UoblN0YXJ0LG5FbmQrRW5kS2Vubi5MZW4oKS1uU3RhcnQpOwogICAgCQlhVGV4dC5JbnNlcnQoYVJlc3VsdCxuU3RhcnQpOwogICAgCQluU3RhcnRQb3MgPSBuU3RhcnRQb3MgKyBhUmVzdWx0LkxlbigpOwogICAgCX0KICAgIAllbHNlCiAgICAJCW5TdGFydFBvcyA9IG5TdGFydFBvcyArIFN0YXJ0S2Vubi5MZW4oKTsKICAgIH0KfQoKClNiVGV4dFR5cGUgVGVzdFRvb2xPYmo6OkdldFN5bWJvbFR5cGUoIGNvbnN0IFN0cmluZyAmclN5bWJvbCwgc2FsX0Jvb2wgYldhc0NvbnRyb2wgKQp7CiAgICBpZiAoCXJTeW1ib2wuQ29tcGFyZVRvQXNjaWkoICJ0cnkiICkgPT0gQ09NUEFSRV9FUVVBTAogICAgCXx8CXJTeW1ib2wuQ29tcGFyZVRvQXNjaWkoICJjYXRjaCIgKSA9PSBDT01QQVJFX0VRVUFMCiAgICAJfHwJclN5bWJvbC5Db21wYXJlVG9Bc2NpaSggImVuZGNhdGNoIiApID09IENPTVBBUkVfRVFVQUwKICAgIAl8fAlyU3ltYm9sLkNvbXBhcmVUb0FzY2lpKCAidGVzdGNhc2UiICkgPT0gQ09NUEFSRV9FUVVBTAogICAgCXx8CXJTeW1ib2wuQ29tcGFyZVRvQXNjaWkoICJlbmRjYXNlIiApID09IENPTVBBUkVfRVFVQUwgKQogICAgewogICAgCXJldHVybiBUVF9LRVlXT1JEOwogICAgfQoKCiAgICBDb250cm9sRGVmIFdoYXROYW1lKCByU3ltYm9sLCBydGw6Ok9TdHJpbmcoKSApOwoKICAgIGlmICggYldhc0NvbnRyb2wgKQogICAgewogICAgCWlmICggIUNvbnRyb2xzOjpwQ2xhc3NlcyApICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXN0IHN0YXRpYywgd2lyZCBhbHNvIG51ciBlaW5tYWwgZ2VsYWRlbgogICAgCQlSZWFkRmxhdEFycmF5KCBDb250cm9sczo6YXJDbGFzc2VzLCBDb250cm9sczo6cENsYXNzZXMgKTsKCiAgICAJaWYgKCAoQ29udHJvbHM6OnBDbGFzc2VzICYmIENvbnRyb2xzOjpwQ2xhc3Nlcy0+U2Vla19FbnRyeSggJldoYXROYW1lICkpCiAgICAgICAgICAgIHx8IHJTeW1ib2wuRXF1YWxzSWdub3JlQ2FzZUFzY2lpKCAiSUQiICkKICAgICAgICAgICAgfHwgclN5bWJvbC5FcXVhbHNJZ25vcmVDYXNlQXNjaWkoICJOYW1lIiApICkKICAgIAkJcmV0dXJuIFRUX01FVEhPRDsKICAgIAllbHNlCiAgICAJCXJldHVybiBUVF9OT01FVEhPRDsKICAgIH0KCiAgICAvLyBEaWUgQ29udHJvbHMgZHVyY2hzdWNoZW4KICAgIGlmICggbV9wQ29udHJvbHMgKQogICAgewogICAgCXNhbF91SW50MTYgbldpbjsKCiAgICAJZm9yICggbldpbiA9IDAgOyBuV2luIDwgbV9wQ29udHJvbHMtPkNvdW50KCkgOyBuV2luKysgKQogICAgCXsKICAgIAkJaWYgKCAoKENvbnRyb2xEZWYqKW1fcENvbnRyb2xzLT5HZXRPYmplY3QoIG5XaW4gKSktPlNvblNlZWtfRW50cnkoICZXaGF0TmFtZSApICkKICAgIAkJCXJldHVybiBUVF9DT05UUk9MOwogICAgCX0KICAgIH0KCiAgICAvLyBEaWUgU2xvdHMgZHVyY2hzdWNoZW4KICAgIGlmICggbV9wU0lkcyAmJiBtX3BTSWRzLT5TZWVrX0VudHJ5KCAmV2hhdE5hbWUgKSApCiAgICAJcmV0dXJuIFRUX1NMT1Q7CgogICAgLy8gSXN0IGVzIGVpbiBSZW1vdGVDb21tYW5kCiAgICBpZiAoICFwUkNvbW1hbmRzICkgICAgICAgICAgICAgICAgIC8vIElzdCBzdGF0aWMsIHdpcmQgYWxzbyBudXIgZWlubWFsIGdlbGFkZW4KICAgIAlSZWFkRmxhdEFycmF5KCBhclJfQ21kcywgcFJDb21tYW5kcyApOwogICAgaWYgKCBwUkNvbW1hbmRzICYmIHBSQ29tbWFuZHMtPlNlZWtfRW50cnkoICZXaGF0TmFtZSApICkKICAgIAlyZXR1cm4gVFRfUkVNT1RFQ01EOwoKICAgIC8vIFdlbm5zIHNvbnN0IG5peCB3YXIsIGRhbm4gdmllbGxlaWNodCBlaW4gTG9rYWxlcyBLb21tYW5kbwogICAgU2J4VmFyaWFibGUgKnBWYXIgPSBTYnhPYmplY3Q6OkZpbmQoIHJTeW1ib2wsIFNieENMQVNTX0RPTlRDQVJFICk7CiAgICBpZiAoIHBWYXIgJiYgKCBwVmFyLT5JU0EoU2J4TWV0aG9kKSB8fCBwVmFyLT5JU0EoU2J4UHJvcGVydHkpICkgKQogICAgewogICAgCXJldHVybiBUVF9MT0NBTENNRDsKICAgIH0KCiAgICByZXR1cm4gU0JfU1lNQk9MOwkvLyBBbGxlcyB3YXMgaGllciBsYW5kZXQgaXN0IHZvbSBUeXAgU0JfU1lNQk9MIHVuZCBibGVpYnQgZXMgYXVjaAp9CgoKI3VuZGVmIFBfRkVITEVSTElTVEUKI2RlZmluZSBQX0ZFSExFUkxJU1RFIFRlc3RUb29sT2JqOjpwRmVobGVyTGlzdGUKCkNvbnRyb2xzOjpDb250cm9scyggU3RyaW5nIGFDTmFtZSApCjogU2J4T2JqZWN0KCBhQ05hbWUpCnsKICAgIHBNZXRob2RWYXIgPSBuZXcgU2J4VHJhbnNwb3J0TWV0aG9kKCBTYnhWQVJJQU5UICk7CiAgICBwTWV0aG9kVmFyLT5TZXROYW1lKCBDVW5pU3RyaW5nKCJEdW1teSIpICk7CiAgICBJbnNlcnQoIHBNZXRob2RWYXIgKTsKLy8gICAgICBwTWV0aG9kVmFyID0gTWFrZSggQ1VuaVN0cmluZygiRHVtbXkiKSwgU2J4Q0xBU1NfUFJPUEVSVFksIFNieFVMT05HICk7Cn0KCgpDb250cm9sczo6fkNvbnRyb2xzKCkKe30KCgp2b2lkIENvbnRyb2xzOjpDaGFuZ2VMaXN0ZW5lciggU2J4T2JqZWN0KiBwYXJlbnQgKQp7CiAgICBFbmRMaXN0ZW5pbmcoIHBNZXRob2RWYXItPkdldEJyb2FkY2FzdGVyKCksIHNhbF9UcnVlICk7CiAgICBwYXJlbnQtPlN0YXJ0TGlzdGVuaW5nKCBwTWV0aG9kVmFyLT5HZXRCcm9hZGNhc3RlcigpLCBzYWxfVHJ1ZSApOwp9Cgp2b2lkIENvbnRyb2xzOjpTRlhfTk9USUZZKCBTZnhCcm9hZGNhc3RlciYsIGNvbnN0IFR5cGVJZCYsCiAgICAJCQkJCQkJY29uc3QgU2Z4SGludCYsIGNvbnN0IFR5cGVJZCYgKQp7fQoKCgpTYnhWYXJpYWJsZSogQ29udHJvbHM6OkZpbmQoIGNvbnN0IFN0cmluZyYgYVN0ciwgU2J4Q2xhc3NUeXBlIGFUeXBlKQp7CiAgICBpZiAoICFwQ2xhc3NlcyApICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXN0IHN0YXRpYywgd2lyZCBhbHNvIG51ciBlaW5tYWwgZ2VsYWRlbgogICAgCVJlYWRGbGF0QXJyYXkoIGFyQ2xhc3NlcywgcENsYXNzZXMgKTsKCiAgICBpZiAoIEdldFVzZXJEYXRhKCkgPT0gSURfRXJyb3JEdW1teSApCiAgICB7CiAgICAJcE1ldGhvZFZhci0+U2V0TmFtZShVbmlTdHJpbmcoR2V0TmFtZSgpKS5BcHBlbmRBc2NpaSgiLiIpLkFwcGVuZChhU3RyKSk7CiAgICAJcE1ldGhvZFZhci0+U2V0VXNlckRhdGEoIElEX0Vycm9yRHVtbXkgKTsKICAgIAlyZXR1cm4gcE1ldGhvZFZhcjsKICAgIH0KCgogICAgc2FsX3VJbnQxNiBuRWxlbWVudDsKICAgIENvbnRyb2xEZWYgV2hhdE5hbWUoYVN0cixydGw6Ok9TdHJpbmcoKSk7CiAgICBpZiAocENsYXNzZXMgJiYgcENsYXNzZXMtPlNlZWtfRW50cnkoJldoYXROYW1lLCZuRWxlbWVudCkpCiAgICB7CiAgICAJcE1ldGhvZFZhci0+U2V0TmFtZShhU3RyKTsKICAgIAkvLyBGSVhNRTogSEVMUElECiAgICAJc2FsX3VMb25nIG5VSWQgPSAwOy8vcENsYXNzZXMtPkdldE9iamVjdChuRWxlbWVudCktPnBEYXRhLT5hVUlkLkdldE51bSgpOwogICAgCXBNZXRob2RWYXItPm5WYWx1ZSA9IG5VSWQ7CgogCQlwTWV0aG9kVmFyLT5TZXRVc2VyRGF0YSggR2V0VXNlckRhdGEoKSApOwogICAgCXJldHVybiBwTWV0aG9kVmFyOwogICAgfQogICAgZWxzZQogICAgeyAgIC8vIG1haW5seSBmb3IgSUQgYW5kIG5hbWUKICAgIAlTYnhWYXJpYWJsZVJlZiBPbGQgPSBTYnhPYmplY3Q6OkZpbmQoYVN0ciwgYVR5cGUgKTsKICAgIAlpZiAoT2xkKQogICAgCQlyZXR1cm4gT2xkOwogICAgICAgIGVsc2UgaWYgKCBhU3RyLkVxdWFsc0lnbm9yZUNhc2VBc2NpaSgiSUQiKSApCiAgICAgICAgCXJldHVybiBOVUxMOyAgICAvLyBzdXBwcmVzcyBnZW5lcmF0aW9uIG9mIGVycm9yIGluIHRoaXMgY2FzZQogICAgfQogICAgQUREX0VSUk9SKFNieEVSUl9CQURfTUVUSE9ELEdFTl9SRVNfU1RSMihTX1VOS05PV05fTUVUSE9ELCBHZXROYW1lKCksIGFTdHIpKTsKICAgIHJldHVybiBOVUxMOwp9CgoKU3RyaW5nIFRURm9ybWF0OjptczJzKCBzYWxfdUxvbmcgbk1pbGxpU2Vjb25kcyApCnsKICAgIGlmICggbk1pbGxpU2Vjb25kcyA8IDEwMDAwMCApCQkvLyAxMDAgU2VrdW5kZW4KICAgIAlyZXR1cm4gU3RyaW5nOjpDcmVhdGVGcm9tSW50NjQoIG5NaWxsaVNlY29uZHMgKTsKICAgIGlmICggbk1pbGxpU2Vjb25kcyA8IDEwMDAwMCo2MCApCS8vIDEwMCBNaW51dGVuCiAgICAJcmV0dXJuIFN0cmluZzo6Q3JlYXRlRnJvbUludDMyKCBuTWlsbGlTZWNvbmRzIC8gMTAwMCApLkFwcGVuZEFzY2lpKCJTZWMiKTsKICAgIHJldHVybiBTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMiggbk1pbGxpU2Vjb25kcyAvIDEwMDAgLyA2MCApLkFwcGVuZEFzY2lpKCJNaW4iKTsKfQoKCg==