YC8qIEltcGxlbWVudGF0aW9uIG9mIHRoZSBUUkFOU1BPU0UgaW50cmluc2ljCiAgIENvcHlyaWdodCAyMDAzLCAyMDA1LCAyMDA2IEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLgogICBDb250cmlidXRlZCBieSBUb2JpYXMgU2NobPx0ZXIKClRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBHTlUgRm9ydHJhbiA5NSBydW50aW1lIGxpYnJhcnkgKGxpYmdmb3J0cmFuKS4KCkxpYmdmb3J0cmFuIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgptb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCnZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCkluIGFkZGl0aW9uIHRvIHRoZSBwZXJtaXNzaW9ucyBpbiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIHRoZQpGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24gZ2l2ZXMgeW91IHVubGltaXRlZCBwZXJtaXNzaW9uIHRvIGxpbmsgdGhlCmNvbXBpbGVkIHZlcnNpb24gb2YgdGhpcyBmaWxlIGludG8gY29tYmluYXRpb25zIHdpdGggb3RoZXIgcHJvZ3JhbXMsCmFuZCB0byBkaXN0cmlidXRlIHRob3NlIGNvbWJpbmF0aW9ucyB3aXRob3V0IGFueSByZXN0cmljdGlvbiBjb21pbmcKZnJvbSB0aGUgdXNlIG9mIHRoaXMgZmlsZS4gIChUaGUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSByZXN0cmljdGlvbnMKZG8gYXBwbHkgaW4gb3RoZXIgcmVzcGVjdHM7IGZvciBleGFtcGxlLCB0aGV5IGNvdmVyIG1vZGlmaWNhdGlvbiBvZgp0aGUgZmlsZSwgYW5kIGRpc3RyaWJ1dGlvbiB3aGVuIG5vdCBsaW5rZWQgaW50byBhIGNvbWJpbmUKZXhlY3V0YWJsZS4pCgpMaWJnZm9ydHJhbiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLApidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgpNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCkdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgpZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKTGljZW5zZSBhbG9uZyB3aXRoIGxpYmdmb3J0cmFuOyBzZWUgdGhlIGZpbGUgQ09QWUlORy4gIElmIG5vdCwKd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwKQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EuICAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlICJsaWJnZm9ydHJhbi5oIicKaW5jbHVkZShpcGFybS5tNClkbmwKCmAjaWYgZGVmaW5lZCAoSEFWRV8ncnR5cGVfbmFtZWApJwoKZXh0ZXJuIHZvaWQgdHJhbnNwb3NlX2AncnR5cGVfY29kZSAocnR5cGUgKiBjb25zdCByZXN0cmljdCByZXQsIAoJcnR5cGUgKiBjb25zdCByZXN0cmljdCBzb3VyY2UpOwpleHBvcnRfcHJvdG8odHJhbnNwb3NlX2AncnR5cGVfY29kZSk7Cgp2b2lkCnRyYW5zcG9zZV9gJ3J0eXBlX2NvZGUgKHJ0eXBlICogY29uc3QgcmVzdHJpY3QgcmV0LCAKCXJ0eXBlICogY29uc3QgcmVzdHJpY3Qgc291cmNlKQp7CiAgLyogci4qIGluZGljYXRlcyB0aGUgcmV0dXJuIGFycmF5LiAgKi8KICBpbmRleF90eXBlIHJ4c3RyaWRlLCByeXN0cmlkZTsKICBydHlwZV9uYW1lICpycHRyOwogIC8qIHMuKiBpbmRpY2F0ZXMgdGhlIHNvdXJjZSBhcnJheS4gICovCiAgaW5kZXhfdHlwZSBzeHN0cmlkZSwgc3lzdHJpZGU7CiAgY29uc3QgcnR5cGVfbmFtZSAqc3B0cjsKCiAgaW5kZXhfdHlwZSB4Y291bnQsIHljb3VudDsKICBpbmRleF90eXBlIHgsIHk7CgogIGFzc2VydCAoR0ZDX0RFU0NSSVBUT1JfUkFOSyAoc291cmNlKSA9PSAyKTsKCiAgaWYgKHJldC0+ZGF0YSA9PSBOVUxMKQogICAgewogICAgICBhc3NlcnQgKEdGQ19ERVNDUklQVE9SX1JBTksgKHJldCkgPT0gMik7CiAgICAgIGFzc2VydCAocmV0LT5kdHlwZSA9PSBzb3VyY2UtPmR0eXBlKTsKCiAgICAgIHJldC0+ZGltWzBdLmxib3VuZCA9IDA7CiAgICAgIHJldC0+ZGltWzBdLnVib3VuZCA9IHNvdXJjZS0+ZGltWzFdLnVib3VuZCAtIHNvdXJjZS0+ZGltWzFdLmxib3VuZDsKICAgICAgcmV0LT5kaW1bMF0uc3RyaWRlID0gMTsKCiAgICAgIHJldC0+ZGltWzFdLmxib3VuZCA9IDA7CiAgICAgIHJldC0+ZGltWzFdLnVib3VuZCA9IHNvdXJjZS0+ZGltWzBdLnVib3VuZCAtIHNvdXJjZS0+ZGltWzBdLmxib3VuZDsKICAgICAgcmV0LT5kaW1bMV0uc3RyaWRlID0gcmV0LT5kaW1bMF0udWJvdW5kKzE7CgogICAgICByZXQtPmRhdGEgPSBpbnRlcm5hbF9tYWxsb2Nfc2l6ZSAoc2l6ZW9mIChydHlwZV9uYW1lKSAqIHNpemUwICgoYXJyYXlfdCAqKSByZXQpKTsKICAgICAgcmV0LT5vZmZzZXQgPSAwOwogICAgfQoKICBzeHN0cmlkZSA9IHNvdXJjZS0+ZGltWzBdLnN0cmlkZTsKICBzeXN0cmlkZSA9IHNvdXJjZS0+ZGltWzFdLnN0cmlkZTsKICB4Y291bnQgPSBzb3VyY2UtPmRpbVswXS51Ym91bmQgKyAxIC0gc291cmNlLT5kaW1bMF0ubGJvdW5kOwogIHljb3VudCA9IHNvdXJjZS0+ZGltWzFdLnVib3VuZCArIDEgLSBzb3VyY2UtPmRpbVsxXS5sYm91bmQ7CgogIHJ4c3RyaWRlID0gcmV0LT5kaW1bMF0uc3RyaWRlOwogIHJ5c3RyaWRlID0gcmV0LT5kaW1bMV0uc3RyaWRlOwoKICBycHRyID0gcmV0LT5kYXRhOwogIHNwdHIgPSBzb3VyY2UtPmRhdGE7CgogIGZvciAoeT0wOyB5IDwgeWNvdW50OyB5KyspCiAgICB7CiAgICAgIGZvciAoeD0wOyB4IDwgeGNvdW50OyB4KyspCiAgICAgICAgewogICAgICAgICAgKnJwdHIgPSAqc3B0cjsKCiAgICAgICAgICBzcHRyICs9IHN4c3RyaWRlOwogICAgICAgICAgcnB0ciArPSByeXN0cmlkZTsKICAgICAgICB9CiAgICAgICAgc3B0ciArPSBzeXN0cmlkZSAtIChzeHN0cmlkZSAqIHhjb3VudCk7CiAgICAgICAgcnB0ciArPSByeHN0cmlkZSAtIChyeXN0cmlkZSAqIHhjb3VudCk7CiAgICB9Cn0KCiNlbmRpZgo=