Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCgojaW5jbHVkZSAiLi4vLi4vaW5jbHVkZS9wZGZ3aW5kb3cvUERGV2luZG93LmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQnV0dG9uLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfRWRpdEN0cmwuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9FZGl0LmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEN0cmwuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9TY3JvbGxCYXIuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9Ob3RlLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGFiZWwuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9FZGl0LmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiCiNpbmNsdWRlICIuLi8uLi9pbmNsdWRlL3BkZndpbmRvdy9QV0xfVXRpbHMuaCIKI2luY2x1ZGUgIi4uLy4uL2luY2x1ZGUvcGRmd2luZG93L1BXTF9DYXJldC5oIgoKI2RlZmluZSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NIDMuMGYKI2RlZmluZSBQT1BVUF9JVEVNX0JPVFRPTVdJRFRIIDEuMGYKI2RlZmluZSBQT1BVUF9JVEVNX1NJREVNQVJHSU4gMy4wZgojZGVmaW5lIFBPUFVQX0lURU1fU1BBQ0UgNC4wZgojZGVmaW5lIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQgMi4wZgojZGVmaW5lIFBPUFVQX0lURU1fQk9SREVSQ09MT1IgXAogIENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgODAgLyAyNTUuMGYsIDgwIC8gMjU1LjBmLCA4MCAvIDI1NS4wZikKCiNkZWZpbmUgSXNGbG9hdFplcm8oZikgKChmKSA8IDAuMDAwMSAmJiAoZikgPiAtMC4wMDAxKQojZGVmaW5lIElzRmxvYXRCaWdnZXIoZmEsIGZiKSAoKGZhKSA+IChmYikgJiYgIUlzRmxvYXRaZXJvKChmYSkgLSAoZmIpKSkKI2RlZmluZSBJc0Zsb2F0U21hbGxlcihmYSwgZmIpICgoZmEpIDwgKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQojZGVmaW5lIElzRmxvYXRFcXVhbChmYSwgZmIpIElzRmxvYXRaZXJvKChmYSkgLSAoZmIpKQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfT3B0aW9ucwogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVfT3B0aW9uczo6Q1BXTF9Ob3RlX09wdGlvbnMoKSA6IG1fcFRleHQoTlVMTCkge30KCkNQV0xfTm90ZV9PcHRpb25zOjp+Q1BXTF9Ob3RlX09wdGlvbnMoKSB7fQoKdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6U2V0VGV4dENvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKSB7CiAgQ1BXTF9XbmQ6OlNldFRleHRDb2xvcihjb2xvcik7CgogIGlmIChtX3BUZXh0KQogICAgbV9wVGV4dC0+U2V0VGV4dENvbG9yKGNvbG9yKTsKfQoKdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6UmVQb3NDaGlsZFduZCgpIHsKICBpZiAoSXNWYWxpZCgpKSB7CiAgICBBU1NFUlQobV9wVGV4dCAhPSBOVUxMKTsKCiAgICBDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CgogICAgaWYgKHJjQ2xpZW50LldpZHRoKCkgPiAxNS4wZikgewogICAgICByY0NsaWVudC5yaWdodCAtPSAxNS4wZjsKICAgICAgbV9wVGV4dC0+TW92ZShyY0NsaWVudCwgVFJVRSwgRkFMU0UpOwogICAgICBtX3BUZXh0LT5TZXRWaXNpYmxlKFRSVUUpOwogICAgfSBlbHNlIHsKICAgICAgbV9wVGV4dC0+TW92ZShDUERGX1JlY3QoMCwgMCwgMCwgMCksIFRSVUUsIEZBTFNFKTsKICAgICAgbV9wVGV4dC0+U2V0VmlzaWJsZShGQUxTRSk7CiAgICB9CiAgfQp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwKSB7CiAgbV9wVGV4dCA9IG5ldyBDUFdMX0xhYmVsOwogIFBXTF9DUkVBVEVQQVJBTSB0Y3AgPSBjcDsKICB0Y3AucFBhcmVudFduZCA9IHRoaXM7CiAgdGNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRTsKICBtX3BUZXh0LT5DcmVhdGUodGNwKTsKfQoKdm9pZCBDUFdMX05vdGVfT3B0aW9uczo6U2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpIHsKICBtX3BUZXh0LT5TZXRUZXh0KHNUZXh0LmNfc3RyKCkpOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpIHsKICBDUFdMX1duZDo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7CgogIENQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKICByY0NsaWVudC5sZWZ0ID0gcmNDbGllbnQucmlnaHQgLSAxNS4wZjsKCiAgQ1BERl9Qb2ludCBwdENlbnRlciA9IENQREZfUG9pbnQoKHJjQ2xpZW50LmxlZnQgKyByY0NsaWVudC5yaWdodCkgKiAwLjVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyY0NsaWVudC50b3AgKyByY0NsaWVudC5ib3R0b20pICogMC41Zik7CgogIENQREZfUG9pbnQgcHQxKHB0Q2VudGVyLnggLSAyLjBmLCBwdENlbnRlci55ICsgMi4wZiAqIDAuNWYpOwogIENQREZfUG9pbnQgcHQyKHB0Q2VudGVyLnggKyAyLjBmLCBwdENlbnRlci55ICsgMi4wZiAqIDAuNWYpOwogIENQREZfUG9pbnQgcHQzKHB0Q2VudGVyLngsIHB0Q2VudGVyLnkgLSAzLjBmICogMC41Zik7CgogIENGWF9QYXRoRGF0YSBwYXRoOwoKICBwYXRoLlNldFBvaW50Q291bnQoNCk7CiAgcGF0aC5TZXRQb2ludCgwLCBwdDEueCwgcHQxLnksIEZYUFRfTU9WRVRPKTsKICBwYXRoLlNldFBvaW50KDEsIHB0Mi54LCBwdDIueSwgRlhQVF9MSU5FVE8pOwogIHBhdGguU2V0UG9pbnQoMiwgcHQzLngsIHB0My55LCBGWFBUX0xJTkVUTyk7CiAgcGF0aC5TZXRQb2ludCgzLCBwdDEueCwgcHQxLnksIEZYUFRfTElORVRPKTsKCiAgcERldmljZS0+RHJhd1BhdGgoCiAgICAgICZwYXRoLCBwVXNlcjJEZXZpY2UsIE5VTEwsCiAgICAgIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLCBHZXRUcmFuc3BhcmVuY3koKSksIDAsCiAgICAgIEZYRklMTF9BTFRFUk5BVEUpOwp9CgpDUERGX1JlY3QgQ1BXTF9Ob3RlX09wdGlvbnM6OkdldENvbnRlbnRSZWN0KCkgY29uc3QgewogIEFTU0VSVChtX3BUZXh0ICE9IE5VTEwpOwoKICBDUERGX1JlY3QgcmNUZXh0ID0gbV9wVGV4dC0+R2V0Q29udGVudFJlY3QoKTsKICByY1RleHQucmlnaHQgKz0gMTUuMGY7CiAgcmV0dXJuIHJjVGV4dDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfRWRpdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCgpDUFdMX05vdGVfRWRpdDo6Q1BXTF9Ob3RlX0VkaXQoKQogICAgOiBtX2JFbmFibGVOb3RpZnkoVFJVRSksCiAgICAgIG1fZk9sZEl0ZW1IZWlnaHQoMC4wZiksCiAgICAgIG1fYlNpemVDaGFuZ2VkKEZBTFNFKSwKICAgICAgbV9mT2xkTWluKDAuMGYpLAogICAgICBtX2ZPbGRNYXgoMC4wZikge30KCkNQV0xfTm90ZV9FZGl0Ojp+Q1BXTF9Ob3RlX0VkaXQoKSB7fQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6UmVQb3NDaGlsZFduZCgpIHsKICBtX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsKICBDUFdMX0VkaXQ6OlJlUG9zQ2hpbGRXbmQoKTsKICBtX2JFbmFibGVOb3RpZnkgPSBUUlVFOwoKICBtX2ZPbGRJdGVtSGVpZ2h0ID0gR2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKfQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6U2V0VGV4dChjb25zdCBGWF9XQ0hBUiogY3NUZXh0KSB7CiAgbV9iRW5hYmxlTm90aWZ5ID0gRkFMU0U7CiAgQ1BXTF9FZGl0OjpTZXRUZXh0KGNzVGV4dCk7CiAgbV9iRW5hYmxlTm90aWZ5ID0gVFJVRTsKICBtX2ZPbGRJdGVtSGVpZ2h0ID0gR2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKfQoKdm9pZCBDUFdMX05vdGVfRWRpdDo6T25TZXRGb2N1cygpIHsKICBtX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsKICBDUFdMX0VkaXQ6Ok9uU2V0Rm9jdXMoKTsKICBtX2JFbmFibGVOb3RpZnkgPSBUUlVFOwoKICBFbmFibGVTcGVsbENoZWNrKFRSVUUpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpPbktpbGxGb2N1cygpIHsKICBFbmFibGVTcGVsbENoZWNrKEZBTFNFKTsKCiAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgIGlmIChDUFdMX1duZCogcEdyYW5kID0gcFBhcmVudC0+R2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgQVNTRVJUKHBHcmFuZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKCiAgICAgIENQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwR3JhbmQ7CgogICAgICBwTm90ZUl0ZW0tPk9uQ29udGVudHNWYWxpZGF0ZSgpOwogICAgfQogIH0KCiAgQ1BXTF9FZGl0OjpPbktpbGxGb2N1cygpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRwdHJfdCB3UGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IGxQYXJhbSkgewogIGlmIChtX2JFbmFibGVOb3RpZnkpIHsKICAgIGlmICh3UGFyYW0gPT0gU0JUX1ZTQ1JPTEwpIHsKICAgICAgc3dpdGNoIChtc2cpIHsKICAgICAgICBjYXNlIFBOTV9TRVRTQ1JPTExJTkZPOgogICAgICAgICAgaWYgKFBXTF9TQ1JPTExfSU5GTyogcEluZm8gPSAoUFdMX1NDUk9MTF9JTkZPKilsUGFyYW0pIHsKICAgICAgICAgICAgaWYgKCFJc0Zsb2F0RXF1YWwocEluZm8tPmZDb250ZW50TWF4LCBtX2ZPbGRNYXgpIHx8CiAgICAgICAgICAgICAgICAhSXNGbG9hdEVxdWFsKHBJbmZvLT5mQ29udGVudE1pbiwgbV9mT2xkTWluKSkgewogICAgICAgICAgICAgIG1fYlNpemVDaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgICAgICAgICAgICAgcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBtX2ZPbGRNYXggPSBwSW5mby0+ZkNvbnRlbnRNYXg7CiAgICAgICAgICAgICAgbV9mT2xkTWluID0gcEluZm8tPmZDb250ZW50TWluOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICBDUFdMX0VkaXQ6Ok9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwoKICBpZiAobV9iRW5hYmxlTm90aWZ5KSB7CiAgICBzd2l0Y2ggKG1zZykgewogICAgICBjYXNlIFBOTV9TRVRDQVJFVElORk86CiAgICAgICAgaWYgKFBXTF9DQVJFVF9JTkZPKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKSB7CiAgICAgICAgICBQV0xfQ0FSRVRfSU5GTyBuZXdJbmZvID0gKnBJbmZvOwogICAgICAgICAgbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CiAgICAgICAgICBuZXdJbmZvLnB0SGVhZCA9IENoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CiAgICAgICAgICBuZXdJbmZvLnB0Rm9vdCA9IENoaWxkVG9QYXJlbnQocEluZm8tPnB0Rm9vdCk7CgogICAgICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICAgICAgcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKGludHB0cl90KSZuZXdJbmZvLCAwKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgpGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkgewogIGlmIChmTGltaXRXaWR0aCA+IDApIHsKICAgIGlmICghbV9iU2l6ZUNoYW5nZWQpCiAgICAgIHJldHVybiBtX2ZPbGRJdGVtSGVpZ2h0OwoKICAgIG1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CgogICAgRW5hYmxlTm90aWZ5KEZBTFNFKTsKICAgIEVuYWJsZVJlZnJlc2goRkFMU0UpOwogICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKCiAgICBNb3ZlKENQREZfUmVjdCgwLCAwLCBmTGltaXRXaWR0aCwgMCksIFRSVUUsIEZBTFNFKTsKICAgIEZYX0ZMT0FUIGZSZXQgPSBHZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwoKICAgIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKICAgIEVuYWJsZU5vdGlmeShUUlVFKTsKICAgIEVuYWJsZVJlZnJlc2goVFJVRSk7CgogICAgcmV0dXJuIGZSZXQ7CiAgfQoKICByZXR1cm4gMDsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlX0VkaXQ6OkdldEl0ZW1MZWZ0TWFyZ2luKCkgewogIHJldHVybiBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwp9CgpGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbVJpZ2h0TWFyZ2luKCkgewogIHJldHVybiBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfTEJCb3gKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKQ1BXTF9Ob3RlX0xCQm94OjpDUFdMX05vdGVfTEJCb3goKSB7fQoKQ1BXTF9Ob3RlX0xCQm94Ojp+Q1BXTF9Ob3RlX0xCQm94KCkge30KCnZvaWQgQ1BXTF9Ob3RlX0xCQm94OjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKSB7CiAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKICBDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOwogIGdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CgogIENGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7CgogIHBhdGhDcm9zcy5TZXRQb2ludENvdW50KDQpOwogIHBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsKICBwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgyLCByY0NsaWVudC5sZWZ0LAogICAgICAgICAgICAgICAgICAgICByY0NsaWVudC5ib3R0b20gKyByY0NsaWVudC5IZWlnaHQoKSAqIDAuNWYsIEZYUFRfTU9WRVRPKTsKICBwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQubGVmdCArIHJjQ2xpZW50LldpZHRoKCkgKiAwLjVmLAogICAgICAgICAgICAgICAgICAgICByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsKCiAgcERldmljZS0+RHJhd1BhdGgoCiAgICAgICZwYXRoQ3Jvc3MsIHBVc2VyMkRldmljZSwgJmdzZCwgMCwKICAgICAgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksIEdldFRyYW5zcGFyZW5jeSgpKSwKICAgICAgRlhGSUxMX0FMVEVSTkFURSk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9SQkJveAogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpDUFdMX05vdGVfUkJCb3g6OkNQV0xfTm90ZV9SQkJveCgpIHt9CgpDUFdMX05vdGVfUkJCb3g6On5DUFdMX05vdGVfUkJCb3goKSB7fQoKdm9pZCBDUFdMX05vdGVfUkJCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpIHsKICBDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CgogIENGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CiAgZ3NkLm1fTGluZVdpZHRoID0gMS4wZjsKCiAgQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsKCiAgcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CiAgcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LnJpZ2h0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsKICBwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQubGVmdCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CiAgcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LnJpZ2h0LAogICAgICAgICAgICAgICAgICAgICByY0NsaWVudC5ib3R0b20gKyByY0NsaWVudC5IZWlnaHQoKSAqIDAuNWYsIEZYUFRfTU9WRVRPKTsKICBwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQubGVmdCArIHJjQ2xpZW50LldpZHRoKCkgKiAwLjVmLAogICAgICAgICAgICAgICAgICAgICByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsKCiAgcERldmljZS0+RHJhd1BhdGgoCiAgICAgICZwYXRoQ3Jvc3MsIHBVc2VyMkRldmljZSwgJmdzZCwgMCwKICAgICAgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksIEdldFRyYW5zcGFyZW5jeSgpKSwKICAgICAgRlhGSUxMX0FMVEVSTkFURSk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfSWNvbgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVfSWNvbjo6Q1BXTF9Ob3RlX0ljb24oKSA6IG1fblR5cGUoMCkge30KCkNQV0xfTm90ZV9JY29uOjp+Q1BXTF9Ob3RlX0ljb24oKSB7fQoKdm9pZCBDUFdMX05vdGVfSWNvbjo6U2V0SWNvblR5cGUoaW50MzJfdCBuVHlwZSkgewogIG1fblR5cGUgPSBuVHlwZTsKfQoKdm9pZCBDUFdMX05vdGVfSWNvbjo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDUERGX01hdHJpeCogcFVzZXIyRGV2aWNlKSB7CiAgQ1BXTF9VdGlsczo6RHJhd0ljb25BcHBTdHJlYW0ocERldmljZSwgcFVzZXIyRGV2aWNlLCBtX25UeXBlLCBHZXRDbGllbnRSZWN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0QmFja2dyb3VuZENvbG9yKCksIFBXTF9ERUZBVUxUX0JMQUNLQ09MT1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0VHJhbnNwYXJlbmN5KCkpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0Nsb3NlQm94CiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9DbG9zZUJveDo6Q1BXTF9Ob3RlX0Nsb3NlQm94KCkgOiBtX2JNb3VzZURvd24oRkFMU0UpIHt9CgpDUFdMX05vdGVfQ2xvc2VCb3g6On5DUFdMX05vdGVfQ2xvc2VCb3goKSB7fQoKdm9pZCBDUFdMX05vdGVfQ2xvc2VCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpIHsKICBDUFdMX0J1dHRvbjo6RHJhd1RoaXNBcHBlYXJhbmNlKHBEZXZpY2UsIHBVc2VyMkRldmljZSk7CgogIENQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKICByY0NsaWVudCA9IENQV0xfVXRpbHM6OkRlZmxhdGVSZWN0KHJjQ2xpZW50LCAyLjBmKTsKCiAgQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKICBnc2QubV9MaW5lV2lkdGggPSAxLjBmOwoKICBDRlhfUGF0aERhdGEgcGF0aENyb3NzOwoKICBpZiAobV9iTW91c2VEb3duKSB7CiAgICByY0NsaWVudC5sZWZ0ICs9IDAuNWY7CiAgICByY0NsaWVudC5yaWdodCArPSAwLjVmOwogICAgcmNDbGllbnQudG9wIC09IDAuNWY7CiAgICByY0NsaWVudC5ib3R0b20gLT0gMC41ZjsKICB9CgogIHBhdGhDcm9zcy5TZXRQb2ludENvdW50KDQpOwogIHBhdGhDcm9zcy5TZXRQb2ludCgwLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC5ib3R0b20sIEZYUFRfTU9WRVRPKTsKICBwYXRoQ3Jvc3MuU2V0UG9pbnQoMSwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LnRvcCwgRlhQVF9MSU5FVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgyLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC50b3AsIEZYUFRfTU9WRVRPKTsKICBwYXRoQ3Jvc3MuU2V0UG9pbnQoMywgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwoKICBwRGV2aWNlLT5EcmF3UGF0aCgKICAgICAgJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLAogICAgICBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSwgR2V0VHJhbnNwYXJlbmN5KCkpLAogICAgICBGWEZJTExfQUxURVJOQVRFKTsKfQoKRlhfQk9PTCBDUFdMX05vdGVfQ2xvc2VCb3g6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG5GbGFnKSB7CiAgU2V0Qm9yZGVyU3R5bGUoUEJTX0lOU0VUKTsKICBJbnZhbGlkYXRlUmVjdChOVUxMKTsKCiAgbV9iTW91c2VEb3duID0gVFJVRTsKCiAgcmV0dXJuIENQV0xfQnV0dG9uOjpPbkxCdXR0b25Eb3duKHBvaW50LCBuRmxhZyk7Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlX0Nsb3NlQm94OjpPbkxCdXR0b25VcChjb25zdCBDUERGX1BvaW50JiBwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG5GbGFnKSB7CiAgbV9iTW91c2VEb3duID0gRkFMU0U7CgogIFNldEJvcmRlclN0eWxlKFBCU19CRVZFTEVEKTsKICBJbnZhbGlkYXRlUmVjdChOVUxMKTsKCiAgcmV0dXJuIENQV0xfQnV0dG9uOjpPbkxCdXR0b25VcChwb2ludCwgbkZsYWcpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX0NvbnRlbnRzCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9Db250ZW50czo6Q1BXTF9Ob3RlX0NvbnRlbnRzKCkgOiBtX3BFZGl0KE5VTEwpIHt9CgpDUFdMX05vdGVfQ29udGVudHM6On5DUFdMX05vdGVfQ29udGVudHMoKSB7fQoKQ0ZYX0J5dGVTdHJpbmcgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRDbGFzc05hbWUoKSBjb25zdCB7CiAgcmV0dXJuICJDUFdMX05vdGVfQ29udGVudHMiOwp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCkgewogIG1fcEVkaXQgPSBuZXcgQ1BXTF9Ob3RlX0VkaXQ7CiAgUFdMX0NSRUFURVBBUkFNIGVjcCA9IGNwOwogIGVjcC5wUGFyZW50V25kID0gdGhpczsKICBlY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX01VTFRJTElORSB8IFBFU19BVVRPUkVUVVJOIHwKICAgICAgICAgICAgICAgIFBFU19URVhUT1ZFUkZMT1cgfCBQRVNfVU5ETyB8IFBFU19TUEVMTENIRUNLOwoKICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwogIG1fcEVkaXQtPkNyZWF0ZShlY3ApOwogIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OlNldFRleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUZXh0KSB7CiAgaWYgKG1fcEVkaXQpIHsKICAgIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CiAgICBtX3BFZGl0LT5TZXRUZXh0KHNUZXh0LmNfc3RyKCkpOwogICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwogICAgT25Ob3RpZnkobV9wRWRpdCwgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CiAgfQp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVfQ29udGVudHM6OkdldFRleHQoKSBjb25zdCB7CiAgaWYgKG1fcEVkaXQpCiAgICByZXR1cm4gbV9wRWRpdC0+R2V0VGV4dCgpOwoKICByZXR1cm4gTCIiOwp9CgpDUFdMX05vdGVJdGVtKiBDUFdMX05vdGVfQ29udGVudHM6OkNyZWF0ZVN1Ykl0ZW0oKSB7CiAgQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gbmV3IENQV0xfTm90ZUl0ZW07CiAgUFdMX0NSRUFURVBBUkFNIGljcCA9IEdldENyZWF0aW9uUGFyYW0oKTsKICBpY3AucFBhcmVudFduZCA9IHRoaXM7CiAgaWNwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19CQUNLR1JPVU5EOwogIHBOb3RlSXRlbS0+Q3JlYXRlKGljcCk7CgogIHBOb3RlSXRlbS0+T25DcmVhdGVOb3RlSXRlbSgpOwoKICBwTm90ZUl0ZW0tPlJlc2V0U3ViamVjdE5hbWUobV9hQ2hpbGRyZW4uR2V0U2l6ZSgpIC0gMSk7CgogIEZYX1NZU1RFTVRJTUUgc3Q7CiAgaWYgKElGWF9TeXN0ZW1IYW5kbGVyKiBwU0ggPSBHZXRTeXN0ZW1IYW5kbGVyKCkpCiAgICBzdCA9IHBTSC0+R2V0TG9jYWxUaW1lKCk7CiAgcE5vdGVJdGVtLT5TZXREYXRlVGltZShzdCk7CgogIHBOb3RlSXRlbS0+U2V0Q29udGVudHMoTCIiKTsKCiAgT25Ob3RpZnkocE5vdGVJdGVtLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKCiAgcmV0dXJuIHBOb3RlSXRlbTsKfQoKaW50MzJfdCBDUFdMX05vdGVfQ29udGVudHM6OkNvdW50U3ViSXRlbXMoKSBjb25zdCB7CiAgcmV0dXJuIG1fYUNoaWxkcmVuLkdldFNpemUoKSAtIDE7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6R2V0U3ViSXRlbXMoaW50MzJfdCBpbmRleCkgY29uc3QgewogIGludDMyX3QgbkluZGV4ID0gaW5kZXggKyAxOwoKICBpZiAobkluZGV4ID4gMCAmJiBuSW5kZXggPCBtX2FDaGlsZHJlbi5HZXRTaXplKCkpCiAgICBpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KG5JbmRleCkpIHsKICAgICAgQVNTRVJUKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKICAgICAgQ1BXTF9Ob3RlSXRlbSogcEl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOwogICAgICByZXR1cm4gcEl0ZW07CiAgICB9CiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkgewogIGludDMyX3QgbkluZGV4ID0gR2V0SXRlbUluZGV4KChDUFdMX05vdGVJdGVtKilwTm90ZUl0ZW0pOwoKICBpZiAobkluZGV4ID4gMCkgewogICAgaWYgKENQV0xfTm90ZUl0ZW0qIHBQV0xOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwTm90ZUl0ZW0pIHsKICAgICAgcFBXTE5vdGVJdGVtLT5LaWxsRm9jdXMoKTsKICAgICAgcFBXTE5vdGVJdGVtLT5EZXN0cm95KCk7CiAgICAgIGRlbGV0ZSBwUFdMTm90ZUl0ZW07CiAgICB9CgogICAgZm9yIChpbnQzMl90IGkgPSBuSW5kZXgsIHN6ID0gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpIDwgc3o7IGkrKykgewogICAgICBpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKSB7CiAgICAgICAgQVNTRVJUKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKICAgICAgICBDUFdMX05vdGVJdGVtKiBwSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7CiAgICAgICAgcEl0ZW0tPlJlc2V0U3ViamVjdE5hbWUoaSk7CiAgICAgIH0KICAgIH0KCiAgICBPbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICB9Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6R2V0SGl0Tm90ZUl0ZW0oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIHsKICBDUERGX1BvaW50IHB0ID0gUGFyZW50VG9DaGlsZChwb2ludCk7CgogIGZvciAoaW50MzJfdCBpID0gMCwgc3ogPSBtX2FDaGlsZHJlbi5HZXRTaXplKCk7IGkgPCBzejsgaSsrKSB7CiAgICBpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKSB7CiAgICAgIGlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikgewogICAgICAgIENQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7CiAgICAgICAgaWYgKElQV0xfTm90ZUl0ZW0qIHBSZXQgPSBwTm90ZUl0ZW0tPkdldEhpdE5vdGVJdGVtKHB0KSkKICAgICAgICAgIHJldHVybiBwUmV0OwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBOVUxMOwp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9EV09SRCBtc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRwdHJfdCB3UGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRwdHJfdCBsUGFyYW0pIHsKICBzd2l0Y2ggKG1zZykgewogICAgY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOiB7CiAgICAgIGludDMyX3QgbkluZGV4ID0gR2V0SXRlbUluZGV4KHBXbmQpOwogICAgICBpZiAobkluZGV4IDwgMCkKICAgICAgICBuSW5kZXggPSAwOwoKICAgICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKICAgICAgUmVzZXRDb250ZW50KG5JbmRleCk7CiAgICAgIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKCiAgICAgIGZvciAoaW50MzJfdCBpID0gbkluZGV4ICsgMSwgc3ogPSBtX2FDaGlsZHJlbi5HZXRTaXplKCk7IGkgPCBzejsgaSsrKSB7CiAgICAgICAgaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKICAgICAgICAgIHBDaGlsZC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgICAgIH0KCiAgICAgIGlmIChDUFdMX1duZCogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKSB7CiAgICAgICAgcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CiAgICAgIH0KICAgIH0KICAgICAgcmV0dXJuOwogICAgY2FzZSBQTk1fU0NST0xMV0lORE9XOgogICAgICBTZXRTY3JvbGxQb3MoQ1BERl9Qb2ludCgwLjBmLCAqKEZYX0ZMT0FUKilsUGFyYW0pKTsKICAgICAgUmVzZXRGYWNlKCk7CiAgICAgIEludmFsaWRhdGVSZWN0KE5VTEwpOwogICAgICByZXR1cm47CiAgICBjYXNlIFBOTV9TRVRDQVJFVElORk86CiAgICAgIGlmIChQV0xfQ0FSRVRfSU5GTyogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkgewogICAgICAgIFBXTF9DQVJFVF9JTkZPIG5ld0luZm8gPSAqcEluZm87CiAgICAgICAgbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CiAgICAgICAgbmV3SW5mby5wdEhlYWQgPSBDaGlsZFRvUGFyZW50KHBJbmZvLT5wdEhlYWQpOwogICAgICAgIG5ld0luZm8ucHRGb290ID0gQ2hpbGRUb1BhcmVudChwSW5mby0+cHRGb290KTsKCiAgICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICAgIHBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRDQVJFVElORk8sIChpbnRwdHJfdCkmbmV3SW5mbywgMCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIGNhc2UgUE5NX05PVEVSRVNFVDogewogICAgICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwogICAgICBSZXNldENvbnRlbnQoMCk7CiAgICAgIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShUUlVFKTsKCiAgICAgIGZvciAoaW50MzJfdCBpID0gMSwgc3ogPSBtX2FDaGlsZHJlbi5HZXRTaXplKCk7IGkgPCBzejsgaSsrKSB7CiAgICAgICAgaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkKICAgICAgICAgIHBDaGlsZC0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgICAgIH0KCiAgICAgIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CiAgICAgIFJlc2V0Q29udGVudCgwKTsKICAgICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwogICAgfQogICAgICByZXR1cm47CiAgfQoKICBDUFdMX1duZDo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpPbkxCdXR0b25Eb3duKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9EV09SRCBuRmxhZykgewogIGlmIChDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCwgbkZsYWcpKQogICAgcmV0dXJuIFRSVUU7CgogIGlmICghbV9wRWRpdC0+SXNGb2N1c2VkKCkpIHsKICAgIG1fcEVkaXQtPlNldEZvY3VzKCk7CiAgfQoKICByZXR1cm4gVFJVRTsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OlNldEVkaXRGb2N1cyhGWF9CT09MIGJMYXN0KSB7CiAgaWYgKCFtX3BFZGl0LT5Jc0ZvY3VzZWQoKSkgewogICAgbV9wRWRpdC0+U2V0Rm9jdXMoKTsKICAgIG1fcEVkaXQtPlNldENhcmV0KGJMYXN0ID8gbV9wRWRpdC0+R2V0VG90YWxXb3JkcygpIDogMCk7CiAgfQp9CgpDUFdMX0VkaXQqIENQV0xfTm90ZV9Db250ZW50czo6R2V0RWRpdCgpIGNvbnN0IHsKICByZXR1cm4gbV9wRWRpdDsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkVuYWJsZU1vZGlmeShGWF9CT09MIGJFbmFibGVkKSB7CiAgaWYgKCFiRW5hYmxlZCkKICAgIG1fcEVkaXQtPkFkZEZsYWcoUFdTX1JFQURPTkxZKTsKICBlbHNlCiAgICBtX3BFZGl0LT5SZW1vdmVGbGFnKFBXU19SRUFET05MWSk7CgogIGZvciAoaW50MzJfdCBpID0gMCwgc3ogPSBtX2FDaGlsZHJlbi5HZXRTaXplKCk7IGkgPCBzejsgaSsrKSB7CiAgICBpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKSB7CiAgICAgIGlmIChwQ2hpbGQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIikgewogICAgICAgIENQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7CiAgICAgICAgcE5vdGVJdGVtLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwogICAgICB9CiAgICB9CiAgfQp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKSB7CiAgaWYgKCFiRW5hYmxlZCkKICAgIG1fcEVkaXQtPkFkZEZsYWcoUEVTX05PUkVBRCk7CiAgZWxzZQogICAgbV9wRWRpdC0+UmVtb3ZlRmxhZyhQRVNfTk9SRUFEKTsKCiAgZm9yIChpbnQzMl90IGkgPSAwLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpIHsKICAgICAgaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKSB7CiAgICAgICAgQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKICAgICAgICBwTm90ZUl0ZW0tPkVuYWJsZVJlYWQoYkVuYWJsZWQpOwogICAgICB9CiAgICB9CiAgfQp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZUl0ZW0KICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlSXRlbTo6Q1BXTF9Ob3RlSXRlbSgpCiAgICA6IG1fcFN1YmplY3QoTlVMTCksCiAgICAgIG1fcERhdGVUaW1lKE5VTEwpLAogICAgICBtX3BDb250ZW50cyhOVUxMKSwKICAgICAgbV9wUHJpdmF0ZURhdGEoTlVMTCksCiAgICAgIG1fc0F1dGhvcihMIiIpLAogICAgICBtX2ZPbGRJdGVtSGVpZ2h0KDAuMGYpLAogICAgICBtX2JTaXplQ2hhbmdlZChGQUxTRSksCiAgICAgIG1fYkFsbG93TW9kaWZ5KFRSVUUpIHt9CgpDUFdMX05vdGVJdGVtOjp+Q1BXTF9Ob3RlSXRlbSgpIHt9CgpDRlhfQnl0ZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRDbGFzc05hbWUoKSBjb25zdCB7CiAgcmV0dXJuICJDUFdMX05vdGVJdGVtIjsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwKSB7CiAgQ1BXTF9Db2xvciBzVGV4dENvbG9yOwoKICBpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUoR2V0QmFja2dyb3VuZENvbG9yKCkpKQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CiAgZWxzZQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgogIG1fcFN1YmplY3QgPSBuZXcgQ1BXTF9MYWJlbDsKICBQV0xfQ1JFQVRFUEFSQU0gc2NwID0gY3A7CiAgc2NwLnBQYXJlbnRXbmQgPSB0aGlzOwogIHNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7CiAgc2NwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwogIG1fcFN1YmplY3QtPkNyZWF0ZShzY3ApOwoKICBtX3BEYXRlVGltZSA9IG5ldyBDUFdMX0xhYmVsOwogIFBXTF9DUkVBVEVQQVJBTSBkY3AgPSBjcDsKICBkY3AucFBhcmVudFduZCA9IHRoaXM7CiAgZGNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19SSUdIVCB8IFBFU19UT1A7CiAgZGNwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwogIG1fcERhdGVUaW1lLT5DcmVhdGUoZGNwKTsKCiAgbV9wQ29udGVudHMgPSBuZXcgQ1BXTF9Ob3RlX0NvbnRlbnRzOwogIFBXTF9DUkVBVEVQQVJBTSBjY3AgPSBjcDsKICBjY3AucFBhcmVudFduZCA9IHRoaXM7CiAgLy8gY2NwLnNCYWNrZ3JvdW5kQ29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOwogIGNjcC5zQmFja2dyb3VuZENvbG9yID0KICAgICAgQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLCAyNDAgLyAyNTUuMGYsIDI0MCAvIDI1NS4wZiwgMjQwIC8gMjU1LjBmKTsKICBjY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUFdTX0JBQ0tHUk9VTkQ7CiAgbV9wQ29udGVudHMtPkNyZWF0ZShjY3ApOwogIG1fcENvbnRlbnRzLT5TZXRJdGVtU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7CiAgbV9wQ29udGVudHMtPlNldFRvcFNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwogIG1fcENvbnRlbnRzLT5TZXRCb3R0b21TcGFjZShQT1BVUF9JVEVNX1NQQUNFKTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpSZVBvc0NoaWxkV25kKCkgewogIGlmIChJc1ZhbGlkKCkpIHsKICAgIEFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwogICAgQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOwogICAgQVNTRVJUKG1fcENvbnRlbnRzICE9IE5VTEwpOwoKICAgIENQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKCiAgICBDUERGX1JlY3QgcmNTdWJqZWN0ID0gcmNDbGllbnQ7CiAgICByY1N1YmplY3QubGVmdCArPSBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwogICAgcmNTdWJqZWN0LnRvcCA9IHJjQ2xpZW50LnRvcDsKICAgIHJjU3ViamVjdC5yaWdodCA9CiAgICAgICAgUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsCiAgICAgICAgICAgICAgICByY0NsaWVudC5yaWdodCk7CiAgICByY1N1YmplY3QuYm90dG9tID0gcmNTdWJqZWN0LnRvcCAtIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CiAgICByY1N1YmplY3QuTm9ybWFsaXplKCk7CiAgICBtX3BTdWJqZWN0LT5Nb3ZlKHJjU3ViamVjdCwgVFJVRSwgRkFMU0UpOwogICAgbV9wU3ViamVjdC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjU3ViamVjdCkpOwoKICAgIENQREZfUmVjdCByY0RhdGUgPSByY0NsaWVudDsKICAgIHJjRGF0ZS5yaWdodCAtPSBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwogICAgcmNEYXRlLmxlZnQgPQogICAgICAgIFBXTF9NQVgocmNEYXRlLnJpZ2h0IC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSAtIDEuMGYsCiAgICAgICAgICAgICAgICByY1N1YmplY3QucmlnaHQpOwogICAgcmNEYXRlLmJvdHRvbSA9IHJjRGF0ZS50b3AgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKICAgIHJjRGF0ZS5Ob3JtYWxpemUoKTsKICAgIG1fcERhdGVUaW1lLT5Nb3ZlKHJjRGF0ZSwgVFJVRSwgRkFMU0UpOwogICAgbV9wRGF0ZVRpbWUtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0RhdGUpKTsKCiAgICBDUERGX1JlY3QgcmNDb250ZW50cyA9IHJjQ2xpZW50OwogICAgcmNDb250ZW50cy5sZWZ0ICs9IDEuMGY7CiAgICByY0NvbnRlbnRzLnJpZ2h0IC09IDEuMGY7CiAgICByY0NvbnRlbnRzLnRvcCA9IHJjRGF0ZS5ib3R0b20gLSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NOwogICAgcmNDb250ZW50cy5ib3R0b20gKz0gUE9QVVBfSVRFTV9CT1RUT01XSURUSDsKICAgIHJjQ29udGVudHMuTm9ybWFsaXplKCk7CiAgICBtX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBUUlVFLCBGQUxTRSk7CiAgICBtX3BDb250ZW50cy0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQ29udGVudHMpKTsKICB9CgogIFNldENsaXBSZWN0KENQV0xfVXRpbHM6OkluZmxhdGVSZWN0KEdldFdpbmRvd1JlY3QoKSwgMS4wZikpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldFByaXZhdGVEYXRhKHZvaWQqIHBEYXRhKSB7CiAgbV9wUHJpdmF0ZURhdGEgPSBwRGF0YTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKSB7CiAgQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsKICBTZXRCYWNrZ3JvdW5kQ29sb3Ioc0JLKTsKCiAgQ1BXTF9Db2xvciBzVGV4dENvbG9yOwoKICBpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUoc0JLKSkKICAgIHNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOwogIGVsc2UKICAgIHNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOwoKICBTZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CiAgaWYgKG1fcFN1YmplY3QpCiAgICBtX3BTdWJqZWN0LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CiAgaWYgKG1fcERhdGVUaW1lKQogICAgbV9wRGF0ZVRpbWUtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKCiAgSW52YWxpZGF0ZVJlY3QobnVsbHB0cik7CgogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0QmtDb2xvcih0aGlzKTsKICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0U3ViamVjdE5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKSB7CiAgaWYgKG1fcFN1YmplY3QpIHsKICAgIG1fcFN1YmplY3QtPlNldFRleHQoc05hbWUuY19zdHIoKSk7CiAgfQoKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBwTm90aWZ5LT5PblNldFN1YmplY3ROYW1lKHRoaXMpOwogIH0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRBdXRob3JOYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkgewogIG1fc0F1dGhvciA9IHNOYW1lOwogIFJlc2V0U3ViamVjdE5hbWUoLTEpOwoKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBwTm90aWZ5LT5PblNldEF1dGhvck5hbWUodGhpcyk7CiAgfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlJlc2V0U3ViamVjdE5hbWUoaW50MzJfdCBuSXRlbUluZGV4KSB7CiAgaWYgKG5JdGVtSW5kZXggPCAwKSB7CiAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgICBBU1NFUlQocFBhcmVudC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZV9Db250ZW50cyIpOwoKICAgICAgQ1BXTF9Ob3RlX0NvbnRlbnRzKiBwQ29udGVudHMgPSAoQ1BXTF9Ob3RlX0NvbnRlbnRzKilwUGFyZW50OwogICAgICBuSXRlbUluZGV4ID0gcENvbnRlbnRzLT5HZXRJdGVtSW5kZXgodGhpcyk7CiAgICB9CiAgfQoKICBjb25zdCBDUFdMX05vdGUqIHBOb3RlID0gR2V0Tm90ZSgpOwogIEFTU0VSVChwTm90ZSAhPSBOVUxMKTsKCiAgQ0ZYX1dpZGVTdHJpbmcgc1N1YmplY3Q7CiAgc1N1YmplY3QuRm9ybWF0KHBOb3RlLT5HZXRSZXBseVN0cmluZygpLmNfc3RyKCksIG5JdGVtSW5kZXgpOwoKICBpZiAoIW1fc0F1dGhvci5Jc0VtcHR5KCkpIHsKICAgIHNTdWJqZWN0ICs9IEwiIC0gIjsKICAgIHNTdWJqZWN0ICs9IG1fc0F1dGhvcjsKICB9CiAgU2V0U3ViamVjdE5hbWUoc1N1YmplY3QpOwogIFJlUG9zQ2hpbGRXbmQoKTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXREYXRlVGltZShGWF9TWVNURU1USU1FIHRpbWUpIHsKICBtX2R0Tm90ZSA9IHRpbWU7CgogIENGWF9XaWRlU3RyaW5nIHN3VGltZTsKICBzd1RpbWUuRm9ybWF0KEwiJTA0ZC0lMDJkLSUwMmQgJTAyZDolMDJkOiUwMmQiLCB0aW1lLndZZWFyLCB0aW1lLndNb250aCwKICAgICAgICAgICAgICAgIHRpbWUud0RheSwgdGltZS53SG91ciwgdGltZS53TWludXRlLCB0aW1lLndTZWNvbmQpOwogIGlmIChtX3BEYXRlVGltZSkgewogICAgbV9wRGF0ZVRpbWUtPlNldFRleHQoc3dUaW1lLmNfc3RyKCkpOwogIH0KCiAgUmVQb3NDaGlsZFduZCgpOwoKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBwTm90aWZ5LT5PblNldERhdGVUaW1lKHRoaXMpOwogIH0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRDb250ZW50cyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc0NvbnRlbnRzKSB7CiAgaWYgKG1fcENvbnRlbnRzKSB7CiAgICBtX3BDb250ZW50cy0+U2V0VGV4dChzQ29udGVudHMpOwogIH0KCiAgaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkgewogICAgcE5vdGlmeS0+T25TZXRDb250ZW50cyh0aGlzKTsKICB9Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudE5vdGVJdGVtKCkgY29uc3QgewogIGlmIChDUFdMX1duZCogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKSB7CiAgICBpZiAoQ1BXTF9XbmQqIHBHcmFuZCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpKSB7CiAgICAgIEFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CiAgICAgIHJldHVybiAoQ1BXTF9Ob3RlSXRlbSopcEdyYW5kOwogICAgfQogIH0KCiAgcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFBhcmVudEl0ZW0oKSBjb25zdCB7CiAgcmV0dXJuIEdldFBhcmVudE5vdGVJdGVtKCk7Cn0KCkNQV0xfRWRpdCogQ1BXTF9Ob3RlSXRlbTo6R2V0RWRpdCgpIGNvbnN0IHsKICBpZiAobV9wQ29udGVudHMpCiAgICByZXR1cm4gbV9wQ29udGVudHMtPkdldEVkaXQoKTsKICByZXR1cm4gTlVMTDsKfQoKdm9pZCogQ1BXTF9Ob3RlSXRlbTo6R2V0UHJpdmF0ZURhdGEoKSBjb25zdCB7CiAgcmV0dXJuIG1fcFByaXZhdGVEYXRhOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRBdXRob3JOYW1lKCkgY29uc3QgewogIHJldHVybiBtX3NBdXRob3I7Cn0KCkNQV0xfQ29sb3IgQ1BXTF9Ob3RlSXRlbTo6R2V0QmtDb2xvcigpIGNvbnN0IHsKICByZXR1cm4gR2V0QmFja2dyb3VuZENvbG9yKCk7Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldENvbnRlbnRzKCkgY29uc3QgewogIGlmIChtX3BDb250ZW50cykKICAgIHJldHVybiBtX3BDb250ZW50cy0+R2V0VGV4dCgpOwoKICByZXR1cm4gTCIiOwp9CgpGWF9TWVNURU1USU1FIENQV0xfTm90ZUl0ZW06OkdldERhdGVUaW1lKCkgY29uc3QgewogIHJldHVybiBtX2R0Tm90ZTsKfQoKQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlSXRlbTo6R2V0U3ViamVjdE5hbWUoKSBjb25zdCB7CiAgaWYgKG1fcFN1YmplY3QpCiAgICByZXR1cm4gbV9wU3ViamVjdC0+R2V0VGV4dCgpOwoKICByZXR1cm4gTCIiOwp9CgpDUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpDcmVhdGVOb3RlSXRlbSgpIHsKICBpZiAobV9wQ29udGVudHMpCiAgICByZXR1cm4gbV9wQ29udGVudHMtPkNyZWF0ZVN1Ykl0ZW0oKTsKCiAgcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkNyZWF0ZVN1Ykl0ZW0oKSB7CiAgcmV0dXJuIENyZWF0ZU5vdGVJdGVtKCk7Cn0KCmludDMyX3QgQ1BXTF9Ob3RlSXRlbTo6Q291bnRTdWJJdGVtcygpIGNvbnN0IHsKICBpZiAobV9wQ29udGVudHMpCiAgICByZXR1cm4gbV9wQ29udGVudHMtPkNvdW50U3ViSXRlbXMoKTsKCiAgcmV0dXJuIDA7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldFN1Ykl0ZW1zKGludDMyX3QgaW5kZXgpIGNvbnN0IHsKICBpZiAobV9wQ29udGVudHMpCiAgICByZXR1cm4gbV9wQ29udGVudHMtPkdldFN1Ykl0ZW1zKGluZGV4KTsKCiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RGVsZXRlU3ViSXRlbShJUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0pIHsKICBLaWxsRm9jdXMoKTsKCiAgaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkgewogICAgcE5vdGlmeS0+T25JdGVtRGVsZXRlKHBOb3RlSXRlbSk7CiAgfQoKICBpZiAobV9wQ29udGVudHMpCiAgICBtX3BDb250ZW50cy0+RGVsZXRlU3ViSXRlbShwTm90ZUl0ZW0pOwp9CgpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpHZXRIaXROb3RlSXRlbShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgewogIENQREZfUG9pbnQgcHQgPSBQYXJlbnRUb0NoaWxkKHBvaW50KTsKCiAgaWYgKFduZEhpdFRlc3QocHQpKSB7CiAgICBpZiAobV9wQ29udGVudHMpIHsKICAgICAgaWYgKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IG1fcENvbnRlbnRzLT5HZXRIaXROb3RlSXRlbShwdCkpCiAgICAgICAgcmV0dXJuIHBOb3RlSXRlbTsKICAgIH0KCiAgICByZXR1cm4gdGhpczsKICB9CgogIHJldHVybiBOVUxMOwp9CgpJUFdMX05vdGVJdGVtKiBDUFdMX05vdGVJdGVtOjpHZXRGb2N1c2VkTm90ZUl0ZW0oKSBjb25zdCB7CiAgaWYgKGNvbnN0IENQV0xfV25kKiBwV25kID0gR2V0Rm9jdXNlZCgpKSB7CiAgICBpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpIHsKICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gcFduZC0+R2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICBBU1NFUlQocFBhcmVudC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZV9Db250ZW50cyIpOwoKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBHcmFuZCA9IHBQYXJlbnQtPkdldFBhcmVudFdpbmRvdygpKSB7CiAgICAgICAgICBBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwogICAgICAgICAgcmV0dXJuIChDUFdMX05vdGVJdGVtKilwR3JhbmQ7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gTlVMTDsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbUhlaWdodChGWF9GTE9BVCBmTGltaXRXaWR0aCkgewogIGlmIChmTGltaXRXaWR0aCA+IDApIHsKICAgIGlmICghbV9iU2l6ZUNoYW5nZWQpCiAgICAgIHJldHVybiBtX2ZPbGRJdGVtSGVpZ2h0OwoKICAgIG1fYlNpemVDaGFuZ2VkID0gRkFMU0U7CgogICAgQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CgogICAgRlhfRkxPQVQgZlJldCA9IG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwogICAgRlhfRkxPQVQgZkJvcmRlcldpZHRoID0gKEZYX0ZMT0FUKUdldEJvcmRlcldpZHRoKCk7CiAgICBpZiAoZkxpbWl0V2lkdGggPiBmQm9yZGVyV2lkdGggKiAyKQogICAgICBmUmV0ICs9IG1fcENvbnRlbnRzLT5HZXRDb250ZW50c0hlaWdodChmTGltaXRXaWR0aCAtIGZCb3JkZXJXaWR0aCAqIDIpOwogICAgZlJldCArPSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NICsgUE9QVVBfSVRFTV9CT1RUT01XSURUSCArIGZCb3JkZXJXaWR0aCAqIDI7CgogICAgcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQgPSBmUmV0OwogIH0KCiAgcmV0dXJuIDA7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1MZWZ0TWFyZ2luKCkgewogIHJldHVybiBQT1BVUF9JVEVNX1NJREVNQVJHSU47Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZUl0ZW06OkdldEl0ZW1SaWdodE1hcmdpbigpIHsKICByZXR1cm4gUE9QVVBfSVRFTV9TSURFTUFSR0lOOwp9CgpGWF9CT09MIENQV0xfTm90ZUl0ZW06Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKSB7CiAgaWYgKCFtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSB7CiAgICBTZXROb3RlRm9jdXMoRkFMU0UpOwogIH0KCiAgQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsIG5GbGFnKTsKCiAgcmV0dXJuIFRSVUU7Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlSXRlbTo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKSB7CiAgaWYgKCFtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSB7CiAgICBTZXROb3RlRm9jdXMoRkFMU0UpOwogICAgUG9wdXBOb3RlSXRlbU1lbnUocG9pbnQpOwoKICAgIHJldHVybiBUUlVFOwogIH0KCiAgcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCwgbkZsYWcpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRwdHJfdCB3UGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cHRyX3QgbFBhcmFtKSB7CiAgc3dpdGNoIChtc2cpIHsKICAgIGNhc2UgUE5NX05PVEVFRElUQ0hBTkdFRDoKICAgICAgbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwoKICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICBwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICAgICAgfQogICAgICByZXR1cm47CiAgICBjYXNlIFBOTV9TRVRDQVJFVElORk86CiAgICAgIGlmIChQV0xfQ0FSRVRfSU5GTyogcEluZm8gPSAoUFdMX0NBUkVUX0lORk8qKXdQYXJhbSkgewogICAgICAgIFBXTF9DQVJFVF9JTkZPIG5ld0luZm8gPSAqcEluZm87CiAgICAgICAgbmV3SW5mby5iVmlzaWJsZSA9IFRSVUU7CiAgICAgICAgbmV3SW5mby5wdEhlYWQgPSBDaGlsZFRvUGFyZW50KHBJbmZvLT5wdEhlYWQpOwogICAgICAgIG5ld0luZm8ucHRGb290ID0gQ2hpbGRUb1BhcmVudChwSW5mby0+cHRGb290KTsKCiAgICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICAgIHBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRDQVJFVElORk8sIChpbnRwdHJfdCkmbmV3SW5mbywgMCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybjsKICAgIGNhc2UgUE5NX05PVEVSRVNFVDoKICAgICAgbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwogICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CgogICAgICByZXR1cm47CiAgfQoKICBDUFdMX1duZDo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6UG9wdXBOb3RlSXRlbU1lbnUoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQpIHsKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBpbnQzMl90IHgsIHk7CiAgICBQV0x0b1duZChwb2ludCwgeCwgeSk7CiAgICBpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKICAgICAgcFNILT5DbGllbnRUb1NjcmVlbihHZXRBdHRhY2hlZEhXbmQoKSwgeCwgeSk7CiAgICBwTm90aWZ5LT5PblBvcHVwTWVudSh0aGlzLCB4LCB5KTsKICB9Cn0KCmNvbnN0IENQV0xfTm90ZSogQ1BXTF9Ob3RlSXRlbTo6R2V0Tm90ZSgpIGNvbnN0IHsKICBpZiAoY29uc3QgQ1BXTF9XbmQqIHBSb290ID0gR2V0Um9vdFduZCgpKSB7CiAgICBBU1NFUlQocFJvb3QtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CiAgICBDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcFJvb3Q7CiAgICBpZiAocE5vdGVJdGVtLT5Jc1RvcEl0ZW0oKSkgewogICAgICByZXR1cm4gKENQV0xfTm90ZSopcE5vdGVJdGVtOwogICAgfQogIH0KCiAgcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZU5vdGlmeSogQ1BXTF9Ob3RlSXRlbTo6R2V0Tm90ZU5vdGlmeSgpIGNvbnN0IHsKICBpZiAoY29uc3QgQ1BXTF9Ob3RlKiBwTm90ZSA9IEdldE5vdGUoKSkKICAgIHJldHVybiBwTm90ZS0+R2V0Tm90ZU5vdGlmeSgpOwoKICByZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpPbkNyZWF0ZU5vdGVJdGVtKCkgewogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uSXRlbUNyZWF0ZSh0aGlzKTsKICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25Db250ZW50c1ZhbGlkYXRlKCkgewogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0Q29udGVudHModGhpcyk7CiAgfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldE5vdGVGb2N1cyhGWF9CT09MIGJMYXN0KSB7CiAgbV9wQ29udGVudHMtPlNldEVkaXRGb2N1cyhiTGFzdCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpIHsKICBtX3BDb250ZW50cy0+RW5hYmxlTW9kaWZ5KGJFbmFibGVkKTsKICBtX2JBbGxvd01vZGlmeSA9IGJFbmFibGVkOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OkVuYWJsZVJlYWQoRlhfQk9PTCBiRW5hYmxlZCkgewogIG1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGUKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlOjpDUFdMX05vdGUoSVBvcHVwX05vdGUqIHBQb3B1cE5vdGUsCiAgICAgICAgICAgICAgICAgICAgIElQV0xfTm90ZU5vdGlmeSogcE5vdGVOb3RpZnksCiAgICAgICAgICAgICAgICAgICAgIElQV0xfTm90ZUhhbmRsZXIqIHBOb3RlSGFuZGxlcikKICAgIDogbV9wQXV0aG9yKE5VTEwpLAogICAgICBtX3BJY29uKE5VTEwpLAogICAgICBtX3BDbG9zZUJveChOVUxMKSwKICAgICAgbV9wTEJCb3goTlVMTCksCiAgICAgIG1fcFJCQm94KE5VTEwpLAogICAgICBtX3BDb250ZW50c0JhcihOVUxMKSwKICAgICAgbV9wT3B0aW9ucyhOVUxMKSwKICAgICAgbV9wTm90ZU5vdGlmeShwTm90ZU5vdGlmeSksCiAgICAgIG1fYlJlc2l6aW5nKEZBTFNFKSwKICAgICAgbV9yY0NhcHRpb24oMCwgMCwgMCwgMCksCiAgICAgIG1fYkVuYWxibGVOb3RpZnkoVFJVRSksCiAgICAgIG1fcFBvcHVwTm90ZShwUG9wdXBOb3RlKSB7fQoKQ1BXTF9Ob3RlOjp+Q1BXTF9Ob3RlKCkge30KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZTo6UmVwbHkoKSB7CiAgcmV0dXJuIENyZWF0ZU5vdGVJdGVtKCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVOb3RpZnkoRlhfQk9PTCBiRW5hYmxlZCkgewogIG1fYkVuYWxibGVOb3RpZnkgPSBiRW5hYmxlZDsKfQoKdm9pZCBDUFdMX05vdGU6OlJlUG9zQ2hpbGRXbmQoKSB7CiAgUmVQb3NOb3RlQ2hpbGRyZW4oKTsKICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgUmVzZXRTY3JvbGxCYXIoKTsKICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgT25Ob3RpZnkodGhpcywgUE5NX05PVEVFRElUQ0hBTkdFRCwgMCwgMCk7CiAgaWYgKGNvbnN0IENQV0xfV25kKiBwV25kID0gR2V0Rm9jdXNlZCgpKSB7CiAgICBpZiAocFduZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfRWRpdCIpIHsKICAgICAgQ1BXTF9FZGl0KiBwRWRpdCA9IChDUFdMX0VkaXQqKXBXbmQ7CiAgICAgIHBFZGl0LT5TZXRDYXJldChwRWRpdC0+R2V0Q2FyZXQoKSk7CiAgICB9CiAgfQp9CgpGWF9CT09MIENQV0xfTm90ZTo6UmVzZXRTY3JvbGxCYXIoKSB7CiAgRlhfQk9PTCBiU2Nyb2xsQ2hhbmdlZCA9IEZBTFNFOwoKICBpZiAoU2Nyb2xsQmFyU2hvdWxkVmlzaWJsZSgpKSB7CiAgICBpZiAoIW1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkgewogICAgICBtX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShUUlVFKTsKICAgICAgaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkgewogICAgICAgIG1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKICAgICAgICBiU2Nyb2xsQ2hhbmdlZCA9IFRSVUU7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkgewogICAgICBtX3BDb250ZW50c0Jhci0+U2V0VmlzaWJsZShGQUxTRSk7CiAgICAgIG1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCiAgICAgIGJTY3JvbGxDaGFuZ2VkID0gVFJVRTsKICAgIH0KICB9CgogIGlmIChiU2Nyb2xsQ2hhbmdlZCkgewogICAgQ1BERl9SZWN0IHJjTm90ZSA9IEdldENsaWVudFJlY3QoKTsKICAgIENQREZfUmVjdCByY0NvbnRlbnRzID0gbV9wQ29udGVudHMtPkdldFdpbmRvd1JlY3QoKTsKICAgIHJjQ29udGVudHMucmlnaHQgPSByY05vdGUucmlnaHQgLSAzLjBmOwogICAgaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKICAgICAgcmNDb250ZW50cy5yaWdodCAtPSBQV0xfU0NST0xMQkFSX1dJRFRIOwogICAgbV9wQ29udGVudHMtPk1vdmUocmNDb250ZW50cywgVFJVRSwgVFJVRSk7CiAgICBtX3BDb250ZW50cy0+U2V0U2Nyb2xsUG9zKENQREZfUG9pbnQoMC4wZiwgMC4wZikpOwogICAgbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOwogIH0KCiAgcmV0dXJuIGJTY3JvbGxDaGFuZ2VkOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6U2Nyb2xsQmFyU2hvdWxkVmlzaWJsZSgpIHsKICBDUERGX1JlY3QgcmNDb250ZW50c0ZhY3QgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwogIENQREZfUmVjdCByY0NvbnRlbnRzQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsKCiAgcmV0dXJuIHJjQ29udGVudHNGYWN0LkhlaWdodCgpID4gcmNDb250ZW50c0NsaWVudC5IZWlnaHQoKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldE9wdGlvbnNUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkgewogIGlmIChtX3BPcHRpb25zKQogICAgbV9wT3B0aW9ucy0+U2V0VGV4dChzVGV4dCk7CgogIFJlUG9zTm90ZUNoaWxkcmVuKCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpSZVBvc05vdGVDaGlsZHJlbigpIHsKICBpZiAobV9iUmVzaXppbmcpCiAgICByZXR1cm47CgogIG1fYlJlc2l6aW5nID0gVFJVRTsKCiAgaWYgKElzVmFsaWQoKSkgewogICAgQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wQXV0aG9yICE9IE5VTEwpOwogICAgQVNTRVJUKG1fcENsb3NlQm94ICE9IE5VTEwpOwogICAgQVNTRVJUKG1fcEljb24gIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wTEJCb3ggIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wUkJCb3ggIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wQ29udGVudHNCYXIgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wT3B0aW9ucyAhPSBOVUxMKTsKCiAgICBDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CgogICAgQ1BERl9SZWN0IHJjSWNvbiA9IHJjQ2xpZW50OwogICAgcmNJY29uLnRvcCAtPSAyLjBmOwogICAgcmNJY29uLnJpZ2h0ID0gcmNJY29uLmxlZnQgKyAxNC4wZjsKICAgIHJjSWNvbi5ib3R0b20gPSByY0ljb24udG9wIC0gMTQuMGY7CiAgICByY0ljb24uTm9ybWFsaXplKCk7CiAgICBtX3BJY29uLT5Nb3ZlKHJjSWNvbiwgVFJVRSwgRkFMU0UpOwogICAgbV9wSWNvbi0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjSWNvbikpOwoKICAgIENQREZfUmVjdCByY0Nsb3NlQm94ID0gcmNDbGllbnQ7CiAgICByY0Nsb3NlQm94LnJpZ2h0IC09IDEuMGY7CiAgICByY0Nsb3NlQm94LnRvcCAtPSAxLjBmOwogICAgcmNDbG9zZUJveC5sZWZ0ID0gcmNDbG9zZUJveC5yaWdodCAtIDE0LjBmOwogICAgcmNDbG9zZUJveC5ib3R0b20gPSByY0Nsb3NlQm94LnRvcCAtIDE0LjBmOwogICAgcmNDbG9zZUJveC5Ob3JtYWxpemUoKTsKICAgIG1fcENsb3NlQm94LT5Nb3ZlKHJjQ2xvc2VCb3gsIFRSVUUsIEZBTFNFKTsKICAgIG1fcENsb3NlQm94LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDbG9zZUJveCkpOwoKICAgIENQREZfUmVjdCByY0RhdGUgPSByY0NsaWVudDsKICAgIHJjRGF0ZS5yaWdodCA9IHJjQ2xvc2VCb3gubGVmdCAtIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CiAgICByY0RhdGUubGVmdCA9CiAgICAgICAgUFdMX01BWChyY0RhdGUucmlnaHQgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpIC0gMS4wZiwKICAgICAgICAgICAgICAgIHJjSWNvbi5yaWdodCArIDEuMGYpOwogICAgcmNEYXRlLnRvcCA9IHJjQ2xpZW50LnRvcCAtIDIuMGY7CiAgICByY0RhdGUuYm90dG9tID0gcmNEYXRlLnRvcCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwogICAgcmNEYXRlLk5vcm1hbGl6ZSgpOwogICAgbV9wRGF0ZVRpbWUtPk1vdmUocmNEYXRlLCBUUlVFLCBGQUxTRSk7CiAgICBtX3BEYXRlVGltZS0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjRGF0ZSkpOwoKICAgIENQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsKICAgIHJjU3ViamVjdC50b3AgPSByY0NsaWVudC50b3AgLSAyLjBmOwogICAgcmNTdWJqZWN0LmxlZnQgPSByY0ljb24ucmlnaHQgKyBQT1BVUF9JVEVNX1RFWFRfSU5ERU5UOwogICAgcmNTdWJqZWN0LnJpZ2h0ID0KICAgICAgICBQV0xfTUlOKHJjU3ViamVjdC5sZWZ0ICsgbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwKICAgICAgICAgICAgICAgIHJjRGF0ZS5sZWZ0IC0gMS4wZik7CiAgICByY1N1YmplY3QuYm90dG9tID0gcmNTdWJqZWN0LnRvcCAtIG1fcFN1YmplY3QtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CiAgICByY1N1YmplY3QuTm9ybWFsaXplKCk7CiAgICBtX3BTdWJqZWN0LT5Nb3ZlKHJjU3ViamVjdCwgVFJVRSwgRkFMU0UpOwogICAgbV9wU3ViamVjdC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjU3ViamVjdCkpOwoKICAgIENQREZfUmVjdCByY09wdGlvbnMgPSByY0NsaWVudDsKICAgIHJjT3B0aW9ucy5sZWZ0ID0KICAgICAgICBQV0xfTUFYKHJjT3B0aW9ucy5yaWdodCAtIG1fcE9wdGlvbnMtPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSwKICAgICAgICAgICAgICAgIHJjSWNvbi5yaWdodCArIDEuMGYpOwogICAgcmNPcHRpb25zLnRvcCA9IHJjU3ViamVjdC5ib3R0b20gLSA0LjBmOwogICAgcmNPcHRpb25zLmJvdHRvbSA9IHJjT3B0aW9ucy50b3AgLSBtX3BPcHRpb25zLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwogICAgcmNPcHRpb25zLk5vcm1hbGl6ZSgpOwogICAgbV9wT3B0aW9ucy0+TW92ZShyY09wdGlvbnMsIFRSVUUsIEZBTFNFKTsKICAgIG1fcE9wdGlvbnMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY09wdGlvbnMpKTsKCiAgICBDUERGX1JlY3QgcmNBdXRob3IgPSByY0NsaWVudDsKICAgIHJjQXV0aG9yLnRvcCA9IHJjU3ViamVjdC5ib3R0b20gLSA0LjBmOwogICAgcmNBdXRob3IubGVmdCA9IHJjU3ViamVjdC5sZWZ0OwogICAgcmNBdXRob3IucmlnaHQgPQogICAgICAgIFBXTF9NSU4ocmNTdWJqZWN0LmxlZnQgKyBtX3BBdXRob3ItPkdldENvbnRlbnRSZWN0KCkuV2lkdGgoKSArIDEuMGYsCiAgICAgICAgICAgICAgICByY09wdGlvbnMubGVmdCAtIDEuMGYpOwogICAgcmNBdXRob3IuYm90dG9tID0gcmNBdXRob3IudG9wIC0gbV9wQXV0aG9yLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwogICAgcmNBdXRob3IuTm9ybWFsaXplKCk7CiAgICBtX3BBdXRob3ItPk1vdmUocmNBdXRob3IsIFRSVUUsIEZBTFNFKTsKICAgIG1fcEF1dGhvci0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjQXV0aG9yKSk7CgogICAgQ1BERl9SZWN0IHJjTEJCb3ggPSByY0NsaWVudDsKICAgIHJjTEJCb3gudG9wID0gcmNMQkJveC5ib3R0b20gKyA3LjBmOwogICAgcmNMQkJveC5yaWdodCA9IHJjTEJCb3gubGVmdCArIDcuMGY7CiAgICByY0xCQm94Lk5vcm1hbGl6ZSgpOwogICAgbV9wTEJCb3gtPk1vdmUocmNMQkJveCwgVFJVRSwgRkFMU0UpOwogICAgbV9wTEJCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0xCQm94KSk7CgogICAgQ1BERl9SZWN0IHJjUkJCb3ggPSByY0NsaWVudDsKICAgIHJjUkJCb3gudG9wID0gcmNSQkJveC5ib3R0b20gKyA3LjBmOwogICAgcmNSQkJveC5sZWZ0ID0gcmNSQkJveC5yaWdodCAtIDcuMGY7CiAgICByY1JCQm94Lk5vcm1hbGl6ZSgpOwogICAgbV9wUkJCb3gtPk1vdmUocmNSQkJveCwgVFJVRSwgRkFMU0UpOwogICAgbV9wUkJCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY1JCQm94KSk7CgogICAgQ1BERl9SZWN0IHJjQ29udGVudHMgPSByY0NsaWVudDsKICAgIHJjQ29udGVudHMudG9wID0gcmNBdXRob3IuYm90dG9tIC0gUE9QVVBfSVRFTV9IRUFEX0JPVFRPTTsKICAgIHJjQ29udGVudHMubGVmdCArPSAzLjBmOwogICAgcmNDb250ZW50cy5yaWdodCAtPSAzLjBmOwogICAgaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkKICAgICAgcmNDb250ZW50cy5yaWdodCAtPSBQV0xfU0NST0xMQkFSX1dJRFRIOwogICAgcmNDb250ZW50cy5ib3R0b20gKz0gMTQuMGY7CiAgICByY0NvbnRlbnRzLk5vcm1hbGl6ZSgpOwogICAgbV9wQ29udGVudHMtPk1vdmUocmNDb250ZW50cywgRkFMU0UsIEZBTFNFKTsKICAgIG1fcENvbnRlbnRzLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDb250ZW50cykpOwoKICAgIENQREZfUmVjdCByY0NvbnRlbnRzQmFyID0gcmNDb250ZW50czsKICAgIHJjQ29udGVudHNCYXIucmlnaHQgPSByY0NsaWVudC5yaWdodCAtIDMuMGY7CiAgICByY0NvbnRlbnRzQmFyLmxlZnQgPSByY0NvbnRlbnRzQmFyLnJpZ2h0IC0gUFdMX1NDUk9MTEJBUl9XSURUSDsKICAgIHJjQ29udGVudHNCYXIuTm9ybWFsaXplKCk7CiAgICBtX3BDb250ZW50c0Jhci0+TW92ZShyY0NvbnRlbnRzQmFyLCBUUlVFLCBGQUxTRSk7CgogICAgbV9yY0NhcHRpb24gPSByY0NsaWVudDsKICAgIG1fcmNDYXB0aW9uLmJvdHRvbSA9IHJjQ29udGVudHMudG9wOwogIH0KCiAgbV9iUmVzaXppbmcgPSBGQUxTRTsKfQoKLy8gMC1ub3JtYWwgLyAxLWNhcHRpb24gLyAyLWxlZnRib3R0b20gY29ybmVyIC8gMy1yaWdodGJvdHRvbSBjb3JuZXIgLyA0LWNsb3NlIC8KLy8gNS1vcHRpb25zCmludDMyX3QgQ1BXTF9Ob3RlOjpOb3RlSGl0VGVzdChjb25zdCBDUERGX1BvaW50JiBwb2ludCkgY29uc3QgewogIEFTU0VSVChtX3BTdWJqZWN0ICE9IE5VTEwpOwogIEFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKICBBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CiAgQVNTRVJUKG1fcEF1dGhvciAhPSBOVUxMKTsKICBBU1NFUlQobV9wSWNvbiAhPSBOVUxMKTsKICBBU1NFUlQobV9wQ29udGVudHNCYXIgIT0gTlVMTCk7CgogIEFTU0VSVChtX3BDbG9zZUJveCAhPSBOVUxMKTsKICBBU1NFUlQobV9wTEJCb3ggIT0gTlVMTCk7CiAgQVNTRVJUKG1fcFJCQm94ICE9IE5VTEwpOwogIEFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOwoKICBHZXRDbGllbnRSZWN0KCk7CgogIGlmIChtX3BTdWJqZWN0LT5XbmRIaXRUZXN0KG1fcFN1YmplY3QtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKICAgIHJldHVybiAxOwogIGlmIChtX3BEYXRlVGltZS0+V25kSGl0VGVzdChtX3BEYXRlVGltZS0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDE7CiAgaWYgKG1fcEF1dGhvci0+V25kSGl0VGVzdChtX3BBdXRob3ItPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKICAgIHJldHVybiAxOwogIGlmIChtX3BJY29uLT5XbmRIaXRUZXN0KG1fcEljb24tPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKICAgIHJldHVybiAxOwoKICBpZiAobV9wQ29udGVudHMtPlduZEhpdFRlc3QobV9wQ29udGVudHMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKICAgIHJldHVybiAwOwogIGlmIChtX3BDb250ZW50c0Jhci0+V25kSGl0VGVzdChtX3BDb250ZW50c0Jhci0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDA7CgogIGlmIChtX3BDbG9zZUJveC0+V25kSGl0VGVzdChtX3BDbG9zZUJveC0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDQ7CiAgaWYgKG1fcExCQm94LT5XbmRIaXRUZXN0KG1fcExCQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpCiAgICByZXR1cm4gMjsKICBpZiAobV9wUkJCb3gtPlduZEhpdFRlc3QobV9wUkJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKICAgIHJldHVybiAzOwogIGlmIChtX3BPcHRpb25zLT5XbmRIaXRUZXN0KG1fcE9wdGlvbnMtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKICAgIHJldHVybiA1OwoKICByZXR1cm4gMTsKfQoKdm9pZCBDUFdMX05vdGU6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3ApIHsKICBDUFdMX05vdGVJdGVtOjpDcmVhdGVDaGlsZFduZChjcCk7CgogIENQV0xfQ29sb3Igc1RleHRDb2xvcjsKCiAgaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKEdldEJhY2tncm91bmRDb2xvcigpKSkKICAgIHNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9XSElURUNPTE9SOwogIGVsc2UKICAgIHNUZXh0Q29sb3IgPSBQV0xfREVGQVVMVF9CTEFDS0NPTE9SOwoKICBtX3BBdXRob3IgPSBuZXcgQ1BXTF9MYWJlbDsKICBQV0xfQ1JFQVRFUEFSQU0gYWNwID0gY3A7CiAgYWNwLnBQYXJlbnRXbmQgPSB0aGlzOwogIGFjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTEVGVCB8IFBFU19UT1A7CiAgYWNwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwogIG1fcEF1dGhvci0+Q3JlYXRlKGFjcCk7CgogIG1fcENsb3NlQm94ID0gbmV3IENQV0xfTm90ZV9DbG9zZUJveDsKICBQV0xfQ1JFQVRFUEFSQU0gY2NwID0gY3A7CiAgY2NwLnBQYXJlbnRXbmQgPSB0aGlzOwogIGNjcC5kd0JvcmRlcldpZHRoID0gMjsKICBjY3AubkJvcmRlclN0eWxlID0gUEJTX0JFVkVMRUQ7CiAgY2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBXU19CT1JERVI7CiAgY2NwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwogIG1fcENsb3NlQm94LT5DcmVhdGUoY2NwKTsKCiAgbV9wSWNvbiA9IG5ldyBDUFdMX05vdGVfSWNvbjsKICBQV0xfQ1JFQVRFUEFSQU0gaWNwID0gY3A7CiAgaWNwLnBQYXJlbnRXbmQgPSB0aGlzOwogIGljcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQ7CiAgbV9wSWNvbi0+Q3JlYXRlKGljcCk7CgogIG1fcE9wdGlvbnMgPSBuZXcgQ1BXTF9Ob3RlX09wdGlvbnM7CiAgUFdMX0NSRUFURVBBUkFNIG9jcCA9IGNwOwogIG9jcC5wUGFyZW50V25kID0gdGhpczsKICBvY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOwogIG9jcC5zVGV4dENvbG9yID0gc1RleHRDb2xvcjsKICBtX3BPcHRpb25zLT5DcmVhdGUob2NwKTsKCiAgbV9wTEJCb3ggPSBuZXcgQ1BXTF9Ob3RlX0xCQm94OwogIFBXTF9DUkVBVEVQQVJBTSBsY3AgPSBjcDsKICBsY3AucFBhcmVudFduZCA9IHRoaXM7CiAgbGNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsKICBsY3AuZUN1cnNvclR5cGUgPSBGWENUX05FU1c7CiAgbGNwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwogIG1fcExCQm94LT5DcmVhdGUobGNwKTsKCiAgbV9wUkJCb3ggPSBuZXcgQ1BXTF9Ob3RlX1JCQm94OwogIFBXTF9DUkVBVEVQQVJBTSByY3AgPSBjcDsKICByY3AucFBhcmVudFduZCA9IHRoaXM7CiAgcmNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsKICByY3AuZUN1cnNvclR5cGUgPSBGWENUX05XU0U7CiAgcmNwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwogIG1fcFJCQm94LT5DcmVhdGUocmNwKTsKCiAgbV9wQ29udGVudHNCYXIgPSBuZXcgQ1BXTF9TY3JvbGxCYXIoU0JUX1ZTQ1JPTEwpOwogIFBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsKICBzY3AucFBhcmVudFduZCA9IHRoaXM7CiAgc2NwLnNCYWNrZ3JvdW5kQ29sb3IgPQogICAgICBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDI0MCAvIDI1NS4wZiwgMjQwIC8gMjU1LjBmLCAyNDAgLyAyNTUuMGYpOwogIHNjcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEUgfCBQV1NfQkFDS0dST1VORDsKICBtX3BDb250ZW50c0Jhci0+Q3JlYXRlKHNjcCk7CiAgbV9wQ29udGVudHNCYXItPlNldE5vdGlmeUZvcmV2ZXIoVFJVRSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpIHsKICBDUFdMX05vdGVJdGVtOjpTZXRTdWJqZWN0TmFtZShzTmFtZSk7CiAgUmVQb3NDaGlsZFduZCgpOwp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0QXV0aG9yTmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpIHsKICBpZiAobV9wQXV0aG9yKSB7CiAgICBtX3BBdXRob3ItPlNldFRleHQoc05hbWUuY19zdHIoKSk7CiAgICBSZVBvc0NoaWxkV25kKCk7CiAgfQoKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBwTm90aWZ5LT5PblNldEF1dGhvck5hbWUodGhpcyk7CiAgfQp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGU6OkdldEF1dGhvck5hbWUoKSBjb25zdCB7CiAgaWYgKG1fcEF1dGhvcikKICAgIHJldHVybiBtX3BBdXRob3ItPkdldFRleHQoKTsKCiAgcmV0dXJuIEwiIjsKfQoKRlhfQk9PTCBDUFdMX05vdGU6Ok9uTW91c2VXaGVlbChzaG9ydCB6RGVsdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbkZsYWcpIHsKICBDUERGX1BvaW50IHB0U2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOwogIENQREZfUmVjdCByY1Njcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxBcmVhKCk7CiAgQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOwoKICBpZiAocmNTY3JvbGwudG9wIC0gcmNTY3JvbGwuYm90dG9tID4gcmNDb250ZW50cy5IZWlnaHQoKSkgewogICAgQ1BERl9Qb2ludCBwdE5ldyA9IHB0U2Nyb2xsOwoKICAgIGlmICh6RGVsdGEgPiAwKQogICAgICBwdE5ldy55ICs9IDMwOwogICAgZWxzZQogICAgICBwdE5ldy55IC09IDMwOwoKICAgIGlmIChwdE5ldy55ID4gcmNTY3JvbGwudG9wKQogICAgICBwdE5ldy55ID0gcmNTY3JvbGwudG9wOwogICAgaWYgKHB0TmV3LnkgPCByY1Njcm9sbC5ib3R0b20gKyByY0NvbnRlbnRzLkhlaWdodCgpKQogICAgICBwdE5ldy55ID0gcmNTY3JvbGwuYm90dG9tICsgcmNDb250ZW50cy5IZWlnaHQoKTsKICAgIGlmIChwdE5ldy55IDwgcmNTY3JvbGwuYm90dG9tKQogICAgICBwdE5ldy55ID0gcmNTY3JvbGwuYm90dG9tOwoKICAgIGlmIChwdE5ldy55ICE9IHB0U2Nyb2xsLnkpIHsKICAgICAgbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwogICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50cHRyX3QpJnB0TmV3LnkpOwogICAgICBtX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50cHRyX3QpJnB0TmV3LnkpOwoKICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CiAgfQoKICByZXR1cm4gRkFMU0U7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwKICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG1zZywKICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IHdQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IGxQYXJhbSkgewogIHN3aXRjaCAobXNnKSB7CiAgICBjYXNlIFBOTV9OT1RFRURJVENIQU5HRUQ6IHsKICAgICAgQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsKCiAgICAgIFBXTF9TQ1JPTExfSU5GTyBzSW5mbzsKICAgICAgc0luZm8uZkNvbnRlbnRNaW4gPSByY1Njcm9sbC5ib3R0b207CiAgICAgIHNJbmZvLmZDb250ZW50TWF4ID0gcmNTY3JvbGwudG9wOwogICAgICBzSW5mby5mUGxhdGVXaWR0aCA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCkuSGVpZ2h0KCk7CiAgICAgIHNJbmZvLmZTbWFsbFN0ZXAgPSAxMy4wZjsKICAgICAgc0luZm8uZkJpZ1N0ZXAgPSBzSW5mby5mUGxhdGVXaWR0aDsKCiAgICAgIGlmIChGWFNZU19tZW1jbXAoJm1fT2xkU2Nyb2xsSW5mbywgJnNJbmZvLCBzaXplb2YoUFdMX1NDUk9MTF9JTkZPKSkgIT0KICAgICAgICAgIDApIHsKICAgICAgICBGWF9CT09MIGJTY3JvbGxDaGFuZ2VkID0gRkFMU0U7CgogICAgICAgIGlmIChsUGFyYW0gPCAzKSAgLy+3wNa5y8DRrbu3IG1hbnRpczoxNTc1OQogICAgICAgIHsKICAgICAgICAgIGJTY3JvbGxDaGFuZ2VkID0gUmVzZXRTY3JvbGxCYXIoKTsKICAgICAgICAgIGlmIChiU2Nyb2xsQ2hhbmdlZCkgewogICAgICAgICAgICBsUGFyYW0rKzsKICAgICAgICAgICAgbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFUkVTRVQsIDAsIDApOwogICAgICAgICAgICBPbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCBsUGFyYW0pOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFiU2Nyb2xsQ2hhbmdlZCkgewogICAgICAgICAgaWYgKG1fcENvbnRlbnRzQmFyLT5Jc1Zpc2libGUoKSkgewogICAgICAgICAgICBtX3BDb250ZW50c0Jhci0+T25Ob3RpZnkocFduZCwgUE5NX1NFVFNDUk9MTElORk8sIFNCVF9WU0NST0xMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludHB0cl90KSZzSW5mbyk7CiAgICAgICAgICAgIG1fT2xkU2Nyb2xsSW5mbyA9IHNJbmZvOwoKICAgICAgICAgICAgQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKICAgICAgICAgICAgQ1BERl9Qb2ludCBwdE9sZCA9IHB0U2Nyb2xsOwoKICAgICAgICAgICAgaWYgKHB0U2Nyb2xsLnkgPiBzSW5mby5mQ29udGVudE1heCkKICAgICAgICAgICAgICBwdFNjcm9sbC55ID0gc0luZm8uZkNvbnRlbnRNYXg7CiAgICAgICAgICAgIGlmIChwdFNjcm9sbC55IDwgc0luZm8uZkNvbnRlbnRNaW4gKyBzSW5mby5mUGxhdGVXaWR0aCkKICAgICAgICAgICAgICBwdFNjcm9sbC55ID0gc0luZm8uZkNvbnRlbnRNaW4gKyBzSW5mby5mUGxhdGVXaWR0aDsKICAgICAgICAgICAgaWYgKHB0U2Nyb2xsLnkgPCBzSW5mby5mQ29udGVudE1pbikKICAgICAgICAgICAgICBwdFNjcm9sbC55ID0gc0luZm8uZkNvbnRlbnRNaW47CgogICAgICAgICAgICBpZiAocHRPbGQueSAhPSBwdFNjcm9sbC55KSB7CiAgICAgICAgICAgICAgbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50cHRyX3QpJnB0U2Nyb2xsLnkpOwogICAgICAgICAgICAgIG1fcENvbnRlbnRzQmFyLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKICAgICAgICAgICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHRTY3JvbGwueSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAgIG1fcENvbnRlbnRzLT5JbnZhbGlkYXRlUmVjdChOVUxMKTsKCiAgICAgIHJldHVybjsKICAgIGNhc2UgUE5NX1NDUk9MTFdJTkRPVzoKICAgICAgaWYgKG1fcENvbnRlbnRzKQogICAgICAgIG1fcENvbnRlbnRzLT5Pbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgICAgcmV0dXJuOwogICAgY2FzZSBQTk1fU0VUU0NST0xMUE9TOgogICAgICBpZiAobV9wQ29udGVudHNCYXIpCiAgICAgICAgbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHBXbmQsIFBOTV9TRVRTQ1JPTExQT1MsIHdQYXJhbSwgbFBhcmFtKTsKICAgICAgcmV0dXJuOwogIH0KCiAgaWYgKG1zZyA9PSBQTk1fU0VUQ0FSRVRJTkZPICYmIElzVmFsaWQoKSkgewogICAgaWYgKFBXTF9DQVJFVF9JTkZPKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKSB7CiAgICAgIGlmIChtX3BDb250ZW50cykgewogICAgICAgIENQREZfUmVjdCByY0NsaWVudCA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCk7CiAgICAgICAgaWYgKHBJbmZvLT5wdEhlYWQueSA+IHJjQ2xpZW50LnRvcCkgewogICAgICAgICAgQ1BERl9Qb2ludCBwdCA9IG1fcENvbnRlbnRzLT5PdXRUb0luKHBJbmZvLT5wdEhlYWQpOwogICAgICAgICAgbV9wQ29udGVudHMtPk9uTm90aWZ5KHRoaXMsIFBOTV9TQ1JPTExXSU5ET1csIFNCVF9WU0NST0xMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHQueSk7CgogICAgICAgICAgQ1BERl9Qb2ludCBwdFNjcm9sbCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxQb3MoKTsKICAgICAgICAgIG1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50cHRyX3QpJnB0U2Nyb2xsLnkpOwoKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChwSW5mby0+cHRGb290LnkgPCByY0NsaWVudC5ib3R0b20pIHsKICAgICAgICAgIENQREZfUG9pbnQgcHQgPSBtX3BDb250ZW50cy0+T3V0VG9JbihwSW5mby0+cHRGb290KTsKICAgICAgICAgIHB0LnkgKz0gcmNDbGllbnQuSGVpZ2h0KCk7CiAgICAgICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludHB0cl90KSZwdC55KTsKCiAgICAgICAgICBDUERGX1BvaW50IHB0U2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOwogICAgICAgICAgbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHRTY3JvbGwueSk7CgogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRCa0NvbG9yKGNvbnN0IENQV0xfQ29sb3ImIGNvbG9yKSB7CiAgQ1BXTF9Ob3RlSXRlbTo6U2V0QmtDb2xvcihjb2xvcik7CgogIENQV0xfQ29sb3Igc0JLID0gY29sb3I7CiAgQ1BXTF9Db2xvciBzVGV4dENvbG9yOwogIGlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShzQkspKQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CiAgZWxzZQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgogIGlmIChtX3BDbG9zZUJveCkKICAgIG1fcENsb3NlQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CiAgaWYgKG1fcEF1dGhvcikKICAgIG1fcEF1dGhvci0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwogIGlmIChtX3BPcHRpb25zKQogICAgbV9wT3B0aW9ucy0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwogIGlmIChtX3BMQkJveCkKICAgIG1fcExCQm94LT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CiAgaWYgKG1fcFJCQm94KQogICAgbV9wUkJCb3gtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKfQoKRlhfQk9PTCBDUFdMX05vdGU6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKSB7CiAgaWYgKG1fcE9wdGlvbnMtPlduZEhpdFRlc3QobV9wT3B0aW9ucy0+UGFyZW50VG9DaGlsZChwb2ludCkpKSB7CiAgICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICAgIGludDMyX3QgeCwgeTsKICAgICAgUFdMdG9XbmQocG9pbnQsIHgsIHkpOwogICAgICBpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKICAgICAgICBwU0gtPkNsaWVudFRvU2NyZWVuKEdldEF0dGFjaGVkSFduZCgpLCB4LCB5KTsKICAgICAgS2lsbEZvY3VzKCk7CiAgICAgIHBOb3RpZnktPk9uUG9wdXBNZW51KHgsIHkpOwoKICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CiAgfQoKICByZXR1cm4gQ1BXTF9XbmQ6Ok9uTEJ1dHRvbkRvd24ocG9pbnQsIG5GbGFnKTsKfQoKRlhfQk9PTCBDUFdMX05vdGU6Ok9uUkJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LCBGWF9EV09SRCBuRmxhZykgewogIHJldHVybiBDUFdMX1duZDo6T25SQnV0dG9uVXAocG9pbnQsIG5GbGFnKTsKfQoKY29uc3QgQ1BXTF9Ob3RlKiBDUFdMX05vdGU6OkdldE5vdGUoKSBjb25zdCB7CiAgcmV0dXJuIHRoaXM7Cn0KCklQV0xfTm90ZU5vdGlmeSogQ1BXTF9Ob3RlOjpHZXROb3RlTm90aWZ5KCkgY29uc3QgewogIGlmIChtX2JFbmFsYmxlTm90aWZ5KQogICAgcmV0dXJuIG1fcE5vdGVOb3RpZnk7CgogIHJldHVybiBOVUxMOwp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0SWNvblR5cGUoaW50MzJfdCBuVHlwZSkgewogIGlmIChtX3BJY29uKQogICAgbV9wSWNvbi0+U2V0SWNvblR5cGUoblR5cGUpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpIHsKICBtX3BDb250ZW50cy0+RW5hYmxlTW9kaWZ5KGJFbmFibGVkKTsKfQoKdm9pZCBDUFdMX05vdGU6OkVuYWJsZVJlYWQoRlhfQk9PTCBiRW5hYmxlZCkgewogIG1fcENvbnRlbnRzLT5FbmFibGVSZWFkKGJFbmFibGVkKTsKfQoKQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlOjpHZXRSZXBseVN0cmluZygpIGNvbnN0IHsKICByZXR1cm4gbV9zUmVwbHlTdHJpbmc7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRSZXBseVN0cmluZyhjb25zdCBDRlhfV2lkZVN0cmluZyYgc3RyaW5nKSB7CiAgbV9zUmVwbHlTdHJpbmcgPSBzdHJpbmc7Cn0K