Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIFNpbW9uIFF1ZSAKLy8gIEplc3NlIEJhcmtlcgovLwojaWZuZGVmIEdMTUFSSzJfQ0FOVkFTX0RSTV9IXwojZGVmaW5lIEdMTUFSSzJfQ0FOVkFTX0RSTV9IXwoKI2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxnYm0uaD4KI2luY2x1ZGUgPGRybS5oPgojaW5jbHVkZSA8eGY4NmRybS5oPgojaW5jbHVkZSA8eGY4NmRybU1vZGUuaD4KCiNpbmNsdWRlICJjYW52YXMuaCIKI2luY2x1ZGUgImVnbC1zdGF0ZS5oIgoKc3RydWN0IERSTUZCU3RhdGUKewogICAgaW50IGZkOwogICAgZ2JtX2JvKiBibzsKICAgIHVpbnQzMl90IGZiX2lkOwp9OwoKY2xhc3MgRFJNU3RhdGUKewogICAgc3RhdGljIHZvaWQgcGFnZV9mbGlwX2hhbmRsZXIoaW50IGZkLCB1bnNpZ25lZCBpbnQgZnJhbWUsIHVuc2lnbmVkIGludCBzZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgdXNlYywgdm9pZCogZGF0YSk7CiAgICBzdGF0aWMgdm9pZCBmYl9kZXN0cm95X2NhbGxiYWNrKGdibV9ibyogYm8sIHZvaWQqIGRhdGEpOwogICAgRFJNRkJTdGF0ZSogZmJfZ2V0X2Zyb21fYm8oZ2JtX2JvKiBibyk7CiAgICBib29sIGluaXRfZ2JtKCk7CiAgICBpbnQgZmRfOwogICAgZHJtTW9kZVJlcyogcmVzb3VyY2VzXzsKICAgIGRybU1vZGVDb25uZWN0b3IqIGNvbm5lY3Rvcl87CiAgICBkcm1Nb2RlRW5jb2RlciogZW5jb2Rlcl87CiAgICBkcm1Nb2RlQ3J0Y1B0ciBjcnRjXzsKICAgIGRybU1vZGVNb2RlSW5mbyogbW9kZV87CiAgICBnYm1fZGV2aWNlKiBkZXZfOwogICAgZ2JtX3N1cmZhY2UqIHN1cmZhY2VfOwogICAgZ2JtX2JvKiBib187CiAgICBEUk1GQlN0YXRlKiBmYl87CgpwdWJsaWM6CiAgICBEUk1TdGF0ZSgpIDoKICAgICAgICBmZF8oMCksCiAgICAgICAgcmVzb3VyY2VzXygwKSwKICAgICAgICBjb25uZWN0b3JfKDApLAogICAgICAgIGVuY29kZXJfKDApLAogICAgICAgIG1vZGVfKDApLAogICAgICAgIGRldl8oMCksCiAgICAgICAgc3VyZmFjZV8oMCksCiAgICAgICAgYm9fKDApLAogICAgICAgIGZiXygwKSB7fQogICAgfkRSTVN0YXRlKCkgeyBjbGVhbnVwKCk7IH0KICAgIHZvaWQgY2xlYW51cCgpOwogICAgYm9vbCBpbml0KCk7CiAgICBib29sIHJlc2V0KCk7CiAgICB2b2lkIGRvX2ZsaXAoKTsKICAgIGdibV9kZXZpY2UqIGRldmljZSgpIGNvbnN0IHsgcmV0dXJuIGRldl87IH0KICAgIGdibV9zdXJmYWNlKiBzdXJmYWNlKCkgY29uc3QgeyByZXR1cm4gc3VyZmFjZV87IH0KICAgIHVuc2lnbmVkIGludCBtb2RlX3dpZHRoKCkgY29uc3QKICAgIHsgCiAgICAgICAgaWYgKG1vZGVfKSB7CiAgICAgICAgICAgIHJldHVybiBtb2RlXy0+aGRpc3BsYXk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgfQogICAgdW5zaWduZWQgaW50IG1vZGVfaGVpZ2h0KCkgY29uc3QKICAgIHsKICAgICAgICBpZiAobW9kZV8pIHsKICAgICAgICAgICAgcmV0dXJuIG1vZGVfLT52ZGlzcGxheTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn07CgovKioKICogQ2FudmFzIGZvciBkaXJlY3QgcmVuZGVyaW5nIHdpdGggRUdMLgogKi8KY2xhc3MgQ2FudmFzRFJNOiBwdWJsaWMgQ2FudmFzCnsKcHVibGljOgogICAgQ2FudmFzRFJNKGludCB3aWR0aCwgaW50IGhlaWdodCkgOgogICAgICAgIENhbnZhcyh3aWR0aCwgaGVpZ2h0KSB7fQogICAgfkNhbnZhc0RSTSgpOwoKICAgIHZpcnR1YWwgYm9vbCBpbml0KCk7CiAgICB2aXJ0dWFsIGJvb2wgcmVzZXQoKTsKICAgIHZpcnR1YWwgdm9pZCB2aXNpYmxlKGJvb2wgdmlzaWJsZSk7CiAgICB2aXJ0dWFsIHZvaWQgY2xlYXIoKTsKICAgIHZpcnR1YWwgdm9pZCB1cGRhdGUoKTsKICAgIHZpcnR1YWwgdm9pZCBwcmludF9pbmZvKCk7CiAgICB2aXJ0dWFsIFBpeGVsIHJlYWRfcGl4ZWwoaW50IHgsIGludCB5KTsKICAgIHZpcnR1YWwgdm9pZCB3cml0ZV90b19maWxlKHN0ZDo6c3RyaW5nICZmaWxlbmFtZSk7CiAgICB2aXJ0dWFsIGJvb2wgc2hvdWxkX3F1aXQoKTsKICAgIHZpcnR1YWwgdm9pZCByZXNpemUoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KTsKCnByb3RlY3RlZDoKICAgIHZpcnR1YWwgYm9vbCBtYWtlX2N1cnJlbnQoKTsKICAgIHZpcnR1YWwgYm9vbCByZXNldF9jb250ZXh0KCk7CiAgICB2aXJ0dWFsIHZvaWQgc3dhcF9idWZmZXJzKCk7CiAgICB2aXJ0dWFsIGJvb2wgc3VwcG9ydHNfZ2wyKCk7Cgpwcml2YXRlOgogICAgRFJNU3RhdGUgZHJtXzsKICAgIEVHTFN0YXRlIGVnbF87CgogICAgdm9pZCByZXNpemVfbm9fdmlld3BvcnQoaW50IHdpZHRoLCBpbnQgaGVpZ2h0KTsKICAgIHZvaWQgaW5pdF9nbF9leHRlbnNpb25zKCk7CgogICAgc3RhdGljIHZvaWQgcXVpdF9oYW5kbGVyKGludCBzaWdudW0pOwogICAgc3RhdGljIGJvb2wgc2hvdWxkX3F1aXRfOwp9OwoKI2VuZGlmCg==