LyoKICogQ29weXJpZ2h0IChDKSAyMDA1ICBPbGUgQW5kcukgVmFkbGEgUmF2buVzIDxvbGVhdnJAZ21haWwuY29tPgogKiBDb3B5cmlnaHQgKEMpIDIwMDggIFJhbWlybyBQb2xsYQogKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBGRm1wZWcuCiAqCiAqIEZGbXBlZyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIEZGbXBlZyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCBGRm1wZWc7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW50Lmg+CgojaW5jbHVkZSAiYXZjb2RlYy5oIgojaW5jbHVkZSAiaW50ZXJuYWwuaCIKI2luY2x1ZGUgImdldF9iaXRzLmgiCiNpbmNsdWRlICJieXRlc3RyZWFtLmgiCiNpbmNsdWRlICJkc3B1dGlsLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKCiNkZWZpbmUgTUlNSUNfSEVBREVSX1NJWkUgICAyMAoKdHlwZWRlZiBzdHJ1Y3QgewogICAgQVZDb2RlY0NvbnRleHQgKmF2Y3R4OwoKICAgIGludCAgICAgICAgICAgICBudW1fdmJsb2Nrc1szXTsKICAgIGludCAgICAgICAgICAgICBudW1faGJsb2Nrc1szXTsKCiAgICB2b2lkICAgICAgICAgICAqc3dhcF9idWY7CiAgICBpbnQgICAgICAgICAgICAgc3dhcF9idWZfc2l6ZTsKCiAgICBpbnQgICAgICAgICAgICAgY3VyX2luZGV4OwogICAgaW50ICAgICAgICAgICAgIHByZXZfaW5kZXg7CgogICAgQVZGcmFtZSAgICAgICAgIGJ1Zl9wdHJzICAgIFsxNl07CiAgICBBVlBpY3R1cmUgICAgICAgZmxpcHBlZF9wdHJzWzE2XTsKCiAgICBERUNMQVJFX0FMSUdORUQoMTYsIERDVEVMRU0sIGRjdF9ibG9jaylbNjRdOwoKICAgIEdldEJpdENvbnRleHQgICBnYjsKICAgIFNjYW5UYWJsZSAgICAgICBzY2FudGFibGU7CiAgICBEU1BDb250ZXh0ICAgICAgZHNwOwogICAgVkxDICAgICAgICAgICAgIHZsYzsKCiAgICAvKiBLZXB0IGluIHRoZSBjb250ZXh0IHNvIG11bHRpdGhyZWFkaW5nIGNhbiBoYXZlIGEgY29uc3RhbnQgdG8gcmVhZCBmcm9tICovCiAgICBpbnQgICAgICAgICAgICAgbmV4dF9jdXJfaW5kZXg7CiAgICBpbnQgICAgICAgICAgICAgbmV4dF9wcmV2X2luZGV4Owp9IE1pbWljQ29udGV4dDsKCnN0YXRpYyBjb25zdCB1aW50MzJfdCBodWZmY29kZXNbXSA9IHsKICAgIDB4MDAwMDAwMGEsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAsCiAgICAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLCAweDAwMDAwMDAwLAogICAgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwMCwgMHgwMDAwMDAwYiwKICAgIDB4MDAwMDAwMWIsIDB4MDAwMDAwMzgsIDB4MDAwMDAwNzgsIDB4MDAwMDAwNzksIDB4MDAwMDAwN2EsIDB4MDAwMDAwZjksCiAgICAweDAwMDAwMGZhLCAweDAwMDAwM2ZiLCAweDAwMDAwN2Y4LCAweDAwMDAwN2Y5LCAweDAwMDAwN2ZhLCAweDAwMDAwN2ZiLAogICAgMHgwMDAwMGZmOCwgMHgwMDAwMGZmOSwgMHgwMDAwMDAwMSwgMHgwMDAwMDAzOSwgMHgwMDAwMDA3YiwgMHgwMDAwMDBmYiwKICAgIDB4MDAwMDAxZjgsIDB4MDAwMDAxZjksIDB4MDAwMDBmZmEsIDB4MDAwMDBmZmIsIDB4MDAwMDFmZjgsIDB4MDAwMDFmZjksCiAgICAweDAwMDAxZmZhLCAweDAwMDAxZmZiLCAweDAwMDAzZmY4LCAweDAwMDAzZmY5LCAweDAwMDAzZmZhLCAweDAwMDAwMDAwLAogICAgMHgwMDAwMDAwNCwgMHgwMDAwMDAzYSwgMHgwMDAwMDFmYSwgMHgwMDAwM2ZmYiwgMHgwMDAwN2ZmOCwgMHgwMDAwN2ZmOSwKICAgIDB4MDAwMDdmZmEsIDB4MDAwMDdmZmIsIDB4MDAwMGZmZjgsIDB4MDAwMGZmZjksIDB4MDAwMGZmZmEsIDB4MDAwMGZmZmIsCiAgICAweDAwMDFmZmY4LCAweDAwMDFmZmY5LCAweDAwMDFmZmZhLCAweDAwMDAwMDAwLCAweDAwMDAwMDBjLCAweDAwMDAwMGY4LAogICAgMHgwMDAwMDFmYiwgMHgwMDAxZmZmYiwgMHgwMDAzZmZmOCwgMHgwMDAzZmZmOSwgMHgwMDAzZmZmYSwgMHgwMDAzZmZmYiwKICAgIDB4MDAwN2ZmZjgsIDB4MDAwN2ZmZjksIDB4MDAwN2ZmZmEsIDB4MDAwN2ZmZmIsIDB4MDAwZmZmZjgsIDB4MDAwZmZmZjksCiAgICAweDAwMGZmZmZhLCAweDAwMDAwMDAwLCAweDAwMDAwMDFhLCAweDAwMDAwM2Y4LCAweDAwMGZmZmZiLCAweDAwMWZmZmY4LAogICAgMHgwMDFmZmZmOSwgMHgwMDFmZmZmYSwgMHgwMDFmZmZmYiwgMHgwMDNmZmZmOCwgMHgwMDNmZmZmOSwgMHgwMDNmZmZmYSwKICAgIDB4MDAzZmZmZmIsIDB4MDA3ZmZmZjgsIDB4MDA3ZmZmZjksIDB4MDA3ZmZmZmEsIDB4MDA3ZmZmZmIsIDB4MDAwMDAwMDAsCiAgICAweDAwMDAwMDNiLCAweDAwMDAwM2Y5LCAweDAwZmZmZmY4LCAweDAwZmZmZmY5LCAweDAwZmZmZmZhLCAweDAwZmZmZmZiLAogICAgMHgwMWZmZmZmOCwgMHgwMWZmZmZmOSwgMHgwMWZmZmZmYSwgMHgwMWZmZmZmYiwgMHgwM2ZmZmZmOCwgMHgwM2ZmZmZmOSwKICAgIDB4MDNmZmZmZmEsIDB4MDNmZmZmZmIsIDB4MDdmZmZmZjgsIDB4MDAwMDAwMDAsIDB4MDAwMDAzZmEsIDB4MDdmZmZmZjksCiAgICAweDA3ZmZmZmZhLCAweDA3ZmZmZmZiLCAweDBmZmZmZmY4LCAweDBmZmZmZmY5LCAweDBmZmZmZmZhLCAweDBmZmZmZmZiLAogICAgMHgxZmZmZmZmOCwgMHgxZmZmZmZmOSwgMHgxZmZmZmZmYSwgMHgxZmZmZmZmYiwgMHgzZmZmZmZmOCwgMHgzZmZmZmZmOSwKICAgIDB4M2ZmZmZmZmEsCn07CgpzdGF0aWMgY29uc3QgdWludDhfdCBodWZmYml0c1tdID0gewogICAgIDQsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwKICAgICAwLCAgMCwgIDAsICAwLCAgMiwgIDQsICA1LCAgNiwgIDcsICA3LCAgNywgIDgsCiAgICAgOCwgMTAsIDExLCAxMSwgMTEsIDExLCAxMiwgMTIsICAyLCAgNiwgIDcsICA4LAogICAgIDksICA5LCAxMiwgMTIsIDEzLCAxMywgMTMsIDEzLCAxNCwgMTQsIDE0LCAgMCwKICAgICAzLCAgNiwgIDksIDE0LCAxNSwgMTUsIDE1LCAxNSwgMTYsIDE2LCAxNiwgMTYsCiAgICAxNywgMTcsIDE3LCAgMCwgIDQsICA4LCAgOSwgMTcsIDE4LCAxOCwgMTgsIDE4LAogICAgMTksIDE5LCAxOSwgMTksIDIwLCAyMCwgMjAsICAwLCAgNSwgMTAsIDIwLCAyMSwKICAgIDIxLCAyMSwgMjEsIDIyLCAyMiwgMjIsIDIyLCAyMywgMjMsIDIzLCAyMywgIDAsCiAgICAgNiwgMTAsIDI0LCAyNCwgMjQsIDI0LCAyNSwgMjUsIDI1LCAyNSwgMjYsIDI2LAogICAgMjYsIDI2LCAyNywgIDAsIDEwLCAyNywgMjcsIDI3LCAyOCwgMjgsIDI4LCAyOCwKICAgIDI5LCAyOSwgMjksIDI5LCAzMCwgMzAsIDMwLAp9OwoKc3RhdGljIGNvbnN0IHVpbnQ4X3QgY29sX3phZ1s2NF0gPSB7CiAgICAgMCwgIDgsICAxLCAgMiwgIDksIDE2LCAyNCwgMTcsCiAgICAxMCwgIDMsICA0LCAxMSwgMTgsIDI1LCAzMiwgNDAsCiAgICAzMywgMjYsIDE5LCAxMiwgIDUsICA2LCAxMywgMjAsCiAgICAyNywgMzQsIDQxLCA0OCwgNTYsIDQ5LCA0MiwgMzUsCiAgICAyOCwgMjEsIDE0LCAgNywgMTUsIDIyLCAyOSwgMzYsCiAgICA0MywgNTAsIDU3LCA1OCwgNTEsIDQ0LCAzNywgMzAsCiAgICAyMywgMzEsIDM4LCA0NSwgNTIsIDU5LCAzOSwgNDYsCiAgICA1MywgNjAsIDYxLCA1NCwgNDcsIDU1LCA2MiwgNjMsCn07CgpzdGF0aWMgYXZfY29sZCBpbnQgbWltaWNfZGVjb2RlX2luaXQoQVZDb2RlY0NvbnRleHQgKmF2Y3R4KQp7CiAgICBNaW1pY0NvbnRleHQgKmN0eCA9IGF2Y3R4LT5wcml2X2RhdGE7CgogICAgY3R4LT5wcmV2X2luZGV4ID0gMDsKICAgIGN0eC0+Y3VyX2luZGV4ID0gMTU7CgogICAgaWYoaW5pdF92bGMoJmN0eC0+dmxjLCAxMSwgRkZfQVJSQVlfRUxFTVMoaHVmZmJpdHMpLAogICAgICAgICAgICAgICAgIGh1ZmZiaXRzLCAxLCAxLCBodWZmY29kZXMsIDQsIDQsIDApKSB7CiAgICAgICAgYXZfbG9nKGF2Y3R4LCBBVl9MT0dfRVJST1IsICJlcnJvciBpbml0aWFsaXppbmcgdmxjIHRhYmxlXG4iKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBkc3B1dGlsX2luaXQoJmN0eC0+ZHNwLCBhdmN0eCk7CiAgICBmZl9pbml0X3NjYW50YWJsZShjdHgtPmRzcC5pZGN0X3Blcm11dGF0aW9uLCAmY3R4LT5zY2FudGFibGUsIGNvbF96YWcpOwoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50IG1pbWljX2RlY29kZV91cGRhdGVfdGhyZWFkX2NvbnRleHQoQVZDb2RlY0NvbnRleHQgKmF2Y3R4LCBjb25zdCBBVkNvZGVjQ29udGV4dCAqYXZjdHhfZnJvbSkKewogICAgTWltaWNDb250ZXh0ICpkc3QgPSBhdmN0eC0+cHJpdl9kYXRhLCAqc3JjID0gYXZjdHhfZnJvbS0+cHJpdl9kYXRhOwoKICAgIGlmIChhdmN0eCA9PSBhdmN0eF9mcm9tKSByZXR1cm4gMDsKCiAgICBkc3QtPmN1cl9pbmRleCAgPSBzcmMtPm5leHRfY3VyX2luZGV4OwogICAgZHN0LT5wcmV2X2luZGV4ID0gc3JjLT5uZXh0X3ByZXZfaW5kZXg7CgogICAgbWVtY3B5KGRzdC0+YnVmX3B0cnMsIHNyYy0+YnVmX3B0cnMsIHNpemVvZihzcmMtPmJ1Zl9wdHJzKSk7CiAgICBtZW1jcHkoZHN0LT5mbGlwcGVkX3B0cnMsIHNyYy0+ZmxpcHBlZF9wdHJzLCBzaXplb2Yoc3JjLT5mbGlwcGVkX3B0cnMpKTsKCiAgICBtZW1zZXQoJmRzdC0+YnVmX3B0cnNbZHN0LT5jdXJfaW5kZXhdLCAwLCBzaXplb2YoQVZGcmFtZSkpOwoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgY29uc3QgaW50OF90IHZsY2RlY19sb29rdXBbOV1bNjRdID0gewogICAgeyAgICAwLCB9LAogICAgeyAgIC0xLCAgIDEsIH0sCiAgICB7ICAgLTMsICAgMywgICAtMiwgICAyLCB9LAogICAgeyAgIC03LCAgIDcsICAgLTYsICAgNiwgICAtNSwgICA1LCAgIC00LCAgIDQsIH0sCiAgICB7ICAtMTUsICAxNSwgIC0xNCwgIDE0LCAgLTEzLCAgMTMsICAtMTIsICAxMiwKICAgICAgIC0xMSwgIDExLCAgLTEwLCAgMTAsICAgLTksICAgOSwgICAtOCwgICA4LCB9LAogICAgeyAgLTMxLCAgMzEsICAtMzAsICAzMCwgIC0yOSwgIDI5LCAgLTI4LCAgMjgsCiAgICAgICAtMjcsICAyNywgIC0yNiwgIDI2LCAgLTI1LCAgMjUsICAtMjQsICAyNCwKICAgICAgIC0yMywgIDIzLCAgLTIyLCAgMjIsICAtMjEsICAyMSwgIC0yMCwgIDIwLAogICAgICAgLTE5LCAgMTksICAtMTgsICAxOCwgIC0xNywgIDE3LCAgLTE2LCAgMTYsIH0sCiAgICB7ICAtNjMsICA2MywgIC02MiwgIDYyLCAgLTYxLCAgNjEsICAtNjAsICA2MCwKICAgICAgIC01OSwgIDU5LCAgLTU4LCAgNTgsICAtNTcsICA1NywgIC01NiwgIDU2LAogICAgICAgLTU1LCAgNTUsICAtNTQsICA1NCwgIC01MywgIDUzLCAgLTUyLCAgNTIsCiAgICAgICAtNTEsICA1MSwgIC01MCwgIDUwLCAgLTQ5LCAgNDksICAtNDgsICA0OCwKICAgICAgIC00NywgIDQ3LCAgLTQ2LCAgNDYsICAtNDUsICA0NSwgIC00NCwgIDQ0LAogICAgICAgLTQzLCAgNDMsICAtNDIsICA0MiwgIC00MSwgIDQxLCAgLTQwLCAgNDAsCiAgICAgICAtMzksICAzOSwgIC0zOCwgIDM4LCAgLTM3LCAgMzcsICAtMzYsICAzNiwKICAgICAgIC0zNSwgIDM1LCAgLTM0LCAgMzQsICAtMzMsICAzMywgIC0zMiwgIDMyLCB9LAogICAgeyAtMTI3LCAxMjcsIC0xMjYsIDEyNiwgLTEyNSwgMTI1LCAtMTI0LCAxMjQsCiAgICAgIC0xMjMsIDEyMywgLTEyMiwgMTIyLCAtMTIxLCAxMjEsIC0xMjAsIDEyMCwKICAgICAgLTExOSwgMTE5LCAtMTE4LCAxMTgsIC0xMTcsIDExNywgLTExNiwgMTE2LAogICAgICAtMTE1LCAxMTUsIC0xMTQsIDExNCwgLTExMywgMTEzLCAtMTEyLCAxMTIsCiAgICAgIC0xMTEsIDExMSwgLTExMCwgMTEwLCAtMTA5LCAxMDksIC0xMDgsIDEwOCwKICAgICAgLTEwNywgMTA3LCAtMTA2LCAxMDYsIC0xMDUsIDEwNSwgLTEwNCwgMTA0LAogICAgICAtMTAzLCAxMDMsIC0xMDIsIDEwMiwgLTEwMSwgMTAxLCAtMTAwLCAxMDAsCiAgICAgICAtOTksICA5OSwgIC05OCwgIDk4LCAgLTk3LCAgOTcsICAtOTYsICA5NiwgfSwKICAgIHsgIC05NSwgIDk1LCAgLTk0LCAgOTQsICAtOTMsICA5MywgIC05MiwgIDkyLAogICAgICAgLTkxLCAgOTEsICAtOTAsICA5MCwgIC04OSwgIDg5LCAgLTg4LCAgODgsCiAgICAgICAtODcsICA4NywgIC04NiwgIDg2LCAgLTg1LCAgODUsICAtODQsICA4NCwKICAgICAgIC04MywgIDgzLCAgLTgyLCAgODIsICAtODEsICA4MSwgIC04MCwgIDgwLAogICAgICAgLTc5LCAgNzksICAtNzgsICA3OCwgIC03NywgIDc3LCAgLTc2LCAgNzYsCiAgICAgICAtNzUsICA3NSwgIC03NCwgIDc0LCAgLTczLCAgNzMsICAtNzIsICA3MiwKICAgICAgIC03MSwgIDcxLCAgLTcwLCAgNzAsICAtNjksICA2OSwgIC02OCwgIDY4LAogICAgICAgLTY3LCAgNjcsICAtNjYsICA2NiwgIC02NSwgIDY1LCAgLTY0LCAgNjQsIH0sCn07CgpzdGF0aWMgaW50IHZsY19kZWNvZGVfYmxvY2soTWltaWNDb250ZXh0ICpjdHgsIGludCBudW1fY29lZmZzLCBpbnQgcXNjYWxlKQp7CiAgICBEQ1RFTEVNICpibG9jayA9IGN0eC0+ZGN0X2Jsb2NrOwogICAgdW5zaWduZWQgaW50IHBvczsKCiAgICBjdHgtPmRzcC5jbGVhcl9ibG9jayhibG9jayk7CgogICAgYmxvY2tbMF0gPSBnZXRfYml0cygmY3R4LT5nYiwgOCkgPDwgMzsKCiAgICBmb3IocG9zID0gMTsgcG9zIDwgbnVtX2NvZWZmczsgcG9zKyspIHsKICAgICAgICB1aW50MzJfdCB2bGMsIG51bV9iaXRzOwogICAgICAgIGludCB2YWx1ZTsKICAgICAgICBpbnQgY29lZmY7CgogICAgICAgIHZsYyA9IGdldF92bGMyKCZjdHgtPmdiLCBjdHgtPnZsYy50YWJsZSwgY3R4LT52bGMuYml0cywgMyk7CiAgICAgICAgaWYoIXZsYykgLyogZW5kLW9mLWJsb2NrIGNvZGUgKi8KICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgaWYodmxjID09IC0xKQogICAgICAgICAgICByZXR1cm4gMDsKCiAgICAgICAgLyogcG9zX2FkZCBhbmQgbnVtX2JpdHMgYXJlIGNvZGVkIGluIHRoZSB2bGMgY29kZSAqLwogICAgICAgIHBvcyArPSAgICAgdmxjJjE1OyAvLyBwb3NfYWRkCiAgICAgICAgbnVtX2JpdHMgPSB2bGM+PjQ7IC8vIG51bV9iaXRzCgogICAgICAgIGlmKHBvcyA+PSA2NCkKICAgICAgICAgICAgcmV0dXJuIDA7CgogICAgICAgIHZhbHVlID0gZ2V0X2JpdHMoJmN0eC0+Z2IsIG51bV9iaXRzKTsKCiAgICAgICAgLyogRkZtcGVnJ3MgSURDVCBiZWhhdmVzIHNvbWV3aGF0IGRpZmZlcmVudCBmcm9tIHRoZSBvcmlnaW5hbCBjb2RlLCBzbwogICAgICAgICAqIGEgZmFjdG9yIG9mIDQgd2FzIGFkZGVkIHRvIHRoZSBpbnB1dCAqLwoKICAgICAgICBjb2VmZiA9IHZsY2RlY19sb29rdXBbbnVtX2JpdHNdW3ZhbHVlXTsKICAgICAgICBpZihwb3M8MykKICAgICAgICAgICAgY29lZmYgPDw9IDQ7CiAgICAgICAgZWxzZSAvKiBUT0RPIFVzZSA+PiAxMCBpbnN0ZWFkIG9mIC8gMTAwMSAqLwogICAgICAgICAgICBjb2VmZiA9IChjb2VmZiAqIHFzY2FsZSkgLyAxMDAxOwoKICAgICAgICBibG9ja1tjdHgtPnNjYW50YWJsZS5wZXJtdXRhdGVkW3Bvc11dID0gY29lZmY7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgZGVjb2RlKE1pbWljQ29udGV4dCAqY3R4LCBpbnQgcXVhbGl0eSwgaW50IG51bV9jb2VmZnMsCiAgICAgICAgICAgICAgICAgIGludCBpc19pZnJhbWUpCnsKICAgIGludCB5LCB4LCBwbGFuZSwgY3VyX3JvdyA9IDA7CgogICAgZm9yKHBsYW5lID0gMDsgcGxhbmUgPCAzOyBwbGFuZSsrKSB7CiAgICAgICAgY29uc3QgaW50IGlzX2Nocm9tYSA9ICEhcGxhbmU7CiAgICAgICAgY29uc3QgaW50IHFzY2FsZSA9IGF2X2NsaXAoMTAwMDAtcXVhbGl0eSxpc19jaHJvbWE/MTAwMDoyMDAwLDEwMDAwKTw8MjsKICAgICAgICBjb25zdCBpbnQgc3RyaWRlID0gY3R4LT5mbGlwcGVkX3B0cnNbY3R4LT5jdXJfaW5kZXhdLmxpbmVzaXplW3BsYW5lXTsKICAgICAgICBjb25zdCB1aW50OF90ICpzcmMgPSBjdHgtPmZsaXBwZWRfcHRyc1tjdHgtPnByZXZfaW5kZXhdLmRhdGFbcGxhbmVdOwogICAgICAgIHVpbnQ4X3QgICAgICAgKmRzdCA9IGN0eC0+ZmxpcHBlZF9wdHJzW2N0eC0+Y3VyX2luZGV4IF0uZGF0YVtwbGFuZV07CgogICAgICAgIGZvcih5ID0gMDsgeSA8IGN0eC0+bnVtX3ZibG9ja3NbcGxhbmVdOyB5KyspIHsKICAgICAgICAgICAgZm9yKHggPSAwOyB4IDwgY3R4LT5udW1faGJsb2Nrc1twbGFuZV07IHgrKykgewoKICAgICAgICAgICAgICAgIC8qIENoZWNrIGZvciBhIGNoYW5nZSBjb25kaXRpb24gaW4gdGhlIGN1cnJlbnQgYmxvY2suCiAgICAgICAgICAgICAgICAgKiAtIGlmcmFtZXMgYWx3YXlzIGNoYW5nZS4KICAgICAgICAgICAgICAgICAqIC0gTHVtYSBwbGFuZSBjaGFuZ2VzIG9uIGdldF9iaXRzMSA9PSAwCiAgICAgICAgICAgICAgICAgKiAtIENocm9tYSBwbGFuZXMgY2hhbmdlIG9uIGdldF9iaXRzMSA9PSAxICovCiAgICAgICAgICAgICAgICBpZihpc19pZnJhbWUgfHwgZ2V0X2JpdHMxKCZjdHgtPmdiKSA9PSBpc19jaHJvbWEpIHsKCiAgICAgICAgICAgICAgICAgICAgLyogTHVtYSBwbGFuZXMgbWF5IHVzZSBhIGJhY2tyZWZlcmVuY2UgZnJvbSB0aGUgMTUgbGFzdAogICAgICAgICAgICAgICAgICAgICAqIGZyYW1lcyBwcmVjZWRpbmcgdGhlIHByZXZpb3VzLiAoZ2V0X2JpdHMxID09IDEpCiAgICAgICAgICAgICAgICAgICAgICogQ2hyb21hIHBsYW5lcyBkb24ndCB1c2UgYmFja3JlZmVyZW5jZXMuICovCiAgICAgICAgICAgICAgICAgICAgaWYoaXNfY2hyb21hIHx8IGlzX2lmcmFtZSB8fCAhZ2V0X2JpdHMxKCZjdHgtPmdiKSkgewoKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXZsY19kZWNvZGVfYmxvY2soY3R4LCBudW1fY29lZmZzLCBxc2NhbGUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eC0+ZHNwLmlkY3RfcHV0KGRzdCwgc3RyaWRlLCBjdHgtPmRjdF9ibG9jayk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGJhY2tyZWYgPSBnZXRfYml0cygmY3R4LT5nYiwgNCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmRleCA9IChjdHgtPmN1cl9pbmRleCtiYWNrcmVmKSYxNTsKICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCAqcCA9IGN0eC0+ZmxpcHBlZF9wdHJzW2luZGV4XS5kYXRhWzBdOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9IGN0eC0+Y3VyX2luZGV4ICYmIHApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZmX3RocmVhZF9hd2FpdF9wcm9ncmVzcygmY3R4LT5idWZfcHRyc1tpbmRleF0sIGN1cl9yb3csIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcCArPSBzcmMgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC0+ZmxpcHBlZF9wdHJzW2N0eC0+cHJldl9pbmRleF0uZGF0YVtwbGFuZV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgtPmRzcC5wdXRfcGl4ZWxzX3RhYlsxXVswXShkc3QsIHAsIHN0cmlkZSwgOCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdl9sb2coY3R4LT5hdmN0eCwgQVZfTE9HX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIHN1Y2ggYmFja3JlZmVyZW5jZSEgQnVnZ3kgc2FtcGxlLlxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZmX3RocmVhZF9hd2FpdF9wcm9ncmVzcygmY3R4LT5idWZfcHRyc1tjdHgtPnByZXZfaW5kZXhdLCBjdXJfcm93LCAwKTsKICAgICAgICAgICAgICAgICAgICBjdHgtPmRzcC5wdXRfcGl4ZWxzX3RhYlsxXVswXShkc3QsIHNyYywgc3RyaWRlLCA4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNyYyArPSA4OwogICAgICAgICAgICAgICAgZHN0ICs9IDg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3JjICs9IChzdHJpZGUgLSBjdHgtPm51bV9oYmxvY2tzW3BsYW5lXSk8PDM7CiAgICAgICAgICAgIGRzdCArPSAoc3RyaWRlIC0gY3R4LT5udW1faGJsb2Nrc1twbGFuZV0pPDwzOwoKICAgICAgICAgICAgZmZfdGhyZWFkX3JlcG9ydF9wcm9ncmVzcygmY3R4LT5idWZfcHRyc1tjdHgtPmN1cl9pbmRleF0sIGN1cl9yb3crKywgMCk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAxOwp9CgovKioKICogRmxpcCB0aGUgYnVmZmVyIHVwc2lkZS1kb3duIGFuZCBwdXQgaXQgaW4gdGhlIFlWVSBvcmRlciB0byBtYXRjaCB0aGUKICogd2F5IE1pbWljIGVuY29kZXMgZnJhbWVzLgogKi8Kc3RhdGljIHZvaWQgcHJlcGFyZV9hdnBpYyhNaW1pY0NvbnRleHQgKmN0eCwgQVZQaWN0dXJlICpkc3QsIEFWUGljdHVyZSAqc3JjKQp7CiAgICBpbnQgaTsKICAgIGRzdC0+ZGF0YVswXSA9IHNyYy0+ZGF0YVswXSsoIGN0eC0+YXZjdHgtPmhlaWdodCAgICAtMSkqc3JjLT5saW5lc2l6ZVswXTsKICAgIGRzdC0+ZGF0YVsxXSA9IHNyYy0+ZGF0YVsyXSsoKGN0eC0+YXZjdHgtPmhlaWdodD4+MSktMSkqc3JjLT5saW5lc2l6ZVsyXTsKICAgIGRzdC0+ZGF0YVsyXSA9IHNyYy0+ZGF0YVsxXSsoKGN0eC0+YXZjdHgtPmhlaWdodD4+MSktMSkqc3JjLT5saW5lc2l6ZVsxXTsKICAgIGZvcihpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICBkc3QtPmxpbmVzaXplW2ldID0gLXNyYy0+bGluZXNpemVbaV07Cn0KCnN0YXRpYyBpbnQgbWltaWNfZGVjb2RlX2ZyYW1lKEFWQ29kZWNDb250ZXh0ICphdmN0eCwgdm9pZCAqZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpkYXRhX3NpemUsIEFWUGFja2V0ICphdnBrdCkKewogICAgY29uc3QgdWludDhfdCAqYnVmID0gYXZwa3QtPmRhdGE7CiAgICBpbnQgYnVmX3NpemUgPSBhdnBrdC0+c2l6ZTsKICAgIE1pbWljQ29udGV4dCAqY3R4ID0gYXZjdHgtPnByaXZfZGF0YTsKICAgIGludCBpc19wZnJhbWU7CiAgICBpbnQgd2lkdGgsIGhlaWdodDsKICAgIGludCBxdWFsaXR5LCBudW1fY29lZmZzOwogICAgaW50IHN3YXBfYnVmX3NpemUgPSBidWZfc2l6ZSAtIE1JTUlDX0hFQURFUl9TSVpFOwogICAgaW50IHJlczsKCiAgICBpZihidWZfc2l6ZSA8IE1JTUlDX0hFQURFUl9TSVpFKSB7CiAgICAgICAgYXZfbG9nKGF2Y3R4LCBBVl9MT0dfRVJST1IsICJpbnN1ZmZpY2llbnQgZGF0YVxuIik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIGJ1ZiAgICAgICArPSAyOyAvKiBzb21lIGNvbnN0YW50IChhbHdheXMgMjU2KSAqLwogICAgcXVhbGl0eSAgICA9IGJ5dGVzdHJlYW1fZ2V0X2xlMTYoJmJ1Zik7CiAgICB3aWR0aCAgICAgID0gYnl0ZXN0cmVhbV9nZXRfbGUxNigmYnVmKTsKICAgIGhlaWdodCAgICAgPSBieXRlc3RyZWFtX2dldF9sZTE2KCZidWYpOwogICAgYnVmICAgICAgICs9IDQ7IC8qIHNvbWUgY29uc3RhbnQgKi8KICAgIGlzX3BmcmFtZSAgPSBieXRlc3RyZWFtX2dldF9sZTMyKCZidWYpOwogICAgbnVtX2NvZWZmcyA9IGJ5dGVzdHJlYW1fZ2V0X2J5dGUoJmJ1Zik7CiAgICBidWYgICAgICAgKz0gMzsgLyogc29tZSBjb25zdGFudCAqLwoKICAgIGlmKCFjdHgtPmF2Y3R4KSB7CiAgICAgICAgaW50IGk7CgogICAgICAgIGlmKCEod2lkdGggPT0gMTYwICYmIGhlaWdodCA9PSAxMjApICYmCiAgICAgICAgICAgISh3aWR0aCA9PSAzMjAgJiYgaGVpZ2h0ID09IDI0MCkpIHsKICAgICAgICAgICAgYXZfbG9nKGF2Y3R4LCBBVl9MT0dfRVJST1IsICJpbnZhbGlkIHdpZHRoL2hlaWdodCFcbiIpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQoKICAgICAgICBjdHgtPmF2Y3R4ICAgICA9IGF2Y3R4OwogICAgICAgIGF2Y3R4LT53aWR0aCAgID0gd2lkdGg7CiAgICAgICAgYXZjdHgtPmhlaWdodCAgPSBoZWlnaHQ7CiAgICAgICAgYXZjdHgtPnBpeF9mbXQgPSBQSVhfRk1UX1lVVjQyMFA7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgMzsgaSsrKSB7CiAgICAgICAgICAgIGN0eC0+bnVtX3ZibG9ja3NbaV0gPSAtKCgtaGVpZ2h0KSA+PiAoMyArICEhaSkpOwogICAgICAgICAgICBjdHgtPm51bV9oYmxvY2tzW2ldID0gICAgIHdpZHRoICAgPj4gKDMgKyAhIWkpIDsKICAgICAgICB9CiAgICB9IGVsc2UgaWYod2lkdGggIT0gY3R4LT5hdmN0eC0+d2lkdGggfHwgaGVpZ2h0ICE9IGN0eC0+YXZjdHgtPmhlaWdodCkgewogICAgICAgIGF2X2xvZyhhdmN0eCwgQVZfTE9HX0VSUk9SLCAicmVzb2x1dGlvbiBjaGFuZ2luZyBpcyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgaWYoaXNfcGZyYW1lICYmICFjdHgtPmJ1Zl9wdHJzW2N0eC0+cHJldl9pbmRleF0uZGF0YVswXSkgewogICAgICAgIGF2X2xvZyhhdmN0eCwgQVZfTE9HX0VSUk9SLCAiZGVjb2RpbmcgbXVzdCBzdGFydCB3aXRoIGtleWZyYW1lXG4iKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgY3R4LT5idWZfcHRyc1tjdHgtPmN1cl9pbmRleF0ucmVmZXJlbmNlID0gMzsKICAgIGN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdLnBpY3RfdHlwZSA9IGlzX3BmcmFtZSA/IEFWX1BJQ1RVUkVfVFlQRV9QOkFWX1BJQ1RVUkVfVFlQRV9JOwogICAgaWYoZmZfdGhyZWFkX2dldF9idWZmZXIoYXZjdHgsICZjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XSkpIHsKICAgICAgICBhdl9sb2coYXZjdHgsIEFWX0xPR19FUlJPUiwgImdldF9idWZmZXIoKSBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBjdHgtPm5leHRfcHJldl9pbmRleCA9IGN0eC0+Y3VyX2luZGV4OwogICAgY3R4LT5uZXh0X2N1cl9pbmRleCAgPSAoY3R4LT5jdXJfaW5kZXggLSAxKSAmIDE1OwoKICAgIHByZXBhcmVfYXZwaWMoY3R4LCAmY3R4LT5mbGlwcGVkX3B0cnNbY3R4LT5jdXJfaW5kZXhdLAogICAgICAgICAgICAgICAgICAoQVZQaWN0dXJlKikgJmN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdKTsKCiAgICBmZl90aHJlYWRfZmluaXNoX3NldHVwKGF2Y3R4KTsKCiAgICBhdl9mYXN0X3BhZGRlZF9tYWxsb2MoJmN0eC0+c3dhcF9idWYsICZjdHgtPnN3YXBfYnVmX3NpemUsIHN3YXBfYnVmX3NpemUpOwogICAgaWYoIWN0eC0+c3dhcF9idWYpCiAgICAgICAgcmV0dXJuIEFWRVJST1IoRU5PTUVNKTsKCiAgICBjdHgtPmRzcC5ic3dhcF9idWYoY3R4LT5zd2FwX2J1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IHVpbnQzMl90KikgYnVmLAogICAgICAgICAgICAgICAgICAgICAgICBzd2FwX2J1Zl9zaXplPj4yKTsKICAgIGluaXRfZ2V0X2JpdHMoJmN0eC0+Z2IsIGN0eC0+c3dhcF9idWYsIHN3YXBfYnVmX3NpemUgPDwgMyk7CgogICAgcmVzID0gZGVjb2RlKGN0eCwgcXVhbGl0eSwgbnVtX2NvZWZmcywgIWlzX3BmcmFtZSk7CiAgICBmZl90aHJlYWRfcmVwb3J0X3Byb2dyZXNzKCZjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XSwgSU5UX01BWCwgMCk7CiAgICBpZiAoIXJlcykgewogICAgICAgIGlmICghKGF2Y3R4LT5hY3RpdmVfdGhyZWFkX3R5cGUgJiBGRl9USFJFQURfRlJBTUUpKSB7CiAgICAgICAgICAgIGZmX3RocmVhZF9yZWxlYXNlX2J1ZmZlcihhdmN0eCwgJmN0eC0+YnVmX3B0cnNbY3R4LT5jdXJfaW5kZXhdKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgIH0KCiAgICAqKEFWRnJhbWUqKWRhdGEgPSBjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XTsKICAgICpkYXRhX3NpemUgPSBzaXplb2YoQVZGcmFtZSk7CgogICAgY3R4LT5wcmV2X2luZGV4ID0gY3R4LT5uZXh0X3ByZXZfaW5kZXg7CiAgICBjdHgtPmN1cl9pbmRleCAgPSBjdHgtPm5leHRfY3VyX2luZGV4OwoKICAgIC8qIE9ubHkgcmVsZWFzZSBmcmFtZXMgdGhhdCBhcmVuJ3QgdXNlZCBmb3IgYmFja3JlZmVyZW5jZXMgYW55bW9yZSAqLwogICAgaWYoY3R4LT5idWZfcHRyc1tjdHgtPmN1cl9pbmRleF0uZGF0YVswXSkKICAgICAgICBmZl90aHJlYWRfcmVsZWFzZV9idWZmZXIoYXZjdHgsICZjdHgtPmJ1Zl9wdHJzW2N0eC0+Y3VyX2luZGV4XSk7CgogICAgcmV0dXJuIGJ1Zl9zaXplOwp9CgpzdGF0aWMgYXZfY29sZCBpbnQgbWltaWNfZGVjb2RlX2VuZChBVkNvZGVjQ29udGV4dCAqYXZjdHgpCnsKICAgIE1pbWljQ29udGV4dCAqY3R4ID0gYXZjdHgtPnByaXZfZGF0YTsKICAgIGludCBpOwoKICAgIGF2X2ZyZWUoY3R4LT5zd2FwX2J1Zik7CgogICAgaWYgKGF2Y3R4LT5pbnRlcm5hbC0+aXNfY29weSkKICAgICAgICByZXR1cm4gMDsKCiAgICBmb3IoaSA9IDA7IGkgPCAxNjsgaSsrKQogICAgICAgIGlmKGN0eC0+YnVmX3B0cnNbaV0uZGF0YVswXSkKICAgICAgICAgICAgZmZfdGhyZWFkX3JlbGVhc2VfYnVmZmVyKGF2Y3R4LCAmY3R4LT5idWZfcHRyc1tpXSk7CiAgICBmZl9mcmVlX3ZsYygmY3R4LT52bGMpOwoKICAgIHJldHVybiAwOwp9CgpBVkNvZGVjIGZmX21pbWljX2RlY29kZXIgPSB7CiAgICAubmFtZSAgICAgICAgICAgPSAibWltaWMiLAogICAgLnR5cGUgICAgICAgICAgID0gQVZNRURJQV9UWVBFX1ZJREVPLAogICAgLmlkICAgICAgICAgICAgID0gQ09ERUNfSURfTUlNSUMsCiAgICAucHJpdl9kYXRhX3NpemUgPSBzaXplb2YoTWltaWNDb250ZXh0KSwKICAgIC5pbml0ICAgICAgICAgICA9IG1pbWljX2RlY29kZV9pbml0LAogICAgLmNsb3NlICAgICAgICAgID0gbWltaWNfZGVjb2RlX2VuZCwKICAgIC5kZWNvZGUgICAgICAgICA9IG1pbWljX2RlY29kZV9mcmFtZSwKICAgIC5jYXBhYmlsaXRpZXMgICA9IENPREVDX0NBUF9EUjEgfCBDT0RFQ19DQVBfRlJBTUVfVEhSRUFEUywKICAgIC5sb25nX25hbWUgPSBOVUxMX0lGX0NPTkZJR19TTUFMTCgiTWltaWMiKSwKICAgIC51cGRhdGVfdGhyZWFkX2NvbnRleHQgPSBPTkxZX0lGX1RIUkVBRFNfRU5BQkxFRChtaW1pY19kZWNvZGVfdXBkYXRlX3RocmVhZF9jb250ZXh0KQp9Owo=