Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KIAovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQoKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BERldpbmRvdy5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1duZC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xpc3RDdHJsLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTm90ZS5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0xhYmVsLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdC5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1V0aWxzLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ2FyZXQuaCIKCiNkZWZpbmUgUE9QVVBfSVRFTV9IRUFEX0JPVFRPTQkJCQkJMy4wZgojZGVmaW5lIFBPUFVQX0lURU1fQk9UVE9NV0lEVEgJCQkJCTEuMGYKI2RlZmluZSBQT1BVUF9JVEVNX1NJREVNQVJHSU4JCQkJCTMuMGYKI2RlZmluZSBQT1BVUF9JVEVNX1NQQUNFCQkJCQkJNC4wZgojZGVmaW5lIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQJCQkJCTIuMGYKI2RlZmluZSBQT1BVUF9JVEVNX0JPUkRFUkNPTE9SCQkJCQlDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDgwLzI1NS4wZiwgODAvMjU1LjBmLCA4MC8yNTUuMGYpCgojZGVmaW5lIElzRmxvYXRaZXJvKGYpCQkJCQkJKChmKSA8IDAuMDAwMSAmJiAoZikgPiAtMC4wMDAxKQojZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsZmIpCQkJCSgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQojZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLGZiKQkJCQkoKGZhKSA8IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkKI2RlZmluZSBJc0Zsb2F0RXF1YWwoZmEsZmIpCQkJCQlJc0Zsb2F0WmVybygoZmEpLShmYikpCgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfT3B0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVfT3B0aW9uczo6Q1BXTF9Ob3RlX09wdGlvbnMoKSA6IG1fcFRleHQoTlVMTCkKewp9CgpDUFdMX05vdGVfT3B0aW9uczo6fkNQV0xfTm90ZV9PcHRpb25zKCkKewp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0Q29sb3IoY29uc3QgQ1BXTF9Db2xvciAmIGNvbG9yKQp7CglDUFdMX1duZDo6U2V0VGV4dENvbG9yKGNvbG9yKTsKCglpZiAobV9wVGV4dCkKCQltX3BUZXh0LT5TZXRUZXh0Q29sb3IoY29sb3IpOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpSZVBvc0NoaWxkV25kKCkKewoJaWYgKHRoaXMtPklzVmFsaWQoKSkKCXsKCQlBU1NFUlQobV9wVGV4dCAhPSBOVUxMKTsKCgkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKCQlpZiAocmNDbGllbnQuV2lkdGgoKSA+IDE1LjBmKQoJCXsKCQkJcmNDbGllbnQucmlnaHQgLT0gMTUuMGY7CgkJCW1fcFRleHQtPk1vdmUocmNDbGllbnQsIFRSVUUsIEZBTFNFKTsKCQkJbV9wVGV4dC0+U2V0VmlzaWJsZShUUlVFKTsKCQl9CgkJZWxzZQoJCXsKCQkJbV9wVGV4dC0+TW92ZShDUERGX1JlY3QoMCwwLDAsMCksIFRSVUUsIEZBTFNFKTsKCQkJbV9wVGV4dC0+U2V0VmlzaWJsZShGQUxTRSk7CgkJfQoJfQp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKewoJbV9wVGV4dCA9IG5ldyBDUFdMX0xhYmVsOwoJUFdMX0NSRUFURVBBUkFNIHRjcCA9IGNwOwoJdGNwLnBQYXJlbnRXbmQgPSB0aGlzOwoJdGNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRTsKCW1fcFRleHQtPkNyZWF0ZSh0Y3ApOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkKewoJbV9wVGV4dC0+U2V0VGV4dChzVGV4dC5jX3N0cigpKTsKfQoKdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpCnsKCUNQV0xfV25kOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlKTsKCglDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CglyY0NsaWVudC5sZWZ0ID0gcmNDbGllbnQucmlnaHQgLSAxNS4wZjsKCglDUERGX1BvaW50IHB0Q2VudGVyID0gQ1BERl9Qb2ludCgocmNDbGllbnQubGVmdCArIHJjQ2xpZW50LnJpZ2h0KSAqIDAuNWYsIChyY0NsaWVudC50b3AgKyByY0NsaWVudC5ib3R0b20pICogMC41Zik7CgoJQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCAtIDIuMGYsIHB0Q2VudGVyLnkgKyAyLjBmICogMC41Zik7CglDUERGX1BvaW50IHB0MihwdENlbnRlci54ICsgMi4wZiwgcHRDZW50ZXIueSArIDIuMGYgKiAwLjVmKTsKCUNQREZfUG9pbnQgcHQzKHB0Q2VudGVyLngsIHB0Q2VudGVyLnkgLSAzLjBmICogMC41Zik7CgoJQ0ZYX1BhdGhEYXRhIHBhdGg7CgoJcGF0aC5TZXRQb2ludENvdW50KDQpOwoJcGF0aC5TZXRQb2ludCgwLCBwdDEueCwgcHQxLnksIEZYUFRfTU9WRVRPKTsKCXBhdGguU2V0UG9pbnQoMSwgcHQyLngsIHB0Mi55LCBGWFBUX0xJTkVUTyk7CglwYXRoLlNldFBvaW50KDIsIHB0My54LCBwdDMueSwgRlhQVF9MSU5FVE8pOwoJcGF0aC5TZXRQb2ludCgzLCBwdDEueCwgcHQxLnksIEZYUFRfTElORVRPKTsKCglwRGV2aWNlLT5EcmF3UGF0aCgmcGF0aCwgcFVzZXIyRGV2aWNlLCBOVUxMLCAKCQlDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSxHZXRUcmFuc3BhcmVuY3koKSksIAoJCTAsIEZYRklMTF9BTFRFUk5BVEUpOwp9CgpDUERGX1JlY3QgQ1BXTF9Ob3RlX09wdGlvbnM6OkdldENvbnRlbnRSZWN0KCkgY29uc3QKewoJQVNTRVJUKG1fcFRleHQgIT0gTlVMTCk7CgoJQ1BERl9SZWN0IHJjVGV4dCA9IG1fcFRleHQtPkdldENvbnRlbnRSZWN0KCk7CglyY1RleHQucmlnaHQgKz0gMTUuMGY7CglyZXR1cm4gcmNUZXh0Owp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9FZGl0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlX0VkaXQ6OkNQV0xfTm90ZV9FZGl0KCkgOiBtX2JFbmFibGVOb3RpZnkoVFJVRSksCgltX2ZPbGRJdGVtSGVpZ2h0KDAuMGYpLAoJbV9iU2l6ZUNoYW5nZWQoRkFMU0UpLAoJbV9mT2xkTWluKDAuMGYpLAoJbV9mT2xkTWF4KDAuMGYpCnsKfQoKQ1BXTF9Ob3RlX0VkaXQ6On5DUFdMX05vdGVfRWRpdCgpCnsKfQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6UmVQb3NDaGlsZFduZCgpCnsKCW1fYkVuYWJsZU5vdGlmeSA9IEZBTFNFOwkKCUNQV0xfRWRpdDo6UmVQb3NDaGlsZFduZCgpOwoJbV9iRW5hYmxlTm90aWZ5ID0gVFJVRTsKCgltX2ZPbGRJdGVtSGVpZ2h0ID0gdGhpcy0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKfQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6U2V0VGV4dChGWF9MUENXU1RSIGNzVGV4dCkKewoJbV9iRW5hYmxlTm90aWZ5ID0gRkFMU0U7CglDUFdMX0VkaXQ6OlNldFRleHQoY3NUZXh0KTsKCW1fYkVuYWJsZU5vdGlmeSA9IFRSVUU7CQoJbV9mT2xkSXRlbUhlaWdodCA9IHRoaXMtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uU2V0Rm9jdXMoKQp7CgltX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsJCglDUFdMX0VkaXQ6Ok9uU2V0Rm9jdXMoKTsKCW1fYkVuYWJsZU5vdGlmeSA9IFRSVUU7CQoKCXRoaXMtPkVuYWJsZVNwZWxsQ2hlY2soVFJVRSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uS2lsbEZvY3VzKCkKewoJdGhpcy0+RW5hYmxlU3BlbGxDaGVjayhGQUxTRSk7CgoJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgl7CgkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKCQl7CgkJCUFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CgoJCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcEdyYW5kOwoKCQkJcE5vdGVJdGVtLT5PbkNvbnRlbnRzVmFsaWRhdGUoKTsKCQl9Cgl9CgoJQ1BXTF9FZGl0OjpPbktpbGxGb2N1cygpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwgRlhfRFdPUkQgbXNnLCBGWF9JTlRQVFIgd1BhcmFtLCBGWF9JTlRQVFIgbFBhcmFtKQp7CglpZiAobV9iRW5hYmxlTm90aWZ5KQoJewoJCWlmICh3UGFyYW0gPT0gU0JUX1ZTQ1JPTEwpCgkJewoJCQlzd2l0Y2ggKG1zZykKCQkJewoJCQljYXNlIFBOTV9TRVRTQ1JPTExJTkZPOgkKCQkJCWlmIChQV0xfU0NST0xMX0lORk8qIHBJbmZvID0gKFBXTF9TQ1JPTExfSU5GTyopbFBhcmFtKQoJCQkJewkKCQkJCQlpZiAoIUlzRmxvYXRFcXVhbChwSW5mby0+ZkNvbnRlbnRNYXgsIG1fZk9sZE1heCkgfHwgCgkJCQkJCSFJc0Zsb2F0RXF1YWwocEluZm8tPmZDb250ZW50TWluLCBtX2ZPbGRNaW4pKQoJCQkJCXsKCQkJCQkJbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwkJCQkKCQkJCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCQkJCQl7CgkJCQkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKCQkJCQkJfQoKCQkJCQkJbV9mT2xkTWF4ID0gcEluZm8tPmZDb250ZW50TWF4OwoJCQkJCQltX2ZPbGRNaW4gPSBwSW5mby0+ZkNvbnRlbnRNaW47CgkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CQkKCX0KCglDUFdMX0VkaXQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwoKCWlmIChtX2JFbmFibGVOb3RpZnkpCgl7CgkJc3dpdGNoIChtc2cpCgkJewoJCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoKCQkJaWYgKFBXTF9DQVJFVF9JTkZPICogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkKCQkJewoJCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKCQkJCW5ld0luZm8uYlZpc2libGUgPSBUUlVFOwoJCQkJbmV3SW5mby5wdEhlYWQgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEhlYWQpOwoJCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOwoKCQkJCWlmIChDUFdMX1duZCAqIHBQYXJlbnQgPSB0aGlzLT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJCXsKCQkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoRlhfSU5UUFRSKSZuZXdJbmZvLCAwKTsKCQkJCX0KCQkJfQoJCQlicmVhazsKCQl9Cgl9Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZV9FZGl0OjpHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKQp7CglpZiAoZkxpbWl0V2lkdGggPiAwKQoJewoJCWlmICghbV9iU2l6ZUNoYW5nZWQpCgkJCXJldHVybiBtX2ZPbGRJdGVtSGVpZ2h0OwoKCQltX2JTaXplQ2hhbmdlZCA9IEZBTFNFOwkKCgkJdGhpcy0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKCQl0aGlzLT5FbmFibGVSZWZyZXNoKEZBTFNFKTsKCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwoKCQkvL0NQREZfUmVjdCByY09sZCA9IHRoaXMtPkdldFdpbmRvd1JlY3QoKTsKCgkJdGhpcy0+TW92ZShDUERGX1JlY3QoMCwwLGZMaW1pdFdpZHRoLDApLCBUUlVFLCBGQUxTRSk7CgkJRlhfRkxPQVQgZlJldCA9IHRoaXMtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CgoJCS8vdGhpcy0+TW92ZShyY09sZCwgVFJVRSwgRkFMU0UpOwoKCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7CgkJdGhpcy0+RW5hYmxlTm90aWZ5KFRSVUUpOwoJCXRoaXMtPkVuYWJsZVJlZnJlc2goVFJVRSk7CgoJCXJldHVybiBmUmV0OwoJfQoKCXJldHVybiAwOwp9CgpGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbUxlZnRNYXJnaW4oKQp7CglyZXR1cm4gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlX0VkaXQ6OkdldEl0ZW1SaWdodE1hcmdpbigpCnsKCXJldHVybiBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfTEJCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKQ1BXTF9Ob3RlX0xCQm94OjpDUFdMX05vdGVfTEJCb3goKQp7Cn0KCkNQV0xfTm90ZV9MQkJveDo6fkNQV0xfTm90ZV9MQkJveCgpCnsKfQoKdm9pZCBDUFdMX05vdGVfTEJCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQp7CglDUERGX1JlY3QgcmNDbGllbnQgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7CgoJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKCWdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CgoJQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsKCglwYXRoQ3Jvc3MuU2V0UG9pbnRDb3VudCg0KTsKCXBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsKCXBhdGhDcm9zcy5TZXRQb2ludCgxLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMiwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQuYm90dG9tICsgcmNDbGllbnQuSGVpZ2h0KCkgKiAwLjVmLCBGWFBUX01PVkVUTyk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQubGVmdCArIHJjQ2xpZW50LldpZHRoKCkgKiAwLjVmLCByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsKCQoJcERldmljZS0+RHJhd1BhdGgoJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCAKCQkwLCBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSx0aGlzLT5HZXRUcmFuc3BhcmVuY3koKSksIEZYRklMTF9BTFRFUk5BVEUpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfUkJCb3ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKQ1BXTF9Ob3RlX1JCQm94OjpDUFdMX05vdGVfUkJCb3goKQp7Cn0KCkNQV0xfTm90ZV9SQkJveDo6fkNQV0xfTm90ZV9SQkJveCgpCnsKfQoKdm9pZCBDUFdMX05vdGVfUkJCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQp7CglDUERGX1JlY3QgcmNDbGllbnQgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7CgoJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKCWdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CgoJQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsKCglwYXRoQ3Jvc3MuU2V0UG9pbnRDb3VudCg0KTsKCXBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQudG9wLCBGWFBUX01PVkVUTyk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CglwYXRoQ3Jvc3MuU2V0UG9pbnQoMiwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LmJvdHRvbSArIHJjQ2xpZW50LkhlaWdodCgpICogMC41ZiwgRlhQVF9NT1ZFVE8pOwoJcGF0aENyb3NzLlNldFBvaW50KDMsIHJjQ2xpZW50LmxlZnQgKyByY0NsaWVudC5XaWR0aCgpICogMC41ZiwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CgkKCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoQ3Jvc3MsIHBVc2VyMkRldmljZSwgJmdzZCwgCgkJMCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLCBGWEZJTExfQUxURVJOQVRFKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9JY29uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9JY29uOjpDUFdMX05vdGVfSWNvbigpIDogbV9uVHlwZSgwKQp7Cn0KCkNQV0xfTm90ZV9JY29uOjp+Q1BXTF9Ob3RlX0ljb24oKQp7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0ljb246OlNldEljb25UeXBlKEZYX0lOVDMyIG5UeXBlKQp7CgltX25UeXBlID0gblR5cGU7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0ljb246OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQp7CglDUFdMX1V0aWxzOjpEcmF3SWNvbkFwcFN0cmVhbShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIG1fblR5cGUsIEdldENsaWVudFJlY3QoKSwgCgkJdGhpcy0+R2V0QmFja2dyb3VuZENvbG9yKCksIFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IsIHRoaXMtPkdldFRyYW5zcGFyZW5jeSgpKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9DbG9zZUJveCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVfQ2xvc2VCb3g6OkNQV0xfTm90ZV9DbG9zZUJveCgpIDogbV9iTW91c2VEb3duKEZBTFNFKQp7Cn0KCkNQV0xfTm90ZV9DbG9zZUJveDo6fkNQV0xfTm90ZV9DbG9zZUJveCgpCnsKfQoKdm9pZCBDUFdMX05vdGVfQ2xvc2VCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLCBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKQp7CglDUFdMX0J1dHRvbjo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7CgoJQ1BERl9SZWN0IHJjQ2xpZW50ID0gdGhpcy0+R2V0Q2xpZW50UmVjdCgpOwoJcmNDbGllbnQgPSBDUFdMX1V0aWxzOjpEZWZsYXRlUmVjdChyY0NsaWVudCwgMi4wZik7CgoJQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKCWdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CgoJQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsKCglpZiAobV9iTW91c2VEb3duKQoJewoJCXJjQ2xpZW50LmxlZnQgKz0gMC41ZjsKCQlyY0NsaWVudC5yaWdodCArPSAwLjVmOwoJCXJjQ2xpZW50LnRvcCAtPSAwLjVmOwoJCXJjQ2xpZW50LmJvdHRvbSAtPSAwLjVmOwoJfQoKCXBhdGhDcm9zcy5TZXRQb2ludENvdW50KDQpOwoJcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9NT1ZFVE8pOwoJcGF0aENyb3NzLlNldFBvaW50KDEsIHJjQ2xpZW50LnJpZ2h0LCByY0NsaWVudC50b3AsIEZYUFRfTElORVRPKTsKCXBhdGhDcm9zcy5TZXRQb2ludCgyLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsKCXBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CgkKCXBEZXZpY2UtPkRyYXdQYXRoKCZwYXRoQ3Jvc3MsIHBVc2VyMkRldmljZSwgJmdzZCwgCgkJMCwgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksdGhpcy0+R2V0VHJhbnNwYXJlbmN5KCkpLCBGWEZJTExfQUxURVJOQVRFKTsKfQoKRlhfQk9PTCBDUFdMX05vdGVfQ2xvc2VCb3g6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJU2V0Qm9yZGVyU3R5bGUoUEJTX0lOU0VUKTsKCUludmFsaWRhdGVSZWN0KE5VTEwpOwoKCW1fYk1vdXNlRG93biA9IFRSVUU7CgoJcmV0dXJuIENQV0xfQnV0dG9uOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKTsKfQoKRlhfQk9PTAlDUFdMX05vdGVfQ2xvc2VCb3g6Ok9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCnsKCW1fYk1vdXNlRG93biA9IEZBTFNFOwoKCVNldEJvcmRlclN0eWxlKFBCU19CRVZFTEVEKTsKCUludmFsaWRhdGVSZWN0KE5VTEwpOwoKCXJldHVybiBDUFdMX0J1dHRvbjo6T25MQnV0dG9uVXAocG9pbnQsbkZsYWcpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0NvbnRlbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9Db250ZW50czo6Q1BXTF9Ob3RlX0NvbnRlbnRzKCkgOiBtX3BFZGl0KE5VTEwpCnsKfQoKQ1BXTF9Ob3RlX0NvbnRlbnRzOjp+Q1BXTF9Ob3RlX0NvbnRlbnRzKCkKewp9CgpDRlhfQnl0ZVN0cmluZyBDUFdMX05vdGVfQ29udGVudHM6OkdldENsYXNzTmFtZSgpIGNvbnN0CnsKCXJldHVybiAiQ1BXTF9Ob3RlX0NvbnRlbnRzIjsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSAmIGNwKQp7CgltX3BFZGl0ID0gbmV3IENQV0xfTm90ZV9FZGl0OwoJUFdMX0NSRUFURVBBUkFNIGVjcCA9IGNwOwoJZWNwLnBQYXJlbnRXbmQgPSB0aGlzOwoJZWNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19NVUxUSUxJTkUgfCBQRVNfQVVUT1JFVFVSTiB8IFBFU19URVhUT1ZFUkZMT1cgfCBQRVNfVU5ETyB8IFBFU19TUEVMTENIRUNLOwoKCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CgltX3BFZGl0LT5DcmVhdGUoZWNwKTsKCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OlNldFRleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUZXh0KQp7CglpZiAobV9wRWRpdCkKCXsKCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwoJCW1fcEVkaXQtPlNldFRleHQoc1RleHQuY19zdHIoKSk7CgkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwoJCU9uTm90aWZ5KG1fcEVkaXQsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwoJfQp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVfQ29udGVudHM6OkdldFRleHQoKSBjb25zdAp7CglpZiAobV9wRWRpdCkKCQlyZXR1cm4gbV9wRWRpdC0+R2V0VGV4dCgpOwoKCXJldHVybiBMIiI7Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6Q3JlYXRlU3ViSXRlbSgpCnsKCUNQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IG5ldyBDUFdMX05vdGVJdGVtOwoJUFdMX0NSRUFURVBBUkFNIGljcCA9IHRoaXMtPkdldENyZWF0aW9uUGFyYW0oKTsKCWljcC5wUGFyZW50V25kID0gdGhpczsKCWljcC5kd0ZsYWdzID0gIFBXU19DSElMRCB8IFBXU19WSVNJQkxFIHwgUFdTX0JBQ0tHUk9VTkQ7CglwTm90ZUl0ZW0tPkNyZWF0ZShpY3ApOwoKCXBOb3RlSXRlbS0+T25DcmVhdGVOb3RlSXRlbSgpOwoJCglwTm90ZUl0ZW0tPlJlc2V0U3ViamVjdE5hbWUobV9hQ2hpbGRyZW4uR2V0U2l6ZSgpIC0gMSk7CgoJRlhfU1lTVEVNVElNRSBzdDsKCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gdGhpcy0+R2V0U3lzdGVtSGFuZGxlcigpKQoJCXN0ID0gcFNILT5HZXRMb2NhbFRpbWUoKTsKCXBOb3RlSXRlbS0+U2V0RGF0ZVRpbWUoc3QpOwoKCXBOb3RlSXRlbS0+U2V0Q29udGVudHMoTCIiKTsKCgl0aGlzLT5Pbk5vdGlmeShwTm90ZUl0ZW0sIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwkKCglyZXR1cm4gcE5vdGVJdGVtOwp9CgpGWF9JTlQzMiBDUFdMX05vdGVfQ29udGVudHM6OkNvdW50U3ViSXRlbXMoKSBjb25zdAp7CglyZXR1cm4gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpIC0gMTsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRTdWJJdGVtcyhGWF9JTlQzMiBpbmRleCkgY29uc3QKewoJRlhfSU5UMzIgbkluZGV4ID0gaW5kZXggKyAxOwoKCWlmIChuSW5kZXggPiAwICYmIG5JbmRleCA8IG1fYUNoaWxkcmVuLkdldFNpemUoKSkKCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KG5JbmRleCkpCgkJewoJCQlBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwoJCQlDUFdMX05vdGVJdGVtKiBwSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7CgkJCXJldHVybiBwSXRlbTsKCQl9CglyZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkRlbGV0ZVN1Ykl0ZW0oSVBXTF9Ob3RlSXRlbSogcE5vdGVJdGVtKQp7CglGWF9JTlQzMiBuSW5kZXggPSB0aGlzLT5HZXRJdGVtSW5kZXgoKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSk7CgoJaWYgKG5JbmRleCA+IDApCgl7CgkJaWYgKENQV0xfTm90ZUl0ZW0qIHBQV0xOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwTm90ZUl0ZW0pCgkJewoJCQlwUFdMTm90ZUl0ZW0tPktpbGxGb2N1cygpOwoJCQlwUFdMTm90ZUl0ZW0tPkRlc3Ryb3koKTsKCQkJZGVsZXRlIHBQV0xOb3RlSXRlbTsKCQl9CgoJCWZvciAoRlhfSU5UMzIgaT1uSW5kZXgsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCgkJewoJCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQoJCQl7CgkJCQlBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwoJCQkJQ1BXTF9Ob3RlSXRlbSogcEl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOwoJCQkJcEl0ZW0tPlJlc2V0U3ViamVjdE5hbWUoaSk7CgkJCX0KCQl9CgoJCXRoaXMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwoJfQp9CgpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVfQ29udGVudHM6OkdldEhpdE5vdGVJdGVtKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQp7CglDUERGX1BvaW50IHB0ID0gdGhpcy0+UGFyZW50VG9DaGlsZChwb2ludCk7CgoJZm9yIChGWF9JTlQzMiBpPTAsc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCgl7CgkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKCQl7CgkJCWlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikKCQkJewoJCQkJQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKCQkJCWlmIChJUFdMX05vdGVJdGVtKiBwUmV0ID0gcE5vdGVJdGVtLT5HZXRIaXROb3RlSXRlbShwdCkpCgkJCQkJcmV0dXJuIHBSZXQ7CgkJCX0KCQl9Cgl9CglyZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pCnsKCXN3aXRjaCAobXNnKQoJewoJY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOgoJCXsKCQkJRlhfSU5UMzIgbkluZGV4ID0gdGhpcy0+R2V0SXRlbUluZGV4KHBXbmQpOwoJCQlpZiAobkluZGV4IDwgMCkgbkluZGV4ID0gMDsKCgkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CQoJCQl0aGlzLT5SZXNldENvbnRlbnQobkluZGV4KTsKCQkJbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwoKCQkJZm9yIChGWF9JTlQzMiBpPW5JbmRleCsxLCBzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKCQkJewoJCQkJaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKCQkJCQlwQ2hpbGQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwoJCQl9CgoJCQlpZiAoQ1BXTF9XbmQgKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgkJCXsKCQkJCXBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwoJCQl9CgkJfQoJCXJldHVybjsKCWNhc2UgUE5NX1NDUk9MTFdJTkRPVzoKCQl0aGlzLT5TZXRTY3JvbGxQb3MoQ1BERl9Qb2ludCgwLjBmLCAqKEZYX0ZMT0FUKilsUGFyYW0pKTsKCQl0aGlzLT5SZXNldEZhY2UoKTsKCQlJbnZhbGlkYXRlUmVjdChOVUxMKTsKCQlyZXR1cm47CQkKCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoKCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQoJCXsKCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CgkJCW5ld0luZm8ucHRIZWFkID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRIZWFkKTsKCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOwoKCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCQl7CgkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoRlhfSU5UUFRSKSZuZXdJbmZvLCAwKTsKCQkJfQoJCX0KCQlyZXR1cm47CgljYXNlIFBOTV9OT1RFUkVTRVQ6CgkJewoJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwkKCQkJdGhpcy0+UmVzZXRDb250ZW50KDApOwoJCQltX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7CgoJCQlmb3IgKEZYX0lOVDMyIGk9MSwgc3o9bV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpPHN6OyBpKyspCgkJCXsKCQkJCWlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpCgkJCQkJcENoaWxkLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCQkJfQkKCgkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CQoJCQl0aGlzLT5SZXNldENvbnRlbnQoMCk7CgkJCW1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKCQl9CgkJcmV0dXJuOwoJfQoKCUNQV0xfV25kOjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsKfQoKRlhfQk9PTAlDUFdMX05vdGVfQ29udGVudHM6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJaWYgKENQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LG5GbGFnKSkgcmV0dXJuIFRSVUU7CgoJaWYgKCFtX3BFZGl0LT5Jc0ZvY3VzZWQoKSkKCXsKCQltX3BFZGl0LT5TZXRGb2N1cygpOwoJfQoKCXJldHVybiBUUlVFOwp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6U2V0RWRpdEZvY3VzKEZYX0JPT0wgYkxhc3QpCnsKCWlmICghbV9wRWRpdC0+SXNGb2N1c2VkKCkpCgl7CgkJbV9wRWRpdC0+U2V0Rm9jdXMoKTsKCQltX3BFZGl0LT5TZXRDYXJldChiTGFzdCA/IG1fcEVkaXQtPkdldFRvdGFsV29yZHMoKSA6IDApOwoJfQp9CgpDUFdMX0VkaXQqIENQV0xfTm90ZV9Db250ZW50czo6R2V0RWRpdCgpIGNvbnN0CnsKCXJldHVybiBtX3BFZGl0Owp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpCnsKCWlmICghYkVuYWJsZWQpCgkJbV9wRWRpdC0+QWRkRmxhZyhQV1NfUkVBRE9OTFkpOwoJZWxzZQoJCW1fcEVkaXQtPlJlbW92ZUZsYWcoUFdTX1JFQURPTkxZKTsKCglmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKCXsKCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQoJCXsKCQkJaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKQoJCQl7CgkJCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOwoJCQkJcE5vdGVJdGVtLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwoJCQl9CgkJfQoJfQp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKQp7CglpZiAoIWJFbmFibGVkKQoJCW1fcEVkaXQtPkFkZEZsYWcoUEVTX05PUkVBRCk7CgllbHNlCgkJbV9wRWRpdC0+UmVtb3ZlRmxhZyhQRVNfTk9SRUFEKTsKCglmb3IgKEZYX0lOVDMyIGk9MCxzej1tX2FDaGlsZHJlbi5HZXRTaXplKCk7IGk8c3o7IGkrKykKCXsKCQlpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQoJCXsKCQkJaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKQoJCQl7CgkJCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOwoJCQkJcE5vdGVJdGVtLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKCQkJfQoJCX0KCX0KfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVJdGVtIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZUl0ZW06OkNQV0xfTm90ZUl0ZW0oKSA6CgltX3BTdWJqZWN0KE5VTEwpLAoJbV9wRGF0ZVRpbWUoTlVMTCksCgltX3BDb250ZW50cyhOVUxMKSwKCW1fcFByaXZhdGVEYXRhKE5VTEwpLAoJbV9zQXV0aG9yKEwiIiksCgltX2ZPbGRJdGVtSGVpZ2h0KDAuMGYpLAoJbV9iU2l6ZUNoYW5nZWQoRkFMU0UpLAoJbV9iQWxsb3dNb2RpZnkoVFJVRSkKewp9CgpDUFdMX05vdGVJdGVtOjp+Q1BXTF9Ob3RlSXRlbSgpCnsKfQoKQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Ob3RlSXRlbTo6R2V0Q2xhc3NOYW1lKCkgY29uc3QKewoJcmV0dXJuICJDUFdMX05vdGVJdGVtIjsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0gJiBjcCkKewoJQ1BXTF9Db2xvciBzVGV4dENvbG9yOwoKCWlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZSh0aGlzLT5HZXRCYWNrZ3JvdW5kQ29sb3IoKSkpCgkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CgllbHNlCgkJc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgoJbV9wU3ViamVjdCA9IG5ldyBDUFdMX0xhYmVsOwoJUFdMX0NSRUFURVBBUkFNIHNjcCA9IGNwOwoJc2NwLnBQYXJlbnRXbmQgPSB0aGlzOwoJc2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19MRUZUIHwgUEVTX1RPUDsKCXNjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKCW1fcFN1YmplY3QtPkNyZWF0ZShzY3ApOwoKCW1fcERhdGVUaW1lID0gbmV3IENQV0xfTGFiZWw7CglQV0xfQ1JFQVRFUEFSQU0gZGNwID0gY3A7CglkY3AucFBhcmVudFduZCA9IHRoaXM7CglkY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX1JJR0hUIHwgUEVTX1RPUDsKCWRjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKCW1fcERhdGVUaW1lLT5DcmVhdGUoZGNwKTsKCgltX3BDb250ZW50cyA9IG5ldyBDUFdMX05vdGVfQ29udGVudHM7CglQV0xfQ1JFQVRFUEFSQU0gY2NwID0gY3A7CgljY3AucFBhcmVudFduZCA9IHRoaXM7CgkvL2NjcC5zQmFja2dyb3VuZENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKCWNjcC5zQmFja2dyb3VuZENvbG9yID0gQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLCAyNDAvMjU1LjBmLCAyNDAvMjU1LjBmLCAyNDAvMjU1LjBmKTsKCWNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQV1NfQkFDS0dST1VORDsKCW1fcENvbnRlbnRzLT5DcmVhdGUoY2NwKTsKCW1fcENvbnRlbnRzLT5TZXRJdGVtU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7CgltX3BDb250ZW50cy0+U2V0VG9wU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7CgltX3BDb250ZW50cy0+U2V0Qm90dG9tU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6UmVQb3NDaGlsZFduZCgpCnsKCWlmICh0aGlzLT5Jc1ZhbGlkKCkpCgl7CgkJQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7CgkJQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOwoJCUFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsKCgkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKCQlDUERGX1JlY3QgcmNTdWJqZWN0ID0gcmNDbGllbnQ7CgkJcmNTdWJqZWN0LmxlZnQgKz0gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKCQlyY1N1YmplY3QudG9wID0gcmNDbGllbnQudG9wOwoJCXJjU3ViamVjdC5yaWdodCA9IFBXTF9NSU4ocmNTdWJqZWN0LmxlZnQgKyBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgKyAxLjBmLCByY0NsaWVudC5yaWdodCk7CgkJcmNTdWJqZWN0LmJvdHRvbSA9IHJjU3ViamVjdC50b3AgLSBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoJCXJjU3ViamVjdC5Ob3JtYWxpemUoKTsKCQltX3BTdWJqZWN0LT5Nb3ZlKHJjU3ViamVjdCwgVFJVRSwgRkFMU0UpOwoJCW1fcFN1YmplY3QtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY1N1YmplY3QpKTsKCgkJQ1BERl9SZWN0IHJjRGF0ZSA9IHJjQ2xpZW50OwoJCXJjRGF0ZS5yaWdodCAtPSBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwoJCXJjRGF0ZS5sZWZ0ID0gUFdMX01BWChyY0RhdGUucmlnaHQgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpIC0gMS4wZiwgcmNTdWJqZWN0LnJpZ2h0KTsKCQlyY0RhdGUuYm90dG9tID0gcmNEYXRlLnRvcCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoJCXJjRGF0ZS5Ob3JtYWxpemUoKTsKCQltX3BEYXRlVGltZS0+TW92ZShyY0RhdGUsIFRSVUUsIEZBTFNFKTsKCQltX3BEYXRlVGltZS0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjRGF0ZSkpOwoKCQlDUERGX1JlY3QgcmNDb250ZW50cyA9IHJjQ2xpZW50OwoJCXJjQ29udGVudHMubGVmdCArPSAxLjBmOwoJCXJjQ29udGVudHMucmlnaHQgLT0gMS4wZjsKCQlyY0NvbnRlbnRzLnRvcCA9IHJjRGF0ZS5ib3R0b20gLSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NOwoJCXJjQ29udGVudHMuYm90dG9tICs9IFBPUFVQX0lURU1fQk9UVE9NV0lEVEg7CgkJcmNDb250ZW50cy5Ob3JtYWxpemUoKTsKCQltX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBUUlVFLCBGQUxTRSk7CgkJbV9wQ29udGVudHMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0NvbnRlbnRzKSk7Cgl9CgoJU2V0Q2xpcFJlY3QoQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QoR2V0V2luZG93UmVjdCgpLDEuMGYpKTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRQcml2YXRlRGF0YSh2b2lkKiBwRGF0YSkKewoJbV9wUHJpdmF0ZURhdGEgPSBwRGF0YTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKQp7CglDUFdMX0NvbG9yIHNCSyA9IGNvbG9yOwoJdGhpcy0+U2V0QmFja2dyb3VuZENvbG9yKHNCSyk7CgoJQ1BXTF9Db2xvciBzVGV4dENvbG9yOwoKCWlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShzQkspKQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOwoJZWxzZQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOwoKCXRoaXMtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCWlmIChtX3BTdWJqZWN0KQoJCW1fcFN1YmplY3QtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCWlmIChtX3BEYXRlVGltZSkKCQltX3BEYXRlVGltZS0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoKCXRoaXMtPkludmFsaWRhdGVSZWN0KE5VTEwpOwoKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXRCa0NvbG9yKHRoaXMpOwoJfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkKewoJaWYgKG1fcFN1YmplY3QpCgl7CgkJbV9wU3ViamVjdC0+U2V0VGV4dChzTmFtZS5jX3N0cigpKTsKCX0KCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0U3ViamVjdE5hbWUodGhpcyk7Cgl9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCnsKCW1fc0F1dGhvciA9IHNOYW1lOwoJUmVzZXRTdWJqZWN0TmFtZSgtMSk7CQoKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXRBdXRob3JOYW1lKHRoaXMpOwoJfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlJlc2V0U3ViamVjdE5hbWUoRlhfSU5UMzIgbkl0ZW1JbmRleCkKewoJaWYgKG5JdGVtSW5kZXggPCAwKQoJewoJCWlmIChDUFdMX1duZCogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCXsKCQkJQVNTRVJUKHBQYXJlbnQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVfQ29udGVudHMiKTsKCgkJCUNQV0xfTm90ZV9Db250ZW50cyogcENvbnRlbnRzID0gKENQV0xfTm90ZV9Db250ZW50cyopcFBhcmVudDsKCQkJbkl0ZW1JbmRleCA9IHBDb250ZW50cy0+R2V0SXRlbUluZGV4KHRoaXMpOwoJCX0KCX0KCgljb25zdCBDUFdMX05vdGUqIHBOb3RlID0gR2V0Tm90ZSgpOwoJQVNTRVJUKHBOb3RlICE9IE5VTEwpOwoKCUNGWF9XaWRlU3RyaW5nIHNTdWJqZWN0OwoJc1N1YmplY3QuRm9ybWF0KHBOb3RlLT5HZXRSZXBseVN0cmluZygpLmNfc3RyKCksIG5JdGVtSW5kZXgpOwoKCWlmICghbV9zQXV0aG9yLklzRW1wdHkoKSkKCXsKCQlzU3ViamVjdCArPSBMIiAtICI7CgkJc1N1YmplY3QgKz0gbV9zQXV0aG9yOwoJfQoJdGhpcy0+U2V0U3ViamVjdE5hbWUoc1N1YmplY3QpOwoJdGhpcy0+UmVQb3NDaGlsZFduZCgpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldERhdGVUaW1lKEZYX1NZU1RFTVRJTUUgdGltZSkKewoJbV9kdE5vdGUgPSB0aW1lOwoKCUNGWF9XaWRlU3RyaW5nIHN3VGltZTsKCXN3VGltZS5Gb3JtYXQoTCIlMDRkLSUwMmQtJTAyZCAlMDJkOiUwMmQ6JTAyZCIsIHRpbWUud1llYXIsIHRpbWUud01vbnRoLCB0aW1lLndEYXksIHRpbWUud0hvdXIsIHRpbWUud01pbnV0ZSwgdGltZS53U2Vjb25kKTsKCWlmIChtX3BEYXRlVGltZSkKCXsKCQltX3BEYXRlVGltZS0+U2V0VGV4dChzd1RpbWUuY19zdHIoKSk7Cgl9CgoJdGhpcy0+UmVQb3NDaGlsZFduZCgpOwoKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXREYXRlVGltZSh0aGlzKTsKCX0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKQp7CglpZiAobV9wQ29udGVudHMpCgl7CgkJbV9wQ29udGVudHMtPlNldFRleHQoc0NvbnRlbnRzKTsKCX0KCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0Q29udGVudHModGhpcyk7Cgl9Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudE5vdGVJdGVtKCkgY29uc3QKewoJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgl7CgkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKCQl7CgkJCUFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CgkJCXJldHVybiAoQ1BXTF9Ob3RlSXRlbSopcEdyYW5kOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0UGFyZW50SXRlbSgpIGNvbnN0CnsKCXJldHVybiBHZXRQYXJlbnROb3RlSXRlbSgpOwp9CgpDUFdMX0VkaXQqIENQV0xfTm90ZUl0ZW06OkdldEVkaXQoKSBjb25zdAp7CglpZiAobV9wQ29udGVudHMpCgkJcmV0dXJuIG1fcENvbnRlbnRzLT5HZXRFZGl0KCk7CglyZXR1cm4gTlVMTDsKfQoKdm9pZCogQ1BXTF9Ob3RlSXRlbTo6R2V0UHJpdmF0ZURhdGEoKSBjb25zdAp7CglyZXR1cm4gbV9wUHJpdmF0ZURhdGE7Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldEF1dGhvck5hbWUoKSBjb25zdAp7CglyZXR1cm4gbV9zQXV0aG9yOyAKfQoKQ1BXTF9Db2xvciBDUFdMX05vdGVJdGVtOjpHZXRCa0NvbG9yKCkgY29uc3QKewoJcmV0dXJuIHRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRDb250ZW50cygpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkdldFRleHQoKTsKCglyZXR1cm4gTCIiOwp9CgpGWF9TWVNURU1USU1FIENQV0xfTm90ZUl0ZW06OkdldERhdGVUaW1lKCkgY29uc3QKewoJcmV0dXJuIG1fZHROb3RlOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRTdWJqZWN0TmFtZSgpIGNvbnN0CnsKCWlmIChtX3BTdWJqZWN0KQoJCXJldHVybiBtX3BTdWJqZWN0LT5HZXRUZXh0KCk7CgoJcmV0dXJuIEwiIjsKfQoKQ1BXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6Q3JlYXRlTm90ZUl0ZW0oKQp7CglpZiAobV9wQ29udGVudHMpCgkJcmV0dXJuIG1fcENvbnRlbnRzLT5DcmVhdGVTdWJJdGVtKCk7CgoJcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkNyZWF0ZVN1Ykl0ZW0oKQp7CglyZXR1cm4gQ3JlYXRlTm90ZUl0ZW0oKTsKfQoKRlhfSU5UMzIgQ1BXTF9Ob3RlSXRlbTo6Q291bnRTdWJJdGVtcygpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkNvdW50U3ViSXRlbXMoKTsKCglyZXR1cm4gMDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0U3ViSXRlbXMoRlhfSU5UMzIgaW5kZXgpIGNvbnN0CnsKCWlmIChtX3BDb250ZW50cykKCQlyZXR1cm4gbV9wQ29udGVudHMtPkdldFN1Ykl0ZW1zKGluZGV4KTsKCglyZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkKewoJdGhpcy0+S2lsbEZvY3VzKCk7CgoJaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkKCXsKCQlwTm90aWZ5LT5Pbkl0ZW1EZWxldGUocE5vdGVJdGVtKTsKCX0KCglpZiAobV9wQ29udGVudHMpCgkJbV9wQ29udGVudHMtPkRlbGV0ZVN1Ykl0ZW0ocE5vdGVJdGVtKTsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpCnsKCUNQREZfUG9pbnQgcHQgPSB0aGlzLT5QYXJlbnRUb0NoaWxkKHBvaW50KTsKCglpZiAodGhpcy0+V25kSGl0VGVzdChwdCkpCgl7CgkJaWYgKG1fcENvbnRlbnRzKQoJCXsKCQkJaWYgKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IG1fcENvbnRlbnRzLT5HZXRIaXROb3RlSXRlbShwdCkpCgkJCQlyZXR1cm4gcE5vdGVJdGVtOwoJCX0KCgkJcmV0dXJuIHRoaXM7Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldEZvY3VzZWROb3RlSXRlbSgpIGNvbnN0CnsKCWlmIChjb25zdCBDUFdMX1duZCogcFduZCA9IHRoaXMtPkdldEZvY3VzZWQoKSkKCXsKCQlpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpCgkJewoJCQlpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBwV25kLT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJewoJCQkJQVNTRVJUKHBQYXJlbnQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVfQ29udGVudHMiKTsKCQkJCQoJCQkJaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkKCQkJCXsKCQkJCQlBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwkJCQkJCgkJCQkJcmV0dXJuIChDUFdMX05vdGVJdGVtKilwR3JhbmQ7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1IZWlnaHQoRlhfRkxPQVQgZkxpbWl0V2lkdGgpCnsKCWlmIChmTGltaXRXaWR0aCA+IDApCgl7CgkJaWYgKCFtX2JTaXplQ2hhbmdlZCkKCQkJcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQ7CgoJCW1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CgoJCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwoJCUFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKCQlBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CgoJCUZYX0ZMT0FUIGZSZXQgPSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKCQlGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpdGhpcy0+R2V0Qm9yZGVyV2lkdGgoKTsKCQlpZiAoZkxpbWl0V2lkdGggPiBmQm9yZGVyV2lkdGggKiAyKQoJCQlmUmV0ICs9IG1fcENvbnRlbnRzLT5HZXRDb250ZW50c0hlaWdodChmTGltaXRXaWR0aCAtIGZCb3JkZXJXaWR0aCAqIDIpOwoJCWZSZXQgKz0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTSArIFBPUFVQX0lURU1fQk9UVE9NV0lEVEggKyBmQm9yZGVyV2lkdGggKiAyOwoKCQlyZXR1cm4gbV9mT2xkSXRlbUhlaWdodCA9IGZSZXQ7Cgl9CgoJcmV0dXJuIDA7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1MZWZ0TWFyZ2luKCkKewoJcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbVJpZ2h0TWFyZ2luKCkKewoJcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsKfQoKRlhfQk9PTAlDUFdMX05vdGVJdGVtOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJaWYgKCFtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQoJewoJCVNldE5vdGVGb2N1cyhGQUxTRSk7Cgl9CgoJQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOwoKCXJldHVybiBUUlVFOwp9CgpGWF9CT09MCUNQV0xfTm90ZUl0ZW06Ok9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCnsKCWlmICghbV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKCXsKCQlTZXROb3RlRm9jdXMoRkFMU0UpOwoJCVBvcHVwTm90ZUl0ZW1NZW51KHBvaW50KTsKCgkJcmV0dXJuIFRSVUU7Cgl9CgoJcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCxuRmxhZyk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsIEZYX0RXT1JEIG1zZywgRlhfSU5UUFRSIHdQYXJhbSwgRlhfSU5UUFRSIGxQYXJhbSkKewoJc3dpdGNoIChtc2cpCgl7CgljYXNlIFBOTV9OT1RFRURJVENIQU5HRUQ6CQoJCW1fYlNpemVDaGFuZ2VkID0gVFJVRTsKCgkJaWYgKENQV0xfV25kKiBwUGFyZW50ID0gdGhpcy0+R2V0UGFyZW50V2luZG93KCkpCgkJewoJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKCQl9CgkJcmV0dXJuOwkKCWNhc2UgUE5NX1NFVENBUkVUSU5GTzoKCQlpZiAoUFdMX0NBUkVUX0lORk8gKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKQoJCXsKCQkJUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKCQkJbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CgkJCW5ld0luZm8ucHRIZWFkID0gdGhpcy0+Q2hpbGRUb1BhcmVudChwSW5mby0+cHRIZWFkKTsKCQkJbmV3SW5mby5wdEZvb3QgPSB0aGlzLT5DaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOwoKCQkJaWYgKENQV0xfV25kICogcFBhcmVudCA9IHRoaXMtPkdldFBhcmVudFdpbmRvdygpKQoJCQl7CgkJCQlwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoRlhfSU5UUFRSKSZuZXdJbmZvLCAwKTsKCQkJfQoJCX0KCQlyZXR1cm47CgljYXNlIFBOTV9OT1RFUkVTRVQ6CgkJbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwoJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCQkKCQlyZXR1cm47Cgl9CgoJQ1BXTF9XbmQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlBvcHVwTm90ZUl0ZW1NZW51KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KQp7CglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCUZYX0lOVDMyIHgseTsKCQlQV0x0b1duZChwb2ludCwgeCwgeSk7CgkJaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCgkJCXBTSC0+Q2xpZW50VG9TY3JlZW4oR2V0QXR0YWNoZWRIV25kKCksIHgsIHkpOwoJCXBOb3RpZnktPk9uUG9wdXBNZW51KHRoaXMsIHgsIHkpOwoJfQp9Cgpjb25zdCBDUFdMX05vdGUqIENQV0xfTm90ZUl0ZW06OkdldE5vdGUoKSBjb25zdAp7CglpZiAoY29uc3QgQ1BXTF9XbmQqIHBSb290ID0gdGhpcy0+R2V0Um9vdFduZCgpKQoJewoJCUFTU0VSVChwUm9vdC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKCQlDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcFJvb3Q7CgkJaWYgKHBOb3RlSXRlbS0+SXNUb3BJdGVtKCkpCgkJewoJCQlyZXR1cm4gKENQV0xfTm90ZSopcE5vdGVJdGVtOwoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGVJdGVtOjpHZXROb3RlTm90aWZ5KCkgY29uc3QKewoJaWYgKGNvbnN0IENQV0xfTm90ZSogcE5vdGUgPSBHZXROb3RlKCkpCgkJcmV0dXJuIHBOb3RlLT5HZXROb3RlTm90aWZ5KCk7CgoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25DcmVhdGVOb3RlSXRlbSgpCnsKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25JdGVtQ3JlYXRlKHRoaXMpOwoJfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06Ok9uQ29udGVudHNWYWxpZGF0ZSgpCnsKCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpCgl7CgkJcE5vdGlmeS0+T25TZXRDb250ZW50cyh0aGlzKTsKCX0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXROb3RlRm9jdXMoRlhfQk9PTCBiTGFzdCkKewoJbV9wQ29udGVudHMtPlNldEVkaXRGb2N1cyhiTGFzdCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwoJbV9iQWxsb3dNb2RpZnkgPSBiRW5hYmxlZDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlOjpDUFdMX05vdGUoSVBvcHVwX05vdGUqIHBQb3B1cE5vdGUsIElQV0xfTm90ZU5vdGlmeSogcE5vdGVOb3RpZnksIElQV0xfTm90ZUhhbmRsZXIqIHBOb3RlSGFuZGxlcikgOiAKCW1fcEF1dGhvcihOVUxMKSwKCW1fcEljb24oTlVMTCksCgltX3BDbG9zZUJveChOVUxMKSwKCW1fcExCQm94KE5VTEwpLAoJbV9wUkJCb3goTlVMTCksCgltX3BDb250ZW50c0JhcihOVUxMKSwKCW1fcE9wdGlvbnMoTlVMTCksCgltX3BOb3RlTm90aWZ5KHBOb3RlTm90aWZ5KSwKCW1fYlJlc2l6aW5nKEZBTFNFKSwKCW1fcmNDYXB0aW9uKDAsMCwwLDApLAoJbV9iRW5hbGJsZU5vdGlmeShUUlVFKSwKCW1fcFBvcHVwTm90ZShwUG9wdXBOb3RlKQp7Cn0KCkNQV0xfTm90ZTo6fkNQV0xfTm90ZSgpCnsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlOjpSZXBseSgpCnsKCXJldHVybiBDcmVhdGVOb3RlSXRlbSgpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlTm90aWZ5KEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fYkVuYWxibGVOb3RpZnkgPSBiRW5hYmxlZDsKfQoKdm9pZCBDUFdMX05vdGU6OlJlUG9zQ2hpbGRXbmQoKQp7CglSZVBvc05vdGVDaGlsZHJlbigpOwoJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwoJUmVzZXRTY3JvbGxCYXIoKTsKCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCXRoaXMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwoJLy/NrLK9CglpZiAoY29uc3QgQ1BXTF9XbmQqIHBXbmQgPSB0aGlzLT5HZXRGb2N1c2VkKCkpCgl7CgkJaWYgKHBXbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX0VkaXQiKQoJCXsKCQkJQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKXBXbmQ7CgkJCXBFZGl0LT5TZXRDYXJldChwRWRpdC0+R2V0Q2FyZXQoKSk7CgkJfQoJfQoJLy9DUERGX1BvaW50IHB0TmV3ID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOwoJLy9tX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6UmVzZXRTY3JvbGxCYXIoKQp7CglGWF9CT09MIGJTY3JvbGxDaGFuZ2VkID0gRkFMU0U7CgoJaWYgKFNjcm9sbEJhclNob3VsZFZpc2libGUoKSkKCXsKCQlpZiAoIW1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKCQl7CgkJCW1fcENvbnRlbnRzQmFyLT5TZXRWaXNpYmxlKFRSVUUpOwoJCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQoJCQl7CgkJCQltX3BDb250ZW50c0Jhci0+SW52YWxpZGF0ZVJlY3QoTlVMTCk7CgkJCQliU2Nyb2xsQ2hhbmdlZCA9IFRSVUU7CgkJCX0KCQl9CQoJfQoJZWxzZQoJewoJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCgkJewoJCQltX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShGQUxTRSk7CgkJCW1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCgkJCWJTY3JvbGxDaGFuZ2VkID0gVFJVRTsKCQl9Cgl9CgoJaWYgKGJTY3JvbGxDaGFuZ2VkKQoJewoJCUNQREZfUmVjdCByY05vdGUgPSB0aGlzLT5HZXRDbGllbnRSZWN0KCk7CgkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0V2luZG93UmVjdCgpOwoJCXJjQ29udGVudHMucmlnaHQgPSByY05vdGUucmlnaHQgLSAzLjBmOwoJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCgkJCXJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsKCQltX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBUUlVFLCBUUlVFKTsKCQltX3BDb250ZW50cy0+U2V0U2Nyb2xsUG9zKENQREZfUG9pbnQoMC4wZiwwLjBmKSk7CgkJbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOwoJfQoKCXJldHVybiBiU2Nyb2xsQ2hhbmdlZDsKfQoKRlhfQk9PTCBDUFdMX05vdGU6OlNjcm9sbEJhclNob3VsZFZpc2libGUoKQp7CglDUERGX1JlY3QgcmNDb250ZW50c0ZhY3QgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwoJQ1BERl9SZWN0IHJjQ29udGVudHNDbGllbnQgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOwoKCXJldHVybiByY0NvbnRlbnRzRmFjdC5IZWlnaHQoKSA+IHJjQ29udGVudHNDbGllbnQuSGVpZ2h0KCk7CQp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0T3B0aW9uc1RleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUZXh0KQp7CglpZiAobV9wT3B0aW9ucykKCQltX3BPcHRpb25zLT5TZXRUZXh0KHNUZXh0KTsKCglSZVBvc05vdGVDaGlsZHJlbigpOwp9Cgp2b2lkIENQV0xfTm90ZTo6UmVQb3NOb3RlQ2hpbGRyZW4oKQp7CglpZiAobV9iUmVzaXppbmcpIHJldHVybjsKCgltX2JSZXNpemluZyA9IFRSVUU7CgoJaWYgKHRoaXMtPklzVmFsaWQoKSkKCXsKCQlBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsKCQlBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7CgkJQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOwoJCUFTU0VSVChtX3BBdXRob3IgIT0gTlVMTCk7CgkJQVNTRVJUKG1fcENsb3NlQm94ICE9IE5VTEwpOwoJCUFTU0VSVChtX3BJY29uICE9IE5VTEwpOwoJCUFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsKCQlBU1NFUlQobV9wUkJCb3ggIT0gTlVMTCk7CgkJQVNTRVJUKG1fcENvbnRlbnRzQmFyICE9IE5VTEwpOwoJCUFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOwoKCQlDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CgoJCUNQREZfUmVjdCByY0ljb24gPSByY0NsaWVudDsKCQlyY0ljb24udG9wIC09IDIuMGY7CgkJcmNJY29uLnJpZ2h0ID0gcmNJY29uLmxlZnQgKyAxNC4wZjsKCQlyY0ljb24uYm90dG9tID0gcmNJY29uLnRvcCAtIDE0LjBmOwoJCXJjSWNvbi5Ob3JtYWxpemUoKTsKCQltX3BJY29uLT5Nb3ZlKHJjSWNvbiwgVFJVRSwgRkFMU0UpOwoJCW1fcEljb24tPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0ljb24pKTsKCgkJQ1BERl9SZWN0IHJjQ2xvc2VCb3ggPSByY0NsaWVudDsKCQlyY0Nsb3NlQm94LnJpZ2h0IC09IDEuMGY7CgkJcmNDbG9zZUJveC50b3AgLT0gMS4wZjsKCQlyY0Nsb3NlQm94LmxlZnQgPSByY0Nsb3NlQm94LnJpZ2h0IC0gMTQuMGY7CgkJcmNDbG9zZUJveC5ib3R0b20gPSByY0Nsb3NlQm94LnRvcCAtIDE0LjBmOwoJCXJjQ2xvc2VCb3guTm9ybWFsaXplKCk7CgkJbV9wQ2xvc2VCb3gtPk1vdmUocmNDbG9zZUJveCwgVFJVRSwgRkFMU0UpOwoJCW1fcENsb3NlQm94LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDbG9zZUJveCkpOwoKCQlDUERGX1JlY3QgcmNEYXRlID0gcmNDbGllbnQ7CgkJcmNEYXRlLnJpZ2h0ID0gcmNDbG9zZUJveC5sZWZ0IC0gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKCQlyY0RhdGUubGVmdCA9IFBXTF9NQVgocmNEYXRlLnJpZ2h0IC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSAtIDEuMGYsIHJjSWNvbi5yaWdodCArIDEuMGYpOwoJCXJjRGF0ZS50b3AgPSByY0NsaWVudC50b3AgLSAyLjBmOwoJCXJjRGF0ZS5ib3R0b20gPSByY0RhdGUudG9wIC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CgkJcmNEYXRlLk5vcm1hbGl6ZSgpOwoJCW1fcERhdGVUaW1lLT5Nb3ZlKHJjRGF0ZSwgVFJVRSwgRkFMU0UpOwoJCW1fcERhdGVUaW1lLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNEYXRlKSk7CgoJCUNQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsKCQlyY1N1YmplY3QudG9wID0gcmNDbGllbnQudG9wIC0gMi4wZjsKCQlyY1N1YmplY3QubGVmdCA9IHJjSWNvbi5yaWdodCArIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CgkJcmNTdWJqZWN0LnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsIHJjRGF0ZS5sZWZ0IC0gMS4wZik7CgkJcmNTdWJqZWN0LmJvdHRvbSA9IHJjU3ViamVjdC50b3AgLSBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoJCXJjU3ViamVjdC5Ob3JtYWxpemUoKTsKCQltX3BTdWJqZWN0LT5Nb3ZlKHJjU3ViamVjdCwgVFJVRSwgRkFMU0UpOwkKCQltX3BTdWJqZWN0LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNTdWJqZWN0KSk7CgoJCUNQREZfUmVjdCByY09wdGlvbnMgPSByY0NsaWVudDsKCQlyY09wdGlvbnMubGVmdCA9IFBXTF9NQVgocmNPcHRpb25zLnJpZ2h0IC0gbV9wT3B0aW9ucy0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpLCByY0ljb24ucmlnaHQgKyAxLjBmKTsKCQlyY09wdGlvbnMudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7CgkJcmNPcHRpb25zLmJvdHRvbSA9IHJjT3B0aW9ucy50b3AgLSBtX3BPcHRpb25zLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoJCXJjT3B0aW9ucy5Ob3JtYWxpemUoKTsKCQltX3BPcHRpb25zLT5Nb3ZlKHJjT3B0aW9ucywgVFJVRSwgRkFMU0UpOwoJCW1fcE9wdGlvbnMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY09wdGlvbnMpKTsKCgkJQ1BERl9SZWN0IHJjQXV0aG9yID0gcmNDbGllbnQ7CgkJcmNBdXRob3IudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7CgkJcmNBdXRob3IubGVmdCA9IHJjU3ViamVjdC5sZWZ0OwoJCXJjQXV0aG9yLnJpZ2h0ID0gUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcEF1dGhvci0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwgcmNPcHRpb25zLmxlZnQgLSAxLjBmKTsKCQlyY0F1dGhvci5ib3R0b20gPSByY0F1dGhvci50b3AgLSBtX3BBdXRob3ItPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CgkJcmNBdXRob3IuTm9ybWFsaXplKCk7CgkJbV9wQXV0aG9yLT5Nb3ZlKHJjQXV0aG9yLCBUUlVFLCBGQUxTRSk7CgkJbV9wQXV0aG9yLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNBdXRob3IpKTsKCgkJQ1BERl9SZWN0IHJjTEJCb3ggPSByY0NsaWVudDsKCQlyY0xCQm94LnRvcCA9IHJjTEJCb3guYm90dG9tICsgNy4wZjsKCQlyY0xCQm94LnJpZ2h0ID0gcmNMQkJveC5sZWZ0ICsgNy4wZjsKCQlyY0xCQm94Lk5vcm1hbGl6ZSgpOwoJCW1fcExCQm94LT5Nb3ZlKHJjTEJCb3gsIFRSVUUsIEZBTFNFKTsKCQltX3BMQkJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjTEJCb3gpKTsKCgkJQ1BERl9SZWN0IHJjUkJCb3ggPSByY0NsaWVudDsKCQlyY1JCQm94LnRvcCA9IHJjUkJCb3guYm90dG9tICsgNy4wZjsKCQlyY1JCQm94LmxlZnQgPSByY1JCQm94LnJpZ2h0IC0gNy4wZjsKCQlyY1JCQm94Lk5vcm1hbGl6ZSgpOwoJCW1fcFJCQm94LT5Nb3ZlKHJjUkJCb3gsIFRSVUUsIEZBTFNFKTsKCQltX3BSQkJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjUkJCb3gpKTsKCgkJQ1BERl9SZWN0IHJjQ29udGVudHMgPSByY0NsaWVudDsKCQlyY0NvbnRlbnRzLnRvcCA9IHJjQXV0aG9yLmJvdHRvbSAtIFBPUFVQX0lURU1fSEVBRF9CT1RUT007CgkJcmNDb250ZW50cy5sZWZ0ICs9IDMuMGY7CgkJcmNDb250ZW50cy5yaWdodCAtPSAzLjBmOwoJCWlmIChtX3BDb250ZW50c0Jhci0+SXNWaXNpYmxlKCkpCgkJCXJjQ29udGVudHMucmlnaHQgLT0gUFdMX1NDUk9MTEJBUl9XSURUSDsKCQlyY0NvbnRlbnRzLmJvdHRvbSArPSAxNC4wZjsKCQlyY0NvbnRlbnRzLk5vcm1hbGl6ZSgpOwoJCW1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIEZBTFNFLCBGQUxTRSk7CgkJbV9wQ29udGVudHMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0NvbnRlbnRzKSk7CgoJCUNQREZfUmVjdCByY0NvbnRlbnRzQmFyID0gcmNDb250ZW50czsKCQlyY0NvbnRlbnRzQmFyLnJpZ2h0ID0gcmNDbGllbnQucmlnaHQgLSAzLjBmOwoJCXJjQ29udGVudHNCYXIubGVmdCA9IHJjQ29udGVudHNCYXIucmlnaHQgLSBQV0xfU0NST0xMQkFSX1dJRFRIOwoJCXJjQ29udGVudHNCYXIuTm9ybWFsaXplKCk7CgkJbV9wQ29udGVudHNCYXItPk1vdmUocmNDb250ZW50c0JhciwgVFJVRSwgRkFMU0UpOwoJCQoJCW1fcmNDYXB0aW9uID0gcmNDbGllbnQ7CgkJbV9yY0NhcHRpb24uYm90dG9tID0gcmNDb250ZW50cy50b3A7Cgl9CgoJbV9iUmVzaXppbmcgPSBGQUxTRTsKfQoKLy8wLW5vcm1hbCAvIDEtY2FwdGlvbiAvIDItbGVmdGJvdHRvbSBjb3JuZXIgLyAzLXJpZ2h0Ym90dG9tIGNvcm5lciAvIDQtY2xvc2UgLyA1LW9wdGlvbnMgCkZYX0lOVDMyIENQV0xfTm90ZTo6Tm90ZUhpdFRlc3QoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIGNvbnN0CnsKCUFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwoJQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOwoJQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOwoJQVNTRVJUKG1fcEF1dGhvciAhPSBOVUxMKTsKCUFTU0VSVChtX3BJY29uICE9IE5VTEwpOwoJQVNTRVJUKG1fcENvbnRlbnRzQmFyICE9IE5VTEwpOwoKCUFTU0VSVChtX3BDbG9zZUJveCAhPSBOVUxMKTsKCUFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsKCUFTU0VSVChtX3BSQkJveCAhPSBOVUxMKTsKCUFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOwoKCUdldENsaWVudFJlY3QoKTsKCglpZiAobV9wU3ViamVjdC0+V25kSGl0VGVzdChtX3BTdWJqZWN0LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOwoJaWYgKG1fcERhdGVUaW1lLT5XbmRIaXRUZXN0KG1fcERhdGVUaW1lLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOwoJaWYgKG1fcEF1dGhvci0+V25kSGl0VGVzdChtX3BBdXRob3ItPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDE7CglpZiAobV9wSWNvbi0+V25kSGl0VGVzdChtX3BJY29uLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiAxOwoKCWlmIChtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMDsKCWlmIChtX3BDb250ZW50c0Jhci0+V25kSGl0VGVzdChtX3BDb250ZW50c0Jhci0+UGFyZW50VG9DaGlsZChwb2ludCkpKSByZXR1cm4gMDsKCglpZiAobV9wQ2xvc2VCb3gtPlduZEhpdFRlc3QobV9wQ2xvc2VCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDQ7CglpZiAobV9wTEJCb3gtPlduZEhpdFRlc3QobV9wTEJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDI7CglpZiAobV9wUkJCb3gtPlduZEhpdFRlc3QobV9wUkJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkgcmV0dXJuIDM7CglpZiAobV9wT3B0aW9ucy0+V25kSGl0VGVzdChtX3BPcHRpb25zLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHJldHVybiA1OwoKCXJldHVybiAxOwp9Cgp2b2lkIENQV0xfTm90ZTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNICYgY3ApCnsKCUNQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNwKTsKCglDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CgoJaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHRoaXMtPkdldEJhY2tncm91bmRDb2xvcigpKSkKCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKCWVsc2UKCQlzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKCgltX3BBdXRob3IgPSBuZXcgQ1BXTF9MYWJlbDsKCVBXTF9DUkVBVEVQQVJBTSBhY3AgPSBjcDsKCWFjcC5wUGFyZW50V25kID0gdGhpczsKCWFjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7CglhY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BBdXRob3ItPkNyZWF0ZShhY3ApOwkgCgoJbV9wQ2xvc2VCb3ggPSBuZXcgQ1BXTF9Ob3RlX0Nsb3NlQm94OwoJUFdMX0NSRUFURVBBUkFNIGNjcCA9IGNwOwoJY2NwLnBQYXJlbnRXbmQgPSB0aGlzOwoJY2NwLmR3Qm9yZGVyV2lkdGggPSAyOwoJY2NwLm5Cb3JkZXJTdHlsZSA9IFBCU19CRVZFTEVEOwoJY2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVI7CgljY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BDbG9zZUJveC0+Q3JlYXRlKGNjcCk7CgoJbV9wSWNvbiA9IG5ldyBDUFdMX05vdGVfSWNvbjsKCVBXTF9DUkVBVEVQQVJBTSBpY3AgPSBjcDsKCWljcC5wUGFyZW50V25kID0gdGhpczsKCWljcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQ7CgltX3BJY29uLT5DcmVhdGUoaWNwKTsKCgltX3BPcHRpb25zID0gbmV3IENQV0xfTm90ZV9PcHRpb25zOwoJUFdMX0NSRUFURVBBUkFNIG9jcCA9IGNwOwoJb2NwLnBQYXJlbnRXbmQgPSB0aGlzOwoJb2NwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRTsKCW9jcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKCW1fcE9wdGlvbnMtPkNyZWF0ZShvY3ApOwoKCW1fcExCQm94ID0gbmV3IENQV0xfTm90ZV9MQkJveDsKCVBXTF9DUkVBVEVQQVJBTSBsY3AgPSBjcDsKCWxjcC5wUGFyZW50V25kID0gdGhpczsKCWxjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQ7CglsY3AuZUN1cnNvclR5cGUgPSBGWENUX05FU1c7CglsY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CgltX3BMQkJveC0+Q3JlYXRlKGxjcCk7CgoJbV9wUkJCb3ggPSBuZXcgQ1BXTF9Ob3RlX1JCQm94OwoJUFdMX0NSRUFURVBBUkFNIHJjcCA9IGNwOwoJcmNwLnBQYXJlbnRXbmQgPSB0aGlzOwoJcmNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsKCXJjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfTldTRTsKCXJjcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKCW1fcFJCQm94LT5DcmVhdGUocmNwKTsKCgltX3BDb250ZW50c0JhciA9IG5ldyBDUFdMX1Njcm9sbEJhcihTQlRfVlNDUk9MTCk7CglQV0xfQ1JFQVRFUEFSQU0gc2NwID0gY3A7CglzY3AucFBhcmVudFduZCA9IHRoaXM7CglzY3Auc0JhY2tncm91bmRDb2xvciA9IENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZiwgMjQwLzI1NS4wZik7CglzY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFIHwgUFdTX0JBQ0tHUk9VTkQ7CgltX3BDb250ZW50c0Jhci0+Q3JlYXRlKHNjcCk7CgltX3BDb250ZW50c0Jhci0+U2V0Tm90aWZ5Rm9yZXZlcihUUlVFKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkKewoJQ1BXTF9Ob3RlSXRlbTo6U2V0U3ViamVjdE5hbWUoc05hbWUpOwoJUmVQb3NDaGlsZFduZCgpOwp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpCnsKCWlmIChtX3BBdXRob3IpCgl7CgkJbV9wQXV0aG9yLT5TZXRUZXh0KHNOYW1lLmNfc3RyKCkpOwoJCVJlUG9zQ2hpbGRXbmQoKTsKCX0KCglpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKQoJewoJCXBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsKCX0KfQoKQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlOjpHZXRBdXRob3JOYW1lKCkgY29uc3QKewoJaWYgKG1fcEF1dGhvcikKCQlyZXR1cm4gbV9wQXV0aG9yLT5HZXRUZXh0KCk7CgoJcmV0dXJuIEwiIjsKfQoKRlhfQk9PTCBDUFdMX05vdGU6Ok9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsIGNvbnN0IENQREZfUG9pbnQgJiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpCnsKCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CglDUERGX1JlY3QgcmNTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwoJQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOwoKCWlmIChyY1Njcm9sbC50b3AgLSByY1Njcm9sbC5ib3R0b20gPiByY0NvbnRlbnRzLkhlaWdodCgpKQoJewoJCUNQREZfUG9pbnQgcHROZXcgPSBwdFNjcm9sbDsKCgkJaWYgKHpEZWx0YSA+IDApCgkJCXB0TmV3LnkgKz0gMzA7CgkJZWxzZQoJCQlwdE5ldy55IC09IDMwOwoKCQlpZiAocHROZXcueSA+IHJjU2Nyb2xsLnRvcCkKCQkJcHROZXcueSA9IHJjU2Nyb2xsLnRvcDsKCQlpZiAocHROZXcueSA8IHJjU2Nyb2xsLmJvdHRvbSArIHJjQ29udGVudHMuSGVpZ2h0KCkpCgkJCXB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b20gKyByY0NvbnRlbnRzLkhlaWdodCgpOwoJCWlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tKQoJCQlwdE5ldy55ID0gcmNTY3JvbGwuYm90dG9tOwoKCQlpZiAocHROZXcueSAhPSBwdFNjcm9sbC55KQoJCXsKCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwoJCQltX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOwkJCQoJCQltX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsIChGWF9JTlRQVFIpJnB0TmV3LnkpOwoKCQkJcmV0dXJuIFRSVUU7CgkJfQoJfQoKCXJldHVybiBGQUxTRTsKfQoKdm9pZCBDUFdMX05vdGU6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLCBGWF9EV09SRCBtc2csIEZYX0lOVFBUUiB3UGFyYW0sIEZYX0lOVFBUUiBsUGFyYW0pCnsKCXN3aXRjaCAobXNnKQoJewoJY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOgoJCXsKCQkJQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsKCQkJCgoJCQlQV0xfU0NST0xMX0lORk8gc0luZm87CgkJCXNJbmZvLmZDb250ZW50TWluID0gcmNTY3JvbGwuYm90dG9tOwoJCQlzSW5mby5mQ29udGVudE1heCA9IHJjU2Nyb2xsLnRvcDsKCQkJc0luZm8uZlBsYXRlV2lkdGggPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpLkhlaWdodCgpOwoJCQlzSW5mby5mU21hbGxTdGVwID0gMTMuMGY7CgkJCXNJbmZvLmZCaWdTdGVwID0gc0luZm8uZlBsYXRlV2lkdGg7CgoJCQlpZiAoRlhTWVNfbWVtY21wKCZtX09sZFNjcm9sbEluZm8sICZzSW5mbywgc2l6ZW9mKFBXTF9TQ1JPTExfSU5GTykpICE9IDApCgkJCXsKCQkJCUZYX0JPT0wgYlNjcm9sbENoYW5nZWQgPSBGQUxTRTsKCgkJCQlpZiAobFBhcmFtIDwgMykgLy+3wNa5y8DRrbu3IG1hbnRpczoxNTc1OQoJCQkJewoJCQkJCWJTY3JvbGxDaGFuZ2VkID0gUmVzZXRTY3JvbGxCYXIoKTsKCQkJCQlpZiAoYlNjcm9sbENoYW5nZWQpCgkJCQkJewoJCQkJCQlsUGFyYW0rKzsKCQkJCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwoJCQkJCQl0aGlzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCBsUGFyYW0pOwoJCQkJCX0KCQkJCX0KCQkJCQoJCQkJaWYgKCFiU2Nyb2xsQ2hhbmdlZCkKCQkJCXsKCQkJCQlpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQoJCQkJCXsKCQkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHBXbmQsIFBOTV9TRVRTQ1JPTExJTkZPLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmc0luZm8pOwoJCQkJCQltX09sZFNjcm9sbEluZm8gPSBzSW5mbzsKCgkJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CgkJCQkJCUNQREZfUG9pbnQgcHRPbGQgPSBwdFNjcm9sbDsKCgkJCQkJCWlmIChwdFNjcm9sbC55ID4gc0luZm8uZkNvbnRlbnRNYXgpCgkJCQkJCQlwdFNjcm9sbC55ID0gc0luZm8uZkNvbnRlbnRNYXg7CgkJCQkJCWlmIChwdFNjcm9sbC55IDwgc0luZm8uZkNvbnRlbnRNaW4gKyBzSW5mby5mUGxhdGVXaWR0aCkKCQkJCQkJCXB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbiArIHNJbmZvLmZQbGF0ZVdpZHRoOwoJCQkJCQlpZiAocHRTY3JvbGwueSA8IHNJbmZvLmZDb250ZW50TWluKQoJCQkJCQkJcHRTY3JvbGwueSA9IHNJbmZvLmZDb250ZW50TWluOwoKCQkJCQkJaWYgKHB0T2xkLnkgIT0gcHRTY3JvbGwueSkKCQkJCQkJewoJCQkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKCQkJCQkJCW1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCQkJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHRTY3JvbGwueSk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCW1fcENvbnRlbnRzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCgkJcmV0dXJuOwoJY2FzZSBQTk1fU0NST0xMV0lORE9XOgoJCWlmIChtX3BDb250ZW50cykKCQkJbV9wQ29udGVudHMtPk9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCXJldHVybjsKCWNhc2UgUE5NX1NFVFNDUk9MTFBPUzoKCQlpZiAobV9wQ29udGVudHNCYXIpCgkJCW1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeShwV25kLFBOTV9TRVRTQ1JPTExQT1Msd1BhcmFtLGxQYXJhbSk7CgkJcmV0dXJuOwoJfQoKCWlmIChtc2cgPT0gUE5NX1NFVENBUkVUSU5GTyAmJiBJc1ZhbGlkKCkpCgl7CgkJaWYgKFBXTF9DQVJFVF9JTkZPICogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkKCQl7CgkJCWlmIChtX3BDb250ZW50cykKCQkJewoJCQkJQ1BERl9SZWN0IHJjQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsKCQkJCWlmIChwSW5mby0+cHRIZWFkLnkgPiByY0NsaWVudC50b3ApCgkJCQl7CgkJCQkJQ1BERl9Qb2ludCBwdCA9IG1fcENvbnRlbnRzLT5PdXRUb0luKHBJbmZvLT5wdEhlYWQpOwoJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHQueSk7CgoJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CgkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKCgkJCQkJcmV0dXJuOwoJCQkJfQoJCQkJCgkJCQlpZiAocEluZm8tPnB0Rm9vdC55IDwgcmNDbGllbnQuYm90dG9tKQoJCQkJewoJCQkJCUNQREZfUG9pbnQgcHQgPSBtX3BDb250ZW50cy0+T3V0VG9JbihwSW5mby0+cHRGb290KTsKCQkJCQlwdC55ICs9IHJjQ2xpZW50LkhlaWdodCgpOwoJCQkJCW1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwgKEZYX0lOVFBUUikmcHQueSk7CgoJCQkJCUNQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CgkJCQkJbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLCAoRlhfSU5UUFRSKSZwdFNjcm9sbC55KTsKCgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9CgkJfQoJfQoKCUNQV0xfTm90ZUl0ZW06Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0QmtDb2xvcihjb25zdCBDUFdMX0NvbG9yJiBjb2xvcikKewoJQ1BXTF9Ob3RlSXRlbTo6U2V0QmtDb2xvcihjb2xvcik7CgoJQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsKCUNQV0xfQ29sb3Igc1RleHRDb2xvcjsKCWlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShzQkspKQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOwoJZWxzZQoJCXNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOwoKCWlmIChtX3BDbG9zZUJveCkKCQltX3BDbG9zZUJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoJaWYgKG1fcEF1dGhvcikKCQltX3BBdXRob3ItPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCWlmIChtX3BPcHRpb25zKQoJCW1fcE9wdGlvbnMtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCWlmIChtX3BMQkJveCkKCQltX3BMQkJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoJaWYgKG1fcFJCQm94KQoJCW1fcFJCQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7Cn0KCkZYX0JPT0wJQ1BXTF9Ob3RlOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJaWYgKG1fcE9wdGlvbnMtPlduZEhpdFRlc3QobV9wT3B0aW9ucy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQoJewoJCWlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSB0aGlzLT5HZXROb3RlTm90aWZ5KCkpCgkJewoJCQlGWF9JTlQzMiB4LCB5OwoJCQlQV0x0b1duZChwb2ludCwgeCwgeSk7CgkJCWlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQoJCQkJcFNILT5DbGllbnRUb1NjcmVlbihHZXRBdHRhY2hlZEhXbmQoKSwgeCwgeSk7CgkJCXRoaXMtPktpbGxGb2N1cygpOwoJCQlwTm90aWZ5LT5PblBvcHVwTWVudSh4LCB5KTsKCgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCglyZXR1cm4gQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsbkZsYWcpOwp9CgpGWF9CT09MCUNQV0xfTm90ZTo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCAmIHBvaW50LCBGWF9EV09SRCBuRmxhZykKewoJcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCxuRmxhZyk7Cn0KCmNvbnN0IENQV0xfTm90ZSogQ1BXTF9Ob3RlOjpHZXROb3RlKCkgY29uc3QKewoJcmV0dXJuIHRoaXM7Cn0KCklQV0xfTm90ZU5vdGlmeSogQ1BXTF9Ob3RlOjpHZXROb3RlTm90aWZ5KCkgY29uc3QKewoJaWYgKG1fYkVuYWxibGVOb3RpZnkpCgkJcmV0dXJuIG1fcE5vdGVOb3RpZnk7CgoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRJY29uVHlwZShGWF9JTlQzMiBuVHlwZSkKewoJaWYgKG1fcEljb24pCgkJbV9wSWNvbi0+U2V0SWNvblR5cGUoblR5cGUpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpCnsKCW1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKQp7CgltX3BDb250ZW50cy0+RW5hYmxlUmVhZChiRW5hYmxlZCk7Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZTo6R2V0UmVwbHlTdHJpbmcoKSBjb25zdAp7CglyZXR1cm4gbV9zUmVwbHlTdHJpbmc7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRSZXBseVN0cmluZyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKQp7CgltX3NSZXBseVN0cmluZyA9IHN0cmluZzsKfQoK