Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIE9yaWdpbmFsIGNvZGUgY29weXJpZ2h0IDIwMTQgRm94aXQgU29mdHdhcmUgSW5jLiBodHRwOi8vd3d3LmZveGl0c29mdHdhcmUuY29tCgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QREZXaW5kb3cuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0J1dHRvbi5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfQ2FyZXQuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXQuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX0VkaXRDdHJsLmgiCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9MYWJlbC5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfTGlzdEN0cmwuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX05vdGUuaCIKI2luY2x1ZGUgImZwZGZzZGsvaW5jbHVkZS9wZGZ3aW5kb3cvUFdMX1Njcm9sbEJhci5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfU2Nyb2xsQmFyLmgiCiNpbmNsdWRlICJmcGRmc2RrL2luY2x1ZGUvcGRmd2luZG93L1BXTF9VdGlscy5oIgojaW5jbHVkZSAiZnBkZnNkay9pbmNsdWRlL3BkZndpbmRvdy9QV0xfV25kLmgiCgojZGVmaW5lIFBPUFVQX0lURU1fSEVBRF9CT1RUT00gMy4wZgojZGVmaW5lIFBPUFVQX0lURU1fQk9UVE9NV0lEVEggMS4wZgojZGVmaW5lIFBPUFVQX0lURU1fU0lERU1BUkdJTiAzLjBmCiNkZWZpbmUgUE9QVVBfSVRFTV9TUEFDRSA0LjBmCiNkZWZpbmUgUE9QVVBfSVRFTV9URVhUX0lOREVOVCAyLjBmCiNkZWZpbmUgUE9QVVBfSVRFTV9CT1JERVJDT0xPUiBcCiAgQ1BXTF9Db2xvcihDT0xPUlRZUEVfUkdCLCA4MCAvIDI1NS4wZiwgODAgLyAyNTUuMGYsIDgwIC8gMjU1LjBmKQoKI2RlZmluZSBJc0Zsb2F0WmVybyhmKSAoKGYpIDwgMC4wMDAxICYmIChmKSA+IC0wLjAwMDEpCiNkZWZpbmUgSXNGbG9hdEJpZ2dlcihmYSwgZmIpICgoZmEpID4gKGZiKSAmJiAhSXNGbG9hdFplcm8oKGZhKSAtIChmYikpKQojZGVmaW5lIElzRmxvYXRTbWFsbGVyKGZhLCBmYikgKChmYSkgPCAoZmIpICYmICFJc0Zsb2F0WmVybygoZmEpIC0gKGZiKSkpCiNkZWZpbmUgSXNGbG9hdEVxdWFsKGZhLCBmYikgSXNGbG9hdFplcm8oKGZhKSAtIChmYikpCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9PcHRpb25zCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9PcHRpb25zOjpDUFdMX05vdGVfT3B0aW9ucygpIDogbV9wVGV4dChOVUxMKSB7fQoKQ1BXTF9Ob3RlX09wdGlvbnM6On5DUFdMX05vdGVfT3B0aW9ucygpIHt9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0Q29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpIHsKICBDUFdMX1duZDo6U2V0VGV4dENvbG9yKGNvbG9yKTsKCiAgaWYgKG1fcFRleHQpCiAgICBtX3BUZXh0LT5TZXRUZXh0Q29sb3IoY29sb3IpOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpSZVBvc0NoaWxkV25kKCkgewogIGlmIChJc1ZhbGlkKCkpIHsKICAgIEFTU0VSVChtX3BUZXh0ICE9IE5VTEwpOwoKICAgIENQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKCiAgICBpZiAocmNDbGllbnQuV2lkdGgoKSA+IDE1LjBmKSB7CiAgICAgIHJjQ2xpZW50LnJpZ2h0IC09IDE1LjBmOwogICAgICBtX3BUZXh0LT5Nb3ZlKHJjQ2xpZW50LCBUUlVFLCBGQUxTRSk7CiAgICAgIG1fcFRleHQtPlNldFZpc2libGUoVFJVRSk7CiAgICB9IGVsc2UgewogICAgICBtX3BUZXh0LT5Nb3ZlKENQREZfUmVjdCgwLCAwLCAwLCAwKSwgVFJVRSwgRkFMU0UpOwogICAgICBtX3BUZXh0LT5TZXRWaXNpYmxlKEZBTFNFKTsKICAgIH0KICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlX09wdGlvbnM6OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3ApIHsKICBtX3BUZXh0ID0gbmV3IENQV0xfTGFiZWw7CiAgUFdMX0NSRUFURVBBUkFNIHRjcCA9IGNwOwogIHRjcC5wUGFyZW50V25kID0gdGhpczsKICB0Y3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFOwogIG1fcFRleHQtPkNyZWF0ZSh0Y3ApOwp9Cgp2b2lkIENQV0xfTm90ZV9PcHRpb25zOjpTZXRUZXh0KGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzVGV4dCkgewogIG1fcFRleHQtPlNldFRleHQoc1RleHQuY19zdHIoKSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX09wdGlvbnM6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkgewogIENQV0xfV25kOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlKTsKCiAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwogIHJjQ2xpZW50LmxlZnQgPSByY0NsaWVudC5yaWdodCAtIDE1LjBmOwoKICBDUERGX1BvaW50IHB0Q2VudGVyID0gQ1BERl9Qb2ludCgocmNDbGllbnQubGVmdCArIHJjQ2xpZW50LnJpZ2h0KSAqIDAuNWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJjQ2xpZW50LnRvcCArIHJjQ2xpZW50LmJvdHRvbSkgKiAwLjVmKTsKCiAgQ1BERl9Qb2ludCBwdDEocHRDZW50ZXIueCAtIDIuMGYsIHB0Q2VudGVyLnkgKyAyLjBmICogMC41Zik7CiAgQ1BERl9Qb2ludCBwdDIocHRDZW50ZXIueCArIDIuMGYsIHB0Q2VudGVyLnkgKyAyLjBmICogMC41Zik7CiAgQ1BERl9Qb2ludCBwdDMocHRDZW50ZXIueCwgcHRDZW50ZXIueSAtIDMuMGYgKiAwLjVmKTsKCiAgQ0ZYX1BhdGhEYXRhIHBhdGg7CgogIHBhdGguU2V0UG9pbnRDb3VudCg0KTsKICBwYXRoLlNldFBvaW50KDAsIHB0MS54LCBwdDEueSwgRlhQVF9NT1ZFVE8pOwogIHBhdGguU2V0UG9pbnQoMSwgcHQyLngsIHB0Mi55LCBGWFBUX0xJTkVUTyk7CiAgcGF0aC5TZXRQb2ludCgyLCBwdDMueCwgcHQzLnksIEZYUFRfTElORVRPKTsKICBwYXRoLlNldFBvaW50KDMsIHB0MS54LCBwdDEueSwgRlhQVF9MSU5FVE8pOwoKICBwRGV2aWNlLT5EcmF3UGF0aCgKICAgICAgJnBhdGgsIHBVc2VyMkRldmljZSwgTlVMTCwKICAgICAgQ1BXTF9VdGlsczo6UFdMQ29sb3JUb0ZYQ29sb3IoR2V0VGV4dENvbG9yKCksIEdldFRyYW5zcGFyZW5jeSgpKSwgMCwKICAgICAgRlhGSUxMX0FMVEVSTkFURSk7Cn0KCkNQREZfUmVjdCBDUFdMX05vdGVfT3B0aW9uczo6R2V0Q29udGVudFJlY3QoKSBjb25zdCB7CiAgQVNTRVJUKG1fcFRleHQgIT0gTlVMTCk7CgogIENQREZfUmVjdCByY1RleHQgPSBtX3BUZXh0LT5HZXRDb250ZW50UmVjdCgpOwogIHJjVGV4dC5yaWdodCArPSAxNS4wZjsKICByZXR1cm4gcmNUZXh0Owp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9FZGl0IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCkNQV0xfTm90ZV9FZGl0OjpDUFdMX05vdGVfRWRpdCgpCiAgICA6IG1fYkVuYWJsZU5vdGlmeShUUlVFKSwKICAgICAgbV9mT2xkSXRlbUhlaWdodCgwLjBmKSwKICAgICAgbV9iU2l6ZUNoYW5nZWQoRkFMU0UpLAogICAgICBtX2ZPbGRNaW4oMC4wZiksCiAgICAgIG1fZk9sZE1heCgwLjBmKSB7fQoKQ1BXTF9Ob3RlX0VkaXQ6On5DUFdMX05vdGVfRWRpdCgpIHt9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpSZVBvc0NoaWxkV25kKCkgewogIG1fYkVuYWJsZU5vdGlmeSA9IEZBTFNFOwogIENQV0xfRWRpdDo6UmVQb3NDaGlsZFduZCgpOwogIG1fYkVuYWJsZU5vdGlmeSA9IFRSVUU7CgogIG1fZk9sZEl0ZW1IZWlnaHQgPSBHZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpTZXRUZXh0KGNvbnN0IEZYX1dDSEFSKiBjc1RleHQpIHsKICBtX2JFbmFibGVOb3RpZnkgPSBGQUxTRTsKICBDUFdMX0VkaXQ6OlNldFRleHQoY3NUZXh0KTsKICBtX2JFbmFibGVOb3RpZnkgPSBUUlVFOwogIG1fZk9sZEl0ZW1IZWlnaHQgPSBHZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwp9Cgp2b2lkIENQV0xfTm90ZV9FZGl0OjpPblNldEZvY3VzKCkgewogIG1fYkVuYWJsZU5vdGlmeSA9IEZBTFNFOwogIENQV0xfRWRpdDo6T25TZXRGb2N1cygpOwogIG1fYkVuYWJsZU5vdGlmeSA9IFRSVUU7CgogIEVuYWJsZVNwZWxsQ2hlY2soVFJVRSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uS2lsbEZvY3VzKCkgewogIEVuYWJsZVNwZWxsQ2hlY2soRkFMU0UpOwoKICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgaWYgKENQV0xfV25kKiBwR3JhbmQgPSBwUGFyZW50LT5HZXRQYXJlbnRXaW5kb3coKSkgewogICAgICBBU1NFUlQocEdyYW5kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwoKICAgICAgQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBHcmFuZDsKCiAgICAgIHBOb3RlSXRlbS0+T25Db250ZW50c1ZhbGlkYXRlKCk7CiAgICB9CiAgfQoKICBDUFdMX0VkaXQ6Ok9uS2lsbEZvY3VzKCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0VkaXQ6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9EV09SRCBtc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IHdQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cHRyX3QgbFBhcmFtKSB7CiAgaWYgKG1fYkVuYWJsZU5vdGlmeSkgewogICAgaWYgKHdQYXJhbSA9PSBTQlRfVlNDUk9MTCkgewogICAgICBzd2l0Y2ggKG1zZykgewogICAgICAgIGNhc2UgUE5NX1NFVFNDUk9MTElORk86CiAgICAgICAgICBpZiAoUFdMX1NDUk9MTF9JTkZPKiBwSW5mbyA9IChQV0xfU0NST0xMX0lORk8qKWxQYXJhbSkgewogICAgICAgICAgICBpZiAoIUlzRmxvYXRFcXVhbChwSW5mby0+ZkNvbnRlbnRNYXgsIG1fZk9sZE1heCkgfHwKICAgICAgICAgICAgICAgICFJc0Zsb2F0RXF1YWwocEluZm8tPmZDb250ZW50TWluLCBtX2ZPbGRNaW4pKSB7CiAgICAgICAgICAgICAgbV9iU2l6ZUNoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICAgIGlmIChDUFdMX1duZCogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKSB7CiAgICAgICAgICAgICAgICBwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIG1fZk9sZE1heCA9IHBJbmZvLT5mQ29udGVudE1heDsKICAgICAgICAgICAgICBtX2ZPbGRNaW4gPSBwSW5mby0+ZkNvbnRlbnRNaW47CiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIENQV0xfRWRpdDo6T25Ob3RpZnkocFduZCwgbXNnLCB3UGFyYW0sIGxQYXJhbSk7CgogIGlmIChtX2JFbmFibGVOb3RpZnkpIHsKICAgIHN3aXRjaCAobXNnKSB7CiAgICAgIGNhc2UgUE5NX1NFVENBUkVUSU5GTzoKICAgICAgICBpZiAoUFdMX0NBUkVUX0lORk8qIHBJbmZvID0gKFBXTF9DQVJFVF9JTkZPKil3UGFyYW0pIHsKICAgICAgICAgIFBXTF9DQVJFVF9JTkZPIG5ld0luZm8gPSAqcEluZm87CiAgICAgICAgICBuZXdJbmZvLmJWaXNpYmxlID0gVFJVRTsKICAgICAgICAgIG5ld0luZm8ucHRIZWFkID0gQ2hpbGRUb1BhcmVudChwSW5mby0+cHRIZWFkKTsKICAgICAgICAgIG5ld0luZm8ucHRGb290ID0gQ2hpbGRUb1BhcmVudChwSW5mby0+cHRGb290KTsKCiAgICAgICAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgICAgICAgICBwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUQ0FSRVRJTkZPLCAoaW50cHRyX3QpJm5ld0luZm8sIDApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICB9Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZV9FZGl0OjpHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKSB7CiAgaWYgKGZMaW1pdFdpZHRoID4gMCkgewogICAgaWYgKCFtX2JTaXplQ2hhbmdlZCkKICAgICAgcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQ7CgogICAgbV9iU2l6ZUNoYW5nZWQgPSBGQUxTRTsKCiAgICBFbmFibGVOb3RpZnkoRkFMU0UpOwogICAgRW5hYmxlUmVmcmVzaChGQUxTRSk7CiAgICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwoKICAgIE1vdmUoQ1BERl9SZWN0KDAsIDAsIGZMaW1pdFdpZHRoLCAwKSwgVFJVRSwgRkFMU0UpOwogICAgRlhfRkxPQVQgZlJldCA9IEdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CgogICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwogICAgRW5hYmxlTm90aWZ5KFRSVUUpOwogICAgRW5hYmxlUmVmcmVzaChUUlVFKTsKCiAgICByZXR1cm4gZlJldDsKICB9CgogIHJldHVybiAwOwp9CgpGWF9GTE9BVCBDUFdMX05vdGVfRWRpdDo6R2V0SXRlbUxlZnRNYXJnaW4oKSB7CiAgcmV0dXJuIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7Cn0KCkZYX0ZMT0FUIENQV0xfTm90ZV9FZGl0OjpHZXRJdGVtUmlnaHRNYXJnaW4oKSB7CiAgcmV0dXJuIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9MQkJveAogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpDUFdMX05vdGVfTEJCb3g6OkNQV0xfTm90ZV9MQkJveCgpIHt9CgpDUFdMX05vdGVfTEJCb3g6On5DUFdMX05vdGVfTEJCb3goKSB7fQoKdm9pZCBDUFdMX05vdGVfTEJCb3g6OkRyYXdUaGlzQXBwZWFyYW5jZShDRlhfUmVuZGVyRGV2aWNlKiBwRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpIHsKICBDUERGX1JlY3QgcmNDbGllbnQgPSBHZXRDbGllbnRSZWN0KCk7CgogIENGWF9HcmFwaFN0YXRlRGF0YSBnc2Q7CiAgZ3NkLm1fTGluZVdpZHRoID0gMS4wZjsKCiAgQ0ZYX1BhdGhEYXRhIHBhdGhDcm9zczsKCiAgcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CiAgcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LnRvcCwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgxLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CiAgcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LmxlZnQsCiAgICAgICAgICAgICAgICAgICAgIHJjQ2xpZW50LmJvdHRvbSArIHJjQ2xpZW50LkhlaWdodCgpICogMC41ZiwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQuV2lkdGgoKSAqIDAuNWYsCiAgICAgICAgICAgICAgICAgICAgIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwoKICBwRGV2aWNlLT5EcmF3UGF0aCgKICAgICAgJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLAogICAgICBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSwgR2V0VHJhbnNwYXJlbmN5KCkpLAogICAgICBGWEZJTExfQUxURVJOQVRFKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlX1JCQm94CiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCkNQV0xfTm90ZV9SQkJveDo6Q1BXTF9Ob3RlX1JCQm94KCkge30KCkNQV0xfTm90ZV9SQkJveDo6fkNQV0xfTm90ZV9SQkJveCgpIHt9Cgp2b2lkIENQV0xfTm90ZV9SQkJveDo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkgewogIENQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKCiAgQ0ZYX0dyYXBoU3RhdGVEYXRhIGdzZDsKICBnc2QubV9MaW5lV2lkdGggPSAxLjBmOwoKICBDRlhfUGF0aERhdGEgcGF0aENyb3NzOwoKICBwYXRoQ3Jvc3MuU2V0UG9pbnRDb3VudCg0KTsKICBwYXRoQ3Jvc3MuU2V0UG9pbnQoMCwgcmNDbGllbnQucmlnaHQsIHJjQ2xpZW50LnRvcCwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgxLCByY0NsaWVudC5sZWZ0LCByY0NsaWVudC5ib3R0b20sIEZYUFRfTElORVRPKTsKICBwYXRoQ3Jvc3MuU2V0UG9pbnQoMiwgcmNDbGllbnQucmlnaHQsCiAgICAgICAgICAgICAgICAgICAgIHJjQ2xpZW50LmJvdHRvbSArIHJjQ2xpZW50LkhlaWdodCgpICogMC41ZiwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5sZWZ0ICsgcmNDbGllbnQuV2lkdGgoKSAqIDAuNWYsCiAgICAgICAgICAgICAgICAgICAgIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9MSU5FVE8pOwoKICBwRGV2aWNlLT5EcmF3UGF0aCgKICAgICAgJnBhdGhDcm9zcywgcFVzZXIyRGV2aWNlLCAmZ3NkLCAwLAogICAgICBDUFdMX1V0aWxzOjpQV0xDb2xvclRvRlhDb2xvcihHZXRUZXh0Q29sb3IoKSwgR2V0VHJhbnNwYXJlbmN5KCkpLAogICAgICBGWEZJTExfQUxURVJOQVRFKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZV9JY29uCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCkNQV0xfTm90ZV9JY29uOjpDUFdMX05vdGVfSWNvbigpIDogbV9uVHlwZSgwKSB7fQoKQ1BXTF9Ob3RlX0ljb246On5DUFdMX05vdGVfSWNvbigpIHt9Cgp2b2lkIENQV0xfTm90ZV9JY29uOjpTZXRJY29uVHlwZShpbnQzMl90IG5UeXBlKSB7CiAgbV9uVHlwZSA9IG5UeXBlOwp9Cgp2b2lkIENQV0xfTm90ZV9JY29uOjpEcmF3VGhpc0FwcGVhcmFuY2UoQ0ZYX1JlbmRlckRldmljZSogcERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENQREZfTWF0cml4KiBwVXNlcjJEZXZpY2UpIHsKICBDUFdMX1V0aWxzOjpEcmF3SWNvbkFwcFN0cmVhbShwRGV2aWNlLCBwVXNlcjJEZXZpY2UsIG1fblR5cGUsIEdldENsaWVudFJlY3QoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRCYWNrZ3JvdW5kQ29sb3IoKSwgUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRUcmFuc3BhcmVuY3koKSk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfQ2xvc2VCb3gKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlX0Nsb3NlQm94OjpDUFdMX05vdGVfQ2xvc2VCb3goKSA6IG1fYk1vdXNlRG93bihGQUxTRSkge30KCkNQV0xfTm90ZV9DbG9zZUJveDo6fkNQV0xfTm90ZV9DbG9zZUJveCgpIHt9Cgp2b2lkIENQV0xfTm90ZV9DbG9zZUJveDo6RHJhd1RoaXNBcHBlYXJhbmNlKENGWF9SZW5kZXJEZXZpY2UqIHBEZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1BERl9NYXRyaXgqIHBVc2VyMkRldmljZSkgewogIENQV0xfQnV0dG9uOjpEcmF3VGhpc0FwcGVhcmFuY2UocERldmljZSwgcFVzZXIyRGV2aWNlKTsKCiAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwogIHJjQ2xpZW50ID0gQ1BXTF9VdGlsczo6RGVmbGF0ZVJlY3QocmNDbGllbnQsIDIuMGYpOwoKICBDRlhfR3JhcGhTdGF0ZURhdGEgZ3NkOwogIGdzZC5tX0xpbmVXaWR0aCA9IDEuMGY7CgogIENGWF9QYXRoRGF0YSBwYXRoQ3Jvc3M7CgogIGlmIChtX2JNb3VzZURvd24pIHsKICAgIHJjQ2xpZW50LmxlZnQgKz0gMC41ZjsKICAgIHJjQ2xpZW50LnJpZ2h0ICs9IDAuNWY7CiAgICByY0NsaWVudC50b3AgLT0gMC41ZjsKICAgIHJjQ2xpZW50LmJvdHRvbSAtPSAwLjVmOwogIH0KCiAgcGF0aENyb3NzLlNldFBvaW50Q291bnQoNCk7CiAgcGF0aENyb3NzLlNldFBvaW50KDAsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LmJvdHRvbSwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgxLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQudG9wLCBGWFBUX0xJTkVUTyk7CiAgcGF0aENyb3NzLlNldFBvaW50KDIsIHJjQ2xpZW50LmxlZnQsIHJjQ2xpZW50LnRvcCwgRlhQVF9NT1ZFVE8pOwogIHBhdGhDcm9zcy5TZXRQb2ludCgzLCByY0NsaWVudC5yaWdodCwgcmNDbGllbnQuYm90dG9tLCBGWFBUX0xJTkVUTyk7CgogIHBEZXZpY2UtPkRyYXdQYXRoKAogICAgICAmcGF0aENyb3NzLCBwVXNlcjJEZXZpY2UsICZnc2QsIDAsCiAgICAgIENQV0xfVXRpbHM6OlBXTENvbG9yVG9GWENvbG9yKEdldFRleHRDb2xvcigpLCBHZXRUcmFuc3BhcmVuY3koKSksCiAgICAgIEZYRklMTF9BTFRFUk5BVEUpOwp9CgpGWF9CT09MIENQV0xfTm90ZV9DbG9zZUJveDo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbkZsYWcpIHsKICBTZXRCb3JkZXJTdHlsZShQQlNfSU5TRVQpOwogIEludmFsaWRhdGVSZWN0KE5VTEwpOwoKICBtX2JNb3VzZURvd24gPSBUUlVFOwoKICByZXR1cm4gQ1BXTF9CdXR0b246Ok9uTEJ1dHRvbkRvd24ocG9pbnQsIG5GbGFnKTsKfQoKRlhfQk9PTCBDUFdMX05vdGVfQ2xvc2VCb3g6Ok9uTEJ1dHRvblVwKGNvbnN0IENQREZfUG9pbnQmIHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbkZsYWcpIHsKICBtX2JNb3VzZURvd24gPSBGQUxTRTsKCiAgU2V0Qm9yZGVyU3R5bGUoUEJTX0JFVkVMRUQpOwogIEludmFsaWRhdGVSZWN0KE5VTEwpOwoKICByZXR1cm4gQ1BXTF9CdXR0b246Ok9uTEJ1dHRvblVwKHBvaW50LCBuRmxhZyk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDUFdMX05vdGVfQ29udGVudHMKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDUFdMX05vdGVfQ29udGVudHMoKSA6IG1fcEVkaXQoTlVMTCkge30KCkNQV0xfTm90ZV9Db250ZW50czo6fkNQV0xfTm90ZV9Db250ZW50cygpIHt9CgpDRlhfQnl0ZVN0cmluZyBDUFdMX05vdGVfQ29udGVudHM6OkdldENsYXNzTmFtZSgpIGNvbnN0IHsKICByZXR1cm4gIkNQV0xfTm90ZV9Db250ZW50cyI7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpDcmVhdGVDaGlsZFduZChjb25zdCBQV0xfQ1JFQVRFUEFSQU0mIGNwKSB7CiAgbV9wRWRpdCA9IG5ldyBDUFdMX05vdGVfRWRpdDsKICBQV0xfQ1JFQVRFUEFSQU0gZWNwID0gY3A7CiAgZWNwLnBQYXJlbnRXbmQgPSB0aGlzOwogIGVjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQRVNfTVVMVElMSU5FIHwgUEVTX0FVVE9SRVRVUk4gfAogICAgICAgICAgICAgICAgUEVTX1RFWFRPVkVSRkxPVyB8IFBFU19VTkRPIHwgUEVTX1NQRUxMQ0hFQ0s7CgogIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CiAgbV9wRWRpdC0+Q3JlYXRlKGVjcCk7CiAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6U2V0VGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc1RleHQpIHsKICBpZiAobV9wRWRpdCkgewogICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKICAgIG1fcEVkaXQtPlNldFRleHQoc1RleHQuY19zdHIoKSk7CiAgICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7CiAgICBPbk5vdGlmeShtX3BFZGl0LCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICB9Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZV9Db250ZW50czo6R2V0VGV4dCgpIGNvbnN0IHsKICBpZiAobV9wRWRpdCkKICAgIHJldHVybiBtX3BFZGl0LT5HZXRUZXh0KCk7CgogIHJldHVybiBMIiI7Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZV9Db250ZW50czo6Q3JlYXRlU3ViSXRlbSgpIHsKICBDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSBuZXcgQ1BXTF9Ob3RlSXRlbTsKICBQV0xfQ1JFQVRFUEFSQU0gaWNwID0gR2V0Q3JlYXRpb25QYXJhbSgpOwogIGljcC5wUGFyZW50V25kID0gdGhpczsKICBpY3AuZHdGbGFncyA9IFBXU19DSElMRCB8IFBXU19WSVNJQkxFIHwgUFdTX0JBQ0tHUk9VTkQ7CiAgcE5vdGVJdGVtLT5DcmVhdGUoaWNwKTsKCiAgcE5vdGVJdGVtLT5PbkNyZWF0ZU5vdGVJdGVtKCk7CgogIHBOb3RlSXRlbS0+UmVzZXRTdWJqZWN0TmFtZShtX2FDaGlsZHJlbi5HZXRTaXplKCkgLSAxKTsKCiAgRlhfU1lTVEVNVElNRSBzdDsKICBpZiAoSUZYX1N5c3RlbUhhbmRsZXIqIHBTSCA9IEdldFN5c3RlbUhhbmRsZXIoKSkKICAgIHN0ID0gcFNILT5HZXRMb2NhbFRpbWUoKTsKICBwTm90ZUl0ZW0tPlNldERhdGVUaW1lKHN0KTsKCiAgcE5vdGVJdGVtLT5TZXRDb250ZW50cyhMIiIpOwoKICBPbk5vdGlmeShwTm90ZUl0ZW0sIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwoKICByZXR1cm4gcE5vdGVJdGVtOwp9CgppbnQzMl90IENQV0xfTm90ZV9Db250ZW50czo6Q291bnRTdWJJdGVtcygpIGNvbnN0IHsKICByZXR1cm4gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpIC0gMTsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRTdWJJdGVtcyhpbnQzMl90IGluZGV4KSBjb25zdCB7CiAgaW50MzJfdCBuSW5kZXggPSBpbmRleCArIDE7CgogIGlmIChuSW5kZXggPiAwICYmIG5JbmRleCA8IG1fYUNoaWxkcmVuLkdldFNpemUoKSkKICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQobkluZGV4KSkgewogICAgICBBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwogICAgICBDUFdMX05vdGVJdGVtKiBwSXRlbSA9IChDUFdMX05vdGVJdGVtKilwQ2hpbGQ7CiAgICAgIHJldHVybiBwSXRlbTsKICAgIH0KICByZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVfQ29udGVudHM6OkRlbGV0ZVN1Ykl0ZW0oSVBXTF9Ob3RlSXRlbSogcE5vdGVJdGVtKSB7CiAgaW50MzJfdCBuSW5kZXggPSBHZXRJdGVtSW5kZXgoKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSk7CgogIGlmIChuSW5kZXggPiAwKSB7CiAgICBpZiAoQ1BXTF9Ob3RlSXRlbSogcFBXTE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBOb3RlSXRlbSkgewogICAgICBwUFdMTm90ZUl0ZW0tPktpbGxGb2N1cygpOwogICAgICBwUFdMTm90ZUl0ZW0tPkRlc3Ryb3koKTsKICAgICAgZGVsZXRlIHBQV0xOb3RlSXRlbTsKICAgIH0KCiAgICBmb3IgKGludDMyX3QgaSA9IG5JbmRleCwgc3ogPSBtX2FDaGlsZHJlbi5HZXRTaXplKCk7IGkgPCBzejsgaSsrKSB7CiAgICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpIHsKICAgICAgICBBU1NFUlQocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpOwogICAgICAgIENQV0xfTm90ZUl0ZW0qIHBJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKICAgICAgICBwSXRlbS0+UmVzZXRTdWJqZWN0TmFtZShpKTsKICAgICAgfQogICAgfQoKICAgIE9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwogIH0KfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRIaXROb3RlSXRlbShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgewogIENQREZfUG9pbnQgcHQgPSBQYXJlbnRUb0NoaWxkKHBvaW50KTsKCiAgZm9yIChpbnQzMl90IGkgPSAwLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpIHsKICAgICAgaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKSB7CiAgICAgICAgQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKICAgICAgICBpZiAoSVBXTF9Ob3RlSXRlbSogcFJldCA9IHBOb3RlSXRlbS0+R2V0SGl0Tm90ZUl0ZW0ocHQpKQogICAgICAgICAgcmV0dXJuIHBSZXQ7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpPbk5vdGlmeShDUFdMX1duZCogcFduZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IHdQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IGxQYXJhbSkgewogIHN3aXRjaCAobXNnKSB7CiAgICBjYXNlIFBOTV9OT1RFRURJVENIQU5HRUQ6IHsKICAgICAgaW50MzJfdCBuSW5kZXggPSBHZXRJdGVtSW5kZXgocFduZCk7CiAgICAgIGlmIChuSW5kZXggPCAwKQogICAgICAgIG5JbmRleCA9IDA7CgogICAgICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoRkFMU0UpOwogICAgICBSZXNldENvbnRlbnQobkluZGV4KTsKICAgICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwoKICAgICAgZm9yIChpbnQzMl90IGkgPSBuSW5kZXggKyAxLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQogICAgICAgICAgcENoaWxkLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKICAgICAgfQoKICAgICAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICBwUGFyZW50LT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICAgICAgfQogICAgfQogICAgICByZXR1cm47CiAgICBjYXNlIFBOTV9TQ1JPTExXSU5ET1c6CiAgICAgIFNldFNjcm9sbFBvcyhDUERGX1BvaW50KDAuMGYsICooRlhfRkxPQVQqKWxQYXJhbSkpOwogICAgICBSZXNldEZhY2UoKTsKICAgICAgSW52YWxpZGF0ZVJlY3QoTlVMTCk7CiAgICAgIHJldHVybjsKICAgIGNhc2UgUE5NX1NFVENBUkVUSU5GTzoKICAgICAgaWYgKFBXTF9DQVJFVF9JTkZPKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKSB7CiAgICAgICAgUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKICAgICAgICBuZXdJbmZvLmJWaXNpYmxlID0gVFJVRTsKICAgICAgICBuZXdJbmZvLnB0SGVhZCA9IENoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CiAgICAgICAgbmV3SW5mby5wdEZvb3QgPSBDaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOwoKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgICAgICAgcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKGludHB0cl90KSZuZXdJbmZvLCAwKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuOwogICAgY2FzZSBQTk1fTk9URVJFU0VUOiB7CiAgICAgIG1fcEVkaXQtPkVuYWJsZU5vdGlmeShGQUxTRSk7CiAgICAgIFJlc2V0Q29udGVudCgwKTsKICAgICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KFRSVUUpOwoKICAgICAgZm9yIChpbnQzMl90IGkgPSAxLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBDaGlsZCA9IG1fYUNoaWxkcmVuLkdldEF0KGkpKQogICAgICAgICAgcENoaWxkLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKICAgICAgfQoKICAgICAgbV9wRWRpdC0+RW5hYmxlTm90aWZ5KEZBTFNFKTsKICAgICAgUmVzZXRDb250ZW50KDApOwogICAgICBtX3BFZGl0LT5FbmFibGVOb3RpZnkoVFJVRSk7CiAgICB9CiAgICAgIHJldHVybjsKICB9CgogIENQV0xfV25kOjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsKfQoKRlhfQk9PTCBDUFdMX05vdGVfQ29udGVudHM6Ok9uTEJ1dHRvbkRvd24oY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZYX0RXT1JEIG5GbGFnKSB7CiAgaWYgKENQV0xfV25kOjpPbkxCdXR0b25Eb3duKHBvaW50LCBuRmxhZykpCiAgICByZXR1cm4gVFJVRTsKCiAgaWYgKCFtX3BFZGl0LT5Jc0ZvY3VzZWQoKSkgewogICAgbV9wRWRpdC0+U2V0Rm9jdXMoKTsKICB9CgogIHJldHVybiBUUlVFOwp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6U2V0RWRpdEZvY3VzKEZYX0JPT0wgYkxhc3QpIHsKICBpZiAoIW1fcEVkaXQtPklzRm9jdXNlZCgpKSB7CiAgICBtX3BFZGl0LT5TZXRGb2N1cygpOwogICAgbV9wRWRpdC0+U2V0Q2FyZXQoYkxhc3QgPyBtX3BFZGl0LT5HZXRUb3RhbFdvcmRzKCkgOiAwKTsKICB9Cn0KCkNQV0xfRWRpdCogQ1BXTF9Ob3RlX0NvbnRlbnRzOjpHZXRFZGl0KCkgY29uc3QgewogIHJldHVybiBtX3BFZGl0Owp9Cgp2b2lkIENQV0xfTm90ZV9Db250ZW50czo6RW5hYmxlTW9kaWZ5KEZYX0JPT0wgYkVuYWJsZWQpIHsKICBpZiAoIWJFbmFibGVkKQogICAgbV9wRWRpdC0+QWRkRmxhZyhQV1NfUkVBRE9OTFkpOwogIGVsc2UKICAgIG1fcEVkaXQtPlJlbW92ZUZsYWcoUFdTX1JFQURPTkxZKTsKCiAgZm9yIChpbnQzMl90IGkgPSAwLCBzeiA9IG1fYUNoaWxkcmVuLkdldFNpemUoKTsgaSA8IHN6OyBpKyspIHsKICAgIGlmIChDUFdMX1duZCogcENoaWxkID0gbV9hQ2hpbGRyZW4uR2V0QXQoaSkpIHsKICAgICAgaWYgKHBDaGlsZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKSB7CiAgICAgICAgQ1BXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gKENQV0xfTm90ZUl0ZW0qKXBDaGlsZDsKICAgICAgICBwTm90ZUl0ZW0tPkVuYWJsZU1vZGlmeShiRW5hYmxlZCk7CiAgICAgIH0KICAgIH0KICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlX0NvbnRlbnRzOjpFbmFibGVSZWFkKEZYX0JPT0wgYkVuYWJsZWQpIHsKICBpZiAoIWJFbmFibGVkKQogICAgbV9wRWRpdC0+QWRkRmxhZyhQRVNfTk9SRUFEKTsKICBlbHNlCiAgICBtX3BFZGl0LT5SZW1vdmVGbGFnKFBFU19OT1JFQUQpOwoKICBmb3IgKGludDMyX3QgaSA9IDAsIHN6ID0gbV9hQ2hpbGRyZW4uR2V0U2l6ZSgpOyBpIDwgc3o7IGkrKykgewogICAgaWYgKENQV0xfV25kKiBwQ2hpbGQgPSBtX2FDaGlsZHJlbi5HZXRBdChpKSkgewogICAgICBpZiAocENoaWxkLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlSXRlbSIpIHsKICAgICAgICBDUFdMX05vdGVJdGVtKiBwTm90ZUl0ZW0gPSAoQ1BXTF9Ob3RlSXRlbSopcENoaWxkOwogICAgICAgIHBOb3RlSXRlbS0+RW5hYmxlUmVhZChiRW5hYmxlZCk7CiAgICAgIH0KICAgIH0KICB9Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gQ1BXTF9Ob3RlSXRlbQogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGVJdGVtOjpDUFdMX05vdGVJdGVtKCkKICAgIDogbV9wU3ViamVjdChOVUxMKSwKICAgICAgbV9wRGF0ZVRpbWUoTlVMTCksCiAgICAgIG1fcENvbnRlbnRzKE5VTEwpLAogICAgICBtX3BQcml2YXRlRGF0YShOVUxMKSwKICAgICAgbV9zQXV0aG9yKEwiIiksCiAgICAgIG1fZk9sZEl0ZW1IZWlnaHQoMC4wZiksCiAgICAgIG1fYlNpemVDaGFuZ2VkKEZBTFNFKSwKICAgICAgbV9iQWxsb3dNb2RpZnkoVFJVRSkge30KCkNQV0xfTm90ZUl0ZW06On5DUFdMX05vdGVJdGVtKCkge30KCkNGWF9CeXRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldENsYXNzTmFtZSgpIGNvbnN0IHsKICByZXR1cm4gIkNQV0xfTm90ZUl0ZW0iOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNvbnN0IFBXTF9DUkVBVEVQQVJBTSYgY3ApIHsKICBDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CgogIGlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShHZXRCYWNrZ3JvdW5kQ29sb3IoKSkpCiAgICBzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKICBlbHNlCiAgICBzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKCiAgbV9wU3ViamVjdCA9IG5ldyBDUFdMX0xhYmVsOwogIFBXTF9DUkVBVEVQQVJBTSBzY3AgPSBjcDsKICBzY3AucFBhcmVudFduZCA9IHRoaXM7CiAgc2NwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19MRUZUIHwgUEVTX1RPUDsKICBzY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wU3ViamVjdC0+Q3JlYXRlKHNjcCk7CgogIG1fcERhdGVUaW1lID0gbmV3IENQV0xfTGFiZWw7CiAgUFdMX0NSRUFURVBBUkFNIGRjcCA9IGNwOwogIGRjcC5wUGFyZW50V25kID0gdGhpczsKICBkY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUEVTX1JJR0hUIHwgUEVTX1RPUDsKICBkY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wRGF0ZVRpbWUtPkNyZWF0ZShkY3ApOwoKICBtX3BDb250ZW50cyA9IG5ldyBDUFdMX05vdGVfQ29udGVudHM7CiAgUFdMX0NSRUFURVBBUkFNIGNjcCA9IGNwOwogIGNjcC5wUGFyZW50V25kID0gdGhpczsKICAvLyBjY3Auc0JhY2tncm91bmRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CiAgY2NwLnNCYWNrZ3JvdW5kQ29sb3IgPQogICAgICBDUFdMX0NvbG9yKENPTE9SVFlQRV9SR0IsIDI0MCAvIDI1NS4wZiwgMjQwIC8gMjU1LjBmLCAyNDAgLyAyNTUuMGYpOwogIGNjcC5kd0ZsYWdzID0gUFdTX1ZJU0lCTEUgfCBQV1NfQ0hJTEQgfCBQV1NfQkFDS0dST1VORDsKICBtX3BDb250ZW50cy0+Q3JlYXRlKGNjcCk7CiAgbV9wQ29udGVudHMtPlNldEl0ZW1TcGFjZShQT1BVUF9JVEVNX1NQQUNFKTsKICBtX3BDb250ZW50cy0+U2V0VG9wU3BhY2UoUE9QVVBfSVRFTV9TUEFDRSk7CiAgbV9wQ29udGVudHMtPlNldEJvdHRvbVNwYWNlKFBPUFVQX0lURU1fU1BBQ0UpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlJlUG9zQ2hpbGRXbmQoKSB7CiAgaWYgKElzVmFsaWQoKSkgewogICAgQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wRGF0ZVRpbWUgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wQ29udGVudHMgIT0gTlVMTCk7CgogICAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gR2V0Q2xpZW50UmVjdCgpOwoKICAgIENQREZfUmVjdCByY1N1YmplY3QgPSByY0NsaWVudDsKICAgIHJjU3ViamVjdC5sZWZ0ICs9IFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CiAgICByY1N1YmplY3QudG9wID0gcmNDbGllbnQudG9wOwogICAgcmNTdWJqZWN0LnJpZ2h0ID0KICAgICAgICBQV0xfTUlOKHJjU3ViamVjdC5sZWZ0ICsgbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwKICAgICAgICAgICAgICAgIHJjQ2xpZW50LnJpZ2h0KTsKICAgIHJjU3ViamVjdC5ib3R0b20gPSByY1N1YmplY3QudG9wIC0gbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKICAgIHJjU3ViamVjdC5Ob3JtYWxpemUoKTsKICAgIG1fcFN1YmplY3QtPk1vdmUocmNTdWJqZWN0LCBUUlVFLCBGQUxTRSk7CiAgICBtX3BTdWJqZWN0LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNTdWJqZWN0KSk7CgogICAgQ1BERl9SZWN0IHJjRGF0ZSA9IHJjQ2xpZW50OwogICAgcmNEYXRlLnJpZ2h0IC09IFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CiAgICByY0RhdGUubGVmdCA9CiAgICAgICAgUFdMX01BWChyY0RhdGUucmlnaHQgLSBtX3BEYXRlVGltZS0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpIC0gMS4wZiwKICAgICAgICAgICAgICAgIHJjU3ViamVjdC5yaWdodCk7CiAgICByY0RhdGUuYm90dG9tID0gcmNEYXRlLnRvcCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLkhlaWdodCgpOwogICAgcmNEYXRlLk5vcm1hbGl6ZSgpOwogICAgbV9wRGF0ZVRpbWUtPk1vdmUocmNEYXRlLCBUUlVFLCBGQUxTRSk7CiAgICBtX3BEYXRlVGltZS0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjRGF0ZSkpOwoKICAgIENQREZfUmVjdCByY0NvbnRlbnRzID0gcmNDbGllbnQ7CiAgICByY0NvbnRlbnRzLmxlZnQgKz0gMS4wZjsKICAgIHJjQ29udGVudHMucmlnaHQgLT0gMS4wZjsKICAgIHJjQ29udGVudHMudG9wID0gcmNEYXRlLmJvdHRvbSAtIFBPUFVQX0lURU1fSEVBRF9CT1RUT007CiAgICByY0NvbnRlbnRzLmJvdHRvbSArPSBQT1BVUF9JVEVNX0JPVFRPTVdJRFRIOwogICAgcmNDb250ZW50cy5Ob3JtYWxpemUoKTsKICAgIG1fcENvbnRlbnRzLT5Nb3ZlKHJjQ29udGVudHMsIFRSVUUsIEZBTFNFKTsKICAgIG1fcENvbnRlbnRzLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNDb250ZW50cykpOwogIH0KCiAgU2V0Q2xpcFJlY3QoQ1BXTF9VdGlsczo6SW5mbGF0ZVJlY3QoR2V0V2luZG93UmVjdCgpLCAxLjBmKSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0UHJpdmF0ZURhdGEodm9pZCogcERhdGEpIHsKICBtX3BQcml2YXRlRGF0YSA9IHBEYXRhOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldEJrQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpIHsKICBDUFdMX0NvbG9yIHNCSyA9IGNvbG9yOwogIFNldEJhY2tncm91bmRDb2xvcihzQkspOwoKICBDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CgogIGlmIChDUFdMX1V0aWxzOjpJc0JsYWNrT3JXaGl0ZShzQkspKQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CiAgZWxzZQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgogIFNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKICBpZiAobV9wU3ViamVjdCkKICAgIG1fcFN1YmplY3QtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKICBpZiAobV9wRGF0ZVRpbWUpCiAgICBtX3BEYXRlVGltZS0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwoKICBJbnZhbGlkYXRlUmVjdChudWxscHRyKTsKCiAgaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkgewogICAgcE5vdGlmeS0+T25TZXRCa0NvbG9yKHRoaXMpOwogIH0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpTZXRTdWJqZWN0TmFtZShjb25zdCBDRlhfV2lkZVN0cmluZyYgc05hbWUpIHsKICBpZiAobV9wU3ViamVjdCkgewogICAgbV9wU3ViamVjdC0+U2V0VGV4dChzTmFtZS5jX3N0cigpKTsKICB9CgogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0U3ViamVjdE5hbWUodGhpcyk7CiAgfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldEF1dGhvck5hbWUoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNOYW1lKSB7CiAgbV9zQXV0aG9yID0gc05hbWU7CiAgUmVzZXRTdWJqZWN0TmFtZSgtMSk7CgogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsKICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6UmVzZXRTdWJqZWN0TmFtZShpbnQzMl90IG5JdGVtSW5kZXgpIHsKICBpZiAobkl0ZW1JbmRleCA8IDApIHsKICAgIGlmIChDUFdMX1duZCogcFBhcmVudCA9IEdldFBhcmVudFdpbmRvdygpKSB7CiAgICAgIEFTU0VSVChwUGFyZW50LT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlX0NvbnRlbnRzIik7CgogICAgICBDUFdMX05vdGVfQ29udGVudHMqIHBDb250ZW50cyA9IChDUFdMX05vdGVfQ29udGVudHMqKXBQYXJlbnQ7CiAgICAgIG5JdGVtSW5kZXggPSBwQ29udGVudHMtPkdldEl0ZW1JbmRleCh0aGlzKTsKICAgIH0KICB9CgogIGNvbnN0IENQV0xfTm90ZSogcE5vdGUgPSBHZXROb3RlKCk7CiAgQVNTRVJUKHBOb3RlICE9IE5VTEwpOwoKICBDRlhfV2lkZVN0cmluZyBzU3ViamVjdDsKICBzU3ViamVjdC5Gb3JtYXQocE5vdGUtPkdldFJlcGx5U3RyaW5nKCkuY19zdHIoKSwgbkl0ZW1JbmRleCk7CgogIGlmICghbV9zQXV0aG9yLklzRW1wdHkoKSkgewogICAgc1N1YmplY3QgKz0gTCIgLSAiOwogICAgc1N1YmplY3QgKz0gbV9zQXV0aG9yOwogIH0KICBTZXRTdWJqZWN0TmFtZShzU3ViamVjdCk7CiAgUmVQb3NDaGlsZFduZCgpOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldERhdGVUaW1lKEZYX1NZU1RFTVRJTUUgdGltZSkgewogIG1fZHROb3RlID0gdGltZTsKCiAgQ0ZYX1dpZGVTdHJpbmcgc3dUaW1lOwogIHN3VGltZS5Gb3JtYXQoTCIlMDRkLSUwMmQtJTAyZCAlMDJkOiUwMmQ6JTAyZCIsIHRpbWUud1llYXIsIHRpbWUud01vbnRoLAogICAgICAgICAgICAgICAgdGltZS53RGF5LCB0aW1lLndIb3VyLCB0aW1lLndNaW51dGUsIHRpbWUud1NlY29uZCk7CiAgaWYgKG1fcERhdGVUaW1lKSB7CiAgICBtX3BEYXRlVGltZS0+U2V0VGV4dChzd1RpbWUuY19zdHIoKSk7CiAgfQoKICBSZVBvc0NoaWxkV25kKCk7CgogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0RGF0ZVRpbWUodGhpcyk7CiAgfQp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06OlNldENvbnRlbnRzKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzQ29udGVudHMpIHsKICBpZiAobV9wQ29udGVudHMpIHsKICAgIG1fcENvbnRlbnRzLT5TZXRUZXh0KHNDb250ZW50cyk7CiAgfQoKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBwTm90aWZ5LT5PblNldENvbnRlbnRzKHRoaXMpOwogIH0KfQoKQ1BXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0UGFyZW50Tm90ZUl0ZW0oKSBjb25zdCB7CiAgaWYgKENQV0xfV25kKiBwUGFyZW50ID0gR2V0UGFyZW50V2luZG93KCkpIHsKICAgIGlmIChDUFdMX1duZCogcEdyYW5kID0gcFBhcmVudC0+R2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgQVNTRVJUKHBHcmFuZC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKICAgICAgcmV0dXJuIChDUFdMX05vdGVJdGVtKilwR3JhbmQ7CiAgICB9CiAgfQoKICByZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0UGFyZW50SXRlbSgpIGNvbnN0IHsKICByZXR1cm4gR2V0UGFyZW50Tm90ZUl0ZW0oKTsKfQoKQ1BXTF9FZGl0KiBDUFdMX05vdGVJdGVtOjpHZXRFZGl0KCkgY29uc3QgewogIGlmIChtX3BDb250ZW50cykKICAgIHJldHVybiBtX3BDb250ZW50cy0+R2V0RWRpdCgpOwogIHJldHVybiBOVUxMOwp9Cgp2b2lkKiBDUFdMX05vdGVJdGVtOjpHZXRQcml2YXRlRGF0YSgpIGNvbnN0IHsKICByZXR1cm4gbV9wUHJpdmF0ZURhdGE7Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZUl0ZW06OkdldEF1dGhvck5hbWUoKSBjb25zdCB7CiAgcmV0dXJuIG1fc0F1dGhvcjsKfQoKQ1BXTF9Db2xvciBDUFdMX05vdGVJdGVtOjpHZXRCa0NvbG9yKCkgY29uc3QgewogIHJldHVybiBHZXRCYWNrZ3JvdW5kQ29sb3IoKTsKfQoKQ0ZYX1dpZGVTdHJpbmcgQ1BXTF9Ob3RlSXRlbTo6R2V0Q29udGVudHMoKSBjb25zdCB7CiAgaWYgKG1fcENvbnRlbnRzKQogICAgcmV0dXJuIG1fcENvbnRlbnRzLT5HZXRUZXh0KCk7CgogIHJldHVybiBMIiI7Cn0KCkZYX1NZU1RFTVRJTUUgQ1BXTF9Ob3RlSXRlbTo6R2V0RGF0ZVRpbWUoKSBjb25zdCB7CiAgcmV0dXJuIG1fZHROb3RlOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGVJdGVtOjpHZXRTdWJqZWN0TmFtZSgpIGNvbnN0IHsKICBpZiAobV9wU3ViamVjdCkKICAgIHJldHVybiBtX3BTdWJqZWN0LT5HZXRUZXh0KCk7CgogIHJldHVybiBMIiI7Cn0KCkNQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkNyZWF0ZU5vdGVJdGVtKCkgewogIGlmIChtX3BDb250ZW50cykKICAgIHJldHVybiBtX3BDb250ZW50cy0+Q3JlYXRlU3ViSXRlbSgpOwoKICByZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6Q3JlYXRlU3ViSXRlbSgpIHsKICByZXR1cm4gQ3JlYXRlTm90ZUl0ZW0oKTsKfQoKaW50MzJfdCBDUFdMX05vdGVJdGVtOjpDb3VudFN1Ykl0ZW1zKCkgY29uc3QgewogIGlmIChtX3BDb250ZW50cykKICAgIHJldHVybiBtX3BDb250ZW50cy0+Q291bnRTdWJJdGVtcygpOwoKICByZXR1cm4gMDsKfQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlSXRlbTo6R2V0U3ViSXRlbXMoaW50MzJfdCBpbmRleCkgY29uc3QgewogIGlmIChtX3BDb250ZW50cykKICAgIHJldHVybiBtX3BDb250ZW50cy0+R2V0U3ViSXRlbXMoaW5kZXgpOwoKICByZXR1cm4gTlVMTDsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpEZWxldGVTdWJJdGVtKElQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSkgewogIEtpbGxGb2N1cygpOwoKICBpZiAoSVBXTF9Ob3RlTm90aWZ5KiBwTm90aWZ5ID0gR2V0Tm90ZU5vdGlmeSgpKSB7CiAgICBwTm90aWZ5LT5Pbkl0ZW1EZWxldGUocE5vdGVJdGVtKTsKICB9CgogIGlmIChtX3BDb250ZW50cykKICAgIG1fcENvbnRlbnRzLT5EZWxldGVTdWJJdGVtKHBOb3RlSXRlbSk7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldEhpdE5vdGVJdGVtKGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSB7CiAgQ1BERl9Qb2ludCBwdCA9IFBhcmVudFRvQ2hpbGQocG9pbnQpOwoKICBpZiAoV25kSGl0VGVzdChwdCkpIHsKICAgIGlmIChtX3BDb250ZW50cykgewogICAgICBpZiAoSVBXTF9Ob3RlSXRlbSogcE5vdGVJdGVtID0gbV9wQ29udGVudHMtPkdldEhpdE5vdGVJdGVtKHB0KSkKICAgICAgICByZXR1cm4gcE5vdGVJdGVtOwogICAgfQoKICAgIHJldHVybiB0aGlzOwogIH0KCiAgcmV0dXJuIE5VTEw7Cn0KCklQV0xfTm90ZUl0ZW0qIENQV0xfTm90ZUl0ZW06OkdldEZvY3VzZWROb3RlSXRlbSgpIGNvbnN0IHsKICBpZiAoY29uc3QgQ1BXTF9XbmQqIHBXbmQgPSBHZXRGb2N1c2VkKCkpIHsKICAgIGlmIChwV25kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9FZGl0IikgewogICAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBwV25kLT5HZXRQYXJlbnRXaW5kb3coKSkgewogICAgICAgIEFTU0VSVChwUGFyZW50LT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9Ob3RlX0NvbnRlbnRzIik7CgogICAgICAgIGlmIChDUFdMX1duZCogcEdyYW5kID0gcFBhcmVudC0+R2V0UGFyZW50V2luZG93KCkpIHsKICAgICAgICAgIEFTU0VSVChwR3JhbmQtPkdldENsYXNzTmFtZSgpID09ICJDUFdMX05vdGVJdGVtIik7CiAgICAgICAgICByZXR1cm4gKENQV0xfTm90ZUl0ZW0qKXBHcmFuZDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBOVUxMOwp9CgpGWF9GTE9BVCBDUFdMX05vdGVJdGVtOjpHZXRJdGVtSGVpZ2h0KEZYX0ZMT0FUIGZMaW1pdFdpZHRoKSB7CiAgaWYgKGZMaW1pdFdpZHRoID4gMCkgewogICAgaWYgKCFtX2JTaXplQ2hhbmdlZCkKICAgICAgcmV0dXJuIG1fZk9sZEl0ZW1IZWlnaHQ7CgogICAgbV9iU2l6ZUNoYW5nZWQgPSBGQUxTRTsKCiAgICBBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsKCiAgICBGWF9GTE9BVCBmUmV0ID0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CiAgICBGWF9GTE9BVCBmQm9yZGVyV2lkdGggPSAoRlhfRkxPQVQpR2V0Qm9yZGVyV2lkdGgoKTsKICAgIGlmIChmTGltaXRXaWR0aCA+IGZCb3JkZXJXaWR0aCAqIDIpCiAgICAgIGZSZXQgKz0gbV9wQ29udGVudHMtPkdldENvbnRlbnRzSGVpZ2h0KGZMaW1pdFdpZHRoIC0gZkJvcmRlcldpZHRoICogMik7CiAgICBmUmV0ICs9IFBPUFVQX0lURU1fSEVBRF9CT1RUT00gKyBQT1BVUF9JVEVNX0JPVFRPTVdJRFRIICsgZkJvcmRlcldpZHRoICogMjsKCiAgICByZXR1cm4gbV9mT2xkSXRlbUhlaWdodCA9IGZSZXQ7CiAgfQoKICByZXR1cm4gMDsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbUxlZnRNYXJnaW4oKSB7CiAgcmV0dXJuIFBPUFVQX0lURU1fU0lERU1BUkdJTjsKfQoKRlhfRkxPQVQgQ1BXTF9Ob3RlSXRlbTo6R2V0SXRlbVJpZ2h0TWFyZ2luKCkgewogIHJldHVybiBQT1BVUF9JVEVNX1NJREVNQVJHSU47Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlSXRlbTo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpIHsKICBpZiAoIW1fcENvbnRlbnRzLT5XbmRIaXRUZXN0KG1fcENvbnRlbnRzLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHsKICAgIFNldE5vdGVGb2N1cyhGQUxTRSk7CiAgfQoKICBDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCwgbkZsYWcpOwoKICByZXR1cm4gVFJVRTsKfQoKRlhfQk9PTCBDUFdMX05vdGVJdGVtOjpPblJCdXR0b25VcChjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpIHsKICBpZiAoIW1fcENvbnRlbnRzLT5XbmRIaXRUZXN0KG1fcENvbnRlbnRzLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHsKICAgIFNldE5vdGVGb2N1cyhGQUxTRSk7CiAgICBQb3B1cE5vdGVJdGVtTWVudShwb2ludCk7CgogICAgcmV0dXJuIFRSVUU7CiAgfQoKICByZXR1cm4gQ1BXTF9XbmQ6Ok9uUkJ1dHRvblVwKHBvaW50LCBuRmxhZyk7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6T25Ob3RpZnkoQ1BXTF9XbmQqIHBXbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHB0cl90IHdQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRwdHJfdCBsUGFyYW0pIHsKICBzd2l0Y2ggKG1zZykgewogICAgY2FzZSBQTk1fTk9URUVESVRDSEFOR0VEOgogICAgICBtX2JTaXplQ2hhbmdlZCA9IFRSVUU7CgogICAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgICAgIHBQYXJlbnQtPk9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIDApOwogICAgICB9CiAgICAgIHJldHVybjsKICAgIGNhc2UgUE5NX1NFVENBUkVUSU5GTzoKICAgICAgaWYgKFBXTF9DQVJFVF9JTkZPKiBwSW5mbyA9IChQV0xfQ0FSRVRfSU5GTyopd1BhcmFtKSB7CiAgICAgICAgUFdMX0NBUkVUX0lORk8gbmV3SW5mbyA9ICpwSW5mbzsKICAgICAgICBuZXdJbmZvLmJWaXNpYmxlID0gVFJVRTsKICAgICAgICBuZXdJbmZvLnB0SGVhZCA9IENoaWxkVG9QYXJlbnQocEluZm8tPnB0SGVhZCk7CiAgICAgICAgbmV3SW5mby5wdEZvb3QgPSBDaGlsZFRvUGFyZW50KHBJbmZvLT5wdEZvb3QpOwoKICAgICAgICBpZiAoQ1BXTF9XbmQqIHBQYXJlbnQgPSBHZXRQYXJlbnRXaW5kb3coKSkgewogICAgICAgICAgcFBhcmVudC0+T25Ob3RpZnkodGhpcywgUE5NX1NFVENBUkVUSU5GTywgKGludHB0cl90KSZuZXdJbmZvLCAwKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuOwogICAgY2FzZSBQTk1fTk9URVJFU0VUOgogICAgICBtX2JTaXplQ2hhbmdlZCA9IFRSVUU7CiAgICAgIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKCiAgICAgIHJldHVybjsKICB9CgogIENQV0xfV25kOjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpQb3B1cE5vdGVJdGVtTWVudShjb25zdCBDUERGX1BvaW50JiBwb2ludCkgewogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIGludDMyX3QgeCwgeTsKICAgIFBXTHRvV25kKHBvaW50LCB4LCB5KTsKICAgIGlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQogICAgICBwU0gtPkNsaWVudFRvU2NyZWVuKEdldEF0dGFjaGVkSFduZCgpLCB4LCB5KTsKICAgIHBOb3RpZnktPk9uUG9wdXBNZW51KHRoaXMsIHgsIHkpOwogIH0KfQoKY29uc3QgQ1BXTF9Ob3RlKiBDUFdMX05vdGVJdGVtOjpHZXROb3RlKCkgY29uc3QgewogIGlmIChjb25zdCBDUFdMX1duZCogcFJvb3QgPSBHZXRSb290V25kKCkpIHsKICAgIEFTU0VSVChwUm9vdC0+R2V0Q2xhc3NOYW1lKCkgPT0gIkNQV0xfTm90ZUl0ZW0iKTsKICAgIENQV0xfTm90ZUl0ZW0qIHBOb3RlSXRlbSA9IChDUFdMX05vdGVJdGVtKilwUm9vdDsKICAgIGlmIChwTm90ZUl0ZW0tPklzVG9wSXRlbSgpKSB7CiAgICAgIHJldHVybiAoQ1BXTF9Ob3RlKilwTm90ZUl0ZW07CiAgICB9CiAgfQoKICByZXR1cm4gTlVMTDsKfQoKSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGVJdGVtOjpHZXROb3RlTm90aWZ5KCkgY29uc3QgewogIGlmIChjb25zdCBDUFdMX05vdGUqIHBOb3RlID0gR2V0Tm90ZSgpKQogICAgcmV0dXJuIHBOb3RlLT5HZXROb3RlTm90aWZ5KCk7CgogIHJldHVybiBOVUxMOwp9Cgp2b2lkIENQV0xfTm90ZUl0ZW06Ok9uQ3JlYXRlTm90ZUl0ZW0oKSB7CiAgaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkgewogICAgcE5vdGlmeS0+T25JdGVtQ3JlYXRlKHRoaXMpOwogIH0KfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpPbkNvbnRlbnRzVmFsaWRhdGUoKSB7CiAgaWYgKElQV0xfTm90ZU5vdGlmeSogcE5vdGlmeSA9IEdldE5vdGVOb3RpZnkoKSkgewogICAgcE5vdGlmeS0+T25TZXRDb250ZW50cyh0aGlzKTsKICB9Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6U2V0Tm90ZUZvY3VzKEZYX0JPT0wgYkxhc3QpIHsKICBtX3BDb250ZW50cy0+U2V0RWRpdEZvY3VzKGJMYXN0KTsKfQoKdm9pZCBDUFdMX05vdGVJdGVtOjpFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCkgewogIG1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwogIG1fYkFsbG93TW9kaWZ5ID0gYkVuYWJsZWQ7Cn0KCnZvaWQgQ1BXTF9Ob3RlSXRlbTo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKSB7CiAgbV9wQ29udGVudHMtPkVuYWJsZVJlYWQoYkVuYWJsZWQpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIENQV0xfTm90ZQogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpDUFdMX05vdGU6OkNQV0xfTm90ZShJUG9wdXBfTm90ZSogcFBvcHVwTm90ZSwKICAgICAgICAgICAgICAgICAgICAgSVBXTF9Ob3RlTm90aWZ5KiBwTm90ZU5vdGlmeSwKICAgICAgICAgICAgICAgICAgICAgSVBXTF9Ob3RlSGFuZGxlciogcE5vdGVIYW5kbGVyKQogICAgOiBtX3BBdXRob3IoTlVMTCksCiAgICAgIG1fcEljb24oTlVMTCksCiAgICAgIG1fcENsb3NlQm94KE5VTEwpLAogICAgICBtX3BMQkJveChOVUxMKSwKICAgICAgbV9wUkJCb3goTlVMTCksCiAgICAgIG1fcENvbnRlbnRzQmFyKE5VTEwpLAogICAgICBtX3BPcHRpb25zKE5VTEwpLAogICAgICBtX3BOb3RlTm90aWZ5KHBOb3RlTm90aWZ5KSwKICAgICAgbV9iUmVzaXppbmcoRkFMU0UpLAogICAgICBtX3JjQ2FwdGlvbigwLCAwLCAwLCAwKSwKICAgICAgbV9iRW5hbGJsZU5vdGlmeShUUlVFKSwKICAgICAgbV9wUG9wdXBOb3RlKHBQb3B1cE5vdGUpIHt9CgpDUFdMX05vdGU6On5DUFdMX05vdGUoKSB7fQoKSVBXTF9Ob3RlSXRlbSogQ1BXTF9Ob3RlOjpSZXBseSgpIHsKICByZXR1cm4gQ3JlYXRlTm90ZUl0ZW0oKTsKfQoKdm9pZCBDUFdMX05vdGU6OkVuYWJsZU5vdGlmeShGWF9CT09MIGJFbmFibGVkKSB7CiAgbV9iRW5hbGJsZU5vdGlmeSA9IGJFbmFibGVkOwp9Cgp2b2lkIENQV0xfTm90ZTo6UmVQb3NDaGlsZFduZCgpIHsKICBSZVBvc05vdGVDaGlsZHJlbigpOwogIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKICBSZXNldFNjcm9sbEJhcigpOwogIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fTk9URVJFU0VULCAwLCAwKTsKICBPbk5vdGlmeSh0aGlzLCBQTk1fTk9URUVESVRDSEFOR0VELCAwLCAwKTsKICBpZiAoY29uc3QgQ1BXTF9XbmQqIHBXbmQgPSBHZXRGb2N1c2VkKCkpIHsKICAgIGlmIChwV25kLT5HZXRDbGFzc05hbWUoKSA9PSAiQ1BXTF9FZGl0IikgewogICAgICBDUFdMX0VkaXQqIHBFZGl0ID0gKENQV0xfRWRpdCopcFduZDsKICAgICAgcEVkaXQtPlNldENhcmV0KHBFZGl0LT5HZXRDYXJldCgpKTsKICAgIH0KICB9Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlOjpSZXNldFNjcm9sbEJhcigpIHsKICBGWF9CT09MIGJTY3JvbGxDaGFuZ2VkID0gRkFMU0U7CgogIGlmIChTY3JvbGxCYXJTaG91bGRWaXNpYmxlKCkpIHsKICAgIGlmICghbV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKSB7CiAgICAgIG1fcENvbnRlbnRzQmFyLT5TZXRWaXNpYmxlKFRSVUUpOwogICAgICBpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKSB7CiAgICAgICAgbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOwogICAgICAgIGJTY3JvbGxDaGFuZ2VkID0gVFJVRTsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICBpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKSB7CiAgICAgIG1fcENvbnRlbnRzQmFyLT5TZXRWaXNpYmxlKEZBTFNFKTsKICAgICAgbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOwoKICAgICAgYlNjcm9sbENoYW5nZWQgPSBUUlVFOwogICAgfQogIH0KCiAgaWYgKGJTY3JvbGxDaGFuZ2VkKSB7CiAgICBDUERGX1JlY3QgcmNOb3RlID0gR2V0Q2xpZW50UmVjdCgpOwogICAgQ1BERl9SZWN0IHJjQ29udGVudHMgPSBtX3BDb250ZW50cy0+R2V0V2luZG93UmVjdCgpOwogICAgcmNDb250ZW50cy5yaWdodCA9IHJjTm90ZS5yaWdodCAtIDMuMGY7CiAgICBpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQogICAgICByY0NvbnRlbnRzLnJpZ2h0IC09IFBXTF9TQ1JPTExCQVJfV0lEVEg7CiAgICBtX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBUUlVFLCBUUlVFKTsKICAgIG1fcENvbnRlbnRzLT5TZXRTY3JvbGxQb3MoQ1BERl9Qb2ludCgwLjBmLCAwLjBmKSk7CiAgICBtX3BDb250ZW50cy0+SW52YWxpZGF0ZVJlY3QoTlVMTCk7CiAgfQoKICByZXR1cm4gYlNjcm9sbENoYW5nZWQ7Cn0KCkZYX0JPT0wgQ1BXTF9Ob3RlOjpTY3JvbGxCYXJTaG91bGRWaXNpYmxlKCkgewogIENQREZfUmVjdCByY0NvbnRlbnRzRmFjdCA9IG1fcENvbnRlbnRzLT5HZXRTY3JvbGxBcmVhKCk7CiAgQ1BERl9SZWN0IHJjQ29udGVudHNDbGllbnQgPSBtX3BDb250ZW50cy0+R2V0Q2xpZW50UmVjdCgpOwoKICByZXR1cm4gcmNDb250ZW50c0ZhY3QuSGVpZ2h0KCkgPiByY0NvbnRlbnRzQ2xpZW50LkhlaWdodCgpOwp9Cgp2b2lkIENQV0xfTm90ZTo6U2V0T3B0aW9uc1RleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHNUZXh0KSB7CiAgaWYgKG1fcE9wdGlvbnMpCiAgICBtX3BPcHRpb25zLT5TZXRUZXh0KHNUZXh0KTsKCiAgUmVQb3NOb3RlQ2hpbGRyZW4oKTsKfQoKdm9pZCBDUFdMX05vdGU6OlJlUG9zTm90ZUNoaWxkcmVuKCkgewogIGlmIChtX2JSZXNpemluZykKICAgIHJldHVybjsKCiAgbV9iUmVzaXppbmcgPSBUUlVFOwoKICBpZiAoSXNWYWxpZCgpKSB7CiAgICBBU1NFUlQobV9wU3ViamVjdCAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BEYXRlVGltZSAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BBdXRob3IgIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wQ2xvc2VCb3ggIT0gTlVMTCk7CiAgICBBU1NFUlQobV9wSWNvbiAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BSQkJveCAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BDb250ZW50c0JhciAhPSBOVUxMKTsKICAgIEFTU0VSVChtX3BPcHRpb25zICE9IE5VTEwpOwoKICAgIENQREZfUmVjdCByY0NsaWVudCA9IEdldENsaWVudFJlY3QoKTsKCiAgICBDUERGX1JlY3QgcmNJY29uID0gcmNDbGllbnQ7CiAgICByY0ljb24udG9wIC09IDIuMGY7CiAgICByY0ljb24ucmlnaHQgPSByY0ljb24ubGVmdCArIDE0LjBmOwogICAgcmNJY29uLmJvdHRvbSA9IHJjSWNvbi50b3AgLSAxNC4wZjsKICAgIHJjSWNvbi5Ob3JtYWxpemUoKTsKICAgIG1fcEljb24tPk1vdmUocmNJY29uLCBUUlVFLCBGQUxTRSk7CiAgICBtX3BJY29uLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNJY29uKSk7CgogICAgQ1BERl9SZWN0IHJjQ2xvc2VCb3ggPSByY0NsaWVudDsKICAgIHJjQ2xvc2VCb3gucmlnaHQgLT0gMS4wZjsKICAgIHJjQ2xvc2VCb3gudG9wIC09IDEuMGY7CiAgICByY0Nsb3NlQm94LmxlZnQgPSByY0Nsb3NlQm94LnJpZ2h0IC0gMTQuMGY7CiAgICByY0Nsb3NlQm94LmJvdHRvbSA9IHJjQ2xvc2VCb3gudG9wIC0gMTQuMGY7CiAgICByY0Nsb3NlQm94Lk5vcm1hbGl6ZSgpOwogICAgbV9wQ2xvc2VCb3gtPk1vdmUocmNDbG9zZUJveCwgVFJVRSwgRkFMU0UpOwogICAgbV9wQ2xvc2VCb3gtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0Nsb3NlQm94KSk7CgogICAgQ1BERl9SZWN0IHJjRGF0ZSA9IHJjQ2xpZW50OwogICAgcmNEYXRlLnJpZ2h0ID0gcmNDbG9zZUJveC5sZWZ0IC0gUE9QVVBfSVRFTV9URVhUX0lOREVOVDsKICAgIHJjRGF0ZS5sZWZ0ID0KICAgICAgICBQV0xfTUFYKHJjRGF0ZS5yaWdodCAtIG1fcERhdGVUaW1lLT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgLSAxLjBmLAogICAgICAgICAgICAgICAgcmNJY29uLnJpZ2h0ICsgMS4wZik7CiAgICByY0RhdGUudG9wID0gcmNDbGllbnQudG9wIC0gMi4wZjsKICAgIHJjRGF0ZS5ib3R0b20gPSByY0RhdGUudG9wIC0gbV9wRGF0ZVRpbWUtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CiAgICByY0RhdGUuTm9ybWFsaXplKCk7CiAgICBtX3BEYXRlVGltZS0+TW92ZShyY0RhdGUsIFRSVUUsIEZBTFNFKTsKICAgIG1fcERhdGVUaW1lLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNEYXRlKSk7CgogICAgQ1BERl9SZWN0IHJjU3ViamVjdCA9IHJjQ2xpZW50OwogICAgcmNTdWJqZWN0LnRvcCA9IHJjQ2xpZW50LnRvcCAtIDIuMGY7CiAgICByY1N1YmplY3QubGVmdCA9IHJjSWNvbi5yaWdodCArIFBPUFVQX0lURU1fVEVYVF9JTkRFTlQ7CiAgICByY1N1YmplY3QucmlnaHQgPQogICAgICAgIFBXTF9NSU4ocmNTdWJqZWN0LmxlZnQgKyBtX3BTdWJqZWN0LT5HZXRDb250ZW50UmVjdCgpLldpZHRoKCkgKyAxLjBmLAogICAgICAgICAgICAgICAgcmNEYXRlLmxlZnQgLSAxLjBmKTsKICAgIHJjU3ViamVjdC5ib3R0b20gPSByY1N1YmplY3QudG9wIC0gbV9wU3ViamVjdC0+R2V0Q29udGVudFJlY3QoKS5IZWlnaHQoKTsKICAgIHJjU3ViamVjdC5Ob3JtYWxpemUoKTsKICAgIG1fcFN1YmplY3QtPk1vdmUocmNTdWJqZWN0LCBUUlVFLCBGQUxTRSk7CiAgICBtX3BTdWJqZWN0LT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNTdWJqZWN0KSk7CgogICAgQ1BERl9SZWN0IHJjT3B0aW9ucyA9IHJjQ2xpZW50OwogICAgcmNPcHRpb25zLmxlZnQgPQogICAgICAgIFBXTF9NQVgocmNPcHRpb25zLnJpZ2h0IC0gbV9wT3B0aW9ucy0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpLAogICAgICAgICAgICAgICAgcmNJY29uLnJpZ2h0ICsgMS4wZik7CiAgICByY09wdGlvbnMudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7CiAgICByY09wdGlvbnMuYm90dG9tID0gcmNPcHRpb25zLnRvcCAtIG1fcE9wdGlvbnMtPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CiAgICByY09wdGlvbnMuTm9ybWFsaXplKCk7CiAgICBtX3BPcHRpb25zLT5Nb3ZlKHJjT3B0aW9ucywgVFJVRSwgRkFMU0UpOwogICAgbV9wT3B0aW9ucy0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjT3B0aW9ucykpOwoKICAgIENQREZfUmVjdCByY0F1dGhvciA9IHJjQ2xpZW50OwogICAgcmNBdXRob3IudG9wID0gcmNTdWJqZWN0LmJvdHRvbSAtIDQuMGY7CiAgICByY0F1dGhvci5sZWZ0ID0gcmNTdWJqZWN0LmxlZnQ7CiAgICByY0F1dGhvci5yaWdodCA9CiAgICAgICAgUFdMX01JTihyY1N1YmplY3QubGVmdCArIG1fcEF1dGhvci0+R2V0Q29udGVudFJlY3QoKS5XaWR0aCgpICsgMS4wZiwKICAgICAgICAgICAgICAgIHJjT3B0aW9ucy5sZWZ0IC0gMS4wZik7CiAgICByY0F1dGhvci5ib3R0b20gPSByY0F1dGhvci50b3AgLSBtX3BBdXRob3ItPkdldENvbnRlbnRSZWN0KCkuSGVpZ2h0KCk7CiAgICByY0F1dGhvci5Ob3JtYWxpemUoKTsKICAgIG1fcEF1dGhvci0+TW92ZShyY0F1dGhvciwgVFJVRSwgRkFMU0UpOwogICAgbV9wQXV0aG9yLT5TZXRWaXNpYmxlKENQV0xfVXRpbHM6OkNvbnRhaW5zUmVjdChyY0NsaWVudCwgcmNBdXRob3IpKTsKCiAgICBDUERGX1JlY3QgcmNMQkJveCA9IHJjQ2xpZW50OwogICAgcmNMQkJveC50b3AgPSByY0xCQm94LmJvdHRvbSArIDcuMGY7CiAgICByY0xCQm94LnJpZ2h0ID0gcmNMQkJveC5sZWZ0ICsgNy4wZjsKICAgIHJjTEJCb3guTm9ybWFsaXplKCk7CiAgICBtX3BMQkJveC0+TW92ZShyY0xCQm94LCBUUlVFLCBGQUxTRSk7CiAgICBtX3BMQkJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjTEJCb3gpKTsKCiAgICBDUERGX1JlY3QgcmNSQkJveCA9IHJjQ2xpZW50OwogICAgcmNSQkJveC50b3AgPSByY1JCQm94LmJvdHRvbSArIDcuMGY7CiAgICByY1JCQm94LmxlZnQgPSByY1JCQm94LnJpZ2h0IC0gNy4wZjsKICAgIHJjUkJCb3guTm9ybWFsaXplKCk7CiAgICBtX3BSQkJveC0+TW92ZShyY1JCQm94LCBUUlVFLCBGQUxTRSk7CiAgICBtX3BSQkJveC0+U2V0VmlzaWJsZShDUFdMX1V0aWxzOjpDb250YWluc1JlY3QocmNDbGllbnQsIHJjUkJCb3gpKTsKCiAgICBDUERGX1JlY3QgcmNDb250ZW50cyA9IHJjQ2xpZW50OwogICAgcmNDb250ZW50cy50b3AgPSByY0F1dGhvci5ib3R0b20gLSBQT1BVUF9JVEVNX0hFQURfQk9UVE9NOwogICAgcmNDb250ZW50cy5sZWZ0ICs9IDMuMGY7CiAgICByY0NvbnRlbnRzLnJpZ2h0IC09IDMuMGY7CiAgICBpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKQogICAgICByY0NvbnRlbnRzLnJpZ2h0IC09IFBXTF9TQ1JPTExCQVJfV0lEVEg7CiAgICByY0NvbnRlbnRzLmJvdHRvbSArPSAxNC4wZjsKICAgIHJjQ29udGVudHMuTm9ybWFsaXplKCk7CiAgICBtX3BDb250ZW50cy0+TW92ZShyY0NvbnRlbnRzLCBGQUxTRSwgRkFMU0UpOwogICAgbV9wQ29udGVudHMtPlNldFZpc2libGUoQ1BXTF9VdGlsczo6Q29udGFpbnNSZWN0KHJjQ2xpZW50LCByY0NvbnRlbnRzKSk7CgogICAgQ1BERl9SZWN0IHJjQ29udGVudHNCYXIgPSByY0NvbnRlbnRzOwogICAgcmNDb250ZW50c0Jhci5yaWdodCA9IHJjQ2xpZW50LnJpZ2h0IC0gMy4wZjsKICAgIHJjQ29udGVudHNCYXIubGVmdCA9IHJjQ29udGVudHNCYXIucmlnaHQgLSBQV0xfU0NST0xMQkFSX1dJRFRIOwogICAgcmNDb250ZW50c0Jhci5Ob3JtYWxpemUoKTsKICAgIG1fcENvbnRlbnRzQmFyLT5Nb3ZlKHJjQ29udGVudHNCYXIsIFRSVUUsIEZBTFNFKTsKCiAgICBtX3JjQ2FwdGlvbiA9IHJjQ2xpZW50OwogICAgbV9yY0NhcHRpb24uYm90dG9tID0gcmNDb250ZW50cy50b3A7CiAgfQoKICBtX2JSZXNpemluZyA9IEZBTFNFOwp9CgovLyAwLW5vcm1hbCAvIDEtY2FwdGlvbiAvIDItbGVmdGJvdHRvbSBjb3JuZXIgLyAzLXJpZ2h0Ym90dG9tIGNvcm5lciAvIDQtY2xvc2UgLwovLyA1LW9wdGlvbnMKaW50MzJfdCBDUFdMX05vdGU6Ok5vdGVIaXRUZXN0KGNvbnN0IENQREZfUG9pbnQmIHBvaW50KSBjb25zdCB7CiAgQVNTRVJUKG1fcFN1YmplY3QgIT0gTlVMTCk7CiAgQVNTRVJUKG1fcERhdGVUaW1lICE9IE5VTEwpOwogIEFTU0VSVChtX3BDb250ZW50cyAhPSBOVUxMKTsKICBBU1NFUlQobV9wQXV0aG9yICE9IE5VTEwpOwogIEFTU0VSVChtX3BJY29uICE9IE5VTEwpOwogIEFTU0VSVChtX3BDb250ZW50c0JhciAhPSBOVUxMKTsKCiAgQVNTRVJUKG1fcENsb3NlQm94ICE9IE5VTEwpOwogIEFTU0VSVChtX3BMQkJveCAhPSBOVUxMKTsKICBBU1NFUlQobV9wUkJCb3ggIT0gTlVMTCk7CiAgQVNTRVJUKG1fcE9wdGlvbnMgIT0gTlVMTCk7CgogIEdldENsaWVudFJlY3QoKTsKCiAgaWYgKG1fcFN1YmplY3QtPlduZEhpdFRlc3QobV9wU3ViamVjdC0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDE7CiAgaWYgKG1fcERhdGVUaW1lLT5XbmRIaXRUZXN0KG1fcERhdGVUaW1lLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpCiAgICByZXR1cm4gMTsKICBpZiAobV9wQXV0aG9yLT5XbmRIaXRUZXN0KG1fcEF1dGhvci0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDE7CiAgaWYgKG1fcEljb24tPlduZEhpdFRlc3QobV9wSWNvbi0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDE7CgogIGlmIChtX3BDb250ZW50cy0+V25kSGl0VGVzdChtX3BDb250ZW50cy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDA7CiAgaWYgKG1fcENvbnRlbnRzQmFyLT5XbmRIaXRUZXN0KG1fcENvbnRlbnRzQmFyLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpCiAgICByZXR1cm4gMDsKCiAgaWYgKG1fcENsb3NlQm94LT5XbmRIaXRUZXN0KG1fcENsb3NlQm94LT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpCiAgICByZXR1cm4gNDsKICBpZiAobV9wTEJCb3gtPlduZEhpdFRlc3QobV9wTEJCb3gtPlBhcmVudFRvQ2hpbGQocG9pbnQpKSkKICAgIHJldHVybiAyOwogIGlmIChtX3BSQkJveC0+V25kSGl0VGVzdChtX3BSQkJveC0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDM7CiAgaWYgKG1fcE9wdGlvbnMtPlduZEhpdFRlc3QobV9wT3B0aW9ucy0+UGFyZW50VG9DaGlsZChwb2ludCkpKQogICAgcmV0dXJuIDU7CgogIHJldHVybiAxOwp9Cgp2b2lkIENQV0xfTm90ZTo6Q3JlYXRlQ2hpbGRXbmQoY29uc3QgUFdMX0NSRUFURVBBUkFNJiBjcCkgewogIENQV0xfTm90ZUl0ZW06OkNyZWF0ZUNoaWxkV25kKGNwKTsKCiAgQ1BXTF9Db2xvciBzVGV4dENvbG9yOwoKICBpZiAoQ1BXTF9VdGlsczo6SXNCbGFja09yV2hpdGUoR2V0QmFja2dyb3VuZENvbG9yKCkpKQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX1dISVRFQ09MT1I7CiAgZWxzZQogICAgc1RleHRDb2xvciA9IFBXTF9ERUZBVUxUX0JMQUNLQ09MT1I7CgogIG1fcEF1dGhvciA9IG5ldyBDUFdMX0xhYmVsOwogIFBXTF9DUkVBVEVQQVJBTSBhY3AgPSBjcDsKICBhY3AucFBhcmVudFduZCA9IHRoaXM7CiAgYWNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRCB8IFBFU19MRUZUIHwgUEVTX1RPUDsKICBhY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wQXV0aG9yLT5DcmVhdGUoYWNwKTsKCiAgbV9wQ2xvc2VCb3ggPSBuZXcgQ1BXTF9Ob3RlX0Nsb3NlQm94OwogIFBXTF9DUkVBVEVQQVJBTSBjY3AgPSBjcDsKICBjY3AucFBhcmVudFduZCA9IHRoaXM7CiAgY2NwLmR3Qm9yZGVyV2lkdGggPSAyOwogIGNjcC5uQm9yZGVyU3R5bGUgPSBQQlNfQkVWRUxFRDsKICBjY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEIHwgUFdTX0JPUkRFUjsKICBjY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wQ2xvc2VCb3gtPkNyZWF0ZShjY3ApOwoKICBtX3BJY29uID0gbmV3IENQV0xfTm90ZV9JY29uOwogIFBXTF9DUkVBVEVQQVJBTSBpY3AgPSBjcDsKICBpY3AucFBhcmVudFduZCA9IHRoaXM7CiAgaWNwLmR3RmxhZ3MgPSBQV1NfVklTSUJMRSB8IFBXU19DSElMRDsKICBtX3BJY29uLT5DcmVhdGUoaWNwKTsKCiAgbV9wT3B0aW9ucyA9IG5ldyBDUFdMX05vdGVfT3B0aW9uczsKICBQV0xfQ1JFQVRFUEFSQU0gb2NwID0gY3A7CiAgb2NwLnBQYXJlbnRXbmQgPSB0aGlzOwogIG9jcC5kd0ZsYWdzID0gUFdTX0NISUxEIHwgUFdTX1ZJU0lCTEU7CiAgb2NwLnNUZXh0Q29sb3IgPSBzVGV4dENvbG9yOwogIG1fcE9wdGlvbnMtPkNyZWF0ZShvY3ApOwoKICBtX3BMQkJveCA9IG5ldyBDUFdMX05vdGVfTEJCb3g7CiAgUFdMX0NSRUFURVBBUkFNIGxjcCA9IGNwOwogIGxjcC5wUGFyZW50V25kID0gdGhpczsKICBsY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOwogIGxjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfTkVTVzsKICBsY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wTEJCb3gtPkNyZWF0ZShsY3ApOwoKICBtX3BSQkJveCA9IG5ldyBDUFdMX05vdGVfUkJCb3g7CiAgUFdMX0NSRUFURVBBUkFNIHJjcCA9IGNwOwogIHJjcC5wUGFyZW50V25kID0gdGhpczsKICByY3AuZHdGbGFncyA9IFBXU19WSVNJQkxFIHwgUFdTX0NISUxEOwogIHJjcC5lQ3Vyc29yVHlwZSA9IEZYQ1RfTldTRTsKICByY3Auc1RleHRDb2xvciA9IHNUZXh0Q29sb3I7CiAgbV9wUkJCb3gtPkNyZWF0ZShyY3ApOwoKICBtX3BDb250ZW50c0JhciA9IG5ldyBDUFdMX1Njcm9sbEJhcihTQlRfVlNDUk9MTCk7CiAgUFdMX0NSRUFURVBBUkFNIHNjcCA9IGNwOwogIHNjcC5wUGFyZW50V25kID0gdGhpczsKICBzY3Auc0JhY2tncm91bmRDb2xvciA9CiAgICAgIENQV0xfQ29sb3IoQ09MT1JUWVBFX1JHQiwgMjQwIC8gMjU1LjBmLCAyNDAgLyAyNTUuMGYsIDI0MCAvIDI1NS4wZik7CiAgc2NwLmR3RmxhZ3MgPSBQV1NfQ0hJTEQgfCBQV1NfVklTSUJMRSB8IFBXU19CQUNLR1JPVU5EOwogIG1fcENvbnRlbnRzQmFyLT5DcmVhdGUoc2NwKTsKICBtX3BDb250ZW50c0Jhci0+U2V0Tm90aWZ5Rm9yZXZlcihUUlVFKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldFN1YmplY3ROYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkgewogIENQV0xfTm90ZUl0ZW06OlNldFN1YmplY3ROYW1lKHNOYW1lKTsKICBSZVBvc0NoaWxkV25kKCk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRBdXRob3JOYW1lKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzTmFtZSkgewogIGlmIChtX3BBdXRob3IpIHsKICAgIG1fcEF1dGhvci0+U2V0VGV4dChzTmFtZS5jX3N0cigpKTsKICAgIFJlUG9zQ2hpbGRXbmQoKTsKICB9CgogIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgIHBOb3RpZnktPk9uU2V0QXV0aG9yTmFtZSh0aGlzKTsKICB9Cn0KCkNGWF9XaWRlU3RyaW5nIENQV0xfTm90ZTo6R2V0QXV0aG9yTmFtZSgpIGNvbnN0IHsKICBpZiAobV9wQXV0aG9yKQogICAgcmV0dXJuIG1fcEF1dGhvci0+R2V0VGV4dCgpOwoKICByZXR1cm4gTCIiOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6T25Nb3VzZVdoZWVsKHNob3J0IHpEZWx0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDUERGX1BvaW50JiBwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGWF9EV09SRCBuRmxhZykgewogIENQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CiAgQ1BERl9SZWN0IHJjU2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbEFyZWEoKTsKICBDUERGX1JlY3QgcmNDb250ZW50cyA9IG1fcENvbnRlbnRzLT5HZXRDbGllbnRSZWN0KCk7CgogIGlmIChyY1Njcm9sbC50b3AgLSByY1Njcm9sbC5ib3R0b20gPiByY0NvbnRlbnRzLkhlaWdodCgpKSB7CiAgICBDUERGX1BvaW50IHB0TmV3ID0gcHRTY3JvbGw7CgogICAgaWYgKHpEZWx0YSA+IDApCiAgICAgIHB0TmV3LnkgKz0gMzA7CiAgICBlbHNlCiAgICAgIHB0TmV3LnkgLT0gMzA7CgogICAgaWYgKHB0TmV3LnkgPiByY1Njcm9sbC50b3ApCiAgICAgIHB0TmV3LnkgPSByY1Njcm9sbC50b3A7CiAgICBpZiAocHROZXcueSA8IHJjU2Nyb2xsLmJvdHRvbSArIHJjQ29udGVudHMuSGVpZ2h0KCkpCiAgICAgIHB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b20gKyByY0NvbnRlbnRzLkhlaWdodCgpOwogICAgaWYgKHB0TmV3LnkgPCByY1Njcm9sbC5ib3R0b20pCiAgICAgIHB0TmV3LnkgPSByY1Njcm9sbC5ib3R0b207CgogICAgaWYgKHB0TmV3LnkgIT0gcHRTY3JvbGwueSkgewogICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgICAgIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHROZXcueSk7CiAgICAgIG1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0VUU0NST0xMUE9TLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHROZXcueSk7CgogICAgICByZXR1cm4gVFJVRTsKICAgIH0KICB9CgogIHJldHVybiBGQUxTRTsKfQoKdm9pZCBDUFdMX05vdGU6Ok9uTm90aWZ5KENQV0xfV25kKiBwV25kLAogICAgICAgICAgICAgICAgICAgICAgICAgRlhfRFdPUkQgbXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50cHRyX3Qgd1BhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50cHRyX3QgbFBhcmFtKSB7CiAgc3dpdGNoIChtc2cpIHsKICAgIGNhc2UgUE5NX05PVEVFRElUQ0hBTkdFRDogewogICAgICBDUERGX1JlY3QgcmNTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsQXJlYSgpOwoKICAgICAgUFdMX1NDUk9MTF9JTkZPIHNJbmZvOwogICAgICBzSW5mby5mQ29udGVudE1pbiA9IHJjU2Nyb2xsLmJvdHRvbTsKICAgICAgc0luZm8uZkNvbnRlbnRNYXggPSByY1Njcm9sbC50b3A7CiAgICAgIHNJbmZvLmZQbGF0ZVdpZHRoID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKS5IZWlnaHQoKTsKICAgICAgc0luZm8uZlNtYWxsU3RlcCA9IDEzLjBmOwogICAgICBzSW5mby5mQmlnU3RlcCA9IHNJbmZvLmZQbGF0ZVdpZHRoOwoKICAgICAgaWYgKEZYU1lTX21lbWNtcCgmbV9PbGRTY3JvbGxJbmZvLCAmc0luZm8sIHNpemVvZihQV0xfU0NST0xMX0lORk8pKSAhPQogICAgICAgICAgMCkgewogICAgICAgIEZYX0JPT0wgYlNjcm9sbENoYW5nZWQgPSBGQUxTRTsKCiAgICAgICAgaWYgKGxQYXJhbSA8IDMpICAvL7fA1rnLwNGtu7cgbWFudGlzOjE1NzU5CiAgICAgICAgewogICAgICAgICAgYlNjcm9sbENoYW5nZWQgPSBSZXNldFNjcm9sbEJhcigpOwogICAgICAgICAgaWYgKGJTY3JvbGxDaGFuZ2VkKSB7CiAgICAgICAgICAgIGxQYXJhbSsrOwogICAgICAgICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX05PVEVSRVNFVCwgMCwgMCk7CiAgICAgICAgICAgIE9uTm90aWZ5KHRoaXMsIFBOTV9OT1RFRURJVENIQU5HRUQsIDAsIGxQYXJhbSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJTY3JvbGxDaGFuZ2VkKSB7CiAgICAgICAgICBpZiAobV9wQ29udGVudHNCYXItPklzVmlzaWJsZSgpKSB7CiAgICAgICAgICAgIG1fcENvbnRlbnRzQmFyLT5Pbk5vdGlmeShwV25kLCBQTk1fU0VUU0NST0xMSU5GTywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50cHRyX3QpJnNJbmZvKTsKICAgICAgICAgICAgbV9PbGRTY3JvbGxJbmZvID0gc0luZm87CgogICAgICAgICAgICBDUERGX1BvaW50IHB0U2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOwogICAgICAgICAgICBDUERGX1BvaW50IHB0T2xkID0gcHRTY3JvbGw7CgogICAgICAgICAgICBpZiAocHRTY3JvbGwueSA+IHNJbmZvLmZDb250ZW50TWF4KQogICAgICAgICAgICAgIHB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1heDsKICAgICAgICAgICAgaWYgKHB0U2Nyb2xsLnkgPCBzSW5mby5mQ29udGVudE1pbiArIHNJbmZvLmZQbGF0ZVdpZHRoKQogICAgICAgICAgICAgIHB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbiArIHNJbmZvLmZQbGF0ZVdpZHRoOwogICAgICAgICAgICBpZiAocHRTY3JvbGwueSA8IHNJbmZvLmZDb250ZW50TWluKQogICAgICAgICAgICAgIHB0U2Nyb2xsLnkgPSBzSW5mby5mQ29udGVudE1pbjsKCiAgICAgICAgICAgIGlmIChwdE9sZC55ICE9IHB0U2Nyb2xsLnkpIHsKICAgICAgICAgICAgICBtX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHRTY3JvbGwueSk7CiAgICAgICAgICAgICAgbV9wQ29udGVudHNCYXItPkludmFsaWRhdGVSZWN0KE5VTEwpOwogICAgICAgICAgICAgIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludHB0cl90KSZwdFNjcm9sbC55KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgICAgbV9wQ29udGVudHMtPkludmFsaWRhdGVSZWN0KE5VTEwpOwoKICAgICAgcmV0dXJuOwogICAgY2FzZSBQTk1fU0NST0xMV0lORE9XOgogICAgICBpZiAobV9wQ29udGVudHMpCiAgICAgICAgbV9wQ29udGVudHMtPk9uTm90aWZ5KHBXbmQsIG1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgICByZXR1cm47CiAgICBjYXNlIFBOTV9TRVRTQ1JPTExQT1M6CiAgICAgIGlmIChtX3BDb250ZW50c0JhcikKICAgICAgICBtX3BDb250ZW50c0Jhci0+T25Ob3RpZnkocFduZCwgUE5NX1NFVFNDUk9MTFBPUywgd1BhcmFtLCBsUGFyYW0pOwogICAgICByZXR1cm47CiAgfQoKICBpZiAobXNnID09IFBOTV9TRVRDQVJFVElORk8gJiYgSXNWYWxpZCgpKSB7CiAgICBpZiAoUFdMX0NBUkVUX0lORk8qIHBJbmZvID0gKFBXTF9DQVJFVF9JTkZPKil3UGFyYW0pIHsKICAgICAgaWYgKG1fcENvbnRlbnRzKSB7CiAgICAgICAgQ1BERl9SZWN0IHJjQ2xpZW50ID0gbV9wQ29udGVudHMtPkdldENsaWVudFJlY3QoKTsKICAgICAgICBpZiAocEluZm8tPnB0SGVhZC55ID4gcmNDbGllbnQudG9wKSB7CiAgICAgICAgICBDUERGX1BvaW50IHB0ID0gbV9wQ29udGVudHMtPk91dFRvSW4ocEluZm8tPnB0SGVhZCk7CiAgICAgICAgICBtX3BDb250ZW50cy0+T25Ob3RpZnkodGhpcywgUE5NX1NDUk9MTFdJTkRPVywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludHB0cl90KSZwdC55KTsKCiAgICAgICAgICBDUERGX1BvaW50IHB0U2Nyb2xsID0gbV9wQ29udGVudHMtPkdldFNjcm9sbFBvcygpOwogICAgICAgICAgbV9wQ29udGVudHNCYXItPk9uTm90aWZ5KHRoaXMsIFBOTV9TRVRTQ1JPTExQT1MsIFNCVF9WU0NST0xMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnRwdHJfdCkmcHRTY3JvbGwueSk7CgogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKHBJbmZvLT5wdEZvb3QueSA8IHJjQ2xpZW50LmJvdHRvbSkgewogICAgICAgICAgQ1BERl9Qb2ludCBwdCA9IG1fcENvbnRlbnRzLT5PdXRUb0luKHBJbmZvLT5wdEZvb3QpOwogICAgICAgICAgcHQueSArPSByY0NsaWVudC5IZWlnaHQoKTsKICAgICAgICAgIG1fcENvbnRlbnRzLT5Pbk5vdGlmeSh0aGlzLCBQTk1fU0NST0xMV0lORE9XLCBTQlRfVlNDUk9MTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50cHRyX3QpJnB0LnkpOwoKICAgICAgICAgIENQREZfUG9pbnQgcHRTY3JvbGwgPSBtX3BDb250ZW50cy0+R2V0U2Nyb2xsUG9zKCk7CiAgICAgICAgICBtX3BDb250ZW50c0Jhci0+T25Ob3RpZnkodGhpcywgUE5NX1NFVFNDUk9MTFBPUywgU0JUX1ZTQ1JPTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludHB0cl90KSZwdFNjcm9sbC55KTsKCiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICBDUFdMX05vdGVJdGVtOjpPbk5vdGlmeShwV25kLCBtc2csIHdQYXJhbSwgbFBhcmFtKTsKfQoKdm9pZCBDUFdMX05vdGU6OlNldEJrQ29sb3IoY29uc3QgQ1BXTF9Db2xvciYgY29sb3IpIHsKICBDUFdMX05vdGVJdGVtOjpTZXRCa0NvbG9yKGNvbG9yKTsKCiAgQ1BXTF9Db2xvciBzQksgPSBjb2xvcjsKICBDUFdMX0NvbG9yIHNUZXh0Q29sb3I7CiAgaWYgKENQV0xfVXRpbHM6OklzQmxhY2tPcldoaXRlKHNCSykpCiAgICBzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfV0hJVEVDT0xPUjsKICBlbHNlCiAgICBzVGV4dENvbG9yID0gUFdMX0RFRkFVTFRfQkxBQ0tDT0xPUjsKCiAgaWYgKG1fcENsb3NlQm94KQogICAgbV9wQ2xvc2VCb3gtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKICBpZiAobV9wQXV0aG9yKQogICAgbV9wQXV0aG9yLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CiAgaWYgKG1fcE9wdGlvbnMpCiAgICBtX3BPcHRpb25zLT5TZXRUZXh0Q29sb3Ioc1RleHRDb2xvcik7CiAgaWYgKG1fcExCQm94KQogICAgbV9wTEJCb3gtPlNldFRleHRDb2xvcihzVGV4dENvbG9yKTsKICBpZiAobV9wUkJCb3gpCiAgICBtX3BSQkJveC0+U2V0VGV4dENvbG9yKHNUZXh0Q29sb3IpOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6T25MQnV0dG9uRG93bihjb25zdCBDUERGX1BvaW50JiBwb2ludCwgRlhfRFdPUkQgbkZsYWcpIHsKICBpZiAobV9wT3B0aW9ucy0+V25kSGl0VGVzdChtX3BPcHRpb25zLT5QYXJlbnRUb0NoaWxkKHBvaW50KSkpIHsKICAgIGlmIChJUFdMX05vdGVOb3RpZnkqIHBOb3RpZnkgPSBHZXROb3RlTm90aWZ5KCkpIHsKICAgICAgaW50MzJfdCB4LCB5OwogICAgICBQV0x0b1duZChwb2ludCwgeCwgeSk7CiAgICAgIGlmIChJRlhfU3lzdGVtSGFuZGxlciogcFNIID0gR2V0U3lzdGVtSGFuZGxlcigpKQogICAgICAgIHBTSC0+Q2xpZW50VG9TY3JlZW4oR2V0QXR0YWNoZWRIV25kKCksIHgsIHkpOwogICAgICBLaWxsRm9jdXMoKTsKICAgICAgcE5vdGlmeS0+T25Qb3B1cE1lbnUoeCwgeSk7CgogICAgICByZXR1cm4gVFJVRTsKICAgIH0KICB9CgogIHJldHVybiBDUFdMX1duZDo6T25MQnV0dG9uRG93bihwb2ludCwgbkZsYWcpOwp9CgpGWF9CT09MIENQV0xfTm90ZTo6T25SQnV0dG9uVXAoY29uc3QgQ1BERl9Qb2ludCYgcG9pbnQsIEZYX0RXT1JEIG5GbGFnKSB7CiAgcmV0dXJuIENQV0xfV25kOjpPblJCdXR0b25VcChwb2ludCwgbkZsYWcpOwp9Cgpjb25zdCBDUFdMX05vdGUqIENQV0xfTm90ZTo6R2V0Tm90ZSgpIGNvbnN0IHsKICByZXR1cm4gdGhpczsKfQoKSVBXTF9Ob3RlTm90aWZ5KiBDUFdMX05vdGU6OkdldE5vdGVOb3RpZnkoKSBjb25zdCB7CiAgaWYgKG1fYkVuYWxibGVOb3RpZnkpCiAgICByZXR1cm4gbV9wTm90ZU5vdGlmeTsKCiAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpTZXRJY29uVHlwZShpbnQzMl90IG5UeXBlKSB7CiAgaWYgKG1fcEljb24pCiAgICBtX3BJY29uLT5TZXRJY29uVHlwZShuVHlwZSk7Cn0KCnZvaWQgQ1BXTF9Ob3RlOjpFbmFibGVNb2RpZnkoRlhfQk9PTCBiRW5hYmxlZCkgewogIG1fcENvbnRlbnRzLT5FbmFibGVNb2RpZnkoYkVuYWJsZWQpOwp9Cgp2b2lkIENQV0xfTm90ZTo6RW5hYmxlUmVhZChGWF9CT09MIGJFbmFibGVkKSB7CiAgbV9wQ29udGVudHMtPkVuYWJsZVJlYWQoYkVuYWJsZWQpOwp9CgpDRlhfV2lkZVN0cmluZyBDUFdMX05vdGU6OkdldFJlcGx5U3RyaW5nKCkgY29uc3QgewogIHJldHVybiBtX3NSZXBseVN0cmluZzsKfQoKdm9pZCBDUFdMX05vdGU6OlNldFJlcGx5U3RyaW5nKGNvbnN0IENGWF9XaWRlU3RyaW5nJiBzdHJpbmcpIHsKICBtX3NSZXBseVN0cmluZyA9IHN0cmluZzsKfQo=