Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIFNpbW9uIFF1ZSAKLy8gIEplc3NlIEJhcmtlcgovLwojaW5jbHVkZSAiY2FudmFzLWRybS5oIgojaW5jbHVkZSAibG9nLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJ1dGlsLmgiCgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHBvbGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx0aW1lLmg+CgojaW5jbHVkZSA8ZnN0cmVhbT4KI2luY2x1ZGUgPHNzdHJlYW0+CiNpbmNsdWRlIDxsaXN0PgoKLyoqKioqKioqKioqKioqKioqKgogKiBQdWJsaWMgbWV0aG9kcyAqCiAqKioqKioqKioqKioqKioqKiovCgpib29sCkNhbnZhc0RSTTo6cmVzZXQoKQp7CiAgICBpZiAoIXJlc2V0X2NvbnRleHQoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgaWYgKCFtYWtlX2N1cnJlbnQoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgaWYgKCFzdXBwb3J0c19nbDIoKSkgewogICAgICAgIExvZzo6ZXJyb3IoIkdsbWFyazIgbmVlZHMgT3BlbkdMKEVTKSB2ZXJzaW9uID49IDIuMCB0byBydW4iCiAgICAgICAgICAgICAgICAgICAiIChidXQgdmVyc2lvbiBzdHJpbmcgaXM6ICclcycpIVxuIiwKICAgICAgICAgICAgICAgICAgIGdsR2V0U3RyaW5nKEdMX1ZFUlNJT04pKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgZ2xWaWV3cG9ydCgwLCAwLCB3aWR0aF8sIGhlaWdodF8pOwogICAgZ2xFbmFibGUoR0xfREVQVEhfVEVTVCk7CiAgICBnbERlcHRoRnVuYyhHTF9MRVFVQUwpOwogICAgZ2xFbmFibGUoR0xfQ1VMTF9GQUNFKTsKICAgIGdsQ3VsbEZhY2UoR0xfQkFDSyk7CgogICAgY2xlYXIoKTsKICAgIGVnbF8uc3dhcCgpOwoKICAgIGlmICghZHJtXy5yZXNldCgpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9Cgp2b2lkCkRSTVN0YXRlOjpmYl9kZXN0cm95X2NhbGxiYWNrKGdibV9ibyogYm8sIHZvaWQqIGRhdGEpCnsKICAgIERSTUZCU3RhdGUqIGZiID0gcmVpbnRlcnByZXRfY2FzdDxEUk1GQlN0YXRlKj4oZGF0YSk7CiAgICBpZiAoZmIgJiYgZmItPmZiX2lkKSB7CiAgICAgICAgZHJtTW9kZVJtRkIoZmItPmZkLCBmYi0+ZmJfaWQpOwogICAgfQogICAgZGVsZXRlIGZiOwogICAgZ2JtX2RldmljZSogZGV2ID0gZ2JtX2JvX2dldF9kZXZpY2UoYm8pOwogICAgTG9nOjpkZWJ1ZygiR290IEdCTSBkZXZpY2UgaGFuZGxlICVwIGZyb20gYnVmZmVyIG9iamVjdFxuIiwgZGV2KTsKfQoKRFJNRkJTdGF0ZSoKRFJNU3RhdGU6OmZiX2dldF9mcm9tX2JvKGdibV9ibyogYm8pCnsKICAgIERSTUZCU3RhdGUqIGZiID0gcmVpbnRlcnByZXRfY2FzdDxEUk1GQlN0YXRlKj4oZ2JtX2JvX2dldF91c2VyX2RhdGEoYm8pKTsKICAgIGlmIChmYikgewogICAgICAgIHJldHVybiBmYjsKICAgIH0KCiAgICB1bnNpZ25lZCBpbnQgd2lkdGggPSBnYm1fYm9fZ2V0X3dpZHRoKGJvKTsKICAgIHVuc2lnbmVkIGludCBoZWlnaHQgPSBnYm1fYm9fZ2V0X2hlaWdodChibyk7CiAgICB1bnNpZ25lZCBpbnQgc3RyaWRlID0gZ2JtX2JvX2dldF9zdHJpZGUoYm8pOwogICAgdW5zaWduZWQgaW50IGhhbmRsZSA9IGdibV9ib19nZXRfaGFuZGxlKGJvKS51MzI7CiAgICB1bnNpZ25lZCBpbnQgZmJfaWQoMCk7CiAgICBpbnQgc3RhdHVzID0gZHJtTW9kZUFkZEZCKGZkXywgd2lkdGgsIGhlaWdodCwgMjQsIDMyLCBzdHJpZGUsIGhhbmRsZSwgJmZiX2lkKTsKICAgIGlmIChzdGF0dXMgPCAwKSB7CiAgICAgICAgTG9nOjplcnJvcigiRmFpbGVkIHRvIGNyZWF0ZSBGQjogJWRcbiIsIHN0YXR1cyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgZmIgPSBuZXcgRFJNRkJTdGF0ZSgpOwogICAgZmItPmZkID0gZmRfOwogICAgZmItPmJvID0gYm87CiAgICBmYi0+ZmJfaWQgPSBmYl9pZDsKCiAgICBnYm1fYm9fc2V0X3VzZXJfZGF0YShibywgZmIsIGZiX2Rlc3Ryb3lfY2FsbGJhY2spOwogICAgcmV0dXJuIGZiOwp9Cgpib29sCkRSTVN0YXRlOjppbml0X2dibSgpCnsKICAgIGRldl8gPSBnYm1fY3JlYXRlX2RldmljZShmZF8pOwogICAgaWYgKCFkZXZfKSB7CiAgICAgICAgTG9nOjplcnJvcigiRmFpbGVkIHRvIGNyZWF0ZSBHQk0gZGV2aWNlXG4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgc3VyZmFjZV8gPSBnYm1fc3VyZmFjZV9jcmVhdGUoZGV2XywgbW9kZV8tPmhkaXNwbGF5LCBtb2RlXy0+dmRpc3BsYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHQk1fRk9STUFUX1hSR0I4ODg4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0JNX0JPX1VTRV9TQ0FOT1VUIHwgR0JNX0JPX1VTRV9SRU5ERVJJTkcpOwogICAgaWYgKCFzdXJmYWNlXykgewogICAgICAgIExvZzo6ZXJyb3IoIkZhaWxlZCB0byBjcmVhdGUgR0JNIHN1cmZhY2VcbiIpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICByZXR1cm4gdHJ1ZTsKfQoKYm9vbApEUk1TdGF0ZTo6aW5pdCgpCnsKICAgIC8vIFRPRE86IFJlcGxhY2UgdGhpcyB3aXRoIHNvbWV0aGluZyB0aGF0IGV4cGxpY2l0bHkgcHJvYmVzIGZvciB0aGUgbG9hZGVkCiAgICAvLyBkcml2ZXIgKHVkZXY/KS4KICAgIHN0YXRpYyBjb25zdCBjaGFyKiBkcm1fbW9kdWxlc1tdID0gewogICAgICAgICJpOTE1IiwKICAgICAgICAibm91dmVhdSIsCiAgICAgICAgInJhZGVvbiIsCiAgICAgICAgInZtZ2Z4IiwKICAgICAgICAib21hcGRybSIsCiAgICAgICAgImV4eW5vcyIKICAgIH07CgogICAgdW5zaWduZWQgaW50IG51bV9tb2R1bGVzKHNpemVvZihkcm1fbW9kdWxlcykvc2l6ZW9mKGRybV9tb2R1bGVzWzBdKSk7CiAgICBmb3IgKHVuc2lnbmVkIGludCBtID0gMDsgbSA8IG51bV9tb2R1bGVzOyBtKyspIHsKICAgICAgICBmZF8gPSBkcm1PcGVuKGRybV9tb2R1bGVzW21dLCAwKTsKICAgICAgICBpZiAoZmRfIDwgMCkgewogICAgICAgICAgICBMb2c6OmRlYnVnKCJGYWlsZWQgdG8gb3BlbiBEUk0gbW9kdWxlICclcydcbiIsIGRybV9tb2R1bGVzW21dKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIExvZzo6ZGVidWcoIk9wZW5lZCBEUk0gbW9kdWxlICclcydcbiIsIGRybV9tb2R1bGVzW21dKTsKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoZmRfIDwgMCkgewogICAgICAgIExvZzo6ZXJyb3IoIkZhaWxlZCB0byBmaW5kIGEgc3VpdGFibGUgRFJNIGRldmljZVxuIik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJlc291cmNlc18gPSBkcm1Nb2RlR2V0UmVzb3VyY2VzKGZkXyk7CiAgICBpZiAoIXJlc291cmNlc18pIHsKICAgICAgICBMb2c6OmVycm9yKCJkcm1Nb2RlR2V0UmVzb3VyY2VzIGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vIEZpbmQgYSBjb25uZWN0ZWQgY29ubmVjdG9yCiAgICBmb3IgKGludCBjID0gMDsgYyA8IHJlc291cmNlc18tPmNvdW50X2Nvbm5lY3RvcnM7IGMrKykgewogICAgICAgIGNvbm5lY3Rvcl8gPSBkcm1Nb2RlR2V0Q29ubmVjdG9yKGZkXywgcmVzb3VyY2VzXy0+Y29ubmVjdG9yc1tjXSk7CiAgICAgICAgaWYgKERSTV9NT0RFX0NPTk5FQ1RFRCA9PSBjb25uZWN0b3JfLT5jb25uZWN0aW9uKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkcm1Nb2RlRnJlZUNvbm5lY3Rvcihjb25uZWN0b3JfKTsKICAgICAgICBjb25uZWN0b3JfID0gMDsKICAgIH0KCiAgICBpZiAoIWNvbm5lY3Rvcl8pIHsKICAgICAgICBMb2c6OmVycm9yKCJGYWlsZWQgdG8gZmluZCBhIHN1aXRhYmxlIGNvbm5lY3RvclxuIik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vIEZpbmQgdGhlIGJlc3QgcmVzb2x1dGlvbiAod2Ugd2lsbCBhbHdheXMgb3BlcmF0ZSBmdWxsLXNjcmVlbikuCiAgICB1bnNpZ25lZCBpbnQgYmVzdEFyZWEoMCk7CiAgICBmb3IgKGludCBtID0gMDsgbSA8IGNvbm5lY3Rvcl8tPmNvdW50X21vZGVzOyBtKyspIHsKICAgICAgICBkcm1Nb2RlTW9kZUluZm8qIGN1ck1vZGUgPSAmY29ubmVjdG9yXy0+bW9kZXNbbV07CiAgICAgICAgdW5zaWduZWQgaW50IGN1ckFyZWEgPSBjdXJNb2RlLT5oZGlzcGxheSAqIGN1ck1vZGUtPnZkaXNwbGF5OwogICAgICAgIGlmIChjdXJBcmVhID4gYmVzdEFyZWEpIHsKICAgICAgICAgICAgbW9kZV8gPSBjdXJNb2RlOwogICAgICAgICAgICBiZXN0QXJlYSA9IGN1ckFyZWE7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghbW9kZV8pIHsKICAgICAgICBMb2c6OmVycm9yKCJGYWlsZWQgdG8gZmluZCBhIHN1aXRhYmxlIG1vZGVcbiIpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvLyBGaW5kIGEgc3VpdGFibGUgZW5jb2RlcgogICAgZm9yIChpbnQgZSA9IDA7IGUgPCByZXNvdXJjZXNfLT5jb3VudF9lbmNvZGVyczsgZSsrKSB7CiAgICAgICAgZW5jb2Rlcl8gPSBkcm1Nb2RlR2V0RW5jb2RlcihmZF8sIHJlc291cmNlc18tPmVuY29kZXJzW2VdKTsKICAgICAgICBpZiAoZW5jb2Rlcl8gJiYgZW5jb2Rlcl8tPmVuY29kZXJfaWQgPT0gY29ubmVjdG9yXy0+ZW5jb2Rlcl9pZCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZHJtTW9kZUZyZWVFbmNvZGVyKGVuY29kZXJfKTsKICAgICAgICBlbmNvZGVyXyA9IDA7CiAgICB9CgogICAgaWYgKCFlbmNvZGVyXykgewogICAgICAgIExvZzo6ZXJyb3IoIkZhaWxlZCB0byBmaW5kIGEgc3VpdGFibGUgZW5jb2RlclxuIik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGlmICghaW5pdF9nYm0oKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBjcnRjXyA9IGRybU1vZGVHZXRDcnRjKGZkXywgZW5jb2Rlcl8tPmNydGNfaWQpOwogICAgaWYgKCFjcnRjXykgewogICAgICAgIExvZzo6ZXJyb3IoIkZhaWxlZCB0byBnZXQgY3VycmVudCBDUlRDXG4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgc2lnbmFsKFNJR0lOVCwgJkRSTVN0YXRlOjpxdWl0X2hhbmRsZXIpOwoKICAgIHJldHVybiB0cnVlOwp9Cgpib29sCkRSTVN0YXRlOjpyZXNldCgpCnsKICAgIGlmIChib18pIHsKICAgICAgICBnYm1fc3VyZmFjZV9yZWxlYXNlX2J1ZmZlcihzdXJmYWNlXywgYm9fKTsKICAgIH0KCiAgICBib18gPSBnYm1fc3VyZmFjZV9sb2NrX2Zyb250X2J1ZmZlcihzdXJmYWNlXyk7CiAgICBmYl8gPSBmYl9nZXRfZnJvbV9ibyhib18pOwoKICAgIGludCBzdGF0dXMgPSBkcm1Nb2RlU2V0Q3J0YyhmZF8sIGVuY29kZXJfLT5jcnRjX2lkLCBmYl8tPmZiX2lkLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjb25uZWN0b3JfLT5jb25uZWN0b3JfaWQsIDEsIG1vZGVfKTsKICAgIGlmIChzdGF0dXMgPCAwKSB7CiAgICAgICAgTG9nOjplcnJvcigiRmFpbGVkIHRvIHNldCBDUlRDOiAlZFxuIiwgc3RhdHVzKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcmV0dXJuIHRydWU7Cn0KCgpib29sIERSTVN0YXRlOjpzaG91bGRfcXVpdF8gPSBmYWxzZTsKCnZvaWQKRFJNU3RhdGU6OnF1aXRfaGFuZGxlcihpbnQgc2lnbm8pCnsKICAgIExvZzo6ZGVidWcoIkdvdCBTSUdJTlQgKCVkKS5cbiIsIHNpZ25vKTsKICAgIHNob3VsZF9xdWl0XyA9IHRydWU7Cn0Kdm9pZApEUk1TdGF0ZTo6cGFnZV9mbGlwX2hhbmRsZXIoaW50IGZkLCB1bnNpZ25lZCBpbnQgZnJhbWUsIHVuc2lnbmVkIGludCBzZWMsIHVuc2lnbmVkIGludCB1c2VjLCB2b2lkKiBkYXRhKQp7CiAgICB1bnNpZ25lZCBpbnQqIHdhaXRpbmcgPSByZWludGVycHJldF9jYXN0PHVuc2lnbmVkIGludCo+KGRhdGEpOwogICAgKndhaXRpbmcgPSAwOwogICAgLy8gRGVhbCB3aXRoIHVudXNlZCBwYXJhbWV0ZXJzCiAgICBzdGF0aWNfY2FzdDx2b2lkPihmZCk7CiAgICBzdGF0aWNfY2FzdDx2b2lkPihmcmFtZSk7CiAgICBzdGF0aWNfY2FzdDx2b2lkPihzZWMpOwogICAgc3RhdGljX2Nhc3Q8dm9pZD4odXNlYyk7Cn0KCnZvaWQKRFJNU3RhdGU6OmRvX2ZsaXAoKQp7CiAgICBnYm1fYm8qIG5leHQgPSBnYm1fc3VyZmFjZV9sb2NrX2Zyb250X2J1ZmZlcihzdXJmYWNlXyk7CiAgICBmYl8gPSBmYl9nZXRfZnJvbV9ibyhuZXh0KTsKICAgIHVuc2lnbmVkIGludCB3YWl0aW5nKDEpOwogICAgaW50IHN0YXR1cyA9IGRybU1vZGVQYWdlRmxpcChmZF8sIGVuY29kZXJfLT5jcnRjX2lkLCBmYl8tPmZiX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEUk1fTU9ERV9QQUdFX0ZMSVBfRVZFTlQsICZ3YWl0aW5nKTsKICAgIGlmIChzdGF0dXMgPCAwKSB7CiAgICAgICAgTG9nOjplcnJvcigiRmFpbGVkIHRvIGVucXVldWUgcGFnZSBmbGlwOiAlZFxuIiwgc3RhdHVzKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZmRfc2V0IGZkczsKICAgIEZEX1pFUk8oJmZkcyk7CiAgICBGRF9TRVQoZmRfLCAmZmRzKTsKICAgIGRybUV2ZW50Q29udGV4dCBldkN0eDsKICAgIGV2Q3R4LnZlcnNpb24gPSBEUk1fRVZFTlRfQ09OVEVYVF9WRVJTSU9OOwogICAgZXZDdHgucGFnZV9mbGlwX2hhbmRsZXIgPSBwYWdlX2ZsaXBfaGFuZGxlcjsKCiAgICB3aGlsZSAod2FpdGluZykgewogICAgICAgIHN0YXR1cyA9IHNlbGVjdChmZF8gKyAxLCAmZmRzLCAwLCAwLCAwKTsKICAgICAgICBpZiAoc3RhdHVzIDwgMCkgewogICAgICAgICAgICAvLyBNb3N0IG9mIHRoZSB0aW1lLCBzZWxlY3QoKSB3aWxsIHJldHVybiBhbiBlcnJvciBiZWNhdXNlIHRoZQogICAgICAgICAgICAvLyB1c2VyIHByZXNzZWQgQ3RybC1DLiAgU28sIG9ubHkgcHJpbnQgb3V0IGEgbWVzc2FnZSBpbiBkZWJ1ZwogICAgICAgICAgICAvLyBtb2RlLCBhbmQganVzdCBjaGVjayBmb3IgdGhlIGxpa2VseSBjb25kaXRpb24gYW5kIHJlbGVhc2UKICAgICAgICAgICAgLy8gdGhlIGN1cnJlbnQgYnVmZmVyIG9iamVjdCBiZWZvcmUgZ2V0dGluZyBvdXQuCiAgICAgICAgICAgIExvZzo6ZGVidWcoIkVycm9yIGluIHNlbGVjdFxuIik7CiAgICAgICAgICAgIGlmIChzaG91bGRfcXVpdCgpKSB7CiAgICAgICAgICAgICAgICBnYm1fc3VyZmFjZV9yZWxlYXNlX2J1ZmZlcihzdXJmYWNlXywgYm9fKTsKICAgICAgICAgICAgICAgIGJvXyA9IG5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBkcm1IYW5kbGVFdmVudChmZF8sICZldkN0eCk7CiAgICB9CgogICAgZ2JtX3N1cmZhY2VfcmVsZWFzZV9idWZmZXIoc3VyZmFjZV8sIGJvXyk7CiAgICBib18gPSBuZXh0Owp9Cgp2b2lkCkRSTVN0YXRlOjpjbGVhbnVwKCkKewogICAgLy8gUmVzdG9yZSBDUlRDIHN0YXRlIGlmIG5lY2Vzc2FyeQogICAgaWYgKGNydGNfKSB7CiAgICAgICAgaW50IHN0YXR1cyA9IGRybU1vZGVTZXRDcnRjKGZkXywgY3J0Y18tPmNydGNfaWQsIGNydGNfLT5idWZmZXJfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNydGNfLT54LCBjcnRjXy0+eSwgJmNvbm5lY3Rvcl8tPmNvbm5lY3Rvcl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgJmNydGNfLT5tb2RlKTsKICAgICAgICBpZiAoc3RhdHVzIDwgMCkgewogICAgICAgICAgICBMb2c6OmVycm9yKCJGYWlsZWQgdG8gcmVzdG9yZSBvcmlnaW5hbCBDUlRDOiAlZFxuIiwgc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgZHJtTW9kZUZyZWVDcnRjKGNydGNfKTsKICAgICAgICBjcnRjXyA9IDA7CiAgICB9CiAgICBpZiAoc3VyZmFjZV8pIHsKICAgICAgICBnYm1fc3VyZmFjZV9kZXN0cm95KHN1cmZhY2VfKTsKICAgICAgICBzdXJmYWNlXyA9IDA7CiAgICB9CiAgICBpZiAoZGV2XykgewogICAgICAgIGdibV9kZXZpY2VfZGVzdHJveShkZXZfKTsKICAgICAgICBkZXZfID0gMDsKICAgIH0KICAgIGlmIChjb25uZWN0b3JfKSB7CiAgICAgICAgZHJtTW9kZUZyZWVDb25uZWN0b3IoY29ubmVjdG9yXyk7CiAgICAgICAgY29ubmVjdG9yXyA9IDA7CiAgICB9CiAgICBpZiAoZW5jb2Rlcl8pIHsKICAgICAgICBkcm1Nb2RlRnJlZUVuY29kZXIoZW5jb2Rlcl8pOwogICAgICAgIGVuY29kZXJfID0gMDsKICAgIH0KICAgIGlmIChyZXNvdXJjZXNfKSB7CiAgICAgICAgZHJtTW9kZUZyZWVSZXNvdXJjZXMocmVzb3VyY2VzXyk7CiAgICAgICAgcmVzb3VyY2VzXyA9IDA7CiAgICB9CiAgICBpZiAoZmRfID4gMCkgewogICAgICAgIGRybUNsb3NlKGZkXyk7CiAgICB9CiAgICBmZF8gPSAwOwogICAgbW9kZV8gPSAwOwp9Cgpib29sCkNhbnZhc0RSTTo6aW5pdCgpCnsKICAgIExvZzo6aW5mbygiTk9URTogVGhlIERSTSBjYW52YXMgaXMgc3RpbGwgZXhwZXJpbWVudGFsIGFuZCBpdHMgYmVoYXZpb3JcbiIpOwogICAgTG9nOjppbmZvKCIgICAgICBpcyBzdWJqZWN0IHRvIGNoYW5nZSBhcyBHQk0gYW5kIG1vZGVzZXR0aW5nIGJlaGF2aW9yXG4iKTsKICAgIExvZzo6aW5mbygiICAgICAgZXZvbHZlc1xuIik7CgogICAgaWYgKCFkcm1fLmluaXQoKSkgewogICAgICAgIExvZzo6ZXJyb3IoIkZhaWxlZCB0byBpbml0aWFsaXplIHRoZSBEUk0gY2FudmFzXG4iKTsKICAgICAgICBkcm1fLmNsZWFudXAoKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgd2lkdGhfID0gZHJtXy5tb2RlX3dpZHRoKCk7CiAgICBoZWlnaHRfID0gZHJtXy5tb2RlX2hlaWdodCgpOwogICAgcmVzaXplX25vX3ZpZXdwb3J0KHdpZHRoXywgaGVpZ2h0Xyk7CgogICAgaWYgKCFlZ2xfLmluaXRfZGlzcGxheShkcm1fLmRldmljZSgpLCB2aXN1YWxfY29uZmlnXykpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoIWVnbF8uaW5pdF9zdXJmYWNlKGRybV8uc3VyZmFjZSgpKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmICghZWdsXy52YWxpZCgpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJldHVybiByZXNldCgpOwp9CgoKQ2FudmFzRFJNOjp+Q2FudmFzRFJNKCkKewogICAgZHJtXy5jbGVhbnVwKCk7Cn0KCnZvaWQKQ2FudmFzRFJNOjp2aXNpYmxlKGJvb2wgLyogdmlzaWJsZSAqLykKewp9Cgp2b2lkCkNhbnZhc0RSTTo6Y2xlYXIoKQp7CiAgICBnbENsZWFyQ29sb3IoMC4wZiwgMC4wZiwgMC4wZiwgMC41Zik7CiNpZiBVU0VfR0wKICAgIGdsQ2xlYXJEZXB0aCgxLjBmKTsKI2VsaWYgVVNFX0dMRVN2MgogICAgZ2xDbGVhckRlcHRoZigxLjBmKTsKI2VuZGlmCiAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQgfCBHTF9ERVBUSF9CVUZGRVJfQklUKTsKfQoKdm9pZApDYW52YXNEUk06OnVwZGF0ZSgpCnsKICAgIE9wdGlvbnM6OkZyYW1lRW5kIG0gPSBPcHRpb25zOjpmcmFtZV9lbmQ7CgogICAgaWYgKG0gPT0gT3B0aW9uczo6RnJhbWVFbmREZWZhdWx0KSB7CiAgICAgICAgaWYgKG9mZnNjcmVlbl8pCiAgICAgICAgICAgIG0gPSBPcHRpb25zOjpGcmFtZUVuZEZpbmlzaDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIG0gPSBPcHRpb25zOjpGcmFtZUVuZFN3YXA7CiAgICB9CgogICAgc3dpdGNoKG0pIHsKICAgICAgICBjYXNlIE9wdGlvbnM6OkZyYW1lRW5kU3dhcDoKICAgICAgICAgICAgc3dhcF9idWZmZXJzKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgT3B0aW9uczo6RnJhbWVFbmRGaW5pc2g6CiAgICAgICAgICAgIGdsRmluaXNoKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgT3B0aW9uczo6RnJhbWVFbmRSZWFkUGl4ZWxzOgogICAgICAgICAgICByZWFkX3BpeGVsKHdpZHRoXyAvIDIsIGhlaWdodF8gLyAyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBPcHRpb25zOjpGcmFtZUVuZE5vbmU6CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn0KCnZvaWQKQ2FudmFzRFJNOjpwcmludF9pbmZvKCkKewogICAgbWFrZV9jdXJyZW50KCk7CgogICAgc3RkOjpzdHJpbmdzdHJlYW0gc3M7CiAgICBzcyA8PCAiICAgIE9wZW5HTCBJbmZvcm1hdGlvbiIgPDwgc3RkOjplbmRsOwogICAgc3MgPDwgIiAgICBHTF9WRU5ET1I6ICAgICAiIDw8IGdsR2V0U3RyaW5nKEdMX1ZFTkRPUikgPDwgc3RkOjplbmRsOwogICAgc3MgPDwgIiAgICBHTF9SRU5ERVJFUjogICAiIDw8IGdsR2V0U3RyaW5nKEdMX1JFTkRFUkVSKSA8PCBzdGQ6OmVuZGw7CiAgICBzcyA8PCAiICAgIEdMX1ZFUlNJT046ICAgICIgPDwgZ2xHZXRTdHJpbmcoR0xfVkVSU0lPTikgPDwgc3RkOjplbmRsOwogICAgTG9nOjppbmZvKCIlcyIsIHNzLnN0cigpLmNfc3RyKCkpOwp9CgpDYW52YXM6OlBpeGVsCkNhbnZhc0RSTTo6cmVhZF9waXhlbChpbnQgeCwgaW50IHkpCnsKICAgIHVpbnQ4X3QgcGl4ZWxbNF07CiAgICBnbFJlYWRQaXhlbHMoeCwgeSwgMSwgMSwgR0xfUkdCQSwgR0xfVU5TSUdORURfQllURSwgcGl4ZWwpOwogICAgcmV0dXJuIENhbnZhczo6UGl4ZWwocGl4ZWxbMF0sIHBpeGVsWzFdLCBwaXhlbFsyXSwgcGl4ZWxbM10pOwp9Cgp2b2lkCkNhbnZhc0RSTTo6d3JpdGVfdG9fZmlsZShzdGQ6OnN0cmluZyAmZmlsZW5hbWUpCnsKICAgIGNoYXIgKnBpeGVscyA9IG5ldyBjaGFyW3dpZHRoXyAqIGhlaWdodF8gKiA0XTsKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IGhlaWdodF87IGkrKykgewogICAgICAgIGdsUmVhZFBpeGVscygwLCBpLCB3aWR0aF8sIDEsIEdMX1JHQkEsIEdMX1VOU0lHTkVEX0JZVEUsCiAgICAgICAgICAgICAgICAgICAgICZwaXhlbHNbKGhlaWdodF8gLSBpIC0gMSkgKiB3aWR0aF8gKiA0XSk7CiAgICB9CgogICAgc3RkOjpvZnN0cmVhbSBvdXRwdXQgKGZpbGVuYW1lLmNfc3RyKCksIHN0ZDo6aW9zOjpvdXQgfCBzdGQ6Omlvczo6YmluYXJ5KTsKICAgIG91dHB1dC53cml0ZShwaXhlbHMsIDQgKiB3aWR0aF8gKiBoZWlnaHRfKTsKCiAgICBkZWxldGUgW10gcGl4ZWxzOwp9Cgpib29sCkNhbnZhc0RSTTo6c2hvdWxkX3F1aXQoKQp7CiAgICByZXR1cm4gZHJtXy5zaG91bGRfcXVpdCgpOwp9Cgp2b2lkCkNhbnZhc0RSTTo6cmVzaXplKGludCB3aWR0aCwgaW50IGhlaWdodCkKewogICAgcmVzaXplX25vX3ZpZXdwb3J0KHdpZHRoLCBoZWlnaHQpOwogICAgZ2xWaWV3cG9ydCgwLCAwLCB3aWR0aF8sIGhlaWdodF8pOwp9CgovKioqKioqKioqKioqKioqKioqKioqCiAqIFByb3RlY3RlZCBtZXRob2RzICoKICoqKioqKioqKioqKioqKioqKioqKi8KCmJvb2wKQ2FudmFzRFJNOjpzdXBwb3J0c19nbDIoKQp7CiAgICBzdGQ6OnN0cmluZyBnbF92ZXJzaW9uX3N0cigKICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IGNoYXIqPihnbEdldFN0cmluZyhHTF9WRVJTSU9OKSkpOwogICAgaW50IGdsX21ham9yID0gMDsKCiAgICBzaXplX3QgcG9pbnRfcG9zKGdsX3ZlcnNpb25fc3RyLmZpbmQoJy4nKSk7CgogICAgaWYgKHBvaW50X3BvcyAhPSBzdGQ6OnN0cmluZzo6bnBvcykgewogICAgICAgIHBvaW50X3Bvcy0tOwoKICAgICAgICBzaXplX3Qgc3RhcnRfcG9zKGdsX3ZlcnNpb25fc3RyLnJmaW5kKCcgJywgcG9pbnRfcG9zKSk7CiAgICAgICAgaWYgKHN0YXJ0X3BvcyA9PSBzdGQ6OnN0cmluZzo6bnBvcykKICAgICAgICAgICAgc3RhcnRfcG9zID0gMDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHN0YXJ0X3BvcysrOwoKICAgICAgICBnbF9tYWpvciA9IFV0aWw6OmZyb21TdHJpbmc8aW50PigKICAgICAgICAgICAgICAgIGdsX3ZlcnNpb25fc3RyLnN1YnN0cihzdGFydF9wb3MsIHBvaW50X3BvcyAtIHN0YXJ0X3BvcyArIDEpCiAgICAgICAgICAgICAgICApOwogICAgfQoKICAgIHJldHVybiBnbF9tYWpvciA+PSAyOwp9Cgpib29sCkNhbnZhc0RSTTo6bWFrZV9jdXJyZW50KCkKewogICAgaWYgKCFlZ2xfLnZhbGlkKCkpIHsKICAgICAgICBMb2c6OmVycm9yKCJDYW52YXNEUk06IEludmFsaWQgRUdMIHN0YXRlXG4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgaW5pdF9nbF9leHRlbnNpb25zKCk7CgogICAgcmV0dXJuIHRydWU7Cn0KCmJvb2wKQ2FudmFzRFJNOjpyZXNldF9jb250ZXh0KCkKewogICAgcmV0dXJuIGVnbF8ucmVzZXQoKTsKfQoKdm9pZApDYW52YXNEUk06OnN3YXBfYnVmZmVycygpCnsKICAgIGVnbF8uc3dhcCgpOwogICAgZHJtXy5kb19mbGlwKCk7Cn0KCnZvaWQKQ2FudmFzRFJNOjppbml0X2dsX2V4dGVuc2lvbnMoKQp7CiNpZiBVU0VfR0xFU3YyCiAgICAvKgogICAgICogUGFyc2UgdGhlIGV4dGVuc2lvbnMgd2UgY2FyZSBhYm91dCBmcm9tIHRoZSBleHRlbnNpb24gc3RyaW5nLgogICAgICogRG9uJ3QgZXZlbiBib3RoZXIgdG8gZ2V0IGZ1bmN0aW9uIHBvaW50ZXJzIHVudGlsIHdlIGtub3cgdGhlCiAgICAgKiBleHRlbnNpb24gaXMgcHJlc2VudC4KICAgICAqLwogICAgc3RkOjpzdHJpbmcgZXh0U3RyaW5nOwogICAgY29uc3QgY2hhciogZXh0cyA9CiAgICAgICAgcmVpbnRlcnByZXRfY2FzdDxjb25zdCBjaGFyKj4oZ2xHZXRTdHJpbmcoR0xfRVhURU5TSU9OUykpOwogICAgaWYgKGV4dHMpCiAgICAgICAgZXh0U3RyaW5nID0gZXh0czsKCiAgICBpZiAoZXh0U3RyaW5nLmZpbmQoIkdMX09FU19tYXBidWZmZXIiKSAhPSBzdGQ6OnN0cmluZzo6bnBvcykgewogICAgICAgIEdMRXh0ZW5zaW9uczo6TWFwQnVmZmVyID0gcmVpbnRlcnByZXRfY2FzdDxQRk5HTE1BUEJVRkZFUk9FU1BST0M+KAogICAgICAgICAgICBlZ2xHZXRQcm9jQWRkcmVzcygiZ2xNYXBCdWZmZXJPRVMiKSk7CiAgICAgICAgR0xFeHRlbnNpb25zOjpVbm1hcEJ1ZmZlciA9IHJlaW50ZXJwcmV0X2Nhc3Q8UEZOR0xVTk1BUEJVRkZFUk9FU1BST0M+KAogICAgICAgICAgICBlZ2xHZXRQcm9jQWRkcmVzcygiZ2xVbm1hcEJ1ZmZlck9FUyIpKTsKICAgIH0KI2VsaWYgVVNFX0dMCiAgICBHTEV4dGVuc2lvbnM6Ok1hcEJ1ZmZlciA9IGdsTWFwQnVmZmVyOwogICAgR0xFeHRlbnNpb25zOjpVbm1hcEJ1ZmZlciA9IGdsVW5tYXBCdWZmZXI7CiNlbmRpZgp9CgoKLyoqKioqKioqKioqKioqKioqKioKICogUHJpdmF0ZSBtZXRob2RzICoKICoqKioqKioqKioqKioqKioqKiovCgp2b2lkCkNhbnZhc0RSTTo6cmVzaXplX25vX3ZpZXdwb3J0KGludCB3aWR0aCwgaW50IGhlaWdodCkKewogICAgd2lkdGhfID0gZHJtXy5tb2RlX3dpZHRoKCk7CiAgICBoZWlnaHRfID0gZHJtXy5tb2RlX2hlaWdodCgpOwoKICAgIGlmICghd2lkdGhfKQogICAgICAgIHdpZHRoXyA9IHdpZHRoOwogICAgaWYgKCFoZWlnaHRfKQogICAgICAgIGhlaWdodF8gPSBoZWlnaHQ7CgogICAgcHJvamVjdGlvbl8gPQogICAgICAgIExpYk1hdHJpeDo6TWF0NDo6cGVyc3BlY3RpdmUoNjAuMCwgd2lkdGhfIC8gc3RhdGljX2Nhc3Q8ZmxvYXQ+KGhlaWdodF8pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMS4wLCAxMDI0LjApOwp9Cg==