Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KIAovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQoKI2lmbmRlZiBfRlhFVF9MSVNUX0hfCiNkZWZpbmUgX0ZYRVRfTElTVF9IXwoKI2luY2x1ZGUgImZ4X2VkaXQuaCIKCmNsYXNzIElGWF9FZGl0OwoKY2xhc3MgQ0xTVF9TaXplCnsKcHVibGljOgoJQ0xTVF9TaXplKCkgOiB4KDAuMGYpLCB5KDAuMGYpCgl7CQkKCX0KCglDTFNUX1NpemUoRlhfRkxPQVQgeCxGWF9GTE9BVCB5KQoJeyAKCQl0aGlzLT54ID0geDsKCQl0aGlzLT55ID0geTsKCX0KCgl2b2lkIERlZmF1bHQoKQoJewoJCXggPSAwLjBmOwoJCXkgPSAwLjBmOwoJfQoKCUZYX0JPT0wgb3BlcmF0b3IgIT0gKGNvbnN0IENMU1RfU2l6ZSAmIHNpemUpIGNvbnN0Cgl7CgkJcmV0dXJuIEZYU1lTX21lbWNtcCh0aGlzLCAmc2l6ZSwgc2l6ZW9mKENMU1RfU2l6ZSkpICE9IDA7Cgl9CgoJRlhfRkxPQVQgeCx5Owp9OwoKY2xhc3MgQ0xTVF9SZWN0IDogcHVibGljIENQREZfUmVjdAp7CnB1YmxpYzoKCUNMU1RfUmVjdCgpCgl7CQoJCWxlZnQgPSB0b3AgPSByaWdodCA9IGJvdHRvbSA9IDAuMGY7Cgl9CgoJQ0xTVF9SZWN0KEZYX0ZMT0FUIGxlZnQsRlhfRkxPQVQgdG9wLAoJCQkJCQlGWF9GTE9BVCByaWdodCxGWF9GTE9BVCBib3R0b20pCgl7IAoJCXRoaXMtPmxlZnQgPSBsZWZ0OyAKCQl0aGlzLT50b3AgPSB0b3A7IAoJCXRoaXMtPnJpZ2h0ID0gcmlnaHQ7IAoJCXRoaXMtPmJvdHRvbSA9IGJvdHRvbTsgCgl9CgoJQ0xTVF9SZWN0KGNvbnN0IENQREZfUmVjdCAmIHJlY3QpCgl7IAoJCXRoaXMtPmxlZnQgPSByZWN0LmxlZnQ7IAoJCXRoaXMtPnRvcCA9IHJlY3QudG9wOyAKCQl0aGlzLT5yaWdodCA9IHJlY3QucmlnaHQ7IAoJCXRoaXMtPmJvdHRvbSA9IHJlY3QuYm90dG9tOyAKCX0KCgl2b2lkIERlZmF1bHQoKQoJewoJCWxlZnQgPSB0b3AgPSByaWdodCA9IGJvdHRvbSA9IDAuMGY7Cgl9CgoJY29uc3QgQ0xTVF9SZWN0IG9wZXJhdG9yID0gKGNvbnN0IENQREZfUmVjdCAmIHJlY3QpCgl7CgkJdGhpcy0+bGVmdCA9IHJlY3QubGVmdDsKCQl0aGlzLT50b3AgPSByZWN0LnRvcDsKCQl0aGlzLT5yaWdodCA9IHJlY3QucmlnaHQ7CgkJdGhpcy0+Ym90dG9tID0gcmVjdC5ib3R0b207CgoJCXJldHVybiAqdGhpczsKCX0KCglGWF9CT09MIG9wZXJhdG9yID09IChjb25zdCBDTFNUX1JlY3QgJiByZWN0KSBjb25zdAoJewoJCXJldHVybiBGWFNZU19tZW1jbXAodGhpcywgJnJlY3QsIHNpemVvZihDTFNUX1JlY3QpKSA9PSAwOwoJfQoKCUZYX0JPT0wgb3BlcmF0b3IgIT0gKGNvbnN0IENMU1RfUmVjdCAmIHJlY3QpIGNvbnN0Cgl7CgkJcmV0dXJuIEZYU1lTX21lbWNtcCh0aGlzLCAmcmVjdCwgc2l6ZW9mKENMU1RfUmVjdCkpICE9IDA7Cgl9CgoJRlhfRkxPQVQgV2lkdGgoKSBjb25zdAoJewoJCXJldHVybiB0aGlzLT5yaWdodCAtIHRoaXMtPmxlZnQ7Cgl9CgoJRlhfRkxPQVQgSGVpZ2h0KCkgY29uc3QKCXsKCQlpZiAodGhpcy0+dG9wID4gdGhpcy0+Ym90dG9tKQoJCQlyZXR1cm4gdGhpcy0+dG9wIC0gdGhpcy0+Ym90dG9tOwoJCWVsc2UKCQkJcmV0dXJuIHRoaXMtPmJvdHRvbSAtIHRoaXMtPnRvcDsKCX0KCglDUERGX1BvaW50IExlZnRUb3AoKSBjb25zdAoJewoJCXJldHVybiBDUERGX1BvaW50KGxlZnQsdG9wKTsKCX0KCglDUERGX1BvaW50IFJpZ2h0Qm90dG9tKCkgY29uc3QKCXsKCQlyZXR1cm4gQ1BERl9Qb2ludChyaWdodCxib3R0b20pOwoJfQoKCWNvbnN0IENMU1RfUmVjdCBvcGVyYXRvciArPSAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSAKCXsKCQl0aGlzLT5sZWZ0ICs9IHBvaW50Lng7CgkJdGhpcy0+cmlnaHQgKz0gcG9pbnQueDsKCQl0aGlzLT50b3AgKz0gcG9pbnQueTsKCQl0aGlzLT5ib3R0b20gKz0gcG9pbnQueTsKCgkJcmV0dXJuICp0aGlzOwoJfQoKCWNvbnN0IENMU1RfUmVjdCBvcGVyYXRvciAtPSAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSAKCXsKCQl0aGlzLT5sZWZ0IC09IHBvaW50Lng7CgkJdGhpcy0+cmlnaHQgLT0gcG9pbnQueDsKCQl0aGlzLT50b3AgLT0gcG9pbnQueTsKCQl0aGlzLT5ib3R0b20gLT0gcG9pbnQueTsKCgkJcmV0dXJuICp0aGlzOwoJfQoKCUNMU1RfUmVjdCBvcGVyYXRvciArIChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0Cgl7CgkJcmV0dXJuIENMU1RfUmVjdChsZWZ0ICsgcG9pbnQueCwKCQkJCQl0b3AgKyBwb2ludC55LAoJCQkJCXJpZ2h0ICsgcG9pbnQueCwKCQkJCQlib3R0b20gKyBwb2ludC55KTsKCX0KCglDTFNUX1JlY3Qgb3BlcmF0b3IgLSAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdAoJewoJCXJldHVybiBDTFNUX1JlY3QobGVmdCAtIHBvaW50LngsCgkJCQkJdG9wIC0gcG9pbnQueSwKCQkJCQlyaWdodCAtIHBvaW50LngsCgkJCQkJYm90dG9tIC0gcG9pbnQueSk7Cgl9Cn07CgpjbGFzcyBDRlhfTGlzdEl0ZW0KewpwdWJsaWM6CglDRlhfTGlzdEl0ZW0oKTsKCXZpcnR1YWwgfkNGWF9MaXN0SXRlbSgpOwoKCXZvaWQJCQkJCQkJU2V0Rm9udE1hcChJRlhfRWRpdF9Gb250TWFwICogcEZvbnRNYXApOwoJSUZYX0VkaXRfSXRlcmF0b3IqCQkJCUdldEl0ZXJhdG9yKCkgY29uc3Q7CglJRlhfRWRpdCoJCQkJCQlHZXRFZGl0KCkgY29uc3Q7CgpwdWJsaWM6Cgl2b2lkCQkJCQkJCVNldFJlY3QoY29uc3QgQ0xTVF9SZWN0ICYgcmVjdCk7CQkKCXZvaWQJCQkJCQkJU2V0U2VsZWN0KEZYX0JPT0wgYlNlbGVjdGVkKTsJCgl2b2lkCQkJCQkJCVNldENhcmV0KEZYX0JPT0wgYkNhcmV0KTsKCXZvaWQJCQkJCQkJU2V0VGV4dChGWF9MUENXU1RSIHRleHQpOwoJdm9pZAkJCQkJCQlTZXRGb250U2l6ZShGWF9GTE9BVCBmRm9udFNpemUpOwoJQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldFRleHQoKSBjb25zdDsKCglDTFNUX1JlY3QJCQkJCQlHZXRSZWN0KCkgY29uc3Q7CglGWF9CT09MCQkJCQkJCUlzU2VsZWN0ZWQoKSBjb25zdDsKCUZYX0JPT0wJCQkJCQkJSXNDYXJldCgpIGNvbnN0OwoJRlhfRkxPQVQJCQkJCQlHZXRJdGVtSGVpZ2h0KCkgY29uc3Q7CQoJRlhfV09SRAkJCQkJCQlHZXRGaXJzdENoYXIoKSBjb25zdDsKCnByaXZhdGU6CglJRlhfRWRpdCoJCQkJCQltX3BFZGl0OwoJRlhfQk9PTAkJCQkJCQltX2JTZWxlY3RlZDsJCS8vyse38dGh1tAKCUZYX0JPT0wJCQkJCQkJbV9iQ2FyZXQ7CQkvL8rHt/HOqr25teOjrLbg0aHKsdPDCglDTFNUX1JlY3QJCQkJCQltX3JjTGlzdEl0ZW07CS8vxNqyv9f4seoKfTsKCmNsYXNzIENGWF9MaXN0Q29udGFpbmVyCnsKcHVibGljOgoJQ0ZYX0xpc3RDb250YWluZXIoKSA6IG1fcmNQbGF0ZSgwLjBmLDAuMGYsMC4wZiwwLjBmKSwgbV9yY0NvbnRlbnQoMC4wZiwwLjBmLDAuMGYsMC4wZil7fQoJdmlydHVhbCB+Q0ZYX0xpc3RDb250YWluZXIoKXt9Cgl2aXJ0dWFsIHZvaWQJCQkJCVNldFBsYXRlUmVjdChjb25zdCBDUERGX1JlY3QgJiByZWN0KXttX3JjUGxhdGUgPSByZWN0O30KCUNQREZfUmVjdAkJCQkJCUdldFBsYXRlUmVjdCgpIGNvbnN0e3JldHVybiBtX3JjUGxhdGU7fQoJdm9pZAkJCQkJCQlTZXRDb250ZW50UmVjdChjb25zdCBDTFNUX1JlY3QgJiByZWN0KXttX3JjQ29udGVudCA9IHJlY3Q7fQoJQ0xTVF9SZWN0CQkJCQkJR2V0Q29udGVudFJlY3QoKSBjb25zdHtyZXR1cm4gbV9yY0NvbnRlbnQ7fQoJQ1BERl9Qb2ludAkJCQkJCUdldEJUUG9pbnQoKSBjb25zdHtyZXR1cm4gQ1BERl9Qb2ludChtX3JjUGxhdGUubGVmdCxtX3JjUGxhdGUudG9wKTt9CglDUERGX1BvaW50CQkJCQkJR2V0RVRQb2ludCgpIGNvbnN0e3JldHVybiBDUERGX1BvaW50KG1fcmNQbGF0ZS5yaWdodCxtX3JjUGxhdGUuYm90dG9tKTt9CnB1YmxpYzoKCUNQREZfUG9pbnQJCQkJCQlJbm5lclRvT3V0ZXIoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50KSBjb25zdHtyZXR1cm4gQ1BERl9Qb2ludChwb2ludC54ICsgR2V0QlRQb2ludCgpLngsR2V0QlRQb2ludCgpLnkgLSBwb2ludC55KTt9CglDUERGX1BvaW50CQkJCQkJT3V0ZXJUb0lubmVyKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3R7cmV0dXJuIENQREZfUG9pbnQocG9pbnQueCAtIEdldEJUUG9pbnQoKS54LEdldEJUUG9pbnQoKS55IC0gcG9pbnQueSk7fQoJQ1BERl9SZWN0CQkJCQkJSW5uZXJUb091dGVyKGNvbnN0IENMU1RfUmVjdCAmIHJlY3QpIGNvbnN0e0NQREZfUG9pbnQgcHRMZWZ0VG9wID0gSW5uZXJUb091dGVyKENQREZfUG9pbnQocmVjdC5sZWZ0LHJlY3QudG9wKSk7CgkJCQkJCQkJCQkJCQkJCQkJCQlDUERGX1BvaW50IHB0UmlnaHRCb3R0b20gPSBJbm5lclRvT3V0ZXIoQ1BERl9Qb2ludChyZWN0LnJpZ2h0LHJlY3QuYm90dG9tKSk7CgkJCQkJCQkJCQkJCQkJCQkJCQlyZXR1cm4gQ1BERl9SZWN0KHB0TGVmdFRvcC54LHB0UmlnaHRCb3R0b20ueSxwdFJpZ2h0Qm90dG9tLngscHRMZWZ0VG9wLnkpO30KCUNMU1RfUmVjdAkJCQkJCU91dGVyVG9Jbm5lcihjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdHtDUERGX1BvaW50IHB0TGVmdFRvcCA9IE91dGVyVG9Jbm5lcihDUERGX1BvaW50KHJlY3QubGVmdCxyZWN0LnRvcCkpOwoJCQkJCQkJCQkJCQkJCQkJCQkJQ1BERl9Qb2ludCBwdFJpZ2h0Qm90dG9tID0gT3V0ZXJUb0lubmVyKENQREZfUG9pbnQocmVjdC5yaWdodCxyZWN0LmJvdHRvbSkpOwoJCQkJCQkJCQkJCQkJCQkJCQkJcmV0dXJuIENMU1RfUmVjdChwdExlZnRUb3AueCxwdExlZnRUb3AueSxwdFJpZ2h0Qm90dG9tLngscHRSaWdodEJvdHRvbS55KTt9CnByaXZhdGU6CglDUERGX1JlY3QJCQkJCQltX3JjUGxhdGU7IAkKCUNMU1RfUmVjdAkJCQkJCW1fcmNDb250ZW50OwkJLy9wb3NpdGl2ZSBmb3JldmVyIQp9OwoKdGVtcGxhdGU8Y2xhc3MgVFlQRT4gY2xhc3MgQ0xTVF9BcnJheVRlbXBsYXRlIDogcHVibGljIENGWF9BcnJheVRlbXBsYXRlPFRZUEU+CnsKcHVibGljOgkKCUZYX0JPT0wgSXNFbXB0eSgpIHsgcmV0dXJuIENGWF9BcnJheVRlbXBsYXRlPFRZUEU+OjpHZXRTaXplKCkgPD0gMDsgfQoJVFlQRSBHZXRBdChGWF9JTlQzMiBuSW5kZXgpIGNvbnN0IHsgaWYgKG5JbmRleCA+PSAwICYmIG5JbmRleCA8IENGWF9BcnJheVRlbXBsYXRlPFRZUEU+OjpHZXRTaXplKCkpIHJldHVybiBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6R2V0QXQobkluZGV4KTsgcmV0dXJuIE5VTEw7fQoJdm9pZCBSZW1vdmVBdChGWF9JTlQzMiBuSW5kZXgpe2lmIChuSW5kZXggPj0gMCAmJiBuSW5kZXggPCBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6R2V0U2l6ZSgpKSBDRlhfQXJyYXlUZW1wbGF0ZTxUWVBFPjo6UmVtb3ZlQXQobkluZGV4KTt9Cn07CgpjbGFzcyBDRlhfTGlzdCA6IHByb3RlY3RlZCBDRlhfTGlzdENvbnRhaW5lciAsIHB1YmxpYyBJRlhfTGlzdAp7CnB1YmxpYzoKCUNGWF9MaXN0KCk7Cgl2aXJ0dWFsIH5DRlhfTGlzdCgpOwoKcHVibGljOgoJdmlydHVhbCB2b2lkCQkJCQlTZXRGb250TWFwKElGWF9FZGl0X0ZvbnRNYXAgKiBwRm9udE1hcCk7Cgl2aXJ0dWFsIHZvaWQJCQkJCVNldEZvbnRTaXplKEZYX0ZMT0FUIGZGb250U2l6ZSk7CgoJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0UGxhdGVSZWN0KCkgY29uc3Q7Cgl2aXJ0dWFsIENQREZfUmVjdAkJCQlHZXRDb250ZW50UmVjdCgpIGNvbnN0OwoKCXZpcnR1YWwgRlhfRkxPQVQJCQkJR2V0Rm9udFNpemUoKSBjb25zdDsKCXZpcnR1YWwgSUZYX0VkaXQqCQkJCUdldEl0ZW1FZGl0KEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7Cgl2aXJ0dWFsIEZYX0lOVDMyCQkJCUdldENvdW50KCkgY29uc3Q7Cgl2aXJ0dWFsIEZYX0JPT0wJCQkJCUlzSXRlbVNlbGVjdGVkKEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7Cgl2aXJ0dWFsIEZYX0ZMT0FUCQkJCUdldEZpcnN0SGVpZ2h0KCkgY29uc3Q7CgkKCXZpcnR1YWwgdm9pZAkJCQkJU2V0TXVsdGlwbGVTZWwoRlhfQk9PTCBiTXVsdGlwbGUpOwoJdmlydHVhbCBGWF9CT09MCQkJCQlJc011bHRpcGxlU2VsKCkgY29uc3Q7CQoJdmlydHVhbCBGWF9CT09MCQkJCQlJc1ZhbGlkKEZYX0lOVDMyIG5JdGVtSW5kZXgpIGNvbnN0OwoJdmlydHVhbCBGWF9JTlQzMgkJCQlGaW5kTmV4dChGWF9JTlQzMiBuSW5kZXgsRlhfV0NIQVIgbkNoYXIpIGNvbnN0OwkKCnByb3RlY3RlZDoKCXZpcnR1YWwgdm9pZAkJCQkJRW1wdHkoKTsKCgl2b2lkCQkJCQkJCUFkZEl0ZW0oRlhfTFBDV1NUUiBzdHIpOwoJdmlydHVhbCB2b2lkCQkJCQlSZUFycmFuZ2UoRlhfSU5UMzIgbkl0ZW1JbmRleCk7CQoKCXZpcnR1YWwgQ1BERl9SZWN0CQkJCUdldEl0ZW1SZWN0KEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7CQoJQ0ZYX1dpZGVTdHJpbmcJCQkJCUdldEl0ZW1UZXh0KEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7CgoJdm9pZAkJCQkJCQlTZXRJdGVtU2VsZWN0KEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYlNlbGVjdGVkKTsKCXZvaWQJCQkJCQkJU2V0SXRlbUNhcmV0KEZYX0lOVDMyIG5JdGVtSW5kZXgsIEZYX0JPT0wgYkNhcmV0KTsKCgl2aXJ0dWFsIEZYX0lOVDMyCQkJCUdldEl0ZW1JbmRleChjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0OwkJCglGWF9JTlQzMgkJCQkJCUdldEZpcnN0U2VsZWN0ZWQoKSBjb25zdDsKCUZYX0lOVDMyCQkJCQkJR2V0TGFzdFNlbGVjdGVkKCkgY29uc3Q7CglGWF9XQ0hBUgkJCQkJCVRvdXBwZXIoRlhfV0NIQVIgYykgY29uc3Q7CgkJCnByaXZhdGU6CglDTFNUX0FycmF5VGVtcGxhdGU8Q0ZYX0xpc3RJdGVtKj4JbV9hTGlzdEl0ZW1zOwoJRlhfRkxPQVQJCQkJCQkJbV9mRm9udFNpemU7CglJRlhfRWRpdF9Gb250TWFwKgkJCQkJbV9wRm9udE1hcDsKCUZYX0JPT0wJCQkJCQkJCW1fYk11bHRpcGxlOwkKfTsKCnN0cnVjdCBDUExTVF9TZWxlY3RfSXRlbQp7CglDUExTVF9TZWxlY3RfSXRlbShGWF9JTlQzMiBuSXRlbUluZGV4LEZYX0lOVDMyIG5TdGF0ZSkKCXsKCQl0aGlzLT5uSXRlbUluZGV4ID0gbkl0ZW1JbmRleDsKCQl0aGlzLT5uU3RhdGUgPSBuU3RhdGU7Cgl9CgoJRlhfSU5UMzIJCW5JdGVtSW5kZXg7CglGWF9JTlQzMgkJblN0YXRlOyAvLzA6bm9ybWFsIHNlbGVjdCAtMTp0byBkZXNlbGVjdCAxOiB0byBzZWxlY3QKfTsKCmNsYXNzIENQTFNUX1NlbGVjdAp7CnB1YmxpYzoKCUNQTFNUX1NlbGVjdCgpOwoJdmlydHVhbCB+Q1BMU1RfU2VsZWN0KCk7CgpwdWJsaWM6Cgl2b2lkCQkJCQkJCUFkZChGWF9JTlQzMiBuSXRlbUluZGV4KTsKCXZvaWQJCQkJCQkJQWRkKEZYX0lOVDMyIG5CZWdpbkluZGV4LCBGWF9JTlQzMiBuRW5kSW5kZXgpOwoJdm9pZAkJCQkJCQlTdWIoRlhfSU5UMzIgbkl0ZW1JbmRleCk7Cgl2b2lkCQkJCQkJCVN1YihGWF9JTlQzMiBuQmVnaW5JbmRleCwgRlhfSU5UMzIgbkVuZEluZGV4KTsKCUZYX0JPT0wJCQkJCQkJSXNFeGlzdChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdDsKCUZYX0lOVDMyCQkJCQkJRmluZChGWF9JTlQzMiBuSXRlbUluZGV4KSBjb25zdDsKCUZYX0lOVDMyCQkJCQkJR2V0Q291bnQoKSBjb25zdDsKCUZYX0lOVDMyCQkJCQkJR2V0SXRlbUluZGV4KEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7CglGWF9JTlQzMgkJCQkJCUdldFN0YXRlKEZYX0lOVDMyIG5JbmRleCkgY29uc3Q7Cgl2b2lkCQkJCQkJCURvbmUoKTsKCXZvaWQJCQkJCQkJRGVzZWxlY3RBbGwoKTsKCnByaXZhdGU6CglDRlhfQXJyYXlUZW1wbGF0ZTxDUExTVF9TZWxlY3RfSXRlbSo+CW1fYUl0ZW1zOwp9OwoKY2xhc3MgQ0ZYX0xpc3RDdHJsIDogcHVibGljIENGWF9MaXN0CnsKcHVibGljOgoJQ0ZYX0xpc3RDdHJsKCk7Cgl2aXJ0dWFsIH5DRlhfTGlzdEN0cmwoKTsKCnB1YmxpYzoKCXZvaWQJCQkJCQkJU2V0Tm90aWZ5KElGWF9MaXN0X05vdGlmeSAqIHBOb3RpZnkpOwoKCXZvaWQJCQkJCQkJT25Nb3VzZURvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOwoJdm9pZAkJCQkJCQlPbk1vdXNlTW92ZShjb25zdCBDUERGX1BvaW50ICYgcG9pbnQsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7Cgl2b2lkCQkJCQkJCU9uVktfVVAoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7Cgl2b2lkCQkJCQkJCU9uVktfRE9XTihGWF9CT09MIGJTaGlmdCxGWF9CT09MIGJDdHJsKTsKCXZvaWQJCQkJCQkJT25WS19MRUZUKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOwoJdm9pZAkJCQkJCQlPblZLX1JJR0hUKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOwoJdm9pZAkJCQkJCQlPblZLX0hPTUUoRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7Cgl2b2lkCQkJCQkJCU9uVktfRU5EKEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOwoJdm9pZAkJCQkJCQlPblZLKEZYX0lOVDMyIG5JdGVtSW5kZXgsRlhfQk9PTCBiU2hpZnQsRlhfQk9PTCBiQ3RybCk7CglGWF9CT09MCQkJCQkJCU9uQ2hhcihGWF9XT1JEIG5DaGFyLEZYX0JPT0wgYlNoaWZ0LEZYX0JPT0wgYkN0cmwpOwoKCXZpcnR1YWwgQ1BERl9Qb2ludAkJCQlJblRvT3V0KGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3Q7Cgl2aXJ0dWFsIENQREZfUG9pbnQJCQkJT3V0VG9Jbihjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpIGNvbnN0OwoJdmlydHVhbCBDUERGX1JlY3QJCQkJSW5Ub091dChjb25zdCBDUERGX1JlY3QgJiByZWN0KSBjb25zdDsKCXZpcnR1YWwgQ1BERl9SZWN0CQkJCU91dFRvSW4oY29uc3QgQ1BERl9SZWN0ICYgcmVjdCkgY29uc3Q7CgoJdmlydHVhbCB2b2lkCQkJCQlTZXRQbGF0ZVJlY3QoY29uc3QgQ1BERl9SZWN0ICYgcmVjdCk7Cgl2b2lkCQkJCQkJCVNldFNjcm9sbFBvcyhjb25zdCBDUERGX1BvaW50ICYgcG9pbnQpOwoJdm9pZAkJCQkJCQlTY3JvbGxUb0xpc3RJdGVtKEZYX0lOVDMyIG5JdGVtSW5kZXgpOwoJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0SXRlbVJlY3QoRlhfSU5UMzIgbkluZGV4KSBjb25zdDsKCUZYX0lOVDMyCQkJCQkJR2V0Q2FyZXQoKSBjb25zdCB7cmV0dXJuIG1fbkNhcmV0SW5kZXg7fQoJRlhfSU5UMzIJCQkJCQlHZXRTZWxlY3QoKSBjb25zdCB7cmV0dXJuIG1fblNlbEl0ZW07fQkKCUZYX0lOVDMyCQkJCQkJR2V0VG9wSXRlbSgpIGNvbnN0OwoJdmlydHVhbCBDUERGX1JlY3QJCQkJR2V0Q29udGVudFJlY3QoKSBjb25zdDsKCXZpcnR1YWwgRlhfSU5UMzIJCQkJR2V0SXRlbUluZGV4KGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCkgY29uc3Q7CgoJdm9pZAkJCQkJCQlBZGRTdHJpbmcoRlhfTFBDV1NUUiBzdHJpbmcpOwoJdm9pZAkJCQkJCQlTZXRUb3BJdGVtKEZYX0lOVDMyIG5JbmRleCk7CQoJdm9pZAkJCQkJCQlTZWxlY3QoRlhfSU5UMzIgbkl0ZW1JbmRleCk7Cgl2aXJ0dWFsIHZvaWQJCQkJCVNldENhcmV0KEZYX0lOVDMyIG5JdGVtSW5kZXgpOwoJdmlydHVhbCB2b2lkCQkJCQlFbXB0eSgpOwoJdmlydHVhbCB2b2lkCQkJCQlDYW5jZWwoKTsKCUNGWF9XaWRlU3RyaW5nCQkJCQlHZXRUZXh0KCkgY29uc3Q7Cgpwcml2YXRlOgoJdm9pZAkJCQkJCQlTZXRNdWx0aXBsZVNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4LCBGWF9CT09MIGJTZWxlY3RlZCk7Cgl2b2lkCQkJCQkJCVNldFNpbmdsZVNlbGVjdChGWF9JTlQzMiBuSXRlbUluZGV4KTsKCXZvaWQJCQkJCQkJSW52YWxpZGF0ZUl0ZW0oRlhfSU5UMzIgbkl0ZW1JbmRleCk7Cgl2b2lkCQkJCQkJCVNlbGVjdEl0ZW1zKCk7CglGWF9CT09MCQkJCQkJCUlzSXRlbVZpc2libGUoRlhfSU5UMzIgbkl0ZW1JbmRleCkgY29uc3Q7CQkKCXZvaWQJCQkJCQkJU2V0U2Nyb2xsSW5mbygpOwoJdm9pZAkJCQkJCQlTZXRTY3JvbGxQb3NZKEZYX0ZMT0FUIGZ5KTsKCXZpcnR1YWwgdm9pZAkJCQkJUmVBcnJhbmdlKEZYX0lOVDMyIG5JdGVtSW5kZXgpOwkKCnByaXZhdGU6CglJRlhfTGlzdF9Ob3RpZnkqCQkJCW1fcE5vdGlmeTsKCUZYX0JPT0wJCQkJCQkJbV9iTm90aWZ5RmxhZzsKCUNQREZfUG9pbnQJCQkJCQltX3B0U2Nyb2xsUG9zOwoJQ1BMU1RfU2VsZWN0CQkJCQltX2FTZWxJdGVtczsJLy9mb3IgbXVsdGlwbGUKCUZYX0lOVDMyCQkJCQkJbV9uU2VsSXRlbTsJCS8vZm9yIHNpbmdsZQoJRlhfSU5UMzIJCQkJCQltX25Gb290SW5kZXg7CS8vZm9yIG11bHRpcGxlCglGWF9CT09MCQkJCQkJCW1fYkN0cmxTZWw7CQkvL2ZvciBtdWx0aXBsZQoJRlhfSU5UMzIJCQkJCQltX25DYXJldEluZGV4OwkvL2ZvciBtdWx0aXBsZQp9OwoKI2VuZGlmCgo=